diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 7cec0d649..a025e66ac 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -37,6 +37,6 @@ Run `zcashd --version` to find out This includes the relevant contents of `~/.zcash/debug.log`. You can paste raw text, attach the file directly in the issue or link to the text via a pastebin type site. Please also include any non-standard things you did during compilation (extra flags, dependency version changes etc.) if applicable. -### Do you have a back up of `~/.zcash` directory and/or take a VM snapshot? +### Do you have a backup of `~/.zcash` directory and/or take a VM snapshot? - Backing up / making a copy of the `~/.zcash` directory might help make the problem reproducible. Please redact appropriately. - Taking a VM snapshot is really helpful for interactively testing fixes diff --git a/.travis.yml b/.travis.yml index 250756396..ac331dcf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +<<<<<<< HEAD language: cpp compiler: @@ -21,3 +22,84 @@ notifications: - "Alt Message : %{repository_slug} - (%{commit} - %{author}): %{message}, Build Time: %{duration}" - "Change view : %{compare_url}" - "Build details : %{build_url}" +======= +# errata: +# - A travis bug causes caches to trample eachother when using the same +# compiler key (which we don't use anyway). This is worked around for now by +# replacing the "compilers" with a build name prefixed by the no-op ":" +# command. See: https://github.com/travis-ci/travis-ci/issues/4393 +# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback] +# IPv6 support + +sudo: required +dist: precise +group: legacy + +os: linux +language: cpp +compiler: gcc +env: + global: + - MAKEJOBS=-j3 + - RUN_TESTS=false + - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID + - CCACHE_SIZE=100M + - CCACHE_TEMPDIR=/tmp/.ccache-temp + - CCACHE_COMPRESS=1 + - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out + - SDK_URL=https://bitcoincore.org/depends-sources/sdks + - PYTHON_DEBUG=1 + - WINEDEBUG=fixme-all +cache: + apt: true + directories: + - depends/built + - depends/sdk-sources + - $HOME/.ccache +matrix: + fast_finish: true + include: + - compiler: ": ARM" + env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + - compiler: ": Win32" + env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports" MAKEJOBS="-j2" + - compiler: ": 32-bit + dash" + env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" PPA="ppa:chris-lea/zeromq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash" + - compiler: ": Win64" + env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-reduce-exports" MAKEJOBS="-j2" + - compiler: ": bitcoind" + env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" PPA="ppa:chris-lea/zeromq" DEP_OPTS="DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" + - compiler: ": No wallet" + env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + - compiler: ": Cross-Mac" + env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy" + exclude: + - compiler: gcc +install: + - if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi + - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi + - if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi +before_script: + - unset CC; unset CXX + - mkdir -p depends/SDKs depends/sdk-sources + - if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi + - make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS +script: + - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi + - OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST + - BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib" + - depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE + - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi + - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh + - ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) + - make distdir PACKAGE=bitcoin VERSION=$HOST + - cd bitcoin-$HOST + - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) + - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) + - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib + - if [ "$RUN_TESTS" = "true" ]; then make check; fi + - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.sh; fi +after_script: + - if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi +>>>>>>> zcash/master diff --git a/COPYING b/COPYING index 67a092a04..c84bfb7aa 100644 --- a/COPYING +++ b/COPYING @@ -28,8 +28,7 @@ open-source licenses. For further details see 'contrib/debian/copyright'. This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (https://www.openssl.org/). This product includes cryptographic -software written by Eric Young (eay@cryptsoft.com), -and UPnP software written by Thomas Bernard. +software written by Eric Young (eay@cryptsoft.com). Although almost all of the Zcash code is licensed under "permissive" open source diff --git a/Makefile.am b/Makefile.am index 3445faa2a..143b2cc68 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,7 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libzcashconsensus.pc endif + BITCOIND_BIN=$(top_builddir)/src/zcashd$(EXEEXT) BITCOIN_CLI_BIN=$(top_builddir)/src/zcash-cli$(EXEEXT) BITCOIN_WIN_INSTALLER=$(PACKAGE)-$(PACKAGE_VERSION)-win$(WINDOWS_BITS)-setup$(EXEEXT) @@ -33,6 +34,7 @@ DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md) BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ $(top_srcdir)/contrib/devtools/security-check.py + WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ $(top_srcdir)/share/pixmaps/nsis-wizard.bmp @@ -54,7 +56,7 @@ COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ else COVERAGE_INFO = baseline_filtered_combined.info baseline.info block_test.info \ leveldb_baseline.info test_bitcoin_filtered.info total_coverage.info \ - baseline_filtered.info block_test_filtered.info \ + baseline_filtered.info \ leveldb_baseline_filtered.info test_bitcoin_coverage.info test_bitcoin.info \ #zcash-gtest.info zcash-gtest_filtered.info zcash-gtest_coverage.info endif @@ -72,14 +74,6 @@ distcheck-hook: distcleancheck: @: -$(BITCOIN_WIN_INSTALLER): all-recursive - $(MKDIR_P) $(top_builddir)/release - STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIND_BIN) $(top_builddir)/release - STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_CLI_BIN) $(top_builddir)/release - @test -f $(MAKENSIS) && $(MAKENSIS) -V2 $(top_builddir)/share/setup.nsi || \ - echo error: could not build $@ - @echo built $@ - $(if $(findstring src/,$(MAKECMDGOALS)),$(MAKECMDGOALS), none): FORCE $(MAKE) -C src $(patsubst src/%,%,$@) @@ -256,6 +250,7 @@ test_bitcoin_filtered.info: test_bitcoin.info -o $@ endif + block_test.info: test_bitcoin_filtered.info $(MKDIR_P) qa/tmp -@TIMEOUT=15 qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool 0 @@ -289,6 +284,7 @@ block_test_filtered.info: block_test.info -o $@ endif + test_bitcoin_coverage.info: baseline_filtered_combined.info test_bitcoin_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_bitcoin_filtered.info -o $@ @@ -329,12 +325,6 @@ endif endif -if USE_COMPARISON_TOOL -check-local: - $(MKDIR_P) qa/tmp - @qa/pull-tester/run-bitcoind-for-test.sh $(JAVA) -jar $(JAVA_COMPARISON_TOOL) qa/tmp/compTool $(COMPARISON_TOOL_REORG_TESTS) 2>&1 -endif - dist_bin_SCRIPTS = zcutil/fetch-params.sh dist_noinst_SCRIPTS = autogen.sh zcutil/build-debian-package.sh zcutil/build.sh @@ -343,11 +333,9 @@ EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.sh qa/pull install-exec-hook: mv $(DESTDIR)$(bindir)/fetch-params.sh $(DESTDIR)$(bindir)/zcash-fetch-params -CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) - .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man clean-local: - rm -rf test_bitcoin.coverage/ zcash-gtest.coverage/ total.coverage/ $(OSX_APP) + rm -rf test_bitcoin.coverage/ zcash-gtest.coverage/ total.coverage/ diff --git a/README.md b/README.md index 65f34d3d4..25c573317 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +Komodo 1.0.15 ## Komodod This software is Komodo client, generally you will use this if you want to mine KMD or setup a full node. @@ -63,6 +64,18 @@ cd komodo #This can take some time. ``` + +**komodo is experimental and a work-in-progress.** Use at your own risk. + +Deprecation Policy +------------------ + +This release is considered deprecated one year after the release day. There +is an automatic deprecation shutdown feature which will halt the node some +time after this one year period. The automatic feature is based on block +height and can be explicitly disabled. + + # to update an existing version, git checkout dPoW if not on that branch already git pull ./zcutil/fetch-params.sh diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 3f24d5ddc..45d948933 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 23 +#serial 26 AC_DEFUN([AX_BOOST_BASE], [ @@ -95,8 +95,8 @@ if test "x$want_boost" = "xyes"; then x86_64) libsubdirs="lib64 libx32 lib lib64" ;; - ppc64|s390x|sparc64|aarch64) - libsubdirs="lib64 lib lib64" + ppc64|s390x|sparc64|aarch64|ppc64le) + libsubdirs="lib64 lib lib64 ppc64le" ;; esac @@ -170,7 +170,7 @@ if test "x$want_boost" = "xyes"; then AC_MSG_RESULT(yes) succeeded=yes found_system=yes - ],[: + ],[ ]) AC_LANG_POP([C++]) @@ -179,6 +179,10 @@ if test "x$want_boost" = "xyes"; then dnl if we found no boost with system layout we search for boost libraries dnl built and installed without the --layout=system option or for a staged(not installed) version if test "x$succeeded" != "xyes"; then + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + BOOST_CPPFLAGS= + BOOST_LDFLAGS= _version=0 if test "$ac_boost_path" != ""; then if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then @@ -191,6 +195,12 @@ if test "x$want_boost" = "xyes"; then VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE" done + dnl if nothing found search for layout used in Windows distributions + if test -z "$BOOST_CPPFLAGS"; then + if test -d "$ac_boost_path/boost" && test -r "$ac_boost_path/boost"; then + BOOST_CPPFLAGS="-I$ac_boost_path" + fi + fi fi else if test "$cross_compiling" != yes; then @@ -253,7 +263,7 @@ if test "x$want_boost" = "xyes"; then AC_MSG_RESULT(yes) succeeded=yes found_system=yes - ],[: + ],[ ]) AC_LANG_POP([C++]) fi diff --git a/build-aux/m4/ax_boost_program_options.m4 b/build-aux/m4/ax_boost_program_options.m4 index f59144185..2bdb59371 100644 --- a/build-aux/m4/ax_boost_program_options.m4 +++ b/build-aux/m4/ax_boost_program_options.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 22 +#serial 24 AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], [ @@ -63,9 +63,9 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], AC_CACHE_CHECK([whether the Boost::Program_Options library is available], ax_cv_boost_program_options, [AC_LANG_PUSH(C++) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::program_options::options_description generic("Generic options"); + [[boost::program_options::error err("Error message"); return 0;]])], ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no) AC_LANG_POP([C++]) @@ -74,7 +74,6 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` if test "x$ax_boost_user_program_options_lib" = "x"; then - ax_lib= for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.dylib* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.dylib.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a.*$;\1;'` ; do ax_lib=${libextension} AC_CHECK_LIB($ax_lib, exit, diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 9c78280fc..1c05450cb 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 17 +#serial 18 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -68,9 +68,10 @@ AC_DEFUN([AX_BOOST_SYSTEM], ax_cv_boost_system, [AC_LANG_PUSH([C++]) CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS= AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::system::system_category]])], + [[boost::system::error_category *a = 0;]])], ax_cv_boost_system=yes, ax_cv_boost_system=no) CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) diff --git a/build-aux/m4/ax_check_compile_flag.m4 b/build-aux/m4/ax_check_compile_flag.m4 index c3a8d695a..ca3639715 100644 --- a/build-aux/m4/ax_check_compile_flag.m4 +++ b/build-aux/m4/ax_check_compile_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # @@ -53,19 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_check_link_flag.m4 b/build-aux/m4/ax_check_link_flag.m4 index e2d0d363e..eb01a6ce1 100644 --- a/build-aux/m4/ax_check_link_flag.m4 +++ b/build-aux/m4/ax_check_link_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. # @@ -53,18 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_LINK_FLAG], -[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS $4 $1" - AC_LINK_IFELSE([AC_LANG_PROGRAM()], + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) LDFLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_check_preproc_flag.m4 b/build-aux/m4/ax_check_preproc_flag.m4 index b1cfef6b8..ca1d5ee2b 100644 --- a/build-aux/m4/ax_check_preproc_flag.m4 +++ b/build-aux/m4/ax_check_preproc_flag.m4 @@ -4,7 +4,7 @@ # # SYNOPSIS # -# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # @@ -19,6 +19,8 @@ # "CPPFLAGS EXTRA-FLAGS FLAG". This can for example be used to force the # preprocessor to issue an error when a bad flag is given. # +# INPUT gives an alternative input source to AC_PREPROC_IFELSE. +# # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG. # @@ -53,19 +55,19 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 2 +#serial 4 AC_DEFUN([AX_CHECK_PREPROC_FLAG], -[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [ ax_check_save_flags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $4 $1" - AC_PREPROC_IFELSE([AC_LANG_PROGRAM()], + AC_PREPROC_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) CPPFLAGS=$ax_check_save_flags]) -AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], +AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000..f147cee3b --- /dev/null +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,568 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 4 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [], + [$1], [14], [], + [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], + [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], + [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], + [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$4], [nodefault], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++$1 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_seperators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) diff --git a/build-aux/m4/ax_gcc_func_attribute.m4 b/build-aux/m4/ax_gcc_func_attribute.m4 index 275ca63a2..c788ca9bd 100644 --- a/build-aux/m4/ax_gcc_func_attribute.m4 +++ b/build-aux/m4/ax_gcc_func_attribute.m4 @@ -31,6 +31,7 @@ # cold # const # constructor +# constructor_priority for constructor attribute with priority # deprecated # destructor # dllexport @@ -73,7 +74,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 2 +#serial 3 AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) @@ -103,6 +104,9 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [const], [ int foo( void ) __attribute__(($1)); ], + [constructor_priority], [ + int foo( void ) __attribute__((__constructor__(65535/2))); + ], [constructor], [ int foo( void ) __attribute__(($1)); ], @@ -180,6 +184,8 @@ AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ [visibility], [ int foo_def( void ) __attribute__(($1("default"))); int foo_hid( void ) __attribute__(($1("hidden"))); + int foo_int( void ) __attribute__(($1("internal"))); + int foo_pro( void ) __attribute__(($1("protected"))); ], [warning], [ int foo( void ) __attribute__(($1(""))); diff --git a/build-aux/m4/ax_openmp.m4 b/build-aux/m4/ax_openmp.m4 new file mode 100644 index 000000000..866e1d664 --- /dev/null +++ b/build-aux/m4/ax_openmp.m4 @@ -0,0 +1,123 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_openmp.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_OPENMP([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro tries to find out how to compile programs that use OpenMP a +# standard API and set of compiler directives for parallel programming +# (see http://www-unix.mcs/) +# +# On success, it sets the OPENMP_CFLAGS/OPENMP_CXXFLAGS/OPENMP_F77FLAGS +# output variable to the flag (e.g. -omp) used both to compile *and* link +# OpenMP programs in the current language. +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. +# +# If you want to compile everything with OpenMP, you should set: +# +# CFLAGS="$CFLAGS $OPENMP_CFLAGS" +# #OR# CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" +# #OR# FFLAGS="$FFLAGS $OPENMP_FFLAGS" +# +# (depending on the selected language). +# +# The user can override the default choice by setting the corresponding +# environment variable (e.g. OPENMP_CFLAGS). +# +# ACTION-IF-FOUND is a list of shell commands to run if an OpenMP flag is +# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is +# not found. If ACTION-IF-FOUND is not specified, the default action will +# define HAVE_OPENMP. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2015 John W. Peterson +# Copyright (c) 2016 Nick R. Papior +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 13 + +AC_DEFUN([AX_OPENMP], [ +AC_PREREQ([2.69]) dnl for _AC_LANG_PREFIX + +AC_CACHE_CHECK([for OpenMP flag of _AC_LANG compiler], ax_cv_[]_AC_LANG_ABBREV[]_openmp, [save[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS +ax_cv_[]_AC_LANG_ABBREV[]_openmp=unknown +# Flags to try: -fopenmp (gcc), -mp (SGI & PGI), +# -qopenmp (icc>=15), -openmp (icc), +# -xopenmp (Sun), -omp (Tru64), +# -qsmp=omp (AIX), +# none +ax_openmp_flags="-fopenmp -openmp -qopenmp -mp -xopenmp -omp -qsmp=omp none" +if test "x$OPENMP_[]_AC_LANG_PREFIX[]FLAGS" != x; then + ax_openmp_flags="$OPENMP_[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flags" +fi +for ax_openmp_flag in $ax_openmp_flags; do + case $ax_openmp_flag in + none) []_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[] ;; + *) []_AC_LANG_PREFIX[]FLAGS="$save[]_AC_LANG_PREFIX[]FLAGS $ax_openmp_flag" ;; + esac + AC_LINK_IFELSE([AC_LANG_SOURCE([[ +@%:@include + +static void +parallel_fill(int * data, int n) +{ + int i; +@%:@pragma omp parallel for + for (i = 0; i < n; ++i) + data[i] = i; +} + +int +main() +{ + int arr[100000]; + omp_set_num_threads(2); + parallel_fill(arr, 100000); + return 0; +} +]])],[ax_cv_[]_AC_LANG_ABBREV[]_openmp=$ax_openmp_flag; break],[]) +done +[]_AC_LANG_PREFIX[]FLAGS=$save[]_AC_LANG_PREFIX[]FLAGS +]) +if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" = "xunknown"; then + m4_default([$2],:) +else + if test "x$ax_cv_[]_AC_LANG_ABBREV[]_openmp" != "xnone"; then + OPENMP_[]_AC_LANG_PREFIX[]FLAGS=$ax_cv_[]_AC_LANG_ABBREV[]_openmp + fi + m4_default([$1], [AC_DEFINE(HAVE_OPENMP,1,[Define if OpenMP is enabled])]) +fi +])dnl AX_OPENMP diff --git a/build-aux/m4/ax_pthread.m4 b/build-aux/m4/ax_pthread.m4 index d383ad5c6..d218d1af7 100644 --- a/build-aux/m4/ax_pthread.m4 +++ b/build-aux/m4/ax_pthread.m4 @@ -19,10 +19,10 @@ # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" @@ -30,8 +30,8 @@ # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -82,35 +82,40 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 21 +#serial 22 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). +# requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test x"$ax_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -123,7 +128,7 @@ fi # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -132,186 +137,334 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case ${host_os} in - solaris*) +case $host_os in - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: + freebsd*) - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" - ;; + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - darwin*) - ax_pthread_flags="-pthread $ax_pthread_flags" - ;; + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; esac -# Clang doesn't consider unrecognized options an error unless we specify -# -Werror. We throw in some extra Clang-specific options to ensure that -# this doesn't happen for GCC, which also accepts -Werror. +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) -AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) -save_CFLAGS="$CFLAGS" -ax_pthread_extra_flags="-Werror" -CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], - [AC_MSG_RESULT([yes])], - [ax_pthread_extra_flags= - AC_MSG_RESULT([no])]) -CFLAGS="$save_CFLAGS" +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; + aix* | freebsd*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - if test x"$ax_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac +# Are we compiling with Clang? - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) +ax_pthread_clang_warning=no - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = xyes; then - break; - fi +if test "x$ax_pthread_clang" = "xyes"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" done fi # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT([$attr_name]) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case ${host_os} in - aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; - osf* | hpux*) flag="-D_REENTRANT";; - solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - # TODO: What about Clang on Solaris? - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT([$flag]) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], [ - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -321,12 +474,12 @@ AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : else - ax_pthread_ok=no - $2 + ax_pthread_ok=no + $2 fi AC_LANG_POP ])dnl AX_PTHREAD diff --git a/build-aux/m4/l_atomic.m4 b/build-aux/m4/l_atomic.m4 new file mode 100644 index 000000000..906724b64 --- /dev/null +++ b/build-aux/m4/l_atomic.m4 @@ -0,0 +1,40 @@ +# Some versions of gcc/libstdc++ require linking with -latomic if +# using the C++ atomic library. +# +# Sourced from http://bugs.debian.org/797228 + +m4_define([_CHECK_ATOMIC_testbody], [[ + #include + #include + + int main() { + std::atomic a{}; + + int64_t v = 5; + int64_t r = a.fetch_add(v); + return static_cast(r); + } +]]) + +AC_DEFUN([CHECK_ATOMIC], [ + + AC_LANG_PUSH(C++) + + AC_MSG_CHECKING([whether std::atomic can be used without link library]) + + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + LIBS="$LIBS -latomic" + AC_MSG_CHECKING([whether std::atomic needs -latomic]) + AC_LINK_IFELSE([AC_LANG_SOURCE([_CHECK_ATOMIC_testbody])],[ + AC_MSG_RESULT([yes]) + ],[ + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([cannot figure our how to use std::atomic]) + ]) + ]) + + AC_LANG_POP +]) diff --git a/code_of_conduct.md b/code_of_conduct.md index 959fbe4d5..acdf8537b 100644 --- a/code_of_conduct.md +++ b/code_of_conduct.md @@ -52,8 +52,8 @@ themselves available for conduct issues: This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.3.0, available at -[http://contributor-covenant.org/version/1/3/0/][version] +[https://www.contributor-covenant.org/version/1/3/0/][version] -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/3/0/ +[homepage]: https://www.contributor-covenant.org +[version]: https://www.contributor-covenant.org/version/1/3/0/ diff --git a/configure.ac b/configure.ac index 9f8f1900f..decf2b2e6 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 1) define(_CLIENT_VERSION_MINOR, 0) -define(_CLIENT_VERSION_REVISION, 8) +define(_CLIENT_VERSION_REVISION, 15) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) @@ -14,6 +14,16 @@ AC_CONFIG_HEADERS([src/config/bitcoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) +BITCOIN_DAEMON_NAME=zcashd +BITCOIN_CLI_NAME=zcash-cli +BITCOIN_TX_NAME=zcash-tx + +dnl Unless the user specified ARFLAGS, force it to be cr +AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to if not set]) +if test "x${ARFLAGS+set}" != "xset"; then + ARFLAGS="cr" +fi + AC_CANONICAL_HOST AH_TOP([#ifndef BITCOIN_CONFIG_H]) @@ -24,7 +34,7 @@ dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks -AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) +AM_INIT_AUTOMAKE([no-define subdir-objects foreign tar-pax]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. @@ -40,9 +50,6 @@ else CXXFLAGS_overridden=no fi -# Zcash requries C++11 compatibility; set it early: -CXXFLAGS="-std=c++11 $CXXFLAGS" - AC_PROG_CXX m4_ifdef([AC_PROG_OBJCXX],[AC_PROG_OBJCXX]) @@ -54,6 +61,11 @@ case $host in lt_cv_deplibs_check_method="pass_all" ;; esac +dnl Require C++11 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault]) +dnl Check if -latomic is required for +CHECK_ATOMIC + dnl Libtool init checks. LT_INIT([pic-only]) @@ -63,7 +75,6 @@ AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) -AC_PATH_PROG(JAVA, java) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -72,9 +83,6 @@ AC_PATH_PROG(HEXDUMP,hexdump) AC_PATH_TOOL(READELF,readelf) AC_PATH_TOOL(CPPFILT,c++filt) -dnl pkg-config check. -PKG_PROG_PKG_CONFIG - # Enable wallet AC_ARG_ENABLE([wallet], [AS_HELP_STRING([--enable-wallet], @@ -94,32 +102,28 @@ AC_ARG_ENABLE([rust], [enable_rust=$enableval], [enable_rust=yes]) -AC_ARG_WITH([miniupnpc], - [AS_HELP_STRING([--with-miniupnpc], - [enable UPNP (default is yes if libminiupnpc is found)])], - [use_upnp=$withval], - [use_upnp=auto]) - -AC_ARG_ENABLE([upnp-default], - [AS_HELP_STRING([--enable-upnp-default], - [if UPNP is enabled, turn it on at startup (default is no)])], - [use_upnp_default=$enableval], - [use_upnp_default=no]) +AC_ARG_ENABLE([proton], + [AS_HELP_STRING([--disable-proton], + [disable Proton (AMQP messaging)])], + [use_proton=$enableval], + [use_proton=yes]) AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), [use_tests=$enableval], [use_tests=yes]) -AC_ARG_WITH([comparison-tool], - AS_HELP_STRING([--with-comparison-tool],[path to java comparison tool (requires --enable-tests)]), - [use_comparison_tool=$withval], - [use_comparison_tool=no]) +AC_ARG_ENABLE([asan], + [AS_HELP_STRING([--enable-asan], + [instrument the executables with asan (default is no)])], + [use_asan=$enableval], + [use_asan=no]) -AC_ARG_ENABLE([comparison-tool-reorg-tests], - AS_HELP_STRING([--enable-comparison-tool-reorg-tests],[enable expensive reorg tests in the comparison tool (default no)]), - [use_comparison_tool_reorg_tests=$enableval], - [use_comparison_tool_reorg_tests=no]) +AC_ARG_ENABLE([tsan], + [AS_HELP_STRING([--enable-tsan], + [instrument the executables with tsan (default is no)])], + [use_tsan=$enableval], + [use_tsan=no]) if test x$TARGET_OS = xdarwin; then AC_ARG_ENABLE([hardening], @@ -180,6 +184,16 @@ AC_ARG_ENABLE([debug], [enable_debug=$enableval], [enable_debug=no]) +# Turn warnings into errors +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--enable-werror], + [Treat all compiler warnings as errors (default is no)])], + [enable_werror=$enableval], + [enable_werror=no]) + +AC_LANG_PUSH([C++]) +AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) + if test "x$enable_debug" = xyes; then CPPFLAGS="$CPPFLAGS -DDEBUG -DDEBUG_LOCKORDER" if test "x$GCC" = xyes; then @@ -191,11 +205,28 @@ if test "x$enable_debug" = xyes; then fi fi -## TODO: Remove these hard-coded paths and flags. They are here for the sake of -## compatibility with the legacy buildsystem. -## +ERROR_CXXFLAGS= +if test "x$enable_werror" = "xyes"; then + if test "x$CXXFLAG_WERROR" = "x"; then + AC_MSG_ERROR("enable-werror set but -Werror is not usable") + fi + ERROR_CXXFLAGS="$ERROR_CXXFLAGS -Werror" +fi + if test "x$CXXFLAGS_overridden" = "xno"; then - CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wno-self-assign" + AX_CHECK_COMPILE_FLAG([-Wall],[CXXFLAGS="$CXXFLAGS -Wall"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wextra],[CXXFLAGS="$CXXFLAGS -Wextra"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat],[CXXFLAGS="$CXXFLAGS -Wformat"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wvla],[CXXFLAGS="$CXXFLAGS -Wvla"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wformat-security],[CXXFLAGS="$CXXFLAGS -Wformat-security"],,[[$CXXFLAG_WERROR]]) + + ## Some compilers (gcc) ignore unknown -Wno-* options, but warn about all + ## unknown options if any other warning is produced. Test the -Wfoo case, and + ## set the -Wno-foo case if it works. + AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[CXXFLAGS="$CXXFLAGS -Wno-unused-parameter"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wself-assign],[CXXFLAGS="$CXXFLAGS -Wno-self-assign"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[CXXFLAGS="$CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[CXXFLAGS="$CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) fi CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" @@ -217,8 +248,6 @@ AC_ARG_WITH([daemon], [build_bitcoind=$withval], [build_bitcoind=yes]) -AC_LANG_PUSH([C++]) - use_pkgconfig=yes case $host in *mingw*) @@ -343,6 +372,7 @@ dnl fi AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) CPPFLAGS="$CPPFLAGS -DMAC_OSX" + OBJCXXFLAGS="$CXXFLAGS" ;; *linux*) TARGET_OS=linux @@ -351,20 +381,14 @@ dnl fi ;; esac -if test x$use_comparison_tool != xno; then - if test x$JAVA = x; then - AC_MSG_ERROR("comparison tool set but java not found") +if test x$use_pkgconfig = xyes; then + m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [ + PKG_PROG_PKG_CONFIG + if test x"$PKG_CONFIG" = "x"; then + AC_MSG_ERROR(pkg-config not found.) fi - AC_SUBST(JAVA_COMPARISON_TOOL, $use_comparison_tool) -fi - -if test x$use_comparison_tool_reorg_tests != xno; then - if test x$use_comparison_tool = x; then - AC_MSG_ERROR("comparison tool reorg tests but comparison tool was not specified") - fi - AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 1) -else - AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 0) + ]) fi if test x$use_lcov = xyes; then @@ -374,15 +398,9 @@ if test x$use_lcov = xyes; then if test x$GCOV = x; then AC_MSG_ERROR("lcov testing requested but gcov not found") fi - if test x$JAVA = x; then - AC_MSG_ERROR("lcov testing requested but java not found") - fi if test x$GENHTML = x; then AC_MSG_ERROR("lcov testing requested but genhtml not found") fi - if test x$use_comparison_tool = x; then - AC_MSG_ERROR("lcov testing requested but comparison tool was not specified") - fi LCOV="$LCOV --gcov-tool=$GCOV --rc lcov_branch_coverage=1" GENHTML="$GENHTML --branch-coverage" AX_CHECK_COMPILE_FLAG([--coverage],[CXXFLAGS="$CXXFLAGS --coverage"], @@ -443,6 +461,34 @@ else AC_SEARCH_LIBS([clock_gettime],[rt]) fi +if test x$TARGET_OS != xwindows; then + # All windows code is PIC, forcing it on just adds useless compile warnings + AX_CHECK_COMPILE_FLAG([-fPIC],[PIC_FLAGS="-fPIC"]) +fi + +#asan and tsan cannot be used together +if test x$use_asan$use_tsan == xyesyes; then + AC_MSG_ERROR(asan and tsan cannot be simultaneously enabled) +fi + +# using asan flag to enable address sanitizer and undefined behavior sanitizer +if test x$use_asan == xyes; then + AX_CHECK_LINK_FLAG([-static-libstdc++],[SAN_LDFLAGS="$SAN_LDFLAGS -static-libstdc++"],[AC_MSG_ERROR(Cannot statically link -static-libstdc++)]) + AX_CHECK_LINK_FLAG([-static-libasan],[SAN_LDFLAGS="$SAN_LDFLAGS -static-libasan"],[AC_MSG_ERROR(Cannot statically link -static-libasan)]) + AX_CHECK_COMPILE_FLAG([-fsanitize=address],[SAN_CXXFLAGS="$SAN_CXXFLAGS -fsanitize=address"],[AC_MSG_ERROR(Cannot enable -fsanitize=address)]) + AX_CHECK_COMPILE_FLAG([-fsanitize=undefined],[SAN_CXXFLAGS="$SAN_CXXFLAGS -fsanitize=undefined"],[AC_MSG_ERROR(Cannot enable -fsanitize=undefined)]) + AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer],[SAN_CXXFLAGS="$SAN_CXXFLAGS -fno-omit-frame-pointer"],[AC_MSG_ERROR(Cannot enable -fno-omit-frame-pointer)]) +fi + +# using tsan flag to enable address thread sanitizer +# TSAN is supported on Linux x84_64 and tested on Ubuntu 12.04 +# Non-position-independent executables are not supported. Use with -fPIE and -pie flags +# libc/libstdc++ static linking is not supported +if test x$use_tsan == xyes; then + AX_CHECK_COMPILE_FLAG([-fsanitize=thread],[SAN_CXXFLAGS="$SAN_CXXFLAGS -fsanitize=thread"],[AC_MSG_ERROR(Cannot enable -fsanitize=thread)]) + AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer],[SAN_CXXFLAGS="$SAN_CXXFLAGS -fno-omit-frame-pointer"],[AC_MSG_ERROR(Cannot enable -fno-omit-frame-pointer)]) +fi + if test x$use_hardening != xno; then AX_CHECK_COMPILE_FLAG([-Wformat],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wformat"],[AC_MSG_ERROR(Cannot enable -Wformat)]) AX_CHECK_COMPILE_FLAG([-Wformat-security],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wformat-security"],[AC_MSG_ERROR(Cannot enable -Wformat-security)],[-Wformat]) @@ -469,6 +515,7 @@ if test x$use_hardening != xno; then # These are only available on Windows. AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"],[AC_MSG_ERROR(Cannot enable --dynamicbase)]) AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"],[AC_MSG_ERROR(Cannot enable --nxcompat)]) + AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"],[AC_MSG_ERROR(Cannot enable ASLR)]) fi case $host in @@ -476,11 +523,6 @@ if test x$use_hardening != xno; then AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) ;; esac - - CXXFLAGS="$CXXFLAGS $HARDENED_CXXFLAGS" - CPPFLAGS="$CPPFLAGS $HARDENED_CPPFLAGS" - LDFLAGS="$LDFLAGS $HARDENED_LDFLAGS" - OBJCXXFLAGS="$CXXFLAGS" fi dnl this flag screws up non-darwin gcc even when the check fails. special-case it. @@ -549,13 +591,21 @@ if test x$enable_wallet != xno; then BITCOIN_FIND_BDB62 fi -dnl Check for libminiupnpc (optional) -if test x$use_upnp != xno; then - AC_CHECK_HEADERS( - [miniupnpc/miniwget.h miniupnpc/miniupnpc.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h], - [AC_CHECK_LIB([miniupnpc], [main],[MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], - [have_miniupnpc=no] - ) +dnl Check Qpid Proton headers and library exist +if test x$use_proton = xyes; then + AC_CHECK_HEADERS([proton/connection.hpp], + [], + [AC_MSG_WARN([Proton headers not found, disabling Proton support]) + use_proton=no]) + AC_CHECK_LIB([qpid-proton-cpp], [main], + [PROTON_LIBS="-lqpid-proton-cpp -lqpid-proton"], + [AC_MSG_WARN([Proton libraries not found, disabling Proton support]) + use_proton=no]) +fi +if test x$use_proton = xyes; then + AC_DEFINE(ENABLE_PROTON, 1, [Define to 1 to enable Proton functions]) +else + AC_DEFINE(ENABLE_PROTON, 0, [Define to 1 to enable Proton functions]) fi if test x$build_bitcoin_utils$build_bitcoind$use_tests = xnonono; then @@ -567,33 +617,14 @@ fi if test x$use_boost = xyes; then dnl Check for boost libs -AX_BOOST_BASE +dnl We need Boost >= 1.62 to fix a potential security bug (https://github.com/zcash/zcash/issues/1241) +AX_BOOST_BASE([1.62]) AX_BOOST_SYSTEM AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO - -if test x$use_reduce_exports = xyes; then - AC_MSG_CHECKING([for working boost reduced exports]) - TEMP_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS" - AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ - @%:@include - ]], [[ - #if BOOST_VERSION >= 104900 - // Everything is okay - #else - # error Boost version is too old - #endif - ]])],[ - AC_MSG_RESULT(yes) - ],[ - AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.]) - ]) - CPPFLAGS="$TEMP_CPPFLAGS" -fi fi if test x$use_reduce_exports = xyes; then @@ -634,69 +665,11 @@ if test x$use_tests = xyes; then fi if test x$use_boost = xyes; then - BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" - -dnl Boost >= 1.50 uses sleep_for rather than the now-deprecated sleep, however -dnl it was broken from 1.50 to 1.52 when backed by nanosleep. Use sleep_for if -dnl a working version is available, else fall back to sleep. sleep was removed -dnl after 1.56. -dnl If neither is available, abort. -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - ]],[[ - #if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) - boost::this_thread::sleep_for(boost::chrono::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; - AC_DEFINE(HAVE_WORKING_BOOST_SLEEP_FOR, 1, [Define this symbol if boost sleep_for works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" - -if test x$boost_sleep != xyes; then -TEMP_LIBS="$LIBS" -LIBS="$BOOST_LIBS $LIBS" -TEMP_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #include - #include - #include - ]],[[ - #if BOOST_VERSION <= 105600 - boost::this_thread::sleep(boost::posix_time::milliseconds(0)); - #else - choke me - #endif - ]])], - [boost_sleep=yes; AC_DEFINE(HAVE_WORKING_BOOST_SLEEP, 1, [Define this symbol if boost sleep works])], - [boost_sleep=no]) -LIBS="$TEMP_LIBS" -CPPFLAGS="$TEMP_CPPFLAGS" -fi - -if test x$boost_sleep != xyes; then - AC_MSG_ERROR(No working boost sleep implementation found.) -fi - fi if test x$use_pkgconfig = xyes; then - - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - - : #NOP + : dnl m4_ifdef( [PKG_CHECK_MODULES], [ @@ -785,7 +758,8 @@ echo 'Hunting for libsnark include directory...' if test -d "$LIBSNARK_INCDIR"; then echo "Found libsnark include directory: $LIBSNARK_INCDIR" else - AC_MSG_ERROR(libsnark include directory not found) +#AC_MSG_ERROR(libsnark include directory not found) +echo "libsnark include directory not found ($LIBSNARK_INCDIR)" fi CPPFLAGS="-I$LIBSNARK_INCDIR $CPPFLAGS" @@ -803,15 +777,29 @@ if test x$enable_rust != xno; then RUST_LIBS="-lrustzcash" fi -LIBZCASH_LIBS="-lsnark -lgmp -lgmpxx -lboost_system-mt -lcrypto -lsodium -fopenmp $RUST_LIBS" +dnl Check for OpenMP support +AX_OPENMP( + [AC_DEFINE(HAVE_OPENMP, 1, [Define if OpenMP is enabled]) + AM_CONDITIONAL([HAVE_OPENMP], [true]) + CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS"], + [AC_MSG_WARN([OpenMP not supported, disabling multithreading]) + AC_DEFINE(HAVE_OPENMP, 0, [Define if OpenMP is enabled]) + AM_CONDITIONAL([HAVE_OPENMP], [false])]) -CXXFLAGS_TEMP="$CXXFLAGS" -LIBS_TEMP="$LIBS" -CXXFLAGS="$CXXFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS" -LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS $GMP_LIBS $GMPXX_LIBS" -AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),) -CXXFLAGS="$CXXFLAGS_TEMP" -LIBS="$LIBS_TEMP" +# Gitian uses a config.site that sets depends_prefix, and then sets --prefix=/ +# build.sh just uses --prefix +if test x$depends_prefix != x; then + LIBSNARK_DEPINST="$depends_prefix" +else + LIBSNARK_DEPINST="$prefix" +fi + +# Additional Zcash flags +AX_CHECK_COMPILE_FLAG([-fwrapv],[CXXFLAGS="$CXXFLAGS -fwrapv"]) +AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"]) +AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]]) + +LIBZCASH_LIBS="-lgmp -lgmpxx -lboost_system -lcrypto -lsodium $RUST_LIBS" AC_MSG_CHECKING([whether to build bitcoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) @@ -881,35 +869,10 @@ else AC_MSG_RESULT(no) fi -dnl enable upnp support -AC_MSG_CHECKING([whether to build with support for UPnP]) -if test x$have_miniupnpc = xno; then - if test x$use_upnp = xyes; then - AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") - fi - AC_MSG_RESULT(no) -else - if test x$use_upnp != xno; then - AC_MSG_RESULT(yes) - AC_MSG_CHECKING([whether to build with UPnP enabled by default]) - use_upnp=yes - upnp_setting=0 - if test x$use_upnp_default != xno; then - use_upnp_default=yes - upnp_setting=1 - fi - AC_MSG_RESULT($use_upnp_default) - AC_DEFINE_UNQUOTED([USE_UPNP],[$upnp_setting],[UPnP support not compiled if undefined, otherwise value (0 or 1) determines default state]) - if test x$TARGET_OS = xwindows; then - MINIUPNPC_CPPFLAGS="-DSTATICLIB -DMINIUPNP_STATICLIB" - fi - else - AC_MSG_RESULT(no) - fi -fi - AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"]) +AM_CONDITIONAL([ENABLE_PROTON], [test "x$use_proton" = "xyes"]) + AC_MSG_CHECKING([whether to build test_bitcoin]) if test x$use_tests = xyes; then AC_MSG_RESULT([yes]) @@ -938,10 +901,10 @@ AM_CONDITIONAL([ENABLE_MINING],[test x$enable_mining = xyes]) AM_CONDITIONAL([ENABLE_RUST],[test x$enable_rust = xyes]) AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) -AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno]) -AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) +AM_CONDITIONAL([ASAN],[test x$use_asan = xyes]) +AM_CONDITIONAL([TSAN],[test x$use_tsan = xyes]) AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version]) AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version]) @@ -955,20 +918,34 @@ AC_SUBST(CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION) AC_SUBST(CLIENT_VERSION_BUILD, _CLIENT_VERSION_BUILD) AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) +AC_SUBST(BITCOIN_DAEMON_NAME) +AC_SUBST(BITCOIN_CLI_NAME) +AC_SUBST(BITCOIN_TX_NAME) AC_SUBST(RELDFLAGS) +AC_SUBST(ERROR_CXXFLAGS) +AC_SUBST(SAN_CXXFLAGS) +AC_SUBST(SAN_LDFLAGS) +AC_SUBST(HARDENED_CXXFLAGS) +AC_SUBST(HARDENED_CPPFLAGS) +AC_SUBST(HARDENED_LDFLAGS) +AC_SUBST(PIC_FLAGS) +AC_SUBST(PIE_FLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) -AC_SUBST(USE_UPNP) AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) AC_SUBST(LEVELDB_TARGET_FLAGS) -AC_SUBST(MINIUPNPC_CPPFLAGS) -AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(CRYPTO_LIBS) +AC_SUBST(SSL_LIBS) +AC_SUBST(EVENT_LIBS) +AC_SUBST(EVENT_PTHREADS_LIBS) +AC_SUBST(ZMQ_LIBS) AC_SUBST(GMP_LIBS) AC_SUBST(GMPXX_LIBS) -AC_SUBST(LIBSNARK_LIBS) +AC_SUBST(LIBSNARK_DEPINST) AC_SUBST(LIBZCASH_LIBS) -AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi src/test/buildenv.py]) +AC_SUBST(PROTON_LIBS) +AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile src/test/buildenv.py]) AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh]) AC_CONFIG_FILES([qa/pull-tester/tests-config.sh],[chmod +x qa/pull-tester/tests-config.sh]) @@ -995,8 +972,8 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR" unset PKG_CONFIG_LIBDIR PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP" -ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no" -AC_CONFIG_SUBDIRS([src/secp256k1 src/univalue src/cryptoconditions]) +ac_configure_args="${ac_configure_args} --disable-shared --with-pic --with-bignum=no --enable-module-recovery" +AC_CONFIG_SUBDIRS([src/secp256k1 src/snark src/univalue src/cryptoconditions]) AC_OUTPUT @@ -1010,3 +987,25 @@ case $host in chmod 755 libtool ;; esac + +echo +echo "Options used to compile and link:" +echo " with wallet = $enable_wallet" +echo " with rust = $enable_rust" +echo " with proton = $use_proton" +echo " with zmq = $use_zmq" +echo " with test = $use_tests" +echo " debug enabled = $enable_debug" +echo " werror = $enable_werror" +echo +echo " target os = $TARGET_OS" +echo " build os = $BUILD_OS" +echo +echo " CC = $CC" +echo " CFLAGS = $CFLAGS" +echo " CPPFLAGS = $CPPFLAGS" +echo " CXX = $CXX" +echo " CXXFLAGS = $CXXFLAGS" +echo " LDFLAGS = $LDFLAGS" +echo " ARFLAGS = $ARFLAGS" +echo diff --git a/contrib/amqp/amqp_sub.py b/contrib/amqp/amqp_sub.py new file mode 100644 index 000000000..bc51e8428 --- /dev/null +++ b/contrib/amqp/amqp_sub.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Requirements: +# pip install python-qpid-proton + +import binascii +from proton.handlers import MessagingHandler +from proton.reactor import Container + +port = 5672 + +class Server(MessagingHandler): + def __init__(self, url): + super(Server, self).__init__() + self.url = url + self.senders = {} + + def on_start(self, event): + print "Listening on:", self.url + self.container = event.container + self.acceptor = event.container.listen(self.url) + + def on_message(self, event): + m = event.message + topic = m.subject + body = m.body + sequence = str( m.properties['x-opt-sequence-number'] ) + if topic == "hashablock": + print '- HASH BLOCK ('+sequence+') -' + print binascii.hexlify(body) + elif topic == "hashtx": + print '- HASH TX ('+sequence+') -' + print binascii.hexlify(body) + elif topic == "rawblock": + print '- RAW BLOCK HEADER ('+sequence+') -' + print binascii.hexlify(body[:80]) + elif topic == "rawtx": + print '- RAW TX ('+sequence+') -' + print binascii.hexlify(body) + +try: + Container(Server("127.0.0.1:%i" % port)).run() +except KeyboardInterrupt: + pass + diff --git a/contrib/ci-workers/README.md b/contrib/ci-workers/README.md new file mode 100644 index 000000000..37f7ad833 --- /dev/null +++ b/contrib/ci-workers/README.md @@ -0,0 +1,62 @@ +# Zcash CI workers + +This folder contains the Ansible playbooks for configuring a fresh OS +installation for use as a Buildbot worker in Zcash's CI. + +# Criteria for Adding Workers + +a. Don't add workers until users complain about a problem on a platform + that doesn't yet have workers or if we anticipate many users will use + a platform, we may pre-emptively add an unsupported worker for it. + +b. Prioritize the platforms that seem to have the most users. + +c. When adding workers start by adding workers for the "most common" + variant of any distro, then if users later encounter problems with a + sub-variant, we can consider adding new workers at that point. + Example: add Ubuntu Desktop before Xubuntu, on the assumption the + former has a larger population base. + +# Setting up a latent worker on Amazon EC2 + +- Add a regular (non-latent) worker to the master.cfg for dev-ci.z.cash, and + deploy the changes. + - This enables the Ansible playbook to run to completion, ending in the worker + connecting to the master. + +- Start a basic EC2 instance using the template AMI for the target OS. + - Choose the smallest instance size, it won't be used for building Zcash. + +- Figure out which user to log into the instance with. + - E.g. for the Ubuntu template, use "ubuntu" instead of "root" + - If you get an Ansible error later with a message like "Failed to connect to + the host via ssh: Received message too long 1349281121\r\n", that means the + instance is sending a text string in response to the SSH connection, and the + Ansible protocol is balking. Try manually logging in with the same + credentials to diagnose. + +- Create `inventory/hosts` containing the following: + + [zcash-ci-worker-unix] + some-name ansible_host= ansible_ssh_user= + +- Run `ansible-playbook -e buildbot_worker_host_template=templates/host.ec2.j2 -i inventory/hosts unix.yml`, + passing in the worker's Buildbot name and password. + - After a successful run, the worker should be connected to dev-ci.z.cash and + visible in its worker list. + +- Create an AMI from the instance. This is the worker AMI to put into the + master.cfg for dev-ci.z.cash. + - 16 GB of storage should be sufficient. + +- SSH into the instance, and edit the worker config to connect to ci.z.cash. + +- Create an AMI from the instance. This is the worker AMI to put into the + master.cfg for ci.z.cash. + - 16 GB of storage should be sufficient. + +- Delete the instance (it is no longer needed). + +- Edit the master.cfg to turn the new worker into a latent (using the new AMI + IDs), add it to the appropriate worker groups, set up new builders etc. + - Deploy this via the normal PR review process. diff --git a/contrib/ci-workers/ansible.cfg b/contrib/ci-workers/ansible.cfg new file mode 100644 index 000000000..c58fea3c0 --- /dev/null +++ b/contrib/ci-workers/ansible.cfg @@ -0,0 +1,2 @@ +[ssh_connection] +pipelining = True diff --git a/contrib/ci-workers/grind.yml b/contrib/ci-workers/grind.yml new file mode 100644 index 000000000..ef7e5758e --- /dev/null +++ b/contrib/ci-workers/grind.yml @@ -0,0 +1,27 @@ +--- +# Configure a Buildbot worker +- include: unix.yml + +- name: Install grind-specific worker dependencies + hosts: zcash-ci-worker-unix + become: true + + vars_files: + - vars/default.yml + + tasks: + - name: Get dependencies for distribution + include_vars: "{{ item }}" + with_first_found: + - files: + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int }}.yml" + - "vars/{{ ansible_distribution }}.yml" + - "vars/{{ ansible_os_family }}.yml" + skip: true + + - name: Install required packages + package: + name: "{{ item }}" + state: present + with_items: "{{ grind_deps }}" diff --git a/contrib/ci-workers/tasks/install-pip.yml b/contrib/ci-workers/tasks/install-pip.yml new file mode 100644 index 000000000..8beff50ef --- /dev/null +++ b/contrib/ci-workers/tasks/install-pip.yml @@ -0,0 +1,8 @@ +--- +- name: Fetch pip installer + get_url: + url: https://bootstrap.pypa.io/get-pip.py + dest: /tmp/get-pip.py + +- name: Install pip + command: "{{ ansible_python.executable }} /tmp/get-pip.py" diff --git a/contrib/ci-workers/templates/buildbot-worker.service.j2 b/contrib/ci-workers/templates/buildbot-worker.service.j2 new file mode 100644 index 000000000..ffe497bcf --- /dev/null +++ b/contrib/ci-workers/templates/buildbot-worker.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=Buildbot worker +Wants=network.target +After=network.target + +[Service] +Type=forking +PIDFile=/home/{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/twistd.pid +WorkingDirectory=/home/{{ buildbot_worker_user }} +ExecStart={{ pip_bin_dir }}/buildbot-worker start {{ buildbot_worker_name }} +ExecReload={{ pip_bin_dir }}/buildbot-worker restart {{ buildbot_worker_name }} +ExecStop={{ pip_bin_dir }}/buildbot-worker stop {{ buildbot_worker_name }} +Restart=always +User={{ buildbot_worker_user }} + +[Install] +WantedBy=multi-user.target diff --git a/contrib/ci-workers/templates/host.ec2.j2 b/contrib/ci-workers/templates/host.ec2.j2 new file mode 100644 index 000000000..dee692e02 --- /dev/null +++ b/contrib/ci-workers/templates/host.ec2.j2 @@ -0,0 +1 @@ +OS: {{ ansible_distribution }} {{ ansible_distribution_version }} diff --git a/contrib/ci-workers/templates/host.j2 b/contrib/ci-workers/templates/host.j2 new file mode 100644 index 000000000..3a5abb0c2 --- /dev/null +++ b/contrib/ci-workers/templates/host.j2 @@ -0,0 +1,3 @@ +OS: {{ ansible_distribution }} {{ ansible_distribution_version }} +Memory: {{ ansible_memtotal_mb }} MB +CPU: {{ ansible_processor[1] }} diff --git a/contrib/ci-workers/unix.yml b/contrib/ci-workers/unix.yml new file mode 100644 index 000000000..6e6cc49c4 --- /dev/null +++ b/contrib/ci-workers/unix.yml @@ -0,0 +1,152 @@ +--- +- name: Configure a Buildbot worker for Zcash CI + hosts: zcash-ci-worker-unix + become: true + gather_facts: False + + vars_files: + - vars/default.yml + - vars/buildbot.yml + + vars_prompt: + - name: "buildbot_worker_admin" + prompt: "Admin details" + default: "Zcash " + - name: "buildbot_worker_name" + prompt: "Buildbot worker name (provided by ZECC)" + private: no + - name: "buildbot_worker_password" + prompt: "Buildbot worker password (provided by ZECC)" + + pre_tasks: + - name: Install Python 2.7 for Ansible and Buildbot + raw: test -e /usr/bin/python || test -e /usr/bin/python2 || test -e /usr/bin/python2.7 || test -e /usr/local/bin/python2.7 || (test -e /usr/bin/apt && apt -qqy update && apt install -qqy python) || (test -e /usr/bin/dnf && dnf install -qqy python2) || (test -e /usr/sbin/pkg && pkg install -qqy python2) + register: output + changed_when: + - output.stdout != "" + - output.stdout != "\r\n" + + - name: Check if Python is in the configured location + raw: test -e {{ ansible_python_interpreter }} + ignore_errors: true + register: python_check + when: ansible_python_interpreter is defined + + - name: Fail if configured Python is unavailable + fail: + msg: "Python is not accessible at {{ ansible_python_interpreter }} on this host! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary." + when: ansible_python_interpreter is defined and python_check.rc == 1 + + - name: Check if Python is in the default location + raw: test -e /usr/bin/python + ignore_errors: true + register: python_check + when: ansible_python_interpreter is undefined + + - name: Fail if default Python is unavailable + fail: + msg: Python is not accessible at /usr/bin/python on this host! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary. + when: ansible_python_interpreter is undefined and python_check.rc == 1 + + - name: Gathering Facts + setup: + + - name: Fail if Python is the wrong version + fail: + msg: "The Python binary at {{ ansible_python.executable }} is version {{ ansible_python_version }}! Please set the inventory variable 'ansible_python_interpreter' to the location of the Python 2.7 binary." + when: ansible_python.version.major != 2 or ansible_python.version.minor != 7 + + tasks: + - name: Get dependencies for distribution + include_vars: "{{ item }}" + with_first_found: + - files: + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" + - "vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int }}.yml" + - "vars/{{ ansible_distribution }}.yml" + - "vars/{{ ansible_os_family }}.yml" + skip: true + + - name: Collate dependencies + set_fact: + package_deps: "{{ buildbot_deps + fetch_deps + conf_deps + build_deps + link_deps + dist_deps }}" + python_modules: "{{ buildbot_modules + rpc_test_modules }}" + + - name: Update rolling release [Arch Linux] + pacman: + update_cache: yes + upgrade: yes + when: ansible_distribution == 'Archlinux' + + - name: Install required packages + package: + name: "{{ item }}" + state: present + with_items: "{{ package_deps }}" + + - name: Install pip [CentOS] + include: tasks/install-pip.yml + when: ansible_distribution == 'CentOS' + + - name: Install required Python modules + pip: + name: "{{ item }}" + state: latest + with_items: "{{ python_modules }}" + notify: restart buildbot-worker + + - name: Set up the Buildbot worker user + user: + name: "{{ buildbot_worker_user }}" + comment: Buildbot worker + shell: /bin/bash + state: present + + - name: Create Buildbot worker + command: > + buildbot-worker create-worker ~/{{ buildbot_worker_name }} + {{ buildbot_master_host }}:{{ buildbot_master_port }} + {{ buildbot_worker_name|quote }} {{ buildbot_worker_password|quote }} + args: + creates: "~/{{ buildbot_worker_name }}/buildbot.tac" + become_user: "{{ buildbot_worker_user }}" + + - name: Set admin details for Buildbot worker + copy: + content: "{{ buildbot_worker_admin }}" + dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/admin" + owner: "{{ buildbot_worker_user }}" + group: "{{ buildbot_worker_user }}" + mode: "0644" + + - name: Set host details for Buildbot worker + template: + src: "{{ buildbot_worker_host_template }}" + dest: "~{{ buildbot_worker_user }}/{{ buildbot_worker_name }}/info/host" + owner: "{{ buildbot_worker_user }}" + group: "{{ buildbot_worker_user }}" + mode: "0644" + + - name: Copy Buildbot worker systemd service unit + template: + src: templates/buildbot-worker.service.j2 + dest: "/etc/systemd/system/buildbot-worker.service" + owner: root + group: root + mode: "0644" + notify: reload systemd + + - name: Start Buildbot worker. + service: + name: buildbot-worker + state: started + enabled: yes + + handlers: + - name: restart buildbot-worker + service: + name: buildbot-worker + state: restarted + + - name: reload systemd + command: /bin/systemctl daemon-reload diff --git a/contrib/ci-workers/vars/Archlinux.yml b/contrib/ci-workers/vars/Archlinux.yml new file mode 100644 index 000000000..ac4a44e5b --- /dev/null +++ b/contrib/ci-workers/vars/Archlinux.yml @@ -0,0 +1,7 @@ +--- +buildbot_deps: + - python2-pip +build_deps: + - multilib/gcc + - make +pip_bin_dir: /usr/bin diff --git a/contrib/ci-workers/vars/CentOS.yml b/contrib/ci-workers/vars/CentOS.yml new file mode 100644 index 000000000..7e09b0717 --- /dev/null +++ b/contrib/ci-workers/vars/CentOS.yml @@ -0,0 +1,13 @@ +--- +buildbot_deps: [] # Empty to remove python-pip +build_deps: + - bzip2 + - gcc + - gcc-c++ + - make + - patch +dist_deps: + - pkgconfig # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - python-devel + - redhat-rpm-config +pip_bin_dir: /usr/bin diff --git a/contrib/ci-workers/vars/Debian.yml b/contrib/ci-workers/vars/Debian.yml new file mode 100644 index 000000000..992224721 --- /dev/null +++ b/contrib/ci-workers/vars/Debian.yml @@ -0,0 +1,6 @@ +--- +build_deps: + - build-essential # Depends on g++, libc6-dev, make +dist_deps: + - pkg-config # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - python-dev diff --git a/contrib/ci-workers/vars/Fedora.yml b/contrib/ci-workers/vars/Fedora.yml new file mode 100644 index 000000000..1c6b0e0f3 --- /dev/null +++ b/contrib/ci-workers/vars/Fedora.yml @@ -0,0 +1,10 @@ +--- +build_deps: + - gcc + - gcc-c++ + - make + - patch +dist_deps: + - pkgconfig # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in + - python-devel + - redhat-rpm-config diff --git a/contrib/ci-workers/vars/FreeBSD.yml b/contrib/ci-workers/vars/FreeBSD.yml new file mode 100644 index 000000000..65909d71d --- /dev/null +++ b/contrib/ci-workers/vars/FreeBSD.yml @@ -0,0 +1,9 @@ +--- +buildbot_deps: + - py27-pip +build_deps: + - gcc + - gmake +dist_deps: + - bash + - pkgconf # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in diff --git a/contrib/ci-workers/vars/Ubuntu.yml b/contrib/ci-workers/vars/Ubuntu.yml new file mode 100644 index 000000000..4acca499b --- /dev/null +++ b/contrib/ci-workers/vars/Ubuntu.yml @@ -0,0 +1,5 @@ +--- +build_deps: + - build-essential # Depends on g++, libc6-dev, make +dist_deps: + - pkg-config # Required until b556beda264308e040f8d88aca4f2f386a0183d9 is pulled in diff --git a/contrib/ci-workers/vars/buildbot.yml b/contrib/ci-workers/vars/buildbot.yml new file mode 100644 index 000000000..38e3fd25a --- /dev/null +++ b/contrib/ci-workers/vars/buildbot.yml @@ -0,0 +1,5 @@ +--- +buildbot_worker_user: zcbbworker +buildbot_master_host: dev-ci.z.cash +buildbot_master_port: 9899 +buildbot_worker_host_template: templates/host.j2 diff --git a/contrib/ci-workers/vars/default.yml b/contrib/ci-workers/vars/default.yml new file mode 100644 index 000000000..38c5afc8e --- /dev/null +++ b/contrib/ci-workers/vars/default.yml @@ -0,0 +1,49 @@ +--- +# These variables can be overridden in distribution files. + +# Dependencies required to install Buildbot +buildbot_deps: + - python-pip # So we can install Python modules + +# Dependencies required to download files +fetch_deps: + - git + - wget # For zcutil/fetch-params.sh + +# Dependencies required to configure Zcash +conf_deps: + - autoconf + - automake + - m4 + +# Dependencies required to compile Zcash +build_deps: + - g++ + - gcc + - make + +# Dependencies required to link Zcash +link_deps: + - libtool + +# Additional distribution-specific dependencies +dist_deps: [] + +# Additional grind-specific dependencies +grind_deps: + - lcov + - valgrind + +# Python modules required for a Zcash Buildbot worker +buildbot_modules: + - pip # Needs to be updated first so Buildbot installs + - buildbot-worker + - pyflakes + +# Python modules required to run the Zcash RPC test suite +rpc_test_modules: + - pyblake2 + - pyzmq + +# Environment variables +pip_bin_dir: /usr/local/bin diff --git a/contrib/debian/changelog b/contrib/debian/changelog index c400dca73..c0b1d157f 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,3 +1,93 @@ +zcash (1.0.15) stable; urgency=medium + + * 1.0.15 release. + + -- Zcash Company Wed, 28 Feb 2018 16:58:19 +0000 + +zcash (1.0.15~rc1) stable; urgency=medium + + * 1.0.15-rc1 release. + + -- Zcash Company Sat, 24 Feb 2018 04:20:05 +0000 + +zcash (1.0.14) stable; urgency=medium + + * 1.0.14 release. + + -- Zcash Company Wed, 03 Jan 2018 23:54:16 +0100 + +zcash (1.0.14~rc1) stable; urgency=medium + + * 1.0.14-rc1 release. + + -- Zcash Company Fri, 22 Dec 2017 10:12:41 +0000 + +zcash (1.0.13) stable; urgency=medium + + * 1.0.13 release. + + -- Zcash Company Mon, 20 Nov 2017 12:31:53 +0000 + +zcash (1.0.13~rc2) stable; urgency=medium + + * 1.0.13-rc2 release. + + -- Zcash Company Fri, 17 Nov 2017 18:01:08 +0000 + +zcash (1.0.13~rc1) stable; urgency=medium + + * 1.0.13-rc1 release. + + -- Zcash Company Wed, 15 Nov 2017 00:02:21 +0000 + +zcash (1.0.12) stable; urgency=medium + + * 1.0.12 release. + + -- Zcash Company Thu, 28 Sep 2017 01:26:44 +0100 + +zcash (1.0.12~rc1) stable; urgency=medium + + * 1.0.12-rc1 release. + + -- Zcash Company Sat, 23 Sep 2017 10:51:36 +0100 + +zcash (1.0.11) stable; urgency=medium + + * 1.0.11 release. + + -- Zcash Company Tue, 15 Aug 2017 10:06:25 +0100 + +zcash (1.0.11~rc1) stable; urgency=medium + + * 1.0.11-rc1 release. + + -- Zcash Company Tue, 01 Aug 2017 17:12:52 +0200 + +zcash (1.0.10+1) stable; urgency=medium + + * 1.0.10-1 release. + + -- Zcash Company Fri, 23 Jun 2017 19:50:41 -0700 + +zcash (1.0.10) stable; urgency=medium + + * 1.0.10 release. + + -- Zcash Company Thu, 22 Jun 2017 15:13:04 +1200 + +zcash (1.0.9) stable; urgency=medium + + * 1.0.9 release. + + -- Zcash Company Wed, 24 May 2017 12:51:06 -0700 + +zcash (1.0.8+1) jessie; urgency=high + + * 1.0.8-1 release. + + -- Zcash Company Thu, 13 Apr 2017 20:20:37 -0700 + zcash (1.0.8) jessie; urgency=medium * 1.0.8 release. diff --git a/contrib/debian/copyright b/contrib/debian/copyright index aea954e07..3fbaa848b 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -38,10 +38,6 @@ Files: depends/sources/openssl-*.tar.gz Copyright: 1998-2016 The OpenSSL Project and 1995-1998 Eric Young License: OpenSSL+SSLeay -Files: depends/sources/miniupnpc-*.tar.gz -Copyright: 2005-2016 Thomas BERNARD -License: BSD-3clause - Files: depends/sources/zeromq-*.tar.gz Copyright: 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. @@ -59,6 +55,18 @@ Files: depends/sources/google*.tar.gz Copyright: 2008 Google Inc. License: BSD-3clause-Google +Files: depends/sources/qpid-proton-*.tar.gz +Copyright: 2012-2017 The Apache Software Foundation +License: Apache-Qpid-Proton-with-BSD-Subcomponents + +Files: src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 +Copyright: 2008 Don Anderson +License: GNU-All-permissive-License + +Files: src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 +Copyright: 2008 Paolo Bonzini +License: GNU-All-permissive-License + License: Boost-Software-License-1.0 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by @@ -1091,3 +1099,226 @@ License: LGPL-with-ZeroMQ-exception Comment: You should have received a copy of the GNU General Public License along with this program. If not, see . + +License: Apache-Qpid-Proton-with-BSD-Subcomponents + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + . + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + . + 1. Definitions. + . + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + . + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + . + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + . + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + . + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + . + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + . + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + . + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + . + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + . + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + . + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + . + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + . + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + . + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + . + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + . + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + . + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + . + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + . + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + . + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + . + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + . + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + . + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + . + END OF TERMS AND CONDITIONS + . + APPENDIX: How to apply the Apache License to your work. + . + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + . + Copyright [yyyy] [name of copyright owner] + . + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + . + PROTON SUBCOMPONENTS: + . + Proton includes freegetopt with a separate BSD license. Your use + of the source code for freegetopt is subject to the terms and + conditions of its license in examples/include/pncompat/internal/LICENSE. + . + The setup scripts for the python bindings include files derived by + PyZMQ and are licensed with a separate Modified BSD license. Use of + the source code in these setup files are subject to the terms and + conditions in the license: + proton-c/bindings/python/setuputils/PYZMQ_LICENSE.BSD. + +License: GNU-All-permissive-License + Copying and distribution of this file, with or without modification, are + permitted in any medium without royalty provided the copyright notice + and this notice are preserved. This file is offered as-is, without any + warranty. + diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index 301fea85c..bee8f3cc1 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -12,6 +12,7 @@ import os READELF_CMD = os.getenv('READELF', '/usr/bin/readelf') OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump') +NONFATAL = {'HIGH_ENTROPY_VA'} # checks which are non-fatal for now but only generate a warning def check_ELF_PIE(executable): ''' @@ -94,7 +95,7 @@ def check_ELF_RELRO(executable): raise IOError('Error opening file') for line in stdout.split(b'\n'): tokens = line.split() - if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2]): + if len(tokens)>1 and tokens[1] == b'(BIND_NOW)' or (len(tokens)>2 and tokens[1] == b'(FLAGS)' and b'BIND_NOW' in tokens[2:]): have_bindnow = True return have_gnu_relro and have_bindnow @@ -114,26 +115,50 @@ def check_ELF_Canary(executable): def get_PE_dll_characteristics(executable): ''' - Get PE DllCharacteristics bits + Get PE DllCharacteristics bits. + Returns a tuple (arch,bits) where arch is 'i386:x86-64' or 'i386' + and bits is the DllCharacteristics value. ''' p = subprocess.Popen([OBJDUMP_CMD, '-x', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) (stdout, stderr) = p.communicate() if p.returncode: raise IOError('Error opening file') + arch = '' + bits = 0 for line in stdout.split('\n'): tokens = line.split() + if len(tokens)>=2 and tokens[0] == 'architecture:': + arch = tokens[1].rstrip(',') if len(tokens)>=2 and tokens[0] == 'DllCharacteristics': - return int(tokens[1],16) - return 0 + bits = int(tokens[1],16) + return (arch,bits) +IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 +IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040 +IMAGE_DLL_CHARACTERISTICS_NX_COMPAT = 0x0100 -def check_PE_PIE(executable): +def check_PE_DYNAMIC_BASE(executable): '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' - return bool(get_PE_dll_characteristics(executable) & 0x40) + (arch,bits) = get_PE_dll_characteristics(executable) + reqbits = IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE + return (bits & reqbits) == reqbits + +# On 64 bit, must support high-entropy 64-bit address space layout randomization in addition to DYNAMIC_BASE +# to have secure ASLR. +def check_PE_HIGH_ENTROPY_VA(executable): + '''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR''' + (arch,bits) = get_PE_dll_characteristics(executable) + if arch == 'i386:x86-64': + reqbits = IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA + else: # Unnecessary on 32-bit + assert(arch == 'i386') + reqbits = 0 + return (bits & reqbits) == reqbits def check_PE_NX(executable): '''NX: DllCharacteristics bit 0x100 signifies nxcompat (DEP)''' - return bool(get_PE_dll_characteristics(executable) & 0x100) + (arch,bits) = get_PE_dll_characteristics(executable) + return (bits & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT) == IMAGE_DLL_CHARACTERISTICS_NX_COMPAT CHECKS = { 'ELF': [ @@ -143,7 +168,8 @@ CHECKS = { ('Canary', check_ELF_Canary) ], 'PE': [ - ('PIE', check_PE_PIE), + ('DYNAMIC_BASE', check_PE_DYNAMIC_BASE), + ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_PE_NX) ] } @@ -168,12 +194,18 @@ if __name__ == '__main__': continue failed = [] + warning = [] for (name, func) in CHECKS[etype]: if not func(filename): - failed.append(name) + if name in NONFATAL: + warning.append(name) + else: + failed.append(name) if failed: print('%s: failed %s' % (filename, ' '.join(failed))) retval = 1 + if warning: + print('%s: warning %s' % (filename, ' '.join(warning))) except IOError: print('%s: cannot open' % filename) retval = 1 diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 90c21be45..de9e405e1 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "zcash-1.0.8" +name: "zcash-1.0.15" enable_cache: true distro: "debian" suites: @@ -85,7 +85,7 @@ script: | BASEPREFIX=`pwd`/depends # Build dependencies for each host for i in $HOSTS; do - make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + NO_PROTON="x" make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" done # Faketime for binaries diff --git a/contrib/komodo-cli.bash-completion b/contrib/komodo-cli.bash-completion new file mode 100644 index 000000000..c1a9930ef --- /dev/null +++ b/contrib/komodo-cli.bash-completion @@ -0,0 +1,161 @@ +# bash programmable completion for komodo-cli(1) +# Copyright (c) 2012-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# call $komodo-cli for RPC +_komodo_rpc() { + # determine already specified args necessary for RPC + local rpcargs=() + for i in ${COMP_LINE}; do + case "$i" in + -conf=*|-datadir=*|-regtest|-rpc*|-testnet) + rpcargs=( "${rpcargs[@]}" "$i" ) + ;; + esac + done + $komodo_cli "${rpcargs[@]}" "$@" +} + +# Add wallet accounts to COMPREPLY +_komodo_accounts() { + local accounts + # Accounts are deprecated in komodo + #accounts=$(_komodo_rpc listaccounts | awk -F '"' '{ print $2 }') + accounts="\\\"\\\"" + COMPREPLY=( "${COMPREPLY[@]}" $( compgen -W "$accounts" -- "$cur" ) ) +} + +_komodo_cli() { + local cur prev words=() cword + local komodo_cli + + # save and use original argument to invoke komodo-cli for -help, help and RPC + # as komodo-cli might not be in $PATH + komodo_cli="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + if ((cword > 5)); then + case ${words[cword-5]} in + sendtoaddress) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 4)); then + case ${words[cword-4]} in + importaddress|listtransactions|setban) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + signrawtransaction) + COMPREPLY=( $( compgen -W "ALL NONE SINGLE ALL|ANYONECANPAY NONE|ANYONECANPAY SINGLE|ANYONECANPAY" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 3)); then + case ${words[cword-3]} in + addmultisigaddress) + _komodo_accounts + return 0 + ;; + getbalance|gettxout|importaddress|importpubkey|importprivkey|listreceivedbyaccount|listreceivedbyaddress|listsinceblock) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + esac + fi + + if ((cword > 2)); then + case ${words[cword-2]} in + addnode) + COMPREPLY=( $( compgen -W "add remove onetry" -- "$cur" ) ) + return 0 + ;; + setban) + COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) + return 0 + ;; + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; +# KMD does not have viewing keys, yet +# z_importkey|z_importviewingkey) +# COMPREPLY=( $( compgen -W "yes no whenkeyisnew" -- "$cur" ) ) +# return 0 +# ;; + move|setaccount) + _komodo_accounts + return 0 + ;; + esac + fi + + case "$prev" in + backupwallet|dumpwallet|importwallet|z_exportwallet|z_importwallet) + _filedir + return 0 + ;; + getaddednodeinfo|getrawmempool|lockunspent|setgenerate) + COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) + return 0 + ;; + getaccountaddress|getaddressesbyaccount|getbalance|getnewaddress|getreceivedbyaccount|listtransactions|move|sendfrom|sendmany) + _komodo_accounts + return 0 + ;; + esac + + case "$cur" in + -conf=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + local helpopts commands + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + helpopts=$($komodo_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + fi + + # only parse help if senseful + if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then + commands=$(_komodo_rpc help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }') + fi + + COMPREPLY=( $( compgen -W "$helpopts $commands" -- "$cur" ) ) + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _komodo_cli komodo-cli + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/bitcoin-tx.bash-completion b/contrib/komodo-tx.bash-completion similarity index 74% rename from contrib/bitcoin-tx.bash-completion rename to contrib/komodo-tx.bash-completion index 0206eba74..69e259381 100644 --- a/contrib/bitcoin-tx.bash-completion +++ b/contrib/komodo-tx.bash-completion @@ -1,15 +1,15 @@ -# bash programmable completion for bitcoin-tx(1) +# bash programmable completion for komodo-tx(1) # Copyright (c) 2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -_bitcoin_tx() { +_komodo_tx() { local cur prev words=() cword - local bitcoin_tx + local komodo_tx - # save and use original argument to invoke bitcoin-tx for -help + # save and use original argument to invoke komodo-tx for -help # it might not be in $PATH - bitcoin_tx="$1" + komodo_tx="$1" COMPREPLY=() _get_comp_words_by_ref -n =: cur prev words cword @@ -27,15 +27,15 @@ _bitcoin_tx() { if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then # only options (or an uncompletable hex-string) allowed - # parse bitcoin-tx -help for options + # parse komodo-tx -help for options local helpopts - helpopts=$($bitcoin_tx -help | sed -e '/^ -/ p' -e d ) + helpopts=$($komodo_tx -help | sed -e '/^ -/ p' -e d ) COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) else # only commands are allowed # parse -help for commands local helpcmds - helpcmds=$($bitcoin_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + helpcmds=$($komodo_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) fi @@ -46,7 +46,7 @@ _bitcoin_tx() { return 0 } && -complete -F _bitcoin_tx zcash-tx +complete -F _komodo_tx komodo-tx # Local variables: # mode: shell-script diff --git a/contrib/komodod.bash-completion b/contrib/komodod.bash-completion new file mode 100644 index 000000000..4c1ec516f --- /dev/null +++ b/contrib/komodod.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for komodod(1) +# Copyright (c) 2012-2017 The Bitcoin Core developers +# Copyright (c) 2016-2017 The komodo developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +_komodod() { + local cur prev words=() cword + local komodod + + # save and use original argument to invoke komodod for -help + # it might not be in $PATH + komodod="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n = cur prev words cword + + case "$cur" in + -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) + cur="${cur#*=}" + _filedir + return 0 + ;; + -datadir=*|-exportdir=*) + cur="${cur#*=}" + _filedir -d + return 0 + ;; + -*=*) # prevent nonsense completions + return 0 + ;; + *) + + # only parse -help if senseful + if [[ -z "$cur" || "$cur" =~ ^- ]]; then + local helpopts + helpopts=$($komodod -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + return 0 + ;; + esac +} && +complete -F _komodod komodod + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/bitcoin-cli.bash-completion b/contrib/zcash-cli.bash-completion similarity index 88% rename from contrib/bitcoin-cli.bash-completion rename to contrib/zcash-cli.bash-completion index f2a44d232..37fa1d116 100644 --- a/contrib/bitcoin-cli.bash-completion +++ b/contrib/zcash-cli.bash-completion @@ -1,9 +1,9 @@ -# bash programmable completion for bitcoin-cli(1) +# bash programmable completion for zcash-cli(1) # Copyright (c) 2012-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# call $bitcoin-cli for RPC +# call $zcash-cli for RPC _zcash_rpc() { # determine already specified args necessary for RPC local rpcargs=() @@ -14,7 +14,7 @@ _zcash_rpc() { ;; esac done - $bitcoin_cli "${rpcargs[@]}" "$@" + $zcash_cli "${rpcargs[@]}" "$@" } # Add wallet accounts to COMPREPLY @@ -28,11 +28,11 @@ _zcash_accounts() { _zcash_cli() { local cur prev words=() cword - local bitcoin_cli + local zcash_cli - # save and use original argument to invoke bitcoin-cli for -help, help and RPC - # as bitcoin-cli might not be in $PATH - bitcoin_cli="$1" + # save and use original argument to invoke zcash-cli for -help, help and RPC + # as zcash-cli might not be in $PATH + zcash_cli="$1" COMPREPLY=() _get_comp_words_by_ref -n = cur prev words cword @@ -82,10 +82,14 @@ _zcash_cli() { COMPREPLY=( $( compgen -W "add remove" -- "$cur" ) ) return 0 ;; - fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction|z_importkey) + fundrawtransaction|getblock|getblockheader|getmempoolancestors|getmempooldescendants|getrawtransaction|gettransaction|listaccounts|listreceivedbyaccount|listreceivedbyaddress|sendrawtransaction) COMPREPLY=( $( compgen -W "true false" -- "$cur" ) ) return 0 ;; + z_importkey|z_importviewingkey) + COMPREPLY=( $( compgen -W "yes no whenkeyisnew" -- "$cur" ) ) + return 0 + ;; move|setaccount) _zcash_accounts return 0 @@ -127,7 +131,7 @@ _zcash_cli() { # only parse -help if senseful if [[ -z "$cur" || "$cur" =~ ^- ]]; then - helpopts=$($bitcoin_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + helpopts=$($zcash_cli -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) fi # only parse help if senseful diff --git a/contrib/zcash-tx.bash-completion b/contrib/zcash-tx.bash-completion new file mode 100644 index 000000000..e808f93cb --- /dev/null +++ b/contrib/zcash-tx.bash-completion @@ -0,0 +1,57 @@ +# bash programmable completion for zcash-tx(1) +# Copyright (c) 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +_zcash_tx() { + local cur prev words=() cword + local zcash_tx + + # save and use original argument to invoke zcash-tx for -help + # it might not be in $PATH + zcash_tx="$1" + + COMPREPLY=() + _get_comp_words_by_ref -n =: cur prev words cword + + case "$cur" in + load=*:*) + cur="${cur#load=*:}" + _filedir + return 0 + ;; + *=*) # prevent attempts to complete other arguments + return 0 + ;; + esac + + if [[ "$cword" == 1 || ( "$prev" != "-create" && "$prev" == -* ) ]]; then + # only options (or an uncompletable hex-string) allowed + # parse zcash-tx -help for options + local helpopts + helpopts=$($zcash_tx -help | sed -e '/^ -/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) + else + # only commands are allowed + # parse -help for commands + local helpcmds + helpcmds=$($zcash_tx -help | sed -e '1,/Commands:/d' -e 's/=.*/=/' -e '/^ [a-z]/ p' -e d ) + COMPREPLY=( $( compgen -W "$helpcmds" -- "$cur" ) ) + fi + + # Prevent space if an argument is desired + if [[ $COMPREPLY == *= ]]; then + compopt -o nospace + fi + + return 0 +} && +complete -F _zcash_tx zcash-tx + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh diff --git a/contrib/bitcoind.bash-completion b/contrib/zcashd.bash-completion similarity index 89% rename from contrib/bitcoind.bash-completion rename to contrib/zcashd.bash-completion index 104365024..65f07cd80 100644 --- a/contrib/bitcoind.bash-completion +++ b/contrib/zcashd.bash-completion @@ -6,11 +6,11 @@ _zcashd() { local cur prev words=() cword - local bitcoind + local zcashd # save and use original argument to invoke zcashd for -help # it might not be in $PATH - bitcoind="$1" + zcashd="$1" COMPREPLY=() _get_comp_words_by_ref -n = cur prev words cword @@ -21,7 +21,7 @@ _zcashd() { _filedir return 0 ;; - -datadir=*) + -datadir=*|-exportdir=*) cur="${cur#*=}" _filedir -d return 0 @@ -34,7 +34,7 @@ _zcashd() { # only parse -help if senseful if [[ -z "$cur" || "$cur" =~ ^- ]]; then local helpopts - helpopts=$($bitcoind -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) + helpopts=$($zcashd -help 2>&1 | awk '$1 ~ /^-/ { sub(/=.*/, "="); print $1 }' ) COMPREPLY=( $( compgen -W "$helpopts" -- "$cur" ) ) fi diff --git a/depends/Makefile b/depends/Makefile index b6beea3d4..472d87885 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -74,9 +74,9 @@ include packages/packages.mk rust_packages_$(NO_RUST) = $(rust_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) -upnp_packages_$(NO_UPNP) = $(upnp_packages) +proton_packages_$(NO_PROTON) = $(proton_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages_) $(wallet_packages_) $(upnp_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(rust_packages_) $(proton_packages_) $(wallet_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) all_packages = $(packages) $(native_packages) @@ -113,7 +113,6 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ -e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ - -e 's|@no_upnp@|$(NO_UPNP)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ diff --git a/depends/README.md b/depends/README.md index 663d49584..41898de1a 100644 --- a/depends/README.md +++ b/depends/README.md @@ -33,9 +33,8 @@ The following can be set when running make: make FOO=bar SOURCES_PATH: downloaded sources will be placed here BASE_CACHE: built packages will be placed here SDK_PATH: Path where sdk's can be found (used by OSX) - FALLBACK_DOWNLOAD_PATH: If a source file can't be fetched, try here before giving up + PRIORITY_DOWNLOAD_PATH: Try fetching source files from here before using their own URLs NO_WALLET: Don't download/build/cache libs needed to enable the wallet - NO_UPNP: Don't download/build/cache packages needed for enabling upnp DEBUG: disable some optimizations and enable more runtime checking If some packages are not built, for example `make NO_WALLET=1`, the appropriate diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 0028d3f6f..b986aecec 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -7,11 +7,19 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -f -o +#<<<<<<< HEAD +##build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -f -o #darwin host on darwin builder. overrides darwin host preferences. -darwin_CC= gcc-5 -darwin_CXX= g++-5 +#darwin_CC= gcc-5 +#darwin_CXX= g++-5 +#======= +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +#darwin host on darwin builder. overrides darwin host preferences. +darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) +darwin_CXX:=$(shell xcrun -f clang++) -mmacosx-version-min=$(OSX_MIN_VERSION) -stdlib=libc++ +#>>>>>>> zcash/master darwin_AR:=$(shell xcrun -f ar) darwin_RANLIB:=$(shell xcrun -f ranlib) darwin_STRIP:=$(shell xcrun -f strip) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index 98d0e9de3..b03f42401 100644 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depends/config.site.in b/depends/config.site.in index 153330360..8cdbcd2e4 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -7,20 +7,12 @@ ac_tool_prefix=${host_alias}- if test -z $with_boost; then with_boost=$depends_prefix fi -# Disable comparison utility (#592) -#if test -z $with_comparison_tool; then -# with_comparison_tool=$depends_prefix/native/share/BitcoindComparisonTool_jar/BitcoindComparisonTool.jar -#fi if test -z $enable_wallet && test -n "@no_wallet@"; then enable_wallet=no fi -if test -z $with_miniupnpc && test -n "@no_upnp@"; then - with_miniupnpc=no -fi - if test x@host_os@ = xdarwin; then BREW=no PORT=no diff --git a/depends/funcs.mk b/depends/funcs.mk index addd1a510..df305a74a 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -22,7 +22,8 @@ endef define fetch_file (test -f $$($(1)_source_dir)/$(4) || \ ( mkdir -p $$($(1)_download_dir) && echo Fetching $(1)... && \ - ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" ) && \ + ( $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(PRIORITY_DOWNLOAD_PATH)/$(4)" || \ + $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" ) && \ echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \ $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \ mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \ @@ -42,6 +43,10 @@ $(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_ty $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) final_build_id_long+=$($(package)_build_id_long) +#override platform specific files and hashes +$(eval $(1)_file_name=$(if $($(1)_file_name_$(host_os)),$($(1)_file_name_$(host_os)),$($(1)_file_name))) +$(eval $(1)_sha256_hash=$(if $($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash_$(host_os)),$($(1)_sha256_hash))) + #compute package-specific paths $(1)_build_subdir?=. $(1)_download_file?=$($(1)_file_name) @@ -124,9 +129,9 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$( $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig -$(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) +$(1)_config_env+=PATH="$(build_prefix)/bin:$(PATH)" +$(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)" +$(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)" $(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" ifneq ($($(1)_nm),) diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 52c0003e4..4f1748657 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,9 +1,15 @@ -OSX_MIN_VERSION=10.7 -OSX_SDK_VERSION=10.9 +OSX_MIN_VERSION=10.8 +OSX_SDK_VERSION=10.11 OSX_SDK=$(SDK_PATH)/MacOSX$(OSX_SDK_VERSION).sdk -LD64_VERSION=241.9 -darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +#<<<<<<< HEAD +#LD64_VERSION=241.9 +#darwin_CC=gcc-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +#darwin_CXX=g++-5 -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +#======= +LD64_VERSION=253.9 +darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) +darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ +#>>>>>>> zcash/master darwin_CFLAGS=-pipe darwin_CXXFLAGS=$(darwin_CFLAGS) diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index 7babd175a..3ff5a7bd9 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -9,6 +9,12 @@ define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic +$(package)_cxxflags=-std=c++11 +endef + +define $(package)_preprocess_cmds + sed -i.old 's/__atomic_compare_exchange\\(/__atomic_compare_exchange_db(/' src/dbinc/atomic.h && \ + sed -i.old 's/atomic_init/atomic_init_db/' src/dbinc/atomic.h src/mp/mp_region.c src/mp/mp_mvcc.c src/mp/mp_fget.c src/mutex/mut_method.c src/mutex/mut_tas.c endef define $(package)_config_cmds diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 679faacde..099993a62 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -9,7 +9,7 @@ define $(package)_set_vars $(package)_config_opts_release=variant=release $(package)_config_opts_debug=variant=debug $(package)_config_opts=--layout=tagged --build-type=complete --user-config=user-config.jam -$(package)_config_opts+=threading=multi link=static -sNO_BZIP2=1 -sNO_ZLIB=1 +$(package)_config_opts+=link=static -sNO_BZIP2=1 -sNO_ZLIB=1 $(package)_config_opts_linux=threadapi=pthread runtime-link=shared $(package)_config_opts_darwin=--toolset=gcc threadapi=pthread runtime-link=shared $(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static @@ -21,7 +21,7 @@ $(package)_archiver_$(host_os)=$($(package)_ar) $(package)_toolset_darwin=gcc $(package)_archiver_darwin=$($(package)_ar) $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags=-fvisibility=hidden +$(package)_cxxflags=-std=c++11 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC endef diff --git a/depends/packages/googletest.mk b/depends/packages/googletest.mk index 652e97aaa..b9fa3e7e8 100644 --- a/depends/packages/googletest.mk +++ b/depends/packages/googletest.mk @@ -1,9 +1,9 @@ package=googletest -$(package)_version=1.7.0 +$(package)_version=1.8.0 $(package)_download_path=https://github.com/google/$(package)/archive/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_download_file=release-$($(package)_version).tar.gz -$(package)_sha256_hash=f73a6546fdf9fce9ff93a5015e0333a8af3062a152a9ad6bcb772c96687016cc +$(package)_sha256_hash=58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 ifeq ($(build_os),darwin) define $(package)_set_vars @@ -19,11 +19,15 @@ endef else $(package)_install=install define $(package)_build_cmds - $(MAKE) -C make CXXFLAGS=-fPIC gtest.a + $(MAKE) -C googlemock/make CXXFLAGS=-fPIC gmock.a && \ + $(MAKE) -C googletest/make CXXFLAGS=-fPIC gtest.a endef endif define $(package)_stage_cmds - $($(package)_install) -D ./make/gtest.a $($(package)_staging_dir)$(host_prefix)/lib/libgtest.a && \ - cp -a ./include $($(package)_staging_dir)$(host_prefix)/include + mkdir -p $($(package)_staging_dir)$(host_prefix)/lib && \ + install ./googlemock/make/gmock.a $($(package)_staging_dir)$(host_prefix)/lib/libgmock.a && \ + install ./googletest/make/gtest.a $($(package)_staging_dir)$(host_prefix)/lib/libgtest.a && \ + cp -a ./googlemock/include $($(package)_staging_dir)$(host_prefix)/ && \ + cp -a ./googletest/include $($(package)_staging_dir)$(host_prefix)/ endef diff --git a/depends/packages/libsodium.mk b/depends/packages/libsodium.mk index 371225014..91e6f27b7 100644 --- a/depends/packages/libsodium.mk +++ b/depends/packages/libsodium.mk @@ -1,8 +1,15 @@ package=libsodium -$(package)_version=1.0.11 -$(package)_download_path=https://supernetorg.bintray.com/misc -$(package)_file_name=libsodium-1.0.11.tar.gz -$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765 +#<<<<<<< HEAD +#$(package)_version=1.0.11 +#$(package)_download_path=https://supernetorg.bintray.com/misc +#$(package)_file_name=libsodium-1.0.11.tar.gz +#$(package)_sha256_hash=a14549db3c49f6ae2170cbbf4664bd48ace50681045e8dbea7c8d9fb96f9c765 +#======= +$(package)_version=1.0.15 +$(package)_download_path=https://download.libsodium.org/libsodium/releases/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=fb6a9e879a2f674592e4328c5d9f79f082405ee4bb05cb6e679b90afe9e178f4 +#>>>>>>> zcash/master $(package)_dependencies= $(package)_config_opts= diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk deleted file mode 100644 index 0d8efbc3f..000000000 --- a/depends/packages/miniupnpc.mk +++ /dev/null @@ -1,32 +0,0 @@ -package=miniupnpc -$(package)_version=2.0 -$(package)_download_path=http://miniupnp.free.fr/files -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=d434ceb8986efbe199c5ca53f90ed53eab290b1e6d0530b717eb6fa49d61f93b -$(package)_patches=fix-solaris-compilation.patch strlen-before-memcmp.patch patch-strlen-patch.patch - -define $(package)_set_vars -$(package)_build_opts=CC="$($(package)_cc)" -$(package)_build_opts_darwin=OS=Darwin -$(package)_build_opts_mingw32=-f Makefile.mingw -$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" -endef - -define $(package)_preprocess_cmds - mkdir dll && \ - sed -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"$($(package)_version)\"|' -e 's|OS/version|$(host)|' miniupnpcstrings.h.in > miniupnpcstrings.h && \ - sed -i.old "s|miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings|miniupnpcstrings.h: miniupnpcstrings.h.in|" Makefile.mingw && \ - patch -p2 < $($(package)_patch_dir)/fix-solaris-compilation.patch && \ - patch -p2 < $($(package)_patch_dir)/strlen-before-memcmp.patch && \ - patch -p2 < $($(package)_patch_dir)/patch-strlen-patch.patch -endef - -define $(package)_build_cmds - $(MAKE) libminiupnpc.a $($(package)_build_opts) -endef - -define $(package)_stage_cmds - mkdir -p $($(package)_staging_prefix_dir)/include/miniupnpc $($(package)_staging_prefix_dir)/lib &&\ - install *.h $($(package)_staging_prefix_dir)/include/miniupnpc &&\ - install libminiupnpc.a $($(package)_staging_prefix_dir)/lib -endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index fe19c6734..f80cd6d25 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -85,6 +85,7 @@ $(package)_config_opts_arm_linux=linux-generic32 $(package)_config_opts_aarch64_linux=linux-generic64 $(package)_config_opts_mipsel_linux=linux-generic32 $(package)_config_opts_mips_linux=linux-generic32 +$(package)_config_opts_powerpc_linux=linux-generic32 $(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc $(package)_config_opts_x86_64_mingw32=mingw64 $(package)_config_opts_i686_mingw32=mingw diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index b1951431a..8475ec7d5 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,15 +1,13 @@ rust_packages := rust librustzcash -zcash_packages := libsnark libgmp libsodium +proton_packages := proton +zcash_packages := libgmp libsodium ifeq ($(host_os),linux) - packages := boost openssl libevent zeromq $(zcash_packages) googletest googlemock + packages := boost openssl libevent zeromq $(zcash_packages) #googletest googlemock else - packages := boost openssl libevent zeromq $(zcash_packages) googletest googlemock libcurl + packages := boost openssl libevent zeromq $(zcash_packages) libcurl # googletest googlemock libcurl endif - native_packages := native_ccache wallet_packages=bdb - -upnp_packages=miniupnpc diff --git a/depends/packages/proton.mk b/depends/packages/proton.mk new file mode 100644 index 000000000..aa49f380f --- /dev/null +++ b/depends/packages/proton.mk @@ -0,0 +1,24 @@ +package=proton +$(package)_version=0.17.0 +$(package)_download_path=http://apache.cs.utah.edu/qpid/proton/$($(package)_version) +$(package)_file_name=qpid-proton-$($(package)_version).tar.gz +$(package)_sha256_hash=6ffd26d3d0e495bfdb5d9fefc5349954e6105ea18cc4bb191161d27742c5a01a +$(package)_patches=minimal-build.patch + +define $(package)_preprocess_cmds + patch -p1 < $($(package)_patch_dir)/minimal-build.patch && \ + mkdir -p build/proton-c/src +endef + +define $(package)_config_cmds + cd build; cmake .. -DCMAKE_CXX_STANDARD=11 -DCMAKE_INSTALL_PREFIX=/ -DSYSINSTALL_BINDINGS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DBUILD_PYTHON=OFF -DBUILD_PHP=OFF -DBUILD_JAVA=OFF -DBUILD_PERL=OFF -DBUILD_RUBY=OFF -DBUILD_JAVASCRIPT=OFF -DBUILD_GO=OFF +endef + +define $(package)_build_cmds + cd build; $(MAKE) VERBOSE=1 +endef + +define $(package)_stage_cmds + cd build; $(MAKE) VERBOSE=1 DESTDIR=$($(package)_staging_prefix_dir) install +endef + diff --git a/depends/packages/rust.mk b/depends/packages/rust.mk index 2e3f0b204..eb28c76d1 100644 --- a/depends/packages/rust.mk +++ b/depends/packages/rust.mk @@ -1,16 +1,23 @@ package=rust $(package)_version=1.16.0 $(package)_download_path=https://static.rust-lang.org/dist -ifeq ($(build_os),darwin) -$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz -$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 -else ifeq ($(host_os),mingw32) -$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz -$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 -else -$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz -$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd -endif +#<<<<<<< HEAD +#ifeq ($(build_os),darwin) +#$(package)_file_name=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +#$(package)_sha256_hash=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 +#else ifeq ($(host_os),mingw32) +#$(package)_file_name=rust-$($(package)_version)-i686-unknown-linux-gnu.tar.gz +#$(package)_sha256_hash=b5859161ebb182d3b75fa14a5741e5de87b088146fb0ef4a30f3b2439c6179c5 +#else +#$(package)_file_name=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz +#$(package)_sha256_hash=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd +#endif +#======= +$(package)_file_name_linux=rust-$($(package)_version)-x86_64-unknown-linux-gnu.tar.gz +$(package)_sha256_hash_linux=48621912c242753ba37cad5145df375eeba41c81079df46f93ffb4896542e8fd +$(package)_file_name_darwin=rust-$($(package)_version)-x86_64-apple-darwin.tar.gz +$(package)_sha256_hash_darwin=2d08259ee038d3a2c77a93f1a31fc59e7a1d6d1bbfcba3dba3c8213b2e5d1926 +#>>>>>>> zcash/master define $(package)_stage_cmds ./install.sh --destdir=$($(package)_staging_dir) --prefix=$(host_prefix)/native --disable-ldconfig diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 8d324a3f4..850cce778 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -22,6 +22,7 @@ $(package)_sha256_hash=27d1e82a099228ee85a7ddb2260f40830212402c605a4a10b5e5498a7 define $(package)_set_vars $(package)_config_opts=--without-documentation --disable-shared --disable-curve $(package)_config_opts_linux=--with-pic + $(package)_cxxflags=-std=c++11 endef endif diff --git a/depends/patches/miniupnpc/fix-solaris-compilation.patch b/depends/patches/miniupnpc/fix-solaris-compilation.patch deleted file mode 100644 index 30eb3b106..000000000 --- a/depends/patches/miniupnpc/fix-solaris-compilation.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 71ce1d6dfa5424f8fe8633e23494c7638ea2c79e Mon Sep 17 00:00:00 2001 -From: Thomas Bernard -Date: Thu, 10 Nov 2016 21:55:33 +0100 -Subject: [PATCH] fix for Solaris 11 compilation - -see #216 ---- - miniupnpc/Makefile | 2 ++ - miniupnpc/minissdpc.c | 3 +++ - 2 files changed, 5 insertions(+) - -diff --git a/miniupnpc/Makefile b/miniupnpc/Makefile -index 5c23000..72cdc0f 100644 ---- a/miniupnpc/Makefile -+++ b/miniupnpc/Makefile -@@ -43,10 +43,12 @@ CFLAGS += -D_NETBSD_SOURCE - endif - ifneq ($(OS), FreeBSD) - ifneq ($(OS), Darwin) -+ifneq ($(OS), SunOS) - #CFLAGS += -D_POSIX_C_SOURCE=200112L - CFLAGS += -D_XOPEN_SOURCE=600 - endif - endif -+endif - #CFLAGS += -ansi - # -DNO_GETADDRINFO - INSTALL = install -diff --git a/miniupnpc/minissdpc.c b/miniupnpc/minissdpc.c -index f200f07..263160e 100644 ---- a/miniupnpc/minissdpc.c -+++ b/miniupnpc/minissdpc.c -@@ -73,6 +73,9 @@ struct sockaddr_un { - - #if !defined(HAS_IP_MREQN) && !defined(_WIN32) - #include -+#if defined(__sun) -+#include -+#endif - #endif - - #if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) diff --git a/depends/patches/miniupnpc/patch-strlen-patch.patch b/depends/patches/miniupnpc/patch-strlen-patch.patch deleted file mode 100644 index df7140234..000000000 --- a/depends/patches/miniupnpc/patch-strlen-patch.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0aa7c46227acd8ddb135c577674ad454bf2fba86 Mon Sep 17 00:00:00 2001 -From: Thomas Bernard -Date: Fri, 11 Nov 2016 17:53:21 +0100 -Subject: [PATCH] remove unsigned/signed comparison - ---- - miniupnpc/portlistingparse.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/miniupnpc/portlistingparse.c b/miniupnpc/portlistingparse.c -index 1bed763..07f3f87 100644 ---- a/miniupnpc/portlistingparse.c -+++ b/miniupnpc/portlistingparse.c -@@ -55,7 +55,7 @@ startelt(void * d, const char * name, int l) - pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { -- if(strlen(elements[i].str) == l && memcmp(name, elements[i].str, l) == 0) -+ if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) - { - pdata->curelt = elements[i].code; - break; diff --git a/depends/patches/miniupnpc/strlen-before-memcmp.patch b/depends/patches/miniupnpc/strlen-before-memcmp.patch deleted file mode 100644 index 8e1f2005e..000000000 --- a/depends/patches/miniupnpc/strlen-before-memcmp.patch +++ /dev/null @@ -1,23 +0,0 @@ -From ec1c49bb0cd5e448e6f0adee7de3a831c4869bdd Mon Sep 17 00:00:00 2001 -From: Thomas Bernard -Date: Fri, 11 Nov 2016 17:24:39 +0100 -Subject: [PATCH] check strlen before memcmp - -1st try to fix #220 ---- - miniupnpc/portlistingparse.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/miniupnpc/portlistingparse.c b/miniupnpc/portlistingparse.c -index 0e09278..1bed763 100644 ---- a/miniupnpc/portlistingparse.c -+++ b/miniupnpc/portlistingparse.c -@@ -55,7 +55,7 @@ startelt(void * d, const char * name, int l) - pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { -- if(memcmp(name, elements[i].str, l) == 0) -+ if(strlen(elements[i].str) == l && memcmp(name, elements[i].str, l) == 0) - { - pdata->curelt = elements[i].code; - break; diff --git a/depends/patches/proton/minimal-build.patch b/depends/patches/proton/minimal-build.patch new file mode 100644 index 000000000..90588929f --- /dev/null +++ b/depends/patches/proton/minimal-build.patch @@ -0,0 +1,288 @@ +From 03f5fc0826115edbfca468261b70c0daf627f488 Mon Sep 17 00:00:00 2001 +From: Simon +Date: Thu, 27 Apr 2017 17:15:59 -0700 +Subject: [PATCH] Enable C++11, build static library and cpp bindings with minimal dependencies. + +--- + CMakeLists.txt | 13 +++++++------ + examples/cpp/CMakeLists.txt | 1 + + proton-c/CMakeLists.txt | 32 +++++++++++++++---------------- + proton-c/bindings/CMakeLists.txt | 6 +++--- + proton-c/bindings/cpp/CMakeLists.txt | 24 +++++++++++------------ + proton-c/bindings/cpp/docs/CMakeLists.txt | 2 +- + proton-c/docs/api/CMakeLists.txt | 2 +- + 7 files changed, 41 insertions(+), 39 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index b538ffd..4a5e787 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -18,14 +18,15 @@ + # + cmake_minimum_required (VERSION 2.8.7) + ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + project (Proton C) + + # Enable C++ now for examples and bindings subdirectories, but make it optional. + enable_language(CXX OPTIONAL) + + # Enable testing +-enable_testing() +-include (CTest) ++#enable_testing() ++#include (CTest) + + # Pull in local cmake modules + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules/") +@@ -141,7 +142,7 @@ set (BINDINGS_DIR ${LIB_INSTALL_DIR}/proton/bindings) + + set (SYSINSTALL_BINDINGS OFF CACHE BOOL "If SYSINSTALL_BINDINGS is OFF then proton bindings will be installed underneath ${BINDINGS_DIR} and each user will need to modify their interpreter configuration to load the appropriate binding. If SYSINSTALL_BINDINGS is ON, then each language interpreter will be queried for the appropriate directory and proton bindings will be installed and available system wide with no additional per user configuration.") + +-set (BINDING_LANGS PERL PHP PYTHON RUBY) ++#set (BINDING_LANGS PERL PHP PYTHON RUBY) + + foreach (LANG ${BINDING_LANGS}) + set (SYSINSTALL_${LANG} OFF CACHE BOOL "Install ${LANG} bindings into interpreter specified location.") +@@ -156,10 +157,10 @@ set (PROTON_SHARE ${SHARE_INSTALL_DIR}/proton-${PN_VERSION}) + # End of variables used during install + + # Check for valgrind here so tests under proton-c/ and examples/ can use it. +-find_program(VALGRIND_EXE valgrind DOC "Location of the valgrind program") ++#find_program(VALGRIND_EXE valgrind DOC "Location of the valgrind program") + mark_as_advanced (VALGRIND_EXE) + +-option(ENABLE_VALGRIND "Use valgrind to detect run-time problems" ON) ++#option(ENABLE_VALGRIND "Use valgrind to detect run-time problems" ON) + if (ENABLE_VALGRIND) + if (NOT VALGRIND_EXE) + message(STATUS "Can't locate the valgrind command; no run-time error detection") +@@ -171,7 +172,7 @@ if (ENABLE_VALGRIND) + endif (ENABLE_VALGRIND) + + add_subdirectory(proton-c) +-add_subdirectory(examples) ++#add_subdirectory(examples) + + install (FILES LICENSE README.md + DESTINATION ${PROTON_SHARE}) +diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt +index 304d899..f4877b4 100644 +--- a/examples/cpp/CMakeLists.txt ++++ b/examples/cpp/CMakeLists.txt +@@ -17,6 +17,7 @@ + # under the License. + # + ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + find_package(ProtonCpp REQUIRED) + + include_directories(${ProtonCpp_INCLUDE_DIRS}) +diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt +index 8edb661..dc7b99c 100644 +--- a/proton-c/CMakeLists.txt ++++ b/proton-c/CMakeLists.txt +@@ -22,24 +22,24 @@ include(CheckSymbolExists) + + include(soversion.cmake) + +-add_custom_target(docs) +-add_custom_target(doc DEPENDS docs) ++#add_custom_target(docs) ++#add_custom_target(doc DEPENDS docs) + + # Set the default SSL/TLS implementation +-find_package(OpenSSL) ++#find_package(OpenSSL) + find_package(PythonInterp REQUIRED) +-find_package(SWIG) ++#find_package(SWIG) + # FindSwig.cmake "forgets" make its outputs advanced like a good citizen + mark_as_advanced(SWIG_DIR SWIG_EXECUTABLE SWIG_VERSION) + + # See if Cyrus SASL is available +-find_library(CYRUS_SASL_LIBRARY sasl2) +-find_path(CYRUS_SASL_INCLUDE_DIR sasl/sasl.h PATH_SUFFIXES include) +-find_package_handle_standard_args(CyrusSASL DEFAULT_MSG CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) ++#find_library(CYRUS_SASL_LIBRARY sasl2) ++#find_path(CYRUS_SASL_INCLUDE_DIR sasl/sasl.h PATH_SUFFIXES include) ++#find_package_handle_standard_args(CyrusSASL DEFAULT_MSG CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) + mark_as_advanced(CYRUS_SASL_LIBRARY CYRUS_SASL_INCLUDE_DIR) + + # Find saslpasswd2 executable to generate test config +-find_program(SASLPASSWD_EXE saslpasswd2 DOC "Program used to make SASL user db for testing") ++#find_program(SASLPASSWD_EXE saslpasswd2 DOC "Program used to make SASL user db for testing") + mark_as_advanced(SASLPASSWD_EXE) + + if(WIN32 AND NOT CYGWIN) +@@ -315,8 +315,8 @@ pn_absolute_install_dir(EXEC_PREFIX "." ${CMAKE_INSTALL_PREFIX}) + pn_absolute_install_dir(LIBDIR ${LIB_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}) + pn_absolute_install_dir(INCLUDEDIR ${INCLUDE_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}) + +-add_subdirectory(docs/api) +-add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c) ++#add_subdirectory(docs/api) ++#add_subdirectory(../tests/tools/apps/c ../tests/tools/apps/c) + + # for full source distribution: + set (qpid-proton-platform-all +@@ -507,7 +507,7 @@ if (BUILD_WITH_CXX) + endif (BUILD_WITH_CXX) + + add_library ( +- qpid-proton-core SHARED ++ qpid-proton-core STATIC + ${qpid-proton-core} + ${qpid-proton-layers} + ${qpid-proton-platform} +@@ -527,7 +527,7 @@ set_target_properties ( + ) + + add_library( +- qpid-proton SHARED ++ qpid-proton STATIC + # Proton Core + ${qpid-proton-core} + ${qpid-proton-layers} +@@ -629,7 +629,7 @@ install (FILES + + # c tests: + +-add_subdirectory(src/tests) ++#add_subdirectory(src/tests) + + if (CMAKE_SYSTEM_NAME STREQUAL Windows) + # No change needed for windows already use correct separator +@@ -712,7 +712,7 @@ if (BUILD_PYTHON) + + endif (BUILD_PYTHON) + +-find_program(RUBY_EXE "ruby") ++#find_program(RUBY_EXE "ruby") + if (RUBY_EXE AND BUILD_RUBY) + set (rb_root "${pn_test_root}/ruby") + set (rb_src "${CMAKE_CURRENT_SOURCE_DIR}/bindings/ruby") +@@ -751,8 +751,8 @@ if (RUBY_EXE AND BUILD_RUBY) + else (DEFAULT_RUBY_TESTING) + message(STATUS "Skipping Ruby tests: missing dependencies") + endif (DEFAULT_RUBY_TESTING) +-else (RUBY_EXE) +- message (STATUS "Cannot find ruby, skipping ruby tests") ++#else (RUBY_EXE) ++# message (STATUS "Cannot find ruby, skipping ruby tests") + endif() + + mark_as_advanced (RUBY_EXE RSPEC_EXE) +diff --git a/proton-c/bindings/CMakeLists.txt b/proton-c/bindings/CMakeLists.txt +index 6b88384..d1a50a5 100644 +--- a/proton-c/bindings/CMakeLists.txt ++++ b/proton-c/bindings/CMakeLists.txt +@@ -19,14 +19,14 @@ + + # Add bindings that do not require swig here - the directory name must be the same as the binding name + # See below for swig bindings +-set(BINDINGS javascript cpp go) ++set(BINDINGS cpp) + + # Prerequisites for javascript. + # + # It uses a C/C++ to JavaScript cross-compiler called emscripten (https://github.com/kripken/emscripten). Emscripten takes C/C++ + # and compiles it into a highly optimisable subset of JavaScript called asm.js (http://asmjs.org/) that can be + # aggressively optimised and run at near-native speed (usually between 1.5 to 10 times slower than native C/C++). +-find_package(Emscripten) ++#find_package(Emscripten) + if (EMSCRIPTEN_FOUND) + set (DEFAULT_JAVASCRIPT ON) + endif (EMSCRIPTEN_FOUND) +@@ -37,7 +37,7 @@ if (CMAKE_CXX_COMPILER) + endif (CMAKE_CXX_COMPILER) + + # Prerequisites for Go +-find_program(GO_EXE go) ++#find_program(GO_EXE go) + mark_as_advanced(GO_EXE) + if (GO_EXE) + if(WIN32) +diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt +index 0cc4024..796fe29 100644 +--- a/proton-c/bindings/cpp/CMakeLists.txt ++++ b/proton-c/bindings/cpp/CMakeLists.txt +@@ -16,7 +16,7 @@ + # specific language governing permissions and limitations + # under the License. + # +- ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + include(cpp.cmake) # Compiler checks + + include_directories( +@@ -89,7 +89,7 @@ set_source_files_properties ( + COMPILE_FLAGS "${LTO}" + ) + +-add_library(qpid-proton-cpp SHARED ${qpid-proton-cpp-source}) ++add_library(qpid-proton-cpp STATIC ${qpid-proton-cpp-source}) + + target_link_libraries (qpid-proton-cpp ${PLATFORM_LIBS} qpid-proton) + +@@ -120,8 +120,8 @@ endif (MSVC) + + install (DIRECTORY "include/proton" DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.hpp") + +-add_subdirectory(docs) +-add_subdirectory(${CMAKE_SOURCE_DIR}/tests/tools/apps/cpp ${CMAKE_BINARY_DIR}/tests/tools/apps/cpp) ++#add_subdirectory(docs) ++#add_subdirectory(${CMAKE_SOURCE_DIR}/tests/tools/apps/cpp ${CMAKE_BINARY_DIR}/tests/tools/apps/cpp) + + # Pkg config file + configure_file( +@@ -171,12 +171,12 @@ macro(add_cpp_test test) + endif () + endmacro(add_cpp_test) + +-add_cpp_test(codec_test) ++#add_cpp_test(codec_test) + #add_cpp_test(engine_test) +-add_cpp_test(thread_safe_test) +-add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) +-add_cpp_test(message_test) +-add_cpp_test(scalar_test) +-add_cpp_test(value_test) +-add_cpp_test(container_test) +-add_cpp_test(url_test) ++#add_cpp_test(thread_safe_test) ++#add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests) ++#add_cpp_test(message_test) ++#add_cpp_test(scalar_test) ++#add_cpp_test(value_test) ++#add_cpp_test(container_test) ++#add_cpp_test(url_test) +diff --git a/proton-c/bindings/cpp/docs/CMakeLists.txt b/proton-c/bindings/cpp/docs/CMakeLists.txt +index d512d15..8576867 100644 +--- a/proton-c/bindings/cpp/docs/CMakeLists.txt ++++ b/proton-c/bindings/cpp/docs/CMakeLists.txt +@@ -17,7 +17,7 @@ + # under the License. + # + +-find_package(Doxygen) ++#find_package(Doxygen) + + if (DOXYGEN_FOUND) + configure_file ( +diff --git a/proton-c/docs/api/CMakeLists.txt b/proton-c/docs/api/CMakeLists.txt +index 7756e48..71ebb93 100644 +--- a/proton-c/docs/api/CMakeLists.txt ++++ b/proton-c/docs/api/CMakeLists.txt +@@ -17,7 +17,7 @@ + # under the License. + # + +-find_package(Doxygen) ++#find_package(Doxygen) + if (DOXYGEN_FOUND) + configure_file (${CMAKE_CURRENT_SOURCE_DIR}/user.doxygen.in + ${CMAKE_CURRENT_BINARY_DIR}/user.doxygen) +-- +2.7.4 + diff --git a/doc/amqp.md b/doc/amqp.md new file mode 100644 index 000000000..f733fa514 --- /dev/null +++ b/doc/amqp.md @@ -0,0 +1,123 @@ +# Block and Transaction Broadcasting With AMQP 1.0 (Experimental Feature) + +[AMQP](https://www.amqp.org/) is an enterprise-level message queuing +protocol for the reliable passing of real-time data and business +transactions between applications. AMQP supports both broker and +brokerless messaging. AMQP 1.0 is an open standard and has been +ratified as ISO/IEC 19464. + +The Zcash daemon can be configured to act as a trusted "border +router", implementing the Zcash P2P protocol and relay, making +consensus decisions, maintaining the local blockchain database, +broadcasting locally generated transactions into the network, and +providing a queryable RPC interface to interact on a polled basis for +requesting blockchain related data. However, there exists only a +limited service to notify external software of events like the arrival +of new blocks or transactions. + +The AMQP facility implements a notification interface through a set +of specific notifiers. Currently there are notifiers that publish +blocks and transactions. This read-only facility requires only the +connection of a corresponding AMQP subscriber port in receiving +software. + +Currently the facility is not authenticated nor is there any two-way +protocol involvement. Therefore, subscribers should validate the +received data since it may be out of date, incomplete or even invalid. + +Because AMQP is message oriented, subscribers receive transactions +and blocks all-at-once and do not need to implement any sort of +buffering or reassembly. + +## Prerequisites + +The AMQP feature in Zcash requires [Qpid Proton](https://qpid.apache.org/proton/) +version 0.17 or newer, which you will need to install if you are not +using the depends system. Typically, it is packaged by distributions as +something like *libqpid-proton*. The C++ wrapper for AMQP *is* required. + +In order to run the example Python client scripts in contrib/ one must +also install *python-qpid-proton*, though this is not necessary for +daemon operation. + +## Enabling + +By default, the AMQP feature is automatically compiled in if the +necessary prerequisites are found. To disable, use --disable-proton +during the *configure* step of building zcashd: + + $ ./configure --disable-proton (other options) + +To actually enable operation, one must set the appropriate options on +the commandline or in the configuration file. + +## Usage + +AMQP support is currently an experimental feature, so you must pass +the option: + + -experimentalfeatures + +Currently, the following notifications are supported: + + -amqppubhashtx=address + -amqppubhashblock=address + -amqppubrawblock=address + -amqppubrawtx=address + +The address must be a valid AMQP address, where the same address can be +used in more than notification. Note that SSL and SASL addresses are +not currently supported. + +Launch zcashd like this: + + $ zcashd -amqppubhashtx=amqp://127.0.0.1:5672 + +Or this: + + $ zcashd -amqppubhashtx=amqp://127.0.0.1:5672 \ + -amqppubrawtx=amqp://127.0.0.1:5672 \ + -amqppubrawblock=amqp://127.0.0.1:5672 \ + -amqppubhashblock=amqp://127.0.0.1:5672 \ + -debug=amqp + +The debug category `amqp` enables AMQP-related logging. + +Each notification has a topic and body, where the header corresponds +to the notification type. For instance, for the notification `-amqpubhashtx` +the topic is `hashtx` (no null terminator) and the body is the hexadecimal +transaction hash (32 bytes). This transaction hash and the block hash +found in `hashblock` are in RPC byte order. + +These options can also be provided in zcash.conf. + +Please see `contrib/amqp/amqp_sub.py` for a working example of an +AMQP server listening for messages. + +## Remarks + +From the perspective of zcashd, the local end of an AMQP link is write-only. + +No information is broadcast that wasn't already received from the public +P2P network. + +No authentication or authorization is done on peers that zcashd connects +to; it is assumed that the AMQP link is exposed only to trusted entities, +using other means such as firewalling. + +TLS support may be added once OpenSSL has been removed from the Zcash +project and alternative TLS implementations have been evaluated. + +SASL support may be added in a future update for secure communication. + +Note that when the block chain tip changes, a reorganisation may occur +and just the tip will be notified. It is up to the subscriber to +retrieve the chain from the last known block to the new tip. + +At present, zcashd does not try to resend a notification if there was +a problem confirming receipt. Support for delivery guarantees such as +*at-least-once* and *exactly-once* will be added in in a future update. + +Currently, zcashd appends an up-counting sequence number to each notification +which allows listeners to detect lost notifications. + diff --git a/doc/authors.md b/doc/authors.md index f9fc63367..8f249b1c0 100644 --- a/doc/authors.md +++ b/doc/authors.md @@ -1,68 +1,93 @@ Zcash Contributors ================== -Jack Grigg (392) -Simon Liu (254) -Sean Bowe (185) -Daira Hopwood (80) +Jack Grigg (601) +Simon Liu (297) +Sean Bowe (193) +Daira Hopwood (102) +Wladimir J. van der Laan (71) Taylor Hornby (65) -Wladimir J. van der Laan (58) -Jonas Schnelli (48) -Jay Graber (47) +Jay Graber (61) +Nathan Wilcox (56) +Jonas Schnelli (49) Kevin Gallagher (38) -Cory Fields (15) -Pieter Wuille (14) -Nathan Wilcox (10) +Cory Fields (30) +Pieter Wuille (24) +syd (15) nomnombtc (9) -fanquake (5) -Paige Peterson (5) -MarcoFalke (5) +Paige Peterson (9) +Matt Corallo (9) +fanquake (8) +MarcoFalke (7) +Luke Dashjr (6) Johnathan Corgan (5) Gregory Maxwell (5) +Ariel Gabizon (5) +kozyilmaz (4) Philip Kaufmann (4) Peter Todd (4) Patrick Strateman (4) -Matt Corallo (4) Karl-Johan Alm (4) +Jorge Timón (4) Jeff Garzik (4) David Mercer (4) Daniel Cousens (4) lpescher (3) +Suhas Daftuar (3) Pavel Janík (3) +João Barbosa (3) +Ariel (3) Alfie John (3) +str4d (2) paveljanik (2) +kpcyrd (2) aniemerg (2) Scott (2) Robert C. Seacord (2) -Luke Dashjr (2) -João Barbosa (2) +Per Grön (2) +Pavel Vasin (2) Joe Turgeon (2) +Jason Davies (2) Jack Gavigan (2) ITH4Coinomia (2) Gavin Andresen (2) +Daniel Kraft (2) +Bjorn Hjortsberg (2) +Amgad Abdelhafez (2) zathras-crypto (1) unsystemizer (1) +practicalswift (1) mruddy (1) mrbandrews (1) kazcw (1) +jc (1) isle2983 (1) instagibbs (1) +emilrus (1) dexX7 (1) +daniel (1) calebogden (1) ayleph (1) Tom Ritter (1) Stephen (1) S. Matthew English (1) -Pavel Vasin (1) +Ross Nicoll (1) +René Nyffenegger (1) Paul Georgiou (1) Paragon Initiative Enterprises, LLC (1) +Nicolas DORIER (1) Nathaniel Mahieu (1) Murilo Santana (1) +Maxwell Gubler (1) Matt Quinn (1) +Mark Friedenbach (1) +Marius Kjærstad (1) Louis Nyffenegger (1) Leo Arias (1) Lars-Magnus Skog (1) -Jorge Timón (1) +Kevin Pan (1) +Jonathan "Duke" Leto (1) +Jonas Nick (1) Jeffrey Walton (1) Ian Kelling (1) Gaurav Rana (1) @@ -70,17 +95,23 @@ Forrest Voight (1) Florian Schmaus (1) Ethan Heilman (1) Eran Tromer (1) -Daniel Kraft (1) +Duke Leto (1) Christian von Roques (1) Chirag Davé (1) Casey Rodarmor (1) Cameron Boehmer (1) Bryan Stitt (1) +Bruno Arueira (1) +Boris Hajduk (1) Bob McElrath (1) Bitcoin Error Log (1) +Ashley Holman (1) +Anthony Towns (1) Allan Niemerg (1) Alex van der Peet (1) +Alex Morcos (1) Alex (1) Adam Weiss (1) Adam Brown (1) 4ZEC (1) +21E14 (1) diff --git a/doc/hotfix-process.md b/doc/hotfix-process.md new file mode 100644 index 000000000..e6ce8a7a2 --- /dev/null +++ b/doc/hotfix-process.md @@ -0,0 +1,74 @@ +Hotfix Release Process +====================== + +Hotfix releases are versioned by incrementing the build number of the latest +release. For example: + + First hotfix: v1.0.11 -> v1.0.11-1 + Second hotfix: v1.0.11-1 -> v1.0.11-2 + +In the commands below, and are prefixed with a v, ie. +v1.0.11 (not 1.0.11). + +## Create a hotfix branch + +Create a hotfix branch from the previous release tag, and push it to the main +repository: + + $ git branch hotfix- + $ git push 'git@github.com:zcash/zcash' hotfix- + +## Implement hotfix changes + +Hotfix changes are implemented the same way as regular changes (developers work +in separate branches per change, and push the branches to their own repositories), +except that the branches are based on the hotfix branch instead of master: + + $ git checkout hotfix- + $ git checkout -b + +## Merge hotfix PRs + +Hotfix PRs are created like regular PRs, except using the hotfix branch as the +base instead of master. Each PR should be reviewed as normal, and then the +following process should be used to merge: + +- A CI merge build is manually run by logging into the CI server, going to the + pr-merge builder, clicking the "force" button, and entering the following + values: + + - Repository: https://github.com//zcash + - must be in the set of "safe" users as-specified in the CI + config. + - Branch: name of the hotfix PR branch (not the hotfix release branch). + +- A link to the build and its result is manually added to the PR as a comment. + +- If the build was successful, the PR is merged via the GitHub button. + +## Release process + +The majority of this process is identical to the standard release process. +However, there are a few notable differences: + +- When running the release script, use the `--hotfix` flag: + + $ ./zcutil/make-release.py --hotfix + +- To review the automated changes in git: + + $ git log hotfix-..HEAD + +- After the standard review process, use the hotfix merge process outlined above + instead of the regular merge process. + +- When making the tag, check out the hotfix branch instead of master. + +## Post-release + +Once the hotfix release has been created, a new PR should be opened for merging +the hotfix release branch into master. This may require fixing merge conflicts +(e.g. changing the version number in the hotfix branch to match master, if +master is ahead). Such conflicts **MUST** be addressed with additional commits +to the hotfix branch; specifically, the branch **MUST NOT** be rebased on +master. diff --git a/doc/man/zcash-cli.1 b/doc/man/zcash-cli.1 index 9dbefb9e8..a30af6fe6 100644 --- a/doc/man/zcash-cli.1 +++ b/doc/man/zcash-cli.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH ZCASH-CLI "1" "March 2017" "zcash-cli v1.0.8" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. +.TH ZCASH-CLI "1" "February 2018" "zcash-cli v1.0.15" "User Commands" .SH NAME -zcash-cli \- manual page for zcash-cli v1.0.8 +zcash-cli \- manual page for zcash-cli v1.0.15 .SH DESCRIPTION -Zcash RPC client version v1.0.8 +Zcash RPC client version v1.0.15 .PP In order to ensure you are adequately protecting your privacy when using Zcash, -please see . +please see . .SS "Usage:" .TP zcash\-cli [options] [params] @@ -66,6 +66,10 @@ Password for JSON\-RPC connections Timeout in seconds during HTTP requests, or 0 for no timeout. (default: 900) .SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + Copyright (C) 2009-2017 The Bitcoin Core Developers Copyright (C) 2015-2017 The Zcash Developers @@ -76,4 +80,4 @@ or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. +by Eric Young. diff --git a/doc/man/zcash-tx.1 b/doc/man/zcash-tx.1 index 4bd1b6b1d..f5830e6de 100644 --- a/doc/man/zcash-tx.1 +++ b/doc/man/zcash-tx.1 @@ -1,9 +1,9 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH ZCASH-TX "1" "March 2017" "zcash-tx v1.0.8" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. +.TH ZCASH-TX "1" "February 2018" "zcash-tx v1.0.15" "User Commands" .SH NAME -zcash-tx \- manual page for zcash-tx v1.0.8 +zcash-tx \- manual page for zcash-tx v1.0.15 .SH DESCRIPTION -Zcash zcash\-tx utility version v1.0.8 +Zcash zcash\-tx utility version v1.0.15 .SS "Usage:" .TP zcash\-tx [options] [commands] @@ -68,7 +68,7 @@ outscript=VALUE:SCRIPT .IP Add raw script output to TX .IP -sign=SIGHASH\-FLAGS +sign=HEIGHT:SIGHASH\-FLAGS .IP Add zero or more signatures to transaction. This command requires JSON registers:prevtxs=JSON object, privatekeys=JSON object. See @@ -84,6 +84,10 @@ set=NAME:JSON\-STRING .IP Set register NAME to given JSON\-STRING .SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + Copyright (C) 2009-2017 The Bitcoin Core Developers Copyright (C) 2015-2017 The Zcash Developers @@ -94,4 +98,4 @@ or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. +by Eric Young. diff --git a/doc/man/zcashd.1 b/doc/man/zcashd.1 index 3fbfe32e6..eaef634c0 100644 --- a/doc/man/zcashd.1 +++ b/doc/man/zcashd.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. -.TH ZCASHD "1" "March 2017" "zcashd v1.0.8" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.3. +.TH ZCASHD "1" "February 2018" "zcashd v1.0.15" "User Commands" .SH NAME -zcashd \- manual page for zcashd v1.0.8 +zcashd \- manual page for zcashd v1.0.15 .SH DESCRIPTION -Zcash Daemon version v1.0.8 +Zcash Daemon version v1.0.15 .PP In order to ensure you are adequately protecting your privacy when using Zcash, -please see . +please see . .SS "Usage:" .TP zcashd [options] @@ -51,13 +51,18 @@ Run in the background as a daemon and accept commands .IP Specify data directory .HP +\fB\-disabledeprecation=\fR +.IP +Disable block\-height node deprecation and automatic shutdown (example: +\fB\-disabledeprecation\fR=\fI\,1\/\fR.0.15) +.HP \fB\-exportdir=\fR .IP Specify directory to be used when exporting data .HP \fB\-dbcache=\fR .IP -Set database cache size in megabytes (4 to 16384, default: 100) +Set database cache size in megabytes (4 to 16384, default: 450) .HP \fB\-loadblock=\fR .IP @@ -67,9 +72,14 @@ Imports blocks from external blk000??.dat file on startup .IP Keep at most unconnectable transactions in memory (default: 100) .HP +\fB\-mempooltxinputlimit=\fR +.IP +Set the maximum number of transparent inputs in a transaction that the +mempool will accept (default: 0 = no limit applied) +.HP \fB\-par=\fR .IP -Set the number of script verification threads (\fB\-4\fR to 16, 0 = auto, <0 = +Set the number of script verification threads (\fB\-2\fR to 16, 0 = auto, <0 = leave that many cores free, default: 0) .HP \fB\-pid=\fR @@ -207,10 +217,6 @@ Tor control port to use if onion listening enabled (default: .IP Tor control port password (default: empty) .HP -\fB\-upnp\fR -.IP -Use UPnP to map the listening port (default: 0) -.HP \fB\-whitebind=\fR .IP Bind to given address and whitelist peers connecting to it. Use @@ -235,11 +241,11 @@ Set key pool size to (default: 100) .HP \fB\-paytxfee=\fR .IP -Fee (in BTC/kB) to add to transactions you send (default: 0.00) +Fee (in ZEC/kB) to add to transactions you send (default: 0.00) .HP \fB\-rescan\fR .IP -Rescan the blockchain for missing wallet transactions on startup +Rescan the block chain for missing wallet transactions on startup .HP \fB\-salvagewallet\fR .IP @@ -258,10 +264,15 @@ Spend unconfirmed change when sending transactions (default: 1) If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: 2) .HP +\fB\-txexpirydelta\fR +.IP +Set the number of blocks after which a transaction that has not been +mined will become invalid (default: 20) +.HP \fB\-maxtxfee=\fR .IP -Maximum total fees to use in a single wallet transaction; setting this -too low may abort large transactions (default: 0.10) +Maximum total fees (in ZEC) to use in a single wallet transaction; +setting this too low may abort large transactions (default: 0.10) .HP \fB\-upgradewallet\fR .IP @@ -333,7 +344,7 @@ Prepend debug output with timestamp (default: 1) .HP \fB\-minrelaytxfee=\fR .IP -Fees (in BTC/Kb) smaller than this are considered zero fee for relaying +Fees (in ZEC/kB) smaller than this are considered zero fee for relaying (default: 0.000001) .HP \fB\-printtoconsole\fR @@ -454,6 +465,10 @@ output (default: 1 if running in a console, 0 otherwise) Number of seconds between metrics refreshes (default: 1 if running in a console, 600 otherwise) .SH COPYRIGHT + +In order to ensure you are adequately protecting your privacy when using Zcash, +please see . + Copyright (C) 2009-2017 The Bitcoin Core Developers Copyright (C) 2015-2017 The Zcash Developers @@ -464,4 +479,4 @@ or . This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written -by Eric Young and UPnP software written by Thomas Bernard. +by Eric Young. diff --git a/doc/payment-api.md b/doc/payment-api.md index 42e325f8a..14732adba 100644 --- a/doc/payment-api.md +++ b/doc/payment-api.md @@ -32,7 +32,7 @@ RPC calls by category: * Addresses : z_getnewaddress, z_listaddresses, z_validateaddress * Keys : z_exportkey, z_importkey, z_exportwallet, z_importwallet * Operation: z_getoperationresult, z_getoperationstatus, z_listoperationids -* Payment : z_listreceivedbyaddress, z_sendmany +* Payment : z_listreceivedbyaddress, z_sendmany, z_shieldcoinbase RPC parameter conventions: @@ -46,7 +46,7 @@ RPC parameter conventions: Command | Parameters | Description --- | --- | --- -z_getbalance
| address [minconf=1] | Returns the balance of a taddr or zaddr belonging to the node’s wallet.

Optionally set the minimum number of confirmations a private or transaction transaction must have in order to be included in the balance. Use 0 to count unconfirmed transactions. +z_getbalance
| address [minconf=1] | Returns the balance of a taddr or zaddr belonging to the node’s wallet.

Optionally set the minimum number of confirmations a private or transparent transaction must have in order to be included in the balance. Use 0 to count unconfirmed transactions. z_gettotalbalance
| [minconf=1] | Return the total value of funds stored in the node’s wallet.

Optionally set the minimum number of confirmations a private or transparent transaction must have in order to be included in the balance. Use 0 to count unconfirmed transactions.

Output:
{
"transparent" : 1.23,
"private" : 4.56,
"total" : 5.79} ### Addresses @@ -55,7 +55,7 @@ Command | Parameters | Description --- | --- | --- z_getnewaddress | | Return a new zaddr for sending and receiving payments. The spending key for this zaddr will be added to the node’s wallet.

Output:
zN68D8hSs3... z_listaddresses | | Returns a list of all the zaddrs in this node’s wallet for which you have a spending key.

Output:
{ [“z123…”, “z456...”, “z789...”] } -z_validateaddress | | Return information about a given zaddr.

Output:
{"isvalid" : true,
"address" : "zcWsmq...",
"payingkey" : "f5bb3c...",
"transmissionkey" : "7a58c7...",
"ismine" : true} +z_validateaddress | zaddr | Return information about a given zaddr.

Output:
{"isvalid" : true,
"address" : "zcWsmq...",
"payingkey" : "f5bb3c...",
"transmissionkey" : "7a58c7...",
"ismine" : true} ### Key Management @@ -71,7 +71,8 @@ z_importwallet | filename | _Requires an unlocked wallet or an unencrypted walle Command | Parameters | Description --- | --- | --- z_listreceivedbyaddress
| zaddr [minconf=1] | Return a list of amounts received by a zaddr belonging to the node’s wallet.

Optionally set the minimum number of confirmations which a received amount must have in order to be included in the result. Use 0 to count unconfirmed transactions.

Output:
[{
“txid”: “4a0f…”,
“amount”: 0.54,
“memo”:”F0FF…”,}, {...}, {...}
] -z_sendmany
| fromaddress amounts [minconf=1] [fee=0.0001] | _This is an Asynchronous RPC call_

Send funds from an address to multiple outputs. The address can be either a taddr or a zaddr.

Amounts is a list containing key/value pairs corresponding to the addresses and amount to pay. Each output address can be in taddr or zaddr format.

When sending to a zaddr, you also have the option of attaching a memo in hexadecimal format.

**NOTE:**When sending coinbase funds to a zaddr, the node's wallet does not allow any change. Put another way, spending a partial amount of a coinbase utxo is not allowed. This is not a consensus rule but a local wallet rule due to the current implementation of z_sendmany. In future, this rule may be removed.

Example of Outputs parameter:
[{“address”:”t123…”, “amount”:0.005},
,{“address”:”z010…”,”amount”:0.03, “memo”:”f508af…”}]

Optionally set the minimum number of confirmations which a private or transparent transaction must have in order to be used as an input.

Optionally set a transaction fee, which by default is 0.0001 ZEC.

Any transparent change will be sent to a new transparent address. Any private change will be sent back to the zaddr being used as the source of funds.

Returns an operationid. You use the operationid value with z_getoperationstatus and z_getoperationresult to obtain the result of sending funds, which if successful, will be a txid. +z_sendmany
| fromaddress amounts [minconf=1] [fee=0.0001] | _This is an Asynchronous RPC call_

Send funds from an address to multiple outputs. The address can be either a taddr or a zaddr.

Amounts is a list containing key/value pairs corresponding to the addresses and amount to pay. Each output address can be in taddr or zaddr format.

When sending to a zaddr, you also have the option of attaching a memo in hexadecimal format.

**NOTE:**When sending coinbase funds to a zaddr, the node's wallet does not allow any change. Put another way, spending a partial amount of a coinbase utxo is not allowed. This is not a consensus rule but a local wallet rule due to the current implementation of z_sendmany. In future, this rule may be removed.

Example of Outputs parameter:
[{“address”:”t123…”, “amount”:0.005},
,{“address”:”z010…”,”amount”:0.03, “memo”:”f508af…”}]

Optionally set the minimum number of confirmations which a private or transparent transaction must have in order to be used as an input. When sending from a zaddr, minconf must be greater than zero.

Optionally set a transaction fee, which by default is 0.0001 ZEC.

Any transparent change will be sent to a new transparent address. Any private change will be sent back to the zaddr being used as the source of funds.

Returns an operationid. You use the operationid value with z_getoperationstatus and z_getoperationresult to obtain the result of sending funds, which if successful, will be a txid. +z_shieldcoinbase
| fromaddress toaddress [fee=0.0001] [limit=50] | _This is an Asynchronous RPC call_

Shield transparent coinbase funds by sending to a shielded z address. Utxos selected for shielding will be locked. If there is an error, they are unlocked. The RPC call `listlockunspent` can be used to return a list of locked utxos.

The number of coinbase utxos selected for shielding can be set with the limit parameter, which has a default value of 50. If the parameter is set to 0, the number of utxos selected is limited by the `-mempooltxinputlimit` option. Any limit is constrained by a consensus rule defining a maximum transaction size of 100000 bytes.

The from address is a taddr or "*" for all taddrs belonging to the wallet. The to address is a zaddr. The default fee is 0.0001.

Returns an object containing an operationid which can be used with z_getoperationstatus and z_getoperationresult, along with key-value pairs regarding how many utxos are being shielded in this transaction and what remains to be shielded. ### Operations @@ -100,7 +101,7 @@ It is currently not possible to cancel operations. Command | Parameters | Description --- | --- | --- -z_getoperationresult
| [operationids] | Return OperationStatus JSON objects for all completed operations the node is currently aware of, and then remove the operation from memory.

Operationids is an optional array to filter which operations you want to receive status objects for.

Output is a list of operation status objects, where the status is either "failed", "cancelled" or "success".
[
{“operationid”: “opid-11ee…”,
“status”: “cancelled”},
{“operationid”: “opid-9876”, “status”: ”failed”},
{“operationid”: “opid-0e0e”,
“status”:”success”,
“execution_time”:”25”,
“result”: {“txid”:”af3887654…”,...}
},
] +z_getoperationresult
| [operationids] | Return OperationStatus JSON objects for all completed operations the node is currently aware of, and then remove the operation from memory.

Operationids is an optional array to filter which operations you want to receive status objects for.

Output is a list of operation status objects, where the status is either "failed", "cancelled" or "success".
[
{“operationid”: “opid-11ee…”,
“status”: “cancelled”},
{“operationid”: “opid-9876”, “status”: ”failed”},
{“operationid”: “opid-0e0e”,
“status”:”success”,
“execution_time”:”25”,
“result”: {“txid”:”af3887654…”,...}
},
]

Examples:
zcash-cli z_getoperationresult '["opid-8120fa20-5ee7-4587-957b-f2579c2d882b"]'
zcash-cli z_getoperationresult z_getoperationstatus
| [operationids] | Return OperationStatus JSON objects for all operations the node is currently aware of.

Operationids is an optional array to filter which operations you want to receive status objects for.

Output is a list of operation status objects.
[
{“operationid”: “opid-12ee…”,
“status”: “queued”},
{“operationid”: “opd-098a…”, “status”: ”executing”},
{“operationid”: “opid-9876”, “status”: ”failed”}
]

When the operation succeeds, the status object will also include the result.

{“operationid”: “opid-0e0e”,
“status”:”success”,
“execution_time”:”25”,
“result”: {“txid”:”af3887654…”,...}
} z_listoperationids
| [state] | Return a list of operationids for all operations which the node is currently aware of.

State is an optional string parameter to filter the operations you want listed by their state. Acceptable parameter values are ‘queued’, ‘executing’, ‘success’, ‘failed’, ‘cancelled’.

[“opid-0e0e…”, “opid-1af4…”, … ] @@ -112,6 +113,7 @@ Zcash error codes are defined in https://github.com/zcash/zcash/blob/master/src/ RPC_INVALID_PARAMETER (-8) | _Invalid, missing or duplicate parameter_ ---------------------------| ------------------------------------------------- +"Minconf cannot be zero when sending from zaddr" | Cannot accept minimum confirmation value of zero when sending from zaddr. "Minconf cannot be negative" | Cannot accept negative minimum confirmation number. "Minimum number of confirmations cannot be less than 0" | Cannot accept negative minimum confirmation number. "From address parameter missing" | Missing an address to send funds from. @@ -157,7 +159,7 @@ RPC_WALLET_ERROR (-4) | _Unspecified problem with wallet_ "Could not find previous JoinSplit anchor" | Try restarting node with `-reindex`. "Error decrypting output note of previous JoinSplit: __" | "Could not find witness for note commitment" | Try restarting node with `-rescan`. -"Witness for note commitment is null" | Missing witness for note commitement. +"Witness for note commitment is null" | Missing witness for note commitment. "Witness for spendable note does not have same anchor as change input" | Invalid anchor for spendable note witness. "Not enough funds to pay miners fee" | Retry with sufficient funds. "Missing hex data for raw transaction" | Raw transaction data is null. diff --git a/doc/payment-disclosure.md b/doc/payment-disclosure.md new file mode 100644 index 000000000..d0aa68a96 --- /dev/null +++ b/doc/payment-disclosure.md @@ -0,0 +1,107 @@ +# Payment Disclosure (Experimental Feature) + +**Summary** + +Use RPC calls `z_getpaymentdisclosure` and `z_validatepaymentdisclosure` to reveal details of a shielded payment. + +**Who should read this document** + +Frequent users of shielded transactions, payment processors, exchanges, block explorer + +### Experimental Feature + +This is an experimental feature. Enable it by launching `zcashd` with flags: + + zcashd -experimentalfeatures -paymentdisclosure -debug=paymentdisclosure -txindex=1 + +These flags can also be set as options in `zcash.conf`. + +All nodes that generate or validate payment disclosures must run with `txindex=1` enabled. + +### Background + +Payment Disclosure is an implementation of the work-in-progress Payment Disclosure ZIP [1]. + +The ZIP describes a method of proving that a payment was sent to a shielded address. In the typical case, this means enabling a sender to present a proof that they transferred funds to a recipient's shielded address. + +[1] https://github.com/zcash/zips/pull/119 + +### Example Use Case + +Alice the customer sends 10 ZEC to Bob the merchant at the shielded address shown on their website. However, Bob is not sure if he received the funds. + +Alice's node is running with payment disclosure enabled, so Alice generates a payment disclosure and provides it to Bob, who verifies the payment was made. + +If Bob is a bad merchant, Alice can present the payment disclosure to a third party to validate that payment was indeed made. + +### Solution + +A payment disclosure can be generated for any output of a JoinSplit using the RPC call: + + z_getpaymentdisclosure txid js_index output_index (message) + +An optional message can be supplied. This could be used for a refund address or some other reference, as currently it is not common practice to (ahead of time) include a refund address in the memo field when making a payment. + +To validate a payment disclosure, the following RPC call can be used: + + z_validatepaymentdisclosure hexdata + +### Example + +Generate a payment disclosure for the first joinsplit, second output (index starts from zero): + + zcash-cli z_getpaymentdisclosure 79189528d611e811a1c7bb0358dd31343033d14b4c1e998d7c4799c40f8b652b 0 1 "Hello" + +This returns a payment disclosure in the form of a hex string: + + 706462ff000a3722aafa8190cdf9710bfad6da2af6d3a74262c1fc96ad47df814b0cd5641c2b658b0fc499477c8d991e4c4bd133303431dd5803bbc7a111e811d6289518790000000000000000017e861adb829d8cb1cbcf6330b8c2e25fb0d08041a67a857815a136f0227f8a5342bce5b3c0d894e2983000eb594702d3c1580817d0374e15078528e56bb6f80c0548656c6c6f59a7085395c9e706d82afe3157c54ad4ae5bf144fcc774a8d9c921c58471402019c156ec5641e2173c4fb6467df5f28530dc4636fa71f4d0e48fc5c560fac500 + +To validate the payment disclosure: + + zcash-cli z_validatepaymentdisclosure HEXDATA + +This returns data related to the payment and the payment disclosure: + + { + "txid": "79189528d611e811a1c7bb0358dd31343033d14b4c1e998d7c4799c40f8b652b", + "jsIndex": 0, + "outputIndex": 1, + "version": 0, + "onetimePrivKey": "1c64d50c4b81df47ad96fcc16242a7d3f62adad6fa0b71f9cd9081faaa22370a", + "message": "Hello", + "joinSplitPubKey": "d1c465d16166b602992479acfac18e87dc18065f6cefde6a002e70bc371b9faf", + "signatureVerified": true, + "paymentAddress": "ztaZJXy8iX8nrk2ytXKDBoTWqPkhQcj6E2ifARnD3wfkFwsxXs5SoX7NGmrjkzSiSKn8VtLHTJae48vX5NakvmDhtGNY5eb", + "memo": "f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "value": 12.49900000, + "commitmentMatch": true, + "valid": true + } + +The `signatureVerified` field confirms that the payment disclosure was generated and signed with the joinSplitPrivKey, which should only be known by the node generating and sending the transaction 7918...652b in question. + +### Where is the data stored? + +For all nodes, payment disclosure does not touch `wallet.dat` in any way. + +For nodes that only validate payment disclosures, no data is stored locally. + +For nodes that generate payment disclosures, a LevelDB database is created in the node's datadir. For most users, this would be in the folder: + + $HOME/.zcash/paymentdisclosure + +If you decide you don't want to use payment disclosure, it is safe to shut down your node and delete the database folder. + +### Security Properties + +Please consult the work-in-progress ZIP for details about the protocol, security properties and caveats. + +### Reminder + +Feedback is most welcome! + +This is an experimental feature so there are no guarantees that the protocol, database format, RPC interface etc. will remain the same in the future. + +### Notes + +Currently there is no user friendly way to help senders identify which joinsplit output index maps to a given payment they made. It is possible to construct this from `debug.log`. Ideas and feedback are most welcome on how to improve the user experience. diff --git a/doc/reducing-memory-usage.md b/doc/reducing-memory-usage.md new file mode 100644 index 000000000..333ea0086 --- /dev/null +++ b/doc/reducing-memory-usage.md @@ -0,0 +1,8 @@ +In-memory caches +---------------- + +The size of some in-memory caches can be reduced. As caches trade off memory usage for performance, usually reducing these have a negative effect on performance. + +- `-dbcache=` - the UTXO database cache size, this defaults to `450` (`100` before 1.0.15). The unit is MiB (where 1 GiB = 1024 MiB). + - The minimum value for `-dbcache` is 4. + - A lower dbcache make initial sync time much longer. After the initial sync, the effect is less pronounced for most use-cases, unless fast validation of blocks is important such as for mining. diff --git a/doc/release-notes.md b/doc/release-notes.md new file mode 100644 index 000000000..a29094b51 --- /dev/null +++ b/doc/release-notes.md @@ -0,0 +1,6 @@ +(note: this is a temporary file, to be added-to by anybody, and moved to +release-notes at release time) + +Notable changes +=============== + diff --git a/doc/release-notes/release-notes-1.0.10-1.md b/doc/release-notes/release-notes-1.0.10-1.md new file mode 100644 index 000000000..fea2f5156 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.10-1.md @@ -0,0 +1,11 @@ +Jack Grigg (1): + Disable building Proton in Gitian + +Sean Bowe (2): + Revert "Remove an unneeded version workaround as per @str4d's review comment." + Revert "Delete old protocol version constants and simplify code that used them." + +Simon Liu (2): + make-release.py: Versioning changes for 1.0.10-1. + make-release.py: Updated manpages for 1.0.10-1. + diff --git a/doc/release-notes/release-notes-1.0.10.md b/doc/release-notes/release-notes-1.0.10.md new file mode 100644 index 000000000..16d2a62ba --- /dev/null +++ b/doc/release-notes/release-notes-1.0.10.md @@ -0,0 +1,79 @@ +Notable changes +=============== + +Signature validation using libsecp256k1 +--------------------------------------- + +ECDSA signatures inside Zcash transactions now use validation using +[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL. + +Depending on the platform, this means a significant speedup for raw signature +validation speed. The advantage is largest on x86_64, where validation is over +five times faster. In practice, this translates to a raw reindexing and new +block validation times that are less than half of what it was before. + +Libsecp256k1 has undergone very extensive testing and validation upstream. + +A side effect of this change is that libconsensus no longer depends on OpenSSL. + +Changelog +========= + +Boris Hajduk (1): + documentatin z_validateaddress was missing param + +Daira Hopwood (8): + Delete old protocol version constants and simplify code that used them. fixes #2244 + Remove an unneeded version workaround as per @str4d's review comment. + Remove unneeded lax ECDSA signature verification. + Strict DER signatures are always enforced; remove the flag and code that used it. + Repair tests for strict DER signatures. While we're at it, repair a similar test for CLTV, and make the repaired RPC tests run by default. + Make transaction test failures print the comments preceding the test JSON. + Fix a comment that was made stale before launch by #1016 (commit 542da61). + Delete test that is redundant and inapplicable to Zcash. + +Jack Grigg (20): + Fix incorrect locking in CCryptoKeyStore + Use AtomicTimer for metrics screen thread count + Revert "Fix secp256k1 test compilation" + Squashed 'src/secp256k1/' changes from 22f60a6..84973d3 + Fix potential overflows in ECDSA DER parsers + Rename FALLBACK_DOWNLOAD_PATH to PRIORITY_DOWNLOAD_PATH + Add test for incorrect consensus logic + Correct consensus logic in ContextualCheckInputs + Add comments + Update Debian copyright list + Specify ECDSA constant sizes as constants + Remove redundant `= 0` initialisations + Ensure that ECDSA constant sizes are correctly-sized + Add test for -mempooltxinputlimit + Hold an ECCVerifyHandle in zcash-gtest + Additional testing of -mempooltxinputlimit + Fix comment + Use sendfrom for both t-addr calls + make-release.py: Versioning changes for 1.0.10. + make-release.py: Updated manpages for 1.0.10. + +Kevin Pan (1): + "getblocktemplate" could work without wallet + +Pieter Wuille (2): + Update key.cpp to new secp256k1 API + Switch to libsecp256k1-based validation for ECDSA + +Simon Liu (5): + Fix intermediate vpub_new leakage in multi joinsplit tx (#1360) + Add option 'mempooltxinputlimit' so the mempool can reject a transaction based on the number of transparent inputs. + Check mempooltxinputlimit when creating a transaction to avoid local mempool rejection. + Partial revert & fix for commit 9e84b5a ; code block in wrong location. + Fix #b1eb4f2 so test checks sendfrom as originally intended. + +Wladimir J. van der Laan (2): + Use real number of cores for default -par, ignore virtual cores + Remove ChainParams::DefaultMinerThreads + +kozyilmaz (3): + [macOS] system linker does not support “--version” option but only “-v” + option to disable building libraries (zcutil/build.sh) + support per platform filename and hash setting for dependencies + diff --git a/doc/release-notes/release-notes-1.0.11-rc1.md b/doc/release-notes/release-notes-1.0.11-rc1.md new file mode 100644 index 000000000..4542a448c --- /dev/null +++ b/doc/release-notes/release-notes-1.0.11-rc1.md @@ -0,0 +1,44 @@ +Changelog +========= + +Ariel Gabizon (2): + make-release.py: Versioning changes for 1.0.11-rc1. + make-release.py: Updated manpages for 1.0.11-rc1. + +Daira Hopwood (7): + Clean up imports to be pyflakes-checkable. fixes #2450 + For unused variables reported by pyflakes, either remove the variable, suppress the warning, or fix a bug (if the wrong variable was used). refs #2450 + Cosmetics (trailing whitespace, comment conventions, etc.) + Alert 1004 (version 1.0.10 only) + Remove UPnP support. fixes #2500 + Change wording in Security Warnings section of README.md. + Document our criteria for adding CI workers. closes #2499 + +Jack Grigg (15): + Pull in temporary release notes during the release process + Ansible playbook for installing Zcash dependencies and Buildbot worker + Variable overrides for Debian, Ubuntu and Fedora + Variable overrides for FreeBSD + Simplify Python installation, inform user if they need to manually configure + Add test for issue #2444 + Add Buildbot worker setup to Ansible playbook + Add steps for setting up a latent worker on Amazon EC2 + Add pyblake2 to required Python modules + Remove Buildbot version from host file + Add a separate Buildbot host info template for EC2 + Add pyflakes to required Python modules + Add block download progress to metrics UI + Correct and extend EstimateNetHeightInner tests + Improve network height estimation + +Simon Liu (3): + Closes #2446 by adding generated field to listunspent. + Fixes #2519. When sending from a zaddr, minconf cannot be zero. + Fixes #2480. Null entry in map was dereferenced leading to a segfault. + +Wladimir J. van der Laan (1): + rpc: Add WWW-Authenticate header to 401 response + +practicalswift (1): + Net: Fix resource leak in ReadBinaryFile(...) + diff --git a/doc/release-notes/release-notes-1.0.11.md b/doc/release-notes/release-notes-1.0.11.md new file mode 100644 index 000000000..d5a12a222 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.11.md @@ -0,0 +1,47 @@ +Changelog +========= + +Ariel Gabizon (3): + make-release.py: Versioning changes for 1.0.11-rc1. + make-release.py: Updated manpages for 1.0.11-rc1. + make-release.py: Updated release notes and changelog for 1.0.11-rc1. + +Daira Hopwood (7): + Clean up imports to be pyflakes-checkable. fixes #2450 + For unused variables reported by pyflakes, either remove the variable, suppress the warning, or fix a bug (if the wrong variable was used). refs #2450 + Cosmetics (trailing whitespace, comment conventions, etc.) + Alert 1004 (version 1.0.10 only) + Remove UPnP support. fixes #2500 + Change wording in Security Warnings section of README.md. + Document our criteria for adding CI workers. closes #2499 + +Jack Grigg (17): + Pull in temporary release notes during the release process + Ansible playbook for installing Zcash dependencies and Buildbot worker + Variable overrides for Debian, Ubuntu and Fedora + Variable overrides for FreeBSD + Simplify Python installation, inform user if they need to manually configure + Add test for issue #2444 + Add Buildbot worker setup to Ansible playbook + Add steps for setting up a latent worker on Amazon EC2 + Add pyblake2 to required Python modules + Remove Buildbot version from host file + Add a separate Buildbot host info template for EC2 + Add pyflakes to required Python modules + Add block download progress to metrics UI + Correct and extend EstimateNetHeightInner tests + Improve network height estimation + make-release.py: Versioning changes for 1.0.11. + make-release.py: Updated manpages for 1.0.11. + +Simon Liu (3): + Closes #2446 by adding generated field to listunspent. + Fixes #2519. When sending from a zaddr, minconf cannot be zero. + Fixes #2480. Null entry in map was dereferenced leading to a segfault. + +Wladimir J. van der Laan (1): + rpc: Add WWW-Authenticate header to 401 response + +practicalswift (1): + Net: Fix resource leak in ReadBinaryFile(...) + diff --git a/doc/release-notes/release-notes-1.0.12-rc1.md b/doc/release-notes/release-notes-1.0.12-rc1.md new file mode 100644 index 000000000..27d36b7e7 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.12-rc1.md @@ -0,0 +1,57 @@ +Changelog +========= + +Ariel (1): + add examples to z_getoperationresult + +Ariel Gabizon (1): + add load-wallet benchmark + +Bjorn Hjortsberg (2): + Do not warn on built in declaration mismatch + Remove deprecated exception specification + +Jack Grigg (20): + ci-workers: Enable pipelining, and use root to set admin and host details + Variable overrides for Arch Linux + Rationalize currency unit to "ZEC" + ci-workers: Fail if Python is not version 2.7 + ci-workers: Variable overrides and process tweaks for CentOS 7 + Add build progress to the release script if progressbar module is available + Add hotfix support to release script + Document the hotfix release process + Enforce sequential hotfix versioning + Benchmark time to call sendtoaddress with many UTXOs + Fix bug in benchmark data generation script + Adjust instructions for UTXO dataset creation + Add GitHub release notes to release process + Clarify branching and force-building operations in hotfix process + Update user guide translations as part of release process + make-release.py: Send stderr to stdout + List dependencies for release script in release process doc + Additional test cases for importprivkey RPC test + make-release.py: Versioning changes for 1.0.12-rc1. + make-release.py: Updated manpages for 1.0.12-rc1. + +Jason Davies (1): + Fix deprecation policy comment. + +Nathan Wilcox (5): + key_import_export rpc-test: verify that UTXO view co-evolves for nodes sharing a key. + Add a new rpc-test-specified requirement: `importprivkey` outputs the associated address. (Test fails.) + [tests pass] Output address on new key import. + Add a new requirement that `importprivkey` API is idempotent. + [tests pass] Ensure `importprivkey` outputs the address in case key is already imported. + +Ross Nicoll (1): + Rationalize currency unit to "BTC" + +Simon Liu (3): + Closes #2583. Exclude watch-only utxos from z_sendmany coin selection. + Set up a clean chain. Delete redundant method wait_until_miner_sees() via use of sync_all(). + Implement RPC shield_coinbase #2448. + +kpcyrd (2): + Fetch params from ipfs if possible + Prefer wget over ipfs + diff --git a/doc/release-notes/release-notes-1.0.12.md b/doc/release-notes/release-notes-1.0.12.md new file mode 100644 index 000000000..6aa6cd651 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.12.md @@ -0,0 +1,65 @@ +Changelog +========= + +Ariel (1): + add examples to z_getoperationresult + +Ariel Gabizon (1): + add load-wallet benchmark + +Bjorn Hjortsberg (2): + Do not warn on built in declaration mismatch + Remove deprecated exception specification + +Jack Grigg (26): + ci-workers: Enable pipelining, and use root to set admin and host details + Variable overrides for Arch Linux + Rationalize currency unit to "ZEC" + ci-workers: Fail if Python is not version 2.7 + ci-workers: Variable overrides and process tweaks for CentOS 7 + Add build progress to the release script if progressbar module is available + Add hotfix support to release script + Document the hotfix release process + Enforce sequential hotfix versioning + Benchmark time to call sendtoaddress with many UTXOs + Fix bug in benchmark data generation script + Adjust instructions for UTXO dataset creation + Add GitHub release notes to release process + Clarify branching and force-building operations in hotfix process + Update user guide translations as part of release process + make-release.py: Send stderr to stdout + List dependencies for release script in release process doc + Additional test cases for importprivkey RPC test + make-release.py: Versioning changes for 1.0.12-rc1. + make-release.py: Updated manpages for 1.0.12-rc1. + make-release.py: Updated release notes and changelog for 1.0.12-rc1. + Fix pyflakes warnings in RPC tests + Individualise performance-measurements.sh errors for debugging + Fix incorrect failure in memory benchmark + make-release.py: Versioning changes for 1.0.12. + make-release.py: Updated manpages for 1.0.12. + +Jason Davies (1): + Fix deprecation policy comment. + +Nathan Wilcox (5): + key_import_export rpc-test: verify that UTXO view co-evolves for nodes sharing a key. + Add a new rpc-test-specified requirement: `importprivkey` outputs the associated address. (Test fails.) + [tests pass] Output address on new key import. + Add a new requirement that `importprivkey` API is idempotent. + [tests pass] Ensure `importprivkey` outputs the address in case key is already imported. + +Ross Nicoll (1): + Rationalize currency unit to "BTC" + +Simon Liu (5): + Closes #2583. Exclude watch-only utxos from z_sendmany coin selection. + Set up a clean chain. Delete redundant method wait_until_miner_sees() via use of sync_all(). + Implement RPC shield_coinbase #2448. + Update which lock to synchronize on when calling GetBestAnchor(). + Closes #2637. Make z_shieldcoinbase an experimental feature where it can be enabled with: zcashd -experimentalfeatures -zshieldcoinbase. + +kpcyrd (2): + Fetch params from ipfs if possible + Prefer wget over ipfs + diff --git a/doc/release-notes/release-notes-1.0.13-rc1.md b/doc/release-notes/release-notes-1.0.13-rc1.md new file mode 100644 index 000000000..4d8a37a7c --- /dev/null +++ b/doc/release-notes/release-notes-1.0.13-rc1.md @@ -0,0 +1,88 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (37): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/doc/release-notes/release-notes-1.0.13-rc2.md b/doc/release-notes/release-notes-1.0.13-rc2.md new file mode 100644 index 000000000..6ade7d922 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.13-rc2.md @@ -0,0 +1,95 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (44): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + make-release.py: Updated release notes and changelog for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + Move libsnark from DIST_SUBDIRS into EXTRA_DIST + Pass correct dependencies path to libsnark from both Gitian and build.sh + Mark libsnark includes as library includes + Add the tar-pax option to automake + make-release.py: Versioning changes for 1.0.13-rc2. + make-release.py: Updated manpages for 1.0.13-rc2. + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/doc/release-notes/release-notes-1.0.13.md b/doc/release-notes/release-notes-1.0.13.md new file mode 100644 index 000000000..3a1a950a9 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.13.md @@ -0,0 +1,98 @@ +Changelog +========= + +Ariel Gabizon (1): + boost::format -> tinyformat + +Bruno Arueira (1): + Removes out bitcoin mention in favor for zcash + +Cory Fields (1): + httpserver: explicitly detach worker threads + +Duke Leto (1): + Update performance-measurements.sh + +Jack Grigg (47): + Squashed 'src/snark/' content from commit 9ada3f8 + Add libsnark compile flag to not copy DEPINST to PREFIX + Add Ansible playbook for grind workers + Add connections in BIP65 and BIP66 tests to the test manager + Add benchmark for listunspent + [Test] MiniNode: Implement JSDescription parsing + [Test] MiniNode: Implement v2 CTransaction parsing + [Test] MiniNode: Implement Zcash block parsing + [Test] MiniNode: Update protocol version and network magics + [Test] MiniNode: Use Zcash PoW + [Test] MiniNode: Fix coinbase creation + [Test] MiniNode: Coerce OP_PUSHDATA bytearrays to bytes + [Test] MiniNode: Implement Zcash coinbase + Fix BIP65 and BIP66 tests + Un-indent RPC test output in test runner + Replace full-test-suite.sh with a new test suite driver script + Move ensure-no-dot-so-in-depends.py into full_test_suite.py + Move check-security-hardening.sh into full_test_suite.py + Add memory benchmark for validatelargetx + Migrate libsnark test code to Google Test + Remove test code corresponding to removed code + Add alt_bn128 to QAP and Merkle tree gadget tests + Update libsnark LDLIBS + Add "make check" to libsnark that runs the Google Tests + Add "make libsnark-tests" that runs libsnark's "make check" + Changes to get test_r1cs_ppzksnark passing + Add bitcoin-util-test.py to full_test_suite.py + Add stdout notice if any stage fails + Add libsnark to "make clean" + Ensure that libsnark is built first, so its headers are available + Remove OpenSSL libraries from libsnark LDLIBS + Add libsnark tests to full_test_suite.py + Add --list-stages argument to full_test_suite.py + Fix NPE in rpc_wallet_tests + make-release.py: Versioning changes for 1.0.13-rc1. + make-release.py: Updated manpages for 1.0.13-rc1. + make-release.py: Updated release notes and changelog for 1.0.13-rc1. + Change auto-senescence cycle to 16 weeks + Move libsnark from DIST_SUBDIRS into EXTRA_DIST + Pass correct dependencies path to libsnark from both Gitian and build.sh + Mark libsnark includes as library includes + Add the tar-pax option to automake + make-release.py: Versioning changes for 1.0.13-rc2. + make-release.py: Updated manpages for 1.0.13-rc2. + make-release.py: Updated release notes and changelog for 1.0.13-rc2. + make-release.py: Versioning changes for 1.0.13. + make-release.py: Updated manpages for 1.0.13. + +Jason Davies (1): + Replace "bitcoin" with "Zcash". + +Jay Graber (1): + s/zcash/Zcash + +Jonathan "Duke" Leto (1): + Fix bug where performance-measurements.sh fails hards when given no args + +João Barbosa (1): + Improve shutdown process + +Sean Bowe (5): + Remove libsnark from depends system and integrate it into build system. + Remove crusty old "loadVerifyingKey"/"loadProvingKey" APIs and associated invariants. + Refactor proof generation function. + Add streaming prover. + Integrate low memory prover. + +Simon Liu (7): + Replace 'bitcoin address' with 'zcash address'. + Closes #2639. z_shieldcoinbase is now supported, no longer experimental. + Closes #2263 fixing broken pipe error. + Closes #2576. Update link to security info on z.cash website. + Closes #2639. Adds optional limit parameter with a default value of 50. + Fix an issue where qa test wallet_shieldcoinbase could hang. + Add payment disclosure as experimental feature. + +Wladimir J. van der Laan (4): + Make HTTP server shutdown more graceful + http: Wait for worker threads to exit + http: Force-exit event loop after predefined time + http: speed up shutdown + diff --git a/doc/release-notes/release-notes-1.0.14-rc1.md b/doc/release-notes/release-notes-1.0.14-rc1.md new file mode 100644 index 000000000..1654bf483 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.14-rc1.md @@ -0,0 +1,156 @@ +Notable changes +=============== + +Incoming viewing keys +--------------------- + +Support for incoming viewing keys, as described in +[the Zcash protocol spec](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf), +has been added to the wallet. + +Use the `z_exportviewingkey` RPC method to obtain the incoming viewing key for a +z-address in a node's wallet. For Sprout z-addresses, these always begin with +"ZiVK" (or "ZiVt" for testnet z-addresses). Use `z_importviewingkey` to import +these into another node. + +A node that possesses an incoming viewing key for a z-address can view all past +transactions received by that address, as well as all future transactions sent +to it, by using `z_listreceivedbyaddress`. They cannot spend any funds from the +address. This is similar to the behaviour of "watch-only" t-addresses. + +`z_gettotalbalance` now has an additional boolean parameter for including the +balance of "watch-only" addresses (both transparent and shielded), which is set +to `false` by default. `z_getbalance` has also been updated to work with +watch-only addresses. + +- **Caution:** for z-addresses, these balances will **not** be accurate if any + funds have been sent from the address. This is because incoming viewing keys + cannot detect spends, and so the "balance" is just the sum of all received + notes, including ones that have been spent. Some future use-cases for incoming + viewing keys will include synchronization data to keep their balances accurate + (e.g. [#2542](https://github.com/zcash/zcash/issues/2542)). + +Changelog +========= + +Anthony Towns (1): + Add configure check for -latomic + +Cory Fields (12): + c++11: don't throw from the reverselock destructor + c++11: CAccountingEntry must be defined before use in a list + c++11: fix libbdb build against libc++ in c++11 mode + depends: use c++11 + depends: bump OSX toolchain + build: Split hardening/fPIE options out + build: define base filenames for use elsewhere in the buildsystem + build: quiet annoying warnings without adding new ones + build: fix Windows builds without pkg-config + build: force a c++ standard to be specified + build: warn about variable length arrays + build: add --enable-werror option + +Jack Grigg (36): + Squashed 'src/secp256k1/' changes from 84973d3..6ad5cdb + Use g-prefixed coreutils commands if they are available + Replace hard-coded defaults for HOST and BUILD with config.guess + Remove manual -std=c++11 flag + Replace "install -D" with "mkdir -p && install" + Check if OpenMP is available before using it + [libsnark] Use POSIX-compliant ar arguments + Include endian-ness compatibility layer in Equihash implementation + build: Split hardening/fPIE options out in Zcash-specific binaries + Change --enable-werror to apply to all warnings, use it in build.sh + Move Zcash flags into configure.ac + ViewingKey -> ReceivingKey per zcash/zips#117 + Implement viewing key storage in the keystore + Factor out common logic from CZCPaymentAddress and CZCSpendingKey + Track net value entering and exiting the Sprout circuit + Add Sprout value pool to getblock and getblockchaininfo + Apply -fstack-protector-all to libsnark + Add Rust and Proton to configure options printout + Clarify operator precedence in serialization of nSproutValue + Remove nSproutValue TODO from CDiskBlockIndex + Add Base58 encoding of viewing keys + Implement viewing key storage in the wallet + Add RPC methods for exporting/importing viewing keys + Update wallet logic to account for viewing keys + Add watch-only support to Zcash RPC methods + Modify zcrawkeygen RPC method to set "zcviewingkey" to the viewing key + Cleanup: Add braces for clarity + Add cautions to z_getbalance and z_gettotalbalance help text about viewing keys + Add release notes for incoming viewing keys + Create release notes starting from the previous non-beta non-RC release + release-notes.py: Remove unnecessary parameter + Regenerate previous release notes to conform to new format + Exclude beta and RC release notes from author tallies + Fix pyflakes warnings in zkey_import_export RPC test + make-release.py: Versioning changes for 1.0.14-rc1. + make-release.py: Updated manpages for 1.0.14-rc1. + +Jay Graber (3): + Add cli and rpc examples for z_sendmany + Fix cli help result for z_shieldcoinbase + Add rpc test that exercises z_importkey + +Jonas Schnelli (1): + Add compile and link options echo to configure + +Luke Dashjr (4): + depends: Use curl for fetching on Linux + Travis: Use curl rather than wget for Mac SDK + Bugfix: depends/Travis: Use --location (follow redirects) and --fail [on HTTP error response] with curl + Travis: Use Blue Box VMs for IPv6 loopback support + +MarcoFalke (2): + Fix url in .travis.yml + [depends] builders: No need to set -L and --location for curl + +Per Grön (2): + Deduplicate test utility method wait_and_assert_operationid_status + Print result of RPC call in test only when PYTHON_DEBUG is set + +René Nyffenegger (1): + Use AC_ARG_VAR to set ARFLAGS. + +Simon Liu (5): + RPC dumpwallet and z_exportwallet updated to no longer allow overwriting an existing file. + Add documentation for shielding coinbase utxos. + Add documentation for payment disclosure. + Closes #2759. Fixes broken pipe error with QA test wallet.py. + Closes #2746. Payment disclosure blobs now use 'zpd:' prefix. + +Wladimir J. van der Laan (6): + build: Enable C++11 build, require C++11 compiler + build: update ax_cxx_compile_stdcxx to serial 4 + test: Remove java comparison tool + build: Remove check for `openssl/ec.h` + devtools: Check for high-entropy ASLR in 64-bit PE executables + build: supply `-Wl,--high-entropy-va` + +daniel (1): + add powerpc build support for openssl lib + +fanquake (3): + [build-aux] Update Boost & check macros to latest serials + [depends] Add -stdlib=libc++ to darwin CXX flags + [depends] Set OSX_MIN_VERSION to 10.8 + +kozyilmaz (1): + empty spaces in PATH variable cause build failure + +syd (13): + Upgrade googletest to 1.8.0 + Get the sec-hard tests to run correctly. + Update libsodium from 1.0.11 to 1.0.15 + Remove Boost conditional compilation. + Update to address @daira comments wrt fixing configure.ac + Get rid of consensus.fPowAllowMinDifficultyBlocks. + Don't compile libgtest.a when building libsnark. + Add gtests to .gitignore + Get rid of fp3 from libsnark, it is not used. + InitGoogleMock instead of InitGoogleTest per CR + Get rid of underscore prefixes for include guards. + Rename bash completion files so that they refer to zcash and not bitcoin. + Fix libsnark test failure. + diff --git a/doc/release-notes/release-notes-1.0.14.md b/doc/release-notes/release-notes-1.0.14.md new file mode 100644 index 000000000..4b9cd0810 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.14.md @@ -0,0 +1,160 @@ +Notable changes +=============== + +Incoming viewing keys +--------------------- + +Support for incoming viewing keys, as described in +[the Zcash protocol spec](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf), +has been added to the wallet. + +Use the `z_exportviewingkey` RPC method to obtain the incoming viewing key for a +z-address in a node's wallet. For Sprout z-addresses, these always begin with +"ZiVK" (or "ZiVt" for testnet z-addresses). Use `z_importviewingkey` to import +these into another node. + +A node that possesses an incoming viewing key for a z-address can view all past +transactions received by that address, as well as all future transactions sent +to it, by using `z_listreceivedbyaddress`. They cannot spend any funds from the +address. This is similar to the behaviour of "watch-only" t-addresses. + +`z_gettotalbalance` now has an additional boolean parameter for including the +balance of "watch-only" addresses (both transparent and shielded), which is set +to `false` by default. `z_getbalance` has also been updated to work with +watch-only addresses. + +- **Caution:** for z-addresses, these balances will **not** be accurate if any + funds have been sent from the address. This is because incoming viewing keys + cannot detect spends, and so the "balance" is just the sum of all received + notes, including ones that have been spent. Some future use-cases for incoming + viewing keys will include synchronization data to keep their balances accurate + (e.g. [#2542](https://github.com/zcash/zcash/issues/2542)). + +Changelog +========= + +Anthony Towns (1): + Add configure check for -latomic + +Cory Fields (12): + c++11: don't throw from the reverselock destructor + c++11: CAccountingEntry must be defined before use in a list + c++11: fix libbdb build against libc++ in c++11 mode + depends: use c++11 + depends: bump OSX toolchain + build: Split hardening/fPIE options out + build: define base filenames for use elsewhere in the buildsystem + build: quiet annoying warnings without adding new ones + build: fix Windows builds without pkg-config + build: force a c++ standard to be specified + build: warn about variable length arrays + build: add --enable-werror option + +Jack Grigg (40): + Squashed 'src/secp256k1/' changes from 84973d3..6ad5cdb + Use g-prefixed coreutils commands if they are available + Replace hard-coded defaults for HOST and BUILD with config.guess + Remove manual -std=c++11 flag + Replace "install -D" with "mkdir -p && install" + Check if OpenMP is available before using it + [libsnark] Use POSIX-compliant ar arguments + Include endian-ness compatibility layer in Equihash implementation + build: Split hardening/fPIE options out in Zcash-specific binaries + Change --enable-werror to apply to all warnings, use it in build.sh + Move Zcash flags into configure.ac + ViewingKey -> ReceivingKey per zcash/zips#117 + Implement viewing key storage in the keystore + Factor out common logic from CZCPaymentAddress and CZCSpendingKey + Track net value entering and exiting the Sprout circuit + Add Sprout value pool to getblock and getblockchaininfo + Apply -fstack-protector-all to libsnark + Add Rust and Proton to configure options printout + Clarify operator precedence in serialization of nSproutValue + Remove nSproutValue TODO from CDiskBlockIndex + Add Base58 encoding of viewing keys + Implement viewing key storage in the wallet + Add RPC methods for exporting/importing viewing keys + Update wallet logic to account for viewing keys + Add watch-only support to Zcash RPC methods + Modify zcrawkeygen RPC method to set "zcviewingkey" to the viewing key + Cleanup: Add braces for clarity + Add cautions to z_getbalance and z_gettotalbalance help text about viewing keys + Add release notes for incoming viewing keys + Create release notes starting from the previous non-beta non-RC release + release-notes.py: Remove unnecessary parameter + Regenerate previous release notes to conform to new format + Exclude beta and RC release notes from author tallies + Fix pyflakes warnings in zkey_import_export RPC test + make-release.py: Versioning changes for 1.0.14-rc1. + make-release.py: Updated manpages for 1.0.14-rc1. + make-release.py: Updated release notes and changelog for 1.0.14-rc1. + Update release process + make-release.py: Versioning changes for 1.0.14. + make-release.py: Updated manpages for 1.0.14. + +Jay Graber (3): + Add cli and rpc examples for z_sendmany + Fix cli help result for z_shieldcoinbase + Add rpc test that exercises z_importkey + +Jonas Schnelli (1): + Add compile and link options echo to configure + +Luke Dashjr (4): + depends: Use curl for fetching on Linux + Travis: Use curl rather than wget for Mac SDK + Bugfix: depends/Travis: Use --location (follow redirects) and --fail [on HTTP error response] with curl + Travis: Use Blue Box VMs for IPv6 loopback support + +MarcoFalke (2): + Fix url in .travis.yml + [depends] builders: No need to set -L and --location for curl + +Per Grön (2): + Deduplicate test utility method wait_and_assert_operationid_status + Print result of RPC call in test only when PYTHON_DEBUG is set + +René Nyffenegger (1): + Use AC_ARG_VAR to set ARFLAGS. + +Simon Liu (5): + RPC dumpwallet and z_exportwallet updated to no longer allow overwriting an existing file. + Add documentation for shielding coinbase utxos. + Add documentation for payment disclosure. + Closes #2759. Fixes broken pipe error with QA test wallet.py. + Closes #2746. Payment disclosure blobs now use 'zpd:' prefix. + +Wladimir J. van der Laan (6): + build: Enable C++11 build, require C++11 compiler + build: update ax_cxx_compile_stdcxx to serial 4 + test: Remove java comparison tool + build: Remove check for `openssl/ec.h` + devtools: Check for high-entropy ASLR in 64-bit PE executables + build: supply `-Wl,--high-entropy-va` + +daniel (1): + add powerpc build support for openssl lib + +fanquake (3): + [build-aux] Update Boost & check macros to latest serials + [depends] Add -stdlib=libc++ to darwin CXX flags + [depends] Set OSX_MIN_VERSION to 10.8 + +kozyilmaz (1): + empty spaces in PATH variable cause build failure + +syd (13): + Upgrade googletest to 1.8.0 + Get the sec-hard tests to run correctly. + Update libsodium from 1.0.11 to 1.0.15 + Remove Boost conditional compilation. + Update to address @daira comments wrt fixing configure.ac + Get rid of consensus.fPowAllowMinDifficultyBlocks. + Don't compile libgtest.a when building libsnark. + Add gtests to .gitignore + Get rid of fp3 from libsnark, it is not used. + InitGoogleMock instead of InitGoogleTest per CR + Get rid of underscore prefixes for include guards. + Rename bash completion files so that they refer to zcash and not bitcoin. + Fix libsnark test failure. + diff --git a/doc/release-notes/release-notes-1.0.15-rc1.md b/doc/release-notes/release-notes-1.0.15-rc1.md new file mode 100644 index 000000000..b4b0b2f0a --- /dev/null +++ b/doc/release-notes/release-notes-1.0.15-rc1.md @@ -0,0 +1,165 @@ +Notable changes +=============== + +UTXO and note merging +--------------------- + +In order to simplify the process of combining many small UTXOs and notes into a +few larger ones, a new RPC method `z_mergetoaddress` has been added. It merges +funds from t-addresses, z-addresses, or both, and sends them to a single +t-address or z-address. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +UTXO memory accounting +---------------------- + +The default -dbcache has been changed in this release to 450MiB. Users can set -dbcache to a higher value (e.g. to keep the UTXO set more fully cached in memory). Users on low-memory systems (such as systems with 1GB or less) should consider specifying a lower value for this parameter. + +Additional information relating to running on low-memory systems can be found here: [reducing-memory-usage.md](https://github.com/zcash/zcash/blob/master/doc/reducing-memory-usage.md). + +Changelog +========= + +21E14 (1): + Remove obsolete reference to CValidationState from UpdateCoins. + +Alex Morcos (1): + Implement helper class for CTxMemPoolEntry constructor + +Ariel (2): + add blake2b writer + update SignatureHash according to Overwinter spec + +Ashley Holman (1): + TxMemPool: Change mapTx to a boost::multi_index_container + +Cory Fields (2): + chainparams: move CCheckpointData into chainparams.h + chainparams: don't use std namespace + +Daniel Kraft (1): + Clean up chainparams some more. + +Jack Grigg (38): + Scope the ECDSA constant sizes to CPubKey / CKey classes + Enable Bash completion for -exportdir + Check chainValueZat when checking value pool monitoring + Add missing namespace for boost::get + Add viewing key prefix to regtest parameters + zkey_import_export: Synchronize mempools before mining + Use JoinSplitTestingSetup for Boost sighash tests + Network upgrade activation mechanism + Allow changing network upgrade parameters on regtest + Test network upgrade logic + Adjust rewind logic to use the network upgrade mechanism + Add Overwinter to upgrade list + Add method for fetching the next activation height after a given block height + Use a boost::optional for nCachedBranchId + Change UI/log status message for block rewinding + Update quote from ZIP 200 + Update SignatureHash tests for transaction format changes + Implement roll-back limit for reorganisation + Add rollback limit to block index rewinding + Remove mempool transactions which commit to an unmineable branch ID + Remove P2WPKH and P2WSH from signing logic + Add consensus branch ID parameter to SignatureHash, remove SigVersion parameter + Cleanup: Wrap function arguments + Regenerate SignatureHash tests + Make number of inputs configurable in validatelargetx test + Use v3 transactions with caching for validatelargetx benchmark + Extend CWallet::GetFilteredNotes to enable filtering on a set of addresses + Add branch IDs for current and next block to getblockchaininfo + Check Equihash solution when loading block index + Implement z_mergetoaddress for combining UTXOs and notes + Gate z_mergetoaddress as an experimental feature + Add z_mergetoaddress to release notes + Check upgrade status in wallet_overwintertx RPC test + Document that consensus.chaintip != consensus.nextblock just before an upgrade + Regenerate sighash tests + wallet_mergetoaddress: Add additional syncs to prevent race conditions + make-release.py: Versioning changes for 1.0.15-rc1. + make-release.py: Updated manpages for 1.0.15-rc1. + +Jay Graber (8): + Add getdeprecationinfo rpc call to return current version and deprecation block height. + Make applicable only on mainnet + Add upgrades field to RPC call getblockchaininfo + Implement transaction expiry for Overwinter + Add -txexpirydelta cli option + Add mempool_tx_expiry.py test + Add expiry to z_mergetoaddress + Change rpc_tests to 21 + +Jonas Nick (1): + Reduce unnecessary hashing in signrawtransaction + +Jorge Timón (3): + Chainparams: Introduce CreateGenesisBlock() static function + Chainparams: CTestNetParams and CRegTestParams extend directly from CChainParams + Mempool: Use Consensus::CheckTxInputs direclty over main::CheckInputs + +Marius Kjærstad (1): + Changed http:// to https:// on some links + +Mark Friedenbach (1): + Explicitly set tx.nVersion for the genesis block and mining tests + +Matt Corallo (5): + Add failing test checking timelocked-txn removal during reorg + Fix removal of time-locked transactions during reorg + Fix comment in removeForReorg + Make indentation in ActivateBestChainStep readable + removeForReorg calls once-per-disconnect-> once-per-reorg + +Maxwell Gubler (1): + Fix syntax examples for z_importwallet and export + +Nicolas DORIER (1): + Unit test for sighash caching + +Pavel Vasin (1): + remove unused NOBLKS_VERSION_{START,END} constants + +Pieter Wuille (8): + Add rewind logic to deal with post-fork software updates + Support -checkmempool=N, which runs checks on average once every N transactions + Report non-mandatory script failures correctly + Refactor script validation to observe amounts + BIP143: Verification logic + BIP143: Signing logic + Precompute sighashes + Rename to PrecomputedTransactionData + +Simon Liu (11): + Fixes #2793. Backport commit f33afd3 to increase dbcache default. + Add documentation about dbcache. + Add note about dbcache to 1.0.15 release notes. + Remove redundant service flag NODE_GETUTXO meant for Bitcoin XT. + Implementation of Overwinter transaction format ZIP 202. + Add test to check malformed v1 transaction against Overwinter tx parser + Closes #2964. z_sendmany once again makes v1 tx for taddr to taddr. + Closes #2954 and #2959. Fixes Overwinter issues in sighash_tests. + Add field nProtocolVersion to struct NetworkUpgrade. + Overwinter peer management and network handshaking. + Add python qa test overwinter_peer_management. + +Suhas Daftuar (3): + Track coinbase spends in CTxMemPoolEntry + Don't call removeForReorg if DisconnectTip fails + Fix removeForReorg to use MedianTimePast + +jc (1): + read hashReserved from disk block index + +syd (2): + Fix libsnark dependency build. + Remove OSX and Windows files from Makefile + share directory. + diff --git a/doc/release-notes/release-notes-1.0.15.md b/doc/release-notes/release-notes-1.0.15.md new file mode 100644 index 000000000..3195c955a --- /dev/null +++ b/doc/release-notes/release-notes-1.0.15.md @@ -0,0 +1,209 @@ +Notable changes +=============== + +Overwinter network upgrade +-------------------------- + +The code preparations for the Overwinter network upgrade, as described in [ZIP +200](https://github.com/zcash/zips/blob/master/zip-0200.rst), [ZIP +201](https://github.com/zcash/zips/blob/master/zip-0201.rst), [ZIP +202](https://github.com/zcash/zips/blob/master/zip-0202.rst), [ZIP +203](https://github.com/zcash/zips/blob/master/zip-0203.rst), and [ZIP +143](https://github.com/zcash/zips/blob/master/zip-0143.rst) are +finished and included in this release. Overwinter will activate on testnet at +height 207500, and can also be activated at a specific height in regtest mode +by setting the config option `-nuparams=5ba81b19:HEIGHT`. + +However, because the Overwinter activation height is not yet specified for +mainnet, version 1.0.15 will behave similarly as other pre-Overwinter releases +even after a future activation of Overwinter on the network. Upgrading from +1.0.15 will be required in order to follow the Overwinter network upgrade on +mainnet. + +Overwinter transaction format +----------------------------- + +Once Overwinter has activated, transactions must use the new v3 format +(including coinbase transactions). All RPC methods that create new transactions +(such as `createrawtransaction` and `getblocktemplate`) will create v3 +transactions once the Overwinter activation height has been reached. + +Overwinter transaction expiry +----------------------------- + +Overwinter transactions created by `zcashd` will also have a default expiry +height set (the block height after which the transaction becomes invalid) of 20 +blocks after the height of the next block. This can be configured with the +config option `-txexpirydelta`. + +UTXO and note merging +--------------------- + +In order to simplify the process of combining many small UTXOs and notes into a +few larger ones, a new RPC method `z_mergetoaddress` has been added. It merges +funds from t-addresses, z-addresses, or both, and sends them to a single +t-address or z-address. + +Unlike most other RPC methods, `z_mergetoaddress` operates over a particular +quantity of UTXOs and notes, instead of a particular amount of ZEC. By default, +it will merge 50 UTXOs and 10 notes at a time; these limits can be adjusted with +the parameters `transparent_limit` and `shielded_limit`. + +`z_mergetoaddress` also returns the number of UTXOs and notes remaining in the +given addresses, which can be used to automate the merging process (for example, +merging until the number of UTXOs falls below some value). + +UTXO memory accounting +---------------------- + +The default `-dbcache` has been changed in this release to 450MiB. Users can set +`-dbcache` to a higher value (e.g. to keep the UTXO set more fully cached in +memory). Users on low-memory systems (such as systems with 1GB or less) should +consider specifying a lower value for this parameter. + +Additional information relating to running on low-memory systems can be found +here: [reducing-memory-usage.md](https://github.com/zcash/zcash/blob/master/doc/reducing-memory-usage.md). + +Changelog +========= + +21E14 (1): + Remove obsolete reference to CValidationState from UpdateCoins. + +Alex Morcos (1): + Implement helper class for CTxMemPoolEntry constructor + +Ariel (2): + add blake2b writer + update SignatureHash according to Overwinter spec + +Ashley Holman (1): + TxMemPool: Change mapTx to a boost::multi_index_container + +Cory Fields (2): + chainparams: move CCheckpointData into chainparams.h + chainparams: don't use std namespace + +Daniel Kraft (1): + Clean up chainparams some more. + +Jack Grigg (43): + Scope the ECDSA constant sizes to CPubKey / CKey classes + Enable Bash completion for -exportdir + Check chainValueZat when checking value pool monitoring + Add missing namespace for boost::get + Add viewing key prefix to regtest parameters + zkey_import_export: Synchronize mempools before mining + Use JoinSplitTestingSetup for Boost sighash tests + Network upgrade activation mechanism + Allow changing network upgrade parameters on regtest + Test network upgrade logic + Adjust rewind logic to use the network upgrade mechanism + Add Overwinter to upgrade list + Add method for fetching the next activation height after a given block height + Use a boost::optional for nCachedBranchId + Change UI/log status message for block rewinding + Update quote from ZIP 200 + Update SignatureHash tests for transaction format changes + Implement roll-back limit for reorganisation + Add rollback limit to block index rewinding + Remove mempool transactions which commit to an unmineable branch ID + Remove P2WPKH and P2WSH from signing logic + Add consensus branch ID parameter to SignatureHash, remove SigVersion parameter + Cleanup: Wrap function arguments + Regenerate SignatureHash tests + Make number of inputs configurable in validatelargetx test + Use v3 transactions with caching for validatelargetx benchmark + Extend CWallet::GetFilteredNotes to enable filtering on a set of addresses + Add branch IDs for current and next block to getblockchaininfo + Check Equihash solution when loading block index + Implement z_mergetoaddress for combining UTXOs and notes + Gate z_mergetoaddress as an experimental feature + Add z_mergetoaddress to release notes + Check upgrade status in wallet_overwintertx RPC test + Document that consensus.chaintip != consensus.nextblock just before an upgrade + Regenerate sighash tests + wallet_mergetoaddress: Add additional syncs to prevent race conditions + make-release.py: Versioning changes for 1.0.15-rc1. + make-release.py: Updated manpages for 1.0.15-rc1. + make-release.py: Updated release notes and changelog for 1.0.15-rc1. + Use block hash comparison for consistency check when loading block index + Overwinter release notes and testnet activation height + make-release.py: Versioning changes for 1.0.15. + make-release.py: Updated manpages for 1.0.15. + +Jay Graber (8): + Add getdeprecationinfo rpc call to return current version and deprecation block height. + Make applicable only on mainnet + Add upgrades field to RPC call getblockchaininfo + Implement transaction expiry for Overwinter + Add -txexpirydelta cli option + Add mempool_tx_expiry.py test + Add expiry to z_mergetoaddress + Change rpc_tests to 21 + +Jonas Nick (1): + Reduce unnecessary hashing in signrawtransaction + +Jorge Timón (3): + Chainparams: Introduce CreateGenesisBlock() static function + Chainparams: CTestNetParams and CRegTestParams extend directly from CChainParams + Mempool: Use Consensus::CheckTxInputs direclty over main::CheckInputs + +Marius Kjærstad (1): + Changed http:// to https:// on some links + +Mark Friedenbach (1): + Explicitly set tx.nVersion for the genesis block and mining tests + +Matt Corallo (5): + Add failing test checking timelocked-txn removal during reorg + Fix removal of time-locked transactions during reorg + Fix comment in removeForReorg + Make indentation in ActivateBestChainStep readable + removeForReorg calls once-per-disconnect-> once-per-reorg + +Maxwell Gubler (1): + Fix syntax examples for z_importwallet and export + +Nicolas DORIER (1): + Unit test for sighash caching + +Pavel Vasin (1): + remove unused NOBLKS_VERSION_{START,END} constants + +Pieter Wuille (8): + Add rewind logic to deal with post-fork software updates + Support -checkmempool=N, which runs checks on average once every N transactions + Report non-mandatory script failures correctly + Refactor script validation to observe amounts + BIP143: Verification logic + BIP143: Signing logic + Precompute sighashes + Rename to PrecomputedTransactionData + +Simon Liu (11): + Fixes #2793. Backport commit f33afd3 to increase dbcache default. + Add documentation about dbcache. + Add note about dbcache to 1.0.15 release notes. + Remove redundant service flag NODE_GETUTXO meant for Bitcoin XT. + Implementation of Overwinter transaction format ZIP 202. + Add test to check malformed v1 transaction against Overwinter tx parser + Closes #2964. z_sendmany once again makes v1 tx for taddr to taddr. + Closes #2954 and #2959. Fixes Overwinter issues in sighash_tests. + Add field nProtocolVersion to struct NetworkUpgrade. + Overwinter peer management and network handshaking. + Add python qa test overwinter_peer_management. + +Suhas Daftuar (3): + Track coinbase spends in CTxMemPoolEntry + Don't call removeForReorg if DisconnectTip fails + Fix removeForReorg to use MedianTimePast + +jc (1): + read hashReserved from disk block index + +syd (2): + Fix libsnark dependency build. + Remove OSX and Windows files from Makefile + share directory. + diff --git a/doc/release-notes/release-notes-1.0.8-1.md b/doc/release-notes/release-notes-1.0.8-1.md new file mode 100644 index 000000000..4650f552c --- /dev/null +++ b/doc/release-notes/release-notes-1.0.8-1.md @@ -0,0 +1,16 @@ +Daira Hopwood (3): + Don't rely on a finite upper bound on fee rate or priority. + Simplify JoinSplit priority calculation. refs 1896 + Add check for JoinSplit priority as calculated by CCoinsViewCache::GetPriority. + +Jack Grigg (1): + Use a larger -rpcclienttimeout for slow performance measurements + +Nathan Wilcox (2): + Bump version numbers for v1.0.8-1. + Commit the changes from gen-manpages.sh, except manually tweak the version strings. + +str4d (2): + Update tests to check actual infinity as well as INF_FEERATE + Add unit test for security issue 2017-04-11.a + diff --git a/doc/release-notes/release-notes-1.0.9.md b/doc/release-notes/release-notes-1.0.9.md new file mode 100644 index 000000000..a1335ec97 --- /dev/null +++ b/doc/release-notes/release-notes-1.0.9.md @@ -0,0 +1,90 @@ +Amgad Abdelhafez (2): + Update timedata.cpp + Update timedata.cpp + +Daira Hopwood (4): + Fix an error reporting bug due to BrokenPipeError and ConnectionResetError not existing in Python 2. refs #2263 + Alert 1002 (versions 1.0.0-1.0.2 inclusive). + Alert 1003 (versions 1.0.3-1.0.8 inclusive). + Disable building Proton by default. + +Jack Grigg (14): + Fix prioritisetransaction RPC test + torcontrol: Handle escapes in Tor QuotedStrings + torcontrol: Add missing copyright header + Convert Zcash versions to Debian format + [manpage] Handle build numbers in versions + Address Daira's comments + Address Daira's further comments + Correctly handle three-digit octals with leading digit 4-7 + Check that >3-digit octals are truncated. + Implement automatic shutdown of deprecated Zcash versions + Wrap messages nicely on metrics screen + Regenerate miner tests + Add a benchmark for calling ConnectBlock on a block with many inputs + Remove additional sources of determinism from benchmark archive + +Jay Graber (2): + Change help text examples to use Zcash addresses + Poll on getblocktemplate result rather than use bare sleep to avoid race condition. + +Nathan Wilcox (39): + [Direct master commit] Fix a release snafu in debian version string. + Show toolchain versions in build.sh. + Start on a make-release.py script; currently just arg parsing and unittests [unittests fail]. + Update version spec by altering test; also update regex to pass single 0 digits in major/minor/patch. + Add another case from debian-style versions. + Add all of the zcash release tags in my current repo as positive test vector. + Add support for beta/rc release versions. + Add version sorting, assert that RELEASE_PREV is the most recent release. + Make SystemExit errors less redundant in output; verify clean git status on master. + Always run unittests prior to actual runs. + Make --help output clean by not running self-test. + Add an option to run against a different repo directory. + Make sure to pull the latest master. + Exit instead of raising an unexpected exception, since it's already logged. + Implement `PathPatcher` abstraction, `clientversion.h` rewrite, and build numbering w/ unittests. + Implement the IS_RELEASE rule for betas. + Generalize buildnum patching for both `clientversion.h` and `configure.ac`. + Modify the `APPROX_RELEASE_HEIGHT`. + Remove portions of `./doc/release-process.md` now implemented in `make-release.py`. + Switch from `sh_out_logged` to `sh_log`. + Shorten the arg log line. + Commit the version changes and build. + Generate manpages; commit that; improve error output in sh_log. + Polish logging a bit more. + Tidy up / systematize logging output a bit more. + First full-release-branch version of script; rewrite large swatch of release-process.md. [Manually tested.] + Enable set -u mode. + Fix a variable name typo. + Reuse zcash_rpc. + Do not use `-rpcwait` on all `zcash_rpc` invocations, only block when starting zcashd. + Fix `release-process.md` doc usage for `make-release.py` to have correct arguments and order. + Include release version in commit comments. + Examine all future versions which are assumed to follow the same Version parser schema. + Consider both beta and rc versions to be `IS_RELEASE == false`. + Add a few more version strings to positive parser test. + Define the deprecation policy for 1.0.9. + Clarify that the feature is automated *shutdown*. + make-release.py: Versioning changes for 1.0.9. + make-release.py: Updated manpages for 1.0.9. + +Paige Peterson (4): + wallet backup instructions + typo and rewording edits + str4d and Ariel's suggestions + specify exportdir being within homedirectory + +Sean Bowe (1): + Check that pairings work properly when the G1 point is at infinity. + +Simon Liu (5): + Add AMQP 1.0 support via Apache Qpid Proton C++ API 0.17.0 + Add --disable-proton flag to build.sh. Proton has build/linker issues with gcc 4.9.2 and requires gcc 5.x. + Fix proton build issue with debian jessie, as used on CI servers. + Change regtest port to 18344. Closes #2269. + Patch to build Proton with minimal dependencies. + +emilrus (1): + Replace bitcoind with zcashd + diff --git a/doc/release-process.md b/doc/release-process.md index b4e2a3565..93a8e8362 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -2,125 +2,132 @@ Release Process ==================== Meta: There should always be a single release engineer to disambiguate responsibility. +If this is a hotfix release, please see `./hotfix-process.md` before proceeding. + ## Pre-release -The following should have been checked well in advance of the release: +### Github Milestone -- All dependencies have been updated as appropriate: - - BDB - - Boost - - ccache - - libgmp - - libsnark (upstream of our fork) - - libsodium - - miniupnpc - - OpenSSL +Ensure all goals for the github milestone are met. If not, remove tickets +or PRs with a comment as to why it is not included. (Running out of time +is a common reason.) +### Pre-release checklist: + +Check that dependencies are properly hosted by looking at the `check-depends` builder: + + https://ci.z.cash/#/builders/1 + +Check that there are no surprising performance regressions: + + https://speed.z.cash + +Ensure that new performance metrics appear on that site. + +### Protocol Safety Checks: + +If this release changes the behavior of the protocol or fixes a serious +bug, verify that a pre-release PR merge updated `PROTOCOL_VERSION` in +`version.h` correctly. + +If this release breaks backwards compatibility or needs to prevent +interaction with software forked projects, change the network magic +numbers. Set the four `pchMessageStart` in `CTestNetParams` in +`chainparams.cpp` to random values. + +Both of these should be done in standard PRs ahead of the release +process. If these were not anticipated correctly, this could block the +release, so if you suspect this is necessary, double check with the +whole engineering team. + +## Release dependencies + +The release script has the following dependencies: + +- `help2man` +- `debchange` (part of the devscripts Debian package) + +You can optionally install the `progressbar2` Python module with pip to have a +progress bar displayed during the build process. ## Release process -## A. Define the release version as: +In the commands below, and are prefixed with a v, ie. +v1.0.9 (not 1.0.9). - $ ZCASH_RELEASE=MAJOR.MINOR.REVISION(-BUILD_STRING) +### Create the release branch -Example: +Run the release script, which will verify you are on the latest clean +checkout of master, create a branch, then commit standard automated +changes to that branch locally: - $ ZCASH_RELEASE=1.0.0-beta2 + $ ./zcutil/make-release.py -Also, the following commands use the `ZCASH_RELEASE_PREV` bash variable for the -previous release: +Examples: - $ ZCASH_RELEASE_PREV=1.0.0-beta1 + $ ./zcutil/make-release.py v1.0.9 v1.0.8-1 v1.0.8-1 120000 + $ ./zcutil/make-release.py v1.0.13 v1.0.13-rc1 v1.0.12 222900 -## B. Create a new release branch / github PR +### Create, Review, and Merge the release branch pull request -### B1. Check that you are up-to-date with current master, then create a release branch. +Review the automated changes in git: -### B2. Update (commit) version in sources. + $ git log master..HEAD - README.md - src/clientversion.h - configure.ac - contrib/gitian-descriptors/gitian-linux.yml +Push the resulting branch to github: -In `configure.ac` and `clientversion.h`: + $ git push 'git@github.com:$YOUR_GITHUB_NAME/zcash' $(git rev-parse --abbrev-ref HEAD) -- Increment `CLIENT_VERSION_BUILD` according to the following schema: +Then create the PR on github. Complete the standard review process, +then merge, then wait for CI to complete. - - 0-24: `1.0.0-beta1`-`1.0.0-beta25` - - 25-49: `1.0.0-rc1`-`1.0.0-rc25` - - 50: `1.0.0` - - 51-99: `1.0.0-1`-`1.0.0-49` - - (`CLIENT_VERSION_REVISION` rolls over) - - 0-24: `1.0.1-beta1`-`1.0.1-beta25` - -- Change `CLIENT_VERSION_IS_RELEASE` to false while Zcash is in beta-test phase. - -If this release changes the behavior of the protocol or fixes a serious bug, we may -also wish to change the `PROTOCOL_VERSION` in `version.h`. - -Commit these changes. (Be sure to do this before building, or else the built binary will include the flag `-dirty`) - -Build by running `./zcutil/build.sh`. - -Then perform the following command: - - $ bash contrib/devtools/gen-manpages.sh - -Commit the changes. - -### B3. Generate release notes - -Run the release-notes.py script to generate release notes and update authors.md file. For example: - - $ python zcutil/release-notes.py --version $ZCASH_RELEASE - -Add the newly created release notes to the Git repository: - - $ git add doc/release-notes/release-notes-$ZCASH_RELEASE.md - -Update the Debian package changelog: - - export DEBVERSION="${ZCASH_RELEASE}" - export DEBEMAIL="${DEBEMAIL:-team@z.cash}" - export DEBFULLNAME="${DEBFULLNAME:-Zcash Company}" - - dch -v $DEBVERSION -D jessie -c contrib/debian/changelog - -(`dch` comes from the devscripts package.) - -### B4. Change the network magics - -If this release breaks backwards compatibility, change the network magic -numbers. Set the four `pchMessageStart` in `CTestNetParams` in `chainparams.cpp` -to random values. - -### B5. Merge the previous changes - -Do the normal pull-request, review, testing process for this release PR. - -## C. Verify code artifact hosting - -### C1. Ensure depends tree is working - -https://ci.z.cash/builders/depends-sources - -### C2. Ensure public parameters work - -Run `./fetch-params.sh`. - -## D. Make tag for the newly merged result +## Make tag for the newly merged result Checkout master and pull the latest version to ensure master is up to date with the release PR which was merged in before. -Check the last commit on the local and remote versions of master to make sure they are the same. + $ git checkout master + $ git pull --ff-only -Then create the git tag: +Check the last commit on the local and remote versions of master to make sure they are the same: - $ git tag -s v${ZCASH_RELEASE} - $ git push origin v${ZCASH_RELEASE} + $ git log -1 -## E. Deploy testnet +The output should include something like, which is created by Homu: + + Auto merge of #4242 - nathan-at-least:release-v1.0.9, r=nathan-at-least + +Then create the git tag. The `-s` means the release tag will be +signed. **CAUTION:** Remember the `v` at the beginning here: + + $ git tag -s v1.0.9 + $ git push origin v1.0.9 + +## Make and deploy deterministic builds + +- Run the [Gitian deterministic build environment](https://github.com/zcash/zcash-gitian) +- Compare the uploaded [build manifests on gitian.sigs](https://github.com/zcash/gitian.sigs) +- If all is well, the DevOps engineer will build the Debian packages and update the + [apt.z.cash package repository](https://apt.z.cash). + +## Add release notes to GitHub + +- Go to the [GitHub tags page](https://github.com/zcash/zcash/tags). +- Click "Add release notes" beside the tag for this release. +- Copy the release blog post into the release description, and edit to suit + publication on GitHub. See previous release notes for examples. +- Click "Publish release" if publishing the release blog post now, or + "Save draft" to store the notes internally (and then return later to publish + once the blog post is up). + +Note that some GitHub releases are marked as "Verified", and others as +"Unverified". This is related to the GPG signature on the release tag - in +particular, GitHub needs the corresponding public key to be uploaded to a +corresponding GitHub account. If this release is marked as "Unverified", click +the marking to see what GitHub wants to be done. + +## Post Release Task List + +### Deploy testnet Notify the Zcash DevOps engineer/sysadmin that the release has been tagged. They update some variables in the company's automation code and then run an Ansible playbook, which: @@ -131,26 +138,12 @@ Notify the Zcash DevOps engineer/sysadmin that the release has been tagged. They Then, verify that nodes can connect to the testnet server, and update the guide on the wiki to ensure the correct hostname is listed in the recommended zcash.conf. -## F. Update the 1.0 User Guide +### Update the 1.0 User Guide -## G. Publish the release announcement (blog, zcash-dev, slack) +This also means updating [the translations](https://github.com/zcash/zcash-docs). +Coordinate with the translation team for now. Suggestions for improving this +part of the process should be added to #2596. -### G1. Check in with users who opened issues that were resolved in the release +### Publish the release announcement (blog, github, zcash-dev, slack) -Contact all users who opened `user support` issues that were resolved in the release, and ask them if the release fixes or improves their issue. - -## H. Make and deploy deterministic builds - -- Run the [Gitian deterministic build environment](https://github.com/zcash/zcash-gitian) -- Compare the uploaded [build manifests on gitian.sigs](https://github.com/zcash/gitian.sigs) -- If all is well, the DevOps engineer will build the Debian packages and update the - [apt.z.cash package repository](https://apt.z.cash). - -## I. Celebrate - -## missing steps -Zcash still needs: - -* thorough pre-release testing (presumably more thorough than standard PR tests) - -* automated release deployment (e.g.: updating build-depends mirror, deploying testnet, etc...) +## Celebrate diff --git a/doc/security-warnings.md b/doc/security-warnings.md index ab14b9b44..556a55c4a 100644 --- a/doc/security-warnings.md +++ b/doc/security-warnings.md @@ -42,7 +42,7 @@ Wallet encryption is disabled, for several reasons: You should use full-disk encryption (or encryption of your home directory) to protect your wallet at rest, and should assume (even unprivileged) users who are -runnng on your OS can read your wallet.dat file. +running on your OS can read your wallet.dat file. Side-Channel Attacks -------------------- diff --git a/doc/shield-coinbase.md b/doc/shield-coinbase.md new file mode 100644 index 000000000..d3986fec7 --- /dev/null +++ b/doc/shield-coinbase.md @@ -0,0 +1,101 @@ +# Shielding Coinbase UTXOs + +**Summary** + +Use `z_shieldcoinbase` RPC call to shield coinbase UTXOs. + +**Who should read this document** + +Miners, Mining pools, Online wallets + +## Background + +The current Zcash protocol includes a consensus rule that coinbase rewards must be sent to a shielded address. + +## User Experience Challenges + +A user can use the z_sendmany RPC call to shield coinbase funds, but the call was not designed for sweeping up many UTXOs, and offered a suboptimal user experience. + +If customers send mining pool payouts to their online wallet, the service provider must sort through UTXOs to correctly determine the non-coinbase UTXO funds that can be withdrawn or transferred by customers to another transparent address. + +## Solution + +The z_shieldcoinbase call makes it easy to sweep up coinbase rewards from multiple coinbase UTXOs across multiple coinbase reward addresses. + + z_shieldcoinbase fromaddress toaddress (fee) (limit) + +The default fee is 0.0010000 ZEC and the default limit on the maximum number of UTXOs to shield is 50. + +## Examples + +Sweep up coinbase UTXOs from a transparent address you use for mining: + + zcash-cli z_shieldcoinbase tMyMiningAddress zMyPrivateAddress + +Sweep up coinbase UTXOs from multiple transparent addresses to a shielded address: + + zcash-cli z_shieldcoinbase "*" zMyPrivateAddress + +Sweep up with a fee of 1.23 ZEC: + + zcash-cli z_shieldcoinbase tMyMiningAddress zMyPrivateAddress 1.23 + +Sweep up with a fee of 0.1 ZEC and set limit on the maximum number of UTXOs to shield at 25: + + zcash-cli z_shieldcoinbase "*" zMyPrivateAddress 0.1 25 + +### Asynchronous Call + +The `z_shieldcoinbase` RPC call is an asynchronous call, so you can queue up multiple operations. + +When you invoke + + zcash-cli z_shieldcoinbase tMyMiningAddress zMyPrivateAddress + +JSON will be returned immediately, with the following data fields populated: + +- operationid: a temporary id to use with `z_getoperationstatus` and `z_getoperationresult` to get the status and result of the operation. +- shieldedUTXOs: number of coinbase UTXOs being shielded +- shieldedValue: value of coinbase UTXOs being shielded. +- remainingUTXOs: number of coinbase UTXOs still available for shielding. +- remainingValue: value of coinbase UTXOs still available for shielding + +### Locking UTXOs + +The `z_shieldcoinbase` call will lock any selected UTXOs. This prevents the selected UTXOs which are already queued up from being selected for any other send operation. If the `z_shieldcoinbase` call fails, any locked UTXOs are unlocked. + +You can use the RPC call `lockunspent` to see which UTXOs have been locked. You can also use this call to unlock any UTXOs in the event of an unexpected system failure which leaves UTXOs in a locked state. + +### Limits, Performance and Transaction Confirmation + +The number of coinbase UTXOs selected for shielding can be adjusted by setting the limit parameter. The default value is 50. + +If the limit parameter is set to zero, the zcashd `mempooltxinputlimit` option will be used instead, where the default value for `mempooltxinputlimit` is zero, which means no limit. + +Any limit is constrained by a hard limit due to the consensus rule defining a maximum transaction size of 100,000 bytes. + +In general, the more UTXOs that are selected, the longer it takes for the transaction to be verified. Due to the quadratic hashing problem, some miners use the `mempooltxinputlimit` option to reject transactions with a large number of UTXO inputs. + +Currently, as of November 2017, there is no commonly agreed upon limit, but as a rule of thumb (a form of emergent consensus) if a transaction has less than 100 UTXO inputs, the transaction will be mined promptly by the majority of mining pools, but if it has many more UTXO inputs, such as 500, it might take several days to be mined by a miner who has higher or no limits. + +### Anatomy of a z_shieldcoinbase transaction + +The transaction created is a shielded transaction. It consists of a single joinsplit, which consumes coinbase UTXOs as input, and deposits value at a shielded address, minus any fee. + +The number of coinbase UTXOs is determined by a user configured limit. + +If no limit is set (in the case when limit parameter and `mempooltxinputlimit` options are set to zero) the behaviour of z_shieldcoinbase is to consume as many UTXOs as possible, with `z_shieldcoinbase` constructing a transaction up to the size limit of 100,000 bytes. + +As a result, the maximum number of inputs that can be selected is: + +- P2PKH coinbase UTXOs ~ 662 +- 2-of-3 multisig P2SH coinbase UTXOs ~ 244. + +Here is an example of using `z_shieldcoinbase` on testnet to shield multi-sig coinbase UTXOs. + +- Block 141042 is almost ~2 MB in size (the maximum size for a block) and contains 1 coinbase reward transaction and 20 transactions, each indivually created by a call to z_shieldcoinbase. + - https://explorer.testnet.z.cash/block/0050552a78e97c89f666713c8448d49ad1d7263274422272696187dedf6c0d03 +- Drilling down into a transaction, you can see there is one joinsplit, with 244 inputs (vin) and 0 outputs (vout). + - https://explorer.testnet.z.cash/tx/cf4f3da2e434f68b6e361303403344e22a9ff9a8fda9abc180d9520d0ca6527d + + diff --git a/doc/tor.md b/doc/tor.md index 10768ed5b..e02c2bb00 100644 --- a/doc/tor.md +++ b/doc/tor.md @@ -76,7 +76,7 @@ In a typical situation, where you're only reachable via Tor, this should suffice listen on all devices and another node could establish a clearnet connection, when knowing your address. To mitigate this, additionally bind the address of your Tor proxy: - ./bitcoind ... -bind=127.0.0.1 + ./zcashd ... -bind=127.0.0.1 If you don't care too much about hiding your node, and want to be reachable on IPv4 as well, use `discover` instead: diff --git a/doc/wallet-backup.md b/doc/wallet-backup.md new file mode 100644 index 000000000..02454db72 --- /dev/null +++ b/doc/wallet-backup.md @@ -0,0 +1,91 @@ +# Wallet Backup Instructions + +## Overview + +Backing up your Zcash private keys is the best way to be proactive about preventing loss of access to your ZEC. + +Problems resulting from bugs in the code, user error, device failure, etc. may lead to losing access to your wallet (and as a result, the private keys of addresses which are required to spend from them). + +No matter what the cause of a corrupted or lost wallet could be, we highly recommend all users backup on a regular basis. Anytime a new address in the wallet is generated, we recommending making a new backup so all private keys for addresses in your wallet are safe. + +Note that a backup is a duplicate of data needed to spend ZEC so where you keep your backup(s) is another important consideration. You should not store backups where they would be equally or increasingly susceptible to loss or theft. + +## Instructions for backing up your wallet and/or private keys + +These instructions are specific for the officially supported Zcash Linux client. For backing up with third-party wallets, please consult with user guides or support channels provided for those services. + +There are multiple ways to make sure you have at least one other copy of the private keys needed to spend your ZEC and view your shielded ZEC. + +For all methods, you will need to include an export directory setting in your config file (`zcash.conf` located in the data directory which is `~/.zcash/` unless it's been overridden with `datadir=` setting): + +`exportdir=path/to/chosen/export/directory` + +You may chose any directory within the home directory as the location for export & backup files. If the directory doesn't exist, it will be created. + +Note that zcashd will need to be stopped and restarted for edits in the config file to take effect. + +### Using `backupwallet` + +To create a backup of your wallet, use: + +`zcash-cli backupwallet `. + +The backup will be an exact copy of the current state of your wallet.dat file stored in the export directory you specified in the config file. The file path will also be returned. + +If you generate a new Zcash address, it will not be reflected in the backup file. + +If your original `wallet.dat` file becomes inaccessible for whatever reason, you can use your backup by copying it into your data directory and renaming the copy to `wallet.dat`. + +### Using `z_exportwallet` & `z_importwallet` + +If you prefer to have an export of your private keys in human readable format, you can use: + +`zcash-cli z_exportwallet ` + +This will generate a file in the export directory listing all transparent and shielded private keys with their associated public addresses. The file path will be returned in the command line. + +To import keys into a wallet which were previously exported to a file, use: + +`zcash-cli z_importwallet ` + +### Using `z_exportkey`, `z_importkey`, `dumpprivkey` & `importprivkey` + +If you prefer to export a single private key for a shielded address, you can use: + +`zcash-cli z_exportkey ` + +This will return the private key and will not create a new file. + +For exporting a single private key for a transparent address, you can use the command inherited from Bitcoin: + +`zcash-cli dumpprivkey ` + +This will return the private key and will not create a new file. + +To import a private key for a shielded address, use: + +`zcash-cli z_importkey ` + +This will add the key to your wallet and rescan the wallet for associated transactions if it is not already part of the wallet. + +The rescanning process can take a few minutes for a new private key. To skip it, instead use: + +`zcash-cli z_importkey no` + +For other instructions on fine-tuning the wallet rescan, see the command's help documentation: + +`zcash-cli help z_importkey` + +To import a private key for a transparent address, use: + +`zcash-cli importprivkey ` + +This has the same functionality as `z_importkey` but works with transparent addresses. + +See the command's help documentation for instructions on fine-tuning the wallet rescan: + +`zcash-cli help importprivkey` + +### Using `dumpwallet` + +This command inherited from Bitcoin is deprecated. It will export private keys in a similar fashion as `z_exportwallet` but only for transparent addresses. \ No newline at end of file diff --git a/doc/zmq.md b/doc/zmq.md index 9fee74c40..c13a31d2c 100644 --- a/doc/zmq.md +++ b/doc/zmq.md @@ -2,11 +2,11 @@ [ZeroMQ](http://zeromq.org/) is a lightweight wrapper around TCP connections, inter-process communication, and shared-memory, -providing various message-oriented semantics such as publish/subcribe, +providing various message-oriented semantics such as publish/subscribe, request/reply, and push/pull. The Zcash daemon can be configured to act as a trusted "border -router", implementing the zcash wire protocol and relay, making +router", implementing the Zcash wire protocol and relay, making consensus decisions, maintaining the local blockchain database, broadcasting locally generated transactions into the network, and providing a queryable RPC interface to interact on a polled basis for @@ -102,6 +102,6 @@ and just the tip will be notified. It is up to the subscriber to retrieve the chain from the last known block to the new tip. There are several possibilities that ZMQ notification can get lost -during transmission depending on the communication type your are +during transmission depending on the communication type you are using. Zcashd appends an up-counting sequence number to each notification which allows listeners to detect lost notifications. diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 08ff3fe7a..0ed693951 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -11,10 +11,15 @@ export BITCOIND=${REAL_BITCOIND} #Run the tests testScripts=( + 'paymentdisclosure.py' 'prioritisetransaction.py' 'wallet_treestate.py' + 'wallet_anchorfork.py' 'wallet_protectcoinbase.py' + 'wallet_shieldcoinbase.py' + 'wallet_mergetoaddress.py' 'wallet.py' + 'wallet_overwintertx.py' 'wallet_nullifiers.py' 'wallet_1941.py' 'listtransactions.py' @@ -25,7 +30,10 @@ testScripts=( 'rawtransactions.py' 'rest.py' 'mempool_spendcoinbase.py' - 'mempool_coinbase_spends.py' + 'mempool_reorg.py' + 'mempool_tx_input_limit.py' + 'mempool_nu_activation.py' + 'mempool_tx_expiry.py' 'httpbasics.py' 'zapwallettxes.py' 'proxy_test.py' @@ -33,17 +41,21 @@ testScripts=( 'fundrawtransaction.py' 'signrawtransactions.py' 'walletbackup.py' + 'key_import_export.py' 'nodehandling.py' 'reindex.py' 'decodescript.py' 'disablewallet.py' 'zcjoinsplit.py' 'zcjoinsplitdoublespend.py' + 'zkey_import_export.py' + 'reorg_limit.py' 'getblocktemplate.py' + 'bip65-cltv-p2p.py' + 'bipdersig-p2p.py' + 'overwinter_peer_management.py' ); testScriptsExt=( - 'bipdersig-p2p.py' - 'bipdersig.py' 'getblocktemplate_longpoll.py' 'getblocktemplate_proposals.py' 'pruning.py' @@ -65,6 +77,10 @@ if [ "x$ENABLE_ZMQ" = "x1" ]; then testScripts+=('zmq_test.py') fi +if [ "x$ENABLE_PROTON" = "x1" ]; then + testScripts+=('proton_test.py') +fi + extArg="-extended" passOn=${@#$extArg} @@ -78,7 +94,7 @@ function runTestScript echo -e "=== Running testscript ${testName} ===" - if eval "$@" | sed 's/^/ /' + if eval "$@" then successCount=$(expr $successCount + 1) echo "--- Success: ${testName} ---" diff --git a/qa/pull-tester/tests-config.sh.in b/qa/pull-tester/tests-config.sh.in index 1cb9ee06b..cc76e8ad8 100755 --- a/qa/pull-tester/tests-config.sh.in +++ b/qa/pull-tester/tests-config.sh.in @@ -11,6 +11,7 @@ EXEEXT="@EXEEXT@" @BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1 @BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1 @ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1 +@ENABLE_PROTON_TRUE@ENABLE_PROTON=1 REAL_BITCOIND="$BUILDDIR/src/zcashd${EXEEXT}" REAL_BITCOINCLI="$BUILDDIR/src/zcash-cli${EXEEXT}" diff --git a/qa/rpc-tests/README.md b/qa/rpc-tests/README.md index cfda8fe91..a0229b56d 100644 --- a/qa/rpc-tests/README.md +++ b/qa/rpc-tests/README.md @@ -1,13 +1,8 @@ Regression tests of RPC interface ================================= -### [python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc) -Git subtree of [https://github.com/jgarzik/python-bitcoinrpc](https://github.com/jgarzik/python-bitcoinrpc). -Changes to python-bitcoinrpc should be made upstream, and then -pulled here using git subtree. - ### [test_framework/test_framework.py](test_framework/test_framework.py) -Base class for new regression tests. +Base class for RPC regression tests. ### [test_framework/util.py](test_framework/util.py) Generally useful functions. @@ -35,8 +30,8 @@ If you set the environment variable `PYTHON_DEBUG=1` you will get some debug out A 200-block -regtest blockchain and wallets for four nodes is created the first time a regression test is run and -is stored in the cache/ directory. Each node has 25 mature -blocks (25*50=1250 BTC) in its wallet. +is stored in the cache/ directory. Each node has the miner +subsidy from 25 mature blocks (25*10=250 ZEC) in its wallet. After the first run, the cache/ blockchain and wallets are copied into a temporary directory and used as the initial @@ -47,5 +42,5 @@ to recover with: ```bash rm -rf cache -killall bitcoind +killall zcashd ``` diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/qa/rpc-tests/bip65-cltv-p2p.py index 1f8548c21..cfd2df01e 100755 --- a/qa/rpc-tests/bip65-cltv-p2p.py +++ b/qa/rpc-tests/bip65-cltv-p2p.py @@ -5,35 +5,23 @@ # from test_framework.test_framework import ComparisonTestFramework -from test_framework.util import * +from test_framework.util import start_nodes from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP -from binascii import hexlify, unhexlify +from binascii import unhexlify import cStringIO -import time -def cltv_invalidate(tx): - '''Modify the signature in vin 0 of the tx to fail CLTV - - Prepends -1 CLTV DROP in the scriptSig itself. - ''' - tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] + - list(CScript(tx.vin[0].scriptSig))) ''' -This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY) +This test is meant to exercise BIP65 (CHECKLOCKTIMEVERIFY). Connect to a single node. -Mine 2 (version 3) blocks (save the coinbases for later). -Generate 98 more version 3 blocks, verify the node accepts. -Mine 749 version 4 blocks, verify the node accepts. -Check that the new CLTV rules are not enforced on the 750th version 4 block. -Check that the new CLTV rules are enforced on the 751st version 4 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. +Mine a coinbase block, and then ... +Mine 1 version 4 block. +Check that the CLTV rules are enforced. + +TODO: factor out common code from {bipdersig-p2p,bip65-cltv-p2p}.py. ''' class BIP65Test(ComparisonTestFramework): @@ -42,10 +30,10 @@ class BIP65Test(ComparisonTestFramework): self.num_nodes = 1 def setup_network(self): - # Must set the blockversion for this test self.nodes = start_nodes(1, self.options.tmpdir, - extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=3']], + extra_args=[['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) + self.is_network_split = False def run_test(self): test = TestManager(self, self.options.tmpdir) @@ -64,112 +52,45 @@ class BIP65Test(ComparisonTestFramework): tx.deserialize(f) return tx - def get_tests(self): + def invalidate_transaction(self, tx): + ''' + Modify the signature in vin 0 of the tx to fail CLTV - self.coinbase_blocks = self.nodes[0].generate(2) + Prepends -1 CLTV DROP in the scriptSig itself. + ''' + tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] + + list(CScript(tx.vin[0].scriptSig))) + + def get_tests(self): + self.coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = time.time() - ''' 98 more version 3 blocks ''' - test_blocks = [] - for i in xrange(98): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) + '''Check that the rules are enforced.''' + for valid in (True, False): + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, 1.0) + if not valid: + self.invalidate_transaction(spendtx) + spendtx.rehash() - ''' Mine 749 version 4 blocks ''' - test_blocks = [] - for i in xrange(749): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) + gbt = self.nodes[0].getblocktemplate() + self.block_time = gbt["mintime"] + 1 + self.block_bits = int("0x" + gbt["bits"], 0) + + block = create_block(self.tip, create_coinbase(101), + self.block_time, self.block_bits) block.nVersion = 4 + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 + self.block_time += 1 self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) + yield TestInstance([[block, valid]]) - ''' - Check that the new CLTV rules are not enforced in the 750th - version 3 block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) - cltv_invalidate(spendtx) - spendtx.rehash() - - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) - block.nVersion = 4 - block.vtx.append(spendtx) - block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() - block.solve() - - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' - Check that the new CLTV rules are enforced in the 751st version 4 - block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) - cltv_invalidate(spendtx) - spendtx.rehash() - - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 4 - block.vtx.append(spendtx) - block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() - block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) - - ''' Mine 199 new version blocks on last valid tip ''' - test_blocks = [] - for i in xrange(199): - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 4 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 4 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) if __name__ == '__main__': BIP65Test().main() diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py deleted file mode 100755 index e60395dce..000000000 --- a/qa/rpc-tests/bip65-cltv.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2015 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# -# Test the CHECKLOCKTIMEVERIFY (BIP65) soft-fork logic -# - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil - -class BIP65Test(BitcoinTestFramework): - - def setup_network(self): - self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, [])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=3"])) - self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=4"])) - connect_nodes(self.nodes[1], 0) - connect_nodes(self.nodes[2], 0) - self.is_network_split = False - self.sync_all() - - def run_test(self): - cnt = self.nodes[0].getblockcount() - - # Mine some old-version blocks - self.nodes[1].generate(100) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 100): - raise AssertionError("Failed to mine 100 version=3 blocks") - - # Mine 750 new-version blocks - for i in xrange(15): - self.nodes[2].generate(50) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 850): - raise AssertionError("Failed to mine 750 version=4 blocks") - - # TODO: check that new CHECKLOCKTIMEVERIFY rules are not enforced - - # Mine 1 new-version block - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=4 blocks") - - # TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced - - # Mine 198 new-version blocks - for i in xrange(2): - self.nodes[2].generate(99) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1049): - raise AssertionError("Failed to mine 198 version=4 blocks") - - # Mine 1 old-version block - self.nodes[1].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1050): - raise AssertionError("Failed to mine a version=3 block after 949 version=4 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Failed to mine a version=3 block") - - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=3 block after 950 version=4 blocks") - except JSONRPCException: - pass - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Accepted a version=3 block after 950 version=4 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1052): - raise AssertionError("Failed to mine a version=4 block") - -if __name__ == '__main__': - BIP65Test().main() diff --git a/qa/rpc-tests/bipdersig-p2p.py b/qa/rpc-tests/bipdersig-p2p.py index 41717377b..f254843f1 100755 --- a/qa/rpc-tests/bipdersig-p2p.py +++ b/qa/rpc-tests/bipdersig-p2p.py @@ -5,55 +5,34 @@ # from test_framework.test_framework import ComparisonTestFramework -from test_framework.util import * +from test_framework.util import start_nodes from test_framework.mininode import CTransaction, NetworkThread from test_framework.blocktools import create_coinbase, create_block from test_framework.comptool import TestInstance, TestManager from test_framework.script import CScript -from binascii import hexlify, unhexlify +from binascii import unhexlify import cStringIO -import time -# A canonical signature consists of: -# <30> <02> <02> -def unDERify(tx): - ''' - Make the signature in vin 0 of a tx non-DER-compliant, - by adding padding after the S-value. - ''' - scriptSig = CScript(tx.vin[0].scriptSig) - newscript = [] - for i in scriptSig: - if (len(newscript) == 0): - newscript.append(i[0:-1] + '\0' + i[-1]) - else: - newscript.append(i) - tx.vin[0].scriptSig = CScript(newscript) - + ''' This test is meant to exercise BIP66 (DER SIG). Connect to a single node. -Mine 2 (version 2) blocks (save the coinbases for later). -Generate 98 more version 2 blocks, verify the node accepts. -Mine 749 version 3 blocks, verify the node accepts. -Check that the new DERSIG rules are not enforced on the 750th version 3 block. -Check that the new DERSIG rules are enforced on the 751st version 3 block. -Mine 199 new version blocks. -Mine 1 old-version block. -Mine 1 new version block. -Mine 1 old version block, see that the node rejects. +Mine a coinbase block, and then ... +Mine 1 version 4 block. +Check that the DERSIG rules are enforced. + +TODO: factor out common code from {bipdersig-p2p,bip65-cltv-p2p}.py. ''' - class BIP66Test(ComparisonTestFramework): def __init__(self): self.num_nodes = 1 def setup_network(self): - # Must set the blockversion for this test - self.nodes = start_nodes(1, self.options.tmpdir, - extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=2']], + self.nodes = start_nodes(1, self.options.tmpdir, + extra_args=[['-debug', '-whitelist=127.0.0.1']], binary=[self.options.testbinary]) + self.is_network_split = False def run_test(self): test = TestManager(self, self.options.tmpdir) @@ -72,112 +51,52 @@ class BIP66Test(ComparisonTestFramework): tx.deserialize(f) return tx - def get_tests(self): + def invalidate_transaction(self, tx): + ''' + Make the signature in vin 0 of a tx non-DER-compliant, + by adding padding after the S-value. - self.coinbase_blocks = self.nodes[0].generate(2) + A canonical signature consists of: + <30> <02> <02> + ''' + scriptSig = CScript(tx.vin[0].scriptSig) + newscript = [] + for i in scriptSig: + if (len(newscript) == 0): + newscript.append(i[0:-1] + '\0' + i[-1]) + else: + newscript.append(i) + tx.vin[0].scriptSig = CScript(newscript) + + def get_tests(self): + self.coinbase_blocks = self.nodes[0].generate(1) + self.nodes[0].generate(100) self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0) self.nodeaddress = self.nodes[0].getnewaddress() - self.last_block_time = time.time() - ''' 98 more version 2 blocks ''' - test_blocks = [] - for i in xrange(98): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) - block.nVersion = 2 + '''Check that the rules are enforced.''' + for valid in (True, False): + spendtx = self.create_transaction(self.nodes[0], + self.coinbase_blocks[0], + self.nodeaddress, 1.0) + if not valid: + self.invalidate_transaction(spendtx) + spendtx.rehash() + + gbt = self.nodes[0].getblocktemplate() + self.block_time = gbt["mintime"] + 1 + self.block_bits = int("0x" + gbt["bits"], 0) + + block = create_block(self.tip, create_coinbase(101), + self.block_time, self.block_bits) + block.nVersion = 4 + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() block.rehash() block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) + yield TestInstance([[block, valid]]) - ''' Mine 749 version 3 blocks ''' - test_blocks = [] - for i in xrange(749): - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' - Check that the new DERSIG rules are not enforced in the 750th - version 3 block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[0], self.nodeaddress, 1.0) - unDERify(spendtx) - spendtx.rehash() - - block = create_block(self.tip, create_coinbase(2), self.last_block_time + 1) - block.nVersion = 3 - block.vtx.append(spendtx) - block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() - block.solve() - - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' - Check that the new DERSIG rules are enforced in the 751st version 3 - block. - ''' - spendtx = self.create_transaction(self.nodes[0], - self.coinbase_blocks[1], self.nodeaddress, 1.0) - unDERify(spendtx) - spendtx.rehash() - - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 3 - block.vtx.append(spendtx) - block.hashMerkleRoot = block.calc_merkle_root() - block.rehash() - block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) - - ''' Mine 199 new version blocks on last valid tip ''' - test_blocks = [] - for i in xrange(199): - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - test_blocks.append([block, True]) - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance(test_blocks, sync_every_block=False) - - ''' Mine 1 old version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 2 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' Mine 1 new version block ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 3 - block.rehash() - block.solve() - self.last_block_time += 1 - self.tip = block.sha256 - yield TestInstance([[block, True]]) - - ''' Mine 1 old version block, should be invalid ''' - block = create_block(self.tip, create_coinbase(1), self.last_block_time + 1) - block.nVersion = 2 - block.rehash() - block.solve() - self.last_block_time += 1 - yield TestInstance([[block, False]]) if __name__ == '__main__': BIP66Test().main() diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py deleted file mode 100755 index 243f816f6..000000000 --- a/qa/rpc-tests/bipdersig.py +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env python2 -# Copyright (c) 2014 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -# -# Test the BIP66 changeover logic -# - -from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil - -class BIP66Test(BitcoinTestFramework): - - def setup_network(self): - self.nodes = [] - self.nodes.append(start_node(0, self.options.tmpdir, [])) - self.nodes.append(start_node(1, self.options.tmpdir, ["-blockversion=2"])) - self.nodes.append(start_node(2, self.options.tmpdir, ["-blockversion=3"])) - connect_nodes(self.nodes[1], 0) - connect_nodes(self.nodes[2], 0) - self.is_network_split = False - self.sync_all() - - def run_test(self): - cnt = self.nodes[0].getblockcount() - - # Mine some old-version blocks - self.nodes[1].generate(100) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 100): - raise AssertionError("Failed to mine 100 version=2 blocks") - - # Mine 750 new-version blocks - for i in xrange(15): - self.nodes[2].generate(50) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 850): - raise AssertionError("Failed to mine 750 version=3 blocks") - - # TODO: check that new DERSIG rules are not enforced - - # Mine 1 new-version block - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 851): - raise AssertionFailure("Failed to mine a version=3 blocks") - - # TODO: check that new DERSIG rules are enforced - - # Mine 198 new-version blocks - for i in xrange(2): - self.nodes[2].generate(99) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1049): - raise AssertionError("Failed to mine 198 version=3 blocks") - - # Mine 1 old-version block - self.nodes[1].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1050): - raise AssertionError("Failed to mine a version=2 block after 949 version=3 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Failed to mine a version=3 block") - - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") - except JSONRPCException: - pass - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1051): - raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") - - # Mine 1 new-version blocks - self.nodes[2].generate(1) - self.sync_all() - if (self.nodes[0].getblockcount() != cnt + 1052): - raise AssertionError("Failed to mine a version=3 block") - -if __name__ == '__main__': - BIP66Test().main() diff --git a/qa/rpc-tests/decodescript.py b/qa/rpc-tests/decodescript.py index ce3bc94ef..89364a840 100755 --- a/qa/rpc-tests/decodescript.py +++ b/qa/rpc-tests/decodescript.py @@ -4,7 +4,9 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes + class DecodeScriptTest(BitcoinTestFramework): """Tests decoding scripts via RPC command "decodescript".""" diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 67acdcea1..339c6a8f6 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -8,7 +8,8 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import initialize_chain_clean, start_nodes + class DisableWalletTest (BitcoinTestFramework): diff --git a/qa/rpc-tests/forknotify.py b/qa/rpc-tests/forknotify.py index 0acef8e30..1be750a64 100755 --- a/qa/rpc-tests/forknotify.py +++ b/qa/rpc-tests/forknotify.py @@ -8,9 +8,9 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import start_node, connect_nodes + import os -import shutil class ForkNotifyTest(BitcoinTestFramework): @@ -19,7 +19,7 @@ class ForkNotifyTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w'): pass # Just open then close to create zero-length file self.nodes.append(start_node(0, self.options.tmpdir, ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) diff --git a/qa/rpc-tests/fundrawtransaction.py b/qa/rpc-tests/fundrawtransaction.py index 1d15fd132..42896be4f 100755 --- a/qa/rpc-tests/fundrawtransaction.py +++ b/qa/rpc-tests/fundrawtransaction.py @@ -4,9 +4,12 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from pprint import pprint -from time import sleep +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, start_nodes, connect_nodes_bi, stop_nodes, \ + wait_bitcoinds + +from decimal import Decimal # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/getblocktemplate.py b/qa/rpc-tests/getblocktemplate.py index c9777c0c7..82082afa9 100755 --- a/qa/rpc-tests/getblocktemplate.py +++ b/qa/rpc-tests/getblocktemplate.py @@ -4,7 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import initialize_chain_clean, start_nodes, \ + connect_nodes_bi class GetBlockTemplateTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py index aab456242..37a40384b 100755 --- a/qa/rpc-tests/getblocktemplate_longpoll.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -4,8 +4,10 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import AuthServiceProxy +from test_framework.util import random_transaction +from decimal import Decimal def check_array_result(object_array, to_match, expected): """ diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 0c9e7e4cc..16b2e9b94 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -4,7 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import JSONRPCException from binascii import a2b_hex, b2a_hex from hashlib import sha256 diff --git a/qa/rpc-tests/hardforkdetection.py b/qa/rpc-tests/hardforkdetection.py index d399dc964..dbfb5cd34 100755 --- a/qa/rpc-tests/hardforkdetection.py +++ b/qa/rpc-tests/hardforkdetection.py @@ -5,9 +5,10 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, start_node + import os -import shutil class HardForkDetectionTest(BitcoinTestFramework): @@ -16,7 +17,7 @@ class HardForkDetectionTest(BitcoinTestFramework): def setup_network(self): self.nodes = [] self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") - with open(self.alert_filename, 'w') as f: + with open(self.alert_filename, 'w'): pass # Just open then close to create zero-length file self.nodes.append(start_node(0, self.options.tmpdir, ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) diff --git a/qa/rpc-tests/httpbasics.py b/qa/rpc-tests/httpbasics.py index b66533543..b1a4623bd 100755 --- a/qa/rpc-tests/httpbasics.py +++ b/qa/rpc-tests/httpbasics.py @@ -8,7 +8,8 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import assert_equal, start_nodes + import base64 try: @@ -36,45 +37,45 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! - #send 2nd request without closing connection + # send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); - assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + out2 = conn.getresponse().read() + assert_equal('"error":null' in out2, True) # must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! conn.close() - #same should be if we add keep-alive because this should be the std. behaviour + # same should be if we add keep-alive because this should be the std. behaviour headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! - #send 2nd request without closing connection + # send 2nd request without closing connection conn.request('POST', '/', '{"method": "getchaintips"}', headers) - out2 = conn.getresponse().read(); - assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message - assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open! + out2 = conn.getresponse().read() + assert_equal('"error":null' in out2, True) # must also response with a correct json-rpc message + assert_equal(conn.sock!=None, True) # according to http/1.1 connection must still be open! conn.close() - #now do the same with "Connection: close" + # now do the same with "Connection: close" headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"} conn = httplib.HTTPConnection(url.hostname, url.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, False) #now the connection must be closed after the response + assert_equal(conn.sock!=None, False) # now the connection must be closed after the response - #node1 (2nd node) is running with disabled keep-alive option + # node1 (2nd node) is running with disabled keep-alive option urlNode1 = urlparse.urlparse(self.nodes[1].url) authpair = urlNode1.username + ':' + urlNode1.password headers = {"Authorization": "Basic " + base64.b64encode(authpair)} @@ -82,10 +83,10 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) - #node2 (third node) is running with standard keep-alive parameters which means keep-alive is on + # node2 (third node) is running with standard keep-alive parameters which means keep-alive is on urlNode2 = urlparse.urlparse(self.nodes[2].url) authpair = urlNode2.username + ':' + urlNode2.password headers = {"Authorization": "Basic " + base64.b64encode(authpair)} @@ -93,9 +94,9 @@ class HTTPBasicsTest (BitcoinTestFramework): conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port) conn.connect() conn.request('POST', '/', '{"method": "getbestblockhash"}', headers) - out1 = conn.getresponse().read(); + out1 = conn.getresponse().read() assert_equal('"error":null' in out1, True) - assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default + assert_equal(conn.sock!=None, True) # connection must be closed because bitcoind should use keep-alive by default if __name__ == '__main__': - HTTPBasicsTest ().main () + HTTPBasicsTest().main() diff --git a/qa/rpc-tests/invalidateblock.py b/qa/rpc-tests/invalidateblock.py index 2b9c8154e..5cbd1ea98 100755 --- a/qa/rpc-tests/invalidateblock.py +++ b/qa/rpc-tests/invalidateblock.py @@ -8,22 +8,23 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import initialize_chain_clean, start_node, \ + connect_nodes_bi, sync_blocks + +import time class InvalidateTest(BitcoinTestFramework): - - def setup_chain(self): print("Initializing test directory "+self.options.tmpdir) initialize_chain_clean(self.options.tmpdir, 3) - + def setup_network(self): self.nodes = [] - self.is_network_split = False + self.is_network_split = False self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) - + def run_test(self): print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:" print "Mine 4 blocks on Node 0" diff --git a/qa/rpc-tests/invalidblockrequest.py b/qa/rpc-tests/invalidblockrequest.py index 272cc08f9..05b33d772 100755 --- a/qa/rpc-tests/invalidblockrequest.py +++ b/qa/rpc-tests/invalidblockrequest.py @@ -5,11 +5,11 @@ # from test_framework.test_framework import ComparisonTestFramework -from test_framework.util import * +from test_framework.util import assert_equal from test_framework.comptool import TestManager, TestInstance -from test_framework.mininode import * -from test_framework.blocktools import * -import logging +from test_framework.mininode import NetworkThread +from test_framework.blocktools import create_block, create_coinbase, create_transaction + import copy import time @@ -25,7 +25,7 @@ re-requested. # Use the ComparisonTestFramework with 1 node: only use --testbinary. class InvalidBlockRequestTest(ComparisonTestFramework): - ''' Can either run this test as 1 node with expected answers, or two and compare them. + ''' Can either run this test as 1 node with expected answers, or two and compare them. Change the "outcome" variable from each TestInstance object to only do the comparison. ''' def __init__(self): self.num_nodes = 1 diff --git a/qa/rpc-tests/key_import_export.py b/qa/rpc-tests/key_import_export.py new file mode 100755 index 000000000..87b2daa2b --- /dev/null +++ b/qa/rpc-tests/key_import_export.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_greater_than, start_nodes, initialize_chain_clean, connect_nodes_bi + +import logging + +logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) + + +class KeyImportExportTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + self.nodes = start_nodes(4, self.options.tmpdir ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + def run_test(self): + [alice, bob, charlie, miner] = self.nodes + + def alice_to_bob(amount): + alice.sendtoaddress(addr, Decimal(amount)) + self.sync_all() + miner.generate(1) + self.sync_all() + + def verify_utxos(node, amounts): + utxos = node.listunspent(1, 10**9, [addr]) + + def cmp_confirmations_high_to_low(a, b): + return cmp(b["confirmations"], a["confirmations"]) + + utxos.sort(cmp_confirmations_high_to_low) + + try: + assert_equal(amounts, [utxo["amount"] for utxo in utxos]) + except AssertionError: + logging.error( + 'Expected amounts: %r; utxos: %r', + amounts, utxos) + raise + + # Seed Alice with some funds + alice.generate(10) + self.sync_all() + miner.generate(100) + self.sync_all() + + # Now get a pristine address for receiving transfers: + addr = bob.getnewaddress() + verify_utxos(bob, []) + verify_utxos(charlie, []) + + # the amounts of each txn embodied which generates a single UTXO: + amounts = map(Decimal, ['2.3', '3.7', '0.1', '0.5', '1.0', '0.19']) + + # Internal test consistency assertion: + assert_greater_than( + alice.getbalance(), + reduce(Decimal.__add__, amounts)) + + logging.info("Sending pre-export txns...") + for amount in amounts[0:2]: + alice_to_bob(amount) + + logging.info("Exporting privkey from bob...") + privkey = bob.dumpprivkey(addr) + + logging.info("Sending post-export txns...") + for amount in amounts[2:4]: + alice_to_bob(amount) + + verify_utxos(bob, amounts[:4]) + verify_utxos(charlie, []) + + logging.info("Importing privkey into charlie...") + ipkaddr = charlie.importprivkey(privkey, '', True) + assert_equal(addr, ipkaddr) + + # importprivkey should have rescanned, so this should pass: + verify_utxos(charlie, amounts[:4]) + + # Verify idempotent behavior: + ipkaddr2 = charlie.importprivkey(privkey, '', True) + assert_equal(addr, ipkaddr2) + + # amounts should be unchanged + verify_utxos(charlie, amounts[:4]) + + logging.info("Sending post-import txns...") + for amount in amounts[4:]: + alice_to_bob(amount) + + verify_utxos(bob, amounts) + verify_utxos(charlie, amounts) + + +if __name__ == '__main__': + KeyImportExportTest().main() diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index 38d6874dc..a7b32e13f 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -6,18 +6,17 @@ # Exercise the wallet keypool, and interaction with wallet encryption/locking # Add python-bitcoinrpc to module search path: + +from test_framework.authproxy import JSONRPCException +from test_framework.util import check_json_precision, initialize_chain, \ + start_nodes, start_node, stop_nodes, wait_bitcoinds, bitcoind_processes + import os import sys - -import json import shutil -import subprocess import tempfile import traceback -from test_framework.util import * - - def check_array_result(object_array, to_match, expected): """ Pass in array of JSON objects, a dictionary with key/value pairs diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 4df8d795d..a735f41ab 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -6,8 +6,8 @@ # Exercise the listtransactions API from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from decimal import Decimal def check_array_result(object_array, to_match, expected): """ diff --git a/qa/rpc-tests/maxblocksinflight.py b/qa/rpc-tests/maxblocksinflight.py index a601147ce..beef3d2ea 100755 --- a/qa/rpc-tests/maxblocksinflight.py +++ b/qa/rpc-tests/maxblocksinflight.py @@ -4,9 +4,15 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from test_framework.mininode import * +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + EarlyDisconnectError, CInv, msg_inv, mininode_lock from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import initialize_chain_clean, start_nodes, \ + p2p_port + +import os +import time +import random import logging ''' @@ -43,7 +49,6 @@ class TestManager(NodeConnCB): def run(self): try: - fail = False self.connection.rpc.generate(1) # Leave IBD numBlocksToGenerate = [ 8, 16, 128, 1024 ] @@ -56,7 +61,7 @@ class TestManager(NodeConnCB): current_invs = [] if len(current_invs) > 0: self.connection.send_message(msg_inv(current_invs)) - + # Wait and see how many blocks were requested time.sleep(2) @@ -75,7 +80,7 @@ class TestManager(NodeConnCB): self.disconnectOkay = True self.connection.disconnect_node() - + class MaxBlocksInFlightTest(BitcoinTestFramework): def add_options(self, parser): parser.add_option("--testbinary", dest="testbinary", diff --git a/qa/rpc-tests/mempool_nu_activation.py b/qa/rpc-tests/mempool_nu_activation.py new file mode 100755 index 000000000..f54095660 --- /dev/null +++ b/qa/rpc-tests/mempool_nu_activation.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes, wait_and_assert_operationid_status + +from decimal import Decimal + +# Test mempool behaviour around network upgrade activation +class MempoolUpgradeActivationTest(BitcoinTestFramework): + + alert_filename = None # Set by setup_network + + def setup_network(self): + args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000", "-nuparams=5ba81b19:200"] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes(self.nodes[1], 0) + self.is_network_split = False + self.sync_all + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 2) + + def run_test(self): + self.nodes[1].generate(100) + self.sync_all() + + # Mine 97 blocks. After this, nodes[1] blocks + # 1 to 97 are spend-able. + self.nodes[0].generate(97) + self.sync_all() + + # Shield some ZEC + node1_taddr = self.nodes[1].getnewaddress() + node0_zaddr = self.nodes[0].z_getnewaddress() + recipients = [{'address': node0_zaddr, 'amount': Decimal('10')}] + myopid = self.nodes[1].z_sendmany(node1_taddr, recipients, 1, Decimal('0')) + print wait_and_assert_operationid_status(self.nodes[1], myopid) + self.sync_all() + + # Mine block 198. After this, the mempool expects + # block 199, which is the last Sprout block. + self.nodes[0].generate(1) + self.sync_all() + + # Mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Check node 0 shielded balance + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('10')) + + # Fill the mempool with twice as many transactions as can fit into blocks + node0_taddr = self.nodes[0].getnewaddress() + sprout_txids = [] + while self.nodes[1].getmempoolinfo()['bytes'] < 2 * 4000: + sprout_txids.append(self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001'))) + self.sync_all() + + # Spends should be in the mempool + sprout_mempool = set(self.nodes[0].getrawmempool()) + assert_equal(sprout_mempool, set(sprout_txids)) + + # Mine block 199. After this, the mempool expects + # block 200, which is the first Overwinter block. + self.nodes[0].generate(1) + self.sync_all() + + # mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Block 199 should contain a subset of the original mempool + # (with all other transactions having been dropped) + block_txids = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['tx'] + assert(len(block_txids) < len(sprout_txids)) + for txid in block_txids[1:]: # Exclude coinbase + assert(txid in sprout_txids) + + # Create some transparent Overwinter transactions + overwinter_txids = [self.nodes[1].sendtoaddress(node0_taddr, Decimal('0.001')) for i in range(10)] + self.sync_all() + + # Create a shielded Overwinter transaction + recipients = [{'address': node0_taddr, 'amount': Decimal('10')}] + myopid = self.nodes[0].z_sendmany(node0_zaddr, recipients, 1, Decimal('0')) + shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + assert(shielded != None) + overwinter_txids.append(shielded) + self.sync_all() + + # Spends should be in the mempool + assert_equal(set(self.nodes[0].getrawmempool()), set(overwinter_txids)) + + # Node 0 note should be unspendable + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('0')) + + # Invalidate block 199. + self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) + + # BUG: Ideally, the mempool should now only contain the transactions + # that were in block 199, the Overwinter transactions having been dropped. + # However, because chainActive is not updated until after the transactions + # in the disconnected block have been re-added to the mempool, the height + # seen by AcceptToMemoryPool is one greater than it should be. This causes + # the block 199 transactions to be validated against the Overwinter rules, + # and rejected because they (obviously) fail. + #assert_equal(set(self.nodes[0].getrawmempool()), set(block_txids[1:])) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Node 0 note should be spendable again + assert_equal(self.nodes[0].z_getbalance(node0_zaddr), Decimal('10')) + +if __name__ == '__main__': + MempoolUpgradeActivationTest().main() diff --git a/qa/rpc-tests/mempool_coinbase_spends.py b/qa/rpc-tests/mempool_reorg.py similarity index 70% rename from qa/rpc-tests/mempool_coinbase_spends.py rename to qa/rpc-tests/mempool_reorg.py index 578ddb1fb..ad12dadf2 100755 --- a/qa/rpc-tests/mempool_coinbase_spends.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -9,9 +9,9 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_raises, start_node, connect_nodes + # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): @@ -36,8 +36,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework): return signresult["hex"] def run_test(self): - start_count = self.nodes[0].getblockcount() - # Mine three blocks. After this, nodes[0] blocks # 101, 102, and 103 are spend-able. new_blocks = self.nodes[1].generate(4) @@ -52,16 +50,25 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # 3. Indirect (coinbase and child both in chain) : spend_103 and spend_103_1 # Use invalidatblock to make all of the above coinbase spends invalid (immature coinbase), # and make sure the mempool code behaves correctly. - b = [ self.nodes[0].getblockhash(n) for n in range(102, 105) ] + b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ] coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ] - spend_101_raw = self.create_tx(coinbase_txids[0], node1_address, 10) - spend_102_raw = self.create_tx(coinbase_txids[1], node0_address, 10) - spend_103_raw = self.create_tx(coinbase_txids[2], node0_address, 10) + spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 10) + spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 10) + spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 10) + + # Create a block-height-locked transaction which will be invalid after reorg + timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 10}) + # Set the time lock + timelock_tx = timelock_tx.replace("ffffffff", "11111111", 1) + timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" + timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) self.nodes[0].generate(1) + assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 10) @@ -69,7 +76,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework): # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) - self.nodes[0].generate(1) + last_block = self.nodes[0].generate(1) + timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx) # ... now put spend_101 and spend_102_1 in memory pools: spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw) @@ -77,7 +85,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework): self.sync_all() - assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id ])) + assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, timelock_tx_id ])) + + for node in self.nodes: + node.invalidateblock(last_block[0]) + assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, spend_103_1_id ])) # Use invalidateblock to re-org back and make all those coinbase spends # immature/invalid: diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/qa/rpc-tests/mempool_resurrect_test.py index dd3f0486f..1cbbd2cd5 100755 --- a/qa/rpc-tests/mempool_resurrect_test.py +++ b/qa/rpc-tests/mempool_resurrect_test.py @@ -9,9 +9,8 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil +from test_framework.util import assert_equal, start_node + # Create one-input, one-output, no-fee transaction: class MempoolCoinbaseTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index b2ec6937b..5366fb955 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -14,9 +14,10 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, assert_raises, \ + start_node + # Create one-input, one-output, no-fee transaction: class MempoolSpendCoinbaseTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/mempool_tx_expiry.py b/qa/rpc-tests/mempool_tx_expiry.py new file mode 100755 index 000000000..9edf156d2 --- /dev/null +++ b/qa/rpc-tests/mempool_tx_expiry.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test proper expiry for transactions >= version 3 +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, \ + connect_nodes_bi, sync_blocks, start_nodes, \ + wait_and_assert_operationid_status + +from decimal import Decimal + +class MempoolTxExpiryTest(BitcoinTestFramework): + + def setup_nodes(self): + return start_nodes(4, self.options.tmpdir, [["-nuparams=5ba81b19:205", "-txexpirydelta=4", "-debug=mempool"]] * 4) + + # Test before, at, and after expiry block + # TODO: Test case of dependent txs in reorgs + # chain is at block height 199 when run_test executes + def run_test(self): + z_alice = self.nodes[0].z_getnewaddress() + bob = self.nodes[2].getnewaddress() + z_bob = self.nodes[2].z_getnewaddress() + + # When Overwinter not yet activated, no expiryheight in tx + sapling_tx = self.nodes[0].sendtoaddress(bob, 0.01) + rawtx = self.nodes[0].getrawtransaction(sapling_tx, 1) + assert_equal(rawtx["overwintered"], False) + assert("expiryheight" not in rawtx) + + self.nodes[0].generate(6) + self.sync_all() + + ## Shield one of Alice's coinbase funds to her zaddr + res = self.nodes[0].z_shieldcoinbase("*", z_alice, 0.0001, 1) + wait_and_assert_operationid_status(self.nodes[0], res['opid']) + self.nodes[0].generate(1) + self.sync_all() + + # Get balance on node 0 + bal = self.nodes[0].z_gettotalbalance() + print "Balance before zsend, after shielding 10: ", bal + assert_equal(Decimal(bal["private"]), Decimal("9.9999")) + + print "Splitting network..." + self.split_network() + + # Create transactions + zsendamount = Decimal('1.0') - Decimal('0.0001') + recipients = [] + recipients.append({"address": z_bob, "amount": zsendamount}) + myopid = self.nodes[0].z_sendmany(z_alice, recipients) + persist_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + persist_transparent = self.nodes[0].sendtoaddress(bob, 0.01) + # Verify transparent transaction is version 3 intended for Overwinter branch + rawtx = self.nodes[0].getrawtransaction(persist_transparent, 1) + assert_equal(rawtx["version"], 3) + assert_equal(rawtx["overwintered"], True) + assert_equal(rawtx["expiryheight"], 212) + print "Blockheight at persist_transparent & persist_shielded creation:", self.nodes[0].getblockchaininfo()['blocks'] + print "Expiryheight of persist_transparent:", rawtx['expiryheight'] + # Verify shielded transaction is version 3 intended for Overwinter branch + rawtx = self.nodes[0].getrawtransaction(persist_shielded, 1) + print "Expiryheight of persist_shielded", rawtx['expiryheight'] + assert_equal(rawtx["version"], 3) + assert_equal(rawtx["overwintered"], True) + assert_equal(rawtx["expiryheight"], 212) + + print "\n Blockheight advances to less than expiry block height. After reorg, txs should persist in mempool" + assert(persist_transparent in self.nodes[0].getrawmempool()) + assert(persist_shielded in self.nodes[0].getrawmempool()) + assert_equal(set(self.nodes[2].getrawmempool()), set()) + print "mempool node 0:", self.nodes[0].getrawmempool() + print "mempool node 2:", self.nodes[2].getrawmempool() + bal = self.nodes[0].z_gettotalbalance() + print "Printing balance before persist_shielded & persist_transparent are initially mined from mempool", bal + # Txs are mined on node 0; will later be rolled back + self.nodes[0].generate(1) + print "Node 0 generated 1 block" + print "Node 0 height:", self.nodes[0].getblockchaininfo()['blocks'] + print "Node 2 height:", self.nodes[2].getblockchaininfo()['blocks'] + bal = self.nodes[0].z_gettotalbalance() + print "Printing balance after persist_shielded & persist_transparent are mined:", bal + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + print "Mine 2 competing blocks on Node 2..." + blocks = self.nodes[2].generate(2) + for block in blocks: + blk = self.nodes[2].getblock(block) + print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"]) + print "Connect nodes to force a reorg" + connect_nodes_bi(self.nodes,0,2) + self.is_network_split = False + + print "Syncing blocks" + sync_blocks(self.nodes) + + print "Ensure that txs are back in mempool of node 0" + print "Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks'] + print "Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks'] + print "mempool node 0: ", self.nodes[0].getrawmempool() + print "mempool node 2: ", self.nodes[2].getrawmempool() + assert(persist_transparent in self.nodes[0].getrawmempool()) + assert(persist_shielded in self.nodes[0].getrawmempool()) + bal = self.nodes[0].z_gettotalbalance() + # Mine txs to get them out of the way of mempool sync in split_network() + print "Generating another block on node 0 to clear txs from mempool" + self.nodes[0].generate(1) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + sync_blocks(self.nodes) + + print "Splitting network..." + self.split_network() + + print "\n Blockheight advances to equal expiry block height. After reorg, txs should persist in mempool" + myopid = self.nodes[0].z_sendmany(z_alice, recipients) + persist_shielded_2 = wait_and_assert_operationid_status(self.nodes[0], myopid) + persist_transparent_2 = self.nodes[0].sendtoaddress(bob, 0.01) + rawtx_trans = self.nodes[0].getrawtransaction(persist_transparent_2, 1) + rawtx_shield = self.nodes[0].getrawtransaction(persist_shielded_2, 1) + print "Blockheight node 0 at persist_transparent_2 creation:", self.nodes[0].getblockchaininfo()['blocks'] + print "Blockheight node 2 at persist_transparent_2 creation:", self.nodes[2].getblockchaininfo()['blocks'] + print "Expiryheight of persist_transparent_2:", rawtx_trans['expiryheight'] + print "Expiryheight of persist_shielded_2:", rawtx_shield['expiryheight'] + blocks = self.nodes[2].generate(4) + for block in blocks: + blk = self.nodes[2].getblock(block) + print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"]) + print "Connect nodes to force a reorg" + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + print "Ensure that persist_transparent_2 & persist_shielded_2 are in mempool at expiry block height" + print "Blockheight node 0:", self.nodes[0].getblockchaininfo()['blocks'] + print "Blockheight node 2:", self.nodes[2].getblockchaininfo()['blocks'] + print "mempool node 0: ", self.nodes[0].getrawmempool() + print "mempool node 2: ", self.nodes[2].getrawmempool() + assert(persist_transparent_2 in self.nodes[0].getrawmempool()) + assert(persist_shielded_2 in self.nodes[0].getrawmempool()) + # Mine persist txs to get them out of the way of mempool sync in split_network() + self.nodes[0].generate(1) + assert_equal(set(self.nodes[0].getrawmempool()), set()) + sync_blocks(self.nodes) + print "Balance after persist_shielded_2 is mined to remove from mempool: ", self.nodes[0].z_gettotalbalance() + + print "Splitting network..." + self.split_network() + + print "\n Blockheight advances to greater than expiry block height. After reorg, txs should expire from mempool" + print "Balance before expire_shielded is sent: ", self.nodes[0].z_gettotalbalance() + myopid = self.nodes[0].z_sendmany(z_alice, recipients) + expire_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + expire_transparent = self.nodes[0].sendtoaddress(bob, 0.01) + print "Blockheight node 0 at expire_transparent creation:", self.nodes[0].getblockchaininfo()['blocks'] + print "Blockheight node 2 at expire_shielded creation:", self.nodes[2].getblockchaininfo()['blocks'] + print "Expiryheight of expire_transparent:", self.nodes[0].getrawtransaction(expire_transparent, 1)['expiryheight'] + print "Expiryheight of expire_shielded:", self.nodes[0].getrawtransaction(expire_shielded, 1)['expiryheight'] + assert(expire_transparent in self.nodes[0].getrawmempool()) + assert(expire_shielded in self.nodes[0].getrawmempool()) + blocks = self.nodes[2].generate(6) + for block in blocks: + blk = self.nodes[2].getblock(block) + print "Height: {0}, Mined block txs: {1}".format(blk["height"], blk["tx"]) + print "Connect nodes to force a reorg" + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + print "Ensure that expire_transparent & expire_shielded are in mempool at expiry block height" + print "mempool node 0: ", self.nodes[0].getrawmempool() + print "mempool node 2: ", self.nodes[2].getrawmempool() + assert_equal(set(self.nodes[0].getrawmempool()), set()) + print "Ensure balance of node 0 is correct" + bal = self.nodes[0].z_gettotalbalance() + print "Balance after expire_shielded has expired: ", bal + assert_equal(Decimal(bal["private"]), Decimal("7.9999")) + + +if __name__ == '__main__': + MempoolTxExpiryTest().main() diff --git a/qa/rpc-tests/mempool_tx_input_limit.py b/qa/rpc-tests/mempool_tx_input_limit.py new file mode 100755 index 000000000..c48d73be0 --- /dev/null +++ b/qa/rpc-tests/mempool_tx_input_limit.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes, wait_and_assert_operationid_status + +import time +from decimal import Decimal + +# Test -mempooltxinputlimit +class MempoolTxInputLimitTest(BitcoinTestFramework): + + alert_filename = None # Set by setup_network + + def setup_network(self): + args = ["-checkmempool", "-debug=mempool", "-mempooltxinputlimit=2"] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + connect_nodes(self.nodes[1], 0) + self.is_network_split = False + self.sync_all + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 2) + + def call_z_sendmany(self, from_addr, to_addr, amount): + recipients = [] + recipients.append({"address": to_addr, "amount": amount}) + myopid = self.nodes[0].z_sendmany(from_addr, recipients) + return wait_and_assert_operationid_status(self.nodes[0], myopid) + + def run_test(self): + self.nodes[0].generate(100) + self.sync_all() + # Mine three blocks. After this, nodes[0] blocks + # 1, 2, and 3 are spend-able. + self.nodes[1].generate(3) + self.sync_all() + + # Check 1: z_sendmany is limited by -mempooltxinputlimit + + # Add zaddr to node 0 + node0_zaddr = self.nodes[0].z_getnewaddress() + + # Send three inputs from node 0 taddr to zaddr to get out of coinbase + node0_taddr = self.nodes[0].getnewaddress(); + recipients = [] + recipients.append({"address":node0_zaddr, "amount":Decimal('30.0')-Decimal('0.0001')}) # utxo amount less fee + myopid = self.nodes[0].z_sendmany(node0_taddr, recipients) + + opids = [] + opids.append(myopid) + + # Spend should fail due to -mempooltxinputlimit + timeout = 120 + status = None + for x in xrange(1, timeout): + results = self.nodes[0].z_getoperationresult(opids) + if len(results)==0: + time.sleep(1) + else: + status = results[0]["status"] + msg = results[0]["error"]["message"] + assert_equal("failed", status) + assert_equal("Too many transparent inputs 3 > limit 2", msg) + break + + # Mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Reduce amount to only use two inputs + spend_zaddr_amount = Decimal('20.0') - Decimal('0.0001') + spend_zaddr_id = self.call_z_sendmany(node0_taddr, node0_zaddr, spend_zaddr_amount) # utxo amount less fee + self.sync_all() + + # Spend should be in the mempool + assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_zaddr_id ])) + + self.nodes[0].generate(1) + self.sync_all() + + # mempool should be empty. + assert_equal(set(self.nodes[0].getrawmempool()), set()) + + # Check 2: sendfrom is limited by -mempooltxinputlimit + recipients = [] + spend_taddr_amount = spend_zaddr_amount - Decimal('0.0001') + spend_taddr_output = Decimal('8') + + # Create three outputs + recipients.append({"address":self.nodes[1].getnewaddress(), "amount": spend_taddr_output}) + recipients.append({"address":self.nodes[1].getnewaddress(), "amount": spend_taddr_output}) + recipients.append({"address":self.nodes[1].getnewaddress(), "amount": spend_taddr_amount - spend_taddr_output - spend_taddr_output}) + + myopid = self.nodes[0].z_sendmany(node0_zaddr, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + self.nodes[1].generate(1) + self.sync_all() + + # Should use three UTXOs and fail + try: + self.nodes[1].sendfrom("", node0_taddr, spend_taddr_amount - Decimal('1')) + assert(False) + except JSONRPCException,e: + msg = e.error['message'] + assert_equal("Too many transparent inputs 3 > limit 2", msg) + + # mempool should be empty. + assert_equal(set(self.nodes[1].getrawmempool()), set()) + + # Should use two UTXOs and succeed + spend_taddr_id2 = self.nodes[1].sendfrom("", node0_taddr, spend_taddr_output + spend_taddr_output - Decimal('1')) + + # Spend should be in the mempool + assert_equal(set(self.nodes[1].getrawmempool()), set([ spend_taddr_id2 ])) + +if __name__ == '__main__': + MempoolTxInputLimitTest().main() diff --git a/qa/rpc-tests/merkle_blocks.py b/qa/rpc-tests/merkle_blocks.py index 5c333124f..2c0fcd203 100755 --- a/qa/rpc-tests/merkle_blocks.py +++ b/qa/rpc-tests/merkle_blocks.py @@ -8,9 +8,10 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os -import shutil +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_raises, \ + initialize_chain_clean, start_node, connect_nodes + class MerkleBlockTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/nodehandling.py b/qa/rpc-tests/nodehandling.py index 9a77bd97e..391a935d0 100755 --- a/qa/rpc-tests/nodehandling.py +++ b/qa/rpc-tests/nodehandling.py @@ -8,13 +8,10 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import base64 +from test_framework.util import assert_equal, connect_nodes_bi, p2p_port + +import time -try: - import http.client as httplib -except ImportError: - import httplib try: import urllib.parse as urlparse except ImportError: diff --git a/qa/rpc-tests/overwinter_peer_management.py b/qa/rpc-tests/overwinter_peer_management.py new file mode 100755 index 000000000..6c59e47ba --- /dev/null +++ b/qa/rpc-tests/overwinter_peer_management.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.mininode import NodeConn, NodeConnCB, NetworkThread, \ + msg_ping, MY_VERSION, OVERWINTER_PROTO_VERSION +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import initialize_chain_clean, start_nodes, \ + p2p_port, assert_equal + +import time + +# +# In this test we connect Sprout and Overwinter mininodes to a Zcashd node +# which will activate Overwinter at block 10. +# +# We test: +# 1. the mininodes stay connected to Zcash with Sprout consensus rules +# 2. when Overwinter activates, the Sprout mininodes are dropped +# 3. new Overwinter nodes can connect to Zcash +# 4. new Sprout nodes cannot connect to Zcash +# +# This test *does not* verify that prior to Overwinter activation, the Zcashd +# node will prefer connections with Overwinter nodes, with an eviction process +# that prioritizes Sprout connections. +# + + +class TestManager(NodeConnCB): + def __init__(self): + NodeConnCB.__init__(self) + self.create_callback_map() + + def on_close(self, conn): + pass + + def on_reject(self, conn, message): + conn.rejectMessage = message + + +class OverwinterPeerManagementTest(BitcoinTestFramework): + + def setup_chain(self): + print "Initializing test directory "+self.options.tmpdir + initialize_chain_clean(self.options.tmpdir, 1) + + def setup_network(self): + self.nodes = start_nodes(1, self.options.tmpdir, + extra_args=[['-nuparams=5ba81b19:10', '-debug', '-whitelist=127.0.0.1']]) + + def run_test(self): + test = TestManager() + + # Launch 10 Sprout and 10 Overwinter mininodes + nodes = [] + for x in xrange(10): + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", False)) + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", True)) + + # Start up network handling in another thread + NetworkThread().start() + + # Sprout consensus rules apply at block height 9 + self.nodes[0].generate(9) + assert_equal(9, self.nodes[0].getblockcount()) + + # Verify mininodes are still connected to zcashd node + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(10, versions.count(MY_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + + # Overwinter consensus rules activate at block height 10 + self.nodes[0].generate(1) + assert_equal(10, self.nodes[0].getblockcount()) + + # Mininodes send ping message to zcashd node. + pingCounter = 1 + for node in nodes: + node.send_message(msg_ping(pingCounter)) + pingCounter = pingCounter + 1 + + time.sleep(3) + + # Verify Sprout mininodes have been dropped and Overwinter mininodes are still connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(MY_VERSION)) + assert_equal(10, versions.count(OVERWINTER_PROTO_VERSION)) + + # Extend the Overwinter chain with another block. + self.nodes[0].generate(1) + + # Connect a new Overwinter mininode to the zcashd node, which is accepted. + nodes.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", True)) + time.sleep(3) + assert_equal(11, len(self.nodes[0].getpeerinfo())) + + # Try to connect a new Sprout mininode to the zcashd node, which is rejected. + sprout = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test, "regtest", False) + nodes.append(sprout) + time.sleep(3) + assert("Version must be 170003 or greater" in str(sprout.rejectMessage)) + + # Verify that only Overwinter mininodes are connected. + peerinfo = self.nodes[0].getpeerinfo() + versions = [x["version"] for x in peerinfo] + assert_equal(0, versions.count(MY_VERSION)) + assert_equal(11, versions.count(OVERWINTER_PROTO_VERSION)) + + for node in nodes: + node.disconnect_node() + +if __name__ == '__main__': + OverwinterPeerManagementTest().main() diff --git a/qa/rpc-tests/p2p-acceptblock.py b/qa/rpc-tests/p2p-acceptblock.py index 83c03eeb7..25221fbed 100755 --- a/qa/rpc-tests/p2p-acceptblock.py +++ b/qa/rpc-tests/p2p-acceptblock.py @@ -4,12 +4,17 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from test_framework.mininode import * +from test_framework.mininode import CBlockHeader, CInv, NodeConn, NodeConnCB, \ + NetworkThread, msg_block, msg_headers, msg_inv, msg_ping, msg_pong, \ + mininode_lock from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import time +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, p2p_port from test_framework.blocktools import create_block, create_coinbase +import os +import time + ''' AcceptBlockTest -- test processing of unrequested blocks. diff --git a/qa/rpc-tests/paymentdisclosure.py b/qa/rpc-tests/paymentdisclosure.py new file mode 100755 index 000000000..48d4712a9 --- /dev/null +++ b/qa/rpc-tests/paymentdisclosure.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes_bi, wait_and_assert_operationid_status + +from decimal import Decimal + +class PaymentDisclosureTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + args = ['-debug=zrpcunsafe,paymentdisclosure', '-experimentalfeatures', '-paymentdisclosure', '-txindex=1'] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + # node 2 does not enable payment disclosure + args2 = ['-debug=zrpcunsafe', '-experimentalfeatures', '-txindex=1'] + self.nodes.append(start_node(2, self.options.tmpdir, args2)) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + + self.nodes[0].generate(4) + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 40) + assert_equal(walletinfo['balance'], 0) + self.sync_all() + self.nodes[2].generate(3) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 40) + assert_equal(self.nodes[1].getbalance(), 10) + assert_equal(self.nodes[2].getbalance(), 30) + + mytaddr = self.nodes[0].getnewaddress() + myzaddr = self.nodes[0].z_getnewaddress() + + # Check that Node 2 has payment disclosure disabled. + try: + self.nodes[2].z_getpaymentdisclosure("invalidtxid", 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("payment disclosure is disabled" in errorString) + + # Check that Node 0 returns an error for an unknown txid + try: + self.nodes[0].z_getpaymentdisclosure("invalidtxid", 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("No information available about transaction" in errorString) + + # Shield coinbase utxos from node 0 of value 40, standard fee of 0.00010000 + recipients = [{"address":myzaddr, "amount":Decimal('40.0')-Decimal('0.0001')}] + myopid = self.nodes[0].z_sendmany(mytaddr, recipients) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Check the tx has joinsplits + assert( len(self.nodes[0].getrawtransaction("" + txid, 1)["vjoinsplit"]) > 0 ) + + # Sync mempools + self.sync_all() + + # Confirm that you can't create a payment disclosure for an unconfirmed tx + try: + self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Transaction has not been confirmed yet" in errorString) + + try: + self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Transaction has not been confirmed yet" in errorString) + + # Mine tx + self.nodes[0].generate(1) + self.sync_all() + + # Confirm that Node 1 cannot create a payment disclosure for a transaction which does not impact its wallet + try: + self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Transaction does not belong to the wallet" in errorString) + + # Check that an invalid joinsplit index is rejected + try: + self.nodes[0].z_getpaymentdisclosure(txid, 1, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Invalid js_index" in errorString) + + try: + self.nodes[0].z_getpaymentdisclosure(txid, -1, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Invalid js_index" in errorString) + + # Check that an invalid output index is rejected + try: + self.nodes[0].z_getpaymentdisclosure(txid, 0, 2) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Invalid output_index" in errorString) + + try: + self.nodes[0].z_getpaymentdisclosure(txid, 0, -1) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Invalid output_index" in errorString) + + # Ask Node 0 to create and validate a payment disclosure for output 0 + message = "Here is proof of my payment!" + pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 0, message) + result = self.nodes[0].z_validatepaymentdisclosure(pd) + assert(result["valid"]) + output_value_sum = Decimal(result["value"]) + + # Ask Node 1 to confirm the payment disclosure is valid + result = self.nodes[1].z_validatepaymentdisclosure(pd) + assert(result["valid"]) + assert_equal(result["message"], message) + assert_equal(result["value"], output_value_sum) + + # Confirm that payment disclosure begins with prefix zpd: + assert(pd.startswith("zpd:")) + + # Confirm that payment disclosure without prefix zpd: fails validation + try: + self.nodes[1].z_validatepaymentdisclosure(pd[4:]) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("payment disclosure prefix not found" in errorString) + + # Check that total value of output index 0 and index 1 should equal shielding amount of 40 less standard fee. + pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 1) + result = self.nodes[0].z_validatepaymentdisclosure(pd) + output_value_sum += Decimal(result["value"]) + assert_equal(output_value_sum, Decimal('39.99990000')) + + # Create a z->z transaction, sending shielded funds from node 0 to node 1 + node1zaddr = self.nodes[1].z_getnewaddress() + recipients = [{"address":node1zaddr, "amount":Decimal('1')}] + myopid = self.nodes[0].z_sendmany(myzaddr, recipients) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Confirm that Node 0 can create a valid payment disclosure + pd = self.nodes[0].z_getpaymentdisclosure(txid, 0, 0, "a message of your choice") + result = self.nodes[0].z_validatepaymentdisclosure(pd) + assert(result["valid"]) + + # Confirm that Node 1, even as recipient of shielded funds, cannot create a payment disclosure + # as the transaction was created by Node 0 and Node 1's payment disclosure database does not + # contain the necessary data to do so, where the data would only have been available on Node 0 + # when executing z_shieldcoinbase. + try: + self.nodes[1].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Could not find payment disclosure info for the given joinsplit output" in errorString) + + # Payment disclosures cannot be created for transparent transactions. + txid = self.nodes[2].sendtoaddress(mytaddr, 1.0) + self.sync_all() + + # No matter the type of transaction, if it has not been confirmed, it is ignored. + try: + self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Transaction has not been confirmed yet" in errorString) + + self.nodes[0].generate(1) + self.sync_all() + + # Confirm that a payment disclosure can only be generated for a shielded transaction. + try: + self.nodes[0].z_getpaymentdisclosure(txid, 0, 0) + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Transaction is not a shielded transaction" in errorString) + +if __name__ == '__main__': + PaymentDisclosureTest().main() diff --git a/qa/rpc-tests/prioritisetransaction.py b/qa/rpc-tests/prioritisetransaction.py index 2e8f11656..134b9b160 100755 --- a/qa/rpc-tests/prioritisetransaction.py +++ b/qa/rpc-tests/prioritisetransaction.py @@ -4,10 +4,13 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes from test_framework.mininode import COIN +import time + + class PrioritiseTransactionTest (BitcoinTestFramework): def setup_chain(self): @@ -23,34 +26,6 @@ class PrioritiseTransactionTest (BitcoinTestFramework): self.is_network_split=False self.sync_all() - # Returns txid if operation was a success or None - def wait_and_assert_operationid_status(self, myopid, in_status='success', in_errormsg=None): - print('waiting for async operation {}'.format(myopid)) - opids = [] - opids.append(myopid) - timeout = 300 - status = None - errormsg = None - txid = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - sleep(1) - else: - status = results[0]["status"] - if status == "failed": - errormsg = results[0]['error']['message'] - elif status == "success": - txid = results[0]['result']['txid'] - break - print('...returned status: {}'.format(status)) - assert_equal(in_status, status) - if errormsg is not None: - assert(in_errormsg is not None) - assert_equal(in_errormsg in errormsg, True) - print('...returned error: {}'.format(errormsg)) - return txid - def run_test (self): # tx priority is calculated: priority = sum(input_value_in_base_units * input_age)/size_in_bytes @@ -67,7 +42,7 @@ class PrioritiseTransactionTest (BitcoinTestFramework): self.sync_all() # Create tx of lower value to be prioritized on node 0 - # Older transactions get mined first, so this lower value, newer tx is unlikely to be mined without prioritization + # Older transactions get mined first, so this lower value, newer tx is unlikely to be mined without prioritisation priority_tx_0 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) # Check that priority_tx_0 is not in block_template() prior to prioritisation @@ -79,19 +54,50 @@ class PrioritiseTransactionTest (BitcoinTestFramework): break assert_equal(in_block_template, False) - priority_result = self.nodes[0].prioritisetransaction(priority_tx_0, 1000, int(3 * base_fee * COIN)) + priority_success = self.nodes[0].prioritisetransaction(priority_tx_0, 1000, int(3 * base_fee * COIN)) + assert(priority_success) - # Check that prioritized transaction is in getblocktemplate() + # Check that prioritized transaction is not in getblocktemplate() + # (not updated because no new txns) in_block_template = False block_template = self.nodes[0].getblocktemplate() for tx in block_template['transactions']: if tx['hash'] == priority_tx_0: in_block_template = True break - # NOTE: getblocktemplate() should return prioritized transaction, but is not - # Noted by user in issue #1884 assert_equal(in_block_template, False) + # Sending a new transaction will make getblocktemplate refresh within 10s + self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1) + + # Check that prioritized transaction is not in getblocktemplate() + # (too soon) + in_block_template = False + block_template = self.nodes[0].getblocktemplate() + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + assert_equal(in_block_template, False) + + # Check that prioritized transaction is in getblocktemplate() + # getblocktemplate() will refresh after 1 min, or after 10 sec if new transaction is added to mempool + # Mempool is probed every 10 seconds. We'll give getblocktemplate() a maximum of 30 seconds to refresh + block_template = self.nodes[0].getblocktemplate() + start = time.time(); + in_block_template = False + while in_block_template == False: + for tx in block_template['transactions']: + if tx['hash'] == priority_tx_0: + in_block_template = True + break + if time.time() - start > 30: + raise AssertionError("Test timed out because prioritised transaction was not returned by getblocktemplate within 30 seconds.") + time.sleep(1) + block_template = self.nodes[0].getblocktemplate() + + assert(in_block_template) + # Node 1 doesn't get the next block, so this *shouldn't* be mined despite being prioritized on node 1 priority_tx_1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.1) self.nodes[1].prioritisetransaction(priority_tx_1, 1000, int(3 * base_fee * COIN)) diff --git a/qa/rpc-tests/proton_test.py b/qa/rpc-tests/proton_test.py new file mode 100755 index 000000000..d9fb27bd3 --- /dev/null +++ b/qa/rpc-tests/proton_test.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test Proton interface (provides AMQP 1.0 messaging support). +# +# Requirements: +# Python library for Qpid Proton: +# https://pypi.python.org/pypi/python-qpid-proton +# To install: +# pip install python-qpid-proton +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, bytes_to_hex_str, \ + start_nodes + +from proton.handlers import MessagingHandler +from proton.reactor import Container + +import threading + + +class Server(MessagingHandler): + + def __init__(self, url, limit): + super(Server, self).__init__() + self.url = url + self.counter = limit + self.blockhashes = [] + self.txids = [] + self.blockseq = -1 + self.txidseq = -1 + + def on_start(self, event): + print "Proton listening on:", self.url + self.container = event.container + self.acceptor = event.container.listen(self.url) + + def on_message(self, event): + m = event.message + hash = bytes_to_hex_str(m.body) + sequence = m.properties['x-opt-sequence-number'] + if m.subject == "hashtx": + self.txids.append(hash) + + # Test that sequence id is incrementing + assert(sequence == 1 + self.txidseq) + self.txidseq = sequence + elif m.subject == "hashblock": + self.blockhashes.append(hash) + + # Test that sequence id is incrementing + assert(sequence == 1 + self.blockseq) + self.blockseq = sequence + + self.counter = self.counter - 1 + if self.counter == 0: + self.container.stop() + + +class ProtonTest (BitcoinTestFramework): + + port = 25672 + numblocks = 10 # must be even, as two nodes generate equal number + assert(numblocks % 2 == 0) + + def setup_nodes(self): + + # Launch proton server in background thread + # It terminates after receiving numblocks * 2 messages (one for coinbase, one for block) + self.server = Server("127.0.0.1:%i" % self.port, self.numblocks * 2) + self.container = Container(self.server) + self.t1 = threading.Thread(target=self.container.run) + self.t1.start() + + return start_nodes(4, self.options.tmpdir, extra_args=[ + ['-experimentalfeatures', '-debug=amqp', '-amqppubhashtx=amqp://127.0.0.1:'+str(self.port), + '-amqppubhashblock=amqp://127.0.0.1:'+str(self.port)], + [], + [], + [] + ]) + + def run_test(self): + self.sync_all() + baseheight = self.nodes[0].getblockcount() # 200 blocks already mined + + # generate some blocks + self.nodes[0].generate(self.numblocks/2) + self.sync_all() + self.nodes[1].generate(self.numblocks/2) + self.sync_all() + + # wait for server to finish + self.t1.join() + + # sequence numbers have already been checked in the server's message handler + + # sanity check that we have the right number of block hashes and coinbase txids + assert_equal(len(self.server.blockhashes), self.numblocks) + assert_equal(len(self.server.txids), self.numblocks) + + # verify that each block has the correct coinbase txid + for i in xrange(0, self.numblocks): + height = baseheight + i + 1 + blockhash = self.nodes[0].getblockhash(height) + assert_equal(blockhash, self.server.blockhashes[i]) + resp = self.nodes[0].getblock(blockhash) + coinbase = resp["tx"][0] + assert_equal(coinbase, self.server.txids[i]) + + +if __name__ == '__main__': + ProtonTest().main() diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 3623c1616..e4fb48820 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -2,14 +2,14 @@ # Copyright (c) 2015 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -import socket -import traceback, sys -from binascii import hexlify -import time, os from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import assert_equal, start_nodes + +import socket +import os + ''' Test plan: - Start bitcoind's with different proxy configurations diff --git a/qa/rpc-tests/pruning.py b/qa/rpc-tests/pruning.py index 21f8d6938..2639060fa 100755 --- a/qa/rpc-tests/pruning.py +++ b/qa/rpc-tests/pruning.py @@ -12,8 +12,12 @@ # ******** from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import JSONRPCException +from test_framework.util import initialize_chain_clean, start_node, \ + connect_nodes, stop_node, sync_blocks + import os.path +import time def calc_usage(blockdir): return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024) @@ -190,7 +194,7 @@ class PruneTest(BitcoinTestFramework): try: self.nodes[2].getblock(self.forkhash) raise AssertionError("Old block wasn't pruned so can't test redownload") - except JSONRPCException as e: + except JSONRPCException: print "Will need to redownload block",self.forkheight # Verify that we have enough history to reorg back to the fork point @@ -253,7 +257,7 @@ class PruneTest(BitcoinTestFramework): newtx = newtx + rawtx[94:] # Appears to be ever so slightly faster to sign with SIGHASH_NONE signresult = node.signrawtransaction(newtx,None,None,"NONE") - txid = node.sendrawtransaction(signresult["hex"], True) + node.sendrawtransaction(signresult["hex"], True) # Mine a full sized block which will be these transactions we just created node.generate(1) diff --git a/qa/rpc-tests/rawtransactions.py b/qa/rpc-tests/rawtransactions.py index 45517d3fd..dc919f028 100755 --- a/qa/rpc-tests/rawtransactions.py +++ b/qa/rpc-tests/rawtransactions.py @@ -9,9 +9,11 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from pprint import pprint -from time import sleep +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi + +from decimal import Decimal # Create one-input, one-output, no-fee transaction: class RawTransactionsTest(BitcoinTestFramework): @@ -104,18 +106,20 @@ class RawTransactionsTest(BitcoinTestFramework): mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']]) mSigObjValid = self.nodes[2].validateaddress(mSigObj) + assert_equal(mSigObjValid['isvalid'], True) txId = self.nodes[0].sendtoaddress(mSigObj, 2.2); decTx = self.nodes[0].gettransaction(txId) rawTx = self.nodes[0].decoderawtransaction(decTx['hex']) sPK = rawTx['vout'][0]['scriptPubKey']['hex'] + [sPK] # hush pyflakes self.sync_all() self.nodes[0].generate(1) self.sync_all() - #THIS IS A INCOMPLETE FEATURE - #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION - assert_equal(self.nodes[2].getbalance(), bal) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable + # THIS IS A INCOMPLETE FEATURE + # NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION + assert_equal(self.nodes[2].getbalance(), bal) # for now, assume the funds of a 2of3 multisig tx are not marked as spendable txDetails = self.nodes[0].gettransaction(txId, True) rawTx = self.nodes[0].decoderawtransaction(txDetails['hex']) @@ -130,10 +134,10 @@ class RawTransactionsTest(BitcoinTestFramework): outputs = { self.nodes[0].getnewaddress() : 2.199 } rawTx = self.nodes[2].createrawtransaction(inputs, outputs) rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs) - assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx - + assert_equal(rawTxPartialSigned['complete'], False) # node1 only has one key, can't comp. sign the tx + rawTxSigned = self.nodes[2].signrawtransaction(rawTx, inputs) - assert_equal(rawTxSigned['complete'], True) #node2 can sign the tx compl., own two of three keys + assert_equal(rawTxSigned['complete'], True) # node2 can sign the tx compl., own two of three keys self.nodes[2].sendrawtransaction(rawTxSigned['hex']) rawTx = self.nodes[0].decoderawtransaction(rawTxSigned['hex']) self.sync_all() diff --git a/qa/rpc-tests/receivedby.py b/qa/rpc-tests/receivedby.py index 16d6bd4cf..59f7bf258 100755 --- a/qa/rpc-tests/receivedby.py +++ b/qa/rpc-tests/receivedby.py @@ -6,15 +6,14 @@ # Exercise the listreceivedbyaddress API from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from decimal import Decimal def get_sub_array_from_array(object_array, to_match): ''' - Finds and returns a sub array from an array of arrays. - to_match should be a unique idetifier of a sub array + Finds and returns a sub array from an array of arrays. + to_match should be a unique idetifier of a sub array ''' - num_matched = 0 for item in object_array: all_match = True for key,value in to_match.items(): @@ -26,12 +25,12 @@ def get_sub_array_from_array(object_array, to_match): return [] def check_array_result(object_array, to_match, expected, should_not_find = False): - """ - Pass in array of JSON objects, a dictionary with key/value pairs - to match against, and another dictionary with expected key/value - pairs. - If the should_not_find flag is true, to_match should not be found in object_array - """ + ''' + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + If the should_not_find flag is true, to_match should not be found in object_array + ''' if should_not_find == True: expected = { } num_matched = 0 @@ -62,49 +61,49 @@ class ReceivedByTest(BitcoinTestFramework): txid = self.nodes[0].sendtoaddress(addr, 0.1) self.sync_all() - #Check not listed in listreceivedbyaddress because has 0 confirmations + # Check not listed in listreceivedbyaddress because has 0 confirmations check_array_result(self.nodes[1].listreceivedbyaddress(), {"address":addr}, { }, True) - #Bury Tx under 10 block so it will be returned by listreceivedbyaddress + # Bury Tx under 10 block so it will be returned by listreceivedbyaddress self.nodes[1].generate(10) self.sync_all() check_array_result(self.nodes[1].listreceivedbyaddress(), {"address":addr}, {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) - #With min confidence < 10 + # With min confidence < 10 check_array_result(self.nodes[1].listreceivedbyaddress(5), {"address":addr}, {"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}) - #With min confidence > 10, should not find Tx + # With min confidence > 10, should not find Tx check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True) - #Empty Tx + # Empty Tx addr = self.nodes[1].getnewaddress() check_array_result(self.nodes[1].listreceivedbyaddress(0,True), {"address":addr}, {"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]}) ''' - getreceivedbyaddress Test + getreceivedbyaddress Test ''' # Send from node 0 to 1 addr = self.nodes[1].getnewaddress() txid = self.nodes[0].sendtoaddress(addr, 0.1) self.sync_all() - #Check balance is 0 because of 0 confirmations + # Check balance is 0 because of 0 confirmations balance = self.nodes[1].getreceivedbyaddress(addr) if balance != Decimal("0.0"): raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) - #Check balance is 0.1 + # Check balance is 0.1 balance = self.nodes[1].getreceivedbyaddress(addr,0) if balance != Decimal("0.1"): raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) - #Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress + # Bury Tx under 10 block so it will be returned by the default getreceivedbyaddress self.nodes[1].generate(10) self.sync_all() balance = self.nodes[1].getreceivedbyaddress(addr) @@ -112,15 +111,15 @@ class ReceivedByTest(BitcoinTestFramework): raise AssertionError("Wrong balance returned by getreceivedbyaddress, %0.2f"%(balance)) ''' - listreceivedbyaccount + getreceivedbyaccount Test + listreceivedbyaccount + getreceivedbyaccount Test ''' - #set pre-state + # set pre-state addrArr = self.nodes[1].getnewaddress() account = self.nodes[1].getaccount(addrArr) received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(),{"account":account}) if len(received_by_account_json) == 0: raise AssertionError("No accounts found in node") - balance_by_account = rec_by_accountArr = self.nodes[1].getreceivedbyaccount(account) + balance_by_account = self.nodes[1].getreceivedbyaccount(account) txid = self.nodes[0].sendtoaddress(addr, 0.1) self.sync_all() @@ -147,7 +146,7 @@ class ReceivedByTest(BitcoinTestFramework): if balance != balance_by_account + Decimal("0.1"): raise AssertionError("Wrong balance returned by getreceivedbyaccount, %0.2f"%(balance)) - #Create a new account named "mynewaccount" that has a 0 balance + # Create a new account named "mynewaccount" that has a 0 balance self.nodes[1].getaccountaddress("mynewaccount") received_by_account_json = get_sub_array_from_array(self.nodes[1].listreceivedbyaccount(0,True),{"account":"mynewaccount"}) if len(received_by_account_json) == 0: diff --git a/qa/rpc-tests/reindex.py b/qa/rpc-tests/reindex.py index f2e3f248e..ae7563192 100755 --- a/qa/rpc-tests/reindex.py +++ b/qa/rpc-tests/reindex.py @@ -6,9 +6,11 @@ # # Test -reindex with CheckBlockIndex # + from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -import os.path +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, stop_node, wait_bitcoinds + class ReindexTest(BitcoinTestFramework): diff --git a/qa/rpc-tests/reorg_limit.py b/qa/rpc-tests/reorg_limit.py new file mode 100755 index 000000000..12cd146fc --- /dev/null +++ b/qa/rpc-tests/reorg_limit.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Test reorg limit +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + check_node, + connect_nodes_bi, + sync_blocks, +) +from time import sleep + +def check_stopped(i, timeout=10): + stopped = False + for x in xrange(1, timeout): + ret = check_node(i) + if ret is None: + sleep(1) + else: + stopped = True + break + return stopped + +class ReorgLimitTest(BitcoinTestFramework): + + def run_test(self): + assert(self.nodes[0].getblockcount() == 200) + assert(self.nodes[2].getblockcount() == 200) + + self.split_network() + + print "Test the maximum-allowed reorg:" + print "Mine 99 blocks on Node 0" + self.nodes[0].generate(99) + assert(self.nodes[0].getblockcount() == 299) + assert(self.nodes[2].getblockcount() == 200) + + print "Mine competing 100 blocks on Node 2" + self.nodes[2].generate(100) + assert(self.nodes[0].getblockcount() == 299) + assert(self.nodes[2].getblockcount() == 300) + + print "Connect nodes to force a reorg" + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + sync_blocks(self.nodes) + + print "Check Node 0 is still running and on the correct chain" + assert(self.nodes[0].getblockcount() == 300) + + self.split_network() + + print "Test the minimum-rejected reorg:" + print "Mine 100 blocks on Node 0" + self.nodes[0].generate(100) + assert(self.nodes[0].getblockcount() == 400) + assert(self.nodes[2].getblockcount() == 300) + + print "Mine competing 101 blocks on Node 2" + self.nodes[2].generate(101) + assert(self.nodes[0].getblockcount() == 400) + assert(self.nodes[2].getblockcount() == 401) + + print "Sync nodes to force a reorg" + connect_nodes_bi(self.nodes, 0, 2) + self.is_network_split = False + # sync_blocks uses RPC calls to wait for nodes to be synced, so don't + # call it here, because it will have a non-specific connection error + # when Node 0 stops. Instead, we explicitly check for the process itself + # to stop. + + print "Check Node 0 is no longer running" + assert(check_stopped(0)) + + # Dummy stop to enable the test to tear down + self.nodes[0].stop = lambda: True + +if __name__ == '__main__': + ReorgLimitTest().main() diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py index d315c66d3..b14ec765d 100755 --- a/qa/rpc-tests/rest.py +++ b/qa/rpc-tests/rest.py @@ -7,14 +7,15 @@ # Test REST interface # - from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from struct import * +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, start_nodes, connect_nodes_bi + +import struct import binascii import json import StringIO -import decimal +from decimal import Decimal try: import http.client as httplib @@ -28,11 +29,11 @@ except ImportError: def deser_uint256(f): r = 0 for i in range(8): - t = unpack(b">= halvings coinbaseoutput.scriptPubKey = "" coinbase.vout = [ coinbaseoutput ] + if halvings == 0: # regtest + froutput = CTxOut() + froutput.nValue = coinbaseoutput.nValue / 5 + # regtest + fraddr = bytearray([0x67, 0x08, 0xe6, 0x67, 0x0d, 0xb0, 0xb9, 0x50, + 0xda, 0xc6, 0x80, 0x31, 0x02, 0x5c, 0xc5, 0xb6, + 0x32, 0x13, 0xa4, 0x91]) + froutput.scriptPubKey = CScript([OP_HASH160, fraddr, OP_EQUAL]) + coinbaseoutput.nValue -= froutput.nValue + coinbase.vout = [ coinbaseoutput, froutput ] coinbase.calc_sha256() return coinbase diff --git a/qa/rpc-tests/test_framework/comptool.py b/qa/rpc-tests/test_framework/comptool.py index b945f1bf2..7f9a97d68 100755 --- a/qa/rpc-tests/test_framework/comptool.py +++ b/qa/rpc-tests/test_framework/comptool.py @@ -4,10 +4,13 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # -from mininode import * +from mininode import CBlock, CTransaction, CInv, NodeConn, NodeConnCB, \ + msg_inv, msg_getheaders, msg_ping, msg_mempool, mininode_lock, MAX_INV_SZ from blockstore import BlockStore, TxStore from util import p2p_port +import time + ''' This is a tool for comparing two or more bitcoinds to each other using a script provided. @@ -25,8 +28,6 @@ generator that returns TestInstance objects. See below for definition. # on_getheaders: provide headers via BlockStore # on_getdata: provide blocks via BlockStore -global mininode_lock - def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): attempt = 0 elapsed = 0 diff --git a/qa/rpc-tests/test_framework/equihash.py b/qa/rpc-tests/test_framework/equihash.py new file mode 100755 index 000000000..e40451978 --- /dev/null +++ b/qa/rpc-tests/test_framework/equihash.py @@ -0,0 +1,293 @@ +from operator import itemgetter +import struct + +DEBUG = False +VERBOSE = False + + +word_size = 32 +word_mask = (1<= 8 and word_size >= 7+bit_len + bit_len_mask = (1<= bit_len: + acc_bits -= bit_len + for x in xrange(byte_pad, out_width): + out[j+x] = ( + # Big-endian + acc_value >> (acc_bits+(8*(out_width-x-1))) + ) & ( + # Apply bit_len_mask across byte boundaries + (bit_len_mask >> (8*(out_width-x-1))) & 0xFF + ) + j += out_width + + return out + +def compress_array(inp, out_len, bit_len, byte_pad=0): + assert bit_len >= 8 and word_size >= 7+bit_len + + in_width = (bit_len+7)/8 + byte_pad + assert out_len == bit_len*len(inp)/(8*in_width) + out = bytearray(out_len) + + bit_len_mask = (1 << bit_len) - 1 + + # The acc_bits least-significant bits of acc_value represent a bit sequence + # in big-endian order. + acc_bits = 0; + acc_value = 0; + + j = 0 + for i in xrange(out_len): + # When we have fewer than 8 bits left in the accumulator, read the next + # input element. + if acc_bits < 8: + acc_value = ((acc_value << bit_len) & word_mask) | inp[j] + for x in xrange(byte_pad, in_width): + acc_value = acc_value | ( + ( + # Apply bit_len_mask across byte boundaries + inp[j+x] & ((bit_len_mask >> (8*(in_width-x-1))) & 0xFF) + ) << (8*(in_width-x-1))); # Big-endian + j += in_width + acc_bits += bit_len + + acc_bits -= 8 + out[i] = (acc_value >> acc_bits) & 0xFF + + return out + +def get_indices_from_minimal(minimal, bit_len): + eh_index_size = 4 + assert (bit_len+7)/8 <= eh_index_size + len_indices = 8*eh_index_size*len(minimal)/bit_len + byte_pad = eh_index_size - (bit_len+7)/8 + expanded = expand_array(minimal, len_indices, bit_len, byte_pad) + return [struct.unpack('>I', expanded[i:i+4])[0] for i in range(0, len_indices, eh_index_size)] + +def get_minimal_from_indices(indices, bit_len): + eh_index_size = 4 + assert (bit_len+7)/8 <= eh_index_size + len_indices = len(indices)*eh_index_size + min_len = bit_len*len_indices/(8*eh_index_size) + byte_pad = eh_index_size - (bit_len+7)/8 + byte_indices = bytearray(''.join([struct.pack('>I', i) for i in indices])) + return compress_array(byte_indices, min_len, bit_len, byte_pad) + + +def hash_nonce(digest, nonce): + for i in range(8): + digest.update(struct.pack('> (32*i))) + +def hash_xi(digest, xi): + digest.update(struct.pack(' 0: + # 2b) Find next set of unordered pairs with collisions on first n/(k+1) bits + j = 1 + while j < len(X): + if not has_collision(X[-1][0], X[-1-j][0], i, collision_length): + break + j += 1 + + # 2c) Store tuples (X_i ^ X_j, (i, j)) on the table + for l in range(0, j-1): + for m in range(l+1, j): + # Check that there are no duplicate indices in tuples i and j + if distinct_indices(X[-1-l][1], X[-1-m][1]): + if X[-1-l][1][0] < X[-1-m][1][0]: + concat = X[-1-l][1] + X[-1-m][1] + else: + concat = X[-1-m][1] + X[-1-l][1] + Xc.append((xor(X[-1-l][0], X[-1-m][0]), concat)) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + # 2e) Replace previous list with new list + X = Xc + + # k+1) Find a collision on last 2n(k+1) bits + if DEBUG: + print 'Final round:' + print '- Sorting list' + X.sort(key=itemgetter(0)) + if DEBUG and VERBOSE: + for Xi in X[-32:]: + print '%s %s' % (print_hash(Xi[0]), Xi[1]) + if DEBUG: print '- Finding collisions' + solns = [] + while len(X) > 0: + j = 1 + while j < len(X): + if not (has_collision(X[-1][0], X[-1-j][0], k, collision_length) and + has_collision(X[-1][0], X[-1-j][0], k+1, collision_length)): + break + j += 1 + + for l in range(0, j-1): + for m in range(l+1, j): + res = xor(X[-1-l][0], X[-1-m][0]) + if count_zeroes(res) == 8*hash_length and distinct_indices(X[-1-l][1], X[-1-m][1]): + if DEBUG and VERBOSE: + print 'Found solution:' + print '- %s %s' % (print_hash(X[-1-l][0]), X[-1-l][1]) + print '- %s %s' % (print_hash(X[-1-m][0]), X[-1-m][1]) + if X[-1-l][1][0] < X[-1-m][1][0]: + solns.append(list(X[-1-l][1] + X[-1-m][1])) + else: + solns.append(list(X[-1-m][1] + X[-1-l][1])) + + # 2d) Drop this set + while j > 0: + X.pop(-1) + j -= 1 + return [get_minimal_from_indices(soln, collision_length+1) for soln in solns] + +def gbp_validate(digest, minimal, n, k): + validate_params(n, k) + collision_length = n/(k+1) + hash_length = (k+1)*((collision_length+7)//8) + indices_per_hash_output = 512/n + solution_width = (1 << k)*(collision_length+1)//8 + + if len(minimal) != solution_width: + print 'Invalid solution length: %d (expected %d)' % \ + (len(minimal), solution_width) + return False + + X = [] + for i in get_indices_from_minimal(minimal, collision_length+1): + r = i % indices_per_hash_output + # X_i = H(I||V||x_i) + curr_digest = digest.copy() + hash_xi(curr_digest, i/indices_per_hash_output) + tmp_hash = curr_digest.digest() + X.append(( + expand_array(bytearray(tmp_hash[r*n/8:(r+1)*n/8]), + hash_length, collision_length), + (i,) + )) + + for r in range(1, k+1): + Xc = [] + for i in range(0, len(X), 2): + if not has_collision(X[i][0], X[i+1][0], r, collision_length): + print 'Invalid solution: invalid collision length between StepRows' + return False + if X[i+1][1][0] < X[i][1][0]: + print 'Invalid solution: Index tree incorrectly ordered' + return False + if not distinct_indices(X[i][1], X[i+1][1]): + print 'Invalid solution: duplicate indices' + return False + Xc.append((xor(X[i][0], X[i+1][0]), X[i][1] + X[i+1][1])) + X = Xc + + if len(X) != 1: + print 'Invalid solution: incorrect length after end of rounds: %d' % len(X) + return False + + if count_zeroes(X[0][0]) != 8*hash_length: + print 'Invalid solution: incorrect number of zeroes: %d' % count_zeroes(X[0][0]) + return False + + return True + +def zcash_person(n, k): + return b'ZcashPoW' + struct.pack('= n): + raise ValueError('n must be larger than k') + if (((n/(k+1))+1) >= 32): + raise ValueError('Parameters must satisfy n/(k+1)+1 < 32') diff --git a/qa/rpc-tests/test_framework/mininode.py b/qa/rpc-tests/test_framework/mininode.py index c39637073..3c9821259 100755 --- a/qa/rpc-tests/test_framework/mininode.py +++ b/qa/rpc-tests/test_framework/mininode.py @@ -30,9 +30,18 @@ from threading import RLock from threading import Thread import logging import copy +from pyblake2 import blake2b +from .equihash import ( + gbp_basic, + gbp_validate, + hash_nonce, + zcash_person, +) + +OVERWINTER_PROTO_VERSION = 170003 BIP0031_VERSION = 60000 -MY_VERSION = 60001 # past bip-31 for ping/pong +MY_VERSION = 170002 # past bip-31 for ping/pong MY_SUBVERSION = "/python-mininode-tester:0.0.1/" MAX_INV_SZ = 50000 @@ -234,6 +243,36 @@ def ser_int_vector(l): return r +def deser_char_vector(f): + nit = struct.unpack("= 2: + self.vjoinsplit = deser_vector(f, JSDescription) + if len(self.vjoinsplit) > 0: + self.joinSplitPubKey = deser_uint256(f) + self.joinSplitSig = f.read(64) self.sha256 = None self.hash = None @@ -406,6 +604,11 @@ class CTransaction(object): r += ser_vector(self.vin) r += ser_vector(self.vout) r += struct.pack("= 2: + r += ser_vector(self.vjoinsplit) + if len(self.vjoinsplit) > 0: + r += ser_uint256(self.joinSplitPubKey) + r += self.joinSplitSig return r def rehash(self): @@ -425,8 +628,15 @@ class CTransaction(object): return True def __repr__(self): - return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" \ + r = "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i" \ % (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime) + if self.nVersion >= 2: + r += " vjoinsplit=%s" % repr(self.vjoinsplit) + if len(self.vjoinsplit) > 0: + r += " joinSplitPubKey=%064x joinSplitSig=%064x" \ + (self.joinSplitPubKey, self.joinSplitSig) + r += ")" + return r class CBlockHeader(object): @@ -437,20 +647,24 @@ class CBlockHeader(object): self.nVersion = header.nVersion self.hashPrevBlock = header.hashPrevBlock self.hashMerkleRoot = header.hashMerkleRoot + self.hashReserved = header.hashReserved self.nTime = header.nTime self.nBits = header.nBits self.nNonce = header.nNonce + self.nSolution = header.nSolution self.sha256 = header.sha256 self.hash = header.hash self.calc_sha256() def set_null(self): - self.nVersion = 1 + self.nVersion = 4 self.hashPrevBlock = 0 self.hashMerkleRoot = 0 + self.hashReserved = 0 self.nTime = 0 self.nBits = 0 self.nNonce = 0 + self.nSolution = [] self.sha256 = None self.hash = None @@ -458,9 +672,11 @@ class CBlockHeader(object): self.nVersion = struct.unpack(" target: @@ -537,17 +763,31 @@ class CBlock(CBlockHeader): return False return True - def solve(self): - self.calc_sha256() + def solve(self, n=48, k=5): target = uint256_from_compact(self.nBits) - while self.sha256 > target: + # H(I||... + digest = blake2b(digest_size=(512/n)*n/8, person=zcash_person(n, k)) + digest.update(super(CBlock, self).serialize()[:108]) + self.nNonce = 0 + while True: + # H(I||V||... + curr_digest = digest.copy() + hash_nonce(curr_digest, self.nNonce) + # (x_1, x_2, ...) = A(I, V, n, k) + solns = gbp_basic(curr_digest, n, k) + for soln in solns: + assert(gbp_validate(curr_digest, soln, n, k)) + self.nSolution = soln + self.rehash() + if self.sha256 <= target: + return self.nNonce += 1 - self.rehash() def __repr__(self): - return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \ + return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x hashReserved=%064x nTime=%s nBits=%08x nNonce=%064x nSolution=%s vtx=%s)" \ % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, - time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx)) + self.hashReserved, time.ctime(self.nTime), self.nBits, + self.nNonce, repr(self.nSolution), repr(self.vtx)) class CUnsignedAlert(object): @@ -629,8 +869,12 @@ class CAlert(object): class msg_version(object): command = "version" - def __init__(self): - self.nVersion = MY_VERSION + def __init__(self, overwintered=False): + if overwintered: + self.nVersion = OVERWINTER_PROTO_VERSION + else: + self.nVersion = MY_VERSION + self.nServices = 1 self.nTime = time.time() self.addrTo = CAddress() @@ -1082,12 +1326,12 @@ class NodeConn(asyncore.dispatcher): "mempool": msg_mempool } MAGIC_BYTES = { - "mainnet": "\xf9\xbe\xb4\xd9", # mainnet - "testnet3": "\x0b\x11\x09\x07", # testnet3 - "regtest": "\xfa\xbf\xb5\xda" # regtest + "mainnet": "\x24\xe9\x27\x64", # mainnet + "testnet3": "\xfa\x1a\xf9\xbf", # testnet3 + "regtest": "\xaa\xe8\x3f\x5f" # regtest } - def __init__(self, dstaddr, dstport, rpc, callback, net="regtest"): + def __init__(self, dstaddr, dstport, rpc, callback, net="regtest", overwintered=False): asyncore.dispatcher.__init__(self, map=mininode_socket_map) self.log = logging.getLogger("NodeConn(%s:%d)" % (dstaddr, dstport)) self.dstaddr = dstaddr @@ -1104,7 +1348,7 @@ class NodeConn(asyncore.dispatcher): self.disconnect = False # stuff version msg into sendbuf - vt = msg_version() + vt = msg_version(overwintered) vt.addrTo.ip = self.dstaddr vt.addrTo.port = self.dstport vt.addrFrom.ip = "0.0.0.0" diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py index e37ab5d45..55a7f8e51 100644 --- a/qa/rpc-tests/test_framework/script.py +++ b/qa/rpc-tests/test_framework/script.py @@ -24,10 +24,10 @@ if sys.version > '3': bchr = lambda x: bytes([x]) bord = lambda x: x -import copy import struct +import binascii -import test_framework.bignum +from test_framework import bignum MAX_SCRIPT_SIZE = 10000 MAX_SCRIPT_ELEMENT_SIZE = 520 @@ -666,7 +666,7 @@ class CScript(bytes): else: other = CScriptOp.encode_op_pushdata(bignum.bn2vch(other)) elif isinstance(other, (bytes, bytearray)): - other = CScriptOp.encode_op_pushdata(other) + other = bytes(CScriptOp.encode_op_pushdata(other)) return other def __add__(self, other): diff --git a/qa/rpc-tests/test_framework/test_framework.py b/qa/rpc-tests/test_framework/test_framework.py index f44a10a40..56151bb3e 100755 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/qa/rpc-tests/test_framework/test_framework.py @@ -13,8 +13,11 @@ import shutil import tempfile import traceback -from authproxy import AuthServiceProxy, JSONRPCException -from util import * +from authproxy import JSONRPCException +from util import assert_equal, check_json_precision, \ + initialize_chain, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, stop_nodes, \ + sync_blocks, sync_mempools, wait_bitcoinds class BitcoinTestFramework(object): diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index f5ef9dec6..f3ea481ee 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -21,8 +21,7 @@ import subprocess import time import re -from authproxy import AuthServiceProxy, JSONRPCException -from util import * +from authproxy import AuthServiceProxy def p2p_port(n): return 11000 + n + os.getpid()%999 @@ -153,7 +152,7 @@ def initialize_chain_clean(test_dir, num_nodes): Useful if a test case wants complete control over initialization. """ for i in range(num_nodes): - datadir=initialize_datadir(test_dir, i) + initialize_datadir(test_dir, i) def _rpchost_to_args(rpchost): @@ -214,6 +213,10 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None): def log_filename(dirname, n_node, logname): return os.path.join(dirname, "node"+str(n_node), "regtest", logname) +def check_node(i): + bitcoind_processes[i].poll() + return bitcoind_processes[i].returncode + def stop_node(node, i): node.stop() bitcoind_processes[i].wait() @@ -369,3 +372,33 @@ def assert_raises(exc, fun, *args, **kwds): raise AssertionError("Unexpected exception raised: "+type(e).__name__) else: raise AssertionError("No exception raised") + +# Returns txid if operation was a success or None +def wait_and_assert_operationid_status(node, myopid, in_status='success', in_errormsg=None): + print('waiting for async operation {}'.format(myopid)) + opids = [] + opids.append(myopid) + timeout = 300 + status = None + errormsg = None + txid = None + for x in xrange(1, timeout): + results = node.z_getoperationresult(opids) + if len(results)==0: + time.sleep(1) + else: + status = results[0]["status"] + if status == "failed": + errormsg = results[0]['error']['message'] + elif status == "success": + txid = results[0]['result']['txid'] + break + assert_equal(in_status, status) + if errormsg is not None: + assert(in_errormsg is not None) + assert_equal(in_errormsg in errormsg, True) + if os.getenv("PYTHON_DEBUG", ""): + print('...returned status: {}'.format(status)) + if errormsg is not None: + print('...returned error: {}'.format(errormsg)) + return txid diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py index 32699ad9d..bbe383d16 100755 --- a/qa/rpc-tests/txn_doublespend.py +++ b/qa/rpc-tests/txn_doublespend.py @@ -8,10 +8,9 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from decimal import Decimal -import os -import shutil +from test_framework.util import assert_equal, connect_nodes, \ + sync_blocks, gather_inputs + class TxnMallTest(BitcoinTestFramework): @@ -77,7 +76,7 @@ class TxnMallTest(BitcoinTestFramework): assert_equal(tx2["confirmations"], 0) # Now give doublespend to miner: - mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) + self.nodes[2].sendrawtransaction(doublespend["hex"]) # ... mine a block... self.nodes[2].generate(1) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index ff827892a..12dfac0e4 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -5,8 +5,13 @@ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds + +import time +from decimal import Decimal class WalletTest (BitcoinTestFramework): @@ -72,6 +77,18 @@ class WalletTest (BitcoinTestFramework): node0utxos = self.nodes[0].listunspent(1) assert_equal(len(node0utxos), 3) + # Check 'generated' field of listunspent + # Node 0: has one coinbase utxo and two regular utxos + assert_equal(sum(int(uxto["generated"] is True) for uxto in node0utxos), 1) + # Node 1: has 101 coinbase utxos and no regular utxos + node1utxos = self.nodes[1].listunspent(1) + assert_equal(len(node1utxos), 101) + assert_equal(sum(int(uxto["generated"] is True) for uxto in node1utxos), 101) + # Node 2: has no coinbase utxos and two regular utxos + node2utxos = self.nodes[2].listunspent(1) + assert_equal(len(node2utxos), 2) + assert_equal(sum(int(uxto["generated"] is True) for uxto in node2utxos), 0) + # create both transactions txns_to_send = [] for utxo in node0utxos: @@ -100,7 +117,7 @@ class WalletTest (BitcoinTestFramework): # Send 10 BTC normal address = self.nodes[0].getnewaddress("") self.nodes[2].settxfee(Decimal('0.001')) - txid = self.nodes[2].sendtoaddress(address, 10, "", "", False) + self.nodes[2].sendtoaddress(address, 10, "", "", False) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -110,7 +127,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[0].getbalance("*"), Decimal('10.00000000')) # Send 10 BTC with subtract fee from amount - txid = self.nodes[2].sendtoaddress(address, 10, "", "", True) + self.nodes[2].sendtoaddress(address, 10, "", "", True) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -120,7 +137,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[0].getbalance("*"), Decimal('19.99900000')) # Sendmany 10 BTC - txid = self.nodes[2].sendmany("", {address: 10}, 0, "", []) + self.nodes[2].sendmany("", {address: 10}, 0, "", []) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -130,7 +147,7 @@ class WalletTest (BitcoinTestFramework): assert_equal(self.nodes[0].getbalance("*"), Decimal('29.99900000')) # Sendmany 10 BTC with subtract fee from amount - txid = self.nodes[2].sendmany("", {address: 10}, 0, "", [address]) + self.nodes[2].sendmany("", {address: 10}, 0, "", [address]) self.sync_all() self.nodes[2].generate(1) self.sync_all() @@ -171,7 +188,7 @@ class WalletTest (BitcoinTestFramework): signedRawTx = self.nodes[1].signrawtransaction(rawTx) decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex']) zeroValueTxid= decRawTx['txid'] - sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex']) + self.nodes[1].sendrawtransaction(signedRawTx['hex']) self.sync_all() self.nodes[1].generate(1) #mine a block @@ -238,7 +255,7 @@ class WalletTest (BitcoinTestFramework): self.sync_all() mybalance = self.nodes[2].z_getbalance(mytaddr) - assert_equal(self.nodes[2].z_getbalance(mytaddr), Decimal('10.0')); + assert_equal(mybalance, Decimal('10.0')); mytxdetails = self.nodes[2].gettransaction(mytxid) myvjoinsplits = mytxdetails["vjoinsplit"] @@ -254,6 +271,16 @@ class WalletTest (BitcoinTestFramework): for i in xrange(0,num_t_recipients): newtaddr = self.nodes[2].getnewaddress() recipients.append({"address":newtaddr, "amount":amount_per_recipient}) + + # Issue #2759 Workaround START + # HTTP connection to node 0 may fall into a state, during the few minutes it takes to process + # loop above to create new addresses, that when z_sendmany is called with a large amount of + # rpc data in recipients, the connection fails with a 'broken pipe' error. Making a RPC call + # to node 0 before calling z_sendmany appears to fix this issue, perhaps putting the HTTP + # connection into a good state to handle a large amount of data in recipients. + self.nodes[0].getinfo() + # Issue #2759 Workaround END + try: self.nodes[0].z_sendmany(myzaddr, recipients) except JSONRPCException,e: @@ -271,6 +298,11 @@ class WalletTest (BitcoinTestFramework): for i in xrange(0,num_z_recipients): newzaddr = self.nodes[2].z_getnewaddress() recipients.append({"address":newzaddr, "amount":amount_per_recipient}) + + # Issue #2759 Workaround START + self.nodes[0].getinfo() + # Issue #2759 Workaround END + try: self.nodes[0].z_sendmany(myzaddr, recipients) except JSONRPCException,e: @@ -306,7 +338,7 @@ class WalletTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[2].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] mytxid = results[0]["result"]["txid"] @@ -363,7 +395,7 @@ class WalletTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[2].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] break diff --git a/qa/rpc-tests/wallet_1941.py b/qa/rpc-tests/wallet_1941.py index 5f2fe3f72..d70b514fc 100755 --- a/qa/rpc-tests/wallet_1941.py +++ b/qa/rpc-tests/wallet_1941.py @@ -6,10 +6,11 @@ # This is a regression test for #1941. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.util import assert_equal, initialize_chain_clean, \ + initialize_datadir, start_nodes, start_node, connect_nodes_bi, \ + bitcoind_processes, wait_and_assert_operationid_status -import sys +from decimal import Decimal starttime = 1388534400 @@ -39,30 +40,6 @@ class Wallet1941RegressionTest (BitcoinTestFramework): connect_nodes_bi(self.nodes, 0, 1) self.sync_all() - def wait_and_assert_operationid_status(self, myopid, in_status='success', in_errormsg=None): - print('waiting for async operation {}'.format(myopid)) - opids = [] - opids.append(myopid) - timeout = 300 - status = None - errormsg = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - sleep(1) - else: - status = results[0]["status"] - if status == "failed": - errormsg = results[0]['error']['message'] - break - print('...returned status: {}'.format(status)) - print('...error msg: {}'.format(errormsg)) - assert_equal(in_status, status) - if errormsg is not None: - assert(in_errormsg is not None) - assert_equal(in_errormsg in errormsg, True) - print('...returned error: {}'.format(errormsg)) - def run_test (self): print "Mining blocks..." @@ -76,7 +53,7 @@ class Wallet1941RegressionTest (BitcoinTestFramework): recipients = [] recipients.append({"address":myzaddr, "amount":Decimal('10.0') - Decimal('0.0001')}) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) self.nodes[0].generate(1) # Ensure the block times of the latest blocks exceed the variability diff --git a/qa/rpc-tests/wallet_anchorfork.py b/qa/rpc-tests/wallet_anchorfork.py new file mode 100755 index 000000000..a4df66daf --- /dev/null +++ b/qa/rpc-tests/wallet_anchorfork.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, stop_nodes, connect_nodes_bi, \ + wait_and_assert_operationid_status, wait_bitcoinds +from decimal import Decimal + +class WalletAnchorForkTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + # Start nodes with -regtestprotectcoinbase to set fCoinbaseMustBeProtected to true. + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestprotectcoinbase', '-debug=zrpc']] * 3 ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + self.nodes[0].generate(4) + + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 40) + assert_equal(walletinfo['balance'], 0) + + self.sync_all() + self.nodes[1].generate(102) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 40) + assert_equal(self.nodes[1].getbalance(), 20) + assert_equal(self.nodes[2].getbalance(), 0) + + # At this point in time, commitment tree is the empty root + + # Node 0 creates a joinsplit transaction + mytaddr0 = self.nodes[0].getnewaddress() + myzaddr0 = self.nodes[0].z_getnewaddress() + recipients = [] + recipients.append({"address":myzaddr0, "amount": Decimal('10.0') - Decimal('0.0001')}) + myopid = self.nodes[0].z_sendmany(mytaddr0, recipients) + wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Sync up mempools and mine the transaction. All nodes have the same anchor. + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Stop nodes. + stop_nodes(self.nodes) + wait_bitcoinds() + + # Relaunch nodes and partition network into two: + # A: node 0 + # B: node 1, 2 + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestprotectcoinbase', '-debug=zrpc']] * 3 ) + connect_nodes_bi(self.nodes,1,2) + + # Partition B, node 1 mines an empty block + self.nodes[1].generate(1) + + # Partition A, node 0 creates a joinsplit transaction + recipients = [] + recipients.append({"address":myzaddr0, "amount": Decimal('10.0') - Decimal('0.0001')}) + myopid = self.nodes[0].z_sendmany(mytaddr0, recipients) + txid = wait_and_assert_operationid_status(self.nodes[0], myopid) + rawhex = self.nodes[0].getrawtransaction(txid) + + # Partition A, node 0 mines a block with the transaction + self.nodes[0].generate(1) + + # Partition B, node 1 mines the same joinsplit transaction + txid2 = self.nodes[1].sendrawtransaction(rawhex) + assert_equal(txid, txid2) + self.nodes[1].generate(1) + + # Check that Partition B is one block ahead and that they have different tips + assert_equal(self.nodes[0].getblockcount() + 1, self.nodes[1].getblockcount()) + assert( self.nodes[0].getbestblockhash() != self.nodes[1].getbestblockhash()) + + # Shut down all nodes so any in-memory state is saved to disk + stop_nodes(self.nodes) + wait_bitcoinds() + + # Relaunch nodes and reconnect the entire network + self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestprotectcoinbase', '-debug=zrpc']] * 3 ) + connect_nodes_bi(self.nodes,0, 1) + connect_nodes_bi(self.nodes,1, 2) + connect_nodes_bi(self.nodes,0, 2) + + # Mine a new block and let it propagate + self.nodes[1].generate(1) + + # Due to a bug in v1.0.0-1.0.3, node 0 will die with a tree root assertion, so sync_all() will throw an exception. + self.sync_all() + + # v1.0.4 will reach here safely + assert_equal( self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash()) + assert_equal( self.nodes[1].getbestblockhash(), self.nodes[2].getbestblockhash()) + +if __name__ == '__main__': + WalletAnchorForkTest().main() diff --git a/qa/rpc-tests/wallet_mergetoaddress.py b/qa/rpc-tests/wallet_mergetoaddress.py new file mode 100755 index 000000000..ff3534e9b --- /dev/null +++ b/qa/rpc-tests/wallet_mergetoaddress.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes_bi, sync_blocks, sync_mempools, \ + wait_and_assert_operationid_status + +from decimal import Decimal + +class WalletMergeToAddressTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + args = ['-debug=zrpcunsafe', '-experimentalfeatures', '-zmergetoaddress'] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + args2 = ['-debug=zrpcunsafe', '-experimentalfeatures', '-zmergetoaddress', '-mempooltxinputlimit=7'] + self.nodes.append(start_node(2, self.options.tmpdir, args2)) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + + self.nodes[0].generate(1) + do_not_shield_taddr = self.nodes[0].getnewaddress() + + self.nodes[0].generate(4) + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 50) + assert_equal(walletinfo['balance'], 0) + self.sync_all() + self.nodes[2].generate(1) + self.nodes[2].getnewaddress() + self.nodes[2].generate(1) + self.nodes[2].getnewaddress() + self.nodes[2].generate(1) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 50) + assert_equal(self.nodes[1].getbalance(), 10) + assert_equal(self.nodes[2].getbalance(), 30) + + # Shield the coinbase + myzaddr = self.nodes[0].z_getnewaddress() + result = self.nodes[0].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Prepare some UTXOs and notes for merging + mytaddr = self.nodes[0].getnewaddress() + mytaddr2 = self.nodes[0].getnewaddress() + mytaddr3 = self.nodes[0].getnewaddress() + result = self.nodes[0].z_sendmany(myzaddr, [ + {'address': do_not_shield_taddr, 'amount': 10}, + {'address': mytaddr, 'amount': 10}, + {'address': mytaddr2, 'amount': 10}, + {'address': mytaddr3, 'amount': 10}, + ], 1, 0) + wait_and_assert_operationid_status(self.nodes[0], result) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Merging will fail because from arguments need to be in an array + try: + self.nodes[0].z_mergetoaddress("*", myzaddr) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("JSON value is not an array as expected" in errorString, True) + + # Merging will fail when trying to spend from watch-only address + self.nodes[2].importaddress(mytaddr) + try: + self.nodes[2].z_mergetoaddress([mytaddr], myzaddr) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Could not find any funds to merge" in errorString, True) + + # Merging will fail because fee is negative + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, -1) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Merging will fail because fee is larger than MAX_MONEY + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('21000000.00000001')) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Merging will fail because fee is larger than sum of UTXOs + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, 999) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Insufficient funds" in errorString, True) + + # Merging will fail because transparent limit parameter must be at least 0 + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), -1) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Limit on maximum number of UTXOs cannot be negative" in errorString, True) + + # Merging will fail because transparent limit parameter is absurdly large + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 99999999999999) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("JSON integer out of range" in errorString, True) + + # Merging will fail because shielded limit parameter must be at least 0 + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 50, -1) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Limit on maximum number of notes cannot be negative" in errorString, True) + + # Merging will fail because shielded limit parameter is absurdly large + try: + self.nodes[0].z_mergetoaddress(["*"], myzaddr, Decimal('0.001'), 50, 99999999999999) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("JSON integer out of range" in errorString, True) + + # Merging will fail for this specific case where it would spend a fee and do nothing + try: + self.nodes[0].z_mergetoaddress([mytaddr], mytaddr) + assert(False) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Destination address is also the only source address, and all its funds are already merged" in errorString, True) + + # Merge UTXOs from node 0 of value 30, standard fee of 0.00010000 + result = self.nodes[0].z_mergetoaddress([mytaddr, mytaddr2, mytaddr3], myzaddr) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('39.99990000')) + assert_equal(self.nodes[1].getbalance(), 40) + assert_equal(self.nodes[2].getbalance(), 30) + + # Shield all notes to another z-addr + myzaddr2 = self.nodes[0].z_getnewaddress() + result = self.nodes[0].z_mergetoaddress(["ANY_ZADDR"], myzaddr2, 0) + assert_equal(result["mergingUTXOs"], Decimal('0')) + assert_equal(result["remainingUTXOs"], Decimal('0')) + assert_equal(result["mergingNotes"], Decimal('2')) + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + blockhash = self.nodes[1].generate(1) + self.sync_all() + + assert_equal(len(self.nodes[0].getblock(blockhash[0])['tx']), 2) + assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(self.nodes[0].z_getbalance(myzaddr2), Decimal('39.99990000')) + + # Shield coinbase UTXOs from any node 2 taddr, and set fee to 0 + result = self.nodes[2].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('30')) + assert_equal(self.nodes[0].z_getbalance(myzaddr2), Decimal('39.99990000')) + assert_equal(self.nodes[1].getbalance(), 60) + assert_equal(self.nodes[2].getbalance(), 0) + + # Merge all notes from node 0 into a node 0 taddr, and set fee to 0 + result = self.nodes[0].z_mergetoaddress(["ANY_ZADDR"], mytaddr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), Decimal('79.99990000')) + assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + assert_equal(self.nodes[0].z_getbalance(mytaddr), Decimal('69.99990000')) + assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(self.nodes[0].z_getbalance(myzaddr2), 0) + assert_equal(self.nodes[1].getbalance(), 70) + assert_equal(self.nodes[2].getbalance(), 0) + + # Merge all node 0 UTXOs together into a node 1 taddr, and set fee to 0 + self.nodes[1].getnewaddress() # Ensure we have an empty address + n1taddr = self.nodes[1].getnewaddress() + result = self.nodes[0].z_mergetoaddress(["ANY_TADDR"], n1taddr, 0) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 0) + assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), 0) + assert_equal(self.nodes[0].z_getbalance(mytaddr), 0) + assert_equal(self.nodes[0].z_getbalance(myzaddr), 0) + assert_equal(self.nodes[1].getbalance(), Decimal('159.99990000')) + assert_equal(self.nodes[1].z_getbalance(n1taddr), Decimal('79.99990000')) + assert_equal(self.nodes[2].getbalance(), 0) + + # Generate 800 regular UTXOs on node 0, and 20 regular UTXOs on node 2 + mytaddr = self.nodes[0].getnewaddress() + n2taddr = self.nodes[2].getnewaddress() + self.nodes[1].generate(1000) + self.sync_all() + for i in range(800): + self.nodes[1].sendtoaddress(mytaddr, 1) + for i in range(20): + self.nodes[1].sendtoaddress(n2taddr, 1) + self.nodes[1].generate(1) + self.sync_all() + + # Merging the 800 UTXOs will occur over two transactions, since max tx size is 100,000 bytes. + # We don't verify mergingTransparentValue as UTXOs are not selected in any specific order, so value can change on each test run. + # We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of UTXOs. + result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 99999) + assert_equal(result["mergingUTXOs"], Decimal('662')) + assert_equal(result["remainingUTXOs"], Decimal('138')) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["mergingShieldedValue"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + assert_equal(result["remainingShieldedValue"], Decimal('0')) + remainingTransparentValue = result["remainingTransparentValue"] + opid1 = result['opid'] + + # Verify that UTXOs are locked (not available for selection) by queuing up another merging operation + result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, 0, 0) + assert_equal(result["mergingUTXOs"], Decimal('138')) + assert_equal(result["mergingTransparentValue"], Decimal(remainingTransparentValue)) + assert_equal(result["remainingUTXOs"], Decimal('0')) + assert_equal(result["remainingTransparentValue"], Decimal('0')) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["mergingShieldedValue"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + assert_equal(result["remainingShieldedValue"], Decimal('0')) + opid2 = result['opid'] + + # wait for both aysnc operations to complete + wait_and_assert_operationid_status(self.nodes[0], opid1) + wait_and_assert_operationid_status(self.nodes[0], opid2) + + # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected. + # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated + # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced. + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + # Generate enough blocks to ensure all transactions are mined + while self.nodes[1].getmempoolinfo()['size'] > 0: + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of UTXOs which node 2 can shield is limited by option -mempooltxinputlimit + # This option is used when the limit parameter is set to 0. + result = self.nodes[2].z_mergetoaddress([n2taddr], myzaddr, Decimal('0.0001'), 0) + assert_equal(result["mergingUTXOs"], Decimal('7')) + assert_equal(result["remainingUTXOs"], Decimal('13')) + assert_equal(result["mergingNotes"], Decimal('0')) + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of UTXOs which node 0 can shield is set by default limit parameter of 50 + mytaddr = self.nodes[0].getnewaddress() + for i in range(100): + self.nodes[1].sendtoaddress(mytaddr, 1) + self.nodes[1].generate(1) + self.sync_all() + result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, Decimal('0.0001')) + assert_equal(result["mergingUTXOs"], Decimal('50')) + assert_equal(result["remainingUTXOs"], Decimal('50')) + assert_equal(result["mergingNotes"], Decimal('0')) + # Remaining notes are only counted if we are trying to merge any notes + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + # Verify maximum number of UTXOs which node 0 can shield can be set by the limit parameter + result = self.nodes[0].z_mergetoaddress([mytaddr], myzaddr, Decimal('0.0001'), 33) + assert_equal(result["mergingUTXOs"], Decimal('33')) + assert_equal(result["remainingUTXOs"], Decimal('17')) + assert_equal(result["mergingNotes"], Decimal('0')) + # Remaining notes are only counted if we are trying to merge any notes + assert_equal(result["remainingNotes"], Decimal('0')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of notes which node 0 can shield can be set by the limit parameter + result = self.nodes[0].z_mergetoaddress([myzaddr], myzaddr, 0, 50, 2) + assert_equal(result["mergingUTXOs"], Decimal('0')) + # Remaining UTXOs are only counted if we are trying to merge any UTXOs + assert_equal(result["remainingUTXOs"], Decimal('0')) + assert_equal(result["mergingNotes"], Decimal('2')) + assert_equal(result["remainingNotes"], Decimal('3')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Shield both UTXOs and notes to a z-addr + result = self.nodes[0].z_mergetoaddress(["*"], myzaddr, 0, 10, 2) + assert_equal(result["mergingUTXOs"], Decimal('10')) + assert_equal(result["remainingUTXOs"], Decimal('7')) + assert_equal(result["mergingNotes"], Decimal('2')) + assert_equal(result["remainingNotes"], Decimal('2')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + +if __name__ == '__main__': + WalletMergeToAddressTest().main() diff --git a/qa/rpc-tests/wallet_nullifiers.py b/qa/rpc-tests/wallet_nullifiers.py index 93f5a499d..743af7c92 100755 --- a/qa/rpc-tests/wallet_nullifiers.py +++ b/qa/rpc-tests/wallet_nullifiers.py @@ -5,8 +5,11 @@ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.util import assert_equal, start_node, \ + start_nodes, connect_nodes_bi, bitcoind_processes + +import time +from decimal import Decimal class WalletNullifiersTest (BitcoinTestFramework): @@ -32,7 +35,7 @@ class WalletNullifiersTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[0].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] assert_equal("success", status) @@ -73,7 +76,7 @@ class WalletNullifiersTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[0].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] assert_equal("success", status) @@ -105,7 +108,7 @@ class WalletNullifiersTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[2].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] assert_equal("success", status) @@ -146,11 +149,12 @@ class WalletNullifiersTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[1].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] assert_equal("success", status) mytxid = results[0]["result"]["txid"] + [mytxid] # hush pyflakes break self.sync_all() @@ -166,5 +170,50 @@ class WalletNullifiersTest (BitcoinTestFramework): assert_equal(self.nodes[1].z_getbalance(myzaddr), zaddrremaining2) assert_equal(self.nodes[2].z_getbalance(myzaddr), zaddrremaining2) + # Test viewing keys + + node3mined = Decimal('250.0') + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance().items()}, { + 'transparent': node3mined, + 'private': zsendmany2notevalue, + 'total': node3mined + zsendmany2notevalue, + }) + + # add node 1 address and node 2 viewing key to node 3 + myzvkey = self.nodes[2].z_exportviewingkey(myzaddr) + self.nodes[3].importaddress(mytaddr1) + self.nodes[3].z_importviewingkey(myzvkey) + + # Check the address has been imported + assert_equal(myzaddr in self.nodes[3].z_listaddresses(), False) + assert_equal(myzaddr in self.nodes[3].z_listaddresses(True), True) + + # Node 3 should see the same received notes as node 2 + assert_equal( + self.nodes[2].z_listreceivedbyaddress(myzaddr), + self.nodes[3].z_listreceivedbyaddress(myzaddr)) + + # Node 3's balances should be unchanged without explicitly requesting + # to include watch-only balances + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance().items()}, { + 'transparent': node3mined, + 'private': zsendmany2notevalue, + 'total': node3mined + zsendmany2notevalue, + }) + + # Wallet can't cache nullifiers for notes received by addresses it only has a + # viewing key for, and therefore can't detect spends. So it sees a balance + # corresponding to the sum of all notes the address received. + # TODO: Fix this during the Sapling upgrade (via #2277) + assert_equal({k: Decimal(v) for k, v in self.nodes[3].z_gettotalbalance(1, True).items()}, { + 'transparent': node3mined + Decimal('1.0'), + 'private': zsendmany2notevalue + zsendmanynotevalue + zaddrremaining + zaddrremaining2, + 'total': node3mined + Decimal('1.0') + zsendmany2notevalue + zsendmanynotevalue + zaddrremaining + zaddrremaining2, + }) + + # Check individual balances reflect the above + assert_equal(self.nodes[3].z_getbalance(mytaddr1), Decimal('1.0')) + assert_equal(self.nodes[3].z_getbalance(myzaddr), zsendmanynotevalue + zaddrremaining + zaddrremaining2) + if __name__ == '__main__': WalletNullifiersTest().main () diff --git a/qa/rpc-tests/wallet_overwintertx.py b/qa/rpc-tests/wallet_overwintertx.py new file mode 100755 index 000000000..61932fece --- /dev/null +++ b/qa/rpc-tests/wallet_overwintertx.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status + +from decimal import Decimal + +class WalletOverwinterTxTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + self.nodes = start_nodes(4, self.options.tmpdir, extra_args=[["-nuparams=5ba81b19:200", "-debug=zrpcunsafe", "-txindex"]] * 4 ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + self.is_network_split=False + self.sync_all() + + def run_test (self): + self.nodes[0].generate(100) + self.sync_all() + self.nodes[1].generate(98) + self.sync_all() + # Node 0 has reward from blocks 1 to 98 which are spendable. + + taddr0 = self.nodes[0].getnewaddress() + taddr1 = self.nodes[1].getnewaddress() + taddr2 = self.nodes[2].getnewaddress() + zaddr2 = self.nodes[2].z_getnewaddress() + taddr3 = self.nodes[3].getnewaddress() + zaddr3 = self.nodes[3].z_getnewaddress() + + # + # Currently at block 198. The next block to be mined 199 is a Sprout block + # + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '00000000') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') + + # Node 0 sends transparent funds to Node 2 + tsendamount = Decimal('1.0') + txid_transparent = self.nodes[0].sendtoaddress(taddr2, tsendamount) + self.sync_all() + + # Node 2 sends the zero-confirmation transparent funds to Node 1 using z_sendmany + recipients = [] + recipients.append({"address":taddr1, "amount": Decimal('0.5')}) + myopid = self.nodes[2].z_sendmany(taddr2, recipients, 0) + txid_zsendmany = wait_and_assert_operationid_status(self.nodes[2], myopid) + + # Node 0 shields to Node 2, a coinbase utxo of value 10.0 less fee 0.00010000 + zsendamount = Decimal('10.0') - Decimal('0.0001') + recipients = [] + recipients.append({"address":zaddr2, "amount": zsendamount}) + myopid = self.nodes[0].z_sendmany(taddr0, recipients) + txid_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + + # Verify balance + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('0.5')) + assert_equal(self.nodes[2].getbalance(), Decimal('0.4999')) + assert_equal(self.nodes[2].z_getbalance(zaddr2), zsendamount) + + # Verify transaction versions are 1 or 2 (intended for Sprout) + result = self.nodes[0].getrawtransaction(txid_transparent, 1) + assert_equal(result["version"], 1) + assert_equal(result["overwintered"], False) + result = self.nodes[0].getrawtransaction(txid_zsendmany, 1) + assert_equal(result["version"], 1) + assert_equal(result["overwintered"], False) + result = self.nodes[0].getrawtransaction(txid_shielded, 1) + assert_equal(result["version"], 2) + assert_equal(result["overwintered"], False) + + # + # Currently at block 199. The next block to be mined 200 is an Overwinter block + # + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '00000000') + assert_equal(bci['consensus']['nextblock'], '5ba81b19') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'pending') + + # Node 0 sends transparent funds to Node 3 + tsendamount = Decimal('1.0') + txid_transparent = self.nodes[0].sendtoaddress(taddr3, tsendamount) + self.sync_all() + + # Node 3 sends the zero-confirmation transparent funds to Node 1 using z_sendmany + recipients = [] + recipients.append({"address":taddr1, "amount": Decimal('0.5')}) + myopid = self.nodes[3].z_sendmany(taddr3, recipients, 0) + txid_zsendmany = wait_and_assert_operationid_status(self.nodes[3], myopid) + + # Node 0 shields to Node 3, a coinbase utxo of value 10.0 less fee 0.00010000 + zsendamount = Decimal('10.0') - Decimal('0.0001') + recipients = [] + recipients.append({"address":zaddr3, "amount": zsendamount}) + myopid = self.nodes[0].z_sendmany(taddr0, recipients) + txid_shielded = wait_and_assert_operationid_status(self.nodes[0], myopid) + + # Mine the first Overwinter block + self.sync_all() + self.nodes[0].generate(1) + self.sync_all() + bci = self.nodes[0].getblockchaininfo() + assert_equal(bci['consensus']['chaintip'], '5ba81b19') + assert_equal(bci['consensus']['nextblock'], '5ba81b19') + assert_equal(bci['upgrades']['5ba81b19']['status'], 'active') + + # Verify balance + assert_equal(self.nodes[1].z_getbalance(taddr1), Decimal('1.0')) + assert_equal(self.nodes[3].getbalance(), Decimal('0.4999')) + assert_equal(self.nodes[3].z_getbalance(zaddr3), zsendamount) + + # Verify transaction version is 3 (intended for Overwinter) + result = self.nodes[0].getrawtransaction(txid_transparent, 1) + assert_equal(result["version"], 3) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "03c48270") + result = self.nodes[0].getrawtransaction(txid_zsendmany, 1) + assert_equal(result["version"], 3) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "03c48270") + result = self.nodes[0].getrawtransaction(txid_shielded, 1) + assert_equal(result["version"], 3) + assert_equal(result["overwintered"], True) + assert_equal(result["versiongroupid"], "03c48270") + +if __name__ == '__main__': + WalletOverwinterTxTest().main() diff --git a/qa/rpc-tests/wallet_protectcoinbase.py b/qa/rpc-tests/wallet_protectcoinbase.py index 1ed0d5b1f..afe851a16 100755 --- a/qa/rpc-tests/wallet_protectcoinbase.py +++ b/qa/rpc-tests/wallet_protectcoinbase.py @@ -5,8 +5,26 @@ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.authproxy import JSONRPCException +from test_framework.mininode import COIN +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, stop_node, wait_and_assert_operationid_status + +import sys +import time +import timeit +from decimal import Decimal + +def check_value_pool(node, name, total): + value_pools = node.getblockchaininfo()['valuePools'] + found = False + for pool in value_pools: + if pool['id'] == name: + found = True + assert_equal(pool['monitored'], True) + assert_equal(pool['chainValue'], total) + assert_equal(pool['chainValueZat'], total * COIN) + assert(found) class WalletProtectCoinbaseTest (BitcoinTestFramework): @@ -16,41 +34,14 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): # Start nodes with -regtestprotectcoinbase to set fCoinbaseMustBeProtected to true. def setup_network(self, split=False): - self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-regtestprotectcoinbase', '-debug=zrpcunsafe']] * 3 ) + self.nodes = start_nodes(4, self.options.tmpdir, extra_args=[['-regtestprotectcoinbase', '-debug=zrpcunsafe']] * 4 ) connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) self.is_network_split=False self.sync_all() - # Returns txid if operation was a success or None - def wait_and_assert_operationid_status(self, myopid, in_status='success', in_errormsg=None): - print('waiting for async operation {}'.format(myopid)) - opids = [] - opids.append(myopid) - timeout = 300 - status = None - errormsg = None - txid = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - sleep(1) - else: - status = results[0]["status"] - if status == "failed": - errormsg = results[0]['error']['message'] - elif status == "success": - txid = results[0]['result']['txid'] - break - print('...returned status: {}'.format(status)) - assert_equal(in_status, status) - if errormsg is not None: - assert(in_errormsg is not None) - assert_equal(in_errormsg in errormsg, True) - print('...returned error: {}'.format(errormsg)) - return txid - def run_test (self): print "Mining blocks..." @@ -67,6 +58,12 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): assert_equal(self.nodes[0].getbalance(), 40) assert_equal(self.nodes[1].getbalance(), 10) assert_equal(self.nodes[2].getbalance(), 0) + assert_equal(self.nodes[3].getbalance(), 0) + + check_value_pool(self.nodes[0], 'sprout', 0) + check_value_pool(self.nodes[1], 'sprout', 0) + check_value_pool(self.nodes[2], 'sprout', 0) + check_value_pool(self.nodes[3], 'sprout', 0) # Send will fail because we are enforcing the consensus rule that # coinbase utxos can only be sent to a zaddr. @@ -81,6 +78,27 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): mytaddr = self.nodes[0].getnewaddress() myzaddr = self.nodes[0].z_getnewaddress() + # Node 3 will test that watch only address utxos are not selected + self.nodes[3].importaddress(mytaddr) + recipients= [{"address":myzaddr, "amount": Decimal('1')}] + myopid = self.nodes[3].z_sendmany(mytaddr, recipients) + errorString="" + status = None + opids = [myopid] + timeout = 10 + for x in xrange(1, timeout): + results = self.nodes[3].z_getoperationresult(opids) + if len(results)==0: + time.sleep(1) + else: + status = results[0]["status"] + errorString = results[0]["error"]["message"] + break + assert_equal("failed", status) + assert_equal("no UTXOs found for taddr from address" in errorString, True) + stop_node(self.nodes[3], 3) + self.nodes.pop() + # This send will fail because our wallet does not allow any change when protecting a coinbase utxo, # as it's currently not possible to specify a change address in z_sendmany. recipients = [] @@ -94,7 +112,7 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): for x in xrange(1, timeout): results = self.nodes[0].z_getoperationresult(opids) if len(results)==0: - sleep(1) + time.sleep(1) else: status = results[0]["status"] errorString = results[0]["error"]["message"] @@ -112,10 +130,11 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): assert_equal("wallet does not allow any change" in errorString, True) # This send will succeed. We send two coinbase utxos totalling 20.0 less a fee of 0.00010000, with no change. + shieldvalue = Decimal('20.0') - Decimal('0.0001') recipients = [] - recipients.append({"address":myzaddr, "amount": Decimal('20.0') - Decimal('0.0001')}) + recipients.append({"address":myzaddr, "amount": shieldvalue}) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - mytxid = self.wait_and_assert_operationid_status(myopid) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -140,11 +159,15 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): assert_equal(Decimal(resp["private"]), Decimal('19.9999')) assert_equal(Decimal(resp["total"]), Decimal('39.9999')) + # The Sprout value pool should reflect the send + sproutvalue = shieldvalue + check_value_pool(self.nodes[0], 'sprout', sproutvalue) + # A custom fee of 0 is okay. Here the node will send the note value back to itself. recipients = [] recipients.append({"address":myzaddr, "amount": Decimal('19.9999')}) myopid = self.nodes[0].z_sendmany(myzaddr, recipients, 1, Decimal('0.0')) - mytxid = self.wait_and_assert_operationid_status(myopid) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -153,11 +176,15 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): assert_equal(Decimal(resp["private"]), Decimal('19.9999')) assert_equal(Decimal(resp["total"]), Decimal('39.9999')) + # The Sprout value pool should be unchanged + check_value_pool(self.nodes[0], 'sprout', sproutvalue) + # convert note to transparent funds + unshieldvalue = Decimal('10.0') recipients = [] - recipients.append({"address":mytaddr, "amount":Decimal('10.0')}) + recipients.append({"address":mytaddr, "amount": unshieldvalue}) myopid = self.nodes[0].z_sendmany(myzaddr, recipients) - mytxid = self.wait_and_assert_operationid_status(myopid) + mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid) assert(mytxid is not None) self.sync_all() @@ -169,10 +196,12 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): self.sync_all() # check balances + sproutvalue -= unshieldvalue + Decimal('0.0001') resp = self.nodes[0].z_gettotalbalance() assert_equal(Decimal(resp["transparent"]), Decimal('30.0')) assert_equal(Decimal(resp["private"]), Decimal('9.9998')) assert_equal(Decimal(resp["total"]), Decimal('39.9998')) + check_value_pool(self.nodes[0], 'sprout', sproutvalue) # z_sendmany will return an error if there is transparent change output considered dust. # UTXO selection in z_sendmany sorts in ascending order, so smallest utxos are consumed first. @@ -181,7 +210,7 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): amount = Decimal('10.0') - Decimal('0.00010000') - Decimal('0.00000001') # this leaves change at 1 zatoshi less than dust threshold recipients.append({"address":self.nodes[0].getnewaddress(), "amount":amount }) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid, "failed", "Insufficient transparent funds, have 10.00, need 0.00000053 more to avoid creating invalid change output 0.00000001 (dust threshold is 0.00000054)") + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient transparent funds, have 10.00, need 0.00000053 more to avoid creating invalid change output 0.00000001 (dust threshold is 0.00000054)") # Send will fail because send amount is too big, even when including coinbase utxos errorString = "" @@ -195,9 +224,9 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): recipients = [] recipients.append({"address":self.nodes[1].getnewaddress(), "amount":Decimal('10000.0')}) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid, "failed", "Insufficient transparent funds, have 10.00, need 10000.0001") + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient transparent funds, have 10.00, need 10000.0001") myopid = self.nodes[0].z_sendmany(myzaddr, recipients) - self.wait_and_assert_operationid_status(myopid, "failed", "Insufficient protected funds, have 9.9998, need 10000.0001") + wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", "Insufficient protected funds, have 9.9998, need 10000.0001") # Send will fail because of insufficient funds unless sender uses coinbase utxos try: @@ -216,12 +245,25 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): amount_per_recipient = Decimal('0.00000546') # dust threshold # Note that regtest chainparams does not require standard tx, so setting the amount to be # less than the dust threshold, e.g. 0.00000001 will not result in mempool rejection. + start_time = timeit.default_timer() for i in xrange(0,num_t_recipients): newtaddr = self.nodes[2].getnewaddress() recipients.append({"address":newtaddr, "amount":amount_per_recipient}) + elapsed = timeit.default_timer() - start_time + print("...invoked getnewaddress() {} times in {} seconds".format(num_t_recipients, elapsed)) + + # Issue #2263 Workaround START + # HTTP connection to node 0 may fall into a state, during the few minutes it takes to process + # loop above to create new addresses, that when z_sendmany is called with a large amount of + # rpc data in recipients, the connection fails with a 'broken pipe' error. Making a RPC call + # to node 0 before calling z_sendmany appears to fix this issue, perhaps putting the HTTP + # connection into a good state to handle a large amount of data in recipients. + self.nodes[0].getinfo() + # Issue #2263 Workaround END + myopid = self.nodes[0].z_sendmany(myzaddr, recipients) try: - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) except JSONRPCException as e: print("JSONRPC error: "+e.error['message']) assert(False) @@ -235,7 +277,9 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): # check balance node2balance = amount_per_recipient * num_t_recipients + sproutvalue -= node2balance + Decimal('0.0001') assert_equal(self.nodes[2].getbalance(), node2balance) + check_value_pool(self.nodes[0], 'sprout', sproutvalue) # Send will fail because fee is negative try: @@ -284,7 +328,7 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): newzaddr = self.nodes[2].z_getnewaddress() recipients.append({"address":newzaddr, "amount":amount_per_recipient}) myopid = self.nodes[0].z_sendmany(myzaddr, recipients, minconf, custom_fee) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -294,6 +338,8 @@ class WalletProtectCoinbaseTest (BitcoinTestFramework): assert_equal(Decimal(resp["private"]), send_amount) resp = self.nodes[0].z_getbalance(myzaddr) assert_equal(Decimal(resp), zbalance - custom_fee - send_amount) + sproutvalue -= custom_fee + check_value_pool(self.nodes[0], 'sprout', sproutvalue) if __name__ == '__main__': WalletProtectCoinbaseTest().main() diff --git a/qa/rpc-tests/wallet_shieldcoinbase.py b/qa/rpc-tests/wallet_shieldcoinbase.py new file mode 100755 index 000000000..b77fedcf0 --- /dev/null +++ b/qa/rpc-tests/wallet_shieldcoinbase.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_node, connect_nodes_bi, sync_blocks, sync_mempools, \ + wait_and_assert_operationid_status + +from decimal import Decimal + +class WalletShieldCoinbaseTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 4) + + def setup_network(self, split=False): + args = ['-regtestprotectcoinbase', '-debug=zrpcunsafe'] + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, args)) + self.nodes.append(start_node(1, self.options.tmpdir, args)) + args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"] + self.nodes.append(start_node(2, self.options.tmpdir, args2)) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + + self.nodes[0].generate(1) + do_not_shield_taddr = self.nodes[0].getnewaddress() + + self.nodes[0].generate(4) + walletinfo = self.nodes[0].getwalletinfo() + assert_equal(walletinfo['immature_balance'], 50) + assert_equal(walletinfo['balance'], 0) + self.sync_all() + self.nodes[2].generate(1) + self.nodes[2].getnewaddress() + self.nodes[2].generate(1) + self.nodes[2].getnewaddress() + self.nodes[2].generate(1) + self.sync_all() + self.nodes[1].generate(101) + self.sync_all() + assert_equal(self.nodes[0].getbalance(), 50) + assert_equal(self.nodes[1].getbalance(), 10) + assert_equal(self.nodes[2].getbalance(), 30) + + # Prepare to send taddr->zaddr + mytaddr = self.nodes[0].getnewaddress() + myzaddr = self.nodes[0].z_getnewaddress() + + # Shielding will fail when trying to spend from watch-only address + self.nodes[2].importaddress(mytaddr) + try: + self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Could not find any coinbase funds to shield" in errorString, True) + + # Shielding will fail because fee is negative + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, -1) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Shielding will fail because fee is larger than MAX_MONEY + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('21000000.00000001')) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Amount out of range" in errorString, True) + + # Shielding will fail because fee is larger than sum of utxos + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, 999) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Insufficient coinbase funds" in errorString, True) + + # Shielding will fail because limit parameter must be at least 0 + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), -1) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("Limit on maximum number of utxos cannot be negative" in errorString, True) + + # Shielding will fail because limit parameter is absurdly large + try: + self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), 99999999999999) + except JSONRPCException,e: + errorString = e.error['message'] + assert_equal("JSON integer out of range" in errorString, True) + + # Shield coinbase utxos from node 0 of value 40, standard fee of 0.00010000 + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0')) + assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('39.99990000')) + assert_equal(self.nodes[1].getbalance(), 20) + assert_equal(self.nodes[2].getbalance(), 30) + + # Shield coinbase utxos from any node 2 taddr, and set fee to 0 + result = self.nodes[2].z_shieldcoinbase("*", myzaddr, 0) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 10) + assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('69.99990000')) + assert_equal(self.nodes[1].getbalance(), 30) + assert_equal(self.nodes[2].getbalance(), 0) + + # Generate 800 coinbase utxos on node 0, and 20 coinbase utxos on node 2 + self.nodes[0].generate(800) + self.sync_all() + self.nodes[2].generate(20) + self.sync_all() + self.nodes[1].generate(100) + self.sync_all() + mytaddr = self.nodes[0].getnewaddress() + + # Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes. + # We don't verify shieldingValue as utxos are not selected in any specific order, so value can change on each test run. + # We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of utxos. + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 99999) + assert_equal(result["shieldingUTXOs"], Decimal('662')) + assert_equal(result["remainingUTXOs"], Decimal('138')) + remainingValue = result["remainingValue"] + opid1 = result['opid'] + + # Verify that utxos are locked (not available for selection) by queuing up another shielding operation + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 0) + assert_equal(result["shieldingValue"], Decimal(remainingValue)) + assert_equal(result["shieldingUTXOs"], Decimal('138')) + assert_equal(result["remainingValue"], Decimal('0')) + assert_equal(result["remainingUTXOs"], Decimal('0')) + opid2 = result['opid'] + + # wait for both aysnc operations to complete + wait_and_assert_operationid_status(self.nodes[0], opid1) + wait_and_assert_operationid_status(self.nodes[0], opid2) + + # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected. + # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated + # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced. + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit + # This option is used when the limit parameter is set to 0. + mytaddr = self.nodes[2].getnewaddress() + result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0) + assert_equal(result["shieldingUTXOs"], Decimal('7')) + assert_equal(result["remainingUTXOs"], Decimal('13')) + wait_and_assert_operationid_status(self.nodes[2], result['opid']) + self.sync_all() + self.nodes[1].generate(1) + self.sync_all() + + # Verify maximum number of utxos which node 0 can shield is set by default limit parameter of 50 + self.nodes[0].generate(200) + self.sync_all() + mytaddr = self.nodes[0].getnewaddress() + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001')) + assert_equal(result["shieldingUTXOs"], Decimal('50')) + assert_equal(result["remainingUTXOs"], Decimal('50')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + + # Verify maximum number of utxos which node 0 can shield can be set by the limit parameter + result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 33) + assert_equal(result["shieldingUTXOs"], Decimal('33')) + assert_equal(result["remainingUTXOs"], Decimal('17')) + wait_and_assert_operationid_status(self.nodes[0], result['opid']) + # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit + sync_blocks(self.nodes[:2]) + sync_mempools(self.nodes[:2]) + self.nodes[1].generate(1) + self.sync_all() + +if __name__ == '__main__': + WalletShieldCoinbaseTest().main() diff --git a/qa/rpc-tests/wallet_treestate.py b/qa/rpc-tests/wallet_treestate.py index ae55368f0..b3edcd7c5 100755 --- a/qa/rpc-tests/wallet_treestate.py +++ b/qa/rpc-tests/wallet_treestate.py @@ -5,10 +5,11 @@ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from time import * +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, connect_nodes_bi, wait_and_assert_operationid_status -import sys +import time +from decimal import Decimal class WalletTreeStateTest (BitcoinTestFramework): @@ -25,30 +26,6 @@ class WalletTreeStateTest (BitcoinTestFramework): self.is_network_split=False self.sync_all() - def wait_and_assert_operationid_status(self, myopid, in_status='success', in_errormsg=None): - print('waiting for async operation {}'.format(myopid)) - opids = [] - opids.append(myopid) - timeout = 300 - status = None - errormsg = None - for x in xrange(1, timeout): - results = self.nodes[0].z_getoperationresult(opids) - if len(results)==0: - sleep(1) - else: - status = results[0]["status"] - if status == "failed": - errormsg = results[0]['error']['message'] - break - print('...returned status: {}'.format(status)) - print('...error msg: {}'.format(errormsg)) - assert_equal(in_status, status) - if errormsg is not None: - assert(in_errormsg is not None) - assert_equal(in_errormsg in errormsg, True) - print('...returned error: {}'.format(errormsg)) - def run_test (self): print "Mining blocks..." @@ -64,17 +41,17 @@ class WalletTreeStateTest (BitcoinTestFramework): recipients = [] recipients.append({"address":myzaddr, "amount":Decimal('10.0') - Decimal('0.0001')}) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) self.sync_all() self.nodes[1].generate(1) self.sync_all() @@ -91,7 +68,7 @@ class WalletTreeStateTest (BitcoinTestFramework): recipients = [] recipients.append({"address":self.nodes[2].z_getnewaddress(), "amount":Decimal('10.0') - Decimal('0.0001')}) myopid = self.nodes[0].z_sendmany(mytaddr, recipients) - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) # Tx 2 will consume all three notes, which must take at least two joinsplits. This is regardless of # the z_sendmany implementation because there are only two inputs per joinsplit. @@ -106,7 +83,7 @@ class WalletTreeStateTest (BitcoinTestFramework): status = results[0]["status"] if status == "executing": break - sleep(1) + time.sleep(1) # Now mine Tx 1 which will change global treestate before Tx 2's second joinsplit begins processing self.sync_all() @@ -114,7 +91,7 @@ class WalletTreeStateTest (BitcoinTestFramework): self.sync_all() # Wait for Tx 2 to be created - self.wait_and_assert_operationid_status(myopid) + wait_and_assert_operationid_status(self.nodes[0], myopid) # Note that a bug existed in v1.0.0-1.0.3 where Tx 2 creation would fail with an error: # "Witness for spendable note does not have same anchor as change input" diff --git a/qa/rpc-tests/walletbackup.py b/qa/rpc-tests/walletbackup.py index 5f3eb6fcc..78128ad49 100755 --- a/qa/rpc-tests/walletbackup.py +++ b/qa/rpc-tests/walletbackup.py @@ -34,9 +34,17 @@ and confirm again balances are correct. """ from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, start_node, connect_nodes, stop_node, \ + sync_blocks, sync_mempools + +import os +import shutil from random import randint +from decimal import Decimal import logging + logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) class WalletBackupTest(BitcoinTestFramework): @@ -134,6 +142,14 @@ class WalletBackupTest(BitcoinTestFramework): self.nodes[2].backupwallet("walletbak") self.nodes[2].dumpwallet("walletdump") + # Verify dumpwallet cannot overwrite an existing file + try: + self.nodes[2].dumpwallet("walletdump") + assert(False) + except JSONRPCException as e: + errorString = e.error['message'] + assert("Cannot overwrite existing file" in errorString) + logging.info("More transactions") for i in range(5): self.do_one_round() diff --git a/qa/rpc-tests/zapwallettxes.py b/qa/rpc-tests/zapwallettxes.py index b15138818..5da4ba125 100755 --- a/qa/rpc-tests/zapwallettxes.py +++ b/qa/rpc-tests/zapwallettxes.py @@ -4,7 +4,9 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, initialize_chain_clean, \ + start_nodes, start_node, connect_nodes_bi, bitcoind_processes class ZapWalletTXesTest (BitcoinTestFramework): @@ -27,56 +29,56 @@ class ZapWalletTXesTest (BitcoinTestFramework): self.sync_all() self.nodes[1].generate(101) self.sync_all() - + assert_equal(self.nodes[0].getbalance(), 40) - + txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) self.sync_all() self.nodes[0].generate(1) self.sync_all() - + txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5) - + tx0 = self.nodes[0].gettransaction(txid0) - assert_equal(tx0['txid'], txid0) #tx0 must be available (confirmed) - + assert_equal(tx0['txid'], txid0) # tx0 must be available (confirmed) + tx1 = self.nodes[0].gettransaction(txid1) - assert_equal(tx1['txid'], txid1) #tx1 must be available (confirmed) - + assert_equal(tx1['txid'], txid1) # tx1 must be available (confirmed) + tx2 = self.nodes[0].gettransaction(txid2) - assert_equal(tx2['txid'], txid2) #tx2 must be available (unconfirmed) - + assert_equal(tx2['txid'], txid2) # tx2 must be available (unconfirmed) + tx3 = self.nodes[0].gettransaction(txid3) - assert_equal(tx3['txid'], txid3) #tx3 must be available (unconfirmed) - - #restart bitcoind + assert_equal(tx3['txid'], txid3) # tx3 must be available (unconfirmed) + + # restart zcashd self.nodes[0].stop() bitcoind_processes[0].wait() self.nodes[0] = start_node(0,self.options.tmpdir) - + tx3 = self.nodes[0].gettransaction(txid3) - assert_equal(tx3['txid'], txid3) #tx must be available (unconfirmed) - + assert_equal(tx3['txid'], txid3) # tx must be available (unconfirmed) + self.nodes[0].stop() bitcoind_processes[0].wait() - - #restart bitcoind with zapwallettxes + + # restart zcashd with zapwallettxes self.nodes[0] = start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) - + aException = False try: tx3 = self.nodes[0].gettransaction(txid3) except JSONRPCException,e: print e aException = True - - assert_equal(aException, True) #there must be a expection because the unconfirmed wallettx0 must be gone by now + + assert_equal(aException, True) # there must be a expection because the unconfirmed wallettx0 must be gone by now tx0 = self.nodes[0].gettransaction(txid0) - assert_equal(tx0['txid'], txid0) #tx0 (confirmed) must still be available because it was confirmed + assert_equal(tx0['txid'], txid0) # tx0 (confirmed) must still be available because it was confirmed if __name__ == '__main__': - ZapWalletTXesTest ().main () + ZapWalletTXesTest().main() diff --git a/qa/rpc-tests/zcjoinsplit.py b/qa/rpc-tests/zcjoinsplit.py index 2b439e831..7e5aba6e3 100755 --- a/qa/rpc-tests/zcjoinsplit.py +++ b/qa/rpc-tests/zcjoinsplit.py @@ -5,11 +5,9 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from decimal import Decimal -import os -import shutil -import sys +from test_framework.util import assert_equal, start_node, \ + gather_inputs + class JoinSplitTest(BitcoinTestFramework): def setup_network(self): diff --git a/qa/rpc-tests/zcjoinsplitdoublespend.py b/qa/rpc-tests/zcjoinsplitdoublespend.py index cb89a9182..98837b57e 100755 --- a/qa/rpc-tests/zcjoinsplitdoublespend.py +++ b/qa/rpc-tests/zcjoinsplitdoublespend.py @@ -5,11 +5,10 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * -from decimal import Decimal -import os -import shutil -import sys +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, connect_nodes, \ + gather_inputs, sync_blocks + import time class JoinSplitTest(BitcoinTestFramework): @@ -41,7 +40,7 @@ class JoinSplitTest(BitcoinTestFramework): assert_equal(self.cannot_joinsplit(node, txn), True) def run_test(self): - # All nodes should start with 250 BTC: + # All nodes should start with 250 ZEC: starting_balance = 250 for i in range(4): assert_equal(self.nodes[i].getbalance(), starting_balance) diff --git a/qa/rpc-tests/zkey_import_export.py b/qa/rpc-tests/zkey_import_export.py new file mode 100755 index 000000000..323debe31 --- /dev/null +++ b/qa/rpc-tests/zkey_import_export.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from decimal import Decimal +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, assert_greater_than, start_nodes,\ + initialize_chain_clean, connect_nodes_bi, wait_and_assert_operationid_status + +import logging +import time +import math + +logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) + + +class ZkeyImportExportTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 5) + + def setup_network(self, split=False): + self.nodes = start_nodes(5, self.options.tmpdir ) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + connect_nodes_bi(self.nodes,0,3) + connect_nodes_bi(self.nodes,0,4) + self.is_network_split=False + self.sync_all() + + def run_test(self): + [alice, bob, charlie, david, miner] = self.nodes + + def z_send(from_node, from_addr, to_addr, amount): + opid = from_node.z_sendmany(from_addr, [{"address": to_addr, "amount": Decimal(amount)}]) + wait_and_assert_operationid_status(from_node, opid) + self.sync_all() + miner.generate(1) + self.sync_all() + + def z_getbalance(node, zaddr): + bal = node.z_getbalance(zaddr) + # Ignore fees for sake of comparison + round_balance = math.ceil(bal*100)/100 + return round_balance + + def verify_utxos(node, amts, zaddr): + amts.sort(reverse=True) + txs = node.z_listreceivedbyaddress(zaddr) + + def cmp_confirmations_high_to_low(a, b): + return cmp(b["amount"], a["amount"]) + + txs.sort(cmp_confirmations_high_to_low) + print("Sorted txs", txs) + print("amts", amts) + + try: + assert_equal(amts, [tx["amount"] for tx in txs]) + except AssertionError: + logging.error( + 'Expected amounts: %r; txs: %r', + amts, txs) + raise + + def get_private_balance(node): + balance = node.z_gettotalbalance() + return balance['private'] + + def find_imported_key(node, import_zaddr): + zaddrs = node.z_listaddresses() + assert(import_zaddr in zaddrs) + return import_zaddr + + # Seed Alice with some funds + alice.generate(10) + self.sync_all() + miner.generate(100) + self.sync_all() + # Shield Alice's coinbase funds to her zaddr + alice_zaddr = alice.z_getnewaddress() + res = alice.z_shieldcoinbase("*", alice_zaddr) + wait_and_assert_operationid_status(alice, res['opid']) + self.sync_all() + miner.generate(1) + self.sync_all() + + # Now get a pristine z-address for receiving transfers: + bob_zaddr = bob.z_getnewaddress() + verify_utxos(bob, [], bob_zaddr) + # TODO: Verify that charlie doesn't have funds in addr + # verify_utxos(charlie, []) + + # the amounts of each txn embodied which generates a single UTXO: + amounts = map(Decimal, ['2.3', '3.7', '0.1', '0.5', '1.0', '0.19']) + + # Internal test consistency assertion: + assert_greater_than( + get_private_balance(alice), + reduce(Decimal.__add__, amounts)) + + logging.info("Sending pre-export txns...") + for amount in amounts[0:2]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + logging.info("Exporting privkey from bob...") + privkey = bob.z_exportkey(bob_zaddr) + + logging.info("Sending post-export txns...") + for amount in amounts[2:4]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + print("Bob amounts:", amounts[:4]) + verify_utxos(bob, amounts[:4], bob_zaddr) + # verify_utxos(charlie, []) + + logging.info("Importing privkey into charlie...") + # z_importkey rescan defaults to "whenkeyisnew", so should rescan here + charlie.z_importkey(privkey) + ipk_zaddr = find_imported_key(charlie, bob_zaddr) + + # z_importkey should have rescanned for new key, so this should pass: + verify_utxos(charlie, amounts[:4], ipk_zaddr) + + # Verify idempotent behavior: + charlie.z_importkey(privkey) + ipk_zaddr2 = find_imported_key(charlie, bob_zaddr) + + # amounts should be unchanged + verify_utxos(charlie, amounts[:4], ipk_zaddr2) + + logging.info("Sending post-import txns...") + for amount in amounts[4:]: + z_send(alice, alice_zaddr, bob_zaddr, amount) + + verify_utxos(bob, amounts, bob_zaddr) + verify_utxos(charlie, amounts, ipk_zaddr) + verify_utxos(charlie, amounts, ipk_zaddr2) + + # Try to reproduce zombie balance reported in #1936 + # At generated zaddr, receive ZEC, and send ZEC back out. bob -> alice + for amount in amounts[:2]: + print("Sending amount from bob to alice: ", amount) + z_send(bob, bob_zaddr, alice_zaddr, amount) + + balance = float(sum(amounts) - sum(amounts[:2])) + assert_equal(z_getbalance(bob, bob_zaddr), balance) + + # z_import onto new node "david" (blockchain rescan, default or True?) + david.z_importkey(privkey) + d_ipk_zaddr = find_imported_key(david, bob_zaddr) + + # Check if amt bob spent is deducted for charlie and david + assert_equal(z_getbalance(charlie, ipk_zaddr), balance) + assert_equal(z_getbalance(david, d_ipk_zaddr), balance) + +if __name__ == '__main__': + ZkeyImportExportTest().main() diff --git a/qa/rpc-tests/zmq_test.py b/qa/rpc-tests/zmq_test.py index 97850bea3..d70e73114 100755 --- a/qa/rpc-tests/zmq_test.py +++ b/qa/rpc-tests/zmq_test.py @@ -8,21 +8,12 @@ # from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import assert_equal, bytes_to_hex_str, start_nodes + import zmq -import binascii import struct -try: - import http.client as httplib -except ImportError: - import httplib -try: - import urllib.parse as urlparse -except ImportError: - import urlparse - -class ZMQTest (BitcoinTestFramework): +class ZMQTest(BitcoinTestFramework): port = 28332 @@ -51,8 +42,9 @@ class ZMQTest (BitcoinTestFramework): assert_equal(topic, b"hashtx") body = msg[1] nseq = msg[2] + [nseq] # hush pyflakes msgSequence = struct.unpack('> 7) - 1 + l += 1 + return bytes(v)[::-1] + +def decode_varint(v): + n = 0 + for ch in range(len(v)): + n = (n << 7) | (ord(v[ch]) & 0x7F) + if (ord(v[ch]) & 0x80): + n += 1 + else: + return n + +def compress_amount(n): + if n == 0: + return 0 + e = 0 + while (((n % 10) == 0) and e < 9): + n /= 10 + e += 1 + if e < 9: + d = (n % 10) + assert(d >= 1 and d <= 9) + n /= 10 + return 1 + (n*9 + d - 1)*10 + e + else: + return 1 + (n - 1)*10 + 9 + +OP_DUP = 0x76 +OP_EQUAL = 0x87 +OP_EQUALVERIFY = 0x88 +OP_HASH160 = 0xa9 +OP_CHECKSIG = 0xac +def to_key_id(script): + if len(script) == 25 and \ + script[0] == OP_DUP and \ + script[1] == OP_HASH160 and \ + script[2] == 20 and \ + script[23] == OP_EQUALVERIFY and \ + script[24] == OP_CHECKSIG: + return script[3:23] + return bytes() + +def to_script_id(script): + if len(script) == 23 and \ + script[0] == OP_HASH160 and \ + script[1] == 20 and \ + script[22] == OP_EQUAL: + return script[2:22] + return bytes() + +def to_pubkey(script): + if len(script) == 35 and \ + script[0] == 33 and \ + script[34] == OP_CHECKSIG and \ + (script[1] == 0x02 or script[1] == 0x03): + return script[1:34] + if len(script) == 67 and \ + script[0] == 65 and \ + script[66] == OP_CHECKSIG and \ + script[1] == 0x04: + return script[1:66] # assuming is fully valid + return bytes() + +def compress_script(script): + result = bytearray() + + key_id = to_key_id(script) + if key_id: + result.append(0x00) + result.extend(key_id) + return bytes(result) + + script_id = to_script_id(script) + if script_id: + result.append(0x01) + result.extend(script_id) + return bytes(result) + + pubkey = to_pubkey(script) + if pubkey: + result.append(0x00) + result.extend(pubkey[1:33]) + if pubkey[0] == 0x02 or pubkey[0] == 0x03: + result[0] = pubkey[0] + return bytes(result) + elif pubkey[0] == 0x04: + result[0] = 0x04 | (pubkey[64] & 0x01) + return bytes(result) + + size = len(script) + 6 + result.append(encode_varint(size)) + result.extend(script) + return bytes(result) + +def deterministic_filter(tarinfo): + tarinfo.uid = tarinfo.gid = 0 + tarinfo.uname = tarinfo.gname = "root" + tarinfo.mtime = calendar.timegm(time.strptime('2017-05-17', '%Y-%m-%d')) + tarinfo.mode |= stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP + tarinfo.mode &= ~stat.S_IWGRP + if tarinfo.isdir(): + tarinfo.mode |= \ + stat.S_IXUSR | \ + stat.S_IXGRP | \ + stat.S_IXOTH + else: + tarinfo.mode &= \ + ~stat.S_IXUSR & \ + ~stat.S_IXGRP & \ + ~stat.S_IXOTH + return tarinfo + +def create_benchmark_archive(blk_hash): + blk = json.loads(subprocess.check_output([ZCASH_CLI, 'getblock', blk_hash])) + print 'Height: %d' % blk['height'] + print 'Transactions: %d' % len(blk['tx']) + + os.mkdir('benchmark') + with open('benchmark/block-%d.dat' % blk['height'], 'wb') as f: + f.write(binascii.unhexlify(subprocess.check_output([ZCASH_CLI, 'getblock', blk_hash, 'false']).strip())) + + txs = [json.loads(subprocess.check_output([ZCASH_CLI, 'getrawtransaction', tx, '1']) + ) for tx in blk['tx']] + + js_txs = len([tx for tx in txs if len(tx['vjoinsplit']) > 0]) + if js_txs: + print 'Block contains %d JoinSplit-containing transactions' % js_txs + return + + inputs = [(x['txid'], x['vout']) for tx in txs for x in tx['vin'] if x.has_key('txid')] + print 'Total inputs: %d' % len(inputs) + + unique_inputs = {} + for i in sorted(inputs): + if unique_inputs.has_key(i[0]): + unique_inputs[i[0]].append(i[1]) + else: + unique_inputs[i[0]] = [i[1]] + print 'Unique input transactions: %d' % len(unique_inputs) + + db_path = 'benchmark/block-%d-inputs' % blk['height'] + db = plyvel.DB(db_path, create_if_missing=True) + wb = db.write_batch() + bar = progressbar.ProgressBar(redirect_stdout=True) + print 'Collecting input coins for block' + for tx in bar(unique_inputs.keys()): + rawtx = json.loads(subprocess.check_output([ZCASH_CLI, 'getrawtransaction', tx, '1'])) + + mask_size = 0 + mask_code = 0 + b = 0 + while 2+b*8 < len(rawtx['vout']): + zero = True + i = 0 + while i < 8 and 2+b*8+i < len(rawtx['vout']): + if 2+b*8+i in unique_inputs[tx]: + zero = False + i += 1 + if not zero: + mask_size = b + 1 + mask_code += 1 + b += 1 + + coinbase = len(rawtx['vin']) == 1 and 'coinbase' in rawtx['vin'][0] + first = len(rawtx['vout']) > 0 and 0 in unique_inputs[tx] + second = len(rawtx['vout']) > 1 and 1 in unique_inputs[tx] + code = 8*(mask_code - (0 if first or second else 1)) + \ + (1 if coinbase else 0) + \ + (2 if first else 0) + \ + (4 if second else 0) + + coins = bytearray() + # Serialized format: + # - VARINT(nVersion) + coins.extend(encode_varint(rawtx['version'])) + # - VARINT(nCode) + coins.extend(encode_varint(code)) + # - unspentness bitvector, for vout[2] and further; least significant byte first + for b in range(mask_size): + avail = 0 + i = 0 + while i < 8 and 2+b*8+i < len(rawtx['vout']): + if 2+b*8+i in unique_inputs[tx]: + avail |= (1 << i) + i += 1 + coins.append(avail) + # - the non-spent CTxOuts (via CTxOutCompressor) + for i in range(len(rawtx['vout'])): + if i in unique_inputs[tx]: + coins.extend(encode_varint(compress_amount(int(rawtx['vout'][i]['valueZat'])))) + coins.extend(compress_script( + binascii.unhexlify(rawtx['vout'][i]['scriptPubKey']['hex']))) + # - VARINT(nHeight) + coins.extend(encode_varint(json.loads( + subprocess.check_output([ZCASH_CLI, 'getblockheader', rawtx['blockhash']]) + )['height'])) + + db_key = b'c' + bytes(binascii.unhexlify(tx)[::-1]) + db_val = bytes(coins) + wb.put(db_key, db_val) + + wb.write() + db.close() + + # Make reproducible archive + os.remove('%s/LOG' % db_path) + files = subprocess.check_output(['find', 'benchmark']).strip().split('\n') + archive_name = 'block-%d.tar' % blk['height'] + tar = tarfile.open(archive_name, 'w') + for name in sorted(files): + tar.add(name, recursive=False, filter=deterministic_filter) + tar.close() + subprocess.check_call(['xz', '-6', archive_name]) + print 'Created archive %s.xz' % archive_name + subprocess.call(['rm', '-r', 'benchmark']) + +if __name__ == '__main__': + check_deps() + create_benchmark_archive('0000000007cdb809e48e51dd0b530e8f5073e0a9e9bd7ae920fe23e874658c74') diff --git a/qa/zcash/create_wallet_200k_utxos.py b/qa/zcash/create_wallet_200k_utxos.py new file mode 100755 index 000000000..d4a1d9d48 --- /dev/null +++ b/qa/zcash/create_wallet_200k_utxos.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python2 +# Copyright (c) 2017 The Zcash developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# +# Create a large wallet +# +# To use: +# - Copy to qa/rpc-tests/wallet_large.py +# - Add wallet_large.py to RPC tests list +# - ./qa/pull-tester/rpc-tests.sh wallet_large --nocleanup +# - Archive the resulting /tmp/test###### directory +# + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import ( + assert_equal, + connect_nodes_bi, + initialize_chain_clean, + start_nodes, +) + +from decimal import Decimal + + +class LargeWalletTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 2) + + def setup_network(self): + self.nodes = start_nodes(2, self.options.tmpdir) + connect_nodes_bi(self.nodes, 0, 1) + self.is_network_split = False + self.sync_all() + + def run_test(self): + self.nodes[1].generate(103) + self.sync_all() + + inputs = [] + for i in range(200000): + taddr = self.nodes[0].getnewaddress() + inputs.append(self.nodes[1].sendtoaddress(taddr, Decimal("0.001"))) + if i % 1000 == 0: + self.nodes[1].generate(1) + self.sync_all() + + self.nodes[1].generate(1) + self.sync_all() + print('Node 0: %d transactions, %d UTXOs' % + (len(self.nodes[0].listtransactions()), len(self.nodes[0].listunspent()))) + print('Node 1: %d transactions, %d UTXOs' % + (len(self.nodes[1].listtransactions()), len(self.nodes[1].listunspent()))) + assert_equal(len(self.nodes[0].listunspent()), len(inputs)) + +if __name__ == '__main__': + LargeWalletTest().main() diff --git a/qa/zcash/ensure-no-dot-so-in-depends.py b/qa/zcash/ensure-no-dot-so-in-depends.py deleted file mode 100755 index beb4b9ec0..000000000 --- a/qa/zcash/ensure-no-dot-so-in-depends.py +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env python2 - -import sys -import os - -def main(): - this_script = os.path.abspath(sys.argv[0]) - basedir = os.path.dirname(this_script) - arch_dir = os.path.join( - basedir, - '..', - '..', - 'depends', - 'x86_64-unknown-linux-gnu', - ) - - exit_code = 0 - - if os.path.isdir(arch_dir): - lib_dir = os.path.join(arch_dir, 'lib') - libraries = os.listdir(lib_dir) - - for lib in libraries: - if lib.find(".so") != -1: - print lib - exit_code = 1 - else: - exit_code = 2 - print "arch-specific build dir not present: {}".format(arch_dir) - print "Did you build the ./depends tree?" - print "Are you on a currently unsupported architecture?" - - if exit_code == 0: - print "PASS." - else: - print "FAIL." - - sys.exit(exit_code) - -if __name__ == '__main__': - main() diff --git a/qa/zcash/full-test-suite.sh b/qa/zcash/full-test-suite.sh deleted file mode 100755 index 7860b105a..000000000 --- a/qa/zcash/full-test-suite.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -# -# Execute all of the automated tests related to Zcash. -# - -set -eu - -SUITE_EXIT_STATUS=0 -REPOROOT="$(readlink -f "$(dirname "$0")"/../../)" - -function run_test_phase -{ - echo "===== BEGIN: $*" - set +e - eval "$@" - if [ $? -eq 0 ] - then - echo "===== PASSED: $*" - else - echo "===== FAILED: $*" - SUITE_EXIT_STATUS=1 - fi - set -e -} - -cd "${REPOROOT}" - -# Test phases: -run_test_phase "${REPOROOT}/qa/zcash/check-security-hardening.sh" -run_test_phase "${REPOROOT}/qa/zcash/ensure-no-dot-so-in-depends.py" - -# If make check fails, show test-suite.log as part of our run_test_phase -# output (and fail the phase with false): -run_test_phase make check '||' \ - '{' \ - echo '=== ./src/test-suite.log ===' ';' \ - cat './src/test-suite.log' ';' \ - false ';' \ - '}' - -exit $SUITE_EXIT_STATUS - - - - - - diff --git a/qa/zcash/full_test_suite.py b/qa/zcash/full_test_suite.py new file mode 100755 index 000000000..d8a076420 --- /dev/null +++ b/qa/zcash/full_test_suite.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python2 +# +# Execute all of the automated tests related to Zcash. +# + +import argparse +import os +import re +import subprocess +import sys + +REPOROOT = os.path.dirname( + os.path.dirname( + os.path.dirname( + os.path.abspath(__file__) + ) + ) +) + +def repofile(filename): + return os.path.join(REPOROOT, filename) + + +# +# Custom test runners +# + +RE_RPATH_RUNPATH = re.compile('No RPATH.*No RUNPATH') +RE_FORTIFY_AVAILABLE = re.compile('FORTIFY_SOURCE support available.*Yes') +RE_FORTIFY_USED = re.compile('Binary compiled with FORTIFY_SOURCE support.*Yes') + +def test_rpath_runpath(filename): + output = subprocess.check_output( + [repofile('qa/zcash/checksec.sh'), '--file', repofile(filename)] + ) + if RE_RPATH_RUNPATH.search(output): + print('PASS: %s has no RPATH or RUNPATH.' % filename) + return True + else: + print('FAIL: %s has an RPATH or a RUNPATH.' % filename) + print(output) + return False + +def test_fortify_source(filename): + proc = subprocess.Popen( + [repofile('qa/zcash/checksec.sh'), '--fortify-file', repofile(filename)], + stdout=subprocess.PIPE, + ) + line1 = proc.stdout.readline() + line2 = proc.stdout.readline() + proc.terminate() + if RE_FORTIFY_AVAILABLE.search(line1) and RE_FORTIFY_USED.search(line2): + print('PASS: %s has FORTIFY_SOURCE.' % filename) + return True + else: + print('FAIL: %s is missing FORTIFY_SOURCE.' % filename) + return False + +def check_security_hardening(): + ret = True + + # PIE, RELRO, Canary, and NX are tested by make check-security. + ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 + + ret &= test_rpath_runpath('src/zcashd') + ret &= test_rpath_runpath('src/zcash-cli') + ret &= test_rpath_runpath('src/zcash-gtest') + ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/test/test_bitcoin') + ret &= test_rpath_runpath('src/zcash/GenerateParams') + + # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE + # is enabled for the entire binary. See issue #915. + ret &= test_fortify_source('src/zcashd') + ret &= test_fortify_source('src/zcash-cli') + ret &= test_fortify_source('src/zcash-gtest') + ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/test/test_bitcoin') + ret &= test_fortify_source('src/zcash/GenerateParams') + + return ret + +def ensure_no_dot_so_in_depends(): + arch_dir = os.path.join( + REPOROOT, + 'depends', + 'x86_64-unknown-linux-gnu', + ) + + exit_code = 0 + + if os.path.isdir(arch_dir): + lib_dir = os.path.join(arch_dir, 'lib') + libraries = os.listdir(lib_dir) + + for lib in libraries: + if lib.find(".so") != -1: + print lib + exit_code = 1 + else: + exit_code = 2 + print "arch-specific build dir not present: {}".format(arch_dir) + print "Did you build the ./depends tree?" + print "Are you on a currently unsupported architecture?" + + if exit_code == 0: + print "PASS." + else: + print "FAIL." + + return exit_code == 0 + +def util_test(): + return subprocess.call( + [repofile('src/test/bitcoin-util-test.py')], + cwd=repofile('src'), + env={'PYTHONPATH': repofile('src/test'), 'srcdir': repofile('src')} + ) == 0 + + +# +# Tests +# + +STAGES = [ + 'btest', + 'gtest', + 'sec-hard', + 'no-dot-so', + 'util-test', + 'secp256k1', + 'libsnark', + 'univalue', + 'rpc', +] + +STAGE_COMMANDS = { + 'btest': [repofile('src/test/test_bitcoin'), '-p'], + 'gtest': [repofile('src/zcash-gtest')], + 'sec-hard': check_security_hardening, + 'no-dot-so': ensure_no_dot_so_in_depends, + 'util-test': util_test, + 'secp256k1': ['make', '-C', repofile('src/secp256k1'), 'check'], + 'libsnark': ['make', '-C', repofile('src'), 'libsnark-tests'], + 'univalue': ['make', '-C', repofile('src/univalue'), 'check'], + 'rpc': [repofile('qa/pull-tester/rpc-tests.sh')], +} + + +# +# Test driver +# + +def run_stage(stage): + print('Running stage %s' % stage) + print('=' * (len(stage) + 14)) + print + + cmd = STAGE_COMMANDS[stage] + if type(cmd) == type([]): + ret = subprocess.call(cmd) == 0 + else: + ret = cmd() + + print + print('-' * (len(stage) + 15)) + print('Finished stage %s' % stage) + print + + return ret + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--list-stages', dest='list', action='store_true') + parser.add_argument('stage', nargs='*', default=STAGES, + help='One of %s'%STAGES) + args = parser.parse_args() + + # Check for list + if args.list: + for s in STAGES: + print(s) + sys.exit(0) + + # Check validity of stages + for s in args.stage: + if s not in STAGES: + print("Invalid stage '%s' (choose from %s)" % (s, STAGES)) + sys.exit(1) + + # Run the stages + passed = True + for s in args.stage: + passed &= run_stage(s) + + if not passed: + print("!!! One or more test stages failed !!!") + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/qa/zcash/performance-measurements.sh b/qa/zcash/performance-measurements.sh index 2c79e04ef..15f3077b5 100755 --- a/qa/zcash/performance-measurements.sh +++ b/qa/zcash/performance-measurements.sh @@ -1,37 +1,113 @@ #!/bin/bash +set -u -set -e DATADIR=./benchmark-datadir +SHA256CMD="$(command -v sha256sum || echo shasum)" +SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')" function zcash_rpc { - ./src/zcash-cli -datadir="$DATADIR" -rpcwait -rpcuser=user -rpcpassword=password -rpcport=5983 "$@" + ./src/zcash-cli -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 "$@" +} + +function zcash_rpc_slow { + # Timeout of 1 hour + zcash_rpc -rpcclienttimeout=3600 "$@" +} + +function zcash_rpc_veryslow { + # Timeout of 2.5 hours + zcash_rpc -rpcclienttimeout=9000 "$@" +} + +function zcash_rpc_wait_for_start { + zcash_rpc -rpcwait getinfo > /dev/null } function zcashd_generate { zcash_rpc generate 101 > /dev/null } +function extract_benchmark_datadir { + if [ -f "$1.tar.xz" ]; then + # Check the hash of the archive: + "$SHA256CMD" $SHA256ARGS -c < /dev/null - wait $ZCASH_PID + wait $ZCASHD_PID } function zcashd_massif_start { - rm -rf "$DATADIR" - mkdir -p "$DATADIR" - touch "$DATADIR/zcash.conf" + case "$1" in + sendtoaddress|loadwallet|listunspent) + case "$2" in + 200k-recv) + use_200k_benchmark 0 + ;; + 200k-send) + use_200k_benchmark 1 + ;; + *) + echo "Bad arguments to zcashd_massif_start." + exit 1 + esac + ;; + *) + rm -rf "$DATADIR" + mkdir -p "$DATADIR/regtest" + touch "$DATADIR/zcash.conf" + esac rm -f massif.out valgrind --tool=massif --time-unit=ms --massif-out-file=massif.out ./src/zcashd -regtest -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 -showmetrics=0 & ZCASHD_PID=$! + zcash_rpc_wait_for_start } function zcashd_massif_stop { @@ -42,11 +118,12 @@ function zcashd_massif_stop { function zcashd_valgrind_start { rm -rf "$DATADIR" - mkdir -p "$DATADIR" + mkdir -p "$DATADIR/regtest" touch "$DATADIR/zcash.conf" rm -f valgrind.out valgrind --leak-check=yes -v --error-limit=no --log-file="valgrind.out" ./src/zcashd -regtest -datadir="$DATADIR" -rpcuser=user -rpcpassword=password -rpcport=5983 -showmetrics=0 & ZCASHD_PID=$! + zcash_rpc_wait_for_start } function zcashd_valgrind_stop { @@ -55,12 +132,41 @@ function zcashd_valgrind_stop { cat valgrind.out } +function extract_benchmark_data { + if [ -f "block-107134.tar.xz" ]; then + # Check the hash of the archive: + "$SHA256CMD" $SHA256ARGS -c < c #8F6125", -", c #956727", -"< c #916B2E", -"1 c #996B2C", -"2 c #B47B23", -"3 c #BD7C20", -"4 c #A17330", -"5 c #AB7D3B", -"6 c #C17F20", -"7 c #B9831F", -"8 c #BB842B", -"9 c #BD8533", -"0 c #B68F3D", -"q c #BE8C3B", -"w c #C4801F", -"e c #FE8C03", -"r c #F38A0F", -"t c #FD8E0A", -"y c #FF910C", -"u c #F78F13", -"i c #F98F10", -"p c #F79016", -"a c #FE9314", -"s c #F6931E", -"d c #FD961B", -"f c #FE991E", -"g c #C58421", -"h c #CD8621", -"j c #C78B21", -"k c #CC8B23", -"l c #C2852B", -"z c #C08B2D", -"x c #D28722", -"c c #D38B25", -"v c #DB8E22", -"b c #D28E2C", -"n c #D49323", -"m c #DC9224", -"M c #DC9B25", -"N c #D4922D", -"B c #DF972A", -"V c #DF982E", -"C c #C18D33", -"Z c #C58E38", -"A c #CB9332", -"S c #C2933C", -"D c #CD9339", -"F c #CC9938", -"G c #D19733", -"H c #DA9230", -"J c #D59935", -"K c #DC9C33", -"L c #DC9E3B", -"P c #E49124", -"I c #EA9426", -"U c #E09D26", -"Y c #EC972B", -"T c #F79625", -"R c #F99524", -"E c #F69A26", -"W c #F89825", -"Q c #F2972B", -"! c #F59A2C", -"~ c #F89B2B", -"^ c #E79D33", -"/ c #EF9D31", -"( c #E19F3A", -") c #EF9D3A", -"_ c #F49C33", -"` c #F99E32", -"' c #F49F39", -"] c #D6A13E", -"[ c #DAA33B", -"{ c #E3A127", -"} c #E7A328", -"| c #EDA32C", -" . c #EDA829", -".. c #FFA325", -"X. c #FFAB25", -"o. c #F3A42B", -"O. c #FFA429", -"+. c #F4A929", -"@. c #FFAC2A", -"#. c #FFB227", -"$. c #FFB32C", -"%. c #FFBA2D", -"&. c #EEA830", -"*. c #F7A334", -"=. c #FAA036", -"-. c #FCAB34", -";. c #F4A13C", -":. c #F9A33B", -">. c #F4A83B", -",. c #FFA83F", -"<. c #FDB432", -"1. c #FFBB33", -"2. c #FFB73A", -"3. c #FDB93E", -"4. c #FFC12F", -"5. c #FFC432", -"6. c #FFC338", -"7. c #D2A043", -"8. c #D8A140", -"9. c #EEA144", -"0. c #E2A840", -"q. c #EDA34B", -"w. c #F4A444", -"e. c #F9A642", -"r. c #FBA945", -"t. c #F3A64B", -"y. c #F4A84E", -"u. c #FBAB4B", -"i. c #EEB041", -"p. c #FABA44", -"a. c #ECA653", -"s. c #EEAC5D", -"d. c #F3AA53", -"f. c #FAAE53", -"g. c #F2AD5A", -"h. c #FBB056", -"j. c #F6B15E", -"k. c #FBB25B", -"l. c #DDAF79", -"z. c #E3A962", -"x. c #EBAE63", -"c. c #E4AC68", -"v. c #EAAF69", -"b. c #EEB065", -"n. c #E7B06C", -"m. c #EEB36B", -"M. c #F5B263", -"N. c #FBB461", -"B. c #E6B274", -"V. c #ECB574", -"C. c #E7B57B", -"Z. c #EAB77C", -"A. c #ECB97C", -"S. c #F2B770", -"D. c #F0BB7A", -"F. c #DBB485", -"G. c #DFB888", -"H. c #E4B984", -"J. c #EDBD82", -"K. c #E5BC8B", -"L. c #EABE8A", -"P. c #F0BE82", -"I. c #E0BF96", -"U. c #EDC089", -"Y. c #F0C28B", -"T. c #E5C194", -"R. c #E9C191", -"E. c #E4C39C", -"W. c #EBC699", -"Q. c #EBC99F", -"!. c #DFC3A0", -"~. c #DDCAAF", -"^. c #CFC7BD", -"/. c #D2CBB6", -"(. c #DBC8B1", -"). c #DBCDBB", -"_. c #E2C6A4", -"`. c #E6C8A5", -"'. c #EACBA5", -"]. c #E1C7A8", -"[. c #E3CBAD", -"{. c #EACCAA", -"}. c #EED1AC", -"|. c #E1CDB3", -" X c #E3CFB8", -".X c #E6D1B6", -"XX c #EBD2B3", -"oX c #E3D1BB", -"OX c #EAD6BB", -"+X c #EBD8BF", -"@X c #D3CDC2", -"#X c #D8CDC2", -"$X c #D0CECA", -"%X c #DDD3C4", -"&X c #D3D2CC", -"*X c #DDD5CB", -"=X c #CCD3D5", -"-X c #C9D7DF", -";X c #D2D4D6", -":X c #DEDAD4", -">X c #DDDCDB", -",X c #E2D4C2", -".N b b b b N >.( C > HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX4 L _ *.@.<.$.X.X...X.X.X.X.X.X...X.@.$.<.@.*./ G , HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX< L -.@.$.X...R R R T T T T W W W W W W T T T T R R W ..X.$.@.*.J HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXD -.%.X.W R T T W W W W W W W W W W W W W W W W W W W W W W T T R W X.%.+.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXS -.$.X.R T T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T T R X.$.-.C HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXF <.@.f R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R W #.<.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX[ <.X.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W T R X.$.K HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX0.$...R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E W W W W W W W T R ..%.G HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXS 1...R T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ E W W W W W W W W W T R X.1.A HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3.X.d T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ E W W W W W W W W W W T R @.2.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX7.5.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W T W %.z HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3.X.s T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W T R $.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX1...R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W R ..1.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX0 5.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W T W 5.8 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX8.$.s W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W T R %.N HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi.#.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W R $.&.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXp.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W R @.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXp.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W R @.<.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi.X.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ E ~ W R ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W R @.| HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX] #.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ! s e t d ~ ` ` ` ` ` ` =.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W R %.N HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXq %.R W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E W E ~ ~ ~ ~ y l.=XI.x.) p a =.` ` =.=.=.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W R %.2 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX5 5.d W W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ t (.jXVXNXuX@XF.W ` =.:.` W =.:.=.=.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX1.f T W W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ R Q eXDXSXSXDXgX#Xa ` =.=.;.q.W a a R ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T W %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX3...T W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ` a a.NXSXGXGXAXNXV.a :.:.f c.tX*XE.n.9.R ~ ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W T @.@.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXD #.R W W W W W W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` t H.VXSXGXGXDXmXy.f :.:.a I.hXBXCXNXiX^.' W ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W R %.g HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX5.d W W W W W W W W W W W W W W W W W W W W W W W W W E ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` i |.CXGXGXGXCX3X~ ` :.:.R %XCXSXGXAXNX>XW ~ ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W R 5.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX2.W T W W W W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ s t e a W ~ ` ` ` ` ` ` W ! eXFXGXGXSXVX[.d :.:.~ w.uXFXGXGXSXVXW.a ` ` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T ..@.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX9 $.R W W W W W W W W W W W W W W W W W W W W W W E W ~ ~ ~ y F./.B.9.T t t a ~ =.` =.a a.hXDXGXGXSXNXA.d :.e.R v.NXSXGXGXSXNXm.a =.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W R %.= HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX6.d W W W W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ W i &XjXNXfX:X].B.q.T t a d e K.VXSXGXGXDXaXd.W e.e.d E.VXSXGXGXDXvXw.W =.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W W %.HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXK X.T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ a ) uXDXSXFXFXCXNXfX:X_.B.q.r .XFXGXGXGXCX3X=.=.e.,.~ %XCXGXGXGXCX1XW ` =.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W T $.m HXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHX5.R W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ~ ~ t x.NXSXGXGXGXSXSXDXFXCXNXmX8XcXSXGXGXGXCXW.e :.e.=.t.uXFXGXGXSXVXE.d :.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHX^ X.T W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ` t T.VXSXGXGXGXGXGXGXGXSXSXFXGXGXGXGXGXGXFX}.9.' W e v.VXSXGXGXSXNXm.d :.=.=.=.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W W T @.P HXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHX1.R W W W W W W W W W W W W W W W W E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ s ;XNXAXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXNX>X|.V.XXFXGXGXGXFXbXy.~ :.:.=.=.` ` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXH X.T W W W W W W W W W W W W W W E E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` R ' $XsXNXVXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXCXCXFXSXGXGXGXCXOXa :.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W W T $.c HXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHX1.R W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` ~ t.V.`.5XVXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFXXFXGXGXGXGXGXGXGXSXCX{.e.P.'.2XvXNXBXDXSXGXGXGXGXGXGXGXGXGXSXDXjX~.y W =.` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W W W @.HXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX: 1.R W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.:.e.e.e.~ s.fXDXGXGXGXGXGXGXGXSXNXD.f =.=.,.M.L.oXaXVXDXSXGXGXGXGXGXGXGXGXGXAXVX(.t ~ ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W R %. HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXl #.T W W W E ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.:.:.:.:.:.:.:.:.:.e.e.e.e.r.W H.NXSXGXGXGXGXGXGXGXDXzXg.r.f.f.f.r.=.=.g.`.fXBXAXGXGXGXGXGXGXGXGXGXAXjXH.t =.` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W T $.6 HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX~ ..W W W W E ~ ~ ~ ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.e.e.e.e.e.e.e.r.W |.CXGXGXGXGXGXGXGXGXBX1X,.f.f.f.f.h.h.f.,.~ d.3XVXAXGXGXGXGXGXGXGXGXGXDXsX' f ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W ..~ HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX$.R W W W W W E ~ ~ ~ ~ ~ ` ` ` ` ` ` =.=.=.=.=.=.:.:.:.:.:.:.:.e.e.e.e.e.r.r.r.,.w.>XFXGXGXGXGXGXGXGXSXNX`.=.f.h.h.h.h.f.f.f.f.=.~ ,XVXSXGXGXGXGXGXGXGXGXSXVXT.y ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W R $.HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXX %.T W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.=.=.:.:.:.:.:.:.:.:.e.e.e.e.e.e.r.r.r.u.=.x.fXDXGXGXGXGXGXGXGXSXmXA.,.h.h.h.k.k.h.f.f.f.f.:.~ 5XFXGXGXGXGXGXGXGXGXGXCX:XW ~ ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W W T $.. HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX8 $.T W W W W W W E ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.:.:.:.:.e.e.e.e.e.r.r.r.r.r.u.u.~ K.NXSXGXGXGXGXGXGXGXDXzXj.r.k.k.k.k.k.h.f.f.f.f.f.W V.VXSXGXGXGXGXGXGXGXGXDXuXw.f ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W T $.3 HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXY ..W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.:.e.e.e.e.e.e.r.r.r.r.u.u.u.u.~ |.CXGXGXGXGXGXGXGXGXBX2Xr.f.k.k.k.k.k.k.h.f.f.f.f.,.d.bXFXGXGXGXGXGXGXGXGXDXfXd.d =.` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W O.P HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXO.W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.e.e.e.r.r.r.r.r.r.u.u.u.u.r.w.>XFXGXGXGXGXGXGXGXSXNX'.,.k.k.k.k.k.k.k.h.h.f.f.f.e.y.kXFXGXGXGXGXGXGXGXGXDXfXg.d =.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W W W W W O.HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX$.R W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.=.:.:.:.:.e.e.r.r.r.r.u.u.u.u.u.u.f.=.b.fXDXGXGXGXGXGXGXGXSXmXJ.r.k.k.k.k.k.k.k.h.h.f.f.f.:.s.mXFXGXGXGXGXGXGXGXGXDXpXy.R =.` ` ` ~ ~ ~ ~ ~ E E W W W W W W W W W W W W W W W W W $.HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX1.R W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.u.u.u.f.=.K.NXSXGXGXGXGXGXGXGXFXxXM.u.k.k.k.k.k.k.k.k.h.f.f.k.~ K.VXSXGXGXGXGXGXGXGXGXCX5X=.~ =.=.` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W W W W $.HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHX+ $.T W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.f.f.f.=.|.CXGXGXGXGXGXGXGXGXFXXFXGXGXGXGXGXGXGXGXFX9XA.b.u.r.r.u.u.h.h.h.u.r.O.w.:XCXSXGXGXGXGXGXGXGXGXSXhXL.a :.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W T $.* HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXV X.T W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.u.u.f.,.b.fXFXGXGXGXGXGXGXGXGXSXFXVXpX*X[.R.V.M.g.d.d.g.b.T.pXCXSXGXGXGXGXGXGXGXGXGXDXpXe.~ :.:.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W W T $.; HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHX| O.T W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.:.e.e.r.r.u.u.u.u.f.=.K.NXSXGXGXGXGXGXGXGXGXGXGXSXFXFXBXNXmXuX>X3X3XyXmXVXFXSXGXGXGXGXGXGXGXGXGXAXhXE.d :.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W T @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` =.:.:.:.:.:.e.e.e.r.r.u.u.u.u.=.|.BXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXSXSXFXFXFXFXFXSXSXGXGXGXGXGXGXGXGXGXGXAXNX>X~ =.e.:.:.:.=.` ` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.:.:.:.:.e.e.e.r.r.r.u.u.r.w.>XFXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXZXNXeXe.~ e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.r.u.u.=.x.fXFXGXGXGXGXGXGXGXGXGXFXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFXCXfXoX:.~ r.e.:.:.:.:.:.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXc @.T W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.:.e.e.r.r.r.u.~ K.NXSXGXGXGXGXGXGXGXSXZX6XkXmXNXBXDXAXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGX0X'.S.~ =.u.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W W W @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.e.e.r.r.u.~ |.CXGXGXGXGXGXGXGXGXFX4X,.k.D.Q.,XkXmXNXDXSXSXGXGXGXGXGXGXGXGXGXGXGXXFXGXGXGXGXGXGXGXSXVX{.,.f.u.r.u.N.J.{.5XNXBXAXSXGXGXGXGXGXGXGXGXGXFXMXH.W r.u.r.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W W T @.h HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXo.O.T W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.e.r.O.s.fXFXGXGXGXGXGXGXGXSXmXJ.r.N.N.N.N.h.r.r.f.J.1XhXBXAXGXGXGXGXGXGXGXGXSXDXjX!.W e.u.r.e.e.e.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W W W W T @.g HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXB X.T W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` ` =.=.:.:.:.:.:.e.e.r.W H.NXSXGXGXGXGXGXGXGXDXuXM.u.k.k.N.N.N.N.N.h.,.e.D.>XNXSXGXGXGXGXGXGXGXGXSXZXjXE.W r.r.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W W T $.- HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXl @.T W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` =.=.=.:.:.:.:.e.e.r.W |.CXGXGXGXGXGXGXGXGXBX2Xr.h.k.k.k.k.k.k.k.k.k.h.,.,.|.NXZXGXGXGXGXGXGXGXGXGXZXgXV.~ u.e.e.e.:.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W T $.% HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHX@ $.T W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.:.' >XFXGXGXGXGXGXGXGXSXNX{.,.k.k.k.k.k.k.k.k.k.k.k.k.u.~ `.NXSXGXGXGXGXGXGXGXGXSXCX>X=.e.r.r.e.e.:.:.:.:.:.=.=.` ` ` ~ ~ ~ ~ ~ ~ W W W W W W W W W T $.. HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ` ` ` ` =.=.:.:.:.:.e.~ s.fXFXGXGXGXGXGXGXGXSXNXJ.,.k.k.k.k.k.k.k.k.k.k.h.h.k.u.O.2XCXGXGXGXGXGXGXGXGXGXAXhXV.~ u.r.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ W W W W W W W W W W $.HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX$.R W W W W W W W W W W W W W W W W W E ~ ~ ~ ~ ~ ~ ` ` ` ` ~ :.:.:.:.e.f Z.VXSXGXGXGXGXGXGXGXDXzXM.r.k.k.k.k.k.k.k.h.h.h.h.f.f.k.=.V.NXSXGXGXGXGXGXGXGXGXSXVX`.W r.e.e.e.e.:.:.:.:.=.=.=.` ` ` ~ ~ ~ ~ ~ ~ E W W W W W W W W $.HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXO.W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` ` =.~ Q a a W =.=.t XCXGXGXGXGXGXGXGXGXBX2Xr.f.k.k.k.k.k.k.h.h.h.h.f.f.f.f.r.y.kXFXGXGXGXGXGXGXGXGXGXBX,X~ :.e.e.e.:.:.:.:.:.:.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W W ~ ..HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXI O.W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ` a z.-X_.B.q.! u C.NXSXGXGXGXGXGXGXGXSXNX'.=.h.h.k.k.k.h.h.f.f.f.f.f.f.f.f.r.w.5XFXGXGXGXGXGXGXGXGXGXCX2X=.:.e.:.:.:.:.:.:.:.:.=.=.=.` ` ` ` ~ ~ ~ ~ ~ E W W W W W W O.P HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXk @.T W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ~ ~ t ).jXVXNXaX2X1XBXDXSXGXGXGXGXGXGXGXSXmXA.:.h.h.h.h.h.f.f.f.f.f.f.f.f.f.f.,.d.vXFXGXGXGXGXGXGXGXGXGXCX1X` =.:.:.:.:.:.:.=.=.=.=.=.=.` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W T $.; HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXo %.T W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ` y q.fXZXSXSXFXFXFXSXSXGXGXGXGXGXGXGXGXFXxXj.r.f.h.h.h.f.f.f.f.f.f.f.f.u.u.f.W B.NXSXGXGXGXGXGXGXGXGXSXBXoXW :.:.:.:.:.:.=.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ W W W W W W %. HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX$.R W W W W W W W W W W W W W W W W W W W E ~ ~ ~ ` e !.CXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFX+Xd ,.f.h.h.h.f.f.f.f.f.f.u.u.u.f.,.T :XFXGXGXGXGXGXGXGXGXGXSXNXE.f :.:.:.:.:.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W R $.HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX~ ..W W W W W W W W W W W W W W W W W W W W E ~ ~ a _ aXFXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXFX7XV.s.:.=.:.,.u.f.f.f.f.u.u.u.r.~ s ~.VXSXGXGXGXGXGXGXGXGXGXAXhXV.d :.:.=.=.=.=.=.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W O.E HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXg $.T W W W W W W W W W W W W W W W W W W W E ~ ~ e G.hXAXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXVXpX*X_.Z.x.t.:.` ~ ~ ~ ~ ~ ' x.*XVXSXGXGXGXGXGXGXGXGXGXGXDXuXw.W :.=.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W T $.; HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX %.R W W W W W W W W W W W W W W W W W W W W ~ d T qXgXBXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXFXFXBXNXaX>X,X[._.T.T.E.|.:XNXCXSXGXGXGXGXGXGXGXGXGXGXSXVX Xd =.=.=.=.` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W R %.HXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHX@.W W W W W W W W W W W W W W W W W W W W W ~ R ` s.H.oXkXNXNXCXFXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXSXDXFXCXCXBXVXVXBXCXFXSXSXGXGXGXGXGXGXGXGXGXGXGXAXhXm.a :.` =.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W W W W W W W W @.HXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXx @.T W W W W W W W W W W W W W W W W W W W W ~ ~ y t a _ g.L.oXkXhXVXCXFXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXGXSXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXSXBX:Xf ~ ` ` ` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ E W W W W W W W W W T $.h HXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHX%.R W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ d a t a ' s.R.oXnXDXSXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXGXZXhXg.y =.` ` ` ` ` ~ ~ ~ ~ ~ ~ ~ ~ ~ E ~ E W W W W W W W W W W R %.HXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXO.~ W W W W W W W W W W W W W W W W W W W W W ~ ~ ~ ~ ~ ` ` ~ W a a d ! c #DF943B", -", c #D8913C", -"< c #D8923E", -"1 c #DF953E", -"2 c #E28B23", -"3 c #E38B23", -"4 c #EA9023", -"5 c #EB9023", -"6 c #ED9122", -"7 c #ED9123", -"8 c #EE9123", -"9 c #EE9223", -"0 c #F39421", -"q c #F19423", -"w c #F39523", -"e c #F79521", -"r c #F59422", -"t c #F49623", -"y c #F69622", -"u c #F79623", -"i c #F09324", -"p c #F19424", -"a c #F19525", -"s c #F49624", -"d c #F59625", -"f c #F49725", -"g c #F79624", -"h c #F79724", -"j c #F69725", -"k c #F79725", -"l c #F69726", -"z c #F79726", -"x c #F89621", -"c c #F89722", -"v c #F89723", -"b c #F89724", -"n c #F89824", -"m c #F89825", -"M c #F99825", -"N c #F89925", -"B c #F89926", -"V c #F89927", -"C c #F99927", -"Z c #F0972E", -"A c #F7992A", -"S c #F79A2B", -"D c #F79B2C", -"F c #F69A2D", -"G c #F79D2F", -"H c #F89929", -"J c #F89A28", -"K c #F89A29", -"L c #F99A29", -"P c #F99B29", -"I c #F89A2A", -"U c #F89A2B", -"Y c #F99B2B", -"T c #F89B2C", -"R c #F89C2C", -"E c #F99C2D", -"W c #F99C2E", -"Q c #F89D2E", -"! c #F99D2F", -"~ c #E29335", -"^ c #E49639", -"/ c #E2983F", -"( c #F79F35", -") c #F99E31", -"_ c #F89E32", -"` c #F99E32", -"' c #F9A033", -"] c #F9A035", -"[ c #F9A135", -"{ c #F9A036", -"} c #F9A136", -"| c #F9A137", -" . c #F3A03F", -".. c #F7A43F", -"X. c #F8A139", -"o. c #F9A23A", -"O. c #FAA33B", -"+. c #FAA43E", -"@. c #FAA43F", -"#. c #EF9F41", -"$. c #EEA244", -"%. c #ECA34B", -"&. c #F8A440", -"*. c #F9A541", -"=. c #F9A644", -"-. c #F9A947", -";. c #F0A349", -":. c #F5A648", -">. c #F1A74E", -",. c #F7AA4F", -"<. c #E4A458", -"1. c #E4A55B", -"2. c #E8A95E", -"3. c #F2A950", -"4. c #F4AA52", -"5. c #FBAF55", -"6. c #E4A860", -"7. c #EAAC63", -"8. c #EBAF68", -"9. c #F2AF61", -"0. c #EBB16C", -"q. c #F6B568", -"w. c #E3AF71", -"e. c #EBBE89", -"r. c #E0BC93", -"t. c #E3C199", -"y. c #E6C59D", -"u. c #EAC89E", -"i. c #E7C8A2", -"p. c #EACBA6", -"a. c #EBCFAF", -"s. c #F1CCA0", -"d. c #E7CEB1", -"f. c #ECD1B0", -"g. c #E5D2BB", -"h. c #E8D2B8", -"j. c #DFDFDF", -"k. c #E7D5C1", -"l. c #E7D7C4", -"z. c #E5D7C7", -"x. c #E7DACB", -"c. c #EADAC8", -"v. c #E9DCCC", -"b. c #EDDFCE", -"n. c #E5DDD3", -"m. c #E4DFD9", -"M. c #ECE0D1", -"N. c #E4E1DD", -"B. c #EDE3D8", -"V. c #EAE4DD", -"C. c #ECE5DC", -"Z. c #E2E2E2", -"A. c #E5E2E0", -"S. c #E4E4E4", -"D. c #E7E7E7", -"F. c #EAEAE9", -"G. c gray92", -"H. c #EEEEEE", -"J. c None", -/* pixels */ -"J.J.J.J.J.J.J.1 > J.J.J.J.J.J.J.", -"J.J.J.J.J./ ..| ' ( ~ J.J.J.J.J.", -"J.J.J.< *.{ V $ r U W _ - J.J.J.", -"J.J., o.J 0 # <.w.$.F N H % J.J.", -"J.J.o.T e 1.r.k.x.t.S z B u J.J.", -"J.^ [ Y ! #.z.H.M.n.0.d n m 2 J.", -"J.X.) | =. .h.B.5.f.j.;.v B d J.", -": Q M ` &.>.A.V.p.c.l.4.E n d = ", -"; I b A Z 2.D.s.u.F.a.-.} C w & ", -"J.l g y 6.m.G.q.3.b.Z.,.] D 8 J.", -"J.3 k c %.d.C.v.N.S.y.@.L a * J.", -"J.J.j z x 8.i.g.e.9.+.W t 6 J.J.", -"J.J.+ s h G :.7.O.R B s 7 . J.J.", -"J.J.J.O i f P L K d p 5 J.J.J.", -"J.J.J.J.J.@ 9 q i 4 + J.J.J.J.J.", -"J.J.J.J.J.J.J.X o J.J.J.J.J.J.J." -}; diff --git a/share/pixmaps/bitcoin256.png b/share/pixmaps/bitcoin256.png deleted file mode 100644 index 1d42116ef..000000000 Binary files a/share/pixmaps/bitcoin256.png and /dev/null differ diff --git a/share/pixmaps/bitcoin256.xpm b/share/pixmaps/bitcoin256.xpm deleted file mode 100644 index 87bb35cda..000000000 --- a/share/pixmaps/bitcoin256.xpm +++ /dev/null @@ -1,465 +0,0 @@ -/* XPM */ -static char *bitcoin___[] = { -/* columns rows colors chars-per-pixel */ -"256 256 203 2", -" c #BE741B", -". c #C1761B", -"X c #C6791C", -"o c #CC7C1D", -"O c #D07F1D", -"+ c #C67B21", -"@ c #CC7E21", -"# c #D4821E", -"$ c #D9841F", -"% c #ED8E1D", -"& c #EF911F", -"* c #CF8022", -"= c #D48323", -"- c #DB8621", -"; c #DD8922", -": c #D58729", -"> c #D6882B", -", c #DE8C2A", -"< c #CE8C3C", -"1 c #D28934", -"2 c #D98E32", -"3 c #D28E3C", -"4 c #DF9132", -"5 c #D6903E", -"6 c #DD933B", -"7 c #E58C22", -"8 c #E98F23", -"9 c #E38F2B", -"0 c #E88F28", -"q c #ED9124", -"w c #E6922D", -"e c #EB942B", -"r c #EF982F", -"t c #F59624", -"y c #F89723", -"u c #F79826", -"i c #F89825", -"p c #F1972A", -"a c #F59A2C", -"s c #F89B2B", -"d c #E59534", -"f c #EA9632", -"g c #EE9933", -"h c #E3963B", -"j c #E6993D", -"k c #EC9C3B", -"l c #F49C33", -"z c #F99E32", -"x c #F29E3A", -"c c #F7A037", -"v c #F9A036", -"b c #F5A13C", -"n c #F9A33B", -"m c #CE9147", -"M c #D29245", -"N c #DC9641", -"B c #DD9846", -"V c #D2954B", -"C c #DC9A4B", -"Z c #E59C44", -"A c #EA9E43", -"S c #E39E4B", -"D c #E89F49", -"F c #F09F40", -"G c #EDA145", -"H c #E6A14D", -"J c #EBA34B", -"K c #F4A443", -"L c #F9A642", -"P c #F7A847", -"I c #FAA846", -"U c #F3A64A", -"Y c #F8A748", -"T c #F5A94D", -"R c #FAAA4B", -"E c #E6A454", -"W c #EBA552", -"Q c #EDA856", -"! c #E4A55B", -"~ c #E8A75B", -"^ c #E7A95E", -"/ c #EBA95B", -"( c #F0A751", -") c #F4AB53", -"_ c #FAAE53", -"` c #F4AE5A", -"' c #F8AF59", -"] c #FAB057", -"[ c #F6B15E", -"{ c #FAB25B", -"} c #DFAD6F", -"| c #DCAE77", -" . c #DFB27D", -".. c #E5AA64", -"X. c #E8AB61", -"o. c #E5AE6C", -"O. c #E6B06F", -"+. c #ECB16C", -"@. c #F5B365", -"#. c #FBB562", -"$. c #FBB867", -"%. c #F5B66B", -"&. c #FAB768", -"*. c #F4B86F", -"=. c #FBB96A", -"-. c #E1AE71", -";. c #E5B174", -":. c #EBB573", -">. c #EFB977", -",. c #E5B47A", -"<. c #EEBA7B", -"1. c #F3B770", -"2. c #F3B974", -"3. c #FBBC72", -"4. c #F3BC7B", -"5. c #F8BF7A", -"6. c #FAC079", -"7. c #DCB382", -"8. c #DFBB8F", -"9. c #DABB96", -"0. c #DBBD99", -"q. c #E2B682", -"w. c #E4B985", -"e. c #ECBD84", -"r. c #E3BB8B", -"t. c #EABF8C", -"y. c #F1BE83", -"u. c #E2BE92", -"i. c #D3BDA2", -"p. c #DEC09C", -"a. c #EEC28D", -"s. c #F4C286", -"d. c #F8C282", -"f. c #F3C48B", -"g. c #E7C297", -"h. c #ECC393", -"j. c #E2C29D", -"k. c #EAC69B", -"l. c #ECC89F", -"z. c #F1C694", -"x. c #F2C897", -"c. c #F1CA9B", -"v. c #DBC2A3", -"b. c #D6C2AB", -"n. c #DDC7AD", -"m. c #DEC9AF", -"M. c #D3C4B3", -"N. c #DDCAB3", -"B. c #D2C7B9", -"V. c #D6C9BA", -"C. c #DDCEBB", -"Z. c #DFD0BE", -"A. c #E2C5A2", -"S. c #E8C7A0", -"D. c #E6C9A5", -"F. c #EBCBA4", -"G. c #E2C7A8", -"H. c #E3CAAC", -"J. c #EBCDA9", -"K. c #EFD2AF", -"L. c #F3D1A7", -"P. c #F1D1A9", -"I. c #E4CEB3", -"U. c #E8CFB1", -"Y. c #E1CFBA", -"T. c #E6D0B6", -"R. c #E9D1B4", -"E. c #E4D2BC", -"W. c #EAD4BA", -"Q. c #F4D5B0", -"!. c #F4D9B9", -"~. c #CDCDCD", -"^. c #D5CCC3", -"/. c #D4CFCA", -"(. c #DED2C3", -"). c #D3D1CE", -"_. c #DED6CC", -"`. c #D5D5D5", -"'. c #DBD7D1", -"]. c #DEDAD4", -"[. c #DDDDDC", -"{. c #E3D5C3", -"}. c #E9D7C1", -"|. c #EBD9C4", -" X c #E1D6CA", -".X c #E3D9CD", -"XX c #EADDCD", -"oX c #E1DBD4", -"OX c #E8DFD4", -"+X c #E1DEDB", -"@X c #EDE3D7", -"#X c #E3E1DE", -"$X c #E8E3DC", -"%X c #F6E5D2", -"&X c #F4EBDF", -"*X c #E4E4E4", -"=X c #ECE7E2", -"-X c #EDE9E4", -";X c #ECECEC", -":X c #F0EBE7", -">X c #F4F4F4", -",X c #FEFEFE", -"X>X>X>X;X;X*X[.`.r.n n z v v v v c x l p l x x c c v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u X>X>X>X>X>X;X*X[.`.@.n n v v v v v c g E | S k f r l l l z z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i e X>X,X,X,X,X>X>X;X*X_.R n v v v v v v x e 0.`.`.V.p.;.H f e e p l l z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y , X>X,X,X,X,X>X>X;X*XI.L n v v v v n n x g V.`.[.[.[.[.[.(.p.;.S f r l z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u y X,X,X,X,X,X>X>X;X*Xa.n n v v v n n n l A `.[.*X*X-X-X*X*X*X[.`.V.9.K z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u X,X,X,X,X,X>X>X-X[.%.n n n n n n n b p o.[.*X;X;X;X>X;X;X*X*X[.`.~.T z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y 0 X>X,X,X,X,X,X>X;X*XoXR L n n n n n n b g u.*X-X;X>X>X>X>X>X;X*X*X[.N.L n z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y X>X,X,X,X,X>X>X;X*XI.L L n n n n n n b g C.*X;X>X>X,X,X,X>X>X;X*X[.g.L n z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u X,X,X,X,X,X>X>X;X*Xh.L L n n n n n n l G [.*X;X>X,X,X,X,X>X>X;X*X[.2.n n z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y w X,X,X,X,X,X>X>X-X[.%.L n n n n n n b l o.*X;X>X>X,X,X,X,X,X>X;X*X]._ n v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y X>X,X,X,X,X,X>X;X*XoXR L n n n n n n b g j.*X;X>X>X,X,X,X,X,X>X;X*XE.I n v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y t X>X,X,X,X,X>X>X;X*XT.I L n n n n n n b k Z.*X;X>X,X,X,X,X,X>X>X;X*Xl.L n v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y ; X,X,X,X,X,X>X>X;X*Xh.L L n n n n L L x G [.*X;X>X,X,X,X,X,X>X>X;X*X4.n n v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u i u X>X,X,X,X,X,X>X>X-X[.%.L L n n n L L L l ;.*X;X>X>X,X,X,X,X,X>X;X*X[._ L n v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y q X>X>X>X;X;X;X;X*X*X*X*X].N.q.! d e e r p q ,.-X;X>X>X,X,X,X,X,X>X;X*XoX_ I L n L L L L K g j.*X;X>X>X,X,X,X,X,X>X;X*XE.Y L n v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X>X>X>X>X>X>X>X>X;X;X;X;X*X*X*X*X_.I.r.o.Z w D.;X>X>X,X,X,X,X,X,X>X;X*XW.R I L L L L L L K k Y.*X;X>X,X,X,X,X,X>X>X;X*Xl.L L n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y q X>X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X*X*X*X*X$X}.=X>X>X>X,X,X,X,X,X,X>X;X*Xx.I I L L L L L L x J [.*X;X>X,X,X,X,X,X>X>X;X*X4.L n n v v v v v z z z z z z s s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X>X>X;X&.L L L L L L L L x ;.*X;X>X>X,X,X,X,X,X>X;X*X[.' L n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u y t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X>X>X@Xb l x x K L L L L k j.*X;X>X>X,X,X,X,X,X>X;X*XE.R L n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X:XW.g.;.H k k k b F k {.;X>X>X,X,X,X,X,X>X>X;X*XS.I L n n n n v v v v v z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X+XE.j.,.~ j A =X;X>X>X,X,X,X,X,X>X>X;X*X4.I L n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X;X*X*X*X*XXX}.;X>X>X,X,X,X,X,X,X>X>X;X#X{ I n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X;X>X>X>X,X,X,X,X,X,X,X>X>X;X|.R I n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X>X>X;XF.L L n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X,X,X,X,X,X,X,X,X,X,X,X>X>X;X@.a x b b n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.e.G g l c b n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X+XG...k g l b n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X*X(.w.A g l c c v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X*X'.u.A r l x c v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X*X].u.k r l c v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X*X_.q.g p l z v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X[.C.W p l c v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X*X*X[.w.r a l z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X-X-X-X*X*X-X;X;X;X;X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X[.H.g a z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xf.3.x.R..X+X*X*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*X(.k p z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X$.{ { { $.3.f.F.{.[.*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X_.W p z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t @ X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X|.{ ] _ ] { { { { $.3.h.R..X*X*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X'.k p z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 0 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ._ ] _ _ _ _ ] { { { #.$.$.f.T.oX*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X_.l a z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs._ _ _ _ _ _ _ _ _ ] { { { { { =.l..X*X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XH.t z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X+X&.] _ _ _ _ _ _ _ _ _ _ _ _ ] { { { #.k.oX*X-X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.:.t z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.{ { _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ] _ { J.*X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X'.l s z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XF.{ { _ _ _ _ _ _ _ _ ] _ _ _ _ _ _ _ _ _ _ _ y.oX*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.t.u z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ ] _ _ _ _ _ ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ ' .X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X'.z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X].&.{ ] _ _ _ ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ R R oX*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.:.u z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ _ _ _ _ ] ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ I @.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.s z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XF.{ { _ ' ] ] ] ] ] { { { ] ] ] _ _ _ _ _ _ _ _ R R _ n k.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_.n z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ { ] ] ] ] { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R R I T +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.T z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ { ] ] ] { { { { { { { ] ] ] _ _ _ _ _ _ _ _ _ R R R K D.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.%.z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ ] ] { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R R K e.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.<.v v z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ _ R R K +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X<.n v v z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.#.{ { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ _ R U / *X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xe.n n v v z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t t X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.#.{ { { { { { { { { { { { { { ] ] ] ' _ _ _ _ _ _ _ _ R K +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X<.n n v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ T K ,.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.>.n n v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t @ X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { { { { { { { { { { { { ] ] ] ] _ _ _ _ _ _ _ T G j.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.%.n n v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.{ { { { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ _ _ T J X-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X]._ L n v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X#X3.#.{ { { { { { { { { { { { { { { { { { ] ] ] _ _ _ _ _ ) G ..*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X{.R L n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.=.#.{ { { { { { { { { { { { { { { { { { { ] ] ' _ _ _ _ T k E.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XH.L L n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xc.] { { { { { { { { #.{ { { { { { { { { { { ] ] ] _ _ _ ( A w.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.a.L n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xx.( Q ( ) ` [ [ { #.#.#.{ { { { { { { { { { { ] ] _ ) T D o.*X;X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.[ L n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XOXI.u.O./ Q Q ` ` [ [ [ { { { { { { { { { ] ' ) ( J H r.*X-X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.R I n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X*X_.H.r.;.X./ Q Q ) ) ` ` ` ` ` ) ) ( J H W ,.{.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.y.I L n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X*X*X*X*X].(.H.u.q.;.^ ^ ~ ~ E E ~ o.r.G. X*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_._ Y L n n n n n v v v z z z z z z z s s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i u t @ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X;X;X*X*X*X*X*X*X[.]..X X XoX+X*X*X*X-X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.f.R I n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X;X;X-X-X*X*X*X-X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X;X*X X_ R L n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X;X;X;X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.%.R I L n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i t - X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X[.k.R R L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X*X[.l.] _ I L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X[.l.{ _ Y L L L n n n n n n n n v v v v v v z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*X].h.{ _ R L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X;X*X[.T.3.{ ] R I L L L L L n n n n n n n n n v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X;X;X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*XW.s.#.{ _ R I I L L L L L L n n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X-XQ.|.OX*X*X*X*X*X;X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X&X!.L.d.#.{ ] R R I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XXX3.3.3.s.c.R..X[.*X*X*X-X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X%X{ L R _ _ R R R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-XK.&.=.=.&.=.3.3.d.c.R..X[.*X*X*X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;XJ.J K Y R R Y I I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.$.#.#.#.#.&.&.=.=.3.3.f.F.}.+X*X*X*X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;XOX:.K U R R I I I I I L L L L L L n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i i i i t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X+X3.$.#.{ { #.#.#.#.$.$.&.=.=.3.6.c.W.+X*X*X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*Xj.K K R R I I I I I L L L L L n n n n n n n n v v v v v v z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i i i i i i i i i i i i u t = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.&.#.{ { { { #.#.#.#.#.#.#.#.$.$.=.=.5.J..X*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XH.K K R R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i i i i i i i u t = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { #.#.#.#.#.#.#.#.{ #.#.$.$.$.=.z.{.*X*X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X*X*XC.U K R I I I I I L L L L L L n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i i u q * s u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u u u u s s s s s s s s s s s z z z z z z z v v v v v n n n n n n n n L L L L L L I I K A Z.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.#.{ { { { { #.#.#.#.{ { { { { { { #.#.#.#.$.z.{.*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X*XC.b K Y I I I I L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i u q + X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.3.#.{ { { { { { #.#.#.{ { { { { { { { { { { #.#.#.$.F.+X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.H.b P I I I I I L L L L L n n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { { { { { { { { { #.{ 2.{.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.e.b Y I I I I L L L L L L n n n n n n n n v v v v z z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.#.#.{ { { { { { { { { { { { { { { { { { { { { { { { { { { U.*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X].T L Y I I I I L L L L L L n n n n n n n n v v v v v z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.#.{ { { { { { { { { { { { { { { { { { { { { { { { { ] { { _ R.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X*XD.L R I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.#.{ { { { { { { { { { { { { { { { { { { { { { ] ] ] ] ] { ' R T.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.` L I I I I I L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t 8 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.$.#.{ { { { { { { { { { { { { { { { { { { { ] ] ] ] ] ] ] _ ] _ R oX*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.g.n I Y I I I I L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i i i i t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { { { { { { { { { { { { { { { { { { { { ] ] ] ] ] _ _ _ _ _ ] Y <.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X(.I I I I I I L L L L L L L n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i u t ; X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.{ { { { { { { { { { { { { { { { { { { ] ] ] ] ] ] _ _ _ _ _ _ _ _ T .X-X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.[ L I I I L L L L L L L L n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s u u u u u i i i i i i i i i i i i i i u q = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ { ] { { { { { { { { { { { { { { ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ P g.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.e.n I L L L L L L L L L L n n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ ] ] { { { { { { { { { { { ] ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ Y +.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xg.L I L L L L L L L L L n n n n n n n n n n n v v v v z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { ] ] ] { { { { { { { { { ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ T Q #X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.I I L L L L L L L n n n n n n n n n n n n n v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xf.{ { ] ] ] ] { { { { { { { ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Y W +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XI.I I L L L L L n n n n n n n n n n n n n n n v v v v v v z z z z z z z s s s s s s s s s s u u u u u i i i i i i i i i i i i t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.=.{ ] ] ] ] ] { { { { { ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R T W +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.I L L L L n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z s s s s s s s s s s s u u u u i i i i i i i i i i i u q ; X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X{.#.{ _ _ ] ] ] ] { ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R K X.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XE.I L n n n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z s s s s s s s s s s s s u u u i i i i i i i i i i i t q @ X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.{ { _ _ _ ] ] ] ] ] ] ] ] ' _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R x q.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XD.R L n n n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i t q X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xs.{ ] _ _ _ ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R T k G.*X;X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XS.I L n n n n n n n n n n n n n v v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s u u u u i i i i i i i i i t q X>X>X,X,X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X#X&.{ _ _ _ _ _ ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R K A oX;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*Xh.L L n n n n n n n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s u u u i i i i i i i i i t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X|.{ ] _ _ _ _ _ ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R U k u.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-X[.2.L L n n n n n n n n n v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s u u u u i i i i i i i u q = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xc.R _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R R T k D +X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.' L n n n n n n n n v v v v v v v z v v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s u u u u i i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;Xf.K G G U ) ) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ R R R R R R R R R R R U A j {.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X{.R L n n n n n n v v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u i i i i i i t q X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X-XXXH.w.X.J J J T ) ) ) _ _ _ _ _ _ _ _ R R R R R R R R R R R Y K k D Y.*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XJ.L L n n n n v v v v v v v v z z z z z z z z z z z z z s z s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i u t 7 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X#X(.A.q...H J J U U T T T T R R R R R R R R R Y Y U K k A ;..X*X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X[.4.L n n n v v v v v v v v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i t q * X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X;X;X*X*X*X[.(.H.u.,.^ J D G A J K K U U U U K k k k A E w.Y.*X*X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X]._ L n v v v v v v v v v v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i t q X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X;X;X;X-X*X*X*X*X[._.N.A.u.;.;...E E E E ..;.q.j.I.+X*X*X;X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*XH.I L n v v v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i t 8 X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X;X;X;X;X-X*X*X*X*X*X*X*X+X+X+X+X*X*X*X*X*X;X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.1.L n v v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i u q ; X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X XR L n v v v v v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i t q X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X-X[.a.L n v v v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i t 8 X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X]._ L n v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i u q ; X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X;X*X[.a.L n v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X_.R L n z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i t 8 X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.2.L n z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u s u u u u u u u u i i i i i i i i i i i i i i i i i i t q = X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X*X[.D.L L v z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X XR L n z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i u q 7 X>X,X,X,X,X,X,X,X>X>X>X>X;X;X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X;X-X*X'._ I n z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u i u u i i i i i i i i i i i i i i i i i i i i i i t q o X>X,X,X,X,X,X,X>X>X>X=X;X-X-X-X;X;X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X;X-X*X].%.L L z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X>X,X,X,X,X,X>X>X;X=X=.5.c.W.oX*X*X-X;X>X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X*X*X_.%.I L z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i t q - X>X,X,X,X,X,X>X>X;X|._ _ _ { #.4.l.}.$X;X>X>X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X;X;X*X[.E.{ I L v z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X,X,X,X,X,X>X>X;X*XF.R R R R _ _ { { { 4.-X>X>X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X>X>X>X>X,X,X,X,X,X,X,X,X,X,X,X>X>X>X>X>X>X>X;X;X*X*X[.k._ I n z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 X,X,X,X,X,X>X>X;X*X4.R I I I I R R R b U -X>X>X,X,X,X,X,X,X,X,X>X>X>X>X>X;X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X;X;X;X-X*X*X[.T.*.R L n z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q X>X,X,X,X,X,X>X;X*X+X] R I L I I I I P x t.;X>X>X,X,X,X,X,X,X,X>X>X;X;X;X;X-X-X-X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X;X*X*X*X[.].U.4.R I L v z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 X>X,X,X,X,X>X>X;X*XE.R Y L L I I I I K k I.-X;X>X,X,X,X,X,X,X>X>X;X|.f.J.W..X[.[.*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X[._.I.h.#.R L L n z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q . X,X,X,X,X,X>X>X;X*Xl.I I L L L I I P K A oX-X>X>X,X,X,X,X,X>X>X;X;Xs.R _ _ { #.4.y.S.l.T.{.{. XoXoXoXoX].oX{.{.E.k.a.2.{ _ I L n v z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 X,X,X,X,X,X>X>X;X[.2.I I L L L L I L x ^ *X;X>X>X,X,X,X,X,X>X>X;X*X#.I I I I Y I R I _ R _ ] { { [ { { { { ] _ R R I I L n n v z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q . X>X,X,X,X,X,X>X;X*X]._ Y L L L L L I L k r.*X;X>X>X,X,X,X,X,X>X;X-X.XR L n n n n n n L L L L L L L n L n n n L n n n c v z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 7 X>X,X,X,X,X>X>X;X*XT.R I L L L L L L K k H.*X;X>X>X,X,X,X,X>X>X;X*XJ.L L n n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X,X,X,X,X,X>X>X;X*Xk.I I n L L L L L b k ].*X;X>X,X,X,X,X,X>X>X;X*Xy.L n n n n v v v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 X,X,X,X,X,X>X>X-X[.2.L L n L L L L L l ^ [.-X>X>X,X,X,X,X,X>X;X*X[.[ L n n n v v v v v v v z z v z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X,X,X,X,X,X>X;X*X]._ L L n L L L L K g r.*X;X>X>X,X,X,X,X,X>X;X*X{.R L n v v v v v v v z z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - X,X,X,X,X>X>X;X*XE.I L n n n L L L b g H.*X;X>X>X,X,X,X,X>X>X;X*XF.L L v v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i u q 8 X>X>X,X>X>X>X;X*Xk.L L n n n n L L x k _.*X;X>X,X,X,X,X,X>X>X;X*Xy.n n v v v v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q # X>X>X>X>X;X*X[.2.L L n n n n n b l ~ [.-X>X>X,X,X,X,X,X>X;X*X[.' L n v v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s s u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 X>X,X,X,X,X,X>X;X*X{.I n c v v z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X>X,X,X,X,X>X>X;X*XF.L n v z z z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - X>X,X,X,X,X>X>X;X*X4.n n z z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 .L n n n n n n b l E [.*X;X>X>X,X,X,X>X>X;X*X[.' n v z z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t 8 X>X>X>X>X>X;X*X{.I n z z z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q - X>X>X;X;X*X[.S.n n z z z z z z z z s s s s s s s s s s s s s s s s s s s s s u u u u u u u u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i t q 7 c #F79827", -", c #F89825", -"< c #F0962B", -"1 c #F59A2D", -"2 c #F99B2B", -"3 c #EC9732", -"4 c #EC9A37", -"5 c #E2963B", -"6 c #E6983A", -"7 c #EC9C3B", -"8 c #F69D33", -"9 c #F99E32", -"0 c #F49E3A", -"q c #F9A036", -"w c #F6A13C", -"e c #F9A33B", -"r c #D79341", -"t c #DC9641", -"y c #E39A43", -"u c #EA9D42", -"i c #EFA041", -"p c #EDA34B", -"a c #F5A443", -"s c #F9A643", -"d c #FAA846", -"f c #F2A64C", -"g c #F9AA4B", -"h c #E5A251", -"j c #ECA756", -"k c #EBA758", -"l c #FAAF57", -"z c #FBB057", -"x c #FBB25B", -"c c #DFB179", -"v c #E4AA65", -"b c #EBAE64", -"n c #E9AF69", -"m c #FBB665", -"M c #F1B46A", -"N c #F8B96D", -"B c #E5B071", -"V c #EBB777", -"C c #EEB877", -"Z c #E7B478", -"A c #EBB97D", -"S c #F0B671", -"D c #F2B871", -"F c #EFBC80", -"G c #E6BD8D", -"H c #EDBF88", -"J c #E6BF90", -"K c #F1C187", -"L c #F1C288", -"P c #E5C093", -"I c #EEC493", -"U c #E1C19B", -"Y c #E9C69C", -"T c #ECC89D", -"R c #F1C897", -"E c #DFC5A4", -"W c #DBCBB8", -"Q c #E2C7A7", -"! c #EBCBA6", -"~ c #E6CBAB", -"^ c #E9D2B7", -"/ c #E5D1B9", -"( c #EBD6BD", -") c #EFD9BE", -"_ c #DDD0C2", -"` c #DCD7D2", -"' c #DEDEDE", -"] c #ECDAC5", -"[ c #EDDECB", -"{ c #E9E0D5", -"} c #E7E0D9", -"| c #E9E2DB", -" . c #EFE8DF", -".. c #E5E5E5", -"X. c #EBE7E2", -"o. c #EFEAE6", -"O. c #ECECEC", -"+. c #F2ECE6", -"@. c #F1F0EE", -"#. c #F4F4F4", -"$. c #FBFBFB", -"%. c None", -/* pixels */ -"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.%.%.%.%.%.t 5 5 $ %.%.%.%.%.%.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.%.%.r u w q 9 9 9 8 4 # %.%.%.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.y s e 9 2 , , , : > 2 9 q 5 %.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.s q 2 , , , , : , > 2 2 > > 2 9 %.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.t e 1 , , , , : : ; > 2 9 9 2 , , > 2 + %.%.%.%.%.%.", -"%.%.%.%.%.$ e 2 , , , , , , ; u u 8 1 1 2 > , , > > + %.%.%.%.%.", -"%.%.%.%.%.e 2 , , : > ; ; > < ` ` 0 c n 1 2 , , , > , %.%.%.%.%.", -"%.%.%.%.e 1 , , , , ; h v - 3 ..! w ' _ 9 2 > , , , > : %.%.%.%.", -"%.%.%.6 q , : , > 2 > W ..| [ #.H V ..D 9 9 2 , , , , , % %.%.%.", -"%.%.%.e 2 , > 2 2 2 9 b ! #.$.$.#.#.#.Y i 1 2 > , , , > ; %.%.%.", -"%.%.@ q > 2 2 2 9 q e q 0 o.$.+.) { #.#.| b 2 2 , , , , : X %.%.", -"%.%.4 9 2 2 9 q e e s w b O.#.( m x I @.$...f > > , , , : & %.%.", -"%.%.8 > 2 2 9 e s d g a P #.#.L x l a [ $.#.A 2 2 , : , , ; %.%.", -"%.+ 1 , , 2 2 q e d g f / $.#.T n k Z o.$.O.M 9 2 > , , , ; X %.", -"%.* 2 , , , 2 9 q e s f X.$.#.O.O.O.#.$.+.Y g e 9 2 , , , ; o %.", -"%.* 2 , , , 2 2 q e w n O.$.[ R ( O.$.$.[ d s e 9 2 2 , , ; o %.", -"%.+ 2 , , , > 2 8 8 1 G #.#.T m m N ] #.#.~ s e e 9 2 > : ; X %.", -"%.%.> , , , , 2 < v B [ $.O.m z z s b #.$...g e e q 9 2 ; = %.%.", -"%.%.= : , , , : 7 ' O.#.$.@.C j p u ~ #.$.} g q 9 9 2 2 ; % %.%.", -"%.%.o , , , , : 0 G ^ .$.#.O.X.{ X.#.$.#.Y e 9 2 2 > , ; %.%.", -"%.%.%., : , , , 2 2 2 M O.) ] #.#.#.#.O./ d 9 2 > , , ; = %.%.%.", -"%.%.%.& ; , , , , 2 ; Q ..g F O.K A H S s 9 2 > , : , ; o %.%.%.", -"%.%.%.%.; ; , , , , 2 E _ d ' ..d q q 9 2 > , : , , ; = %.%.%.%.", -"%.%.%.%.%.; : , , , 2 q d g U J e 2 2 > , , , , , ; = %.%.%.%.%.", -"%.%.%.%.%.o ; : , , , 2 9 q 9 q 9 > , : , , , , ; = . %.%.%.%.%.", -"%.%.%.%.%.%.. ; ; , , > 2 2 2 > , , , , , , , ; = %.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.= ; : > 2 2 , , : , , , , ; ; & %.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.. = ; > : , , , , ; ; = = X %.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.%.%. % = ; ; ; ; & O %.%.%.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.%.%.%.%.%. X X %.%.%.%.%.%.%.%.%.%.%.%.%.%.", -"%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%." -}; diff --git a/share/pixmaps/bitcoin64.png b/share/pixmaps/bitcoin64.png deleted file mode 100644 index 08c676ae4..000000000 Binary files a/share/pixmaps/bitcoin64.png and /dev/null differ diff --git a/share/pixmaps/bitcoin64.xpm b/share/pixmaps/bitcoin64.xpm deleted file mode 100644 index 851829d41..000000000 --- a/share/pixmaps/bitcoin64.xpm +++ /dev/null @@ -1,242 +0,0 @@ -/* XPM */ -static char *bitcoin__[] = { -/* columns rows colors chars-per-pixel */ -"64 64 172 2", -" c #8F6319", -". c #8F6A1A", -"X c #90651A", -"o c #916C1A", -"O c #AF7C1E", -"+ c #B1781E", -"@ c #9A7026", -"# c #AC801F", -"$ c #B1811F", -"% c #A9812B", -"& c #B08320", -"* c #BB8621", -"= c #BD8E22", -"- c #A58132", -"; c #FC8400", -": c #FD8A03", -"> c #FD8E0C", -", c #FF910E", -"< c #F98F14", -"1 c #F79117", -"2 c #FD9314", -"3 c #FC951B", -"4 c #FE9A1D", -"5 c #CA8E22", -"6 c #CC8E2A", -"7 c #D48D23", -"8 c #C39223", -"9 c #CE9925", -"0 c #D19C25", -"q c #D19329", -"w c #D5992B", -"e c #DD9D33", -"r c #D69F3C", -"t c #E29425", -"y c #E79925", -"u c #EA9926", -"i c #E69A2C", -"p c #F79625", -"a c #F99524", -"s c #F79825", -"d c #F89825", -"f c #F3962A", -"g c #F69B2C", -"h c #F89B2B", -"j c #E19F30", -"k c #EE9B34", -"l c #F49D33", -"z c #F99E32", -"x c #F39F3B", -"c c #DFA731", -"v c #D7A43D", -"b c #DCA63C", -"n c #EEA328", -"m c #FFA225", -"M c #FFAB26", -"N c #F3A529", -"B c #FEA429", -"V c #F4AB2A", -"C c #FFAC2A", -"Z c #FFB325", -"A c #FFB42C", -"S c #FFBB2D", -"D c #E3A335", -"F c #E5A438", -"G c #EDA03D", -"H c #F7A037", -"J c #FAA135", -"K c #F3AB31", -"L c #FEAB31", -"P c #F4A13C", -"I c #F9A33B", -"U c #FDB432", -"Y c #FFBF37", -"T c #FFC12F", -"R c #FFC230", -"E c #FFC03E", -"W c #DFAF41", -"Q c #ECA34D", -"! c #EDA84E", -"~ c #F2A343", -"^ c #FAA642", -"/ c #FAA846", -"( c #F1A74C", -") c #F6A94F", -"_ c #FAAA4A", -"` c #E7A451", -"' c #ECA754", -"] c #EFAA56", -"[ c #ECAC5B", -"{ c #F3AA52", -"} c #FCAE52", -"| c #FBB056", -" . c #FBB25C", -".. c #E7AB61", -"X. c #ECB067", -"o. c #E7B36D", -"O. c #EBB36C", -"+. c #F2B163", -"@. c #FCB460", -"#. c #F0B56B", -"$. c #E3B274", -"%. c #EDB672", -"&. c #EDB877", -"*. c #E2B57C", -"=. c #ECB97B", -"-. c #E4BA83", -";. c #EBBD83", -":. c #E7BF8D", -">. c #EBBD88", -",. c #E9C08C", -"<. c #E7C496", -"1. c #EBC393", -"2. c #EBC997", -"3. c #E7C49A", -"4. c #E9C69A", -"5. c #E3CA9D", -"6. c #E9C89E", -"7. c #DCC9AE", -"8. c #DDCBB2", -"9. c #E3C7A2", -"0. c #E5CAA3", -"q. c #E9CBA3", -"w. c #E5CEAB", -"e. c #E8CEAA", -"r. c #E4D4AC", -"t. c #EBD2AF", -"y. c #E7CFB2", -"u. c #E1D4B4", -"i. c #E8D5B6", -"p. c #E5D7BB", -"a. c #E9D6BB", -"s. c #E5D8B9", -"d. c #EAD8BE", -"f. c #F0D6B4", -"g. c #DFDFC6", -"h. c #E3D6C1", -"j. c #E9D7C0", -"k. c #E6DAC5", -"l. c #EBDCC7", -"z. c #E5DCCA", -"x. c #EADEC9", -"c. c #E8DFD0", -"v. c #D7E2D9", -"b. c #E3E0C9", -"n. c #EEE2CB", -"m. c #E6E1D4", -"M. c #E9E2D3", -"N. c #E4E4DC", -"B. c #E9E5DE", -"V. c #F4EDDE", -"C. c #DFE8E6", -"Z. c #DEEEE8", -"A. c #DFF2F3", -"S. c #DDFFFF", -"D. c #E1E6E0", -"F. c #E8E6E2", -"G. c #E8E9E5", -"H. c #E5EFEC", -"J. c #E8E9EA", -"K. c #EAF3EE", -"L. c #F3F3EB", -"P. c #E7EDF2", -"I. c #E8EEF3", -"U. c #E7F4F7", -"Y. c #E9F0F7", -"T. c #EBF5FD", -"R. c #E4FEFF", -"E. c #ECFCFF", -"W. c #F4F5F4", -"Q. c #F4FFFF", -"!. c #FEFFFF", -"~. c None", -/* pixels */ -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.F L h C C A A A A C C h L e ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.D N C m d d a a p a a p a a d m m C N j ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.- K M m a p s d d d d d d d d d d d d s p d m M V % ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.Y M d a d d d d d d d d d d d d d d d d h h d s a d M U ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.E m 4 a d d d d d d d d d d d d d d d d d d h h h d d d a d M U ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.C 4 a d d d d d d d d d d d d d d d d d h h h h h h d d d d d a m C ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.W S a p d d d d d d d d d d d d d d d d h h h h g g h h h d d d d d p a S c ~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.v M a s d d d d d d d d d d d d d d d h h h h h g z z g h h d d d d d d s a C w ~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.r Z a d d d d d d d d d d d d d d d g 4 : 2 h z z z z z h h h h d d d d d d d a S q ~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.b Z a d d d d d d d d d d d d d d h h 4 x $.l a z H h h H z h h h d d d d d d d d a A w ~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.T a s d d d d d d d d d d d d h h h g : $.R.T.7.a B x f > a H h h d d d d d d d d s a R ~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.U a s d d d d d d d d d d d d h h h h z : e.!.!.p.2 3 8.D.5.' a h h h d d d d d d d d p d A ~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.U M p d d d d d d d d d d h h 1 : : 2 h h p B.!.Q.%., l J.!.R.-.> z h h h d d d d d d d d p C N ~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.S a d d d d d d d d d d h d 3 7.r.O.G p ; k E.!.T.( , [ E.!.T.~ 4 z h h h d d d d d d d d d a S ~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.V d s d d d d d d d d h h h 2 l E.!.Q.T.m.:.q.!.!.l.: : -.Q.!.c.a z z z g h h d d d d d d d d s m A ~.~.~.~.~.~.~.", -"~.~.~.~.~.~.@ S a d d d d d d d h h h h z : *.R.!.!.!.!.Q.!.!.!.V.,.Q d.!.Q.1.2 I z z h h h d d d d d d d d d a S X ~.~.~.~.~.~.", -"~.~.~.~.~.~.U d s d d d d d h h h h h g z a [ 5.M.Q.!.!.!.!.!.!.!.Q.E.!.!.Q.&.; 3 J H z h h h d d d d d d d d s h C ~.~.~.~.~.~.", -"~.~.~.~.~.~.S a d d d d h h h h h h z z z I d > < %.W.!.!.!.!.!.!.!.!.!.!.!.W.s.[ > 4 H g h h d d d d d d d d d a S ~.~.~.~.~.~.", -"~.~.~.~.~.i M p d d d h h h h g z z z z J H I I J > x.!.!.!.!.Q.T.E.Q.!.!.!.!.!.E.u.f 2 H h h h d d d d d d d d p C 7 ~.~.~.~.~.", -"~.~.~.~.~.C a d h h h h h g g z z z J J I I I I J P J.!.!.!.!.d.P =.e.G.E.!.!.!.!.Q.Z.f 2 z h h d d d d d d d d d d A ~.~.~.~.~.", -"~.~.~.~.~.A a h h h h h g z z z J H I I I I ^ / d X.E.!.!.!.Q.1.4 I J I ;.U.!.!.!.!.!.N.1 h g h h d d d d d d d d a S ~.~.~.~.~.", -"~.~.~.~.6 C p d h h h z z J J J I I I I ^ ^ ^ _ a 3.Q.!.!.!.E.#.I . ._ 3 ] K.!.!.!.!.E.O., z h h h d d d d d d d p A + ~.~.~.~.", -"~.~.~.~.i B d d h h h g z J I I I I ^ ^ ^ / / _ h k.!.!.!.!.J.) } . .| .3 6.Q.!.!.!.Q.q.> z g h h d d d d d d d d B t ~.~.~.~.", -"~.~.~.~.B d d d d h h h z z J I I ^ / / / _ _ ^ ( I.!.!.!.Q.d.I . . .| .d 1.Q.!.!.!.Q.q.2 z h h h d d d d d d d d d B ~.~.~.~.", -"~.~.~.~.C a d d d d h h g z J H I ^ ^ / _ _ } J %.E.!.!.!.Q.;.4 _ } | } J f m.!.!.!.!.Q.;.2 J z g h h d d d d d d d a A ~.~.~.~.", -"~.~.~.~.C a d d d d h h h z z J I I ^ ^ / _ } z 6.Q.!.!.!.!.n.<.&.+.{ ) ] h.Q.!.!.!.!.R.~ d H z z h h h d d d d d d a A ~.~.~.~.", -"~.~.~.~.A a d d d d d h h g z z H I I ^ / _ _ z k.!.!.!.!.!.!.Q.E.I.F.F.T.Q.!.!.!.!.E.9.2 I J z z h h h d d d d d d d A ~.~.~.~.", -"~.~.~.~.S a d d d d d h h h z z J I I ^ ^ / I ( P.!.!.!.!.Q.Q.!.!.!.!.!.!.!.!.!.!.E.w.d J I I J z h h h d d d d d d d A ~.~.~.~.", -"~.~.~.~.A a d d d d d d h h h z J J I I ^ / h O.E.!.!.!.Q.f.1.z.Y.E.!.!.!.!.!.!.L.! , ^ / I I H z z h h h d d d d d d A ~.~.~.~.", -"~.~.~.~.S p d d d d d d h h h z z J I I ^ / d <.Q.!.!.!.E.+.d _ +.>.k.E.!.!.!.!.Q.s.P J _ ^ I I J z z h h h d d d d d A ~.~.~.~.", -"~.~.~.~.C a d d d d d d d h h g z z H I I ^ d k.!.!.!.!.J.{ | @.} I I O.H.!.!.!.!.Q.C.l I ^ I I H J z g h h d d d d a A ~.~.~.~.", -"~.~.~.~.B a d d d d d d d h h h h z z J I J x P.!.!.!.Q.j.I . . . . .B { K.!.!.!.!.Q.0.a / ^ I I J z z h h h d d d a A ~.~.~.~.", -"~.~.~.~.B d d d d d d d d d h h h J h f 2 ; [ E.!.!.!.Q.1.I . . .| | .d 4.Q.!.!.!.!.m.z I ^ I I I J z h h h h d d d B ~.~.~.~.", -"~.~.~.~.u B d d d d d d d d h h z , ' v.q.X.M.!.!.!.!.E.#.^ . .| } } } d >.Q.!.!.!.!.F.x J I I I J J z z h h h d d C t ~.~.~.~.", -"~.~.~.~.7 C p d d d d d d d d h h : y.Q.Q.Q.!.!.!.!.!.B.d B / _ } } } J 1 k.!.!.!.!.!.c.s J I H J J z z z h h h h s A + ~.~.~.~.", -"~.~.~.~.~.A a d d d d d d d d h > ` R.!.!.!.!.!.!.!.!.L.q.=.[ ~ z h h l 0.Q.!.!.!.!.Q.q.2 I J J z z h h h h h h h a S ~.~.~.~.~.", -"~.~.~.~.~.C d d d d d d d d d d > ..g.Y.E.Q.!.!.!.!.!.!.Q.E.T.B.k.a.d.P.Q.!.!.!.!.!.E.[ 2 J z z z g h h h h d d d d C ~.~.~.~.~.", -"~.~.~.~.~.y C p d d d d d d d d g 3 > l [ <.x.W.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.!.Q.z.> z z z h h h h h d d d d p C 7 ~.~.~.~.~.", -"~.~.~.~.~.~.S a d d d d d d d d d h h 3 , > ; =.Q.!.W.T.Q.!.!.!.!.!.!.!.!.!.!.!.Q.A.g 2 z h h h h h h d d d d d a S ~.~.~.~.~.~.", -"~.~.~.~.~.~.C h s d d d d d d d d d h g z H : <.!.!.t.l &.V.!.!.Q.Q.Q.Q.!.Q.Q.E.b.l > H h h h h h d d d d d d s m C ~.~.~.~.~.~.", -"~.~.~.~.~.~.X S a d d d d d d d d d h h h h p N.!.Q.=.: < c.!.Q.2.&.e.a.d.i.6.[ < 2 z h h h h d d d d d d d d a S ~.~.~.~.~.~.", -"~.~.~.~.~.~.~.A h s d d d d d d d d d h g 2 ~ E.!.E.{ 2 [ E.!.T.l : 2 1 3 2 > > h z h h h h d d d d d d d d s m A ~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.S a d d d d d d d d d h h : -.R.!.B.h 2 =.Q.!.M.p z z z h h z g h h h d d d d d d d d d d d a S ~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.N C p d d d d d d d d d h 3 ' 2.N.9.2 3 z.!.!.q.> J z h h h h h h d d d d d d d d d d d d p C n ~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.S h p d d d d d d d d d z 3 : p l J g 8.T.S.O.> z h h h h h d d d d d d d d d d d d d p h S ~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.S a s d d d d d d d d h h z d h I J a P o.P d g h h h d d d d d d d d d d d d d d s a S ~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.* S a s d d d d d d d d h h g z J J h 3 > d z h h h d d d d d d d d d d d d d d s a S * ~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.$ T a s d d d d d d d h h h z z z h g g h h d d d d d d d d d d d d d d d d s a T O ~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.& S a p d d d d d d h h h z g h h h h h d d d d d d d d d d d d d d d d p a S # ~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.8 S d p d d d d d d h h g h h h h d d d d d d d d d d d d d d d d d p h S = ~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.S A a s d d d d h h h h h d d d d d d d d d d d d d d d d d s a A S ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.0 T m p d d d d h h h d d d d d d d d d d d d d d d d d p B S 9 ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.V S m a p d h d d d d d d d d d d d d d d d d p a m S V ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.o V S C d p p d d d d d d d d d d d d p p d C S N . ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.5 C S A B d d a a d d a a a d B A S C 5 ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.O t B A A A A A A A A B t O ~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.", -"~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~.~." -}; diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico deleted file mode 100644 index 0c4e6e814..000000000 Binary files a/share/pixmaps/check.ico and /dev/null differ diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico deleted file mode 100644 index 754eebc48..000000000 Binary files a/share/pixmaps/favicon.ico and /dev/null differ diff --git a/share/pixmaps/nsis-header.bmp b/share/pixmaps/nsis-header.bmp deleted file mode 100644 index 9ab0ce259..000000000 Binary files a/share/pixmaps/nsis-header.bmp and /dev/null differ diff --git a/share/pixmaps/nsis-wizard.bmp b/share/pixmaps/nsis-wizard.bmp deleted file mode 100644 index 71255c685..000000000 Binary files a/share/pixmaps/nsis-wizard.bmp and /dev/null differ diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp deleted file mode 100644 index 676b5c4b4..000000000 Binary files a/share/pixmaps/send16.bmp and /dev/null differ diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp deleted file mode 100644 index 06c747f93..000000000 Binary files a/share/pixmaps/send16mask.bmp and /dev/null differ diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp deleted file mode 100644 index faf24e0d8..000000000 Binary files a/share/pixmaps/send16masknoshadow.bmp and /dev/null differ diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp deleted file mode 100644 index 2b90422b3..000000000 Binary files a/share/pixmaps/send20.bmp and /dev/null differ diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp deleted file mode 100644 index f124d0da0..000000000 Binary files a/share/pixmaps/send20mask.bmp and /dev/null differ diff --git a/share/setup.nsi.in b/share/setup.nsi.in deleted file mode 100644 index 6c0e895bb..000000000 --- a/share/setup.nsi.in +++ /dev/null @@ -1,179 +0,0 @@ -Name "@PACKAGE_NAME@ (@WINDOWS_BITS@-bit)" - -RequestExecutionLevel highest -SetCompressor /SOLID lzma - -# General Symbol Definitions -!define REGKEY "SOFTWARE\$(^Name)" -!define VERSION @CLIENT_VERSION_MAJOR@.@CLIENT_VERSION_MINOR@.@CLIENT_VERSION_REVISION@ -!define COMPANY "Bitcoin Core project" -!define URL http://www.bitcoin.org/ - -# MUI Symbol Definitions -!define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" -!define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_RIGHT -!define MUI_HEADERIMAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-header.bmp" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM -!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} -!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup -!define MUI_STARTMENUPAGE_DEFAULTFOLDER "@PACKAGE_NAME@" -!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin-qt.exe -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE - -# Included files -!include Sections.nsh -!include MUI2.nsh -!if "@WINDOWS_BITS@" == "64" -!include x64.nsh -!endif - -# Variables -Var StartMenuGroup - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!insertmacro MUI_LANGUAGE English - -# Installer attributes -OutFile @abs_top_srcdir@/bitcoin-${VERSION}-win@WINDOWS_BITS@-setup.exe -!if "@WINDOWS_BITS@" == "64" -InstallDir $PROGRAMFILES64\Bitcoin -!else -InstallDir $PROGRAMFILES\Bitcoin -!endif -CRCCheck on -XPStyle on -BrandingText " " -ShowInstDetails show -VIProductVersion ${VERSION}.@CLIENT_VERSION_BUILD@ -VIAddVersionKey ProductName "Bitcoin Core" -VIAddVersionKey ProductVersion "${VERSION}" -VIAddVersionKey CompanyName "${COMPANY}" -VIAddVersionKey CompanyWebsite "${URL}" -VIAddVersionKey FileVersion "${VERSION}" -VIAddVersionKey FileDescription "" -VIAddVersionKey LegalCopyright "" -InstallDirRegKey HKCU "${REGKEY}" Path -ShowUninstDetails show - -# Installer sections -Section -Main SEC0000 - SetOutPath $INSTDIR - SetOverwrite on - File @abs_top_srcdir@/release/bitcoin-qt.exe - File /oname=COPYING.txt @abs_top_srcdir@/COPYING - File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt - SetOutPath $INSTDIR\daemon - File @abs_top_srcdir@/release/bitcoind.exe - File @abs_top_srcdir@/release/bitcoin-cli.exe - SetOutPath $INSTDIR\doc - File /r @abs_top_srcdir@/doc\*.* - SetOutPath $INSTDIR - WriteRegStr HKCU "${REGKEY}\Components" Main 1 - - # Remove old wxwidgets-based-bitcoin executable and locales: - Delete /REBOOTOK $INSTDIR\bitcoin.exe - RMDir /r /REBOOTOK $INSTDIR\locale -SectionEnd - -Section -post SEC0001 - WriteRegStr HKCU "${REGKEY}" Path $INSTDIR - SetOutPath $INSTDIR - WriteUninstaller $INSTDIR\uninstall.exe - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - CreateDirectory $SMPROGRAMS\$StartMenuGroup - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\bitcoin-qt.exe - CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe - !insertmacro MUI_STARTMENU_WRITE_END - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe - WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe - WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 - WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 - WriteRegStr HKCR "bitcoin" "URL Protocol" "" - WriteRegStr HKCR "bitcoin" "" "URL:Bitcoin" - WriteRegStr HKCR "bitcoin\DefaultIcon" "" $INSTDIR\bitcoin-qt.exe - WriteRegStr HKCR "bitcoin\shell\open\command" "" '"$INSTDIR\bitcoin-qt.exe" "%1"' -SectionEnd - -# Macro for selecting uninstaller sections -!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID - Push $R0 - ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" - StrCmp $R0 1 0 next${UNSECTION_ID} - !insertmacro SelectSection "${UNSECTION_ID}" - GoTo done${UNSECTION_ID} -next${UNSECTION_ID}: - !insertmacro UnselectSection "${UNSECTION_ID}" -done${UNSECTION_ID}: - Pop $R0 -!macroend - -# Uninstaller sections -Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\bitcoin-qt.exe - Delete /REBOOTOK $INSTDIR\COPYING.txt - Delete /REBOOTOK $INSTDIR\readme.txt - RMDir /r /REBOOTOK $INSTDIR\daemon - RMDir /r /REBOOTOK $INSTDIR\doc - DeleteRegValue HKCU "${REGKEY}\Components" Main -SectionEnd - -Section -un.post UNSEC0001 - DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" - Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" - Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" - Delete /REBOOTOK $INSTDIR\uninstall.exe - Delete /REBOOTOK $INSTDIR\debug.log - Delete /REBOOTOK $INSTDIR\db.log - DeleteRegValue HKCU "${REGKEY}" StartMenuGroup - DeleteRegValue HKCU "${REGKEY}" Path - DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" - DeleteRegKey /IfEmpty HKCU "${REGKEY}" - DeleteRegKey HKCR "bitcoin" - RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup - RmDir /REBOOTOK $INSTDIR - Push $R0 - StrCpy $R0 $StartMenuGroup 1 - StrCmp $R0 ">" no_smgroup -no_smgroup: - Pop $R0 -SectionEnd - -# Installer functions -Function .onInit - InitPluginsDir -!if "@WINDOWS_BITS@" == "64" - ${If} ${RunningX64} - ; disable registry redirection (enable access to 64-bit portion of registry) - SetRegView 64 - ${Else} - MessageBox MB_OK|MB_ICONSTOP "Cannot install 64-bit version on a 32-bit system." - Abort - ${EndIf} -!endif -FunctionEnd - -# Uninstaller functions -Function un.onInit - ReadRegStr $INSTDIR HKCU "${REGKEY}" Path - !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup - !insertmacro SELECT_UNSECTION Main ${UNSEC0000} -FunctionEnd diff --git a/share/ui.rc b/share/ui.rc deleted file mode 100644 index 063641cba..000000000 --- a/share/ui.rc +++ /dev/null @@ -1,15 +0,0 @@ -bitcoin ICON "pixmaps/bitcoin.ico" - -#include "wx/msw/wx.rc" - -check ICON "pixmaps/check.ico" -send16 BITMAP "pixmaps/send16.bmp" -send16mask BITMAP "pixmaps/send16mask.bmp" -send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp" -send20 BITMAP "pixmaps/send20.bmp" -send20mask BITMAP "pixmaps/send20mask.bmp" -addressbook16 BITMAP "pixmaps/addressbook16.bmp" -addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp" -addressbook20 BITMAP "pixmaps/addressbook20.bmp" -addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp" -favicon ICON "pixmaps/favicon.ico" diff --git a/src/Makefile.am b/src/Makefile.am index 00242776f..89ee8ec74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,8 @@ DIST_SUBDIRS = secp256k1 univalue cryptoconditions -AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) +AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) +AM_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) +AM_CPPFLAGS = $(HARDENED_CPPFLAGS) if EMBEDDED_LEVELDB LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include @@ -14,14 +16,16 @@ $(LIBLEVELDB): $(LIBMEMENV) $(LIBLEVELDB) $(LIBMEMENV): @echo "Building LevelDB ..." && $(MAKE) -C $(@D) $(@F) CXX="$(CXX)" \ CC="$(CC)" PLATFORM=$(TARGET_OS) AR="$(AR)" $(LEVELDB_TARGET_FLAGS) \ - OPT="$(CXXFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" + OPT="$(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -D__STDC_LIMIT_MACROS" endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include -BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include -I$(srcdir)/cryptoconditions/src/asn +BITCOIN_INCLUDES += -I$(srcdir)/cryptoconditions/include +BITCOIN_INCLUDES += -I$(srcdir)/snark +BITCOIN_INCLUDES += -I$(srcdir)/snark/libsnark BITCOIN_INCLUDES += -I$(srcdir)/univalue/include if TARGET_WINDOWS @@ -40,12 +44,25 @@ LIBBITCOIN_UTIL=libbitcoin_util.a LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a LIBSECP256K1=secp256k1/libsecp256k1.la LIBCRYPTOCONDITIONS=cryptoconditions/cryptoconditions_core.a +LIBSNARK=snark/libsnark.a LIBUNIVALUE=univalue/libunivalue.la LIBZCASH=libzcash.a -lcurl $(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F) +LIBSNARK_CXXFLAGS = -fPIC -DBINARY_OUTPUT -DNO_PT_COMPRESSION=1 -fstack-protector-all +LIBSNARK_CONFIG_FLAGS = CURVE=ALT_BN128 NO_PROCPS=1 NO_DOCS=1 STATIC=1 NO_SUPERCOP=1 FEATUREFLAGS=-DMONTGOMERY_OUTPUT NO_COPY_DEPINST=1 NO_COMPILE_LIBGTEST=1 +if HAVE_OPENMP +LIBSNARK_CONFIG_FLAGS += MULTICORE=1 +endif + +$(LIBSNARK): $(wildcard snark/src/*) + $(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" + +libsnark-tests: $(wildcard snark/src/*) + $(AM_V_at) CXXFLAGS="$(LIBSNARK_CXXFLAGS)" $(MAKE) $(AM_MAKEFLAGS) -C snark/ check DEPINST="$(LIBSNARK_DEPINST)" $(LIBSNARK_CONFIG_FLAGS) OPTFLAGS="-O2 -march=x86-64" + $(LIBUNIVALUE): $(wildcard univalue/lib/*) $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue/ @@ -68,6 +85,9 @@ endif if ENABLE_ZMQ EXTRA_LIBRARIES += libbitcoin_zmq.a endif +if ENABLE_PROTON +EXTRA_LIBRARIES += libbitcoin_proton.a +endif if BUILD_BITCOIN_LIBS lib_LTLIBRARIES = libzcashconsensus.la @@ -99,12 +119,17 @@ LIBZCASH_H = \ zcash/util.h \ zcash/Zcash.h -.PHONY: FORCE check-symbols check-security +.PHONY: FORCE collate-libsnark check-symbols check-security # bitcoin core # BITCOIN_CORE_H = \ addrman.h \ alert.h \ amount.h \ + amqp/amqpabstractnotifier.h \ + amqp/amqpconfig.h \ + amqp/amqpnotificationinterface.h \ + amqp/amqppublishnotifier.h \ + amqp/amqpsender.h \ arith_uint256.h \ asyncrpcoperation.h \ asyncrpcqueue.h \ @@ -126,11 +151,11 @@ BITCOIN_CORE_H = \ compressor.h \ consensus/consensus.h \ consensus/params.h \ + consensus/upgrades.h \ consensus/validation.h \ core_io.h \ core_memusage.h \ - eccryptoverify.h \ - ecwrapper.h \ + deprecation.h \ hash.h \ httprpc.h \ httpserver.h \ @@ -149,6 +174,8 @@ BITCOIN_CORE_H = \ net.h \ netbase.h \ noui.h \ + paymentdisclosure.h \ + paymentdisclosuredb.h \ policy/fees.h \ pow.h \ primitives/block.h \ @@ -191,7 +218,9 @@ BITCOIN_CORE_H = \ utiltime.h \ validationinterface.h \ version.h \ + wallet/asyncrpcoperation_mergetoaddress.h \ wallet/asyncrpcoperation_sendmany.h \ + wallet/asyncrpcoperation_shieldcoinbase.h \ wallet/crypter.h \ wallet/db.h \ wallet/wallet.h \ @@ -210,7 +239,8 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: zcashd -libbitcoin_server_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ sendalert.cpp \ addrman.cpp \ @@ -221,6 +251,7 @@ libbitcoin_server_a_SOURCES = \ bloom.cpp \ chain.cpp \ checkpoints.cpp \ + deprecation.cpp \ httprpc.cpp \ httpserver.cpp \ init.cpp \ @@ -232,6 +263,8 @@ libbitcoin_server_a_SOURCES = \ miner.cpp \ net.cpp \ noui.cpp \ + paymentdisclosure.cpp \ + paymentdisclosuredb.cpp \ policy/fees.cpp \ pow.cpp \ rest.cpp \ @@ -254,23 +287,40 @@ if ENABLE_ZMQ LIBBITCOIN_ZMQ=libbitcoin_zmq.a libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS) +libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_zmq_a_SOURCES = \ zmq/zmqabstractnotifier.cpp \ zmq/zmqnotificationinterface.cpp \ zmq/zmqpublishnotifier.cpp endif +if ENABLE_PROTON +LIBBITCOIN_PROTON=libbitcoin_proton.a + +libbitcoin_proton_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_proton_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +libbitcoin_proton_a_SOURCES = \ + amqp/amqpabstractnotifier.cpp \ + amqp/amqpnotificationinterface.cpp \ + amqp/amqppublishnotifier.cpp +endif # wallet: zcashd, but only linked when wallet enabled -libbitcoin_wallet_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_wallet_a_SOURCES = \ utiltest.cpp \ utiltest.h \ zcbenchmarks.cpp \ zcbenchmarks.h \ + wallet/asyncrpcoperation_mergetoaddress.cpp \ wallet/asyncrpcoperation_sendmany.cpp \ + wallet/asyncrpcoperation_shieldcoinbase.cpp \ wallet/crypter.cpp \ wallet/db.cpp \ + paymentdisclosure.cpp \ + paymentdisclosuredb.cpp \ + wallet/rpcdisclosure.cpp \ wallet/rpcdump.cpp \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ @@ -280,7 +330,8 @@ libbitcoin_wallet_a_SOURCES = \ $(LIBZCASH_H) # crypto primitives library -crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES) +crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES) +crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) crypto_libbitcoin_crypto_a_SOURCES = \ crypto/common.h \ crypto/equihash.cpp \ @@ -312,7 +363,8 @@ crypto_libbitcoin_crypto_a_SOURCES += \ endif # common: shared between zcashd and non-server tools -libbitcoin_common_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_common_a_SOURCES = \ amount.cpp \ arith_uint256.cpp \ @@ -320,10 +372,9 @@ libbitcoin_common_a_SOURCES = \ chainparams.cpp \ coins.cpp \ compressor.cpp \ + consensus/upgrades.cpp \ core_read.cpp \ core_write.cpp \ - eccryptoverify.cpp \ - ecwrapper.cpp \ hash.cpp \ key.cpp \ keystore.cpp \ @@ -345,7 +396,8 @@ libbitcoin_common_a_SOURCES = \ # util: shared between all executables. # This library *must* be included to make sure that the glibc # backward-compatibility objects and their sanity checks are linked. -libbitcoin_util_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_util_a_SOURCES = \ support/pagelocker.cpp \ chainparamsbase.cpp \ @@ -370,7 +422,8 @@ libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp endif # cli: zcash-cli -libbitcoin_cli_a_CPPFLAGS = $(BITCOIN_INCLUDES) +libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_cli_a_SOURCES = \ rpcclient.cpp \ $(BITCOIN_CORE_H) \ @@ -381,7 +434,8 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h # bitcoind binary # komodod_SOURCES = bitcoind.cpp -komodod_CPPFLAGS = $(BITCOIN_INCLUDES) +komodod_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +komodod_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) komodod_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -395,6 +449,7 @@ komodod_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH) \ + $(LIBSNARK) \ $(LIBLEVELDB) \ $(LIBMEMENV) \ $(LIBSECP256K1) \ @@ -413,16 +468,19 @@ komodod_LDADD += \ $(BDB_LIBS) \ $(SSL_LIBS) \ $(CRYPTO_LIBS) \ - $(MINIUPNPC_LIBS) \ $(EVENT_PTHREADS_LIBS) \ $(EVENT_LIBS) \ - $(LIBZCASH) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) +if ENABLE_PROTON +komodod_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) +endif + # bitcoin-cli binary # komodo_cli_SOURCES = bitcoin-cli.cpp -komodo_cli_CPPFLAGS = $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +komodo_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS) +komodo_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) komodo_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -438,13 +496,15 @@ komodo_cli_LDADD = \ $(CRYPTO_LIBS) \ $(EVENT_LIBS) \ $(LIBZCASH) \ + $(LIBSNARK) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) # # zcash-tx binary # komodo_tx_SOURCES = komodo-tx.cpp -komodo_tx_CPPFLAGS = $(BITCOIN_INCLUDES) +komodo_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +komodo_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) komodo_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS @@ -458,6 +518,7 @@ komodo_tx_LDADD = \ $(LIBBITCOIN_UTIL) \ $(LIBSECP256K1) \ $(LIBZCASH) \ + $(LIBSNARK) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) \ $(LIBCRYPTOCONDITIONS) @@ -482,12 +543,10 @@ libzcash_a_SOURCES = \ zcash/circuit/prfs.tcc \ zcash/circuit/utils.tcc -libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) -pipe -O1 -g -Wstack-protector -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) - -libzcash_a_CXXFLAGS = $(HARDENED_CXXFLAGS) -fwrapv -fno-strict-aliasing - -#libzcash_a_LDFLAGS = $(HARDENED_LDFLAGS) +libzcash_a_CPPFLAGS = -DMULTICORE -fopenmp -fPIC -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS $(HARDENED_CPPFLAGS) $(HARDENED_CXXFLAGS) $(HARDENED_LDFLAGS) -pipe $(SAN_LDFLAGS) -O1 -g -Wstack-protector $(SAN_CXXFLAGS) -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES) +libzcash_a_CXXFLAGS = $(SAN_CXXFLAGS) $(HARDENED_CXXFLAGS) -fwrapv -fno-strict-aliasing +libzcash_a_LDFLAGS = $(SAN_LDFLAGS) $(HARDENED_LDFLAGS) libzcash_a_CPPFLAGS += -DMONTGOMERY_OUTPUT # zcashconsensus library # @@ -500,8 +559,6 @@ libzcashconsensus_la_SOURCES = \ crypto/sha1.cpp \ crypto/sha256.cpp \ crypto/sha512.cpp \ - eccryptoverify.cpp \ - ecwrapper.cpp \ hash.cpp \ primitives/transaction.cpp \ pubkey.cpp \ @@ -515,11 +572,10 @@ if GLIBC_BACK_COMPAT libzcashconsensus_la_SOURCES += compat/glibc_compat.cpp endif -libzcashconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS) -libzcashconsensus_la_LIBADD = $(CRYPTO_LIBS) -libzcashconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL \ - -I$(builddir)/cryptoconditions/src/asn \ - -I$(builddir)/cryptoconditions/src +libzcashconsensus_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(RELDFLAGS) +libzcashconsensus_la_LIBADD = $(LIBSECP256K1) +libzcashconsensus_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(builddir)/obj -I$(srcdir)/secp256k1/include -DBUILD_BITCOIN_INTERNAL +libzcashconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) endif # @@ -528,11 +584,12 @@ CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno */*.gcno wal DISTCLEANFILES = obj/build.h -EXTRA_DIST = leveldb +EXTRA_DIST = leveldb snark clean-local: -$(MAKE) -C leveldb clean -$(MAKE) -C secp256k1 clean + -$(MAKE) -C snark clean rm -f leveldb/*/*.gcno leveldb/helpers/memenv/*.gcno -rm -f config.h @@ -542,18 +599,18 @@ clean-local: .mm.o: $(AM_V_CXX) $(OBJCXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o $@ $< + $(CPPFLAGS) $(AM_CXXFLAGS) $(AM_CXXFLAGS) $(PIE_FLAGS) $(CXXFLAGS) -c -o $@ $< check-symbols: $(bin_PROGRAMS) if GLIBC_BACK_COMPAT @echo "Checking glibc back compat of [$(bin_PROGRAMS)]..." - $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py < $(bin_PROGRAMS) + $(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) endif check-security: $(bin_PROGRAMS) if HARDEN @echo "Checking binary security of [$(bin_PROGRAMS)]..." - $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) + $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS) endif %.pb.cc %.pb.h: %.proto diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index 90039abb2..f70672052 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -19,7 +19,9 @@ zcash_gtest_SOURCES += \ endif zcash_gtest_SOURCES += \ gtest/test_tautology.cpp \ + gtest/test_deprecation.cpp \ gtest/test_equihash.cpp \ + gtest/test_httprpc.cpp \ gtest/test_joinsplit.cpp \ gtest/test_keystore.cpp \ gtest/test_noteencryption.cpp \ @@ -31,17 +33,21 @@ zcash_gtest_SOURCES += \ gtest/test_random.cpp \ gtest/test_rpc.cpp \ gtest/test_transaction.cpp \ + gtest/test_upgrades.cpp \ + gtest/test_validation.cpp \ gtest/test_circuit.cpp \ gtest/test_txid.cpp \ gtest/test_libzcash_utils.cpp \ gtest/test_proofs.cpp \ + gtest/test_paymentdisclosure.cpp \ gtest/test_checkblock.cpp if ENABLE_WALLET zcash_gtest_SOURCES += \ wallet/gtest/test_wallet.cpp endif -komodo_gtest_CPPFLAGS = -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC +komodo_gtest_CPPFLAGS = $(AM_CPPFLAGS) -DMULTICORE -fopenmp -DBINARY_OUTPUT -DCURVE_ALT_BN128 -DSTATIC $(BITCOIN_INCLUDES) +komodo_gtest_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) komodo_gtest_LDADD = -lgtest -lgmock $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) @@ -52,7 +58,14 @@ if ENABLE_WALLET komodo_gtest_LDADD += $(LIBBITCOIN_WALLET) endif -komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) +komodo_gtest_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS) + +if ENABLE_PROTON +komodo_gtest_LDADD += $(LIBBITCOIN_PROTON) $(PROTON_LIBS) +endif + + +komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static komodo_gtest_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static diff --git a/src/Makefile.test.include b/src/Makefile.test.include index c97ea692d..582ecb577 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -99,20 +99,25 @@ BITCOIN_TESTS += \ endif test_test_bitcoin_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) -test_test_bitcoin_CPPFLAGS = -fopenmp $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS) +test_test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) -fopenmp $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS) test_test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif -test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBZCASH) $(LIBZCASH_LIBS) +test_test_bitcoin_LDADD += $(LIBZCASH_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(LIBZCASH) $(LIBSNARK) $(LIBZCASH_LIBS) test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ test_test_bitcoin_LDADD += $(ZMQ_LIBS) endif +if ENABLE_PROTON +test_test_bitcoin_LDADD += $(PROTON_LIBS) +endif + nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) $(BITCOIN_TESTS): $(GENERATED_TEST_FILES) diff --git a/src/Makefile.zcash.include b/src/Makefile.zcash.include index 7325fdcff..177931c88 100644 --- a/src/Makefile.zcash.include +++ b/src/Makefile.zcash.include @@ -4,18 +4,24 @@ noinst_PROGRAMS += \ # tool for generating our public parameters zcash_GenerateParams_SOURCES = zcash/GenerateParams.cpp +zcash_GenerateParams_CPPFLAGS = $(AM_CPPFLAGS) +zcash_GenerateParams_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) zcash_GenerateParams_LDADD = \ $(BOOST_LIBS) \ $(LIBZCASH) \ + $(LIBSNARK) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(LIBZCASH_LIBS) # tool for profiling the creation of joinsplits zcash_CreateJoinSplit_SOURCES = zcash/CreateJoinSplit.cpp +zcash_CreateJoinSplit_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +zcash_CreateJoinSplit_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) zcash_CreateJoinSplit_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBZCASH) \ + $(LIBSNARK) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ $(BOOST_LIBS) \ diff --git a/src/addrman.h b/src/addrman.h index 2a08076b7..0483e8bdb 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -234,7 +234,7 @@ protected: //! Select an address to connect to, if newOnly is set to true, only the new table is selected from. CAddrInfo Select_(bool newOnly); - //! Wraps GetRandInt to allow tests to override RandomInt and make it determinismistic. + //! Wraps GetRandInt to allow tests to override RandomInt and make it deterministic. virtual int RandomInt(int nMax); #ifdef DEBUG_ADDRMAN diff --git a/src/amount.cpp b/src/amount.cpp index 0a394c96f..f658c4a28 100644 --- a/src/amount.cpp +++ b/src/amount.cpp @@ -7,6 +7,8 @@ #include "tinyformat.h" +const std::string CURRENCY_UNIT = "ZEC"; + CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) { if (nSize > 0) @@ -27,5 +29,5 @@ CAmount CFeeRate::GetFee(size_t nSize) const std::string CFeeRate::ToString() const { - return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); + return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT); } diff --git a/src/amount.h b/src/amount.h index d49ab0723..9b62f7663 100644 --- a/src/amount.h +++ b/src/amount.h @@ -16,6 +16,8 @@ typedef int64_t CAmount; static const CAmount COIN = 100000000; static const CAmount CENT = 1000000; +extern const std::string CURRENCY_UNIT; + /** No amount larger than this (in satoshi) is valid. * * Note that this constant is *not* the total money supply, which in Bitcoin diff --git a/src/amqp/amqpabstractnotifier.cpp b/src/amqp/amqpabstractnotifier.cpp new file mode 100644 index 000000000..57686ef1d --- /dev/null +++ b/src/amqp/amqpabstractnotifier.cpp @@ -0,0 +1,21 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amqpabstractnotifier.h" +#include "util.h" + + +AMQPAbstractNotifier::~AMQPAbstractNotifier() +{ +} + +bool AMQPAbstractNotifier::NotifyBlock(const CBlockIndex * /*CBlockIndex*/) +{ + return true; +} + +bool AMQPAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/) +{ + return true; +} diff --git a/src/amqp/amqpabstractnotifier.h b/src/amqp/amqpabstractnotifier.h new file mode 100644 index 000000000..c993a2b3e --- /dev/null +++ b/src/amqp/amqpabstractnotifier.h @@ -0,0 +1,43 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H +#define ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H + +#include "amqpconfig.h" + +class CBlockIndex; +class AMQPAbstractNotifier; + +typedef AMQPAbstractNotifier* (*AMQPNotifierFactory)(); + +class AMQPAbstractNotifier +{ +public: + AMQPAbstractNotifier() { } + virtual ~AMQPAbstractNotifier(); + + template + static AMQPAbstractNotifier* Create() + { + return new T(); + } + + std::string GetType() const { return type; } + void SetType(const std::string &t) { type = t; } + std::string GetAddress() const { return address; } + void SetAddress(const std::string &a) { address = a; } + + virtual bool Initialize() = 0; + virtual void Shutdown() = 0; + + virtual bool NotifyBlock(const CBlockIndex *pindex); + virtual bool NotifyTransaction(const CTransaction &transaction); + +protected: + std::string type; + std::string address; +}; + +#endif // ZCASH_AMQP_AMQPABSTRACTNOTIFIER_H diff --git a/src/amqp/amqpconfig.h b/src/amqp/amqpconfig.h new file mode 100644 index 000000000..dcc5f7709 --- /dev/null +++ b/src/amqp/amqpconfig.h @@ -0,0 +1,33 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_AMQP_AMQPCONFIG_H +#define ZCASH_AMQP_AMQPCONFIG_H + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include +#include + +#if ENABLE_PROTON +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "primitives/block.h" +#include "primitives/transaction.h" + +#endif // ZCASH_AMQP_AMQPCONFIG_H diff --git a/src/amqp/amqpnotificationinterface.cpp b/src/amqp/amqpnotificationinterface.cpp new file mode 100644 index 000000000..66f5398ca --- /dev/null +++ b/src/amqp/amqpnotificationinterface.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amqpnotificationinterface.h" +#include "amqppublishnotifier.h" + +#include "version.h" +#include "main.h" +#include "streams.h" +#include "util.h" + +// AMQP 1.0 Support +// +// The boost::signals2 signals and slot system is thread safe, so CValidationInterface listeners +// can be invoked from any thread. +// +// Currently signals are fired from main.cpp so the callbacks should be invoked on the same thread. +// It should be safe to share objects responsible for sending, as they should not be run concurrently +// across different threads. +// +// Developers should be mindful of where notifications are fired to avoid potential race conditions. +// For example, different signals targeting the same address could be fired from different threads +// in different parts of the system around the same time. +// +// Like the ZMQ notification interface, if a notifier fails to send a message, the notifier is shut down. +// + +AMQPNotificationInterface::AMQPNotificationInterface() +{ +} + +AMQPNotificationInterface::~AMQPNotificationInterface() +{ + Shutdown(); + + for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { + delete *i; + } +} + +AMQPNotificationInterface* AMQPNotificationInterface::CreateWithArguments(const std::map &args) +{ + AMQPNotificationInterface* notificationInterface = nullptr; + std::map factories; + std::list notifiers; + + factories["pubhashblock"] = AMQPAbstractNotifier::Create; + factories["pubhashtx"] = AMQPAbstractNotifier::Create; + factories["pubrawblock"] = AMQPAbstractNotifier::Create; + factories["pubrawtx"] = AMQPAbstractNotifier::Create; + + for (std::map::const_iterator i=factories.begin(); i!=factories.end(); ++i) { + std::map::const_iterator j = args.find("-amqp" + i->first); + if (j!=args.end()) { + AMQPNotifierFactory factory = i->second; + std::string address = j->second; + AMQPAbstractNotifier *notifier = factory(); + notifier->SetType(i->first); + notifier->SetAddress(address); + notifiers.push_back(notifier); + } + } + + if (!notifiers.empty()) { + notificationInterface = new AMQPNotificationInterface(); + notificationInterface->notifiers = notifiers; + + if (!notificationInterface->Initialize()) { + delete notificationInterface; + notificationInterface = nullptr; + } + } + + return notificationInterface; +} + +// Called at startup to conditionally set up +bool AMQPNotificationInterface::Initialize() +{ + LogPrint("amqp", "amqp: Initialize notification interface\n"); + + std::list::iterator i = notifiers.begin(); + for (; i != notifiers.end(); ++i) { + AMQPAbstractNotifier *notifier = *i; + if (notifier->Initialize()) { + LogPrint("amqp", "amqp: Notifier %s ready (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + } else { + LogPrint("amqp", "amqp: Notifier %s failed (address = %s)\n", notifier->GetType(), notifier->GetAddress()); + break; + } + } + + if (i != notifiers.end()) { + return false; + } + + return true; +} + +// Called during shutdown sequence +void AMQPNotificationInterface::Shutdown() +{ + LogPrint("amqp", "amqp: Shutdown notification interface\n"); + + for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ++i) { + AMQPAbstractNotifier *notifier = *i; + notifier->Shutdown(); + } +} + +void AMQPNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex) +{ + for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ) { + AMQPAbstractNotifier *notifier = *i; + if (notifier->NotifyBlock(pindex)) { + i++; + } else { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} + +void AMQPNotificationInterface::SyncTransaction(const CTransaction &tx, const CBlock *pblock) +{ + for (std::list::iterator i = notifiers.begin(); i != notifiers.end(); ) { + AMQPAbstractNotifier *notifier = *i; + if (notifier->NotifyTransaction(tx)) { + i++; + } else { + notifier->Shutdown(); + i = notifiers.erase(i); + } + } +} diff --git a/src/amqp/amqpnotificationinterface.h b/src/amqp/amqpnotificationinterface.h new file mode 100644 index 000000000..0c07ce235 --- /dev/null +++ b/src/amqp/amqpnotificationinterface.h @@ -0,0 +1,36 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H +#define ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H + +#include "validationinterface.h" +#include +#include + +class CBlockIndex; +class AMQPAbstractNotifier; + +class AMQPNotificationInterface : public CValidationInterface +{ +public: + virtual ~AMQPNotificationInterface(); + + static AMQPNotificationInterface* CreateWithArguments(const std::map &args); + +protected: + bool Initialize(); + void Shutdown(); + + // CValidationInterface + void SyncTransaction(const CTransaction &tx, const CBlock *pblock); + void UpdatedBlockTip(const CBlockIndex *pindex); + +private: + AMQPNotificationInterface(); + + std::list notifiers; +}; + +#endif // ZCASH_AMQP_AMQPNOTIFICATIONINTERFACE_H diff --git a/src/amqp/amqppublishnotifier.cpp b/src/amqp/amqppublishnotifier.cpp new file mode 100644 index 000000000..589eb151f --- /dev/null +++ b/src/amqp/amqppublishnotifier.cpp @@ -0,0 +1,177 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "amqppublishnotifier.h" +#include "main.h" +#include "util.h" + +#include "amqpsender.h" + +#include +#include + +static std::multimap mapPublishNotifiers; + +static const char *MSG_HASHBLOCK = "hashblock"; +static const char *MSG_HASHTX = "hashtx"; +static const char *MSG_RAWBLOCK = "rawblock"; +static const char *MSG_RAWTX = "rawtx"; + +// Invoke this method from a new thread to run the proton container event loop. +void AMQPAbstractPublishNotifier::SpawnProtonContainer() +{ + try { + proton::default_container(*handler_).run(); + } + catch (const proton::error_condition &e) { + LogPrint("amqp", "amqp: container error: %s\n", e.what()); + } + catch (const std::runtime_error &e) { + LogPrint("amqp", "amqp: runtime error: %s\n", e.what()); + } + catch (const std::exception &e) { + LogPrint("amqp", "amqp: exception: %s\n", e.what()); + } + catch (...) { + LogPrint("amqp", "amqp: unknown error\n"); + } + handler_->terminate(); +} + +bool AMQPAbstractPublishNotifier::Initialize() +{ + std::multimap::iterator i = mapPublishNotifiers.find(address); + + if (i == mapPublishNotifiers.end()) { + try { + handler_ = std::make_shared(address); + thread_ = std::make_shared(&AMQPAbstractPublishNotifier::SpawnProtonContainer, this); + } + catch (std::exception &e) { + LogPrint("amqp", "amqp: initialization error: %s\n", e.what()); + return false; + } + mapPublishNotifiers.insert(std::make_pair(address, this)); + } else { + // copy the shared ptrs to the message handler and the thread where the proton container is running + handler_ = i->second->handler_; + thread_ = i->second->thread_; + mapPublishNotifiers.insert(std::make_pair(address, this)); + } + + return true; +} + + +void AMQPAbstractPublishNotifier::Shutdown() +{ + LogPrint("amqp", "amqp: Shutdown notifier %s at %s\n", GetType(), GetAddress()); + + int count = mapPublishNotifiers.count(address); + + // remove this notifier from the list of publishers using this address + typedef std::multimap::iterator iterator; + std::pair iterpair = mapPublishNotifiers.equal_range(address); + + for (iterator it = iterpair.first; it != iterpair.second; ++it) { + if (it->second == this) { + mapPublishNotifiers.erase(it); + break; + } + } + + // terminate the connection if this is the last publisher using this address + if (count == 1) { + handler_->terminate(); + if (thread_.get() != nullptr) { + if (thread_->joinable()) { + thread_->join(); + } + } + } +} + + +bool AMQPAbstractPublishNotifier::SendMessage(const char *command, const void* data, size_t size) +{ + try { + proton::binary content; + const char *p = (const char *)data; + content.assign(p, p + size); + + proton::message message(content); + message.subject(std::string(command)); + proton::message::property_map & props = message.properties(); + props.put("x-opt-sequence-number", sequence_); + handler_->publish(message); + + } catch (proton::error_condition &e) { + LogPrint("amqp", "amqp: error : %s\n", e.what()); + return false; + } + catch (const std::runtime_error &e) { + LogPrint("amqp", "amqp: runtime error: %s\n", e.what()); + return false; + } + catch (const std::exception &e) { + LogPrint("amqp", "amqp: exception: %s\n", e.what()); + return false; + } + catch (...) { + LogPrint("amqp", "amqp: unknown error\n"); + return false; + } + + sequence_++; + + return true; +} + +bool AMQPPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + uint256 hash = pindex->GetBlockHash(); + LogPrint("amqp", "amqp: Publish hashblock %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + return SendMessage(MSG_HASHBLOCK, data, 32); +} + +bool AMQPPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("amqp", "amqp: Publish hashtx %s\n", hash.GetHex()); + char data[32]; + for (unsigned int i = 0; i < 32; i++) + data[31 - i] = hash.begin()[i]; + return SendMessage(MSG_HASHTX, data, 32); +} + +bool AMQPPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) +{ + LogPrint("amqp", "amqp: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + { + LOCK(cs_main); + CBlock block; + if(!ReadBlockFromDisk(block, pindex)) { + LogPrint("amqp", "amqp: Can't read block from disk"); + return false; + } + + ss << block; + } + + return SendMessage(MSG_RAWBLOCK, &(*ss.begin()), ss.size()); +} + +bool AMQPPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &transaction) +{ + uint256 hash = transaction.GetHash(); + LogPrint("amqp", "amqp: Publish rawtx %s\n", hash.GetHex()); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << transaction; + return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); +} diff --git a/src/amqp/amqppublishnotifier.h b/src/amqp/amqppublishnotifier.h new file mode 100644 index 000000000..08b3aba08 --- /dev/null +++ b/src/amqp/amqppublishnotifier.h @@ -0,0 +1,56 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H +#define ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H + +#include "amqpabstractnotifier.h" +#include "amqpconfig.h" +#include "amqpsender.h" + +#include +#include + +class CBlockIndex; + +class AMQPAbstractPublishNotifier : public AMQPAbstractNotifier +{ +private: + uint64_t sequence_; // memory only, per notifier instance: upcounting message sequence number + + std::shared_ptr thread_; // proton container thread, may be shared between notifiers + std::shared_ptr handler_; // proton container message handler, may be shared between notifiers + +public: + bool SendMessage(const char *command, const void* data, size_t size); + bool Initialize(); + void Shutdown(); + void SpawnProtonContainer(); +}; + +class AMQPPublishHashBlockNotifier : public AMQPAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class AMQPPublishHashTransactionNotifier : public AMQPAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +class AMQPPublishRawBlockNotifier : public AMQPAbstractPublishNotifier +{ +public: + bool NotifyBlock(const CBlockIndex *pindex); +}; + +class AMQPPublishRawTransactionNotifier : public AMQPAbstractPublishNotifier +{ +public: + bool NotifyTransaction(const CTransaction &transaction); +}; + +#endif // ZCASH_AMQP_AMQPPUBLISHNOTIFIER_H diff --git a/src/amqp/amqpsender.h b/src/amqp/amqpsender.h new file mode 100644 index 000000000..7fa85d89c --- /dev/null +++ b/src/amqp/amqpsender.h @@ -0,0 +1,115 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_AMQP_AMQPSENDER_H +#define ZCASH_AMQP_AMQPSENDER_H + +#include "amqpconfig.h" + +#include +#include +#include +#include + +class AMQPSender : public proton::messaging_handler { + private: + std::deque messages_; + proton::url url_; + proton::connection conn_; + proton::sender sender_; + std::mutex lock_; + std::atomic terminated_ = {false}; + + public: + + AMQPSender(const std::string& url) : url_(url) {} + + // Callback to initialize the container when run() is invoked + void on_container_start(proton::container& c) override { + proton::duration t(10000); // milliseconds + proton::connection_options opts = proton::connection_options().idle_timeout(t); + conn_ = c.connect(url_, opts); + sender_ = conn_.open_sender(url_.path()); + } + + // Remote end signals when the local end can send (i.e. has credit) + void on_sendable(proton::sender &s) override { + dispatch(); + } + + // Publish message by adding to queue and trying to dispatch it + void publish(const proton::message &m) { + add_message(m); + dispatch(); + } + + // Add message to queue + void add_message(const proton::message &m) { + std::lock_guard guard(lock_); + messages_.push_back(m); + } + + // Send messages in queue + void dispatch() { + std::lock_guard guard(lock_); + + if (isTerminated()) { + throw std::runtime_error("amqp connection was terminated"); + } + + if (!conn_.active()) { + throw std::runtime_error("amqp connection is not active"); + } + + while (messages_.size() > 0) { + if (sender_.credit()) { + const proton::message& m = messages_.front(); + sender_.send(m); + messages_.pop_front(); + } else { + break; + } + } + } + + // Close connection to remote end. Container event-loop, by default, will auto-stop. + void terminate() { + std::lock_guard guard(lock_); + conn_.close(); + terminated_.store(true); + } + + bool isTerminated() const { + return terminated_.load(); + } + + void on_transport_error(proton::transport &t) override { + t.connection().close(); + throw t.error(); + } + + void on_connection_error(proton::connection &c) override { + c.close(); + throw c.error(); + } + + void on_session_error(proton::session &s) override { + s.connection().close(); + throw s.error(); + } + + void on_receiver_error(proton::receiver &r) override { + r.connection().close(); + throw r.error(); + } + + void on_sender_error(proton::sender &s) override { + s.connection().close(); + throw s.error(); + } + +}; + + +#endif //ZCASH_AMQP_AMQPSENDER_H diff --git a/src/assetchains.old b/src/assetchains.old index 94c0c8e6e..9839c56e6 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -28,7 +28,7 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=78.47.196.146 & -./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000-addnode=174.138.107.226 & +./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -addnode=174.138.107.226 & #sleep $delay #./komodod -pubkey=$pubkey -ac_name=USD -addnode=78.47.196.146 $1 & diff --git a/src/asyncrpcoperation.h b/src/asyncrpcoperation.h index 5475102a5..2b821e256 100644 --- a/src/asyncrpcoperation.h +++ b/src/asyncrpcoperation.h @@ -24,7 +24,7 @@ using namespace std; * * To subclass AsyncRPCOperation, implement the main() method. * Update the operation status as work is underway and completes. - * If main() can be interrupted, inmplement the cancel() method. + * If main() can be interrupted, implement the cancel() method. */ typedef std::string AsyncRPCOperationId; diff --git a/src/base58.cpp b/src/base58.cpp index d09544682..c9c64bc58 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -323,67 +323,60 @@ bool CBitcoinSecret::SetString(const std::string& strSecret) return SetString(strSecret.c_str()); } -bool CZCPaymentAddress::Set(const libzcash::PaymentAddress& addr) +template +bool CZCEncoding::Set(const DATA_TYPE& addr) { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << addr; std::vector addrSerialized(ss.begin(), ss.end()); - assert(addrSerialized.size() == libzcash::SerializedPaymentAddressSize); - SetData(Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS), &addrSerialized[0], libzcash::SerializedPaymentAddressSize); + assert(addrSerialized.size() == SER_SIZE); + SetData(Params().Base58Prefix(PREFIX), &addrSerialized[0], SER_SIZE); return true; } -libzcash::PaymentAddress CZCPaymentAddress::Get() const +template +DATA_TYPE CZCEncoding::Get() const { - if (vchData.size() != libzcash::SerializedPaymentAddressSize) { + if (vchData.size() != SER_SIZE) { throw std::runtime_error( - "payment address is invalid" + PrependName(" is invalid") ); } - if (vchVersion != Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS)) { + if (vchVersion != Params().Base58Prefix(PREFIX)) { throw std::runtime_error( - "payment address is for wrong network type" + PrependName(" is for wrong network type") ); } std::vector serialized(vchData.begin(), vchData.end()); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::PaymentAddress ret; + DATA_TYPE ret; ss >> ret; return ret; } -bool CZCSpendingKey::Set(const libzcash::SpendingKey& addr) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << addr; - std::vector addrSerialized(ss.begin(), ss.end()); - assert(addrSerialized.size() == libzcash::SerializedSpendingKeySize); - SetData(Params().Base58Prefix(CChainParams::ZCSPENDING_KEY), &addrSerialized[0], libzcash::SerializedSpendingKeySize); - return true; -} +// Explicit instantiations for libzcash::PaymentAddress +template bool CZCEncoding::Set(const libzcash::PaymentAddress& addr); +template libzcash::PaymentAddress CZCEncoding::Get() const; -libzcash::SpendingKey CZCSpendingKey::Get() const -{ - if (vchData.size() != libzcash::SerializedSpendingKeySize) { - throw std::runtime_error( - "spending key is invalid" - ); - } - - if (vchVersion != Params().Base58Prefix(CChainParams::ZCSPENDING_KEY)) { - throw std::runtime_error( - "spending key is for wrong network type" - ); - } - - std::vector serialized(vchData.begin(), vchData.end()); - - CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); - libzcash::SpendingKey ret; - ss >> ret; - return ret; -} +// Explicit instantiations for libzcash::ViewingKey +template bool CZCEncoding::Set(const libzcash::ViewingKey& vk); +template libzcash::ViewingKey CZCEncoding::Get() const; +// Explicit instantiations for libzcash::SpendingKey +template bool CZCEncoding::Set(const libzcash::SpendingKey& sk); +template libzcash::SpendingKey CZCEncoding::Get() const; diff --git a/src/base58.h b/src/base58.h index 88efadbd6..24e7abfc8 100644 --- a/src/base58.h +++ b/src/base58.h @@ -96,26 +96,48 @@ public: bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } }; -class CZCPaymentAddress : public CBase58Data { +template +class CZCEncoding : public CBase58Data { +protected: + virtual std::string PrependName(const std::string& s) const = 0; + +public: + bool Set(const DATA_TYPE& addr); + + DATA_TYPE Get() const; +}; + +class CZCPaymentAddress : public CZCEncoding { +protected: + std::string PrependName(const std::string& s) const { return "payment address" + s; } + public: - bool Set(const libzcash::PaymentAddress& addr); CZCPaymentAddress() {} CZCPaymentAddress(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } CZCPaymentAddress(const libzcash::PaymentAddress& addr) { Set(addr); } - - libzcash::PaymentAddress Get() const; }; -class CZCSpendingKey : public CBase58Data { +class CZCViewingKey : public CZCEncoding { +protected: + std::string PrependName(const std::string& s) const { return "viewing key" + s; } + +public: + CZCViewingKey() {} + + CZCViewingKey(const std::string& strViewingKey) { SetString(strViewingKey.c_str(), 3); } + CZCViewingKey(const libzcash::ViewingKey& vk) { Set(vk); } +}; + +class CZCSpendingKey : public CZCEncoding { +protected: + std::string PrependName(const std::string& s) const { return "spending key" + s; } + public: - bool Set(const libzcash::SpendingKey& addr); CZCSpendingKey() {} CZCSpendingKey(const std::string& strAddress) { SetString(strAddress.c_str(), 2); } CZCSpendingKey(const libzcash::SpendingKey& addr) { Set(addr); } - - libzcash::SpendingKey Get() const; }; /** base58-encoded Bitcoin addresses. @@ -172,7 +194,7 @@ public: K GetKey() { K ret; if (vchData.size() == Size) { - //if base58 encouded data not holds a ext key, return a !IsValid() key + //if base58 encoded data not holds a ext key, return a !IsValid() key ret.Decode(&vchData[0]); } return ret; diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 253c49366..178f0baed 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -76,11 +76,16 @@ public: #include "komodo_cJSON.c" #include "komodo_notary.h" -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout) +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { } +uint32_t komodo_heightstamp(int32_t height) +{ + return(0); +} + static bool AppInitRPC(int argc, char* argv[]) { // diff --git a/src/chain.cpp b/src/chain.cpp index 9cd13d997..7bb72d5d3 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -81,7 +81,8 @@ CBlockIndex* CBlockIndex::GetAncestor(int height) CBlockIndex* pindexWalk = this; int heightWalk = nHeight; - while (heightWalk > height) { + while ( heightWalk > height && pindexWalk != 0 ) + { int heightSkip = GetSkipHeight(heightWalk); int heightSkipPrev = GetSkipHeight(heightWalk - 1); if (pindexWalk->pskip != NULL && diff --git a/src/chain.h b/src/chain.h index b7e8a9176..d3c46f9d6 100644 --- a/src/chain.h +++ b/src/chain.h @@ -16,6 +16,8 @@ #include +static const int SPROUT_VALUE_VERSION = 1001400; + struct CDiskBlockPos { int nFile; @@ -92,8 +94,14 @@ enum BlockStatus: uint32_t { BLOCK_FAILED_VALID = 32, //! stage after last reached validness failed BLOCK_FAILED_CHILD = 64, //! descends from failed block BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, + + BLOCK_ACTIVATES_UPGRADE = 128, //! block activates a network upgrade }; +//! Short-hand for the highest consensus validity we implement. +//! Blocks with this validity are assumed to satisfy all consensus rules. +static const BlockStatus BLOCK_VALID_CONSENSUS = BLOCK_VALID_SCRIPTS; + /** The block chain is a tree shaped structure starting with the * genesis block at the root, with each block potentially having multiple * candidates to be the next block. A blockindex may have multiple pprev pointing @@ -138,12 +146,26 @@ public: //! Verification status of this block. See enum BlockStatus unsigned int nStatus; + //! Branch ID corresponding to the consensus rules used to validate this block. + //! Only cached if block validity is BLOCK_VALID_CONSENSUS. + //! Persisted at each activation height, memory-only for intervening blocks. + boost::optional nCachedBranchId; + //! The anchor for the tree state up to the start of this block uint256 hashAnchor; //! (memory only) The anchor for the tree state up to the end of this block uint256 hashAnchorEnd; + //! Change in value held by the Sprout circuit over this block. + //! Will be boost::none for older blocks on old nodes until a reindex has taken place. + boost::optional nSproutValue; + + //! (memory only) Total value held by the Sprout circuit up to and including this block. + //! Will be boost::none for on old nodes until a reindex has taken place. + //! Will be boost::none if nChainTx is zero. + boost::optional nChainSproutValue; + //! block header int nVersion; uint256 hashMerkleRoot; @@ -155,7 +177,8 @@ public: //! (memory only) Sequential id assigned to distinguish order in which blocks are received. uint32_t nSequenceId; - + int8_t notaryid; uint8_t pubkey33[33]; + void SetNull() { phashBlock = NULL; @@ -169,9 +192,12 @@ public: nTx = 0; nChainTx = 0; nStatus = 0; + nCachedBranchId = boost::none; hashAnchor = uint256(); hashAnchorEnd = uint256(); nSequenceId = 0; + nSproutValue = boost::none; + nChainSproutValue = boost::none; nVersion = 0; hashMerkleRoot = uint256(); @@ -328,6 +354,18 @@ public: READWRITE(VARINT(nDataPos)); if (nStatus & BLOCK_HAVE_UNDO) READWRITE(VARINT(nUndoPos)); + if (nStatus & BLOCK_ACTIVATES_UPGRADE) { + if (ser_action.ForRead()) { + uint32_t branchId; + READWRITE(branchId); + nCachedBranchId = branchId; + } else { + // nCachedBranchId must always be set if BLOCK_ACTIVATES_UPGRADE is set. + assert(nCachedBranchId); + uint32_t branchId = *nCachedBranchId; + READWRITE(branchId); + } + } READWRITE(hashAnchor); // block header @@ -339,6 +377,12 @@ public: READWRITE(nBits); READWRITE(nNonce); READWRITE(nSolution); + + // Only read/write nSproutValue if the client version used to create + // this index was storing them. + if ((nType & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) { + READWRITE(nSproutValue); + } } uint256 GetBlockHash() const diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 0f3861040..49c4a2244 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -15,10 +15,56 @@ #include "base58.h" -using namespace std; - #include "chainparamsseeds.h" +static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, const uint256& nNonce, const std::vector& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +{ + // To create a genesis block for a new chain which is Overwintered: + // txNew.nVersion = 3 + // txNew.fOverwintered = true + // txNew.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID + // txNew.nExpiryHeight = + CMutableTransaction txNew; + txNew.nVersion = 1; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 520617983 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = genesisReward; + txNew.vout[0].scriptPubKey = genesisOutputScript; + + CBlock genesis; + genesis.nTime = nTime; + genesis.nBits = nBits; + genesis.nNonce = nNonce; + genesis.nSolution = nSolution; + genesis.nVersion = nVersion; + genesis.vtx.push_back(txNew); + genesis.hashPrevBlock.SetNull(); + genesis.hashMerkleRoot = genesis.BuildMerkleTree(); + return genesis; +} + +/** + * Build the genesis block. Note that the output of its generation + * transaction cannot be spent since it did not originally exist in the + * database (and is in any case of zero value). + * + * >>> from pyblake2 import blake2s + * >>> 'Zcash' + blake2s(b'The Economist 2016-10-29 Known unknown: Another crypto-currency is born. BTC#436254 0000000000000000044f321997f336d2908cf8c8d6893e88dbf067e2d949487d ETH#2521903 483039a6b6bd8bd05f0584f9a078d075e454925eb71c1f13eaff59b405a721bb DJIA close on 27 Oct 2016: 18,169.68').hexdigest() + * + * CBlock(hash=00040fe8, ver=4, hashPrevBlock=00000000000000, hashMerkleRoot=c4eaa5, nTime=1477641360, nBits=1f07ffff, nNonce=4695, vtx=1) + * CTransaction(hash=c4eaa5, ver=1, vin.size=1, vout.size=1, nLockTime=0) + * CTxIn(COutPoint(000000, -1), coinbase 04ffff071f0104455a6361736830623963346565663862376363343137656535303031653335303039383462366665613335363833613763616331343161303433633432303634383335643334) + * CTxOut(nValue=0.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + * vMerkleTree: c4eaa5 + */ +static CBlock CreateGenesisBlock(uint32_t nTime, const uint256& nNonce, const std::vector& nSolution, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) +{ + const char* pszTimestamp = "Zcash0b9c4eef8b7cc417ee5001e3500984b6fea35683a7cac141a043c42064835d34"; + const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; + return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nSolution, nBits, nVersion, genesisReward); +} + /** * Main network */ @@ -59,6 +105,16 @@ public: consensus.nPowMaxAdjustUp = 16; // 16% adjustment up consensus.nPowTargetSpacing = 1 * 60; consensus.fPowAllowMinDifficultyBlocks = true; //false; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170004; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -77,11 +133,12 @@ public: BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K)); nEquihashN = N; nEquihashK = K; + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; CMutableTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; genesis.vtx.push_back(txNew); @@ -93,6 +150,13 @@ public: genesis.nNonce = uint256S("0x000000000000000000000000000000000000000000000000000000000000000b"); genesis.nSolution = ParseHex("000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2"); + + /*genesis = CreateGenesisBlock( + 1477641360, + uint256S("0x0000000000000000000000000000000000000000000000000000000000001257"), + ParseHex("000a889f00854b8665cd555f4656f68179d31ccadc1b1f7fb0952726313b16941da348284d67add4686121d4e3d930160c1348d8191c25f12b267a6a9c131b5031cbf8af1f79c9d513076a216ec87ed045fa966e01214ed83ca02dc1797270a454720d3206ac7d931a0a680c5c5e099057592570ca9bdf6058343958b31901fce1a15a4f38fd347750912e14004c73dfe588b903b6c03166582eeaf30529b14072a7b3079e3a684601b9b3024054201f7440b0ee9eb1a7120ff43f713735494aa27b1f8bab60d7f398bca14f6abb2adbf29b04099121438a7974b078a11635b594e9170f1086140b4173822dd697894483e1c6b4e8b8dcd5cb12ca4903bc61e108871d4d915a9093c18ac9b02b6716ce1013ca2c1174e319c1a570215bc9ab5f7564765f7be20524dc3fdf8aa356fd94d445e05ab165ad8bb4a0db096c097618c81098f91443c719416d39837af6de85015dca0de89462b1d8386758b2cf8a99e00953b308032ae44c35e05eb71842922eb69797f68813b59caf266cb6c213569ae3280505421a7e3a0a37fdf8e2ea354fc5422816655394a9454bac542a9298f176e211020d63dee6852c40de02267e2fc9d5e1ff2ad9309506f02a1a71a0501b16d0d36f70cdfd8de78116c0c506ee0b8ddfdeb561acadf31746b5a9dd32c21930884397fb1682164cb565cc14e089d66635a32618f7eb05fe05082b8a3fae620571660a6b89886eac53dec109d7cbb6930ca698a168f301a950be152da1be2b9e07516995e20baceebecb5579d7cdbc16d09f3a50cb3c7dffe33f26686d4ff3f8946ee6475e98cf7b3cf9062b6966e838f865ff3de5fb064a37a21da7bb8dfd2501a29e184f207caaba364f36f2329a77515dcb710e29ffbf73e2bbd773fab1f9a6b005567affff605c132e4e4dd69f36bd201005458cfbd2c658701eb2a700251cefd886b1e674ae816d3f719bac64be649c172ba27a4fd55947d95d53ba4cbc73de97b8af5ed4840b659370c556e7376457f51e5ebb66018849923db82c1c9a819f173cccdb8f3324b239609a300018d0fb094adf5bd7cbb3834c69e6d0b3798065c525b20f040e965e1a161af78ff7561cd874f5f1b75aa0bc77f720589e1b810f831eac5073e6dd46d00a2793f70f7427f0f798f2f53a67e615e65d356e66fe40609a958a05edb4c175bcc383ea0530e67ddbe479a898943c6e3074c6fcc252d6014de3a3d292b03f0d88d312fe221be7be7e3c59d07fa0f2f4029e364f1f355c5d01fa53770d0cd76d82bf7e60f6903bc1beb772e6fde4a70be51d9c7e03c8d6d8dfb361a234ba47c470fe630820bbd920715621b9fbedb49fcee165ead0875e6c2b1af16f50b5d6140cc981122fcbcf7c5a4e3772b3661b628e08380abc545957e59f634705b1bbde2f0b4e055a5ec5676d859be77e20962b645e051a880fddb0180b4555789e1f9344a436a84dc5579e2553f1e5fb0a599c137be36cabbed0319831fea3fddf94ddc7971e4bcf02cdc93294a9aab3e3b13e3b058235b4f4ec06ba4ceaa49d675b4ba80716f3bc6976b1fbf9c8bf1f3e3a4dc1cd83ef9cf816667fb94f1e923ff63fef072e6a19321e4812f96cb0ffa864da50ad74deb76917a336f31dce03ed5f0303aad5e6a83634f9fcc371096f8288b8f02ddded5ff1bb9d49331e4a84dbe1543164438fde9ad71dab024779dcdde0b6602b5ae0a6265c14b94edd83b37403f4b78fcd2ed555b596402c28ee81d87a909c4e8722b30c71ecdd861b05f61f8b1231795c76adba2fdefa451b283a5d527955b9f3de1b9828e7b2e74123dd47062ddcc09b05e7fa13cb2212a6fdbc65d7e852cec463ec6fd929f5b8483cf3052113b13dac91b69f49d1b7d1aec01c4a68e41ce157"), + 0x1f07ffff, 4, 0);*/ + consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); @@ -119,21 +183,6 @@ public: fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; -/* - checkpointData = (Checkpoints::CCheckpointData) - { - boost::assign::map_list_of - (0, consensus.hashGenesisBlock), - //(2500, uint256S("0x0e6a3d5a46eba97c4e7618d66a39f115729e1176433c98481124c2bf733aa54e")) - //(15000, uint256S("0x00f0bd236790e903321a2d22f85bd6bf8a505f6ef4eddb20458a65d37e14d142")), - //(100000, uint256S("0x0f02eb1f3a4b89df9909fec81a4bd7d023e32e24e1f5262d9fc2cc36a715be6f")), - 1481120910, // * UNIX timestamp of last checkpoint block - 110415, // * total number of transactions between genesis and last checkpoint - // (the tx=... number in the SetBestChain debug.log lines) - 2777 // * estimated number of transactions per day after checkpoint - // total number of tx / (checkpoint block height / (24 * 24)) - }; -*/ // LogPrintf(">>>>>>>> ac_name = %u\n",GetArg("-ac_name","").c_str()); @@ -152,14 +201,14 @@ public: }; static CMainParams mainParams; -void CChainParams::SetCheckpointData(Checkpoints::CCheckpointData checkpointData) +void CChainParams::SetCheckpointData(CChainParams::CCheckpointData checkpointData) { CChainParams::checkpointData = checkpointData; } void *chainparams_commandline(void *ptr) { - Checkpoints::CCheckpointData checkpointData; + CChainParams::CCheckpointData checkpointData; while ( ASSETCHAINS_PORT == 0 ) { #ifdef _WIN32 @@ -354,25 +403,49 @@ void *chainparams_commandline(void *ptr) /** * Testnet (v3) */ -class CTestNetParams : public CMainParams { +class CTestNetParams : public CChainParams { public: CTestNetParams() { strNetworkID = "test"; strCurrencyUnits = "TAZ"; + consensus.fCoinbaseMustBeProtected = true; + consensus.nSubsidySlowStartInterval = 20000; + consensus.nSubsidyHalvingInterval = 840000; consensus.nMajorityEnforceBlockUpgrade = 51; consensus.nMajorityRejectBlockOutdated = 75; consensus.nMajorityWindow = 400; consensus.powLimit = uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + consensus.nPowAveragingWindow = 17; assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); + + vAlertPubKey = ParseHex("00"); + nDefaultPort = 17770; + nMinerThreads = 0; + consensus.nPowMaxAdjustDown = 32; // 32% adjustment down + consensus.nPowMaxAdjustUp = 16; // 16% adjustment up + consensus.nPowTargetSpacing = 2.5 * 60; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 207500; + consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0x5A; pchMessageStart[1] = 0x1F; pchMessageStart[2] = 0x7E; pchMessageStart[3] = 0x62; - vAlertPubKey = ParseHex("00"); - nDefaultPort = 17770; - nMinerThreads = 0; + vAlertPubKey = ParseHex("020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9"); + nMaxTipAge = 24 * 60 * 60; + nPruneAfterHeight = 1000; + const size_t N = 200, K = 9; + BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K)); + nEquihashN = N; + nEquihashK = K; //! Modify the testnet genesis block so the timestamp is valid for a later start. genesis.nTime = 1296688602; @@ -403,7 +476,7 @@ public: fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; - checkpointData = (Checkpoints::CCheckpointData) { + checkpointData = (CCheckpointData) { boost::assign::map_list_of (0, consensus.hashGenesisBlock) (38000, uint256S("0x001e9a2d2e2892b88e9998cf7b079b41d59dd085423a921fe8386cecc42287b8")), @@ -419,7 +492,7 @@ static CTestNetParams testNetParams; /** * Regression test */ -class CRegTestParams : public CTestNetParams { +class CRegTestParams : public CChainParams { public: CRegTestParams() { strNetworkID = "regtest"; @@ -431,15 +504,28 @@ public: consensus.nMajorityRejectBlockOutdated = 950; consensus.nMajorityWindow = 1000; consensus.powLimit = uint256S("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"); + consensus.nPowAveragingWindow = 17; assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nPowAveragingWindow); consensus.nPowMaxAdjustDown = 0; // Turn off adjustment down consensus.nPowMaxAdjustUp = 0; // Turn off adjustment up + consensus.nPowTargetSpacing = 2.5 * 60; + consensus.vUpgrades[Consensus::BASE_SPROUT].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::BASE_SPROUT].nActivationHeight = + Consensus::NetworkUpgrade::ALWAYS_ACTIVE; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nProtocolVersion = 170002; + consensus.vUpgrades[Consensus::UPGRADE_TESTDUMMY].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion = 170003; + consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = + Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; + pchMessageStart[0] = 0xaa; pchMessageStart[1] = 0x8e; pchMessageStart[2] = 0xf3; pchMessageStart[3] = 0xf5; nMinerThreads = 1; nMaxTipAge = 24 * 60 * 60; + nPruneAfterHeight = 1000; const size_t N = 48, K = 5; BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K)); nEquihashN = N; @@ -450,7 +536,6 @@ public: genesis.nSolution = ParseHex("0f2a976db4c4263da10fd5d38eb1790469cf19bdb4bf93450e09a72fdff17a3454326399"); consensus.hashGenesisBlock = genesis.GetHash(); nDefaultPort = 17779; - assert(consensus.hashGenesisBlock == uint256S("0x00a215b4fe36f5d2f829d43e587bf10e89e64f9f48a5b6ce18559089e8fd643d")); nPruneAfterHeight = 1000; vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. @@ -462,18 +547,34 @@ public: fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; - checkpointData = (Checkpoints::CCheckpointData){ + checkpointData = (CCheckpointData){ boost::assign::map_list_of ( 0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")), 0, 0, 0 }; + // These prefixes are the same as the testnet prefixes + base58Prefixes[PUBKEY_ADDRESS] = {0x1D,0x25}; + base58Prefixes[SCRIPT_ADDRESS] = {0x1C,0xBA}; + base58Prefixes[SECRET_KEY] = {0xEF}; + // do not rely on these BIP32 prefixes; they are not specified and may change + base58Prefixes[EXT_PUBLIC_KEY] = {0x04,0x35,0x87,0xCF}; + base58Prefixes[EXT_SECRET_KEY] = {0x04,0x35,0x83,0x94}; + base58Prefixes[ZCPAYMENT_ADDRRESS] = {0x16,0xB6}; + base58Prefixes[ZCVIEWING_KEY] = {0xA8,0xAC,0x0C}; + base58Prefixes[ZCSPENDING_KEY] = {0xAC,0x08}; // Founders reward script expects a vector of 2-of-3 multisig addresses vFoundersRewardAddress = { "t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg" }; assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } + + void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) + { + assert(idx > Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES); + consensus.vUpgrades[idx].nActivationHeight = nActivationHeight; + } }; static CRegTestParams regTestParams; @@ -538,7 +639,7 @@ CScript CChainParams::GetFoundersRewardScriptAtHeight(int nHeight) const { CBitcoinAddress address(GetFoundersRewardAddressAtHeight(nHeight).c_str()); assert(address.IsValid()); assert(address.IsScript()); - CScriptID scriptID = get(address.Get()); // Get() returns a boost variant + CScriptID scriptID = boost::get(address.Get()); // Get() returns a boost variant CScript script = CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; return script; } @@ -547,3 +648,8 @@ std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const { assert(i >= 0 && i < vFoundersRewardAddress.size()); return vFoundersRewardAddress[i]; } + +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) +{ + regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight); +} diff --git a/src/chainparams.h b/src/chainparams.h index 00d2c255f..2041b2209 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -7,7 +7,6 @@ #define BITCOIN_CHAINPARAMS_H #include "chainparamsbase.h" -#include "checkpoints.h" #include "consensus/params.h" #include "primitives/block.h" #include "protocol.h" @@ -26,6 +25,8 @@ struct SeedSpec6 { uint16_t port; }; +typedef std::map MapCheckpoints; + /** * CChainParams defines various tweakable parameters of a given instance of the @@ -46,17 +47,22 @@ public: ZCPAYMENT_ADDRRESS, ZCSPENDING_KEY, + ZCVIEWING_KEY, MAX_BASE58_TYPES }; + struct CCheckpointData { + MapCheckpoints mapCheckpoints; + int64_t nTimeLastCheckpoint; + int64_t nTransactionsLastCheckpoint; + double fTransactionsPerDay; + }; const Consensus::Params& GetConsensus() const { return consensus; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - /** Used if GenerateBitcoins is called with a negative number of threads */ - int DefaultMinerThreads() const { return nMinerThreads; } const CBlock& GenesisBlock() const { return genesis; } /** Make miner wait to have peers to avoid wasting work */ bool MiningRequiresPeers() const { return fMiningRequiresPeers; } @@ -78,7 +84,7 @@ public: const std::vector& DNSSeeds() const { return vSeeds; } const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } const std::vector& FixedSeeds() const { return vFixedSeeds; } - const Checkpoints::CCheckpointData& Checkpoints() const { return checkpointData; } + const CCheckpointData& Checkpoints() const { return checkpointData; } /** Return the founder's reward address and script for a given block height */ std::string GetFoundersRewardAddressAtHeight(int height) const; CScript GetFoundersRewardScriptAtHeight(int height) const; @@ -87,7 +93,7 @@ public: void SetRegTestCoinbaseMustBeProtected() { consensus.fCoinbaseMustBeProtected = true; } void SetDefaultPort(uint16_t port) { nDefaultPort = port; } - void SetCheckpointData(Checkpoints::CCheckpointData checkpointData); + void SetCheckpointData(CCheckpointData checkpointData); //void setnonce(uint32_t nonce) { memcpy(&genesis.nNonce,&nonce,sizeof(nonce)); } //void settimestamp(uint32_t timestamp) { genesis.nTime = timestamp; } @@ -118,7 +124,7 @@ protected: bool fRequireStandard = false; bool fMineBlocksOnDemand = false; bool fTestnetToBeDeprecatedFieldRPC = false; - Checkpoints::CCheckpointData checkpointData; + CCheckpointData checkpointData; std::vector vFoundersRewardAddress; }; @@ -140,4 +146,9 @@ void SelectParams(CBaseChainParams::Network network); */ bool SelectParamsFromCommandLine(); +/** + * Allows modifying the network upgrade regtest parameters. + */ +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index a66b2da9e..475f200e6 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -25,7 +25,7 @@ static CBaseMainParams mainParams; /** * Testnet (v3) */ -class CBaseTestNetParams : public CBaseMainParams +class CBaseTestNetParams : public CBaseChainParams { public: CBaseTestNetParams() @@ -39,11 +39,12 @@ static CBaseTestNetParams testNetParams; /* * Regression test */ -class CBaseRegTestParams : public CBaseTestNetParams +class CBaseRegTestParams : public CBaseChainParams { public: CBaseRegTestParams() { + nRPCPort = 18232; strDataDir = "regtest"; } }; diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index ec1e2a47f..70fd1e8f2 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -23,7 +23,7 @@ namespace Checkpoints { * fast multicore CPU, it won't be much higher than 1. */ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0; - bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash) + bool CheckBlock(const CChainParams::CCheckpointData& data, int nHeight, const uint256& hash) { const MapCheckpoints& checkpoints = data.mapCheckpoints; @@ -33,7 +33,7 @@ namespace Checkpoints { } //! Guess how far we are in the verification process at the given block index - double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) { + double GuessVerificationProgress(const CChainParams::CCheckpointData& data, CBlockIndex *pindex, bool fSigchecks) { if (pindex==NULL) return 0.0; @@ -62,7 +62,7 @@ namespace Checkpoints { return fWorkBefore / (fWorkBefore + fWorkAfter); } - int GetTotalBlocksEstimate(const CCheckpointData& data) + int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; @@ -72,7 +72,7 @@ namespace Checkpoints { return checkpoints.rbegin()->first; } - CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) + CBlockIndex* GetLastCheckpoint(const CChainParams::CCheckpointData& data) { const MapCheckpoints& checkpoints = data.mapCheckpoints; diff --git a/src/checkpoints.h b/src/checkpoints.h index f4c3992ba..b75da9ef2 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -6,10 +6,12 @@ #define BITCOIN_CHECKPOINTS_H #include "uint256.h" +#include "chainparams.h" #include class CBlockIndex; +struct CCheckpointData; /** * Block-chain checkpoints are compiled-in sanity checks. @@ -17,7 +19,8 @@ class CBlockIndex; */ namespace Checkpoints { -typedef std::map MapCheckpoints; + + typedef std::map MapCheckpoints; struct CCheckpointData { MapCheckpoints mapCheckpoints; @@ -25,15 +28,16 @@ struct CCheckpointData { int64_t nTransactionsLastCheckpoint; double fTransactionsPerDay; }; - bool CheckBlock(const CCheckpointData& data, int nHeight, const uint256& hash); + bool CheckBlock(const CChainParams::CCheckpointData& data, int nHeight, const uint256& hash); + //! Return conservative estimate of total number of blocks, 0 if unknown -int GetTotalBlocksEstimate(const CCheckpointData& data); + int GetTotalBlocksEstimate(const CChainParams::CCheckpointData& data); //! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint -CBlockIndex* GetLastCheckpoint(const CCheckpointData& data); + CBlockIndex* GetLastCheckpoint(const CChainParams::CCheckpointData& data); -double GuessVerificationProgress(const CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); +double GuessVerificationProgress(const CChainParams::CCheckpointData& data, CBlockIndex* pindex, bool fSigchecks = true); } //namespace Checkpoints diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 1e3eccbea..ae67e678f 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -100,7 +100,7 @@ const std::string CLIENT_NAME("MagicBean"); const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); const std::string CLIENT_DATE(BUILD_DATE); -static std::string FormatVersion(int nVersion) +std::string FormatVersion(int nVersion) { if (nVersion % 100 < 25) return strprintf("%d.%d.%d-beta%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, (nVersion % 100)+1); diff --git a/src/clientversion.h b/src/clientversion.h index 108c89b85..1203760bb 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -17,7 +17,7 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 1 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 8 +#define CLIENT_VERSION_REVISION 15 #define CLIENT_VERSION_BUILD 52 //! Set to true for release, false for prerelease or test build @@ -63,6 +63,7 @@ extern const std::string CLIENT_BUILD; extern const std::string CLIENT_DATE; +std::string FormatVersion(int nVersion); std::string FormatFullVersion(); std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); diff --git a/src/coins.cpp b/src/coins.cpp index 37d969010..bb40af9cc 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -387,7 +387,7 @@ const CScript &CCoinsViewCache::GetSpendFor(const CTxIn& input) const } //uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue); +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTransaction& tx,uint32_t tiptime) const @@ -407,7 +407,7 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr if ( value >= 10*COIN ) { int64_t interest; int32_t txheight; uint32_t locktime; - interest = komodo_accrued_interest(&txheight,&locktime,tx.vin[i].prevout.hash,tx.vin[i].prevout.n,0,value); + interest = komodo_accrued_interest(&txheight,&locktime,tx.vin[i].prevout.hash,tx.vin[i].prevout.n,0,value,(int32_t)nHeight); //printf("nResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nResult/COIN,(double)value/COIN,(double)interest/COIN,txheight,locktime,tiptime); //fprintf(stderr,"nResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nResult/COIN,(double)value/COIN,(double)interest/COIN,txheight,locktime,tiptime); nResult += interest; @@ -473,8 +473,6 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const { if (tx.IsCoinBase()) return 0.0; - //CAmount nTotalIn = 0; - // Joinsplits do not reveal any information about the value or age of a note, so we // cannot apply the priority algorithm used for transparent utxos. Instead, we just // use the maximum priority whenever a transaction contains any JoinSplits. @@ -493,34 +491,9 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const if (!coins->IsAvailable(txin.prevout.n)) continue; if (coins->nHeight < nHeight) { dResult += coins->vout[txin.prevout.n].nValue * (nHeight-coins->nHeight); - //nTotalIn += coins->vout[txin.prevout.n].nValue; } } - // If a transaction contains a joinsplit, we boost the priority of the transaction. - // Joinsplits do not reveal any information about the value or age of a note, so we - // cannot apply the priority algorithm used for transparent utxos. Instead, we pick a - // very large number and multiply it by the transaction's fee per 1000 bytes of data. - // One trillion, 1000000000000, is equivalent to 1 ZEC utxo * 10000 blocks (~17 days). - /*if (tx.vjoinsplit.size() > 0) { - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - nTotalIn += tx.GetJoinSplitValueIn(); - CAmount fee = nTotalIn - tx.GetValueOut(); - CFeeRate feeRate(fee, nTxSize); - CAmount feePerK = feeRate.GetFeePerK(); - - if (feePerK == 0) { - feePerK = 1; - } - - dResult += 1000000000000 * double(feePerK); - // We cast feePerK from int64_t to double because if feePerK is a large number, say - // close to MAX_MONEY, the multiplication operation will result in an integer overflow. - // The variable dResult should never overflow since a 64-bit double in C++ is typically - // a double-precision floating-point number as specified by IEE 754, with a maximum - // value DBL_MAX of 1.79769e+308. - }*/ - return tx.ComputePriority(dResult); } diff --git a/src/coins.h b/src/coins.h index e7a8a017a..fcc32caae 100644 --- a/src/coins.h +++ b/src/coins.h @@ -171,7 +171,7 @@ public: nSize += ::GetSerializeSize(VARINT(nCode), nType, nVersion); // spentness bitmask nSize += nMaskSize; - // txouts themself + // txouts for (unsigned int i = 0; i < vout.size(); i++) if (!vout[i].IsNull()) nSize += ::GetSerializeSize(CTxOutCompressor(REF(vout[i])), nType, nVersion); diff --git a/src/consensus/consensus.h b/src/consensus/consensus.h index d9f24db11..d2e7dec3f 100644 --- a/src/consensus/consensus.h +++ b/src/consensus/consensus.h @@ -9,7 +9,11 @@ /** The minimum allowed block version (network rule) */ static const int32_t MIN_BLOCK_VERSION = 4; /** The minimum allowed transaction version (network rule) */ -static const int32_t MIN_TX_VERSION = 1; +static const int32_t SPROUT_MIN_TX_VERSION = 1; +/** The minimum allowed transaction version (network rule) */ +static const int32_t OVERWINTER_MIN_TX_VERSION = 3; +/** The maximum allowed transaction version (network rule) */ +static const int32_t OVERWINTER_MAX_TX_VERSION = 3; /** The maximum allowed size for a serialized block, in bytes (network rule) */ static const unsigned int MAX_BLOCK_SIZE = 2000000; /** The maximum allowed number of signature check operations in a block (network rule) */ @@ -18,6 +22,8 @@ static const unsigned int MAX_BLOCK_SIGOPS = 20000; static const unsigned int MAX_TX_SIZE = 100000; /** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */ extern int COINBASE_MATURITY; +/** The minimum value which is invalid for expiry height, used by CTransaction and CMutableTransaction */ +static constexpr uint32_t TX_EXPIRY_HEIGHT_THRESHOLD = 500000000; /** Flags for LockTime() */ enum { diff --git a/src/consensus/params.h b/src/consensus/params.h index d3e6462b8..855729ff0 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -9,6 +9,54 @@ #include "uint256.h" namespace Consensus { + +/** + * Index into Params.vUpgrades and NetworkUpgradeInfo + * + * Being array indices, these MUST be numbered consecutively. + * + * The order of these indices MUST match the order of the upgrades on-chain, as + * several functions depend on the enum being sorted. + */ +enum UpgradeIndex { + // Sprout must be first + BASE_SPROUT, + UPGRADE_TESTDUMMY, + UPGRADE_OVERWINTER, + // NOTE: Also add new upgrades to NetworkUpgradeInfo in upgrades.cpp + MAX_NETWORK_UPGRADES +}; + +struct NetworkUpgrade { + /** + * The first protocol version which will understand the new consensus rules + */ + int nProtocolVersion; + + /** + * Height of the first block for which the new consensus rules will be active + */ + int nActivationHeight; + + /** + * Special value for nActivationHeight indicating that the upgrade is always active. + * This is useful for testing, as it means tests don't need to deal with the activation + * process (namely, faking a chain of somewhat-arbitrary length). + * + * New blockchains that want to enable upgrade rules from the beginning can also use + * this value. However, additional care must be taken to ensure the genesis block + * satisfies the enabled rules. + */ + static constexpr int ALWAYS_ACTIVE = 0; + + /** + * Special value for nActivationHeight indicating that the upgrade will never activate. + * This is useful when adding upgrade code that has a testnet activation height, but + * should remain disabled on mainnet. + */ + static constexpr int NO_ACTIVATION_HEIGHT = -1; +}; + /** * Parameters that influence chain consensus. */ @@ -39,9 +87,10 @@ struct Params { int nMajorityEnforceBlockUpgrade; int nMajorityRejectBlockOutdated; int nMajorityWindow; + int fPowAllowMinDifficultyBlocks; + NetworkUpgrade vUpgrades[MAX_NETWORK_UPGRADES]; /** Proof of work parameters */ uint256 powLimit; - bool fPowAllowMinDifficultyBlocks; int64_t nPowAveragingWindow; int64_t nPowMaxAdjustDown; int64_t nPowMaxAdjustUp; diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp new file mode 100644 index 000000000..c913c7ea0 --- /dev/null +++ b/src/consensus/upgrades.cpp @@ -0,0 +1,126 @@ +// Copyright (c) 2018 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "consensus/upgrades.h" + +/** + * General information about each network upgrade. + * Ordered by Consensus::UpgradeIndex. + */ +const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = { + { + /*.nBranchId =*/ 0, + /*.strName =*/ "Sprout", + /*.strInfo =*/ "The Zcash network at launch", + }, + { + /*.nBranchId =*/ 0x74736554, + /*.strName =*/ "Test dummy", + /*.strInfo =*/ "Test dummy info", + }, + { + /*.nBranchId =*/ 0x5ba81b19, + /*.strName =*/ "Overwinter", + /*.strInfo =*/ "See https://z.cash/upgrade/overwinter.html for details.", + } +}; + +const uint32_t SPROUT_BRANCH_ID = NetworkUpgradeInfo[Consensus::BASE_SPROUT].nBranchId; + +UpgradeState NetworkUpgradeState( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + assert(nHeight >= 0); + assert(idx >= Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES); + auto nActivationHeight = params.vUpgrades[idx].nActivationHeight; + + if (nActivationHeight == Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + return UPGRADE_DISABLED; + } else if (nHeight >= nActivationHeight) { + // From ZIP 200: + // + // ACTIVATION_HEIGHT + // The non-zero block height at which the network upgrade rules will come + // into effect, and be enforced as part of the blockchain consensus. + // + // For removal of ambiguity, the block at height ACTIVATION_HEIGHT - 1 is + // subject to the pre-upgrade consensus rules, and would be the last common + // block in the event of a persistent pre-upgrade branch. + return UPGRADE_ACTIVE; + } else { + return UPGRADE_PENDING; + } +} + +bool NetworkUpgradeActive( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + return NetworkUpgradeState(nHeight, params, idx) == UPGRADE_ACTIVE; +} + +int CurrentEpoch(int nHeight, const Consensus::Params& params) { + for (auto idxInt = Consensus::MAX_NETWORK_UPGRADES - 1; idxInt >= Consensus::BASE_SPROUT; idxInt--) { + if (NetworkUpgradeActive(nHeight, params, Consensus::UpgradeIndex(idxInt))) { + return idxInt; + } + } +} + +uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params) { + return NetworkUpgradeInfo[CurrentEpoch(nHeight, params)].nBranchId; +} + +bool IsActivationHeight( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx) +{ + assert(idx >= Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES); + + // Don't count Sprout as an activation height + if (idx == Consensus::BASE_SPROUT) { + return false; + } + + return nHeight >= 0 && nHeight == params.vUpgrades[idx].nActivationHeight; +} + +bool IsActivationHeightForAnyUpgrade( + int nHeight, + const Consensus::Params& params) +{ + if (nHeight < 0) { + return false; + } + + // Don't count Sprout as an activation height + for (int idx = Consensus::BASE_SPROUT + 1; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) { + if (nHeight == params.vUpgrades[idx].nActivationHeight) + return true; + } + + return false; +} + +boost::optional NextActivationHeight( + int nHeight, + const Consensus::Params& params) +{ + if (nHeight < 0) { + return boost::none; + } + + // Don't count Sprout as an activation height + for (auto idx = Consensus::BASE_SPROUT + 1; idx < Consensus::MAX_NETWORK_UPGRADES; idx++) { + if (NetworkUpgradeState(nHeight, params, Consensus::UpgradeIndex(idx)) == UPGRADE_PENDING) { + return params.vUpgrades[idx].nActivationHeight; + } + } + + return boost::none; +} diff --git a/src/consensus/upgrades.h b/src/consensus/upgrades.h new file mode 100644 index 000000000..620dc94c4 --- /dev/null +++ b/src/consensus/upgrades.h @@ -0,0 +1,90 @@ +// Copyright (c) 2018 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_CONSENSUS_UPGRADES_H +#define ZCASH_CONSENSUS_UPGRADES_H + +#include "consensus/params.h" + +#include + +enum UpgradeState { + UPGRADE_DISABLED, + UPGRADE_PENDING, + UPGRADE_ACTIVE +}; + +struct NUInfo { + /** Branch ID (a random non-zero 32-bit value) */ + uint32_t nBranchId; + /** User-facing name for the upgrade */ + std::string strName; + /** User-facing information string about the upgrade */ + std::string strInfo; +}; + +extern const struct NUInfo NetworkUpgradeInfo[]; + +// Consensus branch id to identify pre-overwinter (Sprout) consensus rules. +extern const uint32_t SPROUT_BRANCH_ID; + +/** + * Checks the state of a given network upgrade based on block height. + * Caller must check that the height is >= 0 (and handle unknown heights). + */ +UpgradeState NetworkUpgradeState( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx); + +/** + * Returns true if the given network upgrade is active as of the given block + * height. Caller must check that the height is >= 0 (and handle unknown + * heights). + */ +bool NetworkUpgradeActive( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex idx); + +/** + * Returns the index of the most recent upgrade as of the given block height + * (corresponding to the current "epoch"). Consensus::BASE_SPROUT is the + * default value if no upgrades are active. Caller must check that the height + * is >= 0 (and handle unknown heights). + */ +int CurrentEpoch(int nHeight, const Consensus::Params& params); + +/** + * Returns the branch ID of the most recent upgrade as of the given block height + * (corresponding to the current "epoch"), or 0 if no upgrades are active. + * Caller must check that the height is >= 0 (and handle unknown heights). + */ +uint32_t CurrentEpochBranchId(int nHeight, const Consensus::Params& params); + +/** + * Returns true if the given block height is the activation height for the given + * upgrade. + */ +bool IsActivationHeight( + int nHeight, + const Consensus::Params& params, + Consensus::UpgradeIndex upgrade); + +/** + * Returns true if the given block height is the activation height for any upgrade. + */ +bool IsActivationHeightForAnyUpgrade( + int nHeight, + const Consensus::Params& params); + +/** + * Returns the activation height for the next upgrade after the given block height, + * or boost::none if there are no more known upgrades. + */ +boost::optional NextActivationHeight( + int nHeight, + const Consensus::Params& params); + +#endif // ZCASH_CONSENSUS_UPGRADES_H diff --git a/src/crypto/common.h b/src/crypto/common.h index 5d5027ada..ad4c6dd5e 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -16,7 +16,7 @@ #include "compat/endian.h" #if defined(NDEBUG) -# error "Bitcoin cannot be compiled without assertions." +# error "Zcash cannot be compiled without assertions." #endif uint16_t static inline ReadLE16(const unsigned char* ptr) diff --git a/src/crypto/equihash.cpp b/src/crypto/equihash.cpp index 9e6d18590..04ee5f3b7 100644 --- a/src/crypto/equihash.cpp +++ b/src/crypto/equihash.cpp @@ -16,6 +16,7 @@ #include "config/bitcoin-config.h" #endif +#include "compat/endian.h" #include "crypto/equihash.h" #include "util.h" #ifndef __linux__ diff --git a/src/deprecation.cpp b/src/deprecation.cpp new file mode 100644 index 000000000..9f394e720 --- /dev/null +++ b/src/deprecation.cpp @@ -0,0 +1,61 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "deprecation.h" + +#include "clientversion.h" +#include "init.h" +#include "ui_interface.h" +#include "util.h" +#include "chainparams.h" + +static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); + +void EnforceNodeDeprecation(int nHeight, bool forceLogging) { + + // Do not enforce deprecation in regtest or on testnet + std::string networkID = Params().NetworkIDString(); + if (networkID != "main") return; + + int blocksToDeprecation = DEPRECATION_HEIGHT - nHeight; + bool disableDeprecation = (GetArg("-disabledeprecation", "") == CLIENT_VERSION_STR); + if (blocksToDeprecation <= 0) { + // In order to ensure we only log once per process when deprecation is + // disabled (to avoid log spam), we only need to log in two cases: + // - The deprecating block just arrived + // - This can be triggered more than once if a block chain reorg + // occurs, but that's an irregular event that won't cause spam. + // - The node is starting + if (blocksToDeprecation == 0 || forceLogging) { + auto msg = strprintf(_("This version has been deprecated as of block height %d."), + DEPRECATION_HEIGHT) + " " + + _("You should upgrade to the latest version of Zcash."); + if (!disableDeprecation) { + msg += " " + strprintf(_("To disable deprecation for this version, set %s%s."), + "-disabledeprecation=", CLIENT_VERSION_STR); + } + LogPrintf("*** %s\n", msg); + uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); + } + if (!disableDeprecation) { + StartShutdown(); + } + } else if (blocksToDeprecation == DEPRECATION_WARN_LIMIT || + (blocksToDeprecation < DEPRECATION_WARN_LIMIT && forceLogging)) { + std::string msg; + if (disableDeprecation) { + msg = strprintf(_("This version will be deprecated at block height %d."), + DEPRECATION_HEIGHT) + " " + + _("You should upgrade to the latest version of Zcash."); + } else { + msg = strprintf(_("This version will be deprecated at block height %d, and will automatically shut down."), + DEPRECATION_HEIGHT) + " " + + _("You should upgrade to the latest version of Zcash.") + " " + + strprintf(_("To disable deprecation for this version, set %s%s."), + "-disabledeprecation=", CLIENT_VERSION_STR); + } + LogPrintf("*** %s\n", msg); + uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_WARNING); + } +} \ No newline at end of file diff --git a/src/deprecation.h b/src/deprecation.h new file mode 100644 index 000000000..78ed8ebda --- /dev/null +++ b/src/deprecation.h @@ -0,0 +1,25 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_DEPRECATION_H +#define ZCASH_DEPRECATION_H + +// Deprecation policy: +// * Shut down 16 weeks' worth of blocks after the estimated release block height. +// * A warning is shown during the 2 weeks' worth of blocks prior to shut down. +static const int APPROX_RELEASE_HEIGHT = 800000; +static const int WEEKS_UNTIL_DEPRECATION = 52; +static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 24); + +// Number of blocks before deprecation to warn users +static const int DEPRECATION_WARN_LIMIT = 60 * 24 * 60; // 2 months + +/** + * Checks whether the node is deprecated based on the current block height, and + * shuts down the node with an error if so (and deprecation is not disabled for + * the current client version). + */ +void EnforceNodeDeprecation(int nHeight, bool forceLogging=false); + +#endif // ZCASH_DEPRECATION_H diff --git a/src/eccryptoverify.cpp b/src/eccryptoverify.cpp deleted file mode 100644 index e894e1122..000000000 --- a/src/eccryptoverify.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "eccryptoverify.h" - -namespace { - -int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) { - while (c1len > c2len) { - if (*c1) - return 1; - c1++; - c1len--; - } - while (c2len > c1len) { - if (*c2) - return -1; - c2++; - c2len--; - } - while (c1len > 0) { - if (*c1 > *c2) - return 1; - if (*c2 > *c1) - return -1; - c1++; - c2++; - c1len--; - } - return 0; -} - -/** Order of secp256k1's generator minus 1. */ -const unsigned char vchMaxModOrder[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 -}; - -/** Half of the order of secp256k1's generator minus 1. */ -const unsigned char vchMaxModHalfOrder[32] = { - 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D, - 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0 -}; - -const unsigned char vchZero[1] = {0}; -} // anon namespace - -namespace eccrypto { - -bool Check(const unsigned char *vch) { - return vch && - CompareBigEndian(vch, 32, vchZero, 0) > 0 && - CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0; -} - -bool CheckSignatureElement(const unsigned char *vch, int len, bool half) { - return vch && - CompareBigEndian(vch, len, vchZero, 0) > 0 && - CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0; -} - -} // namespace eccrypto diff --git a/src/eccryptoverify.h b/src/eccryptoverify.h deleted file mode 100644 index c67c1e44f..000000000 --- a/src/eccryptoverify.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_ECCRYPTOVERIFY_H -#define BITCOIN_ECCRYPTOVERIFY_H - -#include -#include - -class uint256; - -namespace eccrypto { - -bool Check(const unsigned char *vch); -bool CheckSignatureElement(const unsigned char *vch, int len, bool half); - -} // eccrypto namespace - -#endif // BITCOIN_ECCRYPTOVERIFY_H diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp deleted file mode 100644 index ae2748806..000000000 --- a/src/ecwrapper.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "ecwrapper.h" - -#include "serialize.h" -#include "uint256.h" - -#include -#include - -namespace { - -class ecgroup_order -{ -public: - static const EC_GROUP* get() - { - static const ecgroup_order wrapper; - return wrapper.pgroup; - } - -private: - ecgroup_order() - : pgroup(EC_GROUP_new_by_curve_name(NID_secp256k1)) - { - } - - ~ecgroup_order() - { - EC_GROUP_free(pgroup); - } - - EC_GROUP* pgroup; -}; - -/** - * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields - * recid selects which key is recovered - * if check is non-zero, additional checks are performed - */ -int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) -{ - if (!eckey) return 0; - - int ret = 0; - BN_CTX *ctx = NULL; - - BIGNUM *x = NULL; - BIGNUM *e = NULL; - BIGNUM *order = NULL; - BIGNUM *sor = NULL; - BIGNUM *eor = NULL; - BIGNUM *field = NULL; - EC_POINT *R = NULL; - EC_POINT *O = NULL; - EC_POINT *Q = NULL; - BIGNUM *rr = NULL; - BIGNUM *zero = NULL; - int n = 0; - int i = recid / 2; - - const BIGNUM *sig_r, *sig_s; - ECDSA_SIG_get0(ecsig, &sig_r, &sig_s); - - const EC_GROUP *group = EC_KEY_get0_group(eckey); - if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } - x = BN_CTX_get(ctx); - if (!BN_copy(x, order)) { ret=-1; goto err; } - if (!BN_mul_word(x, i)) { ret=-1; goto err; } - if (!BN_add(x, x, sig_r)) { ret=-1; goto err; } - field = BN_CTX_get(ctx); - if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } - if (BN_cmp(x, field) >= 0) { ret=0; goto err; } - if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } - if (check) - { - if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } - if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } - } - if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } - n = EC_GROUP_get_degree(group); - e = BN_CTX_get(ctx); - if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } - if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); - zero = BN_CTX_get(ctx); - if (!BN_zero(zero)) { ret=-1; goto err; } - if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } - rr = BN_CTX_get(ctx); - if (!BN_mod_inverse(rr, sig_r, order, ctx)) { ret=-1; goto err; } - sor = BN_CTX_get(ctx); - if (!BN_mod_mul(sor, sig_s, rr, order, ctx)) { ret=-1; goto err; } - eor = BN_CTX_get(ctx); - if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } - if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } - if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } - - ret = 1; - -err: - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (R != NULL) EC_POINT_free(R); - if (O != NULL) EC_POINT_free(O); - if (Q != NULL) EC_POINT_free(Q); - return ret; -} - -} // anon namespace - -CECKey::CECKey() { - pkey = EC_KEY_new(); - assert(pkey != NULL); - int result = EC_KEY_set_group(pkey, ecgroup_order::get()); - assert(result); -} - -CECKey::~CECKey() { - EC_KEY_free(pkey); -} - -void CECKey::GetPubKey(std::vector &pubkey, bool fCompressed) { - EC_KEY_set_conv_form(pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED); - int nSize = i2o_ECPublicKey(pkey, NULL); - assert(nSize); - assert(nSize <= 65); - pubkey.clear(); - pubkey.resize(nSize); - unsigned char *pbegin(begin_ptr(pubkey)); - int nSize2 = i2o_ECPublicKey(pkey, &pbegin); - assert(nSize == nSize2); -} - -bool CECKey::SetPubKey(const unsigned char* pubkey, size_t size) { - return o2i_ECPublicKey(&pkey, &pubkey, size) != NULL; -} - -bool CECKey::Verify(const uint256 &hash, const std::vector& vchSig) { - if (vchSig.empty()) - return false; - - // New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first. - unsigned char *norm_der = NULL; - ECDSA_SIG *norm_sig = ECDSA_SIG_new(); - const unsigned char* sigptr = &vchSig[0]; - assert(norm_sig); - if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL) - { - /* As of OpenSSL 1.0.0p d2i_ECDSA_SIG frees and nulls the pointer on - * error. But OpenSSL's own use of this function redundantly frees the - * result. As ECDSA_SIG_free(NULL) is a no-op, and in the absence of a - * clear contract for the function behaving the same way is more - * conservative. - */ - ECDSA_SIG_free(norm_sig); - return false; - } - int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der); - ECDSA_SIG_free(norm_sig); - if (derlen <= 0) - return false; - - // -1 = error, 0 = bad sig, 1 = good - bool ret = ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1; - OPENSSL_free(norm_der); - return ret; -} - -bool CECKey::Recover(const uint256 &hash, const unsigned char *p64, int rec) -{ - if (rec<0 || rec>=3) - return false; - ECDSA_SIG *sig = ECDSA_SIG_new(); - BIGNUM *sig_r = BN_bin2bn(&p64[0], 32, nullptr); - BIGNUM *sig_s = BN_bin2bn(&p64[32], 32, nullptr); - assert(sig && sig_r && sig_s); - bool ret = ECDSA_SIG_set0(sig, sig_r, sig_s); - assert(ret); - ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1; - ECDSA_SIG_free(sig); - return ret; -} - -bool CECKey::TweakPublic(const unsigned char vchTweak[32]) { - bool ret = true; - BN_CTX *ctx = BN_CTX_new(); - BN_CTX_start(ctx); - BIGNUM *bnTweak = BN_CTX_get(ctx); - BIGNUM *bnOrder = BN_CTX_get(ctx); - BIGNUM *bnOne = BN_CTX_get(ctx); - const EC_GROUP *group = EC_KEY_get0_group(pkey); - EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order... - BN_bin2bn(vchTweak, 32, bnTweak); - if (BN_cmp(bnTweak, bnOrder) >= 0) - ret = false; // extremely unlikely - EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group); - BN_one(bnOne); - EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx); - if (EC_POINT_is_at_infinity(group, point)) - ret = false; // ridiculously unlikely - EC_KEY_set_public_key(pkey, point); - EC_POINT_free(point); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - return ret; -} - -bool CECKey::SanityCheck() -{ - const EC_GROUP *pgroup = ecgroup_order::get(); - if(pgroup == NULL) - return false; - // TODO Is there more EC functionality that could be missing? - return true; -} diff --git a/src/ecwrapper.h b/src/ecwrapper.h deleted file mode 100644 index efb6cd18a..000000000 --- a/src/ecwrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_ECWRAPPER_H -#define BITCOIN_ECWRAPPER_H - -#include -#include - -#include - -class uint256; - -/** RAII Wrapper around OpenSSL's EC_KEY */ -class CECKey { -private: - EC_KEY *pkey; - -public: - CECKey(); - ~CECKey(); - - void GetPubKey(std::vector& pubkey, bool fCompressed); - bool SetPubKey(const unsigned char* pubkey, size_t size); - bool Verify(const uint256 &hash, const std::vector& vchSig); - - /** - * reconstruct public key from a compact signature - * This is only slightly more CPU intensive than just verifying it. - * If this function succeeds, the recovered public key is guaranteed to be valid - * (the signature is a valid signature of the given data for that key) - */ - bool Recover(const uint256 &hash, const unsigned char *p64, int rec); - - bool TweakPublic(const unsigned char vchTweak[32]); - static bool SanityCheck(); -}; - -#endif // BITCOIN_ECWRAPPER_H diff --git a/src/gtest/main.cpp b/src/gtest/main.cpp index 84e6f867c..d2ae0b23d 100644 --- a/src/gtest/main.cpp +++ b/src/gtest/main.cpp @@ -1,15 +1,30 @@ -#include "gtest/gtest.h" +#include "gmock/gmock.h" #include "crypto/common.h" +#include "pubkey.h" +#include "zcash/JoinSplit.hpp" +#include "util.h" -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" +#include +#include + +struct ECCryptoClosure +{ + ECCVerifyHandle handle; +}; + +ECCryptoClosure instance_of_eccryptoclosure; + +ZCJoinSplit* params; int main(int argc, char **argv) { assert(init_and_check_sodium() != -1); libsnark::default_r1cs_ppzksnark_pp::init_public_params(); libsnark::inhibit_profiling_info = true; libsnark::inhibit_profiling_counters = true; + boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; + boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; + params = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); - testing::InitGoogleTest(&argc, argv); + testing::InitGoogleMock(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index dde02118f..e098cfdae 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -33,6 +33,40 @@ TEST(CheckBlock, VersionTooLow) { EXPECT_FALSE(CheckBlock(0,0,block, state, verifier, false, false)); } + +// Test that a Sprout tx with negative version is still rejected +// by CheckBlock under Sprout consensus rules. +TEST(CheckBlock, BlockSproutRejectsBadVersion) { + SelectParams(CBaseChainParams::MAIN); + + CMutableTransaction mtx; + mtx.vin.resize(1); + mtx.vin[0].prevout.SetNull(); + mtx.vin[0].scriptSig = CScript() << 1 << OP_0; + mtx.vout.resize(1); + mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; + mtx.vout[0].nValue = 0; + mtx.vout.push_back(CTxOut( + GetBlockSubsidy(1, Params().GetConsensus())/5, + Params().GetFoundersRewardScriptAtHeight(1))); + mtx.fOverwintered = false; + mtx.nVersion = -1; + mtx.nVersionGroupId = 0; + + CTransaction tx {mtx}; + CBlock block; + block.vtx.push_back(tx); + + MockCValidationState state; + CBlockIndex indexPrev {Params().GenesisBlock()}; + + auto verifier = libzcash::ProofVerifier::Strict(); + + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1); + EXPECT_FALSE(CheckBlock(block, state, verifier, false, false)); +} + + TEST(ContextualCheckBlock, BadCoinbaseHeight) { SelectParams(CBaseChainParams::MAIN); @@ -75,3 +109,125 @@ TEST(ContextualCheckBlock, BadCoinbaseHeight) { block.vtx[0] = tx4; EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); } + +// Test that a block evaluated under Sprout rules cannot contain Overwinter transactions. +// This test assumes that mainnet Overwinter activation is at least height 2. +TEST(ContextualCheckBlock, BlockSproutRulesRejectOverwinterTx) { + SelectParams(CBaseChainParams::MAIN); + + CMutableTransaction mtx; + mtx.vin.resize(1); + mtx.vin[0].prevout.SetNull(); + mtx.vin[0].scriptSig = CScript() << 1 << OP_0; + mtx.vout.resize(1); + mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; + mtx.vout[0].nValue = 0; + + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + + CTransaction tx {mtx}; + CBlock block; + block.vtx.push_back(tx); + + MockCValidationState state; + CBlockIndex indexPrev {Params().GenesisBlock()}; + + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1); + EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); +} + + +// Test block evaluated under Sprout rules will accept Sprout transactions +TEST(ContextualCheckBlock, BlockSproutRulesAcceptSproutTx) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + + CMutableTransaction mtx; + mtx.vin.resize(1); + mtx.vin[0].prevout.SetNull(); + mtx.vin[0].scriptSig = CScript() << 1 << OP_0; + mtx.vout.resize(1); + mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; + mtx.vout[0].nValue = 0; + mtx.vout.push_back(CTxOut( + GetBlockSubsidy(1, Params().GetConsensus())/5, + Params().GetFoundersRewardScriptAtHeight(1))); + mtx.fOverwintered = false; + mtx.nVersion = 1; + + CTransaction tx {mtx}; + CBlock block; + block.vtx.push_back(tx); + MockCValidationState state; + CBlockIndex indexPrev {Params().GenesisBlock()}; + + EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + +// Test block evaluated under Overwinter rules will accept Overwinter transactions +TEST(ContextualCheckBlock, BlockOverwinterRulesAcceptOverwinterTx) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1); + + CMutableTransaction mtx; + mtx.vin.resize(1); + mtx.vin[0].prevout.SetNull(); + mtx.vin[0].scriptSig = CScript() << 1 << OP_0; + mtx.vout.resize(1); + mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; + mtx.vout[0].nValue = 0; + mtx.vout.push_back(CTxOut( + GetBlockSubsidy(1, Params().GetConsensus())/5, + Params().GetFoundersRewardScriptAtHeight(1))); + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + + CTransaction tx {mtx}; + CBlock block; + block.vtx.push_back(tx); + MockCValidationState state; + CBlockIndex indexPrev {Params().GenesisBlock()}; + + EXPECT_TRUE(ContextualCheckBlock(block, state, &indexPrev)); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + + +// Test block evaluated under Overwinter rules will reject Sprout transactions +TEST(ContextualCheckBlock, BlockOverwinterRulesRejectSproutTx) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, 1); + + CMutableTransaction mtx; + mtx.vin.resize(1); + mtx.vin[0].prevout.SetNull(); + mtx.vin[0].scriptSig = CScript() << 1 << OP_0; + mtx.vout.resize(1); + mtx.vout[0].scriptPubKey = CScript() << OP_TRUE; + mtx.vout[0].nValue = 0; + + mtx.nVersion = 2; + + CTransaction tx {mtx}; + CBlock block; + block.vtx.push_back(tx); + + MockCValidationState state; + CBlockIndex indexPrev {Params().GenesisBlock()}; + + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-active", false)).Times(1); + EXPECT_FALSE(ContextualCheckBlock(block, state, &indexPrev)); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} \ No newline at end of file diff --git a/src/gtest/test_checktransaction.cpp b/src/gtest/test_checktransaction.cpp index 305977103..bec9cdd6f 100644 --- a/src/gtest/test_checktransaction.cpp +++ b/src/gtest/test_checktransaction.cpp @@ -45,6 +45,8 @@ public: CMutableTransaction GetValidTransaction() { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + CMutableTransaction mtx; mtx.vin.resize(2); mtx.vin[0].prevout.hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); @@ -74,7 +76,7 @@ CMutableTransaction GetValidTransaction() { // Empty output script. CScript scriptCode; CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); if (dataToBeSigned == one) { throw std::runtime_error("SignatureHash failed"); } @@ -352,23 +354,27 @@ TEST(checktransaction_tests, bad_txns_prevout_null) { } TEST(checktransaction_tests, bad_txns_invalid_joinsplit_signature) { + SelectParams(CBaseChainParams::REGTEST); + CMutableTransaction mtx = GetValidTransaction(); mtx.joinSplitSig[0] += 1; CTransaction tx(mtx); MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); - CheckTransactionWithoutProofVerification(tx, state); + ContextualCheckTransaction(tx, state, 0, 100); } TEST(checktransaction_tests, non_canonical_ed25519_signature) { + SelectParams(CBaseChainParams::REGTEST); + CMutableTransaction mtx = GetValidTransaction(); // Check that the signature is valid before we add L { CTransaction tx(mtx); MockCValidationState state; - EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state)); + EXPECT_TRUE(ContextualCheckTransaction(tx, state, 0, 100)); } // Copied from libsodium/crypto_sign/ed25519/ref10/open.c @@ -389,5 +395,380 @@ TEST(checktransaction_tests, non_canonical_ed25519_signature) { MockCValidationState state; EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false)).Times(1); + ContextualCheckTransaction(tx, state, 0, 100); +} + +TEST(checktransaction_tests, OverwinterConstructors) { + CMutableTransaction mtx; + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 20; + + // Check constructor with overwinter fields + CTransaction tx(mtx); + EXPECT_EQ(tx.nVersion, mtx.nVersion); + EXPECT_EQ(tx.fOverwintered, mtx.fOverwintered); + EXPECT_EQ(tx.nVersionGroupId, mtx.nVersionGroupId); + EXPECT_EQ(tx.nExpiryHeight, mtx.nExpiryHeight); + + // Check constructor of mutable transaction struct + CMutableTransaction mtx2(tx); + EXPECT_EQ(mtx2.nVersion, mtx.nVersion); + EXPECT_EQ(mtx2.fOverwintered, mtx.fOverwintered); + EXPECT_EQ(mtx2.nVersionGroupId, mtx.nVersionGroupId); + EXPECT_EQ(mtx2.nExpiryHeight, mtx.nExpiryHeight); + EXPECT_TRUE(mtx2.GetHash() == mtx.GetHash()); + + // Check assignment of overwinter fields + CTransaction tx2 = tx; + EXPECT_EQ(tx2.nVersion, mtx.nVersion); + EXPECT_EQ(tx2.fOverwintered, mtx.fOverwintered); + EXPECT_EQ(tx2.nVersionGroupId, mtx.nVersionGroupId); + EXPECT_EQ(tx2.nExpiryHeight, mtx.nExpiryHeight); + EXPECT_TRUE(tx2 == tx); +} + +TEST(checktransaction_tests, OverwinterSerialization) { + CMutableTransaction mtx; + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 99; + + // Check round-trip serialization and deserialization from mtx to tx. + { + CDataStream ss(SER_DISK, PROTOCOL_VERSION); + ss << mtx; + CTransaction tx; + ss >> tx; + EXPECT_EQ(mtx.nVersion, tx.nVersion); + EXPECT_EQ(mtx.fOverwintered, tx.fOverwintered); + EXPECT_EQ(mtx.nVersionGroupId, tx.nVersionGroupId); + EXPECT_EQ(mtx.nExpiryHeight, tx.nExpiryHeight); + + EXPECT_EQ(mtx.GetHash(), CMutableTransaction(tx).GetHash()); + EXPECT_EQ(tx.GetHash(), CTransaction(mtx).GetHash()); + } + + // Also check mtx to mtx + { + CDataStream ss(SER_DISK, PROTOCOL_VERSION); + ss << mtx; + CMutableTransaction mtx2; + ss >> mtx2; + EXPECT_EQ(mtx.nVersion, mtx2.nVersion); + EXPECT_EQ(mtx.fOverwintered, mtx2.fOverwintered); + EXPECT_EQ(mtx.nVersionGroupId, mtx2.nVersionGroupId); + EXPECT_EQ(mtx.nExpiryHeight, mtx2.nExpiryHeight); + + EXPECT_EQ(mtx.GetHash(), mtx2.GetHash()); + } + + // Also check tx to tx + { + CTransaction tx(mtx); + CDataStream ss(SER_DISK, PROTOCOL_VERSION); + ss << tx; + CTransaction tx2; + ss >> tx2; + EXPECT_EQ(tx.nVersion, tx2.nVersion); + EXPECT_EQ(tx.fOverwintered, tx2.fOverwintered); + EXPECT_EQ(tx.nVersionGroupId, tx2.nVersionGroupId); + EXPECT_EQ(tx.nExpiryHeight, tx2.nExpiryHeight); + + EXPECT_EQ(mtx.GetHash(), CMutableTransaction(tx).GetHash()); + EXPECT_EQ(tx.GetHash(), tx2.GetHash()); + } +} + +TEST(checktransaction_tests, OverwinterDefaultValues) { + // Check default values (this will fail when defaults change; test should then be updated) + CTransaction tx; + EXPECT_EQ(tx.nVersion, 1); + EXPECT_EQ(tx.fOverwintered, false); + EXPECT_EQ(tx.nVersionGroupId, 0); + EXPECT_EQ(tx.nExpiryHeight, 0); +} + +// A valid v3 transaction with no joinsplits +TEST(checktransaction_tests, OverwinterValidTx) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state)); +} + +TEST(checktransaction_tests, OverwinterExpiryHeight) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + { + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state)); + } + + { + mtx.nExpiryHeight = TX_EXPIRY_HEIGHT_THRESHOLD - 1; + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_TRUE(CheckTransactionWithoutProofVerification(tx, state)); + } + + { + mtx.nExpiryHeight = TX_EXPIRY_HEIGHT_THRESHOLD; + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-expiry-height-too-high", false)).Times(1); + CheckTransactionWithoutProofVerification(tx, state); + } + + { + mtx.nExpiryHeight = std::numeric_limits::max(); + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-expiry-height-too-high", false)).Times(1); + CheckTransactionWithoutProofVerification(tx, state); + } +} + + +// Test that a Sprout tx with a negative version number is detected +// given the new Overwinter logic +TEST(checktransaction_tests, SproutTxVersionTooLow) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = false; + mtx.nVersion = -1; + + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-version-too-low", false)).Times(1); CheckTransactionWithoutProofVerification(tx, state); } + + + +// Subclass of CTransaction which doesn't call UpdateHash when constructing +// from a CMutableTransaction. This enables us to create a CTransaction +// with bad values which normally trigger an exception during construction. +class UNSAFE_CTransaction : public CTransaction { + public: + UNSAFE_CTransaction(const CMutableTransaction &tx) : CTransaction(tx, true) {} +}; + + +// Test bad Overwinter version number in CheckTransactionWithoutProofVerification +TEST(checktransaction_tests, OverwinterVersionNumberLow) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = true; + mtx.nVersion = OVERWINTER_MIN_TX_VERSION - 1; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + UNSAFE_CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-overwinter-version-too-low", false)).Times(1); + CheckTransactionWithoutProofVerification(tx, state); +} + +// Test bad Overwinter version number in ContextualCheckTransaction +TEST(checktransaction_tests, OverwinterVersionNumberHigh) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = true; + mtx.nVersion = OVERWINTER_MAX_TX_VERSION + 1; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + UNSAFE_CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-overwinter-version-too-high", false)).Times(1); + ContextualCheckTransaction(tx, state, 1, 100); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + +// Test bad Overwinter version group id +TEST(checktransaction_tests, OverwinterBadVersionGroupId) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nExpiryHeight = 0; + mtx.nVersionGroupId = 0x12345678; + + UNSAFE_CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-tx-version-group-id", false)).Times(1); + CheckTransactionWithoutProofVerification(tx, state); +} + +// This tests an Overwinter transaction checked against Sprout +TEST(checktransaction_tests, OverwinterNotActive) { + SelectParams(CBaseChainParams::TESTNET); + + CMutableTransaction mtx = GetValidTransaction(); + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-not-active", false)).Times(1); + ContextualCheckTransaction(tx, state, 1, 100); +} + +// This tests a transaction without the fOverwintered flag set, against the Overwinter consensus rule set. +TEST(checktransaction_tests, OverwinterFlagNotSet) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + CMutableTransaction mtx = GetValidTransaction(); + mtx.fOverwintered = false; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + CTransaction tx(mtx); + MockCValidationState state; + EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "tx-overwinter-flag-not-set", false)).Times(1); + ContextualCheckTransaction(tx, state, 1, 100); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + +// Overwinter (NU0) does not allow soft fork to version 4 Overwintered tx. +TEST(checktransaction_tests, OverwinterInvalidSoftForkVersion) { + CMutableTransaction mtx = GetValidTransaction(); + mtx.fOverwintered = true; + mtx.nVersion = 4; // This is not allowed + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + + CDataStream ss(SER_DISK, PROTOCOL_VERSION); + try { + ss << mtx; + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format'"; + } + catch(std::ios_base::failure & err) { + EXPECT_THAT(err.what(), testing::HasSubstr(std::string("Unknown transaction format"))); + } + catch(...) { + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format', got some other exception"; + } +} + + +// Test CreateNewContextualCMutableTransaction sets default values based on height +TEST(checktransaction_tests, OverwinteredContextualCreateTx) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& consensusParams = Params().GetConsensus(); + int activationHeight = 5; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, activationHeight); + + { + CMutableTransaction mtx = CreateNewContextualCMutableTransaction( + consensusParams, activationHeight - 1); + + EXPECT_EQ(mtx.nVersion, 1); + EXPECT_EQ(mtx.fOverwintered, false); + EXPECT_EQ(mtx.nVersionGroupId, 0); + EXPECT_EQ(mtx.nExpiryHeight, 0); + } + + // Overwinter activates + { + CMutableTransaction mtx = CreateNewContextualCMutableTransaction( + consensusParams, activationHeight ); + + EXPECT_EQ(mtx.nVersion, 3); + EXPECT_EQ(mtx.fOverwintered, true); + EXPECT_EQ(mtx.nVersionGroupId, OVERWINTER_VERSION_GROUP_ID); + EXPECT_EQ(mtx.nExpiryHeight, 0); + } + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + +// Test a v1 transaction which has a malformed header, perhaps modified in-flight +TEST(checktransaction_tests, BadTxReceivedOverNetwork) +{ + // First four bytes <01 00 00 00> have been modified to be (-4 as an int32) + std::string goodPrefix = "01000000"; + std::string badPrefix = "fcffffff"; + std::string hexTx = "0176c6541939b95f8d8b7779a77a0863b2a0267e281a050148326f0ea07c3608fb000000006a47304402207c68117a6263486281af0cc5d3bee6db565b6dce19ffacc4cb361906eece82f8022007f604382dee2c1fde41c4e6e7c1ae36cfa28b5b27350c4bfaa27f555529eace01210307ff9bef60f2ac4ceb1169a9f7d2c773d6c7f4ab6699e1e5ebc2e0c6d291c733feffffff02c0d45407000000001976a9145eaaf6718517ec8a291c6e64b16183292e7011f788ac5ef44534000000001976a91485e12fb9967c96759eae1c6b1e9c07ce977b638788acbe000000"; + + // Good v1 tx + { + std::vector txData(ParseHex(goodPrefix + hexTx )); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + ssData >> tx; + EXPECT_EQ(tx.nVersion, 1); + EXPECT_EQ(tx.fOverwintered, false); + } + + // Good v1 mutable tx + { + std::vector txData(ParseHex(goodPrefix + hexTx )); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + CMutableTransaction mtx; + ssData >> mtx; + EXPECT_EQ(mtx.nVersion, 1); + } + + // Bad tx + { + std::vector txData(ParseHex(badPrefix + hexTx )); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + try { + CTransaction tx; + ssData >> tx; + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format'"; + } + catch(std::ios_base::failure & err) { + EXPECT_THAT(err.what(), testing::HasSubstr(std::string("Unknown transaction format"))); + } + catch(...) { + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format', got some other exception"; + } + } + + // Bad mutable tx + { + std::vector txData(ParseHex(badPrefix + hexTx )); + CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); + try { + CMutableTransaction mtx; + ssData >> mtx; + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format'"; + } + catch(std::ios_base::failure & err) { + EXPECT_THAT(err.what(), testing::HasSubstr(std::string("Unknown transaction format"))); + } + catch(...) { + FAIL() << "Expected std::ios_base::failure 'Unknown transaction format', got some other exception"; + } + } +} \ No newline at end of file diff --git a/src/gtest/test_circuit.cpp b/src/gtest/test_circuit.cpp index f8a0416a7..2cc9dbcbb 100644 --- a/src/gtest/test_circuit.cpp +++ b/src/gtest/test_circuit.cpp @@ -7,10 +7,11 @@ #include #include -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" -#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" -#include "libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" +#include +#include +#include +#include + #include "zcash/IncrementalMerkleTree.hpp" using namespace libsnark; diff --git a/src/gtest/test_deprecation.cpp b/src/gtest/test_deprecation.cpp new file mode 100644 index 000000000..eb2d7bfc6 --- /dev/null +++ b/src/gtest/test_deprecation.cpp @@ -0,0 +1,122 @@ +#include +#include + +#include "clientversion.h" +#include "deprecation.h" +#include "init.h" +#include "ui_interface.h" +#include "util.h" +#include "chainparams.h" + +using ::testing::StrictMock; + +static const std::string CLIENT_VERSION_STR = FormatVersion(CLIENT_VERSION); +extern std::atomic fRequestShutdown; + +class MockUIInterface { +public: + MOCK_METHOD3(ThreadSafeMessageBox, bool(const std::string& message, + const std::string& caption, + unsigned int style)); +}; + +static bool ThreadSafeMessageBox(MockUIInterface *mock, + const std::string& message, + const std::string& caption, + unsigned int style) +{ + return mock->ThreadSafeMessageBox(message, caption, style); +} + +class DeprecationTest : public ::testing::Test { +protected: + virtual void SetUp() { + uiInterface.ThreadSafeMessageBox.disconnect_all_slots(); + uiInterface.ThreadSafeMessageBox.connect(boost::bind(ThreadSafeMessageBox, &mock_, _1, _2, _3)); + SelectParams(CBaseChainParams::MAIN); + + } + + virtual void TearDown() { + fRequestShutdown = false; + mapArgs.clear(); + } + + StrictMock mock_; +}; + +TEST_F(DeprecationTest, NonDeprecatedNodeKeepsRunning) { + EXPECT_FALSE(ShutdownRequested()); + EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT - 1); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, NodeNearDeprecationIsWarned) { + EXPECT_FALSE(ShutdownRequested()); + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_WARNING)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, NodeNearDeprecationWarningIsNotDuplicated) { + EXPECT_FALSE(ShutdownRequested()); + EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT + 1); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, NodeNearDeprecationWarningIsRepeatedOnStartup) { + EXPECT_FALSE(ShutdownRequested()); + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_WARNING)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT - DEPRECATION_WARN_LIMIT + 1, true); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeShutsDown) { + EXPECT_FALSE(ShutdownRequested()); + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT); + EXPECT_TRUE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeErrorIsNotDuplicated) { + EXPECT_FALSE(ShutdownRequested()); + EnforceNodeDeprecation(DEPRECATION_HEIGHT + 1); + EXPECT_TRUE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeErrorIsRepeatedOnStartup) { + EXPECT_FALSE(ShutdownRequested()); + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT + 1, true); + EXPECT_TRUE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeShutsDownIfOldVersionDisabled) { + EXPECT_FALSE(ShutdownRequested()); + mapArgs["-disabledeprecation"] = "1.0.0"; + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT); + EXPECT_TRUE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeKeepsRunningIfCurrentVersionDisabled) { + EXPECT_FALSE(ShutdownRequested()); + mapArgs["-disabledeprecation"] = CLIENT_VERSION_STR; + EXPECT_CALL(mock_, ThreadSafeMessageBox(::testing::_, "", CClientUIInterface::MSG_ERROR)); + EnforceNodeDeprecation(DEPRECATION_HEIGHT); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeIgnoredOnRegtest) { + SelectParams(CBaseChainParams::REGTEST); + EXPECT_FALSE(ShutdownRequested()); + EnforceNodeDeprecation(DEPRECATION_HEIGHT+1); + EXPECT_FALSE(ShutdownRequested()); +} + +TEST_F(DeprecationTest, DeprecatedNodeIgnoredOnTestnet) { + SelectParams(CBaseChainParams::TESTNET); + EXPECT_FALSE(ShutdownRequested()); + EnforceNodeDeprecation(DEPRECATION_HEIGHT+1); + EXPECT_FALSE(ShutdownRequested()); +} \ No newline at end of file diff --git a/src/gtest/test_foundersreward.cpp b/src/gtest/test_foundersreward.cpp index ea6fb0ab1..63649cee1 100644 --- a/src/gtest/test_foundersreward.cpp +++ b/src/gtest/test_foundersreward.cpp @@ -81,6 +81,8 @@ TEST(founders_reward_test, create_testnet_2of3multisig) { std::cout << s << std::endl; pWallet->Flush(true); + + ECC_Stop(); } #endif diff --git a/src/gtest/test_httprpc.cpp b/src/gtest/test_httprpc.cpp new file mode 100644 index 000000000..c630973fb --- /dev/null +++ b/src/gtest/test_httprpc.cpp @@ -0,0 +1,62 @@ +#include +#include + +#include "httprpc.cpp" +#include "httpserver.h" + +using ::testing::Return; + +class MockHTTPRequest : public HTTPRequest { +public: + MOCK_METHOD0(GetPeer, CService()); + MOCK_METHOD0(GetRequestMethod, HTTPRequest::RequestMethod()); + MOCK_METHOD1(GetHeader, std::pair(const std::string& hdr)); + MOCK_METHOD2(WriteHeader, void(const std::string& hdr, const std::string& value)); + MOCK_METHOD2(WriteReply, void(int nStatus, const std::string& strReply)); + + MockHTTPRequest() : HTTPRequest(nullptr) {} + void CleanUp() { + // So the parent destructor doesn't try to send a reply + replySent = true; + } +}; + +TEST(HTTPRPC, FailsOnGET) { + MockHTTPRequest req; + EXPECT_CALL(req, GetRequestMethod()) + .WillRepeatedly(Return(HTTPRequest::GET)); + EXPECT_CALL(req, WriteReply(HTTP_BAD_METHOD, "JSONRPC server handles only POST requests")) + .Times(1); + EXPECT_FALSE(HTTPReq_JSONRPC(&req, "")); + req.CleanUp(); +} + +TEST(HTTPRPC, FailsWithoutAuthHeader) { + MockHTTPRequest req; + EXPECT_CALL(req, GetRequestMethod()) + .WillRepeatedly(Return(HTTPRequest::POST)); + EXPECT_CALL(req, GetHeader("authorization")) + .WillRepeatedly(Return(std::make_pair(false, ""))); + EXPECT_CALL(req, WriteHeader("WWW-Authenticate", "Basic realm=\"jsonrpc\"")) + .Times(1); + EXPECT_CALL(req, WriteReply(HTTP_UNAUTHORIZED, "")) + .Times(1); + EXPECT_FALSE(HTTPReq_JSONRPC(&req, "")); + req.CleanUp(); +} + +TEST(HTTPRPC, FailsWithBadAuth) { + MockHTTPRequest req; + EXPECT_CALL(req, GetRequestMethod()) + .WillRepeatedly(Return(HTTPRequest::POST)); + EXPECT_CALL(req, GetHeader("authorization")) + .WillRepeatedly(Return(std::make_pair(true, "Basic spam:eggs"))); + EXPECT_CALL(req, GetPeer()) + .WillRepeatedly(Return(CService("127.0.0.1:1337"))); + EXPECT_CALL(req, WriteHeader("WWW-Authenticate", "Basic realm=\"jsonrpc\"")) + .Times(1); + EXPECT_CALL(req, WriteReply(HTTP_UNAUTHORIZED, "")) + .Times(1); + EXPECT_FALSE(HTTPReq_JSONRPC(&req, "")); + req.CleanUp(); +} diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 17ac7ecb2..979d0d518 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -5,6 +5,7 @@ #include #include "zcash/prf.h" +#include "util.h" #include "zcash/JoinSplit.hpp" #include "zcash/Note.hpp" @@ -13,6 +14,8 @@ using namespace libzcash; +extern ZCJoinSplit* params; + void test_full_api(ZCJoinSplit* js) { // Create verification context. @@ -86,7 +89,7 @@ void test_full_api(ZCJoinSplit* js) // Recipient should decrypt // Now the recipient should spend the money again auto h_sig = js->h_sig(randomSeed, nullifiers, pubKeyHash); - ZCNoteDecryption decryptor(recipient_key.viewing_key()); + ZCNoteDecryption decryptor(recipient_key.receiving_key()); auto note_pt = NotePlaintext::decrypt( decryptor, @@ -219,8 +222,6 @@ void invokeAPIFailure( TEST(joinsplit, h_sig) { - auto js = ZCJoinSplit::Unopened(); - /* // by Taylor Hornby @@ -284,7 +285,7 @@ for test_input in TEST_VECTORS: }; BOOST_FOREACH(std::vector& v, tests) { - auto expected = js->h_sig( + auto expected = ZCJoinSplit::h_sig( uint256S(v[0]), {uint256S(v[1]), uint256S(v[2])}, uint256S(v[3]) @@ -292,8 +293,6 @@ for test_input in TEST_VECTORS: EXPECT_EQ(expected, uint256S(v[4])); } - - delete js; } void increment_note_witnesses( @@ -311,8 +310,6 @@ void increment_note_witnesses( TEST(joinsplit, full_api_test) { - auto js = ZCJoinSplit::Generate(); - { std::vector witnesses; ZCIncrementalMerkleTree tree; @@ -331,7 +328,7 @@ TEST(joinsplit, full_api_test) increment_note_witnesses(note5.cm(), witnesses, tree); // Should work - invokeAPI(js, + invokeAPI(params, { JSInput(), JSInput() @@ -345,7 +342,7 @@ TEST(joinsplit, full_api_test) tree.root()); // lhs > MAX_MONEY - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(), JSInput() @@ -360,7 +357,7 @@ TEST(joinsplit, full_api_test) "nonsensical vpub_old value"); // rhs > MAX_MONEY - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(), JSInput() @@ -375,7 +372,7 @@ TEST(joinsplit, full_api_test) "nonsensical vpub_new value"); // input witness for the wrong element - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(witnesses[0], note1, sk), JSInput() @@ -391,7 +388,7 @@ TEST(joinsplit, full_api_test) // input witness doesn't match up with // real root - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(witnesses[1], note1, sk), JSInput() @@ -406,7 +403,7 @@ TEST(joinsplit, full_api_test) "joinsplit not anchored to the correct root"); // input is in the tree now! this should work - invokeAPI(js, + invokeAPI(params, { JSInput(witnesses[1], note1, sk), JSInput() @@ -420,7 +417,7 @@ TEST(joinsplit, full_api_test) tree.root()); // Wrong secret key - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(witnesses[1], note1, SpendingKey::random()), JSInput() @@ -435,7 +432,7 @@ TEST(joinsplit, full_api_test) "input note not authorized to spend with given key"); // Absurd input value - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(witnesses[3], note3, sk), JSInput() @@ -450,7 +447,7 @@ TEST(joinsplit, full_api_test) "nonsensical input note value"); // Absurd total input value - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(witnesses[4], note4, sk), JSInput(witnesses[5], note5, sk) @@ -465,7 +462,7 @@ TEST(joinsplit, full_api_test) "nonsensical left hand size of joinsplit balance"); // Absurd output value - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(), JSInput() @@ -480,7 +477,7 @@ TEST(joinsplit, full_api_test) "nonsensical output value"); // Absurd total output value - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(), JSInput() @@ -495,7 +492,7 @@ TEST(joinsplit, full_api_test) "nonsensical right hand side of joinsplit balance"); // Absurd total output value - invokeAPIFailure(js, + invokeAPIFailure(params, { JSInput(), JSInput() @@ -510,22 +507,7 @@ TEST(joinsplit, full_api_test) "invalid joinsplit balance"); } - test_full_api(js); - - js->saveProvingKey("./zcashTest.pk"); - js->saveVerifyingKey("./zcashTest.vk"); - - delete js; - - js = ZCJoinSplit::Unopened(); - - js->setProvingKeyPath("./zcashTest.pk"); - js->loadProvingKey(); - js->loadVerifyingKey("./zcashTest.vk"); - - test_full_api(js); - - delete js; + test_full_api(params); } TEST(joinsplit, note_plaintexts) diff --git a/src/gtest/test_keystore.cpp b/src/gtest/test_keystore.cpp index e94aea53e..76b57cd9f 100644 --- a/src/gtest/test_keystore.cpp +++ b/src/gtest/test_keystore.cpp @@ -43,7 +43,64 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) { keyStore.AddSpendingKey(sk); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); +} + +TEST(keystore_tests, StoreAndRetrieveViewingKey) { + CBasicKeyStore keyStore; + libzcash::ViewingKey vkOut; + libzcash::SpendingKey skOut; + ZCNoteDecryption decOut; + + auto sk = libzcash::SpendingKey::random(); + auto vk = sk.viewing_key(); + auto addr = sk.address(); + + // Sanity-check: we can't get a viewing key we haven't added + EXPECT_FALSE(keyStore.HaveViewingKey(addr)); + EXPECT_FALSE(keyStore.GetViewingKey(addr, vkOut)); + + // and we shouldn't have a spending key or decryptor either + EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); + EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); + EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut)); + + // and we can't find it in our list of addresses + std::set addresses; + keyStore.GetPaymentAddresses(addresses); + EXPECT_FALSE(addresses.count(addr)); + + keyStore.AddViewingKey(vk); + EXPECT_TRUE(keyStore.HaveViewingKey(addr)); + EXPECT_TRUE(keyStore.GetViewingKey(addr, vkOut)); + EXPECT_EQ(vk, vkOut); + + // We should still not have the spending key... + EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); + EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); + + // ... but we should have a decryptor + EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); + EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); + + // ... and we should find it in our list of addresses + addresses.clear(); + keyStore.GetPaymentAddresses(addresses); + EXPECT_TRUE(addresses.count(addr)); + + keyStore.RemoveViewingKey(vk); + EXPECT_FALSE(keyStore.HaveViewingKey(addr)); + EXPECT_FALSE(keyStore.GetViewingKey(addr, vkOut)); + EXPECT_FALSE(keyStore.HaveSpendingKey(addr)); + EXPECT_FALSE(keyStore.GetSpendingKey(addr, skOut)); + addresses.clear(); + keyStore.GetPaymentAddresses(addresses); + EXPECT_FALSE(addresses.count(addr)); + + // We still have a decryptor because those are cached in memory + // (and also we only remove viewing keys when adding a spending key) + EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); + EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); } #ifdef ENABLE_WALLET @@ -72,13 +129,13 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) { ASSERT_TRUE(keyStore.GetSpendingKey(addr, keyOut)); ASSERT_EQ(sk, keyOut); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); ASSERT_TRUE(keyStore.EncryptKeys(vMasterKey)); ASSERT_TRUE(keyStore.HaveSpendingKey(addr)); ASSERT_FALSE(keyStore.GetSpendingKey(addr, keyOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk.receiving_key()), decOut); // Unlocking with a random key should fail uint256 r2 {GetRandHash()}; @@ -109,19 +166,19 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) { ASSERT_TRUE(keyStore.GetSpendingKey(addr2, keyOut)); ASSERT_EQ(sk2, keyOut); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); ASSERT_TRUE(keyStore.Lock()); ASSERT_TRUE(keyStore.HaveSpendingKey(addr2)); ASSERT_FALSE(keyStore.GetSpendingKey(addr2, keyOut)); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); ASSERT_TRUE(keyStore.Unlock(vMasterKey)); ASSERT_TRUE(keyStore.GetSpendingKey(addr2, keyOut)); ASSERT_EQ(sk2, keyOut); EXPECT_TRUE(keyStore.GetNoteDecryptor(addr2, decOut)); - EXPECT_EQ(ZCNoteDecryption(sk2.viewing_key()), decOut); + EXPECT_EQ(ZCNoteDecryption(sk2.receiving_key()), decOut); keyStore.GetPaymentAddresses(addrs); ASSERT_EQ(2, addrs.size()); diff --git a/src/gtest/test_mempool.cpp b/src/gtest/test_mempool.cpp index d73b99d11..9256f196a 100644 --- a/src/gtest/test_mempool.cpp +++ b/src/gtest/test_mempool.cpp @@ -1,89 +1,263 @@ #include #include - + +#include "consensus/upgrades.h" +#include "consensus/validation.h" #include "core_io.h" +#include "main.h" #include "primitives/transaction.h" #include "txmempool.h" #include "policy/fees.h" +#include "util.h" + +// Implementation is in test_checktransaction.cpp +extern CMutableTransaction GetValidTransaction(); + +// Fake the input of transaction 5295156213414ed77f6e538e7e8ebe14492156906b9fe995b242477818789364 +// - 532639cc6bebed47c1c69ae36dd498c68a012e74ad12729adbd3dbb56f8f3f4a, 0 +class FakeCoinsViewDB : public CCoinsView { +public: + FakeCoinsViewDB() {} + + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { + return false; + } + + bool GetNullifier(const uint256 &nf) const { + return false; + } + + bool GetCoins(const uint256 &txid, CCoins &coins) const { + CTxOut txOut; + txOut.nValue = 4288035; + CCoins newCoins; + newCoins.vout.resize(2); + newCoins.vout[0] = txOut; + newCoins.nHeight = 92045; + coins.swap(newCoins); + return true; + } + + bool HaveCoins(const uint256 &txid) const { + return true; + } + + uint256 GetBestBlock() const { + uint256 a; + return a; + } + + uint256 GetBestAnchor() const { + uint256 a; + return a; + } + + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashAnchor, + CAnchorsMap &mapAnchors, + CNullifiersMap &mapNullifiers) { + return false; + } + + bool GetStats(CCoinsStats &stats) const { + return false; + } +}; + +TEST(Mempool, PriorityStatsDoNotCrash) { + // Test for security issue 2017-04-11.a + // https://z.cash/blog/security-announcement-2017-04-12.html + + // Trigger transaction in block 92046 + std::string triggerTx = "02000000014a3f8f6fb5dbd3db9a7212ad742e018ac698d46de39ac6c147edeb6bcc392653000000006b483045022100da0514afd80d3bbd0743458efe3b2abd18f727b4268b124c3885094c26ea09cd02207d37d7934ec90618fc5a345cb2a6d1755d8b1a432ea1df517a85e36628449196012103e9b41072e9d2cbe04e6b22a6ac4862ec3f5a76b3823b071ded0dfd5455a0803fffffffff000000000001236e4100000000000000000000000000cf592f6776810cf9fb961d80e683f5529a6b34894b00446c396022512a02dc2e96918294bffdc988a2627d9b12a9f3176b671e286fc62e3c7441cf35ea5e03d561bd5817ca5827cb2761f88dde280a6da5281af2cc69053816f31abd2170722f72c258c7c6b865c97ff8ae53b697f3b77c239a73e1d0296c2c73d21c3b50059d82866cf9f6e2f5dbbf9b4de9caa3cf836080373311978e1f1b1150ce564336ebf0fd502c2e783ff23252fba4efbb110c28c4fbe31efb6a67bc24c0ad8fd8346c5c9ed1791b555b3e43a309aa8d855a294847368ebdf30365d4dfa9b25dd8ed7adf272ecc08f4756fb9d93b8e20d45548dd4aeab6abb76a2081b6e36a9af9d38ebae378df422f40589769c07a3c12e5da253330314cbc4beaa863fac7ab10055d0310089a44c45179a39b2c4e210cec2e053f54983d744abed49f66959f45785ea90325a310fba15f946e245a0e64caec303f2a3e1d457e3e3ca5d892956c1a93b05e0b0373cf862d7bbb5908148b475c03eec96c9b9ecc7d2d78716d2c2e8ccf96175b25738dfb5b0d356a7e30604ee014c6be1db5e43af0fa6ad3f4e917a9f84b4d6f030cad0ffe0738e1effe570b0552b407ca9c26023b74b99f431cc28b79116f717703158404e343b1b47a0556f593441dc64758930f19e84d5ee468fd9a7958c6c63503054f60680f7147e88bf6da65415450230ef7437481023fc5d94872d5aa18bf3b0212b4c0d938e6c84debb8a4e65f99970c59193873a72b2440f19a652073abd960021bfef4e1e52b8f353c6e517bb97053afd4c8035defc27c3fd16faba5bc924a4179f69cfdcdb82253b5f6472a99d4b78ad2c6c18c45ed4dda5bf2adc019c99b55702f4e7b3fcaeb6f3b84ad411d36e901cba9d49ac1d6b916aa88794fb23501aeb0c585cbc2bed952846f41a03bd5c74dfe004e7ac21f7a20d32b009ccf6f70b3e577d25c679421225522b6290d5fa00a5d9a02b97a62aab60e040a03efa946d87c5e65dbf10d66df5b0834c262c31c23f3c2643451e614695003fb3a95bf21444bebb45cdcb8169245e34a76f754c89c3a90f36598a71ef4645eef4c82f1fb322536097fcf0cbe061e80ae887dbb88d8ed910be9ef18b8794930addab1a140b16c4b50f93926b1e5df03ee6e4b5ec6d7f0ed49fbbae50330ae94c5ae9182f4b58870022e423e7d80adccdb90680f7a7fe11a4ed4fe005a0af2d22bf9e7d1bef7caf4f37f5777e4aa6c9b9ea44f5973575c20fb3482fe357c19fc0c20594f492f5694e3e8eb3599e968fd23b5bdd6c4bf5aee1374b38aafe59dd5af83011e642a9427b5ff03e7a4cce92ee201a0fac0acb69d6ad3b7e4c26dfefaa53a737889e759c4b5695c1a7fd5d988e531acf66dae5067f252a25a102d92916b2d84c730645e15a78d3dce1c787634f6f7323cb949a5b6ad004e208cb8c6b734761629c13b9974dc80b082f83357f3bc703d835acbbf72aba225ffe69396c151d2646fac9bd1acc184dd047ebfaadc6b60a9185ce80c7bc8ac5dbb2219cbc0d35af91673b95d28335f0ee2774b8084871d54ca8eab3a285e4b4adf3f34b4263d67474bb5de2e1e37aa7a4ecbd5b49575caaa9e7208c2b9871946b11f2c54cd1ca7660dff44cf206e7da46ab57dd49ec0aa06ded7980f1557cc7c84023690b4df77f26d6b4eff7553b9a8628c28e8e5c38c6170bc61af0969b072586fa740f68ab33c0f62d0507cc8fe41c680b2f077e49cc2691048006311b46cd5ed18e63089f11c115b797ed5fbcd86836a4da2ab90a00745077f2f13bc9e390fc2f92b941d4fb70a3f098548953566141670317fc17e0ba81e98b8a94919992fb008c5480f4018f3a1ea673fe94a6ba3363656a944855d7c799ccb73d95d4ed6ce04c26f79c4cf79f883f0f810519f28eabe8cf6d833f24227f5074763c7b80f1431e5463cc07eff2f1d6cbfaf0411d38e62528a39b093ed7b51fa8c1008e5c1ce4bf39e67b1703554cefef44b71457bfddf43d23a54fa0145fa0e716d02a5304d85345a2b4ebf98c5010d0df468c8cbfc2db22083b0f5a74d4324ee74b46daa5ab70f2575ef5390e6aa2acb8d3b3eb2065e8c06fd6276aca283f5850e7a8b4da37455430df55621e4af59bb355ba2db0ac6cae6ceed2f538ec8c928ee895bd190fd9c1dff4956bad27d567023bc847dd64d83bac399f8d10248a077c9b2f50d5dda4789e09eae4ed8609da085b6370f6529f3c7b8b13442f9a1cc93565734a81c38c6360235ba23ddf87d1b44413c24b363552a322b01d88d1cae6c5ccd88f8cef15776035934fd24adce913282983d9b55181b382ed61242fb4a5e459c3cad8d38626ef8ccdccb9899d5962dec3f3cc2422f109d902e764186cf166ed88c383f428f195dd5fec4f781bcd2308dec66927f41c9e06369c6806ed8ec9a59c096b29b2a74dc85f4f7cd77a23650c0662b5c2602ef5e41cdc13d16074500aac461f823e3bba7178bcffa000db4ffc9b1618395824ffbee1cad1d9c138a20e0b8bbea2d9a07fade932f81c3daf2d64c4991daf4a1b8b531f9b958a252c6c38cd463342aef3e03e3dae3370581d6cddf5af3ef1585780cf83db1909a1daca156018cd2f7483e53a5fccda49640de60b24523617c7ae84ec5fa987ba8a108"; + CTransaction tx; + ASSERT_TRUE(DecodeHexTx(tx, triggerTx)); + ASSERT_EQ(tx.GetHash().GetHex(), "5295156213414ed77f6e538e7e8ebe14492156906b9fe995b242477818789364"); + + // Fake its inputs + FakeCoinsViewDB fakeDB; + CCoinsViewCache view(&fakeDB); + + CTxMemPool testPool(CFeeRate(0)); + + // Values taken from core dump (parameters of entry) + CAmount nFees = 0; + int64_t nTime = 0x58e5fed9; + unsigned int nHeight = 92045; + double dPriority = view.GetPriority(tx, nHeight); + + CTxMemPoolEntry entry(tx, nFees, nTime, dPriority, nHeight, true, false, SPROUT_BRANCH_ID); + + // Check it does not crash (ie. the death test fails) + EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(testPool.addUnchecked(tx.GetHash(), entry), ""), ""); - // Fake the input of transaction 5295156213414ed77f6e538e7e8ebe14492156906b9fe995b242477818789364 - // - 532639cc6bebed47c1c69ae36dd498c68a012e74ad12729adbd3dbb56f8f3f4a, 0 - class FakeCoinsViewDB : public CCoinsView { - public: - FakeCoinsViewDB() {} - - bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { - return false; - } - - bool GetNullifier(const uint256 &nf) const { - return false; - } - - bool GetCoins(const uint256 &txid, CCoins &coins) const { - CTxOut txOut; - txOut.nValue = 4288035; - CCoins newCoins; - newCoins.vout.resize(2); - newCoins.vout[0] = txOut; - newCoins.nHeight = 92045; - coins.swap(newCoins); - return true; - } - - bool HaveCoins(const uint256 &txid) const { - return true; - } - - uint256 GetBestBlock() const { - uint256 a; - return a; - } - - uint256 GetBestAnchor() const { - uint256 a; - return a; - } - - bool BatchWrite(CCoinsMap &mapCoins, - const uint256 &hashBlock, - const uint256 &hashAnchor, - CAnchorsMap &mapAnchors, - CNullifiersMap &mapNullifiers) { - return false; - } - - bool GetStats(CCoinsStats &stats) const { - return false; - } - }; - - TEST(Mempool, PriorityStatsDoNotCrash) { - // Test for security issue 2017-04-11.a - // https://z.cash/blog/security-announcement-2017-04-12.html - - // Trigger transaction in block 92046 - std::string triggerTx = "02000000014a3f8f6fb5dbd3db9a7212ad742e018ac698d46de39ac6c147edeb6bcc392653000000006b483045022100da0514afd80d3bbd0743458efe3b2abd18f727b4268b124c3885094c26ea09cd02207d37d7934ec90618fc5a345cb2a6d1755d8b1a432ea1df517a85e36628449196012103e9b41072e9d2cbe04e6b22a6ac4862ec3f5a76b3823b071ded0dfd5455a0803fffffffff000000000001236e4100000000000000000000000000cf592f6776810cf9fb961d80e683f5529a6b34894b00446c396022512a02dc2e96918294bffdc988a2627d9b12a9f3176b671e286fc62e3c7441cf35ea5e03d561bd5817ca5827cb2761f88dde280a6da5281af2cc69053816f31abd2170722f72c258c7c6b865c97ff8ae53b697f3b77c239a73e1d0296c2c73d21c3b50059d82866cf9f6e2f5dbbf9b4de9caa3cf836080373311978e1f1b1150ce564336ebf0fd502c2e783ff23252fba4efbb110c28c4fbe31efb6a67bc24c0ad8fd8346c5c9ed1791b555b3e43a309aa8d855a294847368ebdf30365d4dfa9b25dd8ed7adf272ecc08f4756fb9d93b8e20d45548dd4aeab6abb76a2081b6e36a9af9d38ebae378df422f40589769c07a3c12e5da253330314cbc4beaa863fac7ab10055d0310089a44c45179a39b2c4e210cec2e053f54983d744abed49f66959f45785ea90325a310fba15f946e245a0e64caec303f2a3e1d457e3e3ca5d892956c1a93b05e0b0373cf862d7bbb5908148b475c03eec96c9b9ecc7d2d78716d2c2e8ccf96175b25738dfb5b0d356a7e30604ee014c6be1db5e43af0fa6ad3f4e917a9f84b4d6f030cad0ffe0738e1effe570b0552b407ca9c26023b74b99f431cc28b79116f717703158404e343b1b47a0556f593441dc64758930f19e84d5ee468fd9a7958c6c63503054f60680f7147e88bf6da65415450230ef7437481023fc5d94872d5aa18bf3b0212b4c0d938e6c84debb8a4e65f99970c59193873a72b2440f19a652073abd960021bfef4e1e52b8f353c6e517bb97053afd4c8035defc27c3fd16faba5bc924a4179f69cfdcdb82253b5f6472a99d4b78ad2c6c18c45ed4dda5bf2adc019c99b55702f4e7b3fcaeb6f3b84ad411d36e901cba9d49ac1d6b916aa88794fb23501aeb0c585cbc2bed952846f41a03bd5c74dfe004e7ac21f7a20d32b009ccf6f70b3e577d25c679421225522b6290d5fa00a5d9a02b97a62aab60e040a03efa946d87c5e65dbf10d66df5b0834c262c31c23f3c2643451e614695003fb3a95bf21444bebb45cdcb8169245e34a76f754c89c3a90f36598a71ef4645eef4c82f1fb322536097fcf0cbe061e80ae887dbb88d8ed910be9ef18b8794930addab1a140b16c4b50f93926b1e5df03ee6e4b5ec6d7f0ed49fbbae50330ae94c5ae9182f4b58870022e423e7d80adccdb90680f7a7fe11a4ed4fe005a0af2d22bf9e7d1bef7caf4f37f5777e4aa6c9b9ea44f5973575c20fb3482fe357c19fc0c20594f492f5694e3e8eb3599e968fd23b5bdd6c4bf5aee1374b38aafe59dd5af83011e642a9427b5ff03e7a4cce92ee201a0fac0acb69d6ad3b7e4c26dfefaa53a737889e759c4b5695c1a7fd5d988e531acf66dae5067f252a25a102d92916b2d84c730645e15a78d3dce1c787634f6f7323cb949a5b6ad004e208cb8c6b734761629c13b9974dc80b082f83357f3bc703d835acbbf72aba225ffe69396c151d2646fac9bd1acc184dd047ebfaadc6b60a9185ce80c7bc8ac5dbb2219cbc0d35af91673b95d28335f0ee2774b8084871d54ca8eab3a285e4b4adf3f34b4263d67474bb5de2e1e37aa7a4ecbd5b49575caaa9e7208c2b9871946b11f2c54cd1ca7660dff44cf206e7da46ab57dd49ec0aa06ded7980f1557cc7c84023690b4df77f26d6b4eff7553b9a8628c28e8e5c38c6170bc61af0969b072586fa740f68ab33c0f62d0507cc8fe41c680b2f077e49cc2691048006311b46cd5ed18e63089f11c115b797ed5fbcd86836a4da2ab90a00745077f2f13bc9e390fc2f92b941d4fb70a3f098548953566141670317fc17e0ba81e98b8a94919992fb008c5480f4018f3a1ea673fe94a6ba3363656a944855d7c799ccb73d95d4ed6ce04c26f79c4cf79f883f0f810519f28eabe8cf6d833f24227f5074763c7b80f1431e5463cc07eff2f1d6cbfaf0411d38e62528a39b093ed7b51fa8c1008e5c1ce4bf39e67b1703554cefef44b71457bfddf43d23a54fa0145fa0e716d02a5304d85345a2b4ebf98c5010d0df468c8cbfc2db22083b0f5a74d4324ee74b46daa5ab70f2575ef5390e6aa2acb8d3b3eb2065e8c06fd6276aca283f5850e7a8b4da37455430df55621e4af59bb355ba2db0ac6cae6ceed2f538ec8c928ee895bd190fd9c1dff4956bad27d567023bc847dd64d83bac399f8d10248a077c9b2f50d5dda4789e09eae4ed8609da085b6370f6529f3c7b8b13442f9a1cc93565734a81c38c6360235ba23ddf87d1b44413c24b363552a322b01d88d1cae6c5ccd88f8cef15776035934fd24adce913282983d9b55181b382ed61242fb4a5e459c3cad8d38626ef8ccdccb9899d5962dec3f3cc2422f109d902e764186cf166ed88c383f428f195dd5fec4f781bcd2308dec66927f41c9e06369c6806ed8ec9a59c096b29b2a74dc85f4f7cd77a23650c0662b5c2602ef5e41cdc13d16074500aac461f823e3bba7178bcffa000db4ffc9b1618395824ffbee1cad1d9c138a20e0b8bbea2d9a07fade932f81c3daf2d64c4991daf4a1b8b531f9b958a252c6c38cd463342aef3e03e3dae3370581d6cddf5af3ef1585780cf83db1909a1daca156018cd2f7483e53a5fccda49640de60b24523617c7ae84ec5fa987ba8a108"; - CTransaction tx; - ASSERT_TRUE(DecodeHexTx(tx, triggerTx)); - ASSERT_EQ(tx.GetHash().GetHex(), "5295156213414ed77f6e538e7e8ebe14492156906b9fe995b242477818789364"); - - // Fake its inputs - FakeCoinsViewDB fakeDB; - CCoinsViewCache view(&fakeDB); - - CTxMemPool testPool(CFeeRate(0)); - - // Values taken from core dump (parameters of entry) - CAmount nFees = 0; - int64_t nTime = 0x58e5fed9; - unsigned int nHeight = 92045; - double dPriority = view.GetPriority(tx, nHeight); - - CTxMemPoolEntry entry(tx, nFees, nTime, dPriority, nHeight, true); - - // Check it does not crash (ie. the death test fails) - EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(testPool.addUnchecked(tx.GetHash(), entry), ""), ""); EXPECT_EQ(dPriority, MAX_PRIORITY); } +TEST(Mempool, TxInputLimit) { + SelectParams(CBaseChainParams::TESTNET); + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + + // Create an obviously-invalid transaction + // We intentionally set tx.nVersion = 0 to reliably trigger an error, as + // it's the first check that occurs after the -mempooltxinputlimit check, + // and it means that we don't have to mock out a lot of global state. + CMutableTransaction mtx; + mtx.nVersion = 0; + mtx.vin.resize(10); + + // Check it fails as expected + CValidationState state1; + CTransaction tx1(mtx); + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "bad-txns-version-too-low"); + + // Set a limit + mapArgs["-mempooltxinputlimit"] = "10"; + + // Check it still fails as expected + CValidationState state2; + EXPECT_FALSE(AcceptToMemoryPool(pool, state2, tx1, false, &missingInputs)); + EXPECT_EQ(state2.GetRejectReason(), "bad-txns-version-too-low"); + + // Resize the transaction + mtx.vin.resize(11); + + // Check it now fails due to exceeding the limit + CValidationState state3; + CTransaction tx3(mtx); + EXPECT_FALSE(AcceptToMemoryPool(pool, state3, tx3, false, &missingInputs)); + // The -mempooltxinputlimit check doesn't set a reason + EXPECT_EQ(state3.GetRejectReason(), ""); + + // Clear the limit + mapArgs.erase("-mempooltxinputlimit"); + + // Check it no longer fails due to exceeding the limit + CValidationState state4; + EXPECT_FALSE(AcceptToMemoryPool(pool, state4, tx3, false, &missingInputs)); + EXPECT_EQ(state4.GetRejectReason(), "bad-txns-version-too-low"); +} + +// Valid overwinter v3 format tx gets rejected because overwinter hasn't activated yet. +TEST(Mempool, OverwinterNotActiveYet) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); // no joinsplits + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nExpiryHeight = 0; + CValidationState state1; + + CTransaction tx1(mtx); + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "tx-overwinter-not-active"); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + +// Sprout transaction version 3 when Overwinter is not active: +// 1. pass CheckTransaction (and CheckTransactionWithoutProofVerification) +// 2. pass ContextualCheckTransaction +// 3. fail IsStandardTx +TEST(Mempool, SproutV3TxFailsAsExpected) { + SelectParams(CBaseChainParams::TESTNET); + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); // no joinsplits + mtx.fOverwintered = false; + mtx.nVersion = 3; + CValidationState state1; + CTransaction tx1(mtx); + + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "version"); +} + + +// Sprout transaction version 3 when Overwinter is always active: +// 1. pass CheckTransaction (and CheckTransactionWithoutProofVerification) +// 2. fails ContextualCheckTransaction +TEST(Mempool, SproutV3TxWhenOverwinterActive) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); // no joinsplits + mtx.fOverwintered = false; + mtx.nVersion = 3; + CValidationState state1; + CTransaction tx1(mtx); + + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "tx-overwinter-flag-not-set"); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + +// Sprout transaction with negative version, rejected by the mempool in CheckTransaction +// under Sprout consensus rules, should still be rejected under Overwinter consensus rules. +// 1. fails CheckTransaction (specifically CheckTransactionWithoutProofVerification) +TEST(Mempool, SproutNegativeVersionTxWhenOverwinterActive) { + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + CTxMemPool pool(::minRelayTxFee); + bool missingInputs; + CMutableTransaction mtx = GetValidTransaction(); + mtx.vjoinsplit.resize(0); // no joinsplits + mtx.fOverwintered = false; + + // A Sprout transaction with version -3 is created using Sprout code (as found in Zcashd <= 1.0.14). + // First four bytes of transaction, parsed as an uint32_t, has the value: 0xfffffffd + // This test simulates an Overwinter node receiving this transaction, but incorrectly deserializing the + // transaction due to a (pretend) bug of not detecting the most significant bit, which leads + // to not setting fOverwintered and not masking off the most significant bit of the header field. + // The resulting Sprout tx with nVersion -3 should be rejected by the Overwinter node's mempool. + { + mtx.nVersion = -3; + EXPECT_EQ(mtx.nVersion, static_cast(0xfffffffd)); + + CTransaction tx1(mtx); + EXPECT_EQ(tx1.nVersion, -3); + + CValidationState state1; + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "bad-txns-version-too-low"); + } + + // A Sprout transaction with version -3 created using Overwinter code (as found in Zcashd >= 1.0.15). + // First four bytes of transaction, parsed as an uint32_t, has the value: 0x80000003 + // This test simulates the same pretend bug described above. + // The resulting Sprout tx with nVersion -2147483645 should be rejected by the Overwinter node's mempool. + { + mtx.nVersion = static_cast((1 << 31) | 3); + EXPECT_EQ(mtx.nVersion, static_cast(0x80000003)); + + CTransaction tx1(mtx); + EXPECT_EQ(tx1.nVersion, -2147483645); + + CValidationState state1; + EXPECT_FALSE(AcceptToMemoryPool(pool, state1, tx1, false, &missingInputs)); + EXPECT_EQ(state1.GetRejectReason(), "bad-txns-version-too-low"); + } + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index 6bac9ab3c..d603b0aa6 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -19,10 +19,10 @@ #include "zcash/IncrementalMerkleTree.hpp" #include "zcash/util.h" -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" -#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" -#include "libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" +#include +#include +#include +#include #include diff --git a/src/gtest/test_metrics.cpp b/src/gtest/test_metrics.cpp index c199b323e..143fe46d6 100644 --- a/src/gtest/test_metrics.cpp +++ b/src/gtest/test_metrics.cpp @@ -92,3 +92,44 @@ TEST(Metrics, GetLocalSolPS) { SetMockTime(104); EXPECT_EQ(1, GetLocalSolPS()); } + +TEST(Metrics, EstimateNetHeightInner) { + // Ensure that the (rounded) current height is returned if the tip is current + SetMockTime(15000); + EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); + SetMockTime(15150); + EXPECT_EQ(100, EstimateNetHeightInner(101, 14250, 50, 7500, 0, 150)); + + // Ensure that correct estimates are returned if the tip is in the past + SetMockTime(15300); // Tip is 2 blocks behind + EXPECT_EQ(100, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); + SetMockTime(15900); // Tip is 6 blocks behind + EXPECT_EQ(110, EstimateNetHeightInner(100, 14100, 50, 7500, 0, 150)); + + // Check estimates during resync + SetMockTime(15000); + EXPECT_EQ(100, EstimateNetHeightInner( 0, 0, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner( 7, 600, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner( 8, 600, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(10, 750, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(11, 900, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(20, 2100, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(49, 6450, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(50, 6600, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(51, 6750, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(55, 7350, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(56, 7500, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(57, 7650, 50, 7500, 0, 150)); + EXPECT_EQ(100, EstimateNetHeightInner(75, 10350, 50, 7500, 0, 150)); + + // More complex calculations: + SetMockTime(20000); + // - Checkpoint spacing: 200 + // -> Average spacing: 175 + // -> estimated height: 127 -> 130 + EXPECT_EQ(130, EstimateNetHeightInner(100, 14100, 50, 5250, 0, 150)); + // - Checkpoint spacing: 50 + // -> Average spacing: 100 + // -> estimated height: 153 -> 150 + EXPECT_EQ(150, EstimateNetHeightInner(100, 14100, 50, 12000, 0, 150)); +} diff --git a/src/gtest/test_paymentdisclosure.cpp b/src/gtest/test_paymentdisclosure.cpp new file mode 100644 index 000000000..ddab3c7e6 --- /dev/null +++ b/src/gtest/test_paymentdisclosure.cpp @@ -0,0 +1,212 @@ +#include + +#include "main.h" +#include "utilmoneystr.h" +#include "chainparams.h" +#include "utilstrencodings.h" +#include "zcash/Address.hpp" +#include "wallet/wallet.h" +#include "amount.h" +#include +#include +#include +#include +#include +#include +#include "util.h" + +#include "paymentdisclosure.h" +#include "paymentdisclosuredb.h" + +#include "sodium.h" + +#include +#include +#include + +using namespace std; + +/* + To run tests: + ./zcash-gtest --gtest_filter="paymentdisclosure.*" + + Note: As an experimental feature, writing your own tests may require option flags to be set. + mapArgs["-experimentalfeatures"] = true; + mapArgs["-paymentdisclosure"] = true; +*/ + +#define NUM_TRIES 10000 + +#define DUMP_DATABASE_TO_STDOUT false + +static boost::uuids::random_generator uuidgen; + +static uint256 random_uint256() +{ + uint256 ret; + randombytes_buf(ret.begin(), 32); + return ret; +} + +// Subclass of PaymentDisclosureDB to add debugging methods +class PaymentDisclosureDBTest : public PaymentDisclosureDB { +public: + PaymentDisclosureDBTest(const boost::filesystem::path& dbPath) : PaymentDisclosureDB(dbPath) {} + + void DebugDumpAllStdout() { + ASSERT_NE(db, nullptr); + std::lock_guard guard(lock_); + + // Iterate over each item in the database and print them + leveldb::Iterator* it = db->NewIterator(leveldb::ReadOptions()); + + for (it->SeekToFirst(); it->Valid(); it->Next()) { + cout << it->key().ToString() << " : "; + // << it->value().ToString() << endl; + try { + std::string strValue = it->value().ToString(); + PaymentDisclosureInfo info; + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue >> info; + cout << info.ToString() << std::endl; + } catch (const std::exception& e) { + cout << e.what() << std::endl; + } + } + + if (false == it->status().ok()) { + cerr << "An error was found iterating over the database" << endl; + cerr << it->status().ToString() << endl; + } + + delete it; + } +}; + + + +// This test creates random payment disclosure blobs and checks that they can be +// 1. inserted and retrieved from a database +// 2. serialized and deserialized without corruption +// Note that the zpd: prefix is not part of the payment disclosure blob itself. It is only +// used as convention to improve the user experience when sharing payment disclosure blobs. +TEST(paymentdisclosure, mainnet) { + ECC_Start(); + SelectParams(CBaseChainParams::MAIN); + + boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + boost::filesystem::create_directories(pathTemp); + mapArgs["-datadir"] = pathTemp.string(); + + std::cout << "Test payment disclosure database created in folder: " << pathTemp.native() << std::endl; + + PaymentDisclosureDBTest mydb(pathTemp); + + for (int i=0; i vch(&buffer[0], &buffer[0] + 32); + uint256 joinSplitPrivKey = uint256(vch); + + // Create payment disclosure key and info data to store in test database + size_t js = random_uint256().GetCheapHash() % std::numeric_limits::max(); + uint8_t n = random_uint256().GetCheapHash() % std::numeric_limits::max(); + PaymentDisclosureKey key { random_uint256(), js, n}; + PaymentDisclosureInfo info; + info.esk = random_uint256(); + info.joinSplitPrivKey = joinSplitPrivKey; + info.zaddr = libzcash::SpendingKey::random().address(); + ASSERT_TRUE(mydb.Put(key, info)); + + // Retrieve info from test database into new local variable and test it matches + PaymentDisclosureInfo info2; + ASSERT_TRUE(mydb.Get(key, info2)); + ASSERT_EQ(info, info2); + + // Modify this local variable and confirm it no longer matches + info2.esk = random_uint256(); + info2.joinSplitPrivKey = random_uint256(); + info2.zaddr = libzcash::SpendingKey::random().address(); + ASSERT_NE(info, info2); + + // Using the payment info object, let's create a dummy payload + PaymentDisclosurePayload payload; + payload.version = PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL; + payload.esk = info.esk; + payload.txid = key.hash; + payload.js = key.js; + payload.n = key.n; + payload.message = "random-" + boost::uuids::to_string(uuidgen()); // random message + payload.zaddr = info.zaddr; + + // Serialize and hash the payload to generate a signature + uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0); + + // Compute the payload signature + unsigned char payloadSig[64]; + if (!(crypto_sign_detached(&payloadSig[0], NULL, + dataToBeSigned.begin(), 32, + &buffer[0] // buffer containing both private and public key required + ) == 0)) + { + throw std::runtime_error("crypto_sign_detached failed"); + } + + // Sanity check + if (!(crypto_sign_verify_detached(&payloadSig[0], + dataToBeSigned.begin(), 32, + joinSplitPubKey.begin() + ) == 0)) + { + throw std::runtime_error("crypto_sign_verify_detached failed"); + } + + // Convert signature buffer to boost array + boost::array arrayPayloadSig; + memcpy(arrayPayloadSig.data(), &payloadSig[0], 64); + + // Payment disclosure blob to pass around + PaymentDisclosure pd = {payload, arrayPayloadSig}; + + // Test payment disclosure constructors + PaymentDisclosure pd2(payload, arrayPayloadSig); + ASSERT_EQ(pd, pd2); + PaymentDisclosure pd3(joinSplitPubKey, key, info, payload.message); + ASSERT_EQ(pd, pd3); + + // Verify serialization and deserialization works + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << pd; + std::string ssHexString = HexStr(ss.begin(), ss.end()); + + PaymentDisclosure pdTmp; + CDataStream ssTmp(ParseHex(ssHexString), SER_NETWORK, PROTOCOL_VERSION); + ssTmp >> pdTmp; + ASSERT_EQ(pd, pdTmp); + + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << pdTmp; + std::string ss2HexString = HexStr(ss2.begin(), ss2.end()); + ASSERT_EQ(ssHexString, ss2HexString); + + // Verify marker + ASSERT_EQ(pd.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES); + ASSERT_EQ(pdTmp.payload.marker, PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES); + ASSERT_EQ(0, ssHexString.find("706462ff")); // Little endian encoding of PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES value + + // Sanity check + PaymentDisclosure pdDummy; + ASSERT_NE(pd, pdDummy); + } + +#if DUMP_DATABASE_TO_STDOUT == true + mydb.DebugDumpAllStdout(); +#endif + + ECC_Stop(); +} diff --git a/src/gtest/test_proofs.cpp b/src/gtest/test_proofs.cpp index 49202f1f6..e33b1cc0c 100644 --- a/src/gtest/test_proofs.cpp +++ b/src/gtest/test_proofs.cpp @@ -3,10 +3,9 @@ #include -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" -#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" -#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" +#include +#include +#include using namespace libzcash; @@ -22,6 +21,51 @@ typedef libsnark::default_r1cs_ppzksnark_pp::Fqe_type curve_Fq2; #include "version.h" #include "utilstrencodings.h" +TEST(proofs, g1_pairing_at_infinity) +{ + for (size_t i = 0; i < 100; i++) { + auto r1 = curve_G1::random_element(); + auto r2 = curve_G2::random_element(); + ASSERT_TRUE( + curve_pp::reduced_pairing(curve_G1::zero(), r2) == + curve_GT::one() + ); + ASSERT_TRUE( + curve_pp::final_exponentiation( + curve_pp::double_miller_loop( + curve_pp::precompute_G1(curve_G1::zero()), + curve_pp::precompute_G2(r2), + curve_pp::precompute_G1(curve_G1::zero()), + curve_pp::precompute_G2(r2) + ) + ) == + curve_GT::one() + ); + ASSERT_TRUE( + curve_pp::final_exponentiation( + curve_pp::double_miller_loop( + curve_pp::precompute_G1(r1), + curve_pp::precompute_G2(r2), + curve_pp::precompute_G1(curve_G1::zero()), + curve_pp::precompute_G2(r2) + ) + ) == + curve_pp::reduced_pairing(r1, r2) + ); + ASSERT_TRUE( + curve_pp::final_exponentiation( + curve_pp::double_miller_loop( + curve_pp::precompute_G1(curve_G1::zero()), + curve_pp::precompute_G2(r2), + curve_pp::precompute_G1(r1), + curve_pp::precompute_G2(r2) + ) + ) == + curve_pp::reduced_pairing(r1, r2) + ); + } +} + TEST(proofs, g2_subgroup_check) { // all G2 elements are order r diff --git a/src/gtest/test_transaction.cpp b/src/gtest/test_transaction.cpp index e75588685..cf2394438 100644 --- a/src/gtest/test_transaction.cpp +++ b/src/gtest/test_transaction.cpp @@ -77,7 +77,7 @@ TEST(Transaction, JSDescriptionRandomized) { *params, pubKeyHash, rt, inputs, outputs, inputMap, outputMap, - 0, 0, false, GenZero); + 0, 0, false, nullptr, GenZero); #ifdef __LP64__ // required for building on MacOS boost::array expectedInputMap {1, 0}; @@ -95,7 +95,7 @@ TEST(Transaction, JSDescriptionRandomized) { *params, pubKeyHash, rt, inputs, outputs, inputMap, outputMap, - 0, 0, false, GenMax); + 0, 0, false, nullptr, GenMax); #ifdef __LP64__ // required for building on MacOS boost::array expectedInputMap {0, 1}; diff --git a/src/gtest/test_upgrades.cpp b/src/gtest/test_upgrades.cpp new file mode 100644 index 000000000..1066a28d0 --- /dev/null +++ b/src/gtest/test_upgrades.cpp @@ -0,0 +1,173 @@ +#include + +#include "chainparams.h" +#include "consensus/upgrades.h" + +#include + +class UpgradesTest : public ::testing::Test { +protected: + virtual void SetUp() { + } + + virtual void TearDown() { + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); + } +}; + +TEST_F(UpgradesTest, NetworkUpgradeState) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& params = Params().GetConsensus(); + + // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT + EXPECT_EQ( + NetworkUpgradeState(0, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_DISABLED); + EXPECT_EQ( + NetworkUpgradeState(1000000, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_DISABLED); + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + EXPECT_EQ( + NetworkUpgradeState(0, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_ACTIVE); + EXPECT_EQ( + NetworkUpgradeState(1000000, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_ACTIVE); + + int nActivationHeight = 100; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); + + EXPECT_EQ( + NetworkUpgradeState(0, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_PENDING); + EXPECT_EQ( + NetworkUpgradeState(nActivationHeight - 1, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_PENDING); + EXPECT_EQ( + NetworkUpgradeState(nActivationHeight, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_ACTIVE); + EXPECT_EQ( + NetworkUpgradeState(1000000, params, Consensus::UPGRADE_TESTDUMMY), + UPGRADE_ACTIVE); +} + +TEST_F(UpgradesTest, CurrentEpoch) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& params = Params().GetConsensus(); + auto nBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_TESTDUMMY].nBranchId; + + // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT + EXPECT_EQ(CurrentEpoch(0, params), Consensus::BASE_SPROUT); + EXPECT_EQ(CurrentEpochBranchId(0, params), 0); + EXPECT_EQ(CurrentEpoch(1000000, params), Consensus::BASE_SPROUT); + EXPECT_EQ(CurrentEpochBranchId(1000000, params), 0); + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + EXPECT_EQ(CurrentEpoch(0, params), Consensus::UPGRADE_TESTDUMMY); + EXPECT_EQ(CurrentEpochBranchId(0, params), nBranchId); + EXPECT_EQ(CurrentEpoch(1000000, params), Consensus::UPGRADE_TESTDUMMY); + EXPECT_EQ(CurrentEpochBranchId(1000000, params), nBranchId); + + int nActivationHeight = 100; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); + + EXPECT_EQ(CurrentEpoch(0, params), Consensus::BASE_SPROUT); + EXPECT_EQ(CurrentEpochBranchId(0, params), 0); + EXPECT_EQ(CurrentEpoch(nActivationHeight - 1, params), Consensus::BASE_SPROUT); + EXPECT_EQ(CurrentEpochBranchId(nActivationHeight - 1, params), 0); + EXPECT_EQ(CurrentEpoch(nActivationHeight, params), Consensus::UPGRADE_TESTDUMMY); + EXPECT_EQ(CurrentEpochBranchId(nActivationHeight, params), nBranchId); + EXPECT_EQ(CurrentEpoch(1000000, params), Consensus::UPGRADE_TESTDUMMY); + EXPECT_EQ(CurrentEpochBranchId(1000000, params), nBranchId); +} + +TEST_F(UpgradesTest, IsActivationHeight) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& params = Params().GetConsensus(); + + // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT + EXPECT_FALSE(IsActivationHeight(-1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(0, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1000000, params, Consensus::UPGRADE_TESTDUMMY)); + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + EXPECT_FALSE(IsActivationHeight(-1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_TRUE(IsActivationHeight(0, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1000000, params, Consensus::UPGRADE_TESTDUMMY)); + + int nActivationHeight = 100; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); + + EXPECT_FALSE(IsActivationHeight(-1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(0, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(nActivationHeight - 1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_TRUE(IsActivationHeight(nActivationHeight, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(nActivationHeight + 1, params, Consensus::UPGRADE_TESTDUMMY)); + EXPECT_FALSE(IsActivationHeight(1000000, params, Consensus::UPGRADE_TESTDUMMY)); +} + +TEST_F(UpgradesTest, IsActivationHeightForAnyUpgrade) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& params = Params().GetConsensus(); + + // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(-1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(0, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1000000, params)); + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(-1, params)); + EXPECT_TRUE(IsActivationHeightForAnyUpgrade(0, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1000000, params)); + + int nActivationHeight = 100; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); + + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(-1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(0, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(nActivationHeight - 1, params)); + EXPECT_TRUE(IsActivationHeightForAnyUpgrade(nActivationHeight, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(nActivationHeight + 1, params)); + EXPECT_FALSE(IsActivationHeightForAnyUpgrade(1000000, params)); +} + +TEST_F(UpgradesTest, NextActivationHeight) { + SelectParams(CBaseChainParams::REGTEST); + const Consensus::Params& params = Params().GetConsensus(); + + // Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT + EXPECT_EQ(NextActivationHeight(-1, params), boost::none); + EXPECT_EQ(NextActivationHeight(0, params), boost::none); + EXPECT_EQ(NextActivationHeight(1, params), boost::none); + EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); + + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + EXPECT_EQ(NextActivationHeight(-1, params), boost::none); + EXPECT_EQ(NextActivationHeight(0, params), boost::none); + EXPECT_EQ(NextActivationHeight(1, params), boost::none); + EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); + + int nActivationHeight = 100; + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_TESTDUMMY, nActivationHeight); + + EXPECT_EQ(NextActivationHeight(-1, params), boost::none); + EXPECT_EQ(NextActivationHeight(0, params), nActivationHeight); + EXPECT_EQ(NextActivationHeight(1, params), nActivationHeight); + EXPECT_EQ(NextActivationHeight(nActivationHeight - 1, params), nActivationHeight); + EXPECT_EQ(NextActivationHeight(nActivationHeight, params), boost::none); + EXPECT_EQ(NextActivationHeight(nActivationHeight + 1, params), boost::none); + EXPECT_EQ(NextActivationHeight(1000000, params), boost::none); +} diff --git a/src/gtest/test_validation.cpp b/src/gtest/test_validation.cpp new file mode 100644 index 000000000..db382e96b --- /dev/null +++ b/src/gtest/test_validation.cpp @@ -0,0 +1,152 @@ +#include + +#include "consensus/upgrades.h" +#include "consensus/validation.h" +#include "main.h" +#include "utiltest.h" + +extern ZCJoinSplit* params; + +extern bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos); + +void ExpectOptionalAmount(CAmount expected, boost::optional actual) { + EXPECT_TRUE((bool)actual); + if (actual) { + EXPECT_EQ(expected, *actual); + } +} + +// Fake an empty view +class FakeCoinsViewDB : public CCoinsView { +public: + FakeCoinsViewDB() {} + + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { + return false; + } + + bool GetNullifier(const uint256 &nf) const { + return false; + } + + bool GetCoins(const uint256 &txid, CCoins &coins) const { + return false; + } + + bool HaveCoins(const uint256 &txid) const { + return false; + } + + uint256 GetBestBlock() const { + uint256 a; + return a; + } + + uint256 GetBestAnchor() const { + uint256 a; + return a; + } + + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashAnchor, + CAnchorsMap &mapAnchors, + CNullifiersMap &mapNullifiers) { + return false; + } + + bool GetStats(CCoinsStats &stats) const { + return false; + } +}; + +TEST(Validation, ContextualCheckInputsPassesWithCoinbase) { + // Create fake coinbase transaction + CMutableTransaction mtx; + mtx.vin.resize(1); + CTransaction tx(mtx); + ASSERT_TRUE(tx.IsCoinBase()); + + // Fake an empty view + FakeCoinsViewDB fakeDB; + CCoinsViewCache view(&fakeDB); + + auto consensusBranchId = SPROUT_BRANCH_ID; + CValidationState state; + PrecomputedTransactionData txdata(tx); + EXPECT_TRUE(ContextualCheckInputs(tx, state, view, false, 0, false, txdata, Params(CBaseChainParams::MAIN).GetConsensus(), consensusBranchId)); +} + +TEST(Validation, ReceivedBlockTransactions) { + auto sk = libzcash::SpendingKey::random(); + + // Create a fake genesis block + CBlock block1; + block1.vtx.push_back(GetValidReceive(*params, sk, 5, true)); + block1.hashMerkleRoot = block1.BuildMerkleTree(); + CBlockIndex fakeIndex1 {block1}; + + // Create a fake child block + CBlock block2; + block2.hashPrevBlock = block1.GetHash(); + block2.vtx.push_back(GetValidReceive(*params, sk, 10, true)); + block2.hashMerkleRoot = block2.BuildMerkleTree(); + CBlockIndex fakeIndex2 {block2}; + fakeIndex2.pprev = &fakeIndex1; + + CDiskBlockPos pos1; + CDiskBlockPos pos2; + + // Set initial state of indices + ASSERT_TRUE(fakeIndex1.RaiseValidity(BLOCK_VALID_TREE)); + ASSERT_TRUE(fakeIndex2.RaiseValidity(BLOCK_VALID_TREE)); + EXPECT_TRUE(fakeIndex1.IsValid(BLOCK_VALID_TREE)); + EXPECT_TRUE(fakeIndex2.IsValid(BLOCK_VALID_TREE)); + EXPECT_FALSE(fakeIndex1.IsValid(BLOCK_VALID_TRANSACTIONS)); + EXPECT_FALSE(fakeIndex2.IsValid(BLOCK_VALID_TRANSACTIONS)); + + // Sprout pool values should not be set + EXPECT_FALSE((bool)fakeIndex1.nSproutValue); + EXPECT_FALSE((bool)fakeIndex1.nChainSproutValue); + EXPECT_FALSE((bool)fakeIndex2.nSproutValue); + EXPECT_FALSE((bool)fakeIndex2.nChainSproutValue); + + // Mark the second block's transactions as received first + CValidationState state; + EXPECT_TRUE(ReceivedBlockTransactions(block2, state, &fakeIndex2, pos2)); + EXPECT_FALSE(fakeIndex1.IsValid(BLOCK_VALID_TRANSACTIONS)); + EXPECT_TRUE(fakeIndex2.IsValid(BLOCK_VALID_TRANSACTIONS)); + + // Sprout pool value delta should now be set for the second block, + // but not any chain totals + EXPECT_FALSE((bool)fakeIndex1.nSproutValue); + EXPECT_FALSE((bool)fakeIndex1.nChainSproutValue); + { + SCOPED_TRACE("ExpectOptionalAmount call"); + ExpectOptionalAmount(20, fakeIndex2.nSproutValue); + } + EXPECT_FALSE((bool)fakeIndex2.nChainSproutValue); + + // Now mark the first block's transactions as received + EXPECT_TRUE(ReceivedBlockTransactions(block1, state, &fakeIndex1, pos1)); + EXPECT_TRUE(fakeIndex1.IsValid(BLOCK_VALID_TRANSACTIONS)); + EXPECT_TRUE(fakeIndex2.IsValid(BLOCK_VALID_TRANSACTIONS)); + + // Sprout pool values should now be set for both blocks + { + SCOPED_TRACE("ExpectOptionalAmount call"); + ExpectOptionalAmount(10, fakeIndex1.nSproutValue); + } + { + SCOPED_TRACE("ExpectOptionalAmount call"); + ExpectOptionalAmount(10, fakeIndex1.nChainSproutValue); + } + { + SCOPED_TRACE("ExpectOptionalAmount call"); + ExpectOptionalAmount(20, fakeIndex2.nSproutValue); + } + { + SCOPED_TRACE("ExpectOptionalAmount call"); + ExpectOptionalAmount(30, fakeIndex2.nChainSproutValue); + } +} diff --git a/src/gtest/utils.cpp b/src/gtest/utils.cpp index cf025162c..527e613e2 100644 --- a/src/gtest/utils.cpp +++ b/src/gtest/utils.cpp @@ -1,7 +1,3 @@ -#include "zcash/JoinSplit.hpp" - -ZCJoinSplit* params = ZCJoinSplit::Unopened(); - int GenZero(int n) { return 0; diff --git a/src/hash.h b/src/hash.h index 077155562..06fcced0a 100644 --- a/src/hash.h +++ b/src/hash.h @@ -12,6 +12,8 @@ #include "uint256.h" #include "version.h" +#include "sodium.h" + #include typedef uint256 ChainCode; @@ -150,6 +152,47 @@ public: } }; + +/** A writer stream (for serialization) that computes a 256-bit BLAKE2b hash. */ +class CBLAKE2bWriter +{ +private: + crypto_generichash_blake2b_state state; + +public: + int nType; + int nVersion; + + CBLAKE2bWriter(int nTypeIn, int nVersionIn, const unsigned char* personal) : nType(nTypeIn), nVersion(nVersionIn) { + assert(crypto_generichash_blake2b_init_salt_personal( + &state, + NULL, 0, // No key. + 32, + NULL, // No salt. + personal) == 0); + } + + CBLAKE2bWriter& write(const char *pch, size_t size) { + crypto_generichash_blake2b_update(&state, (const unsigned char*)pch, size); + return (*this); + } + + // invalidates the object + uint256 GetHash() { + uint256 result; + crypto_generichash_blake2b_final(&state, (unsigned char*)&result, 32); + return result; + } + + template + CBLAKE2bWriter& operator<<(const T& obj) { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } +}; + + /** Compute the 256-bit hash of an object's serialization. */ template uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index d6b317537..519798d34 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -17,7 +17,7 @@ static const char *WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. - * re-lock the wellet. + * re-lock the wallet. */ class HTTPRPCTimer : public RPCTimerBase { diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 4215a0f26..59ba7c3bc 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -72,13 +72,35 @@ private: std::deque queue; bool running; size_t maxDepth; + int numThreads; + + /** RAII object to keep track of number of running worker threads */ + class ThreadCounter + { + public: + WorkQueue &wq; + ThreadCounter(WorkQueue &w): wq(w) + { + boost::lock_guard lock(wq.cs); + wq.numThreads += 1; + } + ~ThreadCounter() + { + boost::lock_guard lock(wq.cs); + wq.numThreads -= 1; + wq.cond.notify_all(); + } + }; public: WorkQueue(size_t maxDepth) : running(true), - maxDepth(maxDepth) + maxDepth(maxDepth), + numThreads(0) { } - /* Precondition: worker threads have all stopped */ + /*( Precondition: worker threads have all stopped + * (call WaitExit) + */ ~WorkQueue() { while (!queue.empty()) { @@ -100,6 +122,7 @@ public: /** Thread function */ void Run() { + ThreadCounter count(*this); while (running) { WorkItem* i = 0; { @@ -122,6 +145,13 @@ public: running = false; cond.notify_all(); } + /** Wait for worker threads to exit */ + void WaitExit() + { + boost::unique_lock lock(cs); + while (numThreads > 0) + cond.wait(lock); + } /** Return current depth of queue */ size_t Depth() @@ -155,6 +185,8 @@ static std::vector rpc_allow_subnets; static WorkQueue* workQueue = 0; //! Handlers for (sub)paths std::vector pathHandlers; +//! Bound listening sockets +std::vector boundSockets; /** Check if a network address is allowed to access the HTTP server */ static bool ClientAllowed(const CNetAddr& netaddr) @@ -264,10 +296,17 @@ static void http_request_cb(struct evhttp_request* req, void* arg) } } +/** Callback to reject HTTP requests after shutdown. */ +static void http_reject_request_cb(struct evhttp_request* req, void*) +{ + LogPrint("http", "Rejecting request while shutting down\n"); + evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); +} + /** Event dispatcher thread */ static void ThreadHTTP(struct event_base* base, struct evhttp* http) { - RenameThread("bitcoin-http"); + RenameThread("zcash-http"); LogPrint("http", "Entering http event loop\n"); event_base_dispatch(base); // Event loop will be interrupted by InterruptHTTPServer() @@ -278,7 +317,6 @@ static void ThreadHTTP(struct event_base* base, struct evhttp* http) static bool HTTPBindAddresses(struct evhttp* http) { int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); - int nBound = 0; std::vector > endpoints; // Determine what addresses to bind to @@ -304,19 +342,20 @@ static bool HTTPBindAddresses(struct evhttp* http) // Bind addresses for (std::vector >::iterator i = endpoints.begin(); i != endpoints.end(); ++i) { LogPrint("http", "Binding RPC on address %s port %i\n", i->first, i->second); - if (evhttp_bind_socket(http, i->first.empty() ? NULL : i->first.c_str(), i->second) == 0) { - nBound += 1; + evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle(http, i->first.empty() ? NULL : i->first.c_str(), i->second); + if (bind_handle) { + boundSockets.push_back(bind_handle); } else { LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second); } } - return nBound > 0; + return !boundSockets.empty(); } /** Simple wrapper to set thread name and run work queue */ static void HTTPWorkQueueRun(WorkQueue* queue) { - RenameThread("bitcoin-httpworker"); + RenameThread("zcash-httpworker"); queue->Run(); } @@ -399,23 +438,33 @@ bool InitHTTPServer() return true; } -bool StartHTTPServer(boost::thread_group& threadGroup) +boost::thread threadHTTP; + +bool StartHTTPServer() { LogPrint("http", "Starting HTTP server\n"); int rpcThreads = std::max((long)GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L); LogPrintf("HTTP: starting %d worker threads\n", rpcThreads); - threadGroup.create_thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); + threadHTTP = boost::thread(boost::bind(&ThreadHTTP, eventBase, eventHTTP)); - for (int i = 0; i < rpcThreads; i++) - threadGroup.create_thread(boost::bind(&HTTPWorkQueueRun, workQueue)); + for (int i = 0; i < rpcThreads; i++) { + boost::thread rpc_worker(HTTPWorkQueueRun, workQueue); + rpc_worker.detach(); + } return true; } void InterruptHTTPServer() { LogPrint("http", "Interrupting HTTP server\n"); - if (eventBase) - event_base_loopbreak(eventBase); + if (eventHTTP) { + // Unlisten sockets + BOOST_FOREACH (evhttp_bound_socket *socket, boundSockets) { + evhttp_del_accept_socket(eventHTTP, socket); + } + // Reject requests on current connections + evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); + } if (workQueue) workQueue->Interrupt(); } @@ -423,7 +472,27 @@ void InterruptHTTPServer() void StopHTTPServer() { LogPrint("http", "Stopping HTTP server\n"); - delete workQueue; + if (workQueue) { + LogPrint("http", "Waiting for HTTP worker threads to exit\n"); + workQueue->WaitExit(); + delete workQueue; + } + if (eventBase) { + LogPrint("http", "Waiting for HTTP event thread to exit\n"); + // Exit the event loop as soon as there are no active events. + event_base_loopexit(eventBase, nullptr); + // Give event loop a few seconds to exit (to send back last RPC responses), then break it + // Before this was solved with event_base_loopexit, but that didn't work as expected in + // at least libevent 2.0.21 and always introduced a delay. In libevent + // master that appears to be solved, so in the future that solution + // could be used again (if desirable). + // (see discussion in https://github.com/bitcoin/bitcoin/pull/6990) + if (!threadHTTP.try_join_for(boost::chrono::milliseconds(2000))) { + LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); + event_base_loopbreak(eventBase); + threadHTTP.join(); + } + } if (eventHTTP) { evhttp_free(eventHTTP); eventHTTP = 0; @@ -432,6 +501,7 @@ void StopHTTPServer() event_base_free(eventBase); eventBase = 0; } + LogPrint("http", "Stopped HTTP server\n"); } struct event_base* EventBase() diff --git a/src/httpserver.h b/src/httpserver.h index b377dc19f..93fb5d8d6 100644 --- a/src/httpserver.h +++ b/src/httpserver.h @@ -28,7 +28,7 @@ bool InitHTTPServer(); * This is separate from InitHTTPServer to give users race-condition-free time * to register their handlers between InitHTTPServer and StartHTTPServer. */ -bool StartHTTPServer(boost::thread_group& threadGroup); +bool StartHTTPServer(); /** Interrupt HTTP server threads */ void InterruptHTTPServer(); /** Stop HTTP server */ @@ -56,11 +56,14 @@ class HTTPRequest { private: struct evhttp_request* req; + + // For test access +protected: bool replySent; public: HTTPRequest(struct evhttp_request* req); - ~HTTPRequest(); + virtual ~HTTPRequest(); enum RequestMethod { UNKNOWN, @@ -76,17 +79,17 @@ public: /** Get CService (address:ip) for the origin of the http request. */ - CService GetPeer(); + virtual CService GetPeer(); /** Get request method. */ - RequestMethod GetRequestMethod(); + virtual RequestMethod GetRequestMethod(); /** * Get the request header specified by hdr, or an empty string. * Return an pair (isPresent,string). */ - std::pair GetHeader(const std::string& hdr); + virtual std::pair GetHeader(const std::string& hdr); /** * Read request body. @@ -101,7 +104,7 @@ public: * * @note call this before calling WriteErrorReply or Reply. */ - void WriteHeader(const std::string& hdr, const std::string& value); + virtual void WriteHeader(const std::string& hdr, const std::string& value); /** * Write HTTP reply. @@ -111,7 +114,7 @@ public: * @note Can be called only once. As this will give the request back to the * main thread, do not call any other HTTPRequest methods after calling this. */ - void WriteReply(int nStatus, const std::string& strReply = ""); + virtual void WriteReply(int nStatus, const std::string& strReply = ""); }; /** Event handler closure. diff --git a/src/init.cpp b/src/init.cpp index c6a0248c6..3bacc7087 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -16,6 +16,7 @@ #endif #include "checkpoints.h" #include "compat/sanity.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "httpserver.h" #include "httprpc.h" @@ -44,8 +45,10 @@ #include #endif +#include #include #include +#include #include #include #include @@ -53,12 +56,16 @@ #include #include -#include "libsnark/common/profiling.hpp" +#include #if ENABLE_ZMQ #include "zmq/zmqnotificationinterface.h" #endif +#if ENABLE_PROTON +#include "amqp/amqpnotificationinterface.h" +#endif + using namespace std; extern void ThreadSendAlert(); @@ -74,7 +81,11 @@ bool fFeeEstimatesInitialized = false; static CZMQNotificationInterface* pzmqNotificationInterface = NULL; #endif -#ifdef _WIN32 +#if ENABLE_PROTON +static AMQPNotificationInterface* pAMQPNotificationInterface = NULL; +#endif + +#ifdef WIN32 // Win32 LevelDB doesn't use file descriptors, and the ones used for // accessing block files don't count towards the fd_set size limit // anyway. @@ -153,6 +164,7 @@ public: static CCoinsViewDB *pcoinsdbview = NULL; static CCoinsViewErrorCatcher *pcoinscatcher = NULL; +static boost::scoped_ptr globalVerifyHandle; void Interrupt(boost::thread_group& threadGroup) { @@ -236,7 +248,15 @@ void Shutdown() } #endif -#ifndef _WIN32 +#if ENABLE_PROTON + if (pAMQPNotificationInterface) { + UnregisterValidationInterface(pAMQPNotificationInterface); + delete pAMQPNotificationInterface; + pAMQPNotificationInterface = NULL; + } +#endif + +#ifndef WIN32 try { boost::filesystem::remove(GetPidFile()); } catch (const boost::filesystem::filesystem_error& e) { @@ -250,6 +270,7 @@ void Shutdown() #endif delete pzcashParams; pzcashParams = NULL; + globalVerifyHandle.reset(); ECC_Stop(); LogPrintf("%s: done\n", __func__); } @@ -311,7 +332,7 @@ std::string HelpMessage(HelpMessageMode mode) const bool showDebug = GetBoolArg("-help-debug", false); // When adding new options to the categories, please keep and ensure alphabetical ordering. - // Do not translate _(...) -help-debug options, Many technical terms, and only a very small audience, so is unnecessary stress to translators + // Do not translate _(...) -help-debug options, many technical terms, and only a very small audience, so is unnecessary stress to translators string strUsage = HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); @@ -328,10 +349,13 @@ std::string HelpMessage(HelpMessageMode mode) #endif } strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); + strUsage += HelpMessageOpt("-disabledeprecation=", strprintf(_("Disable block-height node deprecation and automatic shutdown (example: -disabledeprecation=%s)"), + FormatVersion(CLIENT_VERSION))); strUsage += HelpMessageOpt("-exportdir=", _("Specify directory to be used when exporting data")); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + strUsage += HelpMessageOpt("-mempooltxinputlimit=", _("Set the maximum number of transparent inputs in a transaction that the mempool will accept (default: 0 = no limit applied)")); strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef _WIN32 @@ -372,13 +396,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); strUsage += HelpMessageOpt("-torpassword=", _("Tor control port password (default: empty)")); -#ifdef USE_UPNP -#if USE_UPNP - strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening and no -proxy)")); -#else - strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0)); -#endif -#endif strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); @@ -388,16 +405,18 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); if (showDebug) - strUsage += HelpMessageOpt("-mintxfee=", strprintf("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)", - FormatMoney(CWallet::minTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the blockchain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-mintxfee=", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)", + CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), - FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (default: %u)"), DEFAULT_TX_EXPIRY_DELTA)); + strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"), + CURRENCY_UNIT, FormatMoney(maxTxFee))); strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true)); @@ -414,6 +433,14 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-zmqpubrawtx=
", _("Enable publish raw transaction in
")); #endif +#if ENABLE_PROTON + strUsage += HelpMessageGroup(_("AMQP 1.0 notification options:")); + strUsage += HelpMessageOpt("-amqppubhashblock=
", _("Enable publish hash block in
")); + strUsage += HelpMessageOpt("-amqppubhashtx=
", _("Enable publish hash transaction in
")); + strUsage += HelpMessageOpt("-amqppubrawblock=
", _("Enable publish raw block in
")); + strUsage += HelpMessageOpt("-amqppubrawtx=
", _("Enable publish raw transaction in
")); +#endif + strUsage += HelpMessageGroup(_("Debugging/Testing options:")); if (showDebug) { @@ -425,6 +452,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-fuzzmessagestest=", "Randomly fuzz 1 of every network messages"); strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); + strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)"); } string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, " "rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these @@ -440,7 +468,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 0)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to entries (default: %u)", 50000)); } - strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for relaying (default: %s)"), FormatMoney(::minRelayTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"), + CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file")); if (showDebug) { @@ -638,8 +667,7 @@ void ThreadImport(std::vector vImportFiles) bool InitSanityCheck(void) { if(!ECC_InitSanityCheck()) { - InitError("OpenSSL appears to lack support for elliptic curve cryptography. For more " - "information, visit https://en.bitcoin.it/wiki/OpenSSL_and_EC_Libraries"); + InitError("Elliptic curve cryptography sanity check failure. Aborting."); return false; } if (!glibc_sanity_test() || !glibcxx_sanity_test()) @@ -668,18 +696,14 @@ static void ZC_LoadParams() return; } - pzcashParams = ZCJoinSplit::Unopened(); - LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str()); gettimeofday(&tv_start, 0); - pzcashParams->loadVerifyingKey(vk_path.string()); + pzcashParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); gettimeofday(&tv_end, 0); elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000); LogPrintf("Loaded verifying key in %fs seconds.\n", elapsed); - - pzcashParams->setProvingKeyPath(pk_path.string()); } bool AppInitServers(boost::thread_group& threadGroup) @@ -694,7 +718,7 @@ bool AppInitServers(boost::thread_group& threadGroup) return false; if (GetBoolArg("-rest", false) && !StartREST()) return false; - if (!StartHTTPServer(threadGroup)) + if (!StartHTTPServer()) return false; return true; } @@ -773,6 +797,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (mapArgs.count("-developerencryptwallet")) { return InitError(_("Wallet encryption requires -experimentalfeatures.")); } + else if (mapArgs.count("-paymentdisclosure")) { + return InitError(_("Payment disclosure requires -experimentalfeatures.")); + } else if (mapArgs.count("-zmergetoaddress")) { + return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures.")); + } } // Set this early so that parameter interactions go to console @@ -806,19 +835,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); - // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 - // to listen locally, so don't rely on this happening through -listen below. - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); // to protect privacy, do not discover addresses by default if (SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); } if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { - // do not map ports or try to retrieve public IP when not listening (pointless) - if (SoftSetBoolArg("-upnp", false)) - LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); + // do not try to retrieve public IP when not listening (pointless) if (SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); if (SoftSetBoolArg("-listenonion", false)) @@ -899,14 +922,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench.")); // Checkmempool and checkblockindex default to true in regtest mode - mempool.setSanityCheck(GetBoolArg("-checkmempool", chainparams.DefaultConsistencyChecks())); + int ratio = std::min(std::max(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + if (ratio != 0) { + mempool.setSanityCheck(1.0 / ratio); + } fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); fCheckpointsEnabled = GetBoolArg("-checkpoints", true); // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); if (nScriptCheckThreads <= 0) - nScriptCheckThreads += boost::thread::hardware_concurrency(); + nScriptCheckThreads += GetNumCores(); if (nScriptCheckThreads <= 1) nScriptCheckThreads = 0; else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS) @@ -989,6 +1015,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + expiryDelta = GetArg("-txexpirydelta", DEFAULT_TX_EXPIRY_DELTA); bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true); fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); @@ -1014,6 +1041,49 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif + // Default value of 0 for mempooltxinputlimit means no limit is applied + if (mapArgs.count("-mempooltxinputlimit")) { + int64_t limit = GetArg("-mempooltxinputlimit", 0); + if (limit < 0) { + return InitError(_("Mempool limit on transparent inputs to a transaction cannot be negative")); + } else if (limit > 0) { + LogPrintf("Mempool configured to reject transactions with greater than %lld transparent inputs\n", limit); + } + } + + if (!mapMultiArgs["-nuparams"].empty()) { + // Allow overriding network upgrade parameters for testing + if (Params().NetworkIDString() != "regtest") { + return InitError("Network upgrade parameters may only be overridden on regtest."); + } + const vector& deployments = mapMultiArgs["-nuparams"]; + for (auto i : deployments) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, i, boost::is_any_of(":")); + if (vDeploymentParams.size() != 2) { + return InitError("Network upgrade parameters malformed, expecting hexBranchId:activationHeight"); + } + int nActivationHeight; + if (!ParseInt32(vDeploymentParams[1], &nActivationHeight)) { + return InitError(strprintf("Invalid nActivationHeight (%s)", vDeploymentParams[1])); + } + bool found = false; + // Exclude Sprout from upgrades + for (auto i = Consensus::BASE_SPROUT + 1; i < Consensus::MAX_NETWORK_UPGRADES; ++i) + { + if (vDeploymentParams[0].compare(HexInt(NetworkUpgradeInfo[i].nBranchId)) == 0) { + UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex(i), nActivationHeight); + found = true; + LogPrintf("Setting network upgrade activation parameters for %s to height=%d\n", vDeploymentParams[0], nActivationHeight); + break; + } + } + if (!found) { + return InitError(strprintf("Invalid network upgrade (%s)", vDeploymentParams[0])); + } + } + } + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize libsodium @@ -1023,6 +1093,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // Initialize elliptic curve code ECC_Start(); + globalVerifyHandle.reset(new ECCVerifyHandle()); // Sanity check if (!InitSanityCheck()) @@ -1245,6 +1316,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif +#if ENABLE_PROTON + pAMQPNotificationInterface = AMQPNotificationInterface::CreateWithArguments(mapArgs); + + if (pAMQPNotificationInterface) { + + // AMQP support is currently an experimental feature, so fail if user configured AMQP notifications + // without enabling experimental features. + if (!fExperimentalMode) { + return InitError(_("AMQP support requires -experimentalfeatures.")); + } + + RegisterValidationInterface(pAMQPNotificationInterface); + } +#endif + // ********************************************************* Step 7: load block chain fReindex = GetBoolArg("-reindex", false); @@ -1349,6 +1435,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) break; } + if (!fReindex) { + uiInterface.InitMessage(_("Rewinding blocks if needed...")); + if (!RewindBlockIndex(chainparams)) { + strLoadError = _("Unable to rewind the database to a pre-upgrade state. You will need to redownload the blockchain"); + break; + } + } + uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n", @@ -1449,10 +1543,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) InitWarning(msg); } else if (nLoadWalletRet == DB_TOO_NEW) - strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin Core") << "\n"; + strErrors << _("Error loading wallet.dat: Wallet requires newer version of Zcash") << "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) { - strErrors << _("Wallet needed to be rewritten: restart Bitcoin Core to complete") << "\n"; + strErrors << _("Wallet needed to be rewritten: restart Zcash to complete") << "\n"; LogPrintf("%s", strErrors.str()); return InitError(strErrors.str()); } diff --git a/src/key.cpp b/src/key.cpp index 4a6a1d25c..c93f8d15d 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -7,17 +8,152 @@ #include "arith_uint256.h" #include "crypto/common.h" #include "crypto/hmac_sha512.h" -#include "eccryptoverify.h" #include "pubkey.h" #include "random.h" #include -#include "ecwrapper.h" +#include -static secp256k1_context_t* secp256k1_context = NULL; +static secp256k1_context* secp256k1_context_sign = NULL; + +/** These functions are taken from the libsecp256k1 distribution and are very ugly. */ + +/** + * This parses a format loosely based on a DER encoding of the ECPrivateKey type from + * section C.4 of SEC 1 , with the following caveats: + * + * * The octet-length of the SEQUENCE must be encoded as 1 or 2 octets. It is not + * required to be encoded as one octet if it is less than 256, as DER would require. + * * The octet-length of the SEQUENCE must not be greater than the remaining + * length of the key encoding, but need not match it (i.e. the encoding may contain + * junk after the encoded SEQUENCE). + * * The privateKey OCTET STRING is zero-filled on the left to 32 octets. + * * Anything after the encoding of the privateKey OCTET STRING is ignored, whether + * or not it is validly encoded DER. + * + * out32 must point to an output buffer of length at least 32 bytes. + */ +static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { + const unsigned char *end = privkey + privkeylen; + memset(out32, 0, 32); + /* sequence header */ + if (end - privkey < 1 || *privkey != 0x30u) { + return 0; + } + privkey++; + /* sequence length constructor */ + if (end - privkey < 1 || !(*privkey & 0x80u)) { + return 0; + } + size_t lenb = *privkey & ~0x80u; privkey++; + if (lenb < 1 || lenb > 2) { + return 0; + } + if (end - privkey < lenb) { + return 0; + } + /* sequence length */ + size_t len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0u); + privkey += lenb; + if (end - privkey < len) { + return 0; + } + /* sequence element 0: version number (=1) */ + if (end - privkey < 3 || privkey[0] != 0x02u || privkey[1] != 0x01u || privkey[2] != 0x01u) { + return 0; + } + privkey += 3; + /* sequence element 1: octet string, up to 32 bytes */ + if (end - privkey < 2 || privkey[0] != 0x04u) { + return 0; + } + size_t oslen = privkey[1]; + privkey += 2; + if (oslen > 32 || end - privkey < oslen) { + return 0; + } + memcpy(out32 + (32 - oslen), privkey, oslen); + if (!secp256k1_ec_seckey_verify(ctx, out32)) { + memset(out32, 0, 32); + return 0; + } + return 1; +} + +/** + * This serializes to a DER encoding of the ECPrivateKey type from section C.4 of SEC 1 + * . The optional parameters and publicKey fields are + * included. + * + * privkey must point to an output buffer of length at least CKey::PRIVATE_KEY_SIZE bytes. + * privkeylen must initially be set to the size of the privkey buffer. Upon return it + * will be set to the number of bytes used in the buffer. + * key32 must point to a 32-byte raw private key. + */ +static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { + assert(*privkeylen >= CKey::PRIVATE_KEY_SIZE); + secp256k1_pubkey pubkey; + size_t pubkeylen = 0; + if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { + *privkeylen = 0; + return 0; + } + if (compressed) { + static const unsigned char begin[] = { + 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = CPubKey::COMPRESSED_PUBLIC_KEY_SIZE; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + assert(*privkeylen == CKey::COMPRESSED_PRIVATE_KEY_SIZE); + } else { + static const unsigned char begin[] = { + 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, + 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, + 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = CPubKey::PUBLIC_KEY_SIZE; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + assert(*privkeylen == CKey::PRIVATE_KEY_SIZE); + } + return 1; +} bool CKey::Check(const unsigned char *vch) { - return eccrypto::Check(vch); + return secp256k1_ec_seckey_verify(secp256k1_context_sign, vch); } void CKey::MakeNewKey(bool fCompressedIn) { @@ -29,7 +165,7 @@ void CKey::MakeNewKey(bool fCompressedIn) { } bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { - if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) + if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = fCompressedIn; fValid = true; @@ -39,10 +175,11 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) { CPrivKey CKey::GetPrivKey() const { assert(fValid); CPrivKey privkey; - int privkeylen, ret; - privkey.resize(279); - privkeylen = 279; - ret = secp256k1_ec_privkey_export(secp256k1_context, begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed); + int ret; + size_t privkeylen; + privkey.resize(PRIVATE_KEY_SIZE); + privkeylen = PRIVATE_KEY_SIZE; + ret = ec_privkey_export_der(secp256k1_context_sign, (unsigned char*)&privkey[0], &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); assert(ret); privkey.resize(privkeylen); return privkey; @@ -50,11 +187,13 @@ CPrivKey CKey::GetPrivKey() const { CPubKey CKey::GetPubKey() const { assert(fValid); + secp256k1_pubkey pubkey; + size_t clen = CPubKey::PUBLIC_KEY_SIZE; CPubKey result; - int clen = 65; - int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed); - assert((int)result.size() == clen); + int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin()); assert(ret); + secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); + assert(result.size() == clen); assert(result.IsValid()); return result; } @@ -62,12 +201,14 @@ CPubKey CKey::GetPubKey() const { bool CKey::Sign(const uint256 &hash, std::vector& vchSig, uint32_t test_case) const { if (!fValid) return false; - vchSig.resize(72); - int nSigLen = 72; + vchSig.resize(CPubKey::SIGNATURE_SIZE); + size_t nSigLen = CPubKey::SIGNATURE_SIZE; unsigned char extra_entropy[32] = {0}; WriteLE32(extra_entropy, test_case); - int ret = secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); + secp256k1_ecdsa_signature sig; + int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL); assert(ret); + secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, (unsigned char*)&vchSig[0], &nSigLen, &sig); vchSig.resize(nSigLen); return true; } @@ -77,7 +218,7 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const { return false; } unsigned char rnd[8]; - std::string str = "Bitcoin key verification\n"; + std::string str = "Zcash key verification\n"; GetRandBytes(rnd, sizeof(rnd)); uint256 hash; CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize(hash.begin()); @@ -89,9 +230,12 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const { bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) const { if (!fValid) return false; - vchSig.resize(65); + vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE); int rec = -1; - int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec); + secp256k1_ecdsa_recoverable_signature sig; + int ret = secp256k1_ecdsa_sign_recoverable(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, NULL); + assert(ret); + secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, (unsigned char*)&vchSig[1], &rec, &sig); assert(ret); assert(rec != -1); vchSig[0] = 27 + rec + (fCompressed ? 4 : 0); @@ -99,7 +243,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector& vchSig) } bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { - if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size())) + if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), &privkey[0], privkey.size())) return false; fCompressed = vchPubKey.IsCompressed(); fValid = true; @@ -117,15 +261,15 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const LockObject(out); if ((nChild >> 31) == 0) { CPubKey pubkey = GetPubKey(); - assert(pubkey.begin() + 33 == pubkey.end()); + assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE); BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, out); } else { - assert(begin() + 32 == end()); + assert(size() == 32); BIP32Hash(cc, nChild, 0, begin(), out); } memcpy(ccChild.begin(), out+32, 32); memcpy((unsigned char*)keyChild.begin(), begin(), 32); - bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out); + bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context_sign, (unsigned char*)keyChild.begin(), out); UnlockObject(out); keyChild.fCompressed = true; keyChild.fValid = ret; @@ -183,20 +327,16 @@ void CExtKey::Decode(const unsigned char code[74]) { } bool ECC_InitSanityCheck() { - if (!CECKey::SanityCheck()) { - return false; - } CKey key; key.MakeNewKey(true); CPubKey pubkey = key.GetPubKey(); return key.VerifyPubKey(pubkey); } - void ECC_Start() { - assert(secp256k1_context == NULL); + assert(secp256k1_context_sign == NULL); - secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); assert(ctx != NULL); { @@ -209,12 +349,12 @@ void ECC_Start() { UnlockObject(seed); } - secp256k1_context = ctx; + secp256k1_context_sign = ctx; } void ECC_Stop() { - secp256k1_context_t *ctx = secp256k1_context; - secp256k1_context = NULL; + secp256k1_context *ctx = secp256k1_context_sign; + secp256k1_context_sign = NULL; if (ctx) { secp256k1_context_destroy(ctx); diff --git a/src/key.h b/src/key.h index 021eac2a8..c2b75935c 100644 --- a/src/key.h +++ b/src/key.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -15,25 +16,30 @@ #include -/** - * secp256k1: - * const unsigned int PRIVATE_KEY_SIZE = 279; - * const unsigned int PUBLIC_KEY_SIZE = 65; - * const unsigned int SIGNATURE_SIZE = 72; - * - * see www.keylength.com - * script supports up to 75 for single byte push - */ - /** * secure_allocator is defined in allocators.h - * CPrivKey is a serialized private key, with all parameters included (279 bytes) + * CPrivKey is a serialized private key, with all parameters included + * (PRIVATE_KEY_SIZE bytes) */ typedef std::vector > CPrivKey; /** An encapsulated private key. */ class CKey { +public: + /** + * secp256k1: + */ + static const unsigned int PRIVATE_KEY_SIZE = 279; + static const unsigned int COMPRESSED_PRIVATE_KEY_SIZE = 214; + /** + * see www.keylength.com + * script supports up to 75 for single byte push + */ + static_assert( + PRIVATE_KEY_SIZE >= COMPRESSED_PRIVATE_KEY_SIZE, + "COMPRESSED_PRIVATE_KEY_SIZE is larger than PRIVATE_KEY_SIZE"); + private: //! Whether this private key is valid. We check for correctness when modifying the key //! data, so fValid should always correspond to the actual state. diff --git a/src/keystore.cpp b/src/keystore.cpp index f32ba0c32..323fe710c 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -89,6 +89,40 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) LOCK(cs_SpendingKeyStore); auto address = sk.address(); mapSpendingKeys[address] = sk; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.viewing_key()))); + mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key()))); return true; } + +bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk) +{ + LOCK(cs_SpendingKeyStore); + auto address = vk.address(); + mapViewingKeys[address] = vk; + mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc))); + return true; +} + +bool CBasicKeyStore::RemoveViewingKey(const libzcash::ViewingKey &vk) +{ + LOCK(cs_SpendingKeyStore); + mapViewingKeys.erase(vk.address()); + return true; +} + +bool CBasicKeyStore::HaveViewingKey(const libzcash::PaymentAddress &address) const +{ + LOCK(cs_SpendingKeyStore); + return mapViewingKeys.count(address) > 0; +} + +bool CBasicKeyStore::GetViewingKey(const libzcash::PaymentAddress &address, + libzcash::ViewingKey &vkOut) const +{ + LOCK(cs_SpendingKeyStore); + ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address); + if (mi != mapViewingKeys.end()) { + vkOut = mi->second; + return true; + } + return false; +} diff --git a/src/keystore.h b/src/keystore.h index 84595cfb0..b1ad32a42 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -55,12 +55,19 @@ public: virtual bool HaveSpendingKey(const libzcash::PaymentAddress &address) const =0; virtual bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& skOut) const =0; virtual void GetPaymentAddresses(std::set &setAddress) const =0; + + //! Support for viewing keys + virtual bool AddViewingKey(const libzcash::ViewingKey &vk) =0; + virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk) =0; + virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const =0; + virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const =0; }; typedef std::map KeyMap; typedef std::map ScriptMap; typedef std::set WatchOnlySet; typedef std::map SpendingKeyMap; +typedef std::map ViewingKeyMap; typedef std::map NoteDecryptorMap; /** Basic key store, that keeps keys in an address->secret map */ @@ -71,6 +78,7 @@ protected: ScriptMap mapScripts; WatchOnlySet setWatchOnly; SpendingKeyMap mapSpendingKeys; + ViewingKeyMap mapViewingKeys; NoteDecryptorMap mapNoteDecryptors; public: @@ -166,8 +174,19 @@ public: setAddress.insert((*mi).first); mi++; } + ViewingKeyMap::const_iterator mvi = mapViewingKeys.begin(); + while (mvi != mapViewingKeys.end()) + { + setAddress.insert((*mvi).first); + mvi++; + } } } + + virtual bool AddViewingKey(const libzcash::ViewingKey &vk); + virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk); + virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const; + virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const; }; typedef std::vector > CKeyingMaterial; diff --git a/src/komodo-tx.cpp b/src/komodo-tx.cpp index 645bc30a2..da2a9ec2e 100644 --- a/src/komodo-tx.cpp +++ b/src/komodo-tx.cpp @@ -6,6 +6,7 @@ #include "clientversion.h" #include "coins.h" #include "consensus/consensus.h" +#include "consensus/upgrades.h" #include "core_io.h" #include "keystore.h" #include "primitives/transaction.h" @@ -31,7 +32,7 @@ using namespace std; #include "komodo_interest.h" -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue) +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight) { return(0); } @@ -83,7 +84,7 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("nversion=N", _("Set TX version to N")); strUsage += HelpMessageOpt("outaddr=VALUE:ADDRESS", _("Add address-based output to TX")); strUsage += HelpMessageOpt("outscript=VALUE:SCRIPT", _("Add raw script output to TX")); - strUsage += HelpMessageOpt("sign=SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + + strUsage += HelpMessageOpt("sign=HEIGHT:SIGHASH-FLAGS", _("Add zero or more signatures to transaction") + ". " + _("This command requires JSON registers:") + _("prevtxs=JSON object") + ", " + _("privatekeys=JSON object") + ". " + @@ -170,12 +171,21 @@ static void RegisterLoad(const string& strInput) static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal) { int64_t newVersion = atoi64(cmdVal); - if (newVersion < CTransaction::MIN_CURRENT_VERSION || newVersion > CTransaction::MAX_CURRENT_VERSION) + if (newVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION || newVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION) throw runtime_error("Invalid TX version requested"); tx.nVersion = (int) newVersion; } +static void MutateTxExpiry(CMutableTransaction& tx, const string& cmdVal) +{ + int64_t newExpiry = atoi64(cmdVal); + if (newExpiry >= TX_EXPIRY_HEIGHT_THRESHOLD) { + throw runtime_error("Invalid TX expiry requested"); + } + tx.nExpiryHeight = (int) newExpiry; +} + static void MutateTxLocktime(CMutableTransaction& tx, const string& cmdVal) { int64_t newLocktime = atoi64(cmdVal); @@ -335,11 +345,39 @@ vector ParseHexUO(map& o, string strKey) return ParseHexUV(o[strKey], strKey); } - -static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) +static CAmount AmountFromValue(const UniValue& value) { - int nHashType = SIGHASH_ALL; + if (!value.isNum() && !value.isStr()) + throw runtime_error("Amount is not a number or string"); + CAmount amount; + if (!ParseFixedPoint(value.getValStr(), 8, &amount)) + throw runtime_error("Invalid amount"); + if (!MoneyRange(amount)) + throw runtime_error("Amount out of range"); + return amount; +} +static void MutateTxSign(CMutableTransaction& tx, const string& strInput) +{ + // separate HEIGHT:SIGHASH-FLAGS in string + size_t pos = strInput.find(':'); + if ((pos == 0) || + (pos == (strInput.size() - 1))) + throw runtime_error("Invalid sighash flag separator"); + + // extract and validate HEIGHT + string strHeight = strInput.substr(0, pos); + int nHeight = atoi(strHeight); + if (nHeight <= 0) { + throw runtime_error("invalid height"); + } + + // extract and validate SIGHASH-FLAGS + int nHashType = SIGHASH_ALL; + string flagStr; + if (pos != string::npos) { + flagStr = strInput.substr(pos + 1, string::npos); + } if (flagStr.size() > 0) if (!findSighashFlags(nHashType, flagStr)) throw runtime_error("unknown sighash flag/sign option"); @@ -407,7 +445,10 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) if ((unsigned int)nOut >= coins->vout.size()) coins->vout.resize(nOut+1); coins->vout[nOut].scriptPubKey = scriptPubKey; - coins->vout[nOut].nValue = 0; // we don't know the actual output value + coins->vout[nOut].nValue = 0; + if (prevOut.exists("amount")) { + coins->vout[nOut].nValue = AmountFromValue(prevOut["amount"]); + } } // if redeemScript given and private keys given, @@ -426,6 +467,9 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); + // Grab the consensus branch ID for the given height + auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus()); + // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; @@ -435,17 +479,19 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) continue; } const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; - txin.scriptSig.clear(); + SignatureData sigdata; // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mergedTx.vout.size())) - SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); // ... and merge in other signatures: - BOOST_FOREACH(const CTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); - } - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i))) + BOOST_FOREACH(const CTransaction& txv, txVariants) + sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); + UpdateTransaction(mergedTx, i, sigdata); + + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount), consensusBranchId)) fComplete = false; } @@ -459,9 +505,15 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) class Secp256k1Init { + ECCVerifyHandle globalVerifyHandle; + public: - Secp256k1Init() { ECC_Start(); } - ~Secp256k1Init() { ECC_Stop(); } + Secp256k1Init() { + ECC_Start(); + } + ~Secp256k1Init() { + ECC_Stop(); + } }; static void MutateTx(CMutableTransaction& tx, const string& command, @@ -473,6 +525,8 @@ static void MutateTx(CMutableTransaction& tx, const string& command, MutateTxVersion(tx, commandVal); else if (command == "locktime") MutateTxLocktime(tx, commandVal); + else if (command == "expiry") + MutateTxExpiry(tx, commandVal); else if (command == "delin") MutateTxDelInput(tx, commandVal); diff --git a/src/komodo.h b/src/komodo.h index 129ea3b5f..ded368381 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -73,7 +73,7 @@ int32_t komodo_currentheight() int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char *dest) { static int32_t errs; - int32_t func,ht,notarized_height,num,matched=0; uint256 notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; + int32_t func,ht,notarized_height,num,matched=0,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; if ( (func= fgetc(fp)) != EOF ) { if ( ASSETCHAINS_SYMBOL[0] == 0 && strcmp(symbol,"KMD") == 0 ) @@ -97,7 +97,7 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char } } else printf("illegal num.%d\n",num); } - else if ( func == 'N' ) + else if ( func == 'N' || func == 'M' ) { if ( fread(¬arized_height,1,sizeof(notarized_height),fp) != sizeof(notarized_height) ) errs++; @@ -105,10 +105,22 @@ int32_t komodo_parsestatefile(struct komodo_state *sp,FILE *fp,char *symbol,char errs++; if ( fread(¬arized_desttxid,1,sizeof(notarized_desttxid),fp) != sizeof(notarized_desttxid) ) errs++; - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) - printf("%s load[%s.%d -> %s] NOTARIZED %d %s\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str()); + if ( func == 'M' ) + { + if ( fread(&MoM,1,sizeof(MoM),fp) != sizeof(MoM) ) + errs++; + if ( fread(&MoMdepth,1,sizeof(MoMdepth),fp) != sizeof(MoMdepth) ) + errs++; + if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) + printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth); + } + else + { + memset(&MoM,0,sizeof(MoM)); + MoMdepth = 0; + } //if ( matched != 0 ) global independent states -> inside *sp - komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height); + komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); } else if ( func == 'U' ) // deprecated { @@ -208,7 +220,7 @@ int32_t memread(void *dest,int32_t size,uint8_t *filedata,long *fposp,long datal int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long *fposp,long datalen,char *symbol,char *dest) { static int32_t errs; - int32_t func= -1,ht,notarized_height,num,matched=0; uint256 notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; long fpos = *fposp; + int32_t func= -1,ht,notarized_height,MoMdepth,num,matched=0; uint256 MoM,notarized_hash,notarized_desttxid; uint8_t pubkeys[64][33]; long fpos = *fposp; if ( fpos < datalen ) { func = filedata[fpos++]; @@ -231,7 +243,7 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long } } else printf("illegal num.%d\n",num); } - else if ( func == 'N' ) + else if ( func == 'N' || func == 'M' ) { if ( memread(¬arized_height,sizeof(notarized_height),filedata,&fpos,datalen) != sizeof(notarized_height) ) errs++; @@ -239,10 +251,21 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long errs++; if ( memread(¬arized_desttxid,sizeof(notarized_desttxid),filedata,&fpos,datalen) != sizeof(notarized_desttxid) ) errs++; - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) - printf("%s load[%s.%d -> %s] NOTARIZED %d %s\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str()); - //if ( matched != 0 ) global independent states -> inside *sp - komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height); + if ( func == 'M' ) + { + if ( memread(&MoM,sizeof(MoM),filedata,&fpos,datalen) != sizeof(MoM) ) + errs++; + if ( memread(&MoMdepth,sizeof(MoMdepth),filedata,&fpos,datalen) != sizeof(MoMdepth) ) + errs++; + if ( 1 && ASSETCHAINS_SYMBOL[0] != 0 && sp != 0 ) + printf("%s load[%s.%d -> %s] NOTARIZED %d %s MoM.%s %d\n",ASSETCHAINS_SYMBOL,symbol,sp->NUM_NPOINTS,dest,notarized_height,notarized_hash.ToString().c_str(),MoM.ToString().c_str(),MoMdepth); + } + else + { + memset(&MoM,0,sizeof(MoM)); + MoMdepth = 0; + } + komodo_eventadd_notarized(sp,symbol,ht,dest,notarized_hash,notarized_desttxid,notarized_height,MoM,MoMdepth); } else if ( func == 'U' ) // deprecated { @@ -326,9 +349,9 @@ int32_t komodo_parsestatefiledata(struct komodo_state *sp,uint8_t *filedata,long return(-1); } -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout) +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) { - static FILE *fp; static int32_t errs,didinit; + static FILE *fp; static int32_t errs,didinit; static uint256 zero; struct komodo_state *sp; char fname[512],symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; int32_t retval,ht,func; uint8_t num,pubkeys[64][33]; if ( didinit == 0 ) { @@ -457,7 +480,9 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar //printf("ht.%d func N ht.%d errs.%d\n",height,NOTARIZED_HEIGHT,errs); if ( sp != 0 ) { - fputc('N',fp); + if ( sp->MoMdepth > 0 && sp->MoM != zero ) + fputc('M',fp); + else fputc('N',fp); if ( fwrite(&height,1,sizeof(height),fp) != sizeof(height) ) errs++; if ( fwrite(&sp->NOTARIZED_HEIGHT,1,sizeof(sp->NOTARIZED_HEIGHT),fp) != sizeof(sp->NOTARIZED_HEIGHT) ) @@ -466,7 +491,14 @@ void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotar errs++; if ( fwrite(&sp->NOTARIZED_DESTTXID,1,sizeof(sp->NOTARIZED_DESTTXID),fp) != sizeof(sp->NOTARIZED_DESTTXID) ) errs++; - komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT); + if ( sp->MoMdepth > 0 && sp->MoM != zero ) + { + if ( fwrite(&sp->MoM,1,sizeof(sp->MoM),fp) != sizeof(sp->MoM) ) + errs++; + if ( fwrite(&sp->MoMdepth,1,sizeof(sp->MoMdepth),fp) != sizeof(sp->MoMdepth) ) + errs++; + } + komodo_eventadd_notarized(sp,symbol,height,dest,sp->NOTARIZED_HASH,sp->NOTARIZED_DESTTXID,sp->NOTARIZED_HEIGHT,sp->MoM,sp->MoMdepth); } } fflush(fp); @@ -537,15 +569,36 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&kmdtxid); len += iguana_rwnum(0,&scriptbuf[len],sizeof(*notarizedheightp),(uint8_t *)notarizedheightp); len += iguana_rwbignum(0,&scriptbuf[len],32,(uint8_t *)&desttxid); - if ( notarized != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height && (height < sp->CURRENT_HEIGHT-1000 || komodo_verifynotarization(ASSETCHAINS_SYMBOL[0]==0?(char *)"KMD":ASSETCHAINS_SYMBOL,(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "BTC" : "KMD"),height,*notarizedheightp,kmdtxid,desttxid) == 0) ) + if ( strcmp("PIZZA",ASSETCHAINS_SYMBOL) == 0 && opretlen == 110 ) { + notarized = 1; + } + if ( notarized != 0 && *notarizedheightp > sp->NOTARIZED_HEIGHT && *notarizedheightp < height && (height < sp->CURRENT_HEIGHT-64 || komodo_verifynotarization(ASSETCHAINS_SYMBOL[0]==0?(char *)"KMD":ASSETCHAINS_SYMBOL,(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "BTC" : "KMD"),height,*notarizedheightp,kmdtxid,desttxid) == 0) ) + { + int32_t nameoffset = (int32_t)strlen(ASSETCHAINS_SYMBOL) + 1; sp->NOTARIZED_HEIGHT = *notarizedheightp; sp->NOTARIZED_HASH = kmdtxid; sp->NOTARIZED_DESTTXID = desttxid; - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0); - len += 4; + memset(&sp->MoM,0,sizeof(sp->MoM)); + sp->MoMdepth = 0; + if ( len+36 <= opretlen ) + { + len += iguana_rwbignum(0,&scriptbuf[len+nameoffset],32,(uint8_t *)&sp->MoM); + len += iguana_rwnum(0,&scriptbuf[len+nameoffset],sizeof(sp->MoMdepth),(uint8_t *)&sp->MoMdepth); + if ( sp->MoM == zero || sp->MoMdepth > 1440 || sp->MoMdepth < 0 ) + { + memset(&sp->MoM,0,sizeof(sp->MoM)); + sp->MoMdepth = 0; + } + else + { + //printf("VALID %s MoM.%s [%d]\n",ASSETCHAINS_SYMBOL,sp->MoM.ToString().c_str(),sp->MoMdepth); + } + } + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); + len += nameoffset; if ( ASSETCHAINS_SYMBOL[0] != 0 ) - printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d)\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len); + printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) @@ -567,11 +620,11 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr //for (i=0; i= KOMODO_MAINNET_START ) - printf("notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s (%s)\n",notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len]); + } else if ( height >= sp->CURRENT_HEIGHT-64 )//KOMODO_MAINNET_START ) + printf("notarized.%d %llx reject ht.%d NOTARIZED.%d prev.%d %s.%s DESTTXID.%s (%s) len.%d opretlen.%d\n",notarized,(long long)signedmask,height,*notarizedheightp,sp->NOTARIZED_HEIGHT,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,kmdtxid.ToString().c_str(),desttxid.ToString().c_str(),(char *)&scriptbuf[len],len,opretlen); } else if ( i == 0 && j == 1 && opretlen == 149 ) { @@ -596,7 +649,7 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr } if ( *isratificationp == 0 && (signedmask != 0 || (scriptbuf[len] != 'X' && scriptbuf[len] != 'A')) ) // && scriptbuf[len] != 'I') - komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j); + komodo_stateupdate(height,0,0,0,txhash,0,0,0,0,0,0,value,&scriptbuf[len],opretlen,j,zero,0); } } return(notaryid); @@ -655,7 +708,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( pindex->nHeight != hwmheight ) printf("%s hwmheight.%d vs pindex->nHeight.%d t.%u reorg.%d\n",ASSETCHAINS_SYMBOL,hwmheight,pindex->nHeight,(uint32_t)pindex->nTime,hwmheight-pindex->nHeight); komodo_event_rewind(sp,symbol,pindex->nHeight); - komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0); + komodo_stateupdate(pindex->nHeight,0,0,0,zero,0,0,0,0,-pindex->nHeight,pindex->nTime,0,0,0,0,zero,0); } komodo_currentheight_set(chainActive.Tip()->nHeight); if ( pindex != 0 ) @@ -787,7 +840,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( ((signedmask & 1) != 0 && numvalid >= KOMODO_MINRATIFY) || bitweight(signedmask) > (numnotaries/3) ) { memset(&txhash,0,sizeof(txhash)); - komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0); + komodo_stateupdate(height,pubkeys,numvalid,0,txhash,0,0,0,0,0,0,0,0,0,0,zero,0); printf("RATIFIED! >>>>>>>>>> new notaries.%d newheight.%d from height.%d\n",numvalid,(((height+KOMODO_ELECTION_GAP/2)/KOMODO_ELECTION_GAP)+1)*KOMODO_ELECTION_GAP,height); } else printf("signedmask.%llx numvalid.%d wt.%d numnotaries.%d\n",(long long)signedmask,numvalid,bitweight(signedmask),numnotaries); } @@ -796,7 +849,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) if ( NOTARY_PUBKEY33[0] != 0 && ASSETCHAINS_SYMBOL[0] == 0 ) printf("%s ht.%d\n",ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL,height); if ( pindex->nHeight == hwmheight ) - komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0); + komodo_stateupdate(height,0,0,0,zero,0,0,0,0,height,(uint32_t)pindex->nTime,0,0,0,0,zero,0); } else fprintf(stderr,"komodo_connectblock: unexpected null pindex\n"); //KOMODO_INITDONE = (uint32_t)time(NULL); //fprintf(stderr,"%s end connect.%d\n",ASSETCHAINS_SYMBOL,pindex->nHeight); diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 76f6765ad..0c905e785 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -25,6 +25,9 @@ #include "komodo_defs.h" +int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); +int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); + //#define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"curl",(char *)"http://127.0.0.1:7776",0,0,(char *)(cmdstr)) struct MemoryStruct { char *memory; size_t size; }; @@ -414,13 +417,14 @@ int32_t komodo_verifynotarizedscript(int32_t height,uint8_t *script,int32_t len, printf(" notarized, "); for (i=0; i<32; i++) printf("%02x",((uint8_t *)&hash)[i]); - printf(" opreturn from [%s] ht.%d\n",ASSETCHAINS_SYMBOL,height); + printf(" opreturn from [%s] ht.%d MISMATCHED\n",ASSETCHAINS_SYMBOL,height); return(-1); } int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t NOTARIZED_HEIGHT,uint256 NOTARIZED_HASH,uint256 NOTARIZED_DESTTXID) { - char params[256],*jsonstr,*hexstr; uint8_t script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; + char params[256],*jsonstr,*hexstr; uint8_t *script,_script[8192]; int32_t n,len,retval = -1; cJSON *json,*txjson,*vouts,*vout,*skey; + script = _script; /*params[0] = '['; params[1] = '"'; for (i=0; i<32; i++) @@ -471,9 +475,19 @@ int32_t komodo_verifynotarization(char *symbol,char *dest,int32_t height,int32_t { if ( (hexstr= jstr(skey,(char *)"hex")) != 0 ) { - //printf("HEX.(%s)\n",hexstr); + //printf("HEX.(%s) vs hash.%s\n",hexstr,NOTARIZED_HASH.ToString().c_str()); len = strlen(hexstr) >> 1; decode_hex(script,len,hexstr); + if ( script[1] == 0x4c ) + { + script++; + len--; + } + else if ( script[1] == 0x4d ) + { + script += 2; + len -= 2; + } retval = komodo_verifynotarizedscript(height,script,len,NOTARIZED_HASH); } } @@ -574,7 +588,7 @@ void komodo_disconnect(CBlockIndex *pindex,CBlock& block) int32_t komodo_is_notarytx(const CTransaction& tx) { - uint8_t *ptr,crypto777[33]; + uint8_t *ptr; static uint8_t crypto777[33]; if ( tx.vout.size() > 0 ) { #ifdef KOMODO_ZCASH @@ -584,7 +598,8 @@ int32_t komodo_is_notarytx(const CTransaction& tx) #endif if ( ptr != 0 ) { - decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR); + if ( crypto777[0] == 0 ) + decode_hex(crypto777,33,(char *)CRYPTO777_PUBSECPSTR); if ( memcmp(ptr+1,crypto777,33) == 0 ) { //printf("found notarytx\n"); @@ -610,7 +625,7 @@ int32_t komodo_block2height(CBlock *block) //for (i=0; i<6; i++) // printf("%02x",ptr[i]); n = ptr[0]; - for (i=0; i 0 && (ptr= komodo_chainactive(height)) != 0 ) return(ptr->nTime); - else fprintf(stderr,"komodo_heightstamp null ptr for block.%d\n",height); + //else fprintf(stderr,"komodo_heightstamp null ptr for block.%d\n",height); return(0); } void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) { - CBlock block; + CBlock block; int32_t num,i; uint8_t pubkeys[64][33]; //komodo_init(height); memset(pubkey33,0,33); if ( pindex != 0 ) { + if ( pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3 ) + { + memcpy(pubkey33,pindex->pubkey33,33); + return; + } if ( komodo_blockload(block,pindex) == 0 ) + { komodo_block2pubkey33(pubkey33,block); + if ( (pubkey33[0] == 2 || pubkey33[0] == 3) ) + { + memcpy(pindex->pubkey33,pubkey33,33); + if ( (num= komodo_notaries(pubkeys,(int32_t)pindex->nHeight,(uint32_t)pindex->nTime)) > 0 ) + { + pindex->notaryid = -1; + for (i=0; inotaryid = i; + break; + } + } + } + } else pindex->notaryid = -1; + } } else { @@ -703,27 +741,28 @@ void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height) } } -void komodo_connectpindex(CBlockIndex *pindex) +/*void komodo_connectpindex(CBlockIndex *pindex) { CBlock block; if ( komodo_blockload(block,pindex) == 0 ) komodo_connectblock(pindex,block); -} +}*/ -int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); -int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp); int8_t komodo_minerid(int32_t height,uint8_t *pubkey33) { int32_t num,i,numnotaries; CBlockIndex *pindex; uint32_t timestamp=0; uint8_t _pubkey33[33],pubkeys[64][33]; - if ( pubkey33 == 0 && (pindex= chainActive[height]) != 0 ) + if ( (pindex= chainActive[height]) != 0 ) { - timestamp = pindex->GetBlockTime(); - if ( pubkey33 == 0 ) + if ( (pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3) ) { - pubkey33 = _pubkey33; - komodo_index2pubkey33(pubkey33,pindex,height); + if ( pubkey33 != 0 ) + memcpy(pubkey33,pindex->pubkey33,33); + return(pindex->notaryid); } + if ( pubkey33 != 0 ) + komodo_index2pubkey33(pubkey33,pindex,height); + timestamp = pindex->GetBlockTime(); if ( (num= komodo_notaries(pubkeys,height,timestamp)) > 0 ) { for (i=0; i= 0 ) + if ( pindex->notaryid >= 0 && (pindex->pubkey33[0] == 2 || pindex->pubkey33[0] == 3) ) { - //mids[i] = *(int32_t *)pubkey33; + memcpy(pubkeys[i],pindex->pubkey33,33); + mids[i] = pindex->notaryid; (*nonzpkeysp)++; } + else + { + komodo_index2pubkey33(pubkey33,pindex,height-i); + memcpy(pubkeys[i],pubkey33,33); + if ( (mids[i]= komodo_minerid(height-i,pubkey33)) >= 0 ) + { + //mids[i] = *(int32_t *)pubkey33; + (*nonzpkeysp)++; + } + } if ( mids[0] >= 0 && i > 0 && mids[i] == mids[0] ) duplicate++; } @@ -759,23 +806,24 @@ int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,int32_t *non else return(0); } -int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width) +int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width) // deprecate { - int32_t i,n=0; + /*int32_t i,n=0; for (i=0; i= 225000 ) - komodo_chosennotary(¬aryid,height,_pubkey33,timestamp); + komodo_chosennotary(¬aryid,height,pubkey33,timestamp); if ( height >= 34000 && notaryid >= 0 ) { if ( height < 79693 ) @@ -785,8 +833,8 @@ int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33],uint32_t timestamp else limit = 66; for (i=1; i 0 ) fprintf(stderr,"ht.%d notaryid.%d already mined -i.%d nid.%d\n",height,notaryid,i,nid); @@ -800,9 +848,25 @@ int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33],uint32_t timestamp return(0); } +int32_t komodo_MoM(int32_t *notarized_heightp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight) +{ + int32_t depth,notarized_ht; uint256 MoM,kmdtxid; + depth = komodo_MoMdata(¬arized_ht,&MoM,&kmdtxid,nHeight); + memset(MoMp,0,sizeof(*MoMp)); + memset(kmdtxidp,0,sizeof(*kmdtxidp)); + *notarized_heightp = 0; + if ( depth > 0 && notarized_ht > 0 && nHeight > notarized_ht-depth && nHeight <= notarized_ht ) + { + *MoMp = MoM; + *notarized_heightp = notarized_ht; + *kmdtxidp = kmdtxid; + } + return(depth); +} + int32_t komodo_checkpoint(int32_t *notarized_heightp,int32_t nHeight,uint256 hash) { - int32_t notarized_height; uint256 notarized_hash,notarized_desttxid; CBlockIndex *notary; CBlockIndex *pindex; + int32_t notarized_height,MoMdepth; uint256 MoM,notarized_hash,notarized_desttxid; CBlockIndex *notary; CBlockIndex *pindex; if ( (pindex= chainActive.Tip()) == 0 ) return(-1); notarized_height = komodo_notarizeddata(pindex->nHeight,¬arized_hash,¬arized_desttxid); @@ -840,12 +904,13 @@ uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_ uint32_t locktime = 0; if ( n < tx.vout.size() ) { - if ( (pindex= mapBlockIndex[hashBlock]) != 0 && (tipindex= chainActive.Tip()) != 0 ) + if ( (pindex= mapBlockIndex[hashBlock]) != 0 ) { *valuep = tx.vout[n].nValue; *txheightp = pindex->nHeight; *txheighttimep = pindex->nTime; - *tiptimep = tipindex->nTime; + if ( *tiptimep == 0 && (tipindex= chainActive.Tip()) != 0 ) + *tiptimep = (uint32_t)tipindex->nTime; locktime = tx.nLockTime; //fprintf(stderr,"tx locktime.%u %.8f height.%d | tiptime.%u\n",locktime,(double)*valuep/COIN,*txheightp,*tiptimep); } @@ -854,9 +919,13 @@ uint32_t komodo_interest_args(uint32_t *txheighttimep,int32_t *txheightp,uint32_ } uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue) + +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight) { - uint64_t value; uint32_t tiptime,txheighttimep; + uint64_t value; uint32_t tiptime=0,txheighttimep; CBlockIndex *pindex; + if ( (pindex= chainActive[tipheight]) != 0 ) + tiptime = (uint32_t)pindex->nTime; + else fprintf(stderr,"cant find height[%d]\n",tipheight); if ( (*locktimep= komodo_interest_args(&txheighttimep,txheightp,&tiptime,&value,hash,n)) != 0 ) { if ( (checkvalue == 0 || value == checkvalue) && (checkheight == 0 || *txheightp == checkheight) ) @@ -891,7 +960,7 @@ int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_ { if ( tx.nLockTime != 1477258935 || dispflag != 0 ) { - //fprintf(stderr,"komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(uint32_t)tx.nLockTime,cmptime); + fprintf(stderr,"komodo_validate_interest.%d reject.%d [%d] locktime %u cmp2.%u\n",dispflag,txheight,(int32_t)(tx.nLockTime - (cmptime-3600)),(uint32_t)tx.nLockTime,cmptime); } return(-1); } diff --git a/src/komodo_events.h b/src/komodo_events.h index ff054c3bb..315a78686 100644 --- a/src/komodo_events.h +++ b/src/komodo_events.h @@ -37,7 +37,7 @@ struct komodo_event *komodo_eventadd(struct komodo_state *sp,int32_t height,char return(ep); } -void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight) +void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t height,char *dest,uint256 notarized_hash,uint256 notarized_desttxid,int32_t notarizedheight,uint256 MoM,int32_t MoMdepth) { struct komodo_event_notarized N; if ( komodo_verifynotarization(symbol,dest,height,notarizedheight,notarized_hash,notarized_desttxid) != 0 ) @@ -53,10 +53,12 @@ void komodo_eventadd_notarized(struct komodo_state *sp,char *symbol,int32_t heig N.blockhash = notarized_hash; N.desttxid = notarized_desttxid; N.notarizedheight = notarizedheight; + N.MoM = MoM; + N.MoMdepth = MoMdepth; strcpy(N.dest,dest); komodo_eventadd(sp,height,symbol,KOMODO_EVENT_NOTARIZED,(uint8_t *)&N,sizeof(N)); if ( sp != 0 ) - komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid); + komodo_notarized_update(sp,height,notarizedheight,notarized_hash,notarized_desttxid,MoM,MoMdepth); } } diff --git a/src/komodo_globals.h b/src/komodo_globals.h index 6c2e56f5b..518d22cbd 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -15,8 +15,10 @@ #include "komodo_defs.h" -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout); +uint32_t komodo_heightstamp(int32_t height); +void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t kheight,uint32_t ktime,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth); void komodo_init(int32_t height); +int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight); int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp); char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port); void komodo_init(int32_t height); diff --git a/src/komodo_notary.h b/src/komodo_notary.h index 438d81809..638327e81 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -126,13 +126,13 @@ const char *Notaries_elected0[][2] = { "xxspot2_XX", "03d85b221ea72ebcd25373e7961f4983d12add66a92f899deaf07bab1d8b6f5573" } }; -#define KOMODO_NOTARIES_TIMESTAMP1 1600000000 -#define KOMODO_NOTARIES_HEIGHT1 ((800000 / KOMODO_ELECTION_GAP) * KOMODO_ELECTION_GAP) +#define KOMODO_NOTARIES_TIMESTAMP1 1530921600 // 7/7/2017 +#define KOMODO_NOTARIES_HEIGHT1 ((900000 / KOMODO_ELECTION_GAP) * KOMODO_ELECTION_GAP) const char *Notaries_elected1[][2] = { - { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, { "0_jl777_testB", "02ebfc784a4ba768aad88d44d1045d240d47b26e248cafaf1c5169a42d7a61d344" }, + { "0_jl777_testA", "03b7621b44118017a16043f19b30cc8a4cfe068ac4e42417bae16ba460c80f3828" }, { "0_kolo_testA", "0287aa4b73988ba26cf6565d815786caf0d2c4af704d7883d163ee89cd9977edec" }, { "artik_AR", "029acf1dcd9f5ff9c455f8bb717d4ae0c703e089d16cf8424619c491dff5994c90" }, { "artik_EU", "03f54b2c24f82632e3cdebe4568ba0acf487a80f8a89779173cdb78f74514847ce" }, @@ -199,28 +199,52 @@ const char *Notaries_elected1[][2] = int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp) { + static uint8_t elected_pubkeys0[64][33],elected_pubkeys1[64][33],did0,did1; int32_t i,htind,n; uint64_t mask = 0; struct knotary_entry *kp,*tmp; + if ( timestamp == 0 && ASSETCHAINS_SYMBOL[0] != 0 ) + timestamp = komodo_heightstamp(height); if ( height >= KOMODO_NOTARIES_HARDCODED || ASSETCHAINS_SYMBOL[0] != 0 ) { - if ( timestamp < KOMODO_NOTARIES_TIMESTAMP1 || height < KOMODO_NOTARIES_HEIGHT1 ) + if ( (timestamp != 0 && timestamp <= KOMODO_NOTARIES_TIMESTAMP1) || height <= KOMODO_NOTARIES_HEIGHT1 ) { - n = (int32_t)(sizeof(Notaries_elected0)/sizeof(*Notaries_elected0)); - for (i=0; i= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; + if ( Pubkeys == 0 ) + { + komodo_init(height); + printf("Pubkeys.%p htind.%d vs max.%d\n",Pubkeys,htind,KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP); + } pthread_mutex_lock(&komodo_mutex); n = Pubkeys[htind].numnotaries; + if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) + fprintf(stderr,"%s height.%d t.%u genesis.%d\n",ASSETCHAINS_SYMBOL,height,timestamp,n); HASH_ITER(hh,Pubkeys[htind].Notaries,kp,tmp) { if ( kp->notaryid < n ) @@ -238,11 +262,7 @@ int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestam int32_t komodo_electednotary(int32_t *numnotariesp,uint8_t *pubkey33,int32_t height,uint32_t timestamp) { - char pubkeystr[67]; int32_t i,n; uint8_t pubkeys[64][33]; - for (i=0; i<33; i++) - sprintf(&pubkeystr[i*2],"%02x",pubkey33[i]); - pubkeystr[66] = 0; - //printf("%s vs\n",pubkeystr); + int32_t i,n; uint8_t pubkeys[64][33]; n = komodo_notaries(pubkeys,height,timestamp); *numnotariesp = n; for (i=0; i 0 ) { @@ -319,7 +339,6 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, { // -1 if not notary, 0 if notary, 1 if special notary struct knotary_entry *kp; int32_t numnotaries=0,htind,modval = -1; - komodo_init(0); *notaryidp = -1; if ( height < 0 )//|| height >= KOMODO_MAXBLOCKS ) { @@ -336,6 +355,8 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, } if ( height >= 250000 ) return(-1); + if ( Pubkeys == 0 ) + komodo_init(0); htind = height / KOMODO_ELECTION_GAP; if ( htind >= KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP ) htind = (KOMODO_MAXBLOCKS / KOMODO_ELECTION_GAP) - 1; @@ -357,7 +378,7 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, return(modval); } -void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid) +void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t notarized_height,uint256 notarized_hash,uint256 notarized_desttxid,uint256 MoM,int32_t MoMdepth) { struct notarized_checkpoint *np; if ( notarized_height > nHeight ) @@ -375,6 +396,8 @@ void komodo_notarized_update(struct komodo_state *sp,int32_t nHeight,int32_t not sp->NOTARIZED_HEIGHT = np->notarized_height = notarized_height; sp->NOTARIZED_HASH = np->notarized_hash = notarized_hash; sp->NOTARIZED_DESTTXID = np->notarized_desttxid = notarized_desttxid; + sp->MoM = np->MoM = MoM; + sp->MoMdepth = np->MoMdepth = MoMdepth; portable_mutex_unlock(&komodo_mutex); } @@ -396,6 +419,30 @@ int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp) } } +int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t height) +{ + int32_t i; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; struct notarized_checkpoint *np = 0; + np = 0; + if ( (sp= komodo_stateptr(symbol,dest)) != 0 ) + { + for (i=sp->NUM_NPOINTS-1; i>=0; i--) + { + np = &sp->NPOINTS[i]; + if ( np->MoMdepth > 0 && height > np->notarized_height-np->MoMdepth && height <= np->notarized_height ) + { + *notarized_htp = np->notarized_height; + *MoMp = np->MoM; + *kmdtxidp = np->notarized_desttxid; + return(np->MoMdepth); + } + } + } + *notarized_htp = 0; + memset(MoMp,0,sizeof(*MoMp)); + memset(kmdtxidp,0,sizeof(*kmdtxidp)); + return(0); +} + int32_t komodo_notarizeddata(int32_t nHeight,uint256 *notarized_hashp,uint256 *notarized_desttxidp) { struct notarized_checkpoint *np = 0; int32_t i=0,flag = 0; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; @@ -457,6 +504,7 @@ void komodo_init(int32_t height) static int didinit; uint256 zero; int32_t k,n; uint8_t pubkeys[64][33]; if ( 0 && height != 0 ) printf("komodo_init ht.%d didinit.%d\n",height,didinit); + memset(&zero,0,sizeof(zero)); if ( didinit == 0 ) { pthread_mutex_init(&komodo_mutex,NULL); @@ -472,10 +520,10 @@ void komodo_init(int32_t height) } komodo_notarysinit(0,pubkeys,k); } - memset(&zero,0,sizeof(zero)); //for (i=0; i #include -void HandleError(const leveldb::Status& status) throw(leveldb_error) +void HandleError(const leveldb::Status& status) { if (status.ok()) return; @@ -81,7 +81,7 @@ CLevelDBWrapper::~CLevelDBWrapper() options.env = NULL; } -bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) throw(leveldb_error) +bool CLevelDBWrapper::WriteBatch(CLevelDBBatch& batch, bool fSync) { leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch); HandleError(status); diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index c65e84270..639f736a5 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -22,7 +22,7 @@ public: leveldb_error(const std::string& msg) : std::runtime_error(msg) {} }; -void HandleError(const leveldb::Status& status) throw(leveldb_error); +void HandleError(const leveldb::Status& status); /** Batch of changes queued to be written to a CLevelDBWrapper */ class CLevelDBBatch @@ -90,7 +90,7 @@ public: ~CLevelDBWrapper(); template - bool Read(const K& key, V& value) const throw(leveldb_error) + bool Read(const K& key, V& value) const { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); @@ -115,7 +115,7 @@ public: } template - bool Write(const K& key, const V& value, bool fSync = false) throw(leveldb_error) + bool Write(const K& key, const V& value, bool fSync = false) { CLevelDBBatch batch; batch.Write(key, value); @@ -123,7 +123,7 @@ public: } template - bool Exists(const K& key) const throw(leveldb_error) + bool Exists(const K& key) const { CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(ssKey.GetSerializeSize(key)); @@ -142,14 +142,14 @@ public: } template - bool Erase(const K& key, bool fSync = false) throw(leveldb_error) + bool Erase(const K& key, bool fSync = false) { CLevelDBBatch batch; batch.Erase(key); return WriteBatch(batch, fSync); } - bool WriteBatch(CLevelDBBatch& batch, bool fSync = false) throw(leveldb_error); + bool WriteBatch(CLevelDBBatch& batch, bool fSync = false); // not available for LevelDB; provide for compatibility with BDB bool Flush() @@ -157,7 +157,7 @@ public: return true; } - bool Sync() throw(leveldb_error) + bool Sync() { CLevelDBBatch batch; return WriteBatch(batch, true); diff --git a/src/main.cpp b/src/main.cpp index 86b52495a..151c42383 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,9 @@ #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" +#include "deprecation.h" #include "init.h" #include "merkleblock.h" #include "metrics.h" @@ -27,6 +29,7 @@ #include "utilmoneystr.h" #include "validationinterface.h" #include "wallet/asyncrpcoperation_sendmany.h" +#include "wallet/asyncrpcoperation_shieldcoinbase.h" #include @@ -72,6 +75,8 @@ size_t nCoinCacheUsage = 5000 * 300; uint64_t nPruneTarget = 0; bool fAlerts = DEFAULT_ALERTS; +unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; + /** Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) */ CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); @@ -479,7 +484,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vectorGetAncestor(chain.Height()) == chain.Tip()) { + return chain.Tip(); + } } } return chain.Genesis(); @@ -656,16 +664,22 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE } - - - - - -bool IsStandardTx(const CTransaction& tx, string& reason) +bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight) { - if (tx.nVersion > CTransaction::MAX_CURRENT_VERSION || tx.nVersion < CTransaction::MIN_CURRENT_VERSION) { - reason = "version"; - return false; + bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); + + if (isOverwinter) { + // Overwinter standard rules apply + if (tx.nVersion > CTransaction::OVERWINTER_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::OVERWINTER_MIN_CURRENT_VERSION) { + reason = "overwinter-version"; + return false; + } + } else { + // Sprout standard rules apply + if (tx.nVersion > CTransaction::SPROUT_MAX_CURRENT_VERSION || tx.nVersion < CTransaction::SPROUT_MIN_CURRENT_VERSION) { + reason = "version"; + return false; + } } BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -737,13 +751,21 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) } else if (!txin.IsFinal()) { - printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime); + //printf("non-final txin seq.%x locktime.%u vs nTime.%u\n",txin.nSequence,(uint32_t)tx.nLockTime,(uint32_t)nBlockTime); return false; } } return true; } +bool IsExpiredTx(const CTransaction &tx, int nBlockHeight) +{ + if (tx.nExpiryHeight == 0 || tx.IsCoinBase()) { + return false; + } + return static_cast(nBlockHeight) > tx.nExpiryHeight; +} + bool CheckFinalTx(const CTransaction &tx, int flags) { AssertLockHeld(cs_main); @@ -784,7 +806,7 @@ bool CheckFinalTx(const CTransaction &tx, int flags) * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations */ -bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) +bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId) { if (tx.IsCoinBase()) return true; // Coinbases don't use vin normally @@ -810,7 +832,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) // IsStandardTx() will have already returned false // and this method isn't called. vector > stack; - if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker())) + if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), consensusBranchId)) return false; if (whichType == TX_SCRIPTHASH) @@ -872,7 +894,80 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in return nSigOps; } -bool CheckTransaction(const CTransaction& tx, CValidationState &state,libzcash::ProofVerifier& verifier) +/** + * Check a transaction contextually against a set of consensus rules valid at a given block height. + * + * Notes: + * 1. AcceptToMemoryPool calls CheckTransaction and this function. + * 2. ProcessNewBlock calls AcceptBlock, which calls CheckBlock (which calls CheckTransaction) + * and ContextualCheckBlock (which calls this function). + */ +bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, const int nHeight, const int dosLevel) +{ + bool isOverwinter = NetworkUpgradeActive(nHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); + bool isSprout = !isOverwinter; + + // If Sprout rules apply, reject transactions which are intended for Overwinter and beyond + if (isSprout && tx.fOverwintered) { + return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter is not active yet"), + REJECT_INVALID, "tx-overwinter-not-active"); + } + + // If Overwinter rules apply: + if (isOverwinter) { + // Reject transactions with valid version but missing overwinter flag + if (tx.nVersion >= OVERWINTER_MIN_TX_VERSION && !tx.fOverwintered) { + return state.DoS(dosLevel, error("ContextualCheckTransaction(): overwinter flag must be set"), + REJECT_INVALID, "tx-overwinter-flag-not-set"); + } + + // Reject transactions with invalid version + if (tx.fOverwintered && tx.nVersion > OVERWINTER_MAX_TX_VERSION ) { + return state.DoS(100, error("CheckTransaction(): overwinter version too high"), + REJECT_INVALID, "bad-tx-overwinter-version-too-high"); + } + + // Reject transactions intended for Sprout + if (!tx.fOverwintered) { + return state.DoS(dosLevel, error("ContextualCheckTransaction: overwinter is active"), + REJECT_INVALID, "tx-overwinter-active"); + } + + // Check that all transactions are unexpired + if (IsExpiredTx(tx, nHeight)) { + return state.DoS(dosLevel, error("ContextualCheckTransaction(): transaction is expired"), REJECT_INVALID, "tx-overwinter-expired"); + } + } + + if (!(tx.IsCoinBase() || tx.vjoinsplit.empty())) { + auto consensusBranchId = CurrentEpochBranchId(nHeight, Params().GetConsensus()); + // Empty output script. + CScript scriptCode; + uint256 dataToBeSigned; + try { + dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); + } catch (std::logic_error ex) { + return state.DoS(100, error("CheckTransaction(): error computing signature hash"), + REJECT_INVALID, "error-computing-signature-hash"); + } + + BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32); + + // We rely on libsodium to check that the signature is canonical. + // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0 + if (crypto_sign_verify_detached(&tx.joinSplitSig[0], + dataToBeSigned.begin(), 32, + tx.joinSplitPubKey.begin() + ) != 0) { + return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"), + REJECT_INVALID, "bad-txns-invalid-joinsplit-signature"); + } + } + return true; +} + +bool CheckTransaction(const CTransaction& tx, CValidationState &state, + libzcash::ProofVerifier& verifier) { static uint256 array[64]; static int32_t numbanned,indallvouts; int32_t j,k,n; if ( *(int32_t *)&array[0] == 0 ) @@ -914,11 +1009,46 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio { // Basic checks that don't depend on any context - // Check transaction version - if (tx.nVersion < MIN_TX_VERSION) { + /** + * Previously: + * 1. The consensus rule below was: + * if (tx.nVersion < SPROUT_MIN_TX_VERSION) { ... } + * which checked if tx.nVersion fell within the range: + * INT32_MIN <= tx.nVersion < SPROUT_MIN_TX_VERSION + * 2. The parser allowed tx.nVersion to be negative + * + * Now: + * 1. The consensus rule checks to see if tx.Version falls within the range: + * 0 <= tx.nVersion < SPROUT_MIN_TX_VERSION + * 2. The previous consensus rule checked for negative values within the range: + * INT32_MIN <= tx.nVersion < 0 + * This is unnecessary for Overwinter transactions since the parser now + * interprets the sign bit as fOverwintered, so tx.nVersion is always >=0, + * and when Overwinter is not active ContextualCheckTransaction rejects + * transactions with fOverwintered set. When fOverwintered is set, + * this function and ContextualCheckTransaction will together check to + * ensure tx.nVersion avoids the following ranges: + * 0 <= tx.nVersion < OVERWINTER_MIN_TX_VERSION + * OVERWINTER_MAX_TX_VERSION < tx.nVersion <= INT32_MAX + */ + if (!tx.fOverwintered && tx.nVersion < SPROUT_MIN_TX_VERSION) { return state.DoS(100, error("CheckTransaction(): version too low"), REJECT_INVALID, "bad-txns-version-too-low"); } + else if (tx.fOverwintered) { + if (tx.nVersion < OVERWINTER_MIN_TX_VERSION) { + return state.DoS(100, error("CheckTransaction(): overwinter version too low"), + REJECT_INVALID, "bad-tx-overwinter-version-too-low"); + } + if (tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) { + return state.DoS(100, error("CheckTransaction(): unknown tx version group id"), + REJECT_INVALID, "bad-tx-version-group-id"); + } + if (tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) { + return state.DoS(100, error("CheckTransaction(): expiry height is too high"), + REJECT_INVALID, "bad-tx-expiry-height-too-high"); + } + } // Transactions can contain empty `vin` and `vout` so long as // `vjoinsplit` is non-empty. @@ -1047,30 +1177,6 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio if (txin.prevout.IsNull()) return state.DoS(10, error("CheckTransaction(): prevout is null"), REJECT_INVALID, "bad-txns-prevout-null"); - - if (tx.vjoinsplit.size() > 0) { - // Empty output script. - CScript scriptCode; - uint256 dataToBeSigned; - try { - dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL); - } catch (std::logic_error ex) { - return state.DoS(100, error("CheckTransaction(): error computing signature hash"), - REJECT_INVALID, "error-computing-signature-hash"); - } - - BOOST_STATIC_ASSERT(crypto_sign_PUBLICKEYBYTES == 32); - - // We rely on libsodium to check that the signature is canonical. - // https://github.com/jedisct1/libsodium/commit/62911edb7ff2275cccd74bf1c8aefcc4d76924e0 - if (crypto_sign_verify_detached(&tx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - tx.joinSplitPubKey.begin() - ) != 0) { - return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"), - REJECT_INVALID, "bad-txns-invalid-joinsplit-signature"); - } - } } return true; @@ -1112,6 +1218,21 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa AssertLockHeld(cs_main); if (pfMissingInputs) *pfMissingInputs = false; + + int nextBlockHeight = chainActive.Height() + 1; + auto consensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus()); + + // Node operator can choose to reject tx by number of transparent inputs + static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); + size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0); + if (limit > 0) { + size_t n = tx.vin.size(); + if (n > limit) { + LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit ); + return false; + } + } + auto verifier = libzcash::ProofVerifier::Strict(); if ( komodo_validate_interest(tx,chainActive.Tip()->nHeight+1,chainActive.Tip()->GetMedianTimePast() + 777,0) < 0 ) { @@ -1119,10 +1240,14 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return error("AcceptToMemoryPool: komodo_validate_interest failed"); } if (!CheckTransaction(tx, state, verifier)) - { - fprintf(stderr,"accept failure.0\n"); return error("AcceptToMemoryPool: CheckTransaction failed"); + + // DoS level set to 10 to be more forgiving. + // Check transaction contextually against the set of consensus rules which apply in the next block to be mined. + if (!ContextualCheckTransaction(tx, state, nextBlockHeight, 10)) { + return error("AcceptToMemoryPool: ContextualCheckTransaction failed"); } + // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) { @@ -1131,9 +1256,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } // Rather not work on nonstandard transactions (unless -testnet/-regtest) string reason; - if (Params().RequireStandard() && !IsStandardTx(tx, reason)) + if (Params().RequireStandard() && !IsStandardTx(tx, reason, nextBlockHeight)) { - fprintf(stderr,"AcceptToMemoryPool nonstandard transaction: %s\n",reason.c_str()); + fprintf(stderr,"AcceptToMemoryPool reject nonstandard transaction: %s\n",reason.c_str()); return state.DoS(0,error("AcceptToMemoryPool: nonstandard transaction: %s", reason),REJECT_NONSTANDARD, reason); } // Only accept nLockTime-using transactions that can be mined in the next @@ -1144,38 +1269,40 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa //fprintf(stderr,"AcceptToMemoryPool reject non-final\n"); return state.DoS(0, false, REJECT_NONSTANDARD, "non-final"); } - // is it already in the memory pool? + // is it already in the memory pool? uint256 hash = tx.GetHash(); if (pool.exists(hash)) { fprintf(stderr,"already in mempool\n"); return false; } - + // Check for conflicts with in-memory transactions { - LOCK(pool.cs); // protect pool.mapNextTx - for (unsigned int i = 0; i < tx.vin.size(); i++) - { - COutPoint outpoint = tx.vin[i].prevout; - if (pool.mapNextTx.count(outpoint)) + LOCK(pool.cs); // protect pool.mapNextTx + for (unsigned int i = 0; i < tx.vin.size(); i++) { - static uint32_t counter; - // Disable replacement feature for now - //if ( counter++ < 100 ) - fprintf(stderr,"Disable replacement feature for now\n"); - return false; - } - } - BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { - BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) { - if (pool.mapNullifiers.count(nf)) + COutPoint outpoint = tx.vin[i].prevout; + if (pool.mapNextTx.count(outpoint)) { - fprintf(stderr,"pool.mapNullifiers.count\n"); + static uint32_t counter; + // Disable replacement feature for now + //if ( counter++ < 100 ) + fprintf(stderr,"Disable replacement feature for now\n"); return false; } } - } + BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) + { + BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) + { + if (pool.mapNullifiers.count(nf)) + { + fprintf(stderr,"pool.mapNullifiers.count\n"); + return false; + } + } + } } { @@ -1184,59 +1311,58 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa int64_t interest; CAmount nValueIn = 0; { - LOCK(pool.cs); - CCoinsViewMemPool viewMemPool(pcoinsTip, pool); - view.SetBackend(viewMemPool); - - // do we already have it? - if (view.HaveCoins(hash)) - { - fprintf(stderr,"view.HaveCoins(hash) error\n"); - return false; - } - - // do all inputs exist? - // Note that this does not check for the presence of actual outputs (see the next check for that), - // and only helps with filling in pfMissingInputs (to determine missing vs spent). - BOOST_FOREACH(const CTxIn txin, tx.vin) { - if (!view.HaveCoins(txin.prevout.hash)) { - if (pfMissingInputs) - *pfMissingInputs = true; - //fprintf(stderr,"missing inputs\n"); + LOCK(pool.cs); + CCoinsViewMemPool viewMemPool(pcoinsTip, pool); + view.SetBackend(viewMemPool); + + // do we already have it? + if (view.HaveCoins(hash)) + { + fprintf(stderr,"view.HaveCoins(hash) error\n"); return false; } - } - - // are the actual inputs available? - if (!view.HaveInputs(tx)) - { - //fprintf(stderr,"accept failure.1\n"); - return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent"); - } - // are the joinsplit's requirements met? - if (!view.HaveJoinSplitRequirements(tx)) - { - fprintf(stderr,"accept failure.2\n"); - return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); - } - - // Bring the best block into scope - view.GetBestBlock(); - - nValueIn = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime); + + // do all inputs exist? + // Note that this does not check for the presence of actual outputs (see the next check for that), + // and only helps with filling in pfMissingInputs (to determine missing vs spent). + BOOST_FOREACH(const CTxIn txin, tx.vin) + { + if (!view.HaveCoins(txin.prevout.hash)) + { + if (pfMissingInputs) + *pfMissingInputs = true; + //fprintf(stderr,"missing inputs\n"); + return false; + } + } + + // are the actual inputs available? + if (!view.HaveInputs(tx)) + { + //fprintf(stderr,"accept failure.1\n"); + return state.Invalid(error("AcceptToMemoryPool: inputs already spent"),REJECT_DUPLICATE, "bad-txns-inputs-spent"); + } + // are the joinsplit's requirements met? + if (!view.HaveJoinSplitRequirements(tx)) + { + //fprintf(stderr,"accept failure.2\n"); + return state.Invalid(error("AcceptToMemoryPool: joinsplit requirements not met"),REJECT_DUPLICATE, "bad-txns-joinsplit-requirements-not-met"); + } + + // Bring the best block into scope + view.GetBestBlock(); + + nValueIn = view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime); if ( 0 && interest != 0 ) fprintf(stderr,"add interest %.8f\n",(double)interest/COIN); - // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool - view.SetBackend(dummy); + // we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool + view.SetBackend(dummy); } - + // Check for non-standard pay-to-script-hash in inputs - if (Params().RequireStandard() && !AreInputsStandard(tx, view)) - { - fprintf(stderr,"accept failure.3\n"); - return error("AcceptToMemoryPool: nonstandard transaction input"); - } - + if (Params().RequireStandard() && !AreInputsStandard(tx, view, consensusBranchId)) + return error("AcceptToMemoryPool: reject nonstandard transaction input"); + // Check that the transaction doesn't have an excessive number of // sigops, making it impossible to mine. Since the coinbase transaction // itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than @@ -1253,10 +1379,26 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; double dPriority = view.GetPriority(tx, chainActive.Height()); - - CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx)); + + // Keep track of transactions that spend a coinbase, which we re-scan + // during reorgs to ensure COINBASE_MATURITY is still met. + bool fSpendsCoinbase = false; + BOOST_FOREACH(const CTxIn &txin, tx.vin) { + const CCoins *coins = view.AccessCoins(txin.prevout.hash); + if (coins->IsCoinBase()) { + fSpendsCoinbase = true; + break; + } + } + + // Grab the branch ID we expect this transaction to commit to. We don't + // yet know if it does, but if the entry gets added to the mempool, then + // it has passed ContextualCheckInputs and therefore this is correct. + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + + CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx), fSpendsCoinbase, consensusBranchId); unsigned int nSize = entry.GetTxSize(); - + // Accept a tx if it contains joinsplits and has at least the default fee specified by z_sendmany. if (tx.vjoinsplit.size() > 0 && nFees >= ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE) { // In future we will we have more accurate and dynamic computation of fees for tx with joinsplits. @@ -1269,13 +1411,13 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return state.DoS(0, error("AcceptToMemoryPool: not enough fees %s, %d < %d",hash.ToString(), nFees, txMinFee),REJECT_INSUFFICIENTFEE, "insufficient fee"); } } - + // Require that free transactions have sufficient priority to be mined in the next block. if (GetBoolArg("-relaypriority", false) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(view.GetPriority(tx, chainActive.Height() + 1))) { fprintf(stderr,"accept failure.6\n"); return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } - + // Continuously rate-limit free (really, very-low-fee) transactions // This mitigates 'penny-flooding' -- sending thousands of free transactions just to // be annoying or make others' transactions take longer to confirm. @@ -1285,9 +1427,9 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa static double dFreeCount; static int64_t nLastTime; int64_t nNow = GetTime(); - + LOCK(csFreeLimiter); - + // Use an exponentially decaying ~10-minute window: dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); nLastTime = nNow; @@ -1301,21 +1443,22 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); dFreeCount += nSize; } - + if (fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19 ) { fprintf(stderr,"accept failure.8\n"); return error("AcceptToMemoryPool: absurdly high fees %s, %d > %d",hash.ToString(), nFees, ::minRelayTxFee.GetFee(nSize) * 10000); } - + // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. - if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, Params().GetConsensus())) + PrecomputedTransactionData txdata(tx); + if (!ContextualCheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) { - fprintf(stderr,"accept failure.9\n"); + //fprintf(stderr,"accept failure.9\n"); return error("AcceptToMemoryPool: ConnectInputs failed %s", hash.ToString()); } - + // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause // transactions to pass as valid when they're actually invalid. For @@ -1325,20 +1468,20 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa // There is a similar check in CreateNewBlock() to prevent creating // invalid blocks, however allowing such transactions into the mempool // can be exploited as a DoS attack. - if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, Params().GetConsensus())) + if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) { fprintf(stderr,"accept failure.10\n"); return error("AcceptToMemoryPool: BUG! PLEASE REPORT THIS! ConnectInputs failed against MANDATORY but not STANDARD flags %s", hash.ToString()); } - + // Store transaction in memory if ( komodo_is_notarytx(tx) == 0 ) KOMODO_ON_DEMAND++; pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); } - + SyncWithWallets(tx, NULL); - + return true; } @@ -1750,7 +1893,7 @@ void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state } } -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight) +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txundo, int nHeight) { if (!tx.IsCoinBase()) // mark inputs spent { @@ -1780,15 +1923,15 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs } -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight) +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight) { CTxUndo txundo; - UpdateCoins(tx, state, inputs, txundo, nHeight); + UpdateCoins(tx, inputs, txundo, nHeight); } bool CScriptCheck::operator()() { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; - if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, cacheStore), &error)) { + if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), consensusBranchId, &error)) { return ::error("CScriptCheck(): %s:%d VerifySignature failed: %s", ptxTo->GetHash().ToString(), nIn, ScriptErrorString(error)); } return true; @@ -1843,14 +1986,14 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins // Check for negative or overflow input values nValueIn += coins->vout[prevout.n].nValue; #ifdef KOMODO_ENABLE_INTEREST - if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && nSpendHeight > 60000 )//chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 ) { if ( coins->vout[prevout.n].nValue >= 10*COIN ) { int64_t interest; int32_t txheight; uint32_t locktime; - if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue)) != 0 ) + if ( (interest= komodo_accrued_interest(&txheight,&locktime,prevout.hash,prevout.n,0,coins->vout[prevout.n].nValue,(int32_t)nSpendHeight-1)) != 0 ) { - //fprintf(stderr,"checkResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nValueIn/COIN,(double)coins->vout[prevout.n].nValue/COIN,(double)interest/COIN,txheight,locktime,chainActive.Tip()->nTime); +//fprintf(stderr,"checkResult %.8f += val %.8f interest %.8f ht.%d lock.%u tip.%u\n",(double)nValueIn/COIN,(double)coins->vout[prevout.n].nValue/COIN,(double)interest/COIN,txheight,locktime,chainActive.Tip()->nTime); nValueIn += interest; } } @@ -1868,9 +2011,11 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins REJECT_INVALID, "bad-txns-inputvalues-outofrange"); if (nValueIn < tx.GetValueOut()) + { + fprintf(stderr,"spentheight.%d valuein %s vs %s error\n",nSpendHeight,FormatMoney(nValueIn).c_str(), FormatMoney(tx.GetValueOut()).c_str()); return state.DoS(100, error("CheckInputs(): %s value in (%s) < value out (%s) diff %.8f", tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()),((double)nValueIn - tx.GetValueOut())/COIN),REJECT_INVALID, "bad-txns-in-belowout"); - + } // Tally transaction fees CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) @@ -1884,13 +2029,24 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins } }// namespace Consensus -bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, std::vector *pvChecks) +bool ContextualCheckInputs( + const CTransaction& tx, + CValidationState &state, + const CCoinsViewCache &inputs, + bool fScriptChecks, + unsigned int flags, + bool cacheStore, + PrecomputedTransactionData& txdata, + const Consensus::Params& consensusParams, + uint32_t consensusBranchId, + std::vector *pvChecks) { - if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) - return false; - if (!tx.IsCoinBase()) { + if (!Consensus::CheckTxInputs(tx, state, inputs, GetSpendHeight(inputs), consensusParams)) { + return false; + } + if (pvChecks) pvChecks->reserve(tx.vin.size()); @@ -1908,7 +2064,7 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons assert(coins); // Verify signature - CScriptCheck check(*coins, tx, i, flags, cacheStore); + CScriptCheck check(*coins, tx, i, flags, cacheStore, consensusBranchId, &txdata); if (pvChecks) { pvChecks->push_back(CScriptCheck()); check.swap(pvChecks->back()); @@ -1920,9 +2076,9 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons // arguments; if so, don't trigger DoS protection to // avoid splitting the network between upgraded and // non-upgraded nodes. - CScriptCheck check(*coins, tx, i, - flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore); - if (check()) + CScriptCheck check2(*coins, tx, i, + flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore, consensusBranchId, &txdata); + if (check2()) return state.Invalid(false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); } // Failures of other flags indicate a transaction that is @@ -2228,7 +2384,7 @@ void PartitionCheck(bool (*initialDownloadCheck)(), CCriticalSection& cs, const while (i->GetBlockTime() >= startTime) { ++nBlocks; i = i->pprev; - if (i == NULL) return; // Ran out of chain, we must not be fully sync'ed + if (i == NULL) return; // Ran out of chain, we must not be fully synced } // How likely is it to find that many by chance? @@ -2272,11 +2428,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin const CChainParams& chainparams = Params(); //fprintf(stderr,"connectblock ht.%d\n",(int32_t)pindex->nHeight); AssertLockHeld(cs_main); -/*<<<<<<< HEA - // Check it again in case a previous version let a bad block in - bool fExpensiveChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints())); -======= -*/ bool fExpensiveChecks = true; if (fCheckpointsEnabled) { CBlockIndex *pindexLastCheckpoint = Checkpoints::GetLastCheckpoint(chainparams.Checkpoints()); @@ -2285,7 +2436,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin fExpensiveChecks = false; } } -//>>>>>>> zcash/master auto verifier = libzcash::ProofVerifier::Strict(); auto disabledVerifier = libzcash::ProofVerifier::Disabled(); @@ -2323,19 +2473,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin REJECT_INVALID, "bad-txns-BIP30"); } - unsigned int flags = SCRIPT_VERIFY_P2SH; + unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - // Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, - // when 75% of the network has upgraded: - if (block.nVersion >= 3) { - flags |= SCRIPT_VERIFY_DERSIG; - } - - // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 - // blocks, when 75% of the network has upgraded: - if (block.nVersion >= 4) { - flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - } + // DERSIG (BIP66) is also always enforced, but does not have a flag. CBlockUndo blockundo; @@ -2369,6 +2509,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin assert(tree.root() == old_tree_root); } + // Grab the consensus branch ID for the block's height + auto consensusBranchId = CurrentEpochBranchId(pindex->nHeight, Params().GetConsensus()); + + std::vector txdata; + txdata.reserve(block.vtx.size()); // Required so that pointers to individual PrecomputedTransactionData don't get invalidated for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; @@ -2396,11 +2541,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (nSigOps > MAX_BLOCK_SIGOPS) return state.DoS(100, error("ConnectBlock(): too many sigops"), REJECT_INVALID, "bad-blk-sigops"); + } + txdata.emplace_back(tx); + + if (!tx.IsCoinBase()) + { nFees += view.GetValueIn(chainActive.Tip()->nHeight,&interest,tx,chainActive.Tip()->nTime) - tx.GetValueOut(); sum += interest; + std::vector vChecks; - if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, chainparams.GetConsensus(), nScriptCheckThreads ? &vChecks : NULL)) + if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, false, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL)) return false; control.Add(vChecks); } @@ -2410,7 +2561,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (i > 0) { blockundo.vtxundo.push_back(CTxUndo()); } - UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); + UpdateCoins(tx, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { BOOST_FOREACH(const uint256 ¬e_commitment, joinsplit.commitments) { @@ -2464,6 +2615,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pindex->nStatus |= BLOCK_HAVE_UNDO; } + // Now that all consensus rules have been validated, set nCachedBranchId. + // Move this if BLOCK_VALID_CONSENSUS is ever altered. + static_assert(BLOCK_VALID_CONSENSUS == BLOCK_VALID_SCRIPTS, + "nCachedBranchId must be set after all consensus rules have been validated."); + if (IsActivationHeightForAnyUpgrade(pindex->nHeight, Params().GetConsensus())) { + pindex->nStatus |= BLOCK_ACTIVATES_UPGRADE; + pindex->nCachedBranchId = CurrentEpochBranchId(pindex->nHeight, chainparams.GetConsensus()); + } else if (pindex->pprev) { + pindex->nCachedBranchId = pindex->pprev->nCachedBranchId; + } + pindex->RaiseValidity(BLOCK_VALID_SCRIPTS); setDirtyBlockIndex.insert(pindex); } @@ -2651,11 +2813,13 @@ void static UpdateTip(CBlockIndex *pindexNew) { } } -/** Disconnect chainActive's tip. */ -bool static DisconnectTip(CValidationState &state) { +/** + * Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and + * mempool.removeWithoutBranchId after this, with cs_main held. + */ +bool static DisconnectTip(CValidationState &state, bool fBare = false) { CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); - mempool.check(pcoinsTip); // Read block from disk. CBlock block; if (!ReadBlockFromDisk(block, pindexDelete)) @@ -2674,21 +2838,23 @@ bool static DisconnectTip(CValidationState &state) { // Write the chain state to disk, if necessary. if (!FlushStateToDisk(state, FLUSH_STATE_IF_NEEDED)) return false; - // Resurrect mempool transactions from the disconnected block. - BOOST_FOREACH(const CTransaction &tx, block.vtx) { - // ignore validation errors in resurrected transactions - list removed; - CValidationState stateDummy; - if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) - mempool.remove(tx, removed, true); + + if (!fBare) { + // Resurrect mempool transactions from the disconnected block. + BOOST_FOREACH(const CTransaction &tx, block.vtx) { + // ignore validation errors in resurrected transactions + list removed; + CValidationState stateDummy; + if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL)) + mempool.remove(tx, removed, true); + } + if (anchorBeforeDisconnect != anchorAfterDisconnect) { + // The anchor may not change between block disconnects, + // in which case we don't want to evict from the mempool yet! + mempool.removeWithAnchor(anchorBeforeDisconnect); + } } - if (anchorBeforeDisconnect != anchorAfterDisconnect) { - // The anchor may not change between block disconnects, - // in which case we don't want to evict from the mempool yet! - mempool.removeWithAnchor(anchorBeforeDisconnect); - } - mempool.removeCoinbaseSpends(pcoinsTip, pindexDelete->nHeight); - mempool.check(pcoinsTip); + // Update chainActive and related variables. UpdateTip(pindexDelete->pprev); // Get the current commitment tree @@ -2714,11 +2880,11 @@ static int64_t nTimePostConnect = 0; /** * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * corresponding to pindexNew, to bypass loading it again from disk. + * You probably want to call mempool.removeWithoutBranchId after this, with cs_main held. */ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *pblock) { assert(pindexNew->pprev == chainActive.Tip()); - mempool.check(pcoinsTip); // Read block from disk. int64_t nTime1 = GetTimeMicros(); CBlock block; @@ -2758,7 +2924,10 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * // Remove conflicting transactions from the mempool. list txConflicted; mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload()); - mempool.check(pcoinsTip); + + // Remove transactions that expire at new block height from mempool + mempool.removeExpired(pindexNew->nHeight); + // Update chainActive & related variables. UpdateTip(pindexNew); // Tell wallet about transactions that went from mempool @@ -2774,6 +2943,8 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * //fprintf(stderr,"chaintip true\n"); GetMainSignals().ChainTip(pindexNew, pblock, oldTree, true); + EnforceNodeDeprecation(pindexNew->nHeight); + int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001); LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001); @@ -2860,10 +3031,37 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo const CBlockIndex *pindexOldTip = chainActive.Tip(); const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork); + // - On ChainDB initialization, pindexOldTip will be null, so there are no removable blocks. + // - If pindexMostWork is in a chain that doesn't have the same genesis block as our chain, + // then pindexFork will be null, and we would need to remove the entire chain including + // our genesis block. In practice this (probably) won't happen because of checks elsewhere. + auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0; + static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance"); + if (reorgLength > MAX_REORG_LENGTH) { + auto msg = strprintf(_( + "A block chain reorganization has been detected that would roll back %d blocks! " + "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety." + ), reorgLength, MAX_REORG_LENGTH) + "\n\n" + + _("Reorganization details") + ":\n" + + "- " + strprintf(_("Current tip: %s, height %d, work %s"), + pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" + + "- " + strprintf(_("New tip: %s, height %d, work %s"), + pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" + + "- " + strprintf(_("Fork point: %s, height %d"), + pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + + _("Please help, human!"); + LogPrintf("*** %s\n", msg); + uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; + } + // Disconnect active blocks which are no longer in the best chain. + bool fBlocksDisconnected = false; while (chainActive.Tip() && chainActive.Tip() != pindexFork) { if (!DisconnectTip(state)) return false; + fBlocksDisconnected = true; } if ( KOMODO_REWIND != 0 ) { @@ -2886,43 +3084,50 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo bool fContinue = true; int nHeight = pindexFork ? pindexFork->nHeight : -1; while (fContinue && nHeight != pindexMostWork->nHeight) { - // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need - // a few blocks along the way. - int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); - vpindexToConnect.clear(); - vpindexToConnect.reserve(nTargetHeight - nHeight); - CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); - while (pindexIter && pindexIter->nHeight != nHeight) { - vpindexToConnect.push_back(pindexIter); - pindexIter = pindexIter->pprev; - } - nHeight = nTargetHeight; + // Don't iterate the entire list of potential improvements toward the best tip, as we likely only need + // a few blocks along the way. + int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight); + vpindexToConnect.clear(); + vpindexToConnect.reserve(nTargetHeight - nHeight); + CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight); + while (pindexIter && pindexIter->nHeight != nHeight) { + vpindexToConnect.push_back(pindexIter); + pindexIter = pindexIter->pprev; + } + nHeight = nTargetHeight; - // Connect new blocks. - BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { - if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { - if (state.IsInvalid()) { - // The block violates a consensus rule. - if (!state.CorruptionPossible()) - InvalidChainFound(vpindexToConnect.back()); - state = CValidationState(); - fInvalidFound = true; - fContinue = false; - break; + // Connect new blocks. + BOOST_REVERSE_FOREACH(CBlockIndex *pindexConnect, vpindexToConnect) { + if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : NULL)) { + if (state.IsInvalid()) { + // The block violates a consensus rule. + if (!state.CorruptionPossible()) + InvalidChainFound(vpindexToConnect.back()); + state = CValidationState(); + fInvalidFound = true; + fContinue = false; + break; + } else { + // A system error occurred (disk space, database error, ...). + return false; + } } else { - // A system error occurred (disk space, database error, ...). - return false; - } - } else { - PruneBlockIndexCandidates(); - if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { - // We're in a better position than we were. Return temporarily to release the lock. - fContinue = false; - break; + PruneBlockIndexCandidates(); + if (!pindexOldTip || chainActive.Tip()->nChainWork > pindexOldTip->nChainWork) { + // We're in a better position than we were. Return temporarily to release the lock. + fContinue = false; + break; + } } } } + + if (fBlocksDisconnected) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); } + mempool.removeWithoutBranchId( + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); + mempool.check(pcoinsTip); // Callbacks/notifications for a new best chain. if (fInvalidFound) @@ -3007,6 +3212,9 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. if (!DisconnectTip(state)) { + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + mempool.removeWithoutBranchId( + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); return false; } } @@ -3023,6 +3231,9 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { } InvalidChainFound(pindex); + mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + mempool.removeWithoutBranchId( + CurrentEpochBranchId(chainActive.Tip()->nHeight + 1, Params().GetConsensus())); return true; } @@ -3098,6 +3309,15 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl { pindexNew->nTx = block.vtx.size(); pindexNew->nChainTx = 0; + CAmount sproutValue = 0; + for (auto tx : block.vtx) { + for (auto js : tx.vjoinsplit) { + sproutValue += js.vpub_old; + sproutValue -= js.vpub_new; + } + } + pindexNew->nSproutValue = sproutValue; + pindexNew->nChainSproutValue = boost::none; pindexNew->nFile = pos.nFile; pindexNew->nDataPos = pos.nPos; pindexNew->nUndoPos = 0; @@ -3115,6 +3335,15 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl CBlockIndex *pindex = queue.front(); queue.pop_front(); pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; + if (pindex->pprev) { + if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) { + pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue; + } else { + pindex->nChainSproutValue = boost::none; + } + } else { + pindex->nChainSproutValue = pindex->nSproutValue; + } { LOCK(cs_nBlockSequenceId); pindex->nSequenceId = nBlockSequenceId++; @@ -3312,7 +3541,7 @@ bool CheckBlock(int32_t height,CBlockIndex *pindex,const CBlock& block, CValidat // Check transactions BOOST_FOREACH(const CTransaction& tx, block.vtx) { - if ( komodo_validate_interest(tx,komodo_block2height((CBlock *)&block),block.nTime,1) < 0 ) + if ( komodo_validate_interest(tx,height == 0 ? komodo_block2height((CBlock *)&block) : height,block.nTime,1) < 0 ) return error("CheckBlock: komodo_validate_interest failed"); if (!CheckTransaction(tx, state, verifier)) return error("CheckBlock(): CheckTransaction failed"); @@ -3396,6 +3625,12 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, block.vtx) { + + // Check transaction contextually against consensus rules at block height + if (!ContextualCheckTransaction(tx, state, nHeight, 100)) { + return false; // Failure reason has been set in validation state object + } + int nLockTimeFlags = 0; int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) ? pindexPrev->GetMedianTimePast() @@ -3405,11 +3640,10 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn } } - // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height - // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - // Since MIN_BLOCK_VERSION = 4 all blocks with nHeight > 0 should satisfy this. - // This rule is not applied to the genesis block, which didn't include the height - // in the coinbase. + // Enforce BIP 34 rule that the coinbase starts with serialized block height. + // In Zcash this has been enforced since launch, except that the genesis + // block didn't include the height in the coinbase (see Zcash protocol spec + // section '6.8 Bitcoin Improvement Proposals'). if (nHeight > 0) { CScript expect = CScript() << nHeight; @@ -3855,14 +4089,34 @@ bool static LoadBlockIndexDB() if (pindex->pprev) { if (pindex->pprev->nChainTx) { pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx; + if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) { + pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue; + } else { + pindex->nChainSproutValue = boost::none; + } } else { pindex->nChainTx = 0; + pindex->nChainSproutValue = boost::none; mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex)); } } else { pindex->nChainTx = pindex->nTx; + pindex->nChainSproutValue = pindex->nSproutValue; } } + // Construct in-memory chain of branch IDs. + // Relies on invariant: a block that does not activate a network upgrade + // will always be valid under the same consensus rules as its parent. + // Genesis block has a branch ID of zero by definition, but has no + // validity status because it is side-loaded into a fresh chain. + // Activation blocks will have branch IDs set (read from disk). + if (pindex->pprev) { + if (pindex->IsValid(BLOCK_VALID_CONSENSUS) && !pindex->nCachedBranchId) { + pindex->nCachedBranchId = pindex->pprev->nCachedBranchId; + } + } else { + pindex->nCachedBranchId = SPROUT_BRANCH_ID; + } if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->nChainTx || pindex->pprev == NULL)) setBlockIndexCandidates.insert(pindex); if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork)) @@ -3951,6 +4205,8 @@ bool static LoadBlockIndexDB() DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip())); + EnforceNodeDeprecation(chainActive.Height(), true); + return true; } @@ -4044,6 +4300,135 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth return true; } +bool RewindBlockIndex(const CChainParams& params) +{ + LOCK(cs_main); + + // RewindBlockIndex is called after LoadBlockIndex, so at this point every block + // index will have nCachedBranchId set based on the values previously persisted + // to disk. By definition, a set nCachedBranchId means that the block was + // fully-validated under the corresponding consensus rules. Thus we can quickly + // identify whether the current active chain matches our expected sequence of + // consensus rule changes, with two checks: + // + // - BLOCK_ACTIVATES_UPGRADE is set only on blocks that activate upgrades. + // - nCachedBranchId for each block matches what we expect. + auto sufficientlyValidated = [¶ms](const CBlockIndex* pindex) { + auto consensus = params.GetConsensus(); + bool fFlagSet = pindex->nStatus & BLOCK_ACTIVATES_UPGRADE; + bool fFlagExpected = IsActivationHeightForAnyUpgrade(pindex->nHeight, consensus); + return fFlagSet == fFlagExpected && + pindex->nCachedBranchId && + *pindex->nCachedBranchId == CurrentEpochBranchId(pindex->nHeight, consensus); + }; + + int nHeight = 1; + while (nHeight <= chainActive.Height()) { + if (!sufficientlyValidated(chainActive[nHeight])) { + break; + } + nHeight++; + } + + // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1 + auto rewindLength = chainActive.Height() - nHeight; + if (rewindLength > 0 && rewindLength > MAX_REORG_LENGTH) { + auto pindexOldTip = chainActive.Tip(); + auto pindexRewind = chainActive[nHeight - 1]; + auto msg = strprintf(_( + "A block chain rewind has been detected that would roll back %d blocks! " + "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety." + ), rewindLength, MAX_REORG_LENGTH) + "\n\n" + + _("Rewind details") + ":\n" + + "- " + strprintf(_("Current tip: %s, height %d"), + pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight) + "\n" + + "- " + strprintf(_("Rewinding to: %s, height %d"), + pindexRewind->phashBlock->GetHex(), pindexRewind->nHeight) + "\n\n" + + _("Please help, human!"); + LogPrintf("*** %s\n", msg); + uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; + } + + CValidationState state; + CBlockIndex* pindex = chainActive.Tip(); + while (chainActive.Height() >= nHeight) { + if (fPruneMode && !(chainActive.Tip()->nStatus & BLOCK_HAVE_DATA)) { + // If pruning, don't try rewinding past the HAVE_DATA point; + // since older blocks can't be served anyway, there's + // no need to walk further, and trying to DisconnectTip() + // will fail (and require a needless reindex/redownload + // of the blockchain). + break; + } + if (!DisconnectTip(state, true)) { + return error("RewindBlockIndex: unable to disconnect block at height %i", pindex->nHeight); + } + // Occasionally flush state to disk. + if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) + return false; + } + + // Reduce validity flag and have-data flags. + // We do this after actual disconnecting, otherwise we'll end up writing the lack of data + // to disk before writing the chainstate, resulting in a failure to continue if interrupted. + for (BlockMap::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { + CBlockIndex* pindexIter = it->second; + + // Note: If we encounter an insufficiently validated block that + // is on chainActive, it must be because we are a pruning node, and + // this block or some successor doesn't HAVE_DATA, so we were unable to + // rewind all the way. Blocks remaining on chainActive at this point + // must not have their validity reduced. + if (!sufficientlyValidated(pindexIter) && !chainActive.Contains(pindexIter)) { + // Reduce validity + pindexIter->nStatus = + std::min(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | + (pindexIter->nStatus & ~BLOCK_VALID_MASK); + // Remove have-data flags + pindexIter->nStatus &= ~(BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO); + // Remove branch ID + pindexIter->nStatus &= ~BLOCK_ACTIVATES_UPGRADE; + pindexIter->nCachedBranchId = boost::none; + // Remove storage location + pindexIter->nFile = 0; + pindexIter->nDataPos = 0; + pindexIter->nUndoPos = 0; + // Remove various other things + pindexIter->nTx = 0; + pindexIter->nChainTx = 0; + pindexIter->nSproutValue = boost::none; + pindexIter->nChainSproutValue = boost::none; + pindexIter->nSequenceId = 0; + // Make sure it gets written + setDirtyBlockIndex.insert(pindexIter); + // Update indices + setBlockIndexCandidates.erase(pindexIter); + auto ret = mapBlocksUnlinked.equal_range(pindexIter->pprev); + while (ret.first != ret.second) { + if (ret.first->second == pindexIter) { + mapBlocksUnlinked.erase(ret.first++); + } else { + ++ret.first; + } + } + } else if (pindexIter->IsValid(BLOCK_VALID_TRANSACTIONS) && pindexIter->nChainTx) { + setBlockIndexCandidates.insert(pindexIter); + } + } + + PruneBlockIndexCandidates(); + + CheckBlockIndex(); + + if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) { + return false; + } + + return true; +} + void UnloadBlockIndex() { LOCK(cs_main); @@ -4709,6 +5094,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return false; } + // When Overwinter is active, reject incoming connections from non-Overwinter nodes + const Consensus::Params& params = Params().GetConsensus(); + if (NetworkUpgradeActive(GetHeight(), params, Consensus::UPGRADE_OVERWINTER) + && pfrom->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion) + { + LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); + pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, + strprintf("Version must be %d or greater", + params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)); + pfrom->fDisconnect = true; + return false; + } + if (pfrom->nVersion == 10300) pfrom->nVersion = 300; if (!vRecv.empty()) @@ -4827,6 +5225,22 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } + // Disconnect existing peer connection when: + // 1. The version message has been received + // 2. Overwinter is active + // 3. Peer version is pre-Overwinter + else if (NetworkUpgradeActive(GetHeight(), chainparams.GetConsensus(), Consensus::UPGRADE_OVERWINTER) + && (pfrom->nVersion < chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)) + { + LogPrintf("peer=%d using obsolete version %i; disconnecting\n", pfrom->id, pfrom->nVersion); + pfrom->PushMessage("reject", strCommand, REJECT_OBSOLETE, + strprintf("Version must be %d or greater", + chainparams.GetConsensus().vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion)); + pfrom->fDisconnect = true; + return false; + } + + else if (strCommand == "addr") { vector vAddr; @@ -5938,3 +6352,21 @@ extern "C" const char* getDataDir() return GetDataDir().string().c_str(); } + +// Set default values of new CMutableTransaction based on consensus rules at given height. +CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight) +{ + CMutableTransaction mtx; + + bool isOverwintered = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_OVERWINTER); + if (isOverwintered) { + mtx.fOverwintered = true; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + mtx.nVersion = 3; + // Expiry height is not set. Only fields required for a parser to treat as a valid Overwinter V3 tx. + + // TODO: In future, when moving from Overwinter to Sapling, it will be useful + // to set the expiry height to: min(activation_height - 1, default_expiry_height) + } + return mtx; +} diff --git a/src/main.h b/src/main.h index bcdd04a5e..14513b730 100644 --- a/src/main.h +++ b/src/main.h @@ -15,6 +15,7 @@ #include "chainparams.h" #include "coins.h" #include "consensus/consensus.h" +#include "consensus/upgrades.h" #include "net.h" #include "primitives/block.h" #include "primitives/transaction.h" @@ -44,9 +45,11 @@ class CInv; class CScriptCheck; class CValidationInterface; class CValidationState; +class PrecomputedTransactionData; struct CNodeStateStats; #define DEFAULT_MEMPOOL_EXPIRY 1 +#define _COINBASE_MATURITY 100 /** Default for -blockmaxsize and -blockminsize, which control the range of sizes the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = MAX_BLOCK_SIZE; @@ -57,6 +60,8 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = DEFAULT_BLOCK_MAX_SIZE / static const bool DEFAULT_ALERTS = true; /** Minimum alert priority for enabling safe mode. */ static const int ALERT_PRIORITY_SAFE_MODE = 4000; +/** Maximum reorg length we will accept before we shut down and alert the user. */ +static const unsigned int MAX_REORG_LENGTH = _COINBASE_MATURITY - 1; /** Maximum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; /** The maximum number of sigops we're willing to relay/mine in a single tx */ @@ -65,6 +70,8 @@ static const unsigned int MAX_STANDARD_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 100; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Default for -txexpirydelta, in number of blocks */ +static const unsigned int DEFAULT_TX_EXPIRY_DELTA = 20; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ @@ -107,6 +114,7 @@ struct BlockHasher size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } }; +extern unsigned int expiryDelta; extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern CTxMemPool mempool; @@ -305,7 +313,7 @@ CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowF * @param[in] mapInputs Map of previous transactions that have outputs we're spending * @return True if all inputs (scriptSigs) use only standard transaction forms */ -bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs); +bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, uint32_t consensusBranchId); /** * Count ECDSA signature operations the old-fashioned (pre-0.6) way @@ -330,11 +338,17 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma * instead of being performed inline. */ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks, - unsigned int flags, bool cacheStore, const Consensus::Params& consensusParams, + unsigned int flags, bool cacheStore, PrecomputedTransactionData& txdata, + const Consensus::Params& consensusParams, uint32_t consensusBranchId, std::vector *pvChecks = NULL); +/** Check a transaction contextually against a set of consensus rules */ +bool ContextualCheckTransaction(const CTransaction& tx, CValidationState &state, int nHeight, int dosLevel); + /** Apply the effects of this transaction on the UTXO set represented by view */ -void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, int nHeight); +void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight); + +/** Transaction validation functions */ /** Context-independent validity checks */ bool CheckTransaction(const CTransaction& tx, CValidationState& state, libzcash::ProofVerifier& verifier); @@ -343,7 +357,18 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio /** Check for standard transaction types * @return True if all outputs (scriptPubKeys) use only standard transaction forms */ -bool IsStandardTx(const CTransaction& tx, std::string& reason); +bool IsStandardTx(const CTransaction& tx, std::string& reason, int nHeight = 0); + +namespace Consensus { + +/** + * Check whether all inputs of this transaction are valid (no double spends and amounts) + * This does not modify the UTXO set. This does not check scripts and sigs. + * Preconditions: tx.IsCoinBase() is false. + */ +bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams); + +} // namespace Consensus /** * Check if transaction is final and can be included in a block with the @@ -351,6 +376,12 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason); */ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime); +/** + * Check if transaction is expired and can be included in a block with the + * specified height. Consensus critical. + */ +bool IsExpiredTx(const CTransaction &tx, int nBlockHeight); + /** * Check if transaction will be final in the next block to be created. * @@ -368,27 +399,33 @@ class CScriptCheck { private: CScript scriptPubKey; + CAmount amount; const CTransaction *ptxTo; unsigned int nIn; unsigned int nFlags; bool cacheStore; + uint32_t consensusBranchId; ScriptError error; + PrecomputedTransactionData *txdata; public: - CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false), error(SCRIPT_ERR_UNKNOWN_ERROR) {} - CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) : - scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), - ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), error(SCRIPT_ERR_UNKNOWN_ERROR) { } + CScriptCheck(): amount(0), ptxTo(0), nIn(0), nFlags(0), cacheStore(false), consensusBranchId(0), error(SCRIPT_ERR_UNKNOWN_ERROR) {} + CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn, uint32_t consensusBranchIdIn, PrecomputedTransactionData* txdataIn) : + scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey), amount(txFromIn.vout[txToIn.vin[nInIn].prevout.n].nValue), + ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn), consensusBranchId(consensusBranchIdIn), error(SCRIPT_ERR_UNKNOWN_ERROR), txdata(txdataIn) { } bool operator()(); void swap(CScriptCheck &check) { scriptPubKey.swap(check.scriptPubKey); std::swap(ptxTo, check.ptxTo); + std::swap(amount, check.amount); std::swap(nIn, check.nIn); std::swap(nFlags, check.nFlags); std::swap(cacheStore, check.cacheStore); + std::swap(consensusBranchId, check.consensusBranchId); std::swap(error, check.error); + std::swap(txdata, check.txdata); } ScriptError GetScriptError() const { return error; } @@ -437,6 +474,13 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc +/** + * When there are blocks in the active chain with missing data (e.g. if the + * activation height and branch ID of a particular upgrade have been altered), + * rewind the chainstate and remove them from the block index. + */ +bool RewindBlockIndex(const CChainParams& params); + class CBlockFileInfo { public: @@ -508,7 +552,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); -/** The currently-connected chain of blocks. */ +/** The currently-connected chain of blocks (protected by cs_main). */ extern CChain chainActive; /** Global variable that points to the active CCoinsView (protected by cs_main) */ @@ -524,8 +568,7 @@ extern CBlockTreeDB *pblocktree; */ int GetSpendHeight(const CCoinsViewCache& inputs); -namespace Consensus { -bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, const Consensus::Params& consensusParams); -} +/** Return a CMutableTransaction with contextual default values based on set of consensus rules at height */ +CMutableTransaction CreateNewContextualCMutableTransaction(const Consensus::Params& consensusParams, int nHeight); #endif // BITCOIN_MAIN_H diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index f8e877df2..a368b31ad 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -62,12 +62,12 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, const std::set& txids) uint256 CPartialMerkleTree::CalcHash(int height, unsigned int pos, const std::vector &vTxid) { if (height == 0) { - // hash at height 0 is the txids themself + // hash at height 0 is the txid itself return vTxid[pos]; } else { // calculate left hash uint256 left = CalcHash(height-1, pos*2, vTxid), right; - // calculate right hash if not beyond the end of the array - copy left hash otherwise1 + // calculate right hash if not beyond the end of the array - copy left hash otherwise if (pos*2+1 < CalcTreeWidth(height-1)) right = CalcHash(height-1, pos*2+1, vTxid); else diff --git a/src/merkleblock.h b/src/merkleblock.h index 904c22abc..0181723af 100644 --- a/src/merkleblock.h +++ b/src/merkleblock.h @@ -67,7 +67,7 @@ protected: return (nTransactions+(1 << height)-1) >> height; } - /** calculate the hash of a node in the merkle tree (at leaf level: the txid's themselves) */ + /** calculate the hash of a node in the merkle tree (at leaf level: the txid itself) */ uint256 CalcHash(int height, unsigned int pos, const std::vector &vTxid); /** recursive function that traverses tree nodes, storing the data as bits and hashes */ diff --git a/src/metrics.cpp b/src/metrics.cpp index b45b5dc6b..6c8f80fe5 100644 --- a/src/metrics.cpp +++ b/src/metrics.cpp @@ -5,11 +5,13 @@ #include "metrics.h" #include "chainparams.h" +#include "checkpoints.h" #include "main.h" #include "ui_interface.h" #include "util.h" #include "utiltime.h" #include "utilmoneystr.h" +#include "utilstrencodings.h" #include #include @@ -50,6 +52,12 @@ bool AtomicTimer::running() return threads > 0; } +uint64_t AtomicTimer::threadCount() +{ + std::unique_lock lock(mtx); + return threads; +} + double AtomicTimer::rate(const AtomicCounter& count) { std::unique_lock lock(mtx); @@ -101,6 +109,36 @@ double GetLocalSolPS() return miningTimer.rate(solutionTargetChecks); } +int EstimateNetHeightInner(int height, int64_t tipmediantime, + int heightLastCheckpoint, int64_t timeLastCheckpoint, + int64_t genesisTime, int64_t targetSpacing) +{ + // We average the target spacing with the observed spacing to the last + // checkpoint (either from below or above depending on the current height), + // and use that to estimate the current network height. + int medianHeight = height > CBlockIndex::nMedianTimeSpan ? + height - (1 + ((CBlockIndex::nMedianTimeSpan - 1) / 2)) : + height / 2; + double checkpointSpacing = medianHeight > heightLastCheckpoint ? + (double (tipmediantime - timeLastCheckpoint)) / (medianHeight - heightLastCheckpoint) : + (double (timeLastCheckpoint - genesisTime)) / heightLastCheckpoint; + double averageSpacing = (targetSpacing + checkpointSpacing) / 2; + int netheight = medianHeight + ((GetTime() - tipmediantime) / averageSpacing); + // Round to nearest ten to reduce noise + return ((netheight + 5) / 10) * 10; +} + +int EstimateNetHeight(int height, int64_t tipmediantime, CChainParams chainParams) +{ + auto checkpointData = chainParams.Checkpoints(); + return EstimateNetHeightInner( + height, tipmediantime, + Checkpoints::GetTotalBlocksEstimate(checkpointData), + checkpointData.nTimeLastCheckpoint, + chainParams.GenesisBlock().nTime, + chainParams.GetConsensus().nPowTargetSpacing); +} + void TriggerRefresh() { *nNextRefresh = GetTime(); @@ -167,17 +205,25 @@ int printStats(bool mining) int lines = 4; int height; + int64_t tipmediantime; size_t connections; int64_t netsolps; { LOCK2(cs_main, cs_vNodes); height = chainActive.Height(); + tipmediantime = chainActive.Tip()->GetMedianTimePast(); connections = vNodes.size(); netsolps = GetNetworkHashPS(120, -1); } auto localsolps = GetLocalSolPS(); - std::cout << " " << _("Block height") << " | " << height << std::endl; + if (IsInitialBlockDownload()) { + int netheight = EstimateNetHeight(height, tipmediantime, Params()); + int downloadPercent = height * 100 / netheight; + std::cout << " " << _("Downloading blocks") << " | " << height << " / ~" << netheight << " (" << downloadPercent << "%)" << std::endl; + } else { + std::cout << " " << _("Block height") << " | " << height << std::endl; + } std::cout << " " << _("Connections") << " | " << connections << std::endl; std::cout << " " << _("Network solution rate") << " | " << netsolps << " Sol/s" << std::endl; if (mining && miningTimer.running()) { @@ -196,15 +242,8 @@ int printMiningStatus(bool mining) int lines = 1; if (mining) { - int nThreads = GetArg("-genproclimit", 1); - if (nThreads < 0) { - // In regtest threads defaults to 1 - if (Params().DefaultMinerThreads()) - nThreads = Params().DefaultMinerThreads(); - else - nThreads = boost::thread::hardware_concurrency(); - } - if (miningTimer.running()) { + auto nThreads = miningTimer.threadCount(); + if (nThreads > 0) { std::cout << strprintf(_("You are mining with the %s solver on %d threads."), GetArg("-equihashsolver", "default"), nThreads) << std::endl; } else { @@ -339,20 +378,19 @@ int printMessageBox(size_t cols) int lines = 2 + u->size(); std::cout << _("Messages:") << std::endl; for (auto it = u->cbegin(); it != u->cend(); ++it) { - std::cout << *it << std::endl; + auto msg = FormatParagraph(*it, cols, 2); + std::cout << "- " << msg << std::endl; // Handle newlines and wrapped lines size_t i = 0; size_t j = 0; - while (j < it->size()) { - i = it->find('\n', j); + while (j < msg.size()) { + i = msg.find('\n', j); if (i == std::string::npos) { - i = it->size(); + i = msg.size(); } else { // Newline lines++; } - // Wrapped lines - lines += ((i-j) / cols); j = i + 1; } } diff --git a/src/metrics.h b/src/metrics.h index 3e830f823..2d60d30ca 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -49,6 +49,8 @@ public: bool running(); + uint64_t threadCount(); + double rate(const AtomicCounter& count); }; @@ -61,6 +63,9 @@ void TrackMinedBlock(uint256 hash); void MarkStartTime(); double GetLocalSolPS(); +int EstimateNetHeightInner(int height, int64_t tipmediantime, + int heightLastCheckpoint, int64_t timeLastCheckpoint, + int64_t genesisTime, int64_t targetSpacing); void TriggerRefresh(); diff --git a/src/miner.cpp b/src/miner.cpp index 44acf06c6..9a8eb59a5 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -12,6 +12,7 @@ #include "base58.h" #include "chainparams.h" #include "consensus/consensus.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #ifdef ENABLE_MINING #include "crypto/equihash.h" @@ -100,10 +101,6 @@ public: void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - - // Updating time can change work required on testnet: - if (consensusParams.fPowAllowMinDifficultyBlocks) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); } #include "komodo_defs.h" @@ -115,7 +112,6 @@ extern std::string NOTARY_PUBKEY; extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33]; uint32_t Mining_start,Mining_height; int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp); -int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33],uint32_t timestamp); int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize); uint64_t komodo_paxtotal(); int32_t komodo_baseid(char *origbase); @@ -189,6 +185,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); const int nHeight = pindexPrev->nHeight + 1; + uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus()); pblock->nTime = GetAdjustedTime(); const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast(); CCoinsViewCache view(pcoinsTip); @@ -202,16 +199,16 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // This vector will be sorted into a priority queue: vector vecPriority; vecPriority.reserve(mempool.mapTx.size()); - for (map::iterator mi = mempool.mapTx.begin(); + for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { - const CTransaction& tx = mi->second.GetTx(); + const CTransaction& tx = mi->GetTx(); int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST) ? nMedianTimePast : pblock->GetBlockTime(); - if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff)) + if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight)) continue; if ( komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,2) < 0 ) { @@ -249,7 +246,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) } mapDependers[txin.prevout.hash].push_back(porphan); porphan->setDependsOn.insert(txin.prevout.hash); - nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue; + nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue; continue; } const CCoins* coins = view.AccessCoins(txin.prevout.hash); @@ -281,7 +278,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) porphan->feeRate = feeRate; } else - vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx())); + vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx()))); } // Collect transactions into block @@ -345,10 +342,11 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // policy here, but we still have to ensure that the block we // create only contains transactions that are valid in new blocks. CValidationState state; - if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, Params().GetConsensus())) + PrecomputedTransactionData txdata(tx); + if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId)) continue; - UpdateCoins(tx, state, view, nHeight); + UpdateCoins(tx, view, nHeight); // Added pblock->vtx.push_back(tx); @@ -387,13 +385,13 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Create coinbase tx - CMutableTransaction txNew; - //txNew.nLockTime = (uint32_t)time(NULL) - 60; + CMutableTransaction txNew = CreateNewContextualCMutableTransaction(chainparams.GetConsensus(), nHeight); txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); txNew.vout.resize(1); txNew.vout[0].scriptPubKey = scriptPubKeyIn; txNew.vout[0].nValue = GetBlockSubsidy(nHeight,chainparams.GetConsensus()); + txNew.nExpiryHeight = 0; // Add fees txNew.vout[0].nValue += nFees; txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; @@ -525,7 +523,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& // // Internal miner // -int8_t komodo_minerid(int32_t height,uint8_t *pubkey33); CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) { @@ -550,12 +547,6 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) script[34] = OP_CHECKSIG; //scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; } - if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 ) - { - for (i=0; i<65; i++) - fprintf(stderr,"%d ",komodo_minerid(chainActive.Tip()->nHeight-i,0)); - fprintf(stderr," minerids.special %d from ht.%d\n",komodo_is_special(chainActive.Tip()->nHeight+1,NOTARY_PUBKEY33,chainActive.Tip()->GetBlockTime()),chainActive.Tip()->nHeight); - } return CreateNewBlock(scriptPubKey); } @@ -763,7 +754,7 @@ void static BitcoinMiner() savebits = pblock->nBits; arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); roundrobin_delay = ROUNDROBIN_DELAY; - if ( ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 )//komodo_is_special(pindexPrev->nHeight+1,NOTARY_PUBKEY33) > 0 ) + if ( ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 ) { j = 65; if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 ) @@ -784,12 +775,6 @@ void static BitcoinMiner() break; if ( externalflag == 0 && i != 66 ) printf("VIOLATION at %d\n",i); - for (i=0; i<66; i++) - { break; - for (j=0; j<33; j++) - printf("%02x",pubkeys[i][j]); - printf(" p%d -> %d\n",i,komodo_minerid(pindexPrev->nHeight-i,pubkeys[i])); - } for (j=gpucount=0; j<65; j++) { if ( mids[j] >= 0 || notaryid == 34 ) @@ -914,7 +899,7 @@ void static BitcoinMiner() equi eq(1); eq.setstate(&curr_state); - // Intialization done, start algo driver. + // Initialization done, start algo driver. eq.digit0(0); eq.xfull = eq.bfull = eq.hfull = 0; eq.showbsizes(0); @@ -1000,18 +985,12 @@ void static BitcoinMiner() // Update nNonce and nTime pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); pblock->nBits = savebits; - //UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks) { // Changing pblock->nTime can change work required on testnet: hashTarget.SetCompact(pblock->nBits); } - /*CValidationState tmpstate; - if ( !TestBlockValidity(tmpstate, *pblock, pindexPrev, false, false)) - { - fprintf(stderr,"formerly valid mining block became invalid, likely due to tx expiration\n"); - break; - }*/ } } } @@ -1041,13 +1020,8 @@ void GenerateBitcoins(bool fGenerate, int nThreads) { static boost::thread_group* minerThreads = NULL; - if (nThreads < 0) { - // In regtest threads defaults to 1 - if (Params().DefaultMinerThreads()) - nThreads = Params().DefaultMinerThreads(); - else - nThreads = boost::thread::hardware_concurrency(); - } + if (nThreads < 0) + nThreads = GetNumCores(); if (minerThreads != NULL) { diff --git a/src/net.cpp b/src/net.cpp index 0dcdae7db..fe6ee1b77 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -7,6 +7,7 @@ #include "config/bitcoin-config.h" #endif +#include "main.h" #include "net.h" #include "addrman.h" @@ -23,13 +24,6 @@ #include #endif -#ifdef USE_UPNP -#include -#include -#include -#include -#endif - #include #include @@ -542,24 +536,22 @@ void CNode::AddWhitelistedRange(const CSubNet &subnet) { vWhitelistedRange.push_back(subnet); } -#undef X -#define X(name) stats.name = name void CNode::copyStats(CNodeStats &stats) { stats.nodeid = this->GetId(); - X(nServices); - X(nLastSend); - X(nLastRecv); - X(nTimeConnected); - X(nTimeOffset); - X(addrName); - X(nVersion); - X(cleanSubVer); - X(fInbound); - X(nStartingHeight); - X(nSendBytes); - X(nRecvBytes); - X(fWhitelisted); + stats.nServices = nServices; + stats.nLastSend = nLastSend; + stats.nLastRecv = nLastRecv; + stats.nTimeConnected = nTimeConnected; + stats.nTimeOffset = nTimeOffset; + stats.addrName = addrName; + stats.nVersion = nVersion; + stats.cleanSubVer = cleanSubVer; + stats.fInbound = fInbound; + stats.nStartingHeight = nStartingHeight; + stats.nSendBytes = nSendBytes; + stats.nRecvBytes = nRecvBytes; + stats.fWhitelisted = fWhitelisted; // It is common for nodes with good ping times to suddenly become lagged, // due to a new block arriving or other large transfer. @@ -579,7 +571,6 @@ void CNode::copyStats(CNodeStats &stats) // Leave string empty if addrLocal invalid (not filled in yet) stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : ""; } -#undef X // requires LOCK(cs_vRecvMsg) bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) @@ -820,6 +811,34 @@ static bool AttemptToEvictConnection(bool fPreferNewConnection) { // Protect connections with certain characteristics + // Check version of eviction candidates and prioritize nodes which do not support network upgrade. + std::vector vTmpEvictionCandidates; + int height; + { + LOCK(cs_main); + height = chainActive.Height(); + } + + const Consensus::Params& params = Params().GetConsensus(); + int nActivationHeight = params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight; + + if (nActivationHeight > 0 && + height < nActivationHeight && + height >= nActivationHeight - NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD) + { + // Find any nodes which don't support Overwinter protocol version + BOOST_FOREACH(const CNodeRef &node, vEvictionCandidates) { + if (node->nVersion < params.vUpgrades[Consensus::UPGRADE_OVERWINTER].nProtocolVersion) { + vTmpEvictionCandidates.push_back(node); + } + } + + // Prioritize these nodes by replacing eviction set with them + if (vTmpEvictionCandidates.size() > 0) { + vEvictionCandidates = vTmpEvictionCandidates; + } + } + // Deterministically select 4 peers to protect by netgroup. // An attacker cannot predict which netgroups will be protected. static CompareNetGroupKeyed comparerNetGroupKeyed; @@ -1053,7 +1072,7 @@ void ThreadSocketHandler() // happens when optimistic write failed, we choose to first drain the // write buffer in this case before receiving more. This avoids // needlessly queueing received data, if the remote peer is not themselves - // receiving data. This means properly utilizing TCP flow control signalling. + // receiving data. This means properly utilizing TCP flow control signaling. // * Otherwise, if there is no (complete) message in the receive buffer, // or there is space left in the buffer, select() for receiving data. // * (if neither of the above applies, there is certainly one message @@ -1216,131 +1235,6 @@ void ThreadSocketHandler() } - - - - - - - -#ifdef USE_UPNP -void ThreadMapPort() -{ - std::string port = strprintf("%u", GetListenPort()); - const char * multicastif = 0; - const char * minissdpdpath = 0; - struct UPNPDev * devlist = 0; - char lanaddr[64]; - -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#elif MINIUPNPC_API_VERSION < 14 - /* miniupnpc 1.6 */ - int error = 0; - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); -#else - /* miniupnpc 1.9.20150730 */ - int error = 0; - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); -#endif - - struct UPNPUrls urls; - struct IGDdatas data; - int r; - - r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); - if (r == 1) - { - if (fDiscover) { - char externalIPAddress[40]; - r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) - LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); - else - { - if(externalIPAddress[0]) - { - LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress); - AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP); - } - else - LogPrintf("UPnP: GetExternalIPAddress failed.\n"); - } - } - - string strDesc = "Bitcoin " + FormatFullVersion(); - - try { - while (true) { -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); -#else - /* miniupnpc 1.6 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); -#endif - - if(r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else - LogPrintf("UPnP Port Mapping successful.\n");; - - MilliSleep(20*60*1000); // Refresh every 20 minutes - } - } - catch (const boost::thread_interrupted&) - { - r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); - LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); - freeUPNPDevlist(devlist); devlist = 0; - FreeUPNPUrls(&urls); - throw; - } - } else { - LogPrintf("No valid UPnP IGDs found\n"); - freeUPNPDevlist(devlist); devlist = 0; - if (r != 0) - FreeUPNPUrls(&urls); - } -} - -void MapPort(bool fUseUPnP) -{ - static boost::thread* upnp_thread = NULL; - - if (fUseUPnP) - { - if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - delete upnp_thread; - } - upnp_thread = new boost::thread(boost::bind(&TraceThread, "upnp", &ThreadMapPort)); - } - else if (upnp_thread) { - upnp_thread->interrupt(); - upnp_thread->join(); - delete upnp_thread; - upnp_thread = NULL; - } -} - -#else -void MapPort(bool) -{ - // Intentionally left blank. -} -#endif - - - - - - void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute @@ -1769,7 +1663,7 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind.ToString()); + strError = strprintf(_("Unable to bind to %s on this computer. Zcash is probably already running."), addrBind.ToString()); else strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr)); LogPrintf("%s\n", strError); @@ -1880,9 +1774,6 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) else threadGroup.create_thread(boost::bind(&TraceThread, "dnsseed", &ThreadDNSAddressSeed)); - // Map ports with UPnP - MapPort(GetBoolArg("-upnp", DEFAULT_UPNP)); - // Send and receive from sockets, accept connections threadGroup.create_thread(boost::bind(&TraceThread, "net", &ThreadSocketHandler)); @@ -1902,7 +1793,6 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) bool StopNode() { LogPrintf("StopNode()\n"); - MapPort(false); if (semOutbound) for (int i=0; ipost(); diff --git a/src/net.h b/src/net.h index 6f28f3872..afb8c9659 100644 --- a/src/net.h +++ b/src/net.h @@ -51,18 +51,14 @@ static const unsigned int MAX_ADDR_TO_SEND = 1000; static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; /** -listen default */ static const bool DEFAULT_LISTEN = true; -/** -upnp default */ -#ifdef USE_UPNP -static const bool DEFAULT_UPNP = USE_UPNP; -#else -static const bool DEFAULT_UPNP = false; -#endif /** The maximum number of entries in mapAskFor */ static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ; /** The maximum number of entries in setAskFor (larger due to getdata latency)*/ static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ; /** The maximum number of peer connections to maintain. */ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; +/** The period before a network upgrade activates, where connections to upgrading peers are preferred (in blocks). */ +static const int NETWORK_UPGRADE_PEER_PREFERENCE_BLOCK_PERIOD = 24 * 24 * 3; unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); @@ -75,7 +71,6 @@ CNode* FindNode(const std::string& addrName); CNode* FindNode(const CService& ip); CNode* ConnectNode(CAddress addrConnect, const char *pszDest = NULL); bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); -void MapPort(bool fUseUPnP); unsigned short GetListenPort(); bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false); void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler); @@ -118,7 +113,7 @@ enum LOCAL_NONE, // unknown LOCAL_IF, // address a local interface listens on LOCAL_BIND, // address explicit bound to - LOCAL_UPNP, // address reported by UPnP + LOCAL_UPNP, // unused (was: address reported by UPnP) LOCAL_MANUAL, // address explicitly specified (-externalip=) LOCAL_MAX diff --git a/src/netbase.cpp b/src/netbase.cpp index 6a28532f1..7369b0167 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -146,7 +146,7 @@ bool static LookupIntern(const char *pszName, std::vector& vIP, unsign return false; do { - // Should set the timeout limit to a resonable value to avoid + // Should set the timeout limit to a reasonable value to avoid // generating unnecessary checking call during the polling loop, // while it can still response to stop request quick enough. // 2 seconds looks fine in our situation. diff --git a/src/netbase.h b/src/netbase.h index 83ce22663..ea3bdbd8d 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -61,7 +61,7 @@ class CNetAddr bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor) bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) - bool IsRFC2544() const; // IPv4 inter-network communcations (192.18.0.0/15) + bool IsRFC2544() const; // IPv4 inter-network communications (192.18.0.0/15) bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10) bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore deleted file mode 100644 index d6b7ef32c..000000000 --- a/src/obj-test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/paymentdisclosure.cpp b/src/paymentdisclosure.cpp new file mode 100644 index 000000000..a33b1c604 --- /dev/null +++ b/src/paymentdisclosure.cpp @@ -0,0 +1,63 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "paymentdisclosure.h" +#include "util.h" + +std::string PaymentDisclosureInfo::ToString() const { + return strprintf("PaymentDisclosureInfo(version=%d, esk=%s, joinSplitPrivKey=, address=%s)", + version, esk.ToString(), CZCPaymentAddress(zaddr).ToString()); +} + +std::string PaymentDisclosure::ToString() const { + std::string s = HexStr(payloadSig.begin(), payloadSig.end()); + return strprintf("PaymentDisclosure(payload=%s, payloadSig=%s)", payload.ToString(), s); +} + +std::string PaymentDisclosurePayload::ToString() const { + return strprintf("PaymentDisclosurePayload(version=%d, esk=%s, txid=%s, js=%d, n=%d, address=%s, message=%s)", + version, esk.ToString(), txid.ToString(), js, n, CZCPaymentAddress(zaddr).ToString(), message); +} + +PaymentDisclosure::PaymentDisclosure(const uint256 &joinSplitPubKey, const PaymentDisclosureKey &key, const PaymentDisclosureInfo &info, const std::string &message) +{ + // Populate payload member variable + payload.version = info.version; // experimental = 0, production = 1 etc. + payload.esk = info.esk; + payload.txid = key.hash; + payload.js = key.js; + payload.n = key.n; + payload.zaddr = info.zaddr; + payload.message = message; + + // Serialize and hash the payload to generate a signature + uint256 dataToBeSigned = SerializeHash(payload, SER_GETHASH, 0); + + LogPrint("paymentdisclosure", "Payment Disclosure: signing raw payload = %s\n", dataToBeSigned.ToString()); + + // Prepare buffer to store ed25519 key pair in libsodium-compatible format + unsigned char bufferKeyPair[64]; + memcpy(&bufferKeyPair[0], info.joinSplitPrivKey.begin(), 32); + memcpy(&bufferKeyPair[32], joinSplitPubKey.begin(), 32); + + // Compute payload signature member variable + if (!(crypto_sign_detached(payloadSig.data(), NULL, + dataToBeSigned.begin(), 32, + &bufferKeyPair[0] + ) == 0)) + { + throw std::runtime_error("crypto_sign_detached failed"); + } + + // Sanity check + if (!(crypto_sign_verify_detached(payloadSig.data(), + dataToBeSigned.begin(), 32, + joinSplitPubKey.begin()) == 0)) + { + throw std::runtime_error("crypto_sign_verify_detached failed"); + } + + std::string sigString = HexStr(payloadSig.data(), payloadSig.data() + payloadSig.size()); + LogPrint("paymentdisclosure", "Payment Disclosure: signature = %s\n", sigString); +} diff --git a/src/paymentdisclosure.h b/src/paymentdisclosure.h new file mode 100644 index 000000000..e6a995ab4 --- /dev/null +++ b/src/paymentdisclosure.h @@ -0,0 +1,147 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_PAYMENTDISCLOSURE_H +#define ZCASH_PAYMENTDISCLOSURE_H + +#include "uint256.h" +#include "clientversion.h" +#include "serialize.h" +#include "streams.h" +#include "version.h" + +// For JSOutPoint +#include "wallet/wallet.h" + +#include +#include + + +// Ensure that the two different protocol messages, payment disclosure blobs and transactions, +// which are signed with the same key, joinSplitPrivKey, have disjoint encodings such that an +// encoding from one context will be rejected in the other. We know that the set of valid +// transaction versions is currently ({1..INT32_MAX}) so we will use a negative value for +// payment disclosure of -10328976 which in hex is 0xFF626470. Serialization is in little endian +// format, so a payment disclosure hex string begins 706462FF, which in ISO-8859-1 is "pdbÿ". +#define PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES -10328976 + +#define PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL 0 + +#define PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX "zpd:" + +typedef JSOutPoint PaymentDisclosureKey; + +struct PaymentDisclosureInfo { + uint8_t version; // 0 = experimental, 1 = first production version, etc. + uint256 esk; // zcash/NoteEncryption.cpp + uint256 joinSplitPrivKey; // primitives/transaction.h + // ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc + + libzcash::PaymentAddress zaddr; + + PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) { + } + + PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::PaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(version); + READWRITE(esk); + READWRITE(joinSplitPrivKey); + READWRITE(zaddr); + } + + std::string ToString() const; + + friend bool operator==(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) { + return (a.version == b.version && a.esk == b.esk && a.joinSplitPrivKey == b.joinSplitPrivKey && a.zaddr == b.zaddr); + } + + friend bool operator!=(const PaymentDisclosureInfo& a, const PaymentDisclosureInfo& b) { + return !(a == b); + } + +}; + + +struct PaymentDisclosurePayload { + int32_t marker = PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES; // to be disjoint from transaction encoding + uint8_t version; // 0 = experimental, 1 = first production version, etc. + uint256 esk; // zcash/NoteEncryption.cpp + uint256 txid; // primitives/transaction.h + size_t js; // Index into CTransaction.vjoinsplit + uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS + libzcash::PaymentAddress zaddr; // zcash/Address.hpp + std::string message; // parameter to RPC call + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(marker); + READWRITE(version); + READWRITE(esk); + READWRITE(txid); + READWRITE(js); + READWRITE(n); + READWRITE(zaddr); + READWRITE(message); + } + + std::string ToString() const; + + friend bool operator==(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) { + return ( + a.version == b.version && + a.esk == b.esk && + a.txid == b.txid && + a.js == b.js && + a.n == b.n && + a.zaddr == b.zaddr && + a.message == b.message + ); + } + + friend bool operator!=(const PaymentDisclosurePayload& a, const PaymentDisclosurePayload& b) { + return !(a == b); + } +}; + +struct PaymentDisclosure { + PaymentDisclosurePayload payload; + boost::array payloadSig; + // We use boost array because serialize doesn't like char buffer, otherwise we could do: unsigned char payloadSig[64]; + + PaymentDisclosure() {}; + PaymentDisclosure(const PaymentDisclosurePayload payload, const boost::array sig) : payload(payload), payloadSig(sig) {}; + PaymentDisclosure(const uint256& joinSplitPubKey, const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info, const std::string& message); + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(payload); + READWRITE(payloadSig); + } + + std::string ToString() const; + + friend bool operator==(const PaymentDisclosure& a, const PaymentDisclosure& b) { + return (a.payload == b.payload && a.payloadSig == b.payloadSig); + } + + friend bool operator!=(const PaymentDisclosure& a, const PaymentDisclosure& b) { + return !(a == b); + } +}; + + + +typedef std::pair PaymentDisclosureKeyInfo; + + +#endif // ZCASH_PAYMENTDISCLOSURE_H diff --git a/src/paymentdisclosuredb.cpp b/src/paymentdisclosuredb.cpp new file mode 100644 index 000000000..ef32f2845 --- /dev/null +++ b/src/paymentdisclosuredb.cpp @@ -0,0 +1,93 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "paymentdisclosuredb.h" + +#include "util.h" +#include "leveldbwrapper.h" + +#include + +using namespace std; + +static boost::filesystem::path emptyPath; + +/** + * Static method to return the shared/default payment disclosure database. + */ +shared_ptr PaymentDisclosureDB::sharedInstance() { + // Thread-safe in C++11 and gcc 4.3 + static shared_ptr ptr = std::make_shared(); + return ptr; +} + +// C++11 delegated constructor +PaymentDisclosureDB::PaymentDisclosureDB() : PaymentDisclosureDB(emptyPath) { +} + +PaymentDisclosureDB::PaymentDisclosureDB(const boost::filesystem::path& dbPath) { + boost::filesystem::path path(dbPath); + if (path.empty()) { + path = GetDataDir() / "paymentdisclosure"; + LogPrintf("PaymentDisclosure: using default path for database: %s\n", path.string()); + } else { + LogPrintf("PaymentDisclosure: using custom path for database: %s\n", path.string()); + } + + TryCreateDirectory(path); + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, path.string(), &db); + HandleError(status); // throws exception + LogPrintf("PaymentDisclosure: Opened LevelDB successfully\n"); +} + +PaymentDisclosureDB::~PaymentDisclosureDB() { + if (db != nullptr) { + delete db; + } +} + +bool PaymentDisclosureDB::Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info) +{ + if (db == nullptr) { + return false; + } + + std::lock_guard guard(lock_); + + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + ssValue.reserve(ssValue.GetSerializeSize(info)); + ssValue << info; + leveldb::Slice slice(&ssValue[0], ssValue.size()); + + leveldb::Status status = db->Put(writeOptions, key.ToString(), slice); + HandleError(status); + return true; +} + +bool PaymentDisclosureDB::Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info) +{ + if (db == nullptr) { + return false; + } + + std::lock_guard guard(lock_); + + std::string strValue; + leveldb::Status status = db->Get(readOptions, key.ToString(), &strValue); + if (!status.ok()) { + if (status.IsNotFound()) + return false; + LogPrintf("PaymentDisclosure: LevelDB read failure: %s\n", status.ToString()); + HandleError(status); + } + + try { + CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(), SER_DISK, CLIENT_VERSION); + ssValue >> info; + } catch (const std::exception&) { + return false; + } + return true; +} diff --git a/src/paymentdisclosuredb.h b/src/paymentdisclosuredb.h new file mode 100644 index 000000000..9352cac8f --- /dev/null +++ b/src/paymentdisclosuredb.h @@ -0,0 +1,42 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ZCASH_PAYMENTDISCLOSUREDB_H +#define ZCASH_PAYMENTDISCLOSUREDB_H + +#include "paymentdisclosure.h" + +#include +#include +#include +#include +#include + +#include + +#include + + +class PaymentDisclosureDB +{ +protected: + leveldb::DB* db = nullptr; + leveldb::Options options; + leveldb::ReadOptions readOptions; + leveldb::WriteOptions writeOptions; + mutable std::mutex lock_; + +public: + static std::shared_ptr sharedInstance(); + + PaymentDisclosureDB(); + PaymentDisclosureDB(const boost::filesystem::path& dbPath); + ~PaymentDisclosureDB(); + + bool Put(const PaymentDisclosureKey& key, const PaymentDisclosureInfo& info); + bool Get(const PaymentDisclosureKey& key, PaymentDisclosureInfo& info); +}; + + +#endif // ZCASH_PAYMENTDISCLOSUREDB_H diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index dd534d803..e1fb1c3c6 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -16,14 +16,12 @@ void TxConfirmStats::Initialize(std::vector& defaultBuckets, { decay = _decay; dataTypeString = _dataTypeString; - //for (unsigned int i = 0; i < defaultBuckets.size(); i++) { - // buckets.push_back(defaultBuckets[i]); - // bucketMap[defaultBuckets[i]] = i; buckets.insert(buckets.end(), defaultBuckets.begin(), defaultBuckets.end()); buckets.push_back(std::numeric_limits::infinity()); for (unsigned int i = 0; i < buckets.size(); i++) { bucketMap[buckets[i]] = i; } + confAvg.resize(maxConfirms); curBlockConf.resize(maxConfirms); unconfTxs.resize(maxConfirms); @@ -57,7 +55,6 @@ unsigned int TxConfirmStats::FindBucketIndex(double val) { extern char ASSETCHAINS_SYMBOL[]; auto it = bucketMap.lower_bound(val); - //assert(it != bucketMap.end()); if ( it != bucketMap.end() ) { static uint32_t counter; @@ -72,7 +69,6 @@ void TxConfirmStats::Record(int blocksToConfirm, double val) // blocksToConfirm is 1-based if (blocksToConfirm < 1) return; - //unsigned int bucketindex = bucketMap.lower_bound(val)->second; unsigned int bucketindex = FindBucketIndex(val); for (size_t i = blocksToConfirm; i <= curBlockConf.size(); i++) { curBlockConf[i - 1][bucketindex]++; @@ -264,7 +260,6 @@ void TxConfirmStats::Read(CAutoFile& filein) unsigned int TxConfirmStats::NewTx(unsigned int nBlockHeight, double val) { - //unsigned int bucketindex = bucketMap.lower_bound(val)->second; unsigned int bucketindex = FindBucketIndex(val); unsigned int blockIndex = nBlockHeight % unconfTxs.size(); unconfTxs[blockIndex][bucketindex]++; @@ -325,7 +320,6 @@ CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate& _minRelayFee) for (double bucketBoundary = minTrackedFee.GetFeePerK(); bucketBoundary <= MAX_FEERATE; bucketBoundary *= FEE_SPACING) { vfeelist.push_back(bucketBoundary); } - //vfeelist.push_back(INF_FEERATE); feeStats.Initialize(vfeelist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "FeeRate"); minTrackedPriority = AllowFreeThreshold() < MIN_PRIORITY ? MIN_PRIORITY : AllowFreeThreshold(); @@ -333,7 +327,6 @@ CBlockPolicyEstimator::CBlockPolicyEstimator(const CFeeRate& _minRelayFee) for (double bucketBoundary = minTrackedPriority; bucketBoundary <= MAX_PRIORITY; bucketBoundary *= PRI_SPACING) { vprilist.push_back(bucketBoundary); } - //vprilist.push_back(INF_PRIORITY); priStats.Initialize(vprilist, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "Priority"); feeUnlikely = CFeeRate(0); diff --git a/src/policy/fees.h b/src/policy/fees.h index 999fa4dc1..6d43189be 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -28,7 +28,7 @@ class CTxMemPoolEntry; * included in blocks before transactions of lower fee/priority. So for * example if you wanted to know what fee you should put on a transaction to * be included in a block within the next 5 blocks, you would start by looking - * at the bucket with with the highest fee transactions and verifying that a + * at the bucket with the highest fee transactions and verifying that a * sufficiently high percentage of them were confirmed within 5 blocks and * then you would look at the next highest fee bucket, and so on, stopping at * the last bucket to pass the test. The average fee of transactions in this @@ -71,7 +71,7 @@ static const double DEFAULT_DECAY = .998; /** * We will instantiate two instances of this class, one to track transactions - * that were included in a block due to fee, and one for tx's included due to + * that were included in a block due to fee, and one for txs included due to * priority. We will lump transactions into a bucket according to their approximate * fee or priority and then track how long it took for those txs to be included * in a block. There is always a bucket into which any given double value @@ -100,7 +100,7 @@ private: // and calcuate the totals for the current block to update the moving averages std::vector > curBlockConf; // curBlockConf[Y][X] - // Sum the total priority/fee of all tx's in each bucket + // Sum the total priority/fee of all txs in each bucket // Track the historical moving average of this total over blocks std::vector avg; // and calculate the total for the current block to update the moving average @@ -214,7 +214,7 @@ static const double FEE_SPACING = 1.1; static const double PRI_SPACING = 2; /** - * We want to be able to estimate fees or priorities that are needed on tx's to be included in + * We want to be able to estimate fees or priorities that are needed on txs to be included in * a certain number of blocks. Every time a block is added to the best chain, this class records * stats on the transactions included in that block */ diff --git a/src/pow.cpp b/src/pow.cpp index 9621fadad..76960933d 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -120,7 +120,6 @@ int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33, int32_t komodo_is_special(int32_t height,uint8_t pubkey33[33],uint32_t timestamp); int32_t komodo_currentheight(); CBlockIndex *komodo_chainactive(int32_t height); -int8_t komodo_minerid(int32_t height,uint8_t *pubkey33); void komodo_index2pubkey33(uint8_t *pubkey33,CBlockIndex *pindex,int32_t height); extern int32_t KOMODO_CHOSEN_ONE; extern char ASSETCHAINS_SYMBOL[]; @@ -169,7 +168,7 @@ bool CheckProofOfWork(int32_t height,uint8_t *pubkey33,uint256 hash, unsigned in // Check proof of work matches claimed amount if ( UintToArith256(hash) > bnTarget ) { - if ( (height < 235300 || height >= 236000) && KOMODO_LOADINGBLOCKS == 0 && height > 188000 ) + if ( 0 && (height < 235300 || height >= 236000) && KOMODO_LOADINGBLOCKS == 0 && height > 188000 ) //&& )//186269, 182507&& komodo_chainactive(height) != 0 && nonzpkeys > 0 { for (i=31; i>=0; i--) diff --git a/src/pow/tromp/equi_miner.h b/src/pow/tromp/equi_miner.h index 9559c178e..ae527827a 100644 --- a/src/pow/tromp/equi_miner.h +++ b/src/pow/tromp/equi_miner.h @@ -3,7 +3,7 @@ // Fix N, K, such that n = N/(k+1) is integer // Fix M = 2^{n+1} hashes each of length N bits, -// H_0, ... , H_{M-1}, generated fom (n+1)-bit indices. +// H_0, ... , H_{M-1}, generated from (n+1)-bit indices. // Problem: find binary tree on 2^K distinct indices, // for which the exclusive-or of leaf hashes is all 0s. // Additionally, it should satisfy the Wagner conditions: diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 9f4a0eae0..d6ad31c3a 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -16,13 +16,12 @@ JSDescription::JSDescription(ZCJoinSplit& params, const boost::array& outputs, CAmount vpub_old, CAmount vpub_new, - bool computeProof) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) + bool computeProof, + uint256 *esk // payment disclosure + ) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) { boost::array notes; - if (computeProof) { - params.loadProvingKey(); - } proof = params.prove( inputs, outputs, @@ -37,7 +36,8 @@ JSDescription::JSDescription(ZCJoinSplit& params, vpub_old, vpub_new, anchor, - computeProof + computeProof, + esk // payment disclosure ); } @@ -57,7 +57,9 @@ JSDescription JSDescription::Randomized( CAmount vpub_old, CAmount vpub_new, bool computeProof, - std::function gen) + uint256 *esk, // payment disclosure + std::function gen + ) { // Randomize the order of the inputs and outputs inputMap = {0, 1}; @@ -70,7 +72,9 @@ JSDescription JSDescription::Randomized( return JSDescription( params, pubKeyHash, anchor, inputs, outputs, - vpub_old, vpub_new, computeProof); + vpub_old, vpub_new, computeProof, + esk // payment disclosure + ); } bool JSDescription::Verify( @@ -147,8 +151,9 @@ std::string CTxOut::ToString() const return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); } -CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::MIN_CURRENT_VERSION), nLockTime(0) {} -CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), +CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), nLockTime(0) {} +CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), + vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig) { @@ -164,19 +169,34 @@ void CTransaction::UpdateHash() const *const_cast(&hash) = SerializeHash(*this); } -CTransaction::CTransaction() : nVersion(CTransaction::MIN_CURRENT_VERSION), vin(), vout(), nLockTime(0), vjoinsplit(), joinSplitPubKey(), joinSplitSig() { } +CTransaction::CTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), vin(), vout(), nLockTime(0), vjoinsplit(), joinSplitPubKey(), joinSplitSig() { } -CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), vjoinsplit(tx.vjoinsplit), - joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig) +CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), + vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), + vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig) { UpdateHash(); } +// Protected constructor which only derived classes can call. +// For developer testing only. +CTransaction::CTransaction( + const CMutableTransaction &tx, + bool evilDeveloperFlag) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight), + vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), + vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig) +{ + assert(evilDeveloperFlag); +} + CTransaction& CTransaction::operator=(const CTransaction &tx) { + *const_cast(&fOverwintered) = tx.fOverwintered; *const_cast(&nVersion) = tx.nVersion; + *const_cast(&nVersionGroupId) = tx.nVersionGroupId; *const_cast*>(&vin) = tx.vin; *const_cast*>(&vout) = tx.vout; *const_cast(&nLockTime) = tx.nLockTime; + *const_cast(&nExpiryHeight) = tx.nExpiryHeight; *const_cast*>(&vjoinsplit) = tx.vjoinsplit; *const_cast(&joinSplitPubKey) = tx.joinSplitPubKey; *const_cast(&joinSplitSig) = tx.joinSplitSig; @@ -249,12 +269,24 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const std::string CTransaction::ToString() const { std::string str; - str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n", - GetHash().ToString().substr(0,10), - nVersion, - vin.size(), - vout.size(), - nLockTime); + if (!fOverwintered) { + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n", + GetHash().ToString().substr(0,10), + nVersion, + vin.size(), + vout.size(), + nLockTime); + } else if (nVersion >= 3) { + str += strprintf("CTransaction(hash=%s, ver=%d, fOverwintered=%d, nVersionGroupId=%08x, vin.size=%u, vout.size=%u, nLockTime=%u, nExpiryHeight=%u)\n", + GetHash().ToString().substr(0,10), + nVersion, + fOverwintered, + nVersionGroupId, + vin.size(), + vout.size(), + nLockTime, + nExpiryHeight); + } for (unsigned int i = 0; i < vin.size(); i++) str += " " + vin[i].ToString() + "\n"; for (unsigned int i = 0; i < vout.size(); i++) diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 699b7a89f..35c12abc8 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -81,7 +81,8 @@ public: const boost::array& outputs, CAmount vpub_old, CAmount vpub_new, - bool computeProof = true // Set to false in some tests + bool computeProof = true, // Set to false in some tests + uint256 *esk = nullptr // payment disclosure ); static JSDescription Randomized( @@ -100,6 +101,7 @@ public: CAmount vpub_old, CAmount vpub_new, bool computeProof = true, // Set to false in some tests + uint256 *esk = nullptr, // payment disclosure std::function gen = GetRandInt ); @@ -310,6 +312,10 @@ public: std::string ToString() const; }; +// Overwinter version group id +static constexpr uint32_t OVERWINTER_VERSION_GROUP_ID = 0x03C48270; +static_assert(OVERWINTER_VERSION_GROUP_ID != 0, "version group id must be non-zero as specified in ZIP 202"); + struct CMutableTransaction; /** The basic transaction that is broadcasted on the network and contained in @@ -322,14 +328,29 @@ private: const uint256 hash; void UpdateHash() const; +protected: + /** Developer testing only. Set evilDeveloperFlag to true. + * Convert a CMutableTransaction into a CTransaction without invoking UpdateHash() + */ + CTransaction(const CMutableTransaction &tx, bool evilDeveloperFlag); + public: typedef boost::array joinsplit_sig_t; - // Transactions that include a list of JoinSplits are version 2. - static const int32_t MIN_CURRENT_VERSION = 1; - static const int32_t MAX_CURRENT_VERSION = 2; + // Transactions that include a list of JoinSplits are >= version 2. + static const int32_t SPROUT_MIN_CURRENT_VERSION = 1; + static const int32_t SPROUT_MAX_CURRENT_VERSION = 2; + static const int32_t OVERWINTER_MIN_CURRENT_VERSION = 3; + static const int32_t OVERWINTER_MAX_CURRENT_VERSION = 3; - static_assert(MIN_CURRENT_VERSION >= MIN_TX_VERSION, + static_assert(SPROUT_MIN_CURRENT_VERSION >= SPROUT_MIN_TX_VERSION, + "standard rule for tx version should be consistent with network rule"); + + static_assert(OVERWINTER_MIN_CURRENT_VERSION >= OVERWINTER_MIN_TX_VERSION, + "standard rule for tx version should be consistent with network rule"); + + static_assert( (OVERWINTER_MAX_CURRENT_VERSION <= OVERWINTER_MAX_TX_VERSION && + OVERWINTER_MAX_CURRENT_VERSION >= OVERWINTER_MIN_CURRENT_VERSION), "standard rule for tx version should be consistent with network rule"); // The local variables are made const to prevent unintended modification @@ -337,10 +358,13 @@ public: // actually immutable; deserialization and assignment are implemented, // and bypass the constness. This is safe, as they update the entire // structure, including the hash. + const bool fOverwintered; const int32_t nVersion; + const uint32_t nVersionGroupId; const std::vector vin; const std::vector vout; const uint32_t nLockTime; + const uint32_t nExpiryHeight; const std::vector vjoinsplit; const uint256 joinSplitPubKey; const joinsplit_sig_t joinSplitSig = {{0}}; @@ -357,11 +381,34 @@ public: template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(*const_cast(&this->nVersion)); + if (ser_action.ForRead()) { + // When deserializing, unpack the 4 byte header to extract fOverwintered and nVersion. + uint32_t header; + READWRITE(header); + *const_cast(&fOverwintered) = header >> 31; + *const_cast(&this->nVersion) = header & 0x7FFFFFFF; + } else { + uint32_t header = GetHeader(); + READWRITE(header); + } nVersion = this->nVersion; + if (fOverwintered) { + READWRITE(*const_cast(&this->nVersionGroupId)); + } + + bool isOverwinterV3 = fOverwintered && + nVersionGroupId == OVERWINTER_VERSION_GROUP_ID && + nVersion == 3; + if (fOverwintered && !isOverwinterV3) { + throw std::ios_base::failure("Unknown transaction format"); + } + READWRITE(*const_cast*>(&vin)); READWRITE(*const_cast*>(&vout)); READWRITE(*const_cast(&nLockTime)); + if (isOverwinterV3) { + READWRITE(*const_cast(&nExpiryHeight)); + } if (nVersion >= 2) { READWRITE(*const_cast*>(&vjoinsplit)); if (vjoinsplit.size() > 0) { @@ -381,6 +428,16 @@ public: return hash; } + uint32_t GetHeader() const { + // When serializing v1 and v2, the 4 byte header is nVersion + uint32_t header = this->nVersion; + // When serializing Overwintered tx, the 4 byte header is the combination of fOverwintered and nVersion + if (fOverwintered) { + header |= 1 << 31; + } + return header; + } + // Return sum of txouts. CAmount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because @@ -416,10 +473,13 @@ public: /** A mutable version of CTransaction. */ struct CMutableTransaction { + bool fOverwintered; int32_t nVersion; + uint32_t nVersionGroupId; std::vector vin; std::vector vout; uint32_t nLockTime; + uint32_t nExpiryHeight; std::vector vjoinsplit; uint256 joinSplitPubKey; CTransaction::joinsplit_sig_t joinSplitSig = {{0}}; @@ -431,11 +491,39 @@ struct CMutableTransaction template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(this->nVersion); + if (ser_action.ForRead()) { + // When deserializing, unpack the 4 byte header to extract fOverwintered and nVersion. + uint32_t header; + READWRITE(header); + fOverwintered = header >> 31; + this->nVersion = header & 0x7FFFFFFF; + } else { + // When serializing v1 and v2, the 4 byte header is nVersion + uint32_t header = this->nVersion; + // When serializing Overwintered tx, the 4 byte header is the combination of fOverwintered and nVersion + if (fOverwintered) { + header |= 1 << 31; + } + READWRITE(header); + } nVersion = this->nVersion; + if (fOverwintered) { + READWRITE(nVersionGroupId); + } + + bool isOverwinterV3 = fOverwintered && + nVersionGroupId == OVERWINTER_VERSION_GROUP_ID && + nVersion == 3; + if (fOverwintered && !isOverwinterV3) { + throw std::ios_base::failure("Unknown transaction format"); + } + READWRITE(vin); READWRITE(vout); READWRITE(nLockTime); + if (isOverwinterV3) { + READWRITE(nExpiryHeight); + } if (nVersion >= 2) { READWRITE(vjoinsplit); if (vjoinsplit.size() > 0) { diff --git a/src/protocol.h b/src/protocol.h index b5e65032a..b0208b01c 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -71,10 +71,6 @@ enum { // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want // network services but don't provide them. NODE_NETWORK = (1 << 0), - // NODE_GETUTXO means the node is capable of responding to the getutxo protocol request. - // Bitcoin Core does not support this but a patch set called Bitcoin XT does. - // See BIP 64 for details on how this is implemented. - NODE_GETUTXO = (1 << 1), // Bits 24-31 are reserved for temporary experiments. Just pick a bit that // isn't getting used, or one not being used much, and notify the diff --git a/src/pubkey.cpp b/src/pubkey.cpp index bdab13760..0b87bb526 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -1,73 +1,101 @@ // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "pubkey.h" -#include "eccryptoverify.h" +#include +#include + +namespace +{ +/* Global secp256k1_context object used for verification. */ +secp256k1_context* secp256k1_context_verify = NULL; +} -#include "ecwrapper.h" bool CPubKey::Verify(const uint256 &hash, const std::vector& vchSig) const { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { return false; - if (!key.Verify(hash, vchSig)) + } + if (vchSig.size() == 0) { return false; - return true; + } + /* Zcash, unlike Bitcoin, has always enforced strict DER signatures. */ + if (!secp256k1_ecdsa_signature_parse_der(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) { + return false; + } + /* libsecp256k1's ECDSA verification requires lower-S signatures, which have + * not historically been enforced in Bitcoin or Zcash, so normalize them first. */ + secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig); + return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey); } bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector& vchSig) { - if (vchSig.size() != 65) + if (vchSig.size() != COMPACT_SIGNATURE_SIZE) return false; int recid = (vchSig[0] - 27) & 3; bool fComp = ((vchSig[0] - 27) & 4) != 0; - CECKey key; - if (!key.Recover(hash, &vchSig[1], recid)) + secp256k1_pubkey pubkey; + secp256k1_ecdsa_recoverable_signature sig; + if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) { return false; - std::vector pubkey; - key.GetPubKey(pubkey, fComp); - Set(pubkey.begin(), pubkey.end()); + } + if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) { + return false; + } + unsigned char pub[PUBLIC_KEY_SIZE]; + size_t publen = PUBLIC_KEY_SIZE; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED); + Set(pub, pub + publen); return true; } bool CPubKey::IsFullyValid() const { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) - return false; - return true; + secp256k1_pubkey pubkey; + return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size()); } bool CPubKey::Decompress() { if (!IsValid()) return false; - CECKey key; - if (!key.SetPubKey(begin(), size())) + secp256k1_pubkey pubkey; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { return false; - std::vector pubkey; - key.GetPubKey(pubkey, false); - Set(pubkey.begin(), pubkey.end()); + } + unsigned char pub[PUBLIC_KEY_SIZE]; + size_t publen = PUBLIC_KEY_SIZE; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + Set(pub, pub + publen); return true; } bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { assert(IsValid()); assert((nChild >> 31) == 0); - assert(begin() + 33 == end()); + assert(size() == COMPRESSED_PUBLIC_KEY_SIZE); unsigned char out[64]; BIP32Hash(cc, nChild, *begin(), begin()+1, out); memcpy(ccChild.begin(), out+32, 32); - CECKey key; - bool ret = key.SetPubKey(begin(), size()); - ret &= key.TweakPublic(out); - std::vector pubkey; - key.GetPubKey(pubkey, true); - pubkeyChild.Set(pubkey.begin(), pubkey.end()); - return ret; + secp256k1_pubkey pubkey; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) { + return false; + } + if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) { + return false; + } + unsigned char pub[COMPRESSED_PUBLIC_KEY_SIZE]; + size_t publen = COMPRESSED_PUBLIC_KEY_SIZE; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED); + pubkeyChild.Set(pub, pub + publen); + return true; } void CExtPubKey::Encode(unsigned char code[74]) const { @@ -76,8 +104,8 @@ void CExtPubKey::Encode(unsigned char code[74]) const { code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF; code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF; memcpy(code+9, chaincode.begin(), 32); - assert(pubkey.size() == 33); - memcpy(code+41, pubkey.begin(), 33); + assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE); + memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_PUBLIC_KEY_SIZE); } void CExtPubKey::Decode(const unsigned char code[74]) { @@ -95,3 +123,35 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const { out.nChild = nChild; return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode); } + +/* static */ bool CPubKey::CheckLowS(const std::vector& vchSig) { + secp256k1_ecdsa_signature sig; + + /* Zcash, unlike Bitcoin, has always enforced strict DER signatures. */ + if (!secp256k1_ecdsa_signature_parse_der(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) { + return false; + } + return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig)); +} + +/* static */ int ECCVerifyHandle::refcount = 0; + +ECCVerifyHandle::ECCVerifyHandle() +{ + if (refcount == 0) { + assert(secp256k1_context_verify == NULL); + secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + assert(secp256k1_context_verify != NULL); + } + refcount++; +} + +ECCVerifyHandle::~ECCVerifyHandle() +{ + refcount--; + if (refcount == 0) { + assert(secp256k1_context_verify != NULL); + secp256k1_context_destroy(secp256k1_context_verify); + secp256k1_context_verify = NULL; + } +} diff --git a/src/pubkey.h b/src/pubkey.h index cce9c826e..237237e05 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2017 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -13,16 +14,6 @@ #include #include -/** - * secp256k1: - * const unsigned int PRIVATE_KEY_SIZE = 279; - * const unsigned int PUBLIC_KEY_SIZE = 65; - * const unsigned int SIGNATURE_SIZE = 72; - * - * see www.keylength.com - * script supports up to 75 for single byte push - */ - /** A reference to a CKey: the Hash160 of its serialized public key */ class CKeyID : public uint160 { @@ -36,21 +27,37 @@ typedef uint256 ChainCode; /** An encapsulated public key. */ class CPubKey { +public: + /** + * secp256k1: + */ + static const unsigned int PUBLIC_KEY_SIZE = 65; + static const unsigned int COMPRESSED_PUBLIC_KEY_SIZE = 33; + static const unsigned int SIGNATURE_SIZE = 72; + static const unsigned int COMPACT_SIGNATURE_SIZE = 65; + /** + * see www.keylength.com + * script supports up to 75 for single byte push + */ + static_assert( + PUBLIC_KEY_SIZE >= COMPRESSED_PUBLIC_KEY_SIZE, + "COMPRESSED_PUBLIC_KEY_SIZE is larger than PUBLIC_KEY_SIZE"); + private: /** * Just store the serialized data. * Its length can very cheaply be computed from the first byte. */ - unsigned char vch[65]; + unsigned char vch[PUBLIC_KEY_SIZE]; //! Compute the length of a pubkey with a given first byte. unsigned int static GetLen(unsigned char chHeader) { if (chHeader == 2 || chHeader == 3) - return 33; + return COMPRESSED_PUBLIC_KEY_SIZE; if (chHeader == 4 || chHeader == 6 || chHeader == 7) - return 65; + return PUBLIC_KEY_SIZE; return 0; } @@ -129,7 +136,7 @@ public: void Unserialize(Stream& s, int nType, int nVersion) { unsigned int len = ::ReadCompactSize(s); - if (len <= 65) { + if (len <= PUBLIC_KEY_SIZE) { s.read((char*)vch, len); } else { // invalid pubkey, skip available data @@ -168,7 +175,7 @@ public: //! Check whether this is a compressed public key. bool IsCompressed() const { - return size() == 33; + return size() == COMPRESSED_PUBLIC_KEY_SIZE; } /** @@ -177,6 +184,11 @@ public: */ bool Verify(const uint256& hash, const std::vector& vchSig) const; + /** + * Check whether a signature is normalized (lower-S). + */ + static bool CheckLowS(const std::vector& vchSig); + //! Recover a public key from a compact signature. bool RecoverCompact(const uint256& hash, const std::vector& vchSig); @@ -205,4 +217,15 @@ struct CExtPubKey { bool Derive(CExtPubKey& out, unsigned int nChild) const; }; +/** Users of this module must hold an ECCVerifyHandle. The constructor and + * destructor of these are not allowed to run in parallel, though. */ +class ECCVerifyHandle +{ + static int refcount; + +public: + ECCVerifyHandle(); + ~ECCVerifyHandle(); +}; + #endif // BITCOIN_PUBKEY_H diff --git a/src/rest.cpp b/src/rest.cpp index 1a1e5268b..eb0bf8fc4 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -405,7 +405,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) boost::split(uriParts, strUriParams, boost::is_any_of("/")); } - // throw exception in case of a empty request + // throw exception in case of an empty request std::string strRequestMutable = req->ReadBody(); if (strRequestMutable.length() == 0 && uriParts.size() == 0) return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, "Error: empty request"); @@ -485,7 +485,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart) if (vOutPoints.size() > MAX_GETUTXOS_OUTPOINTS) return RESTERR(req, HTTP_INTERNAL_SERVER_ERROR, strprintf("Error: max outpoints exceeded (max: %d, tried: %d)", MAX_GETUTXOS_OUTPOINTS, vOutPoints.size())); - // check spentness and form a bitmap (as well as a JSON capable human-readble string representation) + // check spentness and form a bitmap (as well as a JSON capable human-readable string representation) vector bitmap; vector outs; std::string bitmapStringRepresentation; diff --git a/src/reverselock.h b/src/reverselock.h index db5c626c9..fac1ccb79 100644 --- a/src/reverselock.h +++ b/src/reverselock.h @@ -15,10 +15,12 @@ public: explicit reverse_lock(Lock& lock) : lock(lock) { lock.unlock(); + lock.swap(templock); } - ~reverse_lock() noexcept(false) { - lock.lock(); + ~reverse_lock() { + templock.lock(); + templock.swap(lock); } private: @@ -26,6 +28,7 @@ private: reverse_lock& operator=(reverse_lock const&); Lock& lock; + Lock templock; }; #endif // BITCOIN_REVERSELOCK_H diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 91f694abb..1254217ac 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -3,6 +3,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "amount.h" +#include "chain.h" +#include "chainparams.h" #include "checkpoints.h" #include "consensus/validation.h" #include "main.h" @@ -74,6 +77,25 @@ double GetNetworkDifficulty(const CBlockIndex* blockindex) return GetDifficultyINTERNAL(blockindex, true); } +static UniValue ValuePoolDesc( + const std::string &name, + const boost::optional chainValue, + const boost::optional valueDelta) +{ + UniValue rv(UniValue::VOBJ); + rv.push_back(Pair("id", name)); + rv.push_back(Pair("monitored", (bool)chainValue)); + if (chainValue) { + rv.push_back(Pair("chainValue", ValueFromAmount(*chainValue))); + rv.push_back(Pair("chainValueZat", *chainValue)); + } + if (valueDelta) { + rv.push_back(Pair("valueDelta", ValueFromAmount(*valueDelta))); + rv.push_back(Pair("valueDeltaZat", *valueDelta)); + } + return rv; +} + UniValue blockheaderToJSON(const CBlockIndex* blockindex) { UniValue result(UniValue::VOBJ); @@ -135,6 +157,10 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); result.push_back(Pair("anchor", blockindex->hashAnchorEnd.GetHex())); + UniValue valuePools(UniValue::VARR); + valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue)); + result.push_back(Pair("valuePools", valuePools)); + if (blockindex->pprev) result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); CBlockIndex *pnext = chainActive.Next(blockindex); @@ -148,7 +174,7 @@ UniValue getblockcount(const UniValue& params, bool fHelp) if (fHelp || params.size() != 0) throw runtime_error( "getblockcount\n" - "\nReturns the number of blocks in the longest block chain.\n" + "\nReturns the number of blocks in the best valid block chain.\n" "\nResult:\n" "n (numeric) The current block count\n" "\nExamples:\n" @@ -200,10 +226,9 @@ UniValue mempoolToJSON(bool fVerbose = false) { LOCK(mempool.cs); UniValue o(UniValue::VOBJ); - BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx) + BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) { - const uint256& hash = entry.first; - const CTxMemPoolEntry& e = entry.second; + const uint256& hash = e.GetTx().GetHash(); UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); @@ -260,7 +285,7 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) "{ (json object)\n" " \"transactionid\" : { (json object)\n" " \"size\" : n, (numeric) transaction size in bytes\n" - " \"fee\" : n, (numeric) transaction fee in bitcoins\n" + " \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" " \"height\" : n, (numeric) block height when transaction entered pool\n" " \"startingpriority\" : n, (numeric) priority when transaction entered pool\n" @@ -527,22 +552,7 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160, //uint32_t komodo_interest_args(int32_t *txheightp,uint32_t *tiptimep,uint64_t *valuep,uint256 hash,int32_t n); int32_t komodo_minerids(uint8_t *minerids,int32_t height,int32_t width); int32_t komodo_kvsearch(uint256 *refpubkeyp,int32_t current_height,uint32_t *flagsp,int32_t *heightp,uint8_t value[IGUANA_MAXSCRIPTSIZE],uint8_t *key,int32_t keylen); -/*uint64_t conv_NXTpassword(unsigned char *mysecret,unsigned char *mypublic,uint8_t *pass,int32_t passlen); - - -UniValue passphrasewif(const UniValue& params, bool fHelp) -{ - UniValue ret(UniValue::VOBJ); char *passphrase,wifstr[64],coinaddr[64]; uint8_t tmptype,pubkey33[33]; void *ctx; uint256 privkey,pubkey; - passphrase = params[0].get_str().c_str(); - conv_NXTpassword((void *)&privkey,(void *)&pubkey,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - ctx = bitcoin_ctx(); - bitcoin_priv2pub(ctx,pubkey33,coinaddr,privkey,0,60); - bitcoin_priv2wif(0,wifstr,privkey,188); - free(ctx); - ret.push_back(Pair("address",coinaddr)); - ret.push_back(Pair("wif",wifstr)); - return ret; -}*/ +int32_t komodo_MoM(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t nHeight); UniValue kvsearch(const UniValue& params, bool fHelp) { @@ -579,6 +589,38 @@ UniValue kvsearch(const UniValue& params, bool fHelp) return ret; } +UniValue height_MoM(const UniValue& params, bool fHelp) +{ + int32_t height,depth,notarized_height; uint256 MoM,kmdtxid; uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); + if ( fHelp || params.size() != 1 ) + throw runtime_error("height_MoM needs height\n"); + LOCK(cs_main); + height = atoi(params[0].get_str().c_str()); + if ( height <= 0 ) + { + if ( chainActive.Tip() == 0 ) + { + ret.push_back(Pair("error",(char *)"no active chain yet")); + return(ret); + } + height = chainActive.Tip()->nHeight; + } + //fprintf(stderr,"height_MoM height.%d\n",height); + depth = komodo_MoM(¬arized_height,&MoM,&kmdtxid,height); + ret.push_back(Pair("coin",(char *)(ASSETCHAINS_SYMBOL[0] == 0 ? "KMD" : ASSETCHAINS_SYMBOL))); + ret.push_back(Pair("height",height)); + ret.push_back(Pair("timestamp",(uint64_t)timestamp)); + if ( depth > 0 ) + { + ret.push_back(Pair("depth",depth)); + ret.push_back(Pair("notarized_height",notarized_height)); + ret.push_back(Pair("MoM",MoM.GetHex())); + ret.push_back(Pair("kmdtxid",kmdtxid.GetHex())); + } else ret.push_back(Pair("error",(char *)"no MoM for height")); + + return ret; +} + UniValue minerids(const UniValue& params, bool fHelp) { uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); uint8_t minerids[2000],pubkeys[65][33]; int32_t i,j,n,numnotaries,tally[129]; @@ -594,7 +636,7 @@ UniValue minerids(const UniValue& params, bool fHelp) if ( pblockindex != 0 ) timestamp = pblockindex->GetBlockTime(); } - if ( (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) + if ( 0 && (n= komodo_minerids(minerids,height,(int32_t)(sizeof(minerids)/sizeof(*minerids)))) > 0 ) { memset(tally,0,sizeof(tally)); numnotaries = komodo_notaries(pubkeys,height,timestamp); @@ -639,57 +681,56 @@ UniValue minerids(const UniValue& params, bool fHelp) UniValue notaries(const UniValue& params, bool fHelp) { UniValue a(UniValue::VARR); uint32_t timestamp=0; UniValue ret(UniValue::VOBJ); int32_t i,j,n,m; char *hexstr; uint8_t pubkeys[64][33]; char btcaddr[64],kmdaddr[64],*ptr; - if ( fHelp || params.size() != 1 ) - throw runtime_error("notaries height\n"); + if ( fHelp || (params.size() != 1 && params.size() != 2) ) + throw runtime_error("notaries height timestamp\n"); LOCK(cs_main); int32_t height = atoi(params[0].get_str().c_str()); + if ( params.size() == 2 ) + timestamp = (uint32_t)atol(params[1].get_str().c_str()); + else timestamp = (uint32_t)time(NULL); if ( height < 0 ) { height = chainActive.Tip()->nHeight; timestamp = chainActive.Tip()->GetBlockTime(); } - else + else if ( params.size() < 2 ) { CBlockIndex *pblockindex = chainActive[height]; if ( pblockindex != 0 ) timestamp = pblockindex->GetBlockTime(); } - //fprintf(stderr,"notaries as of height.%d\n",height); - //if ( height > chainActive.Height()+20000 ) - // throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); - //else + if ( (n= komodo_notaries(pubkeys,height,timestamp)) > 0 ) { - if ( (n= komodo_notaries(pubkeys,height,timestamp)) > 0 ) + for (i=0; inHeight - coins.nHeight + 1)); ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); uint64_t interest; int32_t txheight; uint32_t locktime; - if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue)) != 0 ) + if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue,(int32_t)pindex->nHeight)) != 0 ) ret.push_back(Pair("interest", ValueFromAmount(interest))); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); @@ -944,12 +985,45 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* return rv; } +static UniValue NetworkUpgradeDesc(const Consensus::Params& consensusParams, Consensus::UpgradeIndex idx, int height) +{ + UniValue rv(UniValue::VOBJ); + auto upgrade = NetworkUpgradeInfo[idx]; + rv.push_back(Pair("name", upgrade.strName)); + rv.push_back(Pair("activationheight", consensusParams.vUpgrades[idx].nActivationHeight)); + switch (NetworkUpgradeState(height, consensusParams, idx)) { + case UPGRADE_DISABLED: rv.push_back(Pair("status", "disabled")); break; + case UPGRADE_PENDING: rv.push_back(Pair("status", "pending")); break; + case UPGRADE_ACTIVE: rv.push_back(Pair("status", "active")); break; + } + rv.push_back(Pair("info", upgrade.strInfo)); + return rv; +} + +void NetworkUpgradeDescPushBack( + UniValue& networkUpgrades, + const Consensus::Params& consensusParams, + Consensus::UpgradeIndex idx, + int height) +{ + // Network upgrades with an activation height of NO_ACTIVATION_HEIGHT are + // hidden. This is used when network upgrade implementations are merged + // without specifying the activation height. + if (consensusParams.vUpgrades[idx].nActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT) { + networkUpgrades.push_back(Pair( + HexInt(NetworkUpgradeInfo[idx].nBranchId), + NetworkUpgradeDesc(consensusParams, idx, height))); + } +} + UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( "getblockchaininfo\n" "Returns an object containing various state info regarding block chain processing.\n" + "\nNote that when the chain tip is at the last block before a network upgrade activation,\n" + "consensus.chaintip != consensus.nextblock.\n" "\nResult:\n" "{\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" @@ -972,7 +1046,19 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) " },\n" " \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n" " }, ...\n" - " ]\n" + " ],\n" + " \"upgrades\": { (object) status of network upgrades\n" + " \"xxxx\" : { (string) branch ID of the upgrade\n" + " \"name\": \"xxxx\", (string) name of upgrade\n" + " \"activationheight\": xxxxxx, (numeric) block height of activation\n" + " \"status\": \"xxxx\", (string) status of upgrade\n" + " \"info\": \"xxxx\", (string) additional information about upgrade\n" + " }, ...\n" + " },\n" + " \"consensus\": { (object) branch IDs of the current and upcoming consensus rules\n" + " \"chaintip\": \"xxxxxxxx\", (string) branch ID used to validate the current chain tip\n" + " \"nextblock\": \"xxxxxxxx\" (string) branch ID that the next block will be validated under\n" + " }\n" "}\n" "\nExamples:\n" + HelpExampleCli("getblockchaininfo", "") @@ -999,14 +1085,29 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) obj.push_back(Pair("commitments", tree.size())); #endif - const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); + UniValue valuePools(UniValue::VARR); + valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none)); + obj.push_back(Pair("valuePools", valuePools)); + + const Consensus::Params& consensusParams = Params().GetConsensus(); UniValue softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); obj.push_back(Pair("softforks", softforks)); + UniValue upgrades(UniValue::VOBJ); + for (int i = Consensus::UPGRADE_OVERWINTER; i < Consensus::MAX_NETWORK_UPGRADES; i++) { + NetworkUpgradeDescPushBack(upgrades, consensusParams, Consensus::UpgradeIndex(i), tip->nHeight); + } + obj.push_back(Pair("upgrades", upgrades)); + + UniValue consensus(UniValue::VOBJ); + consensus.push_back(Pair("chaintip", HexInt(CurrentEpochBranchId(tip->nHeight, consensusParams)))); + consensus.push_back(Pair("nextblock", HexInt(CurrentEpochBranchId(tip->nHeight + 1, consensusParams)))); + obj.push_back(Pair("consensus", consensus)); + if (fPruneMode) { CBlockIndex *block = chainActive.Tip(); diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 545d75b6f..13e9c357b 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -103,23 +103,36 @@ static const CRPCConvertParam vRPCConvertParams[] = { "zcbenchmark", 1 }, { "zcbenchmark", 2 }, { "getblocksubsidy", 0}, - { "z_listreceivedbyaddress", 1}, + { "z_listaddresses", 0}, + { "z_listreceivedbyaddress", 1}, { "z_getbalance", 1}, { "z_gettotalbalance", 0}, + { "z_gettotalbalance", 1}, + { "z_gettotalbalance", 2}, + { "z_mergetoaddress", 0}, + { "z_mergetoaddress", 2}, + { "z_mergetoaddress", 3}, + { "z_mergetoaddress", 4}, { "z_sendmany", 1}, { "z_sendmany", 2}, { "z_sendmany", 3}, + { "z_shieldcoinbase", 2}, + { "z_shieldcoinbase", 3}, { "z_getoperationstatus", 0}, { "z_getoperationresult", 0}, { "z_importkey", 1 }, { "paxprice", 4 }, { "paxprices", 3 }, { "paxpending", 0 }, - { "notaries", 1 }, + { "notaries", 2 }, + { "height_MoM", 1 }, { "minerids", 1 }, { "kvsearch", 1 }, { "kvupdate", 4 }, { "z_importkey", 2 }, + { "z_importviewingkey", 2 }, + { "z_getpaymentdisclosure", 1}, + { "z_getpaymentdisclosure", 2} }; class CRPCConvertTable diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 3fdd3bb89..1159c12c1 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -65,7 +65,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"version\": xxxxx, (numeric) the server version\n" " \"protocolversion\": xxxxx, (numeric) the protocol version\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total bitcoin balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total Zcash balance of the wallet\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"timeoffset\": xxxxx, (numeric) the time offset\n" " \"connections\": xxxxx, (numeric) the number of connections\n" @@ -75,8 +75,8 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" - " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n" - " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" + " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"errors\": \"...\" (string) any error messages\n" "}\n" "\nExamples:\n" @@ -249,14 +249,14 @@ UniValue validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( - "validateaddress \"bitcoinaddress\"\n" - "\nReturn information about the given bitcoin address.\n" + "validateaddress \"zcashaddress\"\n" + "\nReturn information about the given Zcash address.\n" "\nArguments:\n" - "1. \"bitcoinaddress\" (string, required) The bitcoin address to validate\n" + "1. \"zcashaddress\" (string, required) The Zcash address to validate\n" "\nResult:\n" "{\n" " \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" - " \"address\" : \"bitcoinaddress\", (string) The bitcoin address validated\n" + " \"address\" : \"zcashaddress\", (string) The Zcash address validated\n" " \"scriptPubKey\" : \"hex\", (string) The hex encoded scriptPubKey generated by the address\n" " \"ismine\" : true|false, (boolean) If the address is yours or not\n" " \"isscript\" : true|false, (boolean) If the key is a script\n" @@ -321,7 +321,8 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp) "}\n" "\nExamples:\n" - + HelpExampleCli("validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"") + + HelpExampleCli("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"") + + HelpExampleRpc("z_validateaddress", "\"zcWsmqT4X2V4jgxbgiCzyrAfRT1vi1F4sn7M5Pkh66izzw8Uk7LBGAH3DtcSMJeUb2pi3W4SQF8LMKkU2cUuVP68yAGcomL\"") ); @@ -439,9 +440,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp) "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keys\" (string, required) A json array of keys which are bitcoin addresses or hex-encoded public keys\n" + "2. \"keys\" (string, required) A json array of keys which are Zcash addresses or hex-encoded public keys\n" " [\n" - " \"key\" (string) bitcoin address or hex-encoded public key\n" + " \"key\" (string) Zcash address or hex-encoded public key\n" " ,...\n" " ]\n" @@ -453,9 +454,9 @@ UniValue createmultisig(const UniValue& params, bool fHelp) "\nExamples:\n" "\nCreate a multisig address from 2 addresses\n" - + HelpExampleCli("createmultisig", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + + HelpExampleCli("createmultisig", "2 \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("createmultisig", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + HelpExampleRpc("createmultisig", "2, \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") ; throw runtime_error(msg); } @@ -476,10 +477,10 @@ UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( - "verifymessage \"bitcoinaddress\" \"signature\" \"message\"\n" + "verifymessage \"zcashaddress\" \"signature\" \"message\"\n" "\nVerify a signed message\n" "\nArguments:\n" - "1. \"bitcoinaddress\" (string, required) The bitcoin address to use for the signature.\n" + "1. \"zcashaddress\" (string, required) The Zcash address to use for the signature.\n" "2. \"signature\" (string, required) The signature provided by the signer in base 64 encoding (see signmessage).\n" "3. \"message\" (string, required) The message that was signed.\n" "\nResult:\n" @@ -488,11 +489,11 @@ UniValue verifymessage(const UniValue& params, bool fHelp) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"signature\", \"my message\"") + + HelpExampleRpc("verifymessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", \"signature\", \"my message\"") ); LOCK(cs_main); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index ee2c21d4d..d2798f10c 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -13,6 +13,7 @@ #include "timedata.h" #include "util.h" #include "version.h" +#include "deprecation.h" #include @@ -141,7 +142,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("pingwait", stats.dPingWait)); obj.push_back(Pair("version", stats.nVersion)); // Use the sanitized form of subver here, to avoid tricksy remote peers from - // corrupting or modifiying the JSON output by putting special characters in + // corrupting or modifying the JSON output by putting special characters in // their ver message. obj.push_back(Pair("subver", stats.cleanSubVer)); obj.push_back(Pair("inbound", stats.fInbound)); @@ -285,7 +286,7 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) " \"connected\" : true|false, (boolean) If connected\n" " \"addresses\" : [\n" " {\n" - " \"address\" : \"192.168.0.201:8233\", (string) The bitcoin server host and port\n" + " \"address\" : \"192.168.0.201:8233\", (string) The Zcash server host and port\n" " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n" " }\n" " ,...\n" @@ -428,6 +429,33 @@ static UniValue GetNetworksInfo() return networks; } +UniValue getdeprecationinfo(const UniValue& params, bool fHelp) +{ + const CChainParams& chainparams = Params(); + if (fHelp || params.size() != 0 || chainparams.NetworkIDString() != "main") + throw runtime_error( + "getdeprecationinfo\n" + "Returns an object containing current version and deprecation block height. Applicable only on mainnet.\n" + "\nResult:\n" + "{\n" + " \"version\": xxxxx, (numeric) the server version\n" + " \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n" + " \"deprecationheight\": xxxxx, (numeric) the block height at which this version will deprecate and shut down (unless -disabledeprecation is set)\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getdeprecationinfo", "") + + HelpExampleRpc("getdeprecationinfo", "") + ); + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("version", CLIENT_VERSION)); + obj.push_back(Pair("subversion", + FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()))); + obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT)); + + return obj; +} + UniValue getnetworkinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) @@ -451,7 +479,7 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) " }\n" " ,...\n" " ],\n" - " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" + " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" " \"localaddresses\": [ (array) list of local addresses\n" " {\n" " \"address\": \"xxxx\", (string) network address\n" diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 285b5b48b..e918df2c9 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "core_io.h" #include "init.h" @@ -117,8 +118,15 @@ uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uin void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); + entry.push_back(Pair("overwintered", tx.fOverwintered)); entry.push_back(Pair("version", tx.nVersion)); + if (tx.fOverwintered) { + entry.push_back(Pair("versiongroupid", HexInt(tx.nVersionGroupId))); + } entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); + if (tx.fOverwintered) { + entry.push_back(Pair("expiryheight", (int64_t)tx.nExpiryHeight)); + } UniValue vin(UniValue::VARR); BOOST_FOREACH(const CTxIn& txin, tx.vin) { UniValue in(UniValue::VOBJ); @@ -144,14 +152,12 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - if ( pindex != 0 && tx.nLockTime != 0 && (tipindex= chainActive.Tip()) != 0 ) + if ( pindex != 0 && tx.nLockTime > 500000000 && (tipindex= chainActive.Tip()) != 0 ) { - extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; interest = komodo_interest(pindex->nHeight,txout.nValue,tx.nLockTime,tipindex->nTime); - if ( 0 && strcmp("REVS",ASSETCHAINS_SYMBOL) == 0 ) - fprintf(stderr,"TxtoJSON interest %llu %.8f (%d %llu %u %u)\n",(long long)interest,(double)interest/COIN,(int32_t)pindex->nHeight,(long long)txout.nValue,(uint32_t)tx.nLockTime,(int32_t)tipindex->nTime); out.push_back(Pair("interest", ValueFromAmount(interest))); } + out.push_back(Pair("valueZat", txout.nValue)); out.push_back(Pair("n", (int64_t)i)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); @@ -204,6 +210,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " \"txid\" : \"id\", (string) The transaction id (same as provided)\n" " \"version\" : n, (numeric) The version\n" " \"locktime\" : ttt, (numeric) The lock time\n" + " \"expiryheight\" : ttt, (numeric, optional) The block height after which the transaction expires\n" " \"vin\" : [ (array of json objects)\n" " {\n" " \"txid\": \"id\", (string) The transaction id\n" @@ -218,7 +225,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -226,7 +233,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) " \"reqSigs\" : n, (numeric) The required sigs\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"addresses\" : [ (json array of string)\n" - " \"bitcoinaddress\" (string) bitcoin address\n" + " \"zcashaddress\" (string) Zcash address\n" " ,...\n" " ]\n" " }\n" @@ -481,7 +488,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) " ]\n" "2. \"addresses\" (string, required) a json object with addresses as keys and amounts as values\n" " {\n" - " \"address\": x.xxx (numeric, required) The key is the bitcoin address, the value is the btc amount\n" + " \"address\": x.xxx (numeric, required) The key is the Zcash address, the value is the " + CURRENCY_UNIT + " amount\n" " ,...\n" " }\n" @@ -499,7 +506,16 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) UniValue inputs = params[0].get_array(); UniValue sendTo = params[1].get_obj(); - CMutableTransaction rawTx; + int nextBlockHeight = chainActive.Height() + 1; + CMutableTransaction rawTx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), nextBlockHeight); + + if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + rawTx.nExpiryHeight = nextBlockHeight + expiryDelta; + if (rawTx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){ + throw JSONRPCError(RPC_INVALID_PARAMETER, "nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD."); + } + } for (size_t idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; @@ -523,7 +539,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) BOOST_FOREACH(const string& name_, addrList) { CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+name_); if (setAddress.count(address)) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); @@ -552,8 +568,11 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"txid\" : \"id\", (string) The transaction id\n" + " \"overwintered\" : bool (boolean) The Overwintered flag\n" " \"version\" : n, (numeric) The version\n" + " \"versiongroupid\": \"hex\" (string, optional) The version group id (Overwintered txs)\n" " \"locktime\" : ttt, (numeric) The lock time\n" + " \"expiryheight\" : n, (numeric, optional) Last valid block height for mining transaction (Overwintered txs)\n" " \"vin\" : [ (array of json objects)\n" " {\n" " \"txid\": \"id\", (string) The transaction id\n" @@ -568,7 +587,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " ],\n" " \"vout\" : [ (array of json objects)\n" " {\n" - " \"value\" : x.xxx, (numeric) The value in btc\n" + " \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" " \"n\" : n, (numeric) index\n" " \"scriptPubKey\" : { (json object)\n" " \"asm\" : \"asm\", (string) the asm\n" @@ -576,7 +595,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp) " \"reqSigs\" : n, (numeric) The required sigs\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"addresses\" : [ (json array of string)\n" - " \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n" + " \"t12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) zcash address\n" " ,...\n" " ]\n" " }\n" @@ -646,7 +665,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) " \"type\":\"type\", (string) The output type\n" " \"reqSigs\": n, (numeric) The required signatures\n" " \"addresses\": [ (json array of string)\n" - " \"address\" (string) bitcoin address\n" + " \"address\" (string) Zcash address\n" " ,...\n" " ],\n" " \"p2sh\",\"address\" (string) script address\n" @@ -707,7 +726,8 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) " \"txid\":\"id\", (string, required) The transaction id\n" " \"vout\":n, (numeric, required) The output number\n" " \"scriptPubKey\": \"hex\", (string, required) script key\n" - " \"redeemScript\": \"hex\" (string, required for P2SH) redeem script\n" + " \"redeemScript\": \"hex\", (string, required for P2SH) redeem script\n" + " \"amount\": value (numeric, required) The amount spent\n" " }\n" " ,...\n" " ]\n" @@ -845,7 +865,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) if ((unsigned int)nOut >= coins->vout.size()) coins->vout.resize(nOut+1); coins->vout[nOut].scriptPubKey = scriptPubKey; - coins->vout[nOut].nValue = 0; // we don't know the actual output value + coins->vout[nOut].nValue = 0; + if (prevOut.exists("amount")) { + coins->vout[nOut].nValue = AmountFromValue(find_value(prevOut, "amount")); + } } // if redeemScript given and not using the local wallet (private keys @@ -888,9 +911,15 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); + // Grab the current consensus branch ID + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + // Script verification errors UniValue vErrors(UniValue::VARR); + // Use CTransaction for the constant parts of the + // transaction to avoid rehashing. + const CTransaction txConst(mergedTx); // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { CTxIn& txin = mergedTx.vin[i]; @@ -900,18 +929,22 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) continue; } const CScript& prevPubKey = coins->vout[txin.prevout.n].scriptPubKey; + const CAmount& amount = coins->vout[txin.prevout.n].nValue; - txin.scriptSig.clear(); + SignatureData sigdata; // Only sign SIGHASH_SINGLE if there's a corresponding output: if (!fHashSingle || (i < mergedTx.vout.size())) - SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); + ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId); // ... and merge in other signatures: BOOST_FOREACH(const CMutableTransaction& txv, txVariants) { - txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); + sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId); } + + UpdateTransaction(mergedTx, i, sigdata); + ScriptError serror = SCRIPT_ERR_OK; - if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i), &serror)) { + if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) { TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror)); } } diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index f353b9ea9..716992082 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -264,6 +264,7 @@ static const CRPCCommand vRPCCommands[] = /* P2P networking */ { "network", "getnetworkinfo", &getnetworkinfo, true }, + { "network", "getdeprecationinfo", &getdeprecationinfo, true }, { "network", "addnode", &addnode, true }, { "network", "disconnectnode", &disconnectnode, true }, { "network", "getaddednodeinfo", &getaddednodeinfo, true }, @@ -295,14 +296,13 @@ static const CRPCCommand vRPCCommands[] = { "blockchain", "paxpending", &paxpending, true }, { "blockchain", "paxprices", &paxprices, true }, { "blockchain", "notaries", ¬aries, true }, + { "blockchain", "height_MoM", &height_MoM, true }, { "blockchain", "minerids", &minerids, true }, { "blockchain", "kvsearch", &kvsearch, true }, { "blockchain", "kvupdate", &kvupdate, true }, /* Mining */ -#ifdef ENABLE_WALLET { "mining", "getblocktemplate", &getblocktemplate, true }, -#endif { "mining", "getmininginfo", &getmininginfo, true }, { "mining", "getlocalsolps", &getlocalsolps, true }, { "mining", "getnetworksolps", &getnetworksolps, true }, @@ -398,7 +398,9 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false }, { "wallet", "z_getbalance", &z_getbalance, false }, { "wallet", "z_gettotalbalance", &z_gettotalbalance, false }, + { "wallet", "z_mergetoaddress", &z_mergetoaddress, false }, { "wallet", "z_sendmany", &z_sendmany, false }, + { "wallet", "z_shieldcoinbase", &z_shieldcoinbase, false }, { "wallet", "z_getoperationstatus", &z_getoperationstatus, true }, { "wallet", "z_getoperationresult", &z_getoperationresult, true }, { "wallet", "z_listoperationids", &z_listoperationids, true }, @@ -406,11 +408,14 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "z_listaddresses", &z_listaddresses, true }, { "wallet", "z_exportkey", &z_exportkey, true }, { "wallet", "z_importkey", &z_importkey, true }, + { "wallet", "z_exportviewingkey", &z_exportviewingkey, true }, + { "wallet", "z_importviewingkey", &z_importviewingkey, true }, { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, - - { "wallet", "paxdeposit", &paxdeposit, true }, - { "wallet", "paxwithdraw", &paxwithdraw, true } + + // TODO: rearrange into another category + { "disclosure", "z_getpaymentdisclosure", &z_getpaymentdisclosure, true }, + { "disclosure", "z_validatepaymentdisclosure", &z_validatepaymentdisclosure, true } #endif // ENABLE_WALLET }; @@ -436,169 +441,13 @@ const CRPCCommand *CRPCTable::operator[](const std::string &name) const bool StartRPC() { -/*<<<<<<< HEA - std::string addr; - int port = defaultPort; - SplitHostPort(strEndpoint, port, addr); - return ip::tcp::endpoint(boost::asio::ip::address::from_string(addr), port); -} - -void StartRPCThreads() -{ - rpc_allow_subnets.clear(); - rpc_allow_subnets.push_back(CSubNet("127.0.0.0/8")); // always allow IPv4 local subnet - rpc_allow_subnets.push_back(CSubNet("::1")); // always allow IPv6 localhost - if (mapMultiArgs.count("-rpcallowip")) - { - const vector& vAllow = mapMultiArgs["-rpcallowip"]; - BOOST_FOREACH(string strAllow, vAllow) - { - CSubNet subnet(strAllow); - if(!subnet.IsValid()) - { - uiInterface.ThreadSafeMessageBox( - strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - rpc_allow_subnets.push_back(subnet); - } - } - std::string strAllowed; - BOOST_FOREACH(const CSubNet &subnet, rpc_allow_subnets) - strAllowed += subnet.ToString() + " "; - LogPrint("rpc", "Allowing RPC connections from: %s\n", strAllowed); - - if (mapArgs["-rpcpassword"] == "") - { - LogPrintf("No rpcpassword set - using random cookie authentication\n"); - if (!GenerateAuthCookie(&strRPCUserColonPass)) { - uiInterface.ThreadSafeMessageBox( - _("Error: A fatal internal error occured, see debug.log for details"), // Same message as AbortNode - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - } else { - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; - } - - assert(rpc_io_service == NULL); - rpc_io_service = new boost::asio::io_service(); - rpc_ssl_context = new ssl::context(*rpc_io_service, ssl::context::sslv23); - - const bool fUseSSL = GetBoolArg("-rpcssl", false); - - if (fUseSSL) - { - rpc_ssl_context->set_options(ssl::context::no_sslv2 | ssl::context::no_sslv3); - - boost::filesystem::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert")); - if (!pathCertFile.is_complete()) pathCertFile = boost::filesystem::path(GetDataDir()) / pathCertFile; - if (boost::filesystem::exists(pathCertFile)) rpc_ssl_context->use_certificate_chain_file(pathCertFile.string()); - else LogPrintf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string()); - - boost::filesystem::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem")); - if (!pathPKFile.is_complete()) pathPKFile = boost::filesystem::path(GetDataDir()) / pathPKFile; - if (boost::filesystem::exists(pathPKFile)) rpc_ssl_context->use_private_key_file(pathPKFile.string(), ssl::context::pem); - else LogPrintf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string()); - - string strCiphers = GetArg("-rpcsslciphers", "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"); - SSL_CTX_set_cipher_list(rpc_ssl_context->impl(), strCiphers.c_str()); - } - - std::vector vEndpoints; - bool bBindAny = false; - int defaultPort = GetArg("-rpcport", BaseParams().RPCPort()); - if (!mapArgs.count("-rpcallowip")) // Default to loopback if not allowing external IPs - { - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::loopback(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::loopback(), defaultPort)); - if (mapArgs.count("-rpcbind")) - { - LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); - } - } else if (mapArgs.count("-rpcbind")) // Specific bind address - { - BOOST_FOREACH(const std::string &addr, mapMultiArgs["-rpcbind"]) - { - try { - vEndpoints.push_back(ParseEndpoint(addr, defaultPort)); - } - catch (const boost::system::system_error&) - { - uiInterface.ThreadSafeMessageBox( - strprintf(_("Could not parse -rpcbind value %s as network address"), addr), - "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - } - } else { // No specific bind address specified, bind to any - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v6::any(), defaultPort)); - vEndpoints.push_back(ip::tcp::endpoint(boost::asio::ip::address_v4::any(), defaultPort)); - // Prefer making the socket dual IPv6/IPv4 instead of binding - // to both addresses separately. - bBindAny = true; - } - - bool fListening = false; - std::string strerr; - std::string straddress; - BOOST_FOREACH(const ip::tcp::endpoint &endpoint, vEndpoints) - { - try { - boost::asio::ip::address bindAddress = endpoint.address(); - straddress = bindAddress.to_string(); - LogPrintf("Binding RPC on address %s port %i (IPv4+IPv6 bind any: %i)\n", straddress, endpoint.port(), bBindAny); - boost::system::error_code v6_only_error; - boost::shared_ptr acceptor(new ip::tcp::acceptor(*rpc_io_service)); - - acceptor->open(endpoint.protocol()); - acceptor->set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - - // Try making the socket dual IPv6/IPv4 when listening on the IPv6 "any" address - acceptor->set_option(boost::asio::ip::v6_only( - !bBindAny || bindAddress != boost::asio::ip::address_v6::any()), v6_only_error); - - acceptor->bind(endpoint); - acceptor->listen(socket_base::max_connections); - - RPCListen(acceptor, *rpc_ssl_context, fUseSSL); - - fListening = true; - rpc_acceptors.push_back(acceptor); - // If dual IPv6/IPv4 bind successful, skip binding to IPv4 separately - if(bBindAny && bindAddress == boost::asio::ip::address_v6::any() && !v6_only_error) - break; - } - catch (const boost::system::system_error& e) - { - LogPrintf("ERROR: Binding RPC on address %s port %i failed: %s\n", straddress, endpoint.port(), e.what()); - strerr = strprintf(_("An error occurred while setting up the RPC address %s port %u for listening: %s"), straddress, endpoint.port(), e.what()); - } - } - - if (!fListening) { - uiInterface.ThreadSafeMessageBox(strerr, "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return; - } - - rpc_worker_group = new boost::thread_group(); - for (int i = 0; i < GetArg("-rpcthreads", 4); i++) - rpc_worker_group->create_thread(boost::bind(&boost::asio::io_service::run, rpc_io_service)); -======= LogPrint("rpc", "Starting RPC\n"); ->>>>>>> zcash/master*/ fRPCRunning = true; g_rpcSignals.Started(); // Launch one async rpc worker. The ability to launch multiple workers is not recommended at present and thus the option is disabled. - //for (int i=0; i<32; i++) - getAsyncRPCQueue()->addWorker(); -/* + getAsyncRPCQueue()->addWorker(); +/* int n = GetArg("-rpcasyncthreads", 1); if (n<1) { LogPrintf("ERROR: Invalid value %d for -rpcasyncthreads. Must be at least 1.\n", n); @@ -729,112 +578,6 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } -/*<<<<<<< HEA - if (!HTTPAuthorized(mapHeaders)) - { - LogPrintf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer_address_to_string()); - //Deter brute-forcing We don't support exposing the RPC port, so this shouldn't result in a DoS. - MilliSleep(250); - - conn->stream() << HTTPError(HTTP_UNAUTHORIZED, false) << std::flush; - return false; - } - JSONRequest jreq; - try - { - // Parse request - Value valRequest; - if (!read_string(strRequest, valRequest)) - { - fprintf(stderr,"CANTPARSE.(%s)\n",strRequest.c_str()); - throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); - } - // Return immediately if in warmup - { - LOCK(cs_rpcWarmup); - if (fRPCInWarmup) - throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); - } - - string strReply; - - // singleton request - if (valRequest.type() == obj_type) { - jreq.parse(valRequest); - - Value result = tableRPC.execute(jreq.strMethod, jreq.params); - - // Send reply - strReply = JSONRPCReply(result, Value::null, jreq.id); - - // array of requests - } else if (valRequest.type() == array_type) - strReply = JSONRPCExecBatch(valRequest.get_array()); - else - throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); - - conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; - } - catch (const Object& objError) - { - ErrorReply(conn->stream(), objError, jreq.id); - return false; - } - catch (const std::exception& e) - { - ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); - return false; - } - return true; -} - -void ServiceConnection(AcceptedConnection *conn) -{ - bool fRun = true; - while (fRun && !ShutdownRequested()) - { - int nProto = 0; - map mapHeaders; - string strRequest, strMethod, strURI; - - // Read HTTP request line - if (!ReadHTTPRequestLine(conn->stream(), nProto, strMethod, strURI)) - break; - - // Read HTTP message headers and body - ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto, MAX_SIZE); - - // TODO #1856: Re-enable support for persistent connections. - // We have disabled support for HTTP Keep-Alive until resolution of #1680, upstream rpc deadlock. - // Close connection immediately. - fRun = false; - - // HTTP Keep-Alive is false; close connection immediately - //if ((mapHeaders["connection"] == "close") || (!GetBoolArg("-rpckeepalive", true))) - // fRun = false; - - - // Process via JSON-RPC API - if (strURI == "/") { - if (!HTTPReq_JSONRPC(conn, strRequest, mapHeaders, fRun)) - break; - - // Process via HTTP REST API - } else if (strURI.substr(0, 6) == "/rest/" && GetBoolArg("-rest", false)) { - if (!HTTPReq_REST(conn, strURI, strRequest, mapHeaders, fRun)) - break; - - } else { - conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; - break; - } - } -} - -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const -{ -======= ->>>>>>> zcash/master*/ // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) diff --git a/src/rpcserver.h b/src/rpcserver.h index f59972472..1f6bd2f94 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -238,6 +238,7 @@ extern UniValue getinfo(const UniValue& params, bool fHelp); extern UniValue getwalletinfo(const UniValue& params, bool fHelp); extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); +extern UniValue getdeprecationinfo(const UniValue& params, bool fHelp); extern UniValue setmocktime(const UniValue& params, bool fHelp); extern UniValue resendwallettransactions(const UniValue& params, bool fHelp); extern UniValue zc_benchmark(const UniValue& params, bool fHelp); @@ -284,6 +285,8 @@ extern UniValue getblocksubsidy(const UniValue& params, bool fHelp); extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp extern UniValue z_importkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_exportviewingkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_importviewingkey(const UniValue& params, bool fHelp); // in rpcdump.cpp extern UniValue z_getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_listaddresses(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_exportwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp @@ -291,12 +294,17 @@ extern UniValue z_importwallet(const UniValue& params, bool fHelp); // in rpcdum extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_getbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_mergetoaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_sendmany(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_shieldcoinbase(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp +extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // in rpcdisclosure.cpp +extern UniValue z_validatepaymentdisclosure(const UniValue ¶ms, bool fHelp); // in rpcdisclosure.cpp +extern UniValue height_MoM(const UniValue& params, bool fHelp); extern UniValue notaries(const UniValue& params, bool fHelp); extern UniValue minerids(const UniValue& params, bool fHelp); extern UniValue kvsearch(const UniValue& params, bool fHelp); diff --git a/src/scheduler.cpp b/src/scheduler.cpp index 184ddc28a..8729f2a5a 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -20,13 +20,6 @@ CScheduler::~CScheduler() } -#if BOOST_VERSION < 105000 -static boost::system_time toPosixTime(const boost::chrono::system_clock::time_point& t) -{ - return boost::posix_time::from_time_t(boost::chrono::system_clock::to_time_t(t)); -} -#endif - void CScheduler::serviceQueue() { boost::unique_lock lock(newTaskMutex); @@ -45,20 +38,13 @@ void CScheduler::serviceQueue() // Wait until either there is a new task, or until // the time of the first item on the queue: -// wait_until needs boost 1.50 or later; older versions have timed_wait: -#if BOOST_VERSION < 105000 - while (!shouldStop() && !taskQueue.empty() && - newTaskScheduled.timed_wait(lock, toPosixTime(taskQueue.begin()->first))) { - // Keep waiting until timeout - } -#else // Some boost versions have a conflicting overload of wait_until that returns void. // Explicitly use a template here to avoid hitting that overload. while (!shouldStop() && !taskQueue.empty() && newTaskScheduled.wait_until<>(lock, taskQueue.begin()->first) != boost::cv_status::timeout) { // Keep waiting until timeout } -#endif + // If there are multiple threads, the queue can empty while we're waiting (another // thread may service the task we were waiting on). if (shouldStop() || taskQueue.empty()) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 35c764033..444e5ff2b 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -5,11 +5,11 @@ #include "interpreter.h" +#include "consensus/upgrades.h" #include "primitives/transaction.h" #include "crypto/ripemd160.h" #include "crypto/sha1.h" #include "crypto/sha256.h" -#include "eccryptoverify.h" #include "pubkey.h" #include "script/script.h" #include "uint256.h" @@ -104,7 +104,7 @@ bool static IsValidSignatureEncoding(const std::vector &sig) { // 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 + // possible encoding for a positive integer (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. @@ -167,16 +167,14 @@ bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { if (!IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } - unsigned int nLenR = vchSig[3]; - unsigned int nLenS = vchSig[5+nLenR]; - const unsigned char *S = &vchSig[6+nLenR]; + // https://bitcoin.stackexchange.com/a/12556: + // Also note that inside transaction signatures, an extra hashtype byte + // follows the actual signature data. + std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); // If the S value is above the order of the curve divided by two, its // complement modulo the order could have been used instead, which is // one byte shorter when encoded correctly. - if (!eccrypto::CheckSignatureElement(S, nLenS, true)) - return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); - - return true; + return CPubKey::CheckLowS(vchSigCopy); } bool static IsDefinedHashtypeSignature(const valtype &vchSig) { @@ -196,7 +194,7 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc if (vchSig.size() == 0) { return true; } - if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { + if (!IsValidSignatureEncoding(vchSig)) { return set_error(serror, SCRIPT_ERR_SIG_DER); } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { // serror is set @@ -237,7 +235,13 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { return true; } -bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +bool EvalScript( + vector >& stack, + const CScript& script, + unsigned int flags, + const BaseSignatureChecker& checker, + uint32_t consensusBranchId, + ScriptError* serror) { static const CScriptNum bnZero(0); static const CScriptNum bnOne(1); @@ -834,7 +838,7 @@ bool EvalScript(vector >& stack, const CScript& script, un //serror is set return false; } - bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script); + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId); popstack(stack); popstack(stack); @@ -892,7 +896,7 @@ bool EvalScript(vector >& stack, const CScript& script, un } // Check signature - bool fOk = checker.CheckSig(vchSig, vchPubKey, script); + bool fOk = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId); if (fOk) { isig++; @@ -1095,15 +1099,148 @@ public: } }; +const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = + {'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'}; +const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = + {'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'}; +const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = + {'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'}; +const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = + {'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'}; + +uint256 GetPrevoutHash(const CTransaction& txTo) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].prevout; + } + return ss.GetHash(); +} + +uint256 GetSequenceHash(const CTransaction& txTo) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SEQUENCE_HASH_PERSONALIZATION); + for (unsigned int n = 0; n < txTo.vin.size(); n++) { + ss << txTo.vin[n].nSequence; + } + return ss.GetHash(); +} + +uint256 GetOutputsHash(const CTransaction& txTo) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); + for (unsigned int n = 0; n < txTo.vout.size(); n++) { + ss << txTo.vout[n]; + } + return ss.GetHash(); +} + +uint256 GetJoinSplitsHash(const CTransaction& txTo) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_JOINSPLITS_HASH_PERSONALIZATION); + for (unsigned int n = 0; n < txTo.vjoinsplit.size(); n++) { + ss << txTo.vjoinsplit[n]; + } + ss << txTo.joinSplitPubKey; + return ss.GetHash(); +} + } // anon namespace -uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo) +{ + hashPrevouts = GetPrevoutHash(txTo); + hashSequence = GetSequenceHash(txTo); + hashOutputs = GetOutputsHash(txTo); + hashJoinSplits = GetJoinSplitsHash(txTo); +} + +SigVersion SignatureHashVersion(const CTransaction& txTo) +{ + if (txTo.fOverwintered) { + return SIGVERSION_OVERWINTER; + } else { + return SIGVERSION_SPROUT; + } +} + +uint256 SignatureHash( + const CScript& scriptCode, + const CTransaction& txTo, + unsigned int nIn, + int nHashType, + const CAmount& amount, + uint32_t consensusBranchId, + const PrecomputedTransactionData* cache) { if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) { // nIn out of range throw logic_error("input index is out of range"); } + auto sigversion = SignatureHashVersion(txTo); + + if (sigversion == SIGVERSION_OVERWINTER) { + uint256 hashPrevouts; + uint256 hashSequence; + uint256 hashOutputs; + uint256 hashJoinSplits; + + if (!(nHashType & SIGHASH_ANYONECANPAY)) { + hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo); + } + + if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo); + } + + if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { + hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo); + } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION); + ss << txTo.vout[nIn]; + hashOutputs = ss.GetHash(); + } + + if (!txTo.vjoinsplit.empty()) { + hashJoinSplits = cache ? cache->hashJoinSplits : GetJoinSplitsHash(txTo); + } + + uint32_t leConsensusBranchId = htole32(consensusBranchId); + unsigned char personalization[16] = {}; + memcpy(personalization, "ZcashSigHash", 12); + memcpy(personalization+12, &leConsensusBranchId, 4); + + CBLAKE2bWriter ss(SER_GETHASH, 0, personalization); + // Header + ss << txTo.GetHeader(); + // Version group ID + ss << txTo.nVersionGroupId; + // Input prevouts/nSequence (none/all, depending on flags) + ss << hashPrevouts; + ss << hashSequence; + // Outputs (none/one/all, depending on flags) + ss << hashOutputs; + // JoinSplits + ss << hashJoinSplits; + // Locktime + ss << txTo.nLockTime; + // Expiry height + ss << txTo.nExpiryHeight; + // Sighash type + ss << nHashType; + + // If this hash is for a transparent input signature + // (i.e. not for txTo.joinSplitSig): + if (nIn != NOT_AN_INPUT){ + // The input being signed (replacing the scriptSig with scriptCode + amount) + // The prevout may already be contained in hashPrevout, and the nSequence + // may already be contained in hashSequence. + ss << txTo.vin[nIn].prevout; + ss << scriptCode; + ss << amount; + ss << txTo.vin[nIn].nSequence; + } + + return ss.GetHash(); + } + // Check for invalid use of SIGHASH_SINGLE if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if (nIn >= txTo.vout.size()) { @@ -1121,12 +1258,17 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig return ss.GetHash(); } -bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const +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 +bool TransactionSignatureChecker::CheckSig( + const vector& vchSigIn, + const vector& vchPubKey, + const CScript& scriptCode, + uint32_t consensusBranchId) const { CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) @@ -1141,7 +1283,7 @@ bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn uint256 sighash; try { - sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType); + sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata); } catch (logic_error ex) { return false; } @@ -1216,7 +1358,13 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con } -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) +bool VerifyScript( + const CScript& scriptSig, + const CScript& scriptPubKey, + unsigned int flags, + const BaseSignatureChecker& checker, + uint32_t consensusBranchId, + ScriptError* serror) { set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); @@ -1225,12 +1373,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne } vector > stack, stackCopy; - if (!EvalScript(stack, scriptSig, flags, checker, serror)) + if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror)) // serror is set return false; if (flags & SCRIPT_VERIFY_P2SH) stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) + if (!EvalScript(stack, scriptPubKey, flags, checker, consensusBranchId, serror)) // serror is set return false; if (stack.empty()) @@ -1257,7 +1405,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); popstack(stack); - if (!EvalScript(stack, pubKey2, flags, checker, serror)) + if (!EvalScript(stack, pubKey2, flags, checker, consensusBranchId, serror)) // serror is set return false; if (stack.empty()) diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 2cdeb8f8e..b13922f07 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -46,7 +46,8 @@ enum SCRIPT_VERIFY_STRICTENC = (1U << 1), // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) - SCRIPT_VERIFY_DERSIG = (1U << 2), + // In Zcash this is required, and validation of non-strict-DER signatures is not implemented. + //SCRIPT_VERIFY_DERSIG = (1U << 2), // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure // (softfork safe, BIP62 rule 5). @@ -88,12 +89,36 @@ enum SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), }; -uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +struct PrecomputedTransactionData +{ + uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits; + + PrecomputedTransactionData(const CTransaction& tx); +}; + +enum SigVersion +{ + SIGVERSION_SPROUT = 0, + SIGVERSION_OVERWINTER = 1, +}; + +uint256 SignatureHash( + const CScript &scriptCode, + const CTransaction& txTo, + unsigned int nIn, + int nHashType, + const CAmount& amount, + uint32_t consensusBranchId, + const PrecomputedTransactionData* cache = NULL); class BaseSignatureChecker { public: - virtual bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const + virtual bool CheckSig( + const std::vector& scriptSig, + const std::vector& vchPubKey, + const CScript& scriptCode, + uint32_t consensusBranchId) const { return false; } @@ -116,13 +141,16 @@ class TransactionSignatureChecker : public BaseSignatureChecker private: const CTransaction* txTo; unsigned int nIn; + const CAmount amount; + const PrecomputedTransactionData* txdata; protected: virtual bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; public: - TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const; + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {} + TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const; bool CheckLockTime(const CScriptNum& nLockTime) const; bool CheckCryptoCondition(const CC *cond, const std::vector& condBin, const CScript& scriptCode) const; bool CheckEvalCondition(const CC *cond) const; @@ -134,10 +162,22 @@ private: const CTransaction txTo; public: - MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {} + MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {} }; -bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL); +bool EvalScript( + std::vector >& stack, + const CScript& script, + unsigned int flags, + const BaseSignatureChecker& checker, + uint32_t consensusBranchId, + ScriptError* error = NULL); +bool VerifyScript( + const CScript& scriptSig, + const CScript& scriptPubKey, + unsigned int flags, + const BaseSignatureChecker& checker, + uint32_t consensusBranchId, + ScriptError* serror = NULL); #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/script/script.cpp b/src/script/script.cpp index 5069d9152..a4446a0df 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -142,7 +142,7 @@ const char* GetOpName(opcodetype opcode) case OP_CHECKCRYPTOCONDITIONVERIFY : return "OP_CHECKCRYPTOCONDITIONVERIFY"; - // expanson + // expansion case OP_NOP1 : return "OP_NOP1"; case OP_NOP2 : return "OP_NOP2"; case OP_NOP3 : return "OP_NOP3"; diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp index 099b4ad0e..35b9f0e03 100644 --- a/src/script/sigcache.cpp +++ b/src/script/sigcache.cpp @@ -45,7 +45,7 @@ public: { // DoS prevention: limit cache size to less than 10MB // (~200 bytes per cache entry times 50,000 entries) - // Since there are a maximum of 20,000 signature operations per block + // Since there can be no more than 20,000 signature operations per block // 50,000 is a reasonable default. int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000); if (nMaxCacheSize <= 0) return; diff --git a/src/script/sigcache.h b/src/script/sigcache.h index b299038da..134b72a2d 100644 --- a/src/script/sigcache.h +++ b/src/script/sigcache.h @@ -18,7 +18,7 @@ private: bool store; public: - CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, bool storeIn=true) : TransactionSignatureChecker(txToIn, nInIn), store(storeIn) {} + CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {} bool VerifySignature(const std::vector& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const; }; diff --git a/src/script/sign.cpp b/src/script/sign.cpp index 75e6c6d9d..1aade8477 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -17,9 +17,9 @@ using namespace std; typedef vector valtype; -TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), checker(txTo, nIn) {} +TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {} -bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode) const +bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId) const { CKey key; if (!keystore->GetKey(address, key)) @@ -27,7 +27,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, uint256 hash; try { - hash = SignatureHash(scriptCode, *txTo, nIn, nHashType); + hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId); } catch (logic_error ex) { return false; } @@ -38,16 +38,16 @@ bool TransactionSignatureCreator::CreateSig(std::vector& vchSig, return true; } -static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) +static bool Sign1(const CKeyID& address, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector& ret, uint32_t consensusBranchId) { vector vchSig; - if (!creator.CreateSig(vchSig, address, scriptCode)) + if (!creator.CreateSig(vchSig, address, scriptCode, consensusBranchId)) return false; - scriptSigRet << vchSig; + ret.push_back(vchSig); return true; } -static bool SignN(const vector& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, CScript& scriptSigRet) +static bool SignN(const vector& multisigdata, const BaseSignatureCreator& creator, const CScript& scriptCode, std::vector& ret, uint32_t consensusBranchId) { int nSigned = 0; int nRequired = multisigdata.front()[0]; @@ -55,7 +55,7 @@ static bool SignN(const vector& multisigdata, const BaseSignatureCreato { const valtype& pubkey = multisigdata[i]; CKeyID keyID = CPubKey(pubkey).GetID(); - if (Sign1(keyID, creator, scriptCode, scriptSigRet)) + if (Sign1(keyID, creator, scriptCode, ret, consensusBranchId)) ++nSigned; } return nSigned==nRequired; @@ -68,9 +68,11 @@ static bool SignN(const vector& multisigdata, const BaseSignatureCreato * Returns false if scriptPubKey could not be completely satisfied. */ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey, - CScript& scriptSigRet, txnouttype& whichTypeRet) + std::vector& ret, txnouttype& whichTypeRet, uint32_t consensusBranchId) { - scriptSigRet.clear(); + CScript scriptRet; + uint160 h160; + ret.clear(); vector vSolutions; if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) @@ -84,85 +86,127 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP return false; case TX_PUBKEY: keyID = CPubKey(vSolutions[0]).GetID(); - return Sign1(keyID, creator, scriptPubKey, scriptSigRet); + return Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId); case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); - if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet)) + if (!Sign1(keyID, creator, scriptPubKey, ret, consensusBranchId)) return false; else { CPubKey vch; creator.KeyStore().GetPubKey(keyID, vch); - scriptSigRet << ToByteVector(vch); + ret.push_back(ToByteVector(vch)); } return true; case TX_SCRIPTHASH: - return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet); - - case TX_MULTISIG: - scriptSigRet << OP_0; // workaround CHECKMULTISIG bug - return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet)); - } - return false; -} - -bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig) -{ - txnouttype whichType; - if (!SignStep(creator, fromPubKey, scriptSig, whichType)) + if (creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptRet)) { + ret.push_back(std::vector(scriptRet.begin(), scriptRet.end())); + return true; + } return false; - if (whichType == TX_SCRIPTHASH) + case TX_MULTISIG: + ret.push_back(valtype()); // workaround CHECKMULTISIG bug + return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId)); + + default: + return false; + } +} + +static CScript PushAll(const vector& values) +{ + CScript result; + BOOST_FOREACH(const valtype& v, values) { + if (v.size() == 0) { + result << OP_0; + } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { + result << CScript::EncodeOP_N(v[0]); + } else { + result << v; + } + } + return result; +} + +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata, uint32_t consensusBranchId) +{ + CScript script = fromPubKey; + bool solved = true; + std::vector result; + txnouttype whichType; + solved = SignStep(creator, script, result, whichType, consensusBranchId); + CScript subscript; + + if (solved && whichType == TX_SCRIPTHASH) { - // Solver returns the subscript that need to be evaluated; + // Solver returns the subscript that needs to be evaluated; // the final scriptSig is the signatures from that // and then the serialized subscript: - CScript subscript = scriptSig; - - txnouttype subType; - bool fSolved = - SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH; - // Append serialized subscript whether or not it is completely signed: - scriptSig << static_cast(subscript); - if (!fSolved) return false; + script = subscript = CScript(result[0].begin(), result[0].end()); + solved = solved && SignStep(creator, script, result, whichType, consensusBranchId) && whichType != TX_SCRIPTHASH; + result.push_back(std::vector(subscript.begin(), subscript.end())); } + sigdata.scriptSig = PushAll(result); + // Test solution - return VerifyScript(scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker()); + return solved && VerifyScript(sigdata.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, creator.Checker(), consensusBranchId); } -bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType) +SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn) +{ + SignatureData data; + assert(tx.vin.size() > nIn); + data.scriptSig = tx.vin[nIn].scriptSig; + return data; +} + +void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data) +{ + assert(tx.vin.size() > nIn); + tx.vin[nIn].scriptSig = data.scriptSig; +} + +bool SignSignature( + const CKeyStore &keystore, + const CScript& fromPubKey, + CMutableTransaction& txTo, + unsigned int nIn, + const CAmount& amount, + int nHashType, + uint32_t consensusBranchId) { assert(nIn < txTo.vin.size()); - CTxIn& txin = txTo.vin[nIn]; CTransaction txToConst(txTo); - TransactionSignatureCreator creator(&keystore, &txToConst, nIn, nHashType); + TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType); - return ProduceSignature(creator, fromPubKey, txin.scriptSig); + SignatureData sigdata; + bool ret = ProduceSignature(creator, fromPubKey, sigdata, consensusBranchId); + UpdateTransaction(txTo, nIn, sigdata); + return ret; } -bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType) +bool SignSignature( + const CKeyStore &keystore, + const CTransaction& txFrom, + CMutableTransaction& txTo, + unsigned int nIn, + int nHashType, + uint32_t consensusBranchId) { assert(nIn < txTo.vin.size()); CTxIn& txin = txTo.vin[nIn]; assert(txin.prevout.n < txFrom.vout.size()); const CTxOut& txout = txFrom.vout[txin.prevout.n]; - return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); + return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, consensusBranchId); } -static CScript PushAll(const vector& values) -{ - CScript result; - BOOST_FOREACH(const valtype& v, values) - result << v; - return result; -} - -static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, +static vector CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const vector& vSolutions, - const vector& sigs1, const vector& sigs2) + const vector& sigs1, const vector& sigs2, uint32_t consensusBranchId) { // Combine all the signatures we've got: set allsigs; @@ -190,7 +234,7 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC if (sigs.count(pubkey)) continue; // Already got a sig for this pubkey - if (checker.CheckSig(sig, pubkey, scriptPubKey)) + if (checker.CheckSig(sig, pubkey, scriptPubKey, consensusBranchId)) { sigs[pubkey] = sig; break; @@ -199,87 +243,100 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC } // Now build a merged CScript: unsigned int nSigsHave = 0; - CScript result; result << OP_0; // pop-one-too-many workaround + std::vector result; result.push_back(valtype()); // pop-one-too-many workaround for (unsigned int i = 0; i < nPubKeys && nSigsHave < nSigsRequired; i++) { if (sigs.count(vSolutions[i+1])) { - result << sigs[vSolutions[i+1]]; + result.push_back(sigs[vSolutions[i+1]]); ++nSigsHave; } } // Fill any missing with OP_0: for (unsigned int i = nSigsHave; i < nSigsRequired; i++) - result << OP_0; + result.push_back(valtype()); return result; } -static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, +namespace +{ +struct Stacks +{ + std::vector script; + + Stacks() {} + explicit Stacks(const std::vector& scriptSigStack_) : script(scriptSigStack_) {} + explicit Stacks(const SignatureData& data, uint32_t consensusBranchId) { + EvalScript(script, data.scriptSig, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), consensusBranchId); + } + + SignatureData Output() const { + SignatureData result; + result.scriptSig = PushAll(script); + return result; + } +}; +} + +static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const txnouttype txType, const vector& vSolutions, - vector& sigs1, vector& sigs2) + Stacks sigs1, Stacks sigs2, uint32_t consensusBranchId) { switch (txType) { case TX_NONSTANDARD: case TX_NULL_DATA: // Don't know anything about this, assume bigger one is correct: - if (sigs1.size() >= sigs2.size()) - return PushAll(sigs1); - return PushAll(sigs2); + if (sigs1.script.size() >= sigs2.script.size()) + return sigs1; + return sigs2; case TX_PUBKEY: case TX_PUBKEYHASH: // Signatures are bigger than placeholders or empty scripts: - if (sigs1.empty() || sigs1[0].empty()) - return PushAll(sigs2); - return PushAll(sigs1); + if (sigs1.script.empty() || sigs1.script[0].empty()) + return sigs2; + return sigs1; case TX_SCRIPTHASH: - if (sigs1.empty() || sigs1.back().empty()) - return PushAll(sigs2); - else if (sigs2.empty() || sigs2.back().empty()) - return PushAll(sigs1); + if (sigs1.script.empty() || sigs1.script.back().empty()) + return sigs2; + else if (sigs2.script.empty() || sigs2.script.back().empty()) + return sigs1; else { // Recur to combine: - valtype spk = sigs1.back(); + valtype spk = sigs1.script.back(); CScript pubKey2(spk.begin(), spk.end()); txnouttype txType2; vector > vSolutions2; Solver(pubKey2, txType2, vSolutions2); - sigs1.pop_back(); - sigs2.pop_back(); - CScript result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2); - result << spk; + sigs1.script.pop_back(); + sigs2.script.pop_back(); + Stacks result = CombineSignatures(pubKey2, checker, txType2, vSolutions2, sigs1, sigs2, consensusBranchId); + result.script.push_back(spk); return result; } case TX_MULTISIG: - return CombineMultisig(scriptPubKey, checker, vSolutions, sigs1, sigs2); + return Stacks(CombineMultisig(scriptPubKey, checker, vSolutions, sigs1.script, sigs2.script, consensusBranchId)); + default: + return Stacks(); } - - return CScript(); } -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, - const CScript& scriptSig1, const CScript& scriptSig2) -{ - TransactionSignatureChecker checker(&txTo, nIn); - return CombineSignatures(scriptPubKey, checker, scriptSig1, scriptSig2); -} - -CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, - const CScript& scriptSig1, const CScript& scriptSig2) +SignatureData CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, + const SignatureData& scriptSig1, const SignatureData& scriptSig2, + uint32_t consensusBranchId) { txnouttype txType; vector > vSolutions; Solver(scriptPubKey, txType, vSolutions); - vector stack1; - EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); - vector stack2; - EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); - - return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); + return CombineSignatures( + scriptPubKey, checker, txType, vSolutions, + Stacks(scriptSig1, consensusBranchId), + Stacks(scriptSig2, consensusBranchId), + consensusBranchId).Output(); } namespace { @@ -289,7 +346,11 @@ class DummySignatureChecker : public BaseSignatureChecker public: DummySignatureChecker() {} - bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode) const + bool CheckSig( + const std::vector& scriptSig, + const std::vector& vchPubKey, + const CScript& scriptCode, + uint32_t consensusBranchId) const { return true; } @@ -302,7 +363,11 @@ const BaseSignatureChecker& DummySignatureCreator::Checker() const return dummyChecker; } -bool DummySignatureCreator::CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const +bool DummySignatureCreator::CreateSig( + std::vector& vchSig, + const CKeyID& keyid, + const CScript& scriptCode, + uint32_t consensusBranchId) const { // Create a dummy signature that is a valid DER-encoding vchSig.assign(72, '\000'); diff --git a/src/script/sign.h b/src/script/sign.h index 13f45007d..f531ad0d8 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -27,7 +27,7 @@ public: virtual const BaseSignatureChecker& Checker() const =0; /** Create a singular (non-script) signature. */ - virtual bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const =0; + virtual bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, uint32_t consensusBranchId) const =0; }; /** A signature creator for transactions. */ @@ -35,33 +35,67 @@ class TransactionSignatureCreator : public BaseSignatureCreator { const CTransaction* txTo; unsigned int nIn; int nHashType; + CAmount amount; const TransactionSignatureChecker checker; public: - TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL); + TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL); const BaseSignatureChecker& Checker() const { return checker; } - bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; + bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, uint32_t consensusBranchId) const; }; -/** A signature creator that just produces 72-byte empty signatyres. */ +class MutableTransactionSignatureCreator : public TransactionSignatureCreator { + CTransaction tx; + +public: + MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {} +}; + +/** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: DummySignatureCreator(const CKeyStore* keystoreIn) : BaseSignatureCreator(keystoreIn) {} const BaseSignatureChecker& Checker() const; - bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; + bool CreateSig(std::vector& vchSig, const CKeyID& keyid, const CScript& scriptCode, uint32_t consensusBranchId) const; +}; + +struct SignatureData { + CScript scriptSig; + + SignatureData() {} + explicit SignatureData(const CScript& script) : scriptSig(script) {} }; /** Produce a script signature using a generic signature creator. */ -bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, CScript& scriptSig); +bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata, uint32_t consensusBranchId); /** Produce a script signature for a transaction. */ -bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); -bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); +bool SignSignature( + const CKeyStore &keystore, + const CScript& fromPubKey, + CMutableTransaction& txTo, + unsigned int nIn, + const CAmount& amount, + int nHashType, + uint32_t consensusBranchId); +bool SignSignature( + const CKeyStore& keystore, + const CTransaction& txFrom, + CMutableTransaction& txTo, + unsigned int nIn, + int nHashType, + uint32_t consensusBranchId); /** Combine two script signatures using a generic signature checker, intelligently, possibly with OP_0 placeholders. */ -CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker, const CScript& scriptSig1, const CScript& scriptSig2); +SignatureData CombineSignatures( + const CScript& scriptPubKey, + const BaseSignatureChecker& checker, + const SignatureData& scriptSig1, + const SignatureData& scriptSig2, + uint32_t consensusBranchId); -/** Combine two script signatures on transactions. */ -CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); +/** Extract signature data from a transaction, and insert it. */ +SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn); +void UpdateTransaction(CMutableTransaction& tx, unsigned int nIn, const SignatureData& data); #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/script/standard.h b/src/script/standard.h index 475cbb072..5395be868 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -31,9 +31,8 @@ extern unsigned nMaxDatacarrierBytes; /** * Mandatory script verification flags that all new blocks must comply with for * them to be valid. (but old blocks may not comply with) Currently just P2SH, - * but in the future other flags may be added, such as a soft-fork to enforce - * strict DER encoding. - * + * but in the future other flags may be added. + * * Failing one of these tests may trigger a DoS ban - see CheckInputs() for * details. */ @@ -45,7 +44,7 @@ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; * blocks and we must accept those blocks. */ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | - SCRIPT_VERIFY_DERSIG | + // SCRIPT_VERIFY_DERSIG is always enforced SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_NULLDUMMY | diff --git a/src/script/zcashconsensus.cpp b/src/script/zcashconsensus.cpp index d66cf21c0..dbec305fc 100644 --- a/src/script/zcashconsensus.cpp +++ b/src/script/zcashconsensus.cpp @@ -5,7 +5,9 @@ #include "zcashconsensus.h" +#include "consensus/upgrades.h" #include "primitives/transaction.h" +#include "pubkey.h" #include "script/interpreter.h" #include "version.h" @@ -60,7 +62,13 @@ inline int set_error(zcashconsensus_error* ret, zcashconsensus_error serror) return 0; } -} // anon namespace +struct ECCryptoClosure +{ + ECCVerifyHandle handle; +}; + +ECCryptoClosure instance_of_eccryptoclosure; +} int zcashconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo , unsigned int txToLen, @@ -77,8 +85,16 @@ int zcashconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int // Regardless of the verification result, the tx did not error. set_error(err, zcashconsensus_ERR_OK); - - return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, TransactionSignatureChecker(&tx, nIn), NULL); + PrecomputedTransactionData txdata(tx); + CAmount am(0); + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + return VerifyScript( + tx.vin[nIn].scriptSig, + CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), + flags, + TransactionSignatureChecker(&tx, nIn, am, txdata), + consensusBranchId, + NULL); } catch (const std::exception&) { return set_error(err, zcashconsensus_ERR_TX_DESERIALIZE); // Error deserializing } diff --git a/src/script/zcashconsensus.h b/src/script/zcashconsensus.h index a68921d90..ff13471c6 100644 --- a/src/script/zcashconsensus.h +++ b/src/script/zcashconsensus.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_ZCASHCONSENSUS_H #define BITCOIN_ZCASHCONSENSUS_H +#include + #if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) #include "config/bitcoin-config.h" #if defined(_WIN32) @@ -46,7 +48,6 @@ enum { zcashconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, zcashconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts - zcashconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance zcashconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65) }; diff --git a/src/secp256k1/.gitignore b/src/secp256k1/.gitignore index 076ff1295..87fea161b 100644 --- a/src/secp256k1/.gitignore +++ b/src/secp256k1/.gitignore @@ -1,9 +1,13 @@ bench_inv +bench_ecdh bench_sign bench_verify +bench_schnorr_verify bench_recover bench_internal tests +exhaustive_tests +gen_context *.exe *.so *.a @@ -22,16 +26,24 @@ config.status libtool .deps/ .dirstamp -build-aux/ *.lo *.o *~ src/libsecp256k1-config.h src/libsecp256k1-config.h.in -m4/libtool.m4 -m4/ltoptions.m4 -m4/ltsugar.m4 -m4/ltversion.m4 -m4/lt~obsolete.m4 +src/ecmult_static_context.h +build-aux/config.guess +build-aux/config.sub +build-aux/depcomp +build-aux/install-sh +build-aux/ltmain.sh +build-aux/m4/libtool.m4 +build-aux/m4/lt~obsolete.m4 +build-aux/m4/ltoptions.m4 +build-aux/m4/ltsugar.m4 +build-aux/m4/ltversion.m4 +build-aux/missing +build-aux/compile +build-aux/test-driver src/stamp-h1 libsecp256k1.pc diff --git a/src/secp256k1/.travis.yml b/src/secp256k1/.travis.yml index 0d8089cfe..243952924 100644 --- a/src/secp256k1/.travis.yml +++ b/src/secp256k1/.travis.yml @@ -6,22 +6,30 @@ addons: compiler: - clang - gcc +cache: + directories: + - src/java/guava/ env: global: - - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= + - FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no STATICPRECOMPUTATION=yes ASM=no BUILD=check EXTRAFLAGS= HOST= ECDH=no RECOVERY=no EXPERIMENTAL=no + - GUAVA_URL=https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar GUAVA_JAR=src/java/guava/guava-18.0.jar matrix: - - SCALAR=32bit + - SCALAR=32bit RECOVERY=yes + - SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes - SCALAR=64bit - - FIELD=64bit + - FIELD=64bit RECOVERY=yes - FIELD=64bit ENDOMORPHISM=yes + - FIELD=64bit ENDOMORPHISM=yes ECDH=yes EXPERIMENTAL=yes - FIELD=64bit ASM=x86_64 - FIELD=64bit ENDOMORPHISM=yes ASM=x86_64 - - FIELD=32bit - FIELD=32bit ENDOMORPHISM=yes - BIGNUM=no - - BIGNUM=no ENDOMORPHISM=yes + - BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes + - BIGNUM=no STATICPRECOMPUTATION=no - BUILD=distcheck - - EXTRAFLAGS=CFLAGS=-DDETERMINISTIC + - EXTRAFLAGS=CPPFLAGS=-DDETERMINISTIC + - EXTRAFLAGS=CFLAGS=-O0 + - BUILD=check-java ECDH=yes EXPERIMENTAL=yes matrix: fast_finish: true include: @@ -51,9 +59,11 @@ matrix: packages: - gcc-multilib - libgmp-dev:i386 +before_install: mkdir -p `dirname $GUAVA_JAR` +install: if [ ! -f $GUAVA_JAR ]; then wget $GUAVA_URL -O $GUAVA_JAR; fi before_script: ./autogen.sh script: - if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi - if [ "x$HOST" = "xi686-linux-gnu" ]; then export CC="$CC -m32"; fi - - ./configure --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR $EXTRAFLAGS $USE_HOST && make -j2 $BUILD + - ./configure --enable-experimental=$EXPERIMENTAL --enable-endomorphism=$ENDOMORPHISM --with-field=$FIELD --with-bignum=$BIGNUM --with-scalar=$SCALAR --enable-ecmult-static-precomputation=$STATICPRECOMPUTATION --enable-module-ecdh=$ECDH --enable-module-recovery=$RECOVERY $EXTRAFLAGS $USE_HOST && make -j2 $BUILD os: linux diff --git a/src/secp256k1/Makefile.am b/src/secp256k1/Makefile.am index 5f388f3fd..c071fbe27 100644 --- a/src/secp256k1/Makefile.am +++ b/src/secp256k1/Makefile.am @@ -1,14 +1,22 @@ ACLOCAL_AMFLAGS = -I build-aux/m4 lib_LTLIBRARIES = libsecp256k1.la +if USE_JNI +JNI_LIB = libsecp256k1_jni.la +noinst_LTLIBRARIES = $(JNI_LIB) +else +JNI_LIB = +endif include_HEADERS = include/secp256k1.h noinst_HEADERS = noinst_HEADERS += src/scalar.h noinst_HEADERS += src/scalar_4x64.h noinst_HEADERS += src/scalar_8x32.h +noinst_HEADERS += src/scalar_low.h noinst_HEADERS += src/scalar_impl.h noinst_HEADERS += src/scalar_4x64_impl.h noinst_HEADERS += src/scalar_8x32_impl.h +noinst_HEADERS += src/scalar_low_impl.h noinst_HEADERS += src/group.h noinst_HEADERS += src/group_impl.h noinst_HEADERS += src/num_gmp.h @@ -19,6 +27,8 @@ noinst_HEADERS += src/eckey.h noinst_HEADERS += src/eckey_impl.h noinst_HEADERS += src/ecmult.h noinst_HEADERS += src/ecmult_impl.h +noinst_HEADERS += src/ecmult_const.h +noinst_HEADERS += src/ecmult_const_impl.h noinst_HEADERS += src/ecmult_gen.h noinst_HEADERS += src/ecmult_gen_impl.h noinst_HEADERS += src/num.h @@ -30,6 +40,7 @@ noinst_HEADERS += src/field_5x52_impl.h noinst_HEADERS += src/field_5x52_int128_impl.h noinst_HEADERS += src/field_5x52_asm_impl.h noinst_HEADERS += src/java/org_bitcoin_NativeSecp256k1.h +noinst_HEADERS += src/java/org_bitcoin_Secp256k1Context.h noinst_HEADERS += src/util.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h @@ -38,40 +49,129 @@ noinst_HEADERS += src/hash_impl.h noinst_HEADERS += src/field.h noinst_HEADERS += src/field_impl.h noinst_HEADERS += src/bench.h +noinst_HEADERS += contrib/lax_der_parsing.h +noinst_HEADERS += contrib/lax_der_parsing.c +noinst_HEADERS += contrib/lax_der_privatekey_parsing.h +noinst_HEADERS += contrib/lax_der_privatekey_parsing.c + +if USE_EXTERNAL_ASM +COMMON_LIB = libsecp256k1_common.la +noinst_LTLIBRARIES = $(COMMON_LIB) +else +COMMON_LIB = +endif pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libsecp256k1.pc -libsecp256k1_la_SOURCES = src/secp256k1.c -libsecp256k1_la_CPPFLAGS = -I$(top_srcdir)/include $(SECP_INCLUDES) -libsecp256k1_la_LIBADD = $(SECP_LIBS) +if USE_EXTERNAL_ASM +if USE_ASM_ARM +libsecp256k1_common_la_SOURCES = src/asm/field_10x26_arm.s +endif +endif +libsecp256k1_la_SOURCES = src/secp256k1.c +libsecp256k1_la_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/include -I$(top_srcdir)/src $(SECP_INCLUDES) +libsecp256k1_la_LIBADD = $(JNI_LIB) $(SECP_LIBS) $(COMMON_LIB) + +libsecp256k1_jni_la_SOURCES = src/java/org_bitcoin_NativeSecp256k1.c src/java/org_bitcoin_Secp256k1Context.c +libsecp256k1_jni_la_CPPFLAGS = -DSECP256K1_BUILD $(JNI_INCLUDES) noinst_PROGRAMS = if USE_BENCHMARK -noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal +noinst_PROGRAMS += bench_verify bench_sign bench_internal bench_verify_SOURCES = src/bench_verify.c -bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) -bench_verify_LDFLAGS = -static -bench_recover_SOURCES = src/bench_recover.c -bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) -bench_recover_LDFLAGS = -static +bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_sign_SOURCES = src/bench_sign.c -bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) -bench_sign_LDFLAGS = -static +bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) bench_internal_SOURCES = src/bench_internal.c -bench_internal_LDADD = $(SECP_LIBS) -bench_internal_LDFLAGS = -static -bench_internal_CPPFLAGS = $(SECP_INCLUDES) +bench_internal_LDADD = $(SECP_LIBS) $(COMMON_LIB) +bench_internal_CPPFLAGS = -DSECP256K1_BUILD $(SECP_INCLUDES) endif +TESTS = if USE_TESTS noinst_PROGRAMS += tests tests_SOURCES = src/tests.c -tests_CPPFLAGS = -DVERIFY $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) -tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) -tests_LDFLAGS = -static -pthread -TESTS = tests +tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src -I$(top_srcdir)/include $(SECP_INCLUDES) $(SECP_TEST_INCLUDES) +if !ENABLE_COVERAGE +tests_CPPFLAGS += -DVERIFY +endif +tests_LDADD = $(SECP_LIBS) $(SECP_TEST_LIBS) $(COMMON_LIB) +tests_LDFLAGS = -static +TESTS += tests endif -EXTRA_DIST = autogen.sh +if USE_EXHAUSTIVE_TESTS +noinst_PROGRAMS += exhaustive_tests +exhaustive_tests_SOURCES = src/tests_exhaustive.c +exhaustive_tests_CPPFLAGS = -DSECP256K1_BUILD -I$(top_srcdir)/src $(SECP_INCLUDES) +if !ENABLE_COVERAGE +exhaustive_tests_CPPFLAGS += -DVERIFY +endif +exhaustive_tests_LDADD = $(SECP_LIBS) +exhaustive_tests_LDFLAGS = -static +TESTS += exhaustive_tests +endif + +JAVAROOT=src/java +JAVAORG=org/bitcoin +JAVA_GUAVA=$(srcdir)/$(JAVAROOT)/guava/guava-18.0.jar +CLASSPATH_ENV=CLASSPATH=$(JAVA_GUAVA) +JAVA_FILES= \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Test.java \ + $(JAVAROOT)/$(JAVAORG)/NativeSecp256k1Util.java \ + $(JAVAROOT)/$(JAVAORG)/Secp256k1Context.java + +if USE_JNI + +$(JAVA_GUAVA): + @echo Guava is missing. Fetch it via: \ + wget https://search.maven.org/remotecontent?filepath=com/google/guava/guava/18.0/guava-18.0.jar -O $(@) + @false + +.stamp-java: $(JAVA_FILES) + @echo Compiling $^ + $(AM_V_at)$(CLASSPATH_ENV) javac $^ + @touch $@ + +if USE_TESTS + +check-java: libsecp256k1.la $(JAVA_GUAVA) .stamp-java + $(AM_V_at)java -Djava.library.path="./:./src:./src/.libs:.libs/" -cp "$(JAVA_GUAVA):$(JAVAROOT)" $(JAVAORG)/NativeSecp256k1Test + +endif +endif + +if USE_ECMULT_STATIC_PRECOMPUTATION +CPPFLAGS_FOR_BUILD +=-I$(top_srcdir) +CFLAGS_FOR_BUILD += -Wall -Wextra -Wno-unused-function + +gen_context_OBJECTS = gen_context.o +gen_context_BIN = gen_context$(BUILD_EXEEXT) +gen_%.o: src/gen_%.c + $(CC_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD) -c $< -o $@ + +$(gen_context_BIN): $(gen_context_OBJECTS) + $(CC_FOR_BUILD) $^ -o $@ + +$(libsecp256k1_la_OBJECTS): src/ecmult_static_context.h +$(tests_OBJECTS): src/ecmult_static_context.h +$(bench_internal_OBJECTS): src/ecmult_static_context.h + +src/ecmult_static_context.h: $(gen_context_BIN) + ./$(gen_context_BIN) + +CLEANFILES = $(gen_context_BIN) src/ecmult_static_context.h $(JAVAROOT)/$(JAVAORG)/*.class .stamp-java +endif + +EXTRA_DIST = autogen.sh src/gen_context.c src/basic-config.h $(JAVA_FILES) + +if ENABLE_MODULE_ECDH +include src/modules/ecdh/Makefile.am.include +endif + +if ENABLE_MODULE_RECOVERY +include src/modules/recovery/Makefile.am.include +endif diff --git a/src/secp256k1/README.md b/src/secp256k1/README.md index 6095db422..8cd344ea8 100644 --- a/src/secp256k1/README.md +++ b/src/secp256k1/README.md @@ -1,7 +1,7 @@ libsecp256k1 ============ -[![Build Status](https://travis-ci.org/bitcoin/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin/secp256k1) +[![Build Status](https://travis-ci.org/bitcoin-core/secp256k1.svg?branch=master)](https://travis-ci.org/bitcoin-core/secp256k1) Optimized C library for EC operations on curve secp256k1. diff --git a/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 b/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 new file mode 100644 index 000000000..1fc362761 --- /dev/null +++ b/src/secp256k1/build-aux/m4/ax_jni_include_dir.m4 @@ -0,0 +1,140 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_JNI_INCLUDE_DIR +# +# DESCRIPTION +# +# AX_JNI_INCLUDE_DIR finds include directories needed for compiling +# programs using the JNI interface. +# +# JNI include directories are usually in the Java distribution. This is +# deduced from the value of $JAVA_HOME, $JAVAC, or the path to "javac", in +# that order. When this macro completes, a list of directories is left in +# the variable JNI_INCLUDE_DIRS. +# +# Example usage follows: +# +# AX_JNI_INCLUDE_DIR +# +# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS +# do +# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" +# done +# +# If you want to force a specific compiler: +# +# - at the configure.in level, set JAVAC=yourcompiler before calling +# AX_JNI_INCLUDE_DIR +# +# - at the configure level, setenv JAVAC +# +# Note: This macro can work with the autoconf M4 macros for Java programs. +# This particular macro is not part of the original set of macros. +# +# LICENSE +# +# Copyright (c) 2008 Don Anderson +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 10 + +AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR]) +AC_DEFUN([AX_JNI_INCLUDE_DIR],[ + +JNI_INCLUDE_DIRS="" + +if test "x$JAVA_HOME" != x; then + _JTOPDIR="$JAVA_HOME" +else + if test "x$JAVAC" = x; then + JAVAC=javac + fi + AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no]) + if test "x$_ACJNI_JAVAC" = xno; then + AC_MSG_WARN([cannot find JDK; try setting \$JAVAC or \$JAVA_HOME]) + fi + _ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") + _JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` +fi + +case "$host_os" in + darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + _JINC="$_JTOPDIR/Headers";; + *) _JINC="$_JTOPDIR/include";; +esac +_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR]) +_AS_ECHO_LOG([_JINC=$_JINC]) + +# On Mac OS X 10.6.4, jni.h is a symlink: +# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h +# -> ../../CurrentJDK/Headers/jni.h. + +AC_CACHE_CHECK(jni headers, ac_cv_jni_header_path, +[ +if test -f "$_JINC/jni.h"; then + ac_cv_jni_header_path="$_JINC" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" +else + _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` + if test -f "$_JTOPDIR/include/jni.h"; then + ac_cv_jni_header_path="$_JTOPDIR/include" + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $ac_cv_jni_header_path" + else + ac_cv_jni_header_path=none + fi +fi +]) + + + +# get the likely subdirectories for system specific java includes +case "$host_os" in +bsdi*) _JNI_INC_SUBDIRS="bsdos";; +darwin*) _JNI_INC_SUBDIRS="darwin";; +freebsd*) _JNI_INC_SUBDIRS="freebsd";; +linux*) _JNI_INC_SUBDIRS="linux genunix";; +osf*) _JNI_INC_SUBDIRS="alpha";; +solaris*) _JNI_INC_SUBDIRS="solaris";; +mingw*) _JNI_INC_SUBDIRS="win32";; +cygwin*) _JNI_INC_SUBDIRS="win32";; +*) _JNI_INC_SUBDIRS="genunix";; +esac + +if test "x$ac_cv_jni_header_path" != "xnone"; then + # add any subdirectories that are present + for JINCSUBDIR in $_JNI_INC_SUBDIRS + do + if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then + JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR" + fi + done +fi +]) + +# _ACJNI_FOLLOW_SYMLINKS +# Follows symbolic links on , +# finally setting variable _ACJNI_FOLLOWED +# ---------------------------------------- +AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[ +# find the include directory relative to the javac executable +_cur="$1" +while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do + AC_MSG_CHECKING([symlink for $_cur]) + _slink=`ls -ld "$_cur" | sed 's/.* -> //'` + case "$_slink" in + /*) _cur="$_slink";; + # 'X' avoids triggering unwanted echo options. + *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; + esac + AC_MSG_RESULT([$_cur]) +done +_ACJNI_FOLLOWED="$_cur" +])# _ACJNI diff --git a/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 b/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 new file mode 100644 index 000000000..77fd346a7 --- /dev/null +++ b/src/secp256k1/build-aux/m4/ax_prog_cc_for_build.m4 @@ -0,0 +1,125 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PROG_CC_FOR_BUILD +# +# DESCRIPTION +# +# This macro searches for a C compiler that generates native executables, +# that is a C compiler that surely is not a cross-compiler. This can be +# useful if you have to generate source code at compile-time like for +# example GCC does. +# +# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything +# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD). +# The value of these variables can be overridden by the user by specifying +# a compiler with an environment variable (like you do for standard CC). +# +# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object +# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if +# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are +# substituted in the Makefile. +# +# LICENSE +# +# Copyright (c) 2008 Paolo Bonzini +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD]) +AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_CPP])dnl +AC_REQUIRE([AC_EXEEXT])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +dnl Use the standard macros, but make them use other variable names +dnl +pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl +pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl +pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl +pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl +pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl +pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl +pushdef([ac_cv_objext], ac_cv_build_objext)dnl +pushdef([ac_exeext], ac_build_exeext)dnl +pushdef([ac_objext], ac_build_objext)dnl +pushdef([CC], CC_FOR_BUILD)dnl +pushdef([CPP], CPP_FOR_BUILD)dnl +pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl +pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl +pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl +pushdef([host], build)dnl +pushdef([host_alias], build_alias)dnl +pushdef([host_cpu], build_cpu)dnl +pushdef([host_vendor], build_vendor)dnl +pushdef([host_os], build_os)dnl +pushdef([ac_cv_host], ac_cv_build)dnl +pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl +pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl +pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl +pushdef([ac_cv_host_os], ac_cv_build_os)dnl +pushdef([ac_cpp], ac_build_cpp)dnl +pushdef([ac_compile], ac_build_compile)dnl +pushdef([ac_link], ac_build_link)dnl + +save_cross_compiling=$cross_compiling +save_ac_tool_prefix=$ac_tool_prefix +cross_compiling=no +ac_tool_prefix= + +AC_PROG_CC +AC_PROG_CPP +AC_EXEEXT + +ac_tool_prefix=$save_ac_tool_prefix +cross_compiling=$save_cross_compiling + +dnl Restore the old definitions +dnl +popdef([ac_link])dnl +popdef([ac_compile])dnl +popdef([ac_cpp])dnl +popdef([ac_cv_host_os])dnl +popdef([ac_cv_host_vendor])dnl +popdef([ac_cv_host_cpu])dnl +popdef([ac_cv_host_alias])dnl +popdef([ac_cv_host])dnl +popdef([host_os])dnl +popdef([host_vendor])dnl +popdef([host_cpu])dnl +popdef([host_alias])dnl +popdef([host])dnl +popdef([LDFLAGS])dnl +popdef([CPPFLAGS])dnl +popdef([CFLAGS])dnl +popdef([CPP])dnl +popdef([CC])dnl +popdef([ac_objext])dnl +popdef([ac_exeext])dnl +popdef([ac_cv_objext])dnl +popdef([ac_cv_exeext])dnl +popdef([ac_cv_prog_cc_g])dnl +popdef([ac_cv_prog_cc_cross])dnl +popdef([ac_cv_prog_cc_works])dnl +popdef([ac_cv_prog_gcc])dnl +popdef([ac_cv_prog_CPP])dnl + +dnl Finally, set Makefile variables +dnl +BUILD_EXEEXT=$ac_build_exeext +BUILD_OBJEXT=$ac_build_objext +AC_SUBST(BUILD_EXEEXT)dnl +AC_SUBST(BUILD_OBJEXT)dnl +AC_SUBST([CFLAGS_FOR_BUILD])dnl +AC_SUBST([CPPFLAGS_FOR_BUILD])dnl +AC_SUBST([LDFLAGS_FOR_BUILD])dnl +]) diff --git a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 index 4a398d6c9..b74acb8c1 100644 --- a/src/secp256k1/build-aux/m4/bitcoin_secp.m4 +++ b/src/secp256k1/build-aux/m4/bitcoin_secp.m4 @@ -3,21 +3,20 @@ AC_DEFUN([SECP_INT128_CHECK],[ has_int128=$ac_cv_type___int128 ]) -dnl +dnl escape "$0x" below using the m4 quadrigaph @S|@, and escape it again with a \ for the shell. AC_DEFUN([SECP_64BIT_ASM_CHECK],[ AC_MSG_CHECKING(for x86_64 assembly availability) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ uint64_t a = 11, tmp; - __asm__ __volatile__("movq $0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); + __asm__ __volatile__("movq \@S|@0x100000000,%1; mulq %%rsi" : "+a"(a) : "S"(tmp) : "cc", "%rdx"); ]])],[has_64bit_asm=yes],[has_64bit_asm=no]) AC_MSG_RESULT([$has_64bit_asm]) ]) dnl AC_DEFUN([SECP_OPENSSL_CHECK],[ -if test x"$use_pkgconfig" = x"yes"; then - : #NOP + has_libcrypto=no m4_ifdef([PKG_CHECK_MODULES],[ PKG_CHECK_MODULES([CRYPTO], [libcrypto], [has_libcrypto=yes],[has_libcrypto=no]) if test x"$has_libcrypto" = x"yes"; then @@ -27,11 +26,16 @@ if test x"$use_pkgconfig" = x"yes"; then LIBS="$TEMP_LIBS" fi ]) -else - AC_CHECK_HEADER(openssl/crypto.h,[AC_CHECK_LIB(crypto, main,[has_libcrypto=yes; CRYPTO_LIBS=-lcrypto; AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed])] -)]) - LIBS= -fi + if test x$has_libcrypto = xno; then + AC_CHECK_HEADER(openssl/crypto.h,[ + AC_CHECK_LIB(crypto, main,[ + has_libcrypto=yes + CRYPTO_LIBS=-lcrypto + AC_DEFINE(HAVE_LIBCRYPTO,1,[Define this symbol if libcrypto is installed]) + ]) + ]) + LIBS= + fi if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then AC_MSG_CHECKING(for EC functions in libcrypto) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -42,6 +46,10 @@ if test x"$has_libcrypto" = x"yes" && test x"$has_openssl_ec" = x; then ECDSA_sign(0, NULL, 0, NULL, NULL, eckey); ECDSA_verify(0, NULL, 0, NULL, 0, eckey); EC_KEY_free(eckey); + ECDSA_SIG *sig_openssl; + sig_openssl = ECDSA_SIG_new(); + (void)sig_openssl->r; + ECDSA_SIG_free(sig_openssl); ]])],[has_openssl_ec=yes],[has_openssl_ec=no]) AC_MSG_RESULT([$has_openssl_ec]) fi diff --git a/src/secp256k1/configure.ac b/src/secp256k1/configure.ac index 3dc182951..e5fcbcb4e 100644 --- a/src/secp256k1/configure.ac +++ b/src/secp256k1/configure.ac @@ -17,24 +17,19 @@ PKG_PROG_PKG_CONFIG AC_PATH_TOOL(AR, ar) AC_PATH_TOOL(RANLIB, ranlib) AC_PATH_TOOL(STRIP, strip) +AX_PROG_CC_FOR_BUILD if test "x$CFLAGS" = "x"; then - CFLAGS="-O3 -g" + CFLAGS="-g" fi +AM_PROG_CC_C_O + AC_PROG_CC_C89 if test x"$ac_cv_prog_cc_c89" = x"no"; then AC_MSG_ERROR([c89 compiler support required]) fi - -case $host in - *mingw*) - use_pkgconfig=no - ;; - *) - use_pkgconfig=yes - ;; -esac +AM_PROG_AS case $host_os in *darwin*) @@ -80,22 +75,70 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], CFLAGS="$saved_CFLAGS" ]) +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fvisibility=hidden" +AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], + [ AC_MSG_RESULT([yes]) ], + [ AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" + ]) AC_ARG_ENABLE(benchmark, AS_HELP_STRING([--enable-benchmark],[compile benchmark (default is no)]), [use_benchmark=$enableval], [use_benchmark=no]) +AC_ARG_ENABLE(coverage, + AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis]), + [enable_coverage=$enableval], + [enable_coverage=no]) + AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[compile tests (default is yes)]), [use_tests=$enableval], [use_tests=yes]) +AC_ARG_ENABLE(openssl_tests, + AS_HELP_STRING([--enable-openssl-tests],[enable OpenSSL tests, if OpenSSL is available (default is auto)]), + [enable_openssl_tests=$enableval], + [enable_openssl_tests=auto]) + +AC_ARG_ENABLE(experimental, + AS_HELP_STRING([--enable-experimental],[allow experimental configure options (default is no)]), + [use_experimental=$enableval], + [use_experimental=no]) + +AC_ARG_ENABLE(exhaustive_tests, + AS_HELP_STRING([--enable-exhaustive-tests],[compile exhaustive tests (default is yes)]), + [use_exhaustive_tests=$enableval], + [use_exhaustive_tests=yes]) + AC_ARG_ENABLE(endomorphism, AS_HELP_STRING([--enable-endomorphism],[enable endomorphism (default is no)]), [use_endomorphism=$enableval], [use_endomorphism=no]) +AC_ARG_ENABLE(ecmult_static_precomputation, + AS_HELP_STRING([--enable-ecmult-static-precomputation],[enable precomputed ecmult table for signing (default is yes)]), + [use_ecmult_static_precomputation=$enableval], + [use_ecmult_static_precomputation=auto]) + +AC_ARG_ENABLE(module_ecdh, + AS_HELP_STRING([--enable-module-ecdh],[enable ECDH shared secret computation (experimental)]), + [enable_module_ecdh=$enableval], + [enable_module_ecdh=no]) + +AC_ARG_ENABLE(module_recovery, + AS_HELP_STRING([--enable-module-recovery],[enable ECDSA pubkey recovery module (default is no)]), + [enable_module_recovery=$enableval], + [enable_module_recovery=no]) + +AC_ARG_ENABLE(jni, + AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni (default is auto)]), + [use_jni=$enableval], + [use_jni=auto]) + AC_ARG_WITH([field], [AS_HELP_STRING([--with-field=64bit|32bit|auto], [Specify Field Implementation. Default is auto])],[req_field=$withval], [req_field=auto]) @@ -105,8 +148,8 @@ AC_ARG_WITH([bignum], [AS_HELP_STRING([--with-bignum=gmp|no|auto], AC_ARG_WITH([scalar], [AS_HELP_STRING([--with-scalar=64bit|32bit|auto], [Specify scalar implementation. Default is auto])],[req_scalar=$withval], [req_scalar=auto]) -AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|no|auto] -[Specify assembly optimizations to use. Default is auto])],[req_asm=$withval], [req_asm=auto]) +AC_ARG_WITH([asm], [AS_HELP_STRING([--with-asm=x86_64|arm|no|auto] +[Specify assembly optimizations to use. Default is auto (experimental: arm)])],[req_asm=$withval], [req_asm=auto]) AC_CHECK_TYPES([__int128]) @@ -116,6 +159,42 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])], [ AC_MSG_RESULT([no]) ]) +if test x"$enable_coverage" = x"yes"; then + AC_DEFINE(COVERAGE, 1, [Define this symbol to compile out all VERIFY code]) + CFLAGS="$CFLAGS -O0 --coverage" + LDFLAGS="--coverage" +else + CFLAGS="$CFLAGS -O3" +fi + +if test x"$use_ecmult_static_precomputation" != x"no"; then + save_cross_compiling=$cross_compiling + cross_compiling=no + TEMP_CC="$CC" + CC="$CC_FOR_BUILD" + AC_MSG_CHECKING([native compiler: ${CC_FOR_BUILD}]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([], [return 0])], + [working_native_cc=yes], + [working_native_cc=no],[dnl]) + CC="$TEMP_CC" + cross_compiling=$save_cross_compiling + + if test x"$working_native_cc" = x"no"; then + set_precomp=no + if test x"$use_ecmult_static_precomputation" = x"yes"; then + AC_MSG_ERROR([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + else + AC_MSG_RESULT([${CC_FOR_BUILD} does not produce working binaries. Please set CC_FOR_BUILD]) + fi + else + AC_MSG_RESULT([ok]) + set_precomp=yes + fi +else + set_precomp=no +fi + if test x"$req_asm" = x"auto"; then SECP_64BIT_ASM_CHECK if test x"$has_64bit_asm" = x"yes"; then @@ -133,6 +212,8 @@ else AC_MSG_ERROR([x86_64 assembly optimization requested but not available]) fi ;; + arm) + ;; no) ;; *) @@ -225,10 +306,15 @@ else fi # select assembly optimization +use_external_asm=no + case $set_asm in x86_64) AC_DEFINE(USE_ASM_X86_64, 1, [Define this symbol to enable x86_64 assembly optimizations]) ;; +arm) + use_external_asm=yes + ;; no) ;; *) @@ -283,16 +369,48 @@ esac if test x"$use_tests" = x"yes"; then SECP_OPENSSL_CHECK if test x"$has_openssl_ec" = x"yes"; then - AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) - SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" - SECP_TEST_LIBS="$CRYPTO_LIBS" + if test x"$enable_openssl_tests" != x"no"; then + AC_DEFINE(ENABLE_OPENSSL_TESTS, 1, [Define this symbol if OpenSSL EC functions are available]) + SECP_TEST_INCLUDES="$SSL_CFLAGS $CRYPTO_CFLAGS" + SECP_TEST_LIBS="$CRYPTO_LIBS" - case $host in - *mingw*) - SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" - ;; - esac + case $host in + *mingw*) + SECP_TEST_LIBS="$SECP_TEST_LIBS -lgdi32" + ;; + esac + fi + else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but OpenSSL with EC support is not available]) + fi + fi +else + if test x"$enable_openssl_tests" = x"yes"; then + AC_MSG_ERROR([OpenSSL tests requested but tests are not enabled]) + fi +fi +if test x"$use_jni" != x"no"; then + AX_JNI_INCLUDE_DIR + have_jni_dependencies=yes + if test x"$enable_module_ecdh" = x"no"; then + have_jni_dependencies=no + fi + if test "x$JNI_INCLUDE_DIRS" = "x"; then + have_jni_dependencies=no + fi + if test "x$have_jni_dependencies" = "xno"; then + if test x"$use_jni" = x"yes"; then + AC_MSG_ERROR([jni support explicitly requested but headers/dependencies were not found. Enable ECDH and try again.]) + fi + AC_MSG_WARN([jni headers/dependencies not found. jni support disabled]) + use_jni=no + else + use_jni=yes + for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS; do + JNI_INCLUDES="$JNI_INCLUDES -I$JNI_INCLUDE_DIR" + done fi fi @@ -305,22 +423,67 @@ if test x"$use_endomorphism" = x"yes"; then AC_DEFINE(USE_ENDOMORPHISM, 1, [Define this symbol to use endomorphism optimization]) fi +if test x"$set_precomp" = x"yes"; then + AC_DEFINE(USE_ECMULT_STATIC_PRECOMPUTATION, 1, [Define this symbol to use a statically generated ecmult table]) +fi + +if test x"$enable_module_ecdh" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module]) +fi + +if test x"$enable_module_recovery" = x"yes"; then + AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module]) +fi + AC_C_BIGENDIAN() +if test x"$use_external_asm" = x"yes"; then + AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) +fi + +AC_MSG_NOTICE([Using static precomputation: $set_precomp]) AC_MSG_NOTICE([Using assembly optimizations: $set_asm]) AC_MSG_NOTICE([Using field implementation: $set_field]) AC_MSG_NOTICE([Using bignum implementation: $set_bignum]) AC_MSG_NOTICE([Using scalar implementation: $set_scalar]) AC_MSG_NOTICE([Using endomorphism optimizations: $use_endomorphism]) +AC_MSG_NOTICE([Building for coverage analysis: $enable_coverage]) +AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) +AC_MSG_NOTICE([Building ECDSA pubkey recovery module: $enable_module_recovery]) +AC_MSG_NOTICE([Using jni: $use_jni]) + +if test x"$enable_experimental" = x"yes"; then + AC_MSG_NOTICE([******]) + AC_MSG_NOTICE([WARNING: experimental build]) + AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.]) + AC_MSG_NOTICE([Building ECDH module: $enable_module_ecdh]) + AC_MSG_NOTICE([******]) +else + if test x"$enable_module_ecdh" = x"yes"; then + AC_MSG_ERROR([ECDH module is experimental. Use --enable-experimental to allow.]) + fi + if test x"$set_asm" = x"arm"; then + AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.]) + fi +fi AC_CONFIG_HEADERS([src/libsecp256k1-config.h]) AC_CONFIG_FILES([Makefile libsecp256k1.pc]) +AC_SUBST(JNI_INCLUDES) AC_SUBST(SECP_INCLUDES) AC_SUBST(SECP_LIBS) AC_SUBST(SECP_TEST_LIBS) AC_SUBST(SECP_TEST_INCLUDES) +AM_CONDITIONAL([ENABLE_COVERAGE], [test x"$enable_coverage" = x"yes"]) AM_CONDITIONAL([USE_TESTS], [test x"$use_tests" != x"no"]) +AM_CONDITIONAL([USE_EXHAUSTIVE_TESTS], [test x"$use_exhaustive_tests" != x"no"]) AM_CONDITIONAL([USE_BENCHMARK], [test x"$use_benchmark" = x"yes"]) +AM_CONDITIONAL([USE_ECMULT_STATIC_PRECOMPUTATION], [test x"$set_precomp" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_ECDH], [test x"$enable_module_ecdh" = x"yes"]) +AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"yes"]) +AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"]) +AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"]) +AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm"]) dnl make sure nothing new is exported so that we don't break the cache PKGCONFIG_PATH_TEMP="$PKG_CONFIG_PATH" diff --git a/src/secp256k1/contrib/lax_der_parsing.c b/src/secp256k1/contrib/lax_der_parsing.c new file mode 100644 index 000000000..5b141a994 --- /dev/null +++ b/src/secp256k1/contrib/lax_der_parsing.c @@ -0,0 +1,150 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include +#include + +#include "lax_der_parsing.h" + +int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + size_t rpos, rlen, spos, slen; + size_t pos = 0; + size_t lenbyte; + unsigned char tmpsig[64] = {0}; + int overflow = 0; + + /* Hack to initialize sig with a correctly-parsed but invalid signature. */ + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + + /* Sequence tag byte */ + if (pos == inputlen || input[pos] != 0x30) { + return 0; + } + pos++; + + /* Sequence length bytes */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + pos += lenbyte; + } + + /* Integer tag byte for R */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for R */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + rlen = 0; + while (lenbyte > 0) { + rlen = (rlen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + rlen = lenbyte; + } + if (rlen > inputlen - pos) { + return 0; + } + rpos = pos; + pos += rlen; + + /* Integer tag byte for S */ + if (pos == inputlen || input[pos] != 0x02) { + return 0; + } + pos++; + + /* Integer length for S */ + if (pos == inputlen) { + return 0; + } + lenbyte = input[pos++]; + if (lenbyte & 0x80) { + lenbyte -= 0x80; + if (pos + lenbyte > inputlen) { + return 0; + } + while (lenbyte > 0 && input[pos] == 0) { + pos++; + lenbyte--; + } + if (lenbyte >= sizeof(size_t)) { + return 0; + } + slen = 0; + while (lenbyte > 0) { + slen = (slen << 8) + input[pos]; + pos++; + lenbyte--; + } + } else { + slen = lenbyte; + } + if (slen > inputlen - pos) { + return 0; + } + spos = pos; + pos += slen; + + /* Ignore leading zeroes in R */ + while (rlen > 0 && input[rpos] == 0) { + rlen--; + rpos++; + } + /* Copy R value */ + if (rlen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 32 - rlen, input + rpos, rlen); + } + + /* Ignore leading zeroes in S */ + while (slen > 0 && input[spos] == 0) { + slen--; + spos++; + } + /* Copy S value */ + if (slen > 32) { + overflow = 1; + } else { + memcpy(tmpsig + 64 - slen, input + spos, slen); + } + + if (!overflow) { + overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + if (overflow) { + memset(tmpsig, 0, 64); + secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig); + } + return 1; +} + diff --git a/src/secp256k1/contrib/lax_der_parsing.h b/src/secp256k1/contrib/lax_der_parsing.h new file mode 100644 index 000000000..7eaf63bf6 --- /dev/null +++ b/src/secp256k1/contrib/lax_der_parsing.h @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/**** + * Please do not link this file directly. It is not part of the libsecp256k1 + * project and does not promise any stability in its API, functionality or + * presence. Projects which use this code should instead copy this header + * and its accompanying .c file directly into their codebase. + ****/ + +/* This file defines a function that parses DER with various errors and + * violations. This is not a part of the library itself, because the allowed + * violations are chosen arbitrarily and do not follow or establish any + * standard. + * + * In many places it matters that different implementations do not only accept + * the same set of valid signatures, but also reject the same set of signatures. + * The only means to accomplish that is by strictly obeying a standard, and not + * accepting anything else. + * + * Nonetheless, sometimes there is a need for compatibility with systems that + * use signatures which do not strictly obey DER. The snippet below shows how + * certain violations are easily supported. You may need to adapt it. + * + * Do not use this for new systems. Use well-defined DER or compact signatures + * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and + * secp256k1_ecdsa_signature_parse_compact). + * + * The supported violations are: + * - All numbers are parsed as nonnegative integers, even though X.609-0207 + * section 8.3.3 specifies that integers are always encoded as two's + * complement. + * - Integers can have length 0, even though section 8.3.1 says they can't. + * - Integers with overly long padding are accepted, violation section + * 8.3.2. + * - 127-byte long length descriptors are accepted, even though section + * 8.1.3.5.c says that they are not. + * - Trailing garbage data inside or after the signature is ignored. + * - The length descriptor of the sequence is ignored. + * + * Compared to for example OpenSSL, many violations are NOT supported: + * - Using overly long tag descriptors for the sequence or integers inside, + * violating section 8.1.2.2. + * - Encoding primitive integers as constructed values, violating section + * 8.3.1. + */ + +#ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H +#define SECP256K1_CONTRIB_LAX_DER_PARSING_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Parse a signature in "lax DER" format + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input: a pointer to the signature to be parsed + * inputlen: the length of the array pointed to be input + * + * This function will accept any valid DER encoded signature, even if the + * encoded numbers are out of range. In addition, it will accept signatures + * which violate the DER spec in various ways. Its purpose is to allow + * validation of the Bitcoin blockchain, which includes non-DER signatures + * from before the network rules were updated to enforce DER. Note that + * the set of supported violations is a strict subset of what OpenSSL will + * accept. + * + * After the call, sig will always be initialized. If parsing failed or the + * encoded numbers are out of range, signature validation with it is + * guaranteed to fail for every message and public key. + */ +int ecdsa_signature_parse_der_lax( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ diff --git a/src/secp256k1/contrib/lax_der_privatekey_parsing.c b/src/secp256k1/contrib/lax_der_privatekey_parsing.c new file mode 100644 index 000000000..c2e63b4b8 --- /dev/null +++ b/src/secp256k1/contrib/lax_der_privatekey_parsing.c @@ -0,0 +1,113 @@ +/********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include +#include + +#include "lax_der_privatekey_parsing.h" + +int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) { + const unsigned char *end = privkey + privkeylen; + int lenb = 0; + int len = 0; + memset(out32, 0, 32); + /* sequence header */ + if (end < privkey+1 || *privkey != 0x30) { + return 0; + } + privkey++; + /* sequence length constructor */ + if (end < privkey+1 || !(*privkey & 0x80)) { + return 0; + } + lenb = *privkey & ~0x80; privkey++; + if (lenb < 1 || lenb > 2) { + return 0; + } + if (end < privkey+lenb) { + return 0; + } + /* sequence length */ + len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); + privkey += lenb; + if (end < privkey+len) { + return 0; + } + /* sequence element 0: version number (=1) */ + if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) { + return 0; + } + privkey += 3; + /* sequence element 1: octet string, up to 32 bytes */ + if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { + return 0; + } + memcpy(out32 + 32 - privkey[1], privkey + 2, privkey[1]); + if (!secp256k1_ec_seckey_verify(ctx, out32)) { + memset(out32, 0, 32); + return 0; + } + return 1; +} + +int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) { + secp256k1_pubkey pubkey; + size_t pubkeylen = 0; + if (!secp256k1_ec_pubkey_create(ctx, &pubkey, key32)) { + *privkeylen = 0; + return 0; + } + if (compressed) { + static const unsigned char begin[] = { + 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 33; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } else { + static const unsigned char begin[] = { + 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 + }; + static const unsigned char middle[] = { + 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, + 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, + 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, + 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, + 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, + 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, + 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 + }; + unsigned char *ptr = privkey; + memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); + memcpy(ptr, key32, 32); ptr += 32; + memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); + pubkeylen = 65; + secp256k1_ec_pubkey_serialize(ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED); + ptr += pubkeylen; + *privkeylen = ptr - privkey; + } + return 1; +} diff --git a/src/secp256k1/contrib/lax_der_privatekey_parsing.h b/src/secp256k1/contrib/lax_der_privatekey_parsing.h new file mode 100644 index 000000000..fece261fb --- /dev/null +++ b/src/secp256k1/contrib/lax_der_privatekey_parsing.h @@ -0,0 +1,90 @@ +/********************************************************************** + * Copyright (c) 2014, 2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +/**** + * Please do not link this file directly. It is not part of the libsecp256k1 + * project and does not promise any stability in its API, functionality or + * presence. Projects which use this code should instead copy this header + * and its accompanying .c file directly into their codebase. + ****/ + +/* This file contains code snippets that parse DER private keys with + * various errors and violations. This is not a part of the library + * itself, because the allowed violations are chosen arbitrarily and + * do not follow or establish any standard. + * + * It also contains code to serialize private keys in a compatible + * manner. + * + * These functions are meant for compatibility with applications + * that require BER encoded keys. When working with secp256k1-specific + * code, the simple 32-byte private keys normally used by the + * library are sufficient. + */ + +#ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H +#define SECP256K1_CONTRIB_BER_PRIVATEKEY_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Export a private key in DER format. + * + * Returns: 1 if the private key was valid. + * Args: ctx: pointer to a context object, initialized for signing (cannot + * be NULL) + * Out: privkey: pointer to an array for storing the private key in BER. + * Should have space for 279 bytes, and cannot be NULL. + * privkeylen: Pointer to an int where the length of the private key in + * privkey will be stored. + * In: seckey: pointer to a 32-byte secret key to export. + * compressed: 1 if the key should be exported in + * compressed format, 0 otherwise + * + * This function is purely meant for compatibility with applications that + * require BER encoded keys. When working with secp256k1-specific code, the + * simple 32-byte private keys are sufficient. + * + * Note that this function does not guarantee correct DER output. It is + * guaranteed to be parsable by secp256k1_ec_privkey_import_der + */ +SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( + const secp256k1_context* ctx, + unsigned char *privkey, + size_t *privkeylen, + const unsigned char *seckey, + int compressed +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Import a private key in DER format. + * Returns: 1 if a private key was extracted. + * Args: ctx: pointer to a context object (cannot be NULL). + * Out: seckey: pointer to a 32-byte array for storing the private key. + * (cannot be NULL). + * In: privkey: pointer to a private key in DER format (cannot be NULL). + * privkeylen: length of the DER private key pointed to be privkey. + * + * This function will accept more than just strict DER, and even allow some BER + * violations. The public key stored inside the DER-encoded private key is not + * verified for correctness, nor are the curve parameters. Use this function + * only if you know in advance it is supposed to contain a secp256k1 private + * key. + */ +SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *privkey, + size_t privkeylen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ diff --git a/src/secp256k1/include/secp256k1.h b/src/secp256k1/include/secp256k1.h index 9db5cf3a8..3e9c098d1 100644 --- a/src/secp256k1/include/secp256k1.h +++ b/src/secp256k1/include/secp256k1.h @@ -1,9 +1,96 @@ -#ifndef _SECP256K1_ -# define _SECP256K1_ +#ifndef SECP256K1_H +#define SECP256K1_H -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif + +#include + +/* These rules specify the order of arguments in API calls: + * + * 1. Context pointers go first, followed by output arguments, combined + * output/input arguments, and finally input-only arguments. + * 2. Array lengths always immediately the follow the argument whose length + * they describe, even if this violates rule 1. + * 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated + * later go first. This means: signatures, public nonces, private nonces, + * messages, public keys, secret keys, tweaks. + * 4. Arguments that are not data pointers go last, from more complex to less + * complex: function pointers, algorithm names, messages, void pointers, + * counts, flags, booleans. + * 5. Opaque data pointers follow the function pointer they are to be passed to. + */ + +/** Opaque data structure that holds context information (precomputed tables etc.). + * + * The purpose of context structures is to cache large precomputed data tables + * that are expensive to construct, and also to maintain the randomization data + * for blinding. + * + * Do not create a new context object for each operation, as construction is + * far slower than all other API calls (~100 times slower than an ECDSA + * verification). + * + * A constructed context can safely be used from multiple threads + * simultaneously, but API call that take a non-const pointer to a context + * need exclusive access to it. In particular this is the case for + * secp256k1_context_destroy and secp256k1_context_randomize. + * + * Regarding randomization, either do it once at creation time (in which case + * you do not need any locking for the other calls), or use a read-write lock. + */ +typedef struct secp256k1_context_struct secp256k1_context; + +/** Opaque data structure that holds a parsed and valid public key. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_pubkey; + +/** Opaque data structured that holds a parsed ECDSA signature. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_parse_* functions. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_ecdsa_signature; + +/** A pointer to a function to deterministically generate a nonce. + * + * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. + * Out: nonce32: pointer to a 32-byte array to be filled by the function. + * In: msg32: the 32-byte message hash being verified (will not be NULL) + * key32: pointer to a 32-byte secret key (will not be NULL) + * algo16: pointer to a 16-byte array describing the signature + * algorithm (will be NULL for ECDSA for compatibility). + * data: Arbitrary data pointer that is passed through. + * attempt: how many iterations we have tried to find a nonce. + * This will almost always be 0, but different attempt values + * are required to result in a different nonce. + * + * Except for test cases, this function should compute some cryptographic hash of + * the message, the algorithm, the key and the attempt. + */ +typedef int (*secp256k1_nonce_function)( + unsigned char *nonce32, + const unsigned char *msg32, + const unsigned char *key32, + const unsigned char *algo16, + void *data, + unsigned int attempt +); # if !defined(SECP256K1_GNUC_PREREQ) # if defined(__GNUC__)&&defined(__GNUC_MINOR__) @@ -26,6 +113,20 @@ extern "C" { # define SECP256K1_INLINE inline # endif +#ifndef SECP256K1_API +# if defined(_WIN32) +# ifdef SECP256K1_BUILD +# define SECP256K1_API __declspec(dllexport) +# else +# define SECP256K1_API +# endif +# elif defined(__GNUC__) && defined(SECP256K1_BUILD) +# define SECP256K1_API __attribute__ ((visibility ("default"))) +# else +# define SECP256K1_API +# endif +#endif + /**Warning attributes * NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out * some paranoid null checks. */ @@ -40,320 +141,481 @@ extern "C" { # define SECP256K1_ARG_NONNULL(_x) # endif -/** Opaque data structure that holds context information (precomputed tables etc.). - * Only functions that take a pointer to a non-const context require exclusive - * access to it. Multiple functions that take a pointer to a const context may - * run simultaneously. - */ -typedef struct secp256k1_context_struct secp256k1_context_t; +/** All flags' lower 8 bits indicate what they're for. Do not use directly. */ +#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1) +#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0) +#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1) +/** The higher bits contain the actual data. Do not use directly. */ +#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8) +#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9) +#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8) /** Flags to pass to secp256k1_context_create. */ -# define SECP256K1_CONTEXT_VERIFY (1 << 0) -# define SECP256K1_CONTEXT_SIGN (1 << 1) +#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) +#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN) +#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT) + +/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */ +#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION) +#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION) + +/** Prefix byte used to tag various encoded curvepoints for specific purposes */ +#define SECP256K1_TAG_PUBKEY_EVEN 0x02 +#define SECP256K1_TAG_PUBKEY_ODD 0x03 +#define SECP256K1_TAG_PUBKEY_UNCOMPRESSED 0x04 +#define SECP256K1_TAG_PUBKEY_HYBRID_EVEN 0x06 +#define SECP256K1_TAG_PUBKEY_HYBRID_ODD 0x07 /** Create a secp256k1 context object. + * * Returns: a newly created context object. * In: flags: which parts of the context to initialize. + * + * See also secp256k1_context_randomize. */ -secp256k1_context_t* secp256k1_context_create( - int flags +SECP256K1_API secp256k1_context* secp256k1_context_create( + unsigned int flags ) SECP256K1_WARN_UNUSED_RESULT; /** Copies a secp256k1 context object. + * * Returns: a newly created context object. - * In: ctx: an existing context to copy + * Args: ctx: an existing context to copy (cannot be NULL) */ -secp256k1_context_t* secp256k1_context_clone( - const secp256k1_context_t* ctx -) SECP256K1_WARN_UNUSED_RESULT; +SECP256K1_API secp256k1_context* secp256k1_context_clone( + const secp256k1_context* ctx +) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; /** Destroy a secp256k1 context object. + * * The context pointer may not be used afterwards. + * Args: ctx: an existing context to destroy (cannot be NULL) */ -void secp256k1_context_destroy( - secp256k1_context_t* ctx +SECP256K1_API void secp256k1_context_destroy( + secp256k1_context* ctx +); + +/** Set a callback function to be called when an illegal argument is passed to + * an API call. It will only trigger for violations that are mentioned + * explicitly in the header. + * + * The philosophy is that these shouldn't be dealt with through a + * specific return value, as calling code should not have branches to deal with + * the case that this code itself is broken. + * + * On the other hand, during debug stage, one would want to be informed about + * such mistakes, and the default (crashing) may be inadvisable. + * When this callback is triggered, the API function called is guaranteed not + * to cause a crash, though its return value and output arguments are + * undefined. + * + * Args: ctx: an existing context object (cannot be NULL) + * In: fun: a pointer to a function to call when an illegal argument is + * passed to the API, taking a message and an opaque pointer + * (NULL restores a default handler that calls abort). + * data: the opaque pointer to pass to fun above. + */ +SECP256K1_API void secp256k1_context_set_illegal_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data ) SECP256K1_ARG_NONNULL(1); +/** Set a callback function to be called when an internal consistency check + * fails. The default is crashing. + * + * This can only trigger in case of a hardware failure, miscompilation, + * memory corruption, serious bug in the library, or other error would can + * otherwise result in undefined behaviour. It will not trigger due to mere + * incorrect usage of the API (see secp256k1_context_set_illegal_callback + * for that). After this callback returns, anything may happen, including + * crashing. + * + * Args: ctx: an existing context object (cannot be NULL) + * In: fun: a pointer to a function to call when an internal error occurs, + * taking a message and an opaque pointer (NULL restores a default + * handler that calls abort). + * data: the opaque pointer to pass to fun above. + */ +SECP256K1_API void secp256k1_context_set_error_callback( + secp256k1_context* ctx, + void (*fun)(const char* message, void* data), + const void* data +) SECP256K1_ARG_NONNULL(1); + +/** Parse a variable-length public key into the pubkey object. + * + * Returns: 1 if the public key was fully valid. + * 0 if the public key could not be parsed or is invalid. + * Args: ctx: a secp256k1 context object. + * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a + * parsed version of input. If not, its value is undefined. + * In: input: pointer to a serialized public key + * inputlen: length of the array pointed to by input + * + * This function supports parsing compressed (33 bytes, header byte 0x02 or + * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header + * byte 0x06 or 0x07) format public keys. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( + const secp256k1_context* ctx, + secp256k1_pubkey* pubkey, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a pubkey object into a serialized byte sequence. + * + * Returns: 1 always. + * Args: ctx: a secp256k1 context object. + * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if + * compressed==1) byte array to place the serialized key + * in. + * In/Out: outputlen: a pointer to an integer which is initially set to the + * size of output, and is overwritten with the written + * size. + * In: pubkey: a pointer to a secp256k1_pubkey containing an + * initialized public key. + * flags: SECP256K1_EC_COMPRESSED if serialization should be in + * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. + */ +SECP256K1_API int secp256k1_ec_pubkey_serialize( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_pubkey* pubkey, + unsigned int flags +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Parse an ECDSA signature in compact (64 bytes) format. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to the 64-byte array to parse + * + * The signature must consist of a 32-byte big endian R value, followed by a + * 32-byte big endian S value. If R or S fall outside of [0..order-1], the + * encoding is invalid. R and S with value 0 are allowed in the encoding. + * + * After the call, sig will always be initialized. If parsing failed or R or + * S are zero, the resulting sig value is guaranteed to fail validation for any + * message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input64 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Parse a DER ECDSA signature. + * + * Returns: 1 when the signature could be parsed, 0 otherwise. + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input: a pointer to the signature to be parsed + * inputlen: the length of the array pointed to be input + * + * This function will accept any valid DER encoded signature, even if the + * encoded numbers are out of range. + * + * After the call, sig will always be initialized. If parsing failed or the + * encoded numbers are out of range, signature validation with it is + * guaranteed to fail for every message and public key. + */ +SECP256K1_API int secp256k1_ecdsa_signature_parse_der( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const unsigned char *input, + size_t inputlen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in DER format. + * + * Returns: 1 if enough space was available to serialize, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: output: a pointer to an array to store the DER serialization + * In/Out: outputlen: a pointer to a length integer. Initially, this integer + * should be set to the length of output. After the call + * it will be set to the length of the serialization (even + * if 0 was returned). + * In: sig: a pointer to an initialized signature object + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( + const secp256k1_context* ctx, + unsigned char *output, + size_t *outputlen, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Serialize an ECDSA signature in compact (64 byte) format. + * + * Returns: 1 + * Args: ctx: a secp256k1 context object + * Out: output64: a pointer to a 64-byte array to store the compact serialization + * In: sig: a pointer to an initialized signature object + * + * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. + */ +SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + const secp256k1_ecdsa_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + /** Verify an ECDSA signature. + * * Returns: 1: correct signature - * 0: incorrect signature - * -1: invalid public key - * -2: invalid signature - * In: ctx: a secp256k1 context object, initialized for verification. + * 0: incorrect or unparseable signature + * Args: ctx: a secp256k1 context object, initialized for verification. + * In: sig: the signature being verified (cannot be NULL) * msg32: the 32-byte message hash being verified (cannot be NULL) - * sig: the signature being verified (cannot be NULL) - * siglen: the length of the signature - * pubkey: the public key to verify with (cannot be NULL) - * pubkeylen: the length of pubkey + * pubkey: pointer to an initialized public key to verify with (cannot be NULL) + * + * To avoid accepting malleable signatures, only ECDSA signatures in lower-S + * form are accepted. + * + * If you need to accept ECDSA signatures from sources that do not obey this + * rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to + * validation, but be aware that doing so results in malleable signatures. + * + * For details, see the comments for that function. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - const unsigned char *sig, - int siglen, - const unsigned char *pubkey, - int pubkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( + const secp256k1_context* ctx, + const secp256k1_ecdsa_signature *sig, + const unsigned char *msg32, + const secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Check that signature is in canonical form - * Returns: 1: In canonical form - * 0: Non canonical - * -1: invalid signature - * In: sig: the signature being verified (cannot be NULL) - * siglen: the length of the signature +/** Convert a signature to a normalized lower-S form. + * + * Returns: 1 if sigin was not normalized, 0 if it already was. + * Args: ctx: a secp256k1 context object + * Out: sigout: a pointer to a signature to fill with the normalized form, + * or copy if the input was already normalized. (can be NULL if + * you're only interested in whether the input was already + * normalized). + * In: sigin: a pointer to a signature to check/normalize (cannot be NULL, + * can be identical to sigout) + * + * With ECDSA a third-party can forge a second distinct signature of the same + * message, given a single initial signature, but without knowing the key. This + * is done by negating the S value modulo the order of the curve, 'flipping' + * the sign of the random point R which is not included in the signature. + * + * Forgery of the same message isn't universally problematic, but in systems + * where message malleability or uniqueness of signatures is important this can + * cause issues. This forgery can be blocked by all verifiers forcing signers + * to use a normalized form. + * + * The lower-S form reduces the size of signatures slightly on average when + * variable length encodings (such as DER) are used and is cheap to verify, + * making it a good choice. Security of always using lower-S is assured because + * anyone can trivially modify a signature after the fact to enforce this + * property anyway. + * + * The lower S value is always between 0x1 and + * 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, + * inclusive. + * + * No other forms of ECDSA malleability are known and none seem likely, but + * there is no formal proof that ECDSA, even with this additional restriction, + * is free of other malleability. Commonly used serialization schemes will also + * accept various non-unique encodings, so care should be taken when this + * property is required for an application. + * + * The secp256k1_ecdsa_sign function will by default create signatures in the + * lower-S form, and secp256k1_ecdsa_verify will not accept others. In case + * signatures come from a system that cannot enforce this property, + * secp256k1_ecdsa_signature_normalize must be called before verification. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_check_canonical_sig( - const unsigned char *sig, - int siglen -) SECP256K1_ARG_NONNULL(1); - -/** A pointer to a function to deterministically generate a nonce. - * Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail. - * In: msg32: the 32-byte message hash being verified (will not be NULL) - * key32: pointer to a 32-byte secret key (will not be NULL) - * attempt: how many iterations we have tried to find a nonce. - * This will almost always be 0, but different attempt values - * are required to result in a different nonce. - * data: Arbitrary data pointer that is passed through. - * Out: nonce32: pointer to a 32-byte array to be filled by the function. - * Except for test cases, this function should compute some cryptographic hash of - * the message, the key and the attempt. - */ -typedef int (*secp256k1_nonce_function_t)( - unsigned char *nonce32, - const unsigned char *msg32, - const unsigned char *key32, - unsigned int attempt, - const void *data -); +SECP256K1_API int secp256k1_ecdsa_signature_normalize( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sigout, + const secp256k1_ecdsa_signature *sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); /** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of * extra entropy. */ -extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979; +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; /** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */ -extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; - +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default; /** Create an ECDSA signature. - * Returns: 1: signature created - * 0: the nonce generation function failed, the private key was invalid, or there is not - * enough space in the signature (as indicated by siglen). - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * msg32: the 32-byte message hash being signed (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) - * In/Out: siglen: pointer to an int with the length of sig, which will be updated - * to contain the actual signature length (<=72). * - * The sig always has an s value in the lower half of the range (From 0x1 - * to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, - * inclusive), unlike many other implementations. - * With ECDSA a third-party can can forge a second distinct signature - * of the same message given a single initial signature without knowing - * the key by setting s to its additive inverse mod-order, 'flipping' the - * sign of the random point R which is not included in the signature. - * Since the forgery is of the same message this isn't universally - * problematic, but in systems where message malleability or uniqueness - * of signatures is important this can cause issues. This forgery can be - * blocked by all verifiers forcing signers to use a canonical form. The - * lower-S form reduces the size of signatures slightly on average when - * variable length encodings (such as DER) are used and is cheap to - * verify, making it a good choice. Security of always using lower-S is - * assured because anyone can trivially modify a signature after the - * fact to enforce this property. Adjusting it inside the signing - * function avoids the need to re-serialize or have curve specific - * constants outside of the library. By always using a canonical form - * even in applications where it isn't needed it becomes possible to - * impose a requirement later if a need is discovered. - * No other forms of ECDSA malleability are known and none seem likely, - * but there is no formal proof that ECDSA, even with this additional - * restriction, is free of other malleability. Commonly used serialization - * schemes will also accept various non-unique encodings, so care should - * be taken when this property is required for an application. - */ -int secp256k1_ecdsa_sign( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - unsigned char *sig, - int *siglen, - const unsigned char *seckey, - secp256k1_nonce_function_t noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); - -/** Create a compact ECDSA signature (64 byte + recovery id). * Returns: 1: signature created - * 0: the nonce generation function failed, or the secret key was invalid. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * msg32: the 32-byte message hash being signed (cannot be NULL) + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL) * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) - * Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL) - * In case 0 is returned, the returned signature length will be zero. - * recid: pointer to an int, which will be updated to contain the recovery id (can be NULL) + * + * The created signature is always in lower-S form. See + * secp256k1_ecdsa_signature_normalize for more details. */ -int secp256k1_ecdsa_sign_compact( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - unsigned char *sig64, - const unsigned char *seckey, - secp256k1_nonce_function_t noncefp, - const void *ndata, - int *recid +SECP256K1_API int secp256k1_ecdsa_sign( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature *sig, + const unsigned char *msg32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Recover an ECDSA public key from a compact signature. - * Returns: 1: public key successfully recovered (which guarantees a correct signature). - * 0: otherwise. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) - * sig64: signature as 64 byte array (cannot be NULL) - * compressed: whether to recover a compressed or uncompressed pubkey - * recid: the recovery id (0-3, as returned by ecdsa_sign_compact) - * Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL) - * pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL) - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact( - const secp256k1_context_t* ctx, - const unsigned char *msg32, - const unsigned char *sig64, - unsigned char *pubkey, - int *pubkeylen, - int compressed, - int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); - /** Verify an ECDSA secret key. + * * Returns: 1: secret key is valid * 0: secret key is invalid - * In: ctx: pointer to a context object (cannot be NULL) - * seckey: pointer to a 32-byte secret key (cannot be NULL) + * Args: ctx: pointer to a context object (cannot be NULL) + * In: seckey: pointer to a 32-byte secret key (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context_t* ctx, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); - -/** Just validate a public key. - * Returns: 1: public key is valid - * 0: public key is invalid - * In: ctx: pointer to a context object (cannot be NULL) - * pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL). - * pubkeylen: length of pubkey - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify( - const secp256k1_context_t* ctx, - const unsigned char *pubkey, - int pubkeylen +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( + const secp256k1_context* ctx, + const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Compute the public key for a secret key. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) - * compressed: whether the computed public key should be compressed - * seckey: pointer to a 32-byte private key (cannot be NULL) - * Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed) - * area to store the public key (cannot be NULL) - * pubkeylen: pointer to int that will be updated to contains the pubkey's - * length (cannot be NULL) + * * Returns: 1: secret was valid, public key stores * 0: secret was invalid, try again + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: pubkey: pointer to the created public key (cannot be NULL) + * In: seckey: pointer to a 32-byte private key (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int *pubkeylen, - const unsigned char *seckey, - int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); - -/** Decompress a public key. - * In: ctx: pointer to a context object (cannot be NULL) - * In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key. - * It must contain a 33-byte or 65-byte public key already (cannot be NULL) - * pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL) - * It will be updated to reflect the new size. - * Returns: 0: pubkey was invalid - * 1: pubkey was valid, and was replaced with its decompressed version - */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int *pubkeylen +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *seckey ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Export a private key in DER format. - * In: ctx: pointer to a context object, initialized for signing (cannot be NULL) +/** Negates a private key in place. + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * In/Out: pubkey: pointer to the public key to be negated (cannot be NULL) */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export( - const secp256k1_context_t* ctx, - const unsigned char *seckey, - unsigned char *privkey, - int *privkeylen, - int compressed -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate( + const secp256k1_context* ctx, + unsigned char *seckey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); -/** Import a private key in DER format. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *privkey, - int privkeylen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +/** Negates a public key in place. + * + * Returns: 1 always + * Args: ctx: pointer to a context object + * In/Out: pubkey: pointer to the public key to be negated (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); -/** Tweak a private key by adding tweak to it. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *tweak +/** Tweak a private key by adding tweak to it. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or if the resulting private key + * would be invalid (only when the tweak is the complement of the + * private key). 1 otherwise. + * Args: ctx: pointer to a context object (cannot be NULL). + * In/Out: seckey: pointer to a 32-byte private key. + * In: tweak: pointer to a 32-byte tweak. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by adding tweak times the generator to it. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or if the resulting public key + * would be invalid (only when the tweak is the complement of the + * corresponding private key). 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation + * (cannot be NULL). + * In/Out: pubkey: pointer to a public key object. + * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int pubkeylen, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); - -/** Tweak a private key by multiplying it with tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context_t* ctx, - unsigned char *seckey, - const unsigned char *tweak +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Tweak a public key by multiplying it with tweak. - * In: ctx: pointer to a context object, initialized for verification (cannot be NULL) +/** Tweak a private key by multiplying it by a tweak. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. + * Args: ctx: pointer to a context object (cannot be NULL). + * In/Out: seckey: pointer to a 32-byte private key. + * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context_t* ctx, - unsigned char *pubkey, - int pubkeylen, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( + const secp256k1_context* ctx, + unsigned char *seckey, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -/** Updates the context randomization. +/** Tweak a public key by multiplying it by a tweak value. + * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for + * uniformly random 32-byte arrays, or equal to zero. 1 otherwise. + * Args: ctx: pointer to a context object initialized for validation + * (cannot be NULL). + * In/Out: pubkey: pointer to a public key obkect. + * In: tweak: pointer to a 32-byte tweak. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const unsigned char *tweak +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Updates the context randomization to protect against side-channel leakage. * Returns: 1: randomization successfully updated * 0: error - * In: ctx: pointer to a context object (cannot be NULL) - * seed32: pointer to a 32-byte random seed (NULL resets to initial state) + * Args: ctx: pointer to a context object (cannot be NULL) + * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) + * + * While secp256k1 code is written to be constant-time no matter what secret + * values are, it's possible that a future compiler may output code which isn't, + * and also that the CPU may not emit the same radio frequencies or draw the same + * amount power for all values. + * + * This function provides a seed which is combined into the blinding value: that + * blinding value is added before each multiplication (and removed afterwards) so + * that it does not affect function results, but shields against attacks which + * rely on any input-dependent behaviour. + * + * You should call this after secp256k1_context_create or + * secp256k1_context_clone, and may call this repeatedly afterwards. */ -SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context_t* ctx, - const unsigned char *seed32 +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( + secp256k1_context* ctx, + const unsigned char *seed32 ) SECP256K1_ARG_NONNULL(1); +/** Add a number of public keys together. + * Returns: 1: the sum of the public keys is valid. + * 0: the sum of the public keys is not valid. + * Args: ctx: pointer to a context object + * Out: out: pointer to a public key object for placing the resulting public key + * (cannot be NULL) + * In: ins: pointer to array of pointers to public keys (cannot be NULL) + * n: the number of public keys to add together (must be at least 1) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( + const secp256k1_context* ctx, + secp256k1_pubkey *out, + const secp256k1_pubkey * const * ins, + size_t n +) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); -# ifdef __cplusplus +#ifdef __cplusplus } -# endif - #endif + +#endif /* SECP256K1_H */ diff --git a/src/secp256k1/include/secp256k1_ecdh.h b/src/secp256k1/include/secp256k1_ecdh.h new file mode 100644 index 000000000..88492dc1a --- /dev/null +++ b/src/secp256k1/include/secp256k1_ecdh.h @@ -0,0 +1,31 @@ +#ifndef SECP256K1_ECDH_H +#define SECP256K1_ECDH_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Compute an EC Diffie-Hellman secret in constant time + * Returns: 1: exponentiation was successful + * 0: scalar was invalid (zero or overflow) + * Args: ctx: pointer to a context object (cannot be NULL) + * Out: result: a 32-byte array which will be populated by an ECDH + * secret computed from the point and scalar + * In: pubkey: a pointer to a secp256k1_pubkey containing an + * initialized public key + * privkey: a 32-byte scalar with which to multiply the point + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( + const secp256k1_context* ctx, + unsigned char *result, + const secp256k1_pubkey *pubkey, + const unsigned char *privkey +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_ECDH_H */ diff --git a/src/secp256k1/include/secp256k1_recovery.h b/src/secp256k1/include/secp256k1_recovery.h new file mode 100644 index 000000000..cf6c5ed7f --- /dev/null +++ b/src/secp256k1/include/secp256k1_recovery.h @@ -0,0 +1,110 @@ +#ifndef SECP256K1_RECOVERY_H +#define SECP256K1_RECOVERY_H + +#include "secp256k1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Opaque data structured that holds a parsed ECDSA signature, + * supporting pubkey recovery. + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 65 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * the secp256k1_ecdsa_signature_serialize_* and + * secp256k1_ecdsa_signature_parse_* functions. + * + * Furthermore, it is guaranteed that identical signatures (including their + * recoverability) will have identical representation, so they can be + * memcmp'ed. + */ +typedef struct { + unsigned char data[65]; +} secp256k1_ecdsa_recoverable_signature; + +/** Parse a compact ECDSA signature (64 bytes + recovery id). + * + * Returns: 1 when the signature could be parsed, 0 otherwise + * Args: ctx: a secp256k1 context object + * Out: sig: a pointer to a signature object + * In: input64: a pointer to a 64-byte compact signature + * recid: the recovery id (0, 1, 2 or 3) + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature* sig, + const unsigned char *input64, + int recid +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Convert a recoverable signature into a normal signature. + * + * Returns: 1 + * Out: sig: a pointer to a normal signature (cannot be NULL). + * In: sigin: a pointer to a recoverable signature (cannot be NULL). + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( + const secp256k1_context* ctx, + secp256k1_ecdsa_signature* sig, + const secp256k1_ecdsa_recoverable_signature* sigin +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize an ECDSA signature in compact format (64 bytes + recovery id). + * + * Returns: 1 + * Args: ctx: a secp256k1 context object + * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) + * recid: a pointer to an integer to hold the recovery id (can be NULL). + * In: sig: a pointer to an initialized signature object (cannot be NULL) + */ +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( + const secp256k1_context* ctx, + unsigned char *output64, + int *recid, + const secp256k1_ecdsa_recoverable_signature* sig +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Create a recoverable ECDSA signature. + * + * Returns: 1: signature created + * 0: the nonce generation function failed, or the private key was invalid. + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) + * In: msg32: the 32-byte message hash being signed (cannot be NULL) + * seckey: pointer to a 32-byte secret key (cannot be NULL) + * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) + */ +SECP256K1_API int secp256k1_ecdsa_sign_recoverable( + const secp256k1_context* ctx, + secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msg32, + const unsigned char *seckey, + secp256k1_nonce_function noncefp, + const void *ndata +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +/** Recover an ECDSA public key from a signature. + * + * Returns: 1: public key successfully recovered (which guarantees a correct signature). + * 0: otherwise. + * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * Out: pubkey: pointer to the recovered public key (cannot be NULL) + * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) + * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( + const secp256k1_context* ctx, + secp256k1_pubkey *pubkey, + const secp256k1_ecdsa_recoverable_signature *sig, + const unsigned char *msg32 +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); + +#ifdef __cplusplus +} +#endif + +#endif /* SECP256K1_RECOVERY_H */ diff --git a/src/secp256k1/libsecp256k1.pc.in b/src/secp256k1/libsecp256k1.pc.in index 1c72dd000..a0d006f11 100644 --- a/src/secp256k1/libsecp256k1.pc.in +++ b/src/secp256k1/libsecp256k1.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: libsecp256k1 Description: Optimized C library for EC operations on curve secp256k1 -URL: https://github.com/bitcoin/secp256k1 +URL: https://github.com/bitcoin-core/secp256k1 Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs.private: @SECP_LIBS@ diff --git a/src/secp256k1/sage/group_prover.sage b/src/secp256k1/sage/group_prover.sage new file mode 100644 index 000000000..8521f0799 --- /dev/null +++ b/src/secp256k1/sage/group_prover.sage @@ -0,0 +1,322 @@ +# This code supports verifying group implementations which have branches +# or conditional statements (like cmovs), by allowing each execution path +# to independently set assumptions on input or intermediary variables. +# +# The general approach is: +# * A constraint is a tuple of two sets of symbolic expressions: +# the first of which are required to evaluate to zero, the second of which +# are required to evaluate to nonzero. +# - A constraint is said to be conflicting if any of its nonzero expressions +# is in the ideal with basis the zero expressions (in other words: when the +# zero expressions imply that one of the nonzero expressions are zero). +# * There is a list of laws that describe the intended behaviour, including +# laws for addition and doubling. Each law is called with the symbolic point +# coordinates as arguments, and returns: +# - A constraint describing the assumptions under which it is applicable, +# called "assumeLaw" +# - A constraint describing the requirements of the law, called "require" +# * Implementations are transliterated into functions that operate as well on +# algebraic input points, and are called once per combination of branches +# executed. Each execution returns: +# - A constraint describing the assumptions this implementation requires +# (such as Z1=1), called "assumeFormula" +# - A constraint describing the assumptions this specific branch requires, +# but which is by construction guaranteed to cover the entire space by +# merging the results from all branches, called "assumeBranch" +# - The result of the computation +# * All combinations of laws with implementation branches are tried, and: +# - If the combination of assumeLaw, assumeFormula, and assumeBranch results +# in a conflict, it means this law does not apply to this branch, and it is +# skipped. +# - For others, we try to prove the require constraints hold, assuming the +# information in assumeLaw + assumeFormula + assumeBranch, and if this does +# not succeed, we fail. +# + To prove an expression is zero, we check whether it belongs to the +# ideal with the assumed zero expressions as basis. This test is exact. +# + To prove an expression is nonzero, we check whether each of its +# factors is contained in the set of nonzero assumptions' factors. +# This test is not exact, so various combinations of original and +# reduced expressions' factors are tried. +# - If we succeed, we print out the assumptions from assumeFormula that +# weren't implied by assumeLaw already. Those from assumeBranch are skipped, +# as we assume that all constraints in it are complementary with each other. +# +# Based on the sage verification scripts used in the Explicit-Formulas Database +# by Tanja Lange and others, see http://hyperelliptic.org/EFD + +class fastfrac: + """Fractions over rings.""" + + def __init__(self,R,top,bot=1): + """Construct a fractional, given a ring, a numerator, and denominator.""" + self.R = R + if parent(top) == ZZ or parent(top) == R: + self.top = R(top) + self.bot = R(bot) + elif top.__class__ == fastfrac: + self.top = top.top + self.bot = top.bot * bot + else: + self.top = R(numerator(top)) + self.bot = R(denominator(top)) * bot + + def iszero(self,I): + """Return whether this fraction is zero given an ideal.""" + return self.top in I and self.bot not in I + + def reduce(self,assumeZero): + zero = self.R.ideal(map(numerator, assumeZero)) + return fastfrac(self.R, zero.reduce(self.top)) / fastfrac(self.R, zero.reduce(self.bot)) + + def __add__(self,other): + """Add two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top + self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot + self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __sub__(self,other): + """Subtract two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top - self.bot * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot - self.bot * other.top,self.bot * other.bot) + return NotImplemented + + def __neg__(self): + """Return the negation of a fraction.""" + return fastfrac(self.R,-self.top,self.bot) + + def __mul__(self,other): + """Multiply two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top * other,self.bot) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.top,self.bot * other.bot) + return NotImplemented + + def __rmul__(self,other): + """Multiply something else with a fraction.""" + return self.__mul__(other) + + def __div__(self,other): + """Divide two fractions.""" + if parent(other) == ZZ: + return fastfrac(self.R,self.top,self.bot * other) + if other.__class__ == fastfrac: + return fastfrac(self.R,self.top * other.bot,self.bot * other.top) + return NotImplemented + + def __pow__(self,other): + """Compute a power of a fraction.""" + if parent(other) == ZZ: + if other < 0: + # Negative powers require flipping top and bottom + return fastfrac(self.R,self.bot ^ (-other),self.top ^ (-other)) + else: + return fastfrac(self.R,self.top ^ other,self.bot ^ other) + return NotImplemented + + def __str__(self): + return "fastfrac((" + str(self.top) + ") / (" + str(self.bot) + "))" + def __repr__(self): + return "%s" % self + + def numerator(self): + return self.top + +class constraints: + """A set of constraints, consisting of zero and nonzero expressions. + + Constraints can either be used to express knowledge or a requirement. + + Both the fields zero and nonzero are maps from expressions to description + strings. The expressions that are the keys in zero are required to be zero, + and the expressions that are the keys in nonzero are required to be nonzero. + + Note that (a != 0) and (b != 0) is the same as (a*b != 0), so all keys in + nonzero could be multiplied into a single key. This is often much less + efficient to work with though, so we keep them separate inside the + constraints. This allows higher-level code to do fast checks on the individual + nonzero elements, or combine them if needed for stronger checks. + + We can't multiply the different zero elements, as it would suffice for one of + the factors to be zero, instead of all of them. Instead, the zero elements are + typically combined into an ideal first. + """ + + def __init__(self, **kwargs): + if 'zero' in kwargs: + self.zero = dict(kwargs['zero']) + else: + self.zero = dict() + if 'nonzero' in kwargs: + self.nonzero = dict(kwargs['nonzero']) + else: + self.nonzero = dict() + + def negate(self): + return constraints(zero=self.nonzero, nonzero=self.zero) + + def __add__(self, other): + zero = self.zero.copy() + zero.update(other.zero) + nonzero = self.nonzero.copy() + nonzero.update(other.nonzero) + return constraints(zero=zero, nonzero=nonzero) + + def __str__(self): + return "constraints(zero=%s,nonzero=%s)" % (self.zero, self.nonzero) + + def __repr__(self): + return "%s" % self + + +def conflicts(R, con): + """Check whether any of the passed non-zero assumptions is implied by the zero assumptions""" + zero = R.ideal(map(numerator, con.zero)) + if 1 in zero: + return True + # First a cheap check whether any of the individual nonzero terms conflict on + # their own. + for nonzero in con.nonzero: + if nonzero.iszero(zero): + return True + # It can be the case that entries in the nonzero set do not individually + # conflict with the zero set, but their combination does. For example, knowing + # that either x or y is zero is equivalent to having x*y in the zero set. + # Having x or y individually in the nonzero set is not a conflict, but both + # simultaneously is, so that is the right thing to check for. + if reduce(lambda a,b: a * b, con.nonzero, fastfrac(R, 1)).iszero(zero): + return True + return False + + +def get_nonzero_set(R, assume): + """Calculate a simple set of nonzero expressions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = set() + for nz in map(numerator, assume.nonzero): + for (f,n) in nz.factor(): + nonzero.add(f) + rnz = zero.reduce(nz) + for (f,n) in rnz.factor(): + nonzero.add(f) + return nonzero + + +def prove_nonzero(R, exprs, assume): + """Check whether an expression is provably nonzero, given assumptions""" + zero = R.ideal(map(numerator, assume.zero)) + nonzero = get_nonzero_set(R, assume) + expl = set() + ok = True + for expr in exprs: + if numerator(expr) in zero: + return (False, [exprs[expr]]) + allexprs = reduce(lambda a,b: numerator(a)*numerator(b), exprs, 1) + for (f, n) in allexprs.factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for (f, n) in zero.reduce(numerator(allexprs)).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in numerator(expr).factor(): + if f not in nonzero: + ok = False + if ok: + return (True, None) + ok = True + for expr in exprs: + for (f,n) in zero.reduce(numerator(expr)).factor(): + if f not in nonzero: + expl.add(exprs[expr]) + if expl: + return (False, list(expl)) + else: + return (True, None) + + +def prove_zero(R, exprs, assume): + """Check whether all of the passed expressions are provably zero, given assumptions""" + r, e = prove_nonzero(R, dict(map(lambda x: (fastfrac(R, x.bot, 1), exprs[x]), exprs)), assume) + if not r: + return (False, map(lambda x: "Possibly zero denominator: %s" % x, e)) + zero = R.ideal(map(numerator, assume.zero)) + nonzero = prod(x for x in assume.nonzero) + expl = [] + for expr in exprs: + if not expr.iszero(zero): + expl.append(exprs[expr]) + if not expl: + return (True, None) + return (False, expl) + + +def describe_extra(R, assume, assumeExtra): + """Describe what assumptions are added, given existing assumptions""" + zerox = assume.zero.copy() + zerox.update(assumeExtra.zero) + zero = R.ideal(map(numerator, assume.zero)) + zeroextra = R.ideal(map(numerator, zerox)) + nonzero = get_nonzero_set(R, assume) + ret = set() + # Iterate over the extra zero expressions + for base in assumeExtra.zero: + if base not in zero: + add = [] + for (f, n) in numerator(base).factor(): + if f not in nonzero: + add += ["%s" % f] + if add: + ret.add((" * ".join(add)) + " = 0 [%s]" % assumeExtra.zero[base]) + # Iterate over the extra nonzero expressions + for nz in assumeExtra.nonzero: + nzr = zeroextra.reduce(numerator(nz)) + if nzr not in zeroextra: + for (f,n) in nzr.factor(): + if zeroextra.reduce(f) not in nonzero: + ret.add("%s != 0" % zeroextra.reduce(f)) + return ", ".join(x for x in ret) + + +def check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require): + """Check a set of zero and nonzero requirements, given a set of zero and nonzero assumptions""" + assume = assumeLaw + assumeAssert + assumeBranch + + if conflicts(R, assume): + # This formula does not apply + return None + + describe = describe_extra(R, assumeLaw + assumeBranch, assumeAssert) + + ok, msg = prove_zero(R, require.zero, assume) + if not ok: + return "FAIL, %s fails (assuming %s)" % (str(msg), describe) + + res, expl = prove_nonzero(R, require.nonzero, assume) + if not res: + return "FAIL, %s fails (assuming %s)" % (str(expl), describe) + + if describe != "": + return "OK (assuming %s)" % describe + else: + return "OK" + + +def concrete_verify(c): + for k in c.zero: + if k != 0: + return (False, c.zero[k]) + for k in c.nonzero: + if k == 0: + return (False, c.nonzero[k]) + return (True, None) diff --git a/src/secp256k1/sage/secp256k1.sage b/src/secp256k1/sage/secp256k1.sage new file mode 100644 index 000000000..a97e732f7 --- /dev/null +++ b/src/secp256k1/sage/secp256k1.sage @@ -0,0 +1,306 @@ +# Test libsecp256k1' group operation implementations using prover.sage + +import sys + +load("group_prover.sage") +load("weierstrass_prover.sage") + +def formula_secp256k1_gej_double_var(a): + """libsecp256k1's secp256k1_gej_double_var, used by various addition functions""" + rz = a.Z * a.Y + rz = rz * 2 + t1 = a.X^2 + t1 = t1 * 3 + t2 = t1^2 + t3 = a.Y^2 + t3 = t3 * 2 + t4 = t3^2 + t4 = t4 * 2 + t3 = t3 * a.X + rx = t3 + rx = rx * 4 + rx = -rx + rx = rx + t2 + t2 = -t2 + t3 = t3 * 6 + t3 = t3 + t2 + ry = t1 * t3 + t2 = -t4 + ry = ry + t2 + return jacobianpoint(rx, ry, rz) + +def formula_secp256k1_gej_add_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_var""" + if branch == 0: + return (constraints(), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z22 = b.Z^2 + z12 = a.Z^2 + u1 = a.X * z22 + u2 = b.X * z12 + s1 = a.Y * z22 + s1 = s1 * b.Z + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={h : 'h=0', i : 'i=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}), r) + if branch == 3: + return (constraints(), constraints(zero={h : 'h=0', a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h2 * h + h = h * b.Z + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge_var, which assume bz==1""" + if branch == 0: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(nonzero={a.Infinity : 'a_infinite'}), b) + if branch == 1: + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite'}, nonzero={b.Infinity : 'b_infinite'}), a) + z12 = a.Z^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * a.Z + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if (branch == 2): + r = formula_secp256k1_gej_double_var(a) + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if (branch == 3): + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(zero={b.Z - 1 : 'b.z=1'}), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_zinv_var(branch, a, b): + """libsecp256k1's secp256k1_gej_add_zinv_var""" + bzinv = b.Z^(-1) + if branch == 0: + return (constraints(), constraints(nonzero={b.Infinity : 'b_infinite'}), a) + if branch == 1: + bzinv2 = bzinv^2 + bzinv3 = bzinv2 * bzinv + rx = b.X * bzinv2 + ry = b.Y * bzinv3 + rz = 1 + return (constraints(), constraints(zero={b.Infinity : 'b_finite'}, nonzero={a.Infinity : 'a_infinite'}), jacobianpoint(rx, ry, rz)) + azz = a.Z * bzinv + z12 = azz^2 + u1 = a.X + u2 = b.X * z12 + s1 = a.Y + s2 = b.Y * z12 + s2 = s2 * azz + h = -u1 + h = h + u2 + i = -s1 + i = i + s2 + if branch == 2: + r = formula_secp256k1_gej_double_var(a) + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0', i : 'i=0'}), r) + if branch == 3: + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite', h : 'h=0'}, nonzero={i : 'i!=0'}), point_at_infinity()) + i2 = i^2 + h2 = h^2 + h3 = h * h2 + rz = a.Z + rz = rz * h + t = u1 * h2 + rx = t + rx = rx * 2 + rx = rx + h3 + rx = -rx + rx = rx + i2 + ry = -rx + ry = ry + t + ry = ry * i + h3 = h3 * s1 + h3 = -h3 + ry = ry + h3 + return (constraints(), constraints(zero={a.Infinity : 'a_finite', b.Infinity : 'b_finite'}, nonzero={h : 'h!=0'}), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge(branch, a, b): + """libsecp256k1's secp256k1_gej_add_ge""" + zeroes = {} + nonzeroes = {} + a_infinity = False + if (branch & 4) != 0: + nonzeroes.update({a.Infinity : 'a_infinite'}) + a_infinity = True + else: + zeroes.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + rr = t^2 + m_alt = -u2 + tt = u1 * m_alt + rr = rr + tt + degenerate = (branch & 3) == 3 + if (branch & 1) != 0: + zeroes.update({m : 'm_zero'}) + else: + nonzeroes.update({m : 'm_nonzero'}) + if (branch & 2) != 0: + zeroes.update({rr : 'rr_zero'}) + else: + nonzeroes.update({rr : 'rr_nonzero'}) + rr_alt = s1 + rr_alt = rr_alt * 2 + m_alt = m_alt + u1 + if not degenerate: + rr_alt = rr + m_alt = m + n = m_alt^2 + q = n * t + n = n^2 + if degenerate: + n = m + t = rr_alt^2 + rz = a.Z * m_alt + infinity = False + if (branch & 8) != 0: + if not a_infinity: + infinity = True + zeroes.update({rz : 'r.z=0'}) + else: + nonzeroes.update({rz : 'r.z!=0'}) + rz = rz * 2 + q = -q + t = t + q + rx = t + t = t * 2 + t = t + q + t = t * rr_alt + t = t + n + ry = -t + rx = rx * 4 + ry = ry * 4 + if a_infinity: + rx = b.X + ry = b.Y + rz = 1 + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz)) + +def formula_secp256k1_gej_add_ge_old(branch, a, b): + """libsecp256k1's old secp256k1_gej_add_ge, which fails when ay+by=0 but ax!=bx""" + a_infinity = (branch & 1) != 0 + zero = {} + nonzero = {} + if a_infinity: + nonzero.update({a.Infinity : 'a_infinite'}) + else: + zero.update({a.Infinity : 'a_finite'}) + zz = a.Z^2 + u1 = a.X + u2 = b.X * zz + s1 = a.Y + s2 = b.Y * zz + s2 = s2 * a.Z + z = a.Z + t = u1 + t = t + u2 + m = s1 + m = m + s2 + n = m^2 + q = n * t + n = n^2 + rr = t^2 + t = u1 * u2 + t = -t + rr = rr + t + t = rr^2 + rz = m * z + infinity = False + if (branch & 2) != 0: + if not a_infinity: + infinity = True + else: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(nonzero={z : 'conflict_a'}, zero={z : 'conflict_b'}), point_at_infinity()) + zero.update({rz : 'r.z=0'}) + else: + nonzero.update({rz : 'r.z!=0'}) + rz = rz * (0 if a_infinity else 2) + rx = t + q = -q + rx = rx + q + q = q * 3 + t = t * 2 + t = t + q + t = t * rr + t = t + n + ry = -t + rx = rx * (0 if a_infinity else 4) + ry = ry * (0 if a_infinity else 4) + t = b.X + t = t * (1 if a_infinity else 0) + rx = rx + t + t = b.Y + t = t * (1 if a_infinity else 0) + ry = ry + t + t = (1 if a_infinity else 0) + rz = rz + t + if infinity: + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), point_at_infinity()) + return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zero, nonzero=nonzero), jacobianpoint(rx, ry, rz)) + +if __name__ == "__main__": + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge) + check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old) + + if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive": + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43) + check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43) diff --git a/src/secp256k1/sage/weierstrass_prover.sage b/src/secp256k1/sage/weierstrass_prover.sage new file mode 100644 index 000000000..03ef2ec90 --- /dev/null +++ b/src/secp256k1/sage/weierstrass_prover.sage @@ -0,0 +1,264 @@ +# Prover implementation for Weierstrass curves of the form +# y^2 = x^3 + A * x + B, specifically with a = 0 and b = 7, with group laws +# operating on affine and Jacobian coordinates, including the point at infinity +# represented by a 4th variable in coordinates. + +load("group_prover.sage") + + +class affinepoint: + def __init__(self, x, y, infinity=0): + self.x = x + self.y = y + self.infinity = infinity + def __str__(self): + return "affinepoint(x=%s,y=%s,inf=%s)" % (self.x, self.y, self.infinity) + + +class jacobianpoint: + def __init__(self, x, y, z, infinity=0): + self.X = x + self.Y = y + self.Z = z + self.Infinity = infinity + def __str__(self): + return "jacobianpoint(X=%s,Y=%s,Z=%s,inf=%s)" % (self.X, self.Y, self.Z, self.Infinity) + + +def point_at_infinity(): + return jacobianpoint(1, 1, 1, 1) + + +def negate(p): + if p.__class__ == affinepoint: + return affinepoint(p.x, -p.y) + if p.__class__ == jacobianpoint: + return jacobianpoint(p.X, -p.Y, p.Z) + assert(False) + + +def on_weierstrass_curve(A, B, p): + """Return a set of zero-expressions for an affine point to be on the curve""" + return constraints(zero={p.x^3 + A*p.x + B - p.y^2: 'on_curve'}) + + +def tangential_to_weierstrass_curve(A, B, p12, p3): + """Return a set of zero-expressions for ((x12,y12),(x3,y3)) to be a line that is tangential to the curve at (x12,y12)""" + return constraints(zero={ + (p12.y - p3.y) * (p12.y * 2) - (p12.x^2 * 3 + A) * (p12.x - p3.x): 'tangential_to_curve' + }) + + +def colinear(p1, p2, p3): + """Return a set of zero-expressions for ((x1,y1),(x2,y2),(x3,y3)) to be collinear""" + return constraints(zero={ + (p1.y - p2.y) * (p1.x - p3.x) - (p1.y - p3.y) * (p1.x - p2.x): 'colinear_1', + (p2.y - p3.y) * (p2.x - p1.x) - (p2.y - p1.y) * (p2.x - p3.x): 'colinear_2', + (p3.y - p1.y) * (p3.x - p2.x) - (p3.y - p2.y) * (p3.x - p1.x): 'colinear_3' + }) + + +def good_affine_point(p): + return constraints(nonzero={p.x : 'nonzero_x', p.y : 'nonzero_y'}) + + +def good_jacobian_point(p): + return constraints(nonzero={p.X : 'nonzero_X', p.Y : 'nonzero_Y', p.Z^6 : 'nonzero_Z'}) + + +def good_point(p): + return constraints(nonzero={p.Z^6 : 'nonzero_X'}) + + +def finite(p, *affine_fns): + con = good_point(p) + constraints(zero={p.Infinity : 'finite_point'}) + if p.Z != 0: + return con + reduce(lambda a, b: a + b, (f(affinepoint(p.X / p.Z^2, p.Y / p.Z^3)) for f in affine_fns), con) + else: + return con + +def infinite(p): + return constraints(nonzero={p.Infinity : 'infinite_point'}) + + +def law_jacobian_weierstrass_add(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian add, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(nonzero={pa.x - pb.x : 'different_x'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + colinear(pa, pb, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_double(A, B, pa, pb, pA, pB, pC): + """Check whether the passed set of coordinates is a valid Jacobian doubling, given assumptions""" + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y - pb.y : 'equal_y'})) + require = (finite(pC, lambda pc: on_weierstrass_curve(A, B, pc) + + tangential_to_weierstrass_curve(A, B, pa, negate(pc)))) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_opposites(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + on_weierstrass_curve(A, B, pb) + + finite(pA) + + finite(pB) + + constraints(zero={pa.x - pb.x : 'equal_x', pa.y + pb.y : 'opposite_y'})) + require = infinite(pC) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_a(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pb) + + infinite(pA) + + finite(pB)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pb.x : 'c.x=b.x', pc.y - pb.y : 'c.y=b.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_b(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + on_weierstrass_curve(A, B, pa) + + infinite(pB) + + finite(pA)) + require = finite(pC, lambda pc: constraints(zero={pc.x - pa.x : 'c.x=a.x', pc.y - pa.y : 'c.y=a.y'})) + return (assumeLaw, require) + + +def law_jacobian_weierstrass_add_infinite_ab(A, B, pa, pb, pA, pB, pC): + assumeLaw = (good_affine_point(pa) + + good_affine_point(pb) + + good_jacobian_point(pA) + + good_jacobian_point(pB) + + infinite(pA) + + infinite(pB)) + require = infinite(pC) + return (assumeLaw, require) + + +laws_jacobian_weierstrass = { + 'add': law_jacobian_weierstrass_add, + 'double': law_jacobian_weierstrass_double, + 'add_opposite': law_jacobian_weierstrass_add_opposites, + 'add_infinite_a': law_jacobian_weierstrass_add_infinite_a, + 'add_infinite_b': law_jacobian_weierstrass_add_infinite_b, + 'add_infinite_ab': law_jacobian_weierstrass_add_infinite_ab +} + + +def check_exhaustive_jacobian_weierstrass(name, A, B, branches, formula, p): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve, by executing and validating the result for every possible addition in a prime field""" + F = Integers(p) + print "Formula %s on Z%i:" % (name, p) + points = [] + for x in xrange(0, p): + for y in xrange(0, p): + point = affinepoint(F(x), F(y)) + r, e = concrete_verify(on_weierstrass_curve(A, B, point)) + if r: + points.append(point) + + for za in xrange(1, p): + for zb in xrange(1, p): + for pa in points: + for pb in points: + for ia in xrange(2): + for ib in xrange(2): + pA = jacobianpoint(pa.x * F(za)^2, pa.y * F(za)^3, F(za), ia) + pB = jacobianpoint(pb.x * F(zb)^2, pb.y * F(zb)^3, F(zb), ib) + for branch in xrange(0, branches): + assumeAssert, assumeBranch, pC = formula(branch, pA, pB) + pC.X = F(pC.X) + pC.Y = F(pC.Y) + pC.Z = F(pC.Z) + pC.Infinity = F(pC.Infinity) + r, e = concrete_verify(assumeAssert + assumeBranch) + if r: + match = False + for key in laws_jacobian_weierstrass: + assumeLaw, require = laws_jacobian_weierstrass[key](A, B, pa, pb, pA, pB, pC) + r, e = concrete_verify(assumeLaw) + if r: + if match: + print " multiple branches for (%s,%s,%s,%s) + (%s,%s,%s,%s)" % (pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity) + else: + match = True + r, e = concrete_verify(require) + if not r: + print " failure in branch %i for (%s,%s,%s,%s) + (%s,%s,%s,%s) = (%s,%s,%s,%s): %s" % (branch, pA.X, pA.Y, pA.Z, pA.Infinity, pB.X, pB.Y, pB.Z, pB.Infinity, pC.X, pC.Y, pC.Z, pC.Infinity, e) + print + + +def check_symbolic_function(R, assumeAssert, assumeBranch, f, A, B, pa, pb, pA, pB, pC): + assumeLaw, require = f(A, B, pa, pb, pA, pB, pC) + return check_symbolic(R, assumeLaw, assumeAssert, assumeBranch, require) + +def check_symbolic_jacobian_weierstrass(name, A, B, branches, formula): + """Verify an implementation of addition of Jacobian points on a Weierstrass curve symbolically""" + R. = PolynomialRing(QQ,8,order='invlex') + lift = lambda x: fastfrac(R,x) + ax = lift(ax) + ay = lift(ay) + Az = lift(Az) + bx = lift(bx) + by = lift(by) + Bz = lift(Bz) + Ai = lift(Ai) + Bi = lift(Bi) + + pa = affinepoint(ax, ay, Ai) + pb = affinepoint(bx, by, Bi) + pA = jacobianpoint(ax * Az^2, ay * Az^3, Az, Ai) + pB = jacobianpoint(bx * Bz^2, by * Bz^3, Bz, Bi) + + res = {} + + for key in laws_jacobian_weierstrass: + res[key] = [] + + print ("Formula " + name + ":") + count = 0 + for branch in xrange(branches): + assumeFormula, assumeBranch, pC = formula(branch, pA, pB) + pC.X = lift(pC.X) + pC.Y = lift(pC.Y) + pC.Z = lift(pC.Z) + pC.Infinity = lift(pC.Infinity) + + for key in laws_jacobian_weierstrass: + res[key].append((check_symbolic_function(R, assumeFormula, assumeBranch, laws_jacobian_weierstrass[key], A, B, pa, pb, pA, pB, pC), branch)) + + for key in res: + print " %s:" % key + val = res[key] + for x in val: + if x[0] is not None: + print " branch %i: %s" % (x[1], x[0]) + + print diff --git a/src/secp256k1/src/asm/field_10x26_arm.s b/src/secp256k1/src/asm/field_10x26_arm.s new file mode 100644 index 000000000..5a9cc3ffc --- /dev/null +++ b/src/secp256k1/src/asm/field_10x26_arm.s @@ -0,0 +1,919 @@ +@ vim: set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab syntax=armasm: +/********************************************************************** + * Copyright (c) 2014 Wladimir J. van der Laan * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ +/* +ARM implementation of field_10x26 inner loops. + +Note: + +- To avoid unnecessary loads and make use of available registers, two + 'passes' have every time been interleaved, with the odd passes accumulating c' and d' + which will be added to c and d respectively in the even passes + +*/ + + .syntax unified + .arch armv7-a + @ eabi attributes - see readelf -A + .eabi_attribute 8, 1 @ Tag_ARM_ISA_use = yes + .eabi_attribute 9, 0 @ Tag_Thumb_ISA_use = no + .eabi_attribute 10, 0 @ Tag_FP_arch = none + .eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte + .eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP + .eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed + .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6 + .text + + @ Field constants + .set field_R0, 0x3d10 + .set field_R1, 0x400 + .set field_not_M, 0xfc000000 @ ~M = ~0x3ffffff + + .align 2 + .global secp256k1_fe_mul_inner + .type secp256k1_fe_mul_inner, %function + @ Arguments: + @ r0 r Restrict: can overlap with a, not with b + @ r1 a + @ r2 b + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_mul_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r7,r8 scratch + r1 a (pointer) + r2 b (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + + /* A - interleaved with B */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #9*4] @ b[9] + ldr r0, [r1, #1*4] @ a[1] + umull r5, r6, r7, r8 @ d = a[0] * b[9] + ldr r14, [r2, #8*4] @ b[8] + umull r9, r10, r0, r8 @ d' = a[1] * b[9] + ldr r7, [r1, #2*4] @ a[2] + umlal r5, r6, r0, r14 @ d += a[1] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r14 @ d' += a[2] * b[8] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r8 @ d += a[2] * b[7] + ldr r14, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r8 @ d' += a[3] * b[7] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r14 @ d += a[3] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r14 @ d' += a[4] * b[6] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r8 @ d += a[4] * b[5] + ldr r14, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r8 @ d' += a[5] * b[5] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r14 @ d += a[5] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r14 @ d' += a[6] * b[4] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[3] + ldr r14, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r8 @ d' += a[7] * b[3] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[7] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r9, r10, r7, r14 @ d' += a[8] * b[2] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r8 @ d += a[8] * b[1] + ldr r14, [r2, #0*4] @ b[0] + umlal r9, r10, r0, r8 @ d' += a[9] * b[1] + ldr r7, [r1, #0*4] @ a[0] + umlal r5, r6, r0, r14 @ d += a[9] * b[0] + @ r7,r14 used in B + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 4*9] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + umull r3, r4, r7, r14 @ c = a[0] * b[0] + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C - interleaved with D */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #2*4] @ b[2] + ldr r14, [r2, #1*4] @ b[1] + umull r11, r12, r7, r8 @ c' = a[0] * b[2] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[1] * b[1] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[2] * b[0] + ldr r0, [r1, #3*4] @ a[3] + umlal r5, r6, r7, r14 @ d += a[2] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[3] * b[9] + ldr r7, [r1, #4*4] @ a[4] + umlal r5, r6, r0, r8 @ d += a[3] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[4] * b[8] + ldr r0, [r1, #5*4] @ a[5] + umlal r5, r6, r7, r14 @ d += a[4] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[5] * b[7] + ldr r7, [r1, #6*4] @ a[6] + umlal r5, r6, r0, r8 @ d += a[5] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r9, r10, r7, r8 @ d' += a[6] * b[6] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r9, r10, r0, r14 @ d' += a[7] * b[5] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r9, r10, r7, r8 @ d' += a[8] * b[4] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r9, r10, r0, r14 @ d' += a[9] * b[3] + umlal r5, r6, r0, r8 @ d += a[9] * b[2] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E - interleaved with F */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #4*4] @ b[4] + umull r11, r12, r7, r8 @ c' = a[0] * b[4] + ldr r8, [r2, #3*4] @ b[3] + umlal r3, r4, r7, r8 @ c += a[0] * b[3] + ldr r7, [r1, #1*4] @ a[1] + umlal r11, r12, r7, r8 @ c' += a[1] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r3, r4, r7, r8 @ c += a[1] * b[2] + ldr r7, [r1, #2*4] @ a[2] + umlal r11, r12, r7, r8 @ c' += a[2] * b[2] + ldr r8, [r2, #1*4] @ b[1] + umlal r3, r4, r7, r8 @ c += a[2] * b[1] + ldr r7, [r1, #3*4] @ a[3] + umlal r11, r12, r7, r8 @ c' += a[3] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r3, r4, r7, r8 @ c += a[3] * b[0] + ldr r7, [r1, #4*4] @ a[4] + umlal r11, r12, r7, r8 @ c' += a[4] * b[0] + ldr r8, [r2, #9*4] @ b[9] + umlal r5, r6, r7, r8 @ d += a[4] * b[9] + ldr r7, [r1, #5*4] @ a[5] + umull r9, r10, r7, r8 @ d' = a[5] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umlal r5, r6, r7, r8 @ d += a[5] * b[8] + ldr r7, [r1, #6*4] @ a[6] + umlal r9, r10, r7, r8 @ d' += a[6] * b[8] + ldr r8, [r2, #7*4] @ b[7] + umlal r5, r6, r7, r8 @ d += a[6] * b[7] + ldr r7, [r1, #7*4] @ a[7] + umlal r9, r10, r7, r8 @ d' += a[7] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r5, r6, r7, r8 @ d += a[7] * b[6] + ldr r7, [r1, #8*4] @ a[8] + umlal r9, r10, r7, r8 @ d' += a[8] * b[6] + ldr r8, [r2, #5*4] @ b[5] + umlal r5, r6, r7, r8 @ d += a[8] * b[5] + ldr r7, [r1, #9*4] @ a[9] + umlal r9, r10, r7, r8 @ d' += a[9] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r5, r6, r7, r8 @ d += a[9] * b[4] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G - interleaved with H */ + ldr r7, [r1, #0*4] @ a[0] + ldr r8, [r2, #6*4] @ b[6] + ldr r14, [r2, #5*4] @ b[5] + umull r11, r12, r7, r8 @ c' = a[0] * b[6] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[1] * b[5] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[2] * b[4] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[3] * b[3] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[4] * b[2] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[5] * b[1] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[6] * b[0] + ldr r0, [r1, #7*4] @ a[7] + umlal r5, r6, r7, r14 @ d += a[6] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[7] * b[9] + ldr r7, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r8 @ d += a[7] * b[8] + ldr r14, [r2, #7*4] @ b[7] + umlal r9, r10, r7, r8 @ d' += a[8] * b[8] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r9, r10, r0, r14 @ d' += a[9] * b[7] + umlal r5, r6, r0, r8 @ d += a[9] * b[6] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I - interleaved with J */ + ldr r8, [r2, #8*4] @ b[8] + ldr r7, [r1, #0*4] @ a[0] + ldr r14, [r2, #7*4] @ b[7] + umull r11, r12, r7, r8 @ c' = a[0] * b[8] + ldr r0, [r1, #1*4] @ a[1] + umlal r3, r4, r7, r14 @ c += a[0] * b[7] + ldr r8, [r2, #6*4] @ b[6] + umlal r11, r12, r0, r14 @ c' += a[1] * b[7] + ldr r7, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r8 @ c += a[1] * b[6] + ldr r14, [r2, #5*4] @ b[5] + umlal r11, r12, r7, r8 @ c' += a[2] * b[6] + ldr r0, [r1, #3*4] @ a[3] + umlal r3, r4, r7, r14 @ c += a[2] * b[5] + ldr r8, [r2, #4*4] @ b[4] + umlal r11, r12, r0, r14 @ c' += a[3] * b[5] + ldr r7, [r1, #4*4] @ a[4] + umlal r3, r4, r0, r8 @ c += a[3] * b[4] + ldr r14, [r2, #3*4] @ b[3] + umlal r11, r12, r7, r8 @ c' += a[4] * b[4] + ldr r0, [r1, #5*4] @ a[5] + umlal r3, r4, r7, r14 @ c += a[4] * b[3] + ldr r8, [r2, #2*4] @ b[2] + umlal r11, r12, r0, r14 @ c' += a[5] * b[3] + ldr r7, [r1, #6*4] @ a[6] + umlal r3, r4, r0, r8 @ c += a[5] * b[2] + ldr r14, [r2, #1*4] @ b[1] + umlal r11, r12, r7, r8 @ c' += a[6] * b[2] + ldr r0, [r1, #7*4] @ a[7] + umlal r3, r4, r7, r14 @ c += a[6] * b[1] + ldr r8, [r2, #0*4] @ b[0] + umlal r11, r12, r0, r14 @ c' += a[7] * b[1] + ldr r7, [r1, #8*4] @ a[8] + umlal r3, r4, r0, r8 @ c += a[7] * b[0] + ldr r14, [r2, #9*4] @ b[9] + umlal r11, r12, r7, r8 @ c' += a[8] * b[0] + ldr r0, [r1, #9*4] @ a[9] + umlal r5, r6, r7, r14 @ d += a[8] * b[9] + ldr r8, [r2, #8*4] @ b[8] + umull r9, r10, r0, r14 @ d' = a[9] * b[9] + umlal r5, r6, r0, r8 @ d += a[9] * b[8] + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_mul_inner, .-secp256k1_fe_mul_inner + + .align 2 + .global secp256k1_fe_sqr_inner + .type secp256k1_fe_sqr_inner, %function + @ Arguments: + @ r0 r Can overlap with a + @ r1 a + @ Stack (total 4+10*4 = 44) + @ sp + #0 saved 'r' pointer + @ sp + #4 + 4*X t0,t1,t2,t3,t4,t5,t6,t7,u8,t9 +secp256k1_fe_sqr_inner: + stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r14} + sub sp, sp, #48 @ frame=44 + alignment + str r0, [sp, #0] @ save result address, we need it only at the end + /****************************************** + * Main computation code. + ****************************************** + + Allocation: + r0,r14,r2,r7,r8 scratch + r1 a (pointer) + r3:r4 c + r5:r6 d + r11:r12 c' + r9:r10 d' + + Note: do not write to r[] here, it may overlap with a[] + */ + /* A interleaved with B */ + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r7, [r1, #0*4] @ a[0] + mov r0, r0, asl #1 + ldr r14, [r1, #9*4] @ a[9] + umull r3, r4, r7, r7 @ c = a[0] * a[0] + ldr r8, [r1, #8*4] @ a[8] + mov r7, r7, asl #1 + umull r5, r6, r7, r14 @ d = a[0]*2 * a[9] + ldr r7, [r1, #2*4] @ a[2]*2 + umull r9, r10, r0, r14 @ d' = a[1]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[1]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #3*4] @ a[3]*2 + umlal r9, r10, r7, r8 @ d' += a[2]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[7] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umlal r9, r10, r0, r14 @ d' += a[3]*2 * a[7] + ldr r14, [r1, #5*4] @ a[5] + mov r7, r7, asl #1 + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[6] + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[6] + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[5] + umlal r9, r10, r14, r14 @ d' += a[5] * a[5] + + bic r0, r5, field_not_M @ t9 = d & M + str r0, [sp, #4 + 9*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + /* B */ + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u0 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u0 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t0 = c & M + str r14, [sp, #4 + 0*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u0 * R1 + umlal r3, r4, r0, r14 + + /* C interleaved with D */ + ldr r0, [r1, #0*4] @ a[0]*2 + ldr r14, [r1, #1*4] @ a[1] + mov r0, r0, asl #1 + ldr r8, [r1, #2*4] @ a[2] + umlal r3, r4, r0, r14 @ c += a[0]*2 * a[1] + mov r7, r8, asl #1 @ a[2]*2 + umull r11, r12, r14, r14 @ c' = a[1] * a[1] + ldr r14, [r1, #9*4] @ a[9] + umlal r11, r12, r0, r8 @ c' += a[0]*2 * a[2] + ldr r0, [r1, #3*4] @ a[3]*2 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r7, r14 @ d += a[2]*2 * a[9] + mov r0, r0, asl #1 + ldr r7, [r1, #4*4] @ a[4]*2 + umull r9, r10, r0, r14 @ d' = a[3]*2 * a[9] + ldr r14, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r8 @ d += a[3]*2 * a[8] + mov r7, r7, asl #1 + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r9, r10, r7, r8 @ d' += a[4]*2 * a[8] + ldr r8, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umlal r5, r6, r7, r14 @ d += a[4]*2 * a[7] + umlal r9, r10, r0, r14 @ d' += a[5]*2 * a[7] + umlal r5, r6, r0, r8 @ d += a[5]*2 * a[6] + umlal r9, r10, r8, r8 @ d' += a[6] * a[6] + + bic r0, r5, field_not_M @ u1 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u1 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t1 = c & M + str r14, [sp, #4 + 1*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u1 * R1 + umlal r3, r4, r0, r14 + + /* D */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u2 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u2 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t2 = c & M + str r14, [sp, #4 + 2*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u2 * R1 + umlal r3, r4, r0, r14 + + /* E interleaved with F */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + ldr r14, [r1, #2*4] @ a[2] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + ldr r2, [r1, #4*4] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[3] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[4] + mov r2, r2, asl #1 @ a[4]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[3] + ldr r8, [r1, #9*4] @ a[9] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[2] + ldr r0, [r1, #5*4] @ a[5]*2 + umlal r11, r12, r14, r14 @ c' += a[2] * a[2] + ldr r14, [r1, #8*4] @ a[8] + mov r0, r0, asl #1 + umlal r5, r6, r2, r8 @ d += a[4]*2 * a[9] + ldr r7, [r1, #6*4] @ a[6]*2 + umull r9, r10, r0, r8 @ d' = a[5]*2 * a[9] + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + umlal r5, r6, r0, r14 @ d += a[5]*2 * a[8] + umlal r9, r10, r7, r14 @ d' += a[6]*2 * a[8] + umlal r5, r6, r7, r8 @ d += a[6]*2 * a[7] + umlal r9, r10, r8, r8 @ d' += a[7] * a[7] + + bic r0, r5, field_not_M @ u3 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u3 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t3 = c & M + str r14, [sp, #4 + 3*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u3 * R1 + umlal r3, r4, r0, r14 + + /* F */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u4 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u4 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t4 = c & M + str r14, [sp, #4 + 4*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u4 * R1 + umlal r3, r4, r0, r14 + + /* G interleaved with H */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #5*4] @ a[5] + ldr r2, [r1, #6*4] @ a[6] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[5] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[6] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[5] + mov r7, r7, asl #1 + ldr r8, [r1, #3*4] @ a[3] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[4] + mov r0, r2, asl #1 @ a[6]*2 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[4] + ldr r14, [r1, #9*4] @ a[9] + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[3] + ldr r7, [r1, #7*4] @ a[7]*2 + umlal r11, r12, r8, r8 @ c' += a[3] * a[3] + mov r7, r7, asl #1 + ldr r8, [r1, #8*4] @ a[8] + umlal r5, r6, r0, r14 @ d += a[6]*2 * a[9] + umull r9, r10, r7, r14 @ d' = a[7]*2 * a[9] + umlal r5, r6, r7, r8 @ d += a[7]*2 * a[8] + umlal r9, r10, r8, r8 @ d' += a[8] * a[8] + + bic r0, r5, field_not_M @ u5 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u5 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t5 = c & M + str r14, [sp, #4 + 5*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u5 * R1 + umlal r3, r4, r0, r14 + + /* H */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + adds r5, r5, r9 @ d += d' + adc r6, r6, r10 + + bic r0, r5, field_not_M @ u6 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u6 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t6 = c & M + str r14, [sp, #4 + 6*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u6 * R1 + umlal r3, r4, r0, r14 + + /* I interleaved with J */ + ldr r7, [r1, #0*4] @ a[0]*2 + ldr r0, [r1, #1*4] @ a[1]*2 + mov r7, r7, asl #1 + ldr r8, [r1, #7*4] @ a[7] + ldr r2, [r1, #8*4] @ a[8] + umlal r3, r4, r7, r8 @ c += a[0]*2 * a[7] + ldr r14, [r1, #6*4] @ a[6] + mov r0, r0, asl #1 + umull r11, r12, r7, r2 @ c' = a[0]*2 * a[8] + ldr r7, [r1, #2*4] @ a[2]*2 + umlal r11, r12, r0, r8 @ c' += a[1]*2 * a[7] + ldr r8, [r1, #5*4] @ a[5] + umlal r3, r4, r0, r14 @ c += a[1]*2 * a[6] + ldr r0, [r1, #3*4] @ a[3]*2 + mov r7, r7, asl #1 + umlal r11, r12, r7, r14 @ c' += a[2]*2 * a[6] + ldr r14, [r1, #4*4] @ a[4] + mov r0, r0, asl #1 + umlal r3, r4, r7, r8 @ c += a[2]*2 * a[5] + mov r2, r2, asl #1 @ a[8]*2 + umlal r11, r12, r0, r8 @ c' += a[3]*2 * a[5] + umlal r3, r4, r0, r14 @ c += a[3]*2 * a[4] + umlal r11, r12, r14, r14 @ c' += a[4] * a[4] + ldr r8, [r1, #9*4] @ a[9] + umlal r5, r6, r2, r8 @ d += a[8]*2 * a[9] + @ r8 will be used in J + + bic r0, r5, field_not_M @ u7 = d & M + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u7 * R0 + umlal r3, r4, r0, r14 + bic r14, r3, field_not_M @ t7 = c & M + str r14, [sp, #4 + 7*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u7 * R1 + umlal r3, r4, r0, r14 + + /* J */ + adds r3, r3, r11 @ c += c' + adc r4, r4, r12 + umlal r5, r6, r8, r8 @ d += a[9] * a[9] + + bic r0, r5, field_not_M @ u8 = d & M + str r0, [sp, #4 + 8*4] + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + movw r14, field_R0 @ c += u8 * R0 + umlal r3, r4, r0, r14 + + /****************************************** + * compute and write back result + ****************************************** + Allocation: + r0 r + r3:r4 c + r5:r6 d + r7 t0 + r8 t1 + r9 t2 + r11 u8 + r12 t9 + r1,r2,r10,r14 scratch + + Note: do not read from a[] after here, it may overlap with r[] + */ + ldr r0, [sp, #0] + add r1, sp, #4 + 3*4 @ r[3..7] = t3..7, r11=u8, r12=t9 + ldmia r1, {r2,r7,r8,r9,r10,r11,r12} + add r1, r0, #3*4 + stmia r1, {r2,r7,r8,r9,r10} + + bic r2, r3, field_not_M @ r[8] = c & M + str r2, [r0, #8*4] + mov r3, r3, lsr #26 @ c >>= 26 + orr r3, r3, r4, asl #6 + mov r4, r4, lsr #26 + mov r14, field_R1 @ c += u8 * R1 + umlal r3, r4, r11, r14 + movw r14, field_R0 @ c += d * R0 + umlal r3, r4, r5, r14 + adds r3, r3, r12 @ c += t9 + adc r4, r4, #0 + + add r1, sp, #4 + 0*4 @ r7,r8,r9 = t0,t1,t2 + ldmia r1, {r7,r8,r9} + + ubfx r2, r3, #0, #22 @ r[9] = c & (M >> 4) + str r2, [r0, #9*4] + mov r3, r3, lsr #22 @ c >>= 22 + orr r3, r3, r4, asl #10 + mov r4, r4, lsr #22 + movw r14, field_R1 << 4 @ c += d * (R1 << 4) + umlal r3, r4, r5, r14 + + movw r14, field_R0 >> 4 @ d = c * (R0 >> 4) + t0 (64x64 multiply+add) + umull r5, r6, r3, r14 @ d = c.lo * (R0 >> 4) + adds r5, r5, r7 @ d.lo += t0 + mla r6, r14, r4, r6 @ d.hi += c.hi * (R0 >> 4) + adc r6, r6, 0 @ d.hi += carry + + bic r2, r5, field_not_M @ r[0] = d & M + str r2, [r0, #0*4] + + mov r5, r5, lsr #26 @ d >>= 26 + orr r5, r5, r6, asl #6 + mov r6, r6, lsr #26 + + movw r14, field_R1 >> 4 @ d += c * (R1 >> 4) + t1 (64x64 multiply+add) + umull r1, r2, r3, r14 @ tmp = c.lo * (R1 >> 4) + adds r5, r5, r8 @ d.lo += t1 + adc r6, r6, #0 @ d.hi += carry + adds r5, r5, r1 @ d.lo += tmp.lo + mla r2, r14, r4, r2 @ tmp.hi += c.hi * (R1 >> 4) + adc r6, r6, r2 @ d.hi += carry + tmp.hi + + bic r2, r5, field_not_M @ r[1] = d & M + str r2, [r0, #1*4] + mov r5, r5, lsr #26 @ d >>= 26 (ignore hi) + orr r5, r5, r6, asl #6 + + add r5, r5, r9 @ d += t2 + str r5, [r0, #2*4] @ r[2] = d + + add sp, sp, #48 + ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc} + .size secp256k1_fe_sqr_inner, .-secp256k1_fe_sqr_inner + diff --git a/src/secp256k1/src/basic-config.h b/src/secp256k1/src/basic-config.h new file mode 100644 index 000000000..fc588061c --- /dev/null +++ b/src/secp256k1/src/basic-config.h @@ -0,0 +1,33 @@ +/********************************************************************** + * Copyright (c) 2013, 2014 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_BASIC_CONFIG_H +#define SECP256K1_BASIC_CONFIG_H + +#ifdef USE_BASIC_CONFIG + +#undef USE_ASM_X86_64 +#undef USE_ENDOMORPHISM +#undef USE_FIELD_10X26 +#undef USE_FIELD_5X52 +#undef USE_FIELD_INV_BUILTIN +#undef USE_FIELD_INV_NUM +#undef USE_NUM_GMP +#undef USE_NUM_NONE +#undef USE_SCALAR_4X64 +#undef USE_SCALAR_8X32 +#undef USE_SCALAR_INV_BUILTIN +#undef USE_SCALAR_INV_NUM + +#define USE_NUM_NONE 1 +#define USE_FIELD_INV_BUILTIN 1 +#define USE_SCALAR_INV_BUILTIN 1 +#define USE_FIELD_10X26 1 +#define USE_SCALAR_8X32 1 + +#endif /* USE_BASIC_CONFIG */ + +#endif /* SECP256K1_BASIC_CONFIG_H */ diff --git a/src/secp256k1/src/bench.h b/src/secp256k1/src/bench.h index db5f68cee..d5ebe0130 100644 --- a/src/secp256k1/src/bench.h +++ b/src/secp256k1/src/bench.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_BENCH_H_ -#define _SECP256K1_BENCH_H_ +#ifndef SECP256K1_BENCH_H +#define SECP256K1_BENCH_H #include #include @@ -20,8 +20,10 @@ static double gettimedouble(void) { void print_number(double x) { double y = x; int c = 0; - if (y < 0.0) y = -y; - while (y < 100.0) { + if (y < 0.0) { + y = -y; + } + while (y > 0 && y < 100.0) { y *= 10.0; c++; } @@ -35,13 +37,21 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v double max = 0.0; for (i = 0; i < count; i++) { double begin, total; - if (setup) setup(data); + if (setup != NULL) { + setup(data); + } begin = gettimedouble(); benchmark(data); total = gettimedouble() - begin; - if (teardown) teardown(data); - if (total < min) min = total; - if (total > max) max = total; + if (teardown != NULL) { + teardown(data); + } + if (total < min) { + min = total; + } + if (total > max) { + max = total; + } sum += total; } printf("%s: min ", name); @@ -53,4 +63,4 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v printf("us\n"); } -#endif +#endif /* SECP256K1_BENCH_H */ diff --git a/src/secp256k1/src/bench_ecdh.c b/src/secp256k1/src/bench_ecdh.c new file mode 100644 index 000000000..2de5126d6 --- /dev/null +++ b/src/secp256k1/src/bench_ecdh.c @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#include + +#include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" +#include "util.h" +#include "bench.h" + +typedef struct { + secp256k1_context *ctx; + secp256k1_pubkey point; + unsigned char scalar[32]; +} bench_ecdh; + +static void bench_ecdh_setup(void* arg) { + int i; + bench_ecdh *data = (bench_ecdh*)arg; + const unsigned char point[] = { + 0x03, + 0x54, 0x94, 0xc1, 0x5d, 0x32, 0x09, 0x97, 0x06, + 0xc2, 0x39, 0x5f, 0x94, 0x34, 0x87, 0x45, 0xfd, + 0x75, 0x7c, 0xe3, 0x0e, 0x4e, 0x8c, 0x90, 0xfb, + 0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f + }; + + /* create a context with no capabilities */ + data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT); + for (i = 0; i < 32; i++) { + data->scalar[i] = i + 1; + } + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1); +} + +static void bench_ecdh(void* arg) { + int i; + unsigned char res[32]; + bench_ecdh *data = (bench_ecdh*)arg; + + for (i = 0; i < 20000; i++) { + CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar) == 1); + } +} + +int main(void) { + bench_ecdh data; + + run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000); + return 0; +} diff --git a/src/secp256k1/src/bench_internal.c b/src/secp256k1/src/bench_internal.c index a960549b9..9b30c50d0 100644 --- a/src/secp256k1/src/bench_internal.c +++ b/src/secp256k1/src/bench_internal.c @@ -13,20 +13,22 @@ #include "field_impl.h" #include "group_impl.h" #include "scalar_impl.h" +#include "ecmult_const_impl.h" #include "ecmult_impl.h" #include "bench.h" +#include "secp256k1.c" typedef struct { - secp256k1_scalar_t scalar_x, scalar_y; - secp256k1_fe_t fe_x, fe_y; - secp256k1_ge_t ge_x, ge_y; - secp256k1_gej_t gej_x, gej_y; - unsigned char data[32]; + secp256k1_scalar scalar_x, scalar_y; + secp256k1_fe fe_x, fe_y; + secp256k1_ge ge_x, ge_y; + secp256k1_gej gej_x, gej_y; + unsigned char data[64]; int wnaf[256]; -} bench_inv_t; +} bench_inv; void bench_setup(void* arg) { - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; static const unsigned char init_x[32] = { 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, @@ -51,11 +53,12 @@ void bench_setup(void* arg) { secp256k1_gej_set_ge(&data->gej_x, &data->ge_x); secp256k1_gej_set_ge(&data->gej_y, &data->ge_y); memcpy(data->data, init_x, 32); + memcpy(data->data + 32, init_y, 32); } void bench_scalar_add(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000000; i++) { secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); @@ -64,7 +67,7 @@ void bench_scalar_add(void* arg) { void bench_scalar_negate(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000000; i++) { secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x); @@ -73,7 +76,7 @@ void bench_scalar_negate(void* arg) { void bench_scalar_sqr(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x); @@ -82,7 +85,7 @@ void bench_scalar_sqr(void* arg) { void bench_scalar_mul(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y); @@ -92,11 +95,11 @@ void bench_scalar_mul(void* arg) { #ifdef USE_ENDOMORPHISM void bench_scalar_split(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 20000; i++) { - secp256k1_scalar_t l, r; - secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x); + secp256k1_scalar l, r; + secp256k1_scalar_split_lambda(&l, &r, &data->scalar_x); secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); } } @@ -104,7 +107,7 @@ void bench_scalar_split(void* arg) { void bench_scalar_inverse(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000; i++) { secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x); @@ -114,7 +117,7 @@ void bench_scalar_inverse(void* arg) { void bench_scalar_inverse_var(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000; i++) { secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x); @@ -124,7 +127,7 @@ void bench_scalar_inverse_var(void* arg) { void bench_field_normalize(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000000; i++) { secp256k1_fe_normalize(&data->fe_x); @@ -133,7 +136,7 @@ void bench_field_normalize(void* arg) { void bench_field_normalize_weak(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 2000000; i++) { secp256k1_fe_normalize_weak(&data->fe_x); @@ -142,7 +145,7 @@ void bench_field_normalize_weak(void* arg) { void bench_field_mul(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y); @@ -151,7 +154,7 @@ void bench_field_mul(void* arg) { void bench_field_sqr(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { secp256k1_fe_sqr(&data->fe_x, &data->fe_x); @@ -160,7 +163,7 @@ void bench_field_sqr(void* arg) { void bench_field_inverse(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 20000; i++) { secp256k1_fe_inv(&data->fe_x, &data->fe_x); @@ -170,7 +173,7 @@ void bench_field_inverse(void* arg) { void bench_field_inverse_var(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 20000; i++) { secp256k1_fe_inv_var(&data->fe_x, &data->fe_x); @@ -178,37 +181,37 @@ void bench_field_inverse_var(void* arg) { } } -void bench_field_sqrt_var(void* arg) { +void bench_field_sqrt(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 20000; i++) { - secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x); + secp256k1_fe_sqrt(&data->fe_x, &data->fe_x); secp256k1_fe_add(&data->fe_x, &data->fe_y); } } void bench_group_double_var(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_double_var(&data->gej_x, &data->gej_x); + secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL); } } void bench_group_add_var(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y); + secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL); } } void bench_group_add_affine(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y); @@ -217,19 +220,38 @@ void bench_group_add_affine(void* arg) { void bench_group_add_affine_var(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 200000; i++) { - secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y); + secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL); + } +} + +void bench_group_jacobi_var(void* arg) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_gej_has_quad_y_var(&data->gej_x); } } void bench_ecmult_wnaf(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; + bench_inv *data = (bench_inv*)arg; for (i = 0; i < 20000; i++) { - secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A); + secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A); + secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); + } +} + +void bench_wnaf_const(void* arg) { + int i; + bench_inv *data = (bench_inv*)arg; + + for (i = 0; i < 20000; i++) { + secp256k1_wnaf_const(data->wnaf, data->scalar_x, WINDOW_A); secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); } } @@ -237,8 +259,8 @@ void bench_ecmult_wnaf(void* arg) { void bench_sha256(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_sha256_t sha; + bench_inv *data = (bench_inv*)arg; + secp256k1_sha256 sha; for (i = 0; i < 20000; i++) { secp256k1_sha256_initialize(&sha); @@ -249,8 +271,8 @@ void bench_sha256(void* arg) { void bench_hmac_sha256(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_hmac_sha256_t hmac; + bench_inv *data = (bench_inv*)arg; + secp256k1_hmac_sha256 hmac; for (i = 0; i < 20000; i++) { secp256k1_hmac_sha256_initialize(&hmac, data->data, 32); @@ -261,15 +283,46 @@ void bench_hmac_sha256(void* arg) { void bench_rfc6979_hmac_sha256(void* arg) { int i; - bench_inv_t *data = (bench_inv_t*)arg; - secp256k1_rfc6979_hmac_sha256_t rng; + bench_inv *data = (bench_inv*)arg; + secp256k1_rfc6979_hmac_sha256 rng; for (i = 0; i < 20000; i++) { - secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 32, data->data, 32, NULL, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64); secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32); } } +void bench_context_verify(void* arg) { + int i; + (void)arg; + for (i = 0; i < 20; i++) { + secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY)); + } +} + +void bench_context_sign(void* arg) { + int i; + (void)arg; + for (i = 0; i < 200; i++) { + secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN)); + } +} + +#ifndef USE_NUM_NONE +void bench_num_jacobi(void* arg) { + int i; + bench_inv *data = (bench_inv*)arg; + secp256k1_num nx, norder; + + secp256k1_scalar_get_num(&nx, &data->scalar_x); + secp256k1_scalar_order_get_num(&norder); + secp256k1_scalar_get_num(&norder, &data->scalar_y); + + for (i = 0; i < 200000; i++) { + secp256k1_num_jacobi(&nx, &norder); + } +} +#endif int have_flag(int argc, char** argv, char *flag) { char** argm = argv + argc; @@ -278,14 +331,16 @@ int have_flag(int argc, char** argv, char *flag) { return 1; } while (argv != NULL && argv != argm) { - if (strcmp(*argv, flag) == 0) return 1; + if (strcmp(*argv, flag) == 0) { + return 1; + } argv++; } return 0; } int main(int argc, char **argv) { - bench_inv_t data; + bench_inv data; if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000); if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000); if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000); @@ -302,17 +357,26 @@ int main(int argc, char **argv) { if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000); - if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000); if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000); + if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, 20000); + if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000); if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000); + + if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 20); + if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 200); + +#ifndef USE_NUM_NONE + if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, 200000); +#endif return 0; } diff --git a/src/secp256k1/src/bench_recover.c b/src/secp256k1/src/bench_recover.c index 56faed11a..506fc1880 100644 --- a/src/secp256k1/src/bench_recover.c +++ b/src/secp256k1/src/bench_recover.c @@ -1,46 +1,55 @@ /********************************************************************** - * Copyright (c) 2014 Pieter Wuille * + * Copyright (c) 2014-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ #include "include/secp256k1.h" +#include "include/secp256k1_recovery.h" #include "util.h" #include "bench.h" typedef struct { - secp256k1_context_t *ctx; + secp256k1_context *ctx; unsigned char msg[32]; unsigned char sig[64]; -} bench_recover_t; +} bench_recover; void bench_recover(void* arg) { int i; - bench_recover_t *data = (bench_recover_t*)arg; - unsigned char pubkey[33]; + bench_recover *data = (bench_recover*)arg; + secp256k1_pubkey pubkey; + unsigned char pubkeyc[33]; for (i = 0; i < 20000; i++) { int j; - int pubkeylen = 33; - CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2)); + size_t pubkeylen = 33; + secp256k1_ecdsa_recoverable_signature sig; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); + CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg)); + CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED)); for (j = 0; j < 32; j++) { data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ data->msg[j] = data->sig[j]; /* Move former R to message. */ - data->sig[j] = pubkey[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ + data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ } } } void bench_recover_setup(void* arg) { int i; - bench_recover_t *data = (bench_recover_t*)arg; + bench_recover *data = (bench_recover*)arg; - for (i = 0; i < 32; i++) data->msg[i] = 1 + i; - for (i = 0; i < 64; i++) data->sig[i] = 65 + i; + for (i = 0; i < 32; i++) { + data->msg[i] = 1 + i; + } + for (i = 0; i < 64; i++) { + data->sig[i] = 65 + i; + } } int main(void) { - bench_recover_t data; + bench_recover data; data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); diff --git a/src/secp256k1/src/bench_sign.c b/src/secp256k1/src/bench_sign.c index 072a37af5..544b43963 100644 --- a/src/secp256k1/src/bench_sign.c +++ b/src/secp256k1/src/bench_sign.c @@ -9,41 +9,47 @@ #include "bench.h" typedef struct { - secp256k1_context_t* ctx; + secp256k1_context* ctx; unsigned char msg[32]; unsigned char key[32]; -} bench_sign_t; +} bench_sign; static void bench_sign_setup(void* arg) { int i; - bench_sign_t *data = (bench_sign_t*)arg; + bench_sign *data = (bench_sign*)arg; - for (i = 0; i < 32; i++) data->msg[i] = i + 1; - for (i = 0; i < 32; i++) data->key[i] = i + 65; + for (i = 0; i < 32; i++) { + data->msg[i] = i + 1; + } + for (i = 0; i < 32; i++) { + data->key[i] = i + 65; + } } -static void bench_sign(void* arg) { +static void bench_sign_run(void* arg) { int i; - bench_sign_t *data = (bench_sign_t*)arg; + bench_sign *data = (bench_sign*)arg; - unsigned char sig[64]; + unsigned char sig[74]; for (i = 0; i < 20000; i++) { + size_t siglen = 74; int j; - int recid = 0; - CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid)); + secp256k1_ecdsa_signature signature; + CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); for (j = 0; j < 32; j++) { - data->msg[j] = sig[j]; /* Move former R to message. */ - data->key[j] = sig[j + 32]; /* Move former S to key. */ + data->msg[j] = sig[j]; + data->key[j] = sig[j + 32]; } } } int main(void) { - bench_sign_t data; + bench_sign data; data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000); + run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, 20000); secp256k1_context_destroy(data.ctx); return 0; diff --git a/src/secp256k1/src/bench_verify.c b/src/secp256k1/src/bench_verify.c index c8c82752c..418defa0a 100644 --- a/src/secp256k1/src/bench_verify.c +++ b/src/secp256k1/src/bench_verify.c @@ -11,14 +11,23 @@ #include "util.h" #include "bench.h" +#ifdef ENABLE_OPENSSL_TESTS +#include +#include +#include +#endif + typedef struct { - secp256k1_context_t *ctx; + secp256k1_context *ctx; unsigned char msg[32]; unsigned char key[32]; unsigned char sig[72]; - int siglen; + size_t siglen; unsigned char pubkey[33]; - int pubkeylen; + size_t pubkeylen; +#ifdef ENABLE_OPENSSL_TESTS + EC_GROUP* ec_group; +#endif } benchmark_verify_t; static void benchmark_verify(void* arg) { @@ -26,30 +35,77 @@ static void benchmark_verify(void* arg) { benchmark_verify_t* data = (benchmark_verify_t*)arg; for (i = 0; i < 20000; i++) { + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; data->sig[data->siglen - 1] ^= (i & 0xFF); data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); - CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0)); + CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); + CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); data->sig[data->siglen - 1] ^= (i & 0xFF); data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); } } +#ifdef ENABLE_OPENSSL_TESTS +static void benchmark_verify_openssl(void* arg) { + int i; + benchmark_verify_t* data = (benchmark_verify_t*)arg; + + for (i = 0; i < 20000; i++) { + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + { + EC_KEY *pkey = EC_KEY_new(); + const unsigned char *pubkey = &data->pubkey[0]; + int result; + + CHECK(pkey != NULL); + result = EC_KEY_set_group(pkey, data->ec_group); + CHECK(result); + result = (o2i_ECPublicKey(&pkey, &pubkey, data->pubkeylen)) != NULL; + CHECK(result); + result = ECDSA_verify(0, &data->msg[0], sizeof(data->msg), &data->sig[0], data->siglen, pkey) == (i == 0); + CHECK(result); + EC_KEY_free(pkey); + } + data->sig[data->siglen - 1] ^= (i & 0xFF); + data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); + data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); + } +} +#endif + int main(void) { int i; + secp256k1_pubkey pubkey; + secp256k1_ecdsa_signature sig; benchmark_verify_t data; data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - for (i = 0; i < 32; i++) data.msg[i] = 1 + i; - for (i = 0; i < 32; i++) data.key[i] = 33 + i; + for (i = 0; i < 32; i++) { + data.msg[i] = 1 + i; + } + for (i = 0; i < 32; i++) { + data.key[i] = 33 + i; + } data.siglen = 72; - secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL); + CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); + CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); + CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); data.pubkeylen = 33; - CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1)); + CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000); +#ifdef ENABLE_OPENSSL_TESTS + data.ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); + run_benchmark("ecdsa_verify_openssl", benchmark_verify_openssl, NULL, NULL, &data, 10, 20000); + EC_GROUP_free(data.ec_group); +#endif secp256k1_context_destroy(data.ctx); return 0; diff --git a/src/secp256k1/src/ecdsa.h b/src/secp256k1/src/ecdsa.h index 4ef78e8af..80590c7cc 100644 --- a/src/secp256k1/src/ecdsa.h +++ b/src/secp256k1/src/ecdsa.h @@ -4,21 +4,18 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECDSA_ -#define _SECP256K1_ECDSA_ +#ifndef SECP256K1_ECDSA_H +#define SECP256K1_ECDSA_H + +#include #include "scalar.h" #include "group.h" #include "ecmult.h" -typedef struct { - secp256k1_scalar_t r, s; -} secp256k1_ecdsa_sig_t; +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); -static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size); -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); - -#endif +#endif /* SECP256K1_ECDSA_H */ diff --git a/src/secp256k1/src/ecdsa_impl.h b/src/secp256k1/src/ecdsa_impl.h index 8d97db946..c3400042d 100644 --- a/src/secp256k1/src/ecdsa_impl.h +++ b/src/secp256k1/src/ecdsa_impl.h @@ -1,12 +1,12 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECDSA_IMPL_H_ -#define _SECP256K1_ECDSA_IMPL_H_ +#ifndef SECP256K1_ECDSA_IMPL_H +#define SECP256K1_ECDSA_IMPL_H #include "scalar.h" #include "field.h" @@ -28,7 +28,7 @@ * sage: '%x' % (EllipticCurve ([F (a), F (b)]).order()) * 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141' */ -static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( +static const secp256k1_fe secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL ); @@ -42,90 +42,148 @@ static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CON * sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order()) * '14551231950b75fc4402da1722fc9baee' */ -static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( +static const secp256k1_fe secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST( 0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL ); -static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { +static int secp256k1_der_read_len(const unsigned char **sigp, const unsigned char *sigend) { + int lenleft, b1; + size_t ret = 0; + if (*sigp >= sigend) { + return -1; + } + b1 = *((*sigp)++); + if (b1 == 0xFF) { + /* X.690-0207 8.1.3.5.c the value 0xFF shall not be used. */ + return -1; + } + if ((b1 & 0x80) == 0) { + /* X.690-0207 8.1.3.4 short form length octets */ + return b1; + } + if (b1 == 0x80) { + /* Indefinite length is not allowed in DER. */ + return -1; + } + /* X.690-207 8.1.3.5 long form length octets */ + lenleft = b1 & 0x7F; + if (lenleft > sigend - *sigp) { + return -1; + } + if (**sigp == 0) { + /* Not the shortest possible length encoding. */ + return -1; + } + if ((size_t)lenleft > sizeof(size_t)) { + /* The resulting length would exceed the range of a size_t, so + * certainly longer than the passed array size. + */ + return -1; + } + while (lenleft > 0) { + ret = (ret << 8) | **sigp; + if (ret + lenleft > (size_t)(sigend - *sigp)) { + /* Result exceeds the length of the passed array. */ + return -1; + } + (*sigp)++; + lenleft--; + } + if (ret < 128) { + /* Not the shortest possible length encoding. */ + return -1; + } + return ret; +} - /* libscott had to add this to get this version of the library to read compact sigs */ +static int secp256k1_der_parse_integer(secp256k1_scalar *r, const unsigned char **sig, const unsigned char *sigend) { int overflow = 0; - if (size == 64) { - secp256k1_scalar_set_b32(&r->r, sig, &overflow); - secp256k1_scalar_set_b32(&r->s, sig+32, &overflow); - return 1; - } + unsigned char ra[32] = {0}; + int rlen; - unsigned char ra[32] = {0}, sa[32] = {0}; - const unsigned char *rp; - const unsigned char *sp; - int lenr; - int lens; - if (sig[0] != 0x30) { + if (*sig == sigend || **sig != 0x02) { + /* Not a primitive integer (X.690-0207 8.3.1). */ return 0; } - lenr = sig[3]; - if (5+lenr >= size) { + (*sig)++; + rlen = secp256k1_der_read_len(sig, sigend); + if (rlen <= 0 || (*sig) + rlen > sigend) { + /* Exceeds bounds or not at least length 1 (X.690-0207 8.3.1). */ return 0; } - lens = sig[lenr+5]; - if (sig[1] != lenr+lens+4) { + if (**sig == 0x00 && rlen > 1 && (((*sig)[1]) & 0x80) == 0x00) { + /* Excessive 0x00 padding. */ return 0; } - if (lenr+lens+6 > size) { + if (**sig == 0xFF && rlen > 1 && (((*sig)[1]) & 0x80) == 0x80) { + /* Excessive 0xFF padding. */ return 0; } - if (sig[2] != 0x02) { - return 0; + if ((**sig & 0x80) == 0x80) { + /* Negative. */ + overflow = 1; } - if (lenr == 0) { - return 0; + while (rlen > 0 && **sig == 0) { + /* Skip leading zero bytes */ + rlen--; + (*sig)++; } - if (sig[lenr+4] != 0x02) { - return 0; + if (rlen > 32) { + overflow = 1; } - if (lens == 0) { - return 0; + if (!overflow) { + memcpy(ra + 32 - rlen, *sig, rlen); + secp256k1_scalar_set_b32(r, ra, &overflow); } - sp = sig + 6 + lenr; - while (lens > 0 && sp[0] == 0) { - lens--; - sp++; - } - if (lens > 32) { - return 0; - } - rp = sig + 4; - while (lenr > 0 && rp[0] == 0) { - lenr--; - rp++; - } - if (lenr > 32) { - return 0; - } - memcpy(ra + 32 - lenr, rp, lenr); - memcpy(sa + 32 - lens, sp, lens); - overflow = 0; - secp256k1_scalar_set_b32(&r->r, ra, &overflow); if (overflow) { - return 0; - } - secp256k1_scalar_set_b32(&r->s, sa, &overflow); - if (overflow) { - return 0; + secp256k1_scalar_set_int(r, 0); } + (*sig) += rlen; return 1; } -static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { +static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *rr, secp256k1_scalar *rs, const unsigned char *sig, size_t size) { + const unsigned char *sigend = sig + size; + int rlen; + if (sig == sigend || *(sig++) != 0x30) { + /* The encoding doesn't start with a constructed sequence (X.690-0207 8.9.1). */ + return 0; + } + rlen = secp256k1_der_read_len(&sig, sigend); + if (rlen < 0 || sig + rlen > sigend) { + /* Tuple exceeds bounds */ + return 0; + } + if (sig + rlen != sigend) { + /* Garbage after tuple. */ + return 0; + } + + if (!secp256k1_der_parse_integer(rr, &sig, sigend)) { + return 0; + } + if (!secp256k1_der_parse_integer(rs, &sig, sigend)) { + return 0; + } + + if (sig != sigend) { + /* Trailing garbage inside tuple. */ + return 0; + } + + return 1; +} + +static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar* ar, const secp256k1_scalar* as) { unsigned char r[33] = {0}, s[33] = {0}; unsigned char *rp = r, *sp = s; - int lenR = 33, lenS = 33; - secp256k1_scalar_get_b32(&r[1], &a->r); - secp256k1_scalar_get_b32(&s[1], &a->s); + size_t lenR = 33, lenS = 33; + secp256k1_scalar_get_b32(&r[1], ar); + secp256k1_scalar_get_b32(&s[1], as); while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } if (*size < 6+lenS+lenR) { + *size = 6 + lenS + lenR; return 0; } *size = 6 + lenS + lenR; @@ -140,26 +198,41 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se return 1; } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar *sigs, const secp256k1_ge *pubkey, const secp256k1_scalar *message) { unsigned char c[32]; - secp256k1_scalar_t sn, u1, u2; - secp256k1_fe_t xr; - secp256k1_gej_t pubkeyj; - secp256k1_gej_t pr; + secp256k1_scalar sn, u1, u2; +#if !defined(EXHAUSTIVE_TEST_ORDER) + secp256k1_fe xr; +#endif + secp256k1_gej pubkeyj; + secp256k1_gej pr; - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { return 0; } - secp256k1_scalar_inverse_var(&sn, &sig->s); + secp256k1_scalar_inverse_var(&sn, sigs); secp256k1_scalar_mul(&u1, &sn, message); - secp256k1_scalar_mul(&u2, &sn, &sig->r); + secp256k1_scalar_mul(&u2, &sn, sigr); secp256k1_gej_set_ge(&pubkeyj, pubkey); secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1); if (secp256k1_gej_is_infinity(&pr)) { return 0; } - secp256k1_scalar_get_b32(c, &sig->r); + +#if defined(EXHAUSTIVE_TEST_ORDER) +{ + secp256k1_scalar computed_r; + secp256k1_ge pr_ge; + secp256k1_ge_set_gej(&pr_ge, &pr); + secp256k1_fe_normalize(&pr_ge.x); + + secp256k1_fe_get_b32(c, &pr_ge.x); + secp256k1_scalar_set_b32(&computed_r, c, NULL); + return secp256k1_scalar_eq(sigr, &computed_r); +} +#else + secp256k1_scalar_get_b32(c, sigr); secp256k1_fe_set_b32(&xr, c); /** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n) @@ -179,11 +252,11 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, con * secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test. */ if (secp256k1_gej_eq_x_var(&xr, &pr)) { - /* xr.x == xr * xr.z^2 mod p, so the signature is valid. */ + /* xr * pr.z^2 mod p == pr.x, so the signature is valid. */ return 1; } if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - /* xr + p >= n, so we can skip testing the second case. */ + /* xr + n >= p, so we can skip testing the second case. */ return 0; } secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe); @@ -192,46 +265,14 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, con return 1; } return 0; +#endif } -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { - unsigned char brx[32]; - secp256k1_fe_t fx; - secp256k1_ge_t x; - secp256k1_gej_t xj; - secp256k1_scalar_t rn, u1, u2; - secp256k1_gej_t qj; - - if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) { - return 0; - } - - secp256k1_scalar_get_b32(brx, &sig->r); - VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */ - if (recid & 2) { - if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { - return 0; - } - secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); - } - if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { - return 0; - } - secp256k1_gej_set_ge(&xj, &x); - secp256k1_scalar_inverse_var(&rn, &sig->r); - secp256k1_scalar_mul(&u1, &rn, message); - secp256k1_scalar_negate(&u1, &u1); - secp256k1_scalar_mul(&u2, &rn, &sig->s); - secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); - secp256k1_ge_set_gej_var(pubkey, &qj); - return !secp256k1_gej_is_infinity(&qj); -} - -static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) { +static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) { unsigned char b[32]; - secp256k1_gej_t rp; - secp256k1_ge_t r; - secp256k1_scalar_t n; + secp256k1_gej rp; + secp256k1_ge r; + secp256k1_scalar n; int overflow = 0; secp256k1_ecmult_gen(ctx, &rp, nonce); @@ -239,28 +280,29 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, s secp256k1_fe_normalize(&r.x); secp256k1_fe_normalize(&r.y); secp256k1_fe_get_b32(b, &r.x); - secp256k1_scalar_set_b32(&sig->r, b, &overflow); - if (secp256k1_scalar_is_zero(&sig->r)) { - /* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */ - secp256k1_gej_clear(&rp); - secp256k1_ge_clear(&r); - return 0; - } + secp256k1_scalar_set_b32(sigr, b, &overflow); + /* These two conditions should be checked before calling */ + VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr)); + VERIFY_CHECK(overflow == 0); + if (recid) { + /* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log + * of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria. + */ *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); } - secp256k1_scalar_mul(&n, &sig->r, seckey); + secp256k1_scalar_mul(&n, sigr, seckey); secp256k1_scalar_add(&n, &n, message); - secp256k1_scalar_inverse(&sig->s, nonce); - secp256k1_scalar_mul(&sig->s, &sig->s, &n); + secp256k1_scalar_inverse(sigs, nonce); + secp256k1_scalar_mul(sigs, sigs, &n); secp256k1_scalar_clear(&n); secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(&sig->s)) { + if (secp256k1_scalar_is_zero(sigs)) { return 0; } - if (secp256k1_scalar_is_high(&sig->s)) { - secp256k1_scalar_negate(&sig->s, &sig->s); + if (secp256k1_scalar_is_high(sigs)) { + secp256k1_scalar_negate(sigs, sigs); if (recid) { *recid ^= 1; } @@ -268,4 +310,4 @@ static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, s return 1; } -#endif +#endif /* SECP256K1_ECDSA_IMPL_H */ diff --git a/src/secp256k1/src/eckey.h b/src/secp256k1/src/eckey.h index 53b818485..b621f1e6c 100644 --- a/src/secp256k1/src/eckey.h +++ b/src/secp256k1/src/eckey.h @@ -4,23 +4,22 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECKEY_ -#define _SECP256K1_ECKEY_ +#ifndef SECP256K1_ECKEY_H +#define SECP256K1_ECKEY_H + +#include #include "group.h" #include "scalar.h" #include "ecmult.h" #include "ecmult_gen.h" -static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size); -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed); +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); -static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen); -static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed); +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); - -#endif +#endif /* SECP256K1_ECKEY_H */ diff --git a/src/secp256k1/src/eckey_impl.h b/src/secp256k1/src/eckey_impl.h index a332bd34e..1ab9a68ec 100644 --- a/src/secp256k1/src/eckey_impl.h +++ b/src/secp256k1/src/eckey_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECKEY_IMPL_H_ -#define _SECP256K1_ECKEY_IMPL_H_ +#ifndef SECP256K1_ECKEY_IMPL_H +#define SECP256K1_ECKEY_IMPL_H #include "eckey.h" @@ -14,17 +14,18 @@ #include "group.h" #include "ecmult_gen.h" -static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) { - if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { - secp256k1_fe_t x; - return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03); +static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { + if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { + secp256k1_fe x; + return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { - secp256k1_fe_t x, y; + secp256k1_fe x, y; if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { return 0; } secp256k1_ge_set_xy(elem, &x, &y); - if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) { + if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && + secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { return 0; } return secp256k1_ge_is_valid_var(elem); @@ -33,7 +34,7 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha } } -static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) { +static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { if (secp256k1_ge_is_infinity(elem)) { return 0; } @@ -42,119 +43,16 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char secp256k1_fe_get_b32(&pub[1], &elem->x); if (compressed) { *size = 33; - pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00); + pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; } else { *size = 65; - pub[0] = 0x04; + pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; secp256k1_fe_get_b32(&pub[33], &elem->y); } return 1; } -static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) { - unsigned char c[32] = {0}; - const unsigned char *end = privkey + privkeylen; - int lenb = 0; - int len = 0; - int overflow = 0; - /* sequence header */ - if (end < privkey+1 || *privkey != 0x30) { - return 0; - } - privkey++; - /* sequence length constructor */ - if (end < privkey+1 || !(*privkey & 0x80)) { - return 0; - } - lenb = *privkey & ~0x80; privkey++; - if (lenb < 1 || lenb > 2) { - return 0; - } - if (end < privkey+lenb) { - return 0; - } - /* sequence length */ - len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0); - privkey += lenb; - if (end < privkey+len) { - return 0; - } - /* sequence element 0: version number (=1) */ - if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) { - return 0; - } - privkey += 3; - /* sequence element 1: octet string, up to 32 bytes */ - if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) { - return 0; - } - memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]); - secp256k1_scalar_set_b32(key, c, &overflow); - memset(c, 0, 32); - return !overflow; -} - -static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) { - secp256k1_gej_t rp; - secp256k1_ge_t r; - int pubkeylen = 0; - secp256k1_ecmult_gen(ctx, &rp, key); - secp256k1_ge_set_gej(&r, &rp); - if (compressed) { - static const unsigned char begin[] = { - 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20 - }; - static const unsigned char middle[] = { - 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, - 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, - 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, - 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, - 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, - 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00 - }; - unsigned char *ptr = privkey; - memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); - secp256k1_scalar_get_b32(ptr, key); ptr += 32; - memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) { - return 0; - } - ptr += pubkeylen; - *privkeylen = ptr - privkey; - } else { - static const unsigned char begin[] = { - 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20 - }; - static const unsigned char middle[] = { - 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48, - 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04, - 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87, - 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8, - 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11, - 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10, - 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E, - 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00 - }; - unsigned char *ptr = privkey; - memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin); - secp256k1_scalar_get_b32(ptr, key); ptr += 32; - memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle); - if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) { - return 0; - } - ptr += pubkeylen; - *privkeylen = ptr - privkey; - } - return 1; -} - -static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) { +static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { secp256k1_scalar_add(key, key, tweak); if (secp256k1_scalar_is_zero(key)) { return 0; @@ -162,9 +60,9 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { - secp256k1_gej_t pt; - secp256k1_scalar_t one; +static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_gej pt; + secp256k1_scalar one; secp256k1_gej_set_ge(&pt, key); secp256k1_scalar_set_int(&one, 1); secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); @@ -176,7 +74,7 @@ static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ct return 1; } -static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) { +static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { if (secp256k1_scalar_is_zero(tweak)) { return 0; } @@ -185,9 +83,9 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { - secp256k1_scalar_t zero; - secp256k1_gej_t pt; +static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { + secp256k1_scalar zero; + secp256k1_gej pt; if (secp256k1_scalar_is_zero(tweak)) { return 0; } @@ -199,4 +97,4 @@ static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ct return 1; } -#endif +#endif /* SECP256K1_ECKEY_IMPL_H */ diff --git a/src/secp256k1/src/ecmult.h b/src/secp256k1/src/ecmult.h index bab9e4ef5..6d44aba60 100644 --- a/src/secp256k1/src/ecmult.h +++ b/src/secp256k1/src/ecmult.h @@ -4,28 +4,28 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECMULT_ -#define _SECP256K1_ECMULT_ +#ifndef SECP256K1_ECMULT_H +#define SECP256K1_ECMULT_H #include "num.h" #include "group.h" typedef struct { /* For accelerating the computation of a*P + b*G: */ - secp256k1_ge_storage_t (*pre_g)[]; /* odd multiples of the generator */ + secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ #ifdef USE_ENDOMORPHISM - secp256k1_ge_storage_t (*pre_g_128)[]; /* odd multiples of 2^128*generator */ + secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ #endif -} secp256k1_ecmult_context_t; +} secp256k1_ecmult_context; -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx); -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx); -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, - const secp256k1_ecmult_context_t *src); -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx); -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx); +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, + const secp256k1_ecmult_context *src, const secp256k1_callback *cb); +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); /** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng); +static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); -#endif +#endif /* SECP256K1_ECMULT_H */ diff --git a/src/secp256k1/src/ecmult_const.h b/src/secp256k1/src/ecmult_const.h new file mode 100644 index 000000000..72bf7d758 --- /dev/null +++ b/src/secp256k1/src/ecmult_const.h @@ -0,0 +1,15 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_ECMULT_CONST_H +#define SECP256K1_ECMULT_CONST_H + +#include "scalar.h" +#include "group.h" + +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); + +#endif /* SECP256K1_ECMULT_CONST_H */ diff --git a/src/secp256k1/src/ecmult_const_impl.h b/src/secp256k1/src/ecmult_const_impl.h new file mode 100644 index 000000000..7d7a172b7 --- /dev/null +++ b/src/secp256k1/src/ecmult_const_impl.h @@ -0,0 +1,240 @@ +/********************************************************************** + * Copyright (c) 2015 Pieter Wuille, Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_ECMULT_CONST_IMPL_H +#define SECP256K1_ECMULT_CONST_IMPL_H + +#include "scalar.h" +#include "group.h" +#include "ecmult_const.h" +#include "ecmult_impl.h" + +#ifdef USE_ENDOMORPHISM + #define WNAF_BITS 128 +#else + #define WNAF_BITS 256 +#endif +#define WNAF_SIZE(w) ((WNAF_BITS + (w) - 1) / (w)) + +/* This is like `ECMULT_TABLE_GET_GE` but is constant time */ +#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \ + int m; \ + int abs_n = (n) * (((n) > 0) * 2 - 1); \ + int idx_n = abs_n / 2; \ + secp256k1_fe neg_y; \ + VERIFY_CHECK(((n) & 1) == 1); \ + VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ + VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->x)); \ + VERIFY_SETUP(secp256k1_fe_clear(&(r)->y)); \ + for (m = 0; m < ECMULT_TABLE_SIZE(w); m++) { \ + /* This loop is used to avoid secret data in array indices. See + * the comment in ecmult_gen_impl.h for rationale. */ \ + secp256k1_fe_cmov(&(r)->x, &(pre)[m].x, m == idx_n); \ + secp256k1_fe_cmov(&(r)->y, &(pre)[m].y, m == idx_n); \ + } \ + (r)->infinity = 0; \ + secp256k1_fe_negate(&neg_y, &(r)->y, 1); \ + secp256k1_fe_cmov(&(r)->y, &neg_y, (n) != abs_n); \ +} while(0) + + +/** Convert a number to WNAF notation. + * The number becomes represented by sum(2^{wi} * wnaf[i], i=0..WNAF_SIZE(w)+1) - return_val. + * It has the following guarantees: + * - each wnaf[i] an odd integer between -(1 << w) and (1 << w) + * - each wnaf[i] is nonzero + * - the number of words set is always WNAF_SIZE(w) + 1 + * + * Adapted from `The Width-w NAF Method Provides Small Memory and Fast Elliptic Scalar + * Multiplications Secure against Side Channel Attacks`, Okeya and Tagaki. M. Joye (Ed.) + * CT-RSA 2003, LNCS 2612, pp. 328-443, 2003. Springer-Verlagy Berlin Heidelberg 2003 + * + * Numbers reference steps of `Algorithm SPA-resistant Width-w NAF with Odd Scalar` on pp. 335 + */ +static int secp256k1_wnaf_const(int *wnaf, secp256k1_scalar s, int w) { + int global_sign; + int skew = 0; + int word = 0; + + /* 1 2 3 */ + int u_last; + int u; + + int flip; + int bit; + secp256k1_scalar neg_s; + int not_neg_one; + /* Note that we cannot handle even numbers by negating them to be odd, as is + * done in other implementations, since if our scalars were specified to have + * width < 256 for performance reasons, their negations would have width 256 + * and we'd lose any performance benefit. Instead, we use a technique from + * Section 4.2 of the Okeya/Tagaki paper, which is to add either 1 (for even) + * or 2 (for odd) to the number we are encoding, returning a skew value indicating + * this, and having the caller compensate after doing the multiplication. */ + + /* Negative numbers will be negated to keep their bit representation below the maximum width */ + flip = secp256k1_scalar_is_high(&s); + /* We add 1 to even numbers, 2 to odd ones, noting that negation flips parity */ + bit = flip ^ !secp256k1_scalar_is_even(&s); + /* We check for negative one, since adding 2 to it will cause an overflow */ + secp256k1_scalar_negate(&neg_s, &s); + not_neg_one = !secp256k1_scalar_is_one(&neg_s); + secp256k1_scalar_cadd_bit(&s, bit, not_neg_one); + /* If we had negative one, flip == 1, s.d[0] == 0, bit == 1, so caller expects + * that we added two to it and flipped it. In fact for -1 these operations are + * identical. We only flipped, but since skewing is required (in the sense that + * the skew must be 1 or 2, never zero) and flipping is not, we need to change + * our flags to claim that we only skewed. */ + global_sign = secp256k1_scalar_cond_negate(&s, flip); + global_sign *= not_neg_one * 2 - 1; + skew = 1 << bit; + + /* 4 */ + u_last = secp256k1_scalar_shr_int(&s, w); + while (word * w < WNAF_BITS) { + int sign; + int even; + + /* 4.1 4.4 */ + u = secp256k1_scalar_shr_int(&s, w); + /* 4.2 */ + even = ((u & 1) == 0); + sign = 2 * (u_last > 0) - 1; + u += sign * even; + u_last -= sign * even * (1 << w); + + /* 4.3, adapted for global sign change */ + wnaf[word++] = u_last * global_sign; + + u_last = u; + } + wnaf[word] = u * global_sign; + + VERIFY_CHECK(secp256k1_scalar_is_zero(&s)); + VERIFY_CHECK(word == WNAF_SIZE(w)); + return skew; +} + + +static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) { + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge tmpa; + secp256k1_fe Z; + + int skew_1; + int wnaf_1[1 + WNAF_SIZE(WINDOW_A - 1)]; +#ifdef USE_ENDOMORPHISM + secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + int wnaf_lam[1 + WNAF_SIZE(WINDOW_A - 1)]; + int skew_lam; + secp256k1_scalar q_1, q_lam; +#endif + + int i; + secp256k1_scalar sc = *scalar; + + /* build wnaf representation for q. */ +#ifdef USE_ENDOMORPHISM + /* split q into q_1 and q_lam (where q = q_1 + q_lam*lambda, and q_1 and q_lam are ~128 bit) */ + secp256k1_scalar_split_lambda(&q_1, &q_lam, &sc); + skew_1 = secp256k1_wnaf_const(wnaf_1, q_1, WINDOW_A - 1); + skew_lam = secp256k1_wnaf_const(wnaf_lam, q_lam, WINDOW_A - 1); +#else + skew_1 = secp256k1_wnaf_const(wnaf_1, sc, WINDOW_A - 1); +#endif + + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + */ + secp256k1_gej_set_ge(r, a); + secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, r); + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_fe_normalize_weak(&pre_a[i].y); + } +#ifdef USE_ENDOMORPHISM + for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { + secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); + } +#endif + + /* first loop iteration (separated out so we can directly set r, rather + * than having it start at infinity, get doubled several times, then have + * its new value added to it) */ + i = wnaf_1[WNAF_SIZE(WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, i, WINDOW_A); + secp256k1_gej_set_ge(r, &tmpa); +#ifdef USE_ENDOMORPHISM + i = wnaf_lam[WNAF_SIZE(WINDOW_A - 1)]; + VERIFY_CHECK(i != 0); + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, i, WINDOW_A); + secp256k1_gej_add_ge(r, r, &tmpa); +#endif + /* remaining loop iterations */ + for (i = WNAF_SIZE(WINDOW_A - 1) - 1; i >= 0; i--) { + int n; + int j; + for (j = 0; j < WINDOW_A - 1; ++j) { + secp256k1_gej_double_nonzero(r, r, NULL); + } + + n = wnaf_1[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); +#ifdef USE_ENDOMORPHISM + n = wnaf_lam[i]; + ECMULT_CONST_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); + VERIFY_CHECK(n != 0); + secp256k1_gej_add_ge(r, r, &tmpa); +#endif + } + + secp256k1_fe_mul(&r->z, &r->z, &Z); + + { + /* Correct for wNAF skew */ + secp256k1_ge correction = *a; + secp256k1_ge_storage correction_1_stor; +#ifdef USE_ENDOMORPHISM + secp256k1_ge_storage correction_lam_stor; +#endif + secp256k1_ge_storage a2_stor; + secp256k1_gej tmpj; + secp256k1_gej_set_ge(&tmpj, &correction); + secp256k1_gej_double_var(&tmpj, &tmpj, NULL); + secp256k1_ge_set_gej(&correction, &tmpj); + secp256k1_ge_to_storage(&correction_1_stor, a); +#ifdef USE_ENDOMORPHISM + secp256k1_ge_to_storage(&correction_lam_stor, a); +#endif + secp256k1_ge_to_storage(&a2_stor, &correction); + + /* For odd numbers this is 2a (so replace it), for even ones a (so no-op) */ + secp256k1_ge_storage_cmov(&correction_1_stor, &a2_stor, skew_1 == 2); +#ifdef USE_ENDOMORPHISM + secp256k1_ge_storage_cmov(&correction_lam_stor, &a2_stor, skew_lam == 2); +#endif + + /* Apply the correction */ + secp256k1_ge_from_storage(&correction, &correction_1_stor); + secp256k1_ge_neg(&correction, &correction); + secp256k1_gej_add_ge(r, r, &correction); + +#ifdef USE_ENDOMORPHISM + secp256k1_ge_from_storage(&correction, &correction_lam_stor); + secp256k1_ge_neg(&correction, &correction); + secp256k1_ge_mul_lambda(&correction, &correction); + secp256k1_gej_add_ge(r, r, &correction); +#endif + } +} + +#endif /* SECP256K1_ECMULT_CONST_IMPL_H */ diff --git a/src/secp256k1/src/ecmult_gen.h b/src/secp256k1/src/ecmult_gen.h index 3745633c4..7564b7015 100644 --- a/src/secp256k1/src/ecmult_gen.h +++ b/src/secp256k1/src/ecmult_gen.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECMULT_GEN_ -#define _SECP256K1_ECMULT_GEN_ +#ifndef SECP256K1_ECMULT_GEN_H +#define SECP256K1_ECMULT_GEN_H #include "scalar.h" #include "group.h" @@ -23,21 +23,21 @@ typedef struct { * None of the resulting prec group elements have a known scalar, and neither do any of * the intermediate sums while computing a*G. */ - secp256k1_ge_storage_t (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ - secp256k1_scalar_t blind; - secp256k1_gej_t initial; -} secp256k1_ecmult_gen_context_t; + secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ + secp256k1_scalar blind; + secp256k1_gej initial; +} secp256k1_ecmult_gen_context; -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx); -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx); -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, - const secp256k1_ecmult_gen_context_t* src); -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx); -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx); +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, + const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); /** Multiply with the generator: R = a*G */ -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t* ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *a); +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32); +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); -#endif +#endif /* SECP256K1_ECMULT_GEN_H */ diff --git a/src/secp256k1/src/ecmult_gen_impl.h b/src/secp256k1/src/ecmult_gen_impl.h index 4697753ac..714f02e94 100644 --- a/src/secp256k1/src/ecmult_gen_impl.h +++ b/src/secp256k1/src/ecmult_gen_impl.h @@ -4,29 +4,33 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECMULT_GEN_IMPL_H_ -#define _SECP256K1_ECMULT_GEN_IMPL_H_ +#ifndef SECP256K1_ECMULT_GEN_IMPL_H +#define SECP256K1_ECMULT_GEN_IMPL_H #include "scalar.h" #include "group.h" #include "ecmult_gen.h" #include "hash_impl.h" - -static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) { +#ifdef USE_ECMULT_STATIC_PRECOMPUTATION +#include "ecmult_static_context.h" +#endif +static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context *ctx) { ctx->prec = NULL; } -static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) { - secp256k1_ge_t prec[1024]; - secp256k1_gej_t gj; - secp256k1_gej_t nums_gej; +static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context *ctx, const secp256k1_callback* cb) { +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + secp256k1_ge prec[1024]; + secp256k1_gej gj; + secp256k1_gej nums_gej; int i, j; +#endif if (ctx->prec != NULL) { return; } - - ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec)); +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + ctx->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*ctx->prec)); /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); @@ -34,77 +38,93 @@ static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *c /* Construct a group element with no known corresponding scalar (nothing up my sleeve). */ { static const unsigned char nums_b32[33] = "The scalar for this x is unknown"; - secp256k1_fe_t nums_x; - secp256k1_ge_t nums_ge; - VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32)); - VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0)); + secp256k1_fe nums_x; + secp256k1_ge nums_ge; + int r; + r = secp256k1_fe_set_b32(&nums_x, nums_b32); + (void)r; + VERIFY_CHECK(r); + r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0); + (void)r; + VERIFY_CHECK(r); secp256k1_gej_set_ge(&nums_gej, &nums_ge); /* Add G to make the bits in x uniformly distributed. */ - secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g); + secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, &secp256k1_ge_const_g, NULL); } /* compute prec. */ { - secp256k1_gej_t precj[1024]; /* Jacobian versions of prec. */ - secp256k1_gej_t gbase; - secp256k1_gej_t numsbase; + secp256k1_gej precj[1024]; /* Jacobian versions of prec. */ + secp256k1_gej gbase; + secp256k1_gej numsbase; gbase = gj; /* 16^j * G */ numsbase = nums_gej; /* 2^j * nums. */ for (j = 0; j < 64; j++) { /* Set precj[j*16 .. j*16+15] to (numsbase, numsbase + gbase, ..., numsbase + 15*gbase). */ precj[j*16] = numsbase; for (i = 1; i < 16; i++) { - secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase); + secp256k1_gej_add_var(&precj[j*16 + i], &precj[j*16 + i - 1], &gbase, NULL); } /* Multiply gbase by 16. */ for (i = 0; i < 4; i++) { - secp256k1_gej_double_var(&gbase, &gbase); + secp256k1_gej_double_var(&gbase, &gbase, NULL); } /* Multiply numbase by 2. */ - secp256k1_gej_double_var(&numsbase, &numsbase); + secp256k1_gej_double_var(&numsbase, &numsbase, NULL); if (j == 62) { /* In the last iteration, numsbase is (1 - 2^j) * nums instead. */ secp256k1_gej_neg(&numsbase, &numsbase); - secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej); + secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej, NULL); } } - secp256k1_ge_set_all_gej_var(1024, prec, precj); + secp256k1_ge_set_all_gej_var(prec, precj, 1024, cb); } for (j = 0; j < 64; j++) { for (i = 0; i < 16; i++) { secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]); } } +#else + (void)cb; + ctx->prec = (secp256k1_ge_storage (*)[64][16])secp256k1_ecmult_static_context; +#endif secp256k1_ecmult_gen_blind(ctx, NULL); } -static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx) { +static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx) { return ctx->prec != NULL; } -static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context_t *dst, - const secp256k1_ecmult_gen_context_t *src) { +static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, + const secp256k1_ecmult_gen_context *src, const secp256k1_callback* cb) { if (src->prec == NULL) { dst->prec = NULL; } else { - dst->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*dst->prec)); +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION + dst->prec = (secp256k1_ge_storage (*)[64][16])checked_malloc(cb, sizeof(*dst->prec)); memcpy(dst->prec, src->prec, sizeof(*dst->prec)); +#else + (void)cb; + dst->prec = src->prec; +#endif dst->initial = src->initial; dst->blind = src->blind; } } -static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) { +static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context *ctx) { +#ifndef USE_ECMULT_STATIC_PRECOMPUTATION free(ctx->prec); +#endif secp256k1_scalar_clear(&ctx->blind); secp256k1_gej_clear(&ctx->initial); ctx->prec = NULL; } -static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *gn) { - secp256k1_ge_t add; - secp256k1_ge_storage_t adds; - secp256k1_scalar_t gnb; +static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *gn) { + secp256k1_ge add; + secp256k1_ge_storage adds; + secp256k1_scalar gnb; int bits; int i, j; memset(&adds, 0, sizeof(adds)); @@ -136,14 +156,15 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp } /* Setup blinding values for secp256k1_ecmult_gen. */ -static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, const unsigned char *seed32) { - secp256k1_scalar_t b; - secp256k1_gej_t gb; - secp256k1_fe_t s; +static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32) { + secp256k1_scalar b; + secp256k1_gej gb; + secp256k1_fe s; unsigned char nonce32[32]; - secp256k1_rfc6979_hmac_sha256_t rng; + secp256k1_rfc6979_hmac_sha256 rng; int retry; - if (!seed32) { + unsigned char keydata[64] = {0}; + if (seed32 == NULL) { /* When seed is NULL, reset the initial point and blinding value. */ secp256k1_gej_set_ge(&ctx->initial, &secp256k1_ge_const_g); secp256k1_gej_neg(&ctx->initial, &ctx->initial); @@ -155,13 +176,18 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, cons * and guards against weak or adversarial seeds. This is a simpler and safer interface than * asking the caller for blinding values directly and expecting them to retry on failure. */ - secp256k1_rfc6979_hmac_sha256_initialize(&rng, seed32 ? seed32 : nonce32, 32, nonce32, 32, NULL, 0); + memcpy(keydata, nonce32, 32); + if (seed32 != NULL) { + memcpy(keydata + 32, seed32, 32); + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, seed32 ? 64 : 32); + memset(keydata, 0, sizeof(keydata)); /* Retry for out of range results to achieve uniformity. */ do { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); retry = !secp256k1_fe_set_b32(&s, nonce32); retry |= secp256k1_fe_is_zero(&s); - } while (retry); + } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > Fp. */ /* Randomize the projection to defend against multiplier sidechannels. */ secp256k1_gej_rescale(&ctx->initial, &s); secp256k1_fe_clear(&s); @@ -170,7 +196,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, cons secp256k1_scalar_set_b32(&b, nonce32, &retry); /* A blinding value of 0 works, but would undermine the projection hardening. */ retry |= secp256k1_scalar_is_zero(&b); - } while (retry); + } while (retry); /* This branch true is cryptographically unreachable. Requires sha256_hmac output > order. */ secp256k1_rfc6979_hmac_sha256_finalize(&rng); memset(nonce32, 0, 32); secp256k1_ecmult_gen(ctx, &gb, &b); @@ -181,4 +207,4 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context_t *ctx, cons secp256k1_gej_clear(&gb); } -#endif +#endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/src/secp256k1/src/ecmult_impl.h b/src/secp256k1/src/ecmult_impl.h index 1b2856f83..93d3794cb 100644 --- a/src/secp256k1/src/ecmult_impl.h +++ b/src/secp256k1/src/ecmult_impl.h @@ -4,16 +4,32 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_ECMULT_IMPL_H_ -#define _SECP256K1_ECMULT_IMPL_H_ +#ifndef SECP256K1_ECMULT_IMPL_H +#define SECP256K1_ECMULT_IMPL_H + +#include #include "group.h" #include "scalar.h" #include "ecmult.h" +#if defined(EXHAUSTIVE_TEST_ORDER) +/* We need to lower these values for exhaustive tests because + * the tables cannot have infinities in them (this breaks the + * affine-isomorphism stuff which tracks z-ratios) */ +# if EXHAUSTIVE_TEST_ORDER > 128 +# define WINDOW_A 5 +# define WINDOW_G 8 +# elif EXHAUSTIVE_TEST_ORDER > 8 +# define WINDOW_A 4 +# define WINDOW_G 4 +# else +# define WINDOW_A 2 +# define WINDOW_G 2 +# endif +#else /* optimal for 128-bit and 256-bit exponents. */ #define WINDOW_A 5 - /** larger numbers may result in slightly better performance, at the cost of exponentially larger precomputed tables. */ #ifdef USE_ENDOMORPHISM @@ -23,63 +39,109 @@ /** One table for window size 16: 1.375 MiB. */ #define WINDOW_G 16 #endif - -/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table. - * pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for - * 2^(w-2) entries. - * - * There are two versions of this function: - * - secp256k1_ecmult_precomp_wnaf_gej, which operates on group elements in jacobian notation, - * fast to precompute, but slower to use in later additions. - * - secp256k1_ecmult_precomp_wnaf_ge, which operates on group elements in affine notations, - * (much) slower to precompute, but a bit faster to use in later additions. - * To compute a*P + b*G, we use the jacobian version for P, and the affine version for G, as - * G is constant, so it only needs to be done once in advance. - */ -static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) { - secp256k1_gej_t d; - int i; - pre[0] = *a; - secp256k1_gej_double_var(&d, &pre[0]); - for (i = 1; i < (1 << (w-2)); i++) { - secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]); - } -} - -static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) { - secp256k1_gej_t d; - int i; - const int table_size = 1 << (w-2); - secp256k1_gej_t *prej = (secp256k1_gej_t *)checked_malloc(sizeof(secp256k1_gej_t) * table_size); - secp256k1_ge_t *prea = (secp256k1_ge_t *)checked_malloc(sizeof(secp256k1_ge_t) * table_size); - prej[0] = *a; - secp256k1_gej_double_var(&d, a); - for (i = 1; i < table_size; i++) { - secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]); - } - secp256k1_ge_set_all_gej_var(table_size, prea, prej); - for (i = 0; i < table_size; i++) { - secp256k1_ge_to_storage(&pre[i], &prea[i]); - } - free(prej); - free(prea); -} +#endif /** The number of entries a table with precomputed multiples needs to have. */ #define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) +/** Fill a table 'prej' with precomputed odd multiples of a. Prej will contain + * the values [1*a,3*a,...,(2*n-1)*a], so it space for n values. zr[0] will + * contain prej[0].z / a.z. The other zr[i] values = prej[i].z / prej[i-1].z. + * Prej's Z values are undefined, except for the last value. + */ +static void secp256k1_ecmult_odd_multiples_table(int n, secp256k1_gej *prej, secp256k1_fe *zr, const secp256k1_gej *a) { + secp256k1_gej d; + secp256k1_ge a_ge, d_ge; + int i; + + VERIFY_CHECK(!a->infinity); + + secp256k1_gej_double_var(&d, a, NULL); + + /* + * Perform the additions on an isomorphism where 'd' is affine: drop the z coordinate + * of 'd', and scale the 1P starting value's x/y coordinates without changing its z. + */ + d_ge.x = d.x; + d_ge.y = d.y; + d_ge.infinity = 0; + + secp256k1_ge_set_gej_zinv(&a_ge, a, &d.z); + prej[0].x = a_ge.x; + prej[0].y = a_ge.y; + prej[0].z = a->z; + prej[0].infinity = 0; + + zr[0] = d.z; + for (i = 1; i < n; i++) { + secp256k1_gej_add_ge_var(&prej[i], &prej[i-1], &d_ge, &zr[i]); + } + + /* + * Each point in 'prej' has a z coordinate too small by a factor of 'd.z'. Only + * the final point's z coordinate is actually used though, so just update that. + */ + secp256k1_fe_mul(&prej[n-1].z, &prej[n-1].z, &d.z); +} + +/** Fill a table 'pre' with precomputed odd multiples of a. + * + * There are two versions of this function: + * - secp256k1_ecmult_odd_multiples_table_globalz_windowa which brings its + * resulting point set to a single constant Z denominator, stores the X and Y + * coordinates as ge_storage points in pre, and stores the global Z in rz. + * It only operates on tables sized for WINDOW_A wnaf multiples. + * - secp256k1_ecmult_odd_multiples_table_storage_var, which converts its + * resulting point set to actually affine points, and stores those in pre. + * It operates on tables of any size, but uses heap-allocated temporaries. + * + * To compute a*P + b*G, we compute a table for P using the first function, + * and for G using the second (which requires an inverse, but it only needs to + * happen once). + */ +static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *pre, secp256k1_fe *globalz, const secp256k1_gej *a) { + secp256k1_gej prej[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_fe zr[ECMULT_TABLE_SIZE(WINDOW_A)]; + + /* Compute the odd multiples in Jacobian form. */ + secp256k1_ecmult_odd_multiples_table(ECMULT_TABLE_SIZE(WINDOW_A), prej, zr, a); + /* Bring them to the same Z denominator. */ + secp256k1_ge_globalz_set_table_gej(ECMULT_TABLE_SIZE(WINDOW_A), pre, globalz, prej, zr); +} + +static void secp256k1_ecmult_odd_multiples_table_storage_var(int n, secp256k1_ge_storage *pre, const secp256k1_gej *a, const secp256k1_callback *cb) { + secp256k1_gej *prej = (secp256k1_gej*)checked_malloc(cb, sizeof(secp256k1_gej) * n); + secp256k1_ge *prea = (secp256k1_ge*)checked_malloc(cb, sizeof(secp256k1_ge) * n); + secp256k1_fe *zr = (secp256k1_fe*)checked_malloc(cb, sizeof(secp256k1_fe) * n); + int i; + + /* Compute the odd multiples in Jacobian form. */ + secp256k1_ecmult_odd_multiples_table(n, prej, zr, a); + /* Convert them in batch to affine coordinates. */ + secp256k1_ge_set_table_gej_var(prea, prej, zr, n); + /* Convert them to compact storage form. */ + for (i = 0; i < n; i++) { + secp256k1_ge_to_storage(&pre[i], &prea[i]); + } + + free(prea); + free(prej); + free(zr); +} + /** The following two macro retrieves a particular odd multiple from a table * of precomputed multiples. */ -#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) do { \ +#define ECMULT_TABLE_GET_GE(r,pre,n,w) do { \ VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \ if ((n) > 0) { \ *(r) = (pre)[((n)-1)/2]; \ } else { \ - secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \ + secp256k1_ge_neg((r), &(pre)[(-(n)-1)/2]); \ } \ } while(0) + #define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \ VERIFY_CHECK(((n) & 1) == 1); \ VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \ @@ -92,15 +154,15 @@ static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t } \ } while(0) -static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) { +static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx) { ctx->pre_g = NULL; #ifdef USE_ENDOMORPHISM ctx->pre_g_128 = NULL; #endif } -static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) { - secp256k1_gej_t gj; +static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb) { + secp256k1_gej gj; if (ctx->pre_g != NULL) { return; @@ -109,35 +171,35 @@ static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) { /* get the generator */ secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g); - ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); /* precompute the tables with odd multiples */ - secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g, &gj, WINDOW_G); + secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g, &gj, cb); #ifdef USE_ENDOMORPHISM { - secp256k1_gej_t g_128j; + secp256k1_gej g_128j; int i; - ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); + ctx->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G)); /* calculate 2^128*generator */ g_128j = gj; for (i = 0; i < 128; i++) { - secp256k1_gej_double_var(&g_128j, &g_128j); + secp256k1_gej_double_var(&g_128j, &g_128j, NULL); } - secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g_128, &g_128j, WINDOW_G); + secp256k1_ecmult_odd_multiples_table_storage_var(ECMULT_TABLE_SIZE(WINDOW_G), *ctx->pre_g_128, &g_128j, cb); } #endif } -static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, - const secp256k1_ecmult_context_t *src) { +static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, + const secp256k1_ecmult_context *src, const secp256k1_callback *cb) { if (src->pre_g == NULL) { dst->pre_g = NULL; } else { size_t size = sizeof((*dst->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + dst->pre_g = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); memcpy(dst->pre_g, src->pre_g, size); } #ifdef USE_ENDOMORPHISM @@ -145,17 +207,17 @@ static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context_t *dst, dst->pre_g_128 = NULL; } else { size_t size = sizeof((*dst->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G); - dst->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(size); + dst->pre_g_128 = (secp256k1_ge_storage (*)[])checked_malloc(cb, size); memcpy(dst->pre_g_128, src->pre_g_128, size); } #endif } -static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) { +static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx) { return ctx->pre_g != NULL; } -static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { +static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx) { free(ctx->pre_g); #ifdef USE_ENDOMORPHISM free(ctx->pre_g_128); @@ -168,54 +230,68 @@ static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) * - two non-zero entries in wnaf are separated by at least w-1 zeroes. * - the number of set values in wnaf is returned. This number is at most 256, and at most one more - * - than the number of bits in the (absolute value) of the input. + * than the number of bits in the (absolute value) of the input. */ -static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) { - secp256k1_scalar_t s = *a; - int set_bits = 0; +static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w) { + secp256k1_scalar s = *a; + int last_set_bit = -1; int bit = 0; int sign = 1; + int carry = 0; + + VERIFY_CHECK(wnaf != NULL); + VERIFY_CHECK(0 <= len && len <= 256); + VERIFY_CHECK(a != NULL); + VERIFY_CHECK(2 <= w && w <= 31); + + memset(wnaf, 0, len * sizeof(wnaf[0])); if (secp256k1_scalar_get_bits(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); sign = -1; } - while (bit < 256) { + while (bit < len) { int now; int word; - if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) { + if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { bit++; continue; } - while (set_bits < bit) { - wnaf[set_bits++] = 0; - } + now = w; - if (bit + now > 256) { - now = 256 - bit; - } - word = secp256k1_scalar_get_bits_var(&s, bit, now); - if (word & (1 << (w-1))) { - secp256k1_scalar_add_bit(&s, bit + w); - wnaf[set_bits++] = sign * (word - (1 << w)); - } else { - wnaf[set_bits++] = sign * word; + if (now > len - bit) { + now = len - bit; } + + word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; + + carry = (word >> (w-1)) & 1; + word -= carry << w; + + wnaf[bit] = sign * word; + last_set_bit = bit; + bit += now; } - return set_bits; +#ifdef VERIFY + CHECK(carry == 0); + while (bit < 256) { + CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); + } +#endif + return last_set_bit + 1; } -static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { - secp256k1_gej_t tmpj; - secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_ge_t tmpa; +static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng) { + secp256k1_ge pre_a[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ge tmpa; + secp256k1_fe Z; #ifdef USE_ENDOMORPHISM - secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; - secp256k1_scalar_t na_1, na_lam; + secp256k1_ge pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_scalar na_1, na_lam; /* Splitted G factors. */ - secp256k1_scalar_t ng_1, ng_128; + secp256k1_scalar ng_1, ng_128; int wnaf_na_1[130]; int wnaf_na_lam[130]; int bits_na_1; @@ -227,7 +303,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge #else int wnaf_na[256]; int bits_na; - int wnaf_ng[257]; + int wnaf_ng[256]; int bits_ng; #endif int i; @@ -235,11 +311,11 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge #ifdef USE_ENDOMORPHISM /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ - secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); + secp256k1_scalar_split_lambda(&na_1, &na_lam, na); /* build wnaf representation for na_1 and na_lam. */ - bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); - bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); + bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, 130, &na_1, WINDOW_A); + bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, 130, &na_lam, WINDOW_A); VERIFY_CHECK(bits_na_1 <= 130); VERIFY_CHECK(bits_na_lam <= 130); bits = bits_na_1; @@ -248,24 +324,33 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge } #else /* build wnaf representation for na. */ - bits_na = secp256k1_ecmult_wnaf(wnaf_na, na, WINDOW_A); + bits_na = secp256k1_ecmult_wnaf(wnaf_na, 256, na, WINDOW_A); bits = bits_na; #endif - /* calculate odd multiples of a */ - secp256k1_ecmult_table_precomp_gej_var(pre_a, a, WINDOW_A); + /* Calculate odd multiples of a. + * All multiples are brought to the same Z 'denominator', which is stored + * in Z. Due to secp256k1' isomorphism we can do all operations pretending + * that the Z coordinate was 1, use affine addition formulae, and correct + * the Z coordinate of the result once at the end. + * The exception is the precomputed G table points, which are actually + * affine. Compared to the base used for other points, they have a Z ratio + * of 1/Z, so we can use secp256k1_gej_add_zinv_var, which uses the same + * isomorphism to efficiently add with a known Z inverse. + */ + secp256k1_ecmult_odd_multiples_table_globalz_windowa(pre_a, &Z, a); #ifdef USE_ENDOMORPHISM for (i = 0; i < ECMULT_TABLE_SIZE(WINDOW_A); i++) { - secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]); + secp256k1_ge_mul_lambda(&pre_a_lam[i], &pre_a[i]); } /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ secp256k1_scalar_split_128(&ng_1, &ng_128, ng); /* Build wnaf representation for ng_1 and ng_128 */ - bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); - bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G); + bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, 129, &ng_1, WINDOW_G); + bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); if (bits_ng_1 > bits) { bits = bits_ng_1; } @@ -273,7 +358,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge bits = bits_ng_128; } #else - bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, ng, WINDOW_G); + bits_ng = secp256k1_ecmult_wnaf(wnaf_ng, 256, ng, WINDOW_G); if (bits_ng > bits) { bits = bits_ng; } @@ -281,37 +366,41 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge secp256k1_gej_set_infinity(r); - for (i = bits-1; i >= 0; i--) { + for (i = bits - 1; i >= 0; i--) { int n; - secp256k1_gej_double_var(r, r); + secp256k1_gej_double_var(r, r, NULL); #ifdef USE_ENDOMORPHISM if (i < bits_na_1 && (n = wnaf_na_1[i])) { - ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A); - secp256k1_gej_add_var(r, r, &tmpj); + ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } if (i < bits_na_lam && (n = wnaf_na_lam[i])) { - ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A); - secp256k1_gej_add_var(r, r, &tmpj); + ECMULT_TABLE_GET_GE(&tmpa, pre_a_lam, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } #else if (i < bits_na && (n = wnaf_na[i])) { - ECMULT_TABLE_GET_GEJ(&tmpj, pre_a, n, WINDOW_A); - secp256k1_gej_add_var(r, r, &tmpj); + ECMULT_TABLE_GET_GE(&tmpa, pre_a, n, WINDOW_A); + secp256k1_gej_add_ge_var(r, r, &tmpa, NULL); } if (i < bits_ng && (n = wnaf_ng[i])) { ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G); - secp256k1_gej_add_ge_var(r, r, &tmpa); + secp256k1_gej_add_zinv_var(r, r, &tmpa, &Z); } #endif } + + if (!r->infinity) { + secp256k1_fe_mul(&r->z, &r->z, &Z); + } } -#endif +#endif /* SECP256K1_ECMULT_IMPL_H */ diff --git a/src/secp256k1/src/field.h b/src/secp256k1/src/field.h index 41b280892..bb6692ad5 100644 --- a/src/secp256k1/src/field.h +++ b/src/secp256k1/src/field.h @@ -4,13 +4,13 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_ -#define _SECP256K1_FIELD_ +#ifndef SECP256K1_FIELD_H +#define SECP256K1_FIELD_H /** Field element module. * * Field elements can be represented in several ways, but code accessing - * it (and implementations) need to take certain properaties into account: + * it (and implementations) need to take certain properties into account: * - Each field element can be normalized or not. * - Each field element has a magnitude, which represents how far away * its representation is away from normalization. Normalized elements @@ -30,90 +30,103 @@ #error "Please select field implementation" #endif +#include "util.h" + /** Normalize a field element. */ -static void secp256k1_fe_normalize(secp256k1_fe_t *r); +static void secp256k1_fe_normalize(secp256k1_fe *r); /** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r); +static void secp256k1_fe_normalize_weak(secp256k1_fe *r); /** Normalize a field element, without constant-time guarantee. */ -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r); +static void secp256k1_fe_normalize_var(secp256k1_fe *r); /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r); +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field * implementation may optionally normalize the input, but this should not be relied upon. */ -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r); +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); /** Set a field element equal to a small integer. Resulting field element is normalized. */ -static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a); +static void secp256k1_fe_set_int(secp256k1_fe *r, int a); + +/** Sets a field element equal to zero, initializing all fields. */ +static void secp256k1_fe_clear(secp256k1_fe *a); /** Verify whether a field element is zero. Requires the input to be normalized. */ -static int secp256k1_fe_is_zero(const secp256k1_fe_t *a); +static int secp256k1_fe_is_zero(const secp256k1_fe *a); /** Check the "oddness" of a field element. Requires the input to be normalized. */ -static int secp256k1_fe_is_odd(const secp256k1_fe_t *a); +static int secp256k1_fe_is_odd(const secp256k1_fe *a); /** Compare two field elements. Requires magnitude-1 inputs. */ -static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); +static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); + +/** Same as secp256k1_fe_equal, but may be variable time. */ +static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); /** Compare two field elements. Requires both inputs to be normalized */ -static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); -/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */ -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a); +/** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a); +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input * as an argument. The magnitude of the output is one higher. */ -static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m); +static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that * small integer. */ -static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a); +static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ -static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b); +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. * The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); -/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the - * input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be - * normalized). Return value indicates whether a square root was found. */ -static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); +/** If a has a square root, it is computed in r and 1 is returned. If a does not + * have a square root, the root of its negation is computed and 0 is returned. + * The input's magnitude can be at most 8. The output magnitude is 1 (but not + * guaranteed to be normalized). The result in r will always be a square + * itself. */ +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); + +/** Checks whether a field element is a quadratic residue. */ +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ -static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); /** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ -static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and * outputs must not overlap in memory. */ -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a); +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); /** Convert a field element to the storage type. */ -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*); +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); /** Convert a field element back from the storage type. */ -static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*); +static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag); +static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag); +static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); -#endif +#endif /* SECP256K1_FIELD_H */ diff --git a/src/secp256k1/src/field_10x26.h b/src/secp256k1/src/field_10x26.h index 44bce6525..727c5267f 100644 --- a/src/secp256k1/src/field_10x26.h +++ b/src/secp256k1/src/field_10x26.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_ -#define _SECP256K1_FIELD_REPR_ +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H #include @@ -16,20 +16,20 @@ typedef struct { int magnitude; int normalized; #endif -} secp256k1_fe_t; +} secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ (d0) & 0x3FFFFFFUL, \ - ((d0) >> 26) | ((d1) & 0xFFFFFUL) << 6, \ - ((d1) >> 20) | ((d2) & 0x3FFFUL) << 12, \ - ((d2) >> 14) | ((d3) & 0xFFUL) << 18, \ - ((d3) >> 8) | ((d4) & 0x3) << 24, \ - ((d4) >> 2) & 0x3FFFFFFUL, \ - ((d4) >> 28) | ((d5) & 0x3FFFFFUL) << 4, \ - ((d5) >> 22) | ((d6) & 0xFFFF) << 10, \ - ((d6) >> 16) | ((d7) & 0x3FF) << 16, \ - ((d7) >> 10) \ + (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ + (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ + (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ + (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ + (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ + (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ + (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ + (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ + (((uint32_t)d7) >> 10) \ } #ifdef VERIFY @@ -40,8 +40,9 @@ typedef struct { typedef struct { uint32_t n[8]; -} secp256k1_fe_storage_t; +} secp256k1_fe_storage; #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} +#define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] -#endif +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/src/secp256k1/src/field_10x26_impl.h b/src/secp256k1/src/field_10x26_impl.h index 871b91f91..94f8132fc 100644 --- a/src/secp256k1/src/field_10x26_impl.h +++ b/src/secp256k1/src/field_10x26_impl.h @@ -4,17 +4,15 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ -#define _SECP256K1_FIELD_REPR_IMPL_H_ +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H -#include -#include #include "util.h" #include "num.h" #include "field.h" #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { const uint32_t *d = a->n; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; r &= (d[0] <= 0x3FFFFFFUL * m); @@ -40,13 +38,9 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { } VERIFY_CHECK(r == 1); } -#else -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { - (void)a; -} #endif -static void secp256k1_fe_normalize(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -101,7 +95,7 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -132,7 +126,7 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_var(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -188,7 +182,7 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4], t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9]; @@ -217,7 +211,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; uint32_t z0, z1; uint32_t x; @@ -252,7 +246,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { t9 &= 0x03FFFFFUL; t1 += (x << 6); - t1 += (t0 >> 26); t0 = z0; + t1 += (t0 >> 26); t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL; z0 |= t1; z1 &= t1 ^ 0x40UL; t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; z0 |= t2; z1 &= t2; t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; z0 |= t3; z1 &= t3; @@ -269,7 +263,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0x3FFFFFFUL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; #ifdef VERIFY @@ -279,7 +273,7 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { const uint32_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -288,7 +282,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { return (t[0] | t[1] | t[2] | t[3] | t[4] | t[5] | t[6] | t[7] | t[8] | t[9]) == 0; } -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); @@ -296,7 +290,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { int i; #ifdef VERIFY a->magnitude = 0; @@ -307,7 +301,7 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -326,18 +320,18 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { - int i; - r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; - r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; - for (i=0; i<32; i++) { - int j; - for (j=0; j<4; j++) { - int limb = (8*i+2*j)/26; - int shift = (8*i+2*j)%26; - r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift; - } - } +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { + r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24); + r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22); + r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20); + r->n[3] = (uint32_t)((a[22] >> 6) & 0x3) | ((uint32_t)a[21] << 2) | ((uint32_t)a[20] << 10) | ((uint32_t)a[19] << 18); + r->n[4] = (uint32_t)a[18] | ((uint32_t)a[17] << 8) | ((uint32_t)a[16] << 16) | ((uint32_t)(a[15] & 0x3) << 24); + r->n[5] = (uint32_t)((a[15] >> 2) & 0x3f) | ((uint32_t)a[14] << 6) | ((uint32_t)a[13] << 14) | ((uint32_t)(a[12] & 0xf) << 22); + r->n[6] = (uint32_t)((a[12] >> 4) & 0xf) | ((uint32_t)a[11] << 4) | ((uint32_t)a[10] << 12) | ((uint32_t)(a[9] & 0x3f) << 20); + r->n[7] = (uint32_t)((a[9] >> 6) & 0x3) | ((uint32_t)a[8] << 2) | ((uint32_t)a[7] << 10) | ((uint32_t)a[6] << 18); + r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24); + r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14); + if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) { return 0; } @@ -350,25 +344,46 @@ static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { } /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { - int i; +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - for (i=0; i<32; i++) { - int j; - int c = 0; - for (j=0; j<4; j++) { - int limb = (8*i+2*j)/26; - int shift = (8*i+2*j)%26; - c |= ((a->n[limb] >> shift) & 0x3) << (2 * j); - } - r[31-i] = c; - } + r[0] = (a->n[9] >> 14) & 0xff; + r[1] = (a->n[9] >> 6) & 0xff; + r[2] = ((a->n[9] & 0x3F) << 2) | ((a->n[8] >> 24) & 0x3); + r[3] = (a->n[8] >> 16) & 0xff; + r[4] = (a->n[8] >> 8) & 0xff; + r[5] = a->n[8] & 0xff; + r[6] = (a->n[7] >> 18) & 0xff; + r[7] = (a->n[7] >> 10) & 0xff; + r[8] = (a->n[7] >> 2) & 0xff; + r[9] = ((a->n[7] & 0x3) << 6) | ((a->n[6] >> 20) & 0x3f); + r[10] = (a->n[6] >> 12) & 0xff; + r[11] = (a->n[6] >> 4) & 0xff; + r[12] = ((a->n[6] & 0xf) << 4) | ((a->n[5] >> 22) & 0xf); + r[13] = (a->n[5] >> 14) & 0xff; + r[14] = (a->n[5] >> 6) & 0xff; + r[15] = ((a->n[5] & 0x3f) << 2) | ((a->n[4] >> 24) & 0x3); + r[16] = (a->n[4] >> 16) & 0xff; + r[17] = (a->n[4] >> 8) & 0xff; + r[18] = a->n[4] & 0xff; + r[19] = (a->n[3] >> 18) & 0xff; + r[20] = (a->n[3] >> 10) & 0xff; + r[21] = (a->n[3] >> 2) & 0xff; + r[22] = ((a->n[3] & 0x3) << 6) | ((a->n[2] >> 20) & 0x3f); + r[23] = (a->n[2] >> 12) & 0xff; + r[24] = (a->n[2] >> 4) & 0xff; + r[25] = ((a->n[2] & 0xf) << 4) | ((a->n[1] >> 22) & 0xf); + r[26] = (a->n[1] >> 14) & 0xff; + r[27] = (a->n[1] >> 6) & 0xff; + r[28] = ((a->n[1] & 0x3f) << 2) | ((a->n[0] >> 24) & 0x3); + r[29] = (a->n[0] >> 16) & 0xff; + r[30] = (a->n[0] >> 8) & 0xff; + r[31] = a->n[0] & 0xff; } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= m); secp256k1_fe_verify(a); @@ -390,7 +405,7 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp25 #endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; @@ -408,7 +423,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY secp256k1_fe_verify(a); #endif @@ -429,6 +444,14 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1 #endif } +#if defined(USE_EXTERNAL_ASM) + +/* External assembler implementation */ +void secp256k1_fe_mul_inner(uint32_t *r, const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b); +void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t *a); + +#else + #ifdef VERIFY #define VERIFY_BITS(x, n) VERIFY_CHECK(((x) >> (n)) == 0) #else @@ -1037,9 +1060,9 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint32_t *r, const uint32_t VERIFY_BITS(r[2], 27); /* [r9 r8 r7 r6 r5 r4 r3 r2 r1 r0] = [p18 p17 p16 p15 p14 p13 p12 p11 p10 p9 p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } +#endif - -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); VERIFY_CHECK(b->magnitude <= 8); @@ -1055,7 +1078,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s #endif } -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); @@ -1068,7 +1091,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint32_t mask0, mask1; mask0 = flag + ~((uint32_t)0); mask1 = ~mask0; @@ -1083,12 +1106,14 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1); r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1); #ifdef VERIFY - r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); - r->normalized = (r->normalized & mask0) | (a->normalized & mask1); + if (a->magnitude > r->magnitude) { + r->magnitude = a->magnitude; + } + r->normalized &= a->normalized; #endif } -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint32_t mask0, mask1; mask0 = flag + ~((uint32_t)0); mask1 = ~mask0; @@ -1102,7 +1127,7 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); #endif @@ -1116,7 +1141,7 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_f r->n[7] = a->n[8] >> 16 | a->n[9] << 10; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0x3FFFFFFUL; r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL); r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL); @@ -1133,4 +1158,4 @@ static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const #endif } -#endif +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/src/secp256k1/src/field_5x52.h b/src/secp256k1/src/field_5x52.h index 4513d36f4..bccd8feb4 100644 --- a/src/secp256k1/src/field_5x52.h +++ b/src/secp256k1/src/field_5x52.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_ -#define _SECP256K1_FIELD_REPR_ +#ifndef SECP256K1_FIELD_REPR_H +#define SECP256K1_FIELD_REPR_H #include @@ -16,15 +16,15 @@ typedef struct { int magnitude; int normalized; #endif -} secp256k1_fe_t; +} secp256k1_fe; /* Unpacks a constant into a overlapping multi-limbed FE element. */ #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ - (d0) | ((uint64_t)(d1) & 0xFFFFFUL) << 32, \ - ((d1) >> 20) | ((uint64_t)(d2)) << 12 | ((uint64_t)(d3) & 0xFFUL) << 44, \ - ((d3) >> 8) | ((uint64_t)(d4) & 0xFFFFFFFUL) << 24, \ - ((d4) >> 28) | ((uint64_t)(d5)) << 4 | ((uint64_t)(d6) & 0xFFFFUL) << 36, \ - ((d6) >> 16) | ((uint64_t)(d7)) << 16 \ + (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ + ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ + ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ + ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ + ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ } #ifdef VERIFY @@ -35,13 +35,13 @@ typedef struct { typedef struct { uint64_t n[4]; -} secp256k1_fe_storage_t; +} secp256k1_fe_storage; #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ - (d0) | ((uint64_t)(d1)) << 32, \ - (d2) | ((uint64_t)(d3)) << 32, \ - (d4) | ((uint64_t)(d5)) << 32, \ - (d6) | ((uint64_t)(d7)) << 32 \ + (d0) | (((uint64_t)(d1)) << 32), \ + (d2) | (((uint64_t)(d3)) << 32), \ + (d4) | (((uint64_t)(d5)) << 32), \ + (d6) | (((uint64_t)(d7)) << 32) \ }} -#endif +#endif /* SECP256K1_FIELD_REPR_H */ diff --git a/src/secp256k1/src/field_5x52_asm_impl.h b/src/secp256k1/src/field_5x52_asm_impl.h index 98cc004bf..1fc3171f6 100644 --- a/src/secp256k1/src/field_5x52_asm_impl.h +++ b/src/secp256k1/src/field_5x52_asm_impl.h @@ -11,8 +11,8 @@ * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly */ -#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ -#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ +#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H +#define SECP256K1_FIELD_INNER5X52_IMPL_H SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) { /** @@ -499,4 +499,4 @@ __asm__ __volatile__( ); } -#endif +#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/src/secp256k1/src/field_5x52_impl.h b/src/secp256k1/src/field_5x52_impl.h index bda4c3dfc..957c61b01 100644 --- a/src/secp256k1/src/field_5x52_impl.h +++ b/src/secp256k1/src/field_5x52_impl.h @@ -4,14 +4,13 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_REPR_IMPL_H_ -#define _SECP256K1_FIELD_REPR_IMPL_H_ +#ifndef SECP256K1_FIELD_REPR_IMPL_H +#define SECP256K1_FIELD_REPR_IMPL_H #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" #endif -#include #include "util.h" #include "num.h" #include "field.h" @@ -31,7 +30,7 @@ */ #ifdef VERIFY -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { +static void secp256k1_fe_verify(const secp256k1_fe *a) { const uint64_t *d = a->n; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1; /* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ @@ -50,13 +49,9 @@ static void secp256k1_fe_verify(const secp256k1_fe_t *a) { } VERIFY_CHECK(r == 1); } -#else -static void secp256k1_fe_verify(const secp256k1_fe_t *a) { - (void)a; -} #endif -static void secp256k1_fe_normalize(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -99,7 +94,7 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_weak(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -123,7 +118,7 @@ static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) { #endif } -static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { +static void secp256k1_fe_normalize_var(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* Reduce t4 at the start so there will be at most a single carry from the first pass */ @@ -167,7 +162,7 @@ static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) { #endif } -static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r) { uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4]; /* z0 tracks a possible raw value of 0, z1 tracks a possible raw value of P */ @@ -190,7 +185,7 @@ static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { +static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r) { uint64_t t0, t1, t2, t3, t4; uint64_t z0, z1; uint64_t x; @@ -219,7 +214,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { t4 &= 0x0FFFFFFFFFFFFULL; - t1 += (t0 >> 52); t0 = z0; + t1 += (t0 >> 52); t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; z0 |= t1; z1 &= t1; t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; z0 |= t2; z1 &= t2; t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; z0 |= t3; z1 &= t3; @@ -231,7 +226,7 @@ static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r) { return (z0 == 0) | (z1 == 0xFFFFFFFFFFFFFULL); } -SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe *r, int a) { r->n[0] = a; r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; #ifdef VERIFY @@ -241,7 +236,7 @@ SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe *a) { const uint64_t *t = a->n; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -250,7 +245,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) { return (t[0] | t[1] | t[2] | t[3] | t[4]) == 0; } -SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { +SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); @@ -258,7 +253,7 @@ SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) { return a->n[0] & 1; } -SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe *a) { int i; #ifdef VERIFY a->magnitude = 0; @@ -269,7 +264,7 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) { } } -static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { +static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) { int i; #ifdef VERIFY VERIFY_CHECK(a->normalized); @@ -288,17 +283,41 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b return 0; } -static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { - int i; - r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; - for (i=0; i<32; i++) { - int j; - for (j=0; j<2; j++) { - int limb = (8*i+4*j)/52; - int shift = (8*i+4*j)%52; - r->n[limb] |= (uint64_t)((a[31-i] >> (4*j)) & 0xF) << shift; - } - } +static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) { + r->n[0] = (uint64_t)a[31] + | ((uint64_t)a[30] << 8) + | ((uint64_t)a[29] << 16) + | ((uint64_t)a[28] << 24) + | ((uint64_t)a[27] << 32) + | ((uint64_t)a[26] << 40) + | ((uint64_t)(a[25] & 0xF) << 48); + r->n[1] = (uint64_t)((a[25] >> 4) & 0xF) + | ((uint64_t)a[24] << 4) + | ((uint64_t)a[23] << 12) + | ((uint64_t)a[22] << 20) + | ((uint64_t)a[21] << 28) + | ((uint64_t)a[20] << 36) + | ((uint64_t)a[19] << 44); + r->n[2] = (uint64_t)a[18] + | ((uint64_t)a[17] << 8) + | ((uint64_t)a[16] << 16) + | ((uint64_t)a[15] << 24) + | ((uint64_t)a[14] << 32) + | ((uint64_t)a[13] << 40) + | ((uint64_t)(a[12] & 0xF) << 48); + r->n[3] = (uint64_t)((a[12] >> 4) & 0xF) + | ((uint64_t)a[11] << 4) + | ((uint64_t)a[10] << 12) + | ((uint64_t)a[9] << 20) + | ((uint64_t)a[8] << 28) + | ((uint64_t)a[7] << 36) + | ((uint64_t)a[6] << 44); + r->n[4] = (uint64_t)a[5] + | ((uint64_t)a[4] << 8) + | ((uint64_t)a[3] << 16) + | ((uint64_t)a[2] << 24) + | ((uint64_t)a[1] << 32) + | ((uint64_t)a[0] << 40); if (r->n[4] == 0x0FFFFFFFFFFFFULL && (r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL && r->n[0] >= 0xFFFFEFFFFFC2FULL) { return 0; } @@ -311,25 +330,46 @@ static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { } /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ -static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { - int i; +static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); secp256k1_fe_verify(a); #endif - for (i=0; i<32; i++) { - int j; - int c = 0; - for (j=0; j<2; j++) { - int limb = (8*i+4*j)/52; - int shift = (8*i+4*j)%52; - c |= ((a->n[limb] >> shift) & 0xF) << (4 * j); - } - r[31-i] = c; - } + r[0] = (a->n[4] >> 40) & 0xFF; + r[1] = (a->n[4] >> 32) & 0xFF; + r[2] = (a->n[4] >> 24) & 0xFF; + r[3] = (a->n[4] >> 16) & 0xFF; + r[4] = (a->n[4] >> 8) & 0xFF; + r[5] = a->n[4] & 0xFF; + r[6] = (a->n[3] >> 44) & 0xFF; + r[7] = (a->n[3] >> 36) & 0xFF; + r[8] = (a->n[3] >> 28) & 0xFF; + r[9] = (a->n[3] >> 20) & 0xFF; + r[10] = (a->n[3] >> 12) & 0xFF; + r[11] = (a->n[3] >> 4) & 0xFF; + r[12] = ((a->n[2] >> 48) & 0xF) | ((a->n[3] & 0xF) << 4); + r[13] = (a->n[2] >> 40) & 0xFF; + r[14] = (a->n[2] >> 32) & 0xFF; + r[15] = (a->n[2] >> 24) & 0xFF; + r[16] = (a->n[2] >> 16) & 0xFF; + r[17] = (a->n[2] >> 8) & 0xFF; + r[18] = a->n[2] & 0xFF; + r[19] = (a->n[1] >> 44) & 0xFF; + r[20] = (a->n[1] >> 36) & 0xFF; + r[21] = (a->n[1] >> 28) & 0xFF; + r[22] = (a->n[1] >> 20) & 0xFF; + r[23] = (a->n[1] >> 12) & 0xFF; + r[24] = (a->n[1] >> 4) & 0xFF; + r[25] = ((a->n[0] >> 48) & 0xF) | ((a->n[1] & 0xF) << 4); + r[26] = (a->n[0] >> 40) & 0xFF; + r[27] = (a->n[0] >> 32) & 0xFF; + r[28] = (a->n[0] >> 24) & 0xFF; + r[29] = (a->n[0] >> 16) & 0xFF; + r[30] = (a->n[0] >> 8) & 0xFF; + r[31] = a->n[0] & 0xFF; } -SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { +SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= m); secp256k1_fe_verify(a); @@ -346,7 +386,7 @@ SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp25 #endif } -SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { +SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe *r, int a) { r->n[0] *= a; r->n[1] *= a; r->n[2] *= a; @@ -359,7 +399,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { #endif } -SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY secp256k1_fe_verify(a); #endif @@ -375,7 +415,7 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1 #endif } -static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) { +static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); VERIFY_CHECK(b->magnitude <= 8); @@ -391,7 +431,7 @@ static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const s #endif } -static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->magnitude <= 8); secp256k1_fe_verify(a); @@ -404,7 +444,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { #endif } -static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { uint64_t mask0, mask1; mask0 = flag + ~((uint64_t)0); mask1 = ~mask0; @@ -414,12 +454,14 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1); #ifdef VERIFY - r->magnitude = (r->magnitude & mask0) | (a->magnitude & mask1); - r->normalized = (r->normalized & mask0) | (a->normalized & mask1); + if (a->magnitude > r->magnitude) { + r->magnitude = a->magnitude; + } + r->normalized &= a->normalized; #endif } -static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { uint64_t mask0, mask1; mask0 = flag + ~((uint64_t)0); mask1 = ~mask0; @@ -429,7 +471,7 @@ static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1); } -static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) { #ifdef VERIFY VERIFY_CHECK(a->normalized); #endif @@ -439,7 +481,7 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_f r->n[3] = a->n[3] >> 36 | a->n[4] << 16; } -static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) { +static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a) { r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL; r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL); r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL); @@ -451,4 +493,4 @@ static SECP256K1_INLINE void secp256k1_fe_from_storage(secp256k1_fe_t *r, const #endif } -#endif +#endif /* SECP256K1_FIELD_REPR_IMPL_H */ diff --git a/src/secp256k1/src/field_5x52_int128_impl.h b/src/secp256k1/src/field_5x52_int128_impl.h index 9280bb5ea..95a0d1791 100644 --- a/src/secp256k1/src/field_5x52_int128_impl.h +++ b/src/secp256k1/src/field_5x52_int128_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_ -#define _SECP256K1_FIELD_INNER5X52_IMPL_H_ +#ifndef SECP256K1_FIELD_INNER5X52_IMPL_H +#define SECP256K1_FIELD_INNER5X52_IMPL_H #include @@ -137,7 +137,7 @@ SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t VERIFY_BITS(r[2], 52); VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; @@ -259,7 +259,7 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t VERIFY_BITS(c, 63); /* [d 0 0 0 t4 t3+c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ - c += d * R + t3;; + c += d * R + t3; VERIFY_BITS(c, 100); /* [t4 c r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ r[3] = c & M; c >>= 52; @@ -274,4 +274,4 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t /* [r4 r3 r2 r1 r0] = [p8 p7 p6 p5 p4 p3 p2 p1 p0] */ } -#endif +#endif /* SECP256K1_FIELD_INNER5X52_IMPL_H */ diff --git a/src/secp256k1/src/field_impl.h b/src/secp256k1/src/field_impl.h index e6ec11e8f..20428648a 100644 --- a/src/secp256k1/src/field_impl.h +++ b/src/secp256k1/src/field_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_FIELD_IMPL_H_ -#define _SECP256K1_FIELD_IMPL_H_ +#ifndef SECP256K1_FIELD_IMPL_H +#define SECP256K1_FIELD_IMPL_H #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" @@ -21,15 +21,31 @@ #error "Please select field implementation" #endif -SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - secp256k1_fe_t na; +SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; + secp256k1_fe_negate(&na, a, 1); + secp256k1_fe_add(&na, b); + return secp256k1_fe_normalizes_to_zero(&na); +} + +SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe na; secp256k1_fe_negate(&na, a, 1); secp256k1_fe_add(&na, b); return secp256k1_fe_normalizes_to_zero_var(&na); } -static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; +static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a) { + /** Given that p is congruent to 3 mod 4, we can compute the square root of + * a mod p as the (p+1)/4'th power of a. + * + * As (p+1)/4 is an even number, it will have the same result for a and for + * (-a). Only one of these two numbers actually has a square root however, + * so we test at the end by squaring and comparing to the input. + * Also because (p+1)/4 is an even number, the computed square root is + * itself always a square (a ** ((p+1)/4) is the square of a ** ((p+1)/8)). + */ + secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in @@ -114,11 +130,11 @@ static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { /* Check that a square root was actually calculated */ secp256k1_fe_sqr(&t1, r); - return secp256k1_fe_equal_var(&t1, a); + return secp256k1_fe_equal(&t1, a); } -static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; +static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a) { + secp256k1_fe x2, x3, x6, x9, x11, x22, x44, x88, x176, x220, x223, t1; int j; /** The binary representation of (p - 2) has 5 blocks of 1s, with lengths in @@ -207,11 +223,15 @@ static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) { secp256k1_fe_mul(r, a, &t1); } -static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { +static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a) { #if defined(USE_FIELD_INV_BUILTIN) secp256k1_fe_inv(r, a); #elif defined(USE_FIELD_INV_NUM) - secp256k1_num_t n, m; + secp256k1_num n, m; + static const secp256k1_fe negone = SECP256K1_FE_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0xFFFFFC2EUL + ); /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ static const unsigned char prime[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, @@ -220,21 +240,28 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) { 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F }; unsigned char b[32]; - secp256k1_fe_t c = *a; + int res; + secp256k1_fe c = *a; secp256k1_fe_normalize_var(&c); secp256k1_fe_get_b32(b, &c); secp256k1_num_set_bin(&n, b, 32); secp256k1_num_set_bin(&m, prime, 32); secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); - VERIFY_CHECK(secp256k1_fe_set_b32(r, b)); + res = secp256k1_fe_set_b32(r, b); + (void)res; + VERIFY_CHECK(res); + /* Verify the result is the (unique) valid inverse using non-GMP code. */ + secp256k1_fe_mul(&c, &c, r); + secp256k1_fe_add(&c, &negone); + CHECK(secp256k1_fe_normalizes_to_zero_var(&c)); #else #error "Please select field inverse implementation" #endif } -static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) { - secp256k1_fe_t u; +static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len) { + secp256k1_fe u; size_t i; if (len < 1) { return; @@ -252,7 +279,7 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp25 secp256k1_fe_inv_var(&u, &r[--i]); while (i > 0) { - int j = i--; + size_t j = i--; secp256k1_fe_mul(&r[j], &r[i], &u); secp256k1_fe_mul(&u, &u, &a[j]); } @@ -260,4 +287,29 @@ static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp25 r[0] = u; } +static int secp256k1_fe_is_quad_var(const secp256k1_fe *a) { +#ifndef USE_NUM_NONE + unsigned char b[32]; + secp256k1_num n; + secp256k1_num m; + /* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ + static const unsigned char prime[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F + }; + + secp256k1_fe c = *a; + secp256k1_fe_normalize_var(&c); + secp256k1_fe_get_b32(b, &c); + secp256k1_num_set_bin(&n, b, 32); + secp256k1_num_set_bin(&m, prime, 32); + return secp256k1_num_jacobi(&n, &m) >= 0; +#else + secp256k1_fe r; + return secp256k1_fe_sqrt(&r, a); #endif +} + +#endif /* SECP256K1_FIELD_IMPL_H */ diff --git a/src/secp256k1/src/gen_context.c b/src/secp256k1/src/gen_context.c new file mode 100644 index 000000000..1835fd491 --- /dev/null +++ b/src/secp256k1/src/gen_context.c @@ -0,0 +1,74 @@ +/********************************************************************** + * Copyright (c) 2013, 2014, 2015 Thomas Daede, Cory Fields * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#define USE_BASIC_CONFIG 1 + +#include "basic-config.h" +#include "include/secp256k1.h" +#include "field_impl.h" +#include "scalar_impl.h" +#include "group_impl.h" +#include "ecmult_gen_impl.h" + +static void default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} + +static const secp256k1_callback default_error_callback = { + default_error_callback_fn, + NULL +}; + +int main(int argc, char **argv) { + secp256k1_ecmult_gen_context ctx; + int inner; + int outer; + FILE* fp; + + (void)argc; + (void)argv; + + fp = fopen("src/ecmult_static_context.h","w"); + if (fp == NULL) { + fprintf(stderr, "Could not open src/ecmult_static_context.h for writing!\n"); + return -1; + } + + fprintf(fp, "#ifndef _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); + fprintf(fp, "#define _SECP256K1_ECMULT_STATIC_CONTEXT_\n"); + fprintf(fp, "#include \"group.h\"\n"); + fprintf(fp, "#define SC SECP256K1_GE_STORAGE_CONST\n"); + fprintf(fp, "static const secp256k1_ge_storage secp256k1_ecmult_static_context[64][16] = {\n"); + + secp256k1_ecmult_gen_context_init(&ctx); + secp256k1_ecmult_gen_context_build(&ctx, &default_error_callback); + for(outer = 0; outer != 64; outer++) { + fprintf(fp,"{\n"); + for(inner = 0; inner != 16; inner++) { + fprintf(fp," SC(%uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu, %uu)", SECP256K1_GE_STORAGE_CONST_GET((*ctx.prec)[outer][inner])); + if (inner != 15) { + fprintf(fp,",\n"); + } else { + fprintf(fp,"\n"); + } + } + if (outer != 63) { + fprintf(fp,"},\n"); + } else { + fprintf(fp,"}\n"); + } + } + fprintf(fp,"};\n"); + secp256k1_ecmult_gen_context_clear(&ctx); + + fprintf(fp, "#undef SC\n"); + fprintf(fp, "#endif\n"); + fclose(fp); + + return 0; +} diff --git a/src/secp256k1/src/group.h b/src/secp256k1/src/group.h index 0b08b3b99..ea1302deb 100644 --- a/src/secp256k1/src/group.h +++ b/src/secp256k1/src/group.h @@ -4,118 +4,141 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_GROUP_ -#define _SECP256K1_GROUP_ +#ifndef SECP256K1_GROUP_H +#define SECP256K1_GROUP_H #include "num.h" #include "field.h" /** A group element of the secp256k1 curve, in affine coordinates. */ typedef struct { - secp256k1_fe_t x; - secp256k1_fe_t y; + secp256k1_fe x; + secp256k1_fe y; int infinity; /* whether this represents the point at infinity */ -} secp256k1_ge_t; +} secp256k1_ge; #define SECP256K1_GE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), 0} #define SECP256K1_GE_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} /** A group element of the secp256k1 curve, in jacobian coordinates. */ typedef struct { - secp256k1_fe_t x; /* actual X: x/z^2 */ - secp256k1_fe_t y; /* actual Y: y/z^3 */ - secp256k1_fe_t z; + secp256k1_fe x; /* actual X: x/z^2 */ + secp256k1_fe y; /* actual Y: y/z^3 */ + secp256k1_fe z; int infinity; /* whether this represents the point at infinity */ -} secp256k1_gej_t; +} secp256k1_gej; #define SECP256K1_GEJ_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_CONST((i),(j),(k),(l),(m),(n),(o),(p)), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1), 0} #define SECP256K1_GEJ_CONST_INFINITY {SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 0), 1} typedef struct { - secp256k1_fe_storage_t x; - secp256k1_fe_storage_t y; -} secp256k1_ge_storage_t; + secp256k1_fe_storage x; + secp256k1_fe_storage y; +} secp256k1_ge_storage; #define SECP256K1_GE_STORAGE_CONST(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {SECP256K1_FE_STORAGE_CONST((a),(b),(c),(d),(e),(f),(g),(h)), SECP256K1_FE_STORAGE_CONST((i),(j),(k),(l),(m),(n),(o),(p))} -/** Set a group element equal to the point at infinity */ -static void secp256k1_ge_set_infinity(secp256k1_ge_t *r); +#define SECP256K1_GE_STORAGE_CONST_GET(t) SECP256K1_FE_STORAGE_CONST_GET(t.x), SECP256K1_FE_STORAGE_CONST_GET(t.y) /** Set a group element equal to the point with given X and Y coordinates */ -static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y); +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y); + +/** Set a group element (affine) equal to the point with the given X coordinate + * and a Y coordinate that is a quadratic residue modulo p. The return value + * is true iff a coordinate with the given X coordinate exists. + */ +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x); /** Set a group element (affine) equal to the point with the given X coordinate, and given oddness * for Y. Return value indicates whether the result is valid. */ -static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd); +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd); /** Check whether a group element is the point at infinity. */ -static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a); +static int secp256k1_ge_is_infinity(const secp256k1_ge *a); /** Check whether a group element is valid (i.e., on the curve). */ -static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a); +static int secp256k1_ge_is_valid_var(const secp256k1_ge *a); -static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a); +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a); /** Set a group element equal to another which is given in jacobian coordinates */ -static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a); +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a); /** Set a batch of group elements equal to the inputs given in jacobian coordinates */ -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a); +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb); +/** Set a batch of group elements equal to the inputs given in jacobian + * coordinates (with known z-ratios). zr must contain the known z-ratios such + * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. */ +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len); + +/** Bring a batch inputs given in jacobian coordinates (with known z-ratios) to + * the same global z "denominator". zr must contain the known z-ratios such + * that mul(a[i].z, zr[i+1]) == a[i+1].z. zr[0] is ignored. The x and y + * coordinates of the result are stored in r, the common z coordinate is + * stored in globalz. */ +static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr); /** Set a group element (jacobian) equal to the point at infinity. */ -static void secp256k1_gej_set_infinity(secp256k1_gej_t *r); - -/** Set a group element (jacobian) equal to the point with given X and Y coordinates. */ -static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y); +static void secp256k1_gej_set_infinity(secp256k1_gej *r); /** Set a group element (jacobian) equal to another which is given in affine coordinates. */ -static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a); +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a); /** Compare the X coordinate of a group element (jacobian). */ -static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a); +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a); /** Set r equal to the inverse of a (i.e., mirrored around the X axis) */ -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a); +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a); /** Check whether a group element is the point at infinity. */ -static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a); +static int secp256k1_gej_is_infinity(const secp256k1_gej *a); -/** Set r equal to the double of a. */ -static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a); +/** Check whether a group element's y coordinate is a quadratic residue. */ +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a); -/** Set r equal to the sum of a and b. */ -static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b); +/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). + * a may not be zero. Constant time. */ +static void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); + +/** Set r equal to the double of a. If rzr is not-NULL, r->z = a->z * *rzr (where infinity means an implicit z = 0). */ +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr); /** Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity). */ -static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b); /** Set r equal to the sum of a and b (with b given in affine coordinates). This is more efficient than secp256k1_gej_add_var. It is identical to secp256k1_gej_add_ge but without constant-time - guarantee, and b is allowed to be infinity. */ -static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b); + guarantee, and b is allowed to be infinity. If rzr is non-NULL, r->z = a->z * *rzr (a cannot be infinity in that case). */ +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr); + +/** Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv). */ +static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv); #ifdef USE_ENDOMORPHISM /** Set r to be equal to lambda times a, where lambda is chosen in a way such that this is very fast. */ -static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a); +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a); #endif -/** Clear a secp256k1_gej_t to prevent leaking sensitive information. */ -static void secp256k1_gej_clear(secp256k1_gej_t *r); +/** Clear a secp256k1_gej to prevent leaking sensitive information. */ +static void secp256k1_gej_clear(secp256k1_gej *r); -/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */ -static void secp256k1_ge_clear(secp256k1_ge_t *r); +/** Clear a secp256k1_ge to prevent leaking sensitive information. */ +static void secp256k1_ge_clear(secp256k1_ge *r); /** Convert a group element to the storage type. */ -static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*); +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a); /** Convert a group element back from the storage type. */ -static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*); +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a); /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ -static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag); +static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag); /** Rescale a jacobian point by b which must be non-zero. Constant-time. */ -static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *b); +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b); -#endif +#endif /* SECP256K1_GROUP_H */ diff --git a/src/secp256k1/src/group_impl.h b/src/secp256k1/src/group_impl.h index 0f64576fb..b31b6c12e 100644 --- a/src/secp256k1/src/group_impl.h +++ b/src/secp256k1/src/group_impl.h @@ -4,47 +4,101 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_GROUP_IMPL_H_ -#define _SECP256K1_GROUP_IMPL_H_ - -#include +#ifndef SECP256K1_GROUP_IMPL_H +#define SECP256K1_GROUP_IMPL_H #include "num.h" #include "field.h" #include "group.h" +/* These points can be generated in sage as follows: + * + * 0. Setup a worksheet with the following parameters. + * b = 4 # whatever CURVE_B will be set to + * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + * C = EllipticCurve ([F (0), F (b)]) + * + * 1. Determine all the small orders available to you. (If there are + * no satisfactory ones, go back and change b.) + * print C.order().factor(limit=1000) + * + * 2. Choose an order as one of the prime factors listed in the above step. + * (You can also multiply some to get a composite order, though the + * tests will crash trying to invert scalars during signing.) We take a + * random point and scale it to drop its order to the desired value. + * There is some probability this won't work; just try again. + * order = 199 + * P = C.random_point() + * P = (int(P.order()) / int(order)) * P + * assert(P.order() == order) + * + * 3. Print the values. You'll need to use a vim macro or something to + * split the hex output into 4-byte chunks. + * print "%x %x" % P.xy() + */ +#if defined(EXHAUSTIVE_TEST_ORDER) +# if EXHAUSTIVE_TEST_ORDER == 199 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, + 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, + 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, + 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED +); + +const int CURVE_B = 4; +# elif EXHAUSTIVE_TEST_ORDER == 13 +const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( + 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, + 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, + 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, + 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac +); +const int CURVE_B = 2; +# else +# error No known generator for the specified exhaustive test group order. +# endif +#else /** Generator for secp256k1, value 'g' defined in * "Standards for Efficient Cryptography" (SEC2) 2.7.1. */ -static const secp256k1_ge_t secp256k1_ge_const_g = SECP256K1_GE_CONST( +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( 0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL, 0x029BFCDBUL, 0x2DCE28D9UL, 0x59F2815BUL, 0x16F81798UL, 0x483ADA77UL, 0x26A3C465UL, 0x5DA4FBFCUL, 0x0E1108A8UL, 0xFD17B448UL, 0xA6855419UL, 0x9C47D08FUL, 0xFB10D4B8UL ); -static void secp256k1_ge_set_infinity(secp256k1_ge_t *r) { - r->infinity = 1; +const int CURVE_B = 7; +#endif + +static void secp256k1_ge_set_gej_zinv(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zi) { + secp256k1_fe zi2; + secp256k1_fe zi3; + secp256k1_fe_sqr(&zi2, zi); + secp256k1_fe_mul(&zi3, &zi2, zi); + secp256k1_fe_mul(&r->x, &a->x, &zi2); + secp256k1_fe_mul(&r->y, &a->y, &zi3); + r->infinity = a->infinity; } -static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { +static void secp256k1_ge_set_xy(secp256k1_ge *r, const secp256k1_fe *x, const secp256k1_fe *y) { r->infinity = 0; r->x = *x; r->y = *y; } -static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { +static int secp256k1_ge_is_infinity(const secp256k1_ge *a) { return a->infinity; } -static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { +static void secp256k1_ge_neg(secp256k1_ge *r, const secp256k1_ge *a) { *r = *a; secp256k1_fe_normalize_weak(&r->y); secp256k1_fe_negate(&r->y, &r->y, 1); } -static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { - secp256k1_fe_t z2, z3; +static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; r->infinity = a->infinity; secp256k1_fe_inv(&a->z, &a->z); secp256k1_fe_sqr(&z2, &a->z); @@ -56,8 +110,8 @@ static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { r->y = a->y; } -static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { - secp256k1_fe_t z2, z3; +static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) { + secp256k1_fe z2, z3; r->infinity = a->infinity; if (a->infinity) { return; @@ -72,73 +126,106 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) { r->y = a->y; } -static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) { - secp256k1_fe_t *az; - secp256k1_fe_t *azi; +static void secp256k1_ge_set_all_gej_var(secp256k1_ge *r, const secp256k1_gej *a, size_t len, const secp256k1_callback *cb) { + secp256k1_fe *az; + secp256k1_fe *azi; size_t i; size_t count = 0; - az = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * len); + az = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * len); for (i = 0; i < len; i++) { if (!a[i].infinity) { az[count++] = a[i].z; } } - azi = (secp256k1_fe_t *)checked_malloc(sizeof(secp256k1_fe_t) * count); - secp256k1_fe_inv_all_var(count, azi, az); + azi = (secp256k1_fe *)checked_malloc(cb, sizeof(secp256k1_fe) * count); + secp256k1_fe_inv_all_var(azi, az, count); free(az); count = 0; for (i = 0; i < len; i++) { r[i].infinity = a[i].infinity; if (!a[i].infinity) { - secp256k1_fe_t zi2, zi3; - secp256k1_fe_t *zi = &azi[count++]; - secp256k1_fe_sqr(&zi2, zi); - secp256k1_fe_mul(&zi3, &zi2, zi); - secp256k1_fe_mul(&r[i].x, &a[i].x, &zi2); - secp256k1_fe_mul(&r[i].y, &a[i].y, &zi3); + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &azi[count++]); } } free(azi); } -static void secp256k1_gej_set_infinity(secp256k1_gej_t *r) { +static void secp256k1_ge_set_table_gej_var(secp256k1_ge *r, const secp256k1_gej *a, const secp256k1_fe *zr, size_t len) { + size_t i = len - 1; + secp256k1_fe zi; + + if (len > 0) { + /* Compute the inverse of the last z coordinate, and use it to compute the last affine output. */ + secp256k1_fe_inv(&zi, &a[i].z); + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); + + /* Work out way backwards, using the z-ratios to scale the x/y values. */ + while (i > 0) { + secp256k1_fe_mul(&zi, &zi, &zr[i]); + i--; + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zi); + } + } +} + +static void secp256k1_ge_globalz_set_table_gej(size_t len, secp256k1_ge *r, secp256k1_fe *globalz, const secp256k1_gej *a, const secp256k1_fe *zr) { + size_t i = len - 1; + secp256k1_fe zs; + + if (len > 0) { + /* The z of the final point gives us the "global Z" for the table. */ + r[i].x = a[i].x; + r[i].y = a[i].y; + *globalz = a[i].z; + r[i].infinity = 0; + zs = zr[i]; + + /* Work our way backwards, using the z-ratios to scale the x/y values. */ + while (i > 0) { + if (i != len - 1) { + secp256k1_fe_mul(&zs, &zs, &zr[i]); + } + i--; + secp256k1_ge_set_gej_zinv(&r[i], &a[i], &zs); + } + } +} + +static void secp256k1_gej_set_infinity(secp256k1_gej *r) { r->infinity = 1; - secp256k1_fe_set_int(&r->x, 0); - secp256k1_fe_set_int(&r->y, 0); - secp256k1_fe_set_int(&r->z, 0); + secp256k1_fe_clear(&r->x); + secp256k1_fe_clear(&r->y); + secp256k1_fe_clear(&r->z); } -static void secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { - r->infinity = 0; - r->x = *x; - r->y = *y; - secp256k1_fe_set_int(&r->z, 1); -} - -static void secp256k1_gej_clear(secp256k1_gej_t *r) { +static void secp256k1_gej_clear(secp256k1_gej *r) { r->infinity = 0; secp256k1_fe_clear(&r->x); secp256k1_fe_clear(&r->y); secp256k1_fe_clear(&r->z); } -static void secp256k1_ge_clear(secp256k1_ge_t *r) { +static void secp256k1_ge_clear(secp256k1_ge *r) { r->infinity = 0; secp256k1_fe_clear(&r->x); secp256k1_fe_clear(&r->y); } -static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) { - secp256k1_fe_t x2, x3, c; +static int secp256k1_ge_set_xquad(secp256k1_ge *r, const secp256k1_fe *x) { + secp256k1_fe x2, x3, c; r->x = *x; secp256k1_fe_sqr(&x2, x); secp256k1_fe_mul(&x3, x, &x2); r->infinity = 0; - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&c, &x3); - if (!secp256k1_fe_sqrt_var(&r->y, &c)) { + return secp256k1_fe_sqrt(&r->y, &c); +} + +static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd) { + if (!secp256k1_ge_set_xquad(r, x)) { return 0; } secp256k1_fe_normalize_var(&r->y); @@ -146,24 +233,25 @@ static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, i secp256k1_fe_negate(&r->y, &r->y, 1); } return 1; + } -static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) { +static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; secp256k1_fe_set_int(&r->z, 1); } -static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a) { - secp256k1_fe_t r, r2; +static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a) { + secp256k1_fe r, r2; VERIFY_CHECK(!a->infinity); secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x); r2 = a->x; secp256k1_fe_normalize_weak(&r2); return secp256k1_fe_equal_var(&r, &r2); } -static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { +static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) { r->infinity = a->infinity; r->x = a->x; r->y = a->y; @@ -172,12 +260,12 @@ static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { secp256k1_fe_negate(&r->y, &r->y, 1); } -static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { +static int secp256k1_gej_is_infinity(const secp256k1_gej *a) { return a->infinity; } -static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { - secp256k1_fe_t y2, x3, z2, z6; +static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) { + secp256k1_fe y2, x3, z2, z6; if (a->infinity) { return 0; } @@ -190,38 +278,59 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) { secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); secp256k1_fe_sqr(&z2, &a->z); secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); - secp256k1_fe_mul_int(&z6, 7); + secp256k1_fe_mul_int(&z6, CURVE_B); secp256k1_fe_add(&x3, &z6); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } -static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) { - secp256k1_fe_t y2, x3, c; +static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) { + secp256k1_fe y2, x3, c; if (a->infinity) { return 0; } /* y^2 = x^3 + 7 */ secp256k1_fe_sqr(&y2, &a->y); secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); - secp256k1_fe_set_int(&c, 7); + secp256k1_fe_set_int(&c, CURVE_B); secp256k1_fe_add(&x3, &c); secp256k1_fe_normalize_weak(&x3); return secp256k1_fe_equal_var(&y2, &x3); } -static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) { - /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t t1,t2,t3,t4; +static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { + /* Operations: 3 mul, 4 sqr, 0 normalize, 12 mul_int/add/negate. + * + * Note that there is an implementation described at + * https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * which trades a multiply for a square, but in practice this is actually slower, + * mainly because it requires more normalizations. + */ + secp256k1_fe t1,t2,t3,t4; /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity, * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p. + * + * Having said this, if this function receives a point on a sextic twist, e.g. by + * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6, + * since -6 does have a cube root mod p. For this point, this function will not set + * the infinity flag even though the point doubles to infinity, and the result + * point will be gibberish (z = 0 but infinity = 0). */ r->infinity = a->infinity; if (r->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } return; } + if (rzr != NULL) { + *rzr = a->y; + secp256k1_fe_normalize_weak(rzr); + secp256k1_fe_mul_int(rzr, 2); + } + secp256k1_fe_mul(&r->z, &a->z, &a->y); secp256k1_fe_mul_int(&r->z, 2); /* Z' = 2*Y*Z (2) */ secp256k1_fe_sqr(&t1, &a->x); @@ -244,17 +353,29 @@ static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t * secp256k1_fe_add(&r->y, &t2); /* Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) */ } -static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) { +static SECP256K1_INLINE void secp256k1_gej_double_nonzero(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr) { + VERIFY_CHECK(!secp256k1_gej_is_infinity(a)); + secp256k1_gej_double_var(r, a, rzr); +} + +static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr) { /* Operations: 12 mul, 4 sqr, 2 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + if (a->infinity) { + VERIFY_CHECK(rzr == NULL); *r = *b; return; } + if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } *r = *a; return; } + r->infinity = 0; secp256k1_fe_sqr(&z22, &b->z); secp256k1_fe_sqr(&z12, &a->z); @@ -266,8 +387,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a); + secp256k1_gej_double_var(r, a, rzr); } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } r->infinity = 1; } return; @@ -275,7 +399,11 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_sqr(&i2, &i); secp256k1_fe_sqr(&h2, &h); secp256k1_fe_mul(&h3, &h, &h2); - secp256k1_fe_mul(&r->z, &a->z, &b->z); secp256k1_fe_mul(&r->z, &r->z, &h); + secp256k1_fe_mul(&h, &h, &b->z); + if (rzr != NULL) { + *rzr = h; + } + secp256k1_fe_mul(&r->z, &a->z, &h); secp256k1_fe_mul(&t, &u1, &h2); r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); @@ -283,21 +411,23 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, secp256k1_fe_add(&r->y, &h3); } -static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { +static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr) { /* 8 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ - secp256k1_fe_t z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + secp256k1_fe z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; if (a->infinity) { - r->infinity = b->infinity; - r->x = b->x; - r->y = b->y; - secp256k1_fe_set_int(&r->z, 1); + VERIFY_CHECK(rzr == NULL); + secp256k1_gej_set_ge(r, b); return; } if (b->infinity) { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 1); + } *r = *a; return; } r->infinity = 0; + secp256k1_fe_sqr(&z12, &a->z); u1 = a->x; secp256k1_fe_normalize_weak(&u1); secp256k1_fe_mul(&u2, &b->x, &z12); @@ -307,7 +437,69 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); if (secp256k1_fe_normalizes_to_zero_var(&h)) { if (secp256k1_fe_normalizes_to_zero_var(&i)) { - secp256k1_gej_double_var(r, a); + secp256k1_gej_double_var(r, a, rzr); + } else { + if (rzr != NULL) { + secp256k1_fe_set_int(rzr, 0); + } + r->infinity = 1; + } + return; + } + secp256k1_fe_sqr(&i2, &i); + secp256k1_fe_sqr(&h2, &h); + secp256k1_fe_mul(&h3, &h, &h2); + if (rzr != NULL) { + *rzr = h; + } + secp256k1_fe_mul(&r->z, &a->z, &h); + secp256k1_fe_mul(&t, &u1, &h2); + r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); + secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); + secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); + secp256k1_fe_add(&r->y, &h3); +} + +static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv) { + /* 9 mul, 3 sqr, 4 normalize, 12 mul_int/add/negate */ + secp256k1_fe az, z12, u1, u2, s1, s2, h, i, i2, h2, h3, t; + + if (b->infinity) { + *r = *a; + return; + } + if (a->infinity) { + secp256k1_fe bzinv2, bzinv3; + r->infinity = b->infinity; + secp256k1_fe_sqr(&bzinv2, bzinv); + secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv); + secp256k1_fe_mul(&r->x, &b->x, &bzinv2); + secp256k1_fe_mul(&r->y, &b->y, &bzinv3); + secp256k1_fe_set_int(&r->z, 1); + return; + } + r->infinity = 0; + + /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to + * secp256k1's isomorphism we can multiply the Z coordinates on both sides + * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1). + * This means that (rx,ry,rz) can be calculated as + * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz. + * The variable az below holds the modified Z coordinate for a, which is used + * for the computation of rx and ry, but not for rz. + */ + secp256k1_fe_mul(&az, &a->z, bzinv); + + secp256k1_fe_sqr(&z12, &az); + u1 = a->x; secp256k1_fe_normalize_weak(&u1); + secp256k1_fe_mul(&u2, &b->x, &z12); + s1 = a->y; secp256k1_fe_normalize_weak(&s1); + secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &az); + secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); + secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); + if (secp256k1_fe_normalizes_to_zero_var(&h)) { + if (secp256k1_fe_normalizes_to_zero_var(&i)) { + secp256k1_gej_double_var(r, a, NULL); } else { r->infinity = 1; } @@ -324,11 +516,13 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t * secp256k1_fe_add(&r->y, &h3); } -static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { - /* Operations: 7 mul, 5 sqr, 5 normalize, 17 mul_int/add/negate/cmov */ - static const secp256k1_fe_t fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_fe_t zz, u1, u2, s1, s2, z, t, m, n, q, rr; - int infinity; + +static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b) { + /* Operations: 7 mul, 5 sqr, 4 normalize, 21 mul_int/add/negate/cmov */ + static const secp256k1_fe fe_1 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr; + secp256k1_fe m_alt, rr_alt; + int infinity, degenerate; VERIFY_CHECK(!b->infinity); VERIFY_CHECK(a->infinity == 0 || a->infinity == 1); @@ -352,53 +546,102 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c * Y3 = 4*(R*(3*Q-2*R^2)-M^4) * Z3 = 2*M*Z * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.) + * + * This formula has the benefit of being the same for both addition + * of distinct points and doubling. However, it breaks down in the + * case that either point is infinity, or that y1 = -y2. We handle + * these cases in the following ways: + * + * - If b is infinity we simply bail by means of a VERIFY_CHECK. + * + * - If a is infinity, we detect this, and at the end of the + * computation replace the result (which will be meaningless, + * but we compute to be constant-time) with b.x : b.y : 1. + * + * - If a = -b, we have y1 = -y2, which is a degenerate case. + * But here the answer is infinity, so we simply set the + * infinity flag of the result, overriding the computed values + * without even needing to cmov. + * + * - If y1 = -y2 but x1 != x2, which does occur thanks to certain + * properties of our curve (specifically, 1 has nontrivial cube + * roots in our field, and the curve equation has no x coefficient) + * then the answer is not infinity but also not given by the above + * equation. In this case, we cmov in place an alternate expression + * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these + * expressions for lambda are defined, they are equal, and can be + * obtained from each other by multiplication by (y1 + y2)/(y1 + y2) + * then substitution of x^3 + 7 for y^2 (using the curve equation). + * For all pairs of nonzero points (a, b) at least one is defined, + * so this covers everything. */ secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */ u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */ secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */ s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */ - secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */ + secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */ secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */ - z = a->z; /* z = Z = Z1*Z2 (8) */ t = u1; secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (2) */ m = s1; secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (2) */ - secp256k1_fe_sqr(&n, &m); /* n = M^2 (1) */ - secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*M^2 (1) */ - secp256k1_fe_sqr(&n, &n); /* n = M^4 (1) */ secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */ - secp256k1_fe_mul(&t, &u1, &u2); secp256k1_fe_negate(&t, &t, 1); /* t = -U1*U2 (2) */ - secp256k1_fe_add(&rr, &t); /* rr = R = T^2-U1*U2 (3) */ - secp256k1_fe_sqr(&t, &rr); /* t = R^2 (1) */ - secp256k1_fe_mul(&r->z, &m, &z); /* r->z = M*Z (1) */ - infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); - secp256k1_fe_mul_int(&r->z, 2 * (1 - a->infinity)); /* r->z = Z3 = 2*M*Z (2) */ - r->x = t; /* r->x = R^2 (1) */ - secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ - secp256k1_fe_add(&r->x, &q); /* r->x = R^2-Q (3) */ - secp256k1_fe_normalize(&r->x); - secp256k1_fe_mul_int(&q, 3); /* q = -3*Q (6) */ - secp256k1_fe_mul_int(&t, 2); /* t = 2*R^2 (2) */ - secp256k1_fe_add(&t, &q); /* t = 2*R^2-3*Q (8) */ - secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */ - secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */ - secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */ - secp256k1_fe_normalize_weak(&r->y); - secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */ - secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */ + secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */ + secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */ + secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */ + /** If lambda = R/M = 0/0 we have a problem (except in the "trivial" + * case that Z = z1z2 = 0, and this is special-cased later on). */ + degenerate = secp256k1_fe_normalizes_to_zero(&m) & + secp256k1_fe_normalizes_to_zero(&rr); + /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2. + * This means either x1 == beta*x2 or beta*x1 == x2, where beta is + * a nontrivial cube root of one. In either case, an alternate + * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2), + * so we set R/M equal to this. */ + rr_alt = s1; + secp256k1_fe_mul_int(&rr_alt, 2); /* rr = Y1*Z2^3 - Y2*Z1^3 (2) */ + secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 */ - /** In case a->infinity == 1, the above code results in r->x, r->y, and r->z all equal to 0. - * Replace r with b->x, b->y, 1 in that case. - */ + secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); + secp256k1_fe_cmov(&m_alt, &m, !degenerate); + /* Now Ralt / Malt = lambda and is guaranteed not to be 0/0. + * From here on out Ralt and Malt represent the numerator + * and denominator of lambda; R and M represent the explicit + * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */ + secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */ + secp256k1_fe_mul(&q, &n, &t); /* q = Q = T*Malt^2 (1) */ + /* These two lines use the observation that either M == Malt or M == 0, + * so M^3 * Malt is either Malt^4 (which is computed by squaring), or + * zero (which is "computed" by cmov). So the cost is one squaring + * versus two multiplications. */ + secp256k1_fe_sqr(&n, &n); + secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */ + secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */ + secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Malt*Z (1) */ + infinity = secp256k1_fe_normalizes_to_zero(&r->z) * (1 - a->infinity); + secp256k1_fe_mul_int(&r->z, 2); /* r->z = Z3 = 2*Malt*Z (2) */ + secp256k1_fe_negate(&q, &q, 1); /* q = -Q (2) */ + secp256k1_fe_add(&t, &q); /* t = Ralt^2-Q (3) */ + secp256k1_fe_normalize_weak(&t); + r->x = t; /* r->x = Ralt^2-Q (1) */ + secp256k1_fe_mul_int(&t, 2); /* t = 2*x3 (2) */ + secp256k1_fe_add(&t, &q); /* t = 2*x3 - Q: (4) */ + secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*x3 - Q) (1) */ + secp256k1_fe_add(&t, &n); /* t = Ralt*(2*x3 - Q) + M^3*Malt (3) */ + secp256k1_fe_negate(&r->y, &t, 3); /* r->y = Ralt*(Q - 2x3) - M^3*Malt (4) */ + secp256k1_fe_normalize_weak(&r->y); + secp256k1_fe_mul_int(&r->x, 4); /* r->x = X3 = 4*(Ralt^2-Q) */ + secp256k1_fe_mul_int(&r->y, 4); /* r->y = Y3 = 4*Ralt*(Q - 2x3) - 4*M^3*Malt (4) */ + + /** In case a->infinity == 1, replace r with (b->x, b->y, 1). */ secp256k1_fe_cmov(&r->x, &b->x, a->infinity); secp256k1_fe_cmov(&r->y, &b->y, a->infinity); secp256k1_fe_cmov(&r->z, &fe_1, a->infinity); r->infinity = infinity; } -static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) { +static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) { /* Operations: 4 mul, 1 sqr */ - secp256k1_fe_t zz; + secp256k1_fe zz; VERIFY_CHECK(!secp256k1_fe_is_zero(s)); secp256k1_fe_sqr(&zz, s); secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */ @@ -407,8 +650,8 @@ static void secp256k1_gej_rescale(secp256k1_gej_t *r, const secp256k1_fe_t *s) { secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */ } -static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) { - secp256k1_fe_t x, y; +static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge *a) { + secp256k1_fe x, y; VERIFY_CHECK(!a->infinity); x = a->x; secp256k1_fe_normalize(&x); @@ -418,20 +661,20 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_g secp256k1_fe_to_storage(&r->y, &y); } -static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t *a) { +static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a) { secp256k1_fe_from_storage(&r->x, &a->x); secp256k1_fe_from_storage(&r->y, &a->y); r->infinity = 0; } -static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag) { +static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) { secp256k1_fe_storage_cmov(&r->x, &a->x, flag); secp256k1_fe_storage_cmov(&r->y, &a->y, flag); } #ifdef USE_ENDOMORPHISM -static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) { - static const secp256k1_fe_t beta = SECP256K1_FE_CONST( +static void secp256k1_ge_mul_lambda(secp256k1_ge *r, const secp256k1_ge *a) { + static const secp256k1_fe beta = SECP256K1_FE_CONST( 0x7ae96a2bul, 0x657c0710ul, 0x6e64479eul, 0xac3434e9ul, 0x9cf04975ul, 0x12f58995ul, 0xc1396c28ul, 0x719501eeul ); @@ -440,4 +683,18 @@ static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t * } #endif -#endif +static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) { + secp256k1_fe yz; + + if (a->infinity) { + return 0; + } + + /* We rely on the fact that the Jacobi symbol of 1 / a->z^3 is the same as + * that of a->z. Thus a->y / a->z^3 is a quadratic residue iff a->y * a->z + is */ + secp256k1_fe_mul(&yz, &a->y, &a->z); + return secp256k1_fe_is_quad_var(&yz); +} + +#endif /* SECP256K1_GROUP_IMPL_H */ diff --git a/src/secp256k1/src/hash.h b/src/secp256k1/src/hash.h index 843423d7f..de26e4b89 100644 --- a/src/secp256k1/src/hash.h +++ b/src/secp256k1/src/hash.h @@ -4,38 +4,38 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_HASH_ -#define _SECP256K1_HASH_ +#ifndef SECP256K1_HASH_H +#define SECP256K1_HASH_H #include #include typedef struct { - uint32_t s[32]; + uint32_t s[8]; uint32_t buf[16]; /* In big endian */ size_t bytes; -} secp256k1_sha256_t; +} secp256k1_sha256; -static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash); -static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t size); -static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32); +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); typedef struct { - secp256k1_sha256_t inner, outer; -} secp256k1_hmac_sha256_t; + secp256k1_sha256 inner, outer; +} secp256k1_hmac_sha256; -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t size); -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size); -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32); +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); typedef struct { unsigned char v[32]; unsigned char k[32]; int retry; -} secp256k1_rfc6979_hmac_sha256_t; +} secp256k1_rfc6979_hmac_sha256; -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen); -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen); -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng); +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); -#endif +#endif /* SECP256K1_HASH_H */ diff --git a/src/secp256k1/src/hash_impl.h b/src/secp256k1/src/hash_impl.h index 9828827bc..c06db9e33 100644 --- a/src/secp256k1/src/hash_impl.h +++ b/src/secp256k1/src/hash_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_HASH_IMPL_H_ -#define _SECP256K1_HASH_IMPL_H_ +#ifndef SECP256K1_HASH_IMPL_H +#define SECP256K1_HASH_IMPL_H #include "hash.h" @@ -33,7 +33,7 @@ #define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) #endif -static void secp256k1_sha256_initialize(secp256k1_sha256_t *hash) { +static void secp256k1_sha256_initialize(secp256k1_sha256 *hash) { hash->s[0] = 0x6a09e667ul; hash->s[1] = 0xbb67ae85ul; hash->s[2] = 0x3c6ef372ul; @@ -128,7 +128,7 @@ static void secp256k1_sha256_transform(uint32_t* s, const uint32_t* chunk) { s[7] += h; } -static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char *data, size_t len) { +static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t len) { size_t bufsize = hash->bytes & 0x3F; hash->bytes += len; while (bufsize + len >= 64) { @@ -145,7 +145,7 @@ static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char } } -static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *out32) { +static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32) { static const unsigned char pad[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint32_t sizedesc[2]; uint32_t out[8]; @@ -161,14 +161,14 @@ static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *o memcpy(out32, (const unsigned char*)out, 32); } -static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) { +static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { int n; unsigned char rkey[64]; if (keylen <= 64) { memcpy(rkey, key, keylen); memset(rkey + keylen, 0, 64 - keylen); } else { - secp256k1_sha256_t sha256; + secp256k1_sha256 sha256; secp256k1_sha256_initialize(&sha256); secp256k1_sha256_write(&sha256, key, keylen); secp256k1_sha256_finalize(&sha256, rkey); @@ -189,11 +189,11 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, cons memset(rkey, 0, 64); } -static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256_t *hash, const unsigned char *data, size_t size) { +static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) { secp256k1_sha256_write(&hash->inner, data, size); } -static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsigned char *out32) { +static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32) { unsigned char temp[32]; secp256k1_sha256_finalize(&hash->inner, temp); secp256k1_sha256_write(&hash->outer, temp, 32); @@ -202,8 +202,8 @@ static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsign } -static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen, const unsigned char *rnd, size_t rndlen) { - secp256k1_hmac_sha256_t hmac; +static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { + secp256k1_hmac_sha256 hmac; static const unsigned char zero[1] = {0x00}; static const unsigned char one[1] = {0x01}; @@ -215,11 +215,6 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_write(&hmac, msg, msglen); - if (rnd && rndlen) { - /* RFC6979 3.6 "Additional data". */ - secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); - } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -230,11 +225,6 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, one, 1); secp256k1_hmac_sha256_write(&hmac, key, keylen); - secp256k1_hmac_sha256_write(&hmac, msg, msglen); - if (rnd && rndlen) { - /* RFC6979 3.6 "Additional data". */ - secp256k1_hmac_sha256_write(&hmac, rnd, rndlen); - } secp256k1_hmac_sha256_finalize(&hmac, rng->k); secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -242,11 +232,11 @@ static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha2 rng->retry = 0; } -static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256_t *rng, unsigned char *out, size_t outlen) { +static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen) { /* RFC6979 3.2.h. */ static const unsigned char zero[1] = {0x00}; if (rng->retry) { - secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256 hmac; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); secp256k1_hmac_sha256_write(&hmac, zero, 1); @@ -257,7 +247,7 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 } while (outlen > 0) { - secp256k1_hmac_sha256_t hmac; + secp256k1_hmac_sha256 hmac; int now = outlen; secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32); secp256k1_hmac_sha256_write(&hmac, rng->v, 32); @@ -273,21 +263,19 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 rng->retry = 1; } -static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256_t *rng) { +static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { memset(rng->k, 0, 32); memset(rng->v, 0, 32); rng->retry = 0; } - +#undef BE32 #undef Round -#undef sigma0 #undef sigma1 -#undef Sigma0 +#undef sigma0 #undef Sigma1 -#undef Ch +#undef Sigma0 #undef Maj -#undef ReadBE32 -#undef WriteBE32 +#undef Ch -#endif +#endif /* SECP256K1_HASH_IMPL_H */ diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java index 90a498eaa..1c67802fb 100644 --- a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1.java @@ -1,60 +1,446 @@ +/* + * Copyright 2013 Google Inc. + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.bitcoin; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.math.BigInteger; import com.google.common.base.Preconditions; - +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import static org.bitcoin.NativeSecp256k1Util.*; /** - * This class holds native methods to handle ECDSA verification. - * You can find an example library that can be used for this at - * https://github.com/sipa/secp256k1 + *

This class holds native methods to handle ECDSA verification.

+ * + *

You can find an example library that can be used for this at https://github.com/bitcoin/secp256k1

+ * + *

To build secp256k1 for use with bitcoinj, run + * `./configure --enable-jni --enable-experimental --enable-module-ecdh` + * and `make` then copy `.libs/libsecp256k1.so` to your system library path + * or point the JVM to the folder containing it with -Djava.library.path + *

*/ public class NativeSecp256k1 { - public static final boolean enabled; - static { - boolean isEnabled = true; - try { - System.loadLibrary("javasecp256k1"); - } catch (UnsatisfiedLinkError e) { - isEnabled = false; - } - enabled = isEnabled; - } - + + private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private static final Lock r = rwl.readLock(); + private static final Lock w = rwl.writeLock(); private static ThreadLocal nativeECDSABuffer = new ThreadLocal(); /** * Verifies the given secp256k1 signature in native code. * Calling when enabled == false is undefined (probably library not loaded) - * + * * @param data The data which was signed, must be exactly 32 bytes * @param signature The signature * @param pub The public key which did the signing */ - public static boolean verify(byte[] data, byte[] signature, byte[] pub) { + public static boolean verify(byte[] data, byte[] signature, byte[] pub) throws AssertFailException{ Preconditions.checkArgument(data.length == 32 && signature.length <= 520 && pub.length <= 520); ByteBuffer byteBuff = nativeECDSABuffer.get(); - if (byteBuff == null) { - byteBuff = ByteBuffer.allocateDirect(32 + 8 + 520 + 520); + if (byteBuff == null || byteBuff.capacity() < 520) { + byteBuff = ByteBuffer.allocateDirect(520); byteBuff.order(ByteOrder.nativeOrder()); nativeECDSABuffer.set(byteBuff); } byteBuff.rewind(); byteBuff.put(data); - byteBuff.putInt(signature.length); - byteBuff.putInt(pub.length); byteBuff.put(signature); byteBuff.put(pub); - return secp256k1_ecdsa_verify(byteBuff) == 1; + + byte[][] retByteArray; + + r.lock(); + try { + return secp256k1_ecdsa_verify(byteBuff, Secp256k1Context.getContext(), signature.length, pub.length) == 1; + } finally { + r.unlock(); + } } /** - * @param byteBuff signature format is byte[32] data, - * native-endian int signatureLength, native-endian int pubkeyLength, - * byte[signatureLength] signature, byte[pubkeyLength] pub - * @returns 1 for valid signature, anything else for invalid + * libsecp256k1 Create an ECDSA signature. + * + * @param data Message hash, 32 bytes + * @param key Secret key, 32 bytes + * + * Return values + * @param sig byte array of signature */ - private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff); + public static byte[] sign(byte[] data, byte[] sec) throws AssertFailException{ + Preconditions.checkArgument(data.length == 32 && sec.length <= 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + 32) { + byteBuff = ByteBuffer.allocateDirect(32 + 32); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(data); + byteBuff.put(sec); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ecdsa_sign(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] sigArr = retByteArray[0]; + int sigLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(sigArr.length, sigLen, "Got bad signature length."); + + return retVal == 0 ? new byte[0] : sigArr; + } + + /** + * libsecp256k1 Seckey Verify - returns 1 if valid, 0 if invalid + * + * @param seckey ECDSA Secret key, 32 bytes + */ + public static boolean secKeyVerify(byte[] seckey) { + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + r.lock(); + try { + return secp256k1_ec_seckey_verify(byteBuff,Secp256k1Context.getContext()) == 1; + } finally { + r.unlock(); + } + } + + + /** + * libsecp256k1 Compute Pubkey - computes public key from secret key + * + * @param seckey ECDSA Secret key, 32 bytes + * + * Return values + * @param pubkey ECDSA Public key, 33 or 65 bytes + */ + //TODO add a 'compressed' arg + public static byte[] computePubkey(byte[] seckey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seckey.length) { + byteBuff = ByteBuffer.allocateDirect(seckey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + + byte[][] retByteArray; + + r.lock(); + try { + retByteArray = secp256k1_ec_pubkey_create(byteBuff, Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + int pubLen = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + return retVal == 0 ? new byte[0]: pubArr; + } + + /** + * libsecp256k1 Cleanup - This destroys the secp256k1 context object + * This should be called at the end of the program for proper cleanup of the context. + */ + public static synchronized void cleanup() { + w.lock(); + try { + secp256k1_destroy_context(Secp256k1Context.getContext()); + } finally { + w.unlock(); + } + } + + public static long cloneContext() { + r.lock(); + try { + return secp256k1_ctx_clone(Secp256k1Context.getContext()); + } finally { r.unlock(); } + } + + /** + * libsecp256k1 PrivKey Tweak-Mul - Tweak privkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakMul(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_mul(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PrivKey Tweak-Add - Tweak privkey by adding to it + * + * @param tweak some bytes to tweak with + * @param seckey 32-byte seckey + */ + public static byte[] privKeyTweakAdd(byte[] privkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(privkey.length == 32); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < privkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(privkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(privkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_privkey_tweak_add(byteBuff,Secp256k1Context.getContext()); + } finally { + r.unlock(); + } + + byte[] privArr = retByteArray[0]; + + int privLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(privArr.length, privLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return privArr; + } + + /** + * libsecp256k1 PubKey Tweak-Add - Tweak pubkey by adding to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakAdd(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_add(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 PubKey Tweak-Mul - Tweak pubkey by multiplying to it + * + * @param tweak some bytes to tweak with + * @param pubkey 32-byte seckey + */ + public static byte[] pubKeyTweakMul(byte[] pubkey, byte[] tweak) throws AssertFailException{ + Preconditions.checkArgument(pubkey.length == 33 || pubkey.length == 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < pubkey.length + tweak.length) { + byteBuff = ByteBuffer.allocateDirect(pubkey.length + tweak.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(pubkey); + byteBuff.put(tweak); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_pubkey_tweak_mul(byteBuff,Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] pubArr = retByteArray[0]; + + int pubLen = (byte) new BigInteger(new byte[] { retByteArray[1][0] }).intValue() & 0xFF; + int retVal = new BigInteger(new byte[] { retByteArray[1][1] }).intValue(); + + assertEquals(pubArr.length, pubLen, "Got bad pubkey length."); + + assertEquals(retVal, 1, "Failed return value check."); + + return pubArr; + } + + /** + * libsecp256k1 create ECDH secret - constant time ECDH calculation + * + * @param seckey byte array of secret key used in exponentiaion + * @param pubkey byte array of public key used in exponentiaion + */ + public static byte[] createECDHSecret(byte[] seckey, byte[] pubkey) throws AssertFailException{ + Preconditions.checkArgument(seckey.length <= 32 && pubkey.length <= 65); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < 32 + pubkey.length) { + byteBuff = ByteBuffer.allocateDirect(32 + pubkey.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seckey); + byteBuff.put(pubkey); + + byte[][] retByteArray; + r.lock(); + try { + retByteArray = secp256k1_ecdh(byteBuff, Secp256k1Context.getContext(), pubkey.length); + } finally { + r.unlock(); + } + + byte[] resArr = retByteArray[0]; + int retVal = new BigInteger(new byte[] { retByteArray[1][0] }).intValue(); + + assertEquals(resArr.length, 32, "Got bad result length."); + assertEquals(retVal, 1, "Failed return value check."); + + return resArr; + } + + /** + * libsecp256k1 randomize - updates the context randomization + * + * @param seed 32-byte random seed + */ + public static synchronized boolean randomize(byte[] seed) throws AssertFailException{ + Preconditions.checkArgument(seed.length == 32 || seed == null); + + ByteBuffer byteBuff = nativeECDSABuffer.get(); + if (byteBuff == null || byteBuff.capacity() < seed.length) { + byteBuff = ByteBuffer.allocateDirect(seed.length); + byteBuff.order(ByteOrder.nativeOrder()); + nativeECDSABuffer.set(byteBuff); + } + byteBuff.rewind(); + byteBuff.put(seed); + + w.lock(); + try { + return secp256k1_context_randomize(byteBuff, Secp256k1Context.getContext()) == 1; + } finally { + w.unlock(); + } + } + + private static native long secp256k1_ctx_clone(long context); + + private static native int secp256k1_context_randomize(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_add(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_privkey_tweak_mul(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_pubkey_tweak_add(ByteBuffer byteBuff, long context, int pubLen); + + private static native byte[][] secp256k1_pubkey_tweak_mul(ByteBuffer byteBuff, long context, int pubLen); + + private static native void secp256k1_destroy_context(long context); + + private static native int secp256k1_ecdsa_verify(ByteBuffer byteBuff, long context, int sigLen, int pubLen); + + private static native byte[][] secp256k1_ecdsa_sign(ByteBuffer byteBuff, long context); + + private static native int secp256k1_ec_seckey_verify(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_create(ByteBuffer byteBuff, long context); + + private static native byte[][] secp256k1_ec_pubkey_parse(ByteBuffer byteBuff, long context, int inputLen); + + private static native byte[][] secp256k1_ecdh(ByteBuffer byteBuff, long context, int inputLen); + } diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java new file mode 100644 index 000000000..c00d08899 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Test.java @@ -0,0 +1,226 @@ +package org.bitcoin; + +import com.google.common.io.BaseEncoding; +import java.util.Arrays; +import java.math.BigInteger; +import javax.xml.bind.DatatypeConverter; +import static org.bitcoin.NativeSecp256k1Util.*; + +/** + * This class holds test cases defined for testing this library. + */ +public class NativeSecp256k1Test { + + //TODO improve comments/add more tests + /** + * This tests verify() for a valid signature + */ + public static void testVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + assertEquals( result, true , "testVerifyPos"); + } + + /** + * This tests verify() for a non-valid signature + */ + public static void testVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A91".toLowerCase()); //sha256hash of "testing" + byte[] sig = BaseEncoding.base16().lowerCase().decode("3044022079BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F817980220294F14E883B3F525B5367756C2A11EF6CF84B730B36C17CB0C56F0AAB2C98589".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + result = NativeSecp256k1.verify( data, sig, pub); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testVerifyNeg"); + } + + /** + * This tests secret key verify() for a valid secretkey + */ + public static void testSecKeyVerifyPos() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, true , "testSecKeyVerifyPos"); + } + + /** + * This tests secret key verify() for a invalid secretkey + */ + public static void testSecKeyVerifyNeg() throws AssertFailException{ + boolean result = false; + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + result = NativeSecp256k1.secKeyVerify( sec ); + //System.out.println(" TEST " + new BigInteger(1, resultbytes).toString(16)); + assertEquals( result, false , "testSecKeyVerifyNeg"); + } + + /** + * This tests public key create() for a valid secretkey + */ + public static void testPubKeyCreatePos() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString , "04C591A8FF19AC9C4E4E5793673B83123437E975285E7B442F4EE2654DFFCA5E2D2103ED494718C697AC9AEBCFD19612E224DB46661011863ED2FC54E71861E2A6" , "testPubKeyCreatePos"); + } + + /** + * This tests public key create() for a invalid secretkey + */ + public static void testPubKeyCreateNeg() throws AssertFailException{ + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.computePubkey( sec); + String pubkeyString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( pubkeyString, "" , "testPubKeyCreateNeg"); + } + + /** + * This tests sign() for a valid secretkey + */ + public static void testSignPos() throws AssertFailException{ + + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "30440220182A108E1448DC8F1FB467D06A0F3BB8EA0533584CB954EF8DA112F1D60E39A202201C66F36DA211C087F3AF88B50EDF4F9BDAA6CF5FD6817E74DCA34DB12390C6E9" , "testSignPos"); + } + + /** + * This tests sign() for a invalid secretkey + */ + public static void testSignNeg() throws AssertFailException{ + byte[] data = BaseEncoding.base16().lowerCase().decode("CF80CD8AED482D5D1527D7DC72FCEFF84E6326592848447D2DC0B0E87DFC9A90".toLowerCase()); //sha256hash of "testing" + byte[] sec = BaseEncoding.base16().lowerCase().decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.sign(data, sec); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString, "" , "testSignNeg"); + } + + /** + * This tests private key tweak-add + */ + public static void testPrivKeyTweakAdd_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakAdd( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "A168571E189E6F9A7E2D657A4B53AE99B909F7E712D1C23CED28093CD57C88F3" , "testPrivKeyAdd_1"); + } + + /** + * This tests private key tweak-mul + */ + public static void testPrivKeyTweakMul_1() throws AssertFailException { + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.privKeyTweakMul( sec , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "97F8184235F101550F3C71C927507651BD3F1CDB4A5A33B8986ACF0DEE20FFFC" , "testPrivKeyMul_1"); + } + + /** + * This tests private key tweak-add uncompressed + */ + public static void testPrivKeyTweakAdd_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakAdd( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "0411C6790F4B663CCE607BAAE08C43557EDC1A4D11D88DFCB3D841D0C6A941AF525A268E2A863C148555C48FB5FBA368E88718A46E205FABC3DBA2CCFFAB0796EF" , "testPrivKeyAdd_2"); + } + + /** + * This tests private key tweak-mul uncompressed + */ + public static void testPrivKeyTweakMul_2() throws AssertFailException { + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + byte[] data = BaseEncoding.base16().lowerCase().decode("3982F19BEF1615BCCFBB05E321C10E1D4CBA3DF0E841C2E41EEB6016347653C3".toLowerCase()); //sha256hash of "tweak" + + byte[] resultArr = NativeSecp256k1.pubKeyTweakMul( pub , data ); + String sigString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( sigString , "04E0FE6FE55EBCA626B98A807F6CAF654139E14E5E3698F01A9A658E21DC1D2791EC060D4F412A794D5370F672BC94B722640B5F76914151CFCA6E712CA48CC589" , "testPrivKeyMul_2"); + } + + /** + * This tests seed randomization + */ + public static void testRandomize() throws AssertFailException { + byte[] seed = BaseEncoding.base16().lowerCase().decode("A441B15FE9A3CF56661190A0B93B9DEC7D04127288CC87250967CF3B52894D11".toLowerCase()); //sha256hash of "random" + boolean result = NativeSecp256k1.randomize(seed); + assertEquals( result, true, "testRandomize"); + } + + public static void testCreateECDHSecret() throws AssertFailException{ + + byte[] sec = BaseEncoding.base16().lowerCase().decode("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530".toLowerCase()); + byte[] pub = BaseEncoding.base16().lowerCase().decode("040A629506E1B65CD9D2E0BA9C75DF9C4FED0DB16DC9625ED14397F0AFC836FAE595DC53F8B0EFE61E703075BD9B143BAC75EC0E19F82A2208CAEB32BE53414C40".toLowerCase()); + + byte[] resultArr = NativeSecp256k1.createECDHSecret(sec, pub); + String ecdhString = javax.xml.bind.DatatypeConverter.printHexBinary(resultArr); + assertEquals( ecdhString, "2A2A67007A926E6594AF3EB564FC74005B37A9C8AEF2033C4552051B5C87F043" , "testCreateECDHSecret"); + } + + public static void main(String[] args) throws AssertFailException{ + + + System.out.println("\n libsecp256k1 enabled: " + Secp256k1Context.isEnabled() + "\n"); + + assertEquals( Secp256k1Context.isEnabled(), true, "isEnabled" ); + + //Test verify() success/fail + testVerifyPos(); + testVerifyNeg(); + + //Test secKeyVerify() success/fail + testSecKeyVerifyPos(); + testSecKeyVerifyNeg(); + + //Test computePubkey() success/fail + testPubKeyCreatePos(); + testPubKeyCreateNeg(); + + //Test sign() success/fail + testSignPos(); + testSignNeg(); + + //Test privKeyTweakAdd() 1 + testPrivKeyTweakAdd_1(); + + //Test privKeyTweakMul() 2 + testPrivKeyTweakMul_1(); + + //Test privKeyTweakAdd() 3 + testPrivKeyTweakAdd_2(); + + //Test privKeyTweakMul() 4 + testPrivKeyTweakMul_2(); + + //Test randomize() + testRandomize(); + + //Test ECDH + testCreateECDHSecret(); + + NativeSecp256k1.cleanup(); + + System.out.println(" All tests passed." ); + + } +} diff --git a/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java new file mode 100644 index 000000000..04732ba04 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/NativeSecp256k1Util.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +public class NativeSecp256k1Util{ + + public static void assertEquals( int val, int val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + } + + public static void assertEquals( boolean val, boolean val2, String message ) throws AssertFailException{ + if( val != val2 ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static void assertEquals( String val, String val2, String message ) throws AssertFailException{ + if( !val.equals(val2) ) + throw new AssertFailException("FAIL: " + message); + else + System.out.println("PASS: " + message); + } + + public static class AssertFailException extends Exception { + public AssertFailException(String message) { + super( message ); + } + } +} diff --git a/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java b/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java new file mode 100644 index 000000000..216c986a8 --- /dev/null +++ b/src/secp256k1/src/java/org/bitcoin/Secp256k1Context.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014-2016 the libsecp256k1 contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.bitcoin; + +/** + * This class holds the context reference used in native methods + * to handle ECDSA operations. + */ +public class Secp256k1Context { + private static final boolean enabled; //true if the library is loaded + private static final long context; //ref to pointer to context obj + + static { //static initializer + boolean isEnabled = true; + long contextRef = -1; + try { + System.loadLibrary("secp256k1"); + contextRef = secp256k1_init_context(); + } catch (UnsatisfiedLinkError e) { + System.out.println("UnsatisfiedLinkError: " + e.toString()); + isEnabled = false; + } + enabled = isEnabled; + context = contextRef; + } + + public static boolean isEnabled() { + return enabled; + } + + public static long getContext() { + if(!enabled) return -1; //sanity check + return context; + } + + private static native long secp256k1_init_context(); +} diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c index bb4cd7072..bcef7b32c 100644 --- a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.c @@ -1,23 +1,377 @@ +#include +#include +#include #include "org_bitcoin_NativeSecp256k1.h" #include "include/secp256k1.h" +#include "include/secp256k1_ecdh.h" +#include "include/secp256k1_recovery.h" -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv* env, jclass classObject, jobject byteBufferObject) + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv* env, jclass classObject, jlong ctx_l) { - unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); - int sigLen = *((int*)(data + 32)); - int pubLen = *((int*)(data + 32 + 4)); + const secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + jlong ctx_clone_l = (uintptr_t) secp256k1_context_clone(ctx); + + (void)classObject;(void)env; + + return ctx_clone_l; - return secp256k1_ecdsa_verify(data, 32, data+32+8, sigLen, data+32+8+sigLen, pubLen); } -static void __javasecp256k1_attach(void) __attribute__((constructor)); -static void __javasecp256k1_detach(void) __attribute__((destructor)); +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + const unsigned char* seed = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_context_randomize(ctx, seed); -static void __javasecp256k1_attach(void) { - secp256k1_start(SECP256K1_START_VERIFY); } -static void __javasecp256k1_detach(void) { - secp256k1_stop(); +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv* env, jclass classObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + secp256k1_context_destroy(ctx); + + (void)classObject;(void)env; +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint siglen, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* sigdata = { (unsigned char*) (data + 32) }; + const unsigned char* pubdata = { (unsigned char*) (data + siglen + 32) }; + + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pubkey; + + int ret = secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigdata, siglen); + + if( ret ) { + ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if( ret ) { + ret = secp256k1_ecdsa_verify(ctx, &sig, data, &pubkey); + } + } + + (void)classObject; + + return ret; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* data = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + unsigned char* secKey = (unsigned char*) (data + 32); + + jobjectArray retArray; + jbyteArray sigArray, intsByteArray; + unsigned char intsarray[2]; + + secp256k1_ecdsa_signature sig[72]; + + int ret = secp256k1_ecdsa_sign(ctx, sig, data, secKey, NULL, NULL ); + + unsigned char outputSer[72]; + size_t outputLen = 72; + + if( ret ) { + int ret2 = secp256k1_ecdsa_signature_serialize_der(ctx,outputSer, &outputLen, sig ); (void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + sigArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, sigArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, sigArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + (void)classObject; + + return secp256k1_ec_seckey_verify(ctx, secKey); +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secKey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + + secp256k1_pubkey pubkey; + + jobjectArray retArray; + jbyteArray pubkeyArray, intsByteArray; + unsigned char intsarray[2]; + + int ret = secp256k1_ec_pubkey_create(ctx, &pubkey, secKey); + + unsigned char outputSer[65]; + size_t outputLen = 65; + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubkeyArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubkeyArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubkeyArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; + +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_add(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* privkey = (unsigned char*) (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (privkey + 32); + + jobjectArray retArray; + jbyteArray privArray, intsByteArray; + unsigned char intsarray[2]; + + int privkeylen = 32; + + int ret = secp256k1_ec_privkey_tweak_mul(ctx, privkey, tweak); + + intsarray[0] = privkeylen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + privArray = (*env)->NewByteArray(env, privkeylen); + (*env)->SetByteArrayRegion(env, privArray, 0, privkeylen, (jbyte*)privkey); + (*env)->SetObjectArrayElement(env, retArray, 0, privArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; +/* secp256k1_pubkey* pubkey = (secp256k1_pubkey*) (*env)->GetDirectBufferAddress(env, byteBufferObject);*/ + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if( ret ) { + ret = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + unsigned char* pkey = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* tweak = (unsigned char*) (pkey + publen); + + jobjectArray retArray; + jbyteArray pubArray, intsByteArray; + unsigned char intsarray[2]; + unsigned char outputSer[65]; + size_t outputLen = 65; + + secp256k1_pubkey pubkey; + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pkey, publen); + + if ( ret ) { + ret = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, tweak); + } + + if( ret ) { + int ret2 = secp256k1_ec_pubkey_serialize(ctx,outputSer, &outputLen, &pubkey,SECP256K1_EC_UNCOMPRESSED );(void)ret2; + } + + intsarray[0] = outputLen; + intsarray[1] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + pubArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, pubArray, 0, outputLen, (jbyte*)outputSer); + (*env)->SetObjectArrayElement(env, retArray, 0, pubArray); + + intsByteArray = (*env)->NewByteArray(env, 2); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 2, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; +} + +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1pubkey_1combine + (JNIEnv * env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint numkeys) +{ + (void)classObject;(void)env;(void)byteBufferObject;(void)ctx_l;(void)numkeys; + + return 0; +} + +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen) +{ + secp256k1_context *ctx = (secp256k1_context*)(uintptr_t)ctx_l; + const unsigned char* secdata = (*env)->GetDirectBufferAddress(env, byteBufferObject); + const unsigned char* pubdata = (const unsigned char*) (secdata + 32); + + jobjectArray retArray; + jbyteArray outArray, intsByteArray; + unsigned char intsarray[1]; + secp256k1_pubkey pubkey; + unsigned char nonce_res[32]; + size_t outputLen = 32; + + int ret = secp256k1_ec_pubkey_parse(ctx, &pubkey, pubdata, publen); + + if (ret) { + ret = secp256k1_ecdh( + ctx, + nonce_res, + &pubkey, + secdata + ); + } + + intsarray[0] = ret; + + retArray = (*env)->NewObjectArray(env, 2, + (*env)->FindClass(env, "[B"), + (*env)->NewByteArray(env, 1)); + + outArray = (*env)->NewByteArray(env, outputLen); + (*env)->SetByteArrayRegion(env, outArray, 0, 32, (jbyte*)nonce_res); + (*env)->SetObjectArrayElement(env, retArray, 0, outArray); + + intsByteArray = (*env)->NewByteArray(env, 1); + (*env)->SetByteArrayRegion(env, intsByteArray, 0, 1, (jbyte*)intsarray); + (*env)->SetObjectArrayElement(env, retArray, 1, intsByteArray); + + (void)classObject; + + return retArray; } diff --git a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h index d7fb004fa..fe613c9e9 100644 --- a/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h +++ b/src/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h @@ -1,5 +1,6 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include +#include "include/secp256k1.h" /* Header for class org_bitcoin_NativeSecp256k1 */ #ifndef _Included_org_bitcoin_NativeSecp256k1 @@ -9,11 +10,108 @@ extern "C" { #endif /* * Class: org_bitcoin_NativeSecp256k1 - * Method: secp256k1_ecdsa_verify - * Signature: (Ljava/nio/ByteBuffer;)I + * Method: secp256k1_ctx_clone + * Signature: (J)J */ -JNIEXPORT jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify - (JNIEnv *, jclass, jobject); +SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_context_randomize + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_privkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_add + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_pubkey_tweak_mul + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_destroy_context + * Signature: (J)V + */ +SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context + (JNIEnv *, jclass, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_verify + * Signature: (Ljava/nio/ByteBuffer;JII)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify + (JNIEnv *, jclass, jobject, jlong, jint, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdsa_sign + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_seckey_verify + * Signature: (Ljava/nio/ByteBuffer;J)I + */ +SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_create + * Signature: (Ljava/nio/ByteBuffer;J)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ec_pubkey_parse + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse + (JNIEnv *, jclass, jobject, jlong, jint); + +/* + * Class: org_bitcoin_NativeSecp256k1 + * Method: secp256k1_ecdh + * Signature: (Ljava/nio/ByteBuffer;JI)[[B + */ +SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh + (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); + #ifdef __cplusplus } diff --git a/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c new file mode 100644 index 000000000..a52939e7e --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.c @@ -0,0 +1,15 @@ +#include +#include +#include "org_bitcoin_Secp256k1Context.h" +#include "include/secp256k1.h" + +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv* env, jclass classObject) +{ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + (void)classObject;(void)env; + + return (uintptr_t)ctx; +} + diff --git a/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h new file mode 100644 index 000000000..0d2bc84b7 --- /dev/null +++ b/src/secp256k1/src/java/org_bitcoin_Secp256k1Context.h @@ -0,0 +1,22 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +#include "include/secp256k1.h" +/* Header for class org_bitcoin_Secp256k1Context */ + +#ifndef _Included_org_bitcoin_Secp256k1Context +#define _Included_org_bitcoin_Secp256k1Context +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_bitcoin_Secp256k1Context + * Method: secp256k1_init_context + * Signature: ()J + */ +SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/secp256k1/src/modules/ecdh/Makefile.am.include b/src/secp256k1/src/modules/ecdh/Makefile.am.include new file mode 100644 index 000000000..e3088b469 --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_ecdh.h +noinst_HEADERS += src/modules/ecdh/main_impl.h +noinst_HEADERS += src/modules/ecdh/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_ecdh +bench_ecdh_SOURCES = src/bench_ecdh.c +bench_ecdh_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) +endif diff --git a/src/secp256k1/src/modules/ecdh/main_impl.h b/src/secp256k1/src/modules/ecdh/main_impl.h new file mode 100644 index 000000000..bd8739eeb --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/main_impl.h @@ -0,0 +1,54 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDH_MAIN_H +#define SECP256K1_MODULE_ECDH_MAIN_H + +#include "include/secp256k1_ecdh.h" +#include "ecmult_const_impl.h" + +int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { + int ret = 0; + int overflow = 0; + secp256k1_gej res; + secp256k1_ge pt; + secp256k1_scalar s; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(result != NULL); + ARG_CHECK(point != NULL); + ARG_CHECK(scalar != NULL); + + secp256k1_pubkey_load(ctx, &pt, point); + secp256k1_scalar_set_b32(&s, scalar, &overflow); + if (overflow || secp256k1_scalar_is_zero(&s)) { + ret = 0; + } else { + unsigned char x[32]; + unsigned char y[1]; + secp256k1_sha256 sha; + + secp256k1_ecmult_const(&res, &pt, &s); + secp256k1_ge_set_gej(&pt, &res); + /* Compute a hash of the point in compressed form + * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not + * expect its output to be secret and has a timing sidechannel. */ + secp256k1_fe_normalize(&pt.x); + secp256k1_fe_normalize(&pt.y); + secp256k1_fe_get_b32(x, &pt.x); + y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); + + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, y, sizeof(y)); + secp256k1_sha256_write(&sha, x, sizeof(x)); + secp256k1_sha256_finalize(&sha, result); + ret = 1; + } + + secp256k1_scalar_clear(&s); + return ret; +} + +#endif /* SECP256K1_MODULE_ECDH_MAIN_H */ diff --git a/src/secp256k1/src/modules/ecdh/tests_impl.h b/src/secp256k1/src/modules/ecdh/tests_impl.h new file mode 100644 index 000000000..0c53f8ee0 --- /dev/null +++ b/src/secp256k1/src/modules/ecdh/tests_impl.h @@ -0,0 +1,105 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_ECDH_TESTS_H +#define SECP256K1_MODULE_ECDH_TESTS_H + +void test_ecdh_api(void) { + /* Setup context that just counts errors */ + secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_pubkey point; + unsigned char res[32]; + unsigned char s_one[32] = { 0 }; + int32_t ecount = 0; + s_one[31] = 1; + + secp256k1_context_set_error_callback(tctx, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(tctx, counting_illegal_callback_fn, &ecount); + CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); + + /* Check all NULLs are detected */ + CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdh(tctx, res, NULL, s_one) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdh(tctx, res, &point, NULL) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); + CHECK(ecount == 3); + + /* Cleanup */ + secp256k1_context_destroy(tctx); +} + +void test_ecdh_generator_basepoint(void) { + unsigned char s_one[32] = { 0 }; + secp256k1_pubkey point[2]; + int i; + + s_one[31] = 1; + /* Check against pubkey creation when the basepoint is the generator */ + for (i = 0; i < 100; ++i) { + secp256k1_sha256 sha; + unsigned char s_b32[32]; + unsigned char output_ecdh[32]; + unsigned char output_ser[32]; + unsigned char point_ser[33]; + size_t point_ser_len = sizeof(point_ser); + secp256k1_scalar s; + + random_scalar_order(&s); + secp256k1_scalar_get_b32(s_b32, &s); + + /* compute using ECDH function */ + CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); + CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); + /* compute "explicitly" */ + CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); + CHECK(point_ser_len == sizeof(point_ser)); + secp256k1_sha256_initialize(&sha); + secp256k1_sha256_write(&sha, point_ser, point_ser_len); + secp256k1_sha256_finalize(&sha, output_ser); + /* compare */ + CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); + } +} + +void test_bad_scalar(void) { + unsigned char s_zero[32] = { 0 }; + unsigned char s_overflow[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 + }; + unsigned char s_rand[32] = { 0 }; + unsigned char output[32]; + secp256k1_scalar rand; + secp256k1_pubkey point; + + /* Create random point */ + random_scalar_order(&rand); + secp256k1_scalar_get_b32(s_rand, &rand); + CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); + + /* Try to multiply it by bad values */ + CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); + /* ...and a good one */ + s_overflow[31] -= 1; + CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); +} + +void run_ecdh_tests(void) { + test_ecdh_api(); + test_ecdh_generator_basepoint(); + test_bad_scalar(); +} + +#endif /* SECP256K1_MODULE_ECDH_TESTS_H */ diff --git a/src/secp256k1/src/modules/recovery/Makefile.am.include b/src/secp256k1/src/modules/recovery/Makefile.am.include new file mode 100644 index 000000000..bf23c26e7 --- /dev/null +++ b/src/secp256k1/src/modules/recovery/Makefile.am.include @@ -0,0 +1,8 @@ +include_HEADERS += include/secp256k1_recovery.h +noinst_HEADERS += src/modules/recovery/main_impl.h +noinst_HEADERS += src/modules/recovery/tests_impl.h +if USE_BENCHMARK +noinst_PROGRAMS += bench_recover +bench_recover_SOURCES = src/bench_recover.c +bench_recover_LDADD = libsecp256k1.la $(SECP_LIBS) $(COMMON_LIB) +endif diff --git a/src/secp256k1/src/modules/recovery/main_impl.h b/src/secp256k1/src/modules/recovery/main_impl.h new file mode 100755 index 000000000..2f6691c5a --- /dev/null +++ b/src/secp256k1/src/modules/recovery/main_impl.h @@ -0,0 +1,193 @@ +/********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_RECOVERY_MAIN_H +#define SECP256K1_MODULE_RECOVERY_MAIN_H + +#include "include/secp256k1_recovery.h" + +static void secp256k1_ecdsa_recoverable_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, int* recid, const secp256k1_ecdsa_recoverable_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } + *recid = sig->data[64]; +} + +static void secp256k1_ecdsa_recoverable_signature_save(secp256k1_ecdsa_recoverable_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s, int recid) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } + sig->data[64] = recid; +} + +int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature* sig, const unsigned char *input64, int recid) { + secp256k1_scalar r, s; + int ret = 1; + int overflow = 0; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + ARG_CHECK(recid >= 0 && recid <= 3); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_recoverable_signature_save(sig, &r, &s, recid); + } else { + memset(sig, 0, sizeof(*sig)); + } + return ret; +} + +int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature* sig) { + secp256k1_scalar r, s; + + (void)ctx; + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(recid != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, recid, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const secp256k1_ecdsa_recoverable_signature* sigin) { + secp256k1_scalar r, s; + int recid; + + (void)ctx; + ARG_CHECK(sig != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, sigin); + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; +} + +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context *ctx, const secp256k1_scalar *sigr, const secp256k1_scalar* sigs, secp256k1_ge *pubkey, const secp256k1_scalar *message, int recid) { + unsigned char brx[32]; + secp256k1_fe fx; + secp256k1_ge x; + secp256k1_gej xj; + secp256k1_scalar rn, u1, u2; + secp256k1_gej qj; + int r; + + if (secp256k1_scalar_is_zero(sigr) || secp256k1_scalar_is_zero(sigs)) { + return 0; + } + + secp256k1_scalar_get_b32(brx, sigr); + r = secp256k1_fe_set_b32(&fx, brx); + (void)r; + VERIFY_CHECK(r); /* brx comes from a scalar, so is less than the order; certainly less than p */ + if (recid & 2) { + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0) { + return 0; + } + secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe); + } + if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1)) { + return 0; + } + secp256k1_gej_set_ge(&xj, &x); + secp256k1_scalar_inverse_var(&rn, sigr); + secp256k1_scalar_mul(&u1, &rn, message); + secp256k1_scalar_negate(&u1, &u1); + secp256k1_scalar_mul(&u2, &rn, sigs); + secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1); + secp256k1_ge_set_gej_var(pubkey, &qj); + return !secp256k1_gej_is_infinity(&qj); +} + +int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + secp256k1_scalar sec, non, msg; + int recid; + int ret = 0; + int overflow = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); + if (noncefp == NULL) { + noncefp = secp256k1_nonce_function_default; + } + + secp256k1_scalar_set_b32(&sec, seckey, &overflow); + /* Fail if the secret key is invalid. */ + if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; + unsigned int count = 0; + secp256k1_scalar_set_b32(&msg, msg32, NULL); + while (1) { + ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); + if (!ret) { + break; + } + secp256k1_scalar_set_b32(&non, nonce32, &overflow); + if (!secp256k1_scalar_is_zero(&non) && !overflow) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, &recid)) { + break; + } + } + count++; + } + memset(nonce32, 0, 32); + secp256k1_scalar_clear(&msg); + secp256k1_scalar_clear(&non); + secp256k1_scalar_clear(&sec); + } + if (ret) { + secp256k1_ecdsa_recoverable_signature_save(signature, &r, &s, recid); + } else { + memset(signature, 0, sizeof(*signature)); + } + return ret; +} + +int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *signature, const unsigned char *msg32) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + int recid; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(pubkey != NULL); + + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, signature); + VERIFY_CHECK(recid >= 0 && recid < 4); /* should have been caught in parse_compact */ + secp256k1_scalar_set_b32(&m, msg32, NULL); + if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &r, &s, &q, &m, recid)) { + secp256k1_pubkey_save(pubkey, &q); + return 1; + } else { + memset(pubkey, 0, sizeof(*pubkey)); + return 0; + } +} + +#endif /* SECP256K1_MODULE_RECOVERY_MAIN_H */ diff --git a/src/secp256k1/src/modules/recovery/tests_impl.h b/src/secp256k1/src/modules/recovery/tests_impl.h new file mode 100644 index 000000000..5c9bbe861 --- /dev/null +++ b/src/secp256k1/src/modules/recovery/tests_impl.h @@ -0,0 +1,393 @@ +/********************************************************************** + * Copyright (c) 2013-2015 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_MODULE_RECOVERY_TESTS_H +#define SECP256K1_MODULE_RECOVERY_TESTS_H + +static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { + (void) msg32; + (void) key32; + (void) algo16; + (void) data; + + /* On the first run, return 0 to force a second run */ + if (counter == 0) { + memset(nonce32, 0, 32); + return 1; + } + /* On the second run, return an overflow to force a third run */ + if (counter == 1) { + memset(nonce32, 0xff, 32); + return 1; + } + /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */ + memset(nonce32, 1, 32); + return secp256k1_rand_bits(1); +} + +void test_ecdsa_recovery_api(void) { + /* Setup contexts that just count errors */ + secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pubkey pubkey; + secp256k1_pubkey recpubkey; + secp256k1_ecdsa_signature normal_sig; + secp256k1_ecdsa_recoverable_signature recsig; + unsigned char privkey[32] = { 1 }; + unsigned char message[32] = { 2 }; + int32_t ecount = 0; + int recid = 0; + unsigned char sig[74]; + unsigned char zero_privkey[32] = { 0 }; + unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(both, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(both, counting_illegal_callback_fn, &ecount); + + /* Construct and verify corresponding public key. */ + CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Check bad contexts and NULLs for signing */ + ecount = 0; + CHECK(secp256k1_ecdsa_sign_recoverable(none, &recsig, message, privkey, NULL, NULL) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(sign, &recsig, message, privkey, NULL, NULL) == 1); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(vrfy, &recsig, message, privkey, NULL, NULL) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_sign_recoverable(both, NULL, message, privkey, NULL, NULL) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, NULL, privkey, NULL, NULL) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, NULL, NULL, NULL) == 0); + CHECK(ecount == 5); + /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */ + secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, recovery_test_nonce_function, NULL); + CHECK(ecount == 5); + /* These will all fail, but not in ARG_CHECK way */ + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, zero_privkey, NULL, NULL) == 0); + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, over_privkey, NULL, NULL) == 0); + /* This one will succeed. */ + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); + CHECK(ecount == 5); + + /* Check signing with a goofy nonce function */ + + /* Check bad contexts and NULLs for recovery */ + ecount = 0; + CHECK(secp256k1_ecdsa_recover(none, &recpubkey, &recsig, message) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_recover(sign, &recpubkey, &recsig, message) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_recover(vrfy, &recpubkey, &recsig, message) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, message) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_recover(both, NULL, &recsig, message) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_recover(both, &recpubkey, NULL, message) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_recover(both, &recpubkey, &recsig, NULL) == 0); + CHECK(ecount == 5); + + /* Check NULLs for conversion */ + CHECK(secp256k1_ecdsa_sign(both, &normal_sig, message, privkey, NULL, NULL) == 1); + ecount = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, NULL, &recsig) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, NULL) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(both, &normal_sig, &recsig) == 1); + + /* Check NULLs for de/serialization */ + CHECK(secp256k1_ecdsa_sign_recoverable(both, &recsig, message, privkey, NULL, NULL) == 1); + ecount = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, NULL, &recid, &recsig) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, NULL, &recsig) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, NULL) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(both, sig, &recid, &recsig) == 1); + + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, NULL, sig, recid) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, NULL, recid) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, -1) == 0); + CHECK(ecount == 6); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, 5) == 0); + CHECK(ecount == 7); + /* overflow in signature will fail but not affect ecount */ + memcpy(sig, over_privkey, 32); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(both, &recsig, sig, recid) == 0); + CHECK(ecount == 7); + + /* cleanup */ + secp256k1_context_destroy(none); + secp256k1_context_destroy(sign); + secp256k1_context_destroy(vrfy); + secp256k1_context_destroy(both); +} + +void test_ecdsa_recovery_end_to_end(void) { + unsigned char extra[32] = {0x00}; + unsigned char privkey[32]; + unsigned char message[32]; + secp256k1_ecdsa_signature signature[5]; + secp256k1_ecdsa_recoverable_signature rsignature[5]; + unsigned char sig[74]; + secp256k1_pubkey pubkey; + secp256k1_pubkey recpubkey; + int recid = 0; + + /* Generate a random key and message. */ + { + secp256k1_scalar msg, key; + random_scalar_order_test(&msg); + random_scalar_order_test(&key); + secp256k1_scalar_get_b32(privkey, &key); + secp256k1_scalar_get_b32(message, &msg); + } + + /* Construct and verify corresponding public key. */ + CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Serialize/parse compact and verify/recover. */ + extra[0] = 0; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1); + extra[31] = 1; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1); + extra[31] = 0; + extra[0] = 1; + CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(memcmp(&signature[4], &signature[0], 64) == 0); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + memset(&rsignature[4], 0, sizeof(rsignature[4])); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1); + /* Parse compact (with recovery id) and recover. */ + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1); + CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0); + /* Serialize/destroy/parse signature and verify again. */ + CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1); + sig[secp256k1_rand_bits(6)] += 1 + secp256k1_rand_int(255); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1); + CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0); + /* Recover again */ + CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 || + memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0); +} + +/* Tests several edge cases. */ +void test_ecdsa_recovery_edge_cases(void) { + const unsigned char msg32[32] = { + 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', + 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', + 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', + 's', 's', 'a', 'g', 'e', '.', '.', '.' + }; + const unsigned char sig64[64] = { + /* Generated by signing the above message with nonce 'This is the nonce we will use...' + * and secret key 0 (which is not valid), resulting in recid 0. */ + 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, + 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, + 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, + 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, + 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, + 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, + 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, + 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 + }; + secp256k1_pubkey pubkey; + /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ + const unsigned char sigb64[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + secp256k1_pubkey pubkeyb; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + int recid; + + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1)); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3)); + CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32)); + + for (recid = 0; recid < 4; recid++) { + int i; + int recid2; + /* (4,4) encoded in DER. */ + unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; + unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; + unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; + unsigned char sigbderalt1[39] = { + 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt2[39] = { + 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + unsigned char sigbderalt3[40] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, + }; + unsigned char sigbderalt4[40] = { + 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }; + /* (order + r,4) encoded in DER. */ + unsigned char sigbderlong[40] = { + 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, + 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, + 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 + }; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1); + for (recid2 = 0; recid2 < 4; recid2++) { + secp256k1_pubkey pubkey2b; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1); + /* Verifying with (order + r,4) should always fail. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + } + /* DER parsing tests. */ + /* Zero length r/s. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0); + /* Leading zeros. */ + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0); + sigbderalt3[4] = 1; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + sigbderalt4[7] = 1; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + /* Damage signature. */ + sigbder[7]++; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + sigbder[7]--; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0); + for(i = 0; i < 8; i++) { + int c; + unsigned char orig = sigbder[i]; + /*Try every single-byte change.*/ + for (c = 0; c < 256; c++) { + if (c == orig ) { + continue; + } + sigbder[i] = c; + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0); + } + sigbder[i] = orig; + } + } + + /* Test r/s equal to zero */ + { + /* (1,1) encoded in DER. */ + unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; + unsigned char sigc64[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }; + secp256k1_pubkey pubkeyc; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1); + sigcder[4] = 0; + sigc64[31] = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + sigcder[4] = 1; + sigcder[7] = 0; + sigc64[31] = 1; + sigc64[63] = 0; + CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1); + CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0); + } +} + +void run_recovery_tests(void) { + int i; + for (i = 0; i < count; i++) { + test_ecdsa_recovery_api(); + } + for (i = 0; i < 64*count; i++) { + test_ecdsa_recovery_end_to_end(); + } + test_ecdsa_recovery_edge_cases(); +} + +#endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */ diff --git a/src/secp256k1/src/num.h b/src/secp256k1/src/num.h index 339b6bb6e..49f2dd791 100644 --- a/src/secp256k1/src/num.h +++ b/src/secp256k1/src/num.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_NUM_ -#define _SECP256K1_NUM_ +#ifndef SECP256K1_NUM_H +#define SECP256K1_NUM_H #ifndef USE_NUM_NONE @@ -20,49 +20,55 @@ #endif /** Copy a number. */ -static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a); +static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); /** Convert a number's absolute value to a binary big-endian string. * There must be enough place. */ -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a); +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); /** Set a number to the value of a binary big-endian string. */ -static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen); +static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); /** Compute a modular inverse. The input must be less than the modulus. */ -static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m); +static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); + +/** Compute the jacobi symbol (a|b). b must be positive and odd. */ +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); /** Compare the absolute value of two numbers. */ -static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b); +static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); /** Test whether two number are equal (including sign). */ -static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b); +static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); /** Add two (signed) numbers. */ -static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); /** Subtract two (signed) numbers. */ -static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); /** Multiply two (signed) numbers. */ -static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); +static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, even if r was negative. */ -static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m); +static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); /** Right-shift the passed number by bits bits. */ -static void secp256k1_num_shift(secp256k1_num_t *r, int bits); +static void secp256k1_num_shift(secp256k1_num *r, int bits); /** Check whether a number is zero. */ -static int secp256k1_num_is_zero(const secp256k1_num_t *a); +static int secp256k1_num_is_zero(const secp256k1_num *a); + +/** Check whether a number is one. */ +static int secp256k1_num_is_one(const secp256k1_num *a); /** Check whether a number is strictly negative. */ -static int secp256k1_num_is_neg(const secp256k1_num_t *a); +static int secp256k1_num_is_neg(const secp256k1_num *a); /** Change a number's sign. */ -static void secp256k1_num_negate(secp256k1_num_t *r); +static void secp256k1_num_negate(secp256k1_num *r); #endif -#endif +#endif /* SECP256K1_NUM_H */ diff --git a/src/secp256k1/src/num_gmp.h b/src/secp256k1/src/num_gmp.h index baa1f2bf2..3619844bd 100644 --- a/src/secp256k1/src/num_gmp.h +++ b/src/secp256k1/src/num_gmp.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_NUM_REPR_ -#define _SECP256K1_NUM_REPR_ +#ifndef SECP256K1_NUM_REPR_H +#define SECP256K1_NUM_REPR_H #include @@ -15,6 +15,6 @@ typedef struct { mp_limb_t data[2*NUM_LIMBS]; int neg; int limbs; -} secp256k1_num_t; +} secp256k1_num; -#endif +#endif /* SECP256K1_NUM_REPR_H */ diff --git a/src/secp256k1/src/num_gmp_impl.h b/src/secp256k1/src/num_gmp_impl.h index dbbc458d5..0ae2a8ba0 100644 --- a/src/secp256k1/src/num_gmp_impl.h +++ b/src/secp256k1/src/num_gmp_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_NUM_REPR_IMPL_H_ -#define _SECP256K1_NUM_REPR_IMPL_H_ +#ifndef SECP256K1_NUM_REPR_IMPL_H +#define SECP256K1_NUM_REPR_IMPL_H #include #include @@ -15,18 +15,18 @@ #include "num.h" #ifdef VERIFY -static void secp256k1_num_sanity(const secp256k1_num_t *a) { +static void secp256k1_num_sanity(const secp256k1_num *a) { VERIFY_CHECK(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); } #else #define secp256k1_num_sanity(a) do { } while(0) #endif -static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) { +static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a) { *r = *a; } -static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { +static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a) { unsigned char tmp[65]; int len = 0; int shift = 0; @@ -42,7 +42,7 @@ static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec memset(tmp, 0, sizeof(tmp)); } -static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { +static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen) { int len; VERIFY_CHECK(alen > 0); VERIFY_CHECK(alen <= 64); @@ -59,7 +59,7 @@ static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, un } } -static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_add_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); r->limbs = a->limbs; if (c != 0) { @@ -68,8 +68,9 @@ static void secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, } } -static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_sub_abs(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); + (void)c; VERIFY_CHECK(c == 0); r->limbs = a->limbs; while (r->limbs > 1 && r->data[r->limbs-1]==0) { @@ -77,7 +78,7 @@ static void secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, } } -static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { +static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m) { secp256k1_num_sanity(r); secp256k1_num_sanity(m); @@ -97,7 +98,7 @@ static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { } } -static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { +static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m) { int i; mp_limb_t g[NUM_LIMBS+1]; mp_limb_t u[NUM_LIMBS+1]; @@ -125,6 +126,7 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t } sn = NUM_LIMBS+1; gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); + (void)gn; VERIFY_CHECK(gn == 1); VERIFY_CHECK(g[0] == 1); r->neg = a->neg ^ m->neg; @@ -142,15 +144,41 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t memset(v, 0, sizeof(v)); } -static int secp256k1_num_is_zero(const secp256k1_num_t *a) { +static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b) { + int ret; + mpz_t ga, gb; + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + VERIFY_CHECK(!b->neg && (b->limbs > 0) && (b->data[0] & 1)); + + mpz_inits(ga, gb, NULL); + + mpz_import(gb, b->limbs, -1, sizeof(mp_limb_t), 0, 0, b->data); + mpz_import(ga, a->limbs, -1, sizeof(mp_limb_t), 0, 0, a->data); + if (a->neg) { + mpz_neg(ga, ga); + } + + ret = mpz_jacobi(ga, gb); + + mpz_clears(ga, gb, NULL); + + return ret; +} + +static int secp256k1_num_is_one(const secp256k1_num *a) { + return (a->limbs == 1 && a->data[0] == 1); +} + +static int secp256k1_num_is_zero(const secp256k1_num *a) { return (a->limbs == 1 && a->data[0] == 0); } -static int secp256k1_num_is_neg(const secp256k1_num_t *a) { +static int secp256k1_num_is_neg(const secp256k1_num *a) { return (a->limbs > 1 || a->data[0] != 0) && a->neg; } -static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) { +static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b) { if (a->limbs > b->limbs) { return 1; } @@ -160,7 +188,7 @@ static int secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) return mpn_cmp(a->data, b->data, a->limbs); } -static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) { +static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b) { if (a->limbs > b->limbs) { return 0; } @@ -173,7 +201,7 @@ static int secp256k1_num_eq(const secp256k1_num_t *a, const secp256k1_num_t *b) return mpn_cmp(a->data, b->data, a->limbs) == 0; } -static void secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, int bneg) { +static void secp256k1_num_subadd(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b, int bneg) { if (!(b->neg ^ bneg ^ a->neg)) { /* a and b have the same sign */ r->neg = a->neg; if (a->limbs >= b->limbs) { @@ -192,19 +220,19 @@ static void secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, c } } -static void secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { secp256k1_num_sanity(a); secp256k1_num_sanity(b); secp256k1_num_subadd(r, a, b, 0); } -static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { secp256k1_num_sanity(a); secp256k1_num_sanity(b); secp256k1_num_subadd(r, a, b, 1); } -static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b) { mp_limb_t tmp[2*NUM_LIMBS+1]; secp256k1_num_sanity(a); secp256k1_num_sanity(b); @@ -231,13 +259,13 @@ static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons memset(tmp, 0, sizeof(tmp)); } -static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { - int i; +static void secp256k1_num_shift(secp256k1_num *r, int bits) { if (bits % GMP_NUMB_BITS) { /* Shift within limbs. */ mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS); } if (bits >= GMP_NUMB_BITS) { + int i; /* Shift full limbs. */ for (i = 0; i < r->limbs; i++) { int index = i + (bits / GMP_NUMB_BITS); @@ -253,8 +281,8 @@ static void secp256k1_num_shift(secp256k1_num_t *r, int bits) { } } -static void secp256k1_num_negate(secp256k1_num_t *r) { +static void secp256k1_num_negate(secp256k1_num *r) { r->neg ^= 1; } -#endif +#endif /* SECP256K1_NUM_REPR_IMPL_H */ diff --git a/src/secp256k1/src/num_impl.h b/src/secp256k1/src/num_impl.h index 0b0e3a072..c45193b03 100644 --- a/src/secp256k1/src/num_impl.h +++ b/src/secp256k1/src/num_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_NUM_IMPL_H_ -#define _SECP256K1_NUM_IMPL_H_ +#ifndef SECP256K1_NUM_IMPL_H +#define SECP256K1_NUM_IMPL_H #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" @@ -21,4 +21,4 @@ #error "Please select num implementation" #endif -#endif +#endif /* SECP256K1_NUM_IMPL_H */ diff --git a/src/secp256k1/src/scalar.h b/src/secp256k1/src/scalar.h index f5d09f8d4..59304cb66 100644 --- a/src/secp256k1/src/scalar.h +++ b/src/secp256k1/src/scalar.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_ -#define _SECP256K1_SCALAR_ +#ifndef SECP256K1_SCALAR_H +#define SECP256K1_SCALAR_H #include "num.h" @@ -13,7 +13,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32.h" @@ -22,72 +24,83 @@ #endif /** Clear a scalar to prevent the leak of sensitive data. */ -static void secp256k1_scalar_clear(secp256k1_scalar_t *r); +static void secp256k1_scalar_clear(secp256k1_scalar *r); /** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ -static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count); +static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); /** Access bits from a scalar. Not constant time. */ -static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count); +static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); /** Set a scalar from a big endian byte array. */ -static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *bin, int *overflow); +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); /** Set a scalar to an unsigned integer. */ -static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v); +static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); /** Convert a scalar to a byte array. */ -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a); +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); /** Add two scalars together (modulo the group order). Returns whether it overflowed. */ -static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); -/** Add a power of two to a scalar. The result is not allowed to overflow. */ -static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit); +/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); /** Multiply two scalars (modulo the group order). */ -static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); + +/** Shift a scalar right by some amount strictly between 0 and 16, returning + * the low bits that were shifted off */ +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); /** Compute the square of a scalar (modulo the group order). */ -static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); /** Compute the inverse of a scalar (modulo the group order). */ -static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); /** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ -static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); /** Compute the complement of a scalar (modulo the group order). */ -static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); /** Check whether a scalar equals zero. */ -static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a); +static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); /** Check whether a scalar equals one. */ -static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a); +static int secp256k1_scalar_is_one(const secp256k1_scalar *a); + +/** Check whether a scalar, considered as an nonnegative integer, is even. */ +static int secp256k1_scalar_is_even(const secp256k1_scalar *a); /** Check whether a scalar is higher than the group order divided by 2. */ -static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a); +static int secp256k1_scalar_is_high(const secp256k1_scalar *a); + +/** Conditionally negate a number, in constant time. + * Returns -1 if the number was negated, 1 otherwise */ +static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); #ifndef USE_NUM_NONE /** Convert a scalar to a number. */ -static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a); +static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); /** Get the order of the group as a number. */ -static void secp256k1_scalar_order_get_num(secp256k1_num_t *r); +static void secp256k1_scalar_order_get_num(secp256k1_num *r); #endif /** Compare two scalars. */ -static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); +static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); #ifdef USE_ENDOMORPHISM /** Find r1 and r2 such that r1+r2*2^128 = a. */ -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); /** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ -static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); #endif /** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ -static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift); +static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); -#endif +#endif /* SECP256K1_SCALAR_H */ diff --git a/src/secp256k1/src/scalar_4x64.h b/src/secp256k1/src/scalar_4x64.h index 82899aa7b..19c7495d1 100644 --- a/src/secp256k1/src/scalar_4x64.h +++ b/src/secp256k1/src/scalar_4x64.h @@ -4,16 +4,16 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_ -#define _SECP256K1_SCALAR_REPR_ +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H #include /** A scalar modulo the group order of the secp256k1 curve. */ typedef struct { uint64_t d[4]; -} secp256k1_scalar_t; +} secp256k1_scalar; #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} -#endif +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/src/secp256k1/src/scalar_4x64_impl.h b/src/secp256k1/src/scalar_4x64_impl.h index ff365292f..db1ebf94b 100644 --- a/src/secp256k1/src/scalar_4x64_impl.h +++ b/src/secp256k1/src/scalar_4x64_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ -#define _SECP256K1_SCALAR_REPR_IMPL_H_ +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H /* Limbs of the secp256k1 order. */ #define SECP256K1_N_0 ((uint64_t)0xBFD25E8CD0364141ULL) @@ -24,26 +24,26 @@ #define SECP256K1_N_H_2 ((uint64_t)0xFFFFFFFFFFFFFFFFULL) #define SECP256K1_N_H_3 ((uint64_t)0x7FFFFFFFFFFFFFFFULL) -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { r->d[0] = 0; r->d[1] = 0; r->d[2] = 0; r->d[3] = 0; } -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) { +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { r->d[0] = v; r->d[1] = 0; r->d[2] = 0; r->d[3] = 0; } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK((offset + count - 1) >> 6 == offset >> 6); return (a->d[offset >> 6] >> (offset & 0x3F)) & ((((uint64_t)1) << count) - 1); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK(count < 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 6 == offset >> 6) { @@ -54,7 +54,7 @@ SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256 } } -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[3] < SECP256K1_N_3); /* No need for a > check. */ @@ -66,7 +66,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal return yes; } -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsigned int overflow) { +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, unsigned int overflow) { uint128_t t; VERIFY_CHECK(overflow <= 1); t = (uint128_t)r->d[0] + overflow * SECP256K1_N_C_0; @@ -80,7 +80,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, unsig return overflow; } -static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; uint128_t t = (uint128_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; @@ -96,9 +96,10 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t return overflow; } -static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { uint128_t t; VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */ t = (uint128_t)r->d[0] + (((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F)); r->d[0] = t & 0xFFFFFFFFFFFFFFFFULL; t >>= 64; t += (uint128_t)r->d[1] + (((uint64_t)((bit >> 6) == 1)) << (bit & 0x3F)); @@ -113,7 +114,7 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { #endif } -static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; r->d[0] = (uint64_t)b32[31] | (uint64_t)b32[30] << 8 | (uint64_t)b32[29] << 16 | (uint64_t)b32[28] << 24 | (uint64_t)b32[27] << 32 | (uint64_t)b32[26] << 40 | (uint64_t)b32[25] << 48 | (uint64_t)b32[24] << 56; r->d[1] = (uint64_t)b32[23] | (uint64_t)b32[22] << 8 | (uint64_t)b32[21] << 16 | (uint64_t)b32[20] << 24 | (uint64_t)b32[19] << 32 | (uint64_t)b32[18] << 40 | (uint64_t)b32[17] << 48 | (uint64_t)b32[16] << 56; @@ -125,18 +126,18 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char } } -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { bin[0] = a->d[3] >> 56; bin[1] = a->d[3] >> 48; bin[2] = a->d[3] >> 40; bin[3] = a->d[3] >> 32; bin[4] = a->d[3] >> 24; bin[5] = a->d[3] >> 16; bin[6] = a->d[3] >> 8; bin[7] = a->d[3]; bin[8] = a->d[2] >> 56; bin[9] = a->d[2] >> 48; bin[10] = a->d[2] >> 40; bin[11] = a->d[2] >> 32; bin[12] = a->d[2] >> 24; bin[13] = a->d[2] >> 16; bin[14] = a->d[2] >> 8; bin[15] = a->d[2]; bin[16] = a->d[1] >> 56; bin[17] = a->d[1] >> 48; bin[18] = a->d[1] >> 40; bin[19] = a->d[1] >> 32; bin[20] = a->d[1] >> 24; bin[21] = a->d[1] >> 16; bin[22] = a->d[1] >> 8; bin[23] = a->d[1]; bin[24] = a->d[0] >> 56; bin[25] = a->d[0] >> 48; bin[26] = a->d[0] >> 40; bin[27] = a->d[0] >> 32; bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; } -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { return (a->d[0] | a->d[1] | a->d[2] | a->d[3]) == 0; } -static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { uint64_t nonzero = 0xFFFFFFFFFFFFFFFFULL * (secp256k1_scalar_is_zero(a) == 0); uint128_t t = (uint128_t)(~a->d[0]) + SECP256K1_N_0 + 1; r->d[0] = t & nonzero; t >>= 64; @@ -148,11 +149,11 @@ static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scala r->d[3] = t & nonzero; } -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3]) == 0; } -static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[3] < SECP256K1_N_H_3); @@ -164,6 +165,22 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { return yes; } +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint64_t mask = !flag - 1; + uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1; + uint128_t t = (uint128_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 64; + t += (uint128_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; + return 2 * (mask == 0) - 1; +} + /* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ /** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ @@ -250,7 +267,7 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { VERIFY_CHECK(c2 == 0); \ } -static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l) { +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint64_t *l) { #ifdef USE_ASM_X86_64 /* Reduce 512 bits into 385. */ uint64_t m0, m1, m2, m3, m4, m5, m6; @@ -265,8 +282,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "movq 56(%%rsi), %%r14\n" /* Initialize r8,r9,r10 */ "movq 0(%%rsi), %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += n0 * c0 */ "movq %8, %%rax\n" "mulq %%r11\n" @@ -274,7 +291,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq %%rdx, %%r9\n" /* extract m0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += l1 */ "addq 8(%%rsi), %%r9\n" "adcq $0, %%r10\n" @@ -292,7 +309,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq $0, %%r8\n" /* extract m1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += l2 */ "addq 16(%%rsi), %%r10\n" "adcq $0, %%r8\n" @@ -315,7 +332,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq $0, %%r9\n" /* extract m2 */ "movq %%r10, %q2\n" - "movq $0, %%r10\n" + "xorq %%r10, %%r10\n" /* (r8,r9,r10) += l3 */ "addq 24(%%rsi), %%r8\n" "adcq $0, %%r9\n" @@ -338,7 +355,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq $0, %%r10\n" /* extract m3 */ "movq %%r8, %q3\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10,r8) += n3 * c1 */ "movq %9, %%rax\n" "mulq %%r14\n" @@ -370,8 +387,8 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "movq %q11, %%r13\n" /* Initialize (r8,r9,r10) */ "movq %q5, %%r8\n" - "movq $0, %%r9\n" - "movq $0, %%r10\n" + "xorq %%r9, %%r9\n" + "xorq %%r10, %%r10\n" /* (r8,r9) += m4 * c0 */ "movq %12, %%rax\n" "mulq %%r11\n" @@ -379,7 +396,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq %%rdx, %%r9\n" /* extract p0 */ "movq %%r8, %q0\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r10) += m1 */ "addq %q6, %%r9\n" "adcq $0, %%r10\n" @@ -397,7 +414,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq $0, %%r8\n" /* extract p1 */ "movq %%r9, %q1\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r10,r8,r9) += m2 */ "addq %q7, %%r10\n" "adcq $0, %%r8\n" @@ -455,7 +472,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "movq %%rax, 0(%q6)\n" /* Move to (r8,r9) */ "movq %%rdx, %%r8\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p1 */ "addq %q2, %%r8\n" "adcq $0, %%r9\n" @@ -466,7 +483,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq %%rdx, %%r9\n" /* Extract r1 */ "movq %%r8, 8(%q6)\n" - "movq $0, %%r8\n" + "xorq %%r8, %%r8\n" /* (r9,r8) += p4 */ "addq %%r10, %%r9\n" "adcq $0, %%r8\n" @@ -475,7 +492,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l "adcq $0, %%r8\n" /* Extract r2 */ "movq %%r9, 16(%q6)\n" - "movq $0, %%r9\n" + "xorq %%r9, %%r9\n" /* (r8,r9) += p3 */ "addq %q4, %%r8\n" "adcq $0, %%r9\n" @@ -559,7 +576,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint64_t *l secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } -static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar *a, const secp256k1_scalar *b) { #ifdef USE_ASM_X86_64 const uint64_t *pb = b->d; __asm__ __volatile__( @@ -721,12 +738,12 @@ static void secp256k1_scalar_mul_512(uint64_t l[8], const secp256k1_scalar_t *a, extract(l[5]); muladd_fast(a->d[3], b->d[3]); extract_fast(l[6]); - VERIFY_CHECK(c1 <= 0); + VERIFY_CHECK(c1 == 0); l[7] = c0; #endif } -static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) { +static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar *a) { #ifdef USE_ASM_X86_64 __asm__ __volatile__( /* Preload */ @@ -871,19 +888,32 @@ static void secp256k1_scalar_sqr_512(uint64_t l[8], const secp256k1_scalar_t *a) #undef extract #undef extract_fast -static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { uint64_t l[8]; secp256k1_scalar_mul_512(l, a, b); secp256k1_scalar_reduce_512(r, l); } -static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (64 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (64 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (64 - n)); + r->d[3] = (r->d[3] >> n); + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { uint64_t l[8]; secp256k1_scalar_sqr_512(l, a); secp256k1_scalar_reduce_512(r, l); } -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { +#ifdef USE_ENDOMORPHISM +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { r1->d[0] = a->d[0]; r1->d[1] = a->d[1]; r1->d[2] = 0; @@ -893,12 +923,13 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ r2->d[2] = 0; r2->d[3] = 0; } +#endif -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; } -SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { uint64_t l[8]; unsigned int shiftlimbs; unsigned int shiftlow; @@ -912,9 +943,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t * r->d[1] = shift < 448 ? (l[1 + shiftlimbs] >> shiftlow | (shift < 384 && shiftlow ? (l[2 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[2] = shift < 384 ? (l[2 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[3 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[3] = shift < 320 ? (l[3 + shiftlimbs] >> shiftlow) : 0; - if ((l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1) { - secp256k1_scalar_add_bit(r, 0); - } + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 6] >> ((shift - 1) & 0x3f)) & 1); } -#endif +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/src/secp256k1/src/scalar_8x32.h b/src/secp256k1/src/scalar_8x32.h index f17017e24..2c9a348e2 100644 --- a/src/secp256k1/src/scalar_8x32.h +++ b/src/secp256k1/src/scalar_8x32.h @@ -4,16 +4,16 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_ -#define _SECP256K1_SCALAR_REPR_ +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H #include /** A scalar modulo the group order of the secp256k1 curve. */ typedef struct { uint32_t d[8]; -} secp256k1_scalar_t; +} secp256k1_scalar; #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} -#endif +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/src/secp256k1/src/scalar_8x32_impl.h b/src/secp256k1/src/scalar_8x32_impl.h index 22b31d411..4f9ed61fe 100644 --- a/src/secp256k1/src/scalar_8x32_impl.h +++ b/src/secp256k1/src/scalar_8x32_impl.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_REPR_IMPL_H_ -#define _SECP256K1_SCALAR_REPR_IMPL_H_ +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H /* Limbs of the secp256k1 order. */ #define SECP256K1_N_0 ((uint32_t)0xD0364141UL) @@ -34,7 +34,7 @@ #define SECP256K1_N_H_6 ((uint32_t)0xFFFFFFFFUL) #define SECP256K1_N_H_7 ((uint32_t)0x7FFFFFFFUL) -SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { r->d[0] = 0; r->d[1] = 0; r->d[2] = 0; @@ -45,7 +45,7 @@ SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar_t *r) { r->d[7] = 0; } -SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, unsigned int v) { +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { r->d[0] = v; r->d[1] = 0; r->d[2] = 0; @@ -56,12 +56,12 @@ SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar_t *r, uns r->d[7] = 0; } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK((offset + count - 1) >> 5 == offset >> 5); return (a->d[offset >> 5] >> (offset & 0x1F)) & ((1 << count) - 1); } -SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar_t *a, unsigned int offset, unsigned int count) { +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { VERIFY_CHECK(count < 32); VERIFY_CHECK(offset + count <= 256); if ((offset + count - 1) >> 5 == offset >> 5) { @@ -72,7 +72,7 @@ SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256 } } -SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[7] < SECP256K1_N_7); /* No need for a > check. */ @@ -90,7 +90,7 @@ SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scal return yes; } -SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint32_t overflow) { +SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar *r, uint32_t overflow) { uint64_t t; VERIFY_CHECK(overflow <= 1); t = (uint64_t)r->d[0] + overflow * SECP256K1_N_C_0; @@ -112,7 +112,7 @@ SECP256K1_INLINE static int secp256k1_scalar_reduce(secp256k1_scalar_t *r, uint3 return overflow; } -static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { int overflow; uint64_t t = (uint64_t)a->d[0] + b->d[0]; r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; @@ -136,9 +136,10 @@ static int secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t return overflow; } -static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { uint64_t t; VERIFY_CHECK(bit < 256); + bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */ t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F)); r->d[0] = t & 0xFFFFFFFFULL; t >>= 32; t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F)); @@ -161,7 +162,7 @@ static void secp256k1_scalar_add_bit(secp256k1_scalar_t *r, unsigned int bit) { #endif } -static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char *b32, int *overflow) { +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { int over; r->d[0] = (uint32_t)b32[31] | (uint32_t)b32[30] << 8 | (uint32_t)b32[29] << 16 | (uint32_t)b32[28] << 24; r->d[1] = (uint32_t)b32[27] | (uint32_t)b32[26] << 8 | (uint32_t)b32[25] << 16 | (uint32_t)b32[24] << 24; @@ -177,7 +178,7 @@ static void secp256k1_scalar_set_b32(secp256k1_scalar_t *r, const unsigned char } } -static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_t* a) { +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { bin[0] = a->d[7] >> 24; bin[1] = a->d[7] >> 16; bin[2] = a->d[7] >> 8; bin[3] = a->d[7]; bin[4] = a->d[6] >> 24; bin[5] = a->d[6] >> 16; bin[6] = a->d[6] >> 8; bin[7] = a->d[6]; bin[8] = a->d[5] >> 24; bin[9] = a->d[5] >> 16; bin[10] = a->d[5] >> 8; bin[11] = a->d[5]; @@ -188,11 +189,11 @@ static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar_ bin[28] = a->d[0] >> 24; bin[29] = a->d[0] >> 16; bin[30] = a->d[0] >> 8; bin[31] = a->d[0]; } -SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { return (a->d[0] | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; } -static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(a) == 0); uint64_t t = (uint64_t)(~a->d[0]) + SECP256K1_N_0 + 1; r->d[0] = t & nonzero; t >>= 32; @@ -212,11 +213,11 @@ static void secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scala r->d[7] = t & nonzero; } -SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar_t *a) { +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { return ((a->d[0] ^ 1) | a->d[1] | a->d[2] | a->d[3] | a->d[4] | a->d[5] | a->d[6] | a->d[7]) == 0; } -static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { int yes = 0; int no = 0; no |= (a->d[7] < SECP256K1_N_H_7); @@ -234,6 +235,31 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { return yes; } +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + /* If we are flag = 0, mask = 00...00 and this is a no-op; + * if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */ + uint32_t mask = !flag - 1; + uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0); + uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask); + r->d[0] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[1] ^ mask) + (SECP256K1_N_1 & mask); + r->d[1] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[2] ^ mask) + (SECP256K1_N_2 & mask); + r->d[2] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[3] ^ mask) + (SECP256K1_N_3 & mask); + r->d[3] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[4] ^ mask) + (SECP256K1_N_4 & mask); + r->d[4] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[5] ^ mask) + (SECP256K1_N_5 & mask); + r->d[5] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[6] ^ mask) + (SECP256K1_N_6 & mask); + r->d[6] = t & nonzero; t >>= 32; + t += (uint64_t)(r->d[7] ^ mask) + (SECP256K1_N_7 & mask); + r->d[7] = t & nonzero; + return 2 * (mask == 0) - 1; +} + + /* Inspired by the macros in OpenSSL's crypto/bn/asm/x86_64-gcc.c. */ /** Add a*b to the number defined by (c0,c1,c2). c2 must never overflow. */ @@ -320,7 +346,7 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a) { VERIFY_CHECK(c2 == 0); \ } -static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l) { +static void secp256k1_scalar_reduce_512(secp256k1_scalar *r, const uint32_t *l) { uint64_t c; uint32_t n0 = l[8], n1 = l[9], n2 = l[10], n3 = l[11], n4 = l[12], n5 = l[13], n6 = l[14], n7 = l[15]; uint32_t m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12; @@ -462,7 +488,7 @@ static void secp256k1_scalar_reduce_512(secp256k1_scalar_t *r, const uint32_t *l secp256k1_scalar_reduce(r, c + secp256k1_scalar_check_overflow(r)); } -static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar *a, const secp256k1_scalar *b) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -550,7 +576,7 @@ static void secp256k1_scalar_mul_512(uint32_t *l, const secp256k1_scalar_t *a, c l[15] = c0; } -static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar *a) { /* 96 bit accumulator. */ uint32_t c0 = 0, c1 = 0, c2 = 0; @@ -618,20 +644,36 @@ static void secp256k1_scalar_sqr_512(uint32_t *l, const secp256k1_scalar_t *a) { #undef extract #undef extract_fast -static void secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { uint32_t l[16]; secp256k1_scalar_mul_512(l, a, b); secp256k1_scalar_reduce_512(r, l); } -static void secp256k1_scalar_sqr(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) { +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = r->d[0] & ((1 << n) - 1); + r->d[0] = (r->d[0] >> n) + (r->d[1] << (32 - n)); + r->d[1] = (r->d[1] >> n) + (r->d[2] << (32 - n)); + r->d[2] = (r->d[2] >> n) + (r->d[3] << (32 - n)); + r->d[3] = (r->d[3] >> n) + (r->d[4] << (32 - n)); + r->d[4] = (r->d[4] >> n) + (r->d[5] << (32 - n)); + r->d[5] = (r->d[5] >> n) + (r->d[6] << (32 - n)); + r->d[6] = (r->d[6] >> n) + (r->d[7] << (32 - n)); + r->d[7] = (r->d[7] >> n); + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { uint32_t l[16]; secp256k1_scalar_sqr_512(l, a); secp256k1_scalar_reduce_512(r, l); } #ifdef USE_ENDOMORPHISM -static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { r1->d[0] = a->d[0]; r1->d[1] = a->d[1]; r1->d[2] = a->d[2]; @@ -651,11 +693,11 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ } #endif -SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; } -SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b, unsigned int shift) { +SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift) { uint32_t l[16]; unsigned int shiftlimbs; unsigned int shiftlow; @@ -673,9 +715,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar_t * r->d[5] = shift < 352 ? (l[5 + shiftlimbs] >> shiftlow | (shift < 320 && shiftlow ? (l[6 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[6] = shift < 320 ? (l[6 + shiftlimbs] >> shiftlow | (shift < 288 && shiftlow ? (l[7 + shiftlimbs] << shifthigh) : 0)) : 0; r->d[7] = shift < 288 ? (l[7 + shiftlimbs] >> shiftlow) : 0; - if ((l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1) { - secp256k1_scalar_add_bit(r, 0); - } + secp256k1_scalar_cadd_bit(r, 0, (l[(shift - 1) >> 5] >> ((shift - 1) & 0x1f)) & 1); } -#endif +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/src/secp256k1/src/scalar_impl.h b/src/secp256k1/src/scalar_impl.h index 33824983e..fa790570f 100644 --- a/src/secp256k1/src/scalar_impl.h +++ b/src/secp256k1/src/scalar_impl.h @@ -4,10 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_SCALAR_IMPL_H_ -#define _SECP256K1_SCALAR_IMPL_H_ - -#include +#ifndef SECP256K1_SCALAR_IMPL_H +#define SECP256K1_SCALAR_IMPL_H #include "group.h" #include "scalar.h" @@ -16,7 +14,9 @@ #include "libsecp256k1-config.h" #endif -#if defined(USE_SCALAR_4X64) +#if defined(EXHAUSTIVE_TEST_ORDER) +#include "scalar_low_impl.h" +#elif defined(USE_SCALAR_4X64) #include "scalar_4x64_impl.h" #elif defined(USE_SCALAR_8X32) #include "scalar_8x32_impl.h" @@ -25,109 +25,120 @@ #endif #ifndef USE_NUM_NONE -static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) { +static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a) { unsigned char c[32]; secp256k1_scalar_get_b32(c, a); secp256k1_num_set_bin(r, c, 32); } /** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */ -static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) { +static void secp256k1_scalar_order_get_num(secp256k1_num *r) { +#if defined(EXHAUSTIVE_TEST_ORDER) + static const unsigned char order[32] = { + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,EXHAUSTIVE_TEST_ORDER + }; +#else static const unsigned char order[32] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 }; +#endif secp256k1_num_set_bin(r, order, 32); } #endif -static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { - secp256k1_scalar_t *t; +static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *x) { +#if defined(EXHAUSTIVE_TEST_ORDER) int i; - /* First compute x ^ (2^N - 1) for some values of N. */ - secp256k1_scalar_t x2, x3, x4, x6, x7, x8, x15, x30, x60, x120, x127; + *r = 0; + for (i = 0; i < EXHAUSTIVE_TEST_ORDER; i++) + if ((i * *x) % EXHAUSTIVE_TEST_ORDER == 1) + *r = i; + /* If this VERIFY_CHECK triggers we were given a noninvertible scalar (and thus + * have a composite group order; fix it in exhaustive_tests.c). */ + VERIFY_CHECK(*r != 0); +} +#else + secp256k1_scalar *t; + int i; + /* First compute xN as x ^ (2^N - 1) for some values of N, + * and uM as x ^ M for some values of M. */ + secp256k1_scalar x2, x3, x6, x8, x14, x28, x56, x112, x126; + secp256k1_scalar u2, u5, u9, u11, u13; - secp256k1_scalar_sqr(&x2, x); - secp256k1_scalar_mul(&x2, &x2, x); + secp256k1_scalar_sqr(&u2, x); + secp256k1_scalar_mul(&x2, &u2, x); + secp256k1_scalar_mul(&u5, &u2, &x2); + secp256k1_scalar_mul(&x3, &u5, &u2); + secp256k1_scalar_mul(&u9, &x3, &u2); + secp256k1_scalar_mul(&u11, &u9, &u2); + secp256k1_scalar_mul(&u13, &u11, &u2); - secp256k1_scalar_sqr(&x3, &x2); - secp256k1_scalar_mul(&x3, &x3, x); - - secp256k1_scalar_sqr(&x4, &x3); - secp256k1_scalar_mul(&x4, &x4, x); - - secp256k1_scalar_sqr(&x6, &x4); + secp256k1_scalar_sqr(&x6, &u13); secp256k1_scalar_sqr(&x6, &x6); - secp256k1_scalar_mul(&x6, &x6, &x2); + secp256k1_scalar_mul(&x6, &x6, &u11); - secp256k1_scalar_sqr(&x7, &x6); - secp256k1_scalar_mul(&x7, &x7, x); + secp256k1_scalar_sqr(&x8, &x6); + secp256k1_scalar_sqr(&x8, &x8); + secp256k1_scalar_mul(&x8, &x8, &x2); - secp256k1_scalar_sqr(&x8, &x7); - secp256k1_scalar_mul(&x8, &x8, x); - - secp256k1_scalar_sqr(&x15, &x8); - for (i = 0; i < 6; i++) { - secp256k1_scalar_sqr(&x15, &x15); + secp256k1_scalar_sqr(&x14, &x8); + for (i = 0; i < 5; i++) { + secp256k1_scalar_sqr(&x14, &x14); } - secp256k1_scalar_mul(&x15, &x15, &x7); + secp256k1_scalar_mul(&x14, &x14, &x6); - secp256k1_scalar_sqr(&x30, &x15); - for (i = 0; i < 14; i++) { - secp256k1_scalar_sqr(&x30, &x30); + secp256k1_scalar_sqr(&x28, &x14); + for (i = 0; i < 13; i++) { + secp256k1_scalar_sqr(&x28, &x28); } - secp256k1_scalar_mul(&x30, &x30, &x15); + secp256k1_scalar_mul(&x28, &x28, &x14); - secp256k1_scalar_sqr(&x60, &x30); - for (i = 0; i < 29; i++) { - secp256k1_scalar_sqr(&x60, &x60); + secp256k1_scalar_sqr(&x56, &x28); + for (i = 0; i < 27; i++) { + secp256k1_scalar_sqr(&x56, &x56); } - secp256k1_scalar_mul(&x60, &x60, &x30); + secp256k1_scalar_mul(&x56, &x56, &x28); - secp256k1_scalar_sqr(&x120, &x60); - for (i = 0; i < 59; i++) { - secp256k1_scalar_sqr(&x120, &x120); + secp256k1_scalar_sqr(&x112, &x56); + for (i = 0; i < 55; i++) { + secp256k1_scalar_sqr(&x112, &x112); } - secp256k1_scalar_mul(&x120, &x120, &x60); + secp256k1_scalar_mul(&x112, &x112, &x56); - secp256k1_scalar_sqr(&x127, &x120); - for (i = 0; i < 6; i++) { - secp256k1_scalar_sqr(&x127, &x127); + secp256k1_scalar_sqr(&x126, &x112); + for (i = 0; i < 13; i++) { + secp256k1_scalar_sqr(&x126, &x126); } - secp256k1_scalar_mul(&x127, &x127, &x7); + secp256k1_scalar_mul(&x126, &x126, &x14); - /* Then accumulate the final result (t starts at x127). */ - t = &x127; - for (i = 0; i < 2; i++) { /* 0 */ + /* Then accumulate the final result (t starts at x126). */ + t = &x126; + for (i = 0; i < 3; i++) { secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ + secp256k1_scalar_mul(t, t, &u5); /* 101 */ for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 3; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u5); /* 101 */ + for (i = 0; i < 5; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ + secp256k1_scalar_mul(t, t, &u11); /* 1011 */ + for (i = 0; i < 4; i++) { + secp256k1_scalar_sqr(t, t); + } + secp256k1_scalar_mul(t, t, &u11); /* 1011 */ for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } @@ -136,38 +147,26 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_sqr(t, t); } secp256k1_scalar_mul(t, t, &x3); /* 111 */ - for (i = 0; i < 4; i++) { /* 00 */ + for (i = 0; i < 6; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u13); /* 1101 */ + for (i = 0; i < 4; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u5); /* 101 */ + for (i = 0; i < 3; i++) { secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ + secp256k1_scalar_mul(t, t, &x3); /* 111 */ for (i = 0; i < 5; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u9); /* 1001 */ + for (i = 0; i < 6; i++) { /* 000 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 4; i++) { /* 000 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ + secp256k1_scalar_mul(t, t, &u5); /* 101 */ for (i = 0; i < 10; i++) { /* 0000000 */ secp256k1_scalar_sqr(t, t); } @@ -180,50 +179,34 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_sqr(t, t); } secp256k1_scalar_mul(t, t, &x8); /* 11111111 */ - for (i = 0; i < 2; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ for (i = 0; i < 5; i++) { /* 0 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x4); /* 1111 */ - for (i = 0; i < 2; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u9); /* 1001 */ + for (i = 0; i < 6; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 5; i++) { /* 000 */ + secp256k1_scalar_mul(t, t, &u11); /* 1011 */ + for (i = 0; i < 4; i++) { + secp256k1_scalar_sqr(t, t); + } + secp256k1_scalar_mul(t, t, &u13); /* 1101 */ + for (i = 0; i < 5; i++) { secp256k1_scalar_sqr(t, t); } secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 4; i++) { /* 00 */ + for (i = 0; i < 6; i++) { /* 00 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 2; i++) { /* 0 */ + secp256k1_scalar_mul(t, t, &u13); /* 1101 */ + for (i = 0; i < 10; i++) { /* 000000 */ secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, x); /* 1 */ - for (i = 0; i < 8; i++) { /* 000000 */ + secp256k1_scalar_mul(t, t, &u13); /* 1101 */ + for (i = 0; i < 4; i++) { secp256k1_scalar_sqr(t, t); } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) { /* 0 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, &x2); /* 11 */ - for (i = 0; i < 3; i++) { /* 00 */ - secp256k1_scalar_sqr(t, t); - } - secp256k1_scalar_mul(t, t, x); /* 1 */ + secp256k1_scalar_mul(t, t, &u9); /* 1001 */ for (i = 0; i < 6; i++) { /* 00000 */ secp256k1_scalar_sqr(t, t); } @@ -234,24 +217,45 @@ static void secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scal secp256k1_scalar_mul(r, t, &x6); /* 111111 */ } -static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_scalar_t *x) { +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(a->d[0] & 1); +} +#endif + +static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *x) { #if defined(USE_SCALAR_INV_BUILTIN) secp256k1_scalar_inverse(r, x); #elif defined(USE_SCALAR_INV_NUM) unsigned char b[32]; - secp256k1_num_t n, m; - secp256k1_scalar_get_b32(b, x); + secp256k1_num n, m; + secp256k1_scalar t = *x; + secp256k1_scalar_get_b32(b, &t); secp256k1_num_set_bin(&n, b, 32); secp256k1_scalar_order_get_num(&m); secp256k1_num_mod_inverse(&n, &n, &m); secp256k1_num_get_bin(b, 32, &n); secp256k1_scalar_set_b32(r, b, NULL); + /* Verify that the inverse was computed correctly, without GMP code. */ + secp256k1_scalar_mul(&t, &t, r); + CHECK(secp256k1_scalar_is_one(&t)); #else #error "Please select scalar inverse implementation" #endif } #ifdef USE_ENDOMORPHISM +#if defined(EXHAUSTIVE_TEST_ORDER) +/** + * Find k1 and k2 given k, such that k1 + k2 * lambda == k mod n; unlike in the + * full case we don't bother making k1 and k2 be small, we just want them to be + * nontrivial to get full test coverage for the exhaustive tests. We therefore + * (arbitrarily) set k2 = k + 5 and k1 = k - k2 * lambda. + */ +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r2 = (*a + 5) % EXHAUSTIVE_TEST_ORDER; + *r1 = (*a + (EXHAUSTIVE_TEST_ORDER - *r2) * EXHAUSTIVE_TEST_LAMBDA) % EXHAUSTIVE_TEST_ORDER; +} +#else /** * The Secp256k1 curve has an endomorphism, where lambda * (x, y) = (beta * x, y), where * lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, @@ -290,30 +294,31 @@ static void secp256k1_scalar_inverse_var(secp256k1_scalar_t *r, const secp256k1_ * The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order). */ -static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a) { - secp256k1_scalar_t c1, c2; - static const secp256k1_scalar_t minus_lambda = SECP256K1_SCALAR_CONST( +static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + secp256k1_scalar c1, c2; + static const secp256k1_scalar minus_lambda = SECP256K1_SCALAR_CONST( 0xAC9C52B3UL, 0x3FA3CF1FUL, 0x5AD9E3FDUL, 0x77ED9BA4UL, 0xA880B9FCUL, 0x8EC739C2UL, 0xE0CFC810UL, 0xB51283CFUL ); - static const secp256k1_scalar_t minus_b1 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar minus_b1 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0xE4437ED6UL, 0x010E8828UL, 0x6F547FA9UL, 0x0ABFE4C3UL ); - static const secp256k1_scalar_t minus_b2 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar minus_b2 = SECP256K1_SCALAR_CONST( 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL, 0x8A280AC5UL, 0x0774346DUL, 0xD765CDA8UL, 0x3DB1562CUL ); - static const secp256k1_scalar_t g1 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar g1 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00003086UL, 0xD221A7D4UL, 0x6BCDE86CUL, 0x90E49284UL, 0xEB153DABUL ); - static const secp256k1_scalar_t g2 = SECP256K1_SCALAR_CONST( + static const secp256k1_scalar g2 = SECP256K1_SCALAR_CONST( 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x0000E443UL, 0x7ED6010EUL, 0x88286F54UL, 0x7FA90ABFUL, 0xE4C42212UL ); VERIFY_CHECK(r1 != a); VERIFY_CHECK(r2 != a); + /* these _var calls are constant time since the shift amount is constant */ secp256k1_scalar_mul_shift_var(&c1, a, &g1, 272); secp256k1_scalar_mul_shift_var(&c2, a, &g2, 272); secp256k1_scalar_mul(&c1, &c1, &minus_b1); @@ -323,5 +328,6 @@ static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_ secp256k1_scalar_add(r1, r1, a); } #endif - #endif + +#endif /* SECP256K1_SCALAR_IMPL_H */ diff --git a/src/secp256k1/src/scalar_low.h b/src/secp256k1/src/scalar_low.h new file mode 100644 index 000000000..5836febc5 --- /dev/null +++ b/src/secp256k1/src/scalar_low.h @@ -0,0 +1,15 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_H +#define SECP256K1_SCALAR_REPR_H + +#include + +/** A scalar modulo the group order of the secp256k1 curve. */ +typedef uint32_t secp256k1_scalar; + +#endif /* SECP256K1_SCALAR_REPR_H */ diff --git a/src/secp256k1/src/scalar_low_impl.h b/src/secp256k1/src/scalar_low_impl.h new file mode 100644 index 000000000..c80e70c5a --- /dev/null +++ b/src/secp256k1/src/scalar_low_impl.h @@ -0,0 +1,114 @@ +/********************************************************************** + * Copyright (c) 2015 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_SCALAR_REPR_IMPL_H +#define SECP256K1_SCALAR_REPR_IMPL_H + +#include "scalar.h" + +#include + +SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { + return !(*a & 1); +} + +SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } +SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + if (offset < 32) + return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); + else + return 0; +} + +SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { + return secp256k1_scalar_get_bits(a, offset, count); +} + +SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } + +static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; + return *r < *b; +} + +static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { + if (flag && bit < 32) + *r += (1 << bit); +#ifdef VERIFY + VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); +#endif +} + +static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { + const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; + int i; + *r = 0; + for (i = 0; i < 32; i++) { + *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; + } + /* just deny overflow, it basically always happens */ + if (overflow) *overflow = 0; +} + +static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { + memset(bin, 0, 32); + bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; +} + +SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { + return *a == 0; +} + +static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { + if (*a == 0) { + *r = 0; + } else { + *r = EXHAUSTIVE_TEST_ORDER - *a; + } +} + +SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { + return *a == 1; +} + +static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { + return *a > EXHAUSTIVE_TEST_ORDER / 2; +} + +static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { + if (flag) secp256k1_scalar_negate(r, r); + return flag ? -1 : 1; +} + +static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { + *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; +} + +static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { + int ret; + VERIFY_CHECK(n > 0); + VERIFY_CHECK(n < 16); + ret = *r & ((1 << n) - 1); + *r >>= n; + return ret; +} + +static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { + *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; +} + +static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { + *r1 = *a; + *r2 = 0; +} + +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { + return *a == *b; +} + +#endif /* SECP256K1_SCALAR_REPR_IMPL_H */ diff --git a/src/secp256k1/src/secp256k1.c b/src/secp256k1/src/secp256k1.c index 48569ad9e..cecb1550b 100644 --- a/src/secp256k1/src/secp256k1.c +++ b/src/secp256k1/src/secp256k1.c @@ -4,8 +4,6 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#define SECP256K1_BUILD (1) - #include "include/secp256k1.h" #include "util.h" @@ -14,89 +12,326 @@ #include "scalar_impl.h" #include "group_impl.h" #include "ecmult_impl.h" +#include "ecmult_const_impl.h" #include "ecmult_gen_impl.h" #include "ecdsa_impl.h" #include "eckey_impl.h" #include "hash_impl.h" -struct secp256k1_context_struct { - secp256k1_ecmult_context_t ecmult_ctx; - secp256k1_ecmult_gen_context_t ecmult_gen_ctx; +#define ARG_CHECK(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + return 0; \ + } \ +} while(0) + +static void default_illegal_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); + abort(); +} + +static const secp256k1_callback default_illegal_callback = { + default_illegal_callback_fn, + NULL }; -secp256k1_context_t* secp256k1_context_create(int flags) { - secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); +static void default_error_callback_fn(const char* str, void* data) { + (void)data; + fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); + abort(); +} + +static const secp256k1_callback default_error_callback = { + default_error_callback_fn, + NULL +}; + + +struct secp256k1_context_struct { + secp256k1_ecmult_context ecmult_ctx; + secp256k1_ecmult_gen_context ecmult_gen_ctx; + secp256k1_callback illegal_callback; + secp256k1_callback error_callback; +}; + +secp256k1_context* secp256k1_context_create(unsigned int flags) { + secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context)); + ret->illegal_callback = default_illegal_callback; + ret->error_callback = default_error_callback; + + if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) { + secp256k1_callback_call(&ret->illegal_callback, + "Invalid flags"); + free(ret); + return NULL; + } secp256k1_ecmult_context_init(&ret->ecmult_ctx); secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx); - if (flags & SECP256K1_CONTEXT_SIGN) { - secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx); + if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) { + secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback); } - if (flags & SECP256K1_CONTEXT_VERIFY) { - secp256k1_ecmult_context_build(&ret->ecmult_ctx); + if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) { + secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback); } return ret; } -secp256k1_context_t* secp256k1_context_clone(const secp256k1_context_t* ctx) { - secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t)); - secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx); +secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { + secp256k1_context* ret = (secp256k1_context*)checked_malloc(&ctx->error_callback, sizeof(secp256k1_context)); + ret->illegal_callback = ctx->illegal_callback; + ret->error_callback = ctx->error_callback; + secp256k1_ecmult_context_clone(&ret->ecmult_ctx, &ctx->ecmult_ctx, &ctx->error_callback); + secp256k1_ecmult_gen_context_clone(&ret->ecmult_gen_ctx, &ctx->ecmult_gen_ctx, &ctx->error_callback); return ret; } -void secp256k1_context_destroy(secp256k1_context_t* ctx) { - secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); - secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); +void secp256k1_context_destroy(secp256k1_context* ctx) { + if (ctx != NULL) { + secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); + secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); - free(ctx); + free(ctx); + } } -int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t s; - secp256k1_scalar_t m; - int ret = -3; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig != NULL); - DEBUG_CHECK(pubkey != NULL); +void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + if (fun == NULL) { + fun = default_illegal_callback_fn; + } + ctx->illegal_callback.fn = fun; + ctx->illegal_callback.data = data; +} + +void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { + if (fun == NULL) { + fun = default_error_callback_fn; + } + ctx->error_callback.fn = fun; + ctx->error_callback.data = data; +} + +static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { + if (sizeof(secp256k1_ge_storage) == 64) { + /* When the secp256k1_ge_storage type is exactly 64 byte, use its + * representation inside secp256k1_pubkey, as conversion is very fast. + * Note that secp256k1_pubkey_save must use the same representation. */ + secp256k1_ge_storage s; + memcpy(&s, &pubkey->data[0], 64); + secp256k1_ge_from_storage(ge, &s); + } else { + /* Otherwise, fall back to 32-byte big endian for X and Y. */ + secp256k1_fe x, y; + secp256k1_fe_set_b32(&x, pubkey->data); + secp256k1_fe_set_b32(&y, pubkey->data + 32); + secp256k1_ge_set_xy(ge, &x, &y); + } + ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); + return 1; +} + +static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { + if (sizeof(secp256k1_ge_storage) == 64) { + secp256k1_ge_storage s; + secp256k1_ge_to_storage(&s, ge); + memcpy(&pubkey->data[0], &s, 64); + } else { + VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); + secp256k1_fe_normalize_var(&ge->x); + secp256k1_fe_normalize_var(&ge->y); + secp256k1_fe_get_b32(pubkey->data, &ge->x); + secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); + } +} + +int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { + secp256k1_ge Q; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(input != NULL); + if (!secp256k1_eckey_pubkey_parse(&Q, input, inputlen)) { + return 0; + } + secp256k1_pubkey_save(pubkey, &Q); + secp256k1_ge_clear(&Q); + return 1; +} + +int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey* pubkey, unsigned int flags) { + secp256k1_ge Q; + size_t len; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(*outputlen >= ((flags & SECP256K1_FLAGS_BIT_COMPRESSION) ? 33 : 65)); + len = *outputlen; + *outputlen = 0; + ARG_CHECK(output != NULL); + memset(output, 0, len); + ARG_CHECK(pubkey != NULL); + ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION); + if (secp256k1_pubkey_load(ctx, &Q, pubkey)) { + ret = secp256k1_eckey_pubkey_serialize(&Q, output, &len, flags & SECP256K1_FLAGS_BIT_COMPRESSION); + if (ret) { + *outputlen = len; + } + } + return ret; +} + +static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) { + (void)ctx; + if (sizeof(secp256k1_scalar) == 32) { + /* When the secp256k1_scalar type is exactly 32 byte, use its + * representation inside secp256k1_ecdsa_signature, as conversion is very fast. + * Note that secp256k1_ecdsa_signature_save must use the same representation. */ + memcpy(r, &sig->data[0], 32); + memcpy(s, &sig->data[32], 32); + } else { + secp256k1_scalar_set_b32(r, &sig->data[0], NULL); + secp256k1_scalar_set_b32(s, &sig->data[32], NULL); + } +} + +static void secp256k1_ecdsa_signature_save(secp256k1_ecdsa_signature* sig, const secp256k1_scalar* r, const secp256k1_scalar* s) { + if (sizeof(secp256k1_scalar) == 32) { + memcpy(&sig->data[0], r, 32); + memcpy(&sig->data[32], s, 32); + } else { + secp256k1_scalar_get_b32(&sig->data[0], r); + secp256k1_scalar_get_b32(&sig->data[32], s); + } +} + +int secp256k1_ecdsa_signature_parse_der(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(input != NULL); + + if (secp256k1_ecdsa_sig_parse(&r, &s, input, inputlen)) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + return 1; + } else { + memset(sig, 0, sizeof(*sig)); + return 0; + } +} + +int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input64) { + secp256k1_scalar r, s; + int ret = 1; + int overflow = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(input64 != NULL); + + secp256k1_scalar_set_b32(&r, &input64[0], &overflow); + ret &= !overflow; + secp256k1_scalar_set_b32(&s, &input64[32], &overflow); + ret &= !overflow; + if (ret) { + secp256k1_ecdsa_signature_save(sig, &r, &s); + } else { + memset(sig, 0, sizeof(*sig)); + } + return ret; +} + +int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(outputlen != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s); +} + +int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context* ctx, unsigned char *output64, const secp256k1_ecdsa_signature* sig) { + secp256k1_scalar r, s; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output64 != NULL); + ARG_CHECK(sig != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + secp256k1_scalar_get_b32(&output64[0], &r); + secp256k1_scalar_get_b32(&output64[32], &s); + return 1; +} + +int secp256k1_ecdsa_signature_normalize(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) { + secp256k1_scalar r, s; + int ret = 0; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(sigin != NULL); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, sigin); + ret = secp256k1_scalar_is_high(&s); + if (sigout != NULL) { + if (ret) { + secp256k1_scalar_negate(&s, &s); + } + secp256k1_ecdsa_signature_save(sigout, &r, &s); + } + + return ret; +} + +int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) { + secp256k1_ge q; + secp256k1_scalar r, s; + secp256k1_scalar m; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(sig != NULL); + ARG_CHECK(pubkey != NULL); secp256k1_scalar_set_b32(&m, msg32, NULL); - - if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { - if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) { - if (secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &s, &q, &m)) { - /* success is 1, all other values are fail */ - ret = 1; - } else { - ret = 0; - } - } else { - ret = -2; - } - } else { - ret = -1; - } - - return ret; + secp256k1_ecdsa_signature_load(ctx, &r, &s, sig); + return (!secp256k1_scalar_is_high(&s) && + secp256k1_pubkey_load(ctx, &q, pubkey) && + secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m)); } - -int secp256k1_ecdsa_check_canonical_sig(const unsigned char *sig, int siglen) { - secp256k1_ecdsa_sig_t s; - if (!secp256k1_ecdsa_sig_parse(&s, sig, siglen)) return -1; - return !secp256k1_scalar_is_high(&s.s); -} - - -static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { - secp256k1_rfc6979_hmac_sha256_t rng; +static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { + unsigned char keydata[112]; + int keylen = 64; + secp256k1_rfc6979_hmac_sha256 rng; unsigned int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key32, 32, msg32, 32, (const unsigned char*)data, data != NULL ? 32 : 0); + /* We feed a byte array to the PRNG as input, consisting of: + * - the private key (32 bytes) and message (32 bytes), see RFC 6979 3.2d. + * - optionally 32 extra bytes of data, see RFC 6979 3.6 Additional Data. + * - optionally 16 extra bytes with the algorithm name. + * Because the arguments have distinct fixed lengths it is not possible for + * different argument mixtures to emulate each other and result in the same + * nonces. + */ + memcpy(keydata, key32, 32); + memcpy(keydata + 32, msg32, 32); + if (data != NULL) { + memcpy(keydata + 64, data, 32); + keylen = 96; + } + if (algo16 != NULL) { + memcpy(keydata + keylen, algo16, 16); + keylen += 16; + } + secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, keylen); + memset(keydata, 0, sizeof(keydata)); for (i = 0; i <= counter; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); } @@ -104,21 +339,19 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m return 1; } -const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; -const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979; +const secp256k1_nonce_function secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979; +const secp256k1_nonce_function secp256k1_nonce_function_default = nonce_function_rfc6979; -int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) { - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t sec, non, msg; +int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void* noncedata) { + secp256k1_scalar r, s; + secp256k1_scalar sec, non, msg; int ret = 0; int overflow = 0; - unsigned int count = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(signature != NULL); - DEBUG_CHECK(signaturelen != NULL); - DEBUG_CHECK(seckey != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(msg32 != NULL); + ARG_CHECK(signature != NULL); + ARG_CHECK(seckey != NULL); if (noncefp == NULL) { noncefp = secp256k1_nonce_function_default; } @@ -126,186 +359,112 @@ int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *ms secp256k1_scalar_set_b32(&sec, seckey, &overflow); /* Fail if the secret key is invalid. */ if (!overflow && !secp256k1_scalar_is_zero(&sec)) { + unsigned char nonce32[32]; + unsigned int count = 0; secp256k1_scalar_set_b32(&msg, msg32, NULL); while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); + ret = noncefp(nonce32, msg32, seckey, NULL, (void*)noncedata, count); if (!ret) { break; } secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, NULL)) { + if (!overflow && !secp256k1_scalar_is_zero(&non)) { + if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &r, &s, &sec, &msg, &non, NULL)) { break; } } count++; } - if (ret) { - ret = secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig); - } + memset(nonce32, 0, 32); secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); secp256k1_scalar_clear(&sec); } - if (!ret) { - *signaturelen = 0; + if (ret) { + secp256k1_ecdsa_signature_save(signature, &r, &s); + } else { + memset(signature, 0, sizeof(*signature)); } return ret; } -int secp256k1_ecdsa_sign_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) { - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t sec, non, msg; - int ret = 0; - int overflow = 0; - unsigned int count = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig64 != NULL); - DEBUG_CHECK(seckey != NULL); - if (noncefp == NULL) { - noncefp = secp256k1_nonce_function_default; - } - - secp256k1_scalar_set_b32(&sec, seckey, &overflow); - /* Fail if the secret key is invalid. */ - if (!overflow && !secp256k1_scalar_is_zero(&sec)) { - secp256k1_scalar_set_b32(&msg, msg32, NULL); - while (1) { - unsigned char nonce32[32]; - ret = noncefp(nonce32, msg32, seckey, count, noncedata); - if (!ret) { - break; - } - secp256k1_scalar_set_b32(&non, nonce32, &overflow); - memset(nonce32, 0, 32); - if (!secp256k1_scalar_is_zero(&non) && !overflow) { - if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, recid)) { - break; - } - } - count++; - } - if (ret) { - secp256k1_scalar_get_b32(sig64, &sig.r); - secp256k1_scalar_get_b32(sig64 + 32, &sig.s); - } - secp256k1_scalar_clear(&msg); - secp256k1_scalar_clear(&non); - secp256k1_scalar_clear(&sec); - } - if (!ret) { - memset(sig64, 0, 64); - } - return ret; -} - -int secp256k1_ecdsa_recover_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) { - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t m; - int ret = 0; - int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(msg32 != NULL); - DEBUG_CHECK(sig64 != NULL); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - DEBUG_CHECK(recid >= 0 && recid <= 3); - - secp256k1_scalar_set_b32(&sig.r, sig64, &overflow); - if (!overflow) { - secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); - if (!overflow) { - secp256k1_scalar_set_b32(&m, msg32, NULL); - - if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &sig, &q, &m, recid)) { - ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed); - } - } - } - return ret; -} - -int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) { - secp256k1_scalar_t sec; +int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) { + secp256k1_scalar sec; int ret; int overflow; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); - (void)ctx; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); secp256k1_scalar_set_b32(&sec, seckey, &overflow); - ret = !secp256k1_scalar_is_zero(&sec) && !overflow; + ret = !overflow && !secp256k1_scalar_is_zero(&sec); secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_pubkey_verify(const secp256k1_context_t* ctx, const unsigned char *pubkey, int pubkeylen) { - secp256k1_ge_t q; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(pubkey != NULL); - (void)ctx; - - return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen); -} - -int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) { - secp256k1_gej_t pj; - secp256k1_ge_t p; - secp256k1_scalar_t sec; +int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) { + secp256k1_gej pj; + secp256k1_ge p; + secp256k1_scalar sec; int overflow; int ret = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - DEBUG_CHECK(seckey != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); + memset(pubkey, 0, sizeof(*pubkey)); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(seckey != NULL); secp256k1_scalar_set_b32(&sec, seckey, &overflow); - if (!overflow) { + ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec)); + if (ret) { secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec); - secp256k1_scalar_clear(&sec); secp256k1_ge_set_gej(&p, &pj); - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed); - } - if (!ret) { - *pubkeylen = 0; + secp256k1_pubkey_save(pubkey, &p); } + secp256k1_scalar_clear(&sec); return ret; } -int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) { - secp256k1_ge_t p; +int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) { + secp256k1_scalar sec; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + + secp256k1_scalar_set_b32(&sec, seckey, NULL); + secp256k1_scalar_negate(&sec, &sec); + secp256k1_scalar_get_b32(seckey, &sec); + + return 1; +} + +int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) { int ret = 0; - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(pubkeylen != NULL); - (void)ctx; + secp256k1_ge p; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(pubkey != NULL); - if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) { - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0); + ret = secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + secp256k1_ge_neg(&p, &p); + secp256k1_pubkey_save(pubkey, &p); } return ret; } -int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar_t term; - secp256k1_scalar_t sec; +int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar term; + secp256k1_scalar sec; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(tweak != NULL); - (void)ctx; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&term, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow; + ret = !overflow && secp256k1_eckey_privkey_tweak_add(&sec, &term); + memset(seckey, 0, 32); if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -315,45 +474,43 @@ int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char return ret; } -int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { - secp256k1_ge_t p; - secp256k1_scalar_t term; +int secp256k1_ec_pubkey_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { + secp256k1_ge p; + secp256k1_scalar term; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&term, tweak, &overflow); - if (!overflow) { - ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); + ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); + if (ret) { + if (secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term)) { + secp256k1_pubkey_save(pubkey, &p); + } else { + ret = 0; } } return ret; } -int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) { - secp256k1_scalar_t factor; - secp256k1_scalar_t sec; +int secp256k1_ec_privkey_tweak_mul(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) { + secp256k1_scalar factor; + secp256k1_scalar sec; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(tweak != NULL); - (void)ctx; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(seckey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&factor, tweak, &overflow); secp256k1_scalar_set_b32(&sec, seckey, NULL); - ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow; + ret = !overflow && secp256k1_eckey_privkey_tweak_mul(&sec, &factor); + memset(seckey, 0, 32); if (ret) { secp256k1_scalar_get_b32(seckey, &sec); } @@ -363,65 +520,65 @@ int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char return ret; } -int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) { - secp256k1_ge_t p; - secp256k1_scalar_t factor; +int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) { + secp256k1_ge p; + secp256k1_scalar factor; int ret = 0; int overflow = 0; - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); - DEBUG_CHECK(pubkey != NULL); - DEBUG_CHECK(tweak != NULL); + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + ARG_CHECK(pubkey != NULL); + ARG_CHECK(tweak != NULL); secp256k1_scalar_set_b32(&factor, tweak, &overflow); - if (!overflow) { - ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); - if (ret) { - ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor); - } - if (ret) { - int oldlen = pubkeylen; - ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); - VERIFY_CHECK(pubkeylen == oldlen); - } - } - - return ret; -} - -int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) { - secp256k1_scalar_t key; - int ret = 0; - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(privkey != NULL); - DEBUG_CHECK(privkeylen != NULL); - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - - secp256k1_scalar_set_b32(&key, seckey, NULL); - ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed); - secp256k1_scalar_clear(&key); - return ret; -} - -int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) { - secp256k1_scalar_t key; - int ret = 0; - DEBUG_CHECK(seckey != NULL); - DEBUG_CHECK(privkey != NULL); - (void)ctx; - - ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen); + ret = !overflow && secp256k1_pubkey_load(ctx, &p, pubkey); + memset(pubkey, 0, sizeof(*pubkey)); if (ret) { - secp256k1_scalar_get_b32(seckey, &key); + if (secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor)) { + secp256k1_pubkey_save(pubkey, &p); + } else { + ret = 0; + } } - secp256k1_scalar_clear(&key); + return ret; } -int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *seed32) { - DEBUG_CHECK(ctx != NULL); - DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); +int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); return 1; } + +int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { + size_t i; + secp256k1_gej Qj; + secp256k1_ge Q; + + ARG_CHECK(pubnonce != NULL); + memset(pubnonce, 0, sizeof(*pubnonce)); + ARG_CHECK(n >= 1); + ARG_CHECK(pubnonces != NULL); + + secp256k1_gej_set_infinity(&Qj); + + for (i = 0; i < n; i++) { + secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); + secp256k1_gej_add_ge(&Qj, &Qj, &Q); + } + if (secp256k1_gej_is_infinity(&Qj)) { + return 0; + } + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(pubnonce, &Q); + return 1; +} + +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/main_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/main_impl.h" +#endif diff --git a/src/secp256k1/src/testrand.h b/src/secp256k1/src/testrand.h index 041bb92c4..f1f9be077 100644 --- a/src/secp256k1/src/testrand.h +++ b/src/secp256k1/src/testrand.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_TESTRAND_H_ -#define _SECP256K1_TESTRAND_H_ +#ifndef SECP256K1_TESTRAND_H +#define SECP256K1_TESTRAND_H #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" @@ -16,13 +16,23 @@ /** Seed the pseudorandom number generator for testing. */ SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); -/** Generate a pseudorandom 32-bit number. */ +/** Generate a pseudorandom number in the range [0..2**32-1]. */ static uint32_t secp256k1_rand32(void); +/** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or + * more. */ +static uint32_t secp256k1_rand_bits(int bits); + +/** Generate a pseudorandom number in the range [0..range-1]. */ +static uint32_t secp256k1_rand_int(uint32_t range); + /** Generate a pseudorandom 32-byte array. */ static void secp256k1_rand256(unsigned char *b32); /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ static void secp256k1_rand256_test(unsigned char *b32); -#endif +/** Generate pseudorandom bytes with long sequences of zero and one bits. */ +static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); + +#endif /* SECP256K1_TESTRAND_H */ diff --git a/src/secp256k1/src/testrand_impl.h b/src/secp256k1/src/testrand_impl.h index 21c69f1c5..30a91e529 100644 --- a/src/secp256k1/src/testrand_impl.h +++ b/src/secp256k1/src/testrand_impl.h @@ -1,11 +1,11 @@ /********************************************************************** - * Copyright (c) 2013, 2014 Pieter Wuille * + * Copyright (c) 2013-2015 Pieter Wuille * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_TESTRAND_IMPL_H_ -#define _SECP256K1_TESTRAND_IMPL_H_ +#ifndef SECP256K1_TESTRAND_IMPL_H +#define SECP256K1_TESTRAND_IMPL_H #include #include @@ -13,12 +13,14 @@ #include "testrand.h" #include "hash.h" -static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng; +static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; static uint32_t secp256k1_test_rng_precomputed[8]; static int secp256k1_test_rng_precomputed_used = 8; +static uint64_t secp256k1_test_rng_integer; +static int secp256k1_test_rng_integer_bits_left = 0; SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { - secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, (const unsigned char*)"TestRNG", 7, seed16, 16, NULL, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); } SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { @@ -29,32 +31,80 @@ SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; } +static uint32_t secp256k1_rand_bits(int bits) { + uint32_t ret; + if (secp256k1_test_rng_integer_bits_left < bits) { + secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); + secp256k1_test_rng_integer_bits_left += 32; + } + ret = secp256k1_test_rng_integer; + secp256k1_test_rng_integer >>= bits; + secp256k1_test_rng_integer_bits_left -= bits; + ret &= ((~((uint32_t)0)) >> (32 - bits)); + return ret; +} + +static uint32_t secp256k1_rand_int(uint32_t range) { + /* We want a uniform integer between 0 and range-1, inclusive. + * B is the smallest number such that range <= 2**B. + * two mechanisms implemented here: + * - generate B bits numbers until one below range is found, and return it + * - find the largest multiple M of range that is <= 2**(B+A), generate B+A + * bits numbers until one below M is found, and return it modulo range + * The second mechanism consumes A more bits of entropy in every iteration, + * but may need fewer iterations due to M being closer to 2**(B+A) then + * range is to 2**B. The array below (indexed by B) contains a 0 when the + * first mechanism is to be used, and the number A otherwise. + */ + static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; + uint32_t trange, mult; + int bits = 0; + if (range <= 1) { + return 0; + } + trange = range - 1; + while (trange > 0) { + trange >>= 1; + bits++; + } + if (addbits[bits]) { + bits = bits + addbits[bits]; + mult = ((~((uint32_t)0)) >> (32 - bits)) / range; + trange = range * mult; + } else { + trange = range; + mult = 1; + } + while(1) { + uint32_t x = secp256k1_rand_bits(bits); + if (x < trange) { + return (mult == 1) ? x : (x % range); + } + } +} + static void secp256k1_rand256(unsigned char *b32) { secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); } -static void secp256k1_rand256_test(unsigned char *b32) { - int bits=0; - uint64_t ent = 0; - int entleft = 0; - memset(b32, 0, 32); - while (bits < 256) { +static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { + size_t bits = 0; + memset(bytes, 0, len); + while (bits < len * 8) { int now; uint32_t val; - if (entleft < 12) { - ent |= ((uint64_t)secp256k1_rand32()) << entleft; - entleft += 32; - } - now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; - val = 1 & (ent >> 11); - ent >>= 12; - entleft -= 12; - while (now > 0 && bits < 256) { - b32[bits / 8] |= val << (bits % 8); + now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; + val = secp256k1_rand_bits(1); + while (now > 0 && bits < len * 8) { + bytes[bits / 8] |= val << (bits % 8); now--; bits++; } } } -#endif +static void secp256k1_rand256_test(unsigned char *b32) { + secp256k1_rand_bytes_test(b32, 32); +} + +#endif /* SECP256K1_TESTRAND_IMPL_H */ diff --git a/src/secp256k1/src/tests.c b/src/secp256k1/src/tests.c index d0e05057f..f307b99d5 100644 --- a/src/secp256k1/src/tests.c +++ b/src/secp256k1/src/tests.c @@ -10,10 +10,12 @@ #include #include +#include #include #include "secp256k1.c" +#include "include/secp256k1.h" #include "testrand_impl.h" #ifdef ENABLE_OPENSSL_TESTS @@ -23,10 +25,40 @@ #include "openssl/obj_mac.h" #endif -static int count = 64; -static secp256k1_context_t *ctx = NULL; +#include "contrib/lax_der_parsing.c" +#include "contrib/lax_der_privatekey_parsing.c" -void random_field_element_test(secp256k1_fe_t *fe) { +#if !defined(VG_CHECK) +# if defined(VALGRIND) +# include +# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) +# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) +# else +# define VG_UNDEF(x,y) +# define VG_CHECK(x,y) +# endif +#endif + +static int count = 64; +static secp256k1_context *ctx = NULL; + +static void counting_illegal_callback_fn(const char* str, void* data) { + /* Dummy callback function that just counts. */ + int32_t *p; + (void)str; + p = data; + (*p)++; +} + +static void uncounting_illegal_callback_fn(const char* str, void* data) { + /* Dummy callback function that just counts (backwards). */ + int32_t *p; + (void)str; + p = data; + (*p)--; +} + +void random_field_element_test(secp256k1_fe *fe) { do { unsigned char b32[32]; secp256k1_rand256_test(b32); @@ -36,9 +68,9 @@ void random_field_element_test(secp256k1_fe_t *fe) { } while(1); } -void random_field_element_magnitude(secp256k1_fe_t *fe) { - secp256k1_fe_t zero; - int n = secp256k1_rand32() % 9; +void random_field_element_magnitude(secp256k1_fe *fe) { + secp256k1_fe zero; + int n = secp256k1_rand_int(9); secp256k1_fe_normalize(fe); if (n == 0) { return; @@ -47,23 +79,22 @@ void random_field_element_magnitude(secp256k1_fe_t *fe) { secp256k1_fe_negate(&zero, &zero, 0); secp256k1_fe_mul_int(&zero, n - 1); secp256k1_fe_add(fe, &zero); -#ifdef VERIFY - CHECK(fe->magnitude == n); -#endif + VERIFY_CHECK(fe->magnitude == n); } -void random_group_element_test(secp256k1_ge_t *ge) { - secp256k1_fe_t fe; +void random_group_element_test(secp256k1_ge *ge) { + secp256k1_fe fe; do { random_field_element_test(&fe); - if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1)) { + if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand_bits(1))) { + secp256k1_fe_normalize(&ge->y); break; } } while(1); } -void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge_t *ge) { - secp256k1_fe_t z2, z3; +void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) { + secp256k1_fe z2, z3; do { random_field_element_test(&gej->z); if (!secp256k1_fe_is_zero(&gej->z)) { @@ -77,7 +108,7 @@ void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge gej->infinity = ge->infinity; } -void random_scalar_order_test(secp256k1_scalar_t *num) { +void random_scalar_order_test(secp256k1_scalar *num) { do { unsigned char b32[32]; int overflow = 0; @@ -90,7 +121,7 @@ void random_scalar_order_test(secp256k1_scalar_t *num) { } while(1); } -void random_scalar_order(secp256k1_scalar_t *num) { +void random_scalar_order(secp256k1_scalar *num) { do { unsigned char b32[32]; int overflow = 0; @@ -104,19 +135,34 @@ void random_scalar_order(secp256k1_scalar_t *num) { } void run_context_tests(void) { - secp256k1_context_t *none = secp256k1_context_create(0); - secp256k1_context_t *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); - secp256k1_context_t *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - secp256k1_context_t *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pubkey pubkey; + secp256k1_pubkey zero_pubkey; + secp256k1_ecdsa_signature sig; + unsigned char ctmp[32]; + int32_t ecount; + int32_t ecount2; + secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + secp256k1_context *both = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - secp256k1_gej_t pubj; - secp256k1_ge_t pub; - secp256k1_scalar_t msg, key, nonce; - secp256k1_ecdsa_sig_t sig; + secp256k1_gej pubj; + secp256k1_ge pub; + secp256k1_scalar msg, key, nonce; + secp256k1_scalar sigr, sigs; + + memset(&zero_pubkey, 0, sizeof(zero_pubkey)); + + ecount = 0; + ecount2 = 10; + secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount2); + secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, NULL); + CHECK(vrfy->error_callback.fn != sign->error_callback.fn); /*** clone and destroy all of them to make sure cloning was complete ***/ { - secp256k1_context_t *ctx_tmp; + secp256k1_context *ctx_tmp; ctx_tmp = none; none = secp256k1_context_clone(none); secp256k1_context_destroy(ctx_tmp); ctx_tmp = sign; sign = secp256k1_context_clone(sign); secp256k1_context_destroy(ctx_tmp); @@ -124,30 +170,82 @@ void run_context_tests(void) { ctx_tmp = both; both = secp256k1_context_clone(both); secp256k1_context_destroy(ctx_tmp); } + /* Verify that the error callback makes it across the clone. */ + CHECK(vrfy->error_callback.fn != sign->error_callback.fn); + /* And that it resets back to default. */ + secp256k1_context_set_error_callback(sign, NULL, NULL); + CHECK(vrfy->error_callback.fn == sign->error_callback.fn); + /*** attempt to use them ***/ random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_ecmult_gen(&both->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); + /* Verify context-type checking illegal-argument errors. */ + memset(ctmp, 1, 32); + CHECK(secp256k1_ec_pubkey_create(vrfy, &pubkey, ctmp) == 0); + CHECK(ecount == 1); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(sign, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ecdsa_sign(vrfy, &sig, ctmp, ctmp, NULL, NULL) == 0); + CHECK(ecount == 2); + VG_UNDEF(&sig, sizeof(sig)); + CHECK(secp256k1_ecdsa_sign(sign, &sig, ctmp, ctmp, NULL, NULL) == 1); + VG_CHECK(&sig, sizeof(sig)); + CHECK(ecount2 == 10); + CHECK(secp256k1_ecdsa_verify(sign, &sig, ctmp, &pubkey) == 0); + CHECK(ecount2 == 11); + CHECK(secp256k1_ecdsa_verify(vrfy, &sig, ctmp, &pubkey) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_tweak_add(sign, &pubkey, ctmp) == 0); + CHECK(ecount2 == 12); + CHECK(secp256k1_ec_pubkey_tweak_add(vrfy, &pubkey, ctmp) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_tweak_mul(sign, &pubkey, ctmp) == 0); + CHECK(ecount2 == 13); + CHECK(secp256k1_ec_pubkey_negate(vrfy, &pubkey) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_negate(sign, &pubkey) == 1); + CHECK(ecount == 2); + CHECK(secp256k1_ec_pubkey_negate(sign, NULL) == 0); + CHECK(ecount2 == 14); + CHECK(secp256k1_ec_pubkey_negate(vrfy, &zero_pubkey) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ec_pubkey_tweak_mul(vrfy, &pubkey, ctmp) == 1); + CHECK(ecount == 3); + CHECK(secp256k1_context_randomize(vrfy, ctmp) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_context_randomize(sign, NULL) == 1); + CHECK(ecount2 == 14); + secp256k1_context_set_illegal_callback(vrfy, NULL, NULL); + secp256k1_context_set_illegal_callback(sign, NULL, NULL); + + /* This shouldn't leak memory, due to already-set tests. */ + secp256k1_ecmult_gen_context_build(&sign->ecmult_gen_ctx, NULL); + secp256k1_ecmult_context_build(&vrfy->ecmult_ctx, NULL); + /* obtain a working nonce */ do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + } while(!secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try signing */ - CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); - CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sig, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&sign->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); + CHECK(secp256k1_ecdsa_sig_sign(&both->ecmult_gen_ctx, &sigr, &sigs, &key, &msg, &nonce, NULL)); /* try verifying */ - CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sig, &pub, &msg)); - CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sig, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&vrfy->ecmult_ctx, &sigr, &sigs, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&both->ecmult_ctx, &sigr, &sigs, &pub, &msg)); /* cleanup */ secp256k1_context_destroy(none); secp256k1_context_destroy(sign); secp256k1_context_destroy(vrfy); secp256k1_context_destroy(both); + /* Defined as no-op. */ + secp256k1_context_destroy(NULL); } /***** HASH TESTS *****/ @@ -172,13 +270,13 @@ void run_sha256_tests(void) { int i; for (i = 0; i < 8; i++) { unsigned char out[32]; - secp256k1_sha256_t hasher; + secp256k1_sha256 hasher; secp256k1_sha256_initialize(&hasher); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); secp256k1_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand32() % strlen(inputs[i]); + int split = secp256k1_rand_int(strlen(inputs[i])); secp256k1_sha256_initialize(&hasher); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); @@ -215,14 +313,14 @@ void run_hmac_sha256_tests(void) { }; int i; for (i = 0; i < 6; i++) { - secp256k1_hmac_sha256_t hasher; + secp256k1_hmac_sha256 hasher; unsigned char out[32]; secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), strlen(inputs[i])); secp256k1_hmac_sha256_finalize(&hasher, out); CHECK(memcmp(out, outputs[i], 32) == 0); if (strlen(inputs[i]) > 0) { - int split = secp256k1_rand32() % strlen(inputs[i]); + int split = secp256k1_rand_int(strlen(inputs[i])); secp256k1_hmac_sha256_initialize(&hasher, (const unsigned char*)(keys[i]), strlen(keys[i])); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i]), split); secp256k1_hmac_sha256_write(&hasher, (const unsigned char*)(inputs[i] + split), strlen(inputs[i]) - split); @@ -233,42 +331,39 @@ void run_hmac_sha256_tests(void) { } void run_rfc6979_hmac_sha256_tests(void) { - static const unsigned char key1[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00}; - static const unsigned char msg1[32] = {0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a}; + static const unsigned char key1[65] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x4b, 0xf5, 0x12, 0x2f, 0x34, 0x45, 0x54, 0xc5, 0x3b, 0xde, 0x2e, 0xbb, 0x8c, 0xd2, 0xb7, 0xe3, 0xd1, 0x60, 0x0a, 0xd6, 0x31, 0xc3, 0x85, 0xa5, 0xd7, 0xcc, 0xe2, 0x3c, 0x77, 0x85, 0x45, 0x9a, 0}; static const unsigned char out1[3][32] = { {0x4f, 0xe2, 0x95, 0x25, 0xb2, 0x08, 0x68, 0x09, 0x15, 0x9a, 0xcd, 0xf0, 0x50, 0x6e, 0xfb, 0x86, 0xb0, 0xec, 0x93, 0x2c, 0x7b, 0xa4, 0x42, 0x56, 0xab, 0x32, 0x1e, 0x42, 0x1e, 0x67, 0xe9, 0xfb}, {0x2b, 0xf0, 0xff, 0xf1, 0xd3, 0xc3, 0x78, 0xa2, 0x2d, 0xc5, 0xde, 0x1d, 0x85, 0x65, 0x22, 0x32, 0x5c, 0x65, 0xb5, 0x04, 0x49, 0x1a, 0x0c, 0xbd, 0x01, 0xcb, 0x8f, 0x3a, 0xa6, 0x7f, 0xfd, 0x4a}, {0xf5, 0x28, 0xb4, 0x10, 0xcb, 0x54, 0x1f, 0x77, 0x00, 0x0d, 0x7a, 0xfb, 0x6c, 0x5b, 0x53, 0xc5, 0xc4, 0x71, 0xea, 0xb4, 0x3e, 0x46, 0x6d, 0x9a, 0xc5, 0x19, 0x0c, 0x39, 0xc8, 0x2f, 0xd8, 0x2e} }; - static const unsigned char key2[32] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - static const unsigned char msg2[32] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; + static const unsigned char key2[64] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; static const unsigned char out2[3][32] = { {0x9c, 0x23, 0x6c, 0x16, 0x5b, 0x82, 0xae, 0x0c, 0xd5, 0x90, 0x65, 0x9e, 0x10, 0x0b, 0x6b, 0xab, 0x30, 0x36, 0xe7, 0xba, 0x8b, 0x06, 0x74, 0x9b, 0xaf, 0x69, 0x81, 0xe1, 0x6f, 0x1a, 0x2b, 0x95}, {0xdf, 0x47, 0x10, 0x61, 0x62, 0x5b, 0xc0, 0xea, 0x14, 0xb6, 0x82, 0xfe, 0xee, 0x2c, 0x9c, 0x02, 0xf2, 0x35, 0xda, 0x04, 0x20, 0x4c, 0x1d, 0x62, 0xa1, 0x53, 0x6c, 0x6e, 0x17, 0xae, 0xd7, 0xa9}, {0x75, 0x97, 0x88, 0x7c, 0xbd, 0x76, 0x32, 0x1f, 0x32, 0xe3, 0x04, 0x40, 0x67, 0x9a, 0x22, 0xcf, 0x7f, 0x8d, 0x9d, 0x2e, 0xac, 0x39, 0x0e, 0x58, 0x1f, 0xea, 0x09, 0x1c, 0xe2, 0x02, 0xba, 0x94} }; - secp256k1_rfc6979_hmac_sha256_t rng; + secp256k1_rfc6979_hmac_sha256 rng; unsigned char out[32]; - unsigned char zero[1] = {0}; int i; - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, NULL, 1); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out1[i], 32) == 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 32, msg1, 32, zero, 1); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key1, 65); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out1[i], 32) != 0); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); - secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 32, msg2, 32, zero, 0); + secp256k1_rfc6979_hmac_sha256_initialize(&rng, key2, 64); for (i = 0; i < 3; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, out, 32); CHECK(memcmp(out, out2[i], 32) == 0); @@ -276,30 +371,102 @@ void run_rfc6979_hmac_sha256_tests(void) { secp256k1_rfc6979_hmac_sha256_finalize(&rng); } +/***** RANDOM TESTS *****/ + +void test_rand_bits(int rand32, int bits) { + /* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to + * get a false negative chance below once in a billion */ + static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316}; + /* We try multiplying the results with various odd numbers, which shouldn't + * influence the uniform distribution modulo a power of 2. */ + static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011}; + /* We only select up to 6 bits from the output to analyse */ + unsigned int usebits = bits > 6 ? 6 : bits; + unsigned int maxshift = bits - usebits; + /* For each of the maxshift+1 usebits-bit sequences inside a bits-bit + number, track all observed outcomes, one per bit in a uint64_t. */ + uint64_t x[6][27] = {{0}}; + unsigned int i, shift, m; + /* Multiply the output of all rand calls with the odd number m, which + should not change the uniformity of its distribution. */ + for (i = 0; i < rounds[usebits]; i++) { + uint32_t r = (rand32 ? secp256k1_rand32() : secp256k1_rand_bits(bits)); + CHECK((((uint64_t)r) >> bits) == 0); + for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { + uint32_t rm = r * mults[m]; + for (shift = 0; shift <= maxshift; shift++) { + x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1))); + } + } + } + for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) { + for (shift = 0; shift <= maxshift; shift++) { + /* Test that the lower usebits bits of x[shift] are 1 */ + CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0); + } + } +} + +/* Subrange must be a whole divisor of range, and at most 64 */ +void test_rand_int(uint32_t range, uint32_t subrange) { + /* (1-1/subrange)^rounds < 1/10^9 */ + int rounds = (subrange * 2073) / 100; + int i; + uint64_t x = 0; + CHECK((range % subrange) == 0); + for (i = 0; i < rounds; i++) { + uint32_t r = secp256k1_rand_int(range); + CHECK(r < range); + r = r % subrange; + x |= (((uint64_t)1) << r); + } + /* Test that the lower subrange bits of x are 1. */ + CHECK(((~x) << (64 - subrange)) == 0); +} + +void run_rand_bits(void) { + size_t b; + test_rand_bits(1, 32); + for (b = 1; b <= 32; b++) { + test_rand_bits(0, b); + } +} + +void run_rand_int(void) { + static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432}; + static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64}; + unsigned int m, s; + for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) { + for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) { + test_rand_int(ms[m] * ss[s], ss[s]); + } + } +} + /***** NUM TESTS *****/ #ifndef USE_NUM_NONE -void random_num_negate(secp256k1_num_t *num) { - if (secp256k1_rand32() & 1) { +void random_num_negate(secp256k1_num *num) { + if (secp256k1_rand_bits(1)) { secp256k1_num_negate(num); } } -void random_num_order_test(secp256k1_num_t *num) { - secp256k1_scalar_t sc; +void random_num_order_test(secp256k1_num *num) { + secp256k1_scalar sc; random_scalar_order_test(&sc); secp256k1_scalar_get_num(num, &sc); } -void random_num_order(secp256k1_num_t *num) { - secp256k1_scalar_t sc; +void random_num_order(secp256k1_num *num) { + secp256k1_scalar sc; random_scalar_order(&sc); secp256k1_scalar_get_num(num, &sc); } void test_num_negate(void) { - secp256k1_num_t n1; - secp256k1_num_t n2; + secp256k1_num n1; + secp256k1_num n2; random_num_order_test(&n1); /* n1 = R */ random_num_negate(&n1); secp256k1_num_copy(&n2, &n1); /* n2 = R */ @@ -318,16 +485,17 @@ void test_num_negate(void) { } void test_num_add_sub(void) { - secp256k1_num_t n1; - secp256k1_num_t n2; - secp256k1_num_t n1p2, n2p1, n1m2, n2m1; - int r = secp256k1_rand32(); + int i; + secp256k1_scalar s; + secp256k1_num n1; + secp256k1_num n2; + secp256k1_num n1p2, n2p1, n1m2, n2m1; random_num_order_test(&n1); /* n1 = R1 */ - if (r & 1) { + if (secp256k1_rand_bits(1)) { random_num_negate(&n1); } random_num_order_test(&n2); /* n2 = R2 */ - if (r & 2) { + if (secp256k1_rand_bits(1)) { random_num_negate(&n2); } secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = R1 + R2 */ @@ -344,6 +512,110 @@ void test_num_add_sub(void) { CHECK(!secp256k1_num_eq(&n2p1, &n1)); secp256k1_num_sub(&n2p1, &n2p1, &n2); /* n2p1 = R2 + R1 - R2 = R1 */ CHECK(secp256k1_num_eq(&n2p1, &n1)); + + /* check is_one */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&n1, &s); + CHECK(secp256k1_num_is_one(&n1)); + /* check that 2^n + 1 is never 1 */ + secp256k1_scalar_get_num(&n2, &s); + for (i = 0; i < 250; ++i) { + secp256k1_num_add(&n1, &n1, &n1); /* n1 *= 2 */ + secp256k1_num_add(&n1p2, &n1, &n2); /* n1p2 = n1 + 1 */ + CHECK(!secp256k1_num_is_one(&n1p2)); + } +} + +void test_num_mod(void) { + int i; + secp256k1_scalar s; + secp256k1_num order, n; + + /* check that 0 mod anything is 0 */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_set_int(&s, 0); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that anything mod 1 is 0 */ + secp256k1_scalar_set_int(&s, 1); + secp256k1_scalar_get_num(&order, &s); + secp256k1_scalar_get_num(&n, &s); + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); + + /* check that increasing the number past 2^256 does not break this */ + random_scalar_order_test(&s); + secp256k1_scalar_get_num(&n, &s); + /* multiply by 2^8, which'll test this case with high probability */ + for (i = 0; i < 8; ++i) { + secp256k1_num_add(&n, &n, &n); + } + secp256k1_num_mod(&n, &order); + CHECK(secp256k1_num_is_zero(&n)); +} + +void test_num_jacobi(void) { + secp256k1_scalar sqr; + secp256k1_scalar small; + secp256k1_scalar five; /* five is not a quadratic residue */ + secp256k1_num order, n; + int i; + /* squares mod 5 are 1, 4 */ + const int jacobi5[10] = { 0, 1, -1, -1, 1, 0, 1, -1, -1, 1 }; + + /* check some small values with 5 as the order */ + secp256k1_scalar_set_int(&five, 5); + secp256k1_scalar_get_num(&order, &five); + for (i = 0; i < 10; ++i) { + secp256k1_scalar_set_int(&small, i); + secp256k1_scalar_get_num(&n, &small); + CHECK(secp256k1_num_jacobi(&n, &order) == jacobi5[i]); + } + + /** test large values with 5 as group order */ + secp256k1_scalar_get_num(&order, &five); + /* we first need a scalar which is not a multiple of 5 */ + do { + secp256k1_num fiven; + random_scalar_order_test(&sqr); + secp256k1_scalar_get_num(&fiven, &five); + secp256k1_scalar_get_num(&n, &sqr); + secp256k1_num_mod(&n, &fiven); + } while (secp256k1_num_is_zero(&n)); + /* next force it to be a residue. 2 is a nonresidue mod 5 so we can + * just multiply by two, i.e. add the number to itself */ + if (secp256k1_num_jacobi(&n, &order) == -1) { + secp256k1_num_add(&n, &n, &n); + } + + /* test residue */ + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_num_add(&n, &n, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + + /** test with secp group order as order */ + secp256k1_scalar_order_get_num(&order); + random_scalar_order_test(&sqr); + secp256k1_scalar_sqr(&sqr, &sqr); + /* test residue */ + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); + /* test nonresidue */ + secp256k1_scalar_mul(&sqr, &sqr, &five); + secp256k1_scalar_get_num(&n, &sqr); + CHECK(secp256k1_num_jacobi(&n, &order) == -1); + /* test multiple of the order*/ + CHECK(secp256k1_num_jacobi(&order, &order) == 0); + + /* check one less than the order */ + secp256k1_scalar_set_int(&small, 1); + secp256k1_scalar_get_num(&n, &small); + secp256k1_num_sub(&n, &order, &n); + CHECK(secp256k1_num_jacobi(&n, &order) == 1); /* sage confirms this is 1 */ } void run_num_smalltests(void) { @@ -351,6 +623,8 @@ void run_num_smalltests(void) { for (i = 0; i < 100*count; i++) { test_num_negate(); test_num_add_sub(); + test_num_mod(); + test_num_jacobi(); } } #endif @@ -358,12 +632,12 @@ void run_num_smalltests(void) { /***** SCALAR TESTS *****/ void scalar_test(void) { - secp256k1_scalar_t s; - secp256k1_scalar_t s1; - secp256k1_scalar_t s2; + secp256k1_scalar s; + secp256k1_scalar s1; + secp256k1_scalar s2; #ifndef USE_NUM_NONE - secp256k1_num_t snum, s1num, s2num; - secp256k1_num_t order, half_order; + secp256k1_num snum, s1num, s2num; + secp256k1_num order, half_order; #endif unsigned char c[32]; @@ -390,10 +664,10 @@ void scalar_test(void) { { int i; /* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */ - secp256k1_scalar_t n; + secp256k1_scalar n; secp256k1_scalar_set_int(&n, 0); for (i = 0; i < 256; i += 4) { - secp256k1_scalar_t t; + secp256k1_scalar t; int j; secp256k1_scalar_set_int(&t, secp256k1_scalar_get_bits(&s, 256 - 4 - i, 4)); for (j = 0; j < 4; j++) { @@ -406,13 +680,13 @@ void scalar_test(void) { { /* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */ - secp256k1_scalar_t n; + secp256k1_scalar n; int i = 0; secp256k1_scalar_set_int(&n, 0); while (i < 256) { - secp256k1_scalar_t t; + secp256k1_scalar t; int j; - int now = (secp256k1_rand32() % 15) + 1; + int now = secp256k1_rand_int(15) + 1; if (now + i > 256) { now = 256 - i; } @@ -429,9 +703,9 @@ void scalar_test(void) { #ifndef USE_NUM_NONE { /* Test that adding the scalars together is equal to adding their numbers together modulo the order. */ - secp256k1_num_t rnum; - secp256k1_num_t r2num; - secp256k1_scalar_t r; + secp256k1_num rnum; + secp256k1_num r2num; + secp256k1_scalar r; secp256k1_num_add(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); secp256k1_scalar_add(&r, &s, &s2); @@ -440,10 +714,10 @@ void scalar_test(void) { } { - /* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */ - secp256k1_scalar_t r; - secp256k1_num_t r2num; - secp256k1_num_t rnum; + /* Test that multiplying the scalars is equal to multiplying their numbers modulo the order. */ + secp256k1_scalar r; + secp256k1_num r2num; + secp256k1_num rnum; secp256k1_num_mul(&rnum, &snum, &s2num); secp256k1_num_mod(&rnum, &order); secp256k1_scalar_mul(&r, &s, &s2); @@ -457,9 +731,9 @@ void scalar_test(void) { } { - secp256k1_scalar_t neg; - secp256k1_num_t negnum; - secp256k1_num_t negnum2; + secp256k1_scalar neg; + secp256k1_num negnum; + secp256k1_num negnum2; /* Check that comparison with zero matches comparison with zero on the number. */ CHECK(secp256k1_num_is_zero(&snum) == secp256k1_scalar_is_zero(&s)); /* Check that comparison with the half order is equal to testing for high scalar. */ @@ -484,12 +758,12 @@ void scalar_test(void) { { /* Test secp256k1_scalar_mul_shift_var. */ - secp256k1_scalar_t r; - secp256k1_num_t one; - secp256k1_num_t rnum; - secp256k1_num_t rnum2; + secp256k1_scalar r; + secp256k1_num one; + secp256k1_num rnum; + secp256k1_num rnum2; unsigned char cone[1] = {0x01}; - unsigned int shift = 256 + (secp256k1_rand32() % 257); + unsigned int shift = 256 + secp256k1_rand_int(257); secp256k1_scalar_mul_shift_var(&r, &s1, &s2, shift); secp256k1_num_mul(&rnum, &s1num, &s2num); secp256k1_num_shift(&rnum, shift - 1); @@ -499,15 +773,29 @@ void scalar_test(void) { secp256k1_scalar_get_num(&rnum2, &r); CHECK(secp256k1_num_eq(&rnum, &rnum2)); } + + { + /* test secp256k1_scalar_shr_int */ + secp256k1_scalar r; + int i; + random_scalar_order_test(&r); + for (i = 0; i < 100; ++i) { + int low; + int shift = 1 + secp256k1_rand_int(15); + int expected = r.d[0] % (1 << shift); + low = secp256k1_scalar_shr_int(&r, shift); + CHECK(expected == low); + } + } #endif { /* Test that scalar inverses are equal to the inverse of their number modulo the order. */ if (!secp256k1_scalar_is_zero(&s)) { - secp256k1_scalar_t inv; + secp256k1_scalar inv; #ifndef USE_NUM_NONE - secp256k1_num_t invnum; - secp256k1_num_t invnum2; + secp256k1_num invnum; + secp256k1_num invnum2; #endif secp256k1_scalar_inverse(&inv, &s); #ifndef USE_NUM_NONE @@ -521,23 +809,27 @@ void scalar_test(void) { secp256k1_scalar_inverse(&inv, &inv); /* Inverting one must result in one. */ CHECK(secp256k1_scalar_is_one(&inv)); +#ifndef USE_NUM_NONE + secp256k1_scalar_get_num(&invnum, &inv); + CHECK(secp256k1_num_is_one(&invnum)); +#endif } } { /* Test commutativity of add. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_add(&r2, &s2, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); } { - secp256k1_scalar_t r1, r2; - secp256k1_scalar_t b; + secp256k1_scalar r1, r2; + secp256k1_scalar b; int i; /* Test add_bit. */ - int bit = secp256k1_rand32() % 256; + int bit = secp256k1_rand_bits(8); secp256k1_scalar_set_int(&b, 1); CHECK(secp256k1_scalar_is_one(&b)); for (i = 0; i < bit; i++) { @@ -547,14 +839,17 @@ void scalar_test(void) { r2 = s1; if (!secp256k1_scalar_add(&r1, &r1, &b)) { /* No overflow happened. */ - secp256k1_scalar_add_bit(&r2, bit); + secp256k1_scalar_cadd_bit(&r2, bit, 1); + CHECK(secp256k1_scalar_eq(&r1, &r2)); + /* cadd is a noop when flag is zero */ + secp256k1_scalar_cadd_bit(&r2, bit, 0); CHECK(secp256k1_scalar_eq(&r1, &r2)); } } { /* Test commutativity of mul. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_mul(&r1, &s1, &s2); secp256k1_scalar_mul(&r2, &s2, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); @@ -562,7 +857,7 @@ void scalar_test(void) { { /* Test associativity of add. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_add(&r1, &r1, &s); secp256k1_scalar_add(&r2, &s2, &s); @@ -572,7 +867,7 @@ void scalar_test(void) { { /* Test associativity of mul. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_mul(&r1, &s1, &s2); secp256k1_scalar_mul(&r1, &r1, &s); secp256k1_scalar_mul(&r2, &s2, &s); @@ -582,7 +877,7 @@ void scalar_test(void) { { /* Test distributitivity of mul over add. */ - secp256k1_scalar_t r1, r2, t; + secp256k1_scalar r1, r2, t; secp256k1_scalar_add(&r1, &s1, &s2); secp256k1_scalar_mul(&r1, &r1, &s); secp256k1_scalar_mul(&r2, &s1, &s); @@ -593,7 +888,7 @@ void scalar_test(void) { { /* Test square. */ - secp256k1_scalar_t r1, r2; + secp256k1_scalar r1, r2; secp256k1_scalar_sqr(&r1, &s1); secp256k1_scalar_mul(&r2, &s1, &s1); CHECK(secp256k1_scalar_eq(&r1, &r2)); @@ -601,7 +896,7 @@ void scalar_test(void) { { /* Test multiplicative identity. */ - secp256k1_scalar_t r1, v1; + secp256k1_scalar r1, v1; secp256k1_scalar_set_int(&v1,1); secp256k1_scalar_mul(&r1, &s1, &v1); CHECK(secp256k1_scalar_eq(&r1, &s1)); @@ -609,7 +904,7 @@ void scalar_test(void) { { /* Test additive identity. */ - secp256k1_scalar_t r1, v0; + secp256k1_scalar r1, v0; secp256k1_scalar_set_int(&v0,0); secp256k1_scalar_add(&r1, &s1, &v0); CHECK(secp256k1_scalar_eq(&r1, &s1)); @@ -617,7 +912,7 @@ void scalar_test(void) { { /* Test zero product property. */ - secp256k1_scalar_t r1, v0; + secp256k1_scalar r1, v0; secp256k1_scalar_set_int(&v0,0); secp256k1_scalar_mul(&r1, &s1, &v0); CHECK(secp256k1_scalar_eq(&r1, &v0)); @@ -633,7 +928,7 @@ void run_scalar_tests(void) { { /* (-1)+1 should be zero. */ - secp256k1_scalar_t s, o; + secp256k1_scalar s, o; secp256k1_scalar_set_int(&s, 1); CHECK(secp256k1_scalar_is_one(&s)); secp256k1_scalar_negate(&o, &s); @@ -646,8 +941,8 @@ void run_scalar_tests(void) { #ifndef USE_NUM_NONE { /* A scalar with value of the curve order should be 0. */ - secp256k1_num_t order; - secp256k1_scalar_t zero; + secp256k1_num order; + secp256k1_scalar zero; unsigned char bin[32]; int overflow = 0; secp256k1_scalar_order_get_num(&order); @@ -657,11 +952,605 @@ void run_scalar_tests(void) { CHECK(secp256k1_scalar_is_zero(&zero)); } #endif + + { + /* Does check_overflow check catch all ones? */ + static const secp256k1_scalar overflowed = SECP256K1_SCALAR_CONST( + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, + 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL + ); + CHECK(secp256k1_scalar_check_overflow(&overflowed)); + } + + { + /* Static test vectors. + * These were reduced from ~10^12 random vectors based on comparison-decision + * and edge-case coverage on 32-bit and 64-bit implementations. + * The responses were generated with Sage 5.9. + */ + secp256k1_scalar x; + secp256k1_scalar y; + secp256k1_scalar z; + secp256k1_scalar zz; + secp256k1_scalar one; + secp256k1_scalar r1; + secp256k1_scalar r2; +#if defined(USE_SCALAR_INV_NUM) + secp256k1_scalar zzv; +#endif + int overflow; + unsigned char chal[33][2][32] = { + {{0xff, 0xff, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0xc0, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff}}, + {{0xef, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x80, 0xff}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x00}, + {0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x1e, 0xf8, 0xff, 0xff, 0xff, 0xfd, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xe0, + 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, + 0xf3, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x80, 0xff, 0xff, 0x3f, + 0x00, 0xfe, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xfc, 0x9f, + 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0x0f, 0xfc, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0xf8, 0xff, 0x0f, 0xc0, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x80, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf0}, + {0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0x00, 0xf8, 0xff, 0x03, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0xc0, 0xff, 0x0f, 0xfc, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0x8f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0x7f}, + {0xff, 0xcf, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xbf, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0x01, 0xfc, 0xff, 0x01, 0x00, 0xfe, 0xff}, + {0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf0, 0xff, 0xff, + 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0x3f, + 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7e, 0x00, 0x00}}, + {{0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x00, 0xfe, 0x07, 0x00}, + {0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60}}, + {{0xff, 0x01, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x80, 0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00}}, + {{0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xff, 0xcf, 0xff, 0x1f, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00}, + {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0x7f, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x80, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x7f, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0xfe}}, + {{0xff, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0x03, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xc0, + 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff}}, + {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7e, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x07, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}, + {{0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0xc0, 0xf1, 0x7f, 0x00}}, + {{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00}, + {0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, + 0x00, 0x00, 0xfc, 0xff, 0xff, 0x01, 0xff, 0xff}}, + {{0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0x00, 0x00, 0x80, 0xff, 0x03, 0xe0, 0x01, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0xf0, 0x07, 0x00, 0x3c, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x07, 0xe0, 0xff, 0x00, 0x00, 0x00}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x80, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x7f, 0xfe, 0xff, 0x1f, + 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0xfe, 0xff}}, + {{0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, + 0xff, 0xff, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, + 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xf0}, + {0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, + 0xf8, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff}}, + {{0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}, + {0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0x82, 0xc9, 0xfa, 0xb0, 0x68, 0x04, 0xa0, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0x03, 0xfb, + 0xfa, 0x8a, 0x7d, 0xdf, 0x13, 0x86, 0xe2, 0x03}} + }; + unsigned char res[33][2][32] = { + {{0x0c, 0x3b, 0x0a, 0xca, 0x8d, 0x1a, 0x2f, 0xb9, + 0x8a, 0x7b, 0x53, 0x5a, 0x1f, 0xc5, 0x22, 0xa1, + 0x07, 0x2a, 0x48, 0xea, 0x02, 0xeb, 0xb3, 0xd6, + 0x20, 0x1e, 0x86, 0xd0, 0x95, 0xf6, 0x92, 0x35}, + {0xdc, 0x90, 0x7a, 0x07, 0x2e, 0x1e, 0x44, 0x6d, + 0xf8, 0x15, 0x24, 0x5b, 0x5a, 0x96, 0x37, 0x9c, + 0x37, 0x7b, 0x0d, 0xac, 0x1b, 0x65, 0x58, 0x49, + 0x43, 0xb7, 0x31, 0xbb, 0xa7, 0xf4, 0x97, 0x15}}, + {{0xf1, 0xf7, 0x3a, 0x50, 0xe6, 0x10, 0xba, 0x22, + 0x43, 0x4d, 0x1f, 0x1f, 0x7c, 0x27, 0xca, 0x9c, + 0xb8, 0xb6, 0xa0, 0xfc, 0xd8, 0xc0, 0x05, 0x2f, + 0xf7, 0x08, 0xe1, 0x76, 0xdd, 0xd0, 0x80, 0xc8}, + {0xe3, 0x80, 0x80, 0xb8, 0xdb, 0xe3, 0xa9, 0x77, + 0x00, 0xb0, 0xf5, 0x2e, 0x27, 0xe2, 0x68, 0xc4, + 0x88, 0xe8, 0x04, 0xc1, 0x12, 0xbf, 0x78, 0x59, + 0xe6, 0xa9, 0x7c, 0xe1, 0x81, 0xdd, 0xb9, 0xd5}}, + {{0x96, 0xe2, 0xee, 0x01, 0xa6, 0x80, 0x31, 0xef, + 0x5c, 0xd0, 0x19, 0xb4, 0x7d, 0x5f, 0x79, 0xab, + 0xa1, 0x97, 0xd3, 0x7e, 0x33, 0xbb, 0x86, 0x55, + 0x60, 0x20, 0x10, 0x0d, 0x94, 0x2d, 0x11, 0x7c}, + {0xcc, 0xab, 0xe0, 0xe8, 0x98, 0x65, 0x12, 0x96, + 0x38, 0x5a, 0x1a, 0xf2, 0x85, 0x23, 0x59, 0x5f, + 0xf9, 0xf3, 0xc2, 0x81, 0x70, 0x92, 0x65, 0x12, + 0x9c, 0x65, 0x1e, 0x96, 0x00, 0xef, 0xe7, 0x63}}, + {{0xac, 0x1e, 0x62, 0xc2, 0x59, 0xfc, 0x4e, 0x5c, + 0x83, 0xb0, 0xd0, 0x6f, 0xce, 0x19, 0xf6, 0xbf, + 0xa4, 0xb0, 0xe0, 0x53, 0x66, 0x1f, 0xbf, 0xc9, + 0x33, 0x47, 0x37, 0xa9, 0x3d, 0x5d, 0xb0, 0x48}, + {0x86, 0xb9, 0x2a, 0x7f, 0x8e, 0xa8, 0x60, 0x42, + 0x26, 0x6d, 0x6e, 0x1c, 0xa2, 0xec, 0xe0, 0xe5, + 0x3e, 0x0a, 0x33, 0xbb, 0x61, 0x4c, 0x9f, 0x3c, + 0xd1, 0xdf, 0x49, 0x33, 0xcd, 0x72, 0x78, 0x18}}, + {{0xf7, 0xd3, 0xcd, 0x49, 0x5c, 0x13, 0x22, 0xfb, + 0x2e, 0xb2, 0x2f, 0x27, 0xf5, 0x8a, 0x5d, 0x74, + 0xc1, 0x58, 0xc5, 0xc2, 0x2d, 0x9f, 0x52, 0xc6, + 0x63, 0x9f, 0xba, 0x05, 0x76, 0x45, 0x7a, 0x63}, + {0x8a, 0xfa, 0x55, 0x4d, 0xdd, 0xa3, 0xb2, 0xc3, + 0x44, 0xfd, 0xec, 0x72, 0xde, 0xef, 0xc0, 0x99, + 0xf5, 0x9f, 0xe2, 0x52, 0xb4, 0x05, 0x32, 0x58, + 0x57, 0xc1, 0x8f, 0xea, 0xc3, 0x24, 0x5b, 0x94}}, + {{0x05, 0x83, 0xee, 0xdd, 0x64, 0xf0, 0x14, 0x3b, + 0xa0, 0x14, 0x4a, 0x3a, 0x41, 0x82, 0x7c, 0xa7, + 0x2c, 0xaa, 0xb1, 0x76, 0xbb, 0x59, 0x64, 0x5f, + 0x52, 0xad, 0x25, 0x29, 0x9d, 0x8f, 0x0b, 0xb0}, + {0x7e, 0xe3, 0x7c, 0xca, 0xcd, 0x4f, 0xb0, 0x6d, + 0x7a, 0xb2, 0x3e, 0xa0, 0x08, 0xb9, 0xa8, 0x2d, + 0xc2, 0xf4, 0x99, 0x66, 0xcc, 0xac, 0xd8, 0xb9, + 0x72, 0x2a, 0x4a, 0x3e, 0x0f, 0x7b, 0xbf, 0xf4}}, + {{0x8c, 0x9c, 0x78, 0x2b, 0x39, 0x61, 0x7e, 0xf7, + 0x65, 0x37, 0x66, 0x09, 0x38, 0xb9, 0x6f, 0x70, + 0x78, 0x87, 0xff, 0xcf, 0x93, 0xca, 0x85, 0x06, + 0x44, 0x84, 0xa7, 0xfe, 0xd3, 0xa4, 0xe3, 0x7e}, + {0xa2, 0x56, 0x49, 0x23, 0x54, 0xa5, 0x50, 0xe9, + 0x5f, 0xf0, 0x4d, 0xe7, 0xdc, 0x38, 0x32, 0x79, + 0x4f, 0x1c, 0xb7, 0xe4, 0xbb, 0xf8, 0xbb, 0x2e, + 0x40, 0x41, 0x4b, 0xcc, 0xe3, 0x1e, 0x16, 0x36}}, + {{0x0c, 0x1e, 0xd7, 0x09, 0x25, 0x40, 0x97, 0xcb, + 0x5c, 0x46, 0xa8, 0xda, 0xef, 0x25, 0xd5, 0xe5, + 0x92, 0x4d, 0xcf, 0xa3, 0xc4, 0x5d, 0x35, 0x4a, + 0xe4, 0x61, 0x92, 0xf3, 0xbf, 0x0e, 0xcd, 0xbe}, + {0xe4, 0xaf, 0x0a, 0xb3, 0x30, 0x8b, 0x9b, 0x48, + 0x49, 0x43, 0xc7, 0x64, 0x60, 0x4a, 0x2b, 0x9e, + 0x95, 0x5f, 0x56, 0xe8, 0x35, 0xdc, 0xeb, 0xdc, + 0xc7, 0xc4, 0xfe, 0x30, 0x40, 0xc7, 0xbf, 0xa4}}, + {{0xd4, 0xa0, 0xf5, 0x81, 0x49, 0x6b, 0xb6, 0x8b, + 0x0a, 0x69, 0xf9, 0xfe, 0xa8, 0x32, 0xe5, 0xe0, + 0xa5, 0xcd, 0x02, 0x53, 0xf9, 0x2c, 0xe3, 0x53, + 0x83, 0x36, 0xc6, 0x02, 0xb5, 0xeb, 0x64, 0xb8}, + {0x1d, 0x42, 0xb9, 0xf9, 0xe9, 0xe3, 0x93, 0x2c, + 0x4c, 0xee, 0x6c, 0x5a, 0x47, 0x9e, 0x62, 0x01, + 0x6b, 0x04, 0xfe, 0xa4, 0x30, 0x2b, 0x0d, 0x4f, + 0x71, 0x10, 0xd3, 0x55, 0xca, 0xf3, 0x5e, 0x80}}, + {{0x77, 0x05, 0xf6, 0x0c, 0x15, 0x9b, 0x45, 0xe7, + 0xb9, 0x11, 0xb8, 0xf5, 0xd6, 0xda, 0x73, 0x0c, + 0xda, 0x92, 0xea, 0xd0, 0x9d, 0xd0, 0x18, 0x92, + 0xce, 0x9a, 0xaa, 0xee, 0x0f, 0xef, 0xde, 0x30}, + {0xf1, 0xf1, 0xd6, 0x9b, 0x51, 0xd7, 0x77, 0x62, + 0x52, 0x10, 0xb8, 0x7a, 0x84, 0x9d, 0x15, 0x4e, + 0x07, 0xdc, 0x1e, 0x75, 0x0d, 0x0c, 0x3b, 0xdb, + 0x74, 0x58, 0x62, 0x02, 0x90, 0x54, 0x8b, 0x43}}, + {{0xa6, 0xfe, 0x0b, 0x87, 0x80, 0x43, 0x67, 0x25, + 0x57, 0x5d, 0xec, 0x40, 0x50, 0x08, 0xd5, 0x5d, + 0x43, 0xd7, 0xe0, 0xaa, 0xe0, 0x13, 0xb6, 0xb0, + 0xc0, 0xd4, 0xe5, 0x0d, 0x45, 0x83, 0xd6, 0x13}, + {0x40, 0x45, 0x0a, 0x92, 0x31, 0xea, 0x8c, 0x60, + 0x8c, 0x1f, 0xd8, 0x76, 0x45, 0xb9, 0x29, 0x00, + 0x26, 0x32, 0xd8, 0xa6, 0x96, 0x88, 0xe2, 0xc4, + 0x8b, 0xdb, 0x7f, 0x17, 0x87, 0xcc, 0xc8, 0xf2}}, + {{0xc2, 0x56, 0xe2, 0xb6, 0x1a, 0x81, 0xe7, 0x31, + 0x63, 0x2e, 0xbb, 0x0d, 0x2f, 0x81, 0x67, 0xd4, + 0x22, 0xe2, 0x38, 0x02, 0x25, 0x97, 0xc7, 0x88, + 0x6e, 0xdf, 0xbe, 0x2a, 0xa5, 0x73, 0x63, 0xaa}, + {0x50, 0x45, 0xe2, 0xc3, 0xbd, 0x89, 0xfc, 0x57, + 0xbd, 0x3c, 0xa3, 0x98, 0x7e, 0x7f, 0x36, 0x38, + 0x92, 0x39, 0x1f, 0x0f, 0x81, 0x1a, 0x06, 0x51, + 0x1f, 0x8d, 0x6a, 0xff, 0x47, 0x16, 0x06, 0x9c}}, + {{0x33, 0x95, 0xa2, 0x6f, 0x27, 0x5f, 0x9c, 0x9c, + 0x64, 0x45, 0xcb, 0xd1, 0x3c, 0xee, 0x5e, 0x5f, + 0x48, 0xa6, 0xaf, 0xe3, 0x79, 0xcf, 0xb1, 0xe2, + 0xbf, 0x55, 0x0e, 0xa2, 0x3b, 0x62, 0xf0, 0xe4}, + {0x14, 0xe8, 0x06, 0xe3, 0xbe, 0x7e, 0x67, 0x01, + 0xc5, 0x21, 0x67, 0xd8, 0x54, 0xb5, 0x7f, 0xa4, + 0xf9, 0x75, 0x70, 0x1c, 0xfd, 0x79, 0xdb, 0x86, + 0xad, 0x37, 0x85, 0x83, 0x56, 0x4e, 0xf0, 0xbf}}, + {{0xbc, 0xa6, 0xe0, 0x56, 0x4e, 0xef, 0xfa, 0xf5, + 0x1d, 0x5d, 0x3f, 0x2a, 0x5b, 0x19, 0xab, 0x51, + 0xc5, 0x8b, 0xdd, 0x98, 0x28, 0x35, 0x2f, 0xc3, + 0x81, 0x4f, 0x5c, 0xe5, 0x70, 0xb9, 0xeb, 0x62}, + {0xc4, 0x6d, 0x26, 0xb0, 0x17, 0x6b, 0xfe, 0x6c, + 0x12, 0xf8, 0xe7, 0xc1, 0xf5, 0x2f, 0xfa, 0x91, + 0x13, 0x27, 0xbd, 0x73, 0xcc, 0x33, 0x31, 0x1c, + 0x39, 0xe3, 0x27, 0x6a, 0x95, 0xcf, 0xc5, 0xfb}}, + {{0x30, 0xb2, 0x99, 0x84, 0xf0, 0x18, 0x2a, 0x6e, + 0x1e, 0x27, 0xed, 0xa2, 0x29, 0x99, 0x41, 0x56, + 0xe8, 0xd4, 0x0d, 0xef, 0x99, 0x9c, 0xf3, 0x58, + 0x29, 0x55, 0x1a, 0xc0, 0x68, 0xd6, 0x74, 0xa4}, + {0x07, 0x9c, 0xe7, 0xec, 0xf5, 0x36, 0x73, 0x41, + 0xa3, 0x1c, 0xe5, 0x93, 0x97, 0x6a, 0xfd, 0xf7, + 0x53, 0x18, 0xab, 0xaf, 0xeb, 0x85, 0xbd, 0x92, + 0x90, 0xab, 0x3c, 0xbf, 0x30, 0x82, 0xad, 0xf6}}, + {{0xc6, 0x87, 0x8a, 0x2a, 0xea, 0xc0, 0xa9, 0xec, + 0x6d, 0xd3, 0xdc, 0x32, 0x23, 0xce, 0x62, 0x19, + 0xa4, 0x7e, 0xa8, 0xdd, 0x1c, 0x33, 0xae, 0xd3, + 0x4f, 0x62, 0x9f, 0x52, 0xe7, 0x65, 0x46, 0xf4}, + {0x97, 0x51, 0x27, 0x67, 0x2d, 0xa2, 0x82, 0x87, + 0x98, 0xd3, 0xb6, 0x14, 0x7f, 0x51, 0xd3, 0x9a, + 0x0b, 0xd0, 0x76, 0x81, 0xb2, 0x4f, 0x58, 0x92, + 0xa4, 0x86, 0xa1, 0xa7, 0x09, 0x1d, 0xef, 0x9b}}, + {{0xb3, 0x0f, 0x2b, 0x69, 0x0d, 0x06, 0x90, 0x64, + 0xbd, 0x43, 0x4c, 0x10, 0xe8, 0x98, 0x1c, 0xa3, + 0xe1, 0x68, 0xe9, 0x79, 0x6c, 0x29, 0x51, 0x3f, + 0x41, 0xdc, 0xdf, 0x1f, 0xf3, 0x60, 0xbe, 0x33}, + {0xa1, 0x5f, 0xf7, 0x1d, 0xb4, 0x3e, 0x9b, 0x3c, + 0xe7, 0xbd, 0xb6, 0x06, 0xd5, 0x60, 0x06, 0x6d, + 0x50, 0xd2, 0xf4, 0x1a, 0x31, 0x08, 0xf2, 0xea, + 0x8e, 0xef, 0x5f, 0x7d, 0xb6, 0xd0, 0xc0, 0x27}}, + {{0x62, 0x9a, 0xd9, 0xbb, 0x38, 0x36, 0xce, 0xf7, + 0x5d, 0x2f, 0x13, 0xec, 0xc8, 0x2d, 0x02, 0x8a, + 0x2e, 0x72, 0xf0, 0xe5, 0x15, 0x9d, 0x72, 0xae, + 0xfc, 0xb3, 0x4f, 0x02, 0xea, 0xe1, 0x09, 0xfe}, + {0x00, 0x00, 0x00, 0x00, 0xfa, 0x0a, 0x3d, 0xbc, + 0xad, 0x16, 0x0c, 0xb6, 0xe7, 0x7c, 0x8b, 0x39, + 0x9a, 0x43, 0xbb, 0xe3, 0xc2, 0x55, 0x15, 0x14, + 0x75, 0xac, 0x90, 0x9b, 0x7f, 0x9a, 0x92, 0x00}}, + {{0x8b, 0xac, 0x70, 0x86, 0x29, 0x8f, 0x00, 0x23, + 0x7b, 0x45, 0x30, 0xaa, 0xb8, 0x4c, 0xc7, 0x8d, + 0x4e, 0x47, 0x85, 0xc6, 0x19, 0xe3, 0x96, 0xc2, + 0x9a, 0xa0, 0x12, 0xed, 0x6f, 0xd7, 0x76, 0x16}, + {0x45, 0xaf, 0x7e, 0x33, 0xc7, 0x7f, 0x10, 0x6c, + 0x7c, 0x9f, 0x29, 0xc1, 0xa8, 0x7e, 0x15, 0x84, + 0xe7, 0x7d, 0xc0, 0x6d, 0xab, 0x71, 0x5d, 0xd0, + 0x6b, 0x9f, 0x97, 0xab, 0xcb, 0x51, 0x0c, 0x9f}}, + {{0x9e, 0xc3, 0x92, 0xb4, 0x04, 0x9f, 0xc8, 0xbb, + 0xdd, 0x9e, 0xc6, 0x05, 0xfd, 0x65, 0xec, 0x94, + 0x7f, 0x2c, 0x16, 0xc4, 0x40, 0xac, 0x63, 0x7b, + 0x7d, 0xb8, 0x0c, 0xe4, 0x5b, 0xe3, 0xa7, 0x0e}, + {0x43, 0xf4, 0x44, 0xe8, 0xcc, 0xc8, 0xd4, 0x54, + 0x33, 0x37, 0x50, 0xf2, 0x87, 0x42, 0x2e, 0x00, + 0x49, 0x60, 0x62, 0x02, 0xfd, 0x1a, 0x7c, 0xdb, + 0x29, 0x6c, 0x6d, 0x54, 0x53, 0x08, 0xd1, 0xc8}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, + {{0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}, + {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, + {{0x28, 0x56, 0xac, 0x0e, 0x4f, 0x98, 0x09, 0xf0, + 0x49, 0xfa, 0x7f, 0x84, 0xac, 0x7e, 0x50, 0x5b, + 0x17, 0x43, 0x14, 0x89, 0x9c, 0x53, 0xa8, 0x94, + 0x30, 0xf2, 0x11, 0x4d, 0x92, 0x14, 0x27, 0xe8}, + {0x39, 0x7a, 0x84, 0x56, 0x79, 0x9d, 0xec, 0x26, + 0x2c, 0x53, 0xc1, 0x94, 0xc9, 0x8d, 0x9e, 0x9d, + 0x32, 0x1f, 0xdd, 0x84, 0x04, 0xe8, 0xe2, 0x0a, + 0x6b, 0xbe, 0xbb, 0x42, 0x40, 0x67, 0x30, 0x6c}}, + {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x73, 0x2f, 0xc9, 0xbe, 0xbd}, + {0x27, 0x59, 0xc7, 0x35, 0x60, 0x71, 0xa6, 0xf1, + 0x79, 0xa5, 0xfd, 0x79, 0x16, 0xf3, 0x41, 0xf0, + 0x57, 0xb4, 0x02, 0x97, 0x32, 0xe7, 0xde, 0x59, + 0xe2, 0x2d, 0x9b, 0x11, 0xea, 0x2c, 0x35, 0x92}}, + {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}, + {{0x1c, 0xc4, 0xf7, 0xda, 0x0f, 0x65, 0xca, 0x39, + 0x70, 0x52, 0x92, 0x8e, 0xc3, 0xc8, 0x15, 0xea, + 0x7f, 0x10, 0x9e, 0x77, 0x4b, 0x6e, 0x2d, 0xdf, + 0xe8, 0x30, 0x9d, 0xda, 0xe8, 0x9a, 0x65, 0xae}, + {0x02, 0xb0, 0x16, 0xb1, 0x1d, 0xc8, 0x57, 0x7b, + 0xa2, 0x3a, 0xa2, 0xa3, 0x38, 0x5c, 0x8f, 0xeb, + 0x66, 0x37, 0x91, 0xa8, 0x5f, 0xef, 0x04, 0xf6, + 0x59, 0x75, 0xe1, 0xee, 0x92, 0xf6, 0x0e, 0x30}}, + {{0x8d, 0x76, 0x14, 0xa4, 0x14, 0x06, 0x9f, 0x9a, + 0xdf, 0x4a, 0x85, 0xa7, 0x6b, 0xbf, 0x29, 0x6f, + 0xbc, 0x34, 0x87, 0x5d, 0xeb, 0xbb, 0x2e, 0xa9, + 0xc9, 0x1f, 0x58, 0xd6, 0x9a, 0x82, 0xa0, 0x56}, + {0xd4, 0xb9, 0xdb, 0x88, 0x1d, 0x04, 0xe9, 0x93, + 0x8d, 0x3f, 0x20, 0xd5, 0x86, 0xa8, 0x83, 0x07, + 0xdb, 0x09, 0xd8, 0x22, 0x1f, 0x7f, 0xf1, 0x71, + 0xc8, 0xe7, 0x5d, 0x47, 0xaf, 0x8b, 0x72, 0xe9}}, + {{0x83, 0xb9, 0x39, 0xb2, 0xa4, 0xdf, 0x46, 0x87, + 0xc2, 0xb8, 0xf1, 0xe6, 0x4c, 0xd1, 0xe2, 0xa9, + 0xe4, 0x70, 0x30, 0x34, 0xbc, 0x52, 0x7c, 0x55, + 0xa6, 0xec, 0x80, 0xa4, 0xe5, 0xd2, 0xdc, 0x73}, + {0x08, 0xf1, 0x03, 0xcf, 0x16, 0x73, 0xe8, 0x7d, + 0xb6, 0x7e, 0x9b, 0xc0, 0xb4, 0xc2, 0xa5, 0x86, + 0x02, 0x77, 0xd5, 0x27, 0x86, 0xa5, 0x15, 0xfb, + 0xae, 0x9b, 0x8c, 0xa9, 0xf9, 0xf8, 0xa8, 0x4a}}, + {{0x8b, 0x00, 0x49, 0xdb, 0xfa, 0xf0, 0x1b, 0xa2, + 0xed, 0x8a, 0x9a, 0x7a, 0x36, 0x78, 0x4a, 0xc7, + 0xf7, 0xad, 0x39, 0xd0, 0x6c, 0x65, 0x7a, 0x41, + 0xce, 0xd6, 0xd6, 0x4c, 0x20, 0x21, 0x6b, 0xc7}, + {0xc6, 0xca, 0x78, 0x1d, 0x32, 0x6c, 0x6c, 0x06, + 0x91, 0xf2, 0x1a, 0xe8, 0x43, 0x16, 0xea, 0x04, + 0x3c, 0x1f, 0x07, 0x85, 0xf7, 0x09, 0x22, 0x08, + 0xba, 0x13, 0xfd, 0x78, 0x1e, 0x3f, 0x6f, 0x62}}, + {{0x25, 0x9b, 0x7c, 0xb0, 0xac, 0x72, 0x6f, 0xb2, + 0xe3, 0x53, 0x84, 0x7a, 0x1a, 0x9a, 0x98, 0x9b, + 0x44, 0xd3, 0x59, 0xd0, 0x8e, 0x57, 0x41, 0x40, + 0x78, 0xa7, 0x30, 0x2f, 0x4c, 0x9c, 0xb9, 0x68}, + {0xb7, 0x75, 0x03, 0x63, 0x61, 0xc2, 0x48, 0x6e, + 0x12, 0x3d, 0xbf, 0x4b, 0x27, 0xdf, 0xb1, 0x7a, + 0xff, 0x4e, 0x31, 0x07, 0x83, 0xf4, 0x62, 0x5b, + 0x19, 0xa5, 0xac, 0xa0, 0x32, 0x58, 0x0d, 0xa7}}, + {{0x43, 0x4f, 0x10, 0xa4, 0xca, 0xdb, 0x38, 0x67, + 0xfa, 0xae, 0x96, 0xb5, 0x6d, 0x97, 0xff, 0x1f, + 0xb6, 0x83, 0x43, 0xd3, 0xa0, 0x2d, 0x70, 0x7a, + 0x64, 0x05, 0x4c, 0xa7, 0xc1, 0xa5, 0x21, 0x51}, + {0xe4, 0xf1, 0x23, 0x84, 0xe1, 0xb5, 0x9d, 0xf2, + 0xb8, 0x73, 0x8b, 0x45, 0x2b, 0x35, 0x46, 0x38, + 0x10, 0x2b, 0x50, 0xf8, 0x8b, 0x35, 0xcd, 0x34, + 0xc8, 0x0e, 0xf6, 0xdb, 0x09, 0x35, 0xf0, 0xda}}, + {{0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}, + {0xdb, 0x21, 0x5c, 0x8d, 0x83, 0x1d, 0xb3, 0x34, + 0xc7, 0x0e, 0x43, 0xa1, 0x58, 0x79, 0x67, 0x13, + 0x1e, 0x86, 0x5d, 0x89, 0x63, 0xe6, 0x0a, 0x46, + 0x5c, 0x02, 0x97, 0x1b, 0x62, 0x43, 0x86, 0xf5}} + }; + secp256k1_scalar_set_int(&one, 1); + for (i = 0; i < 33; i++) { + secp256k1_scalar_set_b32(&x, chal[i][0], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&y, chal[i][1], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&r1, res[i][0], &overflow); + CHECK(!overflow); + secp256k1_scalar_set_b32(&r2, res[i][1], &overflow); + CHECK(!overflow); + secp256k1_scalar_mul(&z, &x, &y); + CHECK(!secp256k1_scalar_check_overflow(&z)); + CHECK(secp256k1_scalar_eq(&r1, &z)); + if (!secp256k1_scalar_is_zero(&y)) { + secp256k1_scalar_inverse(&zz, &y); + CHECK(!secp256k1_scalar_check_overflow(&zz)); +#if defined(USE_SCALAR_INV_NUM) + secp256k1_scalar_inverse_var(&zzv, &y); + CHECK(secp256k1_scalar_eq(&zzv, &zz)); +#endif + secp256k1_scalar_mul(&z, &z, &zz); + CHECK(!secp256k1_scalar_check_overflow(&z)); + CHECK(secp256k1_scalar_eq(&x, &z)); + secp256k1_scalar_mul(&zz, &zz, &y); + CHECK(!secp256k1_scalar_check_overflow(&zz)); + CHECK(secp256k1_scalar_eq(&one, &zz)); + } + secp256k1_scalar_mul(&z, &x, &x); + CHECK(!secp256k1_scalar_check_overflow(&z)); + secp256k1_scalar_sqr(&zz, &x); + CHECK(!secp256k1_scalar_check_overflow(&zz)); + CHECK(secp256k1_scalar_eq(&zz, &z)); + CHECK(secp256k1_scalar_eq(&r2, &zz)); + } + } } /***** FIELD TESTS *****/ -void random_fe(secp256k1_fe_t *x) { +void random_fe(secp256k1_fe *x) { unsigned char bin[32]; do { secp256k1_rand256(bin); @@ -671,7 +1560,17 @@ void random_fe(secp256k1_fe_t *x) { } while(1); } -void random_fe_non_zero(secp256k1_fe_t *nz) { +void random_fe_test(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_rand256_test(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} + +void random_fe_non_zero(secp256k1_fe *nz) { int tries = 10; while (--tries >= 0) { random_fe(nz); @@ -684,25 +1583,25 @@ void random_fe_non_zero(secp256k1_fe_t *nz) { CHECK(tries >= 0); } -void random_fe_non_square(secp256k1_fe_t *ns) { - secp256k1_fe_t r; +void random_fe_non_square(secp256k1_fe *ns) { + secp256k1_fe r; random_fe_non_zero(ns); - if (secp256k1_fe_sqrt_var(&r, ns)) { + if (secp256k1_fe_sqrt(&r, ns)) { secp256k1_fe_negate(ns, ns, 1); } } -int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { - secp256k1_fe_t an = *a; - secp256k1_fe_t bn = *b; +int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe an = *a; + secp256k1_fe bn = *b; secp256k1_fe_normalize_weak(&an); secp256k1_fe_normalize_var(&bn); return secp256k1_fe_equal_var(&an, &bn); } -int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) { - secp256k1_fe_t x; - secp256k1_fe_t one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); +int check_fe_inverse(const secp256k1_fe *a, const secp256k1_fe *ai) { + secp256k1_fe x; + secp256k1_fe one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 1); secp256k1_fe_mul(&x, a, ai); return check_fe_equal(&x, &one); } @@ -714,17 +1613,17 @@ void run_field_convert(void) { 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40 }; - static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST( + static const secp256k1_fe_storage fes = SECP256K1_FE_STORAGE_CONST( 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL ); - static const secp256k1_fe_t fe = SECP256K1_FE_CONST( + static const secp256k1_fe fe = SECP256K1_FE_CONST( 0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL, 0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL ); - secp256k1_fe_t fe2; + secp256k1_fe fe2; unsigned char b322[32]; - secp256k1_fe_storage_t fes2; + secp256k1_fe_storage fes2; /* Check conversions to fe. */ CHECK(secp256k1_fe_set_b32(&fe2, b32)); CHECK(secp256k1_fe_equal_var(&fe, &fe2)); @@ -737,15 +1636,24 @@ void run_field_convert(void) { CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0); } +int fe_memcmp(const secp256k1_fe *a, const secp256k1_fe *b) { + secp256k1_fe t = *b; +#ifdef VERIFY + t.magnitude = a->magnitude; + t.normalized = a->normalized; +#endif + return memcmp(a, &t, sizeof(secp256k1_fe)); +} + void run_field_misc(void) { - secp256k1_fe_t x; - secp256k1_fe_t y; - secp256k1_fe_t z; - secp256k1_fe_t q; - secp256k1_fe_t fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); - int i; + secp256k1_fe x; + secp256k1_fe y; + secp256k1_fe z; + secp256k1_fe q; + secp256k1_fe fe5 = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 5); + int i, j; for (i = 0; i < 5*count; i++) { - secp256k1_fe_storage_t xs, ys, zs; + secp256k1_fe_storage xs, ys, zs; random_fe(&x); random_fe_non_zero(&y); /* Test the fe equality and comparison operations. */ @@ -756,14 +1664,27 @@ void run_field_misc(void) { /* Test fe conditional move; z is not normalized here. */ q = x; secp256k1_fe_cmov(&x, &z, 0); + VERIFY_CHECK(!x.normalized && x.magnitude == z.magnitude); secp256k1_fe_cmov(&x, &x, 1); - CHECK(memcmp(&x, &z, sizeof(x)) != 0); - CHECK(memcmp(&x, &q, sizeof(x)) == 0); + CHECK(fe_memcmp(&x, &z) != 0); + CHECK(fe_memcmp(&x, &q) == 0); secp256k1_fe_cmov(&q, &z, 1); - CHECK(memcmp(&q, &z, sizeof(q)) == 0); - /* Test storage conversion and conditional moves. */ - secp256k1_fe_normalize(&z); + VERIFY_CHECK(!q.normalized && q.magnitude == z.magnitude); + CHECK(fe_memcmp(&q, &z) == 0); + secp256k1_fe_normalize_var(&x); + secp256k1_fe_normalize_var(&z); CHECK(!secp256k1_fe_equal_var(&x, &z)); + secp256k1_fe_normalize_var(&q); + secp256k1_fe_cmov(&q, &z, (i&1)); + VERIFY_CHECK(q.normalized && q.magnitude == 1); + for (j = 0; j < 6; j++) { + secp256k1_fe_negate(&z, &z, j+1); + secp256k1_fe_normalize_var(&q); + secp256k1_fe_cmov(&q, &z, (j&1)); + VERIFY_CHECK(!q.normalized && q.magnitude == (j+2)); + } + secp256k1_fe_normalize_var(&z); + /* Test storage conversion and conditional moves. */ secp256k1_fe_to_storage(&xs, &x); secp256k1_fe_to_storage(&ys, &y); secp256k1_fe_to_storage(&zs, &z); @@ -797,7 +1718,7 @@ void run_field_misc(void) { } void run_field_inv(void) { - secp256k1_fe_t x, xi, xii; + secp256k1_fe x, xi, xii; int i; for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); @@ -809,7 +1730,7 @@ void run_field_inv(void) { } void run_field_inv_var(void) { - secp256k1_fe_t x, xi, xii; + secp256k1_fe x, xi, xii; int i; for (i = 0; i < 10*count; i++) { random_fe_non_zero(&x); @@ -821,21 +1742,21 @@ void run_field_inv_var(void) { } void run_field_inv_all_var(void) { - secp256k1_fe_t x[16], xi[16], xii[16]; + secp256k1_fe x[16], xi[16], xii[16]; int i; /* Check it's safe to call for 0 elements */ - secp256k1_fe_inv_all_var(0, xi, x); + secp256k1_fe_inv_all_var(xi, x, 0); for (i = 0; i < count; i++) { size_t j; - size_t len = (secp256k1_rand32() & 15) + 1; + size_t len = secp256k1_rand_int(15) + 1; for (j = 0; j < len; j++) { random_fe_non_zero(&x[j]); } - secp256k1_fe_inv_all_var(len, xi, x); + secp256k1_fe_inv_all_var(xi, x, len); for (j = 0; j < len; j++) { CHECK(check_fe_inverse(&x[j], &xi[j])); } - secp256k1_fe_inv_all_var(len, xii, xi); + secp256k1_fe_inv_all_var(xii, xi, len); for (j = 0; j < len; j++) { CHECK(check_fe_equal(&x[j], &xii[j])); } @@ -843,7 +1764,7 @@ void run_field_inv_all_var(void) { } void run_sqr(void) { - secp256k1_fe_t x, s; + secp256k1_fe x, s; { int i; @@ -858,9 +1779,9 @@ void run_sqr(void) { } } -void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { - secp256k1_fe_t r1, r2; - int v = secp256k1_fe_sqrt_var(&r1, a); +void test_sqrt(const secp256k1_fe *a, const secp256k1_fe *k) { + secp256k1_fe r1, r2; + int v = secp256k1_fe_sqrt(&r1, a); CHECK((v == 0) == (k == NULL)); if (k != NULL) { @@ -873,7 +1794,7 @@ void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { } void run_sqrt(void) { - secp256k1_fe_t ns, x, s, t; + secp256k1_fe ns, x, s, t; int i; /* Check sqrt(0) is 0 */ @@ -908,19 +1829,19 @@ void run_sqrt(void) { /***** GROUP TESTS *****/ -void ge_equals_ge(const secp256k1_ge_t *a, const secp256k1_ge_t *b) { +void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { CHECK(a->infinity == b->infinity); if (a->infinity) { return; } CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); - CHECK(secp256k1_fe_equal_var(&b->y, &b->y)); + CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); } /* This compares jacobian points including their Z, not just their geometric meaning. */ -int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { - secp256k1_gej_t a2; - secp256k1_gej_t b2; +int gej_xyz_equals_gej(const secp256k1_gej *a, const secp256k1_gej *b) { + secp256k1_gej a2; + secp256k1_gej b2; int ret = 1; ret &= a->infinity == b->infinity; if (ret && !a->infinity) { @@ -939,9 +1860,9 @@ int gej_xyz_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) { return ret; } -void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { - secp256k1_fe_t z2s; - secp256k1_fe_t u1, u2, s1, s2; +void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { + secp256k1_fe z2s; + secp256k1_fe u1, u2, s1, s2; CHECK(a->infinity == b->infinity); if (a->infinity) { return; @@ -958,21 +1879,39 @@ void ge_equals_gej(const secp256k1_ge_t *a, const secp256k1_gej_t *b) { void test_ge(void) { int i, i1; +#ifdef USE_ENDOMORPHISM + int runs = 6; +#else int runs = 4; +#endif /* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4). * The second in each pair of identical points uses a random Z coordinate in the Jacobian form. * All magnitudes are randomized. - * All 17*17 combinations of points are added to eachother, using all applicable methods. + * All 17*17 combinations of points are added to each other, using all applicable methods. + * + * When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well. */ - secp256k1_ge_t *ge = (secp256k1_ge_t *)malloc(sizeof(secp256k1_ge_t) * (1 + 4 * runs)); - secp256k1_gej_t *gej = (secp256k1_gej_t *)malloc(sizeof(secp256k1_gej_t) * (1 + 4 * runs)); + secp256k1_ge *ge = (secp256k1_ge *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_ge) * (1 + 4 * runs)); + secp256k1_gej *gej = (secp256k1_gej *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_gej) * (1 + 4 * runs)); + secp256k1_fe *zinv = (secp256k1_fe *)checked_malloc(&ctx->error_callback, sizeof(secp256k1_fe) * (1 + 4 * runs)); + secp256k1_fe zf; + secp256k1_fe zfi2, zfi3; + secp256k1_gej_set_infinity(&gej[0]); secp256k1_ge_clear(&ge[0]); secp256k1_ge_set_gej_var(&ge[0], &gej[0]); for (i = 0; i < runs; i++) { int j; - secp256k1_ge_t g; + secp256k1_ge g; random_group_element_test(&g); +#ifdef USE_ENDOMORPHISM + if (i >= runs - 2) { + secp256k1_ge_mul_lambda(&g, &ge[1]); + } + if (i >= runs - 1) { + secp256k1_ge_mul_lambda(&g, &g); + } +#endif ge[1 + 4 * i] = g; ge[2 + 4 * i] = g; secp256k1_ge_neg(&ge[3 + 4 * i], &g); @@ -990,18 +1929,65 @@ void test_ge(void) { } } + /* Compute z inverses. */ + { + secp256k1_fe *zs = checked_malloc(&ctx->error_callback, sizeof(secp256k1_fe) * (1 + 4 * runs)); + for (i = 0; i < 4 * runs + 1; i++) { + if (i == 0) { + /* The point at infinity does not have a meaningful z inverse. Any should do. */ + do { + random_field_element_test(&zs[i]); + } while(secp256k1_fe_is_zero(&zs[i])); + } else { + zs[i] = gej[i].z; + } + } + secp256k1_fe_inv_all_var(zinv, zs, 4 * runs + 1); + free(zs); + } + + /* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */ + do { + random_field_element_test(&zf); + } while(secp256k1_fe_is_zero(&zf)); + random_field_element_magnitude(&zf); + secp256k1_fe_inv_var(&zfi3, &zf); + secp256k1_fe_sqr(&zfi2, &zfi3); + secp256k1_fe_mul(&zfi3, &zfi3, &zfi2); + for (i1 = 0; i1 < 1 + 4 * runs; i1++) { int i2; for (i2 = 0; i2 < 1 + 4 * runs; i2++) { /* Compute reference result using gej + gej (var). */ - secp256k1_gej_t refj, resj; - secp256k1_ge_t ref; - secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2]); + secp256k1_gej refj, resj; + secp256k1_ge ref; + secp256k1_fe zr; + secp256k1_gej_add_var(&refj, &gej[i1], &gej[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); + /* Check Z ratio. */ + if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) { + secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zrz, &refj.z)); + } secp256k1_ge_set_gej_var(&ref, &refj); - /* Test gej + ge (var). */ - secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2]); + /* Test gej + ge with Z ratio result (var). */ + secp256k1_gej_add_ge_var(&resj, &gej[i1], &ge[i2], secp256k1_gej_is_infinity(&gej[i1]) ? NULL : &zr); ge_equals_gej(&ref, &resj); + if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) { + secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zrz, &resj.z)); + } + + /* Test gej + ge (var, with additional Z factor). */ + { + secp256k1_ge ge2_zfi = ge[i2]; /* the second term with x and y rescaled for z = 1/zf */ + secp256k1_fe_mul(&ge2_zfi.x, &ge2_zfi.x, &zfi2); + secp256k1_fe_mul(&ge2_zfi.y, &ge2_zfi.y, &zfi3); + random_field_element_magnitude(&ge2_zfi.x); + random_field_element_magnitude(&ge2_zfi.y); + secp256k1_gej_add_zinv_var(&resj, &gej[i1], &ge2_zfi, &zf); + ge_equals_gej(&ref, &resj); + } /* Test gej + ge (const). */ if (i2 != 0) { @@ -1012,10 +1998,15 @@ void test_ge(void) { /* Test doubling (var). */ if ((i1 == 0 && i2 == 0) || ((i1 + 3)/4 == (i2 + 3)/4 && ((i1 + 3)%4)/2 == ((i2 + 3)%4)/2)) { - /* Normal doubling. */ - secp256k1_gej_double_var(&resj, &gej[i1]); + secp256k1_fe zr2; + /* Normal doubling with Z ratio result. */ + secp256k1_gej_double_var(&resj, &gej[i1], &zr2); ge_equals_gej(&ref, &resj); - secp256k1_gej_double_var(&resj, &gej[i2]); + /* Check Z ratio. */ + secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z); + CHECK(secp256k1_fe_equal_var(&zr2, &resj.z)); + /* Normal doubling. */ + secp256k1_gej_double_var(&resj, &gej[i2], NULL); ge_equals_gej(&ref, &resj); } @@ -1040,41 +2031,121 @@ void test_ge(void) { /* Test adding all points together in random order equals infinity. */ { - secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY; - secp256k1_gej_t *gej_shuffled = (secp256k1_gej_t *)malloc((4 * runs + 1) * sizeof(secp256k1_gej_t)); + secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY; + secp256k1_gej *gej_shuffled = (secp256k1_gej *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_gej)); for (i = 0; i < 4 * runs + 1; i++) { gej_shuffled[i] = gej[i]; } for (i = 0; i < 4 * runs + 1; i++) { - int swap = i + secp256k1_rand32() % (4 * runs + 1 - i); + int swap = i + secp256k1_rand_int(4 * runs + 1 - i); if (swap != i) { - secp256k1_gej_t t = gej_shuffled[i]; + secp256k1_gej t = gej_shuffled[i]; gej_shuffled[i] = gej_shuffled[swap]; gej_shuffled[swap] = t; } } for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i]); + secp256k1_gej_add_var(&sum, &sum, &gej_shuffled[i], NULL); } CHECK(secp256k1_gej_is_infinity(&sum)); free(gej_shuffled); } - /* Test batch gej -> ge conversion. */ + /* Test batch gej -> ge conversion with and without known z ratios. */ { - secp256k1_ge_t *ge_set_all = (secp256k1_ge_t *)malloc((4 * runs + 1) * sizeof(secp256k1_ge_t)); - secp256k1_ge_set_all_gej_var(4 * runs + 1, ge_set_all, gej); + secp256k1_fe *zr = (secp256k1_fe *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_fe)); + secp256k1_ge *ge_set_table = (secp256k1_ge *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); + secp256k1_ge *ge_set_all = (secp256k1_ge *)checked_malloc(&ctx->error_callback, (4 * runs + 1) * sizeof(secp256k1_ge)); for (i = 0; i < 4 * runs + 1; i++) { - secp256k1_fe_t s; + /* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */ + if (i < 4 * runs) { + secp256k1_fe_mul(&zr[i + 1], &zinv[i], &gej[i + 1].z); + } + } + secp256k1_ge_set_table_gej_var(ge_set_table, gej, zr, 4 * runs + 1); + secp256k1_ge_set_all_gej_var(ge_set_all, gej, 4 * runs + 1, &ctx->error_callback); + for (i = 0; i < 4 * runs + 1; i++) { + secp256k1_fe s; random_fe_non_zero(&s); secp256k1_gej_rescale(&gej[i], &s); + ge_equals_gej(&ge_set_table[i], &gej[i]); ge_equals_gej(&ge_set_all[i], &gej[i]); } + free(ge_set_table); free(ge_set_all); + free(zr); } free(ge); free(gej); + free(zinv); +} + +void test_add_neg_y_diff_x(void) { + /* The point of this test is to check that we can add two points + * whose y-coordinates are negatives of each other but whose x + * coordinates differ. If the x-coordinates were the same, these + * points would be negatives of each other and their sum is + * infinity. This is cool because it "covers up" any degeneracy + * in the addition algorithm that would cause the xy coordinates + * of the sum to be wrong (since infinity has no xy coordinates). + * HOWEVER, if the x-coordinates are different, infinity is the + * wrong answer, and such degeneracies are exposed. This is the + * root of https://github.com/bitcoin-core/secp256k1/issues/257 + * which this test is a regression test for. + * + * These points were generated in sage as + * # secp256k1 params + * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + * C = EllipticCurve ([F (0), F (7)]) + * G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798) + * N = FiniteField(G.order()) + * + * # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F) + * x = polygen(N) + * lam = (1 - x^3).roots()[1][0] + * + * # random "bad pair" + * P = C.random_element() + * Q = -int(lam) * P + * print " P: %x %x" % P.xy() + * print " Q: %x %x" % Q.xy() + * print "P + Q: %x %x" % (P + Q).xy() + */ + secp256k1_gej aj = SECP256K1_GEJ_CONST( + 0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30, + 0x0643d79f, 0x05a59614, 0x2f8ec030, 0xd58977cb, + 0x001e337a, 0x38093dcd, 0x6c0f386d, 0x0b1293a8, + 0x4d72c879, 0xd7681924, 0x44e6d2f3, 0x9190117d + ); + secp256k1_gej bj = SECP256K1_GEJ_CONST( + 0xc7b74206, 0x1f788cd9, 0xabd0937d, 0x164a0d86, + 0x95f6ff75, 0xf19a4ce9, 0xd013bd7b, 0xbf92d2a7, + 0xffe1cc85, 0xc7f6c232, 0x93f0c792, 0xf4ed6c57, + 0xb28d3786, 0x2897e6db, 0xbb192d0b, 0x6e6feab2 + ); + secp256k1_gej sumj = SECP256K1_GEJ_CONST( + 0x671a63c0, 0x3efdad4c, 0x389a7798, 0x24356027, + 0xb3d69010, 0x278625c3, 0x5c86d390, 0x184a8f7a, + 0x5f6409c2, 0x2ce01f2b, 0x511fd375, 0x25071d08, + 0xda651801, 0x70e95caf, 0x8f0d893c, 0xbed8fbbe + ); + secp256k1_ge b; + secp256k1_gej resj; + secp256k1_ge res; + secp256k1_ge_set_gej(&b, &bj); + + secp256k1_gej_add_var(&resj, &aj, &bj, NULL); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); + + secp256k1_gej_add_ge(&resj, &aj, &b); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); + + secp256k1_gej_add_ge_var(&resj, &aj, &b, NULL); + secp256k1_ge_set_gej(&res, &resj); + ge_equals_gej(&res, &sumj); } void run_ge(void) { @@ -1082,36 +2153,142 @@ void run_ge(void) { for (i = 0; i < count * 32; i++) { test_ge(); } + test_add_neg_y_diff_x(); +} + +void test_ec_combine(void) { + secp256k1_scalar sum = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_pubkey data[6]; + const secp256k1_pubkey* d[6]; + secp256k1_pubkey sd; + secp256k1_pubkey sd2; + secp256k1_gej Qj; + secp256k1_ge Q; + int i; + for (i = 1; i <= 6; i++) { + secp256k1_scalar s; + random_scalar_order_test(&s); + secp256k1_scalar_add(&sum, &sum, &s); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &s); + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(&data[i - 1], &Q); + d[i - 1] = &data[i - 1]; + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &Qj, &sum); + secp256k1_ge_set_gej(&Q, &Qj); + secp256k1_pubkey_save(&sd, &Q); + CHECK(secp256k1_ec_pubkey_combine(ctx, &sd2, d, i) == 1); + CHECK(memcmp(&sd, &sd2, sizeof(sd)) == 0); + } +} + +void run_ec_combine(void) { + int i; + for (i = 0; i < count * 8; i++) { + test_ec_combine(); + } +} + +void test_group_decompress(const secp256k1_fe* x) { + /* The input itself, normalized. */ + secp256k1_fe fex = *x; + secp256k1_fe fez; + /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */ + secp256k1_ge ge_quad, ge_even, ge_odd; + secp256k1_gej gej_quad; + /* Return values of the above calls. */ + int res_quad, res_even, res_odd; + + secp256k1_fe_normalize_var(&fex); + + res_quad = secp256k1_ge_set_xquad(&ge_quad, &fex); + res_even = secp256k1_ge_set_xo_var(&ge_even, &fex, 0); + res_odd = secp256k1_ge_set_xo_var(&ge_odd, &fex, 1); + + CHECK(res_quad == res_even); + CHECK(res_quad == res_odd); + + if (res_quad) { + secp256k1_fe_normalize_var(&ge_quad.x); + secp256k1_fe_normalize_var(&ge_odd.x); + secp256k1_fe_normalize_var(&ge_even.x); + secp256k1_fe_normalize_var(&ge_quad.y); + secp256k1_fe_normalize_var(&ge_odd.y); + secp256k1_fe_normalize_var(&ge_even.y); + + /* No infinity allowed. */ + CHECK(!ge_quad.infinity); + CHECK(!ge_even.infinity); + CHECK(!ge_odd.infinity); + + /* Check that the x coordinates check out. */ + CHECK(secp256k1_fe_equal_var(&ge_quad.x, x)); + CHECK(secp256k1_fe_equal_var(&ge_even.x, x)); + CHECK(secp256k1_fe_equal_var(&ge_odd.x, x)); + + /* Check that the Y coordinate result in ge_quad is a square. */ + CHECK(secp256k1_fe_is_quad_var(&ge_quad.y)); + + /* Check odd/even Y in ge_odd, ge_even. */ + CHECK(secp256k1_fe_is_odd(&ge_odd.y)); + CHECK(!secp256k1_fe_is_odd(&ge_even.y)); + + /* Check secp256k1_gej_has_quad_y_var. */ + secp256k1_gej_set_ge(&gej_quad, &ge_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + do { + random_fe_test(&fez); + } while (secp256k1_fe_is_zero(&fez)); + secp256k1_gej_rescale(&gej_quad, &fez); + CHECK(!secp256k1_gej_has_quad_y_var(&gej_quad)); + secp256k1_gej_neg(&gej_quad, &gej_quad); + CHECK(secp256k1_gej_has_quad_y_var(&gej_quad)); + } +} + +void run_group_decompress(void) { + int i; + for (i = 0; i < count * 4; i++) { + secp256k1_fe fe; + random_fe_test(&fe); + test_group_decompress(&fe); + } } /***** ECMULT TESTS *****/ void run_ecmult_chain(void) { /* random starting point A (on the curve) */ - secp256k1_gej_t a = SECP256K1_GEJ_CONST( + secp256k1_gej a = SECP256K1_GEJ_CONST( 0x8b30bbe9, 0xae2a9906, 0x96b22f67, 0x0709dff3, 0x727fd8bc, 0x04d3362c, 0x6c7bf458, 0xe2846004, 0xa357ae91, 0x5c4a6528, 0x1309edf2, 0x0504740f, 0x0eb33439, 0x90216b4f, 0x81063cb6, 0x5f2f7e0f ); /* two random initial factors xn and gn */ - secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST( + secp256k1_scalar xn = SECP256K1_SCALAR_CONST( 0x84cc5452, 0xf7fde1ed, 0xb4d38a8c, 0xe9b1b84c, 0xcef31f14, 0x6e569be9, 0x705d357a, 0x42985407 ); - secp256k1_scalar_t gn = SECP256K1_SCALAR_CONST( + secp256k1_scalar gn = SECP256K1_SCALAR_CONST( 0xa1e58d22, 0x553dcd42, 0xb2398062, 0x5d4c57a9, 0x6e9323d4, 0x2b3152e5, 0xca2c3990, 0xedc7c9de ); /* two small multipliers to be applied to xn and gn in every iteration: */ - static const secp256k1_scalar_t xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); - static const secp256k1_scalar_t gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); + static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x1337); + static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0x7113); /* accumulators with the resulting coefficients to A and G */ - secp256k1_scalar_t ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); - secp256k1_scalar_t ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar ae = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_scalar ge = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); /* actual points */ - secp256k1_gej_t x = a; - secp256k1_gej_t x2; + secp256k1_gej x; + secp256k1_gej x2; int i; /* the point being computed */ @@ -1131,7 +2308,7 @@ void run_ecmult_chain(void) { /* verify */ if (i == 19999) { /* expected result after 19999 iterations */ - secp256k1_gej_t rp = SECP256K1_GEJ_CONST( + secp256k1_gej rp = SECP256K1_GEJ_CONST( 0xD6E96687, 0xF9B10D09, 0x2A6F3543, 0x9D86CEBE, 0xA4535D0D, 0x409F5358, 0x6440BD74, 0xB933E830, 0xB95CBCA2, 0xC77DA786, 0x539BE8FD, 0x53354D2D, @@ -1139,30 +2316,32 @@ void run_ecmult_chain(void) { ); secp256k1_gej_neg(&rp, &rp); - secp256k1_gej_add_var(&rp, &rp, &x); + secp256k1_gej_add_var(&rp, &rp, &x, NULL); CHECK(secp256k1_gej_is_infinity(&rp)); } } /* redo the computation, but directly with the resulting ae and ge coefficients: */ secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge); secp256k1_gej_neg(&x2, &x2); - secp256k1_gej_add_var(&x2, &x2, &x); + secp256k1_gej_add_var(&x2, &x2, &x, NULL); CHECK(secp256k1_gej_is_infinity(&x2)); } -void test_point_times_order(const secp256k1_gej_t *point) { +void test_point_times_order(const secp256k1_gej *point) { /* X * (point + G) + (order-X) * (pointer + G) = 0 */ - secp256k1_scalar_t x; - secp256k1_scalar_t nx; - secp256k1_gej_t res1, res2; - secp256k1_ge_t res3; + secp256k1_scalar x; + secp256k1_scalar nx; + secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_gej res1, res2; + secp256k1_ge res3; unsigned char pub[65]; - int psize = 65; + size_t psize = 65; random_scalar_order_test(&x); secp256k1_scalar_negate(&nx, &x); secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */ secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ - secp256k1_gej_add_var(&res1, &res1, &res2); + secp256k1_gej_add_var(&res1, &res1, &res2, NULL); CHECK(secp256k1_gej_is_infinity(&res1)); CHECK(secp256k1_gej_is_valid_var(&res1) == 0); secp256k1_ge_set_gej(&res3, &res1); @@ -1171,19 +2350,29 @@ void test_point_times_order(const secp256k1_gej_t *point) { CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0); psize = 65; CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0); + /* check zero/one edge cases */ + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero); + secp256k1_ge_set_gej(&res3, &res1); + CHECK(secp256k1_ge_is_infinity(&res3)); + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &one, &zero); + secp256k1_ge_set_gej(&res3, &res1); + ge_equals_gej(&res3, point); + secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &one); + secp256k1_ge_set_gej(&res3, &res1); + ge_equals_ge(&res3, &secp256k1_ge_const_g); } void run_point_times_order(void) { int i; - secp256k1_fe_t x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); - static const secp256k1_fe_t xr = SECP256K1_FE_CONST( + secp256k1_fe x = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); + static const secp256k1_fe xr = SECP256K1_FE_CONST( 0x7603CB59, 0xB0EF6C63, 0xFE608479, 0x2A0C378C, 0xDB3233A8, 0x0F8A9A09, 0xA877DEAD, 0x31B38C45 ); for (i = 0; i < 500; i++) { - secp256k1_ge_t p; + secp256k1_ge p; if (secp256k1_ge_set_xo_var(&p, &x, 1)) { - secp256k1_gej_t j; + secp256k1_gej j; CHECK(secp256k1_ge_is_valid_var(&p)); secp256k1_gej_set_ge(&j, &p); CHECK(secp256k1_gej_is_valid_var(&j)); @@ -1195,15 +2384,118 @@ void run_point_times_order(void) { CHECK(secp256k1_fe_equal_var(&x, &xr)); } -void test_wnaf(const secp256k1_scalar_t *number, int w) { - secp256k1_scalar_t x, two, t; +void ecmult_const_random_mult(void) { + /* random starting point A (on the curve) */ + secp256k1_ge a = SECP256K1_GE_CONST( + 0x6d986544, 0x57ff52b8, 0xcf1b8126, 0x5b802a5b, + 0xa97f9263, 0xb1e88044, 0x93351325, 0x91bc450a, + 0x535c59f7, 0x325e5d2b, 0xc391fbe8, 0x3c12787c, + 0x337e4a98, 0xe82a9011, 0x0123ba37, 0xdd769c7d + ); + /* random initial factor xn */ + secp256k1_scalar xn = SECP256K1_SCALAR_CONST( + 0x649d4f77, 0xc4242df7, 0x7f2079c9, 0x14530327, + 0xa31b876a, 0xd2d8ce2a, 0x2236d5c6, 0xd7b2029b + ); + /* expected xn * A (from sage) */ + secp256k1_ge expected_b = SECP256K1_GE_CONST( + 0x23773684, 0x4d209dc7, 0x098a786f, 0x20d06fcd, + 0x070a38bf, 0xc11ac651, 0x03004319, 0x1e2a8786, + 0xed8c3b8e, 0xc06dd57b, 0xd06ea66e, 0x45492b0f, + 0xb84e4e1b, 0xfb77e21f, 0x96baae2a, 0x63dec956 + ); + secp256k1_gej b; + secp256k1_ecmult_const(&b, &a, &xn); + + CHECK(secp256k1_ge_is_valid_var(&a)); + ge_equals_gej(&expected_b, &b); +} + +void ecmult_const_commutativity(void) { + secp256k1_scalar a; + secp256k1_scalar b; + secp256k1_gej res1; + secp256k1_gej res2; + secp256k1_ge mid1; + secp256k1_ge mid2; + random_scalar_order_test(&a); + random_scalar_order_test(&b); + + secp256k1_ecmult_const(&res1, &secp256k1_ge_const_g, &a); + secp256k1_ecmult_const(&res2, &secp256k1_ge_const_g, &b); + secp256k1_ge_set_gej(&mid1, &res1); + secp256k1_ge_set_gej(&mid2, &res2); + secp256k1_ecmult_const(&res1, &mid1, &b); + secp256k1_ecmult_const(&res2, &mid2, &a); + secp256k1_ge_set_gej(&mid1, &res1); + secp256k1_ge_set_gej(&mid2, &res2); + ge_equals_ge(&mid1, &mid2); +} + +void ecmult_const_mult_zero_one(void) { + secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0); + secp256k1_scalar one = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 1); + secp256k1_scalar negone; + secp256k1_gej res1; + secp256k1_ge res2; + secp256k1_ge point; + secp256k1_scalar_negate(&negone, &one); + + random_group_element_test(&point); + secp256k1_ecmult_const(&res1, &point, &zero); + secp256k1_ge_set_gej(&res2, &res1); + CHECK(secp256k1_ge_is_infinity(&res2)); + secp256k1_ecmult_const(&res1, &point, &one); + secp256k1_ge_set_gej(&res2, &res1); + ge_equals_ge(&res2, &point); + secp256k1_ecmult_const(&res1, &point, &negone); + secp256k1_gej_neg(&res1, &res1); + secp256k1_ge_set_gej(&res2, &res1); + ge_equals_ge(&res2, &point); +} + +void ecmult_const_chain_multiply(void) { + /* Check known result (randomly generated test problem from sage) */ + const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST( + 0x4968d524, 0x2abf9b7a, 0x466abbcf, 0x34b11b6d, + 0xcd83d307, 0x827bed62, 0x05fad0ce, 0x18fae63b + ); + const secp256k1_gej expected_point = SECP256K1_GEJ_CONST( + 0x5494c15d, 0x32099706, 0xc2395f94, 0x348745fd, + 0x757ce30e, 0x4e8c90fb, 0xa2bad184, 0xf883c69f, + 0x5d195d20, 0xe191bf7f, 0x1be3e55f, 0x56a80196, + 0x6071ad01, 0xf1462f66, 0xc997fa94, 0xdb858435 + ); + secp256k1_gej point; + secp256k1_ge res; + int i; + + secp256k1_gej_set_ge(&point, &secp256k1_ge_const_g); + for (i = 0; i < 100; ++i) { + secp256k1_ge tmp; + secp256k1_ge_set_gej(&tmp, &point); + secp256k1_ecmult_const(&point, &tmp, &scalar); + } + secp256k1_ge_set_gej(&res, &point); + ge_equals_gej(&res, &expected_point); +} + +void run_ecmult_const_tests(void) { + ecmult_const_mult_zero_one(); + ecmult_const_random_mult(); + ecmult_const_commutativity(); + ecmult_const_chain_multiply(); +} + +void test_wnaf(const secp256k1_scalar *number, int w) { + secp256k1_scalar x, two, t; int wnaf[256]; int zeroes = -1; int i; int bits; secp256k1_scalar_set_int(&x, 0); secp256k1_scalar_set_int(&two, 2); - bits = secp256k1_ecmult_wnaf(wnaf, number, w); + bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w); CHECK(bits <= 256); for (i = bits-1; i >= 0; i--) { int v = wnaf[i]; @@ -1229,20 +2521,89 @@ void test_wnaf(const secp256k1_scalar_t *number, int w) { CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ } +void test_constant_wnaf_negate(const secp256k1_scalar *number) { + secp256k1_scalar neg1 = *number; + secp256k1_scalar neg2 = *number; + int sign1 = 1; + int sign2 = 1; + + if (!secp256k1_scalar_get_bits(&neg1, 0, 1)) { + secp256k1_scalar_negate(&neg1, &neg1); + sign1 = -1; + } + sign2 = secp256k1_scalar_cond_negate(&neg2, secp256k1_scalar_is_even(&neg2)); + CHECK(sign1 == sign2); + CHECK(secp256k1_scalar_eq(&neg1, &neg2)); +} + +void test_constant_wnaf(const secp256k1_scalar *number, int w) { + secp256k1_scalar x, shift; + int wnaf[256] = {0}; + int i; + int skew; + secp256k1_scalar num = *number; + + secp256k1_scalar_set_int(&x, 0); + secp256k1_scalar_set_int(&shift, 1 << w); + /* With USE_ENDOMORPHISM on we only consider 128-bit numbers */ +#ifdef USE_ENDOMORPHISM + for (i = 0; i < 16; ++i) { + secp256k1_scalar_shr_int(&num, 8); + } +#endif + skew = secp256k1_wnaf_const(wnaf, num, w); + + for (i = WNAF_SIZE(w); i >= 0; --i) { + secp256k1_scalar t; + int v = wnaf[i]; + CHECK(v != 0); /* check nonzero */ + CHECK(v & 1); /* check parity */ + CHECK(v > -(1 << w)); /* check range above */ + CHECK(v < (1 << w)); /* check range below */ + + secp256k1_scalar_mul(&x, &x, &shift); + if (v >= 0) { + secp256k1_scalar_set_int(&t, v); + } else { + secp256k1_scalar_set_int(&t, -v); + secp256k1_scalar_negate(&t, &t); + } + secp256k1_scalar_add(&x, &x, &t); + } + /* Skew num because when encoding numbers as odd we use an offset */ + secp256k1_scalar_cadd_bit(&num, skew == 2, 1); + CHECK(secp256k1_scalar_eq(&x, &num)); +} + void run_wnaf(void) { int i; - secp256k1_scalar_t n; + secp256k1_scalar n = {{0}}; + + /* Sanity check: 1 and 2 are the smallest odd and even numbers and should + * have easier-to-diagnose failure modes */ + n.d[0] = 1; + test_constant_wnaf(&n, 4); + n.d[0] = 2; + test_constant_wnaf(&n, 4); + /* Random tests */ for (i = 0; i < count; i++) { random_scalar_order(&n); test_wnaf(&n, 4+(i%10)); + test_constant_wnaf_negate(&n); + test_constant_wnaf(&n, 4 + (i % 10)); } + secp256k1_scalar_set_int(&n, 0); + CHECK(secp256k1_scalar_cond_negate(&n, 1) == -1); + CHECK(secp256k1_scalar_is_zero(&n)); + CHECK(secp256k1_scalar_cond_negate(&n, 0) == 1); + CHECK(secp256k1_scalar_is_zero(&n)); } void test_ecmult_constants(void) { /* Test ecmult_gen() for [0..36) and [order-36..0). */ - secp256k1_scalar_t x; - secp256k1_gej_t r; - secp256k1_ge_t ng; + secp256k1_scalar x; + secp256k1_gej r; + secp256k1_ge ng; int i; int j; secp256k1_ge_neg(&ng, &secp256k1_ge_const_g); @@ -1276,14 +2637,14 @@ void run_ecmult_constants(void) { } void test_ecmult_gen_blind(void) { - /* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */ - secp256k1_scalar_t key; - secp256k1_scalar_t b; + /* Test ecmult_gen() blinding and confirm that the blinding changes, the affine points match, and the z's don't match. */ + secp256k1_scalar key; + secp256k1_scalar b; unsigned char seed32[32]; - secp256k1_gej_t pgej; - secp256k1_gej_t pgej2; - secp256k1_gej_t i; - secp256k1_ge_t pge; + secp256k1_gej pgej; + secp256k1_gej pgej2; + secp256k1_gej i; + secp256k1_ge pge; random_scalar_order_test(&key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pgej, &key); secp256k1_rand256(seed32); @@ -1300,8 +2661,8 @@ void test_ecmult_gen_blind(void) { void test_ecmult_gen_blind_reset(void) { /* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */ - secp256k1_scalar_t b; - secp256k1_gej_t initial; + secp256k1_scalar b; + secp256k1_gej initial; secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, 0); b = ctx->ecmult_gen_ctx.blind; initial = ctx->ecmult_gen_ctx.initial; @@ -1318,35 +2679,702 @@ void run_ecmult_gen_blind(void) { } } +#ifdef USE_ENDOMORPHISM +/***** ENDOMORPHISH TESTS *****/ +void test_scalar_split(void) { + secp256k1_scalar full; + secp256k1_scalar s1, slam; + const unsigned char zero[32] = {0}; + unsigned char tmp[32]; -void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) { - secp256k1_scalar_t nonce; + random_scalar_order_test(&full); + secp256k1_scalar_split_lambda(&s1, &slam, &full); + + /* check that both are <= 128 bits in size */ + if (secp256k1_scalar_is_high(&s1)) { + secp256k1_scalar_negate(&s1, &s1); + } + if (secp256k1_scalar_is_high(&slam)) { + secp256k1_scalar_negate(&slam, &slam); + } + + secp256k1_scalar_get_b32(tmp, &s1); + CHECK(memcmp(zero, tmp, 16) == 0); + secp256k1_scalar_get_b32(tmp, &slam); + CHECK(memcmp(zero, tmp, 16) == 0); +} + +void run_endomorphism_tests(void) { + test_scalar_split(); +} +#endif + +void ec_pubkey_parse_pointtest(const unsigned char *input, int xvalid, int yvalid) { + unsigned char pubkeyc[65]; + secp256k1_pubkey pubkey; + secp256k1_ge ge; + size_t pubkeyclen; + int32_t ecount; + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + for (pubkeyclen = 3; pubkeyclen <= 65; pubkeyclen++) { + /* Smaller sizes are tested exhaustively elsewhere. */ + int32_t i; + memcpy(&pubkeyc[1], input, 64); + VG_UNDEF(&pubkeyc[pubkeyclen], 65 - pubkeyclen); + for (i = 0; i < 256; i++) { + /* Try all type bytes. */ + int xpass; + int ypass; + int ysign; + pubkeyc[0] = i; + /* What sign does this point have? */ + ysign = (input[63] & 1) + 2; + /* For the current type (i) do we expect parsing to work? Handled all of compressed/uncompressed/hybrid. */ + xpass = xvalid && (pubkeyclen == 33) && ((i & 254) == 2); + /* Do we expect a parse and re-serialize as uncompressed to give a matching y? */ + ypass = xvalid && yvalid && ((i & 4) == ((pubkeyclen == 65) << 2)) && + ((i == 4) || ((i & 251) == ysign)) && ((pubkeyclen == 33) || (pubkeyclen == 65)); + if (xpass || ypass) { + /* These cases must parse. */ + unsigned char pubkeyo[65]; + size_t outl; + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + ecount = 0; + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + outl = 65; + VG_UNDEF(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + VG_CHECK(pubkeyo, outl); + CHECK(outl == 33); + CHECK(memcmp(&pubkeyo[1], &pubkeyc[1], 32) == 0); + CHECK((pubkeyclen != 33) || (pubkeyo[0] == pubkeyc[0])); + if (ypass) { + /* This test isn't always done because we decode with alternative signs, so the y won't match. */ + CHECK(pubkeyo[0] == ysign); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + secp256k1_pubkey_save(&pubkey, &ge); + VG_CHECK(&pubkey, sizeof(pubkey)); + outl = 65; + VG_UNDEF(pubkeyo, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyo, &outl, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + VG_CHECK(pubkeyo, outl); + CHECK(outl == 65); + CHECK(pubkeyo[0] == 4); + CHECK(memcmp(&pubkeyo[1], input, 64) == 0); + } + CHECK(ecount == 0); + } else { + /* These cases must fail to parse. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + } + } + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); +} + +void run_ec_pubkey_parse_test(void) { +#define SECP256K1_EC_PARSE_TEST_NVALID (12) + const unsigned char valid[SECP256K1_EC_PARSE_TEST_NVALID][64] = { + { + /* Point with leading and trailing zeros in x and y serialization. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x52, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xef, 0xa1, 0x7b, 0x77, 0x61, 0xe1, 0xe4, 0x27, 0x06, 0x98, 0x9f, 0xb4, 0x83, + 0xb8, 0xd2, 0xd4, 0x9b, 0xf7, 0x8f, 0xae, 0x98, 0x03, 0xf0, 0x99, 0xb8, 0x34, 0xed, 0xeb, 0x00 + }, + { + /* Point with x equal to a 3rd root of unity.*/ + 0x7a, 0xe9, 0x6a, 0x2b, 0x65, 0x7c, 0x07, 0x10, 0x6e, 0x64, 0x47, 0x9e, 0xac, 0x34, 0x34, 0xe9, + 0x9c, 0xf0, 0x49, 0x75, 0x12, 0xf5, 0x89, 0x95, 0xc1, 0x39, 0x6c, 0x28, 0x71, 0x95, 0x01, 0xee, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Point with largest x. (1/2) */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c, + 0x0e, 0x99, 0x4b, 0x14, 0xea, 0x72, 0xf8, 0xc3, 0xeb, 0x95, 0xc7, 0x1e, 0xf6, 0x92, 0x57, 0x5e, + 0x77, 0x50, 0x58, 0x33, 0x2d, 0x7e, 0x52, 0xd0, 0x99, 0x5c, 0xf8, 0x03, 0x88, 0x71, 0xb6, 0x7d, + }, + { + /* Point with largest x. (2/2) */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2c, + 0xf1, 0x66, 0xb4, 0xeb, 0x15, 0x8d, 0x07, 0x3c, 0x14, 0x6a, 0x38, 0xe1, 0x09, 0x6d, 0xa8, 0xa1, + 0x88, 0xaf, 0xa7, 0xcc, 0xd2, 0x81, 0xad, 0x2f, 0x66, 0xa3, 0x07, 0xfb, 0x77, 0x8e, 0x45, 0xb2, + }, + { + /* Point with smallest x. (1/2) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Point with smallest x. (2/2) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, + 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, + }, + { + /* Point with largest y. (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, + }, + { + /* Point with largest y. (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, + }, + { + /* Point with largest y. (3/3) */ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, + }, + { + /* Point with smallest y. (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + { + /* Point with smallest y. (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + { + /* Point with smallest y. (3/3) */ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + } + }; +#define SECP256K1_EC_PARSE_TEST_NXVALID (4) + const unsigned char onlyxvalid[SECP256K1_EC_PARSE_TEST_NXVALID][64] = { + { + /* Valid if y overflow ignored (y = 1 mod p). (1/3) */ + 0x1f, 0xe1, 0xe5, 0xef, 0x3f, 0xce, 0xb5, 0xc1, 0x35, 0xab, 0x77, 0x41, 0x33, 0x3c, 0xe5, 0xa6, + 0xe8, 0x0d, 0x68, 0x16, 0x76, 0x53, 0xf6, 0xb2, 0xb2, 0x4b, 0xcb, 0xcf, 0xaa, 0xaf, 0xf5, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, + }, + { + /* Valid if y overflow ignored (y = 1 mod p). (2/3) */ + 0xcb, 0xb0, 0xde, 0xab, 0x12, 0x57, 0x54, 0xf1, 0xfd, 0xb2, 0x03, 0x8b, 0x04, 0x34, 0xed, 0x9c, + 0xb3, 0xfb, 0x53, 0xab, 0x73, 0x53, 0x91, 0x12, 0x99, 0x94, 0xa5, 0x35, 0xd9, 0x25, 0xf6, 0x73, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, + }, + { + /* Valid if y overflow ignored (y = 1 mod p). (3/3)*/ + 0x14, 0x6d, 0x3b, 0x65, 0xad, 0xd9, 0xf5, 0x4c, 0xcc, 0xa2, 0x85, 0x33, 0xc8, 0x8e, 0x2c, 0xbc, + 0x63, 0xf7, 0x44, 0x3e, 0x16, 0x58, 0x78, 0x3a, 0xb4, 0x1f, 0x8e, 0xf9, 0x7c, 0x2a, 0x10, 0xb5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, + }, + { + /* x on curve, y is from y^2 = x^3 + 8. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 + } + }; +#define SECP256K1_EC_PARSE_TEST_NINVALID (7) + const unsigned char invalid[SECP256K1_EC_PARSE_TEST_NINVALID][64] = { + { + /* x is third root of -8, y is -1 * (x^3+7); also on the curve for y^2 = x^3 + 9. */ + 0x0a, 0x2d, 0x2b, 0xa9, 0x35, 0x07, 0xf1, 0xdf, 0x23, 0x37, 0x70, 0xc2, 0xa7, 0x97, 0x96, 0x2c, + 0xc6, 0x1f, 0x6d, 0x15, 0xda, 0x14, 0xec, 0xd4, 0x7d, 0x8d, 0x27, 0xae, 0x1c, 0xd5, 0xf8, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + }, + { + /* Valid if x overflow ignored (x = 1 mod p). */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, + 0x42, 0x18, 0xf2, 0x0a, 0xe6, 0xc6, 0x46, 0xb3, 0x63, 0xdb, 0x68, 0x60, 0x58, 0x22, 0xfb, 0x14, + 0x26, 0x4c, 0xa8, 0xd2, 0x58, 0x7f, 0xdd, 0x6f, 0xbc, 0x75, 0x0d, 0x58, 0x7e, 0x76, 0xa7, 0xee, + }, + { + /* Valid if x overflow ignored (x = 1 mod p). */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x30, + 0xbd, 0xe7, 0x0d, 0xf5, 0x19, 0x39, 0xb9, 0x4c, 0x9c, 0x24, 0x97, 0x9f, 0xa7, 0xdd, 0x04, 0xeb, + 0xd9, 0xb3, 0x57, 0x2d, 0xa7, 0x80, 0x22, 0x90, 0x43, 0x8a, 0xf2, 0xa6, 0x81, 0x89, 0x54, 0x41, + }, + { + /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, + 0xf4, 0x84, 0x14, 0x5c, 0xb0, 0x14, 0x9b, 0x82, 0x5d, 0xff, 0x41, 0x2f, 0xa0, 0x52, 0xa8, 0x3f, + 0xcb, 0x72, 0xdb, 0x61, 0xd5, 0x6f, 0x37, 0x70, 0xce, 0x06, 0x6b, 0x73, 0x49, 0xa2, 0xaa, 0x28, + }, + { + /* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2e, + 0x0b, 0x7b, 0xeb, 0xa3, 0x4f, 0xeb, 0x64, 0x7d, 0xa2, 0x00, 0xbe, 0xd0, 0x5f, 0xad, 0x57, 0xc0, + 0x34, 0x8d, 0x24, 0x9e, 0x2a, 0x90, 0xc8, 0x8f, 0x31, 0xf9, 0x94, 0x8b, 0xb6, 0x5d, 0x52, 0x07, + }, + { + /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8f, 0x53, 0x7e, 0xef, 0xdf, 0xc1, 0x60, 0x6a, 0x07, 0x27, 0xcd, 0x69, 0xb4, 0xa7, 0x33, 0x3d, + 0x38, 0xed, 0x44, 0xe3, 0x93, 0x2a, 0x71, 0x79, 0xee, 0xcb, 0x4b, 0x6f, 0xba, 0x93, 0x60, 0xdc, + }, + { + /* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0xac, 0x81, 0x10, 0x20, 0x3e, 0x9f, 0x95, 0xf8, 0xd8, 0x32, 0x96, 0x4b, 0x58, 0xcc, 0xc2, + 0xc7, 0x12, 0xbb, 0x1c, 0x6c, 0xd5, 0x8e, 0x86, 0x11, 0x34, 0xb4, 0x8f, 0x45, 0x6c, 0x9b, 0x53 + } + }; + const unsigned char pubkeyc[66] = { + /* Serialization of G. */ + 0x04, 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B, + 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, + 0x98, 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08, + 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10, 0xD4, + 0xB8, 0x00 + }; + unsigned char sout[65]; + unsigned char shortkey[2]; + secp256k1_ge ge; + secp256k1_pubkey pubkey; + size_t len; + int32_t i; + int32_t ecount; + int32_t ecount2; + ecount = 0; + /* Nothing should be reading this far into pubkeyc. */ + VG_UNDEF(&pubkeyc[65], 1); + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + /* Zero length claimed, fail, zeroize, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(shortkey, 2); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 0) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* Length one claimed, fail, zeroize, no illegal arg error. */ + for (i = 0; i < 256 ; i++) { + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + shortkey[0] = i; + VG_UNDEF(&shortkey[1], 1); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 1) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + /* Length two claimed, fail, zeroize, no illegal arg error. */ + for (i = 0; i < 65536 ; i++) { + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + shortkey[0] = i & 255; + shortkey[1] = i >> 8; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, shortkey, 2) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + } + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + /* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */ + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 33) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */ + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, pubkeyc, 65) == 0); + CHECK(ecount == 2); + /* NULL input string. Illegal arg and zeroize output. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, NULL, 65) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 1); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 2); + /* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 64) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* 66 bytes claimed, fail, zeroize output, no illegal arg error. */ + memset(&pubkey, 0xfe, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 66) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 0); + CHECK(ecount == 1); + /* Valid parse. */ + memset(&pubkey, 0, sizeof(pubkey)); + ecount = 0; + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, 65) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(ecount == 0); + VG_UNDEF(&ge, sizeof(ge)); + CHECK(secp256k1_pubkey_load(ctx, &ge, &pubkey) == 1); + VG_CHECK(&ge.x, sizeof(ge.x)); + VG_CHECK(&ge.y, sizeof(ge.y)); + VG_CHECK(&ge.infinity, sizeof(ge.infinity)); + ge_equals_ge(&secp256k1_ge_const_g, &ge); + CHECK(ecount == 0); + /* secp256k1_ec_pubkey_serialize illegal args. */ + ecount = 0; + len = 65; + CHECK(secp256k1_ec_pubkey_serialize(ctx, NULL, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); + CHECK(ecount == 1); + CHECK(len == 0); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, NULL, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 0); + CHECK(ecount == 2); + len = 65; + VG_UNDEF(sout, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, NULL, SECP256K1_EC_UNCOMPRESSED) == 0); + VG_CHECK(sout, 65); + CHECK(ecount == 3); + CHECK(len == 0); + len = 65; + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, ~0) == 0); + CHECK(ecount == 4); + CHECK(len == 0); + len = 65; + VG_UNDEF(sout, 65); + CHECK(secp256k1_ec_pubkey_serialize(ctx, sout, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED) == 1); + VG_CHECK(sout, 65); + CHECK(ecount == 4); + CHECK(len == 65); + /* Multiple illegal args. Should still set arg error only once. */ + ecount = 0; + ecount2 = 11; + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); + CHECK(ecount == 1); + /* Does the illegal arg callback actually change the behavior? */ + secp256k1_context_set_illegal_callback(ctx, uncounting_illegal_callback_fn, &ecount2); + CHECK(secp256k1_ec_pubkey_parse(ctx, NULL, NULL, 65) == 0); + CHECK(ecount == 1); + CHECK(ecount2 == 10); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); + /* Try a bunch of prefabbed points with all possible encodings. */ + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NVALID; i++) { + ec_pubkey_parse_pointtest(valid[i], 1, 1); + } + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NXVALID; i++) { + ec_pubkey_parse_pointtest(onlyxvalid[i], 1, 0); + } + for (i = 0; i < SECP256K1_EC_PARSE_TEST_NINVALID; i++) { + ec_pubkey_parse_pointtest(invalid[i], 0, 0); + } +} + +void run_eckey_edge_case_test(void) { + const unsigned char orderc[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 + }; + const unsigned char zeros[sizeof(secp256k1_pubkey)] = {0x00}; + unsigned char ctmp[33]; + unsigned char ctmp2[33]; + secp256k1_pubkey pubkey; + secp256k1_pubkey pubkey2; + secp256k1_pubkey pubkey_one; + secp256k1_pubkey pubkey_negone; + const secp256k1_pubkey *pubkeys[3]; + size_t len; + int32_t ecount; + /* Group order is too large, reject. */ + CHECK(secp256k1_ec_seckey_verify(ctx, orderc) == 0); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, orderc) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* Maximum value is too large, reject. */ + memset(ctmp, 255, 32); + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* Zero is too small, reject. */ + memset(ctmp, 0, 32); + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* One must be accepted. */ + ctmp[31] = 0x01; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + pubkey_one = pubkey; + /* Group order + 1 is too large, reject. */ + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x42; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 0); + memset(&pubkey, 1, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 0); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* -1 must be accepted. */ + ctmp[31] = 0x40; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + memset(&pubkey, 0, sizeof(pubkey)); + VG_UNDEF(&pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, ctmp) == 1); + VG_CHECK(&pubkey, sizeof(pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + pubkey_negone = pubkey; + /* Tweak of zero leaves the value changed. */ + memset(ctmp2, 0, 32); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, ctmp2) == 1); + CHECK(memcmp(orderc, ctmp, 31) == 0 && ctmp[31] == 0x40); + memcpy(&pubkey2, &pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Multiply tweak of zero zeroizes the output. */ + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, ctmp2) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, ctmp2) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Overflowing key tweak zeroizes. */ + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, orderc) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, orderc) == 0); + CHECK(memcmp(zeros, ctmp, 32) == 0); + memcpy(ctmp, orderc, 32); + ctmp[31] = 0x40; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, orderc) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, orderc) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Private key tweaks results in a key of zero. */ + ctmp2[31] = 1; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 0); + CHECK(memcmp(zeros, ctmp2, 32) == 0); + ctmp2[31] = 1; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + /* Tweak computation wraps and results in a key of 1. */ + ctmp2[31] = 2; + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp2, ctmp) == 1); + CHECK(memcmp(ctmp2, zeros, 31) == 0 && ctmp2[31] == 1); + ctmp2[31] = 2; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + ctmp2[31] = 1; + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Tweak mul * 2 = 1+1. */ + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 1); + ctmp2[31] = 2; + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); + /* Test argument errors. */ + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + CHECK(ecount == 0); + /* Zeroize pubkey on parse error. */ + memset(&pubkey, 0, 32); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(memcmp(&pubkey, zeros, sizeof(pubkey)) == 0); + memcpy(&pubkey, &pubkey2, sizeof(pubkey)); + memset(&pubkey2, 0, 32); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey2, ctmp2) == 0); + CHECK(ecount == 2); + CHECK(memcmp(&pubkey2, zeros, sizeof(pubkey2)) == 0); + /* Plain argument errors. */ + ecount = 0; + CHECK(secp256k1_ec_seckey_verify(ctx, ctmp) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_ec_seckey_verify(ctx, NULL) == 0); + CHECK(ecount == 1); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 4; + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 4; + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_privkey_tweak_add(ctx, ctmp, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + memset(ctmp2, 0, 32); + ctmp2[31] = 1; + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, NULL, ctmp2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_privkey_tweak_mul(ctx, ctmp, NULL) == 0); + CHECK(ecount == 2); + ecount = 0; + CHECK(secp256k1_ec_pubkey_create(ctx, NULL, ctmp) == 0); + CHECK(ecount == 1); + memset(&pubkey, 1, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 2); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + /* secp256k1_ec_pubkey_combine tests. */ + ecount = 0; + pubkeys[0] = &pubkey_one; + VG_UNDEF(&pubkeys[0], sizeof(secp256k1_pubkey *)); + VG_UNDEF(&pubkeys[1], sizeof(secp256k1_pubkey *)); + VG_UNDEF(&pubkeys[2], sizeof(secp256k1_pubkey *)); + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 0) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ec_pubkey_combine(ctx, NULL, pubkeys, 1) == 0); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 2); + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, NULL, 1) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 3); + pubkeys[0] = &pubkey_negone; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 1) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + len = 33; + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_negone, SECP256K1_EC_COMPRESSED) == 1); + CHECK(memcmp(ctmp, ctmp2, 33) == 0); + /* Result is infinity. */ + pubkeys[0] = &pubkey_one; + pubkeys[1] = &pubkey_negone; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 0); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) == 0); + CHECK(ecount == 3); + /* Passes through infinity but comes out one. */ + pubkeys[2] = &pubkey_one; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 3) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + len = 33; + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp, &len, &pubkey, SECP256K1_EC_COMPRESSED) == 1); + CHECK(secp256k1_ec_pubkey_serialize(ctx, ctmp2, &len, &pubkey_one, SECP256K1_EC_COMPRESSED) == 1); + CHECK(memcmp(ctmp, ctmp2, 33) == 0); + /* Adds to two. */ + pubkeys[1] = &pubkey_one; + memset(&pubkey, 255, sizeof(secp256k1_pubkey)); + VG_UNDEF(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(secp256k1_ec_pubkey_combine(ctx, &pubkey, pubkeys, 2) == 1); + VG_CHECK(&pubkey, sizeof(secp256k1_pubkey)); + CHECK(memcmp(&pubkey, zeros, sizeof(secp256k1_pubkey)) > 0); + CHECK(ecount == 3); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); +} + +void random_sign(secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *key, const secp256k1_scalar *msg, int *recid) { + secp256k1_scalar nonce; do { random_scalar_order_test(&nonce); - } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sig, key, msg, &nonce, recid)); + } while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sigr, sigs, key, msg, &nonce, recid)); } void test_ecdsa_sign_verify(void) { - secp256k1_gej_t pubj; - secp256k1_ge_t pub; - secp256k1_scalar_t one; - secp256k1_scalar_t msg, key; - secp256k1_ecdsa_sig_t sig; + secp256k1_gej pubj; + secp256k1_ge pub; + secp256k1_scalar one; + secp256k1_scalar msg, key; + secp256k1_scalar sigr, sigs; int recid; int getrec; random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key); secp256k1_ge_set_gej(&pub, &pubj); - getrec = secp256k1_rand32()&1; - random_sign(&sig, &key, &msg, getrec?&recid:NULL); + getrec = secp256k1_rand_bits(1); + random_sign(&sigr, &sigs, &key, &msg, getrec?&recid:NULL); if (getrec) { CHECK(recid >= 0 && recid < 4); } - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &pub, &msg)); } void run_ecdsa_sign_verify(void) { @@ -1357,22 +3385,23 @@ void run_ecdsa_sign_verify(void) { } /** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */ -static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int precomputed_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { (void)msg32; (void)key32; + (void)algo16; memcpy(nonce32, data, 32); return (counter == 0); } -static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int nonce_function_test_fail(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { /* Dummy nonce generator that has a fatal error on the first counter value. */ if (counter == 0) { return 0; } - return nonce_function_rfc6979(nonce32, msg32, key32, counter - 1, data); + return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 1); } -static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, unsigned int counter, const void *data) { +static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) { /* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */ if (counter < 3) { memset(nonce32, counter==0 ? 0 : 255, 32); @@ -1394,17 +3423,17 @@ static int nonce_function_test_retry(unsigned char *nonce32, const unsigned char } return 1; } - /* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */ + /* Retry rate of 6979 is negligible esp. as we only call this in deterministic tests. */ /* If someone does fine a case where it retries for secp256k1, we'd like to know. */ if (counter > 5) { return 0; } - return nonce_function_rfc6979(nonce32, msg32, key32, counter - 5, data); + return nonce_function_rfc6979(nonce32, msg32, key32, algo16, data, counter - 5); } -int is_empty_compact_signature(const unsigned char *sig64) { - static const unsigned char res[64] = {0}; - return memcmp(sig64, res, 64) == 0; +int is_empty_signature(const secp256k1_ecdsa_signature *sig) { + static const unsigned char res[sizeof(secp256k1_ecdsa_signature)] = {0}; + return memcmp(sig, res, sizeof(secp256k1_ecdsa_signature)) == 0; } void test_ecdsa_end_to_end(void) { @@ -1412,26 +3441,20 @@ void test_ecdsa_end_to_end(void) { unsigned char privkey[32]; unsigned char message[32]; unsigned char privkey2[32]; - unsigned char csignature[64]; - unsigned char signature[72]; - unsigned char signature2[72]; - unsigned char signature3[72]; - unsigned char signature4[72]; - unsigned char pubkey[65]; - unsigned char recpubkey[65]; + secp256k1_ecdsa_signature signature[6]; + secp256k1_scalar r, s; + unsigned char sig[74]; + size_t siglen = 74; + unsigned char pubkeyc[65]; + size_t pubkeyclen = 65; + secp256k1_pubkey pubkey; + secp256k1_pubkey pubkey_tmp; unsigned char seckey[300]; - int signaturelen = 72; - int signaturelen2 = 72; - int signaturelen3 = 72; - int signaturelen4 = 72; - int recid = 0; - int recpubkeylen = 0; - int pubkeylen = 65; - int seckeylen = 300; + size_t seckeylen = 300; /* Generate a random key and message. */ { - secp256k1_scalar_t msg, key; + secp256k1_scalar msg, key; random_scalar_order_test(&msg); random_scalar_order_test(&key); secp256k1_scalar_get_b32(privkey, &key); @@ -1440,117 +3463,127 @@ void test_ecdsa_end_to_end(void) { /* Construct and verify corresponding public key. */ CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1); - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1); - if (secp256k1_rand32() & 1) { - CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen)); - } - CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen)); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1); + + /* Verify exporting and importing public key. */ + CHECK(secp256k1_ec_pubkey_serialize(ctx, pubkeyc, &pubkeyclen, &pubkey, secp256k1_rand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED)); + memset(&pubkey, 0, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1); + + /* Verify negation changes the key and changes it back */ + memcpy(&pubkey_tmp, &pubkey, sizeof(pubkey)); + CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1); + CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) != 0); + CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1); + CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) == 0); /* Verify private key import and export. */ - CHECK(secp256k1_ec_privkey_export(ctx, privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1); - CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1); + CHECK(ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1)); + CHECK(ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1); CHECK(memcmp(privkey, privkey2, 32) == 0); /* Optionally tweak the keys using addition. */ - if (secp256k1_rand32() % 3 == 0) { + if (secp256k1_rand_int(3) == 0) { int ret1; int ret2; unsigned char rnd[32]; - unsigned char pubkey2[65]; - int pubkeylen2 = 65; + secp256k1_pubkey pubkey2; secp256k1_rand256_test(rnd); ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_add(ctx, pubkey, pubkeylen, rnd); + ret2 = secp256k1_ec_pubkey_tweak_add(ctx, &pubkey, rnd); CHECK(ret1 == ret2); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); - CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Optionally tweak the keys using multiplication. */ - if (secp256k1_rand32() % 3 == 0) { + if (secp256k1_rand_int(3) == 0) { int ret1; int ret2; unsigned char rnd[32]; - unsigned char pubkey2[65]; - int pubkeylen2 = 65; + secp256k1_pubkey pubkey2; secp256k1_rand256_test(rnd); ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd); - ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, pubkey, pubkeylen, rnd); + ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, &pubkey, rnd); CHECK(ret1 == ret2); if (ret1 == 0) { return; } - CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1); - CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey2, privkey) == 1); + CHECK(memcmp(&pubkey, &pubkey2, sizeof(pubkey)) == 0); } /* Sign. */ - CHECK(secp256k1_ecdsa_sign(ctx, message, signature, &signaturelen, privkey, NULL, NULL) == 1); - CHECK(signaturelen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, message, signature2, &signaturelen2, privkey, NULL, extra) == 1); - CHECK(signaturelen2 > 0); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[0], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[4], message, privkey, NULL, NULL) == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[1], message, privkey, NULL, extra) == 1); extra[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, message, signature3, &signaturelen3, privkey, NULL, extra) == 1); - CHECK(signaturelen3 > 0); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[2], message, privkey, NULL, extra) == 1); extra[31] = 0; extra[0] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, message, signature4, &signaturelen4, privkey, NULL, extra) == 1); - CHECK(signaturelen3 > 0); - CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0)); - CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0)); - CHECK((signaturelen3 != signaturelen2) || (memcmp(signature3, signature2, signaturelen3) != 0)); - CHECK((signaturelen4 != signaturelen3) || (memcmp(signature4, signature3, signaturelen4) != 0)); - CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0)); - CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0)); + CHECK(secp256k1_ecdsa_sign(ctx, &signature[3], message, privkey, NULL, extra) == 1); + CHECK(memcmp(&signature[0], &signature[4], sizeof(signature[0])) == 0); + CHECK(memcmp(&signature[0], &signature[1], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[0], &signature[2], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[0], &signature[3], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[1], &signature[2], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[1], &signature[3], sizeof(signature[0])) != 0); + CHECK(memcmp(&signature[2], &signature[3], sizeof(signature[0])) != 0); /* Verify. */ - CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature2, signaturelen2, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature3, signaturelen3, pubkey, pubkeylen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature4, signaturelen4, pubkey, pubkeylen) == 1); - /* Destroy signature and verify again. */ - signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) != 1); - - /* Compact sign. */ - CHECK(secp256k1_ecdsa_sign_compact(ctx, message, csignature, privkey, NULL, NULL, &recid) == 1); - CHECK(!is_empty_compact_signature(csignature)); - /* Recover. */ - CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1); - CHECK(recpubkeylen == pubkeylen); - CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0); - /* Destroy signature and verify again. */ - csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255); - CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 || - memcmp(pubkey, recpubkey, pubkeylen) != 0); - CHECK(recpubkeylen == pubkeylen); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[1], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[2], message, &pubkey) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[3], message, &pubkey) == 1); + /* Test lower-S form, malleate, verify and fail, test again, malleate again */ + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[0])); + secp256k1_ecdsa_signature_load(ctx, &r, &s, &signature[0]); + secp256k1_scalar_negate(&s, &s); + secp256k1_ecdsa_signature_save(&signature[5], &r, &s); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 0); + CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, &signature[5], &signature[5])); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); + secp256k1_scalar_negate(&s, &s); + secp256k1_ecdsa_signature_save(&signature[5], &r, &s); + CHECK(!secp256k1_ecdsa_signature_normalize(ctx, NULL, &signature[5])); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[5], message, &pubkey) == 1); + CHECK(memcmp(&signature[5], &signature[0], 64) == 0); + /* Serialize/parse DER and verify again */ + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); + memset(&signature[0], 0, sizeof(signature[0])); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 1); + /* Serialize/destroy/parse DER and verify again. */ + siglen = 74; + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature[0]) == 1); + sig[secp256k1_rand_int(siglen)] += 1 + secp256k1_rand_int(255); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &signature[0], sig, siglen) == 0 || + secp256k1_ecdsa_verify(ctx, &signature[0], message, &pubkey) == 0); } void test_random_pubkeys(void) { - secp256k1_ge_t elem; - secp256k1_ge_t elem2; + secp256k1_ge elem; + secp256k1_ge elem2; unsigned char in[65]; /* Generate some randomly sized pubkeys. */ - uint32_t r = secp256k1_rand32(); - int len = (r & 3) == 0 ? 65 : 33; - r>>=2; - if ((r & 3) == 0) { - len = (r & 252) >> 3; + size_t len = secp256k1_rand_bits(2) == 0 ? 65 : 33; + if (secp256k1_rand_bits(2) == 0) { + len = secp256k1_rand_bits(6); } - r>>=8; if (len == 65) { - in[0] = (r & 2) ? 4 : (r & 1? 6 : 7); + in[0] = secp256k1_rand_bits(1) ? 4 : (secp256k1_rand_bits(1) ? 6 : 7); } else { - in[0] = (r & 1) ? 2 : 3; + in[0] = secp256k1_rand_bits(1) ? 2 : 3; } - r>>=2; - if ((r & 7) == 0) { - in[0] = (r & 2040) >> 3; + if (secp256k1_rand_bits(3) == 0) { + in[0] = secp256k1_rand_bits(8); } - r>>=11; if (len > 1) { secp256k1_rand256(&in[1]); } @@ -1561,7 +3594,7 @@ void test_random_pubkeys(void) { unsigned char out[65]; unsigned char firstb; int res; - int size = len; + size_t size = len; firstb = in[0]; /* If the pubkey can be parsed, it should round-trip... */ CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33)); @@ -1577,7 +3610,7 @@ void test_random_pubkeys(void) { CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size)); ge_equals_ge(&elem,&elem2); /* Check that the X9.62 hybrid type is checked. */ - in[0] = (r & 1) ? 6 : 7; + in[0] = secp256k1_rand_bits(1) ? 6 : 7; res = secp256k1_eckey_pubkey_parse(&elem2, in, size); if (firstb == 2 || firstb == 3) { if (in[0] == firstb + 4) { @@ -1608,185 +3641,508 @@ void run_ecdsa_end_to_end(void) { } } -/* Tests several edge cases. */ -void test_ecdsa_edge_cases(void) { - const unsigned char msg32[32] = { - 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', - 'a', ' ', 'v', 'e', 'r', 'y', ' ', 's', - 'e', 'c', 'r', 'e', 't', ' ', 'm', 'e', - 's', 's', 'a', 'g', 'e', '.', '.', '.' +int test_ecdsa_der_parse(const unsigned char *sig, size_t siglen, int certainly_der, int certainly_not_der) { + static const unsigned char zeroes[32] = {0}; +#ifdef ENABLE_OPENSSL_TESTS + static const unsigned char max_scalar[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, + 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40 }; - const unsigned char sig64[64] = { - /* Generated by signing the above message with nonce 'This is the nonce we will use...' - * and secret key 0 (which is not valid), resulting in recid 0. */ - 0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8, - 0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96, - 0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63, - 0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32, - 0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E, - 0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD, - 0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86, - 0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57 - }; - unsigned char pubkey[65]; - int t; - int pubkeylen = 65; - /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */ - const unsigned char sigb64[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - unsigned char pubkeyb[33]; - int pubkeyblen = 33; - int recid; +#endif - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 0)); - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 1)); - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 2)); - CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 3)); + int ret = 0; - for (recid = 0; recid < 4; recid++) { - int i; - int recid2; - /* (4,4) encoded in DER. */ - unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04}; - unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01}; - unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00}; - unsigned char sigbderalt1[39] = { - 0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, - }; - unsigned char sigbderalt2[39] = { - 0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - unsigned char sigbderalt3[40] = { - 0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04, - }; - unsigned char sigbderalt4[40] = { - 0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - }; - /* (order + r,4) encoded in DER. */ - unsigned char sigbderlong[40] = { - 0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, - 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, - 0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04 - }; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid)); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1); - for (recid2 = 0; recid2 < 4; recid2++) { - unsigned char pubkey2b[33]; - int pubkey2blen = 33; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2)); - /* Verifying with (order + r,4) should always fail. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1); + secp256k1_ecdsa_signature sig_der; + unsigned char roundtrip_der[2048]; + unsigned char compact_der[64]; + size_t len_der = 2048; + int parsed_der = 0, valid_der = 0, roundtrips_der = 0; + + secp256k1_ecdsa_signature sig_der_lax; + unsigned char roundtrip_der_lax[2048]; + unsigned char compact_der_lax[64]; + size_t len_der_lax = 2048; + int parsed_der_lax = 0, valid_der_lax = 0, roundtrips_der_lax = 0; + +#ifdef ENABLE_OPENSSL_TESTS + ECDSA_SIG *sig_openssl; + const unsigned char *sigptr; + unsigned char roundtrip_openssl[2048]; + int len_openssl = 2048; + int parsed_openssl, valid_openssl = 0, roundtrips_openssl = 0; +#endif + + parsed_der = secp256k1_ecdsa_signature_parse_der(ctx, &sig_der, sig, siglen); + if (parsed_der) { + ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der, &sig_der)) << 0; + valid_der = (memcmp(compact_der, zeroes, 32) != 0) && (memcmp(compact_der + 32, zeroes, 32) != 0); + } + if (valid_der) { + ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der, &len_der, &sig_der)) << 1; + roundtrips_der = (len_der == siglen) && memcmp(roundtrip_der, sig, siglen) == 0; + } + + parsed_der_lax = ecdsa_signature_parse_der_lax(ctx, &sig_der_lax, sig, siglen); + if (parsed_der_lax) { + ret |= (!secp256k1_ecdsa_signature_serialize_compact(ctx, compact_der_lax, &sig_der_lax)) << 10; + valid_der_lax = (memcmp(compact_der_lax, zeroes, 32) != 0) && (memcmp(compact_der_lax + 32, zeroes, 32) != 0); + } + if (valid_der_lax) { + ret |= (!secp256k1_ecdsa_signature_serialize_der(ctx, roundtrip_der_lax, &len_der_lax, &sig_der_lax)) << 11; + roundtrips_der_lax = (len_der_lax == siglen) && memcmp(roundtrip_der_lax, sig, siglen) == 0; + } + + if (certainly_der) { + ret |= (!parsed_der) << 2; + } + if (certainly_not_der) { + ret |= (parsed_der) << 17; + } + if (valid_der) { + ret |= (!roundtrips_der) << 3; + } + + if (valid_der) { + ret |= (!roundtrips_der_lax) << 12; + ret |= (len_der != len_der_lax) << 13; + ret |= (memcmp(roundtrip_der_lax, roundtrip_der, len_der) != 0) << 14; + } + ret |= (roundtrips_der != roundtrips_der_lax) << 15; + if (parsed_der) { + ret |= (!parsed_der_lax) << 16; + } + +#ifdef ENABLE_OPENSSL_TESTS + sig_openssl = ECDSA_SIG_new(); + sigptr = sig; + parsed_openssl = (d2i_ECDSA_SIG(&sig_openssl, &sigptr, siglen) != NULL); + if (parsed_openssl) { + valid_openssl = !BN_is_negative(sig_openssl->r) && !BN_is_negative(sig_openssl->s) && BN_num_bits(sig_openssl->r) > 0 && BN_num_bits(sig_openssl->r) <= 256 && BN_num_bits(sig_openssl->s) > 0 && BN_num_bits(sig_openssl->s) <= 256; + if (valid_openssl) { + unsigned char tmp[32] = {0}; + BN_bn2bin(sig_openssl->r, tmp + 32 - BN_num_bytes(sig_openssl->r)); + valid_openssl = memcmp(tmp, max_scalar, 32) < 0; } - /* DER parsing tests. */ - /* Zero length r/s. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2); - /* Leading zeros. */ - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1); - sigbderalt3[4] = 1; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2); - sigbderalt4[7] = 1; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2); - /* Damage signature. */ - sigbder[7]++; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0); - sigbder[7]--; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2); - for(i = 0; i < 8; i++) { - int c; - unsigned char orig = sigbder[i]; - /*Try every single-byte change.*/ - for (c = 0; c < 256; c++) { - if (c == orig ) { - continue; - } - sigbder[i] = c; - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == - (i==4 || i==7) ? 0 : -2 ); - } - sigbder[i] = orig; + if (valid_openssl) { + unsigned char tmp[32] = {0}; + BN_bn2bin(sig_openssl->s, tmp + 32 - BN_num_bytes(sig_openssl->s)); + valid_openssl = memcmp(tmp, max_scalar, 32) < 0; } } + len_openssl = i2d_ECDSA_SIG(sig_openssl, NULL); + if (len_openssl <= 2048) { + unsigned char *ptr = roundtrip_openssl; + CHECK(i2d_ECDSA_SIG(sig_openssl, &ptr) == len_openssl); + roundtrips_openssl = valid_openssl && ((size_t)len_openssl == siglen) && (memcmp(roundtrip_openssl, sig, siglen) == 0); + } else { + len_openssl = 0; + } + ECDSA_SIG_free(sig_openssl); + + ret |= (parsed_der && !parsed_openssl) << 4; + ret |= (valid_der && !valid_openssl) << 5; + ret |= (roundtrips_openssl && !parsed_der) << 6; + ret |= (roundtrips_der != roundtrips_openssl) << 7; + if (roundtrips_openssl) { + ret |= (len_der != (size_t)len_openssl) << 8; + ret |= (memcmp(roundtrip_der, roundtrip_openssl, len_der) != 0) << 9; + } +#endif + return ret; +} + +static void assign_big_endian(unsigned char *ptr, size_t ptrlen, uint32_t val) { + size_t i; + for (i = 0; i < ptrlen; i++) { + int shift = ptrlen - 1 - i; + if (shift >= 4) { + ptr[i] = 0; + } else { + ptr[i] = (val >> shift) & 0xFF; + } + } +} + +static void damage_array(unsigned char *sig, size_t *len) { + int pos; + int action = secp256k1_rand_bits(3); + if (action < 1 && *len > 3) { + /* Delete a byte. */ + pos = secp256k1_rand_int(*len); + memmove(sig + pos, sig + pos + 1, *len - pos - 1); + (*len)--; + return; + } else if (action < 2 && *len < 2048) { + /* Insert a byte. */ + pos = secp256k1_rand_int(1 + *len); + memmove(sig + pos + 1, sig + pos, *len - pos); + sig[pos] = secp256k1_rand_bits(8); + (*len)++; + return; + } else if (action < 4) { + /* Modify a byte. */ + sig[secp256k1_rand_int(*len)] += 1 + secp256k1_rand_int(255); + return; + } else { /* action < 8 */ + /* Modify a bit. */ + sig[secp256k1_rand_int(*len)] ^= 1 << secp256k1_rand_bits(3); + return; + } +} + +static void random_ber_signature(unsigned char *sig, size_t *len, int* certainly_der, int* certainly_not_der) { + int der; + int nlow[2], nlen[2], nlenlen[2], nhbit[2], nhbyte[2], nzlen[2]; + size_t tlen, elen, glen; + int indet; + int n; + + *len = 0; + der = secp256k1_rand_bits(2) == 0; + *certainly_der = der; + *certainly_not_der = 0; + indet = der ? 0 : secp256k1_rand_int(10) == 0; + + for (n = 0; n < 2; n++) { + /* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */ + nlow[n] = der ? 1 : (secp256k1_rand_bits(3) != 0); + /* The length of the number in bytes (the first byte of which will always be nonzero) */ + nlen[n] = nlow[n] ? secp256k1_rand_int(33) : 32 + secp256k1_rand_int(200) * secp256k1_rand_int(8) / 8; + CHECK(nlen[n] <= 232); + /* The top bit of the number. */ + nhbit[n] = (nlow[n] == 0 && nlen[n] == 32) ? 1 : (nlen[n] == 0 ? 0 : secp256k1_rand_bits(1)); + /* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */ + nhbyte[n] = nlen[n] == 0 ? 0 : (nhbit[n] ? 128 + secp256k1_rand_bits(7) : 1 + secp256k1_rand_int(127)); + /* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */ + nzlen[n] = der ? ((nlen[n] == 0 || nhbit[n]) ? 1 : 0) : (nlow[n] ? secp256k1_rand_int(3) : secp256k1_rand_int(300 - nlen[n]) * secp256k1_rand_int(8) / 8); + if (nzlen[n] > ((nlen[n] == 0 || nhbit[n]) ? 1 : 0)) { + *certainly_not_der = 1; + } + CHECK(nlen[n] + nzlen[n] <= 300); + /* The length of the length descriptor for the number. 0 means short encoding, anything else is long encoding. */ + nlenlen[n] = nlen[n] + nzlen[n] < 128 ? 0 : (nlen[n] + nzlen[n] < 256 ? 1 : 2); + if (!der) { + /* nlenlen[n] max 127 bytes */ + int add = secp256k1_rand_int(127 - nlenlen[n]) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + nlenlen[n] += add; + if (add != 0) { + *certainly_not_der = 1; + } + } + CHECK(nlen[n] + nzlen[n] + nlenlen[n] <= 427); + } + + /* The total length of the data to go, so far */ + tlen = 2 + nlenlen[0] + nlen[0] + nzlen[0] + 2 + nlenlen[1] + nlen[1] + nzlen[1]; + CHECK(tlen <= 856); + + /* The length of the garbage inside the tuple. */ + elen = (der || indet) ? 0 : secp256k1_rand_int(980 - tlen) * secp256k1_rand_int(8) / 8; + if (elen != 0) { + *certainly_not_der = 1; + } + tlen += elen; + CHECK(tlen <= 980); + + /* The length of the garbage after the end of the tuple. */ + glen = der ? 0 : secp256k1_rand_int(990 - tlen) * secp256k1_rand_int(8) / 8; + if (glen != 0) { + *certainly_not_der = 1; + } + CHECK(tlen + glen <= 990); + + /* Write the tuple header. */ + sig[(*len)++] = 0x30; + if (indet) { + /* Indeterminate length */ + sig[(*len)++] = 0x80; + *certainly_not_der = 1; + } else { + int tlenlen = tlen < 128 ? 0 : (tlen < 256 ? 1 : 2); + if (!der) { + int add = secp256k1_rand_int(127 - tlenlen) * secp256k1_rand_int(16) * secp256k1_rand_int(16) / 256; + tlenlen += add; + if (add != 0) { + *certainly_not_der = 1; + } + } + if (tlenlen == 0) { + /* Short length notation */ + sig[(*len)++] = tlen; + } else { + /* Long length notation */ + sig[(*len)++] = 128 + tlenlen; + assign_big_endian(sig + *len, tlenlen, tlen); + *len += tlenlen; + } + tlen += tlenlen; + } + tlen += 2; + CHECK(tlen + glen <= 1119); + + for (n = 0; n < 2; n++) { + /* Write the integer header. */ + sig[(*len)++] = 0x02; + if (nlenlen[n] == 0) { + /* Short length notation */ + sig[(*len)++] = nlen[n] + nzlen[n]; + } else { + /* Long length notation. */ + sig[(*len)++] = 128 + nlenlen[n]; + assign_big_endian(sig + *len, nlenlen[n], nlen[n] + nzlen[n]); + *len += nlenlen[n]; + } + /* Write zero padding */ + while (nzlen[n] > 0) { + sig[(*len)++] = 0x00; + nzlen[n]--; + } + if (nlen[n] == 32 && !nlow[n]) { + /* Special extra 16 0xFF bytes in "high" 32-byte numbers */ + int i; + for (i = 0; i < 16; i++) { + sig[(*len)++] = 0xFF; + } + nlen[n] -= 16; + } + /* Write first byte of number */ + if (nlen[n] > 0) { + sig[(*len)++] = nhbyte[n]; + nlen[n]--; + } + /* Generate remaining random bytes of number */ + secp256k1_rand_bytes_test(sig + *len, nlen[n]); + *len += nlen[n]; + nlen[n] = 0; + } + + /* Generate random garbage inside tuple. */ + secp256k1_rand_bytes_test(sig + *len, elen); + *len += elen; + + /* Generate end-of-contents bytes. */ + if (indet) { + sig[(*len)++] = 0; + sig[(*len)++] = 0; + tlen += 2; + } + CHECK(tlen + glen <= 1121); + + /* Generate random garbage outside tuple. */ + secp256k1_rand_bytes_test(sig + *len, glen); + *len += glen; + tlen += glen; + CHECK(tlen <= 1121); + CHECK(tlen == *len); +} + +void run_ecdsa_der_parse(void) { + int i,j; + for (i = 0; i < 200 * count; i++) { + unsigned char buffer[2048]; + size_t buflen = 0; + int certainly_der = 0; + int certainly_not_der = 0; + random_ber_signature(buffer, &buflen, &certainly_der, &certainly_not_der); + CHECK(buflen <= 2048); + for (j = 0; j < 16; j++) { + int ret = 0; + if (j > 0) { + damage_array(buffer, &buflen); + /* We don't know anything anymore about the DERness of the result */ + certainly_der = 0; + certainly_not_der = 0; + } + ret = test_ecdsa_der_parse(buffer, buflen, certainly_der, certainly_not_der); + if (ret != 0) { + size_t k; + fprintf(stderr, "Failure %x on ", ret); + for (k = 0; k < buflen; k++) { + fprintf(stderr, "%02x ", buffer[k]); + } + fprintf(stderr, "\n"); + } + CHECK(ret == 0); + } + } +} + +/* Tests several edge cases. */ +void test_ecdsa_edge_cases(void) { + int t; + secp256k1_ecdsa_signature sig; /* Test the case where ECDSA recomputes a point that is infinity. */ { - secp256k1_gej_t keyj; - secp256k1_ge_t key; - secp256k1_scalar_t msg; - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_set_int(&sig.s, 1); - secp256k1_scalar_negate(&sig.s, &sig.s); - secp256k1_scalar_inverse(&sig.s, &sig.s); - secp256k1_scalar_set_int(&sig.r, 1); - secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sig.r); + secp256k1_gej keyj; + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_negate(&ss, &ss); + secp256k1_scalar_inverse(&ss, &ss); + secp256k1_scalar_set_int(&sr, 1); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sr); secp256k1_ge_set_gej(&key, &keyj); - msg = sig.s; - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &key, &msg) == 0); + msg = ss; + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); } - /* Test r/s equal to zero */ + /* Verify signature with r of zero fails. */ { - /* (1,1) encoded in DER. */ - unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01}; - unsigned char sigc64[64] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + const unsigned char pubkey_mods_zero[33] = { + 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, + 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, + 0x41 }; - unsigned char pubkeyc[65]; - int pubkeyclen = 65; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1); - sigcder[4] = 0; - sigc64[31] = 0; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); - sigcder[4] = 1; - sigcder[7] = 0; - sigc64[31] = 1; - sigc64[63] = 0; - CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0); - CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0); + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 0); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey_mods_zero, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); } - /*Signature where s would be zero.*/ + /* Verify signature with s of zero fails. */ { - const unsigned char nonce[32] = { + const unsigned char pubkey[33] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01 + }; + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 0); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 1); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } + + /* Verify signature with message 0 passes. */ + { + const unsigned char pubkey[33] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02 + }; + const unsigned char pubkey2[33] = { + 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, + 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, + 0x43 + }; + secp256k1_ge key; + secp256k1_ge key2; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 2); + secp256k1_scalar_set_int(&msg, 0); + secp256k1_scalar_set_int(&sr, 2); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_set_int(&ss, 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); + } + + /* Verify signature with message 1 passes. */ + { + const unsigned char pubkey[33] = { + 0x02, 0x14, 0x4e, 0x5a, 0x58, 0xef, 0x5b, 0x22, + 0x6f, 0xd2, 0xe2, 0x07, 0x6a, 0x77, 0xcf, 0x05, + 0xb4, 0x1d, 0xe7, 0x4a, 0x30, 0x98, 0x27, 0x8c, + 0x93, 0xe6, 0xe6, 0x3c, 0x0b, 0xc4, 0x73, 0x76, + 0x25 + }; + const unsigned char pubkey2[33] = { + 0x02, 0x8a, 0xd5, 0x37, 0xed, 0x73, 0xd9, 0x40, + 0x1d, 0xa0, 0x33, 0xd2, 0xdc, 0xf0, 0xaf, 0xae, + 0x34, 0xcf, 0x5f, 0x96, 0x4c, 0x73, 0x28, 0x0f, + 0x92, 0xc0, 0xf6, 0x9d, 0xd9, 0xb2, 0x09, 0x10, + 0x62 + }; + const unsigned char csr[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xeb + }; + secp256k1_ge key; + secp256k1_ge key2; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 1); + secp256k1_scalar_set_b32(&sr, csr, NULL); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_eckey_pubkey_parse(&key2, pubkey2, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 1); + secp256k1_scalar_set_int(&ss, 2); + secp256k1_scalar_inverse_var(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key2, &msg) == 0); + } + + /* Verify signature with message -1 passes. */ + { + const unsigned char pubkey[33] = { + 0x03, 0xaf, 0x97, 0xff, 0x7d, 0x3a, 0xf6, 0xa0, + 0x02, 0x94, 0xbd, 0x9f, 0x4b, 0x2e, 0xd7, 0x52, + 0x28, 0xdb, 0x49, 0x2a, 0x65, 0xcb, 0x1e, 0x27, + 0x57, 0x9c, 0xba, 0x74, 0x20, 0xd5, 0x1d, 0x20, + 0xf1 + }; + const unsigned char csr[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x45, 0x51, 0x23, 0x19, 0x50, 0xb7, 0x5f, 0xc4, + 0x40, 0x2d, 0xa1, 0x72, 0x2f, 0xc9, 0xba, 0xee + }; + secp256k1_ge key; + secp256k1_scalar msg; + secp256k1_scalar sr, ss; + secp256k1_scalar_set_int(&ss, 1); + secp256k1_scalar_set_int(&msg, 1); + secp256k1_scalar_negate(&msg, &msg); + secp256k1_scalar_set_b32(&sr, csr, NULL); + CHECK(secp256k1_eckey_pubkey_parse(&key, pubkey, 33)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + secp256k1_scalar_negate(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 1); + secp256k1_scalar_set_int(&ss, 3); + secp256k1_scalar_inverse_var(&ss, &ss); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sr, &ss, &key, &msg) == 0); + } + + /* Signature where s would be zero. */ + { + secp256k1_pubkey pubkey; + size_t siglen; + int32_t ecount; + unsigned char signature[72]; + static const unsigned char nonce[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1810,21 +4166,72 @@ void test_ecdsa_edge_cases(void) { 0xb8, 0x12, 0xe0, 0x0b, 0x81, 0x7a, 0x77, 0x62, 0x65, 0xdf, 0xdd, 0x31, 0xb9, 0x3e, 0x29, 0xa9, }; - unsigned char sig[72]; - int siglen = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0); - CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0); - CHECK(siglen == 0); + ecount = 0; + secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 0); msg[31] = 0xaa; + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce) == 1); + CHECK(ecount == 0); + CHECK(secp256k1_ecdsa_sign(ctx, NULL, msg, key, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, NULL, key, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, NULL, precomputed_nonce_function, nonce2) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, precomputed_nonce_function, nonce2) == 1); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, key) == 1); + CHECK(secp256k1_ecdsa_verify(ctx, NULL, msg, &pubkey) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, NULL, &pubkey) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, NULL) == 0); + CHECK(ecount == 6); + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 1); + CHECK(ecount == 6); + CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, NULL) == 0); + CHECK(ecount == 7); + /* That pubkeyload fails via an ARGCHECK is a little odd but makes sense because pubkeys are an opaque data type. */ + CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg, &pubkey) == 0); + CHECK(ecount == 8); siglen = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1); - CHECK(siglen > 0); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, NULL, &siglen, &sig) == 0); + CHECK(ecount == 9); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, NULL, &sig) == 0); + CHECK(ecount == 10); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, NULL) == 0); + CHECK(ecount == 11); + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 1); + CHECK(ecount == 11); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, NULL, signature, siglen) == 0); + CHECK(ecount == 12); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, NULL, siglen) == 0); + CHECK(ecount == 13); + CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, signature, siglen) == 1); + CHECK(ecount == 13); siglen = 10; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1); - CHECK(siglen == 0); + /* Too little room for a signature does not fail via ARGCHECK. */ + CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, signature, &siglen, &sig) == 0); + CHECK(ecount == 13); + ecount = 0; + CHECK(secp256k1_ecdsa_signature_normalize(ctx, NULL, NULL) == 0); + CHECK(ecount == 1); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, NULL, &sig) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, NULL) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_signature_serialize_compact(ctx, signature, &sig) == 1); + CHECK(ecount == 3); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, NULL, signature) == 0); + CHECK(ecount == 4); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, NULL) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 1); + CHECK(ecount == 5); + memset(signature, 255, 64); + CHECK(secp256k1_ecdsa_signature_parse_compact(ctx, &sig, signature) == 0); + CHECK(ecount == 5); + secp256k1_context_set_illegal_callback(ctx, NULL, NULL); } /* Nonce function corner cases. */ @@ -1833,65 +4240,43 @@ void test_ecdsa_edge_cases(void) { int i; unsigned char key[32]; unsigned char msg[32]; - unsigned char sig[72]; - unsigned char sig2[72]; - secp256k1_ecdsa_sig_t s[512]; - int siglen = 72; - int siglen2 = 72; - int recid2; + secp256k1_ecdsa_signature sig2; + secp256k1_scalar sr[512], ss; const unsigned char *extra; extra = t == 0 ? NULL : zero; memset(msg, 0, 32); msg[31] = 1; /* High key results in signature failure. */ memset(key, 0xFF, 32); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); - CHECK(siglen == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(is_empty_signature(&sig)); /* Zero key results in signature failure. */ memset(key, 0, 32); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0); - CHECK(siglen == 0); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, NULL, extra) == 0); + CHECK(is_empty_signature(&sig)); /* Nonce function failure results in signature failure. */ key[31] = 1; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0); - CHECK(siglen == 0); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_fail, extra, &recid) == 0); - CHECK(is_empty_compact_signature(sig)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_fail, extra) == 0); + CHECK(is_empty_signature(&sig)); /* The retry loop successfully makes its way to the first good value. */ - siglen = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1); - CHECK(siglen > 0); - CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_retry, extra, &recid) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1); - CHECK(!is_empty_compact_signature(sig2)); - CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); - /* The default nonce function is determinstic. */ - siglen = 72; - siglen2 = 72; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 1); - CHECK(siglen > 0); - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(siglen2 > 0); - CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, NULL, extra, &recid) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, NULL, extra, &recid2) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig, msg, key, nonce_function_test_retry, extra) == 1); + CHECK(!is_empty_signature(&sig)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, nonce_function_rfc6979, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); + /* The default nonce function is deterministic. */ + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + CHECK(memcmp(&sig, &sig2, sizeof(sig)) == 0); /* The default nonce function changes output with different messages. */ for(i = 0; i < 256; i++) { int j; - siglen2 = 72; msg[0] = i; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(!is_empty_compact_signature(sig)); - CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r)); + CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } } msg[0] = 0; @@ -1899,17 +4284,45 @@ void test_ecdsa_edge_cases(void) { /* The default nonce function changes output with different keys. */ for(i = 256; i < 512; i++) { int j; - siglen2 = 72; key[0] = i - 256; - CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1); - CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2)); + CHECK(secp256k1_ecdsa_sign(ctx, &sig2, msg, key, NULL, extra) == 1); + CHECK(!is_empty_signature(&sig2)); + secp256k1_ecdsa_signature_load(ctx, &sr[i], &ss, &sig2); for (j = 0; j < i; j++) { - CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r)); + CHECK(!secp256k1_scalar_eq(&sr[i], &sr[j])); } } key[0] = 0; } + { + /* Check that optional nonce arguments do not have equivalent effect. */ + const unsigned char zeros[32] = {0}; + unsigned char nonce[32]; + unsigned char nonce2[32]; + unsigned char nonce3[32]; + unsigned char nonce4[32]; + VG_UNDEF(nonce,32); + VG_UNDEF(nonce2,32); + VG_UNDEF(nonce3,32); + VG_UNDEF(nonce4,32); + CHECK(nonce_function_rfc6979(nonce, zeros, zeros, NULL, NULL, 0) == 1); + VG_CHECK(nonce,32); + CHECK(nonce_function_rfc6979(nonce2, zeros, zeros, zeros, NULL, 0) == 1); + VG_CHECK(nonce2,32); + CHECK(nonce_function_rfc6979(nonce3, zeros, zeros, NULL, (void *)zeros, 0) == 1); + VG_CHECK(nonce3,32); + CHECK(nonce_function_rfc6979(nonce4, zeros, zeros, zeros, (void *)zeros, 0) == 1); + VG_CHECK(nonce4,32); + CHECK(memcmp(nonce, nonce2, 32) != 0); + CHECK(memcmp(nonce, nonce3, 32) != 0); + CHECK(memcmp(nonce, nonce4, 32) != 0); + CHECK(memcmp(nonce2, nonce3, 32) != 0); + CHECK(memcmp(nonce2, nonce4, 32) != 0); + CHECK(memcmp(nonce3, nonce4, 32) != 0); + } + + /* Privkey export where pubkey is the point at infinity. */ { unsigned char privkey[300]; @@ -1919,9 +4332,10 @@ void test_ecdsa_edge_cases(void) { 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41, }; - int outlen = 300; - CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 0)); - CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 1)); + size_t outlen = 300; + CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 0)); + outlen = 300; + CHECK(!ec_privkey_export_der(ctx, privkey, &outlen, seckey, 1)); } } @@ -1930,46 +4344,48 @@ void run_ecdsa_edge_cases(void) { } #ifdef ENABLE_OPENSSL_TESTS -EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) { +EC_KEY *get_openssl_key(const unsigned char *key32) { unsigned char privkey[300]; - int privkeylen; + size_t privkeylen; const unsigned char* pbegin = privkey; - int compr = secp256k1_rand32() & 1; + int compr = secp256k1_rand_bits(1); EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); - CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr)); + CHECK(ec_privkey_export_der(ctx, privkey, &privkeylen, key32, compr)); CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen)); CHECK(EC_KEY_check_key(ec_key)); return ec_key; } void test_ecdsa_openssl(void) { - secp256k1_gej_t qj; - secp256k1_ge_t q; - secp256k1_ecdsa_sig_t sig; - secp256k1_scalar_t one; - secp256k1_scalar_t msg2; - secp256k1_scalar_t key, msg; + secp256k1_gej qj; + secp256k1_ge q; + secp256k1_scalar sigr, sigs; + secp256k1_scalar one; + secp256k1_scalar msg2; + secp256k1_scalar key, msg; EC_KEY *ec_key; unsigned int sigsize = 80; - int secp_sigsize = 80; + size_t secp_sigsize = 80; unsigned char message[32]; unsigned char signature[80]; + unsigned char key32[32]; secp256k1_rand256_test(message); secp256k1_scalar_set_b32(&msg, message, NULL); random_scalar_order_test(&key); + secp256k1_scalar_get_b32(key32, &key); secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key); secp256k1_ge_set_gej(&q, &qj); - ec_key = get_openssl_key(&key); - CHECK(ec_key); + ec_key = get_openssl_key(key32); + CHECK(ec_key != NULL); CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key)); - CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize)); - CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg)); + CHECK(secp256k1_ecdsa_sig_parse(&sigr, &sigs, signature, sigsize)); + CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg)); secp256k1_scalar_set_int(&one, 1); secp256k1_scalar_add(&msg2, &msg, &one); - CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg2)); + CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sigr, &sigs, &q, &msg2)); - random_sign(&sig, &key, &msg, NULL); - CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig)); + random_sign(&sigr, &sigs, &key, &msg, NULL); + CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sigr, &sigs)); CHECK(ECDSA_verify(0, message, sizeof(message), signature, secp_sigsize, ec_key) == 1); EC_KEY_free(ec_key); @@ -1983,6 +4399,14 @@ void run_ecdsa_openssl(void) { } #endif +#ifdef ENABLE_MODULE_ECDH +# include "modules/ecdh/tests_impl.h" +#endif + +#ifdef ENABLE_MODULE_RECOVERY +# include "modules/recovery/tests_impl.h" +#endif + int main(int argc, char **argv) { unsigned char seed16[16] = {0}; unsigned char run32[32] = {0}; @@ -2007,7 +4431,7 @@ int main(int argc, char **argv) { } } else { FILE *frand = fopen("/dev/urandom", "r"); - if (!frand || !fread(&seed16, sizeof(seed16), 1, frand)) { + if ((frand == NULL) || !fread(&seed16, sizeof(seed16), 1, frand)) { uint64_t t = time(NULL) * (uint64_t)1337; seed16[0] ^= t; seed16[1] ^= t >> 8; @@ -2028,12 +4452,14 @@ int main(int argc, char **argv) { /* initialize */ run_context_tests(); ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - - if (secp256k1_rand32() & 1) { + if (secp256k1_rand_bits(1)) { secp256k1_rand256(run32); - CHECK(secp256k1_context_randomize(ctx, secp256k1_rand32() & 1 ? run32 : NULL)); + CHECK(secp256k1_context_randomize(ctx, secp256k1_rand_bits(1) ? run32 : NULL)); } + run_rand_bits(); + run_rand_int(); + run_sha256_tests(); run_hmac_sha256_tests(); run_rfc6979_hmac_sha256_tests(); @@ -2057,6 +4483,7 @@ int main(int argc, char **argv) { /* group tests */ run_ge(); + run_group_decompress(); /* ecmult tests */ run_wnaf(); @@ -2064,9 +4491,28 @@ int main(int argc, char **argv) { run_ecmult_chain(); run_ecmult_constants(); run_ecmult_gen_blind(); + run_ecmult_const_tests(); + run_ec_combine(); + + /* endomorphism tests */ +#ifdef USE_ENDOMORPHISM + run_endomorphism_tests(); +#endif + + /* EC point parser test */ + run_ec_pubkey_parse_test(); + + /* EC key edge cases */ + run_eckey_edge_case_test(); + +#ifdef ENABLE_MODULE_ECDH + /* ecdh tests */ + run_ecdh_tests(); +#endif /* ecdsa tests */ run_random_pubkeys(); + run_ecdsa_der_parse(); run_ecdsa_sign_verify(); run_ecdsa_end_to_end(); run_ecdsa_edge_cases(); @@ -2074,10 +4520,17 @@ int main(int argc, char **argv) { run_ecdsa_openssl(); #endif +#ifdef ENABLE_MODULE_RECOVERY + /* ECDSA pubkey recovery tests */ + run_recovery_tests(); +#endif + secp256k1_rand256(run32); printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); /* shutdown */ secp256k1_context_destroy(ctx); + + printf("no problems found\n"); return 0; } diff --git a/src/secp256k1/src/tests_exhaustive.c b/src/secp256k1/src/tests_exhaustive.c new file mode 100644 index 000000000..b040bb073 --- /dev/null +++ b/src/secp256k1/src/tests_exhaustive.c @@ -0,0 +1,470 @@ +/*********************************************************************** + * Copyright (c) 2016 Andrew Poelstra * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#if defined HAVE_CONFIG_H +#include "libsecp256k1-config.h" +#endif + +#include +#include + +#include + +#undef USE_ECMULT_STATIC_PRECOMPUTATION + +#ifndef EXHAUSTIVE_TEST_ORDER +/* see group_impl.h for allowable values */ +#define EXHAUSTIVE_TEST_ORDER 13 +#define EXHAUSTIVE_TEST_LAMBDA 9 /* cube root of 1 mod 13 */ +#endif + +#include "include/secp256k1.h" +#include "group.h" +#include "secp256k1.c" +#include "testrand_impl.h" + +#ifdef ENABLE_MODULE_RECOVERY +#include "src/modules/recovery/main_impl.h" +#include "include/secp256k1_recovery.h" +#endif + +/** stolen from tests.c */ +void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) { + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + CHECK(secp256k1_fe_equal_var(&a->x, &b->x)); + CHECK(secp256k1_fe_equal_var(&a->y, &b->y)); +} + +void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) { + secp256k1_fe z2s; + secp256k1_fe u1, u2, s1, s2; + CHECK(a->infinity == b->infinity); + if (a->infinity) { + return; + } + /* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */ + secp256k1_fe_sqr(&z2s, &b->z); + secp256k1_fe_mul(&u1, &a->x, &z2s); + u2 = b->x; secp256k1_fe_normalize_weak(&u2); + secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z); + s2 = b->y; secp256k1_fe_normalize_weak(&s2); + CHECK(secp256k1_fe_equal_var(&u1, &u2)); + CHECK(secp256k1_fe_equal_var(&s1, &s2)); +} + +void random_fe(secp256k1_fe *x) { + unsigned char bin[32]; + do { + secp256k1_rand256(bin); + if (secp256k1_fe_set_b32(x, bin)) { + return; + } + } while(1); +} +/** END stolen from tests.c */ + +int secp256k1_nonce_function_smallint(unsigned char *nonce32, const unsigned char *msg32, + const unsigned char *key32, const unsigned char *algo16, + void *data, unsigned int attempt) { + secp256k1_scalar s; + int *idata = data; + (void)msg32; + (void)key32; + (void)algo16; + /* Some nonces cannot be used because they'd cause s and/or r to be zero. + * The signing function has retry logic here that just re-calls the nonce + * function with an increased `attempt`. So if attempt > 0 this means we + * need to change the nonce to avoid an infinite loop. */ + if (attempt > 0) { + *idata = (*idata + 1) % EXHAUSTIVE_TEST_ORDER; + } + secp256k1_scalar_set_int(&s, *idata); + secp256k1_scalar_get_b32(nonce32, &s); + return 1; +} + +#ifdef USE_ENDOMORPHISM +void test_exhaustive_endomorphism(const secp256k1_ge *group, int order) { + int i; + for (i = 0; i < order; i++) { + secp256k1_ge res; + secp256k1_ge_mul_lambda(&res, &group[i]); + ge_equals_ge(&group[i * EXHAUSTIVE_TEST_LAMBDA % EXHAUSTIVE_TEST_ORDER], &res); + } +} +#endif + +void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j; + + /* Sanity-check (and check infinity functions) */ + CHECK(secp256k1_ge_is_infinity(&group[0])); + CHECK(secp256k1_gej_is_infinity(&groupj[0])); + for (i = 1; i < order; i++) { + CHECK(!secp256k1_ge_is_infinity(&group[i])); + CHECK(!secp256k1_gej_is_infinity(&groupj[i])); + } + + /* Check all addition formulae */ + for (j = 0; j < order; j++) { + secp256k1_fe fe_inv; + secp256k1_fe_inv(&fe_inv, &groupj[j].z); + for (i = 0; i < order; i++) { + secp256k1_ge zless_gej; + secp256k1_gej tmp; + /* add_var */ + secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_ge */ + if (j > 0) { + secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + /* add_ge_var */ + secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL); + ge_equals_gej(&group[(i + j) % order], &tmp); + /* add_zinv_var */ + zless_gej.infinity = groupj[j].infinity; + zless_gej.x = groupj[j].x; + zless_gej.y = groupj[j].y; + secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv); + ge_equals_gej(&group[(i + j) % order], &tmp); + } + } + + /* Check doubling */ + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + if (i > 0) { + secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + secp256k1_gej_double_var(&tmp, &groupj[i], NULL); + ge_equals_gej(&group[(2 * i) % order], &tmp); + } + + /* Check negation */ + for (i = 1; i < order; i++) { + secp256k1_ge tmp; + secp256k1_gej tmpj; + secp256k1_ge_neg(&tmp, &group[i]); + ge_equals_ge(&group[order - i], &tmp); + secp256k1_gej_neg(&tmpj, &groupj[i]); + ge_equals_gej(&group[order - i], &tmpj); + } +} + +void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) { + int i, j, r_log; + for (r_log = 1; r_log < order; r_log++) { + for (j = 0; j < order; j++) { + for (i = 0; i < order; i++) { + secp256k1_gej tmp; + secp256k1_scalar na, ng; + secp256k1_scalar_set_int(&na, i); + secp256k1_scalar_set_int(&ng, j); + + secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng); + ge_equals_gej(&group[(i * r_log + j) % order], &tmp); + + if (i > 0) { + secp256k1_ecmult_const(&tmp, &group[i], &ng); + ge_equals_gej(&group[(i * j) % order], &tmp); + } + } + } + } +} + +void r_from_k(secp256k1_scalar *r, const secp256k1_ge *group, int k) { + secp256k1_fe x; + unsigned char x_bin[32]; + k %= EXHAUSTIVE_TEST_ORDER; + x = group[k].x; + secp256k1_fe_normalize(&x); + secp256k1_fe_get_b32(x_bin, &x); + secp256k1_scalar_set_b32(r, x_bin, NULL); +} + +void test_exhaustive_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int s, r, msg, key; + for (s = 1; s < order; s++) { + for (r = 1; r < order; r++) { + for (msg = 1; msg < order; msg++) { + for (key = 1; key < order; key++) { + secp256k1_ge nonconst_ge; + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pk; + secp256k1_scalar sk_s, msg_s, r_s, s_s; + secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; + int k, should_verify; + unsigned char msg32[32]; + + secp256k1_scalar_set_int(&s_s, s); + secp256k1_scalar_set_int(&r_s, r); + secp256k1_scalar_set_int(&msg_s, msg); + secp256k1_scalar_set_int(&sk_s, key); + + /* Verify by hand */ + /* Run through every k value that gives us this r and check that *one* works. + * Note there could be none, there could be multiple, ECDSA is weird. */ + should_verify = 0; + for (k = 0; k < order; k++) { + secp256k1_scalar check_x_s; + r_from_k(&check_x_s, group, k); + if (r_s == check_x_s) { + secp256k1_scalar_set_int(&s_times_k_s, k); + secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); + secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); + secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); + should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); + } + } + /* nb we have a "high s" rule */ + should_verify &= !secp256k1_scalar_is_high(&s_s); + + /* Verify by calling verify */ + secp256k1_ecdsa_signature_save(&sig, &r_s, &s_s); + memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); + secp256k1_pubkey_save(&pk, &nonconst_ge); + secp256k1_scalar_get_b32(msg32, &msg_s); + CHECK(should_verify == + secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); + } + } + } + } +} + +void test_exhaustive_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int i, j, k; + + /* Loop */ + for (i = 1; i < order; i++) { /* message */ + for (j = 1; j < order; j++) { /* key */ + for (k = 1; k < order; k++) { /* nonce */ + const int starting_k = k; + secp256k1_ecdsa_signature sig; + secp256k1_scalar sk, msg, r, s, expected_r; + unsigned char sk32[32], msg32[32]; + secp256k1_scalar_set_int(&msg, i); + secp256k1_scalar_set_int(&sk, j); + secp256k1_scalar_get_b32(sk32, &sk); + secp256k1_scalar_get_b32(msg32, &msg); + + secp256k1_ecdsa_sign(ctx, &sig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + + secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); + /* Note that we compute expected_r *after* signing -- this is important + * because our nonce-computing function function might change k during + * signing. */ + r_from_k(&expected_r, group, k); + CHECK(r == expected_r); + CHECK((k * s) % order == (i + r * j) % order || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + + /* Overflow means we've tried every possible nonce */ + if (k < starting_k) { + break; + } + } + } + } + + /* We would like to verify zero-knowledge here by counting how often every + * possible (s, r) tuple appears, but because the group order is larger + * than the field order, when coercing the x-values to scalar values, some + * appear more often than others, so we are actually not zero-knowledge. + * (This effect also appears in the real code, but the difference is on the + * order of 1/2^128th the field order, so the deviation is not useful to a + * computationally bounded attacker.) + */ +} + +#ifdef ENABLE_MODULE_RECOVERY +void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + int i, j, k; + + /* Loop */ + for (i = 1; i < order; i++) { /* message */ + for (j = 1; j < order; j++) { /* key */ + for (k = 1; k < order; k++) { /* nonce */ + const int starting_k = k; + secp256k1_fe r_dot_y_normalized; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + secp256k1_scalar sk, msg, r, s, expected_r; + unsigned char sk32[32], msg32[32]; + int expected_recid; + int recid; + secp256k1_scalar_set_int(&msg, i); + secp256k1_scalar_set_int(&sk, j); + secp256k1_scalar_get_b32(sk32, &sk); + secp256k1_scalar_get_b32(msg32, &msg); + + secp256k1_ecdsa_sign_recoverable(ctx, &rsig, msg32, sk32, secp256k1_nonce_function_smallint, &k); + + /* Check directly */ + secp256k1_ecdsa_recoverable_signature_load(ctx, &r, &s, &recid, &rsig); + r_from_k(&expected_r, group, k); + CHECK(r == expected_r); + CHECK((k * s) % order == (i + r * j) % order || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + /* In computing the recid, there is an overflow condition that is disabled in + * scalar_low_impl.h `secp256k1_scalar_set_b32` because almost every r.y value + * will exceed the group order, and our signing code always holds out for r + * values that don't overflow, so with a proper overflow check the tests would + * loop indefinitely. */ + r_dot_y_normalized = group[k].y; + secp256k1_fe_normalize(&r_dot_y_normalized); + /* Also the recovery id is flipped depending if we hit the low-s branch */ + if ((k * s) % order == (i + r * j) % order) { + expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 1 : 0; + } else { + expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 0 : 1; + } + CHECK(recid == expected_recid); + + /* Convert to a standard sig then check */ + secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); + secp256k1_ecdsa_signature_load(ctx, &r, &s, &sig); + /* Note that we compute expected_r *after* signing -- this is important + * because our nonce-computing function function might change k during + * signing. */ + r_from_k(&expected_r, group, k); + CHECK(r == expected_r); + CHECK((k * s) % order == (i + r * j) % order || + (k * (EXHAUSTIVE_TEST_ORDER - s)) % order == (i + r * j) % order); + + /* Overflow means we've tried every possible nonce */ + if (k < starting_k) { + break; + } + } + } + } +} + +void test_exhaustive_recovery_verify(const secp256k1_context *ctx, const secp256k1_ge *group, int order) { + /* This is essentially a copy of test_exhaustive_verify, with recovery added */ + int s, r, msg, key; + for (s = 1; s < order; s++) { + for (r = 1; r < order; r++) { + for (msg = 1; msg < order; msg++) { + for (key = 1; key < order; key++) { + secp256k1_ge nonconst_ge; + secp256k1_ecdsa_recoverable_signature rsig; + secp256k1_ecdsa_signature sig; + secp256k1_pubkey pk; + secp256k1_scalar sk_s, msg_s, r_s, s_s; + secp256k1_scalar s_times_k_s, msg_plus_r_times_sk_s; + int recid = 0; + int k, should_verify; + unsigned char msg32[32]; + + secp256k1_scalar_set_int(&s_s, s); + secp256k1_scalar_set_int(&r_s, r); + secp256k1_scalar_set_int(&msg_s, msg); + secp256k1_scalar_set_int(&sk_s, key); + secp256k1_scalar_get_b32(msg32, &msg_s); + + /* Verify by hand */ + /* Run through every k value that gives us this r and check that *one* works. + * Note there could be none, there could be multiple, ECDSA is weird. */ + should_verify = 0; + for (k = 0; k < order; k++) { + secp256k1_scalar check_x_s; + r_from_k(&check_x_s, group, k); + if (r_s == check_x_s) { + secp256k1_scalar_set_int(&s_times_k_s, k); + secp256k1_scalar_mul(&s_times_k_s, &s_times_k_s, &s_s); + secp256k1_scalar_mul(&msg_plus_r_times_sk_s, &r_s, &sk_s); + secp256k1_scalar_add(&msg_plus_r_times_sk_s, &msg_plus_r_times_sk_s, &msg_s); + should_verify |= secp256k1_scalar_eq(&s_times_k_s, &msg_plus_r_times_sk_s); + } + } + /* nb we have a "high s" rule */ + should_verify &= !secp256k1_scalar_is_high(&s_s); + + /* We would like to try recovering the pubkey and checking that it matches, + * but pubkey recovery is impossible in the exhaustive tests (the reason + * being that there are 12 nonzero r values, 12 nonzero points, and no + * overlap between the sets, so there are no valid signatures). */ + + /* Verify by converting to a standard signature and calling verify */ + secp256k1_ecdsa_recoverable_signature_save(&rsig, &r_s, &s_s, recid); + secp256k1_ecdsa_recoverable_signature_convert(ctx, &sig, &rsig); + memcpy(&nonconst_ge, &group[sk_s], sizeof(nonconst_ge)); + secp256k1_pubkey_save(&pk, &nonconst_ge); + CHECK(should_verify == + secp256k1_ecdsa_verify(ctx, &sig, msg32, &pk)); + } + } + } + } +} +#endif + +int main(void) { + int i; + secp256k1_gej groupj[EXHAUSTIVE_TEST_ORDER]; + secp256k1_ge group[EXHAUSTIVE_TEST_ORDER]; + + /* Build context */ + secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + + /* TODO set z = 1, then do num_tests runs with random z values */ + + /* Generate the entire group */ + secp256k1_gej_set_infinity(&groupj[0]); + secp256k1_ge_set_gej(&group[0], &groupj[0]); + for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) { + /* Set a different random z-value for each Jacobian point */ + secp256k1_fe z; + random_fe(&z); + + secp256k1_gej_add_ge(&groupj[i], &groupj[i - 1], &secp256k1_ge_const_g); + secp256k1_ge_set_gej(&group[i], &groupj[i]); + secp256k1_gej_rescale(&groupj[i], &z); + + /* Verify against ecmult_gen */ + { + secp256k1_scalar scalar_i; + secp256k1_gej generatedj; + secp256k1_ge generated; + + secp256k1_scalar_set_int(&scalar_i, i); + secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &generatedj, &scalar_i); + secp256k1_ge_set_gej(&generated, &generatedj); + + CHECK(group[i].infinity == 0); + CHECK(generated.infinity == 0); + CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x)); + CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y)); + } + } + + /* Run the tests */ +#ifdef USE_ENDOMORPHISM + test_exhaustive_endomorphism(group, EXHAUSTIVE_TEST_ORDER); +#endif + test_exhaustive_addition(group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_ecmult(ctx, group, groupj, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); + +#ifdef ENABLE_MODULE_RECOVERY + test_exhaustive_recovery_sign(ctx, group, EXHAUSTIVE_TEST_ORDER); + test_exhaustive_recovery_verify(ctx, group, EXHAUSTIVE_TEST_ORDER); +#endif + + secp256k1_context_destroy(ctx); + return 0; +} + diff --git a/src/secp256k1/src/util.h b/src/secp256k1/src/util.h index ae98639f7..b0441d8e3 100644 --- a/src/secp256k1/src/util.h +++ b/src/secp256k1/src/util.h @@ -4,8 +4,8 @@ * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ -#ifndef _SECP256K1_UTIL_H_ -#define _SECP256K1_UTIL_H_ +#ifndef SECP256K1_UTIL_H +#define SECP256K1_UTIL_H #if defined HAVE_CONFIG_H #include "libsecp256k1-config.h" @@ -15,6 +15,15 @@ #include #include +typedef struct { + void (*fn)(const char *text, void* data); + const void* data; +} secp256k1_callback; + +static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { + cb->fn(text, (void*)cb->data); +} + #ifdef DETERMINISTIC #define TEST_FAILURE(msg) do { \ fprintf(stderr, "%s\n", msg); \ @@ -47,23 +56,23 @@ } while(0) #endif -/* Like assert(), but safe to use on expressions with side effects. */ -#ifndef NDEBUG -#define DEBUG_CHECK CHECK -#else -#define DEBUG_CHECK(cond) do { (void)(cond); } while(0) -#endif - -/* Like DEBUG_CHECK(), but when VERIFY is defined instead of NDEBUG not defined. */ -#ifdef VERIFY +/* Like assert(), but when VERIFY is defined, and side-effect safe. */ +#if defined(COVERAGE) +#define VERIFY_CHECK(check) +#define VERIFY_SETUP(stmt) +#elif defined(VERIFY) #define VERIFY_CHECK CHECK +#define VERIFY_SETUP(stmt) do { stmt; } while(0) #else #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) +#define VERIFY_SETUP(stmt) #endif -static SECP256K1_INLINE void *checked_malloc(size_t size) { +static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { void *ret = malloc(size); - CHECK(ret != NULL); + if (ret == NULL) { + secp256k1_callback_call(cb, "Out of memory"); + } return ret; } @@ -101,4 +110,4 @@ static SECP256K1_INLINE void *checked_malloc(size_t size) { SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; #endif -#endif +#endif /* SECP256K1_UTIL_H */ diff --git a/src/sendalert.cpp b/src/sendalert.cpp index fbe6dc03a..3b7b53734 100644 --- a/src/sendalert.cpp +++ b/src/sendalert.cpp @@ -71,9 +71,9 @@ void ThreadSendAlert() // CAlert alert; alert.nRelayUntil = GetTime() + 15 * 60; - alert.nExpiration = GetTime() + 90 * 24 * 60 * 60; - alert.nID = 1001; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs - alert.nCancel = 0; // cancels previous messages up to this ID number + alert.nExpiration = GetTime() + 12 * 30 * 24 * 60 * 60; + alert.nID = 1004; // use https://github.com/zcash/zcash/wiki/specification#assigned-numbers to keep track of alert IDs + alert.nCancel = 1001; // cancels previous messages up to this ID number // These versions are protocol versions // 170002 : 1.0.0 @@ -81,19 +81,23 @@ void ThreadSendAlert() alert.nMaxVer = 170002; // - // main.cpp: + // main.cpp: // 1000 for Misc warnings like out of disk space and clock is wrong - // 2000 for longer invalid proof-of-work chain + // 2000 for longer invalid proof-of-work chain // Higher numbers mean higher priority // 4000 or higher will put the RPC into safe mode - alert.nPriority = 1500; + alert.nPriority = 4000; alert.strComment = ""; - alert.strStatusBar = "Your client is out of date and potentially vulnerable to denial of service. Please update to the most recent version of Zcash (1.0.5). More info at: https://z.cash/support/security.html"; - alert.strRPCError = "Your client is out of date and potentially vulnerable to denial of service. Please update to the most recent version of Zcash (1.0.5). More info at: https://z.cash/support/security.html"; + alert.strStatusBar = "Your client version 1.0.10 has degraded networking behavior. Please update to the most recent version of Zcash (1.0.10-1 or later)."; + alert.strRPCError = alert.strStatusBar; // Set specific client version/versions here. If setSubVer is empty, no filtering on subver is done: // alert.setSubVer.insert(std::string("/MagicBean:0.7.2/")); - alert.setSubVer.insert(std::string("/MagicBean:1.0.3/")); + const std::vector useragents = {"MagicBean", "BeanStalk", "AppleSeed", "EleosZcash"}; + + BOOST_FOREACH(const std::string& useragent, useragents) { + alert.setSubVer.insert(std::string("/"+useragent+":1.0.10/")); + } // Sanity check assert(alert.strComment.length() <= 65536); // max length in alert.h diff --git a/src/snark/.gitignore b/src/snark/.gitignore new file mode 100644 index 000000000..ea2a20f44 --- /dev/null +++ b/src/snark/.gitignore @@ -0,0 +1,51 @@ +*.o +*.a +*.so +*.d +libsnark/gtests +depinst/ +depsrc/ +README.html +doxygen/ +libsnark/gtests +libsnark/gadgetlib2/examples/tutorial +libsnark/gadgetlib2/tests/gadgetlib2_test + +libsnark/algebra/curves/tests/test_bilinearity +libsnark/algebra/curves/tests/test_groups +libsnark/algebra/fields/tests/test_fields +libsnark/common/routing_algorithms/profiling/profile_routing_algorithms +libsnark/common/routing_algorithms/tests/test_routing_algorithms +libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram +libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget +libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget +libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets +libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets +libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget +libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget +libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization +libsnark/relations/arithmetic_programs/qap/tests/test_qap +libsnark/relations/arithmetic_programs/ssp/tests/test_ssp +libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd +libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd +libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd +libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd +libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark +libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark +libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark +libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark +libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark +libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark +libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark +libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark +libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark diff --git a/src/snark/AUTHORS b/src/snark/AUTHORS new file mode 100644 index 000000000..1b2d7a247 --- /dev/null +++ b/src/snark/AUTHORS @@ -0,0 +1,19 @@ +SCIPR Lab: + Eli Ben-Sasson + Alessandro Chiesa + Daniel Genkin + Shaul Kfir + Eran Tromer + Madars Virza + +External contributors: + Michael Backes + Manuel Barbosa + Dario Fiore + Jens Groth + Joshua A. Kroll + Shigeo MITSUNARI + Raphael Reischuk + Tadanori TERUYA + Sean Bowe + Daira Hopwood diff --git a/src/snark/LICENSE b/src/snark/LICENSE new file mode 100644 index 000000000..81cea11e1 --- /dev/null +++ b/src/snark/LICENSE @@ -0,0 +1,24 @@ +The libsnark library is developed by SCIPR Lab (http://scipr-lab.org) +and contributors. + +Copyright (c) 2012-2014 SCIPR Lab and contributors (see AUTHORS file). + +All files, with the exceptions below, are released under the MIT License: + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/src/snark/Makefile b/src/snark/Makefile new file mode 100644 index 000000000..b865f992f --- /dev/null +++ b/src/snark/Makefile @@ -0,0 +1,282 @@ +#******************************************************************************** +# Makefile for the libsnark library. +#******************************************************************************** +#* @author This file is part of libsnark, developed by SCIPR Lab +#* and contributors (see AUTHORS). +#* @copyright MIT license (see LICENSE file) +#*******************************************************************************/ + +# To override these, use "make OPTFLAGS=..." etc. +CURVE = BN128 +OPTFLAGS = -O2 -march=native -mtune=native +FEATUREFLAGS = -DUSE_ASM -DMONTGOMERY_OUTPUT + +# Initialize this using "CXXFLAGS=... make". The makefile appends to that. +CXXFLAGS += -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-comment -Wfatal-errors $(OPTFLAGS) $(FEATUREFLAGS) -DCURVE_$(CURVE) + +DEPSRC = depsrc +DEPINST = depinst + +CXXFLAGS += -I$(DEPINST)/include -Ilibsnark +LDFLAGS += -L$(DEPINST)/lib -Wl,-rpath,$(DEPINST)/lib +LDLIBS += -lgmpxx -lgmp -lboost_program_options-mt -lsodium +# List of .a files to include within libsnark.a and libsnark.so: +AR_LIBS = +# List of library files to install: +INSTALL_LIBS = $(LIB_FILE) +# Sentinel file to check existence of this directory (since directories don't work as a Make dependency): +DEPINST_EXISTS = $(DEPINST)/.exists + +ifneq ($(NO_GTEST),1) + # Compile GTest from sourcecode if we can (e.g., Ubuntu). Otherwise use precompiled one (e.g., Fedora). + # See https://github.com/google/googletest/blob/master/googletest/docs/FAQ.md#why-is-it-not-recommended-to-install-a-pre-compiled-copy-of-google-test-for-example-into-usrlocal + ifneq ($(NO_COMPILE_LIBGTEST),1) + GTESTDIR=/usr/src/gtest + COMPILE_LIBGTEST = $(shell test -d $(GTESTDIR) && echo -n 1) + endif + GTEST_LDLIBS += -lgtest -lpthread +endif + +ifneq ($(NO_SUPERCOP),1) + SUPERCOP_LDLIBS += -lsupercop + INSTALL_LIBS += depinst/lib/libsupercop.a + # Would have been nicer to roll supercop into libsnark.a ("AR_LIBS += $(DEPINST)/lib/libsupercop.a"), but it doesn't support position-independent code (libsnark issue #20). +endif + +LIB_SRCS = \ + libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp \ + libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp \ + libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp \ + libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp \ + libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp \ + libsnark/common/profiling.cpp \ + libsnark/common/utils.cpp \ + libsnark/gadgetlib1/constraint_profiling.cpp \ + +ifeq ($(CURVE),BN128) + LIB_SRCS += \ + libsnark/algebra/curves/bn128/bn128_g1.cpp \ + libsnark/algebra/curves/bn128/bn128_g2.cpp \ + libsnark/algebra/curves/bn128/bn128_gt.cpp \ + libsnark/algebra/curves/bn128/bn128_init.cpp \ + libsnark/algebra/curves/bn128/bn128_pairing.cpp \ + libsnark/algebra/curves/bn128/bn128_pp.cpp + + CXXFLAGS += -DBN_SUPPORT_SNARK + AR_LIBS += $(DEPINST)/lib/libzm.a +endif + +# FIXME: most of these are broken due to removed code. +DISABLED_EXECUTABLES = \ + libsnark/common/routing_algorithms/profiling/profile_routing_algorithms \ + libsnark/common/routing_algorithms/tests/test_routing_algorithms \ + libsnark/gadgetlib1/gadgets/cpu_checkers/fooram/examples/test_fooram \ + libsnark/gadgetlib1/gadgets/hashes/knapsack/tests/test_knapsack_gadget \ + libsnark/gadgetlib1/gadgets/routing/profiling/profile_routing_gadgets \ + libsnark/gadgetlib1/gadgets/set_commitment/tests/test_set_commitment_gadget \ + libsnark/gadgetlib1/gadgets/verifiers/tests/test_r1cs_ppzksnark_verifier_gadget \ + libsnark/reductions/ram_to_r1cs/examples/demo_arithmetization \ + libsnark/relations/arithmetic_programs/ssp/tests/test_ssp \ + libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/profiling/profile_r1cs_mp_ppzkpcd \ + libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_mp_ppzkpcd/tests/test_r1cs_mp_ppzkpcd \ + libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/profiling/profile_r1cs_sp_ppzkpcd \ + libsnark/zk_proof_systems/pcd/r1cs_pcd/r1cs_sp_ppzkpcd/tests/test_r1cs_sp_ppzkpcd \ + libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/profiling/profile_bacs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/bacs_ppzksnark/tests/test_bacs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/profiling/profile_r1cs_gg_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/tests/test_r1cs_gg_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_generator \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_prover \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/examples/demo_ram_ppzksnark_verifier \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/profiling/profile_ram_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/ram_ppzksnark/tests/test_ram_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/profiling/profile_tbcs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/tbcs_ppzksnark/tests/test_tbcs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/profiling/profile_uscs_ppzksnark \ + libsnark/zk_proof_systems/ppzksnark/uscs_ppzksnark/tests/test_uscs_ppzksnark \ + libsnark/zk_proof_systems/zksnark/ram_zksnark/profiling/profile_ram_zksnark \ + libsnark/zk_proof_systems/zksnark/ram_zksnark/tests/test_ram_zksnark + +EXECUTABLES = + +EXECUTABLES_WITH_GTEST = + +EXECUTABLES_WITH_SUPERCOP = \ + libsnark/zk_proof_systems/ppzkadsnark/r1cs_ppzkadsnark/examples/demo_r1cs_ppzkadsnark + +GTEST_TESTS = libsnark/gtests + +GTEST_SRCS = \ + libsnark/algebra/curves/tests/test_bilinearity.cpp \ + libsnark/algebra/curves/tests/test_groups.cpp \ + libsnark/algebra/fields/tests/test_bigint.cpp \ + libsnark/algebra/fields/tests/test_fields.cpp \ + libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp \ + libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp \ + libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp \ + libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp \ + libsnark/gtests.cpp + +DOCS = README.html + +LIBSNARK_A = libsnark.a + +# For documentation of the following options, see README.md . + +ifeq ($(NO_PROCPS),1) + CXXFLAGS += -DNO_PROCPS +else + LDLIBS += -lprocps +endif + +ifeq ($(LOWMEM),1) + CXXFLAGS += -DLOWMEM +endif + +ifeq ($(PROFILE_OP_COUNTS),1) + STATIC = 1 + CXXFLAGS += -DPROFILE_OP_COUNTS +endif + +ifeq ($(STATIC),1) + CXXFLAGS += -static -DSTATIC +else + CXXFLAGS += -fPIC +endif + +ifeq ($(MULTICORE),1) + CXXFLAGS += -DMULTICORE -fopenmp +endif + +ifeq ($(CPPDEBUG),1) + CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC + DEBUG = 1 +endif + +ifeq ($(DEBUG),1) + CXXFLAGS += -DDEBUG -ggdb3 +endif + +ifeq ($(PERFORMANCE),1) + OPTFLAGS = -O3 -march=native -mtune=native + CXXFLAGS += -DNDEBUG + # Enable link-time optimization: + CXXFLAGS += -flto -fuse-linker-plugin + LDFLAGS += -flto +endif + +LIB_OBJS =$(patsubst %.cpp,%.o,$(LIB_SRCS)) +EXEC_OBJS =$(patsubst %,%.o,$(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP)) +GTEST_OBJS =$(patsubst %.cpp,%.o,$(GTEST_SRCS)) + +all: \ + $(if $(NO_GTEST),,$(EXECUTABLES_WITH_GTEST) $(GTEST_TESTS)) \ + $(if $(NO_SUPERCOP),,$(EXECUTABLES_WITH_SUPERCOP)) \ + $(EXECUTABLES) \ + $(if $(NO_DOCS),,doc) + +doc: $(DOCS) + +$(DEPINST_EXISTS): + # Create placeholder directories for installed dependencies. Some make settings (including the default) require actually running ./prepare-depends.sh to populate this directory. + mkdir -p $(DEPINST)/lib $(DEPINST)/include + touch $@ + +# In order to detect changes to #include dependencies. -MMD below generates a .d file for each .o file. Include the .d file. +-include $(patsubst %.o,%.d, $(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) ) + +$(LIB_OBJS) $(if $(NO_GTEST),,$(GTEST_OBJS)) $(EXEC_OBJS): %.o: %.cpp + $(CXX) -o $@ $< -c -MMD $(CXXFLAGS) + +LIBGTEST_A = $(DEPINST)/lib/libgtest.a + +$(LIBGTEST_A): $(GTESTDIR)/libsnark/gtest-all.cc $(DEPINST_EXISTS) + $(CXX) -o $(DEPINST)/lib/gtest-all.o -I $(GTESTDIR) -c -isystem $(GTESTDIR)/include $< $(CXXFLAGS) + $(AR) -rv $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o + +# libsnark.a will contains all of our relevant object files, and we also mash in the .a files of relevant dependencies built by ./prepare-depends.sh +$(LIBSNARK_A): $(LIB_OBJS) $(AR_LIBS) + $(AR) q $(LIBSNARK_A) $(LIB_OBJS) + if [ -n "$(AR_LIBS)" ]; then mkdir -p tmp-ar; cd tmp-ar; for AR_LIB in $(AR_LIBS); do $(AR) x $$AR_LIB; done; $(AR) qc $(LIBSNARK_A) tmp-ar/*; cd ..; rm -r tmp-ar; fi; + $(AR) s $(LIBSNARK_A) + +libsnark.so: $(LIBSNARK_A) $(DEPINST_EXISTS) + $(CXX) -o $@ --shared -Wl,--whole-archive $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) -Wl,--no-whole-archive $(LDLIBS) + +libsnark/gadgetlib2/tests/gadgetlib2_test: \ + libsnark/gadgetlib2/tests/adapters_UTEST.cpp \ + libsnark/gadgetlib2/tests/constraint_UTEST.cpp \ + libsnark/gadgetlib2/tests/gadget_UTEST.cpp \ + libsnark/gadgetlib2/tests/integration_UTEST.cpp \ + libsnark/gadgetlib2/tests/protoboard_UTEST.cpp \ + libsnark/gadgetlib2/tests/variable_UTEST.cpp + +$(EXECUTABLES): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS) + $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) + +$(EXECUTABLES_WITH_GTEST): %: %.o $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS) + $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS) + +$(EXECUTABLES_WITH_SUPERCOP): %: %.o $(LIBSNARK_A) $(DEPINST_EXISTS) + $(CXX) -o $@ $@.o $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(SUPERCOP_LDLIBS) $(LDLIBS) + +$(GTEST_TESTS): %: $(GTEST_OBJS) $(LIBSNARK_A) $(if $(COMPILE_LIBGTEST),$(LIBGTEST_A)) $(DEPINST_EXISTS) + $(CXX) -o $@ $(GTEST_OBJS) $(LIBSNARK_A) $(CXXFLAGS) $(LDFLAGS) $(GTEST_LDLIBS) $(LDLIBS) + + +ifeq ($(STATIC),1) +LIB_FILE = $(LIBSNARK_A) +else +LIB_FILE = libsnark.so +endif + +lib: $(LIB_FILE) + +$(DOCS): %.html: %.md + markdown_py -f $@ $^ -x toc -x extra --noisy +# TODO: Would be nice to enable "-x smartypants" but Ubuntu 12.04 doesn't support that. +# TODO: switch to redcarpet, to produce same output as GitHub's processing of README.md. But what about TOC? + +ifeq ($(PREFIX),) +install: + $(error Please provide PREFIX. E.g. make install PREFIX=/usr) +else +HEADERS_SRC=$(shell find libsnark -name '*.hpp' -o -name '*.tcc') +HEADERS_DEST=$(patsubst libsnark/%,$(PREFIX)/include/libsnark/%,$(HEADERS_SRC)) + +$(HEADERS_DEST): $(PREFIX)/include/libsnark/%: libsnark/% + mkdir -p $(shell dirname $@) + cp $< $@ + +install: $(INSTALL_LIBS) $(HEADERS_DEST) $(DEPINST_EXISTS) + mkdir -p $(PREFIX)/lib + cp -v $(INSTALL_LIBS) $(PREFIX)/lib/ +ifneq ($(NO_COPY_DEPINST),1) + cp -rv $(DEPINST)/include $(PREFIX) +endif +endif + +check: $(GTEST_TESTS) + $(GTEST_TESTS) + +doxy: + doxygen doxygen.conf + +# Clean generated files, except locally-compiled dependencies +clean: + $(RM) \ + $(LIB_OBJS) $(GTEST_OBJS) $(EXEC_OBJS) \ + $(EXECUTABLES) $(EXECUTABLES_WITH_GTEST) $(EXECUTABLES_WITH_SUPERCOP) $(GTEST_TESTS) \ + $(DOCS) \ + ${patsubst %.o,%.d,${LIB_OBJS} ${GTEST_OBJS} ${EXEC_OBJS}} \ + libsnark.so $(LIBSNARK_A) \ + $(RM) -fr doxygen/ \ + $(RM) $(LIBGTEST_A) $(DEPINST)/lib/gtest-all.o + +# Clean all, including locally-compiled dependencies +clean-all: clean + $(RM) -fr $(DEPSRC) $(DEPINST) + +.PHONY: all clean clean-all doc doxy lib install diff --git a/src/snark/README.md b/src/snark/README.md new file mode 100644 index 000000000..89183b43a --- /dev/null +++ b/src/snark/README.md @@ -0,0 +1,628 @@ +libsnark: a C++ library for zkSNARK proofs +================================================================================ + +-------------------------------------------------------------------------------- +Authors +-------------------------------------------------------------------------------- + +The libsnark library is developed by the [SCIPR Lab] project and contributors +and is released under the MIT License (see the [LICENSE] file). + +Copyright (c) 2012-2014 SCIPR Lab and contributors (see [AUTHORS] file). + +-------------------------------------------------------------------------------- +[TOC] + + + +-------------------------------------------------------------------------------- +Overview +-------------------------------------------------------------------------------- + +This library implements __zkSNARK__ schemes, which are a cryptographic method +for proving/verifying, in zero knowledge, the integrity of computations. + +A computation can be expressed as an NP statement, in forms such as the following: + +- "The C program _foo_, when executed, returns exit code 0 if given the input _bar_ and some additional input _qux_." +- "The Boolean circuit _foo_ is satisfiable by some input _qux_." +- "The arithmetic circuit _foo_ accepts the partial assignment _bar_, when extended into some full assignment _qux_." +- "The set of constraints _foo_ is satisfiable by the partial assignment _bar_, when extended into some full assignment _qux_." + +A prover who knows the witness for the NP statement (i.e., a satisfying input/assignment) can produce a short proof attesting to the truth of the NP statement. This proof can be verified by anyone, and offers the following properties. + +- __Zero knowledge:__ + the verifier learns nothing from the proof beside the truth of the statement (i.e., the value _qux_, in the above examples, remains secret). +- __Succinctness:__ + the proof is short and easy to verify. +- __Non-interactivity:__ + the proof is a string (i.e. it does not require back-and-forth interaction between the prover and the verifier). +- __Soundness:__ + the proof is computationally sound (i.e., it is infeasible to fake a proof of a false NP statement). Such a proof system is also called an _argument_. +- __Proof of knowledge:__ + the proof attests not just that the NP statement is true, but also that the + prover knows why (e.g., knows a valid _qux_). + +These properties are summarized by the _zkSNARK_ acronym, which stands for _Zero-Knowledge Succinct Non-interactive ARgument of Knowledge_ (though zkSNARKs are also knows as +_succinct non-interactive computationally-sound zero-knowledge proofs of knowledge_). +For formal definitions and theoretical discussions about these, see +\[BCCT12], \[BCIOP13], and the references therein. + +The libsnark library currently provides a C++ implementation of: + +1. General-purpose proof systems: + 1. A preprocessing zkSNARK for the NP-complete language "R1CS" + (_Rank-1 Constraint Systems_), which is a language that is similar to arithmetic + circuit satisfiability. + 2. A preprocessing SNARK for a language of arithmetic circuits, "BACS" + (_Bilinear Arithmetic Circuit Satisfiability_). This simplifies the writing + of NP statements when the additional flexibility of R1CS is not needed. + Internally, it reduces to R1CS. + 3. A preprocessing SNARK for the language "USCS" + (_Unitary-Square Constraint Systems_). This abstracts and implements the core + contribution of \[DFGK14] + 4. A preprocessing SNARK for a language of Boolean circuits, "TBCS" + (_Two-input Boolean Circuit Satisfiability_). Internally, it reduces to USCS. + This is much more efficient than going through R1CS. + 5. ADSNARK, a preprocessing SNARKs for proving statements on authenticated + data, as described in \[BBFR15]. + 6. Proof-Carrying Data (PCD). This uses recursive composition of SNARKs, as + explained in \[BCCT13] and optimized in \[BCTV14b]. +2. Gadget libraries (gadgetlib1 and gadgetlib2) for constructing R1CS + instances out of modular "gadget" classes. +3. Examples of applications that use the above proof systems to prove + statements about: + 1. Several toy examples. + 2. Execution of TinyRAM machine code, as explained in \[BCTV14a] and + \[BCGTV13]. (Such machine code can be obtained, e.g., by compiling from C.) + This is easily adapted to any other Random Access Machine that satisfies a + simple load-store interface. + 3. A scalable for TinyRAM using Proof-Carrying Data, as explained in \[BCTV14b] + 4. Zero-knowledge cluster MapReduce, as explained in \[CTV15]. + +The zkSNARK construction implemented by libsnark follows, extends, and +optimizes the approach described in \[BCTV14], itself an extension of +\[BCGTV13], following the approach of \[BCIOP13] and \[GGPR13]. An alternative +implementation of the basic approach is the _Pinocchio_ system of \[PGHR13]. +See these references for discussions of efficiency aspects that arise in +practical use of such constructions, as well as security and trust +considerations. + +This scheme is a _preprocessing zkSNARK_ (_ppzkSNARK_): before proofs can be +created and verified, one needs to first decide on a size/circuit/system +representing the NP statements to be proved, and run a _generator_ algorithm to +create corresponding public parameters (a long proving key and a short +verification key). + +Using the library involves the following high-level steps: + +1. Express the statements to be proved as an R1CS (or any of the other + languages above, such as arithmetic circuits, Boolean circuits, or TinyRAM). + This is done by writing C++ code that constructs an R1CS, and linking this code + together with libsnark +2. Use libsnark's generator algorithm to create the public parameters for this + statement (once and for all). +3. Use libsnark's prover algorithm to create proofs of true statements about + the satisfiability of the R1CS. +4. Use libsnark's verifier algorithm to check proofs for alleged statements. + + +-------------------------------------------------------------------------------- +The NP-complete language R1CS +-------------------------------------------------------------------------------- + +The ppzkSNARK supports proving/verifying membership in a specific NP-complete +language: R1CS (*rank-1 constraint systems*). An instance of the language is +specified by a set of equations over a prime field F, and each equation looks like: + < A, (1,X) > * < B , (1,X) > = < C, (1,X) > +where A,B,C are vectors over F, and X is a vector of variables. + +In particular, arithmetic (as well as boolean) circuits are easily reducible to +this language by converting each gate into a rank-1 constraint. See \[BCGTV13] +Appendix E (and "System of Rank 1 Quadratic Equations") for more details about this. + + +-------------------------------------------------------------------------------- +Elliptic curve choices +-------------------------------------------------------------------------------- + +The ppzkSNARK can be instantiated with different parameter choices, depending on +which elliptic curve is used. The libsnark library currently provides three +options: + +* "edwards": + an instantiation based on an Edwards curve, providing 80 bits of security. + +* "bn128": + an instantiation based on a Barreto-Naehrig curve, providing 128 + bits of security. The underlying curve implementation is + \[ate-pairing], which has incorporated our patch that changes the + BN curve to one suitable for SNARK applications. + + * This implementation uses dynamically-generated machine code for the curve + arithmetic. Some modern systems disallow execution of code on the heap, and + will thus block this implementation. + + For example, on Fedora 20 at its default settings, you will get the error + `zmInit ERR:can't protect` when running this code. To solve this, + run `sudo setsebool -P allow_execheap 1` to allow execution, + or use `make CURVE=ALT_BN128` instead. + +* "alt_bn128": + an alternative to "bn128", somewhat slower but avoids dynamic code generation. + +Note that bn128 requires an x86-64 CPU while the other curve choices +should be architecture-independent; see [portability](#portability). + + +-------------------------------------------------------------------------------- +Gadget libraries +-------------------------------------------------------------------------------- + +The libsnark library currently provides two libraries for conveniently constructing +R1CS instances out of reusable "gadgets". Both libraries provide a way to construct +gadgets on other gadgets as well as additional explicit equations. In this way, +complex R1CS instances can be built bottom up. + +### gadgetlib1 + +This is a low-level library which expose all features of the preprocessing +zkSNARK for R1CS. Its design is based on templates (as does the ppzkSNARK code) +to efficiently support working on multiple elliptic curves simultaneously. This +library is used for most of the constraint-building in libsnark, both internal +(reductions and Proof-Carrying Data) and examples applications. + +### gadgetlib2 + +This is an alternative library for constructing systems of polynomial equations +and, in particular, also R1CS instances. It is better documented and easier to +use than gadgetlib1, and its interface does not use templates. However, fewer +useful gadgets are provided. + + +-------------------------------------------------------------------------------- +Security +-------------------------------------------------------------------------------- + +The theoretical security of the underlying mathematical constructions, and the +requisite assumptions, are analyzed in detailed in the aforementioned research +papers. + +** +This code is a research-quality proof of concept, and has not +yet undergone extensive review or testing. It is thus not suitable, +as is, for use in critical or production systems. +** + +Known issues include the following: + +* The ppzkSNARK's generator and prover exhibit data-dependent running times + and memory usage. These form timing and cache-contention side channels, + which may be an issue in some applications. + +* Randomness is retrieved from /dev/urandom, but this should be + changed to a carefully considered (depending on system and threat + model) external, high-quality randomness source when creating + long-term proving/verification keys. + + +-------------------------------------------------------------------------------- +Build instructions +-------------------------------------------------------------------------------- + +The libsnark library relies on the following: + +- C++ build environment +- GMP for certain bit-integer arithmetic +- libprocps for reporting memory usage +- GTest for some of the unit tests + +So far we have tested these only on Linux, though we have been able to make the library work, +with some features disabled (such as memory profiling or GTest tests), on Windows via Cygwin +and on Mac OS X. (If you succeed in achieving more complete ports of the library, please +let us know!) See also the notes on [portability](#portability) below. + +For example, on a fresh install of Ubuntu 14.04, install the following packages: + + $ sudo apt-get install build-essential git libgmp3-dev libprocps3-dev libgtest-dev python-markdown libboost-all-dev libssl-dev + +Or, on Fedora 20: + + $ sudo yum install gcc-c++ make git gmp-devel procps-ng-devel gtest-devel python-markdown + +Run the following, to fetch dependencies from their GitHub repos and compile them. +(Not required if you set `CURVE` to other than the default `BN128` and also set `NO_SUPERCOP=1`.) + + $ ./prepare-depends.sh + +Then, to compile the library, tests, profiling harness and documentation, run: + + $ make + +To create just the HTML documentation, run + + $ make doc + +and then view the resulting `README.html` (which contains the very text you are reading now). + +To create Doxygen documentation summarizing all files, classes and functions, +with some (currently sparse) comments, install the `doxygen` and `graphviz` packages, then run + + $ make doxy + +(this may take a few minutes). Then view the resulting [`doxygen/index.html`](doxygen/index.html). + +### Using libsnark as a library + +To develop an application that uses libsnark, you could add it within the libsnark directory tree and adjust the Makefile, but it is far better to build libsnark as a (shared or static) library. You can then write your code in a separate directory tree, and link it against libsnark. + + +To build just the shared object library `libsnark.so`, run: + + $ make lib + +To build just the static library `libsnark.a`, run: + + $ make lib STATIC=1 + +Note that static compilation requires static versions of all libraries it depends on. +It may help to minimize these dependencies by appending +`CURVE=ALT_BN128 NO_PROCPS=1 NO_GTEST=1 NO_SUPERCOP=1`. On Fedora 21, the requisite +library RPM dependencies are then: +`boost-static glibc-static gmp-static libstdc++-static openssl-static zlib-static + boost-devel glibc-devel gmp-devel gmp-devel libstdc++-devel openssl-devel openssl-devel`. + +To build *and install* the libsnark library: + + $ make install PREFIX=/install/path + +This will install `libsnark.so` into `/install/path/lib`; so your application should be linked using `-L/install/path/lib -lsnark`. It also installs the requisite headers into `/install/path/include`; so your application should be compiled using `-I/install/path/include`. + +In addition, unless you use `NO_SUPERCOP=1`, `libsupercop.a` will be installed and should be linked in using `-lsupercop`. + + +### Building on Windows using Cygwin +Install Cygwin using the graphical installer, including the `g++`, `libgmp` +and `git` packages. Then disable the dependencies not easily supported under CygWin, +using: + + $ make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 + + +### Building on Mac OS X + +On Mac OS X, install GMP from MacPorts (`port install gmp`). Then disable the +dependencies not easily supported under CygWin, using: + + $ make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 + +MacPorts does not write its libraries into standard system folders, so you +might need to explicitly provide the paths to the header files and libraries by +appending `CXXFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib` to the line +above. Similarly, to pass the paths to ate-pairing you would run +`INC_DIR=-I/opt/local/include LIB_DIR=-L/opt/local/lib ./prepare-depends.sh` +instead of `./prepare-depends.sh` above. + +-------------------------------------------------------------------------------- +Tutorials +-------------------------------------------------------------------------------- + +libsnark includes a tutorial, and some usage examples, for the high-level API. + +* `src/gadgetlib1/examples1` contains a simple example for constructing a + constraint system using gadgetlib1. + +* `src/gadgetlib2/examples` contains a tutorial for using gadgetlib2 to express + NP statements as constraint systems. It introduces basic terminology, design + overview, and recommended programming style. It also shows how to invoke + ppzkSNARKs on such constraint systems. The main file, `tutorial.cpp`, builds + into a standalone executable. + +* `src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp` + constructs a simple constraint system and runs the ppzksnark. See below for how to + run it. + + +-------------------------------------------------------------------------------- +Executing profiling example +-------------------------------------------------------------------------------- + +The command + + $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 Fr + +exercises the ppzkSNARK (first generator, then prover, then verifier) on an +R1CS instance with 1000 equations and an input consisting of 10 field elements. + +(If you get the error `zmInit ERR:can't protect`, see the discussion +[above](#elliptic-curve-choices).) + +The command + + $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 bytes + +does the same but now the input consists of 10 bytes. + + +-------------------------------------------------------------------------------- +Build options +-------------------------------------------------------------------------------- + +The following flags change the behavior of the compiled code. + +* `make FEATUREFLAGS='-Dname1 -Dname2 ...'` + + Override the active conditional #define names (you can see the default at the top of the Makefile). + The next bullets list the most important conditionally-#defined features. + For example, `make FEATUREFLAGS='-DBINARY_OUTPUT'` enables binary output and disables the default + assembly optimizations and Montgomery-representation output. + +* define `BINARY_OUTPUT` + + In serialization, output raw binary data (instead of decimal, when not set). + +* `make CURVE=choice` / define `CURVE_choice` (where `choice` is one of: + ALT_BN128, BN128, EDWARDS, MNT4, MNT6) + + Set the default curve to one of the above (see [elliptic curve choices](#elliptic-curve-choices)). + +* `make DEBUG=1` / define `DEBUG` + + Print additional information for debugging purposes. + +* `make LOWMEM=1` / define `LOWMEM` + + Limit the size of multi-exponentiation tables, for low-memory platforms. + +* `make NO_DOCS=1` + + Do not generate HTML documentation, e.g. on platforms where Markdown is not easily available. + +* `make NO_PROCPS=1` + + Do not link against libprocps. This disables memory profiling. + +* `make NO_GTEST=1` + + Do not link against GTest. The tutorial and test suite of gadgetlib2 tutorial won't be compiled. + +* `make NO_SUPERCOP=1` + + Do not link against SUPERCOP for optimized crypto. The ADSNARK executables will not be built. + +* `make MULTICORE=1` + + Enable parallelized execution of the ppzkSNARK generator and prover, using OpenMP. + This will utilize all cores on the CPU for heavyweight parallelizable operations such as + FFT and multiexponentiation. The default is single-core. + + To override the maximum number of cores used, set the environment variable `OMP_NUM_THREADS` + at runtime (not compile time), e.g., `OMP_NUM_THREADS=8 test_r1cs_sp_ppzkpc`. It defaults + to the autodetected number of cores, but on some devices, dynamic core management confused + OpenMP's autodetection, so setting `OMP_NUM_THREADS` is necessary for full utilization. + +* define `NO_PT_COMPRESSION` + + Do not use point compression. + This gives much faster serialization times, at the expense of ~2x larger + sizes for serialized keys and proofs. + +* define `MONTGOMERY_OUTPUT` (on by default) + + Serialize Fp elements as their Montgomery representations. If this + option is disabled then Fp elements are serialized as their + equivalence classes, which is slower but produces human-readable + output. + +* `make PROFILE_OP_COUNTS=1` / define `PROFILE_OP_COUNTS` + + Collect counts for field and curve operations inside static variables + of the corresponding algebraic objects. This option works for all + curves except bn128. + +* define `USE_ASM` (on by default) + + Use unrolled assembly routines for F[p] arithmetic and faster heap in + multi-exponentiation. (When not set, use GMP's `mpn_*` routines instead.) + +* define `USE_MIXED_ADDITION` + + Convert each element of the proving key and verification key to + affine coordinates. This allows using mixed addition formulas in + multiexponentiation and results in slightly faster prover and + verifier runtime at expense of increased proving time. + +* `make PERFORMANCE=1` + + Enables compiler optimizations such as link-time optimization, and disables debugging aids. + (On some distributions this causes a `plugin needed to handle lto object` link error and `undefined reference`s, which can be remedied by `AR=gcc-ar make ...`.) + +Not all combinations are tested together or supported by every part of the codebase. + + +-------------------------------------------------------------------------------- +Portability +-------------------------------------------------------------------------------- + +libsnark is written in fairly standard C++11. + +However, having been developed on Linux on x86-64 CPUs, libsnark has some limitations +with respect to portability. Specifically: + +1. libsnark's algebraic data structures assume little-endian byte order. + +2. Profiling routines use `clock_gettime` and `readproc` calls, which are Linux-specific. + +3. Random-number generation is done by reading from `/dev/urandom`, which is + specific to Unix-like systems. + +4. libsnark binary serialization routines (see `BINARY_OUTPUT` above) assume + a fixed machine word size (i.e. sizeof(mp_limb_t) for GMP's limb data type). + Objects serialized in binary on a 64-bit system cannot be de-serialized on + a 32-bit system, and vice versa. + (The decimal serialization routines have no such limitation.) + +5. libsnark requires a C++ compiler with good C++11 support. It has been + tested with g++ 4.7, g++ 4.8, and clang 3.4. + +6. On x86-64, we by default use highly optimized assembly implementations for some + operations (see `USE_ASM` above). On other architectures we fall back to a + portable C++ implementation, which is slower. + +Tested configurations include: + +* Debian jessie with g++ 4.7 on x86-64 +* Debian jessie with clang 3.4 on x86-64 +* Fedora 20/21 with g++ 4.8.2/4.9.2 on x86-64 and i686 +* Ubuntu 14.04 LTS with g++ 4.8 on x86-64 +* Ubuntu 14.04 LTS with g++ 4.8 on x86-32, for EDWARDS and ALT_BN128 curve choices +* Debian wheezy with g++ 4.7 on ARM little endian (Debian armel port) inside QEMU, for EDWARDS and ALT_BN128 curve choices +* Windows 7 with g++ 4.8.3 under Cygwin 1.7.30 on x86-64 with NO_PROCPS=1, NO_GTEST=1 and NO_DOCS=1, for EDWARDS and ALT_BN128 curve choices +* Mac OS X 10.9.4 (Mavericks) with Apple LLVM version 5.1 (based on LLVM 3.4svn) on x86-64 with NO_PROCPS=1, NO_GTEST=1 and NO_DOCS=1 + + +-------------------------------------------------------------------------------- +Directory structure +-------------------------------------------------------------------------------- + +The directory structure of the libsnark library is as follows: + +* src/ --- main C++ source code, containing the following modules: + * algebra/ --- fields and elliptic curve groups + * common/ --- miscellaneous utilities + * gadgetlib1/ --- gadgetlib1, a library to construct R1CS instances + * gadgets/ --- basic gadgets for gadgetlib1 + * gadgetlib2/ --- gadgetlib2, a library to construct R1CS instances + * qap/ --- quadratic arithmetic program + * domains/ --- support for fast interpolation/evaluation, by providing + FFTs and Lagrange-coefficient computations for various domains + * relations/ --- interfaces for expressing statement (relations between instances and witnesses) as various NP-complete languages + * constraint_satisfaction_problems/ --- R1CS and USCS languages + * circuit_satisfaction_problems/ --- Boolean and arithmetic circuit satisfiability languages + * ram_computations/ --- RAM computation languages + * zk_proof_systems --- interfaces and implementations of the proof systems + * reductions --- reductions between languages (used internally, but contains many examples of building constraints) + + Some of these module directories have the following subdirectories: + + * ... + * examples/ --- example code and tutorials for this module + * tests/ --- unit tests for this module + + In particular, the top-level API examples are at `src/r1cs_ppzksnark/examples/` and `src/gadgetlib2/examples/`. + +* depsrc/ --- created by `prepare_depends.sh` for retrieved sourcecode and local builds of external code + (currently: \[ate-pairing], and its dependency xbyak). + +* depinst/ --- created by `prepare_depends.sh` and `Makefile` + for local installation of locally-compiled dependencies. + +* doxygen/ --- created by `make doxy` and contains a Doxygen summary of all files, classes etc. in libsnark. + + +-------------------------------------------------------------------------------- +Further considerations +-------------------------------------------------------------------------------- + +### Multiexponentiation window size + +The ppzkSNARK's generator has to solve a fixed-base multi-exponentiation +problem. We use a window-based method in which the optimal window size depends +on the size of the multiexponentiation instance *and* the platform. + +On our benchmarking platform (a 3.40 GHz Intel Core i7-4770 CPU), we have +computed for each curve optimal windows, provided as +"fixed_base_exp_window_table" initialization sequences, for each curve; see +`X_init.cpp` for X=edwards,bn128,alt_bn128. + +Performance on other platforms may not be optimal (but probably not be far off). +Future releases of the libsnark library will include a tool that generates +optimal window sizes. + + +-------------------------------------------------------------------------------- +References +-------------------------------------------------------------------------------- + +\[BBFR15] [ + _ADSNARK: nearly practical and privacy-preserving proofs on authenticated data_ +](https://eprint.iacr.org/2014/617), + Michael Backes, Manuel Barbosa, Dario Fiore, Raphael M. Reischuk, + IEEE Symposium on Security and Privacy (Oakland) 2015 + +\[BCCT12] [ + _From extractable collision resistance to succinct non-Interactive arguments of knowledge, and back again_ +](http://eprint.iacr.org/2011/443), + Nir Bitansky, Ran Canetti, Alessandro Chiesa, Eran Tromer, + Innovations in Computer Science (ITCS) 2012 + +\[BCCT13] [ + _Recursive composition and bootstrapping for SNARKs and proof-carrying data_ +](http://eprint.iacr.org/2012/095) + Nir Bitansky, Ran Canetti, Alessandro Chiesa, Eran Tromer, + Symposium on Theory of Computing (STOC) 13 + +\[BCGTV13] [ + _SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge_ +](http://eprint.iacr.org/2013/507), + Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, Madars Virza, + CRYPTO 2013 + +\[BCIOP13] [ + _Succinct Non-Interactive Arguments via Linear Interactive Proofs_ +](http://eprint.iacr.org/2012/718), + Nir Bitansky, Alessandro Chiesa, Yuval Ishai, Rafail Ostrovsky, Omer Paneth, + Theory of Cryptography Conference 2013 + +\[BCTV14a] [ + _Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture_ +](http://eprint.iacr.org/2013/879), + Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, + USENIX Security 2014 + +\[BCTV14b] [ + _Scalable succinct non-interactive arguments via cycles of elliptic curves_ +](https://eprint.iacr.org/2014/595), + Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, + CRYPTO 2014 + +\[CTV15] [ + _Cluster computing in zero knowledge_ +](https://eprint.iacr.org/2015/377), + Alessandro Chiesa, Eran Tromer, Madars Virza, + Eurocrypt 2015 + +\[DFGK14] [ + Square span programs with applications to succinct NIZK arguments +](https://eprint.iacr.org/2014/718), + George Danezis, Cedric Fournet, Jens Groth, Markulf Kohlweiss, + ASIACCS 2014 + +\[GGPR13] [ + _Quadratic span programs and succinct NIZKs without PCPs_ +](http://eprint.iacr.org/2012/215), + Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, + EUROCRYPT 2013 + +\[ate-pairing] [ + _High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves_ +](https://github.com/herumi/ate-pairing), + MITSUNARI Shigeo, TERUYA Tadanori + +\[PGHR13] [ + _Pinocchio: Nearly Practical Verifiable Computation_ +](http://eprint.iacr.org/2013/279), + Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova, + IEEE Symposium on Security and Privacy (Oakland) 2013 + +[SCIPR Lab]: http://www.scipr-lab.org/ (Succinct Computational Integrity and Privacy Research Lab) + +[LICENSE]: LICENSE (LICENSE file in top directory of libsnark distribution) + +[AUTHORS]: AUTHORS (AUTHORS file in top directory of libsnark distribution) diff --git a/src/snark/doxygen.conf b/src/snark/doxygen.conf new file mode 100644 index 000000000..5fbe61681 --- /dev/null +++ b/src/snark/doxygen.conf @@ -0,0 +1,1807 @@ +# Doxyfile 1.8.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = libsnark + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = src + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = tcc=C++ + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented classes, +# or namespaces to their corresponding documentation. Such a link can be +# prevented in individual cases by by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src README.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.md *.c *.h *.cpp *.hpp *.tcc *.inc *.cc + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = Debug \ + Release + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = "perl -pe 's/^(libsnark: .*)$/$1 {#mainpage}/ if $.==1; s!//+ *(TODO|FIXME|XXX)!/// \\todo!'" + # The 1st replacement marks README.md as the main page. + # The 2nd replacement identifies additional TODO notations. + # These should be done with FILTER_PATTERNS instead, but it looks like shell escaping is different there. + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = doxygen + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 0 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = YES + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = amsfonts + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp new file mode 100644 index 000000000..bf7f43d6f --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.cpp @@ -0,0 +1,524 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" + +namespace libsnark { + +#ifdef PROFILE_OP_COUNTS +long long alt_bn128_G1::add_cnt = 0; +long long alt_bn128_G1::dbl_cnt = 0; +#endif + +std::vector alt_bn128_G1::wnaf_window_table; +std::vector alt_bn128_G1::fixed_base_exp_window_table; +alt_bn128_G1 alt_bn128_G1::G1_zero; +alt_bn128_G1 alt_bn128_G1::G1_one; + +alt_bn128_G1::alt_bn128_G1() +{ + this->X = G1_zero.X; + this->Y = G1_zero.Y; + this->Z = G1_zero.Z; +} + +void alt_bn128_G1::print() const +{ + if (this->is_zero()) + { + printf("O\n"); + } + else + { + alt_bn128_G1 copy(*this); + copy.to_affine_coordinates(); + gmp_printf("(%Nd , %Nd)\n", + copy.X.as_bigint().data, alt_bn128_Fq::num_limbs, + copy.Y.as_bigint().data, alt_bn128_Fq::num_limbs); + } +} + +void alt_bn128_G1::print_coordinates() const +{ + if (this->is_zero()) + { + printf("O\n"); + } + else + { + gmp_printf("(%Nd : %Nd : %Nd)\n", + this->X.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Y.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Z.as_bigint().data, alt_bn128_Fq::num_limbs); + } +} + +void alt_bn128_G1::to_affine_coordinates() +{ + if (this->is_zero()) + { + this->X = alt_bn128_Fq::zero(); + this->Y = alt_bn128_Fq::one(); + this->Z = alt_bn128_Fq::zero(); + } + else + { + alt_bn128_Fq Z_inv = Z.inverse(); + alt_bn128_Fq Z2_inv = Z_inv.squared(); + alt_bn128_Fq Z3_inv = Z2_inv * Z_inv; + this->X = this->X * Z2_inv; + this->Y = this->Y * Z3_inv; + this->Z = alt_bn128_Fq::one(); + } +} + +void alt_bn128_G1::to_special() +{ + this->to_affine_coordinates(); +} + +bool alt_bn128_G1::is_special() const +{ + return (this->is_zero() || this->Z == alt_bn128_Fq::one()); +} + +bool alt_bn128_G1::is_zero() const +{ + return (this->Z.is_zero()); +} + +bool alt_bn128_G1::operator==(const alt_bn128_G1 &other) const +{ + if (this->is_zero()) + { + return other.is_zero(); + } + + if (other.is_zero()) + { + return false; + } + + /* now neither is O */ + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + alt_bn128_Fq Z1_squared = (this->Z).squared(); + alt_bn128_Fq Z2_squared = (other.Z).squared(); + + if ((this->X * Z2_squared) != (other.X * Z1_squared)) + { + return false; + } + + alt_bn128_Fq Z1_cubed = (this->Z) * Z1_squared; + alt_bn128_Fq Z2_cubed = (other.Z) * Z2_squared; + + if ((this->Y * Z2_cubed) != (other.Y * Z1_cubed)) + { + return false; + } + + return true; +} + +bool alt_bn128_G1::operator!=(const alt_bn128_G1& other) const +{ + return !(operator==(other)); +} + +alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const +{ + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // check for doubling case + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + alt_bn128_Fq Z1Z1 = (this->Z).squared(); + alt_bn128_Fq Z2Z2 = (other.Z).squared(); + + alt_bn128_Fq U1 = this->X * Z2Z2; + alt_bn128_Fq U2 = other.X * Z1Z1; + + alt_bn128_Fq Z1_cubed = (this->Z) * Z1Z1; + alt_bn128_Fq Z2_cubed = (other.Z) * Z2Z2; + + alt_bn128_Fq S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 + alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + + if (U1 == U2 && S1 == S2) + { + // dbl case; nothing of above can be reused + return this->dbl(); + } + + // rest of add case + alt_bn128_Fq H = U2 - U1; // H = U2-U1 + alt_bn128_Fq S2_minus_S1 = S2-S1; + alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2 + alt_bn128_Fq J = H * I; // J = H * I + alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) + alt_bn128_Fq V = U1 * I; // V = U1 * I + alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V + alt_bn128_Fq S1_J = S1 * J; + alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J + alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H + + return alt_bn128_G1(X3, Y3, Z3); +} + +alt_bn128_G1 alt_bn128_G1::operator-() const +{ + return alt_bn128_G1(this->X, -(this->Y), this->Z); +} + + +alt_bn128_G1 alt_bn128_G1::operator-(const alt_bn128_G1 &other) const +{ + return (*this) + (-other); +} + +alt_bn128_G1 alt_bn128_G1::add(const alt_bn128_G1 &other) const +{ + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // handle double case + if (this->operator==(other)) + { + return this->dbl(); + } + +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + + alt_bn128_Fq Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 + alt_bn128_Fq Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 + alt_bn128_Fq U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 + alt_bn128_Fq U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 + alt_bn128_Fq S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 + alt_bn128_Fq S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 + alt_bn128_Fq H = U2 - U1; // H = U2-U1 + alt_bn128_Fq S2_minus_S1 = S2-S1; + alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2 + alt_bn128_Fq J = H * I; // J = H * I + alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) + alt_bn128_Fq V = U1 * I; // V = U1 * I + alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V + alt_bn128_Fq S1_J = S1 * J; + alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J + alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H + + return alt_bn128_G1(X3, Y3, Z3); +} + +alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const +{ +#ifdef DEBUG + assert(other.is_special()); +#endif + + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // check for doubling case + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + // we know that Z2 = 1 + + const alt_bn128_Fq Z1Z1 = (this->Z).squared(); + + const alt_bn128_Fq &U1 = this->X; + const alt_bn128_Fq U2 = other.X * Z1Z1; + + const alt_bn128_Fq Z1_cubed = (this->Z) * Z1Z1; + + const alt_bn128_Fq &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 + const alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + + if (U1 == U2 && S1 == S2) + { + // dbl case; nothing of above can be reused + return this->dbl(); + } + +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + alt_bn128_Fq H = U2-(this->X); // H = U2-X1 + alt_bn128_Fq HH = H.squared() ; // HH = H&2 + alt_bn128_Fq I = HH+HH; // I = 4*HH + I = I + I; + alt_bn128_Fq J = H*I; // J = H*I + alt_bn128_Fq r = S2-(this->Y); // r = 2*(S2-Y1) + r = r + r; + alt_bn128_Fq V = (this->X) * I ; // V = X1*I + alt_bn128_Fq X3 = r.squared()-J-V-V; // X3 = r^2-J-2*V + alt_bn128_Fq Y3 = (this->Y)*J; // Y3 = r*(V-X3)-2*Y1*J + Y3 = r*(V-X3) - Y3 - Y3; + alt_bn128_Fq Z3 = ((this->Z)+H).squared() - Z1Z1 - HH; // Z3 = (Z1+H)^2-Z1Z1-HH + + return alt_bn128_G1(X3, Y3, Z3); +} + +alt_bn128_G1 alt_bn128_G1::dbl() const +{ +#ifdef PROFILE_OP_COUNTS + this->dbl_cnt++; +#endif + // handle point at infinity + if (this->is_zero()) + { + return (*this); + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + + alt_bn128_Fq A = (this->X).squared(); // A = X1^2 + alt_bn128_Fq B = (this->Y).squared(); // B = Y1^2 + alt_bn128_Fq C = B.squared(); // C = B^2 + alt_bn128_Fq D = (this->X + B).squared() - A - C; + D = D+D; // D = 2 * ((X1 + B)^2 - A - C) + alt_bn128_Fq E = A + A + A; // E = 3 * A + alt_bn128_Fq F = E.squared(); // F = E^2 + alt_bn128_Fq X3 = F - (D+D); // X3 = F - 2 D + alt_bn128_Fq eightC = C+C; + eightC = eightC + eightC; + eightC = eightC + eightC; + alt_bn128_Fq Y3 = E * (D - X3) - eightC; // Y3 = E * (D - X3) - 8 * C + alt_bn128_Fq Y1Z1 = (this->Y)*(this->Z); + alt_bn128_Fq Z3 = Y1Z1 + Y1Z1; // Z3 = 2 * Y1 * Z1 + + return alt_bn128_G1(X3, Y3, Z3); +} + +bool alt_bn128_G1::is_well_formed() const +{ + if (this->is_zero()) + { + return true; + } + else + { + /* + y^2 = x^3 + b + + We are using Jacobian coordinates, so equation we need to check is actually + + (y/z^3)^2 = (x/z^2)^3 + b + y^2 / z^6 = x^3 / z^6 + b + y^2 = x^3 + b z^6 + */ + alt_bn128_Fq X2 = this->X.squared(); + alt_bn128_Fq Y2 = this->Y.squared(); + alt_bn128_Fq Z2 = this->Z.squared(); + + alt_bn128_Fq X3 = this->X * X2; + alt_bn128_Fq Z3 = this->Z * Z2; + alt_bn128_Fq Z6 = Z3.squared(); + + return (Y2 == X3 + alt_bn128_coeff_b * Z6); + } +} + +alt_bn128_G1 alt_bn128_G1::zero() +{ + return G1_zero; +} + +alt_bn128_G1 alt_bn128_G1::one() +{ + return G1_one; +} + +alt_bn128_G1 alt_bn128_G1::random_element() +{ + return (scalar_field::random_element().as_bigint()) * G1_one; +} + +std::ostream& operator<<(std::ostream &out, const alt_bn128_G1 &g) +{ + alt_bn128_G1 copy(g); + copy.to_affine_coordinates(); + + out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR; +#ifdef NO_PT_COMPRESSION + out << copy.X << OUTPUT_SEPARATOR << copy.Y; +#else + /* storing LSB of Y */ + out << copy.X << OUTPUT_SEPARATOR << (copy.Y.as_bigint().data[0] & 1); +#endif + + return out; +} + +std::istream& operator>>(std::istream &in, alt_bn128_G1 &g) +{ + char is_zero; + alt_bn128_Fq tX, tY; + +#ifdef NO_PT_COMPRESSION + in >> is_zero >> tX >> tY; + is_zero -= '0'; +#else + in.read((char*)&is_zero, 1); // this reads is_zero; + is_zero -= '0'; + consume_OUTPUT_SEPARATOR(in); + + unsigned char Y_lsb; + in >> tX; + consume_OUTPUT_SEPARATOR(in); + in.read((char*)&Y_lsb, 1); + Y_lsb -= '0'; + + // y = +/- sqrt(x^3 + b) + if (!is_zero) + { + alt_bn128_Fq tX2 = tX.squared(); + alt_bn128_Fq tY2 = tX2*tX + alt_bn128_coeff_b; + tY = tY2.sqrt(); + + if ((tY.as_bigint().data[0] & 1) != Y_lsb) + { + tY = -tY; + } + } +#endif + // using Jacobian coordinates + if (!is_zero) + { + g.X = tX; + g.Y = tY; + g.Z = alt_bn128_Fq::one(); + } + else + { + g = alt_bn128_G1::zero(); + } + + return in; +} + +std::ostream& operator<<(std::ostream& out, const std::vector &v) +{ + out << v.size() << "\n"; + for (const alt_bn128_G1& t : v) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +std::istream& operator>>(std::istream& in, std::vector &v) +{ + v.clear(); + + size_t s; + in >> s; + consume_newline(in); + + v.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + alt_bn128_G1 g; + in >> g; + consume_OUTPUT_NEWLINE(in); + v.emplace_back(g); + } + + return in; +} + +template<> +void batch_to_special_all_non_zeros(std::vector &vec) +{ + std::vector Z_vec; + Z_vec.reserve(vec.size()); + + for (auto &el: vec) + { + Z_vec.emplace_back(el.Z); + } + batch_invert(Z_vec); + + const alt_bn128_Fq one = alt_bn128_Fq::one(); + + for (size_t i = 0; i < vec.size(); ++i) + { + alt_bn128_Fq Z2 = Z_vec[i].squared(); + alt_bn128_Fq Z3 = Z_vec[i] * Z2; + + vec[i].X = vec[i].X * Z2; + vec[i].Y = vec[i].Y * Z3; + vec[i].Z = one; + } +} + +} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp new file mode 100644 index 000000000..da11a2e8c --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g1.hpp @@ -0,0 +1,95 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ALT_BN128_G1_HPP_ +#define ALT_BN128_G1_HPP_ +#include +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" +#include "algebra/curves/curve_utils.hpp" + +namespace libsnark { + +class alt_bn128_G1; +std::ostream& operator<<(std::ostream &, const alt_bn128_G1&); +std::istream& operator>>(std::istream &, alt_bn128_G1&); + +class alt_bn128_G1 { +public: +#ifdef PROFILE_OP_COUNTS + static long long add_cnt; + static long long dbl_cnt; +#endif + static std::vector wnaf_window_table; + static std::vector fixed_base_exp_window_table; + static alt_bn128_G1 G1_zero; + static alt_bn128_G1 G1_one; + + typedef alt_bn128_Fq base_field; + typedef alt_bn128_Fr scalar_field; + + alt_bn128_Fq X, Y, Z; + + // using Jacobian coordinates + alt_bn128_G1(); + alt_bn128_G1(const alt_bn128_Fq& X, const alt_bn128_Fq& Y, const alt_bn128_Fq& Z) : X(X), Y(Y), Z(Z) {}; + + void print() const; + void print_coordinates() const; + + void to_affine_coordinates(); + void to_special(); + bool is_special() const; + + bool is_zero() const; + + bool operator==(const alt_bn128_G1 &other) const; + bool operator!=(const alt_bn128_G1 &other) const; + + alt_bn128_G1 operator+(const alt_bn128_G1 &other) const; + alt_bn128_G1 operator-() const; + alt_bn128_G1 operator-(const alt_bn128_G1 &other) const; + + alt_bn128_G1 add(const alt_bn128_G1 &other) const; + alt_bn128_G1 mixed_add(const alt_bn128_G1 &other) const; + alt_bn128_G1 dbl() const; + + bool is_well_formed() const; + + static alt_bn128_G1 zero(); + static alt_bn128_G1 one(); + static alt_bn128_G1 random_element(); + + static size_t size_in_bits() { return base_field::size_in_bits() + 1; } + static bigint base_field_char() { return base_field::field_char(); } + static bigint order() { return scalar_field::field_char(); } + + friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G1 &g); + friend std::istream& operator>>(std::istream &in, alt_bn128_G1 &g); +}; + +template +alt_bn128_G1 operator*(const bigint &lhs, const alt_bn128_G1 &rhs) +{ + return scalar_mul(rhs, lhs); +} + +template& modulus_p> +alt_bn128_G1 operator*(const Fp_model &lhs, const alt_bn128_G1 &rhs) +{ + return scalar_mul(rhs, lhs.as_bigint()); +} + +std::ostream& operator<<(std::ostream& out, const std::vector &v); +std::istream& operator>>(std::istream& in, std::vector &v); + +template +void batch_to_special_all_non_zeros(std::vector &vec); +template<> +void batch_to_special_all_non_zeros(std::vector &vec); + +} // libsnark +#endif // ALT_BN128_G1_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp new file mode 100644 index 000000000..c4152e437 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.cpp @@ -0,0 +1,505 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" + +namespace libsnark { + +#ifdef PROFILE_OP_COUNTS +long long alt_bn128_G2::add_cnt = 0; +long long alt_bn128_G2::dbl_cnt = 0; +#endif + +std::vector alt_bn128_G2::wnaf_window_table; +std::vector alt_bn128_G2::fixed_base_exp_window_table; +alt_bn128_G2 alt_bn128_G2::G2_zero; +alt_bn128_G2 alt_bn128_G2::G2_one; + +alt_bn128_G2::alt_bn128_G2() +{ + this->X = G2_zero.X; + this->Y = G2_zero.Y; + this->Z = G2_zero.Z; +} + +alt_bn128_Fq2 alt_bn128_G2::mul_by_b(const alt_bn128_Fq2 &elt) +{ + return alt_bn128_Fq2(alt_bn128_twist_mul_by_b_c0 * elt.c0, alt_bn128_twist_mul_by_b_c1 * elt.c1); +} + +void alt_bn128_G2::print() const +{ + if (this->is_zero()) + { + printf("O\n"); + } + else + { + alt_bn128_G2 copy(*this); + copy.to_affine_coordinates(); + gmp_printf("(%Nd*z + %Nd , %Nd*z + %Nd)\n", + copy.X.c1.as_bigint().data, alt_bn128_Fq::num_limbs, + copy.X.c0.as_bigint().data, alt_bn128_Fq::num_limbs, + copy.Y.c1.as_bigint().data, alt_bn128_Fq::num_limbs, + copy.Y.c0.as_bigint().data, alt_bn128_Fq::num_limbs); + } +} + +void alt_bn128_G2::print_coordinates() const +{ + if (this->is_zero()) + { + printf("O\n"); + } + else + { + gmp_printf("(%Nd*z + %Nd : %Nd*z + %Nd : %Nd*z + %Nd)\n", + this->X.c1.as_bigint().data, alt_bn128_Fq::num_limbs, + this->X.c0.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Y.c1.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Y.c0.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Z.c1.as_bigint().data, alt_bn128_Fq::num_limbs, + this->Z.c0.as_bigint().data, alt_bn128_Fq::num_limbs); + } +} + +void alt_bn128_G2::to_affine_coordinates() +{ + if (this->is_zero()) + { + this->X = alt_bn128_Fq2::zero(); + this->Y = alt_bn128_Fq2::one(); + this->Z = alt_bn128_Fq2::zero(); + } + else + { + alt_bn128_Fq2 Z_inv = Z.inverse(); + alt_bn128_Fq2 Z2_inv = Z_inv.squared(); + alt_bn128_Fq2 Z3_inv = Z2_inv * Z_inv; + this->X = this->X * Z2_inv; + this->Y = this->Y * Z3_inv; + this->Z = alt_bn128_Fq2::one(); + } +} + +void alt_bn128_G2::to_special() +{ + this->to_affine_coordinates(); +} + +bool alt_bn128_G2::is_special() const +{ + return (this->is_zero() || this->Z == alt_bn128_Fq2::one()); +} + +bool alt_bn128_G2::is_zero() const +{ + return (this->Z.is_zero()); +} + +bool alt_bn128_G2::operator==(const alt_bn128_G2 &other) const +{ + if (this->is_zero()) + { + return other.is_zero(); + } + + if (other.is_zero()) + { + return false; + } + + /* now neither is O */ + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + alt_bn128_Fq2 Z1_squared = (this->Z).squared(); + alt_bn128_Fq2 Z2_squared = (other.Z).squared(); + + if ((this->X * Z2_squared) != (other.X * Z1_squared)) + { + return false; + } + + alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1_squared; + alt_bn128_Fq2 Z2_cubed = (other.Z) * Z2_squared; + + if ((this->Y * Z2_cubed) != (other.Y * Z1_cubed)) + { + return false; + } + + return true; +} + +bool alt_bn128_G2::operator!=(const alt_bn128_G2& other) const +{ + return !(operator==(other)); +} + +alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const +{ + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // check for doubling case + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); + alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); + + alt_bn128_Fq2 U1 = this->X * Z2Z2; + alt_bn128_Fq2 U2 = other.X * Z1Z1; + + alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1Z1; + alt_bn128_Fq2 Z2_cubed = (other.Z) * Z2Z2; + + alt_bn128_Fq2 S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 + alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + + if (U1 == U2 && S1 == S2) + { + // dbl case; nothing of above can be reused + return this->dbl(); + } + + // rest of add case + alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 + alt_bn128_Fq2 S2_minus_S1 = S2-S1; + alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2 + alt_bn128_Fq2 J = H * I; // J = H * I + alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) + alt_bn128_Fq2 V = U1 * I; // V = U1 * I + alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V + alt_bn128_Fq2 S1_J = S1 * J; + alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J + alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H + + return alt_bn128_G2(X3, Y3, Z3); +} + +alt_bn128_G2 alt_bn128_G2::operator-() const +{ + return alt_bn128_G2(this->X, -(this->Y), this->Z); +} + + +alt_bn128_G2 alt_bn128_G2::operator-(const alt_bn128_G2 &other) const +{ + return (*this) + (-other); +} + +alt_bn128_G2 alt_bn128_G2::add(const alt_bn128_G2 &other) const +{ + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // handle double case + if (this->operator==(other)) + { + return this->dbl(); + } + +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2 + + alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 + alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 + alt_bn128_Fq2 U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 + alt_bn128_Fq2 U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 + alt_bn128_Fq2 S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 + alt_bn128_Fq2 S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 + alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 + alt_bn128_Fq2 S2_minus_S1 = S2-S1; + alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2 + alt_bn128_Fq2 J = H * I; // J = H * I + alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) + alt_bn128_Fq2 V = U1 * I; // V = U1 * I + alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V + alt_bn128_Fq2 S1_J = S1 * J; + alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J + alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H + + return alt_bn128_G2(X3, Y3, Z3); +} + +alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const +{ +#ifdef DEBUG + assert(other.is_special()); +#endif + + // handle special cases having to do with O + if (this->is_zero()) + { + return other; + } + + if (other.is_zero()) + { + return *this; + } + + // no need to handle points of order 2,4 + // (they cannot exist in a prime-order subgroup) + + // check for doubling case + + // using Jacobian coordinates so: + // (X1:Y1:Z1) = (X2:Y2:Z2) + // iff + // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 + // iff + // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 + + // we know that Z2 = 1 + + const alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); + + const alt_bn128_Fq2 &U1 = this->X; + const alt_bn128_Fq2 U2 = other.X * Z1Z1; + + const alt_bn128_Fq2 Z1_cubed = (this->Z) * Z1Z1; + + const alt_bn128_Fq2 &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 + const alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + + if (U1 == U2 && S1 == S2) + { + // dbl case; nothing of above can be reused + return this->dbl(); + } + +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + alt_bn128_Fq2 H = U2-(this->X); // H = U2-X1 + alt_bn128_Fq2 HH = H.squared() ; // HH = H&2 + alt_bn128_Fq2 I = HH+HH; // I = 4*HH + I = I + I; + alt_bn128_Fq2 J = H*I; // J = H*I + alt_bn128_Fq2 r = S2-(this->Y); // r = 2*(S2-Y1) + r = r + r; + alt_bn128_Fq2 V = (this->X) * I ; // V = X1*I + alt_bn128_Fq2 X3 = r.squared()-J-V-V; // X3 = r^2-J-2*V + alt_bn128_Fq2 Y3 = (this->Y)*J; // Y3 = r*(V-X3)-2*Y1*J + Y3 = r*(V-X3) - Y3 - Y3; + alt_bn128_Fq2 Z3 = ((this->Z)+H).squared() - Z1Z1 - HH; // Z3 = (Z1+H)^2-Z1Z1-HH + + return alt_bn128_G2(X3, Y3, Z3); +} + +alt_bn128_G2 alt_bn128_G2::dbl() const +{ +#ifdef PROFILE_OP_COUNTS + this->dbl_cnt++; +#endif + // handle point at infinity + if (this->is_zero()) + { + return (*this); + } + + // NOTE: does not handle O and pts of order 2,4 + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#doubling-dbl-2007-bl + + alt_bn128_Fq2 A = (this->X).squared(); // A = X1^2 + alt_bn128_Fq2 B = (this->Y).squared(); // B = Y1^2 + alt_bn128_Fq2 C = B.squared(); // C = B^2 + alt_bn128_Fq2 D = (this->X + B).squared() - A - C; + D = D+D; // D = 2 * ((X1 + B)^2 - A - C) + alt_bn128_Fq2 E = A + A + A; // E = 3 * A + alt_bn128_Fq2 F = E.squared(); // F = E^2 + alt_bn128_Fq2 X3 = F - (D+D); // X3 = F - 2 D + alt_bn128_Fq2 eightC = C+C; + eightC = eightC + eightC; + eightC = eightC + eightC; + alt_bn128_Fq2 Y3 = E * (D - X3) - eightC; // Y3 = E * (D - X3) - 8 * C + alt_bn128_Fq2 Y1Z1 = (this->Y)*(this->Z); + alt_bn128_Fq2 Z3 = Y1Z1 + Y1Z1; // Z3 = 2 * Y1 * Z1 + + return alt_bn128_G2(X3, Y3, Z3); +} + +alt_bn128_G2 alt_bn128_G2::mul_by_q() const +{ + return alt_bn128_G2(alt_bn128_twist_mul_by_q_X * (this->X).Frobenius_map(1), + alt_bn128_twist_mul_by_q_Y * (this->Y).Frobenius_map(1), + (this->Z).Frobenius_map(1)); +} + +bool alt_bn128_G2::is_well_formed() const +{ + if (this->is_zero()) + { + return true; + } + else + { + /* + y^2 = x^3 + b + + We are using Jacobian coordinates, so equation we need to check is actually + + (y/z^3)^2 = (x/z^2)^3 + b + y^2 / z^6 = x^3 / z^6 + b + y^2 = x^3 + b z^6 + */ + alt_bn128_Fq2 X2 = this->X.squared(); + alt_bn128_Fq2 Y2 = this->Y.squared(); + alt_bn128_Fq2 Z2 = this->Z.squared(); + + alt_bn128_Fq2 X3 = this->X * X2; + alt_bn128_Fq2 Z3 = this->Z * Z2; + alt_bn128_Fq2 Z6 = Z3.squared(); + + return (Y2 == X3 + alt_bn128_twist_coeff_b * Z6); + } +} + +alt_bn128_G2 alt_bn128_G2::zero() +{ + return G2_zero; +} + +alt_bn128_G2 alt_bn128_G2::one() +{ + return G2_one; +} + +alt_bn128_G2 alt_bn128_G2::random_element() +{ + return (alt_bn128_Fr::random_element().as_bigint()) * G2_one; +} + +std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g) +{ + alt_bn128_G2 copy(g); + copy.to_affine_coordinates(); + out << (copy.is_zero() ? 1 : 0) << OUTPUT_SEPARATOR; +#ifdef NO_PT_COMPRESSION + out << copy.X << OUTPUT_SEPARATOR << copy.Y; +#else + /* storing LSB of Y */ + out << copy.X << OUTPUT_SEPARATOR << (copy.Y.c0.as_bigint().data[0] & 1); +#endif + + return out; +} + +std::istream& operator>>(std::istream &in, alt_bn128_G2 &g) +{ + char is_zero; + alt_bn128_Fq2 tX, tY; + +#ifdef NO_PT_COMPRESSION + in >> is_zero >> tX >> tY; + is_zero -= '0'; +#else + in.read((char*)&is_zero, 1); // this reads is_zero; + is_zero -= '0'; + consume_OUTPUT_SEPARATOR(in); + + unsigned char Y_lsb; + in >> tX; + consume_OUTPUT_SEPARATOR(in); + in.read((char*)&Y_lsb, 1); + Y_lsb -= '0'; + + // y = +/- sqrt(x^3 + b) + if (!is_zero) + { + alt_bn128_Fq2 tX2 = tX.squared(); + alt_bn128_Fq2 tY2 = tX2 * tX + alt_bn128_twist_coeff_b; + tY = tY2.sqrt(); + + if ((tY.c0.as_bigint().data[0] & 1) != Y_lsb) + { + tY = -tY; + } + } +#endif + // using projective coordinates + if (!is_zero) + { + g.X = tX; + g.Y = tY; + g.Z = alt_bn128_Fq2::one(); + } + else + { + g = alt_bn128_G2::zero(); + } + + return in; +} + +template<> +void batch_to_special_all_non_zeros(std::vector &vec) +{ + std::vector Z_vec; + Z_vec.reserve(vec.size()); + + for (auto &el: vec) + { + Z_vec.emplace_back(el.Z); + } + batch_invert(Z_vec); + + const alt_bn128_Fq2 one = alt_bn128_Fq2::one(); + + for (size_t i = 0; i < vec.size(); ++i) + { + alt_bn128_Fq2 Z2 = Z_vec[i].squared(); + alt_bn128_Fq2 Z3 = Z_vec[i] * Z2; + + vec[i].X = vec[i].X * Z2; + vec[i].Y = vec[i].Y * Z3; + vec[i].Z = one; + } +} + +} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp new file mode 100644 index 000000000..a996a2d1a --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_g2.hpp @@ -0,0 +1,96 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ALT_BN128_G2_HPP_ +#define ALT_BN128_G2_HPP_ +#include +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" +#include "algebra/curves/curve_utils.hpp" + +namespace libsnark { + +class alt_bn128_G2; +std::ostream& operator<<(std::ostream &, const alt_bn128_G2&); +std::istream& operator>>(std::istream &, alt_bn128_G2&); + +class alt_bn128_G2 { +public: +#ifdef PROFILE_OP_COUNTS + static long long add_cnt; + static long long dbl_cnt; +#endif + static std::vector wnaf_window_table; + static std::vector fixed_base_exp_window_table; + static alt_bn128_G2 G2_zero; + static alt_bn128_G2 G2_one; + + typedef alt_bn128_Fq base_field; + typedef alt_bn128_Fq2 twist_field; + typedef alt_bn128_Fr scalar_field; + + alt_bn128_Fq2 X, Y, Z; + + // using Jacobian coordinates + alt_bn128_G2(); + alt_bn128_G2(const alt_bn128_Fq2& X, const alt_bn128_Fq2& Y, const alt_bn128_Fq2& Z) : X(X), Y(Y), Z(Z) {}; + + static alt_bn128_Fq2 mul_by_b(const alt_bn128_Fq2 &elt); + + void print() const; + void print_coordinates() const; + + void to_affine_coordinates(); + void to_special(); + bool is_special() const; + + bool is_zero() const; + + bool operator==(const alt_bn128_G2 &other) const; + bool operator!=(const alt_bn128_G2 &other) const; + + alt_bn128_G2 operator+(const alt_bn128_G2 &other) const; + alt_bn128_G2 operator-() const; + alt_bn128_G2 operator-(const alt_bn128_G2 &other) const; + + alt_bn128_G2 add(const alt_bn128_G2 &other) const; + alt_bn128_G2 mixed_add(const alt_bn128_G2 &other) const; + alt_bn128_G2 dbl() const; + alt_bn128_G2 mul_by_q() const; + + bool is_well_formed() const; + + static alt_bn128_G2 zero(); + static alt_bn128_G2 one(); + static alt_bn128_G2 random_element(); + + static size_t size_in_bits() { return twist_field::size_in_bits() + 1; } + static bigint base_field_char() { return base_field::field_char(); } + static bigint order() { return scalar_field::field_char(); } + + friend std::ostream& operator<<(std::ostream &out, const alt_bn128_G2 &g); + friend std::istream& operator>>(std::istream &in, alt_bn128_G2 &g); +}; + +template +alt_bn128_G2 operator*(const bigint &lhs, const alt_bn128_G2 &rhs) +{ + return scalar_mul(rhs, lhs); +} + +template& modulus_p> +alt_bn128_G2 operator*(const Fp_model &lhs, const alt_bn128_G2 &rhs) +{ + return scalar_mul(rhs, lhs.as_bigint()); +} + +template +void batch_to_special_all_non_zeros(std::vector &vec); +template<> +void batch_to_special_all_non_zeros(std::vector &vec); + +} // libsnark +#endif // ALT_BN128_G2_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp new file mode 100644 index 000000000..7c23773d6 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.cpp @@ -0,0 +1,273 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" + +namespace libsnark { + +bigint alt_bn128_modulus_r; +bigint alt_bn128_modulus_q; + +alt_bn128_Fq alt_bn128_coeff_b; +alt_bn128_Fq2 alt_bn128_twist; +alt_bn128_Fq2 alt_bn128_twist_coeff_b; +alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; +alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; +alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X; +alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y; + +bigint alt_bn128_ate_loop_count; +bool alt_bn128_ate_is_loop_count_neg; +bigint<12*alt_bn128_q_limbs> alt_bn128_final_exponent; +bigint alt_bn128_final_exponent_z; +bool alt_bn128_final_exponent_is_z_neg; + +void init_alt_bn128_params() +{ + typedef bigint bigint_r; + typedef bigint bigint_q; + + assert(sizeof(mp_limb_t) == 8 || sizeof(mp_limb_t) == 4); // Montgomery assumes this + + /* parameters for scalar field Fr */ + + alt_bn128_modulus_r = bigint_r("21888242871839275222246405745257275088548364400416034343698204186575808495617"); + assert(alt_bn128_Fr::modulus_is_valid()); + if (sizeof(mp_limb_t) == 8) + { + alt_bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); + alt_bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); + alt_bn128_Fr::inv = 0xc2e1f593efffffff; + } + if (sizeof(mp_limb_t) == 4) + { + alt_bn128_Fr::Rsquared = bigint_r("944936681149208446651664254269745548490766851729442924617792859073125903783"); + alt_bn128_Fr::Rcubed = bigint_r("5866548545943845227489894872040244720403868105578784105281690076696998248512"); + alt_bn128_Fr::inv = 0xefffffff; + } + alt_bn128_Fr::num_bits = 254; + alt_bn128_Fr::euler = bigint_r("10944121435919637611123202872628637544274182200208017171849102093287904247808"); + alt_bn128_Fr::s = 28; + alt_bn128_Fr::t = bigint_r("81540058820840996586704275553141814055101440848469862132140264610111"); + alt_bn128_Fr::t_minus_1_over_2 = bigint_r("40770029410420498293352137776570907027550720424234931066070132305055"); + alt_bn128_Fr::multiplicative_generator = alt_bn128_Fr("5"); + alt_bn128_Fr::root_of_unity = alt_bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); + alt_bn128_Fr::nqr = alt_bn128_Fr("5"); + alt_bn128_Fr::nqr_to_t = alt_bn128_Fr("19103219067921713944291392827692070036145651957329286315305642004821462161904"); + + /* parameters for base field Fq */ + + alt_bn128_modulus_q = bigint_q("21888242871839275222246405745257275088696311157297823662689037894645226208583"); + assert(alt_bn128_Fq::modulus_is_valid()); + if (sizeof(mp_limb_t) == 8) + { + alt_bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); + alt_bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); + alt_bn128_Fq::inv = 0x87d20782e4866389; + } + if (sizeof(mp_limb_t) == 4) + { + alt_bn128_Fq::Rsquared = bigint_q("3096616502983703923843567936837374451735540968419076528771170197431451843209"); + alt_bn128_Fq::Rcubed = bigint_q("14921786541159648185948152738563080959093619838510245177710943249661917737183"); + alt_bn128_Fq::inv = 0xe4866389; + } + alt_bn128_Fq::num_bits = 254; + alt_bn128_Fq::euler = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); + alt_bn128_Fq::s = 1; + alt_bn128_Fq::t = bigint_q("10944121435919637611123202872628637544348155578648911831344518947322613104291"); + alt_bn128_Fq::t_minus_1_over_2 = bigint_q("5472060717959818805561601436314318772174077789324455915672259473661306552145"); + alt_bn128_Fq::multiplicative_generator = alt_bn128_Fq("3"); + alt_bn128_Fq::root_of_unity = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); + alt_bn128_Fq::nqr = alt_bn128_Fq("3"); + alt_bn128_Fq::nqr_to_t = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); + + /* parameters for twist field Fq2 */ + alt_bn128_Fq2::euler = bigint<2*alt_bn128_q_limbs>("239547588008311421220994022608339370399626158265550411218223901127035046843189118723920525909718935985594116157406550130918127817069793474323196511433944"); + alt_bn128_Fq2::s = 4; + alt_bn128_Fq2::t = bigint<2*alt_bn128_q_limbs>("29943448501038927652624252826042421299953269783193801402277987640879380855398639840490065738714866998199264519675818766364765977133724184290399563929243"); + alt_bn128_Fq2::t_minus_1_over_2 = bigint<2*alt_bn128_q_limbs>("14971724250519463826312126413021210649976634891596900701138993820439690427699319920245032869357433499099632259837909383182382988566862092145199781964621"); + alt_bn128_Fq2::non_residue = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); + alt_bn128_Fq2::nqr = alt_bn128_Fq2(alt_bn128_Fq("2"),alt_bn128_Fq("1")); + alt_bn128_Fq2::nqr_to_t = alt_bn128_Fq2(alt_bn128_Fq("5033503716262624267312492558379982687175200734934877598599011485707452665730"),alt_bn128_Fq("314498342015008975724433667930697407966947188435857772134235984660852259084")); + alt_bn128_Fq2::Frobenius_coeffs_c1[0] = alt_bn128_Fq("1"); + alt_bn128_Fq2::Frobenius_coeffs_c1[1] = alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"); + + /* parameters for Fq6 */ + alt_bn128_Fq6::non_residue = alt_bn128_Fq2(alt_bn128_Fq("9"),alt_bn128_Fq("1")); + alt_bn128_Fq6::Frobenius_coeffs_c1[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c1[1] = alt_bn128_Fq2(alt_bn128_Fq("21575463638280843010398324269430826099269044274347216827212613867836435027261"),alt_bn128_Fq("10307601595873709700152284273816112264069230130616436755625194854815875713954")); + alt_bn128_Fq6::Frobenius_coeffs_c1[2] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c1[3] = alt_bn128_Fq2(alt_bn128_Fq("3772000881919853776433695186713858239009073593817195771773381919316419345261"),alt_bn128_Fq("2236595495967245188281701248203181795121068902605861227855261137820944008926")); + alt_bn128_Fq6::Frobenius_coeffs_c1[4] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c1[5] = alt_bn128_Fq2(alt_bn128_Fq("18429021223477853657660792034369865839114504446431234726392080002137598044644"),alt_bn128_Fq("9344045779998320333812420223237981029506012124075525679208581902008406485703")); + alt_bn128_Fq6::Frobenius_coeffs_c2[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c2[1] = alt_bn128_Fq2(alt_bn128_Fq("2581911344467009335267311115468803099551665605076196740867805258568234346338"),alt_bn128_Fq("19937756971775647987995932169929341994314640652964949448313374472400716661030")); + alt_bn128_Fq6::Frobenius_coeffs_c2[2] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c2[3] = alt_bn128_Fq2(alt_bn128_Fq("5324479202449903542726783395506214481928257762400643279780343368557297135718"),alt_bn128_Fq("16208900380737693084919495127334387981393726419856888799917914180988844123039")); + alt_bn128_Fq6::Frobenius_coeffs_c2[4] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); + alt_bn128_Fq6::Frobenius_coeffs_c2[5] = alt_bn128_Fq2(alt_bn128_Fq("13981852324922362344252311234282257507216387789820983642040889267519694726527"),alt_bn128_Fq("7629828391165209371577384193250820201684255241773809077146787135900891633097")); + + /* parameters for Fq12 */ + + alt_bn128_Fq12::non_residue = alt_bn128_Fq2(alt_bn128_Fq("9"),alt_bn128_Fq("1")); + alt_bn128_Fq12::Frobenius_coeffs_c1[0] = alt_bn128_Fq2(alt_bn128_Fq("1"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[1] = alt_bn128_Fq2(alt_bn128_Fq("8376118865763821496583973867626364092589906065868298776909617916018768340080"),alt_bn128_Fq("16469823323077808223889137241176536799009286646108169935659301613961712198316")); + alt_bn128_Fq12::Frobenius_coeffs_c1[2] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556617"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[3] = alt_bn128_Fq2(alt_bn128_Fq("11697423496358154304825782922584725312912383441159505038794027105778954184319"),alt_bn128_Fq("303847389135065887422783454877609941456349188919719272345083954437860409601")); + alt_bn128_Fq12::Frobenius_coeffs_c1[4] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275220042445260109153167277707414472061641714758635765020556616"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[5] = alt_bn128_Fq2(alt_bn128_Fq("3321304630594332808241809054958361220322477375291206261884409189760185844239"),alt_bn128_Fq("5722266937896532885780051958958348231143373700109372999374820235121374419868")); + alt_bn128_Fq12::Frobenius_coeffs_c1[6] = alt_bn128_Fq2(alt_bn128_Fq("21888242871839275222246405745257275088696311157297823662689037894645226208582"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[7] = alt_bn128_Fq2(alt_bn128_Fq("13512124006075453725662431877630910996106405091429524885779419978626457868503"),alt_bn128_Fq("5418419548761466998357268504080738289687024511189653727029736280683514010267")); + alt_bn128_Fq12::Frobenius_coeffs_c1[8] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651966"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[9] = alt_bn128_Fq2(alt_bn128_Fq("10190819375481120917420622822672549775783927716138318623895010788866272024264"),alt_bn128_Fq("21584395482704209334823622290379665147239961968378104390343953940207365798982")); + alt_bn128_Fq12::Frobenius_coeffs_c1[10] = alt_bn128_Fq2(alt_bn128_Fq("2203960485148121921418603742825762020974279258880205651967"),alt_bn128_Fq("0")); + alt_bn128_Fq12::Frobenius_coeffs_c1[11] = alt_bn128_Fq2(alt_bn128_Fq("18566938241244942414004596690298913868373833782006617400804628704885040364344"),alt_bn128_Fq("16165975933942742336466353786298926857552937457188450663314217659523851788715")); + + /* choice of short Weierstrass curve and its twist */ + + alt_bn128_coeff_b = alt_bn128_Fq("3"); + alt_bn128_twist = alt_bn128_Fq2(alt_bn128_Fq("9"), alt_bn128_Fq("1")); + alt_bn128_twist_coeff_b = alt_bn128_coeff_b * alt_bn128_twist.inverse(); + alt_bn128_twist_mul_by_b_c0 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue; + alt_bn128_twist_mul_by_b_c1 = alt_bn128_coeff_b * alt_bn128_Fq2::non_residue; + alt_bn128_twist_mul_by_q_X = alt_bn128_Fq2(alt_bn128_Fq("21575463638280843010398324269430826099269044274347216827212613867836435027261"), + alt_bn128_Fq("10307601595873709700152284273816112264069230130616436755625194854815875713954")); + alt_bn128_twist_mul_by_q_Y = alt_bn128_Fq2(alt_bn128_Fq("2821565182194536844548159561693502659359617185244120367078079554186484126554"), + alt_bn128_Fq("3505843767911556378687030309984248845540243509899259641013678093033130930403")); + + /* choice of group G1 */ + alt_bn128_G1::G1_zero = alt_bn128_G1(alt_bn128_Fq::zero(), + alt_bn128_Fq::one(), + alt_bn128_Fq::zero()); + alt_bn128_G1::G1_one = alt_bn128_G1(alt_bn128_Fq("1"), + alt_bn128_Fq("2"), + alt_bn128_Fq::one()); + alt_bn128_G1::wnaf_window_table.push_back(11); + alt_bn128_G1::wnaf_window_table.push_back(24); + alt_bn128_G1::wnaf_window_table.push_back(60); + alt_bn128_G1::wnaf_window_table.push_back(127); + + alt_bn128_G1::fixed_base_exp_window_table.resize(0); + // window 1 is unbeaten in [-inf, 4.99] + alt_bn128_G1::fixed_base_exp_window_table.push_back(1); + // window 2 is unbeaten in [4.99, 10.99] + alt_bn128_G1::fixed_base_exp_window_table.push_back(5); + // window 3 is unbeaten in [10.99, 32.29] + alt_bn128_G1::fixed_base_exp_window_table.push_back(11); + // window 4 is unbeaten in [32.29, 55.23] + alt_bn128_G1::fixed_base_exp_window_table.push_back(32); + // window 5 is unbeaten in [55.23, 162.03] + alt_bn128_G1::fixed_base_exp_window_table.push_back(55); + // window 6 is unbeaten in [162.03, 360.15] + alt_bn128_G1::fixed_base_exp_window_table.push_back(162); + // window 7 is unbeaten in [360.15, 815.44] + alt_bn128_G1::fixed_base_exp_window_table.push_back(360); + // window 8 is unbeaten in [815.44, 2373.07] + alt_bn128_G1::fixed_base_exp_window_table.push_back(815); + // window 9 is unbeaten in [2373.07, 6977.75] + alt_bn128_G1::fixed_base_exp_window_table.push_back(2373); + // window 10 is unbeaten in [6977.75, 7122.23] + alt_bn128_G1::fixed_base_exp_window_table.push_back(6978); + // window 11 is unbeaten in [7122.23, 57818.46] + alt_bn128_G1::fixed_base_exp_window_table.push_back(7122); + // window 12 is never the best + alt_bn128_G1::fixed_base_exp_window_table.push_back(0); + // window 13 is unbeaten in [57818.46, 169679.14] + alt_bn128_G1::fixed_base_exp_window_table.push_back(57818); + // window 14 is never the best + alt_bn128_G1::fixed_base_exp_window_table.push_back(0); + // window 15 is unbeaten in [169679.14, 439758.91] + alt_bn128_G1::fixed_base_exp_window_table.push_back(169679); + // window 16 is unbeaten in [439758.91, 936073.41] + alt_bn128_G1::fixed_base_exp_window_table.push_back(439759); + // window 17 is unbeaten in [936073.41, 4666554.74] + alt_bn128_G1::fixed_base_exp_window_table.push_back(936073); + // window 18 is never the best + alt_bn128_G1::fixed_base_exp_window_table.push_back(0); + // window 19 is unbeaten in [4666554.74, 7580404.42] + alt_bn128_G1::fixed_base_exp_window_table.push_back(4666555); + // window 20 is unbeaten in [7580404.42, 34552892.20] + alt_bn128_G1::fixed_base_exp_window_table.push_back(7580404); + // window 21 is never the best + alt_bn128_G1::fixed_base_exp_window_table.push_back(0); + // window 22 is unbeaten in [34552892.20, inf] + alt_bn128_G1::fixed_base_exp_window_table.push_back(34552892); + + /* choice of group G2 */ + + alt_bn128_G2::G2_zero = alt_bn128_G2(alt_bn128_Fq2::zero(), + alt_bn128_Fq2::one(), + alt_bn128_Fq2::zero()); + + alt_bn128_G2::G2_one = alt_bn128_G2(alt_bn128_Fq2(alt_bn128_Fq("10857046999023057135944570762232829481370756359578518086990519993285655852781"), + alt_bn128_Fq("11559732032986387107991004021392285783925812861821192530917403151452391805634")), + alt_bn128_Fq2(alt_bn128_Fq("8495653923123431417604973247489272438418190587263600148770280649306958101930"), + alt_bn128_Fq("4082367875863433681332203403145435568316851327593401208105741076214120093531")), + alt_bn128_Fq2::one()); + alt_bn128_G2::wnaf_window_table.push_back(5); + alt_bn128_G2::wnaf_window_table.push_back(15); + alt_bn128_G2::wnaf_window_table.push_back(39); + alt_bn128_G2::wnaf_window_table.push_back(109); + + alt_bn128_G2::fixed_base_exp_window_table.resize(0); + // window 1 is unbeaten in [-inf, 5.10] + alt_bn128_G2::fixed_base_exp_window_table.push_back(1); + // window 2 is unbeaten in [5.10, 10.43] + alt_bn128_G2::fixed_base_exp_window_table.push_back(5); + // window 3 is unbeaten in [10.43, 25.28] + alt_bn128_G2::fixed_base_exp_window_table.push_back(10); + // window 4 is unbeaten in [25.28, 59.00] + alt_bn128_G2::fixed_base_exp_window_table.push_back(25); + // window 5 is unbeaten in [59.00, 154.03] + alt_bn128_G2::fixed_base_exp_window_table.push_back(59); + // window 6 is unbeaten in [154.03, 334.25] + alt_bn128_G2::fixed_base_exp_window_table.push_back(154); + // window 7 is unbeaten in [334.25, 742.58] + alt_bn128_G2::fixed_base_exp_window_table.push_back(334); + // window 8 is unbeaten in [742.58, 2034.40] + alt_bn128_G2::fixed_base_exp_window_table.push_back(743); + // window 9 is unbeaten in [2034.40, 4987.56] + alt_bn128_G2::fixed_base_exp_window_table.push_back(2034); + // window 10 is unbeaten in [4987.56, 8888.27] + alt_bn128_G2::fixed_base_exp_window_table.push_back(4988); + // window 11 is unbeaten in [8888.27, 26271.13] + alt_bn128_G2::fixed_base_exp_window_table.push_back(8888); + // window 12 is unbeaten in [26271.13, 39768.20] + alt_bn128_G2::fixed_base_exp_window_table.push_back(26271); + // window 13 is unbeaten in [39768.20, 106275.75] + alt_bn128_G2::fixed_base_exp_window_table.push_back(39768); + // window 14 is unbeaten in [106275.75, 141703.40] + alt_bn128_G2::fixed_base_exp_window_table.push_back(106276); + // window 15 is unbeaten in [141703.40, 462422.97] + alt_bn128_G2::fixed_base_exp_window_table.push_back(141703); + // window 16 is unbeaten in [462422.97, 926871.84] + alt_bn128_G2::fixed_base_exp_window_table.push_back(462423); + // window 17 is unbeaten in [926871.84, 4873049.17] + alt_bn128_G2::fixed_base_exp_window_table.push_back(926872); + // window 18 is never the best + alt_bn128_G2::fixed_base_exp_window_table.push_back(0); + // window 19 is unbeaten in [4873049.17, 5706707.88] + alt_bn128_G2::fixed_base_exp_window_table.push_back(4873049); + // window 20 is unbeaten in [5706707.88, 31673814.95] + alt_bn128_G2::fixed_base_exp_window_table.push_back(5706708); + // window 21 is never the best + alt_bn128_G2::fixed_base_exp_window_table.push_back(0); + // window 22 is unbeaten in [31673814.95, inf] + alt_bn128_G2::fixed_base_exp_window_table.push_back(31673815); + + /* pairing parameters */ + + alt_bn128_ate_loop_count = bigint_q("29793968203157093288"); + alt_bn128_ate_is_loop_count_neg = false; + alt_bn128_final_exponent = bigint<12*alt_bn128_q_limbs>("552484233613224096312617126783173147097382103762957654188882734314196910839907541213974502761540629817009608548654680343627701153829446747810907373256841551006201639677726139946029199968412598804882391702273019083653272047566316584365559776493027495458238373902875937659943504873220554161550525926302303331747463515644711876653177129578303191095900909191624817826566688241804408081892785725967931714097716709526092261278071952560171111444072049229123565057483750161460024353346284167282452756217662335528813519139808291170539072125381230815729071544861602750936964829313608137325426383735122175229541155376346436093930287402089517426973178917569713384748081827255472576937471496195752727188261435633271238710131736096299798168852925540549342330775279877006784354801422249722573783561685179618816480037695005515426162362431072245638324744480"); + alt_bn128_final_exponent_z = bigint_q("4965661367192848881"); + alt_bn128_final_exponent_is_z_neg = false; + +} +} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp new file mode 100644 index 000000000..c3bea7673 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_init.hpp @@ -0,0 +1,57 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ALT_BN128_INIT_HPP_ +#define ALT_BN128_INIT_HPP_ +#include "algebra/curves/public_params.hpp" +#include "algebra/fields/fp.hpp" +#include "algebra/fields/fp2.hpp" +#include "algebra/fields/fp6_3over2.hpp" +#include "algebra/fields/fp12_2over3over2.hpp" + +namespace libsnark { + +const mp_size_t alt_bn128_r_bitcount = 254; +const mp_size_t alt_bn128_q_bitcount = 254; + +const mp_size_t alt_bn128_r_limbs = (alt_bn128_r_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; +const mp_size_t alt_bn128_q_limbs = (alt_bn128_q_bitcount+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; + +extern bigint alt_bn128_modulus_r; +extern bigint alt_bn128_modulus_q; + +typedef Fp_model alt_bn128_Fr; +typedef Fp_model alt_bn128_Fq; +typedef Fp2_model alt_bn128_Fq2; +typedef Fp6_3over2_model alt_bn128_Fq6; +typedef Fp12_2over3over2_model alt_bn128_Fq12; +typedef alt_bn128_Fq12 alt_bn128_GT; + +// parameters for Barreto--Naehrig curve E/Fq : y^2 = x^3 + b +extern alt_bn128_Fq alt_bn128_coeff_b; +// parameters for twisted Barreto--Naehrig curve E'/Fq2 : y^2 = x^3 + b/xi +extern alt_bn128_Fq2 alt_bn128_twist; +extern alt_bn128_Fq2 alt_bn128_twist_coeff_b; +extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c0; +extern alt_bn128_Fq alt_bn128_twist_mul_by_b_c1; +extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_X; +extern alt_bn128_Fq2 alt_bn128_twist_mul_by_q_Y; + +// parameters for pairing +extern bigint alt_bn128_ate_loop_count; +extern bool alt_bn128_ate_is_loop_count_neg; +extern bigint<12*alt_bn128_q_limbs> alt_bn128_final_exponent; +extern bigint alt_bn128_final_exponent_z; +extern bool alt_bn128_final_exponent_is_z_neg; + +void init_alt_bn128_params(); + +class alt_bn128_G1; +class alt_bn128_G2; + +} // libsnark +#endif // ALT_BN128_INIT_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp new file mode 100644 index 000000000..db556c5b2 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.cpp @@ -0,0 +1,547 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" +#include +#include "common/profiling.hpp" +#include "common/assert_except.hpp" + +namespace libsnark { + +bool alt_bn128_ate_G1_precomp::operator==(const alt_bn128_ate_G1_precomp &other) const +{ + return (this->PX == other.PX && + this->PY == other.PY); +} + +std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P) +{ + out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY; + + return out; +} + +std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P) +{ + in >> prec_P.PX; + consume_OUTPUT_SEPARATOR(in); + in >> prec_P.PY; + + return in; +} + +bool alt_bn128_ate_ell_coeffs::operator==(const alt_bn128_ate_ell_coeffs &other) const +{ + return (this->ell_0 == other.ell_0 && + this->ell_VW == other.ell_VW && + this->ell_VV == other.ell_VV); +} + +std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &c) +{ + out << c.ell_0 << OUTPUT_SEPARATOR << c.ell_VW << OUTPUT_SEPARATOR << c.ell_VV; + return out; +} + +std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &c) +{ + in >> c.ell_0; + consume_OUTPUT_SEPARATOR(in); + in >> c.ell_VW; + consume_OUTPUT_SEPARATOR(in); + in >> c.ell_VV; + + return in; +} + +bool alt_bn128_ate_G2_precomp::operator==(const alt_bn128_ate_G2_precomp &other) const +{ + return (this->QX == other.QX && + this->QY == other.QY && + this->coeffs == other.coeffs); +} + +std::ostream& operator<<(std::ostream& out, const alt_bn128_ate_G2_precomp &prec_Q) +{ + out << prec_Q.QX << OUTPUT_SEPARATOR << prec_Q.QY << "\n"; + out << prec_Q.coeffs.size() << "\n"; + for (const alt_bn128_ate_ell_coeffs &c : prec_Q.coeffs) + { + out << c << OUTPUT_NEWLINE; + } + return out; +} + +std::istream& operator>>(std::istream& in, alt_bn128_ate_G2_precomp &prec_Q) +{ + in >> prec_Q.QX; + consume_OUTPUT_SEPARATOR(in); + in >> prec_Q.QY; + consume_newline(in); + + prec_Q.coeffs.clear(); + size_t s; + in >> s; + + consume_newline(in); + + prec_Q.coeffs.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + alt_bn128_ate_ell_coeffs c; + in >> c; + consume_OUTPUT_NEWLINE(in); + prec_Q.coeffs.emplace_back(c); + } + + return in; +} + +/* final exponentiations */ + +alt_bn128_Fq12 alt_bn128_final_exponentiation_first_chunk(const alt_bn128_Fq12 &elt) +{ + enter_block("Call to alt_bn128_final_exponentiation_first_chunk"); + + /* + Computes result = elt^((q^6-1)*(q^2+1)). + Follows, e.g., Beuchat et al page 9, by computing result as follows: + elt^((q^6-1)*(q^2+1)) = (conj(elt) * elt^(-1))^(q^2+1) + More precisely: + A = conj(elt) + B = elt.inverse() + C = A * B + D = C.Frobenius_map(2) + result = D * C + */ + + const alt_bn128_Fq12 A = alt_bn128_Fq12(elt.c0,-elt.c1); + const alt_bn128_Fq12 B = elt.inverse(); + const alt_bn128_Fq12 C = A * B; + const alt_bn128_Fq12 D = C.Frobenius_map(2); + const alt_bn128_Fq12 result = D * C; + + leave_block("Call to alt_bn128_final_exponentiation_first_chunk"); + + return result; +} + +alt_bn128_Fq12 alt_bn128_exp_by_neg_z(const alt_bn128_Fq12 &elt) +{ + enter_block("Call to alt_bn128_exp_by_neg_z"); + + alt_bn128_Fq12 result = elt.cyclotomic_exp(alt_bn128_final_exponent_z); + if (!alt_bn128_final_exponent_is_z_neg) + { + result = result.unitary_inverse(); + } + + leave_block("Call to alt_bn128_exp_by_neg_z"); + + return result; +} + +alt_bn128_Fq12 alt_bn128_final_exponentiation_last_chunk(const alt_bn128_Fq12 &elt) +{ + enter_block("Call to alt_bn128_final_exponentiation_last_chunk"); + + /* + Follows Laura Fuentes-Castaneda et al. "Faster hashing to G2" + by computing: + + result = elt^(q^3 * (12*z^3 + 6z^2 + 4z - 1) + + q^2 * (12*z^3 + 6z^2 + 6z) + + q * (12*z^3 + 6z^2 + 4z) + + 1 * (12*z^3 + 12z^2 + 6z + 1)) + which equals + + result = elt^( 2z * ( 6z^2 + 3z + 1 ) * (q^4 - q^2 + 1)/r ). + + Using the following addition chain: + + A = exp_by_neg_z(elt) // = elt^(-z) + B = A^2 // = elt^(-2*z) + C = B^2 // = elt^(-4*z) + D = C * B // = elt^(-6*z) + E = exp_by_neg_z(D) // = elt^(6*z^2) + F = E^2 // = elt^(12*z^2) + G = epx_by_neg_z(F) // = elt^(-12*z^3) + H = conj(D) // = elt^(6*z) + I = conj(G) // = elt^(12*z^3) + J = I * E // = elt^(12*z^3 + 6*z^2) + K = J * H // = elt^(12*z^3 + 6*z^2 + 6*z) + L = K * B // = elt^(12*z^3 + 6*z^2 + 4*z) + M = K * E // = elt^(12*z^3 + 12*z^2 + 6*z) + N = M * elt // = elt^(12*z^3 + 12*z^2 + 6*z + 1) + O = L.Frobenius_map(1) // = elt^(q*(12*z^3 + 6*z^2 + 4*z)) + P = O * N // = elt^(q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) + Q = K.Frobenius_map(2) // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z)) + R = Q * P // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) + S = conj(elt) // = elt^(-1) + T = S * L // = elt^(12*z^3 + 6*z^2 + 4*z - 1) + U = T.Frobenius_map(3) // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1)) + V = U * R // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1) + q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1)) + result = V + + */ + + const alt_bn128_Fq12 A = alt_bn128_exp_by_neg_z(elt); + const alt_bn128_Fq12 B = A.cyclotomic_squared(); + const alt_bn128_Fq12 C = B.cyclotomic_squared(); + const alt_bn128_Fq12 D = C * B; + const alt_bn128_Fq12 E = alt_bn128_exp_by_neg_z(D); + const alt_bn128_Fq12 F = E.cyclotomic_squared(); + const alt_bn128_Fq12 G = alt_bn128_exp_by_neg_z(F); + const alt_bn128_Fq12 H = D.unitary_inverse(); + const alt_bn128_Fq12 I = G.unitary_inverse(); + const alt_bn128_Fq12 J = I * E; + const alt_bn128_Fq12 K = J * H; + const alt_bn128_Fq12 L = K * B; + const alt_bn128_Fq12 M = K * E; + const alt_bn128_Fq12 N = M * elt; + const alt_bn128_Fq12 O = L.Frobenius_map(1); + const alt_bn128_Fq12 P = O * N; + const alt_bn128_Fq12 Q = K.Frobenius_map(2); + const alt_bn128_Fq12 R = Q * P; + const alt_bn128_Fq12 S = elt.unitary_inverse(); + const alt_bn128_Fq12 T = S * L; + const alt_bn128_Fq12 U = T.Frobenius_map(3); + const alt_bn128_Fq12 V = U * R; + + const alt_bn128_Fq12 result = V; + + leave_block("Call to alt_bn128_final_exponentiation_last_chunk"); + + return result; +} + +alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt) +{ + enter_block("Call to alt_bn128_final_exponentiation"); + /* OLD naive version: + alt_bn128_GT result = elt^alt_bn128_final_exponent; + */ + alt_bn128_Fq12 A = alt_bn128_final_exponentiation_first_chunk(elt); + alt_bn128_GT result = alt_bn128_final_exponentiation_last_chunk(A); + + leave_block("Call to alt_bn128_final_exponentiation"); + return result; +} + +/* ate pairing */ + +void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv, + alt_bn128_G2 ¤t, + alt_bn128_ate_ell_coeffs &c) +{ + const alt_bn128_Fq2 X = current.X, Y = current.Y, Z = current.Z; + + const alt_bn128_Fq2 A = two_inv * (X * Y); // A = X1 * Y1 / 2 + const alt_bn128_Fq2 B = Y.squared(); // B = Y1^2 + const alt_bn128_Fq2 C = Z.squared(); // C = Z1^2 + const alt_bn128_Fq2 D = C+C+C; // D = 3 * C + const alt_bn128_Fq2 E = alt_bn128_twist_coeff_b * D; // E = twist_b * D + const alt_bn128_Fq2 F = E+E+E; // F = 3 * E + const alt_bn128_Fq2 G = two_inv * (B+F); // G = (B+F)/2 + const alt_bn128_Fq2 H = (Y+Z).squared() - (B+C); // H = (Y1+Z1)^2-(B+C) + const alt_bn128_Fq2 I = E-B; // I = E-B + const alt_bn128_Fq2 J = X.squared(); // J = X1^2 + const alt_bn128_Fq2 E_squared = E.squared(); // E_squared = E^2 + + current.X = A * (B-F); // X3 = A * (B-F) + current.Y = G.squared() - (E_squared+E_squared+E_squared); // Y3 = G^2 - 3*E^2 + current.Z = B * H; // Z3 = B * H + c.ell_0 = alt_bn128_twist * I; // ell_0 = xi * I + c.ell_VW = -H; // ell_VW = - H (later: * yP) + c.ell_VV = J+J+J; // ell_VV = 3*J (later: * xP) +} + +void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base, + alt_bn128_G2 ¤t, + alt_bn128_ate_ell_coeffs &c) +{ + const alt_bn128_Fq2 X1 = current.X, Y1 = current.Y, Z1 = current.Z; + const alt_bn128_Fq2 &x2 = base.X, &y2 = base.Y; + + const alt_bn128_Fq2 D = X1 - x2 * Z1; // D = X1 - X2*Z1 + const alt_bn128_Fq2 E = Y1 - y2 * Z1; // E = Y1 - Y2*Z1 + const alt_bn128_Fq2 F = D.squared(); // F = D^2 + const alt_bn128_Fq2 G = E.squared(); // G = E^2 + const alt_bn128_Fq2 H = D*F; // H = D*F + const alt_bn128_Fq2 I = X1 * F; // I = X1 * F + const alt_bn128_Fq2 J = H + Z1*G - (I+I); // J = H + Z1*G - (I+I) + + current.X = D * J; // X3 = D*J + current.Y = E * (I-J)-(H * Y1); // Y3 = E*(I-J)-(H*Y1) + current.Z = Z1 * H; // Z3 = Z1*H + c.ell_0 = alt_bn128_twist * (E * x2 - D * y2); // ell_0 = xi * (E * X2 - D * Y2) + c.ell_VV = - E; // ell_VV = - E (later: * xP) + c.ell_VW = D; // ell_VW = D (later: * yP ) +} + +alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P) +{ + enter_block("Call to alt_bn128_ate_precompute_G1"); + + alt_bn128_G1 Pcopy = P; + Pcopy.to_affine_coordinates(); + + alt_bn128_ate_G1_precomp result; + result.PX = Pcopy.X; + result.PY = Pcopy.Y; + + leave_block("Call to alt_bn128_ate_precompute_G1"); + return result; +} + +alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q) +{ + enter_block("Call to alt_bn128_ate_precompute_G2"); + + alt_bn128_G2 Qcopy(Q); + Qcopy.to_affine_coordinates(); + + alt_bn128_Fq two_inv = (alt_bn128_Fq("2").inverse()); // could add to global params if needed + + alt_bn128_ate_G2_precomp result; + result.QX = Qcopy.X; + result.QY = Qcopy.Y; + + alt_bn128_G2 R; + R.X = Qcopy.X; + R.Y = Qcopy.Y; + R.Z = alt_bn128_Fq2::one(); + + const bigint &loop_count = alt_bn128_ate_loop_count; + bool found_one = false; + alt_bn128_ate_ell_coeffs c; + + for (long i = loop_count.max_bits(); i >= 0; --i) + { + const bool bit = loop_count.test_bit(i); + if (!found_one) + { + /* this skips the MSB itself */ + found_one |= bit; + continue; + } + + doubling_step_for_flipped_miller_loop(two_inv, R, c); + result.coeffs.push_back(c); + + if (bit) + { + mixed_addition_step_for_flipped_miller_loop(Qcopy, R, c); + result.coeffs.push_back(c); + } + } + + alt_bn128_G2 Q1 = Qcopy.mul_by_q(); + assert_except(Q1.Z == alt_bn128_Fq2::one()); + alt_bn128_G2 Q2 = Q1.mul_by_q(); + assert_except(Q2.Z == alt_bn128_Fq2::one()); + + if (alt_bn128_ate_is_loop_count_neg) + { + R.Y = - R.Y; + } + Q2.Y = - Q2.Y; + + mixed_addition_step_for_flipped_miller_loop(Q1, R, c); + result.coeffs.push_back(c); + + mixed_addition_step_for_flipped_miller_loop(Q2, R, c); + result.coeffs.push_back(c); + + leave_block("Call to alt_bn128_ate_precompute_G2"); + return result; +} + +alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P, + const alt_bn128_ate_G2_precomp &prec_Q) +{ + enter_block("Call to alt_bn128_ate_miller_loop"); + + alt_bn128_Fq12 f = alt_bn128_Fq12::one(); + + bool found_one = false; + size_t idx = 0; + + const bigint &loop_count = alt_bn128_ate_loop_count; + alt_bn128_ate_ell_coeffs c; + + for (long i = loop_count.max_bits(); i >= 0; --i) + { + const bool bit = loop_count.test_bit(i); + if (!found_one) + { + /* this skips the MSB itself */ + found_one |= bit; + continue; + } + + /* code below gets executed for all bits (EXCEPT the MSB itself) of + alt_bn128_param_p (skipping leading zeros) in MSB to LSB + order */ + + c = prec_Q.coeffs[idx++]; + f = f.squared(); + f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV); + + if (bit) + { + c = prec_Q.coeffs[idx++]; + f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV); + } + + } + + if (alt_bn128_ate_is_loop_count_neg) + { + f = f.inverse(); + } + + c = prec_Q.coeffs[idx++]; + f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV); + + c = prec_Q.coeffs[idx++]; + f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV); + + leave_block("Call to alt_bn128_ate_miller_loop"); + return f; +} + +alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1, + const alt_bn128_ate_G2_precomp &prec_Q1, + const alt_bn128_ate_G1_precomp &prec_P2, + const alt_bn128_ate_G2_precomp &prec_Q2) +{ + enter_block("Call to alt_bn128_ate_double_miller_loop"); + + alt_bn128_Fq12 f = alt_bn128_Fq12::one(); + + bool found_one = false; + size_t idx = 0; + + const bigint &loop_count = alt_bn128_ate_loop_count; + for (long i = loop_count.max_bits(); i >= 0; --i) + { + const bool bit = loop_count.test_bit(i); + if (!found_one) + { + /* this skips the MSB itself */ + found_one |= bit; + continue; + } + + /* code below gets executed for all bits (EXCEPT the MSB itself) of + alt_bn128_param_p (skipping leading zeros) in MSB to LSB + order */ + + alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; + alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; + ++idx; + + f = f.squared(); + + f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); + f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); + + if (bit) + { + alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; + alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; + ++idx; + + f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); + f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); + } + } + + if (alt_bn128_ate_is_loop_count_neg) + { + f = f.inverse(); + } + + alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx]; + alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx]; + ++idx; + f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); + f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); + + c1 = prec_Q1.coeffs[idx]; + c2 = prec_Q2.coeffs[idx]; + ++idx; + f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV); + f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV); + + leave_block("Call to alt_bn128_ate_double_miller_loop"); + + return f; +} + +alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, const alt_bn128_G2 &Q) +{ + enter_block("Call to alt_bn128_ate_pairing"); + alt_bn128_ate_G1_precomp prec_P = alt_bn128_ate_precompute_G1(P); + alt_bn128_ate_G2_precomp prec_Q = alt_bn128_ate_precompute_G2(Q); + alt_bn128_Fq12 result = alt_bn128_ate_miller_loop(prec_P, prec_Q); + leave_block("Call to alt_bn128_ate_pairing"); + return result; +} + +alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, const alt_bn128_G2 &Q) +{ + enter_block("Call to alt_bn128_ate_reduced_pairing"); + const alt_bn128_Fq12 f = alt_bn128_ate_pairing(P, Q); + const alt_bn128_GT result = alt_bn128_final_exponentiation(f); + leave_block("Call to alt_bn128_ate_reduced_pairing"); + return result; +} + +/* choice of pairing */ + +alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P) +{ + return alt_bn128_ate_precompute_G1(P); +} + +alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q) +{ + return alt_bn128_ate_precompute_G2(Q); +} + +alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P, + const alt_bn128_G2_precomp &prec_Q) +{ + return alt_bn128_ate_miller_loop(prec_P, prec_Q); +} + +alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1, + const alt_bn128_G2_precomp &prec_Q1, + const alt_bn128_G1_precomp &prec_P2, + const alt_bn128_G2_precomp &prec_Q2) +{ + return alt_bn128_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); +} + +alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P, + const alt_bn128_G2 &Q) +{ + return alt_bn128_ate_pairing(P, Q); +} + +alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q) +{ + return alt_bn128_ate_reduced_pairing(P, Q); +} +} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp new file mode 100644 index 000000000..15d325485 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pairing.hpp @@ -0,0 +1,92 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ALT_BN128_PAIRING_HPP_ +#define ALT_BN128_PAIRING_HPP_ +#include +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" + +namespace libsnark { + +/* final exponentiation */ + +alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt); + +/* ate pairing */ + +struct alt_bn128_ate_G1_precomp { + alt_bn128_Fq PX; + alt_bn128_Fq PY; + + bool operator==(const alt_bn128_ate_G1_precomp &other) const; + friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P); + friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P); +}; + +struct alt_bn128_ate_ell_coeffs { + alt_bn128_Fq2 ell_0; + alt_bn128_Fq2 ell_VW; + alt_bn128_Fq2 ell_VV; + + bool operator==(const alt_bn128_ate_ell_coeffs &other) const; + friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &dc); + friend std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &dc); +}; + +struct alt_bn128_ate_G2_precomp { + alt_bn128_Fq2 QX; + alt_bn128_Fq2 QY; + std::vector coeffs; + + bool operator==(const alt_bn128_ate_G2_precomp &other) const; + friend std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G2_precomp &prec_Q); + friend std::istream& operator>>(std::istream &in, alt_bn128_ate_G2_precomp &prec_Q); +}; + +alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P); +alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q); + +alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P, + const alt_bn128_ate_G2_precomp &prec_Q); +alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1, + const alt_bn128_ate_G2_precomp &prec_Q1, + const alt_bn128_ate_G1_precomp &prec_P2, + const alt_bn128_ate_G2_precomp &prec_Q2); + +alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, + const alt_bn128_G2 &Q); +alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q); + +/* choice of pairing */ + +typedef alt_bn128_ate_G1_precomp alt_bn128_G1_precomp; +typedef alt_bn128_ate_G2_precomp alt_bn128_G2_precomp; + +alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P); + +alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q); + +alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P, + const alt_bn128_G2_precomp &prec_Q); + +alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1, + const alt_bn128_G2_precomp &prec_Q1, + const alt_bn128_G1_precomp &prec_P2, + const alt_bn128_G2_precomp &prec_Q2); + +alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P, + const alt_bn128_G2 &Q); + +alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q); + +alt_bn128_GT alt_bn128_affine_reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q); + +} // libsnark +#endif // ALT_BN128_PAIRING_HPP_ diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp new file mode 100644 index 000000000..25ea924d8 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.cpp @@ -0,0 +1,58 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" + +namespace libsnark { + +void alt_bn128_pp::init_public_params() +{ + init_alt_bn128_params(); +} + +alt_bn128_GT alt_bn128_pp::final_exponentiation(const alt_bn128_Fq12 &elt) +{ + return alt_bn128_final_exponentiation(elt); +} + +alt_bn128_G1_precomp alt_bn128_pp::precompute_G1(const alt_bn128_G1 &P) +{ + return alt_bn128_precompute_G1(P); +} + +alt_bn128_G2_precomp alt_bn128_pp::precompute_G2(const alt_bn128_G2 &Q) +{ + return alt_bn128_precompute_G2(Q); +} + +alt_bn128_Fq12 alt_bn128_pp::miller_loop(const alt_bn128_G1_precomp &prec_P, + const alt_bn128_G2_precomp &prec_Q) +{ + return alt_bn128_miller_loop(prec_P, prec_Q); +} + +alt_bn128_Fq12 alt_bn128_pp::double_miller_loop(const alt_bn128_G1_precomp &prec_P1, + const alt_bn128_G2_precomp &prec_Q1, + const alt_bn128_G1_precomp &prec_P2, + const alt_bn128_G2_precomp &prec_Q2) +{ + return alt_bn128_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); +} + +alt_bn128_Fq12 alt_bn128_pp::pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q) +{ + return alt_bn128_pairing(P, Q); +} + +alt_bn128_Fq12 alt_bn128_pp::reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q) +{ + return alt_bn128_reduced_pairing(P, Q); +} + +} // libsnark diff --git a/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp new file mode 100644 index 000000000..ec8059dcb --- /dev/null +++ b/src/snark/libsnark/algebra/curves/alt_bn128/alt_bn128_pp.hpp @@ -0,0 +1,50 @@ +/** @file +***************************************************************************** +* @author This file is part of libsnark, developed by SCIPR Lab +* and contributors (see AUTHORS). +* @copyright MIT license (see LICENSE file) +*****************************************************************************/ + +#ifndef ALT_BN128_PP_HPP_ +#define ALT_BN128_PP_HPP_ +#include "algebra/curves/public_params.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_init.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp" +#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp" + +namespace libsnark { + +class alt_bn128_pp { +public: + typedef alt_bn128_Fr Fp_type; + typedef alt_bn128_G1 G1_type; + typedef alt_bn128_G2 G2_type; + typedef alt_bn128_G1_precomp G1_precomp_type; + typedef alt_bn128_G2_precomp G2_precomp_type; + typedef alt_bn128_Fq Fq_type; + typedef alt_bn128_Fq2 Fqe_type; + typedef alt_bn128_Fq12 Fqk_type; + typedef alt_bn128_GT GT_type; + + static const bool has_affine_pairing = false; + + static void init_public_params(); + static alt_bn128_GT final_exponentiation(const alt_bn128_Fq12 &elt); + static alt_bn128_G1_precomp precompute_G1(const alt_bn128_G1 &P); + static alt_bn128_G2_precomp precompute_G2(const alt_bn128_G2 &Q); + static alt_bn128_Fq12 miller_loop(const alt_bn128_G1_precomp &prec_P, + const alt_bn128_G2_precomp &prec_Q); + static alt_bn128_Fq12 double_miller_loop(const alt_bn128_G1_precomp &prec_P1, + const alt_bn128_G2_precomp &prec_Q1, + const alt_bn128_G1_precomp &prec_P2, + const alt_bn128_G2_precomp &prec_Q2); + static alt_bn128_Fq12 pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q); + static alt_bn128_Fq12 reduced_pairing(const alt_bn128_G1 &P, + const alt_bn128_G2 &Q); +}; + +} // libsnark + +#endif // ALT_BN128_PP_HPP_ diff --git a/src/snark/libsnark/algebra/curves/curve_utils.hpp b/src/snark/libsnark/algebra/curves/curve_utils.hpp new file mode 100644 index 000000000..33a8e1e17 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/curve_utils.hpp @@ -0,0 +1,22 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef CURVE_UTILS_HPP_ +#define CURVE_UTILS_HPP_ +#include + +#include "algebra/fields/bigint.hpp" + +namespace libsnark { + +template +GroupT scalar_mul(const GroupT &base, const bigint &scalar); + +} // libsnark +#include "algebra/curves/curve_utils.tcc" + +#endif // CURVE_UTILS_HPP_ diff --git a/src/snark/libsnark/algebra/curves/curve_utils.tcc b/src/snark/libsnark/algebra/curves/curve_utils.tcc new file mode 100644 index 000000000..251d75d8b --- /dev/null +++ b/src/snark/libsnark/algebra/curves/curve_utils.tcc @@ -0,0 +1,37 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef CURVE_UTILS_TCC_ +#define CURVE_UTILS_TCC_ + +namespace libsnark { + +template +GroupT scalar_mul(const GroupT &base, const bigint &scalar) +{ + GroupT result = GroupT::zero(); + + bool found_one = false; + for (long i = scalar.max_bits() - 1; i >= 0; --i) + { + if (found_one) + { + result = result.dbl(); + } + + if (scalar.test_bit(i)) + { + found_one = true; + result = result + base; + } + } + + return result; +} + +} // libsnark +#endif // CURVE_UTILS_TCC_ diff --git a/src/snark/libsnark/algebra/curves/public_params.hpp b/src/snark/libsnark/algebra/curves/public_params.hpp new file mode 100644 index 000000000..07e047560 --- /dev/null +++ b/src/snark/libsnark/algebra/curves/public_params.hpp @@ -0,0 +1,103 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PUBLIC_PARAMS_HPP_ +#define PUBLIC_PARAMS_HPP_ +#include + +namespace libsnark { + +/* + for every curve the user should define corresponding + public_params with the following typedefs: + + Fp_type + G1_type + G2_type + G1_precomp_type + G2_precomp_type + affine_ate_G1_precomp_type + affine_ate_G2_precomp_type + Fq_type + Fqe_type + Fqk_type + GT_type + + one should also define the following static methods: + + void init_public_params(); + + GT final_exponentiation(const Fqk &elt); + + G1_precomp precompute_G1(const G1 &P); + G2_precomp precompute_G2(const G2 &Q); + + Fqk miller_loop(const G1_precomp &prec_P, + const G2_precomp &prec_Q); + + affine_ate_G1_precomp affine_ate_precompute_G1(const G1 &P); + affine_ate_G2_precomp affine_ate_precompute_G2(const G2 &Q); + + + Fqk affine_ate_miller_loop(const affine_ate_G1_precomp &prec_P, + const affine_ate_G2_precomp &prec_Q); + Fqk affine_ate_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, + const affine_ate_G2_precomp &prec_Q1, + const affine_ate_G1_precomp &prec_P2, + const affine_ate_G2_precomp &prec_Q2); + Fqk affine_ate_e_times_e_over_e_miller_loop(const affine_ate_G1_precomp &prec_P1, + const affine_ate_G2_precomp &prec_Q1, + const affine_ate_G1_precomp &prec_P2, + const affine_ate_G2_precomp &prec_Q2, + const affine_ate_G1_precomp &prec_P3, + const affine_ate_G2_precomp &prec_Q3); + Fqk double_miller_loop(const G1_precomp &prec_P1, + const G2_precomp &prec_Q1, + const G1_precomp &prec_P2, + const G2_precomp &prec_Q2); + + Fqk pairing(const G1 &P, + const G2 &Q); + GT reduced_pairing(const G1 &P, + const G2 &Q); + GT affine_reduced_pairing(const G1 &P, + const G2 &Q); +*/ + +template +using Fr = typename EC_ppT::Fp_type; +template +using G1 = typename EC_ppT::G1_type; +template +using G2 = typename EC_ppT::G2_type; +template +using G1_precomp = typename EC_ppT::G1_precomp_type; +template +using G2_precomp = typename EC_ppT::G2_precomp_type; +template +using affine_ate_G1_precomp = typename EC_ppT::affine_ate_G1_precomp_type; +template +using affine_ate_G2_precomp = typename EC_ppT::affine_ate_G2_precomp_type; +template +using Fq = typename EC_ppT::Fq_type; +template +using Fqe = typename EC_ppT::Fqe_type; +template +using Fqk = typename EC_ppT::Fqk_type; +template +using GT = typename EC_ppT::GT_type; + +template +using Fr_vector = std::vector >; +template +using G1_vector = std::vector >; +template +using G2_vector = std::vector >; + +} // libsnark + +#endif // PUBLIC_PARAMS_HPP_ diff --git a/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp b/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp new file mode 100644 index 000000000..fe6593bae --- /dev/null +++ b/src/snark/libsnark/algebra/curves/tests/test_bilinearity.cpp @@ -0,0 +1,121 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include "common/profiling.hpp" +#ifdef CURVE_BN128 +#include "algebra/curves/bn128/bn128_pp.hpp" +#endif +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" + +#include + +using namespace libsnark; + +template +void pairing_test() +{ + GT GT_one = GT::one(); + + printf("Running bilinearity tests:\n"); + G1 P = (Fr::random_element()) * G1::one(); + //G1 P = Fr("2") * G1::one(); + G2 Q = (Fr::random_element()) * G2::one(); + //G2 Q = Fr("3") * G2::one(); + + printf("P:\n"); + P.print(); + P.print_coordinates(); + printf("Q:\n"); + Q.print(); + Q.print_coordinates(); + printf("\n\n"); + + Fr s = Fr::random_element(); + //Fr s = Fr("2"); + G1 sP = s * P; + G2 sQ = s * Q; + + printf("Pairing bilinearity tests (three must match):\n"); + GT ans1 = ppT::reduced_pairing(sP, Q); + GT ans2 = ppT::reduced_pairing(P, sQ); + GT ans3 = ppT::reduced_pairing(P, Q)^s; + ans1.print(); + ans2.print(); + ans3.print(); + EXPECT_EQ(ans1, ans2); + EXPECT_EQ(ans2, ans3); + + EXPECT_NE(ans1, GT_one); + EXPECT_EQ((ans1^Fr::field_char()), GT_one); + printf("\n\n"); +} + +template +void double_miller_loop_test() +{ + const G1 P1 = (Fr::random_element()) * G1::one(); + const G1 P2 = (Fr::random_element()) * G1::one(); + const G2 Q1 = (Fr::random_element()) * G2::one(); + const G2 Q2 = (Fr::random_element()) * G2::one(); + + const G1_precomp prec_P1 = ppT::precompute_G1(P1); + const G1_precomp prec_P2 = ppT::precompute_G1(P2); + const G2_precomp prec_Q1 = ppT::precompute_G2(Q1); + const G2_precomp prec_Q2 = ppT::precompute_G2(Q2); + + const Fqk ans_1 = ppT::miller_loop(prec_P1, prec_Q1); + const Fqk ans_2 = ppT::miller_loop(prec_P2, prec_Q2); + const Fqk ans_12 = ppT::double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2); + EXPECT_EQ(ans_1 * ans_2, ans_12); +} + +template +void affine_pairing_test() +{ + GT GT_one = GT::one(); + + printf("Running bilinearity tests:\n"); + G1 P = (Fr::random_element()) * G1::one(); + G2 Q = (Fr::random_element()) * G2::one(); + + printf("P:\n"); + P.print(); + printf("Q:\n"); + Q.print(); + printf("\n\n"); + + Fr s = Fr::random_element(); + G1 sP = s * P; + G2 sQ = s * Q; + + printf("Pairing bilinearity tests (three must match):\n"); + GT ans1 = ppT::affine_reduced_pairing(sP, Q); + GT ans2 = ppT::affine_reduced_pairing(P, sQ); + GT ans3 = ppT::affine_reduced_pairing(P, Q)^s; + ans1.print(); + ans2.print(); + ans3.print(); + EXPECT_EQ(ans1, ans2); + EXPECT_EQ(ans2, ans3); + + EXPECT_NE(ans1, GT_one); + EXPECT_EQ((ans1^Fr::field_char()), GT_one); + printf("\n\n"); +} + +TEST(algebra, bilinearity) +{ + start_profiling(); + alt_bn128_pp::init_public_params(); + pairing_test(); + double_miller_loop_test(); + +#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled + bn128_pp::init_public_params(); + pairing_test(); + double_miller_loop_test(); +#endif +} diff --git a/src/snark/libsnark/algebra/curves/tests/test_groups.cpp b/src/snark/libsnark/algebra/curves/tests/test_groups.cpp new file mode 100644 index 000000000..7bb7c31cc --- /dev/null +++ b/src/snark/libsnark/algebra/curves/tests/test_groups.cpp @@ -0,0 +1,153 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include "common/profiling.hpp" +#ifdef CURVE_BN128 +#include "algebra/curves/bn128/bn128_pp.hpp" +#endif +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +#include + +#include + +using namespace libsnark; + +template +void test_mixed_add() +{ + GroupT base, el, result; + + base = GroupT::zero(); + el = GroupT::zero(); + el.to_special(); + result = base.mixed_add(el); + EXPECT_EQ(result, base + el); + + base = GroupT::zero(); + el = GroupT::random_element(); + el.to_special(); + result = base.mixed_add(el); + EXPECT_EQ(result, base + el); + + base = GroupT::random_element(); + el = GroupT::zero(); + el.to_special(); + result = base.mixed_add(el); + EXPECT_EQ(result, base + el); + + base = GroupT::random_element(); + el = GroupT::random_element(); + el.to_special(); + result = base.mixed_add(el); + EXPECT_EQ(result, base + el); + + base = GroupT::random_element(); + el = base; + el.to_special(); + result = base.mixed_add(el); + EXPECT_EQ(result, base.dbl()); +} + +template +void test_group() +{ + bigint<1> rand1 = bigint<1>("76749407"); + bigint<1> rand2 = bigint<1>("44410867"); + bigint<1> randsum = bigint<1>("121160274"); + + GroupT zero = GroupT::zero(); + EXPECT_EQ(zero, zero); + GroupT one = GroupT::one(); + EXPECT_EQ(one, one); + GroupT two = bigint<1>(2l) * GroupT::one(); + EXPECT_EQ(two, two); + GroupT five = bigint<1>(5l) * GroupT::one(); + + GroupT three = bigint<1>(3l) * GroupT::one(); + GroupT four = bigint<1>(4l) * GroupT::one(); + + EXPECT_EQ(two+five, three+four); + + GroupT a = GroupT::random_element(); + GroupT b = GroupT::random_element(); + + EXPECT_NE(one, zero); + EXPECT_NE(a, zero); + EXPECT_NE(a, one); + + EXPECT_NE(b, zero); + EXPECT_NE(b, one); + + EXPECT_EQ(a.dbl(), a + a); + EXPECT_EQ(b.dbl(), b + b); + EXPECT_EQ(one.add(two), three); + EXPECT_EQ(two.add(one), three); + EXPECT_EQ(a + b, b + a); + EXPECT_EQ(a - a, zero); + EXPECT_EQ(a - b, a + (-b)); + EXPECT_EQ(a - b, (-b) + a); + + // handle special cases + EXPECT_EQ(zero + (-a), -a); + EXPECT_EQ(zero - a, -a); + EXPECT_EQ(a - zero, a); + EXPECT_EQ(a + zero, a); + EXPECT_EQ(zero + a, a); + + EXPECT_EQ((a + b).dbl(), (a + b) + (b + a)); + EXPECT_EQ(bigint<1>("2") * (a + b), (a + b) + (b + a)); + + EXPECT_EQ((rand1 * a) + (rand2 * a), (randsum * a)); + + EXPECT_EQ(GroupT::order() * a, zero); + EXPECT_EQ(GroupT::order() * one, zero); + EXPECT_NE((GroupT::order() * a) - a, zero); + EXPECT_NE((GroupT::order() * one) - one, zero); + + test_mixed_add(); +} + +template +void test_mul_by_q() +{ + GroupT a = GroupT::random_element(); + EXPECT_EQ((GroupT::base_field_char()*a), a.mul_by_q()); +} + +template +void test_output() +{ + GroupT g = GroupT::zero(); + + for (size_t i = 0; i < 1000; ++i) + { + std::stringstream ss; + ss << g; + GroupT gg; + ss >> gg; + EXPECT_EQ(g, gg); + /* use a random point in next iteration */ + g = GroupT::random_element(); + } +} + +TEST(algebra, groups) +{ + alt_bn128_pp::init_public_params(); + test_group >(); + test_output >(); + test_group >(); + test_output >(); + test_mul_by_q >(); + +#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled + bn128_pp::init_public_params(); + test_group >(); + test_output >(); + test_group >(); + test_output >(); +#endif +} diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp new file mode 100644 index 000000000..3e127a063 --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.hpp @@ -0,0 +1,45 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for the "basic radix-2" evaluation domain. + + Roughly, the domain has size m = 2^k and consists of the m-th roots of unity. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_RADIX2_DOMAIN_HPP_ +#define BASIC_RADIX2_DOMAIN_HPP_ + +#include "algebra/evaluation_domain/evaluation_domain.hpp" + +namespace libsnark { + +template +class basic_radix2_domain : public evaluation_domain { +public: + + FieldT omega; + + basic_radix2_domain(const size_t m); + + void FFT(std::vector &a); + void iFFT(std::vector &a); + void cosetFFT(std::vector &a, const FieldT &g); + void icosetFFT(std::vector &a, const FieldT &g); + std::vector lagrange_coeffs(const FieldT &t); + FieldT get_element(const size_t idx); + FieldT compute_Z(const FieldT &t); + void add_poly_Z(const FieldT &coeff, std::vector &H); + void divide_by_Z_on_coset(std::vector &P); + +}; + +} // libsnark + +#include "algebra/evaluation_domain/domains/basic_radix2_domain.tcc" + +#endif // BASIC_RADIX2_DOMAIN_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc new file mode 100644 index 000000000..d315e8319 --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain.tcc @@ -0,0 +1,112 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for the "basic radix-2" evaluation domain. + + See basic_radix2_domain.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_RADIX2_DOMAIN_TCC_ +#define BASIC_RADIX2_DOMAIN_TCC_ + +#include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp" + +namespace libsnark { + +template +basic_radix2_domain::basic_radix2_domain(const size_t m) : evaluation_domain(m) +{ + assert(m > 1); + const size_t logm = log2(m); + assert(logm <= (FieldT::s)); + + omega = get_root_of_unity(m); +} + +template +void basic_radix2_domain::FFT(std::vector &a) +{ + enter_block("Execute FFT"); + assert(a.size() == this->m); + _basic_radix2_FFT(a, omega); + leave_block("Execute FFT"); +} + +template +void basic_radix2_domain::iFFT(std::vector &a) +{ + enter_block("Execute inverse FFT"); + assert(a.size() == this->m); + _basic_radix2_FFT(a, omega.inverse()); + + const FieldT sconst = FieldT(a.size()).inverse(); + for (size_t i = 0; i < a.size(); ++i) + { + a[i] *= sconst; + } + leave_block("Execute inverse FFT"); +} + +template +void basic_radix2_domain::cosetFFT(std::vector &a, const FieldT &g) +{ + enter_block("Execute coset FFT"); + _multiply_by_coset(a, g); + FFT(a); + leave_block("Execute coset FFT"); +} + +template +void basic_radix2_domain::icosetFFT(std::vector &a, const FieldT &g) +{ + enter_block("Execute inverse coset IFFT"); + iFFT(a); + _multiply_by_coset(a, g.inverse()); + leave_block("Execute inverse coset IFFT"); +} + +template +std::vector basic_radix2_domain::lagrange_coeffs(const FieldT &t) +{ + return _basic_radix2_lagrange_coeffs(this->m, t); +} + +template +FieldT basic_radix2_domain::get_element(const size_t idx) +{ + return omega^idx; +} + +template +FieldT basic_radix2_domain::compute_Z(const FieldT &t) +{ + return (t^this->m) - FieldT::one(); +} + +template +void basic_radix2_domain::add_poly_Z(const FieldT &coeff, std::vector &H) +{ + assert(H.size() == this->m+1); + H[this->m] += coeff; + H[0] -= coeff; +} + +template +void basic_radix2_domain::divide_by_Z_on_coset(std::vector &P) +{ + const FieldT coset = FieldT::multiplicative_generator; + const FieldT Z_inverse_at_coset = this->compute_Z(coset).inverse(); + for (size_t i = 0; i < this->m; ++i) + { + P[i] *= Z_inverse_at_coset; + } +} + +} // libsnark + +#endif // BASIC_RADIX2_DOMAIN_TCC_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp new file mode 100644 index 000000000..c42ab2f6f --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.hpp @@ -0,0 +1,48 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for auxiliary functions for the "basic radix-2" evaluation domain. + + These functions compute the radix-2 FFT (in single- or multi-thread mode) and, + also compute Lagrange coefficients. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_RADIX2_DOMAIN_AUX_HPP_ +#define BASIC_RADIX2_DOMAIN_AUX_HPP_ + +namespace libsnark { + +/** + * Compute the radix-2 FFT of the vector a over the set S={omega^{0},...,omega^{m-1}}. + */ +template +void _basic_radix2_FFT(std::vector &a, const FieldT &omega); + +/** + * A multi-thread version of _basic_radix2_FFT. + */ +template +void _parallel_basic_radix2_FFT(std::vector &a, const FieldT &omega); + +/** + * Translate the vector a to a coset defined by g. + */ +template +void _multiply_by_coset(std::vector &a, const FieldT &g); + +/** + * Compute the m Lagrange coefficients, relative to the set S={omega^{0},...,omega^{m-1}}, at the field element t. + */ +template +std::vector _basic_radix2_lagrange_coeffs(const size_t m, const FieldT &t); + +} // libsnark + +#include "algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc" + +#endif // BASIC_RADIX2_DOMAIN_AUX_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc new file mode 100644 index 000000000..138b82dbc --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/domains/basic_radix2_domain_aux.tcc @@ -0,0 +1,242 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for auxiliary functions for the "basic radix-2" evaluation domain. + + See basic_radix2_domain_aux.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_RADIX2_DOMAIN_AUX_TCC_ +#define BASIC_RADIX2_DOMAIN_AUX_TCC_ + +#include +#ifdef MULTICORE +#include +#endif +#include "algebra/fields/field_utils.hpp" +#include "common/profiling.hpp" +#include "common/utils.hpp" + +namespace libsnark { + +#ifdef MULTICORE +#define _basic_radix2_FFT _basic_parallel_radix2_FFT +#else +#define _basic_radix2_FFT _basic_serial_radix2_FFT +#endif + +/* + Below we make use of pseudocode from [CLRS 2n Ed, pp. 864]. + Also, note that it's the caller's responsibility to multiply by 1/N. + */ +template +void _basic_serial_radix2_FFT(std::vector &a, const FieldT &omega) +{ + const size_t n = a.size(), logn = log2(n); + assert(n == (1u << logn)); + + /* swapping in place (from Storer's book) */ + for (size_t k = 0; k < n; ++k) + { + const size_t rk = bitreverse(k, logn); + if (k < rk) + std::swap(a[k], a[rk]); + } + + size_t m = 1; // invariant: m = 2^{s-1} + for (size_t s = 1; s <= logn; ++s) + { + // w_m is 2^s-th root of unity now + const FieldT w_m = omega^(n/(2*m)); + + asm volatile ("/* pre-inner */"); + for (size_t k = 0; k < n; k += 2*m) + { + FieldT w = FieldT::one(); + for (size_t j = 0; j < m; ++j) + { + const FieldT t = w * a[k+j+m]; + a[k+j+m] = a[k+j] - t; + a[k+j] += t; + w *= w_m; + } + } + asm volatile ("/* post-inner */"); + m *= 2; + } +} + +template +void _basic_parallel_radix2_FFT_inner(std::vector &a, const FieldT &omega, const size_t log_cpus) +{ + const size_t num_cpus = 1ul< > tmp(num_cpus); + for (size_t j = 0; j < num_cpus; ++j) + { + tmp[j].resize(1ul<<(log_m-log_cpus), FieldT::zero()); + } + +#ifdef MULTICORE + #pragma omp parallel for +#endif + for (size_t j = 0; j < num_cpus; ++j) + { + const FieldT omega_j = omega^j; + const FieldT omega_step = omega^(j<<(log_m - log_cpus)); + + FieldT elt = FieldT::one(); + for (size_t i = 0; i < 1ul<<(log_m - log_cpus); ++i) + { + for (size_t s = 0; s < num_cpus; ++s) + { + // invariant: elt is omega^(j*idx) + const size_t idx = (i + (s<<(log_m - log_cpus))) % (1u << log_m); + tmp[j][i] += a[idx] * elt; + elt *= omega_step; + } + elt *= omega_j; + } + } + leave_block("Shuffle inputs"); + + enter_block("Execute sub-FFTs"); + const FieldT omega_num_cpus = omega^num_cpus; + +#ifdef MULTICORE + #pragma omp parallel for +#endif + for (size_t j = 0; j < num_cpus; ++j) + { + _basic_serial_radix2_FFT(tmp[j], omega_num_cpus); + } + leave_block("Execute sub-FFTs"); + + enter_block("Re-shuffle outputs"); + +#ifdef MULTICORE + #pragma omp parallel for +#endif + for (size_t i = 0; i < num_cpus; ++i) + { + for (size_t j = 0; j < 1ul<<(log_m - log_cpus); ++j) + { + // now: i = idx >> (log_m - log_cpus) and j = idx % (1u << (log_m - log_cpus)), for idx = ((i<<(log_m-log_cpus))+j) % (1u << log_m) + a[(j< +void _basic_parallel_radix2_FFT(std::vector &a, const FieldT &omega) +{ +#ifdef MULTICORE + const size_t num_cpus = omp_get_max_threads(); +#else + const size_t num_cpus = 1; +#endif + const size_t log_cpus = ((num_cpus & (num_cpus - 1)) == 0 ? log2(num_cpus) : log2(num_cpus) - 1); + +#ifdef DEBUG + print_indent(); printf("* Invoking parallel FFT on 2^%zu CPUs (omp_get_max_threads = %zu)\n", log_cpus, num_cpus); +#endif + + if (log_cpus == 0) + { + _basic_serial_radix2_FFT(a, omega); + } + else + { + _basic_parallel_radix2_FFT_inner(a, omega, log_cpus); + } +} + +template +void _multiply_by_coset(std::vector &a, const FieldT &g) +{ + //enter_block("Multiply by coset"); + FieldT u = g; + for (size_t i = 1; i < a.size(); ++i) + { + a[i] *= u; + u *= g; + } + //leave_block("Multiply by coset"); +} + +template +std::vector _basic_radix2_lagrange_coeffs(const size_t m, const FieldT &t) +{ + if (m == 1) + { + return std::vector(1, FieldT::one()); + } + + assert(m == (1u << log2(m))); + + const FieldT omega = get_root_of_unity(m); + + std::vector u(m, FieldT::zero()); + + /* + If t equals one of the roots of unity in S={omega^{0},...,omega^{m-1}} + then output 1 at the right place, and 0 elsewhere + */ + + if ((t^m) == (FieldT::one())) + { + FieldT omega_i = FieldT::one(); + for (size_t i = 0; i < m; ++i) + { + if (omega_i == t) // i.e., t equals omega^i + { + u[i] = FieldT::one(); + return u; + } + + omega_i *= omega; + } + } + + /* + Otherwise, if t does not equal any of the roots of unity in S, + then compute each L_{i,S}(t) as Z_{S}(t) * v_i / (t-\omega^i) + where: + - Z_{S}(t) = \prod_{j} (t-\omega^j) = (t^m-1), and + - v_{i} = 1 / \prod_{j \neq i} (\omega^i-\omega^j). + Below we use the fact that v_{0} = 1/m and v_{i+1} = \omega * v_{i}. + */ + + const FieldT Z = (t^m)-FieldT::one(); + FieldT l = Z * FieldT(m).inverse(); + FieldT r = FieldT::one(); + for (size_t i = 0; i < m; ++i) + { + u[i] = l * (t - r).inverse(); + l *= omega; + r *= omega; + } + + return u; +} + +} // libsnark + +#endif // BASIC_RADIX2_DOMAIN_AUX_TCC_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp new file mode 100644 index 000000000..d8d91ea68 --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.hpp @@ -0,0 +1,125 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for evaluation domains. + + Roughly, given a desired size m for the domain, the constructor selects + a choice of domain S with size ~m that has been selected so to optimize + - computations of Lagrange polynomials, and + - FFT/iFFT computations. + An evaluation domain also provides other functions, e.g., accessing + individual elements in S or evaluating its vanishing polynomial. + + The descriptions below make use of the definition of a *Lagrange polynomial*, + which we recall. Given a field F, a subset S=(a_i)_i of F, and an index idx + in {0,...,|S-1|}, the idx-th Lagrange polynomial (wrt to subset S) is defined to be + \f[ L_{idx,S}(z) := prod_{k \neq idx} (z - a_k) / prod_{k \neq idx} (a_{idx} - a_k) \f] + Note that, by construction: + \f[ \forall j \neq idx: L_{idx,S}(a_{idx}) = 1 \text{ and } L_{idx,S}(a_j) = 0 \f] + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef EVALUATION_DOMAIN_HPP_ +#define EVALUATION_DOMAIN_HPP_ + +#include + +namespace libsnark { + +/** + * An evaluation domain. + */ +template +class evaluation_domain { +public: + + const size_t m; + + /** + * Construct an evaluation domain S of size m, if possible. + * + * (See the function get_evaluation_domain below.) + */ + evaluation_domain(const size_t m) : m(m) {}; + + /** + * Get the idx-th element in S. + */ + virtual FieldT get_element(const size_t idx) = 0; + + /** + * Compute the FFT, over the domain S, of the vector a. + */ + virtual void FFT(std::vector &a) = 0; + + /** + * Compute the inverse FFT, over the domain S, of the vector a. + */ + virtual void iFFT(std::vector &a) = 0; + + /** + * Compute the FFT, over the domain g*S, of the vector a. + */ + virtual void cosetFFT(std::vector &a, const FieldT &g) = 0; + + /** + * Compute the inverse FFT, over the domain g*S, of the vector a. + */ + virtual void icosetFFT(std::vector &a, const FieldT &g) = 0; + + /** + * Evaluate all Lagrange polynomials. + * + * The inputs are: + * - an integer m + * - an element t + * The output is a vector (b_{0},...,b_{m-1}) + * where b_{i} is the evaluation of L_{i,S}(z) at z = t. + */ + virtual std::vector lagrange_coeffs(const FieldT &t) = 0; + + /** + * Evaluate the vanishing polynomial of S at the field element t. + */ + virtual FieldT compute_Z(const FieldT &t) = 0; + + /** + * Add the coefficients of the vanishing polynomial of S to the coefficients of the polynomial H. + */ + virtual void add_poly_Z(const FieldT &coeff, std::vector &H) = 0; + + /** + * Multiply by the evaluation, on a coset of S, of the inverse of the vanishing polynomial of S. + */ + virtual void divide_by_Z_on_coset(std::vector &P) = 0; +}; + +/** + * Return an evaluation domain object in which the domain S has size |S| >= min_size. + * The function chooses from different supported domains, depending on min_size. + */ +template +std::shared_ptr > get_evaluation_domain(const size_t min_size); + +/** + * Naive evaluation of a *single* Lagrange polynomial, used for testing purposes. + * + * The inputs are: + * - an integer m + * - a domain S = (a_{0},...,a_{m-1}) of size m + * - a field element t + * - an index idx in {0,...,m-1} + * The output is the polynomial L_{idx,S}(z) evaluated at z = t. + */ +template +FieldT lagrange_eval(const size_t m, const std::vector &domain, const FieldT &t, const size_t idx); + +} // libsnark + +#include "algebra/evaluation_domain/evaluation_domain.tcc" + +#endif // EVALUATION_DOMAIN_HPP_ diff --git a/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc new file mode 100644 index 000000000..8e3ea7a62 --- /dev/null +++ b/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc @@ -0,0 +1,117 @@ +/** @file + ***************************************************************************** + + Imeplementation of interfaces for evaluation domains. + + See evaluation_domain.hpp . + + We currently implement, and select among, three types of domains: + - "basic radix-2": the domain has size m = 2^k and consists of the m-th roots of unity + - "extended radix-2": the domain has size m = 2^{k+1} and consists of "the m-th roots of unity" union "a coset" + - "step radix-2": the domain has size m = 2^k + 2^r and consists of "the 2^k-th roots of unity" union "a coset of 2^r-th roots of unity" + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef EVALUATION_DOMAIN_TCC_ +#define EVALUATION_DOMAIN_TCC_ + +#include +#include "algebra/fields/field_utils.hpp" +#include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp" + +namespace libsnark { + +template +std::shared_ptr > get_evaluation_domain(const size_t min_size) +{ + assert(min_size > 1); + const size_t log_min_size = log2(min_size); + assert(log_min_size <= (FieldT::s+1)); + + std::shared_ptr > result; + if (min_size == (1u << log_min_size)) + { + if (log_min_size == FieldT::s+1) + { + if (!inhibit_profiling_info) + { + print_indent(); printf("* Selected domain: extended_radix2\n"); + } + assert(0); + } + else + { + if (!inhibit_profiling_info) + { + print_indent(); printf("* Selected domain: basic_radix2\n"); + } + result.reset(new basic_radix2_domain(min_size)); + } + } + else + { + const size_t big = 1ul<<(log2(min_size)-1); + const size_t small = min_size - big; + const size_t rounded_small = (1ul<(big + rounded_small)); + } + else + { + if (!inhibit_profiling_info) + { + print_indent(); printf("* Selected domain: extended_radix2\n"); + } + assert(0); + } + } + else + { + if (!inhibit_profiling_info) + { + print_indent(); printf("* Selected domain: step_radix2\n"); + } + assert(0); + } + } + + return result; +} + +template +FieldT lagrange_eval(const size_t m, const std::vector &domain, const FieldT &t, const size_t idx) +{ + assert(m == domain.size()); + assert(idx < m); + + FieldT num = FieldT::one(); + FieldT denom = FieldT::one(); + + for (size_t k = 0; k < m; ++k) + { + if (k == idx) + { + continue; + } + + num *= t - domain[k]; + denom *= domain[idx] - domain[k]; + } + + return num * denom.inverse(); +} + +} // libsnark + +#endif // EVALUATION_DOMAIN_TCC_ diff --git a/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp b/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp new file mode 100644 index 000000000..a8a2c925c --- /dev/null +++ b/src/snark/libsnark/algebra/exponentiation/exponentiation.hpp @@ -0,0 +1,31 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for (square-and-multiply) exponentiation. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef EXPONENTIATION_HPP_ +#define EXPONENTIATION_HPP_ + +#include + +#include "algebra/fields/bigint.hpp" + +namespace libsnark { + +template +FieldT power(const FieldT &base, const bigint &exponent); + +template +FieldT power(const FieldT &base, const unsigned long exponent); + +} // libsnark + +#include "algebra/exponentiation/exponentiation.tcc" + +#endif // EXPONENTIATION_HPP_ diff --git a/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc b/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc new file mode 100644 index 000000000..dd557eb12 --- /dev/null +++ b/src/snark/libsnark/algebra/exponentiation/exponentiation.tcc @@ -0,0 +1,53 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for (square-and-multiply) exponentiation. + + See exponentiation.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef EXPONENTIATION_TCC_ +#define EXPONENTIATION_TCC_ + +#include "common/utils.hpp" + +namespace libsnark { + +template +FieldT power(const FieldT &base, const bigint &exponent) +{ + FieldT result = FieldT::one(); + + bool found_one = false; + + for (long i = exponent.max_bits() - 1; i >= 0; --i) + { + if (found_one) + { + result = result * result; + } + + if (exponent.test_bit(i)) + { + found_one = true; + result = result * base; + } + } + + return result; +} + +template +FieldT power(const FieldT &base, const unsigned long exponent) +{ + return power(base, bigint<1>(exponent)); +} + +} // libsnark + +#endif // EXPONENTIATION_TCC_ diff --git a/src/snark/libsnark/algebra/fields/bigint.hpp b/src/snark/libsnark/algebra/fields/bigint.hpp new file mode 100644 index 000000000..50f78b780 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/bigint.hpp @@ -0,0 +1,70 @@ +/** @file + ***************************************************************************** + Declaration of bigint wrapper class around GMP's MPZ long integers. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BIGINT_HPP_ +#define BIGINT_HPP_ +#include +#include +#include +#include "common/serialization.hpp" + +namespace libsnark { + +template class bigint; +template std::ostream& operator<<(std::ostream &, const bigint&); +template std::istream& operator>>(std::istream &, bigint&); + +/** + * Wrapper class around GMP's MPZ long integers. It supports arithmetic operations, + * serialization and randomization. Serialization is fragile, see common/serialization.hpp. + */ + +template +class bigint { +public: + static const mp_size_t N = n; + + mp_limb_t data[n] = {0}; + + bigint() = default; + bigint(const unsigned long x); /// Initialize from a small integer + bigint(const char* s); /// Initialize from a string containing an integer in decimal notation + bigint(const mpz_t r); /// Initialize from MPZ element + + void print() const; + void print_hex() const; + bool operator==(const bigint& other) const; + bool operator!=(const bigint& other) const; + void clear(); + bool is_zero() const; + size_t max_bits() const { return n * GMP_NUMB_BITS; } + size_t num_bits() const; + + unsigned long as_ulong() const; /* return the last limb of the integer */ + void to_mpz(mpz_t r) const; + bool test_bit(const std::size_t bitno) const; + + template inline void operator+=(const bigint& other); + template inline bigint operator*(const bigint& other) const; + template static inline void div_qr(bigint& quotient, bigint& remainder, + const bigint& dividend, const bigint& divisor); + template inline bigint shorten(const bigint& q, const char *msg) const; + + inline void limit(const bigint& q, const char *msg) const; + bool operator>(const bigint& other) const; + + bigint& randomize(); + + friend std::ostream& operator<< (std::ostream &out, const bigint &b); + friend std::istream& operator>> (std::istream &in, bigint &b); +}; + +} // libsnark +#include "algebra/fields/bigint.tcc" +#endif diff --git a/src/snark/libsnark/algebra/fields/bigint.tcc b/src/snark/libsnark/algebra/fields/bigint.tcc new file mode 100644 index 000000000..81befd96a --- /dev/null +++ b/src/snark/libsnark/algebra/fields/bigint.tcc @@ -0,0 +1,278 @@ +/** @file + ***************************************************************************** + Implementation of bigint wrapper class around GMP's MPZ long integers. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BIGINT_TCC_ +#define BIGINT_TCC_ +#include +#include +#include +#include "sodium.h" + +namespace libsnark { + +template +bigint::bigint(const unsigned long x) /// Initialize from a small integer +{ + static_assert(ULONG_MAX <= GMP_NUMB_MAX, "unsigned long does not fit in a GMP limb"); + this->data[0] = x; +} + +template +bigint::bigint(const char* s) /// Initialize from a string containing an integer in decimal notation +{ + size_t l = strlen(s); + unsigned char* s_copy = new unsigned char[l]; + + for (size_t i = 0; i < l; ++i) + { + assert(s[i] >= '0' && s[i] <= '9'); + s_copy[i] = s[i] - '0'; + } + + mp_size_t limbs_written = mpn_set_str(this->data, s_copy, l, 10); + assert(limbs_written <= n); + + delete[] s_copy; +} + +template +bigint::bigint(const mpz_t r) /// Initialize from MPZ element +{ + mpz_t k; + mpz_init_set(k, r); + + for (size_t i = 0; i < n; ++i) + { + data[i] = mpz_get_ui(k); + mpz_fdiv_q_2exp(k, k, GMP_NUMB_BITS); + } + + assert(mpz_sgn(k) == 0); + mpz_clear(k); +} + +template +void bigint::print() const +{ + gmp_printf("%Nd\n", this->data, n); +} + +template +void bigint::print_hex() const +{ + gmp_printf("%Nx\n", this->data, n); +} + +template +bool bigint::operator==(const bigint& other) const +{ + return (mpn_cmp(this->data, other.data, n) == 0); +} + +template +bool bigint::operator!=(const bigint& other) const +{ + return !(operator==(other)); +} + +template +void bigint::clear() +{ + mpn_zero(this->data, n); +} + +template +bool bigint::is_zero() const +{ + for (mp_size_t i = 0; i < n; ++i) + { + if (this->data[i]) + { + return false; + } + } + + return true; +} + +template +size_t bigint::num_bits() const +{ +/* + for (long i = max_bits(); i >= 0; --i) + { + if (this->test_bit(i)) + { + return i+1; + } + } + + return 0; +*/ + for (long i = n-1; i >= 0; --i) + { + mp_limb_t x = this->data[i]; + if (x == 0) + { + continue; + } + else + { + return ((i+1) * GMP_NUMB_BITS) - __builtin_clzl(x); + } + } + return 0; +} + +template +unsigned long bigint::as_ulong() const +{ + return this->data[0]; +} + +template +void bigint::to_mpz(mpz_t r) const +{ + mpz_set_ui(r, 0); + + for (int i = n-1; i >= 0; --i) + { + mpz_mul_2exp(r, r, GMP_NUMB_BITS); + mpz_add_ui(r, r, this->data[i]); + } +} + +template +bool bigint::test_bit(const std::size_t bitno) const +{ + if (bitno >= n * GMP_NUMB_BITS) + { + return false; + } + else + { + const std::size_t part = bitno/GMP_NUMB_BITS; + const std::size_t bit = bitno - (GMP_NUMB_BITS*part); + const mp_limb_t one = 1; + return (this->data[part] & (one< template +inline void bigint::operator+=(const bigint& other) +{ + static_assert(n >= m, "first arg must not be smaller than second arg for bigint in-place add"); + mpn_add(data, data, n, other.data, m); +} + +template template +inline bigint bigint::operator*(const bigint& other) const +{ + static_assert(n >= m, "first arg must not be smaller than second arg for bigint mul"); + bigint res; + mpn_mul(res.data, data, n, other.data, m); + return res; +} + +template template +inline void bigint::div_qr(bigint& quotient, bigint& remainder, + const bigint& dividend, const bigint& divisor) +{ + static_assert(n >= d, "dividend must not be smaller than divisor for bigint::div_qr"); + assert(divisor.data[d-1] != 0); + mpn_tdiv_qr(quotient.data, remainder.data, 0, dividend.data, n, divisor.data, d); +} + +// Return a copy shortened to m limbs provided it is less than limit, throwing std::domain_error if not in range. +template template +inline bigint bigint::shorten(const bigint& q, const char *msg) const +{ + static_assert(m <= n, "number of limbs must not increase for bigint::shorten"); + for (mp_size_t i = m; i < n; i++) { // high-order limbs + if (data[i] != 0) { + throw std::domain_error(msg); + } + } + bigint res; + mpn_copyi(res.data, data, m); + res.limit(q, msg); + return res; +} + +template +inline void bigint::limit(const bigint& q, const char *msg) const +{ + if (!(q > *this)) { + throw std::domain_error(msg); + } +} + +template +inline bool bigint::operator>(const bigint& other) const +{ + return mpn_cmp(this->data, other.data, n) > 0; +} + +template +bigint& bigint::randomize() +{ + assert(GMP_NUMB_BITS == sizeof(mp_limb_t) * 8); + + randombytes_buf(this->data, sizeof(mp_limb_t) * n); + + return (*this); +} + + +template +std::ostream& operator<<(std::ostream &out, const bigint &b) +{ +#ifdef BINARY_OUTPUT + out.write((char*)b.data, sizeof(b.data[0]) * n); +#else + mpz_t t; + mpz_init(t); + b.to_mpz(t); + + out << t; + + mpz_clear(t); +#endif + return out; +} + +template +std::istream& operator>>(std::istream &in, bigint &b) +{ +#ifdef BINARY_OUTPUT + in.read((char*)b.data, sizeof(b.data[0]) * n); +#else + std::string s; + in >> s; + + size_t l = s.size(); + unsigned char* s_copy = new unsigned char[l]; + + for (size_t i = 0; i < l; ++i) + { + assert(s[i] >= '0' && s[i] <= '9'); + s_copy[i] = s[i] - '0'; + } + + mp_size_t limbs_written = mpn_set_str(b.data, s_copy, l, 10); + assert(limbs_written <= n); + + delete[] s_copy; +#endif + return in; +} + +} // libsnark +#endif // BIGINT_TCC_ diff --git a/src/snark/libsnark/algebra/fields/field_utils.hpp b/src/snark/libsnark/algebra/fields/field_utils.hpp new file mode 100644 index 000000000..a07ecfe28 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/field_utils.hpp @@ -0,0 +1,51 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FIELD_UTILS_HPP_ +#define FIELD_UTILS_HPP_ +#include + +#include "common/utils.hpp" +#include "algebra/fields/bigint.hpp" + +namespace libsnark { + +// returns root of unity of order n (for n a power of 2), if one exists +template +FieldT get_root_of_unity(const size_t n); + +template +std::vector pack_int_vector_into_field_element_vector(const std::vector &v, const size_t w); + +template +std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v, const size_t chunk_bits); + +template +std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v); + +template +std::vector convert_bit_vector_to_field_element_vector(const bit_vector &v); + +template +bit_vector convert_field_element_vector_to_bit_vector(const std::vector &v); + +template +bit_vector convert_field_element_to_bit_vector(const FieldT &el); + +template +bit_vector convert_field_element_to_bit_vector(const FieldT &el, const size_t bitcount); + +template +FieldT convert_bit_vector_to_field_element(const bit_vector &v); + +template +void batch_invert(std::vector &vec); + +} // libsnark +#include "algebra/fields/field_utils.tcc" + +#endif // FIELD_UTILS_HPP_ diff --git a/src/snark/libsnark/algebra/fields/field_utils.tcc b/src/snark/libsnark/algebra/fields/field_utils.tcc new file mode 100644 index 000000000..13197b226 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/field_utils.tcc @@ -0,0 +1,183 @@ +/** @file + ***************************************************************************** + Implementation of misc. math and serialization utility functions + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FIELD_UTILS_TCC_ +#define FIELD_UTILS_TCC_ + +#include "common/utils.hpp" + +namespace libsnark { + +template +FieldT coset_shift() +{ + return FieldT::multiplicative_generator.squared(); +} + +template +FieldT get_root_of_unity(const size_t n) +{ + const size_t logn = log2(n); + assert(n == (1u << logn)); + assert(logn <= FieldT::s); + + FieldT omega = FieldT::root_of_unity; + for (size_t i = FieldT::s; i > logn; --i) + { + omega *= omega; + } + + return omega; +} + +template +std::vector pack_int_vector_into_field_element_vector(const std::vector &v, const size_t w) +{ + const size_t chunk_bits = FieldT::capacity(); + const size_t repacked_size = div_ceil(v.size() * w, chunk_bits); + std::vector result(repacked_size); + + for (size_t i = 0; i < repacked_size; ++i) + { + bigint b; + for (size_t j = 0; j < chunk_bits; ++j) + { + const size_t word_index = (i * chunk_bits + j) / w; + const size_t pos_in_word = (i * chunk_bits + j) % w; + const size_t word_or_0 = (word_index < v.size() ? v[word_index] : 0); + const size_t bit = (word_or_0 >> pos_in_word) & 1; + + b.data[j / GMP_NUMB_BITS] |= bit << (j % GMP_NUMB_BITS); + } + result[i] = FieldT(b); + } + + return result; +} + +template +std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v, const size_t chunk_bits) +{ + assert(chunk_bits <= FieldT::capacity()); + + const size_t repacked_size = div_ceil(v.size(), chunk_bits); + std::vector result(repacked_size); + + for (size_t i = 0; i < repacked_size; ++i) + { + bigint b; + for (size_t j = 0; j < chunk_bits; ++j) + { + b.data[j / GMP_NUMB_BITS] |= ((i * chunk_bits + j) < v.size() && v[i * chunk_bits + j] ? 1ll : 0ll) << (j % GMP_NUMB_BITS); + } + result[i] = FieldT(b); + } + + return result; +} + +template +std::vector pack_bit_vector_into_field_element_vector(const bit_vector &v) +{ + return pack_bit_vector_into_field_element_vector(v, FieldT::capacity()); +} + +template +std::vector convert_bit_vector_to_field_element_vector(const bit_vector &v) +{ + std::vector result; + result.reserve(v.size()); + + for (const bool b : v) + { + result.emplace_back(b ? FieldT::one() : FieldT::zero()); + } + + return result; +} + +template +bit_vector convert_field_element_vector_to_bit_vector(const std::vector &v) +{ + bit_vector result; + + for (const FieldT &el : v) + { + const bit_vector el_bits = convert_field_element_to_bit_vector(el); + result.insert(result.end(), el_bits.begin(), el_bits.end()); + } + + return result; +} + +template +bit_vector convert_field_element_to_bit_vector(const FieldT &el) +{ + bit_vector result; + + bigint b = el.as_bigint(); + for (size_t i = 0; i < FieldT::size_in_bits(); ++i) + { + result.push_back(b.test_bit(i)); + } + + return result; +} + +template +bit_vector convert_field_element_to_bit_vector(const FieldT &el, const size_t bitcount) +{ + bit_vector result = convert_field_element_to_bit_vector(el); + result.resize(bitcount); + + return result; +} + +template +FieldT convert_bit_vector_to_field_element(const bit_vector &v) +{ + assert(v.size() <= FieldT::size_in_bits()); + + FieldT res = FieldT::zero(); + FieldT c = FieldT::one(); + for (bool b : v) + { + res += b ? c : FieldT::zero(); + c += c; + } + return res; +} + +template +void batch_invert(std::vector &vec) +{ + std::vector prod; + prod.reserve(vec.size()); + + FieldT acc = FieldT::one(); + + for (auto el : vec) + { + assert(!el.is_zero()); + prod.emplace_back(acc); + acc = acc * el; + } + + FieldT acc_inverse = acc.inverse(); + + for (long i = vec.size()-1; i >= 0; --i) + { + const FieldT old_el = vec[i]; + vec[i] = acc_inverse * prod[i]; + acc_inverse = acc_inverse * old_el; + } +} + +} // libsnark +#endif // FIELD_UTILS_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp.hpp b/src/snark/libsnark/algebra/fields/fp.hpp new file mode 100644 index 000000000..9679275d1 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp.hpp @@ -0,0 +1,182 @@ +/** @file + ***************************************************************************** + Declaration of arithmetic in the finite field F[p], for prime p of fixed length. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP_HPP_ +#define FP_HPP_ + +#include "algebra/fields/bigint.hpp" +#include "algebra/exponentiation/exponentiation.hpp" + +namespace libsnark { + +template& modulus> +class Fp_model; + +template& modulus> +std::ostream& operator<<(std::ostream &, const Fp_model&); + +template& modulus> +std::istream& operator>>(std::istream &, Fp_model &); + +/** + * Arithmetic in the finite field F[p], for prime p of fixed length. + * + * This class implements Fp-arithmetic, for a large prime p, using a fixed number + * of words. It is optimized for tight memory consumption, so the modulus p is + * passed as a template parameter, to avoid per-element overheads. + * + * The implementation is mostly a wrapper around GMP's MPN (constant-size integers). + * But for the integer sizes of interest for libsnark (3 to 5 limbs of 64 bits each), + * we implement performance-critical routines, like addition and multiplication, + * using hand-optimized assembly code. +*/ +template& modulus> +class Fp_model { +public: + bigint mont_repr; +public: + static const mp_size_t num_limbs = n; + static const constexpr bigint& mod = modulus; +#ifdef PROFILE_OP_COUNTS + static long long add_cnt; + static long long sub_cnt; + static long long mul_cnt; + static long long sqr_cnt; + static long long inv_cnt; +#endif + static size_t num_bits; + static bigint euler; // (modulus-1)/2 + static size_t s; // modulus = 2^s * t + 1 + static bigint t; // with t odd + static bigint t_minus_1_over_2; // (t-1)/2 + static Fp_model nqr; // a quadratic nonresidue + static Fp_model nqr_to_t; // nqr^t + static Fp_model multiplicative_generator; // generator of Fp^* + static Fp_model root_of_unity; // generator^((modulus-1)/2^s) + static mp_limb_t inv; // modulus^(-1) mod W, where W = 2^(word size) + static bigint Rsquared; // R^2, where R = W^k, where k = ?? + static bigint Rcubed; // R^3 + + static bool modulus_is_valid() { return modulus.data[n-1] != 0; } // mpn inverse assumes that highest limb is non-zero + + Fp_model() {}; + Fp_model(const bigint &b); + Fp_model(const long x, const bool is_unsigned=false); + + void set_ulong(const unsigned long x); + + void mul_reduce(const bigint &other); + + void clear(); + + /* Return the standard (not Montgomery) representation of the + Field element's requivalence class. I.e. Fp(2).as_bigint() + would return bigint(2) */ + bigint as_bigint() const; + /* Return the last limb of the standard representation of the + field element. E.g. on 64-bit architectures Fp(123).as_ulong() + and Fp(2^64+123).as_ulong() would both return 123. */ + unsigned long as_ulong() const; + + bool operator==(const Fp_model& other) const; + bool operator!=(const Fp_model& other) const; + bool is_zero() const; + + void print() const; + + Fp_model& operator+=(const Fp_model& other); + Fp_model& operator-=(const Fp_model& other); + Fp_model& operator*=(const Fp_model& other); + Fp_model& operator^=(const unsigned long pow); + + template + Fp_model& operator^=(const bigint &pow); + + Fp_model operator+(const Fp_model& other) const; + Fp_model operator-(const Fp_model& other) const; + Fp_model operator*(const Fp_model& other) const; + Fp_model operator-() const; + Fp_model squared() const; + Fp_model& invert(); + Fp_model inverse() const; + Fp_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) + + Fp_model operator^(const unsigned long pow) const; + template + Fp_model operator^(const bigint &pow) const; + + static size_t size_in_bits() { return num_bits; } + static size_t capacity() { return num_bits - 1; } + static bigint field_char() { return modulus; } + + static Fp_model zero(); + static Fp_model one(); + static Fp_model random_element(); + + friend std::ostream& operator<< (std::ostream &out, const Fp_model &p); + friend std::istream& operator>> (std::istream &in, Fp_model &p); +}; + +#ifdef PROFILE_OP_COUNTS +template& modulus> +long long Fp_model::add_cnt = 0; + +template& modulus> +long long Fp_model::sub_cnt = 0; + +template& modulus> +long long Fp_model::mul_cnt = 0; + +template& modulus> +long long Fp_model::sqr_cnt = 0; + +template& modulus> +long long Fp_model::inv_cnt = 0; +#endif + +template& modulus> +size_t Fp_model::num_bits; + +template& modulus> +bigint Fp_model::euler; + +template& modulus> +size_t Fp_model::s; + +template& modulus> +bigint Fp_model::t; + +template& modulus> +bigint Fp_model::t_minus_1_over_2; + +template& modulus> +Fp_model Fp_model::nqr; + +template& modulus> +Fp_model Fp_model::nqr_to_t; + +template& modulus> +Fp_model Fp_model::multiplicative_generator; + +template& modulus> +Fp_model Fp_model::root_of_unity; + +template& modulus> +mp_limb_t Fp_model::inv; + +template& modulus> +bigint Fp_model::Rsquared; + +template& modulus> +bigint Fp_model::Rcubed; + +} // libsnark +#include "algebra/fields/fp.tcc" + +#endif // FP_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp.tcc b/src/snark/libsnark/algebra/fields/fp.tcc new file mode 100644 index 000000000..566e99324 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp.tcc @@ -0,0 +1,790 @@ +/** @file + ***************************************************************************** + Implementation of arithmetic in the finite field F[p], for prime p of fixed length. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP_TCC_ +#define FP_TCC_ +#include +#include +#include + +#include "algebra/fields/fp_aux.tcc" +#include "algebra/fields/field_utils.hpp" +#include "common/assert_except.hpp" + +namespace libsnark { + +template& modulus> +void Fp_model::mul_reduce(const bigint &other) +{ + /* stupid pre-processor tricks; beware */ +#if defined(__x86_64__) && defined(USE_ASM) + if (n == 3) + { // Use asm-optimized Comba multiplication and reduction + mp_limb_t res[2*n]; + mp_limb_t c0, c1, c2; + COMBA_3_BY_3_MUL(c0, c1, c2, res, this->mont_repr.data, other.data); + + mp_limb_t k; + mp_limb_t tmp1, tmp2, tmp3; + REDUCE_6_LIMB_PRODUCT(k, tmp1, tmp2, tmp3, inv, res, modulus.data); + + /* subtract t > mod */ + __asm__ + ("/* check for overflow */ \n\t" + MONT_CMP(16) + MONT_CMP(8) + MONT_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + MONT_FIRSTSUB + MONT_NEXTSUB(8) + MONT_NEXTSUB(16) + "done%=: \n\t" + : + : [tmp] "r" (res+n), [M] "r" (modulus.data) + : "cc", "memory", "%rax"); + mpn_copyi(this->mont_repr.data, res+n, n); + } + else if (n == 4) + { // use asm-optimized "CIOS method" + + mp_limb_t tmp[n+1]; + mp_limb_t T0=0, T1=1, cy=2, u=3; // TODO: fix this + + __asm__ (MONT_PRECOMPUTE + MONT_FIRSTITER(1) + MONT_FIRSTITER(2) + MONT_FIRSTITER(3) + MONT_FINALIZE(3) + MONT_ITERFIRST(1) + MONT_ITERITER(1, 1) + MONT_ITERITER(1, 2) + MONT_ITERITER(1, 3) + MONT_FINALIZE(3) + MONT_ITERFIRST(2) + MONT_ITERITER(2, 1) + MONT_ITERITER(2, 2) + MONT_ITERITER(2, 3) + MONT_FINALIZE(3) + MONT_ITERFIRST(3) + MONT_ITERITER(3, 1) + MONT_ITERITER(3, 2) + MONT_ITERITER(3, 3) + MONT_FINALIZE(3) + "/* check for overflow */ \n\t" + MONT_CMP(24) + MONT_CMP(16) + MONT_CMP(8) + MONT_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + MONT_FIRSTSUB + MONT_NEXTSUB(8) + MONT_NEXTSUB(16) + MONT_NEXTSUB(24) + "done%=: \n\t" + : + : [tmp] "r" (tmp), [A] "r" (this->mont_repr.data), [B] "r" (other.data), [inv] "r" (inv), [M] "r" (modulus.data), + [T0] "r" (T0), [T1] "r" (T1), [cy] "r" (cy), [u] "r" (u) + : "cc", "memory", "%rax", "%rdx" + ); + mpn_copyi(this->mont_repr.data, tmp, n); + } + else if (n == 5) + { // use asm-optimized "CIOS method" + + mp_limb_t tmp[n+1]; + mp_limb_t T0=0, T1=1, cy=2, u=3; // TODO: fix this + + __asm__ (MONT_PRECOMPUTE + MONT_FIRSTITER(1) + MONT_FIRSTITER(2) + MONT_FIRSTITER(3) + MONT_FIRSTITER(4) + MONT_FINALIZE(4) + MONT_ITERFIRST(1) + MONT_ITERITER(1, 1) + MONT_ITERITER(1, 2) + MONT_ITERITER(1, 3) + MONT_ITERITER(1, 4) + MONT_FINALIZE(4) + MONT_ITERFIRST(2) + MONT_ITERITER(2, 1) + MONT_ITERITER(2, 2) + MONT_ITERITER(2, 3) + MONT_ITERITER(2, 4) + MONT_FINALIZE(4) + MONT_ITERFIRST(3) + MONT_ITERITER(3, 1) + MONT_ITERITER(3, 2) + MONT_ITERITER(3, 3) + MONT_ITERITER(3, 4) + MONT_FINALIZE(4) + MONT_ITERFIRST(4) + MONT_ITERITER(4, 1) + MONT_ITERITER(4, 2) + MONT_ITERITER(4, 3) + MONT_ITERITER(4, 4) + MONT_FINALIZE(4) + "/* check for overflow */ \n\t" + MONT_CMP(32) + MONT_CMP(24) + MONT_CMP(16) + MONT_CMP(8) + MONT_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + MONT_FIRSTSUB + MONT_NEXTSUB(8) + MONT_NEXTSUB(16) + MONT_NEXTSUB(24) + MONT_NEXTSUB(32) + "done%=: \n\t" + : + : [tmp] "r" (tmp), [A] "r" (this->mont_repr.data), [B] "r" (other.data), [inv] "r" (inv), [M] "r" (modulus.data), + [T0] "r" (T0), [T1] "r" (T1), [cy] "r" (cy), [u] "r" (u) + : "cc", "memory", "%rax", "%rdx" + ); + mpn_copyi(this->mont_repr.data, tmp, n); + } + else +#endif + { + mp_limb_t res[2*n]; + mpn_mul_n(res, this->mont_repr.data, other.data, n); + + /* + The Montgomery reduction here is based on Algorithm 14.32 in + Handbook of Applied Cryptography + . + */ + for (size_t i = 0; i < n; ++i) + { + mp_limb_t k = inv * res[i]; + /* calculate res = res + k * mod * b^i */ + mp_limb_t carryout = mpn_addmul_1(res+i, modulus.data, n, k); + carryout = mpn_add_1(res+n+i, res+n+i, n-i, carryout); + assert(carryout == 0); + } + + if (mpn_cmp(res+n, modulus.data, n) >= 0) + { + const mp_limb_t borrow = mpn_sub(res+n, res+n, n, modulus.data, n); + assert(borrow == 0); + } + + mpn_copyi(this->mont_repr.data, res+n, n); + } +} + +template& modulus> +Fp_model::Fp_model(const bigint &b) +{ + mpn_copyi(this->mont_repr.data, Rsquared.data, n); + mul_reduce(b); +} + +template& modulus> +Fp_model::Fp_model(const long x, const bool is_unsigned) +{ + if (is_unsigned || x >= 0) + { + this->mont_repr.data[0] = x; + } + else + { + const mp_limb_t borrow = mpn_sub_1(this->mont_repr.data, modulus.data, n, -x); + assert(borrow == 0); + } + + mul_reduce(Rsquared); +} + +template& modulus> +void Fp_model::set_ulong(const unsigned long x) +{ + this->mont_repr.clear(); + this->mont_repr.data[0] = x; + mul_reduce(Rsquared); +} + +template& modulus> +void Fp_model::clear() +{ + this->mont_repr.clear(); +} + +template& modulus> +bigint Fp_model::as_bigint() const +{ + bigint one; + one.clear(); + one.data[0] = 1; + + Fp_model res(*this); + res.mul_reduce(one); + + return (res.mont_repr); +} + +template& modulus> +unsigned long Fp_model::as_ulong() const +{ + return this->as_bigint().as_ulong(); +} + +template& modulus> +bool Fp_model::operator==(const Fp_model& other) const +{ + return (this->mont_repr == other.mont_repr); +} + +template& modulus> +bool Fp_model::operator!=(const Fp_model& other) const +{ + return (this->mont_repr != other.mont_repr); +} + +template& modulus> +bool Fp_model::is_zero() const +{ + return (this->mont_repr.is_zero()); // zero maps to zero +} + +template& modulus> +void Fp_model::print() const +{ + Fp_model tmp; + tmp.mont_repr.data[0] = 1; + tmp.mul_reduce(this->mont_repr); + + tmp.mont_repr.print(); +} + +template& modulus> +Fp_model Fp_model::zero() +{ + Fp_model res; + res.mont_repr.clear(); + return res; +} + +template& modulus> +Fp_model Fp_model::one() +{ + Fp_model res; + res.mont_repr.data[0] = 1; + res.mul_reduce(Rsquared); + return res; +} + +template& modulus> +Fp_model& Fp_model::operator+=(const Fp_model& other) +{ +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif +#if defined(__x86_64__) && defined(USE_ASM) + if (n == 3) + { + __asm__ + ("/* perform bignum addition */ \n\t" + ADD_FIRSTADD + ADD_NEXTADD(8) + ADD_NEXTADD(16) + "/* if overflow: subtract */ \n\t" + "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" + "jc subtract%= \n\t" + + "/* check for overflow */ \n\t" + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + ADD_FIRSTSUB + ADD_NEXTSUB(8) + ADD_NEXTSUB(16) + "done%=: \n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else if (n == 4) + { + __asm__ + ("/* perform bignum addition */ \n\t" + ADD_FIRSTADD + ADD_NEXTADD(8) + ADD_NEXTADD(16) + ADD_NEXTADD(24) + "/* if overflow: subtract */ \n\t" + "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" + "jc subtract%= \n\t" + + "/* check for overflow */ \n\t" + ADD_CMP(24) + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + ADD_FIRSTSUB + ADD_NEXTSUB(8) + ADD_NEXTSUB(16) + ADD_NEXTSUB(24) + "done%=: \n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else if (n == 5) + { + __asm__ + ("/* perform bignum addition */ \n\t" + ADD_FIRSTADD + ADD_NEXTADD(8) + ADD_NEXTADD(16) + ADD_NEXTADD(24) + ADD_NEXTADD(32) + "/* if overflow: subtract */ \n\t" + "/* (tricky point: if A and B are in the range we do not need to do anything special for the possible carry flag) */ \n\t" + "jc subtract%= \n\t" + + "/* check for overflow */ \n\t" + ADD_CMP(32) + ADD_CMP(24) + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + ADD_FIRSTSUB + ADD_NEXTSUB(8) + ADD_NEXTSUB(16) + ADD_NEXTSUB(24) + ADD_NEXTSUB(32) + "done%=: \n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else +#endif + { + mp_limb_t scratch[n+1]; + const mp_limb_t carry = mpn_add_n(scratch, this->mont_repr.data, other.mont_repr.data, n); + scratch[n] = carry; + + if (carry || mpn_cmp(scratch, modulus.data, n) >= 0) + { + const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, modulus.data, n); + assert(borrow == 0); + } + + mpn_copyi(this->mont_repr.data, scratch, n); + } + + return *this; +} + +template& modulus> +Fp_model& Fp_model::operator-=(const Fp_model& other) +{ +#ifdef PROFILE_OP_COUNTS + this->sub_cnt++; +#endif +#if defined(__x86_64__) && defined(USE_ASM) + if (n == 3) + { + __asm__ + (SUB_FIRSTSUB + SUB_NEXTSUB(8) + SUB_NEXTSUB(16) + + "jnc done%=\n\t" + + SUB_FIRSTADD + SUB_NEXTADD(8) + SUB_NEXTADD(16) + + "done%=:\n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else if (n == 4) + { + __asm__ + (SUB_FIRSTSUB + SUB_NEXTSUB(8) + SUB_NEXTSUB(16) + SUB_NEXTSUB(24) + + "jnc done%=\n\t" + + SUB_FIRSTADD + SUB_NEXTADD(8) + SUB_NEXTADD(16) + SUB_NEXTADD(24) + + "done%=:\n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else if (n == 5) + { + __asm__ + (SUB_FIRSTSUB + SUB_NEXTSUB(8) + SUB_NEXTSUB(16) + SUB_NEXTSUB(24) + SUB_NEXTSUB(32) + + "jnc done%=\n\t" + + SUB_FIRSTADD + SUB_NEXTADD(8) + SUB_NEXTADD(16) + SUB_NEXTADD(24) + SUB_NEXTADD(32) + + "done%=:\n\t" + : + : [A] "r" (this->mont_repr.data), [B] "r" (other.mont_repr.data), [mod] "r" (modulus.data) + : "cc", "memory", "%rax"); + } + else +#endif + { + mp_limb_t scratch[n+1]; + if (mpn_cmp(this->mont_repr.data, other.mont_repr.data, n) < 0) + { + const mp_limb_t carry = mpn_add_n(scratch, this->mont_repr.data, modulus.data, n); + scratch[n] = carry; + } + else + { + mpn_copyi(scratch, this->mont_repr.data, n); + scratch[n] = 0; + } + + const mp_limb_t borrow = mpn_sub(scratch, scratch, n+1, other.mont_repr.data, n); + assert(borrow == 0); + + mpn_copyi(this->mont_repr.data, scratch, n); + } + return *this; +} + +template& modulus> +Fp_model& Fp_model::operator*=(const Fp_model& other) +{ +#ifdef PROFILE_OP_COUNTS + this->mul_cnt++; +#endif + + mul_reduce(other.mont_repr); + return *this; +} + +template& modulus> +Fp_model& Fp_model::operator^=(const unsigned long pow) +{ + (*this) = power >(*this, pow); + return (*this); +} + +template& modulus> +template +Fp_model& Fp_model::operator^=(const bigint &pow) +{ + (*this) = power, m>(*this, pow); + return (*this); +} + +template& modulus> +Fp_model Fp_model::operator+(const Fp_model& other) const +{ + Fp_model r(*this); + return (r += other); +} + +template& modulus> +Fp_model Fp_model::operator-(const Fp_model& other) const +{ + Fp_model r(*this); + return (r -= other); +} + +template& modulus> +Fp_model Fp_model::operator*(const Fp_model& other) const +{ + Fp_model r(*this); + return (r *= other); +} + +template& modulus> +Fp_model Fp_model::operator^(const unsigned long pow) const +{ + Fp_model r(*this); + return (r ^= pow); +} + +template& modulus> +template +Fp_model Fp_model::operator^(const bigint &pow) const +{ + Fp_model r(*this); + return (r ^= pow); +} + +template& modulus> +Fp_model Fp_model::operator-() const +{ +#ifdef PROFILE_OP_COUNTS + this->sub_cnt++; +#endif + + if (this->is_zero()) + { + return (*this); + } + else + { + Fp_model r; + mpn_sub_n(r.mont_repr.data, modulus.data, this->mont_repr.data, n); + return r; + } +} + +template& modulus> +Fp_model Fp_model::squared() const +{ +#ifdef PROFILE_OP_COUNTS + this->sqr_cnt++; + this->mul_cnt--; // zero out the upcoming mul +#endif + /* stupid pre-processor tricks; beware */ +#if defined(__x86_64__) && defined(USE_ASM) + if (n == 3) + { // use asm-optimized Comba squaring + mp_limb_t res[2*n]; + mp_limb_t c0, c1, c2; + COMBA_3_BY_3_SQR(c0, c1, c2, res, this->mont_repr.data); + + mp_limb_t k; + mp_limb_t tmp1, tmp2, tmp3; + REDUCE_6_LIMB_PRODUCT(k, tmp1, tmp2, tmp3, inv, res, modulus.data); + + /* subtract t > mod */ + __asm__ volatile + ("/* check for overflow */ \n\t" + MONT_CMP(16) + MONT_CMP(8) + MONT_CMP(0) + + "/* subtract mod if overflow */ \n\t" + "subtract%=: \n\t" + MONT_FIRSTSUB + MONT_NEXTSUB(8) + MONT_NEXTSUB(16) + "done%=: \n\t" + : + : [tmp] "r" (res+n), [M] "r" (modulus.data) + : "cc", "memory", "%rax"); + + Fp_model r; + mpn_copyi(r.mont_repr.data, res+n, n); + return r; + } + else +#endif + { + Fp_model r(*this); + return (r *= r); + } +} + +template& modulus> +Fp_model& Fp_model::invert() +{ +#ifdef PROFILE_OP_COUNTS + this->inv_cnt++; +#endif + + assert(!this->is_zero()); + + bigint g; /* gp should have room for vn = n limbs */ + + mp_limb_t s[n+1]; /* sp should have room for vn+1 limbs */ + mp_size_t sn; + + bigint v = modulus; // both source operands are destroyed by mpn_gcdext + + /* computes gcd(u, v) = g = u*s + v*t, so s*u will be 1 (mod v) */ + const mp_size_t gn = mpn_gcdext(g.data, s, &sn, this->mont_repr.data, n, v.data, n); + assert(gn == 1 && g.data[0] == 1); /* inverse exists */ + + mp_limb_t q; /* division result fits into q, as sn <= n+1 */ + /* sn < 0 indicates negative sn; will fix up later */ + + if (std::abs(sn) >= n) + { + /* if sn could require modulus reduction, do it here */ + mpn_tdiv_qr(&q, this->mont_repr.data, 0, s, std::abs(sn), modulus.data, n); + } + else + { + /* otherwise just copy it over */ + mpn_zero(this->mont_repr.data, n); + mpn_copyi(this->mont_repr.data, s, std::abs(sn)); + } + + /* fix up the negative sn */ + if (sn < 0) + { + const mp_limb_t borrow = mpn_sub_n(this->mont_repr.data, modulus.data, this->mont_repr.data, n); + assert(borrow == 0); + } + + mul_reduce(Rcubed); + return *this; +} + +template& modulus> +Fp_model Fp_model::inverse() const +{ + Fp_model r(*this); + return (r.invert()); +} + +template& modulus> +Fp_model Fp_model::random_element() /// returns random element of Fp_model +{ + /* note that as Montgomery representation is a bijection then + selecting a random element of {xR} is the same as selecting a + random element of {x} */ + Fp_model r; + do + { + r.mont_repr.randomize(); + + /* clear all bits higher than MSB of modulus */ + size_t bitno = GMP_NUMB_BITS * n - 1; + while (modulus.test_bit(bitno) == false) + { + const std::size_t part = bitno/GMP_NUMB_BITS; + const std::size_t bit = bitno - (GMP_NUMB_BITS*part); + + r.mont_repr.data[part] &= ~(1ul<= modulus -- repeat (rejection sampling) */ + while (mpn_cmp(r.mont_repr.data, modulus.data, n) >= 0); + + return r; +} + +template& modulus> +Fp_model Fp_model::sqrt() const +{ + if (is_zero()) { + return *this; + } + + Fp_model one = Fp_model::one(); + + size_t v = Fp_model::s; + Fp_model z = Fp_model::nqr_to_t; + Fp_model w = (*this)^Fp_model::t_minus_1_over_2; + Fp_model x = (*this) * w; + Fp_model b = x * w; // b = (*this)^t + + + // check if square with euler's criterion + Fp_model check = b; + for (size_t i = 0; i < v-1; ++i) + { + check = check.squared(); + } + if (check != one) + { + assert_except(0); + } + + + // compute square root with Tonelli--Shanks + // (does not terminate if not a square!) + + while (b != one) + { + size_t m = 0; + Fp_model b2m = b; + while (b2m != one) + { + /* invariant: b2m = b^(2^m) after entering this loop */ + b2m = b2m.squared(); + m += 1; + } + + int j = v-m-1; + w = z; + while (j > 0) + { + w = w.squared(); + --j; + } // w = z^2^(v-m-1) + + z = w.squared(); + b = b * z; + x = x * w; + v = m; + } + + return x; +} + +template& modulus> +std::ostream& operator<<(std::ostream &out, const Fp_model &p) +{ +#ifndef MONTGOMERY_OUTPUT + Fp_model tmp; + tmp.mont_repr.data[0] = 1; + tmp.mul_reduce(p.mont_repr); + out << tmp.mont_repr; +#else + out << p.mont_repr; +#endif + return out; +} + +template& modulus> +std::istream& operator>>(std::istream &in, Fp_model &p) +{ +#ifndef MONTGOMERY_OUTPUT + in >> p.mont_repr; + p.mul_reduce(Fp_model::Rsquared); +#else + in >> p.mont_repr; +#endif + return in; +} + +} // libsnark +#endif // FP_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp b/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp new file mode 100644 index 000000000..1de9d88b4 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp12_2over3over2.hpp @@ -0,0 +1,116 @@ +/** @file + ***************************************************************************** + Declaration of arithmetic in the finite field F[((p^2)^3)^2]. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP12_2OVER3OVER2_HPP_ +#define FP12_2OVER3OVER2_HPP_ +#include "algebra/fields/fp.hpp" +#include "algebra/fields/fp2.hpp" +#include "algebra/fields/fp6_3over2.hpp" +#include + +namespace libsnark { + +template& modulus> +class Fp12_2over3over2_model; + +template& modulus> +std::ostream& operator<<(std::ostream &, const Fp12_2over3over2_model &); + +template& modulus> +std::istream& operator>>(std::istream &, Fp12_2over3over2_model &); + +/** + * Arithmetic in the finite field F[((p^2)^3)^2]. + * + * Let p := modulus. This interface provides arithmetic for the extension field + * Fp12 = Fp6[W]/(W^2-V) where Fp6 = Fp2[V]/(V^3-non_residue) and non_residue is in Fp2 + * + * ASSUMPTION: p = 1 (mod 6) + */ +template& modulus> +class Fp12_2over3over2_model { +public: + typedef Fp_model my_Fp; + typedef Fp2_model my_Fp2; + typedef Fp6_3over2_model my_Fp6; + + static Fp2_model non_residue; + static Fp2_model Frobenius_coeffs_c1[12]; // non_residue^((modulus^i-1)/6) for i=0,...,11 + + my_Fp6 c0, c1; + Fp12_2over3over2_model() {}; + Fp12_2over3over2_model(const my_Fp6& c0, const my_Fp6& c1) : c0(c0), c1(c1) {}; + + void clear() { c0.clear(); c1.clear(); } + void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); } + + static Fp12_2over3over2_model zero(); + static Fp12_2over3over2_model one(); + static Fp12_2over3over2_model random_element(); + + bool is_zero() const { return c0.is_zero() && c1.is_zero(); } + bool operator==(const Fp12_2over3over2_model &other) const; + bool operator!=(const Fp12_2over3over2_model &other) const; + + Fp12_2over3over2_model operator+(const Fp12_2over3over2_model &other) const; + Fp12_2over3over2_model operator-(const Fp12_2over3over2_model &other) const; + Fp12_2over3over2_model operator*(const Fp12_2over3over2_model &other) const; + Fp12_2over3over2_model operator-() const; + Fp12_2over3over2_model squared() const; // default is squared_complex + Fp12_2over3over2_model squared_karatsuba() const; + Fp12_2over3over2_model squared_complex() const; + Fp12_2over3over2_model inverse() const; + Fp12_2over3over2_model Frobenius_map(unsigned long power) const; + Fp12_2over3over2_model unitary_inverse() const; + Fp12_2over3over2_model cyclotomic_squared() const; + + Fp12_2over3over2_model mul_by_024(const my_Fp2 &ell_0, const my_Fp2 &ell_VW, const my_Fp2 &ell_VV) const; + + static my_Fp6 mul_by_non_residue(const my_Fp6 &elt); + + template + Fp12_2over3over2_model cyclotomic_exp(const bigint &exponent) const; + + static bigint base_field_char() { return modulus; } + static size_t extension_degree() { return 12; } + + friend std::ostream& operator<< (std::ostream &out, const Fp12_2over3over2_model &el); + friend std::istream& operator>> (std::istream &in, Fp12_2over3over2_model &el); +}; + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v); + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v); + +template& modulus> +Fp12_2over3over2_model operator*(const Fp_model &lhs, const Fp12_2over3over2_model &rhs); + +template& modulus> +Fp12_2over3over2_model operator*(const Fp2_model &lhs, const Fp12_2over3over2_model &rhs); + +template& modulus> +Fp12_2over3over2_model operator*(const Fp6_3over2_model &lhs, const Fp12_2over3over2_model &rhs); + +template& modulus, mp_size_t m> +Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const bigint &exponent); + +template& modulus, mp_size_t m, const bigint& exp_modulus> +Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const Fp_model &exponent); + +template& modulus> +Fp2_model Fp12_2over3over2_model::non_residue; + +template& modulus> +Fp2_model Fp12_2over3over2_model::Frobenius_coeffs_c1[12]; + +} // libsnark +#include "algebra/fields/fp12_2over3over2.tcc" +#endif // FP12_2OVER3OVER2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc b/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc new file mode 100644 index 000000000..2fbc0b649 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp12_2over3over2.tcc @@ -0,0 +1,412 @@ +/** @file + ***************************************************************************** + Implementation of arithmetic in the finite field F[((p^2)^3)^2]. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP12_2OVER3OVER2_TCC_ +#define FP12_2OVER3OVER2_TCC_ + +namespace libsnark { + +template& modulus> +Fp6_3over2_model Fp12_2over3over2_model::mul_by_non_residue(const Fp6_3over2_model &elt) +{ + return Fp6_3over2_model(non_residue * elt.c2, elt.c0, elt.c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::zero() +{ + return Fp12_2over3over2_model(my_Fp6::zero(), my_Fp6::zero()); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::one() +{ + return Fp12_2over3over2_model(my_Fp6::one(), my_Fp6::zero()); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::random_element() +{ + Fp12_2over3over2_model r; + r.c0 = my_Fp6::random_element(); + r.c1 = my_Fp6::random_element(); + + return r; +} + +template& modulus> +bool Fp12_2over3over2_model::operator==(const Fp12_2over3over2_model &other) const +{ + return (this->c0 == other.c0 && this->c1 == other.c1); +} + +template& modulus> +bool Fp12_2over3over2_model::operator!=(const Fp12_2over3over2_model &other) const +{ + return !(operator==(other)); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::operator+(const Fp12_2over3over2_model &other) const +{ + return Fp12_2over3over2_model(this->c0 + other.c0, + this->c1 + other.c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::operator-(const Fp12_2over3over2_model &other) const +{ + return Fp12_2over3over2_model(this->c0 - other.c0, + this->c1 - other.c1); +} + +template& modulus> +Fp12_2over3over2_model operator*(const Fp_model &lhs, const Fp12_2over3over2_model &rhs) +{ + return Fp12_2over3over2_model(lhs*rhs.c0, + lhs*rhs.c1); +} + +template& modulus> +Fp12_2over3over2_model operator*(const Fp2_model &lhs, const Fp12_2over3over2_model &rhs) +{ + return Fp12_2over3over2_model(lhs*rhs.c0, + lhs*rhs.c1); +} + +template& modulus> +Fp12_2over3over2_model operator*(const Fp6_3over2_model &lhs, const Fp12_2over3over2_model &rhs) +{ + return Fp12_2over3over2_model(lhs*rhs.c0, + lhs*rhs.c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::operator*(const Fp12_2over3over2_model &other) const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba) */ + + const my_Fp6 &A = other.c0, &B = other.c1, + &a = this->c0, &b = this->c1; + const my_Fp6 aA = a * A; + const my_Fp6 bB = b * B; + + return Fp12_2over3over2_model(aA + Fp12_2over3over2_model::mul_by_non_residue(bB), + (a + b)*(A+B) - aA - bB); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::operator-() const +{ + return Fp12_2over3over2_model(-this->c0, + -this->c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::squared() const +{ + return squared_complex(); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::squared_karatsuba() const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba squaring) */ + + const my_Fp6 &a = this->c0, &b = this->c1; + const my_Fp6 asq = a.squared(); + const my_Fp6 bsq = b.squared(); + + return Fp12_2over3over2_model(asq + Fp12_2over3over2_model::mul_by_non_residue(bsq), + (a + b).squared() - asq - bsq); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::squared_complex() const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Complex squaring) */ + + const my_Fp6 &a = this->c0, &b = this->c1; + const my_Fp6 ab = a * b; + + return Fp12_2over3over2_model((a + b) * (a + Fp12_2over3over2_model::mul_by_non_residue(b)) - ab - Fp12_2over3over2_model::mul_by_non_residue(ab), + ab + ab); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::inverse() const +{ + /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8 */ + + const my_Fp6 &a = this->c0, &b = this->c1; + const my_Fp6 t0 = a.squared(); + const my_Fp6 t1 = b.squared(); + const my_Fp6 t2 = t0 - Fp12_2over3over2_model::mul_by_non_residue(t1); + const my_Fp6 t3 = t2.inverse(); + const my_Fp6 c0 = a * t3; + const my_Fp6 c1 = - (b * t3); + + return Fp12_2over3over2_model(c0, c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::Frobenius_map(unsigned long power) const +{ + return Fp12_2over3over2_model(c0.Frobenius_map(power), + Frobenius_coeffs_c1[power % 12] * c1.Frobenius_map(power)); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::unitary_inverse() const +{ + return Fp12_2over3over2_model(this->c0, + -this->c1); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::cyclotomic_squared() const +{ + /* OLD: naive implementation + return (*this).squared(); + */ + my_Fp2 z0 = this->c0.c0; + my_Fp2 z4 = this->c0.c1; + my_Fp2 z3 = this->c0.c2; + my_Fp2 z2 = this->c1.c0; + my_Fp2 z1 = this->c1.c1; + my_Fp2 z5 = this->c1.c2; + + my_Fp2 t0, t1, t2, t3, t4, t5, tmp; + + // t0 + t1*y = (z0 + z1*y)^2 = a^2 + tmp = z0 * z1; + t0 = (z0 + z1) * (z0 + my_Fp6::non_residue * z1) - tmp - my_Fp6::non_residue * tmp; + t1 = tmp + tmp; + // t2 + t3*y = (z2 + z3*y)^2 = b^2 + tmp = z2 * z3; + t2 = (z2 + z3) * (z2 + my_Fp6::non_residue * z3) - tmp - my_Fp6::non_residue * tmp; + t3 = tmp + tmp; + // t4 + t5*y = (z4 + z5*y)^2 = c^2 + tmp = z4 * z5; + t4 = (z4 + z5) * (z4 + my_Fp6::non_residue * z5) - tmp - my_Fp6::non_residue * tmp; + t5 = tmp + tmp; + + // for A + + // z0 = 3 * t0 - 2 * z0 + z0 = t0 - z0; + z0 = z0 + z0; + z0 = z0 + t0; + // z1 = 3 * t1 + 2 * z1 + z1 = t1 + z1; + z1 = z1 + z1; + z1 = z1 + t1; + + // for B + + // z2 = 3 * (xi * t5) + 2 * z2 + tmp = my_Fp6::non_residue * t5; + z2 = tmp + z2; + z2 = z2 + z2; + z2 = z2 + tmp; + + // z3 = 3 * t4 - 2 * z3 + z3 = t4 - z3; + z3 = z3 + z3; + z3 = z3 + t4; + + // for C + + // z4 = 3 * t2 - 2 * z4 + z4 = t2 - z4; + z4 = z4 + z4; + z4 = z4 + t2; + + // z5 = 3 * t3 + 2 * z5 + z5 = t3 + z5; + z5 = z5 + z5; + z5 = z5 + t3; + + return Fp12_2over3over2_model(my_Fp6(z0,z4,z3),my_Fp6(z2,z1,z5)); +} + +template& modulus> +Fp12_2over3over2_model Fp12_2over3over2_model::mul_by_024(const Fp2_model &ell_0, + const Fp2_model &ell_VW, + const Fp2_model &ell_VV) const +{ + /* OLD: naive implementation + Fp12_2over3over2_model a(my_Fp6(ell_0, my_Fp2::zero(), ell_VV), + my_Fp6(my_Fp2::zero(), ell_VW, my_Fp2::zero())); + + return (*this) * a; + */ + my_Fp2 z0 = this->c0.c0; + my_Fp2 z1 = this->c0.c1; + my_Fp2 z2 = this->c0.c2; + my_Fp2 z3 = this->c1.c0; + my_Fp2 z4 = this->c1.c1; + my_Fp2 z5 = this->c1.c2; + + my_Fp2 x0 = ell_0; + my_Fp2 x2 = ell_VV; + my_Fp2 x4 = ell_VW; + + my_Fp2 t0, t1, t2, s0, T3, T4, D0, D2, D4, S1; + + D0 = z0 * x0; + D2 = z2 * x2; + D4 = z4 * x4; + t2 = z0 + z4; + t1 = z0 + z2; + s0 = z1 + z3 + z5; + + // For z.a_.a_ = z0. + S1 = z1 * x2; + T3 = S1 + D4; + T4 = my_Fp6::non_residue * T3 + D0; + z0 = T4; + + // For z.a_.b_ = z1 + T3 = z5 * x4; + S1 = S1 + T3; + T3 = T3 + D2; + T4 = my_Fp6::non_residue * T3; + T3 = z1 * x0; + S1 = S1 + T3; + T4 = T4 + T3; + z1 = T4; + + // For z.a_.c_ = z2 + t0 = x0 + x2; + T3 = t1 * t0 - D0 - D2; + T4 = z3 * x4; + S1 = S1 + T4; + T3 = T3 + T4; + + // For z.b_.a_ = z3 (z3 needs z2) + t0 = z2 + z4; + z2 = T3; + t1 = x2 + x4; + T3 = t0 * t1 - D2 - D4; + T4 = my_Fp6::non_residue * T3; + T3 = z3 * x0; + S1 = S1 + T3; + T4 = T4 + T3; + z3 = T4; + + // For z.b_.b_ = z4 + T3 = z5 * x2; + S1 = S1 + T3; + T4 = my_Fp6::non_residue * T3; + t0 = x0 + x4; + T3 = t2 * t0 - D0 - D4; + T4 = T4 + T3; + z4 = T4; + + // For z.b_.c_ = z5. + t0 = x0 + x2 + x4; + T3 = s0 * t0 - S1; + z5 = T3; + + return Fp12_2over3over2_model(my_Fp6(z0,z1,z2),my_Fp6(z3,z4,z5)); + +} + +template& modulus, mp_size_t m> +Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const bigint &exponent) +{ + return power >(self, exponent); +} + +template& modulus, mp_size_t m, const bigint& exp_modulus> +Fp12_2over3over2_model operator^(const Fp12_2over3over2_model &self, const Fp_model &exponent) +{ + return self^(exponent.as_bigint()); +} + + +template& modulus> +template +Fp12_2over3over2_model Fp12_2over3over2_model::cyclotomic_exp(const bigint &exponent) const +{ + Fp12_2over3over2_model res = Fp12_2over3over2_model::one(); + + bool found_one = false; + for (long i = m-1; i >= 0; --i) + { + for (long j = GMP_NUMB_BITS - 1; j >= 0; --j) + { + if (found_one) + { + res = res.cyclotomic_squared(); + } + + if (exponent.data[i] & (1ul<& modulus> +std::ostream& operator<<(std::ostream &out, const Fp12_2over3over2_model &el) +{ + out << el.c0 << OUTPUT_SEPARATOR << el.c1; + return out; +} + +template& modulus> +std::istream& operator>>(std::istream &in, Fp12_2over3over2_model &el) +{ + in >> el.c0 >> el.c1; + return in; +} + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v) +{ + out << v.size() << "\n"; + for (const Fp12_2over3over2_model& t : v) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v) +{ + v.clear(); + + size_t s; + in >> s; + + char b; + in.read(&b, 1); + + v.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + Fp12_2over3over2_model el; + in >> el; + v.emplace_back(el); + } + + return in; +} + +} // libsnark +#endif // FP12_2OVER3OVER2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp2.hpp b/src/snark/libsnark/algebra/fields/fp2.hpp new file mode 100644 index 000000000..f07726918 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp2.hpp @@ -0,0 +1,120 @@ +/** @file + ***************************************************************************** + Implementation of arithmetic in the finite field F[p^2]. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP2_HPP_ +#define FP2_HPP_ +#include "algebra/fields/fp.hpp" +#include + +namespace libsnark { + +template& modulus> +class Fp2_model; + +template& modulus> +std::ostream& operator<<(std::ostream &, const Fp2_model &); + +template& modulus> +std::istream& operator>>(std::istream &, Fp2_model &); + +/** + * Arithmetic in the field F[p^3]. + * + * Let p := modulus. This interface provides arithmetic for the extension field + * Fp2 = Fp[U]/(U^2-non_residue), where non_residue is in Fp. + * + * ASSUMPTION: p = 1 (mod 6) + */ +template& modulus> +class Fp2_model { +public: + typedef Fp_model my_Fp; + + static bigint<2*n> euler; // (modulus^2-1)/2 + static size_t s; // modulus^2 = 2^s * t + 1 + static bigint<2*n> t; // with t odd + static bigint<2*n> t_minus_1_over_2; // (t-1)/2 + static my_Fp non_residue; // X^4-non_residue irreducible over Fp; used for constructing Fp2 = Fp[X] / (X^2 - non_residue) + static Fp2_model nqr; // a quadratic nonresidue in Fp2 + static Fp2_model nqr_to_t; // nqr^t + static my_Fp Frobenius_coeffs_c1[2]; // non_residue^((modulus^i-1)/2) for i=0,1 + + my_Fp c0, c1; + Fp2_model() {}; + Fp2_model(const my_Fp& c0, const my_Fp& c1) : c0(c0), c1(c1) {}; + + void clear() { c0.clear(); c1.clear(); } + void print() const { printf("c0/c1:\n"); c0.print(); c1.print(); } + + static Fp2_model zero(); + static Fp2_model one(); + static Fp2_model random_element(); + + bool is_zero() const { return c0.is_zero() && c1.is_zero(); } + bool operator==(const Fp2_model &other) const; + bool operator!=(const Fp2_model &other) const; + + Fp2_model operator+(const Fp2_model &other) const; + Fp2_model operator-(const Fp2_model &other) const; + Fp2_model operator*(const Fp2_model &other) const; + Fp2_model operator-() const; + Fp2_model squared() const; // default is squared_complex + Fp2_model inverse() const; + Fp2_model Frobenius_map(unsigned long power) const; + Fp2_model sqrt() const; // HAS TO BE A SQUARE (else does not terminate) + Fp2_model squared_karatsuba() const; + Fp2_model squared_complex() const; + + template + Fp2_model operator^(const bigint &other) const; + + static size_t size_in_bits() { return 2*my_Fp::size_in_bits(); } + static bigint base_field_char() { return modulus; } + + friend std::ostream& operator<< (std::ostream &out, const Fp2_model &el); + friend std::istream& operator>> (std::istream &in, Fp2_model &el); +}; + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v); + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v); + +template& modulus> +Fp2_model operator*(const Fp_model &lhs, const Fp2_model &rhs); + +template& modulus> +bigint<2*n> Fp2_model::euler; + +template& modulus> +size_t Fp2_model::s; + +template& modulus> +bigint<2*n> Fp2_model::t; + +template& modulus> +bigint<2*n> Fp2_model::t_minus_1_over_2; + +template& modulus> +Fp_model Fp2_model::non_residue; + +template& modulus> +Fp2_model Fp2_model::nqr; + +template& modulus> +Fp2_model Fp2_model::nqr_to_t; + +template& modulus> +Fp_model Fp2_model::Frobenius_coeffs_c1[2]; + +} // libsnark +#include "algebra/fields/fp2.tcc" + +#endif // FP2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp2.tcc b/src/snark/libsnark/algebra/fields/fp2.tcc new file mode 100644 index 000000000..1632a04c7 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp2.tcc @@ -0,0 +1,261 @@ +/** @file + ***************************************************************************** + Implementation of arithmetic in the finite field F[p^2]. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP2_TCC_ +#define FP2_TCC_ + +#include "algebra/fields/field_utils.hpp" + +namespace libsnark { + +template& modulus> +Fp2_model Fp2_model::zero() +{ + return Fp2_model(my_Fp::zero(), my_Fp::zero()); +} + +template& modulus> +Fp2_model Fp2_model::one() +{ + return Fp2_model(my_Fp::one(), my_Fp::zero()); +} + +template& modulus> +Fp2_model Fp2_model::random_element() +{ + Fp2_model r; + r.c0 = my_Fp::random_element(); + r.c1 = my_Fp::random_element(); + + return r; +} + +template& modulus> +bool Fp2_model::operator==(const Fp2_model &other) const +{ + return (this->c0 == other.c0 && this->c1 == other.c1); +} + +template& modulus> +bool Fp2_model::operator!=(const Fp2_model &other) const +{ + return !(operator==(other)); +} + +template& modulus> +Fp2_model Fp2_model::operator+(const Fp2_model &other) const +{ + return Fp2_model(this->c0 + other.c0, + this->c1 + other.c1); +} + +template& modulus> +Fp2_model Fp2_model::operator-(const Fp2_model &other) const +{ + return Fp2_model(this->c0 - other.c0, + this->c1 - other.c1); +} + +template& modulus> +Fp2_model operator*(const Fp_model &lhs, const Fp2_model &rhs) +{ + return Fp2_model(lhs*rhs.c0, + lhs*rhs.c1); +} + +template& modulus> +Fp2_model Fp2_model::operator*(const Fp2_model &other) const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba) */ + const my_Fp + &A = other.c0, &B = other.c1, + &a = this->c0, &b = this->c1; + const my_Fp aA = a * A; + const my_Fp bB = b * B; + + return Fp2_model(aA + non_residue * bB, + (a + b)*(A+B) - aA - bB); +} + +template& modulus> +Fp2_model Fp2_model::operator-() const +{ + return Fp2_model(-this->c0, + -this->c1); +} + +template& modulus> +Fp2_model Fp2_model::squared() const +{ + return squared_complex(); +} + +template& modulus> +Fp2_model Fp2_model::squared_karatsuba() const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Karatsuba squaring) */ + const my_Fp &a = this->c0, &b = this->c1; + const my_Fp asq = a.squared(); + const my_Fp bsq = b.squared(); + + return Fp2_model(asq + non_residue * bsq, + (a + b).squared() - asq - bsq); +} + +template& modulus> +Fp2_model Fp2_model::squared_complex() const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 3 (Complex squaring) */ + const my_Fp &a = this->c0, &b = this->c1; + const my_Fp ab = a * b; + + return Fp2_model((a + b) * (a + non_residue * b) - ab - non_residue * ab, + ab + ab); +} + +template& modulus> +Fp2_model Fp2_model::inverse() const +{ + const my_Fp &a = this->c0, &b = this->c1; + + /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 8 */ + const my_Fp t0 = a.squared(); + const my_Fp t1 = b.squared(); + const my_Fp t2 = t0 - non_residue * t1; + const my_Fp t3 = t2.inverse(); + const my_Fp c0 = a * t3; + const my_Fp c1 = - (b * t3); + + return Fp2_model(c0, c1); +} + +template& modulus> +Fp2_model Fp2_model::Frobenius_map(unsigned long power) const +{ + return Fp2_model(c0, + Frobenius_coeffs_c1[power % 2] * c1); +} + +template& modulus> +Fp2_model Fp2_model::sqrt() const +{ + if (is_zero()) { + return *this; + } + + Fp2_model one = Fp2_model::one(); + + size_t v = Fp2_model::s; + Fp2_model z = Fp2_model::nqr_to_t; + Fp2_model w = (*this)^Fp2_model::t_minus_1_over_2; + Fp2_model x = (*this) * w; + Fp2_model b = x * w; // b = (*this)^t + + + // check if square with euler's criterion + Fp2_model check = b; + for (size_t i = 0; i < v-1; ++i) + { + check = check.squared(); + } + if (check != one) + { + assert_except(0); + } + + + // compute square root with Tonelli--Shanks + // (does not terminate if not a square!) + + while (b != one) + { + size_t m = 0; + Fp2_model b2m = b; + while (b2m != one) + { + /* invariant: b2m = b^(2^m) after entering this loop */ + b2m = b2m.squared(); + m += 1; + } + + int j = v-m-1; + w = z; + while (j > 0) + { + w = w.squared(); + --j; + } // w = z^2^(v-m-1) + + z = w.squared(); + b = b * z; + x = x * w; + v = m; + } + + return x; +} + +template& modulus> +template +Fp2_model Fp2_model::operator^(const bigint &pow) const +{ + return power, m>(*this, pow); +} + +template& modulus> +std::ostream& operator<<(std::ostream &out, const Fp2_model &el) +{ + out << el.c0 << OUTPUT_SEPARATOR << el.c1; + return out; +} + +template& modulus> +std::istream& operator>>(std::istream &in, Fp2_model &el) +{ + in >> el.c0 >> el.c1; + return in; +} + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v) +{ + out << v.size() << "\n"; + for (const Fp2_model& t : v) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v) +{ + v.clear(); + + size_t s; + in >> s; + + char b; + in.read(&b, 1); + + v.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + Fp2_model el; + in >> el; + v.emplace_back(el); + } + + return in; +} + +} // libsnark +#endif // FP2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp6_3over2.hpp b/src/snark/libsnark/algebra/fields/fp6_3over2.hpp new file mode 100644 index 000000000..335d61c53 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp6_3over2.hpp @@ -0,0 +1,104 @@ +/** @file + ***************************************************************************** + Declaration of arithmetic in the finite field F[(p^2)^3] + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP6_3OVER2_HPP_ +#define FP6_3OVER2_HPP_ +#include "algebra/fields/fp.hpp" +#include "algebra/fields/fp2.hpp" +#include + +namespace libsnark { + +template& modulus> +class Fp6_3over2_model; + +template& modulus> +std::ostream& operator<<(std::ostream &, const Fp6_3over2_model &); + +template& modulus> +std::istream& operator>>(std::istream &, Fp6_3over2_model &); + +/** + * Arithmetic in the finite field F[(p^2)^3]. + * + * Let p := modulus. This interface provides arithmetic for the extension field + * Fp6 = Fp2[V]/(V^3-non_residue) where non_residue is in Fp. + * + * ASSUMPTION: p = 1 (mod 6) + */ +template& modulus> +class Fp6_3over2_model { +public: + typedef Fp_model my_Fp; + typedef Fp2_model my_Fp2; + + static my_Fp2 non_residue; + static my_Fp2 Frobenius_coeffs_c1[6]; // non_residue^((modulus^i-1)/3) for i=0,1,2,3,4,5 + static my_Fp2 Frobenius_coeffs_c2[6]; // non_residue^((2*modulus^i-2)/3) for i=0,1,2,3,4,5 + + my_Fp2 c0, c1, c2; + Fp6_3over2_model() {}; + Fp6_3over2_model(const my_Fp2& c0, const my_Fp2& c1, const my_Fp2& c2) : c0(c0), c1(c1), c2(c2) {}; + + void clear() { c0.clear(); c1.clear(); c2.clear(); } + void print() const { printf("c0/c1/c2:\n"); c0.print(); c1.print(); c2.print(); } + + static Fp6_3over2_model zero(); + static Fp6_3over2_model one(); + static Fp6_3over2_model random_element(); + + bool is_zero() const { return c0.is_zero() && c1.is_zero() && c2.is_zero(); } + bool operator==(const Fp6_3over2_model &other) const; + bool operator!=(const Fp6_3over2_model &other) const; + + Fp6_3over2_model operator+(const Fp6_3over2_model &other) const; + Fp6_3over2_model operator-(const Fp6_3over2_model &other) const; + Fp6_3over2_model operator*(const Fp6_3over2_model &other) const; + Fp6_3over2_model operator-() const; + Fp6_3over2_model squared() const; + Fp6_3over2_model inverse() const; + Fp6_3over2_model Frobenius_map(unsigned long power) const; + + static my_Fp2 mul_by_non_residue(const my_Fp2 &elt); + + template + Fp6_3over2_model operator^(const bigint &other) const; + + static bigint base_field_char() { return modulus; } + static size_t extension_degree() { return 6; } + + friend std::ostream& operator<< (std::ostream &out, const Fp6_3over2_model &el); + friend std::istream& operator>> (std::istream &in, Fp6_3over2_model &el); +}; + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v); + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v); + +template& modulus> +Fp6_3over2_model operator*(const Fp_model &lhs, const Fp6_3over2_model &rhs); + +template& modulus> +Fp6_3over2_model operator*(const Fp2_model &lhs, const Fp6_3over2_model &rhs); + +template& modulus> +Fp2_model Fp6_3over2_model::non_residue; + +template& modulus> +Fp2_model Fp6_3over2_model::Frobenius_coeffs_c1[6]; + +template& modulus> +Fp2_model Fp6_3over2_model::Frobenius_coeffs_c2[6]; + +} // libsnark +#include "algebra/fields/fp6_3over2.tcc" + +#endif // FP6_3OVER2_HPP_ diff --git a/src/snark/libsnark/algebra/fields/fp6_3over2.tcc b/src/snark/libsnark/algebra/fields/fp6_3over2.tcc new file mode 100644 index 000000000..f4fffde04 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp6_3over2.tcc @@ -0,0 +1,216 @@ +/** @file + ***************************************************************************** + Implementation of arithmetic in the finite field F[(p^2)^3]. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP6_3OVER2_TCC_ +#define FP6_3OVER2_TCC_ +#include "algebra/fields/field_utils.hpp" + +namespace libsnark { + +template& modulus> +Fp2_model Fp6_3over2_model::mul_by_non_residue(const Fp2_model &elt) +{ + return Fp2_model(non_residue * elt); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::zero() +{ + return Fp6_3over2_model(my_Fp2::zero(), my_Fp2::zero(), my_Fp2::zero()); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::one() +{ + return Fp6_3over2_model(my_Fp2::one(), my_Fp2::zero(), my_Fp2::zero()); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::random_element() +{ + Fp6_3over2_model r; + r.c0 = my_Fp2::random_element(); + r.c1 = my_Fp2::random_element(); + r.c2 = my_Fp2::random_element(); + + return r; +} + +template& modulus> +bool Fp6_3over2_model::operator==(const Fp6_3over2_model &other) const +{ + return (this->c0 == other.c0 && this->c1 == other.c1 && this->c2 == other.c2); +} + +template& modulus> +bool Fp6_3over2_model::operator!=(const Fp6_3over2_model &other) const +{ + return !(operator==(other)); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::operator+(const Fp6_3over2_model &other) const +{ + return Fp6_3over2_model(this->c0 + other.c0, + this->c1 + other.c1, + this->c2 + other.c2); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::operator-(const Fp6_3over2_model &other) const +{ + return Fp6_3over2_model(this->c0 - other.c0, + this->c1 - other.c1, + this->c2 - other.c2); +} + +template& modulus> +Fp6_3over2_model operator*(const Fp_model &lhs, const Fp6_3over2_model &rhs) +{ + return Fp6_3over2_model(lhs*rhs.c0, + lhs*rhs.c1, + lhs*rhs.c2); +} + +template& modulus> +Fp6_3over2_model operator*(const Fp2_model &lhs, const Fp6_3over2_model &rhs) +{ + return Fp6_3over2_model(lhs*rhs.c0, + lhs*rhs.c1, + lhs*rhs.c2); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::operator*(const Fp6_3over2_model &other) const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4 (Karatsuba) */ + + const my_Fp2 &A = other.c0, &B = other.c1, &C = other.c2, + &a = this->c0, &b = this->c1, &c = this->c2; + const my_Fp2 aA = a*A; + const my_Fp2 bB = b*B; + const my_Fp2 cC = c*C; + + return Fp6_3over2_model(aA + Fp6_3over2_model::mul_by_non_residue((b+c)*(B+C)-bB-cC), + (a+b)*(A+B)-aA-bB+Fp6_3over2_model::mul_by_non_residue(cC), + (a+c)*(A+C)-aA+bB-cC); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::operator-() const +{ + return Fp6_3over2_model(-this->c0, + -this->c1, + -this->c2); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::squared() const +{ + /* Devegili OhEig Scott Dahab --- Multiplication and Squaring on Pairing-Friendly Fields.pdf; Section 4 (CH-SQR2) */ + + const my_Fp2 &a = this->c0, &b = this->c1, &c = this->c2; + const my_Fp2 s0 = a.squared(); + const my_Fp2 ab = a*b; + const my_Fp2 s1 = ab + ab; + const my_Fp2 s2 = (a - b + c).squared(); + const my_Fp2 bc = b*c; + const my_Fp2 s3 = bc + bc; + const my_Fp2 s4 = c.squared(); + + return Fp6_3over2_model(s0 + Fp6_3over2_model::mul_by_non_residue(s3), + s1 + Fp6_3over2_model::mul_by_non_residue(s4), + s1 + s2 + s3 - s0 - s4); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::inverse() const +{ + /* From "High-Speed Software Implementation of the Optimal Ate Pairing over Barreto-Naehrig Curves"; Algorithm 17 */ + + const my_Fp2 &a = this->c0, &b = this->c1, &c = this->c2; + const my_Fp2 t0 = a.squared(); + const my_Fp2 t1 = b.squared(); + const my_Fp2 t2 = c.squared(); + const my_Fp2 t3 = a*b; + const my_Fp2 t4 = a*c; + const my_Fp2 t5 = b*c; + const my_Fp2 c0 = t0 - Fp6_3over2_model::mul_by_non_residue(t5); + const my_Fp2 c1 = Fp6_3over2_model::mul_by_non_residue(t2) - t3; + const my_Fp2 c2 = t1 - t4; // typo in paper referenced above. should be "-" as per Scott, but is "*" + const my_Fp2 t6 = (a * c0 + Fp6_3over2_model::mul_by_non_residue((c * c1 + b * c2))).inverse(); + return Fp6_3over2_model(t6 * c0, t6 * c1, t6 * c2); +} + +template& modulus> +Fp6_3over2_model Fp6_3over2_model::Frobenius_map(unsigned long power) const +{ + return Fp6_3over2_model(c0.Frobenius_map(power), + Frobenius_coeffs_c1[power % 6] * c1.Frobenius_map(power), + Frobenius_coeffs_c2[power % 6] * c2.Frobenius_map(power)); +} + +template& modulus> +template +Fp6_3over2_model Fp6_3over2_model::operator^(const bigint &pow) const +{ + return power, m>(*this, pow); +} + +template& modulus> +std::ostream& operator<<(std::ostream &out, const Fp6_3over2_model &el) +{ + out << el.c0 << OUTPUT_SEPARATOR << el.c1 << OUTPUT_SEPARATOR << el.c2; + return out; +} + +template& modulus> +std::istream& operator>>(std::istream &in, Fp6_3over2_model &el) +{ + in >> el.c0 >> el.c1 >> el.c2; + return in; +} + +template& modulus> +std::ostream& operator<<(std::ostream& out, const std::vector > &v) +{ + out << v.size() << "\n"; + for (const Fp6_3over2_model& t : v) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +template& modulus> +std::istream& operator>>(std::istream& in, std::vector > &v) +{ + v.clear(); + + size_t s; + in >> s; + + char b; + in.read(&b, 1); + + v.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + Fp6_3over2_model el; + in >> el; + v.emplace_back(el); + } + + return in; +} + +} // libsnark +#endif // FP6_3_OVER_2_TCC_ diff --git a/src/snark/libsnark/algebra/fields/fp_aux.tcc b/src/snark/libsnark/algebra/fields/fp_aux.tcc new file mode 100644 index 000000000..7f8a3eadf --- /dev/null +++ b/src/snark/libsnark/algebra/fields/fp_aux.tcc @@ -0,0 +1,389 @@ +/** @file + ***************************************************************************** + Assembly code snippets for F[p] finite field arithmetic, used by fp.tcc . + Specific to x86-64, and used only if USE_ASM is defined. + On other architectures or without USE_ASM, fp.tcc uses a portable + C++ implementation instead. + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef FP_AUX_TCC_ +#define FP_AUX_TCC_ + +namespace libsnark { + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + +/* addq is faster than adcq, even if preceded by clc */ +#define ADD_FIRSTADD \ + "movq (%[B]), %%rax \n\t" \ + "addq %%rax, (%[A]) \n\t" + +#define ADD_NEXTADD(ofs) \ + "movq " STR(ofs) "(%[B]), %%rax \n\t" \ + "adcq %%rax, " STR(ofs) "(%[A]) \n\t" + +#define ADD_CMP(ofs) \ + "movq " STR(ofs) "(%[mod]), %%rax \n\t" \ + "cmpq %%rax, " STR(ofs) "(%[A]) \n\t" \ + "jb done%= \n\t" \ + "ja subtract%= \n\t" + +#define ADD_FIRSTSUB \ + "movq (%[mod]), %%rax \n\t" \ + "subq %%rax, (%[A]) \n\t" + +#define ADD_FIRSTSUB \ + "movq (%[mod]), %%rax \n\t" \ + "subq %%rax, (%[A]) \n\t" + +#define ADD_NEXTSUB(ofs) \ + "movq " STR(ofs) "(%[mod]), %%rax \n\t" \ + "sbbq %%rax, " STR(ofs) "(%[A]) \n\t" + +#define SUB_FIRSTSUB \ + "movq (%[B]), %%rax\n\t" \ + "subq %%rax, (%[A])\n\t" + +#define SUB_NEXTSUB(ofs) \ + "movq " STR(ofs) "(%[B]), %%rax\n\t" \ + "sbbq %%rax, " STR(ofs) "(%[A])\n\t" + +#define SUB_FIRSTADD \ + "movq (%[mod]), %%rax\n\t" \ + "addq %%rax, (%[A])\n\t" + +#define SUB_NEXTADD(ofs) \ + "movq " STR(ofs) "(%[mod]), %%rax\n\t" \ + "adcq %%rax, " STR(ofs) "(%[A])\n\t" + +#define MONT_CMP(ofs) \ + "movq " STR(ofs) "(%[M]), %%rax \n\t" \ + "cmpq %%rax, " STR(ofs) "(%[tmp]) \n\t" \ + "jb done%= \n\t" \ + "ja subtract%= \n\t" + +#define MONT_FIRSTSUB \ + "movq (%[M]), %%rax \n\t" \ + "subq %%rax, (%[tmp]) \n\t" + +#define MONT_NEXTSUB(ofs) \ + "movq " STR(ofs) "(%[M]), %%rax \n\t" \ + "sbbq %%rax, " STR(ofs) "(%[tmp]) \n\t" + +/* + The x86-64 Montgomery multiplication here is similar + to Algorithm 2 (CIOS method) in http://eprint.iacr.org/2012/140.pdf + and the PowerPC pseudocode of gmp-ecm library (c) Paul Zimmermann and Alexander Kruppa + (see comments on top of powerpc64/mulredc.m4). +*/ + +#define MONT_PRECOMPUTE \ + "xorq %[cy], %[cy] \n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq 0(%[B]) \n\t" \ + "movq %%rax, %[T0] \n\t" \ + "movq %%rdx, %[T1] # T1:T0 <- A[0] * B[0] \n\t" \ + "mulq %[inv] \n\t" \ + "movq %%rax, %[u] # u <- T0 * inv \n\t" \ + "mulq 0(%[M]) \n\t" \ + "addq %[T0], %%rax \n\t" \ + "adcq %%rdx, %[T1] \n\t" \ + "adcq $0, %[cy] # cy:T1 <- (M[0]*u + T1 * b + T0) / b\n\t" + +#define MONT_FIRSTITER(j) \ + "xorq %[T0], %[T0] \n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq " STR((j*8)) "(%[B]) \n\t" \ + "addq %[T1], %%rax \n\t" \ + "movq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ + "adcq $0, %%rdx \n\t" \ + "movq %%rdx, %[T1] # now T1:tmp[j-1] <-- X[0] * Y[j] + T1\n\t" \ + "movq " STR((j*8)) "(%[M]), %%rax \n\t" \ + "mulq %[u] \n\t" \ + "addq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ + "adcq %[cy], %%rdx \n\t" \ + "adcq $0, %[T0] \n\t" \ + "xorq %[cy], %[cy] \n\t" \ + "addq %%rdx, %[T1] \n\t" \ + "adcq %[T0], %[cy] # cy:T1:tmp[j-1] <---- (X[0] * Y[j] + T1) + (M[j] * u + cy * b) \n\t" + +#define MONT_ITERFIRST(i) \ + "xorq %[cy], %[cy] \n\t" \ + "movq " STR((i*8)) "(%[A]), %%rax \n\t" \ + "mulq 0(%[B]) \n\t" \ + "addq 0(%[tmp]), %%rax \n\t" \ + "adcq 8(%[tmp]), %%rdx \n\t" \ + "adcq $0, %[cy] \n\t" \ + "movq %%rax, %[T0] \n\t" \ + "movq %%rdx, %[T1] # cy:T1:T0 <- A[i] * B[0] + tmp[1] * b + tmp[0]\n\t" \ + "mulq %[inv] \n\t" \ + "movq %%rax, %[u] # u <- T0 * inv\n\t" \ + "mulq 0(%[M]) \n\t" \ + "addq %[T0], %%rax \n\t" \ + "adcq %%rdx, %[T1] \n\t" \ + "adcq $0, %[cy] # cy:T1 <- (M[0]*u + cy * b * b + T1 * b + T0) / b\n\t" + +#define MONT_ITERITER(i, j) \ + "xorq %[T0], %[T0] \n\t" \ + "movq " STR((i*8)) "(%[A]), %%rax \n\t" \ + "mulq " STR((j*8)) "(%[B]) \n\t" \ + "addq %[T1], %%rax \n\t" \ + "movq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ + "adcq $0, %%rdx \n\t" \ + "movq %%rdx, %[T1] # now T1:tmp[j-1] <-- X[i] * Y[j] + T1 \n\t" \ + "movq " STR((j*8)) "(%[M]), %%rax \n\t" \ + "mulq %[u] \n\t" \ + "addq %%rax, " STR(((j-1)*8)) "(%[tmp]) \n\t" \ + "adcq %[cy], %%rdx \n\t" \ + "adcq $0, %[T0] \n\t" \ + "xorq %[cy], %[cy] \n\t" \ + "addq %%rdx, %[T1] \n\t" \ + "adcq %[T0], %[cy] # cy:T1:tmp[j-1] <-- (X[i] * Y[j] + T1) + M[j] * u + cy * b \n\t" \ + "addq " STR(((j+1)*8)) "(%[tmp]), %[T1] \n\t" \ + "adcq $0, %[cy] # cy:T1:tmp[j-1] <-- (X[i] * Y[j] + T1) + M[j] * u + (tmp[j+1] + cy) * b \n\t" + +#define MONT_FINALIZE(j) \ + "movq %[T1], " STR((j*8)) "(%[tmp]) \n\t" \ + "movq %[cy], " STR(((j+1)*8)) "(%[tmp]) \n\t" + +/* + Comba multiplication and squaring routines are based on the + public-domain tomsfastmath library by Tom St Denis + + + + Compared to the above, we save 5-20% of cycles by using careful register + renaming to implement Comba forward operation. + */ + +#define COMBA_3_BY_3_MUL(c0_, c1_, c2_, res_, A_, B_) \ + asm volatile ( \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq 0(%[B]) \n\t" \ + "movq %%rax, 0(%[res]) \n\t" \ + "movq %%rdx, %[c0] \n\t" \ + \ + "xorq %[c1], %[c1] \n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq 8(%[B]) \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + \ + "xorq %[c2], %[c2] \n\t" \ + "movq 8(%[A]), %%rax \n\t" \ + "mulq 0(%[B]) \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "movq %[c0], 8(%[res]) \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + "adcq $0, %[c2] \n\t" \ + \ + "// register renaming (c1, c2, c0)\n\t" \ + "xorq %[c0], %[c0] \n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq 16(%[B]) \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + \ + "movq 8(%[A]), %%rax \n\t" \ + "mulq 8(%[B]) \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + \ + "movq 16(%[A]), %%rax \n\t" \ + "mulq 0(%[B]) \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "movq %[c1], 16(%[res]) \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + \ + "// register renaming (c2, c0, c1)\n\t" \ + "xorq %[c1], %[c1] \n\t" \ + "movq 8(%[A]), %%rax \n\t" \ + "mulq 16(%[B]) \n\t" \ + "addq %%rax, %[c2] \n\t" \ + "adcq %%rdx, %[c0] \n\t" \ + "adcq $0, %[c1] \n\t" \ + \ + "movq 16(%[A]), %%rax \n\t" \ + "mulq 8(%[B]) \n\t" \ + "addq %%rax, %[c2] \n\t" \ + "movq %[c2], 24(%[res]) \n\t" \ + "adcq %%rdx, %[c0] \n\t" \ + "adcq $0, %[c1] \n\t" \ + \ + "// register renaming (c0, c1, c2)\n\t" \ + "xorq %[c2], %[c2] \n\t" \ + "movq 16(%[A]), %%rax \n\t" \ + "mulq 16(%[B]) \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "movq %[c0], 32(%[res]) \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + "movq %[c1], 40(%[res]) \n\t" \ + : [c0] "=&r" (c0_), [c1] "=&r" (c1_), [c2] "=&r" (c2_) \ + : [res] "r" (res_), [A] "r" (A_), [B] "r" (B_) \ + : "%rax", "%rdx", "cc", "memory") + +#define COMBA_3_BY_3_SQR(c0_, c1_, c2_, res_, A_) \ + asm volatile ( \ + "xorq %[c1], %[c1] \n\t" \ + "xorq %[c2], %[c2] \n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq %%rax \n\t" \ + "movq %%rax, 0(%[res]) \n\t" \ + "movq %%rdx, %[c0] \n\t" \ + \ + "movq 0(%[A]), %%rax \n\t" \ + "mulq 8(%[A]) \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "movq %[c0], 8(%[res]) \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + "adcq $0, %[c2] \n\t" \ + \ + "// register renaming (c1, c2, c0)\n\t" \ + "movq 0(%[A]), %%rax \n\t" \ + "xorq %[c0], %[c0] \n\t" \ + "mulq 16(%[A]) \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + \ + "movq 8(%[A]), %%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax, %[c1] \n\t" \ + "movq %[c1], 16(%[res]) \n\t" \ + "adcq %%rdx, %[c2] \n\t" \ + "adcq $0, %[c0] \n\t" \ + \ + "// register renaming (c2, c0, c1)\n\t" \ + "movq 8(%[A]), %%rax \n\t" \ + "xorq %[c1], %[c1] \n\t" \ + "mulq 16(%[A]) \n\t" \ + "addq %%rax, %[c2] \n\t" \ + "adcq %%rdx, %[c0] \n\t" \ + "adcq $0, %[c1] \n\t" \ + "addq %%rax, %[c2] \n\t" \ + "movq %[c2], 24(%[res]) \n\t" \ + "adcq %%rdx, %[c0] \n\t" \ + "adcq $0, %[c1] \n\t" \ + \ + "// register renaming (c0, c1, c2)\n\t" \ + "movq 16(%[A]), %%rax \n\t" \ + "mulq %%rax \n\t" \ + "addq %%rax, %[c0] \n\t" \ + "movq %[c0], 32(%[res]) \n\t" \ + "adcq %%rdx, %[c1] \n\t" \ + "movq %[c1], 40(%[res]) \n\t" \ + \ + : [c0] "=&r" (c0_), [c1] "=&r" (c1_), [c2] "=&r" (c2_) \ + : [res] "r" (res_), [A] "r" (A_) \ + : "%rax", "%rdx", "cc", "memory") + +/* + The Montgomery reduction here is based on Algorithm 14.32 in + Handbook of Applied Cryptography + . + */ +#define REDUCE_6_LIMB_PRODUCT(k_, tmp1_, tmp2_, tmp3_, inv_, res_, mod_) \ + __asm__ volatile \ + ("///////////////////////////////////\n\t" \ + "movq 0(%[res]), %%rax \n\t" \ + "mulq %[modprime] \n\t" \ + "movq %%rax, %[k] \n\t" \ + \ + "movq (%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "movq %%rax, %[tmp1] \n\t" \ + "movq %%rdx, %[tmp2] \n\t" \ + \ + "xorq %[tmp3], %[tmp3] \n\t" \ + "movq 8(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp1], 0(%[res]) \n\t" \ + "adcq %%rax, %[tmp2] \n\t" \ + "adcq %%rdx, %[tmp3] \n\t" \ + \ + "xorq %[tmp1], %[tmp1] \n\t" \ + "movq 16(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp2], 8(%[res]) \n\t" \ + "adcq %%rax, %[tmp3] \n\t" \ + "adcq %%rdx, %[tmp1] \n\t" \ + \ + "addq %[tmp3], 16(%[res]) \n\t" \ + "adcq %[tmp1], 24(%[res]) \n\t" \ + "adcq $0, 32(%[res]) \n\t" \ + "adcq $0, 40(%[res]) \n\t" \ + \ + "///////////////////////////////////\n\t" \ + "movq 8(%[res]), %%rax \n\t" \ + "mulq %[modprime] \n\t" \ + "movq %%rax, %[k] \n\t" \ + \ + "movq (%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "movq %%rax, %[tmp1] \n\t" \ + "movq %%rdx, %[tmp2] \n\t" \ + \ + "xorq %[tmp3], %[tmp3] \n\t" \ + "movq 8(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp1], 8(%[res]) \n\t" \ + "adcq %%rax, %[tmp2] \n\t" \ + "adcq %%rdx, %[tmp3] \n\t" \ + \ + "xorq %[tmp1], %[tmp1] \n\t" \ + "movq 16(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp2], 16(%[res]) \n\t" \ + "adcq %%rax, %[tmp3] \n\t" \ + "adcq %%rdx, %[tmp1] \n\t" \ + \ + "addq %[tmp3], 24(%[res]) \n\t" \ + "adcq %[tmp1], 32(%[res]) \n\t" \ + "adcq $0, 40(%[res]) \n\t" \ + \ + "///////////////////////////////////\n\t" \ + "movq 16(%[res]), %%rax \n\t" \ + "mulq %[modprime] \n\t" \ + "movq %%rax, %[k] \n\t" \ + \ + "movq (%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "movq %%rax, %[tmp1] \n\t" \ + "movq %%rdx, %[tmp2] \n\t" \ + \ + "xorq %[tmp3], %[tmp3] \n\t" \ + "movq 8(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp1], 16(%[res]) \n\t" \ + "adcq %%rax, %[tmp2] \n\t" \ + "adcq %%rdx, %[tmp3] \n\t" \ + \ + "xorq %[tmp1], %[tmp1] \n\t" \ + "movq 16(%[mod]), %%rax \n\t" \ + "mulq %[k] \n\t" \ + "addq %[tmp2], 24(%[res]) \n\t" \ + "adcq %%rax, %[tmp3] \n\t" \ + "adcq %%rdx, %[tmp1] \n\t" \ + \ + "addq %[tmp3], 32(%[res]) \n\t" \ + "adcq %[tmp1], 40(%[res]) \n\t" \ + : [k] "=&r" (k_), [tmp1] "=&r" (tmp1_), [tmp2] "=&r" (tmp2_), [tmp3] "=&r" (tmp3_) \ + : [modprime] "r" (inv_), [res] "r" (res_), [mod] "r" (mod_) \ + : "%rax", "%rdx", "cc", "memory") + +} // libsnark +#endif // FP_AUX_TCC_ diff --git a/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp b/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp new file mode 100644 index 000000000..d2da59e73 --- /dev/null +++ b/src/snark/libsnark/algebra/fields/tests/test_bigint.cpp @@ -0,0 +1,97 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/fields/bigint.hpp" + +#include + +using namespace libsnark; + +TEST(algebra, bigint) +{ + static_assert(ULONG_MAX == 0xFFFFFFFFFFFFFFFFul, "unsigned long not 64-bit"); + static_assert(GMP_NUMB_BITS == 64, "GMP limb not 64-bit"); + + const char *b1_decimal = "76749407"; + const char *b2_decimal = "435020359732196472065729437602"; + const char *b3_decimal = "33387554642372758038536799358397002014"; + const char *b2_binary = "0000000000000000000000000000010101111101101000000110100001011010" + "1101101010001001000001101000101000100110011001110001111110100010"; + + bigint<1> b0 = bigint<1>(0ul); + bigint<1> b1 = bigint<1>(b1_decimal); + bigint<2> b2 = bigint<2>(b2_decimal); + + EXPECT_EQ(b0.as_ulong(), 0ul); + EXPECT_TRUE(b0.is_zero()); + EXPECT_EQ(b1.as_ulong(), 76749407ul); + EXPECT_FALSE(b1.is_zero()); + EXPECT_EQ(b2.as_ulong(), 15747124762497195938ul); + EXPECT_FALSE(b2.is_zero()); + EXPECT_NE(b0, b1); + EXPECT_FALSE(b0 == b1); + + EXPECT_EQ(b2.max_bits(), 128); + EXPECT_EQ(b2.num_bits(), 99); + for (size_t i = 0; i < 128; i++) { + EXPECT_EQ(b2.test_bit(i), (b2_binary[127-i] == '1')); + } + + bigint<3> b3 = b2 * b1; + + EXPECT_EQ(b3, bigint<3>(b3_decimal)); + EXPECT_FALSE(b3.is_zero()); + + bigint<3> b3a { b3 }; + EXPECT_EQ(b3a, bigint<3>(b3_decimal)); + EXPECT_EQ(b3a, b3); + EXPECT_FALSE(b3a.is_zero()); + + mpz_t m3; + mpz_init(m3); + b3.to_mpz(m3); + bigint<3> b3b { m3 }; + EXPECT_EQ(b3b, b3); + + bigint<2> quotient; + bigint<2> remainder; + bigint<3>::div_qr(quotient, remainder, b3, b2); + EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS); + EXPECT_EQ(quotient.as_ulong(), b1.as_ulong()); + bigint<1> b1inc = bigint<1>("76749408"); + bigint<1> b1a = quotient.shorten(b1inc, "test"); + EXPECT_EQ(b1a, b1); + EXPECT_TRUE(remainder.is_zero()); + remainder.limit(b2, "test"); + + EXPECT_THROW((void)(quotient.shorten(b1, "test")), std::domain_error); + EXPECT_THROW(remainder.limit(remainder, "test"), std::domain_error); + + bigint<1> br = bigint<1>("42"); + b3 += br; + EXPECT_NE(b3, b3a); + EXPECT_GT(b3, b3a); + EXPECT_FALSE(b3a > b3); + + bigint<3>::div_qr(quotient, remainder, b3, b2); + EXPECT_LT(quotient.num_bits(), GMP_NUMB_BITS); + EXPECT_EQ(quotient.as_ulong(), b1.as_ulong()); + EXPECT_LT(remainder.num_bits(), GMP_NUMB_BITS); + EXPECT_EQ(remainder.as_ulong(), 42); + + b3a.clear(); + EXPECT_TRUE(b3a.is_zero()); + EXPECT_EQ(b3a.num_bits(), 0); + EXPECT_FALSE(b3.is_zero()); + + bigint<4> bx = bigint<4>().randomize(); + bigint<4> by = bigint<4>().randomize(); + EXPECT_FALSE(bx == by); + + // TODO: test serialization +} + diff --git a/src/snark/libsnark/algebra/fields/tests/test_fields.cpp b/src/snark/libsnark/algebra/fields/tests/test_fields.cpp new file mode 100644 index 000000000..969800d8b --- /dev/null +++ b/src/snark/libsnark/algebra/fields/tests/test_fields.cpp @@ -0,0 +1,191 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include "common/profiling.hpp" +#ifdef CURVE_BN128 +#include "algebra/curves/bn128/bn128_pp.hpp" +#endif +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +#include "algebra/fields/fp6_3over2.hpp" +#include "algebra/fields/fp12_2over3over2.hpp" + +#include + +using namespace libsnark; + +template +void test_field() +{ + bigint<1> rand1 = bigint<1>("76749407"); + bigint<1> rand2 = bigint<1>("44410867"); + bigint<1> randsum = bigint<1>("121160274"); + + FieldT zero = FieldT::zero(); + FieldT one = FieldT::one(); + FieldT a = FieldT::random_element(); + FieldT a_ser; + a_ser = reserialize(a); + EXPECT_EQ(a_ser, a); + + FieldT b = FieldT::random_element(); + FieldT c = FieldT::random_element(); + FieldT d = FieldT::random_element(); + + EXPECT_NE(a, zero); + EXPECT_NE(a, one); + + EXPECT_EQ(a * a, a.squared()); + EXPECT_EQ((a + b).squared(), a.squared() + a*b + b*a + b.squared()); + EXPECT_EQ((a + b)*(c + d), a*c + a*d + b*c + b*d); + EXPECT_EQ(a - b, a + (-b)); + EXPECT_EQ(a - b, (-b) + a); + + EXPECT_EQ((a ^ rand1) * (a ^ rand2), (a^randsum)); + + EXPECT_EQ(a * a.inverse(), one); + EXPECT_EQ((a + b) * c.inverse(), a * c.inverse() + (b.inverse() * c).inverse()); + +} + +template +void test_sqrt() +{ + for (size_t i = 0; i < 100; ++i) + { + FieldT a = FieldT::random_element(); + FieldT asq = a.squared(); + EXPECT_TRUE(asq.sqrt() == a || asq.sqrt() == -a); + } +} + +template +void test_two_squarings() +{ + FieldT a = FieldT::random_element(); + EXPECT_EQ(a.squared(), a * a); + EXPECT_EQ(a.squared(), a.squared_complex()); + EXPECT_EQ(a.squared(), a.squared_karatsuba()); +} + +template +void test_Frobenius() +{ + FieldT a = FieldT::random_element(); + EXPECT_EQ(a.Frobenius_map(0), a); + FieldT a_q = a ^ FieldT::base_field_char(); + for (size_t power = 1; power < 10; ++power) + { + const FieldT a_qi = a.Frobenius_map(power); + EXPECT_EQ(a_qi, a_q); + + a_q = a_q ^ FieldT::base_field_char(); + } +} + +template +void test_unitary_inverse() +{ + EXPECT_EQ(FieldT::extension_degree() % 2, 0); + FieldT a = FieldT::random_element(); + FieldT aqcubed_minus1 = a.Frobenius_map(FieldT::extension_degree()/2) * a.inverse(); + EXPECT_EQ(aqcubed_minus1.inverse(), aqcubed_minus1.unitary_inverse()); +} + +template +void test_all_fields() +{ + test_field >(); + test_field >(); + test_field >(); + test_field >(); + + test_sqrt >(); + test_sqrt >(); + test_sqrt >(); + + test_Frobenius >(); + test_Frobenius >(); + + test_unitary_inverse >(); +} + +template +void test_Fp4_tom_cook() +{ + typedef typename Fp4T::my_Fp FieldT; + for (size_t i = 0; i < 100; ++i) + { + const Fp4T a = Fp4T::random_element(); + const Fp4T b = Fp4T::random_element(); + const Fp4T correct_res = a * b; + + Fp4T res; + + const FieldT + &a0 = a.c0.c0, + &a1 = a.c1.c0, + &a2 = a.c0.c1, + &a3 = a.c1.c1; + + const FieldT + &b0 = b.c0.c0, + &b1 = b.c1.c0, + &b2 = b.c0.c1, + &b3 = b.c1.c1; + + FieldT + &c0 = res.c0.c0, + &c1 = res.c1.c0, + &c2 = res.c0.c1, + &c3 = res.c1.c1; + + const FieldT v0 = a0 * b0; + const FieldT v1 = (a0 + a1 + a2 + a3) * (b0 + b1 + b2 + b3); + const FieldT v2 = (a0 - a1 + a2 - a3) * (b0 - b1 + b2 - b3); + const FieldT v3 = (a0 + FieldT(2)*a1 + FieldT(4)*a2 + FieldT(8)*a3) * (b0 + FieldT(2)*b1 + FieldT(4)*b2 + FieldT(8)*b3); + const FieldT v4 = (a0 - FieldT(2)*a1 + FieldT(4)*a2 - FieldT(8)*a3) * (b0 - FieldT(2)*b1 + FieldT(4)*b2 - FieldT(8)*b3); + const FieldT v5 = (a0 + FieldT(3)*a1 + FieldT(9)*a2 + FieldT(27)*a3) * (b0 + FieldT(3)*b1 + FieldT(9)*b2 + FieldT(27)*b3); + const FieldT v6 = a3 * b3; + + const FieldT beta = Fp4T::non_residue; + + c0 = v0 + beta*(FieldT(4).inverse()*v0 - FieldT(6).inverse()*(v1 + v2) + FieldT(24).inverse() * (v3 + v4) - FieldT(5) * v6); + c1 = - FieldT(3).inverse()*v0 + v1 - FieldT(2).inverse()*v2 - FieldT(4).inverse()*v3 + FieldT(20).inverse() * v4 + FieldT(30).inverse() * v5 - FieldT(12) * v6 + beta * ( - FieldT(12).inverse() * (v0 - v1) + FieldT(24).inverse()*(v2 - v3) - FieldT(120).inverse() * (v4 - v5) - FieldT(3) * v6); + c2 = - (FieldT(5)*(FieldT(4).inverse()))* v0 + (FieldT(2)*(FieldT(3).inverse()))*(v1 + v2) - FieldT(24).inverse()*(v3 + v4) + FieldT(4)*v6 + beta*v6; + c3 = FieldT(12).inverse() * (FieldT(5)*v0 - FieldT(7)*v1) - FieldT(24).inverse()*(v2 - FieldT(7)*v3 + v4 + v5) + FieldT(15)*v6; + + EXPECT_EQ(res, correct_res); + + // {v0, v3, v4, v5} + const FieldT u = (FieldT::one() - beta).inverse(); + EXPECT_EQ(v0, u * c0 + beta * u * c2 - beta * u * FieldT(2).inverse() * v1 - beta * u * FieldT(2).inverse() * v2 + beta * v6); + EXPECT_EQ(v3, - FieldT(15) * u * c0 - FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 - FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v1 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v2 + - FieldT(3) * (-FieldT(16) + beta) * v6); + EXPECT_EQ(v4, - FieldT(15) * u * c0 + FieldT(30) * u * c1 - FieldT(3) * (FieldT(4) + beta) * u * c2 + FieldT(6) * (FieldT(4) + beta) * u * c3 + (FieldT(24) - FieldT(3) * beta * FieldT(2).inverse()) * u * v2 + (-FieldT(8) + beta * FieldT(2).inverse()) * u * v1 + - FieldT(3) * (-FieldT(16) + beta) * v6); + EXPECT_EQ(v5, - FieldT(80) * u * c0 - FieldT(240) * u * c1 - FieldT(8) * (FieldT(9) + beta) * u * c2 - FieldT(24) * (FieldT(9) + beta) * u * c3 - FieldT(2) * (-FieldT(81) + beta) * u * v1 + (-FieldT(81) + beta) * u * v2 + - FieldT(8) * (-FieldT(81) + beta) * v6); + + // c0 + beta c2 - (beta v1)/2 - (beta v2)/ 2 - (-1 + beta) beta v6, + // -15 c0 - 30 c1 - 3 (4 + beta) c2 - 6 (4 + beta) c3 + (24 - (3 beta)/2) v1 + (-8 + beta/2) v2 + 3 (-16 + beta) (-1 + beta) v6, + // -15 c0 + 30 c1 - 3 (4 + beta) c2 + 6 (4 + beta) c3 + (-8 + beta/2) v1 + (24 - (3 beta)/2) v2 + 3 (-16 + beta) (-1 + beta) v6, + // -80 c0 - 240 c1 - 8 (9 + beta) c2 - 24 (9 + beta) c3 - 2 (-81 + beta) v1 + (-81 + beta) v2 + 8 (-81 + beta) (-1 + beta) v6 + } +} + +TEST(algebra, fields) +{ + alt_bn128_pp::init_public_params(); + test_field(); + test_Frobenius(); + test_all_fields(); + +#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled + bn128_pp::init_public_params(); + test_field >(); + test_field >(); +#endif +} diff --git a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp new file mode 100644 index 000000000..902423134 --- /dev/null +++ b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.hpp @@ -0,0 +1,84 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for: + - a knowledge commitment, and + - a knowledge commitment vector. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef KNOWLEDGE_COMMITMENT_HPP_ +#define KNOWLEDGE_COMMITMENT_HPP_ + +#include "algebra/fields/fp.hpp" +#include "common/data_structures/sparse_vector.hpp" + +namespace libsnark { + +/********************** Knowledge commitment *********************************/ + +/** + * A knowledge commitment is a pair (g,h) where g is in T1 and h in T2, + * and T1 and T2 are groups (written additively). + * + * Such pairs form a group by defining: + * - "zero" = (0,0) + * - "one" = (1,1) + * - a * (g,h) + b * (g',h') := ( a * g + b * g', a * h + b * h'). + */ +template +struct knowledge_commitment { + + T1 g; + T2 h; + + knowledge_commitment() = default; + knowledge_commitment(const knowledge_commitment &other) = default; + knowledge_commitment(knowledge_commitment &&other) = default; + knowledge_commitment(const T1 &g, const T2 &h); + + knowledge_commitment& operator=(const knowledge_commitment &other) = default; + knowledge_commitment& operator=(knowledge_commitment &&other) = default; + knowledge_commitment operator+(const knowledge_commitment &other) const; + + bool is_zero() const; + bool operator==(const knowledge_commitment &other) const; + bool operator!=(const knowledge_commitment &other) const; + + static knowledge_commitment zero(); + static knowledge_commitment one(); + + void print() const; + + static size_t size_in_bits(); +}; + +template +knowledge_commitment operator*(const bigint &lhs, const knowledge_commitment &rhs); + +template &modulus_p> +knowledge_commitment operator*(const Fp_model &lhs, const knowledge_commitment &rhs); + +template +std::ostream& operator<<(std::ostream& out, const knowledge_commitment &kc); + +template +std::istream& operator>>(std::istream& in, knowledge_commitment &kc); + +/******************** Knowledge commitment vector ****************************/ + +/** + * A knowledge commitment vector is a sparse vector of knowledge commitments. + */ +template +using knowledge_commitment_vector = sparse_vector >; + +} // libsnark + +#include "algebra/knowledge_commitment/knowledge_commitment.tcc" + +#endif // KNOWLEDGE_COMMITMENT_HPP_ diff --git a/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc new file mode 100644 index 000000000..15b2926c8 --- /dev/null +++ b/src/snark/libsnark/algebra/knowledge_commitment/knowledge_commitment.tcc @@ -0,0 +1,111 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for: + - a knowledge commitment, and + - a knowledge commitment vector. + + See knowledge_commitment.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef KNOWLEDGE_COMMITMENT_TCC_ +#define KNOWLEDGE_COMMITMENT_TCC_ + +namespace libsnark { + +template +knowledge_commitment::knowledge_commitment(const T1 &g, const T2 &h) : + g(g), h(h) +{ +} + +template +knowledge_commitment knowledge_commitment::zero() +{ + return knowledge_commitment(T1::zero(), T2::zero()); +} + +template +knowledge_commitment knowledge_commitment::one() +{ + return knowledge_commitment(T1::one(), T2::one()); +} + +template +knowledge_commitment knowledge_commitment::operator+(const knowledge_commitment &other) const +{ + return knowledge_commitment(this->g + other.g, + this->h + other.h); +} + +template +bool knowledge_commitment::is_zero() const +{ + return (g.is_zero() && h.is_zero()); +} + +template +bool knowledge_commitment::operator==(const knowledge_commitment &other) const +{ + return (this->g == other.g && + this->h == other.h); +} + +template +bool knowledge_commitment::operator!=(const knowledge_commitment &other) const +{ + return !((*this) == other); +} + +template +knowledge_commitment operator*(const bigint &lhs, const knowledge_commitment &rhs) +{ + return knowledge_commitment(lhs * rhs.g, + lhs * rhs.h); +} + +template &modulus_p> +knowledge_commitment operator*(const Fp_model &lhs, const knowledge_commitment &rhs) +{ + return (lhs.as_bigint()) * rhs; +} + +template +void knowledge_commitment::print() const +{ + printf("knowledge_commitment.g:\n"); + g.print(); + printf("knowledge_commitment.h:\n"); + h.print(); +} + +template +size_t knowledge_commitment::size_in_bits() +{ + return T1::size_in_bits() + T2::size_in_bits(); +} + +template +std::ostream& operator<<(std::ostream& out, const knowledge_commitment &kc) +{ + out << kc.g << OUTPUT_SEPARATOR << kc.h; + return out; +} + +template +std::istream& operator>>(std::istream& in, knowledge_commitment &kc) +{ + in >> kc.g; + consume_OUTPUT_SEPARATOR(in); + in >> kc.h; + return in; +} + +} // libsnark + +#endif // KNOWLEDGE_COMMITMENT_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp new file mode 100644 index 000000000..27e48f821 --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.hpp @@ -0,0 +1,55 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef KC_MULTIEXP_HPP_ +#define KC_MULTIEXP_HPP_ + +/* + Split out from multiexp to prevent cyclical + dependencies. I.e. previously multiexp depended on + knowledge_commitment, which depended on sparse_vector, which + depended on multiexp (to do accumulate). + + Will probably go away in more general exp refactoring. +*/ + +#include "algebra/knowledge_commitment/knowledge_commitment.hpp" + +namespace libsnark { + +template +knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment &base, + const bigint &scalar, const size_t scalar_bits); + +template +knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, + const size_t min_idx, + const size_t max_idx, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp=false); + +template +void kc_batch_to_special(std::vector > &vec); + +template +knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, + const size_t T1_window, + const size_t T2_window, + const window_table &T1_table, + const window_table &T2_table, + const FieldT &T1_coeff, + const FieldT &T2_coeff, + const std::vector &v, + const size_t suggested_num_chunks); + +} // libsnark + +#include "algebra/scalar_multiplication/kc_multiexp.tcc" + +#endif // KC_MULTIEXP_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc new file mode 100644 index 000000000..e9c08d4bc --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/kc_multiexp.tcc @@ -0,0 +1,274 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef KC_MULTIEXP_TCC_ +#define KC_MULTIEXP_TCC_ + +namespace libsnark { + +template +knowledge_commitment opt_window_wnaf_exp(const knowledge_commitment &base, + const bigint &scalar, const size_t scalar_bits) +{ + return knowledge_commitment(opt_window_wnaf_exp(base.g, scalar, scalar_bits), + opt_window_wnaf_exp(base.h, scalar, scalar_bits)); +} + +template +knowledge_commitment kc_multi_exp_with_mixed_addition(const knowledge_commitment_vector &vec, + const size_t min_idx, + const size_t max_idx, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp) +{ + enter_block("Process scalar vector"); + auto index_it = std::lower_bound(vec.indices.begin(), vec.indices.end(), min_idx); + const size_t offset = index_it - vec.indices.begin(); + + auto value_it = vec.values.begin() + offset; + + const FieldT zero = FieldT::zero(); + const FieldT one = FieldT::one(); + + std::vector p; + std::vector > g; + + knowledge_commitment acc = knowledge_commitment::zero(); + + size_t num_skip = 0; + size_t num_add = 0; + size_t num_other = 0; + + const size_t scalar_length = std::distance(scalar_start, scalar_end); + + while (index_it != vec.indices.end() && *index_it < max_idx) + { + const size_t scalar_position = (*index_it) - min_idx; + assert(scalar_position < scalar_length); + + const FieldT scalar = *(scalar_start + scalar_position); + + if (scalar == zero) + { + // do nothing + ++num_skip; + } + else if (scalar == one) + { +#ifdef USE_MIXED_ADDITION + acc.g = acc.g.mixed_add(value_it->g); + acc.h = acc.h.mixed_add(value_it->h); +#else + acc.g = acc.g + value_it->g; + acc.h = acc.h + value_it->h; +#endif + ++num_add; + } + else + { + p.emplace_back(scalar); + g.emplace_back(*value_it); + ++num_other; + } + + ++index_it; + ++value_it; + } + + //print_indent(); printf("* Elements of w skipped: %zu (%0.2f%%)\n", num_skip, 100.*num_skip/(num_skip+num_add+num_other)); + //print_indent(); printf("* Elements of w processed with special addition: %zu (%0.2f%%)\n", num_add, 100.*num_add/(num_skip+num_add+num_other)); + //print_indent(); printf("* Elements of w remaining: %zu (%0.2f%%)\n", num_other, 100.*num_other/(num_skip+num_add+num_other)); + leave_block("Process scalar vector"); + + return acc + multi_exp, FieldT>(g.begin(), g.end(), p.begin(), p.end(), chunks, use_multiexp); +} + +template +void kc_batch_to_special(std::vector > &vec) +{ + enter_block("Batch-convert knowledge-commitments to special form"); + + std::vector g_vec; + g_vec.reserve(vec.size()); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].g.is_zero()) + { + g_vec.emplace_back(vec[i].g); + } + } + + batch_to_special_all_non_zeros(g_vec); + auto g_it = g_vec.begin(); + T1 T1_zero_special = T1::zero(); + T1_zero_special.to_special(); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].g.is_zero()) + { + vec[i].g = *g_it; + ++g_it; + } + else + { + vec[i].g = T1_zero_special; + } + } + + g_vec.clear(); + + std::vector h_vec; + h_vec.reserve(vec.size()); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].h.is_zero()) + { + h_vec.emplace_back(vec[i].h); + } + } + + batch_to_special_all_non_zeros(h_vec); + auto h_it = h_vec.begin(); + T2 T2_zero_special = T2::zero(); + T2_zero_special.to_special(); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].h.is_zero()) + { + vec[i].h = *h_it; + ++h_it; + } + else + { + vec[i].h = T2_zero_special; + } + } + + g_vec.clear(); + + leave_block("Batch-convert knowledge-commitments to special form"); +} + +template +knowledge_commitment_vector kc_batch_exp_internal(const size_t scalar_size, + const size_t T1_window, + const size_t T2_window, + const window_table &T1_table, + const window_table &T2_table, + const FieldT &T1_coeff, + const FieldT &T2_coeff, + const std::vector &v, + const size_t start_pos, + const size_t end_pos, + const size_t expected_size) +{ + knowledge_commitment_vector res; + + res.values.reserve(expected_size); + res.indices.reserve(expected_size); + + for (size_t pos = start_pos; pos != end_pos; ++pos) + { + if (!v[pos].is_zero()) + { + res.values.emplace_back(knowledge_commitment(windowed_exp(scalar_size, T1_window, T1_table, T1_coeff * v[pos]), + windowed_exp(scalar_size, T2_window, T2_table, T2_coeff * v[pos]))); + res.indices.emplace_back(pos); + } + } + + return res; +} + +template +knowledge_commitment_vector kc_batch_exp(const size_t scalar_size, + const size_t T1_window, + const size_t T2_window, + const window_table &T1_table, + const window_table &T2_table, + const FieldT &T1_coeff, + const FieldT &T2_coeff, + const std::vector &v, + const size_t suggested_num_chunks) +{ + knowledge_commitment_vector res; + res.domain_size_ = v.size(); + + size_t nonzero = 0; + for (size_t i = 0; i < v.size(); ++i) + { + nonzero += (v[i].is_zero() ? 0 : 1); + } + + const size_t num_chunks = std::max((size_t)1, std::min(nonzero, suggested_num_chunks)); + + if (!inhibit_profiling_info) + { + print_indent(); printf("Non-zero coordinate count: %zu/%zu (%0.2f%%)\n", nonzero, v.size(), 100.*nonzero/v.size()); + } + + std::vector > tmp(num_chunks); + std::vector chunk_pos(num_chunks+1); + + const size_t chunk_size = nonzero / num_chunks; + const size_t last_chunk = nonzero - chunk_size * (num_chunks - 1); + + chunk_pos[0] = 0; + + size_t cnt = 0; + size_t chunkno = 1; + + for (size_t i = 0; i < v.size(); ++i) + { + cnt += (v[i].is_zero() ? 0 : 1); + if (cnt == chunk_size && chunkno < num_chunks) + { + chunk_pos[chunkno] = i; + cnt = 0; + ++chunkno; + } + } + + chunk_pos[num_chunks] = v.size(); + +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < num_chunks; ++i) + { + tmp[i] = kc_batch_exp_internal(scalar_size, T1_window, T2_window, T1_table, T2_table, T1_coeff, T2_coeff, v, + chunk_pos[i], chunk_pos[i+1], i == num_chunks - 1 ? last_chunk : chunk_size); +#ifdef USE_MIXED_ADDITION + kc_batch_to_special(tmp[i].values); +#endif + } + + if (num_chunks == 1) + { + tmp[0].domain_size_ = v.size(); + return tmp[0]; + } + else + { + for (size_t i = 0; i < num_chunks; ++i) + { + res.values.insert(res.values.end(), tmp[i].values.begin(), tmp[i].values.end()); + res.indices.insert(res.indices.end(), tmp[i].indices.begin(), tmp[i].indices.end()); + } + return res; + } +} + +} // libsnark + +#endif // KC_MULTIEXP_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp new file mode 100644 index 000000000..eaf72d61f --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.hpp @@ -0,0 +1,110 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for multi-exponentiation routines. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MULTIEXP_HPP_ +#define MULTIEXP_HPP_ + +namespace libsnark { + +/** + * Naive multi-exponentiation individually multiplies each base by the + * corresponding scalar and adds up the results. + */ +template +T naive_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end); + +template +T naive_plain_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end); + +/** + * Naive multi-exponentiation uses a variant of the Bos-Coster algorithm [1], + * and implementation suggestions from [2]. + * + * [1] = Bos and Coster, "Addition chain heuristics", CRYPTO '89 + * [2] = Bernstein, Duif, Lange, Schwabe, and Yang, "High-speed high-security signatures", CHES '11 + */ +template +T multi_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp=false); + + +/** + * A variant of multi_exp that takes advantage of the method mixed_add (instead of the operator '+'). + */ +template +T multi_exp_with_mixed_addition(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp); + +/** + * A window table stores window sizes for different instance sizes for fixed-base multi-scalar multiplications. + */ +template +using window_table = std::vector >; + +/** + * Compute window size for the given number of scalars. + */ +template +size_t get_exp_window_size(const size_t num_scalars); + +/** + * Compute table of window sizes. + */ +template +window_table get_window_table(const size_t scalar_size, + const size_t window, + const T &g); + +template +T windowed_exp(const size_t scalar_size, + const size_t window, + const window_table &powers_of_g, + const FieldT &pow); + +template +std::vector batch_exp(const size_t scalar_size, + const size_t window, + const window_table &table, + const std::vector &v); + +template +std::vector batch_exp_with_coeff(const size_t scalar_size, + const size_t window, + const window_table &table, + const FieldT &coeff, + const std::vector &v); + +// defined in every curve +template +void batch_to_special_all_non_zeros(std::vector &vec); + +template +void batch_to_special(std::vector &vec); + +} // libsnark + +#include "algebra/scalar_multiplication/multiexp.tcc" + +#endif // MULTIEXP_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc new file mode 100644 index 000000000..a6b14c4df --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/multiexp.tcc @@ -0,0 +1,590 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for multi-exponentiation routines. + + See multiexp.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MULTIEXP_TCC_ +#define MULTIEXP_TCC_ + +#include "algebra/fields/fp_aux.tcc" + +#include +#include +#include + +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "algebra/scalar_multiplication/wnaf.hpp" + +namespace libsnark { + +template +class ordered_exponent { +// to use std::push_heap and friends later +public: + size_t idx; + bigint r; + + ordered_exponent(const size_t idx, const bigint &r) : idx(idx), r(r) {}; + + bool operator<(const ordered_exponent &other) const + { +#if defined(__x86_64__) && defined(USE_ASM) + if (n == 3) + { + long res; + __asm__ + ("// check for overflow \n\t" + "mov $0, %[res] \n\t" + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + "jmp done%= \n\t" + "subtract%=: \n\t" + "mov $1, %[res] \n\t" + "done%=: \n\t" + : [res] "=&r" (res) + : [A] "r" (other.r.data), [mod] "r" (this->r.data) + : "cc", "%rax"); + return res; + } + else if (n == 4) + { + long res; + __asm__ + ("// check for overflow \n\t" + "mov $0, %[res] \n\t" + ADD_CMP(24) + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + "jmp done%= \n\t" + "subtract%=: \n\t" + "mov $1, %[res] \n\t" + "done%=: \n\t" + : [res] "=&r" (res) + : [A] "r" (other.r.data), [mod] "r" (this->r.data) + : "cc", "%rax"); + return res; + } + else if (n == 5) + { + long res; + __asm__ + ("// check for overflow \n\t" + "mov $0, %[res] \n\t" + ADD_CMP(32) + ADD_CMP(24) + ADD_CMP(16) + ADD_CMP(8) + ADD_CMP(0) + "jmp done%= \n\t" + "subtract%=: \n\t" + "mov $1, %[res] \n\t" + "done%=: \n\t" + : [res] "=&r" (res) + : [A] "r" (other.r.data), [mod] "r" (this->r.data) + : "cc", "%rax"); + return res; + } + else +#endif + { + return (mpn_cmp(this->r.data, other.r.data, n) < 0); + } + } +}; + +template +T naive_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end) +{ + T result(T::zero()); + + typename std::vector::const_iterator vec_it; + typename std::vector::const_iterator scalar_it; + + for (vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it) + { + bigint scalar_bigint = scalar_it->as_bigint(); + result = result + opt_window_wnaf_exp(*vec_it, scalar_bigint, scalar_bigint.num_bits()); + } + assert(scalar_it == scalar_end); + + return result; +} + +template +T naive_plain_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end) +{ + T result(T::zero()); + + typename std::vector::const_iterator vec_it; + typename std::vector::const_iterator scalar_it; + + for (vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it) + { + result = result + (*scalar_it) * (*vec_it); + } + assert(scalar_it == scalar_end); + + return result; +} + +/* + The multi-exponentiation algorithm below is a variant of the Bos-Coster algorithm + [Bos and Coster, "Addition chain heuristics", CRYPTO '89]. + The implementation uses suggestions from + [Bernstein, Duif, Lange, Schwabe, and Yang, "High-speed high-security signatures", CHES '11]. +*/ +template +T multi_exp_inner(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end) +{ + const mp_size_t n = std::remove_reference::type::num_limbs; + + if (vec_start == vec_end) + { + return T::zero(); + } + + if (vec_start + 1 == vec_end) + { + return (*scalar_start)*(*vec_start); + } + + std::vector > opt_q; + const size_t vec_len = scalar_end - scalar_start; + const size_t odd_vec_len = (vec_len % 2 == 1 ? vec_len : vec_len + 1); + opt_q.reserve(odd_vec_len); + std::vector g; + g.reserve(odd_vec_len); + + typename std::vector::const_iterator vec_it; + typename std::vector::const_iterator scalar_it; + size_t i; + for (i=0, vec_it = vec_start, scalar_it = scalar_start; vec_it != vec_end; ++vec_it, ++scalar_it, ++i) + { + g.emplace_back(*vec_it); + + opt_q.emplace_back(ordered_exponent(i, scalar_it->as_bigint())); + } + std::make_heap(opt_q.begin(),opt_q.end()); + assert(scalar_it == scalar_end); + + if (vec_len != odd_vec_len) + { + g.emplace_back(T::zero()); + opt_q.emplace_back(ordered_exponent(odd_vec_len - 1, bigint(0ul))); + } + assert(g.size() % 2 == 1); + assert(opt_q.size() == g.size()); + + T opt_result = T::zero(); + + while (true) + { + ordered_exponent &a = opt_q[0]; + ordered_exponent &b = (opt_q[1] < opt_q[2] ? opt_q[2] : opt_q[1]); + + const size_t abits = a.r.num_bits(); + + if (b.r.is_zero()) + { + // opt_result = opt_result + (a.r * g[a.idx]); + opt_result = opt_result + opt_window_wnaf_exp(g[a.idx], a.r, abits); + break; + } + + const size_t bbits = b.r.num_bits(); + const size_t limit = (abits-bbits >= 20 ? 20 : abits-bbits); + + if (bbits < 1ul< (x-y) A + y (B+A) + mpn_sub_n(a.r.data, a.r.data, b.r.data, n); + g[b.idx] = g[b.idx] + g[a.idx]; + } + + // regardless of whether a was cleared or subtracted from we push it down, then take back up + + /* heapify A down */ + size_t a_pos = 0; + while (2*a_pos + 2< odd_vec_len) + { + // this is a max-heap so to maintain a heap property we swap with the largest of the two + if (opt_q[2*a_pos+1] < opt_q[2*a_pos+2]) + { + std::swap(opt_q[a_pos], opt_q[2*a_pos+2]); + a_pos = 2*a_pos+2; + } + else + { + std::swap(opt_q[a_pos], opt_q[2*a_pos+1]); + a_pos = 2*a_pos+1; + } + } + + /* now heapify A up appropriate amount of times */ + while (a_pos > 0 && opt_q[(a_pos-1)/2] < opt_q[a_pos]) + { + std::swap(opt_q[a_pos], opt_q[(a_pos-1)/2]); + a_pos = (a_pos-1) / 2; + } + } + + return opt_result; +} + +template +T multi_exp(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp) +{ + const size_t total = vec_end - vec_start; + if (total < chunks) + { + return naive_exp(vec_start, vec_end, scalar_start, scalar_end); + } + + const size_t one = total/chunks; + + std::vector partial(chunks, T::zero()); + + if (use_multiexp) + { +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < chunks; ++i) + { + partial[i] = multi_exp_inner(vec_start + i*one, + (i == chunks-1 ? vec_end : vec_start + (i+1)*one), + scalar_start + i*one, + (i == chunks-1 ? scalar_end : scalar_start + (i+1)*one)); + } + } + else + { +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < chunks; ++i) + { + partial[i] = naive_exp(vec_start + i*one, + (i == chunks-1 ? vec_end : vec_start + (i+1)*one), + scalar_start + i*one, + (i == chunks-1 ? scalar_end : scalar_start + (i+1)*one)); + } + } + + T final = T::zero(); + + for (size_t i = 0; i < chunks; ++i) + { + final = final + partial[i]; + } + + return final; +} + +template +T multi_exp_with_mixed_addition(typename std::vector::const_iterator vec_start, + typename std::vector::const_iterator vec_end, + typename std::vector::const_iterator scalar_start, + typename std::vector::const_iterator scalar_end, + const size_t chunks, + const bool use_multiexp) +{ + assert(std::distance(vec_start, vec_end) == std::distance(scalar_start, scalar_end)); + enter_block("Process scalar vector"); + auto value_it = vec_start; + auto scalar_it = scalar_start; + + const FieldT zero = FieldT::zero(); + const FieldT one = FieldT::one(); + std::vector p; + std::vector g; + + T acc = T::zero(); + + size_t num_skip = 0; + size_t num_add = 0; + size_t num_other = 0; + + for (; scalar_it != scalar_end; ++scalar_it, ++value_it) + { + if (*scalar_it == zero) + { + // do nothing + ++num_skip; + } + else if (*scalar_it == one) + { +#ifdef USE_MIXED_ADDITION + acc = acc.mixed_add(*value_it); +#else + acc = acc + (*value_it); +#endif + ++num_add; + } + else + { + p.emplace_back(*scalar_it); + g.emplace_back(*value_it); + ++num_other; + } + } + //print_indent(); printf("* Elements of w skipped: %zu (%0.2f%%)\n", num_skip, 100.*num_skip/(num_skip+num_add+num_other)); + //print_indent(); printf("* Elements of w processed with special addition: %zu (%0.2f%%)\n", num_add, 100.*num_add/(num_skip+num_add+num_other)); + //print_indent(); printf("* Elements of w remaining: %zu (%0.2f%%)\n", num_other, 100.*num_other/(num_skip+num_add+num_other)); + + leave_block("Process scalar vector"); + + return acc + multi_exp(g.begin(), g.end(), p.begin(), p.end(), chunks, use_multiexp); +} + +template +size_t get_exp_window_size(const size_t num_scalars) +{ + if (T::fixed_base_exp_window_table.empty()) + { +#ifdef LOWMEM + return 14; +#else + return 17; +#endif + } + size_t window = 1; + for (long i = T::fixed_base_exp_window_table.size()-1; i >= 0; --i) + { +#ifdef DEBUG + if (!inhibit_profiling_info) + { + printf("%ld %zu %zu\n", i, num_scalars, T::fixed_base_exp_window_table[i]); + } +#endif + if (T::fixed_base_exp_window_table[i] != 0 && num_scalars >= T::fixed_base_exp_window_table[i]) + { + window = i+1; + break; + } + } + + if (!inhibit_profiling_info) + { + print_indent(); printf("Choosing window size %zu for %zu elements\n", window, num_scalars); + } + +#ifdef LOWMEM + window = std::min((size_t)14, window); +#endif + return window; +} + +template +window_table get_window_table(const size_t scalar_size, + const size_t window, + const T &g) +{ + const size_t in_window = 1ul< powers_of_g(outerc, std::vector(in_window, T::zero())); + + T gouter = g; + + for (size_t outer = 0; outer < outerc; ++outer) + { + T ginner = T::zero(); + size_t cur_in_window = outer == outerc-1 ? last_in_window : in_window; + for (size_t inner = 0; inner < cur_in_window; ++inner) + { + powers_of_g[outer][inner] = ginner; + ginner = ginner + gouter; + } + + for (size_t i = 0; i < window; ++i) + { + gouter = gouter + gouter; + } + } + + return powers_of_g; +} + +template +T windowed_exp(const size_t scalar_size, + const size_t window, + const window_table &powers_of_g, + const FieldT &pow) +{ + const size_t outerc = (scalar_size+window-1)/window; + const bigint pow_val = pow.as_bigint(); + + /* exp */ + T res = powers_of_g[0][0]; + + for (size_t outer = 0; outer < outerc; ++outer) + { + size_t inner = 0; + for (size_t i = 0; i < window; ++i) + { + if (pow_val.test_bit(outer*window + i)) + { + inner |= 1u << i; + } + } + + res = res + powers_of_g[outer][inner]; + } + + return res; +} + +template +std::vector batch_exp(const size_t scalar_size, + const size_t window, + const window_table &table, + const std::vector &v) +{ + if (!inhibit_profiling_info) + { + print_indent(); + } + std::vector res(v.size(), table[0][0]); + +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < v.size(); ++i) + { + res[i] = windowed_exp(scalar_size, window, table, v[i]); + + if (!inhibit_profiling_info && (i % 10000 == 0)) + { + printf("."); + fflush(stdout); + } + } + + if (!inhibit_profiling_info) + { + printf(" DONE!\n"); + } + + return res; +} + +template +std::vector batch_exp_with_coeff(const size_t scalar_size, + const size_t window, + const window_table &table, + const FieldT &coeff, + const std::vector &v) +{ + if (!inhibit_profiling_info) + { + print_indent(); + } + std::vector res(v.size(), table[0][0]); + +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < v.size(); ++i) + { + res[i] = windowed_exp(scalar_size, window, table, coeff * v[i]); + + if (!inhibit_profiling_info && (i % 10000 == 0)) + { + printf("."); + fflush(stdout); + } + } + + if (!inhibit_profiling_info) + { + printf(" DONE!\n"); + } + + return res; +} + +template +void batch_to_special(std::vector &vec) +{ + enter_block("Batch-convert elements to special form"); + + std::vector non_zero_vec; + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].is_zero()) + { + non_zero_vec.emplace_back(vec[i]); + } + } + + batch_to_special_all_non_zeros(non_zero_vec); + auto it = non_zero_vec.begin(); + T zero_special = T::zero(); + zero_special.to_special(); + + for (size_t i = 0; i < vec.size(); ++i) + { + if (!vec[i].is_zero()) + { + vec[i] = *it; + ++it; + } + else + { + vec[i] = zero_special; + } + } + leave_block("Batch-convert elements to special form"); +} + +} // libsnark + +#endif // MULTIEXP_TCC_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp new file mode 100644 index 000000000..a7ecd598e --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.hpp @@ -0,0 +1,39 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for wNAF ("width-w Non-Adjacent Form") exponentiation routines. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef WNAF_HPP_ +#define WNAF_HPP_ + +namespace libsnark { + +/** + * Find the wNAF representation of the given scalar relative to the given window size. + */ +template +std::vector find_wnaf(const size_t window_size, const bigint &scalar); + +/** + * In additive notation, use wNAF exponentiation (with the given window size) to compute scalar * base. + */ +template +T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar); + +/** + * In additive notation, use wNAF exponentiation (with the window size determined by T) to compute scalar * base. + */ +template +T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits); + +} // libsnark + +#include "algebra/scalar_multiplication/wnaf.tcc" + +#endif // WNAF_HPP_ diff --git a/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc new file mode 100644 index 000000000..a5e47e8e2 --- /dev/null +++ b/src/snark/libsnark/algebra/scalar_multiplication/wnaf.tcc @@ -0,0 +1,123 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for wNAF ("weighted Non-Adjacent Form") exponentiation routines. + + See wnaf.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef WNAF_TCC_ +#define WNAF_TCC_ + +namespace libsnark { + +template +std::vector find_wnaf(const size_t window_size, const bigint &scalar) +{ + const size_t length = scalar.max_bits(); // upper bound + std::vector res(length+1); + bigint c = scalar; + long j = 0; + while (!c.is_zero()) + { + long u; + if ((c.data[0] & 1) == 1) + { + u = c.data[0] % (1u << (window_size+1)); + if (u > (1 << window_size)) + { + u = u - (1 << (window_size+1)); + } + + if (u > 0) + { + mpn_sub_1(c.data, c.data, n, u); + } + else + { + mpn_add_1(c.data, c.data, n, -u); + } + } + else + { + u = 0; + } + res[j] = u; + ++j; + + mpn_rshift(c.data, c.data, n, 1); // c = c/2 + } + + return res; +} + +template +T fixed_window_wnaf_exp(const size_t window_size, const T &base, const bigint &scalar) +{ + std::vector naf = find_wnaf(window_size, scalar); + std::vector table(1ul<<(window_size-1)); + T tmp = base; + T dbl = base.dbl(); + for (size_t i = 0; i < 1ul<<(window_size-1); ++i) + { + table[i] = tmp; + tmp = tmp + dbl; + } + + T res = T::zero(); + bool found_nonzero = false; + for (long i = naf.size()-1; i >= 0; --i) + { + if (found_nonzero) + { + res = res.dbl(); + } + + if (naf[i] != 0) + { + found_nonzero = true; + if (naf[i] > 0) + { + res = res + table[naf[i]/2]; + } + else + { + res = res - table[(-naf[i])/2]; + } + } + } + + return res; +} + +template +T opt_window_wnaf_exp(const T &base, const bigint &scalar, const size_t scalar_bits) +{ + size_t best = 0; + for (long i = T::wnaf_window_table.size() - 1; i >= 0; --i) + { + if (scalar_bits >= T::wnaf_window_table[i]) + { + best = i+1; + break; + } + } + + if (best > 0) + { + return fixed_window_wnaf_exp(best, base, scalar); + } + else + { + return scalar * base; + } +} + +} // libsnark + +#endif // WNAF_TCC_ diff --git a/src/snark/libsnark/common/assert_except.hpp b/src/snark/libsnark/common/assert_except.hpp new file mode 100644 index 000000000..781923044 --- /dev/null +++ b/src/snark/libsnark/common/assert_except.hpp @@ -0,0 +1,12 @@ +#ifndef ASSERT_except_H +#define ASSERT_except_H + +#include + +inline void assert_except(bool condition) { + if (!condition) { + throw std::runtime_error("Assertion failed."); + } +} + +#endif diff --git a/src/snark/libsnark/common/data_structures/accumulation_vector.hpp b/src/snark/libsnark/common/data_structures/accumulation_vector.hpp new file mode 100644 index 000000000..37e0c9841 --- /dev/null +++ b/src/snark/libsnark/common/data_structures/accumulation_vector.hpp @@ -0,0 +1,74 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for an accumulation vector. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ACCUMULATION_VECTOR_HPP_ +#define ACCUMULATION_VECTOR_HPP_ + +#include "common/data_structures/sparse_vector.hpp" + +namespace libsnark { + +template +class accumulation_vector; + +template +std::ostream& operator<<(std::ostream &out, const accumulation_vector &v); + +template +std::istream& operator>>(std::istream &in, accumulation_vector &v); + +/** + * An accumulation vector comprises an accumulation value and a sparse vector. + * The method "accumulate_chunk" allows one to accumlate portions of the sparse + * vector into the accumualation value. + */ +template +class accumulation_vector { +public: + T first; + sparse_vector rest; + + accumulation_vector() = default; + accumulation_vector(const accumulation_vector &other) = default; + accumulation_vector(accumulation_vector &&other) = default; + accumulation_vector(T &&first, sparse_vector &&rest) : first(std::move(first)), rest(std::move(rest)) {}; + accumulation_vector(T &&first, std::vector &&v) : first(std::move(first)), rest(std::move(v)) {} + accumulation_vector(std::vector &&v) : first(T::zero()), rest(std::move(v)) {}; + + accumulation_vector& operator=(const accumulation_vector &other) = default; + accumulation_vector& operator=(accumulation_vector &&other) = default; + + bool operator==(const accumulation_vector &other) const; + + bool is_fully_accumulated() const; + + size_t domain_size() const; + size_t size() const; + size_t size_in_bits() const; + + template + accumulation_vector accumulate_chunk(const typename std::vector::const_iterator &it_begin, + const typename std::vector::const_iterator &it_end, + const size_t offset) const; + +}; + +template +std::ostream& operator<<(std::ostream &out, const accumulation_vector &v); + +template +std::istream& operator>>(std::istream &in, accumulation_vector &v); + +} // libsnark + +#include "common/data_structures/accumulation_vector.tcc" + +#endif // ACCUMULATION_VECTOR_HPP_ diff --git a/src/snark/libsnark/common/data_structures/accumulation_vector.tcc b/src/snark/libsnark/common/data_structures/accumulation_vector.tcc new file mode 100644 index 000000000..9e524aba7 --- /dev/null +++ b/src/snark/libsnark/common/data_structures/accumulation_vector.tcc @@ -0,0 +1,84 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for an accumulation vector. + + See accumulation_vector.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef ACCUMULATION_VECTOR_TCC_ +#define ACCUMULATION_VECTOR_TCC_ + +namespace libsnark { + +template +bool accumulation_vector::operator==(const accumulation_vector &other) const +{ + return (this->first == other.first && this->rest == other.rest); +} + +template +bool accumulation_vector::is_fully_accumulated() const +{ + return rest.empty(); +} + +template +size_t accumulation_vector::domain_size() const +{ + return rest.domain_size(); +} + +template +size_t accumulation_vector::size() const +{ + return rest.domain_size(); +} + +template +size_t accumulation_vector::size_in_bits() const +{ + const size_t first_size_in_bits = T::size_in_bits(); + const size_t rest_size_in_bits = rest.size_in_bits(); + return first_size_in_bits + rest_size_in_bits; +} + +template +template +accumulation_vector accumulation_vector::accumulate_chunk(const typename std::vector::const_iterator &it_begin, + const typename std::vector::const_iterator &it_end, + const size_t offset) const +{ + std::pair > acc_result = rest.template accumulate(it_begin, it_end, offset); + T new_first = first + acc_result.first; + return accumulation_vector(std::move(new_first), std::move(acc_result.second)); +} + +template +std::ostream& operator<<(std::ostream& out, const accumulation_vector &v) +{ + out << v.first << OUTPUT_NEWLINE; + out << v.rest << OUTPUT_NEWLINE; + + return out; +} + +template +std::istream& operator>>(std::istream& in, accumulation_vector &v) +{ + in >> v.first; + consume_OUTPUT_NEWLINE(in); + in >> v.rest; + consume_OUTPUT_NEWLINE(in); + + return in; +} + +} // libsnark + +#endif // ACCUMULATION_VECTOR_TCC_ diff --git a/src/snark/libsnark/common/data_structures/merkle_tree.hpp b/src/snark/libsnark/common/data_structures/merkle_tree.hpp new file mode 100644 index 000000000..6f0c851ba --- /dev/null +++ b/src/snark/libsnark/common/data_structures/merkle_tree.hpp @@ -0,0 +1,71 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a Merkle tree. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_HPP_ +#define MERKLE_TREE_HPP_ + +#include +#include +#include "common/utils.hpp" + +namespace libsnark { + +/** + * A Merkle tree is maintained as two maps: + * - a map from addresses to values, and + * - a map from addresses to hashes. + * + * The second map maintains the intermediate hashes of a Merkle tree + * built atop the values currently stored in the tree (the + * implementation admits a very efficient support for sparse + * trees). Besides offering methods to load and store values, the + * class offers methods to retrieve the root of the Merkle tree and to + * obtain the authentication paths for (the value at) a given address. + */ + +typedef bit_vector merkle_authentication_node; +typedef std::vector merkle_authentication_path; + +template +class merkle_tree { +private: + + typedef typename HashT::hash_value_type hash_value_type; + typedef typename HashT::merkle_authentication_path_type merkle_authentication_path_type; + +public: + + std::vector hash_defaults; + std::map values; + std::map hashes; + + size_t depth; + size_t value_size; + size_t digest_size; + + merkle_tree(const size_t depth, const size_t value_size); + merkle_tree(const size_t depth, const size_t value_size, const std::vector &contents_as_vector); + merkle_tree(const size_t depth, const size_t value_size, const std::map &contents); + + bit_vector get_value(const size_t address) const; + void set_value(const size_t address, const bit_vector &value); + + hash_value_type get_root() const; + merkle_authentication_path_type get_path(const size_t address) const; + + void dump() const; +}; + +} // libsnark + +#include "common/data_structures/merkle_tree.tcc" + +#endif // MERKLE_TREE_HPP_ diff --git a/src/snark/libsnark/common/data_structures/merkle_tree.tcc b/src/snark/libsnark/common/data_structures/merkle_tree.tcc new file mode 100644 index 000000000..281700b33 --- /dev/null +++ b/src/snark/libsnark/common/data_structures/merkle_tree.tcc @@ -0,0 +1,246 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for Merkle tree. + + See merkle_tree.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_TCC +#define MERKLE_TREE_TCC + +#include + +#include "common/profiling.hpp" +#include "common/utils.hpp" + +namespace libsnark { + +template +typename HashT::hash_value_type two_to_one_CRH(const typename HashT::hash_value_type &l, + const typename HashT::hash_value_type &r) +{ + typename HashT::hash_value_type new_input; + new_input.insert(new_input.end(), l.begin(), l.end()); + new_input.insert(new_input.end(), r.begin(), r.end()); + + const size_t digest_size = HashT::get_digest_len(); + assert(l.size() == digest_size); + assert(r.size() == digest_size); + + return HashT::get_hash(new_input); +} + +template +merkle_tree::merkle_tree(const size_t depth, const size_t value_size) : + depth(depth), value_size(value_size) +{ + assert(depth < sizeof(size_t) * 8); + + digest_size = HashT::get_digest_len(); + assert(value_size <= digest_size); + + hash_value_type last(digest_size); + hash_defaults.reserve(depth+1); + hash_defaults.emplace_back(last); + for (size_t i = 0; i < depth; ++i) + { + last = two_to_one_CRH(last, last); + hash_defaults.emplace_back(last); + } + + std::reverse(hash_defaults.begin(), hash_defaults.end()); +} + +template +merkle_tree::merkle_tree(const size_t depth, + const size_t value_size, + const std::vector &contents_as_vector) : + merkle_tree(depth, value_size) +{ + assert(log2(contents_as_vector.size()) <= depth); + for (size_t address = 0; address < contents_as_vector.size(); ++address) + { + const size_t idx = address + (1ul< 0; --layer) + { + for (size_t idx = idx_begin; idx < idx_end; idx += 2) + { + hash_value_type l = hashes[idx]; // this is sound, because idx_begin is always a left child + hash_value_type r = (idx + 1 < idx_end ? hashes[idx+1] : hash_defaults[layer]); + + hash_value_type h = two_to_one_CRH(l, r); + hashes[(idx-1)/2] = h; + } + + idx_begin = (idx_begin-1)/2; + idx_end = (idx_end-1)/2; + } +} + +template +merkle_tree::merkle_tree(const size_t depth, + const size_t value_size, + const std::map &contents) : + merkle_tree(depth, value_size) +{ + + if (!contents.empty()) + { + assert(contents.rbegin()->first < 1ul<first; + const bit_vector value = it->second; + const size_t idx = address + (1ul< 0; --layer) + { + auto next_last_it = hashes.begin(); + + for (auto it = hashes.begin(); it != last_it; ++it) + { + const size_t idx = it->first; + const hash_value_type hash = it->second; + + if (idx % 2 == 0) + { + // this is the right child of its parent and by invariant we are missing the left child + hashes[(idx-1)/2] = two_to_one_CRH(hash_defaults[layer], hash); + } + else + { + if (std::next(it) == last_it || std::next(it)->first != idx + 1) + { + // this is the left child of its parent and is missing its right child + hashes[(idx-1)/2] = two_to_one_CRH(hash, hash_defaults[layer]); + } + else + { + // typical case: this is the left child of the parent and adjecent to it there is a right child + hashes[(idx-1)/2] = two_to_one_CRH(hash, std::next(it)->second); + ++it; + } + } + } + + last_it = next_last_it; + } + } +} + +template +bit_vector merkle_tree::get_value(const size_t address) const +{ + assert(log2(address) <= depth); + + auto it = values.find(address); + bit_vector padded_result = (it == values.end() ? bit_vector(digest_size) : it->second); + padded_result.resize(value_size); + + return padded_result; +} + +template +void merkle_tree::set_value(const size_t address, + const bit_vector &value) +{ + assert(log2(address) <= depth); + size_t idx = address + (1ul<=0; --layer) + { + idx = (idx-1)/2; + + auto it = hashes.find(2*idx+1); + hash_value_type l = (it == hashes.end() ? hash_defaults[layer+1] : it->second); + + it = hashes.find(2*idx+2); + hash_value_type r = (it == hashes.end() ? hash_defaults[layer+1] : it->second); + + hash_value_type h = two_to_one_CRH(l, r); + hashes[idx] = h; + } +} + +template +typename HashT::hash_value_type merkle_tree::get_root() const +{ + auto it = hashes.find(0); + return (it == hashes.end() ? hash_defaults[0] : it->second); +} + +template +typename HashT::merkle_authentication_path_type merkle_tree::get_path(const size_t address) const +{ + typename HashT::merkle_authentication_path_type result(depth); + assert(log2(address) <= depth); + size_t idx = address + (1ul< 0; --layer) + { + size_t sibling_idx = ((idx + 1) ^ 1) - 1; + auto it = hashes.find(sibling_idx); + if (layer == depth) + { + auto it2 = values.find(sibling_idx - ((1ul<second); + result[layer-1].resize(digest_size); + } + else + { + result[layer-1] = (it == hashes.end() ? hash_defaults[layer] : it->second); + } + + idx = (idx-1)/2; + } + + return result; +} + +template +void merkle_tree::dump() const +{ + for (size_t i = 0; i < 1ul< ", i); + const bit_vector value = (it == values.end() ? bit_vector(value_size) : it->second); + for (bool b : value) + { + printf("%d", b ? 1 : 0); + } + printf("\n"); + } + printf("\n"); +} + +} // libsnark + +#endif // MERKLE_TREE_TCC diff --git a/src/snark/libsnark/common/data_structures/sparse_vector.hpp b/src/snark/libsnark/common/data_structures/sparse_vector.hpp new file mode 100644 index 000000000..6c5a10447 --- /dev/null +++ b/src/snark/libsnark/common/data_structures/sparse_vector.hpp @@ -0,0 +1,79 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a sparse vector. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SPARSE_VECTOR_HPP_ +#define SPARSE_VECTOR_HPP_ + +#include + +namespace libsnark { + +template +struct sparse_vector; + +template +std::ostream& operator<<(std::ostream &out, const sparse_vector &v); + +template +std::istream& operator>>(std::istream &in, sparse_vector &v); + +/** + * A sparse vector is a list of indices along with corresponding values. + * The indices are selected from the set {0,1,...,domain_size-1}. + */ +template +struct sparse_vector { + + std::vector indices; + std::vector values; + size_t domain_size_ = 0; + + sparse_vector() = default; + sparse_vector(const sparse_vector &other) = default; + sparse_vector(sparse_vector &&other) = default; + sparse_vector(std::vector &&v); /* constructor from std::vector */ + + sparse_vector& operator=(const sparse_vector &other) = default; + sparse_vector& operator=(sparse_vector &&other) = default; + + T operator[](const size_t idx) const; + + bool operator==(const sparse_vector &other) const; + bool operator==(const std::vector &other) const; + + bool is_valid() const; + bool empty() const; + + size_t domain_size() const; // return domain_size_ + size_t size() const; // return the number of indices (representing the number of non-zero entries) + size_t size_in_bits() const; // return the number bits needed to store the sparse vector + + /* return a pair consisting of the accumulated value and the sparse vector of non-accumulated values */ + template + std::pair > accumulate(const typename std::vector::const_iterator &it_begin, + const typename std::vector::const_iterator &it_end, + const size_t offset) const; + + friend std::ostream& operator<< (std::ostream &out, const sparse_vector &v); + friend std::istream& operator>> (std::istream &in, sparse_vector &v); +}; + +template +std::ostream& operator<<(std::ostream& out, const sparse_vector &v); + +template +std::istream& operator>>(std::istream& in, sparse_vector &v); + +} // libsnark + +#include "common/data_structures/sparse_vector.tcc" + +#endif // SPARSE_VECTOR_HPP_ diff --git a/src/snark/libsnark/common/data_structures/sparse_vector.tcc b/src/snark/libsnark/common/data_structures/sparse_vector.tcc new file mode 100644 index 000000000..cfc5d7559 --- /dev/null +++ b/src/snark/libsnark/common/data_structures/sparse_vector.tcc @@ -0,0 +1,316 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for a sparse vector. + + See sparse_vector.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SPARSE_VECTOR_TCC_ +#define SPARSE_VECTOR_TCC_ + +#include "algebra/scalar_multiplication/multiexp.hpp" + +#include + +namespace libsnark { + +template +sparse_vector::sparse_vector(std::vector &&v) : + values(std::move(v)), domain_size_(values.size()) +{ + indices.resize(domain_size_); + std::iota(indices.begin(), indices.end(), 0); +} + +template +T sparse_vector::operator[](const size_t idx) const +{ + auto it = std::lower_bound(indices.begin(), indices.end(), idx); + return (it != indices.end() && *it == idx) ? values[it - indices.begin()] : T(); +} + +template +bool sparse_vector::operator==(const sparse_vector &other) const +{ + if (this->domain_size_ != other.domain_size_) + { + return false; + } + + size_t this_pos = 0, other_pos = 0; + while (this_pos < this->indices.size() && other_pos < other.indices.size()) + { + if (this->indices[this_pos] == other.indices[other_pos]) + { + if (this->values[this_pos] != other.values[other_pos]) + { + return false; + } + ++this_pos; + ++other_pos; + } + else if (this->indices[this_pos] < other.indices[other_pos]) + { + if (!this->values[this_pos].is_zero()) + { + return false; + } + ++this_pos; + } + else + { + if (!other.values[other_pos].is_zero()) + { + return false; + } + ++other_pos; + } + } + + /* at least one of the vectors has been exhausted, so other must be empty */ + while (this_pos < this->indices.size()) + { + if (!this->values[this_pos].is_zero()) + { + return false; + } + ++this_pos; + } + + while (other_pos < other.indices.size()) + { + if (!other.values[other_pos].is_zero()) + { + return false; + } + ++other_pos; + } + + return true; +} + +template +bool sparse_vector::operator==(const std::vector &other) const +{ + if (this->domain_size_ < other.size()) + { + return false; + } + + size_t j = 0; + for (size_t i = 0; i < other.size(); ++i) + { + if (this->indices[j] == i) + { + if (this->values[j] != other[j]) + { + return false; + } + ++j; + } + else + { + if (!other[j].is_zero()) + { + return false; + } + } + } + + return true; +} + +template +bool sparse_vector::is_valid() const +{ + if (values.size() == indices.size() && values.size() <= domain_size_) + { + return false; + } + + for (size_t i = 0; i + 1 < indices.size(); ++i) + { + if (indices[i] >= indices[i+1]) + { + return false; + } + } + + if (!indices.empty() && indices[indices.size()-1] >= domain_size_) + { + return false; + } + + return true; +} + +template +bool sparse_vector::empty() const +{ + return indices.empty(); +} + +template +size_t sparse_vector::domain_size() const +{ + return domain_size_; +} + +template +size_t sparse_vector::size() const +{ + return indices.size(); +} + +template +size_t sparse_vector::size_in_bits() const +{ + return indices.size() * (sizeof(size_t) * 8 + T::size_in_bits()); +} + +template +template +std::pair > sparse_vector::accumulate(const typename std::vector::const_iterator &it_begin, + const typename std::vector::const_iterator &it_end, + const size_t offset) const +{ + // TODO: does not really belong here. + const size_t chunks = 1; + const bool use_multiexp = true; + + T accumulated_value = T::zero(); + sparse_vector resulting_vector; + resulting_vector.domain_size_ = domain_size_; + + const size_t range_len = it_end - it_begin; + bool in_block = false; + size_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases. + + for (size_t i = 0; i < indices.size(); ++i) + { + const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len); + // printf("i = %zu, pos[i] = %zu, offset = %zu, w_size = %zu\n", i, indices[i], offset, w_size); + bool copy_over; + + if (in_block) + { + if (matching_pos && last_pos == i-1) + { + // block can be extended, do it + last_pos = i; + copy_over = false; + } + else + { + // block has ended here + in_block = false; + copy_over = true; + +#ifdef DEBUG + print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); +#endif + accumulated_value = accumulated_value + multi_exp(values.begin() + first_pos, + values.begin() + last_pos + 1, + it_begin + (indices[first_pos] - offset), + it_begin + (indices[last_pos] - offset) + 1, + chunks, use_multiexp); + } + } + else + { + if (matching_pos) + { + // block can be started + first_pos = i; + last_pos = i; + in_block = true; + copy_over = false; + } + else + { + copy_over = true; + } + } + + if (copy_over) + { + resulting_vector.indices.emplace_back(indices[i]); + resulting_vector.values.emplace_back(values[i]); + } + } + + if (in_block) + { +#ifdef DEBUG + print_indent(); printf("doing multiexp for w_%zu ... w_%zu\n", indices[first_pos], indices[last_pos]); +#endif + accumulated_value = accumulated_value + multi_exp(values.begin() + first_pos, + values.begin() + last_pos + 1, + it_begin + (indices[first_pos] - offset), + it_begin + (indices[last_pos] - offset) + 1, + chunks, use_multiexp); + } + + return std::make_pair(accumulated_value, resulting_vector); +} + +template +std::ostream& operator<<(std::ostream& out, const sparse_vector &v) +{ + out << v.domain_size_ << "\n"; + out << v.indices.size() << "\n"; + for (const size_t& i : v.indices) + { + out << i << "\n"; + } + + out << v.values.size() << "\n"; + for (const T& t : v.values) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +template +std::istream& operator>>(std::istream& in, sparse_vector &v) +{ + in >> v.domain_size_; + consume_newline(in); + + size_t s; + in >> s; + consume_newline(in); + v.indices.resize(s); + for (size_t i = 0; i < s; ++i) + { + in >> v.indices[i]; + consume_newline(in); + } + + v.values.clear(); + in >> s; + consume_newline(in); + v.values.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + T t; + in >> t; + consume_OUTPUT_NEWLINE(in); + v.values.emplace_back(t); + } + + return in; +} + +} // libsnark + +#endif // SPARSE_VECTOR_TCC_ diff --git a/src/snark/libsnark/common/default_types/ec_pp.hpp b/src/snark/libsnark/common/default_types/ec_pp.hpp new file mode 100644 index 000000000..b08c2da88 --- /dev/null +++ b/src/snark/libsnark/common/default_types/ec_pp.hpp @@ -0,0 +1,53 @@ +/** @file + ***************************************************************************** + + This file defines default_ec_pp based on the CURVE=... make flag, which selects + which elliptic curve is used to implement group arithmetic and pairings. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef EC_PP_HPP_ +#define EC_PP_HPP_ + +/************************ Pick the elliptic curve ****************************/ + +#ifdef CURVE_ALT_BN128 +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +namespace libsnark { +typedef alt_bn128_pp default_ec_pp; +} // libsnark +#endif + +#ifdef CURVE_BN128 +#include "algebra/curves/bn128/bn128_pp.hpp" +namespace libsnark { +typedef bn128_pp default_ec_pp; +} // libsnark +#endif + +#ifdef CURVE_EDWARDS +#include "algebra/curves/edwards/edwards_pp.hpp" +namespace libsnark { +typedef edwards_pp default_ec_pp; +} // libsnark +#endif + +#ifdef CURVE_MNT4 +#include "algebra/curves/mnt/mnt4/mnt4_pp.hpp" +namespace libsnark { +typedef mnt4_pp default_ec_pp; +} // libsnark +#endif + +#ifdef CURVE_MNT6 +#include "algebra/curves/mnt/mnt6/mnt6_pp.hpp" +namespace libsnark { +typedef mnt6_pp default_ec_pp; +} // libsnark +#endif + +#endif // EC_PP_HPP_ diff --git a/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp b/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp new file mode 100644 index 000000000..c819b4a85 --- /dev/null +++ b/src/snark/libsnark/common/default_types/r1cs_ppzksnark_pp.hpp @@ -0,0 +1,22 @@ +/** @file + ***************************************************************************** + + This file defines default_r1cs_ppzksnark_pp based on the elliptic curve + choice selected in ec_pp.hpp. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_PPZKSNARK_PP_HPP_ +#define R1CS_PPZKSNARK_PP_HPP_ + +#include "common/default_types/ec_pp.hpp" + +namespace libsnark { +typedef default_ec_pp default_r1cs_ppzksnark_pp; +} // libsnark + +#endif // R1CS_PPZKSNARK_PP_HPP_ diff --git a/src/snark/libsnark/common/profiling.cpp b/src/snark/libsnark/common/profiling.cpp new file mode 100644 index 000000000..ae8f85a4c --- /dev/null +++ b/src/snark/libsnark/common/profiling.cpp @@ -0,0 +1,379 @@ +/** @file + ***************************************************************************** + + Implementation of functions for profiling code blocks. + + See profiling.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "common/profiling.hpp" +#include +#include +#include +#include +#include +#include +#include +#include "common/default_types/ec_pp.hpp" +#include "common/utils.hpp" + +#ifndef NO_PROCPS +#include +#endif + +namespace libsnark { + +long long get_nsec_time() +{ + auto timepoint = std::chrono::high_resolution_clock::now(); + return std::chrono::duration_cast(timepoint.time_since_epoch()).count(); +} + +/* Return total CPU time consumed by all threads of the process, in nanoseconds. */ +long long get_nsec_cpu_time() +{ + ::timespec ts; + if ( ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) ) + throw ::std::runtime_error("clock_gettime(CLOCK_PROCESS_CPUTIME_ID) failed"); + // If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef . + //TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__? + return ts.tv_sec * 1000000000ll + ts.tv_nsec; +} + +long long start_time, last_time; +long long start_cpu_time, last_cpu_time; + +void start_profiling() +{ + printf("Reset time counters for profiling\n"); + + last_time = start_time = get_nsec_time(); + last_cpu_time = start_cpu_time = get_nsec_cpu_time(); +} + +std::map invocation_counts; +std::map enter_times; +std::map last_times; +std::map cumulative_times; +//TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map +std::map enter_cpu_times; +std::map last_cpu_times; +std::map, long long> op_counts; +std::map, long long> cumulative_op_counts; // ((msg, data_point), value) + // TODO: Convert op_counts and cumulative_op_counts from pair to structs +size_t indentation = 0; + +std::vector block_names; + +std::list > op_data_points = { +#ifdef PROFILE_OP_COUNTS + std::make_pair("Fradd", &Fr::add_cnt), + std::make_pair("Frsub", &Fr::sub_cnt), + std::make_pair("Frmul", &Fr::mul_cnt), + std::make_pair("Frinv", &Fr::inv_cnt), + std::make_pair("Fqadd", &Fq::add_cnt), + std::make_pair("Fqsub", &Fq::sub_cnt), + std::make_pair("Fqmul", &Fq::mul_cnt), + std::make_pair("Fqinv", &Fq::inv_cnt), + std::make_pair("G1add", &G1::add_cnt), + std::make_pair("G1dbl", &G1::dbl_cnt), + std::make_pair("G2add", &G2::add_cnt), + std::make_pair("G2dbl", &G2::dbl_cnt) +#endif +}; + +bool inhibit_profiling_info = false; +bool inhibit_profiling_counters = false; + +void clear_profiling_counters() +{ + invocation_counts.clear(); + last_times.clear(); + last_cpu_times.clear(); + cumulative_times.clear(); +} + +void print_cumulative_time_entry(const std::string &key, const long long factor) +{ + const double total_ms = (cumulative_times.at(key) * 1e-6); + const size_t cnt = invocation_counts.at(key); + const double avg_ms = total_ms / cnt; + printf(" %-45s: %12.5fms = %lld * %0.5fms (%zu invocations, %0.5fms = %lld * %0.5fms per invocation)\n", key.c_str(), total_ms, factor, total_ms/factor, cnt, avg_ms, factor, avg_ms/factor); +} + +void print_cumulative_times(const long long factor) +{ + printf("Dumping times:\n"); + for (auto& kv : cumulative_times) + { + print_cumulative_time_entry(kv.first, factor); + } +} + +void print_cumulative_op_counts(const bool only_fq) +{ +#ifdef PROFILE_OP_COUNTS + printf("Dumping operation counts:\n"); + for (auto& msg : invocation_counts) + { + printf(" %-45s: ", msg.first.c_str()); + bool first = true; + for (auto& data_point : op_data_points) + { + if (only_fq && data_point.first.compare(0, 2, "Fq") != 0) + { + continue; + } + + if (!first) + { + printf(", "); + } + printf("%-5s = %7.0f (%3zu)", + data_point.first.c_str(), + 1. * cumulative_op_counts[std::make_pair(msg.first, data_point.first)] / msg.second, + msg.second); + first = false; + } + printf("\n"); + } +#else + UNUSED(only_fq); +#endif +} + +void print_op_profiling(const std::string &msg) +{ +#ifdef PROFILE_OP_COUNTS + printf("\n"); + print_indent(); + + printf("(opcounts) = ("); + bool first = true; + for (std::pair p : op_data_points) + { + if (!first) + { + printf(", "); + } + + printf("%s=%lld", p.first.c_str(), *(p.second)-op_counts[std::make_pair(msg, p.first)]); + first = false; + } + printf(")"); +#else + UNUSED(msg); +#endif +} + +static void print_times_from_last_and_start(long long now, long long last, + long long cpu_now, long long cpu_last) +{ + long long time_from_start = now - start_time; + long long time_from_last = now - last; + + long long cpu_time_from_start = cpu_now - start_cpu_time; + long long cpu_time_from_last = cpu_now - cpu_last; + + if (time_from_last != 0) { + double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last; + printf("[%0.4fs x%0.2f]", time_from_last * 1e-9, parallelism_from_last); + } else { + printf("[ ]"); + } + if (time_from_start != 0) { + double parallelism_from_start = 1.0 * cpu_time_from_start / time_from_start; + printf("\t(%0.4fs x%0.2f from start)", time_from_start * 1e-9, parallelism_from_start); + } +} + +void print_time(const char* msg) +{ + if (inhibit_profiling_info) + { + return; + } + + long long now = get_nsec_time(); + long long cpu_now = get_nsec_cpu_time(); + + printf("%-35s\t", msg); + print_times_from_last_and_start(now, last_time, cpu_now, last_cpu_time); +#ifdef PROFILE_OP_COUNTS + print_op_profiling(msg); +#endif + printf("\n"); + + fflush(stdout); + last_time = now; + last_cpu_time = cpu_now; +} + +void print_header(const char *msg) +{ + printf("\n================================================================================\n"); + printf("%s\n", msg); + printf("================================================================================\n\n"); +} + +void print_indent() +{ + for (size_t i = 0; i < indentation; ++i) + { + printf(" "); + } +} + +void op_profiling_enter(const std::string &msg) +{ + for (std::pair p : op_data_points) + { + op_counts[std::make_pair(msg, p.first)] = *(p.second); + } +} + +void enter_block(const std::string &msg, const bool indent) +{ + if (inhibit_profiling_counters) + { + return; + } + + block_names.emplace_back(msg); + long long t = get_nsec_time(); + enter_times[msg] = t; + long long cpu_t = get_nsec_cpu_time(); + enter_cpu_times[msg] = cpu_t; + + if (inhibit_profiling_info) + { + return; + } + +#ifdef MULTICORE +#pragma omp critical +#endif + { + op_profiling_enter(msg); + + print_indent(); + printf("(enter) %-35s\t", msg.c_str()); + print_times_from_last_and_start(t, t, cpu_t, cpu_t); + printf("\n"); + fflush(stdout); + + if (indent) + { + ++indentation; + } + } +} + +void leave_block(const std::string &msg, const bool indent) +{ + if (inhibit_profiling_counters) + { + return; + } + +#ifndef MULTICORE + assert(*(--block_names.end()) == msg); +#endif + block_names.pop_back(); + + ++invocation_counts[msg]; + + long long t = get_nsec_time(); + last_times[msg] = (t - enter_times[msg]); + cumulative_times[msg] += (t - enter_times[msg]); + + long long cpu_t = get_nsec_cpu_time(); + last_cpu_times[msg] = (cpu_t - enter_cpu_times[msg]); + +#ifdef PROFILE_OP_COUNTS + for (std::pair p : op_data_points) + { + cumulative_op_counts[std::make_pair(msg, p.first)] += *(p.second)-op_counts[std::make_pair(msg, p.first)]; + } +#endif + + if (inhibit_profiling_info) + { + return; + } + +#ifdef MULTICORE +#pragma omp critical +#endif + { + if (indent) + { + --indentation; + } + + print_indent(); + printf("(leave) %-35s\t", msg.c_str()); + print_times_from_last_and_start(t, enter_times[msg], cpu_t, enter_cpu_times[msg]); + print_op_profiling(msg); + printf("\n"); + fflush(stdout); + } +} + +void print_mem(const std::string &s) +{ +#ifndef NO_PROCPS + struct proc_t usage; + look_up_our_self(&usage); + if (s.empty()) + { + printf("* Peak vsize (physical memory+swap) in mebibytes: %lu\n", usage.vsize >> 20); + } + else + { + printf("* Peak vsize (physical memory+swap) in mebibytes (%s): %lu\n", s.c_str(), usage.vsize >> 20); + } +#else + printf("* Memory profiling not supported in NO_PROCPS mode\n"); +#endif +} + +void print_compilation_info() +{ +#ifdef __GNUC__ + printf("g++ version: %s\n", __VERSION__); + //printf("Compiled on %s %s\n", __DATE__, __TIME__); +#endif +#ifdef STATIC + printf("STATIC: yes\n"); +#else + printf("STATIC: no\n"); +#endif +#ifdef MULTICORE + printf("MULTICORE: yes\n"); +#else + printf("MULTICORE: no\n"); +#endif +#ifdef DEBUG + printf("DEBUG: yes\n"); +#else + printf("DEBUG: no\n"); +#endif +#ifdef PROFILE_OP_COUNTS + printf("PROFILE_OP_COUNTS: yes\n"); +#else + printf("PROFILE_OP_COUNTS: no\n"); +#endif +#ifdef _GLIBCXX_DEBUG + printf("_GLIBCXX_DEBUG: yes\n"); +#else + printf("_GLIBCXX_DEBUG: no\n"); +#endif +} + +} // libsnark diff --git a/src/snark/libsnark/common/profiling.hpp b/src/snark/libsnark/common/profiling.hpp new file mode 100644 index 000000000..9619117f4 --- /dev/null +++ b/src/snark/libsnark/common/profiling.hpp @@ -0,0 +1,51 @@ +/** @file + ***************************************************************************** + + Declaration of functions for profiling code blocks. + + Reports time, operation counts, memory usage, and others. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PROFILING_HPP_ +#define PROFILING_HPP_ + +#include +#include +#include +#include + +namespace libsnark { + +void start_profiling(); +long long get_nsec_time(); +void print_time(const char* msg); +void print_header(const char* msg); + +void print_indent(); + +extern bool inhibit_profiling_info; +extern bool inhibit_profiling_counters; +extern std::map invocation_counts; +extern std::map last_times; +extern std::map cumulative_times; + +void clear_profiling_counters(); + +void print_cumulative_time_entry(const std::string &key, const long long factor=1); +void print_cumulative_times(const long long factor=1); +void print_cumulative_op_counts(const bool only_fq=false); + +void enter_block(const std::string &msg, const bool indent=true); +void leave_block(const std::string &msg, const bool indent=true); + +void print_mem(const std::string &s = ""); +void print_compilation_info(); + +} // libsnark + +#endif // PROFILING_HPP_ diff --git a/src/snark/libsnark/common/serialization.hpp b/src/snark/libsnark/common/serialization.hpp new file mode 100644 index 000000000..6757e1966 --- /dev/null +++ b/src/snark/libsnark/common/serialization.hpp @@ -0,0 +1,104 @@ +/** @file + ***************************************************************************** + + Declaration of serialization routines and constants. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SERIALIZATION_HPP_ +#define SERIALIZATION_HPP_ + +#include +#include +#include +#include +#include + +namespace libsnark { + +/* + * @todo + * The serialization is fragile. Should be rewritten using a standard, portable-format + * library like boost::serialize. + * + * However, for now the following conventions are used within the code. + * + * All algebraic objects support either binary or decimal output using + * the standard C++ stream operators (operator<<, operator>>). + * + * The binary mode is activated by defining a BINARY_OUTPUT + * preprocessor macro (e.g. g++ -DBINARY_OUTPUT ...). + * + * Binary output assumes that the stream is to be binary read at its + * current position so any white space should be consumed beforehand. + * + * Consecutive algebraic objects are separated by OUTPUT_NEWLINE and + * within themselves (e.g. X and Y coordinates for field elements) with + * OUTPUT_SEPARATOR (as defined below). + * + * Therefore to dump two integers, two Fp elements and another integer + * one would: + * + * out << 3 << "\n"; + * out << 4 << "\n"; + * out << FieldT(56) << OUTPUT_NEWLINE; + * out << FieldT(78) << OUTPUT_NEWLINE; + * out << 9 << "\n"; + * + * Then reading back it its reader's responsibility (!) to consume "\n" + * after 4, but Fp::operator<< will correctly consume OUTPUT_NEWLINE. + * + * The reader should also consume "\n" after 9, so that another field + * element can be properly chained. This is especially important for + * binary output. + * + * The binary serialization of algebraic objects is currently *not* + * portable between machines of different word sizes. + */ + +#ifdef BINARY_OUTPUT +#define OUTPUT_NEWLINE "" +#define OUTPUT_SEPARATOR "" +#else +#define OUTPUT_NEWLINE "\n" +#define OUTPUT_SEPARATOR " " +#endif + +inline void consume_newline(std::istream &in); +inline void consume_OUTPUT_NEWLINE(std::istream &in); +inline void consume_OUTPUT_SEPARATOR(std::istream &in); + +inline void output_bool(std::ostream &out, const bool b); + +inline void output_bool_vector(std::ostream &out, const std::vector &v); + +template +T reserialize(const T &obj); + +template +std::ostream& operator<<(std::ostream& out, const std::vector &v); + +template +std::istream& operator>>(std::ostream& out, std::vector &v); + +template +std::ostream& operator<<(std::ostream& out, const std::map &m); + +template +std::istream& operator>>(std::istream& in, std::map &m); + +template +std::ostream& operator<<(std::ostream& out, const std::set &s); + +template +std::istream& operator>>(std::istream& in, std::set &s); + +} // libsnark + +#include "common/serialization.tcc" + +#endif // SERIALIZATION_HPP_ diff --git a/src/snark/libsnark/common/serialization.tcc b/src/snark/libsnark/common/serialization.tcc new file mode 100644 index 000000000..398f97850 --- /dev/null +++ b/src/snark/libsnark/common/serialization.tcc @@ -0,0 +1,180 @@ +/** @file + ***************************************************************************** + + Implementation of serialization routines. + + See serialization.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SERIALIZATION_TCC_ +#define SERIALIZATION_TCC_ + +#include +#include +#include "common/utils.hpp" + +namespace libsnark { + +inline void consume_newline(std::istream &in) +{ + char c; + in.read(&c, 1); +} + +inline void consume_OUTPUT_NEWLINE(std::istream &in) +{ +#ifdef BINARY_OUTPUT + // nothing to consume + UNUSED(in); +#else + char c; + in.read(&c, 1); +#endif +} + +inline void consume_OUTPUT_SEPARATOR(std::istream &in) +{ +#ifdef BINARY_OUTPUT + // nothing to consume + UNUSED(in); +#else + char c; + in.read(&c, 1); +#endif +} + +inline void output_bool(std::ostream &out, const bool b) +{ + out << (b ? 1 : 0) << "\n"; +} + +inline void output_bool_vector(std::ostream &out, const std::vector &v) +{ + out << v.size() << "\n"; + for (const bool b : v) + { + output_bool(out, b); + } +} + +template +T reserialize(const T &obj) +{ + std::stringstream ss; + ss << obj; + T tmp; + ss >> tmp; + assert(obj == tmp); + return tmp; +} + +template +std::ostream& operator<<(std::ostream& out, const std::vector &v) +{ + static_assert(!std::is_same::value, "this does not work for std::vector"); + out << v.size() << "\n"; + for (const T& t : v) + { + out << t << OUTPUT_NEWLINE; + } + + return out; +} + +template +std::istream& operator>>(std::istream& in, std::vector &v) +{ + static_assert(!std::is_same::value, "this does not work for std::vector"); + size_t size; + in >> size; + consume_newline(in); + + v.resize(0); + for (size_t i = 0; i < size; ++i) + { + T elt; + in >> elt; + consume_OUTPUT_NEWLINE(in); + v.push_back(elt); + } + + return in; +} + +template +std::ostream& operator<<(std::ostream& out, const std::map &m) +{ + out << m.size() << "\n"; + + for (auto &it : m) + { + out << it.first << "\n"; + out << it.second << "\n"; + } + + return out; +} + +template +std::istream& operator>>(std::istream& in, std::map &m) +{ + m.clear(); + size_t size; + in >> size; + consume_newline(in); + + for (size_t i = 0; i < size; ++i) + { + T1 k; + T2 v; + in >> k; + consume_newline(in); + in >> v; + consume_newline(in); + m[k] = v; + } + + return in; +} + +template +std::ostream& operator<<(std::ostream& out, const std::set &s) +{ + out << s.size() << "\n"; + + for (auto &el : s) + { + out << el << "\n"; + } + + return out; +} + + +template +std::istream& operator>>(std::istream& in, std::set &s) +{ + s.clear(); + size_t size; + in >> size; + consume_newline(in); + + for (size_t i = 0; i < size; ++i) + { + T el; + in >> el; + consume_newline(in); + s.insert(el); + } + + return in; +} + +} + +#endif // SERIALIZATION_TCC_ diff --git a/src/snark/libsnark/common/template_utils.hpp b/src/snark/libsnark/common/template_utils.hpp new file mode 100644 index 000000000..8dbfd261d --- /dev/null +++ b/src/snark/libsnark/common/template_utils.hpp @@ -0,0 +1,26 @@ +/** @file + ***************************************************************************** + + Declaration of functions for supporting the use of templates. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef TEMPLATE_UTILS_HPP_ +#define TEMPLATE_UTILS_HPP_ + +namespace libsnark { + +/* A commonly used SFINAE helper type */ +template +struct void_type +{ + typedef void type; +}; + +} // libsnark + +#endif // TEMPLATE_UTILS_HPP_ diff --git a/src/snark/libsnark/common/utils.cpp b/src/snark/libsnark/common/utils.cpp new file mode 100644 index 000000000..dd114fdf0 --- /dev/null +++ b/src/snark/libsnark/common/utils.cpp @@ -0,0 +1,102 @@ +/** @file + ***************************************************************************** + Implementation of misc math and serialization utility functions + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include +#include +#include +#include +#include "common/utils.hpp" + +namespace libsnark { + +size_t log2(size_t n) +/* returns ceil(log2(n)), so 1ul< 1) + { + n >>= 1; + r++; + } + + return r; +} + +size_t bitreverse(size_t n, const size_t l) +{ + size_t r = 0; + for (size_t k = 0; k < l; ++k) + { + r = (r << 1) | (n & 1); + n >>= 1; + } + return r; +} + +bit_vector int_list_to_bits(const std::initializer_list &l, const size_t wordsize) +{ + bit_vector res(wordsize*l.size()); + for (size_t i = 0; i < l.size(); ++i) + { + for (size_t j = 0; j < wordsize; ++j) + { + res[i*wordsize + j] = (*(l.begin()+i) & (1ul<<(wordsize-1-j))); + } + } + return res; +} + +long long div_ceil(long long x, long long y) +{ + return (x + (y-1)) / y; +} + +bool is_little_endian() +{ + uint64_t a = 0x12345678; + unsigned char *c = (unsigned char*)(&a); + return (*c = 0x78); +} + +std::string FORMAT(const std::string &prefix, const char* format, ...) +{ + const static size_t MAX_FMT = 256; + char buf[MAX_FMT]; + va_list args; + va_start(args, format); + vsnprintf(buf, MAX_FMT, format, args); + va_end(args); + + return prefix + std::string(buf); +} + +void serialize_bit_vector(std::ostream &out, const bit_vector &v) +{ + out << v.size() << "\n"; + for (size_t i = 0; i < v.size(); ++i) + { + out << v[i] << "\n"; + } +} + +void deserialize_bit_vector(std::istream &in, bit_vector &v) +{ + size_t size; + in >> size; + v.resize(size); + for (size_t i = 0; i < size; ++i) + { + bool b; + in >> b; + v[i] = b; + } +} +} // libsnark diff --git a/src/snark/libsnark/common/utils.hpp b/src/snark/libsnark/common/utils.hpp new file mode 100644 index 000000000..d7d9e8947 --- /dev/null +++ b/src/snark/libsnark/common/utils.hpp @@ -0,0 +1,57 @@ +/** @file + ***************************************************************************** + Declaration of misc math and serialization utility functions + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef UTILS_HPP_ +#define UTILS_HPP_ + +#include +#include +#include +#include +#include + +namespace libsnark { + +typedef std::vector bit_vector; + +/// returns ceil(log2(n)), so 1ul< &l, const size_t wordsize); +long long div_ceil(long long x, long long y); + +bool is_little_endian(); + +std::string FORMAT(const std::string &prefix, const char* format, ...); + +/* A variadic template to suppress unused argument warnings */ +template +void UNUSED(Types&&...) {} + +#ifdef DEBUG +#define FMT FORMAT +#else +#define FMT(...) (UNUSED(__VA_ARGS__), "") +#endif + +void serialize_bit_vector(std::ostream &out, const bit_vector &v); +void deserialize_bit_vector(std::istream &in, bit_vector &v); + +template +size_t size_in_bits(const std::vector &v); + +#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) + +} // libsnark + +#include "common/utils.tcc" /* note that utils has a templatized part (utils.tcc) and non-templatized part (utils.cpp) */ +#endif // UTILS_HPP_ diff --git a/src/snark/libsnark/common/utils.tcc b/src/snark/libsnark/common/utils.tcc new file mode 100644 index 000000000..f97178f8c --- /dev/null +++ b/src/snark/libsnark/common/utils.tcc @@ -0,0 +1,23 @@ +/** @file + ***************************************************************************** + Implementation of templatized utility functions + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef UTILS_TCC_ +#define UTILS_TCC_ + +namespace libsnark { + +template +size_t size_in_bits(const std::vector &v) +{ + return v.size() * T::size_in_bits(); +} + +} // libsnark + +#endif // UTILS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp b/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp new file mode 100644 index 000000000..bc17e63bc --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/constraint_profiling.cpp @@ -0,0 +1,48 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for profiling constraints. + + See constraint_profiling.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "gadgetlib1/constraint_profiling.hpp" +#include "common/profiling.hpp" + +namespace libsnark { + +size_t constraint_profiling_indent = 0; +std::vector constraint_profiling_table; + +size_t PRINT_CONSTRAINT_PROFILING() +{ + size_t accounted = 0; + print_indent(); + printf("Constraint profiling:\n"); + for (constraint_profiling_entry &ent : constraint_profiling_table) + { + if (ent.indent == 0) + { + accounted += ent.count; + } + + print_indent(); + for (size_t i = 0; i < ent.indent; ++i) + { + printf(" "); + } + printf("* Number of constraints in [%s]: %zu\n", ent.annotation.c_str(), ent.count); + } + + constraint_profiling_table.clear(); + constraint_profiling_indent = 0; + + return accounted; +} + +} diff --git a/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp b/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp new file mode 100644 index 000000000..df8a55de1 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/constraint_profiling.hpp @@ -0,0 +1,42 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for profiling constraints. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef CONSTRAINT_PROFILING_HPP_ +#define CONSTRAINT_PROFILING_HPP_ + +#include +#include +#include +#include + +namespace libsnark { + +extern size_t constraint_profiling_indent; + +struct constraint_profiling_entry { + size_t indent; + std::string annotation; + size_t count; +}; + +extern std::vector constraint_profiling_table; + +#define PROFILE_CONSTRAINTS(pb, annotation) \ + for (size_t _num_constraints_before = pb.num_constraints(), _iter = (++constraint_profiling_indent, 0), _cp_pos = constraint_profiling_table.size(); \ + _iter == 0; \ + constraint_profiling_table.insert(constraint_profiling_table.begin() + _cp_pos, constraint_profiling_entry{--constraint_profiling_indent, annotation, pb.num_constraints() - _num_constraints_before}), \ + _iter = 1) + +size_t PRINT_CONSTRAINT_PROFILING(); // returns # of top level constraints + +} // libsnark + +#endif // CONSTRAINT_PROFILING_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp b/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp new file mode 100644 index 000000000..faa3a9605 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/examples/simple_example.hpp @@ -0,0 +1,23 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SIMPLE_EXAMPLE_HPP_ +#define SIMPLE_EXAMPLE_HPP_ + +#include "examples/r1cs_examples.hpp" + +namespace libsnark { + +template +r1cs_example gen_r1cs_example_from_protoboard(const size_t num_constraints, + const size_t num_inputs); + +} // libsnark + +#include "gadgetlib1/examples/simple_example.tcc" + +#endif // SIMPLE_EXAMPLE_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc b/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc new file mode 100644 index 000000000..9d500b5c7 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/examples/simple_example.tcc @@ -0,0 +1,54 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SIMPLE_EXAMPLE_TCC_ +#define SIMPLE_EXAMPLE_TCC_ + +#include +#include "gadgetlib1/gadgets/basic_gadgets.hpp" + +namespace libsnark { + +/* NOTE: all examples here actually generate one constraint less to account for soundness constraint in QAP */ + +template +r1cs_example gen_r1cs_example_from_protoboard(const size_t num_constraints, + const size_t num_inputs) +{ + const size_t new_num_constraints = num_constraints - 1; + + /* construct dummy example: inner products of two vectors */ + protoboard pb; + pb_variable_array A; + pb_variable_array B; + pb_variable res; + + // the variables on the protoboard are (ONE (constant 1 term), res, A[0], ..., A[num_constraints-1], B[0], ..., B[num_constraints-1]) + res.allocate(pb, "res"); + A.allocate(pb, new_num_constraints, "A"); + B.allocate(pb, new_num_constraints, "B"); + + inner_product_gadget compute_inner_product(pb, A, B, res, "compute_inner_product"); + compute_inner_product.generate_r1cs_constraints(); + + /* fill in random example */ + for (size_t i = 0; i < new_num_constraints; ++i) + { + pb.val(A[i]) = FieldT::random_element(); + pb.val(B[i]) = FieldT::random_element(); + } + + compute_inner_product.generate_r1cs_witness(); + + pb.constraint_system.num_inputs = num_inputs; + const r1cs_variable_assignment va = pb.values; + const r1cs_variable_assignment input(va.begin(), va.begin() + num_inputs); + return r1cs_example(pb.constraint_system, input, va, num_inputs); +} + +} // libsnark +#endif // R1CS_EXAMPLES_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadget.hpp b/src/snark/libsnark/gadgetlib1/gadget.hpp new file mode 100644 index 000000000..dbeaa9d4b --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadget.hpp @@ -0,0 +1,27 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef GADGET_HPP_ +#define GADGET_HPP_ + +#include "gadgetlib1/protoboard.hpp" + +namespace libsnark { + +template +class gadget { +protected: + protoboard &pb; + const std::string annotation_prefix; +public: + gadget(protoboard &pb, const std::string &annotation_prefix=""); +}; + +} // libsnark +#include "gadgetlib1/gadget.tcc" + +#endif // GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadget.tcc b/src/snark/libsnark/gadgetlib1/gadget.tcc new file mode 100644 index 000000000..120229bbe --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadget.tcc @@ -0,0 +1,23 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef GADGET_TCC_ +#define GADGET_TCC_ + +namespace libsnark { + +template +gadget::gadget(protoboard &pb, const std::string &annotation_prefix) : + pb(pb), annotation_prefix(annotation_prefix) +{ +#ifdef DEBUG + assert(annotation_prefix != ""); +#endif +} + +} // libsnark +#endif // GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp new file mode 100644 index 000000000..08e596bee --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.hpp @@ -0,0 +1,351 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_GADGETS_HPP_ +#define BASIC_GADGETS_HPP_ + +#include +#include + +#include "gadgetlib1/gadget.hpp" + +namespace libsnark { + +/* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ +template +void generate_boolean_r1cs_constraint(protoboard &pb, const pb_linear_combination &lc, const std::string &annotation_prefix=""); + +template +void generate_r1cs_equals_const_constraint(protoboard &pb, const pb_linear_combination &lc, const FieldT& c, const std::string &annotation_prefix=""); + +template +class packing_gadget : public gadget { +private: + /* no internal variables */ +public: + const pb_linear_combination_array bits; + const pb_linear_combination packed; + + packing_gadget(protoboard &pb, + const pb_linear_combination_array &bits, + const pb_linear_combination &packed, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), bits(bits), packed(packed) {} + + void generate_r1cs_constraints(const bool enforce_bitness); + /* adds constraint result = \sum bits[i] * 2^i */ + + void generate_r1cs_witness_from_packed(); + void generate_r1cs_witness_from_bits(); +}; + +template +class multipacking_gadget : public gadget { +private: + std::vector > packers; +public: + const pb_linear_combination_array bits; + const pb_linear_combination_array packed_vars; + + const size_t chunk_size; + const size_t num_chunks; + // const size_t last_chunk_size; + + multipacking_gadget(protoboard &pb, + const pb_linear_combination_array &bits, + const pb_linear_combination_array &packed_vars, + const size_t chunk_size, + const std::string &annotation_prefix=""); + void generate_r1cs_constraints(const bool enforce_bitness); + void generate_r1cs_witness_from_packed(); + void generate_r1cs_witness_from_bits(); +}; + +template +class field_vector_copy_gadget : public gadget { +public: + const pb_variable_array source; + const pb_variable_array target; + const pb_linear_combination do_copy; + + field_vector_copy_gadget(protoboard &pb, + const pb_variable_array &source, + const pb_variable_array &target, + const pb_linear_combination &do_copy, + const std::string &annotation_prefix=""); + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +class bit_vector_copy_gadget : public gadget { +public: + const pb_variable_array source_bits; + const pb_variable_array target_bits; + const pb_linear_combination do_copy; + + pb_variable_array packed_source; + pb_variable_array packed_target; + + std::shared_ptr > pack_source; + std::shared_ptr > pack_target; + std::shared_ptr > copier; + + const size_t chunk_size; + const size_t num_chunks; + + bit_vector_copy_gadget(protoboard &pb, + const pb_variable_array &source_bits, + const pb_variable_array &target_bits, + const pb_linear_combination &do_copy, + const size_t chunk_size, + const std::string &annotation_prefix=""); + void generate_r1cs_constraints(const bool enforce_source_bitness, const bool enforce_target_bitness); + void generate_r1cs_witness(); +}; + +template +class dual_variable_gadget : public gadget { +private: + std::shared_ptr > consistency_check; +public: + pb_variable packed; + pb_variable_array bits; + + dual_variable_gadget(protoboard &pb, + const size_t width, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix) + { + packed.allocate(pb, FMT(this->annotation_prefix, " packed")); + bits.allocate(pb, width, FMT(this->annotation_prefix, " bits")); + consistency_check.reset(new packing_gadget(pb, + bits, + packed, + FMT(this->annotation_prefix, " consistency_check"))); + } + + dual_variable_gadget(protoboard &pb, + const pb_variable_array &bits, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), bits(bits) + { + packed.allocate(pb, FMT(this->annotation_prefix, " packed")); + consistency_check.reset(new packing_gadget(pb, + bits, + packed, + FMT(this->annotation_prefix, " consistency_check"))); + } + + dual_variable_gadget(protoboard &pb, + const pb_variable &packed, + const size_t width, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), packed(packed) + { + bits.allocate(pb, width, FMT(this->annotation_prefix, " bits")); + consistency_check.reset(new packing_gadget(pb, + bits, + packed, + FMT(this->annotation_prefix, " consistency_check"))); + } + + void generate_r1cs_constraints(const bool enforce_bitness); + void generate_r1cs_witness_from_packed(); + void generate_r1cs_witness_from_bits(); +}; + +/* + the gadgets below are Fp specific: + I * X = R + (1-R) * X = 0 + + if X = 0 then R = 0 + if X != 0 then R = 1 and I = X^{-1} +*/ + +template +class disjunction_gadget : public gadget { +private: + pb_variable inv; +public: + const pb_variable_array inputs; + const pb_variable output; + + disjunction_gadget(protoboard& pb, + const pb_variable_array &inputs, + const pb_variable &output, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), inputs(inputs), output(output) + { + assert(inputs.size() >= 1); + inv.allocate(pb, FMT(this->annotation_prefix, " inv")); + } + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +void test_disjunction_gadget(const size_t n); + +template +class conjunction_gadget : public gadget { +private: + pb_variable inv; +public: + const pb_variable_array inputs; + const pb_variable output; + + conjunction_gadget(protoboard& pb, + const pb_variable_array &inputs, + const pb_variable &output, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), inputs(inputs), output(output) + { + assert(inputs.size() >= 1); + inv.allocate(pb, FMT(this->annotation_prefix, " inv")); + } + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +void test_conjunction_gadget(const size_t n); + +template +class comparison_gadget : public gadget { +private: + pb_variable_array alpha; + pb_variable alpha_packed; + std::shared_ptr > pack_alpha; + + std::shared_ptr > all_zeros_test; + pb_variable not_all_zeros; +public: + const size_t n; + const pb_linear_combination A; + const pb_linear_combination B; + const pb_variable less; + const pb_variable less_or_eq; + + comparison_gadget(protoboard& pb, + const size_t n, + const pb_linear_combination &A, + const pb_linear_combination &B, + const pb_variable &less, + const pb_variable &less_or_eq, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), n(n), A(A), B(B), less(less), less_or_eq(less_or_eq) + { + alpha.allocate(pb, n, FMT(this->annotation_prefix, " alpha")); + alpha.emplace_back(less_or_eq); // alpha[n] is less_or_eq + + alpha_packed.allocate(pb, FMT(this->annotation_prefix, " alpha_packed")); + not_all_zeros.allocate(pb, FMT(this->annotation_prefix, " not_all_zeros")); + + pack_alpha.reset(new packing_gadget(pb, alpha, alpha_packed, + FMT(this->annotation_prefix, " pack_alpha"))); + + all_zeros_test.reset(new disjunction_gadget(pb, + pb_variable_array(alpha.begin(), alpha.begin() + n), + not_all_zeros, + FMT(this->annotation_prefix, " all_zeros_test"))); + }; + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +void test_comparison_gadget(const size_t n); + +template +class inner_product_gadget : public gadget { +private: + /* S_i = \sum_{k=0}^{i+1} A[i] * B[i] */ + pb_variable_array S; +public: + const pb_linear_combination_array A; + const pb_linear_combination_array B; + const pb_variable result; + + inner_product_gadget(protoboard& pb, + const pb_linear_combination_array &A, + const pb_linear_combination_array &B, + const pb_variable &result, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), A(A), B(B), result(result) + { + assert(A.size() >= 1); + assert(A.size() == B.size()); + + S.allocate(pb, A.size()-1, FMT(this->annotation_prefix, " S")); + } + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +void test_inner_product_gadget(const size_t n); + +template +class loose_multiplexing_gadget : public gadget { +/* + this implements loose multiplexer: + index not in bounds -> success_flag = 0 + index in bounds && success_flag = 1 -> result is correct + however if index is in bounds we can also set success_flag to 0 (and then result will be forced to be 0) +*/ +public: + pb_variable_array alpha; +private: + std::shared_ptr > compute_result; +public: + const pb_linear_combination_array arr; + const pb_variable index; + const pb_variable result; + const pb_variable success_flag; + + loose_multiplexing_gadget(protoboard& pb, + const pb_linear_combination_array &arr, + const pb_variable &index, + const pb_variable &result, + const pb_variable &success_flag, + const std::string &annotation_prefix="") : + gadget(pb, annotation_prefix), arr(arr), index(index), result(result), success_flag(success_flag) + { + alpha.allocate(pb, arr.size(), FMT(this->annotation_prefix, " alpha")); + compute_result.reset(new inner_product_gadget(pb, alpha, arr, result, FMT(this->annotation_prefix, " compute_result"))); + }; + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +void test_loose_multiplexing_gadget(const size_t n); + +template +void create_linear_combination_constraints(protoboard &pb, + const std::vector &base, + const std::vector > &v, + const VarT &target, + const std::string &annotation_prefix); + +template +void create_linear_combination_witness(protoboard &pb, + const std::vector &base, + const std::vector > &v, + const VarT &target); + +} // libsnark +#include "gadgetlib1/gadgets/basic_gadgets.tcc" + +#endif // BASIC_GADGETS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc new file mode 100644 index 000000000..213b1906f --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/basic_gadgets.tcc @@ -0,0 +1,705 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef BASIC_GADGETS_TCC_ +#define BASIC_GADGETS_TCC_ + +#include "common/profiling.hpp" +#include "common/utils.hpp" + +namespace libsnark { + +template +void generate_boolean_r1cs_constraint(protoboard &pb, const pb_linear_combination &lc, const std::string &annotation_prefix) +/* forces lc to take value 0 or 1 by adding constraint lc * (1-lc) = 0 */ +{ + pb.add_r1cs_constraint(r1cs_constraint(lc, 1-lc, 0), + FMT(annotation_prefix, " boolean_r1cs_constraint")); +} + +template +void generate_r1cs_equals_const_constraint(protoboard &pb, const pb_linear_combination &lc, const FieldT& c, const std::string &annotation_prefix) +{ + pb.add_r1cs_constraint(r1cs_constraint(1, lc, c), + FMT(annotation_prefix, " constness_constraint")); +} + +template +void packing_gadget::generate_r1cs_constraints(const bool enforce_bitness) +/* adds constraint result = \sum bits[i] * 2^i */ +{ + this->pb.add_r1cs_constraint(r1cs_constraint(1, pb_packing_sum(bits), packed), FMT(this->annotation_prefix, " packing_constraint")); + + if (enforce_bitness) + { + for (size_t i = 0; i < bits.size(); ++i) + { + generate_boolean_r1cs_constraint(this->pb, bits[i], FMT(this->annotation_prefix, " bitness_%zu", i)); + } + } +} + +template +void packing_gadget::generate_r1cs_witness_from_packed() +{ + packed.evaluate(this->pb); + assert(this->pb.lc_val(packed).as_bigint().num_bits() <= bits.size()); + bits.fill_with_bits_of_field_element(this->pb, this->pb.lc_val(packed)); +} + +template +void packing_gadget::generate_r1cs_witness_from_bits() +{ + bits.evaluate(this->pb); + this->pb.lc_val(packed) = bits.get_field_element_from_bits(this->pb); +} + +template +multipacking_gadget::multipacking_gadget(protoboard &pb, + const pb_linear_combination_array &bits, + const pb_linear_combination_array &packed_vars, + const size_t chunk_size, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), bits(bits), packed_vars(packed_vars), + chunk_size(chunk_size), + num_chunks(div_ceil(bits.size(), chunk_size)) + // last_chunk_size(bits.size() - (num_chunks-1) * chunk_size) +{ + assert(packed_vars.size() == num_chunks); + for (size_t i = 0; i < num_chunks; ++i) + { + packers.emplace_back(packing_gadget(this->pb, pb_linear_combination_array(bits.begin() + i * chunk_size, + bits.begin() + std::min((i+1) * chunk_size, bits.size())), + packed_vars[i], FMT(this->annotation_prefix, " packers_%zu", i))); + } +} + +template +void multipacking_gadget::generate_r1cs_constraints(const bool enforce_bitness) +{ + for (size_t i = 0; i < num_chunks; ++i) + { + packers[i].generate_r1cs_constraints(enforce_bitness); + } +} + +template +void multipacking_gadget::generate_r1cs_witness_from_packed() +{ + for (size_t i = 0; i < num_chunks; ++i) + { + packers[i].generate_r1cs_witness_from_packed(); + } +} + +template +void multipacking_gadget::generate_r1cs_witness_from_bits() +{ + for (size_t i = 0; i < num_chunks; ++i) + { + packers[i].generate_r1cs_witness_from_bits(); + } +} + +template +size_t multipacking_num_chunks(const size_t num_bits) +{ + return div_ceil(num_bits, FieldT::capacity()); +} + +template +field_vector_copy_gadget::field_vector_copy_gadget(protoboard &pb, + const pb_variable_array &source, + const pb_variable_array &target, + const pb_linear_combination &do_copy, + const std::string &annotation_prefix) : +gadget(pb, annotation_prefix), source(source), target(target), do_copy(do_copy) +{ + assert(source.size() == target.size()); +} + +template +void field_vector_copy_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < source.size(); ++i) + { + this->pb.add_r1cs_constraint(r1cs_constraint(do_copy, source[i] - target[i], 0), + FMT(this->annotation_prefix, " copying_check_%zu", i)); + } +} + +template +void field_vector_copy_gadget::generate_r1cs_witness() +{ + do_copy.evaluate(this->pb); + assert(this->pb.lc_val(do_copy) == FieldT::one() || this->pb.lc_val(do_copy) == FieldT::zero()); + if (this->pb.lc_val(do_copy) != FieldT::zero()) + { + for (size_t i = 0; i < source.size(); ++i) + { + this->pb.val(target[i]) = this->pb.val(source[i]); + } + } +} + +template +bit_vector_copy_gadget::bit_vector_copy_gadget(protoboard &pb, + const pb_variable_array &source_bits, + const pb_variable_array &target_bits, + const pb_linear_combination &do_copy, + const size_t chunk_size, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), source_bits(source_bits), target_bits(target_bits), do_copy(do_copy), + chunk_size(chunk_size), num_chunks(div_ceil(source_bits.size(), chunk_size)) +{ + assert(source_bits.size() == target_bits.size()); + + packed_source.allocate(pb, num_chunks, FMT(annotation_prefix, " packed_source")); + pack_source.reset(new multipacking_gadget(pb, source_bits, packed_source, chunk_size, FMT(annotation_prefix, " pack_source"))); + + packed_target.allocate(pb, num_chunks, FMT(annotation_prefix, " packed_target")); + pack_target.reset(new multipacking_gadget(pb, target_bits, packed_target, chunk_size, FMT(annotation_prefix, " pack_target"))); + + copier.reset(new field_vector_copy_gadget(pb, packed_source, packed_target, do_copy, FMT(annotation_prefix, " copier"))); +} + +template +void bit_vector_copy_gadget::generate_r1cs_constraints(const bool enforce_source_bitness, const bool enforce_target_bitness) +{ + pack_source->generate_r1cs_constraints(enforce_source_bitness); + pack_target->generate_r1cs_constraints(enforce_target_bitness); + + copier->generate_r1cs_constraints(); +} + +template +void bit_vector_copy_gadget::generate_r1cs_witness() +{ + do_copy.evaluate(this->pb); + assert(this->pb.lc_val(do_copy) == FieldT::zero() || this->pb.lc_val(do_copy) == FieldT::one()); + if (this->pb.lc_val(do_copy) == FieldT::one()) + { + for (size_t i = 0; i < source_bits.size(); ++i) + { + this->pb.val(target_bits[i]) = this->pb.val(source_bits[i]); + } + } + + pack_source->generate_r1cs_witness_from_bits(); + pack_target->generate_r1cs_witness_from_bits(); +} + +template +void dual_variable_gadget::generate_r1cs_constraints(const bool enforce_bitness) +{ + consistency_check->generate_r1cs_constraints(enforce_bitness); +} + +template +void dual_variable_gadget::generate_r1cs_witness_from_packed() +{ + consistency_check->generate_r1cs_witness_from_packed(); +} + +template +void dual_variable_gadget::generate_r1cs_witness_from_bits() +{ + consistency_check->generate_r1cs_witness_from_bits(); +} + +template +void disjunction_gadget::generate_r1cs_constraints() +{ + /* inv * sum = output */ + linear_combination a1, b1, c1; + a1.add_term(inv); + for (size_t i = 0; i < inputs.size(); ++i) + { + b1.add_term(inputs[i]); + } + c1.add_term(output); + + this->pb.add_r1cs_constraint(r1cs_constraint(a1, b1, c1), FMT(this->annotation_prefix, " inv*sum=output")); + + /* (1-output) * sum = 0 */ + linear_combination a2, b2, c2; + a2.add_term(ONE); + a2.add_term(output, -1); + for (size_t i = 0; i < inputs.size(); ++i) + { + b2.add_term(inputs[i]); + } + c2.add_term(ONE, 0); + + this->pb.add_r1cs_constraint(r1cs_constraint(a2, b2, c2), FMT(this->annotation_prefix, " (1-output)*sum=0")); +} + +template +void disjunction_gadget::generate_r1cs_witness() +{ + FieldT sum = FieldT::zero(); + + for (size_t i = 0; i < inputs.size(); ++i) + { + sum += this->pb.val(inputs[i]); + } + + if (sum.is_zero()) + { + this->pb.val(inv) = FieldT::zero(); + this->pb.val(output) = FieldT::zero(); + } + else + { + this->pb.val(inv) = sum.inverse(); + this->pb.val(output) = FieldT::one(); + } +} + +template +void test_disjunction_gadget(const size_t n) +{ + printf("testing disjunction_gadget on all %zu bit strings\n", n); + + protoboard pb; + pb_variable_array inputs; + inputs.allocate(pb, n, "inputs"); + + pb_variable output; + output.allocate(pb, "output"); + + disjunction_gadget d(pb, inputs, output, "d"); + d.generate_r1cs_constraints(); + + for (size_t w = 0; w < 1ul< +void conjunction_gadget::generate_r1cs_constraints() +{ + /* inv * (n-sum) = 1-output */ + linear_combination a1, b1, c1; + a1.add_term(inv); + b1.add_term(ONE, inputs.size()); + for (size_t i = 0; i < inputs.size(); ++i) + { + b1.add_term(inputs[i], -1); + } + c1.add_term(ONE); + c1.add_term(output, -1); + + this->pb.add_r1cs_constraint(r1cs_constraint(a1, b1, c1), FMT(this->annotation_prefix, " inv*(n-sum)=(1-output)")); + + /* output * (n-sum) = 0 */ + linear_combination a2, b2, c2; + a2.add_term(output); + b2.add_term(ONE, inputs.size()); + for (size_t i = 0; i < inputs.size(); ++i) + { + b2.add_term(inputs[i], -1); + } + c2.add_term(ONE, 0); + + this->pb.add_r1cs_constraint(r1cs_constraint(a2, b2, c2), FMT(this->annotation_prefix, " output*(n-sum)=0")); +} + +template +void conjunction_gadget::generate_r1cs_witness() +{ + FieldT sum = FieldT(inputs.size()); + + for (size_t i = 0; i < inputs.size(); ++i) + { + sum -= this->pb.val(inputs[i]); + } + + if (sum.is_zero()) + { + this->pb.val(inv) = FieldT::zero(); + this->pb.val(output) = FieldT::one(); + } + else + { + this->pb.val(inv) = sum.inverse(); + this->pb.val(output) = FieldT::zero(); + } +} + +template +void test_conjunction_gadget(const size_t n) +{ + printf("testing conjunction_gadget on all %zu bit strings\n", n); + + protoboard pb; + pb_variable_array inputs; + inputs.allocate(pb, n, "inputs"); + + pb_variable output; + output.allocate(pb, "output"); + + conjunction_gadget c(pb, inputs, output, "c"); + c.generate_r1cs_constraints(); + + for (size_t w = 0; w < 1ul< +void comparison_gadget::generate_r1cs_constraints() +{ + /* + packed(alpha) = 2^n + B - A + + not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i + + if B - A > 0, then 2^n + B - A > 2^n, + so alpha_n = 1 and not_all_zeros = 1 + if B - A = 0, then 2^n + B - A = 2^n, + so alpha_n = 1 and not_all_zeros = 0 + if B - A < 0, then 2^n + B - A \in {0, 1, \ldots, 2^n-1}, + so alpha_n = 0 + + therefore alpha_n = less_or_eq and alpha_n * not_all_zeros = less + */ + + /* not_all_zeros to be Boolean, alpha_i are Boolean by packing gadget */ + generate_boolean_r1cs_constraint(this->pb, not_all_zeros, + FMT(this->annotation_prefix, " not_all_zeros")); + + /* constraints for packed(alpha) = 2^n + B - A */ + pack_alpha->generate_r1cs_constraints(true); + this->pb.add_r1cs_constraint(r1cs_constraint(1, (FieldT(2)^n) + B - A, alpha_packed), FMT(this->annotation_prefix, " main_constraint")); + + /* compute result */ + all_zeros_test->generate_r1cs_constraints(); + this->pb.add_r1cs_constraint(r1cs_constraint(less_or_eq, not_all_zeros, less), + FMT(this->annotation_prefix, " less")); +} + +template +void comparison_gadget::generate_r1cs_witness() +{ + A.evaluate(this->pb); + B.evaluate(this->pb); + + /* unpack 2^n + B - A into alpha_packed */ + this->pb.val(alpha_packed) = (FieldT(2)^n) + this->pb.lc_val(B) - this->pb.lc_val(A); + pack_alpha->generate_r1cs_witness_from_packed(); + + /* compute result */ + all_zeros_test->generate_r1cs_witness(); + this->pb.val(less) = this->pb.val(less_or_eq) * this->pb.val(not_all_zeros); +} + +template +void test_comparison_gadget(const size_t n) +{ + printf("testing comparison_gadget on all %zu bit inputs\n", n); + + protoboard pb; + + pb_variable A, B, less, less_or_eq; + A.allocate(pb, "A"); + B.allocate(pb, "B"); + less.allocate(pb, "less"); + less_or_eq.allocate(pb, "less_or_eq"); + + comparison_gadget cmp(pb, n, A, B, less, less_or_eq, "cmp"); + cmp.generate_r1cs_constraints(); + + for (size_t a = 0; a < 1ul< +void inner_product_gadget::generate_r1cs_constraints() +{ + /* + S_i = \sum_{k=0}^{i+1} A[i] * B[i] + S[0] = A[0] * B[0] + S[i+1] - S[i] = A[i] * B[i] + */ + for (size_t i = 0; i < A.size(); ++i) + { + this->pb.add_r1cs_constraint( + r1cs_constraint(A[i], B[i], + (i == A.size()-1 ? result : S[i]) + (i == 0 ? 0 * ONE : -S[i-1])), + FMT(this->annotation_prefix, " S_%zu", i)); + } +} + +template +void inner_product_gadget::generate_r1cs_witness() +{ + FieldT total = FieldT::zero(); + for (size_t i = 0; i < A.size(); ++i) + { + A[i].evaluate(this->pb); + B[i].evaluate(this->pb); + + total += this->pb.lc_val(A[i]) * this->pb.lc_val(B[i]); + this->pb.val(i == A.size()-1 ? result : S[i]) = total; + } +} + +template +void test_inner_product_gadget(const size_t n) +{ + printf("testing inner_product_gadget on all %zu bit strings\n", n); + + protoboard pb; + pb_variable_array A; + A.allocate(pb, n, "A"); + pb_variable_array B; + B.allocate(pb, n, "B"); + + pb_variable result; + result.allocate(pb, "result"); + + inner_product_gadget g(pb, A, B, result, "g"); + g.generate_r1cs_constraints(); + + for (size_t i = 0; i < 1ul< +void loose_multiplexing_gadget::generate_r1cs_constraints() +{ + /* \alpha_i (index - i) = 0 */ + for (size_t i = 0; i < arr.size(); ++i) + { + this->pb.add_r1cs_constraint( + r1cs_constraint(alpha[i], index - i, 0), + FMT(this->annotation_prefix, " alpha_%zu", i)); + } + + /* 1 * (\sum \alpha_i) = success_flag */ + linear_combination a, b, c; + a.add_term(ONE); + for (size_t i = 0; i < arr.size(); ++i) + { + b.add_term(alpha[i]); + } + c.add_term(success_flag); + this->pb.add_r1cs_constraint(r1cs_constraint(a, b, c), FMT(this->annotation_prefix, " main_constraint")); + + /* now success_flag is constrained to either 0 (if index is out of + range) or \alpha_i. constrain it and \alpha_i to zero */ + generate_boolean_r1cs_constraint(this->pb, success_flag, FMT(this->annotation_prefix, " success_flag")); + + /* compute result */ + compute_result->generate_r1cs_constraints(); +} + +template +void loose_multiplexing_gadget::generate_r1cs_witness() +{ + /* assumes that idx can be fit in ulong; true for our purposes for now */ + const bigint valint = this->pb.val(index).as_bigint(); + unsigned long idx = valint.as_ulong(); + const bigint arrsize(arr.size()); + + if (idx >= arr.size() || mpn_cmp(valint.data, arrsize.data, FieldT::num_limbs) >= 0) + { + for (size_t i = 0; i < arr.size(); ++i) + { + this->pb.val(alpha[i]) = FieldT::zero(); + } + + this->pb.val(success_flag) = FieldT::zero(); + } + else + { + for (size_t i = 0; i < arr.size(); ++i) + { + this->pb.val(alpha[i]) = (i == idx ? FieldT::one() : FieldT::zero()); + } + + this->pb.val(success_flag) = FieldT::one(); + } + + compute_result->generate_r1cs_witness(); +} + +template +void test_loose_multiplexing_gadget(const size_t n) +{ + printf("testing loose_multiplexing_gadget on 2**%zu pb_variable array inputs\n", n); + protoboard pb; + + pb_variable_array arr; + arr.allocate(pb, 1ul< index, result, success_flag; + index.allocate(pb, "index"); + result.allocate(pb, "result"); + success_flag.allocate(pb, "success_flag"); + + loose_multiplexing_gadget g(pb, arr, index, result, success_flag, "g"); + g.generate_r1cs_constraints(); + + for (size_t i = 0; i < 1ul< +void create_linear_combination_constraints(protoboard &pb, + const std::vector &base, + const std::vector > &v, + const VarT &target, + const std::string &annotation_prefix) +{ + for (size_t i = 0; i < base.size(); ++i) + { + linear_combination a, b, c; + + a.add_term(ONE); + b.add_term(ONE, base[i]); + + for (auto &p : v) + { + b.add_term(p.first.all_vars[i], p.second); + } + + c.add_term(target.all_vars[i]); + + pb.add_r1cs_constraint(r1cs_constraint(a, b, c), FMT(annotation_prefix, " linear_combination_%zu", i)); + } +} + +template +void create_linear_combination_witness(protoboard &pb, + const std::vector &base, + const std::vector > &v, + const VarT &target) +{ + for (size_t i = 0; i < base.size(); ++i) + { + pb.val(target.all_vars[i]) = base[i]; + + for (auto &p : v) + { + pb.val(target.all_vars[i]) += p.second * pb.val(p.first.all_vars[i]); + } + } +} + +} // libsnark +#endif // BASIC_GADGETS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp new file mode 100644 index 000000000..e4b8a2acf --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.hpp @@ -0,0 +1,45 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a gadget that can be created from an R1CS constraint system. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef GADGET_FROM_R1CS_HPP_ +#define GADGET_FROM_R1CS_HPP_ + +#include + +#include "gadgetlib1/gadget.hpp" + +namespace libsnark { + +template +class gadget_from_r1cs : public gadget { + +private: + const std::vector > vars; + const r1cs_constraint_system cs; + std::map cs_to_vars; + +public: + + gadget_from_r1cs(protoboard &pb, + const std::vector > &vars, + const r1cs_constraint_system &cs, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input); +}; + +} // libsnark + +#include "gadgetlib1/gadgets/gadget_from_r1cs.tcc" + +#endif // GADGET_FROM_R1CS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc new file mode 100644 index 000000000..bc59b4587 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc @@ -0,0 +1,123 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for a gadget that can be created from an R1CS constraint system. + + See gadget_from_r1cs.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef GADGET_FROM_R1CS_TCC_ +#define GADGET_FROM_R1CS_TCC_ + +namespace libsnark { + +template +gadget_from_r1cs::gadget_from_r1cs(protoboard &pb, + const std::vector > &vars, + const r1cs_constraint_system &cs, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + vars(vars), + cs(cs) +{ + cs_to_vars[0] = 0; /* constant term maps to constant term */ + + size_t cs_var_idx = 1; + for (auto va : vars) + { +#ifdef DEBUG + printf("gadget_from_r1cs: translating a block of variables with length %zu\n", va.size()); +#endif + for (auto v : va) + { + cs_to_vars[cs_var_idx] = v.index; + +#ifdef DEBUG + if (v.index != 0) + { + // handle annotations, except for re-annotating constant term + const std::map::const_iterator it = cs.variable_annotations.find(cs_var_idx); + + std::string annotation = FMT(annotation_prefix, " variable_%zu", cs_var_idx); + if (it != cs.variable_annotations.end()) + { + annotation = annotation_prefix + " " + it->second; + } + + pb.augment_variable_annotation(v, annotation); + } +#endif + ++cs_var_idx; + } + } + +#ifdef DEBUG + printf("gadget_from_r1cs: sum of all block lengths: %zu\n", cs_var_idx-1); + printf("gadget_from_r1cs: cs.num_variables(): %zu\n", cs.num_variables()); +#endif + + assert(cs_var_idx - 1 == cs.num_variables()); +} + +template +void gadget_from_r1cs::generate_r1cs_constraints() +{ + for (size_t i = 0; i < cs.num_constraints(); ++i) + { + const r1cs_constraint &constr = cs.constraints[i]; + r1cs_constraint translated_constr; + + for (const linear_term &t: constr.a.terms) + { + translated_constr.a.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); + } + + for (const linear_term &t: constr.b.terms) + { + translated_constr.b.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); + } + + for (const linear_term &t: constr.c.terms) + { + translated_constr.c.terms.emplace_back(linear_term(pb_variable(cs_to_vars[t.index]), t.coeff)); + } + + std::string annotation = FMT(this->annotation_prefix, " constraint_%zu", i); + +#ifdef DEBUG + auto it = cs.constraint_annotations.find(i); + if (it != cs.constraint_annotations.end()) + { + annotation = this->annotation_prefix + " " + it->second; + } +#endif + this->pb.add_r1cs_constraint(translated_constr, annotation); + } +} + +template +void gadget_from_r1cs::generate_r1cs_witness(const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input) +{ + assert(cs.num_inputs() == primary_input.size()); + assert(cs.num_variables() == primary_input.size() + auxiliary_input.size()); + + for (size_t i = 0; i < primary_input.size(); ++i) + { + this->pb.val(pb_variable(cs_to_vars[i+1])) = primary_input[i]; + } + + for (size_t i = 0; i < auxiliary_input.size(); ++i) + { + this->pb.val(pb_variable(cs_to_vars[primary_input.size()+i+1])) = auxiliary_input[i]; + } +} + +} // libsnark + +#endif // GADGET_FROM_R1CS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp new file mode 100644 index 000000000..a7598b9be --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp @@ -0,0 +1,42 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#ifndef DIGEST_SELECTOR_GADGET_HPP_ +#define DIGEST_SELECTOR_GADGET_HPP_ + +#include + +#include "gadgetlib1/gadgets/basic_gadgets.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" + +namespace libsnark { + +template +class digest_selector_gadget : public gadget { +public: + size_t digest_size; + digest_variable input; + pb_linear_combination is_right; + digest_variable left; + digest_variable right; + + digest_selector_gadget(protoboard &pb, + const size_t digest_size, + const digest_variable &input, + const pb_linear_combination &is_right, + const digest_variable &left, + const digest_variable &right, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +} // libsnark + +#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc" + +#endif // DIGEST_SELECTOR_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc new file mode 100644 index 000000000..422ee170a --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/digest_selector_gadget.tcc @@ -0,0 +1,62 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#ifndef DIGEST_SELECTOR_GADGET_TCC_ +#define DIGEST_SELECTOR_GADGET_TCC_ + +namespace libsnark { + +template +digest_selector_gadget::digest_selector_gadget(protoboard &pb, + const size_t digest_size, + const digest_variable &input, + const pb_linear_combination &is_right, + const digest_variable &left, + const digest_variable &right, + const std::string &annotation_prefix) : +gadget(pb, annotation_prefix), digest_size(digest_size), input(input), is_right(is_right), left(left), right(right) +{ +} + +template +void digest_selector_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < digest_size; ++i) + { + /* + input = is_right * right + (1-is_right) * left + input - left = is_right(right - left) + */ + this->pb.add_r1cs_constraint(r1cs_constraint(is_right, right.bits[i] - left.bits[i], input.bits[i] - left.bits[i]), + FMT(this->annotation_prefix, " propagate_%zu", i)); + } +} + +template +void digest_selector_gadget::generate_r1cs_witness() +{ + is_right.evaluate(this->pb); + + assert(this->pb.lc_val(is_right) == FieldT::one() || this->pb.lc_val(is_right) == FieldT::zero()); + if (this->pb.lc_val(is_right) == FieldT::one()) + { + for (size_t i = 0; i < digest_size; ++i) + { + this->pb.val(right.bits[i]) = this->pb.val(input.bits[i]); + } + } + else + { + for (size_t i = 0; i < digest_size; ++i) + { + this->pb.val(left.bits[i]) = this->pb.val(input.bits[i]); + } + } +} + +} // libsnark + +#endif // DIGEST_SELECTOR_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp new file mode 100644 index 000000000..80ca19c61 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp @@ -0,0 +1,63 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#ifndef HASH_IO_HPP_ +#define HASH_IO_HPP_ +#include +#include +#include "gadgetlib1/gadgets/basic_gadgets.hpp" + +namespace libsnark { + +template +class digest_variable : public gadget { +public: + size_t digest_size; + pb_variable_array bits; + + digest_variable(protoboard &pb, + const size_t digest_size, + const std::string &annotation_prefix); + + digest_variable(protoboard &pb, + const size_t digest_size, + const pb_variable_array &partial_bits, + const pb_variable &padding, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(const bit_vector& contents); + bit_vector get_digest() const; +}; + +template +class block_variable : public gadget { +public: + size_t block_size; + pb_variable_array bits; + + block_variable(protoboard &pb, + const size_t block_size, + const std::string &annotation_prefix); + + block_variable(protoboard &pb, + const std::vector > &parts, + const std::string &annotation_prefix); + + block_variable(protoboard &pb, + const digest_variable &left, + const digest_variable &right, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(const bit_vector& contents); + bit_vector get_block() const; +}; + +} // libsnark +#include "gadgetlib1/gadgets/hashes/hash_io.tcc" + +#endif // HASH_IO_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc new file mode 100644 index 000000000..b122d8f98 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/hash_io.tcc @@ -0,0 +1,105 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#ifndef HASH_IO_TCC_ +#define HASH_IO_TCC_ + +namespace libsnark { + +template +digest_variable::digest_variable(protoboard &pb, + const size_t digest_size, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), digest_size(digest_size) +{ + bits.allocate(pb, digest_size, FMT(this->annotation_prefix, " bits")); +} + +template +digest_variable::digest_variable(protoboard &pb, + const size_t digest_size, + const pb_variable_array &partial_bits, + const pb_variable &padding, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), digest_size(digest_size) +{ + assert(bits.size() <= digest_size); + bits = partial_bits; + while (bits.size() != digest_size) + { + bits.emplace_back(padding); + } +} + +template +void digest_variable::generate_r1cs_constraints() +{ + for (size_t i = 0; i < digest_size; ++i) + { + generate_boolean_r1cs_constraint(this->pb, bits[i], FMT(this->annotation_prefix, " bits_%zu", i)); + } +} + +template +void digest_variable::generate_r1cs_witness(const bit_vector& contents) +{ + bits.fill_with_bits(this->pb, contents); +} + +template +bit_vector digest_variable::get_digest() const +{ + return bits.get_bits(this->pb); +} + +template +block_variable::block_variable(protoboard &pb, + const size_t block_size, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), block_size(block_size) +{ + bits.allocate(pb, block_size, FMT(this->annotation_prefix, " bits")); +} + +template +block_variable::block_variable(protoboard &pb, + const std::vector > &parts, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix) +{ + for (auto &part : parts) + { + bits.insert(bits.end(), part.begin(), part.end()); + } +} + +template +block_variable::block_variable(protoboard &pb, + const digest_variable &left, + const digest_variable &right, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix) +{ + assert(left.bits.size() == right.bits.size()); + block_size = 2 * left.bits.size(); + bits.insert(bits.end(), left.bits.begin(), left.bits.end()); + bits.insert(bits.end(), right.bits.begin(), right.bits.end()); +} + +template +void block_variable::generate_r1cs_witness(const bit_vector& contents) +{ + bits.fill_with_bits(this->pb, contents); +} + +template +bit_vector block_variable::get_block() const +{ + return bits.get_bits(this->pb); +} + +} // libsnark +#endif // HASH_IO_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp new file mode 100644 index 000000000..e0c7a7e0b --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp @@ -0,0 +1,160 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for auxiliary gadgets for the SHA256 gadget. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_AUX_HPP_ +#define SHA256_AUX_HPP_ + +#include "gadgetlib1/gadgets/basic_gadgets.hpp" + +namespace libsnark { + +template +class lastbits_gadget : public gadget { +public: + pb_variable X; + size_t X_bits; + pb_variable result; + pb_linear_combination_array result_bits; + + pb_linear_combination_array full_bits; + std::shared_ptr > unpack_bits; + std::shared_ptr > pack_result; + + lastbits_gadget(protoboard &pb, + const pb_variable &X, + const size_t X_bits, + const pb_variable &result, + const pb_linear_combination_array &result_bits, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +class XOR3_gadget : public gadget { +private: + pb_variable tmp; +public: + pb_linear_combination A; + pb_linear_combination B; + pb_linear_combination C; + bool assume_C_is_zero; + pb_linear_combination out; + + XOR3_gadget(protoboard &pb, + const pb_linear_combination &A, + const pb_linear_combination &B, + const pb_linear_combination &C, + const bool assume_C_is_zero, + const pb_linear_combination &out, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +class small_sigma_gadget : public gadget { +private: + pb_variable_array W; + pb_variable result; +public: + pb_variable_array result_bits; + std::vector > > compute_bits; + std::shared_ptr > pack_result; + + small_sigma_gadget(protoboard &pb, + const pb_variable_array &W, + const pb_variable &result, + const size_t rot1, + const size_t rot2, + const size_t shift, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +class big_sigma_gadget : public gadget { +private: + pb_linear_combination_array W; + pb_variable result; +public: + pb_variable_array result_bits; + std::vector > > compute_bits; + std::shared_ptr > pack_result; + + big_sigma_gadget(protoboard &pb, + const pb_linear_combination_array &W, + const pb_variable &result, + const size_t rot1, + const size_t rot2, + const size_t rot3, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +class choice_gadget : public gadget { +private: + pb_variable_array result_bits; +public: + pb_linear_combination_array X; + pb_linear_combination_array Y; + pb_linear_combination_array Z; + pb_variable result; + std::shared_ptr > pack_result; + + choice_gadget(protoboard &pb, + const pb_linear_combination_array &X, + const pb_linear_combination_array &Y, + const pb_linear_combination_array &Z, + const pb_variable &result, const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +class majority_gadget : public gadget { +private: + pb_variable_array result_bits; + std::shared_ptr > pack_result; +public: + pb_linear_combination_array X; + pb_linear_combination_array Y; + pb_linear_combination_array Z; + pb_variable result; + + majority_gadget(protoboard &pb, + const pb_linear_combination_array &X, + const pb_linear_combination_array &Y, + const pb_linear_combination_array &Z, + const pb_variable &result, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +} // libsnark + +#include "gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc" + +#endif // SHA256_AUX_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc new file mode 100644 index 000000000..8ab67be5f --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_aux.tcc @@ -0,0 +1,297 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for auxiliary gadgets for the SHA256 gadget. + + See sha256_aux.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_AUX_TCC_ +#define SHA256_AUX_TCC_ + +namespace libsnark { + +template +lastbits_gadget::lastbits_gadget(protoboard &pb, + const pb_variable &X, + const size_t X_bits, + const pb_variable &result, + const pb_linear_combination_array &result_bits, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + X(X), + X_bits(X_bits), + result(result), + result_bits(result_bits) +{ + full_bits = result_bits; + for (size_t i = result_bits.size(); i < X_bits; ++i) + { + pb_variable full_bits_overflow; + full_bits_overflow.allocate(pb, FMT(this->annotation_prefix, " full_bits_%zu", i)); + full_bits.emplace_back(full_bits_overflow); + } + + unpack_bits.reset(new packing_gadget(pb, full_bits, X, FMT(this->annotation_prefix, " unpack_bits"))); + pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); +} + +template +void lastbits_gadget::generate_r1cs_constraints() +{ + unpack_bits->generate_r1cs_constraints(true); + pack_result->generate_r1cs_constraints(false); +} + +template +void lastbits_gadget::generate_r1cs_witness() +{ + unpack_bits->generate_r1cs_witness_from_packed(); + pack_result->generate_r1cs_witness_from_bits(); +} + +template +XOR3_gadget::XOR3_gadget(protoboard &pb, + const pb_linear_combination &A, + const pb_linear_combination &B, + const pb_linear_combination &C, + const bool assume_C_is_zero, + const pb_linear_combination &out, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + A(A), + B(B), + C(C), + assume_C_is_zero(assume_C_is_zero), + out(out) +{ + if (!assume_C_is_zero) + { + tmp.allocate(pb, FMT(this->annotation_prefix, " tmp")); + } +} + +template +void XOR3_gadget::generate_r1cs_constraints() +{ + /* + tmp = A + B - 2AB i.e. tmp = A xor B + out = tmp + C - 2tmp C i.e. out = tmp xor C + */ + if (assume_C_is_zero) + { + this->pb.add_r1cs_constraint(r1cs_constraint(2*A, B, A + B - out), FMT(this->annotation_prefix, " implicit_tmp_equals_out")); + } + else + { + this->pb.add_r1cs_constraint(r1cs_constraint(2*A, B, A + B - tmp), FMT(this->annotation_prefix, " tmp")); + this->pb.add_r1cs_constraint(r1cs_constraint(2 * tmp, C, tmp + C - out), FMT(this->annotation_prefix, " out")); + } +} + +template +void XOR3_gadget::generate_r1cs_witness() +{ + if (assume_C_is_zero) + { + this->pb.lc_val(out) = this->pb.lc_val(A) + this->pb.lc_val(B) - FieldT(2) * this->pb.lc_val(A) * this->pb.lc_val(B); + } + else + { + this->pb.val(tmp) = this->pb.lc_val(A) + this->pb.lc_val(B) - FieldT(2) * this->pb.lc_val(A) * this->pb.lc_val(B); + this->pb.lc_val(out) = this->pb.val(tmp) + this->pb.lc_val(C) - FieldT(2) * this->pb.val(tmp) * this->pb.lc_val(C); + } +} + +#define SHA256_GADGET_ROTR(A, i, k) A[((i)+(k)) % 32] + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +small_sigma_gadget::small_sigma_gadget(protoboard &pb, + const pb_variable_array &W, + const pb_variable &result, + const size_t rot1, + const size_t rot2, + const size_t shift, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + W(W), + result(result) +{ + result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); + compute_bits.resize(32); + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i].reset(new XOR3_gadget(pb, SHA256_GADGET_ROTR(W, i, rot1), SHA256_GADGET_ROTR(W, i, rot2), + (i + shift < 32 ? W[i+shift] : ONE), + (i + shift >= 32), result_bits[i], + FMT(this->annotation_prefix, " compute_bits_%zu", i))); + } + pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); +} + +template +void small_sigma_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i]->generate_r1cs_constraints(); + } + + pack_result->generate_r1cs_constraints(false); +} + +template +void small_sigma_gadget::generate_r1cs_witness() +{ + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i]->generate_r1cs_witness(); + } + + pack_result->generate_r1cs_witness_from_bits(); +} + +template +big_sigma_gadget::big_sigma_gadget(protoboard &pb, + const pb_linear_combination_array &W, + const pb_variable &result, + const size_t rot1, + const size_t rot2, + const size_t rot3, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + W(W), + result(result) +{ + result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); + compute_bits.resize(32); + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i].reset(new XOR3_gadget(pb, SHA256_GADGET_ROTR(W, i, rot1), SHA256_GADGET_ROTR(W, i, rot2), SHA256_GADGET_ROTR(W, i, rot3), false, result_bits[i], + FMT(this->annotation_prefix, " compute_bits_%zu", i))); + } + + pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " pack_result"))); +} + +template +void big_sigma_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i]->generate_r1cs_constraints(); + } + + pack_result->generate_r1cs_constraints(false); +} + +template +void big_sigma_gadget::generate_r1cs_witness() +{ + for (size_t i = 0; i < 32; ++i) + { + compute_bits[i]->generate_r1cs_witness(); + } + + pack_result->generate_r1cs_witness_from_bits(); +} + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +choice_gadget::choice_gadget(protoboard &pb, + const pb_linear_combination_array &X, + const pb_linear_combination_array &Y, + const pb_linear_combination_array &Z, + const pb_variable &result, const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + X(X), + Y(Y), + Z(Z), + result(result) +{ + result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); + pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " result"))); +} + +template +void choice_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < 32; ++i) + { + /* + result = x * y + (1-x) * z + result - z = x * (y - z) + */ + this->pb.add_r1cs_constraint(r1cs_constraint(X[i], Y[i] - Z[i], result_bits[i] - Z[i]), FMT(this->annotation_prefix, " result_bits_%zu", i)); + } + pack_result->generate_r1cs_constraints(false); +} + +template +void choice_gadget::generate_r1cs_witness() +{ + for (size_t i = 0; i < 32; ++i) + { + this->pb.val(result_bits[i]) = this->pb.lc_val(X[i]) * this->pb.lc_val(Y[i]) + (FieldT::one() - this->pb.lc_val(X[i])) * this->pb.lc_val(Z[i]); + } + pack_result->generate_r1cs_witness_from_bits(); +} + +/* Page 10 of http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf */ +template +majority_gadget::majority_gadget(protoboard &pb, + const pb_linear_combination_array &X, + const pb_linear_combination_array &Y, + const pb_linear_combination_array &Z, + const pb_variable &result, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + X(X), + Y(Y), + Z(Z), + result(result) +{ + result_bits.allocate(pb, 32, FMT(this->annotation_prefix, " result_bits")); + pack_result.reset(new packing_gadget(pb, result_bits, result, FMT(this->annotation_prefix, " result"))); +} + +template +void majority_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < 32; ++i) + { + /* + 2*result + aux = x + y + z + x, y, z, aux -- bits + aux = x + y + z - 2*result + */ + generate_boolean_r1cs_constraint(this->pb, result_bits[i], FMT(this->annotation_prefix, " result_%zu", i)); + this->pb.add_r1cs_constraint(r1cs_constraint(X[i] + Y[i] + Z[i] - 2 * result_bits[i], + 1 - (X[i] + Y[i] + Z[i] - 2 * result_bits[i]), + 0), + FMT(this->annotation_prefix, " result_bits_%zu", i)); + } + pack_result->generate_r1cs_constraints(false); +} + +template +void majority_gadget::generate_r1cs_witness() +{ + for (size_t i = 0; i < 32; ++i) + { + const long v = (this->pb.lc_val(X[i]) + this->pb.lc_val(Y[i]) + this->pb.lc_val(Z[i])).as_ulong(); + this->pb.val(result_bits[i]) = FieldT(v / 2); + } + + pack_result->generate_r1cs_witness_from_bits(); +} + +} // libsnark + +#endif // SHA256_AUX_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp new file mode 100644 index 000000000..c2f31e3af --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp @@ -0,0 +1,108 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for gadgets for the SHA256 message schedule and round function. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_COMPONENTS_HPP_ +#define SHA256_COMPONENTS_HPP_ + +#include "gadgetlib1/gadgets/basic_gadgets.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" +#include "gadgetlib1/gadgets/hashes/sha256/sha256_aux.hpp" + +namespace libsnark { + +const size_t SHA256_digest_size = 256; +const size_t SHA256_block_size = 512; + +template +pb_linear_combination_array SHA256_default_IV(protoboard &pb); + +template +class sha256_message_schedule_gadget : public gadget { +public: + std::vector > W_bits; + std::vector > > pack_W; + + std::vector > sigma0; + std::vector > sigma1; + std::vector > > compute_sigma0; + std::vector > > compute_sigma1; + std::vector > unreduced_W; + std::vector > > mod_reduce_W; +public: + pb_variable_array M; + pb_variable_array packed_W; + sha256_message_schedule_gadget(protoboard &pb, + const pb_variable_array &M, + const pb_variable_array &packed_W, + const std::string &annotation_prefix); + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +template +class sha256_round_function_gadget : public gadget { +public: + pb_variable sigma0; + pb_variable sigma1; + std::shared_ptr > compute_sigma0; + std::shared_ptr > compute_sigma1; + pb_variable choice; + pb_variable majority; + std::shared_ptr > compute_choice; + std::shared_ptr > compute_majority; + pb_variable packed_d; + std::shared_ptr > pack_d; + pb_variable packed_h; + std::shared_ptr > pack_h; + pb_variable unreduced_new_a; + pb_variable unreduced_new_e; + std::shared_ptr > mod_reduce_new_a; + std::shared_ptr > mod_reduce_new_e; + pb_variable packed_new_a; + pb_variable packed_new_e; +public: + pb_linear_combination_array a; + pb_linear_combination_array b; + pb_linear_combination_array c; + pb_linear_combination_array d; + pb_linear_combination_array e; + pb_linear_combination_array f; + pb_linear_combination_array g; + pb_linear_combination_array h; + pb_variable W; + long K; + pb_linear_combination_array new_a; + pb_linear_combination_array new_e; + + sha256_round_function_gadget(protoboard &pb, + const pb_linear_combination_array &a, + const pb_linear_combination_array &b, + const pb_linear_combination_array &c, + const pb_linear_combination_array &d, + const pb_linear_combination_array &e, + const pb_linear_combination_array &f, + const pb_linear_combination_array &g, + const pb_linear_combination_array &h, + const pb_variable &W, + const long &K, + const pb_linear_combination_array &new_a, + const pb_linear_combination_array &new_e, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +} // libsnark + +#include "gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc" + +#endif // SHA256_COMPONENTS_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc new file mode 100644 index 000000000..e8f233a54 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_components.tcc @@ -0,0 +1,250 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for gadgets for the SHA256 message schedule and round function. + + See sha256_components.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_COMPONENTS_TCC_ +#define SHA256_COMPONENTS_TCC_ + +namespace libsnark { + +const unsigned long SHA256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +const unsigned long SHA256_H[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +template +pb_linear_combination_array SHA256_default_IV(protoboard &pb) +{ + pb_linear_combination_array result; + result.reserve(SHA256_digest_size); + + for (size_t i = 0; i < SHA256_digest_size; ++i) + { + int iv_val = (SHA256_H[i / 32] >> (31-(i % 32))) & 1; + + pb_linear_combination iv_element; + iv_element.assign(pb, iv_val * ONE); + iv_element.evaluate(pb); + + result.emplace_back(iv_element); + } + + return result; +} + +template +sha256_message_schedule_gadget::sha256_message_schedule_gadget(protoboard &pb, + const pb_variable_array &M, + const pb_variable_array &packed_W, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + M(M), + packed_W(packed_W) +{ + W_bits.resize(64); + + pack_W.resize(16); + for (size_t i = 0; i < 16; ++i) + { + W_bits[i] = pb_variable_array(M.rbegin() + (15-i) * 32, M.rbegin() + (16-i) * 32); + pack_W[i].reset(new packing_gadget(pb, W_bits[i], packed_W[i], FMT(this->annotation_prefix, " pack_W_%zu", i))); + } + + /* NB: some of those will be un-allocated */ + sigma0.resize(64); + sigma1.resize(64); + compute_sigma0.resize(64); + compute_sigma1.resize(64); + unreduced_W.resize(64); + mod_reduce_W.resize(64); + + for (size_t i = 16; i < 64; ++i) + { + /* allocate result variables for sigma0/sigma1 invocations */ + sigma0[i].allocate(pb, FMT(this->annotation_prefix, " sigma0_%zu", i)); + sigma1[i].allocate(pb, FMT(this->annotation_prefix, " sigma1_%zu", i)); + + /* compute sigma0/sigma1 */ + compute_sigma0[i].reset(new small_sigma_gadget(pb, W_bits[i-15], sigma0[i], 7, 18, 3, FMT(this->annotation_prefix, " compute_sigma0_%zu", i))); + compute_sigma1[i].reset(new small_sigma_gadget(pb, W_bits[i-2], sigma1[i], 17, 19, 10, FMT(this->annotation_prefix, " compute_sigma1_%zu", i))); + + /* unreduced_W = sigma0(W_{i-15}) + sigma1(W_{i-2}) + W_{i-7} + W_{i-16} before modulo 2^32 */ + unreduced_W[i].allocate(pb, FMT(this->annotation_prefix, "unreduced_W_%zu", i)); + + /* allocate the bit representation of packed_W[i] */ + W_bits[i].allocate(pb, 32, FMT(this->annotation_prefix, " W_bits_%zu", i)); + + /* and finally reduce this into packed and bit representations */ + mod_reduce_W[i].reset(new lastbits_gadget(pb, unreduced_W[i], 32+2, packed_W[i], W_bits[i], FMT(this->annotation_prefix, " mod_reduce_W_%zu", i))); + } +} + +template +void sha256_message_schedule_gadget::generate_r1cs_constraints() +{ + for (size_t i = 0; i < 16; ++i) + { + pack_W[i]->generate_r1cs_constraints(false); // do not enforce bitness here; caller be aware. + } + + for (size_t i = 16; i < 64; ++i) + { + compute_sigma0[i]->generate_r1cs_constraints(); + compute_sigma1[i]->generate_r1cs_constraints(); + + this->pb.add_r1cs_constraint(r1cs_constraint(1, + sigma0[i] + sigma1[i] + packed_W[i-16] + packed_W[i-7], + unreduced_W[i]), + FMT(this->annotation_prefix, " unreduced_W_%zu", i)); + + mod_reduce_W[i]->generate_r1cs_constraints(); + } +} + +template +void sha256_message_schedule_gadget::generate_r1cs_witness() +{ + for (size_t i = 0; i < 16; ++i) + { + pack_W[i]->generate_r1cs_witness_from_bits(); + } + + for (size_t i = 16; i < 64; ++i) + { + compute_sigma0[i]->generate_r1cs_witness(); + compute_sigma1[i]->generate_r1cs_witness(); + + this->pb.val(unreduced_W[i]) = this->pb.val(sigma0[i]) + this->pb.val(sigma1[i]) + this->pb.val(packed_W[i-16]) + this->pb.val(packed_W[i-7]); + mod_reduce_W[i]->generate_r1cs_witness(); + } +} + +template +sha256_round_function_gadget::sha256_round_function_gadget(protoboard &pb, + const pb_linear_combination_array &a, + const pb_linear_combination_array &b, + const pb_linear_combination_array &c, + const pb_linear_combination_array &d, + const pb_linear_combination_array &e, + const pb_linear_combination_array &f, + const pb_linear_combination_array &g, + const pb_linear_combination_array &h, + const pb_variable &W, + const long &K, + const pb_linear_combination_array &new_a, + const pb_linear_combination_array &new_e, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + a(a), + b(b), + c(c), + d(d), + e(e), + f(f), + g(g), + h(h), + W(W), + K(K), + new_a(new_a), + new_e(new_e) +{ + /* compute sigma0 and sigma1 */ + sigma0.allocate(pb, FMT(this->annotation_prefix, " sigma0")); + sigma1.allocate(pb, FMT(this->annotation_prefix, " sigma1")); + compute_sigma0.reset(new big_sigma_gadget(pb, a, sigma0, 2, 13, 22, FMT(this->annotation_prefix, " compute_sigma0"))); + compute_sigma1.reset(new big_sigma_gadget(pb, e, sigma1, 6, 11, 25, FMT(this->annotation_prefix, " compute_sigma1"))); + + /* compute choice */ + choice.allocate(pb, FMT(this->annotation_prefix, " choice")); + compute_choice.reset(new choice_gadget(pb, e, f, g, choice, FMT(this->annotation_prefix, " compute_choice"))); + + /* compute majority */ + majority.allocate(pb, FMT(this->annotation_prefix, " majority")); + compute_majority.reset(new majority_gadget(pb, a, b, c, majority, FMT(this->annotation_prefix, " compute_majority"))); + + /* pack d */ + packed_d.allocate(pb, FMT(this->annotation_prefix, " packed_d")); + pack_d.reset(new packing_gadget(pb, d, packed_d, FMT(this->annotation_prefix, " pack_d"))); + + /* pack h */ + packed_h.allocate(pb, FMT(this->annotation_prefix, " packed_h")); + pack_h.reset(new packing_gadget(pb, h, packed_h, FMT(this->annotation_prefix, " pack_h"))); + + /* compute the actual results for the round */ + unreduced_new_a.allocate(pb, FMT(this->annotation_prefix, " unreduced_new_a")); + unreduced_new_e.allocate(pb, FMT(this->annotation_prefix, " unreduced_new_e")); + + packed_new_a.allocate(pb, FMT(this->annotation_prefix, " packed_new_a")); + packed_new_e.allocate(pb, FMT(this->annotation_prefix, " packed_new_e")); + + mod_reduce_new_a.reset(new lastbits_gadget(pb, unreduced_new_a, 32+3, packed_new_a, new_a, FMT(this->annotation_prefix, " mod_reduce_new_a"))); + mod_reduce_new_e.reset(new lastbits_gadget(pb, unreduced_new_e, 32+3, packed_new_e, new_e, FMT(this->annotation_prefix, " mod_reduce_new_e"))); +} + +template +void sha256_round_function_gadget::generate_r1cs_constraints() +{ + compute_sigma0->generate_r1cs_constraints(); + compute_sigma1->generate_r1cs_constraints(); + + compute_choice->generate_r1cs_constraints(); + compute_majority->generate_r1cs_constraints(); + + pack_d->generate_r1cs_constraints(false); + pack_h->generate_r1cs_constraints(false); + + this->pb.add_r1cs_constraint(r1cs_constraint(1, + packed_h + sigma1 + choice + K + W + sigma0 + majority, + unreduced_new_a), + FMT(this->annotation_prefix, " unreduced_new_a")); + + this->pb.add_r1cs_constraint(r1cs_constraint(1, + packed_d + packed_h + sigma1 + choice + K + W, + unreduced_new_e), + FMT(this->annotation_prefix, " unreduced_new_e")); + + mod_reduce_new_a->generate_r1cs_constraints(); + mod_reduce_new_e->generate_r1cs_constraints(); +} + +template +void sha256_round_function_gadget::generate_r1cs_witness() +{ + compute_sigma0->generate_r1cs_witness(); + compute_sigma1->generate_r1cs_witness(); + + compute_choice->generate_r1cs_witness(); + compute_majority->generate_r1cs_witness(); + + pack_d->generate_r1cs_witness_from_bits(); + pack_h->generate_r1cs_witness_from_bits(); + + this->pb.val(unreduced_new_a) = this->pb.val(packed_h) + this->pb.val(sigma1) + this->pb.val(choice) + FieldT(K) + this->pb.val(W) + this->pb.val(sigma0) + this->pb.val(majority); + this->pb.val(unreduced_new_e) = this->pb.val(packed_d) + this->pb.val(packed_h) + this->pb.val(sigma1) + this->pb.val(choice) + FieldT(K) + this->pb.val(W); + + mod_reduce_new_a->generate_r1cs_witness(); + mod_reduce_new_e->generate_r1cs_witness(); +} + +} // libsnark + +#endif // SHA256_COMPONENTS_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp new file mode 100644 index 000000000..8cb6365c8 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp @@ -0,0 +1,98 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for top-level SHA256 gadgets. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_GADGET_HPP_ +#define SHA256_GADGET_HPP_ + +#include "common/data_structures/merkle_tree.hpp" +#include "gadgetlib1/gadgets/basic_gadgets.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" +#include "gadgetlib1/gadgets/hashes/sha256/sha256_components.hpp" + +namespace libsnark { + +/** + * Gadget for the SHA256 compression function. + */ +template +class sha256_compression_function_gadget : public gadget { +public: + std::vector > round_a; + std::vector > round_b; + std::vector > round_c; + std::vector > round_d; + std::vector > round_e; + std::vector > round_f; + std::vector > round_g; + std::vector > round_h; + + pb_variable_array packed_W; + std::shared_ptr > message_schedule; + std::vector > round_functions; + + pb_variable_array unreduced_output; + pb_variable_array reduced_output; + std::vector > reduce_output; +public: + pb_linear_combination_array prev_output; + pb_variable_array new_block; + digest_variable output; + + sha256_compression_function_gadget(protoboard &pb, + const pb_linear_combination_array &prev_output, + const pb_variable_array &new_block, + const digest_variable &output, + const std::string &annotation_prefix); + void generate_r1cs_constraints(); + void generate_r1cs_witness(); +}; + +/** + * Gadget for the SHA256 compression function, viewed as a 2-to-1 hash + * function, and using the same initialization vector as in SHA256 + * specification. Thus, any collision for + * sha256_two_to_one_hash_gadget trivially extends to a collision for + * full SHA256 (by appending the same padding). + */ +template +class sha256_two_to_one_hash_gadget : public gadget { +public: + typedef bit_vector hash_value_type; + typedef merkle_authentication_path merkle_authentication_path_type; + + std::shared_ptr > f; + + sha256_two_to_one_hash_gadget(protoboard &pb, + const digest_variable &left, + const digest_variable &right, + const digest_variable &output, + const std::string &annotation_prefix); + sha256_two_to_one_hash_gadget(protoboard &pb, + const size_t block_length, + const block_variable &input_block, + const digest_variable &output, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(const bool ensure_output_bitness=true); // TODO: ignored for now + void generate_r1cs_witness(); + + static size_t get_block_len(); + static size_t get_digest_len(); + static bit_vector get_hash(const bit_vector &input); + + static size_t expected_constraints(const bool ensure_output_bitness=true); // TODO: ignored for now +}; + +} // libsnark + +#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc" + +#endif // SHA256_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc new file mode 100644 index 000000000..fc7ac982a --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc @@ -0,0 +1,230 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for top-level SHA256 gadgets. + + See sha256_gadget.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef SHA256_GADGET_TCC_ +#define SHA256_GADGET_TCC_ + +namespace libsnark { + +template +sha256_compression_function_gadget::sha256_compression_function_gadget(protoboard &pb, + const pb_linear_combination_array &prev_output, + const pb_variable_array &new_block, + const digest_variable &output, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + prev_output(prev_output), + new_block(new_block), + output(output) +{ + /* message schedule and inputs for it */ + packed_W.allocate(pb, 64, FMT(this->annotation_prefix, " packed_W")); + message_schedule.reset(new sha256_message_schedule_gadget(pb, new_block, packed_W, FMT(this->annotation_prefix, " message_schedule"))); + + /* initalize */ + round_a.push_back(pb_linear_combination_array(prev_output.rbegin() + 7*32, prev_output.rbegin() + 8*32)); + round_b.push_back(pb_linear_combination_array(prev_output.rbegin() + 6*32, prev_output.rbegin() + 7*32)); + round_c.push_back(pb_linear_combination_array(prev_output.rbegin() + 5*32, prev_output.rbegin() + 6*32)); + round_d.push_back(pb_linear_combination_array(prev_output.rbegin() + 4*32, prev_output.rbegin() + 5*32)); + round_e.push_back(pb_linear_combination_array(prev_output.rbegin() + 3*32, prev_output.rbegin() + 4*32)); + round_f.push_back(pb_linear_combination_array(prev_output.rbegin() + 2*32, prev_output.rbegin() + 3*32)); + round_g.push_back(pb_linear_combination_array(prev_output.rbegin() + 1*32, prev_output.rbegin() + 2*32)); + round_h.push_back(pb_linear_combination_array(prev_output.rbegin() + 0*32, prev_output.rbegin() + 1*32)); + + /* do the rounds */ + for (size_t i = 0; i < 64; ++i) + { + round_h.push_back(round_g[i]); + round_g.push_back(round_f[i]); + round_f.push_back(round_e[i]); + round_d.push_back(round_c[i]); + round_c.push_back(round_b[i]); + round_b.push_back(round_a[i]); + + pb_variable_array new_round_a_variables; + new_round_a_variables.allocate(pb, 32, FMT(this->annotation_prefix, " new_round_a_variables_%zu", i+1)); + round_a.emplace_back(new_round_a_variables); + + pb_variable_array new_round_e_variables; + new_round_e_variables.allocate(pb, 32, FMT(this->annotation_prefix, " new_round_e_variables_%zu", i+1)); + round_e.emplace_back(new_round_e_variables); + + round_functions.push_back(sha256_round_function_gadget(pb, + round_a[i], round_b[i], round_c[i], round_d[i], + round_e[i], round_f[i], round_g[i], round_h[i], + packed_W[i], SHA256_K[i], round_a[i+1], round_e[i+1], + FMT(this->annotation_prefix, " round_functions_%zu", i))); + } + + /* finalize */ + unreduced_output.allocate(pb, 8, FMT(this->annotation_prefix, " unreduced_output")); + reduced_output.allocate(pb, 8, FMT(this->annotation_prefix, " reduced_output")); + for (size_t i = 0; i < 8; ++i) + { + reduce_output.push_back(lastbits_gadget(pb, + unreduced_output[i], + 32+1, + reduced_output[i], + pb_variable_array(output.bits.rbegin() + (7-i) * 32, output.bits.rbegin() + (8-i) * 32), + FMT(this->annotation_prefix, " reduce_output_%zu", i))); + } +} + +template +void sha256_compression_function_gadget::generate_r1cs_constraints() +{ + message_schedule->generate_r1cs_constraints(); + for (size_t i = 0; i < 64; ++i) + { + round_functions[i].generate_r1cs_constraints(); + } + + for (size_t i = 0; i < 4; ++i) + { + this->pb.add_r1cs_constraint(r1cs_constraint(1, + round_functions[3-i].packed_d + round_functions[63-i].packed_new_a, + unreduced_output[i]), + FMT(this->annotation_prefix, " unreduced_output_%zu", i)); + + this->pb.add_r1cs_constraint(r1cs_constraint(1, + round_functions[3-i].packed_h + round_functions[63-i].packed_new_e, + unreduced_output[4+i]), + FMT(this->annotation_prefix, " unreduced_output_%zu", 4+i)); + } + + for (size_t i = 0; i < 8; ++i) + { + reduce_output[i].generate_r1cs_constraints(); + } +} + +template +void sha256_compression_function_gadget::generate_r1cs_witness() +{ + message_schedule->generate_r1cs_witness(); + +#ifdef DEBUG + printf("Input:\n"); + for (size_t j = 0; j < 16; ++j) + { + printf("%lx ", this->pb.val(packed_W[j]).as_ulong()); + } + printf("\n"); +#endif + + for (size_t i = 0; i < 64; ++i) + { + round_functions[i].generate_r1cs_witness(); + } + + for (size_t i = 0; i < 4; ++i) + { + this->pb.val(unreduced_output[i]) = this->pb.val(round_functions[3-i].packed_d) + this->pb.val(round_functions[63-i].packed_new_a); + this->pb.val(unreduced_output[4+i]) = this->pb.val(round_functions[3-i].packed_h) + this->pb.val(round_functions[63-i].packed_new_e); + } + + for (size_t i = 0; i < 8; ++i) + { + reduce_output[i].generate_r1cs_witness(); + } + +#ifdef DEBUG + printf("Output:\n"); + for (size_t j = 0; j < 8; ++j) + { + printf("%lx ", this->pb.val(reduced_output[j]).as_ulong()); + } + printf("\n"); +#endif +} + +template +sha256_two_to_one_hash_gadget::sha256_two_to_one_hash_gadget(protoboard &pb, + const digest_variable &left, + const digest_variable &right, + const digest_variable &output, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix) +{ + /* concatenate block = left || right */ + pb_variable_array block; + block.insert(block.end(), left.bits.begin(), left.bits.end()); + block.insert(block.end(), right.bits.begin(), right.bits.end()); + + /* compute the hash itself */ + f.reset(new sha256_compression_function_gadget(pb, SHA256_default_IV(pb), block, output, FMT(this->annotation_prefix, " f"))); +} + +template +sha256_two_to_one_hash_gadget::sha256_two_to_one_hash_gadget(protoboard &pb, + const size_t block_length, + const block_variable &input_block, + const digest_variable &output, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix) +{ + assert(block_length == SHA256_block_size); + assert(input_block.bits.size() == block_length); + f.reset(new sha256_compression_function_gadget(pb, SHA256_default_IV(pb), input_block.bits, output, FMT(this->annotation_prefix, " f"))); +} + +template +void sha256_two_to_one_hash_gadget::generate_r1cs_constraints(const bool ensure_output_bitness) +{ + UNUSED(ensure_output_bitness); + f->generate_r1cs_constraints(); +} + +template +void sha256_two_to_one_hash_gadget::generate_r1cs_witness() +{ + f->generate_r1cs_witness(); +} + +template +size_t sha256_two_to_one_hash_gadget::get_block_len() +{ + return SHA256_block_size; +} + +template +size_t sha256_two_to_one_hash_gadget::get_digest_len() +{ + return SHA256_digest_size; +} + +template +bit_vector sha256_two_to_one_hash_gadget::get_hash(const bit_vector &input) +{ + protoboard pb; + + block_variable input_variable(pb, SHA256_block_size, "input"); + digest_variable output_variable(pb, SHA256_digest_size, "output"); + sha256_two_to_one_hash_gadget f(pb, SHA256_block_size, input_variable, output_variable, "f"); + + input_variable.generate_r1cs_witness(input); + f.generate_r1cs_witness(); + + return output_variable.get_digest(); +} + +template +size_t sha256_two_to_one_hash_gadget::expected_constraints(const bool ensure_output_bitness) +{ + UNUSED(ensure_output_bitness); + return 27280; /* hardcoded for now */ +} + +} // libsnark + +#endif // SHA256_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py new file mode 100644 index 000000000..452317ffb --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/generate_sha256_gadget_tests.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +## +# @author This file is part of libsnark, developed by SCIPR Lab +# and contributors (see AUTHORS). +# @copyright MIT license (see LICENSE file) + +import random +import pypy_sha256 # PyPy's implementation of SHA256 compression function; see copyright and authorship notice within. + +BLOCK_LEN = 512 +BLOCK_BYTES = BLOCK_LEN // 8 +HASH_LEN = 256 +HASH_BYTES = HASH_LEN // 8 + +def gen_random_bytes(n): + return [random.randint(0, 255) for i in xrange(n)] + +def words_to_bytes(arr): + return sum(([x >> 24, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff] for x in arr), []) + +def bytes_to_words(arr): + l = len(arr) + assert l % 4 == 0 + return [(arr[i*4 + 3] << 24) + (arr[i*4+2] << 16) + (arr[i*4+1] << 8) + arr[i*4] for i in xrange(l//4)] + +def cpp_val(s, log_radix=32): + if log_radix == 8: + hexfmt = '0x%02x' + elif log_radix == 32: + hexfmt = '0x%08x' + s = bytes_to_words(s) + else: + raise + return 'int_list_to_bits({%s}, %d)' % (', '.join(hexfmt % x for x in s), log_radix) + +def H_bytes(x): + assert len(x) == BLOCK_BYTES + state = pypy_sha256.sha_init() + state['data'] = words_to_bytes(bytes_to_words(x)) + pypy_sha256.sha_transform(state) + return words_to_bytes(bytes_to_words(words_to_bytes(state['digest']))) + +def generate_sha256_gadget_tests(): + left = gen_random_bytes(HASH_BYTES) + right = gen_random_bytes(HASH_BYTES) + hash = H_bytes(left + right) + + print "const bit_vector left_bv = %s;" % cpp_val(left) + print "const bit_vector right_bv = %s;" % cpp_val(right) + print "const bit_vector hash_bv = %s;" % cpp_val(hash) + +if __name__ == '__main__': + random.seed(0) # for reproducibility + generate_sha256_gadget_tests() + diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py new file mode 100644 index 000000000..496989c11 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/pypy_sha256.py @@ -0,0 +1,263 @@ +#!/usr/bin/env python +# +# SHA256 compression function implementation below is a verbatim copy of PyPy's implementation from +# https://bitbucket.org/pypy/pypy/raw/f1f064b3faf1e012f7a9a9ab08f18074637ebe8a/lib_pypy/_sha256.py . +# +# It is licensed under the MIT license and copyright PyPy Copyright holders 2003-2015 +# See https://bitbucket.org/pypy/pypy/src/tip/LICENSE for the full copyright notice. +# + +SHA_BLOCKSIZE = 64 +SHA_DIGESTSIZE = 32 + + +def new_shaobject(): + return { + 'digest': [0]*8, + 'count_lo': 0, + 'count_hi': 0, + 'data': [0]* SHA_BLOCKSIZE, + 'local': 0, + 'digestsize': 0 + } + +ROR = lambda x, y: (((x & 0xffffffff) >> (y & 31)) | (x << (32 - (y & 31)))) & 0xffffffff +Ch = lambda x, y, z: (z ^ (x & (y ^ z))) +Maj = lambda x, y, z: (((x | y) & z) | (x & y)) +S = lambda x, n: ROR(x, n) +R = lambda x, n: (x & 0xffffffff) >> n +Sigma0 = lambda x: (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +Sigma1 = lambda x: (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +Gamma0 = lambda x: (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +Gamma1 = lambda x: (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +def sha_transform(sha_info): + W = [] + + d = sha_info['data'] + for i in range(0,16): + W.append( (d[4*i]<<24) + (d[4*i+1]<<16) + (d[4*i+2]<<8) + d[4*i+3]) + + for i in range(16,64): + W.append( (Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]) & 0xffffffff ) + + ss = sha_info['digest'][:] + + def RND(a,b,c,d,e,f,g,h,i,ki): + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; + t1 = Sigma0(a) + Maj(a, b, c); + d += t0; + h = t0 + t1; + return d & 0xffffffff, h & 0xffffffff + + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],0,0x428a2f98); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],1,0x71374491); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],2,0xb5c0fbcf); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],3,0xe9b5dba5); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],4,0x3956c25b); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],5,0x59f111f1); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],6,0x923f82a4); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],7,0xab1c5ed5); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],8,0xd807aa98); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],9,0x12835b01); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],10,0x243185be); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],11,0x550c7dc3); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],12,0x72be5d74); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],13,0x80deb1fe); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],14,0x9bdc06a7); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],15,0xc19bf174); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],16,0xe49b69c1); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],17,0xefbe4786); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],18,0x0fc19dc6); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],19,0x240ca1cc); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],20,0x2de92c6f); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],21,0x4a7484aa); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],22,0x5cb0a9dc); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],23,0x76f988da); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],24,0x983e5152); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],25,0xa831c66d); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],26,0xb00327c8); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],27,0xbf597fc7); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],28,0xc6e00bf3); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],29,0xd5a79147); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],30,0x06ca6351); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],31,0x14292967); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],32,0x27b70a85); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],33,0x2e1b2138); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],34,0x4d2c6dfc); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],35,0x53380d13); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],36,0x650a7354); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],37,0x766a0abb); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],38,0x81c2c92e); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],39,0x92722c85); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],40,0xa2bfe8a1); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],41,0xa81a664b); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],42,0xc24b8b70); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],43,0xc76c51a3); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],44,0xd192e819); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],45,0xd6990624); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],46,0xf40e3585); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],47,0x106aa070); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],48,0x19a4c116); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],49,0x1e376c08); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],50,0x2748774c); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],51,0x34b0bcb5); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],52,0x391c0cb3); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],53,0x4ed8aa4a); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],54,0x5b9cca4f); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],55,0x682e6ff3); + ss[3], ss[7] = RND(ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],56,0x748f82ee); + ss[2], ss[6] = RND(ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],57,0x78a5636f); + ss[1], ss[5] = RND(ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],ss[5],58,0x84c87814); + ss[0], ss[4] = RND(ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],ss[4],59,0x8cc70208); + ss[7], ss[3] = RND(ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],ss[3],60,0x90befffa); + ss[6], ss[2] = RND(ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],ss[2],61,0xa4506ceb); + ss[5], ss[1] = RND(ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],ss[1],62,0xbef9a3f7); + ss[4], ss[0] = RND(ss[1],ss[2],ss[3],ss[4],ss[5],ss[6],ss[7],ss[0],63,0xc67178f2); + + dig = [] + for i, x in enumerate(sha_info['digest']): + dig.append( (x + ss[i]) & 0xffffffff ) + sha_info['digest'] = dig + +def sha_init(): + sha_info = new_shaobject() + sha_info['digest'] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19] + sha_info['count_lo'] = 0 + sha_info['count_hi'] = 0 + sha_info['local'] = 0 + sha_info['digestsize'] = 32 + return sha_info + +def sha224_init(): + sha_info = new_shaobject() + sha_info['digest'] = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4] + sha_info['count_lo'] = 0 + sha_info['count_hi'] = 0 + sha_info['local'] = 0 + sha_info['digestsize'] = 28 + return sha_info + +def sha_update(sha_info, buffer): + if isinstance(buffer, str): + raise TypeError("Unicode strings must be encoded before hashing") + count = len(buffer) + buffer_idx = 0 + clo = (sha_info['count_lo'] + (count << 3)) & 0xffffffff + if clo < sha_info['count_lo']: + sha_info['count_hi'] += 1 + sha_info['count_lo'] = clo + + sha_info['count_hi'] += (count >> 29) + + if sha_info['local']: + i = SHA_BLOCKSIZE - sha_info['local'] + if i > count: + i = count + + # copy buffer + sha_info['data'][sha_info['local']:sha_info['local']+i] = buffer[buffer_idx:buffer_idx+i] + + count -= i + buffer_idx += i + + sha_info['local'] += i + if sha_info['local'] == SHA_BLOCKSIZE: + sha_transform(sha_info) + sha_info['local'] = 0 + else: + return + + while count >= SHA_BLOCKSIZE: + # copy buffer + sha_info['data'] = list(buffer[buffer_idx:buffer_idx + SHA_BLOCKSIZE]) + count -= SHA_BLOCKSIZE + buffer_idx += SHA_BLOCKSIZE + sha_transform(sha_info) + + + # copy buffer + pos = sha_info['local'] + sha_info['data'][pos:pos+count] = buffer[buffer_idx:buffer_idx + count] + sha_info['local'] = count + +def sha_final(sha_info): + lo_bit_count = sha_info['count_lo'] + hi_bit_count = sha_info['count_hi'] + count = (lo_bit_count >> 3) & 0x3f + sha_info['data'][count] = 0x80; + count += 1 + if count > SHA_BLOCKSIZE - 8: + # zero the bytes in data after the count + sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count)) + sha_transform(sha_info) + # zero bytes in data + sha_info['data'] = [0] * SHA_BLOCKSIZE + else: + sha_info['data'] = sha_info['data'][:count] + ([0] * (SHA_BLOCKSIZE - count)) + + sha_info['data'][56] = (hi_bit_count >> 24) & 0xff + sha_info['data'][57] = (hi_bit_count >> 16) & 0xff + sha_info['data'][58] = (hi_bit_count >> 8) & 0xff + sha_info['data'][59] = (hi_bit_count >> 0) & 0xff + sha_info['data'][60] = (lo_bit_count >> 24) & 0xff + sha_info['data'][61] = (lo_bit_count >> 16) & 0xff + sha_info['data'][62] = (lo_bit_count >> 8) & 0xff + sha_info['data'][63] = (lo_bit_count >> 0) & 0xff + + sha_transform(sha_info) + + dig = [] + for i in sha_info['digest']: + dig.extend([ ((i>>24) & 0xff), ((i>>16) & 0xff), ((i>>8) & 0xff), (i & 0xff) ]) + return ''.join([chr(i) for i in dig]) + +class sha256(object): + digest_size = digestsize = SHA_DIGESTSIZE + block_size = SHA_BLOCKSIZE + + def __init__(self, s=None): + self._sha = sha_init() + if s: + sha_update(self._sha, s) + + def update(self, s): + sha_update(self._sha, s) + + def digest(self): + return sha_final(self._sha.copy())[:self._sha['digestsize']] + + def hexdigest(self): + return ''.join(['%.2x' % ord(i) for i in self.digest()]) + + def copy(self): + new = sha256.__new__(sha256) + new._sha = self._sha.copy() + return new + +class sha224(sha256): + digest_size = digestsize = 28 + + def __init__(self, s=None): + self._sha = sha224_init() + if s: + sha_update(self._sha, s) + + def copy(self): + new = sha224.__new__(sha224) + new._sha = self._sha.copy() + return new + +def test(): + a_str = "just a test string" + + assert 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' == sha256().hexdigest() + assert 'd7b553c6f09ac85d142415f857c5310f3bbbe7cdd787cce4b985acedd585266f' == sha256(a_str).hexdigest() + assert '8113ebf33c97daa9998762aacafe750c7cefc2b2f173c90c59663a57fe626f21' == sha256(a_str*7).hexdigest() + + s = sha256(a_str) + s.update(a_str) + assert '03d9963e05a094593190b6fc794cb1a3e1ac7d7883f0b5855268afeccc70d461' == s.hexdigest() + +if __name__ == "__main__": + test() diff --git a/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp new file mode 100644 index 000000000..0bfaf3a12 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/hashes/sha256/tests/test_sha256_gadget.cpp @@ -0,0 +1,48 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "common/default_types/ec_pp.hpp" +#include "common/utils.hpp" +#include "common/profiling.hpp" +#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" + +#include + +using namespace libsnark; + +template +void test_two_to_one() +{ + protoboard pb; + + digest_variable left(pb, SHA256_digest_size, "left"); + digest_variable right(pb, SHA256_digest_size, "right"); + digest_variable output(pb, SHA256_digest_size, "output"); + + sha256_two_to_one_hash_gadget f(pb, left, right, output, "f"); + f.generate_r1cs_constraints(); + printf("Number of constraints for sha256_two_to_one_hash_gadget: %zu\n", pb.num_constraints()); + + const bit_vector left_bv = int_list_to_bits({0x426bc2d8, 0x4dc86782, 0x81e8957a, 0x409ec148, 0xe6cffbe8, 0xafe6ba4f, 0x9c6f1978, 0xdd7af7e9}, 32); + const bit_vector right_bv = int_list_to_bits({0x038cce42, 0xabd366b8, 0x3ede7e00, 0x9130de53, 0x72cdf73d, 0xee825114, 0x8cb48d1b, 0x9af68ad0}, 32); + const bit_vector hash_bv = int_list_to_bits({0xeffd0b7f, 0x1ccba116, 0x2ee816f7, 0x31c62b48, 0x59305141, 0x990e5c0a, 0xce40d33d, 0x0b1167d1}, 32); + + left.generate_r1cs_witness(left_bv); + right.generate_r1cs_witness(right_bv); + + f.generate_r1cs_witness(); + output.generate_r1cs_witness(hash_bv); + + EXPECT_TRUE(pb.is_satisfied()); +} + +TEST(gadgetlib1, sha256) +{ + start_profiling(); + default_ec_pp::init_public_params(); + test_two_to_one >(); +} diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp new file mode 100644 index 000000000..0efa7cf4d --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp @@ -0,0 +1,38 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP_ +#define MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP_ + +#include "common/data_structures/merkle_tree.hpp" +#include "gadgetlib1/gadget.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" + +namespace libsnark { + +template +class merkle_authentication_path_variable : public gadget { +public: + + const size_t tree_depth; + std::vector > left_digests; + std::vector > right_digests; + + merkle_authentication_path_variable(protoboard &pb, + const size_t tree_depth, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(const size_t address, const merkle_authentication_path &path); + merkle_authentication_path get_authentication_path(const size_t address) const; +}; + +} // libsnark + +#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc" + +#endif // MERKLE_AUTHENTICATION_PATH_VARIABLE_HPP diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc new file mode 100644 index 000000000..d773051ab --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.tcc @@ -0,0 +1,76 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC_ +#define MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC_ + +namespace libsnark { + +template +merkle_authentication_path_variable::merkle_authentication_path_variable(protoboard &pb, + const size_t tree_depth, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + tree_depth(tree_depth) +{ + for (size_t i = 0; i < tree_depth; ++i) + { + left_digests.emplace_back(digest_variable(pb, HashT::get_digest_len(), FMT(annotation_prefix, " left_digests_%zu", i))); + right_digests.emplace_back(digest_variable(pb, HashT::get_digest_len(), FMT(annotation_prefix, " right_digests_%zu", i))); + } +} + +template +void merkle_authentication_path_variable::generate_r1cs_constraints() +{ + for (size_t i = 0; i < tree_depth; ++i) + { + left_digests[i].generate_r1cs_constraints(); + right_digests[i].generate_r1cs_constraints(); + } +} + +template +void merkle_authentication_path_variable::generate_r1cs_witness(const size_t address, const merkle_authentication_path &path) +{ + assert(path.size() == tree_depth); + + for (size_t i = 0; i < tree_depth; ++i) + { + if (address & (1ul << (tree_depth-1-i))) + { + left_digests[i].generate_r1cs_witness(path[i]); + } + else + { + right_digests[i].generate_r1cs_witness(path[i]); + } + } +} + +template +merkle_authentication_path merkle_authentication_path_variable::get_authentication_path(const size_t address) const +{ + merkle_authentication_path result; + for (size_t i = 0; i < tree_depth; ++i) + { + if (address & (1ul << (tree_depth-1-i))) + { + result.emplace_back(left_digests[i].get_digest()); + } + else + { + result.emplace_back(right_digests[i].get_digest()); + } + } + + return result; +} + +} // libsnark + +#endif // MERKLE_AUTHENTICATION_PATH_VARIABLE_TCC diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp new file mode 100644 index 000000000..b1e3a4f05 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp @@ -0,0 +1,73 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for the Merkle tree check read gadget. + + The gadget checks the following: given a root R, address A, value V, and + authentication path P, check that P is a valid authentication path for the + value V as the A-th leaf in a Merkle tree with root R. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_CHECK_READ_GADGET_HPP_ +#define MERKLE_TREE_CHECK_READ_GADGET_HPP_ + +#include "common/data_structures/merkle_tree.hpp" +#include "gadgetlib1/gadget.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" +#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp" +#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp" + +namespace libsnark { + +template +class merkle_tree_check_read_gadget : public gadget { +private: + + std::vector hashers; + std::vector > hasher_inputs; + std::vector > propagators; + std::vector > internal_output; + + std::shared_ptr > computed_root; + std::shared_ptr > check_root; + +public: + + const size_t digest_size; + const size_t tree_depth; + pb_linear_combination_array address_bits; + digest_variable leaf; + digest_variable root; + merkle_authentication_path_variable path; + pb_linear_combination read_successful; + + merkle_tree_check_read_gadget(protoboard &pb, + const size_t tree_depth, + const pb_linear_combination_array &address_bits, + const digest_variable &leaf_digest, + const digest_variable &root_digest, + const merkle_authentication_path_variable &path, + const pb_linear_combination &read_successful, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); + + static size_t root_size_in_bits(); + /* for debugging purposes */ + static size_t expected_constraints(const size_t tree_depth); +}; + +template +void test_merkle_tree_check_read_gadget(); + +} // libsnark + +#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc" + +#endif // MERKLE_TREE_CHECK_READ_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc new file mode 100644 index 000000000..6002a5886 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.tcc @@ -0,0 +1,196 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for the Merkle tree check read. + + See merkle_tree_check_read_gadget.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_CHECK_READ_GADGET_TCC_ +#define MERKLE_TREE_CHECK_READ_GADGET_TCC_ + +namespace libsnark { + +template +merkle_tree_check_read_gadget::merkle_tree_check_read_gadget(protoboard &pb, + const size_t tree_depth, + const pb_linear_combination_array &address_bits, + const digest_variable &leaf, + const digest_variable &root, + const merkle_authentication_path_variable &path, + const pb_linear_combination &read_successful, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + digest_size(HashT::get_digest_len()), + tree_depth(tree_depth), + address_bits(address_bits), + leaf(leaf), + root(root), + path(path), + read_successful(read_successful) +{ + /* + The tricky part here is ordering. For Merkle tree + authentication paths, path[0] corresponds to one layer below + the root (and path[tree_depth-1] corresponds to the layer + containing the leaf), while address_bits has the reverse order: + address_bits[0] is LSB, and corresponds to layer containing the + leaf, and address_bits[tree_depth-1] is MSB, and corresponds to + the subtree directly under the root. + */ + assert(tree_depth > 0); + assert(tree_depth == address_bits.size()); + + for (size_t i = 0; i < tree_depth-1; ++i) + { + internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " internal_output_%zu", i))); + } + + computed_root.reset(new digest_variable(pb, digest_size, FMT(this->annotation_prefix, " computed_root"))); + + for (size_t i = 0; i < tree_depth; ++i) + { + block_variable inp(pb, path.left_digests[i], path.right_digests[i], FMT(this->annotation_prefix, " inp_%zu", i)); + hasher_inputs.emplace_back(inp); + hashers.emplace_back(HashT(pb, 2*digest_size, inp, (i == 0 ? *computed_root : internal_output[i-1]), + FMT(this->annotation_prefix, " load_hashers_%zu", i))); + } + + for (size_t i = 0; i < tree_depth; ++i) + { + /* + The propagators take a computed hash value (or leaf in the + base case) and propagate it one layer up, either in the left + or the right slot of authentication_path_variable. + */ + propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth - 1 ? internal_output[i] : leaf, + address_bits[tree_depth-1-i], path.left_digests[i], path.right_digests[i], + FMT(this->annotation_prefix, " digest_selector_%zu", i))); + } + + check_root.reset(new bit_vector_copy_gadget(pb, computed_root->bits, root.bits, read_successful, FieldT::capacity(), FMT(annotation_prefix, " check_root"))); +} + +template +void merkle_tree_check_read_gadget::generate_r1cs_constraints() +{ + /* ensure correct hash computations */ + for (size_t i = 0; i < tree_depth; ++i) + { + // Note that we check root outside and have enforced booleanity of path.left_digests/path.right_digests outside in path.generate_r1cs_constraints + hashers[i].generate_r1cs_constraints(false); + } + + /* ensure consistency of path.left_digests/path.right_digests with internal_output */ + for (size_t i = 0; i < tree_depth; ++i) + { + propagators[i].generate_r1cs_constraints(); + } + + check_root->generate_r1cs_constraints(false, false); +} + +template +void merkle_tree_check_read_gadget::generate_r1cs_witness() +{ + /* do the hash computations bottom-up */ + for (int i = tree_depth-1; i >= 0; --i) + { + /* propagate previous input */ + propagators[i].generate_r1cs_witness(); + + /* compute hash */ + hashers[i].generate_r1cs_witness(); + } + + check_root->generate_r1cs_witness(); +} + +template +size_t merkle_tree_check_read_gadget::root_size_in_bits() +{ + return HashT::get_digest_len(); +} + +template +size_t merkle_tree_check_read_gadget::expected_constraints(const size_t tree_depth) +{ + /* NB: this includes path constraints */ + const size_t hasher_constraints = tree_depth * HashT::expected_constraints(false); + const size_t propagator_constraints = tree_depth * HashT::get_digest_len(); + const size_t authentication_path_constraints = 2 * tree_depth * HashT::get_digest_len(); + const size_t check_root_constraints = 3 * div_ceil(HashT::get_digest_len(), FieldT::capacity()); + + return hasher_constraints + propagator_constraints + authentication_path_constraints + check_root_constraints; +} + +template +void test_merkle_tree_check_read_gadget() +{ + /* prepare test */ + const size_t digest_len = HashT::get_digest_len(); + const size_t tree_depth = 16; + std::vector path(tree_depth); + + bit_vector prev_hash(digest_len); + std::generate(prev_hash.begin(), prev_hash.end(), [&]() { return std::rand() % 2; }); + bit_vector leaf = prev_hash; + + bit_vector address_bits; + + size_t address = 0; + for (long level = tree_depth-1; level >= 0; --level) + { + const bool computed_is_right = (std::rand() % 2); + address |= (computed_is_right ? 1ul << (tree_depth-1-level) : 0); + address_bits.push_back(computed_is_right); + bit_vector other(digest_len); + std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); + + bit_vector block = prev_hash; + block.insert(computed_is_right ? block.begin() : block.end(), other.begin(), other.end()); + bit_vector h = HashT::get_hash(block); + + path[level] = other; + + prev_hash = h; + } + bit_vector root = prev_hash; + + /* execute test */ + protoboard pb; + pb_variable_array address_bits_va; + address_bits_va.allocate(pb, tree_depth, "address_bits"); + digest_variable leaf_digest(pb, digest_len, "input_block"); + digest_variable root_digest(pb, digest_len, "output_digest"); + merkle_authentication_path_variable path_var(pb, tree_depth, "path_var"); + merkle_tree_check_read_gadget ml(pb, tree_depth, address_bits_va, leaf_digest, root_digest, path_var, ONE, "ml"); + + path_var.generate_r1cs_constraints(); + ml.generate_r1cs_constraints(); + + address_bits_va.fill_with_bits(pb, address_bits); + assert(address_bits_va.get_field_element_from_bits(pb).as_ulong() == address); + leaf_digest.generate_r1cs_witness(leaf); + path_var.generate_r1cs_witness(address, path); + ml.generate_r1cs_witness(); + + /* make sure that read checker didn't accidentally overwrite anything */ + address_bits_va.fill_with_bits(pb, address_bits); + leaf_digest.generate_r1cs_witness(leaf); + root_digest.generate_r1cs_witness(root); + assert(pb.is_satisfied()); + + const size_t num_constraints = pb.num_constraints(); + const size_t expected_constraints = merkle_tree_check_read_gadget::expected_constraints(tree_depth); + assert(num_constraints == expected_constraints); +} + +} // libsnark + +#endif // MERKLE_TREE_CHECK_READ_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp new file mode 100644 index 000000000..6ec0ca11f --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp @@ -0,0 +1,90 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for the Merkle tree check read gadget. + + The gadget checks the following: given two roots R1 and R2, address A, two + values V1 and V2, and authentication path P, check that + - P is a valid authentication path for the value V1 as the A-th leaf in a Merkle tree with root R1, and + - P is a valid authentication path for the value V2 as the A-th leaf in a Merkle tree with root R2. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ +#define MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ + +#include "common/data_structures/merkle_tree.hpp" +#include "gadgetlib1/gadget.hpp" +#include "gadgetlib1/gadgets/hashes/hash_io.hpp" +#include "gadgetlib1/gadgets/hashes/digest_selector_gadget.hpp" +#include "gadgetlib1/gadgets/merkle_tree/merkle_authentication_path_variable.hpp" + +namespace libsnark { + +template +class merkle_tree_check_update_gadget : public gadget { +private: + + std::vector prev_hashers; + std::vector > prev_hasher_inputs; + std::vector > prev_propagators; + std::vector > prev_internal_output; + + std::vector next_hashers; + std::vector > next_hasher_inputs; + std::vector > next_propagators; + std::vector > next_internal_output; + + std::shared_ptr > computed_next_root; + std::shared_ptr > check_next_root; + +public: + + const size_t digest_size; + const size_t tree_depth; + + pb_variable_array address_bits; + digest_variable prev_leaf_digest; + digest_variable prev_root_digest; + merkle_authentication_path_variable prev_path; + digest_variable next_leaf_digest; + digest_variable next_root_digest; + merkle_authentication_path_variable next_path; + pb_linear_combination update_successful; + + /* Note that while it is necessary to generate R1CS constraints + for prev_path, it is not necessary to do so for next_path. See + comment in the implementation of generate_r1cs_constraints() */ + + merkle_tree_check_update_gadget(protoboard &pb, + const size_t tree_depth, + const pb_variable_array &address_bits, + const digest_variable &prev_leaf_digest, + const digest_variable &prev_root_digest, + const merkle_authentication_path_variable &prev_path, + const digest_variable &next_leaf_digest, + const digest_variable &next_root_digest, + const merkle_authentication_path_variable &next_path, + const pb_linear_combination &update_successful, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness(); + + static size_t root_size_in_bits(); + /* for debugging purposes */ + static size_t expected_constraints(const size_t tree_depth); +}; + +template +void test_merkle_tree_check_update_gadget(); + +} // libsnark + +#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc" + +#endif // MERKLE_TREE_CHECK_UPDATE_GADGET_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc new file mode 100644 index 000000000..1ac08edbb --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.tcc @@ -0,0 +1,265 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for the Merkle tree check update gadget. + + See merkle_tree_check_update_gadget.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ +#define MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ + +namespace libsnark { + +template +merkle_tree_check_update_gadget::merkle_tree_check_update_gadget(protoboard &pb, + const size_t tree_depth, + const pb_variable_array &address_bits, + const digest_variable &prev_leaf_digest, + const digest_variable &prev_root_digest, + const merkle_authentication_path_variable &prev_path, + const digest_variable &next_leaf_digest, + const digest_variable &next_root_digest, + const merkle_authentication_path_variable &next_path, + const pb_linear_combination &update_successful, + const std::string &annotation_prefix) : + gadget(pb, annotation_prefix), + digest_size(HashT::get_digest_len()), + tree_depth(tree_depth), + address_bits(address_bits), + prev_leaf_digest(prev_leaf_digest), + prev_root_digest(prev_root_digest), + prev_path(prev_path), + next_leaf_digest(next_leaf_digest), + next_root_digest(next_root_digest), + next_path(next_path), + update_successful(update_successful) +{ + assert(tree_depth > 0); + assert(tree_depth == address_bits.size()); + + for (size_t i = 0; i < tree_depth-1; ++i) + { + prev_internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " prev_internal_output_%zu", i))); + next_internal_output.emplace_back(digest_variable(pb, digest_size, FMT(this->annotation_prefix, " next_internal_output_%zu", i))); + } + + computed_next_root.reset(new digest_variable(pb, digest_size, FMT(this->annotation_prefix, " computed_root"))); + + for (size_t i = 0; i < tree_depth; ++i) + { + block_variable prev_inp(pb, prev_path.left_digests[i], prev_path.right_digests[i], FMT(this->annotation_prefix, " prev_inp_%zu", i)); + prev_hasher_inputs.emplace_back(prev_inp); + prev_hashers.emplace_back(HashT(pb, 2*digest_size, prev_inp, (i == 0 ? prev_root_digest : prev_internal_output[i-1]), + FMT(this->annotation_prefix, " prev_hashers_%zu", i))); + + block_variable next_inp(pb, next_path.left_digests[i], next_path.right_digests[i], FMT(this->annotation_prefix, " next_inp_%zu", i)); + next_hasher_inputs.emplace_back(next_inp); + next_hashers.emplace_back(HashT(pb, 2*digest_size, next_inp, (i == 0 ? *computed_next_root : next_internal_output[i-1]), + FMT(this->annotation_prefix, " next_hashers_%zu", i))); + } + + for (size_t i = 0; i < tree_depth; ++i) + { + prev_propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth -1 ? prev_internal_output[i] : prev_leaf_digest, + address_bits[tree_depth-1-i], prev_path.left_digests[i], prev_path.right_digests[i], + FMT(this->annotation_prefix, " prev_propagators_%zu", i))); + next_propagators.emplace_back(digest_selector_gadget(pb, digest_size, i < tree_depth -1 ? next_internal_output[i] : next_leaf_digest, + address_bits[tree_depth-1-i], next_path.left_digests[i], next_path.right_digests[i], + FMT(this->annotation_prefix, " next_propagators_%zu", i))); + } + + check_next_root.reset(new bit_vector_copy_gadget(pb, computed_next_root->bits, next_root_digest.bits, update_successful, FieldT::capacity(), FMT(annotation_prefix, " check_next_root"))); +} + +template +void merkle_tree_check_update_gadget::generate_r1cs_constraints() +{ + /* ensure correct hash computations */ + for (size_t i = 0; i < tree_depth; ++i) + { + prev_hashers[i].generate_r1cs_constraints(false); // we check root outside and prev_left/prev_right above + next_hashers[i].generate_r1cs_constraints(true); // however we must check right side hashes + } + + /* ensure consistency of internal_left/internal_right with internal_output */ + for (size_t i = 0; i < tree_depth; ++i) + { + prev_propagators[i].generate_r1cs_constraints(); + next_propagators[i].generate_r1cs_constraints(); + } + + /* ensure that prev auxiliary input and next auxiliary input match */ + for (size_t i = 0; i < tree_depth; ++i) + { + for (size_t j = 0; j < digest_size; ++j) + { + /* + addr * (prev_left - next_left) + (1 - addr) * (prev_right - next_right) = 0 + addr * (prev_left - next_left - prev_right + next_right) = next_right - prev_right + */ + this->pb.add_r1cs_constraint(r1cs_constraint(address_bits[tree_depth-1-i], + prev_path.left_digests[i].bits[j] - next_path.left_digests[i].bits[j] - prev_path.right_digests[i].bits[j] + next_path.right_digests[i].bits[j], + next_path.right_digests[i].bits[j] - prev_path.right_digests[i].bits[j]), + FMT(this->annotation_prefix, " aux_check_%zu_%zu", i, j)); + } + } + + /* Note that while it is necessary to generate R1CS constraints + for prev_path, it is not necessary to do so for next_path. + + This holds, because { next_path.left_inputs[i], + next_path.right_inputs[i] } is a pair { hash_output, + auxiliary_input }. The bitness for hash_output is enforced + above by next_hashers[i].generate_r1cs_constraints. + + Because auxiliary input is the same for prev_path and next_path + (enforced above), we have that auxiliary_input part is also + constrained to be boolean, because prev_path is *all* + constrained to be all boolean. */ + + check_next_root->generate_r1cs_constraints(false, false); +} + +template +void merkle_tree_check_update_gadget::generate_r1cs_witness() +{ + /* do the hash computations bottom-up */ + for (int i = tree_depth-1; i >= 0; --i) + { + /* ensure consistency of prev_path and next_path */ + if (this->pb.val(address_bits[tree_depth-1-i]) == FieldT::one()) + { + next_path.left_digests[i].generate_r1cs_witness(prev_path.left_digests[i].get_digest()); + } + else + { + next_path.right_digests[i].generate_r1cs_witness(prev_path.right_digests[i].get_digest()); + } + + /* propagate previous input */ + prev_propagators[i].generate_r1cs_witness(); + next_propagators[i].generate_r1cs_witness(); + + /* compute hash */ + prev_hashers[i].generate_r1cs_witness(); + next_hashers[i].generate_r1cs_witness(); + } + + check_next_root->generate_r1cs_witness(); +} + +template +size_t merkle_tree_check_update_gadget::root_size_in_bits() +{ + return HashT::get_digest_len(); +} + +template +size_t merkle_tree_check_update_gadget::expected_constraints(const size_t tree_depth) +{ + /* NB: this includes path constraints */ + const size_t prev_hasher_constraints = tree_depth * HashT::expected_constraints(false); + const size_t next_hasher_constraints = tree_depth * HashT::expected_constraints(true); + const size_t prev_authentication_path_constraints = 2 * tree_depth * HashT::get_digest_len(); + const size_t prev_propagator_constraints = tree_depth * HashT::get_digest_len(); + const size_t next_propagator_constraints = tree_depth * HashT::get_digest_len(); + const size_t check_next_root_constraints = 3 * div_ceil(HashT::get_digest_len(), FieldT::capacity()); + const size_t aux_equality_constraints = tree_depth * HashT::get_digest_len(); + + return (prev_hasher_constraints + next_hasher_constraints + prev_authentication_path_constraints + + prev_propagator_constraints + next_propagator_constraints + check_next_root_constraints + + aux_equality_constraints); +} + +template +void test_merkle_tree_check_update_gadget() +{ + /* prepare test */ + const size_t digest_len = HashT::get_digest_len(); + + const size_t tree_depth = 16; + std::vector prev_path(tree_depth); + + bit_vector prev_load_hash(digest_len); + std::generate(prev_load_hash.begin(), prev_load_hash.end(), [&]() { return std::rand() % 2; }); + bit_vector prev_store_hash(digest_len); + std::generate(prev_store_hash.begin(), prev_store_hash.end(), [&]() { return std::rand() % 2; }); + + bit_vector loaded_leaf = prev_load_hash; + bit_vector stored_leaf = prev_store_hash; + + bit_vector address_bits; + + size_t address = 0; + for (long level = tree_depth-1; level >= 0; --level) + { + const bool computed_is_right = (std::rand() % 2); + address |= (computed_is_right ? 1ul << (tree_depth-1-level) : 0); + address_bits.push_back(computed_is_right); + bit_vector other(digest_len); + std::generate(other.begin(), other.end(), [&]() { return std::rand() % 2; }); + + bit_vector load_block = prev_load_hash; + load_block.insert(computed_is_right ? load_block.begin() : load_block.end(), other.begin(), other.end()); + bit_vector store_block = prev_store_hash; + store_block.insert(computed_is_right ? store_block.begin() : store_block.end(), other.begin(), other.end()); + + bit_vector load_h = HashT::get_hash(load_block); + bit_vector store_h = HashT::get_hash(store_block); + + prev_path[level] = other; + + prev_load_hash = load_h; + prev_store_hash = store_h; + } + + bit_vector load_root = prev_load_hash; + bit_vector store_root = prev_store_hash; + + /* execute the test */ + protoboard pb; + pb_variable_array address_bits_va; + address_bits_va.allocate(pb, tree_depth, "address_bits"); + digest_variable prev_leaf_digest(pb, digest_len, "prev_leaf_digest"); + digest_variable prev_root_digest(pb, digest_len, "prev_root_digest"); + merkle_authentication_path_variable prev_path_var(pb, tree_depth, "prev_path_var"); + digest_variable next_leaf_digest(pb, digest_len, "next_leaf_digest"); + digest_variable next_root_digest(pb, digest_len, "next_root_digest"); + merkle_authentication_path_variable next_path_var(pb, tree_depth, "next_path_var"); + merkle_tree_check_update_gadget mls(pb, tree_depth, address_bits_va, + prev_leaf_digest, prev_root_digest, prev_path_var, + next_leaf_digest, next_root_digest, next_path_var, ONE, "mls"); + + prev_path_var.generate_r1cs_constraints(); + mls.generate_r1cs_constraints(); + + address_bits_va.fill_with_bits(pb, address_bits); + assert(address_bits_va.get_field_element_from_bits(pb).as_ulong() == address); + prev_leaf_digest.generate_r1cs_witness(loaded_leaf); + prev_path_var.generate_r1cs_witness(address, prev_path); + next_leaf_digest.generate_r1cs_witness(stored_leaf); + address_bits_va.fill_with_bits(pb, address_bits); + mls.generate_r1cs_witness(); + + /* make sure that update check will check for the right things */ + prev_leaf_digest.generate_r1cs_witness(loaded_leaf); + next_leaf_digest.generate_r1cs_witness(stored_leaf); + prev_root_digest.generate_r1cs_witness(load_root); + next_root_digest.generate_r1cs_witness(store_root); + address_bits_va.fill_with_bits(pb, address_bits); + assert(pb.is_satisfied()); + + const size_t num_constraints = pb.num_constraints(); + const size_t expected_constraints = merkle_tree_check_update_gadget::expected_constraints(tree_depth); + assert(num_constraints == expected_constraints); +} + +} // libsnark + +#endif // MERKLE_TREE_CHECK_UPDATE_GADGET_TCC_ diff --git a/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp new file mode 100644 index 000000000..27b52f9ec --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/gadgets/merkle_tree/tests/test_merkle_tree_gadgets.cpp @@ -0,0 +1,40 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +#ifdef CURVE_BN128 +#include "algebra/curves/bn128/bn128_pp.hpp" +#endif +#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" +#include "gadgetlib1/gadgets/merkle_tree/merkle_tree_check_update_gadget.hpp" +#include "gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" + +#include + +using namespace libsnark; + +template +void test_all_merkle_tree_gadgets() +{ + typedef Fr FieldT; + test_merkle_tree_check_read_gadget >(); + + test_merkle_tree_check_update_gadget >(); +} + +TEST(gadgetlib1, merkle_tree) +{ + start_profiling(); + + alt_bn128_pp::init_public_params(); + test_all_merkle_tree_gadgets(); + +#ifdef CURVE_BN128 // BN128 has fancy dependencies so it may be disabled + bn128_pp::init_public_params(); + test_all_merkle_tree_gadgets(); +#endif +} diff --git a/src/snark/libsnark/gadgetlib1/pb_variable.hpp b/src/snark/libsnark/gadgetlib1/pb_variable.hpp new file mode 100644 index 000000000..fdf64d014 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/pb_variable.hpp @@ -0,0 +1,144 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PB_VARIABLE_HPP_ +#define PB_VARIABLE_HPP_ + +#include +#include +#include +#include "common/utils.hpp" +#include "relations/variable.hpp" + +namespace libsnark { + +typedef size_t lc_index_t; + +template +class protoboard; + +template +class pb_variable : public variable { +public: + pb_variable(const var_index_t index = 0) : variable(index) {}; + + void allocate(protoboard &pb, const std::string &annotation=""); +}; + +template +class pb_variable_array : private std::vector > +{ + typedef std::vector > contents; +public: + using typename contents::iterator; + using typename contents::const_iterator; + using typename contents::reverse_iterator; + using typename contents::const_reverse_iterator; + + using contents::begin; + using contents::end; + using contents::rbegin; + using contents::rend; + using contents::emplace_back; + using contents::insert; + using contents::reserve; + using contents::size; + using contents::empty; + using contents::operator[]; + using contents::resize; + + pb_variable_array() : contents() {}; + pb_variable_array(size_t count, const pb_variable &value) : contents(count, value) {}; + pb_variable_array(typename contents::const_iterator first, typename contents::const_iterator last) : contents(first, last) {}; + pb_variable_array(typename contents::const_reverse_iterator first, typename contents::const_reverse_iterator last) : contents(first, last) {}; + void allocate(protoboard &pb, const size_t n, const std::string &annotation_prefix=""); + + void fill_with_field_elements(protoboard &pb, const std::vector& vals) const; + void fill_with_bits(protoboard &pb, const bit_vector& bits) const; + void fill_with_bits_of_ulong(protoboard &pb, const unsigned long i) const; + void fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const; + + std::vector get_vals(const protoboard &pb) const; + bit_vector get_bits(const protoboard &pb) const; + + FieldT get_field_element_from_bits(const protoboard &pb) const; +}; + +/* index 0 corresponds to the constant term (used in legacy code) */ +#define ONE pb_variable(0) + +template +class pb_linear_combination : public linear_combination { +public: + bool is_variable; + lc_index_t index; + + pb_linear_combination(); + pb_linear_combination(const pb_variable &var); + + void assign(protoboard &pb, const linear_combination &lc); + void evaluate(protoboard &pb) const; + + bool is_constant() const; + FieldT constant_term() const; +}; + +template +class pb_linear_combination_array : private std::vector > +{ + typedef std::vector > contents; +public: + using typename contents::iterator; + using typename contents::const_iterator; + using typename contents::reverse_iterator; + using typename contents::const_reverse_iterator; + + using contents::begin; + using contents::end; + using contents::rbegin; + using contents::rend; + using contents::emplace_back; + using contents::insert; + using contents::reserve; + using contents::size; + using contents::empty; + using contents::operator[]; + using contents::resize; + + pb_linear_combination_array() : contents() {}; + pb_linear_combination_array(const pb_variable_array &arr) { for (auto &v : arr) this->emplace_back(pb_linear_combination(v)); }; + pb_linear_combination_array(size_t count) : contents(count) {}; + pb_linear_combination_array(size_t count, const pb_linear_combination &value) : contents(count, value) {}; + pb_linear_combination_array(typename contents::const_iterator first, typename contents::const_iterator last) : contents(first, last) {}; + pb_linear_combination_array(typename contents::const_reverse_iterator first, typename contents::const_reverse_iterator last) : contents(first, last) {}; + + void evaluate(protoboard &pb) const; + + void fill_with_field_elements(protoboard &pb, const std::vector& vals) const; + void fill_with_bits(protoboard &pb, const bit_vector& bits) const; + void fill_with_bits_of_ulong(protoboard &pb, const unsigned long i) const; + void fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const; + + std::vector get_vals(const protoboard &pb) const; + bit_vector get_bits(const protoboard &pb) const; + + FieldT get_field_element_from_bits(const protoboard &pb) const; +}; + +template +linear_combination pb_sum(const pb_linear_combination_array &v); + +template +linear_combination pb_packing_sum(const pb_linear_combination_array &v); + +template +linear_combination pb_coeff_sum(const pb_linear_combination_array &v, const std::vector &coeffs); + +} // libsnark +#include "gadgetlib1/pb_variable.tcc" + +#endif // PB_VARIABLE_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/pb_variable.tcc b/src/snark/libsnark/gadgetlib1/pb_variable.tcc new file mode 100644 index 000000000..b36b3f8d7 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/pb_variable.tcc @@ -0,0 +1,330 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PB_VARIABLE_TCC_ +#define PB_VARIABLE_TCC_ +#include +#include "gadgetlib1/protoboard.hpp" +#include "common/utils.hpp" + +namespace libsnark { + +template +void pb_variable::allocate(protoboard &pb, const std::string &annotation) +{ + this->index = pb.allocate_var_index(annotation); +} + +/* allocates pb_variable array in MSB->LSB order */ +template +void pb_variable_array::allocate(protoboard &pb, const size_t n, const std::string &annotation_prefix) +{ +#ifdef DEBUG + assert(annotation_prefix != ""); +#endif + (*this).resize(n); + + for (size_t i = 0; i < n; ++i) + { + (*this)[i].allocate(pb, FMT(annotation_prefix, "_%zu", i)); + } +} + +template +void pb_variable_array::fill_with_field_elements(protoboard &pb, const std::vector& vals) const +{ + assert(this->size() == vals.size()); + for (size_t i = 0; i < vals.size(); ++i) + { + pb.val((*this)[i]) = vals[i]; + } +} + +template +void pb_variable_array::fill_with_bits(protoboard &pb, const bit_vector& bits) const +{ + assert(this->size() == bits.size()); + for (size_t i = 0; i < bits.size(); ++i) + { + pb.val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero()); + } +} + +template +void pb_variable_array::fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const +{ + const bigint rint = r.as_bigint(); + for (size_t i = 0; i < this->size(); ++i) + { + pb.val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero(); + } +} + +template +void pb_variable_array::fill_with_bits_of_ulong(protoboard &pb, const unsigned long i) const +{ + this->fill_with_bits_of_field_element(pb, FieldT(i, true)); +} + +template +std::vector pb_variable_array::get_vals(const protoboard &pb) const +{ + std::vector result(this->size()); + for (size_t i = 0; i < this->size(); ++i) + { + result[i] = pb.val((*this)[i]); + } + return result; +} + +template +bit_vector pb_variable_array::get_bits(const protoboard &pb) const +{ + bit_vector result; + for (size_t i = 0; i < this->size(); ++i) + { + const FieldT v = pb.val((*this)[i]); + assert(v == FieldT::zero() || v == FieldT::one()); + result.push_back(v == FieldT::one()); + } + return result; +} + +template +FieldT pb_variable_array::get_field_element_from_bits(const protoboard &pb) const +{ + FieldT result = FieldT::zero(); + + for (size_t i = 0; i < this->size(); ++i) + { + /* push in the new bit */ + const FieldT v = pb.val((*this)[this->size()-1-i]); + assert(v == FieldT::zero() || v == FieldT::one()); + result += result + v; + } + + return result; +} + +template +pb_linear_combination::pb_linear_combination() +{ + this->is_variable = false; + this->index = 0; +} + +template +pb_linear_combination::pb_linear_combination(const pb_variable &var) +{ + this->is_variable = true; + this->index = var.index; + this->terms.emplace_back(linear_term(var)); +} + +template +void pb_linear_combination::assign(protoboard &pb, const linear_combination &lc) +{ + assert(this->is_variable == false); + this->index = pb.allocate_lc_index(); + this->terms = lc.terms; +} + +template +void pb_linear_combination::evaluate(protoboard &pb) const +{ + if (this->is_variable) + { + return; // do nothing + } + + FieldT sum = 0; + for (auto term : this->terms) + { + sum += term.coeff * pb.val(pb_variable(term.index)); + } + + pb.lc_val(*this) = sum; +} + +template +bool pb_linear_combination::is_constant() const +{ + if (is_variable) + { + return (index == 0); + } + else + { + for (auto term : this->terms) + { + if (term.index != 0) + { + return false; + } + } + + return true; + } +} + +template +FieldT pb_linear_combination::constant_term() const +{ + if (is_variable) + { + return (index == 0 ? FieldT::one() : FieldT::zero()); + } + else + { + FieldT result = FieldT::zero(); + for (auto term : this->terms) + { + if (term.index == 0) + { + result += term.coeff; + } + } + return result; + } +} + +template +void pb_linear_combination_array::evaluate(protoboard &pb) const +{ + for (size_t i = 0; i < this->size(); ++i) + { + (*this)[i].evaluate(pb); + } +} + +template +void pb_linear_combination_array::fill_with_field_elements(protoboard &pb, const std::vector& vals) const +{ + assert(this->size() == vals.size()); + for (size_t i = 0; i < vals.size(); ++i) + { + pb.lc_val((*this)[i]) = vals[i]; + } +} + +template +void pb_linear_combination_array::fill_with_bits(protoboard &pb, const bit_vector& bits) const +{ + assert(this->size() == bits.size()); + for (size_t i = 0; i < bits.size(); ++i) + { + pb.lc_val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero()); + } +} + +template +void pb_linear_combination_array::fill_with_bits_of_field_element(protoboard &pb, const FieldT &r) const +{ + const bigint rint = r.as_bigint(); + for (size_t i = 0; i < this->size(); ++i) + { + pb.lc_val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero(); + } +} + +template +void pb_linear_combination_array::fill_with_bits_of_ulong(protoboard &pb, const unsigned long i) const +{ + this->fill_with_bits_of_field_element(pb, FieldT(i)); +} + +template +std::vector pb_linear_combination_array::get_vals(const protoboard &pb) const +{ + std::vector result(this->size()); + for (size_t i = 0; i < this->size(); ++i) + { + result[i] = pb.lc_val((*this)[i]); + } + return result; +} + +template +bit_vector pb_linear_combination_array::get_bits(const protoboard &pb) const +{ + bit_vector result; + for (size_t i = 0; i < this->size(); ++i) + { + const FieldT v = pb.lc_val((*this)[i]); + assert(v == FieldT::zero() || v == FieldT::one()); + result.push_back(v == FieldT::one()); + } + return result; +} + +template +FieldT pb_linear_combination_array::get_field_element_from_bits(const protoboard &pb) const +{ + FieldT result = FieldT::zero(); + + for (size_t i = 0; i < this->size(); ++i) + { + /* push in the new bit */ + const FieldT v = pb.lc_val((*this)[this->size()-1-i]); + assert(v == FieldT::zero() || v == FieldT::one()); + result += result + v; + } + + return result; +} + +template +linear_combination pb_sum(const pb_linear_combination_array &v) +{ + linear_combination result; + for (auto &term : v) + { + result = result + term; + } + + return result; +} + +template +linear_combination pb_packing_sum(const pb_linear_combination_array &v) +{ + FieldT twoi = FieldT::one(); // will hold 2^i entering each iteration + std::vector > all_terms; + for (auto &lc : v) + { + for (auto &term : lc.terms) + { + all_terms.emplace_back(twoi * term); + } + twoi += twoi; + } + + return linear_combination(all_terms); +} + +template +linear_combination pb_coeff_sum(const pb_linear_combination_array &v, const std::vector &coeffs) +{ + assert(v.size() == coeffs.size()); + std::vector > all_terms; + + auto coeff_it = coeffs.begin(); + for (auto &lc : v) + { + for (auto &term : lc.terms) + { + all_terms.emplace_back((*coeff_it) * term); + } + ++coeff_it; + } + + return linear_combination(all_terms); +} + + +} // libsnark +#endif // PB_VARIABLE_TCC diff --git a/src/snark/libsnark/gadgetlib1/protoboard.hpp b/src/snark/libsnark/gadgetlib1/protoboard.hpp new file mode 100644 index 000000000..a910a6df9 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/protoboard.hpp @@ -0,0 +1,75 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PROTOBOARD_HPP_ +#define PROTOBOARD_HPP_ + +#include +#include +#include +#include +#include +#include "gadgetlib1/pb_variable.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" +#include "common/utils.hpp" + +namespace libsnark { + +template +class r1cs_constraint; + +template +class r1cs_constraint_system; + +template +class protoboard { +private: + FieldT constant_term; /* only here, because pb.val() needs to be able to return reference to the constant 1 term */ + r1cs_variable_assignment values; /* values[0] will hold the value of the first allocated variable of the protoboard, *NOT* constant 1 */ + var_index_t next_free_var; + lc_index_t next_free_lc; + std::vector lc_values; +public: + r1cs_constraint_system constraint_system; + + protoboard(); + + void clear_values(); + + FieldT& val(const pb_variable &var); + FieldT val(const pb_variable &var) const; + + FieldT& lc_val(const pb_linear_combination &lc); + FieldT lc_val(const pb_linear_combination &lc) const; + + void add_r1cs_constraint(const r1cs_constraint &constr, const std::string &annotation=""); + void augment_variable_annotation(const pb_variable &v, const std::string &postfix); + bool is_satisfied() const; + void dump_variables() const; + + size_t num_constraints() const; + size_t num_inputs() const; + size_t num_variables() const; + + void set_input_sizes(const size_t primary_input_size); + + r1cs_variable_assignment full_variable_assignment() const; + r1cs_primary_input primary_input() const; + r1cs_auxiliary_input auxiliary_input() const; + r1cs_constraint_system get_constraint_system() const; + + friend class pb_variable; + friend class pb_linear_combination; + +private: + var_index_t allocate_var_index(const std::string &annotation=""); + lc_index_t allocate_lc_index(); +}; + +} // libsnark +#include "gadgetlib1/protoboard.tcc" +#endif // PROTOBOARD_HPP_ diff --git a/src/snark/libsnark/gadgetlib1/protoboard.tcc b/src/snark/libsnark/gadgetlib1/protoboard.tcc new file mode 100644 index 000000000..882af28e6 --- /dev/null +++ b/src/snark/libsnark/gadgetlib1/protoboard.tcc @@ -0,0 +1,189 @@ +/** @file + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef PROTOBOARD_TCC_ +#define PROTOBOARD_TCC_ + +#include +#include +#include "common/profiling.hpp" + +namespace libsnark { + +template +protoboard::protoboard() +{ + constant_term = FieldT::one(); + +#ifdef DEBUG + constraint_system.variable_annotations[0] = "ONE"; +#endif + + next_free_var = 1; /* to account for constant 1 term */ + next_free_lc = 0; +} + +template +void protoboard::clear_values() +{ + std::fill(values.begin(), values.end(), FieldT::zero()); +} + +template +var_index_t protoboard::allocate_var_index(const std::string &annotation) +{ +#ifdef DEBUG + assert(annotation != ""); + constraint_system.variable_annotations[next_free_var] = annotation; +#else + UNUSED(annotation); +#endif + ++constraint_system.auxiliary_input_size; + values.emplace_back(FieldT::zero()); + return next_free_var++; +} + +template +lc_index_t protoboard::allocate_lc_index() +{ + lc_values.emplace_back(FieldT::zero()); + return next_free_lc++; +} + +template +FieldT& protoboard::val(const pb_variable &var) +{ + assert(var.index <= values.size()); + return (var.index == 0 ? constant_term : values[var.index-1]); +} + +template +FieldT protoboard::val(const pb_variable &var) const +{ + assert(var.index <= values.size()); + return (var.index == 0 ? constant_term : values[var.index-1]); +} + +template +FieldT& protoboard::lc_val(const pb_linear_combination &lc) +{ + if (lc.is_variable) + { + return this->val(pb_variable(lc.index)); + } + else + { + assert(lc.index < lc_values.size()); + return lc_values[lc.index]; + } +} + +template +FieldT protoboard::lc_val(const pb_linear_combination &lc) const +{ + if (lc.is_variable) + { + return this->val(pb_variable(lc.index)); + } + else + { + assert(lc.index < lc_values.size()); + return lc_values[lc.index]; + } +} + +template +void protoboard::add_r1cs_constraint(const r1cs_constraint &constr, const std::string &annotation) +{ +#ifdef DEBUG + assert(annotation != ""); + constraint_system.constraint_annotations[constraint_system.constraints.size()] = annotation; +#else + UNUSED(annotation); +#endif + constraint_system.constraints.emplace_back(constr); +} + +template +void protoboard::augment_variable_annotation(const pb_variable &v, const std::string &postfix) +{ +#ifdef DEBUG + auto it = constraint_system.variable_annotations.find(v.index); + constraint_system.variable_annotations[v.index] = (it == constraint_system.variable_annotations.end() ? "" : it->second + " ") + postfix; +#endif +} + +template +bool protoboard::is_satisfied() const +{ + return constraint_system.is_satisfied(primary_input(), auxiliary_input()); +} + +template +void protoboard::dump_variables() const +{ +#ifdef DEBUG + for (size_t i = 0; i < constraint_system.num_variables; ++i) + { + printf("%-40s --> ", constraint_system.variable_annotations[i].c_str()); + values[i].as_bigint().print_hex(); + } +#endif +} + +template +size_t protoboard::num_constraints() const +{ + return constraint_system.num_constraints(); +} + +template +size_t protoboard::num_inputs() const +{ + return constraint_system.num_inputs(); +} + +template +size_t protoboard::num_variables() const +{ + return next_free_var - 1; +} + +template +void protoboard::set_input_sizes(const size_t primary_input_size) +{ + assert(primary_input_size <= num_variables()); + constraint_system.primary_input_size = primary_input_size; + constraint_system.auxiliary_input_size = num_variables() - primary_input_size; +} + +template +r1cs_variable_assignment protoboard::full_variable_assignment() const +{ + return values; +} + +template +r1cs_primary_input protoboard::primary_input() const +{ + return r1cs_primary_input(values.begin(), values.begin() + num_inputs()); +} + +template +r1cs_auxiliary_input protoboard::auxiliary_input() const +{ + return r1cs_primary_input(values.begin() + num_inputs(), values.end()); +} + +template +r1cs_constraint_system protoboard::get_constraint_system() const +{ + return constraint_system; +} + +} // libsnark +#endif // PROTOBOARD_TCC_ diff --git a/src/snark/libsnark/gtests.cpp b/src/snark/libsnark/gtests.cpp new file mode 100644 index 000000000..74c66bdad --- /dev/null +++ b/src/snark/libsnark/gtests.cpp @@ -0,0 +1,12 @@ +#include + +#include "common/profiling.hpp" + +int main(int argc, char **argv) { + libsnark::inhibit_profiling_info = true; + libsnark::inhibit_profiling_counters = true; + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + diff --git a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp new file mode 100644 index 000000000..86831cb1d --- /dev/null +++ b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.hpp @@ -0,0 +1,70 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a R1CS-to-QAP reduction, that is, constructing + a QAP ("Quadratic Arithmetic Program") from a R1CS ("Rank-1 Constraint System"). + + QAPs are defined in \[GGPR13], and constructed for R1CS also in \[GGPR13]. + + The implementation of the reduction follows, extends, and optimizes + the efficient approach described in Appendix E of \[BCGTV13]. + + References: + + \[BCGTV13] + "SNARKs for C: Verifying Program Executions Succinctly and in Zero Knowledge", + Eli Ben-Sasson, Alessandro Chiesa, Daniel Genkin, Eran Tromer, Madars Virza, + CRYPTO 2013, + + + \[GGPR13]: + "Quadratic span programs and succinct NIZKs without PCPs", + Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, + EUROCRYPT 2013, + + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_TO_QAP_HPP_ +#define R1CS_TO_QAP_HPP_ + +#include "relations/arithmetic_programs/qap/qap.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" + +namespace libsnark { + +/** + * Instance map for the R1CS-to-QAP reduction. + */ +template +qap_instance r1cs_to_qap_instance_map(const r1cs_constraint_system &cs); + +/** + * Instance map for the R1CS-to-QAP reduction followed by evaluation of the resulting QAP instance. + */ +template +qap_instance_evaluation r1cs_to_qap_instance_map_with_evaluation(const r1cs_constraint_system &cs, + const FieldT &t); + +/** + * Witness map for the R1CS-to-QAP reduction. + * + * The witness map takes zero knowledge into account when d1,d2,d3 are random. + */ +template +qap_witness r1cs_to_qap_witness_map(const r1cs_constraint_system &cs, + const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3); + +} // libsnark + +#include "reductions/r1cs_to_qap/r1cs_to_qap.tcc" + +#endif // R1CS_TO_QAP_HPP_ diff --git a/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc new file mode 100644 index 000000000..3d0bee273 --- /dev/null +++ b/src/snark/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc @@ -0,0 +1,338 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for a R1CS-to-QAP reduction. + + See r1cs_to_qap.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_TO_QAP_TCC_ +#define R1CS_TO_QAP_TCC_ + +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "algebra/evaluation_domain/evaluation_domain.hpp" + +namespace libsnark { + +/** + * Instance map for the R1CS-to-QAP reduction. + * + * Namely, given a R1CS constraint system cs, construct a QAP instance for which: + * A := (A_0(z),A_1(z),...,A_m(z)) + * B := (B_0(z),B_1(z),...,B_m(z)) + * C := (C_0(z),C_1(z),...,C_m(z)) + * where + * m = number of variables of the QAP + * and + * each A_i,B_i,C_i is expressed in the Lagrange basis. + */ +template +qap_instance r1cs_to_qap_instance_map(const r1cs_constraint_system &cs) +{ + enter_block("Call to r1cs_to_qap_instance_map"); + + const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); + + std::vector > A_in_Lagrange_basis(cs.num_variables()+1); + std::vector > B_in_Lagrange_basis(cs.num_variables()+1); + std::vector > C_in_Lagrange_basis(cs.num_variables()+1); + + enter_block("Compute polynomials A, B, C in Lagrange basis"); + /** + * add and process the constraints + * input_i * 0 = 0 + * to ensure soundness of input consistency + */ + for (size_t i = 0; i <= cs.num_inputs(); ++i) + { + A_in_Lagrange_basis[i][cs.num_constraints() + i] = FieldT::one(); + } + /* process all other constraints */ + for (size_t i = 0; i < cs.num_constraints(); ++i) + { + for (size_t j = 0; j < cs.constraints[i].a.terms.size(); ++j) + { + A_in_Lagrange_basis[cs.constraints[i].a.terms[j].index][i] += + cs.constraints[i].a.terms[j].coeff; + } + + for (size_t j = 0; j < cs.constraints[i].b.terms.size(); ++j) + { + B_in_Lagrange_basis[cs.constraints[i].b.terms[j].index][i] += + cs.constraints[i].b.terms[j].coeff; + } + + for (size_t j = 0; j < cs.constraints[i].c.terms.size(); ++j) + { + C_in_Lagrange_basis[cs.constraints[i].c.terms[j].index][i] += + cs.constraints[i].c.terms[j].coeff; + } + } + leave_block("Compute polynomials A, B, C in Lagrange basis"); + + leave_block("Call to r1cs_to_qap_instance_map"); + + return qap_instance(domain, + cs.num_variables(), + domain->m, + cs.num_inputs(), + std::move(A_in_Lagrange_basis), + std::move(B_in_Lagrange_basis), + std::move(C_in_Lagrange_basis)); +} + +/** + * Instance map for the R1CS-to-QAP reduction followed by evaluation of the resulting QAP instance. + * + * Namely, given a R1CS constraint system cs and a field element t, construct + * a QAP instance (evaluated at t) for which: + * At := (A_0(t),A_1(t),...,A_m(t)) + * Bt := (B_0(t),B_1(t),...,B_m(t)) + * Ct := (C_0(t),C_1(t),...,C_m(t)) + * Ht := (1,t,t^2,...,t^n) + * Zt := Z(t) = "vanishing polynomial of a certain set S, evaluated at t" + * where + * m = number of variables of the QAP + * n = degree of the QAP + */ +template +qap_instance_evaluation r1cs_to_qap_instance_map_with_evaluation(const r1cs_constraint_system &cs, + const FieldT &t) +{ + enter_block("Call to r1cs_to_qap_instance_map_with_evaluation"); + + const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); + + std::vector At, Bt, Ct, Ht; + + At.resize(cs.num_variables()+1, FieldT::zero()); + Bt.resize(cs.num_variables()+1, FieldT::zero()); + Ct.resize(cs.num_variables()+1, FieldT::zero()); + Ht.reserve(domain->m+1); + + const FieldT Zt = domain->compute_Z(t); + + enter_block("Compute evaluations of A, B, C, H at t"); + const std::vector u = domain->lagrange_coeffs(t); + /** + * add and process the constraints + * input_i * 0 = 0 + * to ensure soundness of input consistency + */ + for (size_t i = 0; i <= cs.num_inputs(); ++i) + { + At[i] = u[cs.num_constraints() + i]; + } + /* process all other constraints */ + for (size_t i = 0; i < cs.num_constraints(); ++i) + { + for (size_t j = 0; j < cs.constraints[i].a.terms.size(); ++j) + { + At[cs.constraints[i].a.terms[j].index] += + u[i]*cs.constraints[i].a.terms[j].coeff; + } + + for (size_t j = 0; j < cs.constraints[i].b.terms.size(); ++j) + { + Bt[cs.constraints[i].b.terms[j].index] += + u[i]*cs.constraints[i].b.terms[j].coeff; + } + + for (size_t j = 0; j < cs.constraints[i].c.terms.size(); ++j) + { + Ct[cs.constraints[i].c.terms[j].index] += + u[i]*cs.constraints[i].c.terms[j].coeff; + } + } + + FieldT ti = FieldT::one(); + for (size_t i = 0; i < domain->m+1; ++i) + { + Ht.emplace_back(ti); + ti *= t; + } + leave_block("Compute evaluations of A, B, C, H at t"); + + leave_block("Call to r1cs_to_qap_instance_map_with_evaluation"); + + return qap_instance_evaluation(domain, + cs.num_variables(), + domain->m, + cs.num_inputs(), + t, + std::move(At), + std::move(Bt), + std::move(Ct), + std::move(Ht), + Zt); +} + +/** + * Witness map for the R1CS-to-QAP reduction. + * + * The witness map takes zero knowledge into account when d1,d2,d3 are random. + * + * More precisely, compute the coefficients + * h_0,h_1,...,h_n + * of the polynomial + * H(z) := (A(z)*B(z)-C(z))/Z(z) + * where + * A(z) := A_0(z) + \sum_{k=1}^{m} w_k A_k(z) + d1 * Z(z) + * B(z) := B_0(z) + \sum_{k=1}^{m} w_k B_k(z) + d2 * Z(z) + * C(z) := C_0(z) + \sum_{k=1}^{m} w_k C_k(z) + d3 * Z(z) + * Z(z) := "vanishing polynomial of set S" + * and + * m = number of variables of the QAP + * n = degree of the QAP + * + * This is done as follows: + * (1) compute evaluations of A,B,C on S = {sigma_1,...,sigma_n} + * (2) compute coefficients of A,B,C + * (3) compute evaluations of A,B,C on T = "coset of S" + * (4) compute evaluation of H on T + * (5) compute coefficients of H + * (6) patch H to account for d1,d2,d3 (i.e., add coefficients of the polynomial (A d2 + B d1 - d3) + d1*d2*Z ) + * + * The code below is not as simple as the above high-level description due to + * some reshuffling to save space. + */ +template +qap_witness r1cs_to_qap_witness_map(const r1cs_constraint_system &cs, + const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3) +{ + enter_block("Call to r1cs_to_qap_witness_map"); + + /* sanity check */ + assert(cs.is_satisfied(primary_input, auxiliary_input)); + + const std::shared_ptr > domain = get_evaluation_domain(cs.num_constraints() + cs.num_inputs() + 1); + + r1cs_variable_assignment full_variable_assignment = primary_input; + full_variable_assignment.insert(full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end()); + + enter_block("Compute evaluation of polynomials A, B on set S"); + std::vector aA(domain->m, FieldT::zero()), aB(domain->m, FieldT::zero()); + + /* account for the additional constraints input_i * 0 = 0 */ + for (size_t i = 0; i <= cs.num_inputs(); ++i) + { + aA[i+cs.num_constraints()] = (i > 0 ? full_variable_assignment[i-1] : FieldT::one()); + } + /* account for all other constraints */ + for (size_t i = 0; i < cs.num_constraints(); ++i) + { + aA[i] += cs.constraints[i].a.evaluate(full_variable_assignment); + aB[i] += cs.constraints[i].b.evaluate(full_variable_assignment); + } + leave_block("Compute evaluation of polynomials A, B on set S"); + + enter_block("Compute coefficients of polynomial A"); + domain->iFFT(aA); + leave_block("Compute coefficients of polynomial A"); + + enter_block("Compute coefficients of polynomial B"); + domain->iFFT(aB); + leave_block("Compute coefficients of polynomial B"); + + enter_block("Compute ZK-patch"); + std::vector coefficients_for_H(domain->m+1, FieldT::zero()); +#ifdef MULTICORE +#pragma omp parallel for +#endif + /* add coefficients of the polynomial (d2*A + d1*B - d3) + d1*d2*Z */ + for (size_t i = 0; i < domain->m; ++i) + { + coefficients_for_H[i] = d2*aA[i] + d1*aB[i]; + } + coefficients_for_H[0] -= d3; + domain->add_poly_Z(d1*d2, coefficients_for_H); + leave_block("Compute ZK-patch"); + + enter_block("Compute evaluation of polynomial A on set T"); + domain->cosetFFT(aA, FieldT::multiplicative_generator); + leave_block("Compute evaluation of polynomial A on set T"); + + enter_block("Compute evaluation of polynomial B on set T"); + domain->cosetFFT(aB, FieldT::multiplicative_generator); + leave_block("Compute evaluation of polynomial B on set T"); + + enter_block("Compute evaluation of polynomial H on set T"); + std::vector &H_tmp = aA; // can overwrite aA because it is not used later +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < domain->m; ++i) + { + H_tmp[i] = aA[i]*aB[i]; + } + std::vector().swap(aB); // destroy aB + + enter_block("Compute evaluation of polynomial C on set S"); + std::vector aC(domain->m, FieldT::zero()); + for (size_t i = 0; i < cs.num_constraints(); ++i) + { + aC[i] += cs.constraints[i].c.evaluate(full_variable_assignment); + } + leave_block("Compute evaluation of polynomial C on set S"); + + enter_block("Compute coefficients of polynomial C"); + domain->iFFT(aC); + leave_block("Compute coefficients of polynomial C"); + + enter_block("Compute evaluation of polynomial C on set T"); + domain->cosetFFT(aC, FieldT::multiplicative_generator); + leave_block("Compute evaluation of polynomial C on set T"); + +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < domain->m; ++i) + { + H_tmp[i] = (H_tmp[i]-aC[i]); + } + + enter_block("Divide by Z on set T"); + domain->divide_by_Z_on_coset(H_tmp); + leave_block("Divide by Z on set T"); + + leave_block("Compute evaluation of polynomial H on set T"); + + enter_block("Compute coefficients of polynomial H"); + domain->icosetFFT(H_tmp, FieldT::multiplicative_generator); + leave_block("Compute coefficients of polynomial H"); + + enter_block("Compute sum of H and ZK-patch"); +#ifdef MULTICORE +#pragma omp parallel for +#endif + for (size_t i = 0; i < domain->m; ++i) + { + coefficients_for_H[i] += H_tmp[i]; + } + leave_block("Compute sum of H and ZK-patch"); + + leave_block("Call to r1cs_to_qap_witness_map"); + + return qap_witness(cs.num_variables(), + domain->m, + cs.num_inputs(), + d1, + d2, + d3, + full_variable_assignment, + std::move(coefficients_for_H)); +} + +} // libsnark + +#endif // R1CS_TO_QAP_TCC_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp new file mode 100644 index 000000000..4991d203b --- /dev/null +++ b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.hpp @@ -0,0 +1,193 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a QAP ("Quadratic Arithmetic Program"). + + QAPs are defined in \[GGPR13]. + + References: + + \[GGPR13]: + "Quadratic span programs and succinct NIZKs without PCPs", + Rosario Gennaro, Craig Gentry, Bryan Parno, Mariana Raykova, + EUROCRYPT 2013, + + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef QAP_HPP_ +#define QAP_HPP_ + +#include "algebra/evaluation_domain/evaluation_domain.hpp" + +namespace libsnark { + +/* forward declaration */ +template +class qap_witness; + +/** + * A QAP instance. + * + * Specifically, the datastructure stores: + * - a choice of domain (corresponding to a certain subset of the field); + * - the number of variables, the degree, and the number of inputs; and + * - coefficients of the A,B,C polynomials in the Lagrange basis. + * + * There is no need to store the Z polynomial because it is uniquely + * determined by the domain (as Z is its vanishing polynomial). + */ +template +class qap_instance { +private: + size_t num_variables_; + size_t degree_; + size_t num_inputs_; + +public: + std::shared_ptr > domain; + + std::vector > A_in_Lagrange_basis; + std::vector > B_in_Lagrange_basis; + std::vector > C_in_Lagrange_basis; + + qap_instance(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const std::vector > &A_in_Lagrange_basis, + const std::vector > &B_in_Lagrange_basis, + const std::vector > &C_in_Lagrange_basis); + + qap_instance(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + std::vector > &&A_in_Lagrange_basis, + std::vector > &&B_in_Lagrange_basis, + std::vector > &&C_in_Lagrange_basis); + + qap_instance(const qap_instance &other) = default; + qap_instance(qap_instance &&other) = default; + qap_instance& operator=(const qap_instance &other) = default; + qap_instance& operator=(qap_instance &&other) = default; + + size_t num_variables() const; + size_t degree() const; + size_t num_inputs() const; + + bool is_satisfied(const qap_witness &witness) const; +}; + +/** + * A QAP instance evaluation is a QAP instance that is evaluated at a field element t. + * + * Specifically, the datastructure stores: + * - a choice of domain (corresponding to a certain subset of the field); + * - the number of variables, the degree, and the number of inputs; + * - a field element t; + * - evaluations of the A,B,C (and Z) polynomials at t; + * - evaluations of all monomials of t; + * - counts about how many of the above evaluations are in fact non-zero. + */ +template +class qap_instance_evaluation { +private: + size_t num_variables_; + size_t degree_; + size_t num_inputs_; +public: + std::shared_ptr > domain; + + FieldT t; + + std::vector At, Bt, Ct, Ht; + + FieldT Zt; + + qap_instance_evaluation(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &t, + const std::vector &At, + const std::vector &Bt, + const std::vector &Ct, + const std::vector &Ht, + const FieldT &Zt); + qap_instance_evaluation(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &t, + std::vector &&At, + std::vector &&Bt, + std::vector &&Ct, + std::vector &&Ht, + const FieldT &Zt); + + qap_instance_evaluation(const qap_instance_evaluation &other) = default; + qap_instance_evaluation(qap_instance_evaluation &&other) = default; + qap_instance_evaluation& operator=(const qap_instance_evaluation &other) = default; + qap_instance_evaluation& operator=(qap_instance_evaluation &&other) = default; + + size_t num_variables() const; + size_t degree() const; + size_t num_inputs() const; + + bool is_satisfied(const qap_witness &witness) const; +}; + +/** + * A QAP witness. + */ +template +class qap_witness { +private: + size_t num_variables_; + size_t degree_; + size_t num_inputs_; + +public: + FieldT d1, d2, d3; + + std::vector coefficients_for_ABCs; + std::vector coefficients_for_H; + + qap_witness(const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3, + const std::vector &coefficients_for_ABCs, + const std::vector &coefficients_for_H); + + qap_witness(const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3, + const std::vector &coefficients_for_ABCs, + std::vector &&coefficients_for_H); + + qap_witness(const qap_witness &other) = default; + qap_witness(qap_witness &&other) = default; + qap_witness& operator=(const qap_witness &other) = default; + qap_witness& operator=(qap_witness &&other) = default; + + size_t num_variables() const; + size_t degree() const; + size_t num_inputs() const; +}; + +} // libsnark + +#include "relations/arithmetic_programs/qap/qap.tcc" + +#endif // QAP_HPP_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc new file mode 100644 index 000000000..a4a3c96a2 --- /dev/null +++ b/src/snark/libsnark/relations/arithmetic_programs/qap/qap.tcc @@ -0,0 +1,324 @@ +/** @file +***************************************************************************** + +Implementation of interfaces for a QAP ("Quadratic Arithmetic Program"). + +See qap.hpp . + +***************************************************************************** +* @author This file is part of libsnark, developed by SCIPR Lab +* and contributors (see AUTHORS). +* @copyright MIT license (see LICENSE file) +*****************************************************************************/ + +#ifndef QAP_TCC_ +#define QAP_TCC_ + +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "algebra/evaluation_domain/evaluation_domain.hpp" +#include "algebra/scalar_multiplication/multiexp.hpp" + +namespace libsnark { + +template +qap_instance::qap_instance(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const std::vector > &A_in_Lagrange_basis, + const std::vector > &B_in_Lagrange_basis, + const std::vector > &C_in_Lagrange_basis) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + domain(domain), + A_in_Lagrange_basis(A_in_Lagrange_basis), + B_in_Lagrange_basis(B_in_Lagrange_basis), + C_in_Lagrange_basis(C_in_Lagrange_basis) +{ +} + +template +qap_instance::qap_instance(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + std::vector > &&A_in_Lagrange_basis, + std::vector > &&B_in_Lagrange_basis, + std::vector > &&C_in_Lagrange_basis) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + domain(domain), + A_in_Lagrange_basis(std::move(A_in_Lagrange_basis)), + B_in_Lagrange_basis(std::move(B_in_Lagrange_basis)), + C_in_Lagrange_basis(std::move(C_in_Lagrange_basis)) +{ +} + +template +size_t qap_instance::num_variables() const +{ + return num_variables_; +} + +template +size_t qap_instance::degree() const +{ + return degree_; +} + +template +size_t qap_instance::num_inputs() const +{ + return num_inputs_; +} + +template +bool qap_instance::is_satisfied(const qap_witness &witness) const +{ + const FieldT t = FieldT::random_element(); + + std::vector At(this->num_variables()+1, FieldT::zero()); + std::vector Bt(this->num_variables()+1, FieldT::zero()); + std::vector Ct(this->num_variables()+1, FieldT::zero()); + std::vector Ht(this->degree()+1); + + const FieldT Zt = this->domain->compute_Z(t); + + const std::vector u = this->domain->lagrange_coeffs(t); + + for (size_t i = 0; i < this->num_variables()+1; ++i) + { + for (auto &el : A_in_Lagrange_basis[i]) + { + At[i] += u[el.first] * el.second; + } + + for (auto &el : B_in_Lagrange_basis[i]) + { + Bt[i] += u[el.first] * el.second; + } + + for (auto &el : C_in_Lagrange_basis[i]) + { + Ct[i] += u[el.first] * el.second; + } + } + + FieldT ti = FieldT::one(); + for (size_t i = 0; i < this->degree()+1; ++i) + { + Ht[i] = ti; + ti *= t; + } + + const qap_instance_evaluation eval_qap_inst(this->domain, + this->num_variables(), + this->degree(), + this->num_inputs(), + t, + std::move(At), + std::move(Bt), + std::move(Ct), + std::move(Ht), + Zt); + return eval_qap_inst.is_satisfied(witness); +} + +template +qap_instance_evaluation::qap_instance_evaluation(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &t, + const std::vector &At, + const std::vector &Bt, + const std::vector &Ct, + const std::vector &Ht, + const FieldT &Zt) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + domain(domain), + t(t), + At(At), + Bt(Bt), + Ct(Ct), + Ht(Ht), + Zt(Zt) +{ +} + +template +qap_instance_evaluation::qap_instance_evaluation(const std::shared_ptr > &domain, + const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &t, + std::vector &&At, + std::vector &&Bt, + std::vector &&Ct, + std::vector &&Ht, + const FieldT &Zt) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + domain(domain), + t(t), + At(std::move(At)), + Bt(std::move(Bt)), + Ct(std::move(Ct)), + Ht(std::move(Ht)), + Zt(Zt) +{ +} + +template +size_t qap_instance_evaluation::num_variables() const +{ + return num_variables_; +} + +template +size_t qap_instance_evaluation::degree() const +{ + return degree_; +} + +template +size_t qap_instance_evaluation::num_inputs() const +{ + return num_inputs_; +} + +template +bool qap_instance_evaluation::is_satisfied(const qap_witness &witness) const +{ + + if (this->num_variables() != witness.num_variables()) + { + return false; + } + + if (this->degree() != witness.degree()) + { + return false; + } + + if (this->num_inputs() != witness.num_inputs()) + { + return false; + } + + if (this->num_variables() != witness.coefficients_for_ABCs.size()) + { + return false; + } + + if (this->degree()+1 != witness.coefficients_for_H.size()) + { + return false; + } + + if (this->At.size() != this->num_variables()+1 || this->Bt.size() != this->num_variables()+1 || this->Ct.size() != this->num_variables()+1) + { + return false; + } + + if (this->Ht.size() != this->degree()+1) + { + return false; + } + + if (this->Zt != this->domain->compute_Z(this->t)) + { + return false; + } + + FieldT ans_A = this->At[0] + witness.d1*this->Zt; + FieldT ans_B = this->Bt[0] + witness.d2*this->Zt; + FieldT ans_C = this->Ct[0] + witness.d3*this->Zt; + FieldT ans_H = FieldT::zero(); + + ans_A = ans_A + naive_plain_exp(this->At.begin()+1, this->At.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_B = ans_B + naive_plain_exp(this->Bt.begin()+1, this->Bt.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_C = ans_C + naive_plain_exp(this->Ct.begin()+1, this->Ct.begin()+1+this->num_variables(), + witness.coefficients_for_ABCs.begin(), witness.coefficients_for_ABCs.begin()+this->num_variables()); + ans_H = ans_H + naive_plain_exp(this->Ht.begin(), this->Ht.begin()+this->degree()+1, + witness.coefficients_for_H.begin(), witness.coefficients_for_H.begin()+this->degree()+1); + + if (ans_A * ans_B - ans_C != ans_H * this->Zt) + { + return false; + } + + return true; +} + +template +qap_witness::qap_witness(const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3, + const std::vector &coefficients_for_ABCs, + const std::vector &coefficients_for_H) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + d1(d1), + d2(d2), + d3(d3), + coefficients_for_ABCs(coefficients_for_ABCs), + coefficients_for_H(coefficients_for_H) +{ +} + +template +qap_witness::qap_witness(const size_t num_variables, + const size_t degree, + const size_t num_inputs, + const FieldT &d1, + const FieldT &d2, + const FieldT &d3, + const std::vector &coefficients_for_ABCs, + std::vector &&coefficients_for_H) : + num_variables_(num_variables), + degree_(degree), + num_inputs_(num_inputs), + d1(d1), + d2(d2), + d3(d3), + coefficients_for_ABCs(coefficients_for_ABCs), + coefficients_for_H(std::move(coefficients_for_H)) +{ +} + + +template +size_t qap_witness::num_variables() const +{ + return num_variables_; +} + +template +size_t qap_witness::degree() const +{ + return degree_; +} + +template +size_t qap_witness::num_inputs() const +{ + return num_inputs_; +} + + +} // libsnark + +#endif // QAP_TCC_ diff --git a/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp b/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp new file mode 100644 index 000000000..e20f589c9 --- /dev/null +++ b/src/snark/libsnark/relations/arithmetic_programs/qap/tests/test_qap.cpp @@ -0,0 +1,104 @@ +/** + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include +#include +#include +#include +#include + +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +#include "algebra/fields/field_utils.hpp" +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" + +#include + +using namespace libsnark; + +template +void test_qap(const size_t qap_degree, const size_t num_inputs, const bool binary_input) +{ + /* + We construct an instance where the QAP degree is qap_degree. + So we generate an instance of R1CS where the number of constraints qap_degree - num_inputs - 1. + See the transformation from R1CS to QAP for why this is the case. + So we need that qap_degree >= num_inputs + 1. + */ + ASSERT_LE(num_inputs + 1, qap_degree); + enter_block("Call to test_qap"); + + const size_t num_constraints = qap_degree - num_inputs - 1; + + print_indent(); printf("* QAP degree: %zu\n", qap_degree); + print_indent(); printf("* Number of inputs: %zu\n", num_inputs); + print_indent(); printf("* Number of R1CS constraints: %zu\n", num_constraints); + print_indent(); printf("* Input type: %s\n", binary_input ? "binary" : "field"); + + enter_block("Generate constraint system and assignment"); + r1cs_example example; + if (binary_input) + { + example = generate_r1cs_example_with_binary_input(num_constraints, num_inputs); + } + else + { + example = generate_r1cs_example_with_field_input(num_constraints, num_inputs); + } + leave_block("Generate constraint system and assignment"); + + enter_block("Check satisfiability of constraint system"); + EXPECT_TRUE(example.constraint_system.is_satisfied(example.primary_input, example.auxiliary_input)); + leave_block("Check satisfiability of constraint system"); + + const FieldT t = FieldT::random_element(), + d1 = FieldT::random_element(), + d2 = FieldT::random_element(), + d3 = FieldT::random_element(); + + enter_block("Compute QAP instance 1"); + qap_instance qap_inst_1 = r1cs_to_qap_instance_map(example.constraint_system); + leave_block("Compute QAP instance 1"); + + enter_block("Compute QAP instance 2"); + qap_instance_evaluation qap_inst_2 = r1cs_to_qap_instance_map_with_evaluation(example.constraint_system, t); + leave_block("Compute QAP instance 2"); + + enter_block("Compute QAP witness"); + qap_witness qap_wit = r1cs_to_qap_witness_map(example.constraint_system, example.primary_input, example.auxiliary_input, d1, d2, d3); + leave_block("Compute QAP witness"); + + enter_block("Check satisfiability of QAP instance 1"); + EXPECT_TRUE(qap_inst_1.is_satisfied(qap_wit)); + leave_block("Check satisfiability of QAP instance 1"); + + enter_block("Check satisfiability of QAP instance 2"); + EXPECT_TRUE(qap_inst_2.is_satisfied(qap_wit)); + leave_block("Check satisfiability of QAP instance 2"); + + leave_block("Call to test_qap"); +} + +TEST(relations, qap) +{ + start_profiling(); + + const size_t num_inputs = 10; + + enter_block("Test QAP with binary input"); + + test_qap >(1ul << 21, num_inputs, true); + + leave_block("Test QAP with binary input"); + + enter_block("Test QAP with field input"); + + test_qap >(1ul << 21, num_inputs, false); + + leave_block("Test QAP with field input"); +} diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp new file mode 100644 index 000000000..47003e959 --- /dev/null +++ b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp @@ -0,0 +1,73 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a R1CS example, as well as functions to sample + R1CS examples with prescribed parameters (according to some distribution). + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_EXAMPLES_HPP_ +#define R1CS_EXAMPLES_HPP_ + +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" + +namespace libsnark { + +/** + * A R1CS example comprises a R1CS constraint system, R1CS input, and R1CS witness. + */ +template +struct r1cs_example { + r1cs_constraint_system constraint_system; + r1cs_primary_input primary_input; + r1cs_auxiliary_input auxiliary_input; + + r1cs_example() = default; + r1cs_example(const r1cs_example &other) = default; + r1cs_example(const r1cs_constraint_system &constraint_system, + const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input) : + constraint_system(constraint_system), + primary_input(primary_input), + auxiliary_input(auxiliary_input) + {}; + r1cs_example(r1cs_constraint_system &&constraint_system, + r1cs_primary_input &&primary_input, + r1cs_auxiliary_input &&auxiliary_input) : + constraint_system(std::move(constraint_system)), + primary_input(std::move(primary_input)), + auxiliary_input(std::move(auxiliary_input)) + {}; +}; + +/** + * Generate a R1CS example such that: + * - the number of constraints of the R1CS constraint system is num_constraints; + * - the number of variables of the R1CS constraint system is (approximately) num_constraints; + * - the number of inputs of the R1CS constraint system is num_inputs; + * - the R1CS input consists of ``full'' field elements (typically require the whole log|Field| bits to represent). + */ +template +r1cs_example generate_r1cs_example_with_field_input(const size_t num_constraints, + const size_t num_inputs); + +/** + * Generate a R1CS example such that: + * - the number of constraints of the R1CS constraint system is num_constraints; + * - the number of variables of the R1CS constraint system is (approximately) num_constraints; + * - the number of inputs of the R1CS constraint system is num_inputs; + * - the R1CS input consists of binary values (as opposed to ``full'' field elements). + */ +template +r1cs_example generate_r1cs_example_with_binary_input(const size_t num_constraints, + const size_t num_inputs); + +} // libsnark + +#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc" + +#endif // R1CS_EXAMPLES_HPP_ diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc new file mode 100644 index 000000000..defa07721 --- /dev/null +++ b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc @@ -0,0 +1,164 @@ +/** @file + ***************************************************************************** + + Implementation of functions to sample R1CS examples with prescribed parameters + (according to some distribution). + + See r1cs_examples.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_EXAMPLES_TCC_ +#define R1CS_EXAMPLES_TCC_ + +#include + +#include "common/utils.hpp" + +namespace libsnark { + +template +r1cs_example generate_r1cs_example_with_field_input(const size_t num_constraints, + const size_t num_inputs) +{ + enter_block("Call to generate_r1cs_example_with_field_input"); + + assert(num_inputs <= num_constraints + 2); + + r1cs_constraint_system cs; + cs.primary_input_size = num_inputs; + cs.auxiliary_input_size = 2 + num_constraints - num_inputs; // TODO: explain this + + r1cs_variable_assignment full_variable_assignment; + FieldT a = FieldT::random_element(); + FieldT b = FieldT::random_element(); + full_variable_assignment.push_back(a); + full_variable_assignment.push_back(b); + + for (size_t i = 0; i < num_constraints-1; ++i) + { + linear_combination A, B, C; + + if (i % 2) + { + // a * b = c + A.add_term(i+1, 1); + B.add_term(i+2, 1); + C.add_term(i+3, 1); + FieldT tmp = a*b; + full_variable_assignment.push_back(tmp); + a = b; b = tmp; + } + else + { + // a + b = c + B.add_term(0, 1); + A.add_term(i+1, 1); + A.add_term(i+2, 1); + C.add_term(i+3, 1); + FieldT tmp = a+b; + full_variable_assignment.push_back(tmp); + a = b; b = tmp; + } + + cs.add_constraint(r1cs_constraint(A, B, C)); + } + + linear_combination A, B, C; + FieldT fin = FieldT::zero(); + for (size_t i = 1; i < cs.num_variables(); ++i) + { + A.add_term(i, 1); + B.add_term(i, 1); + fin = fin + full_variable_assignment[i-1]; + } + C.add_term(cs.num_variables(), 1); + cs.add_constraint(r1cs_constraint(A, B, C)); + full_variable_assignment.push_back(fin.squared()); + + /* split variable assignment */ + r1cs_primary_input primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + num_inputs); + r1cs_primary_input auxiliary_input(full_variable_assignment.begin() + num_inputs, full_variable_assignment.end()); + + /* sanity checks */ + assert(cs.num_variables() == full_variable_assignment.size()); + assert(cs.num_variables() >= num_inputs); + assert(cs.num_inputs() == num_inputs); + assert(cs.num_constraints() == num_constraints); + assert(cs.is_satisfied(primary_input, auxiliary_input)); + + leave_block("Call to generate_r1cs_example_with_field_input"); + + return r1cs_example(std::move(cs), std::move(primary_input), std::move(auxiliary_input)); +} + +template +r1cs_example generate_r1cs_example_with_binary_input(const size_t num_constraints, + const size_t num_inputs) +{ + enter_block("Call to generate_r1cs_example_with_binary_input"); + + assert(num_inputs >= 1); + + r1cs_constraint_system cs; + cs.primary_input_size = num_inputs; + cs.auxiliary_input_size = num_constraints; /* we will add one auxiliary variable per constraint */ + + r1cs_variable_assignment full_variable_assignment; + for (size_t i = 0; i < num_inputs; ++i) + { + full_variable_assignment.push_back(FieldT(std::rand() % 2)); + } + + size_t lastvar = num_inputs-1; + for (size_t i = 0; i < num_constraints; ++i) + { + ++lastvar; + const size_t u = (i == 0 ? std::rand() % num_inputs : std::rand() % i); + const size_t v = (i == 0 ? std::rand() % num_inputs : std::rand() % i); + + /* chose two random bits and XOR them together: + res = u + v - 2 * u * v + 2 * u * v = u + v - res + */ + linear_combination A, B, C; + A.add_term(u+1, 2); + B.add_term(v+1, 1); + if (u == v) + { + C.add_term(u+1, 2); + } + else + { + C.add_term(u+1, 1); + C.add_term(v+1, 1); + } + C.add_term(lastvar+1, -FieldT::one()); + + cs.add_constraint(r1cs_constraint(A, B, C)); + full_variable_assignment.push_back(full_variable_assignment[u] + full_variable_assignment[v] - full_variable_assignment[u] * full_variable_assignment[v] - full_variable_assignment[u] * full_variable_assignment[v]); + } + + /* split variable assignment */ + r1cs_primary_input primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + num_inputs); + r1cs_primary_input auxiliary_input(full_variable_assignment.begin() + num_inputs, full_variable_assignment.end()); + + /* sanity checks */ + assert(cs.num_variables() == full_variable_assignment.size()); + assert(cs.num_variables() >= num_inputs); + assert(cs.num_inputs() == num_inputs); + assert(cs.num_constraints() == num_constraints); + assert(cs.is_satisfied(primary_input, auxiliary_input)); + + leave_block("Call to generate_r1cs_example_with_binary_input"); + + return r1cs_example(std::move(cs), std::move(primary_input), std::move(auxiliary_input)); +} + +} // libsnark + +#endif // R1CS_EXAMPLES_TCC diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp new file mode 100644 index 000000000..ca3acb3a9 --- /dev/null +++ b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp @@ -0,0 +1,153 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for: + - a R1CS constraint, + - a R1CS variable assignment, and + - a R1CS constraint system. + + Above, R1CS stands for "Rank-1 Constraint System". + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_HPP_ +#define R1CS_HPP_ + +#include +#include +#include +#include +#include + +#include "relations/variable.hpp" + +namespace libsnark { + +/************************* R1CS constraint ***********************************/ + +template +class r1cs_constraint; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_constraint &c); + +template +std::istream& operator>>(std::istream &in, r1cs_constraint &c); + +/** + * A R1CS constraint is a formal expression of the form + * + * < A , X > * < B , X > = < C , X > , + * + * where X = (x_0,x_1,...,x_m) is a vector of formal variables and A,B,C each + * consist of 1+m elements in . + * + * A R1CS constraint is used to construct a R1CS constraint system (see below). + */ +template +class r1cs_constraint { +public: + + linear_combination a, b, c; + + r1cs_constraint() {}; + r1cs_constraint(const linear_combination &a, + const linear_combination &b, + const linear_combination &c); + + r1cs_constraint(const std::initializer_list > &A, + const std::initializer_list > &B, + const std::initializer_list > &C); + + bool operator==(const r1cs_constraint &other) const; + + friend std::ostream& operator<< (std::ostream &out, const r1cs_constraint &c); + friend std::istream& operator>> (std::istream &in, r1cs_constraint &c); +}; + +/************************* R1CS variable assignment **************************/ + +/** + * A R1CS variable assignment is a vector of elements that represents + * a candidate solution to a R1CS constraint system (see below). + */ + +/* TODO: specify that it does *NOT* include the constant 1 */ +template +using r1cs_primary_input = std::vector; + +template +using r1cs_auxiliary_input = std::vector; + +template +using r1cs_variable_assignment = std::vector; /* note the changed name! (TODO: remove this comment after primary_input transition is complete) */ + +/************************* R1CS constraint system ****************************/ + +template +class r1cs_constraint_system; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_constraint_system &cs); + +template +std::istream& operator>>(std::istream &in, r1cs_constraint_system &cs); + +/** + * A system of R1CS constraints looks like + * + * { < A_k , X > * < B_k , X > = < C_k , X > }_{k=1}^{n} . + * + * In other words, the system is satisfied if and only if there exist a + * USCS variable assignment for which each R1CS constraint is satisfied. + * + * NOTE: + * The 0-th variable (i.e., "x_{0}") always represents the constant 1. + * Thus, the 0-th variable is not included in num_variables. + */ +template +class r1cs_constraint_system { +public: + size_t primary_input_size; + size_t auxiliary_input_size; + + std::vector > constraints; + + r1cs_constraint_system() : primary_input_size(0), auxiliary_input_size(0) {} + + size_t num_inputs() const; + size_t num_variables() const; + size_t num_constraints() const; + +#ifdef DEBUG + std::map constraint_annotations; + std::map variable_annotations; +#endif + + bool is_valid() const; + bool is_satisfied(const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input) const; + + void add_constraint(const r1cs_constraint &c); + void add_constraint(const r1cs_constraint &c, const std::string &annotation); + + void swap_AB_if_beneficial(); + + bool operator==(const r1cs_constraint_system &other) const; + + friend std::ostream& operator<< (std::ostream &out, const r1cs_constraint_system &cs); + friend std::istream& operator>> (std::istream &in, r1cs_constraint_system &cs); + + void report_linear_constraint_statistics() const; +}; + + +} // libsnark + +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.tcc" + +#endif // R1CS_HPP_ diff --git a/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc new file mode 100644 index 000000000..0faa56a87 --- /dev/null +++ b/src/snark/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.tcc @@ -0,0 +1,310 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for: + - a R1CS constraint, + - a R1CS variable assignment, and + - a R1CS constraint system. + + See r1cs.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_TCC_ +#define R1CS_TCC_ + +#include +#include +#include +#include "common/utils.hpp" +#include "common/profiling.hpp" +#include "algebra/fields/bigint.hpp" + +namespace libsnark { + +template +r1cs_constraint::r1cs_constraint(const linear_combination &a, + const linear_combination &b, + const linear_combination &c) : + a(a), b(b), c(c) +{ +} + +template +r1cs_constraint::r1cs_constraint(const std::initializer_list > &A, + const std::initializer_list > &B, + const std::initializer_list > &C) +{ + for (auto lc_A : A) + { + a.terms.insert(a.terms.end(), lc_A.terms.begin(), lc_A.terms.end()); + } + for (auto lc_B : B) + { + b.terms.insert(b.terms.end(), lc_B.terms.begin(), lc_B.terms.end()); + } + for (auto lc_C : C) + { + c.terms.insert(c.terms.end(), lc_C.terms.begin(), lc_C.terms.end()); + } +} + +template +bool r1cs_constraint::operator==(const r1cs_constraint &other) const +{ + return (this->a == other.a && + this->b == other.b && + this->c == other.c); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_constraint &c) +{ + out << c.a; + out << c.b; + out << c.c; + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_constraint &c) +{ + in >> c.a; + in >> c.b; + in >> c.c; + + return in; +} + +template +size_t r1cs_constraint_system::num_inputs() const +{ + return primary_input_size; +} + +template +size_t r1cs_constraint_system::num_variables() const +{ + return primary_input_size + auxiliary_input_size; +} + + +template +size_t r1cs_constraint_system::num_constraints() const +{ + return constraints.size(); +} + +template +bool r1cs_constraint_system::is_valid() const +{ + if (this->num_inputs() > this->num_variables()) return false; + + for (size_t c = 0; c < constraints.size(); ++c) + { + if (!(constraints[c].a.is_valid(this->num_variables()) && + constraints[c].b.is_valid(this->num_variables()) && + constraints[c].c.is_valid(this->num_variables()))) + { + return false; + } + } + + return true; +} + +template +void dump_r1cs_constraint(const r1cs_constraint &constraint, + const r1cs_variable_assignment &full_variable_assignment, + const std::map &variable_annotations) +{ + printf("terms for a:\n"); constraint.a.print_with_assignment(full_variable_assignment, variable_annotations); + printf("terms for b:\n"); constraint.b.print_with_assignment(full_variable_assignment, variable_annotations); + printf("terms for c:\n"); constraint.c.print_with_assignment(full_variable_assignment, variable_annotations); +} + +template +bool r1cs_constraint_system::is_satisfied(const r1cs_primary_input &primary_input, + const r1cs_auxiliary_input &auxiliary_input) const +{ + assert(primary_input.size() == num_inputs()); + assert(primary_input.size() + auxiliary_input.size() == num_variables()); + + r1cs_variable_assignment full_variable_assignment = primary_input; + full_variable_assignment.insert(full_variable_assignment.end(), auxiliary_input.begin(), auxiliary_input.end()); + + for (size_t c = 0; c < constraints.size(); ++c) + { + const FieldT ares = constraints[c].a.evaluate(full_variable_assignment); + const FieldT bres = constraints[c].b.evaluate(full_variable_assignment); + const FieldT cres = constraints[c].c.evaluate(full_variable_assignment); + + if (!(ares*bres == cres)) + { +#ifdef DEBUG + auto it = constraint_annotations.find(c); + printf("constraint %zu (%s) unsatisfied\n", c, (it == constraint_annotations.end() ? "no annotation" : it->second.c_str())); + printf(" = "); ares.print(); + printf(" = "); bres.print(); + printf(" = "); cres.print(); + printf("constraint was:\n"); + dump_r1cs_constraint(constraints[c], full_variable_assignment, variable_annotations); +#endif // DEBUG + return false; + } + } + + return true; +} + +template +void r1cs_constraint_system::add_constraint(const r1cs_constraint &c) +{ + constraints.emplace_back(c); +} + +template +void r1cs_constraint_system::add_constraint(const r1cs_constraint &c, const std::string &annotation) +{ +#ifdef DEBUG + constraint_annotations[constraints.size()] = annotation; +#endif + constraints.emplace_back(c); +} + +template +void r1cs_constraint_system::swap_AB_if_beneficial() +{ + enter_block("Call to r1cs_constraint_system::swap_AB_if_beneficial"); + + enter_block("Estimate densities"); + bit_vector touched_by_A(this->num_variables() + 1, false), touched_by_B(this->num_variables() + 1, false); + + for (size_t i = 0; i < this->constraints.size(); ++i) + { + for (size_t j = 0; j < this->constraints[i].a.terms.size(); ++j) + { + touched_by_A[this->constraints[i].a.terms[j].index] = true; + } + + for (size_t j = 0; j < this->constraints[i].b.terms.size(); ++j) + { + touched_by_B[this->constraints[i].b.terms[j].index] = true; + } + } + + size_t non_zero_A_count = 0, non_zero_B_count = 0; + for (size_t i = 0; i < this->num_variables() + 1; ++i) + { + non_zero_A_count += touched_by_A[i] ? 1 : 0; + non_zero_B_count += touched_by_B[i] ? 1 : 0; + } + + if (!inhibit_profiling_info) + { + print_indent(); printf("* Non-zero A-count (estimate): %zu\n", non_zero_A_count); + print_indent(); printf("* Non-zero B-count (estimate): %zu\n", non_zero_B_count); + } + leave_block("Estimate densities"); + + if (non_zero_B_count > non_zero_A_count) + { + enter_block("Perform the swap"); + for (size_t i = 0; i < this->constraints.size(); ++i) + { + std::swap(this->constraints[i].a, this->constraints[i].b); + } + leave_block("Perform the swap"); + } + else + { + print_indent(); printf("Swap is not beneficial, not performing\n"); + } + + leave_block("Call to r1cs_constraint_system::swap_AB_if_beneficial"); +} + +template +bool r1cs_constraint_system::operator==(const r1cs_constraint_system &other) const +{ + return (this->constraints == other.constraints && + this->primary_input_size == other.primary_input_size && + this->auxiliary_input_size == other.auxiliary_input_size); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_constraint_system &cs) +{ + out << cs.primary_input_size << "\n"; + out << cs.auxiliary_input_size << "\n"; + + out << cs.num_constraints() << "\n"; + for (const r1cs_constraint& c : cs.constraints) + { + out << c; + } + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_constraint_system &cs) +{ + in >> cs.primary_input_size; + in >> cs.auxiliary_input_size; + + cs.constraints.clear(); + + size_t s; + in >> s; + + char b; + in.read(&b, 1); + + cs.constraints.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + r1cs_constraint c; + in >> c; + cs.constraints.emplace_back(c); + } + + return in; +} + +template +void r1cs_constraint_system::report_linear_constraint_statistics() const +{ +#ifdef DEBUG + for (size_t i = 0; i < constraints.size(); ++i) + { + auto &constr = constraints[i]; + bool a_is_const = true; + for (auto &t : constr.a.terms) + { + a_is_const = a_is_const && (t.index == 0); + } + + bool b_is_const = true; + for (auto &t : constr.b.terms) + { + b_is_const = b_is_const && (t.index == 0); + } + + if (a_is_const || b_is_const) + { + auto it = constraint_annotations.find(i); + printf("%s\n", (it == constraint_annotations.end() ? FORMAT("", "constraint_%zu", i) : it->second).c_str()); + } + } +#endif +} + +} // libsnark +#endif // R1CS_TCC_ diff --git a/src/snark/libsnark/relations/variable.hpp b/src/snark/libsnark/relations/variable.hpp new file mode 100644 index 000000000..8c2c704a3 --- /dev/null +++ b/src/snark/libsnark/relations/variable.hpp @@ -0,0 +1,213 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for: + - a variable (i.e., x_i), + - a linear term (i.e., a_i * x_i), and + - a linear combination (i.e., sum_i a_i * x_i). + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef VARIABLE_HPP_ +#define VARIABLE_HPP_ + +#include +#include +#include +#include + +namespace libsnark { + +/** + * Mnemonic typedefs. + */ +typedef size_t var_index_t; +typedef long integer_coeff_t; + +/** + * Forward declaration. + */ +template +class linear_term; + +/** + * Forward declaration. + */ +template +class linear_combination; + +/********************************* Variable **********************************/ + +/** + * A variable represents a formal expression of the form "x_{index}". + */ +template +class variable { +public: + + var_index_t index; + + variable(const var_index_t index = 0) : index(index) {}; + + linear_term operator*(const integer_coeff_t int_coeff) const; + linear_term operator*(const FieldT &field_coeff) const; + + linear_combination operator+(const linear_combination &other) const; + linear_combination operator-(const linear_combination &other) const; + + linear_term operator-() const; + + bool operator==(const variable &other) const; +}; + +template +linear_term operator*(const integer_coeff_t int_coeff, const variable &var); + +template +linear_term operator*(const FieldT &field_coeff, const variable &var); + +template +linear_combination operator+(const integer_coeff_t int_coeff, const variable &var); + +template +linear_combination operator+(const FieldT &field_coeff, const variable &var); + +template +linear_combination operator-(const integer_coeff_t int_coeff, const variable &var); + +template +linear_combination operator-(const FieldT &field_coeff, const variable &var); + + +/****************************** Linear term **********************************/ + +/** + * A linear term represents a formal expression of the form "coeff * x_{index}". + */ +template +class linear_term { +public: + + var_index_t index = 0; + FieldT coeff; + + linear_term() {}; + linear_term(const variable &var); + linear_term(const variable &var, const integer_coeff_t int_coeff); + linear_term(const variable &var, const FieldT &field_coeff); + + linear_term operator*(const integer_coeff_t int_coeff) const; + linear_term operator*(const FieldT &field_coeff) const; + + linear_combination operator+(const linear_combination &other) const; + linear_combination operator-(const linear_combination &other) const; + + linear_term operator-() const; + + bool operator==(const linear_term &other) const; +}; + +template +linear_term operator*(const integer_coeff_t int_coeff, const linear_term <); + +template +linear_term operator*(const FieldT &field_coeff, const linear_term <); + +template +linear_combination operator+(const integer_coeff_t int_coeff, const linear_term <); + +template +linear_combination operator+(const FieldT &field_coeff, const linear_term <); + +template +linear_combination operator-(const integer_coeff_t int_coeff, const linear_term <); + +template +linear_combination operator-(const FieldT &field_coeff, const linear_term <); + + +/***************************** Linear combination ****************************/ + +template +class linear_combination; + +template +std::ostream& operator<<(std::ostream &out, const linear_combination &lc); + +template +std::istream& operator>>(std::istream &in, linear_combination &lc); + +/** + * A linear combination represents a formal expression of the form "sum_i coeff_i * x_{index_i}". + */ +template +class linear_combination { +public: + + std::vector > terms; + + linear_combination() {}; + linear_combination(const integer_coeff_t int_coeff); + linear_combination(const FieldT &field_coeff); + linear_combination(const variable &var); + linear_combination(const linear_term <); + linear_combination(const std::vector > &all_terms); + + /* for supporting range-based for loops over linear_combination */ + typename std::vector >::const_iterator begin() const; + typename std::vector >::const_iterator end() const; + + void add_term(const variable &var); + void add_term(const variable &var, const integer_coeff_t int_coeff); + void add_term(const variable &var, const FieldT &field_coeff); + + void add_term(const linear_term <); + + FieldT evaluate(const std::vector &assignment) const; + + linear_combination operator*(const integer_coeff_t int_coeff) const; + linear_combination operator*(const FieldT &field_coeff) const; + + linear_combination operator+(const linear_combination &other) const; + + linear_combination operator-(const linear_combination &other) const; + linear_combination operator-() const; + + bool operator==(const linear_combination &other) const; + + bool is_valid(const size_t num_variables) const; + + void print(const std::map &variable_annotations = std::map()) const; + void print_with_assignment(const std::vector &full_assignment, const std::map &variable_annotations = std::map()) const; + + friend std::ostream& operator<< (std::ostream &out, const linear_combination &lc); + friend std::istream& operator>> (std::istream &in, linear_combination &lc); +}; + +template +linear_combination operator*(const integer_coeff_t int_coeff, const linear_combination &lc); + +template +linear_combination operator*(const FieldT &field_coeff, const linear_combination &lc); + +template +linear_combination operator+(const integer_coeff_t int_coeff, const linear_combination &lc); + +template +linear_combination operator+(const FieldT &field_coeff, const linear_combination &lc); + +template +linear_combination operator-(const integer_coeff_t int_coeff, const linear_combination &lc); + +template +linear_combination operator-(const FieldT &field_coeff, const linear_combination &lc); + +} // libsnark + +#include "relations/variable.tcc" + +#endif // VARIABLE_HPP_ diff --git a/src/snark/libsnark/relations/variable.tcc b/src/snark/libsnark/relations/variable.tcc new file mode 100644 index 000000000..4c4cab97f --- /dev/null +++ b/src/snark/libsnark/relations/variable.tcc @@ -0,0 +1,512 @@ +/** @file + ***************************************************************************** + + Implementation of interfaces for: + - a variable (i.e., x_i), + - a linear term (i.e., a_i * x_i), and + - a linear combination (i.e., sum_i a_i * x_i). + + See variabe.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef VARIABLE_TCC_ +#define VARIABLE_TCC_ + +#include +#include + +#include "algebra/fields/bigint.hpp" + +namespace libsnark { + +template +linear_term variable::operator*(const integer_coeff_t int_coeff) const +{ + return linear_term(*this, int_coeff); +} + +template +linear_term variable::operator*(const FieldT &field_coeff) const +{ + return linear_term(*this, field_coeff); +} + +template +linear_combination variable::operator+(const linear_combination &other) const +{ + linear_combination result; + + result.add_term(*this); + result.terms.insert(result.terms.begin(), other.terms.begin(), other.terms.end()); + + return result; +} + +template +linear_combination variable::operator-(const linear_combination &other) const +{ + return (*this) + (-other); +} + +template +linear_term variable::operator-() const +{ + return linear_term(*this, -FieldT::one()); +} + +template +bool variable::operator==(const variable &other) const +{ + return (this->index == other.index); +} + +template +linear_term operator*(const integer_coeff_t int_coeff, const variable &var) +{ + return linear_term(var, int_coeff); +} + +template +linear_term operator*(const FieldT &field_coeff, const variable &var) +{ + return linear_term(var, field_coeff); +} + +template +linear_combination operator+(const integer_coeff_t int_coeff, const variable &var) +{ + return linear_combination(int_coeff) + var; +} + +template +linear_combination operator+(const FieldT &field_coeff, const variable &var) +{ + return linear_combination(field_coeff) + var; +} + +template +linear_combination operator-(const integer_coeff_t int_coeff, const variable &var) +{ + return linear_combination(int_coeff) - var; +} + +template +linear_combination operator-(const FieldT &field_coeff, const variable &var) +{ + return linear_combination(field_coeff) - var; +} + +template +linear_term::linear_term(const variable &var) : + index(var.index), coeff(FieldT::one()) +{ +} + +template +linear_term::linear_term(const variable &var, const integer_coeff_t int_coeff) : + index(var.index), coeff(FieldT(int_coeff)) +{ +} + +template +linear_term::linear_term(const variable &var, const FieldT &coeff) : + index(var.index), coeff(coeff) +{ +} + +template +linear_term linear_term::operator*(const integer_coeff_t int_coeff) const +{ + return (this->operator*(FieldT(int_coeff))); +} + +template +linear_term linear_term::operator*(const FieldT &field_coeff) const +{ + return linear_term(this->index, field_coeff * this->coeff); +} + +template +linear_combination operator+(const integer_coeff_t int_coeff, const linear_term <) +{ + return linear_combination(int_coeff) + lt; +} + +template +linear_combination operator+(const FieldT &field_coeff, const linear_term <) +{ + return linear_combination(field_coeff) + lt; +} + +template +linear_combination operator-(const integer_coeff_t int_coeff, const linear_term <) +{ + return linear_combination(int_coeff) - lt; +} + +template +linear_combination operator-(const FieldT &field_coeff, const linear_term <) +{ + return linear_combination(field_coeff) - lt; +} + +template +linear_combination linear_term::operator+(const linear_combination &other) const +{ + return linear_combination(*this) + other; +} + +template +linear_combination linear_term::operator-(const linear_combination &other) const +{ + return (*this) + (-other); +} + +template +linear_term linear_term::operator-() const +{ + return linear_term(this->index, -this->coeff); +} + +template +bool linear_term::operator==(const linear_term &other) const +{ + return (this->index == other.index && + this->coeff == other.coeff); +} + +template +linear_term operator*(const integer_coeff_t int_coeff, const linear_term <) +{ + return FieldT(int_coeff) * lt; +} + +template +linear_term operator*(const FieldT &field_coeff, const linear_term <) +{ + return linear_term(lt.index, field_coeff * lt.coeff); +} + +template +linear_combination::linear_combination(const integer_coeff_t int_coeff) +{ + this->add_term(linear_term(0, int_coeff)); +} + +template +linear_combination::linear_combination(const FieldT &field_coeff) +{ + this->add_term(linear_term(0, field_coeff)); +} + +template +linear_combination::linear_combination(const variable &var) +{ + this->add_term(var); +} + +template +linear_combination::linear_combination(const linear_term <) +{ + this->add_term(lt); +} + +template +typename std::vector >::const_iterator linear_combination::begin() const +{ + return terms.begin(); +} + +template +typename std::vector >::const_iterator linear_combination::end() const +{ + return terms.end(); +} + +template +void linear_combination::add_term(const variable &var) +{ + this->terms.emplace_back(linear_term(var.index, FieldT::one())); +} + +template +void linear_combination::add_term(const variable &var, const integer_coeff_t int_coeff) +{ + this->terms.emplace_back(linear_term(var.index, int_coeff)); +} + +template +void linear_combination::add_term(const variable &var, const FieldT &coeff) +{ + this->terms.emplace_back(linear_term(var.index, coeff)); +} + +template +void linear_combination::add_term(const linear_term &other) +{ + this->terms.emplace_back(other); +} + +template +linear_combination linear_combination::operator*(const integer_coeff_t int_coeff) const +{ + return (*this) * FieldT(int_coeff); +} + +template +FieldT linear_combination::evaluate(const std::vector &assignment) const +{ + FieldT acc = FieldT::zero(); + for (auto < : terms) + { + acc += (lt.index == 0 ? FieldT::one() : assignment[lt.index-1]) * lt.coeff; + } + return acc; +} + +template +linear_combination linear_combination::operator*(const FieldT &field_coeff) const +{ + linear_combination result; + result.terms.reserve(this->terms.size()); + for (const linear_term < : this->terms) + { + result.terms.emplace_back(lt * field_coeff); + } + return result; +} + +template +linear_combination linear_combination::operator+(const linear_combination &other) const +{ + linear_combination result; + + auto it1 = this->terms.begin(); + auto it2 = other.terms.begin(); + + /* invariant: it1 and it2 always point to unprocessed items in the corresponding linear combinations */ + while (it1 != this->terms.end() && it2 != other.terms.end()) + { + if (it1->index < it2->index) + { + result.terms.emplace_back(*it1); + ++it1; + } + else if (it1->index > it2->index) + { + result.terms.emplace_back(*it2); + ++it2; + } + else + { + /* it1->index == it2->index */ + result.terms.emplace_back(linear_term(variable(it1->index), it1->coeff + it2->coeff)); + ++it1; + ++it2; + } + } + + if (it1 != this->terms.end()) + { + result.terms.insert(result.terms.end(), it1, this->terms.end()); + } + else + { + result.terms.insert(result.terms.end(), it2, other.terms.end()); + } + + return result; +} + +template +linear_combination linear_combination::operator-(const linear_combination &other) const +{ + return (*this) + (-other); +} + +template +linear_combination linear_combination::operator-() const +{ + return (*this) * (-FieldT::one()); +} + +template +bool linear_combination::operator==(const linear_combination &other) const +{ + return (this->terms == other.terms); +} + +template +bool linear_combination::is_valid(const size_t num_variables) const +{ + /* check that all terms in linear combination are sorted */ + for (size_t i = 1; i < terms.size(); ++i) + { + if (terms[i-1].index >= terms[i].index) + { + return false; + } + } + + /* check that the variables are in proper range. as the variables + are sorted, it suffices to check the last term */ + if ((--terms.end())->index >= num_variables) + { + return false; + } + + return true; +} + +template +void linear_combination::print(const std::map &variable_annotations) const +{ + for (auto < : terms) + { + if (lt.index == 0) + { + printf(" 1 * "); + lt.coeff.print(); + } + else + { + auto it = variable_annotations.find(lt.index); + printf(" x_%zu (%s) * ", lt.index, (it == variable_annotations.end() ? "no annotation" : it->second.c_str())); + lt.coeff.print(); + } + } +} + +template +void linear_combination::print_with_assignment(const std::vector &full_assignment, const std::map &variable_annotations) const +{ + for (auto < : terms) + { + if (lt.index == 0) + { + printf(" 1 * "); + lt.coeff.print(); + } + else + { + printf(" x_%zu * ", lt.index); + lt.coeff.print(); + + auto it = variable_annotations.find(lt.index); + printf(" where x_%zu (%s) was assigned value ", lt.index, + (it == variable_annotations.end() ? "no annotation" : it->second.c_str())); + full_assignment[lt.index-1].print(); + printf(" i.e. negative of "); + (-full_assignment[lt.index-1]).print(); + } + } +} + +template +std::ostream& operator<<(std::ostream &out, const linear_combination &lc) +{ + out << lc.terms.size() << "\n"; + for (const linear_term& lt : lc.terms) + { + out << lt.index << "\n"; + out << lt.coeff << OUTPUT_NEWLINE; + } + + return out; +} + +template +std::istream& operator>>(std::istream &in, linear_combination &lc) +{ + lc.terms.clear(); + + size_t s; + in >> s; + + consume_newline(in); + + lc.terms.reserve(s); + + for (size_t i = 0; i < s; ++i) + { + linear_term lt; + in >> lt.index; + consume_newline(in); + in >> lt.coeff; + consume_OUTPUT_NEWLINE(in); + lc.terms.emplace_back(lt); + } + + return in; +} + +template +linear_combination operator*(const integer_coeff_t int_coeff, const linear_combination &lc) +{ + return lc * int_coeff; +} + +template +linear_combination operator*(const FieldT &field_coeff, const linear_combination &lc) +{ + return lc * field_coeff; +} + +template +linear_combination operator+(const integer_coeff_t int_coeff, const linear_combination &lc) +{ + return linear_combination(int_coeff) + lc; +} + +template +linear_combination operator+(const FieldT &field_coeff, const linear_combination &lc) +{ + return linear_combination(field_coeff) + lc; +} + +template +linear_combination operator-(const integer_coeff_t int_coeff, const linear_combination &lc) +{ + return linear_combination(int_coeff) - lc; +} + +template +linear_combination operator-(const FieldT &field_coeff, const linear_combination &lc) +{ + return linear_combination(field_coeff) - lc; +} + +template +linear_combination::linear_combination(const std::vector > &all_terms) +{ + if (all_terms.empty()) + { + return; + } + + terms = all_terms; + std::sort(terms.begin(), terms.end(), [](linear_term a, linear_term b) { return a.index < b.index; }); + + auto result_it = terms.begin(); + for (auto it = ++terms.begin(); it != terms.end(); ++it) + { + if (it->index == result_it->index) + { + result_it->coeff += it->coeff; + } + else + { + *(++result_it) = *it; + } + } + terms.resize((result_it - terms.begin()) + 1); +} + +} // libsnark + +#endif // VARIABLE_TCC diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp new file mode 100644 index 000000000..fcd28abf3 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp @@ -0,0 +1,35 @@ +/** @file + ***************************************************************************** + + Declaration of functionality that runs the R1CS ppzkSNARK for + a given R1CS example. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef RUN_R1CS_PPZKSNARK_HPP_ +#define RUN_R1CS_PPZKSNARK_HPP_ + +#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" + +namespace libsnark { + +/** + * Runs the ppzkSNARK (generator, prover, and verifier) for a given + * R1CS example (specified by a constraint system, input, and witness). + * + * Optionally, also test the serialization routines for keys and proofs. + * (This takes additional time.) + */ +template +bool run_r1cs_ppzksnark(const r1cs_example > &example, + const bool test_serialization); + +} // libsnark + +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc" + +#endif // RUN_R1CS_PPZKSNARK_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc new file mode 100644 index 000000000..00af6fe25 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.tcc @@ -0,0 +1,114 @@ +/** @file + ***************************************************************************** + + Implementation of functionality that runs the R1CS ppzkSNARK for + a given R1CS example. + + See run_r1cs_ppzksnark.hpp . + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef RUN_R1CS_PPZKSNARK_TCC_ +#define RUN_R1CS_PPZKSNARK_TCC_ + +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" + +#include +#include + +#include "common/profiling.hpp" + +namespace libsnark { + +template +typename std::enable_if::type +test_affine_verifier(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof, + const bool expected_answer) +{ + print_header("R1CS ppzkSNARK Affine Verifier"); + const bool answer = r1cs_ppzksnark_affine_verifier_weak_IC(vk, primary_input, proof); + assert(answer == expected_answer); +} + +template +typename std::enable_if::type +test_affine_verifier(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof, + const bool expected_answer) +{ + UNUSED(vk, primary_input, proof, expected_answer); + print_header("R1CS ppzkSNARK Affine Verifier"); + printf("Affine verifier is not supported; not testing anything.\n"); +} + +/** + * The code below provides an example of all stages of running a R1CS ppzkSNARK. + * + * Of course, in a real-life scenario, we would have three distinct entities, + * mangled into one in the demonstration below. The three entities are as follows. + * (1) The "generator", which runs the ppzkSNARK generator on input a given + * constraint system CS to create a proving and a verification key for CS. + * (2) The "prover", which runs the ppzkSNARK prover on input the proving key, + * a primary input for CS, and an auxiliary input for CS. + * (3) The "verifier", which runs the ppzkSNARK verifier on input the verification key, + * a primary input for CS, and a proof. + */ +template +bool run_r1cs_ppzksnark(const r1cs_example > &example, + const bool test_serialization) +{ + enter_block("Call to run_r1cs_ppzksnark"); + + print_header("R1CS ppzkSNARK Generator"); + r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(example.constraint_system); + printf("\n"); print_indent(); print_mem("after generator"); + + print_header("Preprocess verification key"); + r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(keypair.vk); + + if (test_serialization) + { + enter_block("Test serialization of keys"); + keypair.pk = reserialize >(keypair.pk); + keypair.vk = reserialize >(keypair.vk); + pvk = reserialize >(pvk); + leave_block("Test serialization of keys"); + } + + print_header("R1CS ppzkSNARK Prover"); + r1cs_ppzksnark_proof proof = r1cs_ppzksnark_prover(keypair.pk, example.primary_input, example.auxiliary_input, example.constraint_system); + printf("\n"); print_indent(); print_mem("after prover"); + + if (test_serialization) + { + enter_block("Test serialization of proof"); + proof = reserialize >(proof); + leave_block("Test serialization of proof"); + } + + print_header("R1CS ppzkSNARK Verifier"); + const bool ans = r1cs_ppzksnark_verifier_strong_IC(keypair.vk, example.primary_input, proof); + printf("\n"); print_indent(); print_mem("after verifier"); + printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL")); + + print_header("R1CS ppzkSNARK Online Verifier"); + const bool ans2 = r1cs_ppzksnark_online_verifier_strong_IC(pvk, example.primary_input, proof); + assert(ans == ans2); + + test_affine_verifier(keypair.vk, example.primary_input, proof, ans); + + leave_block("Call to run_r1cs_ppzksnark"); + + return ans; +} + +} // libsnark + +#endif // RUN_R1CS_PPZKSNARK_TCC_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp new file mode 100644 index 000000000..5c5415028 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark.cpp @@ -0,0 +1,71 @@ +/** @file + ***************************************************************************** + Profiling program that exercises the ppzkSNARK (first generator, then prover, + then verifier) on a synthetic R1CS instance. + + The command + + $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 Fr + + exercises the ppzkSNARK (first generator, then prover, then verifier) on an R1CS instance with 1000 equations and an input consisting of 10 field elements. + + (If you get the error `zmInit ERR:can't protect`, see the discussion [above](#elliptic-curve-choices).) + + The command + + $ src/zk_proof_systems/ppzksnark/r1cs_ppzksnark/profiling/profile_r1cs_ppzksnark 1000 10 bytes + + does the same but now the input consists of 10 bytes. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include +#include + +#include "common/default_types/r1cs_ppzksnark_pp.hpp" +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp" + +using namespace libsnark; + +int main(int argc, const char * argv[]) +{ + default_r1cs_ppzksnark_pp::init_public_params(); + start_profiling(); + + if (argc == 2 && strcmp(argv[1], "-v") == 0) + { + print_compilation_info(); + return 0; + } + + if (argc != 3 && argc != 4) + { + printf("usage: %s num_constraints input_size [Fr|bytes]\n", argv[0]); + return 1; + } + const int num_constraints = atoi(argv[1]); + int input_size = atoi(argv[2]); + if (argc == 4) + { + assert(strcmp(argv[3], "Fr") == 0 || strcmp(argv[3], "bytes") == 0); + if (strcmp(argv[3], "bytes") == 0) + { + input_size = div_ceil(8 * input_size, Fr::capacity()); + } + } + + enter_block("Generate R1CS example"); + r1cs_example > example = generate_r1cs_example_with_field_input >(num_constraints, input_size); + leave_block("Generate R1CS example"); + + print_header("(enter) Profile R1CS ppzkSNARK"); + const bool test_serialization = true; + run_r1cs_ppzksnark(example, test_serialization); + print_header("(leave) Profile R1CS ppzkSNARK"); +} diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp new file mode 100644 index 000000000..6095d6a08 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp @@ -0,0 +1,486 @@ +/** @file + ***************************************************************************** + + Declaration of interfaces for a ppzkSNARK for R1CS. + + This includes: + - class for proving key + - class for verification key + - class for processed verification key + - class for key pair (proving key & verification key) + - class for proof + - generator algorithm + - prover algorithm + - verifier algorithm (with strong or weak input consistency) + - online verifier algorithm (with strong or weak input consistency) + + The implementation instantiates (a modification of) the protocol of \[PGHR13], + by following extending, and optimizing the approach described in \[BCTV14]. + + + Acronyms: + + - R1CS = "Rank-1 Constraint Systems" + - ppzkSNARK = "PreProcessing Zero-Knowledge Succinct Non-interactive ARgument of Knowledge" + + References: + + \[BCTV14]: + "Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture", + Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza, + USENIX Security 2014, + + + \[PGHR13]: + "Pinocchio: Nearly practical verifiable computation", + Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova, + IEEE S&P 2013, + + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_PPZKSNARK_HPP_ +#define R1CS_PPZKSNARK_HPP_ + +#include + +#include "algebra/curves/public_params.hpp" +#include "common/data_structures/accumulation_vector.hpp" +#include "algebra/knowledge_commitment/knowledge_commitment.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp" + +namespace libsnark { + +/******************************** Proving key ********************************/ + +template +class r1cs_ppzksnark_proving_key; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proving_key &pk); + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proving_key &pk); + +/** + * A proving key for the R1CS ppzkSNARK. + */ +template +class r1cs_ppzksnark_proving_key { +public: + knowledge_commitment_vector, G1 > A_query; + knowledge_commitment_vector, G1 > B_query; + knowledge_commitment_vector, G1 > C_query; + G1_vector H_query; + G1_vector K_query; + + r1cs_ppzksnark_proving_key() {}; + r1cs_ppzksnark_proving_key& operator=(const r1cs_ppzksnark_proving_key &other) = default; + r1cs_ppzksnark_proving_key(const r1cs_ppzksnark_proving_key &other) = default; + r1cs_ppzksnark_proving_key(r1cs_ppzksnark_proving_key &&other) = default; + r1cs_ppzksnark_proving_key(knowledge_commitment_vector, G1 > &&A_query, + knowledge_commitment_vector, G1 > &&B_query, + knowledge_commitment_vector, G1 > &&C_query, + G1_vector &&H_query, + G1_vector &&K_query) : + A_query(std::move(A_query)), + B_query(std::move(B_query)), + C_query(std::move(C_query)), + H_query(std::move(H_query)), + K_query(std::move(K_query)) + {}; + + size_t G1_size() const + { + return 2*(A_query.domain_size() + C_query.domain_size()) + B_query.domain_size() + H_query.size() + K_query.size(); + } + + size_t G2_size() const + { + return B_query.domain_size(); + } + + size_t G1_sparse_size() const + { + return 2*(A_query.size() + C_query.size()) + B_query.size() + H_query.size() + K_query.size(); + } + + size_t G2_sparse_size() const + { + return B_query.size(); + } + + size_t size_in_bits() const + { + return A_query.size_in_bits() + B_query.size_in_bits() + C_query.size_in_bits() + libsnark::size_in_bits(H_query) + libsnark::size_in_bits(K_query); + } + + void print_size() const + { + print_indent(); printf("* G1 elements in PK: %zu\n", this->G1_size()); + print_indent(); printf("* Non-zero G1 elements in PK: %zu\n", this->G1_sparse_size()); + print_indent(); printf("* G2 elements in PK: %zu\n", this->G2_size()); + print_indent(); printf("* Non-zero G2 elements in PK: %zu\n", this->G2_sparse_size()); + print_indent(); printf("* PK size in bits: %zu\n", this->size_in_bits()); + } + + bool operator==(const r1cs_ppzksnark_proving_key &other) const; + friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_proving_key &pk); + friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_proving_key &pk); +}; + + +/******************************* Verification key ****************************/ + +template +class r1cs_ppzksnark_verification_key; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_verification_key &vk); + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_verification_key &vk); + +/** + * A verification key for the R1CS ppzkSNARK. + */ +template +class r1cs_ppzksnark_verification_key { +public: + G2 alphaA_g2; + G1 alphaB_g1; + G2 alphaC_g2; + G2 gamma_g2; + G1 gamma_beta_g1; + G2 gamma_beta_g2; + G2 rC_Z_g2; + + accumulation_vector > encoded_IC_query; + + r1cs_ppzksnark_verification_key() = default; + r1cs_ppzksnark_verification_key(const G2 &alphaA_g2, + const G1 &alphaB_g1, + const G2 &alphaC_g2, + const G2 &gamma_g2, + const G1 &gamma_beta_g1, + const G2 &gamma_beta_g2, + const G2 &rC_Z_g2, + const accumulation_vector > &eIC) : + alphaA_g2(alphaA_g2), + alphaB_g1(alphaB_g1), + alphaC_g2(alphaC_g2), + gamma_g2(gamma_g2), + gamma_beta_g1(gamma_beta_g1), + gamma_beta_g2(gamma_beta_g2), + rC_Z_g2(rC_Z_g2), + encoded_IC_query(eIC) + {}; + + size_t G1_size() const + { + return 2 + encoded_IC_query.size(); + } + + size_t G2_size() const + { + return 5; + } + + size_t size_in_bits() const + { + return (2 * G1::size_in_bits() + encoded_IC_query.size_in_bits() + 5 * G2::size_in_bits()); + } + + void print_size() const + { + print_indent(); printf("* G1 elements in VK: %zu\n", this->G1_size()); + print_indent(); printf("* G2 elements in VK: %zu\n", this->G2_size()); + print_indent(); printf("* VK size in bits: %zu\n", this->size_in_bits()); + } + + bool operator==(const r1cs_ppzksnark_verification_key &other) const; + friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_verification_key &vk); + friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_verification_key &vk); + + static r1cs_ppzksnark_verification_key dummy_verification_key(const size_t input_size); +}; + + +/************************ Processed verification key *************************/ + +template +class r1cs_ppzksnark_processed_verification_key; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk); + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk); + +/** + * A processed verification key for the R1CS ppzkSNARK. + * + * Compared to a (non-processed) verification key, a processed verification key + * contains a small constant amount of additional pre-computed information that + * enables a faster verification time. + */ +template +class r1cs_ppzksnark_processed_verification_key { +public: + G2_precomp pp_G2_one_precomp; + G2_precomp vk_alphaA_g2_precomp; + G1_precomp vk_alphaB_g1_precomp; + G2_precomp vk_alphaC_g2_precomp; + G2_precomp vk_rC_Z_g2_precomp; + G2_precomp vk_gamma_g2_precomp; + G1_precomp vk_gamma_beta_g1_precomp; + G2_precomp vk_gamma_beta_g2_precomp; + + accumulation_vector > encoded_IC_query; + + bool operator==(const r1cs_ppzksnark_processed_verification_key &other) const; + friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk); + friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk); +}; + + +/********************************** Key pair *********************************/ + +/** + * A key pair for the R1CS ppzkSNARK, which consists of a proving key and a verification key. + */ +template +class r1cs_ppzksnark_keypair { +public: + r1cs_ppzksnark_proving_key pk; + r1cs_ppzksnark_verification_key vk; + + r1cs_ppzksnark_keypair() = default; + r1cs_ppzksnark_keypair(const r1cs_ppzksnark_keypair &other) = default; + r1cs_ppzksnark_keypair(r1cs_ppzksnark_proving_key &&pk, + r1cs_ppzksnark_verification_key &&vk) : + pk(std::move(pk)), + vk(std::move(vk)) + {} + + r1cs_ppzksnark_keypair(r1cs_ppzksnark_keypair &&other) = default; +}; + + +/*********************************** Proof ***********************************/ + +template +class r1cs_ppzksnark_proof; + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proof &proof); + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proof &proof); + +/** + * A proof for the R1CS ppzkSNARK. + * + * While the proof has a structure, externally one merely opaquely produces, + * serializes/deserializes, and verifies proofs. We only expose some information + * about the structure for statistics purposes. + */ +template +class r1cs_ppzksnark_proof { +public: + knowledge_commitment, G1 > g_A; + knowledge_commitment, G1 > g_B; + knowledge_commitment, G1 > g_C; + G1 g_H; + G1 g_K; + + r1cs_ppzksnark_proof() + { + // invalid proof with valid curve points + this->g_A.g = G1 ::one(); + this->g_A.h = G1::one(); + this->g_B.g = G2 ::one(); + this->g_B.h = G1::one(); + this->g_C.g = G1 ::one(); + this->g_C.h = G1::one(); + this->g_H = G1::one(); + this->g_K = G1::one(); + } + r1cs_ppzksnark_proof(knowledge_commitment, G1 > &&g_A, + knowledge_commitment, G1 > &&g_B, + knowledge_commitment, G1 > &&g_C, + G1 &&g_H, + G1 &&g_K) : + g_A(std::move(g_A)), + g_B(std::move(g_B)), + g_C(std::move(g_C)), + g_H(std::move(g_H)), + g_K(std::move(g_K)) + {}; + + size_t G1_size() const + { + return 7; + } + + size_t G2_size() const + { + return 1; + } + + size_t size_in_bits() const + { + return G1_size() * G1::size_in_bits() + G2_size() * G2::size_in_bits(); + } + + void print_size() const + { + print_indent(); printf("* G1 elements in proof: %zu\n", this->G1_size()); + print_indent(); printf("* G2 elements in proof: %zu\n", this->G2_size()); + print_indent(); printf("* Proof size in bits: %zu\n", this->size_in_bits()); + } + + bool is_well_formed() const + { + return (g_A.g.is_well_formed() && g_A.h.is_well_formed() && + g_B.g.is_well_formed() && g_B.h.is_well_formed() && + g_C.g.is_well_formed() && g_C.h.is_well_formed() && + g_H.is_well_formed() && + g_K.is_well_formed()); + } + + bool operator==(const r1cs_ppzksnark_proof &other) const; + friend std::ostream& operator<< (std::ostream &out, const r1cs_ppzksnark_proof &proof); + friend std::istream& operator>> (std::istream &in, r1cs_ppzksnark_proof &proof); +}; + + +/***************************** Main algorithms *******************************/ + +/** + * A generator algorithm for the R1CS ppzkSNARK. + * + * Given a R1CS constraint system CS, this algorithm produces proving and verification keys for CS. + */ +template +r1cs_ppzksnark_keypair r1cs_ppzksnark_generator(const r1cs_ppzksnark_constraint_system &cs); + +template +r1cs_ppzksnark_keypair r1cs_ppzksnark_generator( + const r1cs_ppzksnark_constraint_system &cs, + const Fr& t, + const Fr& alphaA, + const Fr& alphaB, + const Fr& alphaC, + const Fr& rA, + const Fr& rB, + const Fr& beta, + const Fr& gamma +); + +/** + * A prover algorithm for the R1CS ppzkSNARK. + * + * Given a R1CS primary input X and a R1CS auxiliary input Y, this algorithm + * produces a proof (of knowledge) that attests to the following statement: + * ``there exists Y such that CS(X,Y)=0''. + * Above, CS is the R1CS constraint system that was given as input to the generator algorithm. + */ +template +r1cs_ppzksnark_proof r1cs_ppzksnark_prover(const r1cs_ppzksnark_proving_key &pk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_auxiliary_input &auxiliary_input, + const r1cs_ppzksnark_constraint_system &constraint_system); + +template +r1cs_ppzksnark_proof r1cs_ppzksnark_prover_streaming(std::ifstream &proving_key_file, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_auxiliary_input &auxiliary_input, + const r1cs_ppzksnark_constraint_system &constraint_system); + +/* + Below are four variants of verifier algorithm for the R1CS ppzkSNARK. + + These are the four cases that arise from the following two choices: + + (1) The verifier accepts a (non-processed) verification key or, instead, a processed verification key. + In the latter case, we call the algorithm an "online verifier". + + (2) The verifier checks for "weak" input consistency or, instead, "strong" input consistency. + Strong input consistency requires that |primary_input| = CS.num_inputs, whereas + weak input consistency requires that |primary_input| <= CS.num_inputs (and + the primary input is implicitly padded with zeros up to length CS.num_inputs). + */ + +/** + * A verifier algorithm for the R1CS ppzkSNARK that: + * (1) accepts a non-processed verification key, and + * (2) has weak input consistency. + */ +template +bool r1cs_ppzksnark_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof); + +/** + * A verifier algorithm for the R1CS ppzkSNARK that: + * (1) accepts a non-processed verification key, and + * (2) has strong input consistency. + */ +template +bool r1cs_ppzksnark_verifier_strong_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof); + +/** + * Convert a (non-processed) verification key into a processed verification key. + */ +template +r1cs_ppzksnark_processed_verification_key r1cs_ppzksnark_verifier_process_vk(const r1cs_ppzksnark_verification_key &vk); + +/** + * A verifier algorithm for the R1CS ppzkSNARK that: + * (1) accepts a processed verification key, and + * (2) has weak input consistency. + */ +template +bool r1cs_ppzksnark_online_verifier_weak_IC(const r1cs_ppzksnark_processed_verification_key &pvk, + const r1cs_ppzksnark_primary_input &input, + const r1cs_ppzksnark_proof &proof); + +/** + * A verifier algorithm for the R1CS ppzkSNARK that: + * (1) accepts a processed verification key, and + * (2) has strong input consistency. + */ +template +bool r1cs_ppzksnark_online_verifier_strong_IC(const r1cs_ppzksnark_processed_verification_key &pvk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof); + +/****************************** Miscellaneous ********************************/ + +/** + * For debugging purposes (of r1cs_ppzksnark_r1cs_ppzksnark_verifier_gadget): + * + * A verifier algorithm for the R1CS ppzkSNARK that: + * (1) accepts a non-processed verification key, + * (2) has weak input consistency, and + * (3) uses affine coordinates for elliptic-curve computations. + */ +template +bool r1cs_ppzksnark_affine_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof); + + +} // libsnark + +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc" + +#endif // R1CS_PPZKSNARK_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc new file mode 100644 index 000000000..9cc392e53 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.tcc @@ -0,0 +1,886 @@ +/** @file +***************************************************************************** + +Implementation of interfaces for a ppzkSNARK for R1CS. + +See r1cs_ppzksnark.hpp . + +***************************************************************************** +* @author This file is part of libsnark, developed by SCIPR Lab +* and contributors (see AUTHORS). +* @copyright MIT license (see LICENSE file) +*****************************************************************************/ + +#ifndef R1CS_PPZKSNARK_TCC_ +#define R1CS_PPZKSNARK_TCC_ + +#include +#include +#include +#include +#include + +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "algebra/scalar_multiplication/multiexp.hpp" +#include "algebra/scalar_multiplication/kc_multiexp.hpp" +#include "reductions/r1cs_to_qap/r1cs_to_qap.hpp" + +namespace libsnark { + +template +bool r1cs_ppzksnark_proving_key::operator==(const r1cs_ppzksnark_proving_key &other) const +{ + return (this->A_query == other.A_query && + this->B_query == other.B_query && + this->C_query == other.C_query && + this->H_query == other.H_query && + this->K_query == other.K_query); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proving_key &pk) +{ + out << pk.A_query; + out << pk.B_query; + out << pk.C_query; + out << pk.H_query; + out << pk.K_query; + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proving_key &pk) +{ + in >> pk.A_query; + in >> pk.B_query; + in >> pk.C_query; + in >> pk.H_query; + in >> pk.K_query; + + return in; +} + +template +bool r1cs_ppzksnark_verification_key::operator==(const r1cs_ppzksnark_verification_key &other) const +{ + return (this->alphaA_g2 == other.alphaA_g2 && + this->alphaB_g1 == other.alphaB_g1 && + this->alphaC_g2 == other.alphaC_g2 && + this->gamma_g2 == other.gamma_g2 && + this->gamma_beta_g1 == other.gamma_beta_g1 && + this->gamma_beta_g2 == other.gamma_beta_g2 && + this->rC_Z_g2 == other.rC_Z_g2 && + this->encoded_IC_query == other.encoded_IC_query); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_verification_key &vk) +{ + out << vk.alphaA_g2 << OUTPUT_NEWLINE; + out << vk.alphaB_g1 << OUTPUT_NEWLINE; + out << vk.alphaC_g2 << OUTPUT_NEWLINE; + out << vk.gamma_g2 << OUTPUT_NEWLINE; + out << vk.gamma_beta_g1 << OUTPUT_NEWLINE; + out << vk.gamma_beta_g2 << OUTPUT_NEWLINE; + out << vk.rC_Z_g2 << OUTPUT_NEWLINE; + out << vk.encoded_IC_query << OUTPUT_NEWLINE; + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_verification_key &vk) +{ + in >> vk.alphaA_g2; + consume_OUTPUT_NEWLINE(in); + in >> vk.alphaB_g1; + consume_OUTPUT_NEWLINE(in); + in >> vk.alphaC_g2; + consume_OUTPUT_NEWLINE(in); + in >> vk.gamma_g2; + consume_OUTPUT_NEWLINE(in); + in >> vk.gamma_beta_g1; + consume_OUTPUT_NEWLINE(in); + in >> vk.gamma_beta_g2; + consume_OUTPUT_NEWLINE(in); + in >> vk.rC_Z_g2; + consume_OUTPUT_NEWLINE(in); + in >> vk.encoded_IC_query; + consume_OUTPUT_NEWLINE(in); + + return in; +} + +template +bool r1cs_ppzksnark_processed_verification_key::operator==(const r1cs_ppzksnark_processed_verification_key &other) const +{ + return (this->pp_G2_one_precomp == other.pp_G2_one_precomp && + this->vk_alphaA_g2_precomp == other.vk_alphaA_g2_precomp && + this->vk_alphaB_g1_precomp == other.vk_alphaB_g1_precomp && + this->vk_alphaC_g2_precomp == other.vk_alphaC_g2_precomp && + this->vk_rC_Z_g2_precomp == other.vk_rC_Z_g2_precomp && + this->vk_gamma_g2_precomp == other.vk_gamma_g2_precomp && + this->vk_gamma_beta_g1_precomp == other.vk_gamma_beta_g1_precomp && + this->vk_gamma_beta_g2_precomp == other.vk_gamma_beta_g2_precomp && + this->encoded_IC_query == other.encoded_IC_query); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_processed_verification_key &pvk) +{ + out << pvk.pp_G2_one_precomp << OUTPUT_NEWLINE; + out << pvk.vk_alphaA_g2_precomp << OUTPUT_NEWLINE; + out << pvk.vk_alphaB_g1_precomp << OUTPUT_NEWLINE; + out << pvk.vk_alphaC_g2_precomp << OUTPUT_NEWLINE; + out << pvk.vk_rC_Z_g2_precomp << OUTPUT_NEWLINE; + out << pvk.vk_gamma_g2_precomp << OUTPUT_NEWLINE; + out << pvk.vk_gamma_beta_g1_precomp << OUTPUT_NEWLINE; + out << pvk.vk_gamma_beta_g2_precomp << OUTPUT_NEWLINE; + out << pvk.encoded_IC_query << OUTPUT_NEWLINE; + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_processed_verification_key &pvk) +{ + in >> pvk.pp_G2_one_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_alphaA_g2_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_alphaB_g1_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_alphaC_g2_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_rC_Z_g2_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_gamma_g2_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_gamma_beta_g1_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.vk_gamma_beta_g2_precomp; + consume_OUTPUT_NEWLINE(in); + in >> pvk.encoded_IC_query; + consume_OUTPUT_NEWLINE(in); + + return in; +} + +template +bool r1cs_ppzksnark_proof::operator==(const r1cs_ppzksnark_proof &other) const +{ + return (this->g_A == other.g_A && + this->g_B == other.g_B && + this->g_C == other.g_C && + this->g_H == other.g_H && + this->g_K == other.g_K); +} + +template +std::ostream& operator<<(std::ostream &out, const r1cs_ppzksnark_proof &proof) +{ + out << proof.g_A << OUTPUT_NEWLINE; + out << proof.g_B << OUTPUT_NEWLINE; + out << proof.g_C << OUTPUT_NEWLINE; + out << proof.g_H << OUTPUT_NEWLINE; + out << proof.g_K << OUTPUT_NEWLINE; + + return out; +} + +template +std::istream& operator>>(std::istream &in, r1cs_ppzksnark_proof &proof) +{ + in >> proof.g_A; + consume_OUTPUT_NEWLINE(in); + in >> proof.g_B; + consume_OUTPUT_NEWLINE(in); + in >> proof.g_C; + consume_OUTPUT_NEWLINE(in); + in >> proof.g_H; + consume_OUTPUT_NEWLINE(in); + in >> proof.g_K; + consume_OUTPUT_NEWLINE(in); + + return in; +} + +template +r1cs_ppzksnark_verification_key r1cs_ppzksnark_verification_key::dummy_verification_key(const size_t input_size) +{ + r1cs_ppzksnark_verification_key result; + result.alphaA_g2 = Fr::random_element() * G2::one(); + result.alphaB_g1 = Fr::random_element() * G1::one(); + result.alphaC_g2 = Fr::random_element() * G2::one(); + result.gamma_g2 = Fr::random_element() * G2::one(); + result.gamma_beta_g1 = Fr::random_element() * G1::one(); + result.gamma_beta_g2 = Fr::random_element() * G2::one(); + result.rC_Z_g2 = Fr::random_element() * G2::one(); + + G1 base = Fr::random_element() * G1::one(); + G1_vector v; + for (size_t i = 0; i < input_size; ++i) + { + v.emplace_back(Fr::random_element() * G1::one()); + } + + result.encoded_IC_query = accumulation_vector >(std::move(base), std::move(v)); + + return result; +} + +template +r1cs_ppzksnark_keypair r1cs_ppzksnark_generator(const r1cs_ppzksnark_constraint_system &cs) +{ + /* draw random element at which the QAP is evaluated */ + const Fr t = Fr::random_element(); + + const Fr alphaA = Fr::random_element(), + alphaB = Fr::random_element(), + alphaC = Fr::random_element(), + rA = Fr::random_element(), + rB = Fr::random_element(), + beta = Fr::random_element(), + gamma = Fr::random_element(); + + return r1cs_ppzksnark_generator(cs, t, alphaA, alphaB, alphaC, rA, rB, beta, gamma); +} + +template +r1cs_ppzksnark_keypair r1cs_ppzksnark_generator( + const r1cs_ppzksnark_constraint_system &cs, + const Fr& t, + const Fr& alphaA, + const Fr& alphaB, + const Fr& alphaC, + const Fr& rA, + const Fr& rB, + const Fr& beta, + const Fr& gamma +) +{ + enter_block("Call to r1cs_ppzksnark_generator"); + + /* make the B_query "lighter" if possible */ + r1cs_ppzksnark_constraint_system cs_copy(cs); + cs_copy.swap_AB_if_beneficial(); + + qap_instance_evaluation > qap_inst = r1cs_to_qap_instance_map_with_evaluation(cs_copy, t); + + print_indent(); printf("* QAP number of variables: %zu\n", qap_inst.num_variables()); + print_indent(); printf("* QAP pre degree: %zu\n", cs_copy.constraints.size()); + print_indent(); printf("* QAP degree: %zu\n", qap_inst.degree()); + print_indent(); printf("* QAP number of input variables: %zu\n", qap_inst.num_inputs()); + + enter_block("Compute query densities"); + size_t non_zero_At = 0, non_zero_Bt = 0, non_zero_Ct = 0, non_zero_Ht = 0; + for (size_t i = 0; i < qap_inst.num_variables()+1; ++i) + { + if (!qap_inst.At[i].is_zero()) + { + ++non_zero_At; + } + if (!qap_inst.Bt[i].is_zero()) + { + ++non_zero_Bt; + } + if (!qap_inst.Ct[i].is_zero()) + { + ++non_zero_Ct; + } + } + for (size_t i = 0; i < qap_inst.degree()+1; ++i) + { + if (!qap_inst.Ht[i].is_zero()) + { + ++non_zero_Ht; + } + } + leave_block("Compute query densities"); + + Fr_vector At = std::move(qap_inst.At); // qap_inst.At is now in unspecified state, but we do not use it later + Fr_vector Bt = std::move(qap_inst.Bt); // qap_inst.Bt is now in unspecified state, but we do not use it later + Fr_vector Ct = std::move(qap_inst.Ct); // qap_inst.Ct is now in unspecified state, but we do not use it later + Fr_vector Ht = std::move(qap_inst.Ht); // qap_inst.Ht is now in unspecified state, but we do not use it later + + /* append Zt to At,Bt,Ct with */ + At.emplace_back(qap_inst.Zt); + Bt.emplace_back(qap_inst.Zt); + Ct.emplace_back(qap_inst.Zt); + + const Fr rC = rA * rB; + + // construct the same-coefficient-check query (must happen before zeroing out the prefix of At) + Fr_vector Kt; + Kt.reserve(qap_inst.num_variables()+4); + for (size_t i = 0; i < qap_inst.num_variables()+1; ++i) + { + Kt.emplace_back( beta * (rA * At[i] + rB * Bt[i] + rC * Ct[i] ) ); + } + Kt.emplace_back(beta * rA * qap_inst.Zt); + Kt.emplace_back(beta * rB * qap_inst.Zt); + Kt.emplace_back(beta * rC * qap_inst.Zt); + + /* zero out prefix of At and stick it into IC coefficients */ + Fr_vector IC_coefficients; + IC_coefficients.reserve(qap_inst.num_inputs() + 1); + for (size_t i = 0; i < qap_inst.num_inputs() + 1; ++i) + { + IC_coefficients.emplace_back(At[i]); + assert(!IC_coefficients[i].is_zero()); + At[i] = Fr::zero(); + } + + const size_t g1_exp_count = 2*(non_zero_At - qap_inst.num_inputs() + non_zero_Ct) + non_zero_Bt + non_zero_Ht + Kt.size(); + const size_t g2_exp_count = non_zero_Bt; + + size_t g1_window = get_exp_window_size >(g1_exp_count); + size_t g2_window = get_exp_window_size >(g2_exp_count); + print_indent(); printf("* G1 window: %zu\n", g1_window); + print_indent(); printf("* G2 window: %zu\n", g2_window); + +#ifdef MULTICORE + const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() +#else + const size_t chunks = 1; +#endif + + enter_block("Generating G1 multiexp table"); + window_table > g1_table = get_window_table(Fr::size_in_bits(), g1_window, G1::one()); + leave_block("Generating G1 multiexp table"); + + enter_block("Generating G2 multiexp table"); + window_table > g2_table = get_window_table(Fr::size_in_bits(), g2_window, G2::one()); + leave_block("Generating G2 multiexp table"); + + enter_block("Generate R1CS proving key"); + + enter_block("Generate knowledge commitments"); + enter_block("Compute the A-query", false); + knowledge_commitment_vector, G1 > A_query = kc_batch_exp(Fr::size_in_bits(), g1_window, g1_window, g1_table, g1_table, rA, rA*alphaA, At, chunks); + leave_block("Compute the A-query", false); + + enter_block("Compute the B-query", false); + knowledge_commitment_vector, G1 > B_query = kc_batch_exp(Fr::size_in_bits(), g2_window, g1_window, g2_table, g1_table, rB, rB*alphaB, Bt, chunks); + leave_block("Compute the B-query", false); + + enter_block("Compute the C-query", false); + knowledge_commitment_vector, G1 > C_query = kc_batch_exp(Fr::size_in_bits(), g1_window, g1_window, g1_table, g1_table, rC, rC*alphaC, Ct, chunks); + leave_block("Compute the C-query", false); + + enter_block("Compute the H-query", false); + G1_vector H_query = batch_exp(Fr::size_in_bits(), g1_window, g1_table, Ht); + leave_block("Compute the H-query", false); + + enter_block("Compute the K-query", false); + G1_vector K_query = batch_exp(Fr::size_in_bits(), g1_window, g1_table, Kt); +#ifdef USE_MIXED_ADDITION + batch_to_special >(K_query); +#endif + leave_block("Compute the K-query", false); + + leave_block("Generate knowledge commitments"); + + leave_block("Generate R1CS proving key"); + + enter_block("Generate R1CS verification key"); + G2 alphaA_g2 = alphaA * G2::one(); + G1 alphaB_g1 = alphaB * G1::one(); + G2 alphaC_g2 = alphaC * G2::one(); + G2 gamma_g2 = gamma * G2::one(); + G1 gamma_beta_g1 = (gamma * beta) * G1::one(); + G2 gamma_beta_g2 = (gamma * beta) * G2::one(); + G2 rC_Z_g2 = (rC * qap_inst.Zt) * G2::one(); + + enter_block("Encode IC query for R1CS verification key"); + G1 encoded_IC_base = (rA * IC_coefficients[0]) * G1::one(); + Fr_vector multiplied_IC_coefficients; + multiplied_IC_coefficients.reserve(qap_inst.num_inputs()); + for (size_t i = 1; i < qap_inst.num_inputs() + 1; ++i) + { + multiplied_IC_coefficients.emplace_back(rA * IC_coefficients[i]); + } + G1_vector encoded_IC_values = batch_exp(Fr::size_in_bits(), g1_window, g1_table, multiplied_IC_coefficients); + + leave_block("Encode IC query for R1CS verification key"); + leave_block("Generate R1CS verification key"); + + leave_block("Call to r1cs_ppzksnark_generator"); + + accumulation_vector > encoded_IC_query(std::move(encoded_IC_base), std::move(encoded_IC_values)); + + r1cs_ppzksnark_verification_key vk = r1cs_ppzksnark_verification_key(alphaA_g2, + alphaB_g1, + alphaC_g2, + gamma_g2, + gamma_beta_g1, + gamma_beta_g2, + rC_Z_g2, + encoded_IC_query); + r1cs_ppzksnark_proving_key pk = r1cs_ppzksnark_proving_key(std::move(A_query), + std::move(B_query), + std::move(C_query), + std::move(H_query), + std::move(K_query)); + + pk.print_size(); + vk.print_size(); + + return r1cs_ppzksnark_keypair(std::move(pk), std::move(vk)); +} + +template +knowledge_commitment r1cs_compute_proof_kc(const qap_witness > &qap_wit, + const knowledge_commitment_vector &kcv, + const Fr &zk_shift) +{ + knowledge_commitment returnval = kcv[0] + (zk_shift * kcv[qap_wit.num_variables()+1]); + +#ifdef DEBUG + assert(kcv.domain_size() == qap_wit.num_variables()+2); +#endif + +#ifdef MULTICORE + const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() +#else + const size_t chunks = 1; +#endif + + returnval = returnval + kc_multi_exp_with_mixed_addition >( + kcv, + 1, + 1 + qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks, + true + ); + + return returnval; +} + + + +template +G1 r1cs_compute_proof_K(const qap_witness> &qap_wit, const G1_vector &K_query, const G1 &zk_shift) +{ +#ifdef DEBUG + assert(K_query.size() == qap_wit.num_variables()+4); +#endif + +#ifdef MULTICORE + const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() +#else + const size_t chunks = 1; +#endif + + G1 g_K = K_query[0] + zk_shift; + g_K = g_K + multi_exp_with_mixed_addition, Fr >( + K_query.begin()+1, + K_query.begin()+1+qap_wit.num_variables(), + qap_wit.coefficients_for_ABCs.begin(), + qap_wit.coefficients_for_ABCs.begin()+qap_wit.num_variables(), + chunks, + true + ); + + return g_K; +} + + +template +G1 r1cs_compute_proof_H(const qap_witness > &qap_wit, const G1_vector &H_query) +{ + G1 g_H = G1::zero(); + +#ifdef DEBUG + assert(H_query.size() == qap_wit.degree()+1); +#endif + +#ifdef MULTICORE + const size_t chunks = omp_get_max_threads(); // to override, set OMP_NUM_THREADS env var or call omp_set_num_threads() +#else + const size_t chunks = 1; +#endif + + g_H = g_H + multi_exp, Fr >( + H_query.begin(), + H_query.begin()+qap_wit.degree()+1, + qap_wit.coefficients_for_H.begin(), + qap_wit.coefficients_for_H.begin()+qap_wit.degree()+1, + chunks, + true + ); + + return g_H; +} + +template +r1cs_ppzksnark_proof r1cs_ppzksnark_prover(const r1cs_ppzksnark_proving_key &pk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_auxiliary_input &auxiliary_input, + const r1cs_ppzksnark_constraint_system &constraint_system) +{ + enter_block("Call to r1cs_ppzksnark_prover"); + +#ifdef DEBUG + assert(constraint_system.is_satisfied(primary_input, auxiliary_input)); +#endif + + const Fr d1 = Fr::random_element(), + d2 = Fr::random_element(), + d3 = Fr::random_element(); + + enter_block("Compute the polynomial H"); + const qap_witness > qap_wit = r1cs_to_qap_witness_map(constraint_system, primary_input, auxiliary_input, d1, d2, d3); + leave_block("Compute the polynomial H"); + +#ifdef DEBUG + const Fr t = Fr::random_element(); + qap_instance_evaluation > qap_inst = r1cs_to_qap_instance_map_with_evaluation(constraint_system, t); + assert(qap_inst.is_satisfied(qap_wit)); +#endif + +#ifdef DEBUG + for (size_t i = 0; i < qap_wit.num_inputs() + 1; ++i) + { + assert(pk.A_query[i].g == G1::zero()); + } +#endif + + enter_block("Compute the proof"); + + enter_block("Compute answer to A-query", false); + auto g_A = r1cs_compute_proof_kc, G1 >(qap_wit, pk.A_query, qap_wit.d1); + leave_block("Compute answer to A-query", false); + + enter_block("Compute answer to B-query", false); + auto g_B = r1cs_compute_proof_kc, G1 >(qap_wit, pk.B_query, qap_wit.d2); + leave_block("Compute answer to B-query", false); + + enter_block("Compute answer to C-query", false); + auto g_C = r1cs_compute_proof_kc, G1 >(qap_wit, pk.C_query, qap_wit.d3); + leave_block("Compute answer to C-query", false); + + enter_block("Compute answer to H-query", false); + auto g_H = r1cs_compute_proof_H(qap_wit, pk.H_query); + leave_block("Compute answer to H-query", false); + + enter_block("Compute answer to K-query", false); + G1 zk_shift = qap_wit.d1*pk.K_query[qap_wit.num_variables()+1] + + qap_wit.d2*pk.K_query[qap_wit.num_variables()+2] + + qap_wit.d3*pk.K_query[qap_wit.num_variables()+3]; + G1 g_K = r1cs_compute_proof_K(qap_wit, pk.K_query, zk_shift); + leave_block("Compute answer to K-query", false); + + leave_block("Compute the proof"); + + leave_block("Call to r1cs_ppzksnark_prover"); + + r1cs_ppzksnark_proof proof = r1cs_ppzksnark_proof(std::move(g_A), std::move(g_B), std::move(g_C), std::move(g_H), std::move(g_K)); + + return proof; +} + +template +r1cs_ppzksnark_proof r1cs_ppzksnark_prover_streaming(std::ifstream &proving_key_file, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_auxiliary_input &auxiliary_input, + const r1cs_ppzksnark_constraint_system &constraint_system) +{ + enter_block("Call to r1cs_ppzksnark_prover_streaming"); + + const Fr d1 = Fr::random_element(), + d2 = Fr::random_element(), + d3 = Fr::random_element(); + + enter_block("Compute the polynomial H"); + const qap_witness > qap_wit = r1cs_to_qap_witness_map(constraint_system, primary_input, auxiliary_input, d1, d2, d3); + leave_block("Compute the polynomial H"); + + enter_block("Compute the proof"); + + r1cs_ppzksnark_proof proof; + + enter_block("Compute answer to A-query", false); + { + knowledge_commitment_vector, G1 > A_query; + proving_key_file >> A_query; + proof.g_A = r1cs_compute_proof_kc, G1 >(qap_wit, A_query, qap_wit.d1); + } + leave_block("Compute answer to A-query", false); + + enter_block("Compute answer to B-query", false); + { + knowledge_commitment_vector, G1 > B_query; + proving_key_file >> B_query; + proof.g_B = r1cs_compute_proof_kc, G1 >(qap_wit, B_query, qap_wit.d2); + } + leave_block("Compute answer to B-query", false); + + enter_block("Compute answer to C-query", false); + { + knowledge_commitment_vector, G1 > C_query; + proving_key_file >> C_query; + proof.g_C = r1cs_compute_proof_kc, G1 >(qap_wit, C_query, qap_wit.d3); + } + leave_block("Compute answer to C-query", false); + + enter_block("Compute answer to H-query", false); + { + G1_vector H_query; + proving_key_file >> H_query; + proof.g_H = r1cs_compute_proof_H(qap_wit, H_query); + } + leave_block("Compute answer to H-query", false); + + enter_block("Compute answer to K-query", false); + { + G1_vector K_query; + proving_key_file >> K_query; + G1 zk_shift = qap_wit.d1*K_query[qap_wit.num_variables()+1] + + qap_wit.d2*K_query[qap_wit.num_variables()+2] + + qap_wit.d3*K_query[qap_wit.num_variables()+3]; + proof.g_K = r1cs_compute_proof_K(qap_wit, K_query, zk_shift); + } + leave_block("Compute answer to K-query", false); + + leave_block("Compute the proof"); + + leave_block("Call to r1cs_ppzksnark_prover_streaming"); + + return proof; +} + +template +r1cs_ppzksnark_processed_verification_key r1cs_ppzksnark_verifier_process_vk(const r1cs_ppzksnark_verification_key &vk) +{ + enter_block("Call to r1cs_ppzksnark_verifier_process_vk"); + + r1cs_ppzksnark_processed_verification_key pvk; + pvk.pp_G2_one_precomp = ppT::precompute_G2(G2::one()); + pvk.vk_alphaA_g2_precomp = ppT::precompute_G2(vk.alphaA_g2); + pvk.vk_alphaB_g1_precomp = ppT::precompute_G1(vk.alphaB_g1); + pvk.vk_alphaC_g2_precomp = ppT::precompute_G2(vk.alphaC_g2); + pvk.vk_rC_Z_g2_precomp = ppT::precompute_G2(vk.rC_Z_g2); + pvk.vk_gamma_g2_precomp = ppT::precompute_G2(vk.gamma_g2); + pvk.vk_gamma_beta_g1_precomp = ppT::precompute_G1(vk.gamma_beta_g1); + pvk.vk_gamma_beta_g2_precomp = ppT::precompute_G2(vk.gamma_beta_g2); + + pvk.encoded_IC_query = vk.encoded_IC_query; + + leave_block("Call to r1cs_ppzksnark_verifier_process_vk"); + + return pvk; +} + +template +bool r1cs_ppzksnark_online_verifier_weak_IC(const r1cs_ppzksnark_processed_verification_key &pvk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof) +{ + assert(pvk.encoded_IC_query.domain_size() >= primary_input.size()); + + const accumulation_vector > accumulated_IC = pvk.encoded_IC_query.template accumulate_chunk >(primary_input.begin(), primary_input.end(), 0); + const G1 &acc = accumulated_IC.first; + + if (!proof.is_well_formed()) + { + return false; + } + + G1_precomp proof_g_A_g_precomp = ppT::precompute_G1(proof.g_A.g); + G1_precomp proof_g_A_h_precomp = ppT::precompute_G1(proof.g_A.h); + Fqk kc_A_1 = ppT::miller_loop(proof_g_A_g_precomp, pvk.vk_alphaA_g2_precomp); + Fqk kc_A_2 = ppT::miller_loop(proof_g_A_h_precomp, pvk.pp_G2_one_precomp); + GT kc_A = ppT::final_exponentiation(kc_A_1 * kc_A_2.unitary_inverse()); + if (kc_A != GT::one()) + { + return false; + } + + G2_precomp proof_g_B_g_precomp = ppT::precompute_G2(proof.g_B.g); + G1_precomp proof_g_B_h_precomp = ppT::precompute_G1(proof.g_B.h); + Fqk kc_B_1 = ppT::miller_loop(pvk.vk_alphaB_g1_precomp, proof_g_B_g_precomp); + Fqk kc_B_2 = ppT::miller_loop(proof_g_B_h_precomp, pvk.pp_G2_one_precomp); + GT kc_B = ppT::final_exponentiation(kc_B_1 * kc_B_2.unitary_inverse()); + if (kc_B != GT::one()) + { + return false; + } + + G1_precomp proof_g_C_g_precomp = ppT::precompute_G1(proof.g_C.g); + G1_precomp proof_g_C_h_precomp = ppT::precompute_G1(proof.g_C.h); + Fqk kc_C_1 = ppT::miller_loop(proof_g_C_g_precomp, pvk.vk_alphaC_g2_precomp); + Fqk kc_C_2 = ppT::miller_loop(proof_g_C_h_precomp, pvk.pp_G2_one_precomp); + GT kc_C = ppT::final_exponentiation(kc_C_1 * kc_C_2.unitary_inverse()); + if (kc_C != GT::one()) + { + return false; + } + + // check that g^((A+acc)*B)=g^(H*\Prod(t-\sigma)+C) + // equivalently, via pairings, that e(g^(A+acc), g^B) = e(g^H, g^Z) + e(g^C, g^1) + G1_precomp proof_g_A_g_acc_precomp = ppT::precompute_G1(proof.g_A.g + acc); + G1_precomp proof_g_H_precomp = ppT::precompute_G1(proof.g_H); + Fqk QAP_1 = ppT::miller_loop(proof_g_A_g_acc_precomp, proof_g_B_g_precomp); + Fqk QAP_23 = ppT::double_miller_loop(proof_g_H_precomp, pvk.vk_rC_Z_g2_precomp, proof_g_C_g_precomp, pvk.pp_G2_one_precomp); + GT QAP = ppT::final_exponentiation(QAP_1 * QAP_23.unitary_inverse()); + if (QAP != GT::one()) + { + return false; + } + + G1_precomp proof_g_K_precomp = ppT::precompute_G1(proof.g_K); + G1_precomp proof_g_A_g_acc_C_precomp = ppT::precompute_G1((proof.g_A.g + acc) + proof.g_C.g); + Fqk K_1 = ppT::miller_loop(proof_g_K_precomp, pvk.vk_gamma_g2_precomp); + Fqk K_23 = ppT::double_miller_loop(proof_g_A_g_acc_C_precomp, pvk.vk_gamma_beta_g2_precomp, pvk.vk_gamma_beta_g1_precomp, proof_g_B_g_precomp); + GT K = ppT::final_exponentiation(K_1 * K_23.unitary_inverse()); + if (K != GT::one()) + { + return false; + } + + return true; +} + +template +bool r1cs_ppzksnark_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof) +{ + enter_block("Call to r1cs_ppzksnark_verifier_weak_IC"); + r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(vk); + bool result = r1cs_ppzksnark_online_verifier_weak_IC(pvk, primary_input, proof); + leave_block("Call to r1cs_ppzksnark_verifier_weak_IC"); + return result; +} + +template +bool r1cs_ppzksnark_online_verifier_strong_IC(const r1cs_ppzksnark_processed_verification_key &pvk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof) +{ + bool result = true; + enter_block("Call to r1cs_ppzksnark_online_verifier_strong_IC"); + + if (pvk.encoded_IC_query.domain_size() != primary_input.size()) + { + print_indent(); printf("Input length differs from expected (got %zu, expected %zu).\n", primary_input.size(), pvk.encoded_IC_query.domain_size()); + result = false; + } + else + { + result = r1cs_ppzksnark_online_verifier_weak_IC(pvk, primary_input, proof); + } + + leave_block("Call to r1cs_ppzksnark_online_verifier_strong_IC"); + return result; +} + +template +bool r1cs_ppzksnark_verifier_strong_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof) +{ + enter_block("Call to r1cs_ppzksnark_verifier_strong_IC"); + r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(vk); + bool result = r1cs_ppzksnark_online_verifier_strong_IC(pvk, primary_input, proof); + leave_block("Call to r1cs_ppzksnark_verifier_strong_IC"); + return result; +} + +template +bool r1cs_ppzksnark_affine_verifier_weak_IC(const r1cs_ppzksnark_verification_key &vk, + const r1cs_ppzksnark_primary_input &primary_input, + const r1cs_ppzksnark_proof &proof) +{ + enter_block("Call to r1cs_ppzksnark_affine_verifier_weak_IC"); + assert(vk.encoded_IC_query.domain_size() >= primary_input.size()); + + affine_ate_G2_precomp pvk_pp_G2_one_precomp = ppT::affine_ate_precompute_G2(G2::one()); + affine_ate_G2_precomp pvk_vk_alphaA_g2_precomp = ppT::affine_ate_precompute_G2(vk.alphaA_g2); + affine_ate_G1_precomp pvk_vk_alphaB_g1_precomp = ppT::affine_ate_precompute_G1(vk.alphaB_g1); + affine_ate_G2_precomp pvk_vk_alphaC_g2_precomp = ppT::affine_ate_precompute_G2(vk.alphaC_g2); + affine_ate_G2_precomp pvk_vk_rC_Z_g2_precomp = ppT::affine_ate_precompute_G2(vk.rC_Z_g2); + affine_ate_G2_precomp pvk_vk_gamma_g2_precomp = ppT::affine_ate_precompute_G2(vk.gamma_g2); + affine_ate_G1_precomp pvk_vk_gamma_beta_g1_precomp = ppT::affine_ate_precompute_G1(vk.gamma_beta_g1); + affine_ate_G2_precomp pvk_vk_gamma_beta_g2_precomp = ppT::affine_ate_precompute_G2(vk.gamma_beta_g2); + + enter_block("Compute input-dependent part of A"); + const accumulation_vector > accumulated_IC = vk.encoded_IC_query.template accumulate_chunk >(primary_input.begin(), primary_input.end(), 0); + assert(accumulated_IC.is_fully_accumulated()); + const G1 &acc = accumulated_IC.first; + leave_block("Compute input-dependent part of A"); + + bool result = true; + enter_block("Check knowledge commitment for A is valid"); + affine_ate_G1_precomp proof_g_A_g_precomp = ppT::affine_ate_precompute_G1(proof.g_A.g); + affine_ate_G1_precomp proof_g_A_h_precomp = ppT::affine_ate_precompute_G1(proof.g_A.h); + Fqk kc_A_miller = ppT::affine_ate_e_over_e_miller_loop(proof_g_A_g_precomp, pvk_vk_alphaA_g2_precomp, proof_g_A_h_precomp, pvk_pp_G2_one_precomp); + GT kc_A = ppT::final_exponentiation(kc_A_miller); + + if (kc_A != GT::one()) + { + print_indent(); printf("Knowledge commitment for A query incorrect.\n"); + result = false; + } + leave_block("Check knowledge commitment for A is valid"); + + enter_block("Check knowledge commitment for B is valid"); + affine_ate_G2_precomp proof_g_B_g_precomp = ppT::affine_ate_precompute_G2(proof.g_B.g); + affine_ate_G1_precomp proof_g_B_h_precomp = ppT::affine_ate_precompute_G1(proof.g_B.h); + Fqk kc_B_miller = ppT::affine_ate_e_over_e_miller_loop(pvk_vk_alphaB_g1_precomp, proof_g_B_g_precomp, proof_g_B_h_precomp, pvk_pp_G2_one_precomp); + GT kc_B = ppT::final_exponentiation(kc_B_miller); + if (kc_B != GT::one()) + { + print_indent(); printf("Knowledge commitment for B query incorrect.\n"); + result = false; + } + leave_block("Check knowledge commitment for B is valid"); + + enter_block("Check knowledge commitment for C is valid"); + affine_ate_G1_precomp proof_g_C_g_precomp = ppT::affine_ate_precompute_G1(proof.g_C.g); + affine_ate_G1_precomp proof_g_C_h_precomp = ppT::affine_ate_precompute_G1(proof.g_C.h); + Fqk kc_C_miller = ppT::affine_ate_e_over_e_miller_loop(proof_g_C_g_precomp, pvk_vk_alphaC_g2_precomp, proof_g_C_h_precomp, pvk_pp_G2_one_precomp); + GT kc_C = ppT::final_exponentiation(kc_C_miller); + if (kc_C != GT::one()) + { + print_indent(); printf("Knowledge commitment for C query incorrect.\n"); + result = false; + } + leave_block("Check knowledge commitment for C is valid"); + + enter_block("Check QAP divisibility"); + affine_ate_G1_precomp proof_g_A_g_acc_precomp = ppT::affine_ate_precompute_G1(proof.g_A.g + acc); + affine_ate_G1_precomp proof_g_H_precomp = ppT::affine_ate_precompute_G1(proof.g_H); + Fqk QAP_miller = ppT::affine_ate_e_times_e_over_e_miller_loop(proof_g_H_precomp, pvk_vk_rC_Z_g2_precomp, proof_g_C_g_precomp, pvk_pp_G2_one_precomp, proof_g_A_g_acc_precomp, proof_g_B_g_precomp); + GT QAP = ppT::final_exponentiation(QAP_miller); + if (QAP != GT::one()) + { + print_indent(); printf("QAP divisibility check failed.\n"); + result = false; + } + leave_block("Check QAP divisibility"); + + enter_block("Check same coefficients were used"); + affine_ate_G1_precomp proof_g_K_precomp = ppT::affine_ate_precompute_G1(proof.g_K); + affine_ate_G1_precomp proof_g_A_g_acc_C_precomp = ppT::affine_ate_precompute_G1((proof.g_A.g + acc) + proof.g_C.g); + Fqk K_miller = ppT::affine_ate_e_times_e_over_e_miller_loop(proof_g_A_g_acc_C_precomp, pvk_vk_gamma_beta_g2_precomp, pvk_vk_gamma_beta_g1_precomp, proof_g_B_g_precomp, proof_g_K_precomp, pvk_vk_gamma_g2_precomp); + GT K = ppT::final_exponentiation(K_miller); + if (K != GT::one()) + { + print_indent(); printf("Same-coefficient check failed.\n"); + result = false; + } + leave_block("Check same coefficients were used"); + + leave_block("Call to r1cs_ppzksnark_affine_verifier_weak_IC"); + + return result; +} + +} // libsnark +#endif // R1CS_PPZKSNARK_TCC_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp new file mode 100644 index 000000000..4054b8e3b --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark_params.hpp @@ -0,0 +1,34 @@ +/** @file + ***************************************************************************** + + Declaration of public-parameter selector for the R1CS ppzkSNARK. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ + +#ifndef R1CS_PPZKSNARK_PARAMS_HPP_ +#define R1CS_PPZKSNARK_PARAMS_HPP_ + +#include "relations/constraint_satisfaction_problems/r1cs/r1cs.hpp" + +namespace libsnark { + +/** + * Below are various template aliases (used for convenience). + */ + +template +using r1cs_ppzksnark_constraint_system = r1cs_constraint_system >; + +template +using r1cs_ppzksnark_primary_input = r1cs_primary_input >; + +template +using r1cs_ppzksnark_auxiliary_input = r1cs_auxiliary_input >; + +} // libsnark + +#endif // R1CS_PPZKSNARK_PARAMS_HPP_ diff --git a/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp new file mode 100644 index 000000000..6c6e51857 --- /dev/null +++ b/src/snark/libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/tests/test_r1cs_ppzksnark.cpp @@ -0,0 +1,44 @@ +/** @file + ***************************************************************************** + Test program that exercises the ppzkSNARK (first generator, then + prover, then verifier) on a synthetic R1CS instance. + + ***************************************************************************** + * @author This file is part of libsnark, developed by SCIPR Lab + * and contributors (see AUTHORS). + * @copyright MIT license (see LICENSE file) + *****************************************************************************/ +#include +#include + +#include "algebra/curves/alt_bn128/alt_bn128_pp.hpp" +#include "common/profiling.hpp" +#include "common/utils.hpp" +#include "relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.hpp" +#include "zk_proof_systems/ppzksnark/r1cs_ppzksnark/examples/run_r1cs_ppzksnark.hpp" + +#include + +using namespace libsnark; + +template +void test_r1cs_ppzksnark(size_t num_constraints, + size_t input_size) +{ + print_header("(enter) Test R1CS ppzkSNARK"); + + const bool test_serialization = true; + r1cs_example > example = generate_r1cs_example_with_binary_input >(num_constraints, input_size); + example.constraint_system.swap_AB_if_beneficial(); + const bool bit = run_r1cs_ppzksnark(example, test_serialization); + EXPECT_TRUE(bit); + + print_header("(leave) Test R1CS ppzkSNARK"); +} + +TEST(zk_proof_systems, r1cs_ppzksnark) +{ + start_profiling(); + + test_r1cs_ppzksnark(1000, 20); +} diff --git a/src/support/pagelocker.h b/src/support/pagelocker.h index 88b95cce7..cf42e3dfd 100644 --- a/src/support/pagelocker.h +++ b/src/support/pagelocker.h @@ -145,9 +145,9 @@ private: static void CreateInstance() { // Using a local static instance guarantees that the object is initialized - // when it's first needed and also deinitialized after all objects that use + // when it's first needed and also destructed after all objects that use // it are done with it. I can think of one unlikely scenario where we may - // have a static deinitialization order/problem, but the check in + // have a static destruction order/problem, but the check in // LockedPageManagerBase's destructor helps us detect if that ever happens. static LockedPageManager instance; LockedPageManager::_instance = &instance; diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index d15203945..32b14cb93 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -22,7 +22,7 @@ BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup) /* BOOST_AUTO_TEST_CASE(sanity) { - const Checkpoints::CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); + const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints(); BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444); } */ diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index bf2554875..7641b8b2d 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -8,6 +8,7 @@ +#include "consensus/upgrades.h" #include "keystore.h" #include "main.h" #include "net.h" @@ -119,6 +120,8 @@ CTransaction RandomOrphan() BOOST_AUTO_TEST_CASE(DoS_mapOrphans) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + CKey key; key.MakeNewKey(true); CBasicKeyStore keystore; @@ -151,7 +154,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout.resize(1); tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); - SignSignature(keystore, txPrev, tx, 0); + SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL, consensusBranchId); AddOrphanTx(tx, i); } @@ -171,7 +174,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vin[j].prevout.n = j; tx.vin[j].prevout.hash = txPrev.GetHash(); } - SignSignature(keystore, txPrev, tx, 0); + SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL, consensusBranchId); // Re-use same signature for other inputs // (they don't have to be valid for this test) for (unsigned int j = 1; j < tx.vin.size(); j++) diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index e34750eb8..fc0600dfc 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -476,7 +476,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // this test could be a security issue. BOOST_CHECK(info1.GetNewBucket(nKey1) != info1.GetNewBucket(nKey2)); - // Test 31: Ports should not effect bucket placement in the addr + // Test 31: Ports should not affect bucket placement in the addr CAddrInfo info2 = CAddrInfo(addr2, source1); BOOST_CHECK(info1.GetKey() != info2.GetKey()); BOOST_CHECK(info1.GetNewBucket(nKey1) == info2.GetNewBucket(nKey1)); @@ -518,4 +518,4 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) // than 64 buckets. BOOST_CHECK(buckets.size() > 64); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 2779557ea..383616ae0 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -745,7 +745,7 @@ BOOST_AUTO_TEST_CASE(coins_coinbase_spends) BOOST_CHECK(tx.IsCoinBase()); CValidationState state; - UpdateCoins(tx, state, cache, 100); + UpdateCoins(tx, cache, 100); // Create coinbase spend CMutableTransaction mtx2; diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index c23befe23..3e9874157 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -53,7 +53,7 @@ "in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0", "set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]", "set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]", - "sign=ALL", + "sign=1:ALL", "outaddr=0.001:t1Ruz6gK4QPZoPPGpHaieupnnh62mktjQE7"], "output_cmp": "txcreatesign.hex" } diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 7afa2abf4..7a50b8330 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -523,14 +523,14 @@ ], ["Increase DERSIG test coverage"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Overly long signature is incorrectly encoded for DERSIG"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "DERSIG", "Missing S is incorrectly encoded for DERSIG"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "S with invalid S length is incorrectly encoded for DERSIG"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer R is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Non-integer S is incorrectly encoded for DERSIG"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Zero-length R is incorrectly encoded for DERSIG"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "DERSIG", "Zero-length S is incorrectly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "DERSIG", "Negative S is incorrectly encoded for DERSIG"], +["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is incorrectly encoded"], +["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is incorrectly encoded"], +["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is incorrectly encoded"], +["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is incorrectly encoded"], +["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is incorrectly encoded"], +["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is incorrectly encoded"], +["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is incorrectly encoded"], +["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is incorrectly encoded"], ["Automatically generated test cases"], [ @@ -578,140 +578,98 @@ [ "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", + "", "P2PK with too much R padding" ], [ "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", + "", "P2PK with too much S padding" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", + "", "P2PK with too little R padding" ], [ "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "DERSIG", + "", "P2PK NOT with bad sig with too much R padding" ], [ "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", "", - "P2PK NOT with too much R padding but no DERSIG" -], -[ - "0x47 0x30440220005ece1335e7f657a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "DERSIG", "P2PK NOT with too much R padding" ], [ "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "BIP66 example 1, with DERSIG" + "", + "BIP66 example 1" ], [ "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", - "BIP66 example 2, without DERSIG" -], -[ - "0x47 0x304402208e43c0b91f7c1e5bc58e41c8185f8a6086e111b0090187968a86f2822462d3c902200a58f4076b1133b18ff1dc83ee51676e44c60cc608d9534e0df5ace0424fc0be01", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "BIP66 example 2, with DERSIG" + "BIP66 example 2" ], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 3, without DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "BIP66 example 3, with DERSIG" + "BIP66 example 3" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", - "BIP66 example 5, without DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "DERSIG", - "BIP66 example 5, with DERSIG" + "BIP66 example 5" ], [ "1", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "BIP66 example 6, with DERSIG" + "", + "BIP66 example 6" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "BIP66 example 7, with DERSIG" + "", + "BIP66 example 7" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", - "BIP66 example 8, without DERSIG" -], -[ - "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0x47 0x3044022079ea80afd538d9ada421b5101febeb6bc874e01dde5bca108c1d0479aec339a4022004576db8f66130d1df686ccf00935703689d69cf539438da1edab208b0d63c4801", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "BIP66 example 8, with DERSIG" + "BIP66 example 8" ], [ "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 9, without DERSIG" -], -[ - "0 0 0x47 0x3044022081aa9d436f2154e8b6d600516db03d78de71df685b585a9807ead4210bd883490220534bb6bdf318a419ac0749660b60e78d17d515558ef369bf872eff405b676b2e01", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "BIP66 example 9, with DERSIG" + "BIP66 example 9" ], [ "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "BIP66 example 10, with DERSIG" + "", + "BIP66 example 10" ], [ "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", "", - "BIP66 example 11, without DERSIG" -], -[ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "DERSIG", - "BIP66 example 11, with DERSIG" + "BIP66 example 11" ], [ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", - "DERSIG", - "P2PK with multi-byte hashtype, with DERSIG" + "", + "P2PK with multi-byte hashtype" ], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 4b10e3f1a..572814c80 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -690,16 +690,6 @@ "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature." ], -["Increase test coverage for DERSIG"], -["0x4a 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Overly long signature is correctly encoded"], -["0x25 0x30220220000000000000000000000000000000000000000000000000000000000000000000", "0 CHECKSIG NOT", "", "Missing S is correctly encoded"], -["0x27 0x3024021077777777777777777777777777777777020a7777777777777777777777777777777701", "0 CHECKSIG NOT", "", "S with invalid S length is correctly encoded"], -["0x27 0x302403107777777777777777777777777777777702107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer R is correctly encoded"], -["0x27 0x302402107777777777777777777777777777777703107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Non-integer S is correctly encoded"], -["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Zero-length R is correctly encoded"], -["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "Zero-length S is correctly encoded for DERSIG"], -["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "Negative S is correctly encoded"], - ["Automatically generated test cases"], [ "0x47 0x304402200a5c6163f07b8d3b013c4d1d6dba25e780b39658d79ba37af7057a3b7f15ffa102201fd9b4eaa9943f734928b99a83592c2e7bf342ea2680f6a2bb705167966b742001", @@ -743,83 +733,17 @@ "P2SH", "P2SH(2-of-3)" ], -[ - "0x47 0x304402200060558477337b9022e70534f1fea71a318caf836812465a2509931c5e7c4987022078ec32bd50ac9e03a349ba953dfd9fe1c8d2dd8bdb1d38ddca844d3d5c78c11801", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "P2PK with too much R padding but no DERSIG" -], -[ - "0x48 0x304502202de8c03fc525285c9c535631019a5f2af7c6454fa9eb392a3756a4917c420edd02210046130bf2baf7cfc065067c8b9e33a066d9c15edcea9feb0ca2d233e3597925b401", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "P2PK with too much S padding but no DERSIG" -], -[ - "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "P2PK with too little R padding but no DERSIG" -], -[ - "0x47 0x30440220005ece1335e7f757a1a1f476a7fb5bd90964e8a022489f890614a04acfb734c002206c12b8294a6513c7710e8c82d3c23d75cdbfe83200eb7efb495701958501a5d601", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG NOT", - "", - "P2PK NOT with bad sig with too much R padding but no DERSIG" -], -[ - "0x47 0x30440220d7a0417c3f6d1a15094d1cf2a3378ca0503eb8a57630953a9e2987e21ddd0a6502207a6266d686c99090920249991d3d42065b6d43eb70187b219c0db82e4f94d1a201", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", - "", - "BIP66 example 1, without DERSIG" -], [ "0", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", "", - "BIP66 example 4, without DERSIG" -], -[ - "0", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "DERSIG", - "BIP66 example 4, with DERSIG" -], -[ - "1", - "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG NOT", - "", - "BIP66 example 6, without DERSIG" -], -[ - "0 0x47 0x30440220cae00b1444babfbf6071b0ba8707f6bd373da3df494d6e74119b0430c5db810502205d5231b8c5939c8ff0c82242656d6e06edb073d42af336c99fe8837c36ea39d501 0x47 0x3044022027c2714269ca5aeecc4d70edc88ba5ee0e3da4986e9216028f489ab4f1b8efce022022bd545b4951215267e4c5ceabd4c5350331b2e4a0b6494c56f361fa5a57a1a201", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG", - "", - "BIP66 example 7, without DERSIG" -], -[ - "0 0 0x47 0x30440220da6f441dc3b4b2c84cfa8db0cd5b34ed92c9e01686de5a800d40498b70c0dcac02207c2cf91b0c32b860c4cd4994be36cfb84caf8bb7c3a8e4d96a31b2022c5299c501", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "", - "BIP66 example 10, without DERSIG" + "BIP66 example 4" ], [ "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", "", - "BIP66 example 12, without DERSIG" -], -[ - "0 0x47 0x30440220b119d67d389315308d1745f734a51ff3ec72e06081e84e236fdf9dc2f5d2a64802204b04e3bc38674c4422ea317231d642b56dc09d214a1ecbbf16ecca01ed996e2201 0", - "2 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 2 CHECKMULTISIG NOT", - "DERSIG", - "BIP66 example 12, with DERSIG" -], -[ - "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101", - "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", - "", - "P2PK with multi-byte hashtype, without DERSIG" + "BIP66 example 12" ], [ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001", diff --git a/src/test/data/sighash.json b/src/test/data/sighash.json index f9ad10e18..72d59a870 100644 --- a/src/test/data/sighash.json +++ b/src/test/data/sighash.json @@ -1,503 +1,503 @@ [ - ["raw_transaction, script, input_index, hashType, signature_hash (result)"], - ["0a70154f042bc75aff44e8731f286a9794331cced9f21ecbe909ba6fec8b220d14f1a343fc01000000056a00005353a126ba963caa7f2b9e07d2b87ed956a8b0dc049ba8374d5bbe68f4f2b02b9808392cdbed020000000400526a637ff51cea3078081a198622115e7892ea884223443643b4b838b9fb36a40fe595bd53c3350200000002acabffffffffcc43984edd96a3fee15be35ca5da72046e3e96ab82a85c24995fb4268dfee9b3030000000763515363515300ffffffff02440eb800000000000863ababacabab6aac9dfb37040000000003acabab00000000010000000000000000e5044a0200000000762cb167f99e568df7f7ebb9015ba2ad87b2f1d92a754aef697fa8404e3c2581ed87569ac8cb7b449900acf1e5b543f814499deed9ff2aaabb251194f2f385471272712495da501135ae8d1dd13134af23071428a1d017ecaa3bccc23b8b8b03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cef45de773c6190236609b1a46b3e23a238ee1f644881a85991189d772fe460b7cf0a00cc7768096b6e3f5317b434d97a4ba969a3f90c5b374901f0355c807448a3015ca634cf338ffc2feff8e037c4e82b81249c30c74a08ab5f89537ec235818c9d7ccfd92a60d06ead38d52752db6021e0c02f7bbc7e1403c3a71fff5ff603063e4dd6b6ab831d4373bb8f7f4644855692e7d68406783860c73ba54bb870ca030c1ad82d667f5c6987732aaed4fe88e3430d072f2a8e08d483a1e8d7d22891f00a2055ac1c27678792e07b27e1f2996569530dabf9c80046d465a0ffe8f040923421ed8b38faf264e5cf75c80544bbbbce99d6796968c107cc4e09432e0173f7ee02277aaad4c0533ddb4f174656c042a6812ac4f441a9bf7ca598b3f1bce0a33363022bea6a4baa9bf55e8d44c7f9dcb210293710ae9acd81021221dbe97cc5ca54ce031bf2a0da31aa890eeb74483f08309e23bda66a36425c13550a743fc76c3d03c2030221b3475b3043581d4fcd74e1b69416c82209f63b04a21497c02601b43f1bb0020bc24a91d3b80c79646cff0658caecc76a6acaa176aa2e715a73595fa172991665c2a28f90c71d168c55ae4e1a949336376d2f23bf99bba51ea926eae2db1edd385c4ff301343921787353c4781ebda87eeca9770a132eaece42dfaf9fe8e0393bd5fd4f9ee7739e8d413507a186379e25380295d28e353792fecc20e121ea349eb7a544f8be1aa1a02996c3b191a4323e52072bb02ffc88f36bcb82cd3391f108347e4b1597fb14f871d17a94c10fda49885628e6678c2b7e77c7e773a9a0def443f3748ef2dbffbb418d64e1191678ec5516d7f016eb27b24ef8e26a9a6803ef03e253c5795c80343fe1869af0770fe2f7faefbfa0cc8c8027bc945632fb458f87de209d4d68d851420e6ce4fcc63ee754eaf89a0f6ffb0a449a4d83568e5c9196d02063575edbfb0ed4a11df8edc9b10089ea5fccbaf19c7af0cba388b61a2986263bfe976a9b8e755fbadf0e9a2c36926c7ae102666f3b94f738cf87c14e6a00ae11bf603c4394534208e1eb83c2a741864b0deed4de3acb760166feb4dfc8b8e40a19701d72ec9056650aa9a8a231d609354a28c3e1e645734388b8f62c2f40a9d9555b9b1b480f53aac83312fdf11c2f38c71656fe982b3bff986b799b282abd65768fd14035cbe61acec75b3ca23c8b8dfbc580634587fd1d8507201ef0918f41dffa3eb39235c7cced51446655923db432eaebb3a558b5b5b15d8d8fd1f506b0eb9cf154fe81cc7afc35dd9d48e7709171934e6b762e6485de27c2182a11f139fc7c1a8f635a9ad4b80a58f73d622866906cef14527534a22cd481427902f1d84ba5f4b38d793cc0085b1abf69d2acb763935d984ffd6922d43e61659a44070fc1222a97811d3b1a0463c3955104b4552d681a85896e2705dc28e981b7704fd4dff097c859450e191ca55efb5635c86f3cf6873a411fd4b8f07fc05dd932b1b14e403f422d4a7acefaa635a2f4ca1f406c839c05b17e89054f137985639aa0aa702253c769c613c63519a3e9e44e173295eb95118666633112dca7be2943636f60f4e4806d8a80268541c4b3b071b563a4b8a7cb77c417d86904e7e9046bbcc49373a9737b24000f4396d0428a46d7585bbcd067677c9d782c05d7e87b5c4ef8dc80e01e95acb6167f66f0af4c893596f0c8b4ef2e73ce8dcfa89d5f9476a56767477340c814afeee8348a3ec3a27d8b437604f47af0ba38de043666688877182d1d17c89ce78cf14d8335accebd2691f9fee2ab279be2675d8551756112c0d9cad3d0a496730d868bcf1eae9029879e58290bb751a6a540029eb72715def7cb39e53de75004040a7e6deacca212b062a43e47153360e1bab9d2d800c081e12b3eead416482e48e9d5dfb76499e14bfc79011bfa0c7107e8f67b9eb9a3f6b7db17b9650123a9a7eaa45e9af0689d9167c95f2507dbf13f3d4e771867809859ed8175169205383b1c15c1d20416314f91096674c56bea9dcdb5a97662f4730e624c1d6da58a5f1cce2e684e1a867e93125995c01720f804314a448393af530d2f2ce9eb99394fea50864f852153913f2f25d27997d10e8626407e4b6773d4872ba26303260025a5b8a09a92d4496d467dbd7accb3b7ae8b0e61e1510b0fcca2d728eef322f6c064057bb4b84fca3c9bc52291f659faf714c92a698bc7ac0d60cd6453d60e624cd88be1e8c12df00503eee1a643c02a3fbfef76b1d9f64e7b2034c391e8d57f41c8b1bac269dff9f4500549f1417b683b0c1ffee000477f0a083121302ef3fb23cdf67584b38eb49503b7b400a93e13dd7bf909d11425ce4ed20252335f12cb30067ccee4cffaae44f4ea37d2b37c7cbf988db0662899b58e0a1adcef7e6af074de8efcb394df330c", "52636a525252", 3, 1743887456, "1df6fc62e536c88c0914bc59cd253bf61755f27f7619f67a73463afe658f2f69"], - ["5f1aee89040d9e006691b6d98124825bea8956fde25e0930ada7a3074d5672ea6f25e59ae1030000000552ac52ac512151ddc5a7138896aab72e2216dcc62d140efe9c13b2a513882912d720c0aeceeaa81e210200000000b3672e14ff5aa54b8a4fb0b0793303b3ba69c169ec30a5ac24d9a1549d6ad02d2aaddfc8030000000054417a2f4464efe9b5a4f8bf14e1071c10a6762a40f9a98efe5da96f1ff85b6b4920d8b20000000008ac65ab51ab6a52526dbac29103382ffb020000000004525153ab90254e050000000008ab5252ab53ab63ab448098000000000006525263530065af338e39", "ac6a65", 0, 182861550, "ae8c39f404ab2c668e7c4f2340c5fe4c1e68bd463c5911b68b963e5ea3db1b5e"], - ["8aa10deb04f90d5e471fc5a829bd2adcd44f17439fc6b63c0669b2668e4d51ad67e50016d603000000007eb0f0ee7079ad6660227efb819c294a04d650f6dc723044a4680d20c346fc34948cc95702000000056a6a5163ac42a6917e538f417c5a35ca0aafdcd6b3d0f5a5640613ad6fe12d32787aa6f9220c70d22000000000056351516365ffffffffaf1313aaf41e05dac24290f00a2f862777830e96024107bf1c4942cea3c32398030000000600ac00ac00510a320c0e02b27fe300000000000035fa9305000000000100ebb50cdd", "6a6351ac536a53ac", 0, 1248756288, "40a5ee8d5fa08b812b9756bb95f0cab3f114533c978f8955392a13efe5820824"], - ["371f7ade02310bc501806dfbafa790004d9022295b900a937e59338d1c623089c4582a35be0100000001ab32a28425e75417726a878d55ba477c37a880dd030e81d2e66fc75ce3a821f330e63556e10200000006635100ac00acffffffff02e01536030000000000d0261a0000000000015100000000", "6a6553ac6a51", 1, -89315870, "1e19a51b20045c6a30ec4c46941b3c4055cd06435f52f7acc6e2320b1c8d60dc"], - ["21ea16d302dc64258155a19ad5b0e9d84ad43697648ebe0e85eeaaac4d8fe27d6567a5cc9803000000026551ffffffffa89a5831fc84b335db23d13d2fec9dfcdbc79b51b16c6475951e08c171ca8d200000000002526af27a71d002316f08020000000007ab6a0000ab63ab638342010000000005ac63526aab0f315df6", "006a00ac63", 1, -918284113, "2c812a691ab439532421a17c3980ed6dce697d58bdbe89799be545d03ca442ad"], - ["a4d00cf302f37150c4191465cb545b00b24a3011baa4ad1adf4c2c15cdb23a1f20ebdcd37600000000095363636aacacab6aabee4a08bca6721bc9f9636028f9062c5de108d7d3b263e17fdf8b8e268a2da6c537f12d040000000008526a5151005152ac7552652f038c8ad2030000000003510065024bf004000000000952ab5252536aacacab3127a2030000000005acac0000acd2f9a110", "5300", 1, -1377561406, "7e2803924edca56dd27896ceeb9a31771c246fb16f329c4155a0c5695ae279ea"], - ["448ec2fe0427d4262e976d6cedbce0b6295a493d0e46b9893a1e0fa0481f172ab4c176925d02000000035100ab20317ee55d536ff4638845f9f2ed101e8938a1ad04ac4c6f9e6064f28564795fa33fd9480000000004656aac53367e39fa1c0108646b6ae218e9c0d30550ed023d808a68ae28925756e229e68bb8d118a5030000000153ffffffff230331c1c94d7369e7c4f1f0d468bc46d5a60cf04476a0f0209c802feb0514b70100000000ffffffff0122b69b040000000008ac6363acac00ac63efbfd63e", "52530065ac63", 1, -1200902521, "9accb2591792b3a5517132d80e87092ab6e596b0b9d1b53e01b51bfbec1e48fd"], - ["a5dc7b5e0421c8f6fb20b183b2c8422fb7a24b85cc4ec6619c272b19223b9707c68ad2e6300100000008525300ac5200516affffffff3fb28ce660e19bf863fe7155986b6349053765ad058fbda5931ed175e7ec0f6203000000016affffffff7af9e1f0b0c24138cd1af05cc1a6cd743edbd7d2a085a42e08e5eca2944de75401000000026551243566610f5f729e148fe0aae8a39d0d9f4c26d966b3995a8b5cb9972fd989f8ce8cd3430000000008ac655200ac525365ffffffff02b58304040000000001654c67b200000000000563636aab5300000000010000000000000000964b86030000000080cb3f2cb847e1a214743d954ce55cd35e402bd0ba7e2112ba525077c68349bf101bf479c7664dc60a962c1f0d338045576ce74ef9f5223b7cdaee741469f2021daf3fa8c48a2e055f9b65836457e7aa7422bf1f709a072526feccf373bdd3dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000183b2c4281bda92f7cc50a0bf3c53958f1f70f05a65448144ca7be98627cca7027944fd1dc2b032978847eecac2c4defcb0309d47336090378c983a120297e5660cf9e4f90b224a85745eaa0729700920fe4f813766729a9efb6f8af8cd9a1249f180c204fede8a39b4bffcf763a5d06f53d907820ea1358416a81f661f80ef2031b2c3fbd29227595e2d67e32d1285f73ede798512043f378322c228a23d6fc9e02159ceec4615d8d35eeef5fcf981032f38561beb09d19afc6e769595e49b6caeb0a08f0408f8822e11ee50b9b2b9d1c420c872406ff598a1a717b486544e6af5d902beb36c49a69b7e5ff3f902e2ce7c252085f5d183159964c7337288de61fdc13030368f671c1d6bc63a0155bd9ad3da9faefd4ea6ea8c500213bda48695eaca4c3032706feae9a9274e1fe18941a8db71d5088fcfc38dae8e99f046a3aca58de11810322dc7e08537a5de280e10da22c3a9724cd7d40b00f310ed397d4d202c7a5d355030cb2685d0bb6d4f719709cdee7f7072457b98b4395efc5c57f52821cb6a1289c021b947a7f3c7835b3aada9d1dcea8454f9744c6eb03dae1086619fcc548a40ac1581a244ce82ee4fce1ac37bacc04ff67fec0ffb9c98ba70bc082ca9b06c2a80b10b314426fdaf7ab9fa5caf1ddd8fe68cacf6a6e951a44ab84056bc3019c8b3d4967674539fbedb29b53ec28568f444473f92959ec64a7afa9449b9505be51a3f28b495c95299a18daad4492c01b803f05fbb1b0934e65ac73f7e9e3e76a91aea9c2996d68b807c9afbd1be24512f33e44cb6866344a1838375a3fcbc7e61240438eb0bd8e36863c6a0c5efd1f117aabf247ff7022aad51ea919eec0c76d9a83dea8a34505e337723addf825a398261de1e4e65766c46ab5105674e45d7cca7b65194cc037c777b2002efbd82597118e69c6e756435b40edc246d9541cc6eec1ecbb384f9798124597c818d2ed5fb0fb26e18eead130c79e36f2fafe63001e00bb4fb54ad95b45f8a142b900afaa919c2eb7d807868023f8d8fb8404eb56f2fea1b19b45b11c901088acd8fe5e1320c042f591ee8da8d3cb4494776e872c2b4ced1d6a8ee6f618723fffe2670631527c569029fb8e7ffbb2c906c513e05301662552624a23a81e6e1283625218e00d35921914864e3f8ebb80cf8ad09e124c2d679b378315d049bfb6323c28291fa873b4cf1f899aa975e4299b15e9f8977d863318e0c1ed938f46fadb59c61ee3a168f6c0ba5d24ed78b8eee01a19acc412fb7c97aab3ed7dfc0d21ab8067bd31918bf685580c19440197fba41c6a425d3b373db9689f6546ab22c017819d15020c8a03721dde165f769398657b106f533b8b7659b156a463eddd430cd53bc529ca9824f786f15b8dc7c2d9b91171383a8e393fdd2321171ef78f69572ecedc09fc20f1fb00872315d6f2a847878c6be380a88acada41785a5099275ff480951f3a165e406cc64ec623831a547c482df875e51f0855bca5f44b68fa39c52a9d7fa4540ec895573d2abae8426e65b1403a2cd6bfc445374b2d43eee0d2ff50d31f0cbdfed035b0e9e0008e5f23c572507555e382bae55ac62830ae8d61494cf9beaa000477350ff7c4b1653dae6dc706372c468737f347089496fe1e39bd0432f739d4b4040d50b9290f41b671af98e4f1784938a889773d5531e770f2cc7daea311dc048b524f91b517a8220535165ad27dcc1413ebc62b9588142c64dc8586e5b3afd5ac58d448b953e2c837c1e03609dd3a7778be3d179996d32cfd648eda38a4e2ad7c98fa696e48167804dc2a44d76d63816a3b4788000fffc61afcff2f1b85a4ec2d6570e2b5cc025539af1519c925c235fee21ec2c5b452200211a8430a176672c51bb9658d470339f8c583413fd25762cb1a40789cc2fe2210cc1699a6e329d9ad3569dc3933f48ea413bcd566a0332e8e9b0ebb4fb96bf3dcf6fc55d7d686f72e2286b472e26b008648c2d071b3b5870b74b81d504ea7c5b109ca5d6fef9726a6eb9fcb36448629b524bb23ceadb20f2753c97dd180a9801695310140716cf1799705193e8d48fc3b4cedb1a38d3d6f1da28802f49f3443a584ba3a5bca87c86717a5b06c9a65b4da8615c6312020df865838bf58ef87c096c76ec4d2aaa496e27e6abe1489407b12200c90aac6a10286122c08dd1ef8b51ddd06c2b86d0c66cbb80aba301a2e3071207598bca282d0de0d7be47d74adbac932799266c6db171033a87573a1525a0625c7f3adf4593cf43de4966bc2216c6cafae00b38416b067881f9cd8d3fc1a0f0313dbcc4ec995a5a0adf759f2b45b53e96a6a6c8cd0c3dc99f396f38a02a7e8379aec8c79f6703c403ab6af7fdf16d1f5484291b95cd07276688d273971ed9120e0ffda8092c7803bdd59610145d5c27557d4048ad6a509", "5152", 1, 1101231466, "6b451dc3e1a929fdcf80a8bc1c8417a62ddcf5b1e8e68343c0c68add5c6f0cda"], - ["359e5a4903336cb1214ef0196d97709fe39e289f022a14029d2cbe73ea40e4612574ed8305020000000665ab52acab00cfd6a2c5007ce9bfad72f5a6f1b64190c47600b3c9279fb8eb21e7dc18761b92a1c4599f0300000000ffffffffd5f05efe3e822072f6b3bc7cab03627740447d50e547dc492c1b644e9c700a820300000000ffffffff03ee183a000000000000cb3f8704000000000963006353ac6a6563ac6daeec0200000000065200abacac52eb74a657012f32cf01000000000000000000000000e347160b0201e32be95a4a900375c87a1e70a0bd7561c559ae03c26c776caa641d63fbf1cb09ded9ccf51ebd3e8aed5752a8b114dbabce322005c00c9e707e5b86efdd27b522e79fabf98fbe5a49d61f389e26fd930b1602e22797ae51cc812800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cdeab72c762f864814f7a0c8794d60bad4a89f59ba77b8157c913548dcb564fe4cc7da614ec789faed651b6238608359aec02e921875f4d68622b4f2bdd1fe183544258f85a2acfd6d7db81ef211278d810feb7ba71a87d1aad50c8de4c1d7f6a82b30e5f1976ba739c89f3f8371f1ad51731071e75fd831c8c0b23f28b4b615030cb8c1e2bb4cc84239cfa06e54ff788e7f3810ad5e41c6fd5475dcf8227f3fce021eb9ada27aacc4318f29389e8106156d43b9f4c96dd47eb86e5c5c747c5a40da0a2705ebe216ab60e080f451f901dfe4a1681f9278a716434d458e3d7ba1ca81772465a15a65674c705c7afbce0f41dd74936061a8c6dea97d633a352aaa15d572031b88909343d8b603ec65cef6c3afae7b30fcdd1d6dd55c4465b1a285df882e7202300192fc94cdcfcfe404cfd9904ac5d4f65090b841d1442d5b142f7536baa3cf02145f654e224c8a5eb7c5717d5ba18040b383e851430a42d16eda82529c9bc51d0311c832b0fb625edc84a3f1ab609b7fdb93c0d9134aa0deb7d214d6543cda7317022cf1a470c6ee79fc479344fa28ec804b8c0247e65ff9f4c6b570b2dfd00fef740929d2219e916e42a52d624f8b67fc4d661357e845b5cb747364337b60dadaf0f3bf774cd3ce36a25d02557054459a699c9d80f83b299a9ff4cb8941ba800ad4ea41c288864c173b74904789daee7dd20510b9a87fee893135963b2796b743c35afe38567f264e4b18931db612bc2c312652807dca9432e995aa49bcd6d846712dc604ec1f50731bc10d0141784e2623dbbf5b802810130893b6b22ca26dbd82b92eaea6473da05a0c110123ae2a168eb71fd4be9c550a2c5a50da6d4251334ad23256679c3a8191d0d58427715ff6acbeaf905f997a19dbb46c2de2f006d1936cecc1c1bd580ac8b4f3a89c22026e9c7a16cc775f9a60a06d6f33bf1129a073b3d929c67ebf833d81436a2d4491117155ee2f4c816461824a5bee25598985d3ea25af1671b8bd797220f916acde13a6ca8b7cc2f6b08caf9e4e2564b1b1036d45173b5328d20c4e5de1f72f84232076f0e607b132404d3120b301f0e59b6e2a5706067134b5a38d56944646474738f139801c9195c8eeafdde7d009ff14452d309a35028bdb762708f0eae985e593bc097331a307cf1ccb26420f5339d3f326b000ec8dd3be9b0c7f8f9bbcc55ce92cf437e66fe64959aba7d14a5a9acec94c8308f61fce042e111ee013c89240bb78f5654eec3e3aacff61c98f076c30e2cc191e44b0a70036e20282d1b419b6f9777bc76fe8b448b8b9936b896f490c00fad9fb712279aa102409097b9e44ba649dc10de4b7657c06593beeab316fac002b80d8a643037c1fdd6def7d5540d2b53cfd44742d03ffc421bce4f97515fb046e8b07efa2adfdc4e2af645bbb3c59d6a04f327bdfb7302042aa9046c88e953fcb70a7698a491f34bd2e7b127d3bddae35977ac6d4ff7588d44db3f0020eb9e1cd0406e8a5b6de3bb1d03ade1e2a5a3dd337c42e892444c2a0ece6b0f428b668b37a209c791523dca42e5a66f87d82ae801593036bde09b25954e160956d4c0564856a0e58ca59c8cab84a7bc4f82f6fab4a4391e0e6963a1e81103c0c597918a73b30e2aebc80b094a6d63832520a2a23879d32de39c3cf5cfde4e7f62e0bc2fc3cefaf98de2ce5f9a77e58223bbabafc35fe006b51e45269a49a20893500b375b09d7c80fba7c777ac75909c324e951e7ac9a17194e14aa2171b6f4d32aa0ec4e0e21e459765de38067bbfe124029ec5ad7ec7dd2610d4ef45361aa2ffb57da87944f40e48cd88be4bb3a5f7a885a1b381874abab13f66581ab8a0045bcc1b25f1471d31a101ac4cf537b0221173ac7481fc2344aa9913039aad53eccd537f0f8de0cb0f1bf9f1c86f90e8e9cf3a711ec978cd5404011747cb50ba4e26b87a288efd2c4f893e0a3835046a89bae6f8bb62ac56a62b8b7f71cc898a9011dd5250ad0e02e217c844af85aeb048ed847c9c8d3da7a72653f610578e92c5d85dd5233930fd80ea4ff407f0f3f426e1296c8f323a3b0643d8f25e6e2dfbabc4aa23d99d611e6be93b5f0d2a65012ce3cd487b4f6880e57195eb61f6ff90395008a545fb26ad2e76009db35d74587f8a81c6509d28481b7e73c2eb4b44c5c0a3e00dee6593ca5d4c741e123c68ba7c3eeb11e406b8b21682502b2668b2bee299bebc478ceafe9938c783d44d24d9c5e63c00143bc23ead1cd80ae4fcfd731d5ea70a2a80731398fa089553810b8362e415eef36c84dfe11976cf59bb707335ef927997dce1fb01f538607ad2d1a93a750ac2bc14984b48a6bb1750f667d8877e1cd413c63020789cc4d17f42fb26634f0555d5fb549083474d97b300e3abedb63f31fcf3c7ca304fe247b9148d016e5e59fe881d0f", "536351", 0, -715905776, "e935b698dd300074fdb13ba315666dd29447ec58d38940e7b8ba4dacd5e334ed"], - ["9519f8e001ecbc12afb8587d14dccc2cee79c27f67a3ecd2c23a3c1d9c48159f9a5e985c5a0100000006ac00ab530000ffffffff035c3c2f02000000000451ac6a53a1ab8103000000000563525363ab7517d60000000000046aab006aaba084a1", "5251ac515252", 0, 1197587702, "1e9bcab050160f24c23a6fc92c35d68c61ac8a6a79aa2601269ee0f440dd8846"], - ["9aa606a10335aaede0ae02eaac79306df74d0efba77301e7613f8dca6438b1bde35f8a7c79030000000353ac531344edc95c232498baafd493105b921d8f979726f9220e5dd106c8b984a5c1977986478e030000000565acac53531e1e579e06872bb22e300b6cc556622fb4aa93a586133c67f60ac413ac010ed2dd3e645c00000000075251ac526552abffffffff02b13fe4050000000008655100abac526a514b2ac0050000000007acabac526aac52180e0d53", "536a635253", 0, -582918023, "3c5e6ad865968e86c36681d2c4c49ff62069682f59c912aa7396e0865ef09752"], - ["bc724fbd04799ba10ce2324710633752ac95c8f7881613c10c78a457cc2aa1cf28aa6dad750000000006536a6a51acacffffffffe43a631bafd81d2947388582e8ac9704590e4780286dd9f97e984d6bb877c8b400000000086365ab6552ac52acffffffff3f53fe85f292d997605073b85f1befbe78f0adb627dafbc6fbbce4710d116b170200000009acac650000525363abffffffffcedefb69d8538d1bcc52497530c66d74119650603755b6e4ae156c39a9409d220300000004006563ab7382139704123eb30000000000003f449f01000000000751ab6aab51acab75fff1040000000006526565000063183ff60400000000036a6aacb21d6a15", "65ac6a535165650051", 1, -647041218, "f311ea4b987f1153052c4985547c69ff702390c979791a258e87e81607a9e2a5"], - ["d5d46ddf03b33dbfcc434909ab4cf4ac6bd764d80f075b934b96a18ed26426331af459ec7301000000036563abffffffff551033d067b305a41289696c2cb44b7554da3a5870e3b7d9f714320af4b7653903000000036a0052ffffffff8ebc5b0f63d3730f02b2ef3311731c91ea28f275d6c6a43baab9ec0f604a49fc0300000008ac5352ac6563ab5152bdd1a30285ab3904000000000200533d3979020000000004535351ab343fc798", "ac53", 1, 1912077243, "f70536783e81912d078d88ef9500ebe622207521d5fa3b0331810742badf05c5"], - ["7a3168da029ff840084e48d8a8619e31758fdd8996fe7a58346e6e3d44d6590d74a6a740a00300000003ab6353ffffffff6e5dfca760a2679892e1bb08a2ef327c16b168c1145a2e59c49e66c7ebfd191c0100000007635353ac6a636affffffff0413badd0100000000086a6352acabab00aca5900504000000000500ac63630000b98f0100000000096a536a65516300000063208b04000000000565ab63530000000000", "530053656a", 0, 2134166525, "cfd0515ad67f943cc5a0b303b1ac796276fe56dc6fbf0226122165b5b4f84a86"], - ["a40328bb033251069c4356d1e2aa2be7454c8a9d728ecfc4501ab6d6537e9ea4d53f4ea6b6020000000251ab5f3179c09c9615e481764917fa419b95933e41fcbd53b28cb390ab636793b65d71e1f051010000000565525352001651de4d2a8d5530492a602824ae4e5332df57478d8e153568b0eddd9b47e4fcbfe87778000000000553006351abffffffff02265320040000000000273a7703000000000351acab00000000", "636aac", 1, 1707062048, "60fef62f6cac302374a84b8532d6018c4776f5f463433ee486659e838ce03046"], - ["b837bb8a0236ca86ffdb245fcbe155ffaa5b838160e4cac9ce049b4367901cde8c525bc11a02000000025151e12d173c49a75d943f8a6a89c70e38942eab710acb8e2366b52de94ad317bfcecf77d0fc0100000008ac6a51ab00ac5353ffffffff03cb778d000000000004abac52652c71ce03000000000351636a3946b5020000000008535151006a6a5252bdac6629", "6a0053", 1, -1241762288, "fb04248b744ab15d50b45adee9912149233c36674c4d9e770047bc3c8729c403"], - ["e1a6240104a8fc66fae56dcb20d9a2fde16e7860817c214cf6d90b11c21d575f90b17f575500000000055100650065ffffffff0a3542c639ae7ddb38a065d8a33e4e1e0f09a70975114c520dc3a0f855b4df1f0300000000023d5c6e4cd5197284ea5f0177eb7937367d779c782a08351071f3e1aaf5acdc7bf8e6510100000005656500ac6affffffff4a8cf9d1b4985404c1963415e1ca0373e5e7136a580c3df39dcc5247ff772d8f030000000365ac6538b25b4a043d3ae8020000000008636563ac526a6565183da60200000000026352edf7df03000000000352ac5194f6a0020000000001510000000000", "", 0, -2143379793, "b776d4af569141006018658107b8a076d2e1efcaabf189329a5694b59a6615ff"], - ["9ea0f02e033497e89099eedb0405d1099f4128b4a80d940c803d6996211f203cc752167a0a0300000009516aac536353ab6a52ffffffff27e0c2faf88ef90fdd3c66e264800cec982664e7a10c879a76950d8e431aef9d0200000006656aac000052f2de85cb33b66e6e34450c640cbac7bb9e3e0130639670345851cd7f8e13ce15496058f6020000000153e4a36fc003bded240500000000066a526a6552657dd9f503000000000200636f5907050000000004656a5300863268340200000000000000007726c702000000005d0693996f52df1434e58b3e908eb6af24aa8f30dbd8582e5065b833108c7f1ed6788f89e34aa10a66467558b3a018f4a56f540f45a677747d3d08e1b8a59b8c139e6eae691dab788a12bd54347af4605caa23f2572b82fe0ffb557201b154e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002906a5325863c94fd5e2601bc347fc80054defdd5f94b71cb1633c8912a0ea24c85a63a2e154d047856f48ed3627075d09bd4be96cd398515e0129456ca9bfaf2303adf534fe5100f7742315e15abe212f7a4a0c66f9f73054a6ffa88c53c0d281326e3cc33ae672c97d3566778c2a3eaa19f5fdbd6ec669236064c90ccbf1c2030da61e9c1e1f0b9018ba10c209a7acf52b67a95db41e81eb1d0a85823148cd10022573236cd539c1ea5d33ce220c18ebad1ae8d70c82c53274fa79bc2a164958c90b2afbc6ce33ce8e71236846a9abfa7661eac0322985cbb29e078dd42ec500d91d2366cc383638a99bd33f34b447c18b66487418621de0e3ba10e88d1332991996032240199b45b6a166624014c05c4d97f0f386f7933839d7292e9f29426b1fceae0305efe54aa68feeb142f7b615ba58ad29ec9baaea8019e8e5eb090b87568a4e110310e326c4c4216a72191acb21b235e8b8743a2effcd915789ba4f68dbac3dbe5602066534ab587ae8b70e46b7c5c67615a325e194d5396b875d58f7c14a6582f8cd0207d2ee2c1c03238d60344da6abda73609c347ea6e9b075ed298d26f4e9f2d57f70b1f43fdd7d0270497e6a410eddeef12c3aeea7022c090038bbfdfd9425ca92af2f749c3186af34012b1e9d1a932ad6afc3dab6d75cebd85cb7eb5f7f8f698bfd5e3a83f355c590cb3bafef03f53a522d4a5bf15eb18bd7b552e5b6271a2fca5d268f67c1e8d77feddbe6cdf28be12afe65e6c8b5f345e0b949c2b5f8d94240bb5c991f19fc7d57944d5e1890494a4c34e2bf32cb70664d23f92efe93065b03b27472fe41a131f08d837718e5db02144189fd22b784ca546eca221dfdfb874d6ea55b83d9162177f0055e6dc11471ce842e8a7daf08a42da464af989f90261e5f8224ddd8edd6ade03b42c3f83aa0f798b457b5d58322e308406b605ddb087d52bf14d6cbad20ee190beba58830f53fdff6267dadf073d92b5ba1f86441d9d049df6915dc06db870f7a1701de411791d40039956186bb658cd9a364feb7fb1829d9590225b2c33b39d9669a812e5d5c3e55e6e2622513ebf420fc381971505d1cbf833ae920ba070125c7f69548a932a9e27d1f78cd2f9d0a3e6cf671e2f5aaa4c3c0d140bc3b84095519227141955c2680388483771173d6fc5c68fa4d76864faff6862442724912a2318910632b0cb909519c488ba8cbf559f34c907be8320f633ddc0a7603ed9b020dd464fb36fbfbf943f92453aebd00a9d42d7bc5ef504a902accef2e7c91be667de0a95a4b40741f86eb93c8bd52a3fc03da633f981bc81a430f46440b3d68fdbeb9a94b6265975612ee500e4fb77b92827dc3a185b11adc2fa968ac961a6cd3d8a5fc2008c480acd339e9481e207b53e4058261ca97feaab2b4d46da6d5bba16607f2dc0d155f708baed7add0ab47f059ab91ae08cabb6fbe484d9000ed69228d9d4ca183b48e849d968b5e989a332b526ff01190044f722319a6db0e9eb0a95a01d9e26cac73f3c69c8624a8d5b8d76eb4ea56f3fec554a43e0f7a700c88b38c3c4b337cae1d96990dcfb68183be6dce974a577b4c30536b688a95237b6e4f3ea8238f20139b21150ebf765d706d682f4ebc79bbdae0aebbef616eb37598472762598c36e98e923ba958940b4d9852453f26927bd1f1677c0f41485a3476e8545b00468da71d872971572c6e4381f2c1abb3ad00ea3516a1ee2bdec8ab969260b006fe679cffa6c60565a87233dee0f7930e51567b884db0094cad733ecfb5f96d243d935389ed479db33e1ddf658338db2e00a1bd11daba571666eb9f8cbb9f747b535bc1615f10b49fc71d637dad2e37926cd8050a86cdbf8d1f373bb2b27053729ddb21377093411c6f9d3d11b4c35fc4197ef0fea907e70bd5c2e426595aa96cc8e812de2a447cf3b527e9ea5deadb0671ee76db14cb85688b43342bba0fb315b042c0eab81ac494e4187bddec4b3c82cfe3134583ab8a1d89bc3c0b4f1d86ae0e62977b8992386c36009ce6b591ed8e3e14b84d3e6801a59138ccdc5a4773f6b2f40339163abc7eca17d69057f381732ad088bfb57bdc6d349e9c835d5b96eb38e73e279af79d87039d8095a15f1804b68a78cc4ed800d7bf303db5ada2f6529bfba11402a7a03d22adca2038e84fbd48af597a3b7f5c0a917fe251dad26dba887d286c272faac129bda1f7a3b91a11047f83103209f760a65d3975833c1b19c2a514829c8adb9e88c70714254ed5dc081915264f85b19b1948dc3b67630a4c318ee5eb1c7431890500000000000000000000000098d42ab58c3e792a5d962ab420aa7c3f07157a8024bee96e308c425acd3da81e9a6c1ca722fd0ac4d5ae0b0a1726985267ce8b32f415c6f3f685f1130c46a69ff775030033f7887f875f7b998d223aae44719f31397f1a8dde5f6c2b225e2b1a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009cf397bb2cbee8f13ad61b08184060828704c0d39a6493ac7a8010e2bcc8329269692b69cc263c8d5c3e7ea8019f3482897e59d3ddd8f1594154556387f42bd253f7f3aaf94e1bf72bcc126d429104f3634208fdcbb0f0340ce697b2cca8d7e697b4553079fd3cf3116f6f697141df1add14191b4e0d06d0a34bcafde872ca8031a4ef22a3cbe8c8bc45ede6e58a1c787a0ea9ecfe441948f421ab5d56396f5480302b9b8e8fef180c557d653b7d8de85f7589ec477ac557cfe3c28151841d620c50b19384ab2929c044170c9fe72f25264696a06e0c276a19cc39b0d0eb57875dec605326ca4060ffa8b2a41329f92206085c0bd1417faf6e32702883176a8a4d0f103286b79255b8de6cc4a705f2a8636a43fa3eafa2f50702d2f26154f247d22a6300305a56719a90a9bf4f09f76019cb630f73e5b0ac4b8aa4b1812fb2bacb2332090031ddfafb8bbd3febbfe5c93798cf307f98da2f7188c688034431274d9d0b5cd600221850773a9d888ede695a8bc3116d14e9c0899a40b5036e9d615e8777ecb828e030c8ae1823101990c9904a0b741fec979402edb574e730637f5196ab6deec9617e12e4d304c0c75b17167fe66dac51fa77138d86f1c131160213b386249e55ba2424006aa28aed3d47d48b766efffb8c718d5db968cd7c03782dad8d2057e08b370a85a7a1c481da33a8f9af140a11372abe23435f8e3c6bcd61883666aa7bdb8a8076b6fb72178562e75499a1d0343e72b7c18b458eb786da1144d65cc4ea12fc15fbf5462a0abecdf9dbc9308185a03dde3efa91f02e11e1dabc1a337fa0a35d74251a45e58b75bf8a9c65c129a42f4e571be4c482e51f5a15a6070f503f2e9cd9ebd3b0ea63e422b15041253174487ebb58aa783afb80b40c010d5a952090421d12a08239108dc86335ed41273017a069bb07f64af540e1c0267347afd31993d77ea3b996db9dfe6600c322670e6701c7a25791aa2f6f8a1076e823abce13450e9a3bb5d3eaf9e9f4df9cacecbc45c3e908ec0d2c3c5d16e9dce515895390d8784fa4ad2ec62234df9d85ac3bbf462fa417f9c2760fca4870d7fb8ae35669d550291c10af02cc3305499b19771d7c8243fc9b1cd64156112d57a5102e3ce5c73d35353c36e88fa41e764bbaa0e6e3a4caf133849ee693aa9c39074fba6147d33bafb73806ea7af600315b2745dbba653bf3513b9f5ba1a082cdf3a2eb6f96b354c3d74750bab52de1a78e91d9633ff16ab43298d28c521cb5cf9d990f4f7ab7a419c04e439b7b6ad7772971eda633e85661196c27098080436ee110cec5994de6f4da45ea0a6b0b05a23f82dcffd59f595883e4a743b398a42819c2a9c41370a57ce560f592f0c7ce35fa04628653f9dcb4554696e821a9a7361e71ee526a07a44f758a68cbf45b2d21601a647f85705dcd674b52d7820234466cd3a71dd8653097727cd511f93166213439106a4471cdc0c225346d2b20759b07b9fcbb428b55c4947211821ce387eda503e329a10c37a2d212f0796f5564ef79ebea0555a597f60aa8cec1ddd6e21751afe691be79454abba6ff6dc2361fa3febef4cd9acd78e207aeb07a111b31bc0ea5f0dc2d0e4ff384249ae7baeba14ca8f621b62438673e107b3d2f26b5823098d11ed3bcfee2ab8f0500b5f0061da3b9eb25558c5e0e20249ee5f77d6768f252fb1690bb26ce5106de2d65286a693c9b69b1601b8f14388b9a27ff7b58d8f09b60a4e582e195d8cebfbd0510f72860b1464bae9c0ad75e010cf71eb3a83b6630057c7deb97fc2006c274c59863f08920c11dce7143d1bb119401905ac2ba8edb7c34754a5048381c2ff16dafa394bfe4a9c8fc1a4319f46b0f6ad2f35725f1060030cc12adf83c7e98a7d990f5fa51210e38ed658c8c53fd78f42956d4ea40a5590f30e261435d55b76720ba2b6adbe62b1a5298b04f6aa4d50623fd42d9bc0f1b5fc384d62d931e17fddcb4adfee96c1e3f0c61f1ac5eb5ec557a4aaf1c1337c929eef9b736443927ed16a913186db653c6cbb893249ff021665311e0a881b5f42d0cb0033a306506f95c0fe7825ca117ceab3f58ac64127af29f5b0fd2eae6d9dc77e552ca288858323850e4ff351316179e187b87b5e071188f92b5b4e6c2e397b08f8926418d1bdfbb90721b4273ec9e8b964a5a820573104de532cc47cacabe05180a054a1a51328604212163e904e81d8da795fefe06c0f0327badd1e63f4227c56ce4591784e2903a77649cc177835d286efa6aafcb0b21747e75908c2414e892231a6f9bf4de18e81ae22ddc70b5b7bb3c1eb362c348f28a795bd3d62b77eca7c534d977c00ed4f57f52de4c3a1399b7a9b34de1ea17fad3d6c36da97a77536d55977290ce77fb16137a39cee48b3f6feb7fae49da418177422e635025590899f2100", "", 0, -1302028225, "70ddbf7fe88db129ef81794820f1dc74d65306c0e2c1deebcf32654add29b83e"], - ["8269f5ee034788b9f5fb25c64236c653f0d1ff1ca69b6fc2c88948fe74197ddf2c8130bb8a0200000000dbbf87003a15ff1aec446f5077059a5f2448f2579d9a4d5f8fcde0d55aead739f6b0230803000000046a5153539a3df1bfd3999ee684ee68f7ddf41f3e9e4650258cd54cdc62431af51727328f334e466b030000000400ac00516af82c710413baaf020000000002ab00d339150400000000056a52ac63acb8906e00000000000852636aacac5100acd30be10500000000046aab5265b165d339", "", 2, 221466486, "b78bfbc27d5e94b20e2f4004c8911ca46f5e12710bc1da6a0c2711b39e2905e9"], - ["d2d4e72102d0d847b8d88c7b8ba4d9d0ab4bae9b17f6f2d2c5d76eb9296b43e5a83d0f5e5e0200000009536a5165516a000052e734693510fef10293f52ea7dac6ccff08cb2499b5910dde7f493f1d443773a0272723f101000000026a52135c447603cfac0602000000000163f4471f010000000004650053519a813b0500000000075352535152006ad2ad5f18031f5c30020000000000000000000000007f9a37be262109336617857c6ffd24edb63c3e2668b60642ee5537c60f6ebaee4afb6fd34a1eba4f3f970e070ea36a180aa145aebc38548fcfd2ea3374095eb8bcfc8fe5cc72f5caa185a51f9899e5e036444829f46ba005e705748701050fa2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000729be036c04c80d25bd90f5b8a8283be6909af21cc907e5beac8e01d7806d3dbf7819c7f3c11cffbdbb7237aca7a47abad6dca6a75a55bd009c98f5a0ba76fcd772ac2de6d9867eb47cec4bd6ccdabd84673f2b26f3d79a16f8945791d109da145a63e89f888f593e8dcaa0f6a065c2de50e9dcf2feeb41c6a835fc0cfcbdde0205ebace982ce85d7f9e05a17e1e107a9034b3b9817d9a581e41568c5b58040e202039705bb43faaa71afa7fc7593857fff0450bb86bb31ca39e316ac1d033974fc0b01f7b8223e74e385442335de0912a53aa279db49bf72201490fe9019ab07f45717e1702c9b08721bf85307f4da844670ae42c015d20d70b9a182c1360fa485a6022367391d8e000c5ef1bde51f2cc2c02311703481ae4d050fb394420b7ecf1def030df67041792102a31ad130179778fc60a067ca61279c1a4f041333f1c1f1bd69031d00bc365211fafd3161361604d9fdcde9f40fc5b3fb51c2b2eb41f644c19237021c258667d07ba02153179084d1e62a38f2a7962c5def866e1c2db1e4e30ff5cb030ee7d67bab4cc17435abab55761ba62c4b171bf6bed3ab338ca219f05c04a76c9380a6cfbfd8fe739377ceb1c151e590271074d3dc2e2cd9015c4ed20b5e5a5a37b244bed575b085326738900637669d7307e92c0f63143cb78ca599aacaa9a8a8be0d8f91577585ad92aa7e61ea88cd9b416f646b45e3da64a4c605ba303822f5d0549d670a7884e80b02edfd07a6df63c5a7d34cb042a14b3ed7c11194b824bfc3e5d156bdb35ca3f7287efd775f712c11a205820f728de0a495b0c90cf515d0ca7fee32fd368fefc7f5d618b85408488e98377bef966184af1414c1feac7792c8b957385d20ae551b50a948c72f13d35948ea6d7cdce9cfbf73e1f53c06a1c0954a192c79b177844cb57b8dee9474f83fec62d7af3384fe5ff982c02ad1de22407f2c500c8b677890dd760da8f4b8911d2e56465985147a2fc9f10210bc6ee353262b3922d3cd3512716e69b2a940e98054529c521ec3cdbe4fb5d2fbf1160d90eee6773b62a6c20b3b99bd7990c467624c823dfdb7444bd2a689edf798011bd7afa66290f2a4752027f3f600f995c08a810678e599dddfc72d3a78879c0e20f81bebf39a0a907fb72f14165f65aeac340696b6184a982e4a20ae6770f6b3b50131a37023ffd0888d17b1cf5ebaa5de5d83493e9d141213dc50aa1692e78e255e560a728e2158af84597be9eaa124a14fee1c3ad71076121a67fd7e1e081e4c6b4a5d36d88f8b88f6f5acd3248a5dac2d6e68abaed01830822f44e3fef5265837ce8b1efe655690ab5bca4bf6a5371c110116d0ad5d25195a48c2631425af464736f2cd10af7fa92a9a71863268dc1329bf0d5e4cdba61b02a5fb7143f2451b676dfefe68b4d1c7ef083e97b8e15e5f1284e177e4de50f0a36d31cd1ffa637f4275feee4bf65896d68bca73ddba911e5fa4855c6c418376c6d2ab1963402d34f4ef80ff67be27c6d31b2a6eef50114d72bf2a14e6dbff6627b5f25ab85059a23eb047b0148606f6886f0a93a25ec12be66650d38f697f70adc100d9a709191f582d63a94bca7e413d82c311ed7da7c97ab68b2eb9a5c710ffec33c39e6da4a1e3326e992bda69b6506df504f07a1068bdb378d8cb88157833917cfa0f29bdf30ca1550cb16478747a7ed02b6431cc57b5e235aac4dbbabf701442b80d3f2ed940da8c89e34951499b3064cc1eb729eba27a218c98570243ea105cb45fa95230964366a22de4ebe503a69774b119238fc0336f489cecf5b138f2cb6249de65415fd0fa2af08f7816f18384056b1e8899b6e400eee907b4ae40079046e0a4c2267b8bdb1eab0604fd2d9bd302939dcc3e68bb700f8dbfddcdaabd3406ff472eb3d30f82dcd63a0393f180e926b3d4fa88642854e8d6ae395baa52598603fbb34f51ea2335c25f0b8974eae0e0f8b1b8c3c008a9df904d424685d63d1ee0d5ce04b85686ecb281e3b335bf5233efddd53a13e12586f224e02956329528f4ce3cafcddfd31f3f6f1fcb73425fa10df7c749bbac828f1176a32c0141ccfb2ce2f366f82b431ab1ddd2c759173598aac384c463c534f2fc13c0eec80959171055288f45cf5cea602eb511490fbb6db1335bf386e7abbd231a0e3cd80b56f5e20f3ad494164587157a6cbace63f5fbf5d6c0280733f72ed779d518b3fc76d1c07472949fa29139cd346c689065113dedc5a0c9a782762d67b4153528f1b1d86ead6a58b44aa1891f2945a946c1735d4737f8204ce54b95050000000000000000000000002f286a5158e978c8c9dd040d6279714e6396572a5c195a7861ac5507c0dab8e5f5521cfbc777d83c6e095663e56c1e3ac72f58c45a2da0aeb5e96a2c0fa39068de4f0d9946dd72698d2dbdb8a8fc1486ab0f731f2b096057d6703458191b87e6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005dbd3131cc117dbdc66e6ef8ba9ee605c9df11a67a2303a569c6ebf3e52b5a31288a6ca7041ebddb04fb2057fae06e478be7e62a317148d4a49480974b0ec2b92c40452e0689e10bcc7d89ee81b8b4b40540d6cf29b01f7551f4a8f1388d09857601fdd2e7b753f6067ed0d93d5cc4a887d146ba770fe09b0f6369b406a823a6021d8e699d60f9d848cc54c3e8b45b717dba4690817c0c67cb5b09ecc8ef209bfe031ad489abf0bdf08356e7c5695e5cb6a0e0bab5d16c9cb2c4ba2725eda79f43c10b05d9a5019c47ea36f595cc624a35f63230b12196fbab46b75c69cc87a5d84a072e7af1d5bc501cf24fe9abed3127edf58224b9545226bbc7de7ae3e78593935b0303888eed8c724dc236598853bf150602a0745cff58753952985eb8cb23eecdb5021b08b8237309c8865e0abf39434ca68646a3372109f87e99b8e024af3ffadbfa031bbf00cc5e1e8cab636d0e88b5e9c17b5222153164d67c60a3e40b1eab1a2372020725f88da6f99d11b87350ca66069266cec1eaa45fa3f2d84a94f97803f31348021efbe3a132568b2fd8695290e8a4592e2f909b03b11986d3b1d3915dd115d278198b4590dc5f11b01cf8437ad125c7f33bf55b098b9a32c3b788a70f4ee8586e4c84333c744694b76023b6963f487066c0f57598adda22467c2f9797036e9418e89fa774798792468b2dcd22b23a9a8d9162a36c1143b778f3cdd6f67b6e8a825543486e773dde76466cc285c9a8c6e75a2367154dc9741bd7f994f272b3fd34ec66eadc32ee944751e62aa58c0fa8caf13cf4acf1e65f98ef8e1791f3bdfbef932ea2e841bd2c38727787266a68b6f90858780267e0aba8a2e9c3bd1e73be54096a93e8f3342447f0a8be6c57716b21e3e5a4e4df7496832495ea57cc2e780482000e90b6ba7d9afea51a57b77ba2cb0d901ac98d11b71c007afacbfcad7e4c9d3ed3cb9669fffb5f9e0fd2f8caabc58d60beb2ddd7dc60133b5ddf7c4c60625167241ad4d5e173bd4d13af32c993403586f776b5396a4d06b7718e0e8f9ddf1e80fe518e449ab7bd3e7812984f1f60d73fe169affdd6c0c743b899df1632b7b7e8808b1b91e6a53e1b4b7465ceb04041fe67af7074568407d5d544d300d68d916e595ed87cdef2502da2b1f7c8890d1d5abe773522873b77ac5e30024b7768b304294bd5c78db004238d4fa83015fb72f7186c274cfbb2d59c6025c12e8754175830eea4288e97a4b97a2fddd26921aca0a474273dc07e54b3fdc3b5f6d32a9b8a212afa6eac19753d1bf4b26740652303d1de66dd8a7030b934b73015f076a24e712aafac017d231948a1181b16797d81a919cf0872607835176cd948861287d608f59d179b39084482db6af96b9b0a0136f0e01d53f5b6efe79d86affeea7653af1d1f6608afdef4e80da024472c3d3cddcb4f62f13466bfd1a26666dd95ae4495f2f39bc2b61e7147449c62ce462addc304c765fc518f64dd682fd9ba93be4efeba7ecccc5dbacc9f7bef4afb4205987cc05eac9429ee8056a73cd63ca8a133cc613ce1d84deb8e07018aa3c07939f47ba990cf711cdbcb3bb477309857a04f1fae360ef86846b82c7da3e7ebe57ee23b44ab99b9bbe645af77e16f010e91c2c20982791576bf5e6cf4a431aefb8170fa19048504a2bcd5f437ce08935d3f09dc7ac1231e61ffe95c99d09c02148058c04c5c7b68ed2c6149f7dd925515ad090e6f750a049663e148ccc28c2e2391a3f780d9e25999c2d223ec88ea8a8108773d2be4055ef7e23587c1646d241f96022d40dd724df56cd20c2b947debb2e56d2dbb1f6950b889dacdb715e42e83dc307816a77751021945879e3a390c4fa571e671bbfeb8d2c4818909acca34b4a6d5544014b326cf742924191d584ec581a0f74a216200c82cb422524874094a5e1d3ef980541c378b8d4335968c170a5d734a326be56ceccb7863ab89afe5319be1f6fdcb0eb88cb097998afd174378eb63e65c28767a01263a8a520ae5b881ef3e5e3c08c42a8a93b9c9642e1444580c3ca7ba6f1cc5d2c85a78559cb3a6f99e055bc0b096220fc85539bf704adc8c017961c21d3349b9206a7ec494e64c8df658e3b5eb9b9dcc0f9aa3f816398066d0418a0e7f50f9903fb139f8d9d468928af198f7e2c224b0e95e6f5519a0120797c676e4bbf3b46fdd450fb6dccdd20ba5eb4951093bae496348d79f60a6b45af6f166c1673cee5a228e36fca50d0a19e02a9c5c1f3f9ce68e9033aae819b5867874ef3be6c9306da57f41bad2c4b366942f000000000000000080514e03000000004a2651a1c3f47d7a1c116e6d731f82da6e95c46263c675544d639909e34ed0ae8641ae1b9dd19e2853a0642ae40f7723b389a5cbd62a79e6cd19a5db98cf7b040e3ee35b651121bb2e4f22cb546a39b59aa9835285dc14b8823c949ac3f8cdf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2cdcc587c181ad10e3530cb8bbe58804b323f0ffba1b0e79f520c6efe5d479716683b55c25b5da5b363c6b537718ea890ea941a6eeb509138e2d92c369b05e71c4ca01ebdc2f8503217fc55154263e372dda8f617b244172f33e8c32e9a0cd032d23048e4bf7e3fa6678dbcbe313e29265a9fcf4d2dcb0a703f29eaee2257d902168b91fb9e27422ec6e55ee8d2a21d1986df424a3f3a748041fa29d2fab3b1ba0200a065593331c01be9f1134ff4b9af38bbcaaa9edd8e42083613cdc07a83e8070a0bf4f484c6c217ac26f0c891363629423330375e1c02249ffcfc87967971f7db0e9e9fb45f6a9e04195d6e538f103c818bd8810e848be1d8d3d0ae5e33f4fafe03188ad7dd491b66134d1c44068a2daf69b9bb4c4c628cef85fd1ab9f3574e11c0032e2d72cfd38687be32852753a95d81b10c31139b8aa04d828f99e2074a7b6bdc03220ddde92c94ad051a16e626a4903316adcfe4ed5b2006c34ada70f356bbbffa030e640a40026e0f40c5a83f3805d1bd31797751eb5aa362107530b70c7e0849c80307740e524bb384d96035ec1e11e937643f895b639f6f382e286bd655f1df3429a3b5efe3373a12e393d592bda471d2fcb60da86e79027a91f13f5ecd0df17ebff23fdbb4ea92bcbaa8ceda642cb10849dce86799c921b90dc1dea070b58364a762d1e0d79e7edfa1e89b73986ef02185503fc0b8cacecee4852f86a952b04e5b96413202c3d7d4fe881cf192f4541b3a5e9ce41013ff8dd32bfac38fa4ac420d1704266c429ba3d09c6394de6e6dcd8ed17da1d9ec16b5f52350f2f9b4ad595d8c11d7a2397ac6c64dfc3c894550cef8922b3019553688a663b66400caffdf6d41ea99a39997c701527d9cae04dccc4174dea47da8969266d0a99f21aebaab021be02c4048780b0aea1eb7ee39b1ad11afdf92585688aa67bbcdccdd720acc84f7d470f71d3f67a4f5b522977bde350f37bace8b0c9520c38ffaf37073b279802839d4d696e79c97d60a2450223473cd6cc4db8687e84708cb8d78329954f587517f1f0aa28c49c1eab621cf8bd1c5a3c0d408090d68c0a907c4f78645d0b0ef3ece2d2e1cab0cf8e012231e89ad6adfc9fff6d1c023704129065ed0bf736c20a635e9a7ebbb354d9185cd87216683cac25fa131aff491438d9905e19aac8e48dd1c3aa6adfdd1b1226c44e2a9d08a04626ff3fab35e51187c78604fc43cb53e934cf6e5c93e45832e3017ce576081437ff62925fb6192b010ca06dbf1ba449ced3c807c79c188cc04bbee1d3ab44201838842ccee7f98b40234d85bc6ae5a7148b8b6a59c49bda7e322d077e6eb215ab87b9323ab8781167804fa72b6c05781ed536a2618f8684f87ce2f8d53412ef310a689c541bd314dc7ddad9776fffae8f165f5cc536db8925dfe3bc04285567165a1fccd8c6565b92277d6f492ab34514961576edff18df92e0a7e0f7e9167c020c219f6165440d58e9822b0381f304fc56df20c9f7361d5b4a3d074c0bfd9fa9043fc71ceed95b1e4de5f4658c71f40e89a7f23c951f3fbdb39cc9d8b3bfaf5b3a3812ea90f171ce1273d9991358bf06cc3c94077709e9ad41f8d0d60be4d8bb23f316506f75bd8d42ebeab0a69d33400b76208748a6b12a7b037d8f8bd2cda6f1d4c1c9f2dfcd26a537ccb25b66757adb223e36e2940a043f9af77173bcc13845bb783025ab4dce3784cd96b4237df551f9287e123b3dfdf12738e6e282eb2497adc5e44cf410bb6f1dc8fcb925221de8055f2851caafe7ad7727850d4d40f203b1835310228d95976d204b44e1889a7bc846e3edc67a8b45ddf651b8a69e7c25613ec593ac946c6948ba4a5cd36f10152176561e36ae06bcd115487ac225edcc6ec8d00e1343fda8347738ec9a59043f7f51b53dafe28c8e16596152916e1d3317c951991f5faed961080a147096ea196dfdfb5f5d323ff70ae3afd995027c5844f8215d946bf1be9c47e710aa7aea1bc04dd3b1d7bbb2a0bed71962cb67e94d3cc4938a97a1607cbb926fd4a2bbea29d046e8a2028fcbb644e52c148dcfdac4238d9f46881220ce2282bfa99b2c9c151054486efc98e106e0fae7d224d84d0288cdf17096b52ac968fff4b157d03dec742232fe0898353e7ace936afa1d7cd1b2ecd14ee81b24a1d959ad173b1b09ac25d007af75b2c8f8db9fb9f425e862cc5325db2687511884c2461a0be31e1b642cb83b1b8660f5adf0ec807e13e563ad9a1dcaf4214248e07990488267815ad05fc537c8b8f7f848f5ce97328f05b9906a7d85a857d88db2e2a90f071ae9d4eda49a62fc7fbc530d421ad1657df8197e32c7b1474fde0f53aa3cfeec8827e3cf35322332ef823055cdf8ef0f338347ffbf7be1185d3fb62fcba399675e23dc458b12e8b1911c351290f041e19c1db400c", "650000525153", 1, -264916277, "51db1a19b35632d7716a418ebc120e326eadb9e643bdf465b3f0277710780052"], - ["5b3e4804012b0a783fe8ff043c6ae09772a30f8b4b5b3acfc66939b2c7824f69e11a6de66800000000003b0b672d01ed1a3605000000000363525100000000010000000000000000061654050000000011c8891109be406260037aa1e9a6d7bdf65d3ffd4088f7e950ea129b46a4a6d4341e3373984055a13c4753cb9222d9abaef5ebd2cfbe1e7b42337ebe9e08e38667b9a90c2b5f89596fb39b8c28030d57cbe98507615a2a5046d33963e779fb97000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d6a1963fa8c598f7dfac54a1b403f2b13202467308c49a25eb485b91715f3f38bc12e47a79f4b2903169cabf4c7c4de6a4907c79ae23aa02903459a3e8e0f87203ed6b04b575aea0a6c7391c851a7d2b6940a718f29aed139de7cbce917f29ce0db6b140aec7936d6262137b3490a8c0ad5d8ea8271ffd8d050f0958a5bfba2022305de3aac77650aec9d0aff8738d6a74e38f266450288214146d664ed3f9d6c030e09c7746ca24a3c07ee516567a91a5885b380645d072e123dfb41b5603e9cfe0a1ca538f9978b67f8f22ad911d02b74dfcc445659a5285eed259f89a9764caa840b0755299d56bbd014d08e6919d984b949e8f7d50d4523141bca3f774be13f03032f32a7a23ed95c5b3e9b8c83f1474f6173cb8a40f6430b6dbc18e30472783f54021a7272e7ae56e50ad084c0b67f1b37b54110080be7e7f929790092cf6d579d88032ed446afd634cd98cb07893ca7805ef5de782a387b27cb1566cdb000ada22d430228ea81b3aaab56459c9982a700259c751d15619c93ead0b8b75c715705a07e53031bf681b54f13984bc9f1b4f5ca7087bff9d1bd9cb55b8cb7bcdfd5e920e03ab368f734bb26eaa784b87c2cf319392f93e3ec90c35e4bfada256c52bac1c607709a7edf702d2f0d7f6ec6c531a5efb680270565b80b65712ccad6855b2e81113d1696e8abfe88819f87fe05487784b9bed88e9da16110c6f1383c4f2e28c7ee9cbcc1a2a7e043349ba3c2c43bffcfbf3209655b131bebd28ea9d15db9d1cbb8bd09e1e07b49c3e1663bbd2e22c6d69ccdbbd7b146bcdfb4aacb88b482cf6a68b975d74da3f1fb7d30438ee255eb113c6482c72b6fcc5a3fed4aa0577b3c7c7992c33c190f8b211e835f5a3073ac540e74fcbfde4a29a69547d38f4d4e51a3f366794e89727393a5acdeb8b534c7014411efefcb5361836bb3449113ee8153ae26fd82ab15f55ae0a98a11b4c1a23954299ec58d60c344888a388a0c7f2ec56178ab6e180a668f60cb56ed42e12a51f4c8e2551e327fcf92536b937bbd15046194c71c183c9df93eb2c7ea4b67a2dda07775b8ecbe208a347251f797310074ea25a0fdcbbbd798065951d1ebc8585800345a09db3498fb4d5be6a522985589808563622180680c905f21141942752c6c9911fd5ba43ad797bb6460c0e34fcd161a7cc79344ebdc54cd5b2255f82fd136b907988662531f339e1bd9b2d9ab6508ac6b11fc6721e3bc8c8e333ae86fe77bf8a8831d620c6ea044c082c3e7251913d559fabee8f783833c7c29e79c87d4f8c49480e7402cb9076179f146e31cbe9f2442fb738ff54c4f727c3786457938b3bef9bb4079a41a845302590954d12c3d296077e617ffebae3064a5864b5efdee0618397171951691ab716a4ea7993aedb69d822235e52f895a8103f423b7b55dd397901c0bb4fbed677360ccb67ff4d78c19f874e6f84b5e399f1002716dd2e8ba71e25d179b1af2f5a4103deb921b7a0b9ccf8113787cf40988dabe038d7183949f9f4befb4619c09c08046dee1394b79cffae00ded2961f03df45b204000f670980f41452a71b761608efdba19dc08b49377c6dc7441cdcb80a9786c34fe34fa5fc0d37c9e7062d3567ba6528dddb2ee9265f013f6397e87b1c212ddb90183f83ae2bc676807c51bba053b6a0e0525c850b16a72b46a9d07df2242058a69e4d0ec5d5718ca16e2bb0f7cae1dbf6f2ba8e956a675b37bea937f392f3737784f3334b04e6c3d192b32157691fe2a7ac4b2c26db504d20b1e75c07954e03f882aaaed673cf5feb20b87e5aee663c9779cf653d8751b14038f7257c673e3353c0175562aa563ef2c78365b4d161700a1d56863887007139d8faffd60f32139647b63eec9e7149d7dae1e15d88a7702d813463d769d365a9e894290e9e1af0112aae709b027cce82c90a843c37e1c54bcaf70a215f1f488beec32cf5213159a4134968756bc2a81dafb41ca17304ce11a08c09849b35eba33f5fff8223a6cde05e4a44ed35d2178900d2c20c741b1214cd76e068b19a1a10d8a623c402c060d90bbe30a9dfa5b38cdcde0828ac49d052b9aa73fb3ed33a1f8ba64db77c3714ce69e046d54f51657309456b4245e12c3b45a815d3d8cd66f37fa65c2abc98f46547dfc5d436564cc523f270cd1b7abcfcb984bb5cc1512131baf4afaa423a672568274a6a2b3cc2e65554bb4f877cf79a0ce9a4a9ab5a113641720961ddc4b8c169e64c3bb144b13116777607d2fddf12222af218a540b9c863319f4032576e7fb2abab150367c96ae371f98a77635798b9b53b71554af87eb383eecf0a0ae210ad19f697b972c48e0aafc8d74c0d9908c21a7b41fb4d08ed622526caab70a20188fcb2034548aa122cd5d7a14679c3f1df6976f39bd56f2776210deb4031607cccfba0505", "51ac65", 0, 1682244068, "2905c9c19a7f29b2726ea27b9b2472a5c48ab5bc72f89b15cf3a3a17c1d77da3"], - ["130120f704bcce5de6e256ae6c8ad48ec6d9890684471e628f07c84cb3c664d60ed9952e880200000000d02b9de2768d81127c1ce122873340937dc8ed4ce32f616ade8fbb051afef7c8cfd1b98e0000000001510f7ddebdfa2bd28b58d366df485be29dff2947a4bc104d98ea6bfe646e6c16659a4075230100000000ffffffffb6785f8623755e89edc5c55c57731b7a8b865e8c848313b86086342813e0971b000000000751ab6a5352ac51ffffffff045911ff040000000009006353ab6a536a6a0007fcfa020000000008acacac65ac6aacacb7c7460200000000095151acab0051ac53ac5e68a0030000000009005363ab6a5151006500000000", "65635363005353", 0, -1353169174, "ae724cf2f77ddbb9e59f8a5ea087defcf7b1fc9f36fbf6e53e81b5375e363389"], - ["31fcf509025cd68ee8b66ffa013aaa9b4525994105aa6024dd525e5eab8b1716bb2201ccc2000000000163eda22798025677d6e5d509c1cc33d3c7672d1e438af76d1eeaaa68fb0f831bc0d31129ce000000000252ab86a61d9102b4b557030000000005ac65ab6a6a124688040000000004abab51650000000000", "51655351006a", 0, 107304899, "7d2ec9fa3037ecdbcbd0f42c9689d91236b91a8ecdf15ac9bc1c4472a35a26c3"], - ["fdf3048d020891e4ca3ab4f79b360f02a232ec08365159f1863b2231cc39b1b0bbbc460eac0000000007006a6a63635352ffffffff55f48dd0ca1bf75fac9b045789dc594017fa069ae095728b702cf4b93be29736000000000365ab6a9c301d0a02178525020000000007ab0053ab63ab5205a45003000000000152f5c7bcb3", "5365516352ac53", 1, -174574022, "fef0140b578f7b198cf3ed70a8df74b2a947b297877a49e742395087469a4aff"], - ["674dd34c01b9fa0e4d9a3c21e921450ae84a24f1c96eb78f14abaeab7e4ea2b6800a4e2d1103000000096a5252636363516a00867cf58e042e91490300000000045153526366464d0100000000076a005165526365bc247a0400000000016342b3fd0200000000026553ba3fdbdf0100000000000000006f032401000000006df8e41ec75fee3a33ceb86881b758a537b9a4c69612ab7005cb9b494e5b55edff7c12a44b4fa027a745e5944112e67603a470c6e6891fb8129ebcfeec38e00a9339def532b8900a484401b80a6017995715528a9d0e7f545e566d751c1cff740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078ef8dceb6992ecd94b0d0ef2755aff4fcd8992ba3643f7c8600a05d2a843c0d838ca5185a327db5b44238e87f4a8d9c618e2435d12d95d623e506c8a960edaa59b90188b220ac41d24784c6f8b51ec5081982ab6376a6a264ad8ca6540911b459f119e8f74d507529cfc092ec2886ced813e6b25041de02b59ca127bd3f200203200414d4f21800493ca69f138e13aca30a9e0d5ccd509e56176570d5ee6651f702008650318461bf14e2cc38e6e47ce7a835f049e25209113564874f980342ecb60b174bd4f3374780e83a86f99dca5f7db6053b4ff499418c04fb4998932f3c440f061390a8af313f601e3b025916eb7e571cbcfd816e63a08b0ca54aa20e0be67e020e48f5c09528397105f23aa6f1f967f385d620d9e47e9468482bb4e1438a2a16032332851a57443bca011f2ba77ca7ca7ae39a141a57725f52cb5406a3ffaa0c6b0214a8f73b9f9ae615a2aab28c219d1a1d5b6c828224f7e30708223873290ed5fa03149d3edc4c5a89d9cc7050842c827cb84bcbcd2a88da0658c928b4abacf33efe0222511cb97567c08499a885369932a2d157836701adc68229f489c72014f5b0389d6d8843344116022888f70957bbf08c9fe653dfb58268edadda32a5c7fa57484de8b245afce23d2d054f2a7f54d4592bb48d37b3ab9bd9c912e366e2ae7f0bce02b61b68db78fac3a34702694c18bf7dcb6cf2d87b63ec4f9abe614c875014ea746f0234e50313a219e9da92e74b997bbfae5419d7997ca68f5627eebd81ecca05e064a71e9d17179bd583eba939338c6da8721b53afc48b17cce7fdc70a9694ac11d4103792f704d0738c9e0875d3a88ad85a23660be7fa333f5ebddcb3d7142e96ad5cf2dc6f53992cd90ca4a874a5f85cd5b6a58692eb0e7070bf5b717550362a0ff2e3a45d7c1f347b5db75c3b9925f1db20b02159d78321092ba0ff58300333f095aa1449ea19365a4f0ebd404f9d1c438520a495720305bd3c257e8824a1d419cd35edfa3fe1f31dae16373bd2f24dcc4a7c1f3a948a4e4bdf1d207c44c73f7ac7c2eecfd03f494ca6f10ef0e48571e5dcf816c45d9261adfc3eb5763bd79ce778986b412d1ef2d6495a0cf3a94f06e7a679ccf7261d02bbf2301759b162ca2ac1c98c347944c366d32eddc6983b79a12285e7f662fdf6b7b02bbd68bf8c0e27443012f3c488222b129692a2ec85e02ba678f19550a392c72f3878d62c4bc7c667865bbb5d62f6ebc2f4676b5cc32e797e83b915220b9d60319e4fdcaa9ea3bdd532841bf7ddcd4b079f77ef3edbf04a78553742acf8b60d1f8fec16874376425b79ec8eaaebd4cc7871d1c28c7e782ba709d957a36cf9dd7bea4f486b603bff1ecdf1fd54e12e444f2eeefda3616a23bd00627f9ad7e714f4db8c113e6e68132f74195d42dcb5930611b86b13781699e6c6d5fb749c8deb83f524cbf7e6e6e07e702595368c0b33966ad99825d85d8fd000fbaf40b242bb43531df98fbdef4b754e86cedf42a5715c74666611e0fd41dc6b6b0f253583dd086024af1615bdc181a35f759f353f33e982ac22f4af6cbeb6ba249d6c3720c9dfa603f73749a79f62acfe587543b75c53ad6c1e3921ba0ad95a24dd62df76bd91cb9b93d706223bd1613a779c2079936f4eff9db59790987dde6865d312bded8be486d727034b9076fd275c0d06419cc9bafe8b1bf548992517a03302b0c27f1f405e59fc2cdc732ee65b9bc66ff444f2e7203affe29e6b95463313a9111fbf50408f2269b37d630293f80d12a44565326bae4cedf51c5f6d1e86e90b0e2acdcf26d75473c03bd889e220d27c1317c417b3ad3b63405b72590c6951424e4453993cc313d01bc2cab908aaa0ac58e48231338f9e04fdae1085ffe1f3f354005a425086256aee28accc1f5a44808425552b19f8fcc970174691c9fd8214a583481cc75484bb92e35194cde3d9b180c0cee8125ca41d3e32640afb5f414fb8b0dd0d0b786bafbcd3e3864f6c9159413f43f2097fd251905ced01f4f27ac6e08a664ba0c9ebe9f53e80bdbe4dad4398918d3a4f35836a2a5a023c91c9580f3e7e3263d5d7eff10e266450735411ea0ea33563a6012e9524450118fa00d982919ea6a64f37bf72d9bda7feac818911be520a38a6a4da2ccff8733c8834214556d53682281438cdd1548a778e0bc697b398a4da5f7352a048521e641fb0c0635374406c2ad94954b4ec8449b089c92e979bdde178748e276c7bb43721542845e6df6ed4216637b2eeb807da68c1b51a21f4ac421015ce78f69122e018dd1308beb155f2ba393441a5ba72e595c2320741043c87bc68ea0994d336e065cd96114838d918b09a7308e7b806ca2d1caae1b4016551913b3fc6b59876a44bef569d74f8c4a280248d4241943fd3d080a5741dd236b357b96ec1b0f", "5353635351516a", 0, -1179814581, "cdd936c96410936e0176ff09047d43ad7f021191e30e25cff995b8a0c3e59d66"], - ["b33630b8042e20a4c471c2b8a200779767ed87c3b963d3ef784174e846fbfa8ed4a1f92d3a01000000086a6553abac6aabacffffffff18b00cbc134cb064360fa3367fa435ec0b4ef755b3285f367ffdb5ccaf1f35830200000007655353ab5365ab5daff9c772a06f79c94050683f875d58004964dbe5871df8d93999302de1003c7304d5e80300000009ac0000acab5253ab00ffffffffe47ff817a1915d1f66b17d74c17ad595daf56ea4d74924f63a2f1684ef217eee0200000007ac6553655300abffffffff03e4948600000000000551ab5263652982f402000000000553ab6351653d06ad03000000000852656300acab005200000000", "ac516aac51", 2, -2072248370, "9c30b43f14ae024b160f772d61761bdefe081e1613fb974948c25d200654ec21"], - ["1bb4a88d0491c2da87db48718e23a9ba5dfc1d771da725814fb45c344727f5c12fe012aaeb0300000000ffffffffe72036f23e430851817073665edb38a80cbfb9695d21f86437c5cca92334334a03000000040065ac000f50aeb307bef0476e4286a9b69f17557275dce096249306c57d3ee7e43e1cd3278132900300000000ffffffff978bd571a89c9dfe8d7d68de0b132c183aa36d219ac9e0fd19933207cb019403030000000263ab1af052cd03fd18d2000000000006516352535251060c65040000000005530051ab52594db80400000000025100844fe664", "656500", 0, -492402049, "9b9a0997b7e776a538d70113109a7e7941c2c3d851e02d6660079a8e9f03551f"], - ["c6afc94102f11d2ce065e808ae5fabd8cc781f677e76a0074c31996dadb35ca5ba7f45366c02000000025165f4cf1b580d48d3d884e9a012ba93dec2804dd173e75de41310676cd017481b5e360ad0960000000000ffffffff04199a0702000000000663636351636a028991030000000002006322cdfa020000000007acab0052ac63510e3770030000000001ac0000000002000000000000000041a362020000000066980ec769aba8bf96f4c6c60b1a9b2a8fcc60b1b577f5590e8bf3080ae3baa37be6735c54511fa952ec45ed44adf53382b06cb9d5397d03292fbb02efb6be3a4a9d7d2297bd28ccafde29d1b11d38a59dcc69435a8489fc3e3092e4cf0019aa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000283edefb695b42ea586345abbd6796a171f433419eb6c6da3aec35d89f4dd864c9f81774714dafc7ac8fd6ea0d33e912b9488872af1758a7193c93d1a6f5444431231ccaaf95cf4f5a95a146b730fa44f1820018cf59ca4db2d5eaa7a1da4d542ee34b52ddbc547de22c131c8ca8682776e6b71fddbdcc5cb0bb939cccd80c65021d2ce73e38a78cb46a16a1155567ef85454764ee242a4eee63e0030289b31e9303297868fca02655ebca013c9198cdbd6b52085d504a2074b7234eea9cf9f9d6480b2a0a17ab76a6827c25d94b6f1db26d1949d8b20b7c46718235578c310db1760d06d167b66db203a3b260d4deb31be2ec32cdb53ab698f8482b2f9430f793c8580301a1d99585bba466e0a5354a16b76a978380f4872680d4ca30f91296c0b2a17903276791c0045aceb9e4229d7d0465135a63ab74f48b09d2e6e9115bc7ed39837203262ccfcd4fee1c4ab9a99aec37ec30e392911103f5d59ad5ec2b01621f3b901e020aa925e598f63d69fda3fec15865169ea582e80d53df599a79b310928a11cf590226063ec0af55535750212be350859c31bf23b8e748cb7befac0da4900876368de5756efaea685a8389c1c599751916cea4cd146aa2ca57f51daf1c9151de6303c5870c27f5c0189bd2ddc39e3a36702dba42f0b5ad51b6e74efc3c1a6e7dda69a7f0e121baa6eb9a5b7929f9e62b6f3e513ce1ab89b14eca64916398c2cb6ea630089275e98b544c97f8d9e92b1db4c2cf0e2ed8baff8db23e40071dcbef02138b62c1c3873f192599e7ffd25fc3534b80d1014f14089eebb4f8c943f9032f0b49c0439b57890d0bc86f88a28be3ab71451948cf3402395ae8a809a88993ef3c01b413f86d32f4bc474fda7d63db6d4baae15e173bf9565da616185ae333a1b618af3e9950726e96e248e73ed4b245a4777a6b76baa60c57f9508faa17ef7c95db9dfe4b7755c6b0a9aa7d1d7381329560b8ceb91ca3cb29927eccc45b8f133e56459ca2d997272e1b963a327d921d567b610699196e800c8b5343639e12dde4b7757abc93d319364930948db9c83825f96e64a6f0d62e104242388f3d668bc27f491a73d265ec0e256412ff4b15969bbe229936a1052ba854f4a1c85e49036885bb7c68a6f9de7a8864806a97813460a6ae3ef13950bd6de725357897fdc45b88eb4098a32de1083500e4c33866a85d52bdc661d72e1f2d589c5f3afc3c83a7444ac2540b51b7eddc93cd5c6a1cda114d0fe6686b90374b0d5a4e885c96820cff755d59f61bb129ec585427aa7b47056dbf9a47697ebff5627a01d398a56f9d37ffc0b850df14cc489547a31ca169ba33f6d6182a166ae654560ecadd97d66e6c9ef816a08038d4c803329f3954a399292bdc87dce708e02b3a37a5aa6ccc071f9a181a2c5299a6ab40cc18d1d1204de95358ed816d0c18c0fecee07c7b5b5789949a116268ec000f7a930f6c1c59b3cdeed8ca695cb7a56b4c414a0e9505f5f7ae0855550c3ae8c715ca3d4bf7b2ed06ea3076bc77fff10cd34c336f46c7f4227be71f06693c5ee8494d276b1561d048ab96e1714cff1ff54c9be37c438800c972c706d41fdb25711bd6d3862fb998ab4e37efd233fb36b4917af9a9acb38cb2d239d68cdd72b2f78469bc7364fa6539a244a7fa65ec8f7e2a6d29f97d853720ab868d75d15afb5ac7fb878ccf1896c92d74bc26f5cdfbd8e5778b19d266c0ea4e94f7ab1f5904c24fb02f407497c579edffea8d9a7646ea58b35a024b43ef065f5614762299b99df1a07c5922ae54490cf907975c0b93178667a9701688182a5d38a89be6d16586f80b67997427b77edccc8a3e2c41dd18db3584c98041651907cec1b182da71c1b26d9cc6e22a1dae7e441f693edb9267b929a3fe8e894a927ba82e475e2901a46073c6cf575c1a37bb575f81b2eb1531dfdcde6a670ab6abbf8b5f95b0e210b56ee93b10ac16d55dbf12eb9dc86d382a507da9ef08f508dc7bbecf5c3c13f89a9fa56a1cdc27dc79b484e2e1d2234e81e0b16ea4a2eede6404af0c1df59c99bc97723aae1f6f75a3d77f3090a65ad1ef8bd89b7d2ecf61c43d96a4042fa73db841cf840ac930e4ee6af722956bed97eeeebd11954cabc74ca661e082f1651a7c95dfbc8c356a300061402b78b8e44eaf39607e46af8f84843f3ced294bcc56935b6c872396a13adad7eee20f5bc394536581e41c2dc5327ffeca6a16b59bce81e573e0be21f123a7bbcf40b4579fd11efecafdb7796d2aa4e00376bea16b9db7e443f467a6fcf3f1d44745a903000000000000000000000000e77f4a692b1b612152ef089e52c48a0ea68d8fecad812b5dc17050ac7edf996b55a2c00a977296f44d87d0f572310ca5c79c66d9d096e6cee60878702d3e8d6f16eddf339e6b632b88ebcb8df144e2402068705d2a32409fb21c8791ea9d3b51000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f85fcf65aced049850b3f92871b1f951802ac707cc43502f6fd4c4b41863e39018639190926d46b8ef323e238b5029e4a54f2a77b2d7700a4de0052381c471713435cc423c599a6fdc35bf1d5fc51e73b0d11fa70ee4e8a1a9ee0d061e1c123d5938aa223e76d07e8db0cb87fcfae176f366c6c65f3f07e205f74a2c5561da8021811339698a1a60e09a5e02868eefec358f52daceb5dfe5c235142e071d3cd7703120f4fc55beaadeb4ebc7c34c6c6b8d8edaf4a76f156302fa2f545bfeec0f3520b2a165646f56cb52c7878b437b1d1a4fd3b473f709d4821cd87bc4ac3181f87af1ebc68c45af5fe9e723d827accadbc32fbcad5036f4e93c27c8646f8d9c75a8e021b8eaedadaaa4b0afe17593633dd40c3679c98c0eb3a8726aec89c7b2aafacb2032309fa6b2aae6f81cf249c33a364912c99722a23b161e3faf83b1ff2c8ae151d031b83717c475af145169b4059314f142c155f5c8eaeb5c4d954f16dbce793391b030a7df4d1cc713c7dc1f2a63626cb6b71791aba72e5bb78754fbe4058bcb81b1302174f17c4353cc4622c2b75d2e07c0af3098242140fa64a4d9d662953069d678c7778ab0806508ef710b6f03b3162f0a11b1764e117c74befe5aaad2669005b6834881ec872d31a8cd6da023d4e9f823c1c18a2ec65fb7085fe936461c3d94da4bae1c6d5c0309504b1915374adbe05adbdb04ccb2dc45ab9207f05c9fa10402f295ff0a5e86c3c8efe735a087d4eaeaa3fc929b3e7e2f6def44c90913d0c55ae5120fbbe68f5c7abb556cb8018ba8e2391e0c1c5843a2e06aafb4f6c8ad98c7aa626bd8c26b347daccbb35f78dfc08441db8f8afb6f2448ce54e48a11dd7fb39c78d06229f95b00b5770710e0ef20bb29a4761554c2346fc05d8a3521d68a99a0cd26bb3fcdeaf4dc488c5af519ea1834a9b7a47e0f7c6cc3c97fb84537a8bff0fda39db5a6613193d2813d566d1e66f72a2c51e021ab88111933ac33488e807ae9cae2ba9f01c5f1bb47bf94cf9e11cffb9d3335960d2e896d9808ae2f4295b71f4ebdbf7b6f691447d5880afd4c3806abed195aa119131b72e638e025cfcf326875664b2a7a078a5b0aa89e2c71a5433a6c446d9aae0113ef807290cd820f4759015ddd4b94c4ca6a856bd5342a33b8b1550d676a7b200d21f1c0d55540c2c2fe845ef1d5a1ad408b0865a884e61377361bf5301dfe179080d404b8dbc121070bb6f3dcdce074328a50b5dfa63ee6ae12ea3a1149a0fa7acdb31016551a9947ddcce126066302586759a15c688f54b1f7a99d9ba9414a7f591884948cab193d2f3fa56c19a5e8ff21df2b732dffa4bd0744a1c894e3f40df20bcfd24a836eb250f08e54df48a8eae54568faca8fb2592852bb8fb3ecaeac8bc5ddfae648a09fa363c544b19b4e59c2aaeaca96357f529564f44a10d68cdf971c25e0cf0541a1e9a4a31529dd0bdf4bb8eaaa4044d774a1b44cc32591ab186027349a284cb960a57187d08177c55fabec39ebf43209d1a8ff052c63320f15fb47fa758312a21424cd97456e432912e0af8533f97610b325b1a29d33c1bc1025b8b76dbd7cc14cbfb9dc2399f8256ad23c7310a09922448e79582c3ea0fe694b989cd297b49177e7c22c34e2b5c8f28e7326b47a571c80ca1bf93823c444d359c3fa792b06e12d8ec2897e63eea825e74ca24cb8a3219a6990d660b42b1dfc5c3f601a8058eabeb7e45df44cfe366f5c6a2f1508f425befa4bb8530d98514ba687260d53984ea9db684cf0c971b0b9598a82bcb6a0d1ed1db7c4bc0b0faeec3b20e91de53b54a6c56d19299ebe698042fde436fe2cb944e176d24c6b5df447d043d3335d8446cdd651d3bf98f5862822ebb3e75e16868a8ac2e284c6245fa1ef39cfc39d99f958018f91f876b137d802841d8365c175c1034dc42e2a62b7338c1c281966cf0695b36a8c4853d1b84e27b4b6f4b9ca412dc2537aac5fb26370ccead516d9cd133ada24b470cb2038164ff79ff264cbc88aa2720f478c3921c93379e1aca4c28af301567d415adc3338e6091d29d42b3c969209e03c56a2fab23ea3080a19fb079df036278ab11cf01da7feb52b6e394a5803a2dc53dce64d5e4d7102a594c78bc0b5c328e8b69e44e46a763eed0e6abdec0d7256514a036e2d9fd2cc9acc7b24b8090c9ad25e9738fc45466c3121f62790973295c9c53f7167584eda04a695d868003c3e47fd2b40f3ef75b87b8a92bc7616d1e4c82d8d384c73624a4b72c492fc7ccb5bde3b02dbeb4bddeda0b2c3fa9e0a475ef70da3c8a087ecce68ce5525f578a601be24304e7513b4a39deea80dfe8122ef9ed5b8a5ca2860ab42c1b234bc46b2662ef3dca7359419d935683280b9589cd921b2321a59c6df8b1a92b3dd110ff23a17eff6b791c4b5d79357313b3450b", "", 1, -1806082883, "136b11c237763e8a7550cbb872497f1950bd7e67db8354b838b9d697edb836da"], - ["78b5fed203eb1f5234d3db8396e396c2c0e4000909293c6aa7c12b69275826196a320f49a90100000008526aab51516a535288a7b6aff9f87f8e6c713820cbed15ee30cafbb8c1d420a24c68110c16216d567e388d190000000009ab65656a635352ab53ffffffff1fc42a64e2e7e2d7fc3207971eb479a73b8526d3475ae7c7db641bdd4cff756f000000000252abffffffff01b9b4f704000000000352acacb39edd6f", "acac6365", 1, -312222388, "8237040b585260c6142c32d32376fd81fc0c8e98c223444a098f4cf07ca106fa"], - ["8b58b786014ef8486237a1760a17a3c5959762eaf1fb5efee0e27f9c070838bba7452739e301000000095253ab51526aab636a34791ec60430357103000000000100697e92020000000000dcf39e020000000009635365516365525263af514b010000000003ab52529569d4d8", "006a6a516a5152", 0, -1006106332, "796735219f82b66fda07ab931a3bacd84ffc06418187543a67c51a0de263ff6a"], - ["2dc75244028614d2bf61b75c181150bacb4ef05fa009684b5855ff7f8a5bb7c7c1e9a0c90b0200000001abfffffffff27031029851f364a1301113378078f6a01bfadaa87c3c1765153c319abc441700000000086565ac656aab63abffffffff044cabb4020000000006acab63ab005108eb40030000000009ac650063ab515265000b7beb05000000000863ab6aabacab525359d2de050000000004ac636563000000000299da81040000000000000000000000005446f37a2401cb2b43c310725b7fa9b6b7099b6c51beae1ac35c906eaf0ac4b7b6ece7ac09c1430e92e58d379634a5612b60d578885b20bf83fec66241cc2b1e5f71557a881e8de89fbd922d74f2b99b81de137d08bd6c48ec76a07a0db1e3b700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b23925714944312662d9e0a4a7229997b9017b09ab6201bed75ab263b468bf2fab2bbe11207b7d1e48088ecb1de33e85fce4490c50e35e309cd215537e2b36e8c5bdac4fa1a048a1eaf2bb20668c60cbc93703301f038eca785aaf3abfeef8dc195ad5234d645957b8e9b90c603a9300cba24ab2a4ba9e5ad89d37a10f80cc6c031b034ff01e0c382571b91d4925d6032e72939de9adc6346da88a63b1deda9fca03057f7e442028b7f952c9248ba6a283bafc9e962388243bac150b3319521469660a1ae6f43c874da1773dca1b1eeab278f24999b3faaa4aebd6aea0859aee5dcc061b3356503df94e63790fe2c1ebe61cf58acd104d0eaf41178ad8d9f9f491d712032d90b5bdb2927f7615787fefbae94683dd2ed1a8e4674d608eb35a853fe2c10902212cb566485418767a09d9f7a1fe048abdc0ed24015d4e5339e46f621262abe202288d8a7374694edfb1b1e9ed7a4c6b9af8e38c51a545a6f018d6fa85852bb2a80313f570c79fe5c6160eba019f41add4458049248aba6e13de740d41ef47533cde02158a57ec35ce53c404ad060f467741a60db7e26f24d19034ed2b29c862112c26af96eab14a04b785b122f523cc2f1e806b3b2849bb7be6f2293f8f69df5afddd74f641531dc5470b587a7ba9ada0f747da6587428bc2c2483fbb441c6c3f32a59cbb3feaf14f34b1f718e5607f5db10eec18adab4f45f9c3fa07bc6c2fda5ed6354968c4387d74069c69899ff4397308b809b9e3a9887bc4d93d0ec633c8691e11e15f4391f817114c1175cc38958b7b28faf16709a328b2dfa452c55ac2cd7109cb1374bebd6ef220c49601ffc853fa34681f89c035dd9721bf922c5fff6310b30639e4ff1fc227cacbdbc5e8a9552da95d7f62c0deab621e1546c624e3778b57dd24dfedfa919e1e19412d38570553a830d777cfbb57f16f772f7d5e32d5762a495ab45e087b2b0e28a019551a997c9a98aebc7ee454951c3834ebc379ca53820df17b9a00a605c50d279efb77094a00012ae3df582dcf64efd8104e4b5605b12aed19c7282fc55bc22fd087bfb98db03a104bb655b2e91672c2d125f1c1c8a8099320d105c34700e2aaeece98a6b9485cb6fb8e375b9424c41184679b1d6a96bdbb2dc82424c21ce389456f60f08db44e15ca969000a832f572499c8605e8e12ef9767f236427f731b3d296beafdcebdb1a81c766bef98be9193a64f979c87221544bf8945ce09eb2796cbd80b319d8d176ecfb662aad8871eec1c2325900e96865875d569f5f38aac2a8e1127cafd51acd27840efe57f4064ee7e9f8ac65153442ccee46776f31a08733cacbfd63a01d587c040ec3927c8f9c81b822897685c3cc56b1e3c7ff16b7686140a78742966d07533f4e30be5e034cbac70ee197f5a2b57f4ecad8285359fdc0e3cfdacedbefc8bc8e92d745be9a05cdb79d04c488d2991d9275591adafadb5a88b92c22ef6c57996573749f15da60b815ff114500b3ad6cba4a785417a78ddd25df651bab79ee7950d6721bef191d3434159e583d5969bcea7567e42162610a917c221dee170fa5bdee98fb83fd7ef82533ff3be311e970983488e1855749ef9a245e3b141bfa6b8a2819c9a1374536ea89e3f178a6bb3dfd91ff0ce86245d4189d63aceb5a7f0c755fe41e9413e301c8ee86b250375b3713d935cb2b39cd6757b0e7dbff2af4548d2bc8f3a409dc8198f7e559532661eb33edb041d8e56ce90626666af9417a9570327592ee718da14d4ebe798753c7618a5fd8c9a13a19414fef7df7cb60cac532350a78bfe70c1460d7b967c55a8dbb3babd98e0060e1aa21d40961ea6863d11aae37584aff2e27dddc74814fa046bebf2e3882794fd71770146cef29d46fec4bf7cf6dfb370069734caacb1440ecaac02c364e6f06fd4b946e61ba8e97cac3b9057dbbb97cffe5c213d3dd5f418483b97bd020061bd81e938e274ca585d0550b40b49f21d2756ad94431c653ebe7c0602849d9cff71a5debb18718bbb8a0a8657398f5c6c23cd126e8d7600c0271f7971a2103c0a0db2f570b3ddb67581724b8e90c5a0ac94682e0e7680bf7daa4f84be10c4396e844c4dfae75a15d92cb4074468ed2fe88b9375f106f7d396e049d11e49c3574f514d332c807722371af2239fba379b39524d5dc070a39c3f208b52843307c1c2e9517834ed69f3af6817e19aedd3f3808471dea78ffe611658b7451ce7badd42013d5be884292a5e1360456de371778ecab798e0e3b2c53b8e65a1882df1f39c0feab09609f27a335535bb6030000000000000000000000003466672fa63b69afa70c13987de8e7263bd3690b9c02ce07e55fc7a29b56498006fe36e815365f2ff1f82afc89e764def8d114e6cc1eea5182cf875b5abc0d67f3df7a5c52917d4cc730d1bf6edf00138405d4288baf952c809ac9dc0787cc0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef2a9739c0dd688f9e77555b90118b8c4d7eb749db0b7605f3acdcd59ef0f653e02d47ddf218c1bb7c5da9f4d3624a55a72fb99a0159246d227aa064de05cb56e2fa5a64ea3b227b7a42f721ee6e7a04b601346f3ce283cdc99e45ea06fb3cbe6adfab91d998ad9c59acf1df7a1146c5f01ee0a3e0ff7eab778fa904af7ddc160202649723d2d138ed3d6b0d6bb30c0ff7f9d573633d38f7bfb15c0afecd2d349c0206c12cd59a752a61a783f880d8256475ea3579fdc57b7c7698c58c780f2921b30a2bb44053ae8638bd841868f930b12be85b463fe4598965937e86da4d36adf5bc0606ddd9c97896b235e9263e8653d9169897b8db0abe645bfa572644188c63fc0227b8b5fedfd24c045bb21b4f8df4dd7792360e3d6e1f492e329d5ba25e489547021b010a1d1636cf64ed07966d5c35bebe80028a14e33d4f8ef65a3672996fc57c030c76aa7afb345b772286af10cf4be7879f8fd36d2fb096917f7b94fbfb8d2ec903054282f928a7525bc91dd2ebb247ddce67e3259a04b088d308e2388d7d4e91a9022b4a0e9e483aa11bf448aa61b09dc6c060e15e9c821765ba9afb5204fb15fbfdc1ea8c314ec77f972e2c0396eb42da39d9020ad67b1cc2c2391f0f698aa6ee50cd9b874553535fddee4b733e87139a92d5998d3513400e276cc0631e7b91c35624ab393f9b8561123ba3b118ebed5b9d036797ce50f702b7a4419d151877fe478e29446bd29e1ddd05c41d179b69663b4ef80689dc5141a6cb5d78ccd45e9512671f9fa0c84ef1abc49369908ffa9b582110947c118928142aecc27a35d8b0696eb564eef4d861083e196e8a15af38f31ea580937303470558a64a7792dd7427939ac868196c5f9e85ff270603500138c742300a19ddef6b8336b6b16034e8171c387ca43c8d6a46fb9cda1f81f03b2367431fb21b770028bc49a921c0084374d71314151570b3b9b6a98c6a24e4e5f9eca350b4ca804d2993fdec19d30530537e97099ed36a96a585139342c36f88f50c89841b7ef45acb4da0f28d805ddef2027a58965fb7e79511fe3abf6e41bcff360b374cff3d70b3e1528b563fd05b6dfd480e84949ff68371567cd5d6833ae06cff4ff0bed664d14ed2bc26c8ffb6380b59858638c8ff397b9242765cc98506cb499ca6e6d9fc0b00fc22df125c6d526c76d8b10f3c5a629039f50295349ada63c1121f3b81ff86f8afffc5ad945d38b1bfd4dedaf1a73db76d0888b6126839af7978896437f40d7f4227e0fdad771828c24d4ed608b7d35065c5ff28ba09baf86c235935eacdde68bc5c0b9be1377f5e525a0d98238658f4f693548ee081350db8b1c85e2fe5da244b10593caf303d93d246bfb4414e83cb5b81e015770d64e05e97b23a93fa4b6f456066955ff96b96cd1fd727206ed6cb99d66334f107afae9463a945526c21a1f53d71a960bf84f1e9b0465a1b90cbbce7ff24c3ffd26334f384cd66900cdf5957dc87a9fdcc748df318458b857230a474541e4b75ac9e018223ee4ebbae49898e1a16b1b551c042c1956b9e09cd619a6cd1fbd7a0767f989c5b88524e16f0cc913d21632219ec581cda439370dbcead1c28e03c85c36ea7f99ead600586016e2613bc0cbb17dcb3e597860d710bc197c7345462dc8027417a42d38e71391fdc25aeae188f9ba249557e6e020d32d0f7e6e6ffbb4abf17d3536bbd97a51b03b444b98280b29bd96738ff34485154f963481f62c5ac12c5a842ea9b177f94d9aeffda870d17d608f36131060ecd41d87c9a519559f2bdd7bfe8d7fbf3c0abeba28fde0cfa042a85c023c954db88df77d45a47daef9bf89eeefa74b76095c12e080d1aabb96d7915a32963d0fabc37c976f5a3687188c2c50873540b07e0c79882f17f0d7e9dce1d58a50316be0083a33e366188769506b508308dfb91fc371f319ed1a1a0b5fab4b76ff5742c8b7607885622f8f5d024a0f1dd6e8409313ac455f3159f492e5a2b4d151abac9756deb80df1ee89bcd029f146c6e37eb86488252d95bdf11f419a09a866168da76511654f079dda825043dd33da13bcd914dcc69a687c630e1e2285385a378ccf9c20cf97bc0a656c391c37e3a27cbe5260e18e49cd1316672dc2f29a2fc0cfd2e567d3577fb7f0d5dfa7bd2683390c211732ad8a55cfd20c84694eaa356a993896bfac4e4900f5d0c3d2009ed0285f36158c132821b4c4169568e8cb4306875035fb60caed41070d55bfbab6371cd74f8b2434c4f80512b962f091501b4c575eff689d87916811b18fed6c283a549b93aac815fd2460b16b7241d02f42950e9e548989d30fee2a6826bb3608f699e4ddf05ac852ec54e06909f1972db8767be636df649d8d11545498db1682f033283e13ed134b9cc09b519979f7841557216a6995a6ac45be80d937b355a02", "", 0, 708405700, "7df168846b9a42e9f2b615e6488ae9c008249d663628e738198f1826f5d50049"], - ["890cae4a046e5bc7cde2f412d50dd0b4d0eb282f72fd99c3e36c70423302efbb5f237976d800000000086a6a526a0052ac00eeef743f680a75e7908a6a0413b78e896c697e97f4161d8c7fb28f62a7d72d9c4acc14380000000000d8f313e8f854e92881e1efa1f5f43eeda2e5b4caad58047ecd244ec218a82c598bf5b86e000000000151bf3e33810e17235fe948922a5cac027cf989cdaa5d8c594a06841087974999317b5286a90100000006635165530051ffffffff013a449f010000000008ab005151ac536351c3fb867f01ff879104000000000000000000000000af952889b7a361a74351c06c466d0f383185724618af4dc3b18d7cfd1a0bf7eb8906f64407537d461085a7b65494a791922db90e65a67aed827b308bd775cd88fed5e48f123f735b64799209ecdbda731078433959191f1d1a2af7d0a1e27e8e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000769cf5565f6754f0734d6426f7e302d24f5d2a3dbe9f2ef9fd8b8fe89568aa579690ba195565ce9b08801c72d912c92b014965a38f6a27e2b33b6c896e43dd84e2d689ce8585ba580d72de8be04143569ba2f5c11c98669de1d9fc7ecf22f1299807b81af0ff8ef07c7add772b024b8f3e03d7a297699a0401f52e2683806b140215cd5327a1591deb7d82f2c042e633ce3ab56c8725c06af258cf7576bb14c1900301a87963ef710d0442441c36ee98736adefbe0e82e050bc20e196bb08023fdee0b1c40706c7173d100b959eb6f301226b521e28987d3b7e159c7bc271e75cd3fed17cfceb32622094c718b299bad58cf744e9e65cfdf65722c8cf0b0daacf755f50216596f4ff1645c55d0ced982c34ed375ce6036f0ad4f4050d58dfb8dd416e1a103232338daba77efb9fb2276a9c72199be5ad46c195339fbf2d62b8d5d215f827602029f8afdae74585798cfaee27afe6bcf3f256027a8166d0522fd59750a6356f3030778c12c0724ba990db90600d79cfda870765bbe495ef5ae3594ca595b18d73b031062c79979624891701ebf41224cfd00ae7875102b1b369778a33aef2eec79b37c103bee5af1e6b1b8cc5b735604ee2a273207e10ec5e96229905311b9aca595eabd6a1ff5e54f7a65eceda22cb1941315becffe5eb030910befce7d5e153ce9e36d05793baa8ff44b4663fe0b73e28417edf70e17f98b0aa5c377053087acdeb1571622db00c4ed448c9ef77c85e2f01e52795133e602e707a2f3e5d906143837d7366eed6fdb7b07b6445e53e5f646f3d9035e8b4fd77f94a036fc4909cfd70fc21b2ce890cdb07584d44d1b948971fe22d6d5d668cbfc38d540b15140d4af31fc9df257c9fcbda103948a93b02f0c1114ec85a2c75890779cee5f14f3242c632053908a508f2c402e57325fc8854828da4babf20f79fb4c7a744d771b8ee52dab284ad9c5a386f253ad30d9e55419b5addab154c47344c4c44ffdb22989dc9de0870af3ca566601f42c72081995f55edb2caa15ba4dfc5384210c2c0c236fa2846301b509df221c0b3e1dc5c0d580b48a6263553f7f45c60189fb134e2603940ca64d26f12e20ec7725fa8fccb1d01b487efc5a51f7b6f89947457fcce4aabf5c1daedd92108104864d845612b385a58975718c11d4814cc66133a193719e1bf804846edc525a65931b7e2cb168246b5acf75f534ead657aa5279d854392374c84e49da62dbec50caed93e185eb030b635416480b36386b307ffd885967c39b0b8c5321ae6f67ec9563708013f58eadb791b0eca56bc201f23b8a7e300e34c8eb99f3653d4f9fc41402a8a0a00209148790a463c8ba59a471933f11779ba2edc8631bd52008482f0921d4bdb7dd6b1d65a8a497ebacd32bb4f65aa7e5b16c2e6342cfaf7c8b9fedd72fe37edfbb9e60a5506d5f5b504424be9dac4341e689fb9d2d0e0b7793476c4e1cfbb3085ea7e9672f342df6b506fd1a3b6bad80951c7031a46e8bd79b09e118ea2d86aaf11a8adf87ed384a40330a3e1acb0ad4b4edeb64fa3e836fadd18d6c2ec84a95594dfff68d40510f2c992227183b2ec54e9f3a6311a212262eddcd07f24a5b3a26c301041e5bb35c34374df8d123e111a60414a9611c4651108417b72ea09eb46d609080d3ce0243c0cdd0246ef9a0a2167f3aaeb5fe957a1fd3095619a95180220f94a837a75babe75e1c47773a2c737b447819f82b83eff9e7a86222a7be28114908aab608b7fee0b6a161e3ba8e2355395d1a03f6c0805bfb450051cab7cabcceffeb87b485241be744c367cd49cbb53ebc3b000f71eaf682c431ce210277f5f62666de8a4cfb75394b1fa4d534f37565a249fde13145ccbc556dd0476cc71046652584cb51bfb6c3b19362a5b1f857c58637a77732e49f0c7df9f8ce940059b25c1589649e1149cb6898e8973847dcaa753a84a0fe74eb587cea4091cd68c5ef1d421758428c9c14d8e2472535ee0055331cf7e989bbf1d4321c8799932244b50bde2347525389166ac21df4f5360e62b7ec1b50851df4ae870f1aea007dc2fbd10c7f91376f1b2caf6f89ce478b1124a82e9c7fd773416a70d72e98751829ae10f711f156179b7ed30ad210973fa0387f8872088d9e3ed7157d7c248a3e5e21d37c4abb4621e6dab13df4013f2a99b03785897f2b1ad19d6141c1a6dbbdd467d77558c4f77268df8cf507c32a554b87a523a03750e618958c3295676fbccdc697a3dd412877f4f0281c81cc82a7daedd732dca13c631fb0891b8fea90dd9d53232d719c8b7b0b1bf007b974d5937e4d8bf1f9a265e29aea63f8f2b34d6cb231cd359a712f0e33440cef7a7985a5abe9119089eecee9b43ca57a79c0de90f4be599270cd56e83f5c5d517e1aee9b0e6f0846268af751f6793e6b8e5883a3a903a506", "5153ac65", 3, -436933761, "916016e4626e3fc00fc2ec847824e9430ab883606c993e10ca848e8ea076774f"], - ["170dfb43015c127f3c56f5323f74a3ffcd84e40aa2be12ef65258db4f21e5def908d29d83502000000026565ecceccad016c1e480300000000076a52530053ab630000000001ce148b04000000000000000000000000bff1308c0a531d294dd10117992ff627c00b92aa9b6493779b51ba1243bee64471dd35222b088ea8dc89e8cf88322a59efd05ed0839f542e9813011b91b549a14790ed12d41c18ffa061e5088e798f0c8570de78be4f2a3a8cbf6e602e6783de00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c755356c00348d323a28fe662174c49428a5632ff3780ef038feb8e5f683d1ed3eec7182058ea7a011a4d3bc667b0c51adc62927192548cc767bc954130853ccb4f76b53e283e53bf09dac21e1ceb6d577af0820b2df6ed3fd4a385cac2b52d9258e42b10f893f11664eae709b9387a0d6d605da0e68dde0dea3b4878fa8aa6e022c3e4b6beab31764232f0beabf20e79da2ff0d46196f7ff2b929a8f5cd530d75031b2089ccd425421943b66d12c25328b2171b4af749195aea82626e4c59e0159d0b07b8330882e26cbe2449cede9a4081a72052bac410ad5cbdf33c8ed1e1e448970209fd6ef091234381dd6e5db506e9f4cb8fd2622153299b22eaa5dab117bf4503186663b55679945cc5cb4ea9f765e4da7bf13510e86966a9a9ae1ea9ccd75b5c022c2768cd58513c476b2db2b39716c8ea7e19afd25234c554f3ab98c2afeecc7502196f65d42edadb0dfa35e66ffb86c5f30af3373634e2c172f7d5afcdefa7643702225a71855abb733172836c69e7338960d69f9d72be5a8f04e2ea7c2f328e123502112bcd6117ae913a48280ae7033e034f0ae78c3bee22dc34aad0a6a09140bc5ad5e2a56068367d2d86ea6900d163263d503e398d2e552ac9fbf3d4e06c32fd27695c29963bc0ab0998dc28e887882cfe8eed5d7b3c4fa7d343aabff45dfad13052c00e291582ed2ae62d80052fefa35e625b8b3bedaa8f4102749f7f6761650f4975bc3d2728ec8b0f898c0341a22b08a1b0a77077096d2062510757f01e779afdfeb331a903ba351f60407e92c4567997a2486672ab648bf07a97848d1a6e6907d5e681398a0403edb7fa290e252f5817bbd4f69585516555e0370dfa74decde7ef927d0700075f72d252ece4842af8c3cae32e0e1d9675a1f2525235bd60f3a9875856a935e47def10973489f9a4c645b85fb5d599d885675c59a1dc3af52cd3bdee92cef8f1f58640522da30bda1985dd5bab0d94a30be0270e7f36dc435f9ed5df3998598730c98b10a2f6e01088c95697a180d8d683c5aed853e7b067e46c4e36d6880b1766ff4a3fc26a22c208a39ccab3ea7aa5ba3a3e81628e42cadfd772be65dbdfa0318ead025fa26550af16331911f5ec754d68489e3e6dfe6aec88ff7f5f0f6d94e375a50a0e6e6e1d5837dbc43ba94d9a1268652433d296e07e7fa2170063359e0cf10742bd87360619d6cf0a62867968087c24075c069c2a3c459fbe7e339474178c9121a2af454b03ea76dd60e07ed475b617cd70d80bd87e3d473c68297cc3d5e854a1e6c1640ccde390436bcf9e0f63ec1f2635845fe362b5787dbc52326fa2281db6c7a3b270a84b0b39446700365b94b480d0cf82b9c0f2e24d664ef51a8f8579d35a62fb605905e619295166439422871653945b84022d1771ed5d38af8745e364c9dbf9401497c6526aa197181e9401d3989dc5de39e1f7724fa5243153b65784f7e0ddc213efc4a8217fc7333f0775478793203145c4b4ec5917070178a12381155b700a89be6576cc585ae22b2bdfdc6394b0e042e551569113dc57d664e045633acc29b2da01db62bce6ed863ee9e38c0959267c9b44d3612d165189ac8ffb7565187387ecadd9889d31ca89fd3123432cdfbf015093e717cf9ae19b7488df5a7ede8c04c3bb7362deeef268b5ba0f8ffeec52c0f1d704ebc11744a1deb493aeb870f51561393ac6d85b8e37023b78408f3b7d4708cc04c216f06f29abe0c42d81b8fe20b6ded295d73e3c6cd68f1d1a0dce60da0db8e424b5509b7d7866fde84abf04b1a070c7b4b92d808d06b6bc2b52a080cf65bb1250dc77a702b4a81bbde034d84c9637537282d2b2daaf41edce4ca6263565733778b958461de1cb95cccb4e40ce220342a4a3ce491c59902ab904d076d5e558b11342af0a35710124adef079dd3d95e660f74209e25ff37e60a4b4bd6a4815e3c60e8ac14a8b98f549a70bd305748e5b23ef2d82b253f84252fbb158864bd216c323f7a46903674b78ac515cd0899ca6ce6cffeddf0d7eed8cde56508b65c79fc999a6f51e94f9a832c8a0603ff7ab0a24cf1a9eaf1bda53ebeed64a914c7ed781f745a3499d560e8c308466949502afa3fe76d3215d7c9ba20f427c05526406bf0192b8d942eb3f382afb3adabb525c6173a95a68fd71d3ca546b77464576d6a0d5960adba221417854b8d0539f672cde6023569374326e062eb19070c702806f9bafb4d82fba4f9937d3baf4393ba3e81d195509be32c308d66fb34b444deb73c4e2d4055f6fade9c9b6f7b786c5bb6536b403d7a946f2408f748846cafa8b8192a780d93115cad27927d1c74698f3a73aa5a01a66a8d59c8192d9da8cc11f5e8d81d41f98c7c141929c12e23426b2c41216bf95daa6558264796e0c1977672baf87622c23dc360fdc78826049c0c", "ac510063526500", 0, -542983293, "3c7bac3bf3f71360e4077e75638d2609d5a02d36618b8921cb0eb6d46ae50da1"], - ["d17c7839037cb9daf1338541333b4e55560539bec17a1ffc6fa979b60316b002095aed46df000000000900ab53536a52ac526affffffff5cf799666d14c9300dd41e4c0e54314a7123234c3030041bc0c8dccaa72563f003000000060063516aac51ffffffff95cf77861d4ee92147b5ba7fa4c5434f81d74fd4332345eaba88b45f7fa7a5ff0000000005ac530053ab8be290a4039c20840000000000016a6d5233010000000003005165b59720050000000003ac51000000000000", "6a006a6553510063", 1, 2077770832, "199ed26b22f80c9f0fcdc25f9cf8e474257f62c2bdac83f716241215f92585c3"], - ["3ab0ef5d0379d3efb4163eea6eddf3a71c067d43137704e595b1e09f0b765e36a813be374b0300000001657a468ce30336b321d45474b56d3c4e90bf9f2ae588feed381038df08bc7d9bacc1dfb53e02000000095363ab536353abab6affffffff03101b82a6771daf7aaf71d1c90ae08426bba7cffa1f4464c722cdb7d30b695202000000036363acffffffff04cf560503000000000953ab6352ab6551516356da060100000000026aac17003e040000000002abacf4589c040000000008636aab63536a6a00e0cb8aed00", "5352635300", 1, -2006953550, "2f155d20402bae9e5b1989f1a2bd0442e902af1c49ed140b3a2fecb17b22c76d"], - ["46600beb02305ced6f91f281800f9edc6dea592e3e7b41578a2f2459f3ac45a8b0cd56b3ab0300000001000122f4e9010e5c1748fe612b4dfbc2d423fbfdaf84821fa8a32703ed6f61a679c7eabc220000000000ffffffff029525de04000000000565abab5352302e250500000000040053655300000000", "63", 1, -1066443531, "03f447cc707c48c1e93c4fd5dbe61b74e17fb27dffa14b76b413410c2d494f77"], - ["71556f7004c8c1c2ae7ee7c9b103244c521803fc485d276f90b2a78cd065e2a4d27e18b9880200000009abac6aab6a00ab5100ffffffff4b0f06c64e6ca14bea709372bee1b7ba51cf0fd6c2e2d512de7a64fed0e7d52f0000000005ab525165ab7b5b1349713ebcce7d2e92f224d6770697cf6bd05066fa6dd62443e3175c745286d56f480100000002abacfffffffff3cfb4bdf005766ea035bdf273afaf8d34e3b79beca4ca186c484dfc8c59ffe6020000000153ffffffff047f397e000000000007630063acabacabcd264a05000000000152b14b8d0400000000035153002a5011050000000002ac52ee0ecee70222ed79010000000000000000000000001b032551ab0b0f4e167b4fa5c3607b155ebbe6ec4c2eeebee5d30a9d22873a0bb090e8ee7014774a25ca0cd7a6f8efd9a9fbddbeccfaa52b8f332844083ecd867e70ec00beda0941f98f27ac559fe4a546fc04fce1886cf9d20583dbce1e3fab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000356d61d05a69fc8c1c60e8d80bcef6384452c98f9e0ae98a494347e7911ac38e93ce14ba6f6abf125e03bde9c682f768a1d442a315e2f1658a90405633ff9d32f165fe2fcc22049131429b0e7fa72557bdf348ba5058a0dfa3aac8495275ba68848285e5ac686abbd38cb480b2c399d5edfc269e4e05606860d3c89c897f49f00329233085b9f4b4cd22ca4b7f2761386403ccf85dcc7043ac1ddeb7638102fa8a0211c4d2b18f8db9ba0ccb81a219635d27af8952af08b01fda2899c637b96dff1a0a185547ed9a6b03fae51bdd58f3e88fdb8bcc4796fb3e7eeaa1713bffa84e68342c2e6ccd2a640790b1d697b33d88c9f9e3c3612960e0e7daeb83d5f550cb51cb02025e52c4c89dc58ce908053909db8d1d0e7edf5e374e4a8e92dfac9766441a2e03150f21499b7ec25ce7654a09fd1df391784099cc06db064ac9ef6c0cf1780d240206a2b10e62e6d2d6124bce11cd9bcda71b9c6b7885c65f7d6397fb4d1a99d35803048689a739bacfa6e1a32989d47e47fad670ab39ac426e4bd72982d5e0042f9002096cbfa9b18b2899b3f15cced701f1deed6d2bca19ebe9059cce91049ce81935e6ec318d1ea07100019b8a2e69b5909dacfc47b42c48f19e009a5019e81b3e453b334c3d1557b2e3c05d735feff0d5595b699707870d868355c6c01940373fd6edb5be6b8072d7968ffc7c0f888b3d22297543f905e8c55f532279af41f8263d07a5be8384ef6b9b07f470a823c18d7886cdfd49e292d06ce10cd9c1c52a9ea3b5fcb34881156effdc6c14050d7d95c11ab304fc00f43a8568dd3b0e04b64080cd47b9b3e204df074468a85f96e8ca11ec0d6935cc0adc6e67edccacfa5b68c1aec1dca878b9636ea4dc1d6dc71a119960aefeeebf365346043731754c5ff348e639e94133d47321d85bcf0013ba51f36111ce3cd38deb9554cd5c7fbd53c1cb8810da70dbdb194b828bd5ff4bc080ee4a062f8a60c9d80e4ca31e764ec6e7a845a425e5c882b58b5ac63bde576c0a022b643bc1d548f7c4ea2a3afe92984fd51baf2a483d3c5766465d60c6095db838dccd588a91b33a172c4707d969072607992131de7e554c40710a6e4ffb71e88db781bbfdfe94fe9f9843e894c322fd1289d1154ca880984511bebf1f6eb9f2a77f5d818976f28395db59ae59449e4ad70b2acc5d2fd2080d6fb391014bdfb9ec27a27ccad0a1856ae42347de39f84246340367341b7d878da2bb390f263913367123abde7f10cb3f7f469e9a1bfd6d1dba6a39cb763f8cbea2801c30871c744de66c418144c7faa0abeb28a46e26e9641001abe39ee1ac34b73dd9da9ba01ed5575b3e2bf3efb687c9c76e6e2ac8d0d6ac0cadeb422d809ac2c56ef5006385c054775bb21b55e1ad03078b1a0779bc496989d4e2cd3ba71bab2476088e9292d77d99ad39d2c9dab043e743c92d1669d7aa5404df417ff13f4ac333a999226862e1225a68f6ebb004073e2ee8d99166e9ca396ae29130a5c1b7a40c37492d9789a95559a78c61c12719f7a1a41b8f7330a52ccb390c65610fefb74dea5c61638face847b4b5d8384f33311a250724d0e6755b53c4283e761bd666d04a3531f2515bffec3554d51681ddf56e959406bb63b7ee488257ed26ec59a838b38ed49ed964f1856a9ec55db6faa203928ff4737e52afdde11841c73b8f06cfa270be1dbbf0d830ad6b853bf3fc6ddfc09feb7b1352525891e416c96e948542906458cbffca99bcda57620f239c2c322d5c8a4db89e0003e951dea5f71edb08dd2450f0e6ea77d71c6e4a5cbb2d562c6514c13b357b22cb7e2ab3a7cc38a4479918e25dbb176d0bc755b2676a5d919ae4102051dcc4956cd6f643eec03659cc81246b543579c93d47f1c2a96144b3e0aba7ac759118035ebac1daccb73d69aca5b0fa783b30eb5ec85372fbb2627f8f16b82a503eace174918c02d54b2278b6e68cc1f1e76374f95441d31d468f2cdd2e8a462a2ee3747f0a32eb45571c4dab493c0035ad15702d7dbecdf139a1042e1a79e002b210993a23ce38f85e441124306bfc4a1983aef419bbbbaa1f5f45402894bb1f5c27a72775557ccf0a1c15ef184b9618003e97303e4b06f27c7a4d003f0b001286c2ed807a22dd7baaf8c94d9f624967a49033b81833209d32d2ab28a3f8d6d6b078aab496bec0ad8ec63fabca7e15e9e23a2d541e2e13ee87bf1a2a12e72c158ee2f83cdf3a8b2d5c5f506511eff3d3fe4db9a7d58ff6e581e837b5561ba44d1344125178dd6bda89c8c3712992c42c45e2a5e9d5c80400000000000000000000000008d714886b326bad60d2e9f1d492695fbf08c1307c827490394f928350610f036b7b8dcb3c1935d680889ab8bc36baa16c2154c2f6ff8e882fb6203e97bbce5d62e3f8f1c0122584e6cde421eced48fcdb97d8fb30ed7d613f305185b7468139000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e1d3ca7e170a64e5c5e484f30e427afcfb75b8349983c6a163c36859281642fdea7adf4ca9e74a68760f652c543d6d8dcc9da01974dab23800deced9a80adfcfe60d94ee828842c944ba1f0a44f3d2875143adb14d2934d1a89908135108589cd1c89595401299c6f77e9c270834112b5759acaaac00264d7cb2ddf8e95f05b03270b09d2606aa8ad98cd35e42c127966df82b8fe1b258a0d5ef4eb247c5045a0020aa186522eec9c4876e84223188506ec38bb0eb81e0e9d8ff606f3274038f3d90a23c1db5b720316fd8f828c2e5454708d1c63eae46dbab17103a9b985f5328ed62ad4d0164b4cd085dd7f645dd479f4570edb2cd0015614c009118f327312be140212d7ccfe18429da125d541133468885107f9b4f58a60b725edf0441ad3b7f28a021533353bdee06cc18666b86c63e63965ca5918de74071a30c02e9a34a39459ed0317f23255a54331f65bb4d2d7ba14c3c8e3e06170b30a63241e2fb1486c18a20103017e1469e60159d04385f44352d62d43cef5c4200d430dc9e15c5fd959d32da502147852345185c72ccf750a314f9f26a6c8279b8dbcf17109f77be896ee675ebb693324ea6d66ab06cd1e8ab7c1480b06f45beef8e642f9e4f9e57c2b7ba54804f72e89b089dc7b1a69d5127690973a8f87720e661f9bfd4fd7ba4785daf32a3be54150a06149264056650cc5d6f7eda731279ba61efa5dea91746a07d753ccb1b4588abedafc5e6b49e1869ff00883929bed686175b497d9135d9dbd75a68f83ea6d1219f8a15911fc65e2a2f816869b24a9ca049ec4129806d1bbebde8ef39f181a04af901c464067120a45d0da3556a378886ad2f2bb03d8d31b758b608a3e05f4d498d0745bf0a971a52593696e22018fb783aeac1db61dcd22f4ded591593e1d6db05c38a2a65175beeb91732c9b5611ea4c058d81e4e62e8b0fdeba2a05c7f18aa560a161f297c3e84669c579a6d4d246ec30d9f546a46f10a9bc6fdb1503e299ce3beca994bc571e74d20a551145ab2a8bc604313877d1cb9449ad6a219fd671153ae2fcc6f17e19de5252efcbb47dcfa49d05bdb2cefbc0f7701d850e22f0d6829969ffdfbbad8cb303b8334a23d01ca14d5419998046e86c063ae145c6cbe23a9011f758d70f58ad6a9ce9a6842845c0d5c324d2aa278d01fdb0dad1b6078fc6c673cf74a6a40b0cca2e61803592d2e2e93af2227901dcd4c51078fc3bd593cfdd63ed5044777e267cb0585e839051812ef0827bd1d971595caa4b28b036d15d5d94a84554d4dd5e98b2b8418bb6412f0653d432cd210ea2848b5ba6b4ea63b24cc4e1a206345e67256eb6c37dddad75849ee6436514eed560d263df2e9df68a2d2c49e09fb899b5c1d98f8e685d643d450aba37d8ae9ba4e166c338cda5ea3cb875740e03dd88cce60af9e25dc4c919cf9a9384280897169c7fbb1ffcf27610812c2d49ceab82b2bfc53b895b87d08cbed2a908cd352026f87db00a61ea6253187ddf095da6e62ce971474b070885688b96555201a58c67df8a320e3d8a543a242f183b409fcd7e71668e4609727bcef2ce22a3deedf5b6afcfa550dc4d3f4e5a28507bfdf857c58a71aca3e7073bad56f72465595190f152ccfd1b45c9b2178de37a87943aa92039cfd7f32b70581a5a29b11e7c58b06e30d6bfd00f70c7c0c8ba06787bd8cc4d71b1bb708f3b7255947ad950103759726c618e37a934515a1dc9d22df5dbebfaa5a799782e537a8f8a11e4c0acec324cc37ff385b3ccbea25a701c565e146f5218fb53c06c39632f2379d43f90990e82c2fefcac5a2f691b5a315af068118abe48cc16b7e31ce120fb8283877b2b2e3b5659bce336a40fa2285007446938c8f9ed851416b149238a7e47d738cfd2688728866a2b76459552635ad00bdcb0ec5c6381c12e4e9348b60db6f092ee6fe48e3c3206af77258a699266afd6dd4ff27b2d77ab0ed86343ac4fb435d5f02abe8388335e82064f33592c0b7d666cdb4449e0381dc736ebcf76bc60ea10dacad7a90a9293ab8e06cb83b01c3d5b3380b45fe669de2b92231fa71bec98f1242ff6c1aed5b55090fd3631d3e17b2ad37727118984966fc4ffd994be33a08958e0a9aa10dcc383595ec0b21a05e08bc2f19b0e90a43b1ccf6155591996857bfa97b7f20bca84583339de9d7847a9bd1bcd40cc275630c78b233f26eece2bea87ce7fce606c8fab5fa8c0b6845c3a422f73d86b87b6af47fbbc22444802e8de28796eea34fe298b1945c0cc725e39b17cb958d7098f99db899831b2548e6a7500396186f3d0039a32070fec46ea7967a45f1d69af453d1a7f836790a8441b557c89f2279a05a544f479ef2e7c0faf0a0a1e611327115330b4e5cd4ccf0049a8b3ecad519456cec226512b333a31e2fbbf0d085bdeecf38b7a0e", "", 2, 1953091961, "842e465a3b5eb19a3d8ff10bb73ca662f9a500b434ec30a718f6c3ff15e47b45"], - ["d67129f5011e4d72e966610932dc12c9f748f367289ba98a3984aaabc33bbe8b8ceb9fdc340000000005005163006abcc9d2ab02792cf303000000000752ab63656365529201820300000000086365006553516a634ef76555", "6a655163", 0, -429583614, "2922243e95475be2cfa1eaba00309cefe7623ceb39520afe9ccdfd0e1ef12301"], - ["ce2f5d450389f9f111fbd05f73d48c3c29f1520ef128dd1ab45d20a743ceb16cffb8fa8e9d0000000006006aac525253ffffffff1850091165d4570863ed0a286ab7b4fa0ba099da98c29f24d2ca83899f29c0000200000003536aacafbfc765fe9f9f3d46f5ecd9ef6f8f6fabb06e734e002ff36a6c263a9bbc4391ef64735c0100000002ab527b79d4c3025c9dda020000000007ac5151acabacac06b8a9000000000003ac520032bf3fab020000000000000000a8314c0400000000985882e949e548314b872da6e46f1b99f5f0d85e9df4e1568754ed0cd4e7e05e2975bf73232e3ac861e6daebeb05f566f3de94c5098bdd276cac3b8403d7f938e255a521eac3b4c6944cb055d8069233dd4cbea33b81172109c1949b88df7e3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003da2b5535825a59af0b903a892e9bfbfedd5234f45ec0c59938088ecaf19906696160d1312ab42fb067ad15c348b9896c15c194eda2eefae0ed9b0b0495c6511cf4fdc015cd81812b51b1bb47423d9433f20374be516e0b4a07c17c404d9a9add897c9b5c668c62c1cac86755660d8499de85a7a046a382a58a4b0bcbe812cba0219583366a6691ee7b6f3cb5bc1023c8454422f8dbe0e4713a402b35769fa2a40021714ed9032de1f09302a78f8c982e2301bb34738d472a45d8c2ec583a772fd970b2a4e67669dffe124d36d3f5e7279c4f6317e94bba1e16fb768f79b164cb089e3290b60578cec5adbb9f9f0cf15a84349224b52bf4c4238e1397e577e36bde5d70329f8163395702da7ae2f21bd66ab60a91827285d1902e9329d94dcde277ad4700214fa61e2856bb526f0b73a5a88bc5aecbc5892917a4938773be93dba617bbdc1031f94e236360e8d09b84c4087364dbc2c6d93e1455843748d85f6187419364d8f0308a3b0ed02081b677cccf75dee14a48a3a744c51c669f39f0773aa362bd3d329021ca8f338758a25175f786b038f46cfa12f0c49e4beaa6ebfc59c0f90914bea3f95f6f2e9984a55a674118e5c5af962c1bb1c036aa96a5a06dcf565199e0fe1eba3abcab0fa9af1feab0a93d968c07d4965eb671a0240119c43f7023d605951934be63eff74ca2c065c76803aceb277c4f5b5bc91e0a761984fde692fa888cb57924c15d4773cc1faa30e5c9fd46cdb1b9e7622ee6a2b30fef7f6d5eba2197a62bb03f248c8fcfc6a1f1bcb5d474a580ac35b36dccbe08288324d6404ad5fa38526a886335aaf873df2efc8e5dc585667219f062ba51c37fce05bf4dca360e627b0f95d06a02ff2feaab9fa4459121b0533b174e1ae16ec364d216e7474fb3e1fd67c6c15359f4043d70043aace69a4c15f7b688d3db9b5345d0cae0470c0f7704e7c2144c5f9f3b57197bf34c3a15795a0f36cc5aa05256aaa3b162dc74d3beac284de0d804293b5d7a2413cd1eb6ab7e56276f0ca1043b2f7274dda993cd9f7f1505a6ca61e002d572f0a58bfbb7eb48f3895d42f9bc6bc8f1f6b9a9ba93278145f17666e39f74be83fc13cc29e684098ab1466636794025ffc5f1cb8bebb42c9344a26e5de664ad8e3aeafa45649d9954253681c03828d82191a92f5ae300527f76f4e481f5ffe7bdf2e2475b6622773a215a419a132db7331b144b48a4d8c94d0ced54b8a1d3a2cfab87bd799b8f95a8f912204d092aa02a538b20a69e1b7528d2377bfe72cef173cef31fd5dd7666c60c487e4cc2b4cf8412f5d93989924aa2464da54e09be6d430ef72c16b32c3b85d0893f673d910af4271d0cdf10f090ec2925b631728feea162adfc3fde558a863a98daabec535d4d018f68cfc168410dcaacfae1de4ad3652d9cb741eec3450fee95d21a9afd21db80ad448c24aa02e804d650b43cf37ddda47cc24ad9906aab4f7b91fcaa2497a88c091888fe235f8a7bc4dc3c6c47791ace6f970d1aa48007ae947885f6f3a422e1214c3aabd4f436c11a06ca318d2c5d1b067e4087784016b73eee6303cd5b1c03a4f5d5f8aa68550026b42baf7c5efa86e6799151656727efd9aae358b20622071a20dbbfab922772705e687dee7c2a41df634bfcbdc49ebdc96002685e3706819edf7f1d3a54223560d2ca0a41604fb56ca5072bfa87f7e31317b0f617cf6f793663911ae19488ea7f24b2655829620a55bd044a34121074f556025f33c04ea1151e4223ac809f685a1fa536bf7f1dd32b7f8164fbec3950ac91cf308017e5bf564b6bf18893e14df36c058b76a8078f8064c5384a82d0624e2fbc84cde54df99f446072a3938a0720914e90f18a7ffc0a62905f0ecac8c1a33502e4d234ec4825cb660055d5034528e880dddd94ab4bfe815551745ce845e4fb602735cab97f0f8190ccd4d0f68f36614823b072f9652c80c48a9017ae2639ab6d5d596f30dc8a01ffccd623feb866b99905ec73036372d18fe7071513795e7aa666ff8a8426bf00f2d1be966916212a4371e24f23842e92f74ed50c3a296540a37b0f475077ad453266e6706d68348a726c9db5cd7426e63626f55053642ea27e3ae00b62540ebca02b9144ecc51454445633f3e2db3994fcb572ba7ec4dc2f578c351c8eb67f6a4727afbaa03a907842e76081eb6abd7a33da105189e69ede561d2af7c727e62ab6f8299370b9515fa416bd4d37f911d65f97675d60c32b17acf7dd9b69b8b62adda362edb8708c4084472d7a6dcf2888faedb1321dd0000000000000000c0d3530400000000d4459434f6d84f488b8b9bc739351637530233487572e3c11ebc53a1e3805e3b9b15356ff84223c79bd32cccb47d6522c4dbb72ab80029e9e770b2ad8b944a8a6af6168f7d94600691c912e2558bd3db84caad9e2e639da3f040d45cae189bf100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7d73d8ea29becca10c1df552b79f87c22162cba0123848ab2c131f27d78e6ede1f6b7559763471c1f9894c028bb61fca085721c4bc674bc94cd9f99e4412fc76ec0321461d2b2a3b4b1a370e0ce25b3a90ec7b07bca18970c304d2735011db3c3195683858422c14291607bcfadbeb95a1864198fc98e90d0ebc1bddefc2372030e50ec82ab29d7509039ad4c63d4ec0fd73ce313b3a5303e1e84b5f01c51f796022d3eb97d9c765840d03a63f94393834de3078b54bd202d6f6879ff6f44fa8c240a1084d5ae1dd198f05daa6ed145c9bc795cdaae4df069fe93f75d37c08467349b10d349e4202ad998e7eb05eb860e7fe337087095628cbda9e23c55d91ea1d2d80215cb1ff813e585686281edbbac4e4b9c7846e769678f914ef4b72cc33aeca47e022004ddbba022629ac82e854452497a36cbd8cfac0a9520fe9597f3f0a48780190225204e5b5fab8ad2c5ca61b585bf7004a70bc3061623e470d5359f8e0a687177022a400101b14a884c0bd0a4d5656dac6618e40597661bf8f4935674a591dfdfc6031ba0cb00c93f89881ad76a6b5823de034c4d446a4a1564d620697713a7b971205c4721c775d0c0109b3e7db17cbbdb2f5b48f8ef9baf425c6919e3d51c63fe8023d6fd6cbfc774d0e8b3f87d3b14cb16a3a6a27c445b18fececeb59a8e2f9691ae5e4bdaa3abf1a1366fdd4688cf9e7b1eddcc5f9aafa2e65b7b3942f988e35a8b0d7cb09a37458d0cd49bed331338a929ad39571620fec22200f2e553be3356edf6109150ba9b6192dd041c0bce951dd854ed752fe35b16e8e842cfefa534c7f7dfff206a144ca0a06173a83ed4122f2ace62a7b7ac6ac169696d53f89c4c7d09585ba9a3f81942e445004ca0510f9e986cf28031b1d5ab1965aff7fbb5f2b16cd89feae9a53b36f9d9acdb73fea5d21497b4874a8d5c336d3717acbc6221a9caf0718e3b6095e775a5b7cb851198bf7601087683ee639211cee98f7a49db89ea5e654d1ccc6b66a11be17a1958008fcdcbaf77fd940ed82a25f40a1cb27e6e8b8dd89ef2525f71029318fdaa73f64cd0ea4966f3be320096c91cb8b90555ae1c94e7c9dea6e365536967b6394818f09189690a7ba91d60d2de0330d53bcc453c8116797751b1f3f8bb72bde0fd63157be630fb032487d9ea7fe50049d5c44c194a48b76224e44fd7295ec397f64ec44d89b8e7f7a50720de3ad09ece9f0f280f91ba92300b6cb0b49e68106d6c024463852ef248aea92f463cfe16c2f17b58c7429eeea99c810b1f8b101615135bd791b7b648f0fe6631e8fca34457f37edd9b8744cad310e196ef8c136f714c13858cd358c9dbab270189197aec5c47b20fac07b3100e9bb20466b34528f9e850fa0389dbf36b3198b82fa0128ad1530f3ac747db35e30dc574f6290df67ba6187055845dc5793b605c47b501527b2af5b5b33cec3a657dfdb2ea1020160fecc3a09921cd65d0aa0d2504ce8f2dcfd65cbb4ee34916eeee0efe07e7e9da0237aec7a9b54579f50f5d760f0a7771ed68bed6513338349c4b7eda586008de89da6921514718abcc05b823ad022d51776a2a98f3d7ad00e396a1478044d61d4b2c5cc468d1bae03068a33a17af8ace040b03280e61496ade4e59ddd71a53a69e645c279ebb0872f4a383d7c3dc68c958205542cecee8b4b8a398beb9d1941424e5c35286a50556390c618937d767d75031ccde002ba7992a6a1767f0c323dcda338d1f82019b458afc169bfb45563c7406f7d8399492fd0df18d60bf6a7d4ac7ac69e10b7654e42e470aa8490765cc44712d593c4b9726c4796bee0b06cc44b1b93f04f7036c3f8d2e4be83b8aa2ce8df6fedc207019eb2f4cc7dabea244fe5703d93fa52868e80f2d1a52eadf27db82b76a785e7b864c69fad456e74ef6060ed1c5601ed3c37f197ffaa41ed7f22fe465848f19e2b3809b275f9ea666ef9091917815f4bd2d55d34cbe6f34cc01a24e01d2e96fd536728514fea9653940ba0d762cf410c3ae06c5c4e192b7a9a407d3cb41ae2f097c6057bd5e00f525b4b93c6ebd68edd13a0a24d3803b02bdaeb3c9d3b47c213597f4aef8ebcc0970bbbf07b204859b381a20d790fbaa282caac62dc5b4bda09613f0d98ba3713017881849db45e06e4baa578927fe287fbf812a58b1d900027f89ceb8ead2d26f2c67a1ecaf0c2f62dca90921b40963fe719c7fd2f274018d9742912cc24ce02494275791cc0fd05896c3c816a893c3e7a3ed0f79dc794e8a0d904e56caec1ca101596ecd24a56a5c2d93cbe8e62db53d6b877747ecc1bdca994ffedb7b510513a9d9dcee1f5389b9516b5e9edd43e417083189828b81458ce9e8de95ffe45ce0a2ff9bc1fdcd9346053d769ead35c2a849f1825aa62e386c15bd5b71b95b6dca3d6eed11ced98b1f05", "", 0, -1886920177, "8c937d96e5a287373f87287a69b079e8ab9afc94e34d85a8ff8847a91a34e5ac"], - ["7cb331bf04430613884824b11d9de1243806a691c6f2a505ba20381a0fadcb38a0096d88740000000005abab6aab657c2121221fa0942508f8fdf0f53d92b75369ca13e15d42e4f65e8cb511b1f4b4f4e1a4a20200000001abd13667324efc03965a962d70baa4e3e1ef944d65f849c39bff635ffbe24c402d1c86787d00000000026553ffffffff59a492bd138bf90b11910968118a4eaa3769c06cbd8d8bfe4e8be95ef6d28a1100000000046553ab657f38ff2e03d2197a03000000000263ab18bfab000000000008005200ac65535100cc216e050000000006656aab51536500000000", "00", 0, 297325301, "c73d676231e173411cd852c3b12089648b09306ffdefc5348f921457b613ba30"], - ["f3f4c24a04d9626ae3bb4c4fb7aaaf64e1d338bf38dde3b2a63e71e675a2c51a0b17c40ef00000000009656a516aac52655165034da2bd38c1551b46128bf284a2a053da7d23bddeced13ae2fc37e840b0cc27f8fd0b27010000000800ac00006a656a53ffffffff10614712968671c78c48e074cd6fe8682857f6983c5a2041efe8bb900508726100000000076a51ab5253ab53a1fbe63e4ea5600929b8849c0f53992e736c8d31350a3e90b2ac7402552888cba4a7ffd3000000000165ffffffff02170b320100000000066a535263ab63e203ca020000000009526a526363535265acc40ae28c00", "0000ac65", 0, 2032497616, "a22eef3af46933ed54b8eaab67309d69950ea92bdd5acd2baca812de9de228e8"], - ["6e32a000015db2666fa653e7636a30be946d545ffd995af0fa0c2f874c6629086d84c531b80200000007526a5151abac659e7708ab02c1026d010000000004655153ab749b8a01000000000252650000000000", "525151ac630053", 0, 45710664, "05fc0eb07f39b043e997fb86b7bdb4dca927f62deb6800b1f4c8e71d34f00db2"], - ["2da8587103b0337a0e9e11907e065bf0b03da64de7ac1cf8c2fe71cd77ce5f10cf1de178310000000000ffffffff91322200a8ca284832864569ddab084bd7f0b0ec8a769b80b4d11243061b67c900000000025353925b18c1b1a372108c16211b700a7e28ad6eb46179b4b574800a3c7fd38c340db7cfe6040100000002ac6554faa2cd01f5331e0400000000075363ac656552650000000000", "ac0053ac", 2, 1186086084, "9c17e844d852e98643372cd31e64fa71e0467c1d5dd1e93981334636ebbd322e"], - ["f4f022d801c86e45c5c28c7692d3146f2aa541903d804fbcfdd4047b26ed14a492ce1f9d5203000000076a0053ac530000ffffffff03dfd912020000000000897462050000000008515352656a65656a7d80e2030000000002536a00000000", "6a00", 0, -500505332, "92b28243cb4cf738adce6bb884c9dd610bb9e0729131ef7b42390f4b035bdaec"], - ["d931ed3701f63c9907e03c63e2a74c702b62d1972bfd5d054627a31179332340c700387d34000000000951526363635352ab51ffffffff04166fb404000000000251635b9d33030000000009536351ac530065526aa2059905000000000463526500d3e42c0300000000095265ab636353ac63636bc9dd5003000000000000000005b7f90400000000d8ca0296e10eaf596eae0e6d1b7f7ca2b4a1e1dd39eb9b1556d4d5456a961706ac9de28f2fd7ee3cf5254dee322bb1ef9a2be023338d559ca50ddec0c348622db539d42cb0354d6816c83d9b09dc44c9fef4b462c5d850a2b9043e3698c2ee5e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfc92ba13f9ecd6e7ae5e1489768e4c41e133138482ac2488f575124446f7e601b2bf41da678ec98e9a07f174795357d16b84676000f315fda694b790532ec63166885b2041d5af02cc3e372f7690359633a00c2ef7ee21f921fc350d0dba62cc0c008bd06e4ba40c8fc742da0c86e650f537a8efb6991022ecf0997ee95919e030f1dfa77139ded7e910b3e1d637036e552aac6d8fc275cd2af0d921c4cceae10032d819a90456c93799e3f17d32d7ad16376bca36f49e180be72b761289fb927d90b1c855dbf0404e837e1a5c92ec3829266a0b4a274326e94a075b06bea05ffa0820af335390dc46f11b6667c1c972ff49203b5976d894bbc17aaad1ebc0e5a8f07031a839f1b38c8462c9b24e1915e96c4b5a7e0bea21da6619bad13250669863d6502064d5b99687dccfeae720e33c98cf3e3ff2c2b7bf81eabed5d01e6ebe93684e90209d981168ddca345b7a12738983746af41a96cc8bcde6c4d343fcd298fb2bdbd0225e0af44641e265c4ea8e2d35d61c2bb15459e1c3ed6242628dac5f50d40a5320214efa8f49db05efc10e3099136403217af5ad84d4804e8a909058c20c924500538a56d0092110e01f4c57f72550f19e83e7c15a50bd77fd2edb4bcb54a493946ae5c251c03150adc23d0e5f874852242be7be18516997855a3cf09e2dafc95964af52864e3c9c0516e1a1cef4915fd30bb2ad9ef033954ea18c146d1a4da94926d94f453576ccedf95fe05ce2ead298a10885cf82bea10d24fe89071eeaed5947403b8bbe4cc78efa389ea8f30f1da4d19a18c848f1a09e6c1e41dd007636daa423881d69dcc8bb88cac9b5568dfd2367eacfa33d6da1c00721514aefdaeeee9d26dae1ef6af69f64589fadbe644c236157f247b5567517d69f6fd6508194d3020ba9812db04d888de19ca314e4ea672ac56ce59a13181ab876c72a9db4a0a36a09c5865957db05dc0ebea3feb5542e2b1bea8a9d4a92f998bb6786c645a86a2e8d17b55d54da3b14e72a8a6d5f4c0ecb5f1f22a19c47c61b4b52c47254731afe02684bdb8fa0f41e1f812d52cd4372b495ebe432f334a8827215c31f52588718b3ce30ef958d4d3ae3ac5879131396526475c972eadaf7c36d950451e1b194ce4d2491e984d4c0f1a8b41e52b4295b1ce4c2c1ea96d79c267bd9526ef3f75d724dfab6551be2c73ab8a759d73fa7270c10da955930d3af6e977aa157b1550c7791a5ee3b669fdda39d032fbdbddc4815bd4147db34e54f7199efa4b36863f6f4d4918b14c0795195930cbf1b29cc51fbad98ef22031fb9e0a6fd04f87eec5fe431d5afb408234da5e7ef5d42f5c41b5a2576605b5da9aef01aaa4c36e37fb0810d7963ca2caa80caaf3a4a4482f0c9c392ce0990cd0c875b3fa9c24d1fea4b75a77d95996834bf9900ab890fb5d2885af4afee5e497ebad3449837c2b6d735d1c8f2ebd1f3f54bf71da96df325fbb708c3f7ab509e056c1c97dfc200460874773b212c7b094647c1e0531e3e1fa58639f95c5e394ea80c546227d9ded5c6f81258dbe9492c7adca6b053eb811c239340c4d73a8558e81b69a496ef26383c53bfbb94b031719baef6e47d692e4be4ccf660ce45fc4eb31f29b228251162b2b5adf5f044207f22dc3c372a7d8d3051145dd4204322c6e76c3f87107e5efff68bcfc349b5d638152f4bea665e4d03e836f003672ccf9b7a3e9193320fed561e02df48f4b4291b2f53fa4eb986370b451b8f441006424a5b05b56beeeae69c19de870bc7c15ac3952cf8c4727996e5adfcbb3ed5fc95f01aa1057827f123b34c9aeb51d6961fd5378b7043c7272df6fbf5c0f1ca3069e5baf4f633e2a2a76f38ba6ccde3c6add647946dbad6023f70584d411eb2b4b934d44c59c36778486898966b04081b0d388b25cbb3aae46c1a00917d508487d242cfef91bb5429ca670461d2f42518a3dafd02e193ad4c5fabf682a31c026eb608945f0e455975e39472ff7a46499ad25e0d9f7875e8b7efade978ce5b01b28de60215dd9056ca1b5cc89843df1d36311af9c9a5a545ac8098c332363cb7593732366d58f445724f4caa0501b388f9bb757a16de51bb9c38d92ef0538d9d0caa72ce89e52f32f49371e73b071d93ef2e86a830e8e4552f1a7d2ad3c39dc441b257b690e152a44321c70a9050409693edd5cd520ff6551dcdfe91adf9875ca7e520d6cdad727ef7cb99adeee3645f710fb75624bb42c04554ebc71585942b6ae4c6a06fc0a50beaea7fb4cc41feb0c43286849314d0cd367f47f750b30e6999d3b00000000000000000000000000b4d8825ce8f8bd30e608ce84eb4584688b4f9267543441e292dde6a2a572516f62ff8bbd8d5115c89818e3f1defe3a851135f4163cc57c38a28cda1961c38f9a2d473c5c3f52a1367df99318db2ab077da48832b148cf6067d1ef2d5e23df023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cd20c116437dee968c1fd11bd952a558bb0c3fe56624c444ec196c7eb907182f25f9c4be4f1031e383443a515e8ff926ad6f47140fa8e6d66f0e2278de345f5698d5c5e83eef02cdbdfb971f8b5ba35aa3698a7dbc450bc921d49d2f77f5dae81b7397d0b7e5624804481a2351d136ac784bb4c57f41d5dbdc1b769799731a103204668a1dcd08215f8afd335f82d35ef8f732b2060300af4cc87d0c87226e1cd020079ab860588342618dddb97567eb2393bd3b2a428d11f38b8fb9f6a245e72810b0c2ca3939a66f6f9478d6ff11d74ff32663396aff463eb530ad07f0b0e708d1b2e5c27312a9b907ea0bcafd7e72a01573af2e1c2f5b524712464544b6f8659120304458c30d29ce08c030725d3ff39eb8bd9d80cac99fed0bb850c97c1880efacb0206b17cef974a3dbed9d48ac514bdd3971b713c98b23f82044eb7800bf73adf17031fef423f58363d2737b739fa44b010c5cd06f40d83f5df061f6749e4f68f77180330389079a003e57a184ab52eeaf85478047b7161b3f6381e68854f4c91b9333c03173d9f7e198e1392409bfd3ae420e2f177e4e15ecff6a52ddec3277a4218c39ecc8556a88d23a8de752cdb0a8fcb58c6609696214e95f957732f556d489f0f7be6f0773fd8bea10dc2dede9d6cf49dcf71293d19e434d0d7257e1bc6e762c611283b221409cb47eeda6322760e2ce42eceda4733941c22a176910932382b7fe5c26d8f6f7c7f56669a19814da196dd53d6cd0abc7bb8bf51e7d59f8594d980a15a20574184ac64a5b1b46527ffe78dad54c6c07468323e8df69dc53ecd0c4f4ab5ba6ae35ff6b559ee05049a04d40b9f807fe1078743796c87ff1bc1f677df88daf554e53e149af4200bb36e9202a143c03f3453264be49dfce77bd2b92e418d59fe6819310f0fb0ec91e72f17535508b28660a873720c5c75d384ae2061d32f97cdedce968d7ff2454b25f6a6a711da87d85ecc3b45f44097f5caa5d59c8573df423336afa136a52420d5d5443448b3d53a0813b44f85dff0ff23e6a81c34e8db15f641f238ff1759910b04b9aeae4076ae0af083dc09b7d9b8f4073f36b50c0b6020fffef8f6f76f9f24a8115e82fd7f407d18a8da4ca29f165762d0ee0673606e8ce116035616fc95a3df7e9a6d80f59039c95d278a80716df803b64f43ac69a9e9c1aec32b1d89e08c4f2e82226582115567f6ee655db4aec98922c0e07d592e83ace5a63d629528cc34b91ade9ac342cba121131bf3bfa3d4cacfd96ddca0e2bac721150ee6dade455a6fc99439318f3752127fece2961f97b44b35ccba742f1933790f896ecc15ae3c6b4188b406d48eb879e5d81ac26d10e009aaf452d0ae3fd77efca5194192e276dd954de9919852024cd21e80bad5aaae05549be50acb3383049d7ab8df13a2074d1101c4a70bd9183ea7f534a225a8daf012b91b19a70333fc598f922ffa7aecfb6ff8ef48c4309500b8b48fd648db335cb0c21432f175f6676af57bdb40142785ae6210cb739f4b2ac2da1f861aa7c795e756afb3cb07b2e62d97e8d864368535e96678f927bf569a173c7dc89ee19b2b4edcccb5d1966d0d7dee86292fc7c2befb17df1c1e3dc61dd87a6552e36799f077bd6e04ad09308803f4fed887209ce6c1481b3afa66c907afe17d019ae72f5a35d473488495404993fc1f3119dce6cb8136e68b57ad1fa03de2915f3f676d0fb2ed6add796dbb6433ae27e60f849892386f34bf4893dd5213513818979e97f8f69031ebde956aefc788b4570c8e9aebee90bcceebf9f266b05789ca145bc9ecb101432d72bdd7d476010d803359beb71aaf859873bc1e99d72b728a743375ea67ae493338a87a1e58e4c2d8fccf7690e092c9676b62240d45917f6731a577df948118779a200c48d9dcb46efbcd79a6fc909e9a7b7e0b7d414486ff476be92fb61a5c570ecaa8d557b226357978ee94b74da0b47d27974485384154b6e8a2a77567822c67764baa67abce8254ea83616eede86c01caa3b98d91152f38eab0d1f47df512f1bffc938aa78e6cec784042c3d8c156ce5e7b4a57e59fab7b0c486ef57f49f7d82209b2efc8e553fac9a345c173869cef6a9e24fcb96149c4e3e08c9eff85f75531a848c930bb48afda53563ba357fea4341977b5480240a64b036e97918c6a907df45552c52a2e84d6c6f4f2a875c233d878a48e839457efef7d97c329703dad08dedab9e24b2f88204802eca2041f3887b5681a0ee61e0a463255be9968ac99907be72d98b7b9a11ab84bcaf80c40cf000000000000000000dd1d0100000000921d6daa30a9b7f24b600f1c30850c6c3ebb7c66af7dd0bfb7902d4a034c3e3f2b5df8afd898a487d8a0e3246411bf6ef4ecc1652c7cfd6a9b07c6444cab8c263e80e89012e0841f215538c8bd5bd75db242e3dfac8262ba667a2c19b7d176490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051c3090045d1cb38b9449d94cb236ec590fdfef71a57e90c3bc6187751b15bf9d8c56c31ecf97b6fff49f2e781cc849131459df0305a6060f04510e0d5d9236bfcc4d63db84940f1ca6de03f4df8838c9a58c40f33f13d31f4ecc0f1fafcd07ff38327f2f97da82e4e052a1d526787b90bc714d94be4b9b37fbc815ce510523c031cf166a9d5531364fd3bac2bf9aa2119b88b8afa820f14421199baf8eaee144c022fde4a7aeb77ce3c4797acb6d549b4d9aa0da6bc57b71c97a50fae603ad6b67c0a2e3846dd5de629e89c9c19ddba40dedd66a4df09a9b1b0ffec1c915fd090005200fac587c765a88512a77790871d09373771fd5092b71bd855c2fa2b2fc695b6021282fb3d71a8f9d736a67777bb0ba71a76f74097c6d94c7b80e3c53134ed49be0311740d25ffdef40ede100313f2c1296bcb3aeaddae1a5a27113d66d89d3b018f0305b18cad6e7513265aa05e81105ec00fa1d37c8c1e4551acadcf12360f7fed1f022b724a77c5b228803876c7e0c52015a3510fece85a73bf743909f1774f560a83031512e3860f006e1b0d7eb9d7080b9f6948bd317af71709bf5a35a8f5a2b355f4cf0ba292507b7482325bd9f9c66a48beb0a7d95daa5c1c5c1ebda3b394fff9e4b8b429f1ca6d089b5f7cf3b4fb49043407b36a3663903061b0e2256dd2aebd7a15882cfa71a3bc027e685b4b5e06a4ab514b2c7838ec6e38892e489152ae4aa428a6bfbc20fbf0dcb0352d43758832f9107523cc7dde73f8774b423d6d297f508e2cd371394822721c4c9acd0b57a93ef894656d923a4dab14bc90c4de5bace3646c6ab8bda067377302a87d3adca2df843158143ba00837d85d3d6c654f94ea7fc37a087089e81243d040e6717d0a748629e8b951017aaecf26882ce939c762a98bf4feb03ec6a5245336f119b46fbfc8129908586432d1e56e39e29a5e062e140882c7ba45011574102234185769165fa8864d8796184127db34c762b111caf4b1c70de203f36d86ecb66f6c9a186e686ae401baefb733dbeab9b1df39d0e300415d772e6db377014f669e0cf1dee77a93b10afb5539efe20a43584535797344f3ef7061a877d92c087d4677e1a293d0a69ac00d36e8d435074aa837fdab20547b304397cabe326479750cde85e53cc56fff197c2b8a50e6e9c79d2aa150118519fc58a3248e109ef9a44e0a1e5b82304387ce75fdbbe6263fda129e0998daeff223d6ec9f85aea98b63d7cc8c13e348f2b11530cdea9ef770210026bc6f914a78874c80b854a82cb8ee5fb73532ae1b31a526b740de58b503e73750fa8156a502e3f36b1aca1266d2c7f7f9e6cd41cca82a64a1159b023e0d93d5feba2966c56a28a9d26fcf659bbc90c9595b0ca816a36a3fb1fceecdc5017fb8e48bb9d2930fbae187fe5525cef720122d76ff23f213869c04a1066494f01297470ac4d0c9bfd8cd68868d9062b4207bc2476bbc5d3fc5ea7d84ea96a0f08d21144e6edb48c16ffe3ac349377585e373b2273fc092d5c10cb3579ce2713473e2ca4926a1a0ca399b334aeb0918587f58bdb29bdede9fa4baf386d182bc9e9d9e3407a283a57be482532c4c9d801d9fa70bb3e228aadced8066cd6a919b8e7e81e7d0a49594224afad5064cd4fe200f37cfa515b22161d9cb4c25981248e26f12f9f34a3d8a12d33201adbcd05d3bb524e7ccfae05f2110af0f6ee511b097cece75d97d57db9ee9d70e9224872480add98da821531feedb013e04009f244255ea8fc2652303b4cb3f93e37e2099bdc7994292a488b139a87d788088b6251393a2e37cac392a848d8e12d2dace6854266999af1c31a3d90a1289a8327dd1e3c5e685caaaa69de8ca4a895a595fd03a60b625b36612388570408c5f760285dd68d8a66beee16d1d6c4446d1d6ff380c1a3352bfa4c6699747a5ed82c3f1f46f406bfc5f3040a28cdb77de2fa5db820516c3fd9ee36d79df57d3cd2e52265726bfde04afb0d2c037d2093ff898e09e64c89a081bd5544d1403a4d07d0354a0bc5e037957b6aa3b7a61523427479189a0939c81cf9e150a19c36cda9fcbb723f161d67fdd58593d654f1826f21e2ceb816634551bbeda18c6db44b199379ced8e28722411183df91468ce3528e54f0140e13ca44be501acfdeb0ebf440f2bf4eaf23345ec02b6fd5632a3698845ebd917738ba20631af054b7955636af000bc13e9ff9449f0a32690aa0ceb56cadca9537fb06eb521f2f19da826f1d2eb0513e5935ec1a845dd9b2d2ecd41ffe7cee6a9ba94a91183924871d7ee452dd32bc0db642a14e30cf27cbc7526843e8aa8bd5bd95a763b6e38754fa9f69bbcf6bc52f0e49cf3e091fa87bc7763221f42d141d6033e6e19eb1d0766118ca6384db95b05741c6a114816eafe545ccc94ba397419f4051e2fafd94f03", "63000052ac", 0, 1165044030, "c75654769a91e2e71df9f286619ee434ca072455aa21df4e1113aa811da19e5b"], - ["21aaacb501044db319a3fd79b449821521c34df682f629ea551c9949ef816a903abcccd10503000000005e640a3504296280000000000007ac6552525252ac458c54000000000000f8a93e0300000000065353abab6565fa67710400000000001148577b", "53", 0, 2049148901, "7cdae182725a050e0bd62041f892cabaea3beba289b3cacc14975c3af7b1f9bb"], - ["cc8a445d023282d889e1660e2423a2fa49807a1bcb891611c65a0c03662e1e1c998186743600000000096552ab5200ab650000ffffffff174d3b59ea1c2672bf07b6f35a1249c0b619866551ed6df30826376d9540927501000000046a00656affffffff04f514a70100000000056500635251c15ca2030000000001537633e20100000000026a6a1b1d9b040000000007ab00536563526a0000000003e290e50000000000000000000000000050b23db4bc4347ac2da3cd5a21bce5afa8722c8cf7eec4bf176b693cd3411de9034a6c0fa2c2ea266f7da02dc7cbe4caf94510d5eab152ee1e5866ce42607203b6070a893e52865680d5d2023ac81fc82b3030fff589ec59c8efa5f046d372e500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027d289f7814f6de231e7589473b6d260e6a13d6320c7b6fe2268b0d4de715804976c6dd6117ac234cee9fc2a695193c32456459e8c1eb0935f18c9900a25bdc1c066eb1cb755299d49a2b2887cfe68551e6d606b48c8040af31e0d69299dc8e51a985714d2a2278e95c2d47fef790542e706638c4267cafd936dea7db0d929d0221e945819cdb3e731938db2f01fd7ab763f83718ed55e2123b64b059d1decbb50308ae973455a498fdf31011846ce670dffff1c5586eea9b83ec38e61d8ba2bbdd0a23d04630fd9fd5b64af810d63cd805c9f91797b2e94e7ef4cb0bc123a2cd2a452daee9e2a75247c63569af907d6f63179f9d9a2c42ab6289227448d5fc09e7450224caa9fcfd3ebeaf861a27584b17c79352bd02d5872a954928b141a68f3ac6d20224d9edf73ba8d015590310e6302b87a64632e11c2eff6cbe92e40ba31cdad47c031a1f1b35eaf8f45caca9cbd7027f6129985fe5786deb57ff099e60a63c126da2030b22ce26e9e344478967eedd1d0835b877464724c44fb850216dd2ec8bca4948022180df03edd79f52efe37dbf270c9748a8dfed31ff1bbf4d70df50f53a91f6de8805e618f2d9664b89581ed043b7713393272a0eef47c0e67678fa74de581e828a16307e71fb91fc31625e8e49b37e1009c26e3654fbd7ec747ada63f5e4f368c46cab11cb6d73480e9dc01288d4b735b9a41857332abcc3d3e633999b63fca56ada15d1d4ef2ad8e201e0889a5dbe82c3ab146eaecaa9db6935c10d114afca58c320065150f2e7be74b73c9d3a81b1780f2b81c90b3996fd2b0dd7fadb30226326f5122de57fae5c0005a1052c04e34f390ab45fc6f83d16981cae06ce342d1baedbbc8d3cc3d620fa77023157661a2a0169e2ec7f0a224f21ec4b9230ffda8c0fc3baf2352964808a6db5adb37c5f615a34924f6bfd90098bf13a2663332b152b4e6a563fa168aac65006be072fa2001c86ddaa74dd8c87720899873187cb2052ddbd357fc15d135fe570202037ef32ba39b0e40a8c9858c0ca3b2420febc7ad70e5284627f7d6fc32fdd86bb7cf67c0155ef399a189cbbce6a83c010f8124eed06681b8ae1c6ceee0296f3ff3624b23e3aaefff79ea205d76dd49074bf649e77aac65d623fc63a9ca4c0a148b7cb0b2f54247d6aa23d6cee8031b7495248f32373305bb6a4c085955943d178c368f43ef4f1464850ef78b5aaacadd7ac5cc4f472bfbd4dafc3da16f2db9e6a27e4b4e7edbea62f7bbfe5a61515f83b7d71e7bfa35b565c7068d1d5b7ebb2c11b9433e403b3107ca3bba801bd45348275a19e3ee4803b655c7de6defde5d7d4240288121784c58ef32bee4c84d31c44a59626e3f3f82ab668cef8dfc501bac3076e86085b5d0720a3e977dd17d09fcb940155a2b6b2dd13432cd0059ee42ecebc08b1d230bf9a6138c1b61193e675a90cb6baa69703adafcfa134915aa2cf870e9609bc43e85add3b0be77f59caf9139da9d60c37bb5f71414988900fa9ab5d70edd6f2883cc5e387e2fdce6d910110c0b2e27f82a3b4daa6af72e65ad28148f0431662a829d4d9d9f09fe7760c3439334ee1b361b3847029f9f2a8e56db24170054dee2de9409d12d829a9d97d05896e39ab394d0920b4eac8980f113f11ae34334df9bf590f83832d0a2449b1994dcecaa452bfd0abc68733b5dfedeab90b6be8c30381365288f8ed4a1246e3a44a50abe6f530d1a5e6b615884715e19dff84186fb0097811e00befac87ae75a39e1bd50ad68d2d625cb04d6942c63a2694370ad857b459355321ff2b832c0c89eb11510436d734acf87f30160f42927ba40dcd8e9f0c191dcd018100743f0a8e51bb513c46583b7737d63d0d8463c6266937cec6b8517df27dcf8497078f684f5f6397d35b52a73009724b0996d014ecbfe4a47d3a2973eb6fa8c6ff52bf2465a06b1c2b5d1586a987e87386f523fa94aa843672a5698f9d6145840f1b73705c299f882bc82b230011d1181564c6b2f8d50e24f84bab1d2c7b020542bf2cf5bd3e1db9187ac091a17d9a0ea9ca7a4b29aca1d217b505169a50231532194efd0a7c66397d2ebba0314e451955b1f8a15b29ed5bd33dbd45e6bd91157665400a7205d5b7e5c845254465f2f1cc5abe6242e36f849e97f9f136da87762e12c6aafb25b9ad628bee97f3b95750d44e66219e1f5c2e941dcea960634f0f18bebff7d6e818b6845a029e40dc1fbd8a875cb20d7fd4d733d88e5195e9b921b6664eda182a0c186c45879bbadc412874f17a446d9fe13d9ae9b000000000000000050ac740500000000a6edbad91aa554cd2abea33541b923bcc2eeb295f9c9b32aacb40b147641e271e63c500a70c03213403c87426e36422334685fa2317afbaf43f975f2b8ae2a93826f152329f59ca6319107a78a18db2eb1b26d4b62add8905b93ef08dd127b6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d573133e19b46a9a432dc02c617eed48d442994cc5cb417bbe137bdca94cce1af2dfab59cb5f30d02e402cbeea50b6142762fc8ce884ac1421170a2132946cf5f8a388528c970114be73a9de381df7207ce2524f696b4398f72b66d3ca68272d4c08bb3a9c1506b4377acae12a60ef526fc8c8ec7283c27b3aca7af6275b6476021c11240035f24e4668355e28ff11ae2b4521e4865aa4e3cf3ab56f4e8bb62e45020a5ef0874cd7465d9ca6a851f41167ed615d01d194a8508e4e120a2788f53fef0a246172ef46efbd8944d40534135e01fef85d7fcd9039ece98d62c02b6fb45bc82f4d2785735d3e3736d12be056f2fb896cde97d7c76fcac8a09bd02453808973022e97ec1f07f1a82ba9059b60866f08f90f61febfb31fb6596a91e1b76f25247c02134e3f1fa63d6dd6eb8830e04f1a1f8e921a53983ea0b2fb0614a64564c5cf4c032235f90f938505d1f324b73e18ce2aebd350ff7b1360f447a4fffcf1a4a5424d032a0cecb9c01e10376ebfdc734f1121e64065c7d14f24451aedc2b835cae94a3502006e61e73db14e1a23da86f5d6177b4f6f786e20e23f4ce6fb5f34a915c6328a52d38b7debe50a9bb69e5ae30c7e1babbb83960386c4cd47a6515e0d3691329d42bd89d99b5814725c8776524127c9ae4a0889b47404833f8d5482bb85467ae8b368245a938a984d312118daeb28e8a677ef2835393e465d87756051b5e574a67e6fef9db7e3e4f3c90c6a1f06b1de9dcb6f209726a3074517bae491592b4082c238d1a8c5092599ff700be148f92bc4970f1511c89734f44d7996e50d8ee9076c0624527e5faa5433acd76ff31ab6789a3713f160370ced86e5a20b21b545c079fcaf2a2bf15b97acc842ab58d3eb0931b431c6e643d13cb046729c1b70cfcb4d6ba06ff3a5ea8e4ba841165016da0ed501303c007c5edc775e81a7fb56d6f13387ecb2c2af05decb9c8c3e2665c342cdaacb5c069ecb9b1ea2aaed900b0e398e037d36618954d70158caf0cf734dac91fc0c72ec965eff2cda19b9be52ddc53b918169a3171267cfcc82d1fc3f8d4dfeb20ab3c771e6ec4bbe95ace0f2f3fd6510f5edf4f2745a9795a22a3923ef91e13bb9dd9777e40aa2167e00d565bf318dff12bcba19c30a27340e109e3b956c406806e81bf984c9084b1e8718f161718fdbf69c73b1e7cf79dbf9fd387950f8e858619865ab33b9f7fb59cc14ed935941238cf1c19f8ef85368ab3b354e79007d99f1465b5f06b71dc357501f8e7381459302e925ace62c5eb57b823245bc8eba68f5e1457ea8b46f1a1276a9760e24266321472cb37f941d74a7e858fc4316f87cf2a1bdbd93eda9fd66a6d752b73e2ef58624383c420484968fe24958070885cff4b112ac62cf8f6fd32ed41de7d763ecbb6845ed380b6069429a300ac74eea685d6180a0731e82e9a50d0d7fdb29bb4fc2635f1738bef5d92f72a5cd02f597218d3684e443d60a294caa62f12777c0fc0ccac373cb2330b53d4ebdba6ae070dd44de84be45aad4a7b7212e58d96ce50904537348f0cdc0bcc51b00f5f49aca0c6f8159a7846bb7ea0bbaa5c3750e32a054ed9b5de77e20797dd2c817eba140b6779e0c6e91cb0f8eaa57b12502e9161f8872b9322ffc4b3e83b4a4c42255ccd8f8a0171c7cb770c06eb2c193791496e195ee567a6b39698381dd4d03651411fb57cfc02afdb7c88968f15416a9f985e5213c52db8cb15a8b273759f2546998f88e6d53ff708f836f121d25b38b80176ddc1b514d84523b909c56ec7748e8c6321b806ed95f26453ebe51b8b81e5ee8c63188061c881c9169ce975ade435e570423a85b8d16e02affe7bc228c6b5ce5187cbe1e392036466296cef057f21513c1dece2c6636ff6316d34d51107ef1ddc06676ffbc63d77c70bcdcba1bba3c1f9ccd56168c591ca06c099b1b5324343f02c4447a5133fe6f2fe96f7d4f4bd125162f527d2ff1689d79c65add2b00aba8f7db8d242c9a67d9fce20a25967ec4e053bce7e3989b5b85c0b2e26fc9faf000feb4c0a53075ac2130efd6137a4c29cb9a9cdf8f6ff20c6aa4422450270a12035e393ae69a4575b2df32129cdb5e87278b83868e30bebc985bff5eafaefb1e7010607abe29f92ec09e91ab7d57d4bab36a58f8a648b14c3abe3e87039cacd975fbcfd8f0f5530f2f1b767c776927506263ba8a47a94aa607242d998ed14d1d91d46615ac2edc9f0800cfcb649eca68d85b8b2c7d5e326f3cad4e8968b99b816b9112cc159f8e13481f30e9004c44bc6aaed7870102000000000000000000000000b8fc3be2ee777dabd971bf977869a4559149230980cd013690010b33c109fa96f6bd9be29880c33e46cd758b37b2c56dd8efc73f4d76a7e1d5eda6050ad7050f80121a9a32bb84d27996ba0f2c998d531c590af36db75e2f7a3ee2bcc0806f5e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b0b470d253cd82da93fb647ff36efbca50d4403b4e04d3269d310a0f0401306e69c172399eab7753ed90df4877c443cf2610ad2297028f45521de524566ce369103ddb6e1ad4cb588324a1be7eb034b02935a15922b71530e3fee9747812e6244f08b4ad2b4836ce39dfd68e24cc1719ecb0809c26b0c5280e2bfd6445739580200fbf60d1fdcb06afd5835188675b1ad4c62a0c7d56f15d9fbf20c972abeb2f80319dddd512f9902224915aa3fe7f4a4373935a26f5407e73a99492e7cad04b5710b134c2c176f7ad6d6c65a902ac5d93bfc2a1df4b36406e75b13bbc70a5643f8aa024890c9f35747c7f190a92662bb10b1a7db5b7fb47e494f75242a041d41f63b022ec0606d9f4c48e3c6baf616bd7933c8185f90c5b953c72f6c486f9a56f71b3b020bd29a2cd07486e54dbf7914b0a8a985a0a94179f29c79cfffb9211556ad4a25030b47395191df3f4cf63c94dbdeab09beda3f977af33225151f976eaf7e10367d0305f231a547823cb658aa0ad8b2af715a1d77b93f4f424b649fbf9a4daaf122b4020a4d77bd3b1876b301faebf3cc51a1945df01a4b62545f2ff14b35100fc8cba8b8fe1f8f96e3dcdd10ff391f04b9edbb21de0a5532b263743312985aa04723b8acadafa161e2410b132acff0ac8b5312ec053d8965c36c8483615235cd435765abac7bdebaaca171c4b449a91eef96d35f35173b1dc69711309d49baa0643e21d9a4e416881cfc9e1cfc5707aad4ca871f80d4ff0a96814fb4a02408e242b0e2c44fb092f44ca2f17f3d60715b763ff1356fc066f11934b3d863ef9ce735bc84d42a0b84ea5ac286faeeff7632525f18ef7c932d2a905e16cc7f44a591cc3c13db4e4b1d267ed17d14b1c4f8aaf9a951aa9793d02c2273293824e91a9e71c63a1dead9081bccf2c3805925316598460174beb34a6a17a2bdba912ae578684dc6a6646d35cc3887e66461ee8b597c360f7078bf2079e849aa2446fc0bd96544cde358896f70e95b91918ad73803d36c9998fdea87dff2f47ccc4549db99a8c38bea04c1ec279408a9e36f9d887e5dfa33ce5b06a5bfbf5e536b4d6183045f02e51bab03423690e5eb005e9de4de900b0cd46fbcc4b0f1366d1eccfff1b367800c9ebd755fc821cfda35bf715130a4c678b9ca39f0f14fd13aad08ae23784a79b97a8c8b6a040841f5e5663716295e433c6549335c16a1cd110d069e6cb13c8173412242db6964578cb4a64016e65a64c8b65afb2fe51a534d70d5d8207602c225dc84905c0008bde9549d3b0593fbe950d02f03f91386c446d823651e06f4ac6b74cb616c75342a72f9581917926443346dbdfe25cf21e3a47e118f29728da382299eb1209a6edeccaf28fe6c991d4f0bd14ee16d23e192d48253a9c260a79a68e2034c94b9c724768aecd8fd5896cb7d1b727e03e763a66c27323714796a1ae8e062b38234da619793c3b0c9c7da4c4ba20681fa5287164a110cc61907e33f0756c010dc8bbd205e399add4c8f4a70985e09228bb03854a6de8641f94499f99170ad47571629239bbea39307efa9fc4d70a58ba2ba26bd8ea8a65f5d50e3d21de967d001377222fd660641a0b0bcc543a5837b87f7d93e5ff398912518a7a4cb661f2a518a39c26820282267a8f6584ae95036a1118ee3de1061d80962940f4a22ba0fa61ae2c1636eef7520f10da1c90aca60729717949ba192a0982e9078d72dc18c8164b5f760e093346d175795f632a327bd008ddf0e7fbf272aee6e6d3a9e520d33fd70451d2f49a86344f06844c52f5f842c55bad99510ebc8297c9965628b58ca591fb924a5b85943c8063e6ebf705c0dd5c6a65ad0ad2e836b11735f11feb0a972761b6705c1a5bdd3ce6a45227e6b31e57419f4146166753de60a5f1a577b33560f02fe552fac2c7830bd8c02903b6e3291c289aa1b9e1f6d88252f8634ec075096565a5ce168ff31c22dd7e2da8f4f71f45321efe81122b7058d754fee9740f12c5a0471dabbc709f43cced934720c6db09a5cbbc93c26ab3f0d1da74815a929389765e36005905904292988624c6c732a78ea8934ae00d89fbadf9b05711f100ae8e9ebea04e078b5d3dd3962f61d2a79f8e9231045fa8243158b9afbef57f9b4c8f487d86fa4b401da4f81015755d0bf4abb3c5931968dad5e7aa4341920bcca79e2db50dfbad54f26805d56685adb5c5a1de66eece04f266b4b8e821c0d539f62471096750e9383ba8ac49431f8430dd2de4e5f5ffebab733cc7a99b746d7e6de87dd1f883db17f678861440b58464d8af7bfdf65c7c49844358c870ab78c2bad79496f8df6b146a832e6a27eee5c19e4624bba920887b6a7453a57c096cc8d014258393246ff753489cb9718d4765d0bcc7a4c5131421cc0405074d6f22057bc6ac3ed3be0225b9ee3c503", "53515153acac520000", 1, 199439291, "5bfe737c63659351deb721c1ead1c54d35cab9250e93bcf177f5cd9812f8b1b9"], - ["99237e3403a0552d2841044182f70d23feda6e7a7b7cdc03eae6ec0c10505baa94e8647c950000000000947f48d57ea00540f840ca706c824c81564056e6bfcfe1fbbf06a5a8e321fd29635ed5b9010000000853520052656a5163d8acb61feca1e17d1d8cf8d686a84680bf69f58e3e64d73362e7374f4fe3e3b3b67868bf0000000008ac636a53525151acfefa2eaf04d79425020000000001acae8b4504000000000165b519fa02000000000163a6137e00000000000665650000acacfc7c8e08030000000000000000fb8a2b00000000006da8698b77d5eab763926b230b62dc16fada94c6c277e8ce2c3e5e09b95492628aaaa902190663a755aaf5215cd7849b884c04bcf692ada0506bf84180caa48af74752e7f3dd7bbfca7322952ef968a1b00196885ada4b81c60e82d35ce41f3d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079f6948457d8d2453fc60d2d3e19dcb53d5660ec6d5c3feb10f62e01f722bfc497c6bacd99f767f612a6da999dc5cf9028d8983d5de4ae834faea103168410267b926b8f8de82d175c6e296a5d00011184f0d3536e027108b63d895fb3c46998852418ae90b3df5852fd626e9919bb90e09e74c739e25c85b971edd99ee5eb2d021b1c2bdb2df2322fab1ac0b9ba683b8d39c285bfe2009e0b56423ff11900d815030e964323feace39a6aa78be8934fbb3ca999fdace1714e4f98c8eb7ee98efc7b0b16f6bc69b8da21a2840d0ac43e66d01a4472b7a967b58941c1ff8e739b6d15df151a2e83832a0b35545755f255a2a3628bed918bd70ffb6375e704e54390a0240202fdb2ed2e90836a6dafc08a31b77659e34c0e98ebdcf66039186b296546f239032fc9eb5d43872d22340b2a8a5c5763d6655561ff2854e4b13e71e3898ab52ecb0225cbf1378741d7a0539db47958d7d0dbd28dad35381fbfc31610b5e21ec98ea10222e8b702977589da0c42a7e928d23827e6013bf21f996aede2bcf4466d1f780a0210540119f8695a2232920d5e03d0236c535b1d0d72687a6c20a11debc33bcf5141d522b3e750b628e3cb644a458b8c8fa45b9ccd74c187d57dad4f4f3a29e67b518705d397aaa655baa05e23e1a75455d61bacf19bb5f6b95f8ba2960094700e6ddb0b84e6f67cd2b12d961d6323acf04d171263541bd87f5b9ab19687fa12aa5366ea12bd6d13efa398cad8449a9bd32f2402e30edff0b6be92775c1b1adfc819c987642038ebba7efda843a067954537b44c4fe0d82710530d80f72343aff222081f09410969962a173bb5ee1dd017676ecd818a66f943e64c4590699220ac52eebf9a48ced55d75890fbc17476967ad363d0a374d922a4c1fde1753a94ddfe41d73ce6cff2b02f1143ecd818c8ff463a37e27c0b665227213ac18216f29fab31d04333d56b82f8f0b56407b849c4350ba83406b08828cea50cc99879b81378935ea7eb8f0d709b35dcde8a94cdb929fc23e868b4cb4162197d3f2ebc98275eb91c139f11dd21ff56c7b11dfc2edeb429bf9bb3d43d740fce74aa8f673ca6637dab039e1ca47b1dfcb15d8105c1b3312a1905b0938359aa20e004dc268912ba938aae3320d9ae783ab4237c2420578d9fd852204a18e0becf430e8b14f277b76345b556d4db73da5e086b634deada4456ee6ca824bd805492362134f46cde743b245bac579b93b19e9db1f34d00b7fbc2dfd39cdd35a9953aed4bda03855bef11bd11ecf033b69921e2e463cdb9690a6a1e2a7fa7412409214d420ac6a3dfb14e0f58b856b6fcfc76160b89421b14a0edf31c5671f95fe22856ecb37ed56f9b3e7c6699e5da9e625ab6e40c7b7b36c02e2db7e430b0cdf1d8f94cf4b40e20660b5e6eeb9618af19dad72e6f7fb55dbad9bd20de7f096e41e092439152ce437fb206af238e44d10a5f188ae6a30aaab33316735b90c09f11f9c59313f7eedca6dd712f5b979553a368659feea74c656ad834f2b1cf53de6e622674d9c35c7c4c8e29aacf9f907220940e051f97cc446de6015b61dfa49ba0d2384a6082efe2912a78cb06efc44b4d03f4f140f21524e9e69ccc5d60f327ef2a59af48e32a88d993db4d7bf88e35ab136e0fa454397087494b229f02f61694d5abedf818aec478473b84d6456b48d64c9d3dc264c5fc299188fba2100b30fa92a7fc66bc63dbd0c836bca22cfab9e8f5c2117c2b916c73717fc64c7c6274010b11dd8961d9da03d9aee4710d72ddc56464b688a99109cfdc2ff0898db382375962d24e4bd03b792e7bfd24d549407ee0252c789805114e28d0f24b7728906f9ea09b31bf03c605cfe44a5019e6dbf05bed1ae14fa97d12e90d1bae19a6ad52f14bbd41bfa8ba8a02c2f2248cb21e3b754e54c6a7a52b28fa193091feafb2572ad073d5e0fd5df84a520eed19cbae4fd0205c7f8ec915aab74657fb78982bb60f0a2bde0e54ef5012ae3bbd02bbf2ad2b1d02fa7a45b2fdf767ce78cba7b1d95b857163a68f7ec270e00c736677abd55f194c842aba4cbb6a751ae99f641b74cda815249ba98c97955884774c03759bc70eda0c956a443afff7f2c97abe4f0e7d673c09bda41d5edb5afe1173e87176d423d309fd463c8b4cbce67057151fdec266a1c3f6ec5faff9eaf876b8b6a65b9a8b69ae7a1d29b65b0bd73e9c0e68898d2d9d907d35f7218db61e79efcab1885f69ce73fc7bccc91d19f31cb992fe3056253cfb47102ea38ef6dbccd61d2e7656de9cbbfc077d3db9ea11a2402000000000000000000000000b5106545c4130478b3dbc5ec9f848ba7e2210cab41eaf4d54cc9ada944546f463f2ff374eaa60f63c3de6efaa5d65e8492665406445ed42280761e6fd53d58f36dc51b8a575c2f6345a4b25a4f6bd63a28ee0099152d4cfad2488cb0f3c50e64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a141f36cb65cddf8c5c2cb51995a369b1f9162ec8b0a5787918d5cfd26495198612631850ddd5f8eaa66b6a729c4a16f78ff13814c823ea6ca73a8f87eb065d262fc0ad7c17962400bd963586fa7802b5c37f3cfbac7512e2681cabb91fa9515a6b8db3ae4f862ee81234421f5cd849e25f597ab8982f2dfa8569f9cdfee3df03173ee6f60a0f21c6b2da7a7c679caf7b68654f34320c812e7c5d52b7f593e47d0211fc40485f96e58bff94c3238ba3a784a0f60966526a55ff8c4740fc5696a6d10b08012c2840047471aa2dec485cad7a4104320db4619f39ac3cff373dec0d4ddc2c44ec6f299e3fa0e2341f24d697d7b0a16e01e79071c26e14974bf343178b40021c352a82516328ddf581581431c8ebff6d35d05afd7b4d2c2cda0edde80d248e031a4d7df79874b146e2c5a2766a4e870a71ebb48b8ef65f238660ceb08b7234da020c7b9e173c29eee921d1c864e608111d6e937c0df67d47566918310b114946a50318022a8c8a5e818c879610bf7e086de0ab72c21bbb51d9e8d73eecf5f05ca735031b04dadc3aadf80ba04dcb3d6ffe5decf26b9e3f3c2fc41f8872b7e6f6edd5cc48abc47d07bda14f15accf263e365068dc5f4902e8734ef286e4eb1678486aa7e608205294387f7cd62f0b644eb9a58398903ec9ef5d1a039c84ac37c554c0eebee463c62331254e97a850c0af7ee4dcbe0ee1e0f84beb594d0434afc02ef7bd4ee0565ac76afa025601ab14aae1c00acc71ada53b5681fba32944b6aaf7f097eef6e61ef4ee2981117b59cc985ab97ed91f8a088f67741cfe4431a2854a9ee47c080f9d12845fcbb57fe15baa2aeb01fc750eb2ce07c18dfe76e32bb2f1ce622d4905e90aa114434325ce0cbff8e8ca57de8e65374576c114fc01d934d84180441e6c37c2d3f63fd5055409e67c9fe3d69e9e8f3184c715a925a3648039c4ef2c46271e9a512f87b77b4ad8f32df6cca9b976c390ca86542c34d67d84e2bde8662f71a98fb7d01c3a5941d94d02105badb7d708181910c98e9fd9d42aa51a081f81f45627a6915639b94813426a87a779ce73e8b5099e3c4fa6df558197d4ce34cd926c31ee7f72c3a8c55613c32fe387090c62fb3d1a09d1dda069f00c20ec08ef8a352ccf97fa5ee5a46b24484b3b200ff80378b81fd82824ce1f27dd6a5bbd42785c52e47ae4b267c44825ab1eaf9d3c954d9784630f0807cf38eefad9ebd73dee2b8774447fa94454bd2ead26d8389271b38cf5f1a145e6b0472ea8556510c5a91aa9b40611a7f9ae85a47dbf01836ba6da4f56639c0942617d8f315e6163017b1bf4e748a0a9882bd053383543c568044e6c8f8caf20e4fda13fa25828da66b7129b9124e093e6831d4a4f8b8aae611e483662dc4a1d8f36fbf3034118d9e17eab00ddfb560697269583e4667863bc7903fed6278f1513e6d37004baa90cf2e9613020dd1554b268280d1dbf4aeb3788f5867e098b06ce74e46e1466e74309d277bd5d3882d983d8ead5cdccf279710ca088579183b9ed176bc87e13a1cdbd034efd39356690cc8da73d8f254df60a02dbfc0513b99ed271f54ffbda0984a4a90156fd0b169a7d4d0696c0449c8e73e9c4719f52ca71f7305748b4804fa1e4286572dea5a9183b62eb37ac223e0096002b365675b0dfad43b7073899c80fd0921ae5865cf66566aa20f043553d58604056fd2182b1c983cbafab0549afccec86093e535f835bde3f1c2d7ca5bb4d00127c7b26d6557ff11a8182c3063257076ccd2baea2cdb1da9dc16719bcf180ecde5e9920634947c82dcb3fa4c60e7f0eb8d6c262a5e9d281ffbfb7f5be74ae524ad4add84a2fc3f4586e50937d5d4d07130784c77feb3d583faddc601ff5d013f6afead658c190c9c67631594e5d880038bbafaac85058aa2154a50ee899407249e7a9c52375901a67e8b613b388e10485a26e5586061409d66b7ff620151cdaf80262a4c1ae5ca923dcf6a782a17a3c26d1889fd0b02fa62f3f11723d863f8598a1c50adaed666a05788c8c79a0d8366cbcd08ccdee2adee46caf499e2dbdc6767c8bea4ac214b766978610935a1403dd32be85f7ce566066603e12c4c1725ffa7f09284bcf8b282c91cfafeaae86bc58cd914d3e1f170602b860ed9eeea7c2cc13cbdd4d2d0b4ec36e925cb947fa8183204178a5eddc62b348695b92f29c09d57e9cea0bf8ab956599a84103b1a3d4ed668b60179da599309d3651ccaa579b7091d04b64a1792931f515c4d9d24a586e98838af9f08b54446808da82bd3ea300000000000000000997c30400000000b475fa70d9de06cdef8be6997b04b8e9f6fd5873441feddddb19a1953c8c195e6026befb982c190e0cf16ddff01d8fa36ab7326a8958a332ce5cff59a2a2af0ad516ef14d32351db950b4afe4ccefd288a772b6e7cc4aba38eabf42102da30e6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ab375298139c3a0b0aafdc244b6fa3c991b94ef8a9f2dac03dfb6a07f458d2683f3c7550024edfba3d8c81200e613fbd22ab7bb87838652753a53f5cc70a354ae2c37e2ba0a1b7de94067b73595760c58653aac1abc0f02629d7a4836f2bddae36f01ce17ac1c934f2a9cc92ff7a4f87ff601027410c646c70eb4d5dc082139021ba3b0c3e56c8a14cd8a1f48abe27e3015382444d1be151831ae96ed3ae9f859020e5f80ee2a24f2fe5635c63e1fbfbb753e402e538ff3c191e8984416ea687b7f0b21e7e7e2ef05ba0f20836fc860ec9697e83e99ca4b328cbf3690927506a80fe7185583f8a8c7ecaaec032c4c913c35b9492c7fb3c6d518544eb7c94a930c6f4b0312c40151706d3ec311a218f5e96d1fb921bdc30fa35b3e1d868a3539fe8a719d0305cf07e9c0ee5e2458392cdafe20c496ee71fae9400095caac1d48f4fa5a50e0022dd83cac4a92675de5472a783268edc7ff3a3106ee188510d707bf063691f236032027475e581087c69ba1bfc162516358c23b38981055acc1bea09223ea78203d03137751aaabbfea1ae03f853c72d5239f6ae33af1a8497838a4eeb556ec27a5e9a59fe8398e8660d7f8da481051f4494a49005dbb8313b67a7d5125fa87c8dc70551caeeb213d152042a023ab3e60ada42c08cbd12611611abe9e1dd1796003e53bfd1d86125996bb3bf7619a562c70beab017d8db088e1837fc7b6f7bf3d7108ec2330c3c2e71f0313b751ba7207297fdbd6ccd76d7f826d3dba9a875e8a6ff7d4e3256150c682498a205f811af03f4a47b751c7ff6f6c1024c925316cc3608bc12b2626e44d5f1b385572fb4fa06b7a73b2deb4f35c165218ead18c9b321ca5323f77fb7469320c3b58204b16afc426f79d530ac885865d0be30def533b256863ddde538e24bc78e8ef089aad20bfb0ffd219ec5ba5d92944e530cbc25034763196173379a3601bb9c1bc636b58cd0c4c75a2056456b61e9d88888bffbe5c9aedf1682e2c60718bf0ed1c80dad6dccb11e09bae25b01886717336e845d8ffafa9bf39afdf361ae851c422a60fef9d52c0ebaf34e459a5bb7ba0bace46a03435e9fd47e19c303287aa05f29727383a00440ec513fd05a4696f52d8c252cf3b1ea5dd1b6ac0fe5232367eb5d33df050ebb6d0b0ca048e5175c7fe2a6df50160317311cfc1afaa9370c27a63150ddc87f180683f85c390e2d33a31efe30d4494feae3b3095af5b85fa90450d9f37c6ef9d11c19e23e6dc3c020529c6614102f51c97eeb00c5808d773c7711e8144839ea9d22c6637c11c6dfa85a800d6d0e147cacea4b794ac9970ee135d6fe517dbb5170c7fd020bb248fea1e2f01caaccdb5968e896e5615ad53c0c3a9e9191d55dcb598d7e5d9232c05e5b46494dd834888cc0701aded8861c664950dafe1a29a8ddd78399c1b6cbacd4bb90a3c8c556145fb7b86ebd91bd0d952c58874f9fba65d08c9b362cbad561aec490a5fb9057c7cce9d084b2854fb782f41176254277da637c6db0761a3b7659634256da5d3d0668789e204866c4ac6aaf3b6fee9e11e23b4e07ced4003b05347fae0f0098f3a1f87e7963b1ffb337cb301c3476b992fcaf0cdf6426b7bd6fd937043929166943e5eba4886c9119a4c64c48cb741a759ef9a1895a48ddb1d42b3740aaf34911bb4dee4dbff70138665acb97e7872ff08635faca3eebe1bac533c17e398597e9620ccfb0a0b23e51e7a48f1109600f59a5f3361d746e8635c087a488d2efea3b7a79a529e7f638cf8b4b529c86b347d4546d0b4bcdc7cbfb845b27f12e9ccba943a030ef644f79d8eb90c8a5a840cd8a96728c128b3c97860f1a58020320e56f9ca37cffe9b3fcc6f78dea07a0711c5bfd5fc87f5bae9695d3b58ae1b583a629bb10d09da0fedda26f6c3eb272dfe0fabd15c0cdcf97f4fa409c883113f4caa6564670eea9858571f727276902f97efd57285718b4450ed3104eb6d5385315a75437eb01c60c1fb1fe111860be8165e168fb79ec7e0c6a0330e3b9369ea08748ae3b4475149f06243bf956baad78b767e66d01d70dd6b3720bb73d597e31e568cc9b3c73849c41e5b603a99219c90f64d0ce734121fc0e8cab3d140373f703a621100e699b0519d49814e67b373368ed1bbeaae331d84b007361bbd46674607e3808595c56aceaac52bd7eb3f9296e6dd5efd5b2599397dac58c3320563301c093237ce7f9588a16a227a92821a4727c4e28112538d6491deea922c11d8be430475d7aa6bee99b881da0d2716242df9d7bbad7bb7332bae21701f216608a92d1748a2b06dca8d0e02ccd1289ce17844a31957d174365ef67b6d5a0eb86af951cd4bc68fcf884eeb825e9d24545c8925a97d0dabc483fdc138d765b92a03b883494b32c3ec887cade9ba1cf899c8ef41e8db23000d", "", 0, -525426326, "05ad36f31aaa3a7c4074abc9b6a534cb7247a7d91c8552fdce625e2f81d4792f"], - ["4a7d367602e28c07a0f861c9446c93020803b159076c38c76bb71bec387eb4cab3e12576810000000003ac6a5283fac29a83a7acfd0871b7f2abe73d42f3587798e51f9150329495f4983150325e243f7003000000035263ab9c959b0a017718b5000000000002526a7e7fa713010d6f7f030000000000000000000000001a5407707795b7b9d240d5ecf456eb071486ab837e1ddb56c1d4fc5ea7fa68db0c3d11f163565244923aecb18a3b984f08a2543244931a2d5cdbea041080a83863e33d6a04f13aa7d197efe48db9912796000a1cafdb389671073530d56b4286000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008cd0553361491ff254da41b9d9541f74dd4cef3da03aa0f70fb3263864fde11640647f3c5b65bcb5f9926835245b0688e02b9a709e5ac86bcc97ee5b885ccc01f9375f8f66637174df4ae2ccd28761676f6f5c2eb034105ecf47e3783070418a68afbedfd02b7a17bed2e0a867b5f1b75a4077d476d5adadc042d10e2a623ce2031d8bddbb547fe5fb8a8065490c74a6db2892417261aa9c31fbf108aa185c5af6031e7c90929308c1a708fdc5c9df7e0c927207f41ae63bebeaffeb7b548b59155e0a10382fc0ff43dc5f9e3ead0f9c3297b4efae395e9c48864d287f75d68bfe1b7b27e3cb7594c9f0b7f43fd1dc10237c165ac46c54bba48492f2af53811b860a8c0318647ffc61b467c2fd761333e497e8a630f4db71deb5ef7ec102d1e69d5c8844021828e4e3cfca64197d7d343b1c5f4c3f3cc69ff5facf6fd7f656c4fc4db339a70323684eed5e5775102cc6348d382ea8f5e6607558b5636ff99de555613fe1f5d60322a1d1d094a7ff07db0ddd3686ccb254e6b314ba6118af3e1dd2daeeaa9804b6030abb84950719e0a9eda9557adb716fa9cd0d48d4aa6b01d179b4c9c01815c0340843910ce43ad089127ddac605e5d9e3f7e4bb8ecf0c230de66d70145f34cda9049c256e9c289cdd199e29aa835746febcb77837e46df1a4f52f48f007e839171ef0bd17447101f1cc99925d67e296331ebfa64608e67171fb8a75d50d5104477279e3c2520e494e5ebb9628ae3e5b9f205cf7f45b8a5064bd04dc96762d8d58cfade997eba15262be13bcc3dca27d4df74aba7cea3ea1fd7e3f8b7fc6127f306d9bab5652cc5fd958169ce503b4a76cb5b98341d9b27783063a682080ad010d5f3eaf6d78a236dfd44cda0149e4910c09586658ad61b364589b6337fc0cc7234aea8c2cabd47f7e00ceed1b9abe8f771b82d8987082cae967f537172466d7478c4dca8bc5068a263fb3e161d172abee86c95b96df17d9171e41165a1f5fd6b8cc7fd709cbd132bf22a262191785c55d519b119a2fe70251cb44aae95ac7cf77103d41299d2a9e314d010aa0e0411a65c047d157e9e188688a09922cd68a4ae2984938a404f766613df8f36af4a8efa419d827fba85bcea5d591cf544f40af61653d9430cbe5afd147b15c05bc2921fc354a4da435163845d5e4cf21338427998af7a122505b1f3d195abb059aac9e263711aa3933d75ece78f1642247e0b5aacb4a80fb9e7cf71be4e134ee1b20923093f05dd2410d417494d6265b4d9d747f0abfc236c324722ce47c8c147a33399aadab8b6fa16185a4f4374f1ef7be3b86f4b2b861b9eddb2b1b1c3d08c1cd53dab73fbb56e7137be929be5e91853e6cbb25c5e1903a394133388bfe40e46e3f80796d11cbad37cfd82b0ebc1119bc50ea50c51597cdd4c0e778e755723dc4d2c1f18acd24510d0fefcb821fee783a50904e84653ed0bbc21af294de79d07aa82f5a6574ce658d332b6ae3f7bd97c370cd443210c4be9b883cab50c8ca410994e4088e68056d4e6cb03e1ad9ca32eb8f6fc1f98e5d54680f02f921cc06145717a226ece59b1de73c5ba7a3ef3ac994d537392d61284c1b021350b93aa0b65bff94ed3609ddb1ddc3d29920a31d19c9836a94db293405f1850dbecef0509df95fcb6aa78dab59dab539a62feb81febda3cbe75f4842e3ad075c01c1fb339537c8062d4826d5e56ebacd5ff69e4ed7e4ae75b421b4e46a2061f62da2002fc9a18351c487e2f18dbb42b36aaf6e540572d5a106e52ea71cd225e0734f31a3c4cd45e8093b5a1cdf1da21eeecf38376ab68383267c83a6c02d4813a0792e30eebebe06004aa067a4f484a6e828a7f8311b11c39afad19adba5fdb0af30389aa9a97d3c0af24834656da6057ae931e32fa77ccab57153659b66df98d6b935c7475d4dfeb00b39147b2b09cff740dc00a37af70952d49601a7ee6f39d3c83f7426d65e05ea99da219e38ab1bf3fa8275d8a81c4d912ed0c32c0f608cd6dd7abc471f416517a363b7a144cc8478adc5098baa1f6afd5bdec9cf1afc78b5f1d8c75432b37ed0afd337a2d1ca894b787f36c00dea53a1250109e6e0a1089abbb4d483ea05b95ca8299eb316d4954337faf9e5623a8b4058f66b22b2a02e873c4c14bac76973097edbbe74573fda67c75a5590cf3f6229ff8a33624018b393e1156a5c7726ea9f337d3ce3c657c7b1e797f0598e5a39fa3b772d7c10b58a363d7fdf2ab758fb1e20f653f62ea689f7074017bd5e2e0c81290ccbd9ce8691240d8094dbbdc7265948428dcdf872a588c0a1e319a2f55d9dca25321bc37431664768cd4f64a71b4323431df64cbbc5f535556d378cb2eaa4730192aa9c7380d46b7fe1015b9a498275c99eb122ad883e5f8c5b3e5375ced48dbe1e4b25b6c891a2cd2cfc4ea3966205", "65515152", 1, -1529506216, "e1504e9d9193d0c1d9bba238498bcdeae96ef268e978743909f8bd35ec2893fb"], - ["0eb08e38013522423b6b3f55571b1107d5c111363cb90baad9c72ebdab18419bfc81222050030000000563ab5252aba2984e19012802c6050000000000094ddf6b010000000000000000bf79600300000000d24c87dbb4c4d3a97d51f1b7d414dfd2ffca31e99c3270f4a87907a500a63e713e1fd51060b27a6194d35184e41317f76da7be40fe3f589156464dd915c2d35504d51de0ea8a03858c26787c8da3c4ab374240c5fe55ff3bddb7f28c084cd727000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ea2cc770e8b74849e0bfb578789e38a5be9f1ed9dac8e1dce610de463919d5f6b1df6a01aec97d76d97fc9ecbe67295dd4d2ee47e27344b7e7485ac87b53a935cffae740618b1abadf35f1d05789485827d163d07acd790c421b3ac12b279313249880a162324c98a997f89b2cc72d9335db64e339e616b97f5918ab5b15eda02016b6e101dc14bf1dbe7c3093feb34a7842cb8fbf7b61bb8f65cf7d2bc3b4620022b004be9984fc77194d768fd8a15b52a3342fa4f02b7d1b5d8a0ceffc40f69ac0b0b3b0a8b3956cac814b4e6d5da6d9c1fcfcca13b2e23b4e69607a6957b0c08062ab6de3da010423a8f8b6eb3e2ed7ade924825bca106d00fd412aad961d9512b0312c9e52192c4c5ba5b19e23d8f7d1bad56452ddeff7ec61726e70e2909697e0c03051a26485e29a3772a794b7f8190472f82d8bb0d2f0c39bdcc40a1ce10bdca5c0226b47e1b0529f629aec725dbebd5da8a08b09db7465faaf8f8cbc321b480fc09030a0c80318af7f4d9bbfe73764af7d9ea6e0bde72dbd7cb292ebed119788d098c03278e8dc8d938cbd833a4d893fa115d757aad8ebd08a94c1d74a493738121943fe3de06b3a4894cac7db75609efeba38eb693b9393c22db2807a99b09593b00d81d755b91e482c8d94c90927bd5aae9856786a43b60a36271070d481baacf19b08296577d6dd5b13146dab13485262fec9c1f1f011066c6b2cfd15ab6ff2c6c1b21c3f01b6000a56f7295d86e977b5660a01873497e75a57edebe63c10911db5896fe5851c52bd06a9327b9bfab3e25d9c769a800bd1dfbc75e365813a22dbdeb97623de1ef43aa6262519c85c492db8a6b59a58eba50d8d3b0c2f301f13f34f922a521fd778fc476e7fad21b1f6257e5f5ec951016624608183c258e9a1619ea47e5a04412d7d0d49670298f85e536ee6ba6deff3eea2c36d5ca9ae7958bf9fef253209faa431b96a84b29bdb96d2bd8379e2a3ac88acb4c56edbbed1ff4d40abac75ca8be7ec526405140f8bfda2139dd0b072d78025bf1ab1db21d174d6763b8217381ac385f50bbbc651c3bf734b95e3a81b1051898aa3c84a862fc8be660cba796b1d8b22cd3ee8469b9fb701ff47953297ff59f362dd21c159ba90d34df3240e8aba5148ed3d311499effdd7ab07a8a5501c59edb0f62b6e588c4949956fc7e62a0851c78c6ba758281d84e9d3089c8bde0b9edfc8e67a97a4f2a32ea37647c47867cff72284d5e1184b829434163e3d64906a0028cd8aaa0333be8c0b678445b96f85617538fd612a05d9b485df38a729036c4abca5515a405022f7e8b5bed7c149852b0f5e121d4eeb9ee9bce9731b119db1e2e18c049b552153b352441acb02d1574a960f406259fe3f448a8f7d7ad8d5f8df997d1645a2df48c6f41a4375b80085e0e0c2344ef8bb1461a1e2d9bbab2c6d5479efb17a6fc97fe0887d1e84a835bd8f46889fca80334acdb50e3fa314902fd1aa90d9ca2b605eddd0d589ab04cbeead839fe9f59ca3a5c92575a0c9b7b239371655189ff7bd09bb646641f9208403e64bd0561d669daada0c7c16e119b2637ac7c9440e0aacf9e3bd0597328839c7a36ace5f7e5ff1d9c72af99e7b31e917f57f411c59586d5d399d029c21f5df935e5cd628a692f22c0b034d6e8c1777ed568c4aec4ae3597d26b727f64de1879b1b484ba971bcad071abb1ad3fc1fc1abd44b43007def991508b9174f41a82cd44073a88cb1f48d18dc04b83a1e8d66b337fc42e161a63521b7fdcd1a23faf856d959e960395955c1fb3fda9a85a00e5e2c101ef59f607d90046a5326325380c3fbf3ac6c90d799c9471263b2ccead62d3ea6422b995aef9e12fe974ff4c2a5d2e85bd19cd7a8ad621cd69b5c13d87f0d568f7acde6db59950839fafae81d80209d083143e5ed0e884da3dc782bcddf8b46bacf83c7c5ad33b50962e30baaeedd537a2956764b06c95671c04f77de9ea61d87e1ea40726605dff23a3bfe1c5e0aa9b9ad2c7d7540a8a74c52f861c005443bc094fb7727dd2d970388b3d18f1c454f158c8bf454309d5fe6a6d67a39bcdc0f1f3e339ac0d6da7abe072d6d134c3b94a470317340d27a868355130d1468baf2423b6d650073e66ab37bef561bb0e537a71c453bf94d611aec1ac127ca86ef12c4f9794de3546665d7e9da2f3512eb160001f1ae7ece8a63745706d0e84b7c625151bdaa14342feb2931b894ab889d1c81d5b80bd72244bee3e53db51fd75ffd07a1dc28b7957c8506b2c49ef489609c93408e194fcb17ec11a5362f836df25e1906ceb6e56d0e4ed64414bb7c7854a1aef05632aec7772daf1ee1fa071a347063203e5e9b7c398cc342845e58485c82f9309684d24b4b4aca1dbb8283255cbfeee3fb9d99a030e00f531ece0bd3b9d1a10e0bf9024361782da350c", "53", 0, 252808238, "a4249f889a2f796087c13a5b1b7168c1a9a40a618c240af235cf4749bbd0b7a7"], - ["a33785a303a08555452af9a20a2d3f9934d8080c6a20c8f4c583955d1c96d00e499af5b52b0100000000fce5ace4dbb4a833e93f8389bd94f4b3f645200aaef654673f5fa23e492e37c17ad58fbd0200000006ac6551630063ffffffff84ef3531de830304cdf82a40dc6adaf1a7be17a1121a6b993fafa2b4e965836e030000000951515300abacab6551d49c21da0242fb12050000000009005300ac5165ac5300e2c901010000000008515152006553006300000000", "00", 0, -39698101, "e9c3a082ae3618fc70c65bbf8214e5928e82c18899f97f4d907f13a9637a9456"], - ["137977c20198fcbce246434002f0d0d178ffde4157ca6de20d45cd7b9aa58608c80af93c4103000000006bb2a18602747f7f050000000003006a6a54cc3503000000000363526307bd2f9d", "650063", 0, -1110739385, "ecf9f8c43b878dd5544b952e62ee64307f611a6395d6b121035ab8f72add2db7"], - ["96cc616c03b30686fda9e6763c5b214f19c204088026d9c7f4526d6fa367ee5033b620110b020000000151ffffffff5dcb3c783e17d7ef49065a1fee097f56a1805dbe0385755d015acdb5122c6d2201000000025151ffffffff4412e8de019611899681bb945410b81a74cb5ba92df34082c07f393085e71ee90000000003516a52ffffffff03de0a1f0500000000045252ac0015675705000000000851516352536aac00b4f3a3030000000003655151000000000285129902000000000000000000000000dd06ab591a7a2e814ff878b2906ab0d6f84bc742c7fe66353e113d09f14a5eefc339348f5a1ad9f5d2f3e426583abbb1b9b5076211a8913e0fb9f221f3f5aa08166991d2335954fcb407c1b8763cec921b9bea40d3d33fd5831f703b46a5612f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d3358a1291f2d9498999fac39f0afa94d863411e2b7a33cee9aa9f20920acbf2b6be9a96cb960f5605105e0c0f681eae57098e289e784035a3902d72def0196bf01b12816760f13fa60a73280526a0f7fb95ad96bde211268409b45a3ac82708811202736709566fb5ec68df1d88136b31f9e3419982c837874079f1c28ad0f103213ff162a0c5332d96b02a72d0c46d1bca4e6af9578d1e497c38883a341c07ea0305d75ec0ba096193e5fbb481020e217edad57c988863a6383d84012b5d7cfd090a166e897b37c97b32d7cebc65aff425b0ead37895331c2309adf975388e0eda212e4ae9a82386afcfc3f4af3ab8717d63a76f936c1c94febe9a29bb09ba8d018c021e76dc5fa0c282f109fa18916d6d15bc03eea450851ad16a0cddd7e7a4a91e640319b0f374ea398133a247dd61a4f74e8592ffa6afe9c65f8edbb62984d19c35b2031900326f830716309eba2c0b488586168efa1c029bdf35441fb4913198bdd30e03114a3b98005b20e262b788659685e8f1bfaff5a6ed17a5cd209107a448d1158d02208964665a3c016a5d0b2f1bd91f74debcb32132a7fcc554268e209e56a41de34db790bf397c97966288c5c5405286131becc86c32483e86431e882a9f4a7cb3cf1b1f700e86067bc5a57eff47cfddb4e84d599247f64f4379446deca12ec2950079632563aaec55d0e0acdf9158e03fa8014a13f9b180ac7f59b8405c986be1688acbcc73981804811ed132a6ae84815bb3c04489477132b4107b95869e45e5297ef4ba4d2f72198489eb6428b240e2f603af5b8bce0102b3a67760676bfa5af9a1aa146f63c86cab8140d2eaaa924d068df42c83582c39803015777127e8151b77e5380a3a4d8f6a8d84092b5f2ec71dcfa0b0e39880dc825d2e3dfcd48fc8a486be4c8ee665840d13c3f99b8a4321274cf9b00bef40a3cca44f7697296c4277448c111ee5730c845f6b346f4cca20ad6047c1707803ff64630e5387b9f7bf1e31c6cfa051aa1f6682a5d7e86722abaf5a24d1dac1a6337a3109b78363e9dc3a7eb47bebee030bdd500f608841df9ba5199053846e5c2391e5e886dabb708d48134c6240862ed6a7b14698738783d0d2d22f46a67ff65a2ca84d3ac100db4dcb22db22790443ed5332feb9270c1ed0f355d96d35dadfa5d91b9fb43b73eceb619777ab32b01d6ca24c647fcdcf704bb3530c3279bec5f4343a764877c909eb193f05d3d63e4a94bfcee56f4f587670098a5a18b903af582dc91c8175305866ca6c2c2e6c6c4a47f51eddf52dd56e58aed36c4899b90433cceaf49dd29741504108dc1c8a6aa159a9854f8687f4c51e74f2eab3643d3d9d59dbb921c3dad1fac263b5bcbcea8fdb5c04b15750d8bb282e2ffb945965daead18d7b11ef852c9bbe969dd582c888ce78fe15c3f8a323747f3d703a8fb9b0ef6e3e2acbcf22ccf2603d42da9d905a3e9300887befee6dd3d9f84aaef435eee9b44122aa207bc8718edc2168c448c8582ccd8507d01ea21ae7a312a4ded5b3e8bee869c17b6196b4b0a68a1f8941b147079c9d50a8713308f63c56585096574d8891c8163c8b5110f11531640e0d668b82154fad9c579abb54c820fc3aa9f70063c506b01bc315d59c0a907f20f0008289bd85cbd4106c6c7b2a50355819fac18da5f43a0092612676eb0a8b295dafd15840f7e784845be2a3e6fcc07ae995066dfefc79402c2234b1045f118b42ed030c3a70504ee85828d9f2afa236590f498e53c98af7a05405f7a47d8fb46f642defe14d1ba6bfedbec89664969c08d9777ae7ea84bafb929b3d0803e0c5a2b2561e0fcb93dcfd761006fced31d9921482fb32b655fc78e086801ab3b3157301f4a9fb4f793864fde538bfbd21673ad7bed859ab4c7c63d2a051d4cdd0b138fa95858c07d990c6e0d6fb01cc530d0c8ba46f210f15ba55d3a7130b7a934f4fc6a313638a39d0262330ee65f0cb9f3405988302c381620f7a799143063e59df0f3047e2dd69e4b96089d309a4f5c34acb14e35b6a95f0d69971b705f5f991ee78fe781176e58c6a0879bdd50253a4febfcb9f5bf476f3cfd1c1fab1fa009f08b0cd45edb16ff13df4fdeb4b1f1a42c058893991b3f49cb86222c212c1bb56cdc958d8a79d0fd42b71174653f1fbcf849bf29d2ace9870f491fe4db63f393fe24800f9479a82da59ea10ab35c4d0cf7d4f9d4df8d716a3b3648b171199a9e6b8f7586d6aacdeadf03074336d079467b7121055e59e1cca477774a76cee77ca70e59206c171eb66a93e87ae540000000000000000e9754a04000000004bcec5c09c52b0d1d11df60e7a320ee6268d46356942da86126f255758978797819623b39c0445997d254436c83dfb02a64d625faaef1158b71c9fe125c9255910890a904b1efe435533fa03134ff032ef08cb6eb9e5b0551de20734a6b014ef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052529859f907674aae4fa7e7c4f45132419cd3dbea1cbf3723429a35083bf8743e714f94249e39eac837a56c3ab91727c74699c16f7e2c6cc585eb0670d7d0f2c18d76152cfe13ac761c3a82a679ddbaae56210b66e7ee2e5743e34934a4e30be541fe46608e976f8e1e6772b2e04cda0d33e9330e3611b7ab3ddd1d10e2726e03217265bfe5433a4c81868b94ff1550027b9e5eecda1019ed13c2c9dad9d0770e031484ea9bad28f8819a31e1c6ec8ff8991ddfc93548d6325437d6b8d28d14ee040b1a7fc8c2e00d456ae41ec93bc80dc15936f126f6da3a7dfa22a7e6dcf05bf7d1163e2d78cdf8dc272f4b3897a743405dffa5b935933f68ef1439f89a2d8aefdf020e7ed8c086a6bd237d7e31d91d29d630f0ed3bc686f21c6bc947e855d4b98bdc022ab98c4556bd227dd0ce17489721bd958437591c981ee591e0a4a20691dc9484030d489ec1528f9a3b0a13fc4fedadead49d04a2a5bb90f9de5c3ebfa631dfd30a032db9f5010edb083c3c4973ca216d0d64d183d7874656859ce6bbdb0b4defd16c031a9004a0e0c7be61b98999e05d1e25cfb106b726151995fc463ac73911136337e8ef32eda6e768785486b1d942424d57e46f02fe9365ad35f2e76284f93b9a4e1cfd3bdafc856059d5b0f0bcde4a0d7ffc3264f02e12709614d445b409910708fb6568920e5eb3cbaf469881a3d381e5cad6d85a3763ec3eec7877e604f96622f28c43908bac0c2dd37467dfb040350f469575d455d8ba0e34b84dad44f99c20627c7c911f8bff289297d14ef40b0981df4a7b8c78ca15840be9e4dbdec8da28a73b3d05e58d61dc348d24065cbee248410ca8432832e974f4a6d096bc11bee1502ee50ade65b832032a64a49e294171d1ac667ffeaa1cc0cde497f4d4c8e940a379d4fd2473c6c29519b7979adc6c82f404cfa94b7b1be948f77cc24f020e86ecbe271e809b8d19de1ab20ab6a7b2e15d2730340eea7e0f8d5c04043de531ca6a1fa456f4227703ab38966b190db175b4afb2424a49ceae209098eb2e58cc040ad906e6ab8b1f4c5611f32101f3f9de8518cf2aa3e1a3de7e7503072361f76ea1f8a0a6bdf91ca0b0fc6d5e04b4cba06f45f40d745a02a69e282b5f469c508445902f569494d484c4ecf8620a5ce4d59582886a9bb50ec96c43d6d384a07579929a4d12d6a960ab73fb39877a895dc9e489dab651ec3e6ce6b85ca1db5c90790419205519510d4918aaf61afd99b9fa58309f9050e4a47c15fd86ddc0652546d11d8248db8c82fe4797345c1f287bcf25af9ce4ee4b7d5b2ecda03454a0e2b77d324b9e1475e1740cece6efc82f7ecd10e1e9ad0624dabca18eda76d00d62baa8e7871ab627903ab4aeabb7a27aab20f993d77588bf6b48d9a6f7cd797ac591566be547ac4b7cc9cdf1425800e68e61ad3bca13fa3e754dcca62ac52703f7775a0db7744d0d28b92e205fc4ad8f83f763a96ff01342ece226546d23826924adf13eb19ffbf2e3f5335c81568371e033085aebe095bbb9963ccd5849c767bf768272e65243657c43d9c990089c0b86644c2e18165f02c7486d3fa7358d17f769dafb869fd56a993045d61c5c56e85463ceec8e0a989e3f8a292b26513a623c68c89f7534cc3804d24aab919026de8a0c081268f859714e44a5f320a0b8b4571913913293edaf7c6ed6ea2eeabb61902078b0503f94f281ecce15d65940b83eb468c7cc25f0bbc8783b9cf4b1a1fde5a48fb5b50d6773478d8c77938cda56af63fb94059dab963c4ac5088fc946766a32f391021b71b42e8e8d9476778f24df1a6c12d69efd31f89a8787bd9f8e63e597ade815a78b07885f1cbbacbcefaab83f9f7db1978236c79c3404959bffdc12ac0947f69950c7bb2b01654627412b163323fcec82be9a51a41569b175117144b63b2a994ae3a7b66c93e8747b0e79abba1d0d9b9c304c03afb103901e1e585eae35266ba9fb36a8de2d163f7db65a09ca86856a5bfbeebd940e7b130157026fa863998723e0435e3b8b98255031361a89eab63ef4a6a26560d4d9e569c71e9328322172defc3a185d32d472bfd20de4577174e5b04d7d51e85eb687b12e66f66a3a91a355e57f5bb8082caf4a2ace9a8355e4a0f209deee07b5c786d49899a0995550cf6d164bf66bb918857b5e0114fadead8d357ae2449ad00900dca9a576b79370d2cd6320482828509430597cebd5fc6819cdfbbc278f5722b99fdae2e3772a34ac95283c793c7cdb1c11caaf880d326bfe62dcb3e5896acf90ce018c83ae9b6bca65953829204fabab7f7a3ff650a204f8098047ad97fe86d2717dc4374ec7f0c9c17b208e568a91bc44c6e92c951ba347ae4fa0671aca50cefec65ac707dc2a7d7a76c2c9d393069f9d35ac1029744499d8489ba439ecef0573738b78464601", "53", 1, 2091089239, "c279c9ffb445d262fe55b609f193c0b8db15e3c3545d9791324b769fb6e06496"], - ["bd504a0c016642b2c7121f82f0be00d1a6c0ca54d964d5f5ae8ce6f34949ff5d848c580cf00300000001acffffffff01f28e18020000000002006392c7267700", "656a65636aac", 0, 61419673, "cd93d1c352702b51d43ffeaed094d5cbb11a6651e353edac3681153c0770180a"], - ["1519b826014bdd71ca2f2c105d6cca346cd86c2fdd1a08b6d3fde9521fadd72136913cde8e020000000251ac7a2b7198025d988802000000000563005265000538bb0300000000016a000000000214f596020000000000000000000000006053ae1789765f7035b6bcd52b27743a14a4ef303c53b435ed028865ddda55d571d8f5d06015a2dabdcd3daf687669913e9cb10e4568dcb9b7ba8d9e7f251df9b453e05e2020aba16c5e030f1c0628db509ed65f6c08c8ce0ba425ff4389e5c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000968db0e6ca1759af78105c5fe4f8efef150102c7929661e0acb6ccb4074caa77ed76b4a8193f0bb0634955b477c0af40fec5cfb6faa403ec74a2e3951b4650015357f73d195b660b39c8e1f34b1a27f8160c9e0bc0b74b37faf0e879f59674dbb36365b7607f91edec7010edfdb7c28968fda77867399e5f34e7732d7ead5412030b80ea3c9d346d7313d3b661339c3541473f7f4c05b24617a775ac45d492eb97020e7498a3f2cda1750531ab5310a692e11461468139b22793d51eb8740cad4b840b099e7ee10e0ea9ebcd3ce5911dc6270e15374aa3a3c1b4534b0a928e9e732f5b194bdc2b9f59b0fb9cdf40ba452628bc349c8083c9520bd796230a70a93d3b8a02233f4cf71d029f57e3158779140a76a114ad94330b623b64643892b54c07dd5e03253e255958ba1e9c7d529cb67cff46b8afa4ea931a62adda5ee39b2dc7aa9a880208bddcd3af9f76d7e69814fab3cf78da90ebbdd2464abcb3cc7632b57ac2d87e02007f5aecf7cd166c07347f6ef77217ae0fed66420cf0a93fb4f71996b97cf7ad03039608b6ea729b5f94013a3aa04a16c425bf2fe3e5082d0038ec210ae252055c98abd277895d8e50bf46edff89352c151a87f69523c1d86779295c376108cd8504f9882e746dad315bcd346f4673da3a614f33e1544c4a63d495ff4b1daf96e6b24d598422c0df6211628e6a54b909d8ea523a7b8b269ca6c78f24f629314358c0f26fc285d3a8b75da25283b51ae6c612a288e3b1388bed37e909c183dd8803d6e2723d24a0d9035bfdf01c059412257594006ec51efe78883e53a12711e4f82dda21eff248640d137799842c696247032fcebad8487aedb6b08af5d38f9ea66c5a1cac436f8e97d93eb49fd8bee6764f04a7e33c5325aa3483396fce0d62338887babbc8fd967e85efabf861ae5964615fdaec487c60da6d5f12d549c0abf2c5049e2cc1874c3b4bac1a9657f0bd7d5a65cc238d9169211cab4d48a0867ae9c28a0bccf48acbd797cb96b866481ac65b77e2fa951fad5da11134f8ede75d24ee237e7a5d1af7633e2a25de837e8003da59b76b1a3445c5f6f54a04a6faf6e5b7f66243990147dded7bfe29f79e360e07a6056fc53ef9ce133737c435cf28c56ce541862228a6e4b25c3ee7c6c8e9a7dc3a357e3ff6c74d53f872cc66d529fd5b3ab545ca1da23863790d586913d432cefba57e52424c3ec3ecc302b5e76efa6a41af795b54dbecebb2aa450e20c3fe646fac0d02e4ec13a25fb7eb1df7f7e770c441ff52e2550e11a82d02b9544f565ad8712e2ab7462c0891a08a00080391e1ccd5c43a63161d0d60a14576a6367e19ac6920e3ca08aa9074a3943b7513619f085c618b213619b39b9966ba132e9f91fcb537fc3d887a1ee0d0dde08dbffad2033fda42bf3f0173deb04ebfa2030757c7bac4b6863adac6eb921da855d42db4594d91a41ba5bc3d5d512baca9f08c320544231f3aeee107abf492154841dfa718d6fb29ec6fd1e26f56273cabcfc9933880954db3644c08942747fe0f10673fb58def982919454499f5fb70fd728d50cd9dc29e06d676f73af1ab542767920c64749574c4f6eab2c7bf1fe308eaa04f0c9f35226d9d8cd7203cd7b5d1b41ad08d179c324897cdb16411a1eab41fb79c73df99b5556acb759b872e26ba8d48ee4ec5610291b95414a9e2768bbd1520612924ca03d48be30ce67f8338ccd6f20a415b64972de50444ec0c85e1d2180c251742dc25c6c25dd4d85cb2ac497d5c6167f212404a1c4e4025f9db0594a33564645ea3aa10d21eac46257491154bd4481c5865b4340a0017be130d393d55f372a2a40fd2f687221cda6f1e4965021d32672e08f720863979541905b8b4e7c0010ca963f96f23f9dda5765278df5377d1cf7359ed226f70bf3a63327e5c5b1555562fcd35330428d20734645e445516b9c38c2f376ce0d1b95ffcd092dd5c7083804c4aa5f256a160b2a416d1be1a597c86424750ba18290debaa9ae3a0e44e71ac22c332148fe6f8c939e3159f9f62cdc24a3271ea11ee08e71358ccbe0032a4c9dc06da9d84f2feeb605a4530ffb6e3c9a9b89d5a662692d364a5bb7b82aa80f18120be09f5dc3a55233ce54bbf45183bb22e62a853c5d7d7830ea3958deb9805c64668772e882e169617793f6a9e1649f8f81e16a2e3ac6ae3d7c90a1e12b8e5c95262cdca07d4af123cfc0728f5fce11a2fc7fe78d0496cb81658305b709a4fccbce459a529fb4205dafe3ace1457adf3b5a183945869ff2c38759d3771e4a930919b05000000000000000000000000c2792d8238d9436a45a1e754d1f193dd6a0b618637fa7e2e0c777634a395b1fb4ae86e3fee66b618e2e81cb5f0af233685d3d788eff5649099f2137f6a90264bc8ebad997bff1f4ffa134e9c3a36d5f69ca5570ea12ed59bf4a58700502c085900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000446c8a41181f5c637311cc926a1802ebe230e0155a4c63e5a01dfddd6fa46a32b93769e52cabb0d95d8fac9097b9345d0639980a75e0e00e8ed81f207d225fdd613ec4e442cb03fdc6daedf99013636d5d57960c6e6fb6da92b9aa6c23341ceaa5e085e31f815a1ef7bbce4560b814c5e3b357b1e6f28747cd7144ee71159e6102125e6f8373b7032d92d89a4b6681dce2360551cb0c334d408899f48bc2acffba02026556e492b8b062171667ab10fb9816b0be40277b43e340d4a5d936e3df6ac40a0597bbbe52f511ffc5a5d0ae119a5c99bfcbd551f38882812a4bb23bf051013023e687d8466e63f23c0224f0098df73df1572733bd99370bbff3212d3474752a02076e9c1418d4bb3d95d4107e056a0fb2e62a2e2102d208351a4e44702115bba302158923a9cae0a2ae51c9e0f33edabb868259cbac243d280e1db2f850d104a037032299efc0cbeb8f939d2ab53dc8c7ecceb68b2c3bb0cad070993041fd40c715000324382b3f6dcd21c2ebe48c87a7a3b2e49ff997f7a30917a81e2e4739c83929ca031285afcde7fa887fe83fe60e8ca1da389e021ef6eb002eb98141b4d7d7409a5e55c5e5778068d22f817322398b7b7d36689c53ce3569de0cb65f6527678063aa2389b11d62f7d2bfd784bdb7a2e4600015068d72a3ef6ccecf7ca61c5cb44c92476ed3d32af832b940a4a570213985188c6651117df0e8eb6cc65b353d7ef34bee8d55b36f3ea316a0de868538a4891b5a9493f3ee51289dcc18e2edef1cdf0d0893c418f1b6d9b1c872531902b5312a81652b5f89019d58fb184ea85d77ecbaf13e0c16ab0845c658505f2f734bd8d83e1b2d18ac5320fbb914af608cc5d4518a8c43f2d051a5c83762843ed4370d3ff617e771b645f9fa164a696242d46fbd1f0bf79bbc272ad6637e7efa9900d05e444ea8deac9a07355234636547a358edb428519f37995c1464ef857cd1f4c053072982aebd58635d4130c1936e12a6c46230b638eb72db0a3b5b4a0a22df334ac1c0661446627959a28eb907b1c84bc8dfabc47151fba635a53b0c7b3baed9cc048874e5dd6d1cc1731214305ee3ff201c4e87207f842cd6342e76652933cd32ff5eeda0d89b7c3c8188d43519e7697d61be360ee08dbf325b41d6fe038d1adef33a65bf254b398a02f763a020c0eeb2cff12f52d74380bcc4e76b8414323770719fc15120c49ab508913781351b5d0b4edd16914353fadfb231dabf95144b91e14934b684d78a11109b75dcb79d624cbfa5993bb8a9b80e8a2752caf18fcdc8aa5c085003e577c59fcc1dab202e3537eaa5bb6c919f52ea68fbd47a343cadea666e744d138dd38d463aa0c98eb8c8246cc793249bf4669ab099981138b74a15881ee8eb2689d716ce6c42922891e837b0123770fb1871c73c5583da28bc54825d09c6deb7d9de5635ce3a51e2880b3c7bf65835d353ece6e260f687a31a25ed84a957cda659a70b45b9bfe54f764165cc1d58fab62af4a68e9fba1ffa5bdf46ecb21a2a6a10832ae355b361be948038b724e6d34354af562b2b1d816cc1ac2481effea0b7644252628c4b0bbbf4b51db0e8282bd9e2a884df9d63b2d536a1ac46c049453d29a23c5152416bea74da489fc5fd6b3398fd1eafa11f176e24a5797a10c5be32d0b7721a97946a90a5ccdb40bf65bb90cba686737afc6c2b26bb22ad2b2d7c3641dc573432c7f6d1a3c50ef73864f3515621ea88320b8a339c5c1e6ece9821508036c67203435f2b56c58c819ba8b415f1dde7b5c8bc863e35b88708288556197ba1c120019bf5b017814bba1b4c4d8daa16e54f32a2afec7a5076b5d4c7c273f08966d5dddde33592c35159199f7e430258ec8a7d581b52578cbde6f53788899aeb112112c56f051ddd448b431c62cfd53200bb0040d5fb174bc12e91cf3ebde92cc18f757155f03eed20f3fe59a37830095702ccaa85b9393ce6894bc9beb835946b67aa8d42fb01eea80b5fbc48716ee82fd0983afd08c909f80972e0a4b601c5ef93ba06cf309138d3e363b142f06d0a334e15de7784c6d21013c2fcd7fd13953ff306199fd6ac6f204225efea15bcbc9f1aacfff544eccf6d1cb1ba0699f451223cac9ec9573923eb2bf0bb1a5f4d3c0ec33e649dfa905a7327ee6a288c794f1e6a67330efe69ea324a1239be4d1d9c08a1ff81dfe45fdfaa6382d1400a8872e07b0b60b062a212ec50b7a609740ced718a9ca0dbd0e6de97959d0b3c0a274a739a50305158991c654a571f0a89f3a1a120f79f9bbed35dd980ea283aeb288da994a14fa6b96cbd463e78fddd0f6e5e513bef6723e6efe88664a38a9d9a462e97650aef215ea6a95d4e2b428829420543be04d706f8da3036b5b99dcb5fc9c34fd726707d28c094a3aa83b43b06e8f9764fe9bf527e3ccd70f500", "51ac5351516a656a", 0, 474532199, "bda7daf2e6f2b6482da6e683e1b0a94ae4d5639469f220d8a2ddd362cbb98b58"], - ["5e3982ee02680893e900a43aead0cbf38386ed44a0f67d495caddd9423c9452dae2dc49ab3000000000400abacabffffffff60c8832c879efa965f0a63eb3cd4ca0f72527b2f5d5ab622807ca419aa878dad0200000003525352c73260e4010c2a9a050000000009acac526565ab53516a517954d5", "", 0, 935203767, "0d09db1e8937557be6bb722f4e6379e0df3805e9767ae168845e3a751844ba52"], - ["630a491301befc25d945ddd7a5d98fba5089dde921627e73c7ba17249c909765ee5991b33501000000046565ac65ffffffff0194cf000400000000035252ab6525807c00", "52526a52ac6551", 0, 140865692, "4e0df8ab9c04f37b637f1343e2022775128bf3c7c115bbe292c5f2e974a7b089"], - ["72aa55be013a551bbb24f7724c0cde5ee622f497ec4d77393ace4265a6c75cce2b76b377e70100000006006aac530053ffffffff039907cf000000000001ac1660e8030000000003ab0052ea1a4e000000000002005300000000", "5151530052516aac51", 0, -369397741, "482d40c670cdaff16bd0b2c1418d165250c6a81231a714c8fb1ee831519f6557"], - ["e5912328026533874e65cdf03c746b0c60d2501358bb264949e9e19e0acb61351553c0ffa300000000036552acffffffff9c0e804e49452f2a965ef4d9bc1ecb40abc43788b3e3ed7dd73cf9eb7d5cd6900300000003656a6affffffff029fbe810500000000056351536353d7f6d705000000000300656355598622028a7edd020000000000000000000000006962fd12cdd87b01ffef0288434ac82b5f43f7bdb20fad310d8f221d00a1c1cd3195a67cf5696a735e0408f724d96d741cd4bddac1da0a70bbb4a3f638b531eee6dcb14ddbc86e622371ce57eb3a97234dd3c6b4f48bc07a4e60eb0f3d65ec4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f29c1e168f59160cec51f44505ccd558b614d4025f3a0bc03fc2027111283cf368d19186c4ccc36e453632befb3b9041d421745cf78836728a95a14423690fedc2646949fc3afcd383ffffd8ab4834f33f012777e58d1b26063ef9388a02d3fe743191c7a9a3204e5eaa3aa2632a371f0b8f4ea9589e7812bae28cc52e890676032aade386b88ea48837d2890cd3b5ba3034d1de3b7df3f25061829a7e0225d23d0327f3cf3a9638a1d61f3f6805b930f788141963b680368b4570d5e965bce01e010a1786c6ea155cf76bee5c206127460484f2b7ab23b87e401041c65ef05b24403a21acd886ff6e9001d8654528a09bd1ded0f4d055f0f4a3e9f4043c081f85fea9032eebc1a8b8ea2b6afbfbe51d36330c6007df5f12811b29db67a2063541fda86f0329e29f09457695b0532db438bfbaffe780d286c270264a278c378ca5ff653efc0308c37450af0fb4996922b2393d2e01235bc0192106c28a8664a5d23ff9410c96031fcb0694524cf2b41774c01330bed2ad6c6d71dacd88672769403ec5c18e5939022c0d5309b3bbf9bacaca2b93124b3d9ec89c1c638dbc38008181a5a723b77868470ad2de02d56cf02bcfd4c3b8f29b48037276287fea35e7cc51215a51d7af37e60ff71e41e6bd79b94c513442549b56e8806ad46c1d0a2101482373fcd480b658dc8305a90a63a1341462003d33e70992df3f2fe61d19113d5a60c4cd3eef7149bb67ea33a4b726d579e042d2104fcabc963150724dae33de69f9af12361a33c8a778a14f0e87b40135ac78f55609c997a7b8ac9e2ca67d0e7d68250d78cd8e1068cb33c8168ac1ac3a56694af073e7e2d8887d2532783e88439d1d22e253b44951ede863a9034199135ad61e71c85f8826ff380afddf7b90286e3555396cbda2f74ff10d2c5f1fc660e508ef3d0dd6bc80bf6d99c2a67ef09511b816e6d59ed2cf4bddc3539d304fae1a002b65f078813f650e5bbfa133c5abd125d036669a4033ceed4cf560c6cf6252b529eb5a75f915398783dd62bee381586c4245db2a70853c07fc8fe422196f0520877e09af9e6b37f5f97b3b0bf8763f84579f437fb4b97508f5574e2327f1a0bb820d504df39894eacfb14aacaf5a5e2afa127a00a90935936be722779be3b4c829657ddfde852b2f44cfb37e96c003b4663cf5f5d7b78074281d48d4aff32539b5b11fd5ddb85200ed975f6cf254f134cf2b4c2d555cad59b8ab2e313928d2cbe586982eb8fb8fca7c9d8518cb905597a4b5523eab5aec606d21470100f26c4e2e39161bb448c8a167c0199a0bd9d2ba05b9e5931ca8eb7e2671758fb872757b1047f135219349239f581765cd691df27b240fdfd26bdd77f67abfd6a75dc605af4a879954d58b15b0afb4d1a68be77b87fd799367a8de2bee176065b5520fe6d249d2a96072f3b7a5b8fec1a130c85d9fa725f3127e9f97b474e1bf8cf9ee9e5197f7d058c87cb80e5f78a3c9b2423d06f38a5b92056c6d0a749090461fc8b6779150d18e8902a85d263107ebc5d05302b3f82395109797d29baac9e1a10ca408c4298d986167bc4e3953f3d106a74bcb3634f27282e1507e31e96b5a3623c620627487e943d6393ca86ff56cf7c1a4718eeca5b7f144e3771a4d81aa199b65f6817b8dce53b6f7fda47cb3327e237b13b9ea5b04d1248483a026753e1116b58d6cb7cf544815b2ea3c12486d8ea8de5eceb1ef9c735cb9bd61b71861749ea09262831603e5f36662873c1ebe069096e2bdccd91363310e7f20020b1f22b32024fda4fffb63b12c87d9340fb6a75efc8802d7a2dcc77a70fda8501a7ac972972a8f03132b14228f6ee71ba4d544a2c36c0965451625d38cf95dc8e6405df7747f821bbb30423beed8fa2c3e2732cca84e833cf43bbd33c5d9f1441750e79dfeead7c113c27f2f6118166704ede35b3b59543d2581f2c2424d5e1e837d88fbb512c370099cc3441fd8e116741971c8045503a50ebf28a3c92cf20496994295fdf1d368d9dba62131efaa34adecc0d6830823cfb2dfd25feab86ac578c7c4da4495f4f6c34432df8d63d5bfdd052e9b390d77e58ad871c8d193d3b4b7135ec99790ad41b759bf0e23c97aebd6d7eefb66806cb2bc941d5176dccbef47be62947409a1be79dd67bc6fed1fee9de8b17894008034442b1e8cbccb36d7a68e308d61ac22162d0124c41b0e22411f1fb371ce2dc29b2f3945a7b781efdd1d999bade45ec1f4fb89833a2819d404f99c4069a144f8de5036e569991360ea2ec2811bf9dc28b3c3efce000000000000000076c86601000000004d5609946832de085fa63b6275a2109a7af5d1ea4462962771d7c8094ace9a9cb6664b96fbe2c33d3a85882e8e18e5731d7633ae87a408cc8e82a05676047db4a167551108a466dcd0580785c7e70446e21005ec107b98e5f479c500be99343e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c51294a715c77f0f1183fe01856293621a27e29d37fb024e6e265f3655c8f778209156b6acd9f3914f11a01073f9059d6549860ea991b05bc9f0e30e42e241cb7ae635decda2b546ce7cfad757d9a81cac62409e59c0e32087c3bacf298dc3ad714bf07e72844431e4b489b357758a77ad1d26085e28a42cbd1ea3ddcd29427b030311823e86d20e2b94a1f50babdde98c08902766039fc9875b4ec2d72a48c624022d8ae6f214cb71876707eef8280895cdb4618f7b658b91cc8db8a0105ccec4c40a25af2a7754e19d168a1655ef22a9500943fc910d90ebaedeb7a9dfccc360ea6307bdf665d5072f235f39891f8a3f65a4c2f6872a4524041b374560b223d5dce7031761fbcadaa589657ebd6ad46998efec5e90b2a982c0f98fd87319ec914bf41b03100aede632b9b7a5cfd5dfb096d1b8fbbf7a98666d13fc73e073a4549170e4fa031cd158469e014d24b868fa89f242db4f1c4ac693f91fa02a857d8d8cea37d4ef020ec1134fa929ae0f7d2525195c89b5f8e7b6d1d49eb9ea54c65607f56042e20403281053c1c726548eaf7e395fde706447056a212635beec16eb2fc1505eb1b6c60fde930c72d0fd1b64f48a5eb59958986ed099b4d8a23f7953917f0b29d2a2a8396017bccdd8f2d9f7a79fea75abeb6cfebb58575339a34893dc0702a210bd07fdf2482204d31cef443850cb2bc557230eb0e98c0f7515073db11bbd22cef8af482582c42266dcfe1968d93f609b2f564af0ae90e64ce131dd8b3b0f4219c75f214d8bf2e3d82377d1f166c39f45dffe0e692baf6101fc02b1bb91414b8a4cb182f25141034bd37aa7d8caf8d0a226ac34044773ae0ed6b244fd94a5697d246667e2f91f1faffc25cb8b5f6a558769de18f5e84c40ea1adae1e96e86fc3e2783c7995a5e9e959a8210f6e6f99287b29ce4f06f97c602027f28fbdc69ff347477bb0cc9720e1883ae9aa024fb85c240e71470a0bfcb2cf3a2acf93cd2d012660224aff2efd6cb7ac1f94e9856d6bad74b4a19347796605255471829dfc4fab061ba349274206cf32f6118e10bbfacb41157953b1e1aa7d27bcec08145b53cf0964e8e852e90b44fefce7d9df2a9b561fbf882326481bc45aa8e581c1213839fd0fec080a7fc0281507969a16cdfb8656b7aaf1bc5b8660ec43358a3aa41cf76a9495d96d5478a2e734d281fd8be6f5170b53814010efad9a9f2f178e698dccca1fe115d21a3da12a1206c1057285ec2d888e0e84b5ba6727f109d71533bc3a4f4144658fdd1abc7411c3921e0eff063b143e00bbdac2e5eb0098e5a492c50bd66f10624444ec8864c98bbc264eecc9a97bd88dec7c1daa18bb40c438484de891390f539956aa6ef89a053f836249e7a20478426751ca7b32d24a547bcd0cbbbf58c0c4b869e04269c3517aded5acbfa3015c23475208e1f658a62b8157fe4bcbf49fc67d6de9a17cc329a1a85c330abb06d5e96a33f47a45f646b922f2ae5d5ebc70f51b67a6213bbac01736a7ecbb0c07fcff77df3809b6619a4376e22b3b92876385a61764e15ef54c18d02f9490559b2b2705748f8560da9e0c33d03cde5003f9e0eaeed7a8c571fb31160c5d51029563ceb5066833ac5e90a98bac4bf67b983d0066f279780556f519f6817300fbe1f9d493c149fb8bd1b33ad2cb75874725af15504fde0ffa3d9ab224cce88c7904257adbee2f532a642ec1527acb70f49f3683e8f7a9350456ad08d1682e66b01fe5a50c11295ae40c8bea597d7f898c9fb93d34c9faeea8de4fe029939c8e866511364f01878096c8ec7def6912fcc8ea5f67d5a384ea069ba048d47848eb8fbaf9d08cc0e570adf808ffaaf2fba24b92217985d1556573360e3e8f4ec38ee1ccd999b8a5a45dd9924ccc051c5f4b555464084b338bd500b122149268e3814c5c4043faabaac08e3aebc1ce392dea763619f0b283112f457dba86dc174858ac4645eaba699319865f19de12a5405012a5c0dc9f6aa47a619cb6627c2c9df5d6f2d00c0776cff0ca848efe6e8d924d4be504c2d3ce3d32ce14da33a940b6cc61afb76c5287ccf578c468e88ce0a0bbdf5bbe345c4748f20ddfaaa2f8bbc1bfb65ba25f548d531118043358a89957aa9f045db565037bd250eddef6f147ee6a1dc5dc4eb65debcaadc91c876b0a38bcfe810ea60b5b0cb15765d0e8d5f05dd9c26c29b408e38262d2d0069c1658e12448555bf8dc8f85de83e459100c3d5b9f074ba47f4645ded8d0fa16b07d0373f82aac996b58e4e44b761f7f9cf7a8d2d179ea0e9a2d81e37a81972209136998a91d94047de70e7d1ea2a3937c2fe556972b76edc169a0014320bd9d9e0aff193d095e31e833c648bc4b5d8c2418b1d46b2f8dacb33c6a9f3dad18612aff08bfda922bb199d081da1ccc924875eb2bb6824fa9404", "52ac0065", 1, -615482025, "61b6d166d7a925d56819cda0a5a13d910e15dd03d40e99904f2c4b0a94690cbf"], - ["188e8d4701936708624436ed22603242f473a570017a9cdfd6f8d74f5b37fc36d5065b67dc0100000007acac51ac6a0063ffffffff017fd83c0400000000076552acab0063ac608c344d0300000000000000003934870400000000151ab91ecba54234136f17de77aac2d7ce5c802e0e14c38cc51e887c3d46657ff817be5ab9410a4af39e3a7b181b1ee0671f657da1b3de37f9d28ab00cd6134a06030990df0f1b03a8dcfa3883fc1fd2e800c9100b6a72dc639c0b9e8e7d89df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f88f22ebb3acbc49d5be1b8712268b987696f8a8c9f7d2f54aefed8959262cb2af6854f9785df8bfb67c383fe0b5dfe5d8cdb164baa11311d4831540d1e8336fbf2610f46836c965a4b14f0fb965501e7051a67accb55a5c7975dbcb7ac82561ea64641a121ce686c017522acfe7832687c7a002a1819b697f0ab5d8503cd1d302275f98ddc62a2f8393adc08bb29b06e70166501f64b05630e6348c6ac3d33f44030d32cd67497b2b2d42969a24f080dae5f9401419a209ef964d64e8cc7e07defc0a0fe5a19b9500f39d03fc0c399549617ca58ea4a3106b94adaf966c71c70a92650adc789a5a8efa9b92227557d13a134c078b4d3f1ba05450c19b9ffedfb704970320b652f21427569f2cc292cfc6979c42205bb3a3261b904b8004c843c26efd66030a8fb42a2e7c153dc8e70532a437637ebb7c9c0c07a977406b33c880ffad6d810300ff4d9bc9d51e41e2529eb864bf698a3c470e548b4b609224bfe2c62998b43f032d93ab0193ea7635daa1b7590869f7c7623c57f151bbeeaed89b85250cb0c948031386b76fc49b6edcb4506dfc42f42673290939237aa2b3e84c7da39e2abbac91f3f03c2ad92b250b3142e4e03632fd006d8a66c2c605be63229f30a8fbeaf512cb6f9966099505ed50dc7855326f32b374a2cc0dfd6b6458ace6b1c0b725f3dcdf9b4dde6168a8d532e2b3cd884845efbfab29fc542aca23553c80ea3b66d259f928c29eb9c3e0dd27138850aaeacf33bc9631a305e6b5bc92664cd17a2b0d010b019d497fae99313bdafd1494f87bc546eda123377a92723f7c641c23330032c0bcc6a2b94aaef9b2d5108a3759d7039c724137987e6b2f125768d4e8b44d6b7097065449bedf0535f5d01cb90ef46107954c4b7c3bb636f5990e7c242fc6d644209d7e82608b3b948cb3119488dffcfa458f3d887ac0c499b0908014ca89484d8077baa8f3770debc35eab90fb4228304c947232232b62d2a623ca7946d2c82981dcbb4f4a5cdeab1d40d4c2192c4a249d89d5c1e5b2de9dd6cba5cddf004533f604a4c25885e54eac6595aad3afc9559666699a14d1640219d075a426bcfda1b82ca2111a7ab31bc27162bbf28847616a45e182ad554706f70ae60476f0bae29aca9e31700165365d8140de975ef7dc544d01e1fafa057a0581b08385909af3b0af29cd9dd0a4d69d12769d8d24e62d181aeefa76e02dfa2e55af18c75896581481f4e4ef2e795c58d74613918becf2277c10ef3f174f4c9e6677a1a84a2e1ded4d1630beba95e2ed692e3a71289fca102f2a81c692a2f02424a694002d4dc811cee1911c4254f96c653963203f26012743749129b2c96cbffd238c9050d0e633a3f7050268f2809461661375eba1e6683fc6d489b23dcee685c445a08192374dcfddd365306a5580e19ee9bd17e0fc9772dc74ab3a6836c70d0c8790b2f0b268a69e3236396816bd33b6c1f9e3434e3b2f530cbdcd10f003c81d485c424286f7e25b42a1baa98e12a6c954b68325d2bf10c95a4be9505028d9029f7fd8c3e9ccc1c5aae48f47d38137349afd13df9ba1de5375a45841b7acdd66bb5e4367fe449d9e0fa547b87aa8bfda50db9eaeb06c0ca13911b2576f095572ee5318fdf9637e61fb8db8a9392c66fdd78c744472595f9ca8b8ff7d0f38f1bb716e7148975c0a1c033fda1481a23d7af490416b8c9aa34644e3dd6331d0fcce539fd68ab65903ecc61b07e64297e3e83624d4228370ba7c7f29b0bc314783bc02b64cd40cc61a9a494b92213504572a6b0c51bf91394f62fa0874bacd07c26d5584828a94fe7aeb883dfe6c8155b5ca7fcb4297ae914ffdfc0e5bd73325360247efe3811a86040a67574448c49db18f56d83290a5724bf27e4c5182cd1853386764164e0c5435cca484432a6f7d712754acbe9a60cd1bd76e72a8eb67eb13e712450a55efe180ec96962584b2ed37aefbe25de3868f58833e84195531c15cf9edd36e46b8bd38ae1d10b5f23bed08cdcc7b8bbc8207589a69723d40c507faf3525e841933b13d84e31ad6f6f8e3e96d2ac90d885c50424aef979357891a7336ee5b5099bb576baf74c7dbb3ad2272b63d2ec21854def045ac3dcc49b41b1f252c3a517887837ff2ecdf7ff45fd436fbf3f9b8a49157ccc05fb19e34eeecf49c30bfdcaf668e8e888fb6ee8c4478fc69052e396b02bed67f655975177eb93060d35bf37e70f4ff57d337855a9cc5002124db6ea20ea0ea14dee6f1d556d3ccf55921b4fb629abc85dd1a8347832fe056e3071b44afeee5cd9805000000000000000000000000aff465a53eb93bf639d36b3a33ac50daa4dfdf354f9295bf9b7cf6d7052da14d32b696b76269c8c06c2d401027060d238278cf517a4bcee4e219f49fdd222e403e0da30ab3c7240c854cdbdeb341f33463469d3a4153f5a977ef5d078043e25500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc6652356dedcf42569a269222ad3a1aab05adf2090a0a72e8438d7c288edfb42bbefb68d10182358ede5a937ee3a205b9dcd60cb256ab00f68f37688f04fa93e117d39ad3081658951360b2bae0a559d301f43c5d6c44c90f8ceb2f8c3ce1905a595ed7798f20d51fdab2868505a65aad83ac29f6517f948641faea8346399b03225f5586a92dd872c965ae6946e9ec2f4e14ee25bb27a113e9791fe5e811a1fb030a5a4943e1c84fe17fbf00a5ac5e1d5e52fddaf22fadf686992a87760c2f902f0b1323b4772a8eb0754f85384780cab3e408d1243133f54df8d1f85fbb4ca982450cc268ce288c1d9e2422187c279f2ee21c3edda97640c47369606909505c1d6402279a050ccb5ce64e109cfa2d60888c2b25af23179b224331c0cce3a1b75012af033002f46e54b2294b582ede7ec39d7787b08c3ff84432232f569df520b65970350211e13e0563ae64a7b1ba21747f28541299304ae0cdfcbd380c0903c8c5cedcde0318c9c2b263c3041036ff6539597b41bd974b833ffcfe5ad872f9a04d9db017140307a264a75a111377573282883c6f10e88eecedf4a94cff2e7216a605d8569bfb1fad363866456721afa8ac02da874eb02a836685fcbfebe799a911e6172fba08e887c1c266c1d54d7a68643c720bd763c7c78dc34fac65a6d2ca81db5692fe9404972f4bc9790f9255e7fe6e1cdd02cc7dcef5b8f56a44f5b359539d5c9f376299458e3bb359fa22175285f5c7d740561d73fa15cdde018df32e97e6f5a284e6c2499f6999bf65b9f38e7e7e3ac40c4f8d4fc5ecadbe3467e7fad82540a2a45b609812a836a01699dc99e5ac719d358e59ca0282c83553d1e8b85c9051b930f7557f1ed692447a9868c8357faebfec355d3c336d01308d6a38f281d854709f2d862b6660a001a76d658bd174c05763947d1b050fc6e353f74d85a3fb9cdf8cb71fda45640c0a00a72f22fbabebf94e17cf969600b2ada8b3737a7834e3b56d47bc227b1445af8f0d17884cb426a9afad5334017d36d23edb2ca8f57ae0c726cecb50eeea7f35082d7078a9cd13801e453980123519330707294153e574eff2cc9d75a02fe80ef199e67eec36b458023dfb7462eaaa6bde27c7c753c67b0a2a45eee5a01b1bcb6fc0d30bde6df33bc156e25b51435b30af43a973fd87d4ba61fbf7092fdcfc30fb692d83a2f9698729a7a6c7414abb7ec6ba203f90168dc39c3a009e1bd14e50859dcf8a5ce6eb8f184f143ed4582746a710e5227968b3753466f07e161fff4e05cff4c26c8e91798f871dca37540df0fd850bf073e5c41f209dbc488919d56549555c381ff88c2166a56565fc5275ccae6f45d353dcbef2f04b72b379466085bf1a6a025ff970a5b1a3f5a7e0c2f4532a022bc26a8cfa734a32f8516d73cf7940acff61d634cc6710535318c43f0c967ebc311c16c1993834b96796be4219653bda8f875caee3d34ba1cfea2addbac6d166a06caf12f4824bd71507054742e7b485c44d22ba33f6714a302051bae7f07eaa941c79339537af0574ef65635098e723fe5db4fc808544cb24fb3b515a6bf32927d76c6342137b392d44914b67c1748bf4171278a2bdf939ce028e70b68647447b432a2ebb34d9d9f74f3cd47663d88ce832e7ed0e2b11f0f94533be13949c21d44da2dce16c27927f89634314e7564206e34303566323e5be3ad42ec7f5c5fa91baf658fa0524924ead82923651912ca307cb739e442b363330fa178b80b571e7c1482df6773038dad535247e8c20097d3c22afa3e7c09e40283dc4b8aafc45850c8829282205ae5e5fb81c7ea2000dc4a745312de0ce0b623f9fdd8accc5a9e44fdc0d82d3226e455c7c05f4eb2ddfc69f56f93fa240b430e0b95e88b81b1638c8aa7af5de83793112b7596870d733018f8b61ea5df8a7843709b20bf069f60f02d024c92b66273fe9c3224d97602c3885bc2b6fc7bb4f62b622f7959035d8f3bae84bbec04f89e146998972a5715d53a1e530ef2905319559efb5d4d3eb09b7452000219e36737e8bcf2dc60539693e5e282628667dd86bd896845c6d954892b84c959b204565ebd9c1b0f4dda34884b62c506414288394d7ef83a7b22021c90b776e7fb18f810eea5157f91c8698ba819343c959a4de27f6f3c750714209fc450dfcfda155be98dac6c1fa812e76963fffed29491ed0573b22ef5d7d9a4df2cf1c3783a47ba5236b7567986325759e256bdcf3bf841339044a5c906e12174e4fe09923a2b91251458f7d23e4fb7237950954323e23944224609eca00000000000000000000000000b33d8adbcb8dc8dd92aeb451488d8085015db2e9b856fd604e8adc1e763ac17709d012007061a5f49d9bc9be77f4caf0a4f0d7fbe73cf7cfa9118b3d7761f9f87860444cdbc098b11aad42543c696c8be520e0eecc852a409849ff3284a0f4d500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000624960d40c5efb2acd85ef331c7a1807a096b25259e2e11de5af925e3b3a6f7ba0cb36066c88d2e4cc91066a75971b85969bbccf6d288e8578342178c0c154ae1e4a4dae7e4c6d5ffe6202f0c6ef90632f4ba398b3578d7d3dc953065d8a9c632844a76e4ebab077c7351bace51362b34d1f79179620a237b27d7b00d1b6c7ea03031f8752997d5d164bdc61ffca7401f44c5d369d4ac9c7c386c0637fbd41dad70325938a1bd17a1993312a850684b083f4ef037f4f71319c098d484ac14b2a30610a10e31e3b3741155dd602876e88999de2833d64f1b660e801d86b9ed8242537a910bbab710ac8d6bb55048bddf0344c2c0221a9a2abea65273bacc4d2babf844f02169fb775497db281b05ac39687ca19dddacf909bbe3c3c7c6d8e09fc8cfb18270227100be3ac12338542b019df80cf7f3fa9a20363421986385be74becd988c7ae022f99ad9510426445013a765fd968e87ef1e37b64b9cafe98855d3a2b0f92a02f0207ea6b5ba37054a2d677fe5e6cf9ef6c5452dfe4ad57697fc5b5b63583e827bc030be0da3399bc1b1dc151a67d0b4a5f1acd74732fc9299543db6733d395c901e1ab3811a0e652cb5ab7a5e2fa9c4d6d70f5b1335fdc2945eb6caa5b5ae2ea4addf8051049cbce8613de8add016ec09e5322f7b2158476713b9bd865fb8e7fdfc08d05d9bd08ceca3698285cc5e891bd726e0785aad4be774d8a25ebcc39e1c15ff5c82155545b35fc690abd1caa3f4fb28045c9811223a1583eac081659fc6f837ba85505aa2dfd420b7ed5fa201c6d7c22caaa0961d675fb8eaa3ecab4060220f8e2dbc0c7c6ef2340fc291487c3bb2d58bf2f523a7cbd0af14d0983a78eb38e942a44fee5b5446d951f0e5a2ffad587dfc6d1b6b2feb266d3a248e6a6540f4cc8afd843b8cbe2966e345d15b56eb7261525a5629098c75fff43d9f0f70dc0d8d56a7afc6a138c49e6d68cdcdc87611dfc5f53f8028f95aaa7315efd1e8354db9185bc8b5a639d95a6f9891ae3d4049680e4e44190509936d41f723e6e6a362be72bd261776d2885ca43433fe751633f0bc2d0d5aa5e367605473df8050786b4108d7c91942da1f78ab6ebc225c8e7f84930e438afc4163dbc14c108bcccdf6575c7f888af2c3a47f1ebdc62bb4aa81e57162202f9dc2b093974c475bf3528b938d2f9202c0f65dfd09203dd0e3a32022432fa4f810fb6c9c99eb3d0805cf869063709e6fd6ae8e83cbd92a8e6b3ca129a7f89b470f9e424eea5aa48044e8688a1e72258c6561fe8a52f9a31b9dd4702c75e79599b452b3d05a3799bcfc322439bbe9179424c264c72c3b1aa32c89dfacd1415324ee32a236afe71241cdb0b37ebe5b223931cecd4a0fbd8e314dd16ebe2ecf27eaa8fd2291a45d5feb2f81c7ccfe0f15f861123d76f821ca9dc0a7ff1ddd4d7a89443546f9d073fe7f6ef217dac70afb4ad3be6276d1d6e7c2c83d9399cd1ce648f793bafa441dca15ca43223e987c0d60d2fa4021b709dd5fa56a2872e5ed7f7a83485f65b15bfce9ccd7a346abd751b35877c073b795fc03236d8e640d24317a86779e8b73063ec96d4083d26b46eebef3a4c57e956da376c0d735a27abd7e8351db89622659e2b9042f03d2d166764b54c8684b7a045cd7bce91d8a5a3e61e88c6e67d80855c1cd223adaf9187399bc702b8c7c920c668541fcefa50d79ed653d1edceb4737f2e282b23610f3b9c0ea7e79e09a5d95f66b6f38b8e007c1393ca99a1f070af098e6b3d5bcd84a29468a2486ca5483480569d21301f31a888de3bbeeb7f10800038f7549f6ba72bf96673bcda30972b9497b1010a10f6dca8cdf6b8c811c19ad8f45bd368b560d25979d98035c93e15a1a1137b4c3e5f76e3a8389b4715543eb02babac248ad06cb8280546171957fcaf0db8901abe3e6980e301a521d7637aba207db89a296e890e70640adee46f46d56b158f3e8535960940cac7e21b35e8499cfb76540f235a3630cde995872efbf900b32004ddefd691e7679313a20e7b12023db18a8b8aa6d4375247a701baa88ddf3679fd2dd60e44f776b593116bd63f8471c586426c1d52591042d201c7e8003963ed43e0666da26fe1081aaf0b3b1c03307922f02b65b43d3304e178ee1b6d27caa8a0b9a2dcfe03b34e78dcc75c2077274a61eab66d4146690271846dcf488d69b786e6113c48b8a40552111e2e479dd659d2387cd4d226a13bf586169c310095ff12d9eaeb02dd312942a02b0376603fd9146f756ed90d36524aa23f2086d8805a4ae1747c3da122a800c0cf5d0121287b3c505e50adeadcca2b2bb3f14c88dd6e94133fb459d3edb1153ffec9c688c03dbc81d90a8833b7fcc881ef35d3f362122e00b868dda13df93b1cfdabb0f17e2f1a33d81b448a8d681d02affdbcf4baf31bdd7001", "ac51", 0, -473689001, "e07f78466f491716bb0577ad7fa5f66e028075cb86a335ca2f0e94c4674b60e7"], - ["e2a4d5f203d41e717ccc7e8c36379cb40bffa61bfff86493ab134097798659e681d49334d90300000004636a6300ffffffff00b40f2f6c4ab39690275e09e89d8bc8a45ea7c36884b7df2b4f3483893e0b220200000006ac635165630065b7372662bfffdf3c06c1ffb8fdd048c81dfc2a3daf71be51d6c5c6df34e3b4534290af0100000005655263536affffffff03e89601050000000009536a6a65ac525165ac7925a801000000000953acac6553636300ab91264904000000000800536563ac00acacab914ef0", "6a5365ac510000", 1, -472291830, "b18bb188c82e495d5cf26388e43495047eccdc0719748389a55cdd22bf99747f"], - ["73d2c91c02d05a6f306cce4c7f22088ed3af50854478971c4a233e96d64874bafd9ddd384200000000070051ac635263513ff6cfb10696bd120b95e2b8b51a8adc6f4a65179c0a98781ab82eb62d135da1200b27e60100000001658b48799602d1016b0500000000036563ac180707030000000007ac516aab6351ac000000000300000000000000002dd67304000000009486ee138a5b0a6838b5143ba863615fc431fd36d794ae4b3f623fe3b28d7d89531394ffb0c9434752757ecf9a0f258ae97f46105800351c7880537d5d90d0656868a5cfc53d2146ecfa64a56074686aedc67e0533be90902279e9cd589afe35000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e17f8301de5a85d79525c13c946fc308bd0aa93d68bb710046a828b363d386a1dad0c2cee4828449a8d8f906e8e9fc3c2f2bd1301b07253837a86812bd03c96f4422cb97ebbf526f0e542b30672c486eb4ea45a117dada374bdd0465ed319967782ce6d72461838151bea0263afaa4f284c3fe40a9eabbeb3feaf7404ba2cef03122c767f81d77c5be838454b419c91365f3f6caccc27ff1b329984ff5ba7c0ea020dac100ec74ce6a25ec0104643fcdffb9a1de77c8826df76a7b6c3440f1e43bc0b2d75113199a0cc827c8218875df55328a0d1a8099ada82b6eee4222361178c552a5c9b24ce702a9b8fd4eff914893ae3ca030aad5b130deec9abd1c70c9190a7030278deaa7bc4f0d0c6946cefa1c94b774f4ac0ae91add074f1e38004c33a2bbe0318e3cd44a0d5226be65c99f451fd8cab3a4eb3019b77b908db735f1d003cfaeb0219d29b1099b2254f298d6b177c51e4b669988280aef77441a78f34e6d0f4ea9f0214da4ceb4782515870845fda8a2f8cb9294fd442e2f7da7674ed26f8330e17e10209486d36206e44eac1dd23dc643ced06c9909cd5ef1514abe15996fce3b92d7ba545ecfc773f8e281b6624948d0833aba2c65b634fb916dfbca8b1d03d1f5bb7ef5b93d4c5d48901e8739da8ae37e7761b0d172aea21aeb76e36a015375d4286eb94844a4dfb4ec14f7d3e21e5e472e6f134538b559a3a0e676a3cc452632c61fa3e113b4ceeac11df30d7b53915a086b8265f8063959e5d2b5ae06b666507a155a3f735bcd04cd757d6d6b6c791ca2629b46cb2d444f8e117ffd6c063cd288d13cc635622500f34d0101d397636b60c4e851f2dfd5b22223659d780f3b50e54bd028e116ef61dbcd960cf8ff27f401620d77f7d394b45adc17a291458dad4b87c2cd244ae6bdbbca452efbe41d7800638090738d38d047cccc59460cd365ca88c6b61bbab8f75cf47a87917dd9d682d85bdc5c8640b42f82ec5d6bb0f763046a9a9dec410af65e3bb5be6ccfd8bd071797f9c9e58be5902855f7aef39239324d0d53b7c8934e94fa877bad0bf1c81b11322b226a76f1a9d097b2a6ee6f3b3d3b55e4f91b084d1f242c0f36d6f0b65fc5626abdefeabc9236b7dfd9e7cf6789f1a36ed275575238943db0e4b5b85764e28cd5809a4f23c6c3bae718157caa350accc02aa4c530f5227c29e3d21566e74098a9982c58f7214bc03a8aa7a8602ebdfbffc57a508f095b84e83192f5246568313596211bdeb6141c38ef7c22e8ff87e4b1e67e00a5d1757457d8f300fca35d2ee63dc93d319c43c6254b319391e0f67368f6837fbf2016e4f4df7445b92c00f549a70d800d9fe1a6fc451ccfb280aa4716b82aa741483da7c1fc7344a2207d70d304b925d396bba6470b8842db28aa55fa88abaf5ff6bff615576eee1007cee085d6773f800ff983a2a3829b08ae9798a83bbf30034563c94e71a1678b2a6b1b6f67e87898392f82efee6175ebf92c72b9c10a25ce09de150de6cd08e22168c6d98a37ba09bea863e45b3a8ead2eb28f7617c242279fa0296deaa31d58aedf53a9b81ac8f7aed0c15080c38568c668f173cced57b32b2b030b264b93c6a0b9ebba17b3b4a3c0f6412cc22b414036cd65e3da9cdd489a6a55829f32450a1f1e2e2acccbf4c060c2bdd9c8c262df9fd0e6530a689407a39e6339ea8f92e971557c4f2cded0616bdb1be985d1dc9085a4cbd7ee8672de8de59c757aa6deb83e221c741a9bf0c12e8bbe23b793064707150c42bd9ca554d744410f8691e8a879c56f18b05d8e967817da9179a65d6105eb8d4e5d2df39316740f40e436543bab79b12390c0bdaf37e82371a2cb89c9d4af28e718a169a2ff3c8d2b1e8976cc449d8958e36a0c49ee4206a34a3ede3dca7562b86d6ce9482db54243d25cccc88e601676d6a080a57806f03531e1e7714f89a6aaaa3085dd8a1e36a5d288a80261b481e1fb1f8dae7471235b16f81cb09bf6133472c44caf0b4e8980fe7723da5afa0532035120d3f946f9b87b75d75feb50b5ccc065a50fc0c0e1ac71e727769f23766e7b31f633eddad25858db6e747cc321e2d2d5ae4155919914e54efe7cdc63bd04ce437c2522895f7d9badd1e82b6c07213b82215264e128b331bb2a425964d768844120832aabb0a022363dd8f008aff3d757583137758b77d1bf62a44ad7dcf0e2e77acd552ddc2c03c9204c46ebd129468e40edc84bbcbf714febe129e29abe0b27f5287b52c6e5abbb8ca472e00fd178248e6c7de4ffd9682bee2b648099d000000000000000016eac203000000004f15928adae2cc288c5bd985260d0a0a8b72efc8af5d89aad2034a9d37241f9b9c58aa729349ab302a29c1baa77da0dbac18fa6353e97c64265eaae33291ead90bcd56bb9f58aa65d55de4998ff575d015c49dcc120f5fc264dba14bd4bba4b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e78982ec73409808a07ec4f493691846b61d52e02800998c763c9ed74125f69ec6613124b5160d738c79055c3c9904b0260096decf47573e46d666e9b6218ea55adb69e095427a971b9147d0a94fa95380635d54e0985273f92ae09f320f693b150ba2ad1e6bd81f45462e19e3c02b65cab93a9057449676419dc9c533f6f35c031bb29681bf769f194fd3b0f0894d31e2f026f9d4b44159815f4d2db0c5a01a10030280ad9dd8d47ba1444ce50a6b651ca566a477e634c7e2fe70d0f7cd51ed3f910a25aa90939cdb1eec8cd06450173939babfc57f11a787f734d1b63bdf0c45d4230a6c025839f71a2ae7588aff280560c1d738c2acbf0f134fd45cb0b7b72c6876032ee182887ef29f59de9dffb23f43cdd833963410a7db73cb2b2c29fff984a7310327057e50a2409f9a1207ca7c39428abc6e5c47a1f5befa5b3c2aaa91ccb3abb8021b95a5bf028420bd29888dd7f45f839a68ca1fb740230f40bfeb85482827f844021bd3c9d8f4fff3405f2c1615bf1846954bfcdedcd38e80cae87700c4f340057203270e8572418f8fedaae9050caa760e403f11998b095258bbf00d04dda874d9560075a3d3e1bfede37a32fe31786cbeb4b92b96a7a020ceea044f8665d59e016588b1aca2103452d4d1160931a53e3496052bedcb00201b60e2736917e40dfb4a1502f473e595a889bfa25c858e0cdb598af7516e348075487311a6e52ea4e7d3413f5fdafa6fa2c6deef3393d25b25f786b7717c78c30f3567075179e4e8dd70cc1e92f77f25ac7a766b21fa1855a4188f1a8a9fe8a8673a7413519fdbc12ff03812dad4ec8c5e488bbd291578dd2209ea11537bd23100a5c2fe65c8b246ce21ae2d9333a2beaac06d8226cda5d60a5a4c96079d56ef8405cb3750ef3d859db1d8134639fb5e3e09cdd98190571b59b946acbeb56cce5d2b585072ecdc8cf65c7850a478c6e3dfbcbbe8cc785605d16dfe746fc1d372f6c529d105d1a494a0df2fe266fb61149c974061159d2f3e360dc184c3d73c313879ca3530c56bd7d93a6a24723484f893298922dbc051deb608db95434184a75b501367396616e8eaaacab7124c690fff60b19b36173e75b2caef8902d71fec8c8e4255449f54d4ea631ad66480fa3b53e95b1103d4d391eeef75f3237c071d32f3c7bfafba14c7a6964c01068f0ff40319901a160a4456ea8c795f5f2db08f70d143279d345fb9e9c7fe64f0c75b51e48e3fde8232d85655cc1b7777a0b5cffabc4d4ccc6227b81832c4a8df5668550f5537890096591b7023e85b0b30a320a812fef71b64e173da3a371877febe279c90ed04c2eb8e25eae1a935fe75196ea6558aab110339756ad8d56f26385c26069e8728a75d93d9d68373334d253ca2d4707dec08e4f1740501da8068aee3d74d88dfc322171ca8e2b62c97d289d523e33832e28cb7b09e2d33b84a9f8971b4fa18f7cca27b6e18af8f83e12b3c92572384a3ba3c45f392cbc45d21c8c495fe2b9eb7c485ea3a2bd1552d18cfece62a477a2666ce6e77660b31cf84a0d0a6f524220b457fc6c72519c4bf4b7ad76804ec2b3904f9e07ab8abafb549a468b54ebe77c46296275d294799f7e7213ca3d4b30f1ea356a45e95bbbaf1b5be74bc83c86ff254d4066a679a70a4d06d660f0fd7e036261f3c3191a35d67590f9fd5585fbc32fa42c3beb74af0366fba74ab4f8d2b0176e686be757d454173ab350901ce109b31e5ca9a03f63f21ec4d9198b801f66baa395a26df51cf73cf35403edd40d6fe73f338deda9ec447eb61c8d05f60d795daa6fead0c46b5d08901be07dea4c47a628cd1962a4f56323c826536e194a67d2786ba3882d7117b0c3c78bf892b80cbb26081cbb37d812aaf49efcce43158383f58c249bbe59f70ff1299334bf5d288fa06a2c05d8e0a158ce7fb2ffda13ad0610e0155112d08a096ccc0e4e7c16a98d3db3ade3e34129459f94db14c2cac437721f7a23e83da3cc407596ee36ed7b33d1638cdd31b28f583d33ecdd0f7596db12553f5b7724e0e9ff1ceb803fd6791fc41930f328b9b2cde41425fd25203356b5414efc7527b474f9f493de901ab09ef2b507e1958a129234064684cfc29440a8fb3b87cee05cb94111448ea9f4242cc98748cb9bac5b0aeaab71717d4b0d9adeece7146d2ef5852b6b0ca4b1aa34d995d0a10d2988c6b0db03c5fd7d8b4f60959b8982f66b774948c10c0e6efa5dddf80c0ad0e332c0d1c12bf7e997564ebb6765d9da52290d1bd2974d4421b4c0df2e27c43ad4a2e278c0000000000000000a01cf10200000000d6458214d86d0c95729e081ac1deb9b245bfde5c57f6b8314151ff83d22bb05f4921e7dd509e139859e9dc4c0b363733d5153c25a81c5767991993fe2bc7140de2c130d0f15afee7b02969114e811858861783b4d026ea1e5a72cf4e33f0409200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e979e7aa1e47348de1f74f0ef39e12ae2e362cb314ddd263d8d8821dba6cc2cb651d9768178277a4966f87841efecfe191b24a87c0412a6f896b8fc98a6f40dd43c71384dcff672911977c45bc9a71f17cbc6d5a71080da7604f88071e9181ad2c2d6582d96bbc5510e508dacda1dff08039970fe2773ad810cb8170bd0a2435020bfe8d506b50949bbe4200af7439f71358967b649ded4dada0f37402e8dec0850204abd91723be458e38da27260f886ee66b442ee9e496d056a761dae4efd6c4d40b19b2a5d2f4a913a8ef2ad8a9bbb74cf704bbf30cd93d37fc2a9ccc1969ad45b922cdc389811e981baf7f31082346e020520c779dd474d69e7b8f5ede7a601631030fe25d6fb31837f8c930bca8cff0707cc6a99d20fa9452dda005aaea271b83a40325f7804eae1f53079b053491dbffa69bdf61d2483ea55d0b5ac45163fe9c5e2b031d4f0aef90524cc097bff31738fdb59908cff5682a17206864c7473ffdd90d6203069cc1ea68e07a38a783d0195b6b6ec63e4adafe71d1c0d74329622905d9f413032a43defe830ebe0bd3bba1118c84bd551a8a887f879afe87a68ae6d8189bc089966d228e8ba3f4131879893e79de6ae97bee3d34e41c89ca7f8e4e9422382199c9ad67528f2d2c07ffebb1c1706b4cb7d62e7aa357de502297df184484a81b81011bf0d86863f3f17b995f37ee94fdeb6f447d54126cc6425514a70fc0d2344ea334bd172c2d1008b897b6efd0f4c3a7c9ff6557b65e7de7808f11198c0a9e855bd76c58351b484fe0c82008d7a24b63349053039e22935e9960a03a581b31705fe1661fed9e4edb5535f00887124c35a2a64ee0512f956e446feeadf9d6418fb597c826473c097f8606410462663fa2575547da5b6c54305a68951ff356f8cd6d78fbabe2c2f2246d2e42bd962273c863c2bbcf6127c5e776a8d020c185dabf85f40fc337a7a97e04b241973b301021d6f874394014f88c668e3816abfbb5d3b6d822204c7f4ea41d68c5510dd2e69542c8cbeb9f9375d2527b3461b39210c2fab5ef576d6acc254d465e4b29ff0053eb2b0290199c51e78b38d11696736610607713f05a71e7ffaf6ee97b869de92cc8e62fca1c7e3be166b1fef5995f02668ef9c33b147edbad32c7814f8341ed9130be2e8cb3bae474ee8bbded1a06d212cf122d26502968c6b628b09e0765dd89068225f3ca99a058c037102f7afe5af454f388939b9e2a69052e129e66a296f598e21b1f725002252fb6be2fe06431ca360ce97ef555ad3ffba8bfd11b46fcb4c23e67dfb0ac7b148007bf955942a265f3e636110103f7fbe210aca9d2d4fc6a428a77d6aeb8c5aa9ec071cb4dd73622ead69bf25d0eed2b46be73603c479ce3d85facaff58516faf45ea4b63f289d6c86819c1105bb079594a5ec6f5fe0359e58bc7e5698866c7d8b3740d72af7bc3fb16feeceae1587f8c92af1cc29f21e1b5f96971a2a5659a3d88743f4278c4e627cccda348a79f0d1a88595fb38d02baee8fb5b59dd635a56a0834167c27b51f054e3940700542c6308963a4ac84a7a4cec6287fd25c0e2f7886795d1202070d0925225862436ff212bdbfeb2f19c71ad0d045f3f6f2f4b5b9e00e4a82dd2ce8701500e0efb7f735f39f0a0d4983c8c5d24cdc8b7c094022ba412985690cfb6bef5f1e9c8697b4e88cd69faab84336f518fe7551f0cc50af4b0fe2121d396c0c687a2944fcf54f9ab9e1a27e652563714fd0241601522ad583f72f907c201083b4553c472ec12234c6271197a447afd8e48a7c80c547ef58268827d11ed3e798f8812adb5a51977b8191440db789ad4199d5d1837f6aa5c83dd08ef8ea5ddacf7e43420a8bbc0c36b01a208660a7bf685a33b5251370159f9b44659b863b035e404014518b09b669c67a7b428b6bfc33b468bc423fd151b2665183b550a97b67d6cc5abee057e5f3285d02a35b7bc6674be009f8851c6c083d543f2c594a6681565409c19408d4acc0a88061701f8621f66f9bb564916f2d8b73d2d43668c80c265f481523e38b5fc3207e46466626bb8d0d31079c9bdad95e251e3a6cdafbd3f6374c07dcc1ff4d2895851201d117b2785b951961a650dcb889b6555079c267f95e2fbdfae872f5ee1d9fc57b7d155be1b9e03840835b9c42486d9441ae712b76910c53d122b6b2b351201d8e290c480276a98048e0eed1f3528b54de91ad58a4263887ce85f126b2002f30bdbe0d075c09d4c384fb8b902fd695874080015a0ef06fdbee0d1018887ddb3fd59c2e5120825313933e323a1c1183f7a129d8fe83ad55e407ec1f27013fe11a8f8e348c3bd8f98485e871720d2bd68ce0592527770e3fb52c7cc82ff816752529b55dbaea43daf7848f19563e66f413070b78156b4179ed16f35de20012e39dc3ecbc4639707", "63", 1, -463206251, "3b40fb9e34acf202596e6a7f5ca6da6407bde156632b95e92d323d87e3bde71b"], - ["37593337049f3f73bbfd2d134ba232577ae99cf4b9e92407e040af46399211880d419eb0490000000007ac65ac536aac65ffffffff6f73124ad88d0475d7e839a56b273ac67df92632f6ffa4b584041a1f37d05374000000000963005165ab0065ab53842e026a383832e24ac1eb533c20f4d2a6e68950fe4c885a936069a3d18f07e60e5ae136010000000851ac535352ac63635a5fa97c756e68b563677a86d5db075503605d92566851dc05b9e6d0a8eab0c5867347050200000009635253ab6a00abab51ffffffff0464adc1010000000005635353acac3a21da0000000000060065535153525ed28a050000000007ac6a53ab5263acf0a5b30500000000065165656365ab1edd70a2020000000000000000a99d640400000000e3e07180a02f2a2100cc04def7a4b23032651f45129b460a901dc2ad29602f26ceeee7dd027efdf2d180f10639bb539004f315f8204518cd287043040641f67e1e118a8d292917152e41f4a863568fb4ecc3e8a9c827a34868d6ede8aa4a885a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b65fbbdbacad3b4856ba2b3c0e8be0de535db73cc658955e789f1e350ae3c28ff3e3866156de3dd4c32e736e1836db2f9f89fb909ca36f89809c9bf8dadc4846b4a6e2c24b0e08b6d68efd6d985390b2505bcce189d97a4fe39ebdef72910c0e6b204a5a28e1fa596758a0831a933149a63f4c9d612a2540f3eed23ec2e1977a020c183286501d6389d4d89dde71d49cc72a286a899076068cb70837f38962c5b2032fa4dbb137365409efe648aca4e0698d448ca9d336f11ca18f207811ec8c54770b2b03fbd3e4be908982a932910c70400e6ce91de3c4d0471b61c2550ac75af6270eaa137a0de5d444f73708e7dc5da53efc93f59c9c706bf31292d650de4546e4032ce1602c2f9197a721c44d17ba077f1e5fbd3eba0682759521515d3570b1ec17030af99c5d869ba6eee909b365fcfb106c1850e2e6c2c90745bfb44d522a47989b03123cfdfff31ac3815d2b8de408dead8d8a99f8fec37e3c194aeea597996c1825031b1ef34e5e07f0b37e9f90e0d44ab00c56c68627c1008a1536b15e0d674d77510210565902bbbbf4650aceca6bdc75be916a498eb6bccf13f4c8d4ba5107762c11cb30bfa981aaadac34d6dd406976e9708f46744d509185f147371ef580187b933cc49e3ccc5024bbb7523f9ca2efe560cebaef47f976a36dbcce7618a4509a07f21fdf9de57ce230bcd6014cc502701b8c4b8bb5709f36dcc0a5d290380d9815676576a5126443ffac2508b1b506419d05840e5ef9bf738d45dca4611d2561703a9a16ab6ec53bf708360b2aebc95207edbb015564934db46be8f9355b7dc77d9bc901a827e0a1a2628067388cafed772fb2143be11e9d365f9583cb5eb20c33a2ab3a08f4b6cd991a62f6be6bbb7d1aca0dc05b0e0fd3dd8cb18a1d3ba023d030aceb4db82ab144da0215e0451b2160873a0d899957c3b3949f2c847ff1cbc3eef206fecf1ccb96d68a765153354816696138b1b3c972d0311b4a255bb1fd1d833e98c34016f3c42c4ba9c567fc46a372b2e5677eb346f4ebb514adf3996ce2880ee170ac649eeee4419cab9d71e0f3f537fba7447aa2b6906f3cdc695db28d3ca3afe27864e95d7b3718935555590726a4d46ec2678a95bb6d5f05ddd424e33875e3a58ff37f8413d332acdf2c61c7cd042fa32dc2bac5b5b020cbe1258f1a46e5f14dfe44eecaf7fb2006772b8c2e95c4276e6fda4db82a819c9a6101dd392876cf1761a821e56fd40a77408ffa525f9eaa07549ad87e2d6c1594ffd1659f51a8d3500c1c947a22b5ac967218f413b634aab7494bc714201d73b454267288c07cc13ab66eda57ec8891c53b42bbed1a4925412af743df2cd21e0c0717ca17f94c41d316687d72fcea877d4a14870409f66573a76d243f0645c4828cbcc2ea31e720373dfcaf3366e4f6e422b4319e3e7abb9495053ab13a06af724321f9770e9fb037461643d8cdd44c419a41c07e53eb73546490786f09a705d1a8bbcea320860de854b89ff3e03d30d226cbbc6fc300c0783b253c2af6a2e790d616f3253bef152ff6f4ad974958c34df23544ab820d10136796bfb15ef2b5871caaaf390a7fff5d8df6f61d8ec6775f3344701e19ff380275ff5517a632da4ed7ff34e55b695492f7f0b781eb4cf5c7d8fd3ed6280d320ccaf0b68788a2ed58820cffcf30f68b6ce444401026cb6bfdb868bbbd1ea26bf10464f16410f7776a0d065cd216d033dc7773dfd27ffe08f26a89d271c804187558f19cbf5c74ef87c681092bfb1bc907144cf542db425c54e9563e9154cc2126300d1b14b79bbf63ce65b26d02745f13e6b08c6f1de9902ee9835384e099f4bbf3f891f31e730faccb77bb106686be22cb5a045391c98cd9f54160b2860fbe06ffce33e33bf5e7af66dafde6203071692062056972cf8179bb6a5700aabd6deccc09ee420cabc7fa3b85bda7d26d1a8c1e7f549044c483e24b279d43b6be780f817081d3d69d1bf73fca31c148e1e2b436deebdf56e3d39abe743c705580794bbf2bb9cfab2adc850dc188a9e02c4b4bda78c983930baa17b545f38d476890caf9eaeaad6f47f6a0a80da9d72eb98bac6fe24dfdc27592b9be09e15edaadc5943cdcec45ca8641d33647ce6e90e9a07f4f7c1628fda2adc9d7c66c34f79ab8a077fafbc0b443cb557b5938c980e4ccd021bae3991302366459d4f707d37f78e7bd452636a0aa7293b8893ac1b925f3779d6c9fe57f248231406fe0627e0e5eee3ddf62a4f8d43ea9a4acf1c6961dc9f402a4e4c92e85da4ca9f7ad31027bce5c280200000000000000000000000040c2fc84a7e302acdefa4a63bf58adf873b5c71c5f9fd14221b51b6a651c81ecd57b62a8691beecb825f72b0076a5710d036d56837b4821c13c19bcf851faae29c47c003dbc2844bc335537aa8d7cb63db727220e4b7fb8d3353196a450ce98b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008891048355b2181f300b8b1ae0ad4a1751527689561919395be55369f4711ed98400db85c219199dd8663c155858c2248494d93172274c3cd41365a768cf3cffe6150b5e0c89413b83c64c43a1c59206fdb58a0dd670378b5b0fa7ac1f116f3a5ad2af148e3e01abb90aa6159e9da0096f44be3c9ff605b3fcfc42f0a9cc98f5022465b1107194f95f4c9b1842294654033e5f850427639362d51d9e34900d8af6030ebca3426d6ecbd65ece144ea9be87eed00d77297b708aaae65bfb91af67bdd70b24c7c9921f4234fffe1ed25e33233914640742d102de0fea6c36fe69687f97b02d46eab7902a9c706b3f3b8018f2727d757db74e3b03e2a748a34097700d431d0322add47b95f1e6b6b798b194a01e57a10659d37337842185ccd3873713f69898021efd361b654f0aa8e18076bf74e94d476ed2fabe5df69c1e67a07af78977674c03109c6c6bab5ace647c5809ac3f9f22b5ac0eced14ac1a10e23c800ebc096f766020ab114147a25ae077a387c3a58b41227326ba9ce2f4b6f036e40f0cac2da3a230315db973f4fe651f1d7cdafd438fa55c0f8522769cc15677a17e15130bd194ec3fd9803f805e045221c238a18d888ee31f0cc9126852326d9e24f5061b67cd0620fa9c0ebe53243928db6efd392a33f86f1b95b525c9d69ca394f3789804ae352a5f51afb67b87169cbbc54f0495154e1fdebbcc1080c53e8f840e07c12dd13b9da547f4ec92c20f5be0cdacc9bbea4999356db43bad00cee28dad71ef636cca9f987daff5ccea86e9babae2fe5022e97c086d570a3638eeecb9219579dfb2268db3243e9917ecb412bf2e82a43d1629fed6f663f784d29a26f91890aca825f751a8c286562fe248f2c5b299d607d21002bd17789bec17afe932b1c35c896a8c930d53f71795fb768facb4f25d07630b9ac46f5605b513a60c9e69b875eb46343b05add674538b0e5f4253fb4d1e533fad3f752316fa3ac309de2f7f48e381c5c0dc6940528868a9d4b66121d51d4d1869ee3825061ea3033f1a824552b81edb797590d91422792c67725a069fcda9e88d377265da6385793488e27d630c44c762237c52a185d779df2980b69d937e93aae239710640270f6a2dedd8acb175250761fba3e458c3a21440e96838f79f1ff64b95bd7536db692a2fbf2c448a044388e91209352d89db6a7b3dd8c0bbfad578b2e33d6c9f1767861133776d88aae18e773c02369c3429f735ef26a338901749a47a3d5b14bc1c461be3fb0483fc2f5904bfd8c47185d59e7dee4dba10bb1b9e48cc1f5f73351bde3a5d0e0cf255ffb739579ff02ebe332f691c91ffe051465b7639e5e10bc75abd51b84f6a0b62a5d5e75b635adb14ddd4bc739254d551addd2999c299be48c4cf0d3c2b2024e24a40c7fc4696c85cec4ecf97a6467abdcfedcc56ad4aa03f4bca2ac0fd210698a5b33169fe1bc0abebbf6bd3299a1b467b7838cd141557d119894d0ca306212b25690d47e4b52b4d490206eff22298400bac499a8442b5704e44fd7a1b862f3fda71fb02432a3aeacb1a360cfb4805cda0982b0a864ed62d839d50867807f56ba170f91819002768e889481e955f093d78eb107c7ee1cb3f5ab967d8913082b9d6a0f99bc69511130f33c68a0c432d01e5d2399338ba7cf1af627cb72856d6c680954e0f1afe4c6e8c165bf96926dbc21b990ecfc7e0bc6d117940c9f382fc8fc2f9d6125af334e0ffa0b313232b6fae78d681c47d71bdf1c48a91c2a7cf1412c4d2f589e0827ca75b46e5d9d6492a757db59081d840392878282eafe566e56076e70c2aa3603e501be92fb3b76c84d1ff3f744b0faef1a1dce192e53bd56d3f7f1a02e62a0949758369b19eb2cf0513993d58d3baf3224d1d63aceff5dcd1039082f6f4b67d16263efe34881423e0cab2c66690faa4b8b695c90eb67db92d0161ce569b027cc768282f942dc94884da0dc40bc295574ff0cb5394552c697b3300835881724aab997672370015fc6464a1550fcda7e9e68c7e91fd77963d6cd9a96593deffa11d00b8437e69edb6818a4a0f7c27e4d2249de6530aca0f27c318691b9835e4c90a71ab661115a38f173c0ef80993a584b1d0db30dd7ab33b0e87a3b42a0db777bd07becd3265ed7c76d2a4b7e5f9fbddac2b7f74735f77df5cabb12ec7b8580dc47235f6e4138e5e96f154a6c4c41f3f0cca6399c2948339db6ae797d9f27168dfb6cb38fe70782a4833e7c7e68e827fa64c88f50d63ad8380668c72e711baf6fcd9f0cd58fdd3a5037d0138420c4dd3bd67bae1b85c1b4d7f002f57b37f60d903cc3877435b90f47e0609b31200b70f4569e12be35a348a466ec2f1003f5a6cef50e85dc52b3370fa02e8e400efb16c1247f8c4deea76599c5a69311af74f580131339ba513d670ef86aa96308", "52655352", 1, 193514695, "d2ab576e60f56cf85cda927ce1f565863ae136b314d41022209c7b3621cc5a74"], - ["6ccbe433045a7fceb9ddbf143c05186a03bfdd8cc5b460c314604fca892733128ca4f7a79003000000007254d76a6d231ccffc50447abf0351c54c7eb665915eafad0e2d1a8e28bda72dfc1546800000000009ac656aac525252ac5117b6b777332a834080b3dd85a98d880263f158d51121dfcd30e9a6eed365c142cb0145bb03000000066363536a5200ffffffff0220f7a0cc48e62ae55eee286a81e40c0599561ca806d3d8c0b1668e6507be6a030000000765acab535353ab1b8effe502d7a1a9020000000000ed5d2d050000000007ac006551ac006355707944030000000000000000beec1d0300000000e4f832e401288858a059623f487c96ec2319752b85019620db7fc99b8ddfbed372edca9be416b16b03b34eacfac455997f64a1f5efc6c6267a254b08cbaa43b04dd50c4aaffa749c537a14891a0f9f20f944eae58193e32c99e928a1befc4cd30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092d19aa84d1efb35a46b4e1bd44c5b183240006219886a36712c601cd8aa0d652d7b1205361a9a750929cfaa23d733aa6a3e19b7020d33dddb15d3aad4ff8e06824ddc07d0fed5295d5cb0416f271e77c6237da66d1b1ac713d3fb4c896cf53e5841701d3339d18ce8539716a2929ec0354f3f28e93a3484c0d6fc4dd2d90e290303d9cbd3ddd560629d8bb9011a3e5d6b1b6868b962b9134b04c845bcf5c0d983022231822fd1f9cd702328e7d0c5ab7c286fdfd53d31b5da04afe8d70459a299310b137a4b21107478cef8a6fc0a069069d0128ff64d07fdcc42066a0b12a10ad36213afc7e26121fcf3b2e9cb42f686e190b21e409e79a923f37c47e84e29a7b7cc02071536aa0d13397d819a1f8c4c0340f8e9892a7177ffa53fde9dc8d658f22dcf021de00c0919b9ef9489b33ee1b5ebbaeba9f963f00b2075b8d561d7d25c20620e030e7561387a94b3ef5d5840a0e38dc0bfb467986916234f42293e558a6213119f0323510149cb76fd2a12cc4fba0f0d0e89bd45bd895c621250587decee2fd0db42030c8ed51aed874e674413409c0e0f363c5cf5bd3ee99b375d7830aee4eb675b729a15e5b6247986440a7a16ab76ca5371e034a2433cafb92d25b11c87a219987a049e3237f76610d3855d6e761ccce7495b2c1df8fc95626d33f08439d7091fcd12e96b31c5774890a8ecb35a4f39fb3016c0f46b4762206e6a30c5e83c671fdec2dad21c079d8be9502d466efd7e37cc7604e4f423924ed77a745f6f4a3036a4cd0558fcee6e645e6232d33156a94f22f6b2b6ce8756f67a67d83e337b64e6dd689939a240c29e5b7329d29f75c497faf07da599167c2f46b1ed6224a6afa588072e82e3a66a6ead96429e6138ea7e92c0a820fb4cca4b2ed95b2139d175d09c93229d22a77936071c298a5eb0d69e8843bdee51d733c275e1e08c3c51abc8510830a645f0419f3e05d9502fb3ef4d78486781ad21ef24c5c6e30c99c4ba4036b0294f27d6283e37acbf26dccccc83ac7a6213937e4cd05db68ef3eb372da7be5c94698b702ba7541f0c57cbd36a8dbfdacb762510f76e710e7fb125be7a646dc47e3ac03339984ea625befc2cf3704405411f2290781ed8abdfc77907d65e0816947e1b3e5856f183ea6f7fc3b573ee3ba3eaf5e077dc3acf8b47c03e1338667f77ba2a717693168b78df59420dda27d166be8b871687eab27246518a4534f850749217c9b20ef2a0008ca4bdf232a9a5a2561575a91740875c73112a31bbe0b784e81b3b97cd2b3fdf7974a80404bb928f4df08435fe56a98de493ef938b7446b0323eef737a171269b9047bdb6d58ee898203c65f89a84570bcc416b27388998a2277bdb5469917b5e0cb20891b4b7e4bd1b8902a23ca6967b188a6ed3501abd332a96dc7aa1fc073ea79dff631465ba2378f0c6492541d132632ef11af8379ac927db79109562d413bc7c90cac060a1213082a389a4d29aae6b06983584f453459860ebf0b6981161cb92c9155f8e7fd3c15602a6b32db5795645951765234fccc876a4f056514c0949e51cef0b11716a61fc213f9e4dd57c3778315677a7f6e3d38837c46242fa89c9ba2f8e7f206f5e6dff078d9c04d3da6de01139ee065aecb28569167d2b74d16dd6b11cf0faa99f20b5490612765cefd52ed75457d11d41ba9846c6007974a527b0a9ea9ef5e600bfb75ce38e203fddd6a053531d600b6f5c73fb40b83e82420c9c405f0d65f9df8b77e44be3da895b113c6f2b4052a59dc55bcbad4da05486ed9384fb3698c8d8a34ca4fdf6f7e27a6745beb045bfeba30626a16af6184d0bacde53d5a65fda8832ade85548df7b5204052778b44431ce51be878acea27ede1ff6dc24799f478ee64b7312b8231860410c3a407cd96c1581ae12233f204a96371ef1f1f59cd38fac7fd46ee75afbe649628e698e7dd4b584dc0da0f15959a63991222f064fe9884bbeb2202ba8752ed1659097d20a799021198c657c480d82b31c433a991d8aeb889f464a227817cd75a4482ade76de9580cb05bbc448ed62cf07a3bccf7313d4ccc30212133dcfdb53ef6d3fcdc0a8cb2f4d264af5a81f76178b7d08b4302085b7f3b7aab74b619ddc20989cc6d4bffa829767911a9d630f0dba4c371dffb27437db4d6913e99b89a3bb7261d171e5756813e6503bed209b70129cb5a5ba34c9d8736d8a1e668ec01972994ad9abfb1c4fd274c2ed9174cd9a906ece146b92274e91c61affa098d32d748474e249664224458a42dc87be74b7d7fa6c3fb6898f366f305000000000000000000000000b04904247249aa08c7613006d15e8bdd31ef7bfc5d28800ee6c0940895e90c208d69bed91a1c7c19a867909eb29760578bc9e35cdad86feabeb7b8578c69b3ebae5306af519a01637b69c82b5e118211293997b04e061f853ea652afa18256d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000279f0b68d197ba0ff60e7d0b20ef52c1229cea2fd8be73bd7b26d1d008d9613718fb43399a99dbd93265df37adfb1a59090f40564475fc5b463b01608648b33a536b14c395eb4e5fd1493353229c7157e114f1f5d9420f7181d0da958dc71d199538285f7934f192017bbba8893b0830eefc15b265a20f54a536d67ff1a0adde0223db0b564c7ce074f4464323472efb9693a8e1b28e17dd941c64346ec8b35fde030a8cce16e6bda43966d92281c65fa4b849199ce58e891729634b55dac6940f5c0b0cba47b8c7d4382122e2403b5f5bba09ce91efc71333fbed4935206150a2fba62fe9af1f3882e03e19ad6d2a425e17df9478c956b8914b06a2378bb24a53d8880328411dfb2eeab2ad4e34a77657f10d9a29207326b68fc3cb34a57ddb8a7e5e420225bfaac50057a68f7e08a6f7742235313bf986bc29f816204eac5bbe297ddd7c0320fad1c4f553beaee0d551af54b13336b8bf911abe9b83dc1d235a4885c54d410304fe0596dd2b070fdfc38febbd59e83290dca749c52907916711b0d8b3b01d5803230cb9ef2888168434a49ebd4c554ba7c0579131af1044a8e181359fe55be78c533154af61268efda3b96fd6b741ebfad88844641ebd0a5b9e9ef2413701d34bafa695254f9b739819747152c7a59dae37b659cd964092cf50bc4f993134ea17b26a1ecdf08ff83e8d1b8b3fa2dfc08e7b0bd2468cdf57a7f4b1c5efc145dc2297b3bc1b232187864cf790e6988046c2afb6fcffd783a4034487a7fe96a11a8e156607f1dd557a59c1948d2555349aa7b7a625500a0e10f3fa5881ee16146bfdbee6cdb06ba265153793ebc1685c60ad7da65e6c0c8cb29ea4d0662ca84c93a60a59cc5fc60fb4d8818b06b82d65a6282c9a08b6d6fc9752aecd6db12d792c6cdb72628e16913d493926f3764ef5b4109d4807e766d88af5e66ba3dc7b8aa6c801b02d38e09ef0eb0fdce8cf5f221d8c3f1d7ad28ae0bd97b2a99a6a7703f4783c42ca104af37b720c5bb379965b86d844da0cb46fe55c38484926f79d88eeefc9f2a5c066dc333f8f5db7b1eb8e9c75f33df6ba7b56803eec88ef7d4a9f2d025433de33204edf3a97f15e7a8dd02e322567bbbd5a6142d39aa79cf41e3a88334dcf36763184325f0b74fce3b5722e7d5e26132765f1ca49685064ce9216708630df4d862dbd7225333fefc2341d5ae0ad67b1155d06c1d440a672bb6c9ee7da585bf4c182f68e4f4d0cc9beed090c692c089ed5526ba1c0a7bd0a78b21bd3c0d7464c458ba414271342fc8df70d37df26e8930e9fa6d2118b11d8e111d32c51058d7f10b5e721346e025f00f96b0a6c87825d6d36b84b2c65e84316b2f3564aa216f3e63d191a1b09521d004aefb34a74524c631a498ff5f8f98532496bceb629d1df6b7275a90e1da891e6d9da9008c388ff5e97d9794fdc50f861a78e0bd0c37d60a620b7e6606bb6715e46838534a9404c5d1683a6ab4b1afc1066c649265a8c927c3804a904308aec8b08f9deb8b82349b67d40c8e468679279a3d723ab4e8786d0a2a2394b6d64022d205202a921b295167fca48b3fe4ffa6ac756f2f3842a4e58b149509ac3d02842652b310bf85442ca2829781e0c9aab8613d4cdfe7b979592963f6a38741d69af09c174fcd4cadec7ce758ec5ccbe6dbf2d354eaecf3ea44c9c6ef3c17d92831385d8797783dee56a40fd8428debfcf8c8ee8fc00a3facc1e270aeee39a1f1cdb618b4e105656810a8cd8a8c76a277668a1c3d239e104d9845e516582df6ed6e07517cfe55f8c9283710667a313d25d590174e0b6ffa6781886c619926d816eff95639adfabf2f68b8018273b941c8b12c36ec9d8ddc9c933c6dc95f968cc0d72d4eb598ffa8ddb5a0af5db26c6039cbb8dfbde9f87d3a51a870dd32da02ee610013df99530bbeb3513a895c2667cf30ec246e3b0ea60579422bf764222db8740987b5aed1a1d60634555b105bc51f7ae54df1f8d1bdd85bfddf742b37f1fab41e0be4eda401b69443aa0b540193c479c3abc7248a01ebd4137b0236e3f94da638c8356a8eacea8adde5d3ee690b952f4a57a3db55fec4cbb84c555c354c5e2a6ee4878ea8f3b13820bcaaa2f1efb8210330c031adb7a3870ff88008418980924ec9150b810eec3f958598e9fe6a56edf02cd888db73cbda739ab2fe686853f020f95b8c4e72516c1fd30e9f30930244934081493cf41cd195eeadcd0e61bb24e90b8e92ec03bd3915aff23a50567300875e26b805ef56de0d9531a427ba6c4053ff43c3f615800000000000000004b81c302000000000b77dd84f5668c964d4fe819a774914ff883a57622754350ec19e26596beaa9847e03b0ffa0c74fb0c3ccd4924dca72ea94d45b5c8ccfc8355cd5d236e1e62630331c1947cba8e5abce447c6e5ca7e1fd0508051356bce656bd2b7f3d509255f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb3fef8efcb862fbc9042fe6e9ae67b3cdae6ab8af8b301715ce990048e3393da46304d41a4d244c7b2d1db6561688314438768393a7bc0563334cbed2a1ed9fb14a4b9c62bea43d2954b971fbd968b4e44cfb6c9ff2066c8acfba94d81956ebfae728507d2218913c1f5569c8bf8f2a971747303b597bdd3a93f72862ad5d8802152792f2ab4955bb763934fda5f510fb3ee9f8242caecbb950efdbb2811ba5460305bbfa151adc2b7763ac5a1d32c26014d62ffaa8bd8d57b9999fd2fbf25a17a40b0e1248b20ca0aa6d978de31c94cf956012b806fcbd03f5bf8515b40173944aef1c34bc221544785badb7168f0efb3f8074516381c6e2f9bf57d061f8f1bd1d530312d03dacf77b1c8e621c6f29b0189781e03b4dbdd609cb58f50474cbf4718b510220962f167a29a8e4524c08e71fe51bf2c601cca481ff5106ba81a58b8af1dd4f030604a2856146c27511a063f1ff28132b0258f0e6b57519997af61c9c33c451b9020bf3e40c6834c865ea297613d70ba8b165f8ff679aafdc3f4a8b28743dba14490213c901d5c80dfe0f5efe1c3c5aff7ba95dd11f9887299a9d42852fa487921e9e3eff59cf17adb175647399e599c59b77c843687fa41a54feae74846d0829036ed98feb8083cf5d3161a5a09aa7787dd8c2496f33e1b12fd4fabeb769f3a940c8e3c59cf98e3ffb1881d7850b62880c127d1794e08226f7edd5179a96a8cee92d24dbc9ab4783b8a0ec29161784d1a92d13cf3c28eaf348715f5a9175a9d59faf48e20a4941a7f6b179a802bc14ec5b9b219dcf7d6d3263cac702bcb86c97a94b95b9cabbce6933081108f76b3ef53583d391efe239e910943303b18ef3c55a87677415a0bc2d103e20d805de0bd5ad97819d7b6e4fb94c8ee67cbb1c95c027780433841d344389d24a92c3b7471aee5a7c5675b788dcddf9834f9e707639e2825f080d23cf5555b8cd6e47e35a1cd832591960f941e17182a505fdbf7b50c5ec073695aac0fd132b0f05ea14acb730757ca9fdd9937a05317fc51e21d72a2721cc30f8348f65e7ae4e277d071df1a1176afec1cc0a97ad16f14ea8b38228fc9812390a6d0e254663fe4a6269f115a1c2b82b8c35414cd2a820d19820b69e455965c648f0fc3495df63e888da924c1033bbe09868b7ce3def8aca866c1ebc8296fb37a922f9f742bfca725d674c19959953a071828fac1d21c838ca963aee8fb212d59be30c4570f1f282fa109fe2144b597007fdc462134c3967c0fdc2bf5ef1fdf648da77b4acad6d692fec7111af419e90e24ff80db89fa2805dba7821aff542568fda005fd9e7c26339339cd6dc9f8a693ad31b8ef0d051335a2f00ee48a7a708a8c3093887d9b2c27645964c9a307bd05ff8a1ac66a959ed8b6459f1873d22e6e616c30262ea1eee66145352b290d16eff8be1148aef66d98e1aa1e76f5f5772964bd77b4e619d6d1079d4ac7791b206cd28a6901581b0969cefb5942c9a54558fdb93193737d9a9747c5e1b35c5193af4ef7912065972f50b1ff8560b41e98453d87ec584cb7e0c2c33c5e746589e3db546884ff21fa2ebb5cd06853fa2a7121c50a3d8fc1e7a1a36697d0e9bbf1542675b771952fd74d19fa2e9790d7c3a34f0c28e41e5ceb9fd612011f7d6fac9b4fd63f7c8b40bf8881871f52be5faf94f56934039b8ecaa0c7aab510fe98d36c9a84e4ad4e3da6d7c88b5911c288d9c54021c022b3ee94fdf713f67d0cf85d30e53851db69f0fedffa640cf9ba685d13fe6e3baa8768698462569c1a22fcb125a9fe15072c68eea7ef1a12ea4c532fef5def27dfd761b5a7cc60a2faddec044f8112dea6a10f394bbbe4e5a57942fcd0bac69995294be55268f9498c7b3458089da9e5985b9f18e7ae956af44348e0755de7ab949f53c5432aa0ef366e070f01746df9d570f30bdbcfd7aee470519a2d8e6e406a19199888d0bd408b3877e92f64d71f9762e206ce3662370e877a21c9180b2be2112756aa9e03583ba96ccb23cc282a79d713c4c943108af16b4bd2913fa9faaf0951de683b582aa1c69462b527816dc060bdf9617132a101d830988146e148289f7e98e5ff0b48a40ed06423a86330efd1d5749ca13a558b02980e1198af71dead30402568f2a9abe6ae31d2456b9927946dfaabcc8e6f05f2c6875a9c0647ee84a25ef34d98859be4f5888b59f4f7e653bde0f2d0479c157f54e897b1bae1b41e75fe14f2996d838007b454581276c0784d8202dd0792b4f6ce928e67a4cee25d009c867bc14cba60c94812fb8f3b70635765ada95583dcb3638486467d9f75e8e4b1f352f797ea93b188d370e9466ed762ee08bf9ce8b0022fd2c5e2c0c7c5ec39add17df71f94beea32b9794e339c4bd2a8ba2c051d75382dabf43bf2d6adc82719749fc5cb10fae0dc405", "53006aac6551ac", 2, 764040020, "860078a091ceb86631fe27af994b2834a2a3ae59e5b52f2ef6d03fedd325b033"], - ["27da4dff02f423c474092a53ad9f05fdb225c95f4b02b2e64c5ce4ff85467c8b9a02cea5f9010000000600650051ab65ffffffff89f0b1b24fab59be2e13a9061a549563f1f5df69ac8ec858e57b6583db18d993030000000653ac53655165ffffffff01857dd005000000000765ac00655300abc854e59b", "6351", 1, -1820082850, "d72c2054b239833edc790cbfe1fdf3a4b48368324a71db39e962cb5e7145caca"], - ["e5302daa03355eed6a57ed68518f54743b4e84e7479b8cdf444d21c52bdd440a8dfa2dc33102000000005a65ec26bf969f0ca919a357126f6402284dc17e7a16dce7afd2029a8f65e528d745d32e02000000065153ab516a519626c525a773555c4adb42abb167f4102f2e8181941b74a8e22d3413fc80f033333f1d4e02000000020053ffffffff0264d9da000000000008ab52635252006a510b9f7300000000000853ab5151006a63ab00000000", "65655365", 0, 952444113, "db309a465426d9cb23473c3b885a239172ff64e8d416f6c606c7883f53967081"], - ["22091a4a040f67f9421bf3396162711a367b44e920660f6d7fd4235433e7c9eb10102d49790300000000ffffffff9c5f2ebf6d99e19c990c40b131539cb0e0dc191ea5574be4b29152f9dd9956e5020000000965abac526353536551e2268e94dd9d8728549059f65def0ad15bb3786a78436a59c33c4e76b838971803a042490300000004ab6a63ab237d50adcb9c05c4c9d75436b9da2bef76aef5b4cfad9fb8ad8225f8ee37860a7d684ee6000000000165ffffffff0483819d0400000000016ac5a8e301000000000452525365f5329d020000000001513922ca0400000000096563ac5165005153abc3f83f70017806f70200000000000000000000000059b79cc8a9c45921a1f2cdec0fea8cad52c2854299923a09bc265a129ddd0c475cf1832f17ec7dbf827bcd45a6264545b4abc2b2e28efa779f171a42950d4e4e5b0372fe0a12094c6dcdb5832cddc64b166e2723f354afadf4e4bab7b0bb7c7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009921ff6a4437a2f0485d4d6d29b21cb49679b22ef35062e7981584acf47f526460062db2c3bf5f33f6e14b72063e0891177d44af25eb28df31bdb8503caa71aa2fc4f22464f597a0e5346ffadbb008554703634ded71b562a1afba8c278faee6245486d98df6a1431764e6b727b54fa9c3dbc3b3f822b1ed8c1f0589edbc88f0032e02222713dc36fe593685cabc79c4dc4e723cbe185c841eb18e349446bb22a10310f96e21b50cc4112349eadfe7facc19813b98ee7ce5d655ae7f9fc9424b31580b1e5d440461c7c62516987c6e8c1917bbc1d9f3550cae9fe5a623978b0b457fef26fe6fea20a58934eed54c1444813d58dd21d5b18c1c4c6e1040c74f7579e5fd0222842cc37625a832847f2ce69756a4c806762b51f3ed0f89d4476cef71259362031b7a39b008d8b49fc660944a77d8438f6d19a7b1498c41e55d0bdd052c7d2c90031538a519e75c1e41998127bea7df9fddbd833deaa8ce1fa5834a4379b3fa04a20327d4dbe1ad6054fe2cda467bbfd0d1f8b18ddefa183ec65a15e1c65436123d71031c9b7559a2f5fac30b05818b1d83af39b5028e9294a9508a51dbd5930f714d0698b3a7366dc53abaf027dc3b88d382feb4dfe2f6323de4959f07fc9e41d3de3c2dc7e7d6de9e48dbdaa84ce7ab6efcb542145baab41eb25e4977462042d57c29cc18f098d1a7c07637670488d8872d51d64aad1b1e99c49dc57ba389f5582157158fcb2055e4196723e33f06740a3b1956ce7d27ee6298162ba66b09175f56d34c55a4a3712a96ee49bf03bfeb7326f2ef820198e15f06d03a4d082e7231a2986fbb0b1be54a95bc789224620a819afee7faeb06a046777b66195c9e670362cff1027f42bd76e278a88df5214d8023a56a6e117f38c4b53db020b04bfe0610054d771f459afbd97e4c742175ef30e98bb358d668dad08e9fb490d1f73d9ce47c1abd0ed2b6e9565ea9dab872ac1aecb28f470d74fb18746e38dfe46bbca21be272f0a50561bbf88268ff7407015c39ae8bed3768bd335c00f6097f70f7794b6bfd2b4fa0ad8401764df686de8876d25b369aa9e3db9370321d9c264bac518288c39982860890ad1cf292d82b0bb08140c400a2626702af190ad89e55088278ae48f88b060c12523b44ed3ae699cc2c871053cee023f05dd2d2696918587f61151047b88a5baa4904fe8da00767d96cc14cc3140b43e48df1b301cc96194e91f984e0a7a51667725f295389f62e256bd8b9cdfc2e75eb66b307e30868a4eedaacc4d2464f41cf9ba5995a50d0bb8c104a9744f2fc79671ae60a79cef2f99a9b9fb012846d0e21f593a1e9cd542e0ce7573b0b8316884354d4ddd8a54420bcbf732416029dcf9c81f76ca7c1e276389082f94e72b6be5fe2f4b1f1f2f57da71b98ceedfbc043d595468f1807e193e0e4f677a40f40ace34871a6d985e67f7792d812aa538c2f199431af75393b23d7b7d5eb53785c102dee8ae029443022f3774ca24df59de4406fd8da8badc40eaf7cbeb9043503e70f9ce18b4663f0a56bbe38790c846ee3ddc2329544d21361eaeaa24a6382a04077d51ccaa48ea343403b30264b5da6dd2f722216f44b2d1476bbad6149241c290644e8c854cd418c1a7b9d7e1e5e64906c40c6289b62f58527f3b4e66c78c72078b6255918d1f0c062cec41059f813ea29751ea130cec801d811144ca5529a162f26d102349ae82b6ba4f97b6cddda768ce1e31cd9cbfb901a7cc524ebf3fe8942a39e3a063553de681bc377675fd013195d6534d5c8607a7d9a4ae2c54ff86e1d543b3975b7f77e175a27f257525e48891b0202c8db7f95373fa3e9d0402f50269171045cd71871f8dcb4fd5d7cebb5b532b98d45f390f404b148b74c40ed55e51138fdde7df6f885a477eb9cd5eb098e0197a75dae137d81c5f65c4b0881f101b1f6eeb28eea957545e667e32179ba1336a4efb020d06e6e267c29a9caf4afe109fa81e5c86eb6adf11c6871a08e7246403b3d64dc2b1f2873b03e442d17bdb52a9a0bfa7f8c1fbb88a9c376cd0ec294b331462a3c34731f264629ca6562b2cb83479d586b842bfaca422b3170e5f79000b161c4cef851518b99b14302781b9bf2a08723c23ec57dfa6de0c1371f914ee31e6bede6f23cfea530c22584b8f3bdd8c930ceb123493140a58b23e6f9feab51547eb8b144deb29f1fa6c7f9037477108c9a7648e8f2dd0b95510364fabf25aa1a66c5ae1dd593afd766d47c99045f231a56208d9c5a647a5a5bee5c4f19f11fbb9a1bd19df71b9abbce69f4c3bea6571721ac0d96f6b1227b9e533cda50cf29a1bc74c837fc2d628ac50de0b9894d19f3e1703a88a32d1f714c31c57376a3a93eb3a850e64e85a1cbafe3725c4c01a86b3497549a9337fe296af24b469c95a86ddc32bc893a7dfe3bb20a", "6a63006363ac656551", 2, -1599338667, "66234f37805164833bb1c9c108421fa6f517526702a6a16b3532f9bb20c69f6d"], - ["bb56d62f02ea104eb6d7c6f14940ce125cb4f9d45d04b277237eb25408e24f63ba58b0ff7d010000000251519e66da96e3123a6b2e57986335680414a79a8c5a75e4f5800b9eca407e87da5cbbfebba10300000001abffffffff02eedc8f0200000000086a5353536565635136aa2505000000000152000000000200000000000000002928220400000000178355900605d3edc17ddee9abec0497711de8e539d530be5e1571437fb15e7bb754d33d0ddda624802dd5f26244bcc29c59bf055e700c0a15669e76bbb6f87f80f2806a8a2236cce9adf1496646c6e4aed1971f7b4679e124aca085da8ec2e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e89dc983cabf7b9ba160945a847aabaa4c16b31ea79ee9342fa5fedf29e202b2273f33f9790c22e54f2a83cae17185f38f50dd88b4918ca369ccf22711dfcef2c102078b995578d6ed7992cdf92f84fabe7dee8852ab07197aae85fde0f3d108254d21b7c9ee8ed40e381061dc14e561360cfc47dd190e5f8cda82701623407d0315d08ad9eea9d6a1fc3aacaeeda7e0b785677c667caebb700bb8740966c9305c03052208afb22c787e33f0064fe21a548687c1a9a710231ee85c48007526607e9a0b120cc47de72419b80707cf550f404783a3ec0cbaff61894900e58b2e750e03ae0570524a556fc497e68ef6a6361b537f4ce072b4e33839fd845e2b746616471202094053c18cc2ca995f2de812eeb039dc40674304147903d60a2641c8a4d4fb4e032e234cd7ca457ac4dd1947bf66a81c0d5fca1eb0fe08e1766600c7e2cc23c430022d99c6ca9715f87da5a73077a084cd6809f69c7de81ddf341031fa35b42f71850211d73c3c11f3aee04f8916214a02fc17ed74f7cd03887d76ea775b29f47c45ad03174287b05755f253b17d1bef7c7be9e69d5ca27c3530aaaf9dafb200a2b5af2fadf04805a7dff508c790ce84acc07b195986bc045dcaa128c16ade190bdca82fe7a21996068a28710cc259812f891ddb799403fc7a37a45a3a0f00d93352a3f5f9f6d86fe94ba6d273449f68bae828c6a11847f9f20bdf3f1efd0ce2b44e660df2386f88cdc1238970b59859e533719abc989a8826dfbdeb68231379bc74f3e98096c44eb33ce65708f44534d12684d35a8a9a68a2649f3c9d1540eebbbdc844d7c2ef750b2482810c7a1798fe5e83918de7366bd624b6c5e0603de992dbe6079326ccd0006c1a3b2a24695af025522650001ea0459ef576d7a268facb9a78bb9bed10a9ae8c48773f75406ec3ae6f97dd4f3be0d8f0934ff76702ec4b41ee5e571cae2f871129f00ced361aa7918c92f279aba43bcf0160bf7aab9c35202689eb1c7d2f55f44b11ca16901920d317669ee6af4ea1d02b688a2e7c5f518e6b6cc1c62c6a6a370d27425af5a52b04683c1c06dee2f51bfdb5605b1a76cbf3f8c0c6279cbf8f06942c05b64e4e71c063d06a02b20b736275303a4f7e27c8b589bc06d0d6fbc207b12717c345872cb1e567d550d5708df751f456e934b0c5985e023c48be9f112368072bc68716c565ec5d10608127c6da01c630620a7d8f84c4df549f6b40098992b28315faa3b8935ec84d99ab1be54e08e092398b550950568c3999e99f18d4d0a820a3650c5bafecdde7e4c32bffa30335ebd43bd6b56ffec112a86353b1efe584ad16486ffc80d836f0e2d9c0fae5b5d678afd7026a7e408c4ec82b4e5eee167cf2c1689e785502c1cd8a400c6f25431b8b645d64d25c5b7622f56781b78d3292dd787dd2133e1fdf8bad12aad36c003d5e94bc555c3951f584d8fe8fad98885ec62eb534cd604a1e95d4d5b86e238c277e8ef34bbafa443e7969f7a857a656c6af6b3e009b494dca70fb108878db455359a8daa0fe3754b1306b2672028e87f7aecc3b70f0dcaaaca538e0cbf0712d9ea5300a56703bfb4c97a4ee0eabf8da22e6158fd10ca0a1f5ad6d3f902e248862a9835bfdbd6673ff5ba62f16760d1b8287495b773c36d9f57b6b2ae13fc7ddbfc5922153649c0c972eed93fd6bf36d7b76310eeae577fee9837cd4e221886731ef42c8c76dde62650794886ee000449ac57a423ad11df3f769b19298b0a310fd0a1d7caef026c5fd2334371effbda0c92d0404961a750076bedc7f1c69251212b290d50b7608ce6b70e1bab79f405d2ab2d23b647064f72edda79214fb358bfb78c45c483590904fa42b3cf656d4edb30b4103867ea714baff58140d9cef7d04d6edcc7bb2e79afd699239b47a4bb97625ba1df948627344f603bf68602faeaf6dcd71e4a14ce9355181accd8425008bdebc586ceb8049afa917db4cf9e81830aa699a4dbdcca6387cf343bc0ecf1e4e5fdc97c051e9225679e9a05805f2d7a1218cbe1ef8e297b6eaa30e05a50074337e73f6a8fd95a86a3f7f0d1d3c7d37a6f05a9db5c49cef4c6916dcc0300687015d0b5c3db64dfdcf0a03ca2f9172c71652f1d07215ffa454bd735c80ecaf7a9c147e2692b66291e40fad2bad7b9154024d973f4a99db2ca26ffba3f63e0caafe7a7d7c7b0b921ddd441a2ea9b3119abf728ceaa690cfbc911e456bddf8424d7c183044ebb13b32d6674a58452d4694d67488e80c639fc56b2b8991efdf7d883456730890e114e840df290000000000000000bf21b30400000000208397aebb773cdd6f47f06f7de3a8544b491ebb4482fa8ca5f95d85e0256088af901da8bedb34665b469b55bfad04129562dd296a46f232c126ad9961abfd8fa4e3d408d53e8b31df006ffd3fa3051b9a10cd0baf8f58fced65cb439c7008610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036a79d38a70496b1d9501f49eb15f6727a33de328b591b8d4aeaa3cb97dfd2599fe7a25f7c32ea737d0d94d88456c0804a87da85b4ba5e4f021dd404f36cb3a956f4ec87318dc2424bfa736c2f88c9b5293a742871dc832dc21c9f7fb565b0beff403d8182fe2915e929b95d54566f96c781bacf46f5206d95f3daaf0759bb4d0228d2d04bb161b3279f16be0b1ece1b665e1c40db4a5005387105fae9b93e11df0208e50afdfd56e0240b76d7a5448baa9fd57d1d848a8da90a5862980a1e7a4bfc0a2bd818e56104b4331d8ce231c869869b4f25b13d580cf1f972ca8ebac148120b164e74c894af101c3c588c6a63b7d545e79dc692eec2fa1080527bf0e3f3f2c1031a6e955c1ff98509d40deaa6be3b29324361e1c89d0a06465ed52e4d9f24339b0221369b33b403542cfd905ca36b1cb42567080ade8ab6651d6c9404545611d4d502235776c988dc08b5f1a591ad726f1f8937d86ee822ba03a96e4dc30a09e64d31022c293fc7134c648fd5894bd4ac9a78d007e26d8f849b3166887b03821a1e1dc003052ee06c4341f7710077a2902428cc47f00438f72ada5302d6a4172d267f716fa11c97418162bdfb57c57223a6117898a4a1be946393f6f681a0fa726281c5fc35c19ea725bc51b25a84604137dd8ee14fd5df075dd129a68738b640e76f1ec5f4c3cde89b42bce3eeb752e7fef13751e80bbc1a73bf1b6c9ee062ad6c1d4a7ba0a447a660e8f40a9a108a81ec22f4448785a113823e4af66ee337e9fb42fe81b2bab1cc01d68bedde140793fa8480559a85ff68953516222c7c39cc30d450f7bcdf5b22a621326e79ae63c7c36d4a22af0b936bd91f0e93a12b501468fd7fd617009d4532770c036dfa7279983cfa82c826c923dab21d6196e7e4fff527e0ffa7b6d4c26a239819445dde789ca0e6b3151f9e6794ec2692c0c90f907f13675e3f04f916bc961d533b23aa6541e08ed80e9f60cb1a057220800b38399ca1f3435caa84dd8f9761aed53367ce900f46a46bf9e88443f40a5194f93aa6a3bec2bf28be78e9e097dd0302cdf0165d89814da288cc87a4928c8ddb3edcbc28c3f4978750b6fdffbfa09b92137c6a6738db745c9a0c8d1c2685a5e601ca65b743e75e352851349c5bfcf88e056d2f64639b4b5038facee89944b1c735859767b4ec2c580a58f8a09e0a6ac73008c672533554c153a50d153f22f81c7daa58e24f80d0e2d088232b26074f5ae26d4d68852f369980759bc5f0c42bf79583f2dd15018d27d23de5662a46a3a14a0dc761a8c5582d027781a80ae332b6a0ab81402a5828d2ccd19258f498508855574d87dbeb06ab7915dcba152d4faf04ddbe4aee1eeb0f810b7c3fd02da44eaad67e99fa5e4ddd5157386246a9220cb254b13b1cfb6f3a61dc7f543dacfcb1222bb84416a7e286d84c9f8b7d5b342bd0818ab22c48e629090eebfd12dcdf3f59565f0ea39a23baa55343245295e32312f750135ba00056429b71864b25c4b88ba4aee571dc9571c1e63b1bb033c07f6f382c9e3122428752a4af3190dd165ef109fc0e4a58a8b2a677a70138b010095fe6775103d0a072dab96bef64ec0acf9845152994c0772d48e4d65bd6525c1828b85a41850a099c06a9a8970da0709d195dff39942cdb420cd5666fa814473f2fcf3068f15362aeb0173b1cac4f9915c4ca3a6fcd5e0ed1d55c53c9a848b8d4c71fdda2a12cd8c07e1a0d0d25eb5ee1beb66472650db49c451be1790c88ccf5dcdc4b42acaf75c44c2c0c3a7ac839a3b154f95248ec010c888c8366e91c90fd60920e183b00bd5bb2b32c0a6fbc82162e2396466dd30042cc6e142b701e4e521b54ce2069ceb31bfe76741bf3c86e45a930fa52badd1145fe692843ef146adfdf8d5f05eab38e95adb6d92756eacf4faa6c66c5010267809da11ddcddbd0df9a8c470fffdfcc306b89c647267561871413dc870b3ef6e98ea5fafb36cc858cb4719264f2be0c16429bc84a684ed98d05664a2a1284001d2840eb476d05ee2792955e65f6403245f6dcfddca3858d5300291b2a77617ba3100f657173403ffb87f8be1c078dd7cbd4a91adf6aec79e8ae1f12a5f06a23cab09e73052f13edf9ff9607fc596db701c944c76ad8ee0e334a41df032656a3c89a99b25d9032d7c635f52f990f8d61e26e82181803fa5bf3f1d389d9cbdf3ce5d7d9103e4fbd428db8e6665511a86d0a18b9c7d7a243f7cfb4d8039077c8fede97e80bd1ecc710ad31a45d703460c0d8f3962852760c22069eb7135624de414db1ce1b8be830baa903644595f9cf84600ce1a7026086a66e77114c822b8e3876a05c8ee0426798a3ce91ae8e0e91f3f25928dc3d8bf39d46a15a3d69ca0c10b86d3acca2bc3a7befe68580910c1b597376d915166b363c72aedaf1ed8de96b8ef0e", "", 1, -647169879, "071b4c25ce926612c9dbeafca7339980c7a95018cc520f62a383bdadbec0d5b5"], - ["d69d0dfc03609d9ad6c5a431683984ee79090b559e24e54302448cbf1074b466e9a89866370100000005006aab6363ffffffffa130aaa56174cc506166873b3f9ff9df978953217509a87eda6b3560beb9bd4b0300000000ffffffff5f50e2b6006f6c6c583fcbb4472bc7725016bf72cf4895a5c6982f3b39afb64d0200000007ab000063006351ffffffff0407997000000000000852ac5251535365514e530e0000000000045152536a1ffaa1010000000000ff8afe040000000004526aac538c71f3b5", "51ac0053", 2, -592689762, "a09d65fb9ff0cf00ff9c6f4eb2dfdcd250ec366f53a3dc7905b593cdb169c55b"], - ["a41bfe270219d8d284924a6e3755e2b817dc467cf1b5d266a69c1a3ab132bcdfc871c7f53c03000000026351ffffffff1efa4ff0d3ad8b18813670c101df103406442998cfcc8e236540a6bb39d5e17d000000000263acffffffff04f53f9c03000000000900ac5365656552636acbd81c0500000000026aaca625ff00000000000553ac526352f781e401000000000451ab5263a8d6f70303eb5f6001000000000000000000000000ad8e0a31cdfb52abd86d1c538d2b5eea29ce80751e9879952d674fae94df2e02ff14b879cfa12659aab6f6a79debfa18fc0496b7a4134705d9cd49eddf189a78de01375a0d62bd1a328f959c5515f2886511eceda68d120ea8fc8a4ce09982cf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c274334e9ae832460455df9f05ebff403884c04ea54f361101be4b92b962e3792910eb57e2a71492a6a0a140f4294aa34f3f3ddc9e92f4c92aabed534fbbd8844bc2af896433fa54bb4a55f3c9539f10448da2d218e004a4c6642ebee10c0b44c204cbe8c5f84bb8cb7d8736694eee394a9139569d2af2e642ffcad102235f450322a6a3c4ba3be17b015f76cc14c54dba25cf9e3702a39e586d0c175847341910020b9004ccd6b2cba8cf0b01c365d4f5f34111086be790ecfe81af912ef77a21a90a012fba33cad2bbe0fd3fab1ae5fb0edafdcf1d1b3e7b41c0535a9b16f268dea12171f5b6e39a3322c6f7b8fea01f347eeaa5e3bbb00e283f9d734c85d94f2e02030abe16c10d31e656b238c1036d24b963cb6e1497fc1a5f0aecfe8c71c951b8bf021be727e2304e3cef0360fbd86846316ab732d1d2ba486dc73068180c2c6de56902272f8eb70341bfb2d4469f26ba74c901610585ca172d416d14fdf47c947fb8190218ccdf5ce88ef12ec0b6eb503d2d8193ca45e9894dd6f5292c3373bd7231e1290303ac856751e90a4b1d5a8230844c9d2a14e75a4238424bd2706dcaec1a02e21f819414b7193ba38f5c19f308263d82793d37c7fc93299a4d6d0d6357dbf71ed5df441a5d7bf7062fc0fd19e36af36684fafe321c5cb067c3c08296066034c52b1425420eeb02146b5ea51f127973883c1db4e3c290902785e74c83a9697057ab86ad18868343bd844ad3c76ffe00a8de12e6145a818e55e7795ac8cf69f5499e0c0f10fa174297f95ec273335fc9ce6f8bed1a666c0af74cf081b9b6017598a94d3c74bb33f1cd0eea1595a5b86eba5d84c857c8dcea6b052448e178221bcb71c7b11b86cef213fa3462d95f059b6844cdc812a08d08e5d997590d44cddcfc8b3fbbc5c473f1aac86bbb26c98b97807534576d8dfe0b6ac4f2e0f07577ae3ccb1361f11b855da2ff3c9ddcc64c68b838eef6f968b03a1b4ab0a4a0cf42e9c459b5ae2a39d905750456b777868e61d23a50909e8e044f6e4604f58d3c5a07459d6e5bfc1406119999dea8d5e9d14e9928e4694bc75f521b5ac9e3800aca4864d75a1ebbcbd2796452449fd12868f73fcf2c338cd0702593e24a162c67cd3aa0c4bcdc18cad3feb0524be05588125b92c415cc03a4d1ef301c09a3e09e1686b3c23492cfe2b5f85edfd60369d2924526c81ed579701a8f35916abd9fed7cc8983e38adbf5cffae2eda55517e66b9c74b3ac0cf2d1b348bec562f77da728b6b4d8d2d7855cb6ec0c8251a429cf91d13ec7cab50d74585bb5cc862f2c499ab40408e55b754e05053360899b41b6c13a26206f89ab9a364ad5d0b4f2d3c221b1ffb55399a59cc217dde7ea483cba8d723433b75a9384a400adf0793076e611ca2646cce11651882bd3b3bd9826a8e8f1e55876fa8c18264d5a4a89e62b81afad2256a0a0593c11390ffdb6f571bfa09b2e687ce1706ab32deedbd4dfb68e3101b0a023aea5a399ddb5fdd5b0a9417d546c433914e5f38ee6273862bf0b57daf0a2db0f8708664cd78ea49fa6cf2fa2d97242ea674be019b2579a79273c9ade72a5c28c50fa810e3cb74a88576f02faf89320cd4f07612229840ce2952d959388f274704c42f4025b2fde8b983a18b923bdd87fe715eda25952d75d55c9e9b523f94fd70ffb933af108a3084661dc546e4425bdaf75609dd5750cbab384b0e8881a92083098db7a6dcf703862e6c87ae5b5ec5a0214f3556f9aa8c497aa31996afc3450dd8da1c0723a5121313d6e5c0312773a72770a420de756211740250851a5ff60944e3361c96c2471c808f3dcca49420711f51f8c027aaeb38777ff2ddc3ef47a54cff32eecb8e77a496f73c5b893f109fed6291c6ac00f07cdeff35a3a577874d5c4fc0fde5bcd9b96f89c69be002f8758b7aa4fd3914ecfea9b12c72dad60c8e3c9644908cfdb28409346d4c56f52d6c176a922c4d69737d4cd2d62d037b20f9c3fb1a8ac38d97a71528acfd36d2d614a14de1af7a3143b9e06f64cc3be35fb9076efe0d45f0147af83740f23cf2a5865202c096971c4874afc59235a64901226730b82b2491474806439ed5364caf62c1704b750e236c7d63ff30a0882ca949f009bec205f57c794ec338219a34f4a03471f3eb6d2d9a74515974c4f2ee489bdce459546fca18f6ac8d2b56183297fa5363e927ac8bd9adafcccb1160c58037fd48338b84b18ceb955d8d787cf2f64d5e8a9c41d7c139849ed37f8ef36392e6093511050405fbbc281b7baba7f6be0b7ce0f8ea01000000000000000000000000f17591647ed6e64526afcc482b2db15ce47bd89884d6a342aa48774f3a7a211dff99baef9514945703c291b272a688df4615d824ef6e1624109e8cd561a3c26b35ee6bb188384d9fd221a4a335ca003fe40cd9cd56e47ebdb8b6eb2b3d9c448c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f981ffd9ebc8f7cd4e764b4de70051bd7fb90e9a9c1e32cb02b66af333a2b021871652288e4659284f12b2c5fea81b553fa801f7a19a1343872ecaee34b74460b7d0028f0c142e4081ef85aeb94118ee202348da272be9dee2eedee29e436f277abe3cd0327b92f9feb8f5f0adad2d0424f7ff9d4cd1e9b4403b57c9cfdf5609032586532c8311e5acd3e8249a07dc94c0d56a798ae10bce8f53f4671ce452220d032edeaaff99f79a874f4fb43cc1ac25641c069f4138ae4ec234e8a0cc37e4cdff0a26e019e627fb7e246e1c2291a2299717ff59d612fcb74614600275e14ff377a427159200cdfa0e4a4f91084daabb6746a5e9ac8525718e5c6b2ce5c150ae7aea032b1642126aa8f744f619e9888857e8fa4b44ae04c50927ff62577713356f1f37022ba0fd5442b9a467f9818abbe13c327aedaa4c822e36aeee62d5bc0fe87b37540219f50da6675952ffe026f962e7d00e32c9dbc2446d50a4c0f429245e0f33d0a8030b9a9f1de1c1983fe0347e6119c236af02b4b232d3c1f27cea88834e8fab1cc802156badecb098106f593303b08845291c19a8767b50a58ae7e906435870a90d04e78088b993b48099c233e06477d7783f300b3d0909cc7bca2bb38e8751d13d0505761ac149231a872c09ee9eb031aea1ec84097ea9a052cd9ab5d424e1710d032c63bcd7f8548da45aa0965c9cc434d57e500dbb490d6e3b03c954dac5642fd2ea1fedd255dcd1860a3432cd1c30de3abd43905c1cbb34f2f3e20e2ccd0a4c99f62193170c1fa465b679702ef9e990efd1c915cb8343c4bc10512e36bb952bfe16b7c9d50fb807a80ebf8d2d26b0f3167a1b817b5c50e2cbae0a9cabb20ec0d4f87a6e1f4018001995efa7a59b6be4103d79f167442cc5cd51ae3cc5136c4abbed75f466b164112adda0e7cacfde0ca46b022d74259e83086efcbce0803cbbc5c10536eea9d928d1e7c455971def284deb28e95c33a10cc06d0deb96493754d9e898d618781b3ce8f5871640331e41b9aed8fe293dd4b1e2c5ba021bc5b86d479fadd45b56efe55a02a32ab09eae4c6a857b315c9fa2bd7e966ade37f6de9a0fa0c4052b63b06a7ae7557808367276b08de0f59111eaf483900a9907a1779bbe1b19b7ca342cc882f82478d00539763fd183ad64e9c1ec057216fdfd0cb0464841e8efe3b541439a6afa691076b8d00f332489f636d0e5b4fccec64dc9b65b268789e01583409eed63ac24195e8be542536807c5df7a21aca024304b38d0c33f92517976b89b8a1024d1ce69896627ca2bacdde95d8ae3c512735cb7e2f23bb23551c85b0857816f36150154301b9b9d40c4c2b864590ea40b5274b2e1ba46e68fa7bd16ce7b79636b28cb30384f2be5992148b0e375134bba7da51879d93bd119b38b1cea4e85b68c44d22e70225843afe681328e11e0953444c436b247d3d1d01859bd1329d6c02c3345d26b09060d5d421646fafeba2ab64acfdb1fe9d025b5dcef00b6de2138a9c755b4293f3ffabd7830c8a7baf8b45c4451ea55669abc40eee520333c4c5ec49517a8c93efc5f4cea858ffafd710e10982d7d1e27045fb18009c8ca272d5a09156817b0757713e7fa15c7c981be37d790f99a8986a5b936e201e872e222e566a73683febcf885a9e16021de2275f51d4112796d0ef9c3c889f055b6fef65b8aeb472a6fc2faeb9d5e7bef6e2bc8e93259d8010413455c632118e260d7a6a5ef19f471d07a7dda950de7b09b9b330c46106040d82fd4df2bab1c5e797696e810b2836fd3ac38680aff48c9573b74d1569f063b5477e675325fa5326ba3215c39c04ec11e443d74248bde0d885e19d40d69f4d0d49445f15882a7e78202ec274c1cd03be1c644a9246b0d501bef364636591b942a60e18ebe4295c594ce85defdeaa2677368722d2cf178d95ae016cb3735ca9a9b08b186353c84c2b39b5faeac1ad4740f2bc97478253b5dcebc4cb43bc8a547ec55a6efe939d70fc248f72271e09c9aedd509533e09c6248079048d48906513b5f9353eb1b2f2115e7d30112cfa204bd1613c0a979125e7ad55f87ac7e956f38292040e2f1208106740dcbb08d9553884b5de62009794fa8e972c147893f8e88f2452dcd89fa044021c5fa286026d350d526640f2979e2b34acfb274f3e1c9414b314de07c44f67b2d119756b3f2b7ca8e7a2da1d494323ea0b39e39c049037e4bf53a6eadb188005e78dfd803212a55ad686a6eddc0ac03a9343f026d7a30b6eb2cdcd7462dd9d0bb2b6054728fd5adaf4592f48809bd573020000000000000000000000006cddc22570414d42bd93f5bb7991105efe2fd5220b5abafed1b1bcba170cdb78e48ec4a926917bc0a7cf739634ea05e9b554289df8a7f54fa32f4f46a78bbac67229559f49cfbd6cd5744ceaad52896c8d2f048a4aeef6c0c8dd7d9d930fd07b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a94c0df7b31c7ebbdb564f05c35a06f8b3f9db1c4560e4419894fec32a7a50e6f8f5071f64ca238bc7da1348059b7191eb42c1eafc878a190e1122400e36251daedf46fd2484640d933542beac084ae12f88a4ff546bc8f6e05faa34fdfc91bb5d56b138d8e4a5b45f76ea8727780285cd4539d6123e61bc4ae65a632e3737e903038fe569b6714524276800636b9066fc3ed4e09ec60d292fc6c136a25325861c031fdc31707f7828055007dadabc40cfff64a4d981077fc62303464b2c01d19bd80b2c0713a01383f32515b510f04f3fbbc1491e8d0183b43df8ed7dc05434c341b00011a1393f7ed3de4f05887dcb34274a1a81d0607428283958013d33a46bed420320f3484c91bf4851d69656503d480787d3ac9396840c65a282cb3ddef466e34c021736eb7b02d9d281ae5814c7c70e8a06fb9b0302693c2d810e670eb562c54ac9021d975dc64b65aee12f1999c5fa6e493242445cce64fe0b2327314251516465590218d45532b37819ae1ea4e17f814f670f3d0edd3a7925238408e1ba3438dfc0af030d8b9fd60d4499afcaa8562391db27735c183abb2ebe3fd48d2d5cce05784c71d8ba16546f1eefe3df6a07fb28c09876420d99d0fc478d5fe6496ecdef3c935d835ad892418393bb559e8451ed075ee9b49aab8b584c109002f3c3df89f5320d1841fff612174f4cff45484d9f30d3f0bca77bde6ddee69b54ab95d0ef44d36a8fade15b589e67fef0015db0bf592e1e12ec334848bace92528b77f6910a772c938978f474cd5b158bee7467da565d7f586e109c54b3e7e41e94a47b2067abe8f69fd3f3e6f0d139439a7fc9aa33c95c7aa6d714cd3bcc426617f6453f815d12c95fd1e550f5a538063dba7e157df66d3bd6e46afe754da57f199aa1fb44f74697288962a5ee102cf9e489b192d0d25c54f8cb8d79116217ccfe267f8aad833fadcf6f70d271a5c526ace769a71ae729e721ef28d1af32ff0dcd37c261c14963102bfb45cfa34f98fe2add25cc87426dda9ec16904b405d35cd112b7a5a155348eee24b5c099304ed3ac95c9d632fb84812376784fa8e3840b697a14887c1d3042bca53dfcc913aacaca5e8c5d65f72037ee26afc23be2d5a7c3a0c72046316ca7b03ed4e130eab252560dcb63262ecc3d7334c33d6e47265317ad439ee4a20fb4050ced16e8597b1b56cd8a07f9827ebe944e05e1eabde5142e3bdd3ab63242dba0f97499efe4cf2872e07c2f15ded84aafb50b7421229d1445c424f4f552698ec74c4210a3417d6365ab4167781c68e89c88a0613a1cd52a07948db26fb07bdbef3d307ef24a66a038405ffa5a6a36b0034b387cfd848625a3061b9de6b93fab3e472484535f8e279bb1bd7de208a98ddbae3fb63edc0e1324f9cfddf99aa62040423b5d13819c93709003ffab574407049699297824600938370f081544b72dce2f457ed8e7482bf1e1ce2b92463cd10b1a4dc746883de1c3a3a409d1637342dc851a483d77047f56c8bfd977676505887887462e5ab02c2712ce4da78eb035a29864aefa0803408d2d58270d9a2c6dc265a1cdbceb43055c558a4f567de7152a47c663f999af0e7d884dbad8bc1f030cfd4bbf92d6ef985dac714c558c6071c438fac5c73802dbfee4f48c89afb2c00cbf5a1b9347b53c83f0a67823ea55c2d707829efe30cecd9ba2690ec7253c8748c313c8bb95755e02c75c44d7a50bc53188014c88d772993997895be7ce529d338239c5b1f169e566c56ded6a9cde1f7a3190a958f7f75e232bd0b6cae551052d7f89442ce167376f32115c274c7ecc596c2d578f32a057c883d2028fc07ef8f4b4f32deb37098b57fa0e734f190b2e991f63a0af6bba5bd0b3a3786d1b2b4d9b90fdab1d7599cd2f8bee621389bca95126cd72a8de6f03c2f3727158773ecad9435d9ebee787e2a597ef4d769865066ff733794bb48d8a2c117898872f86a6bf465c6d96e5fd27e058bfdd8a68ed734105423bd6e031e123483ef7dbe935c7e3eb4e1b794a88fb543b2b76972d46629a2711836c531cc7fc8081e164e9557a6f0271719b0c0f19329a8696c78eae3582498d0b62d2ee6adcb318554bcc0d33d717ae61769c91afc08ff87273bfe3b3613f51d3d879b81b1d2d36ef85963f011a85b2e1b1ab4bacf9ece1f0fea3c449652f562684edf7661a9a52710e89f63a1d30ac3dc7b2402b942eda1e335cacc8ab824ffbc54ff57253cd6592fd06bd7a640e64532ac2640f2fab04bb443db0c510d8ef11ecf00352f3858e504f684445520774996cf7e6cf486c297b1794b939a6f0f00bcfe78666c73a63ad8b4eacae60f640076fa6796bf37ef14499a595e650e28d0c943da184b470161f35b705f04717e40d3c5031620169e0babd060da126e26ce51f9619f48643fec7cf3f611b0a", "", 0, -1265752255, "d8ebfcee483977859607fa7d14add1e107f6c096c20367d71b0fb592d6af1540"], - ["9f140bce03448d96772e345909eec99f3a9f3161c03cd2fa619c91ef40ac9636c511413ac10100000006ab6500516551ffffffff488a57b25fbbaea16326811f8e14d8418e0f6004a09999077ea1f28cc5ba9e35030000000663ac63ac0063ffffffffa0102d720c343a65e8843d8dd11e6c2b50826bfe1d49fe9d5edb168ba25c6c8403000000086a5263ac00520053ffffffff02bf9b3703000000000753ac53635353538cd5970000000000086a6a53515363515200000000", "635152656a536a53", 2, -1344830367, "bce3b3ce45ccd8a880dee59e6f866d33d79a8fc388ca8e99daa8a46e637054dc"], - ["33f9ea7b020e2c567b418a24810ce108bee0b292f14c537bdf7ba72856e598593979f7d88b010000000151ffffffff13b96ca128943827a7316b3f26d059b9010ae7a1d159d9efed30ea1b0446c2d700000000066a63ab6553631f33b84803c0ae7703000000000026c1470200000000025363fa92ec0100000000066a53530052ab00000000028f40d005000000000000000000000000b1eee09ef1f34b5fcd6dbd943301615ae0bf560bd2eafebb1da8f1d5ab3c53ee324c75b238a14e86431d7b270c967556f010365ca4610dfa753ecdbae5eac2ba3a9caddf07d04284030f6651c850548ad5c05ad50d9e8636d8e1d47c4fc56116000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001189da5d85208e01f783318ed7f48effff37ec6828cc36f80f3b6f7dd66c8fa2413cd09ac5ad7a391d3a7b4f592fe01b69a362f3cf64d5b97925fc4103cc9654af57dac917ec3ee501572e3793156455835ba542b909b6c73cd7e56f6460d0363a622fc37133b1e6494a14001d0945227e2ebbe88ed307ca29e1bb22c602924802057efe94b8bb4056aa4e8fd0577209a94e5c02c82b256b52d97056406f45a4eb031a2312463dc4ac4614e8bd0af0e6f6a5573ed09f3d875bda8c5f6270eb4e48bd0a20da829c7f0b7a5b7ce90c0077878a7e7466ed616003c29fd4422f46e84be37f13d3911f5b6d1071af1bf20f931c2a40f31c3f2a03288a40f8bcb568e247b657030fa64fd40b9dd5502f0615550417ab20c018220a8d6b8018f55ad7e9df9320200229ac369c64dcd544bed6871ca00b66a0d5f7c0348fe69e257c330a20e59185c5022b95dc61566d3ce88578cc18c1c5e86553eef03e04326ca485bdffb99c03b2810317777c9770c2a0d3cb17734a60cb27c7343adde9c4773b62d22897ae565007b3022c193fd07bac542b5de75d8b1d7dbaa60f56c5a26a90a4f7f7b524c882f83c2341ebe6bf9d340c2506a42e0e82a86416926464f39538127e66c05d806917dd33bd76e1204926beb4aed50d691bdf7e9e3aa4a485484fbffb5f98cddcbf06ae622bfc8bfd9a62352ac140e7f94b7a7b4f887ecfe0d1b4422d4aeba27df0b9279bd892ac87dd4f8ff3bf4d104c8aed8188491e710a6224690540df228cc562ddea9672768c3afb3bb32e7c862aefd0c3b436868cb38f0d4e3ee325962b55e2720d48f64d4f88f11d3c93369e17412f2591eec1140c7574a7363f4e1e90ef668b642c7a660086b90bf19b58cdb964fad1023cff1dec454597f5dee0f74cd1d605ee09a116e183ab3b2aad331f5425500de827fbd8bf446668723f1a827c59091c05fcde09411a80d461b03c7d67fca668da0644cbc1e7d3c6a035108d8124a3049e3b6ade44e7a7b12475fe3f672fa219d05a7829caaa9cde92f3f67e70e8103981901bfe05ad4b187bea3533a420b83ffe670146999e760c82e2826b5a6b9a8c9e2a01d78f639dfa3a795fe875661ac949fdf7ed3de7aa4e2c31ffeb0226bf0b047fd20dc35b215c072519842024f1e02064cdfc6c8f1e98e259c4ad12fb5bd9d8f257d0604962d32d427f4a9bfb30e21181cf293c1be132ff77ae09335066f541cbc8471b019500105ddc05cfdc6db2b7c6e214ec58754fba19e367fd2da81efb3ef699bb4ce86d15ccdd81bb5c162658dcf1e1f895da21cf80b57eb0ad3a815ce4322e78493f3960c9a0b0a7f7bb5a3e5604d9db4b453a625d8d523a36ab0abf617f39b329dca32d2b0d5f3b1a6081d0064c268f6987429076a8a1745fae306be00c01c3eccb3ae32265d450cbc79df85154a7793f611c86b895df82715d23a6b30bf98ae676ef7f8fb069549936c1e985ef4a0288dc81cd5df0d7df4f0102a60315061f4d6e56435b6ea309b6d75d6a5d3a9d9b05b4799428e123b3f61363d86bc322fadc006b10eeaaca647b75d4738a2351c93acecd205c5aefa0dfc64c8ddcd277eb02cb1a86b0479f68545e07010c2d3958494a830d3ce7c04d05946664b01db1a3e0d430e6c118d18461f0fcfcee35912d1f23e983c4bbdd2ed6d0b4dec98b148798fa60f20b93f1165e1eaa9fe12639d0657eeed4d43e34fb0565d9690d400b63ed589dd91ff3bb7ab0eeec87c03362071f85d89e6ec5a7014c17ce38f111f4410fe41c88645180f7feb8f94caf71a68b3a636dbe8078d8f2c6e33d9594d2609019b9039caffbeb758e406dee3c2e7877402fb160bc033c91652eeb62b2b8273148eb430e6b299f3ef82e425a7171ae2070d6fce5e0a68d9d05ed72bcfc650c39058b66ad7d18a394c1b2aed2ddcb476e2135afd07e9cc65d554c67c770fff39c9701f160adbfa8b6bccb7d4d7ac73b0f7dfa4b02cd0954ea437386666ce058e8973c7f1be80cfa5b49d7b0e4ea811e98595446f30777d3485e5630e264c34e8c399836a10d9f86829c398818ea95efd81627508cbbbede8a981dd9a0a03664322a79a1bff94cff88b0158bf668753039f6430dcbe9fce0ac63c355824c12c288e8882e38db04e65fa27ba4f0f7e95a5f75cc13b8821bcf74f2ffbeddd9fd92d1f6b9907c1498c4291ce75f749e578a39a593954a54e3ef7d3d7a4130c1710cd3edfd659b494cceaf5ee55c4b5b222b77d48bbaa3c3f627af79e259df367e88d27ee18587cbec910261b1558375070fb23805000000000000000000000000f24ecccf22f13cdf535b9d731d933dda5696c78cc419049035808a322a0d3e333d5868ddfe2cb2b2fdc0c7875289e0ae8fb1bebed3889021aab4eebc7867b0a6eb33fe68902694f52fbcd0b866a1b7c64fe95934d60a683db9afb62e5f5ece940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090d99a95847ee6e8ec09b8e364d280887044ce7f2d1cd126cdac73408fe096b63f3364e1accffbbb348806bafa3303287a599f79359b7035969921b1c1e44dbaaf7d4201578c10a40080d8c2555f143ce7f0afad71ba0b89afc8e631caed11f15216c1744ea04ae4d618184d5ac7a53557ca04614d5475be8e4b18fe2f4b41560326c55fa4e4ed3e59f7509634c60406c2958d66e5955a42b00adc7eba8c2f8ddd03135f3129931b0dd67dea85c08288248662fe54bf773e42fd75b432059404fa730b19d11003e877bc42ce2d643acd7340a31069b5264d56a6d1c7f0b8a9178b69671e9a32d3a830765cf3cd1d2037a4117e97372d37cd7c53a70cf1ea11c4a9e4730304e15b54c04095188c7198f35f3f11c5680a11fd7f395ef4770c1da023e0e6a702087a15b5a790308b516757c42c81f69eca511fe94276066ce967d3e8e1da9085021d50b2263f5918dcb6602b6017c35d5f254db5fdd392cb9ec93705e2c28ad62c02050c044a84c40e08c527e3fcaa5d64d9ddc8d06f596c7088881f11ebd98ac793030baa611f4fa4565ccfaa95972e64efd426ae8701fbca8687edaa65ec2fbc5d53ca4c2e6ee100567f8e3d9717d22a55ef4cedb7ec926517bff976afc8587a5ae2590442b8efc0b05dc137c671a36c08b433c17f058845deab6803676427146b170c0c6c517f22e07cf5a9a5939a1e52ffc262b7254f9749c12ed95483d09d8edecdc17ff4630462e3c8d55c9e5b6bfba0683c4047c3a05a799f3ee95afcf5d4db8e1bff32210ce1bfd4b8a0aeb976c519a34cb3c3531dccec687c94e33547b1f332035f81b2e43ae387bdb84dba076b5e5790076f8d461d909762ef91411df0835fa95007a240cc5d95181be253f99d093c7a99512c475bbfab680e21d81e4bb51e98be56c7174d7fc943a78dc46c6d058a366c6c0d5e4b9625810f58ff6a42fc4bc7fc08dbb01daf0d42ed0578316f3a9f013d0afcdd25f9f386511d727b102121780c697b61b7903708b2a60e102e8d4e8a57ae009184a01565b949f7f5bdc78c3b1f8173e6a631050d1eeed2a2b0a4eb7106524f730f02594fc8c1faf6adaae736585dbd9e478e845fb5f7f349c3ed183fa9ebac8005dc5cfb9fc3593b4f0f40f99021af5f09b6dab4555c693d4d2070cd44abd126453564459fda82394cb37792e83cb72f7d41cb4a69c525169a822a6f141f17152c532a022ce7201c5223c8c274ef6b26aa92148043985b72f36516e70ac484d119a79eaa4c71572b18be1fe5bb221089231dd088cd6009ba39c0c6f4af1a7e0dc64c15e9bd31fb62b80aa5aee76c89f7f70f688f6280ea79d3e8d58394336c69a60be61d69c0ff41d4fd43d52dd063b5510e78ea88612a6bc7add98f17537075705b1b80043239454f0caeeb6a14604bcdfe07b42d6e3eae55f721d05a9b7c3e67ed769f1da2fc5ee3a625b3dc031371e774046b2887db60fd8a0ac7722633ca31db65044296fe043065f4c73b29f646ce0573321554d5b299b102766ebceab0c0346fc6624f58b146ed68c33695922f6e034be155f6dd242bde508538be5c48a868435354cb185016a39195873dbfb929741b58253ef99d9f0e21f9808b704d2669a5692d78319d846c449612b3b549e2dc4803510ec3f9f587231b12b27a7dc7d93957d1a31c5b74eb120dadddfc6ce99bb7b969a31abc46bd14f79d320482a28280d80fd8048d956f62c1768b46880382da01ca817c19ea065c3fa0a81762cd097d4aafb4933eb9f8f40af98cb2a8b47721d404df4bc6826e5d60b59b3c04f9f79a2f5630fa58192ae9190524683f0181ea62c5c427669b6253dc004932dd6151e541ce9bb75b6f4bf627d38698bb54f8a97d7c2ea0ec3c50da44d20b3cd69faaaea837be624359444c451b2e7bd0314080b5e46d9ed2715b21beb5261cf30c4fc7e190cd0c2a278467c7b9075f5e5eecc89f5d856c33880869a6ac0b6e886fc593deae8cdaea27231c18be495d9a68bc94fc555bf2351bc83a55465364157b0febab684697a4ad6486870ce3fc4fd124bdc5e296ca5159434dbe9c4a8712ccbfbea00fef7d6a7a5d19c75c85700255a5f825743ff7b0cee3318f49508a00793cd283e7c4d32292af7197ea9a68df9480e73639fddcc73028572f6066ab19f09b8eb6714d1a90d3b1758c621a8676779bfc9524b3550d6300a31b712aa499abadc1d80d307310dc98380eacfff411186f2cc720f8cdccbe549d66f6e8a5e91d6f4e2db651ce23110e0329ff535c1d966238482c08e572b25a87a0eea4d057e55cf242c271194edede702987989b0737e48e361d486c9778bab3576995a3e0860315e4e7c076838e832bc3cc8345cff604cf0ffcb35549cfe1ca58353f6d831325680222aa75ef5a355fdd7e5de497b3dd4c50159822ca1c1b2f06", "5363ac00", 0, 1424092484, "63b3814cefd137f46e4b8abf6c24b2d3abb5a84dbc3271b440322b0333c9ba09"], - ["48ca084802a658d2daccf3d6caee4d633701d55081437e6fb709006651a5e655290275baad0100000008636a51ab536a63533099690a6cde0504b4869ee2776d8f2852ecd0ccd7ec6c05e30ee27368b9675db019cc1e02000000046a6a6500447b7eaa03f9ae0f02000000000652acac6aac510fcade010000000007ab6a6500ac53632f09800100000000086aab6a6a6a65acabbe3edc0f012bdf18010000000000000000000000005ff5e0ea6d60c5954131c208f5843422f572a9b0703de46085deac6a4b46c6b39998ac205341fb132623cb235ecd65d1a6410892dd344885b887730c23f7fd22d91f4f132664695e46b3dc2d572bd46964d5c1b1521b391f35fc51ecbba7bef500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000420aa526dc1d06fa221fe7b0c620cddc61f7d47d5e6e8378fbcd021d97c405d81ba11b92951c69289a301f8f133d3cd476c98407d9a2c989963c6b3d1446dd38af6c0ab43ee1dd1e190f4f379c528bea0aa9a90c1c632899cb58e9c0bf3069a695bf06c0704448229b90b05c52de4d33038fd7446fe992efd7c1677d202878b903291ecbec745c5a0b7f786d9ed41bc54e073bab6ab3e712bc752df89c6c1921550302e8d1d85ee2f7b9513e4f83313d933add4c49ea49d9d3ced946b91340a849a60b1e972b6ba2eebbd7cea5ef7dead72c2b52e19eed469b5a47176d5d3c757c5e900de34b979d323d19c96949f91a2eccc60e43debd106d4f6b2f21248fd40752b9022b715002aa340c22feab4404aef2e10cf70f0bb9456c27aa17cf25dc0b57c984021a3c27a747c0ddd3f6c7a941b38ecce529afd3f34708821e70e90151bd253b51030efc9abaec7c27deab60d7ced4968e1d6226753c7d181e71f9aa330fe434f51b022626647eb3c7c47bebeaae12f6c5978830802081ee85206d92ec88112d362ecb020ba6ce43a175e7ee6a550cf3962da5d608d93abd860fc86df663efc83d46f126dd1b7e51ea3e7feed6b5509eb28dd2662209548f1ae85112bb634fdd0e0e7cf5c59abcad46c71153b331d9c07e469fff976c44e97948439479821678b796ffb47b965f6ca4e1c99802f256da71d1fbbf0f902f76b1db29db556ed2317593391e6c02466f49d9f814fb268e8f0acd01d7c9c63005fe7260682d042b23b16f884691261aa500d665cc9ce7f886067b53a394e6aecb47db718c5de535f360bd644cef2bf4a818e7d43afb3a419a79ee633969d2368f7aa3a7dacbbd4dea866e6760195dff5efc1330dc66f1c15f0167bc44268c535bb72603dba90270f130ce96dd8244beadb77ad649e23ca80826745a076116a836b3112c7e6260eda935bfca6677a7310093c3aad6f9631d9cffc9c9a94deb7db33aa00f92ffe034e2650b4e1e18db19250af4155f0fafb392903143070ac174cb72ee22e22f1064539137a8cdba81ff6307b4439f37a5e3368bda46eb666bcf0930f231bd8803036459a461e70d5b4726f720d1851baed72567d8a256b9715cfea8cf0598eb0f968cf98fd254cbbbba84f187f51b404e3b7697bb91282398541d92315950a62dd43104d3560bc8aeb13f6fc96e6ab8971bef9019c07121211c8592551b12cb2e7b63fd77181a377f0a304fd0e716094c8fdbe245b3e597358f6544db02ce0560a32a541d6f20565f2c13458241c9c95a503d13f18203bbc66224947ee608778dec0491859d3ba74099b1ef35656f23382865a12b25070251ee8b08936680894646a52b86d3702eef867ad3f5b083cfdfcbcb02c98fd58c6fc33291a957df1c9a7bdf93ad4584ee6f88c4bdfd382d59852ccf911ed2822570ce801142448d732c92156a309a448227962f63145dc6b53dceebc56a0b5d47df8908d88ad59e11015e3bfe0c0e4e1bd71ac893e22904415b55e5b427ffa09316c55077cc940c8c1f98825de8912f2e89dbd44704e2353eda79b42765bae0ae6cad8182e214710b05b089ca8e2b1629c06d1864353cc6d5923bb54e798d7959175d011eb083f28e94298d02df3765fa2940e803c7e16989ad76b98c66b9a587893ec310eb9cc1180527218c90c1b10e14c4da2f462e29d24f6c55c16a8f632dab4a6049bf0f52fb5c10079be1ea825675d5af1753bb2620f336f25188fc5ee737abbc91223ce9a80cb187664b132f05d27e3b13a123c4179fb42e297fddadb0d26199bb104f2ef3887d0cd6b6c82ecd52435384de5ad5df1d920d840ff626eee8907fe0af3b94c428eee80e9d65f831a25cfedcd8d1ed4c3594e91ee4f1e55c6cbbdba6fc68b22b01ca767c26f3f873baadb7af372907b05d8fba6a0657223682b2bdf929ad58f117645c6620927a75e0b69b070ba44a3a5cc9b9a4d0fcccf497e6a43801ce48c746fefabb4fd86e68a6e8afd0ea58e376a37d3931503e7e51042028ddf81654c10b3db03af110db71381b06871cbcba75b953a24b29227337a2df0fcc11ba20854cbeb4f8889a63b471ce67e024c36d5b1e3b07a689db2f89db5b50b8d2db3782e44bca6d5b85392d7d56b1f69a64b562ee996f66c7308bf06397954f3405210412658626a370e56f2a82ab93cdc0938703dc9866649afb6a5d925b909c00e1c2512649f1f6efc39edebb4eb7692446e14ae4e170e62810fa2b5f2d5201624a13c9c12c3279a83e8dbe2acabb64fefb2d0b350b31400e383e0458f0aa9729e066678f80c5dddc938c79dbc51da937a374b528dc40e6045d2d4e20f002e0e59c924f12a9d86f0a7e5beded9fe2cde5e72dbc7cfbabfd335ea7e64535ebfcd77b0a84783088d3dedebde9fdb4ebe65eba02bc98ceb460c3bb8c06", "006a5165acac", 1, 770613875, "c21a0e5d14b6f8b8b43729fec5536be7865efc4e6c0abcd9e1c64ac134c100b8"], - ["5bcf30040182592723a0b22b11a5313dca10084003513b5fefe8431b5cc32d66be0f1ddbc40300000000ffffffff048d532d01000000000165e485b10100000000025151cf55e1040000000007006a525365acac02fe0503000000000952ac655151656a5251000000000100000000000000007c9a6b01000000004bbdf4f70c8cf49105770af47f51236d4f6e0aa56a29cda699ec21c5d8a733b97f1b4e9ae8b59ff79473f7695b937af3f7f49879705262b435f00e30f672640b813d7885d29803a766965eedf4586b94df6ddcc6bea1a5d8716ee16b1f225afa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076e6a1f2fac13ff58821130a2d8ea11ec8736736a73e907fd6b967cd703029aa21fb1d6ad81ec4623eef32db298a62c96173a7823bc881279ce0e0953f9e48354e947df105f8cf2a048fc39bd59f04130e660d61f359ac4560ec67ec74cbf9d07ddd0e9200faa05d5beb858aa9298c02ce4a053f77edac67323e9a259d2ca7ea0310dd30be4a5f0e439f765da14f746cf34f601e528d2af482571408757df60b49031c1a42025738f7edd0a8a02640fe79070212f8ef1b70950bf6776be2b8f029ef0a041e0cacc92ec7ccfc400f633cd2daaaaffd8c276452cb70514243567536cf4806f340a9d300d72d0483fd717035c17c1a6c7f8186fa4329240cc65220db51d3022d4cbc16d92683552982c84a9047231f542c447f521cb42912d4cd7a4778f8de02057ecd4211eb0948e53665d061ac24266081b130733dfc241613de03f2d4fec003302c25a125067759acb4b78b590f47f3ecf97d4f5d21af4809dbb5ebc697ed5102004ad88c6a096c57ee39fee9c60e70d8501ff2e1335ce76d6839f336de3ecf95021dcce6d640d444019aed6903dbe9cbca74c6faf8b34b90fa10d6a5657d299b55eb585dc02773e65a987608e6d43db37c6f36d6513b48a5bbed3da556fc13ec3a3cf59184153d1c1e091680634d14f36372e51101297e42ea276d4655dc55c27b21a902402fb9f4ba29821784e4ce1c48ecfb96b6902e9d32319169491f00549a343192cfc5e14896ebc452586a1b9e4ba2655159645fe1b46ebb58deee63e572b3e1615a0d018546863bfbbccec4506c2e493c7cdfa343b2f40e6230173ece0a39f1748d5457a9894ce47d38fa2a74c44b638bbde8ff2cb615d0b4b99742e41177354c9e371c00a2e4daf3db82ef8b8cf266c0a96dc8a22770396bc42a9978fe12c17ffddba74f139abce04892e8ba444f1123f57b222f77eae6635495318c038fc97ec16096932f376c3fe60e883a95c8c270051834f29f27eacae06e1c50c589529c4166616350df063f3680c3c3abd6a631bdfa6b79d9868353579ca1b300f521ed1539a7a6709bcc36d28ef1b6268cce85f394bacdbad157ead6155ed79239c43a456aa6274b1cb07626a7a44183c62de03f500f5eaee45c5259af8bb2e15f8854eff6310f835c9e7efabcf1ea98496fa0d4a9f46aa5911c92785bde40a525fe8a884dc875f7738959de5f70d5e5ff6531552f9f3cdc94303f4c1659b361ac65bb1e4f9d65d7166c3e407fe587fe3da4110307bc2c77d37e7d438a4f560738280f8b23aebb4fbd624c04dc8f7a3c82830ab788085734ec0c233fa2a5f4f4b187d906a2ad00c2eff498fc5cf1aa4841b9f528fa40add0544cc11dcbca70e746ab7166974f49ba8f1388219591efdd13afc55a9d16d3e6216985d903a47fc97e1b92738d090ec7e0eceb419d4897b88c2054eeffc1da2971f7013fdf6a0bba6ddf0f8fedbe017030769769a08426dc6ae7abd749be15b4885a1d92372544989b7f272df25fbad7dd1cd5ea4d457d455bc0fb9fb8f89d6f91e065ea601cc7ebf331aa16086a2b4a3984dc1284c664b99181914efc6bcff6bc283718c6184a83c39b39d0bdec510a89aa1a5f865b5831b2b74dc2ca98b19f7b6d0d306db27fdbcbf28c2df3fea3477eeefa35e48d612266476a2383df6a68654c217de0d5892e7956176b790bd630a6f5ab3bebd2340c1ecad515bc6d3ad6d1745eea3bf90d666533abec3786d25ba7983b7d8f2d474cf723f18a1a25eb8a4c02a52168f3fbaa076466424db70c96e7628e8ff29022eebb20abadac90058547b447c6a4e8a33d65825b32090e082987b0dcd5c16177c9e2c763961849646787329fffdd3243577607053e5a3e0dc7b6cb9161ba0c5da57c695a833e40e897123b31ac0d8325bd4bdf3d96d2cb4380df757a9a6fa25a75795d2809c7b80004947295fb7dbd72b0a72400a196c88b52b8823f90a44b2415f1564d57444f8be42a1c5931163fbefec13948c23805118679bc45fd63eaffb311af8b641131b23f0602c5e325e284a08eeb05d376a70f83347bed8e9075a1a2877fc79287548263f7210d54a2b1b862d05dd3a4fcd2870ec928a4ee7fb7cadeae9641c2419cb85acf25043b9fa606df1d117433b24af4c33452a0b62dd26163cad735bca59c08ac6657489fa2bce5d7bcf0198d92a9bf89ce0ad3070310862c4ea8897f338b64e64af5a395adddcdf8e0623e614eeb15a598eb900fbd0c2f9cb20119c9a00ce202ad1078da1140b7d748db41fe9d81f19a5cadc33a6e94c4b01906320c5ff4ae9127f1c3c4fa8f25f09d0dc984ccb799b5116c5c1c595bf5bb4f6a903dc11f294c84f17820b864401a6feea7d270624f3be56f99b09c13bdc954d73e3c31d3bb9aa34ede85e39e194c200316536a77a73be8dac6de57f545bcce07", "00526a53", 0, -482347469, "669ca79029e7deac8f95a9be4f6215f24bd6c2f7cf8a33ac79ce6c3ec17c4a97"], - ["0bd041e00167489f05eab1b162744dd9cbadd3aebb69edeeb681d2424545eff65570c7c93e0100000003006552ffffffff032dd6ed05000000000665ac510053655d39f201000000000652ac00516a528ce57e00000000000365ac63d6218d9c", "52", 0, -1066246780, "ce44ec3d4d348e14b590089dc3b59a5218eb38f41d2e62c01eea8efacc04d2ff"], - ["aea8936604d099dd3f1ff1487d483f3f067a6772b9bfb5bf2b8a2cf3eb2b239c7136a879f40300000003ac5252ffffffff78e901714f5170212a63e9f0f7efb1798de27e54ed969f45db50e908396a1fa10000000007535363abac5163ffffffff109afe24d72fb93755b348c4f77f54fcae10a07c7091cd36fe6d612cbb3b6c2000000000096aac6351636aab006affffffff5075e32429529c3c55d270db54b8b163888dd8e85ff1b8fc2be72509cb0a93f700000000085252520052530053ffffffff0150e4bd0400000000046363acac0000000000", "6aac656365", 2, -1387400805, "91813e2c848414544928217c8be73e27c0d42d6192798c3e0d2a5e1b7968a63a"], - ["19f2bbef03f2ab5c7e28422803875cbab9ee655507c2ad8b7d4cd8b280ac3514283580529802000000025363ffffffffe027a011de891b5aeac344c9e68b6f71a9bd88fc909d4287ead5a3b0648c1a6e01000000056aac635363ffffffff58023fff53d0ec6f7ea899729e1dd2b62c63fe4bac3d6c9b412c6bde950dd09c02000000086551acac536a5163ffffffff02f4acab050000000003525263c4bbb30300000000026aab5cb815ef", "65ac", 1, 1526047431, "048d68308af49c268368b46dd7ad4d2d6c0311ff1c107f5f0ffdb3ab9c5d35cf"], - ["8b4322f901c4f6f29753820f490c636321d29d049987a2412b1786e1dd0dbb9aa78a4cd2ab01000000016a2739a0a101085cab000000000003ac5165bf020baa", "6a536300", 0, -1345134368, "4848e0e38f42840750c72fca1ba97dfd5e301f0f9f04f653f66f1f9e9b7d9a24"], - ["7264c4a701194604c8a93d624e5953c74360fffc603e9aadd8fdfdd3ab75b6079238242e4c00000000095152656a6a00536a00ffffffff03f3877302000000000069a67b04000000000200acdefb85050000000001ac4cfb3d2b", "", 0, -199685283, "e8161ba858734ce7394e9afd05549c90d2e59cb08cf145bc801082e9995fa399"], - ["8911ed3101d5e27ffcc62f3db72763f4ea54a93fed1585d849a678748728e91b746b30a95a010000000253537d3147a1042ddeaf050000000001513df9cb040000000000d8f74603000000000865ac0051ac5300ab4af6760400000000026a510000000000", "65656500630051", 0, -1133301726, "3a5f1c2ed723960f2fcd13eabe5e7392b606e173cee1efef14148cd4acecd53f"], - ["3810b839011792b445c3935ce7bb67bd5a1c28a3b790e37e65145d4bbedf43f61fa7d71560030000000151ffffffff01b8baa603000000000200000000000000", "526553", 0, 668764128, "ab1caa94a84dc308ba8d0faa648a076124ec43e220cac3d3c23c6c177958ee70"], - ["0c9f11fc01557aa1e2e99a288a48549a3035155ff8496a20e045f931080a0c3d0f47bb366002000000016affffffff04b4803e0000000000046a53536a5a066f010000000009530065515263ab53ac1e0906050000000003656a65c6767a0300000000066363acab6a5100000000", "63636a", 0, -2134010377, "200ddaace44f4fdc9a32e0634a705bea0257b163b4a05016daedbc5fb17e2bf8"], - ["fccf5ba403627d953e3e4be7df40e0499f745b49875cecb555e259d4c0322e00f179e9101f0300000004ac0065ac93d53ecacf000bc9f4d7e19f867132eb0c58116666d188f4e7d1e6612dc2a196e681d5910100000007535163ab52006a3112e9ba343a1125f9ba567b194cca4bdce1affd47f338864cef7835a03159a5a8d69a8900000000096a00006a5163516a53ffffffff033412bd01000000000765ac65ab51656324ff7f0200000000096352536300ac53ac00cf176003000000000951acab5251536a65ab88c29831", "526a53", 2, -652258674, "8e78eb139f648a5df15c0fa08bf8ac0dcb43a2332df16bef796a631a44edae8f"], - ["771f435301ce5675eada8e629334a608eec0ef48f5fc92715627ebac3cc5840f398ad6baf70100000000ffffffff02e34fc7000000000003abac5113b1f40300000000090052ab6aac6a5152650000000002845cd105000000000000000000000000aaa975961c5addb05d28d7bbd6e615ce542698066c79f901ee2b994649bf3c7cd75e8ad34a166d254f4acbac26284cd18e673ece9f7a38ac00cc04a091307e84d00b96df1b8068dc1b85661af7bd3156aa197032a973ff7ce823823be564140200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726ab0d869a52761c97b6bc646e3523b112331f1cf8575e9a254b958a741a7284fd2edf154311f382d1b6903bf475b1fbb46def192eec4c7674b433b757bb0e6a19aa2a89ff65ddbe748ab77636040a4eb776640a2b967efaf0f450d48c97b2c253d961d7e673a3ca0edde5b9a22be36d8de9c886cb863bb7009dc1940606740022061511c0c217e1e20f138db61bc3fae18e199a9c572f1425a488314215f01b0030ca7096f8a4a1d099e695f370693a56064ce5b02d7c319f73261d1c927c6ef760b08df6fb362d72c104cd1c83562025ed04b3e749e85be343d218bf74ddba6924102bb50bef83d94234165a61062dc62727dd2050662acaca61f75012d1721a3a9022d3be4daeda2802f0c002448aaeb77ea66da724bab52e30aeb8d5df0f01967c90316629f84097d2e17b8669a9643b895d7fd1d0224b77c6399efd58e7bd4f27aca03239e6d94238a9506a8e80c31c17155cff12509fdbc6e8b9c9ae83f2c7a192db603122557d246ecc7088ac670a1cb8baa25735c7bb897e40e894dc8c54fa5f1ece2022516bc362090a7f133af6848390ae16eba8efaf459798fd19538d563c69425ad3d9e817e792ecdffebf51edce9cd798a14545b2c5f873db9e00394c32117fbf021f5820e5330053ae0e64b2ded393b28fe37838c6dd8391852535f7a2381cd0d336ce0e4f4ddc20e8534fdcbe68ca217cf778e868a93b73f0e76747ef32f85383f8371b46498c96195b178767e1b0150a6bb0d12faa7a7eef4450a12194eb241a6d2831569c03b5239cb45ff2ac9ddbd1355b34223f532f68e08bdb9e0a20bec4281a5767190afe9a99d383c067b09bbbc304047544bca59a000db302c0168cf8a132ebdc2be5cb19327cf03950937e1d8018d7d8197298c28d1e0dac3c51fe1b8312ada6e8e061b7c9b982cfb56831a8697215cb5fad60043e61f8e70f108e26f7ddd98a5b774722d5cb1e44f5eae61dbd2e0e7f7adb1410fd571e0acd5ae2845ab32329aad001d70e347c7e9e0b7d35ed69d68218f2238f7118180da1dd084a174eea1c79ae952c444df23afba5fd5b80736495478dec34d8bc1528c7c9b72c832e15087c3af21c966c462aaec3cac6f7d032354f2703b9a81955645ec07ac59911c06598fc50000da343fe13a3274c47efc898884e965b92f1b79852ac44326dc80c87b46a88b36db5babb4f2c70f9e623245c2f17f0a318f271b9c1e85200234de30d310bfb24962a420a9bc712efeadf429f1d87a2bae4ab09f3df0e728ba5666c6bccfbf999a92a31c290141b094fa6a5fce50786e93a1116dba4e3777116e0b03826153e7797121cd6aa1329b22e1a0b6a1ec1a5e975aee97132090bb337bb40b53ecef63a6719147815c0cc09cb2f3a976e257617fc86f00829ea270b8800ddcb7db97e6b03958e34f5b460b0ac75be7c120779301fcca94a358b94f9dd28cf42ce00083d6c4295ef25fa537cde8b4fc66b48dfd89fdd20d21c065b28ef074ce13bd15db8cc82aef07e71cf0236e7e4e97a0ae9f0d2115a523c5c704b30e2e18b2185dda5a9837423fab18d75dff2d53c4c9ba63fad61b908eef1d1cefffe162117ea5e015b3409ac5a9ff25508932068c451bb66a2e62957dd399e5dcd128ec3ee815cce203cfdb031944c1180cd89ec2ba475129312d83c8c6d4d71059fd55248fd78e15be85900a1dad0d98a7f02ee38dd6f23475de6792785d190cfb9a59ffae6e4556b3a3dc69a34ae004f74150a9d1e209a614a7299ef3a7d4c1750277ce366dc934c4b921adaabd894137d7d26ad1f83711af0fc454d3f469d2aac999206e7d13bb76a6ed63e3677359bbcd78c92ad24d165be0a74ec71450423614f26499ffbcd410db308182b3f96e6c44b60fba26e18ce938ddbdaab31f724e03db1ae764fecd5fd9f1302c36404007bda1c4a9b363438e1d117a0272916d9529203659e15fb22997223c5ae4e774ceaa5b2b92db7d110a32c68fac88cad74753926a6035077a71b09fee9758f7de000f9836180307ab66907f72ef233e3345dc8ace97b549597b7ebac09f947f8cde34502591500438d1e60588d977b0712f11fb5c8db15ce6c3def67f8b4c264db08c717291ba3d867d08e7ee6ec40559436383e20ac833ac0c60741bd0a6fb95204db7d3200cbb655e96f865c8b6018c7d9fb3cb5f15d2a2137857a0ef3f57b9138c6d0c9e8ac8173d6f73e430841d6223424929ff787f0e1ab5080dd8a88a36aaaba5d81433b27c2a3881a7984e52ddb85bc4f6ba5a7e96c4be3531818745dac200000000000000000db03f03000000006df559d336634c0ae7e27324b9090778d28a4a5e5489230c7564be2a9d4a2ffda8c12f64e3228e79d718b7d98fcf986488b1591509f315c10aeed0a0be502ef5afb54f83b9cbcc5390874b3c3714e147750651fc04f26cb09642b33015d4ac9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4ee940a9ee50535115bb897c99a3666cc69788c600241f6637058161828d4b56a6f405d865371b5c01e81a8bfa87ba5384eef19b1264db79e6553959c4fec0140d1da4eb7b5d219915b45e0f439eac709254dc84de63bcb02c51fe6a20fd6212ba1f855297cdbcfaeaf7e2c4dd3dfdaf01cd108e212e659bec27a825f1479a4020cb21693184a0e7aca448f39f4cab95895eced0f2669a23f14cd3fb2f4bb12bc032335a9d44c49603d5881b743d5db7a1a313b078f6b97ce79293c650a3576ea720a2e032430c877d466dee9880e746d0a6d85d304d0f679f6fc2b64731a22363a0f147e4dd875182334c606745fc33b707ae51dd6c1dbea239d381454defd82a6b50200b6565bc09357bfeed21fc898177d6e2bc1327499a6514acd575017e68366320314cfd3809cf7a8274beb0a266a1c249681d4cf9510af16d38d68178b7ec2bcbe0200e3376c2d1072988afba98804728464d5d63ea80ae04c8ac8f55271a6c03d12020508746abab563c637cdedfc92531e86794e5406bc85dd4a41bfa816543a78fd02054a1156591f3bcf85e140e8989aea58377b8958026a6fad0109c920a97e49933069338f3a090bbd8ac590a32ad4aaf74c8c6eac965f5dc266eb82bfae6fc4f073296dc07f82363103508a14902bd6777e8c6ba22d74862ec92b654796c7ef33214c427a9cf63cbb5880f3edcf21fc68b00e791e2187ba9cf5b02035ff0414bdadf0aa8dd37c53aa46af4e2a1d78178040c82163663b3a391e983198cdf04dbc79b48e8e0f930e2e24e4b92b8280ffb9c07e215d33797d1532ecb702e7645d267bd8961afa0315ca8a62153030c9ae069a6f0181f90569bb30603334d07d87a859b7d470286db6c6a67c3b8a91932422219299d18bb23e890a2a710a77f9ea3a17e7b276097c0d3c8f836a2bef7bdfaaf9e9a99eb8e7ca2358a83731a288bd880c3c0099d4a20659de38c24f71a1bf3b1932105db4b06944032cb3a0c7b13e2ae836802768e60c12ef5f928e8430c4439793caa1a37c6716466563ab69a34efb008a38c6f1806d831bfdf41ccd7a71cfd531090afcafcea670749e6eb7b1ee339fa831e529f376fc881b0b98eabb22ae5f0c39cce81af76d97276c7fdda5bfa46c8dfda9d0142ea0ae8aafa512a0bd765fd66b83751c4caa7c485f5d8d1b735d9b1cf8274b8aa4d92fa19dae5dd6b5cda125a8eea85caea2a400cbb037bc3460b2a498abe5b69ed3b1790f62e13e3ca885deaad8c2ad088794f80a92c91a68bbd6c7bf928f15a0a51d77235cc32b1ba24232845b523c98ab395aebc2a6a6bc32f5cf3f7174b7207dd39de6a25acf0df17b409bf598ed92891a80205f822f60b41888441e4064f54511e04eb503f44d95e3c9ff512b79c0ed80ba30b3ed66a7f9b3c7f8ddff87bac386da1ef277640c89a8f421130cc5b5d547183dfd70d1ab5ea5cf6e5a0a80580cac3cfe60b3a97fb9479f4d0d1c853b676115173e9658720d54ae2b32b848225f468dc7fb8cfa009f6af46e28b48f72c7533329faac41940cda6230cdc9316b01098b1fca04e95dda4d94445cde83eefc0fd9e5cd7f3e0c6e07bb9aad89ddf898f233d08db81c7c810966930bfb550c13c5293127a1089d8c7737d03848b613118632ab80083757124d17b3120b8ec62c9b3a1fc4cf4661d29f6588b23c14cf6ff657bfa5bd28ef1d044bcf8f9ce94fec39d78009dcad20eafa4c351c90054459a47e3e7a9f5baabd255be541c543d91b9da4af1dcfac6de50a4ef14df968be33c9b5cbccada349f6134ed55bf0214c4391922d9b66042388cd20220072fc14929a01c710498d4de3f2978a31e36a525e6619aefbbfadfdcbaedb4a2e5c14491d824775cbc271289fce3c077fb8e99edda01137908abcd3cc5c7ae266c30f2185e10eb6dcd22a32c24af9525c29e2853275792854b85a619747e26decd7357ec0b8fa60b784b86c98f2ee0f3671537377d317981ac6b6d616b548198c9c878f850e971524997329334331f9620399b82b3f0c9518871e46220358db89f8c34461bf8aecb91ac2469cb235914d9855e1d292afe0c84ceecc2ceecd856bf619de7d07bd2d2c73876ed1e6e99745b083d90031c8bc903c95419c9b5744a66638f6c380a3fb7a14efa32e12839f57b89a95391d40c6e771edb09c4833af71b24eb2a32f053fa9fe0155bae9e936da618860cf87856e71acbc288b0f612ceb6705e6e5778e693ca3d60a7842c8a30d32b94c0d7bf0deb960212f8b59a300d32c757b1793a5fed3aab5f6a539127a80732073040980c342e6c7e48acb547ed4b6770a65cc5866ce87650b7d9d61d4da38a3f8cfb0702102b4f381a33a74b779b22dd8b502236da884db9d3a756c7e0c8d90344052abe8be2372135c58a80b39cb3552d965443bde72581dde1900", "", 0, 1724503880, "783455de6f1275b80efe33de701f5d86f4f89566950ecef66a1605d432b4f2da"], - ["fe113440034ae3fa311582ed6be7f87bb39242dff04a979f519b65c36bff4fb6d714f2477f030000000453536a5166c82cc766bd97d10dd3d06232dde7025d9ed287d33749c35df825ad4c22a3e530623822010000000463ab656a6c3891435309bac9ff30a67d51b0b56ca3f8a8d1e805d9f28c65330a6b25e9ed852bee5102000000045200ababffffffff01dab4cc0500000000066a5263536a5143295e300188bfa202000000000000000000000000aa5b78f9267032fef731a7e1e53697dc21cc76c79cf3bcfafcdcc7ee08a3ec46e08c126d16108ec7ea66dab632ef2934140bbbf6efde1e21d85ff16c02d48b55c32bbc5c1666495cce591e2b12e7cc9e5ead7f258c33d51266f02955b3526a7a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d8f8c75db22c80fcbdfb1980a306d8cad450730ee4872df7b6431ae2ed6f277836f942c62757f2611a09ff0ca24d4d0f51110012e0179ba333be89733ec8244403ff69e85b870595a7236aca26245e6330f57be18f77ee35ee99e80bb7ab760d4761d22666642133e354dfc12658e5b9a25f3dfa704bf182da181e3c0b0d278030c27833eabc79b7b6bc26cfbefbc683837420f1f00dd52a7743b16098cc7fe9e03139110a492344071e9ebeaabd693ba8e91d05066f411980f2c01117185841b060a25588760c3b8e17295a68097b42a405a4307975b81d503510daae674b41ba5f82d7fc9f898ec263a40e2084664c97e8e293d0f00a696da6758b31bbd8fb482390324921cc3b44925dd5a04699191e147a53aed1b1c9f11170b37839be33212b376031f2423511819424872264a754a1cb3c9b7bc05fd4de535e82bcb1b71f8043f3c0325df5693085906ce2db08917a8870f98d85ac7969e4c70c98f022cb7f67ba38c02011a1a0ddbdfa02b9cdc944ae5566b934393632a4d564e12db424e20f30b1fe80206718d590d2cbce6c6874e517c31adcca0191130b559042125337ab61c3b2f382fde4eb216eb5c1fa1a6c79afb71a5cd848c30c648b5b5dcfa152b96f9eb1d374da5acaa779ac7fa9aae21c8b70ddd3ca81c46031579e8658778ee01a1eabcbc9bc05343c11105abb63366a7a708fa3ed6178243a2bbcd832c0d0594b4e6e97938346b2b50cf78b186d5252f96e8ec7228034bc2e639167073db4759aa9a1a1db01af2acfcb406a14c8be383debdc3d23aa21b4fc34a9fda7e6d59001f96a170f0d72764787a07875fb10357813b281a36227b81b4b4e0d5b260a810293880885e4d114f9433ccef73e9a8dec6316dc104188f8074b0c06c7021f15406cb4e41d937a6c278e86cf32dbb3a269deb4cae077b656720887eee95bb800eae6538abbfc3590d3a46f39d8b15501fcde6c1052816d77e19bf77cc8a71426e39e390fbf0d485e5412c5ec52c429ee6552d9051e076f1861b7b1214f03b59097a628b281e22e676e3c6ef513fb26747f7ed3e860a33b1c891f961fc3b36ea2f7726a9b5c44ab7e54dd655e8f6db27c2f39b7ea3dbe4b4d05473c77f2d1eef301b711995f06ad96b46f6613118893196e0068ae2bdd0a9d7851389ebef79c8e5e5d4d3fc35df8a46ea2a0f673ee458967a7f84933cf5d8047d9fcfd323bda4a43400014b369f67755078f19268107bbcaa51815ba0de53904e0cdcd2706cfc47c6b2e97e0d44f3d7b5c0499a160c8874b5ab34cd5fa025a55b8d44ccd8ab3e93d79b13012c8407aa1e9f0ce18455038019f59b4ef461279faba97b6dca8663cf963912779cb3f8d45d94291f159381b23608e0be160249b08711ad9b324fb2dc00e8df4a940a83a68d16919d2b1db7366b7081c73de093299f7a2aebc61ddc6e1c894a85f8f1af6828bae29e03dd7bb863221dfc8a86974297ad09f1aa0a35d3efaa05be313399a4e2dc8b66b531b19a53d4417300c89772fa9ce771844eab9a4ad0661ea139fcd2134e04f34ca3e76a26c2522e49fe20100e41350c7d61120a510d62002f138b461dd306ac095902f15933e8456a942e0f52abfb129b3fe3110d6ab18167c6b0905fa70ff783b5af158d0f48596b4abc2d52d4e991ab675eb642086e16c036eca4d11cb4dcc38e9d226ed13022d650c9b108dc351c925fa617dde190fc6d47f5a65c1aa020c7e8067c30e226ca0989f10a8524f752038dd60cb9f892b686f2330b3eafa7c9bdc2975872a1e7690dc14920fba105f1250dcda142c6d830dc9f6e91f9387c4fad8e123f7b54a7f6e3143b3380829e1609cb5aa8e39cae32915031e734a433d62c2c553ad8aa6b4385d015273fd605a46d819cd5842093e24b0fa19e2e7a4f4b28ea26b903bc1f10376a456cfbd5de1ebe77e7aa36d9ded9cf1c519fd3df784efc932691ba90e21740f29dfb6996bb7f18517e4f9e1855fbba86ab0bb63b0daafe68da169aec9dd0682c73acd3cc2b588f066c02bfe315144bf35f5d82c3a0769ac7eb825661d82af86465b21625c555faf87ecca4ae8ca54a5820cdcbc0cce3a4f6bd926d304de7587035fc33ded4c74aff3627601ce8af906dd19f156b4db0a9e94e3da7627abc93682bfb26fa84ff71de8d823fedbd0f5a75d1873bfe9cb538f5ad25869752d59ff5461d387f853f238083c225bf38298e6fe976b5eb40acd2c9915febe1a6a63cd3a237ddedefb1a921afa2b99b1297193505c7f01aa0e562d62d39ebff06312b5e4b0ac8f59e92188be68ef9db231c64b5e0269033c745f50febdfa7fcebcf0281d0ffd0fd4f80d999087f06b5edea1db723f3a159fa718d76d3c25fbf39d9691fd9d84a6f898026a9154e3fecb47adad78422a32d53623e29017f892557bb0e0c", "65516363516a5163", 2, -369229188, "46afa7e6cb02ed49a692b9ebebf83155b4129b1589d060853ed64fa0814d188a"], - ["b3e31548030a0bf16ca9e07cd91ca0c4320090d33b8b953f082e3b39657148c01b2b081d450000000007650000acac53ab8096a6797092af7ddb4267af210692036a85a4be737acf23191587ea45c0e8a8c18d03330100000004656a526311bfce0a3aa26732facb0deaf80d1aa5051ebd49972a605cde43786ab6b054b0d34be8440300000009ab53656a53acab6a51ffffffff02147bd8010000000009635353ab5152acac00bc1173040000000005525352636a000000000200000000000000009df9950300000000e5bbcecc49ae91f1dfc22c5e35a6be0317d54df960541a204c7c34acd3325a73db44d7f69354fb52a89a7bc810a4ed90c4434472671cdf103df6d72f700bbe0585857cae503f3954cecc23a217be3ac58da2e7408e6e8f5f4130e7b8ab4bf908000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a702998580d9f5b52f9bba777b15d65f8bc998cf89b8558aa4d3c5056d9a2eb844e9bc396848f47f042e44d1563931569f73988f1b7b5913a501de63399b30e7670e0e5362328a44a31bd859f64135d8712794c2d73d9b1ba345090350908c00438046605e1015f0781adada445644381f7c5c439bc7cfffce8fcea68a5ebe40214212ad33e8e2b11a53f5ce0b425786a775236991280279f9ce15ff85ff516320220ca5911eec0971d3d3188dfce2287e1b7505122d7c8e7c345da5763875e466f0b25f34c727a93423bae623640bd7625415d15691a133fbedb2e7eff576e0a970b10891114126804bbbe820bb5550e2e9abc9e8bf7e28513fe7c19cec97a0989c4032db4ac6e8884422bfc36fddcd049dee2041e8af4c7d63137c4843f844f870e36020ed5065d58b5d221b862c135f2bc2d1e5ccd55698a27ac85061f403d041d70ec02130f3f2f834e3a683c6542f7dab42d375a99f0efb97b629c8e82a8e30e25c9a70224b12dbcd876e87eb9577f81acaee6a13b869814ee529e50ae934881513181360318b587ac18a99bc3fa7bf80df09b4a8dece3cf7528b2ab78f1e523c642ceffb8f95f70f2050716d5d1630d5af1aeb6e5eda4204fb25fa23be2fd638f1c23a475b0804a2ff9cfd57eace427bc2eae298d288f23245581cf8be2af02d877d66106120f18355ea15ca41685d07bbab05208248af983b85a30be407f4f38bc13b47903bd6e3970c135d54831d0ae5ca33a3cc9f1ba00468bb5918421e31077e686908534faf1f6310b64ecd3d5da0cc4c8362c76445a64acccb12fb1111f6e61deb712f40267cf3721b40e9ba39f29fd0a766b33198737919b65f89d8fda25a3c9f8d220133acd83a966b4be74bb00b34f6acf54fca5a4b8c526292c302b7b9131e2836a47e74d9511706e4df4c06fff5aeaa48681412d471c2c151f15319c40adb6cd008ace66c6cf8b9c17d41aaa05c1e9b0ed4052023259aaf66a42b24314f9ae1874c33ba41b6015461dda999f59398e1e2ec935ffe2a46bc63e25f9f2ee972f30edcf708379b15cc6dc4d30a8a19bf8794b7b82ee1b76f7cfcf44db84736834aa28e14cd545f3bebb8ef533f69deb34bf047e86a8c2a133cd38d257b1b81c3bb77194fc8fa62af5c2c018c5fcbedfe74d50a1e682834a3fbc920583eedd7a6725be557c9e9fd2cd1da9c29f487dd2ca52fcf51e09b9110cd6bd1183f3b086a5d17486de07e96f044c1e042a93412b9822005592cececb00a4261d4e254b8e378ee7b41d06215d0dfeb8dd64357cb0b29ca47d09b8676a05823832a3741c5907f1530bc70e7c09e00cf8398af82a11c3bc085d50b29d69458df2c69dcbd1afc7c3cd79855e1c021f57a4b7d1e77ea36f99c1d4892c6b732d9ab22ba7287cd93bdb73edc12c98f0b1b3ccceb45c361d158e1c4c6cfb0357db7e00864359f04f5d202637402a4a590b5ec881f9da2bd2853dae4214598fdc78a9399cc9b44772aab261eaa7585c278dde91384ca853e9bf75199cf24f4e436700e0c4a95a178c1990b9fe0e523c919f310083736dd6acc29ff92b73866d303ec4ab624a1fd06c0c9c1bc8db226fe586d13b8f66107c74b95f0da4a699d6e550101ab622ec8aaa6cd89c5daa69ebfe969c500c2f98c41901f699c5c0936d0acddcb8d39695e15f63f207d17c4acb7f1667a124817ea41b4f5b70048e78c2b158dbfafc8342e2de3a1be2bdbe37e6514312061544abec2d0c2896ce81ef8bf9075dd19d8d7a752b8e581948659d64088fccb92a2009b50fd0183bcbc0182f4f6dfcab4e041e93962f6de17125e7af4da1ca55f98a504996a711fc9027a792113e9deb07c726114dc2b475bef8b0222ae91c4d39125cb9f26697bcc9f3336accac371ac0f50afde8e259d62a430c1473a537f28b248da68c88a5dc55c946c5f3a45c60127f6e3706c784e5a40cd523cb5cc9c034059e069243a5b6598112281f481a2453aa760aad5ab78b0914493de15eb96f4911f39b295bcf3cc198ea9fda52e36727dbf780aad8b3341efa0d0e8fa7d3df3692873dab1641e5bf37105976607180bfdcc016786b74c8d2f5c0696f1f68c10573b0bcfeb01188d5494b0eada33cb40ef59587c14fab6eb4b2c458442b9cb242f7048cf6ed02e172fdff14b9ae9f08210a27d9fe42729c4238d4d555ad6ef5b2724042a5b7b79a22dc1fdcad4d096d9139a7a98b7e75e8ba88c4790243b307c3eb04f1af332ffbc395a2da6e13873e8bee4104b3bc2b41ab4f8af473f6628f22a4192967ac7ab3ba01a105000000000000000000000000a6f9a8675451aa445b35ad6278134857494503cafff9126cce1d7b2b18887b1aae336f6f5826842370908b91941484e9472f6af1d1fcb4dade6a0a784774cdbc7985a3e14a3772a5a867f9bb8953ebed942e8be6e6d2a01da429dc511e1b9aab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0729b72acfc2546f3c6764ab5eb09749c4da233feb491c7ad2fae83f0f2ac9ba818c7d53dd77a77c3a9446cbfe268a9fd0f6bbf6e3d728b0b7b96908adcf4fa798d777b472a63e6dad861044473dd045e2fdb98861fb70cce0800751a00077c17f6e8a58c95a8772f8338c6825e75fc11c67d325824e136d470f802fe31d1a403157810aefe12c7775ca65d5fc1ae6587bf94f69c1db5c01ec1d54f6460da8b91032168eee50f594bca1eee5f603c4764fcd3d823b7b074a5c965b4136fc72d55b80b2874bac85517246abdf767a5d29814bea92b070194ab9a2b3844ef57f5c265a81acd56ed1ef2504ab212407eb8b99677725285e772d0f340e8f057bbb4d10f4b021829be6eb8447eda4caf56da5e88786ea0114ef628ed4a985241c71e529e1e32022ccc9ba437ab84b545144fe56b804a37d8da16d66d8515cef4de4238113ca6a103052af0df8a117930c218cb5e002b3f3ead0323c1c548e17531edaeae95df9e71030eb7cb869fe88a89ec4c598a8fc133ed7f62d419a745f2eb074ddc604cdefb820215a019bee0e44560b458fb2d29142c92e95b2e0c423daf0afd7b10bba767fdc5e5113842844fd43e1d8d98bcbb7d8a2fe969fe38e5cf92008c166f495be8adcb07807dce6b2fd23111f7a78410ce7c2fb606d2e4ad4cd41c8f3192532b36bee1218ea6f877449aa0ef75ea0fa0388ccda594992cca6cc54009f88179886e4eec6da3700b592a3c3f7bd6ccd76aa6a336aa5fb3a3847193b53f63db4e0aa37e36bd4afbdd3553f61c29f489bcc3153d1c9d6d8d50e695b514ffef1d5b3b79ecde2840fd87ec314de1b92f118bdfd81e29c94327f1f977d17420eb482b8cc99818e388e1d3977931b6f9d287017177846643e19f657028ab07c78f487ea08dd1e31645522877092b2d689492a05654458aabb132587e9ff23b6c72b486c01673dc983d9ef1aa7404561bd1ef1fe55054891c558e58232721063b8e17623c00ed3421539e125e6c4fc754971d2ca6b53ce6fd798ac17ca75cdb21793e2a84a0aa60e810201f5f806a63eedfbbfd60d1f5ff1ab744d4881239e47e4e0dd6cc314d74bc36fdf383b7af7853878bf875573767f55bc28d2541e27756a8093067ce54ccd3f4a99d939f6fa1e7efc499ce0b92f5500b19c1fb04483a1970f7671a563f9c69e0f0592ea1c017c7d826286e5a23ce23c7a43bcf764dfc5f82e48894767bd66c9ed7b146f7392f98deb82d85a8ce498db5085cf9619598e91d42f1c3fcb7e5429fcbcd39337df80a9a1377c6fd6d21a9b3fc9d6765521c1b4243e5fcf75957eb322975679d000d0c85486c61dedc01939080531b57d3a5356ea5aa28d1d8be2d404dedecae819278992095d3f16dbf6f15ed958edd4b730e9672f58c0a54d5f2193cb4fa0997e291b9eb75cef05d1034602a37a9364174ee905280b93ccde76f9c876ece1ebde32eda008c22670b9a0b6190bce43e15307ee210284d17dd7b15aedf04a0dd32b9bbff73b1dda8cf066943c41af7c5f939c5bc973e44c159344e495e4223f4bc9d288d072882410b6cc0363cfa9f888a99a969fdde6f25957d4d2fef5bb1c1d28911c031942b069ee8d6d6b99b60d84d98aa7b1e1383b4391584156cc430ad278ab164ed1168dad1e22b8ee90ffdd21cbf9dfca50829d31bae997cd3494930b0d0c6c75e23bbc95557049584f76ac23261e4c01e36d3f05fb4a208936ae2113601a5e45152acc53d77248fafb36036a2041939582c2648f510d8831d3e47d3d3e39eb76e436ea03ff365138bd71168ac26d481078113f4e1efc546b6645af30e30ebaa9e35707bd39db64ea4b6069ee43525d7c5fd4d9bf07ec1830e3aa5faeaf9b1dfbb53e8e1f7a02f182d78485d60d02a545fa0c3b69cc30904fab3443b5015a101dbe7b62f26156b2de5d886c2824701d68338561689462e7340b996e27ecfe28b5a5189d46ab5e14dfe1e818f1a6ac9c50f16f478701f0085855bf8584ecfae3cd06d950814408455067c8e3d33da0253df0755e44d48ff96308bef8b1a6d833ee52b800b2a6e2dcade795d8458249edbb211c333fd8a36179f47928b73c27cab6356cd663df570697a3f2a44d6abe8699264ea88be0aa4d555ba7482a8603c9792c5aa10c244563458f91b7e8fe1516aa50f6063a9e0d2cb53932acb436c23a4a240c28c08f6c9b496e4b45c110bffab4b9297bb4912226488f727d334741cc5f46539a220bcda8b23d286c8ee0a55789b651a59c807b504560204d9a841ca564dc9d89a6af4b0e61e5aa7f7d29779fad903be3ba8bdecb3decb95b8fb76ed9878a6dac90b0c19d92a6d1365dbef47f759468091021470319ca85089497aa184a36ed79c160b6dd390e0a72b358bca5eb9a2469c287b419d760170e690469799838c82057dd96705", "6352", 1, -1980597732, "b6cd18b9f9550859ed5d3c679b348f013b98a1595831114351e5e7198576be56"], - ["e0df7f38017cbeab32f875c3b450d79af64b96f86e92722f83f71d53133a43e077ae504e490100000002ac538979f638018caa1300000000000151fe28a4c603108f7a00000000000000000000000000866a7d513dfdfd00d91c733a9901f891f90e32261f08c040d91c06cf074db8d764dbae717911c5b04e25bf5b83b7f07ca3c8a125f0caac375a736601e381fc752ec516623a4df64e9dc18ff2898b7f23c8f2bb5a5aa254726d33c886277f05a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e1077421c5d3b2ed6bef86dbb97f6a5d2b31e23ed339949434a6c5f5087f065de138e6cd8f123b8a6de08c85d032a6132dd4ccbed152f6cb1184d4b82be3026a072682400699b17aa4677f9d472d21c204e1f4ea85438eac3089197fef7c8f7aef83aa6b75931919a1d2f168e33c388fc1015c42c54f57d145fa8b4223375143022f073ca107a36bc5aeaffee298a02b791ed929fdd144f56072a3521f481446790212d23cbb81607db005a431d3ee70063d36a7ae739330cf49316499f95f84e0fa0b0bc1bebbb0fb53872485633c58afff61d53166535ec73691d355603640cf44d01548fb99e8b76b6d69bacf580087f76518c118eb8528a54e7b3d2fd21dfd9b8603035e9fd9c96a3ebee0796fc6aa71072321efd424b6b347544a840f56bebe4564020029dec1eccbbc86418b54bb1547a59ebfa2faf5949e760d90f957f7cad16650022292a49bb31e1b32c0143242a59b1820b96757f936ab9c05b75b1369cebc14d70304d92a48c1aee00556d2f45d9f66bf367c3ce47b35cd92f50360f312640b2dff030d45441971830c7db0fbbce067d8799c9799990014ca57b734f5a5a970f15212125352a946315dcab21a68c075752bded9bf45806ad8a036272d232b4f76c1bce3e4364d68ab655c3ffebe6527c59a644a4beb0f0b59917b2417d219819f1a0b3f616c388add094ad666444db215342482b6b957d9fd8e71a8100f1086ef1cd3cf1b848e6fdc0e2294c7383e91da35271a9de4b3049a113879f0552e18254af4d4a028a715d5963393e45401b26f454a82ef5a1dc31af031d17f98eb9f6788046f483cba084bc5e057e11a57fe4645cca39ac6176acdc6c575ac029c53c29d8bb361e6ddd62095baf95104c9b885a72ee66d541f374fc6f1b10803ae84e8112c761274cc150ca18665f6faf7f29ba2f27c3a1718a572bed62eb02bea2ddb8100aa972202dfa522ce06dc60294f547bc3a84094aa718761856e22a36574c37753cbd02b40f562c879685806568245f5fbf513b36ff4458647393c8e6c2cdb2da893d602648de1a5a168a81110f6f1ef43991a2b1a39149d1c58f70ab3ccdaeab26cd304bd3e19886d913d73499e3326ed79ccefefa208e10f9cede5bab65d30b15dc58d5296895cbba5b680935bf7f6f93a1edc8b3857d8760c1fd69fd4958ce98895ff4663dff97a91b25a4f9c9758fb26eb05fd194c4858a10680bb8d04f524ebd52ae8633f4d918acbc50b0e2a2ca61d822fd5ae3e64edf01ca7ffa6940c8795188a4daadf004e2b705e28f00ec07f5efe4f3ef0cde0647717fc7282d9fa6daa463073ebf7aa9b9eb69d65fa46cc0f52d5b7b7bf27f37e87c43ca512aff13adb54583652f39b6a96b3977411dd9bd71359c7100302e7065a98cc0ba631eccfbe615073fffbe8f9fd796c86326461377616c13d221c8d7fc69dde882179381900241f4f58331d6b1edf7d54d9e82ee3bee417b0dddf6c86271dd5ef8d4ab75b2a0024d34893e26947ef5be1920172a0e5e99adbd5577aed820f3440d2adf9c09e64febf594e3699b45033ef709bbe8f8b5df1970f3955a3423ca1707dbcf4056f8409ecc6e4bf292bb897dd0ac864a542394276cae44779357e18f2492be2904ecb202b4844e3688f9c08b3adf1712f561efff1df6d5ed1c56d54c97f12b8a86c75e534ff32ed1687586b086c16580d879f9b743003940c5d84ef1108ab183b14012af9471b91fc1ee39570428e621a5ca3fc98f3bbe4593bac00cc1ca2aea169b176a7ba4d5c0222b8787908315337e41ce1dea9839aee492c5efde4d697bd5876d6fb7ff91483b835b9a0f94dad71a728f392796413898747989865b2b43ee918ba9732d25f8e9781a284c61d4cbe923092f98b9289b4f0205c4a036729d2fed25e39eeeb6b13041e2d16c51518e085c96fa056768cc39df4b64f2afcd5d0143abb0b1ecd465539162c2a3a3f6b2411b2761c7fb792b957dac845cf285a865f021b600e619bb07cc3333e1b93e403ed4a019f4a3d4884a757752ba9f130f31f34a50c7cb63ee3824af3a15c0d4eabe346dece45b85f306f3d41d6a276e8ee50347f4af493525e243f0caf1a28f9be8e63451c35233f765fefa35ff88c3eeae0c3d3ee8202c1407655362d12492b62af01386ea12a122817fa2dea699a2c0b934f3e28b444e567e42c0835cf7bf91c8e4b9c14028bd519ad19617508d520c3da2ce9f7c32d778251fbee455a48003da694ef07003b697fd64af471571b358fe53ade34f0f9b69b14fcb8a8e30b1af1b1e200000000000000001b5bce0400000000e141c905ac9e54002b8c495ef2c08213fc396b3c2f2d08e0f1803931394e8dcee19818f0f646fc6ea205cd7dd821100c89307aa0a08512ce239621f6a660e0d31aa1f34728e87d4279b8fc0020ae329986a92f6f7b1a63896d7f1e9e062f502b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad421b73a70fc37957571b9e671bdb382a77d225e5f03f04eaf1dfb445f7f8abbb47bc5a236a2b0eaa9a1b66b3bb475a019a946e6d48298f25c5180a9ed63dd70e85686aaf56a10b9f97f06f2b890557a1ff76b7cbda3922df6b9300cdb676dc06e884fc2f876c75b22bd630014eca7db7ebc09501934dfacdd6db70716ffa9f030a762acec399de33b67e5d677a98704a260cd9cb4973f01961ae4719274e45b0020e3e83b9f870dcb791ac8ccad2681e655aac524bfa8cd713db34fc49b525ea2c0b234fc735c661f29f0d46e5e87ec399f8a74d96e26c96f4c5f4bf71710eaea8d11882249d666b1a035f690eb1d72bc4f35e965fe860279727b29d1e8191e094f3030f062b048c16910cc3eeffd59fe8fffbcfcce40bf42a29d13adf932cf342f0b0022a04c3642d9e242eda204f9081a82d3010e183e399b1c09cf6c5332e0e0d1366021afa46ce8ed9dc8cb0fed99b80c09c9da6d5ce0a97b897f0ab441759a9f4b4ff031af9b13de1f73b4c59e93b1029b406d7ffd80b03c558b93f735d417d5f6d20ed030470736851fc2b257d065ed790781db6690f15f2f4c6494f1dca2d09d20354c8640fa6a6a5a6577d12597b4d422ac93671e50ff0769fc16f01a49482ebde49066390fc65f3412f7fd03fe8f9a4b63cd08c54dddaefcddd089f7463c65580e6ba5c3553c4ff9476128441544ef643370a76509adde29b91cca105f38bcd7f67251d9eee6999f7b72790d989e8ba26519de4b68df1aefeb59865b4376df0b0154a1a0ced988aa542bd236d209ed4e2cd4e23a56930137edaeb2b51ff1197c4bdaa5fbf83b818fda323f2a109e460bbe5fc6c53532f8d6671ce0c3054a02c4d9fbfe084cdea2ef3ec5ef49c687be636f2c0f59d93a30afe950e5cf416b418dce259280df7d777ed01a9a41e81156c77793c40218bec8f0e8e5cdf9523083e12c02b1bdb29747127b478e943e08c605f0e615b5e5e42f888b78e67ab8b674aebae2f366eb33069a38d6a0feccf57ab3aee11ebc0ad8cba4c3bfee0c381fcd31ee2e2e8b6c96515ac20f6359e3c2dd9c269b4324888b2d3afd5da436eb859851405fd5f99f7bbb5df5dfb736cdf029e1da54ff28746a42c90823cd146f2136faddb1c76421f9f9f3014b4a8fb8379de82694284779cbe56548f0cd70b8e30b24d4e676b4ade7731d338b2ef4550dada46ceb539358673318e213f178f6672731e3fd04a9916f1b64ac2c66947a9a89d81986359f2caa0219a9212c0bd69efe930b3a1d626a0f7c8241d1b74971df0de994a9abe20aadcaa41cdb4f89ba8c9d0f01f0be76d7b9a37f8f7ce1dbf75dc8dd1a4dff6e44c2638e04ce0a077316e72cdc7588a62fa17eed19ca2856851f467de44d5d5381798a933cd36e997bdf50ee8eb9445e12a60e94a25bb5655045f5f9f49c4d909cb5bca9b9c134421cde61b41e26ae7d78a40f4bd4253b3840dcd4a6726134293a936055299b17dd0fb5222ac15babf1b1facd7e2f2a06d1200ad5a5832c653747eec9c1e2dbd2cc010987da76167c73adaf4627b895aeec297dba41ef06acdeb7e9d9b9de9f0e0f968c8386af6e2894de71e277d1ca6058b21ed01e1ddeda759225ca17b9f861029c0c6accf911e5d0301e0df0ace792f85c17db7b2b7343ef3e7a3425a6fba6367ebc82c25ae8546faa2d166570cb8e3c0326193d426cd549332736238451eb56ccdc62670033fa79ce6f05af1cf17b2a11c6cdfd8f3fb18851d50d80b3657bbff81b0132d83b3781e67c51d75331837d124fc43d62384a37f3b2f9d6b2c773dd35d81f07d5e5a79174a5396f318816a7930a40d5383841fbaab8b66dc78fc69a31f278d0b7c4913a582c2b267a143ed095bf5b09fa918af40c071657175ccde77d43832ff6814146a635bfa68570f1235a361a02ce7d8688d22b315278d68d6a3cb83fae281c5860993ad3926e3cc54b3a33c8d04e9b3d0cdf1584d10829a6805a00840881ff0c9d744f1a41f3ce078bc3bc191b2d6904fe96ec5e8308e173f427137171ef6761c94847a6902b2c1ac58957413420ff1baab72ea513501395b10a9ee863e8efc193101b79701302ffd0afa3f9f6ea83e99a8f6fd0dd9796ea165d8ada2615c21eb6fcf90698f942947fabaa528f8c65fa26f03e9efbc9ab0e3ae050987e88d2cae8f918f1e273c687af081e702e8d680bff4a38931159a3f7ecafdc64bac38fc127b8d9740460dcc3c7d580667fb7c6e2e5a67af32604aa4de80d94560b8ca44e9c0551cf668587b6a3c5b0306fcdb5ad5c7000000000000000005345502000000000a33745f5988244a24c7ad5632bac7b47de0f6b72ae1b64c25e792aba8f53790a3ba832e831144b83f28a4f476fafc731512febb2b79f91a0f2e5f0663e2381e0f44644d0aedfed9d5e16178c48a80c0e990426ee9242f03e7a2daf28264d034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a04ef042b441b028d18dd8960809f8bbcfd09208091f95668960185c07de270e3230cc12ed3c2b931c417f7dac245ae6c6abf935f0bf13339313b7ae2fa83abebddb48616d12e675f6c75d5b0df422cb28bcf107b63ff6862e2e2d10d9caa085cb63fe61aea8c5df7200d87390ecb153a99fda070ae363e75fbc209a7846d7f020931bc9598d2ec9e59e1a6a7c44b364a7cd7f5cce4210e71df984f84f2b32228021308172436a567f09caa43c6c2b7fcf034930fe9fb1552b1797d89b0936349020a0e1b974ffc1885b9003d51c791cf96e183f4ab5cb19fcf50b1c5336aaeef748a0d4bde532946be11497b2ae1461aa5e83df58bc9a0c4f57a24dda828225bed08020e3445e71ddecb8e363ac45da8960b60f840d5128008b2cf6eba53e45f773f400326b881be94b123012cefdc654c46c88c45fe35bc72982018e1ddfcf97ef68e6d0211809c82c410e90411380a7fb8363444534f7a05fa3f0dac8965b9a203bfa76f02205a86a6e04195565ea20c2b845b843ca027f60e75166088416ff83d472a9b7c022efb355a6c848628f0501f04a5a713f7fc9eb0706bc72976044d2b48735716536b226b4d7f5fe9c33f30bf23bf481d590bad02867604d5889b8615f112d7fe43b1d54a25399cfed7dca810054aa539de50faf29e82e09222c85b6a8e7a8eb05e64c2dc0a657441a2e4f07d8be5a337afdae3327997885b8debd4b196d39903852eec0ad304e59f371add16ffbbfd75052fce34a737c617d922213247af4b4a21cb20a0ff41ac32ba251a35e7af995c7ab8f693365e837c6d3a372c2defe89403f35fef6fad86205fc0625cab3547869056ad7473966c3ba966a44557714aa3f3b43f71a3de02a5a0dee4788855ebe225c22734ea56ffb65f5643a6361df967f9deb99eeefe1afb1866a01903cc946c6a029b7868f0e1c6f7981a80584baad2410d3329e45d33992ad467e9ff0839f92d1ae58e195bf1a6e7b458df63e1c5a46cdbb42d6f5cdaba0b5c040cb1e4670007f3f54759b1760826981f728ba836b02c9b916a1ce2b89928d430567278cc34319eb722cc7d769efd803bcb0399c39e0d72ab87484ac4b5f19fe8abb319a2b62c9c13a19f8511e5f21d0611e0e0b62fe9baf2591cd212cd1313e310fc75fa2033a086fce153af31dddedcd9ac95fa6baf0b74abfaf1e5f6c86ad8af3066c6b108d0b7b4748fc624c3307fd1dd5dbb80850416a847adaefe4672a31ad45b2c95a95be2cbab6da73a8fab13ce5864ab1c6d7fcaa15d31d6a69bd115f96b91ee35b2228427b98a4317fe192b3b725f11bddc311c2ef6ff724cffc4e48c3843bfabdcbe5bbdca1d6be617743efa152a9d24b4adfc15b5bd1505bcd09dabe37985751d123ad50019cd2e3aab9e4195b3bec8f8222dd429731a641cc790e5c09f9fa236e07ffd664611848b4a232ac16f6ddcbd41d27d3d8948167f2dc8808998d417f2bdcb066f276b418937557746fd03ad4da234b6243fe074e28f9850d3e2194acf122b3504a7950a9ce3fb2aba473681478d700829c852d898e6988d965b623f9fc4240d1e3af22eb010ab44b8abe4837b6f163fbace54965cd2ee28222ba33c5d36c2815482349b419042d0340e2bd456c83d6e39b93a9c481f38d9f6f2e92589b361589868c61c103b4c7a1437e2073464d84f9c063d124ff0b30f54ce461b9eeff2801a0648b5a7abee1703581206a5ae3ce3221c528ea721c4a7865e5bf59ab9f7a2f08a6b86ca8b79e8cc1c88a24371a94eddc8866daf4fa366b933d49ee4f0dcfbe41be8f147aca41167acc5a39c6018daf8a53052a9d3c900ed5649ba0459c31e3f0ba5a2f7b81ac50c6cd5e6fbfc8ad00e0de56dd336bb6bf5c7274d26caa9ddf74fe573f65880bd4c30b9dc6e40a1b393455b7eeace5c04a1a53c0927bd111687f0017d1ee8c991da76cdf3fca4d8606b4eccfbc2643edcd3006a1e616059c67dd84748de646ed73eba8d461feaf38246a73f0c2a59da3688f069944c716600632339876de315e0c1ce43b5fe6d47f8273f5eb04235e5c1b576fc61f7e977ab6e46e00eb32725045275f0704ad28c6af718a021f17904fdc13f59edabb7d96548fe1b6498c3c84851802486a58efc8d9a4ffad7cc405a9ac041445c9790521d23ada5d1f2d4fbee0da6fc106ec2f85a90f35530e807fcd4e56b3e93f26dca684aa06453546d94b684bf92b711848934033c9375d2f0f9ada15b748d36560623d007770233c39955756da6ca3fc7da866f44b0378c27dd675634575dced2fc44579d6515bc3c1f78889cd030ab14b48c1e12558eda92ac2044791b73f63ff09ced735cc299d1d78ef5c7611d71d1da6f0f02bf80b7d051e9388128edac3c2f28f7ce4e4419954d4eafe6626fac0b51e45caaa96b8749ad73b040e93e87720b", "6a6353ac6a52", 0, 128863541, "9d17b8ee166e4f38f2cdf2072cb72f9007e4407b4b40db53e0f41f26119050e6"], - ["3f73caa1048516a51ac43cb61efccf141e36bde3bb23fbc8848140adab2640bd358d1b116c03000000016affffffffdc0a47e8a9ac0cf76629188a28fb6b7dcfddb5d44756503df1f2f1148635b734030000000653526553ab638793c4f41fc02560475ade1fa782634a4d079d7509fa1490201b21d1dda75cb0a477c6c2010000000700516352abab52943e3c09ac0291ff4368988728ca9be4ff48ce9114b98147589a76fe47797c87e97b12bc0100000000ffffffff03038e0a0000000000085163ac6aac0052001e0f98010000000009ac51516553ac5165520651af02000000000059d8b30b", "ac6aac5252656552", 1, -1821348871, "1a923e74486b7f5bc723181d16c11390409e5d36c84fe84e4d7d919f64e603a4"], - ["ca1ff5cd024970e0b3f2003beb91a5560b5196a1644a1f8bb13dcc28292508ab94825c0155000000000765636aacabab65ffffffff1baed314a092f845ecdbe04a56a5c3ed9a3663a1388a83ddfbc1e20a8d6c416b03000000036365653fdd8492048e4ee003000000000050f766040000000001636c23f5040000000002656a9efb510100000000086a636a65516a655300000000", "0053", 0, -1881944634, "7966d2390a0a13da243c900675c0b4c93d39a0c671c3330c5f6823796d34ae27"], - ["19270bd1040a5e188346cadb8937e5d10d4aa7c30ae0da6f8b00bc035ee11aee50a1f7a909000000000453ac0052ffffffffb35db0d788f76ff4b945665faf0967ce251f9683345a90e09faf42ca0436f30002000000050063ac52005e2a1d47b43525cef005fa036e98d55e8bd0749fd263b30cc6be939c338af4200b4f4dfb000000000663636353ab65ffffffff90c479fe161bd55e30cad7b42af7c801b15d8949a83b51a8f0efafdb7eedbedd010000000751515152006351ffffffff0380ec0e00000000000852536352abacabacb5fda9000000000003ac526589720c03000000000300abac2f3c567a", "", 1, 1134438924, "477d3f629590ea43cecead36d21d737d57b9d234da296f5bd889a82acca45944"], - ["58c7fe8f04327d97d0084acd3cf89599ebd57736dca88699e6e6e4fd8b546ef61dbf5721b10000000008ac006551acac535166c110d65b24b778fdfa3312f08ce106548ab8b1d5451d0e68d661de732dddde68fa136702000000095252515351635265ab91e99ceebb7619b60f875d3397029cec3e3577ee45cdadf8a2958e47f4a17a9bb01658f101000000066353526552523891e81217bf7d7f7d009e7a1ce94a01e1e303845abbe92ebbe1b1b52dc9c5b0ce82103802000000016a4a01bfbb01f2eb13050000000006535263ac6a53643d78ef", "", 3, 1083632216, "89908b0673c687a0772784bdd701b88f984d6a2f0081beeb81eea29b64cc30ad"], - ["6f9a688f0121d26a76ebd48e458cc19722468857c0e586582a6e0a00232f6af9ca221f3306020000000452acababffffffff01b1e18705000000000765ac0053516a0000000000", "ac6563ac65", 0, 1041860068, "08eaf81ac3c9d68b2bc68481def85f9f80b59ee4ef6192f39cd139b0c65eb904"], - ["07de6e8d04533e3459ddf08070252a835dd3482c8153ea5d3184c565ed7b13905bddf1c5d80200000001524efcbf826a08d12037048c547aa3f063cf41c70a66fd0f60457f9d5b8a1fd88d6b2b77430100000008abac0065ab515251ffffffff576ae9ce06fa7b8c3e0ce7833d61286f041106c37014c9ec332a796319d7ac5001000000026552ffffffff42a1498222f999dc66a2eb0c6799a4d46e9a9f8894448413f37fcc70454afc7303000000066a6a6a526a6add1eaf010394946a0200000000096553636a656351ab636c36b603000000000252ac7fa4070300000000016ae0815e84", "655353", 1, -651918271, "89dd327bf7883045a0469af74127fb0305aeffcbd3b332b72007365d2ad51ca3"], - ["c62fc9e801405fd184205bad4379cfd51be14380865f74ffc28425fc0a6d5ce5853c10aeff0300000003abac639d7658a004bf8c0d02000000000400006a536a7018040000000001657a30b2020000000005536551ac6ae75c1e02000000000865abac63526351633682b52d", "6a", 0, -1533966398, "572d061dd55fd4ae68dff445607b76a601f150bfd8477783954a03940d1f6e1f"], - ["337b9c460249574f7bfd957cdb9d92d54cf7d7a7e0c3d75547fe5b87806684b1ce7c7733c4010000000551ab63acabffffffff6f203195836de2a6e415b6811df74fd68e55e14500cc2517c0aa7a12b1d7cf720300000000ffffffff01984ff8020000000006ab65ac536351fc20dbc100", "ac", 1, 1174314002, "b5dded3633197618f05bf1bed560e3af4112ef0c7ee8e55e022375cbb193de60"], - ["dfcad3cc01752dd9f61c10f14bdfc517442a9c7455cd4838c0d5c803061f5bcd74999ca6d30000000000ffffffff01924326010000000006ac63ac00abab3b4bcc19", "", 0, 2039059512, "0331b1358aaa707a9ee010e1bd436a0d67cd01dc5f7224a003b421022b229b83"], - ["b3647544022f27839ace0e40b03b444b91c84ba739e51d3e6a2865269de89f2949b7b5b51d0000000009ababac00ab6a5252abdca4fd972a1e679d21c1ad178fcab3c3a390cf1a4c85638e6564ee6bfd860814658ec2fc02000000056500535163ffffffff011a41280200000000060065516500512387b68b00", "63ac00525200", 1, 1409950414, "9058ae99f862a83b5f325456a3d70947287253b9af7ead16f5b04389e7dbb5f2"], - ["08080ab3017748d3b5f58657502998a921d637f1ea770bf15697b0f3da81e8d1215c2a3aa3000000000551ac515100ffffffff0399f10f03000000000965ac6a53ac6a5152ace86412050000000006636500536a6576837b030000000003acab5200000000", "0051", 0, -611008113, "1e982c7f40e9063821a1183aaa45e7bfbf9ec57d9761dbdf61689f5f863f1381"], - ["ed71727e01849d913174fbd49ab3705bdd886f13578b229c6921caa9b6d95869d49409818001000000026aac27b0872c04ae743a0000000000020051deb97400000000000865536563515300657a5fcb03000000000553656500003478c20100000000000000000000", "5265ac65ac6a", 0, 679002567, "0485ad4555486f23d3faec7148b1244d30c33e146cbff9bbb79139fecf4ab10b"], - ["16805355010799932737b72a2b9bdae6d193bc87ecbb0bedcb045e59468b4b17e59329211c0200000004ab5153512d68b00902a9eae6000000000007536552acacac522a0d71040000000007510063526300650cf0ff6b01b534b7050000000000000000000000004848cb0fe71b405abaeeb5182f0482cbbebde4d538d2c0df31fe9c269f8e3f655806154ca6916a1b09177301ded15bebb903d0bfdcb5a47d138bd105ba04f4c2aa2cdd2f56973255145b005475b2154f4d2346202e759a736b77159a07c10b0b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d254d580ab94e9a59b0d81c09dd1d8f19019ff918724fd12b46d65eb576b645f8cffcc494ecdfa5141421dae8d317cee82ffe618f068d57d0a4baf1a12f1fd58391502a1e34affbbecd2289f5a4a05c425571ec7548181b2273063be3ad2ba1c23f18a093ae3f566cf7017ba2046d3cd31a95f77bb62446336a0e5b6d3fa7da40227c86d139714ab231cd38b3b43e6cbc3131c459c4c5dddbf08df6cbc79387eb0020834ef0f4b709df66b72ea5ec95d2e137da3d61f4dfccec00ada65d434e21e500a182b117641a4b8f7e3349418eea821753aec96f08ad73e28d609c3759627d4db2e2ab89f728ec2c5488aa5cdf0bd51aecd16b09e388c1fd7ff94b8efa781a4f2021cb8d49a5d5ed860aa274a19d2260a777addd4991c219120cb127d6d93ab6b4c0316be35963438281f50c79a20e8a78b5d8d276954c9677a08f535dbefa2f7337d0301050e4eb984a1f096f821711f882da1bb304c18e7e3a55f14c82c303bca5c2c022ef03c4ad281f656264392af9db0b4e8cad6ca5c32a8ea4de97f71b43475eb8e021df6c6601c2129aa95a49f816ae3a6c5703b9bcc867f3f41f214d9432f325dd2b78dbc730ed99bb2ae80e270e0f00c97e553b2894adbbf49511362c5b62e3f938303ac2cd133e866b42286ee778cf5d15fb4c15a7c9cf48b910356375ce56ed7ca62ac9bf941876189b3a4b87b715e07f56fb213797347883ba4af3c29d3cbb69c4e45edd6e9492ae8689f4701dc934e70f6b2e6669a90cca5f644563ab5b6d7fb150914d6aa39504ba8da6a3abc419f0a00a7bb293a60b1990c3bcecf324843b1d46a8e5ba10124de9056417f7f46007693737cfb03078aeb28e11bd82b6864e69f89e079e475f004547340890aac8230937ae759ea8c50a50538cf5899a38a5cd683781b40aa748b44a27ec90569e1d5e3cd6b76aa1d47ad8a8371a7f38bbf8fca76dbcf8ffb7cba9448f75ae724c3b9ae412b1cfcad322ad241257e6371790852a258c627b5ebd46424a88780003f64b30060f0ca26fe58120cc751157ddb97a7a320f479dad697b2e763448778518fc6127018027e2d7929ece21bbafcdf24675e353b5473277b9ca0d8ff4f59b85f884ade37a52dfee873b4a3e0d79a2e49bfe09aa33439d3e92e3bedd39d8e5c4ada948b1118dd65479d9490f7c30d3f0edbaacf849fb3479c5f8af5c1285a2ac613301a29039fa062680ab5cb2ebde09356c38aa80891b1e968d304a282c822e4f61e2a8436c9e826f9ecddb671331700090d7ffc7f99a72a82f2fd720271091bcf458e9d47f7460336c85f49c1338a3bff33323b28df61750f65de8ec95d17738c2c92efb8d0f5560431b0ca1e345aad0950b9222e974087b9e25377f003b688b64de1f71e9d146bce497edfa72a257f9b46f2b6a0076a83ccf1700b5e265a7e1979597f60aa2462ef26147ae040c22b38646400786d1453021b662e2957e3590174efc365c3a74fc3295275a959ca43f355ed1ec0144bc34db3f96193b9048e34c23b39e8791392fbd78b04768606e30c6213253cbf172053df5cd7f13197adb2696830af3bf8b28097c7d05ece1dfe83c334c23196ab9333ae91c569e524ee814bcd798a26d9e498c4984a68965f117c40fdc6154e08136b62faf653c2f247a25562b5a1cfdbe97d3295f040cafc63ad7834b0de8661b30abc541ddfbfb090a26ed80772079752d3226bde113379b46e4e42cb6df1788153ba41641d38a57e00cc3fb2cc4bc39a5244652be2177c57ecc967f675c5d0fb9e530f7dc115f3a0c8ddd436fd981b58687a204023a54c046cd0b736e6b9911f58a3237fea11519db1053a942bf182edc2195ce7d1bf7999c3931fa913c9fea07d59b0d76bec02ba545c4f5e79a3655813c33eeab483e2b37d81a49344c3c83fea72d75bad66d7381a1a2652d849cbf14eabd7fb30e15f822b9b5874cc6ca04506885e477de0bc5443055c683aad38593886d8d03fb36cb73b467a57e7a83747a658ef6463ee802895eae1b14241eea4e7d0b48071997679628f40af4c930ac922c46672262553c875af2535a7567350cb90618a5baef348b24b2b3e31372d313f2b0f79b058603a073f0c5f109164d30fe6b2a969582b32c6efa40b59a8b3b8bfa5c1982611c74c6faa00bb10e0d490b283e31e09708a8ad352c657c90cbe5b92e0e292567e8798811155cc5f20e089f53bb23d4020fb2bbd30b45047bf8f0a203dc5c0b29874be9568c2868ca593c51b5d6ef9527ae468f91ddc85e42d6d9c43053e4655096802462b3dffa5ba9c1ceff713551b8f4db116d3b9e6863e5fddb997e5fb8ee503583b69ad8641934d07d7c9555973621eed19c2a4c35246e27311cf38475532ee374478b626bb05f822aeea5dca0c1ed81d5414bbd9b3d8b0c5e02cd4fbe72065f50b", "525200", 0, 607907689, "ec4d92295e636458fe1217a012b5956d2ba1295318d677529315c4b729062623"], - ["db86072703859912ecaf9b5cb7e5345e0aa3460c01e46726bc9eea6b6562ea8d4d72b2e15b0100000000ffffffff5a64c671db64ff5ff1006281e39f5e62e898e4fd0f8620339f885a1b312bec6d000000000553ac655263ffffffff557ae782da530d1861ea4a5fb11f054349efff8d4552b4c9cb259a03ceda43840100000006526565536563f233c8dc03e463d50400000000056565ab53532d12100200000000075165ab5153656a0c362a02000000000500635165001f683b23010000000000000000bc40ab0000000000a15d86c7c1135a164e7f9e8e63ec31446cc36ea298b6c78fcf8544af2bf14164130d88c3d9206f5ccf08dd894896bcc3bad09303c916ca64106019567dd453b916bdbd22eab2d30b3f96d2f2e454288ce203f3d14d5477252c2163692e4414da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c457e4c78383e56d73ad49ea38ece84eac86a64af48660c1e9f528db125fe54b0cc1e0aa166e3b899c8428027ddbc3685f79e17f52573e4a11d2b4c5a3e8a043ae3f6bf5e81ccb44a89e4160d7b3d2db799d376b00a65c5f3a6771f4ebe4ebf9dca09cda3b90483828e6d7ebe93b75a2ae4c0e4b5a19179f8ea2f68c4223bcd10229803cb626d175a7229617364683216c2b2c39e34d340ae402b478bcf68c8fa6032a3b62b166847350241e6c76a61364dc8c826228a07f506ff7f91ae0c726b2b60a03359b0ac7c3a7ab268eec95680f13fa68ad4f5825180035caa0f9881fa777011c048ad791d3c98709b192fdcd6322f3c7053f8c1656ea6289763f18c175d60c032d8b74be5b29d6b32083bd69e4c1801dffe17c85e39ae9bacd41a760cf7ce4fe0225b31c88588022ab247389c339815d4ed4a3eb8a2a0b23c2a12d7f4b156f3baa0312989d56288137e151664de563fd902dcb9b98871c4806a18e83c6abcf90757e0315888f79b02d653d02fde00c0ca1c32066226c7c27043ab16a900b4e9fde10210304a1299036c6f1c68090d3c910dc508cff1222fed5481ccd7c2a18d08ea634087f0ac4d602d7b1cfda58f5c44a0c8c1c0aec8f542429409e5a9b048c0afcb4f9f484e4d9b223bd0abcb3d129ab9df62531091cf08a1e6138e8a2c720161f3a83130660411e76502d5f1bcfe852cabb2cf1711e59c3e9dd9ac1ce984238017b9fac963e49454a7846863f5a5c924b550e6bcbb9d515ffa39ba9ef6eddb9c74208bc55fe907e0ae7951ff01f17377a580e622318a94c423a676a52f94495b4c34a867105fc19c4aa08fff63972a06819a963278a9cd8681e9c53f5985b8c77bfe9348ac2ca2addfd3cdfa41d9886a872c52d9de7943ef99f8a08dc8b2f637800ceecb7720d1e43057966acdbf5e97f3436eafbf5d11b5def466b9bba975678775f5e737bdaa7b537c019bf08d23104ead4bb6f4da4f60c1f14aeb8055fadb7872242bf2ed66290953a0077e52ec9c0531fa770598e1b8caac4056a022ebfad39b19f99e065038c0c5d33a424a8d05444a7a58486bf9198b342d2b99332dd2391faa30437ac753186766d18cae72faaa23b993610e58476909912a4c098c80bd53e7b8fec3206eaf19c473aa2c313d157dc52940d644713f8fa07b172c3943d9ad5140ff292da7387e21125dc75d4e922c2422b4eb47e21f855805def71414a871b580cb2a48e80ce4ef188628a7305becb43d862b174b820fcfddaaa370323e00d9679a0eb8c2d894dcfbebf2265584ed23ef07d572c0c66c1ae5e33abb38e949d8e0407dfa50c3efb669e63b74931c7c4b0fa3d07ed2601d4f78823b63e0a7d612b90ab4acb2e3ca58140eeb44c85c70f284043c4eda9c6a11fe9575f543802446e08d42a1a3d106b815a0def78781f0eee95e402d491bfa2022e1ceef6e9e31c6ec7d8b1b4adada3f969981ac64cb18859da69d268707167e4fb1dfaddb2157d74e8757a298157b64eb1073bb0d35326efc282268dbe2003251efe7242f4bcda097d474e45ef022a9a30823ddf7df29894f4aea4f58b0978155336c79f847d2df40e5482600c5ee6338c0c2a1615b200c4f2d1f1aa5c07effd94efabd1237e74c7c5af55620261b6eb1858a92a065a3cbee6a18effca88f213bc82d0f4b993da9bd17b4edc89535f0e138bf05e549a22b83c6c52e74110e6c5aff2324ab5e163a24a0f3af2e9072ea3d316af8b01d8ea3efdd7bc3db06ba50406816bc38d19c7fea4dcc930ebf1c5142bdd95119b70e9856f72f851122e60be9d3c8e7c534ec70fab8ea417056dfb5ff2fc4d39757ce13e5f9fc55c041a53fdbaf7b8af7cba801276f001b2d187b8a9ebdcf98628a59aa02b4beb49a90aaf36240173a3b08df83859e68bcd7d87e910c1e7781d91d891ef82118d725c300b8c92c4bc0dfa7c8aeb1cec3c1c9fb8d055997313115512e5d974f1f9e1298b49e01153bc81df6a6d8120a26bb43f0736fbfd7bf6cd13d4734f7062d70cfeeb43d7b9491ef6aeb36d5d690fbe3bc4e455493839a0403d904398ec3740c41416192cc28b163ad3eaebe2a8f9a45c6a6d9e43e20387ac7c7632337dedfbd8cd8d0df58471c4256d4c9688caa12ea0fcc11ba70cbed4dcb7259d1e775bfe2e139dab651ca1df7c6c8c6b11d4f278ebface64f63f7f240071cbd886b3902475380a0009cb054611669f2f8536a72b16c5ca0f0173e557c1e49305d4b6a2ed95cdcae1bba1035a364a63750572c5f8b3da9c865e1f25f84251cd3fdfe623af359fca62f24a1e12c3b253bf614f8c5bedf00a2ed2123bebe57e2008aca95362806dc0be8f64ac3cc20aff390df74b0b7c2603194decbf38846e2451274d1acabbddf18672cf3bffc0b4d0256b03e486c454e814e93970b878ee81731f04", "51655252526500", 0, 926312235, "65c4254a06c5f4b855d38c4b03920ace1f490b4bcefe139db103dd562a6e251c"], - ["318ce20f045c618f437e83370218f0992858df302769e8659c4bbc16da87c2d34dae3101c90100000004ab515152faa023e0c7265bacb5715713de25b00dc14b805416f8570126d083987afac19c52e18b370300000009516563535200516a008dd9cf5e5b7508fef9a1c726bcf4e61f6af7f51acf6e60ffaa8fae748a6e26db27e642ad0100000009526aabab5252536553449140aaf21eb651df525349716648bd93fa6dd7310e353fe2c060905e6afe230662c7210200000004ac51516affffffff01041be503000000000000000000033ab41f05000000000000000000000000c97acb084558b4ca90623be92f056e3293dfa0ae52d28de8f23f30e7ef229becbfc557dc11467cdef5a19e433e2bf3041fd2a956ea4a7256b706860bc02a222bc3a7f5a824ff40da0bd7fe0e878e58c186b4d303bd95655983110e809b0e6e3400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e506be44e826c4b21b26071ed8469713291009bb719edaeec2c4b0939054830aa090ea6007f54bbd819ed8ca782a2571a829c94df7a73f8c3d0ef6eaa521276082e75dd02202f736aac6d79e1a936926f1c7e17fdc7d61cb9d5a4fc8c6aa0f562287ff4fce6fd8a6bd9d7e45976392b57cec3137a0133abbb765435433695e27032257f6f0561cf6120136730a586771571218af561fb1398f9c64cf63e838f7660324fe831f0f5493693710ffb73dee82f7d38502007e999254acbded952f7856580b174a9a9c24a8e42257aca0a8098bd0e3a28ea1b0c2f684579c5c08cacac30e5405844e34db151a5ecef103379237f5a72592f3187e809b1c9f6b42b9165b1b11031f39e667cd6560ed7509571558c714c069eab0a11ac4f5dacdb110e4d23a5827032b8c9e5f665f50e28eaef22c570bcb58a9cdf5475f888fc94bed1bd87832cfa00321e9dfe1c3e8f4c4b3f8df1c1259805fe1bb4b2be156702faae9d17904617aab030f76f8504fa222a4ec81567ee2bfcc07ffb38928d9b6fa17fbd275f5ada83229020942d71db5eb26ae6ffca38ab47dcb88d6169599fe9359b91a50c49f50840df4d3dc1ea605715249d19eedeb9110e78ef5dc497657ba359c46032e2f9761d0003d45e7448e6deec27cbf62c79b8dc547280f9415af0dba24e1f1598d6cb565d4956b88065205b5b98ec7ec72e50c288efa5846888522fda2b9b7c644b39b436eda6d197d3c588d6d2e1c88b5f955480c255ba36d97277b46885e462f574c155989a8e2a34f7392cf64b346e1019e3b736fbbb6f6a28626767f29f2e8d6f4fa8cd59cf188a4eb58c2f9183e640b6daba0b0a5c638af77ce4d9f3c9ded19d8f2ac8c7c830cc5426373177b2ad83711c6507e27ebe6a433b5904f3e74ecd521b318569a9e657ca5fadf593369119e1521867175f056acf06bf5b33c92382ece60495068bde32bebd7719df32a2e666e8bf378fb9fb1b824d4ea5b8ecbfdf60aed476c3bd2639351ddc11160832c41d4999f8c14175dd2964898c15795a43efc9703e00e680fc762ec30d1ff1736f6b372dfe1d0379ca1edb2f928d6d6ba140d77bb89ee6e8d494a4e990defa1d79cd495c40a171b2eb5307832288dd4b18478afaae49ec62455f5f162f1c0836b44492c3e30c2164c6936113b340c71bb8193cb338c9b4ca4ba6ccb7adc93fd5468c1bf9bd3aaa41279aec1ff546fbe034d4a377acb83f899f13b260e33beed26a7843072b0b403b134e10a46e38d53bc2c65883714bd71060c6926c0dd8c5cf69695d55786908cd9812c956dc33711ddb7d98a84a68f087518f4a0ba941be3d181cad833c98822b80d3a70ffb53283164e417ff99f3f9fc006d6e5f549d8bcee3c67a0926a56020ac71afd795d58ed3824f59bad4f7cb9676ad2ec1f7fb6e840944ac9413c95f3b720ee432b94f2f670e96130b9ff383b7c350c799ca7d018c085edc1abb29a061a93b03af24eb50065e6c7a9732d8bf16cca7bfcd305b9bc1be1211a2b921a9a14252ec3bfcde02aceceb98d4b5985d092463402cc0667fe4bce2808daf73b25f93c9ad9b566b26f2bc8bfcb4a5f5f56734a8fe2794d495e0a580cbf125300f2a6c5a3dfe90d327d20635b18fbf37b3d226f60bb52ff915095c91f5000f99b1c98988bf747c4de62a72b68bc0b344fb12fef039d6f550ad6542c78bf7f9cf978f11bb7ca32b84d0dd94424cf4d51e0556351dc2dd168b9ef16575bf9654cc9cd49329155f02c46a89c5ddbc58b657d22a5905f0796083fd93f837e2adad2be5994930bccec145e8fdaac9ffdea98bfe29a58d59ae99e5b7a1e2816ae84d4a184212c61c9a3344163f696ad7fa23631e48b3125be3599e836ee6e74aff00def9d438f5687a0f18e9afffc08fa210d5199d83eb4c0c69cef70fd969b863b91bf9cacbc03839cad73ddc115849041bb243cd1dd3b543508eec6b3772228ac6456d4221f96ce4b04e85af96ae01a80a3a27cfeaabfa12734429d0135ba4ec8564b119f5811d0adc9a92cb64e07d6a6626790ebeb16449b746884b649324e32306c7830cbf477b6b86ed9df98022324aff207d99e22e8d831e334a62ed8be247023e6ebad1285243b3c29525532fcc90b7df3adcf15f9ce466956474ac6fd6d4c57852bda2109d13d160bd609adb67409b3e80ebcf3db106d0eeebdf5e5b221e413fa9dcf57637cbf8956b56ca7fba964bd350e01cfaf17bb53257ee9fc7a23d099036f6e140d9de4a5800f2933a506a50ff0056d06dd1ebdf2ae0cbc1903fda6f3257fe503000000000000000000000000b6d4a9f6bca27105187d482a94eacb4afb74a65dff5b7db7c41efc81845407eee3b642b4dccccbb50df4a7abb67a9a71b9417762ac8bdc28d3f464c3a015eb04d7eb63035ca4d3a877fca4cbd5c46f6be6f88625ac377f354e217f7be438e77f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066e6987598bb8898304c2115a9f36d9308a71aede20745595174b30e4636c8f938cd537268646d7b77c30852a69c0afa82bde71222ccfee6156f62ad071df096138450ca2cd1e0f76c6f45e26984a4097887a9274866ff4272a5ecf3498cb03ab4bfd84537fd450f82fe76e41aaf468d6fcf6cb122d0d8c5900837eefd98a64f03163b1faac5284897754a07b02565dfeae702b0521a071d3f21b99f72359b886e020a39701bc6c8f6f3f7f18946d3bfb94595f644f4bfc923a27123cda646aa09660b0f33c70149b34e4563ff32a9c276f4007dcc6964c096fec2bf1f4606834c7bee21cbb2231de723d76a4ce729c7d5ce0541c4741498fc81830ed2c3436d533e4f0310663778fbc3e54d9d9d97c8fb138946fa2d588affe39768d6677d5203a6c00e02251233484ef8a335b81fd9d8ddfee2c7be2cd410a8f02599dcda4a00bd23507c0205ce8d82e453015e99d451f720e3ad6ea0bb1935572703e97b17aad9487a3042031a947ffdf378dd824281e9ef30f3c2d486ae84786394759ce8e2435c06dd3b0f022325914468ecbda1b9af3975148c324d18eab6fdc606c22c8ce626553c57ed5710471c030d8eae7d66fd751aabac9d848cf4aad7e4c6d2782ea699247ac435eb45738f7d80497c2af1f02be6a06eae379b10fe8dfde4571046271adff626cd3f888947ddd3fe8ce28019951a349973568af64e607f3e7b7bddf9cb9138001d80182a6f6ae0a03c5d8675f6f90eab8e97a775fc2cc38d926350736ad21e54b2fd6bcb196149035f6801ed97b57468728bd732cc9dd9dc4e55301c91eadeeb9dcd14bcaee764e3af81f6c5a4297e210beba92b338124202bb6fb3ff57c87311a3d292f6312784224067541b38b4a24da7a3e4fbe0403cef8e956bebc8ab87b52a7f530c09492e3572b7585123a92842d825e109d2c791fb2e8280cd426956e61f740c0a4cfddad5335e9e9e7a714998adf61f0b6cbcd94d8602fcc1eb6272d3f9659c281b09e2f06968d095c7951dc7c6754fd8743c900e8cd7ece4eedfc58a0fd8da341a06d57b21694cb81cc23c0e1c58b0f7b3839a6db97a26826ea5e6fdf27fb936edc3ecfe85f9735e75ce20f8a78a6c856ea489b76946a70c4d1c5a0e8cea1595cd82cb009f6fc5258aba8f1c58ed4f793455c28b4b59acaa8fa0ea1b7b67bf0f99c4569ef2f15ba0e180b65c03145709aee45dd024c8ecb4df2d6f677e4dcb292d26273a3184650f7eee179eaf7edc7dfe629df2a5012360edfbef561363518f4e13b294b89621e512346981c39b192547106801b4195c0f903682352295c2fb0e1ee550cd90df6891d2a715f6d06a30b270e9e859fdaec7d32aa58a0368b30850d11e458f95a0698fc62e6cc9bd01b89894b3bb50640bebf1b41ee8d3419c795f93f067a9fac14994c61c79771b0bbd2cac58d27535e7d9526ba0108ff33f6b628741d935cab62fcbcf7dc91c63c50db5003357b6fee8d51dfc8cce0d5608b283eb76589a2c9d376f18a705bb7ccd90801efd6e9859ec2465898df035df8d391130e8212ead5143a9d5842f53d3fa45c6a4edc7c23eb2f8992f2756d716ef9e67142ea75e6965c33e511a36eff7557e1c4cec09354154eaa8e5bd7fa01be2a9d6e455a71eefb610b4bbae3ec342a508c3102bd370f5d08742726099ef9bf844db4538a8aef79163d2999822e27b7097b2b7ab4227850695f43fe02b53ea4ab7203983be56c81e29088eb4ddff7d7530605577093fa44d5ff74ff93e5a7c70db095bf20f437c0c6b22dfefbb59e21da44a0271d95e2371245ee358a9f1e55f3978366ccd5ac6af586a2ba0e0765029f15e3f100319ecd7d42cd0fa06ae7e5309793efdb65fac15b4c7659a0f35d41306730325b48ee9bffec944754abaa2cf25f205afd55733fd41b6179e385143460830f2a514b7184b832f426cd79dff83b0c68b28577757ca7eb508f77b0026b51fec9e7f7d81784eab9a28d3bdb7453178827238ece9a44b45145cd63223e5c9c459f16c2649affa5354c120abb77496d9eb9bd568f6879deb47ec7a30abab13b18f00b46716d9d0e11bc2d5295a70e752b7a5589a4b5f322185e6226f36aa7d73a87b67412e6e4d3d80123b1625a1783135fcf66b3cef1f52f8f7a30812843e07b441cfc9809e98c6a9cae1e08b925fca63cf71d67c23b650025b72b587394f49692822ed6af45765ace8af38ae0f1b721703bf113628968a7fa192527f7904907470c1897d0b9e4434b7f0b4bd9946b76e57f96bb510bddeb3ea8fcacfcc8625b10e00000000000000000000000000027a8580f9102b9833b08b6d65c3378b57faa3af2924e1a4ae42c063865f929addc95341225a990db25942661151e6c40f8422fd9362c3eaa3a1c386264d86303d9fabb9dacf6383910ed4f2cf19e25d44cba9891b7f660372bfd0c211fdbbccd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069621c4a2eea91b6c2b7957acdaa5ba30274eca645a2b0a027ac2a2342b232208d5f4b0090802e66ba397d8bbdd0d48d60d7ad03b68c40f05e2faafb1662e03a08f9e5a4c30de58b0b0e5e9ce56ac43a247bf5a88bc81b0767353dfb97ee94e55a9bdcb6d4209791662af80a1f60eb450ed9d1e11525fc6f5784d325f4faf1bd022644255391cb8db423d1a530c775be1e3b1b964d540a9b6215e96aecca7e2eb5031e751c77787b19cf4b5e58c188473e71984c672657751cca02bbde3b7a56c6690b1ed2952351c9e8e2d760b82d5e11b51a5b19c811d1898ef45396386dbf7ada52056d450554a65bec34503d1958521c2106ee1b8cc2001613b380ac9dc0834357032fe7da9b5b4352ea6575a32d9f868e4fe96ae294c0385ea8ddd8e2aacc14d8eb0215f3e02a642f19b6d71ec84c433e4835d8e7741c071389afeb57307c45c44b490200aeef3b29325e7bb246986655358357627a55697b79d1c78ae254ff5308bbf70309449a1224487d3c9c4d55f7755f18ce31191dacaca7b1aae20e8e3d8abdb09f032a5ce54217ba2abfc6e2ab5eba3661bfdabdb241d471b4e4bb4a539805a10d454daa6a421d653e579cb7aa7e934921e5b02a1f93818db1589263ec7fc492688d1ffe8de03d91030f340982fd9d6e9a39598f4d6daf77430aa059aec779a95c5970240a4e39a6781e87457492958811a0912920e1ca6688d169f1ed4ed97e70a0a8ff135dec707700ac782a7639bdc08239ecb240e385b2853083e72c9badfbbc4174fcfb4d022866dea38e1f647b4b2b84778a55010bd507a879d7dc47bba8322fbdc14b5cf18fe8d6ce24b3e0ab8049cf858a63ecec8c4db21ddf2edb8a559ebb903e11a37fc1c4af5d3d16fdaf4d10e022aa1987ce78aaa9def206f51a6726210748ff0fe09718822ad493b239c8440ba7b7423269d5bd7301f4bbd76d1b4068586ddeb717bfab28591ab8773642c07843dc0e12a310bb685bfe4d63e44b4cf9d9d19ca5ec57cfdb66ad65c2bbd8a7536220a28d0553c55ddd02b3bea4b505baf50f40fbaf6ee7ba143ff3f7546564fabaaa53e0c9887d27d2e8cccfc3964cc41f69da8b4555823a1443f197faa987abf67fb92b38149d5dfcf3f0e72800f984a4fa4f17808c5a82829298a0d48518ea587943827b791c22246e18a19399ce2ee1201de84aa713ffc213d35ea460e19f196fdeaa8089d64ee1d2a93cf81c57e2d768f22bfc85f9cc8417f4a80bba96f248b188a5bdcc3f0bba235649f735defe5c2e950fe15272ba43b317cf3668e8064516ed0e5ef719e43e7a218c814402abb58b1f2e9846e94d1a83e9e3cbec229ed2be9f5299f02579f426fb78f2a1b630b2fa278649f4528836a8cccac2b13af5efd5773666d5d183390cafebb57b98b2840a417872486138ca99d211801217d4ff5d089b44964a70f86e14534b9b18e1f6e704d9ee4424d745d67126bc149eb82f903a7b469215900bb26ee9c35f2d751e1935b0af18500c9e0892d1c439ea2fd7d97bf94ab0cca7ddfb9b729722e42779531915e2d19cee52b2d3c290534f048643f00cac490dfda16c93d60d883661d33b97461f338b1e21b38bb4db92f916d328750cee953d46ac95750f975965b262787ff46b66e6e0b2cf2c574ca53dd1fa59c57d1b652930fc28ad517977d79c810ed7f553b0cbeb3e20008441628131040ed11076d2dae53a4302e854da14af79b900e04d02b318904d2c6978b3e59d72f7a301c9590eb933f971a7fe02ab5fd7863cd564beb42e082bddba37be5e6fda9e5f01f7e5112049f79dd310eed0a456d6fa625f81432bd8bbdca8bc433cecf18ba7df7d23f96a06b139cb75eb68f71e3b9e89d589b87e5c9c9693a2a8d475d1622837d6f6492ec1bcac0f9e6ab0ce30831a279650fe8f5a4a1d49e9283ac2b51f81d8eedea9c62d766c3c43cfc3703d6379c0d6b86609b3bed59c22f45c1005d1a8f5e7850e29090241c70dffe861d8cd1d7cc7c1b06f76a470171e00cc109f1dd07337837b40962d4162919dd7f303a2d204f4360bb650974bfbd0fe6f171e6199779f22bb891d5e628535fcbed9800bed0f96cd9fd2a1a00be89d4bcc562305ded405394ebd608c0b3a85b365fd113a9294e8c93c33e5e205b7e8935a48c3ce52ceb79d3d939431aa0b90090b5ce6f4b856992d1077606b490e8a1f6afcca1cf81c6452c54f67533389addc2fd7d8b14d94faab67bde60ee0209633aab6e92c38f49515eee1ed2afaa06e901d359ff84b1d1beadb575446e42a26d1db955bf39c074fae092aab37d16d95e00f03d2403858daa0878e88be4b3729fdf645fe32feb03227bbf7c07470b62574262872b84d07efdfc59094a0f5710284b0dabd8b142e67a72a760afb7480c20ba2078d1350a810ab6e0bb892ad81d2ec82350d", "52006a52656363", 1, -1692392259, "c53e5005777471e5f26d8273ad5fcf42d3ac85bba732733ed01e5cf6c68953ba"], - ["efae88850299a9387d2097cd9a95061af63d04b34ba8bbd3ca3f3982602b2cb8373d6a240203000000016306a1aec02478b15dced285f5a5dded205ce045d1b90b011f153cd373b6ee4a0132f944e20100000000bbdbe83102da141d0400000000015166f904050000000007000065abacab52151e6e3a", "ac6a", 1, -66816186, "4a0e56d105f7a59c672690db5e55ff64dce529430473d72fa23e36045d5733bb"], - ["44a1886a03ea1f6563a5705907c7bf657c09531197519f40b99e3e33705053393f0bc3c7d6020000000700630063ac51abffffffff03055db53e017363fa21cb229e5fc91f13112b68c09bb0f0f2c62d28d7294730010000000263acffffffffe3bf963d3a50f8622c4eaa109f5996443ccbbf2d21ff78afd4b32983e65093d40000000005656500ac51ffffffff032a4ea1040000000001652ea2440400000000009a8e75020000000001650000000000", "", 0, -1471420573, "bf378b9d49a32cdc281ea4575d6f91a1b9070c0e0042f17471c5ae0587e20c05"], - ["5225d6ab04f3ee7b65c246f2be0288b9c1e7ea7bbc53cde36e18c53d0c4bacff1943626120020000000165b47686723a7ee21dae98875880c4afa53c11cb55945ebdc4cbcac8de23e7f21e3275effc0200000002526a1c7599ab7bb491e71d74f49926b9ff0d19d1a6a4c72e2dabed64631c3d7161e5aaec856c0200000002656a4d45d2c483e92faa4f63a7bd5702060847a7e81f70999fd517c5f1d5d72931f734b865ae0300000008525151535363ac63ffffffff0287944b00000000000665ab65abab633e7e8d000000000009006a536365656aabab00000000", "6a536a5365", 2, -2145572815, "eae16c4363d59c21e137614a667e44940461e0a157f6184adf65cba10ab9d859"], - ["91fb393301ffa03a7927df7856701f833dff8177023f236b7124f651cdc790e0a4d4fd6e6d0200000000ffffffff0460dc3004000000000452520063aa6eb5030000000001ab62827b030000000008516a53ab65ac526a4f040d040000000008636aab535152530000000000020c61a50500000000000000000000000091f4ed160b4230255258639aea1278529ca4139130c7d18a806b8cb4735887f2620a5f64dfc9637b823fd2c71a8646c072435e758bcd103eabc62e6542d3abf5fdb2876c941f56ca0b838c4226b28b78ab03e9771b07ca62b2b5485d2387a85500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000baa64f289bbde7228756f48fb85d991345c1cb0bebaffe168762dcc14511ed7f4a718c474f18d046188cd4a4724fe00aefb99945cfbee6a958dd231c8b19f58e55bad371f95fba92ebbfbf58a63405f521401b116957a0aa291c3d3aa13ec83cf65b16ce7b79291b6bb85e0316d4b9e7262cc152946dc1a80985c77212a0fa66021542c0be58194e3dec43bd76faa1f8e494be4f335bf04466d2b9248a53d6ed3d032457db19936fb3ba1989125e0b6d9844280593a6a6c3f7718bc95efe092ca8cb0a2b5582a046af37a505d69c928aa2ede842a0a664f1c8307d94532683f0681203129d19f3d9d853ab9ff124b92fd593441734d28dd82c230d032b2808c366f19a032dd6aab7dbbda18b1257329c1baaa27da107f10d325712ab16909252f20315c40303b277f3fc2745cb2e378f93233b742ceeff902cb52296f9a1d11f28fd37961e022b3040ae49527618d4d52f20160b8d5df3355e60f3a4869121284388dd5fa627032af4f0ee79f1d19d05345a8e4a5bdef3d96b52ace85b881e4900e39ac6c003b4032a00314a466b53583ddcdd71ad9b8a3f9e56a03d19032a270ecf35aa6f97402f3c79bdf9fd7aedc168b3d5ddedceb2b271277d9d78e520660d60e90aa9597b661c52f544b3522ee2e5bc750d45f8e7e63c82ed0c027c136f85f9f5cfe0be86e4cc7afd2cfdb63119757a7f748be1c89ac21efe58c78c9d78da408fc110efdb4d85af3079a5dd190d04e2945be5ccb4dba604042ecfe86602cc64e4695064abbf5e01f5c05aefa7c538190f025b5b81b804887764b51afdc49f2f771df2f7cc8b1489bf5d61e64120952c3e5191e71e9358a1362a1604c28f26d895ec3fb3d13b2c1750b243dd93dd93846c6702471a0c162806ef6cb9f9369da61b6e766b95a480aadf0c174296ee3333a11487e5109f4d0e27114f360eb4b7fb6c8baa57d45a5d232b4df9da33c8c00fee5c9c626b51aed81df3b4d2532d1d1a9cd21fe3bbfa2128580b2aad91f8e9040bd4ffa5ba9d1f08db101b69b1a4c9091bbc9ac3980c04cdc10df0e2e42d8d4ab3e18d2de1aa4c14e4a8033c12cb214b5ad83112b965c21659995f679032916ddfae80b3f01c89c06835f713a4f24e4b32a3fc688a46878510c9f108f0d290d15d75140a5fd56de77fdd158236bd91d20f79a951d2a72a1ac820d4109ca64e6c5ef6aa34273a0fe7a0f71644b51339db6c11b70f6c0c17059f49f71f2bbd1cc40e191463027476c9f592b77e4f3f0cea91cd4e088bd01b4e04030d0fc50845fe8ad9433f6590ea009d5106553f18df3b051b0c5d3cab9a7f53c3555af5948add3ac1712df92e6791def876f7f32dd4b3ba69ce7783b4be28e52dff6b650860a66846eaa16ff56d7be994e2f70cff3bba2f73c092d1fa8088a35a9bc1c9a5443480cf7a9b95b65b0f1975a3e9617dc2440908c2a9a87b4673fe629e5111c0fd8feb3d41cb8afc0970658e9bef3fceed6e9182e959e4b83d38e114f58079786282f74a9b61ccb84de208adc7c17e142f1846c0d187eb4bf5567a69c8486962831b1685e53908990253657a355d9d1c75df8b92267641dd24bb6b902d1a93a0bf0e43144cf5c3f2b691f02dfa7c738f5dc869cb08a8053cced0908247c009d8fd465a1dfd6053d22355cca83ffdac039407a79eee1fe6b31d7ecc8f400ad4b99ff8ae32721238a1d2276b4b1fe7bd307937f23828e0a2b61e20c823cefdaaabecabd3930cc2411310b5e038ed416b9c32370ca6168e36e681db94106834384cf4f0d81ca5b53ceb470cb71ec47b442a709b307acf6c0a17ea5737a7e3226103a589d19e94c44dd3e0d0e97afac367e16fe4c1a25f64c0fb221c32647086a283d4edb9864f11347a41e4e1420af372838ad79f8319bec1761468bbbb05fb7bbd55ddad1ede38dfcd7de9d1300301c2dfd8f08746b2661cc2f0c9fd429a6b48b68858c1829c7b2b3810e3982464fe205a1b5c6ff6cb8610e988323f8c8e8a4f8ebf463069706da328ba0ed02dd91051c09ee7724ebeff24642775e88584612b0dd41afb70bbcb63611f7cd1817e759e0e4d261a94a8b2f793a61203d65b4b847c5a8386bd15505b132048ea9299820953e2faa107d6d5da0b237347d5a747427ed596ad7dc1c94e45ff6383eec3ef974f79ba733f71b98b012939e7ab0b4e42eb528eb1dc8b9c196f4bc65c28f348b606faf9322a86ba9215229afa0378acd05e6ddaf365858e0f6b2b52b0a88d367fbf92190dfa511a33e3d3bfe7d19570f337e123ff67b2a97d9499fed9f7b7030000000000000000000000007bb00e7a5ad29ae56944d5c37e160f6c7d43b3f31308703926957224c62af1165f1c7d8b733ed988606829e642f2d0304f7b1194ddf813dfa3251c7c16e11543f6270155c31b08086df082da6740ec419331277e101a86045474721cbf0085a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdf050b062a3c664e6f474ffe7ff094dd30ff3b1ae9a0ffb01ba309b49670991d17a231658acfa5c70be9acdf3a212989aaa7f2a64cc7969dba13e89d8cc1811e18e0088d320d4b45211eacbdcbe82c6d2397db4e559900756689f75d566c2a4709d813a3afefce7b0ac44a4a12013c3108f0432d8985d6c1194e7adf1ee84e3020dd1982d091df9e20300f89672c3fe6e508ee651307b710b6adba5330f56ee55021ae627bf2697a75746f00b9e63c2b51675a44eb896ee970e4ff57f7884af04840b14c5d17372642cdc4668c469504ec78a80b2da207c41f674a8bfe4c4e5fd8dea0265b7f75a4d68d3495404dd9aa1b1db0d23792e9be824ea76836d8dce06c1940228434b3ec6e73aa99a4ca2f605fcd5ff0261056200cb187c216eb2954e89b12b032cd13401788e5692ed4ac1978290f816b46449e5627109e4b9c8ed617e993f17022765b6b29c766ccaec735c486fa7bb875166383e606de9e71323bdb8bbebe81a0307a01b111f43bab5a24d73a49cb65b9ffe33967460016e5a2b7c8c0a61f01e59031034b6c730bca82262e55ecf37a65cbe4765d6fddc804944604c6662f4801c037f9339c70ff6e51372168b22645c5cd98864a8d52ab19089d167053801a3ce5e7383aad54e77ca0011f8f6609012a240b7ca88dc2f22e2913dbb2b6e54868df565fd50c8542799cf5091dbd6f9144c05925d3115d7d92975a2dc8ce9dbc5dc1608349d59e49dc547250135230966ce207d215115fd7ab7388f9f539163c7cad988aa6fb75771b9d52bc1e97e73fb3abb1593d3ca7839ae33e3416815e4ff536eb9791830bdf72531f3fb64af76d9e614b77483b2cb22e1a32fbb06bba4b8cf00ee4d6ab3cc0ecb218260afd592adf5bc2c8ef0231947005d49ee0de6580dfb88742e6a0cc226a05b1e8aaff0f1233942e98a393d1a45910d6050d05127ee5dc9dcbc3c1f72d087e50769f0df7e5b61bdf6aaed8b0c5cbf0970b4d5671f09a15de245ec503b6a0b8525ecdf8756649cbda5d85a49df530c1161c91a0f86c1e6003f1ee487aa925bf0e4feafffa635574b5160ae4f730ab25d0a8ee924f81e154ed59bea1f466c94bf14bb37b9e4816fe7f05f5b12b45a18fa2d94ee9915850d8764eed413926c7aa694663611b662c9192a22d2bdb7ae2a9402104fd3ed957cf040d22fcd8caaf0dbdba7a2c87e7badcb66a57454006477ab2ece69bfa1562b4b3c9f9ff5db9acfd9b6c471997506223199843e280d1cbca5788c812e777b71b635f1fe8ad1b7191bb92438ecb67c66979f958c4e051cc210b20f9565d283c57050efd92a105d8d79d417bcb32195650a21d29647ffd1130efb31bbb5c9a2698c74a40456f79d834ad9c410e1bb4a106cd6c5dfcbcccfe9dd6b8811c78956376108fe8d289060ce12d1fdee45888961260cc9dc554efbc51dd7dfe44ecd529fadbaa11e4adac27334840b7792e18be2d683f88ceeb8195b376fb3f1bcb2a448a75a58ba726514259c3e5c974e7a2a2e504c20159bd23b1c361edadc2de7a7d436785154f8ff81e2e94ca33523c0d76d9b2852f596668abed77b48b58da003f6d74c1782b429ace7240068d7191b522f886e79b57c2dca787e41d431af883d9b3d9e8e301222db291f71643b2206c0c625adcbf9887ee221bc1e84ed59faa8adb603882eaa9340d9100adf56adeeacc0744d63a769a497bd3c2e91a3db21514be7a57cc5a9053d8fa67b7a2532eb6d452f9ea0d49015f76345788704626f707722060a5f5282e68e9b4c7d30a53b37b6048dc9c6e933d071d40eceab3511b4ef7bbd257ab1551c5e7da446915bc338e038b0ac2f52489695804c0117cbf627706a32b68a1d90d5cf566b069b70aa3bc53805e7ca7e7bda7bc9aacdb60101913fe56d6e33877f8cd3f6197e6bf666ab0b8a44b124603a10b0a2ac8b6aa4d11953a0ffd1084379b7d0996d0eba1a25b203be1ed5afd2fa8b18e9c39167c22889e34088de7c2d5d854005739b3e385493ef5cc61b2d89eb93d2cdedc8cee3b912b89ba7df3af9ba89ff3873cfb4ee40d432c3736a9c90628a31e2f272d5f1778267f5b3bdfa95223839f8b9b2c561289d3940834e5c0dbc190f8fbfa5177d08cf0615b78eb9e7b2b7b40b1b323019c19b24635429ed663cd8b8556cd4ae9c1a8a306b9e5c2dff348079dc7bb4663dd7122b25d9535f47c5a9dd222bfdea9a71f09e4c227a8f13932dc8344cef3dcaa0f0d571f71e3a2198db9a0bb3c9c1c5c8c5b6bbb591e53ee37acf10cfdb8c8df89bc9a73a8947b5165a982d78ec319e02c16010ce0a02aa9fbc1a19f4ca3a4d80ffc7b411450e915b4dd4f4007376bc42076abb0b5dee0eadf76bb49ad4cc9bcacf01ca995446a05bdb28db74b555b5510bf98f2b427b51dd330ba0b35b5dac7b6e01401903", "00ac5163acacac", 0, -1270584839, "1313d36eafffe046896bc685d84d85620799777588a4f8932094186c191a8ad0"], - ["14c77c7c0433358fcf0de5fd6293c5ba61c18f4e2833296b16b52d88d23d38e78b0e40430d02000000026a53a6c260280dffce3a7797a19feb89047c899ac487c99999523bdcbd7ee9c93ca3bbf938190000000003ac5253ffffffff636c6256772d3f6e0eb1bbe888276e11a3a4eeb1c0b6c3172442ee4095421a4c02000000025352e1f0a84b3eaecda488aaa8fd70769a1e8af3dbfb94216812420ac3fe0427fa79de4a0f090100000002acabffffffff02d98e28020000000001ac28ae5702000000000852516500525151530000000000", "52ac535352", 1, 1083571021, "673763abeb9d133b8da6ebc05b7eb25c80442e9f9108a956f85a3c7218692b09"], - ["620d3ddc038db171f9060e4b505b7ba54648d4f3f90280d6b815cbc08bc7d99730bad63e00030000000151ffffffff4a9b9d74a7b44a9259421cc17f449af301c1fbed02925be2447f7ac19330f4230000000009abab00516363526500ffffffff7fb91dc94f877d9ed15432cfd93f4c352721277aab76258e1805f9b1b80cf3360000000008535365525100ac534d013c6b02427e1e0000000000026a63f811ef040000000004ac00635100000000", "52", 2, 555319295, "90898463afa206339377b83203e57dba7f1357e65d376cfcdbecae770326cc44"], - ["1d8aba200271bf953d14197086ee4213cfa9a8994e4c0764ee9f6c04e2785676531544f7270100000000ffffffff0a2768fdc96e7e44aa7f4f237a2bba905fb1e83392eb1611151b6eab5baa969c03000000055351526a52e27ddb14018b498d040000000005ac530000ab0000000000", "536353ac0051", 0, -436171205, "99940597f26b79fab32648418ed103f6514e9890a4dc3a9a6fc5ae2468accfff"], - ["b88b11ee04bcbc12a34905acc5cd69255f394f8bcbd166be69dbb2d6a3eed2d27a2696413f02000000095153ac6aac5100ac52ffffffff3641e329c0b25e6d8a2345d03f86fa3945b65e52bbbc8d9e1f704dcc1a2c935b0000000002005283c075d252ffaf3802963749bd9617bd8aac83b43221c779c17c50eb437100f0151de69802000000046365635373100e0b72dea6b5755c4cc9d67d70c472180cd13fd9b0aad0b5207edded358dcb88325b0000000009006563ab6aacab6a6affffffff04d64d5e040000000005526a535152db389504000000000263acde27b3030000000009ab65515265ab6552ac3d3d490300000000096aac6351ab6a63536a00000000", "", 1, -1221938459, "09e2886873e26ca2c1d69a56423818c2901bb84e9d1ba4bcf677df0ffb14ab97"], - ["f6556a3302cac79ac24894bda9cb7c554af88da81fcb1490978e42b5cb7f92ef609d1a7fcc0200000001abffffffff0ead6cca7efd102b5a54ce3573fac6882f2f54d879646e0553cf4af7540c2be50300000000ffffffff03318d9e05000000000165036441010000000009ab6500655353656551df325f03000000000046d0828c035ac3cc04000000000000000000000000f8d914c282986930d1225347232484ed0c653d90b1bc0dc793371a49e245cfa58b9bcdb0aca5de37fb5271b882915f38c56382c788239611b1bda97f19cb8c7046cf4663337c1e5f00b7a4690de696107cb5a1fb551b5d95cd5455f7ef782e5a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fc499e7ccd1ba73387238b89d0b0802f13e1b25e712afed726da519c0b3aa131fcd9877b683057578baf3d549e34bc318ac97220acb3b3390c102a5e6063a4d3eae802dd1fb4aa45a591d0cb8c4d637327b505ec29afb483ce19e6d4cfcbe3ca07519a1a8c2f42ed51284128d4a27a12d37b55220bfaba76f635a37c55118eb031b63d21ad1a6aea836c51a494e97761c2423f5ec29c593cfa936339e0abfc0440204adc64855042096006d590d99ee4a431175aa7f13d5e58908337a36d6167a850a0947ad6e5b20193e3d7a7050e249723b18e34cd31633e6db2f91cbbdf134eea50dc9a16c62dcf8c7e819c72c95a3426bfb3f1e12525021367b2ddfde4462eb5602097c21b44d941449df38e54ef7ee11fe0801227a21531e01acfa5f0e3eed796902296d93ab75c2b6a42735b603e11d46607c7a1b1823e9975076eda580a708ea41031cd6b71652316ebdabc56966f0d17b3fdc0ef2fe01539d5e13e33639e44953d8030c2a1e59cc118549f442decd9f83a6b2a47401df724a32e754b3b846924affcf02080bbcd88417fec72bdc14c4929ada23ee2fee8ac698d26444050e7cc12eb7b2b1e6837182f9e88f64db8b627d178a1479bdb0d1f5e4dc9c4ea8499c9f0389080abc8504bcf992056256f3bda4d564d2f2145fb152d84e07ca4e28830de45b089096921932cac39940ee9bc7a741a601f53d2878d95d21c26f567622a6de6130cfb968cfdbe72ac49702c472db342741e77fa863443e1b7cffdea9a83c8441601dcb23e0a49ee48fca4847e6ab9c2614be91d7f7e871218fbe5d94ab56cb6b93e4375c5e0a2c2d97f2212c8399ed5d253dcd5cfb9bcb33399c31157cbfb6f25a4d0cd1533d55eb2a7bbeb54fb2d37a1b68f543da91d1fbc0cd5dd4b31f01fb58aebc15f88d84ba296ffc91bce2a0235c7229a0fe602913fbe850cd505b2a0b8b0df28355337d9949dcc5bf1e99750820868e0eff8a9b2dbedd14d21848cdfd5aecd4ab2f86722cd70e9ad007103e691d04091bb0dbfb378131ff007927a205f0197be652db42868fdfe1c83619a5e41bbb773036140487e1e72c105efab2a685c51d63139cd0fd4594acd6023ff1f4b5b2d8050f0528e1596a5de863b94f5f26ed68e150c09d1c51532292ec65096f374292c2b13e354149fc00d0ca37a59393ebb8293a6df7c6fad4e8edb31ebc5e1fbf459243118382b6d0025a95669a080132f69943638333fe65af2210c07c7bce4ed65ccfed4c02dadc1bed3f2ffea7c3898a72256b64f31a802d5aab3d221e32c9abbb0db9a822ea50e9264a8546fb6c03e19dc265f036dd55b0de11a330b958d9ce4384debcf005f94d1928e6b8f240b762dd404cddef314981496acc815ebc21de0c0009ddc5253e30614af0fe461f132e4a69e656e4dca63938ec3b70d8920389ad3c96ceb8f86983d5432b1e7b4c7450311e10e4809e7b756492611cf238769ee7b5f37f9ed8d2c5fd23f87f48a1d74e76274a6b9a64e9307207fc85acbfa07ec188337e4535b01140e10e093f17d6aa4feb78f9858ce3ededaf34a89cf841a48cf9f4a03169137edf266ac0a9fa16b4ea68686a74ce006e52dd45aeb33126798aa00c0622bfa3c7d7acb5edd08bc6bab9e8632a38681e7e86991d20d09ae08e269c71ef909a50ddd246e96d36c9c858d8a8ae166dc94f4fccef69d00be1add71c996782cd4bf4a768233b16582b2b17601e458cedbcc5b260f4c4b6be83a14658880d261e44a55f1d779f5a5f34649eb92f597543f33f421368cc6a5c3e13f4daf4f1399651ca0024e25487418c9d8dc82cec9c5367d5f17d2be0abaf84e54302ddf5e42b4ae9744039a2d44a939b408087d2c0f91662869eff6e6839622a9924a4709c1e607babf45dfc64b51fbda7662b17eedb60c31e1dc1f7bf394daaba94dbccec5a5508894896792b7f877dc4d5e883d35ef64a53a3e1ae7d983404f99113de0168e4dd76be6e0f283a280047c637f3b59af3cba1317c8ec53b059c336321693e1df502d8c0fb66c2fd921d1becb7bff73e83145d08d68c7190af748602f9b9d1c232616bee27d4a5ad1c16e13ee96a6c9da064fcff74ed7e02c16baf2311214f2c52058d61a136a854d737aab2bf88e1b54c98c2879b2c2eb9df59cd99bdccba6ce8faa3b19314ec02ad90f8f469201c15560964d913786be70f40e1588011c392316c7f92114bd4b9d0831070126d9706b9021e87a513f0a60baff7dbf5f4b0377f6b7fe447f735298c400e56d3163b9b07456e1e827031b5cd188f00000000000000005f9d4104000000007b340546e53a08d9284adbffe45f52a892b3297292fecc5a1777329a99b7980539d1c4365b70d6141f14e453fd4366f1219d58a65120d68ad9df81d2f17b42ee246f3fd4022291ec76788f52715e26641174d8d242e929a5f31be3ede719725600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b66870a95a55b12c367dfebaf1b539481a813549b8c5f23ab51727e6b6ca39c6daca8a381c10ee54cd2dc94d1f0260eb2b56bdddd14ef6428aca50b9651d56ee05183edaf2d044e28e3439da882883821b8ee5273e6df72b91cf24788e7d58d12c1c037dfe89ddd665d1b0fe142f0f88a9bf0d37fafdb2aa3747687b1860931c020f83f36c240ff31aa82f48e1e3e9d82efe871302a9fb4acabac97c8a1e67b15a0209160d04e6b68a99735c461358267508b44532971481ea11ed232f5a9bb474390b2c714f32a5394bb90d83cc71dc2c4afd9db944d85d40495a2c700a9ad3e8283e0716bade902c3c8f79476b2d4a6daf0267850399472fc35b35ee41ca59264ef502025d567cd1cfd3603a25a6deb13896cedfb34d6491b918516e38944508341db30327ea082bb6e9ff9d5d49d347f6c02c346f735f2939891f8989ef18705c4ec676031d144b3978ddec1dce65bf0951a5a037041a0d9454853fcb4ac708974f681a5c02246e311195c68403daa57bc104cc92f648e7a81c4ac3a0e1b98efea5bd1bcabf031ae88c8dd188d8ea46ac273b7bddccf224c131da020e7ad06b6181aa0249875c3f9d92a7255728e35fe1b41d1aecad9c293f6f159a2d3341a9d0d45659f82b13c0f21c8eeb580c1160ef6e1c4369f464e018f81db63bb0177e75f8f1d1d347e3604693dc9adb6386efdba77d81558d0ebf45b3feabf5b450e06e833d75c9f98283d9d83889602ae4aaa5e859e7d03331303c80efbc9dc9f7623e20d3d3d0239fd4f42ef2fe266fe2f849b3539254cd02ec1681670bbdae9e907a52ebe6124f15bee779946cbfc378e35d418e46e5a4f51fdbd57b9b921ba209a584c66bf2fcfa37d7b8c5893ed204f2b4465baa8559bfaec5e94cebcde9d7b52844f21e5fb982e5adc65e0c6f900af39c13370775c995c4ec987eff486dfba964142eee31c83efde16fe755f3378e11611268b9905da1ae112f11ba7313af0f0241d13be7f1fe6d98553a45b34c24c35fb978930aa2eb45b0ee6324590cb7ef762cb4219b371cd298df0bcd08bfaee643f1a254a36050a615a8cb337fc1d1f6472a806663797b563849c3f0300a623d6d74f8ea65cfe669ef62e8214ecd66d39cf6b27c6eca6e94bc808c72784c42a2e42a6618c44f574e6c36c2e696275023cb917651e8def2f185cad670b445b82e9fd7822a19fd36dfd1e3ad32b49f825f551f74636d71c0470ecfcf04901a307dea718f29342d95d80b854c5c0d06c25073e47a44c40446c6b976c39c3f3ba067768c4414e888f6ac43dd54f43c11a1f0965c1421ff491b3ba7aa171fd700e112258ecf1c3554ed6c31b4afc0fe95c6e0fe335812afd8e07e9e9d1d0a6db87520e14733ca4d7ef570ad5e330034cd41dafe70de8e8727ddd530aefc124c4535437fa3206679873d39e5a8cf114299f0715628d0a498d111e1dc839dd5c1c12a877c0ddcffe470ecf35615a387ad775095657183b4bd331daac8ce8fd9ff84a304279ccd816d4ce8838406fe4ef1e0120d92cb179119a893f22a733e9803bd735abe80ff0aed17f9b5106ce5d05eb582775ecb41157cf6ecc48cab05eac56c0beda70ce8a24102d7a6d7fda80f3285d2b88834576494253843920046e632ad82aa7fe2933d7b4927c4a5977dc2c7289bd5fae0f3fdbfcc08f448902b5ab0c8e528a0fa0165ca5c6e718bab28c3db3d10bebb4964fdef227d2f41ba048ce6b25cfacc2b35fa11e4612989373f93514461431b14a434357a1a66967c2ef446388956014bb3d15900bea96cebfa8c4dc75763ddc73fde9c73c0fe3dff173bee412b0a8bcbf9f26c97511f4633fd8040d62f888c7464b3c8d30375d554c93e6ba25604c53d7c89013bb02210f7c95b80f987639d8b3b7bd351c2dc5eb60b3506629c259421e9b508d08a6dd60111f61097364f4b0383e0adba69c59ebf99808ad3d51a97fcc6347c919f3f529c905f2e4dc23de4e663bbb4b490f10afc5f5ba8bd173d1451c9157b51987b9982be105d12327f1729728feaa07ff93433becf42e3b89295bc13b9a61f5e16dba21d2cde0338b0fb8a1bf9b3bb81c0becbf8ace4e3a416087e70c3006b78489051c372b9d2f3c7053db2f263fe5820d71a9fa4911b54eb5c003f7356b222b48b2c0a954c1768faea3dd93a03b07e6eb89cf132de6b0e32cc3c475c6443f254ad07a01736bc13717fdd435de89b6b5e33a1fb13c74bc6f6c3c73af519f330c2f642f371a8919e0be28f77222833f1bdfeebcf49c2a82591fe2719497d6243f6452983ae010000000000000000000000009370defc1b8aa1f7c1a5c0c93f3b27cca5ed52511ba3477b735b0557fcf3fc4912d159dd2ba532347f5e43429b8083990328e012f458721cf3709a57a04a2bdbec90815f1d1794cc08ac2116ce1e69d76d6ee17a2becc9690f2f1152a2bfc09a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a29ba24818df7719462f8ae12447b86f01ba149c24d4c901bbb92660c7ed965a49e5efafdc30db6579f3fc2ef34f7661b78c78e4421357c0aa29aed2748ddee6bedfe5c5ff24e0680b44280bbafefa0768eca8fd321d4f7fcccbe5e09336131c72c31b35fa3c8d91c1c734a5aae4bfad163d7e920474df733c276a5882452a76021f648bbf4cb7fd6bc6b5c0be962a500ad0bd4cd7d654a1a75d3e7ff95d53ff2a032b1319566bc4a169c6a57bd801b0e4babb8c8f9f2e6b16f77ed87195039332270a2a2be9013d21ed64517f6296f1c390ae02133dbacaf8f979042e7bd56ea3e9151ccc49bcf8856455c843f7b6c47c274c0c1ed00c9201b24d9a1523dfb3d553d00328eeae895fd4b8eb6ac6ed77b3dbd94e7a798c8e2902b955442f0f11a8e9c6b8031c20b2ce1909f2685c03e0cd784071d5b59d60854f9bf48ba40afca0625fb354021847c4b08bd9b3b46850903b64531a2e6e564072c1cd7e92c3ea21245e2d1b89020e7f15c1eb08d0767a67ee79abd1dc1fc0e8fcd507c062bfb8cf6fddb98ea4770302849f1d9d8e1696351829abf0b03e8f8565c092b2dd69f5823b3faa907fef155c005bab0f9d702a8666d09d2af0b101fd319f83218539c72341d4b68059a0834423ec94683e1246e4aae624eee275557aa1fee01e4989278937cf20f8b1e6cfd7c5d9b555763a461a344bcf5e8239359ab6b2d55348205ea56c64f6222e6407cf4095894c375388963ab44144ff510d327fe074457d9ae9e45da65054f1381f020a38a94b97a1f83e02b13ceb08e91aa3962583207f6ad8dbe43b05ef3fe7d43fac8d41f244277cc472391e07107bd135100e16a1e03b3ebd507baf04dcb3f06c5a35549947d076e1de121c6c1a8ef2e8a63dea212263cd08045af2c536f2064c003f134d357920baffed41769f33cb1d06ac66c28d8efb3cac23984232aecbc0291160368fd5cbab08922c0b12d67bd16da0909a7a45137551748478ec2b8e747f59c8c5fa64775653a16e844a26f86f9f0dd154e9f7982c4841e102c36b1f926588171aed04876f2c725722b696dfab08eeeba44bf70204806942312838da545fefb75c6842f99141558d580228e8712b2c144444d8df7baa181d06f66f9d2180733c0c4b0b3970fcec916854f311b51f542288fb463fa7f04b5018023594887bec23ae80a76402794e6f6c530f90245121e691cea25a9e94f1e718b6807d260e99282992a41c1d13db6400ba72ec77c81729578eba2606f554225a593833793f328833229bc10397f0f9df0e79b8e420688f401cdf198d502ae1241c7ecb2e1f4326a48d731a247a3fbf931a54531a93cbb9f22033994bc989193bfd58c12d968ce21aba6a05b50c7cb8f69c1ba680076691ef86f116bbabe786bbb9a2b0fbac9124743a7e0e7279b7d1b603942751bd5e24749ac4d197753345118f7ddf760cd5d4d1693212045b8b1129b0e214f63f8f000fe976a50151e65519fec06f368fcae3bb338eab7d2dafcd3dd09116ee8eca38589eabd442df6965eb49637900f7f766f21b9f5afc1d4e9a98ec089609b3e6e97fce7ca6cfe2e61432ce68ed4748154b40cf6aa0038dc3561d3e72a9bbf7944ef9dcb3859ea73cd25977ae36da14f7d60e91af04442e3f180ad865e55bc4f917b0165505e09f02eeb137c6e4ef76a8db522c387734f29fa91f21742f6147edcf9194179f0f26b6565daeb04fc3372defbc6eb1dbe3df8ef834547d13ed1e5d110056470830fcee9635450ee1ded1c678c35f102f3de9c593f6f2eb6f14cb94bdc23f4dca970c25842c8fd17f338e87dd2674ac8f2ece7e9d8ec542b7fdb8cec6ceea08386d670e3b429ec212d15a2f66506b2882e2e021db32d136024003c774053fe5a3ed629523daaf744bb66ead26ff091baa299c1ae0d3e587ea29f3726858e3531c28d605ecd2d7aaef4310eea7594272095ed84ee77ca6f0f51708739c1de6e3641bd2c2f5ccf6e8557ee3fcb6f382f33fe7d5a09933fc8e4dbd4ea5b3c529d75f81d456c9de983832a2b9395ea177d6d864be05cbe870fe2e8cf4108e92c30b4257c992fa90fd4807f5cc90e255bede241afbe2ace56932ccbc6b0e6b460b1f83f576658057f4aa9b2f6374daf139737a35462cf9798def1349279bf87241366fdc3f16dcb4e137f13456ea8cf9f3cc7c09511423bf3843a06be4c23b17ecc4bb55f032aac3d059309aa6ca60356c4d2b5f79824729090206b839bda40eb9ec65859109e4ee5ae4fb20eab05b5d689576291d5e438e5f03b5edbc4e95bafebd934077ee88f0785f5c294910b43f0a226a9f2a05f25efecb7f9a19ea2e0b4f9a4360e757848e17cbacad94cb4ffffd36b8bda8b2573c4fe5867d877b3a461b5d321f94ff5bf27e4ae5b61a394c11cdd3083539627f040ddd8dea0b", "5352636565", 1, 243010429, "429ad3b623a4fdf5ff0a41c4d98737c9cb193f6804846e1c842639d24fbfbe5c"], - ["a252152002207934b706c5b38bb2204d91490fe3e46368590ee57777dcad0e72f074c3f32202000000095152526a5165516365ffffffff12aa3d95d6d184219935b8aae005380c490db2851fe82fdb7d0db3b978b2096b03000000020000dfbc7eaf039ff3340500000000001aee6400000000000033240301000000000853ac6a00ab525252880a79d5012d9dc401000000000000000000000000ba4cbe01878e1591722bec82604dba2eb21c4690c3b21525f1af722ad2f3126d2f7cde565cf780a333ef8955e49d5741244e9152fe2a0fe4c895a44c2c64bf3918b62e4e2726ccad039b3e2e7fe4a7b9249db9383678510515921c48ccd7a68200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f9ab3475a8cdae37033370521e537cc5eb613e7b20e3be1440422b6caa1e38a730df142ff9c92f1d18358332fd439282e3e745b2ad149b8e7bb5dbf9ed850db7d02370589242510f1fef4712750c6881f5c3c48833af5293af88d1ece85585c8fea30c3560c763a55d833cf327539aed5b8075c72753715722aff0805d2bd158020dfb055eee7cf64f57542d4cfb34933930faaffd5cc4f0caaa57adc836efc40d021e41a8849df0c893519520a06be8c8eab7f273728387d97dc9f316677615db170b20b9cb52575730390f558f883f2e8d6c206e233874fc746433bcec421fd0ba2f30474876a7f37546b4be7f42ad6c495440a3753c81d34a1df7158658b1a108bc030a3e9b3211636711de6a47fc010a82d461d376e87e457cf4cbada7db03f562ed030d3c22425278f73931ebeec82a25c68bddc0a133c67acb30fb28b1d5c6a0d86003118cea18624b9b025ba7d6439b9c4d459b86103330e1cb5a2493e0af2a214db2030fb6ca34122cc0fa48949f821124307a52cfcf63d5d5a4974bb6c3e7822fbb0702141559047a630928473c5d5f2778dc790851120a9e4dffa1f4bf142cf5d8081e80e2513d981a7a0e65ee0f8806aad52180dc1ffcc8c042f62d1c44a4280c4017f810d3539cab7ec5ed8f7ef57803ba0bb0f56f40baf98fab1e70f872d186d1e4837273d5dec9fc3e83b145ed20f5512b4c87a0065335f9e6e211256fae23e15379600fbd904dc37b646c348ee3457cd8a71c3c05c54de3a7e7563497f425a2136148e3ae229c4df65878127022d26533d6cc382c54b6640cbc122a6d9a3ec33c6bea8f108bea3ddcd0ccae6087d1838d03876953f66497c8e83c601475b10e7a04f985c4121c648ff5058802e569fc3883430f6fda4c593957ce455399e61a8f7846f418dc59cf924c063b3136f5109c6ff06e71dc59b584aadcaf8791fd74ddb117bf25fc82ce44acc28d76789bfd5d3919f6292bc23c76ec0992693697acb40312f657b3c8f0014e0580b5069075f3fd0097a2dbaf7f75fb4900a62ac1b3b19c84b1697c7545f132b9c32704ec20d7c62c18f7aba5744a7d76420c40167094ad7f838de122ed8bda673488db5dc99aca2da950e412b76b268e282a63e49d6cb76848c3b329de844d676ab0ef063ab777a8251ed22027ee825fe1a52e55ff12de98cebdb37718161be1d1455a32f7703dd84e01bf5b93ef50b2c478586156a2ce725e5010fe99a27a3b40630670e720bfc1211e7b6d3b97e0bbfee2ebb66933ffaec02a26fe9216f7b5ad174d02c3de933e767edc014e0b1213b6ae44b247a02beb9509be59704827f78e492041d9d14870e3d8a6a8c2f7f122583b28d3fb75f9b173a1b2df295747e86fd25f2eb63c6d796868e3f7442a566628f5d093bb4510c61be7caa5f6820b9162d802a2a742605d76960564478373ea7b3020ec28ba9a8b61dc026e159730c210ce2a2d27a4a04be0669a5cfac4bfdbb00e3008b35df2194bc22839db4a91ef1d1c99c90c9cd9db65c81801e072f39047d1243160fd62d56e43972a858a00881607e856bd238fa55a8682cc71c882dd9ccecc37535cd2bd2a364c0b18f2016be3085195e68406f3e954a6c60395186787c733290c9a71c08bf6c27900e38ec44be9bd3677e3ffa445bc6ddc91c03c72253c37af64be5fd6c3a355e1f544ae1a2b76009f3752d581cd575efe9f29e2747225cf97147e582976eb76600f0ffcb4c7c61237d5d4dcd312689b6c032ddcd3e7a6f9894014436cc3a1a49c55175e1683a4b886c7fa548bb47ebd4bcb146d9c949c1acc7f6c0fc7dd4c31d97d32feaba7eadf9d1a019946a714d32d34b895ca13db7c5fbc9736c030fee2762d99a066c9ae6a71269901dfc7d8af9c2ee7c1ff598108a6961dfac3ea0a9878a750eec3c44ce4d91b4ff8699c72181e3c52f949ff6b1e566195d25948f88e2329dd412067d3e1b846ccc8bda8e828fae164e6083e2da4dd959aa0fa9e16c640b44297b3315a54ca46083c0eb4a9b14bff7f97eeb607a8041ed76538d683deaee5b3c9df8ea0ad6b31e2a8663362849dcc9c7ab81540877a36dd4edc5d91e0b7ba08da41d0d717f793f5d221ffdcc6df5569b3d744ed0a63e7e633730e6ddbed936d17048376049de210516486e4d7bc7d5157b3a73cc958a3fa00108f3cbd7e99fcf55f258bdffbaa0dbdc39cf1ceafa6f6271025bd30f34723c1d805f3949c25c56fb922f6a43731c0585a1969a22ddd198b95ee1d8af4cdc8b2675731be49c395780b80e019fdc70e8565fd4a7f32246a359ddfce715b126a42d1e23a6006aee05255a421922d92b9cae9eb8a54a47b98127aad5beff7c3485db8647d7b3a53d1ef367387ae1502b894528094155d3f6af7e91d182fac8a73197f0ceaf31ba223836a7050e80f41a12c01", "ac52", 0, -1038755428, "b41c3ee80aec3990e01535eea14c0c0ef14c6c1bab95f2d6407b940497ef9c9f"], - ["033cf6c20156c448c47ab07a6fbe3322e39373daa3d853ec07b0425797a66aa02995e828fd0100000007525365ac6300acb6c9539d024bde6e020000000004536a5265315f93040000000006630051ac52538f3245f4", "0051", 0, 2032223611, "2823d7cbb65fe8a7e53f1a02474914db5f7cfaf7a9304cc676b0aa8ace80d8f6"], - ["bcfb201504cbc20e963db322f82a9b2394c776679555c9244cfd664fbf3368e8b6f247f82b0000000004ab520052ffffffff18a08dd51b2c4825563ff4154cc71db063ab601ae3f3ec38683aa37e8a07e2990100000005006aac5363ee3ab2a0e7b1c9679ef26641e3eb01ceea517ab379d33d60bbe5874e5dd6c5eb5491c001020000000853635200525300517c05c8bec8f9d596229f76c346ac37c2ee1a5d94b1321e4a55614ad6d12b4e5f6735a72201000000095163536351acac6aacffffffff02fd5849020000000009535152ab630000acabf6f63505000000000465ac0000cabb6d8a03e8849d05000000000000000000000000544138eb89f50f73c083ca71c4b3282c97d2879799e32a895bcf0c2ccf9ac3fcd640e4492174c94c1832adc6e9fc98ea2cad1360237c5407f49268cd9a57eb525bff1c02902ed27d373bf9786b39246dd7aba7ce0ba43912b9b6fd5314f501db00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000937d30fa45e8e50d5334528b93e4c196f3b659624156a02571f55707ce0d384be6d7c9875d1e8b8c0b18d88023faf6ec90a6bc4585e60c45bfd34182911cbd8fc5f47df5bcc529c0d477422d2bfaa3cde4d80c547bdad5e5804f4325555b029453f3094cfd3e169d905aedd53ef6e400f9378ed7c1f0b0b6d042557ab19385d502275f8f4dc3e75b195c751579258de3f0f3933e859eb9219d81f2b63295db82a103125b7e5535df81f86cf0a753b56def46526657fc934b91ef48d01b78dab3d31c0b2a8ec61bc2f5973c47b5778e873e3c19eaa09666c98054362024a9030b5fbd590f4b474d3b8b7e7d9daba2f80298f7cbb8b37c40cf273832e56426aeb1aab37b0321a84e6cf5844ec830a114ed3d534dc4b4049d862747bdb7c6466aedace5101d022da002378bfeb3f79ca2bb36f3138edaac8e865a1603f7e83c72195aa585bdeb03110f4d806be35aefc75eb129214faacda03281891b1cfcf417214ac8eddb9e6c02138feb666e0d15160d1302076064a3ced8663ac07d2d65cd7b32aaca614a6844032329b8c75af647de42ed5fd5bb803d39d793c5a875613d7974018a022cf08a4be334cbd92e8c80f5c824223fad93985199be1daee56dae9e78a2ac72f12a5f092793a2ac88c7475e469b9e1e26bdbc8c494df393505f5fd93ed384f10a0272fd7dc0142b472e09f18dc098d43c56cebb091943848e78c8258247589a5831546842066e28409bd2657ff5f6ec9f09e80b69b986990d04e890c0a3f8cdb4dfc408936e4cfc17fca2fe6479691feec39e325138486fa729f6f4002fb9c1c6e79bccaa01afb5ca0fdd8d2c2fdd813bc4a4109f586b52a541b474f5ad665d7bb934c58d6bba74105bc21fb84606cff398af46fae6925dc10e1d320d485f8cda602123f487b44f4174c60385c0f86f1a993d7d3d3e61726543a2a3a34c2cc46b406ab4d18abd52c71956c9b2e8856eede760b65c41e9c068a4a1ba96043420d2473ec5449fc4207fd40a3124532ec0bce8435495d581da5aa5ab9d251b22a8aae10e201c42d487339555634429c4aa360cfc2cb646dc5f90a3417f860a0b88e7bd9a6966dd8a83b24d2051182cf52b6f6d762ec9659c4d81a0b516f5b877ebf786ccd94c5eeefc55d94d5b2fcf1280b026397272b02cef74b7f15d605a8d26c4741ae83fb82442e80829a51072a7b62a7cef46ab4c0e6efe80801bafd2945cb8812e10f9ac206223bc3d094908356f318b08d7166bee05af4305a499e471cac5bab176251b26742d773b280b8dde633df55269fd5b4ba1d3be04f2592c43ad0dd9c41f871e76b5dc82848441d9733692ab4ce16fd31b00ba0f2ad0c87e417ca86c33cfc7aca9e86100489323342ecc6a3d76e1cf6989b61a5c79a5e4ee8c889ca3d93f1c9dccddaa8397d9e8d00d81a121bd432f19c6b8e3ecddf7a5fd42d9e5635f4d5d2af74b707f23a2356099ba78382e01743166d38196f04526e0794a83ab11be09a2eeae309cedd09ea6deac8f8c39efa8edb345a436c697c13f14c03bfc3ac1b451171aadde4288ca03da90c0fa6a7c513e5b426544d5bd51178afeee241b7d6beb1daf704122fed73d91502935297d981845de8d8b30754a793b1e4091fc7fad337eaefda9e5af89f6c41aa10a1cf04dfbc7299a4cbd361deb72b08967911f3b84e870ee887d312d988fb6055784293f2d240cc747924710eb6e45a182edba542a8e4214c436311b0afb7a3e9961d6ae4997f100acab5d3bfeec4fac5d5d08d91356b7d9ed081eac25cba88036357c44962a782c1a0b61d3210740a9d255dbb45c4a6d196fbaceb23f3061cae9ab3cc7cbbafecceaaf8d89f4dc250da398a6837c4ecf4ac360192b8848cc05736075bea4d824d1f45451294c6b8e6a32c251959939b8fae7baa10880c56905600270ee058b6ecd4c25d40c6d9046f65c711887ddf0728bf2da61ce710d5496b17a955de2233d3fce42c4d8dcbe073f4968c1d14549ac14c0595b67d84b6b05230fbbb5f7f690b9411eda4342a1f54bcc46fff6be45790873572cdd9b81fc9839843b65fa545e489d0a3dde4bf2b6b27d4f76914f86b7a27b48d62f89dde71ae9cc1e2de9513a2af8966a40446191b248200e30284f58f340001b5a45640200cb414b235b76f4108554a4fa0b8b64778df2c985ca0483c1e71fe5fabe2c81987ed5c2ca3751a353ad7a7bf7cce9c95913e2af9573cf63298d66db0ac55d2f2f6849a32e48a59435adf51dcd80d4489e770c6daa654b34215bea3a2ed6d161a03719cfe4c7000000000000000099b78c0500000000c4266ec9e2f9d7b8055569cf53b1099767ffe4b9621246abfc0b800e6971e72b7505ef968430d6f7fa31e6aa88347b38fcee283720e4050f4ebe9311bc55f3b09270fd9b7b9d6c637f8cbeb1dace2c9956c5112b0d32f18c4797b4a6ee1b60ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9809efcafa858d09bf983ad132a689eac4e1bc51da8eeb42055b60cfa9c4697dac3ddbd9fbd641e3e280672ce5b1326f63730d6a9bcbef76a95dd3aef114ba04159d4a6e8a36040ae14557426c458c3fda0666f00f4e5895e9ab3c7cbad6529e78640a8507519304699a53e29c0c41fe5959c8bd6793f54649a9f9b27a6ea0d020d294d70314e3848a42ea4338634e68593c460fc89f3f8b6f19c27544602b95c0223f09b25a43e793bb3a4d7b2925c79cc10d553cd1b78a88f09971e74f89776600a2920f8ca596e7433ffab769097f10e8847992621130d68fd636e5af90e31764213ca69a2d93c548918881954e7794c456f6dac4c843303888bab65eb43a11d6e0315f767be76edbb5051aade7a5a2ad4983fb266f0c0962ca4ae618869d9bf2f4b031e5a5576272824a800fc2d45ba4bf9844a7937e658ecfe80d589aeb70d61ca1c0328d61ce2c1940cd29e073ac49fbf6cb0a911589898b9b35d214c0d3c9e47733d0300639a9aac3c1e800381dc8a1854c105d363884b008526e20842be92b75368ff021d6b863a2b92b946fed01c348102cc59692a8fd1957eaa1a3ab19fde850db56d0e427eec03a3c286fc8bdda71ad68b605575f83b9abbe54cf31ce6bad31c1eea1ffdcc31df258d46e257d5bc7a82a83632d99987444c27f5c90741a041a53800912731a8a67bba626cab7fac95fbf9e43ee6e35473970ce0e0146fe27d3a59235243766d4068c1b950de1e3aee1cb6c9c46660f08e34f28bad06fa7ef2cc0dc9303cfac9e2a725964d07a913478012216c5e9a29d516b48ef5bd80a9cecbaec3b2fe0cb7373e3aa959bf215bc7a7bf27039db2c2a1b7588866248b304c8f89b2110fdc7ecc7d87137403c8b4c340a31927181527e1edeecef64d2eea494d183bc4bee59c48c649de2b2970a8203148c62f26f82f57ee4027bb6be37d23cf0fbe3871e5d4053472c07455d854deb618db23b8e4eea1c5c600477d2d6809b54f4b81ecb113011183bb1b2aa59363f596a8ea33f032f57ee3725023de6c9f95eb7a1026f114de1f20000431ba5072957b549fbbeda9e88871012e1c37812beac7891026ef83dd4c7883b6fa51e90c768efeeed433216eb3cf9b2ce6a1baeb8a4730c8b61ecd4f98d7f0cca1fffcfd28c242a3d9994f0b2fe74f3734704a794a21e6e06c24a5cdef34c486fa9e0eb8b4d45708a886428f7ed1b185af8f230f51603b9dfbc91f861e215a84e4c67cf7b127751a7bebf40a361b69610382ce9707a2ccc9632177f592eb69dea2c07a16faaea165a90afe9b76e2fe81b81693d1f893fdfeedff873fb77f12c419f7369d2bf72a73399dcce0789080e71fa74b7204dad16c191a3f26732454ccf4e8c59df16570dd826239c06ea44100809b5c04d7a6efb4808e79d99e91decedb48b9a00b7fec9bbf19329ba9d284ef85be9cde7abd65221e95117aa9827721283f4c5e5eea14223bfe2b8c1308ab857e1ae8945b23a1fbc033a6ff0be7b82a652362d614965249032942a3e9477f7f98d920247b82b33c38bad9659149303ef0b88e35a8933390651ffcf4da34a3c8711300b3e59c55dfa4a950f17bce08c483e95701acb7f4a4536a0fab82c4074c9b5e4493f755d2a8bdedfd6e6f00d460ace8cbc65d61416adf48544e95401f1856e5bee7785e12cb52a5a1f46c2dc45fee91384e462da906416e540001d1fcfc0abc7de92e11015561bb88c8853be73741fd9d5ca3e848a8c8b55dad643238c951a5ed0bf759dfb90612676fd8a012e5503b9e2524f9f370bdf771e0a6dabc25d33d71b0e7e8c155b2a0fd3a0d30726f5da67863302fcff9f1053b547e299838e282cf796304152b107bd724e023ac1ff18f9088298a3e9f8de937da1dd7fdd0f7804d1c3bee5f6e0f6a0633bd17c849a3b2a185fe7d88d25f86acd4f251af1aedc9b2ceb2fc67ba7ef3aca78e850221136f05847e3b848805c52c05808056c8e4686a317c0e5dbc874bd2f5601a6f7fb9e20370b104876c53a15838a452bed77ff2518e9fcef2c93a41ff729a80c1c206f58a978ac56cb1166c58d49bbe415e73ece6e2bd2ec2b41867bee13182f630fc18c93efcf57ffe9299778142b962152e3a64a7005b12b97c89c285a7f44fe952566994373028a547640aa959411e4dff656fce82ea2935f57bed5a92f2781ac69e14393b357b63d8e77ef7e371f821c6ecad7a2510184a2d1eceb4f96ae90df0ffe35a7272943d81e43f88cf53181d9cf65322a77dd03ac9c96ed32909cb6d972160738c5eb38a29340400020000000000000000000000007d3ac7e830ee29c033f093a20f844e5f93407cf5722da60dcb858ec195560c2b4637950a1a3b398cc478d290551b7b7a0334085bf180bf1e3b5c88b3fde97b9ffb370d8f2be9ca8b72ecd556dc8af0dede19234249822a22c0ca409c5acf09a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c11c5aaf82fbb756ab6653876d176e985ab91729b955caaf12b0f2592e42c7d3c83b754ababcb9c647e90aa8951eb83642cab539699a1590bccada3d59307a14f4cd38ae16e59d378ff447cc5cfba7b06fbfe074faa99116ec3a0414a89a963dbc9484db64f58e8d91b2aac7d7e0e9b9ff70bdd0927b2131eb6884ed579bf6602070bb2d751b808ab7f65abcde45b78d03fbb427bce73060f68d0d85e54e6ca710219e0e665ecef50f9929e15e2701e9dbf3e306b289ba555e3bf650575b8627dcf0a00a2ec37eee6d562624e25466f078a1c6ef4ba7c51f3703bd71a0a8db5602f121e3f3a94e1e93aa9d6004f2f80d66d91753f5c3bd50540036353d840b0253b0702246e5e560b3805ad2ceba58e5462ba4dbdffd21e0955ae9a6df9cfd9a1922b5e0325cea40202cc7872356325378d5bea13f40cd9a33cd02a54f9416b13d71405f903036b1b392edeaf871894416354e60416e9baf4d8c79f980a7fc01c6b060b2f4a020854a9758c455c4c6b73762e66eac1efdb2834c3c6c886f7f1f4a7026b7f874302113fe2b2eec1cb5857e030363e2d387c01fb43268aac4a356248bcf956b21ebaa9c0dd68f7f291ce55ee2d05ecd28f35d14a6d5e82ee6480cc23c659352061fa06a6a5b660a7ae29c121573eeffa092cfd5690fbfaf318609f74a3b57686612471879f7ca4ac9f32fa43c91eddb0875268920860f589b843af9317ee6327e42362f1cff1b0c5f5d9a76e8da2507152deb0aee9ae210176c1e3bc46e1a458bd97541ffe30fc3a103e7315b02016946ceb7fdd15ffcf508a7e2a431014e85261dec7b4c11a9a995b171769b6861a304d8d4b27fcea7faaeb5fb4108f5c88b8ed7540f7081fd002d6289ad3748b3546cb634e41498f5a1236d3a11196f3dcb1e5e033d560cd4503ec10bc20e8f12b586e743e16b208261e6b433cc8b124f2046bbb405ab75b27302f16f7f431c5476c9a8ceb3248e495806b685fd3c0e158028f78178834db60783d3533f54197d2bf504050039ed382f08036e0584703a560655ddf88b6649a0c1525a7754a1a19785e126217554caf85d3f64c9119b9c9c54551eecf43f0d0245cbf21eea8153ac0e1b93c2eee1733d818d299fa1431874ebc0fb50ba3599e251ea4f33fb64fb1cad68a50eb040bf13489702ca9260b9614e606e66046b090b336b8b8dd97bdb6df5d19727f3b2aaf7d2307828904cd4842f4ec79bbb1440a026eaf4440d0eb29b764f69adad4dd6f225827c5995fc59b1c5e97e2c501ac4edfcc5d3f5499d73092a0eafaf6d24786f7b4fee0701ae4165e9a243f598e418e3c6b7f69218219446995a4604851a4829c90c14a94a44244c3d7c0ddbf0703a225dd69ca153c5b6f500e3df94b05008b719bed021b1c7a94619a7116244edeef9af38661009c321b74e342daf63d346caaaade59be5409645d79ba3855bab9ba96603d03e2be3c65c188e46220724d8e50ccedcb1edeae170b272f6e73f7d3c07ec9df5dee7e35357ae23a179e38e2dca9424c973d4fc3ef42db0cbb305e0583c141b2c36de5d8dd64af52e20bdb9398fe39772fd86c67c4a6d14454677c96d318f69c49406744883eba59ab63af223dacf5310a28620d55ca8c68b649079b71925efc1546b4677d89e5bb2d8bda1e41804ad2d126f137ce9e42c123b5956dd3db67297f57e59cb4fb3d90a50ae3336eb8d650f3a47ed9d543c525ae0725b29a340759e3557a28008ef481ddd784915d8c939c8d7bf39845708f78f41e0e8dbd3a1f7148324690c37d6b20ccb12911e8d0ca26c48997698c03bc301e8d22cf2166b9d234f2597c2b32fe4f9f3e3c2f95bd014a0f0bfecbd0f915a01e978219658fd4836ef43fb00590c5f10f76ab5afb521b0059ff74843069e9a6ddfb5698806540982a2d0fc5dfb74f3d7d7eeed185e1feaae5166948ea8fb84f07d1780c910a9568ecf4ca9b9972b6c93c45231cdfe9c55127ef46fe4b4033186175c6ccc4380757a6f58364d05becf5ac5289aeeb3919e6c5c3df40f3b1ed6077889d17efd8a12d97406337d9953708757fae65d44502fd1d2ee58f2b168cf384b1e88b242c6cc3699e58323278218575b1f273523733127bf1c35629d4a2631b16780685cf566680a37ae91d6e441c58cac5576dea4e42ee4e8be8a88517b02cf10ba870c200061df9cb4476fdb6e869ce2b24bbd22ad186bf4e0995a099a791d0fb4f435f2394015deb9b3cd77b22207ac100865fe9b4295e4b6e774360269f394f3e257a5312b63d49f25bd22c2e17806f5a070b54d68a1c8cd4a075d3a0acccf94ade21b33aadc4f463b3d848b5ac3bef4e3e227c1cdd586dc4d3905571c6cee48a9d1000988ac70877ab54dfdfd818a81dd51afd7185c42200bfaea720cc5af4226f081aba456593f2dbb01ebc200f", "6300ac63", 0, 1988561694, "3920a8debbfa14008442688c9a0e861354b379b281158a65a36877f0356ea164"], - ["ee614d2b022d2eb44a11ead6c885607fcc6c6b462cba11fb422036402c3d18df5c65dc463802000000075351abac656a51ffffffff7474db96ab1123890fa7f645f5135445c373408de13f3047565e8e7fc4117f700000000004ab515352b7a6c23c02c2d4c90000000000056a525252005f970a0500000000085252ac6a6551ababb7ee11db023506ed01000000000000000000000000b505023e7512cefac652ce3c6de0ddd21523e159a976bcdd4fee046ada529e167c649437d67e614bf98ebd2f4cbf20e368de5220ce1b8d0e2ef6911d722c523dc1870ca9b52baf1118a486ed3d041e1871ee513d4f434821d26875d5c9fbf14c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e51bc38f540df82005915ae6173cbe6c229f3ad3f4b75a9c105247b26f71e1896ebe01ad900679fb161607795884a7a4d824cbdb0b50195caf569b0e54a72717da6758d0e420308ac63e93b3481befd914e36366e71760820e97752815236c2138fe487b0a65e8d8d907f49b0b777ab12e8f3f6730d2de28d76efb0128af76a0302af944e285e6826db677a966f0464fd5c4f5382ff7f36dff8e040d4b6f268ce0320a92be7dfc454438335c4e3d3ca516905b6ebd10ff991dfb4f82cbde92a3f120b14e189e449930c35b70feec174448e3b413ad0e0a13c9cbc622081f296b2f5250ef536e2f7c2a64dde153dd527c77d9e490ef390e44f7187d0cc6ab8561508980216374ca36ae0b1a3e8255af426a70fb9228100063ff81644f3462048b1724157020cbe61c6449aac81c37c9468d5f8494eb501e72b7bdd629c707f5ef46b39be0202034ff21c71b796cae7a9c47b2e1b409bcca97e56a3fab915826e7358bbcec2f9030b48d8ad632960a87266c430fe3752c3daee0a2c452e915e298dfbc36a2e3d0f022ab5f421eaab6573031bda4dc076563ea7b20c9b7fb0c3bd33451701806bb9baad8eabf26c8f043252c709cf0f937e08c9b14b8986db581148d782c49ac28eeb82e5a85bdf3138daa8f112c5126a439185d441295ca3811b567226ea9795cf9f9ad7d8ae9c43232d144b0ad451a4d5410b49f85dab53a8cbace0b08eca84263b80138b9321e7f7e317a2e5e74a448bbe7e90139b65e8acfd68ead939a4c2befd0df77bfc8a1de3c0c21fa719e2e33aa1614c36b5b0cfcf0df8e3a174c700f610f2e23c4d8d770e00ef9946e0acb9f7d73c91e42f71547299ae85c5a099ed63c606a83cea5dadc11352f4168b56a622b25a4e55952dbc703d24f49f16c852976d3b168f153a6979996282fe73832796bc460c68fb04c2ca3223ab43e1e20cb6faf8743ed48d03de103dc07698b806db37cd1067ca2d7cbafd3342e0a6505ce601d5bbf5371d1e461a974d4c727bb9a592126e1e42264fcd156de30154bbdc382224bb9a1bc76f2bb71b79fc5f3407c7d625d6347a68d575cf2548515074764452337f84d16609b8b1d2c51a028e71ad70fa2c8533c3d5258c5de7ee0a82819414213e11ffa932e73ec17af04bda8977b6af7f3707a31064367ebe99cbccf1ba409372bde830c7c15d07287fe52b6a41a83c33a148b30ba2f9b56c3c43e2f257e4f726c39b944849b6b51e195a5dec4b979049ed9b57e4c238de10a136d80990dd3527723d1a8edd19dc631c4267bb69e124f1fc6906b381b81bdf737d71434add7fdb1c6ddb3e15e39d031bf8f97dd57cc01d99f86d12fd49f30efc74f3503bf640236e833b5352d233870d59633d99ea374a6a24fc6cc10c0b84ddef13f680186c862658ff15a96cb925fac2f8483249cf9a83017bc4a8506cd4c695c88c7b514405dead55e7c367f8fe1ed8e529c528afeb9c452c6c02e1c2286eb87af5970838c055fbf12ad7cdf6fe774885c2a3c832170cd99cdc46c1c52314c51fad61eb481d15602b32071a69f55446eda781e8de4f004a99e67697df091dff54b5e75d74a5a5fcc85eb1a484f874d729e46d251a2963db4b04fd4651ed3b8489f70738692fa2519675221768a15ce42a61eb90c728c54078d92e6cb1af9edae86ffe2b4c0d0a8e52b2c190dfad052678a2ceca55a6b9e5cfce1cb2b3ae1d6844306ed0bef851499592304eafc202fd073ae08b2d0688a040fe3a0959d460efb94e420554ef77604c4ea574b2c1b8aba4ea84c75220c5abee520cf4090018d2bb398749c1c5f00e8b0c4ee7909586f4e7fb20175b50cadeca7a0b553d94caab82493bc9c20f3ec33c674cce19d2ab655147d76e5ad4ca1bd8f5289d78d5b3070cf41d3d8674da3247436b019cf31cd3c5b91574b41d8c9cbac68886c39c4d66b10b137111531e3efd54b08c21634fe1847d87cb51ff8e1265495920c6139c445e0c5f7fb2c87c068e73a98874cb2c3830efaa63871e1841e95b03862a3c75da39e79d1a58b45f96038f16b0d52f3d1dffcfa2a77ad7d031d5c3917933e0cf87133e297ff112bf56876887314d439fe7fb622fdc26a41b4fb224aa6e7d65d68704793f80ca41efdcffb2784c09e1cee276fd44778c438afc62d0b77fe4f3195870bbd112676de202dd9fbcc3d005fb8dcb198556c1645959b8988fc76a6ab9aa230d2493bc77b2533e42fd8829b2e249f242ad408bf3c498e0ab671eb1440fa2d474346fafc6c8c5c15f6edb5e1d51d1d9b8377f4ec5aea589040000000000000000000000007e248f8d79380b0ca2be1b3ae157df42fb1dd73cd8ae3cfbf880e0a6d5130173fb57cc71363c50a2ba00fa181aa17a1beb97f378fa26ff8aa4939239c8a023fc48650938ebe525ab6bafe256e03e79a3ad196b020ee0aff6ce422386e659d39b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004cd2f294355b70dc685d1b4cdd3b05087431940ee62d7912472984178b4c0e637234b90ee8601f98647a2dc6e530179d4eb3948637bc50dc677cd0c898ac9313f52e5077401208b8c0d7b90e028843966a8e77975848fa4e44a6841884fac3aa6badd4e49057a781c8929b9d2502e7f22808593d62fac74840ec91468eeef055031946c8911721633e372297d48bf39b37ecddb6d92e2c8d51d8fd4650f29b3563030ded1229f5f93412222d3f27c246e6fe1267949910fef3766a7b2df5bb80803b0a2f0c02d3712ec37d286a5946ce0143388d7df3df95b4e7bc8798aa6ecd64e82f15023f89439435f5ea23e8aa00e332887171c2da6cfa4cffa136b3719f25bf81032dc2ad0ef7078576d84ce4115d907ad662f71fd8910aa3732e09357d4e5b9e10022a53404413256cf167e1566ce5d51fa5e7a995c097649291dd7c721c68f61047020b0d6e4ed675e2a0e2ddeb8ef5265ce8f99cabb6f4b19f923ce22c6e982fdfdd020a8e13d01f1fe3bb63733dc9af82f134763083e818af6922f86f9aaaea71364202192222a7f5f32d08363d2a13e7e66db8525c97595d7b01eea1bedcafaae43b20301ccd4a992c0644a046872381257e63ddfde0444ec1eb4f5894c6de63a8c09a2e250ff37b14bb2cd2aa382e83362e7692f013ad71a7fa9982dbc6a6b2d528823d66f00b54ac7977a0939658343b57eef1dead7dbbd75640df7ca7c64e043480005248d8380c1eb6ea721959793b41639c5e4bf94d9716906a0e563a92bac68ec5c7615d9e166b18c285676a4e146799d6142683a8e41385ed3073e7ee18c69a7c5f2b08ac2a2f157adefac51548895c036dee7ea369bd1198a3494bf782271715dd202f6d8e3a61929096e21e3fd87df8fd7d6aae5151c90db4466f58111184126a7bb7070f76871f4fecf2f47b8a8f8e6d51952e2e341994c775765744c5a477c068e11eb57fe12e10d9ad50f39ecfda52f80fe420c4abe7056778022a3d3f14370916512edcacc4bc37cf87f571074cc1bb596300ef63c1791a6f82b3c2afdb66dcf228564e89c8ba5030e3d847b132d843ebed30927438fd8dc5d6313483bf35bdb7eda58f8dcfa6b0b0d432a1b0ed2fdc2a1f0cd84b877e17135fa3dfea895a484535c619fcda58370ce1a5dee8c7a6d9c0cbff5162f9dd2f523f3513a0d0ee55d47961f3e8c285635cd3f4451a5837e1c420e4c90b2dea9da54af50f561aa82faafd7aad7b0798d581a560d404ef5e292b1ebb6b4c42c0c3e9dc84486a204c9ced417e9a688b1930b1cf6fb5da22706ef5bbb6aab91bd202d5865fa7ec118659cee2c74b0a51b4d634c2b15e778ba02b39728efa422ffd58e20b826256b2584586c967dacdf9bcb70d2880ce2ad4269ff4efdb5a290da4d7eb6267a171fb03a481b149f8b07cf1d7cfea9274b439816280741deeea541378695d616d12e7088f0adc9abe718033c046ff7264784a567ef13b0f7e7a76efd9b727b902d9a778097879b14437b16477017ddf636016c262331658704ce2191e43a6ef2cb6551cff1b5c7fe75558d5eec1463447667bd49b3f9f09ddf77b00ccaa6fe013252cc624163f51f5d033f96b4ced711b20326998da8363d34ac657ecdcdaf4e8821109c535978cb34635a4272598a4432b0760620d9bb3e32e3c841ce0f57ca16fce84e228935ca12eb91712ad2338ede5a06789d47bb0e60a7d6b6404c1ac9d4d1125fa817ac2fef67f14b9367116c5484da864455c0dcaf635025fe8b5075cd0bf8e9365528d8da4ddae78410c0b9362b092931082a82d8f5d282d15123b0cc9188c5a722e52070d0789f633610d17b9bfd8ceaab5ea3d3462604bceb0ddc5a0ac8bb519501034eb01d4b724833f72d447be563696df42fd137ec23db2d6289365c7beb07faf007e94cb2e8d726a601b2158f320655b4b4c527c28f771ff95c96359aa56b4753595e70c0cfd5c2579524a8c4d3d6a4d5dc71efee714f0604ab0a4b80f0bc19a34c427c761317d0a0f0f7f4ba052f2ffb7f4a5e961f6c4480872f6842e0b57cf69ecb6d9c7dd1a1aa92f6307ac13af1eebe90ba29c1bdf719ff7964bdb1ea7de6e1d46f7b3b467d2b339194f1080e585a00a288ad5045217008feb2128764037ed736e4f22f1feca2a36e9fd4b64e2121cc95597b9b04d0dc3289cf84c7aab8fac6c7b92c55d3fd88bd7bcad9184b078b9eaf17f5496f4a92efa3c16ec5f15b7b74837dc7f3b8fd64ba19406906d39b518dda12efa967ad5325d5aae199ca8369b13805b4d9899923391563afb42e0c23b8b7050115cdcb6a324a444bc2926ebd4a65e28e5d36f17c17f0a6a5fc3409ef8f0ada4085d476c05ca71b5a077d0e1f410c6555a0c7b2246939adfc888eadb2a2af2a8cee0f007694479620c697dd5c1eb9b6405b562682589a608", "", 1, 1669333877, "4e0bca14bfab687a86c78b5201fecccd4c6c0aac072994a6daaee07eac1f784c"], - ["c5bcfa2703beb79e4a9091e469a2ecbeb8702b3e51892fa5e900a05cea488b0d65d9a451370100000006536a00006563bc3c4782a559c1c0763a4201cb328fdd4eb89265bc967d9bdb43bd2f3a6d175cf8da9a250100000009ac51656a5251ac5165ffffffffbde0364e9d09854b6caf19b4a4bc09c86ce455578b5058538245c6b40354a31700000000086a00006a6a6aab650a95855204effb17000000000002acacd54ca80300000000076a536aab0052530f9c84040000000007536553ac5352ab70f5140000000000046aab51650000000002000000000000000029425105000000006482e2630d3c1b540c65b239cc10a2a6951acb7b257fd6ff86c1c543fd86caa7a4c2c6f9f802e005e43e0a6f144a7a62687b42f40f4e569d66acdec06c34f20e1a5eb6896f5cd970a4552b5f8289472ca60613b2d0688998451b2a2ad8d02fcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d195476790f30e986dd5cbc839af1f431afb3f6999f0492de90da90c6ab31aeeef3428262394fbc6c93f176f7fe001f830d412194f57d840edb9481bcef7607a59260225546c8c3531de5f212447a6025c755e663aa4cef6df2e29b3bb86766f4be6e4051371ceab1ecdd720556441ea23c8b030356880dc4c2e07142b1cc3b03177a4e63e9dbe7fdb5fa5293e33182606f8389eacb1659621ecdae478c4d77400223e1f5eec2ed6f2bbaf0810a24d7ab4ff7ada8d2f231fe06761dfda9a096fb680a00023bc9f2adfc1ab8d59ab1d06af0d84d2ff8f88fd936051df1aea85fa332d21d4960d2cac35e977a51c8a081592cf09951d45124d95e0c4b9d524fdf3acee10208e4296c1cc52430ea8a257f8e916150aeb1bedaae81d10ab429edae35455bf70201410f1ddb04369043b438142586375025b36c43d3dfe1ef87c920f6f867fb350207fc03c5cdcd084140fb1fd87c81a7a014576eb81d25356c6e593337d8a58c9f0302280118b8ba98032894c0ca067f95fbb0a7e746f606bd60e171931a97cd602b0322ae62c7f71f0e8f3d33cbd916cfcb15bd4565858284a304d31ddd79e9266aec5ff1567b96e48f810b8dfd90025d4a042d06422ed7f7035a79a0fc6d7ec977287dd96027973cd2858ee4266fb3ce0c16568d724c3dc86f0f00a66ff678cb5ce00c8f52136055ec0b2f3112509dcbd2f255569278e6975594e8d4620f39b4bdb16b5938c454c3540f89de85aec0343c3527354fb79830c4a561be296395ac54194f670e5a7d2bac6e9188063a9e48c54bf6bce4fd9b451c31e26452037fb383a4041713295ac899adc903de3d65570aa4e89e806f254c5930f9c79265a60636b0a2608765649cbbc03de190c81e670fc19c1422eea622191b192d584eca4ff3eec8acd844e0d165c01b6ae77c16962dadce994a7b185542eba7ee78f2bbdd8fc7137765e8f4c65e44a865ec5f6b868df8674da0d6cffb9dbcd7266b5282a9d57e8ef287310f5ebe60e6e105a349d5a982202c76f2a493b5fc823b82795fa4950720d1fb9974c7f6bf13d776cf4a6200169aa053a1118cd558491e4d4579318c762a341cab19543a6af8f0d165011c4a3ef2900f461ae9cea3c58580acb9c5464c9a7e1173d1e5b2a13004701759016d92fb2f0211faab39c6c92aa42076476a54bb4efaedf6af79492be374576660dd69898f582a790e37f90d5b0e950d0ebb7bbeac8805bf21a731ae5fa89ef207e4d581d428fd3e1256767520191130de825fecbaa25bea41fea06a614e6e9b61e67847f21d1ec2f05c637e125cab490d4bb307421c6b39f3c536dbb0e965ccc5753931ae4274b93aacab1a1456f6fe69c91021f43d1eea1eace6342bdd3e17c4410bfe53d4d41861985495b0d289ac02597c2d32dd69126a926c01b46d058e3578c6a439f1e48a411a2ee414e47fb2850289cc878c18fc18de2b1a2b72e6713d8ad91137bf30774bd7e6126887c046bd741c1d65b23f5d1f331d0162313ac72b48ec585e6b8a2045a88a355ff82fe6e08cbb6bb5a7581b46903db1b1f9780ac1f1f0213b2c955c8f030deb1a5f6c834ffef70131e41e496c8022d3e3800794dc0884393fdf0ccafb582b43099df1e4fe0657a96a33c364a32c58003a4e5360db03e94a817e51d07613bf2e4ed7c8d3c7ff5304426cc44af3f01f5f3714c5b5fa36c18ec85c78ef5bd8a8a7a5acd5cf09a209a125a1a6f26fa4ed811cc388a9a90987a388cbf83fa1f8960ea16178606c031edb4200b8badfb1d77aff0c4fd6ca4116c9617af7c70f2245026c3ee29aeded6b9e34526bbf995df34d770d65d268955b8025d7d64f3222da5c7412ad5584a745f15be53b7457dff235fa8840fe2d825e6281ea814102e5bf77c796080062418cd53a0d69be78d42588fb43cc7224eb30f58b44fcd84ae6b8ce356a9c83b2dd8137b9e8218fd8c8a265f9ebdffe87b26c69e5d36ab85c66c781c0c32ee9d276f87aa7f2914cdd7afe05cb7b587a7841c1a8e56c5e65e42ca6071f87dc0e805e7b0cfc2a331635f900b091f95fcdfe7ec2221510c48e8c66f7a1fdfcb2ab9851b90a622f77ac8587b896cfbcaa0f847e9c8a282b2465060293fd0393883d35ae55b367d11b572bbe28c80f3fd653cfe94cd05b2a4e9212f56868733868482503dea7a236c4bd8d96aff6201b03281f1aae9e01c0ac12853fd50ddd91c18e6c80b51600b3ced841516d3fd2dacd20ccbe41685a32a8f8e56333f99258c631795165a3dc34e30ce48ee7f545c75ded2de0179d5062bdd403000000000000000000000000a6c76eb135f4c881a7d8b85a75717a016af78f47c6ca451cd8635c6f997bd97a036334ba00f04679139037facab6d49e6ab2b1e7d3b186b2b0738ce16a795f2a1218e416db0b80d20abbe228546affdb41eed6e20e4e331c2ef18fff35eb2f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d03dbacd926f3f6650f7b6d0ff359749c4ff0611a88f3675e2ed339bce2ae60d1fad07a846c5270b525d27b08f93643291f074ec31a4c27021897a0fcf9ab3fc97c23407517fda4cde02eabfceae26753b1d36731751f30ade2e8f4fa79b74f7783242ceaac859dfbbe5951c558f42f0ff18203003d146cd3052911c53a7f8030e6a884e6a5c32d3450f681aaad19cc6a8686d310cdf7616c227289fbe84a6c1031da3befff8eb05785af83180191abb69f05d584532f7094c2e61aa562490c5f10a17328fe166ab59ef1814be56c091cc57caa8eee740c03a8f16cb74eef580b6a01a5e59768d3f5b5b162d13d8ee019048a28009ab97ec9a79e80869236db764f70200e8bc59ca0d2b233f986e2a562ff15c864f530c4df6a3bd8a96ac85a7a4913d02292527f45377cd80634769945055f44783f571d066dbd3122fb3131427a11b4b021409b570e22ee0ae745d115c4e78c7ea57ecc576b7c82317f3f08e82f30dbe18022b9ecc11498e7f051791426276c0cbf405db76ad5ffbb9997faa06b56474d27d030299550a79a49058d0b0867c8fb39eca90c8ec06ff299113bb8b659cebee2a901845030ace259fce623a4cdd181cab678ea0ef1a5fb071b687564b8802198b306c7fcc6145b358d9e6d386f4c544a90b4a63582642f5c52d89d1d492108df5f7635ca1ee22bbeb119c6fbfa5dd5d42e07a3e63e34d0c4c314922d33653657ee4936173e53f45c6a881bd0ee5eb96d5057f1addb2fd78f3c6b34729de8fbb7a40aa1e19ea3a9c6d424391cab85458f47104aca7bf1b093c1bf0e9d83c1d8acbbb21e6760e4020c4cc800655e8d26a283a429717dd5ea90a4d9e1f5c179f5e8154e8f932f5aa2a652a0cc280d4ba54889d5838dd69521a643caef1c9dba3bfb394f0fdf5861cb459a3549b5b65a6a96b92d18bd31deab247d2259f349a3d82793464d70f5caa6dcd6961f1b2c83d4b981cd2ef22966c19c534ee94160828ff15e528149371eea3668a26fc1f86c78b651f1bbb62c6d38313876bf79954313ac9316097172b3df4dc8f53fa9248783cfeacfe87aac91a6e2f64f63d5cae7023eba9fec9bd172a88a6e04d5512f6613f1e8d9f093b5881ddc7e75961b2fa73c9e3da3c7dfac0e8d18785f049a37f2ab9fcea920598b41a056bbafbf0a4d5bf32cd809729ef27934d05df9ea15675299b0fb21ca6e461ce4099f4ff1e5d4633874dbec28e13424552e691579ccc388a0cdd35f05c231cc09244afcb90e8c7ecfe73abb01a7baf1922b719ab582ea69a2a5039bbc1c513f4168bf860c8851211bf8a5d2c72080780b03121220eb09cdcc3917a1434d717bbff99f30d2b03b4661316ee0e09802b372ae2fdc1a4ff1f327adcaa7c33cad645dff526bbc01f53f9e953bd3e1d43929cf1b511b12c66adf9592d463b12e3d58c90ed514ac6301ec86ee9ff4cf9a5e87198ac61eff77757d3cc048088c6242a3233a94fcf47e6670c34108041b74e29af75b9533b26ae87db5c5c4529dbd22102da1f48237efb041f7026338d248c3b695a1227702cd941b9abe09b0a043a91c7cd2bba1b459fecb9f59cac9135403dc9c8cba965ac6f2ef61bd79d6f0f5e020d64d41adb6c4cca23b581484fd7b39ca9d695a3aa13dc341460c4ddc1f6967e53f697796174cbc25d0f146076e8c4e295e5cd5a27214dc4e7f6ba766a708518f07bdb89ab6f3fb3f3338b7f4eb276ea6238a60e62bcc8983387c112ba99031ba7062ad9c55ecda9cacf9c32a646b2657a72b3137197716cebfbe5d1c11537f5253ab48b594e651f79dd5eddb4641e8fdad71885b98840d171a9866826889837810d94187c47f43fa0eaa2e50bbd7fe25fccace97a29a8920f410cfbbb8fd2edde5ea1a0d28d418ca14aa1496172742b59a03e3c37c0612a645aa2f392aeeaa3720f8e36c7fe6414f555fac84dd71d449080058d0214573399731036a5112c3b77440a630babdbbb29814a6e207c6f689523e83bd61978cf1505f960aefbb3accd7f4b81e9d69136f5ec1d0a980f42c31e127e048ddd955b009e098158316f769e65cbb235fb01ad669bdfb51017b4094ecb828b46f21546f584820f50b95ec54bb6e8e9bd7130e40c006982546a4b96bc7702ddcd635b68dfd39dcc1cbc8487c9ec7f585fd944bd1829a332a15ca8cba520c43e2e0c981a21bef665d64be8dc63c2f0816b0610ce4fe13b0dd2c1e45643f04f838f419208dd63087bf5284387885ebae5d75b5a42f578e37530301406c08a517f0e824269e657ff478c85e7d6cbeebb7577235f2eb446a669a4a458278c14faa2b6a8954feb2c40b99f7cc1c623b6b062d1a3685a1d27d616c2985b43d7e24e2d3cd628668656a06ca0c33fde815b397565ca414f286e730fb1dc16b6e626d42afa1dd9015d8243cd890c", "acac5200", 0, -772939596, "6a86d4e2e1d4e4fc3afd29dce973170854f0004caf4d2e7f5db44cd25f512302"], - ["263890df03b63765c8b5feccede7775a02cebd40ffdd4e0882751e9b374c0ab1842fa9fa7600000000090063636a005153ac52e57118537148f1f44246f724157cdfe65385c5b60bf3b3e9d7a842c46c0563c1b9058914010000000252acffffffff5e9266f6835bd86adf4720732b5177a9fa0fd398f95203e78913c4e4c44fefc200000000025251ffffffff04f1419701000000000865ac006552520053e37cd70200000000016531f874030000000009636a516a5365ab53ab9caa3702000000000552656aac52ab8babf5", "", 2, -1413922606, "acce0285bd72f15b6e6ee23f73e8e5cfe91ea80703683dde2cb1dcabb83f8f38"], - ["88eb4eda045d62cac6e5926fa694c6e720834df880f3129c22e70b8717cd6dd1e62a765f650100000004ab525351ffffffffdc3817998a2f31c064ee03c0e939dde4c078b5fea9458dade1537c32062b14120300000009ac6a52650065ac6a0026b5b1171eba67d16df01ed47c4a83d1aba8c71248c90c839bfc1a515a6c314addce7653010000000963abac65ac65516a5164d9b577515bf485124f5039c4f6d57c74b98a03bd740ac200b6726f7856c2a20182378200000000096352636a00516a536affffffff01f821e9000000000003ab5251fec8c466", "6a5363005152", 1, -309204392, "2aa3305a9b7aa4b070fd9d94906e5fb980ae1c91df100ba3a2518f81b13b0f04"], - ["5e6292da04fb3dc6f44b57189b1c5f3d1c0c504f532449c527837e0b20147b9f07d906836b0100000007526553ac6353651ff1615d359b6b5c13282fb1c5bb42d52108d168fc3a61ee312a3e4f46fdb348a5476fec0100000001abfffffffffb112dcdd1c5463805fee65880731849275a0877751ed705d98dce7507ae077a000000000853536351525152acffffffffd5cb42ae8fba9de81791981b897dde84d84147f9bd73d55c46c843e9056ec61402000000076a6365516a6a6a6b0b86b6022532f8040000000009636352510065006a633e3fb7030000000008516aac520052536a00000000", "52ac5151536a", 0, -890669207, "c57c367c4dfef2d4236007d2ce97f455fdd8f188d18bc7285b829868e7d745e4"], - ["16be321103e110f459a9ff26cab3a01d49926dc7133a1be86c3a2c2ad2708f8c11dbed7b18020000000765ab52ac0063653c500dc73c0aec20b7541399bd79d2ce72b62c66665289835884a812d1fcae8bdb8d5bf703000000056351536565b808b00c126869a63a72148d82243b7f2b4235f15830da309682588d0a98aca5a8f583170200000009526aab00006353ab532f010ede0270aaa2020000000005535153636553bea604000000000151f3ef25b501000000000000000044bd0903000000000b8d659990a03a6820ee963160d87f5e508032ccd28bc25c85aeb6228a490b4b697f0b2ccfb10835335c5e32a0d3d8ce8b8bd7b125c53d7879443872d67b258efc93a6a8c5ca4f89d53c83ac6e14eb7ec2bbd6d3a36033cc8dc876b5c5e8ca5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8116f95fe21eb4d845f52d6aaba514046ef81be06d4df29e925e7e5974433bca2182cb7a3834e871fa8f7bfaf2a53eebf36e18e6ab4ab4507c030e345ed9f2934e75eb796f401b561797cf98759526bf69bc99c45b1dcdde8d00fd42aca177093b2d041d154ddd9cb751a910469f3515ecbb9d9c6f8a2e6a8bccf6d0cc6c6e5020c9315fc080c02ec10e96e33b352f54687f60be2ec9974dbc022b730295d9af802109098db375456b93df2e8a5e20354c962797b852f63d7d36fd2f2ee82d3d92e0b0abe143fa6a4c480deab66aea8fd6f390e3ce0aa1cd213c4f6f04d348abeb367264fd5d3929f6401ae3f9c8af9b74d0d0af7c6db745fa5de01d533b3e002e9df03303d0606bfe92cc70f42780066558d862e67b68d9deec739e0a885accfc508b002125f682c49fa371d51c326c7c0b472c2ba49f192e773d4e0809856e97f62bc97031ced69db8be5c52eaa9446b129e7de76eeb8defd8ff5416fd97ef0104ad0ea7e0223181d014ba31a7e7fa6104c0e35194da377e9e8d829309aea0c6a62000e71790213ca8d889d22109816f5b48727a6553c948acdbbe920fb3584e9124db97abadaee969ad1ca7f5ffe77a123c27b5d429fc59a19bc183f56a2abe6308368f563b0271445c440458cc20186f4f67969e67db8a3e435f2aee695fb25fc7c5e1e9cf370944bace612af1d2363d6e95f54051be46fbe4896c8d2d00037f937a47fe06612aaf51ef7df8e40a01da36c78769297a023698249ca4ff511c2f14c80fa7b989c2419b4b0054faef24b8d6bed728acadea958a033380ab5785ff32e44f5beddc9de012253102a3543ffecfaf8c711933ca3ba23ffdf5084d68e16ff210983e3be9bae3b0626b6cc576470ed0de35ded974bfaac841f5fe497720e2660917965063547d8ef8cd90ffc94ee4cb735ec168e0cc819d6a2cac476453effdbe0b810e8c48d66adfe300c0cfa6e281fce74fdadb163b0f28338d337745bba2a96bb1c9fcd0e55284ffaaad0f745d9425796b6e62ad9f0d863c774d17d106c95129cb7bd3862f2e7c901f63bdcf4c179ba95c7ed20b467755082e4008dfb438b8f03e93a62680c42d8e3478f38a65929eb270fa0de464868dc1d2b8b62d36d81c1ab9040df0304bd8d62cd5d8bf582139985fb97a5a7bc4473e19664f09290a6a01e6e74ae538f1d9efd1c10a11823bc18b9605ac398b8d24eb49a4ca50729f97a7a38192a709d3c95d9719c373a2a30472880ff97a8931fc51929d6e2727f9dd87a0460a3462f89d97630672423d2b17c2afe665bfc6cc3a94d30407ff36f377f2db0a0229193ae20804770bb10753b230a09d44c084de022237c7dd8e63dca3bd480c22a113c00487609bccbc6cd66f7c85594859beeb6216c51c7c202f50aef3c92d1dba45347585fcba6de0e685fc821e9cc050a3b0304102fe54090b0b926cd0fa2f143731a5df8e99749c0ac8dc6282dde57d94db1dd742772aa79345a387af6ca59d1c653bd6cb45945c8fc6719a0f7548465e1c6bb98b146e7129aeada968f60b3fdff6a1476686e45495db890b61a2e8b297b29ff728c7af47037207188176a45b9e6e094a31f32af9967c0367e4317ef8975197c4d29151e2939b52eac7fb16d287f819c7cad54f711fbe5bd66932d98a227e8054cd566c4abeec747cbd4e19541e50a9e3191de031429513bf6127b0261bc021e5e0a99f2bb32f029e7f3a4a2910ea37dea0738450847f0d00dffc5de18c3b7a31d6cf798969f6c5397a15cc00f38c6ba0599ced3185ca0f6af4cd22658c891391e8b0c9db3f80a22416e65be401246cac309016407c6a4f4156d4f45e28fc07dd2191fb72a65cfd304799a08783d64a552c91dcb2293cd7814716b69dc0733627210ec3f33d77244f37748bea32d1a0737d47ef539e385eed24fc392b28ba457d99b8570131094de40f5d5f2b5464b3846d6f78f3128d777626e42c0319a64779508b66bb3040eb0fc837f7b1d87e0a2c1bccd5af6e1bef8dd9caa24a057ae45413aba3bfcdbc548162024d067dad029dd4ca2b10619ec1f8272302d724df0ad527fa4d986d59c435736f8ebddc6fd80d55a85794001a2a4624c6a33331438ed936693dc40cf7fe2293c22fb2fcad5d1812e9ed8c07c7a1cbc4ec5f9df621a13b2fcbf7ccf4ec4e071ea9f0b78525427d0597bffc9634cbec1239ff3ba00eb36ea32706cf82345c1ee805b3b6d950d514c5ec03672dcb17d5b7cd7a40a377dbc3b34cebcb859c16692e3a9cc436df8a300a87a9090bdda7bcaf821f313b752ad25d144e19bbadee2e46164450949a423fe4b0a2aace7a84c60d49b5d7f0ad18115b85618c146f47aaadbd9f091a87b6e05a0540ede37fe22e2bc91e578b1d0356aef05db5ee2553a1d978abd67a33742eda58f11135ad9a1a72be001", "63516a6300536353", 2, -1628321804, "b374c62b60aba0c9688c8b17cd9d1ca982cbf857edbe97169dc6a77245a11ee4"], - ["b234b0d6037f55b5da27f9b9d6654ef6a53ebe7e569e0e882b6bd680abc9a11c79e0d178b90300000006536a65656a6adc4b200f0b40855b9db15b3de063b1c84212ff20c75c86a0bf03002c981f6423be10b6000200000001abebde87035f5fcca345a76d7cdde9ae9657e1f063133e9069c9871d20bf8b9d3ad4fdfd7f03000000086a53516a525365510c1a858901df694a030000000000b6c269d0", "", 0, -482461306, "5b114f3090c211d738ee8b4b5b36e79001bda57c1293f363c67699150bce77f6"], - ["2d457d3f04b3baf0bf8b1cf0b0235fdfcffda11efc44fa3994c6b3f00c2beec1f89c5d92ae020000000151ffffffff1a9bde70521c18619413c1e93b15b631437bb07b72598799aa2796e3398698a50200000003ac00abe6b41c89eac0ad8c08a1eb1c879393296a9ac7f6735573b23fb6e4b04647126c84f576a10300000008ab515153acac5363eaeeecf3b749c9f8c17fa02f80366456ebd698cbe8b4c5aa00f6645d4aae61d5b0d277e8030000000463655263ffffffff04515743020000000000b7e40d030000000003abab659575500500000000076a00abac006aacb765e5000000000009006a636a656351ac6afcab1a3d013eb12e0500000000000000000000000011463c8913f254305e1066337327e30994651e4c0fe0d97360b2f0f561004f837e134a4fa00adb7008ea40ab8d2f101d67ea18863b8a84421d0bf07c07f9406b7da84334e967c55323d64fc072b937162e75618109d5606a198d96d614ab2d80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004814118024f87fe5fd1e291191ca310fc82bbb2e223f8d6d26b5dd6ab423a6f82661e5bd458a323d59f1ce1caaae2b429a5a5cda3512b44761d6ad5c448ab58a36b8b7391f7a8fac7665d4e75fc45a206461b4465af19fe5aca17cb3533f26d8bb8e7b3694fc50606b7ad1a0e2ac62eaeeb410fdacde4c2378949dafbc7a8e6e0329bb6563c71f2f90f46e480e8d3aa11c09cd26af1fded5ddd322e98ae49ea2650309e2744d433d173772bd510578b70aadd1a53177dc942800dc8f67da6055ebc40a065ba358c48da7459b63fb7dbbec4141ea3998bf619c33077a1d3dbc0e9d299311185756858caabc079d91254925db1b19249ea96c7a7dd7cd5052fb167e0f630225dc6a2920875bcce5f6dfade3264af0c8939103239bd9bc455774c66d3a47930223666df287bd609d5e2dfa9eb11af755e6ee794836a739b59b25d57445bcf1b50313065396ccb6c783ba72e20c429b7f50332bb7dd54e2637741a2e6be4d7b0d2d030dc1d432f2c5f2ecaee83ec90e3e338493d09586d217b32be19f28c46a73cb9a022fb5c3579bebd772a0199b66919f23bd992eca6237b445a9a25fd8496fa94fb4dde18ec49ef234db53b7c95db33c0c61e70bb2fb92326e1918ad755ce7452243b1967d91c656746f088a4010a572b67343573dbc89db99a0013fa57de1ff238273fb049bded637cc1011fbadbe8d28d931eee79f716e1f43bfe006c745ddea5dbe1b552c8e42df021c0d5df9120d599f60e26eceac7a17914bd947a73a39bc181acf131a7b070c03a7b52d49cc0a35083c6344ce780a1fcb8614710ca4b2cb1d7308fa69854a7350aa952e5c7dcac33115483b796dce9adb1a4069d5cc203851840bdcfa668869e572a77f9464f202fba68b9caf48150b84dab7d8542dfa2f7aa82e3fbc9b2a7199049c4eaefe824a0950565dd2e2a0a8a9a7c15457dad010e323e134c76fd8df0fd910a9960847c077bedbae59e4111a0c121642ae28011ebca23e57edf177e11524ce23ab835bf2b7281738ce4be68f2a1f243ba1cc6e807a2986a8434cd4e723a157105023b73606a5fa710e22855536dba7fe4ceb8feffa30f0f78535cb5820e00e3fbc4215a482bdf84fc90836f13bb8f247437f5a68af538048273b7606f21f9cb438dacefc6db881017b5cfcd54068177cd5e76242bb12ea06606cc13cc65136dba8500233e5c6c5dd2441867c9cfa98eec8be51e9ff88aa51ee884441458d16d88890a9131f4909350d3226c3460f129e1e816a8879d381567eacbf1b430760209050189879680dfd3a159b2b6483aae1aa14625c401e5dedd1081963d01a754ad07edeaad5c06006ef0f774d28903025b82c6272ab8caff57b32fbddb28ff9afbe33a7c75999cbaff048b4121ba8bf1b195361a5bd902f32311e0f41105d49154b4db2ffb81e57767aec34831dbd99b9551a2f794713b89a1ca7b9746c220fc5cf819b2add29fd5c88e16863d41809e64c01cd956b5bf32acc16c9f4516f4f48c17ecd14977a46d3be2869821e9814375922e006fc70b7d8dd2e7907b6eeea4b42ca30b8f729af6f88056f7ab5811402fb27113200abe6833936cc887aa029bdefdd4a636416c702c2f78376c8dfadb12edc5801e47e5989f81986e92c7f580717fb94def797e59d8b711a0a416f7a198b07879d79cf526e280a6e297fa3009c53448158c932ddadc8dfababb4561a725f8cbe2a18e5f2d7ab6b246e3078b02272c01a9a805ee49ff23ac1990bdf5e2023b1f44e5f26388c70f2fa0259a5239e8e17922c6c19d387db14c8bc33c6f4a12c8715f7a68fe5920a5c6ffffdbf9d8766b662f253d2250fc24fe79f8032258035f012272d9b6900438e7c9b76b20f3bd52bfa09aaf26641e89a710dc76fcf385d6a7b08a248cfe92f53267e0da517dbdff7ce9241ab7455f9c5c7a66a254ef7cbe031f3293c96cabb0d342f1a74845abb33a58c2d8428b67817c14ed376aeb57c422c91704417c561454d8adc45401999c8c52071f3c63c069c03a453909a7421473d1ab6622a9482f6e446db5367642df97c249ee94d9bd507579550e0a61f2034628568fd40ebf6189167d8e804ba9b0fb8b5214e9dbe37206d75f18a78e9994af9f9cb26ca7880500305c6ac0f55f3ee076986a2480b39c6153cd319ead94325e30f53f86942027005827b716c159b251492373cad8d7997bbaaa3940a0984ede2c713cab6e2b0693b34100522ae77582eeafa59d5baa6f7a3291e7e9f931bf6950933103f4e1e1787406b93e4ef9d7ddd1fd96956377b945222e2a04251765fec2bae64fafbb77a0b05d2d2f7c2b1b6c1b4cc39013aaf3cb07b4ea21903be20112df1b5fc370978ae6971b90a3235a719cfdd1034e8a2483b4dee81bbf8aa2a2ae26eecac81faee46e57f1abc3b226099fa086405", "5253ac536a", 2, -26994064, "cc32ea971f2108e4d0921426b524721f9aba2c5d1cba4acf567005995272ca89"], - ["923f05a001de0a4301f1d4b2fd4696ffcf4197c10868df2d71cd25d82ca4159b44585c34a4010000000651ab5300ab51ffffffff01292ae8050000000003ac6aac00000000", "636551656a65", 0, 1477214083, "f0df97654015ce6dde4d13f2a575430ff5319efba996b6d45c94d9eb56cf71db"], - ["8f869c93031690f2c4fbe32e4b1f0ce3b36c3455d9316be1d7875a118aa2269be3d3669e310200000003005163ffffffff918f7073726ddaf54aba7642883eff457f4e719cb08811b02bcd0f8aca8a1603030000000252656f97efd5113396d7449d3c513eddf94ff66e189444fe1a55b5d66552f1fab47bfb12d4a90000000003ab6300ffffffff01f40922040000000007536565ab5351005af2c5cd", "", 2, 1367017162, "4bf65801eba8506064124016f6aeea99098e98a4e5abc6f1f4ae914276c2ed3b"], - ["751d5a950165dddd3a1e58242ebd845d4a8bedceae2e4d9d6a3a172a86f3f0c459b992d35f0100000008ab656a5252526a00ffffffff0207b69f010000000003abac63434ae3040000000009516a630052535253535dce849c", "52", 0, 1130715713, "d5b83082169ebc6c6a2def42c3e2503e4c5e606263f13f4039cfa43a9aebf58e"], - ["d1f299df027f4519d6865344bed835af1fbe6715ff7d2d127dd92016aa458a549f5f91f1070200000007ac65ab53ababab3fd85818c92f96a6c8c700ab57588af1d5b602d31f74c8f88dd15655bbc92a6ef02d54110300000009ac5263acab5100acac9ce5430d0375d7910100000000056300ab52ac7918bf050000000007ac51ac005153651e9eda050000000000cac24d17", "ac6352ac5251", 1, 2067075260, "3a703adf7fb4d96d0e97c8f7e60e2c82d5c04e75015a688ba1ae5f485d6a0b06"], - ["5b6bdcfb047bc45060210ab15013e620c77a067ebe2f3615a290455ed9809ff55e10c894a40000000003636563e37f71ce833882fe9303bbda640fb60d9754b058555672149a96f497e5824cdae6f946cb000000000800536a5300656a51ffffffff211b2c1702ff7d8a0f133a6d100b67e5b6b3702f07a7ad1294662fb3d200b71902000000055263635263ffffffff7adc77ca5210cedf6c5511d0b6a748578eb781d64aa5fd045af35f4d4eb7112c010000000100ffffffff02000d51000000000008ac6353515200ac65e7721d000000000007ab6aac65ab535300000000", "6a", 3, -888625896, "df0226622a0b8c9e23f7ec4fd834263a9edf664db46b2e8089408b7de36d0806"], - ["5e354c320285fff7beb8258c34bd0159897491b21339fbc5c6e1325d88aaa6999c72b43743010000000453005200923704f97a14df059a05a53405b7dd21eb58e7e02d8c5082bc475be307d0c2d9c22443530200000009536a6a6a65006aac63ffffffff0293a4b60100000000096a63006563515253538d58700000000000056500005363a2f654ed022989e70300000000000000000000000049eb7754f96d89e9d4f42371699d18ae98bcd108df702415288bec5b1b670f72f00e7481173ac94542bff189c9c149e38efab666809e412436f97c026104f48ee922c99b9e86f30ea21263027b8a9ba3b06af0e39ca24995abfcef05d9401e5f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1e0e3561a794be12be4d654e99a4c78ce5d24412edc46fbf38333013c000bc4831f5640926bff3ef90bb11e29d582d165a8522aab49fda77e8a6bafe2dd658c1cf61274591f071e337f31f488269f2836055d6b68d594985abc4c67f20018500841183110ed3f9ff256c6766625473f435087cdaa2290d0fa25a06638a17e50032063205a57fed257a1211486c6792e8927d24725cab9ed5ecec058c4913162c50226425252aac7c5cc69f4a3227cb113b855496dfb60c41dcb1b6b7be08b8cbec00b122d80be037ac46c2ffa62dda1928b664ad3814f7077ea4024e3a587eb42318a1e68fba43e0342d6eee628bc5262c47ef40bb27b9abbff19b7ffa52dec0bb5a8022e113320366c596107a7e469e2ba913562bc5edbb57fd050c96df285db5fe4d603288cea501557ee450def6f71acc28429132a473c181799241def27c25988e64e0303c50eb9778079e86d1f21ab1c68e13c049401a9f5f7843c03df9eff309e4173030ff156d0a4291dea8b5bbcd002d5ef7db0b3d2cee368e5b278ccf172d3d78323032ea1663a547c18cdfdf5a1d831649e0ce1182fed32b49c48dc47555b4c945a36a40112af1b50831edb36760f2255278636bb17b6eea93a5ad6fc30c6e403ab52f47b8ee2c82f0cdba9f9be455328805e63444bc4b5208d33a87e18ec15aced5624a4945a7ee183221606526f751d6f2d9811f757d746ec7c9436efc18d0930e02376b6044762f393972a351692f00dc1e675210efc93c8b867fbac632fbe209d9b00307f13f7f9ce062c0d24208d47994a9d5fb02260c6c60bb0b0117df3fa61707f790770cef83f8933377da35cdbfa74c81365114a1cc11aaab8f9c60bf8534d7113ca2886d6a807ff566ba4b2a883edde88ad1ac6b20ec9b62556d39c551433dda9f87eb0bcc50f8daf54273f983c5c658449d99ffd7ff471e474acaeea0b71ffd08d31cd4e4ab4e5222fe1789beda3ab2760eb13f56a024726a0ce3b430da72f1f40e35054f6de7214a447c09b0f719fdc8ad79084e0a947cb381397007d515f705ddca587d56e4bb367d41dba256d40e177b86c8b4935813ee43698123c4c47b72f9a58af4cd55eab62947bd6ec8030ec8385b5691db3cd7b4504111ab4be3f41a3dc16c0d1f8792f54050a2749a1ddd24b4f9aef3abf9f3c27521b88916a8788be48fb432ed2bc23c05f87d353512d87f2bf00cc32344272db5bb51b76c45329c2f43267a1c811a4f3f9ec01323a8a033fe483b21467d04ac13be856bd0556b7cbde8454b7bbc3e2a0b837caee5044844898a946d66017bba73f04c0c3bd04542bc16ee076e1fdf68d56f522ac56d7b47111b3cfd7176d455a2d8f940a4304fb4b641ac42560ba59493780733693e8ee99229967afa941e89dc3c35d907ac6f5e1d376323d3ee5a1c3417c32df969e20a1a1b322e040ce1b94c728d4bef1660fad46e53c23b032e5cc9cd758d44fc2608a719a3defa848c43ef4353d3e9da6677500343ef3c2fc3c2ec70cedc59e6851fb878ca291d0380d6e3201292d892a2b8798351d608d0ce21eed250a8dcf8ded5dc5a31b68c0fdf5a28f5dba4d2f03a757fbbbeb3435a1a7fff1ece97682bf3ae7e51d50280181c00799bc22bb86d320a605076cd86b0c22faf8fef0fd899a30ebb01bb4e97e812be0faebabaf9a179846397964350569cd6c16d8fbce627ecdc5ad5dcf31b4dea0c00a20e74d7e6b68ca04c11509f712fcb73462ccb3763696c5699716a58147e80af762cf5f46045e2a4f07396c5122c5c665a02abe8cff1c9f73fd4ecfeda626092a9b3507eb3d143747ad703c17532f21fa758393d7e8851d9c327c9bacd883ff282d87d693afa6922bc550eb54534d08005d9c70d75dd0105bf09c41f3493661d18ed38104633749f9425b0bd9e8750702f8b375e36401987de6ebad2039ffc53fd632b4d6f526e0c59b0d6a3afcbb0b1ebea60e10aff9d381aa9a69569d02c256f75995453081004da5f75c5790d4a741878d2d7308eb9c41efee5e458bf112c5a111267815da76c6b5835cf6e37c97ce107dad926d3ade0e2616d08fc9dceda999513b6aa2b4cba8483746b2878786b4272ae35b458cf378095a5674ccb68998f0425e92c71cf47ff03979da9e132f24b673751b34f543ee036b3a85f028054cfdb0f758f60d4a4a85b7361964ee0b3ec8804c13ee624ce83c72f490758ca630a98bd60b904d324aac2a3d44b927c1294d76c4421fa0c8dd6d1f196046406d4b609f1bebe7aae67224e6b6ed15ad55dd14de50f6d10000000000000000e784b60400000000327e2f48d2f989a460aaa9bcfb4cb5eedafe65e2d3b34345fa6ae6ea44b0325c8883d31395bafe8f3ef5eeccb500cb617f5bdab9b5471a9fbae3f8f639464f90d77116f117e85b2a6492e11da444601e805f409dab7c8a52d0492c6c256da315000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001150e9b253c2e0a86afd0d73806145dde681467c2d9569ccd30a164aa034c3c77cfb612d7520c06a5c7fb7c2cb403c3bfa70c1471da53c3a9e33210678cd01a76a15ff410f17d3651af4a52c114999291e458a55b804bdf2e38b099b6614bf6ef88920ae88fd1bc2b1168e3ce9d46bc7a96d7b6f81e1334482977675f7389602022f2367ab043ece25b2393d48f417cf0af4cfc5efa8502a63ddb7bd0016f56f5d032370645e903bf26c6a25a67a3f775a8a143a1119993f8a3979fdc9421d9450f90b08ac58969fdf6c77f74be76915323e69e3b38c80134d3946843947d5c646c8fa1b711487016e961a04f8d9506dbe659e545d1608a139ca3d4e39df88468355320204f38e767796184c8b07d4c5ec76e5e59d4a3ddd12f777d1cf8497b5bf8bfeaa0310e245d60e80476a0e62c240efb969c5cc55fa8803cc914bfabc4ccda65f5b3a0219bd4ffcb3c548c1650657389643e06902ec741a571584b3a2cb25ec1e7ab716030a1400d59ffa342227b5ad12e11ce620cc5ea3d7758bca44d886a1dd5572015a020de28b533be263998c2933ab9e2be88c3133622348a588e65a0d98dff3f8989064d2ec2d2e7bdaf09224641106b9de70ab0988ed69000db2ab1c8432316bb91807fbed42f4ef3c86e70025e642de1949f38bc3dd1e4301651571a71f2d551896ea71eda2a58a636b25bcbaae8a9ee088a431d22ff75bbdc53476928e414ba67974f754e119c377b1886ebeabf22f2ad7a77dd68acc32220c61e96a142d419866c3a575785c594d8539991da7f1ce408f3e3b1b5f21ebed9eb0737cc3e7ddf9466893bc10dd8d7bd5f6c7bdb3490922d51db17b8d23f4755066fe547dd4e81dbfcf4614ccc5689968cadde59d14aa3d2f29e4d0d35cd1e310406d3fd89c9cc39883d7d47342176cd4b32e356cadaae9b5827bcf8b9e60005a4ac2796ef749849db7abd2612ef4778826915c40f10f862179f379c002107a3bf29ee0672c5ef18f8fbf60b29383a0ef3bd8db14fb04bf11515995749ac6030cace08f7bcb45d760a608dcefa4ad9b20731c369454f88f00e82a039d0e3637b167d712b4bfc77d94bafd7bc1ce7bc02dcd75c4443bf09973b2b6bd56ebdf600405c2894d4a3cdd9a2f214521c72592026e46d8e0ff3b05549fdb6ce80f13948eeef7acf9e5756d72b3a31fc2fa3f39990a2082ebaad0043b8e41779d4504f29d5d7caebbc41aa184d353fa348cbc991777ebdb1a5fd37f71674e0283ea9da3da822731eddf37361e37b8a0af0f3f6bd2cd2f43d4d425b81d885d7d5cea4df6f318cab45da3741ca20f65ea495879905922c4083999a96f686911b29fa5733dc426aedbbe750f3a51dcfa52e550af3184e898de0c3d33c37d6ca5f4418cab6a2a85c8d8aa7735ec5f0b82fbef81b29dbabe8c6a3848f691f6b9e00b2d8d9b54eec4f18c76a2228bea8f31d64a1979eef363a39a99aeb9a0a11704e37997662cf8c9f5286250724703c494e709c807e9e7c24ebb35dd5e6433d9b6747ed828de19a121db42778f458064d1bdd8a6db1543ad181332eeae8866eb16b8232b580526958f7395f0821d1a4b36c9441c67a868ecbdbd662882d2d90f33d90e179614d1bf59f420a149f2594f29c7603bf88d4e8a3e900cc3bb6a00467ca02966edadf0685d1014c4c8607a537331cf18a964d1ab6602f3ad375c84df4633b0a27a384a8b91dc48d9e77cc94f8ef6cba9d2725f61daa76942ead291c684fc54c189e8867d8f073d6cf9f74f44359aadb512c32a714afdb45f2b665ddf232764eced0d23e8fcd546aaef12e7de658e48d3da2daf73d846402ef78049c028a37603446edb1f5e4b7f6691a1582a1e9e21051a7694a1dfc0a5d561ec08c770a722caaad8e0081cfa685fae4b098df76bf1507c9faa5d4790f7ca5a238a26349cc46b59f126290ef0a94ea91f63bd09ea5b0b1d50240d86af662a755431e8ca7bcfee6799163d41a85c29fd2430759b338e8e7babf64de21d70cf536014c05728fd34d3df7494b439f5f480636fcb985194d70af51bf51be46d73dc28d3fae193a050d07b61214b5a8f4c53625d7174fcd14606c2830cf542cbf0aa252b74bffc19ee7965ee6aadd77a5117e0266acae50b6200ea79557eec9a73d4673d9e97cb755064034e2efb7f0236d54a816b5ac45e2c56ae00404f5021999721efd34b5e3adf8fce84980ba4bc838935ce5e53761b95caf7b974af4d3bdfabfdfa4329b9dabb1e09517eb1ea85c34d1ea2afb83b0cf86353fe2201159d0986ee10aefc5ea62bc6a15079a894de7f3ae25eed007ad99522b9c5dfb6e82d5f5d609dd1d02d61b8a3ef9d7b0989e8f2b9ee591e5008105203719e809cb7d9c4d5adeb70ea4bcbef263ce049150593c8731c11aa340f04c9849f7dc7cad305018d605a0205", "ac53", 1, 792228157, "2088ee52ecb8c714401aee4a3356838d30c800b96173e7f1ac28221179f1b3b6"], - ["c37a610b01c71369e871235b3435acdea25bc9901d24b190cf92f78f280716561b4dd56fe70200000009526a6a51650000ab654c19438e0137821b04000000000253530000000000", "526500520051", 0, -20672650, "0b75be294d98303b5368a9ed951ac29644ad35d8a8a9e9042ec3f88c8f679e98"], - ["5ab9e82d03e109ed8aae02ea4f6f829cd42795fb6bacf867be39bcf24c2217bc8e34a46af400000000046563ac5334e20bee58bf5c6c777711db1f5c62598b2f8ec98c9cce04c26e80ee38ba021322ddbd280300000005650051ab658d404a63eb0690b87ac41e8c4839a0cd7256791118fc07b8aea7aa3de8c45d7c7fd7b9950200000004636a00ac62207772046798c70400000000075353ab635263ab39a8360400000000020052f83cfd040000000007acab51ac5300526f12bb00000000000651abab00ac53000000000300000000000000005eee960100000000d6da2cdd09f3c7d6355eedc6e348be6794b04705b5249136972b38e40c30c290f376c7474abc89fd6d32e4caebeed792b393904d48d9d74f0db96b87f08f517f14811babf7dcbf682557c1b9bf74ab58897fc7e3553e0818b6eb6d1090f0e07200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000735e2f09d1454a1743630ce71ccc8d9a1706264030f1fa516a0a6833d9119e7a5eb34684ecef1ceb702425be86ce253fbd0e48a2200e905b87808159aad327c3830c58495d98279ba8ea2110f5dd58a91d3d71b9bc045d2949c61e74ddecce8854df505ea997f05cc855f04c578cff8addda37042c035c37927bab5396c9ec290208cf8b7177a87e9ab0869a6cb167431ffdec665111f51df1b3470393b71ec1090309583083cd17f0fb6ca2730c67ec8bb0b1aae62fe1597f562825c09b430db1220b1104881d2704ec983a1d77607f4d36ccfa81721af4e3b9442710bc0c7ccaf8203008855a70d4aaecc7b6a12455e645344483747e2203216c3fc83e3cd804b90c0229f21684587a8b92792312a66371e6141ebbf5cae4bd2d317e6eb93354a323f10205fe5ecbb9d30eda3ba7740e2fb20c1dc4bf8e8d3a1186013a35348d70eb27f8022cde0fa62c1a355080a920da4ea2114e5eba9f52b067b9a4b0abb63af4abba5a0227dcb90eb00e27bd55c0d3d35c4de60f5a664a1ae9ec4a225badc2c8860fbcaf021cea261d77efc5928504c5209c74f6df5f6fc22a3580b00e5ea8b068fc647293816917cba931efbff2326454b7cffe3b67f05d5fe3118a4f1d904b8b1394fb843be11a514af571e39120eda679f30903bf5ba7cf8c5181f42c747060e9d7db230032ca5cbf0b993d04efaf74aff8a75ba05ea982bc88682f6afe29d13f4e6e53a5fffba8e2b773e69ae21a52de0a5b00bdea7109cd1bda86b1fc3b8e821062334598ddb4040e29a902d9964c03b28a4a8a738f9d1c40d9de5df1f2b09fad148b8462486e24401f60d49333eb78e61475e426fb7c23316c203e64011796f310cea9c1c8f18ef44b05b5cce4c8eaacfed4c2604a781362b0e546745a416203a345f1b21dc0ef6a70096a570795c606084d167238d2bfb31013bc3f1d9fcfc1ffd7c470f004ad81a602e32da199d3911b3a23f65e5a2d0a25ba3c11892f19cbb6c3644b133f4eef14981263b4b6e7fbc5ff2cb81fda7e05e0c27eb08d86bd65e4f6d066c002f5d4c2d4610e59e21bc1a20872cd79d4faaf97ca82ecfb21a3bdac1424a7607f8464fd259fc3ccdc843745922b8f05e4f22dc1b55dc565395b0786a7b92f9cbcffe5d4041d25c6c9ac3d725842d35e1c542a204187d55cdbddec16618f0685e6737eb4cd701d293266db6b8375989d4c932e0259198326f8f685645f3a6b235dadde0817e17100ab90992a9cc3ae38c22cf9bcdf2aba92c46dc194c8377ba44fda0ad9175470899ec0bdb70cdaeea4e64edb0534f35437d0979a756d4eddc22aa3ad4bc583480e094356fc18951563bc1ebfea5c5c6f963a3673cff68a5c220a329481383a5f9f33a27be6c00e63f08cc348f68b83794e7bc44079a5d9a7dc5b5486211a450bb56104d19e1e68b35b10445edd162485c86e4c9780d65d9d1c37427695bb780a9d7cad553c4c2ca90594937677e5f6994f9a67a01bd8e6b415e976c09e26ec85bac494ba93cb4d44a8cf0ee2192e8f24e98bbf1bbc8ae5e4d942d8012885ea21310079542638e1e1771f7a94ebadc6fecfea62d7292988cd68ec731b909e46ec12f8d3d7b84a97149db7e23bd1c6f25b43a394542a1dacadfe9f9d3ee05aa61a9fbca0558fe9129f247dbff05633c90237b91f9882ee26de7cbea5b3147cc7c3f0c4db8e73996b48c575477e40505548d56b252353ea0cee4b06c819fd271237fcf109f338ef67d4af9a11eaa605900988b77a0192f80eb932d158fd5835fa59e01ee93c9919a33b1ab47f76e122ce84ec81860a5ae7d46bd8e50c74eb242c039a7e1df5721cbeabf224ece6a692162cd90e6cbf8e7afe8c0be8a2b206d99cca8d43f42356f9680dd7556df07149db25814b94ab45bef1ea1f362ae57bfc45b6e4e07cbf896ff2e4b2e5fe2e1f2d64db1b2764ad39e5441ebe26e32e15c99c750112af7c747f72d139a00dc0de75ac81e21534fe8c25105afc848234974bb73d03b676284067ce41323d19e518b0993dbe130cfcf980d97a0d35e747604240267871445046da838463b57a9c3326b37e31a5f019cca40049edcc0004ceed48be212f4aeed6413ca06382ed0eb7209ce109279fdb6505870fe365a4d104c627ef6901bf8db7651d268b6061ebaf1a185af87660ece3ca26b77c6d9385d6bc67e861afa95f6d473b174bcfa689cacad64ab3cede4dfdeaf8b99f38bb4e165a68d77aed810beae95561ce0cb670a769277ddbea1838e2020ecfa60ee95f3bbd48e5a9eba8d945c55861000000000000000034e6cf0400000000cca9d3d619fc8d7211d680966d87ecb9d6b9645b9ca31f6aa1b81bc1e6bafcb97cba5ea368eba9da03a72146ba6a314b1fca61d72e3f3252cfebd0593e33d76fe62ea728ec1c0b226d60ad73d9d6bb76f398c1fd90163c844d5e852820627b3300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000536a999386d867df0adae6a2b00f9f79673f107b803b39f4944ac453e249d6c2009f5d73f6bc2fff092c70d6c0305b9f950bb4662ec280e8806d5aeed1717bf1ce89a5052ce2670785954cd2fb8610c2151710787bc2a94bec81468233a7a313d461d521c321bf34e8df6e5913684420511b7a044a9c845466e795992629a029031a6d4e2c98d1e43bf520674b6973ac0c122a3e2ef7a8c414c573f56336195bd602014cadee939107aede54b3ae55ac898c1bbea23ef213e11e8efb2bfa7e902d2f0a2e2c5b7b81176432873285182500f5389fe222105752edbf5717e95f937d14b0138d1d8cd1cf8ce8c70926c1868d900ed49829260f7243cbdf3f0b95306c1d06030aee29be19a9937d4e87b7e6662be97f7eed3fbd2fcfbdf89f1e9c117c2cd4e30224cf4c3a5c8a17de38ddddd5d0e8732b9d7aa5d3aecf726f947d966e03f68f010320fadec34f37b9f30b33bd35d834b5d354b791ce106fe3d720aed62e9619f729030f311b2c5924632e6fa64790b76ae02b80eb547f77bb5f9a60a92cd394958df60200898a92142df4a447299f65cd8b572a1659f1bf4f2eb0b4dcd65696401bb2a1af31d96153fb92c80c7c77d05044b40b8e61ab0f9080816e29f3ecd2f74e7c03c1213617ebaeea3e8f4e9ee4b1477748b3d0db29a54f24bd3fcfe4cd0b291c38eebafaa38057915b0386de46a60e650925039740ea0b08de0cf669cc317033f23c9cef474f704b7880500333a066296264f4436b706c5ba22b1da680e26353447b36d1cd5540b3756c33b957f6007f00353daf7ba27dd4fd96aa346d621a66a3662faee7b2719eb02ac9f3cfb24c75be868459ddcc68fabae2c49a175eff57a04fe3558414a4e66e7dbe744f744b019e365b9cbae950345dade78d143c133b5299832d50a55a5a27f4cf45c1cf5a1eb3b2dcc4ef431fb82ef08e78b3b2ae3fa0aaa9e037ade725d8f0925ef39c3aa499c614b320df9a244b18c5ad78fc8772a2f6640654c9e0f25bbb2b48a6cfeaeba4c278995b9d82617c1fafeb706bcd067e8a689e325b5a376be97abe83ac05ecb8e3d33bc811b69811458fb29ae36cdf98514534bb8e8dc9f57158051a7188ab0f56c008918180ea80f2e6072a8aa59073317ad26e6552f5b3dffa13ceef34962301c6c20c0689e01b136ae7156d492ea02046740e3dd1181df5380170b11a94fe48694dbb97056055cab407bd8c8a43e390ff1c80bdc3fb70be1d1d41259c92bd69e9368a63eba401ac129c2b3d49f32ab1af331fad4e312f60ab45b4cb3e6e5f7380cb35ac68635d2ced20429660a7f7402c3cb67776482c03aed367c024fc9549c18f9e109d65d03adfaf795b68c4d25f5edbe69fd3a43f66a7ebc7ba85e3655253985fd8382e97fb41ad948a2c3d2237f55940a2bd5be4ef3bb3361b827e249ce454ed77d7a90a702779233185b90b6870f4e8030b90c2391dc739ce34dd81c5280c984b2acd21d151e9f2e007aa1dfed84d54bd170e580c7a72c5f0b61514845f481a15cd51266cf6a7be80ab6ae7d28fba090c82ee02b13bb9307150396a7b0d9184913459922ee102930bf142f38366bde2c982bd2907e5a044d24ccba17703cd3b0fa29ccf0c3c509a9e8f175194db5085ffa4786bc891e584b5ca73b0e6a464df858e446617a028e1360c513d2c338cad229f1711c2c66d2ca7490dd0abc8eee48e9eecfa117dda77036b122787f611f4e38f48e13b5249d309941f97792cd9c8df7a46ff9b8de7a53d7bab0f6e132decca6374614003ce0103caaa774ba2254980d2db3de670e8fa2d198d264bf907be7283713815cc9908950723391fe89fcdd8629cda4a760fa743d3861b7d22e151f6d3bbb3c625db4dd1badc1178e596fb57baa73fcb6a07366bf0dac095e1d5a782164be6b9d116cac74237b8133b6c3d878502c521aa688865704050b0df138fcb85010ebdbf686ab7933e388d017f46d36521a03e24e6ff79f5248da743fc5492444bff34b5716de01f393fe1a9bdfb98a21ff168040e00ba61a1d1d2e79f0d61164ad92b4e9ca1fad22d3f4613e5a35b13ca99c1562a991c64fb7d834a2c618ece909aea9f68f2ec4e7779896b3ea253616ad7de9e3ff840cefe3b269881acf53149d5463b219a42a58c503b478cf846e266b12a3030cddc05323a4ee96a0bd51a0f255bee9ef297dcb332f45d4836a414d25b4a7303fc5317769ba204783f9337bb0828e60082d91f59521966ad0331af7ea9dd52019131fcea28fa856584d077eec49d98b4cbb3e65a8a0ed38e0826030000000000000000000000007b617d34afef78aaf6f13ab83bde532e6f2e01dda1596cc29e21c61f0df2a50c9c3e66ea59af3a5bc19ddf108ab75dce7b7a0dac93e5070dc39c45ff798bc50d670e03fb76560933fa8cad7ae7c5c9ca9cf150b450c9513c3536a128cfdd19bd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000701aa0df7a0ba53e45a796367ac3d04460622b0977109a77dbf8bc231057f7cfef09b90104a2f48e95a651ebb4679c814f2bc29daf4febfc9652e45e03a7ab64d586b938e2482149b8be8090b462dbdc8c7191f99a960e28f3ce27b5002ba8bd9b60002fe2a29b5709a7be432c0a4b5fafde864317d5ea43443c36164eca228c032103a7df0ce0099f371129bff986150fe7d0ea4cf7f2df149a36be1bebc0079e032ce463446e37898130694485cf835bb3c644df57206e78296bf9124fdf91c8ff0a06e832bedf55d7a5a53133c0b9ee954f571f9b208f4502d1f1a8fafcc9346b1a23c1d108ee01a4f582f2eec233ff7896140635ceaea6d91c3da9b987d52615bd032c53619128c8be98e40095e227659cd7a4259dbec8881c8543b2c73b5f0ef96e0316bc118995a8e2a0ff674fa6611226390a064875784449ae03a826506e566edd0324dfc992117f810a380a37d8cf1352c0864348d357180ba14ac3e7bf4c0fc54b021cbbf423a4acf8fe0532a745e5a4ad97b8f5c0548bcaa53edb5129b84ed090cf022f8fa100a2561c2dbb7f4c208051fef612cf7c52626eac71fbd2c06a69f71be0de4c514935a1a58c65eb391f915165e242ca1864e9a6e913dc4a9b1216a7538e9c97d048fb4015e7dc0a75d5bbe42150256fb53913cf40ae79ca5dbb2ab432766197c79aa8fcbede0fee55bbeb6ae08b02e310a56ef0bb98b01ed62bf2efa20e5c7272aadc56b6fd24dcf955161abf68c885008196efa3946a75a4755f75c54d19cb2a9c60a44c29eea63c42e66717e406d43023eab2a3c785786d6086b072f5862d6fb612c94567f2f6475c14fe5ad243a71def74c23fd81a5f6838cb0225d0cc9d27bd7575f93c0d22d3563617c9209bcca2732c0ca2e8f0d785009fe98ea47a4019850e3c8bbdf8b0f80bbde8d4366a12e085a78d3ac5447b9aa754f40dfe1df24e53f4c982032a218b66574575607e1ef1c39ee10b4f44afe8b255c5a89740b2b61ac4a980ddc0e78fabe8bae29c0f7a7c24258af9e7fcdd2e0b615dbb35f455fd6fe7a4b9be2c0030b8816bde74b2a2b9073996a88bc178eff8a5fc895cb5fa1bd2992cb39f0bf5c1c5d830f867b28c04156dedb9854c3d58043b4e03d02a58a243854166581cc19bfac5a273b8f0206a437772ec39f4794e122b3a633acfa4b2a31bd901a582727d70b74979bdb8617362d7de373249c52ed98660894c0535aea871a7dc4dd1bfa248dd7c435e0a1eddd28c75f16e9aa532ed8aaf3738bdcef4b6c43c79b6168fc3953ec004ea85ad9f9b5df1c58e0c983d483c42e5764e22659048919289395328e5c59f345d53ac9e74fbfc2c8b91634b1eac9191b7777fd67fe05be960de78306638c17a9d3c5438b6e73efea5803849f9334f61fcccda31c9304d1be000226e90658b60ce00e0a9f3feece57df8909de82f3df4719919dc5ca5324c5e34378c932997eea62b6990c653b67da3dfeac72dc66587afdc76b287a99f4e5b67633f9f62db87064912b300ed25f206b0d3dc821f8b30f4e2124cf3a1fb9d0dd011fe40e38450e58a166e7235f8cdc2492973e9f7f341a09204c73d6579a1c6239cb2833f941cba615af786f7a44c6e885fa15fbdf0fc1fcb5dcfc3e4bfebffb6f7195e15d51480c9861e48e992d2b4a8cf75a2b48267078e3bd4a1380c32f64472bd20331de1f5d73a5376ede6d44d03ec4a8f73cc5279df833c930ca746f69ae4f2b88b0661becaceda229275b097872114626a0fcd75be78e1612d2963b296397d05bda98cc0336179030c65e1db466a67bf668a231c6227ade0bc4fcb1b72340db4389c3c613cbb58afc6561ded3a17f03841c099df91663c084241b272aa88d416179973317e3d8e895763752d90688bc86723433084d4eab4f9e9fd80285c11b5177e7a7565a8f1f3db4a1306224ade352364c5de7672df531a9b216bfbd7305b061ccaa3ab0b487162fb5b9eb2d4af3657d18e6d30439e708efb11a2623d748203c2e16076a785a20c89ba4bcc67b2c435414e1fc1bbc1d92d3b1e5c394ac76cb7ccb12f2199cb7ba220a9b0adcb03948ea970658c821c1141aee11063854c827dbd535fa2b8102c5d66e945f9b5f2f3dc77ed8a5b3ce86d4d846d386af2ced8f3b436deb3331c8bcd7dbf47d013fbf2938f807eed7a67dcb0dd7779dad330d4452c8e51d54feeaece2425a7b9365edc86c4103fca6d5f5a6de4ded825f348667112ef81c7c08dfa6fb3c9a5244c15d9cca7707623e0709d70793f2faa86306ded9d253ec36f4b0e969f39d52c60ba52d18160a2794c3037689ca473fa0b4cdade2974898c7956d832fb7c51f10d03f15c132d5dc2e76abe2de7281b26aa2822e0e7d63c87b160f239cc262714f5891a1771270b8eaf6bfab0e875169e9e9bc631168f68ca02", "ac00", 2, -1904449756, "93d83faaafd586410da2c51ac54ca90a1c7ba277f3c1f0a4509250bcbad02713"], - ["5bad4ad003654d36fe20e607b87fe2b69d7d84611e6e60ccc76d7bd2c9a34a0584bcaf6180000000000852516a63000065534b7a4ae34597d55b85b50f9af145d5a431e555bff1920cb5f6ad8b1ec44597aca44f9a8b02000000006021d235c2d374351ce844b59f3179e354c917eee912653eb28d2628928d90342187e5cc020000000563656563526388abb003d52a940400000000095353536353655100525a8f17050000000006abac52515365f52d360000000000066a525152510000000000", "5165ac6a6500", 2, 2064777289, "0f272e6235f73885c67c79d308002e8187b46fe353bd83f1689707a6d037f957"], - ["2246e41803f905369dac3f896e060b879aab77d8382e2071c64be74d932deeb1938d71e2920100000002ac6346bc8cc19e5da28e80b39a6eb834b895e0ba43c525464dc1a3ac4b4253acecb540ae7a4302000000046352536ad272c77452317e2f1872ed1670f116d21724c059027a17ab6a50b52a04e7f10e20279995020000000165ffffffff0300d2510400000000056a6a5152abe32e8b0000000000086551656aababab65542e5200000000000500526351533505359a03ea4ce10100000000000000000000000011618444ef61df8d4216b7067e34509e0dfed6f4230f2fb5fd65ec9813f2324996adc069d0e73a1d938403f3a90ab3cd63b0291fb6b2c6f34cfb90b67607181a6024ecfbfdf0d8e29f0d3fdb72ebb08aa7c004c4c821ccefdcea90538c967fc4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003372d3d97c9e20069c41d779d66c7efcd79656b33d18c84900eaf3875ff4bafe312710ea80caf7700953795131b9b659dc03c7de867aee1055279d9ba37c5b3909f212972267606f08731186ee9ee494625b1ec115d61e1e55080bcbbc1d10d9a492a4627804bfe2ad36b584baf2bfa1f39e2a7eb334107d6a19acb0b75570c0021d91a74893c664bc0d672a56e1a2ea4c0813ad621e5cbce875035ed96d0db5e4022bc23495b65b059da74966ac3d75342f25c7518a52236063fc6b037e04778af10a2a56bb3e87e668d392e37efa9a83415ed0a177803be60ffd114e9027d567a867254f2a0dbdc050450d05a5ccc378c741443b70a425b3a77a0e99223c07874ef003167205fe755fe642ccef9bab8899ece2b846717e6d36eafe59db98b6fe2b24530220c867a105b96fae89ba2cb066412c2d2ffc780fcce26774a696c49624a3e8c202101c2db5c1c5d77fa6b85706d5f34eb8c8c1a1821195f9ef2df3289205e1212702184a6c5a48077ee2ae2a19da751187e5b7d3df7657dafc38308ecdb5ebb7be4d0228d770238ef5516166b650d490f2dfc7400ce6395466084ac387800c0ef09223d58b7b71375bbc600247ea7d54f69babb51097d1e6f58c5b148a680ea909a1a2bda490b2cece95be03cf8eef94b8ed797254984b95ef4572bb8582e87f7a1a7120ce4cf3570fd8347355339cdcd4ca853ba2a1f32884a057bd3b08b8f5b7b16cab9477bd3a44961bc7bceb12d0512202dd9a2e0c4d55851f954c57f53358e935645be5b2d488660c0cb9fc951ca6b1c07ac6d14bb7f7f9e145688f8e77d36613b4def9477cfcfcc8bc718fbb1a8ba3e72dc20c9dac81537d6feef090ddbd6cc51761f26488eaa479396cb5858c34e87bd3fec6b6b4cefb67370777f4b64ca138ce1cbd38862dcdc8b9f78de5cb06c66a1e374d0e9fd24832bf3ecc3b52092cd0dd3508eb26276375746bc6d81424cb3e87f6ab3751027c625760c7d310a3c79ff74431fa1bb77eea49b2bcee5ac487d0933e541227997710cec7315bd84f0347a5a313aad56fb7ee99df996ff345fac3ee38932ef3611f23f4a78f833754c41b6aa4fcef2763684e7f1aba6e08a59ae7e13d6166f3e5566b2efe39d44d46396eaab6c9c3298f8278a90d3b833da249c65742a81319ae308d5f5a344b7557dc91b432b6deb7520f828834380ef8f3aa2acbabc720a179f4780cc3d8784b16fa509711f722912f1177405f10d6daf5737aebefde634200ef7cdcaa7069137404871958ce2c26d1104e09e11a8df290e636e59a81eaa0ebfbbc206185dc2d4786bcc9c8d22e85194f5ec2b8af67c961f393d5575f4ea48e851acc1c2de3d0a99f51d916bf97586a1a1c0962344b4e2814896577b44a05cf5a48111f49bca90f58aa95a788ac7b912b540bd8c36b78297872eda499ba7e6421a4b65b3482aab6c23fa5a708a12e333c7198489863f94c87ce2c7577e6e86f65dbf5753dd1682a29fa577a5376196957a387dbb4b32c27b8fc22043adfdf890353248fa2b391172770c0435ac5ffec7122bc72d1b6de1470fdc3d22f8f1f03c42242c32ddcc4ad32fabeba00faa16cfa049dbf5e97b85c21e02c6dce3c947bb0ebb5675a3e4ecd3ad205b2b3f336fb02703186e185db23ba9c8f25c82588efaef9bd0e22da7598b204ab541718dd8e96b5f8cf5a7e369737a405899ec1f23b43f3e49ed60b21029b213e9bbdb3ec1fc21e982de2d7ddc2ed9052be2345cceedc3b72baebd0d633bf24bc38964ceb5158c018dd86a47fe3dcf92d204b2a0e74c0ede0ac826739543894db7daf14f85d6f2d1e43d231d4eb34c56df2cc75db92345eee5f761531da4b397fa6f35657c1dc4624453b39d817556ea29a229ec6ed9d53b0f18bc3e941b33e6c200e3071b71b9351eb4e3f52b3ed62aa594cd3456b0f4c4eb19e6e29fa1032fd98560374aa91eedaa8ba18805fb649a8d1fa7baaa88c21398686c6b74ebfaa6f4af50e1d08c556402b52fe97d1d8ea7c4f8d96029a47159ef2abe8c18dd4084e78b69a3fe49951055709ef6df6f25d040262b9351f4c4b9adeeaf787d8817739dbacc50fae75983f8d3ece736528a2a0dd606b07274b6b3d618c2b2b25fe8a3452675646ce893350e53f59c48c9db479dbd35427e40d2d21c7964b53b416d842b515aea7a645b338d36f19c818fe91155c7c4aa82ad716d1490276e7b7fe79205fc1e0e273bab7b6a15e7ce8dee4117809aa6193fb66446b54168c54c97e4e3ac8cfdcee4ec60b99f63510c1589e405ae4bc6c18040000000000000000000000006ad3885d958335ad559ef351777bd489300b6bb1856d5f66891eb672aaba71159586ce11499bc208e8ce3d234789b8e4d8fad6e5908df819930b23486010e9db98965acf1c7060dbfcf8e3934f5f116f989c19f219887f7c94101ad1367485cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001cc284aa8056b8fadb7ce136e7459768a3345b55b210d17b211ae15bde91954e4d282029649e0b721cd04399ca9738b99dd9061fe3b2d2257680c62c35642fee7e2c10cfc419d1ddd389e9c0d3b5c8debed701ef5268768de9f5c66972901b5a2e19b5dc78c0da103ac61be49941d06d68d5149c39c90d761bee322db932a4eb020188d1fdef5cdaa501ae6dac22cad736ee6799d93c0b49cf16eff285cc987fa6030b70991891e92fda52dc2297151cdaa8afd733626370acfc0be0fbec92d9d7070b21d3ebb5a9b9df9b46ab52fd63df626ab60762a7014b5d734ab3969ad5854d6b1749bbe5f0775f0e3ea2745d554e885288fe5f64fbbaf141ec25fd46c417debd0208b0f791c8f009743700163c7089e9b398e6e9f461094ea59f4f8338eff365930312d054b451a27576b4a571e2b7f1e483f6faec9c3bf20215cc23b00f5b86b34c032651f1965f7d57e96dd34fa34536ac2e10fd77ede917cb038197126db2421ad40224babe2e81ad1acf7e992b7375192edec678306dbb7c22167e2f2ce4862a85500203771cfdb248c6e94371f8f1ab5556497a329ebb64b5d80583db6e9d088599ef439fec7a247fa026343d98905dd2d2da0bf91be1b69690187553e7fb5855abf76f72bbc6ad03fd8ced6c1cbf895fabb935834feaf6507a12da09ee7610553cf611ebe52c1635467e4b5ce9845749be6ef38715b4defd51e0239cb2fb1a8e899c6aeb67dfdf3308d5ac8c281b5d9b6f9ac99be33a5108395b1936b3e8bbb4fd22a1eb0d5835867bbe317a1d0d505a9db4b628885df944401a66b2a459f49c4d0a3c9829a9d24721c9cdd086151e9101d421ea2df1501e10a0587390426665b45bc062bd9b2a58c805570ff70f0eff3e0714570e1a1d0de294c62f3732d3e03783911df4ded95354783843ff3aba7e2bbe2f26542be7d5dc49e1e82643b6fcea8bb701b216fc72fccb9f8c056361027c8768d87c82fedd71ca92da04c7acedf7989965db0e3f323c99d07bb33d78014297ff28cd7cec5b8dff7126bf81ba5cefd62f84ecc1ede853ac531c144722ba48afac8d27cc04fb21233fc3e99bb01bc61586eacbad898c9b94ab4e9e23f71c9deb0733edea3bbbb2df802195b7d254b5aee1311a9a8189054ca17d43e3068042b54776c2e91f7247491cf83735e757c220fa5c3e7bf5e5fa212b3b9366d3562fd49f0b4098aa94d5b7dcf58783a923c6fdf82e0632b268abbb59fb177644b902ad71415f04c6c5c18e0efc040ed86c67e0c4c48f5e385b99078d2b4e4c51d6125bc897cea531e1bad6667c5638850c930fb3681644e9c327cb72500c90ab0b0b8a39725bc38d510db2f324a47dee97611680b8f0ae7e0203ff9b7b07cbbe7611d8f4c46637e440c4bcc7f6764900798187dbf6e41a4c458d59a9a9a2e74a15670a038c7e521a2f681430cec12e502b105839a5e758247a779fc82f55af7c1eac01e2c004d772ac8721b3dd9645173b0c811e0d01acd603e5156adbae2dcd256ff64f68c9720b909fb584dacaa5848017244d5735f4b90e72abba7f0473ed2cdc6e3978f473448f81dd24aceea8711b00e6423fd50a115d42176a105af15f21b53d7d961e771b72af92d7cd6d6645a78c7610411ae1de7557b5f4143258dae8378a02297b74cdfd5dc07bd7072a29aa83e70eaad70dd163344e7ae5faae5ce112eab156d87f5bccd4d1756b5afee4990b8c8dfcbef9d51385effe3cafab89d6b1741e5a2e5977dbe9cda59a251610167fe6919936a035ea15dcb7dbfeea2123057c16fa8087bbe704772818935c0b0576c22e15b90bfcdc2b2c7811e19f36fd1fc9858a44fbdb15a02c67dc96fe41dc27a4fbe321c8d5b02920d845a5c9b86ce257831f88792030360ea32797b0e08f7a8987e0494059baf8c3a4283d3eb6a216875bfd2bed1187c29f6e315106daa6dcfbe253069bafe54906ac0b1f0689e246609203f6742118c47d1b32a88a75cefd2a4f91e34a03c3e7d5e746266638cceef9701486e3205ca0aaaa328000ca2a2a46c17ad2d0cd7e4f8f9d4e5cf1229c3eb3a9a12b0af047aea514b1c358998cf77ca522ed984463bd07cc2c567f28fdd5f4e366070a49f1284abd2041273194dc4d85df8846bd1251d09e4d952e4b80f1e771c14a4d1b143d8d54d8892e55213fe051362c10c6df4e33e575fe61687b1a7e1b79945c78b158ae4cde89acbf18a717bfe12794439a99153911aa251355f4dfabc3990b794ae5a85dc9f3d4d0d71b00a6e476fdafb891775cb5c0545044680f9805dbb33003000000000000000000000000e3ca9a40289ed769796163abff6928b0a12f4d2726b0b5cdd86d25f8334f9f98a6f940fe124d85314744eb6fc6578c301a6039816e8f9cc534ac57cae369e0238b908e204f8dbc6938cf9a09a4b27c583ef056eb2993f152f514fb8f953735a2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bb25d16aee1b133d64bf2e1d5b67d4570b4b8a770402381595a6736159e00d539c9607c0c6619cb70db4404de68f8513e9fa6ad32daf8c7b38f6ab19297003d27ced7008b0145d306b33749726f6cd3c3c65e476e5c61d74a3f1a6299eedc71f34f72cf6e041612bea4aa9c57e04c4773c67dda819ba0bb5bb9c8304174d2c4031dfb72abb0dbe6ccd17c8343f2a79e23bd72c0fb5f78aff337e757dee0d81f0a02265982e1dd547ea7b6fbf481fc4a8a23ded8fe35d90ec7f22bec3c2b662cd0510a19c77cc2861cdb25e1873af62757acdea7e4bf097c81f0a7394b618f892fc0fd184d0756aded90834238a518d0da52ed569087fc3ba08a77af72722cb0bbb200030eceef5ff08149f1e95c01a24844213baf1a13c44f94034dced8955b47a9b1c4020dd120e001ffccb14386468b86fcf0cd7b154906368ba4f17c6163fb273e30d3032a480a07896b84860adfd80118dab28533cadc85c69dc4ede934735f4a24123303062b56e01fff7f8f52d1560ca2f4b4587a0b22d73bcd30911332ed36ca922b3b030a711eb3b802186f44fb82be5f7836169d0534a1fc16bb6fc1e2018f9a77bcf535c3c31aa070ce38ef3c8bda93db06e38218e4a9127aad33921eff88ba5d1dbc7becc6d414152e2677689130b8c421fd63c3ae3a3f952d034407dfce1d3aa82d5144c201f4388f271a3b39f68429445f24f3e194a3d6b5ea87bdfb26c8603165704f3e9322478cf80ebc1617e5359068b79db2df8218e8ed4a625611f5f84bca3594d270e9e6e125a1def7c6a1afd11f8d984d497a0e560e1548e643441c132d609b6f23346bb88193a9d3621f485af503759319669513b4534728b7a4b0ff4ab2bf7bceddecb04d5fa8edd005b03f6155c242e39076c42a96ef23cdb71488d9cab1009e546d72c7b872540b261ca38702c537a942959af8ed7a89910b610e79778e04f37d12b5a41bc0b0aed5053cd7cfa51fb53ca5a2cb33fa3d01368780654d6bb1601790289a181377906476ddc8e8ba1df1501908213d2b35a85b6a06d6ada0f14f4935f45eea762a5056f9ea9a5dbb9e4d6432e6f2c8fff264718a368d0b40081ac48f36ded848904488a94bb894cc5169688955435f74b121be3eb1b0d6651bd1602e9ce5743b1e754b8e0f986d1897f4fcccda676a8c6da7c3f357f14b6604d234e2f7dc8b6a9ec7850716484d6b5fc9aeb6037240cb3d43de684a57ecd236dba30d260d765e3023b9702c708d4d76c212e29c141b4727755b907ddd647bf5859cfd48a5ab4d493dcc95c78c1e78999df71ef012592b5a20c6bc5eb239a11726d94ebe6b4689b1e45253c8654fd1229df8572f4d1a87c598c8a20e8284150628c603e39104c73b24552151ad373e87f5743ac5db911932956ade74ed97266379bd8a9b265409547154b75e43b7a25cb5255ef1edef597a65c6db5cfb8ed1e3614e007e19d5af49116c56e6cc8d1c590f76226b29761ea72f45e1c04bd27f5df1565ac5d01b0c6d07ab132b6f82f229bb56c7b383af425a70435790114b1862b64c96a81b1d8c419e857152b07b0dcb9bb213bd82c856e4a3965dcff0f57aec4aa5c92cbb31589d948fcbf904da73566d3fbeee9e2c8440e3d53b08230de46d360d5f6d61c2723837fc27ad92b696857a9c0c053924217694375ac78855114845299b2d15397a353ddc1f4af0218f8b915c10666973ca4d2911e250684ba62dbdff12805be9a3aa5058889a81929d2a95140f18494adfdca5cdf55c75b500fcbb5354dc9c9333f3653e69bc173859223522069fd497cf0809a612b5a576b69e3106f3dc1684b54641d3cd191b8e08285df955fe39f8d8d7fd8cfd85b3b8f99b16a700a80d73637e830741cfa5d53a175a587df60eeb4ea70e39e987e1d3c6d15e00d100138d3d0ba5462192ab470404bf656444582c432df21e3c39b9a0e781ec331186929eada8dbc6adf110ac85f7a8584ea1d87be4061f0cf25a05a80a4f05290093dfd87df196969d5a2698a70b1f05be735ff0bbf53a6c5a118ea3113a496496e333ea9f1bfe8f0ef984946e4faca597fd84dd28ac42c702dc2ad3379ca8cdc9aa62f15eb8ca39a1d2fba5f3e5ab4b10435e73cf4f383b3ee3f19ab7cfecf749b75a74608c014c848f27ffec2b9a04ddc5e210c2ac7c3fe2e9010bf6b17534b02705152f3d3cd2e3a22184b1508ea459cc416c86cf0e3fda10e41ab909b8b1f8cdb2fca2c8809191c58d3b2d3e50deaf3bc8d836940eefc1590c16aecefd8cbb51e8e4c96b3ede6140a690e7887a38522f98454d5dd3280c4aac994b8594d4a91fcf712688fe2f44b6a4b2e7350ca96e063d80c48b1d0024946b0e983e93f3581348a280ef56de1bcbbc8a20656468126a0ad8afb46a39ee541191910046d3f2af959f429370e47e7ba8e700", "ac52516565535353", 1, 1829739483, "2ee08477631418580f29aad1dc5a14d564316023ed8b4461979304af4de9d854"], - ["8e87076601061e118f34f9754f608802553bf8e19681aa28294a7c38eee90711b049f784d30100000005ab63ac65acffffffff042744b50500000000015227161f0100000000075352516a6351aceaf903030000000005006a65ac635d2a59020000000002ac5100f188c20300000000000000006e61db0100000000bf9f970054537ab384a68e3a8646aa510b6b09a8907016d59bd4c7ea959bc7ab16ade410439c274c77b5cd1833f7485a30185ec35aa8eb56da38daafc973139487f3b16c73431506be67385dbaeacfc409259e9e30765c3bbeea45feaf91eeb600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc11cc47f347be56c021bef74df2351b60afbed0bc89438372da840ec1a5c4527c794a5afa8df91e394a4fad1b8ba1612772bb6cfc6687102e0f04b0a2311b648167fbe6c027592513ee25bb6d69cd770219a1247d60e14e6ff53555c3ed2e5b87f791e29b24f06230cf345fd7b0278d3a5796a1c84e129abcc8633d857c1e5b031da2a8c40fd2dcbb21ef8833775944d35d7afa52b55945bfb3660302a0b1246d0321d2b1c5f307c8998a2f74c62ddf8cc040fa156191959119ca89f8d476f5a40e0b14089d815b450eebc52ce0e7e843419b09cd3082926304a7f50dda1e56c8739410676ff81fb7c128e7bc5e3f9c41ffce56674f91a385190395ee06ac56b831230305f0b079a037196eed9b6d251fdebcbfa682836d49930483ef1690ac69fc4181030ab67992de9c25b5aefdcd0117d8539dbe5f86185e8bee0a75ac062db43166dd0227dd8791ebc397bb3edfd0d356e2b501aff22041e2be24e7e63b6498f880c6e30325f8d6413fdb36e0d1a4a705fa5fbda20b9b6c4be831a510905ad449983d8925022c41fc54766f053bf2b77262683f44cb0201c087966223ad021f82758fade3f4667b74272610623d2dfe4ad4b2aed242424f59a9a10b634a51edf35feccbf69a5d74c2b6ccfddf93ae49772b1eec045fc998b1d447043f9a127a49863a28021763f899dfab10e8a4503279fec3793c3813eae1407234945cf7b2f094766422cecfe58a2cbc227f2dcecfaadd70c1dc63f20e61576f20cf5bed7ef29d083cfa5db1e2d762edbc1670b7bd81a97968614e355203b95855b63df90aa9669fff12c36eed7ac49bfc83818bebd6da9fed1066fc69a9b865d2d156b399aa15941172755a4a7b6bbf41ec808088274688c0b906bf7003d76198a6163973685c1e7579159dd772b399dbddeea0c1b0515a974bb2872d7f076739af21b6932710a07e7e411d9b23fcd7aff97d37c2be332e79fe4504cfed83c41a30198d4ac4f813bf91001c117aeffaea331d176a869195b8429929dcc798b993e5cd50f09318a6bda78478b2dc89ad1d46a539add7aafa7f630a4e24ca7751a8f3171f29adac75ed29f2eab1997eefbc9c4eb711026e36a4edc1e48aba00c83e8c5a9dc63b5695c00f5f00e1d67880a1cde9dbe63c81bbf1ee3119665b134c34a985b95a5b0367d85e691d58f054e21f08e215713734ed1b2ed466177d77150f84325fb487b73b923138c349157f7233629f426d6dcf5be387b4b93f7c233f056d0f64c5cd3776dea7087ed711a8e5e017f9252af98240294c32bd7d65fe9cab36d43fbb7d9bc07c0520ec4d10cfe4ae2222a3b646f8b62046a9f39cc5cae45259a43e914915f3c0df4f25b8ef7de14096aa7b4d996a841b9dfe0fbdb1c81273136132fc1d042b75bfc06da27de110567f261e4e772785d6b5561966238e269c74a9166d301bb08fe5d74234ebbeed6470ddd8d7e986c225a0ee32baa472b9142031e9d7c6671339e88838c6fc635c83170598b28af2c9aac903ac8d2be2395b30c335d9f5ed0c306d6d4900f56771970c09f867c13e8e275d459fce070ed307387b767bdba011fc2e26437d31037b0352dc30d9880168f287bb54ffadc34aebda28c5a74bd5ac5036edc4b8f3ae0e74886efa03c42b2cb5db6b2967f3abb1475b3eaa5df92d7c6ade2d7ae5f82742545234469aafc49807fc531b937603abdf367954f485c5077ed2707cfcfd7ddbb5676ef30094098f9372eb0fc5cd46eabd070481b2e00f25644c983a6099a5ad13010ba64f833b5bb86dc95de13aa217401968bdcb4af291926b3bf730ce4152a89dad437561f4c107d43df9d937e7afa1102ec4ff908c05805f277e874894a4465fe544d2a318162277c2899e70e9c3f2a6111689ed47f31e608d1e9ec1f470ab67510fec6c7cc25a36a4bbc4abc6cdc0c08e6266178f2240045ed8f9defd5fcc1612237020837ce6d57c2bfbf0408dfb471fa885cf9eb8522dc1039d9da432d52d6746c69c4e8e617e3a20bb9f5938ee96f8d2d1eb4d30e40b31a52711a95090ac5ab525fa1d49b89539479737a8600b052c9e70b86df1adfe297c820cd97903adf2305c2290a64c89f86199cb778a461716e944073b5e4ae52ab4baac9b2dbc1b80688cb4e77d5b08c74234b23c48c9f8b496f1aeb46fe4a003de4a749d1ef7826bd9116916261bc53335ed741234991a3af981a14983f47b8b27dfac5e1de81e0f801167080b24b55d922b9a7cf40efe41871b5cc11d9606577067fd917ceebd916706df622699980b8d3e367c670200000000000000000000000010202dcbcb11fb776ad54cf8622f6781e936aa86be28077889f9a02ac8c2038cf44730c8e5569ca8df25a3d3003aee5c305308e24ba0fd61da513a78b02ed2369f3a2e624f2fec3b69dbc6231fe156eba920311e94a88ac870351415540d8d0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5c13e4e7ad49b9b785a7727de80b6bd2c881bf88d102ab5c1863b46ed0c9e147e3afa7b6c5df06a234423896b4e8a73eef1500ce8e6ab2bc89dd181ce466d0479c8959e6c418034eafa67c5f93aeac910c7c8e7ed1a76a1025478ea23acbcd014ac6f9af8974939dea3a794d2bc0653f0f7a76b363b1161940a02f293483b7a022faf05cdff5aead9963b49bb853e7d5a955a8ccbc9dbc19b8a03a3b4392b0514032375d4ac5cffa322607e5445334a522529a8229422450c9316bfa338a81ac3580b139b717891c794014aa71e8b670b3dec0c213e222c2075e9f7d04df406493d58070bfa6fe5265df78f16f75c101db1875efee5e59e4e92d676cfb7cef96614a802173299ee9ddd8e3eeb52a6d240b4d4745e35bef9ce2b33b8deafc3417c4068790205fdfe2cd6726ca1d6bb06907f1810bf729da91d2b9d78cad329a5f148e3c3620327949b823f739b3cc5956e96170383a692db6571e7dea56f76ecdb8820421c42032eb3fd96cc4efabdd6dbed817c3490bd1237d1859d84a83b3551e840b13fdc95031e996d1be6024f3a70d1a7ae9f797a0052edacfcbceef5694c1158c48a4902b3dad0270b6425243ec332df96c068eee526a841b304de512e74196e09d80586848767eac4c416174e8438bc0282d25baa8a086ff578912bf355eeeb31c57d123eb204314138e7e691d8b0cd1b5faa9f6f499058e562fc230e1244d0fd7c85c10e3ef3f4312f55c3055fd2f6145777cbf9bc25dd3b3d63f47ae5fa2cae42f59330de29d7fbbd69421ca96f90336a2a7afe086cd43349b146efef77dd6fe1fef86bca21c425af21c025d11338a94fbfbd3a3ba70243cd4903b072372e1374f3c7d8160e3089aaeec9b7a82af5f38c650801e37ae3e1292232225f5006670853e058b613dbda6ef9d3d6b4c39413b88f619a90fecaae6ddb1d54b7244e4d17bc3ba84fc1acffceca21ee4ffdad1f55796e389e3a34db63f619c2544e7c00acdf8938a5da2ae951b5ae9bee1d5bbe32492ee4cc39cdd0a69704321cb8e0b6a611dbd5d2d0214e10881d96812fd23715cba243401abb67c38df3a0399c2dc2b88d11615985f2093bb0aee13b553bca3bb0d663843301609f12a3db7eeb0c91b1068c60d666b6c78beebbff544099777437c7fe33b3295a4c902d708ed435528136b5fee6dd50e8d6f12555f11b71fcb4b80df2bd7e038dce588de5d78555c9b932f4ff80db94d95fcceee9d12c6692ed4f44bc89385be54d1db7aba1931ed774073de0e23e0767a6d59debe34f6b05185aa9f2fc5830ebed467b7a09e983ac54700f49a77ab74c0ff3fb0ce3f727ebf634d38f9efd86b30943ddb0713bb5e59c10f62a4797e850c49117dfa3457e574836676f13ac1d6b8a755bd75dc89025683e18d025c489f38bef5302eeff3637b8041c1c9a61ce34eb0d03ecef048d17b74d1073d4938233c836aacf230137354b28595f555a46bb08b377c7489d904f6d3a9efcac71339fabcb5ba995600388cc3abed4a137fbff5a8903ef1ef7f92aa8f39ed79d8711394782cf0357e8dba3d1681823a5ef158e1ce10a148ba69f870136888069999a337080e5c2fcc1135dd8fcbd397c727f5b4b80db189523bb524c107914a2e933f9131ee259b5f96a940a4f721415ee86f2b3b7fad148de2f6d2d6334c3bea29f84507ac417246aa8150d844724647b52881db456ffeb72c4012f748ea032448150c0e73380ee1783e1dce84c52eba30918ad21cccf3c954fbf94415d622feaef1d8d7a19f38afcfbfdfb0c8b61eb80df8d8edb38dd89e536c27451d03dbc9feeaa11c2ecbbc9f3e4a5a7075d39c18a0d05e3f145dfaf30ae2bb5020e35e0d99c25a29072993e981f9d34bf26c137eb75d6a783268431b5357f31027ae916e1636edb273195e3a2ef10c8b3f0ce816f1a55e9b3307811b63d0bfcc2972552a4ad19cb81deaaf389c1220ae4077fb8c06a1d69137999738d197d8834d5b395022a4c0dfe1ae90a927dd0c6c8c591ce439897a97e3743c854f887784e0d70f298cb78724d6b62a81fa6a67825635b586a1c21c96d220009b5de6b022c6efb625ebb72c8f055b96a3b89385abcdb610685ee337be00eae0785a934703b49da75987b299987e4474c503cbae49e9455ac4544745a2da8328f27209bf62009dfaf846d1173c603ec82a06974c18c7b97f65d50323a8b4f521af278b9665ae18bdf68b92063d19408e8e66f3fed37af8f2a6ba0cfd91c276ed9adec7b919d191ea0ed26922a4cc6560c9cd758677e4fd53c3727964f010000000000000000000000005e3f40355546a6667fe6e3a791df6ece1abfa60619fdc10d5b54266e98a4e5ff8d4f3f791c78023d18e021c85d6fe889096b44be369272fd3d35c497a3754cf5bbd6cfbc9417b33643786c1d914ad10bc384a108754c475346eacd5ec68c58af000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e4009c6a5c1b51bc48ad853bbecbd9cbfda060be8d27270c06b6aaf9f0d8e99bd69d731dcb0b17e517e3e18dde40a503d810defbb9ea798852067557dc5511c69c30ce3830151533d63540c03c2d8530b7079b5f3f4edc79477a7158a103e624b280966ec73ee655d655f76b379dd57f1ff081afa6f076abfe102985a6877f702134a883c3b12615de6b1b27b1b39a500b30869684b749615da9a21fcdf282ea50328f5586cd19cb118d786368d16b2e080c2627ed425b63c5fbfcf27419c94e7d30a1b8131513b8befd61f992871cb27a0acf9cedbfbcaafb346c4e30db80178a7de1565286e5e41fb1285569b9356eb830aa44711cada2a64852e1f9b2b7c0872d1032a0e4dfa742350ae60b222e1bb27cec5d63da3f428a4210cf515505907ca9d6c02274c9e96b4b843545003e2ac77d5671c305a8cb4947a29cb351582ca46363776033036d3a5173f568400ae6ea10da27c39ed7d6599fddc5fec7333db4c8de75fd70229076c77be3fe0008d303f371014a8622db6242797ef846be29c2d252edba12b02000498b29103d5c8709894195b64d840feba65f08f557cc343bed8d5891e6cad3f7beb8b208b56d6a7b082c79635b914e861fcdad2f5947f6c41ee328ddeea662a8b5dd48b5f750dc18958e12196deaca6f3d17d7254bea919880b6cc8b3ef02b12718b018803df747e254828427f341a4ddb2473c89f5b2a040ab3dc4d09e57f41d850884799c6b50d1a13c67acaca194c298bc2790873b4e8064ee50a6a636479bb9b01591b0bf4bcdb5b72204f221c687365b93043ee3b282de41a0e544f3cb750929560c0d8edb221520b9cc778e6830ae8997d4f9bf379516a343b5b9df0aa8edd1e2651890ff1022c82440739d8ab845fef08130fbe5b7dd6645483f3946de8f02af67dd2584399b7525b6f9fc07dff717b094d1147b99f40d9b11813bb0dacfeeff588aefa91e2d71337c046c2c5d5f96b7c90622144541e1034e93218ccc65d75c643359ad7797d28e14e58c93384635a4a870b6b7226bd5d5f35a11a1573d649e72fff9957496b4f08addbc7ce8b339f002e4641f5ab13809e9af37f97312c27d7ba932cf4a1f0a6ee7ae9c1de49929ca2b590dccbbb6cbdd8a558d7ef5fb7e330076ceeb33938858a18eccbd9b1fb8b7abadd6d70f163cb632e75fe927112c0c991a49e48a6908479f8c8ffa80ff7261e2e57c82acc99e6e77f27346e0e0d56127132ea63a28c76c1cc9048ffe44389aef8e01f6e768eb5fcff35d237dde8cd999c05c4ae1797c1e483ce32586ae29acf5ea7694d557114b386c89d4a9e98b4c72f6dec91ea20520717ef4d817349747a4c183544c0cf3a01c75138a7d78ad4ced38dd12c0485b080cc87c2e869e52ca44c0a3d429c8dde924f8d617175b903592321b9ae2e971f23e6b610f8ef6f7be9f8e992fd16eb8171a6016d2d42b36e8b94c2951791a48595cf767dc4281bd3042516b3d5f2f3a68918a202ef8b541f8f445e1f6e99e944b4cd0e967ef46e38a852a517ef96ad0ed503c6504b6a36006765f79498c4dba83f9f6243e59e473f8c08a2c9f8b84ee6a507e904975282f5e84a907b456bba8b3e9444eafb5d36450c8a9d9af9a723c797e2d6436f8e5b1d7ca2c4285cff988857f51a6d7208f5bcded8f69dd7bbcf8372db2ba9928bb51de3573ee94a1f5156b5125fca4b3d29ba0ed33cb9d61dae1218b564ac8dba4d7723c4d03ebcae0ece8efc263ecc474201bb4fdda6137d56818e147785658474931fd1fe0ff92b472774b8d29e8f969690834d1d15beb0da7ba8d273f77540de435d3b742a03407a24150a1410418b6cf09d44425fe44b649bff700d11ec0f10b88c00253a7f4f2c8940be33de1aa0fbfb3b5a9d523f6ac6dba86fae6ea666bdc5bf2e316b5736e1aae9226abf9f370c76e71d24c1294d40736eae8f632423b89220df2d8a3c5d1003cba39e7041b1434852725433d0421347a4edb57261f47826d061bf27e587b74bd5b9d954de83d11878c19211334e7c386481aa4b54f9517a1ffd9383491f4a8086d4dd96ac34734826a4bba6f9f570b0b5acfb944bf581d322e56596f65745aa5349a2f66d6e41f7f1f9ec0ec0fe091a9df01096535a59b83934d7c3d219a13b9eb9ccdbd5030894c98853dbdcc64cfc93bfc127dd64d0a5ade440bb03f452e50f3bb9b397b1a6e4befbbed064ef4b5e99dc80916bf224ba27b44c8207c46e23bc2ee9d2d5d9009f8ba414c47d5cee35cf66b93ee3ee4f1ed14bf274fbdda97812cd3fc9fbecaf5bd0bab84ebb59122841724502bee35b3a3ca2e16ab6a8a0b72d19f62ece15a0334493b3701866b0fc90fa1a633b0d203fa348a169a3a7775324b0d5a31c9b5736b71cf721374c5098d86f4b312c4793a76cc54efc18ac49cdae3f200f80f", "53", 0, 317509884, "f09edbf798b59e2fbef80c480e999d4c7596679f7714abfcbfad6f83480fb53c"], - ["34a6bf8502d0b9b25b5379453756e1825b16d88938cfe275219a1e72f3b57193e0eb1a398e01000000045252abac3dfcd3b3f1bf14a8e5956a505f7e2842f2b59bed0ca086d5c0b2e6a53981d2672615b8d7030000000165983db1c9023e83f10000000000066500abab6553446bf4030000000004ac6a636300000000", "5351525252630053ac", 0, 2015930870, "11e9ca597f29de337124f5a11b2d4d4796323e99ef94acfd444bd13afbc390cc"], - ["be3ba9e202ad33ed4e4e4930177e5cece431c5da3d87f262f95b9bfe84adacbd6db232c5ad0000000008ac5100516a6a0000ffffffff981887a4634abaaff6af2b9f9130b94d6c0de9cb910bdaacb16e9efeba300c0a00000000046a525253ea0a53c103e01bee00000000000253652c400c00000000000453516a00e4f3e80400000000066a005351acab24cfd602", "656a", 1, 319576615, "16a5733a4a65b251b7c2c3781777047667e8d0aa8552a85d44f053aa9b191714"], - ["86214a3802ed24ed7a512e882469eba8449aa21ea22f1d63e738827fca334eb7c93c1a4abb030000000553ab6a6a65d3e196a867fe92c099bd3de01735efdb1eb69b94a45a90d15deb7fb09fcfe14ec02456ee030000000251515de197af03cf0b940400000000007b257b01000000000200000463f6020000000004635252002a653f3202864dee04000000000000000000000000c511532eed3a6c91f164f283bed3c0f1eb1eefa0c816619ba87b33916fc79cf33795d92939d4d78bd0eadc43a46c193fe5e72527bb8231211806171c6af6b7b30ce9a320fad2a8ada64816aa14013d6e2613162ea2e8932b10d83e1f4969d97f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000807b59db0f8f4696935dfb6ca0136a60a22daa61ebc1b404dff1ab44977ff7135ebab42c1bdf4bf24ce706e8371ee7215b985f188a436c5b7167ab62aabb720b9498364b734015eba0ac7bcc033aaa1bb0032be20d6fd26c3d7cb2092311e72514874be82758db0eee94dfd0ae7dd7841436b8bd98db8919472006dc55a9b1bb0220e12b3beaf93ab79ac65e71e820a9490346a27800b75203ce82812e795668950323e9ab691c5bd954d07cac2d465b66538eaa767504a437c4c5a69e800a3e16e10b13bdcdf5a726aa7d280c4f92596f9e1f878a8b081fc52d845442d117025840580339424ccc67bbdd6365d7d6cd105774fbcdb6f201ea6a53316d088653ccdb6103164aa2592a3c241fdff966fc8ef27d828a4a6e33cf02e3eb546b99cf56ce796f022daf88bf66cbbbf5548d413cf73f88c61b7119ffbf749091a979b1bd21ef8afd021fa3ce54dc70ef5306b9ea04a6c353e489fade09a88dd491464e42e605141cd4022cc27637589a3301250deb6f5e1f1cf103edf1417f00cd9ec985e792999cd4680328e036368c692f7516ffadd69d4ef8692ef8ea6c5aa54ae6beebfb4d0e84fe444765204bea445cbc4ad32d243b927a6b69bd9b4b8aa348ca1b243ab6f0fd0a9479ae6c9a368bcb475c0efa606bf48079d1a63d5417719688154965d9c5416e703899c6abcaa45405a0152e7ca54a4579db0bc1f92624b245658c901e5c9ad490d64243b60925e3bb77fca8c9336ad7d1799899834c0cba207dab69947c6a74d60b24c0384f1843c18a7cae766bcaa7a0444e5388c0d342dc6cb6614a7321f4df18d0c1003dbdb613389b9d5f26df919b35a06aa7766651cccc93960057dbfb857b974682c33121ad392e1c4eb8a8537d8ea4bbf7c3e8d8a051c523cc1b7f123a4c48192b1ea0c3231200fb747d32d2c38e6b1d693b7effe704d74aa85f8d85e479656a146618a8294c23ae45364420cb957edee1fc7e31e1de775d2f34d02901ce5f6b763decf59039f0e945ea6ef549e818a80c5121d1d6a48cb14734b7230cbd93a82621fa84bc3e935b8fed73fe2c830f469fc2610da7b33987612cb148314c70d51e54e9a024cddf040a041f6b646475a7b1051a913e3cfa097c7ffa5fa034b22432de26f3bf9efd206f267c9835eb67af43d99408a263ed01a74f900ce756a891fc1d9b7e168deb74e97a92e5d171fa82d1a3099cf985ac9969e8703fd02d0dd96fd9e07ad6b3c538335aa3f3e9f055b7e6c74433d1403f11fd4167d3516c3eec6b14c9ccac3abd0de136114b8a1f8316ae86b609e849cce4cc0da2c482b564dea471b780dd4c6388b520b199fe50b5c2099ead88c2361b7eee4b02c040b722f7c235c027186f326255c2d5c55b29f9214c80ea61d65ef111ee974c9888664211658ba022bdfb4fa8e6d3e87af9a2269e1b41ca6a7da144562169508291ec1c3461b54b0945f03399820e144ce2520eeb1ed8be9d20f25bbfdf14c479a8a6636b91327a56e565b60916afd24c86e52a2da3b52140655a2fc660a94eabd19b1a32b547850d0a3ffdfdcdead7db2b9649fa43f596f8ef6091bd1fecf36da4e63f9f0557b042d5ee179317b50ccac7a9bd50221fb7fa64b99b916f0fc21eb53d37bfa1e6229c257de8b9164aef6f464296726cfda3666b85a4aeb64292f9591a729be7d1c26b3aa85ba6de5056498fe3a8c65e2b7232c850edf75c7dd9ce850719db2ab18585c1660a70893fa1fe6c226f35415628c5f259fd3a969fc6480051b16578cc7962c1c27e47e4e275787130ec1e3cf31114717f7e1dee7c086bdc5d1d954e19f7f6953f5ca44ecfc66bf537acadcd6e672e79a07c920328c01a807bc2276bf64ee851192928d9c3315d261306ed714e91d0d1d0ba8467253d7f414f8ce73fd1564521d07d27aba4c7981c755965c9b979d533e458d5dc08f612a627d3337a02b942e1cba8cc2f8a790054bf3d51e5c2b784c9939481e6746ed0f2c12821780b244693987c8355a02ddc5978b923f9b29ed33b99948695e345894e4f297598ca23f749737b28356751150376b71d5ac5d757160a1658f4899e910dff9c9b22c262a36263e2e713ecd5ba0eada5d228db79b959ea7c34bcf3a8d247a599a64cb6f08c7c19bddada376cb47692665f2f6810094b0d96e2c1eb3ea87e2d81ae5ad3f3d5dcda0a20150c1d2cae24187fb7a9d3d2ff1c24a701b86684114a099360643022288b1a5ed8b032314eba43fbfcd9567d72259468b03551f7963c5a29ade0b85f1fd9338b04f2b71504e896d287ae0100000000000000000000000053d1acc9dd20a0d6fac61e0726bde5e949c482913b9d88ba1f56065b759b48ea99b31a88fcc3d973adaa64987ef7c4eeb021063223a65674c79c288dff7b7c943d1f1141963ae92704d98de36a3f63376af6fb713bd12bf6b24df3fb87c53c2b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005eda13d5cc3814b03eb7c1baf0b365651474d6abf23751c5503db9c2f44f8db36103e5f73e47c3dc138c3d046aaf2752697408e52ebe05b64897eef1a94519353c85d4a0ca9ff1c45bf2cebb1261cac4bbcea73efd543c57a9ae1b7e280830382e216773e02a17f23efd177b5c95ae72fd7aab02008a0c63066a99b2776d14d80318578be6d89e3313f2549c7876185ff1f1504e8091d93659359054163a7e754e02085cb19fa3695d956fd8312baaf187eccef6c29fced77947170521bd5c78046d0b1c6bc11c818274168c036e771d574a8d9bc66f4f6a78d193d54a70084958aa0a1367d97afcb2830c726345bbf1136c0ef803994d03563acafaf6da7871b0d00002261c58d27d22c766fed761411a77c4ed87d4fa2dbfd7601caef16dc0a061f27e031ea51ff40e06e319d312b3ad7cf5825bd82bbb6fb4aa34c5f1be95b68669986b02147f6b7006a790876430155e6cfd6e09a5773366fa82016a10219ff4ac5534d402190136bbe547bdba3852b4250ef3f35fb6ecf476ced9e64118958c2a27baff65022be98ada6370f32ad59146de40680d6f33c8dd64eccb1d57b2b8d90575667d7e0d5c31cc555f5e5119a8bd8fe00ade53bcbc68b5d1bc86bd29fe8aa47c14beceb5bf807b19cad55a8f0cd42f76fed8403030224c857b0581a8046f3eb787d955dbde82939c7f93384db2c524a40bd96b52bb0ca9fac4607faa05cd72e2c7d6bd1b0ea2cab15091c6da5f3bfb768859b4c424e02612c6d39e84e5242e9dc6ccdf0a9aea367c4a2991c17db0a27d279aa93aee6e3ee194c532b1e89c13ebbe22ac590e5f38d290ec2c3a1a6cda7f9e21bc94e53c2fcbb53d9dbca535590202c8516da69cd715b0913719a1cd2ea00f50d3ebf0ebce5e51710e4a299dbc3f347182d2cc979d75e93c54b2f97f7dfe41ce71c2bb665e3d7426eb44eaa6db9edbbfd192a226b7239051d1ab44df254424a788a8f6e0646dbdd9a7a1074e814a67e867b845d02293f92aa6e3e421433c8832389ce3d431c73e177be6a87ab830f73e4716adb907227327d8ea533643c486b7ec828e7496cf88c0b896ff5033c718ce2a483148f3494d2747e9e546da67cb021c4648c67ab605368a1b34c2200f5d9c1f9e55db319e9d510a6154b3c2620a568a3b17821323d93a772d24baf72243168f6f9c2d76e79824d1293a62d9e791360d8860c4ee3c317ffeeb00f9731ceb483c3a3550786cfb8ba87582c375bba5c3d3e401225955d30d7729e7aec1057d4b34157339201fb27663d6df7b16f916ce560c5cc4e928ad96dd8a7a9d3f5cdbac35e42b9b8905fd7d5ee7a4144bb3e3f61ce3428f3fca90da2bfbd4308a6a93d000a6dce99906089a5ec7e04eb62d662c651bdf2d94213a272386abdcfb1601f15319564c9d537c507e2503980bc92940da0b8cea91e06ed92625c7e6aba94f9668aed6217a4afe4091f1f3d9f555c1cc094d838768e29cf4c9b2c2b6b0f2c27fac1ec00a6a70cffa445d8061f89d584df9d972562b879d90fb9abe93843f3e4a57273caedba2cffc8d1ad7a4b6a1dcbc6889054e21a19a32de6b7e97c2bd339fe2582af3a6ce1b079710728d034ed7a97d6c71ab118e37c2d3d2cef4ae673b52db073894cf1785dab370dc9ec22632018126d48ce33dd73762060361871497cc15ccfa5cb15f1f31cae2d5e4b0d895c9a1829a43e9ec1853740461e9da095fb598dbc922da03a4ae4663934611f428361ebcac794f03648fb90e34bbfa74707a22f17f463d0bc97afbac55ac5179caec4e44820d5893a462c17f9945e9d4ddaa7dca1ab2944be65d620e9e8852a374cade035a0f998b5120dbce1545e08278141778e070d3da328fe1f7678d8373d3bc9b91fec1d30a1cb1088ee375238dbe5c5eaaaba361818b612de9252b53e336ea37cf484106424c9e0b172d3f7562487bd3cb8bb97b662ddbb74437f3505a79f5b0838b7fb4b082589057e6a07e630c53efb609e300ea78820e8c021339c72602062da151f07561faf3efcf54de2693a2bb542f07f78658c0650e38854964d6c51af88f336b54c52f63d91ab3fab705428d20a882bfbea7b25dee6828f69d20a31b60511b8f25defa2a6a25a578c033c0d0321e5bdf86d9a873519002e9aa8db8a2ba126e03f973d099220ce8ed3ec2ebefbeade39fd591af8a049a8fcf5085db4cd21d00693d4084a297a95530de02f6089ce1f929b95067129baac467785f349317a706727063301375548b8a85ce36490c6b69e1d84d57a0241e4ab11702dcf39a714f8e3e7b3e1f9c6253a3c88951f1357f8285b9fcd4a71af7c74c5d4df8f6a51ef879fd15a3043b13c28ec580c31203be44273dc156901b695161725ebf8ff8ac9a2bc3a4aea496df21f065091e35f14582ffb975fd9c6635828d45b139d62f07", "525152535251525252", 1, 874355774, "c194cefbc952cc19d73bb72fdcc2616eee20409955737998e5a6be4218ab4b42"], - ["4b1779130379773e90a7bcedaf6166731c2dc1f7e802fab53ef2b65ee2ee01032281b8d7700000000009ac51ab6a0065635300e9e7dc924a2cdf4685fc9b80c5d86b3692e5431877af828f969b1832610b7b48ab640839020000000265acfe422382ac0e0b607fffe6ad09c178d09f4eee441360b89c476556fe721babb8b0c37aa30100000007ac6551ac5251abc3d4b4f70286cc1a040000000005ab525152539511ea00000000000465ab6aac0000000003ccd31705000000000000000000000000d9487ff77afe55fee6c556c1e9d472c01a149f04eb71de893ead88bc752757e90b11251e28ad76fa8df9870d60f9015f5a8a5df8d96a8d92f2d9369cd5b8171ad1b5436b22f081ecd5d8481446f7f26009fc845e326bab8808b6243c9ec11c1d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a428780351be73ed3050765bd5a6b0bfe46ffe57f2c9f82e39ef0d844901dfb8055321878ea2d6a7eab9cc413747aa006026f9b992198c8eed012a2f60d6176487ed271caa2e85b3d636e2c0f7180df01ab818e9b6895fd9e66857cea65fa77b1b1db2160bde856ba58dcc052277cda303d2d33f69a831b256769294f9704c8b032aacaf7ec4e214cf15d4c4f208da1f88f415e5a8866972e784d78130c7c6622d031478f7ba2c86cd74c16d5a8fddd6ee1c9b6ee618740112a1ad5aa63bffc23cfa0b0eecdd268cb559db0429a8e639f390b5c17ad0de365b855e169ae0a249594b6d0478cc2c6801ad97525256ea6b3a5344f4fd707a398e7edd6d0aaadc6839d397031a748585f414320cbd09972ed0fff8bf65e0356396682a1161d2174863e30c0f031fc57333ecd583d41309c4e21a414ad348e7295b9924fb322b5a6d14eeb830d20301c35527e81094ae9bcd4ae566a04e2fcffbe650b148e59c7b0cd092ed17aee7020c5cfe7f044178eb00cae6936143c05325d79b888d39e9599f2f2641ca8eed2802265c6c011cbaab15aafc0d13ecba67d7558379caa745d131b3959777b82a8df30c8aa798f2ba97cf5597d97e6f0251c1959284b58d157d0f4c56054cc6163759eeeee0628170c3ee95face0c794b5879246d071b06898124f00a280973fae574b6b9a19ffbc4f6546f92a1d63915955a299b523d45543e21317101979d25aaf1a4ce85f766686f7f7a0d830fbb85e0a7cb4183c673eae2b5ebc36a64e7bdae22f7810638fabc7dd42311b397d6ec8eaf08f1696dc39fab22f0f39302593221fe88802dc32fc379214538eebff1f3f5a2ae8bc4368af8facd91ec1154a82322d6b9c9bd24c24d54a39b493b8a2432d82fdf193533a80d41bdb185ad7e1734ea6419187706af5fab470fbd0c80af29bfc667aaaa5ad8928a28075771f4ce1474ce2dccbcf2866d134a3bb8ce63cc240ab13042b90a52fed31d2b17ce16d830f465293122945c22edeadf341b7e7ba3d3147bef7d110ec23e6332ce38f25f35d27ae208db400c5973ca10fe5b209a651eaead5efc82268676e88fba757cf357ec1e0825151b2e4dba49486f3124d871d27165077b6771f7e585a99910b559780e7cde8f83eed55b5c4f00dd03b4f8f6f730f719d714ed0d85acf6a7f1e3a37c194ca4bb2d88a22003fd90de7e84be7545fb66b17fd300415fdefa9128181b1b89d5c40efc817202d862e3c94e6683fe1f496e67fb9185c14ff7e15ddac69401099ce985c81752b4b61f93c3ae4c340030d7ea783ef8ac7e6dfea111d696474674b474c1d5457dd245e5ff778c8b6afd1bd460f914c5b52e1b61c980c8a04924082595edb7d701d0d1f42e0aa3951032d241b3296e0a54ac548d2a9a9680ed1c1f983f24e0283a1d8d0afe8949a35df08e90bee507dcd46ef9eb6403b0b2b5d7d5ed34fc217d220464804e7f9ef17107cca9ee0626f858c266589a6ae959d6f35d691e1309361438b5e816dad576d14eaf7d01526101b96ce549f3a514f191a89fa9b0c187589420e4239e9aee2d7dee1bf743c9475a8aedaa2d1fa386341697b5344bd4fab30da2fd907884e0f165a8cce0ad057ec692aaa882a50249266278d67723a4fdeb1f044aec6c1036b5f09e865529fe218074999ce2e6b6e5ff485cfad18dbaa3de2b298a2d9a34a7bb82af8d65236643c5a618d25735a5256c0797f83f104b2b4210eebfca239b164c4244ffa9e35bf619a6a0ee65416d3005cdf27b401902cc80df3ee8edacacb045f3371cc67b14bf66bcd815c373cc0ece2edb5ee9727ab0f6f2bb6ec100c4fdc25e3369a1f250fcc5621aa06397174f3e42209fe138c9a00d4d75a6a567891adc81a44afae2843bb383b9698cbf42fb1cd63d3b87781af773b4c778d0f5ed33628e79a9b12c972125cbd3b28eb899df7ae356ed62ea39f684ac826eff9f5caddc45707381ea25a705a012fce56df09f13816c9c7a34e1a53b559af271d071ca377b236f385144bfac6364fc8bf764ca47a4a39cce788029c7bd05b9ef40d9ea303e673005aab3c5b40148ad318a3ee1a9c230c386b86fdbe6d0ebc8eda18d4ef266c4476338f2121c128a59b4c8e9a745d76d44ab6e1db64b8c6f8c90296a2233e41017e87ef069157c4f798e65c56f1819de3b1c51d48d381667d0ad275319702e0f163da86e81dacdee69ee4c8119cdb7c475e4a59e3812d741a4aaf4da742a1a6ccd7d6e091c1385516a3c8df50a8b859739b2ccef872fe4b8802a9e425db8f64f327c28e5a60c2b01000000000000000000000000ce5f74589e08caab399398c755ea75549257b9a7cebb5a733f79a12c8a0c2bf4570740b22b7a49ef59b7c3d7e0e2643df77353f9493e53aece306cf72848626a9c0fc91fae0b2ba596c75256c96fb5450777c98e043fa9453df85d4c4af42d1800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000638cfbd2fc165bd2fb60148d24de56a6571d5ff0a52fd7ae813cdbbed07cba7d7733efb13067367b21b04af5bcb531c5e70f75b1cb7f6a753f9dfb05fef76ec0645596bda5cd0f3efeaa10f041603d40abb2c58a174a84fd82822ec0854e59bc381f5984b9a3899b6662db8b7cb062b9e750497bcf171f741e317dad0f6811f6021dde911cb1df4c62f5906f3a4d609f9d8bb795d6e534cd799620eedbedca98cc022d1404211e5f8d066500c7bf7e41061122e11878bfcd0effce5b2fdeb683ea010b236564cdf7f3004ce7fc8e40c6f54ac3f99756856e8fda69f652cc9cf46d110c1b4361803c964f9d58946fbc2913bc4c30804efdd655549fcacc40cf9d9958ff0227dffb689854ceafcab78ee7e486f3ce3bb6d0578821eb82cb1ea3e87117d67c020b901b8ca404a89e51e29ee0536cb51432bb80d43f46f8917a303491f37f3b72031c7287b239862351b5dcaf178c8eaba4c15a247ba17437eac4a7f7cc38d1d405030f8d66dfa75642567e8526dff5ef7720ad9f52e38d9ba2e57e25e3b64036f82b0205831e8d87bc8b1346b5d2070c251ecc81b0803629202131bedc9e648032573243e675b5b0853c1529fcaf71c05f752146ba35f659592bf18acdb2ea19ac9df27bc940201fdde229eeb6eefa051ba61a4a7fc7021a822b5859bded09c44acafac7895a4ed39688f5188fcc68521aeb53a94a71b6fcbdc509e565fa02bd0f6e5cdea177241dcef4f36428020380e0a5563e746ff070fbba992068fbec15d3294cad73ee77f0108af39d377e26bdf1ef0e08db8f14bd2d1a64811a47a013323bf75fb9ae78b40981960392fca5d10b6666e3d878ab439f5090ed239ac426032912d975127f5fb2fcc7e315f677ba125e2257d586108fbc61703543ea9d832f97b65de4de4f680b5f0407819ae90abcb2a2b28e16f83fc6dd8be37438391796d89c79f289ea1006c6e986b3d8af2896941864ae32220862b841df8e2bfcbea24418632e93ad7a54a4b5e128447e6d7e9eee81631f2a1258de3a1c18594ead1163ccf4058c086e4fa2e6cfb27bd3a9611514e93282747299c0c5333d0af8cbc136ca3a7802680a1c0fc662db07b0c03fee8233d20c67af2ae88795d75a16a09593bfefe58c1b198999fbb099ccc81a3b9b7704ef53710260447f6876089d7fdf0b1cb2e84e52fd57c9398d5e127286b6091ab2a47540b1ecee5a9099a629b3d320be43b202a579da775a0f8c47d65307f63193f76952d55e7ebe1aceb8510548ad9cd79db3c50b292f9576bfa5ed392fb2ceada2fda6b7d8528bdba12ca7362f1bd59a0b05e480553677aa2ef5e7dde4ee04d4dfe071e031d499746e30b9fabf37923f96a2977840c26a26eba7bf4dc11f88a8b02911aba8fee0313fab261525a486582bb74ef926a58bc39136c6807c7065c63c97e8a1127b9e552cf777da7986cc3baf5c6abfa4aa3526309bf58063ee14988ea5d910181382cca2962e4064dfa134c0cae378eaad8d10b60db8bcb4e3da957e558aad35845d033386a2586425a278b0599ad07a276e9bef7259392023f01168ab1d9d7519d0797dfb50887b869fb0011a39cefa3d401d73d8a6c0695a24680be302c2abd5e89236dfd1dc80a9fc01a040aeb78b22984a012a9015ad36cc1e201b6950fbcf369374d14416152d5d62972107cde474f8d8dd980ae1e5bc1a68a46b18d4a879f168e61810bc97e5ebe5ae4763525ab4a1612d73e7ad98a6d8db29b56c8b1e2f6c1f722739cd459afe73aa7a7576b76530d7b75f907b8e848a702c33c6b563ac191bb41538ec3f05250b0e37e270e02431184e4041c8004152d6a14bebc83e55364e1a634c4407e2c6893e51b6b5dfbd8c7bc9aa09d8ca7105c46b03f809dbc5f47b93f07b7da8c6f2fd6a1c3452bc04f664ca34edfe3bf4450dbe3db82626686171a606f81432ef81085fc4ac1a03ca0fd502f9e986973f0d159e4c0fd5216b516f5987fadb51da2c25c68c60c11a152b31019825f9e65252a117b45abd5ed3d93d826d7f54125d2ab07867f69c2854e3a32124ddee15bc5306b1f6c243b681cb37d8c999e41aa0e5da59d27a199d1a2daafa62c4d9b511e669bee748c6f6647692bbd475291719dc3f03285ba4bc65b4888d8c841dc5289ea39bd126f8a78f7efaa430e5776b73efa28c785eae2a650a99148c158dacb42fc46e379133fc4eee73df9a906446941e64dd861105e410486b35e2732b3938c1d1ff8f831b4e751d8e4034b7c4214a310c6bd2182efe18beb2705332ce1c96574da40832b604000000000000000000000000cd77635e675e51776ce6975519748096d64d553a4dd6a2eec0b2531b59b2a42e897ccde04954046c7bb7d51dd001e388d9883d467270d132123a8f439ff9f6bb7c922cfac4563677844fa25814e75eda15205bdfa39eba89ce75274a54d49fca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042e9defbd88613c3612a30af34d8efc6b3b9086746da3917ce850fa1bfc50e47edcc2087dc5c152a2d5140108dbc5014e8350becd81799afc7961155aa76ea43324a66316dbcce7136b4ce9fef2df97ea5771f4647b2b447fa0f290cd6ef6b8750e310de2c29d986a97ccb5db12b4f27a78849e1a9dcf7aee3629267942b990203029ca20775f6d25436fd31c78e213736bd2132b3b35880377137d677aad2628103087c5d1da4526529666261c2d1f5844882e7682209f6ab6eb0192997539473310a147f536b9eb411315de9f0e3e1947c1fc19d424fb499c15ca8b5d77e474c811413f51866395745124492023aeddd1e85d33d9a63d753ccbf81fdb29a2b5774df032b7ee51481eabd98457d31887e9a3c121033f4a55c0b347eb7eb5e0562f03c3b02003d367bb570852d5377130eac51ae22d062e30c60dce8f83654534e7ab9cc1802191ebbff4274cbe658ccbad5f1f7d3b66dc0c9571338b83813daafd2b0f2b1d9022a827c0960f696290cb161318c94a4438a4926e9bbf0eb2575919fb5983f4880021c66ebb0a66a09655cdf39e5fcf39e093e89802860a5ef4c930db9d065d644e548bb6ada41dff43a800247537260246ed58cff2b16927716a190dc77fd845fa5f5f58602c3c693c98679b3f932c5d36dc7f5629d17d28bebc8ad92f762dd4555950208de06512a0579197577681eeeb78a0d72fa7670179cfefe278ce6881ea796b75e15bede4597da05a063cd47416466102ac88d153757baee330f4c1f91709a14bfeaded6c3e28b913798023d385b769942e90df5033d83e6cd8da03c46a0dd8a61b8419bfbc14fca3f281061bb021dc0ffeadf6f73cd722f6661a1e3d9c63ea22f3d32c4d3cfb2d7d7126cd7fe73bf4d6ecfe4f25439b675e18314ff40d0e2e5d1b7304fee6b65722d96fb60245824413bd8d3119f474ebca5b61c4ff88d0049db114ed170f814d509e312082e1cf73a7f447e0b80947da7cdf2964cce8817e0aab8ff903a7af48ecba038e9a996bb0da92d3a11ad3cd1f61477fe7f145007d1e64439fe64f59a2dd68ac40cc75f71cb3373398c986e3326ee1818dad79a43274dc7c1d4415b0165c204bf09d0b7fd06a267b2e265682cc87cb1f2d9c84ebec907817da925a361b89f3c3a6c81d4cef229bfcc6b077199d7da629c1972215d0dacfb355b5c499e7b8d8ebae14dd4889859a55bb01b3e335d483e577c940309c4432701209f50165ef6b551d22079a42c91a5147d15edbbb128cb2b9e0a500f503bc32dc530ad6d703b21b451999914f0a23c191eac2f967b75f16c1a31df1d50acbb65e3c122c337636d7e7f46ab5e581f6ce72409944e0fd77160d264e61b2eabf8385112fa0682097661d9043bc8988db60eaefb7a9727dc9b5276081605b0b14d00192defed1f153b7ba685b561fbc4e9c73ba428d736d40a50ea0e3d780707f15c2a714033a73b698b35506bb2a8ec10263d183040a06b3cd010259aaf42ecbd19b368fdf5e691744610a7cd2a73bc196265203d40cf0cb57df1e6d73ba8e20fb36df43c62b3e8433cc918df72212799acc8cce1464d342cdf51d528138fcfc2adca26bbd1a2f460848da24d1395ba624c547cefd5d16748a17e0d372f535c9e361e7b7baf110720d49e4550ff7d9eb3159e47809f30b565abfb08d26061d2adf64cd74f3c0e26cdb5ad540ea0d98c3742a8604a669d6b73360c051fe79451bb7c40491d44e77fbbe804de044a4fcc510ad1fadf89f9b1e68cb09fa23f64cfedfd29950b8e689298455cf6ab1a934cef9165ab019ca494b8aa2a371c4ff6eeeac9c227d7057c53c933be858df2b483f89a70d1ce5be1c60d5d4fc8968a6d4f4e62c37a867dae33c897db39826de3acab936232929753e4ef444c3f14a1674f32624e0dd970455a8cad745c2e63a076dd2bd3ef6a75de78e83307b896b77b1c59897f293dbb051746aca8ddb60e6105a280ae9c8bef1d4b37494251b4c209fdff09e3b590af727c5bbe679b665d9364d97619da56448e0cca0d7a29bbde2720023ecb1372c8722c1e59453c5e78b0408d72829eb1f1c0700a0509d440286dead5feab4a5dbacc190171769450cfb98fc8c3afb9a4f03314661bb235a8fd74cab2a9993dca5d4cd8ea116a1864e4924539904f6fd68484e2a67c212a58fd2bb4b52443a2ca9e5769b767c0f5561b4962e4adf7522c66cad338a7e576b7e47903266f5bdd87eb3fdf66b15e267b617007615a2867801976e79c65e2cd79acfa805449ff7f80f8f817a712ab64c8f99c674fd9743f4066bb02333ea24a7ddbaf637f5f6de6aaa2434bb990fbad94b6f9f047433322019864356dfdb17ce6ea710a133494674e2395d4813ee558e71f034d149e7a81c37cf9d788dc725a70df540365b3ed89422f9aee450c0506afd900", "5353", 2, -629875690, "09b872f723a94b60ea54590fc0b79fb1df5927d2f346f690bb1d397775b703a0"], - ["9a8e738f024c4f2a0ea0d9798c23731a778932b890a9c034702f44398fc47785500fa5572d0300000007006551636a5263ffffffff3272fc64982e6460565b78fab5b21be8175379d1e0c620b6d828da5b0df6f15000000000045152ac52ffffffff03d9af1f050000000001ab86039f050000000006abac65526a65eb4d9b0200000000046351656308b139ef", "acac6353ac5253", 0, 783240628, "901a14f3e80ee663834cf4ee657bf76a6bff8741303c245435aba668e3163234"], - ["2ca92b8903b596f66399b4fbc286ae984476fe859e0cd5bf38eee2348d83018a704b7fd7ff030000000665530053636affffffff168d587268f3e11119af4cfbd8f18fbf0ba118c2db8d85d945b686f5b459031000000000056352ab5300ffffffff44475b5bb3f71c15ae82e015289777c131491feb7c3960b0c67eae3a8f3f2c630300000000ffffffff011d8639050000000008655252650065ac5231716896", "656352ac", 2, 635848537, "d3b1a62d55e5abc3dad759107b31dbea0665002601f8e7411a374463c7004f57"], - ["d1613c6002503ea6ca8266ca1360d0ef5b481f624a0ab62d20c149e87ef77f9895152e29420200000007655200535265acffffffff6c8839515e5117259635abb496e3ba6e12e991d76f17f63c54bde364f38e5e9b0300000000ffffffff0315693e03000000000363ab006b862b000000000009006aab5365ac65ab5226d359010000000009006a5153abac656a000000000000", "6553acac63ac0063", 1, -603815286, "a42f1473525fb6f429924d8a3c203c140410809f2419c5f877b9b9ad021c5481"], - ["5455cb3c01432e337b6768e607c5e7e5c821034d454e9888d051b7cb7060b8426b64ec1450010000000363636affffffff01a88be8010000000003656552000000000158e1f804000000000000000000000000751475f75d70b36f157e8f65e942cc9524ccfc9190e2db56e7112d9049cd2d050c95fd0cdd4fff9c28717fd9f2b4677be36211eb2e0bf5ed39d007dabd60d1a2996537a179148027c33af3c554241adb6276a43cb64df54009275b74e81a71250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a4b7420f640d7c142b469654e078391fea6e159f9e4cd1e7b497742c835d6d2ee6541e9921b3a1e3dac983e030e2428ac0c8a656d70d1bd73ca4859dce7474c67a9a9a23deee42a7c6f55f979e8fe2fd7acaef3c984c2ce2317327ebb666be81d77494c7b11c4fef923e495624cb4e99dbacb6f16054b93433bd22002ff5960320739676f7499bb28680b0a0bb4c6c3b543c056c5171550e55c40234987c9eab021d23c9103fe2d156320453d612c05bb90f0608ce325b1e7d4b64469a00f8986d0b0a476d9ab87be33fd4354bbce74bc3e26035fa989734491ee1758aca9560279c1b63a937b254158049de831878d02b18eb86d580ca106c033c9a20be924216a40317a835f491f8d823d305ba503b2de52f3d06d5f9d9c243ec82d0e3b07c308d9702267fa8afbdc1f7d44210e00aaec1775ba10c3d8dfe7e3dc3e60f201546f8127e032bf45bf81d13f298e84859dfce04d6c70a56720d40f6526a1000a54ef1a053260314c3daae1a483ba53dd41dc60e42af2a9cb80df2163cd35d0ba53b75eda1190d021d0719685bd3d8012740ca4b43d4d9b50cba7be9e36a883d0e030d110b3775566c665aba9ffb8980fc72cf00d83930ecd4e89a5663f4d901fdf493ffedaeff1991860ac9f83c13344a905acbf5f38ca74a6432573eb10f0e1e18ec4095e78873aeb06e983ecec3aa8c8a32ac826435bdd9b619d0431c5e2884ac44ffd7b9a92cd44b597d57dbcf40d0688ca19184f7d5668876ac74d17d3ed20ebfe88d7a3094306db963b468f95d920ada6965ef6694bfc8598f95bb4baab21cac2724a4ef7081da2d99130d823d034694c69d86c4e7cf435e2348579d30391a3e77ab0ce461d14fa803483d77bd4fa913ff7e489585928480e344999ed1f14e8593b05c9991a2a6e6b7ddc6fac9546ce56db5694fd842f499fff530fc263d773e82732fd51651dd0d174daf3d5d3ac67010dd3afbea04312a6a358c3b8ed840c64bdbc1a626c7ca91f826c58cef5ba13220bd7cf81de7dbf0663c4f57f55377627259dbdf641c3e3cba5845fe0d0cdafa0b81ef3e774ff837e0ab06f785f170e074760ff405a30f1295e0666d77ec8e162f5dbf1606e610d0b1e6489f7983ed1cf23c703cb9ab27eae34743b941730a534cce3f47ea9fcb78e957ad2d4e9fa40bb0343d0333fc4c6ce257004fb3554f7b3856ce547120299f7ebabcbefcaabab3e99e0dbd5485ef45a8c8c671c1a61620024e3a92b3801ebf40179fc02838f97905964be0216cd3debb2b429c26efe3929b413b4ef233dd41c0b26277444ca5e2a052698015ce5fef5a4ae48c1bc8cac2560d7e0ffe2dc4d32a81fa8c763bc8d74e64b5a04fb5c3e50a99fe9eff605173b28d36276fd12bafa2bbcb5f07df06e8c042fec67067738bec50b2fbb8855d6a87afe03dae01ead1b6a95172212c75aad6279e7114fa794e4abb580dd2e4f1238fade127348bfc3dc5a07f0e6a8e15fce7c57f8b8d6a56f284652ecff7ec103c92734576e12a3ea0150ae4300ef68643b01a46ad549fae633375dbd48472b0c7f0951b72d340627e207b8256326f81c8bd7ae99042ef7e2a4875dca1daede0d2d41a4337d1cb122dc9ecdddf9c0a25a124ac07817d223d9563fcf362373de0b04292e0e1b5e2d0d6e908604d51686c283aa14d886f39d8ab2ac0ea9b87ca805b6d48d6615e12920c3d66bfdcbd40520d8ac33111e1773f93238fece846aa2142b54114ab54ce03bb78baa7cd8d453063d644c685d108f5f6729dbb8d1f0a7fdd71b3c16f3687a87785990e0a130600aa3bc1e3587515e0110a53987484f8e0580909265abc2cb174d946c6dce5d3647a4df34a88bb3d318b96389b87a797fec4b25479eb687350304e8b27e4516ceba23dd2b256fbc0eba047ae0d0743fadfac8af71e1ce276ec3dedb979d799bed3c1157a7224fd37a0d3988a36f9d99bf2943ca0f56852558674dbd623972de50e933da9157262a6243571b13e2e571f05e6cc693f426d9c55f485a5cbfc3af30fe90669eb4923f51d63667509cbc62a811ef2e969616c451353b913a2c8d189265c56a320f3bd3fd8ef6b9d6282a755e23bede679879283e8cceca76ed0588ac69df4131eb32116f5f9b5d113a0185a7133081b7fb27693d86abe865466662b80cbf0600e43b3ea570e57c6900fbb9351d2410b91ee7402aaacfb55ee2efc6a3fe46995031e2e264646ac91fd1c6a4399e5ade4600850c80c4425166027a950b95826be0e2b7263ba63af842f7d1ceb6f5e952a11593b01ef89812e274d3f6e4307e5ab2da3aafd2f432faac3a6cf1722c8243f4df26aefeb8cd0d0b65232dd71f81c031930bccfaf8dcb2acc8aad0e1bac03e9256968c3a8d3b99e2f67e23e7b7a4b43a6f53e72a0d6da30e18caf33cfb3fd32ff330ee108", "52acac530052536552", 0, 1940604312, "e8ff3902f4734992a164fa90c5265e1398b3d331761475a65ae0e87a3263c9f4"], - ["154665a4026aa2fd146f4e8a79032d6e0454a9c82c0268ca9197b2b68ac796ea2ac56b546e010000000853ab65acac536565ffffffff44acf14606dfcb7fcd297cfe103163e3f98e9e2682871bfb60cc0952a7f171110100000001538ee733d70359dcc4010000000004ab636a008508580400000000026300055e230000000000056a00636a52e1984350", "6a", 0, 1651199864, "842e198cfb641f46a037d06831df40a409fa64af50fa4ae563e88ec964790e53"], - ["58e8d02f027ed99fdcffc2df7e96185216f95fdb98388874e61aa7cd6da183ba581b234158010000000963ab5251636a005152ffffffff47579746a4b26895843ee92a90846d79ab474fd7c3099e103179acdb4995a6130100000001ac7e85dce501d3cb110300000000002653fb75037c01440400000000000000000000000082ef75cb536bc53eebac6a5ac8d2a5a02270483727bd6612dfffcf083032cb7f0d10b0f927ae789b9975672cc8b8de06a43f68d9ed8f1027082c9084441f7eb3d6de06f487386d3936ecbdec1c9e6a7a5f42c8de77c80ff563fc493a6134718f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000423035ced872c6533bfd3694648a024f1a02cb09e64fed0cc56b6ed7643924014d7de5d4d94418c3959c08ebc16a91f2f5ff17597e85a55e86ec7d702f2e2be90d2a9e7dd8b893935a695819123f922415d5671ad77a29f425cba7ff1af219aef1469712224bb5a184c4f2c2a4b8d4f0db908762b405209e35dc0b61b992ecc10214a8ecb02598120d14c44986f004a80552ed28e773582c5e1dcd23fca25145e5030f0b026439be670fb3d76f77233df3a24abd08626993b22293de2f47a24ac8990a0cbac0bc3ff248affd7d2222ba504899da26f536541b422aa477f714cca2b3612cd6a3b7decbe5407ad80b1f85d15234c7d347aa497ddb361886e5620160c3200216d3ca2f5565cab1edaa55d64bba9567d7d2905cd41af2b376315e56f355adb6022416bf973612f9b01137c31f014c2e1155b2b86a6c252dbdf6c44e6dadc627c8032e942977d4982e4a8a24a47569538fa4855de316324009e44fbde5c3db03d013021b8906127a97f83198465f3f749cd51551495c3effe044f3688f6460ab1154640223240aae3daa867cb8cfea6d4dc63841e14e3060a49abfa46894d4ddf8d761014eadf7f6c2b899e9f4122e2cf31ca6d889e0e6247612ecde38e2b72d3b3d022db6b1d3ab800d40ad5de08f9f7c1ea1ef0c52b7c474358e5fe2e8b206834a571627da285a707697529137baf999b9e5280735659ab21ce1f9e7f6865c13a4c58a53183a8c69f50edbdf680e9c1a3ecb879a142ce907c686e88d82f83a5a46740071b4c6430fa8dcb636fd704c24952ab05b79506a9626d0172e7ae09ce01817118587265bfebbd32ceadfdd96862f774bec74e3fefcdf22296b135bb8985554c0f77d2122236da6d9f1bd95c55c498a0c1a1e1551f0481abc0f3bef2139645a6b50f952600b850c91c9413ce87bc23dec606c7f7389cb8a99d034f778c7f79b93013346cd7c93375d546a358ce73201e852f78d15460795006cb5587c93dbc45139ed414e040a7732f616fa8200fa864e953f0c6bd918231b4431a3bcb1544d8b917aee6ab7118bf34e4c6d5b6cada9ff622fa6e7508bfbb148d29d025d59a3cd2adf38b15daaf32a8f78e75241ca31a26c099ef60c464d2a04f6e7fb4af72af91c5cb19d5a43b5d84ff64f15478775e53a57655201efb684c97d31f56f8f973bc9a09d06ec5310f0c4a4b58487eef7d75d825d0b62f33929c65bff9f5c7fc682191b7b1085510cfbab0fef85fa374c4b58e8743fee62bd945243a0426a002e52e72bd6309e7b5573f2282ad3112f24bb1a377a4c6b94398f62184f1d10b341c8631122cab23c76a948a927cc953c65183a8daffe6f03189e6e0a1aad0f627c342c45dfada7819f647aac14047ec68fbf178a11d9d4a76a3a3ffe62e4fc78edc25048dca9ef8708c4d4c4235a63c94dd2ef9ac88ec51c8038f31272d2ce3fec3a223a7315191188720e4bf43fff1068401d8c68df31f45b447a645029a400f8630adb4b4d2bbe59f92657ed658e4de7650494e2040ef22e929df571263f9ad3df70a4ba64d0a0c76ebbefa90bf2639494a40e7aa96d0c0d2e9934a23bcd3a8da68eb676f208b67bba762791efebb223c63c01dd72af1cf5f3824e436d8ace97bddfd8cacb2665f38d67da411c61018c6ccf5740c659a93d1d50460c7c29f4af929e405f72461365e28f2109847d1adc3a7a7e9bd9cdf5d92d0b5b41065f8ad4a99c349b2953535563b7ee98b2247b85ee9485f5b28aa20a4eb740003f2630c659fdc2200292d7410d6ac814d0cf7057180b834ec27c3933b8cacde0ce61b17c6d84ce4b78d5bf8cdbd5aee80bd936154d596311e60f4ed546ab34e9abdd0d615705817afbc9271968ebc1cb2a97cf632285795c6140c6fededb1ebbc5fb094de81e09a4823bd670b41388133827818f8afa61abce79b5b1e2338f3d80616b7e16895b162d50ce3c66d0d6413d45043dc06c5409b039eda8272a355ee95ce8dfc73febe60370a469c11f7104e3fb5814a51f31be6d39e3e7665a976a182627e69aa8bea2176eb29b8a41add57eff802ffaa177da349b0d7d82fa312b90a2242cfa068c24c6e0a5ae847db6205c192be8258f0a183306dbd57bc1cf48fe768e8f6af085e040bddb95d1151f3f22c0c91942663980608531f6f5ee77c0f7679b1052c829aaf92d5aae7dd6a51282554dcccf63ee415a7c457a9702efd5f19f4dd1a667addda286dfe0106690a23ec7767545db3a69dac22984ffec1ff76db2ebcf99bac9c54e42608593ca3084f34b53f982bf7233bb12000000000000000000000000008e0bbd06099a4fab16867e79e6264b4a86236f3a9823c1d0bd67836e383d6757078d0966e597e893b818ea3cfe9ae2c003690d92170d942cd3f93fa05fe58124bd815c12887ce81548c2bf0871c39d004269e942575920fb85508d93c076bd6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d15240579c4039f5050bf6885bcf6bda28c6464106d1eb8bd4f95a3a00c662223c1425faef542021179c419db04ae7670af016ba2f1a13412f3bcc33773a7336442bfa96fd3333350173cda6fe259e7e9cc86dc6b4427d912709dacbab0f149320f0d16ef51d8d16759ba5e44d36f97e8e0651f391c5524e4d7cfb8407627ca70326548059d9731d9bac1492bb5ea60d89c414116c4dbcca00e75973889e67694e030de7b56dd945dd534ea78ff63319de6cf3ee429e2c407ed1ad8f094fe163ee690b213b61c9cc192c64e4b890eb5d5a83759fda99120cbeac2e77b5cc4d3deff39910e37063a1f4854846c36a726b4e5aafc6afe413df43e235210bfc2b0210353903130155ecaf7480dd096a39c363ec8be6004d7dd443bb8751a1c4ae85ce8ef72c0226a2680997630763bf4eeb888da7718a433de7e7c18ea634ada35e7355bc2acb02176e983e237bd7600f7bb0564da426eafc99a56899ac03c2daa363a5bdc2296f0213b376171038a441ea1721c8a2baf4c7bce462c67a2c4ad7871c8ff39d976caa0318ffb5d01dd3b6f7b2c742092bd97e85662f6de2357e9a5dbece5ab1fd6ea20380bad06b94508c74f4885eab2955b86964022faee9a354487df5024842d8750d9fe068df12687f938951910c275653624ae755498b778cb17aff7796b62866c2677d02ae508b1ebe27a248039ade0523dceb08f7d3befe0f2a74b3d82487dfc2aafa2dab9388619a4552910347977e76e244989c0c5a74e20787bd2ae454a98d7fb73873110837dd58312a80e99fefab86418bb805325660f2c746dab46ad747bf3e7cacc7ec94d5776a14e27fe1b94e655fc861aa2425b4d1741098a83037272405dca44aa31a621ca80bc025aee3c7411bc2899356dca2e5e010753f97de4644b62f81049e25c849675346bd490b1def1eee5ebdbf5ef41816d643985433ada53c254ed63b99331a5b92375a693c7bfe4a2dfea1ba0161fdfe1e74f8ce699b3ded075fae4607f0426d2b8e77e0440c16ad9a2ebacd96b88a060d5a9bee294cf3537858fa00dc2675e2520a22dab46e42cde8dd67cd1cd59e2c2f2599ce5f7efbfeab4c8a01eac646d394a0fc6dcd32d197d9c5edc9accc809456178a99b0ed0cbd934e4169f702631bbe7d112c4497ae022674e632a8adca1ea6014ecaf10730cfaa7705d66c3b4dba15a45c51eb876df0701f689a01c8c870a717620574e6c23dcad2a918dbfc8964eef4c1ecefcaf13935466d5d46fc1aa4555bb83967ccbefb279327ec911c2c7f0ef42ef0290496cb92ff505058be316475bdd0a404e416028811c5f79715dab0f889f359c1d3acadc896ef7a854843d13487ad2adfc47a08e442ecb70ea603406cb2e9b70518b2283bec3f2de0b402d505b48657d028af184c79175f888ebc6e3fc9bd8b57680e394b8da7e896a66966fa93e0e12079a9f96065a30a319d67290eb6916cf0c0d0dcf9fd04108fd9d9af52496fe40e05b413e19b2d795320abd60fee3acadd4469204f64200d588a2af97adf8d926a6a594b8fc7fc91532504a57152a370e2b21c67545ea0f171f08b48cfcfabe6d8a437e0b3c4b97605550d8f9ac18c659afe3ff9cb452e94bb1ced9b8135c06d554256fbd325bac22b84e4418ee2925f9d28981928d4be8dde43176908b2cfbdaa669783ff0c49eb395220cca22376f76f5cf0590d242b977a3a806ee0a84764d1af667ac20e38970adec7ecab31ca7b6e148010a319f922a95f4c15c8500ef9cef90b0667a01e465af90182c25b27828b59ed39ca6007e69919b084537f68b4b020439ae783c58ed7a460c63923bbbf67703d8e0926377f4a332146bce96aa4118481509d8149ff27fb2ba7f7d792314cd44789192f181eda67c3c86535bfaac27f76793259c2d4b13e2375e0d5b066768fa6d0058a9030aa08eeb69795ea3da14148dd1f58554f953dfd58a40553d6a24d26601ef3d2c0e952fc1a5ce5d4e1c9e2f68d3e6f4fe058a03f1ac3a74ac176a62869456efc2ad7b73c7c2021efc6da0ce91dbd606b9b020b00f64689f03245fa4c358d113095f160d2808e37257828eb4a0810b882fe936f4c4d838bafa03c13cde05f1b14e366a7e7091862fe65abe51dbe4d61a0a17c8bd41d884ac6755fdd7826484aa23852cf800983c6a06f9480f6da40efddb7364e1db78cab53039cbc50883a91b557e97a9f137b60b5f1610868b578e317c1034e67ce03755a79f5c2957eac12954d6bdd41057db147435ed6da5f7935dc807f6f148def7586f9a80af245c16ef6000000000000000000000000007aa9695c49775d6bfbafaa1078287e25e7a81f69db13b37d8d237bd0b5ae7c2cdc0d6c9ccd7d9fc4fd075ee08d85352996fa6e50687254c2498332c9c1f9c0d2e9ff2775edcf8828eedbc9c220ad54255dbb09561d3cd4a00df1d24fd620831d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094b672b7a2826e7782bb82ae11737de3e68ccd9d81d85640f715ab5d8584d1edceef543f7f5d0cb83eec134f3300aba8ef1a7db4354eb98bce8c6d61f449bd448310886ec5dcbd90d9106fb8fe07d60284d5872aa79bdb1c57f59874fc5a4c7924810b6c8450ebab9ffc9adccca5c7f8605386e7132cc67898be6ec43a249a52030aa4cadc4da7d51038e4c30ed661ad397fefa58a609ea2ed90c56cb356be9eb90212010b99f229abecafac18eb3f7d4604b63e3919b10faef141a10cc701ee69110b0ed2d9f8c362ddf26564d4b5451bbc539f4cb50a174d1681be92f7ea7569fda108bddc13060a84821afb604996c70da366035f628c67eaf8f4f3153e81c7204d020d96d0a40e8f8467cbc48909a118408bc869e82c4e53f6ffed76db0b7b127f45030f8971ab2cd3c871e14e74564e8c5ce1a36bf682c8d3fa121f88c1ce50a35a22031da43be0aa0c0d59d7458204497a8d5d07695222fa6b885d2d3c1b1d564ddf7d031808ed87e9df58bf11ea52ec7463dd80e46b1484e0dff58398453ea1b5cb5af0020ef3370d85a7409e6f2bce772a6c160fa4a33fa0855299e067600938e05a15fdce3e590d6e52c3873b6d100be00384fde43f0379aa7f47d8d2ad50126b12aa0f07daecb5e15c6247768e675f567ef5385d1b7fe79522febdb0cffd29e1ad75f61c5010cf6ed918683ad3438db8498d1e819a77e3f5d9865c5a5b1388499558766fd2c3cb7bc444a3397037bd5245ba0de4f72ff9aa5434a9c9d8b5f1a7e225be20d4388f5f5cb3c15c84ea4360bba04822057930b63a44e43a7f6791e1ed6d91d65e00333ff2af060567e79c3beae3e74a9980e6433d5ac8685a7507eafeaf223545e91e2243456abfa44c112a0f38faf12d7ccfca0964b141ed2dd3cd98d484ea7fe64d29648ba56235ec25461e20ab3ffaa6870fb97cc2b48e48f855af222bd53d5ef1494ffa99975e3298add50ba517436fc4c452b11e3e766f686bd24324df54361dd435b7c3a1cfd85467c728141baff0bb12200e7986f1276c37211881c2bf7bac9e30351c01402d782b739f818d800fe47c0e11272ce0c13c6bc77b21e76291342f40e7004407ffbb88c0cd5fbe3357a2ff8c8eb0d34ce50145f7eaf4226ff24b4bb050315a1561afb4fc282c69bc99f2613d91efe016537e4aaa9ee6d44ced0a4db50ef6419f2d608c7877f80e607ff3767455a82fe308d290c5de110375ee3b243ffe6cc9ecd581376c3b27c9c538c7fa8a9bd023c44ffcf9b6aeada50f7af9058f79c21561062b4e9de60f7adcf1b74c37096cf0b1fd0a7d6344a2880ff4742e3a76fd773d08e395cd46dc959f05f018860fff134247eb3012d97e90eb93b300da9d77bd597ad8f35f69b440a7f0c8451cee1e12f29df55bbdb5c24f1ae78a87baed841c222d98e64c51575330d4e6283af19ab433a91a9067657ef9c07d7f168c4afd1c300eefda59c7cdd5defc0ed5836baefe4cbc6ba63f43286fda85e1dec16d0cea555ec43d9a78262619ac62a6bb31240fb5d65bebc11f8952a97cb451466340bfcbe16e44f327dd7f813a5059835f8087568007513fe49f7d0397149fba37f67331fed6ba2e9b3cf19e3f4a31bb1ead3e5982cd12997db23a49a8aa02d06460a99feb547039f5fcab2e75342c3026b64423798f007c34421120c2a223bd164a557b101c18d0351e1c3a912fdbd5a1160c1dec1b6a0b4f3502db6a1ef2a8f8fbe2b74b0c72c1994006efcd96cd0cf68fa789881ebbf7faa251bbb461fdaeb9dbcc3ffbde0a28a6d51b804f5648527a3821d7a85c5bd5ab52f684a5a10ed4eb23231a56b1845cdfa6caa1a2c6c95964570f2207783ff7f72249a0f6dd3c5565d5d825dec8606256b8c08d9746e31b048c101a410b260d8bc8ef4aa288c5894dfbd6187e4c1d58a74652494e33d3f31d58b32023f17d7e480fb006fb4fdf852ad005f2be377b7c04e50266e9822d03e22fed97b1e727cd74944addab2fbd1d59da2fc773810d4fb3a4a69598aa024a3d4389665e20f9623313ebc05224f8fbb5f51eef82dfbed804533ba259b43a98ebe34a4123f7d562d8688aac4f2230b97e26d4d47614929d626b88a31a2da3485e178f7b235db7277098a6011bd686f959717eaf20223f0e8f3386e25b8b88cb530418e84e2aa44bb69494a738bf945d93f398312f1c91944c11da44965cb6110b355506c15cd3f3b520f5bdd716c0babbabb892dad45341cc10dcc8a36bee9ef1e939feabb1fe1aa3a33774bf2a461f77efa8dc8f47ac4ead6b59fe30df7add988f0ec4db2144b88e5a244b035b674becde69a1fe1658c6d9432e73d037e12ec178ed80aba1d8a0ba2c89c99ba27b9272ec7d6fedf76453864f6241bf5e55491469cf6c54cd64f234c6ad871376ed11766c8113301619e9b979a900", "6363ac", 0, 167502891, "455b580fd754ec18bd182b43895ace9eb4bbbe31886bf727da9eef7fbf2c391f"], - ["fa84bcf9033dba0d6d2d441513c45b0d3fca6ea783da7dac27ed64ed0c3fd822fca9bcdd620300000003005351ffffffff9c80345ae2ec420276ec507611933ecaaf670936aaf0b2b0cc1c5ca930f8a28e000000000151da7b050f66dab7317adf034ad5d711e4547d240aee8aa63e13f5a55c6234514556ffed310300000008ab655351abac5151c8b19207042b62b4040000000002acac3459bf020000000003ab52653e510c040000000008ac6a6a51515200521cd4470500000000076a5152006a63513ccac9ec", "6500acac63525353", 0, 1022872894, "3e72a051d1669777e21b5633880af32c0c3e751022c31d3fabadd238c0c2efe8"], - ["0b37f89803d14061065e2f61a881c46b898c490e1a263b5b8cddc7a52f989b7b10b3710eb80200000006ac6a516a526aa7cedcac6b91644632a63a126c105f3be0b2f5d4a96612c0504dd79071d5b3d4d4e9328a03000000026a5106913bc558c602a6c6cb527fee77c3a155c541fe08c08ac00f32f34119bf9a65a942958d01000000076552ab52516a5284eb1e18013d4f3d0100000000016500000000", "006a6a6a", 1, 855527435, "4c1f9e489fcbc71d9094f219f8cfdf043b500501053f6fbd3be7a5883a675144"], - ["b4317b62015545327b317f5503116840e6820dc6901d57b362874337b5673db0fe7457738903000000016366a01fb802903ace03000000000763526a000065008d798b040000000001acb2641b3803ebe44200000000000000000000000000e31341c5db55e321fc0e9ae595e88b233e493217716bdc93f999509dd33caa8251d92e3c2855c87e040eb4d7d47c58d8de92d69c7808ac9f648a01e6b536bfb3418dbbca307896897a5a125337fb7faaf5c96f09cd7105c89b15bc45f1af104000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc3af08b3b5ff3671a26efc8021f65734cb68dda01e1af9ff256317ae2f41abf2706172f9d7fa0f94082ab91938daa87d5f6a212ab9a8bc6630b3d7dcecf52d659e95730e40b0023f69ee942c858ab3e3d508d42d9e30fb97d935eab80d36779ff3570b8413ca26f6a34e28756c412ee4f09298bae2769b8abecee632deef8100304548ce0921161a9b63fdad2a618b8e40ac73819371f77f2db3f9aab0237c1ed0216d73ee756aac36ee4b82e09df908ddc3ce60f464862f712e897ff3a6bc8fe620b25bd87eb83c7f80b7db225441ff69b7dc191cfd1d6434aca2e93dac7a54243bf12a54eab1d6ca695cd347eaed8857b7623033f9480c107f0cb04b0938eda37d30203409b68c9b5a18967fd122f267b4ff922ced9cc638290977102bc6d49953acb022b3ff7bf0222eeddc7b2010e084eef3c0195faa128f598f614795fe6068e3a000226f291f7098c09f6ebb9af1ca09800f94d5db30c88d2adb7a94d8907468ff78c031a0c26b57401987dcf943f961125f343934a9211f3d4bc61aa02ae65a3facc0e032c5aacfe26cd372705777783995f757ac1e14d4a7e168f8d0f187d835ef883bbc09dac19030f469e8654692196bb78410a576cd29b54f1ed416773206b9ff220c77cde0deca05045cc68638c51dc04b680b7e3b9f68228bbc26d11a871a82bb5e8ab6c1946692f000577b0bf3fee74415ff6efae22fb4311ba8b344752fe440aaa4595659f9b918dd30bd0c2330d5f9daee211d66f30a5e4ea67f3f830edfb9b261b00168aff97c4d569da841fd34be20feac6e4626da0c72577a21616803042bfd0d48a6d3aae7259016849855622795778595301027b0ff24431ea37b32973e5ff3823529e0e5f74581b8609f31c2029540f835669879e68185a596bc3d5f826fe4465e9d24dd7918dcf72d23d8579fee2843504a94c8fa99e0af0762b90c8e5cca6c40ac8e2d379f1f70882158e6fbc202c791c64e19efdfeac5a913098056561c6a4bfc4a6967306191d2e19991303016c388bd3e369915206e4a95f8b484fee43bb8ac961ff26b19ebb2c391b66a9547d7a68f2ecea94e554f636d1f8bc4b8ed7a4683119dcf1729b310c247ae0cad269ed12d3e866528459a80274c208c82fb27cfb90914401cfd3e0f8a62ee345cf581e0d11cdbf42eadc5c49cfd785462acbed681b70dc73c6733fdb12ae758d6729a784b95d932fe27494bbdb476a24a0f386e656d038587dc4ae1e491d13cc855815ae096398e3e6ec138da275e31461b8f44792a10c913f955d9e2b811f21a45c3ac85c0f41d67af9c93fb42adb85dd39684b5bb63316ea46e4058e5d2f62cac8c57c67646673304fa36fc590a03e0bda71f0cb858552397f0be5c8d9805fe4e2dc90fca6dc444aa9dbe5a2cfa316c7242dacd0c1d65ceadc76fe6c70760287cc0e7f4cb39cf408ba2f021d19006adfeabe78b5e7bb14c1dabd78c12db32c077666a7649042ce3e43a8aecae9e4fa87617d68b4340ccfe9018baedb3ca31b212e4d71cbe1c0bb8b97bf6f4fa4042fb01e9f20aaba395d06d48dc09e7a629df696a7f4d224c1df17a31ac77c95568b1696270ebf8a074aa144b9000da0003bb123500b24a4e0aadcb7f617a6a94c9c4f649fa70ef52efbd0396be0a4117ff1a69473e260f9711194b4c50450b621ed37f743614f20434c55d4aa3c4ac42c00c0e58b132420b13e2c44a14bc39f407493ddcafbd26dcd50227c98b1080891bb2a831863238529093b8a5edfc3132e858ba12efe4f0a2f140c82a7391a2d36c89e7ebcd53799b970f57f4893fcb613f825aedfb3977cf674386221679aab845e986507dc26715bfc41e6608922674af56fccec89169e055fc38fbdf5e9f9f52d2f1b9932705ae43e6136c702a5a23c880c9c5ae11e06665cf32109110ccdeab85351cc57828a3cbe0d433730dba360979b4b30d72df86d7dae8127a6fffa7ceaee49ba657ca5039a694ba233505af05bf5695f3b438f874e560e11f2486930c9645af61faaf246b13a5ddeca27f1eacd2d9ed54ad8ba38b85169d8db0a75696d7be32b2de494a62da931cb5eda4ef9ac14bac7c4a89f0cfb3a492d45ee453e7c232700a6b315122fbc5a96c4e45127d232cd475100e9b8b1a3a5d9307d63677b63b3ab116e0a07dc0f5067a90332c24e9eb75b818e36811c26085f510a6971de316ac82be7a729f5ccdddd86e09c431796859bf1e2eaf3c899d8e6cb1b3f0710c69470e5f7a190ebdffb29a3d74d7421398ad09395d6715bdcc14dfeb3bb190987000000000000000007623a05000000004f19b5221ae5df56e73f100c40b29f1f1f99ef5ff317a305fed39f1e1b299e36dbe4b979ee8c879b2d3684e33e2e717225e1b0b3a1a9f8db3f15451129913e3e71d6303725ff708e03d3bb0c967c8621a2c68c97003c051aa928748b64ca398500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000887c01884471d78e40c6e9d35b74ac4b349f8fb42fa7f35bbf1b2f1ebc711d29b2714dcfdd907500510581fbd5c9755b5d5fde55907a8a77db0a1f213ed430aa18bd6405587e94b06e78e66c481fae3a9198cb57ce6448d48abe1fbbe5464a6e2ed2085df2f2843c2071c5a4a5ee779e9322bcde31a14442c5e5a2ee1fcd9cb20226bb35706e4380463862961b5bb107085506337839827ffaf7666552f2dc7a320310693d699295f1fd9431f8529f1ca40c22c8f735443ac6c38eefd202bdf0a78a0a28a33a3cfd9ae90dfbc65dbaf359b74ea0ec00e9f18697e602566ef1bf5ad93c18ed55c5bb441cab5221d6957495ff5bf290784bc5ce910dc872b16b5bcc3ed90301984b2a8dd9d57dbce58a2e88ac082da853532e4d46d2f2e41b4a5591c305c40224edf0b7d5fee3a6290954a820d006581c0bd8fef8ffb3cf510035948ac226600201d6375d627e3228d80801174048bc52f04ca3e61522b82251e95ba684fc134b022be9abeceed6fd1dde3dd78014b421ef48f7b1660d376b7d6e02f8f7eeb84b70031d0ed28bf983c0665b17f1953dfa1dbf29885880d5fef6a377b0d19c79500780651cee72c004dc802b0a1dec7335875fc7bc18f6613b7814053cea91a68151f43ef504d9f0a10553f692d15bbdf30350ab9e23469f4f62a982fec3bfe05c9267ad048d1d5b461c5df946cd558c3a5e4ea22a003df018a6e7c459f99517e899ecc0e8c06cb6af4bdb9c5bad7c81e5095b2deeaaccd7fe7394d8c026769123e9df81c5dfef22aabaacb309128f68a7bfaea975aa47b465af43d5b09047cd812243cec675e5369a4bae145ef628096b4fe480548ced43893dcaf2975b6d29c3738334e893a4db704b7eae704edd47892f984db9b8816bfef25739452b360127c66c681623e576a92ba54626e29df897aaf6e566f1c85965889cda7138055108acb81b2d1ec3e0c44326764e86760df1e1b7a06580b54dca26a00d07bd0360d49bf2ae132f3dc851b9f7f3929149c60826ee5cc51459b0d474495e6d6cfbe96788ba1e0c67edad43f4ba78c6975cb031d66546348cddc8729487baec8eaca6efd5688c047643a1637c4f86e925dba37a4d192a252ba07e2d6d4d454a6d85a3bbcf5e5757b7af3024b2ad5f525519426299e0328db26fdd554ca846c7353c0f5e03f21925344ae3d4585e682dd9a439c8891686b7f45ece4ad6c61f867c80222ee50206d776017b41118e60e592cbc6cf2e0ee497d464e044afd19cbc2c5513412a4f2508458265a7100cbd8875fc8b6f00f099969a23281172977c95a7ed6a73f89b98b2ad9a9780b7dea4596d335528ebca2681fdbf351c21d7387479a6a8f8d691dea34c4f9d90f5c7b2c089165b32f00b402b605cdd237c0230c3b49a30c20a04233d34b1fd1adafbd9090f2b060b8cf6277e4f2765040ed5037e8db735b2ae1cd2f4768a56fd55dc3237c72696fc0ee40bd8b8864088619899ab0dbc8a301cde4de93ab6fd081720b06821c2b801b54e0b3863072e85da989abe616e92a2456365a5826942ab4bbf6be64308f4ea755478f0d45926efb4588c33bc4fe439c500cfa640497d472829d0c69f876dabc69aabfb26650413a342fd55e3da6795af34648bc790be46c8e1a89392f9cfde7f27eff8d76d2fd2916d6082b71d8290dfff6975ff893a5ee24cd140dcd8ecfbe3a32fa870de8ad0d609e4d19b17eb57fe963e818251fc86ebbb9b6dc3780c3c8cc84c815cb88f371c5ac4fc1f85ea9e9a5b5e3e0e7d82e78a18de6e7e3dc3d472a324201c9c4fe7d87ae9c287fbbb6f92188d65b2badb13f6e6593b222d4a4a99fcc50f4c92c3b60909e577ed2a62006c5f09fc4fc8a56e1d39c4d0b6ccd6f5112c7a80ac7771bed5076def2210845ffff066f71be94768a1eadbf099c298ce00b07fdefef9092a8fce660f6e908bc5003bcf15e1eb8090c03e209f61e1d95ebb041f509568442099495f6049efd6f220ec102495118f7f52f15444fb8b51532ef3ba6da9c028a2cfe51835c181b586deefaf05bf54875bc36d2378678c48d886728343e618b2c5107ce9290774e7a7e429e960a375e4ec98cd06a8babfbad80bd9d810b5d07112b3f7442eccc9747a7e9b1afbae4f9c81fcf036cbfbe4d4c60d2d87e9175a23f04093f54545139bc0f8dc75c6bf6d72c74aa251ce34d5e8c38f9c960b6a2f0b98b494ca39e42a5b04e72321b841ee854023d92141b277ba51f221e9068f28c9bd40676334c4ac37ddf508ced8f8ed3e1531a068006766f022d65373e300000000000000006f6bbe0100000000f6b7bbad8ca78fac5c661b1f6865db349006ff0afd38cc92d6d1efa872ce5b96ee7a6076055e7c1d13b527ff6b8da1621d70308e3f0c762a3b8364056edd2eb407d0e1247bdea99321efd1a8f8c712eeacc7f0fc60ac2066244652bbfe72016a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064b452c55af14333d0a0944fe97426c2fd88cc62e2b48e2f831b58068acd2aa3641953c02c66aa94e11754153da6785eeb5a67cdc37a0298ae5e3ca47d93f0833e8f6e8a32d78aaf47c56905d79cf48c0791fe9752151c10f22056efe979c84bcd9e8583db5863dff37274c44f4e9d17520e9aca52e3d5cd11b34de593385b480222f142e9b81d270b2e20ed93fee91182c4abf7317d487ef317645c661a9d4c2a03152345edfb654e4e16d36193766d052c00c48960fb79c73757ff874d5f743ada0a185465c002486e55c7ffe8384bb0277e833ebe932ddb4bfe63db2258fd02889a0b802a3ddb3784bd8eb57d5f825dc277be94a3dd8636a22b01b6ae85f8a25ecc021577a71e2c19b95954edd2791cf0bb8182dd2981849ab6575351f022219e1730031e6827a4ab334a1d5963920c653adf2bc7b66b978fc082bef6b88b0ee7172aa1031a1065e86ac235f7c2ed1a5ea1f46bddc6f7935439f663bf9bdae4177cd4548a031732a67d0fe10e69b7b21707800932a4d09ec8addfaa943b2ded3e45489c8ba3030bee3ff3a1968dd310bebc04d6112a7e1617f559fde1463cd8b1b3e5b8519a82ade53efb357110675a9c20f2a51e0748c0eed7ef91b1a1e361c5eb8d73e54dc2345d8c031be8bf1758242f5379f4c63c296575a9fa9bca02e8be91408c8ddc8602f3c6d4a97073cc23b6b560b4511780ea16bbfc26918271377a300a64daaa96bfbcff9edec7b7e9095ec82a58ba3e8191731f59bca1a9ac5ddb34ab4166ef68dd7182ede74be6b0516c3993fc23d325ce87352ad2551e0dbcd5bc9feb95eded6ec9a06c7eaca9564947b8629deed9928aa52b9e628df5fe0e9545fa51e8605b7908ad2751666028d1bded1bead16e94a40fde72aed1d9815da3ea1949a82cfe84932f36d33b0cc38979c75ac494f4a667155ffb220bff76c56302b88101a41559e8e5341d6b4962f92e2853b49d1678010ea2e583c5c4dd1063f17b8eb42a65f9c1ab592ca9983a48aa6b5721c47e03b759efc5c634c3a81de17fcb396c70c074c48ac81c67219a99979d1a97fb688ce0f7fbac42585cd403e146ed8ad6fe76e5dcab4dea0404451c6641ed2e13dd316bb0114c025e3a5595e08d30d128320b2508b1f1d3ef554834bf0455bfc981ba06470b5e7402cd81ff3dbecf96a5b02e40c329a9173e5e2ec28f71b61a28396f66f076412cb789a5c7dbcc98ac9e366e94851bbeb6f55c1d0b20818e8a0925df5625726f538dc2e0a282eb2c64a1acb963d4e2b026298c80a86f6bd71f56e46f43d9268ca0489a42c9f226cf86a637ab6181ca58d534f0c049eba7a10effb95b8f8bfdb09e734a7e0460cf812d9c1d01a27c866aac4723b0ebac057957a7685150c88c7dfcbcb05ebe46561f041833c80035de989efe86eb5dc64dc88718846bf5ed0a288f972b150599d414250a894c1fe20e5bb205f88bb275b6044ba27dd804806f4065d749b6f727e1c7f990d7e69742093af69aeb1058663af7a11d5adc9a16e7f7a32a2e62706d753ffac87f66f958acde75e398b39237bef82e3d6e873c8fe8b388bd556b240ac795bc0436ec83dd3c0241bf63f95e98b7a1060f4500bb5977e6391b0504216a37c37ef78a451f36643da17cef14f04e8dd301a7cc9f4fdcaf547010d278653a236b84ad60041efc63e2ac9d96a4c46223ebc68f96cdc571f844f2a8156011c446c76c06e76dac297d3a35d1e6df625c60b018509495cd6d720bb589e5739c74e6a1248d9e366664a6e3a6c6c74e6efbe1e814f89d597767d383b7b226b38da8bd24b74c24b30e1bbfc5e1a189fcb0fe72b338da81f99a6fd97ebb5fa44c3aa487a803eb092eaa6eeb1749dc8bdaf1eabb1d65de08dbf53f2900b3f8d28ff29b580f416fb5fadd93acc23b2cef5b7946f77f9246fe2b36bcb8c3b2d2ba959617d0e210257c7d2cd8e18f49fed42e985163ad0a8fffe0653ca14b8d119a6c9fc9bb1600c8483c13c27c38713a0c732b0e46e1aea30edd869325bc8bd610b47510aeeaceb277c66d26317e5e41ab8d9227b7f89df73423cded756cdb378f881296c2254dca2d9e84d91069f0e20495150fe98ded4a7088e67086328c3e7917f7dc55461362b789f9a536cc9ca5c66873c06b4e929305da2747d0044f85c4fc8b1a23177c15260e77994099ed33a7fa56ce696c2aab22fc495ececd66950fb96642f7c1997be95ad48b082923129fc9d52f2857c938472a38336a4c6cdd51f009688c03a41015e85b7dd34c484119adebb44e505819bc3c8cd78afc88cc03c9577e8f1fffb7ed4c01f50179d10e4888cdc54c247089211d8b71bfd1b451da33789de74d4ca3b5cf8e4b39c03683a1410c251ec80e5cbaa12cfaf6457c634021b35600923c7f170b344ed1d8024214ad00d3991ca03410cd9504", "63535165", 0, -1659337291, "a50acd061e7748742314f536b9048c568f3dee6acb070aa93f1ede8cc0a9ecb6"], - ["9ebdd9e20475ed0a09b0d55c26f49fdb2cb8f84c8ccf4ec936860c9815a6f953ee704ad7370100000001acffffffff699cd83250db6064f6a1349f45cc2d3d76fec3d72372a5299338085c9b7805ae010000000563acac516affffffff3668e8fe0c43529e0758d5c593d68a9e79217aa167d16bfd5fc14906f6aec5290300000009536a6aab0065635300ffffffff89a44fe143954e9acc737a71cf479550155a18e236d88668bccc67e44fac14e700000000056aac6a536536794c9d0455cf59010000000001521cd2de050000000003536a52ffa357030000000006ac655165510020e082040000000004526a6a6a494b2528", "", 0, -1346940735, "0adf5b0dbde906ad89ca42f32f5ca630876e3af5164f4601f984e73f4b6a39e2"], - ["f47e9cb0040d7035888e38d7ce54155245b68ef3f4ae4b421101e472087bc44a75431b3e54010000000551006365acffffffff2806634f410c53e42f15d457d19429bcdf676b10680cda26d3d4d8d91f54e9cc0100000001acffffffff42d2a7c5db77d4cb686b322b83727f46a36b3eb4f3dc1b5950a7fd6e581ffb340200000009ab52636aac63ab6565ffffffff4af7bfeb86f5861d7c85b3e81ed70877ae13736f26b2af22be3e7749c48f616d00000000086365ab6a00656552a1ed2e920155a6d304000000000965536a6565ab63ab6abaa73e39", "00635265510000", 3, 1002574041, "de3f0130978084ea2dca7089ed915adabe1cbe78ab573e845e0ffe1c6680942c"], - ["bc5c8d26034c25286c11cafe3a4df1e5bbfeedff181abef88ed4fb20c78bc3da4a799191e0010000000465ab6500ffffffff1d007a3c0a11d914a81bd359d118a51fa6326b07cf642e1c3fb16418adeb01530300000008ac5253636565636ad60c021ff26dca92c26e9e93cb230fdca2602392430c4f9b2f49d04ccc28c3251679ed330000000007526a63ac6352acffffffff049b963e0200000000066a6352acac00a66fe801000000000652006563acab32d71b010000000000aa7f260500000000096a6a65535263535352c71f468b030000000000000000854eb20400000000d9e98c76e928f374e9156a43ad12de000a6b473443914a8b7235d2f140302c72249074165e70ad6726c16022281f6dce179ff6629008202de39ffc937e7f9d1f36c8a781719e500c4a9716bbe153f96c991519d6af505a8bdc5ec61bd2955b3b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b75e05f73362234db01432c9825f2cff0000aa56701082ebe544ee2c34f8bee50ae27d8247248e65326e66594e9d3959871de523fad2dbe5dfb39df66c90b1975f0290f04905c1faf6f7039646b0b617851bd17b81b044fc8285a70e92f1bdd8015625c10b420308a8c89a59389db8a9c1c6f03ff7e100c57ae9a6c11ae484f022179adc8367bbd65bafef76d3d5435ceee581386b8dbd0175a92b963a360ca67020bbc841940c6ee8f23420fc301dc6e643c7fb40c3feee68408469ba6213c425a0b2074b5e9e9de8dad1b070e8c0c17ed18a04102e93f84b58b1db42bbbc0d710ae21497cc395868c7a22939850a1b678947f17b4a7ff3a5ad434444b68f22be42d0303c979358ed2a7af2ffde334710c6b0ab074e8d96c56461531f8305851742d080311580c2f350c24d33c408c63dcb3eaa544f88bb3d38b9d08dc879112c31583a90306a2f94497e12608f81252ea3afefe9a4ce7498e5cec32119ba9008799c579d5022173ea40dac1c84686ffe35ae6124da7e8cfddfda141c8cb8b8f65d7dcea43ca032e06556819e873d1bc6da68c6b4bdb877de237d2afd2ed02756f3cd9ed1efb30715abf158da1d84863f610561e8b5ceffd8fbaaabb71286f512a8de49affb897ad4f6743b9bc41adc1efb9c15e57a3d5dde0a77b79f15ac53290f5111f9ff80695f3345ba05f4fed7982800b30c1bebfc8556ff5613bb38e7364e348a1d2c980c5ff1c7732d3c078facbf9292801177fa161892235fe9cf8cf987610220af33c09c84eea75ed8e972524ca82dc736fd78809a71938758963047b7c56a9834fff62ff2f6dcc0c12214cfe34c5c749a0ce98ab7a94a092e106b43615151090db5a2011c4167a688d870240e47e9a63609b28ce4f923c23d6185b7958dbe699b3ab8bf89c1ccc137115cdafefd5501788c3dc1ac7f9d7f03f8fbc189beefbb60e23daa70a7670659299a188e09e3be565d7f78c2241b26bcb2cd8fc6b26f53a2713b240655e36aed5d808bf48fe1023642e0c835302f80d889955ed56446ebf6939a9294b762f3330671af959fa62ee546d5e7faa1a4d0a3a7bba37065ca44ae781d7d5f377e2d10e14d92236fb925428145f6bbfc166e43be3f2c2ab776a7f01ae0e5dfcd4c350248c7548d728a5ac90f0ab49813883ac4fa3f4540831628af19a69af46e3a1b722c7e2be1830967cde78ca8f19402fe602cb4b1dde1d0cc0c7b17d2547a7416362cbb186b7c82e3d23244f83f896fbeacd531cb0eaed3001a0752c6ca1b9ae10de32ae2c2135033b0418cc11c0289e795f2f3913e61b04d421b47da5c2bd4eaa0453a04449bf4173498820e95ab3482cea94a5601dd124954cdc577707799bab1949f7a12b04a86fcfa8f36b507f501950f12a1bd49aeebf8065e0c39099d5f1366335d743e21e634b8ba82a60607dc68e5344bda18d79bd2941b0a5173401edfc7130ffe6e5f337a5570a56b9097d50ab9cf6dc2aa1d49d459a054c265c808649e25e5ab2304d0b3d17cc490ca13f7940087fc415277024adea323576331051eba4912b17b3b055746ffee204f6e8623d7afc449e1196c33b02fd382de2beb59d5824742c33b765d1a4ae114e19574c36e498b6c3627713315edd9da0f18f104681b113af11824a9c135f40bc838f00b395d9ddf8fc7cbfcd751aa773c8301b6b4246487cad524d2154ed9d2f1f0aa0c1c3cd4c2252cabc755206cba067119179f6d7923843f065628fb23aa435436e83136b4eccff06039583fdb5622c0d620c8d685b8a5c8e99728541984388bbb202052a8d8ed054447c4cfe3029f3fdd66a03a4d9222b1c8aa7d164dfb2fedd06cb951a104f28d559e779093d14be557e9aec0db333256ed93e9502e694caf9c7e99f3b7327d7252111092698ca45ecb9d202229f342bad13fa6ccc0ba66c75855ec4964427149f2742236c7dd2438167f61abdb0aaf01dc27d291dc44d79d99ee1856830134c325da5b049fd51e8140de0eaf4771ce58b66983cf6eda62361bc34fcfb16d72cf48622b81071c3976261285b0fc9906017e34ead89ebab848afeeafc3a4ced874e2ecbff436f2e753b627617cdb263e02c536d08a598e404038addfaf38fb05c92712a259ecb3c270bfe7d1bf8f25d04faf5408b1813a957ff1dcff4c899f4b0e7c3773844f9656525e59f0bf9254e3c2e494f41ba870d3be5142f8b03102e07fe6855acd5af11841c6e5a3a50241af48bb183e1c15528d98aa82594572fb984689887e88360c34a56a177499a1a111f3ebc29fb993d0000000000000000bdaab50400000000ee71db8515537c9c57d82d6b0bddd140a8f22f11a55cc6898e32a65177ff9a02529970daae19db1dd16224dcb6da6c4413f701c9d0207a6b6c62ded800eb285208a413174ee90692292b2d5f0380863fe79f8fc9b10ebbea845835c4be0b3cce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008742baa6972172748d18ecb9dffb0969643d2807bb5123cee4b91edbdda40f45fc5237f816a68a0ec927b234c82c8ee5fcdf95dc4468c2bb115ed247697dfbb0e0c8ba5ecccd23d0086cfa71d18c895e8d6cab692e07bf89f621926eecfbf960acfe70a773efc9cf608865a4296565a8820a9f2a7c550d4fa9ba3510bd4b3e3d031cd506fc96b615f6446c655e9eb0c07808310783c3013bfef88ff3da5a3896c5030ea1ec70d1d420b8e973970720a0f8035fc690e1df27841748df02e70676b03b0b0b2c73dea58b597ac1851c55c546bf464f4cbe2b604145d548022863c5accbe60002817074eb514e26de6f5040ac810d154e031f52fa6a9fb5cb743b1c8fc8ae022eeff8c2eac9548420b8c18e6242d74d16f42cbbebc281fecdc102f533123c94020ddf6ea5890e0f0c7e3205e6ee175853d15d72b6fc3b0ebe5d3e95c67a4d0b53021b41deb2b7bb8c173161849ee43db23b2b8411782be28ed2bd0ec8984bfb19b5032ad6ce55dc97a2a3f4ec3cd36485af2f7592cd5c6b5735688facae6955711c950306f3b4636162f36173121cff2fbd51ad3677be4c870d42a1bf6c503894cafba2fb083259b0f4a50793143d2e3e6f868d0c5c7dba05007fcdab1fac0b9443ef96eeb0d86ef67b26ac59a5b984a4ec67f4cac3bbe862c70065f0953f003d0c672487529bd24ee8b4765ffa017221fed7896770224a7e5a73d66525403e905174c4c7200a0ddd2110140daec94c42e55558b5c1c3fcf7ca20e46605faa1bf4ffc77ed576855027ad817befa9101d2c29b7825ac46d1eca7a454945e729782a69b3d945b4b89cb3eff2a1ca1796ec6fcf13b107c42019f1e1455e60c9da83702786addb59973e840ee3b6775d5ad2481ff11b7fee5288b96c87f525d42ddbe36d90f0f122a1438a25d9ddb7637cff3d07ab1863ca5096ab92c9d9edb56ae5cb13c7ccc71c2ef859d5612564464385249d7be93c4d293cfc8c0e1ebf828409d2031c60ded3f735eb92b60038b1496810dfcc81df6ab56d578630e03df843709585de231d2206ed6236682a4ea482a0315fca8150885012a7e3db0a183edcffdb07297f70603dca08320409adf6042cbdee502e4dc0b5b602f076b87f16bcd5d91140850c3b8cb5706a8558cd742bd782a8ab453be8def490f6988f015f831c7c4169ede585a290b6edea38c1460d026e86206344f4bb953937534e07fac75dadc1652d2126b6bf99c0d3013c76771bf89fb64aa3b355d7bb38fb9dc65c4091be9cc1847d2c63c871ca0ded34b8bb5c9d2c8670cfdb8363e434ac31a2f2cc7f1edf5fdfc42b153d560fa246d96fa7287967ead6435a02a5128bd8511aa848238b71f2556a19ab2823dd5ceb9c89deb6b0897bdeb1f78580ec479f0be7e1e17d1411400baf9c21536cabe2fab2ea4c50e5351ed127a4afc99c0f037a2a3a88de2a511f3b48de9db3044e2cde2883c442e597f285a43c5baa14b18166403b11ca12178459406599b44c6e1cecdfd3a5d7864295ded100cd77cf695e9654e242e11ee721db8dfd581d599c3d2face220ea18fc935081afb3a5f8d97c327e905e5eae6172ae1e199b0acc880a579b904c5d738e82571b32a7412f1f21e5bf6e4f5e4d5b8fb9529a16493a37925f4e5911348c0b6f4f2b22ceed325408d881923d8933a309900b6ebad672d156b0e5f2af5247ce741b905e27a11ccbcd4e4e335796bd81cc2b089a928695f1c71159dacfcbf7b36889176dd7b697aa9370a932ab96f07c4a8f0f0f4fd69fee52ea5b9204d2224c88d83501d92e3f7dea4fb07270d8cad5864bc0470912825ed8ece071e246780b9ed8a91a4b102b88a04215640ea3ee6ae6d6791a4c5e42b9878ef5cc39e5b05a71c5613408e135950950e269266cd0c767391f7951074a1bcdb28d3c314bd2799c4d4d8456f2c1b8cbdc5eb2bf287341f0103a096be4035060b36615b8c17c08e464da07d4334d0c63f767e8517fa1fb3ae830b143e398232f55935ea77b8488f94a7829205ae8a4472ef0e6668cadf0045a4b101bbff17358d446700b4c9cb69685f0ffb46f6876c2618e9dd120d234281863c13bbe0d3fcbfc6859b84241e761a72d6acc35f8db995a220193f0ea73aedda95387aa07e921d0d76c76f69497976f35598ec5af700f70047c3a412fa5fe765e958fd30a360bb56c61ff6c7063f539968211b6c470a2a11ca1fce3dc3ac379a565ace15296ec0d534c123f79a1b88eaa02ee34e17fed967cd8e3df3b79aa54143a52be0f37c8ea27c11f31e44bb04e7d9000000000000000070a96b02000000001789e00ac17c724881cb0935ac80fdd60da5bf6577ee4d428f54723480b84725db6fc4cd0449d741a1d6eb1dcfa24272426bf6d2c477baa08fcf7bdfcd7035ea1750730470621c2275dc8ef837d824a8a4459c4b98b36acc4eae8a99aa4bd40800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6dd41907a9519b977ecb0d944514e1df85e7ad1354d2bffdf9589fd077047c6d63c86acc5f21fcf0557a6fd52e821a22f582477d5897724131e9c98ebefe8e1fe048c6afa2c59f874a3c4ea5684c4f2a1eb87a13225c87b8d309c9931a2ea5d8063b037952ebc2c2a3e476c4f84248d8c1f3eb14b7a6d21385846afadde0b77021c66a914e6006c441a2ad4c9d2100bb93ace301e8448fb1091b832eee94f92e30229b4d7a6b71a9b3e62487d950303df088d131dacf57e82433142131e46fefc580b124060297b1a8e4dedde7bfe55257624db945835d64453755f488b6f894e3b0612b34ea0fd9de3b452f048755ccabff9f8b55b597273f50e8045b28069651fdb03172e067863134f5ad043de7246609f230e29ee756ef028f5db1b6d8600bb465c03198f63847ad26e8849cf16640e95e54a440636eda5dea78a11df60e597cfd4490208931de7172bba75e8bfc5051bff949b3a98eb8fb7be006023ac1bc231cdab6e021c366cee84b53a6c2768e9e6ec4665ed671a19c822fffccb217d01a0ebc7829703002ad327baa3d5d686b1cb68543808bc4d6c4d6bd2d3822b1eccfe4419f6bfeeb89f4d3643370140e4d045442488be7c624ce429d227fbe0b5ca1c93ce0b7a5f55699ea5442eeff95ddd03347488499d4fb4c184ff6e862e608a11278bb37e70b3be6cf5e08d6a8f3ef16b3e40812e7c6d23633c878d85a38ed94170fe746b57cf1772a77bdb886e552134028834f315482518666dd64046053301071fc6d3123a868bf3c1b391feae951b7a94410b4d7aa3a5d34997cd920dc29e4c77bcfaea13bb77573383d9863834f26f9a46754b44c4f5b61a2206d59810369ec449597921446b7c9396ee34be7a224073b4b3f9159ad8b2bbf239c4ce70832bb79bf16c6db6dad39379093f776207f6d9277a4d90917512a04213efcb266c39b6894843e297372091a8dec939b99cb1bddf4c156190d8469191db53c2bc3fbd5380a033539f07304d42a82c8d45fe9fb9cabba3a6d769d71d669bea420d77d5c7100f130b1cff07e9c39285e8b30af0f12f8f7d6e2aae10ade8f5f038d1a9393d461ef49c43de327a48375f6037f5ea74d2a9f123cc41ca805998e84afa4ffed452b0ecbeb4fb727add7e725ad2387a726eb19509f5770a1e24d68b0d6b3f8a0b9a7e9f6e7e7b13a3a44d012d77e091abf8d0c162fa2a6fcf7474ec4a4f3a0a8d30e83ff23a586369f6432067987c000a685d777a5bde335c5277280c88da582696a6fd33f984e938ffd0e6bf63474df96a94646844ec0e6a33a088735f3a0597a1f7a69f28445fe33a75d8de628387478e9407c285601d7c6e1ab618f9a960b382e8a4ee3a138ba4196a78e3e36cf3fa9bf795b0ee8fc85dea966a32bd7dafc0df2e9f3385f3c001dd3224e41bc3882fad0a696b8929f800e78a005011d05d01a8f4586fe9d597b61047c14e5a36137da3148110b942718debbea1985e3a6607d00dcb202d003591f7c1e7452742c09af9f4af835e25e584cf5e80008a7f84737a02e281f1eb1de08b7c365af265d6bbe002bada8ea225961eea1df5c46c1844057cdbab73912c8ea8651c37ac7cb4bd47b5ead6b060bf191453ff96cfea538698faef8679c22d30500d964618d43eb5b673c99323dc93b601d3e0c0a643e8b965d918441fab6900f1e52c0b8b8a07a15abf6c35a7c42c5f7724cd204b10782e7e72d31e287bd3c13efc7a2cb279de579c134fdc88f5983b1218632ce4f69cadc3198576cc0205d1cc235e0ec222ff81cc6a454ece169c3fc2da47b00528ee735390efe949f112f8103b90bc8c33ece8f113b3eeb82b97b416441dd85577c68ce7fea69f886fbb326890da0cda686d27ee9098703776edcfb22793e180947c24a574c651071f9da09f341f86cac1548bde5fd4f84978917f2a64aef8ea685abda80a979ac2789cec81f4162a6ca86dd92ef954bcd057e940f173e05c9b4b78094d1c7ec77e72d14282895013cd5aff63f4919bc9960cbdea95342f265b1d26ffec9be87dcbc1935cc75925593c0b3ca8159cdef1ba21933d6e0bb5449ea68ccebf0114fc88f8b61a10c4f92f09541a62531a8fb2f977045fa10e24a190aedfd8584da727dd7111b3a8573811bd886f71076376e375d9234eb45f901fa20e1bf6e687c231983d7ecdde9a83b93a5f89c4db24dd6f3e1956b4050b2b39595055c0e8f5e313cf0ff8b7b98d14b031a7fcff8010a2be7b8220fca108c09646219cb9d1e22233f67c7c6704cc6854030c5e17d4686fcf5541593501a51ebb3f84fbfdbe085189115b23908eb1090ec6e2fe098618ca6e989ceea83ddab020ee68aea59901b9a9295182ef29d6b085b02f48ff3e8938864c83912680e54793f8480bc3f6b8696d99f5a4b5cee071f10cae06bcfd1b2d4c0e", "00ac5251", 2, -1325687916, "d4e400985a1f96e4d085d69188ae7ba4ef94270eb88e05c0d7b627dad95f152a"], - ["8364924002c191d9b6c340d9b499d244c51c8d7df3991056d82f2d3e8fb6eb3d0ef894bdf9000000000665ac65ab0063274b06532a7988b4cac6f3d947ad25bb364e5eb669e9553f6c0075c41b47a6f92ca4704b0100000008ab5265516a536552ffffffff012e44ea040000000004515353ac00000000020000000000000000f4665e01000000005752eba3f2655435ba29e8ec0a0df735bd219ef11090becd0a05546d2ee40f3052625de2cb4c3e7a0312a56828f4377b90575207bf19c4a51ca9929978e301b950004013df107d38d3e4a968649f834cdaa47e99835af81d34d667030e43c8110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044eff4c8b97816576e02a0acde96d02dc58507fd7a5afb846f1280e680fe76d146fef0415050901ad17561065c121f4ba63701062b28614f3653aeeafb2e712dd7c7260a49e2b5aea0e6fc0de0f4c0f953948af5ff874b21c835f0e8c91fda7926ca20a6276bba49fcfe9e1124f98335481b14096c6ca5af277616c6dcc6c50a03034b738ba95bb74dbd5bcc8a087ae4267eb192605963dbce80a2cb7636d9887f0209cc16e6292419a209f41aa27e470e322fc23f2e75d89f70177c6dde43fe90f70a29a9eb997ee02396003e6471f28ebf3e7f551e33baaf27d368aac907468827a916b716304dd8e488978ac5a821ba0cb57599065574ddebfd94326c80f5c70863031a3e3f7a51684a6acd4e346ac2385532f67640a32e1324991e33456bd02ca79102054f4eb3e5b67d6c26c3f68f85188dff77ba7f261cc5966a401484444713488d031427c9ccf20cf7aed8abd58a24aa0eb9b2085aefa480a214ec657929417f046d030b03293a5bedcb43e3f8de71bd8231f55a58792a3e420e1f488f5e68611a5b6d02189d8a0c4aade43263a89710ca7252faf718c29f0e60750e02c91ea0c7c3800f0fc3b66f486c74d88de1a1ce973ee325f91bb9daf4da05f0c93c8933c07116c0c338eaff94e188d6ebb454576db0fdbf31d2655bf9f6e5575e74dc50f65673c07e43b8c695f32357de38ba642a123c65474d9158be65d6645e19b67028d96296eea5a3f8041e4627cbdd4caf022285a3a3eca289ac8a311b120e6a6fcb8e17658ac2610341e94ce28705fcc32606fbfb5bbce7b6c5d4a3ec84b58899a9d32a83fb1a1c8f55da393e39142d5c2c4fbab8a062f996bad6f029ea6bcafed5a4f72a2253f507987e5f3547ccf91a7dec0bc5f0c72aaeeffa374164177245bb853d71848e372b4ad0a0dba1b808cf014eb87ff1e648e6622fb79249dc42732ea92a083757841772e7e966782d9bf7e72593c8610082354fed14fdc9e9ba2d74b05532729650be0ffbe8904326f8986d823571a541730c96778fc163d3e376390ebf3882613fc49b7214735ac4be521a7c8d985e4b154ea13c758421b611306438dbbb5dbd39acf449aeabc989396fd9b2314384b60bfac65fdee415790851a8117be1bd69690ef24a210b2d40bc54ff45800f44a97a4603365e00903355d0fb5fce83cde57e8573e2665550516663aaf4c93f54a0924df35398e88f8fcaaba0f1d24562666e76e53daec6156555a4adeb915383ec3f2a214c586a8fa318c3f6f116aa6de8843b35302a5fc3db45c97a6e08088f56661a9d6f924c1400b8310da9e1bd5bbd131acf0f36f329470323961898b939b16cef8127dd4177eca42414150e220dae434b1e492960cf5388b3c57969dd743f7380ac7c5d6c15ac5299015aeca72f6a096090e5a6b07e492990d0b12246f8fee9ef8989e3a746fbc7a4314ff7d80df1f2cb988d307f15518c38dd1ce44d0dca9e6068be725c22db0d4430bcf34aa1f859f1c1f5163d335114f7f85afc3ca7da596b6b3d37d7e32a69696651c91b7db46ee1a02278a0231294b5e276b9c52ef85ca675fd063e11e2046811df7a1218da87499d02fedcbd1ae6303705345db19e5de25c8d6b841e6c6a9a8962527613bc626adc81fe203239ffc75ad066cf132c07a86f1b43ec7d846e039ef142680554e795be3e8ca14322130010114cd346e09d0ed57ae4bb3db9c6fb979668bb7295a08220859f44c49cde45aa6fe0131ab3cf6284e0ba905d6f0291b400f874240c728b57957e6f5230fc9e3e0f0e0d58a44b4701205d0d42f1de846bf3ced4b89fcf5b2120caf1a12ef079052f2a59a4a964a140d7af5fc7890608e196c946d6917563167b5bdbc5fd339f74529259e8775ba0025289fd3acebe3d85e00b941abafde025172c44d373d16c2d8205727faef0e774e9c686edf09081c1878443cb115e5117b96ba4147f7814c5174f43ea72d29c32330950091ba266a64bf48d3bb6a020110c24df616b451a3b5ff580b2c81c58b827dd479cb871308103d0b1b1b38449c56f51cccb5df135b34506606d6b135a461a2fa2d1db34534390d66d296bbd3336208e09d79217922bb7073a05454bbc4e0e06b8c92a58a549b641a3c1bf1db611ecce9f2f220ae79d4089a18b91de107288ca04a5e33c9f11a66212908ef9c2f11d2e4a650f2f7ed73fcd2d66f0b4bdd86b1a927c8a74d569fa4bec9363a3c7c8f13722f74eb750230614127d3c23d125eccf341282f0bb30f451cd761d7dc489e04667daeb7438b56f775484f12866f303000000000000000000000000d82d5c3ec7803c510a36ce55d9d907cfbd81faf9189ddd707d7c52282f169c30711b6f72101108e978a102d354880a367e213af8b4fe136b0ec99ce28aa1a550057340af5b2a29a09775a2970822323347d1b7337c46b6e55d795e347e4e41e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c30f32e1e270cf4047d9bb9905a2e84515d07d739cce97f85b6b65ee9ae31f148ce6e1c4c58f25cb21d98290ddcea3e393c94fbf5cc33105cb8a99e50b2e74f6e1f39d0c3300d0a4ed1ff82e616e249208bc33f15411e1aab030af3b138cc23df790aed23bc80d882f61a04f5f4b25c8ddc4a4027e8d0f1be71395aab0efc4d021808f76a74e2b19f216712b9b6c9c946bb14b379604317dae42261128ac54d0b021fee390bc2e3286c70e2e5b09193ea3821f5e50e6665f4739dff44c965e480810a034f161b236613e4bf6916f8dcf1661f2cb1fee2c5535db15b6d6ece2e54f10b22211a0ff4df31b578344265a2229defba5ef90737d0b69cb1d355c13451f366032735be17d3da6f3b9ac6c0b8b4f7e3f8175aff143bcef1560a5b20ede31a6c15022c7e17ed133ae9d66b62ab1f2edd6f2178870ad4c55f9d4ab90ac22d5169ecbd031bcdf26f3f7c49f0b560795495870b333d0e9777f5c5f110df5a718c5816c485032a26389b7b8f51931998e43222adaac3027f90c06825ee055ba393716dfe273803053a26c418a442dfe8f0fabe558c9bf8b7dbd132db39813f65398ba9dc34f940a87ed688cfee15762cc15c30936e35f239a943d04820e2fdb17645b013232faafc1968be47a5d071a61ad4db05978f2b4a8061e18774c66cf90d3dd142a4b1b9d5c0007fc9146de1227cbbb0ead8a1fc0fa13872886fe87cf250a395f262586cdb4d4e69c832dd83af991dc0bb3c97c7c660909811d65327f4c49a802e6351cae058f14871bae3971f814bd3461b2927130c41338a9c13eb1dc32f91697b89dc73fbda258a692e5c3097072347ce4356da28b93a1a8ab35971763646f91ed94a5f0df3868bbc314eaf731d577b20323c6eb1f3be009e0c4988149246c124fb35e06938e32341d9809dfed033a9063e9ca54b630359f7db412e1c81cfeb4c1dc585e51fc9ed14e6f385e948db70f796f6798ad6aed17e330587c3c69e1d1c7b70d3505a2446ea42634a69bbc7623ffe6a83bdb3d2d6fa66a3abe3eca4fee9845dd04611a2e44af229e8b8e9f704941ac63f14b26d499aa478dbc17ea676c1138f911456f635894242b3c5156f901612b9ecb78b2fa279ac2f750a29e74a993ba0d02e35cfbcd02292d1fffe6ce335b4c49c31e1d7773f67e62ceb2b120896a1c102b4e5d23fd414aa33ba357d05b9c27b4d4a634b051317f6f6d6515711ba67636a7efea5b0f744e96e5c778eb45ca0537b7fd385cfbb64dd0f77ddf1b1045b1d0c523cdbe375705e957ce54ee89c8e0ab0d81208ccc515246951e72ff9492dd4cfa4aece981391ab6dee37676db059f7c87ea49da9f38be9772ce3ed026449c520579232822e170b8e98dbd71fc286f9d34e51c8a2e6106064ccf2a5863ee9f13aa1a2e1a6f392c798073f7538146b4b6ed18f5b61054fdc6cf928ea744a8c47c464290c880fed4bc73ca37a9075fdeb66e512377947cbefec53eebb7772e06bc502112f4528e52f52e7695e22a2eb26b0390f5ccbc5effcb9a33c51fbfa3b23a5a4be4565908688203138f9a6c6612372d4bd015b5aa8e622d2d780f1f70ab81fc89404582a634869d9684a38a50934df952c3aa8fb592a12266bf5fea504c28c728440f8fd587e8984d872f4fad4cd674263e2e0bfd42f6642ac69ee7740fc50a6a80c8fd398e4c5054261b91ec001edcc8d2c41dfb0152cd17ec2971ca6faff0004d29fb6ef2dd4635b8612111572d7016c90d9ad30f23b0ba6b53bde4d770a7947b5f8c1a8204af7a08f2a03101ce96bc4f87415b672ee6608528a9a67d963ca2f287fb52e6938b61fa30681017aff69519d5a9bbf3388f963a1bb68b66165ea6291f25d6f5aae9e8edbb58d3c9b9f6fdc5b2b3b43b8c44fae519b8ba6fc246780ad3295af5867a1a472bddb88279b4ee7d664d00bbf367e849df3f68b6811592e0a686cb511dea34a9d140fc2cd048219c60cdef64d9d6003a6866069388fa657087282e962cdbd44fe3d1e4df6484b34cc6a8fe27e895f371388b3a617c4f1fffbe5586bc46ccfc2ca38f81b23c62a536cb6e36300871d78fc78b1ecdf66ce2a195ec39f45fd904d5a5780f36fffeb2a7e65cbd50ff9fa261edb9ceafaf55fd035ab6e248f3b408ac8abce851524d5a6ae59f46109b46047ffe15be60165763aaad5cfb435a45331a09fc09ae873f53732fb1a46e53952bbf77d839f9e4d41e88587eef887759ff903815dfdf8e7120d32ffcbad66cb1446a97bcfc63c1a7785cbadf543cd83101d0dd885021a14d1fcb2a36bad0515e166e8cedfaa4624b67aaa133f1676db9e85dc674a59878913b8b9b9363f6dc3c14afdaef801b15c8ebc3c8cda47dffc2b85a1b05cb2bbb15d02caebd9b100bb8e12b2d8480d5d4cf5f90ce14015194073055e86d94a678b09", "65ac636a006553", 1, 111584454, "ae9a1f4c33e051d22ee01be50a0fb5052d7b6f37b9210faa29eff238a0d6db3e"], - ["b6624c1601ffa40b37c26b187a5e286188219041d35d9396f6f659980f7b601f7786f4aba2020000000552abacac519b3d01290104a07e0100000000085363525252ac52530a856f5c020000000000000000be9b2a0100000000588796a289150046530d442dc20b0fbcf38328d59a54cc33274815fe0e0abdf6fb25991d054f6076f85b973f8dd0db187b7bccc298e35cd7cf1e26e3bba3273cd4b6872e89943a1c17e9666efc3f5dca740a31cd9784d731f134fb87973309030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088aac9e3adffe00f83d962f368518664309abcd6eae62eab46f1943008820de9202660da039398fabbffc693c866ff56b1e4dfff741f8644f0df435564a3ec0972d36d6e9cc1fd3ee8c6445ac713fe1ce95f6c69b4277a4e60caf499fb39077cd5d93850be1b258daba6c1d44f13638247f5e7e189c8b287fc4d322168d96414022db15787d1ee437d0b97dd936624a1505522e79ee55b19558c1985132b4e8e3e0209e524010bbb926f9ebb179bf2ec4527b04d95d3a156bd0d18e88daa1b7976220a229951ee4ca880777b81320e65f270b108b0735e207b6bc0cca8ee435bd104ec2ef7c15acdd7f54b6cc3d4b0de941aa17f9c7bb03419f844a0ab64d7cf2b2d2f02115c4ae210216b041f21680aa978df5ad59b42fe1a66d2c09a1f16fb09e7bf690308a4a34c9ce18c98278e37fff10d81e3a5df30b963d2aa35e6c2c7b8e2ef9af803046292fa7ea38dfabf0dda3b7d570642efb06e1c0ac07b89e875a375a14e15160327eb0da766f05661ead0d02d38204d4b5de3b8db122ed14a9aa3f6f651f73da2020080d7196a585bce20e8b2bd4c898c0083f5cfd9eb09d2a39d1a87f88beb49444839f5f9dc9944d90ece91940f9a01bcf906671bf9d365fdb141d42c13b0d1cf0cd35a7cb8183c876c3ff9afe3d17e6e22d408e640a544480c40c31cdfcf065d9ece11f27f6ed9977e09c5ecbfeb121295f9262ce25fc733bf80271452451c455b718e523a362271aa9da451292fcbc8d4238b1c4b7a3e00c0b0c0c4379f9776eae04b2f78347c38b4ab4a7e6a1bd40d41c6cff3bdf4bdc74899dcfa7d10d017479e7d60c5feb0e0b6b4cf2f54973e2cc9a1d6ce8a066f8140c701efb82f2fe9079ff8930e3c424a69f4bd2705ccc09cf27090a978e0e319d5c8b91f2c68f1dff268fdd37d6a94ea8f40595d363a08c0a3a627905b0cf0e8b61134685e48fa966edda8ed7f54ff0b2bbaca160eb69a13d011c77624b56f252c9518326e7cc8befaf1b539d8617cdd43be2e1ad59169fc9f64b2675c6d5701cb777fbd9a4b090012d044acbbc0337092e6f780fbe28240648a42ef000f8d497f4fe1a8ef2f14e05f162d3f7081480338afab0d387a3b7ae7beffc7c817ddd024404f248a53c2364bd2c46b7115f117266dc488f903c0f04d8323106e6d5e9b6c372a2548fca8b03257d0191fc5450f0e9271ff4ff079a502b83f590fa8000ef37d20266fadd4e541489c695cebfb79a0d9bc9818119851daf8b6a9a02e6f88fbe9480a25d4c90245dda897ece4fde86e52e8670b64e06d00d8753d414ef015f39cbd425ae8b99786348cf77dcb2a566f9b1e7e2f6c623a42642afcc151869460dffd646130a0cad96a16ffe93d5ee7c4c0c4b3192c129600048f95fd0973ce777b8cf06dfb69e515aa52ee5b7daf8c7d4f98ed071d05f4537cf9ae15b93d304357ca401139abb7be260cec3d9f47803e7479a3cdf51826754de5289a0b917865af3c76825c1c055173cbf22f4d85f4dbcf4c56b8c34808820bf51f990ea0b00eace7dd88c39e4ea865fc4b59c15b45b71676b24c2fe8fb9f39eab1c016cba32825c80a0d621360aef80390ebcb2b35cfe1acca7bf662272c7bc50a02c55eadbd905f3f574179744b41fd549268d8efb6e6848b96e966efb991cf42eb1f6f127134ce92834a74c5a727ee1525d7ed70a051fafd038833349ae33669a767690e43676060adac5f8d424b91107723ee65cd95c425d15305c8d08bb3ac44e061dc281280f9fdb65281362a77e7dbb8ecfde405e34353b16aad79695476e672396825629e8bf49728daa932f00500accd0c25ca9bed7a6b3e9e052f5be5e73aae76465e3cb4d555719b5859c75b79bfb2a88c820cfb1ff095fd7a8022656c064622e4060371654cffa87413b88c1e7f633ea1802e73cde0afeddf7fc6a9e84aa8c47388de145462880edc5e87e9d7812d9021dbd570f0a6c690b44f6b0b70a76451cda140b83b26aef88deac4042fa04110895305eb676e345b88ede86ecf892574e3670101ab7e5487385c29a587fc88c5a95e9083c9bc17aa18ba1487ca761c13a179014eae0b624eea20a325f783f34b426aa31a0da3537986703481926db0ce1993dd3fba04e33db9589a898d58393ab43980d744a03bbc6f6fd4c11e6a5c411d4f454b8259a2aa893cc054a94cd764eb03e5146af54d52ae6ce6eac77953b08100ede643b4025fabad50e16aa8ecd7e20239cc4456a5ab54bc480dc604185ebc560409f61b1820977a7f6d0f865bcf487f8a1a5e152f0da2c2e6ce16010000000000000000000000004abba0baacb8b7c49c6087e5a887027d8dbb85bbc46bfd22cade43dfcc65cba0d610756c48c9d52ab71e29098844893be4facd7517bc40ce05b2244a84e12516c7fe09517906d1571cde877502c7a7fdb38e278009918543e1876d3212b54a93000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001146af6a917891ca2c7018b9236ad169872af0203fc2ea6c66b9b5abb8bd3a0b33d971957cabb53ae689d591dcb8867a6f6348c3910f3bba59084f7088b172271588d2ad4fe8f85ae87adbaeb0d4465c4fa7db029571576a9edb9732b287e9e922e7a120049f5551bdbfa4bd34961b405ce21752b9606429dde74d4d037c798503171ca25d475960ede1afb64546c2ca529f014d3b55ba878376469d0b5d175747022b35ec345213c3af0de572aca87d3a71bc65c2fb4d8ef0cba974460b83c538ea0b2a1f805efac1a16ae7697f447c69e9a7b5d9ce60fd40ef911602cf208c967f262cd36bfd097efde9aa900645fd755a4851007ac1545af146a3dd5b5ca7e3dfe903241ca21f76fe8afe7c15e9c24842b929ed6ef4c521d42f95af0495d2787e6345030d32e33f3917628151715c782cd7ea20801999993fd7eaadc09dc9c7a7271420022e10a87e3cba1a409c7aaec9f359d7941ac30f6e9ea654b67e971f2707eb57a0021fc559af64631556df198ff4c869c361f701d2c10784dfef3ce94032ff50c474032d4c709b0990e9fe55b55ac7ef284c71df585cd8f8a3499da32ac077213d6bebcd4b6d4759b7560e3dfda34377c6606a7bcc0dc838504474f2c688cb61bf17b3597753652a591453ec6be31d0b1e22fbc86e7c746f1c25be123433322174174f375a6c622e6e959edf54cf2ab82b48bb37eccdf9ea88ba885abcd836b95f290c1df17b6eda944e340ea4b313fdb67173f52cc1bb13639e1fa282102fcade3ef78fe39baf962f3f5bdc658c6b5d48ae718a88e4a97b870f8f5a5f63818c547d93b03cbae776e4ad00b12a10580c66156a1e4fd070ebb2f4cd9f75d4bedc5384b7412aaa92df6b93445dcc57d458df8d739788d124d7008296c40c044736709faa6137c878518f6725afcf76c53e35ea78b168d6034bc57e416d0bc9749d02fa111d65fbeb182860efca14a8736be5afd343ba7a905e01d177d6a055704cdea64f21942035a318082780f5bd4ba6c54f788358fcec8c5ee42b71bc04b64bb357762a9bfffe180251f409c67845b78e5f928d5e51e1787a5f7240bfe932dc279209bc67ba2273f16e04f95b51f5373ceafb88046856c9739952a315cc170c4648c838728ff0059d46d57aa951d99fb151ee5c5ddee1c9aa4789f00b647d4c3b3dccc85d6259940f67b31b7b3ed25142528063a2bef5ccfffd3421a1e9feea148982d7ad73166b67d44150a9a35fbe419597b9e4951e913cc6869bea3667688a94a637995675fb66b393ffc95cb3e18fcf4e875da1f3009f495d9a2c9ccf7bc3cc7556d804296892abf0698360b4c6846edf7d6d9c004d0cbaba63af7365d30db859589d6c406ac8ce96985ce742f8049d5055d8eabe302ee54dec7fcfe63e83cf11f05212138c62e5165ea32a7d48cb99069ab0f547c428e1bb81222c1ec3078269aa6b807168ef873f1e25e32675819c1fc0dc4e419c5482a23f9703b7d785cf3d276bb7732254859c2d248e9efbf182fa2929a31419cbcc4cba82d453adde408c219d19b2dd0c3367c6ebffe435ccc22caf363f436eefd080fcfed054aca28f6cf1e94e53812911eb83743546e91bd70dd65ab8b3505342390577e0a34a794853b330563f6b42d22156e0b5f2645d1ed9bfb9e5f62013cfa200d4fd3fa01b5628324364c8e14cf4818142b3d08025a39c8863a199fe20175d68efa2a88c9b04e2028fb38053c4fe6ae818a38314c4aabae53ee2cfe1902ba37ceb453c66d5b22401ad4c550cb8f690820adeb8d3add5a9e4efcb70e876a8994f9c3dab4ad6263ce86ce18bc8be62dbaea3b5c8c45f4819cd2c838211a5dc85fb5663cd985acbf0a4ce3a7f891aaae8189d46838dfcced0da0e05535f47eca2ceda9b31451cd8b2ec570f82d99c33d93ea5695dddae1b264d13c25885fc5847799481bfabafb4dc01a0c7a3d53f282c2073c22d8c48a1eb00ce0ca9e1fe09e2a2fdd0359af7159e85b70ddcbfff678977cbfacae6133173ba1231f38b1c77fda68f3f1422f444779dec35d1d6ff8cd7fc62125ad4d138810c23e4204b2ff43f90ed93a3557548758930b1bcb0e1a392a15bb2b03dec454d6a3683e06afb2e01ed3bb890ec3d588c44e9dd1f08a2046e1edb4f4d78308d792669cabbb3db8b5d39f38dbabee44ca504644add7568a5e59dfac7cf9464ad90c16efd6242225b7e29347aefdcee2ea2c68ac90573f755aa7660e30a7a1b32ed3da8028d3419bb08d774a4393cede2214457595b665f0befe9cfeca2a2615e22e05b4fbacc1ff173defafb1a340bf0fa133eb7d9388037949533c3aab1b5ed114237d65efec3035f294994a7455607a5c57ae5750c05850f9c90159975a60ea92acb1cd62beb004dc083cbe06a0cc95d8757484e5673c1cff40c0cdd53ae62d9d206", "525151", 0, -813588375, "847d8d58e3289c8d346cfa5b1f9214b1e5462fc79586b985c829fa2a982b35d5"], - ["8eea8d72049e59534741a8321bfa9bd2f69a421b45ac9ed8af37e5e1716e28631c3afa1b260200000005655265ab63ffffffff765c02ee0e8e027e0d3ecc575b23653585e11a7c54214cd412441becca5aa3c20300000005526563ac65ffffffffc67b50afb5ad3675f927861cbf20764cda9dfdd9997ef1e5355e27b71da240d000000000016ad682af07043e6ad517701a6ea8a6d5ff856094e60bbf6ae64e7340b4ecb40eccfb67c68d000000000400006353ffffffff03bbbc530200000000036551ac5f5185030000000000c4a0c900000000000153a99c51e0010000000000000000a1e1820300000000b934df8968a9cfdaf14efe4cc4ffd70c1a93234d2ca92a2010245e448bad4eb1c1549eb1d25392c5f3826521fa9b8ca4064875e63ec4dbc8751bb7cb42c9e0f749253167de42946c5f956cb2a4b296c008724f8b8619a7fa2f4c93bd152b10ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075d70107d3ada5248c6f0be85d43d5a79e05205fb97a3ca55179972f94bb5dd98d2cc3a6c556f36ecec7dc29c00cda0b10cab3fcaa820831dc177f2b5307f7e3979d39e1e3e0952dfd0093b64b321b31ef4e6b0a3c22e3f7bbee68edf99907f03644fd42d5b8e02fa61de87c6ecce6496bbbe35022fbe31c7674c71689c1ddb50308785b344295f6c442adf5f71065fb5ac110d496c9d81208b755bf6c7400e2f90210144353fcbaf16dcac5ff8ef491757b9a9c4eb7121ad887c00fc9ae1cd7123c0b2233e019405d69739ed2f7a7c48cd933af4ed203a37125f7f2bd289f98cbb5a82edc474fe5fbcdfc6e2a26d8afc11ace1c2f45d6c9d08905b68b8cea338d3356020491864efd4c5e5cc22a48ab37e49941ecdc8660e106114ffbab7010044a715c02033520ac0d8faa3a7bce7d1837602d702e3efa25710504231efec39a502608150225726e64de2875f24dabbef59faa35944e5ef9e1568684d1d315635811095b8f021556f4fcf4e26a28cf45e0f93c6b6ee97268414bfa29f7aa1570b443faa2c51f022f900b4c4de9c473e09a72f37531dd1b0212d74e5631e7e2019750c8c3464420ea5472f4b0b97477ec536139120abe17be36c40c671c17a6b28a163d7d5e3a27f4230cf5e949b83f43a679bb483bd9280b324ae0785847ebcab6c464087f35c9b1d7ff9e5a5a283afd619f0db8ae5b983ce3f732efe2b0346be28d9276c2b94776e5159624687ca7f82f85fe4cb78ace38b68c40666fe8c0377744784226fb904c99afddec25fed2dfee076b580c9d459c7c164104ed2a810e3fcbc602360228ce08a1ce885ad533b0087c9f3d04306b5097c3a6e4915ea02254374662fe3e60ccb120c5e343328368e5c606c8d17b3463b4673ef52a9f4312fa926e68d420bf0a0b4454920047b65f0dcc7d7a2669e2c09117750000ac5cb02d107da7e3bfed0e0b4dccf05e2df7c96116b89fec935764aad376dc90ced94dadb68c8d7c80293a4faca175361be133ce66a9ced4f4dd04ac6379b5e7e46b76f0a6df05a9c6f7035bc27c431eb96194948416aabdebbf73d64ba1b0109795d4ede7853567a4d3ef150bb0ce220f6d05027977e99609aa28dced791571ad26f9dac3bfde9b968dc52ae50f2f807a1ac2a3ba365a4abbffd502ff383cc50989568df800c6c3cde192534d496198aae3ae82cbc0f370a9e1cc3162f8be205a7472ed322bc83a0516d5ed16c022b1127d48e18eba075100d74bac299016c998892ac3999b1de7fe733c846cb72969a67e53e482b4dfae41c8ece706179a806b0756bebd55e30287f24809b5d0f586399bffb3559b473a69417b95e55348d3ebc63cf6d8296bfb5147967f037a9d47b366455a684fd87d4ed070289379891c2557bdb06813d46f36bc47e67e99d86a7cd400e7719b9c6d7678f14ff9365ba6d9072e783636d9466ed9a37ea88ac5d3b7299384873468f1091792dc3cb29797e991ff5749f33781ae357e4fcd2e489eeba23f9f7b4b1d5fbd0fc7f557359d03366f60425f8875c82e914acdb6c65afb223a2889c365d3f5135abcef68270757f45d32ba88528695d04340f6d30ff168c2c230bb046918fbd0693dfb389a4ba0ec75872e4bb343d7e1b70883f02caf22019e917c55dd405558bc1cf32c90d5d9b463a9aac47fa5aeee1bbae8f137fa70b6bf33c79871fbda688e9b341a70f9a5be58cbe983eb281302a400b5c34b586b33a92497dae5b1e7b1c31a321b10461de66d1d3400bc0d6ceef7b4a5cbeb71abadc20830c1af6e6eeb9eb0469f67142b1bbb389e29df79b8b1d2f0dc002cc9942b26f5034c3313bafce0af580934c15eca30375d29c01c5267564803dbec9823c87fd518d3f485c315dfc43d2ac5674fa567d9da16b09ec500c8ef31a03d711a57b83bfecc6ed4ce8b4cd752703d88b06950a4cd7d83bd51e59d4702e507d2b7f662c4b22451f867c6a4c3a109db1b9feabcde13cf70194737a74e6974a83e36fece984ed0760b36d3a04d531f23badb9d67565ab029e2d68d015113fb4892772c72abcbd9c5f7f0679b9222aab2bd0f36b2b13490b2328efb5cdf0794cd2eed10036066e124074d7755962372fa0a6921be6b04177efef9353808c66c12d1232f99209f2aaf8f2cf37b5227bc4192a19cdb64224d6e1488f631f07a5cf4181392451083d2f6314db41759492230e2ce1c5243f352299790af3fb991afab7cc5b3a8a7d655809febaa60a6a91218bc3e43148e378a20f4df76a4c3ed5955bc79492c47ea3d8a845083b5a6902bc64d208fa5c0b791aac48f8fe4fb4a34135428d606b56e507f60acc01771cec5710d9b4ad328fa3cc9bca3fab916b062db0b71df6e146119b2ede19415757feed9322cb1650e8120b8baab0927e5ec6202c260d84a4d5b21eb34c36c9d4e07", "6a65525253", 1, -1958060010, "f35691a0c38a23dbb55f17be00e5f307b330610d1add51087ee979b58bb3b5ac"], - ["12d2440b034f63c818c24fcd55b113dd79864f13c17ea994d44906dc199d8a3462604299f10000000002ab6321e7a38c1193cf34ec2077abf72b4496ed1625f74e1e8c74f1a08fe1775107afc11a668903000000004b8816ce1584ea979330d35ace064b911117a3eb3476be1efa4b684b19f7372aa6ab1ab10000000000b0cf69d603375d670100000000016a380f89040000000005acab53ab5271f0720100000000009fc9085103502d79040000000000000000000000001102b0d1a8ade113c144c622ed5cdbb77ea1565934d8a64ac1ed82ca120916c1e18f28f6b8c507ed0f969c330a398e9eae66b7d714def8ac71e633a85ed2a736a96b22a15a0b9ae5373144f6fcb28d48237eb6435301e816c6a51a6c596e092400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8f3f214d33998341fba65d5c8cb6672aa4aeac87208b5da66c489a3797eb0523960c6132a74602ac22d9f2f4136c15c86f14b7f15f910b9f1f0ceb2f059063fab9e33d7c96e148957d9feb99324412f0ce394f7e6b17a8caab45884811941c1b5cc88b02107e18ca0e561da8130f23feed8662ab13b726c5ebd6887d90af0c402105ddf670093bbe501962e38669b5f4d5298bb9c17c96958b2217c811a7adb72021cb94509ecac16678258b12dece67b4a1819ff543b14ef9b6d9d05b38876a0320b1413e508b84e14c2f05eefc7aaea1ba72d627221e91161293307b4bdfc8cbf85150b77e4d3d04e04ccb5c539b4991257bf32af607009103b8ea6cd8608750c580315ee3cefef4e9f9fa2d3c4d1c8954fb9bf47d6c1ad4a4453ab761f80ea05dbc70202d843596fcead7c2f403cf596aa80f97ce3d08b29ce62aaf1bace6188ee637e0326a8535ac525324dbbabf6b20823ade96af50e4e59a8ab1bd600b430d4bbdff4031845dd0485c0e069e7f9bb966e7a5bd75f786bc3dbb3be6f6838116cac49c1340323c974bdeb17de6a9f352ec1f5f9a6daaea78afc833265a2c7c051dc2fb01a95e475517d6c2564c2209ca55814b56f92f27deac6f8b065441a6506ed180a49062299469097e0b6d70676f55829c381dadb8e805991971136abf1c166fef605b62af87d2c043f6ba1847523f074fe4100f8b2ae14210030e7b6a613130732841d71300762e2c373577e211b6976ab795eb44846948d445f38ae1cc9ac9abfb7e16db668418b0b10a377d8a46e0f3bd4b60d393bf6e94bd489985f4f92d0776b8256b0c6ad59c66c5784ddd0aa0c456d530159601d8d4bc935a77dc6f83ce44dc91f2a25f35d6f2a72f64a36938d34c0523ad61f515e769c0081e0249adaf16f28cfd47642d28121e583b96c50efa3dfdd5be3d7ab9b13c3bd2b88fe8a2d9e7c061e733230b6ab43c38e04ef4cd9a816bbcb71c88ae670e5e348341a139c4628b617009093cbb866a6859a1591f8706b9132bd2074d6972f97e34c42092d9665bbe37953e0ce7d66e326092ea73b7f4dd222662c868236b55bc08e0c36a713af44765494d9fcea405893a74856e1ac2173eae49eacccac4bb56a82f9c22af680171b88f033e9770555e47c556a4067ca16a318c50f6e1fca7568cacb3eb065267b245c82e9b56029efb947a3a060649173b5f62b79c8fab211466ebdfa9af122975d5c7730f14ef2a4e42cd547dccfd7d42f42c376086d48502cbc090dae72792c92237cd595eb0ebafeb3b0860de7f9e2b4be33dd7d2a27c52ed33945362ab8f902c4fdbf19f3fcf258550e9dba2ca440c4a023b8478b8aa8863511ef0e5e58a0e86ebe3cd0cf8d866695db4380a490c4098050d0c7a34af6c2e74353bc8c7e3db399941610261af82f2ec5ce6365a8d432cbf145a4e819f25243484df800c9964279a66af35c713f7d5ffcdf7f5b11cab683e6f33b2d37299549349e748ec6c09788c001c4aaca9ee710901803773d80c0ee4e5a15d469e5bc356a63c8d5e0e188e58ab227e4d93c23da0e2734ba74f754442608714eaa366e2dfcb2a963d8a52391daf03384d088778deb20d0913a75513912cbced18705247bf95bc94d5d34d3bb4c5604b4c9a0905c95a5d20c94d101b8f6bef58141a447fe6b5898b4f204cc546f6e0363ac0bd144f520b287d379a884f0f44031e799dcc7f32da75d5c8381ffc4a44984e05b505c00bbe93519947f0f08e62fd59961b01eef40f06404ce65afdeaec8e6af6bb69cc6d5f00af919265710210482115408233822d35ac23548656f50a579f61469269010db3f0bb93d59f7d278080331a73d8d307fa0443d240b242c776eb8e067a3fc2d65a3d8e7fb67e29907c9731c051173f98ca864ea5c4980ac8e892d33d8f4824eca438f3232022dcc56419b616d58d595c8817305a6d1d62604a94c4ad9b1b920930038517244ebd8fb9e4ec89a39594eb9e81854d6a00c87f45ad6774c379dc9791abe800cd131516534c3e934fd9ab385215c3be0ddbc5d1fe599dc0d67f1458bf68e3bfd66769f1a19bf6c1ba7c7c6d3772a8db86e49b081ee904863f2305b0e8fac9199ee1951d33fe566e0ecc3f95fd05aadd1877732ec2b6aef5993fa63442accce120a0dab8abe42233dbade996b5ad8fcf61904481152bfeb6c176e04e98482dfac4852868b78f8fbc1acc50828acb6eab3953494a4d13d6822069fc0aae35ae807d7182843bdcb53387a4729a697230e4428ff76c510878fa3d8ada083685d5263b76b7fe20200000000000000000000000064c3e2d1a57f4a249517d3f63e3bbde8d7836221674ca7f804e6b95ad11a8205f943c7570d79f91935927a8901020169e2a14e77b5ccf5329ca5c0e7430ebdbdc7117573f9c7647310d179b0ab602a4c3c13c0aab3be8ccc4ccf660c5ff06b0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de9c2255d86257a3ec0e6b8a3bdc2543b05dba0bdec6ee970859cef548065ac2e3fb0837afaa667faaecbb09bdb86caffc3810f35cbc0bd6b6080768e6d793a1f1f4b7a6bad71a15d1e4ef792a550dc224707c442ac405310d5d5938df14ab954808607791187dd2995fbd47ba9cea0af80421ee25f22aea977e334b56105f660309f9d206d975bf7ec4ab625cc4adbdacb57022583aad30ba26644b7579642de30311c976d9ff8835cf301314b25cb9b318910e7d28e756723e342c423403d3a88c0b0cb087a3cced3a5d8c3b389c6e29b56d1dce22d24f2615405994d28b3244e5432032ef7eabb0fcdb6fe0c1202b9134b27ce4ae9c0c50abe2c4075168c64fc63103235972c4da78a4191cf392a43f3878becc7a751bbbe597148dbadd5b09fdf9fc021c45cd567ab38653e73d6518f79d275b398f01229337afcd99f570860bfdae4f021c36d71b6bd22cecfe4ac9f1112d7e68a287f0616d3aa450c622cc72526756e6022e9bb81e3d37342d7b0125fa40871f65c5c6754c64d46a9ccb54f742de292cf6032454879bb97415bc7085112e26211c4ba639b1af4f0e00bff4826cebe32dadf4dbabb444d80bdb466fcb7b2fb4d5af08642d0005eeeaad27803d60d8b771b93d6ee5515877733ef0c0fd9a1d42408547fb9b0803f577a73d955b061451f6a65fbcb8f01be6a57a55f788f0bb186b3f4727c7b366adb948e26e3af869cf42f3b364516d7195310fca888aec8b88d20215306064eb85b544304641b6fb1b3a3dbbdcb6a82fd6461b657ff708aac43f546669708033c1601caf07801b92cd85caf2e7e8010846a1038e35330fc14185bab513e23f6181c8615c992f32be487151250fd4c8331c0172dd68102fc03bcd9db7fb062b5c647947261a9445d1e15b6c5cf3eb4b269566ebcaa7924f071be92e048be9211d3756cb043427427456d37071fcc673ddf5614aa927cdbb14d25bc227e22250770d7a1fe3f255c289090287528b9a5d90e6f862a819ffe2b30fbb9c24d450c54062e4c11abdb3163a7f8317b41f5089100c24abab31f16607707b6f0777590d75284931fba79c1545e00c1094dd2983288bd49360685fb07b8c6f11afa77970371ccd73ec503f569b13131c1f63894581785ef2859dea25d941e3844152ecf2bc3a45dcce809206248c383d4cc502e329217d8d132f788112e38d4e8973c04d7a2dc188df142594624e0abf13f3d226ff3699633d302bf0b7fbb0bd94e15468deb8ddbbfce948d792ba5cbd2a84be5b6da55caaade4b00663666bd9afb475c68eab4cf32d57e493667e6ef9b95a681a54313f496d83be028ff5c375802108529f72c8be96639a67af001a810f49ae5723286631fec5a1b79187baacb27f1223c679cd1629bbf6907c42951f85e3982ad9cfff6ef928f0654064772f735bc7d703eb810c3a7e1240292c60928381352bd66e3bb45114e4751469c0875fa6225d373518cf1039dfd3acc2b3b35ecc53da46e1434221839ef42a1337dd9b95d51ea23b83fcbcd021e362dc39465565b74cf522f12a0bd88a2a987a78a5bc056ae15555844ce54b3010cd10f662600e5e6733471473943c8cedab4f905ed45a0903abcb27abbe00baeb8a31cddd5eef8bee67acd0201a98c17c40bc93df3151fb27bb33ba5b2cbd0cbc756159b0b2fa11cb93c256e2087502dbe431566f77f7b3ff92d6f7b3279a13b8ecc0a766150f27363a32cc1b1f747f526b331ddecfa7a57791d0caaf1af9a897db3c40979ab4c7e9da8a8563e2cab4c894b949b1e33860a56ef7a347b045f7c62fc92093118000fa280c19a73398c7360612fa776f6aa6ae929eb18e326fab848acd609c061624584b860f385c31fa63b1b8f28e62200215111532efac37bdecae760cf65386910a1e55304d5a1041f91cfdbee3e22be6f022530c1dc0d95b0b54dab432dc8140ca52b84faaafe16fd33a477264c266e99f3f01bfab16ecc7310f02e8ca9dfaee1cbd2c09461330652c2618cc0b2beeea73bf9c443c7a0ca8acee89905ae64a3fbfeeb7774858b866809d1781a21361a181cc6b2d25048e871ee82a8c0956d86cbe1b7e3c42e27e67a1501d874798260b72a477902abb16a4f76719651fcdff7979f1dfe2307e8d89641fd12c9741ef7d65b56bc7a70e7212aacd9b5875cd63acdfcad78f51389a2654bf118dda47a004781f729063ce2cc9ae2b186014f80f22cef1e1d4e4e4f25832c7a038041cb3fc1f179ae45fee1c1bb13f216bec2fb45ce20b5786b35125713b9b1e4ba401045c0000000000000000ced2f100000000006a19095d9daed068f5530705e37ae57a4a1de489cd06f17ceb0198a3c06373a455e24bc428d55d1f2bae876fd246526fbec24278537cc84fc08f04a1fc68cf2e3c92ce62dbd219bbc25b12e245330e89d996f94a47de1aeff8ee7af48200206e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ede7f40896e83c89765327ce2827e496cd3212159ccb07c7d37ceb5c48c9160558377915f0a51c40ca3bdff9b7380688b5a2dae9c6a9c2edc9ea25ec9ffe00d29d2de2d84b99b951f70629403ce7532c4b91449c62489b737783da0cc3da5e4b5bcbcea411b01d4c78ef5cf76d953c5c619ecb315222a9688a9f76ef03407943020c7da18697ac40746a4481bfe5b056414b67ff31a2d5a8a3024fde681bc566680205e96dc9ead6afdcae3f9969b52893330528fd8eebd0dfc22b6ce2d3521c07860a2cb18f103937423173144dd9c182f61d5b24b0e4acbc66d4fd52ebca53081a9b123f25acd9bf199ad3594472dff3dafa5d14ef00fa1f9a337c10e912e7a0bc31032efee4cb17e9b2d84a136e09019bc68ea50882e19df1400255c68671ab1011a8030d5054ea7e7e72dbca3c8df9ccb54310ea17724ea2801e413cfad272f16ee8dd022e75a9a2369ed45612d2245bb4857d7e5ec616767af439d0ab319a1e4af9724c0211eec32c332106f48cd82a2e784f3f59da713e2d842b06c8322af9a83878178403188e614fe8940d50d15513474fe0b6debced368b5c0457f196de7f905818c69e8b48085b3598c2be957fa493f1be52d84f0614101d1b9ab8069a647942f48eafb7f2fabf7a8516f8ff26d9f88bfe9a60884a12074379b33365433377056466c315d1341198b1657c459b75d027ae18edfc7c720108bb3717e72035f86fb50c39fd52a1b6a28d2321d5ed76647623c84f5294cf0d29fed32637e0472ae7b864afc3eea2c5d02e478256a6682f78543912990c7af33fe8af0500a7d6552bcffc6fa765b78524e9821a80e693e90deb0e503ec96854e6c105e18665d604ddd25fed7b9850da86625eef9559b6b3b4d4662c002e90da08f697d15711d995cbe841b7b9dada2f5cc8b60edcbb7e483b7ae6d4cce5885051b402e3c6e5491045c8fdfefe85c1260c6ea83b6c4aa8f9b90e38e15e919904d46ce3659153c983e4abdfc11d71ee4cac44ae4cf18d77e88ec3cc663b79b6290a7b10216ddcbf1f4bd7c44d4935b91596871f34502f26a84732e651414c19c76c910378c032970fd2dcf1f6f094486a1bfd7d33ce975859e3f8325984cf563ae541cf1b67c9769452198ebc7aa34b50582c41ff572d708c9de322f4f4b0cd5fc7f2d7aff29fad71f3ecb7490a459d9736a8c4687b9b4a92ab50d78f0dac3a6a30509a88744fc207245856a873406b881e0a70dbae0974a0ebe5de736fbdaa7bfea9f1e74110405e89344eab1ba1ed68fd92593a1c532e9cdbbba8b26d69f4ffcb03f946ec2f6d75da843c295c0b7f5c25ad6c9d5e827b9f52dca7659ef9b8fb711e85feca40a21cfa2761fa39abe326762a0ce95c41e3835895710e728c59e09bd3eb41ee5ad7eaab7795764ae0d757b26deef09bf7d21df90a50b3261c3ba20991205dbfcc92ccb384aa6f302a5edc5855573cddefc26e2a7bff7638a88650c2b1cef383b8ca60478b4651a4c47c791308dcaae1f4f7094fb5afb3bc3931a55add9c8e779391988e1b9ea4d3842300a5bd97cc6ffca62c0490fe9819f581a436716491333806c0fc910a44f06a026d3507401831952d863eb2eabcf001dd34c397f1a5a11eb6345dd7bf46f1a3f2827f1b106a5fc206a0690ab5db35ba9af79a99025f5d78b7a33afcc3c8bbcbda6d98ca09deef7d703a260b5c9e30220d62fd8d5091a57af6e2db269e62ae767125fea9357321fdc6740b5b62fdfa853bb134f8034586b88d269bd4d4b56b9d6b054caaf5d32aea5827c8dab7ddf06aca3ec267e4c29c45664c8971f15e5883a52e07c9ccedac7674a72aa562e291c6576823af9bd8092f1ab4fee921a597917d9c6ed39f97e62d0206799582f1d1390f876f744c89d959cd2f7c02bdf4f9f4295ea5b0fe214ef3fe4f27f4ddd2751229785ad84ccf5cf2c5c77c1f76a43394b162c10f02c39da7e0b41334a5cec12826d2cf8e391b8050ba609bc3696c7b1927691ffca3fcd6b7c6c42c80074bd1130e0d5d065eb15743190d55201f36ff751c8d450d7b3bd69cca56d696c1cc0433cd989b2b11b8241a7d4acf9ae83502f7298e547374e83a6a67b190903f9bd13164978ea08b045c3e489cda49c971468688cf7d479e0a0262e273c67d1239af32a0046577638059bdf6fd015f165939288696e92d52b135f06f0a54ada811bb1af094392c12d31fddc725a95559ebf5819b946970a503947b2b9a21e6c6744fe4142b8c4b5a45e76e50dbdeea1292747451f275d306e7296c1912f6bf579b2b4dfe58c2db5d3ffd6b7eee1ad5e38bf82189f6f5e0dc13d79f5ae03ebae2b497741f6bc3cd8c309cad12e9a2a1eac84cbf1f350d3ab90ae6124af71beb2cae176cceecef0f990f358ba55115c6f16dee73ca5b423bfeace5375b83f8c7a189d203", "6365", 2, -750381347, "af9f8c5599567707f27b2f6aeec73743d102621a4e0210380045c322446504f5"], - ["214e28b003af544be812464d44e22b4c8dc3d3d4b0c65efbb4fec73e41575096111d5b9f140300000006ab52ac65656affffffffd53eac49a44663d481fef714caf85b30100a519fd146b8b665aa2216257bcdcd0300000002ac00ffffffffd9cf4767ad113dac2596a58069b7a1258dbfeaa53e24af7c3ea8c4b7d056e4a3020000000453526565f505d75303e0c4a900000000000852656a655200ab52b3e63404000000000852516353ab6a53512ecbf9040000000008516a6aac0063525200000000", "ac", 2, -1283255426, "28e67ddedb91643ae4de8d46b4d80902c093ac38a94625a7846ee6bce3a24379"], - ["cd63a80803fca0fa7ca3ac8d7c80ec1a4009af3efd5f3796d12eaf70131c3d996f0db1aca90000000004ac5353acb09ac11cafb4fc220a99df884d44f1ebc3a69b364e8a9ad9e23703fd0b3ca1d093ea536e0300000009656a516552ac526353fffffffffd3190c418ad0b4a77d023da937da482d76b39a61909d3e94ec0052d558f3cd003000000036551518e48bdb302fdcae30200000000046a6500acd0fe52040000000008abacab52ac0053650000000000", "ac5352acac", 2, 696732980, "f29d9a223444116199fd6993fcb13ac8972241e1239ec100083f314021dd7382"], - ["7541bcf8042017d7bdcb49fe74f1ae00e35afbdfc3650c3a0709d6c362ed9a227a539caa2c01000000036a6351574c7a01df84a800f1c252c5d4d78c749cb862f4f71dfc74258c90405a287eff5da91f190300000009ab0053005251525152ffffffff5a8c08665b4a8f53ffbde7567fe74d837edaaafe8dc33eb35f822d176689cd440100000009abac6363ac51526a531ec30443c1ee7f324baf539a6bec33b488b259bafa176fbc3a641b7481082e60d487901903000000025300ffffffff02b5e07a00000000000763005252ab53ab57ba620200000000026a6316a1d60e", "51656553ac", 2, -1104625456, "ea5bc7822f08606f1e7424ffcf2d809bcd7bf2c26be5c0974e220af8e74cfae9"], - ["e1e836af04937d105ca23a12aa0b31de5d61b57b1172f30a591f18acde7997cf2554c2551e0000000006635251516300ffffffff9ae19b6fd7df800d68bd0d40acc76aa1aa4829a6c13826d60db53dea1e426c2a0100000008006a6a63ab52535394bc96e9f163a287acc46e6c6367f46d09e3e701b80aa3df4ae1d4e1afc19e537e4387fd0200000002ac51997f4030a370cc0a1c7a04365e931647cbaf0fb6517c4e5596a8749101da155236c89cd80300000005535365ac6a35e6f26b03a822c40000000000045263ab635f00d404000000000951ab656a52ab006565349b500300000000096a5352ac526aac526a3d81eaec", "ac00ac6a53", 3, -1056346309, "47958d5b000b153e438bd118d8197bd5573a762e5f1b16cf2a51db50c8f86b4b"], - ["6baf4cb4035df082d6fdc4087ae0ad8dba2d1d7334b9edc14ad2525e0a9f7ff3469b920e3b02000000036a65ab4c002ef79fd584210a4dbd2e4490226085b7bc1e1ae7a412d168b7ff8e429de73df4ff530100000006006a510051acffffffff9f0f5de6ff6d5ebcb56463b35296e1b96c46fead630133a3cfc66723b89b8fcd0000000005ab52ac5353ffffffff0173752a000000000004ab535152db4b6bf2", "5352", 0, 1174973847, "c422a2359177c92a63e2a1e251f5cdecd470c0811452470073c744a6db6621c3"], - ["f02b254002cd3289c08ba76c07bcaf78d94ebe15c34d5abe3c8ee3090225b4567ca66bf8b1010000000652ab00ab526a9e93a9c6722adaee59b1f41f258ebecab3f5dbdcf150fc5cb99adcb98d2f70ffa2b129b9030000000851006a6553005365ffffffff03772f510300000000056351ab52ac49808b00000000000163c9362e0500000000036a6a65aed4dd3603353fd804000000000000000000000000a8c4c7f95be6f4ec3376e150b54528483e48d9ded92f044304175109b2186e56d1c4d878850f952c9316533a16250d90f9a4db026802566a0e65afd940def6d2110ec7351445fcd693c3661a65c0e368e1d28f70a9deb8f039d172c9240b7e02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006856150647578f9963e237b6fcbb802592deb6911aca54eda13e03e2c851b1abc6ab967b6a8054b76e64973ba373566e0906c2e1a009be709d6e938c1c9418157cf2209946528972ea6dbbc5bfab2e384a15a6a91c7d6d41e9595faa20f417d0f9640df5a2a10f90d35c26230b8f3ddacd9380db46e86847c800e1e14c1cba76020a19a36c3a37b56c1d5c67db8243a5f0c96c9421e84214b613a100d1387478070320a1996ab8347c72d19908b6c831089fe21ccb03872facd53710a6555b45d0cd0a18e131d3fb7dc6e55a0e4638b172a85ca6ff2a4e461c9acb329602ab5b243ae401b9a82e8678d3e9bf52f618c62ea9ed56b806247bd89aa068b5520c07dad3c202145b65dacb748d5ed03e90eb7f96adeae0b2739bf2ee26a47abdd4a38b624b3402287eca8d7c52dec4c0ae592fc1388c6d4886ba0344f10f346101aeefa69b2eee02253cbef503ec6fe0397badd4397452b42fa58b56dac467d56d418d78b0184f83020da1e26291475dc44e4808b5e83cff69459597c6aee9bd9ce08d196c4055e6450308795f1ec16a15bd6330aa69323d1084661f5b869eb399cc5e26413a2513c1e6bfcbe114a668cac87498af7183551bdc59958845caa110f0b300699c990a1a575b8d9b45f8c64544062157a62213d289c06f8987452be2eed49254dcd1142dca1e7a0cc0f5cbb6de18cfd95bdb42f75648586e9700cb460847571aa38a4f400003367033f00b94dff3978aeaca2135c509949dabff373459183c79e57e98479f72008b724f9c5a19f47beb5787c6fef22801c8c99ebc7e68e8334a54709d7d621cc54c98b159fa664b83594ee937686b946af26c1c76caff5e8d46767b997491fb4723d111a7e16391f9c8c83d7e527f8e32978336b3f9eb00fbf73ab2d39a73bea0a7794996310ddc54a7b7f4c7b05a0d55afcaa8d640e956fcd69fca6188de6c44f314fb8db86e9486659aceb9d1f39242c9039ce400747e05f6b943c2ca00b2892c2828de1318eb344b6e529e87337f2017ab577961a94f17055682ab76e4017f0fdf381528c94df7431f271826849429702959315439b40c3ce1abf354b5120624ba1adb580ffa76a895e3748da6ca1804eb1ff3e689abd52922420a4ca7f7caee5619cb55d481fab50665fa5078c666804a02cc2f7dec1efa291799acba2bbab9b63acab07021382e8c7531e08b654d451e98ee38318cb50bfad8bcf9868eb6960fed6fc6c2d6b1ca915cd6b4df5e545ea873086d60cf6ac0b64bca6e6e4b3240054c7ef812d5272dc217b5d4aa8cb7099a5a4816d3320528d450142938bdabfde026be540b48156d1d376f8993a58793068c8945b628a282296c7f3efa76feb5f643dfa6563d5c44a7561d48ca8405cde96d1d5d1430d7d6ebc2212e5f1c2739190dd2ae3f72a15b29f0ca1566ea9b1bde8fb5bbbb270660a66a2211ed3eb26c437e7ef7a40f9c6c6cb46687b4a165def8a07fbd6bf05fd1429c3c63e5703ac4f9da315ed4faaba6b74cc3c2dc8bab0d78798389ae1c787bc57b39afc4d572796d7d64605a65633dfc56b236214d7fab67b5f481a4884430e6c07eddc7096e995d70a18d388e9ce6cb98dcea761f559031f650a26d1094cb49c12d8544961dab1b58189ccf8657f13cca57a6b49886e252f1e878b83586e8159b6e297fb7362862f914121d7b764a88b2d9e67cdd7b9f588463069f026c3e6f98bb70bf0e1058162682930465398a9dc4f3efc654f9e2cdedd457c23515a1f6d8a87a147556ef81ba732b04cc4377e8b53b23962d046a73691671354f26b91c708d110a1ba4013125394a2e7f10dd457cbf7a25280cfde15f4508fc31404961e2f0e921009d6de4963d8f0e2b38140386c30c1266944df04081d4a27016c6cd4259903011146fb3dc671e897ee27e2f51cf524f95eedb1ca939481e8d2e53eb845bcbf3463e700f8190c9c225a23fdc160553106778d59b4ec385c21466687788785981b216b5074f946e4934155d70c63a2dbd8773c475737a9302460d26d36d33695b920002356bf3e04783c6d2e2f7519735a4a55b8d90b62de8440d73cec7e2e783950272372678b07999c9ca9ce9eb658c04c5e205953d9eec7c7aa7087cd09489ad0d1545126779c480d807b9d58c0a748bd1905cb8726916a5719aa6d882521b5fc61672370a4b60aa3c432293af4e783b0d90e7601a18788b5b7106fa9f36da6bbe2bb2701704eba721ed7abcc61755ba012f9e46926ff95b79a70c58bb8c5240087a4f095ad8e00f4d23736e9dd4153952cb884800000000000000000000000000a3c0adf0aea334809857b699300464d37efb70976caf9befde18749795bcca5d35df6b0d537ab5d328b5d92e4d3ddfface2c8689c0fdb49e84bbd76eb5311f600090e4e7f12f9514d754f4326e1e2dbb96499175ffd88d7935d8237b113afe32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a5bb1d4625c92b7a69a3373cdbe2698a3756927e0735a4317aa8518aedbc519f29ac627281415f95dcc41cbe6d04819543e447da000fdf5ce0a78505387214a33a0e07ddb4a5314255ffe8c200cbb03ec134cb2711394354fdb88d1d32b2bfbeb2c3efbda8b882c80bb790127192b1170f25992933045758e4384506108e0c80300992dc44b563ec6c523eb8c1b608aad5586b30d61f4ab50b82d718daa73dfa9032ad6cabb4d4495bdd162d1260e36b06bac43e71ff8191449c3e3951105cf4fb80a2d9fd00d2d08a8de672f89323a66e63a13d3d93007e1107b3a0e4b6d087d3e542b174cfe72cbd0fc1d5c6a802d57bebc545d0603555da51ea645d8c0b529650d021b3227d298126c36afc9d2accf3c505ee686b8ce13bd72bdc273a57f43e83c6e032a0b82403789a5d418bf911c1fe1c79f9769054c557aa8aef81c5bb9e88062380218460d1366ce7c65c84bb49dae47d0a4b38a6779bc80a6d48abcced741f622e1020ba62acbc92bfb5c1045054acef13d0ab26d90ed1792c0f4fceb7db8b52b4cc2031529215db12fda83bcd016cca996ddc3da3231f73451acadea93c106211b3de2563bdf059488039cb49daea8c51e79ea0abf2706ad762bad1462c97a3fa52e86710cb9b6f0b3b523f674d8fd158fcc291faaf753f2a63d26efa6c60fbbff9a6b8d8dd154972d972bccad9a5f14032d51dfc37e97176d55bf98fd3def175edbfc9f5492b35bd363da24c36f8dc967f9c3403896dc17a4217c022b504ff4b3d9c267abcb6a8bf807f5dc177593cf934ca1d81a5e8b7d00882bb938226c22948e67221bfe352c0e72ee78a2d857925aa5acf155da3378414393f7da7448d6fcf643ff446f0fe681ac9479554314af6977f2d258b5d57b3f63c5b44e102384c6b8918e5beaa0c21203d5f0f895288fe51dc4fcb135daefac0004ff83a06fdaa5217f9b1fb28c536a44efcd532ce385811c58c2c210a859ceea4e6b6f9f657f46231464ec1fe84c2a330e8f689771d95090eae75118d0dfc1e63ee1a5472dd8863e70d39fd175e3f35fdbc03188fc63658a605a99442f000cba0113aeb101c8d550246ad3b96926acb8df45f8a55e2b1361b26c756e28ffac3b355e760500fa896127fda3cb3b8fd99338f7525ffa4b8d55fd0b20b1c349793476a1172bc07e025c7f04b64d66c3a46d12faddbf148161ab745958f1d52b8fb45bc0f9a4cc3a1c6e31a25d493a3c696537e43ee789e363baefa9000a51c76edca55b3e741e1a3ffd9e3f9228d5e5e4955de30c98bed85ff5aabac1e7c01d38738b1bd82369cf0ad4a6234a2ba98fd1e26f0ea9fd38fdf1aad6cb30fd151cf581901dbfb85b63a3082581a9de96497f95aef1f8d915b1357707e3ca861ada0bda7dc4d356a7fc710ab4e5fbb45a2a5f03e0ea26db1e82b5ba0769656add53b6e3bdb8e9ec2fd9fb7aa12e092404024a4e8110c60d793714ea9593e25fde7e151ca531aa888cb9f1caaa6475450c2fde7a0f853bdbf8c1b3c6c869a6679fbe64a237d62cdc65f32557dc5358de6a4da3cc72b8a3b6d08d9137a001ccc76c0fbdf696f8c9aebf474a402c6ee790ba57a665b926ab9714677c917311da9ed0152c1373223c9afc4e0841753208b623f398c4de21a0e93b38c1bab83dda65e517d532509c8f93486623bb3230507755303bedc9c73e70f94ab4cdfac4e09601f44cd40b16143e9dd5ea870f47d7cf49d3ed65a60b07d4e213ad5bc0d50d9aa9f64ced5d4b14c28800f3c300212583d6a7c29bcacc3fb622b54f6b8a304b7f098781aaa0415b8bac6ede24dac93b77f15787838016f75f166c09fc7d66e1e146e2a4a077cf7c776b579097a18165d5e2c30a6b7fc392a1b0a74d6dca72bff51cc1528b8a87592917ffd5e5c3bd30ffea208c02957eff6e42ca07d371d8c6d3b8e74f2b0ffd37cd30e1a24f395db946ae2f1924acd4214d57a410f225d76ff61ecf8de7ae87ac94e55fec495786e6a49147e3461b43fc460012854a25903541aa8f1385b0255db053e6f278497356c2005df720fd7f3fcf20bdf99118bc5dc6a4cee8bbf2bb0d9e84cea99901cedd6e1f6421a914030bc51b60ab07143ef26ed8aa8611eea86a20a2fc1e45fbd277b3911e8d8a0ddcf2aad39e2e3450f6ad7f63e1925d134c446e0e3272a1c1212b257ce99428db2bf91d295632de45870f62027d23810059c490c396c339ae1b741e8bc83d87ba4400d2e1307afd2e00598d0461dfe1eb848bb1dbc36aed18649ef0da48724bc297ded41a382857dea1a3000000000000000019f9bc00000000000f5fc9186cd59b52bcb56f07bfee640553f4b406efc8965f81c1fccad358dfef1db056f0af97012f7aa793bc78a464f0e91c2398c32d2b5df19fe98aa195cc8a8d40e2deb91cc05ef2d755ca0c3f3b451beeb5e31a0321af83af6f63ad15c6900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046fa3692d1c4fa70464821fa620ab01948dedb4c913a942f3f7bb9c7cc61734cf901248352c8fe37b58c90d1e7519d3bb50ba9df194b55d83d351553f0ff040567a412e8ecc65cfc3286556e77ca1ac94a94b1c789b1c66bc0ef209adf22ef34b098a57bbf03ee9965bd4b4ee8131e3d5cf59723c560c90147d0202b362a882b03218e0f35c9511529cb27ce4b2412789645bf2e659a96c18be27ba8e4def3d10d020bdfdbade230222a121aac1732ea44227d4e5b603bbd83c7015fe0c6dfb4f6820b211409c147562bb46f5803768ce7831234e5320d8e6be3cdea30c4052a4fb30a152a1207d0837668047c27e6868ea1d3fed9a8639174ad60b243313ebc986351021227ffe9ad89f336fda4f388de15c7fa0010c197462d34640318f8a6ec4606eb032616578b106e62ee854e27e6a14bf9177f7effd10f897de4121a2e746cb25a70032dce9a7739ed16239e66e5ff552213b206a16f49f046a061493f2613bf4706da032ac5884b9c3b80f9dc04a02ccbab661f4096a5e1dae38e00640b51f6f374771c0212509ed4a098711426716c000b0fa9642aff762f29bb0c3ff72a04c1b603a9b63ab6f3e75f7cd286e867c99fab82464eb65941d0007da6888789401255cd674c03459e769a32e53a58738086d96bdefec3814c461970abf23a8bb87733f7224761cbcef7bcbdbd5d7096013e8f7c32afa13133b94c665fcc2d75073d94a42f11b3acd056e826be4aaeca50ba57105e7289f14fc87a46185814b8c8acde93cf764be798bb60a8df5eb57eea46c182deb0c73734c16920f10b611fcb6fd94a825625f256ac3783f683d9078100a17a5943f04b1fd667547b4a45da6c5b4ca91867d0732a4986efdba087c0f1018e331a7be381f382c49776391ba66a54cf291a837baa70315096e6601984de92e870a6c436506eb1cc87e1f3fa26de651a502088fb10c5617093767ac278983ef1d72091475d9a33d9f2a7e3ba39166139e1c34450844539e6076a1025e221659234644e17ec712c6983f165a7968f13216f7ea09d4096920618998a4a69b052a5197815a1758f0771039ddc5326fb79514efa938680a38b63c9659900071e0db4b0fb2584e8a806063fc064ee34a1b141a426568348a872caccc5e3619844f103948a037f60bf67ffac7c39d70ff13755c9be1aec0674396aa3873b85496008fa58da9435129b3f86f1442939ffad184e223dbad2a46caae73cafa293016ad7690582ab9ed17875cd259eab147f896bfe848fa0d699718279c9b9b0955854fc54c3a2e53f52b2b2a574fb923d726403dd869119953cb55ac09c21a2a788253847b02f16dbbdf9b6b7d36371a5b96e92bcba500594a6a87b48a142dce573819f515b30d51e702df373acf5537a6e9d1b63b9305c3eeb82a3d312369bc2b7c15080e44a45639a6e6ed2e7026cd6486c6eba04d7e62d3449bcdf2f95d8f804492b5a0b1775f7149f71dea76185cbab4d8c9a6ca8e7f29ec8302aecdedc6538df99a04483d1a12fca7a42db1db8dff6d124245781b8fd7668765381c3d65df8837af2491a6e6d2c87d1c57a9ff5a4d5a3c3fffca11f68f3d6b65dc975854fd9009d9fe98882a24a4fbe069eca0191b5539f60c9f035cfcfe88919828f7971dbcceb6bed9228602a0f07318af73a8215a0fc7119aacf994244f53a4433a82766872008ca3492e27012efcf7b45e8bfae946e610a8a5b6cd3a25a8cecea023a4a2e105bf38134b8559a0f90b1e43a5f6461c840672af1a2b1e08215324a937f618165a11b53b0f66ee9ac1168850f661debbb8f176ba5c0f2e5055016653691d10d2cec7e06285f8e9489d322f77ac49c918bff1a75371ed04a580de53da6835a880dd24777865d70296b7f6f24acba203ae368fb2210e2df8cc917fc106ec82d95066bf64ae524cf5cd0b05b6d9666decbf30e33ac14ee12e498c82dadc63567f1fc9ee299b2247396d26768b73bd11db2def7ae73263402d3358145244358d57eb3b5bff74918e0ee6f99cc3c8ba61f202ba0e8eaf1d71429573b9bc63485db27493c3db4ca298be3254be11f9a7b1f4cb9a6687957688fc8d7fb03cb084216653abff509df629a71cd7d7eaa292d59ba0490bc0a7e5e1156c712279124de5d2eff498ec4345c6a011d3a36a9d9aa4eaa0b834c6e7740e2194d42f3bf570213ae1a89554f0ed814f04ff8522fb4a435028f72b88c9839d64536754944914184bdb2227be35729d618866a13b1fdd1a0054dd9d261ba7bf99b1e23e6eff46d170364fc620f27bc6ade1c852a171dc8f4ee1b95618e358a74318a9f508d9e8037047ee5c215eeaeda15d1b1b16f867c6b46a9d6e7d0ba16c220e85167de5a6da58f2af9b2f5ea17c11a75a33d101c1d2a8103dff36a7a6532cfedde7dd52068403676b62f3c65340c", "51006a", 1, 432578750, "eea69ddb1f784b1444925271c8b54aa2fa666b010a82d16feb6c96020104b459"], - ["6c1c079b01bd30dc31df27440816f063fe02727d10dd2d29becf2969f33d5c93c3aec3b7700200000008656a5352abacac0071259570013913ee00000000000000000000", "0053516a", 0, -1869686261, "5ff87e607f414b2fe4d8813500c99df81593e0e96e5dbd9749217aa7bf9502db"], - ["4607d131011f1dbb9b145d7769b569c6bc19ba20548b402c0920b12ea5a45860c5b7439a3c01000000076352abab5151537b30d8e9017d5e4405000000000853ab5363656a5352000000000189321603000000000000000000000000a8245434fb4e22ed89dee0e8d3602f309370dc01a8f6022f7f9828c2859331590430721404b3e54f1116cbf4273be81cce0b9fdef0b2ddbfcd0aca49c78e2b4bb2af4a2934a39f33f8a7e3d08988a9bcaf722442441d61e7e05d2a0085873e1800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f826ab2d8cbec51e6e29e7023d84bcbc0c3cffedf81b7b49a5f44e9654e327f3061274eacea85014a5e5994dafa52d2ac39849e632475e00673bb99487f3a1c6fb7a71e6689f789ba056de4f580929872ed27988b6bac93af3de622d2c9647863dc908565308d7abc73124978088fc42b1414309e1740176598b0af4f5b3c58c022533fd94f597efea5283a98d72a6ec5afc07fad11c81021fc49f582f0c1d00290301b1d0613f90cf09970aad1d9933e5d6a9b2d825860f06a2c2df833b315472300b03c4c5656fe930fad0325503ad98ef8017028418c08c00ceb3083dc8a8e941d512857153d6afb289de7ec453c17c2ad8a68fdc36b41eff06b362778b11c842ae0302f7a8be2f720c6b6c3c695b0aa3d5866636e776ca4d1ab22e9c7b2b85c7280c0327ee5a8b11fc30a0790daf068c3e1775f6f0b1db7219784a0d0c05f21c7cdade0213ca2724ed7e5add37ecb2f094b159201069f4ace6973a1e78241dfbab7bdf76021dd186236c169b1de4bfbcb9b915e02e4d1e18bb1edb4de90240e72a33be848d031c602850db92ea4363170b028dc7cf9337b8528fe4975ced67a39b5a94bc2c8721203f19cd0b527b86aeb25f5f70cc35a8909477f3080a3ee59da66ecdfb62e979ed258c5b9becd7b8f8018b7e69c7c3ca83ffd24b07fd496cbe548ef22ffc81200d491bed3664dee2a54222fe38c393b4640f17523db260dadc5f100d0f899171c381cb233d340b4fd71d5b2221734466be1f908548baded264ef5ea3b473668a1da2241e0b768e4d0492e34aa967089cfba8b887bb127cf7c72665926477ed492c39a8570fd6838e5294849d19547c824c448ee5d2076e2f5df3c08a85dee86bf291fa4493c70e41520afdbfeb2f93c5c23de0f29d86771f1489ea0fc7367a11fa7abc53d381e21e170ad1cc3009c3ad7399bf46215196b39ce6820c228e49d44acff681552da1a7f820f12441bb2978cf0c1b49bf3c2828e157ca73a7303e7f89e22a4ae7f35a7dd9c78cc3d4ac23fcda4dbd514c6ad473959bc81040000077e1832d03426f3ce575ae1b786071baa818bc776cd6e2eebfa479193365e44b9de6798f6ee98c403f8678bc79307f69a00d054f6beee89d8216b3ce9c8b2a099db773c9789b5f92b0ee18e0df4551daeac9f832b8cf054fb7bad2e11ce872154e9964b8daeb7ae6e4a3bc8695a055ee0c8e5acca90a9e1fb91160449f18988d6bd69ce9dd2df97b7e08da7f99b6f60f03533360cadb26efadc7230cefbdf05644b327ec482f88cf84c8265b97457644b7533dec471017f62b53a93b562aa5e64a8e816c32573730295a84f7e60ca382efbed81bf983a133c832b23bedfa493da0927946d874278a53e3908c0636a2f07d1f22def3959878b7e1e64a0dceb7458454f43c339015b6c01943aea1b19d6d444ba1f798ce49d321968680dd2dc75c4b83fc1c75d18808421a5840aa7b93e9aa729569e7bdd290d82d50dac8cb98db8fa0a9641144b58f90c840127f9fc5175330680c39b6dea1047b8ca569e2817491c15b98988df72ddf9dc2b61c5c937f131ea6a83dd786f2a70dede77e57ea82f56802a28ec0954a5e6da1958a0235acefeccf6851dc539fae28c3aac0a08804bf33ea4ba6928a1417ff32de335174e755359755ff47099b417f673ef32ce42785573e367f650e2e64de9a6adc0d906000cc392b5629fca7fa36a2b3c83d6aea9f7657221453076b515e383c4f1a88a5af9289ba5c874835c9aead5d451a8b005ab8111af0e3e8cff86cdff78a761f63a8d144d1c7e70732dc178179a93e30eec54b7e6af162ff10ae189abd8fb121862f416e9670b70cf97636c223260f7dfc924c52663bdb67851069fe5d9a6ce2fabea1328989fb05da81deb15262523865dd271de77f4e8ef88793e68203aaec64e606e32eeb26600fbdf913c4f1579d2a2e567141ee9e8d0da1a5d62aa16c8148fd26058633ef38a7e5593bf2bf38dc8f63ff79320c13ca29423a88287db509768bc5b54b078a08b2b9a87e42aea9da9f004285ada76958312f9ba35de86d9fae3f352e6f36df3166be08383ac0f405267b00a44d44b82629c95513619d648d3573ece307b09f701e570629b6127d0e2af856f392729c3f702f9965facfd0666a9f86627e047c762f45d96f1051cd95ca1dc4348f9f2626bbd2ba2fd79f4e4b04f65ba2436639897c28fcb7c4eb5d9ef3a96614b718993840bbe4a07ba8574b991abb5c375d1470b461207c0c61ad21f6c8f6ce4068e78ea69f214fa11cf9b17636e558b0b77fa488f36d883edc01b97f0c02ffbc84d477971940248d615f10be6ce2740de21c90f39596972ea83a4e8d093b398f2c533e5db739d7d691e22d4456d4b42afe7c43f3c47abd0a9f8fe5772e88b4941185fcb9d5953ca26b2f7193f10d", "ac536a51636a65", 0, -1786274802, "10085739477362c6f2d12d690d83bef88ce842406d593fd64d5b883dade95702"], - ["73ff84f304339609758b9473a16f2a7f2387c7e8a8d69a059a34ae1911250f8b458dd99406020000000451ac51acffffffffcd468fc36635bcd26920bfe21ffa9c5465b4792109c6fe954e727f2e820732eb0200000003ab51acfe9c78c7584c444e629d6bdf880df240b3b0067bcdbe39a2327b73bf799ebb5c01e9ddbe0200000005acabacab53b3c08015547e6f5c57d95eac4929ca8bd134e5c202cd19649ab6a13524de1ea9ba1079270300000000ffffffff0171e0010100000000075251655163536a00000000", "65ac0053006a515151", 3, -981835875, "3e01b78a3a31b8db363b4b2df5cf1143f3f0905cf2f650e67388e0e9b08f11c6"], - ["f48a9d9d03ed37f1263c59233eac80682c30cba6223ea8552bc113f75b8fec8f0ea8257370000000000652635252ac638869d40da0b6bcd433d4d6d70b36c574f496789ffbfdbfdcc4c86bf94126fe628505a0a3020000000751ab5100ab0065611f87526aae7a8960aeda855ed118187f9fbf93c741c4c953c7ac4b5f551eef8f6819c0030000000852535353526a5363ffffffff04d9210b030000000000f00ff8020000000000b562fb0000000000015276441d040000000009ab535263ab525353ac01e347d3", "5353", 0, 1518285991, "a9e361394a0019e8974f2bafd0784a85df605f607d8c9ef7bb4e2737cfcce20c"], - ["ea8f36d70327f19ee777df1ce00a0f67cb80fd233d7a8e7f7946716494c83d26f3031cc44b0000000006655353656aacbe6db9dc8f934ab94897b05f2b13b6f8ebea1a2adfde4f75c83aaea58d47f968dd06ed17010000000551acab5165712215ca8ae89e770b0994d6f1ad5c76247c9250daf00d8bb34b780c2a92b505a6ef415e01000000096365656a005165530031500933024857d2000000000000ad6cc2050000000008ac006aab6aabac0000000000", "6551ac65", 1, -375164970, "e19cb5134376e9482f08f20586156ea522abf3ed4ced101fe18c4e9bd70ffa3f"], - ["61331e4304e358e96d794be8cc4e2a6f3b902b8fe12d5b35ebdfdabf3e57407a5f1ac24b0c0200000006ab53ab0051ac76ebd0d9f1ad6847135fc48597dd29f0b8b45145b98a149d949725be2df17ad46ecbca010000000001acffffffff4412bd581f448c7b517f615986619dee164234ccb4f1ce490017abe9e82846dc01000000056500006aab6e5602be92b624b957b13294c6c8639dfa283784d6f856b5bd67cd2ffb3cd2d19e1e26040000000007006a51536aab63e281637204b6dfa805000000000652ab63ab6a6ab679dc000000000004ab52656ac5f936050000000008ac5352abab525363575c54040000000007ac005151ac00630000000000", "65526300", 2, 887585537, "13e866b4bc90efd140a89a7f214372334aead7ed2c48c9997df83e85b074aa13"], - ["33f022fe0429b43b66e7e0cb97c73b6cd9a528341942fb2263c35db30e4ed0098001237ebb010000000300acab0fc5895f3b9bd91e89b64933ac8a314c906e2b7bfb484774efb9c2e57e185bb71c5c1618020000000151ffffffff49e4f68bd9a6bdc289e246d1ec59ba6e68f86087507e2f250ca587d974c7794300000000076a006a00536a51ffffffff9900d9a17c8771c82234f619759bd6559f7a54e8fa7dc1c34fe2dc56b6b5c906010000000963ab53525100ababab8cd6577803d2015504000000000852ab656a5265ac634659ae0300000000066a65ababab63fcd1c205000000000263639cf303c9", "", 2, -706112884, "a54bdc5770f71b88561917c533f8a4cd009efc601bffbda8c8951ce68ec414f8"], - ["7d0bc11503b64a5ed807183e0c692eae77b3130e3a01ba51c6556452f65113f4647aa274640200000005656a526553e64c52056f240b26c386c0ced9dd8111e5f325e6a6da724f99b8ee21ff81840c5f54bd600300000001520b74fd3255ec38a436cbe40d7e45735aa7c3486c626ba0b93f197f12c7d24b1471bbcf5c0000000009abac53ac006a51ab518f25ddca04bc55b705000000000400ac00006c7def020000000007abac006a656a6a1e37ad0000000000075352ac635100ac55761b01000000000951abac6500ac6a51638439b06902000000000000000069a8ff0100000000b8267637f0676c0dcc9b82109aeefd4c5a5067b27c5ef6bf7af6cc205e68360f6aca77919310bc354717752bbb88790be15b706830d952b6e62d7a6f5db83b5c5cf14d257964ff1b70051da2fd85985d4924d48003c084e049ef27ca83d7d5fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2854f9b58f66885e0cd0287cc9cf5758ebef5cd48366b91a55493f5c9e8b17edddd63be5f50849ff67a92bbd4afa63297eafaa4ad336a30877f970a5d78d651c5fee02026fd9e035012c6d55948ae95ddd8430d8978616ba6013bae9b5a13b292967f7b06f5db169981cb7417fda6fc82fc3e1b6bb92e7647e9e06d5fdb5ec103155821a5ff43947d5377dd01a554e310a83676537ccb447ae2d30cbf44c2d06203253e9833f0ce597236df939861fd8824655c676459cfa15d9a2a47c50c9bb3fc0b135348befeff9b9b7ebcf903099ccdd493d4edb99cdedb3081ebfa1a093f17fd166be3068e325b3dc1741f9a16ecf03fb0e5b8729b1e57cf12b23cf0c3e55ba803111349490754ff1daa28892259cc8ff4d75804a2a6c340c05b4a68035b3f4124030749a0a15e7b8938ea5530ef922ff2d496060a9eb633c049722c9c04ace5f9be0210451365968e316ad320a8e90fe4d8053fc51af9b059b7b2a215ef335e98a6ac032e74fed95568c7182df7d3b7d311576a08c30c2e0726fc50f33ec8c5eb36dfae0224ee56a96daf5c19d1dca64c63232e5625ab712526da80ce34c140b073b03268bca5cbdedfcc8bdcd75f1f22147810724609b70452780f89cea6c346e400feed0851f7be8af3c4c2df8333ede0505859bcf9e718e3d4326aaca9ec2b0a1a57f2c55011510c212d98e7f17c1544378eb0d2a243b7c340c57d879b096530f52dba5380a871f88c6ce6a013beb57ae9a98700de255b95c21167ad5abc9ccecdf413dc1096a418988c876af5d1c2a417658a1d49f3f545817763ea2011381c36bf0c0b4325c24fe0b303c9bcc9d4ab56082075530ff8bc76b0ee2ecb13875699eedb44e69e604d70112dbf6fc31fca56a12f56a8c275339677d776c10c908d2ff32031ce4fd6ecb7bba53c1f142a2bd15f51885be17af7a921709cf4bcaa60d362884e862d5c015adc527e8ba3f99bde3537711e34643a6ab50e3440a67f0a40223b765c0fe39c85881398e684af8987b6855f7123d96621b41884e7af17573b5dd8810562ae1cf4bbacac5c9edddd5e0438197c79d73d48e072ca5da238457285604fdfdfda26dc6271a59f5cd3cf664b8308e98b04e23c192deb4c4b9e7224a7f28923783f94bd1783d45483e2f1b4363c60730452a4112196ca539bafa10fb3928a9ad87633377021a03bb43d59808f97cebaafebda789559b57e30e08c33de9108fbdf821fb6c562057520af55d9011ddc4ddc013cfcf6de18be9e9200094b06124bd5be679abbe4423150e3f941c0cea95f680a6344adcda63a2a168f0761b155e6fc2145f1b263f9ef4c5e89d3d8254a510ca241e53bdb72ae431a65ea69dce289ef2f090346e216b01d7da291f67972f53a015d9d8b0930b9f22e6710a1439e4d89071c55634f162abe284f995d6ed515233bef1a561e64387b26ef1f41d2c6f31e29a1ba77853a0fa624dbbf14f6533ee3e91ce37f5c43bb47424dba1267bbe80d5338ea0758cf0ecfa3087585de1d4dda0696354fa2d58ecc042fb5d04e9b585bb9c2cfca8d42eacea32a9d28c3e9de97d953ac0d0a8f7adb119f1d49536ed57eca3ad7b2813daf0e1dd0dd1ca2535e44783caf20dc024a043b6185c7e08867b6a98548e9fbb193857edfa49662aef64b43b8ac930ec78d3b29401c4828f7fdf4fb427146b3a4dcc79d1d69a108531ac0221c51c26721d7e85bb06e1e1ee48a0ad7a7f8a4dddaf4bfa71c20edf6644cdc453df105a521fd863a1d0490dec8ee8a229b7f97e334f71d71875b2a3cfd0edea4140c3f12af187ebecd29be381544e2bc081522d75649d439c155a7bd48c15576f1903f60e96d5ebe09f67bc58475c651b773c663fea11e178ec67a05fc63c00713272d9a72a21c3d28f01ebd877911937a735957e69cd7f0641417a39ea081833720fb0e9731f8f8363d0e4d6c33f57cbb96d854c6a231aab673c0a38ebaf7f559c31446e3a3adcaac291d9851aa6dfd62595948fc968df81754c8fe7e90f7358d4741813a0183a486aab39cfa1acefe0b125e9c4a2c49aa4af3dbb93e2adfbb5f5152c7961d8e6332072a6e35046fa2da3ad5ce41b40929aa3ec2b4df90d9bf5b78e6e7453cc082cb10b15615b6ccd27253bd91601cc3501478f88b75af57d69bf7e39a866e1f48f5b493c6136193de5d4d27ca529bdea34bb4d9d0c1c24dca6dfd65e2bf0d2418c7794bb6438d4298d9e5cd14e7a8a8e83aea9d103814c23d5697b7ea1993db653b3276641240a75d30ab37decd556b3466be054e98670000000000000000e2d1b60200000000e0ee6c782d9e6b5369d26cd12f0d3a74ac89f41fda7a7f6118857365aab57043a6cc42af2b2942020c1a7299b1ce92b323a42c98e4b03630a6934d8fc6ad4cbe61da6b3f821cb698a36cd505b58d5708b0adecaa38aab6b3599b789568ca62e30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a1c617d89dd407299aaf0726b8e45568f01b15eae81980d6fcb9ea7933a21243610764d3741c73dff812e155695110689aab42e74dbfced6318ce89ac541aa45641d10e0d5e1ef062947890e9a237dc98d9ad0597637e98da21636da8c72d8bffdb31ea2a550c8c11f82f93a23f5e98be938256efee502d16c1100d885adcf0303ebb2ef45649d5538fc99019cc5c0fb4ae672fbb836f311f13fe055212e43a7020e4b6309fd7bc1e9d3ff3ab806841d883b006ab6014257cac253fea187c3e9fa0a0e6b5c6b1c0574dbb3d6e474593dd4329af1b8c890ca0a01b8450f8f16dc48e61a5d27e731523cbe6c0897497d3c01ad62070e71a3d85af2822b740439a084760312439eb975205727157df829bdd71b9aa6e390f99aa1be4a033478591b613491030aec0ae9272433d91190dcb5896eee62af3158d9271b01b016ac093251e6359f020e71cf5eb748697f7836567b521c09485fbfee49c3f4182c4ac17c20a4b47158022f7c819ef0ed17de9c38e16228989f6f45d3a318944cf5ccfd0b37540db640d50304d2a668a2732d2464ef1193e3e0866ff0fb1b4b8c53feb3f2bbfb9aac1805ec9c277fb0c1dd1872c8ed82e849cfb7a60b2b08240f8414c6d81f4409a85c56901c53b240cbbe11a2579450eabbbb5d2b84a6d40645c92d45eb479503efc9edd9245ec962751cac3fac369d1a0f257ec27fbdf179dd633b295d212eff54a019c67c14d817ea35cc7aad81baab420dbe30413b6681dbc6ea13724292c0afc84f297e03e7e266e72eaf80764534185b06fd5c31e6ccfae703191ddc9b88f8788e6923138453df2a2af6d340c440dd8de1f7de2fdd272e310e788c0cface7ecfc83250d33b998f2b75b1f99364ee27fbd7ad605b7bf0ec0d0af989543ac360e18b57013c3a8229ec6ca54f097e8b52422a1ebcbb78eac9f0a0df244082a4a641078e568e612a4bd1051112c512872a5cdd237a10e7a33f321d130247a8d4dd8364088591fe17d847dbd445fd8195c5217b96f53e3cc4281bda7067873a1e603b1e9fcc2d1b1d230f8f178ea3e8be0c58e78cc44446fbc312be55b9d9fca769b75e4f245b3727270d6522587d5865a8ae29bbdc5a756b7630f90b0c7d69795f364d3ef4347bb69a6e16a7cba611b4ba9c4455b1ff0ce6ba15d1538b21a47cb46a64452bac4960e0d8022a83ea5679ddb7d1a7b7973d1e559345beb7a0d1d32bf2ca642d0a3d3727104ac9407a6e18cf353d3bd8365c73c97b890352c3d3a041d3736b23aab347d78bfe01cc004bf4ba1d1e1cbacdfd4ad2819b6474ce2563cc189a1db65cab93b44cf191c8c385bc24d0e61295cd05f149c766e8311ebf4f449404669c704f28f364763e623aaec9ab31f4f5d5fffaee5d91aeac69830887d9ec9ce38ef26abed4fa60c68c9a0b6986c648098321a4700ae20ba179b89a4992eb884087c6e299be2a3294d0a9fe8d33a85ce8627a045396e7a11c4efd8449bd352c938bcd9539dfd7754b0e05a2a3041250806de3ef682b813aa887c4ab6610e6f2be57e58a337384c1a53f5840f2681ea53b3b21ac09fcfa2687b2cbc7a6830ab07e21d80c1c19944d0ed1127b2679ced4d1a84feb239f6e7267ed5281234c32d659de8c0cd16e7b9820b51af2fa3d49921cd687d183fd40bcad612411e9913898af2e2821664ba072235a835b060188ee90ac1d7e73b5aa27494cb0f42d9f853014cfdc4464948e4cbd2b504adcbeea2a3d4298949e643cfe336c5fac443dcab22a3e5b78e3da872de4ab49b6a33c0f5df594735b71bfd370f44d5926503cbe5c97521cf4fe3d9fa9e3ee4f31c1f6a51920bd4cad05accd8c998646da4bd069ff456f82d4b03d7400085026b36f3dd556ec1295ee501d5a2db6e6d997bf1cdcf66fafe219ad583ff86ccf8a9de753f37341f6c840c9d5ef5cec76722735ba4c5530e4ae1295e14236abb1bb3fe4bb0bdbaef39a58696c0bad9dd6943897589d71a760b275b891b63073f8ad910285e86f59f3b6db8fbc735bbe89ea308ff6c97e9d1a64418cdc0c4dd5e8100982339d171cf74d1de1fd08a2e2d17c0f77918e8023a3b9c35b01d4ebcac86efab96eedef0e0ca6019217d184df22cd066aa9080e9478e5a9e36c07feb9eea5d8ddc6db3d56b5a9d03793513eda4b3949e6fd6a4615b0555eda0c8d6160b08d3a91e3208e116aa0853552b1d85ae86df34d85e0f7be87f19b03ec60b21cb298ff430b1815d20de54aa182ecf8be8927e3abada7346b88451e4dec1b69e8a000518d1ec5d3ba8cca07ecc99811916ac6d977eae9a95865eca59436108376038b0eb387d519520b993e6356b021d446a9eb686f3f636394b46cdfecb82ceff2e43df9758c68a4b70ddb36d13be267ad8f4ac05851141ef60ca9d22de3a362fb01db0894871d814008", "536a5163acac", 2, 1668438795, "075a3200e4995286861c8da88daa90ab9bd59650ae0e5a620368d672adb21e3c"], - ["68a90293017be2f74741d5072182034f457fa173b9c9b87143e5297da21c46a5a7ca58f123020000000651535363ab00da08e4f4035b879d0300000000056a6a635300462d490100000000066353ab5253002b8dee04000000000200531fa73bce", "630053", 0, -1936509849, "5e1d2c080b706122e45c90da31408b65deeef428222ea347614c2a3e782f5f5d"], - ["dc46d3a901d63aad7c615f7e50e6670e219bb90b7d4edd1214ddfd5af4fb0cdae445c877be0000000007636aababab5251ffffffff04a3a0e6020000000004515151001dfd19040000000001005a501b030000000004516565532f929c01000000000553526a6a6500000000", "53536a536a6551", 0, 479598192, "0f9f9d62b89c96a56e1c26fdd07b694e008a0ac2c95f833df5171cea6d119258"], - ["7d382f4c02e01b0ed95dc1a387d48299ff8d55f1a49cdaa983b00191d889109e69a5ced1380000000000ffffffff9272be0beae10182cbd060181477d9dd3f1f27839111113d4c8e51f6ef9fb86301000000066a5365ac5265ffffffff0364dc9e010000000009ac51656552536aac635117c2040000000009516a51535351520051fb7ca5030000000002526500000000010000000000000000989d980300000000d211c789dc7c18f5dd5a106fc042c1d1189f1bc486c7b671c943333e0ced0d1db0a5b7a4c4be4b3e123ca54c1e1d603d2489f01b7473ab12106b0be0e1fa1c849639c829a941c03f45bce0a77c21b27f3129e3219e6070743d97351f5e05034f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb8c4eedc048595ada4f994bda71d414849253cb604150b1900f1613b839d125adb5acfe74fd30003be53913963f0ed6aea9ac8c9738986def9d9f4b7bd300689eec0105c4d899213fde8b20d46319b8b078ab55c914400039e3dc6bc847e1cd720ff0bca37deb51cbf921a533d2a06a56f4204384bfcc30a49e8084119714e020311984016ef70b15136e4fb075c9a1b5f429a40a1e04bc672f68a310a09c150032d2514a94ec1c7a551e173299b6af7b8366127a161bc8decb872c49e471b96d50b15d2b34df25f7d82fe181495437bd576ff9b54c67d29ed42d746294acd3ffe060b3ce89c1466ba35390c2e6ea38732cbc914e80e199492c3f869f733aca962ec021b2dd3e601cec86207e941bfe5ee36ba8fb8af6d99ceef77f2799d3ccce9068f0325750907b1d8da8503ecbdcc1b22779c0d7639d37dc09c1b75115c293a66811e021de377b346ff46c71112ea1a81c4b5e976b65b60c239e09e30cf8b8088890cf40328faffbef05a45d893ef9da5fcd3eb6074355a3ed057218d260184ae639829a7021ff4958ead6da2f794028ea53c4a2abf1b5234d8f90dc2512a71bf20b3cd4cc0d80330f3e1d673e01788b0f80b4ab3b6fedd27145984a0493bfb9a981452bc110471d3365229249c282d37bc86900ff6a21017f295cc1d37c2b0f1ea744e68158c22aa6e8451c35bb053d950b3747176aa811f4b74d7310bee42fe042f5eaea81654dba52a786f8f1f3c3f4f8c4c93ef8de9aab1e0c3589a28df6012ce5db65f2ac2b58de723b12998d4f2f6902cf0b2d0b70d6f61be1afa30929ec03c65cb6c1429ffd3d6040bb5e9e5122bec201a44114a122a92fb4010a07f25ea78361dfff2cf9823cabbdc3f9896225a621f348018cfe10e3601a22f89f50bc66e974f1f3d0e19dc070316bb2c0a44029c418fad7cfbe65ada98176c9d6aac11de0fdf4974105e5105bcd7bf1ed2b4c9e215bdaae702429ccf6c5f281efb2290cd19f080f2b93660a4715c7a02c8e34ea4e8dd447f800c7aef4c2d22fb7d8ee79ce4bc613a76bd5585fe8289461e51c65e59bfafc7a190fcfc7d6e15c0014bca57de9201223b1184e832c8946e73ffb89896c71f86e3e9089b7f3668fde753a32fd654c24253feb5feb52a43579a230759565b7769cc40779c04fa257f51cca8069566416da823f8cc5a9ed883e18b20f1ca77a7bb669edfe7085c72fb775879e16437b148930ba262761f068cbda3fc8f2a49a75556ccf5d4dd05a2b63ca9834d4ff5f10b0b8849cd6d3927828c4d08abfd3d07b4d1d9a949af569640be04fe966e517324b051b751c986f9b7dcbf7ff9375c1a9b8c40b07fb6ac2cad59c97b311776b67b12e606b85379f098d0d19105a5eab31df2c1ed6b87cb83909aa4229a17b7eb00478296eda5addb1d27cfa304c7f6a7ab628b98f476cc6d065e44d878cc10c86a93356a4e3fbaa797825530ea5db92a67ebd5aa0a09b7a1be7b1b76db0aff1b60e2138cc339795b2ea029e5d4002e300e3869bfb07c33801edcca975a204f065c4f1ebe9d75377affe07d7ac1966aea50f7d5b772b6224c2874e392034d27917bea64645373b5b20caae4e5bcf3504faeae8b2189488d86d534ffdc2a8097d0e3de1d08ae9b5bff400abc3a047efec772e2f99abb1906164ae7e6f1fb9e36faecfb60aa0d861d8b38db10c6e572654704f6532589e3f193491aaaab8e5fda8cb1bf2acb4bf3847e5558be6e7407ed2dfc33f32fcdaa8a6e3c0019ff8997435aeaf13cf1acd9cf8d075c9489e0f3f7f78d6153f98ad07e420d3b96ce2c12644268e556ee5b6f73785bff62ecbe79079cf7eee6326b095c336fd13e25844dd57cbadae0a5d7f98f55c20a6abb3ec74010704ee1ec68153d87ef76a70feb548280cc9237c922b4b071498cfd51d134dcea93502b37c724bad36aed3f4e828ee90ef06e8e94d9269a3bd3f256ab772286aa9a21db0f9d2fe8d443f5617285b95bfec6dc50b4fc35836ee68fd1f1dd3c3ff1ed40b5291aeb0998d5eba42da28362d567032e69b710c0ea9e064b1bf77fdf711ee1abde4bb429f82c8ad0ca7dcc1451b2531f78e0052e013a7f85d1d275351c4677c1a78292e47bb0a59a42011520c55a1f7ecab7d05bfaf25bf16c9a4da1210332e327cdbb437927b8f6153e36fd3b2923d7cc5a235ca0c98156337d392ee8b54af47c77e01eab4379394b60748eae761c932ea48214a922b0e8ca1f6550db7c624969d7153cd4401d9758d825e90881ef74b7d0ce58cb16d136b9c4528e01d2b2c5d9008eb711494de3b536571c1e298636fc5297d17b7adc525c1350267abf1ff0ad6129ab2d71bd1ba7d3c7bd6dc1356c8b04d35ff37b34af2d950f129991705847afa033e67088d0c7e6edad07b85942088faf51db7babc8f6758c7303f908", "53", 0, -27663804, "373bf6870aa59e6a6ed88d383c96c1d73b681586d9d236de535a0b009bdae012"], - ["7919a08b03b162540f3415988459119f87ff6a15e681499b6540714611977330de26b090cf0000000000f5d0ca0b3c523d267581466ff19f162185ba114f18aaaaf37c55a861a15a2a5aba3008200200000005ab6a65516372ccb82c9b4ffc1aaaae1bcb2af939eeb353920fffbf306f17f966255e2a8868c12800c100000000026553bbc29cb102a379110200000000066a00536363ac0cdb850500000000015300000000", "ac", 0, 1563405851, "cb44fe4e571c49c7c431001f5956423adb8025a5372f84ef5fb0b222d586ce34"], - ["1f54fbb40153c70a39490ff96a978134c290eba6b0429fc4bd009ae7918ed54799a135bcce03000000096a5151536a526a0065404e89ba03b5ae4403000000000751515300535200f8217704000000000863ac520052ac516a7406680300000000090053ab0052ac52636a00000000", "00536363", 0, 322938114, "a305f058143e2ec8ca7ab5347de346573cfff0c4d39efcf8b508acecfd0a20dc"], - ["35e36f5401988e113c4782d4668403b50b9547587dd526d92179e1d5f5eaf258c21ffdd79d02000000045163ac001b7fbf0b03ac2e710300000000015312a86000000000000453525100b9e6ee000000000003ac51528c56333c02b01871000000000000000000000000002ff4c6707680735e096407e68c03ff04e1be546a5c31ccd925cb7ec1fb48fcbe7bfbfc439fa693d5f8ed0c1c8a249441324573efa3c536ee5e1400adf151481939a3fe1908194288935df6bfeb705af269fd35e964a79424914b7bdb0d8b8233000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006733211d15fae2a552ddb697f5e041fcf48d8224303f3c2ff7b65c3bd57621c795c15867f044950bc8c34e2778e597a79131773346a68fdad21a92dd255c055091eee9fdb94836225780c6d3b5c666fbeb82ac6e3bc835a6ed301a7f780987556bba9265e12da877d46991771f7ee9c1dadf9eb8089475e97d58e7a55dd1beb5022626bf509b4e0b2eab012d357f6eccb912fab71bcdfa30085a01a265eee41fb80304b072f561e337dd19a78788b2383b3e8346b55ed875bba87491dcb5829bd5bd0a250dae0b9a25b90c572edd0df2f5792de5a15d247a43550656639ed60ae790390aa78a6801fd59726f1c62be05293b396368e17616c5f3b02d6ea07950f1dac30312445dfe54fc13864808e46d1478f3c4dcdf65790e46a11af89a4660312a70ea0305eca6a4d98aeb9bc9cd13a41c3864cec90426a209aa4e1f5f4fed800c3c3d02022e1a7096da95e15f83c1aade3068c003281e9de1ba3cf4e95c0ad1bc909a704b022ed176e947b5a08a6c7ca83f3761a3540dfa5c2fd8ee7dcd6e0e63d49df34b4903201d5e651d6af29256ebe1230c0cd636bcc9ebd3f6f8ad7754ba569bc98f4ebc6968969f49b00f44099d7f405bc6dfc4e9d2a69ef3bd294dc5d433bd3638c04d16bfe50d4f850937b5e3c8e23ad27ea950f58535dd23e9b070fc81b639f676c154358d4eb996a778ea7e5ddf40aede849e0ffe1e47b7c359934227def62cb6a6b6472c15492c3542ff659421b28a60d0f7c5c48b1e588f8d267877ecbec713efc6b4af35325c4a9661fb1e2ab9a8cd49a921a0b2959b4e81c36e197b1b54495317b9e1cbd7723d83d752eaf875033a2208efb56a8fc69fe437f7d90de783857e8d2f585c4b968d3e2af7c4635d8f6e448ed91fdffa3d30a0f5f61f19eb6961c6c07fef8a6fe7d8519ba31dff370d1b4fd343e298b4b2b16b279ffdc61e25bc91d8540f1d2531d4edc25d690688938093f65e7db2e308eb17d6040a5f1458088855cecd60d7d716df82bc14d6e88710890ee9ea56bced3ac99e1e67e7163b13de8809c8f17d4f76cdc075d5b6f7b693061c6daf5ae143d7055c9a0d993bb535cf21fd473f88aea038563c23db40ac7b3083b0208c0623e2f7c13050ddf7aa40e24a50d1d35aecd1bdff3bdf0ef3b48440fae359e08f8af9eaaceeec35f4c69d5dbdb174c44fe129647d869e4c19761439443079aa6aed88f02c21c6d911c26612d2b49fce435d36e4545b29a996735bf92f1c531ceb6f8f59588ccd9aac14fc77d3b158004617ffa691c550296901f9056cc9a1d6989bf9821bf7f43bb33b5d645be2db5cd91c0cb452fac17e617ed758b13f6bb664517b3f9d72e67bb7698c2aee42383fb45db011e595132bd7d90fcf8862577d874bc16300d2040874709e1c8e3469b04531f56f1532f4c82bc344a45bbfcb952ee697528b58a93962d6e5f850d29485197eb8b021c1b940373b4ded62cf341700acc46c924642585ff51c1293aa1becd0eb6fc5e5c83571985d11bea2f5573734a0d93d362f5ef1f71c873c9b06aa3c9f78e789c484a77cffabe698e1414f01a0dac13abb8a9443fb2f045827a1d7337d680a3fbcff4f065bfded06856284578e16c7dd2ddc2e7a5d0e362d27bbd09d59426633c2d0d4c1b985079d10b91d05a58092828e5d880a7c562ed89469198b11d40645d52f35a12332506e3db72c9bd734602ac56f90d8093f3ffdd0eab1e455b417416c3690da403db570e784b30488b9ce99b137ac813883a421d64571862deeab827a37b07d4d5d875638eecca2a4942057d253826e7610249141c90114c53752dbfc3dbdda9ed57d8f860bb8b758d042c07dd7939487e73270eec0e1f602beec06a2626a70005759c8c384988ad214ab7fae7032b8865afb3426658d8c6dc8b6495db391de9dd6b3485b6ed98952ea6e69fc4b0dd8e433151a56014cd5c5d53806909e178f5cc2e1a3015aec285ea3dbf252d02f8e19f9621d56a086487a607561a0f2572b5a2c63a9b41dbe73466341eb383654a1320bfa64251b0c2c5fafba026080140791ee155ac694af27d51380888d4b9c3777b2c6fd49dfe2b4dc5eb3f521a74fc5af8187a413a233c2ddbd4e8377758897d67072a8bdd56d812414ce0823ed444028c98c93cc0f62aab69e088d65e1cc3d89120fdfcde0d5d38aa2e3155505180a0ddae59e6d7a33e320420c9f4a5c260326bed0eab2ea16a31cfdab2414a621cef6902568dc6910968aff2d60449851f27d154cd2fa15929268c3690861f9ed37f3a2079b8cbe000000000000000064755c010000000082a5e4ed0e79c1ed83481f522f404a319641aeb779dd1dabec04010102552a0fe15ffafe8ddf9fe59d8c7359811dcad5c9fa9e4869b58150e0290d1dabade1c0dbabb0af584fe87ba663596c467ea2386d40845055fb44953a7d20f20c547a040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093e8d0eebffd723ae40603e23cdb84f1a1747d6b9ee4de89fb8f948a049352db4cb9fce800a11682d1e54ded46e3bd482b7291544ed8f3771df9f8779a5bee6ff3664bcb6edcec424c8773d70a4e582059cf18d86c9b83b019fd6b4b19c3ec97f8bb22eafb02a12ad7e8c34004416dd004260ceb1e44c0cb1aca811936a4ef0003109f17a115fda7c4e746ab81692b44ee1de8fdbab1a7ae4ef1dd91faac262b3f0309c90a1a5b97336e1501b730e1674ee221d4886744f257217e24f3773c5601a30b0f432345a23a6a300ef8da147ee298ef0318fefcb4c82bb6071f996752833c2d2225ea960a15b581729bc0f25ffd002f702433a7b93b30b786851964859e4a240310c93fe4eea72c2cc298b663f1f995b0554da01a2ef626ba568692a9f4ddb3e4022d0cf8af1b04f6050667280ee19e5bd66f412d83e97bb2162dc28aa8a6c617f2032760e1bbc3409bb57994b05dc25de41a0da3596564ec2fa78f6f2c9035fa93ca021e1385ced4f44a6f03aadf936ec00b4b4b1904c19de03bbd7ffa7da01e6c30d5020875cb10e337cacdbf05b9735b179ec54aab77687038a36d5ce21b20a64816afa46f4172c567a34c4c251f12b778ceab51702dca4a3ebc41247f6631503c164d2f459ca6d7aba5829f7391c197d44fe70d72a4128e644cff73df147b9c67cd310be33a7334c1232946d76a33921ed018c3093f948c0ef0a873a0fe7a3a3506d2ff39107666c873af40e17d666ad7062cd3ae3843bc3d9d8f12b4b5333bbbb3007e513ca35e1f2759bca413b5c274a7bb9cb8345bb2fdc9f6eecd937fd28e3370284fa7189f268a7478e9aa353e364dafe696aada14c2ea3e1b59ed5705bc9a67e2a66d83d0d78f02951b8c21c57f3d845842751096e0ece04491e096166672d66cebbfe1c2d38ea117d0d8c1cc71d1ee2d5fd66852c721a127f165801db752df10ee7083bbcbdeb93723b9695b1aa2a5217550c80da8efb6ce5b98b3ef12b1f1b2e08e92150ec25f8b58075a326f0016509c1fdd21b4353bd68da092d1a2ccdf845d931f7526f4f8bcc03d5c4b3b1401396bf886400a2b7cc39fadb65c552eec1da43b320575900b70fdd72d580e1d6aae276f5e4641e6d0038fd5681ee540643a6a022eea71da1f40eb084ab33ad083c1375445251d5871d9bc73c1545c0436b2bcef176aa9f9cf57f797913c4870e13aac989a20b2f51dfb32b5621b6e875a4c7ba40c6fadccf79944bd25bc87ec6a2db06926d20fc8301fa76d23fe7f1e18d154accf68e1823b7945870c8c4a82c709e0ed6b2718f3c85cc519ee9f1827def2bef7ae952b5bdb127da496e17632ede046a5b77456e0f73349ce07d28cf06951c65d873e45936ef2fb7300e5323b3fc4e92d9853b93b456fa8184e9c167700e22720814be7cdfe0995ba0331f712016388c0ddcf8bd1da60900b3b08d3e14831508965242e093f461a8b1e7e382b51d685e8f9075c50d5ce9448c12d06d016e4dca8ff4046418097ea1375718890df77f638bd9dbfc4cae0407cfdfb2058f35d14579fc49b4e695c7d5ffeeabb20d55a472c9489519be94bf9d98536f87887c16055a96d483cc72d657fdb2deb1a088c04d27407b3678c74b16cb45c012639632aeca6e61e94a826881fac1f421e3249b3e0888d0f1806649272dd55bee35fdc6ae9aea49f143169f97abb9bf55f9ef5ed009db96ac765e5b2d2ba09350c90137126249f27360474f2a4931b26a08ddd4ba98278b6f95516bc51aac5e8f4d8381be4507c9c24fd7ef9db648fba63f306392ac5880af5b1438cb716d1a805b1dcef9a0c2c9f3bad12dc62a1fbaca2f8699f5e3b5a3b4400890a54cfd7902e5977c2a4384afed777e3549fb5dcd8c7cfdc503b1d0849b9520a8a40218518c3f2acf84b653e3ebf1d176d0a4c2d0ee6792c8eaabac94dcf896010e4aba3d4b91511d0698fc2e2d04b83c752f131b63c434a761544b738ecb2c38abfb398c9e2eda8170758c00f211143b61c68b50c64bcb756277310e0c8dafa0c2001f027928a130029a4505e23d3650c87a9a3a03f52c010727b45237b089ff68a5341a3c6fc969482da4a2e62dbd0cc175df14ed10c1c540ac27dfa39a4c50e04fc320438df5a22aa91fb1d8b7132c6c3c63a06c499c3d26d8aa41285ea4701c165546fccae445c13bdd3b29e27d145363acf3dcabf66687398d325b8385d2990ea7ce5d6974befaa3af3578dc2660080bdd17fc3d33be05fb7f7dcd53f67c710381d91240301ba5aa471f98573463bab0a40e5b9c5fde35777bea1cae1843cb3129a60aac91cad98efcd37b637cf5a21bda00bae9f019e0ff2b43a7df8420a524abfd179621c85976b044d854f4c25a032f2c3408de810c0b7b0d9d1c2fe54d661ad402f5d802715b5a6925b1c8282296253c28713c20b", "636551acac", 0, -2043176623, "95bbc51bb2bd0a40a74bad3102894ad63b9fa56aef94d50bfb298883f783205d"], - ["14b505d0034729f44da95b72469c1919325d531131bb0e99689300071b2eed73c8113bc88e0000000005636a510000e91989f9dd19db5c8d12676dd08d8013ea6c606440230a499ceb051db1257b03398df5d70000000003635253ffffffff148b748b363109f789521a1a0d12e19218a364e1865fd59a9c2746649b03d4a403000000055151525163ffffffff0406d365040000000004525152002e932d0500000000026a528c0d66040000000000fb6ab204000000000071790a41", "", 1, -1884621492, "dce39e723fd59a35713bb718d815352df04253f30eb3b1792aa2d48e4bb0d5ad"], - ["6620c602032ad5a8c2b24dde6d1bc0bc4a49e263f7beb3b27ebad417b5d855c07ea6ccc7c10300000003516353ffffffff9d47c2ce3f709963f0e19cab79e26d772252c501cda33a1607bd7b7518f114be0200000006ac53abac6353c96e464eea2566d6189de6b0116665ab1ed85a89cc436f1f3f649c25a816f0fe4c73b53e03000000056352006565d7f054ee02846387020000000001658ec1cb040000000008525153ab000065520000000001541a2c05000000000000000000000000dc5bdd184b1ec3fafa2ed7520cf862f0f89b0074c312e6d2d96965e4f8c934f44517066205d5b76cabc743e5267017b53ed66f4a12a2b74ab5a43ffd782a0dddea4499cafd062e473aaa21c0e1946083791ddda22359f981bc05ab8d8ce83d54000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b4a471cb90d72ac4a419af1fc42c6581358f287f6161afff81dbf0b22fdf650af4c8fa360025fae84f8d4418159a5bd548871f6a176b27b896b72ed881322762cbc9c797420599fbe1bd1bedef5405e78e9839a279c015d0761be7cca1483f01bbca3c317a0f9d6ceb4f84ce92ae5513f04a9d5c17de0f90b194fd559c7aac902284df4dd77949f9faef3bb0a73bea227460b41595d75f00ebea36400cde16aa00327655f41e6c37b9ae8bff772c0f16c52d2014fb75639e0a2ca8f94d479d6f4a80a281d7ddcdce41e452cdebdb7a741b1d2e0b1f10f88ea19766a1afd7564085332008c3a5d2b88f25be24a97445fbc99d7f1fb0761419e7e2a791be3da0a7e14fa030949f5e4c4cd85836efa2f60477df379523e8e72124d9a242f08f80a2e2f53b70321702903ea84b9acc620c305aab8f4f184ce3344e839dce53aa9cd9e259f0ba30306b3ff6cc404cfdfac48ada13a645828e8f9a54f10a89f042901aca32809af83031e62cc5ee6d9ea08a5500c38b40aa3a56ad5a976603220ac086d604bfbd5a998031c332fd550192c9533a69906d06da8e0589b9d578f7846936e06cf49007498e5c45770d122cd21c0f471633004bd71b914a20beba940917255d357ca3f13835f81b003b73f4a66e791a915ec7b4a37f027de8ce221d45079f16cab5046f09b4caf25662526d11725fb97714cb3a306791872f4d0458580eed9beef263929c214f3eb86ce0f19969c0288ddf768271935519e1cd13a75b3e9c89b2de6d59ce2571364f5b326f05136af3b1d6c2b7b5906ab3cb57ec7005e3a719be78ed6ab0a379f764565c1d826926a28acdba2b9e9939ffef3f29c1cc8697b8a6285b40204686b7ccbb5c326c54d666890cc9f4701a57a3e33cd4fc5a582226477ca39dc3c0c4aefe953a5026a05eca65d8548a6b9e7efb7c699e2722a813d057aac25ee617c88a2628f60cc92ef23a34e4a6df3f2144ba4b6cd830d05816c924e513502542aef742caec5a81c8f343c42f527991f06239c4e37d2b29a81a8e4258538a97d1b5ad97d4bbba420605646507f705a5bc31405c724e5dc244f3498b0c44aaf8e079b8be3e4e62c49fdd2b5a2f5cd9c480f610d8f841327971cab5f0a3292d171526e9cfae9cc59b0ac9e38b9107191ca162516cdcb1cc92c357e74e56c386275008e36dc1d8598b6b6aa6121a5b39da8ab310c4dd6b32bcbc3cb65e6729f669ef32b55ff338965eaba184bc74d3c048e59ddfe2d960244a5a3f5263a4d64f072afc6398ee0dbd00ad7645636162a050eb23c7a01ea63ed6d7e81ce180ba449f58b1f8cc17c93611c10bad4538138890ddb9748cb00067643a3597f9ba946f1235978c3b686f7cb8900534eeb94de895614effb0497f4dab85143306322e6c3593bca675a1c97205b810ca955a032778c0f4f2b9cabe4c54da07d3e8d17db728a56abe921c6ca88655145a72413663c2375f0b2ab43dea81daa76747c24c4f9de6f411e4bc9560b625e08aa28cdd6e2eba342dbe0603f0d857009bf9b32e09fc886a7e80453953cfbc71b74da9b9d81e9faf0431b335b97bfba3eb9a01a7c9ceb93d64a25816db6d92925df995ceecd19e87f29bad369460b7a4f68f09eda656eaeefe8aad59394d7589749dbd18833f3c96c9f32cd3cc1b31ce86bac672441449b9c16f9853b1388d0c0ad13de28332bcb590a148bb7912696533840659ed4e97dac9cd65af7cce189c5ff686a0a3cf5d7b81171ce579a3942ebec348e1d06f30866ac96e79a39472b83038be9988a59f2aac229408cc992b4eef9a1f28f4bc2a355a77bba9df4de4a74c1b3fb4d4edec67c3350df95d6b75821606ea788de31f43bbf7511c58dd58ef09c2faaddbccdb376fdf3b407da3dbed70926cd6f77b718808f26f6d162af73b2b62f610a375e89d27d34dce0f2e3003c36e1aba360d776c9cdf6080971ddca6424c9f7ea4586931ff1bbdf2a9f9b2219412fa0248f33a33369dd8243f336cc8537b7960db9f94a57a64564d33e87b9e51a60dab7c3d42e718c327a72775a5f6cfd9efa0b607d05b9bbf3f53b5b89669611b699263ff7773900cb6ac1005ff71e85a29fc418b7b76f00f5783de94a29697740ad3708369d770475d0377669f1e865400788a3a6726e0169c349c103ded33d12e12b327d5f021091bada7b833741d0fa54c195b072d1c59d8b778a78aa6c259bee94f0cefc91e90d907a721f9fa3509a3f734e1b729a5ec85c80134c0945b0f78e85cd8d7748fa137f23a47d9569db50481e15b5ea4b862e4c078300858f79d44a2060cea09e7e3017e28aa3283234ed4d8d3021560276ba2ebe184afea98bb0d6c6da06128de4fae720e1ce7e5cf288f8a53712e7a32d9e347e4ce6c1c4b53aa8425010fbf45bdfc278a0214f5b4a2f8c31f3e561fa0d", "5100", 2, 2109038873, "8a42a93347bec043f620f773843736691648dc58121c1664c80e14c46ad681ef"], - ["bfd23ded01b04038a75c11fb19c9e570f5e0491400f2f6565657c69bf81f31e18919f297ed03000000076a005165656551ffffffff04f38ec103000000000763526a516a6365bae6ab030000000000a1bbb20300000000076300515165ac65f5384801000000000353530000000000", "5365acac525252", 0, 415677267, "fb383852c20a94f8d0f63489dada2a654454b9e7973c83850cf90609c048e41d"], - ["8b96dbae033823141dbb58b652c6f1031144802cd4499e1b7b707eaad8b31dd23792f61fa7020000000752526300515152ffffffff93548e23814b220601f05969a1f5010ef7a9f5138d63831a784ab5a24603282e02000000016affffffff9dfd37f3b352200c5e8ab1c7a421d8938c53bff2e30aa57266b926f19f7dde920000000006006551536551ffffffff0450be9b03000000000653535252ab511a576505000000000963525265525100526389d6a6050000000006ab6a5365516a9c9bc3010000000008656a52ac6552ac5300000000", "526a656a635152", 2, -987330185, "9dee181c0dace90d70af2d2ce151ad54cfd963e0792b05ab7800633b76fb6a7f"], - ["4661474c02159257ab033f526fde4f279e2ee046da0a9a039fbed896c2fc7689a1916c678901000000076300525152006ad9f3080e507e587b4d930a21fe7b96296505ef7941ba7e5af7b452f5e1bd2c7c79e651d800000000002d3fa233014f8a010000000000025352000000000241eab4010000000000000000000000001454c51a51a62db3db97f05f3588cfa73d42fbd8093721f00d6b6d772cbb206795b8d8e866f40245c7fe15a2a7684070b94feb2529eebd452a68c1b69cf6c7a3f6753869ac1e3edc721c62b6d9a54265247f06f5c0f42fef4825caf8bf339b6c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5969b87fa98ee030b76df3080f6fb08e81349470bf6821585e0287d75bfed6572ce290ff82effe36cca8f4f5585c1c0f52dde3aaed30ccb9866d73a942c23bf3f962ab107b4637b2dc76412401f21eb1463ec3e9cc06bbd39826daa1e2a2d716fc78832852f68e9d0116c1ee5a03ea0dd1ee292e5dd074693473fe4ade83e1f02085ad6d2097dbbb9f92b3cd7d9582d421fcb1f2c5f75ed8f1ce332a58b8a630a03017e3ff909b2a0b685438c550056fff47c58dbb05ed7f89bdbd921c6e04c74660a16ed97b9bf809a998ad37d0346fe40fede82c4115904bf3c32850709c6d0b36a07c5bef747752e01d0afbed76c7c62677fcbb70035bb2664064c37b3be8af7e602111ebc5d68384885f73c2b6bb8b8c1860f7b0fafa4566cefa49486411fd6612203025df4f542f6f3b96fe15a6ae3ff297fdce71c04d2040e1313a612eff907bc03030dbd986008f73dd35a849b15c189300b36cc1cf21c03bf815b530a8655538024032ec9a3b69794a6b6d24c2c8ad088b08a11164b2a5bd497c0d00d1910940a5dc203015fbbc5bc2e21ac8eeb9d473b1ea497e7a2929f2cb7d18b140f55d85016c82467400aa84adcfa8be43b064d63a7f2e9eb9194979f42dab8ca50f7c1b0df159d02a1dd1a069b115ab55c6a6e2efbce8e715c566a1d1f4da3326e3f95d53ee033072921722d6634743ef2844a7b4c48edbd539ac91827655f345cbce5c4419e723474c5181c9e16fd8d88d01d854ce9aa2e49929b0d07e862985de0ac424f3d6afcc0a1c0612055be7cbb42acf0188b2072cfea1ad031ca35995aee2c59168a4d9fe6e64c156d46746be4c502d3af0831b87c9c304db9be2b57e3b94d287814b550ccbb4ce93bbb2446def5a111e0aa560daf11ee2d1905267cd7d37e103623a0e5297a09bb95a1c22889ad4e029753ad8c6c552b1f4773728766ce87bbcaaeb3eb1497c494ec61e49d7d5227f59dde516b89df1fdb8a523a3bf7a3b883deb3d8e41f57e74e4baab71cfbf8273e8597d1d97aaba5eaca53687d50704a89b609a24e2bc8e272d897c183407e798bdd9ed6b9ae2ae78692189872b5943ff791b260a21c7edeaa4576f2996ff836ee17d51b976482520293b5dafa7b8f656597b940fc6096d80f6b4e697ed482b9987d55d9651d258e89edc2774487a3ea795d1543edff7eb101960d00ed0401c6e86efd431091baa3c2a505062bdd2ada8d6d552fd1f1a08ced18321b3ca3b6a9bec658e7606bc1a1a5dee044efbb34fdc0c2dd68316f82164cb0f09b56ee4063f7406f2ddab2c12ef14cdf864254d7d9a647c326c256fa4302f1301bfcc030348937a187e071bc62603857e53b0379d613d2d560b83dcd9b678ba8f1fd7df136449ae71b0cf248ddee97a5bf62d00bcb580c0530d4d3d25a615c6cb86cc163180908587c9a57f85ef5412a2572c2283c356464540655da8b0b6ce581f574b1ee2f7d75f99609fa5d6e340e48c2f5199d9ec96bed474f892b3e3f436dc6fe17b68b1ccb58cc259c40b552581139d3abf45395e7d8958f9b169674697ac897ca8fa54ff4c894a5aa4151b154345c043405b26937525aaadc4ab7441b705e32996b484420ae74b08b89f05bc08a70ba8d56ca7cd19a72bf622df23c2f408507b7054bbf48bd177df0436c00d6095f5224d3b8bfe3baa4c1d1b7bbacdc14f1a0070211aafd86e27a99a77dd7dba81fbc48cbaf0a974df2245682dd3027a7587fc531aa57f4a815f95298696f3447bc105a0fa407d5b729684fd7698ebb0bd6469ceb0092affded325e2c50cd501a91c1c6bd95e5d4dc6a5bcf9ac5ff241cbb8fe85add79561ca900d89d4fedee4641f12b27d115d39c187463c78ec27c48433d5bd8e055e005b414e5e1b09f0f2f9410ef2708b5109082a05ce063d0756373bd6c7ea2a23011eb2a34811969512bc76a052b7d06b1a4ca408843aa70fe2582676fc948d79da608eb24465b1716469228772f082ad57edc6a419e723a4e86789b836400c5433829d8e648c10f67dbe384687050094f711dd284ce6b00b7853e6ea9ccfa0c825f9b7ec34cbaac1739107f0e2f19313e3d823635d637c0a4a3666a8be87b32d4993fe6a90e279e56416c3229f8827c2f56ed334893cf4a64a08785220335319fde60c93cac14981aeec7ff543bfc561a81168c203f586c601c4a1719f62a79b4c8ae9e8351535a14a619a9c170a4e5b096e37232c60e254a0f194269729328bb50bea8c6764dd94205dbeffe9568af72057e971eff130a271c618618cc09bd2b9003b50000000000000000f2808104000000001acb1811f3b81029c8b800a39922c372b44a9d992f41127552968ea00125f1c0380b2bfbeea0825b23b2fa5e09e4467e65b0066d7c0cea97a33b99b31dd5dce548aa352a026d8b05bec57312c32ef46b062211a052d75ab3dbe961f4012353ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fba856ff0154b75da19fed0296a5f60d1670e92696e2a25035f8036deae80856cff0823cb1449fb1693a80f61ba9b905694a2225432d692d6de2d815b711d252f7756a11435f0714d98f84493cb0fdcd8bc84bef75d0836a1a5ea7b4a83017398b1d2180bbfd02373af3c97b4d5d30d8a8bf7a94223d0af9122a97174a94f8503232bc1c516551848f755e3ab39bedd33d187dff34e72dedba9ddaeb10257d736032ddfca43aa50e81f3897059684b0ebca2cf7758ab34c3f87eb80b39071c1c96a0a2d441b9281e740dc9a37a290cf262668c0041c73b03c6b0143ec53c39922bdb50f81459b73e7ced760520744727ff0c02a18f2094105cba319572fd3fb5931f1020b603db58c8a7e613b229f620eff888c52bc40851ba99658b948bc48300591ed031a29d3b256be79ffa3166b9553bb4299e169f39ada05bd01f0cb1bac14f50454032b5718f99cc245694c4784ccab6702419bc652e9dec969c9fc4593d2f402b5a20315ca3bd814d57746c8df11152454fb2c1e6990deb42df925b1270c8bbbfbd594021e38f1c1eddc5b15d5458885cb2a0420a47d342869d621bf197db37fb573114208659b79205151bcb6356edaa96d956b11ae58047f6e2fef86b175e1df61a2a794e44f872ef1e5182f65b5aa2cc54c4190f6225a0929c6e6ae8d1192aefbfed195054d1d1e95bbb987c1bf18a49559fb8f8c25d43c6eacacb5ae4169b2137f682bd5363c2492fd8aa0b81ac5648c851ad29bbbd70de841c8953a4371753bb9d70f03d18efabc1100796f294d8f3e9a79605336e3ad21b5a5cf451f6f8e8a97658a543fc3e70dd81a0229594e10dfafc1bc55d7c762f332f8efd1a543aad5c31bc6d43f01e194430d6138c470d15b9342cfd0363d05669fd9b9230327eff2ee8fded5d8be6415c2ffda0e34b3dc0b716050f12437ca340d6cb2fc0eb522f5effb3f15cdb53dcf4875de438c724334ee779d6f4e84dc55b9a38ca7637ccc0a757ba1dbe6ddc8e9b4d98574a58d5187b6aeeb025fcc31f566c15a51ed9cb4c13597f124ff273ba6162c7446a31a31e57a3014ff7aef415bf1c82a389d1022575352baf37d65529e53048c675a1919118e9027238c52006e65b56d43e7dc72a210852e9384de51f0bdd80701456953ae2989e3f8d2c5b13152124d4742039b672b1dacab90317f457d565aa43f1377f0208904f2f32459a2cc763147907fab3a10645b621836fd1ea2971985802da35692611ed1ce504b129c4438160c235882cda25023024615b1e3cac216cf9ab5734dbf9455e47e73a8070c28d6b2e65c1d9b563405089314f5db8c75168376d52f351aa4ff06ee84103e3a04d2513935cd3576af2adc90f80324e184522f0ea71ead49f459109a3a82956dfe11a89636d028234542c0a415654cb723c7f27f379fbb6d1a0a0bafcb114cdd2a45a75d46720d151b1b7395b2c404dcd267ceaca418a78ee1240e9241c9de6ace5b2a40be92d35c59cbcdc8d215523d42e62944441aa33a6c523f8bf97fc70247b341e995bbaa059ae3c5e5951fc6d359ec3db6e6dc46844e952619f3b0ab2a7dc25dba7c82b7c502661ef46ef88a4bb26429f6bfe4d98dca045702f7cdb9351ba4c76d5382b6cfe36d9f5cd4534159204d18c702f5d9adc1297b8a09b3ae0d4ee1bf53dba43cee153723d51a66cb72ada65a2ae5d5da33776b7948bb83023e99548dde3b1455ae3438badf5fd5d55ad04a8b8a35c241bc631911096e863b69ac5f6d402075ca3d86f71d48c488ec77273258da9700e71deef7178d8272f80c6aa1626057e549eee37a4cb2127b6b3854bf69afdd1d94e721f0ec8099756359dff12b3a2097b8a6af16471d2da51b2bf5fc0edeada2fdd118cb9633731a1a1d7432ee6e67737cd71239f1d057f47a65818e211255d4af9350409d45d12fc8d54968b30def32843e9d48a4d479feeb218c056810641cb4d62962a2fca660b37d8432156a5488a4b7bc1878b5c64201686ebcb22af19368706c43904b0927cd322b09e43af0540e2169aa323ce15a39c08de3a188855be4683bf3989cc39d1961cc93fb10890ea2c321b67d3d2d506b4a66fb226d46c368ed5eb2af543a3570d97cf15aac65b52a18ca2188c3db423823dd89577e59c02f2b5fcb887e274a1fa6d62403745ce5a9c544c8220829ea9d66ce036a3db6ac13bbc024dd58007cb2e574abdcd51aeb3ced4114fea6699368a6d4e044a85b602b9e74e692b9c28678913dd8e7fa1289e25f680371e5b5fa98547ea385ea29160dc41f58959db7bbdaa973d9335034db1d5abbbff3387fd47ee8512f86fbf4923c4097d180bfd4a54e81eb044d6380a97de62539ba07a8e12c1c1acd56060d39844ce34ae003974b069f6fc8106ba2a7bef0b2ce0843254a85bc494d8a307b739866ff09", "526353", 1, -939854848, "2b814fd86a37a51ccedc9053c0a1633c06ca4912f7937e25dacb54c838520db1"], - ["a1e293ca028c9a9837e7940a3d8173f05910e7f5fd862021e7d1bbde71f1a2afbf82c21a0700000000026553ffffffffe1380cfb378489113d3b4a093ff18a44191695f8d259d48c4670c5a607159081020000000451acac6a0bbdafae04073dd8000000000004526552ac49c49405000000000263aca6717104000000000963acac6aab006300acf2bdcb0300000000095165ab0052ab52516300000000", "65ac6a6563ac", 1, 1855726952, "99acafe8241d54ce7755466966d471574ad1330e5a8f4bc07ab13b84d3ba6c8d"], - ["51f4743e01cc89a7f7ad46b09faadcec812dc6eca2486c88f70c097e595bdd4685dcd20c9501000000095253ab5200ac536a6affffffff04678fb0040000000000ecccdc040000000007005263536a535144e51a040000000004ab52635340191204000000000300006a5b4d9dea0200000000000000000e6b430400000000cd7ae69b909f6b657000add78d09757d181371225fa62d476c411e82d676a4feda6f17e6f632445c9cf0acc153f049da32272cb3b54f74eef2837b6d8bcd0c4b242940e62437132502eac0995e641ba2f0130bf1c100d8f89ef4f5295b334d25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006143a9cfe4e67e5331155ebbf3c96da5f6c19519cdcd2fb66b75cc97f2ffe13e6acd053712f3b6fabe4b67194925a5e1f812ea8f4f76f7426b808c080bf84e8807b65812010ce63de8fc296b5d823ad9f67b37583e662a035f2c7f5f5ae561ef0f18acc4232e55c0ad176138c19a0bb50bb14e2809da3808c93162e5baa5417903103a2c0de040073ae9e4cdea0ccfbce431f0e096f080a63aa8d4a4a80f4cbe5f020b444f32d1c47f837d3e9b71c726c42d79cf4c5b05e278a3c6d960006699a51e0b1ab0e1c6f2e61af949b2477459a6e7960055b38573a209e5dd5a793f6aef254f2ec0d30602b3aa049881c70d36baf107e34c111ba77c8c4c4f7eea3b9da641e40309e9490db578b65b17889809d2a7d21830920bf83041c5e009c0069547edcac9020f0b6b2d2ec141937c57e8d176193af4ae6f70b18637ee1595fe3377b1141b090204d1b6c0776e20944402e55e6dbff03a6c3c25c5b9c4bdb5869fd6cd69a5b91f031c6dea013b2890e61c6edcb7cda76ea83665ef63f012681739e7d6ba30787ffe03277abe04539e02f659e60b34272489230d316867dec236424fc676ed2f4f9c92d87584e2cae67118b1e326bac86575fca134f7a266a307a5ebbfa67a9d106b6a6a2f791b855e700f125c49c6585a2661d89624deb9370f6d20c690f8ce1723371b1f030fc08315fd4a008593e4a7d8c2c2cf7ff5fed259773ea9e32ea6353a7690bbea54771b1a2fc5df4fb7f1998e23cb8492c7e9b4f147a6bca1751a3760f1751bc0fd41e7aa550c17583dd621068b878574aa28d269983d068405cb4010c3e6fc89f72ed1b54f7f8516c9662577e9eee35aef24fcc5014ffaf25a8fea471bd3e6a4c9e033383a5bfbe77e941a1d6f0f3f1779de6fcd3b265a8acb4a62675b65496d5c13208e747104dbbd1c6af73b446ac5cdb35d7163262633d5049d467efe224ad783d6cbf51c154801765f9a8ce6495f36452662befd3801e1d3f9799749c5dbf3e7397c13ac57f3d6e84748495a02ba64eb64b380154787a10cad4e29ad5354399499dfd5efa542909da7f9cb860804e370948417516c979b7fa7db506f6d792915e857051619c697df43941b6f1d6693ecac81a61a80fa29ad2a0d783874fa3df0010305bd8bb9993a248dad5d29d012a226998183d17f34aca45c7ff271f2c3504b32456514801f30ef819481acea2c2ae0bcee480cc9e57f910e0d0f602a0ebff4d4499b94e9835b7ab5842fb11d40ac8f427755ff21dd2ccfd716bd941098a5c312dd898e837c790df35dbba7808f875bb3b41be555d786aa8a8cfb1e5c517d9474c477c0eec5898666b2f03c42488577dd0f409fb6ded1cf49db14434b1981f74e631d5a0770873bd0981916f5787db954777016c81815e94795dee30681472ef53063a75c80c0dca9559526cb5e424156d0bdc18ee2bdc3bdc58ed59d536fed46530eb26bfa0016aef7da6b16a08d9ff353ee43d4afb359500f018188c2fd43e0fc295f0c5b6763e6a3d174cc983341dafde20f5373fae5c4d439d5e2014714a70f8b7f3d0f40c60183a99c33c09088e6b92621eb377d988b98d633376bcd1e33aaa2c84d49ea1d4aa5f7e7c75d2440b741d9e9f299f8617a0a895c76abf8362cbe982cd45fcaac82e43618e716f94b82424688fe38137d66d6b016db6c971804dee8b9eb547a4c0f148868f2091a9c564d6051409c1463de643a9d48ec8bf535e990e8345e9765ada822d7cdd71ab2370b057ad46af9904257232c49d81fd597ea02c34bd80bd05e9150843a7baccf86b4f7d328c8e615fe777980a2fee52adea9f1453707cc8f4eaac9a5bea6a1a0279ba3a47126b7bd71449e303dae4580592db3f56ed7d93e639b0eb99194df9562849ea66409e4e4f93927bfc161cff4a9b7972b853ab1fc6f4e7777045f92ed560a37cf79c2daa4210d3756f4e84bda0e5a953e7c20457de1d1051c9c7821f420b9ac8e2a0130dffac727542ef4c3f2f6f6400cb6dd09d6549111f72c982b0b2a539bdeb800da648c9b904e9c69308ec1f731f4699a1fb1e7b68464e513af702203783ad0a658d2a3fceb9e5bf178b83a323e9e883a6941405737acdcc98acfdd7f76506ab87afd829cdd584087748096b038edc6732ba5cb99e80b560ecf8d0859b9d87c0aab2e2959c857723c5aa7a5895640e069cf30a12b8fdbf1db00f78583d430bcefef6b8166c92d96ddc6962f99b3f7e2ac7c521c698b8fc7ab64b3d05d7bc063e2b1dcc94063cdbbb1ca25f6b3b909386cdd1f7266391e0000000000000000161cc1020000000079affa3dcf9e8c4e92a80d8bfa9dbae9a4a9d58dd5476de07425ce68a36f96b50b6ecbe6f821c76eae2cd8a155c4f5140ead62e5fd4888f2b725416d2d215e67c585785bca2a17eeb86b717f6e4778974820b9722d431831ac15629ca8e258b600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de998c4488e7ef48debcce399746f1725930a66d09a2b004d64f449f0edc4a690c6dd1b944880b99b0b62adeb0e1d0561ef274c8bdc86509cd1dc4762236ca6847e471ecff9ad3a92114c86a31fae2ea5256459225f618ee7b72c42f69e1d0112fc2cb3a989248514619376b1f74339749e6eda1d4e1988595ba1ed85dbe5b3503253668d90175b15de1696fa1a0081d504e9b9d5ec180599386c6edbcb189f6b00312ab5bd82744eb649e226503f79a495fb5b1903d0946ced0868b7447dba3ccba0b17941c198d563ca61bcb3db5a3e242d9cfb667546a29dfaf170a25201653bdad2b39418bd1a6673b88539b1901f6ddbb4a2dd983a1a4a95f21f6db4998d5ba470303538a22b25a2eecc28e06f2a20cb10a42c534fc8fba5024622108b04bf7d3d6020ab1510d2fbac965a5192d156e515ea43fc349c9843de429100d5cb9bc8fb875022f914c1edf125951b5461e84f0b82edcf1c605703b11f868bfc08ad7f9419a500308f9ecc758a346b506953d63089ef170be888daf98ceff81e2ecdcabd263b0c60320a069750189c99899897831d1491776625bb7dfb494c84ccbadb4efcbd16260a68a9880a09591ce8a70f90b152d5df6904475f8c0ed2886b490319ad3a9bfba4337ae40f3cd0e96b5256f01f39df8bfc8db341f81de8bc450074c9ced9dc4c31d33861350f74210605cc5722a8fe9c296f90c1953387254220973982d5851b2dd6bd09d070a45e40258be687cc8c2365e4784cbfe10449dac7f0be3c514103f33761fbbb8d14634d7d5651def1c4922ecc496db48c5554bad34c70db8d9d4ba0aa1116a7e7c09c74e44e646bd63462faa0f6ad3de445c0a05b2370a72c41c46500260c10b9f82e7cdee3777b7b7d3ca0e97cf0385562d47adbdc7681d7465e05d2f3d4f20f47d9696900e65903682f09bdccdb5ac5dd30abb3912f9ed2d436bfaaee80c074be73ce5ad13f18894fca0087b5fdf328d8e73d939cfe1a6a29d3aa72ca19dc19d651471e4ac028ec099d0e41eabcf8e3118466f529d52ab0842f1b61d88c9598ecae71ed0fac0cf2dc271cd152957282400732ecde26faed564b8949863109d96bc5bcad2c68160fa6a348b780c37f2a9db9b5bcb086688aadfb92533cfddd50e59a6d176cc9b76091313789c56be502f42d90f4a86e4d31513177482d2a6bec33cbb2be3024d72f3d2cf9af625759dfc4225ca82d0b64ee862bf51afdde04f0b5b4c4095b8096b09aa16e83a9cc9b623c0df1ffe35e5d09ab6c1b9e242365a622ec63cbbb01e06a75746122e5346e8f16c8a1c3eda13dbeae5b168171566c2637ecd9ab67ea07e2081128686f7b3fe7cef6bb4cd2a981ad2e9f610c878523ae79aad8bfeb49ec922de3a175cfb250c529dcdfd3082aca565b5730a478d915de6a65e5563b3ce4949799b0ac38287191feb197abcb0e917c70173d7c000ed1fe8b97677c1dd059bbc5dae67ce34b4a7fdb0cd8cc2057e16df82a4d4c0a4502b51c72b34193366a429127a4b138b68abc27208cc7a05348ecea2c921f04fb0b0bb1d9b7956df6ff3b7c022ec3e1dcd8d6ce2852029065e1dc48dd9bf4c4b0e49445b7edbff3b9a74271faeeecb48ca240a9fefd320fb37d91632da573f1669a006512094850d1c009128dd4c99828250435bf87c895595d6a50966750c127266059afa4d99cd718d36c96c85bc74da3fe5bd5e0a7f0d48b450e54409c7322e33d13b1c8f27c2dc9a0f339a7f13bdde4399e58d9289451d5581a7b01b456e0a21e9ab82c2f692e026f750f2859c43bd231c570b23d5fab65ea2fb4632cb70dccb60b97a774ac38e2c001aafbca08e03ba4e659fcfbe425fb9a4ade4978e0c39f497f590d6c7a6a65597f924adf8d7a165dca6eebdf0b5e54efbea040b4b4e386018231115fc087884534f166d2ee1e847728a6bad5c78054aa98e37dd6d2ab1e3a304364a454cecf06f37355d317ed10ec35b313742c5be0098324aef12b51e2df9956768d2974c89cdefaa3caffec6454f228edf74b56675a88663429067f4308252d80e9d6d9bead603b5e46c19ab9eb5366ec962a215a48046fe1ac16557173c5592f45801bab964c7991edfb140670f0903d5f537726f3f25d4731b929944913c86663b36552ad82b05800da2972fc768795169931753f0be221f8471307e61cbbecd0770ca1d7ee39ed88bf4495a8d62894835ddd84784f5ed4b54354ca335718158fd90b206ebadf2b7769163621353f4c3df57532afcdf96a4a2facc1bedc425df0aab021a83e9745475dbd86990432a739cac5623d154439fabbfe8b8d47001075881975915311b4fb9f08b8848c37aca298c3749eda4470ee29290598a9fbe2de10fb6e31c1f77bc3c9e204916cf09cb4659961d5ed66329afa589a11b45f8b88b6d4147d8d0f43f0a", "6a6a00530053", 0, -68433880, "be5aa43ed45a36b3b55b5051427930e1cce17d17c5afb474a3de33e288148e62"], - ["772d123c028eb5803fc214874e5883d6535c70656f4c887128dd08e3444f19051f682fa4a302000000016a4ec5e8964b500b6f2095c8bb5a0b6be9b3c00e6401cad4a757cffba93ab4c3a3df5f804a03000000066aab0053ac6a47e56707031354190200000000056aabab51abbb08c302000000000153354c7204000000000763656aab6300006476699902df36ee000000000000000000000000006a3858752253cf990dd1f072ffa512a04e0238445f76960d04dee1000b35bbf559e96e0c305b4b686d5ca8b1b4935c4508817d005909fe955e27caac536011e79656df3bb9d79f5fd7310e5d4a492f5c0f5ae4723840573ebb93eac09bd5e647000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ed285c127ef4ad219b9bc56e7c4b98f980d33732b05bf4a7d891855aa3e0cb9c569f26d70a9dc1e3da7e2bc6dc7b8f4ce2e0b552afcb7b22077f244fe7d9216667bd12b6744a5618ab7d138b4027074b6722d34a2cb4504b2a1490a067bb44608884ab882731f3a5ab1e65696affbb2a467dacb4f24e6813f27d4986b8b3e490215d1b37f1d0707472c72958b0fb49a6bdd9c89cf86ffedcbedf39838b61b3d47022322e2b1ef6048952524f5e4607d98da6898bc6cf13a5d68c5dd6c2b35a34e030a23c8de0dc1fc5092907e0ec63668ce159bf30ee2cbf5eaabccda58a7f018454c16c6fb426f3d329b3842961ef4b5f2cbed33ac8209f1d178bfd0c368905a023e02253e254389cdbe780a20352164190f0272a0d264056af034f521e217467268d8020408a141005db6c726ecd7a0cd90993b1727d617f61076ab5382d80e6fc9a2640325e28215db7f3b734f9dac2ab2ae752575a863dce81b7ce5c0bcf95d47fa9b300222edbcee38f3ea62168e2bdc3496a9662a3605acfa67f590dfd31693e28d34700209fd46eda242a248564851aa23346d6dfb37f66fd02aee6b39020f6b4e1a7ccdd8f5b5d7d1eb900ca9d44999c9baa8a35c3bbb0958bb3cd301e99cdbd0e08f9a4eaaa51df7c2fac40c3ea16c1e9523756f7c6dc0944124356e4cfb277951c70df9d89d1987f4a8ab9797df96442887465b512843409ca321593cbc6008dc7f5104fb89486e9627ee4feb582099c66e41403a89f1b214feccb3c0638cdab387b31ebc8c9445442f8c1d9f46529367bc37c95a48d9ed7682e331e6bb64beaee46637a5a61fd9ec2331b4d7f2cb68971f9b2ffa4451d0753eee04d977585e630cf5e7cff5b67ba9475a564b4ced32d6808cfa4360f523f246814f1a7d8d3f0012d16216f29793df41d68636691dbf8084a0a46d04ccb5bfdfeb5f0448ed90d1d1216e3e2c138d5f3cf9f452576ac0a131f2b60ae73715fd56d302820878336dff75b30a65e7d7e7ff8108761a14190721bf0330804eee9fc4d41b830edb268bc972edcac8b1c00342afcd8a7c37dbbfc9c088951f8509a516b4990b2bdc1b0d87d556635c24a2f3d1ee60f148c1ccb917cc305c5948ee89d281b58a39b952b1af2ec4d40214d3387d41e9ceac1cc0c1265ddf0d0f05af830fda5c128df3fe754c2e7ace13d6f036593dbfc21e997ce710102dfd416d3ab5f37889679250d31ca7abcb23b96202e92c39eee8aecf9c948eef20e598c6b4bbb2206001855d870c728ae7b82915d84db18ef3000d0814d59d41c8eb384255cdc8779ab25bcb480717c87da009b33f5687ea7e2ac877ea77aa88f1df27d3a8875244dd0b45377832d6aa7812cba4945c400e263f6b8c0e72c86a1073112c862dc6da9c63a0060ec784674e47b0bc6a8316b9e7dae80b06315d1328ea38c5689c5cd112042007fe0f0ae1e20815500943f681174540dc86d2a9f0c91a59c747649cbd57ee74ad85dbd4ddfb3ec64c9986808c964537e0fb7ed58e37b91a29f93add87aeea96a86ae94279b314d63d4a9254e520b954fee41c56e7716b5b39b0e1239471d930f25d7cfdcdb5f0f27fb5ac9da5a971ae96907698eb850b82d984e337612fb015895a4a1b97ed256847a6af8e9f58331a87d41fce1a4fa8cd1f54f05f38ec1aebd592d45293b991ae0caad76f39dd4c19ec839cb807d2edd2e5ffdab73bf60aa6b6c952dabf0968ad8e03b5eeccfbe5894ab8cd568e5bf8a16cbcecb0d6f0e535d938b0615db6c4c4e7b1e3de435272262cabf5e6e07d672668d9a29e31e5d41e3ca60a47f5600c27d566ab73f799c3c3ea9d20dab160e78d70a1a6e02d8ed0683a3af5e8c7e4e12ed4c596696da7dd5d9b41c83ed44c5d1fb18c62f6b1dade67cf72e0d303e65437e30e930806ad7fdfa76cbed3ce0d7f9b2eee6ae787ac66a7b54af8e77149771edb5e21f4f041929840f882916d72b7fc90dbb46c742a9e87912f0bc54d7d2a61c4821a13366837c08eb04678459752525ee73011fb00cb534558123defe0d1aff65a41eb46e7916b055878de3fdb4c56269cec4dc3baf53c80145138fb0098aefd9ea199ed8d6165fe836a861be55fcddd111dc409ee6737888efa8e887d13f58e0982f7f1cf73b8428ed08aeee801ce402d3c8dc6f9eb7aac2c1aed33964ffd0987f49ac2315b337d696ca88c73f1ba780005d4527b88198b81fbdbe16d41877122e826256c10dfb45fd57e2e28299f1c4fa042178dd9d5930fae61d596fdd83fae6db2630cfc2e95531f1b49160e0f03f703000000000000000000000000db154ebd17ad1f21e8b74a221d9828a4294506eeb9ba9c6471183c5f115f450046bba44380df6abe11f0d89c8a42db050f4ae4f9aa256cf34248f6a5dd06ad3be281072ebe19f24ce274dafaeb888f4705db8af7e321c227e4e9b376961af2c40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092b1c5704dcf16203b3fd4899c7d75ccaa38ee2ee32b4b095d2d50a55ddb8de49554abe9091baa0d5a96e9cea71528b9c32ba6dc28738f1dfe56a2d63a7fc6759cfaff5c84e71bbc603cbd196c5343f6884ba000a1806a87f1c263f6a8d8671b30e43ac73d32e53c269636a3c165a6cb7a33374f4f7312e1be07f28aee3d34de03086edc321a55b97580d4e560c295cd68e40ce859a5ac81b2808673ec42f24d1f030da7f38cd6d272a5c5f32cb3b9d672abcc028770b2a7966913cd98f91905a33b0a1b4a942eeeef7b008db4047768a93bfab9b76396e92f80b1d7f0253f102e9f230a0442d99afe7a3925993b26f4a47c2d4fe5f16d02317d57c2fc1b940005bd6a030f90aaf75f567d93eb499026877a552a4ae43fbc1d1de82745a4f0256cbfc8d9030983737a849fcc5370ef563e2607cc6e5cf7b26f7f9166f8a045dd193830379e032869a8b87135f61ddda2a4c4025cc2c3afd7b93fd2a2d96c880352f185f5bda9031c5e3d557dd7abbbfc3b5f3c389432af100546b203effca5f834afc0c8c208fe031fe60c6f522b809a0ee7f1b5bb7ebccb33d33619c51948cec2a8a2c729d22960767c786d98cca7a915d399e7c1923809ab7a69033fd8af171a59246c4f2375ffb9430ee1d6d11c4e17b824da60f75ebc2936260c140f2938c43ec79347751f4c193b8119cb87f9630a897885e2fedad1a7560d27bd4b1de192c76da87c1bd3d8619634a6026e6fcda282b893c71bf1722574ff4fe6a5cfabea345464a24a9c862ce5b6dde45194ec1f17582625bcc4f18610717ecd6461fccae6ce8faabf0b584320b6dd635919557b7e540ec824352b708134186c2da0fbe835fe92db9a90b609699c7d94c50f08cf03ec23dd4a49bf850139e873c87245582c64e6fe2ae0ec1091a24bfc5578b9e009ba04564bed277a5385483d5c5b303f70f455b91ba25c3d8fa1cee0a997cbe8896fbac20a5d895f0cb33a40047414e4babf20d2eada66df6625dd0cef3147cf29b9046057654e36a42c41edf0341a11739562be32f4bed8d722cfd376c84c17871eeb7d1ab59da5e3c7c2ef19eb5d5680e6d2e2646a830edc372d5d0d1fb7b51a44f4cf63603dd444af0191a61f91f69ce70ebd50fd05ad8a1f24bee3f2a3dcac613dbd1a60fa1c721eeaea2ec3bf93b3533ec357f8d0f5a0631b0585913a2a12fd48436fefd3fe2901ec8648ec1db3048d4b4458a4ef3d47ecd99a8717b8a835be85fc769594433b99702047a52d99ef34dc51eceac29c395d619aaeac451b3a3e62e7a85a2700fccbe54bb0e677f0b29299a2f01e58adad107de7c2ea2403672714fde641066b0b1c1a04bcfcb57b74262c68656211e4c3f94823d275afeb097147b17825d5b28d5215c7054d8aae7b07167bbf465e2e5ff87bc6efd6c0d16b872313f355ae7f150d04fdb08475dd6cebf7b1b6e3f41122da6c49463708e3cd3cbdc77b919a45569b63547aef63d83f46e5f2f1102bed100939c986d51a49c55d4239c8e502c3bc947861e954c171c4c032bc7a58ec33059a541ba4c29d4ae8b6843cfc90dd16318417e579a9028028811b68d3eb3c188e0553f0485eb61fe86ba2c15811afa6978fcb81b84ba81fe03f986f7ed0a6238d1823251eb8ac040b9a9a810b530e7e58eae2ecdb184f06bd7992a63fd98c8ab55ef6941f37c229c6541764c52ffc60cc5883962769fde7db50e845105ce159153dfa0ec4fb37f1013463df57e173b6bfe4509b5448f443fe0082da1262494b256e29ee314813e63cfde6dc4f77fce0e3e4fbc13ebb27a4e7d2351c5fc2d0c0b99691ef7e8caedc358c22ee4a6706c983f49675d3397774b560c6831f1631787eceada2318ec38ef4c9f3157be120bb75fc3f7dc51ea8a04930b8e5a7df970cb4757f9a4bd769df4bc005edeb09e9eb6b1b2075ff4334714f878fe1a9d94fce0dee4df71f4acdb8fee01f7c658af90568a9fc407d5b39451cf1ad64ce87ad440689d1b386e0c1f7f03ed0cccb9fb9276850a3218e8965c31265a3c94d07946d6dc5006f0b763b67cb614b8134dede62a7f98abf669d6fa05a2ae69c9a4eb834f9088c4f5365efe5ddfe1d975167cd7d3821047de84a4d218625fb9fd80800f883d04c026fd130f3df60db2ea024fc124380169db30d73d113594de1ae5bfafa20e1585e5bec465792ac42110570ec8a1a1b20f6365de69d2d54bb8f37f06c713d1f1fa1f3f2fe5648815d917203b520aacd984187ab04c8a5fe5a57e83559fb6650c91fe7d76e10c23409ce19fd5ffc7916d598559769368742e899337cd1d437af0acedf9158eb5b6490edb45ebd188f2a9b330909387710982694ead7ae8c3ec217ac16dfea016c406555ab856142e3e9874957bf085a224e8c3f9b6d75dad5e08a2db484ba9963a0e2d8bf324eea04", "6a525152", 0, 1018266003, "700ae3e226e466219e7b2ef9cf74a9748984d22ff74f5d43a7f6bceeafeb8401"], - ["7ddb00cd03b7aacc765775e4f59fa3a53347b74b9730bf7d506c5d0eb8eac2f67c62be378c010000000853ac5265ab520051ffffffffceefa11781f8b2fcbb235981913820c9a2ec140205fbdf9b3c48767629a9ae820200000003ab6aabefb3c6c020904a5906479892d56e060774d8f20cc336e02776f3fa9e4b4bb44efdb19b1f02000000002e4c123204c1fcab020000000008535163acac526a63b54bcc0100000000055251ac006a4fc8ed010000000000582fb90300000000066aab0051ac6500000000", "53", 1, -2008903590, "4c960e20c1d46375e399bd29503b6488cb2b51d0db6ab010f74a503d2a3ef729"], - ["15c4851c04437ad35a6a3c7874c5e2ec24ef79aeef911f43523a388a5c0fa29315e0496d63010000000363006318abfd7d6e7aea4f82427d6f35f25191d0bbf045ca04d0dbb2b9f5a9d270bd4408f4e0e3010000000900ab655151ab5251acffffffff0c9fe60c16f51e358ae132f119afb6eb256663feb659488a5d21e2c0139a720d00000000035251524f8ac2b5a3b34a89fd9469d2a6388e9a148fb44e942ccb4897cf897d49cc354d25c31d6702000000070000636552ab535cf6f6ac0128d9000000000000055165ab65536f1093f801456e3a01000000000000000000000000d2624d64e5881abe9ffbb32d987952c31ccf8e8d3e7a886f5222571f730fb7fec301bbbb675215e3fc123b003a78cb42cfe1e708e1fb6e90bc4afff4898035534292a1d53d6e8a2e043954260280a710fc452a58802b0fb42193bc95aa78164f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a7b5d3e7e9fb1ddf182c44335f3ca6ade70d47ad6273a68f3f4714d85e515863de3ef7ad41b8e068fcaaafed496198b8aa86569f03b37431e1e592d752c3b85c815e4105d96a2732053d9ee8f631dd80ebc36129a2f918bdef1709b024ad0310fed1ef021a5d65c2b5275ca4337a238e6886cdd5314022250835c5c4786a2eb0318c3d6f8fad30d001c41c93f02d30de5cd6c1e7bff349a646729bfc9e1962ad7020fc6501b6c38aa187ad258e68e0d29bf51b3444b05113d4bd1d4d8e6101cac360b03c69d8b73a89fa05eb6ee921bd7acef3cf6adcb69f027adde0df6192910c0af05bbc29a8cdd67adaebb91bfd675858d5bf386c0d7fd7da8931fdd4df12101e4021ab57c973eba01e24f0207bca4f88e28031bf35193af2cc0d9142e7fdc2524ba02266d6cabd9ce4b2b6ecfc25414685cf6bf822e7ac386b005ef8eb4426e458e8b03066e941e8053bd33155a1aa6915b2d3d4dd91817772cbb6ca6b5ac3cd3c8fcff021f16da04bfaf289aa3a2fb998f5742a342153dff341e3edfdd7e95a08f20369c0309daa0265d387ce63da7d1c5d69eb248b5b8d85f69806adfda24f10b5030ec36606012ad9d8e6b557a3018a335118e17126eb978ea617412bc23632ceaf78dbd8536f23d4aadcfceaf447567ee734b1f63ef38bce0500bc5e5d46513ff85e3a170efd88eae3c0a9ef928ebd4584f400db85be8ab36b5fc17d536c8ca39d88e29c2220a2cc6ab10b82017355a6b0123e0214c97c5287c735a02837368c7c59b12e70c26b2b3fa9f6c9dde5bcf064873498c112e965985c09e4f100d8a5b4c188a0b0bc060457c93015db65ce31079e0f76a3cdd10f104b097a49419d21146e0f67798a3af51977587d2a3d41f6d1bc27cb578748cf6e72137ed6435d421125dbf8c6e5c50c689d745dfab2d3cf1fcc10f121764acffa5c44c0299a7317f90af865742647b441a330fdeb2a4b62ef27751660bcda71a8f5f24a3eb207a9e5bd6a282166b8abf232ea10ccc3116d007996077ca9ea597b38df697683e13b3e3fdef019620001cf0ae1192028c0b9d7dfac6b07660700f590d017867b3087b92db1af23dd6f4e3e677d44a5fa174422cde5fc80d1d31e4acdb5011a036ec137e08196278255a6a5c0056d4ceffe60165387abcc73bad6b778842e5baeefa2b67fd2b15a704f2387ed2838b1ab0d5bb1636ddbcab57633fcfceabfb55d5dab9d46fb86476f672a2f8998ca0ede0f1e6cc74670b4b7d77a72344b8faaf04897bbfe32bcaa30f6b7bdf5b01d70b1e5178e59e77adae610fb01c17b54108c84f61ca5483fa9f4918ed06c02850b3c7add334579a333e4491f64e2bda747fb9bc9022d785545caf29fe1087cba29146a41ab2709ec817ad112b315b135686989412598bc526b6b72c21e9a9c54f2a26a5ecb80e0d9da23f7bfa2ce1ce988853d8d852f1119ea782bd0e5856992a842f2e9719787be34a584eec5acf0b9557e80c99153a2999deffe08d9677d907476e6b93859caaf2fa430adbc4032c9491653a625ff4d7fcc40dff10d665d43351b82c2bdca8651ec89eaa2b31c3f4f662210190bdda396de77f4c5a3f642b904af23419ea4a408cb74106063d98e558816a342b97f6f42942428135ce32b604d3b285b4c94b50588b059539594c91c36f14125405fffff2bf58186155a6b1b21c01fa40b29fabfd7bb0d6a9a57dcf734ff7e15c430d01899142b4403e07d771c2d8f9487fa32f8f3c23d13c773a196f09fd29c5cd17f92f6d6ee46df2bf8b6fe061a0706dce46b41d3b9e747d7aeb7ded0f18fad8312971ddc3de5bbaf72945c31210096079149e4f1205437393ca48e3f70e511ed9349f2b17070f3207fbcf444fef8b86f0d170fcbbc21547740e9d5f5727264af9711aea9dae640c1459ae03dbc12b08f44769f79845b40a1d5dcba80807ee7287c6c4fc9cde9e157d5fb3d33917aa1eb76aaf7fbd36766f170e1735edac1122ea677c8c7f384def718f2ace4a47d5fc5e64662f6721cea3acaaf2748d91de39c75def704e70408ba9901a402b182d71c0750384b055a00616d99cfd0d052a80ca8e7aeeb3e25b3889305f0308bf4e8b0dd6cefbcd14291d84dffa17bba29a5275430aaa3178802d89c3741e79e05657d3536340186aaea7940e4d1d768686803cf895e52d6529b91e4752d07d132fb0b76a1a770f6ae2958d69258d6247bc5be00722ac47f559eb205e104a274dfe3d3f14defefb7818860d1ba02f05207f0a6a4fbda568089c1260ae7e1dc32b3a7f462c1de2ee6f4d56a49fb4f4a53f1134b9178eb6f1c1d84f674df1270689888694e458b808162166f2d411d10aa5cad54f24bbadb2310d7781257e5dc26b3b630e28951f0ed06bbf2ab653efee09f92e3d8d3f5f18e15b2ac367b6908ffcfd26ca53160b", "53636365", 2, 382546450, "2500c389fdf94c6e14cc923a814dabad91f376a7a873c3a582ddfb937b62e3d6"], - ["bb91b9b20477dbee99867eafc7abbb386bdddf91912c825f1311e0cd33beca05980c9b49cf000000000552acab00003a7c30089f984d91136e6fa9432c419f14bdd247f61e4254f271d14bab8af1e3045befc9020000000565520063acffffffffc16905ae3cd2a5ce04d7812eae0011b894454ff305aa4bb6fc01f836af56ff980200000003635251ffffffff0d180123afa9277243dbd83e04260dbf2ab3497ba8583b4521b58ca4754241630200000000fbdb89160411bb5405000000000452ab5300524cf305000000000551abac6565f4110704000000000551ac6300ac376d4d0200000000090065ab6a006a5300ac00000000", "0000000052", 3, -56704158, "25cf50fd167c1231fd14d9befd5b7a4b40deff5cd14307432e1f97bf8bcf9318"], - ["7e241b7004ddd45969be779fbdfbfc15eabba52b197d4beac4cd8eff78e0700f0ac9ac09d201000000096aac00ac5353ac6351413df6454fca70a5d3cdbd0139c3d6b0bc13da23651668aa358ebb68fbcad3bb3f542a0700000000095100006aacac005200934e410c757db808288d17385103be9cb0656e9f5dc7b79130e0f559d4824aaca27254f800000000056aacacacacffffffffbc2dabc86ecd1ead0cf22d5378e1887fe4e6849dfc3e118c7a9bde1723dc41880300000006510063655365ffffffff031525dd020000000005acacab52637f0cfd0200000000066565656a5152cef59a020000000009ab6a6a5352006a52ab21ffc2740314feb005000000000000000000000000029e8a5c965af746669a8ccbb6f3bbdd8e40ab1af9179561e3838f9f2c53ed21dac86625278efb2ba834daa4bf65e582d08f460a7d219b7e400a3312a9ea3bb74320eaa8994b5653c64962589501723bf04435da5e3b569f79cc7822e871091400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dcebc4a949ceb144bc2207f3129a5d4f653f70d3046a6679acd23f3d22083b8d220104f89e30b846e234bbfab12bc536885a127697c62809199daff840dcfafce10e14d91b7b041d9828e11d92af5fcc1707d6b3729b8742bfde7801336f8ccdfd78a76ec0c57c517eb8aa63c4eea5ff5eeeb24f8232e1acae2891084d881f2f0206ea7464776b73e57e5ef5669582cb2ecd8bd7d50294c4a6bbc28e2115f3df8f03014920783adc89037448d61f8131a9cfa40d0442fba7b1bd2bd3e9fde1dfe2d60b0ee96380ce132ed43bbf3b2dc81cf69d456b26032d2e1a1e3ed125f49bb5cf6f0c17b3ab4fff901c0efc9b88cd3472a28eb8ce90cce69ec080147f02c5e04ae90202f1b836ca39cbe1acafaac80d4ad6b33c3287c698750dc5f0bb47e1d14ea2aa02052237546eba5bd7bd93c24ee5da333f5731341f57392d176146f0a91474dc93032c750477324d7b650a5bfc6a5d96962c3674c08fccda87b7ae235618762c52c4031341f0c5f7c1186faaf87bdd2237d84db109f943a4dcc55c4c9d8c66e3ded25d0324353ee08093bcf78fc2b8929c7d61337c853cccef3def5cbc3dee5891154fbe2c9dd96a4639561a9a944bd4f4824af457f37b1d97fdf7c869e71eaff1d41d09305b2795af276b05ca3ae7974a0ac9ad82d88886468d978b44950b0e8ab006716887513287ecc8447693a3f3c71935a845e53623efddbff39e1d8d0ed3b387b6f2dbb65ea6d83d9e60200ac574417f38aac38fc1d7ac1bf87dec292a0f70397bd1284d0d1913ccc2a23438a6d86f5c558c5d443254a0905a76cc6fb393bf0415238b511e0b5bd70cbca0c6d2ee2711a23665b0e626ef9614cf2e20cc2e1201f0347085fde046d428062c5a1225966e570c449cbc70219ecd258cc1e798c712b4bdb81309bcfe52596139838d33e7cfdb42386e9e5c5b2218a8bd9eaf168437cd732a54c2eaf0878d66f790b6e7b1564777b035a4962c939e1137d62bfbef10f6ee24a3cec39437d46eb52152af986afe8ed3b2bbc463306c1fd97fdd9f897a4559bd3f98d46272276baa85ae1df9411b79b9472bc9e4db84e56f0f042c6c131af37039c01f71b3b8aa47b0789ee89d9ceecf8d183d249ee29c46b9e44743c3811885c93b23bb1454e380b58788f46431dd5032a7b14d801348c2aca81ac7f6171733841cb6e9b139025056492472577014b8a0b79378b82bd09b430088dd863c6ab71169b58f72259a42e61bdf8bc08188fe8bedab20f60f639f43ad62313e3499122689b54886425a343726cd2590a5ee62d52e6cc066c949088a84a6cce6ec440e03ad06f0949e99986d228dd3ba39455d81ef3f7172d0f457dbe92c5083d5118417d781b120aa35a7f77033938308d1a7c199fc1487a9411e5b1d9e2ff1b78471ffd853f9be8d19a0b0ca2eaffa76e94d2db2eaade5cc9f3f5480cc4fb0bd9f80023a6a9949e0bd8d242f2052c9cab05b784e73242d7ac9e88ff15430c7290bf2dcc15ac09f58f6830035e6d11b8a6531ec97ebde2eb4034e57a5f4cc3f9ef1112260494750920e1a6ff1495da21b9a47516463bf84525e104c78420825037e143638a0b2031dde026b5a92904d0c59c0cf61439e3c808992fd9c6afd1190cd4a7621807929b2c555cb0f63713a4fd1bbacfab1a9a4a210d668a92a461dd6b22d7a285c34918f837d9a5b6248ed2c4d938e456d1a8f47e1b6a9a10ecb50d67d51e4f86e5119dd18c08ec34234b60fe848dca1aa200beba03418a2a7d9e23dd5626a0ce33180562cb9a872e3ecd39cf21bec34167385826a911027d914d11a53a26b90dc18e0ac014f52091d436436fe012e2f34b0e937c04c962c80cdc1ed88b183d876e10e35e5500a3043a59fda68e5394330908dbef26515b80ae711146994df8f6b33836ba44829279ccb3ef8ae3c5199e971340302aa67a76964d6c3899fa09ab179a032b8cc4a9ce4b135d1dbde1f6380afa4f5be7f949fde638eb48f680438333eb04f8b55ea69eb575e6819adb84328d3bb3757e4e94dae3516d8b9ce457bcbbbd28265117a7a79bea82e268c651df22d7744fe76e7da14d49c1f2477652724166b3db451f52554aec1245f6dad06b5320b9af287207e4a2d503857b7c0fe62541790a3664790e1826e2fbadf0a88d7c41aef347fc96248c924e4482ecdd64b2dba3015e166d183050c79aebaf7a43add5daed42473e69d675d07f644895b63260619db4dea7003a2c12f38827b181f30628254b94b59887756de03e3f188a6e3b5db249d90df5fa7b03106ff5e308d0500000000000000000000000081ac3cb29b94dde9452e1a25caa9de17c04e9fc751d8ced86c601bbfc4ffb44570c22a6179ea7baa3bb47e7be898b5858245025e58e081d956c9c661875bddbba2abeadb4e57d93163c3567a0de7114487e146ecf262b896b998fcf0d523693a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007adc2ecca302d8f52ae021cbed6f0470bcd68c29a79e1f20642b5ffa7040448fc7e8e63cea84df67a417451d3cfb1a025aa877d47e7fba661f8cb70aa67cf1716da3f65d35fda909d2e09c018a5eda4f0094820a6c29fa1399ae50827b11aa2e142a68184b38416447aab7c8eb2048c615bf4390e390efc05bf15a95b545f66c021de4bb81034cf0b4ab292fbdcdad6444b6b7cf2278d3f07b6e2a88d0555bfa210207e675dc610b680ffb911b7be7e48c7e4bbc1596759d5f831aca4a040caaa65f0a1ac24cd7806fc9290d99553deeadcc21753555c644b63b682cc36fda5bbc5f690a2403b8c0df8835b2f8df6768ce46b90c43876fdf3871dbc51878f72cae608b02124b75b93b197e9ad8c22b637a222878fe9c85333b2fd0847cb8806d9ca86b9802167e173ce84eb215a713001a7d04743e3bef23c0fc8a5429e77daedd5ff83f99020050a8327bab6fab26b03de06f5c9f7a9c489f6b925b1060db630916f524dd2e02000654fe4791265026d045fc91cfb3a796ad27876c6d031185edc1365921d4bf022e8ad88212b92d213ffa58d6443020e55090efdf95a88b7a2657521d8c8bc50e3b6874c9bdfbaba962f85965913c7a4da9a004056f6458bd80457c1fe00918c94a307805770df8b0c503a3d65683ae0c8b8ca0d37a54ab8e26f98f76c137878879ac7179621a84354d4a950c6bb08ade766779919e2e16e11c28c71d714450c9c93d886b19ae7fad9775351a6d173af242b87c0b587def8766e82b96ce16a72ae88a2b783306a740ca6d58b9cfc1a46df6eca672cf545a4ec8dc0cb4be5bff91c3e5bf61c485e1d4241095cc74f1baaaa41cde9adf10a7957b9f27362d8f1df6430a478c65fa8a5f61ed34bad83c7028305e40e5d208d379186c6fe90fcae9d497829b5c078893ddd49619f2fb8eaaa48c1bade05fbafc050a00b678a802197e43eca6c4980b900d72da697006ff34289e79e2b771cd24488e9e74935acf4f3451b43c84f5efc35292cd5fc8eab83693d09a1bf2590b2979fee8bb006a17f1a209f4fe99ba2d953389118d262bc7fddefbc6736a8843718f362b5cb4bb733ca1fea2a56d5df376c80403995ee2b3593682c566e3084ebffa8649d68b33254faeb7d979c902b91bec3008ed3563d6b5b4ba2197d7c1f39f94a54a2b7ad34833ef0b85894472e1da3c13f5802c1321c5da69a63deca16bf0bd625f66c9a935412c6af313c9a7442e70052f260e038a0d9650567acf3cafd2a226abfaf76ba49585d8aa189c380ae3dee67d72dd43d62441b26d08f444b0a4445887a0f4c3e6360483cdfbd9a3d4cc2001c81d74ea396103ec22c7f16657d889c156c5bed4bf844b3eef6f2a843072c758f64be72e9b9c9180dae87883c79290a5d26fd271d69c1d4b133d5f39bb754b2af4741aafe09e999a7ae2c6c206ab5447b196dda8cadb9b7d2f7eb06e476d7622c8accd43be28d33a20fa77dab28bc9403cba376c6f7fcddc4bb656563bdc3bf64934935ed7d925a7725661293865f7df7bd09c7346654c2714e2468d89d4510a5a7d7cacdec445880e0c03a83917a64d6adc766f4144d1ec47e95534693e9d50b9ce302975cc6a54fbd28a026e3a355cfc3c0cb626d57ed5244fe3434b71f08d3475ed295bace0b8ce73e8f1f47ba6ae7a545d4f16c0ec289597618a096207d63b3adb68728ffc7e503c7bb785a0fc7ced68aa1d34a58ee495ba9be655b5dea6cce045a26caf2a7cec703ccd5ca170e9fb736ff4b4811c03877d90fecb44dfc7d68d5a6e989a1c0c03caeccfc80afda46a25ce6252bfc7f0827b275d7d3b45b53116c2fc9e93ff898c77323731ed0c6e2543de1473175a501e658fda7c801e6306cb5b7856845453bd43b698c217e4e2150be3e1de7335609d11c1477591c37b3b2fe80f5b41123a5500bc7f183fe96e150d04e8654b7b6fdc4e7904156d4fd12f61e54ebef5f1fbb61e58ac2c89a4f55f9f743b3337fc43dedbab699ba418346769d60b3ad9e5989d23aa92d40870ff781d0bba2c868599f1a2079f3ae2dfd761bca7fef65effc6a780d624eb25db3936c4f740bfd6d27e2ef5aa2d4a3eaa59a5c7fe24cfdcf5d8993b689445dff86db9e7a6d3cfffc363411a867ffd57adc776e42cac589932757f6d4db90f1428557437fd9697a5d0b4fefbcbb98820b242a689e5adaae10ad99e0f6dc27659b82e2ad69dd10a844bb6a34a3e32c49b9a336674725ff9385983668e6d59ea34469ac8e5c3bc33378d20042580e022a50a7b3082fbbe43e17eaded73701e02000000000000000000000000ca8a2ffa00f5098fb1f1351f3977ad2ff3dd2c2ad32785f6d829eeeadef4d936112dc2a3c6ca6cae07bd206c54b82c79c4b3ccc6193a245dd060a389198dec1f2ea6db1b475db8a9248c313d1d964f79d1d29afbc2e8eb013b4cc8fe0fe496cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fcac7fa49fc34c7eb7275e7bac7d7c74064de784826e413ffbb6c5c045b28a992fc252dcd14f242c3dec56c16addff19e0db8d8942ac8fa70f390f44568282067a5e6269a227f61c0fd9ad185a8ea537dfbfe7949251be78bbfd92fbed9a9c0514142d8224a491afcdf3e931b8f3bdb1d02529076e96ec08dab6354def0b2080222756d600f13baccb593d57079fd241bb1bc6cee4005075da70eae357fa3be1e030ce583b1a76376d0ffc1c656b56f582af9cc7c9a75554e27fd458589fdf4be030b09ed4cc4cf97fc84517f40f735485896cd41ae89cd61a5fee3123574f835185e0dfd2ebf9a0aabf440e85493ec64666903c09461933c78137816918b6d133220022b2bb35f8dca3fa547c70a39abedd1a22977b2a4448011efbba04276e63d57280308547f72a8e4ca8ef2843c05514507e982eea7565e80991978b60d3df57392a30300e87b0d74619605f03f62743ea723a9397fd28c043fb798f541599b92a9153f0314f39027db745e3fb7063da8904a74d24e561e882e464b0dd20f990912365eee0212016bd95f7352fcf2c6e117e2742c992f07879b63e8cd5d579aecdf4d004e8306170ef47950e0394df0b4f77e16970275dfcb3f78e53f63e3315611163ed874a6dfd3ef688ab985a53d569cea26b89a62774dd8c5c52e2c2c2fbddd04b683dd30091e7c3f0560ba66de10d8780e35230c9560b32343a111dfd6c52c74fa9e70c007ba0d3d7d76960428748105aad11a5c18c376383ec7148a3e70b12cfa50a6c960c89fb7000e6f22d11083a47427c23eda5f7098b4bb041a9c7ca4ec63897270d8804ac27803fc584ad1ea535192f925dae90ecd97b21465f92dd482576492222c63bd47402a7dca1313a6aa3579a4cad1079b0000e2489e1ede1fbbf1a1294600836b60ca080d28964f0c857c8973e9625a40eef2063d2f0621b1cbc385c0aab8fb6ad780d0afd01e61b603163778fe75e15eac12d0805f9fcdfdccae2d641f3e65def4a8a9f5309d5bf10c4ab9580599a524590dfae5cc396a1556ba2835727541b083b06c6523faa3aa57528b81bbfbd0ef588cbc502123f396accce66a4a6ad86886eb9fe2cef12cf7853c668e1befb46e9514bd0205d49b6a248fac6755b51a320beef815797eb4927ca03df907eaf7b4534e3184792092ad18a1de61a99dc912ae442c19ce062688edf4d006dd03518f0cd13d8b898537ca78b2a6ef3599c166c6e49e639f2c684430a599f28edc096fdd1018c694558b2e5db12266f47c3882dcbe8712b1ee9a5d4680fbcf102dea1dbfba912a55c1da85aec6b9cdda321a293e01b7f7db858370f979e96cafd6fc4a9444b11c3b3cfeab8e30b9d8de06fb3b2b9865c1358c93c82070d29bd1dee1e13ea70300728b7bf739f82693877de75ee6893ef170cda65c88618678de985a9d15af7e2a31d2974dca46a0c6fa36c0a5579efbf2e514d9713e5c46e6635f3134f6ecd5c3bca9cc230c1caaae02e7d1536287887b546c1522d51c16f5645a6dd74a73b3b5b8fed47cb4dbbd182f1fc20a5fcd342a299779dde5c82fd2a4c33a6ad78917f2e1e9772233735cb27773568adea50b1caaee0b34327d08fa61cd5f90fc9792a1fb0fb7a827573c21fa674343b32f281c9067750479b58a80e1d878448883009b33b723a7930031bda87d680ed3c7ad49726cb0bb47e597ba358f99ac87fb4f231c8587ffe7c2a0f014aa0b7074b99bbf8dd8ccddebd3c352891515215e6c7b97e4720f98369d7371959dd23f25eb4cad950091f6f2bb1fa71041a2947d661bbf2f7024ca16c056c6f2f297f8eaadcae3fa7e2f0ba3c1211aa6476ca09f609464566784624f1a9848ec20ed32bd107eb87872c9dcf96a8778bb65649794bd795ef5dca040a46df7ad98663db173735369cd55dd9f3d6418b4598cdeafc07581db4160bea033af55b7d33231c3b8146917f8d6ac2124652dea405ec3e75cca5341d9d99b9f49ce28efda6bfc3e071a78b73a11e9a0a33cfb7e6d7e02e86dc72a104fb398ec4d6588f57138987b73d5f1727acb5d906a8eebc24bd0be39f5262ea8be0c646625b706b8be502f6543937ec816c152e260405b3deaefeac746a631f4db4e25a7ebf0216f0b4474bb16d83494f723876b2c417fc71804ca3ca2b1c7f1333322aeca4456c59738fa057855d7a2ea5ed2fec33f9c3e989f2ad5d68ab3536f9d154682e776d5c6c916da0601588fc681c37a848b126883572d15d7c4c9bfb44a9ad43951c0c01620286eb89716e75dfa3ba878f72efb2a42d376f61906bd9ef23a48353da5c611f6fb6dd885a5c8239381bacaee8afe555227fedee62cf336d42620a291e74aecc0ed4f2afca1ffc54e5c6a109a835fb7f59b5d93fa6092e2e95fdd8e11f404f8efdf76646095e1b83ef5d35f1ee80d120c", "635263515152", 2, 1521598844, "63f17a162b529a91227a7d5495fecebc3d0ab437462eb4a8bb8820797220c8af"], - ["1426f2f30135d87812317afe89df6eddfd56795680dce37192b4df7460001a5822a11903aa0300000000ffffffff02192681050000000000e1bad90500000000056aab516551b005ed06", "acacac6a65516a65", 0, 176944165, "ce3be5f02499dccd44fa367ae3ccb075c2e958351f61ad9f7cc6d86e8b2d3d21"], - ["b01ab05c038ab68e6776c73e9de8ad9cc51cf6ef93ef47fcec2098f202676d2c96b71970e7030000000700655200acabab02e25fc6add75d2b7f7c2430db84a53e5d3121d805c9a13e7037a5e42c63fecb2d6634b101000000016affffffff9bb6ff47d0b5c7b2c370ff5dcab03328a225eceb3589e1ac6aa55e506e7683320100000004516551abffffffff0492c4db000000000005655353636af49470000000000007656a520051006a82436e05000000000653ac63ac635315387f01000000000351515285beb87e00", "635353526a52ac", 1, 1746047635, "cc3c7ef736f9ccc3fc6c6a2376217e75621d68c7e5f8a5f0ae7ecd2db692a291"], - ["0baba3b00365ea480b3e62d6fb80fc9ceec16020a907f0bda1974f10d6efa2dc4f6c2a6a2302000000080065525100ac5253ffffffff59ea0f0dde3aeb915e95cedde060f3a080daa4ed45f52638527a9d6eb02523df0100000000ffffffff3ddd9d57929e43ad0bdf8dc4c110144bc9e61be071314de4390f88f8fafc7ef50000000008655100ac65510000ffffffff04cd1e5e000000000006ac6a656a526563b0e702000000000865630000ab6500512ff1a00100000000086a6a516a52acac001ae4e6010000000007656352ab53ab6500000000", "ac5153ac52535200", 2, 805302827, "3e0d21e1c255fb5827183b669946fd786aa206a66101f8e86f2ec762ea9c833d"], - ["a3f0c44d032974b876a5484ffec7a600089c32847471911008e7a2a092138300f9f701afac0300000002ac65ffffffffd7cd6252f3424b9221e1b7daf14e153301460b3ae0b6da5f2b5410b596eb919e0300000004650063abffffffff67bdbebb64d2dae02fa1837342d3c7daaa20b8bcdcdd64a0fa5117785196b19603000000085100536a5251656343ec53e1049dc23e00000000000100020ce6020000000005636352526a10a6f6040000000009ab00516363abac63abd76dd0000000000006526a005200ac0000000003000000000000000006eae60500000000c35d50a1dbf8d0ea78b3002a39164408de2c40782a41b4be06d67eef33f401a750ecbb38a349c9f3bf890fdc661deb496be431b015a0e43276a9487976403c1d4e60cf1c29001b4d53fcf110f11fd1f575aeb20388d66710bbd5548b4a230fb3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d5c7a3686214b61536a735e3ae319f732d5756dc9330b594bd0d4ca05e852490bd79ee8dd6a02edaa642e894eb8fed920520e9d62544c8e59c15184b14794b1cfffdd9cd356f8f510c4a0d06361758932c160e2365fb7d300819bc31fc857d8bc5f2e7942c8b01d4ee869acb81cff8b5c1c03648e89655265c706bd038d1226022285ac367597d10941b3c6cc75a2204a8ccef09eabc4ed848a061595ab580d1d03176c83a1738ab7acc47cda819dea0bcda82d677505ebe0d35852fdf201db1e3e0a25c7b609efc7db6b6fb7e6d70b228ba974fb5ecd0ae1d2aff38fc0475846d34c11d2f540622258bed6180843fde407db07aea2292713df0bd155b050cf1300f2030a9f20fda0889b4aeb8ab60654be996a5de769e59a72033c40890d1c012437430206266258510d889da1cf7e37534f6281aacbec1677040061551471eaffdf80f60201c698f9fa9dd6cbfec167c60bb54f3a4ef9f02a822d68c9dcfa78a66320d53003110ea432c9c269d4f316f027d9fede1aa1da9e9e78a6bda4a7466b9b84044fab0212b5dcc0e8b1632900d334d8a91b0539a7b4b9d2415c4c30cf37417f423753a34a61116bbd2d2c505f83d725525ee5e1d9c61935329074505579d5093ae241b34bc49fc9defb02f079e184d9d9b27e53fc08dffda79bb089b8d9ebae88a068d287209e8667e4e5d5c112e9bdd2b53d00ca7bf22493e89f2023d46897f66b88a03d7bfd6cb47f4a88e2d6e3fba93c52d92158c6a736adcde1f5dc851ee1c43784309fac45771ab715f771688f7ed5baf93e1e7137f51490ba61c90b713d5e09b0db92ec02375660f06c921cb3d0bbeb67ec3f63c659f2fa278adfd874d3db7b21f800235af687e8e64890baab73c09be3891c71c12efeb1fb9cc7f2c470cf245df4db2c3eed7d8c1c4d0a8baa84916eebc21f1b27c439507d96e45f9591071737418f3b25fa2648286426fb1dd3645f7ca15c3c38170ba6ef26e4b0686c55b7b964fb02958c58abb07e895be6ac7b0d33dd208180066bbd4d4518a2a097c781578c1a6bb0f1b818312e07f4c8ffb077ce3a608c476a1b8a8945ad61bf5e76b9fe54eb09d5b701afd32eccbcc7e2fd32d744de21b8d8cbe3e34c4950df85b1a1567c170297b5f2210255d21c4a892dfb123eb565635870894781376a19e097f18069e24356eac6bd7519c3115bc72ab6e37e67f431d1796e9aec2db1a7a0db1e207804ceb204259f488c23b1c6e759d6773de99a73660828a41b8ab661c7e4dcaaf14909050c51e53e6d9264803fe1bf5dcb571cc318b6d1b8e5ab4756da60810977cb3d773407d5230c710257c390f89b53d42d3509fc23eb6889c03f09883d84b2582c364b46eee43d275c5dc2cd28fdea71b1bb9499633b9cb288cede902402cc82be41942c799517a52d061242d9cb6cd94cd472458fada2f7d7a6893d508fa90030155d9385f97d5654cdf093ddd43011e6296136cc27443002371d1a623c0c6ea471bfd72502ea4a58bca895c52a1547495ba9591f9329b1feffb89f7d7cb2bfaea47c38a27b03b888f5ac4fb3999fe1fba8e193d4dda49a94c601af0f68c7a54ccb9a3fd555b97fb7e5f8e9933363a353069bf89ce0beecdd467d00988038466f904aa50536a05a9124e3a4f2b522d8e5dbd0ae8e17a9a96ec55acdc9dbaf8d26ec19d25446fb8426737a4546c0783f074b0a5081d00e11d41b36fb456092ffebc90dfcafe530ea2b45a7cf3f3fa02a73b92bb9ef547c8f473554fb72ff3af43ca010eff18a3103aff9071e93b6f1f8d57c7fcb43a972a22e4ffc39c7524c29bcb6aba0e58693eb647098bcf5089fed1eb68256f5d6e99aa056597fff3e34211d1069990080da81b82e83a8fa65751bf62be909afe2df4a2ca1b9c7790e8c6174433b290f6ed87d242592992b14e154e1f00f70b2ee542c0b729d71f96e59f1c291f2e200d6659f484159f2375b4b8d5c0da767ebbaebbbd4480616e9128e9bf78b3cf32c4b089f1f58466b48487c6ba3fbd50db344535ff5579e543a01b85eaef12541959b0f0884569739ea0b5fe2e8969144155e74228c99c94dac086415e816bcb447b9ff90e78877470714ebfaab1b33aeb1eb0e4c219d3ae310fe05e7aa845573cf9e9789129418369ba8fb0abf93f9b1a809b3723c1f16f2dc9120e97a79c1446930afbe35ec61c78094ce08ddc6ae026e02936ae8fcecc65ed67008f1bf15f94153ac48f97f0939c74b1a4863a20f64f6f68f1b1b3761b6fe9abec5a3fe3981d7071b5b283f8496c29ade56000000000000000090f59b00000000006f912d02e809f35b6374eed8179e7107cd0db095e1221634eebcd0636f2b57b2f65936a4cfafa6b48f31d6a37eac6af49e147d51825fa541457caa9962f3c587e31872bca14d0a8354be6017725878e28392b950d90789389b8de1948374f4670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000062b5776ed34909d6e222f3b45053d6fcfea2dc32b01028e578164a11127d20fb546883c4b77a13e454ec3d6970ab9bc004ffda47446aaba8ed1fa86890d80e7baba6dd368e6afa10cd0e90e310c0905c6c6279ec938725d753d704066d542fc7af9e1c0057c0782c89da6ac1a6f869056569fc77f666e1fa343be5255389c00c0310d4277f937b1be2cc8e3a865d03ba8da36a9fdabda51b9f8e168d4a9ffd2fb403152e0499e58ca8ca7b02c323a87baceff9c28cc98402ad6d16dbccc7c31344810b2366e9695b3104e70a92ba579caef31ec084bda848198a8d2033967f9d81857e18899e00b8d154abedfeebad0d1e8b524fd26822ad55ea285495756da1942625032221f4f9587e8bb182d861781215d55d4e2bf7504e8d76fffd258a6bad39abc30312d8101f01484477f9163d8f2cec0c871f7b124cf32aec1bfdf738a9f9be8b5003114d614f04bc0695f0ab265f2433a49d939aa28eacd936b0e50db7a4d7f96c81021630e10f5bd75520625b27ea1f1410b1d62a5182846839525d0443a2128048b903219e058f22321f63e63874a332f8f411ad2a5fb75d14a03311f94041a8d1c9cbfe83fa04134b03cc5920f8a0914dca283cb9959f68c56526a7794a877d5d4438fe6c543d1a507b3fd19029fc683bf1ba61b6fde978ef18726f760368ddb454487fa4e8539ce7c6b6013657112d70a05675039310d7de249f9bb6ffadfcaee24452dc068f8b8615ee5440e625c2989892c2ea467066a6c9edfc6e0a94a66ecca3938fddc97555a23ab342f4a593ed295e1c3f71386eda66c95653b92fa780f9b7af4c5f5b189e2f9830815b045a11199a6961a39806cf71a409a7bf65b2223318cc76383a9fad0d171b21bef099b2d6aa78af24ad33e83d0cc47307abfc91a235e79161da3062977f61415ddd7b8d560f3c39c5cfa4b59f40b2b842f2d3ce7ad9532e4016293ca6d9524bf3fd04eedc02eb953aabc8224c6b7e41ce05a05683f19fb7b6cf912c3ae20e2a2d268607f43c69db9fe3ca3be731a97f558db80b973a787c9b575372bd8e42772367c72e6c587443cf22e7979f8c16ba31e27befcb2bdf3165f12fd227297805d4353de12f2fb8203cfe248718ae15a2b10e62b30c433ed9e2b88feba77fab0bc1ce548eb10326def1b6874340caa51a887e4b35e8c1937e8e9e12d3fb9c98804827927b4c0b22a801ae22c84048a2974cdabd9f886b798d34d1a2d6aef6ec4eaecff15374b936e9c42615ed6aa247f09835b891d3eea838deaced79a7a94453891c0262956842d5731edc9f1b44d5000ed5834cf3dfa7f8608f4cf897fc96361bcf3eb2b8b16f6d52ea0ee5b3a2bf7e34e58ad658f7f5967d710e8dffcb86476bec4cd9a9eb7c5d6427396d3f2274cdc4b55bd52fb22b26cdd5e8f711a8413c68a1dcd526c350b8b87427dcf8220760322ec42661ebf5be74a5d3a8cea81d351c4200b49de1ddc4dcc0437961f489b48ad9dba5ffb23330b9f5cc52a514b1fcf567a4eebc386f5fc6c112ec8d4abcf7121d20da07c047226dd0c96c07a613e11d9f000dcee6f45b59679c33c3efb21edc85e00ad0316e3666e6b47f75b16bc3066721327f707992133c692ab7ee0d75e28ff8488b22d11817d943bc8aec59333efd71dfbef3f47580b2086dc7c15cde8750d2227582f865b059c51c9b497e1dea6611fa676074d2f24eae523069e19c76408225dbd4f845a80ee408daafebdd8fdb74a9bd71f5d6895f9b30daa45492b536618b6d35ffcb3fc8dcb58451dedd04e755f7a77daf458f33fbd6895a253bab7d1adf4c34ff04cc5f288ff46e80711bb3a693411064bab61db7ce06c868728ad07828293de5bf54971cb45b14a8feee5c3e8730257a477d1b72dfcd9f19b9e1fd6910209a7dcfb27526f013c7e24d05a13db8e457dbc34f8f69b5989a59e0fed4625ad2ca396b7b17b574989b3c2831e7fcba1c8416f3d70fbd443e4ed784bae456de96894833e19fd7ebb7645d08ded5ea0b890667ca365ac0d6dc2fa077552669b73ba32d857fb31c3aaf572361de207ad288dc47890184d9d9177faa6e78b565437363148b4c24b921f0d261b51502028361899d2ef38d38348420b38d2a9a43ea10b06211b4c9ec3bfa8a850198216ff1fbb164625770a5499e10e414f0b129efd30f31852fd17f394f14572a9e16a597a03266333dcb5f6b65998ab941d5c5bee3c42f08cda26a6cd18370bcefe0a2eb88d9301f3207cd164e647f4999649a15c1e1b615978ea3d0f0ebb5e544d3165e99a98f3829e2d20200000000000000000000000034df100919f61700b17b228533e590ca9767096d169d10817a230ac12907622ca544af6b980d60d0359d611673d3f1ba9529ce89f540896140b6bcffd6d245a96a0aa99ca3eed3b76d57852190e9ddd32ed2fcc03525e7d06d5b73f57c297fe4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b48f1deba0511c13112e53974a0c2aeb74034a25d942bc94d7f50d2f1e1976f432a12b65490fff3a549a1d6bafb49a44b3fb139b53c736a83ad044b31d66edab01304158f444a878395422fc45ffaf9f1d7eeb2f9032207ed2fa356dee646706d062c31c56dde517b9ae4c545b9a489c53d6260dbdc519e20283933777ae9090317de306b8e4fdb06d5a0f7ed16e61863346849023f930ae242ee4dd3e4ef1ec80309afbf0c6a70fdf8772c7bd5c282805cc519a6d7d02d024186d8abeb2a93bab20a11a9721b9470c0065367af9bc8421f9814035d1842bc8471842cf47d645021570a18a57ada7dde903a172649a707c391487fdc93676f24f1b339c02fd7fc5fe40221ea0deda6470a48f25c9da023033d06e571ec77bdc1622306eb96df4cf9a884022db81739af9ef821d2e45466a4e1577e398378195f0fc9d7593daf3a1db77772030b29215d6675d626075371b00d0732b6563309390cc0724b569ccd2bd54a5e54022385e9f4af202d08c361534ee20e39c215614e2dd28bbd7aaa8ce832a1691f1803129e478707f72e107a6dbdbca3b9941175d0b1d0c0687170630257bb59c080fe7983859d360627be9ff00279606c5c1e553d487ad35f6823e8838df88f72ede470db03cdbd3825b8777a94fe1c7ecaef15f8ad2c9c8e6735fb43d5f783a6b362b11388a05373bab035b02a458809ab42859756ce1af212d2081e328204971191374f121f9e668ed1d9094a6462c5d3cf864d9b1a223f9c6d696c8f0c37246d670605a7b1683494a02213c9515d80b7f78da883b1ee27e041e7c1c95a8d69fd3d0d1a9f1c603f3f454cfe8cc4cd1b1a26049c8a3ed98b418c968a4777005c7c5ec50c533951d5651bb0e412b4bc7b34adfcc7a854c041e9c2515dec8b13bd6e2ee2a5de2f4df9213aa64683c86c3e931163402856b54a5f3c560e522d466fa798d735fb80489f2ef9c6191ab54423d06b2b905b0b7e3b13af9b83265a9a23e844484059af55716f24588191376c664634e718c4b7f8ead80216243e09783907e35b7b27b7ddefeef3b10ce309896665ed0e7669069bbc5cee661ef0ee60eee9545396e5ce27b87c942c9a01d028d684bc492289af6d1f0a7252ca96731a15ffbc3f1825bc864eb37123044e3cd1bf4f91dba9583f53d5d2d3d586b45c884c35a40edc855d58331882aa11812e0420868ef86e607f1aeba180342c30d38b136b69eae915612279cc22f8e48ffd81d57c013e35dfec5b39c7a0d2730d77b4593aebb21bffaf53313b93663da7cdf12a52f586bf489df4c2e1fe2c178b035a25017f4b85c998c57849aaa2b05f5f299f1ea6693769b255eb1a433e3eeacc6374c0279dbef68ef28ba6af70f32e2d6c8bcbff7991dee116393dc4aeaffbfaac02091ff659bd24bdb129c86d3cb14ee4c263ad585b6c0b670dca0a1e3e40c560161f9571cc136d2a94e77b432f4f8e0cbb8dc1fd2cca0b26b970a56d30dfc6852d03d5472e75bd718d346fe3b30d6b85066ebc8de3b77077687f9cc81a211fd11b27095f8e0627fd6143ce1fb8c8595cc1bdbe217a2969b0c3601152dc6213c0108fb8ebdfd9dec2d8803cbe70ee78f59d7c8b9aea03b98e86f0fd630e348589f151f9e08e1151a8be249e01dcf4094fe5c5e6d81ce3b643f9a79661c1873ec81830273f37e1ab5ac2e521987385e529861ceb74bee5da581cab9215edaeb920c6515dbb048052f087794b229fe664e657af336bb948c006329bb78ef4da135d9f353cd3df1a6a02b5ff906197cc3f548bbeaecb3fc6d81744cd0a0ea096434461d8cb248677ce3c5981a4fcc3ed75ff2bd411607d099844b397776924d1c8419f7fc4307c19fc5154db427deee3c636b6ba69a71fd3e222a6a04c0e44b10ba2ad165c6c6e9171aa80e08537714ccb9b1f4af1522d0d5307e52470c828dc3eba9897ffd1b8250b9dbd4d4c69a9a1cf4e9cfc9ec606e187e6ed680724da200ceacd323d37e317bfaa0dad7809977a3e07a7adeeeca73bc70efab8f7965612b398082ab17c5b675e4453fa23f31766a1c41ba064c47b9d57a38aac4927f44493659057559acf6ae501619bd6b3a41ccdf7d5c7b6b2603b2802e85d42344531033ab7cb3935638708d960770164fa35f8c5c42191ef94a9ae70a8c63cd3c2579712590a733956f6abd357b6d05571bd2c50ff4b509996d979ec36cf21f7990798ef26c1ff2bf837114bd33137bae17300ae6880e19041ca60b0c7076ee62511b718705b9e3e15bef39da9f698e43ebeaae708196930827557fe9a708a31ba1fef54d43fa96079a4331fc36855b7c577e2db2a06681dd7fd54fbc1b945faef66956ecfa47872663795732ea5ddedb87bcab47030f2ff8972c89f8ef491f0f72f0d5237924a631bc9f9b1d16554938b88d543130f3c4f04", "5353656365526300", 1, 388989590, "de7c96f96bd2b012b875e94b591e4954b2513a5b487f239593309ad900f46f6f"], - ["b470bf9a02cdc44a4087d4fb99faeb75d218ac4da2b25fe640cefc49425f9c6c2c2d1f1720020000000352ab65ffffffff91b544692c82af03892e3676815a0452460fcf7c9377375d77124a06240044db0300000003006a52253b6ece0487cd8700000000000451535152be99e9050000000001ac61821e0200000000065251636351ab60068f0500000000096365ac5365526553ab00000000", "6a", 1, 478489352, "da1fcd43785e9af672c9b2e8ecd128b83d55473f66e198c9e79fa4d438e29576"], - ["4b7e7e0403eec4433aee67a9a35307520b0de2c41721a05c1d2106256b8db7ece933defae80200000004526aac51bcec317615dc4c0f95d9ab6c3fefdeb4600f5ec5cead6fae24fd062c281dbbfb4167dbf0000000000165ffffffff78b4d346033a26442cd919da0b08b9eafd2a5c2aedb6dd7b2b1d1bf8b236727002000000045263ac52ffffffff018c1e98050000000006acac53ab6553adf707af00", "6351536a6a51ac", 0, 1014381787, "f114f8b79dee2a96f0aa0c6a0eef2807ef19fd88c8e0143e4e726e2fe6a8d994"], - ["c6cf2266020a8416e6bd13c25af9b14969b1aa8c1b0985ff3c16048a94f1e88bf2c8f2f483000000000151ffffffffd2bb5b02045b9d87f456df1def469522085684211ff9cd7a36f950560508f6fe0300000002acac0f47dc5504472fe20400000000085363005151ab6a653400f4010000000008636365ac5365536a11b2f001000000000853526a5252ab53652e0b7f010000000006acac535165537cd79fd20200000000000000005cc3280200000000637f77774918b8bcd58803e8e22005a9cf6fa77906a340f2902850425a7d4351f1d04c4ea5747f0fddaad45b0fdbf949e3116ffda98d0bbc2ce60ecd2ebf7687f3783bcecae1932de85e994802cf8989bf6571c4631441cd43fc5588f1d5adce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fd7f91b5fdf23ff40fd30ea55103b814b9e44a3adb3a9adefd56a811d2a18e17fb9ae15cdde51ecf25a12fb2d8c22d97e0b16891cfc8b52f26b1eabc7fd85935184d3e25bceafaf3623083606d6763dd9dd557a465fb8ecaf575307bb3b7b5468db62f8f9240b4a9255ae38da93b3c79744afe66c5533e46102fc37315afaba02214e589cadf80592b3a9004c30d7aa160ae4f23bacadff4f27e16fdfcee2564c021c6ddb35f7b11b0cb4464a02a0bd572095118c9c6eb5870a6f44c5d93d8fdd470b1f822eef97cb244b0638a3608337e0ad9ca7d9f627ca95cc1c3e01e7c9ad8f7413986667fdaac571ef0a383705becfdfb287e3740d5efd27955931143b99d8260228ec3409d2d9489faf3856cb78e8700c6d780397ad6ce65fe94b3fe386d60bbd032653b1a0e033c4e64b50ca9f50967d70d82c124d3e546a23083e538c59c595a302094656546a112c54e9462ad4930a538d5a359b5f524e68986c731e580970b859022ab4cfa78738c2a933025d0d656ee6a4d24742b9eae4cf83850ad670e1014c0b0330177b98641dc2724c9f4891c0f7b7f00d8ff497a762c2b50032e0694540d8c1cc8f9dc01536a896e0fbbffb0f8c1d997dbcd2455c806b373c5b4d229397ec11769a4a4c930859f89191df03753a53d59d9b800c53957d17ac2ecb4f8337ed1661f162b8275b9b54d0c3d787d4e015463952fdf7b649b68e7c47a8b935a815db0419237802089d305c750edd2874284f0be3f79ffe889b1e0968fab83f4fbff69478dc84108d56ba8e16e6116b6bfd574dd2ad918d88f46f143f09c27a0c192d1b92e017e72f14377ee658d55b0833895dd60c8169c083e51392bd1a4a8189361e808cda7fdeaff113ddd94ec33e238517ace52bb6655737b0f0294795256803a22246c2972c9bcec900c79e0ed34531a1d8835b5c2059f040ca19099a1b9e3f4689ccd0a225535c613c8207cf02032412d15632d17c06cc6b9adcc41e18433f2ca5e1266e2fa0cb0d6a20d8252b27a1aa51068b34fec21e62748b279dd5a300c5dfe9e6ec97c02d55e09b0020417a3d43b0fd23d2608b51b33e70206b43dd016a028fba18c79d26122fbee446bc3b924f4d1a2d4a984b918542f48de741f8f3a80a3abd875a8bf5d287ef9141be173225a0facdf2449a97e30a78ae9b6cb49d74cd19d69f0ffa10a5d5a928c0d6c0715b7f8ac04f88d4dab819db50d4b587c0a39360a8bcea36c5dc001f0f7bc787fdcb7a52f7c8a729d478690a42183932a40306b7fce3149a9704bd0bf776289c2f8b60b4816b0c542b2b919101024a5f92da9fec1bc25bfa0dc34796175c0edb4e0f188ffd3e20d68cc5bcae2508faabb3a490a529706ad967b9cf02dd479e6865b09bcf49e6ead14d8b064363be2b71d2dda851d999343028f212053fac2455821043de97f9240639e51ee6d404bfe308cbc9241ed3eb908b970b0d47921b6a9ea3c544e7e39977004ad2f663b3a4853e84df4ecf1a2e73efb775556d3721702e519f5c9326c1dbf68018d92ca6b26cd672e982a99e0b990e02e041a8c62ee7c421f060a5aa71fb116ac49ec8ecfacd476d791fdf7f32545641ab83765fb75fea5db3652d63fe64d8f95ae49275aa48055844e8178352a221a3fa90778145452bc19abe36f6f7293f9d7263238836f0dab7beca701b0efcd798c3ef49dd70e07a7e17d449b9a262caeecc4d6738fb3527037ec2961097fb1091ad2d8382b4c0fabe4a9aa87d95b27c31f1cb696e1b5ed21bf8f117928a1ba46caebe35d7dc302dbd568c4e614bfb317902dcc5d6cee2ff817dba29b8f632c6cb943873b4f6fbf75c3e445a90370aa901c7de6a3da62a55b887af6f98ba6d2f039ea5d0e7cda1761b993e2a3abbf7f6f0ddc0eefc5e49ca914019b0cae20b8e9b73902bd9647f8a33905d194c7d818d31673ed0fab398be476f6fa71517d1aae9ff8bb1b078077d3dbe54a9109915a6678b69e100fff54ff6980f4dd6e518d5b908c52b58eafa7bd22714a7f38570c5c641e009a2c5f116c94cb24cc6f66ac992fd21aef1a0ddcade3202dbbc07c785142389c17ccb21862034962800a7434f4488cb44ffa336422f288bcd62bb3aab7586ac246138e6cc1c2d9968de1dae8c3d80489fed80cd61856377703d0fb39bf6f8876e1a916fcf668ec70a5e67886c8abb1deab76985963abaf498a9e6797fc3c0b60b53b0b6f06e7ea4f0033aaa9b76133b5d518bd5c977908cca7a059cfe5da7176289eb139d338f853c237a349e55617600b4a71af7b121b5204203000000000000000000000000e5cf696d928ed228b95808fa65b3988be984b093b984ba0743ef59b5bbf02f589bebfbc40814819bc9a0615d8e0bc69a377a7b1b0940fa09f3a9b8433be4543f23d458d8dbe87dbafd6726b7d25188cb763b07d3ad9ad7ea7fd71a0b85e78b9b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8528e586bed68356c34ff05e8af80f6460082e409428c8f2c9207c323592ba6f0143ecb63aeb9709643e0e387fd0f922da5c4dce8253099ce3f1075f52ac52cb8280659c12cd2f051e760a3c11029e8d5c42af3f39bfc5534e98b69ec91c7ae7fb2e74dda6860aa9a7647f5992ab88ac225f9564a873b765266886eff3e65280229973ee4c6c89f431b027af20762d9c54a1e9101da0a8b86851c6c01bb89f46a032de466f057aa4101c0d170a6711ddd719e39de7e8e11c45105fea3993a1344ef0b13f5c45d9a4cf62c48f1da79b4bf36c0b2addc3f93be0cb027a0a2135167dc3205d2956b724d9c86b22a3968afc0a9b50a9b10c08ec216d0dc3de8c48c36228d02086ee92b0b627394e29d296d1686d1f0d96c6d1d9a17e8ac89990fee4c9d8e140304c061e86d0d1a3650ca741664e287650586d46c4a3d3167ef070240644172bc031f30cccbca8ff97dabb86cc42a13bf4be516f63649a22dac88e5749109391c0d021e7a30e8d8974945aaa58c10bfb5bdb444e1387ff51665d43e191e7ce7eee25003242db9a9abf980dc0bb6f6b7a76c620a791af9c53448618cc6be26f442e201fd2096506332854f3c595b929d2cda4c59f23c15785a81c007637f30aad500c6ffe9b43cb59d26c46e3316f503f27463e3fdfbadc138f0385154ac1deac6b611d2a695058f0a3339eaf6a007de92ff3121092747f4b47ec66240909a575954c7caed05d4242e21846a90e67af9f0b21235a41e443a2d51ae9714536835effa65ef92010fdf4fbdd4a48868a4cd7d2ef9afa1ce10e9c0836de516d640b88910a715243fbb94e5a4f46b9e3a20585d453263f043688d1d0c46341ad46cc4b457b558888d2e1cf9a5abba7794fa03566318d3e15c6b451cd63c6d4c0d47f12ba86d4fdfae12d8bbe260494ed5ad8af9b8223a84d118173924037d5d3437c47be8c1afac52cb841197960f2e5ae2987e087d1f88b6fc67c452727f0b17d91dac07b47f01c4ae7f5ed739336673c34ed28c4f554a3c608e9716e6ad7a21bd516549ab9c3ab90d2a1db253862e666406647f8421aa7d1d28f02b49f0cc703a737ab55413a9aceec8f4e2ce4dfc3ec915ffe5255b9a1d0bb03f07f12953d3be8c001c2fe687da54474d6e490c7d0ebc1c05d7d60fb4a79b3a48556bfd7af2aa5e9527ba8125f8c555f16d67fe2b5e4195629835ee3afc1b6906e29f983542e5744333882af2dc5a524c0a99e03b6e42e72cd18d70b0be554070ad937fb773b31a64297b96bbf214df82117954a9b70225f2328e99a9d2ebc621d40808ba18cd12689e1800803cb3efb6d79fd66a5b3c9fbafbb42487a0b4183af79d72380b1f93db3be9867f03fd66b68e330ccc457274dc19157de01d8b1317072c5a832a8d02474f68639ef9c50eb5d8e1bea5805f7bcf301688e420ca97b8c8882bbc6b26bdc9f541534f87cfdfad6f76abf8956437b331bc0e9c86b631c415e68c121a33a3d5c0e54a2af0d5306143af1992ab90b9e5c1b41fdd79128d477873f60da3cef2a4f6649bfa73e986359e60b762824b57048b8feb2ea272a3d79916d41a831aca2bb4ac1acd043e21d49c4e89ec15d155540a7344267aba2e4af51e134db84b8003cb8fcf79dc16ece17b7d06f72d9db6f200ef39fae7db80bc0c1a99904cbca0914a7d7353c0babe6c4d32acf2cd986302faec1943df323843b94b4efbd6daa71762606048a68fbd57d39387d96a0e252a7aa8901ba84343b6792486929a7effaf9efe79890b4309d6494dae7ef81bdc5e5d266b617af6b2b828fe6fef2fe285374fdb271639ccdfa7b83fb06997289cc186ea9b79e7919776d83c3e13a4b14498cb3eb1b007dd99c0c33cdba050c4ca93847595b01081a50fd4e1dfc59012e30815a9755be9ebad98717a54cb80cdce48441f15a3551618381d28cfdec30f6ff803ef1d0c5b4b77faaab615ab58176f65088581ae664ab1a7fe34a46f4488dc4b80774463ed9c32dab8fa9da77a3f02dacc873af6a5c15b58d8bf7e2a7e73f60f2d2c873fb94a5ed08869eff465b0f0eac1eff7f52189f25f11bb3223d6b5b5f7e9d83238048a0b2f71b32674f011e4cec9dd63573426abb6b84c1f245b2a1967abe32b380a5fa384c9fd751a16438ee978edf509a155b3cd1fbf93f3aa10bbf1716d35ea78c3dd5cde3197b6971b043e5d79d9facff902b012cbcf6817d71b873c445ee8e129beb88b06a6fa2346ee08bd2956b1abfaef6a3194dc7bf8769d768be4238201f4be52f1222c84d4d302c880711e91a9fc78c4cf306e0a8b6ed80076b57d7a23830cea2c94eb468babbda699562a4485a21c706f93dda8d4f1047c28b39714d42952473d3799e207e634e7a79ba5ef9261910d9697ad11d5a2c2543c7d5158e0840b9f25d9698835a69db5a3eb237f08", "", 1, -1362049862, "72b91ecb9bd1d56a9031b010e0a23af5d8a49f4ae7e399b67e6a9794bc587386"], - ["4462e9ec03e0a7539e52b2144ea6e3d3060d45dfc26eb8b293762cae8b004d9dc5b11907c102000000060051650063635e0f739cee38d30dff7621bdcb5f588efad654f5d017cdb5820c56514ee41adfccbaf466000000000551ac006a52ffffffff4cad5a0fdb7b5f9f7ef74b76e268f5622e0808ea9df3fb4ac87d1763b4f4aaef0000000009656a536a53006a006affffffff034ac3c605000000000765536aacab51ab43c17f0400000000016a297ff10000000000066aab5200006a6bd52fa7", "51526353", 2, -1213420752, "8622a4dc91adb87d8a7bbb05bb76bb3a564ee7fb7a87c188ad151dbfdeea12cc"], - ["ed3e3839022ce200d160483d7e017a68f7c535e326f0f4665a3bce592a6a0530fd349eda90020000000963526aac00ac535200198cd0542e39bd37725ad435c11ae41b21f110c88f1e7878d658b3027a50315a2bec76d100000000076a6a6a6aacab6affffffff0400023e04000000000351536ad84acd050000000007006563ab526500a9bd6c05000000000852636a526a6363658479bc030000000005ac6552ac520000000003943118010000000000000000000000008a18627f0db1da9640d85c34c29355b4d992aa45e0ed917a4927d36c598da5d2297a6bcf4d7da359a5f16463c02bf2de0f18f600b55509538536a4274732b9287d19be75dbf106babb8971d2524184b79685b71c5d17d5ad188d7477240f041a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f903ffb6d9f3a6c91ba681c63eec47136fb984aaf27a03876fb0f64bcfa51aaabfc36d173536e9b5f32001ea46c881a957d24c7d0747759b5eb7ded760e58035159dc35d0eaa00bdccf896df6192516f1d2d80844c5f4957c7c94427678c229ab5a43dfed1639eb2acb5991c37385eaf392ee31155e98720055641146f6a664022bddf8fd661d434ca94998d138e041e46f69b809e99740e70976d2710e0f27310211749d1c9549e042a37f102b4b3aec78ce1a87ae4aee6dcea595fde29ec3f2df0a13fbfd26060f7630479190c69a66e69fe5141927ee9d3fa1952e625329776f3420fa183e685e6d1c077a8929b9093a9472dae8da2e972b45341079cbd7deb6b5031846a3cb79ba3bcc7ec880d838ff1848f2308554778e71f403c2724e620de472032d7beeddf4313462f077b08492c8e51e54961224b29e4e69a51213db890319320319019b268d0dc022153db8135b56a5d13e5738c9a7ae1709f7581e0c8d45a55e02204c7cf6b6fbceca04ea0e336b797f2c7ae86e73a910f1f2c07fa0cf6b89eecb02098b422ae351deb49491220ac3317dee8e635c02558b76101cad97bd4ab1c1adece00c6d7ba016456cebe4ee5a07fb920dbb4a280c17cf9c2f5b054d6a48ce2d7d990c9ec2c58d1a0ad0c76b779dcfb8de6c36de6d507d5eb2f03cfe288c0b394820cfef56908eecdc1ada017f3937d02268ec6c815860ae42b51aa04eafe6b088b70bba5bdf6d56db0c19c48a10f1187558c7dc59f2099c01c6ce5d2b354a7664d8ea0b8d3b486f8b927bc6a157d9c5cfb08d9f82c39af3d5c10f852d51d26cb13211c8312eecbfb1082dd1fa232188192c665230eda6ed27fb2489f8dd414971ff879dac94c91141a9f88922138838e0ade54f028a880d32e70479fa09c5a366541c5abc1a3f243b7161fbedebd6844761eafdde59312fc750a818c773830118f0c36267e35cb67ef617bd84c013b00ab48593cfdaf14bc508957dda1da7d322378dd89e8675b68878bcfc860e17bb9c8281bca644d30875501e9b13e2de087de74c2afc7a145e080bf41a4fab5db64555837c10ed0b1034f0c10d2de95797acef73ce6ec1b40a44ad717dce3a6fa2e3bd17281f11e73cd301805b84b6f91fa5247b4d61b89c8056be911ef6774033d2716708ea79b5a6924401328bc71ba2579905c11f44b4531f1dbceaaee168c63c27539779ceeded0ef1c3ad664a6660b69c688ed6e670c3ad24d04e11e845b8ea1bf37f8eb31f6ae5e1e25512d56ec6f3a0b5cc7ab424ed69151e41dee915142b62c6f5fae55b0de7aaa9dc6af8a09753436987ec3217f6e402aeaac7a97c062cde4fa174b2d6f62af77773b125eb7d23bdecc2b6ae9df817957dc3765c230361221e8240b2d9bc384277acf559c57ac6873d0ff7376b8755d835757ed4aacb2712bb7ab4f30a02917479205f8eca9104c5da8c08021173c3e221cb4e2b8e16d803ac96a289b2690b2a0b797c7bbbfc1b4388f7662e1c34a4ebda376fced8105c14b39d3460ce56a0850f23e189d659b3c8191e64078a8ceb75c331e4c375c81af38d7138b6ee7d64aef9053981a625e29c7740dbd0e01b57943931d69404c4ab68948ca111372b404ef05db38c10b96bcbb56482e803f1459d597ad3ce156d8d9dc326590e48847155ae0c70159b1815985b99d16280391c65ddde8da1fe3c9221622b154330751efd3ff3fa1d0417eb91781bdedba44b496b3d9cc2fa65a512f4fe7d28aaa8ca45cfe0369cd649abe4ce43aaa6afd3ba0e702ac6252eca9c7095215ca8ceef073fed7a4edd66d5eb752b55805c49b70aed9b279f21a9cba245e972cd8cdc6454dbd481ec9481d10727a6c2bbd7830e589eebc1bad331f626be53a05f7cf30adb83328f0466b66eb385548e89d2fe741df76450c03138255059e252a8342cef33799ac78f2f001427780fe5cbfb6713489cef62063707c80cd1f9c802dc16b463ddca19b389b820aa6d87ab8003ffc0c877c3b24940330d4d094ca0369f03b23d9734f4a45e9f92aed9ab964596464b748353f65960bf19f3c4cd5585d7760c2da5b5f0ce8fd6aa5bae8f17d76b5c138bdf2a39d70f2a248371e0ae5223605c131f82c3532ca2abd57286e69fcfbfc8b9485705708857b02f230a0156d0af5bc1a98cef402443026e75115cf131edc144f907172e7ceec315a328af567ac1dd70c4a4525c828dc1d0c0cbcac9dab336ff2a8c49496d12652ca2e1c18a7053f2de6b922ddcf5d4493d2cf582e3a14e64b3b92b8b4638951dcc443bf79df300000000000000000000000000cfce473bcc522f54649240a4ebce568605f95153a2e598b369020c0c285bfc619d01813b9d4e92c1b0f42c8cb0d7323f9851fd2c8621f239002a5e786a7734605e7e48be4e197d5d7c8312db61000e89fdaf4b31a3035d32152ce4d62681a95a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094d50ee657a313fa6a8b2b6047ad5274116e1752055beabb65365ba6d513a4b7f5c266d486fa374bfe6bd9bb7082b51668858d4e46b84f4ff38a9ccca113209e96d485d3f7af795a6705237862ad7a5892b8b470f09c95998143e6387c8a098c21533a4a2672f6fefccc0af5e0c12214c4a4a5ece60446416d7bdcb27edccce0223d6156ab521342dab9e9afe89745671648704148c5eabac88a8cac5f0beb0c2021ae39dfbde19f160311e2ffc6991caff6210771ae8aa271e7e9c2f2ddc964b360a28768a97f854d925c49cd40e0ed70092b1ff222bb92497db4e555c6a137a144e1fd0bf5f2ca896d78b9232773346f87c9195c6c434da1c9344fd4bf9e182f369021e76ad05310724a4792e4b5683091cf6f7863324e02cce5c14a6c7c8b99882ef032b8b4dabef43b21c6ed17f1dd60193ef238c8ce40e2f09b7c340c778721565c7031ca1506fa5b111748f655dd89ecdad1910605e0a32bf1e66544b73a312354184022c7bba48039f008fc91341aa1f86b7e1ac39903c91fe478f8e2749ef386e23940316101736edd44426495a0524dcf6ea02c616b51365c1e1d92a3d4d2fb56d748e3857d7d1e0887965a4457cd9d3bef49fc7204945e3ed88c95d70c678744f62ec68bf425bda66a2162eba7f209c0520f5a0bd5d5708dd341fc3d0eca59e63c73e5fcc660c58303d9984305379d52ca480f64dbb25639dfb5bf004be8b6aaa520c6fac999e6784828c0f9702c7a686145f0a0be66e04d6686764c60ddb40b38cd315f3b7072bbe02f69ea97bcd2183d9bd510ad6bfd192701a110745fab53970b28cfc0735d6adf30c117bfc1166d250082d11429fbb26dcca0f0e177779e0589f7d9edbe2532249b7254454c48794e1460a9d483a862470f0ee921b0cf57b4a8e21d1c3359b4d478155417605e8f18d0f9cc96aedc5bf8973f94a3e8d30cc0ac80a6b4055e84837fa0c251df38ac1f678ecbebdd1d9e50b91eeae6f2c9b86d1293efba5644b9dcdaa280a627c29617a2447ba4a7ddaae46bbb246e7783aa7eca5bebed536431fb6d47bc66b07d9d4be24c5eadc50f8e514150c28b093b79b0e5177d83d50ce839db12eda9670355aa9021db6d8f8823c45a7c93cb7def5610bd7e81fc2ab988ff4018c979e22f60a884b514274b2053960f9b0f4570282dd714fdb4e2258b867e813a5c5de65cb3ab898db2cf655673176e20444d57af30f735abb007cf597bf8e3b128d1d619c320271fcabbbc866e345266c06312e05b78a073f75bdc4805798853b5e6c0ffdfe4d1c88f78d6441a16c0d8bf409bcea2d5926bc055aec8233c654b19ad144ed1bfa9c73ace10d45c33cb7979dbbde519e73e8b8b265ee02de76acb914c8f984efa524f23ec3baa824e2505df76d39ea0facda88376f74bdc5632426081534603280ffb692e350416f421549a8fd19197e47740adf59aeab1d6f0ef650f2aaf2cec23d169b8446dcf02ed27a11a79f2030d87910d9098ce601f75754f2d69f048dd0edb931b86965899403734c1035ae34bbddf1b223dbd5183cacf2500f46fd2d88c3b5db50f184475a06dc14d38db4ceaf8360e8d5e8802d6953c4ba9c6ff0ef06ad5c8a16b80249b7a1f3dd900f7f580f07407f456a7e8b678796a6951731d4a764547a980c8f63d7da2992d7e7af653e8f1b916090724d99f7aa03f45faabc22c2a0858a936e5b84b0da32ac33dc9d37b9006e7e03cd14c026593b2e525484a0547ad4f7585506f3b13d95c08e5d6dd8bd7313bfc5ba0d046476eab5e3698947ed1f6d22c0ba11d3dfd0fb95104e24c52e8cad727468146045a52adf6fd52c2b9bedd035a7dfe2ca5b16401fea533facf932d256d96711a70106531b768cb12841d2587a154a923c841ba0cc9d46d9d8f831ebf259d43dded3b9a52bcd69daaa157394cbe19bfa674da928c6c7a95e9f127dfd2522b59f89f8322cf4193f64475501e7dcc3c547e6a617fcb31e7daf86eebb7d2499d182bba328f04b8ec2f32c5c1c7953f03e830a472b552fa043b01a424d912a35abf94b140f514a6e3771f5f509bc4f274806d1b5f6248f23e5f101958ecefddad0e16862cf49cd280d56762e101a84bf500edf71abcbc6205fb3c13a4da47b4596db61855833f387334c3bc78de0007e085396cd470fa3bceffe37e0c73b389a4723720e67691228e142483bb1ab51c0245b98b13e71b7e8d136b39c0cd569117230e800adf2e3c25e5752d97048f68996cceed5a5404b8bd035a069cb43aaef6483d47c650bf5cb435b50c3e0ae0000000000000000159acd0400000000b056dd456589859ebfbed8562ea46f3bbcf196d2f2239c4335b74c11a5f972c694b5de666c6be61e25cbf32bc5f84accd970a533b4e6f68508509abbf84dc1a5c0f63ea2e7b9e070f2851de671675f3989d83f4de9e08456cd020bff1ebd4b35000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ee30d22a23f69fab96f58dce0e5431d46fea6bbf7df7d37661b9b2e0a12bae7baacc79c9210f7cc69666cc1789a835096a72a878c83525826299006eb57775be122175ce74cbdbc12b3610a21a78c6f8cfb3dbf5921395fd22e88f5c9b9b43dab5f52055c5982a6db0a9ff66092cce3f54f10975353f6587034ac24237ec146020289236fd24f053a7c65895f28b3360a3264f1d1253efa8372a593748fc455cb0215110b472648fe0283f087f55c68f1155c70a14aa855a1a6fc573e1e47da54cc0b247d6055393c2e87947c2295fc05b5c7fde6d028a6d5bb7cf67841d0f98e860a08dc8120ebaad4bc8bd0884291fae288626198a1acff8f8e4e0982c579616f360216d95d2bb6180121fe924b090a428edc630e6affdb9d428345969163a62188a90315ff565e7eee4acc3cf7d834671387c96f79f7dcdfc4430a95779878f06882440308840c15ab5f3c03571925858d3542aa76cbca34579ede934b78522586322b41032602ad9ff2b38283a16e173c02132249fc6a171ed6945c1f225153e33cac89e1021a4a07875e4d55f0b4c1d42a9619f340121c474389ec61a105fd01c810e502e76d9d15e12a95ca578544329427ea2cb849ec7627d4120e95b658a846e3d26ad2f1d38b1d0a8431e7e19860de5886ee9f9b24137f4e1ca53f515d6e809a4dfd0320a4b4a5cf0f4bcfc8113b2f52fb9fb261b663ca84af6c183830c2b17d23eb748645f27e9efcdb8a301a24575378c6a4d5598ed56d91b06b1e6eccad3a14b170675fc2d17afedd334ccfc56cd8acb58d35cac8d1a0048214b4d48421fc1f954b7987261b5f2f85a291a69f7902a03fb9acd97a9c5cd628e960ea0d3d0d8413d811f517892dcc683e672866bb55a36241b736bf847af46f949814508ca7beb4f2ed3d00043d7c845e7f56d66fbdfd041dd1dd2587a4c3396c77f14c96359b26e8127163325f9bf04f4cc670377a240cfaaeca86226f7967719b231d44f48057e38c2ca914824d560da50d433a1e1e7312e87572366e46f176ca6df30ca8d8153b3ac0657beeb8c4440ffe68ea90588087271cbfcb2427fac9ce481296af3cbdaa98b3d2d511c65ca16ef450b88c0d5e23950a6aafa1ad84f5db210290819c699fd22454aca701f56407cf439278d0cc478091672bef6136fb5496de49a5dd9332cd5fff7c99cc658345abb8575fef4cdebb394c49b47f9ae85d6a30631fcce43476eec725ba14a5b8a024a52e646f4d9518493d0353d1e0f4c66ea6e7f04374bc606b090f20f05e0d92dc39c70a2e2de3ebdc653e3c2f506d6ea006232892c7466a3c79743fe021201078e656e967bcd03e398b20e3541a52bba60ee08c0c48b68a61217a281677314757f7b0437b8790bc93e3081d31823a0626fafeef703fd33254d561973a7f64714e63bf44775a4e15b23f56017d3e8d1726402f679a3b6fa08b6d6bd18cc2026ddef1d1f17484781f2e645c057fe0709043b7fb6a46040fcfea7dbe76ad949d153fd62d9c26fcd8d304d4e6764f87cc6f962877205c1275c5b2096cce9dff9589d07afacaa0266093f6f9681f891bbaeb5477168fd5784b8c8124675a5e79997b5d7f1c2172a704fff9fe7fa7fa7106d58a1a3425540946e8549caec2bdd9b0f6f921b1fd10c1365a9c6eecd4a27efcccc1056e634509a9182f3882016b4d003e8654ff3dcfd2ab87dca1c843b4560e9682aa6ba2d0aa99ac7fdb9930161cd994e9a66e11a390a5c414f3ff1454293ab42c6f5330c0f17ad1c5cdeb2496b6bf559940c1b10a6164d42439028d7216f69202a2b7b3aab303fb9a40ae8ae5de518cf3ab5347898eaaf54755909199e0361abd7a364960b8c146f78e6d7e618ad579f53279e6ef2858405cd9c68a1355e721c0171a2f43687e24330e3c5d818faaca4467a35e1eb5a9d6b6fe34933cd5a69c358800f07697fd46db214f466a74484a6461c34688c30d700d82317fffa537dbb386f8dc6498b40c9ed6a33fd972e1709dfeb62ae644a75d9a7d3be17083449bdd91af96cf172d65f3b71551a47c45f06ac7be03fe1243d60c0c57a2b4aa4aea0f3066f4850bee8f890fce9709848bb36c712c62ca1d83aeddccf9134cd5bd95e0710719221a6af290699400132ada6dd090eefba93e3ecee6576f6627006551f11fdd4d3c74154afd675766f577412ea25870dc470ac64635bd12286b71dc339cb15929b0b406b48053782dfbfa7549275695aa7b3021df74945027435311f7e4cc07a859c7a42573176ece6dcfbf80b0806329010ed0ed8a0fab0d76dd2632c8c6dab33eff3264c954c1c5f700c7a3209a874e0da931cfc2ff19bd97f062b2036d1cdc6e3e8cfaab36a81c1b2bd533965125bf51a12daa0c0420cc5472310599fd5daad5821170f1990a518ac063b6e9b5091b18ba79dc06", "ac536aac00656551", 0, -1704031587, "dea3549522cc05e4d4b1c6a274cd6c6204e3b5820ba15eb5b086c3eace4e9cd3"], - ["13a3080902ed4c698577175b8470c98a5663dabc35ba8591f7a4e0d4107b4d7d4395c752df00000000096552656551656a516a86b404550a7b2df8bb9f5b48874a1f28031b8973d415086b8b8da04b08ea1a94c7adb8ba0000000007ab65005253ac65ffffffff03aee7a005000000000965525165ac63ab6351acb5ab0100000000086aac0051acac00abf6290202000000000000000000010000000000000000499f530400000000cc925d05c139c1af551f1593edc4cd554decd9d9a0c538d562aeb3e07cd42d0ad1f5e8dfc0f8c4cf26f125577ee5f46f3713978b8d07f742185003af6d9ac2b534b5d41e69a49e013c32c89534da2f5609e14f4b27699bf515c5d8f9d93bfdd500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000978cf53bece05211814af6ee0f7a88e75ea98dfe97d46a548c02ed327b8456080d92dcd03940e848cd84120a77804564dfe80b3a5c29e8d0ce557824c73d3856dc29d61340094fd6b644e1ca2097fddbcc8381d1250c98fefe5b1547be8d7363ea651697e0ff25be66a05445472d543e71c86afbf620c81e5ae8585a66b2e7b403257ba01c58a0c498a1c02bf66b717486673d458359d953a1412ea66dd89aea950218c4e5d4ab9b34ce267f8ab1c40809332406fbf0acda1a94260a98d58df816730b1520e8cb11de9a4ba961c3fa2facd5c12a74d9c98c514a55ae91f5f7a0d419150d87a1156c4765e2e89318b7483812ff2b97ca9e9214b27d67f10fc9da399e2b032afeb469948e91cc17f59d1092e4b9dbf96e181eb9c9ff5e21e8712c1581725302265eb50f20d4052b0e4ef59a9c64c35f53315780b8110af045eeb747f80e22300309029775eb3d46a294d54ae55195bb8a68658370ffd0fe43722871b3caa95a130223745d2dd20e9f277e54ea4d6213d36624c08eadd75b365703f911147db8c1eb022b30780dd1ffcfcd227e1a4a60eba9a16a1598977da8d70c65112abef84da4372166a1cbf2598d4a8edc6c76cdd20756898617994cf7d95e39997d985f40ee7e2dbae5fd8f31a8a79d93fef02108c5da457ebc2da18a4b620f268e0a7bdd78b6d62f08808ede3c1b6006f29cc9a4fc111bfe6555c0c8c7313ed8d4d7ebeebab7d54f0e51cc3891edd45cc401e20d5e28930b4533616993830b8225171be3f5e6fc32887f4257b669331aa882f5fa6ab221eb8db6e98b80f518d4a205cf8f02f3a9c89cd2f69e852cd7d8de85dc8089d04195a9e430288b963f7bbcd4e4ede5bd31446d2cd6b0a8dea3478d5212843d1a7d8c9030a695ceb29170947e8ea111fe474b0b4148be35a4035b363792722d24d37b124747044cd050f4bc0db4a02b4023c7f51dfa507d811fe428c30b4fe42654e907b7d6b3d62d89f4d1a11e15d134e588d446878641173dd093ee39f266c2712b4df34b698a33c63b077d3017603c3fc9f837d5d754acfdf6982831e29a81701889c3ed337f67d12a7cf70c587fb5cddd2476b4a5f79b67b0d5498957b14b903408472eff941fcc249ec10181fead130623958f65939f1b3f92d1f8724be6010fc7e2c6d66cb092338fc41fd4099942eaa45babb0905111e8c91665b69bd507534f22b8e015f80b795eac032f631914cbbe9246d3e98e3824e88dee6694d43c3b03029f524d9b62a87bbded88728d2e11511d808b003522b58b73874d0214e6f528c2e100bd70ce1416507f486605cd183288e562a3a6763de413427e40638879e81efc2fefe7bbe282e0d360ff71745e0623351e84a0177130ff262c89b9f016640efc0811d2d11fb0342d1dd34b2d41ba363e021d202cbbe0d9a2d769518f08786d635ac2430bbea671ea9d2e12615ba8955368d8ea3d3ac6b3ce485ec9677a2435e910481c546dffc601941502f5c2650fbe5e821ee69f3f86c2f1cc17feaa9a15a0a9efacf8ae8273a580b7c5c3dfce88d33ddbc05ecd6f9feb424ac40acda33a8d1ca4ab0f9b476c6ce5e033ecb9b794e485c886bf8239895ad81cec006b0b716daca46c433af40f6d384fa9b13ca9349c5cf6431d6c719e5d208765b1bd9b57a5a19c1aa3d988bf1b88ff47447993fb00a987356f251151a39661cbdfce3db12ad109cd1fd2aec81bed703ce35c03360d1dd3a7c278b920ea9435be414f8ac6c5fdbcdafc2272fdc7cc9314598f0e4b6ee3926a886d7b6f48d55fc4fe8cb8cfbaa999b148440abede58ded0abee83f41a4bfb2d29f5b7e657316bd520353298f14cc86687b3a30874faa9fa9e44683d01f8e010848e3855ff5e9c9f412e2f8e4c732556204649f894da39d58f89f7bb6801c09f20769d1093b3868b5f1d1b429ade217c90caa7097d108ad70e01994c0cf094bd04494919a4a4b0f30e1a0329657a1647a71851c61e38f18ae61a66d70017b9c00302ce634cbe34b60000a8e9fc2025f2cbc1c680aaf8b139979a24c67af4a6c11afa17461b7e489ab4661a5c3546e1ac6e7c7db4cd87db7533b39c43f3c18d36d5008713aa9ccb4b22f8bc46ea7470f97c795a17ea228a8a9623306497a770d6bb42afdda9ca860acdfbd3a0ba56396851ab13b5bf4e6d8521893b0b8ce5ecd7fd3cf26601a9a4e105c8ed2a2ec97bc6c3d798fccd0f4f56b7dd6b14c1a9829148ad67c826e0fb557f17b15771d1434a026565ee23e5ed2240dbf9eb6f0f8e6063b8744cf7fab0a9948435f2e3f7f0076c6ab2b42691ba335726318c577125132ccbc481aa3854788acacf2abf52cac47768ea4c06e063c3ccf08b3526c3a2aedee68baab482ea84c7c259f3483f3df95340d8b36d03707764ed80c3249f3a84aaeb78ec8dad93c9c207", "6351ac", 0, 1194704766, "63f4499d8c52ce7c9a1fd79aedec16c277759e3b56335bfb11034afea76911b7"], - ["35bc927104167f685dce655b018ce23382d4c8c0d4e5bda2364d6cdaf31ad36feeb5f89f8f0000000003526352a2d417ba209aeebf3f1ec844cc8f9556dc1eab0aaecb547680d56361f4cb5d099569372b010000000163a5178e9286ec0f0f1c3b1e9e1c5dca6030148442ae27682f0033d45e9e7fd4a88461713b0100000000fa6419adce6eceb6fb74d590ee43d94887a4d4badd66e09f3e6fed487e7e703bad2e59020300000007525265005300abffffffff04e01e2e0100000000036551526dab760100000000050053636aac14d0a703000000000500ac536a6ad5a7340200000000016a0000000000", "635253526a", 1, 2094929526, "619ca4509f95c361f56309ca4a06e29147e49338dbdfbae9d8e6ed1755456e77"], - ["8037793e04ee98e2d5cc63ef92decc6091f0d15ce01c83a6f0bbf3f0427a0f2672c2093c380300000000ed503ec1d6c2ec97bd5f7e5e253f8a9d39c2b4c16d59012c0471dad1999674ea3349f8670000000002ababfdcac76d2dbb1abf37b4feb6c4636ed698971fb3d87bcc0dd031b9aa786f7376d98747540100000006520053650065b9b5f65b84e29621ca8e85db887a6afc887973983c0f48a9a590c36b834889d24c0e5043010000000163ffffffff034db24b0000000000055351655152bf78be01000000000951acac536a51526552b9a02e0000000000046aab6a6aba4b720502d5201405000000000000000000000000cdda55c7a13129748c7ac36097d2d3034a240629bd0dc2ba1f923c2a813550f6aa8f211a1aebb0eca3bd6e4bfc7483fd2b0473d727562ddd0e6dd2d681b23cd90c8e09391f88fbfb09a1da6b02d017fb0c32cf64d676bd0f19ba07c2983371a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007747f160ae45b36e77b1c7e13dda1f8cdb7f2ffd7d871f2a1d5fc17edcbbef1520ca17af9a8e9520fedab341133746265ee6af4771119509469c72fb21d90ec89aeb77dbbe024d85a5a4882531e201c359301d9d04486dd4e4bbc13c6fff0984600dfe0af4c116c296b005330fd903217b3a9681223702fc44dec0beede894e7020e6d9dbbef43255a246f433614ab9da70c9af2a6133101b284757704cd846b6102050bf694993ab78a67dbcb09481aee09460586da258e99c65357566347cf174c0b0717e0104f26cff6ebfabffe7ba5c3b59f5c6dd95317bfc1694e7c73e0fb93c72431c4f42fbfd4212600aabfb63b67422190427601d812d581484bd64dbb3e3e032cdb63442718b5f4498c3914cdca10ddcf05b068d8cc505b893c45ac64afccb30314e68a809928d3d9457ef66d41576736bd9768d7814f7cfdc0010d76f1ab6ba40302cc170ab83cb76f77612cb80fed80822ce6e284e3df48fafc3193672d38df3d030f60ea11cef80fd27aca78e4f32c0ca3925085d73c63e79cdf2fcf480bfabba80316a7e0f12cd5e1564a46229cd48c0fc09cfcfd9444ef8529a866065c67f40414f0105f458efb976cb03a58973f01009c2a97c9734dcbccf28deeeae52d373087a1156874cc3b5b909b063b9154b6fb29d482334d920c25de83d8ec19cc2f3da831647b39eb172a2cf37e719181eac366c43cc6ddd2b6d7de26afcb44d78653278a5320c96547db2ee31e549e8916b4bc9be9960d8dff4c0d31c75c57667c3c4ed4018dbb974e21c0a8e94ac7486a395f50bc0c445d7c5f8e7e295a070e0dc7031baf867481a043a3d7bbac7c106a8c44f25b7078f56bb5263c8b42a1cac373dc5c717475431ec7153897bb3586e458b47bbab361997e09a4f05d2b5d4924a84dda24b9d0bf1692dd51a6f0912f0ee11a5125928a76392f4ca86a20522de03067a8f1d0fae5933d0d84a3d2356f16e3c0da02a870672bbc2bc426983935134b36998067994e432751aee9f507e7aca03d1dfacf0142677bc7df16ea3fba5e981dabbc8f81a83b8413d2aa3aaf6f7be8fd0b1672bf057f6de28f224264c037dd445da83d46cd89ad1c9fd87d54da65688d70503e7bd642b27772e8aeb4db608167ae1e06feb6f0349c5131a243ff76ebfb5cc8d75378b6e7e5ce8eecd0e03f9cc93e22992c14ece31b647bb4ea49efb8cd37afc212d6628657058ef7d5d3a4aafee2c015be2cdf46d9e13054768d247cc110e29675972a7fa2043c1c08e1c26ef76a66fb23b560f9c5e852a8e9d26d44c751c1078ffe60ff19b2f3753a51d6bd020b87a663952c307a02b578cc6eb70ceb96410c1d18e613d6932fe37f12b4487df0e28f5a633a4a22921ac5ef25f7cf41f3939c7c79d9ed8c6d94332eceb683b8e50b1aae74bf5e6b1f4a952a89fafacf8f10b9a3a4c23e810b9cba06044254b6ca16114e1c224eabcb650a26f6e11ea43cb7aa411abc8916b9281c5fdad4a52ec2d5484d3f9944544a4581e212732966bd4089cb5d32f8e636bf14faee0985b5beac8eff8f640a1874c0bcc2ad1fd61cbcd45f876f4eb074491b678d7662a7f2e15693bd3a27389c112180ccaf47dcf49306a57e89035b51098167c56db6673a946d7ac72a84792c4d4a11279b05478dbca2c94b00e111ce2607195166ba3f214b4ec816adc0654182a810a328a6e9e0a32b4cba1d486fca3261fb5d2a4c81172febb682ae3ff959e69bb6f2c8e318a9af682a60b3dc307b2ef4968b4aec1d0faf8f617aec9cb88df34bebb4b91b104cfc44ff02b4e234fb7e982a2793f93149aa265fc773a94302a6cd69b73632478319927a0a828b3411514d091a13405506def1c28b2543f6a2e4f3473b5913299a3694bc5f769a42561ed954f0b49df8a641ed33fba51c90e528bd27bdfd42b2c638b5b371bd10e203696239f95a249670c89f6fb9fee3eaadface720a6c4f79f6eabff56965eabc17dbb6203f4e2d9980124a3b60227d1b255e5693575eb1bbe1d2445d1cc99891c6e56e841d821cc17de013d9cea99535c6422cf99b8aea81ed521332bb3d10bcf0aaeb873e8bb2213b8171a0966dbc0ab89ed0e2b2d3d253fe350c911bff67e5666ba1e9e207a81f0d986c4ca2d6545051fb089c4e1903105d5285e1e264a7d047048eb6648c58e998ccec3d26e145a447422d16adbe78b14aded2cc47b8a79d85c15ffebf62d3d0344588799d2123cf15f3e997993f7329f302da91eee0b2457b30923effe5650f45a9a81b53dec8bd6b05ea490689d5e2b5397c3c5a5b040000000000000000000000006bcb5a821c9cd7b0384ed348b7eb3d5b1dfedc750c1de50146f83edea585afe46921897962ae74ac006cdf8931c2d91cdba0d5cb6cfb7ea3985673545c2b0ec04724d1b35530211e98905df96fafac655c6f504bef09d0a5d7b280b64b26ecb300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a6bbe7aa78f815f1fde921ba200f2ce11444855b980f726facb7772d9c394ea23beb97df4b7d034110afed49626baa65579ac0365f6564acbfb7eceef1a5becb41d8a795a629c6c55b050e5c883df2072658dcc537103486b5779159b81365436547149612fe73bc034d94136f729c3b522ff377d8095846b1b25470300cd19d020fb586f9251fe31948bb268ac5a2b97c088ce6e28868b5be8a40c65d95db0ce00227374043ccbbb74ed85d46bf92111e9bf00e79f0725fada43228a72c985e5a350b13ffd714657016facbac4c11e057c251afdf789ae97d7c671e5a51099df0f7450dc0eb4fdc6ac6306d107d0b7b7901fdd171908a220e537f067e9cad13eb087f0302710f0a7cb5867a240d92eb5c9c4c28414596417442aa86f68eea34f2b3b7d50303cb2e0b5580ea42627c45e1138cdb66bb11fb50b9a41b96295fae11497b458d021ff49435e5b263e4159718e8681c2cb3d6d597c8359bede90795eaf42b69b7c60227158036f13fe64df5f7b1a5fc71aed84193cadee41791f4985509ef90482aec022b332f9e21210a5e1fb088ea8ae6c7b5d33cdbd92c085b6c554da67a5d507fdace28b422b07fabadef7be93078d746063e33e2170c6bfe583873e862ed0bd3cb7d7ea3718ab45a25b718b2bc4577e5c42fdc3306e0bffc78fbd381662f527694d9f1d0445ad5bd0343c310e7af80a3b93556d85b0a8e42b6ce94ad8ae09fced3ec6f3b83caac56ac3b8bb0bd9f6ffc8bfe6a7a0dd4a9633c85405e3749ac599fe780171e1ded0f80ccf0f27f78600e17a9f3fcb48e9a426e9c0161c9a1769eb37482fcf7dd2874b2ab4eae6bfefd3a62a046f9e6fd7e38f8cd4d319fe9b99d7ff891a81791592e0fb6f6429261a9440bfb37204c86e475dcde47f135c002b3bc1109ce62e1a41e5082b9fbd598b0102737e6889b204d29afa31d0bea4a0f8caf28069c567a207230eb721993c9cf145e2566eaffe388fcfac533d98acbeb884bce8b6ca2a8468531370da6c2e3879dd3ddde89aadcf47ba562474f9ac3f03df391687844165ee854b237c6018eac607d3e7e6c85b7a04a7625cc63364bfec44cbeac0bc2abffb3a1b85621b88b6100cd4c292ecdf9f85a4c7749c14bca3a616f4107c8562dfeb372531de09c8f0b1ca4bf1b8076c3720386b06f8c9ab80d8bf108d0b38e44f412584d8316670c8ae3bd5ebf3cc14025de49da66377c277e39756b01a5b424e9a5940651aa186625a1311e2e6669c0cd387103fbd77e28be66c82a00f9363a08db6f05dc65eb57d53019e715e5cef88ecdf0a09984dd0245a0ff42e931c0134557234876c9fd234c4ae09590726350a0eafdf4108194efd36d7ecf7b34b8e04b49f930acffd574ee8a17de286d70f70f940032c837e29c08a8988bfecb716b932c651899978c88ecefb530d3a7912d7655f19b06b98f0ff581ca65cbd6049c0d1d02737a0d832e06c8be2782b10c9b914b7d198a79926d7b8685af7bdd53b41364b219b793431766e924c66116fe3e16491d7f8047eb3d19370142bc4db7ae54a6b60628165a3037ada3835937d8ca7a570ac0c4dbddcfd576324ce59bce98dd153e6a3b818645f3ef9af1dd4b5ea8aa1243dae784a0ec55fbf6dfbf874343d5e9eaba18870c113f3a9124d605584ca8765bbf30226729a0baf0bd27d62f5671f238c28c00d4688e591ed52bab98690dd09221b6fd035d2f3a25e446adafb074237dd966e926b2141bbae24d0525e896dacdaa429ed7d378030c2f0737aef0751087245129814f55be7b824aba0d4cd7c4a2add214b9f72e1e1d681aa0383041ad821c8c087c9b27f407c4d6505067f58c722704b972242c545bcaa97d4c489e440ea1d1f5e2316e28c4d7d4303cdaa3fe76cce4edc98938c1e249ffb92c164fff29668dac77918ced416b39ad02f2aff3379501636925a71b7aeec111d81cda1d756ae2eb42d3b281eeacff97963c2f0b322458a93fe24d7470e454597699f3c992e8cf047756226f1792614745701153a86ee974053e2dbb34cd68a02bd2f2c224f6739e1ee09e9730666bf030938d62affb9348b66e5bdf42743a50b52741b692a0bce3ab9228cec7a675a94e0eb2e189e870b324b04c52cd781b738f97e04b94869ff6fb1cf9e487461df836d3474971d8eb84a1f43b99f2fb81f1fbcba9f6e6235641d2bdbee313db4b1dc7e2189803e751276990ae63e20c2b9e05786d6ac9ae6e6701e5f6672fe367978088ab657c461105c07b40e094977417e5b3884f2171fc5544a625dd7157a416361791611133591dece679a896cdaf5a19f71270337b18a2b97e1207b4a915ba4e6216e1fc8d4b74886a80ebcb7cfa17fce9849e068b3e73a807e52c68e2eeca7fd720e02e934d75c3d8c6e7b063ab0389ffb5073bf767b3835f5935e23d07", "ac510053", 3, -1097935595, "ce5e4af1d6d5f548149b05c30a2f6b520758270c59517b20ef1f8a75596afe0d"], - ["325f455501afa59b34d56207bc6936c8b91dfa27746c78b748ac95053c2e4e25dec67af7610200000008acab0065006563acb2f012be016f97740500000000026a522a33bdd5030000000000000000de7c7f000000000079413817901c6f4760190513cd9528c741a417b83ecbccf7d51c6b8ed17c44ef34e192e1dd705ea104af272ade298ea752ca10bcee9c4fe424fc9e2e6c5868eadb254d7acb15b6f1fbada7e8cb0c06511d66e4df2f6a4475bc252010d824616800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9b534db00c6fa16c159fbc224480f0b7f9ea366811c358e309fe538de911221c6e31f582e7b1434469869810f548ec92e7ac8066c669c464c8228a0c7031a036c48d9166a053e0d8903938737b7a068286b5e10b3a0ba972e4e8349cbc12fb510b2049e43b2765093a977b1b8bdfaf639a10663615a1134a8b0ee6d1d99652c02228cf8d4741b87f55d65a1fa06666c5a402b98398351666c287db34653ce20e302271d8b2f470eab8f0bf98549d31bcd556324db69aaf4af9c9a036acf7105435a0a266e3b2d70f14292b0a9b998d251d588ce58a8a2b9ba1476fd24a2f21d5cc8df063eb2e6a658e0aefee7fdd4953f8c2c544e236b61d8ca0bcce02965120342a503231f6823fe73769837e65347fb171b08c9643071851f88de95c508a7db1363dc0204baa492e2bdec14dacb66873fc058f48ba205b8ce6cfa83f4cdfeb202f0ed39031563c4daf3f9fd2b554c070241dae65235178bcb38686f9a8849ca72a1594ed3022f4e40d64509db2349f7910a2c516b2c6fb8b6846fefee23d7e2dbf442c6404e0317ccf7f36dec469df1b0caa1dbf17a44ac8b2f8ccc43225b683a407eaa7c9c62a2d0f95f54701b51f082fda924a9d36bef863001eb5196646d21870df253ec86f882410ed81356b758d52b26abeea40d0d4ae93c07e8ab060cb42444335b7f90793e7803d455c8c8b8fff130ef91f6cbc03268dc2fd19a598a0899801c44445ad5462630c555abdf8e3ba4bf6383097f73af5f1ced2ed1fa472a14c66fb49e9ac0c478c0df36e3d44eded36fdfaa8f875d57cff576e96945421dad4ac3841e9d843d7db74b2e13906677d55a83dc40aff089a77c27657930dc3582e39c933d8f6204a1af41690f702981be2edb12b89aa55551c279cc3ade224c8705093c2b14f1974dd463d79156f9d8a4ac77d3104df7833c5d72716d984ef5ae5f8790fcd154a359c3fc87605c5acbad1861ad21b84466f6b5e26433743a7955df2dffc174a4a8a15fae8ff9e3c671414c5f1dbc0a95dcb1d3b7807e2a6abb0b66dc24cdda8d038c3215425076f05f3dd2c0dc9e612038eaa6126ccc2efb8b1bd5b7fd09356b7c77ca97d46842a2389568ff49585765c9aeb15bab1bbf43dd4bb8abda9904a3ea4ccab9c680961830a427e5688fce8d0e17fc20a50fe378c0c9ea288410026a9acb51a2dacf0ac457d02ed2c7d0564962515fd379854f445c7b709ec22c8b16d5fea02460398ee3414da48fb3d12c0f3bbd6ccadd97c2729648e726cb1988e568ca340ca6547475b74885bf806e5967a8d0c5b7eae01304b2d405c48544c07a369bb4d4ab944f9a1e39e4521c0867745b58df1c39422f603af5e9d180940c64965ad772d43e8398a55d06ae421783e736fb2f2afcfbf2cd1049231ccdbed41ea570e4ea85880cc8163b9a8f90f0a260b7d94fe8091fb4e455bd9e8977dd9028f31326ba30a37eae125c1f60e1b06523ccdbe5f4ebb39246570db177a1e87e4a27b7ff11f2f6bcf8e91b0ac71969b1a6ced4e77baef7916989fe78ae0ca8aa5ada088a262dc1201c6d44363823e9ae4f2267191bef565852e4dc613fd1b0f30747ec83705732b16b126b0bd6c5d2455414dc032efed97973546a896c3c2c97bc61b6ed24593d157d42d467e612a328f7cddc7184127dc07d9fe5c109901a9317fca78a675af0c52a51915429a1a1b3f0b082f44142fb50ee24d1e152596c90670674610765bd797e1f14bdf8f9a83552a789359eec463b8fb7910fb2d8f2d33e839bd2c69f8513d288909e3d73ffa55d64ab52fd18396b4880da89ac27d6fb9edcaf7da1687508641253f1762f6397a916c4c7737fbb276d1c1716608423a477d14676e182e1d84d68463b35448d45f2026627a725e3e66d23f12a6c2f470a03feaeffba0c901687ea43a38478cd5bf2b96869aac7961b3efb1750f3e307c2ff8df3f22bbbcdc2c4563754302d24bddcd60325d750a0121c8cb09ea2701ca334b4a58052fad67d9f66b0d0bb543d1640d14a5bc1cbf14ad9cb57971111913d3db7634cf5078c0877c4278369da2e52030aafa2bdfd5af95d1b758d6d1014d59da30afb32330325eef1a9eb74406863e1aae3d83b76deb59cda3019b124aa67650dc20a40cddedee8d3572070b8be660edf4f51f021ec083b0a3cfefc9142a04410e2da74fa8613fc4ab8eb633b5170ea04d4bf4892cc05c854d859ef1636977e7bf1d3b09e8fe1dcaae139743e134b65bfe877c45457e08bd1d4854fb1339ff3d311748ed94a25a4cf161322a8f99cab192d556a040000000000000000000000003b2f4ff6a7e35e8ea2a630b034a71ccadedc74485a1a000df438d7e47356149e2689e22e5fcbdd0757ecedfc1a4daf9b41c99a48d52ad7ab55d20b28cdb0ebad2c101e9af25dedbe12b463322f25f1b6e342bc214b8002ab82216b56ca71d7c6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008014bd7fbf8e741d22c25db2c1e884e15399f7e28a6e3a02f8d1d53bd830f49f21ce413afa307d1fc8446862694fbca3360010ef4348f1eb258ab002e2f6ed88a2b0b56a606c3f2e486a38634503c9dcc3c766e8a77b3eff29326ab81e4268e4329a1a70374521f9e0e94e80585e3d6254474e8707e61ba94e64ff9af265539b032cff3b11e3f7666302bb1fd4b66b49e1c9fa03ca0dbf9268fd22a40efd9da652030b684dd0ce95e825fa826cbcacb12f63a2871634b14618bdba38676ba3d5a6a80a1a5db30b205f30ef7b82773bc18bb5b0901481809a91f2b18bf5d566d3f7fb920a7f082349bdaabb0f6f90caa9b63f9a66a161af42e255b2a6070198a3e910f0030162fb8793f3733aea3f2a0452a84d61f4a83de6ede7297b9fc6c50a792dea1802204cc606085f5a4e7ae3a9f36145f0f04f0e54021fd6ebda0093d6b48a4e8feb021d211c50e5d07577bc7358f7dc27776647d882e7152d6d05e424e082d2518558030800250b8c5b0765672e7b5409c5d401ec8c9a31ed15634b6f8255ef015707dc032d1c7d8dfd61a64410251fc6b4d4b8463659336317c97446b08d4edccb0f9546fa7202ce447bed2f1e77b7264232615cbd3de2955a044f4dd518ad27d30762c61330cd1cc3773616f239bf2415a0f6dedd10163585d1ec4eb17bdd5740eeccb3f190a4e533a093c755572c0c8447c44a374258d0461b88fbf5400770eae8a6355337fb9e3079eb7c0e4851a9408d628a6a87d503c6e6ef9bdaa6c81edf99e177e7e3b7f123a8e7799443dd067c09bdabf36b8023b0fc0104e52cf4b7289cc13e4a70df9046a662dfa8532a914f4419d430c356b4b95fc820d363d4454ae227197dcccc8063438423cc9cac54a94a05316f156360f61ec28fc72783e3416e4f6dd857199d1b037b17a7be3a6c70dfe761a68077ef2a2134a014bf6cadd061d8c65119a54103e5bdf3d7b7aede6b02a37eff136bc00022971cc394fd1a6444ff6054e4a611ac868503ba9d33fe2caffe865d3c20af2c5a8a5d3b864b6b9dcc561e189262f36191c99db53efd9af6b9ad6156f90b697d244205fe147495dc32d7b511a12a593f45742dc0cd1e6f92c767ce0b1019056ffc406fbccf40d6cc5406993e4008d1e5576a7e59c3a8840680068754571a30c9fa59b15aad6b1902b17ac4f12ec448cd4978aa9dd50b67519642426f556e3fc4cd2ddd20159280a9c539f4f174a7278a7a248382da6396b2ece28793c0b38cab7494d43ee971ff85551ef87d3100228cb7bb0e4a34c3d1cc3683654ac41e13a0ed78ec5549f167cc3e75e99e0c32b4615dbd8cc79f64a624135b21611208f9d3b4ab67945b3dbd99013e1c9639cfc984320fcb10da2a6d24820bbea6af1ff278410bbedd898af0f81342f7f2ce2cff92e373877a759366683145a76025c3ada5bb1469c1a186b524952ea1c6ac5e8f2f763a791767e909689d3d21649bb4c16d576770fd936eaa92241bc1bdbd0f7056454a979a07434e1374c74bf207319d6347c6656b867d58849a9a94ae0ec2a8ed20b9833b483e8def0aeb294bd1f382ca8dc85bff75ba4c49773b214bec82018a58ece0dff61bdea148190dc2573d62b64be373c3b7f36a61cd9fd1788477b01261c5f4903de8e8da2b3c3ba1796773f9e2ff8036991094297a0e7b664fc44617390457f2acda1ed5580c090c0db2a0f645a552fd263c29466a1b84b0395786a3ce5ce9e13824c99b7e1ad99fab7e7a5a31f24747eae7f3daf3ec0d84b25598733ea1a51f8b1e2658f0325a8da94184b839a64cc453a28886d4325271f34e94bc8bba225a76ee3d46a64db623edd204e15a6ce8306b095dfaf684ea9d2ea520e077a77e1752c5ab00fea777ca628d598bda4f02a9d439eae4ce05269b05893a073848fae57f20cad8b11042c232c24427838935055c988cc2b4ed47dc0a8d9a9dd1ce861b93beeb535a026fe04d15ac6f8ac955655f3d8bd1f051e293b6e6b31c5251ffca76a2fd2a6ae607d2f7054f96f76136cb98a115fed52e51bda7e54114b0eb98d95596b86576327ce651237bbe6e9ef2fa570d75c5cb39b5ad5f6aeada66d533c7eae90f964fb71cb04d225572b95e44b1efe1562e5613b17d6e09e316b5dee0b127ccdf6b146b47767d03a02474dab43429ecf15a393fc87b0def431d61f5ce1366e7da79df973c24bc53e51006d8cc73f43f8613c2442b01ec264ec74cfc96fb19a1f0cadda0769279b754cec6b3f918063a8b9e5ef372393572f37d80ee5f42b355bc950f8d6bae6e000000000000000003cac1050000000025031e7ca99afa09bab8e4036302f545032bf2b0112d7c8ad4b0222231e94185229e7c6999531e958aeda711f4ed84707311c2cca1c694d937097ef323f0af07412c611abbf178abf2b56186f073187570bc61e9d7345955bd681d300a40d34800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdf254108fae82f8f56ae500f60a52b19ad4d862cc01229f9b280ecc0a588a263e993b0840256fc57dfbeafc297095d5f9beb71d847ddb824db064ef719bc4a50993b813dd492d0c03eb9ba07944f2799ef630dcbd5d427ab15765ebc76b22e44b24104d6cfcca7a30884f4a1e2aa0b2d15409ffe6559f8c5e5e90068d89be31022687a5c53b8492f81b5517484046e1626908cac5f4c6ff571285878907c77002021a425604910a417d0c0bd315d5739f56c39412a21adbc6593a834184d0ac93130a1c0831fcf22f83d8e2fe12bbf5b30dfdca4660cd325fc7240f3f97a6f3600952168a48b9e2ca4b4b2cb2f0ecff61e965bf3a7efe99ea4704ea3aab9d2588c76b03003d8df27ed4e3e125219ffc8bb54637479776bd56d45f98eff1dfc9c50b2f3b0221e73c28f0f46dd89f8fd2cca9979b4142af7cebd54a93dcf8e0e3c6d0625290022797979639041ecf9773888d733229b116fad24d70f6d714d6fb183b86bb5c9a022f85238a1885437f0c9f4e4b969a77d034b7b5b81da76b40ba188a7992fc724602302775f0d7bd63e70d9b4f18d02856e10b611840433929c0e38e02c407008f1c82744b320c466d268851b93392b88fffeaae42e3e40a039e094faac1db76a437cd136050a8cc9bc017d79fbd7f4e5df406f764059b0c8be9ccdf4410e9da30d5073ddaea386b0a8375b86049f8d8e717aace13102cd8c1c21eaae6c5f3bea72ebd5d0cfc1892d6a01d5c966e26f8483fc5cbb79c0c8fdc7849ca99c563b331c420ecb5bbdbf88003acbbd33c7d657982f77d6b57672ad735f658027b931207da8176bca3704e5edd183d4ba9770a597aec8424263097a2d6abd3d1073c473bccb1dd26330f7c3c7413f6f43daf63d74baca3c20d51f25c81fcc8bb2cdb1102df73d8ec13a049f1a063366c46fa3ecac55889e7fdf3c830fe21d314ba5cf79ad35043951b613506becb34ccd854384a976abe008fe5561eae6b081aeec8a536e642a858a320efbab8fd3b3764df12d732be2d7b9dec300571b44dc34cbcbb1691dae597f0e9f4e3c019987f3e04d41024d325d5b3eb0d7fa7aea2d0760b140e3f21dcf9b44ed21012fdb16420edb9573685681fab94d5e2792fc2f4b260693fda7ad5f054f3a6dd24eff0eff16b22b2571a1bb1eaf321fb01808937537efc7b8d3b439f84b58abde01dc69ce3da19a25f894396a0dd8dbc9865bbfd72cb52adaffb6b3b7ae4c25ebff24efb0ef9bd65ce1e407cb280ba03a29e2062b8d796bef73621aeb1c0ee7cfb77d5b1df64f3d9e7a438b8ac0cd02491e4da4abdcd990d9b0002a63d9c24c1450f85ef96d1a61faca03b0fdfebfa4fffc7d2e084c7b070c9ecf0f499fa937f6af9e54dc8f9f9612e579185e14609a6ef7376917d60bcdbe7daecebd7c175675e8c839d672b1feb7f623815af7005616576eee4392d1f31f9d3760d8b079acde637d66d858cf7c9596880e0a82c8d2351206d7f71e4ccef070ea14365a81a2888e8ad5482335770d262c8ba3c8b44fc486e5ed1a5de63802415b621b82184be24213c72992330c93a7959a93705f7f855d13d5967395ea99cf6974c8c13d60f95d1c8d5688085832e9e388ff3aebc4897275c98c8c50974167a5285459256beca0b32da4456cc15d4a16be6571f135d440709f43b03c94a5f2932d9307a5800da7fc5bc2bceb77a95c5cb8cf06847e5eed64535ccf7cc896214fba46f8fd10e3cb00955a9b40074831b5ab77b3c05f1824eb80641e3362af59b800960ffb5e5b44de302b3154d3f7d11185c2a62c83de59952b140bd73d57724f6258b781fab216b0439f983a89da4f8882f6c8c850a42e002321fce93bccd4037bbfa9e5ed538fac4ec0dd3e025ca37a9ecf231ae88434fe31163c2707b98b776f6fedc7bb3e501e450209edb31494041721bc3838079e718f9be043ada2619ce63988960b84d68734e6aa945aaa1237b9d7e037b4ae65cf1012d88cb073e307fa10b550d6a5c1c43b65026f4c02b80439a6a32d3f61325b79f72a61111a1c4f158540164050b36a5bea1ffab666cf086643220ea57c69c9600b4c75d1e30e764e9bb0314ff32feb2c253381eef1d3c554cd908218782f66c9ba53416729779e73d60e88900dc698ec386f61a537eff9d3444e1cf2422e11ba5a835e48c61bbee69213ac9b232a793bed092f5858a43af8300e47cdd4c0e58cb705529317b491171685508a3c67cf0325bf70907616377f090100478445efcd9cd795c5b07945a907d75ed84a97c66a4a257cd91649456fb8f9d04d26bb10f5de8cf45b48f8c40a741f89d99ac18a268fa3ff2727a3d9e579dce195b0238d00a82ec332250aced67c502d2b8fa72ddebe4067fe0d7cb227250d3b760836d66ce43165c126c6fc50153c254ca3e0358e23d36e1c829a10b", "", 0, 903307813, "7faca3188962cb36c245ed8ac22175264ff732d0cfa840883a0fd76f3c30489f"], - ["16168e5604f3f18f9f95944c2c7f614796cf454e347ec2413807fae3302c568c7df0644f860300000008635353000063536affffffffd1fb1f0fac0af43355c0e21ecd764966b45b116e86c159e6013781570781c45b0100000003515363ffffffff56bd2ebe1470fe7efa49774e289eb7fc8e16e7003cd2e0dc127928454c3b3e190000000001528ab954cf834925d15108feea22fc117dcba7aac68cbb8bcaab77ee50112b1cbe69a855390300000003000063179bd79d0274c23f000000000002abacff550500000000000365ac5166020687010000000000000000d0c55702000000006fa58d797cf9323c1cee9b09fd09aeacafeb894815465f0ae225ca3caf671dfeb7795945088b4b481949814e44a667782cf7c56e2420b24eeafb044d10d8e81948f915c4c6a317706ae3a49e149a257a183dfee59b205a668d8cc660ad38a11b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f447d0db0071712b4b0c0fbba0761d048949472956b9e0a69bbf3cc330d101c1f6109abc82c22ad03bec0b29c48d685c6584637368d2bab93ca9c7e5847166837683688d8dd7af5a93a061920d3b78c6a8e796f31d35e7949b5ef197de73355b601627a866a267eabb812a8412f41692e1bbd62075cb5b5289630c254c101078031a408e366c3d1f0f12293231486970808863a52032eb889d2a308916ea78f14b02112ab1b4026e6966634362cdbcbba7b3726a875add9cf68ccbc9486f7a8ff28e0b2042ab9dbb7b7497c2083f759ebc0236c7c2ee83562b0af122535f1970661fc009ff7605119db3bb1b8d7d2c151af28f42f6aa9e25d12162bdabd60e744257df0219235a7786c9c0fde28469e438b1c64e843ae876866b4c9c55a14eba4fd6f3db032238faadff841170fc09d67763bb5eca136be76aada088c102b8e2bcc327a9c402107f96a8a0bf0799b4c4790909b01c4495412d004450939a7d6334d2b9d3b2870225d6f2cc7e578473083c1d34cb9aab03f56bd791771c81fd30e7de16d7b7937602200c3790131a2a32829893baa53080c3101f3883cbc4d1bd922f99d603ad741cbf347eb32e6050f16f7898c969faf0b10229c8cf17e1dc47fefd3af0212cc3bbc89364fb21a2e951a75f75948bf4359386f23aa5bea2797034545d9bc6729ac8224ab37fc06caea3dec0221d95d9af61b69c66b9b8b04784563c85b46b531472244c867e66ba44b274161fdefd5703fde7650689be7889a830eae605dca322460a297373b3a4db53a4c7b23c7533c044cf7adab1387683be9ad9806f5d6aaa9cc4f44e66c4b905689c627021012c173a03b2703578c634c491ee6e21d2da498f0b2d62b0eba9c6184d3fc1bb75c2e2041e68511b7cbf2daa78d2c7e5d0365382de9238347cdbccc0520755e685ea10bd415d764e89df7be5b03a56c16f1c23baee2a923e67ad359d2e6eaef397145acf8dac59198bcbd5e1aebb675dcb6b72db959597bdd61a8414d1abeede9205f7b86529986a6574fe91d35d1900ed7a0bc9c32789d20bb61ba5090132bdc673bdb28cfbbc9b8213f1f7c96bd2ae2c8b4b217ea9d2f5601616b8a7651808832a32bb0a0c766c1179fce3b440a7ec7649149ecad0d4eb92444ac9b63d2d288868589656b6cea5638dc0f1e427cf512b1bc7a55f6f41b54b672ba924f622d3c894dbadca33da0439ec5240a13d5953c659e6d39f4cde70035ad19a0b291058d5750e5252a29500192bf456be9f83dde561009ad17915220c1c68eacbdf8d71be17d4beeb0f5b6a143d46ef2f1665f36bba1e9534a0df4e3847119bdeb5be0b3f1d5d0dea8358774f09579aae17e74d81f2fb5a2113b5f1fceefc027cfbc7e4e4e6b4b1623593863efac5369261361fb23c63d48e6fbc7e7919477b7ee71561d447ee2a1cd65d608c383bb45de7fe70298dc77e30fa99850dae100e4a883b77c4589455f45e6e6ada287da8d5aca850902a040cfa368e28db6420ba7bd81124e695fc334b6d665b704ad48264208ffd358d5f9d0c5bcec817c63f581d8c444a1e55721b4fd90aef943e326f56a88301b9d5b1c9b68efba26ac3e6ab9c52b6f7efe3f40f5f13548eb063a2c2cd05cae1b5d2932d8c7ce9ebccd82a0596edface486cab83a5625e362e97e13df03e0e5a7c13ee769eeaadd601aef1f4440e332642c0107dd934337693433deb41915c401eb99fa361ff8f18cac6086207797e8ef5492ee44472c72fb31e46c563cb6b57b44e4eb5818fe4aeff67d8e588360d83de5d8a45f53226a3b813323d96222eccda338f489d4e40a48aff3815f48ad96b533a89d43ecf017392bfe7f1fbac2f7c3bee788fbf43594739f4761fdd4afac507318fc0a87d948de3e8b966a4015477959264572e15c89d955c99df13bb03943c27908a2ff994f74d1bb6cc0ae3036f46ba2769ef72f79ba2d328a62a45257ec768b28c5053bc068b8327f6d253cfe1cb5d24cf216cf393535aee68b6807b3b5edb4fd81774f1ab590a91372acd1407f39840626b5fb45e758916ea19b53c62eb03472c139a76947c75e0a8b622ca72feb4b1972691dfc763cc0f3192698cabd52bdde09b8f9671a93846126305fd153f06e41d8ec0e4702188f2be3a13e529ff0e6238710ef71eef94e6ea45c062357cb3d65dbc6c78bffec437bb39a9afe75215f9e950afce606df5370a65c7c49bdb3b9f84921aef36e246b80a99ea7f83ca4c5f01af231cb06b4e5e25db5f96b61de6de62159192e45cf44df620430946557ef900a9231fc2ceddadb79e7b788865b770fc3112cece0dcc21c8bd6dc81992d596cbc45392ee95945973cbfaedfa7deea247561868f869defc20b80486494b5ca5b11598ca816959eee32fb67c7d5dc13a61984db654ef4029719a70d0677ffe79db8b0c", "00635352", 2, 1001794760, "4fc778e0da9b4b3ce1649e83df9855385b44b188627f0e28c980d19ab211b05a"], - ["2970338402093b71c16b0a23c41a448cf766380d046ff060566a35097cf7c1290e0f4715310000000005ac656351abffffffff5d23358c08924835ec3a876fabb14fadfc31f0f687f1f879ad6b7836eb4070b002000000046aab6363ffffffff04cb4c0003000000000852ac0051ab5152ac1673b8030000000006ac636a535365ed1da003000000000852ab636365635300555a970200000000086300525200abab6300000000", "6565", 1, -2075150975, "d4647527fc5dc9a6019cb37f0020554551657189a61fd84387723294970b8a5a"], - ["9ffd779002b4cfcbf880e28a60d877abd9550fc87a1b25a257b8ee92960fbee9a572c911b4030000000200abffffffff15cef9a7bcda6885de240e9120561b01d7d391307b6eaa8879636dbd8db99582000000000700655100ab53519c6b238703c810920200000000066300abac536abbe4cd0200000000036552ab1585f10100000000090000ab525163ac520000000000", "63", 0, 340739621, "ce554b552f70d3a699557cc23e36aae4463c01eb6096d97f1659393369bd07c5"], - ["ec624ef304eebbabcd8f4110e06c12baba3b09a13e6824ed3fd3e750c2154d01b88dddba14030000000653ac0051ab52ffffffffdca2010a69c6e499d0a3084b9587c17afe85b272f3b7f240a41aab4ff928caa40300000003655151ffffffff7a8bdc820666bacbbc7257049e79a425b2f2d1015a21f8e95586aabdcf671be301000000076a526aacabab51f3bc1f829ed337063ebcb09ff7894a07098d7a6e9f9e8c885421074177d514e181e219410300000001acffffffff03862ff3000000000008abac6a65ac6a5163be13d803000000000853ab0051ab536a51d31f9303000000000953635163516a5300abe6e5de7f", "65515363", 1, -259701290, "4c1c0c3452b6b1ec6008d3701b68724ad8b9621247094c31beb9d54e0ed7c252"], - ["4588794202b8043ba4a721e03bbbf9691e14698317bc37ed49459ab67d93293a7a476a557d020000000963515300ac65ab516affffffff8cf0734111c5d05d571941265f588cf9e0a8c395573e0a1cf96f5eb4ac08b9cd020000000563ab516563c9aacdcd0326548e000000000001ab0e7f97040000000008515251006a6aac00e9855303000000000463ac65630000000000", "00516365526a", 1, 1014952118, "10d26763e7f0c573fddaa0af979a6487893381e3f877e25beb6e2788210569b2"], - ["f3d8d8820122aead1599f08730bb84e4615c58e9d8d19b27d4744779de21d8848ebcf426590300000009656363006a5100006affffffff01b0b9a00500000000016a00000000", "6565", 0, 1627452599, "df9dfbe0523c14792369b8db42c62b8b51889f7cf358144f5ea192a7d28c840b"], - ["730b96f002cc3f4c89ed24cbfeecbc1cde91428ddea1d437eccb01401a1d75e26da34ea4e30200000008ac526a5353536551ffffffffda6e50d6b6bcf7b8b227fdf21e9228fe65522fe58780a356d7f65dce0561cc290000000004005352527e8a1e0f0295e6c1000000000009ab65ab53ac00ac6a6a5a7dd400000000000000000000", "535352525265516a", 1, -794700861, "a472621c06baa06f032391d1c287e1dffc355ddffeed064aff289e558b156249"], - ["602aa4d9047d93599fb919cc55cb861bdea2afa0cf0a3113d080c9e0b31a714ff233f877110100000005ab65510051ffffffff7166c368d4c5b31a34f34861be95a14de71932e9dbc229c79cbf17eb1cc5c4690200000006006a63ab5365eb19f32f09a02b7d2f776e13f77ae5a7ca7362ce39eb242382365eb198228a8a06232e8b0100000000ceaf4bd385c841b35f0eaa68c897a6fc77ae8da7fb0953cc88387bba1822a41adb6142770200000006ab006553636affffffff03314e3901000000000263ac180f380200000000046a6a5351726045030000000008650051656300ab6a00000000", "006aacac00ac", 0, -1388646795, "950ad71d30c89ea92a671cf75b8648a19301baa0585123633601ebc7a297fd60"], - ["e3f17c6003fbdb73ee4e785a840c95bdbb671dd3ee491eb733e4fed535d6c300698f1255540200000009526351abab63656a51ffffffffcbe2eb737bed4af394463993247bc9f403ad827524192c92d97078580791cf9000000000066353655363538dc6ed03fde75133bc0adb813790232650f1e03a0b2059de9342dea919b5bc3a7729c1650000000008630065526563abacffffffff01ce9bd80200000000086a6a6552ac5200abb20f4d0d00", "63516a5151635100", 2, 1131340203, "1e88ce1b19580f1d8a285df3b620945ebcb64d75dc025c25f0ddf97e14281b00"], - ["4fb51b23047d4236e833d3cf70d65c3df208f45afd36c581e3d832b4c100cab5a57b875cf0020000000965ab535200ab52abac4d3727475cd781d1ee4269d999a0a54ca1641ff57e70f6e42be284fbd2942eba18181db100000000003c6627b513f340029cab17cce9910fb485145d9e18c1da80a53163b00056bf5b5e5166a60300000002516a8f68ac934f9500d71ce1a0b55b5e4f838222326324be16f253a81af14da3c2c5ef50478003000000085200acabab52536335b88c7e032f6f4a040000000006ab53005265ab953bd7010000000005ab51635351b11d5f02000000000253ab0000000000", "", 1, 259841327, "c462ef448b54e7ff807cc0c7d4bf4eaa28b4ef03dffdfe18d864ec0379607d53"], - ["054fd8220111440577303defac7dfe3f2a44153e6eb2df8a8643e5d64c30e8e06e67928dea030000000200acffffffff03a22a790200000000076a63636365526ac2d84a0000000000000d345702000000000152e000e11b0197ea200100000000000000000000000049dd97c238725120df6ffe847d8b475b2bf83b235ca1326b052f77e9fe1f5362af98baa95c9795304432a728f450fdf29e673afa67e82b7f4c4af85717d59f247e969fcbd30a4fe5237a0110a8c178951c58dd0fe9e6d763bc3cfb01d99f135800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000206012236dc9b4157aa6af4c9dca2e2ebe6dea25497e44e9692a4b9c3aad507181352da129995dd75dde219d2d3ae883e81496ca9f850acd26a803fe01b0bbd10d74ab025c414f2de67abb48ba71c0d82d0fd2c00d2ba5e8b571266071872e5261a09ca530326da5a94c428d42fa16cf4d75b86849a1f6dcc86e30e04ad3672d03096baa8f270ce36d9974216a51ee1d5638e25e0d98e083fa7278a234fc1220e5030b3dcdab2e0ae7954868638a399e8b99f84f67ba1a48ef6977b5f8a8054baa4b0b2122f049b2a10ff1ab0a5f80fad703f68d01ca8a7b21dbe0ff90a34a10b64d12007e66db28fcfef476d264cfd81a3826ac1b032d2585a3b4e23852e7508dff9b02278b50de5aeeea5e78d090fa1b131aa558ef438c615425a9314292b07d21da1802134f99b58a9af5a2b296a76d89660e024a219ff9fe18cbc89cc040a42d6eb2d8030062e7573fa5a2aa0bdcac77d9f65b8dd06851edd834cb2b57510dfa55f8f2d70300e90d5b44fa86b18bfc742c35650a6c9e7cd41e80ba46721e18800d4c5b0843020de7d615f3448c0eec49f38fcad618e05ef3e691d3f1913f7c4fc34f4ac1f0ff20cdb8a26353a4b12915a58610995dbdf34f9c193297aa3b5a0f5b01f05cb6bf67ed5f41460c23ccda05a428404df5e48a55a24f7a54a74f78a668093caeff6dcc312c9c36ce6cff929ef98de8290994981d276ec23f91a614814c06f35faa292f527906379b0bc07e918d403dc4adb43b654387cd087406d66cedb1472e3c78803fe1618d2e73799d85143b85fba3961544c51a996cbc4391509094be6d3d141b38d15442cd2710fa5635ce07ca3149f99740bc1670e00e542ebd26d95de5b774658b1f22588ec91675ebd86bd47fb631d8669fabfbc67b7951118c538e03c50d96b26bb118697f43895f44ac00a29226aeac0c0279fd1be88432bf1a2a372c128a7c59b8f4cb3639670430e6640ec97b3b4b70e9fa981e8f985b5d93ba98e00a3a9e9aa0796e16926b9200530735ee76fd191295d6380cf778ea2243d9fc8a8b65b2f3c0d3ffd34dc64032296f15a1d61459bd518095f01a0e0c6f49fbf3e88b4a3806575bc1ed52fed382a0ab7dfbb5d98021bfafd9804dedca928d4c9db13a51127570eef4e2854f1148be70b0491883e9f451799bcf7f9c2ffcfd54fd579937aacf4a8924b039d8703398e0f94d3ea31710ce5f5495defb867b076a958e3ad42685a9bdeb83babf553b31649a40c8cef34f8296ca497ee03172ae68549b727c2d0cdf6960d57074ab507d3916c305a3e68c23ac6673019edff5551cc75596d5c94f9736476c524e3283231bdf36b3e1a2b08b494b8a87f1e31e2dd80650e5573baa8db3bc6895c8662260e73380a9b5fdf13f19900fb9e3ff5849b3d0998e62d6080598d23ae8b38d9884be12336b5167f12e5c6f3cf735aea9c2bbe5fb54327be237608b992a7828bf37dba32899108665adb4aa8864d64133d22d79077adf87a9f8a350693bfe26d68cce1ec344241797486739f5e05cd95543fefc8428d8f7b1919c8eebe9d19a8e920ab6b263a9c6f856d1331877889f6f5f479b3e34f6ebe03942592e6d4273c485370db2634b9941fc000b8664d3703bf131c8ea461dc94bc8639c9c4dde4ce040139baa2e65035be1df642f0be20b845bf333ac29d420b3beb50df165e25b3f019a44f7d6704b2b776ee9602ea24f9e475b708c0a842dbd5fe575054123d9642b903e1b562b95b127de8139e215df60ec83eba1f95a26a9f89f771a787f7cf6221a08d8fd23d566e20a2010ab6235b10d705e5e0557427dab664fc519d8d25e06d2542700906304c6f6948aa55289b1a029454e8cd3a7523a140b014d4973a0656fbceff833b6c8495a62808f1b54c18a72dc5f5bd82e7ef4288b7cdf66cb33ed12f7a3299c5bf03b10dd13b2121285df8401cf5e0df1eb3d8b4f76d3e05ce9c3f295f95bd7135c796986e6c645b04b3546249ae38fbb85c29426fa2a4cc54cd0b77a202d03babd74aa60d507078b84d0ea8eb5d85a86968953e663268627c01998bf1f7421452a88c364f976396ce5eaf520d7f7d7f1f58fe26923906668c8e0eeea24bf7e9a9339abf8bd56441d3999ef7a2b5e0babdc7a319eca64dcc197493fb047daa9d0e0f231e9f006dee4815fb15a6f4eb2b63732afa9e1cb4203e2b2d98220aeb0fd17c54af33350958561d612553a283b099329029b80162bab367eae5f97ef3353062521f294edf5f7994686faf08130a878c1f66698e1f99eaa1f89d19defd7f8217a5b7fececf8202b970c49e286c566342d0dac611f82a208a3fccd6a3b3c2c45cb402f11eb5ea5c12705d987fa4c3d2e18bb660ebf3b00589e289c080c29a249c9d7e5cedb9e50c4a02a91dd7e56a59421c35207431c78135dffd2e6ce06", "", 0, 2070529321, "f16c97aeea9638f40efed010227179bcd6befd1430a2d5f566d8db475b87259e"], - ["9815ba3b0144295ce0a97a2e8b341b49478f8486ce4dc50d24c1977a9bd4de84b245fbcba3030000000151e20505f5030eb86a0500000000075351ac6a535263172dec040000000007656a5251ac65ac15426203000000000055ab1e740288a1ed0000000000000000000000000022075df33922e4a0d6ac332eb382222b8f9cca2cca91f406d64e6f996e751882caf34eb93672baa57279930dc252f233a127b02af5934bac8eeddc9ac17c39257dbe36c7e631aec1671aa2d9795e9ede40d34bc5c769f588e7ebfddf228be3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050ead43b1b21955c190ee223074020543005cfa16237b69f2c7d2008bf56007bf90c46b0218f3150866762750073a306c3875f156a2ac23f2b9af89cb1d95fa9603392f24136b8e7f3372c24be1bec7b26a4d0adbd25c7f4b991c8982b57eb82efa20821614d9b0165c42f01524d661c3e2ae52c249ee0d1811b7b95753c41a503275f6cdc22415e297ed98c7a6514fc96ac22ffffe76847138594426f41d317640300d5ce107e1093ee69e704e249aae9a03070e6de6dba62ea023a734d5ddbe30d0a04b351db11a1284d86ea4e886842d10717e45af633c4131b5a4029a1b7c31bde0742653e22c27c63ec2832f44d6405c450254d3e5c8aadce942bc8ac9bece7d6021ec545e3ac9d0fdce35fee9dbd83a4b02012b7dd0c11b4a87c3b92ab94deaefd021229ddd27216fe70d2f990e71348680302ceab8573bd6c08c3a731d30518b8a2022cb1ba8b3e3a8ea2f192562db1acee61c2d4ab7a26654a54fd77c4a26a7e2bcf021404e30ed0eaefe30e3e037b133c37f616eb9eff48cb044714c67b4f5b5d79130327b7a585a124f9db529e30cf17accda54a7f6493eb5bf455a64b179558592550e7a2ec04fa8847b950d8daed968fb5cb634e24182ced22d4a9e73f88eeeb2b8d9b93dc6d85b2f7ef0e5afed3500978d3c9c554d9fe16c21372fd38d98dddc2a2d9981db39715d9043e5e9cc257c878f1263b844e54f31fbc8ed448436e4804a34c63de188f26551d1c41826ccf23f76ad6a53364fd8dd9b463090ab45b1c971e8a5d097e46ade38075ec9edf81ff463e3113f12a875827abb364b08e92de2f226aa6afc6bef186593f92b6c86d06c86896dd87379b5d098a3f1115b712ba888fa99cce5d37bd11c17ad6786d9cb543991a65adf88417d1a6abf441bb33185cfb9d1a477577d203da4beae0b2f239165e6eed7f8c4c0a6fc1ba4274f99e22be26c1ba0d4377b9fae4f86434bc8ae8eb4e45258f4cd22ac8f1cac2f35d0b21fc3f4dd7de661ee8de4fce713b914ae83119e24107558582795f1410c9c6da94b77f741da0c57fa457356e54c5653607b26566a087e66a87fd0242732e8d496b4bb990190872112d7ca8c3b3995e05953438d64032315ffde74d195dde3f33efc684d11357b70b30d9815379fc2a29eec88d6313d8211d55634b1b4512d40b917eca82056f3b90a3c9a76b773a61bc962d62c83d415922e01a82acc81bc8151710910523e543af91b5fcce9730952ae25a3c199ff60a47964fdcb283414d7c748781bad7c07cce0768234743d7e80cc9e8044cf5ef78f2b0d0cbbc644a40dede16d5d370825e8c489af06a507276448f0685fe4e3dba277fb95fb55f61506590e39c4329f84b00cb30d1630777b6fd080304f6375aae081f591d42603adf7c67391c62eb8d2f5a6d8d634c4551b42bd884ae7d92aac1a7b08889a254943103ff067f8f60f5314cf07b8936d0f60f8595ad88f73e17ffa10431131e81e5ae81687873f95b54a416c253778fc3b11dcab99eec2acec7fc9f4d039662e8835def6124266c54f2cec434098ce9b08608d24d43980646c294a83d217bce444b866a5b942be465f42e17776358f8e432ea91417415e7f13a58fe688b917b5151a30eceaddbd0a28685d11ab753ca308705eeb2674aa6e6fb62219225197079ccc45a78b223a46a411946e047d0c6f7e3d2bc2503e74d1680363d9d52c47de6e7e5bd892b807cb1f93e84a50c5834524e947dde8ed6166f281a359baa10484122d3afe76c42063a48eb296e061be4ecc368959b7f863f0178cd242f4a81e48dd01d41ad76852235375774ef6aa606cd4fc5f9024a57658b8d5ad54740ee603322ea5edb546e81bd94c2baaaa08ec096af21535b52e09157160142a01136c71a9190ce0005d0b3969bff42d15a24533dadf1e510ddfac8e957a89ea449ee652e20588c8dd11bb6042e4a142d79b4a5628fa3f49b661c613069d56a9656bba77d280b8bee2e8ba5e349f370861be3f9d6d488706eb7c753972f1d6a13058faf90c4e37bb69a248ea465f707654444173a6f7a2a3c7dbe4349898ecd19b6c0b3717b6b416dd694ec9781c38e9649fa857ac163f5689c2092135190d991fa1b6cc52d716a7712767c925edb765eeffd1646832c6749bc2697cd019f64afd472c7c7bab5305669250ff6ea085655086689aad3378315b98425a58341da93d9019500c1e9651cd78f5668ddcf4dbf10ad9cffd9c39f3ef28b89ff3f4941bcd64d182b74847d0c77cc64159e518feef7582710a6b5f8c7fe038a0500000000000000003e0bab0400000000a4bcbb1db2ac10f645bf09f7eedea8fb85e7cebf9719edb6791c1b264f1351806f8d4956d8732ee81ba73d09480b402ab245c10c4bc0f396ea47c0d09e82ec9c4fc93dffae8cd4870bc22ff0d3fdbe22bff109dcf0f0b31f58ab26734039dead00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c31b5bfeab70a89e9f1a2a58992a0660d2e72e373b1cb6c3f0f6ec8077dc36f22af39526c5f3b6307d8246f9d9d6c8d80a36f40ffa5903c819f88ed3a44fb349f5b552ae2f19e294b36066db4dd95b9bbf6ae08d501426c8a984fd645ee83226c9087a9449470369fd6c26bb924a1f312e0e5a181219322d7c623bf0740e554c03234b1e29112a734ced9d078a18f79f1aeb1ddcae8f6b7cc9cdefc41f97308414032aab2aeba9576ef162968379750cb096fe5fb507dcfcc6acd8e72cea7544907f0a287cb271f0776d2393dcb1dad076c4262cb7f4789c58f497b6fb959181f027e808af5752a9e9578f5c7fe174d41cda6d4b29bc3d4edce73ca9fdfdcb9a30af91020dea01afcadb2823713553deb64f478958593e8fbb19b3cd6789482dd775f3f2020883185705d8e50707506aa9eab8071ecb55a0829f5332f6959e546c61ab0a2e0221d2daa49e3dece8298214c3419d8f6050970e6e76e4f192bf6ff7c0240ef529030b8a8d0b7a6cf9635453f47e306663c2abf62e51f9e04e8bbe7c6134f9704751030a202799583d9205055c081e9cd9376af0b1dbe5fd53cca403b00db4f19398057ce89f4f0ac016c90dd76e4792027a314514890332d26a7097f65d57b1fc295934ba676a2d634c25d5897acff070e1cb9f9d0355e63c66872ddd2f29cfa70c29a1295ed0f769cf0da02345defb206c3f56d8aca4cb45e2bb2a81d6fc6317dc5d7566988667609bcf1110600a19474c7b837a0a5b611fcb7bd4d4f448db020b938d512eb91e8b428aeb9c21bbc27c3b826c57fe7bfec9728b9c907b6f81e1c6cd37ea6463d86e80ea57af2b18605d9f9b56d9ad5dd7708ef12a3bb3773422329e470403c39ca62e6544c143d1baa7624cd481910bd40058c2ca219e72f7422a21893a726f00b817516c7150bc7975ebacffbc816c8690940b3b2179da72422b45867651a547ca4be25f43157a95cabb2b2cf5c9d13369fbd79fb8e40ac2c998cd0cc90037a43522244a449b5e366b94acbdfb314bc5295f7155db597ed59c1c1ae442aeafc1110954947759c2b4921062b1e7d84c4fb2f886240767aa3f858bf145b33998281b417cabc66b42f0fa27a4dc877ff9448257fe848905307b566b46220cdf6afac309821e063962f9f41a618d0b217fa39971d63066a45ab43f5818956603b44ebded0ee883a39a46451b6c7588593e7517848ffdca0b4b341c1857d732ab3f67004dbb30c7de8474e03c0df346f97ba5c6244f0b55a637ddec3fc22538c4d810e595b96de3ba11b2a68db889abc6655c297aedc75723116244c6deba23a57aa6c172004bea8562689578edb50308d2879762931ec43aa7984ef7f900e8663f64ba863dfde5c6aa57f0461a8e77901b1eddfbfdd12f6edb783232b1807f6d856ffa3513ef04765f44009b79d64d49ce42fe4fa7380e00704aa0832baa2808539ed6ce68e7e528cbccca6030e8c06e84c17e40c4ffa4d07b34151a9b3e9c13e3aa051827d830fdd774cdb323ed8c24138fe75c85522f600814352ac6e0b9282c0bc531b375feb94e3e6afa82f63799463d3639e57763d24561b163bdc32eff774c8794f9a4ed53426f130131aa6ccf921fa874a93569b866fbfa0e4c7942d8451ff27904883ed569cdb6070329429cfbde0a7977660b6d911004a3a830dda189bbbe703e264f19338c4e919db148e3a05403b8a803edf45199b505d50c360d34558c2c2c9dc2ae60838dffb3b9e67f03972f27082f62777035fe4e311a1b35a364beb30459f86934efdfe42c237d6343a46065fd68858eae73f060f88421cc214ce723c3419ab468ebb2524838626857a0a2f20f33876bac4c444d707da115cfe83374a3fbe421c8619826b9b6e513e3201c0f2e9e7ccecd637531a17a1db1979b3167d8a37f50da5b0f7bf5ffadd85923b6b61739ed19dc7b239e0d6dde28488016d7bfb7f8e7a8ec60ca9cb45ffe958b1d0de14d6cefc31d2298966d008bd6b8a8aa5c8db97792cfcb1d156da3d60fb03e3b49e49fd5616d262b70fa04c1f4f28b112de223d88de5af7710ae643d11d709701acbfa25405321fcebb72c8cc21f5923dfbe7cd6243afdd0f963212f955eb716e55a88708c7ac39aa98f3bbd80762a2f7751df7751e4b3ab1896ad9975c9c73e4254a66935b2602923bd4029d6a6bf1f78739992c7d8b0a8634ab50df74d42457ee996dd8c05e8a2c8ac41761350a7ce29229065d6ab60a989d3b1224099db41c14013da7c3f0bd589e8cb84438c1e77571261226c3b236e25d6fa51d4e99c873860ec13aea4ec7089aedf711b21efc1d1f58fba49057f0f6a88814b2a6c5c999efc5003554d66879c2ab2feb13128ca77fb996b162d58113deebbe02616992956da5b436ceb199c2b4121249467def4abe446cfb38592a32ceb07", "516a5252acac53", 0, -1253002160, "06a11dd91b01b190705f37634f66466ea26b18dd95ac3e515375c64aaabef459"], - ["2b5c6719040c3d261fb8f6cce1a8f216d78058d63a581b3bea34b19030d15dd74e892302d9010000000852abac53006a51acffffffff02ad7ac26fb207e1cd9161588e364f0e77154f5a9581b087f544b99b19e4309f030000000200acafce2aaff20e1f4ec89f4d7688242000abf9c4843034235edeb2565f8089a11011ccd70c00000000076a63abac6500acffffffff94bfd1d3b3ef1a7334e19b1f7b7a9d37c8f4da2c4ae881c3b9b1dd7482dd0d330300000008516aac6365ac6353ffffffff0308c3bd0500000000075353ab53630065d832d9030000000002acacd91e9503000000000351ab52b759d631030000000000000000ac69220100000000bd69db426809d6840a4469cd58757583fd0803452fab79046c96beee219c38f42e643266597bbbc2c838054beed103c400d36734c295b61348827e8805c9172efead005763ebadbc24ac1ade27c62985ca752c3e6bbe26979e0dce9b1d4ef07d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a3d6fee38affddc2c8d8f99607ed97a564c041e2c30f3ee203868ea86f4b5639b5c6ff4c62a31c931926f19fe434e844bf2d8b71a8cb16aacccfb36d440bc599809063eddde75b91b223a2fdbaabeabf6960db1743765a577a281f4c74bc186d82385f56a514c2119e523f307a11d280364e6c56a53408a8f29045d69c68d4a0321a702999605b1c810f3b750d12a82601e305b22329adc232615e0bb7eef306f020a5f10538b02841d02106508c28b9f27d58eee4ab0d2b13b4c11cc53668fe40b0a16e8e8c1c934de22c26e66aaffe74f98f8289f1c61e015321c739327c0b6d0450cf636e51bca3cc513114aab0afba049af60e2c6ddb69244959dc15f9b388203030b1105860293ff7b61563793fdec62f1d596a57bca347c92dc0576deef96284d0325a78fb1b96e898b4df7e331565ed41ae79f917e949dc0b532f32b8fa77a95a0030208b2b36ec9267d438bfb304cbc76de42e31b1283f21dfd2daf9438f73897940212ac7d3738e41e16e7bea844399aa7912d68022e18a3a8aff91db47a7b70300e0216fa509b4870e7286a67a010ada141b42e3267cd328b8c8109c9e64dd841aa94ea69dc5365c143fa53084ee32155a74b2a6bcbf4533758905949c10b23ecea30fa300d9c5fc5de42a7ca850dbc5d1ee9cab7e94eb391725e5b79549796a13ceb4abe4bdac5d3ca79ca8fbac370a41e27670f21595b5ab5fa79ada67299097240a19a8441c5345b7dc9c9b5cfe10114f38fc6cbd341273ffe208fdfddaf37914570afb052930940d4d70ff3d3947a24b36dddd57676647572a3c506542fcc8ec060fb5d4bc858fe26db921d94f51c9eaaf6ba2f270cf62819cc22823b8f4e939db77b494261fedac5a76041b9a20c427ddc09b154a13053c006714e6a782a87b36659e955c30ec82747f45a1ba082071cc3c4500f7dc4f4a74b52b017fdb6628e669186abb4a0ca9af1970d54b05eea2a5e95c2b78c38e519544ce9ad67211e189789dc57317bc8e74753ed858f295b4b4a1e164ae6307872092a88b53d00dd2552156ee8b8d2cbf6cb8ecfd8dd42e1570c578b996cf90303c1265186984f85905a8e9e76902e6a0f1d389c0d6366ec1aba2e73019c50ff6a4ff316bc9875082fcf6c1e4702eab1d9ce95e52e2223f3baeaa413d6affa098285b91683eecd9dbf38e65449867f330ac4470c392fdd8ffa23c951c769c5a8fbbd48b575bfb87b2408bf924d0352626f68be0a0a330aa4d366acd869db9a66208a08265bd4baf1007e4be5acc8039a87f52b69e8d3ff074d93500298449ec605ba28a1123b749a82e35309ca3a16679cd06055df7cb982094ab2198e19cd4f36631ff14634e4d87045a88edd1d983551d3febeb507b528163206085ecf3161e2dbb2197cf0d6829be357679c6344832f4792593676c4b5f7c815ee1b74c6affa2784f527f301a04a0b0c0a51ea9f74c9fc5ce0fbe695b3d72767a3cbcfae29f145944eb54048de68e29485d9298c7c9073669867178b136355384953abbb9d8d51d15b77cb765af51be0d6688e3d2942abbb0e2c1c91d85ef4c8f876139a12aedc18bb67607054574cc393caf42dcc36adc2850e83812b5cf2cda77d2302d5927e141480680f5b8f03facd8e4202c78472856811b4c9e02b0b2e2724e7f99eaa7211edf9ba17ff5d2ea3e157a64c1dc1c40c8c464a91ec8a663b32e5161ec155423dc67bbb3602a2dacd6237e12eeda84d4785aecb4d07611e5ccaed133d3cb43758350a8d1dc043c13c4b608898f37a8ce7eca3f31f0102596528b9db9f049c7c073f4316e99f769db91d9f9441de7d5b8b1ec785c1d8c05858e6dc3b6ce8f46564e5feb0b43130e3f65721115a111ee37a78213cc632a7973c43758542bbdfead279acc352a3aa323674c466774d19a6446d36a29ca912765991222cd02800e1b012ba7b4ef6f65163cd2f182572b65609fc579356244585e7526ca6649e347190b794dc78f336a8bae58ad0ec9bc3d6cb85cc5edb8d0e5b115584738f67837c4071c320f78a521a5d1c92228fc401cff04b3e7c93a8a566d07d926a992add5b6ea01fa06723fc4993b1b6a22297811610ff56d42bb7be060ade8da1a4c2b292529124770842c971518a46ebb39dfda523e51822e1d18e25baba3a8d5e5436f2bf1fe06c4c88262e2a1ce54867d32cb5ca63e6b00f69741d95d64076c4687be84a6017a198e328915526078ec15f326403732de205aa7fa453b3ffeabc907be55e3cd6c495f9cb388ee2d642f7d39f19052af30060e7fb03c4d4ac0e010000000000000000000000007a074e7ba3baae44f374df2ee2d03c7d4025a385bdb1f1427dacca9951d39a777ef81272a75f7867f774d58d27a2b284b70bd0099176e450ef6c1a73c5cc51710a2b3309cf7f676074724969bab811beb7b04c66f5612cb0bbfb7cada35ec64d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1f8b76133055eb1aad330bb0a87bfd64d8857bf7730080840710e06b5077cf8e5a5006996fa34635c2e7cb1ab1d4dde078f19ddd97226316f3a2bbfce68fdb48c35b97fb15579736e9b692dd196e9a14569fd5f65f9e71a44312517dfeade9e7610c0d4768538c46876c777aa0b8bcc576e204eff567a9357fe1ad97246a5ea021a348ae91c1cd2373ec150b7cc904f2ca37e6f29f93b386cbeb60eedcfe41cec030510cfeb3803087fe859451c6b68ee66d9dd4df6c9c198e14cc4e40cf4c378c50b126ea934cf801053b70c16dd4e7fae1e030e0584b432df369459fca2b4b87aab26446136753cfb479b73a509a7b11c14bc5c46d4b52b235f3dd8c72d349c3567022c9e678c45d7255d0a1c777f1fc8a47ed8c7fab87c93cef7fd3ed0530e4b489c0306fa6b297de2c4a5f0187ae95b1e7a27d31880f433420946252ba9a5e811ee2302192096dc2c61f5b0f81e0603e286523f87e59e9b9b0627bdf1253d6c06c85d7b031506530e411ea44afa43684342ebcc70a2f5e066dc903736135b6c8c612e037502131dd81b80485c59048a22037d1d9ed35354f8439930a0c33ca86059fe71732037ab7d2218827a10355a75cd3606159660b5e6c67d003e1184f18396c979d343d872d461daaf7938bca00ad85a2db697c2ffbd090eac9eba03fc8b87935b4b2cf0eae9ae9370d7d903df7c7a5a0e1382b49d192b0746bf5bdc3e7741964dfb2d6cc8fe701306c6168b7585e26fe9938e7d8620380cb78ca2f860d2a643a515dc070beb5003951fbfea8c1e457b39ed5f030fac051155b1a793cf2717466741abaf51be2170bf7e8d910f01f7769974cb959d1ebd7fa76a96676482ebb6e643330afed1edf01975912bc9a55800d76eb82f61cccc34aa6b2c39cb418c7137c48d4c9b37e3bb6bc265bb40056c5c5bb681640e0f8d52b6cf9299e819dcbda97d5910829718c8b25695c7f0705a6c8884100f695f0ae2a518c7c054c29171399db9c52f755bd2a46af939f09d4155bf8364e6f3e26e375dd9b33328d09c27e195360fcdb4baa1deb84d5cfe9bb53f4580b518da98824d43da74e5cfd1fa6a6f5e652c41f8d6c190ec4953bc9f30228b988c3aa09acc003b12fd9c240bb0d28e4169d02131132068a91b08b4042f6402be1d4acaa0bdfa113428e986dfc1dfc332a03cc2f3137bd60824e2994c887232e89b6112189022fda0969fbfa6ad19b303e9fa119d846123634249fd42818bd98962ca794faef9fae3a248fe1956a5d7b9e9eae84b853ae041be5bef75df9ac7f5274fa8cca39f3f1eddbe07d798fcbf8d51ac7c31d26e90a0cf8155a3226deb5280ef6de1bb09c2334d94583ca28e3e908b7677b369012521b76765fde828a229a64978b5c3d9e8e7abb8bfafc4439d766c17c2ed44c95eb5c3d03a9af1bc29156c77294ef242f84520b5d8cda089cd69540c9715f4c2d6aaa9084f40c24d3e554e3f0ba087a58be7ec7b82f1c593c11ea4f63f338ff5edd80e40116a4af95a8ad056b95618b49ab039bd64fbdfe376d1239db08dc3d56812db4be255a5fad9567583bf97571a8677e762a31f8060c50a55c04d22791b0605ac48bcfd8afce3e344cb2437bf92589eb07c093d94275a1da1056b90b5af8751f86c23c4c86f7e7d98cb5564b912eeffa45a5211d4d5db29f04073447fa3063603c096675ae48821805f6c4f628342676d9cf790d31e6bb57917a4146c6382801d35c25fb5e1656b3e476068e9f0232ffc6d686a0022a3a6437972e49b31d2be70fe800c408219b17d0ef19c60cf365afd2eb3897f34d218de48943c978bcb972ab69dfc67e2783c636d67f13c48ae8d4fa38143707e8be6136cf14cc9950f712773f833559b53d3722205bfdddc3ef0744cb40bdaa8a85caa3a9cd77f881e3061fcb10711904fc50efb3a6835ccb3bd24148f2039d55cef0687e6a73a2a18bcf232815b6a0bf71deb552273fc28eab3457cfa66ba60c6f106860b9192047dcce68ecfa7a3db2281ab0ee6d3bd899a6dad21b230c6afef051a6b7c0b151bd4f6445b12b43fda38fd3c06378ff28f79ded84bb59e6592c3e5e2930e461b903e8ee099b52c8bbdd05f0a3fb72a36df17946f4093b4f9c283f44111dc319a300c57f3d1a30adbad08937f36b07a860b38be90823ed5c2e07ce609093109f660813cfd6aa04b5f37017d8eb6fc9963b6ce6c5c2cd6101a226dc60da376cf527fb00e456110b2c7cc2723905811165b3a13bfae475c654a35f24a346177c38db83c9dbda1866df5a469dcac7d220000000000000000433104000000000053efed4eefb0a598846e472749f06003636a80ce324de48b839d4373a4f0e255012b69f56a6428659d243ccd4327b87f39abd5f9497aec7a67f84badd808471ecde22bdf02702ea7a7992c123e8992ce9241a1fd3aa5a735231ed9744a1516c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ddc63bb2ed4b93c602040b4520a85e011ad727c4b6c699843a1bd686c96118dc9bc21cd1efa36ebfea40847c72d7723a0a3167606b3d771d97090030fb6dd029ff2d38e9970c1a4c7632115848d850c42eb5afe18521d484693bb098ff6f3c985481b2bf6223818dc89d9bcead6fb5db7b2161413ebf3c0a7419063ea8ef492d0223f68daab7e2d28e3f02c6090ef9eaf0fc73ec01c81646cf9360d9bd09da1222032520a200f33429a4bfb9f11583998ca3e4dd7f510747875a7eb7f02393d61d7d0b0989ba2eb80f0c8a32aa0c19e990b521c610012f3426bcb93e275ecb323d44c123d31ce1b420b42d148870feafb50b2d6143fd281e50c672653de42a90d3fc30022e8d98f0e0ebd45a3b72f0daf6c145c90950a2415edffa7d3f2346d59001d6850224b5e490eae88b9b413ec045e8023d536260804e467d5d5327c3dd1e4a81df46031b256506106584bd1361d4691f500ec9a866ee9d94e52597f05c1e10578db1ed020bf9e5c4fb1168f85099f0eeddb5dd91a1dd322972a3d3257893095a58236abe021bf55bcc2e87b2228f954af0fc50c3d67be95dcf94e1deb1f9d2c81848c269b92244a966ac21354a07bee36e124582dc413f094fa9c84d635eb20e8e98dcb7345faa736e5303048b1a9f78043f3d64712918bb28d8440c5325dfecc79d85448c5e0b997648c5edb729e1813fe06e0f073b5a5cc0ae800c164856d48fddd2fd34b8e778b116ae9cfa44477935ca411c241595aa9bec686d896d6e7e4b270ec08c236a644193146d2eadb546c856aa9a18b22ed2a421411db92dd67aaac4a762b489f9c3c9e1ac096affb529212dada0112004c6bb2002ea95dd924e3d53043606ad55df63e33f1c1783aa4c526ac133b9534b4507138084d0e729684b3ed361453d690adb7ea1e598297b5326d35a9a18c98897a07db6c17d391727df1d6a74275c909376965fb8400a3d2aa54c7bac82f8c7401c0ccf0dd36c5a5f4ed070e91e0f420717696a65156c834f28fee937ed299df5528645607114cca2338cc2acd6c759cd0b268b982824d59e0620afac162ffa94503891e792ed7a6d8fb4d6a9cd12b5a2dfde80d3af9b818df89ef09a9d75999e6208ad3c688a6bb8c4d23b19412eae58ae7bdfeecf86f026c3e637e30fc88889a253c066b00889f0287ba4e9c7c5929ddb53ac337013a7f82fd888f99c8c5986025aa38370cf23003c9ed05e9a99d0e3dddf4fd6fe99354ce38875751af10f24601f7e6639acb8f8cae41d58c69af922630c38cdc0b17765a8d9060e4d174fa2ef150319167fc243a059c288044e1e9058268578acf98ac95c0e2ad998fd2cd8b9aa45c3ff108bd4ac66ca7f74382be2badd922a2795ff28c3a27554d82a9d9e6e8b43f327760e19c93b0f5c5be4d830ee2dd7727b3f17869006ba8abc98867fdd91c19b1e883b33ccca87d625cbd873ada1ed4adbb61f562d7348c6679aa465b7cabb1ab9e1430f57d4249e24e1843714c118b3fef6609bd05eac0846382669a8d1832fd26a16cb0ff322bea38e42735e98575b7edbea053bd512605baab813e23905e19cdf07037e35c61c5d6fdeb7829630f44e1a0c51cb774bb1a45c349329f04fff348ff7c01ad8b12e6df26848c59f8a8598bce8c3806a486cdcf468291d9abc868a3266a9b0ae35b1d5c13d593fc53dd5e62db07bedc89a55901d599595170126916db2bfa7e9564fc6516c9697862aea18da9b47749f2c965d65f0db65454a7b3bf1a202e56b00c19a40723b5684667997ae403bd99c61a28256b030628104e75ab9bd0aa9a60919127d71a4644da83a1ea15f15334c6a064180da3e73d42321214b95812dfa68453759216bea2cfdb7d58dfd4975f298b5c0a2a50b5ea616f7336cd7c58a28f7e2b1c7c99bd7248c8f42e0cbc439f83fe60721a75882551b1e0539750d3c56df15ee46245b320e10e24277a975e19cf05358c759bcba7c5f3e61efda9492b6ca7c4ac69bdbd5a35e2cb11f860636cb533f34e6af203285a1c1f34f75db8c2670178b1d74383ae3e6ec26c5eedb6565969830b92b5c4bee568b6b49b92ae6b308882e02fa83489351077dee85de54e7e0660a7e58f5e38da6fc40fd973e89b557c9d2fbefd4b65abd5f7c8243e75b6c50b9b16b957866bcedc785209317a297ad3ef08d284db0d4ab8dcbbb6b652e2667fe7fba7884e7ecef3afa8cc4a15830b2f92ea5a63cbe2b090452119ccd5941dff957300973d0c1af6d04e2e39bec34bbfbfff7c08de0d78f6c48977f48110f3b847ed047d137c7a0d2a99a55b4fc7f5cceb58d4fda7ae8ca68b6f2260e811921b88321d960e6a8a1c1f33a9d4db68e0ce13b5cac05b6e526c33e45e2d62d48da80cbf7cd683d4346304f166a8b4560f1cd66bc6990877886fff782759b93f12e69792e08", "5365ac", 2, -525502696, "f3237a1b1312899033d4d41803ea786a781fbee414039f25de6806ba03a529a4"], - ["4bf9daae0312216e594c3771012d1aa3964fafbf02b8e22736ad1fd5cb5d78ca754d25c8fb0100000003ab6a53ffffffff2904229cd87f61b7147c8bff248ff32b7489710a8da50743cf800794ef7b7f8c020000000165fccd0e45e0bb272cb7caceed967f3959511aaa682891385669fc7c0c080df15206b9fe4403000000076a636300ac6552ffffffff017cbef6010000000006ab5263656aac00000000", "6a6a51515163", 1, 1899844270, "b7ee1c0fb02ef3ce7600951fa07c312aae1a2259b9dbd0d89a68a97fefd0e176"], - ["7d14241d0393e10e03c7b894a46efb7a06b4dc8f0226f90ad94c828cc194c351e90bf9bb3b030000000663630065ab00ffffffffbb4e10313914611196153207d6a9156e85472ba44d8cf62fa8a8b6fe6a06c23f01000000036553521796d2402694b6ae0f98791df13d5ba5265a2b0ed1c0a594b8b34080b435aab386f68c4a000000000253ac4b8332240263cd4c040000000005005353ab52e2b98a020000000005ab6a655251dd1826300311e65405000000000000000000000000f15d9fe5ca7fb7042c655088301c70d8cae12550a425b97fb1ccf2c95cdadb30edabd22e45641ce4f6e18c9cff4c02198720c2cb8198e0e0b98063ddfbb1eaa46c66c4835844272141441da20a5e98bf2559878ec1b970f04a5d7b8cabea6364000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be91e565bd97f409cd9ac49ad7e05c855515faf2dbfb2fb9386729026959f4fbb995d1419a34df6ae0e90105b5e2504e63f0ac0cbb02fd1e4e4c10b5259412264ab8276a3aacee08abe21dd72dfa31f6cfb08a8c03a34485c711ab713f3b2e18a9da96b7b715f1e2a87b9b91e15458200d0c3e60830f4ff3725677de7d3044f0200e5bac08ea07e2ef1890812eaae0fac8235a890d018dc8ab124580b41d57daf020d1599f8539697d9086270ca727a086528a7262801466987b3e6b4cb105b5bcf0a1abcbf05444e99d0d33ed85eb7972d58bace201d327d3378a5213bef38b79bd91ecd11435eb94ae69bd129e064c271f426b44efa8ba7fdc3e99b303d29d2b53803156fb1de28dd2e056b0c1ffa102c1c3ce35763509fa7b8c2255408e131e13fd5032548943df06ff10424f85756f5230960b99d484c3a528ea106a83025e03269d0022527b68c58b89e3b5a84ffee3e926b4d8b39a96a868e1fe451b77ddd8e4b576e02260c9b72548d6fc2bd5e11e142fbd6519ffa9ee21657486ac02199d5df88f57e021244bea69ff539aefcb4df731c5613fdbdef545895ebb05d6c814524baeae52ba35c48995f5fe4a949b2496c7684ea2829e1bd119da71108ccb9478c502ca96315552c991b8f6dd351a27225ea26eec27dc34f7b7dee0b81a7418b5adbd64e8331021c1ede4704f824bf0c775b84ae82c52c04aee792ab9e920180a24e9e2f5b1503384e2d966f191acd045335989bd134e33fc4d11c2764e2acc3999ba5acf1db685ceb1ce526637b7cb99c3fb79580c8c35b646fa3e8b90d37b4622faf95d16514d6315b0b75fcc993224be1571f1d3d91c4086d3654a508804eac38b28797b9740a717e0eaaa3c4ce815bd97817c066f97ccf78a746f85a835b56b2fedb8c59b7d7d6a8158cf8a4986246cfe5777f5049215baab7cb06b4c20140f1f8a8a05977a508ff11f39bc57cf2fd04344c44bec4ce052dcd2ca2f84fc7fc21d11b6be6c139ea6a78f515b719f841b27bea7d875f6e6a97e4a49b9e0e933b1d57263fd9e6905e05b800ebb1e350086113a537fed611bbe0e19bc531f71da7b68e54305c93dcfe5f21658882160a3baac26ce5f1b02d65a063f4fe7e7d99bda297ca32555a0bc3f27e18488a782d5660ddade727219c189d7879817615c1652a51660e7d74a3ba8a38963aa707c47c51e736f561fc7e99a7e2392ec5fd6a311cf25e8b8bd990a71a60bd9ff8d163178f08adcc62ce67be1a5c629f595151511f36fba49e7775007ff714fdb3174e51c86b7480cd226353d00f99ca20930669b1b757a7dbd47b104cb34f24cafe61343b82040618ba6d2860dbd658a8a01ef3d3fffda6628638ddf9b25c8e19f1ddd8becde8b4d8615e2cda0a498e018591f29372b6f2ad7a8cb34cd19564622bb76b4ea65873985654c76570bb97bdb4583f2c934380bf02c33f66c171df240d520f91e6ab40e5fb6f9c4befba6bd5aa5fbd56cf2add90ad1db0ac0da9715a27a0aa97984e4bd449d85566f1237d75a3cf5089a387c37a21342059a608deb33fe1115733f0630a653619836e773175ace293dc59ba6a06072ce8e58c1ba95f7e10c7941e15be27f5d95ff03848315f51dafdf8dbe359f501a1bfc193e1cfb7d635d58ca5503d4a3cc8344486e5ddbf67ffd69b064516ff08ef5cd375c94a6ac7b9e07fbe1ce2d478c8628a2e0718a68be26c1d38fb2ce969fb3e5970b0c1633befa9dd1cb06191b407aca93179e86e31ab70f99590a8cdbf3348bf6f500273a6b8abe17cab543f89ec4bd7ae91262b0abf44f06f2ad374a5dd85cf54d3e086b178565034ef94f767b20af39eef2b223de9a1fe2296689a6d2a35d37ec6a68f964537c351a0a504cbc25ea6c1e576d16c926c100c6593e4980b48457a614d05341433c1a6c7bfb0a89fc9029c9e440f786d152d52094a19fb2d9dfd1060a3df2e340fd3fcac7a07fdbc3f3229ce9dc2e4980d04cb98fc1708bfdcfc42f7962c195248f9f59e0b2bd94a3a9fe4684c3d64bcd65fbca6ee6975a101ea7f093ee42794bbdad8b925d327ebfb8e23a1b9bc0b402b2ce7f58be79af09b73c36abad698c683122a0ac2e899c1b80adfd9c82de62e24de5b7931616c983527a2f586a622fcbcea819afbcd411dbd22f4af86046b04e788a6ba31e192cd79a843301f6a1903f0c6f166ebcdf34fd2e5d2d7f506b27c1bd273f1d83a85ecbb2ee1769fe89641277aaa75967ddfbb339b63a292f63eb5b96cb0d7bbea7978a358333219a0d8b2c3987d6a3953000000000000000000753b010000000000282dff56fa52e3dc4acf1608cce2f5424b01f804b4042ef898e4d253cc9ceab229c97bd6bfdd3a5f7491599c88d66b446540ff991f801f5510e6cf7e4a946c7afd4158cae7161347986a14e58ad5ec193c66d1a2b8f1441fd360e01a5495a07700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f66417c5bf70e7aa6469e79d29c238383b60b2c2856efc6d07d0a44bcd0edfa8c6789df398cb2ced361a97ad86688b204eb2d46fbd2daef39550e24e9091b75d7c60a9ce1678e6ad341275d366b23e3cb31ff876ace4052b509d993ddc552d7e9fecb113f061b5f8c6ce21072acb83de2e60780089b36cb5514833a89d9d1fd202167f22610b5b82a4d872dc89115a9944a052dd7a2147c8406b6385f94618aae30217bc1858e7c72e867e0e4adad14e3c75c0e503184a362090e3d795aa74c4535f0b1c3303ba2335f7c6fb248878384734011d05fe69f96ea75645dfdc5bfb15bdbf2293f4054c817eab8a1c07dae92b3bb78e88f53ab4e9a92728592e20f34fd96d022b272b01adf24f3792d1f7c415bbf429416b001aed4d8b0ca9af2fd6549c3d060210bd60ce0cb903487472cecde9cc29a94427159babbd13a19b4d7361ec111e0b021f101172eb3b6933c2066d55c5e5baa9a38793bd022565657ff8db2abd16d4e402157fcd1d0f68d12b94e09b03dc7ba5498ad9b627ad58ba5306544c1dfaf1ed490220365e3e2ffdfadc6b83fbb4d8dddc4d0bd397197106d3b03336cc7e58239728b9735a711d724ff23381927891b72e871ff3531f1a41c3fe19207fb505432dac4b3f1857f8c6d0225383c400a2fafb1671a830af8b8ebd2aa208f475f3238ff77a1dcbd6a2dd5e02fb92496ca8cb3631b369d866ede077ba8e9d64837f1454a0dfc3784acb2623826efa631195a129cca18c7cbd9ccde12232b67ca99459bca206e5498ed69083f623aeb161ae9b2d80cdf43076ae6498205ab8b5b98f165fd2c5352c6b85f2d466a05b508d267f1eb868ce9e9f6bc9878f589037d3206897b9a17c8248d1870fe20e9f492ccddbb66cb19ba148d565af0df42bb6fc65a84f91f8b34077e91c627753215529eea884030c85c9e95c9ddd3199bdef7c1ae41f9b952d382bc58fb0b01ad3e518ba2389981718d969064c9f7b1a7d6c3d4bfe580d7f74c8cdb5bc75e57361e54696ca9c74a30f1ffb06fdf60a5a440bf160f38c823e7c4959f57d36a6f7b41988ea1da8c7d3689eb8d17a2db7f0499197299596f2716ac4adaed00c11275d6d273c7d145e74dfe7636c08f9b6d492a40f7eb0c26953701534b9ee57a3c3db3ac2e8f3182112c73a9a767d326359113b277f44dbd08833085738af5cf31a1001fe241bd487d9617c369c8b0083672ec593ecc4356186f8c4ee714d8fd00abdceec5ee9fb226ac2119dfcf4061216be27640ff90cbd25be695c6775b50dce13b81f96a704e5bbfbefd8da11f5f7328e7b408ae423b82f731e75643dfa50e1f57cdacb2c1a2a8aa344b9ac7eddca1468fb4296d100fa0837d3b70e29ac67e30bf74435ab868444d5776f671df430189d81f06d5addcae4364706537ed828bf5add2ec14adf0a00ada75e45b7cf041ea3d8fd259ae2141938a3b8e9e8965530bd6cdf36d1efb9172314c9aaa90a5c68b7df2817ba6e2d3b4982e12e8acd68a5ab43cebf4a727fd7d2c5ed736b9aa96d24e18a8f2b0020ef73fe557c0608491186a5e426e06fef0a574bb38c0fb0417c42e4bb5021cd6c01fc2cb4b3fead025d1c345b7f0063715e8551c825022bebf51b8771b2ad74a3e86986d2f456deb9a93ef36751d860ae296cc511e2dfe85c925661073ec6b60fb1bf02ccb6e91a0d31ef87f36bb122e8869b335db38b6c0ca072161c5256c800e9f37f099dc37e6f662eef82e1b41d58a05ac39b4634999243c2774dd0508db85e2b824aac3d851a6785499e7009efe5eba4edf49c7fe04bd1bbc77d4a0d9edaf55c7b7401de21f4a907c582cd4938a3d70d0f9593a71259ae7c3aef4dd43fb4a7e1b5b12641cd931404561b293ef265836bf938317e2ec412cb5311d04e883b36e6852337804f03fce6bdf2b7322438052217a4a89ac4d9e69eaf99c6de22848df19d472a4a559ee34cdd4581a5ae62182e172b2c96dd1776f57d0508e0e4093ba3aff1a71b5c793844a0a8953abbd2f293c373ba5517f2be423c8a7fe406c73a6fb28e588c1ad624724455ef2d181980ab29e7015f630076ef55d68df2ee381923e0bc4e0eccbc52573bc7187ed978a05890c6d94f1affa82314802b45c67ffa952764e4510785ef83ddf79a53e12086ec7a35691aef6112afee30ebde960c8160a1e28d48a21d4f215a886e145d7baf2758f806d207fa7c5be21cf1d446018fe856d88a7da08547ee043f6091282d5968b8a5966ea067ca8c10ff22804cadd56affd1f2d90c0af9ba2eaeeea59af0f4e40000000000000000bf9abe0000000000e4b95bb3b1c757af25af9e544edb503d0f8e4e0cec8c1642bdede78f9f88f61b981ed056608b936dde696ccee684aa862edfa66cead9a80e78c7c9a2cdc8ffba11f8a46c93806b4a58a02b95c5d44bbad5f3f042d94db660fc12d345a3167c2700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b53e3722ffa874e6f321cba2b2128b32a04aa481ca8d7ad18d7d10e5b829bcfd8dd61022f154b0a8ea674914c839129d908aea63a9d474c05a8af09afaee67d3db6c6505abf8a62526baac57d325fe41a6e7680808aa52739e32f8960ddd0f1b913c0b3f010edef9d4f190fd71b4cb765bf639ddf2f3e35bc2b527ba705c07a8031b1168cce6ed4dd268c595c05a7e4a1c827b4d0d86aa2b603ccc20e250427b17022fed553fbb0bfbaf81531653b847678cfb9553b626c2c1ed9c39ceed56c5cfe20b045fef8fd6494ed7a2e86a41e03daba5013af73a7e8a64f4e15f91e14394fbc40f73aa745365eff58ebe82ee0e2331171ac20d434425c67f192641efbb016eeb03105941f0494e7ea4175ed745b3b590034e20ebb7d4b5925e75deb0bb6bf0e3b90217356f6a79694784c4417a0df6694f5258ef615dacca61f8c78453b59d1386eb031742b71f38f010f887824efd7cb2d90ddbe96e1720ce265f3022530aa3f893b002292e224c6117ee77e658d2fe8eef85cab2c5dfde0c78cf8bc643b239d12543f30314cd8e51ed2ac29818ff2c7b91c5fb098734a7ac86b3a1615a7d38d1ec212fe9f46a7a8d4e6319bb3c65ac64dd05258393551a29406c9c15c9ffc19eba16740659cb9c1cedcf034519aefd5a88167d2ec952248220304b30bce62a5c15fd7d22a06b5aa59299fb2425f42a06f7c290ab8a006e37822c05c84b542f0b48055fa8c63261b200bdd412f62ff35189cb58290b5f1d25adafc7935081a45171fa30460ff424687ae8a4db6feab0b776559efb7206d75f293d274258061d7926dc4f6a3ee7087f817d9ac88d616576421d98146cdf296ef00482370435cc19e4dc2870ffa070f02b69e9a5c0a22abee26dd2964c97def45db6a96a68a6426664d6d8a3ff14bdc433741210f7baac64397e07e1b4268c3a65d2629cfc35f1caf8368fcf97006c00274cd677252ff97267758ef9311c3e928dede0295fab8b39e00cc8a66ff9f7f251a25b3b90f77d4c4b3bb1ef0d099f0d77176a4c951897cfdc435ee73f8eda8ec9494e195468f5a29db780c74c42c8ba4bd59d0e31f089805ea6c7d769b84a21801e543106ddb9655e03bc3a18c5368f817b08607125d4b57e3c667239ae42c0c5abf961b3b6ecb126f272777cbaddbe08523b8785fdddc5531ede6254b6d631d958b3851cb5f7c92c6a992a2f841896e36556c346a010f5eb5aa32e6d5f10c5ee2157e0f4d8dd1436dbee3ae6c3a03d4d85bdc900257c490ceeb09cdff7818594f43a230b30d556a1f06c7bdd59e32efed9e3bafb1ee5d67724b05bfe58f0c20b079d15505af55957fa62d7df5351ce51d4a348bc949ca7c597faaf5f9dd21dabeae54c4cbdae380ad2fd24e1f2a9e661be7689ef34d55f561aec43eb1341671480931a8ef90999719f2adcc04dd9530be8c6149b39cd7751cedeb5443282820f8b8b78574e856b932c62f470209725b6fff609eb8ecb671fb1591991398cdd863ef0a7b056abf4ce3c05143715232a7fd1e793efb10d863832e3f2db88a016f4719c15c1d99499ecd51ff6bb1c6e20000e71d2e5a571d133de56a4c9aa86af138ce8828e7ebfa4b6481194a20dca1dd78822c6fa92c0223153d468413c8513b9a31c5c7856c63aaa04e4cb38b7deff043a0b8af91b9885c8d94cf994e62c41b55b0f85606fdc04a5e455e45748230da2c6f728c5213c3909ac37175e1da1b9ac4ddf026ebacc10a0f0990963a2163a99103b180ab401d7f1cc08f45efcd840cfe354080eb1b0d639c6cc94b1ed48c6b0e5d24a4ea3f509c66796c7271728fe3f638d8781306bf0d2a7b8c5dd38408eb3ae003097d0458c9938b52bf0cf6d54c4c0a006beb62a4f6fe2a75103d665c7796fbf2ceed26afc329bf88a697ad7624bc49a5df5d82d909a6afb2a4425e0350acba55027ed4560b813eb2d789992213d144010baef7c7b26e10832120831533613be50d18be6be2ab26fae345570a4524ff48c58c6dd18b0c11197c6a8ee113bf590b6b6b5f9f062d06f26c61827b292a973ab27b6b492f0ef46f4c9fd5805048b7deea6548dea5f82d6d4e9808a117fe524e1245327ea24b5dc487ca3514c1c1781f4b0958f5333a144a3b1fdc9e0bc07e22ae533da9d629114972b96da9341def59261d0312db1778053721698d302b7281af7f23e94f0445f5938968527a4bab524e4b92fadb39224b06cddb96cd489a3791d67c3060f9d75854afe409e0a3e6de2b29280d919d9e6c54c806ea9809796d7b2772dddb925a3a614f568dd8a4facf43733c3be541b5cf0b87aa0bf2967f92b38bd96f0dcae3456189c701260d9640af6e297e8d878d97850479a88e7ad62aecff00e2ad586718276be1d447bdbde06dfb092755ff453657960cda5c6f3318e0761f6b961cabe497705", "6551", 1, 1528788085, "cead04bbe4cfba9da21c4fe6ace13e4748f33eb45e707e5a1e656e44e211d3d5"], - ["b368de2f0283795a2488e6e246ccd210da2535c96bf56ae0c46b348bdeba068d0f408f328803000000046352525314948fa64c56a922ee4842c770d7cb7fe268b283f0b72d63899bfad5124b6f138095125b030000000700ab6a6a63ac51efd22cb3042f2851030000000008510052ab5163ab527e428903000000000151dff7d80100000000015178abd00300000000046a535300b270c4f900", "63acac51ac", 1, -95135240, "751069630daa51b3d37feb5855b631fbd835adbce2b2e301b6b364b7dc553f9c"], - ["0e23c912032ad233bc74749dec650794db5b06113d515fcd8e46fc33628ff3f1d57de939590300000004516a6352119cc15ca366193a4ccc38c2fe72fa8a9ad1ab0cf99814beec5b7aad59a042c63dfa8b0d000000000653ac636a6563a6d2da8781bb04a15d6f00e1cb9ef6fbd22e301f953944dee29b55ec93b3e1c28fc268f5020000000552abac6351a6a6562e037dd10f010000000006acab6aac00ac7b891d0500000000050063ab536586f86d0400000000086aab5253ac63536585a8777a01b03ccd04000000000000000000000000b3526b8f50a3e27f6b27f2ae16fba54196161c51c3d0ce270a782c8cd3dc83ef55379f80432ddd3e5c689e0446f30711038c1d5ba5f74092d37fec7a885b6d7a3f80d2ec66621498f65754bb1b36b2720dc2cfe7a465908da82b215bb5655f25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc74f98a094fa387a0111f9ddc8b1a9035073de746048059f2883fbdcf3c63d39d890f72db99867852ca3bc61d0a7df60577cc248382f2bf230fb1652a6203007a86a4f18b8891172359e048416b463289abe1469956ed1b2006c5fb40926f5920d3f1c264622c846e097bd089d7a0c013dd2e38fecce153a9abddde08d180f02257c7daeb8ee3253300ed438e6e73c8fe5dc1eb6c9d63f0eb28660a833a5a6c503113457ffc43f900a350ea32aba65ba8aff45c3484f992759866f60608d4d16670b20e2e92ddb7b2262f3e05bd661197ed7d1c9bf62c2d90bafbe7c62f39c3c695229e6f426c5ccf8cef5d29ca8541a827a1a948312bf88bef18757a52fc58a5cb20214f9528cfa9c0c44cbfe7c37da300b4e14ef926e6d80eb8ec413416ad0ad3f15031cca46d91d5d5fca39f5304d234c6fdeda51105833430e1d03bc52b9a7b07518021d89c8e7d4935cbb5d5dba2e956f0698b08b1929b058cf18c10b1091ffe637be02239f179df22c9515e60d5655d56c4b0f0e9c8d2652830afca122594d06324f740306ec787e1c47d94d9186efca90d06e19716e12f03d14d36e91b5793ee8aed30f070ffc8619654e095f90db6243166c521830b52da247b077da0bd3f27d66645e45097cfa506be44bc92c2b769feb68d56bf067e316254be11154e54062132f4ffeebf7a825b3fd98021f1312d80a1cf4598856996e5e1b32fa5cd9c38a28dc3003aee049c368cdce81ebb328bb62c1e99883618591923d8f929b7e8cd0b9c518ae4a1ddd91a11fe798223a5c39c5e500585a2961838cb525b4ad1e33fa74a14c02cd0a1427bbfce79446cea22cf1ccf4709eccf18dce07cde96f88e9141f5cc8d69c088bc641a4add34b1adecc67e2d4fb40a5d17961707b746608a24121470e464bb90a5775b5d15f99bf181e8fbb603645f57f2377ad79791eb67f2250622d4f96c56d45de3cc1e42719c07f81c35bc7d8104701daea32934d0d0d4fe1eace4e90b83268ee2d38c4ed40510ac6d5461a88bc0ed8e9aa5474f7bc29236cc41f4616ab4f586228e0eae89bc2adb0e41b5047379ea157e9a2a90e41a0ffd1e53c70019f4760975aa07d0c661bf092359c38ca9d727e5abd3d196b0ab6e866e1b206240788d0514f25fe375fc4d8a7854ccd674f2350d4d02598c7f2c056d34d921f18e0d38ca906a781771e844dd7dabcb7c5af2167e180c3787f9e13ebf7c5def02f19b23b1c719d7d6d78f35dcb1b160ceaaefdfcda93142b9efaa5cbc082fecdfba000e965e4f240e450c2215d72284b0027abf7a221da9657bba8bfa036d296316103d9842e62b01d6e80181a951b3fff5a9a662e5d1649e518f72216967bf93f74892ca984ba7ddf11c0f6907fbcde4c2e38e8fd2e4571ccd1944606e8941fc918dae9d3c0135b67075d5ac2b56881f94f7bf76d4a6cff738a491df5d6149aebddc85f12bb2b680e3007c6a501fb3f7582ed6389815495dd9255755eda2a3e1bc75bc0ad3de5dfff6744a10fd0c132474eb92dece565baa05849cc10d94e878c69998f1f31d12cd0e02c56168fe4d71d3830dc97e4c1ac6b7c7cc901b5fb091a1d5a0ef5e6e7053894f2c26f5389c3a493761e26ee07ddc7b5fec335aeeda027fa03c15f0817a4b1447744fca62b98f7d3ec9096709a33ff83b002d3ea8c00ced8a58b5db6dfc287d9d71f8dd59f74815cd1c0d60261fd7084d8e8d81acaa266f18774a68d2d01916854190ed20597b5c2364add50b8ec839574c9c6998e8a1cdb26f9bda0577d424d514f05c2a28f33bd2e02929c1ef0b4b88eb8360b45bd3d179b7e9075e6ac5ad4106289dfd0dcde5b1a25e2f50b619fe39079c3e5ca57c665b090d840bf4fcf555c6f9f2f1043ede2184748ce9d05550206185b49536db8c4d4a3be93b03612f0446e0c49385aeb788c26b270d06ab5406d86d2392915f7047677ca5cbbe8272fa00300c966b0f81b7599bf3e94b4f34323e896e86694ac40842e716c14646189c8de8db41830dc3ffffeb387b46791ad7d497f0737e8de90e7e1453158d560a06ca7183112692517464b5747802272c9fd68bfbf7fe92a406270272476fe7c1fb3a7ca57df31b93b4dec46f9cee9251fc3db389d82f94e4f426edcd3555a56078c766a232269d36a381c09658ba4e103bd9d69123a1cfd34f3bdf461479a04c1da070967dd431460e8c319527a121101f563af5da348b23352e2a66d4796d596419c7e4eab203fcbc5b57a387f53f9db792513ac59c3d2bdf70ee69101cf7d20b3890a8a2ef1fe7b627b66f98be23540d8c2352dfca9c01bebcdaedd584d274b63ff24b9d55591e7c439053b198e1c52a828b9758cc64a1fdfe202e646942ad720f6c6371857f60f0527d49e112906a7227de36aa46038920c40de01d24a1c74b16fcaf2d1d30b", "63ac5352", 2, 1302013768, "575c31c8f3e45a2d2921bc8cb11f99e1225751c4d11bb5d0ee532efdb2435cec"], - ["52dd860f049dfea4677980ab584d201164556321b73b8d7718f7b93188ebd9aeb9806719d90100000006abab635351acffffffff42f10c0b0bbe572ff550b6db6691360b5532ba7c469c631b6f4ab904caadd1c0030000000353acacffffffffb29bb232cf7893688a582c636f8df2cdb6abe5ac42ef2bf98a699a0fa029bebb01000000036a5300c07cbb036bbff20ee14ee3e168da3e7bf8bdfa9f912562d507efb0fa9baa7ac7db583c2f02000000095353520052526a6553ffffffff013d2f8300000000000252650000000000", "005163", 1, 1501550457, "2ec2bc433ca1641e1d4825da76739748b1f72ac9fd2601f73382ce641321b62e"], - ["729eb7d50332cda816be68e70d39e33cd1b45e31ab4ddc88c02996156f177afd4344248c81030000000953ac63525163635153f463dee30e55a0e38ba1a2bb4fe98403d4ff08e6cdb64a2f3a7126d4d2d82b087aabf3120100000005006563ac6513557dd287f02f761551581fb7177e72e835dbe3fd751cd7e203d532d3248286036a69270300000006515353530000ffffffff0302f458020000000001538050b103000000000951516a650000ab6a6322d264020000000000ca99fd1c", "006300006363530051", 0, -338681313, "6e51288425b657680ca63ed9823bbf52e1c01d0d7d9ab50409beb0964943cf14"], - ["580c944802cb24e10e70285f891eec869f7c747e452ccf46d85591f2a36d6d1e407af3c5d0030000000152ffffffff3ce3ec30253a9374193db045d32d027e6b389520d4cb7e9d49d53aaabd34425d0100000005ab6300ac51ffffffff026ae8d005000000000963ac636a6a63ab6a007f8e840200000000096353526aacac5200637d28910a00", "636a6a51ac0053", 1, -2052287101, "c145fdc2b12fadadab616b8996e6f7a71f3c70c2d15776df3d09267781592fea"], - ["cb2f69e103ee061481ff3b1826757f1777b3a0ec54f0f1aa5981973239ec89a45c3ed457a003000000036a0063ffffffffd8b9f9d9ac2b4334ccf44ea4e14d3c218a4d66000b7a98141a666759151b91d1000000000765ab65ab6a5353a97e95a49f81b533b7a75d3ae4518080bd332c42259020d42624a74dca6888c8d7d9335b03000000060063635253638605a6b9036a00db01000000000363536a33e8a60100000000066aab636552abb615660300000000066aabac00655300000000", "5353536565", 1, 853468471, "2100f4d6c0750a42e448db061e6c7f664bfcdca7a0d25026d642d423cb5e0581"], - ["dbbe5c97047ca2f3baa9096dd3e4f085004fb0c336041dc070e49ad9ca1a5b5911c5b721f002000000025265ffffffff8de1e2d398e875bbcda1c64fa7b2852dfbebee0925186650b8fbf23ba1efc69201000000066351ab535153ef59f8c074a066bc8d17c19ccdbcce0e9f866c938e6544175831c3ec4df67216e1e35b400000000003ac63632928f1b721a3e1ba8fbc61ec0be74a282927404fc52f89e6e09bbc0fa38a50e42f50499501000000025265bde14d75035ff2b704000000000663636563515384e37800000000000665acab6a63ab0639a9020000000002ac0000000000", "6a6a", 1, 1016383838, "7f9f3a137eadae7ca4ca352aee5c027c2260652b1e9c1c55b33acb67904b157c"], - ["c3fa3c76043928d19402b8b8599ae4b2951ce33fd09a016af373796a44baf355e1f584807d0000000005636a006a65b6138f62be0624d0358928c2e6267ab7f9ab29fdd8de810339b2aa8a1a5d6a72feb7284e0300000009ab65ac51ab6a536351ffffffff53e1520ea981923cf7b4b65a6e999b4f628c218a4534ed6110e22e3eb61270b701000000055163535300ffffffff499814d66599d08c0f7e634f590956b30fd12074941e10d34c2531a335084468010000000152ffffffff0431288a050000000002515347bbb3010000000002006a9a33e9030000000004526a63aba3fe2c0300000000002b62876002c80aa9050000000000000000000000006ba828fc06665ab5bd6b077ba2cd1256bbcdb9a3b87a2f7d7a3d9d7ae2063f68a2b8fc82041649a086edb0d3b327111790682b94d4c3fac9810911a37254f11352ecd933933516cbb67f4d55dd41d279f0cf4260ec461b9eb1b1d91f6e7286b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001500b5c8651e6a30ea18467fb8f066d4845db6d8c425ec706e1443b003fd19388f41167999d02ec6749f02ffe5d6f2bbd2b3afb3ae39b0753955fba5d9a367e72080e0f9b8ddcb38504e39fcdcd9f3182093e527444ef88683f57dcbf5d7e0ea6392460d5ee938fc74790c8a1775a2e50a11afb5af0e54ff0abdb010a6bf3c1b02021a7cd079c38d511c13427a03c36eca7cfbd55faa65ed4d0396b6f0212ceab8022d1cf0b865a42d567fa83ce060e20d9f6ccb582bc47cf068814af9de241720120b0ebe4b0add4e9608981ab0f085f846dbc88a65745ab0cfe6dceb8210e7d3cea817688ec3cc84d310becfd7be1414cdcea01e4d9089f4439153ab4e2400287dee0224685d25ec97c360c1d4242e41965f7a253a580a15a976d9bbb81d0ea5294846032452d2e81a711d1110610cb117b9ee1bda425bc240f885bc320f7ce6080481310302c6c63262cf77430e4ae2dcb12ff6c05c882a0929c90cefc50f5969a35cc5040308ab1a0f3ff23b12f392ed5941d70c2662e32f7a5bd3cab5c0e2705bf8b107490326df7d3cf4b628a733258652182be74e1544fc9d99778f7b642b839daf94d212fa4b4c96ce47e76c135f650d1c5ec808fa1f1a455159115b92d4c011108641859ee3536532cd1b7bba67e9b7b0fb8fd5f0cd6f878031fbbf4e5721d09d819068b74c9cba91f59d24bc52eb42c35db85c9764b160ff193d8ce67789c4e3247626a523a4c2df4b846fda60d32269b5f68b6b1af779f05fcbbc5e89e2eb88907ba56532ba49e2843362b951abd7ceac11a0484c07f5c33dac23df65d8aee694e7d7de4e906ed9595924949fc49817ae85a3cc2d4ce56636582baceb3e9b2d32a9ec435295b2fb62068082740768c62e9d82429cdbfc599415b3cc515d61786f02aa5577a57a843475af3ee921a9a5b3eaa10dcbc8e65fd19bb4218392f962c41f745edfbedda425e47e49fe69e45568804001bf1ab041a2328a2c33a2f5cba2d87c9e0e9ed1d4a01e5eb585cd4112aad2f902aab86226f7ddf5ee9b5a442eb3c14806ae328e92f3fe8d111cd3f8d428a4fec6072add7ebf7e29a32eab0d51799683cf7fde102eb6d55cf52e923d1bae5d8c07c21c3098926a6daf6daf3e2d1a53ae61d3c45c0a5a837d7c4d6be64256bc9e0568adfe545e28b1588d149382f384b56e5871a490898456cc43de49677089453c65d929f2da7622d1db394e4ac08577e27106875ffbb2b40dafaaf8eb7df13c62aabd8fa57b55bf33ba84b5a19a2e086e609f590c08236e681eac98f1f43add0caad986315a47d774d7930c3feca199bfcbf74454e85a03be697b4217c02dded3504c170dc4f568795a46583d774aa6727fc6eca91b0ef4b6191ebac415f0f159c1879f9860847c3c17c2d40ea1009b5baf9276f1b5c2c01d9fc4039ba425ce2a61ba02933930859a29888e1071eee1c3029b53b512daac7185844b5122ab88577bee750af5791708c68a38375359cf5b2617c5872fb0191ada62159635bee4a990e3a8112ca12d94f390b91f87e54da1ae45e1fea954808b41d22c1677b8b3b0e99b376dbfbb882cb39967a4be3c13c8b51ca027e390c1be51cb3c476bcb907041d7c5682cdccb3fc937400470c4969446890e9ce0cd432d89e45967eec36431d5c3d6ed6604f946f80ce704136913e6ccfc104d01a21ffbddfb16913695e8ef32856a9a73aa7d4a08ba917919d861a3eadd08702d21f8f18dfdc0879ed6adeb47e26140ac7ece55862d73d3c998642ea7db77f2f05bc72d00510a11d5e4c3cc7da5c4006aa0a0af3fde1bd731c6f445e3587d6f69f205d67f1895435573b4c7ccc7e2e079c6f0f04ad6ea7ece399911f833894e5a1769c781261966cd3bd6f41d822b6de3490171bb4809c663959a053df4d50da1f5476be79cb7c11af63db5db6bae5c1a41fa912479bf8099c822dd72625a81c7c3f1f3be0beba8c0730ca441e3abafe55de36d80b31e3c23e5f9b728073286fcd0c4baa1f605cf922e5371bf504cf888986680abb8566eaf3b987206e46ff2d8aa5ed775d4756e16a95a3efedb963f3422150626fa29885556d37aed5be80336adb749fa8bae657d40e5dfdd932074d548979a8f61911b4a1019146ce953b38fd64635e3f76366937750fbaebea104303ef9c5c524d46b6af56d20434ef18ceb441aa89257aeb91efbbb7717a3d53bfa925746decec5a6aa016ded5a90e1aa1b544c735cf6ac58d4f996bad5e10e3ac1d6acd886ec249ce4ff2c304c0cee61590499ddfc2473d97ae698d2665f0cbf050000000000000000000000006ee1c940030a7aa69ea3c7e8a3bab44aebcc1652688847f47b196d6bcdbdca30b5effcc019cddc822c0cd3b1510e84ddeb86822f30040356f85be316125eb8f98518ced77e415da904b416e6021ccbe431c30cb0bd47d6a218257be227662a68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e2bf22ac619cfafa590d2cbaaebdef4cc2be878d5e7d4e4b48b392ed9a26637501ecd10771c96765899883820950dcf0dc8087507cf6950c0183c118b4a5c77f2bb27099bddaea39a51d73662468c33c2265acbe680a946f3bc6bb7d0d8a969c9922df957820c3d8e0a8004ff3a5e7e4a2733f1ad61ffe307fa51d5b602354b020d9b17385719631b52a819115e076b8a3f6e9356172e39659b9aed70c6b35e42022b5de6e90ee3cf301d42e8885ff479c8a563eb03982139e78747c5cacb5cc61d0a09a284595c7e7489752927445519981c374a811245471a508b2d41f33e804461046f7d5287b88139d2be9dac2fa8e7f563d00201d7e967accdb557a14d0be6cc032e2eb5b132f72308ee66a929423247f0f8cf6fdaff314a4f424c2d05e9c72deb032a11ff9731461ba0fe3faf06586cf48b3f91b89160682bc5d8dec3c746a5cbcf0311f9c7a98bceb117785fa7d31601c5ef4d5b41107e4551dfd9d97293beefb2320321dd63fdd6bc970032bc5232e5d04f626ad6e7b9af237b8c35bc668366f4efe40204cc1d37d437b240e5f329d69ae6719e8bcc95e6c9b7c88ae00115a8d70d37663de5237f2e1d05911062d66e0fd88b84ae4f8d16b9474d0db3c86b2981f21d7772a3d649b3986b86967abf799ff835f1197c497c60c0f2e9e0dbf1f39f89679986599c4c0296b32822d487762dab7a4ae3fb37a2f0bff369ee27a01fb4b6f0d9c0c6d0a2f320a9d2f61a196eb701c9831432f671cd7a1d5fde5e85c007d1e0a8f7d8fce0f2f058c516c5e6bd77f0c2dea49de02239867070a544fa7aadb4ba242753776f00a6d8f29a335766d76c7ee80e9d220d9e7656bdc801abc3c7061aab432446b90b846a76051f1c870c8188b92840dcb182c191c004d6f03344ffdcf9a9a97df0891f12113f4ee2b37ed2642fd2915c7f859a713145b5e5d0508c63a88162300b0fa285b0fd52d98ce8c62edb528bf41402cb89e5a0802fd5af4a9a77419182d5a529895a7f5a3d2772e68f032ac0a6f5506fd256ac94056f2f75fd7b8e70628473eae7c3880c207e6747ba574fa7b73c8b779b216c2e7d1c8d67708c91ef50201a06bf5765f386ce30b2cb849eed20f1e8e6375230c899db3f23bfa8d1f3d4ad7ba7d085605328d2e54e249e0acb05ce92aff474ca5e4bd9c3ad42fbf56037346dd3125dab55fadaeb5918f4c83e51e1c67b58f104830f375443d40080bed7b2ab9cc106f066ee054ffcaff74d01252d3071d316ce6477aa1e3454bfcde7598fd551ce7c89744815716bcea8e59eb34cef529d936fe1edb13122bf2d2928115b1bbef5bf2705ea4fe0c1caf9feb3c7a0a9aa9671753ec8be91d74d625a15f317dfdb09fac2ba7bd76b95220ab1c8e611664060d49f1ef7e6e782a53bc2721df0799061b069b50c2d153cd7cf5f4b0150018ddbef10c77d16d3a4555d6523eda2244e2805bf7608b2328b60eec3fe61acecbf63499f93d278944591b7185e04164f3730cd76b263d035060a967d5e52576b95e6d9c1503106439a52e4404511715a0c54ddfdcd172c4c330020ea678a50d4ef5f4ef02a513347555a4ddab3c83b0c403ce03434aaf0ddf1f28d3d1e9182142e8e7de69e41f4076802e7846677f23f11247f6a5eeb7f483f36a6206a7d8d8fd65e0d1ddcb433ec0dc61d950a3594c8b365a65091111678c9827b4d1c954282bc7eaac9f861a4b69b0d8097d48fa47e4b76cdf7474203a13d155f3df50d1ff54e86b6bc6a230e602a5eb2565304bdbf30c36e9b917c32c4a0a8905ab5f691398dee0f509f39b25abf3c823cfd7443ca11cc67f07c1dffab9b71b1136944a5dd17f0448e9076f081fdee4c6194f7faa4b323cb306ca59c0718556f14563dcaf0720a777f6349f735eaada87e11788ac7eb97cfbbba744ea9d3c4a916e9d2c14a8c4b94a8657b5d96496498e75f41ef430a44e5cfb3c34a1aa52ac006b396d058b7db16b1af0f742822e7c654b7ac84cad4892719c09dc4a271c72202f8266d6795397c9013bfb9f43d44b40a4ea814b6b8fdfd23fe4b574bd6f8a53aa9f1b1668fe3e5a24a2c40168ea7b57a78f590d1d1879509b3d8cc182e83b5b9fc6307ee7b31e018d015b50214a34a37260c26bcc8d9cc4d9d5e8e42e55bd6914a7672a44ee90842932b5a97c1346499afc4003aa355bfddf713d5acfb01354eb3dd17fd5745294f65f525c846eff1bc241db78f44ffa2f3a71a68d976903bd389a52f94a8433fc0db1e3e00e926b69ed03d468888cd016ee6815601efb23cca221a745f1bc8e756c4941cec55fdfd6f4c8bae0b28b54a1f50793bd1b0d9b9a03a1e55ca4da2b5b57152954fdf50d24b7e5b326b742591085a394709f39f8b7fdc0d79b02330a21a2b8a63023aee4e8e810b007890e87852660c5eed16790f2805", "51ac005200ac65", 2, -796780269, "e5b7a021c9598970a47c9d942a5ce92a49863369c76f9c386ee16e621c1767c9"], - ["f216e61704d65e467307e8476f294cd674cf219459323c29cc9b46fa4aa062d72d5bf60793030000000200533b7846a58d38a726d44f2c358dc5e0bcfe9c3597dd26b5668192142e9bc223c240dae3cb0100000001ab25a927140b2154a15bbdf25db42d787786b20634740ace9dc34d9b8dc046dbdebe78f126000000000865ac65516353526361b71e5dfb0c20811070a8b9cbb33b1dafd94d53dabbad638937b631781676137148195f0200000005635300655348fa2ab903f5a803030000000008acab6553516300ab1a70e10200000000076a5165006a6352a853c9030000000002006328c54ed50293a53f01000000000000000000000000aed6bf4cc1bea27da7b2caff87d3d9d6f8677c778276fde626cdd38468fadaba8b262c6170161ae0b572426fbe76d2c233860a526ef589d02865940bd80fdfcbf26b3480e8c255a351457bbcf1a39bf3d706c2e563f80ecdd26c4af6da3e2d50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e42b577596a32e07ac293a0c4de4c32c4c61fdd393837deba8cd65a55a968c03724e4af3cf4151c71ca8879d483eec2b076ca0b7c2e3d266ff80e2b228c1f58b46ce87bfbcad64c7b05d367b52214508b252bed2a54eb4c68d4ac74b7087803420d4d1b958932f420b238b312696b75453fffcc45301b2fa3e55750babfed13021cab5e34459df3a78ef1d45e52569a51541a136a09cd70c144864e5698354cf80303c79f1be5609118c2c7690243df5fe381433724e532d93778bc261c4ca347280a237e8977614c955099d0eb54b91bb8d1aaa8f91f7a3ec2ecc2f1b640b913ea26170e2dc90e34facdfd62e50451231cddf72832f5cfc0333f6f7d38853be6795c0313cf638c3e884d78765713c4623735f3de32bfabb75e7e77197f43d554f3dd1c0217de7bf41d2946f384c4ee6ee1ae16ef435abaf59822f3a472d5caa96d4ae905022430f80b9c121bf53ed337bd3c4e539e165abfdb6edac06dc52555cb09fafcaa030e317f16fbd06f48be127700e46c47d6a327c3d9ec5ad616dad5da55db1486e3022b38ef64f23b4af60da245ef90bdda41447032a56dcc71479994e23d35436d29938c120f2b649cd4bce186abb690b96e3e02c711e88b6e6fca80325513a025d745da15693cb531e9ae28d4071f3f455e1a7527cd11695b30e43420c5ef2e362431b28463138ac17d910f6df493087e661216b5fd514caae249d779fccfa2ab8c5e9827dce325a1d90167fd5f119f92a5c939fcfbc43d8718e5426eb033cf5f4a1d4d8c166ede5f5db4edd625aef60f4e3c37374485d195d43ae0b909966b2c7bb7fcf88796a8f8fe8da06afb1b6b2c956eeb25b7ca6c6a4a609d15d4b9a2350b6e31ae861ba5ab3e41535258ff0401726f9a522a2afe05b636099a312a32fd997cde02f0f92ae6c1bada211d5d9f4fe90e6f07d3e15213c0bb75fb2e1aadecb84331b24680fb7f0c05a310392a947eb1c11091572f35e76edfabc491d978e3c34c3ffdcf8c1633dd7f75324bceaffc5971a9e27076a755217092c7358adb662d65624b1be99d0fad11281ffd35ac3db2539e4bbcb0a06565e80cf0da5c47ca60b8b07fdf696317555df555e0eedd88c86ec1aee8d13d2a97a679edd2dd06dba4d6170aa6f8e18564a146bd18a16a0f23a2dd69dbeb624de55af7c56565c87b07269f4c2842615a63240c20263c9a17c0d15df515fdaa7fe2e13d0329d78e75bd3db5750186445d6ca91e6703f2b190eaf7c3676973a062840fc69bf05deaef025c885398040b6781492957349bbe911729c3d371c334929aac564867e208e7690f433bb0078d85b4d37726bb2309499bab7c723db7dbd20ab491180b57c73475ebed106b5ee6cb50b17f3280b6253d09b467ff66a4a27f5d28e8a115fc42c3ceeac3d1c64ea469072f2e8c749cde284f56d7c3ef682fb2cfe574bc197366072fdf3598a41022c9772a7bf3fcdae65027738bb223eacc222976e4a96ac9184310e715aa0665860a3f97bf89b0d5473b1fececa8ce580863edcd08e1f423bcf832ab1ed1268ed005fe26e6c796db4dce9b226fe8d4adb903a7f919986946520673a896fc490a42d5a7e8c39089189f022ed49bedbc11eb33b800daeaa07a9347e013cacccdea50083cbb3d17f69d8ca9089fb5db92b53025735a4705ea1db9ea82eb1e153f8c6b85c8329d8f3caa588999913de11951c71d26249f48074cc206779883451d052f6d7bc4ed3b80cfa49d692242043e8969e576f6b438f4668a1c28cc56aacba3cdb6d48e8bf73a29817efe3f38216c0d6031d5bb4d278869cc1903d399358b4662b9c3fc9dbbfb2d8a554a4b675219ff015dac30a2e3af2d3adee91a980b37cb661a55a99a58feefb768f28fc2fa554f7a3ad1d5c0b0b76598fc4b8c4d667016b3b98ce7aee2ae2481f60a9a1deb207d922f5fa0fb2a55960becc26056fd7fc256e023c35dc7aaff9c762d49bd81d3228cd7be18329b026d019ff8d2b5340f42518b6fa6521a3d6f5b525a459fbe7c1f9c51bbc9b866126fb84eb84b88221434f29a856075072a73de27e13b29833d78b62ba58cf972cb79c82f5b2601b2c6a674d634b8e56d4309fe3a6b9dd9abe872fa53dd1592238031006046e3501a9f19775ecb3ef826acfa3d77c0249c3c78dd7f0e5b7055268b71f75b802a2b97529322d3e41e31dabfcbe84212923f6e45f6eb46e58d168f8fad893be2b975bf88afc0de01c0b70b520546363df9564abf9655b626eb8e3b68561cf76804d8a82684cf7336c3aa6345ec83a64eddf20000000000000000b8410d01000000001701cfa32c9c237c32a5f9933fa6126a59fefdef036abbbf1b85d4329be1b0edeb79dc15eb5ff70a5a7f365ed25e724cd2c20495fd01574928df651fbb00031d829e88aba4d5d076860963a39b761d0bb1a4e9342f0001131906c8fd4a52a0ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc291a9603a767ed94db1eea13a0ccd816218fcf3552f7085c1df87ca8f0e3cdbab33f9ada42c74abe93aba7362c10b96444a6a95d4aa6a3a53469500275a6862d8ae4b93a79dbb1acdd589c0ac57ada45742c118da952c07ac46ee63bea1720433920cc5a9305c73b286d1d8ece0204c59f1da92b8f557db3ad37d94134d986030f99afac4ba99e123c219e4261e566b26f56af8b2156ef115f4721c8bc976b60032659fd0c280f155cd630cbc8b078d27642f791895db79145c7d8db747ff9d6730a04ae2ce8a93e1a04c6aa8bbb37afa8ab0f5adbb157932da28c3e2aae463a245829b81308d12feba1617739dccc5d4e9a2d336d3e4afcc4740a38caf2ff3a2a62031460fae20424384fc9750d716f8897a5a948e844356bd3c14743c597ed3388de0229df1a16e7d50a127573d849db033c76d356dc6ed3a35dfdda50b8b066b7ccdf032272a3c0fbe6c89f67c3c363f0a7928803307f21c8f888f0cbe2165451575dd802200862354450c5db01e60634c8781dff3692cd650142425184c3136e3656f511031f453e133334b80d68e117e7c6d3f48468e756e0973b63d3435c79028aa1457212affba6b99873b0ef6f56d7b9991397107c6e6362019ddd99a30152719073a262c663e0b5087fd4f6772d1b0329222b006b2ae34187d96522c03646f12c04f6c912372497633ee93777730405caf13d172e5216d513aef52b0551d16fdc14a4e708ef9260bc0aed26a3f30f3d46f6cc224ad20de20bbbff5a6f294c6a694ae17d72b0b0565ee4b14d4c6721a720741d1b1faaecfe58072f74a4c3bc7e2d18f7453126e973bb7eff63a6d7c85559f0d6a1ccaa4e2b29c3cf0c126da466bc48a705290fa00b56ca96845a56961a124970db49c2b7fd78df11446558fa6952c8c9e0327b4ca99f59fb47a094550700dd76b992b819ca292a6e42afecb34d239f0b83ae10f85f20adf09ca74cc8b5d37c930c32be797849c604f56f9ab308f81f001f8e7a470f643a44f2f30a350f236db528781eea72189e9eac4e68465a40e77afd2050a0be8d45c5df477398a8c3cf4e53ae046b6d37abf6cca379d64245f6c56de308d461e0b6725148c4a19fb03e3276f98b789f78e0f858c1530b8853df87a2e7df29bc14d4ddf5386a7a521284113170343ba51c74a0a8fa4525b5358a9ad15d3e9d82608d80d422a25ea9ac2af85185558054fd643404d8829b2a7bb6a46651b448da4ee0534c6b2cf8c99e475cee0c4d4e00714f94a9425b9ed2a4d70376159ad0cdaf9472f881f801b65031c448d54d1fbadb04a71471db9021898eb3ff2a01479808902b7c1330e19bfc5f07e9f2c8612470742de7657d73d0c9ff911459369db420a2b127eb1791a63045870f2c24c80401572215ec1099711405c49efa0844df2ca4125c11e1b2c55fb608c9df413fd20bfb75ec66893f71935794d6b3c16764ef7d4f5539214a8037cc4ae13e099fe85a7b6dfcda53aeda990f9a8f318fba1cb60232ade9696bade933c1bc6067c2b926b2b0602d866ff90a7a71aa22dde3e06db66935e87c7653b2a49e62f65c7199e584ee43849ef127ce8a17bce81cc294e9d6310c7e8686463e42d03489e62818eb4a93bfba71f6f1e2dd72249a6c2caafe7ebd543dedd34875ac11066c2ed40b96834c843255daf8a502536b29e6548316f5160df65c3c7df77a9bf8939f3baa111c6aef3186c1231d2f0d320766ded3f688ad26b7397270390544cb8d65c8b712f558fe74ad681e7020a37bf85486fe91a2f996f5fb1811aaefed655f1f61af569df701652756fbd25397c7e86aa4f1476181b341834712328ee7a493999ae10a4a73029b109ea42a38527511195b9c5b9ee22f725cd06cebafad81a5cb1ba3f275165b32a21192dd331684ddd87b35c5985f7c42f82123dd2b1a3ef773738817468a268ddcedfe09dc25e89ded6195ba7034512c6b432a816901de65ee40492d51aa6503788e897269179e0b661543695cea35fe814e2480abe7395161bad78190e09438fe5785476a0959b292cdb02475831edaa8da10a49aa79129b4f13e77746e9e28ead440262dadfeaf98724f02f7e0e5f16d7ec51c992678b20d8b4930564d06fb897cb2295bc8ec53926fe51032d193f6a1d0e9fb499b7fb9855cab6195dc1e570df56b6ae9ded852a563377326c8596f306c444a4c09f4eeea3d97a0fb1ff68b7ed779973b94194e0f621a5b817337fa6e297f92405c95c6bc1dc0169f98e28cc717764a9371348b34d215a455735b54972bdebdec74bc75063ad2f02e549c53daefc6c7b9c9aaf8811e4fa12ea6cc05176260807f3ed4f45c3d7ad3fcd1877f55b2971a7d460125850abcc4d2ed6bdf9e2ce6e15c10be47f9376116e8d668b6774bcb30358b0d49af968d7d0c725ea4c73ad1b1b8210c02", "65536a5153006a52", 0, 1172551030, "74eba569d5cd0a1608f8169b4a29d0a8da39341b1f0f64a2c496dfbee6300e57"], - ["931d5b050408de43cba439c12faa3ced38a819c29164087ce6822f415a15410d1721e9f3700200000007ab510065acac6533acfbcb4c6ce4ab222af7e2af45a7dca1eafe3daa9fce19fddc02dc1003232f91004ac9000000000552635200acffffffff0e5ba896a60f23586bd56cf8dfd8900af1914d74cc362824c230a38d6a9ca679020000000165b29e9a19a4c3ecce5667f53ad2841162bcf032843bc72da9dd203dd275bdbcc0950a68740300000002ab6affffffff042021e80100000000007b3b6f0500000000026aab84c90b0400000000040000acabb3ebaa010000000009636aacac6a005100530000000003af57ce03000000000000000000000000ae0a73100a2b25147eefd536f40ba0df8f84f13005308d04bed1855d81f6f1209e358590b84121019a1fb68a8664b0d45ac960be200ab2357fd2313e6208ff5d3858e454d5bede4389ed5e829f824a3920c7497868e2c46e1d592af1fc78fa4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d62f6e9fd2a447bce8653e7c4bc361d7ea82ae5f335c154a55c01ed1e4c00dfea83c23ecb3992232575eff5c89fefc0947d7d2dcdd9c0f5b548881bb8cd318ff9ec59da0128d6d855353d6133bcdf2f594789acf172e234d4487938658196d7032c032c8f6fe9b9e42bb3c24a1cefe5c34f672410537b468fe20120f81fec6e40209811dd4a9b19f73e2ed5a78d3fa8b5dde834b36774ed80fa7e100b96c268c7003161ca16f7c0a512dd04113e5677d5f40ef568d9dc21123b01010724113e261190b2f777b5c1d8d806af8ed67761fb50be7d0e81d73a8ec395bfbba2ba269a3ed8c11f69d1f8b93e761fe8b30f4e88a84f8a5d1ab39d31f02349ef68906e4d0538903016a7d3d38fe7bb70c69a922bfa329689142552f162eab4847c24dce60d28bdd022f84006cf5053fbf6968972a6bb52d6f26c04ceeac1fee7caae28b4d9e9a5a4c02053ac080cc2cfe73d143da493da2bccf2a235cb4fbee1a53acca722aef5721ec032518b6ac7bb653a95b2709d73169a783bb49493b7ccb5273c1ebaafbbf354ca7030523c301a4bd7e2bbb453605a44b18e334b8e3d16752824c882835715633b2babea3126db377418c39d6e97a79eb3a951321c02d101564d090036b3e7cad606bbbf0d20e47a8141d6e7f8e3325266d83e6d3e920babf35913bb29622ff4fd134e3d467e2d72ce62c39781a4758094ff35c1290eb35ea469baff4782cff32fa5559f9215ae6033812f3035883213f92ff0893773e1b0614e70645ff43948e542e0baca5bad99bf8cdf17f11c4073d9f4aaa40ca71e3f44929e56e5a4a4e64c070e34766039fe43305dbf30e46b7cc39c0933b28f99e68464475af9ffd37962e5c134300b8d70b0aad68b854360493490fea41866b38489764422d2d36ef5e6677bb88aba572638439fbd816a6cda1a746c5117506d821cd70f69aa84bfccb0c94e6c5a0d880dae1933580d806a9af3d1db779550a7c0345480e361d0fc5d491999924707938009d3055faafcd8b1d9d7e92befb4371c4837b87307493ad96b87ff67467297e71bbd950ba8dfcd5d35c967189079bf59438b77b8a0660b5b6675fe1154341d594a71a2fd5a9a0fef37199c457437db4ea3c39e471df0e888d42af61fd6c8109738525521ed62162d9679682c0a1ee96d8e0116e9961ae9f6645366a8c9877a03237f0711e5de6abfd0fe614d27fd0b89866d305c2847af6418937d45e30f21533a92598f94c8706b608489c2d8c35ce591030aab55e963ba770b2edea0ce68124be57119c2330eefae4f34599e99670a5db5002d7589cde10b85a61190a554fb5ac1facf6673ae35fd671dd57371a7f6ac412d79ad1fd994b339070e87ed5a53c40d25392a351525cdf4de5f95bb571eda0985743c63bf7d5471e1b506408afc925bbe28c4c183d4e5e19e677bd72c9f677f2f21de3c7c56270e92f20b8e7c95e536aa7a4b11298ffb7db290b6dfe72e9d84ddcc7a1e329eda112d4c4d691c699d373dec7dad7b872cc502a5ae24e6f27ce32c87b7491a0dea89e21ef34753006e389907dbe32183c3ae5e9c62ae954163e7513e18198fe51f4862b92b8c3950515a088318815cf68d0f0e7fd38ba15bf4e07e89c4c8c7c344844bb47d759498ed6333c084e2b523a305a4a9e60f52e4a29b497822e43ca38bef1718a482c04a2b62e76268556cd342dcb5076d92c7b5c7199bc689461f351f18518e0b614d624c3672f8fe5a7bf3bef829c833fb78fb0a7698b42f9f66d6f89a09693c1c1e12214790f2e8ed667520d7b536a670bc5ca365db06404bde3c20724a322d48856465143351f5a58ccad6807d129ff531877d0bae09153c852b9ef6094de0eb7ce4c40c46b77caef173af9aa1a49966b4fb0b4a153cc7db2cef4929b7b241a55b609f912facc9296adea2ca20c797010722dd1b7b0e55aba7b4686804433ff86f70be599b025b34259187826e965d08b14a6327a9899900e8d1ee6e4d0d9c3701ed72048dfc94495e9edfb581e172d2648450f3ca76bb2e135976d19b4ed0763c61896069e4e9c58d6530f4d729656ec1e701eb4c90936c498209b44934b02f20e41aeeb521ed8053aa5c601037172b357dce2a54b84eee334253cc0bf170dd8964065160c54ec3a51f8180dbe9f6f1b07f1cfc8a97359ee6dd305199de387c10029d4110a583afc76bc4e3ea491c4795255b2c3bbaab1f4ad20bb27571f31fed97d0655261257013c71634b7e02dd08c5cd1f4f37a3e38ed876950fbe4e31f2d2a9dbe6c742f3b8efd90a679b25c912c405000000000000000000000000193bc408e118712b2eed44a69f5a5dc531c8c764edfb344314f4c0e213965695b95da5255e7f9bfc0701decef5765e32f334b7897ee45f9385b3422ed83447d4bc841eaaae792375eb45c84d6d8cbfa6aea4ba6cd27e65fc486af56fa27da9c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000724246e81d38abe3e042f5ecf000807aa2a671aa04a2fab468938ff1e782b14712eed261a89a9b2bd3f1afa26f8983ee42ef3e623c261f591040752682b4d1934f21f12cc3e6647f4af571cd27532ca33c677951ec0843993df002600d1c83366d53a3826c7e7fd33c465e3a8adccae90d16778e93c0ecf1f175cbcf7b966a9c030ee6c048a29e8307fdffc6db09830478a408002ea1fc95d4a66d5120fa1d0278032c77ec6a4f9ee0c4255a55824395631993c8bd871bfa899bacc347e9fdae1e9c0b058f8fa34dc1f0a160310120ee0ee7d71874b3019ad4e706cfd8e4858efb1cf6121ef4c8bdb82927f688fbd673780de0a8b1db2cc25de59f9a8c05c42a9da7ae0308bce83dd4e9cd08cf0820aa9b2f3f0bf03115efa8aa4816f19f8262229cb7540225a3dbde7e8030b607f64b879e9162c6368e2477c8bd9a36583c9d1f8f2a96a203213148e78d9ee9eca7b831438236e2697ba6cbae0228b391aa9bdecf8d764a9e020c4d19b1fde72ccb102478c7496b71e03daf52df30dceeef245972955c35e9d9020c66f9f93dc00b934bfb10c28badd77f1ced57608c403069b703d2db7d7c3f3ae5d7dbbba392acb49432feffbe2264f009c018ee5474da2d9a566b98df2c5abfe22c108b5b4ba4b6ad876b3d98b2bab6445fb5b3905fa527d486690f0bb2295b0fbc2b183b4a12ff6e3591bc5fb71add0f150e4b30d4ba253527c65aedec85fac7ac26474d4ac7b0cf239083361e6d8b04e2e0c89407f120514b034c373323b06f101ca0d61e9d5b0a6082ce68ba1fe42e4f343deaa1e274b11249efc342bccb9d3c282e7cfb7f54aaf66d7d1e546e9c18f30a20da243a3fd90b7cee8688df9e9ac60f1b647a6c7f0255a676397995156062c012e2896768665f47d161b59344bba4a60dbb827797b29a6ded9277201e40222c12a65e1d6829cb4c7b2d23c8458491e994e6cedf0a186c4829e6dbdcb321565c3318ce0cd0b24ae3924cc4e42fbbb5541d21e16e11598e9faac19f2d2c6f021ea577d52f435712a44b777997986d29fc5671d50fee1eec7e4c4c577cca811cd5220ae71006408f0b60ad135a93b789dbbf9cba3cea3f4046e6209a882105c3942f8fd2a811114db6caf011ef06aea69cf8af708d9e705a5ea8b0782f54d1a65824233c443cb0beddf16439b754c225881b59b95380187ced39baea643edd1f3d23406a4b670a55f3a8475cd0cf5f73cb5942f4ca5f688d8df13ae211cf7335cd388074c9da9bacb06dd2be075612739be2cfbfa23a387df90b1301bac8ef50c8b2220456b1d403615bbd85fd47a05ee65bc918d2373505ad3f01dcfe433bf73ff8631c993465ce233f75a8212672b487b67319aa7edf8f630b502e7074afc789077369da17d303a51cea4a99297f166ea46093f82a44402a222a4db398ce572659deda2be6cc72d3e4b29f473ed60bcf1eb283096f6fc43e3357ba96ab041a2f7a2071c2080f329fa8079fb55d669d08b4611cc7a80927fdf7432d4c1c09a0176eb2a72ac7b053542e5fff9dbb8dffad6ef6a0241a46bb6b5f1452059e76a36efc749b4c7e1a3a748beee0bce09474a42db205a9593d54bb966d8efa404356f38644e50c47272940cacfda7231c407027b0a954fd4544144cb882870b08135feea6357b9d37b77743d1fb18f9ae1ca2211c2c0da9e3616f60eb9e7c1d93653abf2a81fd3a10bb05b9dab202116c640dd9dace9d631cfc273df39f657e8ac3b340484f66e741aed3e35ffb90128ff155e6a3c45d6914138cd164b2c797176a16f1bf9c9bd19b7ffa6a866e15dbf060ab3d102ca82b519410e2dd7595ac622505a6fd59e9b6b0003c05f6fbfc114947498015c6118876fa1997545160afe14383623111c8324cb3762a314ab55d0399523bb788029b62bb4da24668e3a61ea3a1279c27a304b5950f84916133dc52e1ef5cd4a34ee418135544ffd2dff893fd4a1f7fa5e837e3cf1f12f587697205052b619b645ef7dd82d4725782e73805245b8400f0eca7422d0647f1b86bf0fb896326100b9e4bc30dbb882e7d1f1a814861d6735f3fb239952f569acf3b9a13264d951bee3b5b5d1ef448c37f0eedb07a0fa3bcc299d2239c5774cbb46a0891e27b277fb6af272f9238b2602e891b8b983858ad53d5142b726e3e71353ccd1c82c6b27774c773e903a2a93393d40c153145d21dc8e3ceff5cb3cc1a16669025777a33d9c8b986e6e42658c60531b4f2c3248794c70b41e50339daaf3a1dbe35fb84047da5ffe845e2dde760c1b66b508550000000000000000f886890100000000e80353b9eb784d8aa119847b20c4b1f23c0a177a0a84fda3401a2b61fe199aa1c026edead450f8218fb949380f7853eda4d3b44f950559d97d3798f775ea779678320253be6566c23561f326d2ef04ebe404bfd21ba930cdf0cf65c58b4df991000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000edbd8cb502695c951b40f1a346a6813cd263906b849ae5a85127579083b9d67b8e3290cf95025b805709a93e360f8206a91d6391876e2f8fc9f8ec4e83b1e63bd4915507671d4a3ab9e51e0ccf3f2e3445f2bece157d7b00d84a780ad488c3627a6d9fda774d0278260ee1da87a844e10e32377f67bf6421170caae74e4375c031b30e9c2826ce2a3cd33901fc511e461cacc2817333d949dca4e4cc7672e9cda0207d8c595a91417a4b78b6c80514a6d903c1e953b50ec8b4d40213b03c7f612430b1947b4c46b74c75ad94d63ff18a44423cc231cb725bd797e90e0b2881592fc1a222c68be31e49031291edf40f292f87639a833d7d6e9db868b4a9c4ebd242ce60211c89df481b5a5e5cd9a973bdcfd5dd41d4d943ad9c4675a90dfe6377c9af42d031aa5e3094a555c87e8ffcf073903f028b840df7413f6f3f3ceb78e4b78075b95032873cc2982d03b8f3d22f64b7e820e837b3a868c1579f63c61418706ba5b0de3022ce8a9f1d8d28891ede031128dfb2b7ef839743fa19ce4497525e120b834c6df02173d9e3c5abe12aedb636af9c618f61a23809a02da28cc2d5a9886a5f043af31d018584098e54f7ac26a8277ea44d0cd5e2289eae3dc8b95d2af6023995380213df8ab0090e7d8dd7c013fdfc9790f7adb4444315b3c0268705dc3801195ade88b4bf9eb258ebfee4f7c3f685322ec3c394bbca7fb0befddd30dd58f32d30bff2f6f2119740cfaf019577ccff979f9ec7c09b949ec1ef7238e6906de2a9074981dfdf56b709958e84b34ac2354aa68ea21574b6b4a32d18407ac244e9eedf85e82697abdffc2277c44684406499c6e5b00e053f9c47d6bef49f316cb3c96ec5629606f963789d71e6a2d0597178ac9339f37473e6d133ab0de2e5a8012dbbda90cb2dbd4a95db6b5dec9fadb4ef0295475b10807303349c85f9a4bcd098ea975acfb0e7a9c2b83fa12eb73c7aacb428cec60f90e256dc3c3e1f36710980860cd514c2099a99c667f8c4e738cac705b7614d94054ce44a035ec2b31090f5db17bd2bc0c0293f4d6c1cbd0de8d1a74982b09867b564696f5994bf45bb5b54cafc52034ef2ffe41b44fdd2c2ff7a87cdb3d76f119acbfd80bac40cd9c8620c9945c36371b373af221333b10836e81ad329f86543818bbee6ed104fc836d771c33719006abf74c3eb7f452e85bc8f866d2dc185b7df154c5cfe3d3854c40c3c0ef498a4a43bbc761b8f026a1df7353435a2d9024fd09f65b205e4e9e413015cf336c20485cd75ff3e11360e46e6a0e16578001d06188fb48a7d82792da6e1dea911893dfd1159d1e9f27017e039d608de8cc7eef0690ae1ed6e9cbcaef44e9f571c19b09be1bf2fedd3e20a3df484740ed08026b2b2aa315b57230303511671184e7e23de98d87cea42e3b8c62bf8f07ef4c5ec54ff38deedfc56388985f2ce4f4005a5ff5cb62d47f39f5f6b8d2bdf9506393ce500d1bde2941c46ca63da9691e1f50634261897375eb3a9dec25b78d47d9ab278fb0355408b78823e24d647c0d184a5eb972ba34a39975201d2f5708b2c5206c7dada38cd57938b0e5213d3e89b1525d4e9fd084fe229bf9a6ace4cf8eee86990c2b36bf7f1b3c6a49e016f8a6f7b31dfc606e3d3d6f21167b4e7e352ab7a484bcfb6db8f026689d2b05c88c3e66d124d3432779bdcfc99e03c3158d9e79d84267bcd050ec567c03984600f867f2b7468421d933a9a8d78eeef69d6784834baa6f66de04839f93c1913f84acf524c8a8631241879e2b7c79b87cd052b13f98432a3312ab6134bfda66e98fff1da7e697cf5375b4a1974f68542693e2adab4b77b63657f83dd759d4e70d822c78b72dd24f2e951cb80c3c026df36c716e4572bbf4e58e12827209a8f730980f04d560479e13a6c5af887f197dfcfab15c6aa36135a5a9a15058d76681e8560c0b12cccfc322e998b8759039dde9048b09fa898f2474e61c1a960d85784aa77df6b9525743746e22fbcab65e3fcaf2161eae56fae6b212d4aad0e426d04bdf96fdc36f14bffca7ed7bc260b41bb12f62bad51cfb9b27a87b3484fe940fac88817c61225849e625f0f196b351bb484116005e53b03cbcfc40dd8bf382a1b340f1779ba4d1ba009007c871a06477ff365a86df0622ec74d75877eacfc2c283a2e23047f6cda9f591d666e03c54ab9957b6c43e71eeeee101dc02773fa203dcba609a6973ace33b0235c4d5870b2489d4eab921e957b2e7d4630b8c21a5720cacb1e344720d9a9c050e7b4fce4820b37f9b38a1512e8aaa34f23fc12f0ebd1f1b356231ca301b7e863d7464a4cde87386bad92d6a0b995542145d41d908cd3ff6201dc5308a5c8a730bb66302edc9620ee073a683caee52ebb67446d9ead88a009f0e9576a4ce6d87090168480cdb53f8a8e9e53409", "5200636aac656365", 2, -956787194, "d9b03fe192df1b358701dbcd5ec5bb390ac63d16c87b7f5cb61791d44d7ace68"], - ["f5132c83018ceaaa7d17e35feb0973b073563a6353d9c9483f4af61bbe15180648e0ae429b01000000016ac3f5ab4c015bbc0c0200000000095351ab63005365000000000000", "6aac5265536a", 0, 1055742825, "3f902efea4b298c0ddaac3ed4d1ceccb47e991c63d3eb88c33830461b93fbbaf"], - ["aa0e5a7d037123cb16e271e11204fa1e33668b144fc86bed1b77dbd3a09c1ee856a7588c440000000007516a52abab6a51ffffffffe46fe0cd80ae316cfb6d0a85e718da2ec1483e8da759925cd15fbff224cbbb1603000000066a005265ab519de29f4d8ce7d836bf804fd9b22677211bcc5c394aeb9ba2149481cb2f6f6554e0d6c21f0100000000ffffffff02a4cfc9040000000004ac630052a3e91a01000000000451ab53ac0000000001b9e06d0100000000000000000000000071ddb17d1247af8b1a5aa8443a498c50a4c846a09e77a694a86fca9b70b311efca5f0182688a18aad51a8565547d9138de9fd8df4d642fb5d260fba28b3511551ea0a0e4214f257fd45319ed36467bff2e93ba8a7395bdf5e14e61ada4025c2d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b46930594f661ea98fe2c0fd602ab26a5d8076757706a8d30a2f2fabcef2f4e34958971911f5a5dce0f145682d71976dc76f790adf3d8cdc63b2416ad7227448f46274d696e591419323357ae47815946413ff488adcb4fa138ee19e948f2925b708ddfab265ee975c76bb4196e28e81ba3a7f43d75cad1de3b601f02b20aba0022b2fa59fcf83bb7e09171150a654c65a0e77650b953d0bcba88b9c782a31beb70330407ae9a5a1b0c1b07a765e02412816eef12d703e2b9098992a1c7e05efa3c00b20da63b5d5acf40d758baf57c804d0054bea986690c2d498867959198d3f98051d59ff2c4a3be5f87cf148d31107afa58204a85c4fe22ada9c10e60244fc49450229a9faff414bc1c844e978549eab2da1db610cb809777016df2eeafb16d45676030c1fc2f3629e8b00f96076c8f35ff2613113a52a7e76f850365032d55dccdfac022b95f7b9003c4bea064cea87de599eafad89a1b5b39a579afd48fa2c18afa43a031a5071433e0d8444c106440538543663d3a4ab6915409d20509473fe9593d4ee030ee23acb632387f4308977757f777b5bce0b7ccf53cce7e9c7f850f475fe938960837596da9c40eda2da85a4eeef7c3a0a4f5c31734a4be2a6cecb0af5052dc856d9c02d500bd0245adc5c22d25e3d8d2be09e3dcb0206e8360c9cf18f9f6b381ae4e22622ff75eac9dfdb182fad1704f45508287ff306d576e1ec93db5801b7fc585ebaa239edc2cfde99b76b18e4509f7464baae60e5a3d8efcada522a7d797380aac50901b57e7a0aa55cb2c92f72841baa72b2552d230a5219d0af0252811c218866aa68728ec521d229cd4558e580654c7e8b8072946c792d59c22cc4dc46effef480c35e306ea6813b6266cb4b43e2a2d723c90b3c5e9a92cb87bbf7ac3ff3ceeaefadb2aafb5b73ba9fae5924502cee6a0fed3634cc031df4053fb3062a862f4891fe296435a07cf3a48ab8fdd9c3c9e065bcc507a0c57a1ef522b798f47cdfa7d07ef5321b37d6f0ae4a9c52906c7e5c881e1c1f4a21af0a3f7a87dce9a1408771e0526ae3643b9d7568e3940eeed695c2336e828ad3ad71377313fbaf431c525a4dbf862537f087045dc6403a067622c42cf4caffc38de7cfc2012a9ae1da75a734f3bddba97688c0f67f269acb058482cc86adcb2f0221bcbca8d966ab9adf26a184656594b8d613c913cf8da9f021a76300bab89d910c6e3aaaba1d61c1766b3451187d752c78ede87617c37d9164286633ff9f8917d9cc1d7ddd472e4b87722c1b40c76788c21e1dcb4eb645df9c94a05681164adf58572809d8a6f4166d406e3afc8d92778b735c210d5d863c06ec8444fbb3da06787e007efa6e5d8c7d9abfb8bc3465964d72cd7ad28aaf0e6174c9f4d33290faa49f3147d98c80548b9db82d29c5231f292f4acd2e190875872023ece9d1578e5e5b444be75644ae010be4defbe125353c33d5affe8322423119a5cb33724bfea961772c2a53501d0260a41c177f87e1ffa4a1351a7f240793ce5b567354d3e54d78a41e64e157ea3aa06c0e86b0e66c9a4567b2c2cfb708c4cf5ca3ed891c08fb099fb73c6e846e68bb72488826a5436969076203675b043cd3b8409194127c7ec1f9fd52579843a9ef9b2336b638aea2177bba267324b100d321324388da888be92513d504c10ca61cedaf518081d939d3b87fee9e6b697996ffac594775821aa88c7c6e92db68f8cd5ad198e8d1f04743ac275d9b25a0680748346cafc36d1100465f3ae83ed63190001a94cce0feca6173be30732e6578c57753e7b104379b91433b752f8c109dac12488289ce7bdd1d80bc2d71add9ea5c77f08ac9c025f4227245a74d809775862b1a9ac759f40648a6807b75a93c84be9e07bf108efcf3ce4b9003d817cb684a999584238e1c5dc3ff857092122292e93256a61fa96a5691cd181e0ee106d9f655e1264f0cecfd26c246eab9fbe299a2a8eccc7c83d5f2cc7837ba1020c0baf1d87d44aabb279ea552ec2660cc887592090df6e010f784aaaaab737a66f21d85bcc2c3da17934bb05e5ce65f91cf21f07c6f10386a962df32d13126cf77dc48c4fcc727eda7586cd2fc245f9f09324631c6709ffc2e4d38402700e805fe05a3c016d2ed4ae9cb042b3407e1fa1d895cc64a1986e38521afe213179d8db8dd8b45ddaa740effe292101337086829766c1d2d4b4de8bfeeec6cf6c851097ae0b0f4ba93fe25dc9c3ead7801d22e8baf4bcaad41963da202ac7742ca5ca7d93e8fabbbfc1f1155a2f183428b25c7e6e33cd016cf1dad235cb82848e339fa49a838262b315f3d3c8786a74b4e7053e48bb7170704ca10c0d6998238ab788d85d50bbec037db506967d1afcfe4e581455f737c300e9cb30894f8c1a995d284f147a147af86a3a0fcaae45aaf1463d0d", "515353ac6300", 1, 2865390, "279250d8f887d29f299f2ea5baf28985957c5f294cb8e6dec842e735b57ea033"], - ["4d97089a02ab0ed372ec190025feb89731c0e52e74e1aff6227ddb53a108c53ebe378e2ca402000000086a6a526aac006351ffffffff4092f1af0be76c780e8358dec6d4d745e679945bba9669c7260d55a0c9c260030100000005526a6a5100ffffffff03c41e3303000000000365acaba132df050000000000ccd88c040000000004ab656a6500000000", "51acac006300", 0, -1925098182, "eb395b6a5f87e75aaf9ceda494314f305d60610da4aeb82b2fb35afa557157b2"], - ["32b5e5f101e7e90f162c2016d38b774608f568c917fccfaaddf88f0207fdca9e888785fdab0200000009abac63636a53ab5265ffffffff027349d20200000000046565516aaf1c1e020000000009516300ab6a6aacab6a0d341760", "ac526a636a51", 0, 1050565107, "d9938c3c6300f51c233e2b094d330416d0639ace5d8fc5382e73d2ce78af0a71"], - ["4ac8d6a1021c51414a92c123c75c1da57edd4a22e99d9a8fad0b55f33b652ae1d164c317070200000004ab5100530a0f32e67d37611bb244217f59de40d20ac4fcc6a53279b0889e29fe64737747c6d8532a010000000551656a00535baab3d404b9c9cf020000000004535263ab308a3f050000000006ac65ab0065ac218fc2040000000006006aab65abac16aacd0300000000066a6a5265526a00000000", "52", 1, -173005906, "78d369b9852c64abb24b5d7348b140f28135ea248da53356349d1499872e9d0b"], - ["c5a8bbfa030668d48f9645858e5adda4cc05a03d598f24f2caefcec2ab3f145696e07fae930100000000ffffffff46cc05252837d9bee8f9335a04c69b4641a5ce767608379cb246a543386b435801000000002cafee77cc2b67d631dae9ad42b2d47a57c80b0365c75249af6e34111b8c5f97c6f090c90100000003ac6a52ffffffff017a42c703000000000352ab5200000000", "52", 2, -622472365, "df6cc514ce1c44f7f302f6e15b27ccf8504c8ef6aa0e5c02f63bb95c4e2d18a7"], - ["ac2648e90208a6997bbb57dd2289bdb7482c1b7565603c18e09ccea7d82a79efb84638c2e2000000000153ffffffff711fae6be6588c24bff48b87367184cc7ef37d4b2b7b9ce19bb5e4d61288a201020000000800635351ac650052ffffffff028eef2e040000000008536a51ab51ab53ac74fcf3030000000005535253ac511236d78e", "ac5352005265650065", 1, 1223022458, "8fbe583841e6c94d2c19be54a1d813bdcd28c95a7e87f7d2a372b703e7f1cd50"], - ["fde6dd3403cf0b3ced21eeadae43508b5c30eddd5439a4996311a70c5ba016c0648dfd445e0000000002510050c4d481141e56f551fb59712ef671620173ece9631ac02c1e639307c0b40a9e7bc411d90300000002516a621814daf93c1870506872ec0cf294a03535b73cc88d385dd089037855afd0b8c29b6a0100000000096a53ab5352535151abcee4e2a2041e1700000000000000ee7228030000000004525263514ec02500000000000565ab006365d7d8bb000000000006ac6352ab5365fe71331503f2e6c8030000000000000000000000004bd7c0009fcb08248eb4ffe1d21aeaccbb95cea1dfde26fe8e469bcd2c3ccfe429b0241eb3192c5796df13066096120293b098fc562ed5b60c4fa8616e4ff1db1d6e2aa9127b8bafacde3cd3c6a3b68f4706bbbd94c6007194c264f9abb27aec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000650db20c3fb2e279cb71e3db42f9ed81c785b4bb1a7b95552392e39ce5d066b7af05db776a6aefb33f83d71dab9ff578ad05df55b4e4729569ee4ed65f8f8a24164351b764179ae3f89fd552ac6807921c8ed4728444fa4b7de8ed9b1d1f6c91aa78fb299494e7027d89c68163ec93431ac558b35485fdf01aca6b2ecf6d520c03260572c0f425c3ac0f5ddf2e565827c0c9c7de4598a25467d1521eeb13f81fac02108a7e710d17507d964231a2f059acb864b2dba29372113b54cb4ce7c88cc5a00b16484fcde4a56f06558a82b387b6069324f73cb9b2c1b46be7e5948997cf6eb72d656388b58517b83d6de0c6821b5607e83d6aaf23d8259f513c0fe1622bb80202129f3abd7ab0663f247aee86cecb49633e538c7a0d73f292df8508d0ab59c10b022ee4f993cdb2dfd0bbea7249ed14f7099fa8516ed40f22f0c522b063d1e3935b0325fdea70ec76589300680aa49891b4f0be839512ee7f7a1b04f1d1d452d385ec032fc28caad9b27c51f26ef1af38d6cfdb51c25a0122fac70617dac808d3cbd73e030c690624e87319da02e77d91fcf619cd60f56cf73b13999a50ac4c85e67f809c106278a2e09203b7a2ef70492937828fa1db01d8f1b07ce92660eeedc98fac7013dd4c4a2c6c9228dbb01331fbffd7f8f2015a3ea632ea082344445ff5ff973d75bb7b8cf999a4f2342b61289b67a13850b8923ffc85fdec34c40dbcfdb56be8cb323b0c773677b55bf300a90cb9354dc6b5f747a1a6ad4767b59d9662d1a5795b24d14ac19847f6728fe382f6d6e0daadd0322215a65301ded56efa46534546e4c0167249aea40b8d77e10968367ff69dd3a673981e8dfe5993d2efc398338d8c630776a5fdeb262a0b50f93096ccb540e6f4f187da393037c30a98aa1344e46046cfa11d8a4e9643859c4d512fc93015e71db14655520188379f56003836c9fbe151d9055a4b55959f6ce3828cb279f3d9622d7235cd46136279d2e39d93471ea8a0e53a050829eca78e356f7d945798673e60faf638f2cc8a4035f865a45c7b0d6cdb2f4edc04b050d191707586e091b8890cc91235b00f84d84cdef81cede10989cd269209fef5195ca3eb32ee4a915c5746b7ea4dde6f356a17a775ec8330736a9557c7184281a4153b8ec037ce222eb7af6917d95d22081fb743e2f62dfb83e37c3643b4133fe629349d40ad10c3a1c8ea13435a83415950fafa375fecc153e84b81719d3e3a605c4c46e87ba59582d1aa39988338281a542bb37efc2d1bf6d5a717d527696e3684a711be9ea626c48b2535d05d383c28084940d92f5adce72882b294a7fa23dca2cb1f853f671443b151add8512faeffe10d6a0516c2592a8c877302c807c222736d52b5d3df2b551bc1aa851dba67ca867f1892d084643b4acfa48622163cd25d8316a5e804db495275f4c95401bf0c9f86bbee8da28775a4c1fecc8482eb1664d6f9b654e368f31bb0e0ee57ecb2ac878122eb98047853e52f802f6abfb5858b3fb726e9ab8805e740513d7f1665ad7211db79b42947b8fe320aa8a87988535b4eaca1bcafd10104a8fb133b2de796a89d4ffe057f58ce874733792769c3174e39e7857150c53ff5d30c293bdd4ef601f0c8505bd7bc3801adbd790542ca2c81853a12f82867a24768bce00771de693f06d4dde4c7e2fc53c81fbd9a53cdead1cc520a25576d54b248bd3fcfefee384e10ac2e4778070ae21eff11619859ae1371a0f5ec32d78a46f657e877f2cd73fc29e08e64a7938756c4d22ed18407238c6e21d615fac8bbb1fb525422dc8614785b8bf4bddf8d9ea043073123ad37a972f4c41b128c57ac13f6fa94c34509605d78b1fbd8e2cced5e9efe9219f9d89bf6e4586ed6b184eab88c1ce9505ad0921df38fad8501cc1a79f6bbdfe29edd3caaf24428a61976b5ce3b82e22d330000df2eee0bf7d6d41f87b6cb018b0e70948e58d359214b7762ab7ac694da0deb7c94a37ed5db93ae57f020bc3c69d26e46dfd32f9da04f443e9c61631466a109c98e99f3367bb8bfc197fc6a4b657b4873423a235cdb5c156fe2c6411906138320ec114cc117002db45017d77071cfacd2738e2ba3745a432560c5076dd72016f6fe36f43a866325d00c3133052ece931338cf435015e9081d9cf6f0540cb6048a90cd925ff044b0f03421804514ce8b30665caf07b41897a5e1290fae5fec219016026f35fc122c924c6b91f2895be1fc18417555b2ef6fee1421d4b973b9ad4e946d86a9d3259e38c59e296f7325f4eb54cfcfd9617c26840000000000000000ffee15010000000031ad32008a6cd0b89b21d0801ccd0afe69588112f09d7c2a59c268bb59464fcbcf4ffd5d584500dd6645adf96a965dbdc7a9a355125669527c98e1f9f4c33f37620d3ef47867fd5bba163f37527a3cd14ad9859d74b71ad9d4e6571e352a49ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1354cad0881a4ccaf56ae491dc64f371aa845cc06ac1f9c6da10f85743a5608327aea011288cb8966e3978905fcda1e4898677fca4934eeafb3c00913794ef37b3df73bff38324ebfa5637978d5c6af78a847c7fa8d97a744d48d955d399183e55d008fb44004c8308927db01400e8dda91b93503f3051e451441c0110abb3b0226a360069e64ac40e66f925ff63f0e824dbf9b811a10ca4a3a260856a9aead92020950609669da8fbf11e5d8ac6ce42648769944ef99d5a76d301a81357e7852180b194d5016337e52c4a473e41b9511bb1e09a1550103abb69bda3c1e373b8f59611225a6986b5fdba99f956bf7a089a6dba207b9a488ea57a0a3d63a6526adcfb902109868d402b350e5bf7f071d6ffb1743caf64a8ec81d12044378b6421b4b9cf5020802c586b7f764300ae609092616c4bd9b7cc3c33b222c643fcdf6cf5bc23212030f40ad181dd4f66b41274be43937781320ef750581f2e660614788fadc36f85a021b7faae78ede3c8ccb3cb77e74fea40d2999908a468824a8082f9e9be1eeb08e03103ea2ad4d214579f5696716716cb90563fbc6faba1238b8bd0c11e27d1ab1c530107f42736b7f5c0bd99c58adbe39ee8bcaff270f49d0598455a008a7019fa31a31da138335aeac858cd9b151e2dafa1d8de37510a943834ca5818c28bb359f29904c7c57f22619936918bbade8312a46d121a5c042dfc911a4c2b75d477ca506691b4142eb93043d6ec4d69428027492f5cfb6dc8a0248b636985b4ebef8f93b2487632cdd45bf307d8d56e9b0490630f5eccb213683f2217165ec6884ce9a97ea9116abfb84dcf79d412e24ec465133a6efc1b77e6251a16526982cab2b701c112d91db4f53776fef36c29cda68fd5d6073e8d0321ed9b599a9fddf06cc6140d3debcab799436daeca6b302b5aba2ded1eda8fe21a6d7e8d92a7db1eb5ece85adf0a73ad7efea8f6a9641a6912e403dd97a9e22d1df579010f268275d30104b8925fa09a6166c19a4f72374c06097751520803b40250732758b33a8dac8b287f84fb7033be0bbc279b3fc3eeab7d2db77002bfe7d278e4a533f5cfc3330183187579813434444a248262e9cc59e22f0a1e8eb30cb8b6f7725658cddd703aac16cc9f150279239c04413ccf3fe10b48b291c6055dff824c2e46e076b7dec3fb1a1ac516a546f44b8aae19ab964138ef913b1c4cd18e0a907a80adff15b03a4410ee2d50533750c1ab279c093a9c869e2ca963e0b397c5b2dd339e67e29c2ebc4c9ce133e7cc5161d89600de6651ac44ffb264aa75f5d040d5c9c89605538006b0777a3bd42701cc5e461297dd2c9bb971427b7e45ab80b997c3185c9bbcbb100ae29275f1db4d76a5f1a42ba1a0f75e430828daf09f99888ea4db80b67ff394e278d36d51a0b3e74ffe035ea2c33a27494c4e30668bb32a9dc286e2a8a17262e841bc9978bda141063161a2795306eb9dab1b87cfdb61fa960285bb381cc1f5f371da48a45008278c626c6fad470fb124cec49e50f24c96f6dba516d060088d83af6ab83827460517d16158d3afdd52af4efa73ae0502419ccdb112fa94a5371e232ce09c949995fe7b2544e7b53984b4142770b4e9f60935327e7585cfc05ad6533a3c87cd245f211af065674143603a23362dcf8573a76e18485f0cb38f80f9d4a2032decb328ccb527fb6bbdc187ddc5d9ce0ebba0ec0c3338da2f88f709e52faf693837165542410921f184f5e81c57b921f0a5520d22fee7843587825d8dd734417f1752b4d17104baa579be70cfcec8f49fd968822fb05870787e50b8a0bd0dded3065de3cb810ef02bf4239e725a8609e6dad3c3fd10f4df7e82e74ef66d909b9af2e315bced62d32aff959c7492aaf1d5edb615f19ed8978c9ec60912dbe964dfcf35b2010558e9c1777ffc6fff9c28bd285a607bab11c1a2344d753fa0d3aac1de14d99a288422fae796cb9bbfba90e6388b76a1f2e88607e3c7aebe15cdf5ec1cc47cde6473df99d50047a74a74e26a591b747d4108831aaaf3f863392d228db88179f13b3ac8028f7d6c46d896936911849384952556b7f55e368cb0a2f0338eacbf3908124de2a3095ad31fb6151a2a3b19fa2ae86a4e2c02cee152c885ebceabd6e7a15d83fae288336c257b49faba5dbe91b0ee90c6e3646bee2de3a72f8e7c2380712137c93c9ddbdfa7967d3c760c0652a3f0493179c58d0216647650f40e025328cb8bc8ec9e4c2d8054db5573ad42bac7049940e4de6775189a66a279171d0ea41c20df87f6f46b2b715590000000000000000000000000068ecf9b4e09568e5b178d1312b1b031a0820254e147839a2acb4eeb1c9b52b6bbf13578d786b92273d5ecb84a392114f38e9bfd59fda15773f610111aa9617a3e2a634d9ae4cd988841f081a7dda7b79ceee1995ab7965e5cec32ee3197fb13c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2ae215a006d9f695994dd0ab2a0a1705350f06f29276a7c252e123212fe038de8f70e468e3df5ef423367be5d4d97c7fd837b00357d7aef21b84eb87afe8a2995194708229bfea15707bb0415d021d29102e89dab1c84519ec8cff052c37af0e4681daf99be39e8874d41ff46b9b7e662504c8ebdfe5e2b78f227c5cb82481e02243ac641a0325daf2cc15978a90932ac51e3d3af1f41d97d10e4a8fa1fd8cda5022d255bc44af3203d255822450a759c92d62aee7f425dfd4811bfa043eab15f960a170b0e5c91f8e64ad95c788b8d4f7735b2409836ed7d0c5404ec8cb0cbacfe17029aa18136a9fd5a25d6d441ec4bdddf6898aa4bfaaaf27657ab725823a78e34021cb225abd557178bd33dd2387c9bd1492e04fd54d67bfd598557b5ba6584344303104c1bd1d45b84ffca94c29db67c85a004a25252b63dcae0a25c7d78fc2e1296020a8dcf36550a86e41df1dd8242f75213636033201eedcc8d8da07ba122d09917020ca03ce5c3dcefeabfde7d23354fc0bef148601b5f9045fbb436fd02f11c317c021ca8d0e6a6dc79733275ec0a96cf567357bc6ae4508732b85d2a384e4a1012125c70d27b87617b265a5319414d6787941c4a4d7dc7047271605746f2cee2a6a160014abb3754d209d4b023a728c4063c685b1d244adfc5a4f07737e2771b2bdb6c85ccc98f476c2c4b2859c4fe0547c19c1fbdfbb750e0f4d7c0f853ba72cac4324c59edb227c10bf96d4c1dd5cfb0be24b3416b9b3f427a5ce115c67b10a63e3c0afa884aea52f0a71a228e02030246f59f74a69272d12ea1365b3409643ca28a9f8db99d9c46cb704515cccc69ed4bb508de1b4f0743a0cbe57f8a6f0b54aa4f8ae045d4d764e21e2f13a51ecf79c9571865bef8f8c12a9e2119126b91ac3dd6e106630c2bff8ba8b8d758755de174332880537bcbad8bccc238fd869ca20338f5d5fa012fcdadf8dfbcd88a2ef4f5888cfd73c82a97a10c7ea033793b2b6be67338c74f5a9b0f6e9e4db2ea7a4fb650b6ca6035536c02e9190d85f205ea8430d3d2fc6b48361c148717dc3037218220684c60e8d1405f221f7533934bee0e122a066e4540ead8a34a953131ea08e9d207e2b98956098da7f8b0115e872da7e0f6e0c1df549fa18a78b11045b4b1e59774c71b67e9aebe082180c8019fa443d80074f3b8ba1cf2a78db506cfe2b9c9a14313d236d1000c999789c38ea07f1430dca9909e220b9fc9efc07240b756e406077a789642e77b2c1fc3c2a533e04434a75d4ea3a37556268d5fcde72df387739b0f05ee42443e463480ed3763e1d5097bbbab7b6e18bc88a9296875eeb4daa7b0b3a16c96eed3d35663997e15b970691543c9551b7fcfc3d9903c07e0ea51290d6be138b48b92543e4b4f89fcf128e167b152b1e7ad39bb2abdac3c1d1cb230c6cdff4fe66e952f24a383fc2a662efc279753aba545e4a4879dcc6fbbda2f794240fefd0b1baff8b1fee6728b55847d19b4ddb62ce5acd6fd2c6ede2002ab54028f328ed184497af1448d5e3a09c4f8e371f3eb98a3ca533b7cb33607b9d0b033aca1f6250a82e9285e9c3c501daa4b1a2127724ec53807f60464af88643dffbab50bf3c398086ccc19ca73318953cbc12611b32b3efcac13952f7c563d52ea6d7effcbe336a748bdd49779018b5b0be8f214997a7fa4e39d65e1317a8be75509cbdbbd62ec5d7afda0047eac4fc8cfa7236b01a35fee9c04778460569087b337ea19aa49cc7a01076f3d6f1ccbf74b731fc82c916220bc2526357a0004dc0534ab0b88208d53f199cfb17681f32ff180e9779b5c364cf68e8244d7403e64091ec2680924ad90cf23a131dead43ddd7383db038641f660e36a59811f5d5b4c1d25c7b16194f7ac1ca0eecf4ff4631bc9f5c4c889148f29330a2dfd0bbeff3b9da88d6814994254e7a1eebdbe2bffe4a40f9a7584a9c856a3b9982aab5de1afc20371a907526b629fc526af52fea9b17171cab295e9ac19d3f3741a9cf8837a7d8d695acdf746548eb508dfe4a21a9da805790ab557804b25e18db3b2b80ec9cb7013bacea707c5aa7a6500cc8620071aee800e0fca754d3cdc7a69e1992f3b228e491fc898a122aaf4f80eb7842248cd8c9c71d4e82c758bf7a2a61a718d8391f0243f09555200200456272d13bf10b7857dbeaf124d703975914daa66ace52c16c5590db45fcbb7d80dd3b743ee7fa329d071a99b6436d4b5f2c3eb4e776afe0e2c34978248be67249c1d0e481ebeb649a3a522f7eb2d43aa55ba696a4d19b84741828c8eeed03a9aab98de0a32f820e61097f228d9b0a37b20001adc6e57dfcf259215b10442b4ed0fe061be631e1ff6a632372e7863cc0150b335d9b5b5383a062aa6dd1af0586c2be4da4bcc5f8d89b6a1c3848b14870e0b01a90c572b907", "6352acacac6563ac65", 1, 1985332090, "42da1ecedb570d11e3a3631d197ed6ed72395345c75a8e0df4ff5d98826e39dd"], - ["c6424d5402fa820442851b9cb718852cf4d6b01f406448bbae5bb7631080e412484996cfa80300000001006a01b4dc4b83e09339712339e90c87340f4bc8070465aacfc88d19cfbbadfb7212a3640b01000000036aab654156692503ca49f20200000000026a630aac1e050000000009ab00abac636353006a8123a9050000000009515165acabab6a6a659ac8665f010000000000000000def3200000000000ac74b6e2d713345b5dba1357cedad10ef147dfc73a1c030978811b2a87f86786cf476b156c038df54aa0db175394168076016c29c09fb353e2667ccb19c690ecee5768bf6e99b93ec3fc321e126fde110ee3c9d1c70010cfeb7627b46b7954ed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007323b93bad9047160b72ea8914dbe247dce5cd42c161dc03810494306bcdaf6d10e630c390e3750e1c345b2a9f86655d9550f62a194c41c3c64b688abb27b6abd5cc83e31b6e055b2f1e74dfc618b45c25f5c9aab7045572e6cc70d90ca5b1e3408056caf908c0fb1a026c65c5931a10496b6299eddf6db7b72fd05a5edb62480212394ba83ea4550e60fdd51835bf9466941cfa8a8c651274a900481458e98039020e13dd32cb0e8347f098c224d1b50d4bd70bfa8c8d9b2b04d7d5302fde60958a0b1227d7fd5627782ac65eb0217b06d065bc57696e6eb7aade0e60b43836a1753a066891fbc085e171d0e8dc19e89de53ef7d6a6509ab88bee70c69cd17a4611f0030d62dc9ff6dd77628281aa3dbdbb1de939addb1784761ded282a72ed5cb848ad0300b970da264be954f3d8b7917acacbb06c65d72af7633ecd48d99c26d091d95f022172f7037f3c1770fe284906bba72d600c7685f79201c33310dc6c26d49ea5f202245e85cd6adc8e3cd169d31729ea1a7c71a66ccb9ac391155d7260f951b4866003292b3e986dd4691d6a8ff78b3ea436734d7840c0175a03f2aa4547db76ab37f102acf9639161a8c54401e34dbe9227ca68f92071c743c806eb69436a7523b7b62c1b1e8a0c51fed144b0813c1756226a91bacf397fc3b76ca0354cdb3892033023cc37b0a47d995f88284013def2486498f158330c39a0a6e172617982a2c50fbda7b749eddf9859a73af255b3c1d16f4de1a16e566ee2e7231441104f5a0dbadb422cf7bd0a556ceaa5ebc0954f72796b212c0a2cbacfb6bddb0c45ad081c9937db3c8f759609a563f3eda122b0849a89ce5927bb907d553a36814a4a81c81eb78c0fc65332e1b175ddcd642db8aff3eb247e4397320fed15ecd4600b37a07e95b6ef062f83780c68b5612a31beb39924cef8cd3e0c0c63590158060b20bc731f1652963b4046059c0d54f66ccf271706661e302a8d01559c0fa824e4b3075093ae57141c502d106d49ea5dc62a6096f77cc35e220d3dff9a4e1811cbdf638af3da35df83669455709064a5b392e22c15ce117c58a7ad6e00bc959407e5b09e01936df052f362be20e07292418e4bcd39ac54fbce9f611f17d5a7a9057381788dfc201dcbb93d3bbeb48440b6c11bd7e1bee3675c7b3f88f8e2f3ad9c547beceafa9bc3f0b2354a4a946e956e06a0ef530a5b6e0c1a37ee757763547d47abfcb05201fd0403793e7ca3966497c6ef2fc64f3cea0f46a1aaf59cfe8f626fa314adf5960cf9f9b6f1a77ccb6a8a12b22bd70d56be7ed74e36a5371cdf6c8e1f844a365c5ba9f966f557e16eeb8316b6ddd571d5eb6ff83e60db3f190e760aae835c1e2ae595a707de222b70c9972f8a8b89a468fc15a2bd7baeadab2dcefce2e457b9ff9e948dead779f73a003c70f61f8f5cefce8590de726ea3daf414d851a51d91d90d40200e0b7e28d4f39a113282f3dea0e5c77f22f2d0b1943bdc6cdcc262603f6d5941901badf5f5f677d69bec3db9e619aab9a5ea96112229086b09aafc5395e4092e0c259e1832d231c6cf6cbe544bfef536b098facedfe2ba0ff8e1493204eedaba929de0b7454af2cc228d40469384b956873631d42f4c4e4e34ef763e5c05cdfe176fcb9bd9a3bdce48d2dbe3420552a2237bd005fde30624a65c7efa3ad79e101748ab0e12aef1ec3f3475285846102346ddee256411cf3c598d165e0082c82dea183dbddb63a9f1def13f29e21eb614c535fb05b02ccb15a1b088ac2540f4b50675dd3afd828474ef51bfdb4d5d6444574907ac65ca8d0de26cbba54d12c6c6e6d42b6b79772e9cd9442c2b80a5920ef3b8f0765c64a356d9b67af75f9fab5736f75b21570387de908f48b8a50e86831f823120307598a72c646cc1656c6bad481e3b871aae19038d9d77cc589cd6feb822485068e68957511887fef4a3000012c06f938163c7883e430fcffec3d2bc90b251153f62cc66732cc6e26ab57f223349530f818105e7cc7417db01e858be0768a50c99caa50778e333c36cd0efc2994533bff6554905355b38a89c960f569b6c5de66b1040de0121e17044f1f44978eb1fbad22edb2722569ab0ae6f71ed29293084d4758b9b4cb0faf7362faecc8e07cfcb767ef6cad448cdb694a20c815a22cbad41a8f5772de9e7cb0e228ae1902e539f32589c660e83d1849de8c4109b6045323038334f4ea9fc012dbc39eec324254bd2045e41c7d30ff310ae52878ed9110c0bd9d0a846572572d9b3c4568901137303e4fae6ba4db2890eb88e6fa3e460115d564174e2ba35b059da43b97b718e013410ca7d5ec5b0cc8c2fecf84b7dd55b1435381991156fc729906fc10302d853079be9835aff1d9ac72893d6c6b9fd12f5b8fd3ef3b615b13abde4bab127da829190243eaae7cf03", "5265", 1, -2013807467, "ea37f526b1296e31f83bb93bddfd8ddcd0da6d32b7e7404a103f722b00df88ee"], - ["a461d6fa03532ccedd77480e4a5676cb33b44156aad4257d6eea83a11e9ef2c2eaa7b317d7000000000551ab6552acd150a7faf60a083dae3b6b4a12df830e2a5273743f22a7d3e71639b9f1a81748ebf73bf902000000020052a70c7c5f4a7c56aba56d3babced3e31d950a670a3b098377475cf3f611341820f96c71150100000002515171c5f35704770eb7030000000009525153636351ab6a6a69762e030000000009516aab6a005251656aca016e0200000000056a6a0051512df915010000000003ac510000000000", "65516a00525163", 2, -1277086031, "3334e51e0ffc08170e348f3a92d327b1d53a16667f387c374c0454d54c1c66ff"], - ["750ebe96025479f3183c8f37cf3eeff39ca26e82622b7692fce90db6b921458915e76ca94902000000095252000065535253abffffffff0f312b40b5c2ed63640e8820ba8059c87e2db66a7037bd183e11ccc114318763010000000463ab5353a522a09003f1c05a020000000000ee5eb0050000000008005363005153536a29d6de020000000009ab516a63ab5252515100000000", "516a536a6563", 0, 1687881631, "8e1576c098e32b30f0f093023c4a1eb08642a0f96d3c6129ca6e41a65a0855e7"], - ["83d9db93029058c3b3575835c286861021bdfa188813bbbce11c4a446fdd8a25f3a1ef605c020000000600636aab6a634f15624dbcdf4f3021dd065b6b78ac493de0d3da50c0d7ea47d0512acd3ddf183ce4de300100000000ea9c05bb037cf759020000000000920d8704000000000463636a636ce68f0400000000085351510053ac005200000000", "53", 1, -1600632552, "eabe5b2d77912c095e58ec68c93a2b3a042188fbfc894cffd713e817580745f9"], - ["d2a5c86c0318cb8d489722d94cec7962c0ea611034094a59c99a60eba79f83914377d3a0470000000007ab6552ab5352abffffffffefad732ee75c2f8eb77fabab3c0f96dbc35554dcee43869897baee0f1355fc1202000000008604a48f70434b7a0d95af4671822f0ef8f703e9f7d52c60591ad9ea9e0877f332fcc790020000000551526a526abf6baf0d046f694c0300000000026a52ccfb1b010000000000e6f51c0100000000086500abab5352acace66128030000000008abac51536363526a1139d1a202d6592e05000000000000000000000000268b72ff830834d97f76c0fe96af7d1958377d74c856c5d80114b3696c498da6d4c076581f8bf4c5252befa64406611eea2f04459e94666e3ff7b1c5d7123446d3fee985123e0e2cf2db4c006bb1d879c8b7c4e3d3267feb682d9593778788b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e21dc571b39258c67827fa2d30ff1891f73bc0b069e590fae06285c27fe3dd7c0d41de3daad4b4e2b0de95d8016b367eb2c0d6205dfdeb86e0bfc73b3fc63859a65f403802168eec53212c7fe15a061565abd4cc866d2128163bc161bec8fa098fecc809a3f8fe2ef57623af3461a86110789a56bcf4d08d8495c126308fbda7031bc86e5e8b7f1dd8f3bc87486e7d0225a07e5040156ccf06d9f01a8e3f36bafa031576abb4ca27252b8fb81adc417a55677af12b0062ce24218b98a21fd68ab8ab0b00dc06a64c76b0fd4cbc7af2e725e725a3441be8ee139eaa90b1d153adb182b50cf717d459b4be4f7ae1caa187cf8f8f7f6ca08f430b6e4fa5f1714b304f6633032a41d99d0bc3ebe0d3b22a3dc65d980b9331e049b62a27dcf63437aad557d6de032622adbdfee7e4991265d68ba634f407fdd835f263b98301e2d7bd12cdb739ba031eebfa7eace374df03a0b8f36aaecaa550ce7923c045acca0bfb6333917956b8031be0c6bab9a43b7c8dccdc1439d9b7308df4b8d69963360e1ba9a7db3a454630021214c2cd4beb774ed345a6a2358a09df6f6ef1f14800eabb939bd5807411b238024c861222944e0c02b46b55b02d95e31c48c19e1356bc6ac5fd5da986f4c828c9eb7026b1cb34d36734c6c14b49f4870ee3ab8fca04efb6400211c3e67e80d2bc5fcc623a75275036669dd84e22c5ab89122e16350eebeef0592b5e6f11ee07e9288a0069d0410deac1b6a9453e18ba4a30e2b1408025e24441319acf9e94f859ec29e416ad4f8f2d805c17c7cea78bc1b4dfe9d719acdfc9231a658e0da25cb5dd9c25d2e226fa92c40cf4d5edb2d66879420d3881fd3659fa3291a5766ab9804daa6ccee27bce29fe7477b3d0a272df473e0f6c7bd68571f14fe0780b1d8621d2ff675831f959ee4ddfd705ed584e1e6ba7833a47f9f23dbf0847acb919375cc5f290ceca05fd499c13548dd6ae973c4c00b68f0da5097e058445f08511f4e32c943d0880c5af98270258efab00889c9a0f29e73df80ce404277c4fd3c9069ef6c136cd65f1faa477b41df5d0165cde39c90d5188688d91de49543ab4134e3570f9ffcd16f1ab63186520e5d6a2cdc9a7cd1c18b5cefdc47d5ee8c9aaeeae8d7a406da1c17e16b0409035b0f099a7ceb651711ef8491373ce2c22cc2b180ba6332dda0603699477621af7bc761710f24f7fb7394dc52298c7847b9be2771f1ae6e49741ac0599b90a9a3c128fad4ff1f7059d553ec7b46e566bfddd6736fd9fd7078425f20fc6fbe7e27138cc6193d2eb82c3290ee8a9380ac54c30bd9b262e328f354337de85170889a1f7e8404d168f9328182a2aa127d1e36a00d853d8a8fa955a8f34e44dabcd701d04870f8bfaf3763af52a950763a63486457f6ca9bcef1995945702181e64a2cadf601f3f1648abf94eeab3eff752b506f81a13e868da1b97b979380ad1f09a25299b09af64e2e0b227fd44c5ff0b75a4717e910746b486702ec616412316004e0112e85b76dca8b4e875019286ee930cb51ae4694e3821acd81c61d56c2f02542057478b9204b53aac1bee0db81ddb0b620f8e1fe5a1869805a7443af4ea38804edc3674f2dbf687c28f265f99b9930723354417af21374b3c275115c8fee6b3e43a8541ad78a70386376a94c657e37e9c230146ed2bf204b7dfe53b794fcb397e06f0c221f6d42930511e9e4246e97f2c7a0e8e36c3cf8cc11771f58db257b7af66879065acaf8683b60f739c0c4151f48c1a608ba9f95d58df1d678dfa9e3f857ec09fbd7c23c6ecf809a70b2ed8398fa1df1ecbec4e167d1ba9e48f677a09f27a532649f47fb75ff2859a6b78b87730905770d8ae8af219180b7bd7c282d38a01958568f9e20884c2900560a01d0940214693b523b5899c04a8f9bf6ee693f69535fa08aa894440f085c0adfe11686284735050336af60da82324f3cc52805cefc72fd084c69c284344951ff6542f7eced4561b919fa780acdf11f621567ce5cd7d9bb0dd710a06cf044ea0986fea3fd14f6764bbcd38eb2c6ce20ba3333b4bd9c9fe60d41e567a13eb4476be3555df39527ce7deb78cb818982aae14e7e500e15bd972034961621ec0c6550d47c83dd1d0b62c4726ea1b38f1a54ac5677bb9ba3311656edf5a6f442a7c539aac6cdc59c029e109de58f39e8095b66782156763057f63cff17a6bf3d3837aa513e1375939d6b6659e8a0ef562aa6e47564c8fbfc68a1705422d5f778dfbdb7ffb81c5282de62239bbe82513273b1ea1595c03c68e45725bf52d6801000000000000000000000000ea42b8a70d852a41a8761bbacfc1a74d723206d902640c7e6735ff3913293905aedd89bb6822b79a7f5e1d7bcad9839579091e4f1fa2b6c1ad4ffeb172db94ec292faf6ad3bf041314e15082df994046ff664ff2a145fffcdcb05ac098c422d500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c62fcf62079ce0b3f2f198411f6af1c84eb1d04f686b66e769386e7d7f58c0115081b5233944e9e90a0f7fc9fc491e44ff123a80632ff95077dc6c81a466b6300459993e494d83db5f7ef44a76eaae5c8d714193289af816e377d749245be5101b007ac38894494f8dcea0502787ed0932c76bf933c96c70c4504254c8e689bf0201d6acc787c9366da0bc7d72c73314bcc7eb526367cfe0718ad0db5c7747bf19032d4d4b2dfcc89a33c231f550a64cba645f160ab523e26f5052f4b81ab45797090b04ace123ddf58aba6fbbb0ba24a938b00e006e390c0e9407a4fa62fe4b8fd3d62c510811fa074bba5d5d5c13ef3cf1d087278d28ef04eb58493d00caec5f5369021f8b492e740fd53e7cf22cab72ceca2f3d20ca0e538f26fe955896663f3f9d9002301a01a29585f3eacdc02510246a50e4c5f6bfbd567ed8311796f821fb5a1f0503216004955e3c8202ffa24028ea17326b8702b59c8221a327998d3faa283c8c39020deb9b87748b0dbb19cfd281d921a7a19a7eef768865578557d89d209edb761b0224571714bdba146bfd016af1b78985127b532f26ea234032d4a8b68bc4f76d5dffb5dffa152f99845a4e76784758861cd61a9f94c76792f39fdd45ab359664a33cce0e24bfceb26193de8580c10fecdce66cb7562c66a5fb8ca5ec71963199e1cc4b8ae8cc50b10ffeffb67813f85f39486ec4863401d8415feae95012e02cdce5503ca24d2791eaf81e7ed72df8669c82776fb13e97cd0eeb3f3126cdbb1cbed3926d32660d2c8b41eb9d9f132ab30b3b9d1fbb9e08bb2962e9623c7d27b4eab11b60f2d4f6c6da4b89dbde6fe02ce758ad6f2e4dc2fdd17152548a948fdea57329a26f91857710d796cd647f767b367b7f55937a91a88989203b20ce493cc4da665c5149240161c1e6038e463478cf286890b727a0a8d85d62d5725225d7b064dbc1a4c84e10b74409402b19e3c7c2054ccbba294bfff4a2640ac16ca2a4a813f3feb4d1d535b0de12003a984435a024acba5071e22e4758fea855400e7872fbd438579b9d29471efc0cba22a8680fc1bdc8746f4e1b5fcd278c64c938861ecfab64433ded85f99dd54028ea79c53b8e960d4827f69d80924b550af17f4996a819d7eeda3eca414fcb89142916eae38899f3c299d34956a2d234229b7867ae67c4614ea3e4bb99c319ca762d984d86f28ce8d9b5fd1c26a437c842baef5fe2ba682154db963bc3c24d0533811d5179c1b2f1105e111cf98d1578eb3ad90056a7dcf958c1b0ed7b3482fc305eb958abb797c54e52c00881fe8526c3eeeb06e2e54fb586535733de1be7db1694f8e5fae5105935b3645b079cc081aedf25a41b714ad249da5788e9b4021cf080f3eef9af9af324d65a253867fed418eb205c2e231ffa50109a0be9e361c054d25597786b47317c740fc57a5014b42505493ca998faa2f932f9632d21ed270dea44c636a64c604d058fc811edb0076d1ebdf75a18ca15e6063ae1d0b8a2c1cda6c29722b929b4f63b730141893654d0b5611ed11b386516900c1041868b9a5386156211a5858a40272c0726d76310ec507daffadf6c5c05a06dbdbdbfa46f87609302e5f5b709888014aceb1f8d279e33f89476eefc2fdf9f715b680de4859f8846b917c2fe290a0c1219648a2034d934f307a9043b4195a5d0918b7a154cb555a031a15bcc3a799290342cf3145f61b87cc407fbdf5269dc424dd4cd037e4d1b70d1dd0038500e385996afa9dbb059ae55f9c8622c9023cd1f445346ea61742b65bf71bc62e29317181a9b4e38690f8929c32e3e39b5b2c030e43cf9501c1fd7bcbd3681b8f8f7c86de5ebe549dbbaa098f620e3843ed428309d2f07e6025d60c0b38b5fd5f6675203e4ae10bbe8a42549ab14f136f9a3f20a04c607d72cceb554398e23c85535230ae9e87aabbb6c6dc929132f22a82beaa6524526c9db052fac38fd0318d8bbd9e591e78930ff070ec32ea081b142131c2bd144f3f8f24fa2799c7753944b9f8ee950a4308972f13ef0fef9182f455ad0993904064941a43f3c53ad45fb9c1c9b68bd81f3e96bcc6bf1177c6a0249da1ba979919612e9511760a6dbbdcbb488c024c81bce5fa8a8a7985bc198c4841f7d0a3cbdef848d903dbdf909e805b0816ba2a72c1ad75411cd58b927fdebd0648bcc451070435c0dc06c68a1395fa8ef6e2c022dea6c66f3d82b1977b5fcaf724c3864715023347343869ced02ca96df3e78a4a82de8bbf545a0f04cfb28a252178cfb4053503b2a79eef2b6ab235f8492379758ecbc0a3c90c90742d59e017e483d61c05811c98494bd830562c73e8dca55e0fb70a4d90ef99e74cf8f45cc4e79acd648f883bb5e70e6a3325538e75f04190cba15a8dbb45925855129b1a3b9e56d127f133a3604da8d7a4a3604", "53", 0, 1749204536, "bc4a201b4f0b7c643c61fb80adf0f54f4887c70751097b305eac5d2218fa5fa3"], - ["785a8333019dc51a6fce400cabb92ed5a02e98749fef8f8e55c0ed73b675923043b3489c91010000000800ac525353ac52ac8f4835e5046cd4b90200000000040063ac0067c8670400000000066a52acac535371019a050000000001abccdf5b040000000008acab6a656a5352009e66c9c900", "655352ac", 0, 1391260418, "afd80705814b26dc1cc896282c759cf3be490c585efc04ee0e079ec8b4ad720b"], - ["6c71e512046ec85212ac8c1871af8e5a02365cc3a43d5caea726b3de8ecd64e081d0b91da600000000086a0065510065ac53ffffffff72afbb57e6ca32c04d22f6b58339589fd10c837688c5efc26bf9768a2fc06271000000000251638b33abe4778445651032e7a7f3cd745c86c8f53e156b549d8eda290a76e17a4397a1c5fc0200000003516a65ffffffff39803b5e9ed34df487eeca63a6a9abc0cde5a288b96d8a5a382a8117a17741d102000000090000656352ab5300532103dc33017fdd07020000000006536a5351ac00bcad61330100000000000000009e7aae01000000001e315e86b332cd50716d81029e4c48a2c932ecb2d8b5a26584302d2e8ab4496bb3a2ab26960e5e09911d99c4ce5dac5075156a629ae637f1dd02f3b8407fee8247304753200d0ce3ef47ef143dd0e18ca3198a7c4116bc20872d13105c4075d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a9fa4990aeae69e92f52a206c32e80f9ba9568ddf45bdeccf3d8183df5f1d38a6a5ed824932ec42b18a23869f79fae137f69232061f89eef510f0b2b8765c8cecf69360954893349d1f8f0604cc810fbe309161fece7c34d498774b70d536b55797726a314709786c3da4a09b3a87da69a96404eb1d2e91296eaa58b7c473e80328deb064afdb201c43d69b3f6564e2640e5830ecfa8c8188ab705624e65f44460323762a4ec3edc6244c9898e5eb053c635cf7c5ba72d3006c69e3d95b952ed9380a2fd9345be1653a50d52c523e999a87e93f8ba613821ce299ba566c2024de198b23467a661dc72e4c4b3c5176a1fa01e532f3aa67322d69c95042b0fd5180befc032876633f96e6e94d2a53d1a3e4e3aaf2d48c85ab844742e7117b0f2cb14463b4032f86dc9250e19a747ecda56a8bee0750dccf751540b51cef1906bd7daad496de020ea9ba9c02fdcbbaf15b0498805f469cc5bd2ce6e8add6b068f77c5c85b4238b021575acf1fed83b6973cdcac419e0392cf84d92f0cb8ebc76ce10ff97cc1101f902294e901ae30fe0cece85ac0ebebebd798cdafdecf781772af35f1bfa1c1b3c48edc2e2c414b849be6fbbcc35a04f428a293c94bc428e5e8a325fdbc477efc8e95e747cc574e3240f34bfa71233ffe72472cb2106d691f842bc31e8761704558b2d5068129df322274888dba1cbaa7d0eff0e20b34f2bbc1f925c3090d1b74296dc77d3a0997dba873eca43ee4aadd679cf21811545a4f3d64b704f3b1e33c9f02de692b5010f5f8720950d01d46f1ecf843a976d8d303a2c5f5fcacb33176681fe58d30d53a793ed33fc278c1778a91a68b66fc9e4fb4ddd84bcceca3e26ae66bae599bb5e43fbf6595a3f8fb3cb9c90c700de0d29b6cffc885fbedee256fa2548793429aac944aa1e20e6503231733d8de265461546a23cf8a20bc8967ed83c7a5497af34087baeccf5bad4767a3f999e94553f6c8651b9888e49ab39995bfdbeb2d08743176f732c6342bd567c10506affa9c4c1518582c696711e52c60cf2c7a6eabfbd3688017ba462953f44a7face6ce05f871982536f786f7eb74509953198cbdd7efdfe571134d80b3f378afe6dfc393f0c29acb7f1cdc0e790b5ca40c9c4c04b42058adca6ac898b09924e17b19306b35216b032441d5824fc8d57f88639ceb6b5be3d117c92a4d9ed54372eb077dd42db87436ab540f005f7a65b15c6462ccc8e936551f559d4fb8ca780d67241dc395b34ac53933c114e78358ce37b191b4bc2b20c7a9c2a7387c447d9104e857c75607301b190ae212ad51d0261c9bb1a5bd50479c75ad6cea5b84102289fbc3cdffd89109d0133e907b14cc5a2c19e6620eb56e648103d671e5b000bf93cee41c1685eeb3dc342fef53de8a6e51586244950172824757f91d596c97e31286fda509154d56f9b05b18e817e957569c1b577ac678540f68189c4eaed80fb5ef288712eb12fada91e72eb9827f41ea5051acb5220740c7fcf78765213a541929f8473b6eec097259f2fe262d5bbf3123cb1685b4114185f6faa1ca9370b1ba8a9b0cf3148052c37d2f87d1014b49c4032e42694aac21488d2d15ad8fb545dde50db5c3d058c01f054cbd0934b4f033a196411ac309102f39df7e1026e7664998718e31f4222c890e2ef9549c9512af4b573eacae1c100bf8a8ddd20d7734e0c07ca35da3198bf7b6d496f885de7e5a5240dc399e4875da8798253eb5410496a77d490958c9b36ff690c528632b81c194c40db6493aadb6ecf26c7b352c446bade5cbe6f09ec103c59b0c30036c1cba285518064ae668f244dac240ac01e70bef70677a8bc06f63e0afe9c577986335452caa24101743aab6d71586b7d26c272fdfc0c82b9df5c120b3f590ca94f257a03615df480c98f90b9af1efbd63a0e99169cf884b4ea4cef9492e4db8026ab3d7de160926fe2d1410f7ada2436a37c83aefdc4ee9e60d5a40f1711e2fe62aacca0acbabd1a7d2901cc22c9dfe97df7d223a84b0c85df1c0919619aaacd159fe53002436a8fe2157145f3bc9f51bb66986cbb95280b2d017fd092484da4cf3aca47dcc0a16f532b2666d8e272e9cd97712cce063948249d59f76a48dcfffebd7e0767fb8524361d49b288a1c51641034a8747b1fce87bf5283ca0416c6f98ef3099e3b0c2db0aa2a8edbc1b93381cec8bdbc88a1558bc6847222dd18c6f0bb6af62a4b90b9ea96f0897d1afc47ae4e2a0fffc37995abeb442a55c113d291fa8eb370d9a5f46679ac2e223df79096b6256840b0764d56f8dcbbe7e91347b7abe1f5d4fc072971c63fec0197776776d859e3412359188a11c1f6c6324710f574a79a937914d1e71daf3f19ff5bdf2373d2482b1790260cdd45cce50afe069491e9dc527c82fda529430dcdc04722064068204", "51636300", 2, 1321403412, "f5bffa690843838e128b8f5ba611fa1a3391a5ff2c966b5275710eec092da6cc"], - ["665e13680298312a0555feeefc3372316536da4b6238d28ed12963551fbb06ecba622cbed8020000000040e1e6b9c9fccea6e7bcdaa9aa97526d00324744a0c427a591b69dd4f1fad31df901c0b60000000000a7fe0e1a018a73a103000000000251538fb522a5028f389305000000000000000000000000cd804e7d69634a5afb456ae15179a229355cea576505290b4aca8ce93f829409d6f59d080261d236e238e8214efa8da10e8ac4376f80a4964080d905fa1b83e55ca03540752e5a44f133e7ea14defee523afa89f974b7322acc61c93016ec96600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c53a759d9ba2632e55853f1499ab228d1bd669429c7eb403b14a834a89c2b470e4a52cb4b128a315a7a1cf580d0470b7cc36b557838202f5f3ae87c04251be1502c389036f5e9e51cf4a3d87c08a76ace209f021f88cea6f07466164d9e65295f2c41b7e544fc8f76570c69487e0eeec12573617b31eefdea4dfda6af61a18ff022a81a53cf2670d74efb2902e2b7f1e807486f7024c2c37321955ba3a9674392c031a375fe3499df25f5b20af4fdc1a004ddc8ed9bf5a7b089a1328e81d194492070b1461f4ee87a2fc18df2a617289a59f56bf01b3663adfebb66e4ecd9fa2c847f32d99e7f768e295df9cdee9611e0f393cbe7289d4b8e12c12cda9d3cc40e79ff10320bf2d4b8d334f195aebd62dbaffc0df4d36c0617f6764088a5d56e7b5fcd18b02124637b8cbeb18b23a196780a5ec2e188f845ce7834b0ca7a81b6730e9a3f8cd03053a31e0f45e967264ab4b0635d1b7c94c2b03911dd6714f0ac7a2494355c947021d2817905c1b013401a8edc40942330eea344c58d3396a6e94abe6ea046bfc2a03116d9d56d8b980652c88bf9731f761b54428901d27dc4247ca033fcf2219470bd8cd3b596f6e7e8ea46af077836cf90deabefedc12c8b9323278091760e46d04f86aa54fe77c55864cc7857b473a8861fdf4bcd99e31a5446c511a6d5a47c1a455f6de2223b0e35caab824fa45d7748c6a7c46937f5383b2d6d73a2076d25fac8940cf52265e4f93324354133d3d8de46b2b531434c92bc09d559f9a6fc512a303daa12d694ebf17b1eae49f4673ae89b8cb4725edec2a2399ebc0c602a28a484fb2c937aa7361e8fca1d788333148573a6587390a44ff34f65de6cab195315d1fa153ec6504599a1d60c8403b665cebdb9e5f71ec6eb7413ed9eed30d58ec0ce2f4ab20c591c3359a3c1f2462d7c78484481b610c3c7cffa9a8638ae00b0d4433a9b111993d1467fd96a3a1de6146fc4ac7e512c4aa61bb1ce7985df894f53be854149fe0891deb5738032f2398b5110da946a3e745933e12b5862b2fe08a3c5472a24b579802128c6a22031ab3d7c657038ffa82bec9c5c0eaf912465ebbcaa9b906f2b035133563afa2a55588cb7cb480a19a2fd73ee2d068df9f8f46c1ea10ccacf655d97a65008ab5159b03e458ec440c88895ba2c605783a2b0dc9296e94ae7c6e2d7c524a4ee37af7ee0e8c6b6f331ecf371fb346a1eec58cb96aa28cc3f644286140b43894842f2361e9c24c73edcc15717c6ebbe7df72169247266b8a4c44ce3118cfa012580d26892c23c64e6f910127be5901a508fcc8bf54aeccea32a596f6cfea5e700e381458e9dad3562dfe5056cdf0f14eeed40b5841c4ccda442a9621a260fde99b32bf4377986c0b5bed71dee6ce91d282b76c2e3476a298b5669493e25a7bc05ea922f8fbb64703d87101fa8b4a533beb6e83e865a51e351e7e29fa81957b81387962f251bad050cadae694d4ae68828dd5751d89bb00aca77af63427968cbff8a2af921cd960ccf27c0128c2a8d83aefa05e3e8db0c578c2b303a5047e5e361c33f28a085fe1a03bfc6b808f506c298a901b2e99733e4908162a068c79f27838069360984c0022eacd9f245fe3cd82110eb3156f2e4afae73b2d9f6b57a22f8ea25126e9981b18f4833c18fb1e34d894c90621715c8ac356f7d05fe541c54e191aabcced39cc5f35ef3357babbd3605c062b08dc836aa7c6bad543fa3eef4a8922c2d31ffe676fa375a5f204bf11623fb82b3c140ebe01ea1ebd2ca9f167cb14bda6fe0a8a547ed208959130bb04f7e81a1d28b505dcaad0ef181f0b64b78f5b9af2b1bda4ae17d5e1b94db680cc8461338f73c651091a32b4e5cdd36bf7c02728e7d00e53964894b97ef29309eb6e2a701bea4580c7c9a898e261de04e4db43f51d527b5dd92a98011eda8b4bffe0b6cd64c57210044d9924b82c467bcf556213b384a2573dd0a17b416ab27f201457ee709d12e6beec0386007df0afd948d8e6f7ebb8b308f4dc23f59c5198e84fb2442ec97daf7c1113226eb274dc487a11665b2b3562e262be2c65462d3f7357792d52b6a86cdd56992c63ec45c86eb293455381e5f406fef7bd4c3d6961f7acd84a9b02659ba288a408ff8ae9b0abf0d2a88102930e7f5793791f8b8e92ec562c0aa8ae7b389067a0cf2b8a58cc34c14213c617f5d27d15181a3df654bc07e68b8c81884c8f0f9f72d369b31f608bde43943e434433041c2f5724fa1c4f1af29b7f1efb15505eb77a4dd182982aa3fad145946473af9c6c3b0aaa8905000000000000000000000000b8507a9f012908f1c2896efbee3d9885a65386429e41413a3928a88f7333bd2270d8b529a0c6a9947c5f3a95c60d8c735dcc622d4bb6a11493ebd9d1fca898736f86c17937468e5678464e967b7479a39f5ced95b0b6e080f4ef6f985488e81800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8134e9382ac4c15ff1432eecba700f5473bb644a552fac62fcd8ca77584b336eb079505d148742fe5a134740f69bd229f352b096add38aca4fb83db94cf87715eb83e0f168cfe48600b2f898514e04ce9157788021d49c3b0a8f6613e5e505b35a1dd9dff53dcde1115ff1f2f5aad978eba6138a075f7d0678126e2eb79477b02007067b0bf36b49428adbcfc4ae167818d9f5b86725f73c5b4e5f28d6d3e97ff021639c5ab252e85bddef737419c4cdbc507f9be862e19aec448ac581fa1944e780b132f6327cc370ee9bf6efccb567f5e7d5312cb4be8b8d3166b2e605ad775701b1fedce0a4bdee6b04320122107408207e4af37938112d886563e184d67efb4b2030f079431cab83b5b3f7ff4076aaa873240deec73b7aff16a9b807ff5defef69f030cf29052ab9259ffddf19d1c6f63c28438cbe131b33cc53d3772de25ccf4bf2c021ec3d2c51193c1d736773d35765c255a47d233d86108f2d37ce6bb59fd7237c30206d0b5643ff5ef67e4b6523b781644b32771dca972c7df61e182a1f5230d14d4031d18eb13111bbb3e4751354623d9f565ede90cc4fa386fdf5acc42a64177551977d4e761d3b8369e4db5334847ac9c0623fcfb4a4d95e92d592ee12c2307a899727fb9c05b3199f0ad6da181e96557f0137acc7908834f9eef48cdef0040b9d43396d8dcbe3ed6e07e86a9fe6a08b924ee1e0cda10e768e5b6a84e86af0e3651ebc980dd14292465aaea13a52687987a8257ad2084bc3fba6c44fa9208c2db6e124d79a678951f49c3177ec75abe3df212b55f67aaae5ecbb11af87558c787b71c57b7703db98f1a5916a7e5484fb284f77513e6128fb686175d1c82e3e2de2e906bd68557d3ff2090cb27419ad297293740626a99e3083657399e6adc8c17e9b82ca713c63b2626db8f6f7832106170a2a72dae2ed4aa6cd1db987dad4a0dd9a7467ca3f026857095617c1e28d09a2e8618d9feda0e5feb930e64a68335efc1ee587073e37a11066230b2bc2f9b2fc7e2debe6b95e4ef3903bfa2edc9be7db16b8c59da612fed13f17633b0ebe29e36e16520e6d76678f03ec1aaff3882af456b6b3fef4901673f41c0987d8340417a793bb58ccddddee699cfecacd6ceb7d21b310ca989faaddb5e76302f8dfd961b2a557cb26c495bca15a6a1d38ae26ca29a0f552083262fff7dddc9a66e0470364ed74787f620979fab2535922262b583ee00554e14c3391fb6234693998e6a6a92a81731f44ce09edbcb9fa82f08b12281f282e69f51ab36379f693e1ef2ab5ebadec764cc6fd5f3287535a8371095861c8cf2db16b33647cb5d38730268c4aa7f9225db9d27e2432e9e2e6702e90410828ccfcc7198c9bf30af6dcdf2df37f3c01022ac79419448a7abfe6eb2b9a004f92cea0b348003545fa08d521a0d1e1a4c0512a6f123fa11e683c150de9feacac27692f9cab8a2d34146653d9b98266b331a1d1515726627fe98e19af851664fcfd1a2d05f23e7b5df9f636e1ec443fac0155b71571259a5f9a895b10af6c9c161e45ca2142c8c6f1c1792a42464c4eab015569568f04e7139af1df38938dd2c6c4066daef4141f2c7f13fc372cc94d7db8855c1995b627aca9950970163c1a283869731b616285aa9f4b1e1a88e3822add16d5e3414aef87284922ef3a15217cfea4365d2666edf25bccb5edd88ed038ba72398817dbe4c5f601ff9dbe567927b970a3f3826543602c88e60234cc7da886d7ed57a93ba20f7ceff870c5bd9858272f122bc144f5a22269b851595ac0572ad5c5eff293c7f0680858c30203578c671e1988bfd5efaf5658beeb579ea7c421826b49d1b9d23ec8c2b1ecb270ab42b7d2b981aee460d692c87bf8ac6f66e72af6523973b1c1535750ca21cc1f9dd98813c94ad53acf11a118c752e4d9946006f157087f5cb04aa778d36fc4bf8fc36382b859edaeeced7c7f12ed04bab647b6aca33bf2307a742191ea6b4d686fe02502ab92cf138ee0cb2e24e2560d3b8f8159b8d6c5a387710b4d5a4013bfba681970c5527a8032ecf0b59391a59789c7cdd146ecb04f4576a5f1096c6dd5d3ac7498b2dbdd9045c92ba2553c3c30587de7fb1a978bb0d7de62d650ef8cdc80935147844f720472356721e905e6bf29ba37569bb3d3bff6431f2bc1eb89c0b4072f066eb9759e5f4241e51247de398d09c3f3c1eb65455f01fac9eb3651b0ded2ee0aa70d3a795de3e668a448e85d72ed03b69acd622cf1dd94abc1d2d76d5404f71e58e5e59c2a23f78c19653307cb991f634391f51093adfa673fb0d1bd4da99c6273c059cee2e0472b0c6c07040c8be46b11703673591179608d4944dbc8cfc85dcfe208b3c377580e1a452828894ef52a2d76faa1d11c73a77d6901bb46662ecce4c2479caa962c7d8545daccad6ba0d", "6551ac5353", 1, 6529874, "ed8d34bed38c23551dc44b9ac45d8d06e9b638be3da34db702f3433d7c5e36c6"], - ["7c60923704f1ed3a407bf3366889aa1256015f1757c58c351b1f5047d8b97717c94a9ff222020000000965535100536553ab00ffffffffdf0abb9dd92f46363b2ff8c40eb9a42ac9cfc2526ff3246beb8212389e1137dc02000000080063ac6500ab6a5183959f3a019c18c321b6ddb231d9899e5ac7a44b8e032fdf1164a007a270f086f5f24278010000000465526a00326e5c7852f912ebcc0947e1e906955e88843a61fa14c0854d3613a7391b9f699f9ca92c0200000003abac6a2621853b01005b6705000000000953ab636500abac536a42fc2b0a0100000000000000005210aa010000000051b5dac1508d8b8ee853449477fd73d96f46faec14ac5186172b3a142a3165bd8757b6ac2deaad84e59f7a4ccc203d1dc6a917653ceeddc28c0a1f96b3e95317fc2aa5fd4c2f9ec58859c2efff063d2ee9f6f641a120052f93d27667d88c40150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026dd6110f02216ef5e1f17aa074f48ccdba5ca2b4b0b09032a45d047efe870b03cf584350aeed8e5976b344ba365763c852d4ab6d2f01b36f0e1dfb6e5077f94099957f2059b47a05a9163255439997d42339412ff408565c144fbe06566702e2b49e6e1eb784c4307309ee4fa198b37da626b97d5b7e8f8c5b5ac63e88e9f85021a7177432b214346ec7e4a91819e01cec08cc08d024d95449dcbba7995cb84aa0302eea3906ee5a78c59b6c223ba2165a56821b92e1f123149356f69240612c13f0b1c4dde516b92e7bacc7dcc8215a85106edc1106d1cc6c1171630ffc09a5a158b1f9bdaad86722d1e06d4d575146a38b070e8645644ac3aee511b3d6a89c297f30214dc538d50b9da1d04375076cb4ae2a0f1dc0eb76e2d47129401ee6faf29ce2e0322f033963b6028f36509475125f4fbe6e62118594ec0d1a1741d82cecaf6773b0211b520eb2f072aa74c6b30d7a104577d03106705ad59a64a6ec84eaa78b7a354022358e09b0dae06a80db5537ffd51006fff196fa519489ab02e9ef3e4dc74a787021be2006712054b3db7bf0ecade45ef80919c72c7f4fc045180c8fa59796a9d5ccb5163e841594f24ffd0d8ef21fadf97c420047562c982a23df0f96ee2e3d1f07a9a4c60a0300a4595a2ddc7faa7be17831d90dcf33fa2b95ea0f612288c01cfcf542ebe2007fc245ceba9b2aeedb95ceca6aacc45d0544a47bdaf2993e82eb4eb6f3cc3fc742812232cf67abf265e377050fe8fd2c03dc768fa5ecb654518316ccb6e2690ab22a0b60b96ee34ea91e214df7604ad4077cd752b7c6fe3e91d2f6c3534cbde537ee6873a199ac1179de8e792028c391c1ddbe4933fb298c6acc6a0af9d0efed11bcbbfeac8562ce63155607d33c2f10bf2dd3555e130cd22b642e8afcf19d7ccbda8a536cc77e8dd03e8fef83a8b2c4109438b6aca246a396dd449ad3af37c227182809fa047c6e08dd6f0d72958927bfecd5a2ef1ed43fcbb94ab956fb1d84187cd7fa741190499152286660173318bf19cc3b05e24328e02a92e2a85159e4afa868a26c8892111a7a2e5ee9befa29f661274292a6870f8c93b1f37e235d6d7ef5c9c8348a27f97e073c1eebc4a1389ee26127cbf60d4873bea4a8dcb3043cdece4c56e6a0bc7b54de203109ce4549cfee4d4bf6195169d46f84e4cf1d884bb257d34bd250e28474c85cd3c7eeb36fc7d26915d7633a154861b4da5adae1fdea80b00e5327123e9b1633ac31492e5fb1fc36cdb902f164bec86cf3f0790cd03ccd9e304b4091fba6cd16e2232dc9b68816deefeabeaaed19586e52c898149bd02ce4c1c84d2e54c7e64ff8e4ed68dd3742a66d7a9f0900b1e54c6aca4a62eadd62002b2ad8317030e46ed7f0d68ff8401551b8e32260368ee0b49c5c7180b057d9fe4b381136ba350859efcc09e43073781dd67b72320349522470fd74d4409754fc25f14d1525a7aed3b05d6ccb3251c92312e8eb1e5530d94f73d96de9ba0e344c936d039061e6cb86202f1c08688622b1800f03ca899a5d6f1c0c539874c8df1d6fdca7b640dff2a19e28a84e93d9ae62c94d2b11e2224243ebb143c5f7664aa218f9cbf6a662c1f5eebdfd8dbdd8bef5a989b5e0dc0464e9d174a3340d2688e9560d5b32ddaac8ffd6e5fd50c5f09c184ca30541bafbfd57f5219ca0e8964c952711b94b8b67297ed2a8e3ffe3a24a174bc5540a871b756d78608a9065b910043a69fba68f63c22465b65d2b7b897b961879e3fdca9a964400093867022757e0f00ad16e220b0452c919c24dc7b60a7913763e88892637bff95c07e848db5bfc3c4c73416771bfdc3c94e7ea663388677e3c1a9be812023da495dc2abc9633d8e2784293c62ff83166be08b016ce8cd9f1c841f971e71f3d621ef07f07eed74045f97d646f05f56079274fb19212808fa3ad0bb7b17bd439c04c46d35e49854ce31dc29e18861bc07d189f79b642f7df77c34807642d1cf0bbdc712856242e5ff486c38297a9c32b855a4dd70f3a6562ac9e2288b79c97731113f1cdd736826ead24f0c03ee0aa8d080badec29f3cc83c54df4cd0cbf62c5b7e02af8b7e443c591f4da5cceb5f6fc5babf86e1608e93731b48bcd47ead5e70a153934e28eab7bf0beb5ec5cba676ca439fd921bdf7cbabc3f09d27661621fef4dca4fc84ffbf647152114cbe1a1bb24033257a499fa2b19e22765b5c99a478f3bc2f3fc531ff488b419656036778b2d91ed3175cd935c2e56297117540ca81c1770bdcea38ec96acbcdb32ae4c61069774399a7152f3162876d9c087f8e5a91afb8fc820c5638ec71ac9dfcae4c37bd57c30f0f1dd3964fb5547e0898d056acf9db596d8d7d20a45681b9d2f93485056f7d616a562c4e52ac81d62e8f7c867da09989d58cd2819e0d5d4b34900148006", "00", 2, 278787095, "595479af589ef54cc63e14af96f50d41f051358e067f29a2c348f58e0fe3d147"], - ["c8f86daf03cb6c51f19814577be2098519dbadd8eac3b158f12f4c06e35eb6865bb2bb0a59000000000200ac99d9189a40f7e6f356762f7c30732490ca771d2e919864a07f3ae644c26fb40d0f678b46010000000064644dea2f10c8600910fd8d229986ce85dea5dab185588c45bdee74a14d137e6330b9c1020000000365ac6352249a3f02bf46c60400000000005fa87c000000000009ab65ac51acab00530000000000", "6a6553520051", 2, 595599069, "8babd12203c4bb5fc88699d916570510937b095a98a7d64372ed4584ff28f3ed"], - ["cc3ae5cd03a9267fcb743ef444bec78a182f1a4f52c12da4cf95dc4ce01e69e09c4db3c5850300000008ac53535352ab0063ffffffffef3d19cdcb900b282453b4832b46de1ec2491a88d10cbfd1e1ab5b000c7e36c703000000075163ac6a53ab65c0d49b37a8e61cc5be3dcd60f5ce0377dc0d0009904500c91d03643181f1763b92c0387501000000066363ab00ab52ffffffff0490fe28040000000008ab5363656a5353abe9fe300500000000085165536a65515200fa74680500000000026565b8e9c0040000000002526ac88966a7", "53ac65ac63510052", 1, 1559386461, "9d87903db5856020793dc1be5b0eb458e6d16ef6ec46d9c0fb83a47c87e8305c"], - ["f0a3010303b86865f43feb5c3ad5055aeef2f33c0c4c7ba363706d6be8295ec2f4e484828a010000000351636affffffff7c735f8f3c215d1d14a02ba981de30e402f1d1ddac4f046b9a9d966614f029f1030000000951abac515265006aacffffffff0f21cec56a4594a011559b9b9ac491618e7c25c15463c3c84cbf7d6c4505e21d030000000463acac52d0d5a28d02ba13e10500000000045365ac51b49b810500000000026a638952a30e010000000000000000771d6803000000006975c99722381b64be93d59f0279f3755490d03dba4fb97862736d9e48764bf1417ee6d46012449460460bd4f808740444bbd403018a730ee407455d4ca86ac02492ae39579d07f11c4b1ea43563970f45df03f152aedba32fe1562d3c7b15390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007cd44e17513299f2ecc2079a464d83816a71c62f0f5642e430f1376a9c98a3afa5296191c15d68a0a2019847d12dce35e151a0e2c0d5d7aa55e404c697c084aff089a4d373ede3454d657cb915a278b39178a74cdb537ba803243644e8377aefff2b316e84faeb0f1f956d7809a367ff19395b22c0bf72da3bae232a3d1d668030ce36625adbf69ba488f6e60753bdd00fbbc61fa1537de6443fcfd698d6a976a020ab797ff6fc059be0bfafb6bc3712f80e9a08cee7bbfc1f969ad6d2a4d4e6b400a19c8b92c150e97b3dfa5b7a1322edeca50ab66857b4825ebaeea870f17bf72fa25eea50cdc6dd9f100b9be47f8e979999d958f096d14867bc991090013efa9a802049cae8083c1872634b7337eb89ddaf337d4ad6a4bb2ac02c95a0bda7f73ebfc032310463e0116b6fad19b6de10768dda2ba84c43a03041d6039832065bdcbffc703043eb908d95925eae74dfa5a2d69bcbb90c1fc34a553ee82e87372c94f5a9328032b2b5ba8d60dee77508b23ebba980c4869f703bef1309fde4f52f8f3dcdb450303124aacc30c15a87397f1ee3acca7c98c014913ceb7ad4d6f9da165d1a9e7e7963d0c43e6909600640490e871e9b0f4234a713278836139234752f93021aaf6441062301014f2979c4bf6aead6baa37cd462f7322ed6e333b6ebe93e74eece28276421be508c6d5007c490b575db18107c8ac49cda3d985d8ede323ce74bd0e2fd9d7e5eb1300059b6c752123ce3c809bef3ea089c9bca82c8e926944797ad7db3ad83b62c5028dbbb443d3e524286ba686383124b7851e717599eb17020c432d54c2b8dc7095edde114c6408495f342e9590132e8e2880e35eb10e575fb8624678a49b2b12b291efa38472683e2e551d8c06d0602ee573269792cfbc59d0a08553286fe870bcc1f51ee1697f451a7b7436f92da5f5d4e07649013da86ec0ff779a0e1d11dac7f72dfd7b3d1f33a89408447b98b79dd3ed678c9d8496ced7ceffb505230b605ed92978c16ad57b03d9be5361ea106792c3d6826f6d8e8b36e69ab191207a3eed2a6e2de3a5413d54e721569e0a394b51b9e0abc7b84fa66544cb7e67615bf92ecbca6ca50fc2789ad1f7878ffeca0d85f924e6073baa6f9c7ddb8f96f2a30e937d04c864a8fad3192e439f3d9edce4e9802e9ea0020867274ea576194a1d8efc29ba7b0856e0f30da12b0fbdb6ae412e72a115a8791a46da48504644978c5ecaf51d604291d45612ef705819c66e0b3fd11ce659f42aa636817565550637fcccf78ebf82d85cba17a63be2e8be7929ca25021f3e97a7af7ff613a407e45b885f96fb5d95808e179546a7ae264029516f3bc717b4d6d4358a5f5192e104b6812d880526432193644e2d9c9e40b6f371b9505b96e70a062d486714aaadb29d2abb10e4c37450abdf438ca95d188612ef7503061e906e166d4bc7f366eb791b8fe2aa9f5ecb04642a258c618cdb803ef8fbf4f89f85c886f10c2a153d09f70c3349efb604a75dd7a73fc3e5449a8089718122e972a858cd8c69e141fb29391695a06b5379ea21a05c7de8608d04ac8b1247de934eded9d4502cdba145f4306fc5501df25bae612d2b2ca1ed203437cfedeeee96f6a5fb6b724b9585b4361dc295bda3905bf7ad65d8df778338dfe6c3def5353d431a6df12a7330a0189519c59652817940033d90cbfc296da442b12d011ad9b4beb59dc974f9bcaae2352da382302408d0994565d64aead81a578dd3adb44ca1b4b58cbedaf2c2855f8c0203314c0da48afff87d2aed9dc966d4003de4b0adde327118067b826db4babf7fb7049a4c6be746cb697ba465074da69bd91ad68aa84d097a4f2d0db8fadd8a089857f185976e98b20e3c9e85804f9aaf4cdc9a87bb0c5d91cf8eb0cc926c0e8fc298b645c07fc0472c84e7ca0eee5b4576ec7835f9d78512cd00361900b9a813efda32a03a242ad8ae2b90778a4d5f7eb910295deedee5bc4409b81797d9751a24a1f549b9d2735c8460059d0d7f433e8229a63c49535002780351a415ae2b77ae0980c313f9f0be22c625a623baab69f273264b2079709b4b3e9c7daff40fb71f3c1d4c9ae4a4f129c3860b23af8071295063ef21444761515fa1f5b1e9e03c402a2a42cc56e98dfcc35fdef4bf97e530a0f6e8ef798228442bf2a5b63633ba10637c5fbd9436a5ca94b5235760343a976731567cc840fa165fd3b181d7e8068098db4bce2aab6eff27ed3cef98a6b967e7940fbaebd67d16fe83640dd06ef6869a577006dbde001ebcc474753da64619d7f0e0b4369196bc1f1e77583f312dcabff0c3967c63be646a2830185b721f83127c89761735f80d1a8ac05ab30a50a15a545c044182ff9510768c882603e4877e5045d4a854a6ccab0ae92d9c80e4477c6eb4a12dd5474198fb0cc6190f", "53006500ac0063", 2, -1000506218, "f9d258fbf9fbc4521d5a3f854e64f9bf0d6a4295360172711718c24d0eaa98e9"], - ["ed3abb9001316b8865d11773b05612e79d715eeeaea4c86446cec5ccd8947ad3a2c84751c203000000086552526a63536a51ffffffff03abb71b030000000006abac635165001552b0020000000004ab525265d5c3d80100000000046a51abab44454df5", "006aac", 0, -2059530830, "176d14038f5ecdcd58200bc5eceb1a082db6eeb2994b2fa1bc7e477affcfad53"], - ["46ffeb4001e9365eb1ef05f45f65a9c5672080b857258836dbc186749657ee4dd2ea62b5780000000004525253522daed4d401bdfd5402000000000365526585e41dda0100000000000000003d815b0000000000b365a23ec123cff9b76ced883132c502473aed28babc4a64523c2f23f7aaf121b4da223fdd057cc3aa62d4c07aea086f456b093a8726a596bad3df032170a0045be1ca558ffe35aa60b6314f9be4cfa63f0cf81b10aa589ed278f093eb93d0150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084a5660fb132fb4813fa8c738622dea51c93e8d58cd81ddb72883141343c39c615ae602797cd52e964ecc40315c0ae85b0e94ae0b579799a6c18e8f0b0628c1f5a57b4b2c6cac5ee968d802f54e26a255fed9016e2f6656f7ca3e9598c6077d55284a5fc36507156b1c157614f0a6194ef2ce3341b5bab5eba7e185c704418f6031a8668d574420b6fcadb8e625a9f20f7b97439cee77390c0dac2386f8ee7236d0319ef1846e45d8afed7f2ba96a677302e18329a581c568265daab6ad3a7d1f74d0a2ba57a0100eeca9301dbad48a1121aed03ea15bb49aa02dd68c144970e48b87f1705879347f2f36cc503bc38d48d481990833dfef26117ed35baa7fd20e8ffbe022db1027c5aad3faed076c5531c9b645dbcd3a24a75c92f18f1222f983aed3ede02174ba91a42af82f86ca3510989abbf7879a9e44d6d7e17d79d8948d57179b1b20208e83c8db4a926412f69cc59cc419ce5113cc6709b2f59ce59475bcfa5fa3672032710bb7883ab14080e82e887e337fe471210f098c1316f2fd395ffee7125165b021823e74f3167343b6ead1097f95cd0a1897ef90c6c28a563d56bf3e09caf60e9acd0834f42503124d429d89f6337d31da32ed041ab4d07ab1117ea7e842951374416dbba4040d7d58f685e2c0e883473729d396b5bd74f7ffc67aaf7e7475d45750b5664a47cebbf5b16ed3b671cb8080bcbcf015e4b4ee62105df635ea499e444e4ca46d7f9ee85c7af2a0868360a93295062c9c7fe3f1554631b094b194b5ac03976b742cf8bddd8f1705c8476784c760f249c9163a22bae28ec86262fad9224c9325af5a736a8f65c139e24e332176e15382a454e52c92e216ee42de5421294c3b537daf3a0bf6bddef25701edc454409979489cc8b481de34f2dc87bcfc9dd6fae38f1d0e2a3cb3cce2998b5a4969a8198766c220436cfba39e82e89de1dc9c2de49cf66468f4f95de8d555fa24a31028910bc4c9a3407e89e3abe9761f6ad73972b8afe9ad0fece24a72d164e39251f6da4637fba9707ac891b7ed8e03cda16f88abeafb74a4f38032602bf2d89240dd6f9fadfd5846d26825c43914936d45fe8465c000e24debe8b8432755d7df574192918f7f4ae5e8c6bb9e670c558bc44006678c7428d1d423b53ccae6962c13559c43b13630f107d4ad838309cf1a0dc4c789a62ec43c524f4f7c07634f33671f67cb233cc4597e57684284656601cdc14755cf2dfed3faa9a57e573b3515edbd23918c5d470ccc0946b40f7ff507f383d26b8c3c2e532e1fe12adc1ad0386159b1707f0463f20a91b32d38f8f0a4402349704c4628438268a44c134a061102b26edeeee3b26a0fd4f194c6b931a4dfaf1184b83e9cd411c07f28514c2480744d0764c5af78f567691b833dfdb5031299e0b2bac752300b87a23e1870831cd6fb511450c8085bbda2fa20940ab284e41ba070ddc44d4169ad7d07e0139c6331ae9c8dd4f5b4ad787ac84787673445400b9a2ebd645a42cf2dbea82b88c47bf3b37c93cbc1e835b87242a464e45864be2a478e28437b17c76159775480e290b9fd01619d24d0cd357dfdadc1c6861988c40eadb8346a68ade7dbe812459729ddf22463be5144a19799bff76ff01f489f349f0b54b900a1e134c6cb115bef0e6f811199053452271b89a65169f561eecdafa00e75df625f88bd0b394ea1e995e18d1987124c6c93a44c0b6bdc71073a76991ba91c950567623fd8456b5ec2f435d68e8ec36517e8818f1c8710a64b65a95e8233852c4ba74f311693e10226be8c2b5bba5366b562b729f9a539c71930a1de676a8a7e466642afa67e230f684395b06214e20c049cbe55f34b57bbd45ab03411eb8fdcf4683aec744e71e55dde436eeb6ab7e51ce63febd17fb0ec3a4a406292fecd235a93f0a7bc22e4062fbeca438cb9d1cad46e6f65d28fbd9069695dfc4e244919ddff3f7ac8c283085b6f55c84b3f34b16ab834c17742ae2fcedf1ce55dbd5dabb6aece3786b0c95059d5bf146683875bb1cb320479920b3563fea86d7ac6f8101d4edd33679b27f1ce72e3792e8f7147bf8201851178201e89ece75e2cc53e773519bbe927f6151684b571aefc994d2fe36914559945d4b637510174c5687cfff3107ca230ab963dd4392b2e7a10eb7f685550f345f3ae844be51ecc8af24c824ce63ed1d5a714dd8711d0880ee0fc5135b1c1131c803efabbe1391eb9ba853c09a9c414812fed821091fcc482c209d18f9c4f8f94f9afa51b9ad8ce47a17996eb54b230955896c26f72ce50e5f8bb93649be349aa765bfda58db4163dd4335cd06a5b215fb2f2dae2319ca6ef6343892d78ca293a7930dc796cf93e6970d97c90e0125ad31633cbe39017b24ca21ead318d42187a5f43efde50eadbc432a6f201b60588041460f0d5fa20b", "530051ac", 0, -852224685, "016cbb95af8633735892055162236b783185aceadaf3fb515b2991a969db12ec"], - ["7760c4ea03450f9733d2d752f87b1ea87688902529adfda7496d5ab6febeedcc4af19b52f30200000002ac65b0a9aeb6b1ff1036747e5decc4fcd0eb9112e7ae0302c5538d82d0a8f40105177a4bf8690100000005ab63516552a1268da2ae6d8a2c9895fc0daa1f4bcb60da7406880ff3f17331a7599b9ee1a6c00148630100000007006563536a6553ffffffff04e70177050000000002636a84b8d70300000000085365510065516565ba3c8e040000000009ab6353abab0063ac5225a4c7000000000003655353115fa50d", "63636a00", 2, 388073941, "241efde580b050e7e35b13d26067bde5c6143ca692dab5690f9ce64dc45cdd50"], - ["c67c4c750343fcdd6f776ff00a1dfb7f3dc5e943b7e2fc0a18a1c212a6380acdf6c2f8ef83010000000852acac000053536a48bf476abd5e562913aca2198d9caf781a110040b179d65c008c880dad3e116bd0d61f6402000000096a0051ab52acac636a3793f5355cf8594427293af4d7ad33a7d5675a9cc44cfb3c1a00032e1c52686e34fa36380100000008ab5252516a656a6affffffff038dfbfb020000000009acac6a6552ac53ab6afa545a00000000000152e7583b030000000008acac53ac636a536a29205bad01a8b5dc04000000000000000000000000cc0bce2fe8ede95052ed924e1c142a0462481e16ee6131a1d1c27a829e4ec1eab446afe9ae716f3f0c5fd20d6079a840a3e70461e6bc52065562b1abfb7622b45367e39405ec33e169f28ebad94311fb7bd1c6eb8e04c8d31a356a5442d0f95700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000def7372281b97a6058b3a16590f4e95fa603bd2430484a97860be09997171cd4aa9d5b5eeb8c8b66de681dc70b23cdd8e953cfddedd1c5be7d9825805ed27435207e15e5d1e503217b982d264ea94fa95964c4f9bedf804bb718e0ac7f1f42201bc6dd7de939172c4310288142703215a13f5aaef130e665d0f021e98a13686102085c094eaeff2bb7fd25f6429ff6ffbc5bf08ef48c3cd77090aa57e132ba3759022ba1efeaa1fe19b2c803040b56c43f5d8b5ac78c9be3cdc6e764ddd0e99936200a2c14470fc28984bbac0fc64844d2425c2d976386f53da7621279ccb722dadef927d55e8550832d4e1f86cc1b4771536e3f134055b681640d0692cbee8d2e696b0308cc87636eb24502c8935ad30e4c747d90368cb1399d7afb4b52df65c5e7c437021f5662aff67ef22f3f5a1e0122307fb9823adc8ff990b7436696a49f0aa52077032418de48bce41e989ffd045e2cff3d957ee13668b8c8b2d6bc2fd2d45b23be3c020dc449fe0bc9db9142c09d23ed14c434df0ea4d850954787691698e22be996a8031a9a45c841657762f1a261a9cf8a9e58bbf405c9d1013b9b857b04de3aec00704ae554aaf9905e0fb28568dd8c8e6218eed2f300977e45ceb3ad40fcd3c762d1332628fc2557f1e8ae15766907d0447d04f7951b985ef399a2ff349b24a8c3c2549eae4bdc27daea74e2e7c2b885b646c9925ae4ed3a2ef4ae4a5df4ce6f6abceac59511028b23d81bffdbea3726368c84daed87f2762cea1e583fb72bf31b99d07840d622dcc376b7e5990d3462c1dad8fae60f4112c2e56b1005e6f7f2e714f32e47471a2126abbe604e45469a81b1ad19a591c25e7ea81dff5f43b201a5b030f0e00c16a5ab5f600353efaafdf833b4c9e121aed6bbe7afa3e8690b4607ec5bfc946e8e726c854d9cbf5611a84277d3ba77d41e4ca3c0dc148622338b6ba1a051c944a0250f3129c31b26a1b8aa519fe0c13dc6ea39c42269afe97e6362de05694a7f45fc7593a13a77babc14f9c093261126ea7264df367e22a0a4affa90612c2073a1c66dfaec0464a2dd02d3c91057f8864c314acff7279e992273e6ddf28b2811cf4c3c9d109510ac5fc599e80d784c967501eff22cf721e8bd20028be2708fba67acc741c798086bba94546beadd5ae2664a95ecb65a384b86a962242b1e5afe29fd09d2dab35a99c95d4226a9245fe09efc45b3f65f17827062ea5c0d174eb0ecacb7e5baacde82e1a5e110800336b57564d1fdeed769fb9cabd6ed94717380fc94eebfc710bb59afb18ed05b20c5f9005fb0c1efb5cad95cdd9a5988098b03ed76aea2fcb05fdc835c5020f99d381ed55824da0ca01c91550cd3d4d429510544e96d45407f2ff5ef74f94b82c93733ab4574e637ac6a621bc63b72dadc95f70260c31e22cbfee0cb1b4119a3a662699e5b7c8bb7b2fa8f5663b4952bcf46d2a94fdc3ad65950a79d17ce20d4d9e53d923cbbb0684156b2b9572a86a71a5729649dd1d4b822742728382e6dd92c959def266295e41c46e7be1d0aeb88f771ff159864830df2075fbb12497de623d449383f67e78dd31dd21267e57f1aadd5d1b740dc5728f4dbc0d5e0f0ffe4e83d8f77cbceb3ec3abdf0cd48baec4735dcc211fd9df802b9593f7958c3df7f085b3fbe5f05189cb5c5b9d76459a8781de0d168caacaef20a5e6a561179cf5f426461f890fda742bbea8f57e5150d1032c09c025991bfbd8294b4f66c0b3cc6fe4ab1344d837ece1587b393a52c71d659ab9720f0ea17f1fbe55042a8bb077180a9e4a86781140ece78bf1cef46b1dcb1a852b14078a91782f761dd4af6d701de61cc62a16789738761fe064cd811734d082edc9bb8eb4be5b935fa57a6cc0fc1da0fef311460085cb877b3417d216254102ed8822bd9a7894f4afdb9973cf6984bf99c7c7c2c20a90f9a3c15950d93e18d69f49b22a963b69b3ac3a7b6baf4c65d8313cefeeee0a535f5afca64ab8a7fb0339ce8371c9b62fed2da06cf14beca4e02d60def4d89f34e82ca7060176abb8cb026295d7a4dfbb1f074f55e9c64cda7d504ef0cff39b1a78444c022f996d92eb117fcab5c59d7f2a3e8c879ee1d256eea5548bf5ca246dd7639fec29d8dc22b1d8b1d8fbbfaca88166a8c0271de1b1b0ec3cc5b6d3fe22157579a8afebc34593705f69d5d0c73cf84bcab0740c3d2c21ca675adcb64b8575419167b190fd486bbd87d8d01e1f7f20ab1e17e87246bbcf9f98cec7fdf2616e264d7e94fb8a74cb22a7ddc2ae3c4a3c23106c0ee226f87b25e5927df2ec2c9df6edfebfeb18c699a7fe7f83bedf81b4c5aa2723e315f30f7c6f9cbe99e06a8f3ebf84a40ad92d3ccef17f79d02b5e850c95fd0bac754e939eeb2ccd2b9a1d084469c192e272c1dea9f8c26303c0f8fae666ce31b8b09", "ac", 1, -63997144, "00aad930114b9698ae668aeb8a7c623f4bcf0ae67a8b7d7cda6d942517115ffd"], - ["dd360ae204e8f56adc69dfe4c3ce1d2e573298e94b7c47138dcf5ed1849ca94a8fe263682e000000000863515152ab515152df057c78bb57270276cd9a6c64ea36758619d6fa8659ffa6f56f08877a55610cdeda17460100000004ac5352651cb4bd7b0d2d7fb2c597b8e325c7cc8240bb17c08e37541c91477751afb50556220c91a600000000095153ac516352636a6affffffff11fa5b2637e7da18f32806cad41bd5fd0c4d5424aaff874a91c03593044ee7e9030000000851535200ac516a6ab568d46901e18afe0300000000036a515300000000", "6a52ac65636351", 2, -840047507, "bd786974c78f019d9840a8ed947e95e2b83261af67f5c36206859cbe116845a0"], - ["088270b804e2447082287bf1b751bbf4b7d4539e3392d91ce769b1cd77fd7d86f0121295c3010000000263638071292937548f74605849363c3f22466ea15382273b4701d1d2924f78aa501691ecf65c020000000852536a51ab6363653f58564f38622a2bc25dc1dd982301af418a2d61276f99b1c83c9695a4a8021b3096ecd600000000006e18197b10f4acb757a52de07d094def4c1039399227ca4f6c6daf29e0f137c51315756a0100000002515379d61db2042b2c77040000000001abdf93c9030000000002ac6aa2a86b040000000005526a520051c0a64f03000000000852656a6565656a63ae712300", "536565536552", 1, 2086079035, "5b770f9a5e5aea286e5d3ce0c51b0a7dbb450b6dc864873d5f89d38f64ae3d46"], - ["7f72a64c03e68fd8bd2e1c79e074d9a4e07fe0b0b42ffe6ec275ea8799b1616ed15d8d7ecf0100000008656365ac6aac6563ffffffff370a68c2656bbec9f516f84538217a2936f189fab6dd726eacaae6490746c90a020000000500ababac6aa99d02c92acbeba4aad94d248c7440bc84bde7f04f471c2efcb2e11ade71f5cce7212dfb0200000001515354a9a403c251af040000000001ab427853000000000009ab536565ababac65528f189e03000000000000000000030000000000000000763cc50000000000d2a7db38046036ad5dfa68ec606a49eaf80c6c7022139828bcb26c65e96d951c4ad3710b20957e86c33d24a84433ded5be9719c3cf9b09f427ba53db0d33b7976737f876de36584ae434326ed61a595b0022fd14ba78fda7590964f1e5cb8d9300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000902c111fd203768a569df41494f3e0245e2d701e6a53f27f2ccd3cdabd05bb97296266cdba217ec3f4f0eca3b7009a0b6edf4ac8d424db0850948b4372a5a1f4aa57e6f8d039a66c0d539fc802affdbf25a92350a564733bc8477219bb9f9690e0e4304dd4947f585ce3124ec58021dbd662a8c697356cf7dbb8343326f4c1d1020d6a1f8189c68c1479d3b06b366b2757ac9cafa1f9599f6ccf6fc5caf3823bea0211d87f45747f359c3b885412a0c80d955eb3f2cddd9d05daf4980240b5ad0b7d0b2b9968c1cdcc872e79382da2c98b2e946019c8ff7dffa5d7c397a8ca0fd23df0271e3efb4003f8ac542eaa7af124e02786cd4d0e53f9aea50c0f06cd11fc3098030e33c8b4850d8b6fe9def18f101d9acad43ad1bc6c9876770722fd8bce287c390210439518a019a994857aa8fd9b4e2b09a8c6549e6fe90874c13738b02d7d279b021dc6490d125c4d2617f9765170ee5e4b06d46d0d42fe32ea752fb3b5b4dd28bf0309f4d721f0c6bc52886c5acb8d5dfd2c88b9c6de3a9a0b92d47f997364ac89cb021c6e0e0fb9ea6aaffcfce275e2acf1064cdebcc59cb5cd91003091646219a3ee44b6e45fa34b4f8e68b8871ba31c24d15e45d21f9f66aadb6f7046432fa868bda8c46f9266712d5e05b67ddd07bf42b7c3ea2fc03c31216eede8f2dcc9c52959b241c144b668104bf4aa8ce89450c25af906084d25aa63ed88da8ee52252e9685fcd1f613f88e144afbe5f5ffb12b185f7426ee4da5d44b12f25b80195f6c88862469b9a225f297964d1b56f35d7c204f7c9294fc9c11f17e7002ee42354fafe8506b1ea04a9a7ec0e3adddde7555f58661fa1fc38dfcd72413289752313ed994957b4c3b211c408699daeeeb4a680a0dd153a7453d2fcc6d1a0f9cebb24d22815137a779f6530b9d8915ab3bd12b96af012e309e5061ba4cd624367859c332746330c6758867dc5609941f82624e7eecc14d5fcb6124f023e9ce25045f69ebe04416c3d71e7eff0ddc55455d9b2d5ee4e13194baa800e538ef4a2a1666738694e2a2150a2b344604b9a5fbc99a5d29b2f2fdc2a427149c0a6580de805891be8f5912ebb717759ef25bf5684950b47a432c1ed420ccfc560c9ca1305748d48bd42f1529e28d73cbdd193de7a52d8b6296084467b8a6392591f72c4e6f2935d126aa5ce9e20cb247f2bebc681085015ad204ff6f11ff0472468a03e24b7af1bd133e7a71ed0157f9cfa0c4e2a922aecb09f054c1c6c96aa7393798b72166ebd96a3928a9fd6ce1a464dde4da6d9d163d1d6a270d2c52aeadcab7464f8d36f44e4612c06314171a119f6762b65f7228841f80093c7c7633d0824d7a97d6381f5a2dc70f595aabe79e096f6be7a80858e18672641de300ff28ca609997204ab2f397516f3bd0cee7621173ec370a3f45b34ea752694a89bc87fd5f8d696bbe0840f31dd91e2ca6e3b20c4dccc7ff6c9ad2b94bde7df72757d91ad18f23527d4353c5f13eb167324e1f9ca44c050031f6929a700b2942b1b012510cb61f6a54495093a9ca1900367a95d57230adbf02afd6ed3baac157585816face13debe91580c776a69d23782fd83c5d2b58e2cd586c9ab671734ba147d2290f6c91d13ea742bad4e977735c4d15432d30bbd85e6548c530608275dd635665262150164b62f2fcb142ef0297c1b5d24e1f989b523262ae3936bccb6e00b24b326b7efd578354198a20fa4f199445b4958fb9b68a4a071fa95e86447d7da6aeb5909172cd5c7531f563c38f8d6eb6aeab13ba94c3d7d956e3fbcce98c2bb018e72ecec248c0f73accf842d2d0da326bf22d2a7c648cba2efdedc0aef5e6c4d8c72ca6eb7a828079be80f6d5692e0eb34a330caa834601734c1f745f450da69399626939edd9dd1833d663bdf00c01ecb77ad84f82d6cc75c5aabb3c51192e6f67c861ab7d5a5c560b08d949f4d94a0bfffd9189d382e0174b6a2bf58316c43b6f9354683c1fd7895c6e429d2eaa4df4afef7b7b9a139dd094a8ffa16c549fdcd976c7308c22c43af30507bd9b7e3c1eb825e141a8c90f951c5292a94c131e70bb115054f94d8a395a6101af9b11f96d204249af89e619115ff2ac9965c9bf7c4bd438b47d75fa6b34fa46ad575f83d3fed27d104f862bc67182c062e98ea334485c9dabf575f7a64193e2f678aad02d7d85888532c0e294e7d14b8b36818fdc586905e2af22832ea968553b6db0934ac7f213a61e2e418c76a5c4ab8c5272825d0ca9c561b38df55f88a4e084c598d65c590c7121c233f34ce70000000000000000b679b3000000000054ee3bf8cc1e7fa163c850188925514df90c8ce36fabca10ab798307ad627d41b9b4936dc73b56ae2e9f7ba5fb64be01db30cd1c858814d332fd5a2d2ec41e52b85c8b57f846b377e20691e85a5a1a8709253b7e3d4026a5af55e9f09ca1037400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000289cc8d6387e4890e9b4ab2184f965461f1e4684b97a5fe033aad2d13a5d23b515a2b0a70b45a381f3c7e637bb208907abf2e0863cd6b5fbee519459c127e7ee5da0b8caaf84a7fc468ddb986c75993dbad10bd0827607fdfc86df6161aaa81258232861dea0f80b6cf3f788cac55d79a6b1267d4a2048dff42a88154d7bbc77031c4bbe0d3350b9667d5a676c433a18e9f63916914be487de113172cd4171efb7031806baf72ef9c888d79458b96a5b65e45c6cbe9e950389a7d5ff25b4f25741540b2d3a278382bfa9588d4a69daffbd8b6fe1b51babc6ab45977ccf9425ed0acb451b25293916cdf41dcc5d79a80c61043dc7d96d4b6faf330bb4b9d262303f6d0f022b4ba0cab7b4990ea4053be10e9d00079ac39df0b89dad012c2017112bbf21810313632498f20daff064453fe895fea253211b8efcca7450182359b9f26ed03a36022c0b5a6c64b31bfe18f52b39d2bb18db2781a63c59067d928d751714a71e3f53021c6e64b631b68b7e605d3eadd4398b6196f9f08909be03b8d6e6cd4edfa3393703265a3c4f516488b74c0a606d7fb227179810a0c55bf44ca68f8216ee42edd9759d60fae6081c3b107ce13d9d7922ed754ef716064130db0151e59a43c270ae0be740643f2f290fd5232c9979866ce38f7ae6b0bbe9a5e2cf8215fd35a7bae3e252bd9c49a8cfbe2d9c43bd15f4b639996e11c07ce3a07249878cd2a5342dcc689094a88c43fbc98dd2c4ae86e7833fa5f933b3440c6c48955e5bb40d11905b645b19a3a33cf7e42cb8d494b44f8da4305a9719076edef9e8410b9b52e6f814937ad5e4aac5b57f996734cf59998c1ecf5f1cc897073f76ffbb3668deee919eb5f5b7b952aa92c213ce62533028117ca2a80897e45bfe9d33b11f9e67885417a8e2a688de3645a1eb9a5266d3c36509cb01b4bcaedb5b9b8f90085a74c8f7172f0a5c3406db69672728e706fed150625f5381327e6bd6e5532b6ee6900ed5634c3fd2d7669b9cdad3644f36b55025113caf1955d666511abe7f3e1c58799511e249d9c2cac060c0979b732c4586ec38c07a6d587b4545d9a88639f887342bffb429220b09d09101b4536be08e54a1d8a7aa1d8e334a0e4c5a44fb1011b4da05d17179f513810c35fa41fef1ce6c834acbb5a508321cebe5f6d27f4f2ece3dd55b05e987c45173d3a474dd02e818a7805543c4384e0ddfaa6acc5697ca8124e06d12ee13030be5fe58f05bc872914f51a247c7f2714e1024e00f1814165dac6cd162db8b06c6a599393cd870f9d2229fa2824a86270944dac044afe229970afe6c3d73d09d697e72c7fa5393e72a22448743a5527a2f8c7e6cc1771cc6ce3b55b0303bbb48e62a6f77f870f8421c70e41a4b3ec354fd612724dffc3bdcc79a9b4f52d35f6c41ac87fdbe2db36078d193af6ac9ca9c8aed0d5aa40642d2137e89ce4ad80963d48abc40c7dbf7f156bb5c95e5d00d3496f66d10e2c2f2798422a2af43da859f443c7147d63ceb072a0bdc7721e17581069d643cddae4cafe781cd2e66d7ba27e01c74c407b2838fcad022324441418e3127c1128de0535891c626f435762221ce5c1f92b07cf3aeb07f44a886f85d88578e43da3a71832be36668bf80945e296e965263408f88cc711a096d47239aa1a4c65fee4c1968c17514b7676fe61df11062b711d1b93b5445ec44ecc426663b3ad9a9e17b105866f0fc06fbdd69ea25767a85ab57e2b70ec48dc6fa4c83f4b4955fa6f5f31aeb6ef0c8fb1832803b8f3ec3c18eb7293f6903863533cf635651a9eb737fcfd20c77b888dcc8b09f6c8e16e688a0e9a4919a356755142b96f51b0d3664fa0dfd88bfc2ce29d4b09603acb942ee1596fdbf087564641d669b59cca3724c8e57b67874befb996c10a660ae331b496ce0e0762b7dfd837dbc3b92876cf9efb34cf384bca505e71dcc5625684d04ce1d36d656f722faa27cdb32e4f16cd24c1e466823d704db4ff1ef8398e8d5f80cccb44fb2a9decc2f724423651d568df05d8de0d0cf6c20440c7d69114706ecf9c03f027aad95fceb372cb7df3037f2a0e042f366db8354d326d40d9e561e7cf6e2f9fbfdfb6dbfb7bc8f30a0d996070ba6d664aaca7d3ddb0b6dcd5a4689c6115e902d8b648c90f2dd521072fb1ecdf9d429de54b3d26d7cd79978ec4483ab6a6925469080c1551ceb476cbabee6795cb177ce70c4da6c3aa16e559d6b4b6864375969785724a100f8e18b6521bdf2483a342f88731ef7c2d9c40c317879b2873d3d325e5fe5cd5fe8d5686dfb5a02000000000000000000000000ecad6f06421e083a41438eb8084d0b37e7a5fa698ebc286819b154c2792f8e8701652ac612d0bc583221166c61a411c6348482955e77f7a8cc24a4faba8570c4ee8977b6c1213c0400c8345685d69d340755bdfbde2367cf6959377a5e07901900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a85a4a909b0f30ceb8a6c5a119663161507f19fced62b87d379759f0cbdb690ee9e60e70830c73a6ad0037b2b789dd44775eee3114793541eb98d8821d6b0e04325859ba77b55fac30971ebaa66013f5f78436119a8a17273546f6ee3bcab7dda20dec4cc53c990d396b6f7d6fffe84d24e65dc4dc5b6b834cc4477d11b23a4d0214e44d3690825687d4c6fea30204f5760bab846f672436149d3db19f1742de120218b912a0b82392122cee384d16eac481e03fb7252053454ecaca2c455d780c970a2a08eb6ad25385e34738066ed00d0a4053a81af46146ac8d7ebedbf8250bc8f00e3a3360e1e88265d0aced96161b7435dd467e1c06e8c16a4234bd2b908018f602085b3ff1e055f8aafb1173b9f93f95ed8b75dd51a512e2e245c39fe0dc2946fd0322e033a86a4c34d70b4ef90c85185bc80ea7c0576773712c1be7454553a30ceb032415a4bb1dd00d48f12992b43013199d68b60c38b6493a0159c06c4b1bbf4d0e02215842c6fbb1436f6ee7b5d452485cfc0a900ae9e77412bea9a8ed12b6adf263020a6201b379060eb46602821bd2272786cf4dcc3b59c1eadfae9cc9c54a5559af41621f839d698fa447873af03faea8d6203d6b33d8b4caad1b888721afc8d212bd0c67ca67f631ee787774fc22e5d8b51d2586e2490f6f250e3e39636cd75b2f63159b773b50327a70b298c5147c793f47f09e89e8e7b48009fd95fb9da18deb8bc2d39954dff6f8c3900c187e0f9e83a6a9ccf5cc2336ebc8a79813667573a1cdb87b5dc5393207aa7e80020e8c9496e0a70aa929c51780acde14f2ac8fd51e83aae55b25ed24aaf414d48fea191795abdf1011ac50205b01dd4f0a348bd8ed0593af4eb647c5b5512619ecd73b82b59fada178d0e12b083b3c731e6620fb4d7081f32c4ec77c7f8cb2058d765cbd7c7cc3ed4064e1da8fa82b00d73088af4b34b6ad735493a002cea4431d41424017c49bc21a7314e837195c454c1ed19d67b7fa785e57e0aa76382cd18c600f27aa7e34aa6caf8dfe001972af26e980bad619797e4380de44fc3e165fabf293a80bf92de93ddf8560f2ed572e8e34c9c76b37147a74c4b093e9b0791fa6dafb18e1fb061827574ebc4e0329d141634342f80492604c661f8b7a88ebbaf7124da733667326b72a4bc83dc850e7b5e3b8146dd9b3dc40a5a85bb9995efbc23b8087e5b1d8a6894dfa6b03f1250c3f386ee5bc29298acd18d7ccf3e50cf8bf3cff611b269a341d6b16c7dcbaa517ff866586a9ea18f06d0c288e7ec6fd5ee097e09a0d0cb5bdc17bd218da1a8a8d0a9bb56df2bf22720437ac0d1443a853d19e66c674f803a881634498c934373075944bb137afbddc770ad169003af1ab53e1780949863ffcc0bc7bf5cad2c278420c5ce34879b2e47dd200a04879ba553841349c1bbae3482c654d459cfefef9196e05d21d305ac44d52d8373cf55c6efec7c7143aadd846e7a58bc066ae918b170d0e0943c4031dafe4e968eb4c1356180847d290b454edd8b31614548b9dd679d6a867f86d2ce954bddaab9060b3ed6a13929bb1f3d19e97026f50ce8f554543daf68ee3fa2673ea01765fb92cdfb11a8a54b8882fabfa345c026f13a083e62673882b6384e17607acaa05763605112e030829e63d1fafc42e9380ec3c755d552ab9ae5d4508758a2edde5adf0b036e1d43687deb7405969952d2f8caed09564c830192f7db2e3e4bc7b9d8052a6b0eb8cf54ef85f0839a4b0b1ea9ee215c702b2346d8cd227dca38a4a4f27e3e293f0428094b495a7bd2f0d844806746840de2961ef7101cb12de7260bbd0993d0c4f5e2ef564d4fc22bbf176a718c7ea90426932ba904cc462b75f98a9936c90bd7639afbbbc14f03b2be72e6614930a72c9bd3d46188d5a1c71a57b6b91195bde54afab89294be448e2171be68d541f1f6b65889e67b4842cb29b2200da3182fabfe961aadde0bf3ba16cd5fa54a09011ddb21bf158d5be70d6ca3c9e50cd3019c90f0fd9ed92a15b1bf802d8754c7f2fbe86935e91980dbe6de8c433ee10ff882a93ff813814566da92e1ca6ec57b76a22536dd04b49de1401ce4b65992221cefea048871fb49988d45deb6bb6943f9c47dcc2d1e189cd007ba52d9378cb0e9141ab716df06912ae84d6df890fafe6392581cfe9c581bb76d5f62731b308b3a36609874b322bfd806e27d8185260a091a67c73f5bca98948b077d3cec6ee1b876aaf237bd10826cc17a76ff82ef5b8b94aaada6949b1fd861850829028e3d12aaed62f6464b1cc449753ba15e4ef4dad8195a44ef93a3ab7ef141cc0724d903f42fa407ea4386fa855b2630bc6ad898d5408af5fe6fe9bb94438b2f5e27f703df4355f1f4a7c69b1b41ec211aff789fc9c37cd23b3a4f628f13f66edb19031e83485a91675e10d", "00", 1, -1803528140, "e48796b19bbac4e6b38cd39ed7c866900842f3794071ddf1a597da64d44ea2e5"], - ["95f189830293f601ce888ea34da0f6e1052835224fc1a58eef280ae80abe38b2fef32b7e1a03000000025352457719e872c9d650d0a7ce1241c7f48586b4d4bd3f18e096c495e88812eeb6cf98640e2c0100000003656a52ffffffff037325c9040000000002abacef9c65040000000007ab006aabacab52018f2104000000000463005163e0e85e6d", "6365536a", 0, -2071810366, "16c0a7bd6381e1709e3dc88ebe989d720becae8dd58ae547144f6387ca58859b"], - ["fb73677a01231964c0bd7e4d1735c8c4f13cddd088441d3701ef527bc0b8b4bc769e6217bd0000000009656a635352516a5251180d22e703729e88020000000001abb5403b0200000000065263655163ab980f39000000000009ac636a6a006a656a00000000000200000000000000008d276f040000000022f5b722db159bd649b5544bc2385a901d7f83b3fc5747e5eef017bc7737bd1ec30d42a55902c24a28b5907e34f295c81869a8dcd0fe7ade5d06da32db1459b46995db517f7c5b2946e356c7f15fdd7a827b7529abd1c73f78df50feec88c11400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421cae3b9a9318fd6be61421f1d0b0b720d90dd267c15fc5e99f2e2086e9ee3812d73be8252523e188ee33aee6dc1ad11227d227915a9a5610dcbf13b067023b51761aabe1355f4c078469ddd01a2644cd732ab29f552abd767afbcf46ab646ff59c585662e3654f188c18e2b5d331918b0a7551dcb9705052158236c5cd385802056575c9cf79b4108726efd79a74e18d7ddfed15f263262b253d74816a6201c9021f39f7e748095796c628f7aabee0af3ad440742bf5de3258b9679398dadcd0b30a1577fdfc354250fe96df24c0f2be1cf777e7c1137936c4c9534c3e67628f01e9153d499ae248fa115c0df47c20a466f22dc93a12567d4c51f8946a14b6ffe7610306e63786512d108489b9593caff16722a2b152d7a0e25683e49baf16a8c8ec21032e13e16bb9d7f591b2ca9fcda22205223908612b67caed5b94d591f8f3c230d10200760c6da05bdb2dcbcf7d64e7906e56a01e7cc97d2c6873f72c0fa94002002a030e8fe46d8cdb5e3656f75bc3d027ebc4ddc0fb6aedadd21f1e4bdadc2642562c022f670d1448d773976339fb09c66336661ae16f28c206b0c717e0c364aedac242b9ed865c37586925813aac8d4974b8a18df747a958265e316c2bf57c6261897f04888d23ed7d91d30dd8a8982fa5d13e481699bd0291e223e333a9df95214336a3e21292ea7e1cef975727192d1c726504c137e8fb5e53a514bd932bbd2d9171a1052f91a57c6937c24068c4edd57959a33929dbf7939666be3f97fc751de6eb23e473af354576c9e5a9c28277ec078df9f8be0128cd74a5e822816bd80555db569d28fa304528b5ef532488e46a3681e3336122f29b3ea22ca80422f5d60fbb9ea1f502c0ff77a93c9c5d096c8bd17562be53f22fb9f5071e2edb76ffd064c7c0fb9631bd5c2acf664eb31fc61a81358cfb5f4f0afd7d0aaa598761c94b54e229974435d62fd8ebeecae77eca50cc6f07189a98241f9b3d4962b22233de909e76fd43b47b57d72eb73b0222820b1d061532028d5b3e80536c002f55aea802bbe260fd2c8848cb93cddaf57017953f2a54bf33e99be0d3356f1a448d57223ec1b017a4556fbc8132fe3d879032f422e6cddfe1df3e0ff3c735fd19f17f23dfcbac06ec32563dc4198dfbf1cb731fae2e5e323606376dec2b1fca68542293d6ae2613faa336e1566485b48e49f935f21eb4f4070425cefaedef8b9a57f2b95fd145b1bca30af810d34ddd9bd7269dbbb070a4edc131e6fc8b3bacd6aba9d0ccab56d92364895e110a6f33af4c1c69fc2ca46908e6b75698cc9b13ea73a8815778fd7b0c41dc687783722f85d25e4d0cddaf87be795304847ef7a1580eec9613f210366cc007e41a70b5575e0576d3421485a8a7713b4c96b8663ce5f0d5837e2952a71c7dbece3dad54d30acd597cfd89df912c77b8b7135cf91ec0a656206dde11d598e7e47f6b42020f4b9e5f6c9cf337bbf5019946429a414a9aa025c57aa83def9daed2dd73c0b6c5456fd520e12b8791624d7d3fb685ab5a1b9b32e19d2915e5cbd1831745dab4aa498a1b9947cfd1ca5707b566e1204af78b73273b9712a1e292acf7f15b706e9fa8dc3ef2b67b038728df06c249848a78777bc9a2a7e6a7454f08f1a1cd60e6bbd7ea7a4a4b75478d3994fbef7140d2038fa7e295819a7513c0397faa01958e80ae427ac9ce3fbd91796d7afd7c8f29e061519b1e446117e722c05be4dbf0fe5f6ec5ad65939332baed73c1f883dcd1c74a1217d041ade6ef83d718b152026335a2866a4b520785e5d593d2cdb6c513839bcc35adf185c11f213e8fa6311d6715be26cfef3588d4d5c90783c83c6f1c50eff1a502d7cdbd23f6c2a4b2aa9bb2b78cd30537a05372c96f6e69dd63a3ea7283cb79df29e5947f3687e0c9fb81debd3efb7d226fcfca873fc777f7b588376d8eede8774cdc8efa8d3aa3a32eccb8535d521cfc6f516055340681c49a7fc17e3af82884fbfceee4ed3b9e7857294f638029312c403f6a037ba40335df5c44904639c5e2e7b4a21e3040bea55ccecb1b9d8ba9460c70599149ff2fb2a57efa9a615d1f7a8a64f21f91a4a2a4ceddf4e66038db4c32141262ca761d0f60aa23befff1f7341ba8738b298b94a490b4f91f0107d4ad849ad8a991130caf058bc3c983899e0c6d09c1738d76e8c974c94325ff0038039e5660ca8b6c4d675fd151edc07fde2281434c9b6d14201922110b50c724d84d364aed3ef002f9c0b46d57643387f068f803dcb5433145d1580976e3248e8998f66498c40000000000000000c85ed405000000007253ab1b99506848f337fd94841f254066d22d38cb1022a32504cae7dd8f8678519b36037d1356543fa23b75ed364c3f6600ab1b08d33c9000f49e3da0176eded209f54b48fe7b8567f57dc9dfdb0bec0ad96c7fd97edb530b2b4ef7d573edfc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033aa38d77fd2b5d9cbc82460e0cdb80f566c60814d76c387ac7ad67a4ca03b2792981ddf3d9287a273c7a248832f1bc90886d1498c80ce7ca4a2f6fd4f9cc513d365d2e1a775796a2c989caa9d31c25334acaf8c87683ebd14d7710984ef0ff1140d42680695b8ee75689cc9ad9be78cd1a6da589094e0d656378d998dc32b7d02019ed4c4a18c2b6d3d2701c552868a98c9a493e324b493b4703faf19baf687790306cf6a7de7449a61b486734fc713e2518b59562b301aed779228f19fcf2f92060b0d3d42257b8fbf89377ae635a4e20d3868045a46190d3f6b87551d63abda439022624cfd46e1e2c4a42ccb491fc70ffaf556f3ad027849f2fb925a4db0b2914a0220ec64b3871301d2891baa9dad047b2360099fb42f2ce4197d75afa42d7e1f8b031c42a7b4de3bca64ea66a3cca11e43094e908e581c4e4a21f1cf7ee6a15dc3d602252647957d0560a274e5d25ff7b24c50883ef8b052e6c662a262c3a316d614250321c8802883f7a13371c9ed99b948671558329cf97c7a0b39b3d8c387d13126520216843941c5f69b764d48fa356902ef5d672d08217dd7f153e23b9a49c926b984e035baa58f7dd2337106f17726f6e0818c6c46b66545b2b6bb3806921a4f494d8f61070e8d211a9e8e402ebd1798b43a7c3990b0a76f7c5edf6bae148b741cc7ae0f5ff2cbf281e101f753bed8828e6861483382ddaa5fe1ade6d58db8915c540ed603c39c7be85fcf985a42aedf879295de9ce56f1dc0898a05663de8e750c3d750299d48305ea8d2329325a88da195157b585f6b188047decac6788fa02f40551e0a1dc5598e624e0a096e20a0e3af5c963793f85171140821d548e57c6f98e4e18ca8f83c90158d969c3ad178b3304c8528079145911202a6d603df4f31092ccb3bbe6180127d0688e4d998fe5aaf6ea5ad11fb6eaba675915bcb3cc7554f97191891148b0d74f30ca3501dad345eb04a6777255c5cfa8394d66634299e717bf81e0b0270f3b95e0b6f444bf5f084467517d379a942ef7d92df02e4af1270b76c96396fa2206690b17b352ca9357787d7662fd008ee3113d2fe67d9d09e091ace67ee1e0ffb69ba4556b635eb8935ba30a70c32dcb82134a97d268aba5aaab03340482d38b914d8490a22dd5a57e2f8c5399f863f0e29718e26744197c452ba108acfbbe6e4d796e2320710c5acc2ed9035a8c3f0f804a3367d17ad233a0de2960d1703e1eb1600c16a0c41f35ee9b285300e709f2ab4a5efbccc53e391dd8d2e78085b44d01f443045709d56258e26a0ba7462d3d1ec581e864ab6547e3a4e50ef89732a4f69b9374d1878ba59cc2bead32b5d274843d6ad2967cbbb1743e3f49c55c38496c44005a5193ef78e1901260ba5bd315e896bae1c812bea84549e8b4a7ba0ee0e00a4b01bdf57cf2f6cacb67e92f9af26972c87493d6ade4b0b3a687f900b59effabcb83e6da051b3fac5bbc378f9146cc91853067da3f59118a805f6fd8417830f36eee3033cd95cb2ea53f76d242488f09376a022022387ef141803777195e7682fa7f0d86548099514a74199e95527156fe26067cec7df01173cfc32ccb2b5517af529b386c588aac31c02787a37236ec74a8b9964cf327cad5197a4ac38dfd1979a4a1bf8e88ca40c34d1b237920339a9249922f90e67a7f693f9436dfa438d4b2e23ae6fc89ad9d08dcc9465d3be9886286ce208d4a64ce50173a8633c56e91f9538a5271b7da986a9de609ea2c9d527bb6a7878cfb19bfaf0798e6c6e89970687de13aa12a23380f8cf3322dd56521ada908c45c8837acf3102ae720c3d19a815f1082958aa2a7d4005c49ca73f14c9346d6ae9247964736392d38ad6d352fad01942141c85d20b402d961c0fe7e9ece8373034a835c6b2fe5dd39f03ab1407da1aec5b3ca4ec05d9948a6c14b7dda98f484a21ab87ac34649608d0b85f7d09daa437392fd38c1f1a7f2bd36fb73bbcb0e5d8b7599f3a29c1ad3e9f4a7e266938e1d7c3bb53daae95dbc37596a3db8114cb09e9236daa313f91f2efd39d2c5c2e0d3d9c82f5193b2442a2e338d2425704af10513d2687bad97e678ec201781a62d76a478ba11c9a59951a8c43190a31a20dc2e05e0f10f214e23ffff4821114ba4a17531e91bbccb5c056f1adf526226bbff802f24124a31e9fcc5a3f2b87667d6997cd9ec19653d35b5511c3b53e9012b3543b381a916d8668075bc854ded3b480057881dae93024a03889b3fc6fe9db242460081c9e28d05d15b65a7de846e3b81eecc13cbe0b67a6594f9e23c9e97e1b94a0011937c90b6e8bfac2d50e093b28c26ee35d5932b3fd802936cf6d4cd0a9f9ec55896a766eaeb7a1ff09a358c29b3a235675be2106ccb3b2159827b8165c412e7bf97dbfbc0c35b2bd075a18673b6a587d0539c402", "6a6352ac5353", 0, -82554638, "e264cbc7af2aeed77741e52925b9583406bbd280b48b8f37c794833449792d02"], - ["6444e0ba01f122dcebc01a378548f5ff3612feb286831f5b7df7ed5989577b6fcafcab8933030000000753516553ac5265df5af14901fb1983050000000005536565635100000000", "6565516a6a0065656a", 0, 1013967395, "f708753ba3ff589f03bde341fdc47a34a1463d8bb3bbd24a7b4d752ac860f06b"], - ["f83342dd0111eb06331f754c74c48c9a5b3de873fc514c14e18b2926b19203b2978111816d0200000000c7d35b3203b95729040000000004656aac51d924890400000000003ccd7b0200000000026a53feb8ef2a", "52", 0, 1860359320, "c4ec322d92b3198201cbb43e7e1e142d2528b3fa8bdb5301a3d77210de22f906"], - ["fd42002604dda956fef1d0af0229229dcad217d84cf180dd18fb1dc0cc1c5cf6104f03eb2f030000000865005363636365659cf191bd8c0ac6d1f5901cee8b2dff9403ff39c5c8ea238e60be80326ca8e7a44d5a41da0100000001ab159937cd2cbc8b5fd7b627e0d4377e7e32d36c9298ff452ff15570bd40fc7f66c8dc1d0c000000000751abab6353ab63ffffffff9dbe63265c9c65e23b10e88178c2c9dfc5ad967a6d3b83a5474f910589d305df01000000025363b03fce610325090e020000000000d2e6e6000000000003656351c215ad02000000000852656a6300ab536a118e2ca402bc0f050200000000000000000000000080a07f3b988af3e367374ea12f68ae62b23da30f73798892eaf7c129da41a091bb0cc03c03853a42accdc206629e5ba63c66f6f045d3357575352e1d23fe4728fbd0b8def631c375bc1048301b3c407e5c4d4d94a0797b9ab2a9d890298063220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030aa7371ffa104f819fd501a5d3825ab39614d5bcec450c91c7d27992266d1dd48e60f2b5bce1c6199fc293bcc337f270d7f057d5d0317900cb85136ed241cabd181be70b7da56f944ecc4a779c8913d01cd80db3fd9167799119a5af10f02671aed549473f50bb09eef56efa5e32b8c42d94e066360d00f750dca491b657673022ba16dabb677e78efaabf3424b6489a5cde91226a6b82a3586c5976a32559737022a338ae7b7959ab10bc410ecd8bc13e65b8fcd28ab853bcdbbbad024ff34e8b30a047214eae7ce2e3362cfcb98f6f4a4ccd3d826957f44aab43163ff04761817850a684f42a97a19702622150572eded3468dd0a64b8bd06859794008b20ae17910210ed44e0b1e990b9b9afbb1a02a3064a28d4743b740579e96278d57a3a5bb2a8021378c6892ea292d6576c489e8084deb603cb8d70be5047c2142504f4ef230e5d0223a6e90dee2f051d4432f8332a52eccc8bf12e180e3dd29e4ae20a31165986df0300b58a571d445ad5268969857b03a222867470312fbfb3f78bec03b0fc7ba68d020fe482de6396bb2b63db9dadfa419b26d1acdb0d5079ff6996da0c512d3545e32711c4906b5dfda13fd10dc91fe6bf4434bf555e01b37761ebb11ef52cb644622ad33ab49adfee748542aa8d6e34a9c14d43f7526e0a734b1bc987a5c7b1192c661150a7cb48f47092f11396065e8e857f2e53f877d55ef7ba6ae97f91aac3802e2afac32b476e20935a0ee2e73f4413c34be60b3aac231a4e692931a2c1dfaf3c96de1284842a0bb418fa79c8d5721212983a072f942e3a8e4aa49246c5ecdfee7832f508a8cd3fefb3e529a9db9e73d8fcddeeef9cf773462fd6613de196e6e2b4f61b98ee08b52b59a54bf448ac9f4042afd2194dfbfcbe462786e852c2f411c32a7e4ad13454e273d28f83994886a48965a1750cf5fef3c5dc2565dcf2f04aee67451b2c9552ffb446853d1764269b3769646acd475bd17b79b81df9632a79eaabc1c299b1711b4aa0e9f8054b28fbd9cd63a1befe5604a0351c79abb0cfb3af58d0e5f84d08c0af7aed45e2b7bf22fdb82c98f381510be4476119306e8f6bd7493c25dbfc8adb7ea7cc7f5b89620c72548ceb2d58dfcf4b4001b5b50d8dfa777e3d055da1ed323dfb41bcaa7a9c1af1ff38f3958954cbb87b60f7c2a4834f9aebb9f2353fad7ba21b2c451b53e1536237a07348cce6c78331e66741cfdae40bf101825d340730de698516cbdced78dfb45cde15b89d3da6ccace0393e517c7bcfff802fad1ac588bc402aaf02e6184f31480dec42e70fdac455becf014c365418b33f2c776c4b88681fb16e167889b61ca3256b710b2acb864113cc8a0fc0af73cec944b6d5a01562e1cd3a59c421d8054b5209aaedab7287a4ea2b233e83cfb71014a6d8e8345bf8b9b3fb355eb3a4a2ae0bd8e350d0f28b79c96e9c3f4f688208ff724a221d7137328658a3d398d9ef2e591eddeed28eaf2c80afa59ce12a106780d3b40d0e534481e03c1d49575b2b29c5b3c9424cb9f9655925cbaa8739417e1fec647bb279684566937348e1a91d0dd6b15884018dd2108dd1e2cb4734536e56c86ab90ef79cbc7a7930028a027f5a43b08f00767bf8e5bf96ded88d30613099f7a6b8039f8b8837affc64b878f302d2e01e7bc3edadc04b3395855d50402c10f73a04db2232daa2b04b770cdaab138c1999ad4ba4cb56429f1c4c81b5d65328b463832c345a5c0c49f3ab8bd4544de21505fc1f4f4cb368b4cb0e805766441264af46d2e45378fab422efc916be317009d75a87735638c164ade7714b51812006801d8f4e8e06a6eaa7d38e8429136beb570cfd91586b7cd5c69ee9ee6edec9a76144da653d4729e32d28c38071aaad62ebfea88be295dbcd77b9d844b9f8b6a2bf82aa1f3479d5ceb468f2d9a399311453c29d397649dfc9f7627bbb0c6cef7bee3c20dbd4ba3fed36805da5f0424d8bb908c4e31f5af93cbaf20860a3d1eed4d0635261eb88c6cf1b6e5940b0e29f122893f7658da82c1e989d29430e22b4f306bf88b00723aa18dd7999bfab94d307c7f0dbf5427acf46ae14fb20721c7e8313a86083fd5880dc239a5055ea7d95f82b4a252c7c297e4f7fd56f29af5a209c0e28f9546299834cda791c0152ad6ad2178daa21d0ad10f14603646f26b814f32ebbd8bc8df12310dbc7a99d156ddb15edb60cdf9f1d8bd6769a129d9822e99b37e643889fbd32adaba74cc7010726024c97e8545303dba084143d27bcd600f216ac03bd2cf327830f4ec423cb942e00000000000000000000000000947c5ee9041afb5cb791e3df2921b4e7cf4ac0a0a849d40f2ddf7d0cb0fae9be0ae2dfe457c5c98e982aa301ae047d93e1127e2359dfd608cc9aa53dbf658bfa1e948adba4cccd02873363889f0093c896ccbbe4262d84dc513b4221632d141d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a95ef668963b501414c00fee6c900df027ee6c72e8680fc4d5d0d50754d1438d39ea515f07eecc31f36f815507161df435dc8d7dc52438ac1b099c27a99a4565c3b63798f1d590fbc8aff70184607950607254ab38b0515f256bd1e3993fec3abef4edc60aef2f7d2ba777864406e6b46a9c328798bfa3a044dcb6f291aefc0301c616d2493b9b028b6b6eccba59fd313cf25f6463b68dd34432f8ce0d4cca29030d12c56ab92c8386114b3936fd87eeacb30f078a4edc303a26a8b8cdee6056400a013471c9f9ceb83bb91d1b6cdbaf4261330dcf8f2ccfffb6de9fee16018662df086e2c6651c44700ad1f6c8458cca448ec7ed431d194d47200d604a0fb06feb9030dda8d7aa81d6cfd1e08d9724c71b0aed4988552d4ffab4749ebf1972fbce259022a4820e678f9d34ba54b0bd3d583295286c8fb7d76ec7eb85669375085d25c8803225bbae7724ddd6cd9343f016bedf0254e1694e1c4278cb577d5beba2db9a432030961bb367a0edaacc01090d34acfb468828538c20910d6b20dfb45196bc1fe990216eae1c2164a44b05a536703c3d8bee97556163df40f95e1dd6a42abb8089a10acdfc64b629f5a0812b9bac61ef70db4a1d14081e4ec2e332e620ac0fc3a0a54ca4d290ffd71bbf5125392ae16fb0f94f4f09a9d88d0432ef98cc528c77c77ce100007afd314882a0b8de95e135141c887e9471c97acc98bd7b44ed4aa2dda18c2df75ed751f4c5f51dec7286f8e39d009746559d570a9674f6c21794cc04140bdb37fee30d77a6eace1938fc0947666fbf84c02117b010df99f0e61296b4ed2ec86d6c81e38fdffbb97115e399fb366ca68b4b2f719e5e96c6f60933a5bf6aff9f5447780ce5a14d471ab62d7750108ed5403bdc499bb6537c31a4531f10bfa1af197be3fde59fe1e924cd376c512f8643c840c805f62e1857946d8097dc831a96e8adb40c8db8f54e1a03757bd051e074b1f43ee703bc5a2978a2050d7fc6f78abe240cb04d6f5220cd7bab6778abe8d606c6bdd46556dbb71166f43bd3a81bf4e2865abf8f4cad102f56c20b2248d1fbfa0c47fe935c6956101a6d523cbc0e389a715fb2463e9cbc1cc6936cf5f41815c8809d76eb3cd298b7491f542860eda711996c4bc0d1720c15f6e653abb4ee94ed4c9fd4166ff4c5a9b08e343421b2982183510cd242befb546c807e6aae93423aef3484c82be28bbfea47ed2fc7b32f9cc8e61f359c6b5015e74437dac1b7c011de7508a62e81a3c24fbfdc4f65911771c61c54f5c27f243f4d700cee016d8ca1aab22b9db1fab29eefa6025e6342725e2ba94aa2e40d8bc84d9db974c9b2ac4f314ed554c1d612b46bde4f85a81bb104232c60730e8f3646e70b29131d155500b74585b978fdc9c9ae1b951bbfd0655104a6db230bd4a85259279098b435d4c91777cd748e31504bdda69f38f0ada1620f2f10322e704d94dd33fd61101e80e9c0a137e95ad5d5552cce521001978a85cf2c0f781a476ef8a311aa54484099b34e47a37f62018fd41fc6f5b46c1b7a479c12e86ea440ec1424401db7442e0c98fba7baa5059b98d9b7dcab2dc84944d0e719ccecb1e2d5e1d61598755446de261ca3909b2145c7fc09d51a0b8c8603c3d828d19d5e78ca3e9a5127dfc0d94f06a5f2ddeb52a7e25798bd6d89c78f11e1caa3a5df8a27757a5d26a4ae6073b041cd6c9db3a7e094bdd6302310208650000712bf1dac3688c8656e336195e16e17f7b51f4a729e8e0b654416a3273dd4e1c6806b031cf77e2acf374a0e04ad7941146dc409e02839a5cff26e1a29863e27c7a55526aa16cc6893866a7d4642baec1c1d3aefba0405e831523317c2bf76f9d98712eba715159e0fc0a8768a46f1fc9caaef1184f3d512762ee120522593276f0fa062461bc41079e58b6261cfab21e766727b8075b3dea8dcace79dc3ef3676e3322691c9784024278b548bf5aa82b67146ba9cef42048ea92f4964c8f463e2780df53eec5e74cce4c72e60e6a137b37dbc49a7da493e3bc02e689b4cf3f5ebb1eb5839b0f33870ed7c94724dda5dced0e866f491850325b8ea84a7d7a0780fb2493619b5e6116c917896d5af87f0236dde936011b85541d1d107595f93ef8c1946c587323b7f985c09f2dba0f4f0ed0cc58dd9b8e50972134a1a749fe6f65d902092860d916ca0c2e6026ea3658fbef095529186a5b471f0c4a78e8b0c24705d8b0ff1965dd33ad9e0db7fb9dc45930311f29726f6aaf1b223200a6009aae084524f1cd7353badac0c15c43ea57c966acfaa440ca710f4d45207a318b9bf734425227f437652ae3733c07aab849257afd82fcaf3a50f90cec9c86f7f64ecdb9df7e95e05a1bd9faba4f4ccff3dd3cc628cad4ee07ac7a547e0e5885ab51c131d76b6bc9c5d6216b7ada9be82402", "63", 3, 1199084511, "edf9af713d143d096a702b08d9832b287f183fb4a2d90d014d60eba7f1474aa1"], - ["6463ce6e02e9d996b8fac84aea4a44af3c64ca46a2c4c5f4f05836af09380f46236abf0d2003000000026300ffffffff0849e30ed29afff540a7f504e4bf0e83cdcc32fde550d05474dea58d474d046900000000000d48dcc9042378300200000000015321a2f800000000000365ac63d7eb380500000000065251ab5100514258120000000000056a006a5151000000000300000000000000002c8e3901000000006b17a6f8eb67175d7e28215fdfad7946e921c6ee3779d67ed30934cb318d229010808385b0f7fd503371b9b7e4f526e30ac7d621c6034e5a62cda83bf8e2a2fa4adfcb593346bd72a90a48998e4b5a3d5c4b85f9dbd3578d53ca2a16d6e3a84400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000862994269f9c33efd088e6f52f6c2fbd6f304ebec24622cb389031e2f443d2ecceb1a1ccecf10bd83a9e5bb04fa608cfa0b1f2c9ad8c337f0ac5fa2498be75ebea203bdf586ad13804a9324794a0842a2d1b7022fa30d741c4b27864f7a384a531f4245a6ea0d8331a2417de612d42c155bebc6b6f4c3fee28b835cff61cfd11032494da34cf098fc0ac4945d711e0a12c16c81cb78882a7f5ffedfd0e68fd945b020d90a0f6cd365343bbab6359c7c9b170029743d84418881a0ef6336f4b49768a0a243d6c0058d6603d9f5cadf6fd348a10b5e6afd4b0265209d4f2a8f917a1ee81137c30f8943b83e43ecb04484e690222c2e8fde4f14d67ee1e6b1cd0eabc49b5032fdbd1c440a12b59b88fc9b3bc1448a6bc36aa090eb2c45d89b7040e9f94f82203279556cf4a800aa2e70a2a531feb52f6d8700093eb58130cb01d1ccad73ab277032362c9143938888833621e23f03fd3e691ccbaa95e899ee41ed0b6c34344d377020132625a577d446102fe06b7466a451cff3a86ca890b7d4fdf07e56c990f2429022c4947b4a9a32fb8ab88f2340a3d7d55b3ede79966c6ce40ecbba2b05910443d7f8a09b075ee1f4ec351b55090bd93018e5238fcb6d787db62ef167eb2f01e5ae3d68ab66568b1e929558c05a5449694cf083ffa59c52d57dc83349ac33756689b6f65cda5ab9f5fdc3b0221ddda6cf42e95f8a4abc0998f13bbe8de74f74cd08d4e57fad1d65b3ab9f719add259945d4c3be7162796db05f4f7b086a393f06778a65b8e2ef5cc7c945419cbd6013e16910f4c856bb97eeef3bf1fc18dbd36183d8b321305cee17270cd068962a4e22ef81487dfc22e87d0653bca3c2a0ef1d6f0db9d008a9fcfac0e4a062e2db95cca0cfa49fcb58dbfcf766c4719079d69792d7e5ea4580de13328fa0482759659046891b873ab469df34023079ba5b827382100736b8de5555ea9cd556ca8d2ebca48a45d6d3244e47616849d39cecdfe292fc4aacd2165ba3f62a3dd3d29adf251fa6f41195734d3fc7e76575d2e26de2a1084fde7d9a20a40891b647342ada9bad2749901850e5e224be4bc55662f407df90eabae544e7e7fca3731164426376f2c06a8a966dba8b668c5d01e6759da1d1dbc159cbf02b2a94db94b30eead2c32ec7c4f75756747f69d265dd86c743e9680f987970900c97fdb2001ea0dca2ae10b3b19c546144d3de8cd64dafe286adb7c4ce4d44259bbb100b09b2a223456d935f00b0f2beb2a356233078c5e28eb601907bbde3f22bd17dd58eb434bc7b6a2de0992d2e11a47ab803fd65f99f2b7c171c1a3f1c84b37af921ed9267d92f4242f8442aaff0909379b5287077c9bc91f214ab9c7fd7f4fa4e415a3a08253fa409559c46eaf09b7fd1a069e3e6c3f07c65a00a2d539c7f435ab1e94a994ff6829c6bba1e30fc863629faaab608a6d8b7587cf76ede132fc19221dc3487381e5086cb36467e75989b7c99f59b546f20c62ab278801f0fcfc6bbf1f9431bdbbdfc768c37703d7e654d4d114fd661a6864e943f78593b558d32ba543704ad0636203a37514da0a01076febdc9615e0c3709cd8b7de9a10cdfc5a455f66644aee1e999de094a578f037e063c2c528b23ecc8b7d9f6a81e46f1d0822f077509228ca4cf42729d404f123f194ac7180834c866eae38076599ae0c14563a32d70687bec65089f652384cc101e5ae10ff932b60c0d238034bcc0dbda4e4814f001328f6e8fa7cec0159b21870cbb6d74a07b86a00262621910ca5fa23b16edf201a15658b74dc7377aba3df38460b426078177c805f1fce884c805599b45f3c9d29e5f57f05a0db29dad53f99d513f578113097297b10cbc9a2a66d3b0cee80d94e7157629fbd319481c90e0a69833dd211d6cb47426cfd729e9f1095bf469082ff910a873e7d0f3adbb6ea875823bd5dc5c7dc1d23706f14f26bae2f332e46449c449997b04852d1b6b83c5e7794fe51ed4ef066bd8d344b507587a9d25c91eaaf5b098983c93ada9c5c3055d894d119750c7dff25ff4fc4aa33c85f4cdf9c79be3f747228a19ef13d257ab4404e44be2ee8a8fcc095951aa0b584ed600749d7a6c5efd96b4d24b7767308c41c0e9d1751ec04fc5b28830aec646d0b982c5c225e8fe705d1d5c66976f17f25adcb1e31c9cd0985eb4bc16d7e6ae19d73aeb908f803b46d7de054771d24264345306202b1e2f6b72202de734bc843db81b6d98fddfe46ed0a116e653dda5ff988b1d7796658c635ede48e223733c55cd07d7c666bb20617bcd70000000000000000c1d8060400000000b2c6c385a7ac1b3e811877fdf9b7445bacba0b0762f26b60861753cbb428d6db58ef529d1168f8542b89959da828591044213a16a21dab68fea0e2f6fb0fd76b4d05a6b3fbf1d593864441377b377aaad7263b03adb4504363e0a50f74981a1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b26a1e2b09c03a6fcbf9754ba07e909a648c34fb78938740f006e96e2e08065ceaf7409083dbb5b6993dc2e1a7af47258bf826a23599002b4eca2557412edf7f719cea45964e6e23a7b5effe12d014795012846c599b19fb7f6608314e2e16c5b4d7ac7cce33c9785957f80e0eb3cb8460599351eee124d69f6a23816f46c7630225d325d89c2cf3ca718b5e4f48235f279c02041f4deb9d1e845b5798a657549702087cf0121e8915a2840434f8ce1ce44381d186d2437976bac45629a7d8b326ff0a2f69386ef4ce4c9d668af30f99a6b123faf0be5bb554e81dcfd3bf203a06710823f8d0646554132d866836b2a893f974db7ab00b78a35194796b2d0558c8ef7f021817ef778393dcc3be8d4d47265995b7ada64a95073eb659b657f50c6a86b01303083f1767ca1462acadccf1d1f58ee24efca5c6e2630fc47fc1ee92d76d4c99340320aed09739bb70affed825ee5dd07698961ccc961791e0dd7b50d2d3bc9ad38c022fc04201bc7df3309e87b8ed8f4e90b5553e791b8fa3c9ab49429b201d498e5702301ec466e455334d826c7edfc4db7ab8c33ab00ed9f8c8d7106db78275e0b683b81e176578da6d6a632256cb047081d00c4b35c3dffd62f044a58d91d8edbabed9fc263c4727b6ff49c21263165fe7e27e0ba42bfda1c0af4d91d2969bb01fa1cd72ea5dc37fc0c55fb632a8ba893ccba9e4062fca606c0b910934f1da70a24f0ffeb9e540eee2000608bac086b8372304e663bc924d4ec1f599b72a1307458c78ef85c0e14e69d0371110bc6a1093fbce3f8b166993058b9f2d50f384f4a13f2318f59e0c341a3ff03905b8cdf694193f792ec941e6e22e0b737e8fe08d4335bfbe5a3f4c550a3aa3a8acb78c54c17728670490b1ea7a72faa7a6168393268aaad198dabf3707db3fdb5a1e2f32886a1afae666b5a7faa67ffcb862b6f64141b384dcda7e4e778c89aebab97c849ec5f04eb6e59cae1b5ed37b803310363f3f50e0b40d4e7a94ce54c95da0fbb402975cf7a534cc36cf2c94c7a4eae2f932bfe856e036b4a6900ce55b9ae048a0b7809c7bedf5c9df474b83b2193d752600dee3877697be154a29d2a52ab5bc16595c942c59fca757b88fb0c797591048ea0beec29b5bbe23885261a0556e1c5301a32dc5bacbc6cdc7db0b6eedba4ec2ab862ae91a8d2655d99f484e790cdd3ddba55f5f41f049c0bf797ed58732d999b68f26ba52d2d3e1be7e8667506c936db25b90a9cbfc260e0120bb6266f7d465dc7648b3ad0caffa7cddb83cfc6b082a75b1284c9ad646e80a21c572cfbd98a5ed60e93736c29fac0a8b6d99fb150b2f1d0785fec0f83282b38426d90b6903172d2441e01f41127aae4610083e4c923ded35f51342252acaef99caf8f586c9861f62e9105416bd0f2747b4d1411130b8eeaa5a33ad4440667fbf0886d26b5e56aff9e04ecef7ba37d0af283eba511caaab56cf2180def5f4f12796dd348dd5f4d62dd2a685238d4712fa04efce7c8afd79b4b48d83e4828713142f83edc7f8bbd6f98ba6c14a8a9edf2db27edf99f807276cb54dc614b90f93ae4783b8c346ff17e53dff8cbd648b4b6e922b55ad73e0618cd3bbf9329db18896461baecc459452cd521fb797faf45b3f0f697373b0c6a64e1a97b4c70bed99713491edcbedc85b37e7bfeb236c30438ff49e3cd1871ef462ea11e389913c9ba4fd9f5c8e2b9299657cfeaee068ad32d83adbcec71724d99d8834c9ad47db84d595c304de25f1223233519c184ebf92f3286bb16e8b13d55946a84789643d4c456e478f5f19b241b6168c9b028a5e06c65337319d27c3771b88bd2de323d1966b176e832cea71c74c566f3cb22b5c7a4a511c0f31f4592633db52fb0e2ee65b51c43903d834c4ea7497273bce80a3861e561162a6b43787305b45d257bc9df91d0f1dad4b3ca42248424d081f76a9d3e543ccfa27c201b58242a4db6bf0720fdd5a88c9dad9d5bb491abdb1c2fdcffd2363188f29ecee10b29e96523331eb2cc330f9f70b6877ca8175995daf96396e74f7582905f036c0f10d2ab3a2bd9d5a777725aaeb5605834f9b7db7101dc290619573ac4d9c171491bc5dc791bf42ec9afd3bea0e5287124b87da542b26dc1a3c286b41dbc72a72e48197b2629da1878db13059c67cf9369704a945d740598fc5cad0ba3bd853ee03ad76c50d5ddee59b03b71ca02aa7119b37524db7c76732be5f76ce87984c91312e6d481e84ad64017c7764d3b7e68c10b2a67cd7b67df383bc3f64c13e59c10f76cb0000000000000000a4328a02000000001fe13c5c19f8629bc40bd568d81c38edc54cf042963c76f2259c31badc69a83c1ca147bf62c13d8bf896cd744184c5a0008f9502b8a07b23212aa694fe237894b6365c94673bd7c91cde5d3802a7a585c261efba18e2940388d9a95f4e09395e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f15c05bac924950a36bdbcf6aaee63837231da5896622b1d342867685bedb20af666cb4e4fe650b1691b2de893955bb998eeab33e004b756e143116deac6db3b9fe6e3a31c521e74535c400d15419c1644a12fa671b1df2f0c3c010bbb0d3f52497980372447fdad3311db2e06eca61cd7169b0f7a38ce13e4d8fc00a90efbf031cc360246c6525962ccf039ab93a45a1c54316056e090efe6cb27817806fdc5b032bb6bf02fc786f7264c994948f095aa63da37768562f6b7c4edc245bad98bc960a19b792f0e2715a2b6ff9c5d145967deb3b3ffd6c62a848465bf132df505bb991198e6dc0b27bb71d7a3ff9623f662e90264b77504b05e25cd3d79098b90c9a90032494346bf833eeb0e78cbe131e8b1fbdae381eb76862c4e9cd48ce1c4282f5ed031dacf0958eb5524d2a7b57e5b64de98bbbe3be7425b166eb6d8b3d9324d7152403253e9d8ec80855938ca33dcb17a189d9d44c50399e5a8cc1e6ca2ec4f603f44f03073d0e4e1e9c665dc4304265bc61ef7f2b2e500e43edfbcb1ca877050d920a4f03161f2c70b9488951b624ec4d6c3b656f04d95627503e7d23858bb022771a6597bdb0663f62eb7c051b396293ab06f43689560a86d4c4b87697796436feb962ff4864023d2436a9069865fb66f79dbc2a0a5cd3ee03077fd63eeeee01d1ea7af61535b2ed322a6368f654a9bb41357397c429bb3d3b9444cd34b2d3c2a250c07ac19cc01dee5fbb76b28d871f0d6da2b6d574264f25a323cc00611c10f2e90301e92f33ac2a4d4bcc28ee8776fcff992e02e6e92f0edb27e7defa69ca8462f29af4a633fb767c3d59b53053ac743f24ab5deb3162776df65598201cc7920c8de2759bd40e80e6e579c67015fd29bede45c5501405c3d935e311eb8fb7841f7dd06bae4c89582522a3628d071769f7977686dca0b63c78700922e0e0c092d92e2dc56d7420528fe38eee4b663fa03f80d2eedb2537098d1ab9a57c1bbf8bdc8e2a10b5d1865b7a443d189f8aaa9f74a8d6fef16bb277c1c8cd063a272b509a6fc76e3c48cf68adbde03bfec75900cb3db44bc9dbd6e620c8605e3e0046b14e767066739b29f37d6b644b0345b2733e2960874ef8ce615d76cec178426960ffcd194303f4071023616a4ae45cc97033dacd23c87a8c12ee1b897e57f2add27e73448c3c6d4e571b5e89d2317beba1d1c9c5ee1ccd44ce0afb6c7915654d86048144173e40253d82fb6455c482bb6e20264c8496afb0ff7055b7bfd5e945148146553b73c640274b01f5c8bae40894c005935de9a661c9b3be353f2be49eeefcc76dd2916d0ece479fb7fe93fcb287b0b213d015a9d3673612335a4f241bdf1fa2ba8034b91b838fe5533747138bfc53e359f98ac51edf7145bce9ce50dd8ae3edd205579d55ddced275643819c0edb5a3ba939b186f790731835070d11b1fe61c368d0613b2899f8dc1db320a62739471841f9bd7ed5af5238fa7241e30f4cbcac2fb916fb57c3c5d696f6a92df0b8653146e43510d92495f9bb8a705510a6b865cc629cdb3596b90f8246ec77e8fb81bab6b5b1a7ecc376d3cfed3bf2f603543c72c874485a41d8e4b046448daf3182256f24e82a3636a0c5dae41a346808e7426d5365ee171e4511a3470e6bd7b66ba2c0c38e20bd7d17614dd336413fc427f3defa47198afcde98891376d46c44453b3682f357196ac80d93ef02e46f844a312ba05094e32b405fad857b3d35e5b1a75673cd55d40683b0382310fb067a46bd0bf5a5f5e4a8bdef26579a99ba9719fd73a362c7e3ce3397b4c2b06119330cd05e65154491d33445d8f44652bd14d643a42a924cc0366777094f29ee2c40737d760d323b9f75d391712fb71d1e4637be0c59841086d0b131f9275482424398638a71ed7d8b2a0e0fdf596a50045a507a1d56ddf909a73b27bdf4b7ded57c898e4e0667a85fb926b0b87eda2d5ae260f4d09bc2bb0c15b3237327a1f1e15da97f4af0529a102f995b7abdca3f5d1d8ff64b673c7ebc6280a7ee034b47f105c934afa52d540bd9463a65e824b3e6962f956f5c0091b9af9c054d1ff395569f2f3958ef6639cb716d247cf97f73bd74fd96abfb8f85b7197104be081c5455bb94839e990a829097e96ec95e315b24f7a915f338c974c958572f1b146a7c16322322b5ef1780cd8bf8a5bc5bdb155fa3a5bfaf3b540dc18f90e39d94c088aa0483deae8f247f10416dcb495d69e2e4ef476db4adcee99e67f9072d2eb168191942cb00f7f26a8ac8854ecddee2298cf7c4d4f468baf484246f4dcfbbd885b865b1911017a07498dda21914a3b4ff49cbfb56434d28216d7b53872619763aa6b7e600afea67850d729c759f11a828f54bb3d5aa3c9d4b452dd96b94fca6843e5f2b027922252d218cebca5ddf50adf3e82f1be1b05", "ac5151", 1, -1726989944, "080dc8a9eb240b13bbcb4b6517ca75db04b4b125acb09fe1f6b6021789f392d9"], - ["542e0b5601e10e4d571ca155db82510b56bef90f9218470115a710a3bf9b737f851983ccc20200000002ac009b3f3313027eab0d000000000001ac8905ca0300000000046a5151510000000000", "", 0, -290389119, "eb65ee9dc7f73e05bcd9724c7054046c65c7690436853e784d9ea8cb7f86f15f"], - ["7ef28558030f4816a8cf2ce28776246dcb4d2841f8ebd15e95a859655f34bc76306d14349200000000066a535200536578485d14488dd71c97cbde9f60f923d9ca7600b5f7dc361c37b0434e32593d6da4a1b39b030000000452656300dcea2a44894cacaee08bb793b9f85259b682caed4d3bcd084d7ded66bd17bc090a5b815503000000076a526a6365006affffffff03e8d8b1000000000001650791fb040000000006acac636563006ea5bf04000000000351ab520000000002bec5db0500000000000000000000000073081868e00ec06098788390e1698139c275da042cca454de1b4d0e2f3b4ebbdab8883416162dbaa50a838127dc99604a9e2718844bdbe8e9f76e763b273ab58d20a3c6dc8452d5af014cb26741eeda65c652f05a1ed3d91c378133a2506de41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009192ed1edfcc855b669938cf7d43d81e3a3b700a3b96c44b57040f6b0d044f23f50ae1ce6fd97b0be29ed545ad9814430dbca5ce23b63143453ea99b99cd90f9e9e980a513d559ddc36c699cb1315df185ae810359473bf6aad1d1a162a4309862eeca9c65d5180ab790dd18e3dc9c02b48b3149bf972e96b007b2d331077dd00228cfae77f5844603c0082d7589def8be11293514b481f561b82491939c5befd10318bb215bfd3aeb8d5b6e687f6cdcbf88c9c53b87954f404e8762aeb4a2ef87480a28886b43fcdeb8505fef386ac02d07c2da9ba04180f5b3532f494dc9ad78aa3c2831b03ce4b2afb3070004a012cad889547853e4eb5f5a98ae24b1d714d54d43021d10c3a71ce98453323f0d79775a96368fdb11827fbd9e697c5946176a7f847c0317731cbf069632814f785b6366b357ea45c54493e3b2aeca197d36a326ac42fd022cbb4c49983ee9b9729efa7879c0ebf380b9da12a7afa70e53bc28e95b0a247903213d4281eae1c87ef489a842452567acb09dcbea7ba46d054d134387ba3be6900206adf24fcea71bb8505244d87a65a6b7202d0c28b8a6c0f5c1f2f5e41303a7850851266cf2e6caea457f4a58879076c7fe28f36e4da7c2e65cd6b7a5056fef9ce11df95828836bc8460c46dcd8a3ef3d4f0138b2502323f466b2a2323a8d1cbae9535353264fca9e34e9ee1f8a47ddcb951eb9f378c1c2033dac4f40bcfd53c08e711a0ee39ef57957167e49b83449b95babaa88b0cf64ce8d9b843aa652bf2260cdc6550d9fb93e5eaeb902a6c05f962cd19741d822f204ddd1837a4f7d01a7afaede06c9251f36cc5bdcc00e4e2c00379f89c1ed01e1f3a93e4498706d1eb99ee5c9e515d7b9f8bc4d6fedc65b8e2ffda20a86dfb8dbdfa8b1cf7803950d1fd7209c04822aa4df65822bd8b1a66d7b14830922a76ba9f957b3032d3eae14bcf3995598a48be5a315bb099eac11a34c7e0a451224591cdb8536b778ed61ed81f2933b89e8aeb54fadd0aae255511f83f2102dc0dac5eacde259f38ec7545d0af566a8441b0074f7800903ab678abe4e7819f4da413d9c5c660dcac7e4cc86f40e21ca1513def9108cc7b60a82ede9624f84b3b0bb07c4f8fd19f777cecaef7ca0941ff97f5e443f02c906cd1eafd6353426e0cff3f5925ad9e2ed54825242756660f1acf26cb05c800d9eefb9113ac5d72b6e12a98c676f227345caf33ece14b7ee682d5e92e0c5b73df78a619d8fee6da4e3bb2a96b6d81c260429ac7f56fa76c833fbc3af4473858219030d479eb84b0840f4a790b1988258430604425e1f6b12e3532b81fd7800a25f00a2941e349649c1434c16276bd57fc86a6ed7ea7c1f1d678bbebc07ffce92d9280e546a12d5f9016600a641143efbb30cd8607c2f8c442e8353866b21ad19f3356f4448d0b103bc1bf39f8826aa4d3e61615afafd0e2ae0ad390919be30315807525746e31b3f0a1bbe45bca1b84ea07179ad0fbe217a1b99adee144d7291bcde4971952a4870fa13a485817ca7f1ce14606d91ffbae20b71befbda1fc2ef313e056595c0b073c345a7b5e65cca1776882c3289db92c387576f82b448582fb686efeb9162eddf2b92e85381b91fb95ba99d11fd3ab0496dded7eea7a2e33adde399113f7ac3938b276af51559b5fe33cc9f4f17a166b3e3651a83cd811036e5310023bbd2fd96ab803ee615b510957926afd529556ed6623479daea580a852bef7f6d1ee220417895ad815aebcfea0a39ba6c3b8859857b60822610082e76dffe19e189718c4575662647eda8831b136429ad046be6f94f99b3c9763ab40b4a9876ddc44ea1daae923ae69bfb6dcd1b4e097301d60a16464368d9790b5a38c960911086a2343dfd3eaae0d61989c10bce24e992f1bcf595376a0fa0dc0699fd56511f7dff3b21c60678037346d57b3c936021fdc5b906420aec9fa9bbee98edd896a25b4f12615ff7e0a832ef74b5cdb822d01896c84010fcb99bc7c7ea8a420459254460c97793962f7883344b9b11d7377d91d5956c5cece3c6be38d44f8bf179dac1678f51bf1177fbc8d5d209980fe29381fef36b52f896cbcf0248a5690572a752bf3b4c6d3a612721278ec3a0c9c277c16287d531c73095c94ba3e5652fc01544ad04a223585485dbaf9ee018f588067f9bc15926dfbcf31dedbd353425f1f0f72717c3714e402602a6535957866463f50bcad84b10f916bb28999da557a2ffa6eb668eee2b0f8593c5ac612847e6821c71fa946768340e09c793b503a2f753af0fb7260000000000000000be90b30500000000e32e2a9783b710b8c1bfac22fafa21ead92229ebef219c6ea411655d4251bea8cd9fa786711b8d61713c88d7167a1e41ae24e4250285c7d46ac41da9ddefb12466bb1b1a2bf008b186f6492f0119e9fd1a4e4f380de456489dbf4f35c5579b950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b81023016e864b05a03819d04198b70bba6e2dd1dcfdacae24200034cf82613f66468c5a563b2b92b4e447e74614cefe3213a68d587d2ce3bf84beb4b68c291e9e02e75ad67fb38e7a0551c527e0be4e1ab9e6d0c2e798d8ba00a0409fe7534bb6c2e006a13cb7d62f9012b25bfe34344f54926617b226f0236cf21ef39093020611622cbc8162d19e2e674195e1619441494fbcf802ef01b49050c9c20e82060222b106751799db84268a7548bf640e44c5f47c23de92618cc6805658f7524f3d0a0f3fbd7387269c7309a7ebbec0a98f1f7dd99747d72339ef8b9d1f304942341408a901641b2fa58ece65ebd80c316839b1b8307908f4d00544f9c46884a2b95c02285bd2bf2a7a3b975f5b3b8d74a2903d285f2e8ca8982444d98dd0310a73e51e0315cdfd95c23960bc472e77f1a6b62c8a8a9ee5db3f368ca452c9f67c546323fb021cd7b937bb62be123176311f08ef5422fef56be596a3f935f5d7c71ce70a45680305853fe0da697f79956a51510ee985126d1479be99798194174fa6b6193909c7030629c1de6bdf2a1e71d5cc5385d3002e9aedb77777ac4f6fe087a14dc3e277c0236e764e3d137828adc248611348e271801167434c30b2a083dcc87c143e6de3d00b27f3aae418fa0fc70bf6dbdb0c617b9c278c46f92daa329b79aeca4a2a497ca29b644d51b1a8d552036e286ab80043710cb4ed91aff667718b50b2d2a1760b826931ba4a9c09b25af19d79e62a3befd96d4ca96f8531819fba4466d1b61b3e5eb0e9441792ff7d7db57b64eaa8eb77a73e8c5527b8c28483dffbe97c14d9cdb10a63e7218f43efce2fc8f10e5cf11628f87619ae55fe464716fdefb52d3f7d65369307dbae93cb37d571a80536a9fe07d4184d44c7167cb27fe9f40503ceb0a248959c0c760dc326dc8a18124de4993ae316d6730d2240f43aea503f9780622e1bef4bdad926226f8d8abf8e4b925083d5d9a9113c960a7ac880b2035be514f42d68be4a8c442da7d2573ca7f52b122b15596ffbd123f2b0136d0e172c260466db6b54e58d5c5dc8e720c9326408d0bdd3551ccd92e454c26110b335915189d826642a0fb872de4c05c882affb3954367526cc7c5f92c53bd6ae8779dccc92b42215b6fd2a75f3eb2b42f074dce9f015fd119657bb307d47c9d7156841127b59cda59a41b9aa0c7a021e692b630094e5d5781a73fd8702e9fab49616b79cec0a87d0c317fee94e43120f02379e912d2f6446eb764b38920550d0503a9f28df3f597f33b7ebb92d988f66ef222320408ca1d54fa098093984ba5e00f46bdd806012247bec3f7f7d61f23a0c98a3c728a34ae79e09fe9d712c45fddc61b9fc66ded86d3f64aa692516c87cf7cbd90c924d75ada478b8777fa8e8d60c5ec227fdd130a92f62f7e4322a6f48d1b41411736b9e807f8da0b64a85d28968739a88c234cba392a739976fca6117cade2782c330b3724938f43f9ab7416642527dc037d21456f937811acf9a934af77daa5fda782ca4a6a72e60cc7ade7dcd8de154658afbe9e0a706648c96b33f50577df1b8106d9bc8bfc13d2a3a8dcb750d592ba52415ccbc778c99bce559494e221ea14905a9b91143c146edf22e8c0693d932947d55d8e465ce2374ada079dc0955385bf7d4f293cddcd0fb10024b52626ea64d31b33b6372d76c55690d080f876ff1db0662645435a6d987bdecf39bde6584a90f0ea61f0ebc2a2bbb5c891a0b02fd760b01989996641841c0a1653885ea15e16a13eee741527050da93f242bb474397a0ded294a1baa74609bdf8f4c97790c0f3aec9f0ecf5719263e22dea22fe90008520cf165c27d782a776d31cfbecd486433ca9c3e7acf505e1e6efb158ab796df653f6827151117a002dfc6388d928c28f883d7739a7a007f32d73e7c9fca0de3125d2816556c426198c73458eb76b5a7433a48e89d6e5751192eb1be2d4cfbec85c4fa3ebdad2ef181690117d994cab9e220e18fe288c8aa713b2e0659bd9db0a33a0efa94255bdaa7d892888b211878cdcf6597dac02bfd9fcf7a474bdde6890bfbfa1a7926ae6ac487a1eaca7ea9a916d8380aa3b1ee770c9e459c73945731d0b3741db63ec170deae322cbe26c65bc2261854a7e860345d1a5d96767bf84f7d8b3d1b50dfabc87dd47448fe681f91b958725d8c2e7719233ff04362b9c2f13a31e1588f7fa46feaab93ccdd4dc765a105ad50e574c09dc52f657903100326e1372ee08a703db22d262286c9f7f22bed25fa56fe729fa54afb1f45656d3a6c254d92c427b74c9f7fe91c757d8b71be355f871456fb59c8fa5d424b8072a998d0678946318c510cfa08ccca387a51aff5be1e23516d208618e65dfa28b8a37c9c3aa40b611ce5ff0ada5aee50356af6bf65a38369e73005665485e1183f81005", "6a636a51515251", 2, -1238398950, "433b51e68779b2a9de9047eb2e4eff77a2c9390026b6c7cb6e2971403edea6dc"], - ["564e568902c4558bf19b5bcc39584a99e63ea792933b27db00751745ded3dd2325f0a77a69020000000165ffffffffc38e69e6195ce85311996eb0fbcfbe598c79bfd9571310315a8cfacd1c37e240020000000465526a6ac4745686014ad955000000000004535352aba1ebaa88", "ac526a", 1, 1983747537, "4ee8275452e77cfee2478e0eaca526877d5ee02c5fdb4ca47c0d893e76d3b41e"], - ["f09ce524010fb52565da3c21d4ef247b662da4ac4af9ada04dd9166a2da1db07cf6f79c0ce020000000365ac52ffffffff038dd9ca01000000000253ab3acd8d0400000000035352533cd43105000000000553ac006a526aa2df67030000000000000000b405a700000000002301dc8ec30f708b1dbc94533c333df59c7ee67de17554160ada87a7c81cc18b12bec116ed4ed40b3fdffa4328bd9a335a9c144192fdee8fc71c6c4c2205d5768cb03036c6d106f545e0d58fbc446e27e21e23e53f8b9cb86badeb3296ad3932000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002da3e3c1ccca7b4436555d780b11bcc1c2329a2415d266e6a5e76dd73ac7298620205976fee47ec88f57cc7376827467455872bad4f7fa98b05e731f4624d3fa031f8a4a5bd6f879af1418d83cc1cb0470cd9b4376cec24c9dcf76f5763f5e2f7308cf9d3056ad1bbadf4c10cdf03a3b57bda1cfb019aa57e1a6d27796c72067020cac9cae53a90a1c5337407f9de718ec62052df2c50faf224f3aa7ed081412c50311b6bac2512314f5a23705387f032923352ee99c4f2113cdc22068504fbebe1e0a18d97803177f3c6e1c737eec952f1491f21c139d6e14922ac6c3f5eef2b87f600bcc1abc2891fce5a45555e4528aead595024e214a11a3b96abee6e7f09c30ac03302a6d4c1ff0c4c441276c83a582e9a86692375849fdb8c22e7b5bacc9c53c960310ffc5c944ef78f21b3cb0bbf8d80a3aea9531add3debdc91cef4eebf25272f80227f0e03ac052d35bce293a75da7a6b9c62d31bb16e8704b41fe90017e045f911022a622bf2ff5a49742439078d6bf2d1e8754b0a1d21546b38d4a753012089415b0217babfbbcfc09dd1aa8019012818d675cada7cd321fc49c258a344b03ccafc9beadfc62b3b55f23b0f04d424b06c1c8c7ff97f727ae24ae869d132a1d81663c8a4132b6fdf01179ba59632e31b7d594d8d5d45ab0bdde2baaa4de035ea438029e0d0266e5c86a89f260ad05146b1463cfa53d42624fc76cb7e45a12a452cd9c591ca2b2ed8b670187664680cfb0a4b7407743f219f8301c6c1fe43ad654b61019bdfbda7b1cd6c39b65c759c2bab8a65f691904eb80f2607a493523dc1c34ffb2245b0245372e18ea4fd9da2ffb7dcd97f4ab4d278f4ecab3878cf118e078039ee517b3a6bc85e8fd88aa064b8da3733c56984d1255235856b368ed2fc44353ea60f389459fcb46e5eda3519a3f080d8d9b7c1af1e643d9e53065744f4fe53553cc9fdf02c0c98023ad9a7d026d275dd780f9fca2bd4aa87b30f1013a103502eb26235816947f3b375f2d2dbc7ce0963f377fd6aa4ac937cb9d3ca64e0d7df6cad739081c7a14669ec1bb18eae9cabf6582385725e49b6d46c06e347f84db195e7227b5617cdacca540eeca6d17206311b0dbb6ab796aec09fa054ac51c49bfee56c5fd82f1858a144619b50c6604a521a1d5ff1392f3d6b017795f377f87fb1b579ddee9011f14f52c1868e8c0800ec141caa8389550d4525914f37d5b91e9c86e193ecb4754def1f36a53ca421da8eb22f78b38fd60300fa7ddabd0e89219ec40b77677304a4afc3d1c345669b6b4793a7a32a1ec8074c47fff97c659ca17b9dce7a65999d48a64030d07f5c6e28b09cc4275bd2612279f48fb41f0d9ff3d3b3c1f83203b5d40727633491e437df369cdd101b213b038b19a35ac51a4974e471129b207108d1e5e1987c80adecba5773d34be5e6a18c73dfcb5dcd9ff3248624d6399cc542141f0796c1881413771571665ecea78264848c1e6756fc899626f9d2a71121a751a7fe56e13bc0314e04050f36d90bef059fb943a13e252cfd1f81708db2e103ee48c5bec45fa06e3c90441cca303a8e808d9a1cbffbe0ff5429652eb01187bc0683c636a4a764e69e34c68d4724c4854d3b5e03f7f3f7e2e8e634397a26831a3664f9c7f5bfa9bb6df2c37b8868c2a680e060f272543937408525d09bef9344bde486e3287571ea69d8b0cca81d41605ed7a651bd9419abc9ccc27717616041ed76f186fe9b5f8c5b90c2b0064a8f9e88ff6f4b2adf82b9f519c0d49288bb0312e75dfa233ead8361fb7607d4c9b4d381342017dd6c1ace2cf8d13aa8561ecfb7458b640b84feab05680028ae5b12066d554885999aac901bbe222a72fec0c30218f041929685ec2463fa43d7c2919a806bd68de2afee88f8b1f7210c61ca07c6ac58e177503520e5ce0409e4c469a878884e5e84c16d91adefe9975c943fac86641572ffb13d160a80df4d9595b06060065c45fb6e05ddaf165f5f47454ed1f0a43b58528f6fcfb631284c2287fa0c296bb2104667c0748331dd90858d7ab609889e19a7a75b74b530b1450b4b362463a7843eda96f94b817be7bd7b3d73e39cca1b4a68d101dc1820395090105cc2ff56a4143b15d26cd78c3e9d9c3c130efc028b7fc8204567082d39e8fbb13504d636cd2c87470003174a8754da3359ccac2fdd7e0bd8abb9253b4d9f7c30d928806a6c465763173e700b40ef109008dbac2fdabd2972bf89c453dbdf90fa0c3e4fcec34818e2a80e9a5e3edc91702891be75741910c18ecfe9069e86000000000000000050709c030000000078a9601bc1b69420f26e20d0c7811f7656226f88f951d894cbce91952dc5dc2d1eaf2d7803591d1b1e5f6105dd20bdddbd13341425eb2d1ee017c58988978ce38f28b426efee129f1ce8839a924f595050e379aca932a185bdbc894ac178db2800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000596f022757748b241679b22ff7f2beceb578804171f7aa1010de0ba663701f9c3ab348d7b67629bf10cfad0ea2174f1c51a19e172e9e79b9f668854eb593d578aac1e86cc707aad6c1d244b577fb5868943bdded553fda72a8d42448757c21f05ebe7abf58a171450e563702f61ff6176d021dab6a24b49a7c11af15f99118e10328e2160c477434065079ef4aaabb293e216cdded92c8dd3c41da23a85ee8abb7032f584afb7d6a5dbd3729da7fdf64253a6e0093b116e50a9c41548b995a3dfe440b1d04e2981becd2797a79ef9cead7335933d135fa8ac6abb389ce5e3ecfcf78e122bee486c659e8714942a04d70f672ebe2f268d8db8f4868007e451fc674879903184186491d51488b04cbed0a3c4007efb9088b5ba29ee30b969b4ea2cf945c2e030291fb27c8542391f96d12a7ec2a2e8f6dcf014deaa4f09e37e28857a2bac0ac030b69e6cd449fabe7c6757d461f16f52a5e98c277f6bed82abc95f6066a38ff8803257238306ca51c0854af4f8a16d3c3405398d47b55f22be850c928623c40d418030777357dac57d1c285594af87043f732d465445176359e3c1ebc30584a0bb12f995fafde1fbddf341eb2a854fd07ca9d9398c546c610fae3b57b5eb2e6ceb9298ab6af14a6b58a828ac825bd81c7fa6ab09b9ac360e2496d481e84b0c1e63690ce66dd4e21e396b07f555d5b0e02dd1d849c84d460c0ec80b147b03278352e275756096a1e52808dbac3a77240b8259cb7861157e3263c6e8fe339d0894616b138d238593c75ee7d543019e21c6669548f6ddfb2511a523da46a3c81de91fe539a73293d80c0f146f2c30bb32bb4164da5cab5cd0c1e86b95adbb3666292a1647bc99fd0305b62255e00c484e3ee506f56d68ffdbe6800051b5454b813d6e53ad1949a8a55edefc5e0028cc2e823cc0afdf8456f3ec24f588d8c764bed023f081f5ccc5ba5e58ba9d60ca3ed97b9e4e3b20046f6cbcd766037a855ae94ccd0d809d8faeb272e36de845ce91f141bec99146d5240d3270aed4074c9d853fa07b0e67d86a9bdbe2979e79a379c3eeefc9777487aa47caaf92213361e7f5d39e9d43a17fcacdd8274840adef4cb74ca55d05446e1e85242ea8c9628abd059e28e96cbb32e12b1908430d4387f3508024f0eec57218c735c5428a4f2eca59f1f140816bd97fdd518c5df706aa8366dffe73d6f6d23ca93627fac8448028ed0cb5daa8e751cdf644e18cb8c6fe498ea67b5032bb22aa271055ae158b2c3449f3811e3ec597d73e9ba88149a02102b72a8e0f4e9025b8930c798ed3004687fa0967a402214b1804eb105faba46ff6d038b7d8b8d3464f8fd43460a62ca912fdfdfac787f595200094307dbd2927750fdd26fa88e2a17dedfc8ac690836a6243d4e90488e2f1531ebe00693337e4f9d079567563ae449872e6ab98920f28e67e6ecd371a25e3def9833d770e347e45b8ab616cb3ce398be53611abbdd7bb1b95da7da53c0b900b7ea6d2471d3051407f0c5121814fbcd4d6794ee08b3d9753681cb743be1fca9112e7d31a7bb140487ea705133dd66d5f8dda83b87cc8d5c57d640bb2fa563e57411628bba3e2614af0405cb67f6995963b3742ad268e4b45829101b6e82833f5edc40a4cd82bdf56b952346f6b5d756988342829a0bb9a5bad19207e3c9a6efd4c610f0b68bf20d6df6f4c3b991673f809991c334ad7c40f93722c93ca16b2758ffe032eabdc18775962d5453a948a0cedb79573544b5f4b18f61129461f106fb29a29dca52632858b167214859f7fc1d99cab6f7169519b346fc83cf228344410752e34ee4800ecbbecfa7db316a1733bb9ca1240728fa72a9b855b6641900d6879dc2b7bf2d13590b40a63bda34c2cd82ec506a474c0fcc61d68a425302f2d07c74ff09ba635569090e4419a02a47018c5eec7f990f6d6bc93ef167ccce988f4fa83a2de5a171767ec2ec72217aee22fcfc6e0417c5a3433fa27e727418da5696e0bb089b60a038bd4ec76e605ae29f6e3b4a0c71b4ce644bc855a281af5847e01b0da92f6dbe9fad7571b4c9cafe43016c107c699b60c51d852185ecd7175a7de8ccb327bb2abdcde1172a3f368a00b9981a88f4b0a503e5f8527028dbde3457d0bd3b2fce639cfded4bdd5713cb0a0daf274d01e8faabb34eea546b09efbe20a12b477193c79fa761f7e75f289d43c98cb4a84625ba1d71e84158766b30c66c6ac88af0e29bffe3dcba84be3d70bae17aa7d9bf211b9fb49ece73aab4691d854560444b026183adffd4adcaa40000000000000000656659000000000001dacee507b685648a0bfa5c9143377e68f50fc53b7b5da9467a383b02100eb12ba5da98ec2fcb72115cb8992f3061637c2b315853b8787442aa40103e970f36e1334d3a908b4687bf1b02ef25159ed2b3f9fceb771a96c3b6ae3eb2675f80bf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074f9281e26388ebd67b7fc1adc45dab0be1cfadb225a22b626f79e7195222f286a93114e9d445d86a45f630d7839e44c5e12fb50095098bd12c5eb5db813207977c69c1ce9f506b2882449ef561b8129fbda46692ba0eee65ed5142dcd972a9638fad0ff4aa8c503068b6c7313b82e12df3561a727a126da00c291046bf1a3c0022da9bd78528337bba3158de197a727847b884afb73a7c5de6b1bf91146a1a8e80223f2f7d51310d5aeeab8d184be20390e82ef208f8101a8c977cd68958aec3fd30b2b79fe514d98d2d439b1c432c6d5b31b2fa2a90f88f0e82da4d3d7f21a67c8b41abb97170147fd4ed5a51ad77e113d3771822ffa5a08c1f8be95cc02a570cdf0020d2658c7c5822e4d1a8746bf83aa4d63fdb731da9262d5faf9f2f3723ead39eb0205bffb8b39560f11dc22b4bdee459eaaf4a60314e4bc0c86918875ca3c6cc0d402174c9ea3f0e9a3df6ce57cf37825fcef57f44edced96e7942e5e1a0080280a1902004789dbd4b5abc9f457da42af0fa9e768ba0eb556cc6a81997b7cf3273270380329ed320877c77faf82f1679fde0304b2218747c9eb3c09a7972d5b680c74c8f47dbdaec057fbcb5b3766d5d0100809c89120415b86f2a33ff08435ee80f0f61e3d2b7275818729faed9e18f476eb6bbf512400863c1c41927de066e8f82435f3040994d8a0f215f83de1929d6e52e3e05eac767dcedee3a84963746ee055cb34b18ceeddcf0331b8d8ae2a0061413b3e3bf8dd4b3fa1d51655f5acf1465637f9b1328998d42657631f8dadff600b1f0ffd633abb12960466b3f76850a6fcea705a71acbef608609acd159a18e260768a568700d732665b8cdf786ba19d3f2eb9e7d94e264755adf688e7be1019d65658b97cc88f41cc084b3ad39901e4cf48eb9170f54ef14a8dfd427ee58bc92415326f264073d45ad6c16384de06ae6b87b1aeccf5223756433da267e158b3b0935df9db3ca4bcef8d259c69148cf93c25ce8cd09d431ec8c8eba51ca8581edff9194d823b5d7b765da0716ff9b61ab9d2957e5a1344b74b912a46f88a12fe80b79f5987cd83537d36a040c3908fb3a29cfef4860b94b3630037388f418fc8f9da9deccf07b80d4f0c671ab651b4283cae35d1cfcac90e225a524fc754ac5c98abfdf1f0257c213c79c08eebb75122a315994dd5493c15e9be03b6e7129d3ebf7d021d60be2f2e5dd6d11f0a7669190d35f39e8881390c0cd70b1635f255ff005f4d0fdb300a6880566a87f809c76bc8d715bd47c8ed83d91b3e257447f45cbb0b3773b40b10a460601396840ac210f5d1db7d80df5e6853c70690cbe305b47a9cfc1f0119c68cfe232e15de169aa7a652635871da67284e1e2783ccc21847e128b308355bf175a1c68d4049e365d52a19b06e21ffd329afd7549c88c3b6877e770a51d2e57c9f0372ee5ad7893e0b076a6f6a38cb56e66f2ddf2c66e33792ceae5c4de5f998c95acccba97fdc949dd18317d01161e9ec0b3ec162edc144f587835fdfcf953ef03873163077f229d22307559563ecc592b5c7e9d32b389576aec190de1256cae7932a705a9633c29de94424ba04bf140f2000da2b07d6212344910eb9fd45a507ecc90a4779a03b201a0bf333b8bdc80a4e922007ce1c679094dac31f828613d4c30b1e565dd650782fa14216946e9bec6be35083a1c3289a26ae669b27c9dd934589f227d169d7be550c2cc2bd0e63235a1a49317efa704e4b631ca34fda21043f85eb166403bee6ac6b01a8f51bc492e18d7b8bf10ed4dffd1a80928457adc9c96882baeac545009891f94f0433169bdff321f3d4af1e9c940c665b21b14210fd7215e339205197a403d79f2123c531a9f952bae70bc10b6cce8c8468454471a22417b022d4f1c3120585986784e0ea9ea7ba05ba224f61f73c0309c805031da4b50f19f6383b89ad5a64ddba00d98f46964a4754c10bcf40a86bb5f69f5abcf98f5c5a123ec494ea60b3ba2c8246212637d7556b156effe113d54d74dccc91a3ab573c64c5c4efea94b615326f64b2d8a8d99c5ac2c228cb89107671fb2d7fefe0796205e8e840021e73de6b04dec02b32489f4e6abd47947c9784ce364db9c592e8c5ccc1c48e5f2de56012a1c498968d4c3734a9ac46022f92f274fbba044417f932c7be8f1ac34eb327af743c24b92100c67b4aa5f92a27263226403e8c2bcb5a93f5d930ee5ab4912b98c96bbd76514b4b4d0e8ae42a01791674bd63e3cd0066c3703785e1be31bc09bc72b6904da5871c541a4f5eee591dc8cb87b8f2805d093a17ce7914f3c528bed447809913c8a5f6b3acf47eca867ec7024112bb88badd7090e6680251bbf56246a5d6e21e3b2274111d7a6cd97d4f6fa37459f40950ec06b5ea77a8c7db6531893b345f59fc05db07672c384478ff580e", "ac63526365", 0, 1568516646, "2397c973c5490211be7a4f81ab50cc02aaabb65eae14b749ea1664ece05eb747"], - ["00f10ccc013722ba86ce5fafc7a7ca8acf30808bc2217f5dc3be2e32c47b122b3d756a5e1b0000000007536365ab5252532939c340042f507e0300000000056a65ac006a0a28aa03000000000300ab635b60cc020000000003536a519114d7000000000008ab516365636300659cfbda60", "0065636a51", 0, 1234170252, "b12fe4d831c509670e41035a935b6e4ced174fa9713e133d811a1eda403f1ead"], - ["407b037501a54a7da2ca4c3de1b2c08f8f34a504525a931f4d1d3480486b23104bc8e5f257020000000963006a5265ac5265aba14215eb01a556b0040000000005636553636a00000000030000000000000000d2043205000000008ec924cc3296f1c3443ed9f5b67b1299d50b0710e394ed20e4589f48baf97c69386973110ac533589663e74e0eed3f2c133d3b9d27ccf270dc36f12a10a1ff96a71184888ad3c4edb083b017282e02d9615c0b0a7b72ae72f330bfa034b4cda80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098c6defe469e21c92087b182cb4868d70faefe30dfaf1d8693ab97a7aa480477784ec6fb02d3dbcda213f26d1dae517480aef7569254141bf5b590678af7bd0dd972a3c1c63c6607e99fa816aa5f6fe615a7e65389ef76e112dade76b0fc0040df85f8a97d4f45e06b43ae6ecabd9ae472d4788615eec01a2e60119c43d344a403270eaaa3fddec50954cf990342504383927fcf2fd9f0677f4cda6987fffc2719032a6f1d8450c1b161dddcd69e6bb17ae398e24a63a308e031f6fbb8d42a4278180a11ef696ca22ed0bab6193fb74e698642265d411882c2b39e69ee7e4b1f5d65b72b1e7641a9b9720a0054327e126288bfb5b84c80631b4897a8ec4f537631ab4e03202333f73832d4343cb7c536ad85ce6cf988e6f5cd3c8e9e9681baa692e63b90030cb03690c792584d4da93c5389446d4ad6af3dbd4a5e6c8ddd06d75f89842fbd022ca11a7545971547a9ae18c7718733a334a1f1aca711771276f8e60bd11256cd021e116ada2a7fe777f8743058887c7a2db81931a84aba28e653f72ec0520d81be0326abe2d48fd5cb859544253293a4fc7f128662addd50076a87b17ebe7a3182799231c5d892a47018ff5b7af5909f3dc892adfd752fa26c8dca6390b263b9be0b6d8f2fb50ac50f58f8ea736c8559e274ffdff0dc41be72ef6fa0a3ee3f68794867659e3b20b775cc738c0bba5bc9ae4d5e581d7c4e84d568acb011f628a96997a14fca5458d5baf9a50cb2ada4c3fa8cdf5a6be086813f492ba0ca6f72f95956bf2e4743b057c8520b6cfdcc491153471aff9997805a286ab0b62b8493a69bc30529d846cc2656339289770b7c7dcbbc29275b5d91f191a4559260e0d1371ff815249c9d419c9c5dfc22c63ab24f66fe31fbc3c5a70586a869b23c8178ffe9133d1dc749873b089dab1fdf327852a865d4527613981e8460660023dc38edf7409cd1bc8b947977ef50cf6bd65667097655dc5ab81ea7a3e0a00f1729417706c4e6f51079dd53ea1926327a243c812511f318004f199b9540807da1df79fc2b0fe2585be589295abda753705db84ea2889712c679ad2ce367fbe96f9b7f06665b4fb4a068495addb02a6682247b15d57fb9a5aa7cbda90fa6014408a14515bd41c1503bf0ce46624d5f3ca5ae2c05ad0048b4204c1e541d63c0f7e4efee5976f17eb188414d9bd701d054ca88133b09e4f5ba217782de41525353d447ce84be7b8ec2f4e940a7f27852377ad3b048554423274f7728c2445971acaabd61900b044d76ef48a1bc76fdad5780a66600969b17170126c3c9ff6bc940983392d34a653fbd372d3752f3ca093c1f056b9d8bf56e1631a44e32913eb68f4ecb281dcb8d56a8236854337e95e6b8dce348e6f8f5aebb6f44267ececc0e65c5c619f8f4747bd22dfa2c12485d12d55eae8d59b5b31a070c43502bd404696381a1cb4cad6d9c3c14fc38bb903423e8fd633423003d4ac7e8cf3ef3d9533e122b138f7bb3ea522ec1cd7dce12b804dc5126f7c51733fdd1136b575fd92397990d2ddd61e3b021cc9160e04cb3a2f6f36d399e568900067cd3b9cb42521a6868be930414a5b6f5230f380bc71a49ac0f0f5bb99a2af2090bfadc26a367cbda542f7f76545a737f570e7a66a97f0f61f7e7fbfa3a070ef391737e4889a97f2e5083742c187ebf0bb5cd4d764caf1bac8dc159f5672530ea6b408efb7a37698136473247b28a8d19dbced435d7480953acaebd9dc42a37d3fd5e61f3a193b237139bcb7c23a1e7b754d993f6a49ce1e46c4d3ef6b13bb177ba4f1e4b780e712926f558a6da6f92cd5798350e5cfa30b4d90bce23671f1c1d44f2f2b8dfa45b54ebeab7603c51450c5582e1fd9788d38cc32367bb4d89279c8048675862ed77c9e88e327c60cd6d93932da554528e24a619b1608bd44274e120bba2b69e8aa191cf4f48b033ffa12cb022ecc16831f73ee06bcc2baf9cb4a18acabce311005ed4806e82e534181a696b76e50f4941e81e5b2dc1b44bb9a46ceba2a085a9ec5aa2f8e696943ad70844e256d078a0fd6c2c5551a6770ea8fec48846221ed7be01103b1864f027c8a334bfafff261e06f26c50a1af0f49140372843910911d8e9a09c7dc10e0f9d4516c1448ade32b8d251e5d96db405b801d2adc6607ee6b0da1855121bf1185a5e51367af1eed1b9a776f0755e7fbfcb71fdf76816202dd18670b94df76767dda342929908e2f9fdfa9a39db87b29eeecae966fb41a20067f839a2a8eac3851004fa4def2accb6c8694dbad1143695fc9138bc600000000000000004c4e430300000000947c44d496deac05f014fffd06cf8348183bd0f9c78ce5c6ca538fdd444810679cfdba47c2dfa2bb8cccdbe3d20993cb4d128ef5754675b0aea0eb43c0a50ac228bd62e6012de4b79598f1869177580f37bbdc97131102ac7d116c72f35005e400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ac05b3c602fee4895837600b196631d6b0fd45ff04e27a05a1c0f3c302ca7bf067efc33b7665777cd35106d7b8346c91be5577d1e287ddd740e1278acc28aadcbb7edb0ef8423f481ff676412df05641c17e5b621ab08a46e0cf5c36edf7099f23236ee69df4a222877e7d49db0659b539f119a6565861f4b2601e774a468aa7020b7cbd67c20c79707f9522b72705dbdb1a2e17daf146876b4dfb4016eb1e5f0d022748bbc054576bb99a59ecbb386e8b8c7c7b6881bf8e6a01e2a4443d0b1b30520a02a9db909591f5db3426f9f490eba9d61f3f7da53c841fc62f6c8760b8e273f8220fdd6488ff6e892732fe497dd8f12d548c47b7b2fe456a5bffddfe9decd03b0208e685569b1c6ae89423c42ca7be294b46d67228561c9730819c89b3d38ac97e03025d56612bb891caaa071146080593e94b7b3c40671911ac4d922608b986180a032ae183afa7b8f9076837a3d5ab22b479bdb518f7c07bb6495a6e378b3a41b8e303194a5b84bc85f7f7b74f84d23f152731175544b22a5ce0876061ab3dc3b983730301ba21c8f9dfa12ea3c6c4e8ef598d790aae7fd448f6bc7ea2cb4580c5f0dc0a759a8c6f35b4f45e549ccbbb10e1535ac2a8828cba8c637ddb391ed759f7864e97d108bafee90b5acbb5ccbe842400933f2080ac443e4e24cbbc9d88a28d3a192184137151115ae4bea75ee7a4a246ce5c47540ca54ff91b73a5118f805ad1df2a50f9fec65430783bb0f3c107eb2421d41d3b7f8879fa237c8348e6d448c549cf0ef2f38594f387bb79d828569c27440d601e43b3736bc1b0b9b44ae5ab121aecd7e3d808b695260a175cb75ec5190902bd1e34514d37d3f3de7181d4bdbad00ad7423a5477810fe0d05e5f7616501d1689b09f288c4f76d2659cd9e034c98324193fe73934c69313acdfdafda28b795a02b206c34c98c075b089ce592a3194614af7443d39ce33f9955a848658cc8ce02d8cf03534f50e0c37237cb7c6095ec1806b5c1f1b46414c21ac7e631dea32425e290133383514d42dc2c6b6ce1ac636889d9d560254888697438e041b26b5fcb109c022b2f02ff43867f8eca6cc57a77033e38e700608beebe5cb3446df44e44d949c0a37384688938f0afad67c90b00c54b412f6d8169b4fa902dcb6967a3ee6ac51810cf9adb5ee93ef199332c9b666e9ed70dd889c8aa7c8592c9c62daf6a6665455d721520de5f75785e2ca6643fc6bf33ffaa9fafa0df03ac640b10b35979d829e0ad369a98bb85794087030f6c2c7a4757bae894f375070190b416dac0e5dfd92e14095730cebe980aa608b0f975be4f73f3cde8b84e51e9305c0eb9488a2c491abbaa4f8a871e4033ab3c8f1dbc7c1f83ed668f1ae985683eee4c14fc5a4b4bd293c676b532b7c9c1044235d8cf1354904b2646dd810ad8fb18d63c5a87938ebd6781f81e32ce57db38a777298a6b1485014d4c70581c764fde45039a0fde628b1551f98dacf5175c8ba647be7007246949c0b5c8b24ff28482620b801aa52cdbfecdfcea82bb7152ca43288e2918d530e4119157ac0a37517cd7c951082b0accfec225d00c3707f6176347cb0dd9d52a4ebfdb33ba68f61b929746bc7b586a72d7715b5c7550c109dca82ec3c3b86bacddc588f56aa629c1d7d463453a282521f8c2a2a06b4da368fe325045365c5cf05502c4f4702bdc4f7f0024df3b5e8a1c57c7f4fadbf2b7fbdf8d75e024a2c52ec1fad0809defd2545491d412969728a43fa4092d2b2bce8d87439241763ca9ddeb5096e8d93157e05f3d19cd55c0ec956463a8c8b32183a974041d7ad6a08e60d1464e84c3ad1c9809ac6999ef48c130966a5057e7304599c9e1695dcf657bc77540bb0e1f530f8f4eed6004e689cd4c5aabfacaed76c60a2b074e90805cb5046bee53013e5a15b3052b82666233a18f8e1a659741865436f36f4b2c8a608dc325c5ddf391ecabbd1bc7fb0b2636f3a06980096a2bc2456c1e2dd43f94383e04d2654db924e35ea4c534bf96d9e87693ace6683ab997aadaa62fe611a0ed8b7a1161eeb79e560872721b77b8569f01cc2afd2edc573004a8189e5cfdab8f150efd1e89e5c899d5710ac70469fae24a7b6a34bbf660e46d8ff3b36b492ce35b03819a822422cb9f996cf32ba44733e4d4a6367a0fd9279e9b1c2e5af8619968f662e5da79b4631c65dca262aa21e9684c086e048b4536d46b586654452437d164ff4c52efc3982d45a9cc591800df3b1fb8a0fcd92143e199311eac54236a3bf3b496c1f10137020cdae13dbc6a91b8004000000000000000000000000ad931bbe068cfe525dce323cb6f624dfc5a576d34c67b23ab2c489936308fb7d1eb4e29b837a382096343046a199fc996c4481d98e480352b8ae2798e983b27a7e47d01f1978b649ade08ff8f32c804217d0d25135c2b9405e58f134348be57d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9978c95e8ec2a2852965c7dfde8868f6dcb0ae3948c605c60de93aa30b4475abfbff315cbf6934908ab224e5b3995ea6fdea2e024e4bff0da55a5f6f6a24b014378e47418468f474f39f048d5628595f3ece5b2b5d086ebaebb563c94770155b1a657cf52ba9236e4125c52c263654ca4a853e9ca88e54c36f628757d16a1680214458e4c899201ed230ce87f3ff329e67a605e25ae84352be4f4767cbf2e9a80032bd347bff92554b187e3059fa191467da126d9e51cb17617bd82e61f819f06990b2ebab0a858d70e0832cbc9fca3c42e50488cea5b1ff845f8f64bac8b15a08bbe1c6e26b08c98db7fd454b3406ccd10725acd157c893f9be9a4cf49c5faf02b12021cb076b5fad8671a7310fca4927015a954de4a083ef121a5225a35d5f5a529080222a3438ef979c93d169b00b0fd427ab70dcc2010f9a08b9117ca24821af2beb8020656f4e02d790d482a44054dcd8c7958a190039eb8bb19fa2a48a09cba3ee1c30306d50c752afe3b87f23228448041e2f79273c253b722b77205a1a1e184958dfb030e80ef44f321bde3b6c56ae9d2be585d7ed90645732b2401f3d7c0f158566bc4f4b091274def31084ef1cba001cdf66422821be316ef29206c10c2a5d5dd9391a454a7f15243a20d0c267ceda8a0e78694377c03f9567014d1abce797d3dfc7108c539696910c4fc65fdb437d2b08a0683afa56b2acc22d3d2ec54ae1d5c7ca08abad1cb865264edcd7a9d7a7e7f280df22ddb76d1ebc1ca3d5c68b0b370793bf42b90e031844f5d917602dd07b6a22c1d89f6aece065af39ff88a4c78939f174fd743da87c8b8e09e425fa6dda1eb5fcee5b0b50f336ab2100e8a027e180c5d4c605510f80dd0660956edb22d7791ffcfd637cf3337fdb7266bee9b0c70e43f67c8b0eb8af672859b6290c06937f2ea4b9164c59a5fe29139c12958c2293167c22aebe59574b0693d1905c120a8b7c08cdfb9b063ece139ac1af95c79ac7c7cf0c25a8f824990b90d93b4a078796accbccac97a5c4454a4846720437d686e7ac4b6bdd9d69ed1d117324b848f1816d712c7940dfc84a1ed309c77571844532613082e6748463245215ecef9da47303e1725023b85673ebcfd72243f5282eb3ed01f2328270ef518a7fd234818cefcf5960d216018a001432ba3ad7801e2eb70e86f1ac4169d4e618a1a9f3a25a607f3038aebff05fe367d7a567e86409f75bc4b491ab10886ddd81705f923ce0998913d02d80e1cd7f145f5c252d61c2539bdaee4bbb1333ce357d51d24a53cfea437d94317784b7cb08164f2ad0af9af9ea630807b54ab54c38dc4cbdbbd1b604c2e85f00a18a696496615ae75893cfc484f3b18b7468900e8392dca1f70fa44f500cb0491007f7b084863b6b4e68f3fbef543945663053c19a845fad5a8a7d7b8b3a5edadaabaa8e79c2d53260f4a7c6f6c09f9137e3ef3731b2b2f40709fe0a43f1470ba551e16c6337fa58605dd48430d03d2e16468407b1704e9d4f2055aa30acd5daacf6c6ea9f75206abd8ad825035e8ac37fc6bf26439d544988996a91ad40a46bf35c9659bf7401347e96821a27333c8631c51bcba000dd0ba888a7be66871ac5c7ce72b5049ed36768b69b043343099922851692173c211b6ac62ec94653ee9c5c914c08d9e4cd9c2ff206ec9fbc7b74fb419c637bdf9ad30a2bce91da56d1a7cbbcb894d3396a23857361c3c1ca74f5afe7908d7f3272bcc0223c572039368c9e51c0c96e2503154dd0eb1b520af47faeccbb478a0dbf35077ecb35d57f7a4a63d70a028c2a717cd1d90e7e8238d005b5bde3cc07b1b887b0cdf67cc9815696c3665a16b076cef1e8260fdc748ee290aa941ff54a8ce1880caa129c8123baf6ddf24450849f93b2d3e259957d3ef6ca681753db995dc125cf996ead4cd1da4b59675d8899568c7c8ccff89b08c13cac2470baf943ab70df19c7e4f27f5384409aae0ebc7b71fa0682165e0218674c4fcb87c8ea60e42505ddfae5a15dbde26a5b8255501cec32ee25fe01e639db4d7ff24ca83bd687d85ae32849cd6992aaabe7857e69e451dba91d509ea27e206a7de1d631aeccfaa88f04d4527e777a19059e744729985f4ee1ab1538aae9ad49fcaf1275cd611cc70e4272a0f97ba1961cd98cecdf94f0bf16f392e82016ea074b2349b7863f48174482486261a1b19671ea139024d42bc576a63a5d584a05551919ec6bfbde014a8cc9b4457ba13ccce4393aeadeef0db4aff71a6b2d38ce20412a392a4c9f2d0a9f7dbb415f4271be2a9c71bb7c1d34c2c243b3a87d3374d824bddf0d1282c95cb29c6b56b9387d02a0c96eb874735450ee7ebb241ca53019b55ac046e6d48c1889e94d0b2f8cb76ce661ed9b6c5283b321e5e9157bb761cdb0f286e63ee6f43f6cd6231d299b6530c", "52", 0, 1120056016, "96a8e6affe8ced96ac5c76eeb0500abe81de5d8d6aa7fb584ca27ca1862d11a1"], - ["9957d8570126b2d4845c788abe9f76099d202af0050057dba9c149e678fad3f11ba7c9b53e0000000009ab655163656a6a6563ffffffff03b9f2d5010000000007abacac526aac00c1b860040000000004006a52004191c903000000000452abacacc328955f00", "6565656a525165", 0, -666266533, "378563438a3b73498f92232c92e8d334c99cbb709049a236cc29287dc295163a"], - ["73e470bb04664e75279872c17279b6de080d1aad0e1eb7676d1096a3908d047f300106dde300000000046a6a6a52ffffffff9bdd47a3883f87b360006f9fb62219bd7dcc6d4b94f532bdbe5dd5bf6b133f920200000004ab6a53539734bd375ae620578600b745bc6f975beab43bffeeaa726c7fd6f02a741287047dbe27280200000000ffffffffed2bfe7e04da2e0a33aad81f50823094ebd804cc7fe48eb5b293601881c0247803000000090051636a65acab525215098bcb026ff47b00000000000200ab52f4630200000000060063ac0063530fda4314", "51", 1, 317459275, "65637ea11f3a75a8b64a561858a5b574cf09e3956f612c29a47a07208c04f68f"], - ["a813c34701afb5a96b8f603d651d23feda87151d1ab3069d2976997d96658e7505e15de2f0030000000365ac52ffffffff0204b4f4020000000002526595bedb030000000005ab5251655300000000030000000000000000b765df0300000000a22d51f43e58f37b248b3d12f4c37ad79d5a985da1bcf428b864e74a2c16c04739b6f3b56e458020ee48715319cbf93e4a256676d01a42278e6b22a987de1d43525fe677c84fe788b46e95afcdce49d2e8bf5dc804eefbc71059c12ec2b9d3c100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bddb050a7ffe28f80640f944c54526ce43ad7dd852647e64c24ca7a14daa705b47f89b6c61069f5ac45f4a15329d9a5ade3daea6af54257d3dc806a9e41dd879df09585e8b8e0af0ecfc214a9458e1c0e4fb4c30f88cc36dc74b6e9998709ad7633eeda3530c9718ba7d2906fbf7e83bc0a606061b1afe99adac24bc276a1887032a332fe7ee82ffda0c56e64f970d3b0a54e560b465782e303d67dbad8dd41c2a032050007ea046ed989afb9c093c39a1896c9b54ca0bb9593f140a6a8b18f1ab7c0b023b7e9d51d122ceec4eae2925a2965129e1e4723bc0a3a7fc87ae954bd543b9289b53c29c8408c89997d3dc0282341c0b9d8618f6747e6794a38bfb75371f7f031938bf4b4966d668eda88a421864c781facdad75fb5e90807854cbae17d4ea910207338586be6e533f8967b6a78d538b0bbf2ac2368df9f8b1963638a67a14e315021e6e82bff0fe29ee58a5ea7dd9a3fd9e4c38994b9dbdccf8783e65a81d2c1d6c0229dfa447fa9f22b969726f871dec6d10dd3756b801daf88764a39946e24b945f020f2faccea46935ef4dd81a74b0d915674cdf2346bbbb68d100dced97b6fe06dc228cc9bf206b791f8177238ccd910072b34142c533ba56af7de2a240ad17fe98bc824c983e07c1729344815c19dedf4e0360d1d194af550d558ec4fc4eb896a1cf57c9381b8a79fd7aacd17df802019ae566b79e8775ac7ac7a9c059aa315525377e90e2f6df95ef79ba625d50fdca02a4ffae62c432db6abe77224ba4c6531a671e82cbb03405d54f50d9f1cf841988fb340aca6f89932813304d4444c87d9de48f2ff1e09000c5ceb81a92c22490f36331b18a0eee86f3b77e7e766187928db00fa355fb524a5c4da0e9266438851bf8c6f3822a24980d4064a8568c0414ab3ed11780167dfce83856287908fcba3b51814444e84e721936c304d9afb4bf1608aca1428110cfc9849717f900d5795e48dd3903e07bf7d2b8643db90624c4a3e4443f9dee82ee55a45e4c29e98e85923672c1a57c375e35ff1870bb344b60f6908c20be7621207e47b40c80f4642011e56d684a1f9f8ec3bbd50ebeb3e704660dc93af18ad825c4439239634213366cea0eec93f98315e057582f3d3f235f1b7d63baf8dd216db06c54f3cd64c2b254a816d9a6879fa0f3a7164d40c486124e1615034b33cdce528fb080bca11c2d8d232efd4335b9b0a7277811127ae59f6800c40f997a3da2b17a879fbb791d9a78a4f357d52da5afea25133086ab394069ba19d555b71ec3fc1f67be3249d2be8860597aa685bb46f8fd5b6a8a1df779a622fbbf4b4cfc0d901625025001e5f7228ac87451937b5dd25ebdb689132453a7886e5057dab39168c44c5e96eae3d65f59675c09d82f7126f00f13e2e2f9b5d51394ef7d206f112680b4afcbd90b9117961bf8925193985925130a0619076e3fc889066b6604312c72f3c761c241f231bba1367de3b1cc95c0158ed37e10ee63cf850e0be1fec07e66ad478d515be0399513f90f36cced3bb9ad9d17614beb09a941cd2304d9f301d635cc43587180563567ffb27cd9d105f8e3b25710a2504aa9f3311c9e2b4a0d78b35f967749e1982598aff9ebd6d03f1895f818b61d511427eee8b0a73ba88c158d5c778327ba0b11fec7e9468975363b49c8440efb16685abef74ea1537b5cd539e502865a653cfc8e14f86c3c0806b2119ee40677be499b73603046bec6769c732231688e81595c634c2c7ba73c7e9a1cfb67bb1ea1d9827eda64b76612a29ab3ef53757f39f792bfbb40296917d60b8f6b2e606b9ba822018aa631e572e6e7e7d3c273746420865a736a544637b7783766b9e2936d55312a01fd7c4674ad07799e7b1d7f8317e19047ecf406f75903874b8948509cae095e872b4a81744fe9853fb5c665f36fc0c9b5866278868342cd169332499973e48e8a5ad57317014a54c717f9dab5485ae720c6b0be239e00ddfd110b8e59798b027f7b2699ecd3abc928d8ba8eb31e66cf00c87c98a33b330bae417e9d8d92823a071d3323b6ced7db4bea5a2989d27c7695c5972b05cafe2cd75a5eb69b5a782a9573a667b420d838cab531c39956d1bd7c5db4401eb40401f69504d38fcc3f59e9427d79069c6f9b25a18f2ce726c7df7bd0457449ce4c9cff9c67a5b095f47a2c766fd9c0ecf2db07ae506f3221daf0a4e3e9a62cbe694b76f96a8a5db092c47aa7efdd6eaa0ca4c90d85b88d8f695bce6690cb431aaab8c24057df583beb0a89cab683a19a0aed39cede793c66342a0000000000000000966a63040000000051855d73a6d806ebc13eac6e32bae4d7b7a99e23be0ed37b69c4d0f01cc09426cb5523b9b3b188a429cfd897b42e97678cad8f9940dd79d6904584436768b802fbc3a3dd1dad3efe331323ccba8c30fe5a2a94cd5b45709a770aacf2cc6c30c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005678a51c3c44b2453dfc25cf71739c05aa3311fa63dfddc7e7056b447d7a32739e98c5b1377dc80d237e9a981d8b1937461d608cdf3e62fdcaf74b068d6c3053446ecb350b3f4b14d8b3e1121f0880333f478f520d34042fa9503115b333f8e3f63ba150b5e789e764d642b3fd5552bbfc1ab925c3e5274f93c4382c198b6dad020d21c36ceed4852a00ce23b25627083fb4c1facd68ee60dce1ac01c6b1073f0c0206ccfff08e3c7393ccc78967df8f3a1cb253678605be9c99b1955d9fa570a98a0b1eed64dad7c5817b51054bc9503326edc8bf77336afa178a788a4ebb81105e3119eac8aa5da834964bd23ef8f569b6c2cf2daf4dfe93e51ec82f28c386ca749b021c4c08349c26354101288e9a17640b31d7e25fc69c8e19deb865898d1cd227970320610a19585b690052b3cfa40ea04b03b24062ae52c4327c6ded4633def16d28032535bc77257a19c55727ff5cb64e5750bb71caf865e73028ecb70b10d376da1e03143311fba756ca03f670df87d313468911a204439a5a806d4a252412a3e6674d022dbbc6263e824711b48011a3a5d1a951d33d9871d7d5b68b2fa4e82500ffe815d5fb31c7c5bf45adabc4917db9e744583e61dd9f500f0ccd85c49778362e5394f8fa79caa2a5c97d0a7dc78aba6ad52a584430185524b818360fc9d05ed6ce23e6271f56e11d60d9358692aa1baed8949adaea1773de530e734f768fd20d4d61eb46aa7704a9b9250ae857ae73f4f22b144ec546208bba7f96266d08141598c834a9378920159bd411cc49c4a630c4eef8c5d46cc4d02675baffc4141bc2775a0520ed7055d8b52c2ad5e65de46096dc1aa3f586b173af57471297fbc0656a278c3fde39b487c41dc365e606255a0b23497ded20680bc1f464f02b9816413768e7af4c2db2d16eb27d9b6c2e8f5acaa6423ad2687ea8de009d19a65b6b39c2ef9f92a0c5d8f79fdceafa9426ae44e4f5f82e8306b2ff95db1b03441c6b67ffa98f6201e159c3ea7053e8c361b125b4f0ca7c530055aa1aaddf90cfc1065028a6f160d72e059d924a6e9eb00615f97c77a9beadeaa7a325a9db1c5c7b4c3978ffd62550526fac570fba3576bf931d3cd6025c6d127df70dcefe0b011221f5f1c062c1f9d7b6dcb6e617c23dec8d36d905bee8b75314ecf34b3f5e402c02cd53c85dd328fe24bb75caad4ac0076df90121366d9df6d2bb3c22de62d6cb6853169965f57716dd304cae7837694973d26b3f79201e5099a34da054f0d420dc2b106fc7ed6ce1754500537fceb673d9c7bcdd327c5499fa9616b9516a2751c32d5125c03d5f2bf9ffb408eaf705be12abec7f9bc706a43fcb437cd54ee70ac8000debef2ea8d70e6636e1a084efbfe6612e23c9191d21d2d5d1388193290641a279556695cbd8eba9d66ca0d23e9e9094769e09a93818934aa2bb635d90e4ea313c3a264ad125910553288a02808bc47408aa57a55016ba8fcf3ab32648cf2cfc3f375706729be3a93f3a5f48f1edf5e94e8d2ba29a3debe201e70208bd96b18259071fe38141c51fa5aae516f97c62b120b636d2f258744fd2f12eeb6fe0bc48216b81c794137f198fbc9adaf57498bc96f2a5b3069b5bd054cef0e1be7a40f0fa0ed26d5a4be654cc64fe3b073e4099b4cf198c6ad51ed33209d464f6e79468fc6f047f7e2e996a5574866e605a529a3859a15c9b77230f2daafbf584343f3052ae4ba2e8ff7f87e335e6c6e53e7bc8074bbd9d7105babec8536df9f0f8f7b357dc8c21dd0647ede5095795a3e2d872e594dc13a39b5ece9aaa7e6cb75f7c4c880894b99e525a13e8d606d4c0e1008b7c790ef57f956a78be7ca1a3f45f2212194f3411bba6bf6d47852c2d3377deb8178a361c611c26012eeadd72f7029a5a10caab0e9edc9ea1165d524283a8b11a0018b11f31cb271ec0e1a480423c2fa0953c25661ed3d65226f682160c1a128868b9063653fe9b829693700a7236a26905e93fa11a8cb0c8d73734758a1dbfe01eae3c92716ce512868b7eb2005206d42854743e5ebd4b1f03b7fa926b1248c7a4b2f009307b78a1bb5887d6e686a92378fd5317882f7162991c7dc6bdaae3814b4b26b49a8a330972efa25de68728c4e9ecbe09039a064c2823c2d8ce22b08326e8d1f19a8f52bdb898efb78701478dd509d91f9205ddc663bcc8e67e8e316879d621d87f42f2e8eadbe040c4da03edcbe4d9f80bb25f8673568c00849b428d15d6a8a55ea3311f86a0af232ab5857fdb9b8de938e97068399547f4c64c0fa0ef2b69d80000000000000000b217b2030000000070c738b43074546ce187ca5b001501cffc19ad2ad5979a8f3beeab47b79beecf038356f7ce22b7484c4cc4dc584a5783ccaf073bc60b1941e1e24fe4e964c1504a230c47315e79b9d5ae4b28ad27dc5ce60bbf2e8ed68c2fd4f5fa2252cdaecf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007895bae04c44e7046cf345510323df921892abe40a9bd9f359825a0010532ce8a5e9d225acee2aea419cbdb74ec3efa1d2d28039925a8a0ad96fc1a850c85ec3bd8d84ce9ba36ab236b2631574fd918d677219b987513bb9cc84be3738d7a147e2a010a133352bc8156b201192084fb6afe3f429681c2ad171044d4db32b2089020b89dc84d67eea8013a621a5a08d8703b204da86b337a70341eda09593be6ba2022a8b3d221168054e48b0fc04e1918b9b7557794182c4e383cce3e8f1187329260b148325b13075b82674e8739f7440e36207a718ca1e56360d89f9cd20d8f4b25a29f426f09c89767fea07711f7162e769e39d654763d1026beaf9617ca0f693520312e8d7ccdb418c846d72a432247bc4e05d3577c8af732c6f47c759e2e643e75a021d2ddec3f8daea0cce16adbbfe2698e6d2d4d42b3ed7bfda06b87200c420fbaf0224f4868e59b07815e33b94a5ec854b4d46729f0488225d3bafab738fc1818811022b0b852559c5e837a7ba135cd0c0cfd78ce8d5377909040e8e9eb6cd6bc4dfa803259b03517e3c0fd2647618d2d0022d83157033d7d09820bd438ec2d63a57c27c7ec6eab3b8bd36ab9bb573640ab418f3f8e9532ab37d8d47deaf11652ec529b091cea1cdc9699c40bbad2e11cff6ae6a5dbf81e12c216b31121ef31f73a9bf43653fc75582a80c5cc42f0a65992eb15380dd57c6bd54ac931ccf869878c0b0d152563e21024f8ceb4a1aef3664461eca97a533a4846ac62ad9aa6ad6bea44df47cac0b978232e52a595caa4fd617ca4ea6a32f77ff6e771839813650232395d10750641d38f47d0c84b7578d946ccfea2251bdedd9fa44bc41394a2fce81bd37cfead9c831e84ad488384f42ca1012248c920c72267339250669432398879353b17d96405c06fa6f49bd6ff06fbe142ef8d444b3bfb159a2a6cc8fe4a3f401103409aaecc9f9eeedc52917d8a22c6721bb43192b146fbc3041b5a5d2470ecc97e3e7df20bfaecaa254d8d788731742cb4ebc200f68fd41d36b23eac50254e9f33e5ca7d514a96acad35eb8e52f580c7973974a72a23c74467355e7a5dbeac60fcbf5bd3a5e73adc469067de1c2c28845227bca7bcc0b5bb0935662f3b89440159608a8ad455c6cd0c8e68334e5625bc2848fa562b08bf566b79f87f738c1d373c08bb4402c379dfe6cb025937d85e12baec8b0d89fedf79fcef14c47ffa04f97a9320f6d4267747a87fb63105724736a436e5e9e9e8c80e0b981f704fffd36906832efd63406e7f85c46855960bf10780083f20de391d1a9f098d723dd6e020c09f84c2e4494961e727beda34ace46d08f98469e67628255e37d012a8b41c7262451c1ab67c4632f98742afdb6b47155dd17f8b4d3a62be849476832e372144ea5bb15af6ba48eb0852b06c5624b4d9738bd7594ad63f67dfa71e7d0fcc905278634a03734da472e8508b16ac50df57df46f9d0b46886fc08ddb9aa7652dec757885ec4b48ef8b1b26591547381b6f22cc30dbcbef6c54b0c09f29516c9c6d810fb0b4cb2f3f07f47372d34eabfaedd5e3a03c68821d1569f6c6791a27cbfd69b728bf3716db902b3a3a872916edd4a95f84cb94415c505d5a0dfd8c652d411ee1a1c6b53e63f3f74c26870bdd46e63d37c01344de86880ca6cac33599f6302877f4fc9547e7a7df42664b9dc852f5d2c3f9cc21fb6a412fea571a7d49c34c7c51e1fa275f95a18e67449c24c0d2468b0595f724fa077d61841c9d67ad8ed0be7c27d42682632b4b721a1d9b8f1a7c845936f0a71b4f16098563f483408651f52b816c3cb14ff5cf3aaee388b428097acd1296c6ced5cac03336ed28e9bb418736fb45ce69194dd94e2b2db685dca7c727884066e7c10967d2992382b2ac9846287aef634d1603731789cfd91edc37aaff44c14d01352d978ab2113856d155c6ba592f8a71f90270962e5cdb5a333ff6f6becdb80be66316d4970c8846b06861cb3aae3ea84f5147b4173e521ce91f67a89772c55222ee45aaf3438dbdc1e955b9799aae63a80d613715f062f7b9b1c8d7ecea0289927c2998b7b1f4bd41bf171b6937f0fc1b5b6963478858bd15677b6ce0122d5c4777e3d61faaa7f622ec317229c6c69a7895846ed3fffff89224268c821ddb17a89a2f7f893a7189857574dfd5756677e0bcb39be5c73a99bef38143a13d888d3ed2c63c1f9eb7f1d7e2c76eff28df4ce3948c2fdb782a67f31b263fb82a32922ae74cde2e6518de084ccaccd56ea229aa43dab0e5f0c59bd40c4db179921aa63af8c49c7c4ed1798ab7a7433af73ee7d767581eea9817465e45540bba97b0adcde1573c13629ca3a95249bd01ea7a05d1c7095329a37d2b7276b30cb41e6211c4aa8f519c197b49c5a243a97150cbbcea2b62db2c5cbbc519211b8303", "63", 0, 871174497, "ed8b7e5bb9b41806932990b2c2351c3d163bfecacc42c634f9cc943703b86d77"], - ["5dc1bce602ff337b0dd41e91d0692bbea9a75553535622f1afde0d5287bf97195c6af7ab41020000000100db57ddfad53018ddae9754ef216e6fa8edaa36f6450fce3d45674eac08439b51c4253b0102000000056a63ab6551c0e1cea10156b6320500000000005d10af86", "5153", 0, 1602741303, "17109bd3260621922b1d8e8a96ba46c04f35f4da2fb1d41931db84dc1ddf30af"], - ["da83c45b0192ec44098cb8d436a7724fe8de8a50114b0fa28b92efedf1b5d9a70b0e96ddc10000000007535163ab65ab52faeacc1a04d8af6200000000000165f1257301000000000553ac63ababad2b64040000000003ab6aacbb79ee04000000000352526a00000000020000000000000000491a4b0400000000bd297fcdf40d2ff9d89b50a866ee61b5a416ba840cf3fa95a466fc160117fbe4ed55a04d5d2bd6e1fab8a8ad7d63d12b926a1339c29520b66906ed1d8d18e2b75c39c7d23ccd787826789171e5d3fcd8767dd7249cd9cc8d1d55b14ec6163b9500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000513628920ba7a926d496a78a711ffcece462a99dc730b6a5619d2f45fb64c3b81a81ee4a95a5909570b86798bc59366604c97d4dee7a13ad598f68186662ff65ebc7ad96cb5c49a5552850c0b840c800014e1f8759bd99becefab841d885cf2f7a4ad45c934f5b95e4da497755426c50f19494ce83f573b1655f6232af70c51e0208fbd545ddd6f35337166fc3aa12c6a090fc4b7f1c1068562423d8eadb58bb590300307510a71a23e29f8b782b239732a62644c2583bbab77bf1a66cca3010f0070b2861fd04789159a198e85c158217238a42af088d88bf5988ea8722e50fa747251026865b6406ed95f0fd24207c96f0e2b69958c87ae66e46698f7e7f0bf32ff60214e2e8fb394d80f704d66d713bdbe23896a6a334aa45b7a14ec238f91f1f6c7e0227abc039dfc4af8a8075cfc3af5513175e1cb6f159d1915be38dc7f74b0f5a4e022f662f1a087158afe29f36578a497251f90f37e20109a40b470fdb22d9e7ce96020db3d77bc75234327941b89e1ac9adce4839ce8f19d3dad78be8bebd74ed0b480326b28cccfce1ab3d451296b49abceb35937dda55b238d05ead511939a84084ba2741fc01c7e87f0a5ea869a8a0a99e1552fbebd62e136d4d48a89d9d15d75fe7318f2a647603b85e49eadbd979f1a1eff1957f592af8b830b6bd6615a0c2654699a50883145c6510499eae99299501be7beb546e9e4155547896986158096b522fbc88cda061dea11abd06a60c667eed28d4f3d907d0c3a6a94f70c3d116cfc7f1d9b39e8e1ea81ab2328ed8a0140c9821663e066330783ac0b9f5d151d62d5f9b60a7568949c789cb8130cc039426c746aa17f2084ee1444a11c1197ab38f56de69f3957b3830fc0ea1ea6583d5f0a3c0e65c0aae923d2d2712bebb349ffe33c53e371e94d0894c5ff4574e5a67b5dd73de63aee952995d86c313dbd6c654b2bbcbef9cd1131cd3221b8dd70581faf1c8ac8fada4634172573a821bacd86547f5d2615d0d12963c5b8cdc96b274cacf2fa0e9a0a6e1a04834783f7c0e48335549d96226a1b162bd46c6e9c6cf04c3cad15d6879e51c8d1e17c97f811b5de1572468ad1c14a4e959a654a2cb55cb94da2986488af7793a8c46ebafce2a15b49225de868a2e0f19f42f7fc19243a29825d920c6df910541811ca09d0d902819f94e03958808bed53b3751005b05b4de9216d88ce966e38a14a2e304d446ae414ae4d4f1dbd678cbb057c65de78ef1f8ac689abe98b1f3e9122500783005a8bc30625230d97bddb31d00998d847110dfb53b0833a1925ad6eb0b77e599505fba891995e2b2ac60f5ebb229a17dc24c6ffba2e60898b49611f90b515b07563a2097526319e37c21f26901ddeb9c395492eec4e485d5195d510cc81e6d8758e916da7a24d1604c8d6b325b1036bab09fdfc88d63dea7d32885eca8972bae597da054e03434a35298e00ee171307d87881a464340bbafb8fc2125093d5e1293b02a2585f6c12ad59e9492ced7801cfe89854c27308b9eec698101ddb76f4166a3c38ee6903fdfc1d0675515d3301c1ce3e5755d9001b0ca1939e455b1067fb5a3fbed89c26f0cf5592d4658468ed1d83305e5d396a037ceed9dc88792b3c8cc98d379d4b625008845681d00f0a6f93e85264fb0d65973f84a7e93479b7582cebc2223494a0eae482b29bc8b9ac5b471ecb994b69ff4137b278b1f3ec38416906a058ffa686772033e0f1ba807b1208b5c6cd405699ae7d553457262d1a0680cabcf6144feafacb8e575b30c9676741685b017af171d0d2b08ea3a58347f3006fe132db2723413a050f845a0fda80a1e5d7710a2f116801b0a1b91a46bb7afcb2b2b62fc00d659a35681de8d24d9cbb375ef6065170e79af3eac6c2fe2463011c9988b9f1355e82bc81a7fba3fad13d5082387061b52e184ea53d8a71f3d45cf4a12968b95a3c0895cd862ff45c3c1b380f450a62a4b49dafc304585edb70b36ff5c619b93e7f7dd7c8e9b2cabd5fddf60e9154608edf291eeb9ac45026879bbfee46f8aa4e846cebbb04a83896ed1c38004d0c354766b872ec31bcd6f20fe3bae1a4136922ffbf95f956f025d759fe585afb463c78e3c03ebd708c1d18dba0d011596680e4bc5e91a527b058b0a8ce53eafd45a69886f8292e56da0603a6fc8e71c7af2fa94c5bf21aef85ccc405ee66f2762a8d2a129bf8eceda2d32147a09d081be78a8a2828cc94c8298939efc35aacedda42e859635378227d1769b187483b9c6724462851bf3942fb98bcc7d2204e69cc26504859604000000000000000000000000d60c99cdd5613343518dc852c4d0b84d053347498d4a02629eb00e961dbb007846692f4871c4a2805b3ba857041940639298af31be2b16c16529e18182991b98596fab62e5191f8c9ad2e57508fb68b2d63b4fdd94681e178df50d2e1319cfb800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af196f8cdf210500ad20af7286d29cc11ad51c51e39d3e4b6d340b10b360a2887dbd81a867ce0e9ad6e15e3409cdecbf251416da19e8cb643fcc6ba80c0e3a0ac6298dd67b43f42eaabef609eff2c195e068cd59fd0c352e28b1b29f3c89de14c41ae3d8918110ba5efd502e12e51fdbc82ce9470c9ba26975f22dfa1f6a61da031442b239c2580f13adfee0d70f5e296441828783339c618f59f2b5803c9a0b9a0306e2b45d2070e8947dc3e53c6ebf5cbb46f13ea43645eb5a37c0a1a66303a7ff0a2888e85e55b766e45b97f474af5c938a29d04fd1370d683e3cb3058c896b09a721aa1ddb40f841115d4fe92abe26616c4ef82eb52e20d7f22f0c4a089106357b022d7abd065c8c92ba3efd9f109d64fb0f5256d18fa5588a251b4b97057d2b92710315dd34757e9906195eb9fad396acef5c18934c5a3a00e72729c583c3837c25e80321cbbd0af3ba52a8fb7947104f002b683ae4c2a58d3a94966047ac939b7acfee032b5be2067c5e5b9b396568347c041741f8d18d1a6935fea7aec808c3d2d66003031dd091e19e694dd343f84e26629ba32fa8264d82e3845c1c09a90bfbce4e94337b4295697ca9b02be6ca667e4f8884c224c18242ea779d0729e80089f82b2eac7a7e1b2f09d87b8c7ebff6bb21a6d12c1907e65743ab7cf9936c348158a658ba10d4006b0be0ee81d60f9f00486415ba87ef6199ff4b7b599dfc17b04386f5247957b8c5e757bc341c13d950c49409bfc885d1c3416e3949414707e138aff0cf58f8c31d1038fcd58fe3c33abd36c75ffcca60686861749fe9c5a772debd9feafb658189b8e025169333fe7ea3e630d4af29572bc58aa2ddd9a0ced08f4761ad0608229019d88296c7a5a2cff49d41c48fba0c91f48c35e7b6e7badc9d42a63189504ede7bda0cad84a25311d1dfa5fd806d8d69cc5d18d56e0af7589ee3140a81d8953894a177b02ad80afd0ac07a28eaad30447a094ac69569bd77ddaf79f675bfe2cd2bb80379dd1e15014406d12f0fea2a8c8aa3523d1f178345601b3279b557170c7d73ef0e8504afda34b61f9e497bbfac1c55a20c113db78a3289f8bce18b1155d1534c3a7ec3728c723148822d061a32cda38febd5fa5119efa1d4e501f7550c850783a721b6d650b42f2414bfae05eee6759c74868f6cef8b096370bf5ed1205976ecff4436a2e0f07c6e104755bc6f9aea92b261c61e68fc57fa54687591b942f7997861b25082cc1ab3841296472a82a2fdf2fb8998f382ef4d0873bccb4211f494863023faf85b0b704e2ed2aafa8e3f8ca3ac00258c59a75bd302836ac4a9bf466295553982747c477dc0ad9368beff67a7bee975ba136eba6c6461ab8a1f8cc164720f59691795456cb90136dd88e38026be7785a856950720a635abb649ae99bba35823b6e2db0c3dfddfd9cf9789ecc5609e94c86e4f9d9b7c9edf03adb29031136be34672d608f3781ba29cea52716d4ab219d2df8cd0dd23ea7fa1d62ab3ac258f57d3fc0b4e7c0c4c233276a09bed6a5259e1de242f7f775af369f64464a988e84db7338b7b16b52b443cf5cec951e6c38a56ee8da8d19f3cc27d54c56d60ec85fdbfe672a7adc0a14737603d5e32bcff5d438ab150ee7c1bba3889634b6fb217ff1fe1add8428267ec6ea785dba625e42c5be4da8e41b6c190922f13bc912d6a78b2b71279be215a4be06301c31f770a42a9af0add1e3d3b3c6696ca9a0693bea4e699cc4be930f367ac3c425c247de3fb235e5d1b05555ae919dee430bb9bdbcc95dea12568799048a508f8a27b835ff10757dd23b01e9bf76afa07aa251a7bce568cf8a7058b012c0ea6bfb4c0e6739f026830a475b0589f7a89f0c3a0590bbd062769749b007a72c66edd910b85c90f1249612e6fb3223b9e819d1303b06c040568bd5ae386fd439f05f21584969bd632410413dc528acca9c51cc9eb0fdccea39154719a73da892d9af011fc0fbbc99223df592bd15866447b245f39264d4d71034310f07fb602292d8828adcf0e4a08e2a329fc1023d754aec146572b258340b8286a1b0905fd13a7531b8c7abe0743d48efcdea40427a3e4a9c0c189bbd365cdf4d4bc90ade1bba1d9c4cf75e62fe91a23ff8bc9281953d7baabe70245f9bf7b0b7121e7a197c9eec8ec8874da375f57349b46335490beba22768626cc151b03d98a15a3bd27660665652ff908d6550c6810b6ba3f1070737cbae4fd9878ec66901621ea54fc2851a0061535acf88b43cceab4f3cfc53b78b130fc1b810d9d374e08c1e4ddbaef77147ce826d2e2f6d2fa41a42f103c9dc314d5b73739fe1d8bb3532eb0ba1ea0f4375cfd9f43f5a12de5484d299d1f7f30b6f9ed37a7932c3a71cfb5e94706de825e0abbfafac97ee1fc0cf3908aeab138f776720cb917b047a1bb84a604", "", 0, -1961460397, "060539e926e9099dd4ec5305c0feb128e24bbc752f545aaffae68bd45a5d06d9"], - ["bad8eba901bc0eb3f1baf1fb3862a6d4094a2ff543e3b369c0646a42148b8af42efd8aaae50200000006535165525253ffffffff0471e5b500000000000865ac005153636a6366c5740400000000007ee37804000000000451526563629d070500000000016afa8ec8f7", "acacac", 0, 632984595, "1035beaf256c346ebc296386ed481d64c80a25740cc9f408b8e62b6a8a33f889"], - ["0e2052e601f5490cceb69177e69d6c4742a0330287224a9d0f8b572c8e01fa8b72857a44ef0100000005acacac5265ffffffff010154d00200000000086a0051ab65006a53c89e9a19", "6552635351", 0, 1541011043, "a6a9556ba5131ab9dbb4dcb81aaf7def7cc3bb1e96304fa149342c8af35cb62a"], - ["2b92af9d048afb8c498377650832d2ad1173e10a8896994ff38d1858ceca11c1573a2fe6e50100000007ac6a006aab5265ffffffffdd67724ac13168ef2f98568f6f2a1e1d9f8c5c43467eb1ffc1c961d2efd4a8c40000000006abac5351ababc1ff34a725bf51ebfb702fb716c6b9d432cc44a2bc29c58d53ea9d27ec73fb19b99c653d0200000009656a6551ab536a6aab17322e450927876ddafe25c84a5c5e7274bf44ab40fa652ac521d8e65ee450e1e419437b03000000025163ffffffff028a095501000000000153801d040200000000016a13fcb519", "6a", 2, 909642013, "548c905d6a92f83eb47cbd46e783e6a9a11221afa203b77c59d83f1115cfaf66"], - ["0c555c11043775c30d8716886cb161bef009d1449ec9bef2526f240779ed86db07ac751589000000000300535201c893885c393e709bd6c52fcef75c1c13c84072d8231b3b02d4965d8f4bfb833c3fd0ed00000000060065655152acdd819d2b7ddb96e668d044f3bfc8710b3eafae6f9c38532aeeb61251221a85c145a96e5e000000000365acab6b22e07c8af29d79eb0410094dd83fe358a665fb69ea52e3896ca57a0a3354052de4ba4100000000009c9f747b02d396b003000000000465abac53168f650400000000025100fa3d64d4030000000000000000c99a3b0200000000d9618bbe4ef50ac728af3d263787b69326243c1b65b9e481324fa922b41f7a394044fd8807936d7c94bad4c41e8153ec351b720b74018255ba9bc126fc379f3ed10bec0ec6b78ab8d330c71d7fe71adffbaccc8f9cb7ddc6e9368d74d60eccd70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064c32e455b29db0832993755777084a60e9cfcfda7333f9acb9d6606087306ae3b7779c5ae6f889b59545365fbcd9ee047ec23930677459c911fc847e6e7d454543615e1b23b4280af86e8b1207c4e9e363e4a59283c88c0197d448fb08bc4acd6505935ee128c8268c4399850734fe0f042ecbd3b467564353624e8f61ff454020a6121ded076e2a2b2e46ccc6be7ab5d365d3d223148018050c76385965db8cb0300ef41787060914e7beab9e3557a15d5e7b89bf564d08cde2ba1110b013e0ac60a19218b773f86e7fcf577c8c5f44c5e522d467644c559dfa7bba43f63cc1cc6cf1314e802eac1248f1fc3413f3ecc72cfca31d407b33aca2871890ae6ad4deb9d021df5d48101b451ac6a9c6c10f9aa9ea6fff0e46e80fa86ce22f704fd2a8713080324c1764a859586d5122f97b12513fe694fae72804f0ed0ffdf9fddf32285731402206d1adc4e420aeeea2b314f1cedb362f588df86fbd74eb9684b5df5183929680318df61e33842761d1a69c967ea95d17bd102cd4cdc1e97820e4150c568b636bf0210d341240f10c09b68b90fea140a32fee8293a086bd8fe4f2525ac30846de1f372e129f77340b307f3c740b6efc599bdec4a973ee5c03ed03450dd0bb0d9f18a6b1ddf4842411910da8a49bf92447c771d77497ab8daf01f9a100453cd6edeb9384e241e65c41022f40d5f982b97e69daf710c9ad9900b9b316181ef1a5379527ffb4d86d6d39648d8d19f9584abcba71d97cb16b3b761794db272eb4b5715424bc71593c6f914d6b41a1a28643ac76d6eb5042f47bce688471c51da394bbb4ba5700591ca83e89bbd760c77bb9b8c53dbaf5362c189d257916af805e8f5e33153763d13f31766a85e3ac9d29dc6d329adf5e21f72d48c913fad2e2ee1b898a6853447148642f44126aec083e74f3937beec374c6309f928497255e561c305ce83074316b164779701eea5efb3480a36821157533db62ca1028393d33e3139daed91cac68217a8e9c639c9a1005ba40b7c848e102531d97ba832aeb6bf926b831a6c1e7de8e14d08b26f40fb86ad085bc6aca16c167e6d912adde0d44d82befc60b4f925b303f99a9b7b265144ea09bb539169f798d93c418ccb2fc601dd9a513550b532a052e24ddef357dd2b18db7428991288176b11a7eb249f561a2866e8a592677a9892b98faffba728c27de2215a1a9730475d74dd153208edc6bfc4e39a831e814fe3675bf795fa89091a983aefcede555fb0d3a89e571baf490415e648d37863011f1a7cca73e11bfe70ad44f9f1923af2a0dbfffd6841d4adedb58b54eafe66f703ae665ac606b69a75969e46fc41f291d88fafa754930696d7aba987da15248636df50839988f2beae734041c0127e133ac5956351205893520ec804796576edcff239aa4fb65185a182c3ce79cac85938f36dfa18650812e0158cd0b3fe997f8f6e9cb4223f3306175679ba33c6e8b8d9894760a267fc23778573acaae3ad14d1c7bc0b5122838cdb4d6c9a746f304e6bb85874607e953d83e9f3b4ac75150a3ef5ad905ba909a802226c9e94242a3db7d3fef355ef9e77144cd1d5a4bfca7e7742ba3e575d02efa7474a00b55c4b3cd176cbd3bd945e642f2322587f3199fa445da0039adee4c9864c22224d056bfd001d3573bd6375fa4e1ee4884d087887c3cad008c8e1dcf256a966de29b52d4111372e384b11d3f7324c38e22db1ab82a83b614d8784ce7933ba3e5560c1036b92af758f24083c5375020d8df709f884bb46989f6951a0179766abaaf0c3a4877234ed13b05263cb9ca2186f77f14ea4aea4c72d8c3e0fefbb81f08d2b2d7dfae1e317e2a47111bff33c947bb493060e178dbd00d9cc7e23290fe4b09bc5f6cf3d897fafdd79adaa7a8880c2e97e39a84947143647fb331357fd14f377190d853916b554899531391bb1f1ecf1aabf1fa3b71a2f41d78cf154bc3b5b7650794156b266323368d5b49db28f0360603500267a2e7100a40e499ff6b61cd5d85a03a8e3e887f913d3f309e37f3efc08cc013aa354cb18c4385d79197047676f2056f87ab7331d64b8e3849efe0bfb4590ac676a1744bd2101796a49ad4a0f6e900f84cfb48e7a1263d5a8f4d498127944604e966b424a65f7e682c633a23632b75e7eb610cb6b2048af68b1f74f40c0d708e2f1756da9699f6faf5627d4c38cac7f0528b4c6d854518056c159f85784b4d5b791ffb5d1c5cf54427a40f0810cfe24f405c6dcba0f5975106670e104a0f1b6ff6428cffa25cb2d9f8713dbb3000000000000000061060f0100000000c49c8ddc38cfe53986fd487fa5736405fb59828b5037381f64740522681465e44a8abf3c7fb18cefce9d02ef7429773b73bc898c7cdef533a1bf2539d14f5daaa1b5ce7747148b95ed860a8304656190d941d0db7cf83d7abd575450370ded3700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb4f187af42a78125f4c5fb204ef37534d17b2f66441a4bf2be9273646ac4857d82a8efd43c78d778f5faaca01b54eba5a36d4c3844b4bc08e06a178bc37875e54114b2f18f910a2c7a57c1c515efd720d5b98ffa3d8ee4c5c6fb72351cffb4abeb2ca31a5944896c5d522d33928211c98430ef2e4ee42b9ced4c40a52e9e88d0207e21dbd6348ac17c7a15adcfa6feec9fbdfa14349ba91d2ea14e983902853b303193fb9e76ae3d9d015dc5223f0fe0fa91b5cec0503259cbe0ebedb73e373ac0d0a031f08999d957544e7caaf3339dcda8ccb4d2073ad756397ba55901aa78167502ba7fc454380c14c771273e9dba7ee26ff3081a4a935ac50830ccf394658ea03030e9c94905c05da0baf68333f9a889572dea012e5feac6de63f9d24cc1226266f020ecc5c6efd2294d9eb2bb6addacd5f0b2d699b393a8abccb639c81a03ade844b0311987cf26ac24c26d852ba3101e68de0c55645c98e44d2fa041bdc95e7e6d55b032046b532797e7aaa8d0412810afd1688b6918ad4f7532a58ee891c87d897226302284ce026423885d88c4e7e7b559a6a285b5d746be2b5a48b11e6e1a17816f2560a2f83aa54703738fb598197e29ce82e93942d83733859a7fc595e9e1ccf540b4ebf264006a489dbf2f1aca99267f4790e357349c6d2992475b016673a6c1b006f158b086b6d3d612eff30ca6f5af00a49e884e5792972bba19f0262bf859a4800d65898ed6ba2597e2f88f72f5a1f3d07dba6cd3bfc71822166a45f14133cd9b6dd1e9e853f94d5bb132ba09c6ec60b7defacf6251c1a6cd6022c431dc7bd7dbaedb732ef39b37916dd609f24dda32d21b5dfe67790537c086406966b181b2ff2aa861ccd8232c52d55e739a6b6a988fd629468a00c08811cb0b5bbf1bf3e14d72bef5af12915d1354e818d902664f60842ad808e2816a5201feb695790c1d21c2ab4dac678cad48f946e0a160faad4ae1e7fa86f2449f4086d3866a34a282d31f4dad680fe5bb088b41790e6757e0e3b4cf00117da6cb4fcd3551954a7459ca2d61b1097abaca512c33fff400ab0bbf987ad35c1bf8dd9039dc060520e3b4483b22d4722f5516f84a806f15160c88537e8aae3afcd637cc58e8882a033797452d2e0441a15fe3d2f3ac76f0f32ff63708f1e68a1869addb2344df940376fcc0b1a95c37a27583d2a84080a185c00a81ef7d726e0fbf135e8331f09484f4a9d823c50babf33beec2985a71d9006b78c60cc44761092f82c93be7e200dd48b28865f20586bf5c382bc04d1e460ad29f49825e02c9182585c2bc670e21d623a4451902ff03c06e75e9de8385174b799376f34e07cb2933053c14dda6936c9dc7d292be56e178270a3d52c988e9a6a84926d0daa1838069e26e378d03311403bcd2cc4327df86c42d71ea3c8849e2f40521e76c8e3ba22991e8ec724a62801ea0da8f542863c33734edc5b043f0deee43fb7e503841850e21e1afda0fb03f534fa664ab7bc0d967cae323e17068ff06a1c4fe2db3fe05e18c2f63fecdaf216341d6ef9e25c85b7236b63a8f142ec67405f4942f4b572eec98149416dbc5a52a20dd4828d8d1080c4193b2e68c733d28a44edc08a3ec3cdbd99e0827ec9a7ce3b769e0e879dffd8575320ac43c6fc922781918575d02580af9044d408503402a5523575e64fbace3ff418a331db7fe21ab98da44811e2a66765fa2c04c4cea9d138c4a539ca73b6f0e224eac33d9bbd35a3d3227b3435b0e08a57b9be9212380d78186a58db7b411e83b51e5f58895e4f0bdf3ec3cf71b1357d53454fa0058f87140832d35d81065b3da0a6a8ee603592be15fda1763a7b6738576aba93978042a4b6fb0f0140ec4e95fecf8d806d398c0f3e4ec841b8ee98df022b5243e634c3e07179aaec1d7ca4b9c98870ece30d126178313ebce3c1592a2ce1660295f3f84ee0414f1a66bccab470b40bcb1dcb1741d3baf9bf3d3472f7863eada3dee0c1631c2a9b1e7b745a65ce291f07b054ff8ac3e5b3f56a74dd41596fa4db99835c5f952e367b6e964bb93b8837b6d8b456b38fa89cb3020c13cf32735d19afe0e3adfb8ad79c934ee51a43b6eaf14a344fff0265122768b891fe3b76be9128dcddfacefd2538c631bb063207d36e834fd6fd7087722b38252191f9c59172839ef5c13d230514bd7d25014d0238cbee91aacbdd22edb78cf68a8961e66dfd26c13c7820434ceaaf6c57a2d7db8b43d3271ba38ab2a2a09cc9887f342c977dee0049fa2b8897a7f0872dc879e0f5939f610cc51bc30000000000000000703a560400000000b4cd80fa7e467b58ebd8a8b1184177b31f500d2cda4a6b5f90f28f2b218c0e96b2ca02d3348f942b70cae0e7cbd538f35cb97a7f11624be1b21c123395543d83d83f8f48cc650fea4da3833dc8b9cab2d4d6c72f185a49aab1e7d2714d723bb1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005979b39518ba30c4c13b8644add18ac10377a50aeca0a0a66e060b07f35442d7747bf5f0f6d0c6ca9690a37c50fb964c3c419dc6e8c5edb2224d4eb3b8e5a7382bc6353cdfaef82427d9b477712e41ad07649c1e56cc7a92654a5608b55dc13ce34d8c8363def8021c401e87bce2798cdc44cc84f58a8d22218863d7d0cc54110202b43d6fcc748374bf0cdbfa6c03b54bd24fe8823163e2e55d45c3b0265e7dc9020683a6dc6406747bde1c1ff77bd739a27236af0c57f90cc843d9a4377c841c480b0b8e86600b2e08f634a11ad3feb4b2364300f5b78cf2b283d2330be9bd08584f2e3d24dab1aa036feab67703336e7120e10f5918d882ec60e1eff8a386d04487022efa4b50a4e208a4124998510505dbd8f29eabed8c2a63b8b90af7485121a9a903103b4f1d4bfb4f3314fa8b43bc865d45ad21d20bc7e3ab94199f61eaa1b73aa0032ddef1286be8f1fcf5721a0b1536fcbc6866c41623ba5840a46ad7ef63481a57021bc9a89c3a6fd3172b9bef3878b1f81e48736b68142b853383e84e5fcc8cc7fd030da93cf23a50e2e8a4ff32cb0b1ec6a13263e20c87257f9e1eb05535a13d969e120d5072baf4f6f66e0c0e19e94fc63dce9b4653f9c7badd4c5e3f0b454f014b4302b318501f5c7056508208299715f40b31b98cc7a262c408aa1b4c6dcb4c8189d93ddd26e0306b4bce8c59789d8bd624d43952b836bc97be6dc88bd05efd714b0d199ce064e61aa33d4762b788d57127ff2d929aa4917c3d948ca5f955cca46b1b563f6e878ea1c3b83dde60762060dee8057de517b756aacbd2060ce9d5e227ed587e3d52e861c91ce6e25fc14682a9f9d63ac465286c2476e25904a3e6e46ee567583c4a95821d620d6a1db247ed9c171804facbb6c7d8ced34f5f7f29fe7aa9bb0783b237a0e6cf2fabd0b33a3229e0647ac23877232bfac1c227486eb5e8555dcd140aa8749c83dd851245c8b9efde686a820d19d58b24dad8c6cb92b31b53e3d8d3458e42b8a3a53799bb783e6f9c5cfe10a172c11125c36d0ba84f655595348f51089a09392cb6929d70b7ac4adaff62f1d6a0f0902785a08420242e05616ae428de339e78c4c6b46102831fa00b571301615996d1fe47e1bd46409046f792152bc409c3e134b531ed9903f81227b6bbe8e19110cf2787f1e69029f3b647f78e74f085cb5e1afba2beb3dc8d4ea6a352c0aa9b73e51dbed6c92241d8588032e7c3f1483dd2680a336ac95ef743c49108233cbd4954fe5aa497aa4426f94bdab9d1990c55665561f7ef8efbfbc184af4dc9b0ef3a676217117f19e0b5f6c0961912983c46c5eac07af673f324d036c3eeeecbe8e4a42c0e6d1225e994d20603959e0670898622241ef3758eb25ecc485344ca5d3fae029a39d6e0e4a0a09926f97813698564fd333eaed5f9eb6878c14bb468de53677874f986d81a9ac0f73b3dff5aa37769ff66aeea7278eb27aa5f5c1873d0280082c989a889eec582a21e3145604ad867959b000bb05759554f3f81c6af10961e0a1098247df616a87d010080e84dd5a424d2dc15778b593ce8707d8bc5e6e9244df8d7485f0431ea009dcd62a9bb9be26824d5de12bb83778d86e4e20d5c2c9ac38bd8f7f8235c6ae10c4bc532cf934568cd8deda6b85e96032cbb3bd5a6adf7039db402c30783b8cfe8c48867120e9323c19657c6af61b371a5e82b4031ef2749483accb6b5546f58470e2aabe2e1b6ed07af89dc76eedf15d467a5f3219127904b19d993046250a1b1a6d6b59a9f301b639d403969abe1f3c671856120695643a1fc46110679dd7d013afb0a2df1c290cdbad8780318151bddd048a1a2b3622af5fff5b1a9a1e1446df823e67d4e625c2a22411989866f9b14729184fe8e29bd6382554daf9822e0331dad7fb0bf5db45696bea0f0de86d7f87b965d324b27716b6bb402eb3152ee26a5195f8da741e38064e812d8d9ea3da5a3324b2b3c15f3b7e93ab3f00224e3616d31c65aae1449ab79d934b7897e77312676023686549071d24162558542202a6c933e729581f6b0d7ef447a22d6d185dc194e6c2c5cad389350539b0088a6fe9d53d63f4aa3a2768774446de7d6e6f5edf346ab65bc5385dd46b0407680c062baa157ab9962bd17299cd42e6742f2c929c1a06783a3287822020e78e0a1921eed5be2b897050dc38d7a7a0edeb95527d7cdfc56b95866fe52c14416c1a1595d72cf6c0ad9df910eb6923231b1ac2fd48e621613bbd137ca33d24ccb06eeac1fd993c231760fba44b9d46b7f704a61f51f0d72a018de4c26e1f2ba57654b4222ac62a263e649d0fed5ad5eaa875da6ff6265e89de92cbcc85f0a150e9837c7177d7b6024e8fcb062172c02511e0ac5d3923942ca6196bccce532c4eab076055b15e01a21e65501df902714aabfb808", "", 1, -813602244, "7083eece9646196e0b4f6f8db28e41d176ecbb03322f4c9f0b04a3ff89eac319"], - ["5ea4c489016714f3a65e6f273cf22e01357b0fa681aeab47414fa1744037b338ac7924022d0200000002536affffffff01a95b080200000000096a5253acab6aab6aac95fd3187", "63", 0, 1986878410, "53759258d0dc155db40aaccc7b34fe5b4f49d9fd57ba2f463ba04ef96873b019"], - ["d7f958360358ce3260c199ebba36c293fc660200577f629d6074149812495b0e994358c4fd0100000008636563526563acabec1e706f68b3d2b8de3ed03c6aa6d294dc3f02e8dca7f8c7df58d8f77020507374838cbb0200000003655352f89a0cd208c36ab6dfa02fc53f11a5576643bb28e60a08e0c5f59f18fd38fb983f9e23160100000008ac51526aac53656affffffff02ded5f800000000000552acac656ae3c93d010000000008ab65acac5163abacf6e2847600", "", 0, 1781783393, "84ff06f6522caddc6514b0844d8cb269f43c2634f6a0e3faa4dbb4594cf5c151"], - ["a72d7d1e017d68dbcf34506b073ad6ca2eaad4a629b6d975b7493b549c04510d6457bbd7b70200000003acababd8e95ba00400ca2002000000000752ab5165000051c93bed05000000000019b7ca0400000000086a6aab516a00005239e2a60200000000095253006a006a635363000000000200000000000000009c085c03000000003a4f091eb383e9aa0ab3580ea6eea5dc24f4de0015105c9f80322a1374f23125a67b2cddf10507284234d07199011529aac869d3c2a124560eea8509fc7273d1cb565ddd2d406d287dd03795ce3fa64fff1b5af2c5bf71c036e966d1fc86f062000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008aa1483da628d8e68eba1e2326b5363149371d7672c907dd5577b4885f69719562ef7f59c16131141517084f9ab75be263d929cef077244fb63c71557e08d96a7a1f8a48f016ffd838d858ee08487409d389dc1c511233852a1213bdeb8c93abfc32904998378c8aa1b2447c7213557f113d9ffe6efb64ca80a436b466ceb2500323460bc1f9550cce564fbc5135600a5f37f654ed797e61d85b8a6c919c807232032810ae34212019e50a5fe9d667685ea7b849a69137b2f8b0d806f09d19aea6ea0a19e256d5bdf94a3f1fe69710778b53338dda20d60cbd7eb92c411a35544d093e1ff4ef2e2b66c07bb05e7e48272587d1b331ab41c32f2963ae6986686027acbd0315db3710f5aca07c82027347527b3951642d3e42fd3f05bf568429af2806e12a02299553e3b3fc00de0ae51918f623386cb348622b2cafcdf4995983ce14da2d14032355ec8a9977a439174b340c929973a64a6dc93f84225fc911265d671e72342d0301b373cee741bd55f8bd1ef8faa441549b423109bf972a44be1d06c4eefa7945020c1403592f95409e5ff957dec44ae6d107db6a59f3bf9c08aa46b1ff86f4d15238a4cc5b3f7b545abf88011e7bb324d8e082100646676c0f23576ff8c476fac2970f5cd9cae2c9f5d287452cb4319e848b3e0dc643372e5daea23a91b10d83aa7ffe5ba5b326a0f0d39462e082cacad0905b34efbca28c942fb2201f278892076b1b6a60348bc8c821835f7415f393baacecbb48b261da5dc92485986a14882e5ca9fe6d75982b05337fcb192c957738d5c434a7587c634e6283151aef4d00787ae813f427d751256abb2aa16c7c866e38dda635d869b8cd4c99716d0e6a78a294771015140224cd5cfd756154a7f1c921de433a477a21356beae799b2a04299b80e02231708a71a0c90b7f7261ef78ead100a07168a1cd622df77ef3256f9d28dd4aa07998bc651485a0e54c45cdbf7cfe6b93112db02f9fd5c84668cc289bcb4b47b8056b63113470b8a71499bfa80f981f41da79e00868b4e8e04e401e185606d965ada7d6c533c8f49dbbec14ab95be859c3634e0ac13f4d2db6cd2d00d55aed9eb95c62ed27e7ccf7038eeedbdedba67e20962419d54e392d1fbc796c52722888c9cf66ddf5fc6b00808e871daef29e2357fba08e480789d0590e759a00b622f08d5387267e84c3c57e95dad2dc4dc69931bc15fb64b6e8f96ac22851dfce7dc0c7f573bd486dd3630eac00391d11f49ae7fdf59b0c0f8cf6550a866b27cef66f64751df72407b2299f10cca1bf9f846c78ec64f8ea802b24bf3d13ddd0f4070d3024d345494b914f8d58695d4b1ba88261a4a7811a7c992e9eb35b82e84be4da9519defe94fbdc66c73a9d4207752cb8ea1f6fe946469d656f7283b759f3f3d83adf11c941858d0977785111acb8570a4e8877e41e0cafe038cd6f7b89dfe62299a6328b7af50e53a7f8d43c986e5ab53dd3048fa487504fbb96129e8a3ce45a0230584e6a2a83a05e4ee38d6ee957354fcd937b9937bbb284b5f8a3677714774ec9971e29adcfa4f494e50bf7d883b8bc87e348281d1e5e5da66482603369060786acd740b3a644fc95117f9a86098462a135c5be52b96954dd93676894ac129c4b8c97c4c794d8d3c6dde2ab0322bfa551f41f13176d3e1d0691601b4de53fe2d205dbd7fe978509d918b0b9f0d7d9e7aa8c60d867501481fbe1d2baa3f0140be5413aed26c70e9b883f120ecafcc1aa7ed4cdfd7aecdca734027576623ed46a5f16d8abc8f575d3143a2e16c6803db1e8ba8bbe68688026884934bf69fd58431857542e55fed9ea9fb6d8fc8d6f9adcf0dd09f674e6e976131fbc563220f6cb0dee7cf5350844b6d2b9f361961c3159aceeede01c26bed60ff252a090067d002db499af03af3e9b76accc1542e3f09dd609e94424b37aa8d5f783fcca1ca1763719d1a71180d95089811c58d0e2448605df87ec17780e39dc92933d8a63260a694a3b213433b5838880fd7e5b39441dccb350434c12e2e5a14cc08a1a5837634fa61b980bd9065b413b22c9e044e6718ffb3f7d8c746ba57dd12d5aa8661ea20dcde200e47bed161459fed4053e7df1288cbdde736986f66cba2d2af0c872d88c6ac2352fa099c4515c15185eb6060dd4cd5711cc3e55760409cdc5f58615afa6f6e1c4a043f6d8f377048be2e8d4818ebc92568ca676120099352572175f1ce77cc3bae1982bfdc4d92ff79d9aa35f2a1806c69f425a8afe458188a7e3edeb11936aeef5aedfad2b873f7a9e03bbabc50200000000000000000000000012950f3400ed62d552683039e6f379df179d4a8fb56bb3a13c3531e751d9c4b3cb4257f8456db00c91e2bf0e851705f8bb01a74f42c6d823451662809dd6829455387197053e0aee493ae26a6678f0e7e6d132215073f5d9cb0c353113067dca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000987bcd528e07c326be002b865eb2804727b514cb5cb3141d076d065c7a093b6dbe6395aea08301caa9243633feec82acd4b5aa5708e2a44ee2c9a68fed7671e2d85267c43fbf43029ebb2c4c10de089eeec3905526188355970e991066557cc73801e380484d2eb8312d8570f6c4807da7f771c35a866fb4cdd902010d0399840210b48b6cc8bf1e997b569a656d0c314055609f0b0cb20ce62c1f56778e9b4a60021321ec2f98473d6ee0e68a028ed759f99fe813db98b667cdf00e47d679c0dcef0b2684eda8557b63ea26ebce009ea71bb96508b625bf67a7969167bc3d10db0a7307f53c5709bd9d9406a8618a12eb51fbb7aaad86d9f5183d8282690ec490f1790322093591e37d1f059a1efc56e059ac54c31087d5937eacd4134305b00e617955022c69a876a424f352b7cc2db8c4a115ce8f41c9ea8ba41a8614c4c791cd8a54ed0322ea65fb1aafa8fdf1edda7e276c23afdde4892b189ec57d72673543fbe1320103005304dd3bd493b4e9ba08949bb231c4f5b2732e224c331874f1bebbc67cc13603043f371b5ecb48f712f7ddca4158e2e3ccd43f7050d34a7fc02bfd6671511f2c83a8114732c9a484c2b529b82b13ee5687e85708d4b4e4a8383d0f46f5f587b3108a70e198957e05bea648fd3acf3daa6e42b58827bfc2c7e6c919ffbf1edafdf1597268b16f3f9332c3816c9807add4901fdada55aad9803960c402062bac44f54bec6a97fa98cd755eee8c87c3528e25f8fae54eaec83c52770f3c2b5200b7d0abef7387ffe001e6f0f2c4e6ff9c98cd3fd457dc39b9a3bfe094749727ae9dc7f703834b1e0b5321f8d248b38452d7aa022b9d2de3f8bd2f9b0144a38d95e4ea7b5a273fb8971a2f46b9751f20bbfbccfc5a3fc530c2dd8fba50733817bc730fe83e61afc8f81ad2058538c4a7a4d7beebd0b12220ee98ae8e2a05165b328e38a80052560dd9410c353de3ba6a8f4d88e3dfb88e0d3c1eabb502b494514d46557320882271c3fe14a2f2f537b9de01b49eeb622cd16805258cba3b72691385f1126b9389c43df51cbdf7a7cbb6ffdd7821172a043ffd3a7541a24ad856ec5a22de1a7754b446239830fd58ca8be672d8cb4f45309a88ce1c422bb48941184c547918d949f4505d57e44239105ae74f205eddf4e41d2ed9e4e7318970e78541c7b41638333027e019242fe57a1cb85a6dcc8661a3b5e4d40e24e7a8d95a2611206ba63b1689aedac3490e53351fc105efc2cb57183db9b69ed310963fbd0f1169e3b606f5396bbc4eb1e7a821fc0b4c21865c9e93b8557d91a4480bb9f1a40c406d7e49526b2efc7aef71f4d5bd7032194eb4fd5d2232c171eeb65a304cb5897cc3d2dda35c1f57931773445ee7e5b9647f832c1eec30b7934e5de2103dbecb14bc31cd58f25946c3904fe56f11ef8a980fc76374905e988139ce41739f65b1317be26291f787e3926da63550132186dc997c12d8e42c5c575cf6b193d8562ee7f3f2d2251c1759b25f7fbbb4c814fe4a68de5372526c4a46a03d632bcf2ccd633bd7c7637339b774c8af5174d045b5a299a72748fc1446513014d8324c1c29b448eac36094023cafc30bc35a436acf2a6e941d80c9be18cd55cc532b2c7da79fbb52fd1f8bb94fd935210ed6bf7471f89e4b6bd1ca1b963b73099f3bb0d20e0ca571b0d6f6dc65a088cb555e8f4cbe7f1b6ec27778cc07dbd2cb38cd7fd3e6f15bc8c255a6ff3140250f9618946b5cde62eaf250120cfc74e096c504707399c96c93fb822683f1b57cac53899db4a7c00c5b36884c8f24c58b7b5062eea2e066752c3d4bf715b03cfa93da8ec1786bba2fe43fefa9c8b4c95e26b48da190beb3808062bcbab8f2e936da191184baaab34d84a2318903c78b9a432cd9512ac0796f0ebce937410331a01651a2976407d2b1661161733ad46c8338beb54e0e1fa3dea001877fb608bfedfb7107af4cc3096d8f86f86a10e94db4076b06eb0dfa1fee2228de863d9e6170fa93d626c65f18521db940a4afc4fd76c1fac543bdb95b39dbdaa8d74ea8710d25078ee431d0aa66b28b7b37f63c349bec05332f02639c952fc289f2c352e5ece2eadf2ff9d3494989e65af2147560b747621854846dce9bbfea2249f3cf41067150f0974a4461724213b00494aff114824538efdb72916bd41de188bb6f82c70a1d132ba496f651bdc980a8e662545942b0ff5f61a00daaf6e7dc1f8919825e6051ddb216829c33a93218b4626dfd5d642c30fbbacc7274d9a32a3702f8f4f46c42d9f2de5fb46334919cee98a87a70049baf4ed43fd47267bffef5830c14764ea7c347adb4e41fa61f815c95c05e9291269427186b983ae1caa852a25580f2059f139a9ba1a00774e89e8ccdf10022cf9b7f9dc028bebeee447692e49d4802b8fced18589adf0a", "51655265", 0, -525441219, "cfbe0a09eec11a0f693f276faa37f1cf8b6e7c764b1e825a7e695daec47e9666"], - ["f65015b3017dc69b6743e79bb838aef89bc7ef4ae0a26b050253f844e257830e4c3702978e0300000001abffffffff01f45f96000000000003acac5200000000", "005353535152006a53", 0, -302394150, "f1f1b20d8c6ce70d862e2e40b2778a130216ab8f4546d237fcf44641366e946f"], - ["398c7a17043b6ee9d7ec2641c492333e49aff0cca591c4f9ba82ce5d50981df5635bc19eae0200000000ffffffffed78927ab828aaace41ba45f264cbb946c4d19a7c2fc5cd69a342fdb13ddf4d00200000009ab525163acab6a5300ffffffff282c153cb9134c26fd83e5712e92f0810e2a6ea59674ebe5f29e31cece75f89b0200000006ac6a6aab6565ffffffffc65a583b29e9407779bc2b7fa4c59c2dc5cf3c51c259f2f4f7b24ec5b7c0695d0200000003ac5200ffffffff0137904a040000000007ab65656563630000000000010000000000000000cce64c0100000000368ab9891329b85b00547a9e90f619f1f6b1eb24bc4114dabf18743789017a19a8d556f55b18d786102e4c9c9d8f4a0982675d0132add9327aa295228af0ebc02235f0cb8315979f6f3e26504020ee4936800ab136c040596ff8c870ba74e23c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000890402268b5e02f469c884cc5b4488ced011ec28e8ad6926a3cf77e3d1c3e6cd8d5ff90c44b31338ba582ef376208a942375c5bf5687c0f93640588041cd99adccfd17cc63083e2b53b728c6fc6e3cb9a8be67f8ea323cf7a5aa99defa8eca66363f1c21e5ccd0607a63e991f56fa027be55f2422ec7a842a2d7e92afbfa4a490208d24fef37c53965e627ce2b031cebf47db3e1ec2fc47a7888f1572278a5d84f031cfaee7b72c3c99a34054feffdf105d79766633859b8bb171f80a4d9a29bd7630b154b6c53f9c497b19a7b474f1d705e9a23c29f074c9900c237da4a027e6548281ac8e1ca1ad388dd6c6584d6b71c05d2cd2c042858e7927335f8eccc54f4669002236d6c6515c22e5862d7187af7847fe7f07fa0a5057bbf8f5f75b57d05f4bbf703130fa40e100ebdc35786acd3f1d1c0980365fd8a8bda71bf318b40d6266a21ed0329767505ac9b9d9ee9d3433ace7c5790058926bba22366d0544adf7382bb343f0215d22823823284aba47fd34617bddf28f545241845a14d069b3475c78afb16490314971f36789b594717e5a7a8f1649c99c2369d23bb4b413ad422fb9c658d5146551280de397464163342b9256584e4cec002c5ed1fc641bd9af268b53e07911b1a44f63f7dfddf803b79dc3a319f1b5beea49b400bfdf4d7b552e735747322cc7c26cff7d64a14d29b465bf4056890cbb7c9c81464d4d82582d6d805568e132055d9143d1c068b13ca7375446cb46180d921d7b5c4f4b3c036142ad699555e46ca1c6c32b8309bdb33d531fefb59327d0a49bdad5e1f6396eee9792818c0852343870b3b386156d7087a50f11ebbbc185700c2a767f41d8a1a96ad80502cb8f7a45e8dbe7c4c5eec6ab7e746407a12ebe18735d358f2e9c55954dc2551ad141e751dbbdca86586f7e901dcbad341d3ca074f2e974aec8b634c332595e4c91f6261332decf7079e5a440cdb3e04e889e8bd0b8efe2648248e038b79bf73229c4a487ba0e07efb74f9aea35070e8cac550b6a5702e37b9335d72ab0673df8b7418d5d8e27ec9ae02b5619179d7b3080bddd88ef251abd6e34b1006e4d566ca1db304578544d8257d852edce03e3b60a6c1922930f09a868bf88fd3d444a20fa2a6d64ef7d16499acd94dac42f765a9b924534cc3d89adb09dbe82e3db435ccbb1398e2c7830536f16d8049eabb635720c27b29669a8b8072749d836a5526a9f13f53f227bf64f9236fe30cbfb9833c060a052e3bdee391d6753b219675651509a1d22484f70159a4a0756db0aa3dd69bd303c7009b69725918da4531dd021d46faefccbd34bf1611061f1763bad082d101b06ed31e4bbaccffccac2c3808adedf8d6313342e11816e8913dd1cc159baea4c701dc69b14e77dddfd149d2368d10a06057613cb7df8578afcf8f524cedd6c71959b9fb36983c01df2a06441dc8eafd4c905fa7e27831e63118e0b54ebeb8dd5dda99b59b22afe2221d27e5c606b659d116d65ca39825d8a65a417a44acad6cf9fce8a9d37e51c435087255f21b6f539cc04d8d790337e4c5702e648bb9b3204bf0b0fec16e2abd6774186bd15eb5e9bb75e6ce54d14d4ef6694ae305ed9cfdfdd03536958ccedb7c2cdfb9b698b88c43cc3665dd52ee7ad5e47651574d3cd91a7648a5ebe1830e1c22fa0711aaaf5c0466afc4afef98fb181da81bd88b3a9afcca084335cbb3242d9f4d7a1b7ea50b7c1c87cc4374175dc53c26b2d24ffd8558a8ea997f54b68c0b4f96dd55d27fc468508f4021f5cd7c1f3d9dce7e1581aea4058c50a3cabd6685ab20eb5a2c9a675a3c1f7f8bd5c799309befc898be9ac82bfb5b50bbea527481e5e590222ec335d156a6669028bdc98c1b4bb436867258cbb76001d2869f47e555303eca51c8b86ac22f6a08afda538b934745e00e6f141971c4475f840c3e935a6feae15f1ac0cb656b895e6146c35c85843bcce40f2ad6d44637cd6fb0e05e582420b046176b8d3a2f656a58bf2aab13ad109308683b8252ff9f29838fafb3fc59914bd6952526c2db233f9667b6e9d1cf1309356eea129b2aa6f856dd20e23ff741a213fe38357f842c4bdb1649444c5c6cae52ecafd3d0515a40bc25d7c4e788ddbc80919c31e7a7f7819eb2375d627e861946ad4edd5b0dc2def9b2d1991827318004dc6c47e1b25d739a78101d015aaba99cafe7530205c40562ab00ad4e5b0bc7ea2cbdb5cdb1da4e3514ed153b1fe17ac80405880980aed98b13c7beee8a0ca654817803397fb61e29bb80961b311a7bc3ab9a6a7489498e9b378947d3a56b898e743ea6bbe86cfa1457bfed40d2b0259fe106346c8151d8113cee2c653d8217fb08b17cfcc0ee478d5ce72600cb2128f931356fc7de13722381fc9356b9e7b3b74250b427bb01b8bd8cb8a79bc7acb687c81cda08", "5300ac", 3, 1173390327, "affa86ec3013bbec718a0dba9289cd7deca7f86e7248b6a7adbfa17eca735d97"], - ["fb3cd34b038db8d5f5486b48406a158fe90f385ebb36fe43b2d1ebe60d069e72adfb88b7de0300000008656563005152656a2db27e801657175d7c2780d1bb43fb99b88a80bd9e3ee580e829a715fc11777f205e28080300000009536363655200526351fffffffff4de5a3ce1aeb91ccd9840c799b57a837894f8c231bdb8e922bed6a6db23f64b00000000065252ab530063ffffffff0148ae02000000000005526aac535100000000024acb5b0100000000000000000000000062e9b57efd06e7adcdc5dca9b5d669ebbf3ad383f2dd9794b1d38d52b91a8f0e3ae4fd15b22494a043c1a326dc6d1aae103e2fe5e8e1c32899e7d3e24f0257024e0a4f9d3ced9578910ea62781616535d69de5bd83af55dbb6047b821a4eaa460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012edbcbbd9f3e70287d7db7467c25d42f7a398d24ee97bcf0e5b79c51c7a84cf055fe123641f912788291e6549b1241e9b305cfd5fc97a256bd953229e3b627a79ffb084dddc135c5197649040838c49ad6261cd0020ff85fb4497bb6bca801879d97b5ae044c3338e26402528f5c162617f4aa1333779ef635458316d472660032aa3b4ac31bf1a9ac64924cee0d23a932d84f0fc168013db443754069df3a99e032ab3853086683261620f8128fdfe84695e44890d045d583b955c16aad3e1e5820a02e7685bdf3c95c058ee796e35ac38b26bf1b2b21bff20266145f7b3ebd0d7b71108d36b3f1691e3c755bc1fb989fbb13a5b0691e36098d94b028966afc241970208456f2e6dbdd48470ca8b5d2478967cd2f0d120ecc3ee129aa285df40f0f33b0315137d1b5c75452f60a7feb1e824cb5317229003fe9ba3bf85d5a7f598aa83b403245121107a4c06bab76b55d2e03ac9c0cca49f20b9fd3ff7b60f7ffe6c87756b02034e5bfb3407b2a1b436c899ff5432cb22d525c680b2cce874a632fd27bdc0b1031728d5eeaa7ac535a1f656c4f5a3822ecfe3c5bd4c65a35f422d20a55fe00bb85a9ed2c53a5e1db94b89440b1297985a8faa8291b0befeadb17681fe2c8c0aa387535b79491c8e51f9c19b8b66ba9f9e1c362251c4378b762c15a7f3b9df101572933d939d3baf0497e2b0b3fc1403161cdda7ebfb5fe84865f9128ed177b39a54d83071184e059de0ef19f65ffb462add38442734cbf261340c4e4008ca259a08c6333a7a562498b5a57dada72e894926a40ffbba99e8b95d91bcdce5482764f353dbb3fb8724096d4a1dc6367f95ff617eacb2ec1a520674584ae708035c25ab6dd78aee9e8d3ddc26af42582df2c6a0855f71827b41040970ec1e37e1cf516107f10fa70cb7f8c25f93e812def78bac643bef7079876e6e63701823656100b753aeaab1b1791fb336326f33ae0af46d18a5bb23d520cd93d677584df271aad8ee2361873623e2e2963e99472ab4d6394de87add71de2822efa2a232b5aa6a03739d57514598d4ceb711978a3e3f39ddca115deee210e03abb53e3e53942d887bd8baf3b152bb7dbe2913132e875c6acd5d5d9386f403ea32132ef57fea4abf2a539859b6eaff30acd352ed8ecacea8fa5c28bc133f7e99a6ad248108ac052292c788ba963abaf41a484f74c81aa8a2cfc17184cb4049f3ebdb3aa1f1af2fe27fcb48b42f1c367851ce2a4817d619f8e2a0b767abb150723b6045d8750245d4d495364a27eaa20a464ce75a0ef8631a662e8924e86b206ec1f93d58d412a8b1a6e60b0ccf0e9b88162fe7b0e53c5c9982ccefcb9ae5889f9a2f20cf0e8aa9aa9160fb21753030529615c7a04c718e3906d297dde6c3b0506889b19a00d2eb7b8c0bf24eb46ab88486c5ab6f7545e085e763cf75b62493fec611dfe3302d93b8b332c8b42f481d0fbc38db996af57fb619d2d7266bac7e007228e6d2d1e931f400c02e885a047f8765cc70f6a2f05c05a2e39a428c3058224f1addaa92a3eb5b74b84b311c124e95782ed7f51990d94b7eb4fedd7c816ec71b3822285fbd397d911f232432c2b106c451b77e03abc8b850b41de42caebf19def9bd2528ba174abbc6cafd0289a9c9112c2f541f312d67b8980ae7ce3d6cce0de61dd5b1781d9cb5e7d3e4ce67c2fd3fcfc77548cb08b32e98058789801a49f59a32b44995372ee6aaf8e8d1db1e00418fb71beb8e18d481c34c4e7d2f801a53ca119f698fb7964b86e8a5cde6c13b49afcac9bec19bed2b291639cde42b507256b68bab99cb6101cac9b8a49590c7bc51303b4bb1895647156ea2362947ee992b357ab617b755a823a2fc4d1a4dd8fd2e81c4761717969ad4c74a6a01c969e12eabef05519dfc70a64b8aeba5474b9c541ab1868dd71e62c9f45c30f5219a6411d0de0ca03ea65a91b72e755fe3d4dd3973fa6fe48b143b878f52668b39502fdc128209bc02added2682b52e9bf5e1c20353c0ed8e1098186587a394c877d5f64a47e5305da666ee4aefb387a30c3a1c9d4afb5573145a78aea8e22a611ef3e3a752944d15a89a494494f611f8e0d7f501028e333a4055423368e7178e983b72ad1936257b85685d1e21f8f24227f256aaccb2d2bf41f3a3b621849ddbc0b5b65d95e3f15efb59135c80beac4c25546473700586b8873b15d0e2940999167725c89eaf9a5146eaf6d893378e2a1468dd195a536388a42436243e6f44ace743b7f9e1ca0270db31ef0def8e3a95dcfaf23071246c07582efe0000000000000000d9e0fe030000000018f9c49112db256448a397df0c055157a0aead4515c4609e17ce6e5b881c9ebeb8247c17c4e9d56517af9a83057b93c9015bf3f02b7ee3df4228cc138d6d3d3f9fe7d8f7db55153fa5eca89a1aa5fa51a3095817e0e2fb2a6aa093d5d3eb494100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eaa44fb89fef41ea55ee82583c38302b338b0992cd7ef32c5e3107f131d9e490c996d995a48e152c06d757d572f9a87159d6c8dbd16c731bdcd0837e8a620cbf4590a022b67d05097f07c2a4fcd155baee2441e43b90c914e43071a4c5226347d22492c352d17efdcdbb95d673cf2c980eac16e56cdc2a41bc6448178f6bef060207a1334247cec9e557e7625c200aea1e88d49dcdb1c371438195ea2de3f63c550313d999111c62d0161c2722ab859b95475b71c5a85e9858cc909c72d99ab4b5ff0a17926b5825846dd414d9d32a734314e2f92df3b29ef20cc2857194e165c81fb60ee5df53e01830d389629e7296bddf1246cf77619f2a568faca11cea4013d1240311b41815d3cae9041a1869001ca09236886e44325a8329ac7d964aa5161121980226b111d5a1fab1f016b5109920bc60fdd977c1ba2970038ea21ad51129b0bab803085c358d17a2b026835d3cefe8fd7db5dd931a099fd6eee3f4ac152668a412050315745d6d6f07328bb425bd731dcb40d27097ec26b0fc498b8df9a4be283f559f0327574a248befcf9268291b386f634fb589c607ec4f235786eca43058625bece36a98848b357c8c0e485a7190bb5abe79cd918e0a20bc7951018714df227d3a376b5f0977d5beedc3243f07de065991b583ef46c5a322b62bb1a2dd2af345548b416a4aae20fbc200978817cd6ee4a715fe2fe909d528bc8e3e48185e75baeb7ecc0b50a09e7ddaa8b0ff027316f0f0a9e1dbeedb4639afe334f2025c9cfbdeda46e176ba5f63d49d6cc7b2184bbd05d94e7761c136406ba636673bfb886bb60690d352a8e49425d7979d8babf78c4dbfa4dc105518879400a913825b8a65b77ecb4a8620d154795118ffd82201734e52662ffd818973ff98865de5e6a0653f7d2b1ef333b250a6a166dc86b488413ba782e5c465de887fca598238aceca40fb2c522ce23fba46fb4b57644fd489207f11b37aa1ba24c9d01cee69534df6b5a1980c0fe46edf1d457ff8a81023c8c72a105ee501b191639a371692a92e7e820c31dd1778f90d538c58d78b79f6c38d647eec2b7468855962f614ee7f760f6f288f015ecf221f9b8b8ff0e5c6cc124c153771474c82e36129055304902a8a80a22c683f587f1c97743e1757bb9eaeea948c0a58a0a8569aaf124c0fd42e286c5d7a8a1e8095fcc9378d272b8df159f477e790592a38dedbbb8376d8f8ab56689867e822223d50ff907456a59aa127cb9df3745958eaed4f1d5a42d7b4b0b5b730b322e22519bdf3add4884f2f3a096b15bf32706c3165d6fd4b6eff60e84b23fc6b9e130d39ed24345c3ea59f83cb9331a697425a2d760a1483f3602a96ea44c21bd93a65b6f4cc7d4d0727596869868273f58c8750cf180d8451b8576a87035c860d7b43caef4249637a7b17da5207f7d6ea5db839a7e1facbc1c93bdb425a11715f7387caf4e1062230cf2631eaa24987dee0dd1d1b3988c40ee8cb1d62b4e44aec140cbc87b00b344594a3f7467705939c613050ce22b879f43356c89b0c6bd5d906333e3e1d1dc62b654c187619196a56f55543d069a38ecb50a9144c8fcc64d93161344ddc78c4c822f72f069ec8074d5e1277597fc010d5e133cc1e53991cc220de915ec53bf2937d02746642bbf91a353a90ec0a9236492bf8b521c627d2f2c9b20dd37d772e0314eb0f5c9b803b42b04bac1f8f190ba6ce451516137ccfd51c1af3a3bcc0b1df44c17f2a9e02b7dcbfd5c991d719e66bf484e9d28479be16ca2c67b28aeaf95aa6d322666a694d1f23a6bea05a4302ed367bc96170216976f2eaff74368b18283770b4888313adfdb08e7d7fa3658b0c724d56a107cc3b76ae80d98ace8d43cb48853d14b2050131f4f86e173c26e2e3a31c6c2903f86402bbe31d83d6c33b1cd9a280f787ef13899f8e80eb928956ba1ac998331e77328665cb2d34691ef7380d8ea038a7ae61b940b7f78160cdb853e21a91e70620299202bb3d1f20bbcc25d5e86bac30afd849e113f8205eb185c53b728014286c74c3fb3f7519029ecae5416d6ca673457630a8b9d5e4bcf247a9fa80cb8bc9102757efb8e1701d079e6df0095fb2ef2a74e879e1f3bd6439e343704845968ead749289700dafcbd75593b6a6ae06b8b3251cabadc68758c46cd44065463ea00e82416b1ac0261117eeaeea6b726946e58d17d5d9dce329d18d8a7f5e123238634feffa2654aa881823c9a4926d70be4fc0a91fb75a74e537098b8bd4a1f17058f3aaa364d90c13b8811a79fa18e6852fbf03b068d415f66ab0e9bd5b90aa77160257e1aa2f01ae604d123938ecfa89b7ee68f78ea7aa1b3c5aff4780f19585bbc18d2a5d3846661aa7f498bd5705b5a0f0e32a25c6db81de8f3afd48dc2822d61673861d9e4736a1702630f06f01c9d0e1c0e", "65", 0, -418714248, "591cecfafbca68740e991124da123d95f95e313da1f957c63f6540e3ab6e1a54"], - ["4833a89902352faeb4132ce88d89b3d894f20f2a92605cd136418c8ac7f0f87c7161c6e5d50000000004ac00ac52f1c7304e1c39400e7215abf70008a6aa6e7ad2d5aa5634ef6db67d057b36ffc8c801ca9e03000000066551006a6a6339aaccc30130114a0200000000030000ac895efa01", "636a5152", 1, -169617858, "d0f2e4714914fd6735301bb06b4240e8684c47bb6c170a1462167c0364995c24"], - ["c7e0db4e0130d96173e798b12f0b200eb5e9223fee3aac944f53ef7e417cb62885e847fa3c000000000700005365005200ffffffff045b89aa040000000001ab0b8dee03000000000753636300526a6aa14d3b00000000000100f4d48900000000000353516a00000000030000000000000000fe50eb0500000000c325257fc10dc9e14a15138bcafdad9b77a801dd48f62fd33a98b3965e68fa60879fcc9e5aff295a0702bea32b690b866d93a7c4386acc4f9c0cb4def6938404605a18f59c87007ca91fe74960b6b77135c94ce5b30a44baf451cabe11472dba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f3ef785006d864bd99722056f7091d25fcdd11a7fb744162dabbf7a9b90388c90aa7bcaf6b8c298f0f6e6c61174e7a23513248bbdb22d4f15fd92f3abc5f05e8dccc75bbd15e359f6bf12b3097cfe8bd2cea74d6266542df9338986b8b322ceb8dcd81d10c4b103c9a733ff6b0a6136fcbc84871bdf917e2be6b3fac039cbc60313af798c98a1ec0c7e9c9ef905177403d86898cc7e43cca15079a2fb426b713f030f26fb6d687eb3db4d3c5dc3686b3d0aaff32d61c8605cf7cc20406bf129205f0a1ef49d4c1713aba42ffb4dc88c845ca94f0a8c97cd2cb92700ac9b0cb244e096248929eb57f50b05dd01f63a77dd9afe054908d33a104a9a94bbc4ac6636dae70216bfe9b6fd30004f1dce37eb47cf7e771035eec0aa5e2a4f0eef5119557a7c850305854cc4e09289082bc14f69b1db86e8406ad72306649b24113eabe0ec13b019021adcf24b30310958e0db01d1964d7ae79e11163ee79dddb503455b43712848450305e2b49ac4621016ad56478f9046a4d8c162e3668ec88a0d8f15520870226e2d03156f3d8a7b0437abfdc31850c9306c010495385cf1bb6c709769d8a1620e67fddbec5ccb9aa78db04469abe5358434e05b291baa788c38f7f56ae5e28a116948f793f4dc031bae4a604d03f245f1962b5e1cfceba557c690d35fdf1d2c1007bb5511e8350c1c8822c9bf920b74564a9c51c43a0e5cc80e8b0bd248bf51b2f1551268e5ddbc44b43ab744501f55be9bb2b6e81415b441191c8f62142a06911f0a0362ebfb41d1c09532778e2d735acbeb3839691aaac63c48518dd28bc5eb04b12799c8e97fe144e263a0203d297a70dd4f1c4825258d601068fb8e74bf12e4a32920e0ef4418c1eefb9e0dbd6dff02f24257eb12ec1d8f5978cc915637599fc1565bc81c063eaee6f357b6cb471bfe31425dc01fefbd93dfaa25f517c1354537e3d4f36959853f7073090c51964a5c7a0faab24a829abbaa8879d311efdf8690acca4ef414bf9cde07ae5e9f118e9c96f112556b7cd0d1fa1c3e33d67919565c2f01fa051b22c4d323550be73ce2db8b26c20c7cce9ba3df65f8a87cdf941a2ae8f561d8903e01d2761b75dcbd7ee3f52e6445853990d18d9a77c7ce1d80055dcb3ec080c5e8784f7200a2503e290f35ef54c25596b7ef329d82e12a401f8f53a1cd323ba2b3250bc8223920185b65b48d7e0b800706f5212e6891f8e9f4c2912acfa538c51e53e9f331663353ab3755f0a17f3d9227e0d68382aa0051933a4f7ad2d3138194fa2de30bdab1de7c7db80e0fa4ac4069160e733a54169baa61eac7e34b288c3d1ecb6ee52220493c1ad0a6c14f48a960da0122b66b4c7e0a1b34e2e7b4efe25cd6c6ea9ccb7d757efad4ac1174dd2226930ab511e4390e149d2bd2593cfd69f7e017d12a972217b7d555a19b9c07becc057cdb4649ff6c490a06e59fc95ac7349446aca7f8de2a29bc4fa90cf372c2a31e1b14a06f36dab2d75a2c66bfba8ac8aa80fbb403ad340731e1e4a9b2c05bf6a1099847de84e56b5e3e1f242bb0c2dcb35d344a40765ef8f49b4e4d033bd486c006017ed390c11eb7a321f7a19bbc71439ad8cd1cab24608897174c4918732285ddbbb43bdbc6f445d5b8dcc3f6ad6086750baa75e6810aa51b61982a059e38d1e664b910e3df7308609fd3347e21ff5cf841431d74f26debecccec025574c819399a5b467bedfe4f982095bf5a8842b8cc7fe2b6da3bc60020981052bc598a6b01931199bab6c2974ed5a5801a0c034cb9199b4eeb4a2afa5ca3fe6ce42260331ce199426183cce03f276ae5229de948d115b9e918928a4b21f91390d7127bd68cd58c4b7cc5fb395b5ca9f5875a68110b88bd5cd86b80277987b43b47f9f3f34c4026329c6925f1afb03898e44194b5dd838cc12724e0607b17dca50e0b825591dc0154b90797973486513b9974f2ed156a7fb64b7f19eecd0786ff525434c3725cc56102d67dd22bd2996dcc7fe3bb3e54642f3bf02e4841dbf481453b75f2fcac72ed66fedc527091ac1ec2b21ecad048826f5384a9f6ef1e5ef110363b059f0042eb1d312a526db93782468ad3167e5b8d66e5bdcf75558bb09337c5663c23e302985d13546a412f4e7eafc7ea88192d521c4c49e989d3de94f39f0d2998c1a28a6d627f6232023a1a8b2e6a77b4e77fe4299da8a3e9e7e5912e161ffb171aadc1533e34ba6c77b5f29e1e37b1610cd4df8cdd5bbe41c6072ee0199b3047c4f06c70a2312047ebc6c6daf46521e217ee8a166f8e6a578156d6f285e700000000000000000000000000612094a44dbdfc0d7a2bf73917d6a881931a053b30f4fbd33f912ec497adb02342fa332ed9569fb9e4cef811a35b29550d78ca82fdff5f43edc5467e7624e61c3e53992ae17f604e7db622e9ed908f686889bfcb64f6f033d1b9c697b1b6809400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc4c2ac088ba5ed3091f14782203e72f77864a5b49b84ad3a4a11a4e5d86af07df944207c2e7f6c5fd18c31e59e6dcb657e3dec5756f29a6d4846d0796fc3e0572e6a22f8874f05329ea9f92f004c0efd4914ee68fb4e3765553d4eba81d7caa126aca8a84126624d089cd31d8b70d7139deb0fcd782bcc569d06639546778870305213819538fa97e3ad501a6acddf2ecb383cd494f218d9e3c16f7026d117e75032ab6b29602c63cd817917a87fac49603b3b7a5cd9aa5e779fbfde96006a841ad0a0eaff69b1b12cd5496d3a0a6f393f34ba8fa58f9ee9e3ee4144ee3113ed71b87169458153d3cf2ab8f4970a0ab5b5d115ecda04f0857ca34930cfee1e44ad9bb030d849f05f36a84356cfd4321e0be9369481be65167f74cba25c5dd7566e5ecc402070ac916563db9d7c3f4a38aa9192982aaec37779ea3efda9d59dd9ac706a2c6022260a91a6e3696bb85b3494209765f37032e9810a7ae0bd114c7d40d7abee3560312e15911e2572b9518b3d002f613f357f0f3fa355041741da59d72082d74dbd0020c6b868a38621f9365693b3eedc460292e5b7068503a449c258fef17ac999d8d1f44a70ff09f96ec8f8d8fd4412f1d0f633b20c773fa4da9696a7e1e71c856f9a85e06bb5f9e87b39fe75a160b21e318ae0268d82628b1ebb827aa5bfd33f0f915c6ad625fe81328964a28412646c75bdf88cae238a1604f5b8972aae1c25a83d58d6bdd53ec67078f3619cc4361d8555c644a85848fac472a5eb63fb3eedb216cbbec34cb137f625fcf9cfb71b26d5e40ae8c26cade09af6a1d0d3f8c0526aac59cb62b659a9e0f70d0572f4fb0430c7e40fb0dbb739d7a4538a8c8d6d112d58b41b3d7b39dd9a28202c2679d4d516d8a133bf6caa57d7c4db0f43885a9fda6c940855fdaf27cbc42563a6f8096fcc726c0b6eae5432f25b986095750acb8e005a68e13151aa67d9ccf1099d29ad3fee2745e315ce512a09f756462e974afe11a9efc62462fdd388ab2ea9c90b02bb03ca652cf9073284c5c97e31b404a653832d82d882b29395762ac1e0e4925869ead00d7dd5ee312ee071e59fdc4c1ab15dd1989f25d8428a3747a5cbfdf07077ac4bb1c499dcc52c4b1b89656e1e4ad07a5026af7d7ad95af820f4dd3c84578ea5016230ac7ac027111ff89824d2542994125caa7cf494ba696bf7ae5df4fed2f41aad648e099c8527a2d6610513c82b0da58056a17acd16da52ee2b638b4c0645bab67aaa9b0e63787455be599164d29e53e64aeee25076985a708fc5d12504d4a8db81017a5e5ca1f8dba711d7d74bafdbaec74ea6a0e26b89fb39116d8f1303d2f1a3dc1837ec5d68d3598913473a4903677423278a62dae77cfe2564b68ac3bff81e0523e181db6c83a51b6930bec49b444a86de27b0d3237ea3d90299cb39a55ed68c1fd6b5d65a7d8da72e12ed9761e9fd780aaeb6a1f6e402811f82bf57c0b360b4771baa484129f7055a2b3a5e05eef80f3a15d8f92d5ad537c4a931c6b32353f113df2a6fd2264a89187d676d60b32b18652d613ef951699faa07be5b0108cbc3b41ab538d4b0a900be10b65386a8c8e0338d3757c95e0aa20d7320ca6f251bc4136316725cd2d0e553b797e648777d11ca8ac8547bd9b98dc6b68189cd2b86bf310dec10471a10f0ca4a3a3f90657c7bc1aebbb1f747546d83baa4f9ce1b24170fbe1caed047baf8935b569eb0617640de32033d45cd18f500f425e30f589d9da06c03c26aac7751a8f63afc1cd9fa4efd9a48bab24252b248ebce7b33b3203f4eca8ae94f032206412488d0525dbb81aec713fd83a9c71ab3b3059d9e47e75c203c14ec2b65c611c5926175fdb5cfceafed16feb98df760666c893bff2beb71442a90964685805d9d0e68bb3861ea7aabf54beabe4f04684ec49e11d15057610dce3890d47f5150b16f837ac4daab7454282adce51e8e557b9e9a5ca8f55c159693a7e52e97db2c298ae3337677baa21fb2633227272a7d4a6b7bb659ec9c0e4f1180701ef02585a1d237aaac82429cd1ee8bbd03521bf2b6118daa65a4d72fce98a4e6d2ae89ab591141d8d6541dd87c7c2557e72069c0dd144f473d2785ace846ea1f0dcc65cc1fb7be0675481fb10d8cd25787adda2513ca8691d2a25f75db67033aa5c9616e49a8f7c6f0c60517f31d3fffd4dad0be9072350b19c4dd1577ca369f9f39e4592b59850403968a46062499960d79647894b85e1e09a8ad9a843ab210549898098b602797b9557aae160bbdefce2f074028b0dca52690000000000000000cd6cc5010000000043adb713a05b301f2c1ed393d1aeb9e4e7b8ad2aa7ca00bd1ef3f056f7cf132ac78a8b6db314fdc64772ec3f3a8782595e4bcc1780614dfdb035b9f496fad9241e5ebac521cfcdce6d7af3f97e03d2b6fc69766111432797c2b555fd5a3b324d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca8b6ec469ffe1f69b4c7df490dda03b681645c4fc7c3d3c29a0709d575b7c4ed064c5560b9b46a42f003ddeccfdc5c7a507d637c3052943ea9564acc1bf9776d7228cc53d036b272b2bee1257e47507171a4ef71530e474e99bbc7e911c77c8c881264a42c8e4bf8d53633ca94defc78c3df56800156306a778d80a8955d47e021dddc3e7fc9dce1c5cff57e92f8d9472e02d12b54e6e899bec68a47597fb3a57022132aa23a589c6a4fc60cb9c48bcf8134bc6085e06c0691d9d10e60f028014d90b08b9f91177cf686675c607a20ef5e6010313cfe365aeb4e6981821cf2ba594941c662c60edd1bee7a8d151506ec5570a43488cde56cd1d1798ba5bf0aa1469f202144ad5aa9f0d463755cc3ea19749c4f6018023644974cdbc4d96a6edcbffa86f0202128fd6371d58180ffa6de2005bd22e2cc96f4d12f37edab0093244e9af08630213787f36096747f72f56f665ec2bf14c5207bded787a93da0945d2ae12a0e1aa021132cbdb47f561fa0c920b1f2cf6343348efb2721a538f928ebfe2ad44ba481a031e909610d9c8fd704acd9455dbca9a9d54c5c1cbe738727c1d28941ac7c9c3c2395b413a9f1a9ff90b5f1bea2a780f19d79677008923a3168f6863346743cb32b7a80e28b547b16ecf7a524485c1b98618878381e5d7a8f8ebfb3f9ac375915fee4280365b8d1895bc3b4543172b312c4c04c086207ab8d4af55a2e6ec1354c83751eea6e29e7fa5e53c5dfad1347b4d5e2877d35745c7df446beee9e71c260c274066284b93fca95414efcef121bfd3e07758f7cfb39304a3bee32e95f043de0e89476a15ad37bbfe03db557ceb7ddd316ea0fe280990eca896f88e668647a23c8ad072596934f243043409d7f8ff76eb47a808d6dc4d96e47b62eb8a2c0926f412b00335180559a75455fe989f66e8b6f586abbefcf70009938af805c57c0846a150e4e7c70a40c5a474c2d8424ad93760c14c471ce479d1aca73f0bab8fb81faf0504e0e9f86a36fff97d661ba443a8a2191742380e7373389d97eb76d6599e580d697aa205665c699674b6adfe627c2d1493ece151bce065510187311d82e050a857d31b8c62e929b30f9d83017b9e2a406bc6f7a99f78866dc1b3ff0cdf883d18e0f1fa7fbcb0c9a3a0bbdfa3d48730cd61cb5bb91afd0b11bbf60ef579a3db0d03e9594e640f67cdbcf664b714e039b361514d5760a7096d341c216039dbcc8e28e58a497ad83bca3d495c60a8cec99d57a47e88cad9789216be262002af2245d04d53cc2b615064ac5c57d3b13b2979bc8ec39dea4bf9798c3819dfaef397989f11e50f8d76b92c798975c3d7eb16ca7e3235750812e04c579cca246be72ff87d6cb6d588b27280bc005994d03e0700db36514ff699fa588d3be74681996f546714d01a7fc5da1e6df8275f5f5bc929010010a7a05dab95add0ffe755b28f710c6d06ee14023257a6b6599d0a828b3e9b3dc98b634c0cf5ea5398dbafe3bed541514dfa8867db9f7ac88fbb4a2052930d3ca483380a8acb8842464b128503934f82ccc2bed49bdc09356eea52151094d21306c0108986545e35c99f7270cfaf38dba1bce76b79011f305e3cc71e50b7746697908093458cabab7719c6804d31f001468435c4f209233df30f72b4e8ad664128178a6c3fe0c9e3fb5dee618e841c01b02a86916522348085621d3cc5ec904e1ca52f35920c66957a56832cc99654cca222a2f0f40809afa95baf87bb09127ec180bfa72c12b21686b8004d204b52aa0f0871f9ef2c8c80095540adecc83c10b1eed3bfc927f77a65ab0f65e83b01f5252327805b53820d9a74ef8de95ee6dd763bc2643c216903c6678145fd76227dd9dcf6f2eff73790615a7952474b510a0b4ba8c223e0e8d76d3fc8b2c315b7628791b80b900ffe499c7b2883e7ddd2883027ba9504d569ea1f32b8e4aac33d6ccc52280b37e9d84b82e2c62bbc35a8982edc25e2259e389fa822d8053ba5e4e5abfffa92581858dbbc44dc31d7eeb42a3d3681d5ff3ff2b89d7a2888cf9ea0e60b1660290f234afbcc89fb22e1a23aa43700de41dd43eacd253ef1f00366644c991ec54124a3e73d2b2f1db75ec0e3c77fd3a50ce8f5ecec9092567ac78974410e88d5fb54104f98e99cb2a155384d22ed87748340b6f8e87456ad9ea42a163503f7a1df363733bf1d9f149fecd206d2528759f74dd12bba50e01e2df3d1ab9add569b0fd653870d8fa47faa5ca3eb592258f2d8b854d650d6c308b1923981f3e2cba6be5828621d93453175d4b2ba7f761ac75515a01995af05a6b9dcdeeb79caf224e721e5c0a6b914e1c8a3b8d25c4d4d88b0c4b76a81d15cdc1f0d7362ad9c13421bc3b90a9ad2d00fcae8c30bb569e6920ddfdf1841e5bf002c9f250dc2b8bc68fcff046a6d5d26a8f405", "6a", 0, 1898689840, "d3901dcdcca3c29910f29318864c39b2b6a5b09de414341c214ffff2ec285f23"], - ["6271506c011e74ff7a17e249207d4e91daf6c1825e0a7b018d2aa4b968636fd398300dcca70000000005655365006affffffff04bd0fc104000000000900ac65ac63536aab6311004b000000000008516a51536552656a7e4246000000000009ab53ab000063ab636ae2afb2050000000000e94596cf030000000000000000d2fe750400000000a13291c71bb1c0ab1a400d230722b8c0d8099a2c920147729ef75e54c2b82f48c838ed9eb179480e0bb4744548bbaf54a6fd52720adc91d3c5090636bd6fc1f9853de9be170a06e8fd0533300f8a5d0d354da8f6c25122843419d077e5b0e7fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003276e09df6f95109ac57f6bbf46d9ef323032fa17cd1745c77e7b99c922e85f3288af6d53c6822790f0415f4fd6ca2c6f04c33dfa888993c1d31fb87b190034a677bf8f21beecb4f8608869a3c0900333f8580a92651bd7b9009d953154967166b04a9b3635d1b29f706a3e48126d59b5d57a0cce8ef9c3f127db87deb2e9934021a48d0e68911f9f7b7510a86a1399e8ac99df67aec46915e423fce7cb14b671603247c949a6e39c309dc46253062da43c4fe0981ed7b0b516330c2c3ca505da7c60a26ee971b92759f695a3198f57ca56473d07733f5681e1624d9cac6a61d1a933b0729b1dd1d6828f0b4acbbb7820be39aca6202b357e087776cc64074f40cb89b032f3cf19b007180b262c07065f8b3a5857fa4cffd24714b06b8fb28730d9a4c100302d31993eed17be46a7003968c114b101e1dde2bbd15597939f7b07aabeb985f0220a29a31a40ef91b42742434d1cfded026068ed7a5fd6b69110a7f490f04064c030391d2c655bbd7337399188aeaf1ef602fc4d4d314de437e6496e86b323444f50229e7902f9af808074ed57360a512565891d1dc354e1cc4259c19559f26c559cd6edb33f35146392412d25881fcf97e8d27ae704ac872aacd4db166e25bd913f1605d14492c0d80efe8e671fb14f126efcc232fd32699b6e059488201da1038bf2bcd07109260cfd11d2b78ecc3ade82e96c13594c11932d417ed7e0cc30af7970edd2e2d87a8e812d9cc3de536766ab1e2c218801ac4127ce51ef75801c9b221c6b225fb340c7d6401c5cd771bdc6d1cd58665e6235a6ee374ebb7202f60d9f1390dcec0fb841f080794591aa056a7ad9da7c2256e7699cbcdce7807e6bd8e42deab71847032a58bd056f1bcf32cc1de805282c4a9e648d12b10b531cb94b541c33449d054f5aa9502bd2853fb2f80f61cc8ad4c9ffb981021b5136c233513e40ae239d58fd96050ff9bd3cb8db80b2a12c0bc3f0d139659a63feb07487c4994f903ce6d7783cd65b2822c647f45c8945ab7086686448b4621d93ca9a2284e2f58e8aa0509bc8705c184c402fedc4be1841952dc6f717e3212de995a6d98daaefe42b3f2d0064de2d0ce53d63f80af2d5180e6b0987026eb3ad34039ddab5307d54aecc394988f1aab4cac29faf102e8085adc399ecb6af314b1e43fe2cd405342df8ae5b21553b6b419f2cdfb82d748c96fc4e347c8d3f0070f029a65b7d771e14f0c83ddfdf15606e405bb5f6addee1645ec27a56b901447006e020324ab7d6e1504af8976b4f36c9bb12c799aa3952a9809de82186115a0f1f3651db275c066ba822035b1ee3b55fcadcbd76468603a1575577d0a308ab481c4941a9d507f2d7c9015867d4d4db101e49ddc3ff5b5e502e631c30fdff983227c5db671c69c086ab63947853356d901cad6fc7c90b1a3b22988cedc869f2787af819d467e134b71c920479368fc15df430109c1eab475bfc3837701bb0eecfc5e449b130819e578f87524ec667fab2b8f84808281d1065a0233968e7e0a9fd1b4552904ab4f8aadc1455cfee17f78a3fc16ab4b9b94af9ea71d0d084ab6e2c021d5b71f49c47542ff9ea19d2ac11cd71d5609721442de6eb1ef976784c87b3ac1f9e97b3566dd85be83c859b5aeaeb2a04f9daa6f488ace09a3e5dc0dfdf81b796354e01131962e478268520c542f28f6c2854124de98502aaeabe97536e064cd668555d9fb9abb5c0a6018221e4e7792620c219bb1fac4557b7b4d568c38a2b265763f55f8d073ae47337d5270f475125eefeb24f752656c0d66d6274c044c6131861905a4e6de5b716bd6072f2b4ed6253ca604367ea39f809c15c1ec7d78799e954c57f4199b904cd7d46059e3db9aab86672f092f823f23e65038a680e013119fa1fc7b719a5a3a9742a3c61541919acad7210319627665d91e000d699b1319de42aba733468a77bb3e29bb3aa3c2199d42dbaf228650645dd23352545ebae28180c199357a34d049f468ef47d52108b2f5b53e51de8d104170d33d7333bdc024a945f2a40a0cc1b4c1b09c8db948741c750a699d0686694ca4515b3bc80a869f55ed3f15148278545a9c842e046c3ce0d23765338e9aa874ca9c954425cde2fc988ea17a950df395b44263b74e94bc776ce83a45fb5f092d79bd9dc8a612d1419b3487fb9e54c39dc7f8d6494d36fcca8ad177699c043fe6c2b292f2d85bcfea5ec59074996a0a12308ddbdf1a81d806b7b115b7f9b8a8b9a11e22027f6d9bdf13366b38a5c0b29004c4ba7d595ddeaa821daee05f0000000000000000b0dc510500000000b190f0cfccf7e6e49d2e3c93e181d17fb20b752df74af6090a29141458fa976d9691d917bae2f2c2f1018ee76b777d89945e687e64aa7a398037558a0901ea5b628531b9effbc34775b749035dd58a17758ade93ae2c13791d65ceab2604c53f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031c8ce001c3faa3be73ef97aef44cb876ea5bad8104e5238271c5229b8fa33d658fdc43fb9a27b65fabcd316b0776338cbe5c177b246d7694947ea32f2b7ef5e76453b6e35d710c2956d00c03116b492c8deed9a89d0632cf16b145922e9551dfb269bb842cf4cdaffa01d39b8c176230b04100124171188ce191ad47951df42020819015e21e6bf1b4d32219cca8ae8c465a6309094201ede9b9a047846fa45c8030ae4bd8d03661b803cf87b3691cc3013506931755878652d0149aa6b5fcf04220b26aafaf52bdf88c5769dd320f52c27a3f5b61cdfb5939ec5e46d4268c7a526d70db76998a515e38c37f8aeb12f497c09d26b242285173f1afe5980c2dc2c09850300b5910d5824664a3a717019db7a185385410f0b19fb62600aa65d1fae7ea49b032737950916288acf4d8972107753d2c1d34a50b4967b3bd5b965a0c951c0846a02165ae3a030cec5d1efc479989f437ad46c6ed201522107eecdbeea84b77514020321692f9fa83090bf28a23fba43fc1f92fa1464cdc69a835842189ed532cd302a031724ce12409b3eaad73fc85e2f728d58a5d05c66b8179c7f85b2beb06c0a3b4d4d95dbc2ce03cc9761407feef28fad087301bc4cc3d2542f57468861f141c88e3dfe34c2ae39710f2c92bd6d0f4f46b3481a23b2202f5c1fa0519b9b297362079481ab42eb4a60e9dbd79e31efb905c015f3098256837d55a71c6ff3bd10b7b11a8ada0c24584dbdcdc5c9bd9bd9df25b5a03da5bbf500b53e54563b0f3e9c9064baa1ade2ea688ec2980790442771d1518c289df73d89aa6fffbe064fd9f8fe03bb76ca2f74a195f9cd590c9080bd8aa0fedc0266f54afe04ac746fd78f9a051d05ed96d7637cc7fe8d306e8cf41a8220a117d2120f985f0b8e6b99ba2fe7b7cae7c54ad16e2954c071b0ae922528b15e78e0a0a790b7304d5bc29ecb947a7bfa774c017da3e6757c14094251723ada8008ff607b67663842f704b33e58108ed7514c9521641f51646db809fdfdbb3ea9c55add903948cbb967a6607e1c0b8e6ab5b2b23522ea94defce4274b4423bc0300fc039e44cff871aba968a84d3bdf2f3b58e0ccc83b8cd655d8b3994af67abdf7a7016e432d1b3cf6692db7bec5cd56396caf195c5482450ef50d343883b27d023f8b0c1934c1bf0152465ac3592438510f5eea79a9e3129007c536f8b39d7dc989f721e225c8518bdf619bfa8b3d435d42d3b992280ccd527830068451874cc869f95052b8112a9413ea49a632451967c7d5239156d9d026dd7ae6126defb39c7e67979388c25141dcac57a6818b4642274c49cb432baac36547a9f5db9d0c4916465ac71c1fbe8333d0dae7116801744974804952d0a73513b92261c1e58a848a58b00a6e1f70a7d36f1d714c4739712edc91b7e840096585a01771e3a4c551181a16032c3cfa15fbb0e4de07f96987855ba910d14af8ef4a63f34ea72efd90628d3ba6d0d173924de735640cd18db5a0f1b304c6176efb708c36fb13ae6638d988bb9d631c478cb2f99c604ea4ef62b6734f8c3bf304cca9d057252ac7023d5abada1f40b695a92b38a604b47d494ca39adb8b623ef250e1506a1a92a9d96fa135369c9c4350dd843c2031287787ea385ae07e5d5df22147471fc87fa9cb2f0a0aba2ab52fb04556091b3a9dc147dd0213619d15774f2bdfe12b610d423a709b835225ba0c944e864c9cac123053eab9a6a8aefa7c0f22b733b257a748e4f945a28affd0d21d15ab29eeccb1cd4e38d997b18782f6cb35ddbe99280b52485d1d227df4345d5876bbd024524077242fd975ce61ae3f7a7f557c57775d96cb2a60a271a2cebd1577674f496a0f0fa31b4b416bedb38476ccf836c9de883745ba2adcd697a88f2ba966ab8351e42cdc056bfb7d62320f240af68b8a248abd2b4ce8ffda5b09f20446f2a36b946ef07b6be937a5b33d714f05b3702440883ce98e104f4bd236333f5d2ffff7d74a4c56a4faea7471382de9b99d66ca3075fc85fa247a2c333c8e8da2289acc119b2e2942b752be60920c8e9f4ddd6edd46a150bf20ee885ef899177f74811966c2bfceca2c04f28e3b7c74d854b1eb0f8784b7d41910499cb34c7e724c8162fc956ed446d2c3c41a93e577b9148eed42b91da353ccd98c49ac67709373eef9c692161019b8b18e10b04eae8b9e5928511551da3cb4a3c08b6e2a3377e1a371af8bf1619055bbabb3e4c7a1e245a5ba09c3187194da28e7ced19296518e179399430551692126e414ef3914dd306f29acb94345ff00000000000000009d639b0200000000c5692db1f406c09ba4a5e2b6e8c98dcf6610baa549649045dae3d6cdef0376fa0c775e74913ace2fee5d3102ca48b75d10d833035be27f955de5c7472af9bda7a0d27cbfd014946408a69da609415cb917c4122bfc2b01a00caad7eff4e4a8ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009854f1e1c7fae5bd041c362acc9d0e3eb0d7d709caa6e4c8b9be509d024dc48ed0c7613cea2cd166afa12dddb6593638577908dd74afc2e2de61eba2cce63b2c6144d8029ffd33aba8bdabfe51882d24978a456aa7ab82eb886d93adbab505fc91348cc4fd5cd1f19f246d25f2df21fd80aa01c05b09b9589261559be16697c90312f30a2d5c3392930f02366489e36c7598a9a6459c36eb2da9c433d30d14df35032aad753c29a150112f25725866d9390571e24ad2b882bc44a60f1b23505c7d890a2d316c1ae6092df636c384173ed4b16a173b32ca9ae43506bb16a452987aaa3100367225df1464c70739978208295c9dd567e97a37277978cc89b6bed234defa0218ff5cc8d0b84f891e89e87c2a095a436efa11a7fb67045cbe6d36cf8c03d298030c16cb367767d81e663f1e1be5fbf32a7114ce92e717aa2c6eb3791452da7234022d7b9b5eb253fb4803685448f7563918b22cf98663999d54089060ee247e1675030a14ad95a540519d2b79604c7bec35357d096ebcaabee2b495d0b3ecf353464303090f96bfdb5f90a7ae4dee215b6fa967a4a31548d228b7d8c8439556832ee5c029ad05b4956027f80a8729466222c1bd1bc3fcae63c0acb03869c61b8ff792e76c0e7dcd6db9458f1d33756efbde774836aef8e5128c7239cacae2d2b804446fdafc639f03ac75da6098dc23e101d6f705cba4e29c8a30531595f91aa7c0dcc629ada76359c0a085fba5e0866045855ec0fc69450cfa403bbadac7f3ac7d0bb6bb26278576c59ecba0d6ccd338d011aeba5db5ee7b7d453853fc871cd4512ff5d76ab0285b2b3bab5c2167a7f11fc0ce883787b7be6359e6c488794c2f0489bddeb87586a17e77f28471e4a694152aa0d4576dcb3f98f4600a4e6b640fae15687170327afa98c0399ad1b7d53e8536cfd1647dbca5adb940aa4ff81084df580106220b1b37b7a8b9c42ccec0676f0070c148b686cc838c679ca724586b4e448871288469e9c90fa2cdea509db5552574421dd64de39e164a9111f71bf8adf7984c94f35dfa931327b681a2f78a91e6ac78d4b39aa21e589603b2eb39f7bb1446e20042420eb1c5ada46f1d745259c5f2d03738e09cf1e2ecda4d0a33601b19cafdec51123d585fb69c15cba7e992f2f5f588b58b47de5f7e377129c6ea9e309c09d8e967a58824794ece5fd55109a200fef86e93a2ece84738a003df2d41c9cd41b93d5b78ae2aa551bc15f209678f3de22efb856a14ee123e3fc4eb2c9eadd39b966b1770cd205f9d6ae9bbf97f92eb2397ebc4da5dfa58a830b3874d46fcbb1db1fca2be33c909059bc412a84afff0b23e8493ab7fe9996ee2cedf4a04e27d797693a5fd79d8d085704960f2711a383a3e6290cf80fd7e201f17ed86c003e58c46bc0079d858de92acb3c19a20b1fc9f5f7579347f7180755a40e6c4b4f909fa1a746de222f9021794b9cf5416b2dc45e13b85a6d303c7ec8a80a43c5df1cd25be45409958c45982baba5bbfde0feeed94c50e4e7a4243e7023b7f2e4f23442fe5ff644dc94ad69119559117dad875f11de55c56324593178d553ab90b79bdc867c85ac2cda1dd29fb0645ac29addf69a29e7331157f253ebe2219e4d072914ad82702474f8e1fc2be00762b5106b989cb82414613e265501510ae083ca42b4a33c4f1fb1750452504f2ac2f2371c0e5e3ce676b6fe4debf5f2b6966965083145728c44eacde47185f7313ce185bc6745d778b9538a3b1b1ac852cd0ddabd35cf26721acd0011b3b7323d28794367f7d20fcf69b1c3787c4ddde563d32d037bb1c3efac7a27cf664203a441dbf26c824404127db4b4360aa0f5d83a191535bf60d8ca235c92169f8457fc6588ae7bcea61bb3974463474cb2d8bacea2458080a0fe1bf5e5deda46bfdbc53b42867816cc8d3f4e43e7ec017d3c169266ba8a85f8d235c107a9983ce65fd994f251691e6052f89640688c923aa95fee44e90cb6b9b26417dc5432f58830bd8810d2b65c77a69347d7ab51d24aadd081da0104293e1a43eae9d47ba1afb293e4da2388f395762a1d5c5a84fd7aacfdd80e386401ff09d9d99406b9706b30b8b52f322ea425a393c934b799dc7c9dcaef277599ce1426c00698e3c10c9c40f9656f478bcf272e6a3fab767a4d260bfcae6fb9d4da6e9f6f1a72206fff72dd2cfa0607e0dcb45fccef2c6f81bc18e838042cb1632f9b17b4f3b7b4474b15ccef364479c5ee2ed20652c262bf9a65cc1e7da994ae27fe6306222224e98045208bfd60652e11f607024198a4875fe6a558609b0118f261ac49efa69482d5efffc25f8a9dd4e03209d87ff93388a2a08c489f7d9a522c9879a272e3e175fd903c53359af3c9c56b3726c3a540b53974e9a5fa3e577413adc3c80da03477cd3ef4c6418876015a20e", "5363", 0, 82629267, "e5c96a29c8741adf85b3580713fbe4499a14049ccc07512fef94343ae37599e9"], - ["bf8a3b0804fa894753aca690320370387b6744f47b07957cb3618ab0fe293237c0e027d454030000000263527ae8824bab8fe5ff45a2b744c4920af7b4aa6ecfedcea45b9d3c727a20f57e3834e693860100000001655a47359092aa7b0a17edd287f314e73f87b136cfdcaa525df24176b879c4464aa9f72e640200000006525165520051ffffffff1339bf2d0e822564db4e6cd7a666588d03d844d89b1e6ed1563adf031d9ff707010000000963ab52ac6aabab52ac41a571ac011d777303000000000163917deb820199d3a504000000000000000000000000333442fbad01ca6a4998ee2b643010b8b60fd5a759cffb001c33168216f1eee6585b47e2b2eca4ea8c101d795467e8424599711c98e6f3a36aae85c580d6a74a8cb6347ab09f46e85ebfb45096efaa0cb20d80d78901a795b4bb3b6131d4024f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cffab9caa58f02b71ab422108027f57bf2872e902671438345c42fa75a357ea4ba2b1f09b3a254a94fd282d53dff281bb1b7b981c63fb0c80faa1c932183f2e7077edd64e8554d5f83862f97141294a8b6924d160119ed3dafb1a48d5b2269de94c42499eda9757add067e192bc93f3f760bf39c41eb54b7d393ba432baa4fdb0203d3e65db776171ff5338b973299b9df98ddf1743b4c942884075935a2f5ce9a021ce11bdbb6f7fc8f1b9a884efbc18e8cd9521576f4f272462433066919c0b5330b1167f732a871fcf8edc35006e6953bfbe2b044016766af1aa332a22315952429048697dad471c41319e42bd542b69f7948e63082f8ec4bceee5c4a770227dfcc0302454f927ac341a79823b46494b113afb2e53f1d59d0077f49e03e5571a7cf580310f667eed011852114cbf9d829b5b1f40d71ed9f9b4927c90977142df2f1481e032ccb3af40da681114c42e9995c33975b06383b2f586088d24ebf085453716387022ec5ef05bf07a5e190b0c3fa530ec5e30bdb96bdd82ad55acd25e6d80f7e6f64030cc1496cfb3d8051e70ebee344ff571e23a84685aa51edb28a36e5c4e58efa293b7e7de09cc264a952abbc669031b6da68646ad55ead97dc0ace0d0ef9c2857bc1f1c09bef4daaab5195a2503edc4c9a1ee5d3a413dcf8d5c00e0ebc1a5374bfe3e1981b6888db803ba0996e4775727c502e649e3a466fb6c71d9799472bac0fc49a4064eb6f9c009fb121f6a937fb5e2a653743ae20a9ea78e2a7fabc92c467523414d2ec8ded07b8c72b732f541113763d6a6b25f66c023e3f03c486aae8904aab3777d1d879920edae186206c82cbe44cd3103acf3186ad029af902bdcfc0b767c4a080ddb4b477d1fda7084b72ce45e37ec53159747a14d66eb44e8a15c2610ab3a32f6b28714b25d3b7fbcc516145ae29fe6b6735ad85477eef5b3228b5571eef93e887f9ecabe65c4324ae32ff1e9d432c683389533e00383ab70bfc019e033c74f64779c4ca46d548b2b46225300af3651c51faa495999f303e4060e66d21d51df7693ed08f5be1497409cc91fde9866d9e107008f6d983293f7ce96538eb808cfb76f990ceaca99476f2f31f27e1096ad37040ad3b83d15aa1bd50c0c026593ca09b5f041870d5eda29d21fb838704a6a32be1b6e0f97237038472207c3882c4ba96792189205cbebe5182d42a84a7ee153ba0066ba4e6b695190748017032ff91f7fd4570c8ffdae02c6d36ee0a9b522a935bcb5a603986f82ad72d0eb511eb698f85a708e4b6e23c163e93df74b2e18646420ac54cef1a05c237c7a53d362c3df11fd251ac40829280fa428d35bddd211ac5e0a9d9cf7a07bfe672e6600cd49bae0f61e1b3bc13b776d7ba8ff69d46ca1ca463caec80f5b4fcb88570172a0feae3b84da0c8d3a71db129551e16f736a2223b09fc3e5b02c857e97e5579f38cdc7104132d224059f9572145b5590bb8b0082c05076f983097829a5ad903adb2ee486b1a1cd2dcc25b4b5ddc7a635f93a2d3e6a358e7f1bd02681326eebf4141322f2bdab3ded4fecbd876a39267d1e3b638b1142696c31b0e26b3b327e49791dfe70e870e32da84b9c1d99cd5a42252a0e2ed3d92c09be596f8905e71878c94c5b4504e75df732f475356e335874aed20512508c08bd22ee1c3c50dceb0799f236780ecca9686475738b45d54c0951e40397e93c55a3f05e4d73e99d4a1c5669661bb662ca648b1ca778355e0b48df65e3203b6b88f0ec4ea47f51afd2846e23bf77b0cae4ce30f7f5f110dbda3ec289c851efa2c4d3f488778ac4a9b38cb6bb4d8a5080765aea1477a0af160ea770635ff3784c7dfef6f182370474d16d8ea4ba436a60d9b3cfd79f7d00b3ac7cc056a4a8bb364f0a310a1aa2285101ca9db5c0f1dbe758ef870f0c2953e8b1b664165a5bda567499399eb289ac688397726a318cb4c46e16b6135bcaf2cd64e160841288969fac690bdf3f26ca2352581e1468ccc98f31c8afda1e47cbe3244bc239f85b6c70661bdc6035ae31bc978f1fe2575fa19c5a1d6945b86bedbc5759a4f0c7c7347ffe76a4a9bb23c110bf82b39f71e0a161da1e247b102416df614ef4919a6f5eea6e2d865d1166dce80516940011c01ef76d7037a36ef03aa71904649054d2f577aab2913f2a3d97ca3c558a4864f27f5759af0b71eb66d6d5db6b3efbe8f1655c70fdfbd784f15b29ba850f6ca30bb961e4dbf47288a784d550d8a6d63649b409caa75d1da2a765ad7e6f01b1ff3b9464f4b88389358718f5dc09a74d39a95388f500e9c42e955b5e023d121fa9e5839b2ef78aaaa9dcdfdfdb332730bfd92983313a7be753a7c0af40c4fac78c82b7b36bdb73fc5045c768582f6e2143f9aab97e809cf5177884a64e79e8e579d921a93a84cfd752382acef07", "525353005165535365", 3, -604189762, "396e8d6b6673b8135c8ac29ff2dd9cee6827defbb16cb6cec54dcb0ec32a0af6"], - ["2ef30d77049f64dfdd155f1d5ff83ecec61fff15118ce1b075ecd26780c78a490b4ee22d470000000006515152ab6353ffffffff1c50142f3b7c13dd3344ab02b7bf0328dbf891df31e53340b725496950e0f42b0300000006536a006aabacffffffffe9ec38313be666250e9628a038282c74a03b5f04b478ed28c74d2c614309e5db0000000005536a515365ffffffff168e58b35ff97e828c478d3be2ab8b16e58a3a9b9f1ec5bbe7f1b0769415f0390200000006655200abab52ffffffff015658f0050000000009ac526365636a65ab530000000000", "655263526353", 2, 1787584635, "16712d42b278b33e1115b51b44b02f0c80cae74fea95b35a7f4a4ae8a7114d29"], - ["2948947004821f488a000d39c646da1c42cbbd76544b69a0f9e7c44ecbfcd43f46864f2ae70000000008ab516500ac51ab53a6b78ba7bf8c7e2a80c2f633bfcd15b3d1cad988ab1cdd103d2c009c6b08fbcbd12ffda801000000003def159327e776adfb7fd6742a98e65bbadf8a66cb1082db611bffa173b9c5af3777a206010000000153ffffffffd64cea1b805fb34081405f1a251e558452c4964213602d8c81ef0cfa60abda7301000000015267a3571f0394db530300000000096563ab65630052ac534dafa205000000000865ac52635365636584fb74050000000001acc3169f460100000000000000009ce1e7020000000002570c9d70b63953e8bd4b581c5ce59c6313f06e0db0be5ffdf408f292e4f92cebfe7c81c0ec26d956d1e69e819f8ec74cc18bbf1e3e0a3b2c611e5c3feb40fc73e4ea9d76b929262f268d7b9df0d9f06b32b7c539c24221dfa4df9d433c11e500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000449159acb66cff3c21fc9b8babfe56024b822478f9acb6c2b7f68c42695a390b9908406572a5115e05319b34c9db51087e53b26e3a63abc0280c24259bad9da2543480cfda49dd3a1b0d2a357710991bc0cac8e901e7c735be08aa7480a561b1806acf6ee9d5a76e0a08c4f3f5307bc681bff606fc38fbe6167fd16570efdf8602166dd4aec39e89a521489f6b4f3cf7934d7cd03e299b5b71b8e60c7e31f0da7c0315d7bbb7e128fc05e8355665a6d1354a735f90e76c8528b6c97cf294e8d0a6520a277cdae56eea7919907e6d835d6bf605aa25c5041a923913cf8433626f961d260aeaa0611f56c9c7f2f0ee2abc331a63c9653e4065d77356e49f11d42495683a031cbd1d7075167f4d6836c905247c88a59b5e4b7010112159c67ead399c2dab8803250401f6b3f58489885ebeb28c6c8c27e104bc1f3672a40ae08ae4b32a13a55803133e1ce170e923232e47274fe0d4ab2c7728fd43d8cce04f71292a17831763ff03137989a654d67392bfb5329930acffcb81f96311b2c3466bb50b407569daf7a20323a0d3241ed03b0cfa97d611ddccc049c78e89ab8976a51d5c89d5762a0e6001766cba493cc05b6d50afc41b87379134ea7f9a857fb434171a895ffc58150681c21dd30c12ba7b1914a1657011d475c2a905c0ce09c8d9c863310ce041e00d68ce006a7e61a557e04a34bade65bba55d0272370c2fcd2b9aac3dca58a9fc734a92d81104d5f7b242dd24664510fcd6a12b58faf6b11761b6f9022403116c68892d621c65a4b6b5be5413bbba3b4b2ac62c3a205d044051f4f56dd083cedc06c3273b2afd42913085b1000b243277c53358d9d3fb3a94ef35751b3bda28577cfb624cca38708a29d1c4bed0805524b650e624ef49fe2b202ca20dd496824a8ba7ada0e16b1db735cd4cd48b0bbb4725cec0fda50dd033084b108d66d8ce28259c3b14564155f6d2c2db0e182db1e6a0e27d5aaafb2dd0b28b7bef2778d37109b06cc609e33ecb31601c952d4d79a27c0297913c78e4b5eac02ded3dd8bb7e99983ee069d319d1a0f58e26475c8b88b4f31c531d8d36e70b294302e322889c23ccb08426ee4a1fbc0fc9ba389ef370f8af284a214578d87adcf2de351633cf1f0d7bcc87a7baacb002bc672d9be2d970d2d018a5b42a3124795d753cc76204f06f8b249c8e167ed0de2888196243175f55b1aa4cedb2f8c2b0dda188c9650d8c616b299897fa882b6269143159c7871721b516384d95bb1d3d7cafb4acc0fb3b2509f419fffe89b2e63a81fac41a2a2d09cb43497718e2eddbcd0013a4d35c776ddbbabfdb69acb7c26342ffc3d8d1b5ca6edeab70ce11e1fc196e9c3103a87f26a3bf10ef517bc6bdd9b5ece920b7b64ddecc4be792a4182b79dc671dcf2af8c16c92416101d22a73f253a18a4667b2d02fa207db1c6d5a7472c56cecfda669d06725c6bd763279704ce92833f1c0129bee695d6db09efad962b7bba711a8db8c1db2137d90feccc6a2e1737d1e3346ff62f94de9e4e112d45743a26e171ff00ef92d7805e44138b1fd698adbaf2480573845a7110df69f16760bd870be8ef66e91b3b613367318aa28fa5effceb08180a9eefabe52b9b359df472ccaa007370c3ace9ed816a5b4ea2451ab4b1075a290aeb01f7ab753c21bdeaced13cfab7c8d557f2d0dc2af92db62e3cfb8ef2980b26c4a9c087dc6124e73097965cda4bb619ead2b3cb329175ab3cbb8d2c30a0339928f216f91bbd45b3be6444ddf1840aefad1567d3d9081bc986b4d0497e47ca05cb25b7d76e9b40ed913f87ac977cf813826bbe816dcfc7d9f31fc36833882dc1076698a8414e3e501e93201d6b151b7007e7f2b91989a64b396d7f5e871cbcb6543084c68b60a5fcae59a4d57a8b4b0a9eff01b5577a56756ad2b4297d62265a5e438477e59a4f4b72c9f02a20823dd5f87eea905d11ef4eb8b45840a388c04c49c012b69a2cacf23d7e7c985a251103e8cd8de4f4639fc9bacf92809e9535a256deda0d47b803360ec0454e498c7458afc3d63e52510b687f4169c0fe893dc40485255b3bc02b60e5b6fa0504839b84ab677bee57c43fe65b0987a9673fd66d3734365e8fbfe5a8d8bc7357511c47b3259d06adacc817fa24a2f2bca8d8d7ab646777b11a7b4b5f1d787558a5f61af0d0b3ea82a088a1ca3fc59440043cdc5d32defe8ec3735193b04d03d8bf8f1ac0a2dfb18a2b4bc2df9adabfcfcaf7591367b6464f04c417c0d0a2833c9978bd49ad047a9772da068f4d65e9916409504506188baae2259d22f8bc9ca5b4716a7314aa02c1fc82e7f53704c3f8357546c5fb088ef055a82eb0eb22ca12caa62151970ffc6fb1e6dca0dd589d6c8801ee8c9cdfb07fefb0e47e63edd85d597be2b08848ccb6c0ba6c83890cf11733820eb990d", "52ac", 2, 356458880, "581a4440aa66df8d50b7b1b9d184acc94271db485fb9b4d8f478c9d7ae8513c2"], - ["ad27122304affacfd168901af107231f7cc7c5d08517a6f732512aa49178dc6b1021dffe4a0100000007530000525263abffffffffa67c63d62fb55e2c64399e7d0bd7db6ba3d571b1e30cc6e97e2340701e57e0d9030000000700ac00ac535352a8f456b9c4c4e7a54e3afdffdc54c5e0a0b92fc8b0256b5efccfaad2264df35add70862d0000000001abffffffffa731a85912c7319c654f5508f08cbc3fc0cc6a3cb1f1882f84f4c700f68fe9c103000000086aab65515351ac006b89ae3a04466a74040000000009abab006351655151656317df000000000005ac52005151ceeccc000000000003516aab15a539050000000002ab63b115cfe1010000000000000000420be00400000000034d6101e9b89785531c01906e9ff0e910836abaad764de1393d3a36d481902ffe9b5b8031967693791a532baf56b7451a925beb4e04481291589a84421ef5c5b47f347d25d351063280fd0438b7bd3fd788008090484791cf91a2ffb64c8d80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005aae5871f61295c68560c384d84d20ebb6216b36cc0b2054d64250da548542bd0c6b6e8aad8aedcc606700e0c6cd944685d4a601c0a18e3fc018ec8f68c03f70ce317fb90c12755fba476fb4ff7d8a38c80c1d5b208d621342774dae9475b63b9ffe10329ec59cfd77da4ffe57088e1f3424a3c2ac36a836b7344fd01d88fb9f0222bed57c79bdc04afcdca64c47d3604a5f8494b6b16082f8814ee91b97f3abb50213f731821b30f9fcdb6cb8388e423e8b9d1e1c8ba0fa53a07a1110f1fdaa65b00b207fc8a3fa7e84d1b46a7a7d3adecb1442172531d374401c3fe94271266f03e202d80e9b89bcbd6c906de20430f32927db88eb2a421bac4199b37a916c62a53602074a666fdaa5d33b82f8d4ddb2cb7ea1bfaf92853361fe3957ce437687c7c39402180ee87ced11e422e5aaf4c8c2879f887fc6c66d16b6b4f23cea92bc7d164928031aa2b2f7f5293076dbea1b1ef8eda9d37e3e40c29b48322bc6447badb473532103177b6a160aad8580784710b60dc7b9f9dae73bdd9e0f921da9f42e619c7618ac022cd77ceb4879f9c61b9ca9fd32af6c03eba6ee73b00f0d68c93be90ced455dbdbda1262d10d620cd5307d1e5debe21bdf9ff3dae0f3879057877c858b312ad2a38fa9ae855ba04268428305e9f724b6c4f94f5c04716d05a310ead935d13d1a61afc2b41e818544eb1d105c7f854157e151c7a1666bd7f00de453933aa57dcb0c45255ab048085f2f31abe4697a1f0a9377513bb590779555df94d7d0c23deb468b7d1aec6ae51d8c3e63d10fc63f62236ceedc6f16165222ff0d6e343d92771bf73434e97d85b23857f9f1d01697a0c822505d02ab04b750f3aeafeba483eecdf7e2de8506baccab5c48b387533dea608732b52e9501c34258fc88b2f2d648feecda678a95b30b9f80908a2bbd9ff90131e27d50a114a12ff7d460700efb44543cd9ced178c7cbbed232571508e704251c1384b06f62fd9191e3c40f980780f2de247c426d7ce7ea4557029825c8f43bcc64fc73dbf2602dc5236cf2f40c8b8e645a83c72d2ae4078636f0cf8e2836af0964117ca40752195174a0334573690becb0b7349828f64037e8a7953b6e5e285bf2874cd7918e5682f4f48b13b3ddf0ee478cf555db5cc6426c4e365e6cc11710ec93b18b4ef8b17099735a87bd9c200a2efb2565941d574aa43bb517bbd8d0e51c09a406efa9e1d0608e7620cc3fb7ac32b098936ccbb9cbbb9a9f19d005204c51e6979e67a188c8802ddb1a4258aff84b3968092ee2a4eeea29edbf1b6c67f72834fa1e295a0655c7462b65241ef5fe925a3e285a794d55259324c17352c116432aab28bcbb3702ca9fcd758cb465129baa659d2b1241b5460f01f8c427bd8ea7b27aa8a1977ea18e9de0049913046cfb8b5a4f87e98beb4b3c4f65efe1ce198f1f40638049f9f29cddde518e2ef2909ebb36c14be127272adc3b4a36e2515a02d85989c2bbc9ff97c581c80ae00fdb0ea8d5082edea7e77f3c9f7e2b8304df130ee7cd502c77ec8712660bfae430e10c7d73e998c10cd8effa3b0bc3141179ef60661e21004f979ba64ea1ef06f71abfb67774bd836bdcd2623866245c73f0d78bf4df88477c1b74bb34bdce98f9c50efef5e5081625c175802ea7ff91c1b6a2f45960404cc0997a0748d92d9494bcd6fc72e744a98256c53679140a7612e95bdc6e2c1cac19d188ec27a3b55c33675b5468ff8240cf6d8ede002987c1c5d5076c85c295b251c214d001be1beb3a0e7dd3d952e95c3aad40d39c6578e19574b62ee656a9100a6a49eb483d6f77fda183eb7e4786403fdd7b3a245c3c4e6d9ef0863bf66c355a216cb9c74946508aa784e205e03c1523e4a0d27aa899755d314f9f683a2f731fa672bcb572cf1c7b4567b7ee5e7eb837fb329a253f30c729e8e897bdad874f86a93b548868f5407b74a33674fa5d69335995e54362fa1b7144d946346c9b05c20c3f65a6cd3bd64fc7681df698c62e57962782d94fbffd2cc4a3e65150ac368210b7d2e1447adfa47fc95e078e687c7af2fbcd1343002adc2f4773a9612be5c8d9cb3ebcf2dd18dccfe96d090f1470ca47521f6548a111aa8255b53590ceac0aece91dbe5337bd26a802f8405f08fa97f0441fe0a0dda8b08492d4006f287624508b005b168d8c06688eceb63b9239916d73c238c12a65ed42dfb4932b5b8c775dc7ee6da13194aa7de1245f553ddfd57553ea4d524460f4865c90a3f206ac0f2ab9624bb396844cdc6e8c4fd5342e039bca5e8e3d08d12f85e1fc99905818c9399c56edfee3a53cdba456ba8c3aab90f424c27c04e1d9f4d32dada28a33d30b7f7714af1422ef3583a40bb96b3f6ae169143692d3f98d0157069ee2d3215948ebe7fb37537ac91146633984dce19e645bf2cffafc9b3b17c06", "51655353", 0, -1366103095, "52e61d542410198b92525b2d4350a354ea74bdf9c40ca81a0e6a2e2a1d60afdd"], - ["f730670b02b819203e4fcbd569e1efedd9b5fd983fdd0224a7db7ea049d9af9b59e63f94760300000003ab6a00ffffffff16276ebd682469a8bfb0093fec1e87a5c0df6591c4354b2e33d57697b9f12f0901000000015259e8812c02d609c504000000000153bc77d0020000000001520000000000", "51ac52", 0, -447471684, "33c3d2a3499b8f570c0c539cd47995c05203618a007918fb32fd194c444b2f41"], - ["dc791b14012d4167265bc134c400dafbcb9eaf6d05a25271a655db96b2626ca97928131f960300000009526563516a005153ab487e4fc604a13860000000000001636628e00200000000080051ac6a5263636a841caa02000000000014975f00000000000652ac65656aab51656aad023f796305000000000000000000000000c9bda62f29cad177ef7f20f3c08986605d0d9c6f67cc143ff9a2118c8033f66d3123b1c6aef8849bb4e967fb9304a33802f25bbacf57d1e025acfe6d88ce663eeecef1d2a6477dcbaa2aa77c3972424eb306dbdba7ce3990e85fa69bd56baa9d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008fff75bf9b1418bdd840b3ddeb7519b7642963c3a32b3700e1798dcebcdef7cd127fd1485b43c00ba9348e42fc33e27126bd34598c1e1109e906fc8c59ebf496a18ecc635c1930944a6f20bd58cc06b4776c6424ab3300d6935cc06dfe6b29ecff1a998b4854948e0a6e8e7313faa7c4516cf01b8232c3a7b19f9bd5c98ae09d032599cf6a74f95885cd36867e1c81e32a7de044450e9783f80dcfa0c3ce172fe7031851084faeef624498a5498681518d51ebb11a75e27bedd306336b6ba2f28c760b01d264c29d972295c6524cd97163634b115d73d77458d7af316496bc271194e10facb86e38b586b87957c0253daeac34282a6bfe47697035abb053e523252d20030a3fe347315d01e78e978fa95037fbaa94036abfdd737031214118240245a8f40216ff3d88e67151c97a3529ebab753a82f70e683a863f32f7f6c240a0d13427e70205756057ad179adc450ff7b0b7d34c8f156d2405641694705ba1d97ec92bc079032173b1ad7ea7d7fc11bb283d61e19dde28c31e8a2ac74112db4648b46f77fa7103148622ba96b563b97ba6a4ddbf196e17dbd17a037f2edf3ad78b6ba45ee6c54736c0fee85ca5df9d72b9e1c58c5ddd89e7a25a2367872def5f7f877cefe8d8ba06d81d4afa92f1cab45857eb7c08cf5ef7600427cc68e0c7126c12f92524e375a7713efbdf4b25ed2a48fb9b87512319853e5d4d0eb04b8a5a9dae4862677c4d4dd14daf614a188ec1d36953019df830d68510d7b09f25fbe407dc37fec591779ba08894bd8da29ad430aab9ffe47f3108d2cf6e9e5548ea751716577df44a7b42911cec852327378290f147458b9a0aaf1f2234cd6ae9ebbf53008c3f3872c8458d9e3e75eed791989fd29e0d4635df40df68543a6617983a2a6d8f483ec01656c56d92a46a49557b4933fe8e1d7e4086fac35f0a1faad653f1fea7c188117a41fff0f516e955ecf2756f4cc010aa587c633c7a2b1e9fe0cb281d8ba36136660d40037d504dc63260c45e6b1de3e34330dc1527665ccf17ee8dae264a7574439cd0906a703f779c7cab11d10a177fa0ff8cdf3c170283806b5288906519d91bbf8a7926c55f39d4f3dcae0c492e8f8b5e466d94a44ac9d23d111b458b1270d3e2c6f8ec60e8f06f57d61850cd5f351a45be6cbe18a9f4715f39b1e433e6608568b584f9a7c55321ed075edcbedd9eb2756b520fbbff31bbf3532b81d1627ea97f50cf216d6bbe19c550b97b8ebfd27f334b794cc9b8d50d559dc76899facf6deb2467fb59c6daee191e5aa0f92404ad64725d7a7824739fc2a1f44e84e6f094cdfcd98f689f116d628a53ae82e8872c4565cf1f736c8f4195426bb1938ebd5562f36578fb113c3695fe52906879f661e4af7cb21a864bf2019806f7474af08aa0c1057142ab7d003b5b3978950939a3aa528656f0771a3081e5dce91a5b26e72317b5eeeaa09976edb62fa0e2e89ce91b29bfb88f931037d7c0a5864be0e067f43fe906fce3ba356ebf5f6dd023630865a17bfee140b3ff0f7350184f32520c05222d48547999ea86b96e7912273853bcb37d84bb73fa45bea4eb63d6b44d2ffa75e34733d49cb30f44a71c2ec2a3fcfd849c77385efde6c1ee87081c568968f2a95e58820f9ee9d083aa0e05566eafe389f9c7ad6b32f9f2338a86163c0738306d9224dda0a8c653947ffb1be8c638bbde192b8b176369bc236560b2c82a206587d36348667d3cc80942dfa2e34233fc70cc0f8f75867a377426498ed998e276c3eccaa43e2426860ba835f32d8d529f9f6f98ede1a1323131900a7a7c3563cb0570b27727746595b179f445c4de71dc642e5f198bb29e1d9d488e8d9e7b6f2854479544b9d7f9c1cd67a241aad066d893d90348493c9816c83217a44506abe230e28e93096d2cdc6af453ffd1daa6ba55b86fd4957c094fa6b26257acb3aa6c2c700f6e519091304b62977e2fa103e0136bc0dadafbac8b8c66c6b82b542c33a5ad77e68ad097485cc46a3ac564f84aae97584f9e419459d93564d5a198ba69332fdd5f913b75728005082772cfc6a450268cfa293fc0944187adade23b15092631fa4c8b04abe5c2a1b0e43fe4835b9c0376094551960cdb8053dac3e7439f6d3bd69b489d99db19c3e0418ddc4ed099a8acfcf810bac80e2ea281e1f6d53b063e67946230a8202a88a5fbbc9943877b6d8fc1caa8f8653a2004b9b4b3f5f6d460d20b58227e03df6e990cad6d6734a73746eef4b05926a17d6b63532ed43caea6f5b048298e0d391ee9f49bea66c1d00000000000000000890e6f0500000000d0a71932922bc6eea5bb62f8e50ab0bed9a6d6a14ccc4abe537037cf27ddfc828ec2b93ff752dc0683422d94a6723d9a23d6fbd376821e4bb253a15845670905045c61a19aadd4279ecb6777ef851abdf0cb21d1b0f16b33adf7f638ea0a1c490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029efeb77ce9f5f0793304e97cc610c2a761795ce333031ca7e4ccbbfa07884a7a657cb6bb2331de9bf1d8b1b936aceaa3a3f57748fd927d660674bd073765ef090e8ae3b2be239b3d6c602452f460c91057f4bdff0e591aecc740a0c4e45e1c20483fe45be94b809477f619eb78711bcb582e49017cb0f97ba11cab5ebb1de07030b2624adb44f195334b3e6242316f4265cc3f96b2ce5e105a390e558e03f745a031971b9c9a66ea5031037e761e618b757012bceb32502d86479fbfcc8b501837e0a0012c01d1eb31be25a3bc696c05bf74700e4122e2da8d6ad0ce4b6f0bd04fb582977bccbd2cbb48c446b1adaad1735bc3e2aa1489693f03931fcd0198980b4ed02148f2ebeaeb19c8aedd10ba4e123a87a5e5c396300b05b0ff4c912608e3230930305633fbd820be760a37ac10a7cf69b8c3db7a9141d268a51c79cee5b7e8ef6df0317f344d658790345d6e41e765a1a1d0d13f8277663e9a4561af95abd096f623c022f90731caf6e3120b248e10e5023115654ea5038c75be9bf11c03210aa844ed4030a0a6b754a7a54ed09099ea6734354fe1ca6aeb673692bcf27bcd8f9bdc47536dfc9c02c9052e9b43f350f28b88c2ce85548d1bbd18eccc40a275f446c5c9b71d0dc79c35b6587bd19e5a65c6a16ec6cbe4388cf63809605951acb17c9dfb95692784e3151c25e60d5c093dc7c852ac0f317e96b06e7ca72f1bfded3abfef87a1f4eed4f201259f64eacf7d45c9728f1341e2e84ec7befaefd117726972128cd97b9cb7bf6e962bbf15f4bd967fe56c94fc14e88792228a325d065c49418691ec14a27e92ca50acd92985ff0f53bb45bff773f81a477877be323a22bc813c1fadfb87e86918d9fac6d3b3b97bb83e2d3f83cf13bba3c4135af36c9d4f6dea79f83873e423dbed32fd6e52f857c5fa120d0beb13f25318539785ccc7ce7f10892d6fb78140654d6831bc3971a8c04d2e14f9228cfc3a5cd313b22b993aeaceeefcfa55bbd02046b76a9f9d7b5682b7dcc3f39ac51822653317be80cc843e62d9b24f5450925df6c82f8b7d17fd92b1fc639d9986792e6275042d528e936b84fb71955513e7e0cb61444a2c7c86fcad02e5ff4506039d98e7dcfde5a30827242a9fba4b64f3a8fd5780d0d93f847d806ffd03c19d4a8fc1f5eadd80eaed9cad9ce818529559f70d4844967fd3af536f5fb31cb9c7208791a8405d9da342605079ad914704d56e339cafce0955d0bad9be9801d78adbb081a55a25f080dce1c0e85c510ec90dec8d09fa0e14873cfa6d2e71fb1325b591fdfd88ce120bf3040a501b04124a1bc38c73ad7e0a970f853ac9c71dc646cbf3f18fe0a56816a7a3fda1e460646d7f4c7a09014837e1d12c16178d2f91762108e1dab5b37d73003b217b8b55ee7cbd7bed419a7ff5a30de8bbe8e0a7164ee521fbbceb38f3671e698363a13c51bfb29e1eb16e0d5df1c0317209f83c595cd76dd7ab38d72e3975be1129c8f3f24897035079f98944643e4513d05900e2a8aa39f8b5d3cff4b1fafbdededdd56e5de30db5380f830ba57967c2240f705c141b03f6049f3e431a412b05ba70546d2c0f12f9b869f35b3d79c6ce4b9712c05f1ad91e70571fa68e7493e11d78d509ebd594f28e64d09e017dc0c63ec2c1eb10250c267eb1c3532aa84440beae35e800751d4d5d8afd72deb9d3b390aa1a7e60df0da2810732f9c1f143b3ab64582ded931fa26e0a5fc8a31cae6e1feac32b044fa8520dbf00619604e5cfd06b296590c94cf5c0cdf2075e9b7072814fb1a764a2614c44aad1611547c4d8d82a2cf8a9f560366888b54a2b81d127c88be604448e1f42c6cea5e2a836f1a554fd07a93e64e9699667a993bcf3e35e2bd1e21a2265f995cda658c1c50b19c8faa2805c339c8f754c11691dcb847875e4dd3a51f4aa7cb9ae048a474b32e845ff6f68a6f9b3e13dc7939c4e200976d11c1acde74a654b96d2d6529d54051191f4b73ba7ecc0a888cd4d7850f4fbc5eeeed8a4cc40a1127fabc9f633e917e268187b69a0348705ddf0cad14adbb754850a89ea687cb33135fcef2dc0c533da8d6d5e363ec49a669aab2142773e12215a6fb38ca9b4bd871c6d2eaf8fb0e6f1ab0ba78643aad69a9a4f35cf8922ff71a29c633148c0d1518fe14ab027d8ed04299bcf32797a9232844f85c87af8c738c4c96402828c4e9fd523e8bfb378f4c66177ca166cfe80476629b642abafe5d19bcc46b878871cac6e46bedf608c814cc5d7d37d32a864dea654bee513f8d4e395b8e46d53730aa2b551c4a209044f6b1412e09b6d58605b13ae7b3d538a969baffa6c3bd3bacf530c28447777286e7553b7b627492197ec76e4bc6900066e0c313d7c814cc290dcf89af1f0b12f769d161acb1b9fdc15585eb9a07f6b4243c3905e71b0e", "", 0, -962950417, "adeec5cb231177795300024ea6057c3cd6edc1d970efe15d86110555fbd7dd68"], - ["b8a8cac104c2f1f1202b2b9a8c5464f103abfc76ec68dcde25a70f9c97c728404aee42d40e0200000009655165abab52ac0063ffffffffeedea1c908e8d6a0984e64c64ac8c4b77acfab8a65bbf1c83dd6efb5cdd79acf02000000055151ac51517c16a1fafefd0fab05cfc43bca301bf716d2a0f6ba030b3fa6cb47ce8c95ff209f32184e02000000076500526365ac6ab7e947d19c2f94b294f5e957d61c6d6fdfa023e08c48275754044fb96f74d14127e2a8000300000005655263ab52ffffffff0339d5fb02000000000253ac53bd5c050000000000023bad010000000008acacac65536351ac00000000", "", 1, -1190876437, "912a11a1d0a91d3b9872fcaa8ef970beedc1d813f7a0ed093a31ef546bc7ecaa"], - ["f2df72a803a849704a7119015f0a221405dbbdd49d37c7f45066ff3978aa7c26a5c00b23ce000000000951ab636a5300636a65ffffffffd63a76e3bcd9a3978bf765a4494b6cef8f4e3076419b1e83a397df7c579be0c00300000003ac6a522ef12d5e1ba7ed59ae4465127d6bfdd6e908d2b83124eac8f4ef96b96292cfc2a83220f20000000002ac00d0c91506017ae9e30500000000086a5265ac515363ab00000000", "6365656a526aac5100", 0, -1406636751, "b3f3fd143dd5df417028849aaa793fd03eb93f2e12413c664fe3919efedaba04"], - ["85e7c33e01ba66f9e807d6591eb01dfad925439101263a1603bfe81fc647bd23ccb781a9380000000008ac63630051acac5368db7384023ea0c0050000000002ac53f3ff27030000000001ac0000000001eacf2405000000000000000000000000e58cbc6e6f5e83dad8fafc48df52197fae268c571ea7badb90f5c90c42bb68381469f3dcf6467bcb19b205c098c8d1a307357187e4eac4e1b46b431945866fe3850db11bcdbee76b7b4d6f7fb1c68bc47e12ce034d20c28461cd7f23a8d08bba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077d91fe7e9b6bf1ebaf5a113981b57665bc61c857fa7b2c4f2bc41d3a3ce7eb4ae453ebdde3f30b7dbc43eb360184676e8b100c6e7f6ea6d3bd2f1e18560e220b35d45fded4336a9f659559c597e7cdb3d84d897a73a2dba5391712a0b027ed87747b2757525bbc6341f6f922666b4865d1cf38fa998f40ab940269ea2834b3e02295ff66a347eb0e34dc24c482e0dff70a4fc9ba51436a2ea4a100e5f6df277e90208b12143cf806b1328d5dea3c24b90c6dd4713e23d5a6fdfde2a994b315dd6fa0a23eb70dbe88f23c8c245808ca9b5674dfea5d089bd99e1bfed9a48ab91e6d1e40b5fe7c764e9f8c7ac8a033fa95af9851d1add3fe86240679cd227d7041969a1021d5825068e3e8fa0c5a1b38491d8b2e5cab7d57709993156a73c36f02c9765220222547d81f931e3007322cef9379a81467e2d547f5997f84672b7ff028debdbb8022886c6fa0bdfd15ecc06ebf58f45f5b23d0c6ac1b10b61f0d2d3fa036a979f21032aa0cd94963593de76b71813d1f51641f2738bbd305fe134aecd71495684d191022cfd973db29858a06a3d35b533a1c90d2724abf6328301fc439700b89ed5166ada24f5d08418f4b385b2f690b9dec0d7a3b8136b00f6c7db8edb0691bda9601705364ace2d157939755b7d42b7fc3f4604976c38ac3df588dc1d6570f05aed8c697531981015eabc559b9eeac959e40f41d3f7f5d0b2b4f06cf37a0623f6e9d6bbaecf954ccd725fcf142b17bb7fbe3c89ad69876c702b9658f00b6637ed6c704304f7c2d234c5e4ed39c4816e83f63a30f6858b2c8f20569d4f81a5d9640f332e8bb5b68796a7dc9b5cb84c86aaa4b1b50717cd5b03d89ac59ba53a637ab3c9b9bfe701d105b474744337819b73a32f30072acc579818c860d90e9c29c207c850de8ceb24a75f519d8a7a5689d09701c71bc44cc00577bfdd451b1f0aa9d4dff2bafdb1c0c9154beb55d4e7f0e5fd52894ebf758de10d5fe8b2d6bfb9dff2812a04888e805eb59a1051636d8980f1b6332b22eb4be6c508e4d5d39f1a021d47b03fd7e2062fbb7b5b615ec02174e793a4199d6a9afcb9be63a9d0c628028a07466bf7f6078828932b6c45c9acc5500350486168d93b137e936d9a4e1ba115b0a08c6023a99771a815c56f17e2fa8c885c8fe2542902939057c1f4a545e440d65b7184715cd3d6879d83affd91064d60d00bb2c3b761a77733b2befa96ba41b10065bdf7e860e1808c7499111177a64e067be32a55f5c30dbe0a8b2431fc66b741d8b5747070c4f18b8b0da38ad378f6cfd6ec1a9fae81f5e863193ffeb8539525b2ea4db09615ae19c85fb0fc9852d9c968a8845399c2831c8eab30202057138a757b8d5ea0461ad2ab18a0e69b221c2d5544259b5ac4a2ef95b86eaebce4bb5a6b94041e06b941b4124a8448cf7a44a629a600a5f3eda14f5d0d576a80f11a44a2ad28f0f44866440f19dfe1147aabc0d41a05b41cfd768965730069763f02ec6b3e92064dd622e58c72135a3773235374de227f12406cea6297236286f396436c3362edb15e3fafdb78ee669b362b7ce9f689b9744e4956cb9416fdcd72c57815a6cacb3758e8b7fcc111bbb95e40e9ae16ebbff8ed7d5e4f3911b2ca7a0e1d435d51e061102bc424875bc44611e2f3ae59e64ac0c104dba74df7fdcc2bca3335ce69019dacd35d03ea7c37bbaa9ed443406e3e3df97ccefe6bb085fce791546784a5aa1c13408ea5c390a5189f6c3bc44beae656b91537ee4dc1fec087918467176831aa9d993270f6e2a13870ecd0d564e881bb5a19f142c84481db18360c59cefd90175559e587853a4b8f32ce8f2b40ca81cd2b5ea6197f66ed13fec0b34a0beb93e1ea57715649e2d53d02c3fa150999d5462ed4a0c2c6ac41d3cb78c2257b10ab4b43b38090976dc0a8a61a5463c2d3b5b44ff184d62c368cae8305ad525f95fd1f4d46bb6102e4a0c02ab083970445334a7c559c21840322625122c431abc3870284c5184c794cb5aa09eed21656a6bd032c7bf8426b680b6f88c5bb2dd4e93d2bdbb6cb15ef533f3b7bd3a8d62b8d1ed153958abf1911a6206e6a62f0476aa3e90f1072f39f64b4fa138a3e1cfcf307740747d2b2ec29dec7031ae338c4920419bedcd3a7a7ec776e992d9255fcae841a0aa3ee3e482d439cca50e055c3a5e73e405a179beac86be3cb274bf829b253bb294321a26a7f879691de0ae72a2c2c7371c03c96c7ad111f12c8aa6a251293314ddf865aa71a83bb4c247a0efdc9d5a281a6acc8807e805f3da60d428802a6cea3df86b81af73daf372bc267b05394dac8c7a152e3fd87be62a9913c462f68f21ae9cc76c87eb1f1ffe4e88c94d5bf5e9baf547b56e00e1d2bc62ac11041a0b4c34e113248b1db16a195fb31bf0ecb9396403164f5884654ff6c750b", "6300", 0, 2087165888, "add44d4812a1693bd7b9d4247b3d817064fbca9071a028bb033ecd92e21ade87"], - ["4713e12003aeafda525f98cac4eaec4b0635b922c814f7ccb472749ad1efa0cade708f32f2030000000400ab0065ffffffff97953c7affca64a02229cc52e4062bf5e46d2bdab2983c2bdc63ac189007b0da0200000003515100d278ece696fae8a6359dab5d73b63bc49b61f5f1337e6324210edc9e7dec7fe09f71dbdf01000000080000ac52636a516affffffff023957b7050000000005656565acac6255850500000000000000000000", "00005351526365", 0, -709014167, "3c000cd6b6b9eda3cb021a81e764692dd4ce478d65b9d8ad6092492d566002f9"], - ["76719c220252cad5f4fb8ffae5a54b762ca7bc99770ca1d7ea0662482ce27e839808d6b1960200000001acffffffff09b1ce3fe90f6b25b3c70705af6efb869db932fb5d6dad7a812b7eabda5269970200000006acac655165ab9034ca7e02e22f9a020000000006ab00636a636ae8c6940000000000056a51ab63532278433a00", "6352526a0053ac", 1, -495979550, "c44945fde90de88ae3cef44bcd0a39b1427ea57535644661a8f82227907d2ee5"], - ["1f87774104fd311ad25b33100a05f1d478c78bf20ec1ab1118d9d8e60e843ab1fc98f28529030000000151ffffffffd315730e61194b4e0e91159f37540add66307c1b7abb02403d54d5daca47d3380300000007ac5353636300653b50f16a9277bc40b985d7c51cffd7c92986f988a71cd6e50576c58953313974cd412a8000000000046351516550007b35de29477e7cfd9b11573351aa7d3dd9ba776841bb8654ab3d171febc54900baf60000000007635153ab53ac53387d31df03c0d5ba00000000000952526aac00acacac635bb9bd020000000007ac0052ac63ac65b4ba92010000000003acab6a00000000014cdef405000000000000000000000000c09b5e6f2cd01019e3d0507a9e3d15a1bda4345e28ec6b2f5f704a95d2689fc54ac05bfc5cd84a5d05ee9775eaa292b2f07de0279e6865c725c59f8cf85d91906e3cda1d8de648d8b06b9c774df6a47d3d6fe16c66e9e7e651b8e49873ccc04600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000851e7b02ffd413649e59ef6d4a7ee2d7145b340b8b95e7e923b2ca4c3715bad8545b64a3eb87ef5489dcc2887615676384eb8d3a7b12ffc395f0702f1b4917d5ef9109eb0052b7ae48109f515d3b3fe5b620c992f304bfa03e1db976e954838a90ee44c384233be3a21b979dad205eed425695bfbfc539411d9571a891448a2a032e678c6c495057c837858f53bef79eeec86079eada3fcd56beba7e8419da85e8031c82183f3f08bd4fb020ef5ed2db448c51b1a513939dd6ed590d54f8a56eef9b0a14e30e0bf5fba74309687fbd71b43909012c50db2e27a7caacbfc944d135a925189dac43cb9d92c91b396893d2d1bcd85ceb160f57a67827045a7d044f616942021bb612d6cfc429fdb8e88d069530db4e73c972c07f7da379a078e6c3aa95e1800203230678ed0effcfb4c8a2ad222406124172e3b6d63204269add610f63985e16032351e5e2214385d612f4e21b94b6bf6759828542bc3fb94076dfc202aa16cd81032e01af241c401e7023cb211a57894f128e652dee45f7e435cef65d151bf1efd702259399e6f540fd8b3af8df783c850c2a725c863fb592a759d45251e576ee2db958cb7c2ce30506e36a5699693b2316c4fda5e8ff16620e37afc91e7c223f2dbed02efaa2b7cbed8fe2bbd168109b17932eb4053e88e53e382bc3154c8cb681594d4f8bf647d23b044f3fe1cb9b745fa202aee553a7e1619bc8a81bb1ec1c57615e175a433a2acf5fef795d6e2e81ffbe6fdf07cba64c1018eefc1c96139e11f36de531ea98b4ce85e6b4a43bd97efc15b2a7bbc106be84aeae61df05f4acb27293cc716c110d73adad75123314d4aad0ee4d8521ea184e02afff0e622a3986efc62fabefb4cdeb44993673e6cfe98691e697bfad78a57a804433980a149945a58a065047c432cff46c5ee9680ebce0d22c58dc9a7cb0f9ef545492064063dd8379b93752a23700d7b8609ff402d2dd840db6b92febe91ec21c2cf9a92649611fe5b5f5acbf0145e98150b51a7d3234ba0e5139132d6660933882f5bb98bd989c9aeaaa87702f22de3a86d65698d58d8c6bd7d01bfa5081e988984562080fa403164d205c2c60d7436dca585139b1e2b23e32b90ce1f877cbb30b3184495568c0c1e70bd87f836b193342450ab9eaa582f077dc791642c4c0a7140d5f068ffc7489a932b89f118568fd9531ebe59f6a83022a82bc77a79b5e69f4be815b69b01adef0b8976e9af93188ca0ac834c9a73e06200d49b4665477dcbe8815c8db995f61ae7328ac70500309f05a9e69fe8b26ea3d1ecccace6255e54b1bc658ee44be9ca3ba1062895d77be054bc844cad3100ef1fa9d66bb96f02f5e21cb6b027d40a1640e479171fa4455b27f43126d0d539bff7252aef8e3f6260f2030e31a794753e7b1fab124c2857ab67587281eca6c2dd174082554f143c6b83ac12b6036f6936dc14c7d681a1a5483cf9743e185ec704936f006c9c938aa5c4882085886d169e4bdab42d50e3829f31725916629680a1553d4d0b30e1688a24447bce5d2066f7f91a19afb954a4e8bb54db745a3b37e4664ec250ac5f5554471f18b4994d50e8fac718d1ee6de5046846e5457376bfa6a0a487e33d60947e4a27037a2c0a8c4ae3a6f6275988f084251d01f5b204a8d943991b2f6aae92b501e6dac2a4e06ae3f8e17ffbe94eb1d7a344a0e96dbf501b309bc8f17023dde9c4e585e574e79399fee9435a14e7c1e0d06e85ceac768f297d2fb5a293d0c5a61847cdc9d40addf9fc32f6381a20ee6fb9f0909111272191de84d61e53c55573b44d1bcbaf57fc777042d2e4b06595cdf312f2af964d699218c8c29421eb059460425f7db3cda5792d812202d9d02970bb34924cba2198f4701cc054919d212132bcd02709a11261dc5eedc26ac4b26988727e667020d8289ececb1fae5fca9753ad450d8ee178c4e29865afbc4d92d844bc889e36849aad76858b3be78a2457d08a5b9b6e924e7c95b2fc56974be62435ea58f2c6c8623eea8e77d647120e734f8085ae8dce371ab36d7194f93522aaa06c644d3f655209a46b359fd854780f7bd5a684048e9456313730e80ea947d629b426a5b41b688e6213df7a8b5fabe5d86f491857db7a7d31d4df3658d6a4928d6da2d2cd39aee67c57d9a3c469c6c5076315973c59820e893d3b459a785526224ddc35704567b9778e9943585935f42179a9640efbbb69b191e62fe23605b89b2d8c08bc5926cb0f158c27818b54a255d269bed0ed32970000ae9c6156678cede674206e9380b85e120b54d8051e4ce1f7d01a75cd937bb0921f8e1ee2a4b1635ce39db3e0f3a08d70f463fe92322c8d6c62ee76ad7461754f588856a7a8d2c9d44a1d064da068c256c3c1c0c76d22003bd8f738947bf86fb73a9a0e6b7334581d042309a53b803", "5365006a", 1, -683488930, "450f6957449a8d0f8fa7f4b0e53aa284246b74e9f30e3e78f4c9c8900c61f152"], - ["63bed20e04416fd75d28e3eb741be144d42ec9d551ad78efee5d637aca0a8300a57e2c295c020000000663526aac0051ffffffff2528c63802e6287670636d7b4aadab8d24f2dc31da1c05df6b95cdb0d6092a750200000009ab6365ac0051ac636a1d620ce12fc79b1f9a594b7fa5759aeb934663f20387a5419659fa24f8094c26ae88dee502000000046a6352ac0778bda0d9418bbcf6ac3edb478b55cefbefbbb95ec3782cf7c55a6a5630555f4b933642020000000151f0653ecd04d2893504000000000352ab6ad5d8c90200000000046a516a6a377274030000000001ac1a688202000000000865ab00ac52515353000000000102739403000000000000000000000000fadf89db2bcf407f9b717ec9a852c1d9a6e231309d7305c56b69f6156a77e9fb0ee5762b01c4e30b4dff842fe343d614d8c68f3a2f31e157a9f426b06c1b1696ca13a19f1c591adee00d5b0805abef6c48faac6725ce0bd203fc15bb70dbb3d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a19bca6eca0b478ad3ef6609469a5e34b28bac3b192dbdb3d8d12ca289c438a566f043023378c0cbe143d4fb3c1b252bbd12c68ad5072e1261a7cd4d909e58dfa65cea2d8c701dc84cd019a6edce795a8c8e1a1ebd2b5f15a1425a183fcbb537cc7e66a71120befac00c2e4f2a88d1552963711f994e7f85592ae369eedbee39022e318777fac9857961fe2bc8d971b0ba10489df20e717fa99953413f3c1d6812021700167f9a9c167ce31698ae72538523da79cd6c2e0fbc4d880e6792191edb950a0ee40f4035cabfbc80b0a5bd5ab2626c9706c14b044d02b5b50976ebf4ea362f0b1dc867786985dbf29810c789e06de40dae4fa1f9318981b636c694d017b7e302002ba8044be427adef8d51fffb64b35acb0f580d687bfe8bb7ed8ff42c359fe50221dc57c0a1db143509a273d5304b544562e7a86f910740675c1a11bad6ed8696031de82e58ad330d470545e6465c6271d40f367bf7cb7645a229e3554d522b4adf022da1c4bbd133cbca07a651edca904e87059d2f0fd7339423863aff3e4a5349e80214d01865e3d7cec5504f6decb1483cdee88d93c27e58880d825e64a8e1e191279da0d7f90103aa4192a4016242833af50d1903136262ce8156cb8b0c57a09ae4c79307d8f8b6c736ce05540712daae505772db5e1883aff9ec9d58ef3b126f9bfde8cc22c97db83449d0b78f139a6ba0c6895c957451901bde7ce7110e82c82d81d32f1d63d4efc5895db87bf317d164341c319baac0279b0c9f0cad6c393eaf9fe270c5f17c3c03177e76d6415f41df81ceaa3f228fb0f58c0b547f595fd63a04e70ebdeb488c9df9b9c2dcc90c218db6f05a2bcf5e13fa83a9b3c3b421148e11a84f8594c869bbb94aec09e1635285910878757076f500c7cd9132e356c2ba0b1dd976528c2c41cec5726ba0efddb45d8d23c5e93163fd3b5a5f80ded1b8ea05c095131a8a13dfaedd9bbd37ee23a03abc44b8cca04aa3090c88c76c53c5f8e87f6fe8460294297a9c0caed5e069aa6bf375a82c2c76f79392b20441d458c333482ee09fdfe2fdfa92335fb0877ce65eb7c92e72c05731d7994d7540dcdc1e379aac871f5c4c3edf16535f62f3144b726c32d5a4f130555bd6701c44509607a1e879e68544e32004f09bfdb5c8c8ac9356b98cb8c2237b43d2cfa5b0208daeb7e570fdcb352b6f6306c468d6c4f06fc9be94e2ad2a4e1e902274d4d1d92fdb534d56ef9454400453dac47af7113fe42b88325b66a6e36832cb0e512629826e1bed20241d05dd0ab6f02f85f5522d17b34f8bd3548409b18f1b33469f8f442b067283ee5a3bba1c64d69e860f5a70988266d199ca52bdef9dd910f69ba0daa866769e766e94f30f4ea84ccedcdcd346e3a3fc92b84e6a53202fc7f243bf414c58ddd324bdadeb86bdd7e090282ed395061d0dc6804795f3859bbc9aacd0f0af4ec7060b4b688febd9065954da6831b83e6cd107848359ab82f470e478b2d45f738d6ad1248e7606ef6727362c33c711ca25f10a2e44d1b125ccb90b122b37cf0982e8d069da3dcce5601dd00f3b56461a9723f0fd6beda083f10d159f0c1ed3ce862e68009d0c9dcf193a382ccee645006758bc1f8ff0282a0f60727bc35070b158acf741d9ba6df7edc68e56ff8de5045ed6dcb4c70de4425b101c9a88a1429d81b46f5046563a518cd63314fb3f1d5987feea0c8b8ebe776417fbfb7d02c03e706a8441ac5ab20dbbb05c8ed3ef7613f87e2b3c57c593c1fd391d588a285638fc146db8dd294346ef18b0eb80aedb0c5b9211969d03af94dda5de40fef146bedf2681e85916d14c2d56d7e4f9f54e960a85ff35e9bac2b521e1c5371922f5bba9c786d078f0d62767a30aacb00c841bd9de9b72aecb4ebb8527919c38413501d6fa42741cf767b89a96d03d77b372faf86d7bbd7a960317c867a9d0cfafc3fc7995074d094b2ec4859240c74809d7f45c7331f3945cc4cae9d8eba99431193cf935e0ee96640b65f35b8fcb0cbb7d77d5f5e18bfa005a11f8cfa4d7f85669851f2c1de188a0062162a98985d55b2c61ebb5cae48960f417cf6187dcefccfd8a92e7c16e5a1e24509d7fee2e68961ca2594527a35694cf179a9ff6e67565d79cee4fe2f06695fd7736749bb603c55b16a7436f9ab7020339b71ba76c8dad5d3515a360ccb5190c5509550f3d2a0c11358ae31122b01c124f5c2abb94abe890b7995e4017027ebbf2642973263e81e66bdee616b83b19199677f643ad5f502b1676aee3a07ce09c69f65dd1346385202077ce40f6159b0b008585fc5b39298ecb135dbe41e881ba5003512adb8ee9514598009204346dca7218de9a794e9758b353ab156c9c75528aef15eea817735fe11c18525c0484c6ecb50e50256724f5cf2debcbb5b2448560675b70dea4a7a1a205", "6a6352ac00525151", 2, -88450697, "af59dbcc6d7bc923432c631b8876ba7927da6010b56d117ed91dce8cbdabbfff"], - ["295546c60360d1287e9c4c67fe0e8ff101ffc5ce5f0566ae4d8f68c6c95a7b572146cfdc300100000005ab0063526a4d7bffbed0cf8a91c00e2d99346a7ace4eafbe5259966a7a2a37d42ca93b6bce4b23e8150000000009ac510051ac65536353ffffffffafe93b13ddc5da3b5ed17b98c2fe7261a169ef5d33979040fe9f8eee3056302100000000055251acab517707a8be02d77f7d0000000000036a00007e370d0000000000045152535200000000", "", 0, 1347590081, "2064e8aaf6cb16c46dde6d7b43656fe7f98496e300c756512e1327d51f8425ce"], - ["d469e4850209ae0e1b2f1fca793f467b5356a7d543e36915d936e2099eafae4dc97125d67a01000000096352ab635263636552ffffffff8ec67f49c7ef0fda6af855bae56d87a4e203ec94c183b9ffb2b4a820d4f9a07303000000016affffffff02ef159f010000000001ab5c9a4302000000000000000000", "6aac6a63656a00", 0, 1034546221, "3281c1afd32b47a8068cbefbf7f143da472998ae25fffe1a4bed7e878f5a6876"], - ["babbc4e50354fb024837d24a3a172ef8fb4bbbe0c908a28303903d47cd378fb7d867301078020000000500516552acffffffffa1f26d1e880e5a32c86e735bb59d6926eb5e53289c7e10df58936e5dc14162b701000000046352536aad818bc117e1696e5e82b6f98a7b4167565b2517e51a411a4b0ee43297cf3e4bd36721680200000004ab65526a9271c5af01a31ed5050000000009516a636352510052ab00000000", "52530053ac65acac", 2, -692393489, "09bf3703ad560e529f15cf30e6a9ebe10f53fd51034b6d65ba0211bfb3d3f3a3"], - ["9892616e01ceb38b1b47845894e4c6962bbfab6b66a601b51db09e438016f7426cc4da0c3c0000000006650065510053ffffffff02d579130000000000065151536aab512fa6ec00000000000253519731b2c902000000000000000098e73002000000001d03263d242c299aa10c36897e197284686e6761c7a3250fe8064c63c829d8d34b332f96302a02c43571acf3ff215db278c248891a0be6b131e2ae296d4ec6103359965d1b44f7f16dd64a3479dc7529bc3e5e19daa94709e707e0a5d8e19079000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005bc918de29c7ef6e081b2683fdedb12f59bfcebaa017f7b9d725c4cb259c66c130f346234d5130cdcdd92f5039d53234ccbd4b0bbe7bb3dc17452eeb1089addd2164f1c57a9f930c402e92469bddce4ae590f1fc45fa3e2f93862f214f3ce524d627c71140c897a768408aeae47457670e09b1f5c5eb23a210ed85c9ba51e198032810f187961ff8b34067eb82b714d1b7690afbdffa0b2fb8d7335bbb1d44b7540201d469033d3c85e3b4ec7727a1181bd5e2e745e073ce87236fa6b439ff88edf40a29cf2918768d8a9c18302bc354f75c2e9a2c7027981eecd3a5012581fe3d8ba1036ee198b3dd93612551ac551e0f6906b2775f08c4108e955e231d965e7e4c090227e0926453d8ff4f4e5a2fb52a2094e3e485c847e2c710e25d8d8b23c88b0dcb0217e62195f0aae90cc76600146047e566e21476cf408b5e4cb9cd098cfb4a1a90031c2a4cb5319de7a737f7d2370bbeb7c438f9575701ee5277b2ea1f9755e6f78b0212a8aa80bded47bf2081fd68fff9a36c82263a0c3d9a3f438b840cfbd16261c403229510647176c7ad841671bcb763467391147826b732382bc6a44789c0268ad9f05680af1345d3255a0419eacff6bd332626f6a04fb5fec00dd25f3c0b2812d703ce788690d1b66ae5bd5fb5ba907721490df47808aae1b30c427e3b13cd7fc50dde833d5f7ef35552b67efff8d571e19efa21f958777997ca60da7d3a8f085be2c2963ca59f08e640ba01d28415f80b90e7b320cae84f0af96b1f6eaceb2ecbe97bda4a817b4f3a077512f783e61e95464ae690881d950ebec2308c1d3a295993bcf2168aa5c46e8d3014467a22b8063143ebbdded3e338cedcd84f7fbf8b1853bd8a4a20a70191dd432f0ed82037b41015cbb593daffc59c83c625701400c5775fabe97df6335895a754af1cd918823770ae8d585b1822064c23d2bdb9b9bbebb0e7f0c925b58de9d1b22fae8f1675d6cd6e5d76c67dcac9ff10b3fd6f37320c92953ebdda7bbf84a8e87b9b2558af2feb6ded41221150006b0b0e1e444dc6c46ec76106baa206db1b94d8b5a7fb026ffd0de19797f5d4dfea521ff0790ed83ebe7c74ed5f238189f0259d2e62d6857031b6e7d333f48a84340876979ef59e1da82a4ee28ebc7ecea5058d64cdc1958f70c3a5c0a63134f5767c384f5af795a4ddf3fb434da677831c10588c55372170ab96652cdad4292f32550882c5f1ad750f398fc4432ac11ea7e3dec403e1ddc95eaaeaec2f38a30bf221ea50a5f6c5f929507c472c81b7bba43a729bb2ca143bf619f0b61883bfb1e41277ac91247032f5157b3eee4934f21a8d102cdfede05c5f914de84868adcb94b61654537dbc7fff3156aaf36e651447302e50d2a91788c762d977970a48372a10ba27b26b0069c8744bcc0a5dd1f16ffbc1ed9384e5f5f420090b974fe7a2febd99682e58ceec438ebd37ae06f7b9de342c7834fef164063479fef2abf2c9c24cdd71934df9a297be24dfe71d5c71f67d8326afe59e06913f98369b82de32c1076493da6bf826095d926cf2b92d5392d86fc518234fa4bb855fc8fd76a6775e8d08b6ef4785c3d6b5be60cce170773a3ece25bddc0370594978f3e4ee1325c7835ea8cb094e21356978fb79e59846dcf4eec91fda8ce7439ae4321a21f0151fc5714ca11c0f878582d78e065d380f808dec316066c085a9f2e6ae1b64939ee6eecd0c68f80dd1892f8620590fe9dba4b1f4952ef5e2e96afd477febfbbf47b2a47a7a1d2075f32ccd8b27537fbb2ce52325777967e2876373264fd55496a5dc8f1b3d89ef6054273657f237a3c4f71ea015d416a90d6a1145338c5e35d5c205785f9f69a899ff81f234dd076f36a9226607e1598395a5d814c68716bb4bd78a5ce86610fee789bca6df20e9f910ad602dff695b0398117a7417fd9207d9f1aedde5437d4d84e12d3b3794e580d7525e15f1d78abc5e33078148c3201d6d7f8372f205f1008047821107de0107de9103ca452c760d5961571de6e82996f514d4581fdb542a795f4e739cdbe2b27b52bceaa2b0f53b937713dbeefc250947879269a8b55c916e3676b7ed41082795969c58dd4d33e921b66cc9bbd7983908fc7e89bd5bc0db58feb567fe232bdab8b999085cd482e3dae9ab64b6534508763bdfa8ef79152d28c366cbe8aed8b5ff9993ff0ca8ddb41fd9042b5eb2e19383b01865081d4f8f0d57991bff0db2e0cc87e9bd982f69ea71d1cfd5713ff26ab037b30e72859a9b877a649b4dc33c5dd547fda850618531e4823ac3b0fd010000000000000000000000000a64b7eb59f259748906b02676d69ed3116b2dbd6d1afb0ec79809ff43334f9df803c1c4a7dd4a5d6ea2bac9aca0566abc13f3bffcf074974755e350cdc5f48047ada8fe442d0442f1cbd27dfb0549fdecf0af356235cebed2ddce29764e780500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000245caa44317a42e2f10c816132a6891d7245e6be929cbf2ff8adcdf0a9c4c186563813e45c9bde0b41a24d48093b1fff45dd6c80b91721f564f6ff9b05b89efd221486a93ceece49269aa10fb50c4ceddbb0db1baeeb6146daebd240e9b151de8e0459e45c1ed2c08ed392c4a53764a2444950df3ac507c70a709c8a10a79a0b0314dd15eb13042f2c735186af767794ea49b88af6d100782466ca44a0fee8d5ce02020f6580539c8ee63d601f38ab68b09bd7c112ca9be20ee9fb79ba83397018390b1254ed52763d7937a1164ef090cb6f6d6253089bdc1ab2820d380efe37cf94d50c4c8d1b396e5a6aa93432573446524f3717f093d096bf18c0071dcc532e2da9020d4540ff609b4c436f8f37b7cb0c78a92ea7856334e69fc277a5bbec848b4165032461875f4dac230fb526a9f43d74c3dfbcf7874146f7b1f3656e8cf525defd80031da12e74c5683b52731113f689f1fc7e8ff18e92c15259a0123d95a95bfc924e03214f41ca0f5f642c23d8d06cbcfeb857022d620456ed9721707c5afc08ee4f6d020c61fcc4346f6f50cbf71ba24f9cfeab167da86223d0b8507259bd16cc415e51ddfff674513723289e54ce2ed1f90a586275c27179ad671eb4ca3dbe9d03c599fe91d17b882d73ddc7868408b5c3b2f53c1dee0a827d3008ed298a555d83bb64b208c052be8cd8760526a7a693b95e676726ca39cd096239ec62e39720b108718e421dcf66ecb398292e1e2cee7cf36c1086cc0d826a7300fc57805c27d7a4ce1b6573b7bb5ab2febb1ac1730207031e028ab51d17e7e2a189ea788c2dc7dec41f2157cb825235aa843019b66832030c66bf572aaf2879aaaa004296c96261f018aa4d38c41e05ac12d0ec66af54d9e6af9e86bd7f401a61a80a89453b206e5203d86a1223c291987118572b178163a553e4063f7a1787f3b163980d77b1c506d04bb3f978f63ff60fb0164f80765f2ac51583a72ffcabfb428ea29900f266a5904a206bad6391b53d042e4623ce131445a6b2972361c42011495481b76b0795614f61515e22f51bc76646c8a603b10d7fefd72f05d472aa47919927f65f28d87a6c21a010d293c29b064636a3c6a536dbaba570ba6341ccad314ed71aba31442b9f41be83429ef5c3f87be284f99e917545e9a830d3efb3b0327ac8576046f020aa0b7d8fb52ffd9739cf5ae785908b6fa55a98244784df7e204094cab4583ee6fcbc7b90bf0ed7c73881eb1ea1c805062ef795dd6a406752d0a6bc4913daf4e32e6caa648463c855a7464e6a08789d173845339c99d8006f2322f7bc0137fe85bfcd4e55e86970ecbfb02d833299fa663dcbf4307107a0ffd255618833cd780e01fe93241117c4f29cb190586a564af170314cf365f629449678cce9e2adb31b5538fce4656db064aaa4d13387cf569cdf12458ad4f081961e53da52f564a691352d1269f6ff4501e271c8a6a70850fa5a9445af1003dd461718ded4f75bb0d3cf553622845f5519f47e763d096e8cd5aa29242f38da9fc65f83725368686c6fe969a4a90642c73a47c3a02a841e6455cfa534eeadf715d60d93f0c5855bc5fd5d055b5046e9aac35fd173dbdac8c075a68634ad0f6bfe107de3d7f39f28870fd948781f5fb7c65fe1c772efbc133e438b1864177384aaf02d3b346ce1a45676a40609d3357f794d272a87929ac4fc3a551c2e315b34e23c2f7f127234078aa32e7a6234108865fd3d7741d8126c0cb933adf529b1437f94c35821289bade5a210191bbbe8cdc90e9444f6bb4710602493e9d9dccd18ee58e27d997c4665d8e9e0c344404e8b42af169a548e2b09c940467532ed177d0601972304da4388d3803d73551b4a5f84128daf12cd467270296a6128631fbc0ea5f805262586ce176f5131dc8596d46302e1b2e7da0bd89d33994ab362d2c3e21638d135fc97fd9afff0e5c183f9a32d5babd815b90a84b1124387b165f8cc660ba3e74eee35ba48f080962e6078fb91804181012173e1418fdc4401b514e7d71cbccef05fd491ca41efb0374e1610925370f1e3a3eba9a9ef518c96c472fddf7a0ab1564bcc2873bc50f05a5cb0fe1f3e75c534cb818dc05bfb6d1e6022bca849ed0e2e10fb8ecc7b41a7028370840a04ad6b1b7e4e82cf5968dd2dfa8abf55635e56c985d97b89da0c3cb43f7a4cac7e608dfed8aea49baadaf149f756e90cf2e4455010c9430636b2f4fbcc681ee2ce7fbc2f34be1d4422c672b0aeb99e42122c597937b352de6b7ab979bf0a52dc703883387b6632286a2ca594af5614efd00608179d22938e4ef5aaab801e9c6e5f5f7ca6eaaf17cdee5101f097f9f9d497fa8988236bbd01ebd9c640ed3a896d4c89ef853daeb558eb0aa50c935a9a6d108f8030ade97afd35831d0c6ce495a1624928d906affc00b00f", "6552536a63", 0, 1892728135, "6bfaeea13cfadf49012587029f1d02d79f71d521e9c3fb692b7020dbd057e880"], - ["7689ad9d029f16c29b3e263193aab8db533cdb68718995b25f0b2c76475b6e3bafaf6ca0c5010000000165ffffffff0679064e307d1bdf157152468c7f4d9e71392aa1601066f8f5ec2826f83e58670300000009656a000065ab6a516affffffff0434f1be010000000004ac6551ab3c5e3300000000000465abab6574793d0000000000055152abab53c6eeb603000000000700ac53acab6a6a00000000", "6a65530065", 1, -1047218082, "e11166347a75746b579a16ec592be7149e66893b64e89afb1bedbc09d9c7d544"], - ["e4f4601901aa28e15581a3d2096702176f61c9b2f47be0429b35364df06b2512f221a8314f0000000006630065005252fda584f1027807b7040000000004acab516563a6fc0400000000075363acac5200520000000000", "", 0, 2114858216, "112c419c700b1f6df42facc85790691a56e57ed20c41f9e1a3095f38e261fc6f"], - ["846fe45403e7d8a4535472dd3e820db507fbcf46d473db1011926a70326f33fc012d0e76440200000006ab5351510063e9aead3e202c50dc4faa484bc497d6fe094cf4276292be894189ec40c6e1c5b1e04fce17020000000851526a536500ab51ffffffff1d016303bfdbde375f0c12d6bbc8fcccd44669f6c66f44e4b2bcab1930c4248e02000000085152515353516500a9d863b9028def11050000000007510053006a63abded0690400000000000000000002ffcb1f020000000000000000000000009270d9aeea91ce99c61f2ed3078235c76e2e540adee55fb75f017908fa55858bac11cbc0ebdb84f8f1f7ce9b06ab65ea4b9fb4788d9280efbd1b76414a4890c4e072bcbb74b81e95212a385281ce8d99cee9a45857f3d92b57fe42e20b993c78000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ec3391758ea56a3ea48b9556dc1a621d085d56e13b6a6eafe50c6e62ea90a69793e78ca9063df6d8fab5b8fe2bc685dbb360ab5641e70dc6732c45907876e2c1410c6fefd141d917180a6f47094d0f64cde604e124325d43d8de1412b9f778927158bd61228d1cd90f28a4567d49ccb10a3abedae0bf9766f792c982c1f27a3031131e8bece564989792cd473632042c434fe6f394cdc7bd0fa98f407c9804aac032a442c80f93dd8e4a1daa3350086d0e2fecb6274a343f28fe24854b67acc182a0a2a81a38d5d9d0e806c1ce40216161022df29700f3f70fcc8ec9e9b7199ff75c405810a3ae051b958189aedc9a4636d4bf0299c698e1a461c634ccb482173ad940312af512454b6177189c1598b1ba2bde4fe80511473ae9867c854012cfaf4ab3b030484deb51892c33f7b32573f4a832a9fde7fbc68baed21c3f0b3cdbad536695003201f94617f43b108f65969f522cd12431b26b680e18371819499530a3ae9a03b0207107f091d3908a8938ea3eb7b23ae0e2859f22a80663c670f972d35317b6a88020b11df65c9d0413f3c2665cbc4c2facc4738ec9512d600a6aefff6ddfa6a318de3e08d407a4a2df216f0ad0b55b9aef3057e293fab46c8b5091374c1c9e5dc4802cfd162109b0d802005e3a117c0a7b7c7a65b2c96910fd9ce0b9ac2cf3622746fec09a76381978273fd52c59bde4595fcfc32b5096586669378e944ab2d5f8fe6d9d1a92565d982f532bd129a58dc205805bed06db72d44982e343537caff78e72484f6f379a020572cd391f7e2bdafe480b372eba2186ea849a296b9bec2c15d1f21cb1b0f217947a63389464b7e339cdccad24e9777611c3d8a11fb1d15fdeedb7b506bf6c3ebbc7c527549d7de56db6324f3fc333b279e49cf7a03bf82e11f543c5308699560696a8c3587ece47eae791f1b842a5a9cfd486b9fb4a4c6d1e8678b7492ca370d5750d90785d1c7138b4df7364a20c659768303720e692be4fe88d70d950f23d38120331bc2b5c6d81f228bd8e5098c5091f665f2868f654e943e8942181693b134e5b772239d2e7dc086456ff6cbd8c18fcb3c27785b45cef9eb52aaaec803cba110c0b0b73f542e64de53fc3d8410c9319674e87e0947ad4861d8a24096cea7a4e9e59c8c687396ea229fdb5d086ec8cf472d5052600fac86a37cf7ba210e63066b21a860a1e9bb6245ed51e7646c9bb9638d3a641987d89641d1914c1d55a8ee9ea0dfda5fee47cc68a3323ef04dc25d9a439fc6b6aa59f577e1b7f845ef073057c04506400b87747318b3b586c561f9ff0f9e0d2ef27788b6872715f9403926dd0ea89a52661e7ac04506bd692a574e350c74f9c0e81a498777362a14b676460286731d1c25ee135ae820106200f0c936e6ace7fea5249f0f36079a862492582ad6cb0f4124e28616b620cf5240cce4f7d1096f3c2ffbd401db388b3e8da05f5ec17f2903648d1d12c6df2ad464b41f0d3073629d7707b1e5ceb20dcd24c6de57a46f06cb45d664e7eff7e34e737944bda9f608cb9fa1dc4941c6bc4be06ecb9b214b50e7d906bc94b9befb5ff6443b80b4111b47dc4df011ba07f795686c11700baecec3d738aa9dc92903609300eaa8aff595a4dbde6c07c62e8e6f76ebe2b1251bf5b5abd8d24c11353844f7d435cb5a3b5a400efb7ae22bdaa5482f3aa8492e3f9f31c38caaff910f6693e488ee2d243a446b44a12c1da808ca84b108198307e5a1d26eff8c544018bef51de8baf6a37e6d1511befebb398d3fb50e87d9cbab880268903bda163f4ebe6532787d6cb9f5b16ee96bdc1a457d960e14fbd10195538f717c178938827d2a054fac9ad06fcc641f3dd51b7fb0cc51c6634b51bb764e7263a7b580f9058b5333576d3cfeb80b557c146f079eefbedf05c767791ce15df3e71426e16ceeb7bfcb0e1960bb73959e16a0bec2e1162e5ea28bf5ea52806e9591cb57747e30f4c3ce911ef544d930c4ba410e40f80598347e1efe61c0486e469325f4a27ae1da724dde390a4a7f1369caebf8cec717304300209c041a0a531232f959f61f4449ca48ea8d3dc31f55897270fa4e24621d5b7d8a411b859735a42cb2728adf6337de910b5d46844a0a10e75dfadf7ba69c4ca4ee7c503bcc4b8900d9f8bd69b744b5607977a5565fdfa690fbcb4c24ce208522ef0e517cd252d715b8cff6ad3d2bee69b2270a6ccf9f3647198cdfc29c2a9c4398f6b057bd51818714f8930dc078be83b3a8f5abdbcfd06ecfd41c703efd87a61e3abf35f71d9636f3f79f5600000000000000001ffa930100000000b64f67a66bcffb1c63ac0a6327e1b428f9eea8e6645d9b0acc2eb2f456da633b45ea36c52035e5b1cbda8d9971e2ac0f1168e1293e4c197c5c3983ca49004dede4fa6334c04e3e58d34f10b970ac40dafe137fb3934bc887d5028303579b2bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080dd3b72eede6224bbfefa4615fb3951c21ade7e728049edd9c4a47e949ee2ff19d8cad1220488ffa1211de15a42ca35c6f7cf3a9427b1ee8bf2b68506d4cd93f13683484372325084064bde1f82f8453198ab4555e2f18984f595ef145d82dd58863cef31e3ec176a3119a090d3fb76feae688dfab365c6080cf58e0890c0c502122b8eca7f7a03c96ed979d0bd7d3b57a1b635aa849df7b30647ed57af820017030726cb4fc23c1dff991c995fc8f7de98b4075ef27181e85c3b472f4dcc68bf3e0a04930b8a92b0d116f8fc61664f5259d52b8a7a3393ce5659053890c9723cf9c030295a0fdb18cef7c2f18d18cc4a27b410db639a2dfd6db323da01cf7c7c97870207b4ab144b656afb6bf1a5578c62cc33de42b8bfb4d28d318de1374cb3e23c930303330fd593e9cf7aa499a300a479169d100abf7dcbfa3466d3c082f02f077e6e032ad328df1598992103b68ddbc2cf92ab6f921bf5c70f8cb310ec56699b10aad0031f835da933bbd3f10d49659f27b4955b45efebbf7c57331de9c2338470e9c52702287fb0414847c7fb6d6aec40d626a33a52fa36d904ca02d61639c03db72f3142f0f7eebd249c7c7829792f395e91fce1d19fead1ca23adabf8c46bee535436bc72642c06438a344d8bc17d39fb400a73b17e5499a92468777c47eff62a342624668fffae4fb34991798776519abb2f6133edb1d08de1003f51d6a9e59fa0a2980b305ced2c91ac80fc6a11b3e93249894682986ee780e3647f7c294390afb46b562ae442ee15232594bc0b1f720e57a8fd25f028d4f3c5be66968b4a66d61303bc3708e2833c1cd8e4ae4b0e3231237e5d124ecc0dd6989d438c98b0414c482ba1c00e2da895e5167d00f2a6dc68ecf557bc945ae5caeb929f8eaae33189343adb74512cefe32e0e8afbfdfe67de127325cd6b0476ddd36ecc3204e8b66a5373ec43cd72fb7b5def7b77bcd1817828400b6dda4a2dd6de5cde9127197912ca8d5509713d8d4bce8a38516f49af621a4bdd37eecf6906411edb3105e81f20ee002ff22871dc4092b61c8623efce4a8bd61cd2678d1a1f28ad1f3b2eb0efe17d1c90fcb7fcf976fabe3a68cc563301d8d37b552749a018cf46dd0e674df1bca611a6f60e6a673c08c0b99c1800881f0dd59f09a8cea8e1e8fcdc7957df98294e4e2a2d177e879dbd8b32b0b8f792dbca4863324f202e2b8db6a954add0b48e2e3ef073bb1b26975f99ea9d35dbbcc0a0f05d6bf9ec98783d76f0675e9ad1d4241cb6a8189f1fc98ed5d63921a3ed58636dc6c47db66be370aa5585b7e00cc9552186feaeb36433bf8a5f34fa17972de7a2b1af7b86b4ea809b56adf7c10da88ca2b09a33c259006e68304b0043b8212a5db9a80ec41fc783096964f76afd8ccf1eff36d4f567e1583f1d374e6d43ced952eb51a93ecba2b0e778d37687e9607c60e4e7fd0dab394f6d9b64904008c4c3847d5c953bd69175100cbfa575b69231e11366f2a4430190ba809f65855422070f957d87ca29d1877a0f1ce5ff3ab24d999b01946a354d7eceba6dbfec78c86ddda721a88153fb5c2b641265f8a8692cf101f121841f61c3fa21202829867389144c0a99173e51dcf077ac42b97a981046e116cfd8f17d130c7c374effc099bdd7716d44fd2c64c46569b2171f4013b36a96ff7dda89069e6a00203db08d559facdf998c3790777fa9d6f5ee592b0316c6dc4d096078622e66c0d3772020ea220bf520732c17d0b1a8e5ff24fb6bf01f1cc1805c63fb7868c083ed74d17bcd4113876b82ab2ba377553eec003c89fcf7940e3ba7797da1b9311fc6fd3bfba1550db9b8dae11689c65aa074e41dc99f206572597b83f69a08e972898a4b50c29985528e66627d556c0b65ee4c4636488ddcca46f6fd8422689150e3d98de849b5f3c521f8132e16fc0a7eb2f06710ab2b140a0bc3736bc133695ed6b1daf504b8303f3c9ca61c6953c53c77f60723b3ce20eddd797573149b1a8eafc01ffa2d6200bfff9b7993aef0c260e1e28f0161607eaaca9676ae5ad8956fcc0035b9e08072bcd0a3dc4405958b52505e39ea2697a5b6999d0e4ac545b4ddb00800229aa966d3d9bf46e6813df3e9a77af6c342b696766de3a6ad60107b32b060febdea7e8cdaf6a548c51444aecbbe58acf2674cc8c2e367b01ffad453f65d9d173f885445e9bd54d67ca8eaa79b5b3621e525fe5b739b08d4de425d121636a5891c0f78e1f3d599898ae09a8370f1ac87bd84350635e7013047ad22b106860fbf9a88e1d3cb5e0249192b2daa5ff11e762a090cafd172bf57717e242d98a50e095ee50cfbd5bd2f2ef66297a21ecfdafef66e9bae8673ad66e2bfce58a6b407f54941ed66be7a913e56841783254b9894bae527813903b74e114f628628679034b7f6245f2d07", "ac00acac65", 1, 1641639284, "9d2a18f5a50f6816f54abcf12e64b04a0a086b3adae6b1c98b3bbc9e4b4c5447"], - ["5526363b02207539a5179f292c3c6b5b04deb0c210e76c55fbe05e38d92a29891d05e790820300000004ab006300ffffffffc99aa8fb5b415011e101e533443d030e520ef680931617c71c195e19b8a14dd50000000000ffffffff023a731702000000000100cc7c8f010000000004ab65ab510000000002000000000000000025acad0000000000c2f0ccb56d91f1d17893dc7982921ef048f05f2bcf6a5b91a5c2e42d1a351877a7f9266194ac9a461aab0f23d2137d1650dbb942c18d8b08a368dede4ef62fd8850a235b91411e030d000a60f041e98964960b1541a0be27f60b092bc3a53f35000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009736ecd469493aa81b274004f367e9cb9d0af0a475f5996d80359e5bead13b02d4ee67fe0c2241776d8d4be8a42cf897423590abb81c19f868bbff4f36efb0a28c8392d983951533fc7e64d273015896f53892fd3427149fca84b1029248912f53d07ec1193e1354a82462050f1bc3dcdf813c7a0f6f89e003dc69637141f9a502283ac7c874d38f1e90a794f99f743a0e9e073c2a7ea5714bbded7873d8685da80203c0cecc4ceffd291fb0feed6dd80f3c89a7f8c64fbec08ffeff6ae3f3fe6eda0b2874358b22f646dcf47584f1587e5819adfacf21fe0e791f8f83b8b54d22c0030dd07103201e0f9108637ca0410f6219c1016cc6aea1f050cdb9b30f4d2e53ee020fb37cd018135c47ef183d07087849de3db284dff4cf41676ce6d79b75896e68030a96aa0f9ae1105891341616edf8a977e758bbc4b970d6d18792a062dcfd6ee3030dd86f623bfcdf9683a202a635a19c21e43587b8e059922c8541e3eaa8f3d77f031b38740684cf2b05384221a93a2eb70548e311a207dc5cb73ed91b87029ab2bb020a27d97eec12c614d68198306154306210067e4f2dc55b26c1b6e98592eca4fb45d15a19b8402e9ad51e023316f1797c2eb4162789c4a91505bc1eff2dbd079933efe3544004c60ce661208336e632c3e3728b6efe467e6bbe95836820896f88c5b830c16fafac4241e9ac7075408c791442a64d4d5dde985de46c27ef3cc9e943e1fb7978b15f8a42d15e623e2be6a1c8d57f472f7292f7bf286da361aa4b0701a35c136eecb879a5de93b9c92210e7ac8e546d0a6a15e8985dff8d5051a5a15fcdd0f9f92ac72481be00de734e4825462928f81a0a520a03ece9bf22fbf5f0f118fa02f5192821810a2d5b5ae225c357dc9e6125c53dfe278dd318d7a4a9a1499782c07d7a396d9d6675f140646054b87b91bf38e45fe74f51690f273310514c7adc37b12769e65752a63b5a8c3885248f63f6f21cc375a3963efc213eb09184825c90010b652176fe0888e56be49698e65e5ae3120aa4668b65febae01d89d9a3aff26e0ffe1a68252341579144756920c248e7b4b91f3105b7ef016aef312e7009d738da266862e4ac10c8c003312aa1a9f6fa9571ef99db4d1b4ab3f61441454f85329410999fcd00bfcde0473fd8499d6f29d43e23cfb0cb40927c72ca29ed914b63d98fe3b0ec68d23262478061e6f85c540276275aef0042022251de62dd4426ce0de56d2490204a969076a3597ed5e451224b8205df17eccf51af80dbb411a29dbfd24eeeb5d27c11bfef47c3b651282ad65feff88fcd21ae46cfa046630ee85b1dd4bc79899b9e32fa2dffd009c9e87e24896e9b9ee7a3377c739e36686a496d8b4b6805758779ae61556254af4a741074332417dcc82a89b73209528e44d34108837640578641611a4323d14fd06a33db93e861a1bf88d72e50e53b719a89dc5ca036e058e2a2fe86a3ebbe8c421aedf3689d0de13efef148e821a1618d85cee02741c92ff64cef6c51010fe04e0bad10244ba4374b8c0499ad82dea48620b1a4daae78650466c424f6c56860c2235cc3e510b0e4209851c1246bc9fc453a44ef2803497cc2d1475da1b32fba7c7e25852b4f628c55004c27cb5cfc165d29def914afc0a2fe4e779a4b49d3387e73469c9d63a48f731d6cb655f60cb923aceb41f2ba9a414899f42109f3335273aedf7437fe5153da4a3d3fa9aafdbee9b263cd6ec6b77c6e95d9bf518bf3c5cdd672482083b72b7e6cd59e0f9e71f1019997a23be3c475eb146487a87998ed8186102c86dc1d72abdb3b50eac4371f86a3130848153c59bc2e5b1fa4d11c4c3a497be063167aaadfbe6b81e883765fe2f0dbd4784211de1ea7bbb7673a264e17317d2255803bc9513cbb63b846802a370e82b0313b3ba7358eb2d107697c70c990eac6e46fb77c9627b8aa4770b158b610f2a97892d8f5620c9b52dfce7e9de215845448acc8f86da8183601da4796a0b347b3942afbd01c08ab0cbce0b950a65e911ff7fdc6013a4cc06a565f89bce90a395ffe308fbde9b1760a4e26fd6a91c641f98360212c638f5f36692557d634ee86b8f6e144a2961fd74fa650553e58fbdbea376d5009f8a7b91779cd405f0a03e597f4bb44cc5896164c6c7ecdaa7969deccd47d85d0dceb358fc2aa87c871ecfbbee6a3267d0e07d8407a147e7147fad3983dec8e4bbb6cf2c95fa9fec33b7266450b03ef9a53e766ac0a0b696dbcb493226bc9b4cc28e3e3e3b07b2e32427f56d6fe02ec95f45dc9a3d519cf3e00000000000000004057a004000000006f8f0d2dd5ab8233e3deb9effa58757d69f0ec390426fa06a11de6098beee9ea912ef902827c191ca8324aaed4ec9948c76cdbd91fa1db72fee428a28ab32a20171bd13dbdd2a134785ed6e095cd53673fcb2fc5bc3f851f369f4fe7506d211b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2ef009022d1d022a2f8dfe875499efef58ba3a039aa45b97dd973eb010cfd2f0bda6b7336e846482dd99dd2b9141aac08bcfaccfdfe12053af77522617eadb7316dc33b50a09d029cba7a2f2be2631df3926e6541102c1cf55199daecf3bfe38f975f1677cc6a2a7ade33e24b244ea3c63ec85d54935f3f196ecee691d5871e02093e0a09e91624a6077c4f6f7646b460500e8d906fae440ff2a9fad536544750021dc494f451c984306b4494fb39fcb801fc3034f630f2f4a28a3bcd082fe241760b1532bcd9a0508f98fded2a02bc0b2c8475c1efdd85a09f63288125fb6f1fa1d008fb20b56d2ad5f249075cbb2d0fea0d61635defa6490298e52d060589c4e7d0021c7bdbf03382a417b85e2d1be0e6b0fd7c4fb6cbd41cbd4659a3464740b133fe031e4181297fc899a9ab43c08bb9023e8e1057b1bdc0275dda41b020fe360942eb0222a0f03e2d97a5a1a7d4631d1a6f9456f7e08d9be1108b2b4f1e58109f6dcc93032d2c65cec6964626937896a1c1f7c15a0a036429e6cc97126c55f9550a0c6b4103024361e6bc8df921089c6631f65d1783ef621963d156be394f01df54c721bf3502d06adf8096f87134326c698b5c131ac2b87b5d80fce3bd8fcc74fcf77bee563bc75579dea6aee2fa4b25827bf14155211396cb7730e4a8dcae92980b5905899adf2a1e985d46522c33c3fcb19dd76e565b889694795fe342b325b37befa8a59c5226d212aac3f56dfee56499cb2c613a6af98a4d24aa791430606d0cd2e1f90004aa7571cae53daaa8b782c702813945581d536162b054da3b18be206ed7ffd8ff63aa38eb4a6032650aab892cba38db534e68f92f6ac44cecac1c4c00f6067cb114ff0f02b77b215446d62c2befbea645fb824ac18fdce97581f69c02050312861c09ecdf9fcf3eacb943963e19d4b10283fee919b7fc9b29f8e0191a90f2869cef0628f6af8ed5c3e3a38629bd12732a35234a14fa138181dd96dfc8a5868d4120564ef1cad8f18f6ebd308115422d4c8efa03c583880adb01bee8905e3c5d68bfe40f88c5b2c116530264b58c9c1af32691eb6dfa75aea7048b4313f529b05f5e05b80d67c544acdfa1316ef9ae51bf7bca9267803bc6d5879d0c507b583966d76ad9b3760db9e74907a203d08cfa96e9528ad036fed55ea5536479290361780821f30c0c29cb5d21715b07d15a10533f27eaaa5bbc517ab07b4b0a4abe785f5e1bb1bde454a826c626f3f0d7202b65be539b3920e5e438241f30015bb472be95d6488ee7e799942007b78e13d1d1917e255fa954b215f57524984e4accd12e354bfb0a1953b68732d7cd64d79706b378f535a25f8c2da0a21255ee4f1a6e4b6a30a55dd1fe2e9fd7a24aef9f40100cb930a62568ead6753118922aa9c127e93f333af8a7c74624ac303ceb215e76e0458e8c9facfbbf5e61614daa6aa143fa1d70d916b23407c032032490558558a20442714f2f09a79c02cb4acc9be76b312729fe12b1fd0b424175b81f5bc79ed67cff14a17d264b4d371b957ce22b246c427ed0ba5f32cac6a4d5bad7b6e201afc5e59e8a6895c28fdd1591770553d2b90515261c69ae018883922316a4dce211d794163d050c3869ebfa1b37b9b525768e5a01313f367f6c456d83995cfa23566ddcd78d110e9866b2ddeb3a0e26c7c560fa635894cba77dc422fdb636151361c723ae2ff9458bd583007e26a692175d6d522f7f52f4047579f5b2b2c970b7059d72a63c10f98c8d21f0bacc78c7cfd120af6c1748372f80bae8924430e79e4bc03ae32ac80ba0fabae9fad13afea0d587e630e7a6dd8b54a5b3f7ee6b10696b2f8e1d20e95569543dd1263d8b88e1c14e94bf8b675513c33f63a823a02ecd5e17d3df8863d61eeb37d2d21b7f7eb3afa2a49bb7d45150cc8ffbc081d20ad6f6da4be259abeae68ed3541148820af709b6f3163bcefbb4e3571caa8d13569ba751e4a0f04408a46cc6dac51544e6ef13c234ac33848e6aeb660630d540a525ed87251489698343e278daea6a4655567c33c245b6e8f2ae336859d59359fde81b77096896b7b2d3a152c0de84ad01d2d6cf0e021b28f5b7c5cd3c669f8ffe06d6aa224d5e43d7f49bf5d7306cda15cc401f554d0d2bc4733e9ef01c600542bb92e93bc3cc78ba09ece5f7d0dbe27d2dfdd8d170f5cef328f269b279c84b51f90226a0cf8118997de6a8c384c58484b36597330f38e2f69d019be136c4f8dd224b81004672a6d7bac35f62ad7c0c79dec02b2e69c6c6bfc883481150c5f4b4714dc7948569655a307328ee88597e0460ec97022ea828f9d722ffb304848e20e283a7213c1a191d15d08ccd97c8e205193215ca07d4c016bab8d6f6918b16915b8cdb4b3d0fc8202612e4787bb3272cdbcea247c16fb7f87aace742f7e409ed4e01", "63", 1, 960838316, "7f089987164ad3f5fbd9f1625ff59ff41182322e8c1f5270d38db54987ed5185"], - ["9bac7f9e030b2bbcd8cb7a5770477cc8b22267ca39e84c25bf41c765a5ef7981028d52fbd4000000000300ac00ffffffffefb24d6e766fc4738adf6b29e9da8611d5183aa8bc1c8bd233c4dff18d2488d10000000005636551536affffffff7b88da37333f75c6d25b003830f1d4985ee9fe66e68a18e2224baefa75ac818f020000000251009d1a0f4f04b04e39020000000005526551ab0044c081000000000003ab6565f2e4b300000000000963650051006365526ab375e30300000000046a51515200000000", "ac", 2, -1086449835, "9a7cb056228fd8a5c4649dce58ac942efc79961cab6834fbf4c1d17087ca311e"], - ["5358e1970428ef726cf86e705c4e163da8a74505b779f89607b1ff5220841a2766bd9b6f5b030000000152ffffffff29b333f03a03841b9e5a61c79a318c9f24978dc2fc812d075915ba63016e6c4f0100000007650052ac5151637f73db8f9f115c7b4d6954e5edc5b76e68b8e4205814a63db9efb92f657539b0ad0e4e830200000007acab52abac6500ffffffff96121f2a8ab243f94bf36cac375e5adb73f94d206d8c14db4ea1382dcfae1773020000000863ab65ac526351522742635003da1a25000000000007ac0051ac65ab63ebd74501000000000265ac1f3900040000000007525200635300ab04bb0250", "65005265", 0, 551506993, "5b2914174ec9ccc43daf416bfa1986d811c69a00c2e2ac831bea774c9090ac1f"], - ["364148b50232d66d22bb4c5bd1ff075a1c5b6858957dd028f444de125a7f75b6431dd5bfab0300000003656353ffffffffa652229ab35b609f08b0dc29ac15b600ba45c1b41ae0449b2d463bd97dc00b4d020000000451515200ffffffff02daa301050000000005ac000052ab696dfb000000000001ab00000000", "5352", 0, -1999539600, "c754a37ffd5465ab6b041f5c31941237b783f62c70ce09bd9513d6a8351b8090"], - ["148802ca01502802c7bae59f87102b3ab620636f8ad5ff45444ebd8114c11ba71acd1b9c9201000000036aac631c3bf57104d4f1f8040000000000aa86b603000000000500635200ab2527b80000000000076552ab63006a00d287d9020000000000ec2472f0", "6a5363", 0, 2111177408, "0f6a9b49933131fbf3a0c23bd9e21293af9a160d09d3ff26db1d3892e2dcede3"], - ["e48ddceb0100469ab989efe004280d671e42a12fceb7e40c4fa6c6d537f5e92afe61f55d8e030000000800acac65abac6363ffffffff045c10d503000000000352acac438ede050000000000645b8503000000000551abac6a659476c1040000000002526500000000", "5352", 0, -1542168280, "da74be9b9a2b04dfc172a01c3cb4e0d08a019f5cc722f9e6b2b018dcee8a9809"], - ["c6504740016fb606efcb4cf94898bf3829e76a1496d02794fddc4f6b3b45363432889b3cdf00000000026363969d56e10197f23e00000000000453650063f5e64e970352da55000000000000000000000000003d71e0209ab867ab1ae99403d8979e4da7092b44312ce4246500074c88e1be49c55ce0077ddf5525bcc482d9ed9b535d3396da364683f2b51d7a2e2f42d15140cfb5dc200011b31d62449e0f48a95102930f874d5fb5ef6c47226da8c63d780c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f5b934aae6a4cf6fc51c197d036dfe7935c8150f8641f89139e8c69994258cd6e9fa8c5c84a506045cc10d4bd5b79c490fe4dbf4b1b2e4a4f82a5313abc980437c10e9d2af4a8263d7980e024db244368cbf22ce38b9fa61e23248663f823ff7ebab3f9bdd701c0c3e211d480a3aaebef5ed07513f2d17d79b0fdd73b2108a9032ad7714af6cc8e5561cbb910e31840754524f4038e843d6b90e30dcb7fbac44803180bca320bfe88ac9af382bd4c43d3dbdca7dc69a83de56e1d21e19147c11c9d0a06cf297cfac0337c96386416f10a8908d3190f4654b6582ba79bd4669c8c8c5103099fa23861f4b99c342c66ece8cc58bd7523a313865f42a7efe7835166ab6e02006d3dd53710721539de0c3170cc4aa5e27462426b2622ccfaf629b08d6ce596021b228df19ce5ef9615c2de90e5284e85e9d67c5ec19d22f9a8000ff4b8cd60b20305f0e6a86cf22f2f823b9e583833f16d798e677590da0c6339ab00e042d2fd600321d5adaf0bea96ebdf75a81e98f41c5d9603ed832d13ef210922e373be56e3b7031af15eb5886cbda69745cbdc3b5e719262451391f6dbfee1ab4a5cd5d234ce1f9bd77f87416a2384a4001c5e9490e907a4de087d0a57cdb24f4e4320d88404eb06ff2e8dc9504232c108c228d9c1e43c1300778fda465842a11fff264e0b62a0e18b3d30a6e7c4e28e58c751f3c75c962946e63e1b52c08944a63cdc1a13e70c628038b0f251f959a9962d9470c1c032c980065f2aae719b086fc12f4927abec273c10d65d08562aa6727456f9a507240582fc11e041fbf7b1edcfc4f04c850d937e743882f7521ce3b912ad4785999d1ab901b00f11d9ea5ffa40ae6013fc67c910cdac4968645e05e5379998eb3be3c558a04dc8d5ea5d7d81a9040dbfac50a2f40120281f5b5d64a9a5be228e8389f8bd630d0ceafb67c3b11a391118871e5d2b9fbab5182e65959719d53d64696b4b46669ec81df24be2bfc418aa24f447997650a3a6d3a2781715d6fa445605db762ab865bf57cb10542eaddcdcb15fab27315259ae4ed97175bb9e28b2c59353b4d79ff2e33c35d4060f241223374b9c20c92b3aea0290d33577c81484b83956d7838d1938af7b5d4d97987c44fb1f7124ff36bc85634b7e4ee36d9242bc91da00134934ac40f4ea4ca4241e0bf3431f85beec3bbc612dd5948bfb5509318dce2f6430c65bb7e1f01919c3ea7b657b81cfa9d7167d2caff8a878622825bb99371c50eaafc87f492999e082afa64b51fd34c653f84c2b70722c1ae20d66da171d484e74cdad251606af9ab4a5c640363e2437b2fb5b3c8fcecffe6dac6481fb85a406620c351e6716ceb91ecf14af07951120563679f8c3bd418842738eb12a94c245100614fc7f4c4b044cdc983c8588a10d08c9f7525674a2e6253c00eac9cda450f9676b3be731f20deeeefa8792fa6b6938c036e0d283bcb965c3f2fdd30fa3a1dcae15db2d09ac56f99142f063efb765d374a4435c5b9433644410d4105bfe3742071d8f58d1d9739906f920fb817d4e65d2f85d2a6423fc693db4e456da597e3607b8960fe39623ecb67319a298adfdc51cac58726bac88995286e09abff241b888450d624fc2a098a3503920eaf85163152797a5aea0ecb824f2d01424e4ccc832a819c50b45347a6adeef44222995aa3f88e36408290929cb945071746dcb96cdb45a4532ab609054aabeb01097b17ffe1658302d7c12d3ca2dcfda6fcc92d6331c41720123481f0d8fe04ae69fb0e97b5153ac809475198a3a99ec4b7b99e099f2436ddcc596c414206748af51d60c792a37b0cc5acd6e79adf8b576952036c289e24046251f622c85fa20b22b2f25631c9fa6564348b2db192ea51ef562ba45320ad6d977f3ff3e6ea209954b2bb974b3303f36137470298246b223f5aa5c036aed4f57ac23e0a04f4acd7345f98de6cdbd74353723602f69186a505d3482b51eb2403e6a2a1d4ec606626c2b4cc2f86b044923264ef1f1548b3bae2a3ed59611eec0cfe1a8a77d5312dcebcd20a6edee208049d4d2d0dabea12bfc8ef9487bb3091edb9285c2683dbb4bdd8db21d397f94238f4909ee818fed43fd415cf0d2e3f88ef5a6e44c19c02dd7e0979e382c204bf10b2fe90a5f0a3c4a5dc1a23e42767228fa5d4d462de098421d826b4a451030954147e786940fff8344fe03e87e32deaaafb09b97ee3f1eac121aac557124ab9984b64db315a6e51b380ffb9403c834741b9d037da45195f93c7ae5f2d0454611394c8ee38ed2b89fbc6aadaf1438030000000000000000000000003a5a935336ebf09f809652d2c24ca5e9a8a1892ccce1890de760e8e474ca1e08f8399b1397fad7ee3581f4386b30431307b2db1170daab394017cbd0c2e949338d75092c1fdc6a7b457b0fe481e67e3ede9ccb419d3370d1a914886688ae7caf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2bc005eb4038747aed27933d48c1207ac30f0603ef9c0800820de281438e39120061386f1197db87531f2472fa308da52f3c02f66fff25e7abccdd723a61c0793679e799c11713d1b185a8ab45b2df0a58a6846735ab4231f6f845e3abcbd4b0fa0cefa62837ea8e23439f9d04de6d46c79e7c0560d66f200ba4425ab7086d1032230e415b50f4012b3bccdd0ff87a62b9c742b18532f2860b9df641408d5900f02274387adfba5beb62b3e32e32a87dba1cb20ac4483a8707a223dc0d596ac52680b1c60980c9efc10a9231bfc223909c37a38b77d15036ac0d13093e96914b77bf91c07e01b1f33834844543b1821380ec210a42678b7a3b06cbf1dee2f03aac15f022aac205a0b77648911c7d8475e1834715c18249ea7a9eb9da564d7c3e3ebd460021085295d3ffb71dff34255ea4364248fcc0a05003cbce7aa0bceb0244872ac3903241fbbbf93d57b8f3ef6141a50e40ce15e26428036155a84fee5c3cdeb38f311022ebf16eb52a1ceafd1cbeaddeec868e88f3db7e6608dccb1859e24db323abe39022f50851fa756a0a75f0ba921454b9a717a4e249b9516bf6ad8173792d041ad50e5eb1b2d2cbe5525e4e1c7818be470916251a9e95202892e0351b4dd2c5dfa765c71310d8412fb9473cd939cd1c07605c53342d167c2aa49daa7c7c702e8641c7606273d5dcab10ca42253ad560ffc1e19a5cdd0388f144a65c9defc0fdaa8861f42933aeef6bef1726d7a8c171d1fc09d075356ba8064324700bfb1fd4b897d98cfbd585384c465bf690e6a5ccda7e64519c8791f96600db0428712c6e417364b7179114aac76159e49e0fe0c59365fbfde2eb8d447d302bb8947b70c9d5fe05a270175a898e88bdeca5c9192795f8e818cec7ab99cbd7f5a3785bb643105ad47b60037eb1f36c4fd29501362c29fd40e90f61879b7aa6f89bd45a84a7e0b57443370ae0cafce14bce5cf5b8c4bd9c0fd8c05a721904444cb7d6512f125369d2e3822da83a9964773a7f23cba5ecd6a63a08832e561fdb962dcf4ea7da80958751837765b2db2f43702da6f0eb43acb7e1ca678014f642f08282df0539a3bfafdd30596f5e65f3aeeba9d185f6e881c7ba2c6b5d82daaf6bfad6f844f58dd84f0b36dd231dd6972d5c5fb59c477a0a0c3298bb37bb007ffd6fbbb30202c6c401bec220fba023b5a6f0a4efa67d4672cfa30f2dfaa366b0cb159d60c919cfb527080471c03b3ad148596352b4878c3f175c3eb5316da85e2f6e39858b3495265d9fca8584bb08d698e5f3e66019f4356db609586970a3e4ff5db2411b8f687a3c5d20d78b075402bad7a1bccc3fd8c89fd3b261c8b98cdd94551ddd1a306b82197d05cfde1ef70494638fb0db768e6e5f8e974d5bda7b09a52b561c5f20a2d64b385f877abaaebe158e95cb4377bf53cd4f69339b0d5cc3d77c61d79616d55e89b85465555f4ee934055e6ad2c6e172f0b154a4c464c4072a2dc23a713b5de42a84511d956735c05dfaef5b833091500833d49f24632d651fe872ab426ce0da00ed6a633644812cdbc10de53c0c0fb89056eaad9e444c0814766b451c7c7062367a6dd440117c8a4a2edaaa2940f798cd631aa447d806d622f9ba38226ab8b826efc46fca361168c434c83f1e3e36b392e33700a0daf2636548a9fada33e8696cedce851c71ceec096f1862d296663814b39c0449cf6fe6a5edc6071066a5ba623a7de49d40eb508dda5e970ab482848dfbdd6ce32fe83df71e7d19aa4de1e941fd01bb59d62b3382121916f901a07a9ec285a601bf8ba5ca20cde8aa3b02f8dadd013a32a2fdeacec5285337c4d49f9ed3dcbaa311aea901f92ff5fa87e9b2ccc220c3bca897ebdef4ad02312bb1300e19e831f33552260d3090caf28493e6879dc1808bfb33c0b303b18d5e2fbb6c1bcb50977e53fd6cd7733696d686b565660947e1a73a85e2eb5ffb9393811e4d349f7672d05d24f086acbf651cd9976f9435b46e31bd64c5e83db61ebb9af3396a0c3e3c63f110764449203996f101a90b8e52f8f5ac8133e80e4bab964f9c8068f39b2a74e6bad5b23c431f7c4467f100808abe7541e9248b22057467902d7c3d7961437027b2a820e8f7f4399d8ba59a61f06d4b3c2063628df594cce22ef8f539068ce0fff67f6597b883c9174219875c3baceed2ae2b146251e2952a7902c655a4939b442af425b4ea370f57401db1a545e1cd761c6461d84b500599783c4b7f9331fca3a62c8c1360d855765a5a14084beef62687e14fb5c816963fde2e6ae530000000000000000e9057a0200000000df4c54642565d4e94dc6fd69c1e1fc86d09a8aa9b6a257c38b4be18fb3f65d70948826ef36b22352015912a8a1c1b6682e49f56c6afc7fdabbd2fb4e666218e3c6ea04d27616932dcfa6129601eed83a9ba7995952098e62e66adaaee1372d700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052fde838098b434a8858a335614c14127330589d3805413929a4a555634938c145fb4b190fb6b1aaa5eb465bcbb6d958023c0ff32061e66d87d31ef4bdcafdbdf6b5ec5cb0e913d4080207d862cedb4d829d94f3829598b5a4cbaf5e11f764b5f10cd37aed2b0168cefcdf64a26a115232c9486b1ce2c4f927a13752b60ee9220311becb4ebaa1e190effaffa02b24cd1299ca52d2486af9640620be27768286db0303a5dcdd1dbbd30e2846f56edeec5615672aa35b62bd055e373c7c9c0b4604ff0b2071f12924f2d9c3c70085af0037c9495ed9b51e21832e6998dbe4f0fd56c5941eb36652c7499f1d897733ae156c429fb786d87ff8f5e0a0dd025a518e6ad237020d0bd4930c827891979ded4e7a1b42b0973edc223225c9646ed780b2dbc54c8f0315d338c6d62edb42001e98b47b5e31e0276272505a6571abd168f586e451725a02076eacd727a5f5f514ae0caa1819a7a0ea0a0ae6d5b3d7d4d044ca7e3b68be19022114b46e2680aba4753ebe3af1815d6d1e5707f11f9b4e32ef0ae6413ac58a15031f2c87dd2b5f9558ce8ca6255f0a3dfca3d86322ea4ff6964cd715201bfc7e2d12808373ae732ffcb11cb9fd120ed583d43a2719f510c2a01c41f308e4a70c572454431d1b090a0f4428b9c72cb4ed9f3c71bbb786b76e3f617f98316076fda943498d879a280930c7c8fe44dcdba36287e8444300d02ad78b76fafcd993947962ba713691b84bf756b3e132a508b93b3c4a014d455e81157c1775284d9ad0c1d7498c7e864e5699b97f58eb6cb054edc911538c7cb15c6fa80c8fea37c21f597cde8779d5da0c059d1ffe2e08e815c465710177f2b395fa0f82fdecd5765ab41b1d21a9eb0749f51a7c2bd50eea16825dd3d4fb59ee12f014cfe6ea220322c588eef92090355ecc56b02a1fa3878634cbdb84aad371521bd62a2e2b038eaeaef353eb5f4501b0c9e79e7f3487fd1ba508fad784055dd90e9d91fcb8dfc23c879fab9c582e1373aa6016d83a533946624dc67539f0388c8360334bc330904de3ed7073a105c3949ed6d346f242fdc600e229f889b809c7da88a7fbb4c0e88187c90b09bd212c3619c9a5141d20f1a16bdbff6358857ca7a6b55397f867b8502af97f29bf276ad489df2349d106786f55a9be04570b4b6828f6fc7d03bf526cf29456f1326b79478305bfab078f43ad71b1fc7a14b9255f4af29327d839ce2e876300096e3e9f84346c4e99b10b33bc633530897acd4ab532164e9a3cf9d8cc4efd564be46bd0b74d1a22760d5268f6af5bac2235412f0d6ce7aca0d1ff19590b476d2a87933c8a056e85bd17b5f3d78cf023e9e08c9a796ae0573e00bf6e0d547691ad249ea12cd85fc190cba9398fd021f2ddf28e221de8ff5002654cf3ea04f4a9009e05164f47326ac3754e8441639ca4dd5dd87c83cd70277bb2255cef936559c81c48e14424132b90e77f40d03eeac0efa5f3afaffc39393468c66a432a85c771660627e44376dbf5f06b49bc7813498443c8fbd75da3d4ccc73d60284709a423c5e8a789b11cffa3b0121566c4fcda4e87501a3b82f75f02eaae5fc055b5b65b625d2c494f2b1237a1e68c6b70c0e2d513d0f1dc009cd0d214042c1ccc2c816eb561cb6e29e5dbef60351db4b4a7c6154d8310263d950d4e2a30c1df4817d2686062e4b0399abcbdbdab32f73168d010827791cae05a4db9b41f17f0512bc7fdb3f763463597022179cf203b82592b1f86357fcae7ab294fd90a63d85515258e95acc80186ec5bbfe6f5bf0177161d92cf6670bd615c011b1b77b0820855420d448a6391ff158460d0b793e87e948bd62d8682ae3b4eef51e3f7a2a8fe41c7bf0f346f2736906d993c2027ad98edb70eaec609c1ebedec22fa149cae1159bc84dd0a0dbd8f44b3cf7478575ab0cfaf7e882ed8d314ab2e7a7dedc0fdc61e39fe4c08c7287ef98e1ddc5b22806990433e5273f47ca9b48324b97f8b0d4f927c36eb8410aac6c0d49de6614ee9f85d126246a8b665149dd295240d91cd5066594dfa951856dc7c213eb92237cbc899a179ce133d3261adb9d8c15afd94223bbbcb1107c7939849fc0ba9b55fcf71b9702990ab7a2233124f389f188edb19261dc57b25aad58faec5508d018eb000892880fcc8f5546357ac6517f4add7d5c9d37e090b59a48e1e89430c3a7317a0a5bbb974efe960203cdaa798d1808e54a0a3fceaee3bb89da21312c5732d54d58d26e353eb0a7968db30b6ff4d386c2b9e8bc1b6f8d9d55e771c96123cb03c355f6e4ee8757df2d886d3f6e11f83fb95b99c3b71caf49518fd10f8e0f4c743abd6c222b152e43fe4fff0d100144abda47313c2d3bc65e1c5b4bc93815ec3e89a82fc9e8ebeb803aef3b1384d549b25cf2b937cc83cd2a7c123022836106d600dfa0b", "", 0, -1841663445, "7a170d5edd5a205d4cc689d5dfe1f6bb014c4dc81548d2af72a8e27603560344"], - ["032a494f01ab7c151fe33ad7d81c789709bfe8fd863cf01299ec1cd014d154b917b93180520200000006516a6a630052ffffffff0118574c0300000000080053ab5263630063f8f5877c020000000000000000fcdf5d000000000026bc5f42248feefb4311e3419b69662fd18223bfdae341b751b4c560443129bd6cf6b22c3f3b23a2e06782adc9f73a7c4770b2557dc848d7d62e57e60364b9647705ff6b1537baf1d2334346cb2b781bac899ec2b4b5e08ae2ef207f70c28bc7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002fa8c402aa46ab269bf22756d10b3ce60cdab6a67bbc184ea5c9a8e55da4122c94b31d19d7f77915b75ab38121fafc1bfe4e797271eff7b61fd0db9abbceed99e6dd304e571403e39308123c43fe422d599106d3280b0cf3c9cbadcbc9ff69372c6a7206048c4bbd2cabab839d362b3c7026b65308036b5de835296bd4438087020196acca6050717a726506e98a48b850f9b507cac564111a9bf2f4fa025d49b40225cfaaf82522edbc99c564a5771890acd438fda508855cc82b8e1a8c13f00bb10a2a5ea60471279eb15e0cefe8af1de6b0a6bf6792efb3aa67e50c12c196324df01ffd5a072264705496a400c633f8353db74db221373fdd14358cd07a6b8e1bae02239891623e089f4d902f3df5e39e0d7f48cc2c2cda0804db4da96fea9cfcb7710323211c11255fba1ff08ef70ea00456722a3de78cf09838c32b74c425211a66c3022e4be9b305e08e59bff8f4e069a83f54a71d9f9f171cfe254c3bff103bf163a8022340b7bd5f23b51acb046edf3c8ec35468c3ffff0b55c139a39c8af13e44a8d502167fe7cee56a94f1f8ee5638a5f77e980848e69ce63eb9101b0ecc0b43ae70dc765059f96dccf8cfc842b5399af375c7002b8aeccf9c1834d00e0057385a3ca60cca51b92ea32fac8a8a960f42cc870b60b63f41f49a66655594922a8655314fd448eb7caf4e17a64f018ea1b8fb4cba9f8228d2767d9443ba88c3d8238f4e4376fbb2c4e0c2d4b49a1029ab72f8cbfaf3d5caf3baa8091c3ee391020fbd30a7e0a6dd44088db0dd90502a7b3afe63ae118d1213bd770fc6ad972f35123da2b6b38c2af3b78720bfd3641141afa68b0e07a96919897fb79b0967ace6c5e386b1c691c1239924133d01f3ddbda81bfe9fccea9c27b6f8b9716faa0752280300f18edc5dda145aeb6e7d3ca0922fba755abb452f297b8e8ccba8c4d57c30ead6c14e83f69cbbfa013b74ed1a861ae48067751670e01739e78ccced2ecaedf6e2ca49a2f158b0ce42c454c45c772a2cf2b16fd0dfa27a9e0a5a011124f87dbdc2dea54968bff316b82d173009fadcacc93114471632eea032e65df89fed1d3d6ab8db177df1dded3c67de8fbaec971a27c7040b38fd2f479ee93175c089e6db30ee203ac6eb847d9cf72a7590258c2ea8d3fd9fd903d57ac805ed539020986a090c073f980849e940030eb392da89c2945c2d2df1730755e79c864d478fa6d25020910843a80a6ba5eb8cb1fb3bfbaedc6ed960d0dc0771f1ffcd278d760ba672fdf0db1bd46683d0c7956e9bad819fdeecb2bb3d86f3d88c0199e80ddd2e78fc1edd23be405b35c2f3f41e0f0dc98c6f4c8fc996737529d8cd103c7db864d6826ad685bbf81a7aedcd653bde576654f241787ae82b1dbb5f01b0e41ce10e78a40dcff2a6eeb8681dc80701b9b6bc7cd45e60dc5b56a952f2fc22b6aff0e7ee0a96734303e6892b5b2804b611a7fd004fec8f30bb98075c833bbf44baa8e59234410e81bdc61c9e092d59a74a810d834df8b84308cd06829fb28d395bec56b4a6ffc5c84681d6623d047251df71bf719f8d22c64e924500995c1eee22eff3db50ec4a21b4edd9e79fb8ad0f182e3eddc1da1cf958e5570bfe01d723d4215e0456e59d00e9e0603f7cef2dc85f142161233d9022195e7a8e9e632f5d5cafdf4c5ee8cbeeac927bcc5bdf7ceccfc418db50bce4f80976a7b9d0d56d701236a3c76f8d1b1f56c9c73cf9c2010ac8a8835cddb212b93db76b035fa134ab04960ef493e6c63a504ceb782234e02115dde458a029c0f6fbe35a6c54f17b2a1b1fa744b56fa7672f80050ccb20c3324bf75b46ea43ae0057cf3a38ea7141477469c3d6842727a08e420e66ddfd61d72c5775b53201428f64263350200740f83b32f45ee18b22249eb02a9ca21d05c6e48ef45d973518cd296d2aa6d1e5e49b23b182397284c869da31582dba7d6ae724ac405bf0b9d61f10dde367d9f20c562d52ec76d210ffec6dc4cf5b01ca6f1b441bff23a488dc5a778c4cdbc83b9ee6b95050307696a8f738092c9ba005baa35347c9f906a7d06e3fd57afd776a785ef2e69e914d5d2672cbf188b74841daf611413e1a8a26e4b3e1a4ea11eb992e25ae444186deb9424178d9652d9a0fbe72dc730735b1ae4422bbbd272eafc1bddef2b75a6d4a555b25d9002a9863ce1a30c6b2ecd92decb6ebd07665a889e8ebddba0b90dde0f6988ebd229e2f56a8529cd8b902984528596523eda40bc9cfd5e19bf9b944f0114566414bd1687150f6964006e1535ec0782b25d85c020000000000000000000000008bb8bdb4ab1b5cfaa19a54f0656942168c38b149d2ed6114938a94751715e0330add409d89cbed4eebe4a66ec10bdfe30f1b33381f521bcb592a6b3a176642a05c68b9f61e72ad30b4686cae2c123da77fbb31a123ca75d10fc4d592267ef581000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c80e01cc6f6003c88509e3eeb69739b3f791cec3df1c6d934c5ffc1c0474b84d50c72dcc122b410789eec2040066bd92de378c4d815fe5bb55772bebf0355aaf6f502733f0c34829c5dac11b72cc737087a85b52e9824e685e4c239288babbec41934b88398da8210907a6a22358e45080aa9745f36bab9f88e3753124ec1810227c4902e86b2d1e0decff4047997af566010ee4dae7f3482e204688c3080590f0327b24ba99dcc8fcffdd92865134a7aa47a8d99a8f851b467e78f90bd35de2a630b0323bbebefee0a6ba0c2f7bbef1818fcdb98832eaf48bc3789c93dd936b7901c218baa6f08870362b960aa034c07c084b347f2b5ae013e9f0e6899d9ebbe54e8032d519b65fe1b30759d7661eb8d7f8d9d082fcd5798125087608308398acc8f830213fe1fb091e6f363e47306823720c22629f7bed16c8c097ef093573027d2602802235157a2b12748bb299bb85ff6b6f0f509c402c07a163c4111e88f31aec1683b021cced7867dcdd63cb66ba2a3bd6ed58197ceba7f22c62c952c017036e81964a20214e05e06e69a585a6089419eaf7d52683e2bae8ba344879d0568a09f3532f5e7021ae0f9e931a220c68d5d7f6a8a4f121dae7954656a09be94a29fbe3ad71c0cda67ae70f9b5510f15f81ed6e18a770deb38f5f549fcc92aa731f42d522ea70f70842edfc686a68c03d84236564e014fa7205dbc343dd0576768704b408b875d26641c8d4b8683761f513a951528f6a583eb173424fffa4860167b370b5b23152c2b63b55e77d33692b6949d75cb5f101351ea25c23ca432bca7ff9788eafe85cfa15b5a3b7d176b3f076492ecc4b78506945b8cfe48ebd3ad092a764fbf6ba0d13375887e5b23fa9e412b7bf9b1a5fe65b8ec89d8caf6f61e2957f6644fd19c5ad75e9785faa1cf32a72ca1ab00d856bccaebee64022a61a9224e94940a2ab31203510db397d763144629e3369a1f3964d4dd1fde8b1ce04ceb6b23044677514258e6a2a30f53a323dbd7ded403cc059b895615f29551396b20abcf127110932aed675797b0234c1150151c6190d07b17f7c69d92fc310ac13382583a6cee845262094a6b292ba4443fdc16a2e5133c451cd650693cefd701199cbede8270d14689ae5ac4d50327943a58c933b5f75e39d0fdefb2f680a1131e7038d9b12130aa7cfb18bec358c097351b1eefc7a03d63e73f26795f33c13c066f2bbfca2c64511a64a489c3d84131d160ea51564f421ae48c3fa13eb16438b431da3523c6be7abd697ef582b2f175678fff221e76a1e0afc3fce3e004b8c0b657ae4eb3aa4fe171b90f1051ee64b29002246a0be39afbf6579b5085d0e792ac1d8414280d02cb960ca1ed8defd272a6c82d8bd3046706f09bdfa2fa0d2d5d78b842560bf4f7095b22b1b32d94bc2d25997c922e50784ae66ab4d287f32e867631a8ce2579c478deb494005e20e2dd6becdd0ed7720438f50fb6244adadf537be00e136561a0f36ce65cb8801910676be06b278bf752ccda3ae19515329e49e90823dedcc1b4be4b5d130f664b40adaaa8ce97b705016358b52aeca221a289c848e19f798cc54de3f981a69d6cb2ea41b22834ee34a6fee5c261e872e69b62fb0c222297cf78fd3c80d76cf5c024f06931bb4bd18910edd79595ed533a897e3ec8677641e7a7a4e63704e2b1bc39f404235c6aef9ee7fb3fa1b756c53be4b49a2ac3c82e4d1d7831aeb3e6b5b670a82a7beaf47dc65cd35a7f3b25166479cbfff60aea1222e589a1d1449ec19d97a272655651e0f58b8423d252f486637ccfab66e4db1ccf1d2ed4a4d5041f78b06890f370ed3d57a8232bc050b485cf8570f78eaa6229385cc13df2c9105227ca5825fedee8238be8151310b67d91db7f02400f501a4bc4a5fa186228037fde65363982d9ace513a41770525da7c5d6c4385e0004b662364bc5312440a2f2fe21125ebfbe6140905512bd8232ec3549fd166772fb390788e94607d93bf3f001116cac64de0008949daa981e67a657e24b73b5c1f0c10777210ab072b78e90bfd878be48fd4045ac219b6ef72ac016ba14db4479bf9d49c970aabea88fbeda70f002801284f6451fee852ce1b2d406c0db388ea448fa7ff67f41173b208237c5aa791a4f1c226671f1b387f598a45ba493cb65f672d86381aa1dc84b71573930817c1bbdfb4f32d08952afb04ab3f3490f068e4f4a5f0c071f319c906ca3dceac7d93908cb08d4c083f01a19fe809328fa4d4a30e4eb09a36052589ea109ce9a897bddd5c5653566a0d383312c8f5711d799a79032e38ba1ac578e03b3a62786f58e24798bfc43d5edf04b877d7603e297690c72a40974fdec71bc0313309d51f9f6109c4dcbc0f04018fd690c8e8e7491551f94b27b14d290bdd73ebd48a45896f64d6663b61ef78df00e", "000053", 0, 778527675, "60328390b953a2aec3361977a080191325a490521a11420bb49bf20f6f7e09b7"], - ["ea9d4b84015e476ac6d168f5bdf6ba3e1bea23bcb4f8433009cf7822ff59ecd44e51aea8f702000000045352636ac5c26a4702de0c9003000000000600656a63ab63619ec9000000000003ac655100000000", "65ac65535265ac6a", 0, -1916090835, "c4e635b1a3308524cd77ebdfb16f0232ea7c863015b9b80f578e5bc8472650cd"], - ["cc1aa1f101ece3501b2731333430c171cf329554ef5ed89d333f4bdeb8a655a22016ef2c160200000001acffffffff042f263e0400000000055100ac005113a9da020000000009ac6563ab526aac53ab2d19990100000000086a006a6500630052c7500804000000000365005100000000", "6363526365ac65", 0, -1093365599, "df8eca24d5e03174e1fab2471f8b371696d9501a624530201114d8ff83748a42"], - ["0cd4d5cc0288acaa581c03168c1dd38fe58708b5edc59490e21e4315079e3a25ea561c796f0000000007536aab6aac6a00501096b8beb09b6fc9c90b79f3dc3917d68d8d7e94e5d64a1f8424e30920d7a23796e563010000000651ac52ab516affffffff02f1b46b020000000009535251536a525151ac560921010000000003535263bb41cf51", "6a53ac53", 0, 1868094718, "06f9fec640896fd4739ddea761c9bdbe1a835ec167694db1edd02e8cf201dc2d"], - ["b03f84f103019281a3c59b8930c49a6459196c1ed600f1f3391704ec8c53d268c307a44b770200000000ffffffff060206570eda726b1fc475109288c9fc227b8cf02a797dfc4cc60eda083624c001000000026352a188563735eb3cf04fa784d6ba93245833f3d9b8fc6428c1cf61f0cc5f2c01659a9a99590300000007ac6552ab655100ffffffff031c398b010000000007510063006352008c24ef040000000006006a5365ac006bcc17010000000004516351abc8882918", "", 1, 1360849158, "768bcf818d9467a4db822835e9496a60f71cd7d2f6f0e29a79ac59014ef7dbe1"], - ["da1043600382c1b9692d16acdc9c7b3239d40ee697f1ba8cc5b4e717cf6370f66656a5d6c2010000000800525151635365acffffffff09d873d1334cee6aa222b6ae9caf30fec163a6b74d2c9d646a59e66bf278b9520100000002ab63ae54c974153ab76c594168520c37bc2949d11cf4c019d8e06b84ea5fbcf7518eafb8f9590100000004006a53acffffffff025fbf820100000000050000515200436f7305000000000165e06c32a903eaff0c030000000000000000000000004ec68ed1fa6ef0fec9fb119250f4c8857560c16035d651de01f549ba16d4684841402578d8ba1786df0027e2ab72b72ddc58b89b14a93355fb5263848c3415f21fe1bd3caa6e3859f51c1a5608b31ef92123fd63b8193147c32f8657a3a54362000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc9e14d083d536282684a832de854bc372aca43cadde34765ea8fc2e33e93b6e5d2d11a9b502ce42bf804d7fda5cfd754acab64add39e462c346ea3857a4f56028d92a19d0a81365152280784de298c777eb0278a502e3968ebadeeff3bf66c8a41b66d0f56df029170e01b91a5e45e5578ba4824ec9e34f242816648a84850021289439267ff305dcca4e9031dd36a25fe58caec51066776db3895039c53e42f020a43cd8dc633bc201e6590a1a9b94f1180139ad437255f83fe86407dfde01f670a2427db711f22f07534f7257367813e108d0492363db315488a11202d1a54dc512e241176912ba21b9724b5e9946eca5c023b28733b3b9a9569d03579a5fa26430223c0a54d467ddbb8414401eaf64217bc60982a9ebfabf3e1552c4f1fc27dec430306b77a734498bddd1231cc05aaf78a60eec18810c8c74a07dde0962b0dc27c4d0328d9b7735364bc6ecd4b97369eb4019cac35c26d0f5863fb11b6ebbf56726256020a1741011748a09ab4483c68d70a0b7bf4fa59c39549fc6972169f8a87ae19b0032fd716d8ad5594dfe20149689f3dc8b21d03358bff4b95df9727eda64ada2744606000445d814fff91abf53c58485133cdb3c2f8ba085799bfde35341e1e3510b6ea6ac93c39eed1e8bd414b4d50723b0ddf648fee66b8b057479f7c669243f40071c4c6db6d3534ce7c925a23c73d0129cf97f23d2336959fe4c7e48f87c97ebf1545c5f957a7a83717a37b923a0c80daa413e2dd61046b099d4fdf653424a61c8bd7685c2fa3d2138a4195c9140c41ce8df81c0ec85b49506be49b628fddc26133f4b8ee29ec8e604332fba41a1dc723a1daa39dc28ff9d3a5963317709d8e5eb1907f77ef17528ac3b82925dc28f9bcf14777c87d168d336955a2d20337196e4656a4c6874eb570768d598869c6d15599a17518ffc876e63fb6e56ec5d8519715cef67c81bb6a1b67a4bc20f12a247dc12e6848f4848a7d82e4832813cd4b69bb5ade38b9e8bb0682beecd01a50a8aa44a2c3d5bffc1e6e69326f614f32b28e641076acdc34beb6a96943b5774ae3da2b6787ab9f197246991f4f1f631d62fd6c30f501689877e12e9084019631e1e27bb8847ab9aa3c5b159a72e98f050fbb869a9965986a8dd081244db7cef9f34282b30112e0a6a95ef136f2d310a2d3151cee71817521506793e9408139056a94f3c9657ac593fb55b026f458f5751677ce60527d4f47c19b7be45af84edb2f779b3b193935994720a041c3fc32e80dc5ec453206a97304ade085454f3dcd4218cdc8d8e4617793038c4e6ced4b50e2c6336b6a33c985f2717e44e39075f3b08a8f9f0a9627f81ae5731f82094a41becd2dbb1f29d03eb96e7f3935f137a2c83cf613761c89fb5b87cbeaa76c97e76228aaf09764a24bb0c995eb70c985af2a037bb0ec90f58114048c9b5d86d3438f2067c7cabb368f980ec29f2b931b53e974a375edfd83a1460ca270c373b94308676e761f441a82b5cfa13ff40ed3bc37d9807b0737863caed34aa535087afc5c63d0ec1d1151506485c51c33058c94de1e20cfeb8decbac6f6ebb17d41752b99c48e1be1bc8aa69c6aab3842b9c7896f540c7c26b03ff8a9d5fdcd59f963d4af19cf9d3405b9a49c8f1185ad2d3c6fe78fba679460aaada3f56ddc742a0701e08a7d3c6161c76d85e5f7374be28c53dccd47ca5a9f66541c8cc18e52654e5313e1f044e5a1d038d0ae9a21612ff9477f2f220c5f0f1b11be04f57111069cfccc489cc8b9e33ec8b182e531a625f68a1f670600bc8a7bf533582e420a56584d7bd4b6a950aa2fc2ec121f3a880429aae696dc0b153399d835b88e6550a6263ce6d8742047faec98b64dc7b7d6f1be0b762d0be8655e410742386b83ea8e4db1a958c4b763fcc382593ac9abe213f28e57976a855ef9822d963d042e03078f6c5eaf85208ccf6fa5705023759f6f394b5849008e4d0bd98368a738868a7a64e12132ce483d99e95caae6ca25e758d773d4dd8721c772dea9a5a37134f80b29d0100fcb44548f3a8ca5c3302f57775fe5cd7448a4c9b84dc531ba76e4942ea8a4c917b808c753686de1e3975cc874c6db4df5dd8d2c2631f9d8ee50987221702f5f835a7720852cf8085bc78ee970cd2660b61cebb660cf23e89bff547392c4c439d92c63db8272589b0cd35a261dd42e806105eeff27b991268f9466161128af5cef6f0e2c578e5bc3eb817bed5724152334dddd46c7276ffb0e11fbee88839c8b0e55bee1edc2819f1bb1cd82963fdff6c7aa38005f00000000000000000000000000a4c7ceb4995c9f8735a4e51511f68df15e3106a8f3106904334af7bb0ce649283373021425c85e64a54bd667c7bf79f14a607dee1987aee8972dd3dca4bae88f455fe698f2bb3a744c54af3d436a05231e29af5086b068f95d33f9567b5b6495000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e96d30c16e7d1f8793209cce5a3eb6dd6e7f5123d28a4ea48bef0469c2f72c6b2f4f637211b1924ce7cd3ecd85ea47f984f4abb54e1321441a9737b5f0ed5a483e8c714d0e255eb30ceb321d06b20dd254d48c21f9e654e097278d766be081eb3550b60d6b4aaf71c38ffc29cfe07d6fe49567dd1d14074db099d720870be240305219be6b66a8b7203ef7c4e002285b30e56f920f62160ef2b587b7cc8983d480209b476433e745fd0cbddc409f95d2494966129e3b55f766b07271b964f1e40570b2112b6e672b8a84b95e0d045d121b80b96484bf1f01c239099bfbd605f9d1d890cc6a508720d14fbec3b8b7184271f6b93b7f43f9d677506ac783bd667e1968a0317ac1a03596ccc206f0fff6880c357fb4a223973f9c414b699df5e4ceb6417b702178f6d0ba27c9da6328a3f402709795b98e5815de4bf4364c5a9f4bbd473b7f80324ee1c44f879e54f157f660d6a3e77651c36b2ce1b844a58494a3be2504e7da60310b09816cbf5324e475d0636e1c7d559c37f3a0fb5f5cdf8addea5041132be0b032f07e02978472c64436bf9cd48b94afde0fe900dfd2ccac40698c7ece106b248bd792f63aa2bac08f2634f4931cae554c7f92c0e029c0c2e3b1ac6069eda2570939c15a583b484d547170cc52c91c432949ee95a381142a304a74ff2a56fe8aae7b0b0fa247f6f97585575b27695bc7d5bd0b2a979692967d4ba25a7aaf96b44de4413312723791dfef255ce8ea1da652d02147c22d169b48c44fd88d69a5246eabf2150a88cea28989a2871600e74555ac79403d34db29498108c85e33496a740d41b35928367dd140a76ac7eaf1cd86dc24317c4f0d7f44632c5b1062fc3b42ba7e7d1e74d57f871b17bef4e53ef673c1fed2f3ca2f04c345ae0193bc2ce485ec788fb067e8d9ac4f66faa1f28aa5b7d2cbf54ae9a390dfd1de571251f84aaf283cd9806f431a39c16f637b6329aa79422a7c56aa07e151746966caa517681485c24562e166b41f1c1d9e494fdc5cfa92211f8c170fb9845295a9806b54fa6ef7b4b4a237059e44ad03d1c23023b45872d9ad86fa3b0bd1f053597e15e922c5d5518eddd5f4e114d63f85c9869de49117ca840245adc9f07882e6a1e0eda56fbe5c9fc42e4d2d8f02bcb1f8920fdfb1f984a11d89c449cb9ab75ebf0184e696855a8634e28e7196ecf692e836549208324f923258359d2dd15bec75ad576251b97e2c9a83b4570d1725f91c85dbebde7cda3a016b3cce5474d900eb297ce224eb152f47b011f79eeafd44e3f60c97f0c92fa1ac5b4b1347dc00629c73f601bfbf9b3ddaec675318ea0951b881928d56c82ac7b1c04371761b2665fa50557691a0857a68e7cb410f6ce3a39813c7e726b55e92e13f914ea960071029c98dd3bc289d51294be0a31ba747bd89c603d9be40ba392e757a3a6584146f608068b673b24a5a21d4495c10e6e6fa702d2db952acee5adef84d8c8437b995e75b13b8177ba59552cac113ae15594d599f3b06da31eba2c04dfb2eb3e0017a6790ffe6055b00ea5699245b69866ed99576c0b49cd4b8d73ca6ad9c5089afd64a7c31b8f10652a8e8d52c493af6cc9b0747a859cd187535eea5f958e4efb1c6327973e15fa7b133a3fb0bdcd9f65252f3d466dd75834b0bc99e748130e6718024ee3a0ade77e7ecf3591e9de42570db5bb1616132e9b51ddca06ad42761155bdc988810922ffd27c1abc8b4aa651d022762e5439153226ad4e1de693c207ae3496b76b9de38b762c92c29f1526693ff0449b217bb5b89d5487712a4c064f1a283e9a930520520783150ff0f8fc61be10e6ba183cdc9021f92f94ba64e3a4bb27e10f771eb109fb45af24a68b308af8fad9f6251a7941bcef81676ec0834bdbfbe2feb813d2d6ff69d4037551ec7d625c9a57e866cb98ba7c887a5f2670699fcf9b30969c0047d03046e17bc065bd61cf15d4c156c40622071641696798e77d5b1cd13ddbe4e7300615c6b434db9a187d34cb0f0d7c66f5f38261493235772f0219e8705f0fd3abd53a07dd5c10810580521f12f0e92d4ba19ca70d92dfb8d1280f111fbf2b87c7fd1a385f644d96d728aed5051ecd7b9a2876dab5df7f58384b34dc97300db2452b07f7cc7011afee8f31f7702f9f3651fa53fb7a87c4223174a14d161a021516d9e6b59efa1d125643890625ffdea45c311893a30c18aa893868e65dd2acc698245894e0ea7d494822d34a508ddacd7464c4077bd292e9e01ece3ba58068175678b482fea2a6e6f8f60254ebcac2fcd10195020000000000000000000000002624cd299eea61c3d34e037615146f006c6c5611e674bc7188e84ed925e18f5f3effa8c49846d531108c3bb162d98e83c2e698f814273e3e963a1891a65b3e646de12de72c2453c2f76accb2d6e068c8c512b6fac015f0a6dc7eff4dc82d084200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000127571f610c4803b43cf2a0855cad3ef03ef7e2b14b6a72a05ce49b96498012d00ebb6032130897e6c0fb97ae45ab1eb77cd7d9ca7ca5496cf852f193fb2fb8b5ff322324efc388f7957b81342aa3743d2d6d88834165ff521176141578c7e9cd9a0a7f182645311fe611ef32bc52075176cfc994e5369fbb02ff5d3a0d67bbf022de28d0f9029188e0769aa407371c950599b934f2d1f2926930b9c89540a7473031d4bc39225b8e7abccf80922c59f0a9df7f089a309e928bef0f9f6bb56e12b1f0a18eb5c2dd8fc2d2ceb8ecdb96c69cec535d85327c7d4ec32cbfe14345558fa001385f7b79a4aa4f1888f090417e28ca6e9d8963171477cd1b0fe45870d2ef7d6020586d484a60f0bd0483284adcfe1356434edccaae871ef881933f154cc80fe7602192dd05fa0c97ea410109f9abce0159b73a48e0d07622f69c4f8e74c844d5bb4020a45a5be898d6fbb741221af6dca840568a161e6320f74b88053ddec2d08e9b4030b3c6f9b5a82127ba086aaa5c44c6b3e542626e1fcf11898c9a98302e704319a02243a47207516c30d92955373cee28cf19e17b6ffbd88b9c155d8b793ec7eb02a651726ba0d66c225c42676884df0dc7ada7ae28710d5fb9caccbcc4ba6799c7cd451726899bf1c50d6beb290a897a941139f8de65113af10cfede8dfd90858ae077e740e074b055a8c78c0f154ab5216a0c53a60253bf0193f8a960804edbf1ee03bb3eb57753b03bca1b90adff3986e6424b552b270317cfe5910d451e3f1964dca1e1a592cf2bf4ce8c85279d30afc111fd58a0875831e6a06c807881edb322b7c060e15f44e61e22c689088c3d6faa2f30475e85fa8d84923bfd7c6333140b03a8892e979247769fe7610b865a7c0460d9eb1ca9c39cfbd713c12f09922d84ac8c018c0b413005e6cb22a4703dd6ebe0e2a9c125cb11b3d92fd689a13f571f7d52c286007ab4584ea5cacdaa058e7fa5567337b4fdbc88baec3194b75180285f9056cea9d6396c07f5b9af171b11d642317f47be9a770bab1ef39d2fda5c90bba6f33539c914334fbf0370d517cf7370e7290a267cce3253f99d0d551994090d1344f548ed05cb260ad5087e517e831448f3ef7c387e11b49173e460b3668ed843bd448c1e6b5e62b63c7fd6f33f7ef97d53eb270f92a01650a54f057e9ca55549be60097f2342d1f6411fd50150cecb61512cd872db0f262c0e21d1b4a3154f194f0f753e2f4de2ebab52c8de4fa24eae7d25d2159c8cd8acba1d34376270f148ea7684a725661ccef7feef7f81c3eeb8273e91cbc32df99090da49f91469c6d44e536bd198e8ba6a116d3c489ddd52479a95ef601b5041cdb19f3ca36dc5533be524db77cce4d1b9255e8d61a95c628a4cf4f02834e68e798766aaea1c77d15b6d67c1c6aff565dcc14b78fbd9a82408bdefbcf324b8312cdf29d761106ddce55bae250d8d31ba2be1f130b6cfbf85c59e6926df5a396cc347fe499288e0655e8429ae6eced23a4d84e94057f3e7fc86ff0ae73f257e10987596b3dc85aa2d02e8caa50794161177488ecefbefc3c9d9ee4a02e68093023c95cd5b6f6e37d5e1c56dcb53802ffbba91ad9e5ff3bde931c83b748cd2f9197ebd6e2b16d695c3eae122c3d1390880945cff673864e6c03c1229670c01fb2e9fd02c4adfe2b305f665ce5ff97f0e4e745964472d69fb9456188003bda15f8a5e845846c0c9ff59be982dc36c5f5d65bf0937933c6bd2acd83c3bb07ce22b9e057a7363e605ec6ec607d317023f35c9bdd62721a5623eb9f07378f1f11c0df7986419a36a76cf5c55a9aa980f26750021446f40719f802df2ead721652a9fa73450ef45f4794f99bb783efe246057b5526445bb41c8b0c5bfd50f2bd7b16dc1916d63a6111d82135dd63ceef902d3d828799f9d6e00fc1dbe8efe52b915900ad39f089539f217799d3654351e310fb847b0dff0496ec025d9a9fabd08ed88d16b8fe5dfeebff1c97f4145e25c1fdd90292df6e80b9e27df646e7535c783d6538f93da6e38f3baac5cb9a1547361bc1c6dafa0644d9c020f8591a5c5bb846584a1b57d1f09f226974bdee3ec0d8e69194cf31a5764cddea51ec5cd07c74e678b56d9a83b577f1fe4f98bffc9d3e616d3062ad98eeb6777a829f521e5e1a5313ca5c969d7b19648db4d2b95bfc1ec352bcfbaafa6c4a6dfcd04344c5bed83c1283c2a63737cedd7a000129b0ab0f840f2a98d545410c1561687a27040dc28ed8196d1fe46b6eb2965a35f35b8ecfd9d8901262a6fe0cbee646956fb0e431875e954cb5f4e030ebb0af98653150e050eb815e15a7008e976826ba839f2aa68368dcf76619431bde2e582515ab6fdb546b0593b10963570c3b019fafc873f5bda3bef238e11649d0bc5321c732e02ed2a9d88cc89dba24523207", "6a6a63006a", 1, -1240689834, "44f062e40d540884d4e663cbc4ae54a85e810ffea42ff921493c3805ac0545ce"], - ["69dcb5ef0453ab0a5c9b34222bc3e08a62ea9c6ccab5f8876d617029d210c30a70fc28775302000000050065acacac63ba6d8c534d7a8b0f0b5923282e7057520db56a95768e43cc037064037686e09c0926db00000000085165005300650051f5cf5fdd0b34d25e65fae2cf793e3efa74e300f85f7677d67f1ac9aa845098312704230200000000016a140a083bb5f2c2b862e9dd13f83066071054f756f42eaffa63931d176d7cfc23d798fd2201000000085253abab5152ac6394b1edde015a4667030000000000e607082d", "51650063516a5100", 0, 169180113, "f9c16e31842d706da21de0df806ee6d4fb18206a3c5d33526b417add435e2fbd"], - ["55be2d630131b94b7142abfd8c2f7269178be517f0941bb0a05d141561d646ec38c57e622501000000056a63005265ffffffff021291840400000000075365ac0065525377be4f04000000000900ab520053535152ab967f4cf20300000000000000005dae6f01000000009ec063775bd36fe71da37002d123b2651a3a40396d1b3eabe214c7f2086779d7fc1456649bcff29cae3a2ea015a41c99a900023083a2fa21b6a921c03764582fce2a18acaa9465fcc5cc8bb032b87609dee086e5ab9b237b0f41cdd34c670a7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad2fe553ad6889cf033e84b177648f7b6ad71f94dd83a658b6745992ccf9669a5f416f5129c8f0b88683753e201923f28a8155249892f0fc20e1ee1183dad5fe84f261e70717828cb0f5ddfa1489c0cd653d2f1739bdc255acb9225fd4ef30a8f91343f5f3b4c2b5bc9e4cf2651e2e4c45acdcd5a93ddaf4abd73219dfafa5c80218aebda6097fbc311133f4e0b6f3a8cace9d95fdcd7492bde181861a5cb0d6de0326704f24d47f9b5eaf2f42e5af4d07657c5e781c193916b78bf470bd783e62fc0b2f4d4bf71b15b7bd421f110e972d35554b417afe7ba43cd86210d1399b19559511110fe6b946311e9061cb9394a74dc37d43cc705463115d3ff183ab4649a4b3032fc0c6290c6860f19641c71479f11ce9c7f095e7a73600a397d00bf4f9ee85ec020ac185e3e386de9da606381246cf2874ceb6e7386ce5874089bb4fb4ab535565021bd2f461e4c37d3953102edfd3ca7277a388d82465af35d91bef8b24c0d8d19d030dd15d284979be9da1994afe399a4112013f20eeaa1b03cd26cf740a8a9278a4030e1e53bf171ce465e05985f59052d6c3a1e3898579da611c1eb92a241ec816478d711ded2b6c2308765e07619fd33490854dff5a2e7f69b5ba8ce847dbd5089731de149f8a3488761b794135392f776d080c2303e37c96534d27c2625383c63bbc3d6113787ce0de12b1e630d605664aee6cb216f2588b75daa1cdeaa23998a71bde339f4693aaa500a9fe86d8a61c2e2c31b8ad5b1617b8a49bf12406c3e96478e783d4ff6e1f3d8a411f26f7d0ffad597d89e3d79475ed123c1bb6b00676e7e3bd592ab1c72ba8e42dc5169e2909d41bb34ba976417c6f73aef87cc620bf59ff995b93ab60bb1e31103e8fddf91893809eae20b245b7899c5c763ea8205263d45f558df836439293c0d9b1c81e075ae807908f566c761f9310af6e0266b98c55a5ae8925e1ef103c0260359656a3270846a86e19bc257d1c8f3f0f3f3a714ddbcf01b6a99d07bb27975759a9e41704e393f04c5080291ae5793aa3b687032b73f2f3c3b20fcc0e9d301171d1074536f3a8da3921521be5a1efd1d1204cc47e60a14d44ba977b8b4782ec587d1e2e911eed09ca196b9ec4e2f9a6606d59e3507e31464425d638bf335b4133af2ee5ad4c7ab45aca6a0c17d6a8520a40b633e52e527dd891b9fd7ed8e286a213c5885e1909ad56ad2945c9d22f777f6332cdd25186e18f1b24f93b006d221a5179bdfa9c3ba23df3b519bb6baa56ca08f68bcde2c6b993e87857f88f8372b086918b6899e92c3de31ce204f1266261653a738b43ba27eddb2d6161afbd75f75c1d7fdd3367ea5e4ee5500424751e94fcb25af08f33280d9772eb4e72b6ae9693faf044808ad11928bf47545c6f7faa93c052f926e1d9f386c04f12819ace596e70b41c390afa5e70f27874725c9dfb887ae49faf7cab5d29e12a9935bea1b891594c36e74d52503fb219868754ec04bfb386e01257579f043abd6bc309daafc8cd95004707de1b041b4e4a5ae9b64d6b4d09bf8f75abfae0f261aaffd6994599721c74a0594710e6c3feb1b2f70c683610fabf74a77a10107e1957808d71c8407429026bc5fe4781fba99388f5032213b22c7e3ff5abdaa9333a776cd5705c3f62f5acce4c5e12782fd8e617e51eb1d2c9c9082c5d0153e471a2779bf41fe0dc066d2fd925c2ca3581c5ed5214254eeec60cd0299f59ffbe5aeac77fd0d86df46b0c7ad2ca7f04fd3453252d102774b4eb0b75da17c7b315a7953b34b759f365f8156bc38d9b66c4ff22ce4621b776bb00636a79da8feeedb57520d06396750e03de6fc00c3cd7871fe00d161e7f0a1b197bacc8bb06a8141b35a392b1540f238e95dde4e3ef10d2f6db907c8d52b533c9e1b2c2c52714edd7254209f273972dfeaeda537d2f0535f7aa72c4eb1bb07e024469b2df6fc8fc4bc8d163f46741c74df8964f763d8c55ba536455452ded8c067e37aa3ebe0230c61412fab99cfd2c9b0a3d8c28a6a7a53d2d27322263833c60dd94e61fd13d3bbd5e98bf7287e2ecce6d71a729dad3d38d27f1f1890f2f9b1b51a52b4a6b769c4386d23923a21c389f4a1a5c98d2da008f06f20855fc5e713dcf2028582b3f39252c06bbe4157013f6f87b3c77387e66c85dd47708e98feb929700d1c32003cd91864d796173b91abb46acb51fba30a2253c5b917bdbf98319723b766e8c72c3c056d930b7113563d4c6a16056f3cfd947c2433af51bbcd90c732f54defc0698c47fe6363499ae4a7329850e9b00000000000000007765610300000000ce03067158e407b1f83ee826a83cdcc0edf1603ede3e638768d07bb0cf4cd2cfacda96aa0b769b01b6a34a95b014637bb580291e9826a10522acd20b55639357f525c9428a80d4aaf3c9de389a45859f8f241a5e782d0f3621dd127908429c8d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de04c4d679375b8e553e4491e14ade38dfc0974d57c30d3ca5e7ab29313766af9e751868be3a83a5a1b5b3b75c251540cd0bcffcd6d210bec420c9b8b620b81de4ae384666c4b8ef5213cf7475ae261e83369a5da5eb25a3462ed9d133dd49fcc7ea951b12c704ad71b77d2467dcf82a48d6688224d5b9f80d7951e9abb7965a03033afd2435b41468cc8843253ffb8ad63e791bda27806a5d3358f3585efd53a5030d7604a82ed43c24c5f855516dcd5a2113ccb36b9978bccd71f7741cc7b129e90a1a07fdaf5ea097ec138a0e4e5f069e8296a1f7bc76fe06355dcf076e68a6064e182244238523357ee5c33d6da9fead28ba9a22b77f2f0fe13674ed5f9ca588c2020df18db8a757a846d887f130063278c25cf51b75d6c56537ad712bdbe59405be021ac7d72a14b4fd9c9926fadeeae914843109de702fef3c1257739e06963f1ae103102949c24583c159b6dedc05f2fab70e2e990dc5fc7178f58b9c4b105abb92f5031e009393929b6e84d191e712e65d360a30fe6db524991c707e19a4df244f70ef031aa4e545b70ec4d84220c31f6d3c7c8d20904cab9e3a6b2549cd63ed57da49dde8925cf96214123de40d177d815b22824816bfd730432f3a85ff7034a08ed9036020e0c066a6db13cb2883d798d5ff521aeb4b40286f85aa35ca402f4ce221136d90f7c9ddbcafc3d54c52ceb0c86eb6ed28eb9a9bbe9616992c0e6421afb004387933ca34a81904e4cdada099cb602a7e6c2f3fc53a77207ab0e21fc9a4eed6681c332ba775c17e84e30c563ba768c12c12a1abdf94b52af2b0eb2e63e645acf3cdbe3a54234e201025fb1cc9da68d0ce3a9cbbdb9554de3ab914ac0ceff4d0824686a4daccd97100428dc947281d35c53e341c918a6987795cbbf5b713a0bca511d89babd1b3eee16796493d30b330766bbaa167c7dc261cb22f9221eb3ffd50caeb61ec33599995f3cf4ddb2a8f06fe1671d36931841b3f942d0d57c5b2e0c714c7f0d8ba9653e9c6a1dce722894fb48f4bd2188792f67844498d442a417c7910c8b382b9553bcfcdf89f777948073dc2765aa8742018950685ca283d9d2e380b0254602cf56fec50513570e1d5d93b095b3f89243005e8c651e3d2525d36fdc15b92bd5961cfd574f89eeb6b0b50c7e3a96220286a628992280c8bb031304ca00067cebac035d216aa5cf9e143e412225c21c707572fe1874d5af8f8412f3a17a203e6484a878eb0f2a7e8b47d3ccdb08ab1a3b551128ba92589dfe6b71026f240d23faa18e28a1f456d5a4850d8b22921ea787812dca1e6ac07ca7d943726b0b0155e93ed514969a0e8067bac78f04a72025c89c77a2fe2832f642e12b7568959ea31258032dba31ef5e18ebd6009d6cf351bf33c0f4e28855e0a4fdbe9f3f0837bc2714814e6ebe7a901659134f060fdb88c1042420e7454012f97ee2b217858d35f377e151845fd41089effebd8d2f5f6533b446d807e64e355710613d5ab4b3e746705ff1729f6738de0cafbafff3618428a42c1d11117d072733be0347ad08b1c38988b32e5a4db3cf3ab87019527b735f1985b96cc2dfe175e8e48bfdd2a95bd1e157659282cae156cc4459fc29c054d23463f4a405e01e223b96d58448b222ee913777481b8bfee8352c676043f4588311e607a0fdb2c415e76f525fdd486c9fbcdcbf3b77d25ac10f9fb37e981bddcf9e92031d69dc8f5a0426a340f316945009e84b9546908cb3762a2ce504ccaa98611fd5fdf2c2567be137ee3a159762b479528abc97d7f46c444bb102111a2aba8f3ec567e6851c0b5883429ff40ead6ed1107452e90fb0024861a32b3616cb72c6bccc1384afc44f3a3ce1a6e1db30dac1a75ad409528161cf0974ffbf187895529c58f126dd647bcf956ebff9f572392f0bf27c76b53e2f2169d103dfa8422c7b34fb0d5e7e15362bcac42155a4931b9e6a8c55a85f8675835e9f2b98e30b6830959307c6bda6dd1da973032e9df57f4eb9f2b26e5a94c8d0958189cb923c6c584918520d72de2cde2713e014f94c7b027ec67d224f7b6494276989fe42d66c8f9e444806179564eb667912447919881cae586da93b9501e8bc380f869fbbacc98d8f9cbed198596abe825c53482ff699947d62a70f0a2db346b7791b174731c1adad1d3e90c654d5385a93e44dabe71a00298d11d5cce7723d1710bc78e802b340a20cde7dcf05d8bfafe2bf169c0727960b2dd838c1bbc5ae6be6f33c386e352ea91c3f80b4896964a67ba77d4c4ca1a9d2e0814d3111c2e4594830000000000000000bd2e840000000000f04b5c14d36978eb062ff1cd0365748491e23e8a1865b94c6b64331be18ea6bdb56116b1dd6e5e4afb140037bd2a2b017de07a51efcef46ed30ae065fc8b37d468db5283cb6de49e60e2d4c62388f741bc8230fb08bbd50d061acd01937179a400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2ad07216f4f93180a15afc1b6fa4a71401e1645f1600327c7fb8d4348c86954f449c0097e804141d3e1b31ba80f8f30f3400738fcb79f9324df4752ce34c36a38b09a0eb659a1aed13100936a2c669a68a3f35f3a87516e908807210b64e7d827c11425d997ee006b21cea3e09d68b6728aa1254b81e5c074aa3c3d3cb23c60032232c6348a384293bd2244cbbb1441f3bbf7c37c22ee7e1825e44850b2c405c2030992050825bac74891eb3176dd7407574a802ed8434cc9b909c3e0a5e22152c40a295c71b17f11483779c20bdee39729a1c2ffdd6198e0df23bd8228eefc6289e12f2448988efa31a33ab5a1e15aadfaa72ce41a51b6a97f7caa8883e6f246a5f6020cf9dbdc0bd1d6698a71b19dcc8df7988d8fef1227ee426f1f8af6e5c9bed9f9030ab773e9b95c32dee2bd5f8d744884ac4dc79c3b6940a1c327367ae40f466a6f03219b0ed7d1ea6fd8e0eadbe5e89ace092e328881366371b4e8192cda19df5bd5021ca14cae37f1a81ac57b5962fb31d302a551390dc3992ded2409fa8792a7ed53020948c2ac942e03573006b9ba346c98b17eeae1d42eebda0a59fee324ea685c0092e50cd4ca65211fce3c5869d640275e7bd8ea114ca6d23f361535fdcd05001150c6a7022929fec4232d4fbeb2286c78fcea7e376613137316037e6b6b1aa1c8a60905f670f9a8a204bb8d0117fa2efdd3b64e99995a99ad5255daaf5a6e25aeac2392e4f360bde1570419a0c6d79de7777d0c7442c1a2bebaeb335fafa8dc552228cde1e2e283d627e1a4c0e04e4b57c73cea2268dd5d44560a24bbf052ef7f1633a3714005e1e3a14d6256551fc1d758aa8d07531bbc4043aa2033bc01b5b67e9822dcad6a6eefb61447886456c1c02d1af4720668fb7286e76f079c90382534d3fc287fc10daedec21a32c236bc8e54e27c9c5ad9a667d9fc6f2389ff1b1ae5a28359469dba22e0c9661a12bb72dac1eb06e99208209c839ed7688f13fa1f9199a8b9279c294572da27c6eb71ec8429539b7de4dda4f42e7e7c43ef1997b5c1cab2b59aa73a746c703777438ab8c73b1e63c9990b2c763ac7627c07cd9798e33a906f16639922a0c35cfd763eacdc562cca7eb9d71610a0c77083ac8d5ec4d73d204452dfdc1636abe4bd3a359495a2f467f92601304da949e1728661880b2656cbabd29f7d0a79f9c7586c01fa7f7001a37603c95240ba19c07f8a1ce9af2bcd94448483033602a327adf97bc56872df5aa48c30fe05389b6b37714c8c83dfb2c440d13c8a982ee6aa5cfd13a141bc6c049d3ccdaa24fdb824e27e596700d2b2e350b02d56e97e75c4385fcc487103c4ab8aa913e83853ff9374d4c8e731eba568d51046d68704f3dbe882e2827a243379f6a9392bb04544ab75a8f66fa8f37638b1a9a2327c1c993590dda680d03f2c0aa77677b9f9b1cfcfae8ddb619ed308cf2a430d8797cbd683d1f42ec973457ccc3f1e9704ca3433a16f65900b1297fb9838c52de2c85c11bdd65341ea72c9ec3c65b0be1ad9c6f132b6d0fdfa3aadfca929c5830428ae008ea510887b3fe9a8f03ac5f21a3a3846e084b9022583919483d0a30a85250a290dcfb889f21e8d8d82d4e787d305e91029c87b51403a15a38e68785ef282a392a4d1bef09a6b5563620501b54f7454a77ca91bc66fc161846fc6edeb097ee6c855a5164774726b1cfe255625f08e1623e1ca91e25c12f25b2f9da08dd9d5629ac88ae98b57d663321ae81d3ee0d2ea809c422cf0cd0b5dc7594f67287b30af9bbbdf62d7c38970833dd9c761bb9d94e9261d39213263412890fa8d6bbbb0a63e532db6c301b3f38d5df57c2da1a657e0f5f8bb221360008a8a5d1b3f1dd4bd15a32d2a7eaaea7a18f7d0afb90683cb7ae84a1d5fc3c05f3ee6935b66da7efb8aa7e1c4088f7ca57d4612d0ad687a8ac524889cf515573f472c1ced70e55bc0c010510678abc95347487b1598bf1d1c07df1f50665d03c061a408e4c7ba38758be3a8c50b9658cfe7d4801e5688ee8b1f44e9386c9683f2f40cc1b2282a24c437a6ae6026dd13f724a3a68d42ffb8a2127ba74b1fab7cea59cffe9747dd0f944be4b285a57b724123a869a786cfdf6c17d32af099a764ed954526e8e5919cd5e379eb487b6b82674f64d8943e442ba1a18e9b89c44241a749dc767cc9f44b6c8e57a6caf6dbfcf255f0c0b130aa50d842bab44b64b5aa56559945b7f28d5c21dd4a4609970a321fc844c6ee723908c0fe3c5c7fe0f5f4ec30bf25d428d338991c8b38fb8ebea1b5cd8958dc51b7d1ee93afd2421f0d263103ad15094ca7d25706fa9442f2b8974765c42e4409458917f7024f4a6de8bfd3ff5751bb0c752673b6243ae3c13e1dc3c4f0858fe2e602c4447561a4a507b33a3df3a7fd21782c0b9219a525cabadddd0b", "ac6a", 0, -1298197879, "bdb945749e4d2091bfc08450ac38449e41e4d4275b6db0b41d12561cf9c49d8c"], - ["5aede9bf037ab9981f60acecc315bdb983dfcbbda67197db02c9ad64f43f629f6ae70c3f610300000002006395e1786fa2fe148f648042aba0c4205c22fd002af02ed5a4fe9559e2fb1c04b60c651fad00000000085352ab5151ab63520f80b5a289f5e62a89909c839a38958aaa5e8b0a0b216291d2fbfd02a391812a476c337901000000045263ac00ffffffff04b5efe501000000000752acac515253ab2e6ef8010000000008005151ac51636aab3f05a601000000000098263a03000000000952ac6300ac6363acab9bbe7300", "65", 2, -1506628071, "667dedc6b69f810fd7b6a4504aa083881480b25d4f7b247ec8b79d8338212c13"], - ["6d398dbb01eaeffa619e9f336f9f36c22777b17bd91cdecec28707141cf3b3ee56b19ce7de0300000006ac6565006353ffffffff01ede4ec00000000000000000000", "", 0, 1136078499, "ceb8da137e33912b22e543fd2a7d612f04fbbe148fd81762fc59ed7dc0a1a365"], - ["8ba8c3a904aeaee25db958c1e8cf0c2958c40d5930dc8ff626609d17fafd3a61ffd70fbbf203000000066552535165ab706d4653622c952bc1b954f5b3efd01bdc37e2e716f05e369af6c37678b2f3bfea1a916601000000055265535351cf0a94d5ce4ba512295d7339321975def47a6e77560301f18eb5ac787e5b69b3d635487902000000036a52abffffffff64e08af76c458284f6bf2d10a7bdcd7e6ced63c49409bf3e91b14e75413b62f70200000008536a5200ac00ab53ffffffff036d934f0100000000065300ac53abac0723c4040000000008ab53ab52ac65006507a5f7040000000000c6a46a24", "5151", 2, 735845796, "9584bc3d5bd175705cf4827b0ef53d09ffdd971a73d205b0aafe85783bdbe142"], - ["aab932b70250da6211953210115aae2c1067bd41897228399d83674f8cc84f6759498a40f6020000000002b052424e00da443d7ea5629e62f7de50a022991d6de059d8be6caee061006a6ab9261c020000000152ffffffff01a1a53101000000000863656a5152516500529e36d8", "6a51", 0, -1774314734, "0fe8c376968a59589ebdf18e5ef12055bca7cf00f4875a31b1ccf9755233b068"], - ["efdaa37b015a168d5d1f0ae8d3d2c2eed29b95f8ee9b2d2e16f902beed074a474df26de6620100000001ab2b95ad4b01458bd605000000000863ab526300636a008b8db0c703ce8cb602000000000000000000000000d85d40e47c2fee569cf64287417fdfe8315aee5b6975f4680703a3e660ab3d45cf441587f019f73d132f804f8c3df63f6c37a020161684a47707e01d6c3ed30a41862acc421e01c5b81846878f02bbd78e5d14a249e24e0598affdb1f61c8a310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049098cc0d4f08fe09bbd42bc52611360f2d7c6e0ccf9b2d0b79cc632bc4304a1720753e58b7cbc0b56ea37fce7f87fd90edfeb98335f85407947453fa3107900310b18309f8c3eb4eac67e3295bfd38a09ea6077a43f87cdd4793f7191ddc5aaa26fe274037d0bad037b83676f71b86c3ee3252c2130a94b399487f965dc72d203305455d882704d877b6bf00703f9cc4934adec9a29946a2d6772fb06dfee31fe030db7e2a279d6e22e246e411b69d471effe74ece73570d267d6c844764b6585f00a01a9236a4c0c464161797b41b0e339a61eafc2b76e3b300fa68fd43f5742c5992951f0fa98d70731a1c48a97207bf602f9b84919aa0d814bbef6991f32280fb10313b62939208d5acb465bb829efe5b65296bd683011b337440018d961d72d2e3d021c00c8e1f462eea02c87b6c55bc5eca9e2e8e8cbe3564829cb4361648c2d5c870215106532731abe5f548725bd02da1ea5a6f653fadce0e420e57eb3728d22505302011352d607702022996f40d1ea3993389f6f3d6e8eb58e51d93ceb3a73962b1a021cf6a81176eb51c0c44c15aaaf9bf0726da6402127f2a58bf51e3d902a871a26333addcb43094e086aaf250b51ee74b1387338e3453aa95e3d5a171a09773fd1bb2e28c6df2300e6a7e620104dd3beaabcbd5ca0bd150061b4e8ba8afbf02a49999452d72e15c555af86be894ec71a3a767e9ae21723d784fe68374cd05061dd020df1d1a4f89afaa3c1c0aebfc4d91d9a0b2b289fe714edc4e909945dad1bc56cf9caa3f71a4f94919b653af69f45516d8e88beadf901fbd81f62d932ba4a18735a4a4527858e1d4665d4bbcd3c43ea01b01b539c4e7cfcc3502c9298e6e0197773f3fc91c8e051b4406cc948834fe07677d0fbb67c0e4ed67a810402f3cff1648567b4a27a28820af6c1e3a809fe23845c14dbb8739edc753a1a698b000e386ccdba98a8e73903da9dc74bcc3b7f14e261b7d643ed85796f555d89083aadeef7a344c0604f1c320adbc255b9b0ff0beec691dc04c077b5d2ca9be6c7868020f148c9583d75ccaef761764b6ee99832f6999ad45d885b51eb3af53100ab7c4258994a1ad7828729cf7ff219812f60d73d19b11af3aa102c387eaa3e3503d385c725e98d2eca62436e9bd9455573a696cc7ab778a2b6465160df8559a10ff38ffb230e531815858826c604320c530277f39bd0eb3d1ee812c24690ed478f97596fe703e9cf2bb875e73ed72c90cb3629d21be5e0e0bceaaafb36c1fb54ce76fa8799f164a7f218f9a893faaf0c416199752db12acb1e9ec31ec2f80fb9380545530b5043b841a73327e745c512c7033ef6762df6b15c2a0dd0949e08d93954c9fa3ecdbecb45ea475882b3a3c475cdf9747cc847652a4fb49a30159660540e350b0cb1fc92e68c97839a38dbbdf015770fbf726dbc901d8f00065ff018e9a34854cc767c211d01bf5ddd165a787d0b567a19a4b42c7b78d9e88646196f0bf7a9e96488c17772b4d74964430c65c8be815572429035ae363ff8dfcc03a78311731443e234298c78778f1002103a29b81d187a7747fcb3643c419dd0903094b8a20e0582f536cbeccb6f9075509b20b8a8abc4c31b010551ae1e50f294ec9d4dc96255f86decb6078a6de5eb249277b234ca6e196916af08ec0f2b18c4c5207af8815c1a20601598ab04b3e478f1eda3d3cd23ad2d65e2a13ba695625da7d64a0defa1b3355e81b67a236e3f0f1c2248b4208668986f577330dcffcf472014168654d0166e23fa340a5260a3d1983d29bd88cc55712b507c06bca6efcbadb339eeccb075784e12865fa6f9db24e2e8f7cc83ca1798d92b80277c8b18b993f5198d3643c73bc17fbec35159e15a63f3c7298f40ec3acecb0dfff22f2e7508ca0986179b9cc369a8cea8679cb327f5b9b959ad99f1d36abc85374fb6f39de6b7a7575d0714603ae2556a8f55d62c4d92fe21604d46697fb8cf675662e9696fb4900651ca246cc8437f442a63cfa54cfb698cd2310f417bacc181eefe636cf4d3fb45a3f5b942bd9fc490e42a10e45345bbc889b7c93596ed1b68d4a3ed169b0d68786e5dc83858589cc71fe09cb243f2452aa21d4f821a9aa0118672ce059e458882ea27119f9092021db22de911f97d36d32c50e041e725fb2d73eeb4adc8de26142fc14e827e103309d3cfdafe201548fbed60c621767413ce7dcdebb58101067afb19cec1bee0d87eef049ca87cc2fa55f0130f2140a1511db4248d1cd359d1909c8abf3ae940c457f2014b7541b78be4ca2236f8f9020000000000000000000000007d8706e8037e60a44f6e79808f45c4cdd2e77d81776007505b829617d5fde2e37f000a86e38dc38d318ea90aa8ef1f30ba3d8c4ff955d416dc42ab9aad0b099d0cc23967ad0461b0e067435e3e8e386b5ca0cc97eb70df89005fc2da2cdb44780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017aed005a6c9bc85480eaa46d87886e582d79e38c89ecb980b43c4378323de8bec96a96b97256cf57050577183dbdcdc6c39d5fc49be7a8cf0c0e689481ad4a9f9013960fb34c17f812054c9ff32820f84756c7d6694141ecf63e03e53c847f20bfcad36383903d42f5d6935a78d1186c2253f57ddfc9437331dfe67c3a1204c031c1a28f244ca269c98d4ad49c86d02b321fa79561585a654160e3ea8730fbca1021779e5253e4a73c0dbcc0c1983f43ee69dea12d2515f6dbe7d68841d7d55cef90b0630cb3b4b01cf8a5137f3fb79d19033304e2f6580339a0b12a769b642d50ce911f177dc569cc3a03a6ef01c53453a141e55b71d8daf1fedbba0cf32c5cea3d9021ebe059cf244ea844615239e53b848d135bee164c95666f3f2d603ed0aae60fe030bf72b10fcaba18fe99c96a31a160f897ac69f10c770d3959ad60ce8ae9214620323430ea640689016106d3c59cd1d31345a14c7073048280a91695ed23ce48754030b7b7f4611240c8a1ede0bc6c91b69e3bc6dbfeaa1d8f1d048111e2389aff273032fdf832713d39288598a1227a56c27521aa23c316cf886bc024ac3734ba339dbb5a7a30aa1ade57ca845767e7a68fea803aa9e5a83db5d977b3d15241d0cc9d53f612d0e89af85325cf579f1dc9330a9b33dc21de537974115c51e46fc7dc818325ece5f3ffd96a063adf2509da718a606836bbb6fcf638f5d9a3a5843effa900c6addc21e579f498d0fdd640a27425b7c19d1bb2473038cbe45e7ab5d7862a4aa785f0bc865926b7cf1aa51ee5a516f776da6224e5de48f87456d426911481716bca4444cf01a2718c85cb6532d4fc85d96a4b4bed4b698496a2fb158e9a5a767d1ef8439c7e88ee97354f17201954943231f0bd7e54ecdf19962085a0dd9207462930ce49393946c565be9cc402580dce9017ff571ed848cbee1d82568fde147f3f8f67cc9e543d526a4d65b6f356eb43ab43fef557ce5f129feeca8533febc0eea9bc950184ae1b58c71459f64c1bb04675b959467d1706cc305581695d4818de6830d8492580149065e8699be0f60274accc15721188dbadc97f4a2881cf9fbdaf92bd1bc68e33d1021dc98e05bff82324bdd3bc88ffb4e9e6c54ff3203fa0346538ddadc9e571f6cf12d3657c41f586742a3282ff8363a2ce1d767eaf9c8dbbd121305f3ae4365b9739e381daa4a8001b579959adf1de70bc7356b688361fa0ac57d2d227d2e37b5c0dbd93de8310c4862d5bb76685e55567855940a75e1b501c26853e1b6ddb7245f52d389af73cdcc51b8c113804149d13e266e6226ef4aa9dab670335892b4dd511aa4e84a9ec2c5d5ef7d734cd70c42f431f7e411a29c7d0021dbf2a0722d291c132cbfb929841c2cf65ff2a4c9e2e0cbd83999dc731620334e20f8d91a7acaad1fb6ec774f33329737a94ee8fba4c48824501f73f1877fdbc47af1a16e2fa20160bb02575238efa3bc3f3d61976db9d06350434f23f4ebd74357f7ecd3c4ca1a510e8b3593211f56850b4267615d917663bb2912eb663fda9b161d1de6af1c48e025a39bf8533d95d7078d26bf373bfccd68338e7b7407a85b2203b7572ef7a81c9bdff7b6d9be5d1c494c902c0085bd3be992e7fbd11be14fcdc29d75e4f659d7a52bdaf784d297f65bff85f4287b9281a00585473d4af7f73f79e420e54371e0b22ed8c20a39f1717e56d10a4b9eb791ec40d782526b5015adc718cd2f8349e14f4d4a5dc69ca6357b87e3c906db1154896eee80e7a42cb95c5dbddab429fb7abfd74c2e1b37f4aea346a526234569b54a7a2df70f84ba3071e359a466d61a6eb3c7d97838ac060acaa00870740cc228b513d4f4924b47aaa768a681f55ddfffe45ddded494cd183e9512e0001e061c7c96134566156737d9d0c076c5af07e42190570e2817902cface024fc1401f0fcc3eec98c7352ff4b231a0a5209ea3eb8685dfe68494fc46edc368203cedc94f3b591cd2954ef03240f7ee4df4705916a9dabc06aba86c7b1253e9bddb4ad3d036c3919745443300563596baef84a410497092de530c36a3ec06fc5820c1870a007b655156b54e5f3e714534463d2b71be1a863d62615261029234fe0aed3c383af07f5e425a59cc77c38adec36f4a6ff03480dfbdd0b1d49a46bf1f0571b8319283847940ee52998b5064002ccaa770b095cfc8f00143b569ffef273a4ec8cdb7cd63b48da77c72fdae0496e3ff0372f5340ffb33f8d24fa3d023582a91e889e9acb1a45e64348b16465c688aae156cd48d3670c3f40000000000000000a2089501000000004c49c9064bfca36d780efc4c824c1f813f5c257a2476fc10d5072ef955d9d8c32cb321cf8dcb643db958d20d1b96309810354f79dcc75d2849be3b5d4a0a78c9e8b01c2f6322423a39c274646a1139356fedbed57e5fcc37d8de604de90651d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c050c851598e12027cdd9ccba1818930734605c38626068391575dc5efbc9024608ef5e960297b1b95f55205a0ed8480f43eff3efd807a38f5041b37b1afd986e027c0693dea31a5fbe7c279f5e673082e67ae068bca2b8c97cd5ba6321148122ddf3f60c8d12a975583d3b9439739285100a87479f31d4693f42dbe54aba62c0310adc338abc60b33ad19a5959db2ea59ee650ce3ffb09a68e4425db2de7d070b020372790f31660a270641741be96d444f339725ab3d12ccead101d8943ed62f850a25260fbc1f858ccb88daa79b1b9cdf7e036ccb943d9e4fe5de10f7f6220603112514d2b5f1dd58f6e73d997d313aaaf960e62ef7237782bf5244ab2e1a6eb6f902139c02fef1989923a435aa5fb3d0be38906c3e28ac0ea8dfea69762d9db05a90021a07ff1392c0f5a9f9a5a0af0e056fc1cfdf637c013ea4080b9a29dc2cec44be0311fb5648559828fb710bf6a34568f705ee8e143b8cc891f8c85135c07f7142a8021f10b5d6e163cd97db342e7e4fedc8bf3e660ebc763fd30834667050a4336c420211da5535d309f68061a32bd2f3c13207b4f842b84e3ce2f1d7cefc4e7fbdda12fa4758f296ebd70a5550f558d3e970c47670530e8b7c51aefe98fc48597de8741489aa49218560cce2ac0d01020f274c2d1074c6140764689b05b6cbb0451201e65dd83e6101a21342ed813202d9fae6d39ca4bc6981de4b99309157c07a520876cc22df7ccd7edbd350d57498374e9f009b4e63e47acd12c825fbe53bd8cbf8313016e307efd5535c5c70b551e3d0115e133f362aa19e50f6027a62de42cd0afe0fdeb258b468d3098a849e3d690332c2b9105a1c135a28394ba3d63b83ff417762dba3a0c9ac6e56da633cc65de23d7eff3a22653112e4c3c20f5304b091266d49ef23b889702b4fb5c245fa682e436a116682af0deef501e3d9746abf5bdcdb04b1f2d4372e985cb82169fc92e4a34486e5e0ffa7d99113899494dbb191b885ab85ec5fab48207e8453bc7bfb949a58675ddf25ac2d6458b295ede58bfd2e05842334a8037c8ccfc6e9fd7d410acc04f1dcc9dbd446f1b30384e0cdf83b9bfe66e132e000251034c1c37497cad54b8e2a26b750b0da3f462a40f822a13952112242e5b09513af01c49f37c6dd63616a83ef42897e95c84ed8d552b5c10e4826c66e9da1f7c491514a6242d2ace7150ad59a82a29ba60a000fcaaa2a735271a9cb8beb1ad44a09a17f5cbe74eb3100afdd1086337dffa1a5bddbb14badd8d33909cf15c107f863ebb8b81c5e8826ac18ff035e46cd3a9aa2f183a428ae428b1a4a0d50de410953a402cd34756ee94a77b2368808a9f09b50089a9de5f59ddf8043afd9d69f6a58a6c6eedf56d9aa667ee97d10e0a0856f2b8a606091923b83818b547e77d8134b879f50da87a04f70a95ee3d7b8035f42b679b89b596d6a54affe4e1b1c55551bed2184b6836fbfc52095a68ff3619dd91d74892ba671a144c24cc152a423a7c02f0350bcf40455c0b978d77d4e6caefe43d1e9d2ea79e332774e8561053a2f6f605b29591752b995270142c084fbda343e17584caad6beb885d06643e5f54beb73316cf135788f708befa5bf4e1641ff73b016618f4435db68869d872abfe4a6308db023f5a267c5a6a0330fc6de6eb9c270939cd071da688d69324aacd3c3d5735293721485f43519e59bda5e4e94d9e07cb1b347b16ebe9defe6a829ca4dbc023de08641997f9278aa9763ec73187b5d2f03bd80e68d0778e52cfef10e5268978181cd978952cb4a2f2a49921d956ef3f3b3f0f2df9d08e77998dd7f42deb50a7b5cb4848cc01d1960e8089a8513f7c6a2044092ac9a4354c1c31aacd657cd302426bc86e342306242aec06c1b5d4308282966bd1302f70c9edfffbd9cdfb7c4c105fd488698bc253cfeae5adf041a2cc79f422881a4f248bb4a2c61221946206ec081d79854565b423b34f168e978d8a691e41fbdda9e4fb3303292c5c6be382db12600ce38588d65fbae1ced80b61b4ce699dec39f1d277239cc4768acf25956dc6a7b0fab9f7b35e0dd758f516add3e1234c50c6237692fbf02efc65608a50d88952dbba5a246d05db859c7c1afa31c487c92a252470d3653b410f4fc5715a865708366e3294bb341c0cff2cd438bebaed434ce09cbb608d0b82025e6b1690f585a736c52ea183db58c4546706379d990c71f148abfa9b00df205272132a61816887261a5ac897563b876697080056d8c64a1cedfd0bd720f949460834862d54c446ab9ec0e9ec9e73f6834cf58fd877780c72d2fc3490579e7f7347a26d7a60db37962e02c045739145e45a23b372b7ab441fc516ddc96e7639eba7423b70cefbc8ef907cf96d1a099a42f1397aac6da1c201f13fb0fffe2022d05581aeb0a04a97c40df37ad06", "525152", 0, -1654978657, "c01782158b69fe9e15b3c94646f2be62866ac8b8676c23b54bb7a9771167558e"], - ["2591496e01f779ef4946e4c6a3306a1a67c09fed6ee9be8d2bb62eaad59b5be8054dbce08100000000020063c0510c9403438e2102000000000452ab51652d0ec5030000000008630065630053656aba5b8f0100000000007f2ded250201992f0500000000000000000000000029a62c583a9206af173f0a691321d1e7ec30d751aaf091d6e6cbb0ada5ae21b515fc97f19d8e867e838bbf9148e26d231be8402aa314bb618f0003f86b1470695b43895dd5239f4dca8cab37970e93c92525e0dc2f1fe636ccfeba904ddf02aa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007017f3d8344537c7f99d73fb8c2317a7cd5c4842980a23899090b1f944f8082354296dc6e414ef556edba7d525b7b6813f87a58f4b206a34adeda14eeca48d7395c923a5b0f217eb765c7ce1d378793ad7243f32e9435348e86e105f9fcb1c32f8c3a572a5140b39b739110f443d3bc65838fa0aeeb7494e6cd99803f43da37c03114da1b96c817f1e906d61530ae9be3b454b5f81f79520fa3e7c041bb09d5623021a40565105a74381414eb67c19aa22441fc10c14eac75a40657116492feac2760b0f0e0997114fd39d73adaa8ac8e76b6ed40ded8a17c2382626087f03cdb1a6d20a444f7b482ab9983560558694f8c5b3f2787df6c5570701330d6c504fc7b3bb031ebb64187138a69bdb58a5f05d8452e17c410cb783ca37ffd43ec417880fc107020fb031dfa9377d6a7097f6edc54d6b796cebf30097964e45467e644892deb77c0226d62b289416f1b50257c94aa652364c925d4b30543602a65f37dd8cbb59126902178c03ecc6374b9fcccce97b4300b7c3cf32a89f4a4b8cf2630fd8846ab99200021dd63ac4eacda2789b9398496503004cec37489eaac9b8bc5c96c14ebeeaf12eb3c7453aa722c2954f7691e3ca5dfd8b5f7a1bfd57193e33d8327c04ab8fcc1f3a0c9ef93acc35875a9d345b9a6bb0920a78ce71a8d4b16bed8bc45e433cd4f553b8a5e2ecde5cbe5c6d577ae88bc7d31d6f6ad6c74b9bc9aadd539535ab7d65b6adef2b49a6721211a25535fc58f65bedbc163d11f765df4b19a7f81a6403192107e81a1263587be1dc1408606afa31f961029f10c2cc2ce0afe5e3c2e6632acf71ae44fa45bc52f119990395b7696bb0e139d984d08df2fe3ef723afe42dc5a8c5d64422caec4187247d64eac8c2c8bf57b51c73f539702cf4ca77353554d94d33e44f3d54592c797c88ec01ed00c8aee5aa280d818261fdccd24af355595acaec6d89845619edae744cf16544196191af37d2847c819045967741a6db8751c8155828384ba3f7d431cce075510e54c84d63863f88fab670b4fb2d53e1eefa01cb1e35b2ee12f9afb4fa24a0c4dffd1f8de5376c302ceaa2e287d41e23a0aca21e027be38ab268a8b584b951f890623e9089908e1eae5e61f757cf5de8e26a3aeac8e22ac6a746ac3d979d82e52ebfd9f41c182099059f3953fe168687c5f08a9e3649e475bceedcd855d74a8f0b111c55410def5d9c2408441abdd4be60af6d6fe2ead622d28943f73aca642f20a72796c0794d668c10a3a751af3e5a5077df3e4f26e145a5f110137323dda00ffae2af1a5993ba88e28ad1cc7ba30ad1d442e465678e1596f1832c74025e806ea88131f5a6cda2cb3de6d13f174430e6c025f7b12c4a0a9699beed3be11f4c81ff08c2bf27e3a340424b99377f586c5bda771127c40e3f88ac8162a65085e773e132a07f5e9337984403e10158cc8cdecd11d93393f7820b345821771fa652ba3ea9f0fa6970a0206dbc704ecd8bec7fb1c9850f52d273bd322d3057cddc21d647b4cb6941e96eba83091fd1543d415cee47ef967220b0eea5d5bb8d1cff5d6b83c1a5b79c93e6eab5738f9fc26d25abd1d4c124a6bebaa6e37243356c13b17058dffafbb4df2148214294ad2a30a56cfce5dd21637dad87ae04a64fba25ad93ba35e2c008180fcaa49f7c7c6bae9c539c81b8799f019801c39ecbac86a940ce68b071748cf5fcb88b584fa178fe04594a006fc4a8382343ad4e07635fff350ec09a839a89ab93b58c3bf8fc469c9163280f2a7909d088d17f71977ae81f16ebdab65c49753a69b396ca108f072eb629ca448f746b7065cf683638ac6a522f43a436d94c523154c3c20a2c866b3b4d50e6d4b23e0a2494a4f28509bbf042383d57c9d84db5fc3dc194fbda482e9d69279efab15aaa5fad3ac308f7f6438dbf57e0ff68dbd7461c5e460978860fe04f200e2025c154dbfbdd83cb6578cf3770bab63a42f1dd918dd2bf0ba22386376801f358f76a5dba88adec3f8346c1e885981db12f8c741199d216d7beddfb83ad6343a4d75a17d1f6da9465360ba2c7882c654d2d8448b423d0487128cc6456d901218b34265ecb41bd833ac01554247cf570fcbe3542091ffe458f38613e4e1fd7a5101640c3dd8445f0793a010d022d39c2eab0dd0618f1e8d4f057f6f66f4727ced018c754224c7ab2f064390a8c66dd1c462409162171d199a93cdd35379701c477ca6df65bed55f5ac07f1f295dccddc4cd596086d12e777834e6a51346c15a3efb9290b4ff0588195ee07f465fe3bc023836c8f2b010000000000000000000000009707920df44486d8ff13900463da8b0b3bbdb1e9adf72c568eea9dd4d3b404075e11e2f7d3e68e14acec33477d2199c1510ba54f1c81bcdf020c0360dff89dede24ad641c736ac2b6ec2a1545e4c72b510b1243bff3fc00133f6ee83e72174a2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e423a8003e7c7b75af165588f6046d9c102f637526b846414007d7261c09d36ac2ea496427ee0d86ab855d47ff09250e772579bcbd8cb3f35805026203c01cf6968b81f637c6ea2aa0cc07ad4648175b2c83d7713462e61fbbc63a57c430fe8bb6ec5e6d1673b12913e56d624a7bdb5e18d5d7f58c2d7e38cf08f7cae278e90030ef6ef782ddf871de024abd67c1fb2a0b179e984267ca7c9618d4c18ec6cd30603169f3405ac159a2629f3d3dea02e6a59c176c99d0cb4fe993e19340f261fb7eb0b274e21573c63e604e654a013aa0dc4372734a30a44dd99c0fe691a56e980bbbf2a50ff0002709d9fd1942890d74e9cae2553eb10b43e62c522a18446efd319a10329825fbfd9da260aa528a980451b7ac826ce6787c41b12285b4d5371a6d169a1020d030612e076ed388b74401217670b86a3636085a649aa86423c2c832a2938a3031a11fc1e335a5fc6e85e2079ade553d9af53e3f54f401feacbefdc4fda7359d80305bfd303c73c8e2aa2c8ecfa83d9cd14305d68880fd9a5e2c847731c0ad4c7e50206e3434f16529c1821cb792227691ed7e0cd022b5337d7a7f00c62202d35db2847770db41639f16e763926f2fd5e1602f1259e65164e53f69a0ffce0b067e0875bd8d7f11ef27813122c5b70ea7d831fc7b407a2a479b1ee742ea2d48edbbd92b2307435b01244237796e0a4db8ea1b87ccae2b0d47d61e87be51e3d3b273d7c4e4d1ed7ad3b88a686cf7e1100a8822290e14fade00a61e298c5d053eb3c24fbae3d3b8d62db6ab429214780688190f5e9e0ef618d83e8887fd3460705b2c45d51b25137e16eff997265358cfcb58a4541a825109f1842fb53c7a9a0345d0fe99b9f47c3022019e97f8e8ea9001cbd20b70d0bf1f05f4e2d06d3d9d2faffda86765c27a57d0a3894df7306bfd8e4286e498f17fea0ebde2a83cae20c397f00e7dd9a18cca626b2621956e52f1ea0cdd605a873bc50fcc839793462522c14b8eceab7cea075dabf78a1b7a7344dac18966d6a00889d5f8e7f60b6b29bd2447016e1655cde20a5a8dc9226e64f6f0b27956f87a637ca9802714afa945bb90010d8d00933d7bc2ceadf76116378fb866f77c83edac32853f4d2623d027c7aca05f0db88bb103896e96e5b601e77b2eef1e8970b7f76cffc7e9ea7f09a034349780ba6cf2260e5450cee36b3b148b23fd251f5ed8e0e7bcbef3b0b07ab945944a3cfc1d2ed73e87148fa185963422ca333bcf712b1604b70b8867fe11c874cef2df4ca50fee8fb7bb8c84c506281f1d8a4a16e9e12cc3b04b6ed3382e59c01086cdf023ce3ee6c1685761b3e56c849ba339d18fdf2a5fb6ee80fe309a76d4f5642688509771047ed7093c1be8df9a3f68f56ed05adeee575a9f733e7062b9c4ff04e3eedbfa8ff0629aa685436f49869ffc384df5b6b713baeba2f79867fd9df188f7324f8804e89cfef9621537682e81f6a7d4fc4139ed1ec0297b566f724aa6826f0f1a1b061ed200cd5875169a2f0ed3ada92c7733d896f1b39df8bbb72af2bf929fab7f8bfd3b79ab84af758011bd8d145d20a1669730aed3174df6227fabd7571264438b3ac18b8b0924a577c9f36f34b83bfc3fdb029a9fdd944346b69b456b75643c89e2d2f4c4cf7fb80ce97df71047cfb0b4f2541a97e45f1ad55fd7b3399cf3fffb07d5d9330ad42ddf2e3e2ca27b5c3a89401642d6902eb95ec99b72f0d2f4a5c2200cf48d8978e8d913496f2e67b9cb26683b5169dda0d98a37c39dd4a63910b621541966a885157677a671934840bc898932f0088a56b97b61cb9cb77f483bf71df80b41e25b580509395b83b172fd87a1b01466fc92346aecf5295da16c9be087ebecf6b63667cb42c3349eaae83fe846a16a291ebe4b950c00b6b5d8dfa1f917d1e58fc57b2f692af28aba4ba5f71448a3c5fe7a7947e73ba7a111b50c2ad5d8dea3f3c70c38fe20a25800c38d77a3ff75f44f19fd900a19db6f700380ff1b7049382eade90cfbe028ab0f78edd9ae77863b261748672d10c14103b55262ff8e9dab05a41a32fb042304acaa4d1655ee3df2d34ecf8a98bd2154c946c6905e8c023e2b6303bcc76ed96ca16e55a67bb4153fc4c97aec46e9abc4ce78a9836b07120f191b43e2824c7e015884b74799249e584fbe1b2a3a2af0840c4e7a0b3e434da7103c9f47ad8b46820b81865c1f92e659e98da0d48dd0258ee013c5bbdb7b0f924625904c26c22df8da0026c926d96eee94f7a485f0f4ca7e65ea3b19caed1f2b950416d9c8b78746e99502c85879013f19812a5d1c36784e2deebdcffa8f83898c8e123e1efcf9ddea754fa1b629cdc6155e045cf3ce12eed8f53f65be1494e5f881fbe049a03761018122335f1c7d38c345098326f5cd61b7eb1b45f5ed121860561c0ea62c35487f507", "", 0, -1021158988, "fdef9e51c882dc5534aab2baa2f5d45c3c925abc9ece4f08e6146050d8eb1690"], - ["372c3ba10215ddceca14fd896f9406cf7a9c56053f56e338516601c9c7e35cc07eebb97e620200000000ffffffff30d4baf013e73e095f7cfc068290649f0f19de1bc4771998fd0632689a1559d300000000025353ffffffff03e502cb0100000000086aacabac52ac5352cdc2480400000000010070ae9f0500000000046551ab5300000000", "636300", 0, -625391440, "d3859297efe9f455a8c4b8c34446aa29f9224eb2545da90266f47f75b57fd58b"], - ["e5b92041039aafd5c53b4a554797871a6cbab3f1823d583ab32e2bf21c3b40048cafaf48b6000000000265006c547f91605555f9f31fb886a4c36b5ec443b1245b6a2d13f166ee689a7558b30b5084d20000000005abacab536ac62b6fe998bb29a3ea2e7a233e8d678c087b9ac7a8321adaa9c9d81aec2f0ea2e2503e2a0200000005655253656a3500802d0222c94a0400000000001f1ea00100000000076551ac6563656ac28d18b902ae795003000000000000000000000000ff13a0594e2280dab0e6de7f8c1611a6a2726d1b5296629e3baf10cbe6c3c40a7eafd9a32d75248ca33cd581bd15083cccfd9cefdbe2024f06f4b58c6481e24eac11d01f7670aab707efbc6137f1d2a9713590e85bd32950a8d820d18515e85b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000309c804ed1a241ae1ecabe7e249be4664aa01338ab285c9df5446936c829d7e9e435b4070f0fa130263afd1c85f15754b6ea0363a4652ddaeeda1d2005c9daafe9a59ef44c5f0bbd795e669754a1725eada891cbeb62d53e216cec837bfb83f06501a1ff7e314f99de59f01ecb0ec90e82af65733ac37e55b27203c9d1f439f10204867c061be913cda0c9c82a03fa798e045892ccaa3257b9657152c39064c7da03219ee8984be7829880dc055055d30b209bb4b83de9dc000cf07297fff583eb2a0b20d25371c906a4bae61a0a57b2104d8d140b571b4cfba3a7dfbbaa91d1756eeb183431510792716187b3b718aa168e96aadaa777d16ce4e0f58bd6a3ea3803d00309cc2d5723221ba6e81de9a0d1644e9538bd833c5ab84b29522802b1e8c068d6022dc02e2a381c54e2186770d05cd49d81cb33051f3b406c77a17fe0a79b42b8bd031c39d75b70d14e006bb9442870fee16f75243a36fdf111c5b7084c0d58962aa80316a329b20cd5d574e7cc28dbcc2a090d45ea57be3088d7116f319135422b2ed4032530c9e7920fa7d9f44f85b622cf0f6436554892286b3e86919143366f7d5638c51c6bb7f16dd686dca8a77bf32524cb1155f022e405e7e08ad7572c7ae2deb3d1b881f3ef9e471685d96cd7d5aa17a6f7617c76f92c055e0ba71fbe2062a6e1a5223da6dccb358344cd876f04aeb2e480dfce94df3c0f968b8a319ae43c54c7f34e81d6cc99779beac27257e691488a83b1879c1aa2faa625743de21ebcb8ad222b73906266b6f8d132fc870879f71878c079ef2b0a130f2b4063f93b477d945c292ebb1c6b98c1059348f2e137b1c1a3c56501b992024af9d3d1b52483b98bc20ff155ca1b38bac95a19cac2ac325331487d91560bb262406f8507bbb1d7fd90dc1173463cacf8b90d07c2c93cfaf45f69d58482e0bfe1aec5255dec2882a32f879fe0d08cf9affb10639e3030967c7d271884bcbdf299ff702fe85a8f3e1e2fa20552921b24b6dcfead078e0784dd7d28bef9427ed791f318610179fbe43e3adb159bc0c69edfde3016ad593d2d6d93239ed904770213034585dd2fb9c9db651d88204c431cbd5c3369b36825afbbd2cfda2ccde0016b53b475b9ecc2b70ef89d4f6f9878a14977cbaa74594251d97b54b038b65801b6dc207dc95f52dc843148c787c9e652cc5f9514fd0ae2fad516d93020154e3f615c0902b89aeb7f6481b1f465fb01b0e4947a20fa9bbd6be5111c5f66e3c9cde8ed96c25166a9f37452043ad771129b78785db7f11b0b0c2634d24b25bf169e45236c7f68f6cbc343147b8f8f2fde6ba8b633eb9a6a209f148599e72804bfdd128df92452faf1ae3f83ba195a9605638228cc6702e523b09d94fe3c2ad9a4dbbe15e77e88ce009334831db2cdcb50b282e485254bb9fffeeda803e09cd8d627179ed0f40ac5e5a6be692aec7b5a33f70c331e133873564d41edc1f10d598ab4024b87e101cb8e6eb5f097567b1db07cd825d2c4d0174ee625bd9e695c26ee84b50e1d4c23a9f8ca6eed73588842dd72819398ad3485d8355d37b27a9fc43282bf0ee4127f3913c9f5344aa4c5c9b0dbd32b1b1fa27cb34a45bb538e488da0ecbbb37cc4053a0b0c476052e88ee1d71cd3aae8777dfebb09006888ac4bb4b390a784c333c8d9b17a31eb1c7cac60327bebb5a893dcd1fd32fc4c88d858499c9e9cd3f1c84cc15652d05f4b8ddfb7ccfc3ba4d5b137be1fb450d9005e5367b6e89bf7c2e92f23247a3566f8f5b98fe97bd2fb466025b020bd1c19fd32725ba52bb52f8c94d1107cdab5a63b4a469a923b28cf1f5eedad7318c288186c62e956adbf247d72d7d061d13ae257e61375d9f569a2a0db862d3df1ef1ff3864ad822baf132af4386cd55c8ffa634b1f4d749c992c1c2d4c04c07ea48a2363d5f537e1f3d3f7d50cb0cc221b97aad0fe62e0de11519588ccaf4d348ac9a26175f72644fa2fc57346373a92bd1fd5cd75982752ed690fdd8946e579aafd1b83bd62bc24ac31a963d09a286a3ef31c07c0a7d4ace5279591dfec8d82d02d5135432d86e6be38996f00c1c743b6c4337bd01787984520b2f0972e88f818a0c6a2a951c781afc6d6876c37877d525ee127545e5fbb1c3f1db87b84443fa27d66b17df9181ff4e5d59c206f2dff424449cf2a5012a43c9a6eb50f29eb10ca96a0d466c4c683c88e0a16be673d043d23d6b7d71665892a2f48743138bcc38689303aad868a2d99780d5347e9ba020c517fc74b758f550dd903b6c1380fb04d17aacc756b201000000000000000000000000a1aa1baa6f0f4d3b3accd85c65fdc9d911a68438a798b10c7c17a72550087d8206f1b419c51bc6c01c90441b0845fc92dbf5ffc91020eb8fb19ba3b73ae533f53e57505805befcacd4ff2915fcdf5f24cd963b9807b8b51d30954d54c8375240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002abe8e55ed9f73a1eeab13beb058fdba6d653b4c7dd41c467cbfba9ddc9e255571f9525aebcfcbf346b613fb145ae1039bc9751e1dc7757b43a9a1a60bce0ff17669a8bd6e33fed56010cb7bc80343f42c4480448215ee45b55a311f522631f8d8076d54073d5045b65c9da06a085151c16eab4f75bd49a7338e78cfeb7f770b02084815ad0198a950a85aa49f5359d4f2be5a7b5d04457d2373ad0e2079a7288f032b9957c4dfc04126788db8a11e0bd0801e5e6abdc9ff1f60413620d0657db7f00a1c5ec0a9d16b5ba013bc97531c90a01a4844ca5105a0ab64e8ead833dc5793980c6ea4df133f513d4083ee1b991d2dd725949fd57f4b6aa4e1f89af07ad21519032618162be804fbbde3ab07bf0e6079ad6b2c3aee3365ddef8424e276ddc333f803066d1aa254848b9fe197b009110e9f287ff71d97f6670c1f04a48c6fc0106940031113bd6ae0b713d4da08c70a2eba99e470df2bc790796e0777de8b4bb9df28e2021c92d8109dc018d281a9b8e6404f74b81341ce3737fe2374ce341b569b1ae56c0310248287daa807c727bad587caf9c56f187ef3f7354d6e716b39514ec0698978c29a03b309e13f9e476cf509faa1d4d9b0267d976fb77a76c163c4700fa539c7f15b4e69f36a39cd40446e71b39d17b005b012bdb4411bb618937ea8b82e7c61bff6481ee2194933411a56ef966775f7eb493fa00c8d822c27a6029145beb3c4a13bc22728513c55764b8118671c2ef5d932a7baee687ab49eff9dae9d17f893c536fa2323afe5c5fb6b2ce266bd8c02d95f8d878dbd2b44cf0fb94119d46c4b317217e607256f8ec4a2dc853615696c878e2730c7548cc379c77c4360301799c0959e8cda85444f1264c766b8e0008818cce935361b75aa78751d1fe235778bcff796b77ba53336022ab31b12c3852685f24e6dff8ba0883e372cecd0e7570451b9ef039f23f07b441e2e03b9019d7928868e87b518d250c861fc9c0b87b4313fc82e24990c463eacf75a2d33464debcd0c71f7785094395abfa1ee12bdd9e6d266b4a64801d4174f4839119dc235ce71d4eac13f2ad6ac7a88d47ef47328b8bfa9af8b008f76a8e3c00f35071d636ad82e2b10c96aa06cd159fa97f4a951013fd7a65c538b2983f12f6af76c25bf6423a34cc0f23192ea2aa684e5dd865f1765503d6b5bddd829a2ff43889519ef58ce6e9241fc20bc2ded1815a96e084da7be8edcd22e2ad566c4935fa282ad3038f80baba4fc60811fea9d581b02e489dd800380cd1644e3f3228e358697e6f118b01310382b6a0eccf471dc355f8d2fc1206abb2745fbd432ba0607854601800a039c3c7da2ad91a05dd7096ee47b31d033aa72d5d647291ddafc9606e188e3fc4b49e3aa9cde7f53149c91ba0b0bbc03b3104a39e5756c1a480227095327d4093a236f77ba14702ae1fe1da89daca648b9484e64e7baedf75b5425ce3fa2c8d13097b3d1b1ca27113e649adc944da0ad690e794f97edd4bf319181ce3017a490d5c740348242510a46ff7b67453815bef259c37b52aa8056c0c4a4f7ac103e8cb7ecc9e2a945392b541f3813a1df73d161c10691d9d86cd07d8b8616a54bfb63a919e158e9107ef5ba4a6061552445982c3986d91b41812077d84891be618640d3531afab61b769a92c4937281e1248e87a000f8f70f558687f38ada579c344861a8c86bead638ab8bf9070c3397f04dad50176fe1562b7954b67bd740e32631b885d8f6e8c99e5aa5e0c63bd5214c0a942ca7b8b2f130f75d06abd9f4fdd82ebad186c81c57e1e7df267af906ff2dd05b1460f4ae1ada79e1acb597fa787fd44284b63d8173c677b11d75875da65c3f3ee35b0a8703072b88a34e092b3ca255b8faf94af42370870199e9415bbf92012d51ecbd8b2e7120c6dbff4a3176b7f85a3c3b16de6efabcaa2cd37da666698008fc4cdaa4f9791c9b9877c89469bb285965625a59615500758bc0d77afafd552382fd039d20888b236070307d10dda352351b94825ced5f58d48f1339b459c2b835fe5c7ffa5890b7708eeb48b279331956c4f767b54efd8023d9e47577cd7f4ee7495b3115fa77656a6f48867cdc3d2d04ff9d1bd2a9b02b1e550ddbd4c057441277dea9977291e30c8d2b43bdd148a69b6b72d1c1464b4247195c0d4d410777cde6fb3e3ed03cdbbf4a4bae7ce16ad6f619a02402bb2d6ffe1e9a979ab131b152d7d4843e42cc1169f460b7a492ad2f856c3d2555037e185125456f2fdb8bae87502c7300571480a88e3859ab04a603de2c9ea1205ee1ea5daab2359f30654bdee9b3c6b613f74cd3b4181553cb73f4841a0737a4bb8f9b28d4e1a51813d809880fe958a4bbfe0b0561986c97216eecdec45f3e8bb12077d33b3f1be0b175e282606ce4904d9962d140d269b32dd7050c", "65636a", 0, 1974178227, "0090b1b2f97a6c181953e5ff474d10cac44c7c592647bca80937113871c722ec"], - ["9ae7653d02f383d092cff961707ae4f008539a8242ec4054de6d8c2eedd7a1b298d65d78e00200000000cf31fe50400513e89d4c95b63dccf2ec131ff00e222a2480bc97b3ec82f1fef827aeb7720000000003000065ffffffff048f39cb03000000000951ac5365636a536a6a86d510010000000000f9e385020000000008ac525263006aabacb88492040000000003ac5163000000000100000000000000007d012b05000000008fae83ea692172e2c36838673efc669d94c5705b64697f2100ffee0a36db3d19819086a60f876e6de94abf3fc326ffb91389f91712ca6f181a909510f78c1144978664f6e9aafb55365de91e6ac59912bafffa9f7e8056d3cd9860bd47f740f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a098a1be624af328e4e212f6b2c347e7f11600283e02008ee818949765d60bd749ffbf32dca121e6f8977899ca8870ed2945a0b63a7ef142751b4e6e0ed2e00ae625a53d0f2c6e0b896874765a73e89480d0147ffbf49c3d81cb3dab9b496a68f4ccaf0d5ab242f04eb55219d2a356b27c48f633dcb2252b16e43b505dc842950216e7aa43af82f0c07b524103cac64c5b3579c122618a001045ac39814a108d70021e1b415d68dbc7beda57fef2f3e5f13958ffff0dfb87bfa0bdae28d5dc5fbad20b00a8e0df526bb69aee4692231171acbbd2a07fe83ad122d5aecfd4dca63dd0282efd4a91c61be53c8ae361df75ece9e2db0b2ce98bc934a33490c59f52d7792c0224aea0ad39b54ea832ffc8b43755ee54b7745ce51a6e1a1cd83dccfe9b7c95d50315ce5c3aa94076a3d669091e8f17a32de8b27736675f7fb1ffdd52d4a28cf8ea022974b595096c3c3e1d71c95359c2dd4490a357a14e00f28bc2c852715f0ff6b9031b42ea6d6352a2859f535f7e1c760c966a7146d408e4df8847f8235b48426567031664b2e5f971141e5de5a167c45beb0f385ad6bd86a8abd35e3771edee30f536e48167a2d9ebcc5138b92c138b8c42ad30f029e20c60ec19471f2495a7a3e0df23e39bb13c213fb28ce12c7aaefdb9d5477d44f23ec11321629b8f18a6fe22ddb85642455c8500968eddb2957901170dfeda057bd925a993220846a11575396b75513079a4f0ce3291d6b135fd2edf727846e8d7a29665f0587641d6700886b31461436dc87566bea0e4b3245f9cb802259019f43400e0b80c57b9b9e8a3a3f688c02219275491c3487e8a517f5a96fb91e06b4c5cd3033f8f2b6288dded4b33dd735e1043909bde729a757e4a0366ae27e97ce066a32c399d0e8831aa0204a927b097a5e5a3589e598adc04226cd382389c6f50e9f831644e262ac90f5a0fc0b5a8ad381dc049935092adac3fe591e850bcf83c77d0cd9295d9a6df4d58a9cb5474726ffa5be89c895638d171e3ed86d9cfa337bea978f1c31cd8afd07139a2ec69decd2b22250533f42666c6f710cb1f0f2193aaee9a3467d0b06a912e16878d22a15f7049f24bfbaed3b17939a08ddc5f6926881e58113519cc08d277e8a52de283aea1d2191cb5d79a0312f76b86b64416acce4a414f129896feed05ec2da078bfb376648debf78a065f5b1b4e5849a85e4d594a61799897da1ca4443dade74ff45507474ca2a129c2aeedfdabc0c3e57bfd998c40c73268d33e7edc3baa2d78d62417922b580e9ab73649238a562a88258d1f7dcc606c7ae713a8d3ab1f1f25e7c3960eaa625c8e5ad4f997354397d4ba1c5193ae817b001615fb991667bc96c133c8b20919e27258b3b6f4b8ccf138aa756aec20da041099d985cbe8d09d231298a8278da623b72e7845d780ae5c39e2866c963b82c1bbe6dfe4740b60aea2231ee760fcb669f4c6c20493218859b478c4dcc031e2a13cf08c1fdf800ee77da5a6dfcc71e77a6aeced8da4c164cb3d1e561d829f095cab1564c6a033b62f7664877706f64cdaf5e3cc069fe718d452b9f4dfbbbd6120668da6c3994c73d7d501e5cbb1371f9979076d7f8cab4dfd0fa441b6b86a12381132c7cad0ea907ab7e603fc2626ffa8eb0d13cec932343453820211c14b91845deec991ddd052c4f7aee075a237b6261a17282da00735e7ba98269d9f090c8ebecec6b09ca28b8deae2be1a388fef96056493d8839f7e8d1cbe2d4b221bdee9ed87b215d12e828e08e3c38a70d4ee3754ffc1d98c90fa3a85da519396b12c4d35a049410ac3aaee2e1b240ec8bddaa6d2617dca488a69f8dc8dafa159f226f2408f4f85896702897f9db0c931b03342fc03690ced9629bde0969b653547b864983b29bdd2d6136c945dae9de66661a745ede4c189e09603d4f81fdd56ab3917997da8f5a9764101a1fc91aa573e8794dc61d52391ee8c0ab9e78efe214880ab5648219b755f46e4ac8e4e74d26d08ca478619cf487def0a0b60d0be4186f857042d98b2abff51fa9fbc92054bb69b3810f10f1ee2cabcc91b783b22ec0b985724b4d852c4abf762b50249770ffecb75c84025d19fad665878dfefdfefabab362c29bc94ad278c8790b48eaf9b487780257f395f0e95fc706fcfd76dd0ad8bebaeaefac253256b75af242844f50de36f999d4d2e12136340268070c0df0fd125006f08c34df9f40ef0b2bf3261809cca848aad6d8a7425cac660b41dd8dcd61425fe8b8d2104aa7a4ac3bd276ddbd89104f253b091b3dd2186ff6b6a951689cf718380eb6d33c6bbe7312b1065f3c5d424c8c46b5369d6dbf0ead5036e89b97296ee9b0d1f361c0a3a419b6da49a6fa334fbef3ba64cbbeda9643453c5f9eee5b44ae5f26bd635f6a9ec6f8025d0e89ce9c344a4600b64fb05", "", 1, 1180931806, "687bec462be15f9b68b63e325599248ba136c8aaed0682052ae3ba3ba484d01c"], - ["8b360cd5035ea33dd7505591825b8c1187e28d0b0471d8cf2c86ced75392fc10fc73ae953e00000000046552ac65ffffffff6ace879ebf9e3b4ffa24a1669b7729d1094fcc2a1c9e55cd2aeccc18ed35a726010000000352ac65ffffffff83f640fe69af18e18eadcbff5d021ed9fd577f6bce8d16c6a61a24c07cb9c8f80300000008ac65516a6a6a53aceb68b25303ca0d9502000000000552526500acc3eebd0000000000020053d1198e050000000002515200000000", "6a", 2, 6510966, "03a6f52c6f30c3a4174d00a69a3d68873bfcbf85bbf4d6cde82913d1861f6bb8"], - ["85b6c6bd0326c462ffb480400fc10122e10d97471033562cb13545151cf1352b47327dc52803000000066a00acac00632944e2f79c0a84524b37c693fa35db21b1e1c50da26b93634c9a8400d00d4268a11972490100000006525353656a6a062ed4446745bd9c642328e4cd1e6c69593da50876721e795e1f6e08f479c306e98647fe0100000005abac51ac6a007b9f6d021d87ed010000000005ab52ab5152a2ee21000000000006acac52636553059480b2", "00636a6565", 1, -1617374854, "14352697bd88ddb3cf213e8d11e36871146077d6a7d18e70a573d6a915510e30"], - ["3aca2f82025be8abfc7a26b083e945abd2f85354dd40864cafb74b9f190d3d27ec2ea90eec03000000026353e83a65df094ba7886ef61911260bf0e1fcf1b51abe904177107ad86e6195213724aae1400100000008ababab63656565abe193e2b803a1a1c205000000000665abab63ab63f0a680030000000009ab5200ab0052ab5153bc4769040000000009ac6aac5152516a536300000000", "526565656a51", 1, 886859900, "74feb3bb9f5ca1eec5eada7b163d915b7763e2813fd74c87b306df39128e45ac"], - ["3af8de1604b81bf64aaa19becacdafc83f1bce21616e422d4fe71e57021bc6d4d61caf147e0100000003ac6552ffffffff4ea19dee3486148855977b161c6d7b1ea3b86cdc0572339b52ea71aceb47e71d010000000965ab53abac6300ac522ccbf575575a6067dd9f081fcb21444879e44492572257eb86041b05677ce2b257044de5030000000900006551636565635129bf149fb201814cd135a7deca0c8579d1777cff1012e66c9795daf83241178d0d8f953c010000000665516551515358c530ff042ade3604000000000042fd700000000000025153d3d65a02000000000151ae421a040000000009ab53535353515251aced5383af02000000000000000035a9ed05000000008a9d754954f2ce82940f09d2931fa480dec084ed3d89321fcc4c0b65385dd37a6a6e1226becc83b07cf29b23cd97960f53437925236300b64881d303e2363877b6c34a42d7e2a9d2758cdea41108858f9081b78eafcc399116254b1c69c525d40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083bfa06c2ad83766e68fa47a519b6eb2ae633f9a3431d6b04695f4f832e655e06f4498241d155bf9d92a8a04fc11e1469c9a697ed68ee57c79b53c277c2fc432f50fe77464b4981c3efcfd3903588f787bba7d9d765d80da94a36efddb3aa4b90f28a8d923db4c23dc025d96cd2ec4681386a4539fc50387e3a345ea70e3b5e403018707f0994db3e5f115e3ef36f8b68860b5639458e049577d2f1206d6f46f2f032060750b10f6b456c281abb5734de953e502d8c55c8ff140a9dc1e38ab3bde350b283b9e4d561c9e94a0b71bf07fc0a2ac510bcdd370f4f938d6cd9f1cd2c30c111ce77ba708c283e1c940fd84c6a82e4d9ba372717ed98c1fd99e75e895b25ea6022269b07ee13bef3fb4a80ae6a976c6b20fe234c4554c4a91bdf4b80f9db788c203057127605b0cf4a0b8254db799bd85b7dc0a7225b6e2db78f5a5bf8aa87d35e40212c37c91e6d004205c76536221d7e2a144b5930b176aeb0db4dace15917b93bf020d3a1d7682bf5c8d90df733b83df4e41538313c6be8019625b87a91e781fe0bc02211050875a782770c483e11edf308d20fb6eee8c1f779c96cd5e279fa342dbf773a8f0a3a28f351fc3b3704911b65d7b160b3693c737cfd4f0eeacece751eb715a35eab54bbf8f86273fa3d63e1337ec68fe13f8e2bc1e8b89c4aa4c5bc5c976dcc51a6d5aec4f32f3b1ec24b25659a858b84f33dfbbcde6994cf1322c3a77cc5c3529d136a2b6156e792cb7746c8ecb24b40dee6fcf076265d7b5af774d374506a8af77e941e6fc72b4bf0ede5d4bb44cd29954371c380fdd60869c27eaa9decb626c85ba6cce8f000b3c67963b7081aa5460fb4898ff15b87ac322501900653e3c470b27c9300335d05d81cbed4b2ff9d0c6ebb15584b0badbbc76ae3a5eb0ad9362338f25a9ca4141c756034df72a404b240d32bc8fd66679cf3edcb2f8760ec26ce8e94ee4c54d069fc169c162d82f50059d1df7890cdd8d0ed8c8031f9e60ac453d0e341b8d269fc48c47ef92d4184f15f17018179a23f3b73464214bd28c73a8712914c08b4c157a6da8b810076ef8e0f9420eb6808c989dcb4b1eff0ebac89dc146f6bc298d3e05bc42ca7ab73c6b0a159674968e03e4c4047bba279a1bb3354009be544ab790d216cae361e28395f7c8bd91c683bfe6f675ef166b125ee68338d6c578c51f398a1352bee98bdd08e8621effd286dac852f668145143a851ad4bedc55061ba02b4f126a2046facabd42321070982de337b786c8a9fa071c82496ce16b70eeb54f55a1fbd3272ad6b3b974432bef4d0b31fc4b073279d2b720198a02e06cd9aa5541b730ae2ef319d59e0f35fff9b17952af447b5e4c7f24b34183d8ed19f8307920c8abbeffc932264d08cb40712e74f4580a76cbe1419927ebb504633c4224fe3cb4a26581226c5cdcc969dc6ab2faef350e765fbddb593fea29a1517f5d5f9e89eec982daede2533debd8bf1df7b481622a8aec5f069468233f5b67c757edd6812b06bafd81d40a7ac2c3e47762aff6f20ea6f2d9646a8b30713e06195ee0483286f7a64013a783967884ad1a35b84918aa1639ff20a56924d050d96f1a0c8171c2f07398b7d282474964ba90a4884b11300fccdfd5a0d5db70d93b5be8b4b54acd939cc0fff399291389e98b99368138a60149d28fe0337523d7095b74caca182a1dc0c698f3edacf277c0e2f653187e2dc5d368d214eeafb5c143815840a4d13f79c458b3fcea8023c1dfc58a4ae7112cd866d7c4418702105f7fd50f69773acc7fc59648a1a3b6c1d0254995649bc940c2c70a152f73ead7e01d7500de0fac705dc12be0b5a0285d7f1d8b2354af24bc1e197ad8f2559da41f1fc834c3e055ee28938d5b9d79e9ba88e9f5f72707e035bc3bebe24a67c7c15d9eaa5dfc4e446e3e9013dc47ee77a451182b45448ad6c813e4a87c9ec45240a423294c73e9f84af2308832dfafe8cf0cfbd8e538db15222a334b7ae2517229878c6b79153256f6da976e1685a182f5ee10b9319a9d85f94311ed31077d5038beca7d9b65ec790afaf8851ce0b8bfedcff596246012ac24ea083516322f34aaa4bcc30195e726763b5e26d58ace989e1c13382c8e87e42b976dc4903b3b0a1ba18b665e0087e878f4e20b72a015519e6096ef3b811595f7a584ba3d8467b5885f4b557b9d04d69cd4e7fc62634c64465d8bda858921bacda980137d2e80c9c266b57c2d9c1787cbc60462c4e31ecad90d18f3cc3f3f310dd4918923f29a35d9dc2fe54180ddf6ef765058be59c0d6584010000000000000000000000008ddc00f45d7eb4f360a5ec68b247c93b6e9644cb1d01fc50b65ee143bd07101d5e664c19eec1e864a317f05a950424a300d5f75dd5e88adc0ae73e94c175b15185771ea6c782286ce6ff8e05570f844e5cb3331c2cd3857ac1a1a40ccecba7c800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000906d9819253b03c08981a2f5ed41446a173d5aefc063f606fbf1548b5f5394ed9b5bc87817140c8064002170eb9dd2f1849a98021ed55b7303bf652b7760b8245da6225729209bcc6d08af7828674c5d367d152592a1f2169a510a44204962741bbd97d4f5bcce824011b58dc212a3782e94011523417f7de61c65a3288dd7ad032aa387bdb2cebad88ae8e91ca85a7875031c897c7066635edc3f1471f36c54cf0219240319ee89162a28fa5084680343c1df93548dddeb7107c9a34efdd8c5f6470b0cd5ded935bf4f18a9335a90e88281a92818dd9888432275dc021c2e38feb27c15c0a5cf4e22f75f467dccb489c769c41a78743118924fbdfe1f302208f0d4a5032a630a728af43dea94ac7e241bbb42d5beb2f0cca3cff8557fe1ee61064cab2a022b4af16cb3278a31e66e89c96a9edf03f2dbe697b5ea3d1e579f92889b6cec91032ffd26a47c3b1a07ec510680e77485a41518a62e91e665a88417c8562a63978d0314ded6c7d7f59fb6199a269e32f5e2bf42b499e737b4408d9eeb59697ea2bc390224b2dc1a2310bf2bcfa9e0a47d2a3e3db1b697ee44d30536bb44b6aaddb510243d54bb0d0f8e9d104d43148308be6669f72d8758f285bb8f01a13baa0992001b77bb5baa991fb15c2d5ed848b728d17ed60f554831049d649cb2e1b6d7d0a6e2f2e71aee47bf317f1e0397d0680e77741a219030b08da08df36953f164d087d78ffb5ea5ec7b93ef6f4d79823a3f58eb06d13d288e68c08acc6298990447559b223cf4142351e6274cc4abcb331fcfc24afdbe4a33638c4ec957a1c021a7295499d2fbd0860faf0f98986310b2bb857baad2f1c9ab69d5ad4f7a3d71b3bd9fc49a7761ba6e1faf23eb3c95ef83a072cbbcf96b0e50f24879b0d106bbfc91b2f188fe547204fa32f631d5be1b1e080123801fffc4106c571afa2ad7639b2f59d1c2de8b9a2911c007aefbabd9773e4158a4bbd77d1a24c69d3c8c9d44ec30d82794d9d2f2acbf527c0f20b54a0cf321cdee518995521e7a7cc2d9d373bc453c2f3be3f7793b941fbdaf0eaaa5aff96d8239ed1e20242a070b2bd1f290c2a5f853831d0b0b344b42b6fa05052988a7deb0eda52edc1ea288290dc05cfb50b4d9dcd7cc9682c3b9e74706ed3e016aea80564cdfbb707a76a5cc629a826e299af611e866cfba066db8762f3b52c58ce041610e4bef5b9a4a2b015d57c170742928407a0fb01211568e51c77fa3c12341c79114f6cf784e223d1005a5e2666909995029db468c9b81411ce547643fc93223f9ab4aa215f3500ba18d6d2ac561af9907e66d2097d7025055d64638fb166d9e55f3f57dbea96615989404b447c5dba4b704d3a4852cd905aa4125d6de12ab30089084887d4a78715c97204a86e31565dbab123dd5a15dd76ad22b7c73fde992da504a32a25852de3668b507a4a8b30364de227d8bb6f38a57f896b439dddd855eb1c89aacc6111281ce8ead5cd9099407a8c401b97dc13d91e5049f7ac29f50935338dda3df66ecfe06ee362f0fde8920cf39775f008b68b9301d605c35a11fd26f0114acc7f2c2cb74a76d4eca019a30cc4a4c8e3871fbff4a7f009924b8192576f87187eb7a302fd549ad077141f064a7a67f4812af4b1920e97e3df279104970592b5f7f2fc746f92dc8d1e01294a77e254f54b41545a7dc1c690669291e58667438a26060f5921823af7eb2dc9d35e2006d4ba202e2884ad439dcade7ea96d6d7ce06bf84d1d821d214635c023c2eea44520c74c06788a3b0b0a1acc9189ab9f6a8940afb1a3bf71bfe452e5a3161e3377a56a61113a24396cf410dfef16eb220e5f0a84b0cc5531d5155723c39f931f8fc82f05087fb6e5cfce2ecb709779619612a465853415c22b1a2ff07c0d08ccaa9eb2e9a371cc8ee4726331d2c744846ac535f2af7a526d9e8178743ce4f730ee9ee5a55e7fd381a58b44b78fd70f3f6dfac3da4523bf271844bd0fcf40497ebd23c91303a6f0717682361e844a05426d04443066c5c0e1696e1c73d63c56b2e5e0ab51ed1eb8598f72b477760f2564fb64ffd05696fac0acca72eb1a6d9a9f2cf3b7d54530fb6a651582b1fc0e2b474f3de7579e914293187e93f1045e22ce609d1e84afb535f50240ae71ec6741f7c88b536e1fa0af794cdd2145d23bf752cd12173362519e1a4c7f10011d67d2c4b83146e4f770b5207b7cd4f7e65b3bd8f3b608fd112a81a544c63a3cce146f0acff46551b54b27ce9d947a5c68d5d6dd0e20d17291325971f831093b2cc2a7f185e541ce8770a2c72bd689c62fb17e1a842ba5d655eda51a418aa181d6b3b37390e49678f1cf2a60a9050d0f1a7c3335d623bdb565310855e27201f43b1ac8829e7b06f704455cc7186bec1d5f4e06166336e5145fae4026e796cce9adcc9ee0d", "ac52636a", 2, 780349869, "deacf13c09dd487d97325f96db572b4d82904761147342a01c968f37d3c436e6"], - ["75c726d0022d14c59e3e668f2d75fb43bea5e125ac0cc3f436875a610fdb76b67b444c8218030000000500ac52ab63ffffffff61211151ea9e8839249471b25e25584f92de7963c5ace95bad7769a60838f71400000000030052acffffffff0429084d000000000004abab51656eed95000000000004acac6363c61b1a030000000002510041752d000000000004ac65006a00000000", "6353ac5252655365", 1, -1425864140, "9a0ee10c0eaf545b8da697765107986408ef9bcaded9ceb4e91ceea0d9c788bd"], - ["bacbc0b703de80d482c996a1cea6b9e85798da6e6879f0b7571102a82dd62173e13ce5b98c0200000000ffffffffcffe4a9f7d16f8dfe44aad3742c758c1fe8c0a6678e572b15a302408e6613d1e0100000000a2389cb4ee1931b5d4a868e47d4159fbdb379793cf58c4bd5d5ef50dbe3303aa8ceb52170000000002ab630fb922c10131284d0300000000035200ab00000000", "0052", 0, 1194006058, "3edc8e198076c84cf47c0dfd91bcc54ce75b425b3e6976d0b77ca32626840515"], - ["9748908903633a6c318997ac5fc0fbeadbba8c9883917a1d319483e32d3cf68a858f314e890100000003ab6365c92299044f6fec74a4b0409fa962d46e7110d1a3d70522076a7e48b5ca10ad6060d7cbf30300000002526afcfa059b3dac2df5b604f55b34b78f759ab467804a63463cd38b0eaf0cd7e949bae4176f010000000152ffffffff02cefa36000000000004ac6352516c976c0000000000046a52ac536d03ec27", "530051650063", 1, 1537933915, "80ff07ee25278f799946a9e4ca9b37b56bf3bc6d1b0222d9577197be4a3b64a7"], - ["05d98db603efefa517ff7d7a62164b194d6b00c5000cf079c8628d062428067d261a0f5ef60100000003656353ffffffff0c191f75ce8b3c961fc5a08592ef3bb7d68069aa1bde0a938ac96daa08f653cb010000000153be739905d56299f3c5084d37470ea0b9cf7d3808e754055ba28e5bc50907fdb51cb039d6020000000463655251a685233302a8553e050000000000014d6d050000000005006aababac00000000", "6aac6351656a6551", 2, -1084709125, "342d2432d08176182f60e15da6ffc903b137c7865c2b4dd4fdda3feb71bbd7d1"], - ["f06e13d801f99431fdddbaa1441166509e4138d9648811a9500eda786a98956a60107fcfda00000000085253005200ac53ab6613c5e6029baf9305000000000653acac53ab000c61690300000000056aab52636500000000", "525251ac", 0, -1508217707, "0471c81be230bbb98d78b497a0183803abe3d4c0fc0980667ca5e3d4bad20b46"], - ["af037f1902505a2a4a167973ab96d03b0ae562341a44d8cb641c92137ad353fe0002ad889e010000000552ab51006a91b7b3ecc6eb1d06f172ed9ee369c9de5ec312de5362edc8e9ccf517b416be6379ac34450200000003ab63512c3079ea02b590c90200000000096363636a65656aab52ce893d050000000002635376ee421200", "6565ac655263", 1, 1248727546, "330c54361d2d14326ea9c612baa1f9e6fecded397db2d59f20b95aee553290e2"], - ["bbb49e5d03f982e0fa32f4946e60f3db377a941a1ac45c1571429ca56966576bbd353ad5f10000000000ffffffffd32a7f0792039d9388b52258b73dc16c60c93aa4572753c9df240c36c31e9fb90100000003536365fe94c1e30619e25edf91a15b38ae733828b5ca3bc2778e0c96aa3010378a2464e0d6b4b200000000085300656a006a00acffffffff01e262d10000000000096a5165ab53ac6a51534097521800", "", 1, 1410944772, "c6d9687fbbf41cf2e946adb7d8bc1673a3a960956767733a300d1a992ad8bf68"], - ["cf2e43570299f19a5f9bce98cc2cc77a22bbfff6de5353a3fb8b1284ca8e7e066a31fb44f603000000036a656aa183a698d97013c0354399a2120b8dffdf8acafb48fad94a5afaaa2f51ceacad4eee5ba503000000050051656300ffffffff03d8c751020000000005ab5200ac51edc16f03000000000852636a6aabac00634b7239020000000003526552000000000300000000000000000d93b00300000000675a46a063fbe7544f1440889554deaa0ed281ed0ef61f5f35d256d8b3f78201e308a8873e7f92704076106222cb9a00f78c0d0571f6871b29b1b8cd82718ac5bb21c2a464c1f7f1d630e7aff94e4ad401156e8fe92229d45d3e91be046b97f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000867bbd8d18980d2c7b7355b3a2f1b8ced57e25930aa11f58a3ab22d23df67b72789d13c9adbc4cd1673cd3cef15827060b3e3e173f98490a37c9384227c9ef9dd6c85ce0bea343f770dd013f279e53213221a2f36b9b1fa6709fdbe8a1707a74db4b526841d4f80f99cf9e97e35bb39356a88009d76f9af8809a2eb53ac41cbd0211706f7b5055a835c05f1f3ac8459249b0573d924fd1e0737bfa74e43ce5d1140321c70e88953501ff726c3f146a16c059b27698d951ecf5d827ae0980e0ea4d650b130ed349fa668d7852a983873358b7cab179a6e58d3348bcc445bd383ba29e092adfcef314439edb2c36706327afac821414c83b362cdadc85cf94785efe73a403279f9fdc6111c07921915698ce2061fad8e57893f098720e13ff00c5307532530202e67759d79c48ffdac5d5469f2c70bed60fc60c6f800d043c52d3bb3741427c022f7c44f1db0735a50cc17b6ba48bd81906982101c63a1830b182de56e4eab24f0214fbd81875c41d42f3eea60768404a5f1d5e56dac6ccd1d74a6822b56f358ead03203d056fffb1fb3d44358d7ce9aca780eef910aca3632f34cdfc90cc9772594b6cae24bb497cdd0eeca0e808f352dca9ead313081dc9585a36c2de9f4dac064fd3dde45c38f4fadcbcffdd4be1b41b62c5c55ac0b31fdc1b91b320ff8efa2225f7512081085db81fca7213e154d290e5df0321acb44381d9a859706c803c8602c21226b444d5b22506a7c35797e047b1748051cff732c08376fbca00a28d5a145da7036c0176e68fa82a1114c1cbc0dc2aa4e30ba1686e27356549f1ffb3ff7b447f9cfe9921cf806a8f2ff74c12ca7b93778867b6276443d53233be63f8f3a086f55fb873b30f26236fb0932aa9e04480a66271481c8a21b14dfb7bc6d24311fbe86ce6c2e87a58d111bcc485a27a3a4502a175e4b205c1e1d18d290c8f5c5faeda087829a6ae5ad2a776a8fa130c7f1c307a2aae76f99d952b416ae6c4abfed1b8033fac463334c387b25ce3cd87b25e392fe372d0fbda81e79fe857006a50b6c27fd62ad707283e462c03ebf3aa1a322024da05a426dbccb1d667a09d0295bed7c97d51d235257bfbca068d8942cc3e5348d7da456f09c6513c329de8f5a18d869b0a823d358fe56e1e9078d2d4afd97bc3c624eafd4c8d5d4f934944087926855c00633acfcdb72fcd1640f53cd4f82a0e91154db834232ade875b013b465eef7cd88603477981e21e42ccf781aa1808c3ace2095bed821921a5e8bc53cf5fef1af297a7febd52fb735d2ea31b60bd17d9773160812067a500cb8f63d153a05e82563db858cdc12d6541b85f837aaf53a61c1035a81a789b79f810351c96518fff14f0c36e4268a179c2bac4dc562cc1af6fbc0c8378b836a2ddac5cf520853f65099ad461fc203cb791af896474e6b9a0c70f773d1d1bf4304c2e094b6d7c458ae7e1f6c3a11f3ef6b5563b50e7f946e27e96e1b72c4a888c8adad03f5c585e643af4526bd45f8be515a8d0b15c2bbd21eebab7d6093fea59722072acb44f0efa9faeeb91cf101431e2977112100a3e7376dbfe4fb9ec9a41a741400446cbd883a27168c1698ae5cda69400550d5b0bd6e0d78319c20c913c7931b9c2571e0ed8f58f47da06c3b8894f51abf1f4aef2d8e5849f1b36b31d41d499f35cfed7dbbdd5894d69cfa419312379533ea15165e2229cc72d47abee19f944ffb0cff4cd4044575b41dc1efadc165cf2c2165026b50d639f534897ef8ec253284bb3f9790c3ba344c1b35015f9f2937ca616b51c4f18a989d2e8462601c7e26436cca3d3096dbf78c27be5d46c384840bb413cef273c9d84bc87141577f20c4f9efcdec65787c42d8769383543b91c4d882e795870cec989218a80216def7679088cf93b6844f9081a59c2214fcd9b7f068401412f4c5197f664f87dd60087e214507c3c0141bcb33a2e384f8b17ee350a1df091251084da2828bdec7d222bc582f30e176bc9d8fc5e278ce1ab40eea9c67f1800ec801b96cc20816533e15bf09fffb0431ff50128be4a976c47770e99201a3f9c7ece6c1e2019244e0e47ad5f22e13b3a3319bf98308c7350c95c709ea0575c149616b99e1b0f03084bea4b6c62e739d3b3072fef0dc15adb417e0bee7ec628faf2eb898f707d77bc0f750886ae8b1b02dc5f7ad1a0868ed4205ad729c9246561759ad40f7b0e660fcb5ae5036aa055d2aa9b19d39c6aacf594a31067a588626a3866ba41a508d9b35450e3024e767ed642b9281162aa2915ea09041f4d75a12c000000000000000011e70c0200000000324af9b0dd417a75c282f4842f088858da64e6118d684457df61b2d6ee472916331ae2d112ce18a8c70925447f96e9635e38863c5a9dd4c6bafd23de33892df0a961bf30864d52b592dc3641ba4fbaa789763ad2ffcd416af18681aa0def830e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d85a6c20a91ad69fa700ac3ebf5e5189f8bbe11150255f9787d4d4f9a688ad3ddef84f7b8320e833b3116509e5e29c4e5aea58e79988e12c99263db4c6bc595c4fa8d39f9dfa269ad49428ba4beb22c9e2ee3207a8b5b017a43a8abb7db2e0fb5cbbf14a6808af7caec6e31385f706129e357602717ea76df9623831c95ab9e20226b9d1fabac38e29205324016392934e642ba2452ba6626fa6c05e9af4eef0a2020a2088d8f1a757b172da156a9996a4503fe0278643fb2aa94e5e0b54b062962c0b2e83eee8ad8a3dfa787077d989b5b72909e4a03d61ab977e03b32a25bc60bf0d282a797016717735ce5d8c553c7241b9d144fd5a9e08df145e8aed9d047d3b1c020862acd25d7cb7470ba6896b5e6a4dc76c884d13941ffd6c86cda3ded54bcb150328335fd2f1ed3c09b38861eec106c56450746dbaaa46caf2b481f2ee47d4dfa1022a382ce342a699f9d8779fd9bcac97fee0da808e63c3af3b0ff4437751fd85d803287de5b7fecf5e4d4dde722195b8577600cff028cf3346c00b634e1260301e6b022e7330ca21769eabea32e645647a5af2b001a2551eae3239b0538522791690651cbec157904a423482e875cddea2d9b65ac14c49117a0ee4f7fa8d896307c26bb0fbb033a38015b56128b1ffe211e7545f38b69a44c40c3abfc195f02bc2bebf732870ad7b0e1add15f54ecf15476b7c80d342ef46d56ee8f63d1de4fc1daeacc5e913e223734dfbbe22fda356c31e9156aae3abfbc54aaccd37303f88b187f5d46b726696532a6761c55e95ed3e970836e897fc74ed3987b147ea8cc9b70cc374fb68435af4f264136b74e24a2dc5c686aab13c5cfce7d93e2d5e37e4305ef0309feb8953faa7b81aee775c45d1f7a4c080e93f7ad7572e86d5d15bfc204cbaf14c1adbf9e1af5224200037d45e78aa33407f97978a23f28f68c071b2ce536436204b0509690b158e6241d28a4b0c4091b48aa24694d3244d9ee40c9bd35e985b57aa1e684913e178a21b8ec56597c0e16c198395b95bb403226d77a815aa7a5c1ea003172c8b0e6c2dbbcf66de811e8570cd7a129e0789b65f7a671266f0b0eecb671363b13bfd9d9e2591dc76c3c0118cf129193796d17c11ba9c9aeb2043ec04b95b6beca0fbbb86ea587aced5d468c98a94de7cb7cefc16672cf12dd90b6e84941e436ed6b637b1a23f20939de03b0f6de22c5553dc72395d6f2234e487ab27d52a1b7c075534de2516ed25620e8b2792390b085eb17234367cad341a9869f61a75d32951244527d236f82d86709582919070afe462ff5bdfb4c9bd5259f6dbb0f8ffd6edbfb89351e9febc3f1a711a259fd28895962112804f18d81cef06f2ca1e81aae9b26238bb0866e8ba309a3465eb703808f8d8c855236fbfb18fbc236b68fd4e95cd752d16a8f953747c139eb7d798721f7018ef162e913f04eef807436cbcafe924ffd56ac2a61060a8fd60e902b6e27b62c3179f8f2818e3639bc91fd72ad0df1d08cf177fd598259ef6ab9216655e8f275e5c5b5a53930652f9039f7b357d162c4a8e2d6788e61d724bd234040cbe0054572b5564a4ce6e2e422123195b1207a5956f05a75bdd97a33941e4776bd1b964e5cf4c316b6375dd4db8d84499fe7a0c99420665bdb9571a263500224bc9e539e51bdea62e50a281951eaaf079721aad28ac579a6d6a7a6f00dbf97377596a776baa8cd6c742ce84df90859a88b250fa856b45ea898ca1934e9cc760c06650097786ba41940f1e383f27fd71aba0598d9fcc8ec35bbbe568fe80d9da93d348e8607286bba627d2b688ed39b825fa56479c9ef77e819ed60dd2f25085b5f1318f6293c3a683ed707966012a3443499edae329fc822cd9c8ca82e34788a6770434648e064900616ae00498da624c1bde12df7289de144692129f98292b6fb969a9f66da08067c0dcb46ee3a9bfd03244670f1c7ef1449f0d95de2daa44f98abe1f4fed43a3e02faf0b72ffdb9cd4e715f16822323914eb3958425266307cfc07f4c3def01426a22a46d5c47b288f81fb869353a4482e9893d8e1ca3fcc030c99dfbfe5395e8cf76ec691da81997c8c3712eaf0f217d7f2ea7d13957b78e56172f35c31c68253b7f4334e6a1ed2d699fd85eb78658f763237c2d8dae438dffb0ccde2a0fe4bde01b24551d7ff554ea46398701ff79829841a8276bf32e9d043dc18be3855be9403ca84a0ce7a51b851dd223893c87e0f306e51e29d9830f04a45873ddbd564261a907e0b4713afe836838adc62b5af8cf6193e7cae000000000000000051a3670200000000dd07a8becf8409c69d13cab022c4475e96650c7f33f08c56f609a0fd3d8f2840200913aa1cc8b09ded932194780f3576109da2360df1e8c3e0c2a35245ec2e7da25c6c2341dc833a62de4bc7c4a488c4e427a734467ac92f45047868278be5700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032f06286b9d226a7be816cbbdffdf16a105147aa89846c0df1963807956795ad370963eabc9ce5a923369ee15ba3e2fb74c0d9f465aaf20b61b419ef94a4b7029fe070984610ae58ae94f400c7389ada940c465a393049d5b1539949c8aef2201c451a3c5e417683d64ecbf67db9d8d1f7ee584acee730d998bfff2d0583072e022b343f4023b19e7dc41b444b2577fd1173a2895f03d368229fd8d8f1ba5824120315995e666f162af804799310f9ddf44b5b8af7be8b8fc4ae2496a4ff82912bd60a0360caed942992b91eb7495a94154fd738f60eea3f54cf7b87557d1b61d64d9a1390472617f16852600b7c92a17553602e31e369fd380099cc4514770af7d1210222795ca6d362151f1fe088abdc7ccb56f96c40811079aaaa221c34bf4c8a95d5031e282d2986ffd33e76638747cfc90e70217a2247ed18970a5df5dfda2a69f77102197f3669036b83105aa076b5d8362a0fd2e642f90334b57277bdaa29c688964903256cdf0bf90e386e2b6cc49d8f1c40f9a340994ef763522a60c127a3780eb5ec03215a33033edf8b89d83e6cc3c667a385f65e705932f7f47ee8c7364fa9bc6f1714a0da5ec7920dad2b3b53c7b425526cc0d4a95c58c5eb884b772c9fad1532ceddd203676cb12e2b2f2c5974411920a722f83e2731d40daaf5d19a326ecc09538503a673e5f40d0b4f10b1e98971ca485590315f7909f3dd0b184d5c2e6488a1a6ba384c72b1f9bf17341da50b434803554e6424c67d2daa0255e79dece7d7d173373338b3e2a6822f3d59735949c50da2108c6cad36d4bc16030bb59c5c57bca36fefc0fb274e9952d4519db01c76199700b622784f59c27f46dbca4c5df6882c0b67ff585b9f4f06ea1b299d9e709989472763ee1bfea63f5aec800653fe3eb035ef16a0450edf9ce3246818865ddf3b509d9d661d912cf2f8a5b0c475dd2f29b1441d3e31653c624980f9b1fd6b653ea2fea597e69bc93b676260292d45e0df8713455dbeabe33e7da5159003602c434ca4f078fce9ba0304631d7a53570f27c6881e5b3746e939b280688eb5640abc822a69a20a94683162a0416267398269fdb806941af28803110f432a7f49506e647bc8756d8a97925845073ffe619837fc5a57b036db326f77a4e2b5882c42d69f16dc68a0cd3f0ce0fb952b4951e771fdcd595b09d248b4969296f821d57a99882a3c9115a4911c7312fbfc4f50928de4689ce7e5dd2d54e6917ccabb68f28e2fc0700157e20c8062e3182503a6bc9fe9e3eb5281e1ecb92313ccca95f5ae2ce077d8bc45bb1a35b2f629aecb104cf666a7cce59b8f5315e3986f2ba50d650bacf9001315dd357215c6caf0212a331b058e6acfb7bc392339006fe0a7ddc4c54200acd784fa9d208afcd614c5c62f668e717d7f36d907f7bcbea0245a19d45c8b8b17706e95e9d9aed227cfe58ff5be56f66fd52353eca571d318aaa416cc6348d8b416927dbd81c025e13f8a3ea4a776d1319f02eb848d57f9d3e96b77077b7cfe2d25e01651240068efa05aa7390795f942347f5bfc6d9aa575e6d5701b6b750517544adda94f54b92ce0c4a7638fa614fda153871004119c5439947b9206d8d4a0ef99360d9be75976ac4a9ba3d82792c6732d108efdc1c1d16198b210b45fd17e9afae48c216f6ebefc74791826c7d8bfa9fdc28b1004bdf77b1b86890fa9699468d17be030a7f7d14328f014424feabe18a4e469754e68a460b291e34f770fec2c3d86e96b93f5b7ba008327bc7c05c08e300a89c59051fb8fb121694ec846bc82dcc3bb8a86ce4b7080bcc3f9caf5854ed4249ada4ae2d4fb5c9f4185ca5e31ecf9779ecfa03f11eb6322e0e29d1bbd31026cd82ef3df7776c93d728e244248da4a12b6c088e7eba17b1b521d4213bde8655b2da5e781c865aac05a954afa1a05f49423b4a2d24fdb67f386ed23b7622bf9d2f56c9e386a9847a214a4a916492d1ab28eed1d2cfef658d22bd0efe50f6c1c7c475ad5aaeeb4c05710e5d994599fde659b7f92588daacf6d85acb3a4b9b77f33fccf529254f616a61354d1f3e51d58c738e7b87b975695f7c99fb2ed5d64cdef93e36ca5b48619695af4e7a1cc15b32c7d3478681ae8c35a0ba6f97dcaaca7c4b0c9439bdd8dda451e19a6d2f4706c00a0f1627415f3457bd8736915851f5e9758dc7867e6fec3617fd975909f20240ee3157f0ee942acdbb4dea1988f451aa2788f2c3900b1a92b5e329b838b44d0ed1b9d4376c5606f4117431e95a5cc1fffe0751089fa6f996e197002483a0bc6fc92a88afd10378066b7ced791d988e65eb324a9094aa3972220752bd98aa04b2641a8736f3ba451401f71dd2fd5d2a99fd9cc5a40390bea686af8128cf74b9a8054e1d8cb2506cef56d3e6c0391e17478a3fd10a68954eebaa0490f", "5151536a516a516a", 0, -1779429524, "3880b0bcbc241503b202cd0d42aed05bb8f1f4104056c2be34a03f87144dd140"], - ["0670a5e0012633fcfd1f4504af54b52da9c924f3f663555306827a42c585663a37eb2dc4ae0100000001ab90d762e902909f4d0400000000036565aba1ff870000000000035365533ccbd562", "536aacac51", 0, -788489278, "593b582176d2f6dd7b89988b476830b2772644343481f5be706ac14eed4cab50"], - ["0bd7783c03b04476639ab5dfa8e6db347dd88c15783d239a15975a837060d21681b6bedddc0100000003acac00ffffffff02ced335acf28d22cec71035f9c445492b457cc0078a3e4384b1a764d5eacb300200000008ac65635363ab6552ffffffff23c8da0b98a77ddc4c44b673d39491235531dbd62c585778e34ae80140a40459010000000751656a516aac52ffffffff025f2e6e050000000003ababab3cb8a40100000000085153636353ac51ac000000000235330902000000000000000000000000176ee8dfe605a21f328deeeeba66111f5132dfd79099134594ac6f64b9ddc73c86cf470a003e0ac31e4743a33f7f4aa5ffa5a3d56372ae4b4354dbb7bb45c3ace523b12f0598dcfe12dc23febad51bec0555c3acf0e8f44ae526096c2f79fd1f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e4b580210e224f730e2592ae2cdf96bcc2d48f38a4ac9cc5a22db59eee47a82529867d859a391681388fa60e5ffc4a861515bc0df0cb410739db2a08c7a978cc8232f2a382be1215756af34dd3e740f79835617c5c41b986d7b13cf3665c05dcec504a2f56ef21f2a38fec50b29d5005c3acd35db519e186d10dd0f94fad82c02301167aa67f2d687d826e1a3a0c230fd7b42dca485f9e4355404bd0a02723f51022e1727caa7ad0c9efff7b94dd2ed1bd45c9ffbe3fdce9970761e56713df4cf7b0b1ebd4b15fe4205716932274f3e2e4ff95612eef415ed92cb3067a1ee46667db511bba9b253e736f2f105672ae7459dcaca6d04271e0e33a619da95081141011c022a40b48b8a4825223df59aff63da6a5521d51f924c70d126f136988c87ac396b021b005e70f6ec190456a0d9629139c42c719b3381547c7ac3891044c848b336d2031d17f4ab542c60c9e4211088d7173cf9effadf2c663eca3cae58eb9cfbc589ad03215f1005b780bf2f2cffb72fbff0b6ec5e75ebb9e54ccba8ff5eb4cf5c30bb20022a17d79768d5c4845112f895778549149cecde057f8da964cdfa82bbac1fbb9dc0cd905b65575008d1b4b5b8ca766a6a36ac077ac968d238fc950d7f38cbb4d0239de6dc2093dea3a2921589cbcd529781a8dc56bb6571bdb23e28f8a8e29aeac2c8b7380f20a8ee36b26585923fecb941a8fe3baaa0e83dcbead907ba214ee38df6cbc3d9cd1a394de733e229e54df0a1d4e74f1e2ffef9b01bff3e8762623175b63cd23c9e1c1b3af6dbebbb3a82c902f3e041333dd4ba7fdfd62a3983a84c430a895db4dda9cc8d28ccd9dc7a6e30f8d68cd1856771c6e21744cbee7b07bf96a8c049afadc2ff29173905b2433cee36f8aa6d480fa2f44302753de13bdb602fcece5210f3f16def20b9b357fbf50062a6dcedb99eb48ba6361caee8501d34055ac96162e35fb6e0dbc454bb7d18968205f24028510d25060c6f314dd0668f574dc60c54d5640930478e8f91775af5e8499b6a8a13ba73cb0e5a3d437a7e630c00dfbefd8421f9d05d38474b18b9883f0372133270c38c9bac9a0def8266c04acb6ddb94b629299f04df61aa48d119a91fb16692b21ef3b0bd22f041a133e394800b601530aa76d8f4d8b552ac307ee666b1b5f8637942cce9f3dbc3b50a0118a58667de98c69f9ebb46015588cbca533b6110b80bc09a7e9afb2b8dc055aa11a903e88bb3c4aa563c513a5a51991423c7e0a25d624f16f022d7e5f244d995a5d4abc2948761c4dbb0dff4f55f37b07c9714db365b73e960728aeff92d053bfa15933d08c7ebe19d70c4e9021eac15a3f726acbeaaf57bc05c04b60c1c01938d8d422681b90d1bf5a9c6de986ce2806749b4eb830af4f859b7934d886355b3cdbe8d8606a6471813f2dfe70358c173d687e009539a47bfccfbdc072f8255176c5aacd962fd9d75e1808b0420d6c9ec854c06fc9ddf5811d2ec726d43fb10db9ce9f7373db22da536734dc79a0107ce257d182ae2a153895ed23b4f1cf064f07738fd1e35f59c549d156dae80fab2cddee21b41dce2aefb7fc1048578a8b9e04a196b26082e199f541a23bb1085c0dbfdc873181e3581e1eb2f690505a68b81cfbef179eba48d3aff836c34a2405375ae66de3e02e4cbe5facfd6d87322bf3146aef3632531915b677f812bc0a795bf9c9c2df1577c2f7980322bee8637a5dff7ae3c4a6258c4da8139859e731ab29510109f7ab4da010f5524e75c7959dd4f979468c5686df482da95c7825ec493e4e6c45758ce8d27a68cf9b15e43f132d60a5c85008699241895d2124001cd183daab1d45a3a1e430e000edfb4bd228781b8806c43dd0744576af86f11902596ac0fff62677214de26d86d0db3ca0efa98d90150e4ac5b73f4e5dd38433105954928c746367b2eb2acd13b86b40b37da8fe7a3d5d3453caa02aa375215877d2335a372c2099e3e4d156803bf911a1ea0f96f43683a919fa259206fa0c4ef15d95f10653c246e97711d5c19b860d5efcfef52de00f99b93adf55bc5e79bb428f5a71d3f929ad87df5e208769fde1f563a4cdcb95f4bacdbd37ad9e2d541ab810cb995c166a5ebbeca41297ed20fae37be2a6ac4071edddd4f1913cf30567c11389a39db2d165e605acae683d02b6a167f8ede0d956b6d3d5c007d9961a8031064f85c09c9d884473c5a4068eebf6c779bbce1f2cf14d8071bcbb9fc809a6515a6cbc4feeaab6dab8ace9725cef8c59d1bcc4d9b8b7b6aa38ce9ff45455a0ee402e39b02af57b202000000000000000000000000ba2cb3a465a7aa4a90514f49d5b5cf6595916892ffd20f00f2794e32652cc29677a2cce8eba14eda52662c2eb44a78d48fcc614e718ecb658658f2b36bbfddc7206b5e057ac1b3db4e4dcbf7d098a6b65d569bd9aa2a7a82d1f0b1f081da9866000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d970ed89a88f42ab0f71924ace1c755f35c7c288e728df9bd0429b0fdb73f8c46be8af6c0323f07a2ce0f7d505b51bfcc6969d66a9b11d9c4432d470aeb8445568088646d0e0fcbc8468f6f9066e96af76cc9f2683870249a6c6b8f3f1449d2c10c399d579b3d02e092af5990de82d5e6178e6e0638a5136189802e7043a4df02156ce2c279b9261927e61aee7f9575f394f9dd83e249f75d9b798f9c82e622d00327dcb5666923d2adbb4e681d8d786b0ab2bff0419b4142f4af3f24813f4564930b14dcc952aacec67843a9cad5fab8acd826464448e709af1316a13210c89a02df07e73c82d34f3dcab19fcfb0b23e62863acb6d90ce209ecbac50984f3d17e5990311260bd8b30aac83b7aed100cd271c84469c2ce6d4a7d49bfd8df19e9d6e67cb030748f54d13e6b1805652044a9e7d7cd92d61340c31dc80b95485168533077937031244b9e0242fb1ab302f0d87e33cad787af0556c34a91c6035de727d937b52f8022562ae3e15ace447fe03a0caf2ba8a9965642c69ff4860c841c4beb946f7f8710203f6f788bd0b60ae284d296c12e9dd6591dd7d739e44b371d9fd381b1283f6b1e5c1b32e74a782b82e4fc8f83280ea0c2e0de1073e31d5a0d3e6660742e931a65ae03f6b13a73ab02b25e3f141a6bdf644e3b59c527c64a515f4b39cb0119b3901a06c95d084cffc37c7c8e4363bef53411a31023eb9660afdf1eb0c3b22f6a17e08241f0f183aeef0013466834622dda84ea69fdbedde614ed516b54b96bdc7243264f6a96ff1b661dc4bd19b5c8c028571c27948edacf9b871d6f706017d80a122b39ec21ffd30e096fc3fa25f9894b36cbf068236504df17de9480eb3b0c3bee14b8578913a32ad04aece6b718d44be483aa6a62a83c4cbea4a65bfcf5e99d282e637683d1e2ee16663d13fcb976e8fb84ee63a1a52b6a35abb0feeee73dd9bbe9423afdd8a50d1d41fda8099e8c3c0adfdcb4eb65098919814acba2b365cbb311bc76d1c0f73b3c874d835981785968a3c594b66a6aa65920860d35b58257b951a392341b8e3f39112b954efc771fd36bebceeb78bd2874bb6dcc0bd53c735f40372dc8cdfe9da1b25ba19e80804a2733e1a5f925e4f16a08971ebc49e59f10d0056cf80c4db848cd122cd3768dca2f1c7c2ed5e71d5e19669823b87655a3baf0775e26057dd0fe0bfc7474b9be1a903432667a232bae233816cba6ebc59957b21e950866f8a0046af0a80ab6cb409353fd17020dec284af879b0f7c92961db178046fc2609a749634101ca405dd67104125f2946a8dc20f95e94a8e2c6a9044a0d464c96baa022d921a09fcc4875389779df99ba3632ee19f43a4d742d71d61096238c765d6945c7c92fee13e5962ad237a2a865c76e75ac45b07ec69d329dfc14bdf7705dddd0cfe3e38313ab0f2ac3f442a486a16ea620f6d8dfc7a3f79eef58c3c9c92f73d373f66cc73a5e32e3a4c5c0e93672515814d49225c0d633b7bf4676fbe5ad4e0ad03b836202c72874a5689dff0e309f07adc84764923fe0c94c66bfe7a5e4745dd2880976084954adbd77ea2d74e4d565706974e6879912d926eb496758c48e063c8b2adc9a80ed19a4bb3342f28d24a419c271b2cedc189edf82fec762c81b8e5bfc7b2e60e1465907d8f5ac03b2b1b7c89cd4e5e09d291844650f4f076e359a0e2455043c55a9c69dbdd8ecec809d87a02db24a69f8f92a597e832b88f7dccc2a0cc6e293da334a95b095eb69ef7e36b4fbea14bce9f82ba7ea1cf0dfdd446d67c95623753e5267945493756794f0a5e31de64f10b816fa34a566ed00c94760d5ed0d5bd0b7926cafde75168ab5de79fe7f636b1cd2428f8208fdc7126ef847a641a90aba0ea420353141bccbdfc4bd81b68d2960e7355a98eb3710d20b02c811c25ea8794a5234062771067d9befa54b7d56219dd314cfd450a089fd177c65f29d000defa37e1c4a7445f0f8f6bcfc2ace9c30e888ddd2508ae874ef60616ad50a4072d0c70688475b349c0ba2e464360199f8d80de93044b3f2712df0e48fab0a7c67445ef6c79d29a05d4409f917227f9ecafc5aadab485d6a85e33ee32cd9a6e0ffd73ad27684dbfa70cee64bbf51823db60226685a195386e7f9bf4cb541044069cf9cd05c4dc44d92d67a72b20e1fbb1f61859c55bd39a7b910e0cc23b79fa130b6c19127e1f79d42e59753223c5877ee4f119f7664b6b54b1440a618317599cb8d8fa09596c5dea7ebc5632c761bcc6ef5a90e8481a3a2141a83bf91d5f4de2b7b29a3ab3705e1aefe0865cec6a2898846dea10387076de9e64c59ff0c80468b31f97feadfafd225f8f55e1091984a630921f55073fdf9df5cd0dddd99821f940fcbb463fa828e1d778aef847eca34057173707b6c6278eb2937d07c200fbbf3244477205", "5365", 2, 913450060, "0c7ed87fb8931ad02e034fc0979111cc78a75335d0d5e0153c4df9748bc3f968"], - ["da3638a90413686eb1f4dd31df8f4d2225f01029c646f8779992117f42873310e7ef588565030000000151a79f1f897636da0aa20218fcda838a702bd4de2172215cde2a01eca49d6f1123df6ec35d03000000025251ffffffff38b405904f5c2bdb86acb16753ad20cd7792e063f0ba08ddf245adc267a54e5c0000000003006551ffffffff25f70dfa535a49e951392a8eaf5064bf668ff3b61b3b87814c8be7e19866b02e010000000663ab635252ab88e00214026a3a53050000000002655380491f0500000000056aac65635200000000", "ac53", 2, -965840814, "3903fe7ab41fb776aa221292fd81356c8ba9194da7ac2b35e1646a3d6b15368e"], - ["f83654e803e8616df0af37c926ec61ded73042144376ad74c99400e4b4d51fff8465c91a040100000007520065005163001610171b8d74536c5fce3d434b8a6e1c03b4a7616dc07f384da8b32e25a56257ad53a6d302000000035363516681d9af59261dbffb5de78483841195300babe0b2e7eefec57065468a53050109716d0d0000000002ab6583687d7a02cc656d0100000000086a530065006a00ac17a14201000000000652526563655200000000", "5253", 0, 1461359083, "f590bd1372ed7bd754e67ed727123bf631c58a0bde0584952cc0b23bc107135b"], - ["128048330410257a1dee50a1448a7f9cee3b9530193495ffeabf8d5c97df4801c4a77078ac03000000025365f6d2e04eed8b37c750b44d7dddb9b16a25793b79496282b4cdb46165ea3223cc4152cc880100000000014293b08fbcb0818fdb47e559bf717856d868279f5e4685c16d327944960ee7c8aa43010100000009536a655351656351acabe7a51d22b437161b4d9a2f8d3b744517e54913cca556a418b2127318b71159592ba0f803000000025252c66c26cf03f848c704000000000265633529780000000000015140e6da020000000003000000000000000261e73e02000000000000000000000000aaad652e16901fa3a93dedeae86a531926369d0912fa66e895350c0c7f605e54e5c325cb8d92afc01bd5fe3ed90eb0f7b730bd6e66db5a96b6fe7c520c36be3f0e6d22c50c4470d92915e2982d01f58516bc2ec18113ce83491d50281a6329e6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6600504f8979bca86213dbe04aad9d991c61a3ba35148b09e0924eef49b2af47079ca0f7ba54f2aff6d125e921010122cf28aa0a84f983f26ad2a76ea7cdb363d337708925b26674546c323b952e1cc83992e594290aed5ec29ab8cb0c1fcbd864836bbf03b1ec3bbfad0073d5a0ef3f2096e1ddc861ea5a2ea298a8e6f4510317b11c7c1c2396b7fe440ce097002d5e6bfb204d0335e4264ed98fd499c2b2fa030c74d85df4b64fad5a13bee801910d245ef1dbbd201e4cb16fb9abbe22f785330b1ddb5e031b03c9253b19df7b221265648d19d02bcd97ff76a5f3b89977278592222d8be40656b2bc91a2d4cec14afc5a92eff440f087c31c06790cd7bef2f500031bdcd901340aa3d9791903f5b0c05cf6c1f14f3bc1282bc2b046d44ddc7cb8320227f058e9a7907f44548849292db144dc48ef9fba493cc39ee87a5e9139c6c2520314dbc47ef6e9f1ed072b3edd255728cf9d83ff83b62973a82755d58b26cc83fd02236b5cc149043a454ed8faf2abaa70ab60cab5ed389237808687da29a40acd97020af8a7a145435543ee659bdd3492b813123c533f49e39285c2a3fcac9a135ef08b8f483de98b85a5d256251a3170bd7ddbad015a1daa16c1f99e36ba99edb321a407e0fe7695796854fee1bf526de981b6a13e1ca16ff6784f11de862a55427637588ddfaa297a2cb57dba5c23085f56213e42af11d77f7390385db95b84cf07e7fdd7270b3f3e120b5abacde6204782d4ad8583f6f7b5338e25a2541a25334cc501c75f036d52b0c526b9bdb63789f85dc5b06c95d712f5b62e63621fbffe3e5044fc0655e2483fed5792fca197d1730ef7dd1d2f69f62430ddd9e7c3edf2752d74494ccb3bcc7bcb567e506a52a146c6e3a41ef53449019ffca1c854dfd895c6a41e98575ce40a00f5692d987e090db20696b059093f83a6a77ae536d38a5bda7c3113e7a37767474a5b53a684a0632095d698a080a8582e5067761604ab5b8732452f03a3fb9f983c120b21f02bc18c473a4414142b8e143731606615097303fbcacc1892d62d1eef55a3cd10b4e4a037f6013f1849b7f827d2a4fd7c015fed38bf71c85c4048e5a67e990cf24670ef3386fb996d241d61cc9d0d2cc0b18f25b34a6cc2451fc63a2950316984a10b741584fd7f0a4d94fbd8823e32d2a4c933574b5737d3949c83ecbb08dca1e4515a4df57d0b13ad37b640b9a0844c4d74b679822b2141ac9316387db0b5c1f81a7417e2b0522cabcb6d58f6ff0d7ba92cd58c76ec31b5f20d6bd3b04eca54b4e5541fcb566bde99ab42032da3875f42d7caebccb6c6b3cfae34c83c0856b7bffa5fe4c9b81658e2ab8d3cfbe741732df36931ea5b549a748913f61706edd506505e7e7e8277f6d9d519a5971b5c57d04912baf0331616bbb3dc3d7d270da6af69cd0959f16dfb1c78e7c8b17162653f2d07b572622cf445ae4626fea35125c89a0b1a2c4b59f8b43b62896ca0d7439b66d963f2af4eb3fd17c4bfd6cc0eab1b2ff7702446efbb9fafa19e3e5ad3a09be7210aeacfc0c6a819e4e0ee50a1b83f0f5204b316f09e869a6f76f76e17b772f8248e18f00320a560823300352426ce1d0eb94e168b3e348d71494f8c043e4288167f782785b902337ea5b47c8acccee9dd06ab295389d7907c5e17d995ac586abdd7a1aec1bd520afb793c9cf9dd297f96f72d46ba0117a6e0414440d80b6aea61d56c2a67d2c64f3b9071b89ff563cd2fdd08c5b484246ac31194e6618590c695ef7e47eca5ae1cbfeffc7ef57b32c6341a8da0839a90e5b75640ffcaba5d79570be3fa787ae782bf3bf832b03569b387ab861d693caf975bd6930558fb0334dd03e36fb63ec37d7a227878bfc792a74b8afce5e95d14262e35950252ef1d208ff5d57d96411e70c8b31111760839bfd499ea1db6dda42f2a02f953eb087b3b09550fb4a8dc3cd9e5353c8f80b8211e3cf38c4de2fa40bb4fbb6c153efeea7fdb64f521c49aa5687178dfc10b84e7c685fef3e2fc171a81546ed2f3a802fedbf5d2576c261363d0b3d0c8d797cb1cc9a975e1e3da14e17bb22e428cbfb3d5cd13dd8464e3b45d4a3220f40fcb4308bacffc8363c01023d558919f39b6ab1d4e8ef312a4ac863cd34165e8b9e3ff7a10b88e5481d434d31eab8b850b70069668ab60374dc40061ea20f8ec527152ecc821379ef8e178f0d37587ccc3b35388f40f7b6cae92576ec95b61ed7f28ca4c91a29226e17650373096e045ac49c2260fc42615be56b09859f306fbfb8f03c7f68068260a2a0000000000000000000000000033342ab98e1498eac22861dec9ebe951fe940909120d55771dd2f430e8da596dff22ee9316a4d178b3500b021a220debcdcda5d24167a0ed048714eb0c93d224854850cebf378367b7ee70a968cb9296ae5f887f85ea0c085caaedc76866907d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b35e0eacd77a0d29c5d4c2d77284a770ff5f2467e798db0f8c67de40af40a7c59076eef715bb9eee0239eaa69818687d60d37ad3beaadced45403b692fe1e5fbe9460fa1c01cbdfba3237df03daed07968bf0e25a514b421598dee6d2535d4614981475191bcc582cd22e561054fc79ef430cd53c9c3f53d84c90e29df9c30032c6e310875b9f81c022fe855effed2a5512345ab99f4f9d8f6bd7e6fe6744dae0318c5bbfdc5624dc5d1431ab50f20e11b09051e590bb69964a1bf02b76f1b3a6a0a1904133eb832c5331ae117affd148ee33fdcb64833aff3a9afb46b18e32dbf1e1ffb542f8b8367a71721748ed1e2a9df1b7811c7d051873fa5c55bfd9901bb62032ee87438277c87dedf616970fbffbbf3fd2853df01a2a5f516e89e8741bd03af0209618b37289f766d0ad2d0cfa0514c0100967c3c672357840f090ea97e0de169022fc94aad774f17d283751256885087ec5a8b78013dce47416ed2b1d0296c335802189e37d590d213c5c75e646567d4c0cf8b81a8634523b1c3c84e71c3bb976d56020898fdbc2389e86e9d473ae87212a5745e0e47d123c51801b8279aa7eda5f7c3c1ea5a54d2067e4a55a19aff0aab0e8ed5a1645856d99456d896b571228b7ec48acae86e476b3a433b38210f3ddc09f3b0bd6351b9b7931d70d69202607a7a9127cac42647630138b7eda26e222835385d8920b984099fc44c70c57f876ede84b84662eef908558dfa960a8595db3e6d429288ab5925b99bb2dfe697beed2569a6a68b12453e554780c49d657e2a95e560869fe2ec5b522f0dfdccd68608fa8524c5009e6c524c89e94dd708809758c57ee2a753d12db1d53c76ecdbcdc39a7fad14f579610064d542e1ef64c7b7f4c54990d25e73f0b22c46afd2661b98f20d84f9c0e04d523ab23f47f4dcb9f4d25a11d109ff0b3f8cc5063f0680cbaeb223e2a6bcb0794d0d8e580158598d4df1cf143030fc0906295fab1a839f0b332e4665c548034dec99d3ea27ba98c0ce78c73d46bda0e4784c8bf1a5dec3dc0f9fce7f8e0ecc4b42fb476ca95bb79d9f2d4c593742ae34b8ea649bfa6d9c361aa32a6047eb46d4731d099ce6b343d4d3321791cd73b53b5d66d1a30c47c7eef7e0c1b4a8d5f8e02e9724f258a991176f0960fb1517028fbd3274877b70764d3c1757752dd047287f5cfb14c46cf07bb58adb3385f2ba5aed4f009aa03ae329d0bb801d1be6d03aada73b69ac20a175f813df7be043d6c7a59b8aa9f7b1fc29105ba8e7ebfc1547d7ac405a14f4d74749ef901a50efe1998895fa5e1e30ada16fe0427126b3b2531c5b1689a6df2064134b529edb780a570daa82fad042a7aee32f1870482dd542949e7df0978361198bb8a46b98a136e495834cf01144a7ae496a6541e47e79cfe02d98e8375b9707665cc7271274738591f0dab3b0834e562ef5b3ddb4c433fa7c6b3f05b06255b76a53f16735a781923579bac738ff3f51cdc4141dae22c093e0114aa69e37a235b632e144a4eca614b90e958201bc74d3df5f2eaf934d0bf09749b31b9ef3204d15ec8f8f1e9b11523277f68a4bd17fb9cae8f0ae659bd93a5708e84e0e417f19ed8721d4341940334e1d28c0030ec78add0ca9fec279894a3cfd3cafe3e62e4e3407adbaf07ad6cdd3420cc753ccdfdc05db9ea5692509e9a5cf804fd37f38f1a3f248cfc74979ee4671d659dc98473f329c32005d41861f11a949115ed83fedbea48be1ba50e1e5a330328f75ff738401158429340d6d750989b5a9f92e1cdebec236d2f54465482fc8c1c9e66a3efd53e41a34c8d4cc97ae6da13ad9d18d491adf231c7a09a1b6c6e5534075af8ed4605082ce5d167a314ef7d3351025ba400e074343313c2b63c0f4f0274fe2b344bc9b73a1b36472df190dd12e5dc7cfa6996c83fda388956269134698c02f0377b67cdc39c1b001759db968c590892023e3af969e896ac692425205a94c4499b451702a9a8d8743417cfab381a27a994da666eb0b29c739c2d93b3182e7568e04cacffb5ec168ca0ace6de66bc4ece2fd82783ace48c2abf94065fd49e218e113f27ecc86fdedf500dd8c722c1f10c1bb227003d50c04c3286d2a64432dc3230f3a57956cb7b45901fb33d785aade364cff2cc952cbdb4dda13ffd22d4073e4c733e2a1b3ecaf249a4e46a948c44d9dc89f382077603b097754ff03e237e8db5e4f49044f645268ef322c2ae0b2828fad701688b49a3173c6b33a4aee9d56e58afe2b7d597509c2101006fbdfb121386ec3da18c5c35a99165cd3911ccf365c5eb8b124ff37ec6b2fb7b5a18403fb32163f384dcd29825bea6bf093aefc5be3fd8e8e6bb8261ff0c4d5635e43c8c6e4939b9535de6c8efa74a9b1b409f7cf55b73e80e1dc81d42b32c070e44483678814792b7cab03", "51ac535352", 1, 1337258466, "8f21e9bdd1e74f426bea7890cbda23fd8d4050133e96c8d756513311527c5ab2"], - ["ebe33b240241c4711911f86dbdcfff42149a5fee383947a085a14ee30b11a8fa1bda88a40a00000000050051ab5163964755654c3e91cfe323df8b9713a5fbf706ce1c9733d284f25e9f92ce8c0f2ee8b6cb61010000000700635163ab6300ffffffff024b784c03000000000552515263001cb7650400000000008874683a02000000000000000030e6a402000000007a12d56d236224c43bd61a3a93c5372c2598dd34585272e45ce983cc6a7082717a75520de9a55b8a1ab9237bfa31694068a6b183749192fed5bc163964acdeac5b402656fdd986d237c932d241a3cb021a7befaed084d33bb39c5135cde1768d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c11058c36aa2c5e7e857d9b0c14e6da0c9a0c70ce472f9977e71089906240b3d1f1f9776b227c54d6870888cf3180a3ebcb228ed0bfddaa061c29d3b96581100420ee77b87a87f22312152c8a508946e1cf875cf03c11fc5ef66690a242031403c0463b03f4d764ac1d708a7ac650f77b393318c01bed1e43b6fa9966c1fceb20316ccb53c8b6eee54c3fad3542b8b086127e53fd31e51e8b75b49cced025d7ce80221a7be2840784c793e6631313d5843f20c752e7ea5db9a4cae1bd836c705bd290b0a35762284cc35986db70b5a80c9af34a86331d0d70ce3f2dde731c19ac7d28607b76a1878a52b012ff27b34cfeb266e18bcc6b37556298ee9d63eb94b62b6d6021021e4be741eeddf95f4b81c9fd6b5246cfe0c3f6e560b80dc17ca1ff7d90b9c0201d6a0309c4cc91f2d01d44fb486fdc85ba06ab73b299a1cd7bedaafbfa7b18003241804e2a39929b51cf13928fd625edd05db2be3f7897fa587253e67b21164960309e4c152b735b5f003fbdce49c23404ee7823ce995ecb3aac267b1d4a0918a1a03063771bab43e4829c7f42b54aba1087ce6ececf64ffe110d707d9448000d49f7f1feeabd5da6f373af2b31c6b4503b3f06c93462471976423dea86f74172272d24a271420e6d9e14a8260afcc3b6a477425c6dec27aca0ae801f57eae65d3f1353d2667dc860d02a016bfc1e564d9bdacc0d396ef651f9ee6c415bc3193e43261d00e4a87aed37448218a60355cc8c547e5b3973016ddfb7067960a7dfe156cd5f43f1d3b7fe002de8d272bd497721edcabd1cac671b1c095f3cda4aeb2013c0c914f0a5fb99afda0fb5ceadb82181806f506e674d88a872be88c77e2849d7a7a7e141004a5268ae14d3ae2b1b8a163e13df02f151ff211ff2ca723970631e5f9001a6aca5a98d0ff06f2a325319f6b9b648fd91a79cc0a785443632ce87889d16b05ce670c695e740daec591b044a677843d05a141cebf0ebb4cc80f44bcdf825d34dce8ad112970532ef56f81c95d3012ca0533e0c999b4149406dc3609a66895373120af2edf1219b255000c2c0861ddfac9ffdbeb422ba8aa42b6afedef04acde65173f99964f62df8a193615f3cda4bb56b2c62f5eb2b98ea5589ea239419ff52145ec942dc74a699e758011ab925d365dd302ff462a8a51e4fefbd7c33f2c954c2c5b6e47aad05df4fe5a8eeaea4fdef4710251d2319ae31baa540c8d577ecb87408c2b59a3974dd2c4e6981c6458ef48b2e58320831272b9419576a1b4b0a24880d3aba6b6bcc83cad5b60a1f60bd32c99a35ee339c12d603a7dccb5d135beb89d53a8c8686879a80608227721bbc4ce95eccd4794c0f4a39c6b4b2625b8df787e8614da2d2d959f8b79d0e698ef602d4b91384a173b6c275873b20823aff2673a504326da0dd96eba6c39f775ff8a703f09f2f5cfe54ce8ff47048ab1e4c766fc129e9465dff900b61a3da8efc53f24e31fc2d8f4764b2f34406cca7448a6a4894016612d9dc474e8e236f91e17aa52714ba253dd4b10d10967061d1d7c6ac1aa489a91efa62587fca5149362b612b7da2b3e5204867f4cba6df22e5f8ddb1b7e8e894a8469ee8badbf57aab7fcdfab7e10f302835b74c71159da070b92e8eadb9d60f5ca2627027b6cab1b08341389f6a95e33231e0f50ae9e4e2aeb199ba2d6f354ad9796d9ad3aba54d17e04813ca26dd0e2c27efce4dc3d5f7f900dbd502866f7c20a20dff319460742a3d1fa4cb91b743965f97ff4d150e061e0e4e93aa3292ce87133f4a2dbbe0a64c5b1f32b11c00dc3dbf4eafe9ee48ed8e38fcf2b8ce92ac2b487d824133b7c39d65fa1ebd689ee7e1058fe5075bb75152678069ce646a1ebb1e22360a9ae1ed387fab42fa7c082528c6be36bef91b60c0aa599a83d953fc64f0307b7f189554fbdcefd443d7f9971038860c881ac66bc41c0e7b4806b2ee4848cc4bf6d2801a3f68aa79765259ecc0ee6298ca40eb6674eb0f5d77ef69cc9f38c6efac3f870dbb1a60aba3b357587fd9ae9851270c5f0720e667e8f32c86e39b640c4cd5eadc4470cb95884b2a9ef82ce8df88a4576bf5e076f31299306c5ab72faacb1338e5c2d83bd8fb8e838d84638cbd000747ab5511a0802b298a3494914790237b90fc77dc3c605d49dc16142f1ac0ac9cadea6c2696e22e7b02dbfb8f07fa89f62745393b58299af22071fa4bce57d6c10f7f62030cde3e7b57ada3f67ee698334ba71a5368a76277d15b41b9af5d7f20d99503ca9562b24927b7cfb361a394cb73bf182ace6165c702000000000000000000000000617fba4152e1b65fee78317eee7cfbf67652f090b13b453bdd2b8b2c8ae7a747318a634a474f386bc402cd0867df36c3b946a0be75624fc641751674102d345f7b7243ed168e07cd7c7dd8a40ba76ed705d2319111a7e50bce081161eaa43654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fb88335891a20c9b1bc4c74ed63d7569ac2ecc0bd94731eb28170c969d6b8f44203af47ae4a4d27b31cf72644946feb3a5cb2080e779fb942747367a22d0c7e48df37878e38415707a09301de5651e0302006ad3e6102845ea53a1c653cf5c0f044cab99043cc94835f111b258b6d835517e5ec6536b74eab64308ee450bf4e0206a5279f4c44058c91be9dbc1bfd60dee16a3c2f99aafba78b7572a0720716040223d407a3cd3c4964cad39bfa510557c012747651c449e02ec84f34c2efd6b0850a12c317532177f17c02809e2ed9d8b5dc53948e68b12a6c69cd04913cb1d0ec26145911a5f040fa6f92cb4d426c71d9c9cc10f0cb4b13d1f0ea6c3c2e1e965983021091993134b70c644c4a1edfba27c6f973c2ae1b6d786863f3281e2e9dde8e14022fa4e96868a3a138323555cb758f6dd3aa37236058d29d07f3bf5634cd85deb4020738ba78037fbf67118c6f4af728382ee9ef026eb2fdff7626efa62610f37a8103039266f802be11a92c5b45b7cde9ad50e86a58ea011bd16b3546ab2173f669ba021740dc8914bf9c06b1b8acff8d8d9b4a14b74522a68e62f17f5655b0c78238a86a5262f6dfb601ecc59f7620770bf63942fbc0e96c8b37c5f95edf89bebc75ac8db044f180d71bb81f24af69bbb89abbee8e835f2365547cf47251a0b26ab9497146c424ba851523109797c1298524f79aef928cf0faad47242c6e391f98e613d8b62e300bd0ad3f73fda654d078fe82fcb2eef0d7c5bb3846009ab431d4b039d95a891d194f06258712a44c697b4bd5e9ed6b79cfca7c3c71a5bfdfab4236cb3b2a45e2ef2bfc314cd98879a3a6bbf77b796b8f78ec27d260dcd079ca9372ccb6205af88bf8a19c62645c459768d32e4a7d871d36c7b37af18c292adf64a4815913efbc2ceab01ba208afa118e94f06daff052bb25d61e89b3206075d4740888094e34e121e05415e2df7aeb7c3ed0c37d6b71d955eb32cc1d8215df4a9bb678a4395812ad18068f3c42a375c35abb85539700d70d6d78654a2f7ff0d32000ddb40a470365137c19cad9dfc96388287b3dab3f0343d7456b029c5a9bf9a70237353cbbacebdabd3673f8c6824b13007dbc857fdb88e212753ca1760afe380a8d2a6ded20d0ef0700eab0b4d6bac00ff36a42344902cd82ed4e79379ce32410b97621df0cfb0423ded8b3116d9c93cff6a17cc9104bef7c7f2ea1448c4b8c76228eb2fff8f3970daeee4bb91e35248d4b3249c6ef55e60b1d432de449dfd940b0a4d1e8793f14c12c7669064c5919d320da4dbc25e8b3dffebd240fe974bcaff8752fc08f377218144370cf2b89764f516b2e2ec9d1a750d3fa107e05d6477ce1a3ba882ce054ee3089d850ae2988a435612aa423f37ab77e7395672c4a45054deeaafb392ec53bcccea26a23f88fd9782a7ec3d44b5222c31ffcaca5cf3a91b691b40adc728c5e8dfde77d8d4578f7493af077a4230b2a549af21059f04dae40d61e1ac30b955d1a98f8010758c893f8bb4e540d9595f588a171eee754170d2fc40ef43cb56597fb45226d3629052200392c3bf3843d16cb605e6f41d8b9e9bcb55569afa5057cf1cc4abe47c12c2217342967f8bfc53d05fa253664a9ffc48fb230e245dd5d29b51b7b3158ed983274586e99750747893f3d6a49f4462a0106124f03a97a4a6adba016f7c3b9b697c4c5351932f8b39775e6a260c57c746245f390f824fa9c7231c357701170ceb7e410b537f18ada9b47d29635b2c57b59a7debd84039e28529cdd40508a7a5d67efeac0dfb0f27a7783b24995ab29eb04a2bf5b0ef62a764d8cde0b67621e8920ab680a4194b460b8c856ca9a1e0e0cbd8fad6edcd586ba7ebfec8afb508ce10a764563c25419b06345b97abb1a03221668ffbeef1248c526bf9b384d3d0b90d63ddaedcda5351fc25ef55e4a4e46ba9f2b10d36eed68f84280ce2569b24acf4d43c4608f444eec23540815b7b39303f4f625c0412c44c8191fcad1485f1356d14912b25643329468679f870903c3f65325d9d03a8ad292f6f5d3bf49f023ae1d82f29183d2c855d16b9412b0a00e5626266edbb188d17830fca7da47c0fe977dc8785f027f025153dd584da0ecd972b99937cc207f56e61badc146226e51417f8e330a183e3eb53bf3bddac89e8f5878a001d4b333e4eaf615202bb1b82001daa9e68ea377391a788d12d149f49f0dc9e34212a369c20d179353db8f675a57a0fd9e4751ae5ca8b2d40edef297a980f641d41f9d73b9ff1af3df2fd9325b58f0c08397ac919ce240d23cd567133110a58352e3a3474d6a47eb283b96c1557d6067e20e2fe48d88412cc6f81c83f0b60a6cbbc505056c3ea45e2685eabda2117ebfa1f334cb446a791b69a038415ee867dd7c325ed7a8e858d445b13630a3f546bfa0f", "", 0, -673625490, "340c7587b869a58c65ee7d23ec2cacf2cd76b19db46251cab29c315bddf5aa4b"], - ["5478007a0315d527fa3b36b69ec00d46573f3fdf6c1dca6b2c2d134473158736d930c484ed030000000851516a525363ab53ddd8d9446cbdcf75c89584472773a42c5c700e0424ce2ab21f31cbee423474d2e0976aef0300000002006385fe1bf377f38953ce0674a4aaefeb6b0c5307e6ad27d538126475e68e690ef4f8e95a5c0200000005ac526a6aab20c6aef602d777720000000000066a6551acabab0ef861000000000005656352ab537310f21d030000000000000000f4ee0d03000000007b3f7e726506a1441ea4802a84034025ce0ffad9080e5c11f271cf396a599d5d9fa6c8d43f3d84ffcd4ea06c27098e7cd8264b5508743f8e9d85ece916ea2aba5962213b6c544efbaade9ee75c6211e36e467f159afc8e50b122778d5840352a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0bcc884de573d8ccd303de2a0c13eee8be987934cbd81916e79f2c399647a9a23a023b02202330c77ef7a60c5ac467f6bf10c9c70a6dd237f6a2fd0fbb784158d8bca50b99509358aea6cf9e12ca71fa0738b098b648c1771080f1962b51a71bbb43cad9fe6c3826cb6bd630864d9051c589fd25ecccfde6fcbf60999dd1456022ad8371e96dc0411a5490f58bdb5488b78ac2d2305a1c175245c6539bfb3034c0224aac7ac901f5ff034e81529350eb5ab66c7b577a42cf36cab0394f01fa3e3af0b267e7428486eccb168fab3cb425d0dbd58a7c887b793f1bfaa953476f273c3cb1baefee33c238572f3643a80d3957995c51135697010d7e0dd3be1284e8ec1cb030cfd2036f82dafb6d3bf3ed4554a9f6c611ac0d5f436f1d7650a23a18d36e96f02035bf3e47cb2f229143c3d92a587e77fbe5d2d6ee60c69804765d9c4c6cb3bd202300a159db4441a95561b262e7722e4df3d25fd1b3f4beddbef15c79ed18959c50222cbbdd7a483ff185fbea1e16067e7ddc0bd4786c11629f3ccc51735d7172e4202102ce0e77b6c3f90ca163dfa7d585b39a65c8416169814e778639405b88c94bd410ee00df26bb455080cffa1a8ca9fcab0463d6969a33525bf0bb222ec9a55a2d9b13562702e0568fb2b6f41f221b57c4870c02c0d4d8d66eaedd4c758fae32d3534f5be1b157eb248b96d65d56fc01e75fc1c0d8306eccbfe3c0c306e64646e6aa876cf0ca9542fddee2eb09fe454c520a1cf84776511b4aad48e2f6717c8b544e5a30837617a992beb43a04e8379bffe5c9d32ef63b08f4b6a94f6c1dc9c815355d5123bf93a09b8fdb0625db8c89bfaf08758aaf14e8894ecbd93bb7db64d42b05fa0a16134500599001b408ea4ae40193eea6c5cfa1f157a60d1dd44ec43b1a7fab5d973c8b615a38646d5eda7baf42743ca6bcccfe23e992962f4d7183a31cce8f0baa84e67eb3521755fba9d7429aa7bfb6f7ad3e3f5f264da6dcd59ee9e11bfe60084b9001183fa7f436f550be3a914fd73d2e825b1a4d8fdeefdd23eb6b94cdf3af4bfbefca32481aa743e794bd8cda54f357c0652ffe46e32a6260df2451ec4da1ad448f157b4f684fc554938720d70cc85f1ffa1039688bc9c5ca6d298179997c9a190ad64114efa825195e0526ec5e378698edac683d1fc2cc5b222cf721862ff3fc8a69b44436f6944e6f3884a47e16546f10c7438d3538bdba398fc689351568de15e430f2630ddc4e5eab869485228e242a0804454dee90152ed568eea7ce326188803e31ae79e6335eafef24250c0ea37bf0e5593e986ec13a36cbe8cc906343c2889735dc4914743a4d7c97ed983f7b806750337b03da763676f96058c111f14a56ab9b7dac6bf4d2e2a9dd3f435564fa95f75f69f60f3b4c509b4512f98037a294971f562ae37767e02951bad6a8991b0fd76965ff3c0fef3c37a7c59b25fb3338578e79f8d611d50fb074a0da25c660cd10e3f2124258c536f9301145a8144a73d8e5863f80279d2db833461e269992023494aa75ecda48fb1c3debc158fb059d2499c9a61691ead526565e34701f2e0a5de2485954f0d4021810745d4fbfecb03daf40957389c34bae51cfb5ea2825c55f4c784cf420bfc09603e4b75c2014a9d5d9224cfde48ed48fd67246b79f069dcc12161c68c4b1d0fcee0e14d086d78ecd32e5af0b3e7617062415ccd15293cb2e9760d7ee8817b82ecc128b46d88b2c901f0e184d72406a475051d6c109555beec0b1592518c476b646ecfb77d839ab938dc1f662d942811e7f93504fc4d9663fea3745ecdf142e20be1330918bf1f70ee332bf4d56cfa798dd5e058c906b2bcdf0bcdd95e7d5b907520d85d3de0eed71386e0c154403bc3e04abf8706eb3afbd91fd84ea49f8c6c663f1d6bf9dbc711b07fd4159f59e8b3d62c41c758ec1e3bb54520fbdf49fe23109a59204ff3904e096506e07484f725b2dbbed2e8615463cd8b3841d5f99d4f1e09833e1c9fac0dc4f96673224b154a066cb16b83ad141bd6aaf749e4f1fa4db796a9054e75f3d8f65db236e1b16ca7bd825401c37f94b24d288d1e3e50fc6345c9dc28550ec4ac5b3381ff34b403d7e9bb4c88ed981a3bd7516eabb770919deae38270b623c128352fdf4205d2bc4e7c26499e454983578d500499ef296b0cdab01ffcc734f77f4641eadfe2cefbba7b865c2024c00c92cf0432af2cd15b7cb8239f5b2b1c75278a2cc3346d59e32021650d0bb1293d7d2c2a91414321ae060c15a2251fd53efd5d5ff16ea63aafc6bd4c52040000000000000000000000009486eafb3e385d0862da7308ded5722c0d4a14b6e8744f04dfd12afc7b746541e73d087d197299cff88a007aa7033003922217e3cc0e38a360bb73eaa633329cf3edd0ddc5ad133a1ab69230cceb5469a4c25b3607530c20377e1c8df274bf8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242a2b443b8bf5cc438de2cc760618084293fa2d3fa6af259945d222c8b090e306039eea9e494d2c65dd1591363e7d3bc053d70b707be3d28be322bd5e5d0710d461eaceae3ff45289c26d6ce4a0f4248dcbbb4c41b70f80eaed0d3832ec6d27b094b826d942ef014aaedfe14033ff24039e8e29ae39e8e819d6e939f27bfa60032a219905c28cf6dab334779fe4ec7f4a2519c0c0358771fea44d2f0c7c951e62030816b857e6891e1540966387578eff869bb5d75316a86112777a5da6277f79b30a0bbcc9e69f569b7b8059e9a1b29e580054e2269a9f78151ee93f779e4e329a771acf6c4515a3e527d03f45a10e81362021547d281ca63e3351b9b6bc541b4c920215fb21f8ee21d5f7d9372941f5f907f82546141de9d6aee5980290fdd4179918022d97b71561941b9861250e2627d6e8c7ef7f39fed8855e3e4f6644f423ffcc45030113e9b447b7ba8a8237053ab15d856842cdb94d6660a7871bab478e3d7d977503002bee8582c02b879c8a6f38b4d6be1010a5a2ea3d952543773dd7d3c6b042e2021f8576e502585bff5595a63ad38cde0367d47473dda01dcff607fec940c0465bb3623a886430001a2f4fac6974994bebe973d352727d6c2ee587f62f65d1c8bf148541759e775ff8b97c8ea01d712814da1080b4b40fe637ad459d1aba817f88119c643bd308a26bdaccdb51f24761ad6c9a8ec949d9b2b5edea4aa86f372793b9975bcc73d6492fa748bb0fa39e88ceaabdfda0db9a1a83a8458b6a911535d746e4211e55eb524bd7027bbe9b58c112358d63b03b66af10910e23e990b8982af31688372b6c7fe03b0cbe9b01fec0830d474bd10988b4db2ae52f73fd172df3b143e17f2fad969a64d7e0e4ff4992c93b722b8144386e4f688b7b3ff6fce15583a9dca604b83a790c2fb9814694fe241b96dd4b2812f3d9111496e0757ab43b515a68ae5addb55aaf5fe37f32e17d7f02e68d887df6824accfe01ab1491436cf3747828063ab220f5d61311acd8992ac5792d6be5ad5e9433c050c3dee0746cce732f344bf6677f4234488f7e544b43a21cff112e5b654f88bad95fcb55f13520bcd8feb617709300beda28e6ae4f3a298855cca30c665e95f67918a9dd34b957f26db3caa514eb81845e973f54af3a049f9fde1de19ebe95f27c0f9f202a13b9747e43a2f29a3ef87db5d83758b58bf68b29f5ee9e5450c17caba6ae8e519667f0f4c6e72c8f4e958b17282c95790ed1c87e06a1a832b3f50d4db6b49740eb1d00b3c6a8e4d56f458226305fbf09400a2d2a62d0553921f31e1193f9c7dbdd1d399f39b121a5b24b010e3ecc854ca4bd5d598c7a17d1af637e17cf253966de1cf25ff5b7b218f4883513595d7baa87847d4561211ce4a874f697943258253bd17a8eaf61c62d9f5f84472d6c81aedb07104a1fc7de22c7fe888770ff730fb19b334fb3df35399322cf018d41d5e2a28e6371e166c6d46d12375cf351a9e24930daa63fb0482fd8dcf31d9480c6a3d06fe13efe6e3d163e2b91e9e19afe8e260a112d90e559115b8f6fcc41266ff7de2e951f8ea44629c7fa13a26164e11d6010b5187883e0cdcb3b987068c92c70f5528db99d7c9f0861ef7bc036c4eb5e734bea4f45c57ccbc0f0fc53d58324aabc297782d392c0d9e962f9e54ca4b261912d2c4b9bdc985e55f6fc16d4bf9995a7255f6dbcdca7d29b62566f92d977dd7b6ec9b9122f4583c456a058273900141dbc4f546373c1bc16a5514afa4d4d56261d897dc2b4e5bc32d66cd81058fad1ef0d5f55152fc7c1b74c0644f07a9ee28032308c562f2e4f5bbdbd1fc8f90bdfe2194f97e32e6a0f3b9ad10ceaa6081d24be56c806a186b2d2887fceaf83b481e41da0024cd08fff4e75b563f9be976010afc5f5b7fd534ab8fef458eeef24b9d04b6edc66a6ab9512377b5376bf8ef1f86a2135c6cfbd3bd7bc90a6a40abdb345b2eb83a426513a45893cd0d0659809aa291b8bdc20408c4e31bb2faa32c5474924742c0de822ec6e4c634657393c181cca94b47d7cb183c4441449d924a7641a3a8839145c35c47bec80cc4f541ab0dd04dbc714c23e7a4b1130505e7198a62605ea5ef7ac0951e1ee346104ca50aa9a51a3a15a83c3ea442045df125061ea9b727a5dc7154f0c3037cde5644318ddde1a84f9e8bc1c74aa8043f91baf94de156f05ab235dcf0151c24b0f694c5615dbb00ff6031e484cf443162fe7cc6df5fb784f54b4ddb5cd576e04faaa7266af92f2506815d0228abd0e7d9aa360a2b0da5dd826f99b030000000000000000000000008b501169b91d65161ae9c60696a15b777fee6f89242eac44f620c67e86f779d7a8d6f02361b1a682ffa53e499d7d375920e06ba00d51e6c5ac2cef2a8242a499abf41fc5abd1a289668fa699d400bc26355519d5e1b1b87c90754b5857d4af76000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bf47bebc82a4967e66cca05b3665c214bcab0bb9dda46defa86d0d4a7072d610aef3a611a6b502d4bfd047dcec543afebd068c44a119397d4373c2e0245997ac705293c7afc0eda64a6da22453169b7f226ae05d55a423485a64cc79dc13ff8bbcce3b128706f3ace9b076d979c1edd76746fae5a9bc4171b21ec4930d08895031693bc5b1e2573618e45b823195ddc4cc32192a02b96162e9bb64f7c43f9dd9c0316d3c9b21525959501437b5f766b5a310098c8d0d920c6f23ab32172554a4c110a17a3824217970696e52a147a7cd9b3d5285d57e047918e21b06f1c4f3f87bcbf014bef3b96aac6519a1f5149552ca86078e5a33e724050fb16b53330188e77ad032b67393594c5dc7450c188cae702d6ecab94a52165e657cfc93aa641224af0c302258608b80ead03d65a4fc9210c4822a810a719bbb4fa1738c79775f5b439f4640307c24e6739428dba8ec9debdc42db40c1f08394c3bf3064c830fee2cec576fb10208d1803265ad6b50f4cbf605497b1e7410cd3a9234024f6af34d2f693b162e75031faf100697fd22626bd2e4ce74f18ff640796a3570a924a0bb00e7595f82f0d76653e654d9fd86c209e7e335c492446d806a1e7c570b751fcc60d5fa82d719317e00c9c8039dce25874c4eec32b052becc831e69a5016605a32445498c13a336b330710fe7e2308de4eedac17fedf7330d674c9e3519b5080ec47056de9016a2f496e3fca876d63f87cfa696abb05217bd5272d158c3809505d8f5e781614c7e1cf0a0e9427064fa6399db0216b6f614adcfc3766213b8ed04228c71d05189ca4b2a04f0c2eff45a6093132af82161f5dc78ff2bb1453ad8a8866ac1a0ff4022c1289b852d06932223453e65bc4d7efdcae9c3ef731a2b5c93053abf2fdb8d4a40764a9b712ccdde2f4518d8f75bd160a2cc0f02856db5e068368648e85ca60572aeb98b2e67226f783cb474af9360dc5ade319489635d6751e93ce2c9b36214051a6ee8d0899fda4b3a133d8cb1acb0d5ba9ed208e317f4cafc539c18589a359fdf00466263f85b5c4a94d06e73159117ad0b9a8ecb6375459733a8b35ad19369a8122f3b126d97dda7bf88238c939f41c1c64887a481bdeb58dc9ede917ff2a386e8dc56c4a8bc3ac3b44bc2d591270ebb36d923e9a02dda25f69ada33a905c71263d6584bebbfd1219d2af0c243de8b1bad8dcf53b3bf86d63c37698d0a9ad4229318324fcc9ec573b564f2d6e60b8eeb9eb4168fb47948b1391b45ec152a0c79ef621a21aa4b679ec744c6d5aeed91c46664f54d2c781bec0b121d154ae65794bddabfb30e114f9f49429e9cd4a391665d4d74c83e71151d8011daa64ade0cf9e31fdf391d2604c0baa1279ca5bce00a0fb79823af50b92383748555bea10d0e3ecc80152b4e495351d0ed3e39471795b7778ecb4fb9b3c0f340cb139e81187bfac16f74005ed3b26bd40c2c20ffe31cd26848ce940dda89e6c9782743e41391f0cf6fe5cc23b0b4ba3bb6c1413fa1cf71404511ff137200307810a31b47c3c2147e62735c222032182caef30c27a44ab9ab23d7a46c4a181f56de46c0ce46638fece6f2573d60af0764d60b94974556f5eebbb919a2202bc287543f36a766a3a267e43a266e343ce93ae5e3420464b33deaa480cc651068984f7a51bebbb2d22302244f71a163f9b7aa9493e1c0fc80b8c305fbb874105a0010886fca31760bce319127b8003075ec2b31caa4f65fe70fa42de541a2218b66301cbeb4e404ae5fa78c1dc0d576ab3be72f3a2bdce5c435da9d1b9d14e5263c4b113daeeff4837a8ecb90a609976668497dfb75ebbd64150aa4f2313be7e503c854dc41dec2295b91f7e44f664b8cdb482d42fa21d000750c6472279cff7b3032981090185885a8e8df6d1e98656fe2f452c9dee1a9973db527a84da2c503120d6de7b7a84aaef55a89f09344cfa4e873c7691a13402a9dcddf86127ec9e5c04ecc0def9d6aee0aad38cb9f2c648fa577587738a4b6aac7549a29d6978b26de1230d85c935be8658a7fdcaf601239d45f0b22891a691f6409c321a28fa56689d4a96b5a4f9d7e0af23db5ceabb9e0e050e6b4f6dead5236a3ad43ea1c6212f053a2a6f646eee48ca06f1bf33b0395abb97892825ff210cbe557753076c615319044d68ed948b426c3feea4673f21564b8c664d65e7be785f5658b1e588d3a57ffabeaae29c59e50de87f4e6b9f6f1c187196590f23e75876008064f76de9221be6d1fbf7a1e719319769e852828241ac7601dcd0ace66591a597fdf960832bb712f003ebc5b74317a1ec899b3ec20f19c57c91015476125f51f1c88b2c47e8796fb4349617feb41188e7bbeeaf496b3c272d03cc6b1621466cbfbc14f13c2d023bbc375d9bc00766f12ac13ac7f4801ba3292b9beb503", "536a53516a53526a", 1, 168192221, "e6ad0915ab74732849e8aeafb2bb0435306f732ce4964a9ba244ae7a551a7e26"], - ["f0762879041480af8233ba928398061057cbb88f7e8ec0686a4b60856847a1885d4e75f30400000000026551ffffffffd0bf60ad0eab1245b8267ba856f1d1a56a0477d6048334b270025811d6deda2d01000000026500ffffffff09af235c4290f9cc3e4d50485ed96b4fa75c530c7c14e7c215dc2d78698b7f6e0300000000ffffffff4b5c4b26cd78ed0f55fa058d59365e28f183906cf8e1b51e41e4fe741c24cbd70300000004ab656a52ffffffff012a216a050000000005acac51ababc5fa9b4d0300000000000000000272000400000000f7f95685c7139d969a33b9a5ddb06372bc0e46e0d787f600e64fc6f1a2a94b469ed563c92470322da0267900ee1926c82998a08042b3cf757ba28246789fd97d9eccecfe75be3a6a8b1e4ca1650b76d67ed78d101526ab0762ce78e9575cceed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ef13446b1e5abc6c883f24fec623ea098401100a22ccaff4c195fa2329ebde55193bb7459ad3484329fea24997e54749511361bd0895ca670e71052a7eda3c1529b422ca5586f80bb927076a56388794edb941c56acec2940b566364c4666aa7131d4697df9ed3cb22def09a70cc34648d209bbc862aae65e0809831615001e03038873ea0894e931af4965df88150fef62d38dcaa3aa7d103f8d8481cde4c9460229709d65b66f140103313b8566e4aa636b3672ac133706fc6898049e36eb53c60a1177f827febeffaada10a237217315daf42c4e62285de0ec85761caa6c46d9a9189380d4758fcc3efc7b982158761c7746ad883b186134f9e20031234ec291d0030f0825ab37bc4c1c89a9f659c6a2dd310ffdd9a4276245341946422ea4db7a62022bfe058105575bed3ab6c45a232e533160167b80905339b640c9d7b7aa172a30032de51e2b8297a1c5b080f7e3648e13cd43e6f007795f5d9e802ddc0d86bdc9ec021afe5cee70a56e9926980c095f5e231a67d972afd42f92de3e82c63c4ff45112022bccec3ed5efbf6966129c15ac4630d77ed31346f4d4cb19311cedd9449500399146b19e04fe4c86249cf04f2767c2767cb6e6599ddc76288a79a940a7b42802f6347b8d1def9e0a67f2d1b10dcd37abba50d10d23fdbfaae6d444888cdf03dc12a508cafd4ffc656755c7867aefee8393abbfb7400ee177de05ee22a3c3de42d24bbb6b198ed987e813acb601fbb90d51cb3d2c1a50cab7ed38656b85cad867440df34082cbf7bd4f74ced05d48488ddaa733772e824abeacc9db8baeead6b4ddaf3572c54fa4a89c01d27c2120fa0d694edf68a884feda901db81ac4038ee661ef3f7be8870329f5f343bf927cb26424a8e16592b64b6183e9bbabeed444eb3dba693f94e06be36cefea9a95cc22eafebdf48ab8d5b2f96684aba9cea546e697668a8d322c3b939509700c0a38eb19a8729e25526cb5a0046945ed771c257059b30c2eaf00025362f2454ce5cd8c55c12128df8082961c4ed894daea849f07c1b173f0be984fd71162ffdb830bcdcc9391f73cde6352c745a2caf67edb2b7f07aca68acc914d4d17f1341a4bc36bdf5d34c898757f5d59e286a473c28bbeff3af98e0004402570df1241fe71888b1cb0df69b1a2e7775e0e26f0c9f2a235aabcbd945f4ea0adb4333194cd0bafa8ace7e73d6f38ee4ca7264149cfeda385781930cd337b290476bb68fdf25af373f8205a1f183968cce5ab3bd31fcd932ca4d7616ff4fa2860a6a34b1c16fcdba5e6de4f7758795817361cddd973616d1fa24ebda0232b39be1479d8d85b7a8f13f444c4eab0b38c7ef0e833a7f4e8fab51e55639bac7ffe84ccebe22dcd3149cd4206f4e6448b0734088c75271085ad80ca9494247d4e11bc4c7234796e690477304a8cca4c16c7b2f3a44563242d5211556e2949b10fe83bd6181885d430ea5c918c369fec99a8247c2a0080810a5bf4f6b914daa67ecf0b961fb144a031c1d7e6e15e506c6ed5e4a009e2d65604f86e3c099ac3dd9999d47648bf44eb6c83fe2bf9d72d75fa59841d8cbb6cfc3b869a04a9828c75cf1e6cac244d1cedebb75db93ebd1d93222bfecb3ed0d07c522c87ebe4ad985f422e2877bbc751a934aa1efd3619ee6c632ffe6121fa7abc33720c006732cb45bbd796b985bd36eb8e324494c35457eeeaa38e77587ad920858fc80d55ff9940e5b5df00bcdd4a046298890524fcdabd5e2d03240ac8d3c879542cf0844755e744bf8a82adec1cc7ec0f1314116f62fa868d491163d835530d7ce48d6a327b11771581e6a42409defc7659b8b934012b7c8034a11dff3f5fba66825f136986da900d52a41f2bd2a596a2cff27fe92fff2417208998d78bba2d98f148dbf5b840b98003f7bbc44b90fb2554247ac9655048e1be08c5c9e34bdb402e5246007a7c197083f6e1928e9ba4257302790ba6b65ba9634e399759d8da1270e95504caab8277a0eb8e15f1405f6700ff635420c5076025f7dad5214647ae4860af630423c717ed21ffe60db802a3e9074a0733d2481e5dc046cd2a04ed68dff4a6f58c2caa2fb73ea5981c84df4868b5e916c8b6902e2e9b0b682eb09d61957e4137ce6fc7ed2660a42564b80907dffef5015900a97d04254a791b506602c8b50e409f37098e10e9ee7d338871d5524958361dd332d07d674601028b81e8c3b1d9722bc8bacc68c569220d141bbbe17fa662ba55decb756d4bc5f22311c6c3a3ca1ec99840464358111dfc2590a1bddde5e0d5d2bf0100000000000000000000000092dd64e1a13e65ca2913bd59007b80bbfb2e22e63d426c679e532f7585cd0adcb53c5261452a3609420b2797d73100d0fc63cead14a3cfe1c0e6b612d93a213e617e55d2f6b084d435c7b5baae9568e5f7a934f488440f0792f551134bb337b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5c5434fee8063559198d5ad12e01b02ab882c5c5aafad542f9e1b3bc311b8cc64c2645f4ed79b1ad29832e6c838f1c053c39b9a68ec80196eb91b0762c094ad5e7555650c2ddf3ac12eb5f435d21cee9bbadfcf76456288dd150f793551cdd88f725a7168b104ad6b07558a3f6de73d872330cdd1fbf30c7989c284da95456d0313bb8c2fde6c7163dc84d65cbb369bfdbbf6e3de9427cdb707b3f4cfe2ce15ae03239b5224e6c77eb3935d1e66557b197f238532fb63cd3b2d060da59649be42d90b0ca9a97258da539b5dedb30ede947226073a503593fc49541f240803f1478cf320743f90da9521fa3d945ded44c30552c2a0e915bec5fedddf6d2fd7f690b88e030cb7e7a4f195904432bc38cc672bf59393838ca5af4650633002ac4645258779031335f7cf12f428901d7b8f5a041722fc3e8b5486b8186688121cf715ce74c6bf030cf4b00f34e4ca2d2531e3cfe9a758a3599d385b954678df79ce996d0f816eb6021aac2bc7e933d0a3406a99b609255f75dfaf88da34eb3bf639212c8c9d409db3021b5a1cdfce10c26a0912644022fdd1927156a1e76652187db6351b66fee764dd4123dbc7840c5392bc5205c519c079b62c41a63297a1cfec0ec6f47059217d0ee5349dbe4b9a418c94b0cdc265616a709a04bec0b998d53b8dc822c97e151d58ae7519d7fefedefb320123514bbc59aab95214a28ffef2df57956a8bd01e38415ff9bab47316ffd2df4bb62debc82cca2cea4cc6e1e4208968670f074acc26ac1bd025b46bc886b831dee42b8f5bfc6b6c949d91701c19d1fd31068bcb4f74b4dccba9d0b10ae97e8d5b52492d5545001f4d4280be9c96db1efdc1640226acb006cd019d113e1eaa52d56e1420f5daecbcf8090d8062f2b89a06c16b1fd9532044eed9335390c4ffc73dcd73e6a61b5f7f4edfbd2fa64708055eeeba57c49436ffe300749fcc8dc88274c4c767c6cae5487fcc9cc60497f7e172ffd53eaa81d51be2173a3da66d850fd47edc7cd855bba965de0fbd0be15ac07132af39bccfdf2614d7d5f9f42feb6b27ad44c9d1990c704636055032ee1d9ceffcfd87e05e61c976e61271d9b3eb0134dca1318ebfa3f88a75476a3b7bf44e3ded74ad6713c99a3e6aeff6c0a1e2dd51140a5898013e8eb90e27883d00ad6fad9cb0faeb0569f457dc8a173a4af1d11df5ca893f7aacec548eaef6e100d7036216050bd8f04863c477f5dafb923cade71b0e49e83cb41fa2b3cafd210287b83f079729f736574962ca1ff8865a5d0b10c4db91169660441a57d2e8affc8d11d2eec9dd2d194105641f57e984b99681b98d2f5c36ce4a341da36ae0b4a6b9753bf463da4207c2f24b4d4b5ea55a70883491498d43ddfb8998dad80fa84162aa18958be297c2f259aa2c5cf5357880934bdff5691e519e8c3b40d2b34bc0768d946819a4b7ea27f8e9243b45ea0dac3ec27626e0ae15aa7b22bd7cb8d6787ad918fe1b008587a56e5a415ab6980341600c6d373550f2102b8532b7eb5a317ba9ed743aee3b3ea5b11c29e96c7d71359fe3fa35c8a0927d7db42cbcf8f328e490a748a5ea0e7b7ee028776b6639e5f6dd1b8306dab92bf4b7d29a4f1379a64f8d9eb8ea574ad66795bf738582de4541c0bffacd9a5ea25fc4ac4e6649c2c5ffe41d5affec41ae45f78d97a85fa47d84290723187049240f14aaff3c44f6f42902b31c5e67833493dca6925439b160ebc13f73cd5b7fd941be9403a1f2f208fad45b39e0e957ee555d0741891e03b37d089cba00985154cc499daa4b458d8e9fa69124ee65dbcccab3e9ee237f9cdb4cba06069d515d10104af676a411021113bc31d4d617d1946180f2c0f76fd627b5126b9f25829597bf838110fee364a4ac981f7ed3f6ffb334806add543ebc64625890e0b27e47273677721e21b37043851d59c7b37a7293c9c3d4a2d9699a933ce39133cd503769934f319a0ecc51919e7abb61753a9644af11f8e23f0e10b77b6f002c56d1721af44a7f7519e161ecefa1c2139639bbfe953269632e861b25aa6186c2c865ea19bf3f08d0c6e1e17f99ec1584a501361661af8fac7039f8191731732f77002fbcf390e00cf63726b2786be9b0de86a332a53c13c6c34a4facc298c9989e06b95b5637d2a4fd05a57f419aec978c3dbf6ee70c3d4be6e50ccb0d6dd17c6c4762bb7c40c222e5e6dba6fe3eb22b5a5a6dbe44c5015ec0d56fc75b56e5553667215049b9a417f4e82dfd5707a0bd4f792030b66379c2511696986b926715ed846dcb89d77d4130d7020000000000000000000000003d81386369992605dc2c9302c1f385a70823cfdd9ff4ddede7e60f55bb6d1a750645941f654478327490458eb3056907330b569a14fea55fd7358fbae14ed938f45d96beb4de933000dc6c7e94cb272b34dcb193a61b27a9c1a20fd8c652dfdd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e1500680132e4936dfcf07c83ca45206831038abdcec1a8b6a30882d7a2de60281ad26822122d43a009cad7c3dcf4dec12c518f67b2c3a530c8c670e257d71e5b3ab656446433dd62474d9e328e9a5a094b4d393ac083f5101a4d00691d2c0ddad013baa96a8b44f99130e91c24009102e98bb620c21b369e7ee23c9d1c3024020650498e5cab2696a8ed14c1d78be61363d78f94aa3581e125e9b73fa56500710207d3b6bc4ead015290a07038c1bd22d407b0dc41fd0526c689b66067464dd7010a01dcebcf439de94d5d86a959355d7107ef481c5779c4dd75b33d17ab308905ca1421ea827814dbd88f05c188e5a6f33fa086c87d1f24d5c416f9d7f274750f56032f2f747969603d1bb44edd169fb620918ed56c6fc0aa620274f3a06b627578bd02043ec3b6e21c0f40bdff42ffe59e1962d32db72d5fb4a07bdeb49395311ebfbf0313ef3c079adf6f53989d49a792bec7c5ebf79a7e076637551ee1ef5b1a22bdae0300f2d58dba4caa079a43468c11c1374610c2c40142a7d7ab2d1bed3b9b33346e030bbbfc94530a9913afe26658912bfb0de275e8b912da2d714610608f7d2de776dfbd7ff9705fb3fc70ed866e2dcd04e287220e9f9ce7c048e528e59c40354865b47df164302761f7b067c0b256efafe41311aac2891cfc92bbf6e95d9e9c64cea44184cc4f8e88a3a6e90eba3d4e8f49d0e92a31b4315908c217945d4820a6887651ceba874a41d99c76ea3af724863f2b080162038bea7fac5af0156b8498af393a4ede625faae0634274dfffe3435035a8d2237d7392c18683dd8317d961380c7a827fd9520bd340583622023eb27fdebab8f89f1a0aa5ee8b4abb23643d9bfed89d1a1cafcc297868a439a1367eb1735c6a61beee0e6c8f2e35f97bb41fbe3ae60d823e2372c3912a680a9e79677d5f1fce7a7f4109450bfce6438e5afd22788f5b10e4b598e5123eae62b6edbafa8625f9d037697b9d94335aefbf47881f47bec4b3f2ddfe51911c82eb31df79b5915a7f6f1a66275f98e515d305d1f4cb27f222a692abb7e5c782e5970ca88be086d73505a3051c467d097cc21864a9070c1862ffc6bc6c3d415a3b4b7ed7b4a1ff8f75c42b1e833a6bbe5202474219c22d8696015b93ec89f091b8878cd072a7e05f87d1bbed535fdb46d913672ac8fb9d6f65e2c150252872e1d8d79077daa40367e3a2d111749df40474722202dd1c339f7207cea611425f36d90e81d9492b3e4d8e1f571dc076e736e9a2a1ce27fd09d552a06d8f2e81c6043f72e2fc1b4a2d85fbb9c98f6da6bedf167b7585e873536883adc57617718409fe24a43c21e62aaa3aec817d625df4af985259c05224c961ea490e66c0fcaf2236b0e6b397d8f0afbb5629ad9a19532fe68befe10c06de7db78f17c0c890f7975ff90bfcd76fc7b0848b9fba963396e8c38990539b38ecaabecccb74cd7731c8b009f4b833ce874f51ab5750bf7ca7607ab71f0cfd69113a985a780a2b736998413dac0d0b028d4c19ce70aefac2520d843a134e8a7acf4ad404fc6f1fe98c1c8461f291af2a570496135fb38685f4492fdf93284e786949b23fe62d5fc08d75f852161e1b219c8a09de4b8fe8685f4651f582c47e890e548a5c3b939009f9feb4294bed6373f28426221b05a6f93445c8233e943deae440ceb37a87ff45e9430c97dbfd54435d8c5ef3198b9fc55f300bc9156c64aa719c239e8ea8bbdc8bb80e178895798c2a4aa571d3dcaf0e923851eace0ad6c26181c21f92cce1d62aed61552da7b411e7fab1e88df177c397e7154e0dc5e78a0a1631293aed44071e9c005f017d448e46c97018d24edcd838a7252d37ef31b340898be408c98124bbb2ef73bb9be0795ddf205717d344bf5afe9e65e8bf03e41fe9d6e84a0d98d23364e943fb4788e6b880a9cba50964f1617ea22aa1762310cae88a49e8ba497f5ca45821668788e728348fe700d5055440b17a1370092ea802478ce1a6a86dca54185d031b9af9d8f6754fabc943aa3b1f53ca6769356fa8cdd5d590da451adb63f2355f0f6401f6a562ff16c300ca6ac3030aedcfef9d830501bdd4e77fe2a96176320d1ba9307dae8b4022123ed72d0b53867de48de835c12b2b2c4977b9a8349f5aa30b68f6d757586a389c8c3aaa4baf0e4fcf31a10ba34fe8259353195733d240cb8107f46dd78f2970171162baa30da2518ba6d7041e50a498dfbf881d22b7dea780c6b00735b5007eefa7008a6b6697d8f305b5cfd49177f403e3739faba34c042c12fa7f28b07688d886f62c72e258e360e4e690c26a86b749ef5e7b19d48489b7277f36c23fa0d2c1984f9f2ef22ef5f8a4676e90e3ce7b98bbf10a08d463815b2d138853dcd22dc2646d8c8d8d2877564533487a3634fbfe3a8667a8e0ddbf4fd4af6d3202", "526a", 2, -12162373, "ff18b2bd50f0c75ccea7e5b1dd670c4aca36cb09c195a5386c33030a3c2c3136"], - ["1fea829001f7a6e1e3ffd2bd37ecced7c8f716965c160614fec758db75498310dc47f8ee9b0100000009ac5363655300535300ffffffff02e89905050000000006ac51535365524afc7d0100000000065153525300001c8b2d54", "636aac5365535165", 0, -30289340, "b27322eddfec9985656d0733cc2704d8ca91f95a66847e714bd89b61fd78df79"], - ["bcd5a94f0223cbbaeaca4e7bcd136abc02fe6f2cc4d14f4310b7f55baab82f94ae6dbdafe10200000003516551f0af98d034792bafddb1156252df7e267a28e6a152013aca4392d56060c9b9c670c9f07103000000025265f2bf1c0304559f9402000000000865ab00abab5363656766f30400000000000bd4a201000000000163fbf06e05000000000253ab000000000200000000000000007b380d0000000000d9bdc7658885a7d261e8ef95d9561bbef309323bd3f073f9397b39c841dffdf7ae18b03201867dd70c79c27f8385a6528142a7bbf5da10a4c2a6b688b5a0d3fa9f0f16c75efcac5590075d5290085b7090dc629e20f495472acd822e51d690b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cbc63d28964a0fa41739c114bd7be688b3099389e87951a985fe2bf3c18ead44b6e2972d54c2a8742882b6264f1c515ccb3a8b262b05f466d8d96d20aaa3e3c2afd156bc4f1b6a597d608d47c1eca3a4f8e82c3b2ed0a1855dc9220a5c5188a08a432db4e48dfe109fd7554692969797d3b54c5e3839cfe5a328cebc2d0fbbaf030bc8881639a3c3f49b93acd05f91d1911323c165127d5c00adb27edc73cca8f70300bc4f9e0815bfabb3626cd990eedda6a4020db6c57ac92025f0fdeadababe180b1f0a53623cfe66807346699ea30d1500447d77793fd33818568124b696df176c2618bbfa066003236464189fa56e73c376bf44e75ec02cc7d5b2ed2d0e9621080318ac014509f26d4a2794bf27db2ba9df6bdbc75ce7ecffc2d793ef47cb5224c70211fe8e6de811b7c6b57e32677fa901d965223a6c63b6f81d6cf4a94d28e8e5a40216c7739858243d19851e383ec7dc0d82ff6c14b9ce6a3d148ef261d27e08c2e603002ea5e1705287a8e879f4035ea472c6b4c69324f29b31deb547d173b5a7835403198a8625705d2626d1f5af905a4539efceced4341f4ae5d0debfb7d62c65e86287e35fe0bbf643e9b7bf141666d81f5c02f97f05bc3ba06810d465e94dadc1c3afa3285a2fba373a7fcb86e8b3709b230fe17fd0df4aeb0c564f3ca9f0619ce31d8ca60d57e3989d81d4990f6379ae6dc092e2602703b44a38d819ef427d3b44787fc6b239ce5fc80f8bb9aac3a6aa52a682081a621d3a49824849771c55fc15b463e864a892afa75ceb1388b81f1e941ae87135ea1059a6c99417aa667ddcf82806c83d2d89c9c3ea8c233be667e92ac1b6daa2886a31c874ab75f34f86282256047baf8281090bd1f43194e69c07555ff7bfe5246ca73429219ed8d99dbd6c3df5c0168cfb9af9cc213bd45b37171a897c6aad2cbd8a349429743e7ce1a49816d44dba1c847f071343c164cf8648e9f266e3f0259bb117338647c6f27862e44baa741ee59de68729b8c06f65efa662949266cc26fab90b714c3d3c61c5770065fe0b94ee47285ca6670c419105adce7f2d03492257d59cbf1f98ee502dceb274ad43ca8f37fd64b221e35901d24bf55db002a9093bf9a28c5ef0be2d7e8f0024a456221a0b86a0062c22eea54691f1e440e48f555f3e9b8979daeb17d2f6b75fc791e493a9664ef452759d8e87c6e24339f9b8a3d74fa8995b6aacbd0def385725946515a78ab6a53a9a9f49408f4ba24589fa42835e712d7043522537c7572e6613ea0d3e9c7a6671f40957e32cceda5e38cde42701bde4e4a1e4f7d88533d07d5592a4fbdb85725c830307007ebe5ec8579415f5c8c613a5efcc8e20d83f991a9952a9a97ecf0220de067a1e5ac382505d025d8a1304bc0e556b0683ca8204f86ec57d56a6dae13dec5f5c72bf6b4e1cb5cbc317af9d157ea57305ad7df9d2c44f0e2d1e99109e78ba39bab9234a7a1b1447718424d3c869230b5fea2202deff2d140aefd08b9b0f5cc1dbc197ea312f2533ecd29486a1c975a2a2828443687c94a7c19c702ac16f6a6d07f8ff9f62f0b8b4641b9f18b8e87f59dfaf232e305527367ee0d4b369f2fbaccfe8146c6057d4469fb81ec7064475531305f03d4b737c19ee037c0990f61c744751a2cf3c97ec73c4a71b44690d7dca9a0db461c64010a2ac6f41b71c3ee36e2f32bd6c21921ffac3e55ebcfb41f0829c99a3d97676fadc926ba84098e564cf2af7a30c775a2b1f022520b5cd60740d099c53129acb94a59fd15dde8341211ddd8f7d6b58bbb0fe2ed4f6c9cedda38d86a6b7ba1d0f736cc337e838502b2ee4115d566008193b894dc0a5e30d3aab525980b1d92451133849bc5760ed4759f90f1515c0db486abf8ad45d1b5dd4e34d621a3fbc091190599ae1c95d3019b21bbd659af35bb3617f223655ba34ebf41e8878fe1a969d0e7fa4928fa21feb28f002446f06a502e827a6360e3e53f9002f2ff8faf07d9f87a6cf2d06aaefcf36be306a911adcf8affa6bbc3e91f1bf3c3741674151ab9cc9fab26a25bb489c5f0c033ec8050834308e4329fb3ebf48479c508634f401844cdaef5e08f299946bbc4bf63b13898ff9d44551d222cfec0d52ec0ae81cef4e5eec22dbca13d5d48807d1833dbedf39e9c03e0e2c870ce3fd4128c1cb467ca8fdfdf1100b018bd18e8e4b4e4d41b857b775f89285c247f356507a0a5f6906773e8d26ba2544686a07d157d29d63489c6e5913f6e33f583f2ef911c9980a4f1b9566487350340a2e968058c834c0ecd68ee844050000000000000000000000004026676682bfd78494d5513fe415b480c9d529daa8bb73472bcc53872a6c34a6032cb2fd9a97bca9ef4006c2b030cbc6b59151c46c1240983f309a596704c2f7cbbfc39336c35fbc95261bbb7b52aa54dc26ac76cf7b3ff2ad4f22e63a9d5f63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aca253a9afcdbac5dc2e9bb91f0acc485fc8b25152aa7b0b09a42c790ede59a58524b6d07c0e171821e287f1c007078f671d0ec96e3bdc98759465b7d8b67cc1d4f747336d97f517b1491b0e196f804bf601fc26a2faa83c41bc85bac9704a52729205e03f8f15366cf8674cadefc9b003c885b66c994948a653fad3d66dc39020fe987f1dc302e0869e701c6ec747549ac32b9651ce51a38ad0f549d682c7b110317d23abf8bae69852b9651eae5e00507fcc53d733e51945689bc459fba13bfff0b0ce29885568f2738b8e14e6e12266f2319699c8b0155d2be1c3f83a5649b47f404e14896bf43f29165f01572b6285bb7103337a461578ed7f3b7fd77359a4720020635f074fefbbdb2cd8aa8cf8a211c0284d546932f0ce81bbfd530afb5effbdc031120b320f4148938154f4ad53f35a6989928b655efeb8b3028584c939c465f95030f200bf41da91a73f9b336e8b468f5f2e0f3c7ce63c6491104004a4250eb85c80312c28deef9163aa2d6e87e94d5588d3713ff7f042f8480ee17d686132aa86a2a03276d0461e06018b951f052bfd52da80217152de35b73835fac60c47ea306e77e14c456b8324708c81a337a5bb54a758f58d9088d057b50c02c00e185c700234df92a80964fc8b6f54f2806622237f8d16bc00dba9ba5edf91aebc808a003418ea1f34c57424db1d0e579fcb491df81c295f6c6b67397c0d99c0e991e95f3d0f26a8ee7edb45ba3e1d686dec5d572bb411f043d0edc072978a9df643b392dea62a0c3598fd8223eccc1564bef3c38bd82db43f27002a7b92c0af0912e6781d0fbe40760ae0c11b6340a52967d09b0b4a0c19a62536f76e41e17a6cab3f4abefc51ef41dd337df10298e0eed80594fc8c191f167d5a01a53a9ce9687d5dc8f11994557e978cffa07a3ec62e22ce4be99930114c1f5334fa011d2e83dab0b53fdab145a6acae1553fda4755380133e367d93a49e10eef8541f8f9fbb8df8c887ff87f4921859fa2f532fa339f8e11245cc3fdec6a2498a99fc6c43e73669ff7edcb38b404d8ee3552f82dc685b26c985c99c5d1d668b765c8c2210f6ab27b84b504d8a59a730f32f83a0a36d0bc1204dbf93da22762dd4fbfc75e6e56c2b96b8ce8b0a47cc8ddee310e40ad53d4a29451718813d20a4fc84ea84b80dc3a31adb89b247e905215bda5fb2d114213b09fde3933968fffe8a065d2ff7aab0de54cd1e2f518b3f0c0946960f1debf1e6972f1b8ba56e8bc5e765ec7a670db6f485e30bdccb3a53fbb5d0d037e9653f3b34c13181753027f94f39087b834a6cf75525f28a373f57c1df9d1624fd6da4fab3800ddebf05136f7a380f6952c8e6ed8a85ed7d9a18f19deaa872d260c0fb4669a23210aa7d34b88183c2d4e07488030185ee20ca99dccefd25868f9ff9e654d540b798ac909124f3e6b437d29be08b883a5500fa541bd8bddff13029a1189e34117956045e73261117cf02361cb855af7c7f5818c11d128943509ba501218f1a57fa590a4fdf31e93e650e2f455c50097cfa224207ce1837235234b400028b3cc7e848e17c889e099df0124473ae4d00acc027513a15954ff0b618a75f3f94572dda4eedcce4ba2e4552d0b727651ee06e087aaf1766044ccd82a39431f13af51f3dfafc341c0007f6e8666950557a1cd36d1762a438d37af45addb36fb8f851c3e3cd34ccbf21cb831da1a8124e6d81962178cccdbd3e720035293c2b2366ec0a7de334cbaeffc7b244fb50c7ca3e2d37ceeddd9144a7b295a013cbf0c1530dfd2362191b76eafc859ffc493dff0a150e9553b09a0b05df79611fab87326ea6f4f61338e941c177266f481627287933d861cc4ddca8b45d87bf702416e6f823e158dfb10bae152bc7ed1b9d6712f2cf20c46c4af4a62a739477958a0a3bb145257b6c9c768762046a6ad87e3b66187dd208e9da9aa25b5ff6656efc52708db0d0450ae0b2f1f14010be49f5a572f42b6b7de1c31c0025fe1abeb61ea7cf524c67b1dae24b6784416356f92b9b476f7031fbf8a4542c5e7807bf26310979e3b1b9149a304633160d8107598db08edf91b2295114c0e1ad92c6c6a5591fbbb40b10fd597ba5c0c55096f786e5b6a9183a78f52d6892b72803768a251b97aec7d04073fa93da6ba22630322d50af0bdc9c526646bdb485ef4473b822cded1f4c3e6d7442f342ae1f5b1508c9fde55c08bed22d4b15cc102674f5d1f7cd629e5205aa38734ab0eff553b5968630ecc5167360a590e8be2ac0f739b19445faff82b01e931be1f2c09ba87c17f4954de1df498feea6c829276748fe95268abff14c19e6ef9cc57dd960010af3c8c57674c73b8888ca4cfb40361b8cda758d3377143def8252942d4f6926566c778d71efbabdf6463a831740c0b82e083e6c23bf3c66a31a39308", "ac0052ac", 0, 107574252, "44cd030ea0b398afe12e7e709ece0e93e14045ce1dd715a9c8a19870a152edc3"], - ["82b8f44101da90f7080c7767b6238427917eb58b7d86ffd5380eae5cbe0044fe194bb816e3000000000500ab530065ffffffff022e2cb102000000000953ab65656a00ab635164d3ed0200000000056a52526351b75bf805033f2e3f01000000000000000000000000724be09c4cdb92bd4e494cc5d65120dfce62b608473dc91fd6b97fd82531cc08f30917e475ded1ea55e3a9aa1523b918d170bd9dcca7117cf112dc61f4c0c24c91186ba7ed2eb056b6aad78773ec40327058d763f92f29d96f20d0f8200e32a40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054a916d3b79c1fd63b9264c4864cf61a744239e9ce8e5cd8a8db76844e6cdb549f49b299383985803ddcb9e92bfb38679b3d579744e06d83865e058f8a8f0ac6e4468bde8a8274c441fd553c0c712da8ca8e1b0bb5ef04194d65adb2ac40281bf2076b97f4675c31790992ec5fd1203241cce6399c6f2be7638717b24d166ade031f69cdc897e543b26dbfa19c8dea80c65bf4913160285128e9ad0a6fafd14682021099785a8cd6e8ccd90c534b4500039c74bb36dbb50d24a3897269be30a362770b2c2da6baedd2f307dddbd3b321b9fc08fc50b85042c6ef1bc54c4dfd251a9c0825347a16308b554b85798a6baea5c0a5a0fbfaaab2881077953670021225b91403036a66de053cb953995cc389266c8a0bb226507543552a8d6b777315179759f3022ae345dc7fd13c881ff482e2a70f39676ee69649fdd5a6c4d11debbb48d2017a022544d415273607b6b84c209720c2c297007029971eab04589de2e50ed3adb9f20205163e138d09faa055c3a39b1a87fea1eedc84cd4b953f1744c3133ebf8a775d0304ba8e37861407f6f673f674b872a1b9202eba778035e725c917f4efab688616799cd77519b65ac863cb553ac297e1f8f701aebddc6918771add15acd328e237d6990ca0b5ad54561677e6d614f3c63307f918d0a071c83f613d58ea5a939d49891764c9013e7a8817baeb1cce3ef79f35290a9361cd47eedb905acd7ea011ae358441333f3ed5d10c8dd10d566a8d01f0f68947a54dd74e1a555000bb3e0f2db5ddd08deba47441759162c66455a24e22c59475a6861d50440185d233945b02a57413204fdf9c267fcb65ad5a94d771a893afd56c8c061e80f81e3acf00b560d87f769f67dcdc3225288cb6b605bfa93b37e8336964d402bd5982415a154176407b8e7b46f1f98e55abc4e9e0eff38ad7be4334693dd5ef96209cf91660e17be7bad5f8098da88dfb0c4045e74e094c30c8351b6d07a95f149bddd07f6b3c975155fd7ef2b627559c2dee286a7bb38cdb363522ae1cb4539d0291cab4c4be1cf6f0edcdc49f33905e1c5621cd4a81a82719e8e3e4867c5be1d932d3fe1cbfbb5d993b1d9da27b8f77227d5858dde217ef768fa0f1c05d7de314b24af7d66a319d5c8f260352ca0b58a8c0a14a136c5b99032b6994660bfaf271b3efb355c162707cd237b8f5a601eceaa493c03d9f8684bfdf04ba331225d341d86abd356cc6835a8f614a7c8dd93e5c69f1de8ba3cf04de16fabd6e5eedb9aea3236093376e75e5a1b20dc660bac661a41bfa33dc6a2e89437a15b9ba147c60122a7a1ded8d42ac38e4bb34cefd353fefacb6c911656e06e5c9e85898945cfd03542c1a537a75fd06a7ae40fd4831f6048972d745aed8c88f46393ab0e6c9da108942964b89bcc50d731bd02bd4f390ac35fe0501e89f86ca1ca79b849e611eec80cdebb67d24408e7f217e495d82981cb873bdc71187792423462b4e48858c0cf8e989eaa6df83981a744d979baa1d9b6fcb5fe4eab9386e8d65604036c64da39edee127e85be30b98ef731287f5ce955d6a234d49da6280113052ff455b1a59f0ce83a45403a4f92829fd8031f596a5347e8035ef52ebe28361c28f40948938ab9ee55f225f07c980737a0afc912e77a01a94f46babc19162e1ef3a52de94d0170a578f9f1d75b8f141a75100f07752b1f7d47a8f9828f7750e6a4bfaac9842164110a64c742f2c226715c7e51fb2e06f9729a6be160dd7d5cb9a2daa6cff94bd00e44f08d69786cce6b8cd88caac39e0c8ec629d866495662fe7b9078e3ea0bdc1a3c79fa292f5092ad0cc88101ceb5a329c068d0149d953ca4e95b340f607c5d35d86dfcc7b5a52364d6c3f6ca64f316e33eee945781cfc69effdc6f4fdb03c3babd90994c4fca93f0a07661ace346dd3ff21fdbccb726f42c85bb0fcf8690f0265c927295890637977770249c7b49b84ddacb0e51e8e83cc25145c8571bc38f817e264919e6a06e8d670668ee0dbf9200ce68cf48e2c79cad2de11fae98884484888e2be877a11b1bffeb6c03ecd0d0de2e789044e8c606f6c6a29d295da9e0a2595fd2008acc47fc66ff3e71a0bad89fa640f7692fd01cc372a10b0c1ed01cc1e80ec92c895ff03dc252f7acca5d029a1db31a5dd325a59a9a1482e91c09f43eb711832d585096b46ebf27c25fc3d1305cc77ae94f2e7935d3dcc34e4584307108d8548414bcd9c87e14f8e8bde1226042efe407c264f63828e54c72a20a1edffae22724ecb55375e76a917e8c6d86ad44c8cab53678eae040000000000000000000000000d00bb62667a002cb61cd0fde3c6dee524c7e4fd7b526856ce8342e88b45735bd5fbfc6dc9e036accca287b3fc41a16485e8460f3ea183826196bdb45f68babbce0cea5775f4dd25fbb82ced95745915b7972ffd83c2ee22235a9a8a176481b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e4b7af4ef33c819679b560eaeaa7825293859076ed47d82b6c28a7b69701fe36cafbe61c80c9480dda94cd10145985915c78e0b13a1d7a023bb426327f707eabe1ed4dc9352f0d041e02dcbff217af210ae7992a6522663dfc02067b2ae04826d573e28705a6b6a8097a77ea5beb74e8533875cf738a62c755b186ba26e979b021d6d7f56662cf581cfd2c296784ee88c2c14521acdebedb0c04a91a21219490d03115e78271b5c03d9802edc055abbbe9c744c94bd10118e04c228e0384d9f6e250a1cfda6ae6861523529e193d4e738c48731d97f92f33fb056111595c4c582e48d1c1780a39777720a6125e4a4f635bbb39f9291d704953665edc36e096ddcb2b1030f867681bfe57e6d64f139e80750e40e1c405025fe3442d754cedd2b7b9b595e0213da9b831f0ebe9d5ec7da25f057e00c9caf8fd2d75c8f50cddff84b0189ee25030aca94571336a048b91250b0f6514618cfbd2a1011673ee94cb7bc8aacdbe8f9030089be8504d09c4f6f13e95444eb9ee39fa88b03022b0b8f8855d1d70f6337fb0307c72e692bdd5a0b24c9173611acc7a8bedb6256bb8a7e040ccc452e3e228cd1e9842c797b2058bff2b656ed7d8434ea18e4bd07160b7e7f9c63111d4d6fc3aa55733e22e589125a129c04c78aad7c84d76f32d72d3ba2ac1f479b74ceba8be4384306b886359adeab9258938214bb439a6fd2a196f1cdcc737e79111acca47da60eafaa73e5777a798f66b5f52fd9161fa061735eb391290e50f7d00970df1d20d1818fc97d99f877b81f7d0419bec687c08a7b1155c93a96a1c720ba9136aba523bf61acde31d99895074f247f1168af8d9d9de55e909e1a1eff1f8fbda24a7f097dea701ba02ecb6a3629b28f15a731c62cda6d7edbe0e3b7e6b57d431eb60968a1491eb3574a3d81080bc2c315ed2d1aba04657cf590b6721c280948962cdfcd2189190648429bdc9ef31cdfb36e2b4b3981f5ddea620412abb1cc52eec1d31c5ca31e1ea2b236c6310af01ae5cfd11981ad6e3be3c45d96955acb15d7f95f4fb98d8d5b55d8da8a4d25c57a3b699637bb1edd12c36dbc73c9af72819d8ada0ebfd222b8b1bd99c1c36fc3ef994b389a5b6eadce9a83cbe48d12fd9249acff9cfce4970371cc534553c342b415ba2ca80156da9f195e1e963a007e377be989257bb7c8fb55bd6fbeb54094fcc565ae74eab4bf5880210e4286d98974ed439439a50165bb38f5d8884c7f80da209df20e6fadc927219774301490207baf9fe1bbb12bc4f00997539ef8880b808eca31a82efad8d5af990fccf05712616ecd763a46cc5795c71ba989963ffc43d60e20f07cbbcaa693ed35bf227b3c81770beac95e22bdf3bd04e723d230a3a1a763b5ec27e036d37aef61aa42470cf338810193e42ff5110093b1bc4a26cad07006757759ea3deaf1cfa064b7a5fb9e6c402b469c0408f80f51db952e22b50c52b4ab186ef76aa2e60a93da85e1aa2b9b4ad8262a32232d33f2bf1a459a72d298450746a724b0fa15fc555dafe6f58469663126f36bc7302e63b941ac33a2adc415b244ee98c0438f8e2d440f55a4b1529880677f1cb4e2a1b823d6e859daff89b0d274ab3cb7472d1143cae0b471fd1b1c5c01ab824e0594f91968de421b2c666a904e4cd676aac4d22baf503af8883b5fe6b1034f892e3032e9c20a38a03bb677b5c0ff9c5610e4163e2612076e2bca3e016b4df2f3be5e9eefd499a7ffad01fff939c56b5c6cbe7bb20e68ff1aba69c71b8ce38185f876e573546149cde481aef73ea6fe75dbb165931e21a49c2217b21146598a5c306913e7ab6cb82954adca71064828f042ec77ef3405261a376c1993278288c49fe50ffb9ebdbe0aefbeed7b52d0b2e6f442b5bc6ac65bf706daa8cd94a01da5d6dedc106eccb1ef32032bccf52bb291b7ba80b9f6f13093ed5b73057ef678aba8ef861f4203baec68e8d698aea88847efb15fd485bdcc96317cd66822aa075aae1ffda83cabf554daeefcb1f093823d7ba3866b723d18ce3b564618fc318d63c8b02fd016d2478cb1c91ec598bf22a396faad0546be55935ed1422bfbf9725bfefde535a0809b12d923f7c269bb1a7638ecd965ca205d5189752687a6d5e04de91528f673f95265a532a5133bdd585366c1c14146910cdf40044a6d80946d6739c16f96ebf59dc8f02d980962720d67ea100ee601de69f5cbad94ef3bf00d7489c202c3f050a2ec398da3ecf4ce0ab18e75ad1eda1ba2f0e14cda72e5bd8ea02b0648c90c78691715b646889b00000000000000005072870300000000fe8b82a1fb0ae1435d83e17e77105d2b2b6cbbf3a20d2e4add5c4b477b09da7e997466c0359f414fd7b462e1217f36899e82f9124f6e9000bf83a641b53a03257d28f7d650d19c024af4e6106d801f8a7295bc7ee7aac33e28cfd79424d955f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a01d7d614e4b01729430456d4d07007c9af47df247b71e18bb1646a7690ae17a1d052c13201ffaafe362fd9657996e4283393047d218187022830c79d9fe79287eaed55e7bab619981ea857947f5027e640980f818d4d8a1fa77d5af5f0d102a7704ffbe18e20aa2ce1dd8256081709efbabe7176736fd7cfe661cf89861cde0201b18cc330d4cc869320604c4800beea2ac9cc6b7bca593832118c2e2c4af465031fd8a1fa7d9d411bf2a7092441ee24f60b136a77edb972745131a48a5360e8bc0a169dc19450582a816271c87c378d05b5599fbba323aab1dd5a4796c71a55aa3614d721113d3f82e28b472a0a155c73f75c34898027cdb8e9ba150a3a9804de8f02254d11ec9e778a6c1272c4a42a02b7e6a0744504a2d0487fa75062893632bcf60318371b85cd7fa59b2e79af7efaaa26634dae94102a5209d566230c8d4e0bd6c4022a187d0e779920dc86426fb45decb58cc8a1a2ac70a1e2dd3f33175110b9c797032551189ea71f515d9f157c97e489dec9fdd1057ca7036cdca90b5303953a3aa90211d66f615bfe36a784e241bdb834b395672cc9664ce2dcd15e1b5492ef5384b2b1040af81d4e15b7b82fba6a96eb6e82e73a4a9b3154a28e1c1862919b990c10a017be6ff91177572a5b10025e47a819e051bdd7713e656b794bab7d34e254b2003897f39b23c9dd62a0469087dd324b71c016302a349e85f27ddc190dd984267717d22c2f53cb1ffac17176d5fe454c0a7fe485e2cca5f0c9d285e4ecb9cb6b7177b9e43d5d4df178f61dfd05f5da3201d05847e69965d9fbec2be34468d2fdddb52c5b2b1b4d91dd5890cbd6099a686931bae577292f37f82d455aa1341b5e6d36169a5a1283abdb00c46a120ed056c4110db1f1de8369d3f3add7cbe85f7760182723d7307604a48361e18d5b494ef9d0f939a0dfef4e8f21b145e9c30bbf829303034b40a3c18327a5794754a158c065568a909211ab4e13a64d6f1999d39448cb396d7b100edd0edb1b14cd4afaaf2fdee78b476d5b57d7ab9721b0aa454b791b990374851c5fd6d9d23eea2d545d7eb8b7356ef47d370ae753bc9ba4f9be277c4bbd84c252571343ec50fb11fe29536188055e9a3e7d996c3bd31f8603f438df2cfee4588baf79af4e9971f6a308213550f1710477ff16a7c2f9db26ccdc46568c96c201eae9f2d9d15fcf29cc8f964793bc10c2afffdf84182bb2d566e2af596ee9d149f7e351e1a875b57fce7ee780d4dbd8374052b0929e09c573968adf4d030c15023a4420b41042258c2f34e6e6a4cac97a630182861dff375e2a70a0e138fe9c03fbdd18df7ea774e85c7025343a69776968eb731f8cb2e52a9bef32a3599506076f8d5364f1162a15c5138fa14df5da541ffd6f556f967175e261e50d11ff82c2f205d5ed73a136b8c5e54774824cc93eb231de4fe0ae3d322c78ba47c48e87d3cbd0265e5a4788f41001181b3550eddbfe0f27fce664c6f6975fca9dc8fdb7c8bd312a1887be3d97ea2a8bdc8078cf12eb50c7d2814b521168861ded1703f4ebda6458f56c47ca9fb9d721e9f08153ed4431dc945540e445d281b8085b1da9cdb40c624550f596e70fbe74067d8b18436b23f26859ff0d2e38d310bb4619a4544d9e28b268d2366d98f1c282a66fd7cc680bc2a426e2a4fa1ab6f35f934238412ed7b9d46248c95e7628b3b4ce282077bf99c7fb6e3bfd7320e866c9cb37d2226a91c87ac3f84fc3b47b6cd8fff5a44231a36885770b3e4a926924f670b74aa723913aafbda305825eb86c213399f50d3371751f02296088075cbefc9110b7c07dde7ad1a6b78e622835271dc78cc3217be84fcd4a108af5871cc2b7d91bfbdbee12a254c241a9e4203a2494a11907705da9ab33cc5a78e88cdaf33eac188f8df9a45df5fec4143db19bbe77da5f9a0206d648da69307b1c56ad2a119f0245cb84e300af1adf36a3c88f5b9f03f6b8631a1585fc0e7768a6faa490961c1c4b8f1de6a296de97f52f43f7b7f2d060d1e4807a8de27dbbed473839e7aa0c8611fd2362b647a4b050acf04a13e1476af0241624ae74a997b1c49cc7a136025e9d3bf6f6cd8590ee08d99948b2dfd22709546ee679e41e7309c71c58b9e9a1be13daf56f96b837d2c2286851919cbd3944ad00960cd721daad9c25bcf43fbe749e770f8ed734d33ff34cdea1a3cb9965658a9bde4ee684a8551537f138d672e41f60e47be959d9ac20dfbb17993a491bb339f45c7573cedcc1c3c9f70084b0832ef6d7f35cacacb17ac4e2c7735219050611a4860779736135ffab2b8c0e925a28a68244081abe9abdec702d7444bf85ee430ec7c954d54085f1bfa2dd7ae64830731a650b4362076a5c28ec559ce3159403f1ec993209dedd0faa915556a84f3e6a78e87637edb1c68edbcd00", "ac656300635365", 0, 2062427382, "9fbf4d6cc85d27736a3ed295008c2bd2a0ac3526251b866e074aa4330f19fe71"], - ["897afa3202d395fc3e5777a38fed5a2ea36ab53ffb0ec25cca8f58ed23440d1791d53230fc0300000008635152ac00515253a0898f9217fa68db9b150a3ceee7ff97fdcb9264ee136e76988f22fac841d192aa1b91af0000000006ac6552acab52ffffffff02ffbcde02000000000163f3a33400000000000000000000010000000000000000d095960100000000ee41d784990f73dbaa548929269756b252e3df85d52098495fa0431525087a020a7bcddb962cd9247fa75f2dcb5d9fb633715d1c3c01ac0715114dd7ff755f71190f398b55582d49ae992dd09e93597f9e318396ad40471d0e9dc524f472408600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc41cf1799399b0ecb79477f344f998fc4d52a955cbf91fc0d384e27f39abdde3c04bd6db0315a20f316e76116b0f55c9795036a1c9e7055e12e9e1c27d49ffbd9545c84e19a9441ccc2689ba7387e272e911fb9b9fff8cbb416b71d62922bf57746a1e00598c30cbe1028e7b21b5d749f2676f401473d8b05b1807ca4a41a95020c9e9aeebc9a3a2a63c457dbfcfcfa51bd3dee0b4d24c8625b14fbd882e95df8021f9c8913cb5a511515422949b897fcdb6c5813ddf51315e3e2c5a41c3e3c86fa0b26bc645c4b27eb1a8e3b7074a5de810fb029a7dada18a7d8c49ae4579d4064ad119278cba753bc8df82060e67a54ed7494d916b6fd6556034aa4037b02a96245031248e36f0865b0935dcc0eba7f81cf1bd6eeb75f0f517996e1f4b281a328e38b0226c69db42e07ed7fe44e0fd8f44ea07bcd0a0810f0fec9db78a0509edcd19f560205b8aadad25c1976be265c698918cf157137cf9d7c8551de21ca6301a52e7de202291e16062f93928213aaaf3215b9a9b63700eaaefa4b33dc9b25b49b19d632b8031b4ec7467a39bec293d0dacdab832d16a055cd94de5d761052224e2b900b3caa8bd363166e82de396e3b2e8f18832b591f4f4eb751daa913681b23a980ba1ee43a8baae540f97502c1f2576412c383bd7a79af4fcb0386f6fb0b47d0f04126e3801acbd30a88df65074732ffc77a07d7077134697789a0c043bd3aa7f877d1529297fc269740a5459ae0b103357bf0cb409697027e89150eb3b1d6ab61293eacabe67ecadd700fc6617219cc9df797a55d51d31b54a6c2d5955cb54f5fd28b300b3f049f95d7001f3be197a1437995986e840d0c1f4a71725ba1531a350ba5142b9049efb98fdac264de2643bc5ead18ae14507409628dadadce3c6a66457c59dad3beb3c6354161e2739929ba84f5a160740b8a16b3b3819f9d6fa26217b121b5974cd6bcee41918b2bcb1b10858856dc31182c5310cde8a4044864a636151cd435b08a3e61b49a18813f55392e03cd744cf4c67efc9f97d350b70b850c3ecbdbfd135c64049cba4ab8db8d9da72e9d5c07126b7aa4f2dfdf470d621bd94735223d41500ea8409139c9ffffee933bb15ff49c8f009b29aea83b9d86d0fb57841bd26b82866b7a6e7a4fe400487711f19fedb16aa59b346b780266767639a906d9792028a6b0cd9cf9c91be1eac6c8d99b80a611fd983f8e420acb9efed271e830dc6bdbb60d8b74c2125b73b492c694af496d38dcffbe6395fd50b208b0a4e7771aace630e6c82b156100097fc87d1a3a1fe739ef3a60ea48b1827b5de9ab8fa0464988c4398084d1ee5b426118f5cf8a7ce26034510fc905aa48794ac16bad73309391a50b3b4b66307f2f36a87a96e1a024d69b5e16a90da67023faf33e1daa3859e38a81e6cbd642d6939866f8f82a068f3ea407cf7d03376e14e3e539a30b3c155dd08e43e7e6d1ac82ca7dd5bf46f2818dde6d43a6f00576e25fd006d042481b57eb569def219d0c55c8f3e0c6ba23a9eaf5ce9a1008b06026e57a8529e56bc536d852739bf23153c5c55535e0cf7b30fcff40818a31b61bee6f7f72f390e9a2eb6a338d9d3305a88925b0766d66a707a533f1a550426a9a749c06322aeca698e861b63b68766279ade8488f8dcf87104426454cde486de2f4c33be4ac9718b41c8593148a2b127527487a919f21625eb37a41440506ae691f2e69281210f74e6d992e9e1f662a60c88b859ddb137767441eeee7245be30ee2bc12e9130b1847790d8e2c0bc7309a3ad02b365638779c283f641fbf23159f92de82b8137ac3103cba61a1841c345b06cd324c38e6b11d55f89c2e072b062adb91db35efe4bf01ee41cac22afbd2ebef77bca91a406ace35c693efc6b08ae7b8315466de6decae705a55b6c3ef03a356e57238d714e3177702cd5fe45ddf61d72229909ea6a363a3355cc10f290ba53f2f7ceb1ac71d0bc5abb0232685ab6c6a688a971be2a2a2e5b41467f8b2ccda1fd1c506dff75e31b73bcfc78997959097a148f826022147797c32db852527fd9106a7dd3a621d5d5cd7686b9d23f01b7dd750e8532ef3f21d4766602c12bd56164460e6405ff426a58e60845a0b9a7e32a53e0bdde67da3723f8804f256494e750e4ac29deb32cb2ead83fe81abff8532ee3f7c3c441aaabc4b325773cb4b4b3b59ecbf76f5f33b5a00a102250bf44cf67c492ddc0f38007183f1282ba1f812669c7481c09fa4ed7fd6444c9c8f21b1d6586b0fa999ed1463f577c2d35585e233451f6e1bc658e7cc15dabd9360a9cba3d641e6ce296a58d70770bc2db17d8d8b1394c28942b3b33c401a9e7502f2a41a24a09313d73bfef46c77e1b7a22199e29e24c41b3e789c4b0ec0cb7567e54376272fb981f4e46b3fc2249333915ded4e612ef4cee60c", "5352ac53", 0, 189443197, "c77c8f76f34597ba7339847c389f79e05c3cb6ca3d96929110a4f29a3cf43783"], - ["1391e5530159535a6a6a032194214f67bb93c70e68aa738276262cc4210556eac0be3d76d50300000003ac63abffffffff023917f9010000000008abab52ab6363ac002bbbd8010000000006ab65ac5100ac00000000020000000000000000947d4c0100000000804f4bec660523f2ee9377d5d3a9227bc5c0c3010f3b311433e1b4258d2ec37176380e6e46a26a5efe8a5dc99f42a8557dfa25903a4ced01cec005d5640758ecf5cef6d0c949177bedd9d5b8e8d52cbe55c2c09cb1d503cb938f150f6523ecb400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eda209429ede09e67f8fab9374d07fa4dde784012e61ad271d841f18e6b310af40e9a44ccbc77ebca3357bfe84fca49a9c8cd060cd8a6c5ce4743ef39859b44dcceae6613de0dbfe6e94c10626ee11345d8ec32858467913836e2b8bb5f43ef0e46e2fc1658c30815f6481ce39d57ddfa620c6b43f820dd011f5e73f6305a7d1022a39e218e417f2783d431011455957f315bfbaab18771d6d0bc7789d42d9bbe8031d84c0d497f647226f0fe6ae4d81348c1f2b2721a59b1a145019e06622a1a4610a1270c4757aff8836eac3836ad2b7e5bbb80ed796aad6cedeb1093bafceacb7810c11ea358f1ae2ae308a3722b46a72b375ebb59946343e8b1fbb6c8d7a6399ac02241e6c1b91ac88d845fb88f0012cf4596ceae0494cd630ad7c3917a777f91eae021b83b43cf79624dda5c6077618673de93d33f713d13c0ac6e7148eae2fdbd9400210f464089032184e74d48271e01ce1d809d8184222965a358ba58dd1871e94a70307ca646f770c5b96388db8196e8d58157a2411757dae462f8d742b4ac39f9ce40323184a26ef63847abad34ee84179561c3e4cee168e14a67e0dfd76c908b801db94f4d79c60119bd475371abaad7ad75fb2d512dcae6be06c71ce6c192bf41f20cd6ca2c4997786600953fff7a7893b60b8266060cded79e4f7b80c5a0f089d95c657738efeb9c4661bb02e0d2b8baf3524247f9cb6ec4e12742ef04d568e9905837e3db3e399b96d5f2c39cf472d01ea6df9aedde45153cdfc5e027e99cf49290a703f88de34a0316b457c21677adfba828a00e55d8f1defbd1fa6e602d2e8b511df7b87b928f49a5bd648559426aa044e8f1264422e5514abbacda808b99b4988b1a634d14daa154f9e99aed27111fe105dc9fbdf44ae99da0767bfd0ada9733e08fab9a64eeb8dd2f5ed8aeed9a93c2fbe3e3b6d330442c776271666154ffc21c57d3aa8af2a826d9ce5b9e7347b78db6081ca6990c6ce4cc877e15ea4f36e7833c4950e374c369e0d72f559b8e40bbb33c48fb7dff6dc71fcaf96f914a7bb90ea06a1440d63516dafebf6e53efdd82cbfcdaf11a4e0f451f5b247e6679ab61a6cb3bd5777c455428c80209db3ba770bace7fb79cb73ef68e30b20b46167be8030ad7120643d71e33b2e2059c1227c9e8518b0dcf1af56494ee2a0d11ccf5bb24ff0c0e7011060a41d10f70c0701896b74a4115e2d44488ec7799ad76be29afef12b27391fb30dfc2355ac3f91a98e093456be3fa9f4e1413b7d50448ba2e0c24471658dd3e6ce53df345ed1ed9c4d851d89faa4ec0693d024db5347bd8beac3a3f7243cad653a962c5b6c9991e0f89c5aecdaa12a045857149e927da259a8eb1949e0ad792b0899c24ef610979c2d9d927928951e3f5a491b2f648e9b49f782a2bed2441b71ea6708bb793edf2364168da195e44a883068738d075345d3d2d2846edafd8c846db226dfeb0febc15e6366c39dc6a438351ce803d12bd4478cc389e57178dac6908704604a5be6a49ef1707f762bf0d1aba2bcbb6110aeb232e2dd972e12eb7ed24d11f4e6198398c979a67208b6cee76ff24c889a7f02fab60f6b27540764adc1410ca088cd63c8483b6353faef4d6b51e37ab0a3821275154bdf2f6aaad5b6afa8d49a07f8e594954fa9f4b86fe783673e1ac03e1439c6d8feb1780b2fb21c9243c4f5130c173c3cb2c179655aabf169d441daf427aa1a191e3c889b8b8b0d470f3003471af6831a2d984ba4167f7df50c4b4c5e90cfd385748ff280a88e4336935b3676dfb38091c17e1a938ffc79bfb1151a443b9828f3050381de0337d995c1562a34168dcdcc61c9a4501c5459de34062812330884f23e1fab6c7bf42b05ac161d0659319e365e9c5363e48deded138ccda8b5c517106b6d60509b25fc17bd28c6f14aa62d52bb57dc0dd894fc92f22e6d3b3c4e047c47978c92220bdde8747473b09f0991d51fdfffb515eb3801239bd7e8b53a8d70c2fb43e1bd3c61f0f25c90304209a7fd070c1530cd7868a1b1542cb2beaeb8b4d5f6812e78a7b1ebea4d3e507d831200b5661ae87e44cda6fdbd0a1deb86abf1f915ad4fd8ed9419e95fa30fef11027205cfe982d9ec4ed8a1579e36527a1c20ae0796c8f3c0e087edfff6bd7b0e4b359bc3c7cb57f2b5b29b060096b49b97209502f7ed85c0c6f29ddfc1744ecc24030d30f959f532be9deba469afcb8278d6d81a541e02b3c3035cbf25b01fcf9100d94df47f31624483622b701bf53781ae92fbf9b70a06cf4e400c7e9ef11cab54c35400000000000000003474fe04000000001e30bb534d5e9b0c12a83ec827062f1da5576d1b62371b69d5090d0ffae837b3679ec4ed63e63013c7ad87e8e21125201df350e9eb9658ee8c94e2531ed06547b4e8222e05fa0bed13a9a151bda4708aadf0110438ccfc60b3fc6404ff26240b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4c52724aa0baf0821422a0c7a2377dc58995a0b12f4ad6c4636d6cc255a49e971a64fbf52c881afa5e05457adaf498dbf5402181e99344fa303af6f6d75013879fd16e6c566dd5fdc773fd123fb899366341061fd3612c2301dde913495c7546a32858ad8c4e5af95ac5e822fe7b2aaa144e721c11b21b2c1ff27831b90983c0205b0c02744112ceb4fe5a9e70d22c4a96d0bc87a6c2a50ae39d81ed3afcbe4d30220fb807bd29a63fe52eed2e5c11a9c9be9db4f51e4dc966294004d75f59ad2190a165776345ab89b243aab8e89a56d24eb8933869ba1541d5a9cacf425657ec1001e163743a39e727c7d9887900b756a73546e285bbcb69219c22bf2c3cc8127990217d1a876951eb8f1bacdafe74a0e64c8dcb402c9832f20ee7ab7d3b3b59f9192030e1efee087562398f2012a6955d7450372eb06c2e23a64bfdaadcf9f67c5ff560314422e7a90568ced913df2051300d0d917d2bbf6168392b826f3ca68776a294a0320c9cba6af48c1ec86132a7acc3a3bd81f47e936165f240120d19eb40a8618f7032f4cfdf840c641b4f8ba13d20b384678e1107ea369872c5cc61ef5e939cc443f32136927af9597aa14a673d174915ec75e14ae73620432d12d9760af27b9632967213e54e0f4b4a406b18d3fd7fe9335cbaa120355a8e36748fe29d98e56f62bfc0a8757dfd0571cab549f948952481ef287b464ce5dfe02adfa6dabaf322d0e8951b8e877d6a265c6b572c5fc4a732fadf3271b79a04c32bedae84742e373d8d8536c63734d51da2fbdf2624e6ccc425e67d5c903f7df87be204a08610266b07fe27493703fe8abca77df062629a274b89d71a4164cb70abd6ce653002f92ffbefd87ae0be47f45b746408d35c2fa62d3569ece89b487ab99a42b5d0e277844fdd839df0b9f639dffd72dbe9d2cfac156b3d99b58abd70992899d624bc508eaa13f9b42b31ba6667c755e7428f67ab4d2a852174b961881b7adbae47a6cafb5393ba7da9ae8f791187f397dc7cefd1a55e4e6bd9425933a44281f882c23f994a5c494fa97918c8e50030362886e70eae0c032b61ce4f6fb129d67256c34599fbf798d1e87fb68c16b7adbcce095c372ead324af85dd093b183b7d160cd9fe93e5d93fc400a8e6a83630415672f7d82b12a8cc84cbf68f5e05fc0802c7dcd91016541293e20710bbcbf15380e641a2d9940bc7030ec6387b1ddaad64aac3d47bdaaf40bbeb0b74544932b82f01a35d89899dc247dab720b56c486cc036f8c1c67cac65494be3530cd30d2bc490c9b9b016566d7b56044b61caad1e616c86a050fa1c7e4f65bade82973031f4eb08de63209befae479c598d5ec57f542ef84d940a9508035c635a44520fbbd8d4d8264a48a88f9aa6f8a2127cc6dba5c3dac18ee8fa4ef4d2ae4b62f9b6859171412551f81f897a13f23e8791a21ec0437ed53ce8235b3d370704b197f19d6a8175ca2644aa955ce4d017fb54d4514b9ee20a7b6cabfb56c2df939efbdac872369a87e1af472c57aa2524a50196a1cb6561a36c451e37acb0e4fe1796c24f893af350b621170f83ce81fe8f63e25661d57849f0a0655dcc12deaf1a8e9e6e40996b4b4942f8b6d130d1ed0f1e3197f08faf3481aa6979ce839dd7a095f6d31eb7f68ac1ab1d84678952d192cabe5810ecb50133e2a90a631c5e680715c2c360286c4831c236ede55cc8782367feb887426ef0b852ec3d8c2cb3baa86e91bba7d8f58c313a2f40f70beeb4d8d8f464be150b49356508fac176798c3a1470edb9e762c64a92b9dfb151431b18d826c4b63a010b70c3a24dd408443d8116d7fcc8efcae8509c9379ae2f78f507bac507051332240dfcf045dd520fcc79b9af4cb13c86384e31b31282279223306e5c76f68685c2ae723bfbc0b5f9da27ed37d3d88e227da72b673c9f508a3e98dde620498ea540be6ee91a07980f898b5ce2c16d80c6b18187db220f9492f2f62f7541c287e2709951d9209b010ca1f5be87fd737b0254b56d19c218ae35146aee108fee97293a9060159672ee1b95c5f388c5ea09f36015944f62dacfb3bc92665f0712562b2c22549925903300c2f4184e7e8f5f53bf2842526b0212c5f4f9073b529b29e4b67f29c673b508777710af6982f4e35e71486880cde2efcfe41f3d3efeb91938cc92b5c4099e75096b0cb0d666b39f2b1fe6d6e3e05534eeb32138501138d1d172d423ec4e52b7f8a2f104b9270dbddc9c6d41597d57085300b0ea0f3516da7a3026e140f4e6dccae69514149a1861023564289733bc969d56e69718929d5323623c7ae8b97950066630757a320a0a67fd780fa424afc5fa4ad19673ccf8629e0e899fa96f3fae80498e36ddf53bb1e40cbc2d7e740f2ca494d7d41476558492935e9699ca4e0d25f8c29233f5a976eafc09090d", "6553ac63", 0, -1016846359, "cc30e5b1d01b5756264f78559c4252eb9abe2695c663ee02da5928822ecc2a68"], - ["0a33374a01adb1d24f422b83575818ddf34afc5b75b0170cf976f870c4705bc0df2f5812920200000004006a53acffffffff04b82c9003000000000252525eac890100000000001283e200000000000152ad6690030000000007526a65abab516a0000000001a4a8c204000000000000000000000000c35bf3894cdde5b7c1f26ea0cba11bd16dd6b0f1989a847cfc4dd204e2f218fbfcfc49fe5711475e970290c3a7c1fa90d5d26543934fcecbfe98cb033709d072c0b25a2de4d25bc6f8f34c48f87a559aa50eb09159d912503c887c566a846a5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ebd2e729056dce034482adaef351f1298e5f2247b5e253ea77946c1e7af678abdc64f9b92a94952355938f17781f964587eed64cd126ef0583d0cee3315e237544ca57677e3acfc1a11621c3f76bb3e61c03ba15c7d0ef3f611e5570b564a37770a6749e290abdd85ad9d0c714165581ac994b5c3af83d9dd253eb5664baed1030c5e4d9aa0f8c8e4e7b48e059b60244a395716e56cba7d2c3adea90ff9ad71fe031d23a7f8e70beb8c85e10aca0da72c696490ef1030e17a640c5e3b8ff53d75ea0a179f6742360163fb63003712001ee27399cb9342547adf78ebfad9a2081cc6592e0ac07f3d7a98e4b69326b00d17dd72bf1e4c5ce2c3ec2ae28601eeb43d3806031372186a4cc1b6b9d3bfaac0b33810e4b1ec1c4f6d0736c5f44c29e9f049685903145de7406f7718b2ab3265d1cd75f244acfc10d9786091136b6882874a8c09ee0214142ae42048d3f0f43df0dc2ea7a1a405066e9b60acc46330608cb4c07cfbcb022e5d237646774f6136bf30266285fcac485c14d7057516aa9e9fe82c2e5f2927021fd61c11ad28fc871a897dcea6cad291a0d8eb33df1b6f3276669ae5edfec80c66c6c97dd13b65dede61b66679f4cd677e824aeefd653832946f26ef2f74b358ed0425ce4030cef39fd9ee800f373b96b96cc8cec57d348c5890a2ab8fcbcfcd7d94315734a0d8ad8ce8a8ca6bda00f53db7751ae575f8f682b42b85bffb02060c4315026327953d6a82edb512b2205e89c3eaa0d641529a7fde6b8d732f2cba2e51c43ee7e417bb1c38fe3badf1889e572cd1620667894ae55c5917c89a23c2280ce8ada3242593961bebc644615def7b0d298a8993c9ddef51217c136c17d6c3b78fccfb373c385db6da2fb6ec58e0f640f0feca578d2ce75c26f6eae8daa5e83b4aa416609cff2d31cb1936dd9f042c7a8ed30fe4e60e575f766025498aff67755b17d56f35fb1cd7454eafa3e91d3f6272f0f85381647c6efd388c320498b48d3bd5959124639104a8d1019475f116080dc68e5c48db463c942ad3400bb95adabca079f77d6596eae2d56d964ced53e68c6b6a31e0ae437032988ba7e1097c5ec05a717eef5a6920fefe5c8138fafe9210e0f58852a66183e40df943a5b420340386e2b1ddef11ec1b3bf9e2a46265ef64afc24d52e25dc269e8d6ca2f00cc250dd7e8f5af488fe17bfb36c6c1ec0ab90147df4fdf700217a87b3bc1557de1e8719fd712693f4a695cda6f71ad2c4927f60f383b45e65456c424db799d96190cf7aa30e1b1d4a138b00fe88ab095099ef8ec7be0127094e404f0d2d135d1d06affa24af415b6711d3fef181877e0f0c0a1812bef9f59ffa460dbea205cedc21e7c859a332cf9f49042c8b428aa02c78e33e3f4387277af6cd19afb21d3154c66c36a564fa22aae27dafaa5c55dfbc989b0652de046cd2705a143e697df4d34a4782547f1364585d11516ba0ed8066b8b09393b5b33ddfda2a607b433bd118dc541c0c5e4460e922a2c34b5f2c1b33899dc59ee5202503d0024f7005b0fcf5c9a16db2ad447ff24297866d309428e991edc6b5fb96b1990c43df35b5b75b1fd85d48dc9be956dfd32b89956b7b2142049d641392298fc24cbcf9db257c48cba13565dc9a454bf00eeea69e47149bcac097a0356dbdf5db097c7ff2d59102dd5759f1ab1306b9b2cfce950d79d7a6f99c318c55010de3df76f90303c9f019c39687b42a85cee05f1c5420e6462d2b42fdc66fe1af968bba686c1aed4ef3da23368c26d2b6a249213737304c094605f344e0708e2f580e4042b33c576eeda0ad5aa53c4a01a77441ac3bda104c18e76166be0d33f7b727578147da07112754257303577d56a2b36e2c1fcde11ed51a35bf97a3c62cde227ac5472b13f4b7c1d88ec8ea35cf46cb415c26ba99c3f34a3ebc8ffbb7caf7fa4c51fd0f600c17021688bb562e01f1b0f7549a9dc423509e08bba239e25b5b72367b50241842f84f6fb28f5a10c2ae0a0d7d8d34c81a6a7dfd1daf7fec578e2e0ffa586904522747e650e61849784af19efd28bbfd6ba35644a02d75b19cd97362b64753361e6f72dcf3f039c2c677e941905a2d8b65e4f04ad40bc65f6fee43339adfb8b208028b5a480399e1286528eddb4b7c5868eecfc7ab2e06fa573035841a888b5d0652865b8c9cd2c199353fe86ca7d2524e97482109928e48ee2409acc0dc06d64a7308f04551ee8301388cc7a84fa63b888086ea6918c4c5c2724108a39a3d585e63430152d90f7c2a8a51479625c40da5997d235335ab5689503ae9569e3a97411bf1998cb6c5d0e08086f5186b1ba59feac3e7df227a449111c14b74e4ec54045b0f687cb2afc5fcb871f162bf6797d78982b2020f9ebd1c527de487e56093dff27422f866854bdc094edc07db75b589536b4530c", "6a00", 0, -358242065, "ce5397e8003ca2d2463ac14fb73bb584209eb9de035bb1624f81d3126a5f7a9d"], - ["b49a962504b3f04efd97e9eeca1ceee42990fb65fd9a5184ec2b1561c90a031300147b08100200000004ac6a6352ffffffff2b57800bd2ac5237522c76aa02f8216df3f6bdd21e35dafb3e3a41467052578800000000016afffffffffefb0c0521ba3b80fe3b894e08ccb32fc559753205b0d6470b66c6493b50c3580100000009ab52536565ac656365a8084cb6f7a2968c04a2fce11e8974916e09cbe1d8945c91a436c412b38e44344dd31f77000000000851abab6aacabac6affffffff02c698f8020000000004656a5365625bd100000000000163f64ea8e300", "63", 2, 1869610916, "e413d82152380a2268a27da125b9e416b55dfae7192f45860b57bf865fcea7be"], - ["7f42472a03c3641435ba5f5f902ea83ede33e571135629fd4bedb189a9fb59671b618e8fa900000000076565ab5265ac6a5c327bfd33d9daa303fbc17aa306ecd9a4b908c39df985f5bc5e3b1aaba68bf42ae277ea00000000085352515152ab52518152305df97bec17bfa2ffa86cbbfddbbf6449b5574f1715e2e559283c3b737cf3130bc00000000004536a63abffffffff03100dff0300000000020065d9d76e010000000002530018c6b3000000000008636a656a6a6a510097dd7a1b00", "65ac0000525252", 2, 2128441131, "dee489bf29b679e1d4c5b8877024ecf1c161a2027801e3f0e5a01603581046ad"], - ["4ccdacb3010c3b427a449fdad295f0a5ad5eec05acc8a555ae94416586c8023440429772530000000009acac5300ac6a65abacc26f1b73040fa22203000000000253ac0b4a670300000000025151e49b78030000000009006551515251516a6a61064c05000000000000000000", "53ac6a63ac", 0, -303626256, "a01255ee198af668547b3f0b23064d70add2685a683bd079824cdc8a6bd8b021"], - ["561a8ef7049ad310c6d702a64bdd612178d4a56b2c4bb958b05380b6aaa7fc941bf19e273c0200000003ac6a52ffffffff05b6c6112511efd1252aa060ca5cf786abff153197a13631340b6983c46e3cb40300000000ffffffffdb77a62027a58a3b1a714318675a41e1fa00637fee754ebfb956cc9069d90ddb000000000700abac510000510a2ba2308adcfbcaf3ad13ac29be03909d11743a1cdc3f77200d21df2266769ff7169368020000000165ffffffff02e3b0fe010000000002ac5177410a05000000000000000000", "00526351536353", 1, -1996700804, "e1a6ba8aa03bec5636455f2d49a78ba6306e4db88c8fe4b01a78b63339574cc0"], - ["c1237cc1042410a5e9f7426a0c5e1377ed9ab75d1d9701723091fea588e3d9f9e22634da6402000000075251526a510000fa51f3ec4ef0aa67fa778c64a8bce0bc507656f9c60f30bc9265828fc015e1630de16a21030000000300ac6af5d8dd23aad3ef7147bfb76b76e94fa74e8b7138e5b9a9954d5a6debe78a10106d008bc6020000000100cd39bb81e49eceb5a08c382847648565df6d8b4d134f5bb1bfeb2e6e09cd5a4d1835dad6020000000753520051636a65ffffffff03595abd000000000008636a51ac51006a65a1b0d40500000000086a51ac525153636ad55c780500000000056363acab5100000000", "63006a", 3, -647895388, "a838d324439cac781cc8ab9036b6f38f488a78bd1b814ed8a6fcb33db7c13f28"], - ["1501236b0198f6fcc414dd4c6ed0efa6c89b0841257bb2f81f96357657999926106a706ebe030000000451536353d4b739bb0249a24104000000000751536a51656aab88ab5901000000000853ac5300000063520000000001000000000000000000fada0500000000663915591a5ff35662e95ed4070177905fb57dbe16f74b6a5cf2d1b337797342f038024d3658c85e545b65db5fc0463be5ecfce3955e55c23063470dd972797437371589ac382aeb6ed940c95518ab3cfe31595ce90f44dbe8709a958f6829990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066ebff329536b4cd2b7d2207cd3cb512e03f5cb89b25fa0db758c2f6b55b648c50390fe3d1f910ac16abf2d5c41e8cfe104da9f81d2746b3296065a16ff1920c450e36c46f73a49140592fe19f2cbd0e5744b91dfd6d20e25d32809d6888ac713d953933093279e13db19fa1f3cfcce534a8fbbba75b7f010bb1e19ddeb36557030c6464909fa77e1efe40a86fcbe922c021f0e6d708b29ff42709c4dcc2f05c3a022f5c161158393787d7bd0d178eac90bbe02081a8dca6113e94d0d16e632b28ac0b1917416c43fe8ff15d3bd7e09613244e4f502443e4f7fa9e89682b3b4ad45f2224894cd4c37f7ed0fa8036a166cdb30a3477263fe4cee8c3f5138fb06cc127670224d905d614e35cdb383d47a732443b06ab02ec105ffd91bc548e7eb0d55d8acf02138df9981f9ddf1b23cc651fc7ad4d8cee7538b6ba637a5cd1e646ba5038393f022c3f7ee1fd4ab373660940b4bce19b4289b2c646d66441d8fea8bc93a07f855403185aca24299aa363cd9b2d2558adfd633a8008161ccfc525d5403bd08e15200a02093e683f7427ca58897d99741966a4a93ce38a33f892c447170c399c70db6d16443a32d046385c57ba49d9073384016536e60b422e6480cbd4aa8a54d1029a33112f4ac1b1bb4b66b512409ee2ed3009a732224f3510c589df717a117327a88a628ed8879d626db1320c020dc69a6999193e4bdf5993d32c5ab0698f4f63acbdc26a126c9116529ae4247e4d363006a7164f360b6c75dfc120b71163b2566baa4d9daa35074d40929590771cfc95d0a53f7cb6679e73166c8a1721c04375b292f90d7e836a42194eb50dff760263fd32fc3dd91a190abe5c273f9686cd9ee3fafad1d514db5278785ab76239ce60dddd89650ce034c2f6a1aea65e9d6adccacf02f1b3b3cf1cfd1587c670a7e985bf55b553ae1b98114f846e9d48f81dffb3178601476fc7b34e875c629ed6e8126befe3f6196cefc13f41aa5aa4f04fffdb9157e5633d4f056b67222f85ca6afac8a8d6eea448f04655b17847a1ec0eaa23fdd581f2a9780d946105782e7d5b3abea042d3084d3fdd63869c4bdd156d3788e375881d7856108742f7c84c2789df9c102844f49c1c55fb13598b2ba6c887c8cf7fcdcfc2edc2695ba5edf6b3ea9131994b9c191b573fcc6e78eaf9b77459d54e0209ccb29e865277fcf0fba3d0a120e68d6a6ce856c67d3c7ddf6dc0b7a98a72d32af688fc46b3042c17d2b6ae54d70ab20ad3f250d8f95ee0e886fd06c5d0cfa9be5ff2e3b821b4664018806ffe9d392c947ad4dbbd7dfabf90fefc3b6537a82f5e4c9cf15906f5a6bc54c78878ac4039ac087a81a5866fbcea23766a974cdaedf3c70c3cb925dd0ebfddb6cd1515c8927c9e458730c80f1d4d5ef16b1f1f9a86eef8d18bc34e0ec48e524173d80ebe3a50d664d6d8063aa937ab071792cc2c04adab63718dd3d93a09c6568c3f64db6148f618003357b578d3373132203aaae440a4673302229bdf0ea0c5a856f7cb85ad79fbcdb79df06ae81034266cb65c21502724d9961f61f875bdc984e803fa458f501e041da6630880d07fbb380a511cf418e13269346282858bf176041c378252183c910cbaee1cffc2b90c3369e00c2a5ca82417e7bc8a3236bff00c79dcb66f7bd92c486d4cd63823eaeaac8b2bbef8ac5f3e243676d77bcd7665c09ffdd29a1ae529c13aeeca426719b69c4c8ca07a5c5e9ed74005e497317336c31ada464a4f30878036208c32fd85ddc2b19d4ebead5fb049e448dcb4f3b38b367a2b0f06add70c3b0475b3b3575eae4952065f60a841b691fa6b37bb662a6dd0c9fe56fe0b6fc177b26439f9c23bf7f3cd2eb9afa80f5f9ff089132797844d0597f2efe8d316b9a6b1d00fa922b2a199b7f274da9a128c7c06df9ca87acfb28d734d617a5b9fa0437e45e2a11f60b35ef2c143edf43a29a5c27037461b119aaafa72255e242185d0f966bdd7dff3b5898eaea77bd8f69777109ef4f7f2ac7da67d6a9e5af4c477273b73b0306b641368244a4ea8ccec4a7c7d18876e5d2af7ccf7fb7e560cfc9b82f64d8077d79149d016736119b5856daef149f2b78fbd5fac180b45ea25288ba932e1e7c15428b6ac4760f20aa2096ae09ace879729b2a2f02e14644fc09643f72a25a6018fda49ab82a7734c3e2d9ff233ada6648315c0be0a8de1b80eecc7ae9a92467cd19b66c38cda28c658b12c0a972dd4e6dc3835f18df0292031a928909ecde27f55f93f598d20b8ddd9510398c369ffd164da4fe5294e091a8716aa5710ea8394ca1756d4c6771826c8887f3559b25d0932c8cb8561959bbbfdec1b7883bb92465c7d58b083f04ccc66e769369f1b2c57e18e007639e92fd5b1abb4b607b893da82342330781c51977c259438b1c2ad333335b3a1e98ce608", "5153", 0, -653046097, "60266cc5be98b13e101c62b57a3c3b699d48bf2504e84a6e1db3c1356021c5c4"], - ["eda22f6801ea227c8db6a2ffe961e88b638f7738d59af2d3825aafdcc6494f2e4b2fc7942601000000055365656565ffffffff02cca919040000000009ababab52ac6a635165cda025000000000009516a5265ab5152ab5100000000028ff0c005000000000000000000000000c803773d250e8ed48246b3717a46abf0d088ab09407502058eb700ac4706564d39650df70e74937d1eac3a6be89a90914b79bee4933d9d93c1078dc03f0f23a82f0f83e66068fadcb4262ae4e1884e1bed3673e00b2181d9f0b2d8bcb25e17a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008993ddb139eb08051d0b26f8bc2db7002abcb880595a82081decf6c68921f4bc6a66b9fcf89e190a83c2f13e7e64b43a7ca43f93f21e2f2ab2abfc6b186384f63b2a86ffbc08b07536a947502b05210490cb95ec8ae75333a4d0e468cd05d3424902e8f95271ad359413845e84e064608b13baacd9492e48c1bfc2154c7e5c8c0304e20a365f05d7b3c10417dc5ca17804dc7383b478435e12c40c69e1aeb8345903098f31fe9a933018bfad702131e7ef798396ba1f32a59f4860720ecfd9436e7c0b2c7f63367e1aabaa1130c8c8a2df6323589236c3066d0908cce076aad57ff562285c82ad71d1e1225cabbede8b2b27a3f0c7bc35b7c8aac7109052708d180e0f0217a07deefd2f46dc7c406618ad14e9e038d76f61543aa503ee385352634eb607030413facbe5ef19d1593a40ffcbd78a2f9d39a604ed5b297ead8a43eb93b5f7fe022bc71cda959e2168e93048cb7fe2d0dd03135d0c603cc835a4a8682d8d38a32e021fa63a4b677a866e3729091a4ee2196631006907dd3335c9ef2bc955f4ffba1a030838c1333b3fc8bcf614f8b2038cdb492e41e046cafb18637812d3a32d44d71daf715765047ee6552d0a61217efc1c8b1df5f98aa5073cc7681cceb4571766a84a8e7e14b1ab6026d1de69dcfb6016328ce5e47a355bcfd089151e04c80fab00ba6ef6eb6fc83c9e5aa0941a23085f2be0635495089c8d0a49674b848497b529bba58f8a42a1a107e26872bf2d714ce5e434f8c44b5e4825f57f2b4ff0b2160d873db7c945262da0c1dbbd40a88d525aa12211e26d6df4611a2072794b5ab02969025778dfdbbc777078f225681ccad8d473a2b529bf1b5ca47a1efcdc1376c7d3e07ba522db88d89ad60b477ab4374e4ea238c85df40d16304da6fe5e11d500d75cad1939ad1e6ccfbb15dec3239290ba9f3ba4b9646be33450842b8c5fbb28758f0038133bdbcfcf143c117b4b0fad474b633b497f1be2a1020b2747b3ec87e55911dc4f1b340526b6006eb25509aaf30919c3eaadea6c3b680ce77c31c68085564b047abd546f14a2ffb865eae4c52d6f199f6b08eaeeb0a2cc0308e99e1cbbc506eec3783a030b9dc7324466326e7cb70653e930f4366c5086919ad4207dc2e40f901ab9eb50806d5a5bd0d74348d4cfccdbab19f7e29afd3c73f50c0f3247f9f1a9edcd02aba59cddac1a90d7aa046deeba90c481ea9f4d882b7086af8885bb021bbae1fca89b7eaa0f6dc17517df07d2b58931a72b771ddf783009b803127aabb396311a3d977a9ce118130df77def598805e5680c6e7d3c9258d918cf534d5c6649ccbd309cd41c53ed45549db4c27f3261cc868a4406543ef9720d06818a45f8fde026271f219ecb609c962783ba732908c88db5c307c420646110b374aa3bdf53e556dbe0cc35b5e91845f79628fc756fd6b8de8ecb66883fd8f30af65aff876ebc2385ec81a0c14768ffdc7b4356cabe1723a7b18a6c1cbb4e65c256f9f6de14f2d00d6ae4239827c862d8c49d384332b79d775b602b1ac6b618006535b1ef7ef79b2b24ddd51c40115b6713a602df2d056e44da3cf75425c3e3a400c39f4721ca39fb160167a1b3fccd8413f56e3aaaaaf36b8f49a56e87a6563499109068ca7f4ddd561dcda3a14cdc7a1cd4bdef147a2b0315bb6ece1137762194ab331896e137d6413099ae2e966a9e020c8061e933890d8c48a1ad5a84fad4437c08bf649c39c8ff091b37d8450ac04cb22284732ae83321562cba0b0340f23d15cb835e81f7f13ec22fb7b4a383aa91207f75e5abb80868408e1bb4388d8dcdf7e1e36ed85e9609841f192a7f680d4406b6c3047a01d93f4fde945dcfb16e6610b293baee156730e5d3145b056c47b12ff31d910ee1a3b166943e9d30e989fbd932817183cb0b5d780bc43ea1a2fec8e3772688fe931f58b3ba5d33e8175948e346c09a8afc7a3ebeecf8faf9b4e291f481adbb11dc718b46a5ea734df72ec5dd07a724ea0a6549726900ce2433000bd0478700be499d97d82feedc89ae764afc306b513cdfffa2c481addd02da903cef4783fef35792a4a9cdf2b6c8d51678a0441b729f6d522bc3143f0366d8188f55e67ebc8d90dc7984a6311c4356caeb6f0b2194217385186cd2ab86cde24be4fa116132747365487621287577103a67ab19ab2d515ad7f94aeb5517cdfb5d4d356ec6e3d962d2b545eba6d7ff66a72a760625b1248bf9cf29a71edde3b5e9c5d3edb1d9297931b8477a65e14bb243908c8f8da79d394fb0e45357b4ec41c482aa0000000000000000c2b0f10300000000764000efcecfc93b6761b11012d00a94b69ab083f37ba68674d0f841b484136112fd6d38c642e6beff12d1e158dc94b75d1e4241c43c550a35262598ed38cf65dddddb7f05b7275bd0c0abd71ef705589a06df2c80287b04fbc87446f66223a80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e825423e226a8a71a9e966ec02abcecb817bd930a4e41a350cce0e7e33da819744cd921121b6a5acade385f594783bc02c9f16c7d99491540634dfdee5ea334f58873b22c14bee48c8f96f3a796cfc31ba3ef1c9f9a7435fa43551aff6c0721969e549f905bf2b0d29f71119054b9bc07a28c406a8515098a2857127bb55ff0220a5c48362fa0fb4efbcad1e4ca896837708612b4714746a13c055dedd3befff02064401b08d2e9b58d4cc3ba00dcbd15eaf604bb81ca3189fb09101159954af5d0a13b86ca8180492673a430b9fc8fe08056620f9e7e38cb8a47251ca0b11722d952ed2eddee2c65cae4d8d63040a312a7b8bff4bc6644c20d5397f2c646988d34c02158890a5bb51e7eefa7aaca88f6496586f6478bba69511c31d135c62e70c4b4f022e6f560dac62859bacd984d935623979417ee879fc0e5ef1601fe097c9c80f89020f9a056b303e9b12af36b8c77301d63e173c60e8e872fed401f40105eba40a9b022a1cf403969a64a0d0006119a262fa52cf33b57ef17e078447f60f1dc7997a23021ec7c10baed9a7b67a49a9d401ef5de3022518dea8cbb91ff8ab7fe3ce70347bce764e0fca2e32977b7a39e3e034de8fbca1d1fd3c81acb8e335cb157fbe0a5531b0c755c79cc2c296208a51f2f8183af6d0c6d6c3eedc95f24a5ccf39cde0234502215ff3b19a47c2a64d479a2e8fe0b60754085671865686dd5bc67807ff850dc5207839438b0aec3f9e82ded4c11f0c37b86b647ee064274b0843e9ab8b2d151aa3fb9bc1b21895cbf2d327d175b9cd4cfb2b8aeb4acc79bc5d4ff7cd91f195f28b0f1bb36ca207e74cfb793218c8601f6878e1bca454cb27393857cd4a5c4fbf53ea09f88e52ba5de9be3c5ca84ddf16a30273fce14492dfc644940ff91ad00f1098750eb5980c6b9c73d5d26ab34393fafd559c600199af8aeb95ab133f290b87597cffb0ae33376eb1df90c6d09b16141b1289f1dfdbbe2d15a427a05cac07f931d98a8b62897a3cafb484d49269c25045951d233f5ebc4a9c439fc69c8535452e1e560fd67dd91ecd3f0431133c7c3d17317022e09935dbe22dd3ec7f5e660e67f886e65a467552d14a74d4aeca16fedebe7f7e88aa51473206979ec341b0ea4c5475ad73f153009ff1299af157c6ecfdcf9e704536c5f1e7b8dc6c9e5c6f6f79f233eece6bb82128e8e45fa7234fe221a5be192be78229569573c4d7b7226291b85f3155ffcbe92a4dc124d7a4f9fa478845bb8c17947fe12e074b284676ecce42d48c110c725cf478813b624fc937add5120e7946341e8eb0d0b895b3628e6566e7e68cc2b0bcd7211531e2535e34ee42bce43d26c7bdbaac960bee1b9f38232c9767c11bb555652295971003acb38eb6a3ff091a681aed7dcabe7cdd2347974f5bce3e9360a8fe35fd5406ea95d9d633c16469b854ea869be69ca23be0fd8846efb43c9204d996df6c3c01b67ca3989d54777a3ef0d73e37fde2f59164cceca596d7d36c1f5b589007bce1e4b23dd2e47b84351d801acf66412b35529c038fe9f35e65a8a4392aaad83dd75f820efdc5ef7bb2aea589920d59dc9a1c259c78de0a371d89f164e16ee33fe9ba303b91693140e3542b402e25b4c8027c98d8aa12e98c01345469234904af040cdc62fbfb9b279e26672bf08f84dae1e96810b52cb3c078e768fae07675d893d3c8eb412bc8c80a0786df3bb312b1c7e7f51443213d18b9c2275a311f1b581cf731498cd53a0d0719c1e43d7f9d52e4edf99c4e3b02ebd035b8ee2315982893cd45c928007ab6b2e2c0ef3625f27bd2448dcf0adf2c6320a5bd64f3aa8d2ea724322d0d75023a6691eb1d159db4494d8bab8a0cfd04aa3359dd128badf582c5b2b5e9aa24fa8aa60ed4ef6911cdbe2cb7e0591745fb92ebd655700a5d4abd06f180a747ec2ddc22b15a797e3a9d2cb796145642018c7ff59cddb6527c123573df0b8861b18da5f019707f7477bef102cca7e88a7d11624f8447050436721f79ca719e1baf2d92dabe751c3d6ba713ff8e3618a887856749ea77094a6f9adcbae82c32b481545b41898c8b838dfbcfcb494cd92616a755440b5e4bbd8cb8fa6741e1d9ac7402e34543c3cdb77ad5db528cb9f8a09bbc479bebda001f2bf7593bf023493a49b6649b00bc72cdf5a7a18ff1893d0c661de51e9b8d4ab59201352264873cb390245e8b5a1971ec664e5d06f49c6805bcb5b0c7c113b25e2fb506ed77772b7609d493e44f1363da4e851aa26814529117988aa1c682e0a6785f809bc22587c1fe508c24aa410c828fd90bceb94c14eb8e5f33d8eb354a0aa2df02f9d58969830ce12ca3ce81ceefff95cbab99a1b72d33d13de2f950577b28a20ddffbb0032e17d1dfc1041f08fa0134837ea77ea742545817b7503e41f642b721453d0a", "65526a63635365", 0, 591722917, "566fd1cf0adf04283d4a9d27bc0de05ff76ae71baf898672b6df219a85d9d74b"], - ["671d6330039b82198f810564b5fffe0714f34fc1a31cb6a24d7d8e487b5cbaa37208c1c2ec03000000006cb8565067e11731e52cf55cd7fdae0125dd70a41c685e229fade51b6a7e1b5b3461a69a03000000090000536a6565655151ffffffff5b99517bc4811347b1e6651bd4937531083f3a738a59921003f4b1b74a4292530100000006650063000052ffffffff03e1d0c104000000000600ab6a5200acda6e49000000000008ac6a53ac535352653736090300000000006bccbb6601b399c40400000000000000000000000035dfa222a5ab2b88d72a04335a07163ee95e72bcd71826fb0d2b20964c365b1f25dc616468d635aa21b0eecaf892360fdbe3237d9646d7c2798d4fff1100e6ebe4180ddb2dec97cfb9568a1bfc1040f1da10c89c004a4d57dea18bccfcbf1a17000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e6173b825b40cfa28d6fc2ee684d2f66df9dd631adac4f6e1bf849d449e24a10076fb8a77540ba6f7f2e5f2331011cd75c51aad3617547c3745be61ea3a8642c0bbc1d04e58f4e2d1e422a8ec3565d100672c4357e80eda8f66d150cc4023de07dc4c0796672ea1a9870904c10a949a11bb3a416f757755546c15071f8b40c403262d7e3f778a1450db53a33bc1c77042eb62afc5d7e22358bf2a66f11114fb720305f501bc4d1ec3aa71af4b41b55d0fdfc7b45169c8c300fff9799fe6803503ef0b23a0a2c4dd1414e52dc3e3d284faaab796c0da38a37f9b51d37e49cc7001e1f806dbc88dbb067c22b64ea314b8d999f5bd503c62a709172bd3079130804da666032defb4f74c6a13e651193ea1e1f08f8afe40076e3663a3dd273571675e0ebdaf021f8b5723739da8042da59db3a23ec03a5131fe8d545344b4ea397393bcdc1654020c8eb7ab04c1d3bbb41f4b8f4a41cfdede126e4ba48c0d666559d8dd24fdd12803152a3a800bf6ef8614def489c6131ce52e00e60cad9f552889a5a2f0e276b5890215d64e4d8f5c965f1e1effe446c53a6665b1ce5242167f6ea60ec3dc8d8aedeed988352a3f0572ab97ad72d9c912e1d9293634eddfb52906850e6e3f833f4dc334d7f1e49cc38dafb7f563e513c377ff1c5d94207de23a64a737ccd6372de38ab2376e823ffc5b6fc3c3fe70ad82c9ca85b1ace045c9fb88c98583fa361aad1ecd61792b9c1c0c64753fb1961dadbc4ebde2287bb81da0a50c56785430222f6a9af73ee03fd27becf0d5710d07b1e77298bf6b2a81f42f0d537f019aa50b400b5b66dd8f1e6836ef43f3d8adf6efd8ce145d39dc6269b6224217e1ab80f81d498b8aa830bc140bb29bfe8897337d31ac712824d7cf29f8fe0c85f664e6115f92aab0bd865bc49ccb10372fda90c3f72606c2d1597cafe8a6034edbcf245aae94eadb218279930b830b7dafec78991f537c3aac7639d97480e352483be9a2f277c11720a355893df4cddb5932f7fcedd113c510947aa57b8f8a32ce85c62f17bbdba1b6328971b8e556031dd9140db72b263f542aad4cd9227b842722d15982fada8f20ecb81b0c92be1578c7137c95a0212f912e3ed255216d73e8fc49cb1d8fd36f681f6880cce066b9a2de48a4782d30b7e10b15f6019337d8a263811c94d297dd2bffd1705b001eebcc548c5255b79f35662a961a1efde7b125346fc72e4fe73897b2c3fd2ab6842106b62a7c1be585bed00ab691a3f452ade5827f646977134da370e49ce2540d2d03f49f3f33d4368ae391005587360a3c30c2b3fa1520c020152a42824b9191bf665a960c0fc78dca99e1642e019572495f8658c7732d254358bdf0e270acef11d2f03ddaae0c1ba7766a08ee11188951116d0f3524562761ae7acc5fb696ef9b4f052bfe19b6ff7505b49f414c5fc563af99884810834e54df964a3b74f04eecd330019c55d35dded2fccbed7951baea25fdf9cc95ea9295ca603e6878a4a3d44bf056e3ded4ec3fc20735bb5b1011aaa7e7de5c4ec37d7d5f9f18a32b9669aa85e3bf44cdd356ec14ee883ada6100a800ecd82d7404e79d060b138213b78e3384e18c3b655607ccbc965b51d0cdf38465c1193f69ccfe2e2edba1d4225f30cbe5fb1ccd0496c64426a1a14863069f9da5cd57ab28d48a2ecad1195dd4b511a4b8cee54dfc5a05d0d615ff7f783a06d56e9de7696b473756838cd630d3df7ea2b2de2f727aec6e1824fc45f634062180d69cc7c9d23ecefb1925b7cb4a92da35bed64b06675973100101cad20517c9f314527042c57020ccf0a60403d5d707b64bbca0b3abb3bd9b7e62d9ab12a1933fe8f05abddb9e58a1be6982493ca32cd1513d1d78b66f4079ea5c2c30c071d47285c7617265c3dde4b27bbdf050fe948f1bba3f4d243b4c5834aab2466b07abb28821159eb3ae0b28d6e53aec5847811184bc4de55b7580584b2aefeac0ffb3d375994419a0889950fb8e322e057d585e045df194030c35305a1d8bbcaf82a0d1db0c1578fd2a7a0fcc96e0e33d085932e4f200044841aa2cc6c6ad6e6f1132940404ded6734f2aed1c9cc16143f98b639ab15a73b3281141f22a19b3594c0f745df4aade6af014a26b83135350ae0ab8cdbcdf28806064f870cf7eb2b4a7397e02c8f165db2adfcc802c0f4bd42a84f000e295dd0e5e800fb36047c774c52e556e34fc867e4b8594c0f3b6997f76cb6a5983769f1e2790322ff8034ddc5d7d8a42124b943989d1abb3ef6f8332345605a912a71f4c144de616c1ca2d2830865eff881f4b22e07007da42450e5b87263de61f085b80aec68ad17908ffd20c054b812ebc788780d78609f456599ac1551cd40b1ec6c6226adfe9a929a671e968817a25197d8d4083be229ad19bc7e4527fd62e36ef1895f406", "63", 1, 224243722, "a11612b83405de660c692a3f620464ab55b171d03387234a298b3da872cecb55"], - ["128b99fd04f933ce98b5068548c64e6eb072df506c4c181bdeda74018fb07a2198416c4bed01000000003296409e7e63687e697ac11dd485bfdfa1d4bd2426636eff05bb0eb6ed49e3064c254bb90200000005ac63ab5365ffffffffe575f688fc85b5366eb6127f1196f91fbbd41783e5059f0d72882766f605db8b0000000000ffffffff21f6f83c639ec664761acc28c7cfe87a54a5069cd6d177952ed89492b2cbcdfc0200000007515353ac5352abffffffff02e837f80200000000095251ac5100acab635390c439030000000000708512aa", "65", 1, -951791733, "e9c15dc1952625e3dd73368df47625ddfa37c5979e1b29f8f06f74b50ad514eb"], - ["dd227cb004a68ef5b081345deff7d4aff4a2ebd82642f0de68becca9bd65a008a605aef92603000000006eaab95477b5234246274586ce9cfad13b2bf13e6f366dd64f12ce57f0013110374ee21601000000007144b8c771c49660f3714e49deb88071f600e5d46ad26cede55362584b2d816aa05d60a5020000000100ffffffff7a3946743d146890609ab5540b32727861f2e9f2d8ca4a28de239b009192986c030000000400ab00523ae8626a046cb52d0400000000085300abab53abac518642dd03000000000151f44e8d020000000002ac534ce0cc040000000000bf9d1e3e", "636552", 1, -614446, "4517dd7c13047de918e173ea6d382fa9d035bdbc2a4883154379657ee2555d09"], - ["2731335f03d813cba1fb1a109072e2f21cbd55b990579aec4653bbbf9ecfe24003a7bb6094010000000265abffffffff553b90af86abc340722e37e96c0de1be80bfbc8ec18933864d26dcf66c115d1e0000000005656a6a63ab2d7c463ee99ea2d5ae75c5c559be03aaed37a060fd171e6223bb721d2d22c57f32a8ba780200000002636573b111b1010963a00500000000046a65ab6300000000030000000000000000c87c020100000000f7be13515a34f64ff9a9f77e85f64f217e904f85c2769ebae9be7fa95dc9342bc61172430ed374afe3e605631f985dca23e6b1812313592b1844729cc2e505e7e2963282776cd5766bf2eaf17471f8b220bb4b62ef1f9cd3f9219d2b252f5d8b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d165a604824826ccea94691653c7faae4e40b3c2c15a8e4ae52f77191ff906e08da7be865964b6531ccaa5c4baf7df76701c23454de3011780c7645f982a5b56fab6beb1d06edec37771e7ff034f644d37302c2539bc90dddf4381349783f25543fbf7d552f7c21ad7382952df8cd05c0f9768e848f57dd7a2ccd041adf30e90030e4653f7daa2ff160b5b70223aa2d5dbfe441b392f714a4ed66467758343e690031956ecb5b318eddfab3a75c84f4a1a8fa90faeb19f35fcddd74ed6b6492d95520b256726b2dde131a7941d1481cf319b612a72aeea92afc0dd703e40116f12873906f2bf194219caf689c708a78bdc2d51a2709c53414c94397c36a1435b8231b8020126af80bb7d4c5f3649a60f12870b9229dded123102b0ed53fbf23c9455170503057cc05d0b8f124d805faec466247e5702113614d5152e0b8d6a1dee6a5b1a00030fecd96163438d269f63197313603b529895723f4cc362dfccf4541542d670100305c7d9a6e6229055452d01617a4f6e87b9472e77316febad25f9735be09fba80030e0b3806aff9302be0a549c690e5ea318fa27ba067602fd3ad38f2db77a430154982a8ebb6ce598ead66654b1f529dfa95847f60a808aae94d9fcc36d189d4552cba69ca2b0e418706d511450d6bd1d54ebb447cf90f424a5ef197cd7aba9907330b7e79eae2936cac8a780358252dbec3bb18356c477b23a2f2183ddb53c90bea781ba9186e8347403f0e12ba210b4eb7fecf91e265c6bc9135d0b7b3f06d714950b588aa8a2affb0966b3f5d16b37f5e6b5612c4fc46d6b875974b47d185f76219ad9d4d7b1bf8db3adad49002422f4c4d745d2086af52572f6edeace8067c58915309e0f11b4870d324298d079dc81690c732212231bdc3a8d33e41240973b3697e4f4f163523ee20875ba9ae2962aa636f64e5d65f9288840e199e290260044d93d12fda28c7939625bff3c34ee4cb5aaf5ab2d6b8479dbaf52f4f83dbe1a884abfbebdedcfdc42b23b397a05c3d61ea087100eec9c8e3257c3ab6e309680a78070263c34c7d4f3c5fa7da540ba178b5c0e6077ecc7eec1106f9c9f525fda3e89b98b5da9e8483c2c3cdff3fb2e32a8d9146d6942ab00dbe08adc2cc7241def9f7fb9d62eb0a09acf0956f63ccc955a5792732cdb2e84e75a0b0b4a69b7bec919c93777ecfcbfade1c0632f79745c4c666d08b0f8819b6ddc196b6c59747cb110c4fc07066d2530b90c8f49417309145f4f96abe7125bf8e448f49b45125b8634a0aac0bf2a7ab650227088c69ce46cb77157370229b539cfd430e70b35ca8d8ed1019a787c980025bf2cbda824113f38468d8f3a31c7d4bb0d7d735067659ab84e17c635ee019d36a758a3fb4dadff801a2a3af26955e568f37562ccbf011d7d8fdbae0b9bee6c5d034edbaa171d0fab9182895ed092c91b8c9dd92af24a522d42f1ceee346d070cada76c3bbaacec99b91f63a781aac2d0afeb82910c6d1b1ddb7cabb24cb70e5a74bf56b521b1bf16b15ee25c8f61397ac8bdd377a81f90aa2f3f6e31decd813ee3c761841668ebe844b7d59ca06e14c5b7ec0a8c4008679b86345078e0e01d23e022ee3c4f90145ddeebb2b693530e42ea6a48fea82873ebdf02d430a3af8be6eb1cdbb3be94f6c6a6bead8fb05c4a85d6d6fde8b15bde55394bf10bb891603c63bd3d8c1f660f3b601292adb9b81feac56f7cfff61c8c71a65731cc21e071e1dd906a1191f7ce52c07713c3591d1cc8267793e7e9b30fed3c1fdeba71077f0ad160ce6b1d666af13317c338bc1a84d9ab27e2c60a8ac628d5f678ca0608ffb90d66cb2034aaed347c24ca7dd11696b9ad14101f1e0a75facbf30115a851a40f6588ab1a3605be32923e0ce81cb78d2711722ae45be6ef04c0b7ca0263d1b8cf8ac9c31b8525fd00316d3a8e7dc554f42b40ea6d2d951f9427f54984c3a78293d4a01adda001fc1eaa26cf17c6b88bb63b11abb5a868b17881b8067b941ed787ffd6c0913b2d1056c3a5142148666df69512508636ea2f95accff258a766f1f6a17311d601e801345fa02f9766d58bd34a5c679eb781e51021d83fb0ca440a9fb62adeea83d2910b0f38db270cdbaea4021d6748fe445beb49bdebe58edba98219bf0a893ce8fdad1a41036d6411a2745d9984e41768d50f3a1e2f6b4497708ab524eed01dc8119928b202d3160c9b0c6e7ebc51bc03efd2404b64e304c81f6175f38a066c64d225606f27ab71b4ecbc4e9bc8e8bb551568d74f8ed54a4545b16c06e50c4ff582df7ff3f020000000000000000000000002fd30532b72fc65f1dac7c0e7784ee9c15600eedf45bb2f8772fb1c0f55919fbd049ff9e80194043857e0ba55af496654ea722a0c5118af2e2699b1d217497055b644a3750556d8c79b2e8c7f36e7d6924d0ff68357c5c3452e55db62e718f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc71b7f3f33a1187b5523c5b0314f250c872948669204c7512797005aabd8d709594b1eb2c16de4aedbe06aca05f7728797acfdda8246c99754b5979c3b09032c862fefb4d4f477fa7b99fdcf6330f03b0ef69da2c5dcfb7b751f2f2f0bd0ff43d0d29fcc09489291740eeb13eadc5d37df6e0136099f998a286ee3a4d4218e703288f453bd23d9d9c31c2bd6b504943ff1e6d8e2b231e164dff2b2fc3149725cb0320f650fff360a8b67a7c387198ef0cad06a71329a79c4d39f7cdd0e2fb6f54180a2af45f27b6b2123f307362deeca7c3c6132d639ee0ad387848f1345b8d37b61913b43216355c782630178191e2dadd2b96eb9d94391a3274b410d8fc6af80da9021077f012ad1558e8af87338dd459cb3175585f9840c27dee8c4d6c70e6bfa7f30214810a2f7ae852c7dc296ad9cc47460769b74ed99e7514b2f8a39a73f8cc437b032120cac40dd7a49e41e67f159cfb9f3c3c85057dcb89cdb98f3d9a6fa3320314030be989e4b71b105291f3ca1b170a3437ca5ed4f81cee6ff127296baeecfcaa0f0327be33b43987da66187523c9dc3b7681e41a4cc0763c311e8a0a6ea84ef1d72069f0a1c0d0b8d876da5d44dc49673b64c3b522243a4d03db0dc8739dbafef1c6d7448b80f160337ebca7addd3af17ef4666a981daec563278c559062b15e179ccae6dd7ad2e8591b7deffc08e968a58989515410ca64b1121b617d5ba95663739c4042813a61d1837c0ae28f570bc1f3251c52ac9c8ec5b168ac1f4b721b7bda2b2144fbf92c3ae33e06aeee1982348c471671191efaec6e6f3d46f84d5d4a87bd422455ea1294cc031a76c86dd9c1e73999388d2703f074c8a1ce93b76554cef4d0e6ceb802b0d0e7b5f223b813aa5de5c3ca8e63d7835d51eb92fe2c79a816fa16bc5a4f6704dd1cac0b874d005f4151dcd99af83ac6896e585ad18fd4263bfc6f3294731627b99bee7a327f1416a78a8c44bd83f9f92c75de37e44910d8aa7572f588f1917d626c3105544a35fd2f2cea686aca25dc88351111acb67a0a2a2c1e3606c987e0e279c436aacf9b71b2c22c16e0861a83c10984ec6773536b74e44823f3b2774fef4f546d1d7bff318f9c5d05485b930d35c90c1b4819db06a88c9256a8a1f9cb5187acd0467dbd0f1c77e2ade02f7842ab1c2d867451255cda298b4c7cbd5431222269e3ce0892ac68b6cee01306d8eb51165066343354aabae3879a315336969badf60c3e0b71299c6f0ba5185aaf40cf5d845e82b4953e81c32068841ae30cdc0b732a0a1b39f3e370b795ed4ff3d392394fde9e49eb33660451f40dfde4a3d3ce52e691d2638bdc5326196eb072070dc8ba4179a72223cf9b0553d87d64a2217798c58725f5c29c555ff7233351c7384b0486940ad8b1f6caa5d572be5a8364d6d8c8239b2b996dde645cdc0c12270246f82ffd7702bf40375a2aedd237ae3bb665cf50915a47524e655febd7017802df4cb3d7736d23196f97694e016b06c7f81dc4a630a6f298a8548fe069bceccb316d42fb4cf291443799b42f136f610ef0f19a7d60227592ebdee6d96d761369d4a166cadbeaaf718e0171be8659230ea0048e8921f73757c277d5d79c13d55a424e772ddc6ae9943004ab2dd431f0869f6b73d52e890c744edc7e2296cb2ee2518f8ebe212688fb7c855944c876c7eb81b00beb59c6573d0b8cb524b5bac198f0eba4a6fd43613f8053f85d7e8a1c445e348967fc6baba5bdbafbf7b52b02ce7f2f7dc4dee6272430716d2441f1810879d229cf6652209d771446c405576708b72ef469dc7e3b5877c4e05cbd5f3037188d5b5a2c1e872fde5f3da876f17ace6fa3884fb371de2ab25ab18ebd7846189b00353e31c193a8b04c9cf4f949e7b6b91a13727f011d016464a8419484a1c55dadbb0300402dd0e595475ac3b931c078e4879bd6ce7a24bbaa1fed8c473b36c8d421b371a35cf0fa02cb491c75cc29aab44b444fdceb354169ea0c099fc09e3dc6392361f97b42fca2bf07724de164adc8d2cf832bf354d12322a020328a895893776905f9e63d6265a386bc65bf61757c38e995c1bac156eee2734845441ce062b4e2afaea3da85fe5bd95b66d99ecfbfdcb257b34bee147e471bd1084b979c56412f848a356e362afd99c068ee431580d19ac7ec84bfd43567411143e12f49a036486d6464da8009fe6d40963c5546dbd5cc342a691429f5f57a173b89998c193b22bdfd4ee50363907492f6bfbac7bb66a0bea010e2c12c8ff51f650d028151404f88ad27062a46294bb101000000000000000000000000f2b1cd346fa6e13c7576fd4021811e69c13efd7c4162b41b5f24c57697cb59f6ba8654222edcb5af8918c0288f61bcf0975734449a814f8d91d64b85f8a65a4276049c8220a5033ed2d85565a1e674db2e1ee9885a30d0fbfe3f574f3aeb44c100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ce050dcdbb071cc0fc3a09b21e8143a0cfad526056ce03d4d1d170f336c470c69b2a15a8bc9f183e2dd9f93c6fd2bda9a9b539c0b31e80605f1b3a9dc2d9c80e6c0726fb8923989cd386e0af6b7997fa847a4ad53d0edae6d02b936085aa6e12aa123e7888cc75ea1d8541285b3821e4a2ac1d8f56b2be74e08928e465e0ee3a0318c4d76d106209e7c29af3f5822c3765d97bdf39f5451954d6f355c00cbd1e270308ee39265bfc05ffea6bda1ce13f5348c131234c6bfe018e7733f74406e7d1450a125d684b1d32906835bcc08150684c60b951d1257942513324756fb76981814108f8817b80c6a820ac93e296367797dac5ac2a465fd6ec685461546b29fb269402250a78eda38b2a3da1eb1c7b97e23b3f45feb3dc721a654899f44493d62708250226b88a93d063edd15b4dbee6e0749692ddc7640bde9662d812aa7bbef52eeb440223b037273f0f3395e6ef935c91503ace8efcdd733dcbfd4f0353c5ebd8db7ec1032a01199edf7ec2ef55bcb938ccdeb5e32db40fbfc85f5f55cdcfb9834003900f032dc8df7c91416624ba191b8493e5ee8f360064fb25becd1eb8a9626d2a42b9b6bb2bd00bf581cc3ccb70ce9af62252a59f1a6c1f8b45869eeb2b98bd10face6e918a10818285ed1eecddfe78721a91e36dad19f3c2a667649ebbfc819f4684a8f31b42bad43a8846167735efe2f3fe168b17ff27e793b27d362eabf42a389f913088be7f9bb07b017ab67afc6482636cc6f5728acced37414df410924e38fa64bff0ddedf183db4c32ea57061a1b310a8124042fe6fab8c2bccc520c9c3a59d6d92ac58a4e53062c912638fef707d1e6b28e6b5ec277794b9a375aede8841bd05acdea522731c18d379466ea40ac8ddb722021c3a9a25a962ad555d4cd6b8c1947aac0b2c1115988c8646aa647c27ed66ade29861bb75f95033554be6414e8e4baf523e41ef2774808f0f6e851e7ff9c59ab7fbc0c103653eb0ba5b07469c787e1761c61dcc973478e9d332ef506ab8dd0ba638c01d44026411502790f6a44b6f2a9d3627760853462aa8650b194da7c335bac7c82c8419d75c957102b0f618a184653dfe1847702383929941dfabc2bf23e8c4ca58ad644382edd3338e7f35187d3e8191acd8d316859c7b7fb3bd95bc9e324cdd45ae0f602d8a6fb01639c17945722777dd5fe6fbdf51684c32fe3f91e9d064fb953170431c3151618d92c1ee88e316a21799d95950bb55157c6ed62bd3458897843512cf692e72d891f85ae73a672e1fa00937d2e37c6b6c344019aee3c4a0ecd276bec1123f43e02056c7b7ee180e9e061ed9b09457f40cafdc5e6f66a4d4ae57d4b810edbbd0588cc3e4c1a60dce455cf08fbee5ab523726be1b376a947ac9c43731409544074e54681de7620866b652edf0d66741eb0a855cee07baed52b974ce687c20e8c84b8faecdac79fd133865dc1e275f97a9b06fae17073c3ff59a5f4b50a5a1e8b1770bd9b0a29aa3a8b452fc25f4687a853291d852537f1e57ab64d386122368986f575462e9580cb929d99a893e53b543d1e7af9e01c694bf48e274d71270744444720a3b37012ecd2b988c8a2e49a1d8a3bdfa52019752aa2a46f9b91924e4fd8a817501ddb04cbddd7de25c55d88c6a053656273f0909b6a2cee36da7db93cd44fb4dee2a3071c3b635a6deb357fe17b77a6d67388190333362327ae0ea588834d57d3ec49d23e41db4602d9750dab0dcd6d3d94a42309bf3e05ad0e9a968162bb9154e990081d9530a36e8fdba6310d12e12a36d3445d9476dbb6280e4b82ca9751686981e1bd83386589db846060be88ad122bbcf3c02018fcc275298ca4088b8813f12d5a02de13d3401d85dc228fb34586ba440c4ebdf69a69f6684a16c2a66a8ca4eb822f0236caa3c64a48c375c21b0675d52c6a2f149f3e590356d26ab5a4768a51e4b35f3a91a54859ceb3dedeadefa219a30520b444635aeac6b5e2c3c56b95dc7fde327b77be41934ad149448da202224e7d095a94f10b5d11cad05e78f887b11c3f1cbaedd8fae46383584052ad8eb176d638615ee8f82157488f8a608f7cb21ebf5ff47846c87478e9b5cf1144a110a784f3d0932f920a5c1a345ef4f3845714ebdca5f2b5178a76e2dab47f16245ac6aea7e22eb81cfb47d4af334e771eb1ef4a2f39d01dff646a47f6172d03db54dac2bcb28246f73f6622d843f83ddbd6525880c97a546ca12791efb386aff201cdd14311bb42b2c71333427f160dd5bad9367526765c1e2ecdbbe82f40c4eeae999bb8e604f5846ba78e9701bbee2ad771ca13dc695399c0e64a73552dbbd833ee3a3bfba3f50a62f3b6103410eacc7fa636ecb361d7a77b67be2957d2139c0ca21ee4a65bd2356239d2b82caf72081382d1398970f75c8a6e3381e6de51411503", "536a00ac6565ac0051", 0, -720254056, "3757ef29cef296203f9a815b1cd8a7a23081465d2a7444dda1e95c1b8b79cd6b"], - ["4bb49efe036700b1a8841c20d2b8aab40acb662396092800e7a3f9bce23e2779b34920ee8d010000000152ffffffffdafb01f60b3106f56009298fcc1bc9837e44855c635f51a49516529faef7fdeb01000000086552abab6aac6a5199c9385f1e528118fe6b3a00b3f4517f68cd80a52a0f53397a9c7096f1de4c0b1deeec10030000000153ffffffff022bcce201000000000763ab536365ab635092a102000000000000000000", "52", 0, 659936838, "974a66ca5e3db186eaac4c80c5ab4c908147c9cad232cf1f5b97964291f44914"], - ["87a557ec018cc7b4bea3ee1c9bdaf2df147045d4fb60fd6541e2e74542cccd99abd68b33800100000003515200ffffffff04a6c9a005000000000263ac22d86f03000000000652ac6500ab00f9b95104000000000463525353da9d730200000000016a00000000", "526a", 0, -1721199352, "566888685633185eea0daf69a229287a46fb3706cc1d734ff027ff66b3f9a81a"], - ["4e7ecee203ac7138c2def93c0dcb33e6d92d723e030dca45d6ceeddca26c58171212420d73020000000600530063516a1a12487f731af39e060f363423c5d58d880e6915c82884182807fd11db3c41375f1816de000000000651ac5200ac65ffffffff0c292af49fcd1153894a5a5d7775b640806a1817118c07cf33ce558c33f0069401000000056a63005353ffffffff039460ab05000000000465ab63657106e301000000000563515352519c80c0040000000007acac6a6365ab0000000000", "5100006a6a63", 2, -961177221, "da044153645ffeefe053ce9b3e30fbbfd5c9bd1ff0e7d56436971b90c86ac33d"], - ["5cb4ced703eeacc541c7261dd573a333791de19c1e3b5d15e5e2f1f6766d147a95a610efa80000000000ffffffff42d364e05a41dcf1926520d60a8be4771326b81fc774a9bb51b149c1a6d9979a030000000852ac65ac52ac6352ffffffffa132bcea653564e0b317ab62459bd659a882d35fb1389974b3c894f59cba2c86000000000453515300f06b3cfb0146443505000000000363acab00000000", "00006365526a51", 1, -1941457561, "a09555de29f4ab0935a3e7b3a2716687a8e33fba574ff9b5abfce6b1d3068e3c"], - ["81f028d30232190c88962f99f29e5fc2e604dfb6a4b066d5ac526657805f4ac69fc22b8f52010000000152ffffffff68cf908441f72ee5ee413b591b30516555d0762c157c7ab06fe4ed916bc4ccc10200000005635263006357b1804b034c4456030000000006ab6a53ac526af11231050000000009515100656565656a53c89c1103000000000000000000", "ac636a6a52", 1, -728757991, "d82329442a821e0d79d5f1293e3cad34e94c8a6290e8994f4fa9b0818428e1a6"], - ["83b65b6902dff28a51a2351428ef2a8a8b61cb5a0a0f5de131d26bab4388d617881af8b2c8030000000863ac6551ab516500ffffffff32c074e7e67b60f3f44ee848a4f244209c7a6f0b7963eebb01b3c4823459c9ac00000000056a526351ab7160aa1e032a51a6040000000005635252ac636c15a8030000000003abab522d448b0000000000016ad5d8312601c12ac804000000000000000000000000465a7128be77190af81b465eeafa6edcc4a210116428b4bd12d8fdb8078001233c4dcb156a8fb8313c6f979a7efb2691300195d55b023420a69a2ac93f17db954630f509eccaff4c857b3366850fe305306dc5e0f75c27e0f059478dc9d50924000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd7788844f1c440b86cfd5b26261b18faba87e5d238f13d8dd77ae4302e99781a2fe8e5fbfeb5060c725e9f584e374359f4d07a03e50c58fc11fe06d96b9232e195255680d3384194cb1f9705c78e7a10b0cd05f32a25ead51e676d97c0509a349386ca06e6fdceb42b96e8e127ae043799603777e9dd73c8959dfe3cc5d7ee031a981cc889e31538814b9412e6d060ebde1f16694e81788c1b65713af9d4664802022ff243839553641be55d45929600a7bebf2eec640724d8771895c16f4e157c0b01a1f468f42a8ad2f16826cad1bea07b6ffaf39bdb8430cc8c7cab8b36b5501d1eef7a9d13a72637c74eb5683a7e76728bb53ea32c36c96ab9c9e7c71b12d73f02281a10a795b25a65bf9c569038e017af20cd5aecb7669ea1f9f01f7b56ced574030891d11f4c11e9e4d9dda7dad37874e53c1d6bdefc64295df0202d51e30919be032c22cd7bac85f9ea5c0c96062fb2147418291a25c2a83b0858704970e602e4a00211e03703bf0a02fa0cfbd8fa7cb52923bd41e706c41b3ab0946b8bfd7c875b46032541ebae7e1ed369f5cbef41d35611b1927817d0825662abce75425ef4916a3e9e0f99f3f9c66f792d20cb9e30de2694d75180dc41bab5ba4b27492ac191f8927fc15fcf2b6ca64a7a8aab8b5f3faf1e3a62618a3f1c8209cd540ed8a7aa56cc2e1f33de92bb81976ef3d3e7d86eb7a8b6a712727fb579a1b86f8c1742deb11d9ab99e5b2f31792c9620f0707d493f662fc635f8d7a266983336c0d078f97f4632aed3b738a4b6bd3e0149bef27227ac324477c65a07e68c139597a290e92fad1e4b82855e0bb48ade19cb0e080c49c97045757f5019ab867b26d576657ab952c92e5b128b967fbc673234bf857354ac639ba137108b2b516fb0684315d28b6c7ac3c5375950491527130e9de53b6390eafb8df9b14184b05265043a0ac3d4e7febf8b6440da7d2cfb8f7f23afb4b4c61caaeb90e03f5dc756879b7612562559a4891f3d29986d84e1a280b029aee71d059bbd68986177435b86706303d2c7182b271ce23a5a07213b9c213bc8ffcd412cbbd73b6922254d0105fab83a7d8452d20b2c99fb46272f49b8e7de18fa02f7041e338b5ca5ce905d549bcb169f404d49a4d780c338eb73bab77b1f0189893b6352e148bd98ecfd97a6f0b44eaa78b1e70aa572700d79cc7ae902d8bfc202be28f2bc78e114969f73246b0174e663e4ef220af1ec3e479048dac934105069a75afa13ec5b4ab2df9cf1049f9ebe524ce4e50b8899a9aeae4ba76693e726c44c6f10db52371ffce4017885fbc317889c1fcf08402aaa651ce143639e9201567fd43ae5c5478c2259ef75612062a57dffe96a8b2f16ecac4ef5a5c731f5ccdeb42efd3d43ba46ef0a47050a8586ea366ec8fddc3cb624ceec3f67250c2c966ccf8697b5ce17f824d91d7052cabeaa7befc111facf3d6c610db5cec03878700d924a58fbbea8825f0158643e36277a5e6682f2f1d395cbf3fd43bb6440c50ae76ccfc64b9f40f5fe53afb97f4565529920b1ce535ca392a18ac6b1793cc6a493758548e86228c7e042b4db59e01c776d580736870ea5705877ac15bc3c2ef40ee7dffb687a35bff18b0a08116f3164dfd2833c2f0f5515b0d23b38203b195fe37674346811a7670533d01b215e59045379c27be55c2e98c5c4bf82f847ff528c57b49f34669121c11245e2735dcc55f128aba77590cc1cc4ef047ad8fa73f1ce0b7502dcf06e267ee34adf1c1ba5adc6684de424495f255b8438f560b02660c394a5074dbc9da381623a938e1da16d15bc015d9ff3253217c0c590f714a60ea371b5c2fb6da520a9eb8e1c50fe764b1b6ca4ca9f67c6c5b164163e1953e86051782ddb5f674eb2c6f2139fb2a535aff8d24be58ed8df38a45e39d0fc6c5a209e47f8717946fb7387b70be0f65e2425b12f665aacd545743b487cd079cd1ec87eac1ed8fec6666aac3cdde990588e500fcf8f25677557495ccc235a5d925e6cd2aef3f9d6980a485479ba7d0985ba3076465a606b6260623f6771aa2e3a9f85fa6bc03ab501dc4b91cede3529d4481fc93204afd408aa470de2c9191db6dd05529c76d33a916a500ef4b957a49182a76dc9dc19bfb7db98aa407f1d18e914525cbeaf575af6d15b1e9431eac12848213250de301940b6dd54497328e72f91ebd7bc5c4c602b0be2b99b5c00099296a74e62cf408e6ee1845c6f0f2c9441e38fd99ca6e75b674a0259360358d69b41745408a23fda9de2874c88e92e403c374a87b2ad797e534890e6025960710f3491e81d8af25aee983ec2c08c51d57d633158e3e7ac948fd1e105999023c86e780e3b95ddbb3f836eb93b522adf4184ec150863ba703e65229c0431f3257d16413f9e0410be6be4d63a7a85a58d360f05f30d4a310d", "5263535252", 0, -1835847718, "faddb4bd04d3a6c918933e017926526e7590ef2203fae2e07d607a5b3629a85d"], - ["4d6172840202bed3ccf849ae7b0ac75ca1b696dff59c52ee191066cd8da69dd699fd3d452f0300000008ab0051acac0063520edcf5d41e5a709ade8502563461427b6a4bff740ac26910f044a047b89eac93bb25427c00000000086565ab525351536affffffff016c2020020000000009acac656a52005200539ad86e35", "51acac5253", 1, 469254342, "6e730ac3e8b31ef8dc44709817dca89dec6114c38be80a744fdbabd032128464"], - ["7d51ab3c0404e46657df49c00cb939cfb57fb109c828904b855bf63a6c3a5432dbe40972eb010000000965525253ab52635352ffffffff4ada2884c23158854715057c3fc43dc4e25df4ee697616d6c40770aed59affbc0200000000542f68b8dbd510db5a20dfd559037d4228a1c53c6d3546f731d295cd66ba3d9bd792e32f000000000465535351ffffffffa1fc2229849dc96dc2a5e2133841e9c6d49b070af6151206dfa643ec3e50947f020000000200511931486d017736ee0200000000056a516a636a0000000000", "5365", 1, -1114740331, "5a2772187fd2d998e3bf36d953a0fdc2a84cbeb45e6c44b6c3fcf3ea9ff35e06"], - ["1bd9dc9f03ab3705b0ed884d18bd53ff3ad3aeb6e30f0543449491f0ef22f18f34c36dfdd903000000008e81f17d414fef0c4d306f208b2c1c294afb0309be5f8160a67b5548e9f14e0981f1c87c000000000952acab65ac6a516a53ffffffff4280d64662567c8b50bda15a2777d6617ffd0ae5a8d6eae8eb3382c016257a8101000000066a51ab6563ac89a9b70d0170e40e040000000006006a51656a6515239679", "5265636a63", 2, 1182737273, "8af6bbe9885ab99e6759f0d4178d03bebace2d297b2443c5d090a99375cfb7af"], - ["42adf5c6039d52a50d27e50f71cbaf0cca5469272e15d09e9417bae721af94765104fef4da020000000365636563f479169fdc2d0e2a421284f07f97e8ee28389a65aa31ce3517727d9a4535887b33b8310100000001abffffffff841b9c5de0c748ecb4b5737cf82d460d655a33a83a12fa828ed5c1b1abf6aa04030000000700ab63535165acffffffff011404910200000000066a0065ab515200000000", "5200515353636a526a", 1, 471122597, "dc70c64fd8c8e34e88e727dfe44325a1913e1baccc2f02c20a7f717fd50b6fe1"], - ["ec81ecff030bf08520417c4fd07e657f885b3f32a71a3b7ecec3fefd9d4060a5350d4a48660200000007006aac51005152ffffffff211fa2d830dd8d6330aa2d0f763f448e68cfbdb3e960a916ca6b03b91dc037e001000000035352653bc6212b03104ca8391689911622581729ea638a0c7b62e6112af61155cb11967e39b7280100000005515363abacffffffff0437dfb504000000000096673c0500000000007816df03000000000765ac52635100abc2bda400000000000000000000", "5300", 0, 246438760, "4614ef21963de20bb70abc89de8448031bbd31b4fc35bab759abc065fbaa1b61"], - ["a44c0344026c3441ffaffe081b245cf3d4ef2cbd63a7c25b311fcb264fcd0bd3c3adf1e9eb0000000008ac636aab53525200aae90845262dad03d2c0939ea1567f798906dccd3cd155bdb031072e1b8bdf67243a2f910300000002516affffffff03a9c0830000000000066a6a6a5153655497cb030000000008ab636300000000acf11d500100000000095153535152ac636351000000000300000000000000006bba260300000000324bbab57eed08ca11e2e7bd846ebef0c81ab0223a900d21f72d2e8147dfc6d4e1b169d6ab61981b06faeb7c50f4c0cf12c0f6acb6a33112b9c0f37fbac411780a8384cf5a45e5a89408396aa9e3a2c5567a855ef8b20c7f298732108b931d3700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b8d393e2d2e637af2f397d751f0ef5776b6595ee001a8da90045d8c6e80b4d0590f454f8607dc26f327f9e6e4f8ca965cb48cafa9f59968327ee9378cc3e0158367c3aa73fc615c7aff617bb0890901cc1830423822e85e8afad002ed9bed85277bd2bd8056f9c61eb8bd1b77700afad188fe79550335bfc58918059027ca41a022b6880222ed63fe312bb38ba6a6644dfb904733bf23d2f0e56bf694be0fd1c1c031fe0f99fcd3588059210dff5ecc862b5243e37cf83334a354e0f30fce1f2983d0b2bd18b1788838842a97ce53eb4786756d4896103760e4a3338a177efb4c17308220409c368890bc3ecb284fb1ef9112075471059e4cdaec1d5efd937d4d807c902153969e80e5b1a53a03986db99802441ec78e1e8caa29037148cafeed3beddd3021ef1a26c62a31d9f73bb9e29c6f4c6932958aef1f91a248dc46bf1fbb1e3fb5f02126d8e51b0367492b79ee850d1654cac42b4d4e5ba686241e651fe7828085fdf0328ab33982e01c5eb95d992fabde89f334f8eccb38fb0b9e34112e8128ef37e920202fb9d4d1da47b2ec70619932109db6f78d5cd3ed3583c0351f6067f128e428fd8b592300e624845bbb66e79e7f30f96fffa1e8bd7556e5e520eff793de61bc6c71308c53ede90954c6bdc7e00b36034612a2c1dba5c6280b933110c45e48e1b7fae4b2cd6b4e704b60ebf11c564c9614387368d22d5a171b8b19d5ed80019e15d90d77aaef8d23477248e2eebba74ac62e9de946678bb0aa6afb4c38f5d1fba39c9504670f874195b8b80074f53b4945231e66f13cf671e71ad4f7843cbadd3cd9673ec070cce4481518fcdf91bbe6e7f80dbe0cadb1ed1ff1099752601ccd3cbc7d047688976d81c4147f3f10febddd5add060591413a7ed977b365a3013b4ae992f1337387a53ae26ab56d6ac4f058fe969218542d441b781b8d90fda34b0fad3d3e5d6767c7654326abdacca91e88851e9cdaee0d3e9029fe95b2e6985a1c1952807a9b09e9424bc6d6c125ced8ffe8ea8f280520b1ca4c3493a809751e8b49f74d89da09b66d7ca661f0416890569e83afb4ac72ac4062deeea3ddbdfb6728b402c8d5bee75f88f186ed42fab3260d87e14d6c18c357a667ff0ff71051ad65c654f8278a8b167751026d741ffec3815e9936bc019b790d65384e192e4156871d93d2e80716600ac8b98420d700c22b800fad509ebce3145e4a0768dc30c8932c7c9938fb464f6acded64153e2336bcb0d92d4db5f8053d3f870cbf9e78e0a8b77d842fba77f7769f625958abcbca716ee8607cb4131a466ab9f7daf05ca4ffeacdf9df5fb2d1d6123128584fce6850686802aca8a81ddaefbdf79223fd935a9bb06af2b90fe236c4c39dc65e78dc88074f3fef8d1e663cf40f52bcd23d1d9222af0ccb102347feb2b8a59a97c8aeb286f3d3b3d3fb108237574ad023e229bd758e0183a29defe6af4d8732ad953d6ffbfd85b628b9c95c3b3eae0459aa94619b4b8e2a615a67a27446d8771428a8989a6115db3d4860a9226d63a264aed54505b59187a2372e9535ca17f6781c25f44f9a30d59c52f997bca2fa1a71845ef6a8335cc257582e38d488e1530d318ceeb590d565c690897523485abb90c5564503253f7dab4380e8c79214af5b179718e02c687c4762afdc84e4bf20b2f2b1749f02d232a57d611ce3da8a5a114fbbe962f931cd2f4e504be72ae65130d2b889dd805ce41ed60f67489f92f9d911c4db5ed447d2e437ed2ac8589dae7a94f3da31e1b91cf98bbcdaf6146e02541dcdbb9fececa91c5020678e93cf0c8833d36c840ce61ed7fa0ee4c5e92d917e65f391ed1f1d3af7d59557e60cb09e71e03a5c4ce1b775900eca8e010bdbd17016d6e651486ed040bbddece4850e524e2ac5f4cb42c71c7be7ca1dd908bc16f21b880c2a1cdb1cbf6947070e1e7e0da74042517d8961b87c75c75db879f7f438b99639eef845c42dec8a40bd0af6ee455b793e7d0981daced5e2eaf5cee90952028225cb692a829c5a920ddc2dc7a4728c595e0510027f68b197a4fa29189576e7934af94052fba33d0b849d167eb346f55acbf038372c4b9c93ee078dc3ee78fd6e2b2f96b46e9f8545945aa480b93829c183fa7c65afbd7bde3cdaff19bfef3b9ff44a91951a097ef0d0668c1548c042e89d62c2aab21a84e8ab0dfdc68e1ab0608a3c3ba66a64efd62ea9258662a6d4d34e7ea34c4fa9879962c40011095ba62ecaa947e8eedff6c2879998e18c47135d97a608b04fe33852af028272b6b1f14ae050000000000000000a0ef0f0300000000f4f7dcc72d18f970743346808892170483155ff1e6ae6a67a5d97910e8eac4303b521671ff212560433ab1363088c28816424249443076a94b3ba0687dde539f96f89cecc10bd7e06f2ec3ec3b71198c8989e599ff919181a86c4a58f0a02c9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bede59e25a46627a9d5beb9e8a6572a83f7c1cdb1c193b9d182c0a6033ace3215de28b8e9bf7dfa40156f839be296f5eb3cc6e3128ea9d304e2d2861127c82e9f87055ad065ba84be36b81f0d10f50fa65339d7cd6bdda99d9053d02717fea4622ae0246383623653ee00489179e6179d9396ef41208aca4d4cd8958190070430321d2e3aef8fbbafc757ceedbdb1067bdd19c37d5f345b22cda19d1285e7fa65d02212f8b22b2c1de5d9e4c4d09273256ba368bc53c119dcdc36e25fb65778ec7720b092b2b63fdbda002a9a1d219c3cd0944cad951943257295709f15b15b70faa5e0edfd6e8962c16e05b8c9ddbfb090cfaafedbaaa8d3ab6fc85f11ae6dc4016530323ff41a46a086e3416791012ed634182e44dce606a65e63f4d62f5e083619c510326f9b0310d85aa749ece0963751f33cae15a19c3c096dc31e605771487aeb9e00307976ecc2f023940373920204f80134e8b475ee9e668e2dc2a8f8eb5f435b83b02290978ea3ce7c609c80b89de68f8931f7fe4e812e797c822647eec62607707f00315d740da55f4a28e8f17bee736c2b0936c414db32e7abb6eedc2acd74f658ef572a80079f66342d0b81d89d16075b01c3c7f03b351cf5d193b079a6e76dceb40e63ebed706ac5b265a1bfa8ca8c7816a05646795e9e6f3a490b0b4919b15f1585443bb9eca4efac0917b0f2fa7e9fcc052e2ec802360d92476af448a2bfe17ef77ec080c65bd92dda95b18cda55a99aa7558817c6bd5800f4ba9ce4a8857a7ac48ed259793ed4aeddceb949c16923c537b05c7111fa8ccdb56be7c27b0bc2e0e21abd4f861025d569815e9670fadda882d09c37a14fffb8c21710550995a62fde76b06f4fd8b3d2a2789f2d2f0a3d435635a5bc061082294df901576980012a0ab04cc46db7e66aae8a0efb0496ffcb0fb9ebc60426de669e3bae7d0987b8608e825755621e686ea1ebe26f769497c20406d6e280284bccc9b098501afec2d912d9e38d8966738f4fc542f5a51415a7f38d486a62f6429eece0fb5d88ca7a6d11bdafc42556d06c316378223d52d2975df3102610763e4000d0bef3b0eaa227690bb6726a2785402ec2771886f78a462f2004db996ea3287847bcf2763750d34b8ff894891c5f3633c0ceac05ec319c11a99fb5b83f04a9c2e9fc4d9a5d496c30e95daed0f2d1e24b6d257a8e9aca957342885ccb1009f923d1bfdaa4c4dab1b4a70b045eec95bc21b1efc516746b6cf65b408d2757138cd7c296039f27b5b59d6964eeecfc998a6bf692d1f95818f87daa472af62b1963157622fa1655589979d1d92a5d0540355f4b78887d22b3363ab7a29f10c8f0681472f9b50cac4c786c23d3541af04c4cc86e816e124f115ad360d650cbab6e036287a4bbb45e64b1abf51dc44a5d6398ae9685b1d63815f9ca2817e2d8191afdc4d005a87c56c5d9fda4ebed80a9cbaf5ce048f9395467f90b1a51c26d38199766b3de29aac6a085eee30e2fdec47f9827c56c1bf8e5e968dce40680618d2f123f306b30344dbde9310bf0635a6e2768e00f6c4f5f11294588e85c5e6621a92f5eb449511fe288e1c7cacb72dd4766e3903458015f8f6228954c23dae2da53e1a5ae48d60ab705c358e27d7707221875b2ebd81541e4fe376622051f368c7a561db842021815a5f443b6c0aec01350481f75b7b23d85b74e0acf234e024c5032041666091a0eb9a8dbb87ffe9fef1a6c9fd8f9808536c8ea3e18bab5f361dfc655fc3bad97d9606af876f817e2e8bbdec8acb174d6996d61a17d5b3b70ec3f0ab077eb42e6b96aa68d4ce4598c9977ca24d8c40c7f1f3b32f6b0c6a885063fcb64af999b1b9dca758fda4595a5a2543de14a743be8df6c8fad46c479f84ca18d01f352a228983ad5ef96744145bbb178d2cbf459f1172274493954cecab38197962c4af24fb93d5a0af4e005fd507c4c8ccb47c950daf245b0f41d3bca38946fd9061046b3b47027bf2f248f5210a4dea5f910a600f0c87c4a21046c2177cd037542979b9741574b4f28dda1004c897cc80a78994317d59b1fb1dd7fa0ab1f73d4505a6d1af9527d910fa1c599017d3b6894d0ed6ca6505f91b9c6fd86802cb6cd2da4eba531f0aabed267a26be1508262b67977a766eedbb6ac0fecef35e6fb14d62f7e25bf99cfb6755a9675e4bcb5c11b6928a68f241acb4842aaf5108db874b15ce932f9575972664fd9e872c6c5e4e7a444dd3644a9814beb42f3fcde8c47ee09363bcada61aa89c9f58b51c71374dfecabde27dc1b69d8d208c4604000000000000000000000000184ecb82c5c24d87b6ba0b59e4b13178f53cf6e6b60e924c51410e72da78715cac675fba516ca207aea71eea8084d5cc9e22fe222e4c7ce246dac90714b149ba86ee370e27be2fdd02157869ff75d0a11f1b3247073a490cc9233a32bee0f993000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a9e33f41bef190b94446e96d35a9e6807d07f52b7ca606a4e21a2a379fe8529dbb6f897ee0c65f5b25b74219813be5b2408315d164fec0a7992b4b1c95bcf3827f461f3a7022146abde4d5e51cc7793fc4db45505e3e7b1bec88bd081385806b8faa06ecc9fd8202f67f93410883a229d5ab3f1537d3d4c168cc09d278875a5020c3cf8bf939439fc55ec1d70a18cc1b3881aaa340a33377318891f5ccf2a1ed403065e0c582db8d949c0ef6ba7bef45732786cd0d1928342917e9a73ec5ad23c470b1cd77395cd57cf4406bbb282acc57aa16457fdf8b294e06e1679f7d218a123e326e661d040168f15ee868e5a9840a6f2ea65e038d9c84b1ddc0375181b870c65031a987faffc59f1421653363c3d31e9aab6d3ef7cb0331d6342db8c598665b544031127dc523801efce7b322f7bb73cd4e3d36ba4ff45d47ad459fdd5f8724b9913020ec151a89be917c55b0b680d5d6032f2c76a047165df729bb6cb7369454b23f10219cbd3a05ad36dada98039c5e6b39791559375940ecb69eae23577bd1f8c129b021235ddff6660ab5a538d5e8650d40a88950de8330f9c3848a93eda7589fc2de318c79adea4bcdd83a610a1777cabfaa96c5dfceceab313d0ffdd45c91e9ec4260950acb22f2359f87d4393fdb7a6d449c8a1b548602f80305ffdcb45cbf79cd6b5fa73f78d6cf3a455ff072b4c4163f998b90bc4bb20a02848f2d1ea74809264c7eedd59bc8aa5a2cd04619f9e1fab7c3d6920c09cba91569ab1ba122ad65c9e9aad1d406d7fe32a7093af91cf9a95cd64889965b05f404a1ad7b724f588d878c36de1babcbe111d0dec31cf36d3b959869dcb85d82906b1b7e46382d1c85dc2d9c6f35e96ec6edf36924a71e5f2ccb57945c646f4c76856b1fae0878332a66dabff1447248480281347c89837216a3400bd9ddcc95f03494ddc66517fc5f439bb9320119b96258f40393d19b7d8294e5566a9a6afe1dada837b3da32d7c31395f6a10a331929ad801b48c2763462f9ffafcbc12ade324981573c4a47c1d18b240ff171b4431b5c8ca82aaef4d8b6709a368d5a3aa3a5e0d4d3fc8371cea74c20d227a7f9a72dadd4fcc359bb87024e3257f2d4067ca08b84d3f601d4559d2ea35f4fc0e1defe8b5a0dfe2dbb6be903f82521a5dc94584552832e67ef04b5514d9354e1f6bb0b891c4c52344dd35616031d4359da60fc930c7f137cc8df411ac5439d7d2b9a69dc9f092f215b7d84ac377fb23f0d34825e988ad236f53b29c09a4cc3cb0d6d22de39a4720fc4c595ab8780934ab3a5c4fc8b07db996281c11e8fb4b7b61075fd520d1b00ae5a7aa3a6d31c2664dd9d72a75348fe5422d5e24fb30d1a7cc7e9431f6db6c17a91e64747012a2ec340b20da7486855ee0d1f477b53ba6a92a101d5a0b75a3fbbb6450736e849dc40d9f07c1c49bee90855d0c0c3d1f4a3fd36cae03ea99bf720219935a330bf65f7265ce01c8b3f946bea454b4ebe580c1285dd1edf9bd5dfedd570d61514f3d99e05447b37444e90abf615dac664c9b565b97d50ba019e279ab7d775452daf1bba04f5549b10b7922b45e73cc39e5d4967a1d04195a0ba2f06bd5a6956e47eff0ea5e583824f8e63769ccdeecb17446eeb7ab136e6c98ee69b2f46dfcfcd37772298f181a9766abf919ba942c05aa2699da4c19d0014f93202c8a51f7338d5686f3739faf79fca0d584f0f39c87c0b1356d616df357d6e356fa07d33ab0ff51cf447fd4605cf157718d88a34a1c5231bb51de8f554fcca0605b8637e0e30283b27319ab3a194ce3182586c1037d5896d257d0872a314d7e56a34e203037954811094aea7aba04cf12b7fdfd67ee6c8fe0021d7b56afb4234efcb4f3951c410c84fc674b0d8589378bbf71a84dc572feb42319069fb93076c519a77f38468a9332d57c62251edda1d8813c526c06b8cf7f752a42738033740bcb8a53aeba1d4a6ed215557797eba357c981454915fc30325df67537b7429735b9ad749104a942f559a00dd2eef1bcf4088666077a78863b7ae9a8c7221d02189f81b5c684c6212400229432bc473e177c4a8f5d1ec710893a5305b6eea7cd5e3ad39703419d561daa55f5471970d6570727f2fa2b1c1545974986c246db3257007f12e66ba2f8d5c5c9626e6a36cf40d06dff6ebe069ace3c76e8f1c7ea89c0c3cee944748dae97c3405d071d7f2c2b6e0764966acf06a1450bd4f496752a5553e6c2fdbb450def3e31c1b648b7555809e66443273d0c9098c937a06ede63c81d4abeaf8ce53723ea98ae25fc878928a093f846d434d74d6ec3e732fa6770ea5119d6638a420ca14e3748eeef987a5c3e2b8abfb0471efb82ec964b3b498eeb7a0c1ef02436bde3535b66d570ed85395ad5defedb4cb73626fd1a1b7197110485df315d833b05", "", 1, -253004569, "b9792a61bc77b537792b3a5b59dbd1050556eb42fe4faa42399a32365026783a"], - ["a61ddaec0452307ce7bc47fac5f36bad25ac9410c16fd8ab2a9a936f368005e013b5d36fd90200000009655263006aab006552ffffffff278dd8fdb92f72423a1326278137298607ca8f4dea1193c75c0d620e51a7ca60020000000152f464e668c757d18dfed275b3fb19e6a725352006ade9ae60b4ca9f319ede2e5cf6bce3bc0200000000ffffffff304271c8189575bd49fedc5d1044fbd5046163b8322853fb891ef00e28724c4b0100000006acab52ac00ac51087d79024ab3630400000000076a52ac52abab53a3a96c010000000003ab6a0000000000", "51635363656a", 0, -477329926, "40bc4dbe0a8c8709157c33d09c9d06f8c41300b2afda5e516c631e8cbba074d0"], - ["84c78bb6040f31bcbbedd16e22bf9e1a11032654fc923151b501e99b713804cac000aa335c01000000075353ab006351abffffffff866475c4c109aa93697d0755df4820cd631a1489634893da3941eecca3feab40000000000265009200f193da4274a58026a78e28467f735951a3bfbb01bad79e91c323acf81a74e3cd29d6000000000600535353636a63bf2f1b48e956f61bc2d95522ec6c2a0e982c3d1d671245c1b53171f2a566709c585b560200000008ac63656a53006aacfdd54efb02edac16050000000005ab530065abe0ac270300000000056a65ab53521d6f5030", "00536365", 3, -2079048284, "cb8943842968398b86a36681e48058e9df41f6a216beed5b95ec2df9e7bc6d74"], - ["72736894018e424ea797e461de40294b30ec5302c72bfd931cd2e12b43e9ea684e1bf9eef302000000036300abffffffff02b29ec701000000000800ac51516a53656aab2cf903000000000465ab536a2e56904b", "6553ac635151", 0, -732131452, "85b36358deeb0d96c6c17c21627b6b1a6b61f065ab595607e66333a810680008"], - ["d24ef04801fc0c0214bbadb9cde4bfab39a7e1240c52ecd9eaf1e5fc7c60ff7a60f6230bca0300000003656a535698f227049b2005050000000008acab0053ab51516aff2626020000000002ac510b0768020000000006636a536a6500d26e040300000000036a656500000000020000000000000000c31cbd04000000002135aa48c1975a25e34edc1224a4339c01fa1b798de7eed24bb144c10e75d722dc2163b45baf73dd77ed12dcb778b649834c84eeb941d05a0dd7110e53b8bd033322126feaa306f14d772466503a70854b594f9797cd529e8a472ea72149356200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c28a133e6eb52e40e6bda336591210b1750a4ba7e9b7197edc298d12fa69524781a0f6673c550deab8aa6d39ba6eb8da99d215079e1589e85591b527b32aa17ac2db2c5e96835da5f6cbaee3f4fbba99a22fe772a69239f9b1faefe0c18271b6b68d738eb78efbfc023107439dc3bdd2f01cfdcd0c535aac097c401a6b37d2ea032cd063ef904abea9d1b9dfed2358219febb309fa80c2610645ae7458db109fd80217e9f9123fa803c6ec2956a211b6a867cc097f8b08fbea1a891f6e888883a5d70a2103f5fee0f7d98ddf739481a4127eba777168c3ec4a460261705d784a20792c077c51d1314b2df81171a4636c1af7dc6dd1bf1daa0be8dc8ce87dd71f9df20e032f8bd3451d5c293acc6cb0e8a9ee66555234318250221062311e70950bff8f82022c0f96f8439465962e3a5aa8e87fde380fbc07acdcde1cd26fc754a19050ab52030178724381937acb6f8dac03f7dabe096d31146ee9fbe75f0fd4cfb82a765d7203087e3a3fef9920a79ba530007098aa3d7398f152060a5e865fe2886d0ce12a2c0218fc07553ac4cdae6aa81aff3097ea85cbcdd4d922514ccd50f3be70cd68bb89b7cd0b389f5b77aa837411a2cf26a5481653045417d6c892f06076d4a40b6835e7f8e9df70d1dcbda182511148d2094dfd62cbeb8090494cdfcc9b9f4846a65d1bc3e72521d04f33af17b2a98aeac1a369569c26c9140c6ae526ada577b8861038f2557d440d61b4276207cc593f66f45111f2a5f4a194362f4ecd4e015257f5d6934810422463e7237101a5ea0d4d1dde8f51c13a798344a133fb72dda03634a83a319107cff70e92a0ce205764fec982832a9d1e08c6548b18763585388faea7aa5fc2e3dd91d82c14db270b593cf327e58a656e6da44af93d3c9ed3dacec6ff1a601c2fedbed9938fec1419b8b04300c591c893bb0a592c6194752fe79dc0abe97d07d96bb8ffaf72474ff532e1b9520bdf5ec60f3d91bf7da1661b7df7377be9beccff63ef214e8d52652401ba703f3ee5a4425889a7e9bc473744ee209ead12d8d65a873c4ae6949ed331a542b4d81e4e2572c292b2deda2e495e60dabfa440f1ba33a782067c6cdf372934d24767628feec4dce5bbd1a84d4d4f2cb6cd6bd8c01655bf09ac065f7c94ca84c285894e7aba924b422eed357f1347041ffcfaec496743fe61e12bceffa17b6fc5818f5d2594bb2be5e93f4aed1afab828dc6623a15965f1329f49840c247ad1b5a7247800dc14d923b8b694c354049b610a7380459e682a7ed936561f6613843e5deeec4a627e555a533a932d832fe136558be57c4dd8c5b313b8c05eeef087292302536614ced4481f57c7d55c8cb44e1ae629df76164c678c6fa62bc499c72957c5176b8ac4c5212016b6b4c5d84141b30def1b554d51b0d3a10eee980e91542f190dda43aeb05cae4ae87f800ee3c78951ec0fb1fbf502cdb2c21bf6f51eac4d096fa7dc9a8081cb94f0ab7a71c2169b4c9de82063ef9369c81269d44b8491ff4c577bbb47db47efe1a1e21e1f99a275d59e005d729a25849623b960ef26f291777bcbfd9dd1fa3c6f4fe881ccc6698dc54c4a63f6e5f4f9dc68e7369c03fc3f211db2fdda17ccdcffb714a9e6d1071dd602f9ea9975d7a81403b6340bae5ca2ef70c689110419ac33d571c84c8e3f69087e37c1cd7769c2ccdb4700e57df07e7615d2299a452734e753a6435d0049049bdc81f6096848d89e3eff329384b02fb78e90afa59aa046e60a8c77e75e963656e484cbf0b1a60d15987f84c38b286796af0a3dbec806eb4134974c54a7beda49756d041e3d233888769e247c674d0885a56deedcb4c8266903f1c61c7a0d885019d2fc855db6d6042bc89af78d4de2b08bb055a6054a5c9ea71a49e7a588a1be873eff0d2a3a8af15d29492e0ce81c9cf4f0f2fa4cddcaa361d0ee3098e131f60b8174630c112487d39699fd236a47744850f6edb6bfbc6e804ae3dba02893d377097ed6ea2fd7b6ff844e5aae3eed658b9da1a69ce8189ad083bd40ff5881f48f528ce1d9eb236922be4837b612a01838907d03e6ddd48e0e23c5363c8e10dad10ab79c0432834b288ee1bf9a05f7f8f0a253dfad33f2d61694868e452ff10a92069474021608b1eabf53c1efbba8870d27be59aca0228b313aac81350be8925a637953aea898a01effb1410c4aba05e305de31c325e090e014b655d0d3dcdfda5bfc2daa0781a53662ca74b60651284dc909b0edfef629078c34f96b76d611ceaf9260596394aabaa0f53c5c5d43e55029a74200000000000000000000000000a0704d44fa33d462d5b221848e8557ad251d1b2b0dbfc6249b5480ceccd05a508f2da60d5d366f24774ec25e306f0e7db776e4b7dc41939fdaae42a2b30229e5280af298c682334cdbeea3a84641af33982e52c8c5c99b8f118af4a755272eda0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060ebcc76330a4410295265c537bdce025b0eeff1cf248b167863de34cf83f401d95bce4181c4689252a0a364ecb80506d560ec1a75dbd4283f99f06c9043b463af9dfc35268729da571a61e9da4dc96ebd2a1d0271df7ef96a84047d5716a08638c42ab7781d28010bbf603457498c3f77c0a61ac96eaef21b93b469fdb7c436021be9a37bca61efa934a8196a0f8eec1de88afb0c4e3507be021130d0ea6f70e1022e0ccb66ac8fccba3885754b703c8c201df3c4721581ed377f9893dd18c839bc0a2dbdbeb146f4b66a00433f464173195ab4afefc18c3cbfcf2bf61fa38880f9db2a8d6b416ef90e3a6305f52849d9857520e8086d175793748eda8a6ea1eb566a02130dff87b6aea228239f91aaadc69076d05ec49dbdaa8d73b302babf655fa1fa0225977ddbfb48af8615a73ea631da8342429ce8d26397bb6bd81d59283640f1ed030d17225464450dd363b852031ca84b4d3da61775312c1d45ccc078278529e69002295748610380998c1203e1f7a8285363f4be967e07a1b94e6ea05eb85064726b031f0534efa16c26ae557c511aed9be77bdeef4dc36cd6db864ab4695f069870b06f9a4ab756b213cf088e9da937b082a7d3fe90af7b2be87465fef2f106ec9b8ed822b4b978de7afde737df4c101fea7365a7a8b00b92cbbbb03e466423cff3a2fa15aa8523b1a3c30b3651f7e38de3462320e134ea932c7cf990852d4514804d182bd047df7965322a1cd3a9c7a50cbd7a581fbd87d28e8e0090b64d0957037d95cc2e29c4bc696b87ee05b4a6eccf73c6526723bc39960ccbb5165fa40fa7bcef20822485c16b2c5811f02ce5a86376dc10fcee4f08db5ee6ce16ba86d0d5990d1bcfa98b8e51bb1444c77bbf83a5ed429822fc61e1289fc85a814597256626a4bc10d4baa21c9f893873a728a23697d6afa474944881ad51da38cf1a7d334486bd7864433b9b9d4a6aafbe8cbcde2f3f0a3cbb1c3ebb388b0613ac57516a468e943652082b2f1c884c08d4db838bf3bae086719287017c9ab5f01e25e8274bb86329f81cd0a4a965f8a1d1b76b1378366a02c1fd4b3b8ac02dcc114dd82ad2c6e7b2fa543a29488d3ef10845e7f04791ffd5a7b2adc2e340ccf8feb6afc0b76aa945a8d775f70aec7dbc23165ad4e1cfb585279f895a9ed8351592d3d65b531eaf8d502140ae1f13059d57b89dfe4860fab7f8843c167a56b14e8d318ca0d27c79dd5d274069f69305053fd58458c020c9521359a5e70cf0877a577d8e74f708b567c9c6ae26007b0e6df62cc3b862f009acbabc93e4b06721dad39b50ce119050a6528941667e080c1643138ae1c44ee88025f5ad1cd82cfe3cb041b0f8ca0e45208b1407fbb1f008d83e8d89dd6755806da7e144539cd83d69cf73a8aa00c5e04e5072b997f1cdd8e850d4acb28b28a1062e5664d2ddbec8618011b8eb5415883e58aed18a1c0f6b272f4d73dda6ea4c8240b24561ef661344c1d3e9049875cbf8688dee4188f6379fb5bdfe4c8f4308ad1f2de3b716ae6f7fcb1252b23ded44c9df712ae1b818307cbd883e580d5c9838882504c29510c2d1bf341db037927ae2dbe16a3812fe45f67078871b55b4e7eac09cdd761fcd2f308c8551542ad04b7db9ea386eb1148c00e9a12697b4e9015d7025dbc1653fd55ac71c9495fa09dcf1ca208e13655f1b73b43d4cb8da9314041dedb70a9252d1b51982bf8d271efefbca2bb78baca250aa925260cebcad6724402eea7b5902304db9857898b473e4ab80c0f233cfa28af3ae66a082426bbff86da24d04daf7d2897f3261ef0aa69b50923cf32c490952865ba564be70158f5c87ee9bf43c197bdac9b28bd5c6c0743616fbfff7352d525eb253668aaaff20e45cc0a83bc32c0f3654fe4994677147d6ff431f7fcb279d9ec6afb873ddb8556e5612f80fdbbdd97174f09bdf8931838b7faa99e42c240c831193d31a4e36e29070129dc98ec3cd45529845e3cb0426eeb4ad4d07bc3e74e74fc6813142caa20f059ed6030d82be6d3d111aa8463a2165875f5e6a6b35a1541afb2aceaea9bdfdb58259d1d14ca068e3ededc6a0d5b425214da6ceb99d240ed49e2e54ae913cad4e8f7915198ca032086101a3ad424340b9f15038f9865af10e600c9359999db0e1731fe82726fb320eaea658adb5ba808b4c6bf5fed917dd68a845bf5d31571a337fe0e84e1efaf425d15059a19557741d886e7c937379a8c9c6ff8dd68197810a706997cb24d5c24bbd8b54adae58e50cd1601d71b3b462b1bfaa3324da867f16f37b3bdb0db17304a9a40073419eed474f41bbeddc761f016ded91aa4c92511d8d6190cf7999d9c353322e709f7bc33f7a5dce45c8e6cb5228a9d83ed4b2fbc8051d0968c9e6b40b061c6d42e46eecb1f1f91aa0b141fd22e1d427171e04", "51526a6500", 0, 616562880, "550a3450c2b3ea42c462282df57e53d25c09e14e0e6fd1f12cb49ab9e26ad0ff"], - ["0f1c987d03d0cf72a62e2627e00211db45c7d042fa695f7420b295aa2a650e722ff4c7bb2d0300000009630052535253ab0065ffffffffe7b866040f01bbc674a00c7bca7d2a5e7d5aae6121826198633545aad50528e80300000009ac636500515253ac52ce7ae54dd7d99915bff6ada040ac740f266b4169639b418735167825cd8f5e77a5eedf410200000004ab65ab65ffffffff02098d99040000000002515238bb430300000000055300ab5153ef15ced303c8995f00000000000000000000000000bd903a9858f70d3974279028d28bb6bf0c83be93411a7d283e2a501cbb7313bee05b227bdd331625b7bbcaf0600416bd1d85fa5305b24a60f0cbadab26db665969b1d722fbf70ba2e12a2b19c724b5f035797d315114fd1795ce3af2da57ebe6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009eb1e57c77df09819b680914bcbeeed296153380d7fb6823ccf106c881bc6d6663a173a08aa00fc5956f50681e5e68fc5be829e5f94ce8c8239c6f37b0648dee648bcf0189a5ffdddfb421598a0703454929a9d551262e93c1edb467031b532ca419586b58ae6018fb0b98eefae22c7aeb7cbafa4c01abdb26da6c469d9104fb0203be28da2ae6c41a7b188795731100ce5f279d6958f6849cd918ac208a2918d3022f70932658bc1ec673bb471959e9f9abb7b282dc57c2afd62644bf0819bbb4b90b157680ed59ff29dacd16f1f50049e821fea4a93339bdd6df34588cdbb46381e71cfd88b0ebffd9ad85274efa3fe8e31565d6b57b8c44c71ea882a2ecd08cbe8e0226b151f83e79c58fa3a8a8622ec75cb3fad6590191c99042d06af05d1ea57db4021058e0184a1ca178754ef40bf8affe314ba344e6bc7bb080a38480bc3748a1780316bc512dff9059576487151e62a41a7cdff07ded7fcaddedfd388f56f680d2c8022f75f4d54a2b128bbe521f7b018f29eb02cabd44076cf7909c951cf2ade3fb26031abe2486594bf6c86a43b5a040d60cc77567a95b2aeeda017deeddbbb916110be47fb96303a9ecbd8f584995669194f7d4dd8c8c65903c314ec24391a8c85cc67a55f23a85d8b5af9d13e446c84e26ba9ce8042b21c36965347e5d02de5e26cf1a2f8ea4ce4374f108b50faf7a28c7ba54c2584faa87d92c2c08786b1283c52c65343b47a770a2d1b315a6f9bb49a417d42ca4a711484e1f830bbfd60e9706f8b141422449d8b0d9e3aba6ccad0046ed2acf96280e995a629df3013575e1fa43f1ef6ff43d35b34de2add1bd5859cb6308fb774c04183c184a2076524dc05e2b2372f1e1ff95e842721911279212ae46d243e54703d0ffc18b6459771e25f417e79d5ef85fa100141586a0764aa6f563172b52bc2071776c7f16e2ac85a80f28989068848a9aed74652e809e8d9cbb5ae40b13c98437d00840566e8bcdb367ad915d989c618f8a6d3715c8a5eae7510fc0fc58fafb2a469df99ce0eca583ad04bf2b235b94a8a4c11204305624782a4c6ee33c65dc897291992b097073642ae097c7abe33cd0cc5baba447d29decc864de0d2ce77d3c3afec4bacec885d9216131c80650df2cbd80a75c5c7483c0d7e0f5df3ecf371605b84318584c8348a661195254b7723d743e6737a19841138ffb45a5ae5ad748a5b7321ee1406fb66d0cad92de74f17ca191bb0de36b4a97d9fbcd1a0f390da202e91a1e7ed3fd899de132c6093038aef5f0d513dec679c3d7af92f819a797e8f7acea8dfcf333ad8317b44de245762a30870245f1375e3c6d88ed3ce40bf72e98cd9d1a02d24b7fb54aad8eaec237581499c42498a7d713ff3831607e90132b823bf78540147ba750941eb6d4136aa1c0217bd160362877432c814937f25a5e55f0a1a47388b4ce173da82d3c26246370ebb5efe4c43e5164f14a74fd2d24bc81055095ac2f07349040b67b9b97609f535f569065e412aa6dfdf1d85d16f901e2e53e285a9272f4b68a0a85de908499ae434c78f2f2ac7caf78423694f81b93976dd0e3c3b5ecf2879379dc5bbdd7aa3914fd8beac75adea5d91eea600542774f1ee3343fc0277f3373a1349221847b65183bd565f5b875ae3053fa6f56584391426bd304def28bf51609983c397c2697af3c4dd4d21e75e8a514aa94fd3b0659a009adda2c331b1da1136c3c6384e97c1c999277edf9acaabab60943adf9b8cc8a9e1c744cb1090d5718ea9bf74735d0ba573b017b54b52d7ffb81f99b7718f892d6f8295bed370e0dc2e06f5b48f5c5bfad74adb50d56eb9af86bdd3e1b28172e2a92174259f2154016495477f405dbbe6fa16b33e6f123a35c1f0a8c406cdb8bf8e800f2a7287eef02f33a4422b5128a753b3af5211b8a0ab40fd4f31dccaedd590fa902ecb932bbba3b58ae7a45eba3508b610c1912138ec71ecbac93d9aed8ea110c1b24786adc62e390752ce2282ab05795ac2502b5b1d2a8be75f32dfab93411da404800453e0159ec254742f12516a9ddca431ac53cdf656fca2dc9d2cc23f95ca0e144d87ab068b5dc67e9afdf0e422763eac1f25ee33cfa4a59e90ac389c3d2a4b862962bf566b3636e6d73840cf3db1ab1967c7e358d391b8b2c848354e82fa89190ea967e033297fff42d7cb8c2224ecd8889ff9605bd64f7122a9741791edcff11624fa851db3606ec9e936b86b56e926e4b136cd32f5210ae70aa89b42c7726a4d8110693f3c0c18cae286628d34e7d700e680a9a00000000000000008f659f01000000001427eb266f535c9064084b90fab607f2935fb0a78e49d2e4b252267e79512ae9b49210fb1e22d9fba7c6eb691f399f83edd2601204b9339cbff5b9fb5d2e85e59bcb58e6225b6e8475e76891bd15a919f0f3edaa8fb3667e76dae009820f4e9c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ec3fe26a08b8dc07028f72d26b9d184d27b1050d341ffd6575e62451210e9ed61e10286989f77c8ad295028a40ed4845dbfde53f20741d219af23f35f6098f385ee63aaa9a6a763d44f947f9e53174b4f61ebad091bc4cfe913274e81d791aecaf4c85bdee7f40d8fe632651654c1ccd5a6186c21342c1d1f84fea250c0efd8021151cd44449fa64baae5631e9028c5a1b81ddf29adb545d4a0acde012fbf7a9b020a7e12fe972df913ec64d23cf7bb6521718c57ca09fb4631a14493c0841e76c60a1acd6cb8eba15be15e154677155e9d384db76f8fd213566b771804a01aa96bf11ad730e17ace2a633cd0b46789ac1901f77a68034ff5f6a23b6974f79f6512dd020ae7cd70d7d877a428a7c9c55fe4a5b109cd61869b918c2a837423e5083585d6020e697b2a0a93b2e04c18c4ea4a230fa7cacdd226d36fe027e7dd5f1a51f92b83030bdaf4cbd37e90a7d977aeda12f2baa106e358a78271eac28d7ec913d7feb0e6032c2e142c28065e5b19368e8d0fe9b92a315be9f39f78a46c3da8e913bf2ff59d032e150ea73ae8d3b6ae9a94117a53b56dcbdc1f09408b9f87957540be6d6edc1cf2eac3fe04fcae81801ae814100a33c3c8927055f12f4687574e2d11fc9bd0250930736d084ab006ab062e1d7d231c85da5ab3d325ab5413362fa2e58d7fedab7c6dddd49e80d8397e92b2a799d67683251267d5f58c3e7e80678a61ade049a99152cac182c29b14c78604d78ccdf1cd92ca393e0bd759d64247719edbe7523f202b6410f8b054bc9411563a937613624f5439ee41548aa1fa0d6c2ea04b9c03bb9b15ff897d705c1dba1d5e52081a466a8b7018f6be4e2eccf1d4d7b276fa9af8b2f1b1d30316b63a4cab320f9e88a7e97c5ef0d3df4b5ac1d6788e8d43dc7bcbbd9dbd8cd3a983c1b1e2f0202d90178ad8e7086b60a27a5dba0b557a98d1c9bfe1c239a689cbc5e81e572df444ac3dbe2d0b5dbc1990e18b71254c12dcefc818e400c2112dca22f7c45061bdde1f918ba3a6a50c011c42d35ebe395b231afbd03d6040a0c795784b56d08106d5616a362bbf2b498ad25d3d4fb6f87fabe5118fbf6352ef91a3c1e881b33491a3e9cf287d5ce4c1c525d929fb6c0d802988a68efab3a060a08302655a4a9d78b118fd423a91ecb97fd1d49b09d2e14725dc5c328832e4e07cd112ad5fd0ef6616c1bf160b2f94aed7c05dc13fff096b82157c7c17f96109a40021a67d25d577916eaa2f43eddd352c1b225e4ab3da13acc0087bd361c5b2bfca32451b53c4cab83dc18aeeb3184ef0a4c230cb79136f57438395d766a7cadf989aa0e9e9af7930c704dd95201b320c5723b37e65091e554313dd757165d2f24928950c29cebd31083928f390cf537d791568555131e27daadd3ec1822176887edf4de0b28305cfa34158bdd7bd8ede800667140eea8f865b7ce83bd1c720d85d783695d30f51731fd81c65fca06b07d358666f938c6b96786df53a972bd53d1529b9c88142880472ffcf678e60582917eab6b94ec3d6c11677cb1247dc72936c65903b0d9f4d195f91cfc08f2057db18948489237503d67f756c23528ec43b1b27985a355f3fd4087289058ded33979381daa8395d6d37d2447fc99580abe3c637662c8608dde027cb1bd8575cf7c08a565e9b1cbacd6e31d111a80b67909644b78fa59ee7e7b4ad0bbecd76ad77ee485cbaaa2cfa9f19428292562f416b7e908a6ac9cb3fec0b6acd6ecb1805192fb8ba4531280f6b763ef64bba4ca0f7b6bf3a3bb493ad24704e52ea3232dc486b4f678092f5ce63aeea34cb66910ce91d6f0e1d64f7782b7f122dc115e63d86cac55465a7c46c045af5ac85e483d0928b478c03180659ab469c6d617d0c67ed7308a2948300dc02374533d55cd16421a39099b27a0b0c2a3879861a18ae63392c81c62df09520a0aa2b16dd95470c7f1afa1c7e0a560f718e332be26fbf97d1b5e074148f7a5780a7e92ad1bd753bc226495de02232f5c371cdef06582c699bac566455e2539f444d95c01bf88f9f3d1413116a7c16e521fa6c97f2fd6cb0998eedce5c55841050b2e8128bd6160202673cc0e95c6dcb83b1a2e45f03b888c1770a2cc9125438186b8020a9c0111ed25e3d71d3b7a4076f5bb56a9ac9aad3115f5a66554320ac1d35886845db5fd496f44802ed11b7afab8710999b1da0c83749de46f80c0e4418944a1fd6551143b99e53f23e85cdcfa8d12b3341f94111ff18d53c52139db9fe32ea028b7fc1bdbffa6be85dc302ca259bc6f6478897dd6c05000000000000000000000000b9b200e72bc4c09f1b517e261d2886b24012cc68cfc9e0d4fe819a1ac2771bbee43ab800797345d6a95ba486d5b2f8b855bb6f1b936bb6b5e89fd0407b5b3140297648f8c68ed2c820d6d1712179f961e7e1ad796cfb3d2fda30ddf59d0f6744000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3e5ecbd404110fbf75824fe5dbaf9b57b6133fde01a77a7e30a6cd018842fda6f365a353c29f6d262e2cbfe20cd0a8c1c624e6a6e4fcf97856e532740b5f7f563a0c47fcbceaa4d1fa8429d00b2f5e737454b8b4b8c23b286a5e440f7ca3f35c81ba621cf898d3e64d22b32afb2cc5e209445b9fa8d415cafc5a64f28489690327bea66cccb349325912e1b0e038cd37806f856ab75e19cb2648a00a4282c9bf032f6f6fe0910d07b99ebee5ef0ea5ad34266ecf33de617fa4ca807c8702c671eb0a00c1f8a383bdac14827e4be0572aa8384d12b357a9a13ac831338ec93eb641810b4ce24dd1f52a2f84c289d4f0ff33692bc7aa68965745c7f6e6e0cc32c0089a0313bbf94763175d3643dae025de45bea2759115011cecbce3eb4c7ddaecda1d5c0214f5ba88684512410c7aa2a05baed28934b430a1738f13a57bffc7ff7d75e2020300c446a3096d56770505c677480918ee4e946c7561f306b7f1d7aaccd177c5e3022c7cd94f3ad32ddc6db9f0fba3e5075ae77e581a827440f0c263c800a3b0b7f1031f96e197f06a9d2c003305bc8d81b36b65159eb3c77e024911f080f2e08699155c4a8d7ed28aba5fffd234391e0baa129c4a98aa6c415b5cef50803ba6c282619c1258c07fe6677bfabfe2056f76d4907636e3ee58429d63f6b524d2d3a85436f1bfcecf943a6f69a2af29cd1e91b99217a8c355769349735c3350c837acccde4810aaa83fab2a777cefff7ace26f980589b70308e5d2bbbb60cf64cd5c09882342679506a919ecf6360aa5c3982c62b1dc7897757e7ce016b69c42e62419cbc210f6a5d4d06f57fc9bd59e3a1ded33e9483d09b6c128b0d68aa34c50f22cf38cf4af401f455409e1eb58099c5e6f1346ff35941aae4d0e1a864327ed5dde3d2db9e16b7037283290fdb128b6a1b23dab8af931ba26394fed7825ef7efa3f322a17589f3bf77baf8a93e74407ba90b3c377750a2f25b1ff8b56c2c72704635927dd8793095b394cae822414ecc3f39102fb69306393862fd6c81a977e3ef30b68309c92bd358d627265714add08dd5607a4fa0e959f8cdb2ef2fb4caf0ee9c20bd6861fb4c03bd132e0c8bc2d14d80b0e501f06bc01aee2edba55c743d7e71690735e8297857f5ecb3ae626f23288acb814cf6350a40ba1c311798522e3a0410a07e14006339a054536f63a73fe3464b801f201f11ba2615dd90ae63486ed67d57e90adbe109bbcf69dd35367675066d13fc1b77bc62899446021d1f7f0c2e5c532268e2acee12cd1f5ea07a1e57d5c9f6ab30a26c426a708c31acd9b6e39e55dfc81c8897a017468bc011c81b0aa3631725baed749eaca8ba4509d114259c3aa23045c98f847b4ba38383bcbce13038286999e35a202ee1ad57ef38bb9ea7b8ca9c9d7e301e20d9ba3755354efd81518af5a296c227ab188a07e46d9e8cce4277ac837d78c3d6c022d7d0d71dd84c0ff3bc6c11b24dde049ecc36d294538cd683287bf00c551330a5abdf40b26f4beedee1cde431370a3fd0ea4c72ab4ef3cf95c9bdadc15e0962b5bc0cc8288fd4fa660b337245ab0df6152d91f18bb2e959ed42e1632326664324211443f745600b2df2d89ee106c3b7adf7662437b8ced7872bd294fe73e8df44dcdf0142bf3d6f52f98fecd3e11c204cc2422cd5b8912cd174c1120ff1f800865a15ef774337e14359701cef17bc0d08af760b038e7b40b95ccdfc6875fd628b7a4221f2dccc96420da9325f75e149175d3a8250dd826f3bda65182854dc03e00b4fa06f73f5609527e3cb1496282613024d254fea3b65f20c757a4cdbf9ba99b41b4054a217590af69f59c4b28ea90cb606610cf2403b3cd0491e9f2897ad44d7c933dffb606adadafe709ea234474335bf037a02a256e30ff5f96b713e57eba6df62124b13964e45ce31e3aabcdf7e79bb67930980128bada151a612f1a79df7755fc73e8285525d9caabc181e8a10cb1ea1abc608c6103dc0bb2522fc5eb863d544012f948ade9118e5c16624d420f6f5287233d68e7889e7d8ff510f4a31cf611178a60cfa88a31e986d63f769f7c3ae523ee4a8a7d33f565b87a35950e8453173520c2684b9d74fe8a137a625c3f92755b13ecf73110c2bc5e09f84fefeafdb4b68efb234ad6e2377d00212309678ab32cb981347d04fe140ac5c0b14940d51ca95de5beb4d7a8aef66939e9b1d041d822b228f1c8af453e2a23a0b1ed29f148e3edeb35581d97979739f1972192037f0d454a48f70f0f75439807095bcb6ba205b496b857df6d0258a705f10c5382bad9ed936904208b48aa3ab696bc983c2fd4b88a162bb7490adb11d47a624441088b2f3448b885f3ba24f2799c1aebc84c17cdfe71a186971f5626ec1db695f979b606872a4e5cfd2c33953061c1c8587928d583c9f700e", "6a53", 1, 968570945, "db97a44659afa6a8b8dab437affd047b78b5e8a528a2e7aeef971e588bba9441"], - ["749d52af03d97dbce330b9dcddb01aba477ccf318f1e39521577578ffd6f715f1d28e476280300000000a29bb643fd85bad112e8ca8a541fddd34b00c8315c86cd6cc86138c4d08d8451b35889a30300000002ab6590662a8d7613e996fb1566a0d78f435301b4a6ce4d2f8323c8d3e305dc75fcd0ccdec52b00000000055351535200ffffffff014aa40c03000000000452006a5300000000", "5265535353", 2, 1722198015, "722cdba9d2cd57d981c90a50eac8d3a79c5f1e90b40390cf8809112021d1c517"], - ["b10018dd01b6598f0febe78aabf545f890ad67e0f869a56a864a6f81861fc6183b050344bc000000000951ac5251006a5165acffffffff035be8860500000000096352510051ab5300abe737fd0000000000025252b8cbc50300000000096300acabab6a006aac9795f0a7", "6a53", 0, 1198506131, "0ccfc41fd78f4185055b65b650a00c0eef0f1efeb281d273e02043118de0810a"], - ["92acf4d20342b456acd940e834770017fb19115c889d6fe2bed5f56a9677383dc807df05fd0300000001651ff8febb5a2da28ebb29598f70af8fcd85aadd928accb42c06721dddecf305067530e4fd02000000056a52acac53f11a73e22717203d756482483b9031244c50898e8d65a725e5bce9bca5df00bc14eff418000000000952530051ab53acac00ffffffff016e73fc010000000001abac784a53", "65005152", 1, 1544025466, "d9403b6a24a00f08e0887c6294e72f828f2f392c24fc70775a370431f71f7937"], - ["1465af2603916546bbbb49eab4cda6d14d83f361fc605a1536923169fa10cf74e0ab4e2a4201000000076aab52526a6a63196a5bc55c6f4733399b88e76264c9391788ff4cdc11731b26fbb9549be0340fcd40130a0000000009525151ab63525200abb07604c93f25ab7078b963732d27accafee671b5cc09d24d839dfa43ff5e2628280a034d03000000016affffffff030fc9a005000000000452ac6365d4a1ad050000000000f1d4940100000000076a6a53ac63ac6a0000000003593536000000000000000000000000007af3e76f4980b702387e0afa5303db62717f7fb2907f0de7806d1aa17b24b0c019b0754b34871fecdd2427258e8bae932bfaf0f5406940582859cad20dbbbfafefb6ed5440c6d5f8a92177f7f83720188dad65629b2ea0f46193add8637906d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d8c6ba008fc8f02bd45886c2a5eb995271a34cea289fce7f70ee8c216de2837b42ac8801f1235723b400f78d52beabf5b1deaaa4ce8625866f019e024010d9051452cb487ba8455450ff1dd86a13403914377ba495f674f69f2ea58fd3ed7de831a21e28b0bf2cb070684c63fc3dd3ed247c492e863513a0f1849127a0881940211fc3fd78b78b35ea65f8736e09d5ee78ea9a73fd68452fbeeb9d8f478cf9f8b021892eb6841e3bf6003e57f9bb65b494bd249823f6d55d48247ed75db022839590a06ed7e56090ba2469d191f83663904a164957f5780a4cf57c3027b412210d94f2128606059996c1bf2f9899e5faf4924457cf064dff0b903ee3b3356b3a09976020b94e8fb5561b5fb7a59bad897e2ce84ab4eba6647c7a79559ebd73fe773de3f032ff07964ed66b14ed46c37af807840692e02605ea063796208a04642190375f003209c65102401b8d0c4396b4fc8a818c7a2c432d5be2601362504804782bd3c1202241cd923e81abee836c1440fafdf79be9a6e4db2f338213fecee8e4bc73aab0d020639530ecd245642b282ffd5b10ca8df118c1f210c5c0cc4321d6ebfe1a8132ecaee553e0e9abe00e8bf62b851831acb3ef0c565aa5014291204777b6bc7e33c404376e6a5aa7a2d37c9db4f80ee94b14f95705ecca2d04b58f03a9c27b0542f16846d08ca0d5b064539e0ba52808e032a021357318cb5026b6a25baab77213535ba80d20a293e02e8c4e9d9a23f48334262ac3519cefaa81dfff81fd3b919df768ff2be2c5722401c6a6d7470613f08dcfe08f3c1d2d7f595951dc656bc2255acb8a0cc0ccf903e1127a242e3f67a4272d870036d68d9f8ebc08957b1e42359217513f3478d79cedd996294d722d54d7b7f7a60562b574ba70c1143dae78e3e99ad7f27be1e3a99131e4c2c1c9f19e7e0604b81f19d8f1b44793d716ba54fdcb9d12cb781e83eebef9e15c1c0ee9059831c6af37ec797cc12bcd3a80c23429e91e3458d2ab0e908c54877cdab36b660368bef6d961c7664469112cc1ac2f121130c56a104ba1f4c3d410d91822b50617aa022b8e1e69b2c9fb0eb5071e164a238f2392d52447505acb850e1d30b009326619a821506596482c383492d5dc6c3d70df765bcc9badc9de0f3bfeae2ec4c3a7fb31742a9e3a2ad04d96af02ff6b3e7959fb8d86974b832ef72414963877b95dd8953b9acba05c80f9d6f64064d5feac82c5fbd46768b5cdffa48e6d00535b5437a71e55ce5140dc67ceec4cabd166fd927c4ec7f38954f69adc257db0fc902427fadf383c8802c36719a89a3188ad95754637270e99a914cae4bd469f4a4c2d1312088fd83a4449122bf3112a34cf5179577a73dd8b6bcf239bdf7d1fa5eeb9621225dc46b501247dfe94e8db0b0b68ebedfd54835ccafdcb5cc273de102453b5fa2944c3324f8a5bae189bd99f4624d95e541e5a612dea168bbd1e7e248a8f15067e99198070322b7d5a96a929b4ef601126fd9507410557f55f345b6d50b73606c6bce1296f87d4f8c5eb2cd9b023a7dcf400555ba591022442adbaaf74e0d169d37f3fd5a529c6379ec4ccd8548122c4fe6dd988f189b6a9c4373227f3b3b6abca212a04865e9acad5b841cb51fe1f704a6fa4a872a0280318f883d348b3dd38a88402fb935f4ae9d52427e90779184ae1893e3c71d622b003e0a794eeff9bd7351dc72da65e7c9fc2b3c792121a1266241019fcb4a9c22e20eaa58f8495a5c2e3947b9ea654a4a02727292d183f6f8ae5ca14c50de60760a38d81d468a6fa1a798a02539ce095e759a2085e0fa8c2c676c39a471f8dad064f24fd7fe510d23d455c49219b2d5c8e14899c29eb2d2e4d76065722b1231829f2f15f06757d344926620da40860308e237fc81f43c7cccaf103a7c5ea3c6a5cf466cc94aac8dac53a69007a0a10789facff54abaf945809fbe3281490bbeadc5cdc11ed01efc9331c2f8a7b58ede38a3261082db5a30697f22536e363aa4192d40e71f25d065d77147849218593a9418c7370135af511697424057b0df15b3d70978171f7ab543a0e6a77556c1d93fa496c42aeb1eafba05609ac362ced553855baf8ee73e6692ada2dccd123c33d3d86991d0391f2458ebc44e86d2422dd34df251277b78d4d61ff5086eb046ae92f6616f222e98703d89d944c04396647de5b20814c6d3497f3af1674f467837915fe6c98a04083535658ec5e3e473c35edab29208be96975a9ab48e63e7eebb2d0aac4c8493436353cf1255b6ff5557c3667d59288a172c00000000000000004515bc02000000001331979ac742c7f6bc036e49baa52f3ddd0cc0e6d094a45e9f9b3676fed9453cf7748abdc3683a263df4156144412d719821c46e971407d3312e770bd5f2181ed3b7266c648c9814b40e0a1a7cfbcb806a7c831f671669e54561cd9ea7d1547e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dab2749f7e301a4c204223d0ef4bbffe0c0a938310425bfba71fb3b374c5b335c6e75350d06313e7f0de0199ee6c6536ff1c3f3addc3664670fe8c0f2963b00330c28d89a26bc5cddac81b178fee3bdbbd78e9859a34a3582211fa626eba7c61a651877fad43af7fd7ffc445ea679760a737d83ff8eab78faa6342b5fa59061c032d10536c053db45361766b7971a90b6c8b1f4e7e67d3b2eb2b2cf1e3183ea17e032e34eaba6ba5ded39fd236e4e9f94f0a1a43c3fde91713193ec46ba3d948178c0b2ddb1bec3943458ebe2323d8d0e2fa471d1ea8ebfea3a30f78aff2c65d438ae814cba2df42741de15504a4a0828a20b4f932ce4a83be74c01f325f9e4d762f61031f08eefd750500000a15ffb8cfb044e79b677f4f5cbe2ecd45e6e5542828d0260220555caeb58b03b51c59d53a150a4fdf72b3e1bbe34a91bebac2f0c18b6b33940204a6aaf7f72f4a4aa86678b405db1b21d919458f72406b39889fc7a2b0336133022e46c7afe396956e85080148071da595e3cc1831c2b37f5b36e0179a26f430fa030571582d3282fa3dc0712813d5639060f2ac917778ac5eba962794fc2891da7a4d291c09b01a6d83a1407c89694e0a14b3ed5ab080d9f95af76390b86f8c8b1c4538231087e0d58dc0c8921e1c88e39f1a7b12af42b04714a7c2e7f23e0bbd8059d2f62533a50c215d3747e6338cab85d425b1491531d017fdc1d8ee6b927bff39fffe386491e26b82caa69b3f9251802f37c2a6a48f7d7c8b44ab3b0d201955bfb78b78df7feace037aaed675149f87e7bbff9689ab5348f5d50630d77b214b822c8677feebacd9be2f390a44d265f4b0376c77712c23df227ae2a1155a2763e23eea4df15716707cad440b3013ca6e40b4158b9f20e105eecd3c3057b155443a734d6e95e58ad4204f5835e73f1bd01bf042e8601001869af091f4c24863a86e80de02554e0f368a847a5178e6c8e8900f6b356271538c9bbd91513ae3fcab36bfb62aff0e9fef0bac93747d6930e3a432f1c623e66675361bc548bf8b83c667d60f3e0d16ff5ef85771241dcd41fe76ed833070c7105ce0ec4075c4a0982552db63ee002a8d47afeee97a59fa1e73e6d33f8f3205d5b05d0ad5ae1c43a0db2f0b430c033aa4727dd60633f7819f35ed00c433ba4f1135141ef623074c2e86e2565810bfef81443789842c41e3059c81b183c802d71154f54055beba6a47d47d18be90b93baeb80d272d31fade670d130e773ab0c04fbcb279f5a23cb164987f3793b48a6dcf95894fae43985c04df3c5cf76d1e57dce61e4ba3a384844c87602bde0bccb634c66f3b26da59d9753d4cd82fa8059dfc83ea504de12fbc80fade645c7d8342d4df15751bb2cd648a13ce39b9bb9ed3aa002dfb50bc7f8b0e0181df18e1c9ea8c323017218a6c9d19ea5a3010f127309dd4050f7a1fe9513f72b5cfb68aca5865dcde7b3db3f3a49037290418ff0d91912304805c400551e11e041feb6809e6b509f32758a205847b9331f7bae16526a9b57c49c6ef4e4ae73fb6f7b73f788665ca338b2de1f1e0266654589cfcf484777778eede800940a0fb0b021dfb507f2bb4c564c404777b02b50b4b3b3c4223aae2dbaf5dee0baa829881ebf81764d557fc10d11f502510e287f058d42990bd2734aa7006c7746359d412b3c575009905d9aa3473140a1962948d9184e2494df8509c00dc342ea8e509f7f4f3a68cffa6d602f182a92ffdb16188fffef1a752494f3d755dfa6facac8b574ddc79801dc820f39defbfbc9882c07bc92b129955ce4f918a3cf85641027e91233a94cbeb806aae1e0c15d5d5e3d9de2483e139f61c5f52c30653697ab5e093f7581e6d768410a233fd7b5a62bd6dfc3519e4dd3f5cbaf7152f625a13d0002f9e394a61e40ddc582ecc46bfc2400f71f5e8d6111803fb4c454f124531db111f498f4986d9da4b058caf954c6220dbcb82fa4d1490a30ec336dc8bff1fc1ba3cf6d5ae24ac863722dfa0a07f854768ce154df2343475f849048d9bebc767af64a5cf5a459185bbb602da315e0c619fdb5e6b828836d2580dae4e3236731e559c5e8fcc62d11634ed98ba63c5809cec1171bee9d2c37458cb4b719cdbf744701167deb8963b013f28049a03aaa76b9bb3254b9180ed09f4732d70ca26bc75cfa33e168dbdf07d89d7471e41e0486f4660c9893bc774a435ddc7e4a07aac5ea566dc49e09bdbc4d316899bdd72f3f4f8f99558266e39ce0ad95df0bf6d5b245e09bd42d4a5ad4e728b1bea572a7703a4bd5b445c750000000000000000000000000007fe571bbb2e812c4a70b78cd78ff90cff57f88adfbe2fdf7026bb8b33f1ae5a37dbbc82528f249fab10c471426a342ef9a39a2cd7d65a31056d9f62dd1ca55e8cc9a2bc0a567a0c9ee0ace60f32e58795fb683efb6b922ee16f333e60a5f26b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000229c561756b18475f936fa3ba432376f80260b3f19f3baf76026493954940b8944f3af0cea0142b384e239fc538c4154b606fdf0a311841fc5fc63ea5f35366afafb1708b232ab0362b81024531f267aea2061d146b92eb81cab77bc16af0dab1f353513e1b9b2408a1c1f2ebee866b39b67e25ce096455ff850cdbd5bd350ba0320ab37a3ac35b23d7ee63d98ec182bbf57b1094295d31fde44f875a3a13b3b21020f5414f4523e2bf72069730a357a3dcfa58ee848efc03463b322085dbb86dec80b280f8947b1b431bdf8cf9216f3e8f919fa2ecb085201f42235952127218264a122b9e7b2242333fa8a808cb04d9a95c04615b3dc639161a07b2a9119d68407cd022bb540099345376e89f9e029f38548a8698e467382e4900a000d8ec01d8fc807020cae80d43b8b84120f18fee4b178f396cbafeac83d52da433ea406484f17787603146d91352f4e312c955a3cd1c6f47ed7f5f7b1e55e4b3fda1ad7e90007898d6802062819a15ddc40ad189b2adb634aa1db873563614cb6d9bf4c8cf564ff28e27f022e7d21056188e7a3c1b57b5f44b7f4d5e330640f8646c7cb1927b29dc6e816523f9e98ec9bf2bc28efa1ca6969888a5aebc0ca6998e99db1f0a3a74e05f3f3b947bd8bec29fedd93e64e1213c6d019c6ab69677ec3af870cfa57b605b942f546490f94a89ec0487c3828454482b207601e283a710b796287eafb3a60d2330eeee0d1282d38fa43963de55bf1983ad3202f2688188d5635a6b83cef6fac52eb40522878ffa2f85cd9cf12efbacb7a6e95aa1e24fb9995cc3890ab5712011c0166ecbe04b15de6c135bc985ff2a86499c11b4418d74af0eaec419249976ab1a80f02b561edc659cced2d2b01a15c807f20230cac94cc14c608198f0160509f1f36f48da82451929263f08232e5dda037873550b2b6b8d7078ad1dcc8a1f4c36674cadc2a3ba2b0a406f97d1e105d537ae7393d611e96125af0d0a5d1dce1713340e17c1d3c75403019dc6c6e71ba19b467ca141a67de50f8c1c10c90d2bf01e7bc2d1e8215bf7c885de117e064dbb28b4561df8fef0c4168a95a1007940d48c6d5417900f6e0c9d26d728b480b8bef337ef383fb1f291a00c66e5047bc4f9eb1c4570673a867731d477116023fe03014aef0e7919cc30ea1349bbf4317f994a964d16852816525705634623cd97a8e82443b54cc74753465514489f1750ff5131f56d169922410173ef4fafbb53aa501a7de0b8840888ad33beab082d82260d3d1ddb8c9d6618a7d9ad69f5cd7c9feda347831f1f0baf0e28325f683c2d56c871c3600c8ef9ac2f4126ab5ca2d958c9ea57b9837fe950977023fee46834fc8a7a02b298a4dbc13711bdd0f483344d7ab20cfff38695b19d30987369480e7463cb4e96a3396d241a7f218f9b3b62715b4fbcac1e52a2b5c3cb3bda58270da624986e95a15f368d63f1c86abdc67d4739abb481b7bb8b0b506635fdf8b92d19cd3c06877ccba8f4f7dd73dcc9eec0bca263348d7228613254279bc8800f1a666bdcc78cfaa9a206180a17f8de1ae30d080635bb9811504a4762867f5ddc55d7730ce8636704db52ccda2e4f2bef847a82ef072f1475134b0f330fba9edd9c232f86725ec6a4059ea6f7630d6b4d42bfe50c56ef8d437b3128bd311f60e83b7e933743b4cbadcdb06d6d61cfd17499ecbbe15bbdfd3d7a859a3af798e107c11947271f7be5a6b5ed87ba5e072116af7dc78f71924f0b4508689e7b36d56c368fd3292ae54649996e298c65c84de6a01ca18f0a7fd3336676541ea311eed6984f1462610fd8b5ec3b719c37232c304c18e2bcfdf9ebff6dbd8c243ab5ae348ab94dab17276545d0432a942744851e13ad9c290f82af8692d1066b8f2e8516881db2b658f3ef1b5a66586a51e275b0262c9fcc124a722f0ce68f40ea5d8c88a86ea064f154194cb9a82f89f2e6bcb16af251b7fbfacb2c86a3def22aa08dc4729e17733134adf84e9309757389dfcc2522ee07c494373670818799fb8d7753504ef7b8fc187f0081c029b60acf247d93e1b3f25581655a76c2cf40fa7e3c649ab2018c5169415cbf90f05adeda85e0f4eb03966b8b3b709a83de22c7a699d3dea42fc4773e7c4d83e1810595670bb1285a93102514e9791f3f9e7f1f74ddd5674c9c6e1af9d8d774e1dc05c9451ef8ef0a83c7a730d8a1b870c016ad291af915a004434f77d6f747a24e51c7f8a3b52e7e363c4cbadba573ad4e429189541618bebd594bc28f3c85bf67bcc8f5e3a45ddf38c5a77f3922d4bc47e76b7311da5aeb2ba31be339a3ab87ffe9271cb61ecf6b94ca4a8cd9661c5c5591e6520c11d10166860deeedb8d9644a02d313e843108fb8997f967db29e96e476c94f7cc1f3cc9cf6568f5ac82f06de91f6b8982cc879575612c05", "516a6365655151", 1, -1609995268, "0c90fcffd7a7a1b35b849db654fff8f3b71dc9938fbb4740555346f4c03f65e2"], - ["432230f301f4ac25151ec09c420c6372b7409ec85a25a4d64a2b8a47048755d5b2939242e400000000056a5363ac6ab2f7e1d004ae2c15020000000000a330480200000000046a515100472be1000000000005630052526a2a815e0200000000046a0052632bdd6d19", "", 0, -441325616, "a2deddedb2e2ab7cb40ae5740ab8669f47bebc8ba6f3c1a1c85573465130645a"], - ["ac02aded03fdb1f89354358a1496207e2fb9e4210968aab55c65848c6be62c9bbca33c0c5100000000050000ac65533057faff1f15bc5f7e08fc57d59f630e7b611e530a63d1bfae1d0fe8c92afb2ddcbbba650100000007636aabab6363acffffffff508e7c465c0dcfdd3d3535434446ffaaf22ef803ffd4d5c9d92d1e9ce034fdf102000000055300ac51ab62aa389f04a77fcc0400000000008850990400000000008d838c0300000000008f115201000000000800536a6a63ab536500000000", "6a006a0063525252", 0, 1181079097, "0d001d8ad43abc4457a5d8b1e6c39810517d5459451a5a274c73231b1b090882"], - ["c301e7a201790268bf7f418ee32b3f0b84e7d5f9406b27aecd4ba69b7b619467556d4663270200000002ac53daa5eb7e0445e57702000000000665536352ab51e5f3eb010000000001ac55170f030000000003abac65a4182002000000000751ac6aab656565b745b34a", "", 0, -479447383, "96d09221331b6a08e224ba65003e62309f8304183a3f71373a0704535b13bf5e"], - ["c3d7619601e46ff07403d2a789e8ea3ab4c6295e51bdc751d4a361eb02618700fa46b028160000000009ab00536a636a6aababffffffff042856e00200000000086a636353006553ab3f4a72050000000009005200ac5365acab65340935030000000000436aab000000000002ab5300000000", "6553", 0, -817234043, "0e7eeae3d0ef319b636eae2e9d6beda237f6b0884528b0ac0cf8b4c0a243e92b"], - ["b3b490cc0437be797c194a2a6063273c2ddf18c31598800270d1b269fc9f17f8e1eedf2bda0100000003656565ffffffff72fbd6c465c18bca4ed28e8aafa231f765509f34fe6b29dc95016acfd2188d49010000000853636563ab000053c9e35e34ccea0039fc21f5d06ba00eb241a5315243a8609d2e621b5b5bedebdfd25187850200000000ffffffff9aa2d4fe25dbb060213943d456608bbe0ed4ff5228461fcd56498487fba75b8f00000000065352ac5351acffffffff01f54dad0000000000086365005353ab63006886b81e", "63515300516563", 3, 2112582072, "feeeee394d78315fab87fbc2a82d1bb119de3660dbd6a781bc45e052c09cd45f"], - ["7881b80b010723adf5f2184187b78357e4f786707ac4f7c6790726facb60f6ce0baca2cc7a010000000151ffffffff03d6e6be020000000006ab65005253ab850e8f010000000003ac52ac8328be050000000001abb38b24ab00", "53ac5165", 0, -1702400657, "944cfac48535d715d11bbfb90eab3ac85abce145004c5521923c7fc9220adbe5"], - ["0d3fdc3d02fad2dab63a3b20540ac11effdf753ba3974a5afeb813a713f531ff5e781f50ab0100000000450ec220476f4ed01e8600b3dc65fc2ad1cccaec5ef45463e61d28f93d1ed0e4d2d781580300000006636365acab53ffffffff021ad25104000000000073091e05000000000000000000029bbda604000000000000000000000000b967babd92e695b9384cbe8c9ef3306326f97095052267a469cb893fe601176433137542e55619acce4b6d1b5c50c952dce97e46544c8e34956c7f02de29ba7ecde8a3a908290033715b03a15a6d2d1335caadae339899ad941458230b24d2be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d4092529c74f171e27d8b95538fab12a98448ca7e4a0a523f0617e9fffb9547d9df569b123f9c8f1b25eef44c040fa1772a6241542a12510ef1390e6257e2bcf2c1423d22f7cfb0560a5b1486081e26a24507aee52148152e3288268a7eade111c59cb017600ae8d499868630103839cdc837ee1e3006adc644fb1c97d123ab6030e567fa7782441c36c253e971d4ade298d37eeeedcec933d8904ffd226df79e9033062fb66afa0fe4a8fcfa732e7b530a00e80f487b5da5511d9a2107f617535de0b2bace505b1dfbaa2ea5a9d064b4dc6b8c739971dff6e6bf26d3b5925a4a3b2140b51d144f7d5cf1f98dd8ad05fdf160da8c63f84e77541725508d3d7c57279d402201cc4c39d7321903826a6cfbf312b861aef3997fe14ce0437b04d4c7b73922d020d96c96feb0f795837314b8870c41b9329040750733400ef08a664593b6759650303b944f477df31a5eb87f966df884ff0170f59debb42019c06ab8799b69738f4021c15df2d6753beccda8a1118ea1a14726ad0f83d03c5e09d3ed22ce53a379751031811fca622c07b4b39f8f4bc9aed8283480c8e191fdc38e78146019ec8163ace89ca2197e91bb59507064c77bd383ae4c309c9ffaa98bd6790de8459d46216ceafae59092c2a73fc9d6c725ea2609492673d91051cc177cf11b9588ace097b5ccb8126043b036b5aad053e44816ae193ca201ec6f4c9426baa55ba897983e46182fc577d9f05868428378f175fd6e49ed007d8c0061e5aa481f414aece9ef5c314d969bd928b0791c013f90ba843578e921cc969b2ac3045319af3dcae35a76fc0a13c6e830dcfd0f5a0c61d24301746f244186a2949c12e1041090f916eb8857868da6203d2707cb899891b480f2889ca6ea37c0d5f30b68a4281023e06244e4ee94af8338e1e2b39ac35a4730f5b77618503325e7c3c5f0ccfe47862083d9eabcde4315461cc19087cb59fc2aba7e4ccf130a630f126a98cbed04ee5c04da4772bbac7a8b1baed76c67cd89efd56e0f54b7b1c5f2b9924f26edb3792809d03097b075bc0b814ea31fc2f9fbeb7f413b6c95006fd518b3739cd71c798e420fb4c82a8c6440f5291c4ade64e2c2accadbb865b486f2674d5ee48c0b2a9b91025d25cb25f704586ca29bcdad33bb814053d9c47937ef91c5aec054430f13c3a060858838a4d329d06bec441e40fcec7d961f08ced6b6433b392be042cef1d22de662b50182a7ae8c89fe3c5dc2f18455c286f04c184aa1f947f1a7ef989ada707d43c148be212110488d456d2bf4439d7c6882d56fb00d5d0688502269c9579d1afb705a01efc4b1283fba0cb2085ded66e1e38d115ba7daf4c91b79b9efe4a4f6bb0ba89bd887d6f3f84382d9628dacf455c9b527f84188818d3b0af5cb35b5643b7df1b09389b83dc1dcd9d1ec9e3bffdea48edc25cfd80c2ac4aaacaa3855577d31155ed45662051d30827b6f603e99156c9771b7bca38bd4070b18dcfc443634d1aa68fd2940cc0e7a3a6d7a29e3351d1ed4aadd5cb3cd5967b2f171fca1da93c88ab350a784ea2d37ce86ccea403bf34f1863a749ec5a8a5c07b7f13160740210baf4f97388154517471b20e20b8c7f0c7bfb61e59ea90e287a9870adfcf1c4846f538f905890b5d0bd1df0689542913df76a549888acc7578317962d93df4f7d708a5be7f16cac48d3046330321beba670d59eceeba41c17c45f0a2cc4628b17ef1422d1c665fe7be19ce343e96a3bdf5ee2b8aa4c0e6ef5e307ebba40f5866ce81da7550ef83542d0d013ea377fa81e463f0990160b1f2c8e40941c67c31f2787d4fc255a8344d90a1aefd8b101909048922f11309f275a3ab52e8e1190dcc5767ebdd1cccff5ebbbc848d54ae7d7ee075b398bdf8d95c9c4f599dd8dbcac4d8704c4e48ac309edebabaccb3ec6b2889a58cd72023bbd504977c0994be6f5e768cbaa5b543056b01aa8ccaa47aceda7d39064c5d0b7794fd2836099f6637de2c63efcda05c2755ce752776e87d1dec4641d93011564329ef82af428f75fe829059035bfd26713eb433c751392023bdf08d8eb0f17ad9b84fbcaa6ced4ef93d1aa98209ea71bfe92dea32a49538fc1d660d2ca72f2e0030d107ba2751a667c06034fc4bc80276ccb2f32e8e739f1410749a82733e6c2c9e0c68a801af82f6fd38fbae3b90ee9e540aa6b986b9b26094c8d743daf9103ad272fb6cf405a9adc516583261f09adff7893332f38e99851d2ea7ccbf0098675a336f4586c0a9ede469ad68da365032ae799b8c21ddf771270000000000000000524b160100000000618a203257b8efeeeb6e595ac4dd1ad4b15c0293949347aa2885b5008a817147fea016c72d6fd119f26aca7802c10e58bac60d55857862e38a949b8303f66ad06cbab3d91a9067ede04432f58c15c38f3f70e3a05ab04445a81586d83dad231700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103ae9ac43f6f78bcff81f59f06d516ff046ec5618dfcc4be5d7c6ab2a16a9da2fe1d61c61227b920a193baf5430691724d71a147ebe00a6e081702133200ee7e5e9a4bfc309623ae5c60dfface6f12f2c4fcf82bafa51f6b3fb1e982707697ffed09cdc9178183d35a7983aea2ce57040a1ee475f4e4fb9815d2bebdd06c7f70217d0faa77aa1fa537ef644bffe281d9662372e7db4b21eaf370f4fc08e37068e02280070c3d9f3244798af536ab7d269408cfd1789d12335a47f2c364f5522bcb40b28ea1ac2b56cd9258879fe48eac397ffdc898d78b5aa7ddabc8d81805d8f17b126f46ba25fe36169b02551bf8131a6df182c270ebab092dc546a530719a6b86f022fc652557b55b794b71a78800f7b4d1ee608adb0a245a3b0ed4db95f48e80acf0202abe5c4cd0514837133feececc0dcc180e123ebc66121b3d931f7ffa58ecd7f021bf87690822b2d406dfe9c90460ed947f9cea689d787eeaaa3f612e04d9e68fa03226553258175dc16f8ee81ca0696da749649f71c710afd574f1d6b5831d2e172022935c8f79ddd10bdffedf84797d03f087913048ff3d762f8d7a53fa7295b0e948a05074c5e0a626708998710dbd7c1ac15ea23b91ea9e85e266f389e0678fe0917d42ceea98fec564ad188800ababeed1f79e9b52c25704666361949c18900f5f738040ae42eb822947fcf5ffffd585fc7efd7b491c18b47851250a7faab4aca9c1355730c249390e0760a80913633d73f5e15db6c4808213521eddb1ac308b19725fa15a4d0b92604896fe1ff0a2e21081d0e955a71031b124f6e052b73ed52fa087c34557696651adf397aeb0e37c2ec8cbd0d13fe92ce08bbcd34c454459b15a88ae8fa62f3eb67f421c4a4c152b20dcabe18bc08684ac0d280d2a24fc3c847edd93230a4e1d6736a938c174cc1a43b46b54edcad8a532957f56d152134e5eaf4e1d064c137883883d99b68a2246dc435e7e226b77cbe6ae1d37c3031d1f405bfb99fea16883d7dc9d37aa81784c3d826b87e69b94ec76e3fe76ddd1bcd2b90da32991af5cd4d06d74e0ce41eaf8f4c300af227a5030e48b3601b3e793672ac134fa7b2a5538cfa1659e6e4062c6f0d18a23abd2711b7f0319e780f06dbcad2a83c92bc5e283b12b81f44d096c97f4442be19386cd1045efff045920b705a09eb5f7e16571a6104798b354888eb5af2c623bd99d7ebd8704ce7ce0f874915fdf4d86eb70e75acbf872a1a93c5a1a7f2ecbc986f939882c273d30c5eac1a1e37f9fab3f25b5a9a96ff4a805c13bd93dbb33b22b4674c47d99ef9f631fd98710d334b7c16a46d6e4a46317b4a6a781ca639113182b950aea6d97f847780f0035951e05865e4c17b3b744963f28e5d1a5d568620252757d8968e77489131f6ea7c3a513cf1b96b245894469991789789d5d80e1d7c5d6d1f74a844671830179a1c4e990f6c040b57cc0d45745823bb17aa827020131e5a02402c86a75ab2d1b483d481158af8ee9f82e0f9ad3acd5c8ce92fc2f50917c7c8577b4ed600b819e00593c657c21661cf3ee74f83e119a4d0ed19046bbb6ab28dc121db3548341af8e2c197d0f526a5413a264051cf7e27eefd56a7f3c1bdb0115fe837916bfbcaf23c7492efe00fae49fb55c058867df7705146e6d5a4810cfad56c41b6bda09ac8ff6063405da4f902dbc666e6160faece051a0ffe0b55a3fbaa11692f0722e0e12144e1a58c28c10fce7de95a960272cccb74eeb106503338b29dcfb6e22ca4bae8c6d2d58ecef29a8d59ae3e70e34aa2a99144b6fedc47558b6d566f03add2c937ad5bf1e152e45545c76b262c22e46aaa93250be9172d388e8f951a4893e7c0b7919a95b46d132c41e6049315da615e59dcc07c0f9d4dff5a9edfb9a9b0bdce52018668d3d01f3117ec1eb286ab9c1fb192bcb2786edc28416ad89d2b54418cce414e86f6aa996e5700422aba15f6a2bd44745523c4f9a0232996d309178d866aaa9bb7904ac5d841d1a642e5f747c4be10e90e924580ed140be9c5f19aa03eab0b19c1965c719b53b50a96f9efac911ebb8c6be0ae7a4ff38af1ecaecd938e77f15982c53552699555e9c2e7a10857d7898832f9a43bf9263dbdedb2918e91470b70908845192e05f453872f18788f9da67aaaee83f174316bd2b73c124aa4edb44edf3e4569ba42f33df5cee0e02b98d5a5daf430a37bfee6d091f73837adc8befebaf8eb219a659bd1906ad8c1a62c20ddf5b31086cf41e0b712efc3d2fc402c51f4b37b971081a51cb78e688609df83e348057668fff52fbb68944eaa66b04665b447a31eb8dd903b234b6026b22d590e8c393e4595cc3b942546da2c6e433c487c8ab3911f166af66ab47cd46d8f13337b240ee380dd03802cb7fd9596646bcc63af6655ad9bc2041b1925fb65530d", "5100536a5153006a", 1, 2128484212, "0c073667f8a072a52d55497381934a4e350c33c82c4705c7abae57b483f41d84"], - ["89634d970348a02d05bd377b79ec5c303d175e4c2c865cd6551671d3a1a7c8629b977faa110100000000ffffffffde45d190ade6253823d55ebb5ff720d1167b5dc0ed62552207dd2f9be10ef66a03000000045100526a423559a3be47061578a8f2103f300eb6412111530da6a2fffc547e6c0190b81fb59575fa0000000001aca0a6804f02864ac40500000000046a53ab008b2aad02000000000351656300000000", "", 2, -1183668709, "4e4ba43568605e895800309260cd06e9233767e6c57e0132ba703df3c311955c"], - ["bb4e996603078125edb44d4c80bf286c8d2b83dccf0f352f4469a99b981017b8c34a16152400000000076a5365ab5365abffffffff569c13493d32578cf6e0d143952e649922433ab1fe3edd2e21e8bf25d2fe6ea000000000066553abacab5140ed5b672e206b9c9ed00efdf30967d9b4b5771399e496a2bbd72aeca4a992360e6566b20200000009ab656553526353ababffffffff01c67f6f000000000002515316d1e16b020000000000000000ef4c9001000000008ef973fe53762692895a5b28b0fb2e55c560f3f41df626fd66586e6b822fe777aa8f9908453ca0fc05ac31e99ab75086dfc2e3a64890267769537db05845f5c37fb791e4aea27eff91978b35e8538ed90a0861ef8d1edb58d5f8a5643615bb85000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a174541820080547604fdeb2186bf9f1727ee8a92d5bb2971b1ad8c614e0c5d50d6db7d450b3585fce05d1ea6765105aa69a2de1e644f1a26b0025cb0365b69c4a07ffd8f1d86bc0ef20da7639a1b6ffd0cce8beecdc4606ce1322abcc25e47e4240559ec0d66885395963ddd1ed091265b23aa42aaeec2b20baa8c8144effc0229fce2606bf7180da14f77d5de398deaca5e543728b4c9e6381567f18157249c022079316778e811b5d3214a89545d042130eb33f4b9f5e1574ab491fb544e90520a050edbbdd814ae40c02f43cff407061c68c4a4e17a337e35ac1eaa4e5e973cbb2bd5fe95882b7b28d2cf26a3ae80c470813de98ac204c1041e7b4c2310848cf803075a2855e9dad212a2d635bc8663dea374f313355b40118e5ec10635d2298d8f03136635a9015c5aa9962bdb3668b0d4400c51e59ba83b9d6de5908f8d470859880308c229c95b5afebdd48d496ce0afeb4b14a10aec76f414c5ab102946b8a9bf8f0229741b95182dce271cf6b6c18e6bf7ed462402186d877af52a1e173a0df7a95b021934ce30603a236e2529f11139ef04488733264fa4a8f9b15abb92265b8d76532b3db3d98e063ef67165eb0513dc9c303cf50b0d42e912baf04408aed41366ca77bc9185aa611598ee7eb8e4ec255fc4995afd2deef44f486880ff43023b4facbd4d56a7deb38dd22fdbbae24f73a227314043256bb8cbbd0badc228b4842745436c6fb0b5bdf3d0698a36188220b4204976f045a87fa1e41cacd2d90fe967039fc7f8c7536387b53cc3c64e955da105a536c952c79312712973ba8c464bd7c0a18876082b9f36e4e61114ed1b64e1018fe00385d01ed619bc60ccc9db4c626a7f742bea3e8db863543ea717bc72659c6346d4c3003017f052294fa1ca06727bd8f443f34b5e6117647298a3c1e5aadeb0a9f47c7af9ba9bbef24de6d1d76a28a13280ec8e156c9b82b6c1e9d235e62029a2eca899b603249b85ea4cd36669be3fc8879190849425356e10ef3993fbcd7be0be83c936c4e6fcffb63c9a8a5bd23812cf7b826f86109c1999f7e55477c4a4438f8cfee33ffd15908e823c266108f955508cdd6715c756be951abe4a9bdb436bea6e7b84e07f58f553c84529c5c4cc30f89978107e827babe5f6d8aaa7b9d081637ad78d5a323b8b3c3349ab21dfd3777821fd81e152345d116f4523ac4bc8c8fa58158b345574e5c597374f18e899d81f742a554e65658627ca245b9885c873efc153793334e51762ce6b5136cd31545f94f9feb9fc5df1fa819481b9846001a91d5f885da5feaa7e9e1cd2a9963055b6043267d177850db68d7ec57c968bd122426a12df8a2c528e4da611349da4120200db82b25359b9583cb7dac27f6c6338079432ba44ddc4f4be82d146336466e14af252411c466c3c2f7f7509d1953a90794fa10959d983be145d73e4b392a41bb72cc3084d0d663e622c2def6f3b526f32da7e227f12647da138b2bf3545f823d68fcf9f7cc07bf21ccd30aea972a4958e2e0c4dc63111671c556231ccade97a11173a97feefc169bd497d4f8a0d7b8229edc164335a7d68b10702a9d2e55b5889c43dae47818775eadc1ce22325affa13b095c63f8619f86ddc282e99da9ae8bc1910b8617f632789b4c2b14b18298fec213453d88a36a9e7565bd13c6b19ece9fa36d2fbcb3a2afecde525028350141ee94ede7c4148fe455109af07f215df20f070ec68d42969e883c10b255faec11b6d3d2e3a3d7aef4dcf5df715ebb60ec135ccfd61eabbedc0145c3172fdb84d939c4d9e4f50c59b894f1f271eed99988a34f929958f36a1cc2a0fea2441359e886e37e1be1ffb4dbf544cfe544286856b093463f5bac71f9b24f49a1bcf984e40018f5a52c69bbd7527f67490f11bb6f0c6842730ab25ef2d9fe8fad21c9bd8e1d4a9f512cc3e6bc49ef12d095bec7c78eea93ec7f7e516529cf8c23f2ea31def6e90ed4477999be12c84298aa65869ebdd50b7677ad7f42ce7833178f8da2cf21f307103c4095955b188a1b6711bde4591fef58227ca14d4ea6d4273d1d9dbbc9e88a21f1502d1b45564d8671c9b71bb6073922833763e8f315488d14c17ab2dc1c0d7de79ea00bcacfe62c12aee086f3cc0783bf97dc8c3d494845d1d85c2d7741e4f2aea5b3829751535674caf36543c8b76afe33f5a7061309176bf82a50b9c9ce03063c9583b90979069ac36326e2d4694bf4436e9eb2f47c8e54562b28e1a278398c850d6ba84d93f20e18aa1adb651340304d7ec0661a2641871a03366370500000000000000000000000095673fd59d4d44ae78dc9d1f8cd54941c617719d8433787da50afea7a32c443412fdb222a2403c24606061066b585794e62c679837d878bb3ca27f88f78ee097aa96017c12ed83be765fb3c38dabe13b41d83a2e08e20106dbc2f387a912ec29000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004eec79f38ea78fafe9f6768ef1edde8d63320007e98d0e51a9dc5258e1fca929f2d1c9fffa0a7563644908febd3212a18cc06cfff72bac86810e5863f12e19a03e5ee07af114636dd9a5c35b7d06bfe66511dd5a9c48e18aac4c18b6461a0814320499203ffcb47cf8b41efd20c979ceef5afd1a8619b6d2e00bbb43fbc798d10302fdb946fa1796b2fa5be961f965b38392c4536c9d89e0e2850bdb80b0b867ad031cfd43f24a4887c4aef3c82251e804fd99c266a44bfe3555234b200607f436730a02ff9165b47ab4c9e378858bf9fd151a7d4d3e511a9f8d857b8487a4837e97b61e1c6c7bd94e93b02ded2426e8ae9713749f1a080fcd1823b89250c648215c090217428cd2789cc4050d9654f049beda5eddbd398199231b250052c1e8dd0afb24020e9064d2fcdb9cb88b16ef32979612b3f1875789f5e1fbbf4cf56f3c7ef0c3c9030c3a22225f7421e93f1851e04c42acbad136462602667c7e83cee465e09bf3640212b25188350c6fd44d6d5233dcf718af262752ff6303b3e42a382c888ec3f33903260c6024e1339c5f910fec4b3adc63582ab574baa69c3ffdfaf96fbaa6e926a336b1b26b1066acf29a517309f5c13c17a54087b1d3754478a10c7ffe3e9dfafdabf06e4902047863da6d78eb36766f995a2c9753a9a745d0eaf427b0bfa01b932a4c785c7c5bc3e8903fbd58f1ee9353a69171a2a07d8389b4167df10917aa446e3cb59182c8583b6aa5a039dfa357bd498963fe82dec891efb8a9d14041e5d48e336d3f0a00f2d5faac67d9bc20187b7012249c86078a088b2488e69052f921ff6cb9bfe69e02594b100f4d2dfbc7a27777d26eee885e5b5ea1253d1e503d224b45675a282e5da5a2f2897c1330820f35d7273a36bb2138fb1be9cd8c2c8872f63a885f419b4fa9517b050724e1829f7ded707bac4f4237735f743cd55960a1b75ecff53dad1be864b9304465a9a033287f8bc0056a37926799d4cb889b7592b5c1dbffae18f41d104bacd64a2edce91e7adf8cfa38912ffca52294a841fb49a5ad1e30682080071a57c58999dc7fcdb8442f918354e15d2854394def1b5187ae5752c15bcf9ff930a8be1a0b7950a21c135af0551acbaf482eb990b391bccf89c97f427e802bbda3eb2d087aefbaad4534b7ca75858d6a11ba903974dabcea521afa80c995012afbd78ad8ee6de1939e13942e8fd2b3a4904a46fe827c3b209e330b7c37b8dc48e208b78612f3188302cdac6457a5ea44b757f99627cc7e39ab785f13d46c04ed388d6cc83016bdb4c5383a098f461fa39b33537b5427141cfea2afe5720fabe35839a2737f1ce6348f1209ccd9740928b911d32368c2d91c1411e91b72aa876ffca25c83504a8af8a9b7b6d8366e87557cfcceda90ad231a64b52f06a1fd3f59b7675764799cac94360b0106e5a8ce4e8792a6a8c07589918d7cfd9f290cecc370649224b271b1eaa118f4740b15993330a83c7a9cabb7bcb5adbfee12b5f21b759f0a309146448781c17653559ae4490f5f1601fea151485aa19ca9afc84617071e9e9a103c4e31e1c0bdf108bc2753e4eca718c4651eeb4839682157e8e6e19029f08e5312acea3ecdcb44adaad5939f0f68227080f164daa72ffd6965cbb5372527a1ea1bae2597376b2797701bab637ec29673511b362e5222716b6ace3a3983da48042baf113f7a92ea96752966a816eb0fe0fe7768b4a57f9f0853d495e8a3810a97114e56dacf4d8d5fd452f58030eeb257f5359163d4d66d988376b95973141dcd27f2b42bc7c6c28d5df66d82bdb3769b8ca1dc679d0505d8c29eb3d0253b62b6406d908707ff206fa4084034b74dec7e56423ea2e4688d568eefabb188fe5fa2f5bd3afe104e5ede7527b2df85ca48f5f145511bdf05c73926ff9d53aead8142f334c5396399598e7d71217678ab053a89782bdf1d4c417abef23cfddf874c1f71b08fcc6a635b3b3215994b6bb422be696cd0ee67d42b47417fda348ab7f7c0d96c1e31f9232f9b7b6be06ce8a6ac733ea42cabab7f8d72c0b1bb8f72aeb074dec504b7fff08af8991a1908384162da12fe2e2edc0be596772ebd7e54a857e227e6b20071b34ce6c5de412e7289d6ba76454ad8baa56e9dc0aca42235b00e5f82c335fa37dce0941551689d3a7dd1ab78f0ab0a81ebe77986c80abe6ee8ce4a0a07b70ab64648cc7c79f87a007bbd9303d98764ca3589563fd72c497c9cf64016c75e602dc2a6ae6195eee93fa00e7a96a1ca0a035036e1a862abf084010834e105e088b3da8dd3371a42d162341cac2d32fbc52bc79e9dd07319fc3d27cc36fd8c669a4f7008c47920e52eb083c1b65edcf398947d27027494bfb75610991d7698a624508f3a528632f2c820af6036e918beff68734c1d05c7cc00364725c91cd9569d0b", "6a63536aacac", 1, -2126396243, "7f6bf6a09ec6e56563d0b47e82e0fe82eb4a038c737f5a1b39c90fab74a0290a"], - ["f940d172020e6ce30407d65e13b5be3c043cb0e23941bd5eae046476682ff35e122c83eb6c01000000075251ac6552ac00ffffffffbc79826d613f48d49e3e557ab308bdaff79c9b2bcc9f5251f9227e912a69cd74030000000853656552656aab6affffffff04e18c230400000000040053006adf8dd50200000000066a6a51ab6aabd06dd4020000000008630063acab635151356ee101000000000098bb7d5e03f7c69301000000000000000000000000ab01731d5fe01b221c4175f7eabf53fdfb9957c5e3961de7211c1c99e2c7d9e58b8114f7e20a651997bae3fb317b7e452186d3333236df2a222d05cf3177df6d61f83544a023f04e9f0ff8f337712fc4b9f7bec6d09fc432fac9b2dea13c1dcf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f37283587292e6b50a3038d1aace7102ff00446789816265528d0f1fb6de5ba452865c724d1e5535b4560c62eb647002a5cd17927e8471c926d7d8c58f10b62ff263ee458fa8eb2122b247df0878700fe2aee424ed194dbc55f82f29896986049528bcda3f35f081bafc280906d6a57fe9cfec13da52f10e72a3562c581ee77a0225536a25191c1ced1073402cd9bf2ed01bf374a0c76e7cadf5510d409e978db50227f992d756734419688e76b5d2addd7081c2edbf1672277648b954eb1678302d0b0c9909dadab876f72bc47374495a4f112b0d29f5a96b446b8a23ef52b062af212930f9a4d8c073dadc6524386e8530ba140cd47bd868ab8eb26898c5666f1102032d078ee96da32cada0efdc4dce5098a63fc3aa69c104a07692fe4d57892d4aee032d1878d93c450e3c73fae0ee71f777b4bafd40f11c1e67f49a6f4f4d8d57d38f031f8e44699a26a9fa03ff09d96f8ef4c8285623b1dc50ae84443c93f5e3495cae032f6a8b297796ebd9f6490df07c984452ddd767b2cee94f004c60cc0ac6e85ca402183b2c2950245367af8548b416f28ab77ee92b183df1128977857193dc6c07b65c0651a3eb2447a610bdae079ddede9f7f0e3b913703c3f819acb11513f16804fe3923c0dac9c5c3825c4a9406f867dfe1d089197ccba0d76beaaba0084d277b8baecf63b892269b7033b60f718abd992172fcf87f209596c0feadc5319d3f2bd7c3f6066a5c9c84b180f16e88069c6b317c680fc085c4d8d8643a44663e8bc2aafdfb0bd84ac5980de5508bd2adcc26615fa3083d96257f35db583b3b729b5e0fe22fdbcb06575db814fd3a06faf33ad1f75d46a5ed99181f2c0b70a8540df1dec0a50c24cc3968e342b8fe6221a4f29d5bf6d19b4d61e5af57e6ad5a87c4021e73a5672910f368964c9ffd25d46d3719d818bf6dd21cf0f5c921faef2e94594e0c5bdefc6369d7d24fc974ea8457e9733278c09f932b3896d0244e96ed1dae50deb803bf82b37f1defd71c67df95be1add3eea9d8d595f531c8bf5adabfd437e4663cbbc89187c99b9ed8d63ce2eacedbcf77686e31c2ddf9dab65cc879620d1a46aa5365377fbd63bc5e343e2bce140b3f6927151b450dac48b6c694e2a11619e01978bcf1b13fecde40834623792b40954e2fd784317be9d6b53cdd902e16d5a3f843043463c5f5bae553095bb94b194c9f999ae718a69ca634c13a7721f3ad2d9aed1026867defb26ffce0e652f379c2669e56f5cc0618a88e3decf3aa81b076872c0143ed790ac33f5613d19629190e4091463a158af6f403d22c8f10c61660314df26ed320283f218171adf0eaeeaa01be6980fff565989b84cf36da2f5d08e31141669f475baff566ccc1a97895c1e93abc0f6488bf907eaab654710e5d479304a77f42f6ac802c9f7c16b9f14b2712e2d636557a5540cbabace0257e560956064f4e7e1b2f83a46bab5aca5f9efe63e4d9dc94977db7a6ea2adabc6d59a56f53a8211bd77bfb0732062cc466e39c30b3ede76c6c828cd727f0b6546929ac418345db068f7e47b33fb6b3168672f2324ea206c84f149656bc9a60e0e887c8f178645634b808d0ac8de8edbf90082ac2f5c147706c9deb525366a5e5c92f1240ce65db0e98583a4ada6905accdae579e5e8fee5770eeea3f7f50a15bbb739a4c555d0b0625f4bd4c3e673313bf2ed91f2bb1f3f3700add15cf44588314ea3945476aaf4acfb88292fcfce1616bd658f2540b7d6f77daa74da205d8cbf67dc19dd93c8ebe06ff28b27d1b5550d6cc399fc94dae8e7fdfb421f9ec51fa9b2a642fe7954ee6bd4e15a98e05c52d8ecdabc103bf5d9b2153c4203c49d7bba65b43563803d222639af9fa84e3e74a32074e6980b862c77027cdd1a1fa5817015cb7bb43b237aeb2789cbf0a5f1fe619698a626c625cc91bad52dc651d76e3e1615c32498dd48a71ba92cf3872018effdfa6d1cb2aec293a2e564ceb9d0e6fda32d2f32b4a57ac5c751bbe999edb16949f66f217402dc3b3a086a811805d454d64a77138137b65145fb747d6add79ddeafbeba5b222421ea71b48bb313b0e85848c59ded0a69e5f3941d7884517375cf831ac6496281a008cefa8cb3cf9591c822deee6c5e5adf2916c1998bdd522c51236ab02b3cd56c68501122d0f85aecf8edc72bc91fc44927e365ebb001593baf3e12725a06664aa345e3ddf992e3f46881904a59a8f54d45a826367e2ff8c033bbac052206d9c54c7162b919af3c09da0ae0bae2414870a5a1f3b956d5f62d0a2d9000000000000000056b95805000000009bbc0294528f2050c510db4c90af0fd8035fcb4ba7932350df20b8d27a2bad48b17fc2eea127b0508a88920e99551e3e34634f1d460d08b33836a626922377bfedcaf22ddbf66393b14b1683f06c61166e8b972d725ac0d4f90f40a00fe7f52600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd24cb07a154d9255404d74d87c083cf90707d20cabbeb54d144f9722643acacf9c593e6f8347da755a766ea4d5c1aef772fbc0da9441ec3fbdf2f384c5721b122c81530759571ccc4faea8605950c8a7f277af2e22a902005cf5389d0ac1cc07563fd46cba0f3afac7e96d2ada05e381d12f34fb8da0c8d6fc15b50e3b0d05503046795ace7092af55b415b74bbad8a19bfa8c657940d7beb705e88350ec1b82d020ac30abfe7de4bfd395b4c6c044d9c0fa24d9aaa6fb5f53a3154f8316c0cefd20b2af69df37fd4c161ea608e3e3e507439faed3185ae4a4182a02f18e81a8ea49224487ce053e20489deb2919aa2deb9d47beef1adb189672c5b35492608ad073703021f20898fb876643d4a4d5878df085270ada308c6f0bd4f4e2e5072034dc6190301e1f26a1412dc6d01843787d032c1a44a7b2ef16d40f63ca34dc654273bd7f003252cdb5489cf65f385c7ad676d39121ef836c050c5b93f73e8acedad2d49fba00306724be3af062c4f6328731bfa511763058de4e557bcd859937823d52cac59a00212292dcdc0ae3785286a109a4c1fdf297e7f244d94ac0e01cdc6a074ccf4e81bdfd3387fcfb7fec1b34df291bbf4d3a4c32d278f335497cf1699e00a393c0371d5c00df1ac9388eacd76918099a011f5736a79ad0604abeed8b5f030d07afc3400ea84d46fd1a325ba504495d0304f9bb2ff08e371b046783589c0ed516e9a1d832a89df3cfebd7b0bc89732f5d6d560f57335563aead411720f418b3685416611e6f55bf409732698f899b70a1aea18858bc69cfd39301cd472fecc26fbfb95a7fd1ae7abdcc1bac6b949f0044eb4a1152811878f42f4354d7909b18dac3d20154e80aa213677c0b9ee014e58472ac7934ca56e41f4a5c9c7bc7eef20c4cd6e8564368ba9cf35cd4d624790b45f2c5752d8419d8853d52cc92427c01bbc32201125b09648a704c3c70fe1c9ebc7bff171915292b2f2da94d3229dea579affb4158d2a764e5f6ad17c57f17ce287484a7d231dcdb4bf54e678d944fb969381e519773324f0b06b710d30c34be8c2580db85e2c094dc398618c38514110318dc55e3ce49f04d743f034c9699ba4fcf474fef9f273af563a569dee158f65216ec88e3f22fe17e37f5890cbee307d8bfe358b470e8cae95569daf502ce41e15a0ea941506740ae274e2d440ad7fdd5c04a177e3e59dd9740b9b16b20f33e59a2e4cd5449f4bdadcc52c05b7076425d37a56d4d5fe2bfc86468b33b05f33b8de1065e8b763acdde296d9860ea8be57bef211f972917c0cd612e444481a3b09c21903430f1c761d2b6d6894486f87df4498400d5a824874b4556f8dc569d381b34500392f144c5e3801cae195b3f8a0f184943725d6abb77fdf598af9bfee305940696d1f2bdeec12225e3f148a3844154a59986d39be1328368bebbf434d8d63d5335c62f2f42d25afa756ed24f7c75b9bf32ec5a6ed441d9bd302ced84aa05712d80ae6c0d84836283f8b6a33e3b35cf934e936a4885e28160f0169b20a4e3bb451b22d1b74b9ccaa2aadfdc8fa77768f01a59ecaaaaef9a768825ec7f85003c81a0002ac51c13644579a9253150bef29f4355db646b065b3e36f276d59ea74ece4a2df0da54fa225cbf13b745cbe51cd8d2d135c66a06254d9b01cc6e8dacfcce30ff6e31b0eb149e6f9564d5c9ef4f755e5cc9d8ae44ab7bbbf0da7c0bc890c79a1be3b1495cd46b09540bb0a2f58f761570f016b6d3969b91f1140b9377b47d1ac7399add9610ae76e9ce6185ada417f6d22d66788c387cb419d7b485dd54bef00901322c4bb42f70b6d59ed5098ae7ecbe1a37ede2ac393b8a2f98671da7af667fa724ef2283d3ee3c55df2a2724f94b32bf9c8ef90e5d509d03b641777b8d7ebad9ce7309cd33b04f9b5f49be5a4ad65154ec045a00e7caf70d4b459c15684fdf235972ff34f6061b8f893c388d1da3996cb40b8a69c4899ef80f2dc3dc8b71518b6d71ca68805fb467c11a0a3a57c20ce35bf0a885431d40ac29800ce881a544c0f9512bc9f1ac9a0cce0fc3a78aaf364f87eee4f137316b7370ce585b95d60b9fb6a91ffa2c7eecd4fa563073aea51b212a2d540f9dedeb082fd6e4e4a793e62faf4e14dd0829e46df88da05e58615d687b21f6a25b3654c6a71535fa3bd6f74b26f504f461b1485e7d0d140be8afc970157fd69b34a253aa1197f2ab8e70c0307c33ed369b519c36de4863be54b690c8539f7768b17052b55afc22c3a83e3cca210ef216ebb86f1ba057864747cf0ac0000000000000000714e640200000000a6c3f86361684c3fd9825f7d19b9734713140f25a15453121315837776c70696415331698658e322cfa843170d9e7f831e8d4d149f9c8128d7a34fedfbe6905400c8b0b81591245aaf08b613f1b388ac383b77e11ad749de1cbdc184645dcfc5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b23794da8db34c9dfe349c18d95ecc7cb66b9854302fd3ffde82be948a7012d16ac720ba10247ed95d2c3de3b1f45c096231696ce46616daf4f019905b25eb9f9e576ce77e01fe6e14bfc0e03d178483715153a0b4a604e2720390c298a628311b764f0edc20418b8c7dc094bc6b60896bdab280739544a7451004de4ea3bbd0213218f9758ea127469cf5a13280566076e0aefedf64dea2041bcefe09dc6430d0215f3ba49720bed55a826860581d9c50e3c4097d9f5491ba8a14eb31c11a5c0420b08b8132226292d7b56316a5ac14c670b9c9fe4d71ca9588e393d79739bf3aee6179d8dd08465e4f3bfbe45a4cf20e82e3b289e8705e96c3468b45766d55e0096021c036df5e48217b03389b94e5e5047026a7f3af6fca415893987456c4e4fdb25021099276ce71fe17db677fa08074061e66d54689497091e60209b7f13b4a73a760320acad174e0235bb08edfa7c5be99d0fbbb2dba2ed3fadf7479e0b3d018543e00202d6aeab86af5cbbbad6c1ea8d2cf71a28b8af83de16673d01a2e34eed9f342403247a8e9ce8fa2cea5953880736cbb28fff62bfd1084df1f9a9ae6fbf54e75814353c3a45fded83a646a93223e796648ec547aae2d1fc548708c57613fe1ba4c186e298aad7943a48d0cf451b272218635978013f1be6a6a7731214c83c15d38dde2a6170d08315a853f0e029ff50a1526d556a141dae11c804364266111d1c0dbd32b2234c45e610ef2328bad202f8f1f470244b3e4f81a892253e6ec7e33652a419b276bd065e14589ef8903a6ea1a4902d5d84444131f098797c356c3affce420d3bba883a334348ffd38f91d198868319f3231dbb1b186594cb3e53f734c05f54aabcf6a5e1079a7da3afa85c467b1e4a9c17907107f92f757e904ac1115b6f3cb8ac695cfadfb6c721c04dd8ebae9560594fe891ba045f62f5de4e1294c3f7fea463a8db901e757ef6aff7ad9bcea177b5adec237a4b26135d125ebe91215b50c3363020c9ef120349dd1af164fb1523ec6908bcc446880102e7574fe605ca5310e17fe21ea365b6a82df2a8e7bcfe9eb2ad745a22fa39447ed3d5ed84d919d8c3b9874b0cc4ab230bb618725c8bad085235941ab95f9cce6da608326a1c840f4e290d65c64c342d5e63c14ff09752f5814c665ac594cce0c219c70fa943ef0e4d0f14b6e10be6a319b7b57d45a6b44c3cfb02c4281ab6e3089b91bfa1c60f283b33931e2bc2a10204f7e68edfddccc1d2f9c8a53563ea2b6f49594716abea23ccef2d3d363d03b7b4f2d3192485a732b74b1693e1b42a50b5ace9ed6244dcc5a29ad20a01d1c24c92d24ba42f6cf3e6cb18451e416af5b4fe6f54dbf5733d7d01d81c97a37da041437d238265340cc178bd37255ae7b7bc9e19b57b37044eec48a85edd1b38de4ace5722ed91940044c50446e7324fbcf8db1a9510d96ceaf56bbd91c301583de243d8ca27e4bc63256ad39eab717fecd5dba1974b9547dc22adce9308f32f1c1883736b608d6b6a8667916179ea3b90ff79fa4b0fd946c15f070af3613465f6e2bffb4a794716d832e38cb0e9a9569fe2b84c2b79125b3712b3c36ddaa3a18737d10d84a04365aae98f4a6090b7fffd689400653575c3f5b5c24521bb4a78eacc80beed4c51de2de73b17d0a4138ab5b8ddfdfedaccfbc3394766fb03b66e9e52e972af28b9ea8562a4188ac8b456fe03ed30fcb525ed5bf379d6fe4db0682e857f8dc27d70c7e050788a1cde02e6b33f6e549b39efbd72b84ead17cc2b184fb41f0b9a4524aa5523a3a81ad911cf4f92038114a3d062e9f87b6cf929a5012b8d22591fcf709bb5cbe79a44bb4b7a8d992e69db192914b75d8d65da62d463c9930535bd915aac7dea64e15cb5c4d5402268f926ae985bedb250e43849a5184009d8e3b61c41abcde3ef0cfb391ff59dc0485265aaf5236a75b06c0889e0737e6c29d3463e00bef157628a49cc04ae2d9f9765ed5d87fbdc9768ff984a3680e9eb3851bf5bd7dec0c15950a539438b0151382006c3532525c716f112859c5bacaaee02ae7b4d7a1ba4f6b199b9c084c426bcc1d94ba8d6d6d802fac0844f1f817530dc19b47fc1250f4a5a37c4777ac971804f24a4a293b318839a93dd8a071f93d8518e23008152a2ed722dcae901ebb82b2d0787b61ed696f64fdd893db844fbe78739e713e120aebc1bdc376916d005bd2ebb495dcfdcb91725cfc9713b54751e25ef9dae7828567899afb57dbe6bac3c325d91a973789300e0c2a7ae0a8e4e8da76210cfa5270c4bf73add72dbc19696faed6f81bc08d25948c372e672eff153f1b255978e6fe681fd5f3cd91c3cc49e8f817ad0ffbd92256ee7b827fc60bb31d246fb242fe8b85da3fbfebd4734aa86ecaed31b2b1a9d09c918f5dea6a86c5d845680ff93ac09", "6a65ac5152", 1, -1523284677, "a652bba3d14b4a700388c133727a872a2437481c4139a4d1794280ffd15b95af"], - ["94e756b601fd976058da034883dd970499e98483ca928387e379d81882933e27e7c6ac90090100000004ac51636affffffff021c73c7040000000007006565abab6500b24069020000000004ab00ac655b797bb9", "535252ac535263", 0, -717663808, "3a890b896816074a0bcf66112bddce4798c178f2fc893cf5d00453542908fe75"], - ["610e9f1302f8aac74170da6488397674fbcbc884ba16022194b51be977b2e42f32adde1ba40000000005ab655353630db007e0f4b0496a738deb2af3961ecf13b5171121ea1a7fb04ccb0557223678586d0d280000000009526aac5251ac52acac42533ddd02591b73010000000006acabac6a0051bc3e71040000000000bdc689180200000000000000007dd262050000000081b108b9ad8f35aa8ab2e8be05d20c680201ef8790e9f748afb1cb84b3aa3e4632e09cbbe65ab3d9f75e82d59bd9faf9b8c521265515c115e028634e72286adcb9527a7b21e0c78b3b200768e07bfc1005a4d140eb34f88c2fb8b1c0a793527600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fee1fddf1bf38445fd330d1356f88fd8840bbed58842f801160e9966fcf52d73538ac9a68009672a1de6153625f13db32e5b632eb93d90aca07bb77d446535195044558873aff21d7b176bd3d738dcce39f14f05c43a48d4977365905a3ea1a05ed35693d39f93edaf2204bfee017f1c6ee77a27cc50de9f668d092cd092c31003177b17ee383214acb0767c8b2ab77e5eb532cefc4f0fa1d0f794f071579998450319302605c8afffa27cfb16427b6a78845f666c8cae3e6fe7e4fc17c8275d71a60a1ebc8f7f7a40f0121366065c66de76c8a21555aa4f25c3f22df9b5096494b44b0ad3847545aa55875b0ce1f6f0571f43d1251924ac55d2f213e24a5f58fb23e2020f121c4c0c5b8435fb923ae46c3911e1e1dbfc60d2631190e767c45fbd9df33e03072548abf98acae12564f344a146167134788a14da5bad64e111fd4b8379a70f03268bf09d62318b5180a510614704593840f83bb7a1f7f72c08c0cae9e7ddb5580309005b85972c4439b2ba805df54c11ed503ae362242a6782eb7152e0e7645975022889dc0fdb484c8a769d2a42ad9c0c5d35453f8b9a0837bcdd8887253c6fe1433e619750dd553296efe8fd1bb4c1bf94599eadf524f6dcb237e1ae36a82d526f4f9e447cef7721d1a409c3eaf8c24f05701ce2912ee144bf98b92a215d451bbe1c7d9efa24993d9969848ca851cabd04400d27b19351655a134c7db4ff7cdadbcf5235663b0cae58fb6046a7f97b2f7b71839e9dc10b029e98a4a0e6c83afc43217964e09c2fd225d46fdf5d0b5fc628c542fedae0ab6978c059e644eefba12496614d24f45004cb89ee39f47fdca31f267f55e691d408d4b9dc425aab10e298d8617a64ef14936c9dbf019f03e68b36ca1271ee451f360d595543456d4489f26b4afe39d4e97e5e0f47468ea7d4a5aae8e757e19f95fda233ddbe1f2d245ccb1245a42ee8bf8756d06ccf29573ad703545970f7d5e457ddf8b42b24582028813e4a83a28309dba75dc14f1a24e2b1b05a058be0fd0ad2002a7dee7d93645065a95c153c984aa9ae1e303447d29a25a159f497c40784cb254b61be7b66754950e5b0aa30fbc6ea22bbb725be4bfb8c3d2cf20c010d4ef197b6c508e0da15087c9e1bd65d6d18432c81fda253b53ae425cad642fb3209e5ed57b4ba058340c56239608942b464c5f81bc9d2bc8a9ecc58ddafe198e3486214c8937fd58cceab8085c7957ba7258d7b196fef88f519f8ea78d933d04f798345d898a43520f60f9849cbe5ea234d3134cd760b2ebeacf36c9d8beb07730df1d6c28073b62e6f20d7fa8da48604384c6000c937324af3691bd632c701055ff727d49adf955623017f1efca0e8e34268062c32cf101d1c220b60ddd942561e2ba644fea9d13be350fd13ba779fcb31377c7783b2511e8c5983054d6610084bb616ad56d1a518685cc21cc27f133ef2b3013e496fdded2cbf2e125ac3d38368337f67ed7f955ff1ed7686f03bdbc33e7713f22c8919639d051ebb00900b42357b5ce830c26770a0939d197e8bb72fc1d552dba15eb75cfcd3595517b65eeeb08edba1dd49837485baab75008fdea4362d5c9b8bbee7f4edddf358349f8a9d20145bdad2c4c16e1de5da68fd9eeb8366ab6c98476b0f3c02258ede713ba8d2ac8a5cb0a14c080c7d2c3e2311569a29e4b9c452111897c9349dfa2e220fe3314500496f96992ce4e5ed0b7b23084015db74281608366d5b031f80403391f70518fd2a893164b6c89cb2686ff77b26d3578b1f50cb03a7f14014f4fb258416acba7b0f4616b1757b15be7711de9d76bda8a6823d6c6ac3d1858552482080d6b01d792fbb2d7e90f7d4c0d6b9966feda57c45e2e8588e57ed91188b85f982dd16399ef8a564c3ff8c5597c76820ab7de4931ad94f84ca38db7296c2df2d6c515d519d07dc1ad932a40f0a1d9e61ec4c0a53feada12cfbf6c1c38538ea7fabbfdd8d23a799086b474cba3145fb3fff56c0ead51cea3299b6a92c280e1348fed887c254a48f282026cd508da2ce0abb297ff4df443e8f7ee5a3ce6c5f6588b6cc9c6a4d5bc9b1a630526a9e97a87964828c288f8a9f50f3aa44dac43684f1b09370716e7f786b7265863702afe58f862042958590e304c6ac79e488581492a3ec9803bcfc498540114d5e3ce138e24fa0b67b17aad7be1d6f4760555f620680842cdaec49882fc5994c0a9f4e341c1a7cbc76d47c78013e81cefb3ce13260b09ef88285ac82bae0daafcfed50d1f08020edeadbc001771ba4cfde547c055c98b7d705000000000000000000000000e8b281a9860f7273cdd15f4675b20f13b7f9ca24a8b76e17e1c1e4b1155920240e83e49727f061e6b70a844d3c9c4f6df5aa7e8aba61e17603c89857fed92deb87452a2ad50337577f8663cf9a72ee9331923e7fb607e6dcfab8b90175719c9700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cbb440f81d4549e0309e46509ce4c3024c9c176663ba428483c13f284b116d6860cacac5032afda3e7d3c86bd15e653dcc5a038f78e65b0b55c7a5ad4bc57873203b3f1c4b4ee2c489666f67c8451c98ecf0dc042cda16bd9ed7d0031b035166cda77758665578410fa9d4786f3f774e0dcb8a7bc23182d190fe7c54a637eb3a031334fe8379a5dfcfe68ddd7dad9cb2e04f74387a45dd72f8946ceae0401b39e8030e907abbefc8a07b456342cf656d8fe949a74d148d081ead68370763cadf8e270a20761e02a061667e96b374904e023c5e70ae2d8219e176f5fb2b713f88e595c00cc3810a4c0d0cdf8b833f9f1a3ef6e027c629e8de3d3009eb38a26f1cc27724022cb1e36cb17190940c56f37f0e2a760b4c2b6e268ce11da77b8783436912b0f403179f4e5769e57a8333645f1d99c30ae8cfb563867fe762393da20f3433a56c2d030fb51df639562712157a165aeb7a3a77211ef263d70e7a116cfcb4dd9d2a87c40314bd6c07ba4590209398ea3f28e076005123d1277b86ba189bff76808bc3c540030af451ee78570489fdd72c39c4127252dcead075f284093776f5908ccdbab1d2d103fb217bf1f3511db971a6b153fe02275bb76ae0d1674f136c95badd05728651eb0b201236c8723d029356d3d56bf8d08543c47998726f1b716450813d18e0940455dfcacad2dcbf18302cb0e8efbaa7217dd0e923b411297541d8d4eea8a298e2e6021dcd46d2679b0fe7e38db81188b4242e1655c6db14335c95e18a90b05b5254aaebef462f58438811b6c11d291c038a853db7dc6ff6599d3770073c286bb9e3b7bf03d4412c2753072033723fb5dcbc2a2a3e20eebdf0c42b8b4bd7fad076f06c9b1ab1a3a909a787767ebe7747f15f55084ad87d7d7a12df98ec00fb450be3fd52959a92c915d4137475d28fb616724d48b688773712695164d1cae531fa831bcf7fcffa90f3732ef8b5164042dbde286ec9db0bc34537e91d5e1d11fcc3a5fee6b2b63c75c4a6459c367f06d4934bc9c850349ca0c68c2d967115c607e6de97cc8324dff65ad2151e0a9234c082c27f2debc4f0595f7ac38b4100e36ed6f7e5c1d4a337c0a2fc92976bf27d26dedc5175f07031331402bd25d8d24cc94415d3281b9e29648aeb2ee701e3574792f3ac51db3e550f3d1024d79d54569abaadcd33810cb56985d451261c1c061dd1352e5038b897e79c130a31f9bb494623becb727ac62e584b0991eba72a1595971fc2af17b6e882dfe833f15f8ffbe623dc99890137418614951529c6f93e02500f33fbde5706731dd540aaecb930cb8dd3b241656d31def4e57413f4c78f336d0b8e405b02f870681c37d35d5ef751891f814d00b11c871f925c1aa510e93c2256580462fad9e1cd42aa4db790d111368ba77627196310c7c5823b63136c141f64856c0fe178f6268d7c405f58784a151fce5083218a9ee53c7e4b5a60fc21c1f55ab5d27c7f1b5075f9bceab87185333b31008ecae651cd9e368781262fbabd0436fe1ac2d68daa603c125bd9cad5bb8f427cde404d62645915793d6138861148500770e618ab3212a6091436dcc2d4c549c7c06d279c310b1531328ed95b15bc3ca3e7f036203866fb51b7c0dee9a8980feaab5800b90a86dd11aef0d9ee3138315e6de38b2856f9ba76ff10288bf278ce72c8d0d6dc2868c3f3e53648303279ef4741a66bd881b2edddb4eae8eee5545fff832249b53008ac4126fa3873c615670080f76af6707c0819b3e832b4b957fb2e7499cd55ca291686068ae61c8b4808e4ab84552abe29d795870f8a61214934c71090e612a419b721c65256d2f1f54f7f91616342e6400ab70b1d39541b1707a07ef938cf3aa4cb04a564e910175982c9796b457bda71c2a012526626609e207cef453ccecc9e58e9a48face985aa2598b381e29bed84294da84d68eee0949546a7f9f088dde48439ddb1dd041c30156ac859afa6ad02c4fd42800ee3c82a058cdb6799a0d58a6c4caacb00f05f461827754144ce2f721497ee98815103d8f3d09807161b98281ebf371295863f51fb6424b4f0d6bf96d0d862d379606ea0266c47069d9f30ba5034236dc094d66d4faa7da5c17767967e4349dbd472ced5d7fa0d8dcc9bdcc07a23bbeab004ea8d7922f47474eb4333cd76c0a7dd38e739e88d584d8aa2590c44802628105a93decc243d44a3901cc3ed18bcc73101bd30732945be50e9f61cdea13f4f50953286f53e10f58359fe8a6b00a2982cb71b1676600f74f1c8e28acde2cd509661f7f2c66b10e39998f50ac9ba40b5cc35adc9de9ceee847303ccff3cba3fed252e4c78979ddf63d537a1a24a257cda66fe0d6b3ba75730236d59e69803d3305021cac9247d6c9e8086790e4f3021569a03ae7066704d1ba8b4607ead5b6c01e8500", "526aac516563", 0, 690020955, "1c972b28ed17bc256167bb0eb67ceba813075121fa935a981421bbae0495c4c2"], - ["8c245238023b85dd56547c8b04045672be3fe4867c299e2894597b962796089f0375a243f50300000005ac63ac5363ffffffffccd4f49704e65c38f39c6cdef108912032f201a5ee0f643af66a6ed53a3aa64e0100000006006a655253658eea69b8019694190100000000065152ac52636500000000020000000000000000b5b2de05000000004b70f3b2a3489a26b7c3e35c71b41227d16cba9a59b611fd3330bde0616e976d766ec0a35179b80c445677178104a8c80b92dbb72edba771490a2c18f21df0d6d3f572031ce191ba44e034a197e129cabacec5d0353323f4da89c82ef71c24240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036aefd592f85b834e8d380350ea8ffb44d6a2dacb72707b053fb53d583e1a7c9dcb24baaf64000135692fa454aa24a866654f47e5c657fd8475b1d688d1137e04ee0da95a5cffe3c60fa24407d6bd2ca6c6d86aadce126ce3dbacde9997e543feba7054606609714a9a263f6120243f45adba67b94a9277fb188273dc9bf4d3a022277d2e531f51596325c66813afa2fb533c35574b9f1143036edd32b3166ee00022555e6c179707665cda11ccb3591442e6c21a1d995c610b311a58a0a8f82c4ad0b0640fd3538fa9540516f88e8c1b0d72af5a6b1d4c57b100dd44c536df729416008e1efda1fa80d44e53a8b0aa4e7e6711071063e61da92626efc565b26fdac44031c4c2d4bf1617e214da09eabb869ae266c02965a160049dfd370495057aaac020309f6ed0a3127c1c3682dce976dea4ffede0865502fefe61db618b60647949200022f895785803f68f464a8a01cbc82804bb99fc0c162f4e79556de659c17205bad032792f62f5c8f55e2acb915a81c287114951b274b22a4b2225a5bc7d1442bc3c1022b96cf7623c2c914ef94cff2c02cd3a5b421ccd17fd2f7f35386a3ee869538413faf62d5e6fc51c0d867fba42f6dfdc2131e649f0c6b01cd363cdc35f56370f039f5f1832c1653002ab7ced29a4b699a5363af66f23a00f681597bef04141992f14e7f41e2b6fdebdda8dc8b9e8aa7fcbcb973128a25102c7bfd0123f5b8a5c8c239ad6f59c5f51febd81a838576f6f11aea9c0ab3d7b155d36f8ef0c403760809d650438f760a37e55b1cf22de8ef6ae43f2affbbccfd7fe6febfa08f5944f864570b703dd10950bf801376a0cbe1933d30ad03f9f3758e47e948b4269e5ac153f90e28d5f80fd36e05fd88a20609ef751cdad4fc44f401b9660fd7dee8c51e1c43420507dce9c70e9378afdd99afe0d7aadfc36d964751b4cb1708289bf7c1f336452c8f74d8a2d9e5e22db0229febc819357f38c94a3472a2048ccb805bf89c27f8cac214e2feae4a8e817ba188df08eeac94980faa3a27f57d15759379f07fd98ac0832cf44214e26c061843730531767417b8605848e228f9e00df17c25aee32acc88e5c9af5f0d43a8e91424290d50c50b521565f0f4b1c5195cc951b9f3a295251c66c181d78df2114efc7a94c5489da353992e44db5237c29dc8740a10487c44bfc69ca4bacc991890dc4928841b660a1060e1007e0083e7124da5b2972bdf1df082385b0796013ac3cc85ccc8b57a86dccd6d3ba900b8e9b8d18e597477a0282747579f0d71a5a6524dc142a11e4e81f18f38788956c52e2eb584e02d01b13a142de5c09b2074cae574f5692db25aa43a3cb4a8b66603ea943c0cd53093a329cd4bf39f117de3c46bb74f867c097e91cc0d1aec7df6b1bd56ffad831e9c25d2ded963d9e36e6399973f024a760b847b65a9dd8eb50bcdd739181f0351ebbbdc53698fa7bb26b4b117d7b6d34a5b0ddb14ce51cbcca0e923005bfbaf11d96a08be0bed36ca31fbc1d52f7fe2f3285344f587134caf8cf3b92cd3996393f17f0d112770a36727824ae5c571402dcc9b8c1fbc5dfb57ae639e766b5d1b2f8e219b390793cacd15eef105decc539c00289150b5276991b2349deee2efed440a82cf8e1de3c8f895a1043f899c20132cea9adb1bd92f3e43222c8acd881ab92ec3a0290659478dfeeb81acfb48c855fe9282029103a592d0944efcb93f01af71f4b925feefe9c289ef92e1fc8a939d83405dd06424f1c6e076980319a3f9021c8cb4aef01cc3cb155f523328f4d262f175256fc8ed0846ef87f8256b1f155eaf02bf257e967f3ea94f36ef3abd91b4f076323bb812de6295b0eb3c3b20c5b490e7ad12465fedcbcaa0308475719a86e4fbb4a53bf9073020d05e5c060ec862bc3cccd2405c6b4f4cc78a78b76fb1a7b281aaf164fd6d535ba5e7deefc121929e4525ae0b9f226d16d57741df0ec0ab3840473fc01acc252c8ad55c2f572c36c7832e06987ab27d70e68fcb174a807fae6c577ff6190f0f8096f46b5a6e47b160a7af14c1466556a6fb4a2950e52d695ce3ba67cf4857421d17eac44dbfabd259694fe2313164d2b801b9dd583219670284ba7162c8d11e16e9d2b391cf567a7f4a6eb8a581e7df63041eb0a0c8e48585d615f543e6f6623a8b675a99a6716c0124775b7377fdb497bbc5ccc82225ea390457d5f5d665264a2294747c4e9ce2972b68b6bbdd339792b47b2ba660d3488b3399dc566859e40754a964d8407f76ee63b7e98b1c37ac11f347cd4c4bc19b0ad1f874020000000000000000000000001e9a5f950d18ef7eada2e9a5113f26a2d0346a7592a902d9e41d0075b8e300b82a218c7ca863781d82fda0da040c036e53eb26835858e5e5d2563542ceb67ee806410ddf0a57c7e9d8bd5171a797111119c28a7bcfda276ec26992bbcd4c617700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b665aa6d5a0ea7ec8831fbaef6d68067caa7f37f721f701226c84b061b78859a020234cbf3226c17bf663861197c979fbd8db9a17059bd397d1f2ae01b02c772620e3ca8790c5172ca75f90b70f3df7b7c79929071fc16c878228da167f5b3b4dbe8bb3dc4fae068d45a954cd4206a8cd44818b3e41c4e83785632d42cff3655021f809eddcce8fb102a2432fcfe021d104bf94aa68143058fb0b6ed52dc1224b9020d248df5acb65923947b02fb94056c8b500d42339d802c85d233659a5b646c070b158931b4d000e5ae2a83e34d47485572fc558a9fa0e80cd0d34441d867fdfc9b29580725b84583e469ba08409e6d6aa57eb42c7b1826fe3044657527cf03bb6c021f9bfba19e7808021fa0fc831a04ac0d71b9a81b916bcf784a437b3b99aaa1130227f3999117a4b5ff21eaa946c1773996c15907f9a76784f4cbaaeaf21b40cf08022148249301aa7792a3deb4e1af2d7d06c51a89fcad3c307f46710b1587e35509022df8d139f9b016c72c3e0c1d274d458671432c74e3b9f72c4c0027df722aa8e1020a9133435be80ee6f26dbbd2759838316f1fd8591368372cb079d6da6dde3dbfa0bcf4753d64a2035c3370ff87cf6eca46838cfc93d916c5a5bedec9545602e7bdc96700e467abbddc34b29418a75f31aec09eab56ed1ce3f635002c3a0aff418d7749f9d2aeb90836e5d7616dc38aa0ffe615a618d02fa4fb3cc0c0fc827fc2104026bcf25b0eddf8c204285bfd524076bc9549e96efa3e010eee57a211455a99d1798aac35e52acab0c11d9929afd052ca30f612eac9a73f3349d0326971e45830dfcfdb5145c78cb4998589456121779524ac609643f3039e182aee32f074ea24e98d26c49d1740e875f10bf291965cd51102600e3b4893a6aaddb802956b862f40754121796e4bba8d35b48c38935dabb975082fd11d6732dfdab2ac0b43901bc7a3f389f6d2cb0f0cb8fedeb1be55d82906e863025b3119a2c0eca44d54a2638ffef8a4a5358f6bc27ccca946f77c49807e4245dfc442b8cb336881b4f11980578396d0ea6b5b8b08b3e4b88ea57a26be679d83617db5c3de4acbd034dc32ed5746ff77cf6b1c8bb1b6721b47f6b32d41157835f7b033a7bf6ba17d3286b2e444c8b4d938aa3710c45fc5c32642fd0c5ccd73edaf8cdadfcdebdb52912a9c5d6d7f44a720fe9179b4908f6f44f319f1a9695816cfc6bffd838fc2f67aa52e84eb6f86fd21956c1bc943219b18aee8eb21999554573fc97cea18cf507b6a8aab8d193d3540c486babd264d144c3924e2e6523756466a418c19de381e368f5429ed35f6498559cfd3ac730304fc63935f0c507540bb72bd9628fe10afb258230f329ee8880db1e3ccbc45458e846cae164f80ab536d60ee19343c7c79a0bcf2bf47d57a12918d3777c698b49ed438331db2eb0d1c7d0b5957cd802e7aab227d68a81bec0b6ec31dd31d217db9275257afa0c954f8d913e0c81a3c4b9aa83cec551be8fba4ce797324b3cd2437d54dd0820b62eac1eb03421ad667657d018ac29680970494551b154e054fe757dd256396df15de2c3ce46e123c48c8c42ed57fca565c8b862bc0239b27519a54c78dedb6b64bc262afe62b1adbbc87211922fb25948d26521307b5ae0b6fac1b227d63cebd5edb66cd9fb232f3ca4b57ca72925377fe3b8f8a869d8cff703c646504f37d03ab3793690308c1b2c8f59fe79b84b975b243d2cd62dcdae3a90c19ea33eda7f6e1f27701dc27d5367646e6e3dc6cd4154ccbd0af28b21279d667002b8f6b2d35d9c4f92e658d17617c3c595c9765d208f0a183cd238c3f54e8e5630eb337c9f8e563b489f353064cb6a2bb3aecb1988e86b63099fdbf2dbb84599f6efd8918928eacb8e5edc3e79beb82aee9176733e8e72298afb29ddedc2a518e409ef3d7f8ae04459052eae14c7f0b6e8dcb18d62aa1b63be51f8845a90fb49e4607006ddfc0ab551dfd08797f168cf3be664c183429400fcf44cbf32696c69654815a18dcfe8f950f179f408d1e3c6f89bedb6067dcf0513aa65bab314b790b6a223e2ef8f141ca9e3ab6842c42cc77e3008f1776a8bf4d88e92006ccdaead15f1a4be23f538dffed693199bbf32eec21a03d7ff67612589713808d245e42d010236efdeb03b8d04724d135a121964511c076a7db2bb69245023e05ddfd92d4bfa3fb3cb82cc49273e7a78c17e7d31221600e1b093aa9a8dcb12f8f796726d3da2c72d0bab8b3d07164ac70b44d99440c285c20159d902b6e2bceb676b1e0b26b3b84030fecbf1ba9c70ce04058a63bbed23dd4b8b8a29ed019b8f07982b257691bf7e118894a9e2555cd430c73d29077c49a4cd94d4f67e3c1a9f6c2a90e4879658a5aca1532ce9fd779d2e522e17db9318d404fa0f3bb21c45f3234bb86dddda4f505", "0000", 0, -926080502, "e8d36d92f19253e9351bb522511852c54c190fd186da53729378b2f678515e7c"], - ["858fc233033ca627c2c1d40767e385baddf648c30f49d536bf213606dd63240004991b50ee03000000025351ffffffff78fe020d977077e998fc9b98770b059c905e914d4e4d7610726a16b9d447ac8f0300000004ac52ab52ffffffff14e4d519c04e8e4b31d426884e39a9d172971c271eb6ffed86b19604758feb630200000004ab53ab63ffffffff016e9757020000000001acb3229a0303176a2500000000000000000000000000941e0fb5560a19d6ec8114be286264d9bc1d6ff29bfccaba358e3d1212faa4e3cea01013c0472e09d2addaf30e24d32554d425191d0cbcf9cdff319532bfb0435855af96e3b7de651d423bd1cf669894c8cdb6ac475ffc3893dd3d930d67719f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a562b4f8e5d15cc40946f958c765d0b7787e07a1b9f295d70d0da0b07d1d6e68e43aee7b5161cfcac87f10619602a6128189bbea897c9e36081302395679c601a556754feca5047e2f042b0b9dc867f4f4c10d1407f0c30e4ac6b4696c099c2427e08970f77f8580b2f2a0e3480711977bc94f6a0a08f9a123cbae819bb9870003107bba9dc852eb77c71a164a35c13ad7b99ec630e2d90712f89e727759fa5e35031c77cc37865f4c2e4e819170044ffcd69e320f51a00f042fd813fc0d52c54bda0a28616ac3f7b0375711035069cb289adddcc6396a6f9d424806ea62f32797530104e2e85ca57fe91d8e2f0cc2a606c7567010e8edebc68c7d5fc40a380512a19903280f66c915e38a130dd921f333a937ad47cdd45150e69f40813079e23c56c59003118423a55f4f01396dc29d5210d01a6861206e334cbe01506aa0e8de35f24be2030933903afaceeb82a9362dac1394f7a40b49a4bd55e8e45636089943bb933aff03148b958a1322729538b4778c65281c895d7af5cdf9a31f2a927fb76fc103a3af021ecb51e1b8d9cde1719fd6c1ffd62fb298c08586420b94b4689e6651e733332d406499067112411cb1945389522e12743a8c802abf0a1786fc3ef470d6de2800667b199f424ebecffdea25dd3af7dafea8223ea8d7250b39751cb1ac7eba026f0e0cf07e7ec9a5fde28206d8ef9f099bc16a8dc872a90d08460acb795402b93898cd87a033c4e5311b2de65e471b442a71f18fadda378b0408ec7011f227a639e9d0b4125f46bc125a5e8ba3de1e922642348bc8f9328125699623c9fb7b8102340d18f95970be9a092c24a71ce43250478166cc2ac14da96893d1d86db66af75cbc2803aab5a7797e033512709d1563a0b668ccfdbb0bf73c2db2ac3d6b8d6224aa2a8a70f4439bd31054ab0c32cdb17a499bbc259b8676904e17d4d8824be979594a9dd779ac4dac090d6b3ab79da67f54401efe3ad726e021bd32b063a36dba0e8e3e017d4a83b852d558e3c6f2825da3392afab26b60bcfaa044ecaad1d584993f31c192b7cb7679e77dadcfa1589118e17b2dd5f63e95f9eed91d9d9ef94dbbbafc8ec3701fbdf8cc5f1e5941a393199aac7ab10c981561131aaa228f4347bcebbcfb90f651c5af1cf6ee047c19e34381c149b2268148448f791ab650f097941ac02e723394761b9d03108953486740e5863353ac78a951f3704767bc385b4cfb82245ecef374807f18994a636bdcba4761c0bae54c22b943b24c06e5fc8e98d5b6f9ccce18132110e4934213f54a5cbe5e9c368dfdd825bfcab4785d9fec7350d0d092303e611325973aec8d2f0f27b82855854e8b51f410c016d18104d4d9539e9fb086a8138d15fa008adb1dea32f202058228884737c8025bb4e0db9377fb62bf61c8f138b086784d0dc77ae6a55c921d56cc3c2eb192b0fa23fb5cf7dafb944f8f5c203463c4020543f0e39d832ab986f1b7a8b9144e0d788e5eb3a309e5280fe3b113f10230e30e06624f9a52a0725ff94c0946cc870215b12d577b666bacdcc9be4ca227c116ee140283fc1a85b43f40685295e5f8343ef12b0cbfd321d831640ad0ad3b6cf34fd47cdf8ff1851525c44c140b37185268961c04f4fed619963bf958059ffb28aa633cd08ba0fa5f4f97f90e15bf8d73b22192a7ed78e58d5809208c60b036b59226339505f942fb7b2f18e0d319bb2ba7eaa4191948a3de01d55dde215a9354122d26df1371edbc5a8c5d3fc14f3fc51a89c855826e1651e61708a263f6474819e769c9f7ca29c94aedfd501e4c77f80808e05ff934dfc04cecb3ab769db271df429fed088061a8355c376c492571886820af42abc3d5743be2d4168bf5bf2a1ab62228402761f4a5ce0d41c5e171579197aefd92cfeebf81ef288f2f2e789d2c4b106c6ce584fa3474f12b0256203841729c82d6fac5e61921f7a1b2270e4ed5674b4ce7de0d428772f99c688551af2c7bad00d0e348ed2cb0de9929957b250b11c2e78a678cbefac57b17966f48043aef3f5bd3df29e34b24306fc85d45904024d1644e5b8556560324161e123bd3c9ddda7375e43cec6e435ec1b9aedfa52b0d7e3ce0f2f41c49854662f42e924e168d89a74fef004b67f2c6de92ef928fb7256aa5f03894837dc15d4d1843021de68882041b05a6879a09489250b118b05e0d8e3bb42c92c78c9ef40b16085f114efea59d470fbe805aede9a2a08ac876f1c5cf257b914c0dd1c6df4c291b187acb5c8da34d6642887e9553b5a11efc31769fb1d700ec08def500000000000000000000000000f611f27cc1f995e631538f345d547847884c9aac383e26c8f258e6ce9c64405a376c8bef9df1960addc28b62dad3c4b3ea4c2f01896412893b8671b85d86c41aaa45e8731686488029ae040ca41dc7155e0935b6a04128a8b70f62875980815500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f21ce9f73a7bfe2719cba1bdde65c74c864ea758a201bdb68748fca3b8d290943e6e7a39c8a06e9b778937534a19d63fa1d9c705b38e4cba057d018580d753b0b909658db44bbe0839d5a1bd6e8aed920fe65eedd4eda212eeeda1c0a95cdbacee7063797c5683d0432941ad49a5681ab3b27936c135ffe47b6315b7b8ce7d7603146a4a6ad3c22507af59282a172e0eddc5c5f210e304d6e12c515553e7ddf7e903030cfb94843b1495492ea8a6a4779c5c2179b92601e90faf24d644f9ba16078e0a15df6c5d2db6a538759c47852e41285a6f81404568e51941438c4acad45e0d161a6783da1dacb6df99c60c407a9ff0481f4266ee6efa9cbbf0422fd6f1f53926032261f17ab892f149e787af9528bb548a96f02a9ca59ccc69d025d92f7feca0ef0225aaae370e6cff2f0b5f40d5dd569a553e0db719cf20bbcee19d31a5e864236a0211bd2f6b9bab5cb423766b5218017966b7411c2645d0d70ea6c4bafcf1338a80021bfae25d4dcaec161d8921ecb33e1dcc249ec9eed2fb7c4d93a4ada2fd697acc020dcdb0fb1d84cf299fed68499924f593d26d1e78e395c0ad1840d7949b84ffbdc15fa0430a81141df3e7402d9f739343f4d8d4a70c277a73acd954e707dc2221b522c2caafdbb25c188be063d9ed600aab5f35bcc29983bb8b76b736f04705cdce3aa51bf28f89134dacad03b565ac903fc4aed77c8f7f0f08d2cd221039a606a5f823ab498293b33c5fd28da7b98195c29d34da7cafc3eb3a49d6e04586bf3e921b7747d57b49dc0c9e39e180f879504b4bffaaabbbca8930dd36d56674551d9f53cfbbdc95c18eb5013b936135353547f21c7691fdc2ad89edd8d8d62424802f4b539d099e77e822c1d2bed7a45e6ec4c3c5bc644111f555039348cce363ca83fd0552f00a0d574870c50756e57e69bc6facd8fca6e74c3d50cb539a8b0577e480df2284a0264529830936f9d6fce34ac0043b2961d366ff0d5b72ad9dd60625ffd619e1b5cc255165e6f3593b555770b2a37702a3ba1d810b75288de65d069dff4e0581408edf2666a9ef7199e4efc77c17b2c5616de0e4dddb3fc36c06bc7407c858ba4812e1ef83ba1a22d95f4bc626c435783ab2f90f2377f94d3f7f2aab6e46af21829e5202dad5d4f6e3b0332ecce7cc43902522a0e799af48aab08693c50938501bcd427c13830b102e1c572f16494774368d22ad83591eef8fd568203ba5197c3bf5dc8c3869da8006d2e77cad6d782e55320ff842160cfa62e993955fb6f68c4eaca3575a5105a89772b641244abb958e5d1536733f2e5709820794ecc4578db9a390d98f60bdc1a4477392cabf65a9f54610f54c0810656104f963612771096886f0f651006e539b9eea9c86f5a7157cee195058ba3ac0b6e51975448701af0e0aef0ec08ee74a4d292735c4983e0023f282faac0b77541d23918abf1c628214bdc33fe01d5c975f21fe42c62aeed80af365d508c79417ec103b3c5abe24a5ac1d5c5186c631af3e237f96e2bfe1e92060d92ebb4b6d54df964e786b272f2d6b54b1a2fb306bf768be11c4158c8b0152ce37a8d45db5c75afc569f95844dc895dfe74f54b9b0bb813634b779dc972d83c46d6bee822284c017a8cf8180ff39ac4dfeea24c3242adca0a4ce8a0765d879f6f41e217e8ce3eef386a89c0b82023ca3f1e936efd737a0ccb1f44f69f0e8bd43c7e26f41b10f9d90a1fe6d57da8214dfe598812900f69a506bd90509fb935e8369e2bfbe2f06753ca01e92b45001101ba151de4683b40bc4f73e1c2adbdee8818604a19222f5f5e55589e8b5088d4fdb26d636792d915f5f927ccb2a6c3ef4d7e9cde4c9f4af9c69b547d86857c8590411783be87674759e5642805ae9b34e3e1a61b397f71330cba0be8e267f76f170476f99aaa6e493ccb6bdeff4f67047ae1199099b5f53e0d21b5553800c0e67f2b92713fc94a6033a37bfe400264176ab072426877b1d447dfcd50484321179e93722be552a6b89562a5cafc81b6906d64187f8718bfedf32c064263f8aafb13ed0d71bb3030aa92a124230ce0c2936114d75811197318f3f8d31ad7bc7578f91afc5a5d2443bf6ed6c25e4f5ed0e8d8ec0f5f27d1b381c25d50d548b61d967074109aee13a216da149753be684318580644add363386a158f93e3231db540a6cf18af66a32baf17dc0a3acbf38725f2778728fad9d3c51eb8f8d30075f1fc2f4928207babd9326214474ad433c17819c48531d34f818fbe8ac0b4fecd467d6a1c8a42550954754427bcf46e87fa8010000000000000000000000009e85966989d8af5abd41862b4f560e42d57ccff7550f5ec3c43bad0cf9cc5c04f40734cf9949348016c97fd129cee02614bb23eead99ebaefe96bc781bbab5be9c4651c387a5322006bb24dbaed0552ed0a74a9cc6979a1e9655c5b672c97c41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c42388b54195117ba1fe35b004594ac0b54478e56b125d00eb48fbe3f1d045d381f4b2a7ff1f8b9623bdb7cb8cadd6c193182811d717b520ddc4cc5e4d403a6bbf3d8306d131e279ac6378ce115397a742aaf19ff8b68edc8f384902638e00443d4023df9e00473bbd4347856e46cba09595eb0cdc5176dbfc81c1396d298dd02154daaf02db6951a58545845d91240e1c0f309d53db32ab614fa9e34ec9c83e2021bae843bb89a1a36d195a027308c68dedb3bea00a0c9430c5f3e03fbc6ed34fd0a04314ed0a7da2917e12a35c3ef047c3ee8da013f44e5158d44d2c92e80f8d38716330167ffaf7de2330a5f057aa98044c18fb717ebc6c526ae0cab8f95e768c703214cdd90b7dbdf8351c5a28ac04eceeee27d3d2458aff34edb8dbe47a23685950323d6ca23eaacea4799ce8900ac0fb98e97ba3d45a48d2b3d6368f78814574c9a03052d1835446ba7259e8c11633322b5eecfe78f3f375737dc1b50e2a0c5f90d94031accbcaa430200e94a0cf88b5d15a193393946bb050b0629985163ce4ae3b78d032bb1953bfdbe280bbf4774649e7a4d556ae328a38070dd960de0b0151e6540bc2b0f29d0715f724828083b3fd6f35d0596ef83df24a7ad63c2f6ba42223523e4ede248d34144e4636f9ed7b31d753c9daa351a38b32a3ff63cd27f04dfe9955de67901b339b5d3a4a3dee363b4b79102e4455ee53df8da4ba623ce64f3db8a57c74f1f1370a6e1d2d3724e386aee947cd4588ed9a75db25e0f14943a77604e531fd3826ca4d4f85e71ea6b02f357d19291ddf72584f0598530d2e9a95fda4cf9361461072a26dd4257bfde27276b59e6cf4059377f386357b8f61a90d0c240307bfb40b3cd96c2e0cfa2a5285f22b5c6c3b814c83bae1a4faf522902b32bea7d8d77b2decec50fc4d468019c1fc681c885aaf47d13c86c0fc7ddbcb34b6b58206e172691b70b67e64b7d2906eb8f80d47888dfa69a1678d56098eae1a7d429d73fbc865753801ff3cea7ab399df84ecd13d833215f4608cccd4160b1b4e8328b429419c6b69346c52715066fe9914647fd04b72d89f9ca00f22fa365e9ab01499eddf50fe807a61a71ee3744582f6628ea3b537fa640a1d79b8b076dd9cfe13c55e115c34e6f261579c19d1c639670d1e84fe64026b01c183fa6c8264a76e40d722ec0cc7d2c1f847963404a4debc6eabdc23d0c03c5eb3e896e72156056e0401d9f99c1a977a52b39afd0fb00eca6f6651099afd71656602bae24a9d74e8e25d59cedd3d1d87d094836bdb98e8a26cc6ba9f0a8f8054863d92cbdb7cc2c4ca5db089ab0a511d6e3bf10b7c30a7fe021d6c04d1193b85fe1ed7dae25eb7d89dbafb2e25c29da42259f431eb667b642306d806b72712084ffcb87d5f0c71dac0b13a958dd371f401ee8d9f8021bfe6e321ac4b5d74f64470eee82264b836cf5672dfcd4f861d19c3a64b5128cadc480e95690d6f5aaa09fdaa372a423250adde7ba48e36b5b8ec6650512b3282fe5284942e597ce755e44babe743bdb8063c1b4028cc600df559e1e7c48d4a4aaed58522e1d17921ff59186657beaed7583751822e70ea66f89f5b83cb2119f81c3bbf0a07101959841d1114c228adbc82700a52c08ae16a8c6a847b87b2dfe8519697b92731ef2f3dbec12a15bda47d4008930b38e8cca015c84890c9220caf581d682836e54ec4333b56fa26c3004759e8eb1ec1fb677f7966eaf7cea57d8eefa77e2f71b3a00c282ee747d14d69e5994ec5772c40efa46727e01369b664a79104c4071c06796e00b8def3f54b605fba239631806d5e71b2027d74c0dff81b98bfb67c798c098685cf2de82cc2a66ca392373b31c466472ae98a8f3b946706ab5a1a93f11162a587a02643a109dddcb4ddef19f65f9783b8fc9237ae8e6dc4bda72a7c03f5a31aff7175cc39cf640c7ef1e8b772bcaf23542ab345b4e144d7a9d77286053d2a4fa372ea12137c4e91611611f66da2d3d82cf74b0e817e78bc99c01f1e627b1e96aa7a329c6306d4fb1576733145abab2bafca9557fdc7d54063d8d57476d5cc71c4d621a79f76c924693ff39c801ed66a586bc257471a7ec6da6fa92bfde12e81633762e17f29d896781f2a1cc026343ec56c9e4ce4f1655ae9e834989f301dc55f010c79b72b80d6caabe576cf8b0f7b77160a8f43f4969b926107cfbf0d47904a72e2b03400b16937e32d0603d9263c3210ec4a1054b06c846903e46ed4a987a95356cfe3debe4cb05645dcb9d33f91030e566cc42b4abcbb86fb30c58b90fe3a7e2b3f82f8ac13964be9d9fe9764c42bafd0e6b2bb7dc7ca8df14ee90e37ad5990bf8a8f67840f228a8ab01f3c5acea796e84106432b31f8db84452edf2309971d858347f41987aa2a8ac80008110884bc9e515cb89956c9c4aeec701", "006a63ac", 2, -1633900595, "5716eb5829a40cb433fc003a1bbc356ecec53c64c7684148b5138030a2beaf5f"], - ["83f79225020fc35fb09fa9e5207ee49f96fd6fb3b8d282bf0ae47e36278e99949639497ac200000000096a536a6300ab6a00520d030e5e1aae0a9a2249ae04f34844fa5512060503d4ae4236598810a59418a32ee8a66b030000000253539abc1bfc0429a5a8050000000003abac65ce118204000000000552536563514e1ed40100000000065263515363abb0f279020000000007ababab5263006a00000000030000000000000000720f0d0300000000f77130710f3c9dbe060339377d73de73974d0812e49d54115bcf667020349cae54e4add91a6409d85d20ac45d96bfe0d6a41f3525794d0d24e918ea59e23307702b062a622c6f038fb2697ceaeb4890927149bacaf6d3e222510d68f6c5eaa94000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005ac1847538483736211e62c6b52e24bdb8d417d4cb417d631588b97f03736e12152afe5978900f33556e72d46543a76bdccaed95d907fd028bf3793b875d2122c3c552d12fb95b097d3893465383bd682a4bb64891d9d0b8a1f11b63f4f62ecd7d8e13da2399d8872bb52297645200204f4d0a1a607fb544e0657da0f0b81e1c0212eb49fc4ce0672b07fd72503f665eee3c55effeff095473e59683a4b42adca203060931f337f6bd4b31e56f48f3757e25d0f71c55262ba0ecff8443ab879563570a0b8ebc0467456f7d642255c1e246a6178b2f34635232baafe56ebdde0e73c99b2450a51ec14e3c2afb29a9132efc39dc2ab409f7d965bf86e0a30b978e02b34d02184de582992b6dc644e93aa3fbbd76203c1dc03dc4c62dba03daf2d9adfd896f02002ec89c77ce02f8150a378a9cfa1c810440c634642d6807fcb23d5729633492022a5c5235b7f15e46775d8ec229f7b6c82a27cdc69543b903c757a46fdc2a3dbc021be619a59be2a177bf5c58ac8526e4b86eba0c643186fbddc56458ec83b936b0030fa816f9ff4d3dd471f256a7a730ca0745938c1afd5036f41ecb0dd10b121ddf078dccfc430b895254852a3396abe0229616cffd12bcfe8146af55fa60ac34443384486e7216b07adeaff17a8dc20b194033cb34511d22b238694ed086d0b6135dcb456d30ff02cece2a4e1341c7b72388d1c4e99726af2e5c4e9e0efa744e387b10df25b607bc8fabd4a72b12ca8edecada3d308319d0ee2ee58bf9eaf4554fc5346f640d3526b21088050c02a8ffc70a1a0d7afa2df92a33af1e4d9e2802c8b1a4439014dec9854a4d9f95fdd0f3aeb416cdb1f2a169a45203e3cdb631675bbc03fb1f4b9dad23114c31cdc136475902ac1113b775c0ffd0e96e210d9cc2ab813212fbefacc0eecde0cee3609cbc4a33268934ee7cf8436e3e1ff27d67cc8ced49a8b711953ac2e07bd6abb832d180616e87f40958aa9aa5f81162e8083c5c27abf4b3464fef75fcdaa447c1da8aa291a50e46405e8d2b5eeca8e8cdfafe21b1be50e47d2eb692bb981e0af2218e484e54f56ede23254053e819db5bed2e653b2896d9599e55d409bae1b539ddc3f84e0e1937161d74135f17b23a3d474f087b57137b7dcdcd5862a6effcf9bf813a805be52ba9e9e006807e51127876ced82c4d68ee4a7b8144fb1e5cf8889bc68ffcca5e208c91d4217c15735fbb67cbda1a7a330327d6b13b92f853de95d5445b799beca4a62e6c327df4cd1da052323456dbbc999918805c2dde203a9f29f8e561d5d9313195655b1cb7a24136a55c05164cfd6ac7bb45c1a04da857098c9a88429271d3c8c220e83da60683764aac91412ef9109111b24b7fafdd2ae74ee785f2cd4435e2ce8937d3d780ec19f3755d43e16a160fe88458edeaa401fb5cefe4d2857056e5e223a128909126b156f849772a2c8cbf2146e5deef9a142d49d175a9c98cc9d5c411474a0f8bb91970c57a1664a3e88e46f8e0ef5541c3994b021c2dcb02c1ef15bacde40209125287406578f4609083d34c4c4a98d9ebbbd97b8981846ebfa7dcff709e30725ee1f9c6fb3184930c0bf3125bf94a0ef4ae3c6869dc19a2be19878543bd56ff81348579862598a30b727b04375511642a65a486b08c54555043ffb3f3f65b0bebec601e4b6e7778f264bc062e7d2ae73284a243d85b0520b0a0765b917e771ba8dd1d6e91bb5326bb1ded294dfb7cc37e99b3414893ef0116ffc9d48ee70e1ffa306bc94621f3f909fa22e7d2b0247f5826ae9a37de001bb0dc8ea8f063b95994758a34a25125908a468801abe4221b0c7ce8d4627b375a068662ee4ee1343a73b540d378066dd2d10ca39a98c6bf7c1a534fc3b64a317fab3ae459057ce0cabd2d9258afb61e59e944c4c5468fa55768222b45604dfb42133d0c76e13865c8938a807c421cbbb3fccf9edf42995e16e000f403917b95d0f29d9c3e1cd8ed68644bd2f7655f68c01d5a178e021d5063c62decf51c99ea57aa443f14c2d53aaa73b88d0c8266d018b36f2f523c41db59fb1b342ca8b1fdc983e24701b2ebf41ffa76b96a3974dc1d0a0c70b1eba4c3a8ff01a78699ca165ab10503bc9f3c52d3cbe68d6c13b13cef27160104d910dfde91ba338a894a05842bc9027e4c842ec027581f680cdfc7e0511b0c151270539d58d1f592ea616db32a80c65d9baef8074bc8c2c6b815dfa589414c13d242842b9aad7ef0f8a4279342154be3eea29d0708cee66149b9e64c51f81d93393ae8e92ad420c531f4f407f7a00400000000000000000000000050fa76c248ad9b8fc6fe70e3635acc80ef665c6f38bf7aab39719b76aef79bcd098db99af66815ab876a3e611c2b4324273e21a6854d73cc13932232dc4ce3988252cf3a8712c36dd27774f596b89c470fec4ee85a0fba8182878ddb6f7d86ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007cd402f152cc62cdc8abcb4d220de4cbe4175736469182f4ef817162f8b0ecb40f7d88a022052c8d1377c49a0ca675607e62476eda4620af03b2076ed2f6c6b9e5a7edf2b577250538919440f6a5130060be7db00912682f87202ecb2f8055fce09f06331567f0f00c83fcfc5cb68378e5c8702fa7d8b07cb441442e309bd2d0316e7c8a2014eda1e4abb3c977ae953d3b8df62c6fb3ce2612a4ccb6aada8688e031699aea6a3a2e9a236c85ed1dfbcfda87726f68a60cac560ba476b2d2c36871e0a0132f9c768a71b3a5638fd89f5b067ef68f8aede9f6771adb89eeab325b1d4411e5608ae17c49193ebc4c3d71842d5be8bad806b93db422b73a4e97ba2ac78a9021c604220f0dd1ff65def79a71555875fde5bfa1075d004bdc072e187637d7fcd0218c6609d6e220d1f9585e2f484deb61b118cf675a6089d30dec75aee5cf2fb48021e4a2116012b2007c7b9a830cb5a3629c77a1d6ba275a410fd1826adf5046277022d3b89ebc6d0872576d56b4bceffed0df1ba9bef29bd7fda02b5ae2cf51ed76a030ecc6c08ce3222cfff83940e6bdc8af59ba1d867a760aa384a20a03b546a315a1f786b37408de0782a068096088d43d7573b9112c6788e7d51e49a3a0dac903c26148fecc5bf5cd9358bb6f01593aaf8326f7f2c965b85bc1b3d234209505292d7d526f8d7717ad28897491ab8a2e192fb0ecbc492a57f96e67a732ef3977f6eee3f3f218c33430c85ebed98e46f0761d89c66c0128b7b3af2ed70c19203b276f8c8db0a7cb30fc3757550966378262e0864e5998bfc360b373c8c9786fd54e3b9e18660a024b34495fb35d075aec850a8a8d5e58e7088beab2050a3d9cce0ae1ea65575be7fb15573916dcfbf1def0f020fcd07dcbd38062c35184e29be301ea9b591a6caaffc5cd7e10c4eaae8596667ddb45acfd85e82648c876baf40ecfc221c130cf61d5f69e61d5dcd99768cccc23fdae1bbd078cddcdb077954aded2dedb30d41bd3e9d00fb53cb8633d52d88671f5de62b061100861ce1115132b51fa0bedfb00ee2d48b59984161fdcd4adb913a797ed58c1802f04c4bf08553f8d8a2d1cd1bd0091614e7214996cd452a25134f1619aecf0a9b5e619af3de5c6f49428c2a727a6b2711ce24e6002912986145e4fdeba81eefeb879db1c822e6db12c05c27aa7e5ec281c2f9971eadf4ba74b8228074bc19af2e17a3e779e10997faca340d8269fffb8b77d6e455e72f1eef323ae6f38d3d775e5e6e1f951a5679cd4fd6b6ff5c261d174d643466e6064d6ced7c223cabbf4cdd1664eeeaf2e1666e09b5a959389ed14aae60afe2b4f8454d88930552b03ea0d313b19b3f125e635dd6eda0e8c31ab29d4d2711a336f4758bb8220cac5fdbce62aeb28fc6e08f4398a79a5140b04034a5b5e9ffc32dd88da9cffb42d72547939738e609e19e169b0265e581a575947c9947e1fcc86bc9dfac54c4d9ae08f4a9e120d69214471349063155b41cf33225b87a1b8ca749a9de9a8a312405f655bbee105b661f2f5ce494b4967e0901d41ac2d117c44f86c32f6f586676f9f912e32c63cf57d42dee7102a238251b145c1f0a51618e18e3d382c06e1b557d62caed665a3e0cae8b278aea47d6b43046933579a3a67390cec68c4bad4457e0ec424e61afa064b5b5dfc740a6e1f6dce431eeeef7dbd65ab51f809ff5b1033b5aba7bf6a9626aa493747f3e588e479115d48fdd99fa6d4d275b845b12f4b0cc5277324a2c340a948303d1fe782320deaf47cbee1f2bd215167ce621871104f366a7f4f11a26ac524e666fe1efd1d8a6532a3e39b2a29b077d3ec2a599b5be0c607e7230ae2eb6ca7a2cd2768b61300ff22624f6edf6f8bf84ebe78e3d1b11ad3dd833ecf080f4e42e417cefa3350dcbdce5e78301cd5b0c8aa9d1cce9817b5327ec68ae4faec08d6e88bedcb523bb774773bd980657190d4d65a46ccb4b0e6de8513e7698ccbf7c1a2923183b704720abebca8eba5aae39e3018e204aad58ae7cd643b0694cdf2fce89f8e8bc1db01ac9da31c5ddefdbb6717c2423106b84f4d40b718cfe269ce85b93f6447e98e189771cb88ac8152ab8bcb43caf74487a2ce3ec330dfdb539a48df4181a0c27f0dc2666614024fdc04c660ae3c03b384858c7b2fb955d632dba29fc1a1ee589c22f6e4a50357925923ac8889ae2381a49088ab0e40aec31b85c644494f306bd7afbef2f4d4e72eb4893fd829741ffeb53788f456b613e932e30fe0f78b494d8d427cfc564afa82c22b6cf1699e5f6a2000000000000000054d6f30000000000b51bbea6afd8649f1b6da89520b2695c94681e22b64ca0398b90cad9470dbea9e2eeec914f4cb3cb38888d980d5ea3fa24fafdc73fe9f35466587f24397d1cc137533d61de3f61977c579efcec43a059fb23265dd77c17f1ab0833c1e15571850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019002b16552e219df7a3f588a1e35211b5aafdc0a2732f2de978b59ffc1eb50bee0d5de5cb4725e4bf64fe9533164bc3acc345995302768cb3347469be3b582586c53cc5e586a91a7fab937c417c1375a17bf3af3d00da0eff4b3e6010ad8b2e26a3643cf81484bdf0cb5134fbf0b57aa53313aee64e97caa9eb6b1e1e40250f032985a0b7980ad15a4d69ff2f3abf12049227e741c38719cdefb64f2e2d84b9af02005a090b0aaa30cdbbd32b15d50b17178f9e694d28c3bedd0ba79f09906021bb0a140f5548c626dcc9ef9c389aade96407a0713747a6df5a1e1eb3583a07ca956b297402a5d19199d11334c9d55892729eeb9b6d1e2fc3e3ba124a620ae33cc3a0020267facbf5eeaef3ae869501bb6154ac65eb2e94be83171e4d4652188683bbca0202fb9b6f43ec05763b6ff81815a8a90d28c94d659f403aeae3ac5dfe798147730222cf8b4522ff3d354a6653c90b6349dd0b1ce4b6074851e177c694f92264714702174457eacec109f0e3a2f9d6ab2d03a2ce2248a50d0c72550ace3afd0c3f646e031217ab6576043fa0c3651ead0fc8585e7d6ab538385d3bea46bbe29797fa4edf199631b56e257268224ce82b37e9fa08d8900b834f2d0d850907ba26ce1daf31a2cc50ee5974ac572868293714aef0de27d07a12ef4a4ffa8129b6782b996d699d1231a5d11784e67f24e51d23cb893a2cb8745a6e2eb821777381162fe138f40f2e8458bb0b267da8300f630a1331c20dffc750ce7d24e5c0319cbb6b0761b8b10a333c2ed05bbfe80e424f9f9688ed19f2380c4b7654b91975d32198c088a13830ef4b4bcc2a24ca988a118c4943b0e739e0fd13e199a56392fe5dd3fd78e2c0c3fd855eccea482b89f0f8bceb22432f661e8b5d438bf03c97b07e9457b7e27fc3948a6c153dc7f8cf5c0d4739243e254959c16d7d6abe73202f8bb6020cf06e37ce17914e5a7f04aed8dd021bac4a93712ef30de273cd0cb263b95218eabe7366643c9bfed5e4b2f6f15d4611c1272c8119e5edd7121fe687d711366131c77448991c5c8d8751457b78bc8c454b1fd3dfe3f69a644ac4a57f697337c3ad969e996eee6081ef1424beb1dd50185100318524b1649d8b9dee1f8ae43874e828727145f5f9196c844c6957da845baa5418ccaab3f940b0117f3df0ad1809eef3f6a57a64bb1e3b3d9578759b1194588258df5d1d8b5143c2beb3b032873b357ae57043b466cb05b7c272478f9e49c1d21bdd047ecd88bc92ab8eab24f15f715b3837694f295400857f4340222d9fbb997dbdbb49b17d725100dde3bc2de80040f0fe49a98a02e10bb439b3e48d681d972318a06545fe31d9cd5a935d26e5328c9e1850e1cd11af398b02e38931ada28786367ce4e9da793d6c49f93882ed730c884e40a2ee7399f3eb47586f9fe3defc81491d1ae5c2b7e70355e455df7142ee7d35ac1fe8cf8da02ae278397a9f351caa11b923c9b9ac68bfaaa0f9caca7d0c18184a2a611bb4adb6a98cbf30e7bb9f3442fef3346a6a37c186c3519f43a63a810b87bb5713f60cca0eed4d47d6c8fc0c4a0181230b04a5be5e97db49d72a39d57bf6a369f8df829241d202c80d96d97949de4272ec4f94840f94e6b5f77ce5f9fed10b26f8988bc12ef89482867c190a932d593db1e5bc182b985190d1f7bb741ca8479e9a927566d5e95d941eab9d54cb55af3b175d2d3fd012b8127243582f22888d679e0d4619883fe8807425700a1624c97eb313ce27adec83f5c4dc07c87757f1771d78d90eda3a93ec8c4ee0bf293b81e2d990a42e2a1205356860c98e1ceff2fa49d7f16fa16bb76c859c05826a525e1acff240c5ab4a2582e11b0888b58a9c3b46753d31ddd7d6c3c422cbaf2ba9debc51bcd26988d51c1387e8289b10c88b734c0d4637c596bac28ab5a836d15a0c36c69cf18191d2310e0e9f21b75456e3c702efffea5cdb0a22a982ddfd88e35409ddcd9955d4f00e251784097271b403ee9064752ca359d0efe4e2cc11f958642f678e73ca7d07877fb6143b1563f218ab73f2b3be14a2acb13d249dbd31dd8a0a84a07149f50ccf3c0791975a52ad1c75d9c8ebeb6b7b60ad111c87927b45a5242ca8aa4e6d9c679944ea9a30552eab935f55dc2edf1457a34532f5c7791bcc566b1dac4aca258b0e98bf06003191815e08ae2eb9357d0adfd1f9e01cdbbcb48635d2afad4027cb3e94ea4f178f5acc6238aa871dd609dcc155f54ea8621e672be78d9735441b703e78b5d2825f737b1becdd54811c3bb0b5d350098a2328cb91d1f1beb1307bde18ff6f8dcbcc3fdc18519d51e8815797489d445638460af48a5f105725e90969e3dbf5ca41fc07ec47a398c1431bf52abe1df39761ad426ef738465c78d44e7939f3a2aa4a0b98099834f7ff49519d0e432d3750ea0c", "63", 1, -645320676, "a8c5132e7bb19250f74c4e1a1f40c9ababad51df8a9624d59268cac9e8af9bc7"], - ["c137b74f03c654f9773c1e2b2c3cc1dfcdee992b9ef59fd91e7f931c207d6b1b2cbfd3b7dc0200000007636a6a53515163ffffffffee6ddd63193b6ef3c2922b7302e4a0e9ad37a6362d225b44c421e8742712e91f02000000086351ab52ac6a65658f3ece963f6aee77ee413c848788ca41bf021379f2a328dbd9edc98166624fa06906eccc000000000865ac5352515351513400126204990f5a00000000000800ab635200525351bbe831040000000005ab51520053d6a79a050000000008ab6a6353656500ac3fad2d0300000000036a5163c2430f2c00", "6363516551", 0, 200675681, "ff929a188efa75c2dea4369b26f03325cc3424889b88806ca7ca96494c0286bb"], - ["375cf69c035d9eaaaf9319b3828790371b66b32c87dc5d552785763eb636f6ee7377bdc91503000000086a53ab6a6a6aab6affffffff012a7e43f342508cbb049d45a7464a4fc6f38c753de1977c59e04de1a34cadb80200000000ffffffff00368517c490a0b80c4bdc84caad3646823ba109b0af8a8164cbd70b60246836030000000800006a5153656aacbce599960408de59010000000006ab51ababac5263d8b2010000000007526a52ababab6a9897e204000000000500acab6a65383ce10000000000010000000000", "00ac0000", 2, -1351539974, "ebc543ce646e52c153f106160e0864344195b5a6e5e53826334cf71870e0d218"], - ["d0c482aa0408a9da36d79a7590b110464bc309b1ce492fa915a40422d62f72b136d2d0ca89000000000753ab00ac5252521e9dd1fcb2d94aa944b565ba6aa77ce1137d7834fb7ed99c3893052f809a0c01b5d2d42701000000025165799ddd7dd27b42043c4c6d41d5b6113a471712f98c6d817860e3565fea814216362539140300000000ffffffff85b27f4ec728de8081554b3ca6f4b94d76c4b749c6cfc1ae39c933d48a78a09102000000026a532ac3e62901f9dcda04000000000000000000", "63", 3, -1506398402, "39fc0281befc99b730774e7a32d41025fa46f24015a833f5cd0cf37cd910372b"], - ["7c6b0c00013689d3e55feb133bc0b7117346475668431f444f6f2425aa50cc1201741c1f220300000006006aac635353ffffffff030723fa04000000000600ab52525265e93c53040000000002535220c66a020000000005ab6a656a5172eeacc301d8218701000000000000000000000000444b0e625e8f32625a61a2cf67e8df6b11138229228c77155a73da0349e4ff9ade2d976b0ff75dd6d95133379b7fd8378f582eb390de278314769aff032fda037ccf490c3532fb9658466f2b916afbafe938bace9b0210d90216031a9e13eecc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa9e41668af0cb147507a6c874e40b32d4ac2e770b71ac1dc605c5dfce4debe08a22a95cb07782f0cb9a8c9c2decf4ce456ce1e1d88b94fde6bc3db4d2a2dab9e0b3b778d0f900bf9a5d0b7e99ca797b3aa711b5d2e2f3e22c592696ed77e63d303076aba7f3ec753f00741294e911644fb730315e6c1db97d1148effd547e7003053434d3e3e5d007b07298d254c2a0285914dd8bf65d152289a11735b97deeab02219f61546a79ae96193639e7da7519b1fcf278185d5b7188d07f0f9fba5177df0a256e1eb58aef20e185a91b95b478507926e53ab039f1ba647248a661b08d3c6f06099fc0adc1a8e99a73e2efbeded2f2a798d34784a0de5cf98057d313994d160213764b19d74dfbc100e3b078ad14b2fa37917736914ff5f8c1012cf0472d7c9a0207229c4c9b27ff8bdd7d6748089241628ffb454753e9425102c41ea15001d79e031cb6f9b7320feff3a5a61c79ada587aec18d7bf89ecfc161bc2327542f2d58ba020af00d1d1e1b071c31cc802a9aef3b3f3a972c8a781745b3e711c435dea9b10a0211891a070170000bf0f705c37e72aaf4a16dea74cbe8dcdeaabedc9d03ab826b2125e139447d741320c14d7fdd9c3097fb1ebb8d5e7b8be0de094eb6650452319f5b831152f6f3f52fad061c024585b309e5ee4f2df34f1a09c0bf280eebad41b68b8a33da5556179c02908c18153517176ceb91c728242dc3bf413f90dcbaa302ee438c00f2a8834097bd20b2bcf0e7b43c7bf52ce7d83c281dcd6957b2e783a8ec0f8f14db4d13d85db3d37ba569d202a79986d470e58f788edbde68719e3bb006216f114ae2b7f4b98ea0260397d6322a732df57ad032072cd73d04d210f74aa06da14f68a1eb0d06aaa8a94f20dbf27787d71ad517bf3a3e6fb356fde8ecfcb2bddd9f146f6b2e89efeddaee7a1ade1f2590a8eb782170446a329ce33bc0071d43e953c84679ac8b371e1de43e8898fc061dfd8d98ce2b10166655f94f44a110feae99765f252c8c09695742ef3c905a291d992ca9c179e50177105cb69084d0f0098f93d8c059d9d84d8b39326c823c0f1a1365bce78ab2b8cebbab59d2eabbc9f2228d06f3d06a1b63b1448c1c0dd3b1fdc823c07ef426812b9fddf0f9de39ccc6a133d0c64d9a5d7c2f613baf03b7c693ecfa72208023bd8463bc8256f0b8f99d5314d0655b29a71ae2fb2a8ad8d1d9c9c76289bdbe8bf56343bce99d8ccdc75435dfe13d7f67615552609ff6bd3c9915f7c1ec999174410d3fd3b65ddb0defd028a20ac47e7d27c5c010abd3849a38bfc809ccf0beca45ca9852053d7cf138fc2c87609786cba1ec837abc92e8d04c7a7e2fdf15a00768ef32f7e9b80a5e27a18847eb6b09c7c217998951abb65a68f2f1ffa96381afe4ecc6c20a511d97053377bc145c09af39c66ebc74bdfe97a89b7ba64fa7a066db0c6b37a8f510236f29a10e0774f6c3b90217f32bdd985df928c5dcbda5f1ac19ad6d63b9dbc2b991e0e619d02ea3f3548debb6e75848fa0e00cc46eed946ce8dc8bf82f0ff676aa8384f6bc3f39551e7834bcb973f98e2bb6cccdc1744c2f1df9b11e2a1ae45566caab33b3627104d1b6fd281b1fbb5aebeae14639303cf1d40a782c4686d3920322bfa51147d450b27611cdd9f27d8a9acf5145fefc2881646858623dc827128a8978c2e543f4f309c090de65ec91c6f25ae92ed258cb0752ccb8256176704b3d482b216d7ec43b0a8776a7549feed2931909b9089f2998629729238bd68af80e3c2c88c0f323af56bf3c4d2b1efa1f0e6b3ef8617503a8f159d4f917d956024731f9b4677d0d5eeb9e8b7fd8e9e6143ce3567b47b79370027b74b237d264927d58b82ebad37207ca02ece242756e55b25b0d83be831a0ae06daac936ee4fcca56afddb9f5230d5b21e91e4d2d9ecb91b19f592d2411cb6c08c14738c3283f1c3872ef4d24f92ca33664f7ece4445895b41e785ea77b6607bbcd8fbedd021265541c717c97920bda17af39436c5b4b380029faf60db66f5ab37a08e76625c22824fb35f87caf91ee9166cf2e734100e217044ddace2290947ef53f9ff84ccff89b0e238131b13e0628ce96bf6a21b9fc7304d7ff739d867cb10b61f9fcee77373b610502abae21a6c6607629dd6cbd1258b42614b3b89bd6628b429538993fe5f9398f2f370e8ed27832af8dc4ba84ca216c59b4b348c185da7094ce7a5ccd6d8745d2b4a2b200e33a081b6cf049726bc9c4b3cabce0b3ef28901919f8ea537a7ad4323da2165648325b6658739cab548a8386c592eaa485a6bef28b9815ab13a885acedaf8b473c9d11439c735c2219e616fe812617adbd9e3e82781f31430cb8689b6ddbe85c2bd3931201c0a225548dc4216b02e7a389111cda5f6d2fc984a6fe3fcccc67070fae0c23a005737001", "5152516553", 0, -1490017737, "704e94177f5a311c53590bce2d1bd3df848b1200e471f3cf8eef58f0c3615f22"], - ["3dea1afa015b498fa64bfe13a54f42947c295dabf75fe7ffbba2d78984760726661d6ddb4c030000000851acabab63516a51ffffffff01a4641402000000000663636553acac00000000", "5165526a51ac6a6a", 0, -1612566191, "906390cfcc1cf43a915fb597ffbe08a3d441d33b21a33b157cc5998d5127a21f"], - ["1c28162f044291ac71b3b7adf788f47b432a373154aa8238be8d73fab579f0e9c4c2af2c4d00000000095153ac655151ab5253ffffffff27bbb1278809761ec719969e01fa07fe0f34e5dbd57e2e7975d5f744912dc0a70000000003ab52acffffffffd4aa0f1824a21fb5f60b91c4f83c03dd6eb3b008c62d3bd097e5fde2b637311f0300000001acffffffff63336a920801f811f0ba287f17948b89995f8454af67c1a5bd994694094093d60100000005ac00516553bbc9751603be1141000000000007ac0065ac656aac2c2acb0500000000006d423a010000000005636551636aaba3252700", "ac", 1, -287142519, "03c12df20878e11e510b07eab2b62b7a73e220c8e0dab6b78c2ab8bc6c87720c"], - ["b1a534fa03a0472f5c0f1b021024090ffc1c54a7ed838c7127307d7da0de8fd6c391b9d4040100000008636a52ac63ab52abffffffff79c37553df16a1688b5ac9a2b59e0bc28377f6a42ec97bce0453f4c6b831b16c0300000004636aacacdfb4673a847e55fce4ba1396b64aed279017e07a357722015cce29bd7e4c562ec7334ea2020000000100d66c3426024f8fed0500000000025352e46d570000000000046a5363006617eeca", "6500ac6551635363", 2, 158221600, "50f6487c617267d11ecbc6831b52ac3e8fba68e72abc7c9f9b00233eaa584ace"], - ["372fb39f036c7a8e6b1bf477f2baa7dfaeb9f0a71dad045ee1030c132dbbbaac3951b00c9f0300000004526aac63ffffffff65d2473bf2f55f1937e0517c03e197140f315f3739cffe188407655b5e7ee9090300000002526a43018420be5d38c961889373da283a5f74b3e5b3c29aa556936dcd83b5725b641b6eecd20000000004516a0052ffffffff03a1b593010000000005ac6300ac5243e0cc010000000008ab65abac52656a65de3936050000000005516a65acac00000000", "5200ac515251536a", 1, -1807372379, "06951c75f703be46fa836b70c623ec7024719b3d72426c4bdfd9bab034f09fa1"], - ["d0c7d2a8015c34558957fde6643c7c2df5efdca813a8d49ce42127b52ce07ad430ab1ec81d030000000251abffffffff0337fe8d000000000003ab656322133704000000000365ac531ca5c6010000000000787d924a", "ac", 0, 1119628954, "4188e3514f32a682890d71498123498d76a2d9c9fe460513c760b0f844413f30"], - ["92785a37034f9d20008dbc283df80b42d43357306bb1f0b185a5a638b3dfbf88fc8e126b6000000000076552ac53515300ffffffffba609f4bec2e35809fda050d770364477a37cee6a37a26c34633f842406d193f0100000005656352acacffffffff215d9e7d4f1a8801d33a43605dd03ba2ba95965555bf113bb7649996f4fde8660000000007acac5363abac53ffffffff0252845800000000000763ac0063520063b228590100000000006f64bdc502000000000000000044bd1f00000000006eea51c33062ec244064cdb0a03ed4fbd2cf05ea617b55e2eef84888dc6829fe542d995fd6359b47541e4f76eec037e79a2f63eeb66993f8e35e6e66d1f57e449590e413b75163e42c89f497d5d8fa4f91d65a7d903a3925205b1ae8c3d460b90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089050010f4d7c5b1d2bb4703903b0ac4b2761e0c2dcb1f1679aa1dc7995c3ef75eceadc98b4b0fb2ff30290abfb88b73d33bdd7e8874f8145e29f28c683b906ae5ed5d588e64e612dc44b2cbb3f795040d05dd881b9a074094f7d95105c745ce0a3bc184d9554a71bf881aaa106fc6166536922f4c78e501cab4e24560ad9be4032448370d101d40d1d541d853cb6c3958d34cc688535850386dfba3a7f840645a022e90252f86437c7f8173e319a78d9dcd9bc51db6e4bb83ba68ab419c371dea260b1639eaa6457c9da6dc7d68c06bd9b77c01d34e5b8c7284f566e6687347c69ee4279be083a7fe57276284342bc13c986599be3ebed89d8316ec9eb37cba2c21c90328684526385bcf6eab24c91bca30f38a2732b33623a0d051fdbcb0b940fc45ac030fe9e6927964a2f13837ce562a4b4c46ca683fe4b08262c8144e75e32d242946031c5f137d6109488236e21cd3e8ae93078393de186681c62408be2b3dd0f2d83f030b868822a44e51972f773ebeadc9b1e6194bb48575fef6223db6dc7edf60ba0c03143bd923714650762517bef19fc194b43a37c9b70bb0ff93f8a825d3005e2c339d6925cd71da9887202131b20a8bc5b5ecc9deacfec9126ddd338d6f2a3841359c3481d5205962bdc767c7c5c45b27429598695be1124059f3e7e7bfb0f1dc3c88c0780d5e20453b4fabc83012e093195976b90e84226ff0afe1085c35f62a8790fdfc2241dc1d8bd2ecb3453fb99bd8d86065457d4f6e2d90cca23cd171e6092ed5664e89a98c7933738eebe64fe023d33fd5f0675b9ba98e76a5876c816fd91075065d4b390e93524f9595c628ac9e63f28271894b4a0c84e88a5b41c93f38100f274dd722da6344123ca41fba55ade43ce0fcccf3babd17fb2c86b53c38aba85a84a72826cf41a620e72864e2805bc7d0a2b83e99bc16bb088121e83ed016692d36ae5565879a0dfdf852df04a8b35c5261420110113fd65d47c264c252da2911d58a7ed4598a40d94d1e0d385fdb289206986cf76b5ceb4481c5a98863a5a349196dba37b2b091850ffb225cc2bfe744daffff1ed1d6b947c6391561716e05736da86cbac5240176fc4d3600bf78e2e177a69aa45823c80b2d5fa0ffa7227c989820c06e122caba43e2be39db55228d6f8bccf32692419cfb649b42f56ae241a0dac1f7237b2ee3812245fb57bf568b4305871777d1724e5bfa5e5d041006840e55ff22d326f39697639a030e77dec40cb69903230dad10bb291d7af1e0f191c0dedb09b20bef3bdac66463c1d5cffc417b8c7f5784c0f9a08f1816bb2d9130e4ccd9bfa222b647a938ec15ea6e72e3c3125852a80f0b70e6eef18fc6b498cd90c7d321136875c3c06aea6b2adb8da26ed79f91654dc9c3c6d3f537c4a06dc4085b4db6cd5595dab9f2878c3916eb6709b8f3f238b4a0df1a8728189d276eecb6e4093eb1bd876e3d581e7e8d4790c2ba9ecfab3a76a036b54201cc77547c975298a598aa2a3bcface420dacbb76aa935d8a7472d2594ffaa475ad686f0750fcfc466a31450dc39d0fba72215b80b188df34f761f37ed6adda8fe185b1293218b3f20d87253c24dd91e99359351e68f78bb25106646340d1b75a1d86e8dd56349486643b38836bf05c7361a8b849d836a830bf5b5f1b9c0177c5e873908cbd9f5724cb10846e13556f13a2b4a75b57b2d1f7518cbb1a212bf3ee2e0a9d7bb3dc7ca978ffc42101cb4479ee8c1c42038b7273a12c6e940a648a080de59308ed3cc65222bee82ce6ed29115d0db76ffcb95f13dee8fd185a8dc6f31f522f04414008defe094e1020fc9053a1ec32068d22e75916ebba036af64267792ec7cb3bc1d1b121fc57d97ecb7b8dc53a12be1f93df73bf62210e213c759190b9f5ef15f80ffec7f53258c328890d42b5f3968addc2814d66a8c87b56b234f20103a533063b3bdc1688944dbfc3caf1171a53292e977e82e7fc7e9c98f5bbc86b952d9ef59e587725a5241b754b7d037b814c49bad63c110420a5c80bd115785115ad65e0ccdf5243f5e311ab7fbc106e1d70a64814e5fe9902ff44d37803626ad080f57c5e4af51472e26d8f62500cd8e3497ecc34a50be4116ba9d935b50b8b8630b9e767724ac15008e80ca35aa506d1672c75310dfebad4e0deacd070bb508671cfb31ca700e5a4b0e9661d600f4c15838b1ec5d1be0b43aca652e3066341a31c1dab53a4963fdffeb35e5a8cfda780fbb59e8d02b0a65d9dcfc5b5740efe99bf0298d4bef84b9252ae6860adb950ce13a9d200000000000000008a60b302000000009fb24bc204c521668af4eb34b1a91ea2aa04a6c32c075fd717120a860fd7d513b84ff3df8dcd9f205674bfc9f0a460936fcaaa8cbd5490a7b1ec05224bb4432972142d398bd78ac0dadfbd87369d11d4458f831110285e6fcb2c6ad350472f4f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007880f49ae7cab9979238883a39204ed99d4ec88fd0df9b41938cc4ab8042b932b288f054293cff8e58f6b23fcfbfef87c2e830eec2e8b2af333a8105184bc08b9e8c501a9570865f23991e56cae8d484e007bbe28a2c19c078676ce13f5947750bd7f94c59ea1956bbb26d1f02dadc5fd933c76e16133fa9277a6b94a3760deb020081cc59c034c4cd8d72c67c4ea8c50c64cb812a0424bf10edb6ab376b04b1c1021bb93b6bbfb929ad2df1d6de9a9f27aeb8d9ee024493473d588e9bed28a16cd40b02ad297932e653f9480362e1f0bf85f0e76c2b0895f2b89fb4160eb27640c1971c84b00ac569500fdf28ac7206faa7393f0b02701ab1b451e4db1b9aaabe42b10202c3ec4cbe6d7743948f7a5f4fe9390b59e12c783e6e53a3af4c60c99b2dc521021a34a3586a145a1a3cf577c7637bc9d416b162ede2e6f113dd8c4c5d8f85409d02057b803742d91353fd868eeb04244d2745c7f2ade0f719c008434719022a580f0220fb3afc6dfb044c114e90e47d0ac4a90644bed3fdf96d098a2fa3f96509387f0216cbab6ab9abe3afeb6c5733f654ba644900013f6e09b0db74bbec659b3915427e924b97c4161db3342efe54359dfdf4c5f7589ffee5fff9f2f4b31cf52f2628ee534730ed379c63ea1863edde61a6a12248986b950dcbd3dd77083b6bd70319b376e69125643445b9b93a07489675315694658b6f704664d88a19f6cf3392b1fccb1b2bb836dc9baac19225ead4437c53e81f7632df8e9cf1a018f8be57b05b9abc427a1f7494a9edaca3747e691d57adb9d53d36e84a455ea8d92a42d331dd8223f8e2f6abec84c86f79c1c935f234b6234594e838bf6a889533533082039c25d807341701aabef6deb869bea6102c8849da2cf11bc186cadad3b63c2c8a5d0fbe3a4b8777d41b6165083bb0bc75674ac45ae91a2ab54a4a544445ea5f73cbce7df28f0431c369bc7c7f9428aff441b79325fcdda0b633e58247bedfde51ae8cf6693af7df1a8995da85ddb8daafd83e4e03759a06a114bb72757ebcce0e6ff940d71ee4af585a78d667fde9783f307e33c82819c4a8e55c30b6c182081d6340eb2994a33f0aed31251036461bf2a7241b2443ef83f1651e7896e536e433bde0e666a472b458193f974aa9bd691a0b2a333294c71e38a2d352edff3a47c1c2837da1cb5e9d12a261ff63019df0be184dc888314bdcc18f07c842c0dd5ef0e2ef3529343cc09496af6400592224ba6f794a82965e5edbd76d82fe0d12166b28516aa7ef6e02ba2e68f960acb2deae00152fdf9e1d9fdd4134e9fa303489ceda760e8ab75f3f8e2307d4047c273f12cce3f06ad3a4ffa6c5530f46bdf93b3ebedddf79430358475a59cd2312c50570593f81e4dd3f4467dcad26739f3f87dba6234bfc0256478f1737d6f90583e8269e69583e77dcd776ccad439ab4de7c584792506c541ae7aa0432ab99e6fc0218fb49a46049b42a686678618269796754c94ea80050ecebd84c2b71bb9632c3a0b744129afe77ea3d6d917541f55d2c61738ad542bebf012064561977cfdf124ed404c87b6657f23c1d4137f260ebf999989a5c266b08f827b645b9766bd7cfdcbc53389fdd04dd024675ab25333e9676f64966085eb35a78bd925bd9a1209453c9d55803a63739639bf4b8bb67100a6a7522bc472d94db5a518927af92d9a3ed6092493b43385ec511d3fc97386d767e16d395369f034a58c861ca86702b0633d9d757ca2f4c5d972cdfb6f88d691f9182de11caee24c7f78427aee09173a690a5bb6f381999a4ff65988a1604e1bc60d13649205f6d17da9fe87745cb2ec815d22729051f21a7ba09190cb4a0340d6a8ea163efc6899e7e0ec45a88d1d7d4ec58d520d05fbd653a68431433692527177f0557b4f63c5fe4c85c13c8ee22e9e05cc1c7fa126733a9de0eb50c6be1c7a121c03c2bef66b64cb38f4ae93b6acc5bec7ffb036a85f54ba0932ac2614044783d325cfcc99e709dcfaba1913061453334b6f5b245d9033c2903a886ff24cdc103943f05c6fbcfcf55dba347de03574886477702138e65d353071684aac0f9d24f5fd115d6164ad602b51b33dfc6488236623681f53e57a6ed011789f9b3d713ffb656f24d5dbc119b1debf6fda83849446705ecc105b6606b95c581782563f6686027ed41f626c96cb8c54e3ccdfd4fb2ff9047f052025de6612f573adc54fc06288f2e5b2be67d3f8a5dd2d2fd533daf356d0985307a91a8a0cea625243d884d4ed16f8308c7f9e404257baf5b6e100c11c24e3e2a6c0d840506b36c8d3d10fe9c06844f80ad6cec1f3a3a0c4837042c7dd3e00c1275eefee93d92baba41996807d489b6de57cb6aeffb71fe54099682c49ea9cc84bc6ecd83663af952c722afcaa067f9e12b6a66540a6c7e2a364b86b10f", "ac52ac", 1, -2006459521, "49d4df96f9c3cec0889d4ab64086607857846f090daabedc61213e4e85698c73"], - ["21410e0603148b7eab5fa234d5c72e381a47e7e165348d3b2e91cd059b1c461c2066cbe0180000000007536353ac65ab65ffffffffd3bb1945642fd76ccd2cafdeb3f7531526945377996b75c9117802e873920e5701000000066a5100655100ffffffff900370fd304d531d55579cc7e61ed7dea5344643fbed641f01bc4717ec0695000200000006ac6363abac52066b11ac037b55a8050000000006650053636553d5d67d04000000000853515353526563ab3965d201000000000653536565ac65f454cd6001d11006010000000000000000000000003fc3c7c70d6f0c2261a91e1ff5ca5ae8a4e0d57c3f71f6ca957e65cd6f0545369d8b8e47a91b43b9c920c5ab218988630586230644ebfb1f4f7da7014b0df377165b5b989be955bb1da1291c398f3ff78bef19b5f16827c23cc0e8cba81e787200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000654e225a282b89f56e7d6737e88b74101bfa04786e3ff42ddde5bd4f8ce52e5e2a114125ac19ab708bf7d9fa6bc52549943c4e1888f41ffc6d10f842fe2ca9478ffb7ff5dcd423b065f87c857651fd49e7cdc9b167fcd6cba484936de507eafa0157909eaab849a3333b3484b2244aac0b4fead589f7d70257b665f431a5fac6032550bcc66f9986366102c42e40af642bafba6bad31b1722f0e4c84c469799be7032eb1209b0a10181a69130ee4104516bfe08e6baff91d4adac673fa11bcafbea60b13c0e88c9871afaeac120c17c2ac2057698116098894e901d6f9825fa15546e3113d6b3b6499d553801fcebae84dd48eaac386eba3e7a387304ea36ababc1a06031b4a59e7ec79e146b982d61db2b28223f242e55ccf8aa91f06fe0caef80d6c3803191549e4100d0eaca3445d8991c7194bd6e1b7f66bb1726288d95b8272dc4a45030f99d6a0740e2e7e4f9df4f84f04777bc0d5a428c0d98cadd0eca3f10a1a02d60217e11dc9d6155f671acc2714ee97adcc1ded409c41d8e4749bd6148b9bd4ded6031ea58547713cce136570414434f8cfae877b20cbfd8285c38ded546ae552756b15e3ce7de4ecdb5ef7edeffcf3e09ce62512b686ea5115f1992caa0d1d530bda8a2f82cd7bf0f3f1dba93234b8d22d451c9ae114c31f4a8200d4c630a56aedade3b328f2af776d2e2abdcbbe1f288db7fb9eb568b067b559f27b83bc5c569a8d357afb6afcbcfb6c2d8c253079f227d8c9933ec9e1db51af97c13de5f683ed85893152c8c606aaf6eda638c1ea2430c7e56e2874706bb50d94b67204b2b3bc82812616ac15981eddcc6cdc9e05b14b916e236ec0ace63fc1fea090ec120ffd338dcc894fd3379f4d528f0a945e8b49768107407c46fd2066aa6ee1575ebff40e928792a78bbf303c41948251660abfa9a90a8d900df14ac3c877dc419505af147a5068c6a6d2fc94c2bcbae88e07a7987588e564bfaddf9f7e8beabd56cad76306aeefa048fc3498ad02eaded6011775d40cdd41b5771b32be578bd11a5675eb22133dfed19ecfa3fa1faf0b918183f83a9bf3852ebdde2a183fb088f911e22efbdfb4d2fb74363f7422169d4ee812a0cab5b17c851c70461ed701d30d08be4067a1a75f04958155ddb91424c7ae99a54e4d85cc30d86f1b57f88232d95769e926605769c6546cf5ac8286b7c2c715076a7e973c1fd57a7dfc3fa843267000af221144f783828e97b1312c7782746cd25a75de1213e31402b9ac692284de1d103b3d4bf3183de7cff35a388d4b6e69da79809a00c03dc182b9408a0cea19e3c67dfbc66b5e8cb8a503b7808c5d25ddf3ea88b7a6b687f1234f76751dad2277969f29994455a7951a81a715bade8f8c47be0d2bb52261763fc869d6dd3bf0e0382150f6645ab5e145b29c0bb561c23657d351da835401cbc2e91d09a932312fdc118a53bc3596ee3b2725e814bceea8c549a664afa4db89f3ca467f8f9b94a543f6bf7b68b9cd39c97ec4ac07a7c3dd56561dba35866b6fdf56ad2d70e8fc17ab6c950ba70eb30dac277bb1ba7413239c4bb8af0ae0f5d21febcdbbf1ebb0839062fa393b1ee7cfe3b78dc478f5f45c8529d0f21eaee2c7b2fc7a288baa0d31cac1f1846a954abce93e29502b5b0dda98cc2506b479f3245d0bdcd0145614dad63f22079de6f6e173bffe5cd61ec3047608643f27a4fcc5a3294c0279954e247f7e3ab8a1824a1184a0c4c400d6d2ecd37529f11b5630db65e63e0a76936f7a6e0c895eb27c526c48a5f2006f79d59bbeb5a7c212c30ea1c934608a8ffcd536f38cc548eb996b356591f3741d578cf9d8fd280820985d89fb6faeb2cb68eb21d2d7496edfdaf3380c2804a18cd36d8627491d789daea21193c701103b73a81e034033fce65162f89d9b9486bff015c3e87b2f15db76826bf67b3e62410a1242dc2a13c1474052bc2ca5e4b059d19b0c12f0ecba94d657c2578135405fca4761b86ca8d0e0c94a54c686b6a3a1d4db45baac949546137aa4cac1baeb9e7778e20abd876dc25f9d42d6c4a0f3b23c30b016ca4fe153d1c227cd9517bbbd964d9e28dc131cbe679eab6f9564e3f0050c353b103f8fc9172318d261d9276ff9eef2d20616e3300d1591fb0960f46143289bf1d9c26483c9e3c5ffc98fa10a23cc211d1b9fe84dd5f032f8cc16cfa743d5f081349370eadd29ad2efce20990e62a5385a9a7d92928fa52d9b5ad7abb590302c4b16e2f95ee7eff96167be894ed8367764d251eade35659821d81e565af5427a5f07800fa0875de34debc3fd96a5ff158b275878a64b729fa00bc6f194107c3f9e4d3c601126402debabeccd8f63f7567ad90ad95868e9dcd8afec27aa8075c75f71d5dd7d244a7e4d5721a69e0582639ad08235a6c40e287def5b045f9b7b41ed506", "ac005153", 1, -1261392869, "821e787a1fd1d2a63b0b83b192cd1e7d20bc2b14296c7ab1616782b01f15d72a"], - ["db4813b3023983d2eebfb3aab865746c655736ee7682cbeb671b110d3f04ac573a9ca5e1ff030000000100ffffffff0e7211b4289294c4f8785429d343ea57b178870a6869cf8675dec1a9edf45cae030000000951516551ab52ac0063ffffffff0160dbcb0500000000036353ab00000000", "5265526551", 0, 1228609669, "75edabe179544a7055878c4aa824862185d5b7a7c8c4006f8001bbbdaa96abd9"], - ["686ee92e03e5ff970fb5acfb484fbd2b971af67cb5f827bb2819c2e740edf9b2956035bf2402000000076a005363ab6363ffffffff7b7b949dde6f992989297d075d51f791e90faf5ff80a1dd02fe8a283afe8944401000000009e66457ecb9b459529b16614bc9f64506537c29242de08a2bc05dcadd291cdb161f9e20e02000000016368e874900189f8eb02000000000551515153acd01ebab0020d879f01000000000000000000000000a3f6adb5ae818b1826f115ebe60e9e477657e30e6eb29e46506740cb27be5140547eff1ee0e7bb65e10dd4f8904a1bb20b65608f980e39c4471397de4fb9cdc87e3aa9f055a8e9d3d1fcf208a9c6bc828c4cbc4344cc3019702d391727b933e1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007cd7d2243d138b0094636ea573ba728af48fec4ec464cf2d8aec2c14866362f74b709cbc2129da5bf0d53d9eb1ace831be480f6d73d0388e79296b578fcc59e7dc04d0a81cd2bcb12d47f093950aaea063460e090e47a8d8f9d8553d2de9701e933060bda424be647b5aa8474b0716bb46d5f1a1dccfed37b162c74fb8b824b10301dba0e998d6546aeebc8f58ec92320d3f116f19cf9b570488919555c1a55c990220bd6b64af38214573afb827f59dc06a9bab938b47bbb87163f1d5e8fdf1e2ec0a26a75016fc0fb3cf72801d3ba047d74e505e0f0c4f99c917a58fc4174f2ae2d81c605bdda62dee15744a17d2322f46b80995dd71aa472bc7b17264d5786842e70229076d8e168f04e68b2982919aa4f1f9de45858c0d8607e18ff31aaebdcaf7da0305339e2c0945f9297322a47fdaa13f097a93477fd130ee4698ba952243746da003073ea4914219d282ffd261b84d4fc1052fe6f711adc2f5fbb1b96a952b9a8e0a02134cfb16a580051bc38b3f4e6feab16545173ecd2a0ae05fc997ffb21a6e3809021452efe114b895e5dc098e86333fe493e2d294923312114d3ccb942b87e9432c3abe2d55194dfc41915c6955edc2e575ce786205b8b51d500b6a1d729139f8262b77f30fb4d1b0df357f71b72638496149d8c74f59a23df8ecc124df808f33de49e309b1435e3db5c32f7ef60776f04318c7c7ee5fe04a022983e6fc5e177fc98d3f0bfc31508c8f2ad847cf298bbe697505c241604e2f3c078b92a2770c9aa362cb8b8091d93bb4d1ae1963d61f3970f2cb948fd6db65bf52ecb6f0ad585b100f83b3aeb7a4f8942407cb5013e0ed2a7d1dcfefbae72ba79fad269032a4f0f88d380b2395d8c3093fd1ca1f735253bc412dad4446c85a43770542cb7c260b7efe6929afa4c21a43432c9c0e1b7c377c7540adee9bb2893d323afd3ea882a7b29ea8c69391f36d628291c6cb9660dd7b39e8e813f9b4bc5724ec94f3b713ef8f764c3360299408e820ce2e7163ae47f6ffde18e082625a06c8051e2d292c62530b9b225d1d384aadc27ac268791737a05db08f70bdf343bb71844b94c061dd4e76247db6ad81dac24c56e371c22a61a8c9285d2a91ba350514a9bb9a478698257bff1eac039cb427afb413c4e4f7b8b1572bcd4f0ec6d2dcb2a3549f191d92ae2a1a9430733efb2afed70414c7f4863a16745ff7b637d0ccf4d23452deb0b5833778076662ff75b31bdaa1b8eed4f1415f76ad18a3750bd3c6492e467f659ea8b862b7afa4a7838545d02344d88eb487418c403248218eafc3aa2f627f7aec9263ed5ef51a00bfa2a80b4d921ebc3276a9e77dd9f15cc8af06ef5c5ce1949acbee87d0e9f6381a396984f21e05f23b5bca81b1d05305cac375b6fd58937424b2bd325987dbf5deb8fe6e7f54a93b70320adc7e099c93f0e26eb7fa6062e692fc2be3998c40b97a46fa5f3de3f52f5684763d42f919b04ab84aaeec0bc49481449a8864e1d3e83cf45bb830d066ae924c51e947149944c170ae66a2cd4ef2b05815f0db685e043e08e6514ab23a9ade3a855644332cd3653866c00e2a704d415d2b6ceae003f0540066246e762cadb125db8e1cee6a2b94301e454b45a191e8d70ac7368d50439ea43aaa0e1ec3374cfcf7e771bfb0af727fb59b316600f448adeaf2c2e08965b755c0308ac71002f89f9f9b9abfa28018acb0020b82efc49d83966d2bc613eb2143e6f42b85c3ea600b89b2c4452a9f7ad4307812666f01458865e93fed999dffbe2bff13b860713a06487a230687c33a1b30fde9e0b8c2510a59a1d66ca9303bc3b2206c142bc0806007f5d31fcec6f78deac9d957e4c92c4c9cebf22318c5b4c1100e61ffd19ecb22e0cc60fe2985af55c62a9712a08fedfb2da7938cec0499191e76bd90d8df9c6cd4a0a5d0aae91a393a6a2c5759919ab96da5a1a8afbbe3112c2f711a6226af91b1e369ebb746c11dce48f22fc5053285c42321ba6cbb32bd5dc1e5da4ee9bb108553162b12bcd772dc7c6272f91db945fb374337cec2d475fcf8756da6a83feba68a42acd75070c4be0f82eab462c3679e4836f5fb80f8776dae7f3cfcc94978c8adeadd18f5624def202010092e854d250ea780c8f4576405450551e7da3d8e1b22490a85b55bc648b8ae97b0fc85a8183b7689bbef3b7d6e846544f5cd9fdc9d5a3c2a66e1b2d42f55b629544492e23de5b89f6cc0bdcc086c9913586f7a21b5b77304ef74dafc440a5af563236b6ffcd9a853d3b996821270ea7cbef2b84d108bd8466501000000000000000000000000920dbb0b8206ae6b022769960dbd126af68f628342255b9101bf98e0e4b05df9c31779c6275a63538f756ee08f2acd445d2f73a6b506c4f286472fbd25ff69e7ee0ad4d4cbf126ef1a1d237854e5d797de17c551725908f42b22857d5df0182100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2fa06c55dd6a34764846f7812ad38c259402bfb5d2b8f05f4dd8f384167d7d39deacfa0064e25e74276254144f71fd94d75bb4971c05a2ad31fde4487bd8ad50fdace4cc741ab42a9b6acb3025181bbec0386a1203042282c322c1cdd39b32be2cd9f4f589b68fbf61ff4a60ae87e03921158d9bf6b6f190ef30187578ef88f030e14df6b75c3ca02c7c00f42751349497a81a5d8bfbe426806bfd6097be201a4022151897ea041ec6f203cc02e28003130a77f03cad330d0522ffc87493d91c1110b0333a4bc91324c4eedfda78f9661808fe0c164c6a009597e8d31e851fdf00a4c2e210207f399d9392f75a09b86bef5a064acde6ac73240c6ef81816f54726380021c739cd182c3cca87bc6f1eb6b9a9c91154f7903e6609c75f8d871f99781bfdf02166368c1996d7d136e1daf6cee4591a14e976a25c1ba3fa942cbebfff4ace9bf0319adf8bee8d7a09ae7d6581e2ad27b5e39ca663397238fb8b04ec8d7aafc58d00305db1b6e108175a99cd4121b5c0876090b0285aedd05b4d4508aa6938df365d5030a4f131cf47877714eb4c393f1a5d6ae2a0c6687e676c5995bced1102c3d4e6561522026d60d0e89e6da1d55d392a564c69934e52392ba18087788372ddc42a1f624b20b646c02c74d202330370f0e30bd8b7c49948dea71205afa2b3ee4b289719f90e796756cdad86bba9fedd6e4fa832e1ff2a93e0c90f864a63a7f5b1a9ba0aedb7db72ed0ed935e9dadc2dc20c4683742a860225a73132e0db60611d1d4d85cfda8593d10b188a083caf62813c13c7ca606ae40c18a73108b00a65b2bc1973f5bd58ca816873c5484b5461b9376af9355eee0af0268e104e136ad4f85ef2681cb0ad4a2b2caba11f19db17dcb954f05da239fd38a5bb3293d4c7cf2ffeb5e77e3fe7ae3ebebb93bda26000ba3f0601b00212fa97f03257095930d52accc250b67b6d703bfa200c1dc68f10cdcd8b9e9d02f52c06d9627849cf6cf76e4c2fb2f0238b3c21c9d2ed9636ec112b2d0dbe3a3d6de122155f2bce6bbdbd891ebf312a09614cb6e37a4faf12fcfb6e6f6158774351ac9560eb2df0802094b7b6eb6c24884b3b762c150ab043dc340cc68958aeef70c6c2555125c620e4d1532a07e04306539811cc1bf896ee637b371ad9fb0657157331b07673921d9f860141bf71c1d817853c25cf0c0ff23ae83ce42f29e54b106b2badf0a1bfc815981c15b6c1818db20e4f0b6de165c5256e110fb7c98766da9112cfa5301062ea272e6687d19386a2ea020a66359e5dff5745f59ec28658e4e11f5327b488ef1c1e595164700a555928da6401409b91ac7ae8d1623cec2fddc653fbc4ea7b8085a699d241fc4367656a9d9a5462276909c3d61d21789e3c3712b3633702a40de4385a8e152ab1002b9820db80cb6b2c9cc365ea3fe2da3ac752bafcfffac318638779ba4f80f0a88f807cc2f28a2f29ade17457342f4877ae9a28aa7bd1cd6a17b477e7992b5a433ffb74eb72fad0505871d592eb02c30459f78a6dbbe5bee333a150682855e98a7a417af0cf2ec8951de3b329944dafed9c8ab3374942070c63f5193291f0d188b97282ab8681838f8bb62724a04c1367bd72560ea15162d528ac79bd15e3561825f1ce26b9fc47b6eec0365c706de3768f99d554ed914c16eb0a7c7bbe1f0fa9960b69fa1900020354e6d1be7c471c99f2f38a68c9e19b516c628657a24b3fc1974dbf05c2f3d193289cf446a5524873dd9522c72254f27e5263a0d71da467eea1618c1b843e83e2b344e90d23306da90f3828d195bbd4801455a7b3f8c0dc18a2085267005c12741a45a1af3fb2a989a18f1d374c8f7f7e9fc20bb5c9fe56a3de1b28dc96680fbcc6363711133c896e7c05a947981c3a20079e3797a587b756be3ed629a0f0cae22c2167aaa7fac0f4b2d473a1922ed11d51775bc170239ff16185ea170b2504fcf2d3970427c206f8904dc83f10077770dbbb2922fc85f14f0d86dda2ba1d23576431ab83f37d7c90046bda028d712d95bae1d94e4e8d098f92c4bab87979e3c10d2794f446da706ddd57723b4018542c8529393862e7a1c6e450b5722c67debbb57787551a0e7c151256659183e735098e342879ed6858e41e0c97f9245d01cca17e97f1dddb814ecab83db28c6f64c4eff569d25375d205de500f7379ed26df771b2646afb5e4abe04bd18c1b7113d553949fd3018c484cdf63130fa88f6fcdf629338e0787bd35ca71ec4923f594cb2d8f853b88f673028195f04bedef619b88e3f3cd44e29946d90d105307080afd566e75c0f078d8e0ccd4b9d593b250834c45e82b3ccc093acdd2bc014183c4ce318efdb475190e8e6fd70d35b8a4bb90952b68de8dfcf5cd9c214cc6f9b1395cf29d1b4addc05d6a17e4bfe9a7dd6d124656b72de6908", "5351530000acac", 1, 2055472226, "271189653df5d8387cb9b64d996c46ac37da99906be9705099b547a8607c9a05"], - ["266a8348024815decda64aad93ea273c28bc3bcc154e11b54fe98381c204d51cc41f4359060100000006006565ab006547b5f89c93caf4e0f2f9203aa2447591fb6619d2758ec36866a1f71f1a939d9f31d6ef5600000000008621b5dd042dad4d0500000000065100006363ab4fa4dd0200000000095263635152515152514f88f50000000000010005adce01000000000200ac00000000010000000000000000144f6c02000000007d70a8244c98d73389fffd7dad3d377a27e0b5ed0884f4b9ffd23bfc25d7a28b5e17aaeedfd6ace3cd60772e46c86787ec65b722fb54f996a2e08e5652dc4e155bc842beccc2d048d87393d0074d40f8e864986b3427131909082b9268b5e8e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f75cced1a9ad7639a4551ff313f04412f54b349df98359c3bf7df72252cf09e5246aaaa7242788993afcb9e6842d16e388bb14023003ba5213b6f8992f68d93529a5fdbdd89a1e825973999819237b87bb2f085524fc85736d9e34b8ced8193247ded76d3941b34904a2642dcb1209ff284c26876c6ec649ccd2a3199b9f521e02282fa07473be2524d70bbf11fe24c23d5b92c99f7b94ca7a48021e0a4975e1e002087ba8082aafdf48e6502e9664f5fe96b23f7ebbb221df0c6ef2f4a43a7be2b90b16032239b42956e382f9e2d4098b02d425fa7a358ca17b442e92c16d83e949d40b8fc04732d62c1664631c8568adc865a61a2295e85c00c929ca96965303724d0313a366f72b0718a1cdd0da27ced3ee7f578a5b8d7b9e08a2721db726dc0dc02f0319fac83eefe9c673da1c200f58012fd1114c02fb82e34a1bd4edceccd6a3e53603252a963940dc23d8d58c95af380aa80be20fe772951d51522cf48601baba1ace020e9f118befd29a1afc0891d4fa8ed68e3b2e81c2239e2c059d37debfe88793b0021e03ce4579d6b2942f349b735a202568ab370001b4fb2425029b930b71bd07cf486dc092fd17e6b51707435be531f89ff648ee176cab080f4ecc5476005d2937af6fe2150653e31f7453b4d3a319ec987040bc24f7009a60208b25b74be3f9c58938c86e650ad7e884f79d72342217e757e49f9962bb464140cf77ca0844eaedaac9cf2a02d4290dd16df18769d8d15994f86702224d30cb79ed3d6f4e2d9010c8abe13b875e78b1e71c586299cf14d136542d32711b2e063f63ec1dd75c787969994ae883399ceffb178c467d2bcdbc8f7b3e6424edf4d681cd0746def8413eb18557070350e7a8abf2a60320b7c81fae25a14d0f7f17b959821874cc94cd462f826f069a34e63ebcac9abfb4fc4d13c88d00eed65854a2ac47ebabd6c1c0ff85d5e52fbf37a6824e69d71ae6e7e114aacf7a0ba24024f85abee18cac2de013dc457c38704e23986e0a67a04f25e36a5ea5ec8eb02529361f7afa86f688245e9529a15ce80e84dea83cf0515ffa88455b895d1b30f550a63bc087d31a4cc96a97bcdfb4bd21728919c8673c888e73b9457b7166a026360a8118a76ce1e652876df8c897f66890c87853f6c3bda0ec966a4e8e93a3fb1b8042d06d8445be507944c64bc41fed3a1ab99d044f4df6e614db41d54ad606dcf0838d7c27256511d4959e8ed2cbd32833d58250ec08ca7bb4423d0d1cc22a8b8482b5f9993ee23c8e50a489a4f558b16257a61fa378dc022ac74c2f74cc2ce26c6d5c377cad8dcd6900113df41c455f50211466b0a32fc5aefad3ed6392941858002987d13ee79c619cac44b7ba8acc23c80a8581af57e223b40396a54d6aa0951246e86bfd53a28793ab30d4f16b0ae4bf451526fa7a13fa0ef01f149845941933f10a448712c1556dda458c31f227a3f72312e7872200a47d8b9864247fb2fa7e511ffea17d9dc71f7492ca4a7efb6045508a3f4d03e4befb57192889136a54d267f52f64462c15b5e9f2102650d2a6e87d82ace89ac74d9ee9c12bab752370993ffef820c74eb524ebd3bf7d99ce9a8efdc711106165e6ddfbd600008c278a8d4a045d1e644c23ba09f413b16c30f3e5b9fb8107656ed4d5910470acac74c91bdef91449369b4d84a2ec99d077128f2439ba03813dc9d134bf087a66b53fa12a4c860ae19cecc04740f63e8e624c2e28d7aa0f17bef6bd69c575b61346711cb4287fb0822e6512bfd95fb26484de2b9432d99e919377480464c9018609afce1ee5b1addc7e37361675f8810f5ca320da87dbb7a04e08790cfa50d603ccd07ff87796b4d66e2ca6a4e12666a055b66776cb05111b720fb3cee1a64bdfb5203e16af95fb0b9835a7cbc0bb07a9a6fefaa8e89984c1dbad493b9e0b57cb166e69545ba4727764cbbd3b104297676c1bc4ba8d45f56213d5de048ea8b934043b9107411b3ccc3dd7ad639fe82e92a6dea8e41542220bc82158fb6c542fa61c49846ac3e2b601621fadafea7712fb30b8c9e7e5508763c26a6bc564dd6e1bd72838848bdd7b782eb6e7b9833dff5d1dbc0dbe913a1d795877956fbdd5f820ccb090b009e1932205083de1b9538c919c09b846ffc527a3f8860958b7b24ff257c96f458e22239b4b29cda74ef55e26b61b3d74a798459862b3e573171f8b375d619b4fc6340b9446e652632169a0bd41b3f4989e480affed216dd72de5fa01fa7f449d91f17ecf29ee5648bccc55fdedbe78f5f96cd1b3c329b27be5e6291d478d0622dccca998a67b3b2fb37aacfcc9c789df044c0884cf36d4210c13f0097cbf5596b6a3a12ff0b8537e206d6a17afaf7c93845c9f9dd7fdc782385825e4ad6ce23bc319adf1f2ccf100d05077707c095693ed76c2d3d7ff946104", "52656a63", 0, 980983185, "4feb010621bd08ce9d64707081fc66b3e0d321b4a83636f04931648439d850fe"], - ["9551c938022164dc49b221004651eacb2fe596c509c3f506d3582d6ef1c1e27c07011eaa5502000000055263ac51652ad1ce10f7eb67817fbee116eb0cbc12753abf6954bf85fbdc5238e53c20beb2850dd087020000000752ab655152ababffffffff0280a051050000000006635252ac65514132bf010000000008535200ac520053ac0000000000", "ac5352ac6565", 0, -1733984556, "52e51eabd9edb4c335ba6c68fe33695da0891f341acb48a38a8d7e53c0fecbcf"], - ["ed4b022001f2264a0ff2f451fb63eda871017bcdbae48d51921fbdd01e9b90a1c6b4fbc67f000000000163ffffffff037c6fe30300000000095200ac5353526365ab3a7c0f0200000000066a53abab6365696d6a03000000000351536a0000000001cffcaa01000000000000000000000000a07f832c8d6b558a38214227e31a3ebe8ef3787ff824fb72f31318c973e7f01b1093fd18c0ca7afbfa82ae44fe9774d61b4f5c83ed5bfbcf22cf648a63111deb663794e62bf30dc39be7a7c9a74eed9ef61b7c60b41d9cdf23839a2225b9938200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4e84e0a09c4388a6a80a10360436ec58e4f2ed1783ae94f0ce62d895c5289abfc3569e224fe1a4da2a86a1168514f8755711dd5c1437ae629662a17e0b3cff7c883b0bbc4cd53a0be8059d6dcf843d34ee145bad50eacc7ef3dae6771b1f100d2f854adca6e2e8788e937831e82298f80b852fb36ceee2e81e0e483b8ae56b9021e8d323d5c42f5b73c43e0627a6bd5919c201d4d3fae7fc205f9784c63b61f2f021f5583425e662463543e716b01de80eecadd19b6a772226c1d1737cd6db1b3c10a093958358a828240b0ff5ce6c928337ba4006c706d95dba59d72a12541e2350a182c4944e5876f82ed9e8c9c8660a883858255c8c75da8cba20224aaf21db82e0201202656d814584ef18018a2d8e6d5a062c5bb8c8056d96c708b441e7eb1e5db0310553659f00077d06eaf5e213dbb0a67f15a0970e72dee13ca27a118171ce7ed03061e085e8cb429c1b3d54348f87aca0a08321e6d66aa6b83364eabb32e99d8df022b1a5ad0abc5349302f75305992c9ce2ecd487a290772f5c642e50e655cbabd003283637d19fc0578f91b08e60ec18e02a581775be4207f7c1ae2197dbf45183c84005c2d924e447e9949d4b1131887d23e57d720d79bff400d07fee27877ddf26d0843fa10a2deeee71510e1bc0e72dbf5eaa108d0a2a3c2a4a3c75f5795b3ff8d4746bba92088b4313a7bdc555ec975793fa0706efa998c4d2c912db3508a3e5900a0d29bbe3302ad6a1c5f41b08d61f692cdf01de2897d06d5440ea4617a143936f5f6e34e857fbedc008f85ecb6c5152a9d21407c6855547d9ecd7d2560a5a5211eb1fcb3757a65aa35addd4677d02f9966a16a6afa4715009e6cfb0f444c3d84cb2979dc46c94e3c4e3495ff6a0ad64e7bd7d28ee860c95f529312d0bbc3b34f839ea61c7c989b5f75443b47eafd58b55cb945ed7d0f8e0f8757004a048f7ae5a77092fd3cbf925358863eab4883a47e8a38ffcdf8f06e1454a2bc25ed302870b71521b1d7db6620f573485ac37ad4904fc091023c4af9ed705498dde889f30fcf78501bba180f09171c7cb86eab15a0cfd321449e81e481f22a9989f07bae0f73081f07f260bb8a7cc557bb6f6b9718bb4539ae1848c26a94592297f25fe0beb84b2485fe771afbd83af02340b6ebee08bd3324e560d606e564b197b740a1971c8e43c105ec15ead7b5bf07d7ffedfaeee16b692c794f9a6fb31fb253650bfcf12d95ee210b624e791c9ca38b7f0557284c4741e9ee01bd69ed9aa38fa18d970c1a96fd370a543fe1f79a9a05747f5ba49fe1160f36f0dbdd1b448fca921a5126cb082c13163ec314ff39853550364ff34a10ceffe4f5c8ca77f83d44ba7846bf90a67d9fc7aeec1f8498ebaa1c8f878d3e704fb8ead5995bfb434ed94d8a6ab12d17abbb697406fb8e9321874fc6c285f1939c15c17ac493e739a2af68a2f21623a93ad59f779bf70c148c2b6ddcb1343076efe85e1dd10fa0d997adbb39f6f06eb48cc3c8f181aaa1f7ff1561b04c3c9095335097780bce454f8761325bdbdf52cc35bea93c248c3055d1f71a237d7a17b07cba7db42ca8a4a2e09901fc3748b0565d07d647204a42ce04a3debf7869b1eece82f6d3bb3de3c59c84f36878b36f32c9a46d676ea590bfa24b22159841311388064dee76032bf4fbea970ca005c44610caa7d063e576ebb1c301390e9b963bfdb6c1d6df08931d3c91098f795d08472120f43ceeb90f97b09ba93dea0768afc07c7fc92813b02c73b0cde3f161312f08ef2643639870b239f9ef57ea0fd5eddbe0be93d9a2f342023a13145fdad08eb197d07148efbdbb46f8987bc7eb1b4e25f2bb0056e36400cb0f730af9a427149899e82e9bd4ad5a52cfe44507a35d29ac93544046416e0e24c62d2659ea598c0fb4245337a3672adc72cca6c5b965c939a523ba439559c120dbe2b86d269eb310787649827c1ae8fe78f741be7ea308845406ddff993ec8e6b24acfdf0920cc011c962f993b0fa615ce75ae813aa3375c12d2b4061ed82d1b28c96a3b8f0847bd9e8908c73e4e2bece05a97197878e8d4898a5d90788ae2bc93bb3f0b118f80b9ba95709b6769059b2585b653f31a9e461ba6e010ddc7e734a1b088ef5c9fc976143ab9d2a482f8027039f0d5d5bf3928435cf7c2ccef380523337c8b4c79748a7f44688641043433caad4996c1617626c571bfe379f73c1359b040631b00c53afc09dc3c590578f642d268eb13dbdd5e3ec5e71d721358d439863a63f6f3a1315a19e7e383e9a14af8da9c9af86275e29011230358a52a054562fa4c8ee33379737b0167c06ef4419998f79b1c1618fc726fff2de7b225702b7a579e90ef11b0f1c6456829640180268c487e066cf89e969cb369ea1e8a3fc1b1d88822eff5e686510cea9c155e42ac57b4404", "ac51", 0, -399663988, "65112ea9d2c6d5c5e64dac15c79bd6b8de093a0c76715afcab1110e41c0bdb6b"], - ["62d90c8f022dc4b84ccace2b3835fea403b965fb6f38dc73131ce204734d13cf07d7f94b3503000000095365006a6a6352ab53ffffffff2c24eef8cd1259685154560fce4f7766da8d30a22114d9ffe0867e191fa3e38c000000000752526500ab5252ffffffff03b69d790200000000056a0063526a2c9f8104000000000651655100ac634baf4c020000000002656ac10191c8", "516aac53656a", 1, 1457994268, "cd77a3b431a124cb98f825db6c7d2d8652fe5a39df6be90e9418365f438f9bc5"], - ["74d2fd49046187da7cc7a83262f2c6d15d4b3de9df25a97774b375249bbdbbeb7eaa81948900000000035252527188dd8ffb2eaa610c37db244b8f271db433bb0604940c7352f4b487c3c7fa23d1a3ba820000000009ab51ac6a0000ab52acffffffff8c8d5051cef9baefd8afb67add44533093e33bfdbf7facd12a6f9522d8d5f54b0300000006515352ababacc3bcb3145d7c3584ed6e8fc8d5cf061b5bdcf5857b772ca0cc8d004c0bf8806b1fb4e1f60200000001abffffffff040a4c770200000000066363636552ac5ef4e7040000000003ababab030bc3030000000000f89db201000000000000000000030000000000000000d140c301000000001d41e0a75f718352daca18103fce57f8b45faa8752b60f781e4863b12f8a248780ad6774f7dcadb0b1b9b7146ed11324422d73cfbf3eafc4faafdd94d0bcfad39e09982d977cff4e92ff6c0c4ee9ea3d76a406ec9ee1e6aa8f2685bdbe4727b900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000992fd456920ba7d294812e2d5d9ff670519bc4794b75dbdd0307c7297baa3aa52b3eb09956418f9ea93500dedfd3c7a21cb7ba9b4ba4efb62a2f995cb60ef25282a5bf92805d7c60b92b00eb9d0b71acf601ea74e66aed0087203d53d2e2749e5c34657c988a4f2af213dfac269ccd5bdd0730d5c0f17d260949042c4310d1c30212ccadb1bb3a24a961b7d4216183ea3b59b54c85059b08baffcf23383dd92c4903209d4fd13cc026f3a12fc856915fc2792f0b7457a39543a2962ba9c2bb5dc39a0b20d093d6d9a3dfdc8f56989375c4e4b53802e932b77e3f674e6b7c22e225b1fb012b48e8985ecf55d725e7436a3f5b90e69306021aa769f933347e346652cafe03237a4478a72e50a7cab013c3635bb312ab989bbb398e3f9d6e2f674a8e58ab6e02209d653fd5c8d8c8515cac110fab2c759f16bc23aee748e58803fba5ffdd4bb10221977518ac5725ebee0f910742c83bb59128aed4a47b2ace1880efa3c02314ad020e12cb3b9dd54c664228cba80ec9265744e389d98ed421852f12e61157dc8da103046dfe0556b6709b6ed8109abf98765ec8a0ae292047fd12a324364264c0df5b7d3cb20bda2cfa0165b2a7b3258caa28c1448c0a1c251b652fe7d89acf65511aba4f8fdec0ad794002c4a61fc6a6f58ae99046bb4577e21d306a6ed339d7144a8009b87027a2b835d3f3c41bbd4c245084c9a51c3af31e89588d18161f2d43f2f9836f1a0338fd53d2f5cffb32ac4dd877b1ceec9f488dc84bed43b29c1cf7c1ce3845f6a8d006e9cbbf40e3d4066a10cc6a17d1e965e877ae278a649fdefc4e0f1c40b1923eb1107a9623911a92243c1b696eb43ac73eab935277a6f01a892e33fa22aa87eefa3214fcf4679beb34b5e8b4c9bb2673c556524f628c78f2c8c913fbe0860a29eceaa18ac42346192cb85c2025e374971758b1b75dd3ae4cb0b15b2e47596cc2dfb94124d88e73d39a7f55cd1485a8be512cd072e765dc4b4d898c5ea43a7e20c31649bd15ec1fae111f4301dbb2fdd0e925658e0f7e73a02312c7ccb009b0bc03d3da4842aeffdd9a188716f7be7e1a9cf029504ea85c458152673cacb0264ee85b708f0a864b0a63097c47e1b1f5b2ad73ecb5c10d8e6fa532e902d11b6e0ccd42d38d2907aae35a974df799cd4ef4679e7dc8cb4a41a0290b69d7b1458901de6ef2f119addb0ca795c3fac0e13fdf9350ae7ca5a81737f00bd4a7ee632dfcf609abf9be25ad3cb7c8ca626fb279c6fc34550c7c30a7227cc28b69783ef01feabf88061587099e8f2ad71012b2d6d818282cae95dd5323eec72e39606e79b7c3f42d1c312b9b67ce7484bc97b29277d705ba4ac1f5942383325ae69d2a7cdc35e87fbdebd9eacea2e8563df4c5b4ba48678e0bee6a6700c4c8305be022270089aa944d3903e7f9d7b07e60ed53ccac5e8ad76dfb8923b49b1b9faecbc934408dfd7468d7545f51dbdcea67604157c1bd4f0f181559833eb61e65e186eb206642ec7a632b71805636bdeab23f01369fc4fbc0864c2b826fa4a4c48ea9c9aac18bc7af602a9783b84621d4ae9b4a5cf3285ed91658bf2e7d3f0ee72154c0cb0f058d4f7ebebfe33044332dcd4c6741ada9edb34dbbe1ff754b8bf21acf2263bbf4802c9f172250c3323524aea50beaa8d8f2dbc195716c42963304367e92bd9a288dd7e83cd5d390928ed057e572c0926a781f1654d503c73be951cbf70a2c552b3be8bc0fb576754abc76bcf829ea7383c87e25286aeb4cc41eb78d20236a3a88c50e983eb48d31ddef3f4d031fd3f9526a69871ebf2da4b3a65d1c9781402626f24c8159d59174a82d0e70760d60dcffff08b525016a506ba835c9e4f18b3359b6c4a9d68aea4bcae1835ae1aca703c6b36269659b24d7625246f93b975f9edbf3bf8b6949e217fb082852ee9d8ede1c376626d2c10f7e22384aa5308e78b13fb167827a4d32bffcb349ad4e3b6d027ecd2c9a0d901f6b850b947cc40b5ae058cb28b885a2f5a9df69cb6b96c6ad4b16a9e3cccc0c77a2cadfc1af0fd528baa4c693e4cd3d36f9474ff6a33cbaeef23927568f47aed1f6388d42768c875cbb1c8cf44a02ede35720865ec347f268f0373fec19a4941d6db6f47f23e4a1154c16dc791bb6a7bed4cb6848c71cd5cb34aeeae999a1a608404724d1ebd1c04b543a66e32f2f0a1edb15dae03c627b1c457b36f157e445e157db5abb3eb6deca5f4c8a80f8cc527fb0b3da3676a8cbbf2e5be574fe05dda7ebf697f0551e056dc58c529365918b41e176c479bb0000000000000000a7b90d01000000005a24985f27d452daa9b15c339f279cc9b5902ee949aec313865e26fbb4c1dd5ed650b16b0b94f07e3315eeb54c95735b233971abf6ee0ce6639d7fa7ec2a5fafa359e3f8c74dd3f3242128f69f35a7d12579962b4e4d1be8ae32a9bf9e035e6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000714daa5dc3a07359050201a1e5825bf539d0e92863b65d043b96629837a1d8e8792334bb7a15b026f27e4d7fd0bea95af76a6eaf922301ba2d055407014d24b57689f4a58dc667cdfcacb87b337fd0589c02ed2780a7e37e85325f88b37b4d6b49a70aeaa9466de8131f67c9b349fb42ecc46159f3a0a78b2e419a0c5c3b4a2a030287157f7e9c6edb947320bd3c2ae88975e979093cd14857d309e54d5aefbb6503167c90efc8c1fb63423a714d822b2b8af61931097d4b6e804501af4b9243bd5d0a1dcab20a530e7333db5c8ac46d482ca4231a5ac2001bad3287784885ebb48d5f27a13905a24ce46a3f4d061f09168d07923993bcac08f06743a99fb70ef9daba0323c26063c309d87dd469202e99e7fd11eef565432b2d1c0fa34cc267e40693ed0209c2ab673eb1e458f212bba29149f11dc80fb72f8f9be4d5c1b5d30575122e820305ef73ef7ddba35180cab24692f95f5c3290a648a06c37b2a085613693824468032ed757799c5af04c133f87e4797b5fb89a7aa675f2761b179252ea2519451e9f031497ad3cbe40d37517216fa3b5f71954058a246d97a5dec823a29957db2eb5ec56e1ccf5a9c1263ee356e95775ab36e7dc68a4dc00f90cfcf906ffff99ce91c2b2d79661db716077885359b53384620fe4a9582507defbe9d2d273c1992445ffdf3c567f8dec65e16a44aeeb316b705eb95d8a9493fedb4906c5cc414f9a4f288f140108ecbb45d4590df4f3dd3087f35d2c7fe274aaf710e60637c5e3182be37a1f94160e79158759aec5016aaa3d74fd321debd78fcf475bc0500d3af746f916d58fcb9951662adbe073264b471b28d6be5242de33c1c73dc93509bbbf977be4595a87cadd8d789d74a40baaa1ba428884114682932e8b1bea9ca0e5c372286c3b4c5c8c9bcad257b37ddbfc57046c8888da30afc0f6277896b971847ba7e52f44cbd340807559dcb17b0939bacf097959fdf4bc6be436f6b1d7e2ae8ed19f098a86eb42787d1c92bc146acb8479488d57fdaaee643af24b765238afa5a94aea11b6568caf2406e29b804f27981b6216e5cbb37b23671dc9274d48c62e2ae31ba4b2646d17f63f9331690d493d45de6792e8cfe68c634768b4f2ca0329dab550b3a4a3eefaa692f60057f5b85d368a167ff0d678779708444f2677f96cf4a6001ce6fbbfd322d6e3507834db56decb4bd8ebc87a6cc72891f11a5713687d483ce56750568a19aef71551bd7c628f5bf0b1ebebdc74f788b88d7c8f94716dee05e4f937f92bd2db90153a93540da6993610336e6112a03f93be64518aba71ce5434cd1db82d0341b9c73346ae43940354e66fbe6bb9db6c3efa024c08ceb6a1639552cc755fdf6094499e61fd0e832774f00bb14346bc08a540ac0b3ed8912bf3fd96816045abfd0fb08b9e3e8238795f4b1c9161c08f40c5be51ebdc107af271ea090c0f4746fd82782e08756f89d774919b6a3c81d2d97a644147f2e16a4d57c948f977a277abfc733b9bf6838fd6f343a5fee471b2f4fb07427e76e05a4f1bc6796d54dc15295efc0894cfeb71a239e8264b02da8becbfdc97b84a77eb79adfe92cefeff50cd5ba0ec235803fdf641336a94dacaa16d064eaba1985d959471680f507e0b0c37832a2bbcea202714691db7cf9d30f7560a2c62f9e124c136048797c146b0e6b71f249d774e440cd562e18882e738129d4aa1857e8900ed2f3ed029bab8837df043666f69551273d34b2ff2278df971664359abc60c5bc29ac0753fb1b012ae2d9d3d45276d3adb040f4113a6eed1d663784cd35c92ff77fc00c9dfd1a09abff13bb93bff175090192ee02cabbc7bdaf28093f7ba832a00b5e46bf50a9c5f651bb39dd1847b6ecdc0ede368f1127dc5326112ef54f6b481250636e3ca23ae96aa7b9af27a2855ba7a7a1234707299d2c475c1ccaafeeafc75fe1eb431ec87dd69129d0fa3a512843ad55ff8c628c936179fcdce567c84eabca5687f367e99beb1520d11c5affda93776e8e3037407ab12292392ac015e5eb13144eb364b3bcda57670960ce023fcb1b89508eea2f466774893df45a74474d46f20bff52fd9d53dfc3478e88e9416fa645f82c91464434528b35eef16aa48fb8c9d43ea0825e65639defbadc2a9cf8209b9749676973b35109c859f9832bb47a98b303682ecdb3c6eaebb666d8b772b0119267feb97de5921b4326c2b6e1f8b7569218b8ec4e816f9ae8722c2f8a369c41a84c16d2c0caaad2bfe53bf6620ea3083703d478ee9971d4d11fdb00fd9e95b86f7e4aa01000000000000000000000000654d07910ad834e954083a529bc6c7166ba6fa5bb090348ef800e104bd9dc7920ee65cd3cb0dc17b5c2ba3540d26fd5fd58151edc92702832f6d0140d58a74a40f04c8816630b61ea81e858bfe841a5c4ff74d0906d4a23ad9153f5630904f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad71c2fe579a9186acbf525024f80e7f5d65bdce07b71cfb6a0875291036da76b5d3603f382c66ca642e466bdd9804a15700ed8b7bbf1b94afdad959a048531907457f1b862ec562cf0c6c45037e80b2a376b392648bff2ffbe411e1b052f7de1a51f3a496aa3970d4b9784f72295d0985b4b68f7ec7e787c3c67db22be2905e022d64d858d268d2beac923796a4287e6d29c7ae43253c3c5182a73daf6cc67b5e0221939eea4d7a70f6e7a63f85a5a23cd8fccf48ecc6f25ea1fc7bba2cee9cf25a0b251aeac7fea1b21014d64c2975aa73934e8fd10a03a4f79633788a149b547b800f4adbc8ede2725e05e6ee4a7593fc34d8c8de4b019561dda4889ed4472a5066031a96a0a242655c0fbb84a20990f333666672806108f41b549fa866c0acc393ce020bde6a60422023923296426f9bc42cc16e650b76e51a767ed63674307785c39a0220206c26186effde9af5a0f48ef47e6bff7c3e6fc9921561ced573c9636e0f39031bc20ee7ea11eb0d40a66082fda8878a69178572dcc0b3a0bfe24078755586f40327c5cbddaa93afc495c4af4762f7d57fc37ba2d608e3bdbb848b72d25d03ec080e78d23ccb485e0dfee6964d6e157eb0b267fc601d1656571a5c9a09b3ea1bf1a1021c04bf3b71a5f7a9448613a7c5d878501a1da85395ad054b24ca3c24f883c9c1fc703a1229f60c2b1e22cace53e4a78a79d2677f6ba2decb9e294e24790928a458adea555c8d03f6dd33ef9907d7ec50f664ad8902c86922cd13d87b0ba8f34fe8487b59a2b319de48ddc94a6fe116ef4ccc1f677f0538ea2b1e954f71768fb5a3bd53ae482acbef153ba12c725d00251c2609de0a44964aa92c43ef32e6babd8b679e5f43d78c67110f15ea60bccfef41de11e1aec4abeb1d36dec6067ff4e66c157a459606a3ba3b15b9dacb45d35c8f5d3a443767ffcc5aa2fbda17e6f79681c3d1faea7adea12b63150e3217189c21ceafdedf5a3a0f1cea0224da6bf63a77dbc77324c55f8e8be346e5acc2044700d45729d71899f98507f3cabc18fbf103369b88e48376b450269726e2fbe6fa99ab2d5cca2fd6107cdf8a032e97a88378a864ba6dc5f294a867e05a5d98d810bbe0d85537ec1aa9262a892c64d256397058b4e28fef54c40edd6eb3466983599694dfe4eb62bf01e841640fdf7731872118df4edc580bbc55a42644e0ab0f536acbdb05d21b319994320d3ffed50a5080a02d2cd8cd8824f12ae196eee95fffafbd22e095e40da731a11ce0ae3b15d293cbd414a9cb2bbb2febe91204b313f263d54edfa56facc5da1314ad61d4708fdcc601d2a337770810a2860dde14de0715505c3ac1cc7f4fb68e1ba81406f4d0661720e7c1c8b2158e7b7365b231b06a75347d4080159359b8faf481f689caab193911d4f698391087f13d35a47502f6bdd9943f438515f3112a769a1a79b0c68d6d855ffc79494300ad0dc1c09ef557c3d0f1334967e5e77180341f38d4e4ba615260a772a313ff2adb4e0f5a17b434f70f94244e3cd135328dd1d508e40c8f21b5c51aca77d577097e9ed52889c384e1dcde762f962ee8c8ceffa2ebe18c0210ea1cce95fa51811c826a7fe13da347dc031195f2f55397b07eecd8343a91727f8c06589018841207620801902548caee8add568e7c4873638adda391c18a2141da93dbc36def038cafa5c2b537ad90cc0706d28ba4d49fc3b12bacb5f3f04257e4796c56beda0961c507b19f555148bd64b2145504741fa8eed47f6a27f87b496e37326b726c7d7b29024941119581ca1df49d207b0b2648cd922c53c1aec79fec5dea56ac234662faf5ac8801e9ca6fe5eb6d6133b2b3683116bc7cee48212e10d2ff92d5ffe0cdf2b801448644a2426f9d547de9e3707fb7fd619b98a0b1751145c80b03b0bb7226954214a9edf704c55f7acb408775164f06ccbb253de9b3a3ce83d4d1039f9457990188a3e3fb2ce3734e2ba69f9d73bc1c3ebed15c48d3de128751b9d7762a7e89a1179642476f3c88311ddfbf951f568bb663db5cd48671afb0312ddda3e9c15cdf888d9ea199e875f4d9cc6ad86c9c4def9a1f8383ed9f06ab166202869f3ff878ab05b1acc7943a54595541d17f3f8c597b5cef97b5d1c840da57009a65bc0502542c3da3b428ee5aff55f404549346da59737d8b1d520917bf4efdbd6d91c5686456eab2b29d4289dcb9a54f8f036ddd9daa1c634bd959b79a6c6195cbaebed4f12b430868977d3d011cc07055f9f47882f96ff222dfddfbd7daa12758b1653540c0e29c821fa3cf83368f11eeb7e35bc9ddc4cf7574a6b483a9a192e5b9ee7a6422706f1d9a8352564f87f14a48f8b7431de41c296c1699f7586e649feb62b350288f1dd4ad3c4584e84723380863a7e4a3c463b56a49965b0db0a5a550efb9c648a30d", "ac", 1, -941057562, "26871f674a555fec36c2b4641b631133a3f016de0fef311e7086bf5e838fb2f8"], - ["4384790001f5562fdb01eb3fff3ab35a1e98837b88146545bc3da58a442aefaa027c19061d0300000004006a5300dd28d60204ef375905000000000465516a51d216650200000000066565ac00006aea486b020000000003525265984eed02000000000763ab536565ac520000000003000000000000000031e60f0100000000f406dfc80ad580c7cd4dfa983829922b88807b3435e09f421b3057635cb584d565e49fb52295486c559fb19bb90d445d5ac12a031722a239712f90b03015ad38780f3afc0883415f24ea4ccb8224d99153441d99935e68db810b26fb8077dcbc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023338c787dd0d0e06120cce25b6a7fc3180a447d42075ac02850700c889d34f18fc363b88c464a0a958d5172dff796085e4799aae411277c5377a720571db3f8d435ce5c1d89d6ceb6ccfd07382a1a0d01adc3b44b876a6a6e66064507e096ba220f1842dffcfb35defc83727d30c24373f6f0540513c55e2e26e03cc229245b0319bfc59dfff2a2e89792b6db83675bd9197f4cbc353470c454d3c4c5371d8351021dd87004aaf5fb94d2bfd5aa18e61c6e9243ded34f21a6302d278dcf363133780b0cde4b6a2ad5e3e25c5b7772cda63634937bb493715820a59be21bd7068079200206818ba1e36537ced6f29c9cac7484d11f77c3ca37edc7b62347f04b9d7f000226fdbb9b0394af9cdf77f737f71cfb40121ea388fcf6b9dd7d751757e6a34968021dc3e74356dd0d749b3f6c319c3cfea46fd093935546053653237408097b2daf030d9ab64172fc5bf54a69b4cf67b0b8f5d1b0601f3bf7ed205f6fc475ca03f2f30326bacc0fb7516268028b4a8cc931da97c8c23b4b918c1dffd22b0893bd673c22021371109fe735d3efdfcd6fa6a2886b78dd067a288c16278bac39ffc5fbbdfd02e3bd8d8e475d37eab11f876b1748bec1fd3667eafaf7acb64a8bd2e155781a3af9f6c0a75deaf5c1871a44c857db0b7a07b0282dc33857ab0fc2559fc09574e2429a2f0ebee66b46ddb1956cce56bc9a1307dc6936383774e0ff8f80acb4ff4473284af79b1605bc0394e8b1bcc65baf584208c40ddfe5e700c508bc2c77a727ced4204f047f68dc339b7185c60d1fefc6030a83882958b628f8e61b6a78d8406ab3ede152a8d1a16a1a0a6819c9cefcbc5932f74ba2ec5bebcdf54276567b4c7870e6c261bf32834e753356bcfdfc5fcb9e080915c04a10983ed0f047bc89f635d6418fa645c5b8f1dc5a6e4dcef00372e0e2c3ad627f2fae0643f049bee8bb0f2e0eb1d9e87f70c4db1e6fefc55a9faa4e9e9746c4c4a7c986b29f43397466103da0cdd307faa82607d64d0289b08443e115a919190e66b518a7c110cef1f9684841befa3d2cb24d04a5b1987991ea1907de0f616c3312ba3674f2568144a3735dbdf451abd885cf5331803e1020f8ec7bbec524ed1b70625cd87ceb5cbec9a04b58d157e57c32eafaa413aefd3ee45e28cd519caf091e38910d3bc08e47b43bb22e0823fe32c3045281c88da961d8e8ab1a1c7513c80795ac484dbb872ab0fa43e572b9013d1adc81416d957897b4a428cc0b553df149742214e03261de276103d9496950e4a5a3103a7624d2aff9c8c8fa27efde90c869e4df2ebcaaf490d2ac3054f1ec0056e8012da7a0d915c70f5af1a430d3421b94c4fe6bccb26d1b89ba32e989c696cb69980eaa90bbe3ed4ee6b2b5d39037b6d452268ee504bb28648fa9fd55abc6c9814b9a3c54aab67563f66b253000ce1b82ef1ad9f085dde2dae8af653cb2db87ee351cf88d78824fa668e590286f55c93b50bb03d0e87e6a384a33154801472b1afa9d86643c1a36cbc028d5a5ee391266bc29408120eb30ce51bf193d727bf9f12f1e7955fadffb2baf5c197c35be52b2a179288f20fae433356625123750ed15c08315df70b31a22eb1743909d8759d97a944e02651aea642b0682efbf14703c7df0aead58678f5e1bcf1d24582cbbde8e462ac2aa8c4806f6286be744c69d16fd718b0268c9acdb5ec5faeb273c03186dd8e272e35a6bfe377b184339a09c84a0dc44f81b77dd32c40a2789c034e01e2b0b2cebf66a02741515f2a2f323b6d1258119337cb44e26d93ed6d38c4c4094e57e37cd57ac138ff3dfb85dd180a317a107333e6454b07d2b2de26d32e5c18ed2dae6393fcdee7d17a18f7dbcfef317be650bbd3fee34c53ba827f6f7c5ebe1a14edbe41b968ae16dc60f4d12961facee91f100876b4a690fd64f250d633b8af8d62e38a8875965c04e31de21d9c40fda23da4b859cc90e0f56d54441743ab4e0ccef7915df569af50306e3bf6637d505618b513b289dcfb2ce13cc28f7a2b024f0a093608f2c64c09066424fd7780745aef4e84a7cdcee263cf27d77ad7a153a004915bddc6596a1a024a1132557718fef9cd72bd92e6e4cde2187c357e906c649f032b218a7a0cfe4ba27d908835829461b8fc23c75b7c2508802494dd5192f88005a76958ee675d758a444779f70e2f6310ad51dc79f2897a430002df37a6a2281e2c5af79035d7f1a6c596e1c49b604deda44ce70a81be2e73fe4e56640762143ca011cd042257aa6e5a08392505c742d972f0686bc943b7fe404000000000000000000000000786ac66066bf1e01e71fc83bb1b2117d5dda142e509ca517b631f9e15d5c97d9b83e45b12e6cd1c3e97de311be40d8810311e5c2cea6481fd9923e15996940138b6100cad0757a6b2b7a44e6f31a8c0f31418f2ba3e12e2bb7f860d78bf122a700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2459fe73efba355eac24fe9a393d5224641799ecfedde15c8b8db6db5ff44b1ea52fa150d73dfb1b5587cfae4ca644087998fc42b2733cae776c9c44ba3a267b1b0e5d7ea3a91d7a0c1984018f3479ec5fee96a9fdb3cf5a5ef7eeda754d3e491adf2f24b5f0c38c8a8ae4100da27156984f12141365366a2242556177ccae202112576da80054eb52560d837dd2869f5da6f224420991d1dc402ae522fec95b9022d75568cc9b1e7f762cec4c173cc2456f8b45b1b08c2ace058b2c9c7188194e40b0104f0353c8133253d21b51a8dfae97b1f27a7bbe1132b2731103683d204a7172ad9f04cad8cb6b25311a428597f39144687b7e202fa6ede5ae968772588e75d022ab725479d6c46961f28ebf7cb48c5e3adb7761670ee711672cef214eefe4d1f03163438c334e5d014c606f49f740c12e0d2b631bf745e12b48cc324f3a9cc4e4102129275a0a9fafbdb223667aa7bdb49825051ab0018a3e09b3421a620b9982212022de7d9b239189990cad2ec85ffb244dd42d0c7d96eb0ff57265ad7fd27ccca2702163e1352d486eee55ccc18187d8dc819cb4f1512d6c4802ddea01cc600d43e94c6c6d7d68b577c77cbf17537f040541e517559ca79f82699c755e24cc965a2029275ba27d76a9ba588bfd9f00026cea0eb955314c38d24a6d583acc30518bb2c7ee74b8d762f6c6508bf163a628a4bda8fa947b3413a8b4775c9e5ec9f5658074d9f9f8e1b96f15084e172a71f558684bf3f97e3e5b6ad029a03ca25f76497624a77f372c23de89915773be639389b2a688a36e59438f9a6bbd4eb15f6ea7480e7cb26a0c3733c8324b7ac89b39ca58be9a5a2d09b89e063df97419ddb42f01dd13422d4fbbe6f93dab73907120c3f84c1adbca36ef54e2e511a0d3087bdb3b1b856727281da6480fa40fe2096e9a2c8c61dc2c674d90ac3eae798ae670dce45f5cb9d6aa8a63224c02d8a36cec56e9bdb122fbf5ddeb988b4023f1e0c84791f13736f1a566d146fcf7bcc367ab662c58d9b713b0de35c05fa939d84f17446133dbff922ab7602b927a7d4b721ab5d893f2e720a582a26e597173c0ec3e9f023f8f7396caeb35053ac15ade6c753d7554652f20f515015d3a8b9e70244aa2ce7d901155893a0fcdfbbc78bd38488fe30987ed6ab880f993e85679d81716426172d38e2659b422338510485cec37373a03f0fda92788fab9fc32ee20f5ffc17c53ea19b8f9c6634c5890689e2c93dc9cb8c2df73c27e34f45e0bd6ccad43deaebfb8727f0eebadb837b625ba092dcb1f69316686964235e52463a43bfab116f5b8476e8c826dbb4edc02673dfd97f7b89a1d1abee42c9fc9ef1117a7e9ec22049616a3bae6ae06d28086f174ad10fae70d99787bb503703dbab0e1cf93beecf99897a70e41bcb26354bb6f6bdb56f9e4ce55639ad961c13cfeefe9a5dc253722122e89eb85e57b75ff8f5a9e9aedc7b43b039239a42915fb9873040676289a90deb9524bcffb3e0ece801e937fbd1703a24c22b69f43095a1bf06978228bb613951f6d3461b5ba63c984bbdf3487c8dd430f39e6fb849e13d1153c090c58471482c5e57ef844024fcd0e932e1c6d3a559c829faab36d590551383def8a98083cdefc65bdde0d492e60f9bd88564ad7619f79a7faea7045a340c17404a864eec44a69dfa693e9189e0e09ea071de355f24e5c6c989de46215aa9c7adf1c5f008f43de8232194df2ff7f31c19cdffbe3d4e15fd40ada7b88703f1c9371271d780f4965c05215996f5aa23adf5212350d6b30aac35cded0ab7907efbacd2a6adb30dfe4ba44b331dd767365b654980929c48ff57d7d27b3ad93c8e4201e29e2531ca9aa22eb173fd5ffbf80638e32749e30f074eace7d51dcf3d9f8b6f50c4cf1c057fbc816b70932ea097064a998e9ef09a36d7a1614ec722c51b727e55bf1bc0c072b5132e9c0b5b14a080aff97a25115fef9f46cb2f1cf6ae6ed6d156acc961f8708879e475f6c915d842aef14e9799f5d0c4227ecb3363e039108342023e235c65225f4909a35ff29600888d3ca3aa74d6df9d3f0a2e026c428bcfa8e087405d91fadd5f08bd5228066153d47f6afb91582fbe75785541e93ea1c9374778c781f741acc0a76c906ee2b5e615c0520175a67302116747033b98e66c4cacd98aef3954abcc55d628bdfca5b43b317e447f599fae07dcf76608c8948f3a8762f3dbe5777ff65df025a486dca66bf8ffa6d7bee405fbcec684c15813cd483b51988ea4d2e1e919199c441964a8bfc47320d14a3d3d87130500000000000000000000000053dad622af7576d00907ad969b63b1bb5040c14d4dfeedb2ba37b7c39ce458fbf1dbfa37df21a50e953871f07224ed37fe03251354c31d8f07d2110783427c7755cbb62212bad8ba6f121f5f94302050137b23cb9aa7fca9826ad473ad99e82d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a1e2411bd703b1b6a31dd4dee9d41c18a5a8d5b329f4e88fca9bb03af65ffdf3444e3f97f9e67c35d0709b3761ca822f3c60f97cca74025370cde2a28f57737a9f12774cfa8fe3bd5d2aea4920feaa646c202a69e265becb260979a5e718cc1b14c6cd8a7bfe522586ddd0acb60497903d81f8e716d30d64b61dac84b99426f022a40a892a21dcbff64bcf4f8c3b50c5f59aafe70999e926e5052a4ef2bc73277032479eca488d960b1bd127cf9cabf59b3ab5a3d18b77f4ebd8101de1e0e43661a0a0ce45a518c846d7f20dae93f938cae4e7eac9385873511c265a16ee49dee614c06444d4bcb2a3ef186e690a70ec1b226321673954ad629583a9374c6fda2347103128f7d6bf6347b2ac12ba70caa9c73bf05768f50d379f89fd9877f45cc81e90702291f0c3ba75c9801cdec05dbfc0c322a4b090650eb4e7555d4f416744a70c0a7020ce6062e161ae075e62d5edfcde4f3ea9ea0a59ef9ea0f01a046b78c333a1ba1022fdc73329259a4877172d8a246808938911c98937c2ce17e5718170e29625a7e02186fd9391ba0a1cfcc5cc3f9082a0a12f22813cd316ff0a7b3bde27dbe5c652b98857d05b65adce84900e292e62388542f1136fb9b11c6a3948d7019a95513012f688c2e4757d6b906689ab14a125b6473fd64fd5088fa57e12ecac8cfa14aa7b6745569df3272c812fbd2dd12c3acfe9b9c42177132087613ce8441c9bbe804afc25744f12d30857e2bb26da15f944151fac959e863ebd4c9a16698aa0f0718fc00b50c589eb56b65c028de6ffe7e393e705e9a248fd954863e3bf4550bc99d157e805d2e1d54a5b177fe6b430d2abb32c662013a10f1ce799ffc963b7dbe38a993cdce4b49edcbaf975df0ea755ca6134724900749802033f9179504effecf5342b421ae85e2b4376b1d41ca011de5190b27b79099aa3e3c2c9a799a01e9edbefd1145b3d5d0cd2e0390d9e6d4863346d6f66b04465f7fa1c9bf414d4d9a0df780c801aa1a6560714eadf342a7f08db210cfff5467cb2fc0f0df3393550068f537ff5447eae7988067aee1c4c98a35eeafc9bcc6b0d5d7243d74f61509974b34ba4ed47ebaf53a8ebe4015d70634f65afd75aec95192a2ff1f3d68987c86659b91e937efff58f40badbf2cd293e75ba21085fca99acd78785c456789e9ae37bfa888d4cf5707b292c2d453e5c0152ff9c0973f4ad3306a963142be64ef0554e4a447ed9ce19ebf849eae2c1d1db4fdf7387e74541ab61759610995e1dde6e59f4d8815456deb5a4a56dd226867de4666a9d9e37e944c50cae995c4ffd31ab9ebf6d7a86d4850c19596a7773a88463c1d43424e54b3e57bcabffece95b4938cf33fb06f8f5a1a3556d2536d2c526ba3a407170fe5e2df44193365722884263a7a3a90e3d557378a16d1cb5bf4edc4b09657e41030827c96cd518cc0ebd5ad13a4419a15baabfc21e2b764cff1552bddd36fbf61bd8033dfd70073326bcf2a1e49060403f9aadf77b3bd59a041ebf9662fa5e1bba70b3cdae08ab97895d0a23bcb11163bd2beff8ead5cfcc4f05ac0c221efc8be662ad16f907cf896c64caca1ed265d6ec09dda36034e38ccffd1d29785b42c707fd1b10b31abd888a1c042542ecaf4e139bf38eb869295725bf3a7c30aa7d90211c3686ff3fe06bbbc7d05532da3e2bb55cd7926c06ae6cb8e6a3a5d92ec0e70121964b3c418efc25e681ec5ea0fe7b5bd02acff3316aa109b7d92dabbaba05cece217b71e0fd576723927fa3fac59bc68c8adf4b817a96578fa083e61d1ada3db9bf93ac25b5486d2ba24a8f6d16dca059ad18f68c2ad05e48d3d74749fd458f02f2af8feffc7e73ef6c04a74379b3c2867497e21466c8ef08697d9c5b4f1c59647d310cadd8d6b22598e8f313a3e1c78dbc55590b0fa33500fb4ca7c06614a615a34c18a1d6eb76b534947cfdce82a73b10a4480fba1bccded4324f191a9cbbaac2f2df877685cb39a7aa86add7a5ec451f3a973988b6755ac580c642ca38cb0424ff2187e3b00b3836a12529496468e36f30c5f44e0d4e42a84f67317025138e9cdc40f1a9a1bec50d20d8b304bfb024e375752a22a0c51d208034a4b541b289c2015298147c96ebbd34354851e6a2e2a812747b3ca0d4789690d2ad13487c6c4277de65d872fcba58646d4b75640b8940aa642f9d77a80e1d60e7020af6de68329b8f6599bd1a71ba518996d5e036a79fe3d609eade5b85444c53a3cacfa2cfde1772ddc5aae035375d26a459e1d74697855055840965672fcaf126f8462dfbc2b2d32a76649f0219a8e6613117cab1931131bb76ab517a55255b66207c60554017b7626315d28e4ad843f8914e1d9afb1e3bdd69381949975f3c3461e7abf28104bc26b423c9dddeb32b9bc808071dec590449db4b877eeacbf4204", "6553535363", 0, -1507154841, "0d7d9d163b83010bd7e82cb154af0aaa63ae35b472e6567086dd9ae49d608860"], - ["1cb311e5047a5625e2da9147245b52634d20d0b8d21bab797289b8aaef5d3c0ba2a628af1502000000070051ac65636aabffffffff7b513e1e92edf8b8e5f776b845aa1a5745f113f87d7c4acf2e1342e6150493a203000000026a5201115cb0088bd443beeca6931df2c269a87679b5054daff72e3aebb8605adda306aa0a2a03000000026552f10ca9ebcb16268af101bb686875452127fbca63bf625e93c4f37875bb479efdf66c78d00100000008536a51526363ababe96d24c8047080eb01000000000253636c723c0200000000009f9c0f04000000000951515351ab00abab52098a5a01000000000651ac00656aac00000000", "0065ac656a5353", 0, -1533137217, "274c7ce6beaf089bebe36c0fe30e8811220355eec7da101d2e56b42a7c65fc78"], - ["a76f7d83022402bda653adc5c38985e8094e0aa9346a741cb421043c4e49689ec019e9e3530300000006520051516563dbe0f3c21616e05c0d56139c9211f045e180a1132bcd3d39ee70b806489654c537e3181900000000036a5365ffffffff021583fc010000000007535351ac650053713ec7010000000004005253ab0d657db8", "5163", 0, 962319507, "d0b4e917270c5b7dfe356dd7475733ca31bc07631c48b55a117755e57b162fb8"], - ["d56f8d3601774412e534f06fa24b8b9ffd01c6290d3c2b3407ed051f8f9c9e815d8276e3b9010000000165ffffffff01e92652040000000008ac5363536a52006383d49a8102240a090100000000000000000000000066ca4d44de2ee1bdc95b335420997333912d01856459818d9650b06231f4de4173dce3beca5445d4425a28e5b7698b1cc93d9238b700fed61b173ba6cdedff3a2c988826c9edfb33e4c6ea5d375ea149808fac6e17f9686656ba2d75b0adc61100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000895c353d7313751376f368cc743abf1936c29010e740848bf37d3931e22237a7f544f15ed547f7c5b0185f33c589c9ac9cd7c3f1a44fbcfcc68ac96e02bfc17244c624b0a33de554564d86e04fa56757117f21cd65b28109bf0b8923b7d94e56fd170cd3bad114a7ff844b3aa9b23a9dfde7d8a03a753d3d6ce598b528d67267031da884755dd064c78bc6cc96d6e8e4c60c28bdffc2a915fbef42ec6579c474a0022c047fb49144eee159a87f4b8fac2140cd1eb96910140e588505441253387a440a23c56081df7f470bbfaa5f6e038cd2d3cd0e20cd8a0b336e7d6d375c0ab5f7f627377e6bda8e106156c37925817d4030f8bdd0cef87e3c97d2b4c52c07565e94022ab91cb24adefb3adf90bd2ea25d66fccd32b895f641cfb0423045e23d40c23903248aa50fd29e1baad51961d32168e72b5fa94ce002ac367c7aefb82c23a8d93403230c95c440f850f5b3f58c3e083073cf54992cf90641e27f75c2e72f7236cf94031e3ee062b6a81a64f8a49ed23502d20a980fe081b8fa8fb96c532e762bd5d857030c6acb5d6ccb16938d1830e2902fa44584bddd1a75c18534948bc87d9e6ae23fb477c4ec55ef21317aa8dc6ad1d70c98f14b00a91317b8a7a6c6b50ed8130ccb6e2127d0a45dab00815454fe11fd9d0adf06c924ac229eb4fd41765f03028133a18a5578eecf1dbe1c50b7de021b3f8285af17738995ba3a3461f44e220f1cd09aef2997b810845f76b5de54b00fa48e4a98f02a0eb5625030775bae352d7d8e456acaf7b8dc829df5beff8a31c1921a2396a288b3536ab265f781948a63147a5f26be895602e4f5f225cc980ce1194c5a02512106b51c8cca0e84ba63caaa7238a2fa0d9077196c7f1a46e34de0cdf680280ef126c01e2a729212695613b95270ad52f2bf902b32a75cce2b1a94d5f5f604a230a1a0ee384df54c35a4a2c8754dacc5b12d1e884997c87c38e10db2c8e72cc0e90e618b6b749e3dbe592a4412153cadf179171ead24dce08e9b5e4195b5f05f411ac8f3db98c60a07e41de2604e61c846811510c8d0587baccfc0334603587a0f61b2bed50ee23477d20b1dc285ce35f49ace3513af2a184636435bf81468e17f6866717feb085a42e840e67e5279087faf344def3aa82f32080dfdda8fc777b2b36aaf5e81949bbe1108dfaf2ed2c4965445cc5df8814aecac8fecc35c2d3a1f70bb9ff31ede8aa2f12cd38504b24b23ea4e0472be6697f8d0b768a1b53a5dad220292bb2bcef0174965825f27eeeea8238533e92cd03d19e8d4f888cc6f445eea839f5672c6ac76b7958eee4f3877ccc9f4a67717aeabb18ca3e7a650fa8aa6480a8cb861922f77f1b9ed8ea940d1fd68d49d9c0064fd75771a0ead8fa1be4c1db13abd501f07ae0565fa65c95905d7edca9bd101ada53d855818cb37d7b415aafa4531d5f8305ec1ebb47c50c86f700704c2d90a8444f3b6d240949cc8dd4f2b97836b4a82e2504c9d71562f01cb75529c3dc7f6c248689bbbf9f4f24ccae87f45b39034bad4de0ea3047382649870d8e0f915d9f5b4e1ab6baeca7187707afa6adb04420a3e3478889f1bec57ebbe8a6ad860a6ede2aa942b4f5df1129b73c81e96b17f484c93835ed3d4a488b13d3b27a65d5f187b983f7490431a6199c5e8abfdbb7c14048d28ce63a3d9c1cee3e625a08b8bff9b1d5df6f7c3e2c60d6d5a2757eee6caf05c96870ee1b609388f2160894facf165ca65af2523a9128e6d1d42d6822b1ca0128ef10c513848d84df10515074e932a7cb9059bacc91ddc66c84b9c84aecb7863bc01ab86699127e72d615d52fe13b26142295e024e5a93be2fc847d5d6f92b24dfcc96af2c3fc92cd01f3379325e06f7cae0bfcf8086473353fcf657d0c071a9aee9e9e3b9a131645e1c439d0d6e9a6c5648c097145888f2b92e9f2ccaff420e6370e8815a7f78dc8fd6720d8550a938faa954eac2712a0760abcae6a3add93af1e1f44b5f2fb54962afb39e2a9b65aed7af11487815b16d8638c9e10bc42a8fd8dbe98cfe86ffbecb959c57615281f6d67bbe2f8680f0c504fe5c26d2c064cb0b5590ba75ac8f710dbd7d7c6efb87ceb5d9a3e8daca4eea117003c5bedb6867bcca2d06e170adaaeaf2df7c744fa8c17d707cada10da9eca1d79d0fd90bdd32b89952ee7992fa245a553658add8f462c69d7819d3e98a1541408c2305f1a28c613acce628e57e9ddd079a5638d40f034272b401baff84579e4db6f42f43c0093a91dd3ee3a3709395d87e571817b8eb725de39ace2a0000000000000000c280da0200000000462d935c1b7032a04f09cece0fdf082523ec095050108e936398ca77e62267a9d1f02b83d2912ee2335796ba509b0ac34d434316a351d59e72b2b2d223366b0da4d301095db6629fbd4c6593a54310237fc93210d3f7fc5061efae7657205bf500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd38c10a581a2d916ffc2623ae6e36f96c80590ce3859edef89702154bdbf877897685240cb018c8784b7f221aa7e25825d1a0427ce25e47558212a436b9a57ebeafc2fae3f4ee520ade8e2630d334ecb0dc9ce20b29136d813122fb91bcc9a1eebed83a48626c863f87ea23c117c64f4c8c0b4d7eaa3015bf8b3b7dce0addb20327446d624f686869bbc7ec3f61106c884861d3b84082860d23cace9af9ece24c03064d014044cbf62a8e44daf60f0f9a71e275dd580a7fd04dfe3e4cb516bdac4a0b27e74dfc66f211c09ed7a7acb79b67dd12dfc929ccf56556a0f0ef5dbc11e287049a0e635565af59cc9b66834bdb6094ace75c172c2216a32a74df40c2e9b55e032fd842b756da797a4839428f0d2b77eee6d37841e0b20a612348e6bb0f7ede2b02073910b7a4615297beaae6fe7408f72085b40d5c3a227ba60f4acd490c842030020080066d76a0c29d5b3bac1dfbc468667deef0558f02547a88fcc624ae7c11ce0201c90971ee0f3cec8a59fdf619d252e83ed0b98d91ec6a0ba0097d36425121cf03100c99a14847ae04059909aa08efeef66118df68a90b3099fb6e6d3caed1e43c21908a48859ed018d2bc5fe1666d00cc0d6430e4661525fd6437308171f2b7b85635bc7fd0ad186e4cfa034d2de329d41ee8a8349dd04deb34b76bfdaca035b8d173efd4e4add5d1fa3069a21fd7bc3b589f949cd436be6addb3c23019e6d831ec45638e2292d5bea41395f7e3f0de4937b27b8b6f8c6b670afb13e2dbb05eaa12fd93bd161bb6296c5d7194a83f3ac3ca76cae229caf7765a767c6fc6f09d3518840ec5be739f4b17a1d2345cf927fb67d23865f00975c9868b24c1877bdc3e9bd371c8191090a9e0433ec0712a8815863ba4b1518bfa196a436ea8d164b887384cc7784db7229aabf18111066e6f680fd83a74b69c853a0e2c20552870130093b0e06730614a9e9397c9cac16e36daf7b3107e34520981d01bf197cdf26b2056711c4d5b56724d3db98b9c7138c2481b134239cd54d42ae5094e25174e224dfb2cc4355581770316f4a9db417683b7f4f31cd5f49dba7f93bf0a3fe62b85de23de21f439ac7769248cd9929cadf6b705f36eb4d537230869728cfc109f5df7e839e36682c1a4cae9472657dbf900038279a2bf616cdd93fbb03c15b29f44e806b4427e2bd35d2e4202ef2b1339dcef0a369e05f3f5dc89d110181319ae54b4b4798554452bfd6bc3ac2b91f4de92efbf535f5ca223e8940008c8b35376b8a02e18799cb6b00964cda27e5c699f2642b6cfd588df943de99abefdb702d2c44a2fd0df2f093cfe89c30ad77a4b4508ca794207949068bb96a79bfb8100372e26e16fa6b397e0cb8c91974734a9646b515b892d5fe725032b4ea614563e59d8b1abcb97650feed6b41b55765cabad4397f8f3ff51f5e2f0456c430e324e1697d4d287d1b2656480e0f404e0512f18449b170925f5fa95fd5f51dc8a88f2b598e6d46cf12c74050ae942c2a2c0f831590c458ff30807d497ece2ed0eb4ce2d68b2947f1029e692089aee44024711b51378cc2635f1929dfa41a1b8dcbc8406fb559af1acd2a52eee96fac53a6a32a25e327a0b32b49577ffa08b5a1715bd2ff126b4c8c9f2e6763883a6c541e200af43593d486c646d21d67a0836b72a24ba402d9d4f7a5285005b7dd9228ff5f333545eb65f23caca641bea1fde914477c4c602f21b9aad9e9dbb0f8ff4ba3e1e2ca0667fff5f706b508a3e6a7fd5540baddcd7dcf904b744d87de60fa4f56fddb702fdbfb45ffee6090bbb23ae6da4b2d518b4c1888d5f42ce13484184e31f79414e3d232ef429d52615a0f50bab4252c97a5248b3761b9cf5e8f2dd16d732166d168d8cac11d3b5634b2ce52f7b1278d24713770953e2988dda6435c1bd3913cfdaea8404176738ed111b8ff41c12afd2fe7172759948b1b67782c837763b81eebe297d4e74db72603af0cbde50984f4aac26df214119f964dd8599d9e75b9b56dce2077eaf0b9d63355d4ac24bca1f2b6899da15266eafff492ee0247e06876a729550ddf1dff7c39adad548add69da80d6c584fa8a8918348f5030b56bf31c6ce88f555392e327e8b1c1d847f57388c1fc9de02170447ded4b1ed6d21f07c18ff38045dff82b426c7ee894629dc2365f9a8dba37d4341225c67a750c746615497650f048de89c07b1422910607d3aa9599c354a1ed35a40af07d8829a87e3ab254af724dbdcf49bd00d579fb22a5a28478883c3c5e62075ddc6fec307f8f1ffefc4354282894dffc73c1b47265dab7a860a296a4849cc6bcd21ce02cd6822e8495cef7241e3731744c7e8605d53d387d0a91e3e1baf99ff3fc6de8f045983011dad0fd28a87587c71646d024d3c76fc1e3521ec6f6572d674819e30e29f1c804c85ab0c", "00", 0, -189858871, "31302b0b5bf82d67fa0bc55dfba2b0212d1653f1b770d2af757be6fbb320012e"], - ["ba854ed102e09b9dd6135120c4c23c1445579c344491c16c375368da910f4fa936ac795d1b0300000000af79ff6b2b18f0f81a764666eb9a36b178d1176b5b1a72cdb9c5d15f57ef37e52a2283e60000000008ab00ac6300636a531f433c1c03dfdd04020000000004006563519310df010000000004ac51526351a9140200000000075200ac516a6a5200000000", "53ac53", 0, -246097963, "432f48bd7288c5fcf8084474c909ec7d03c870adc68fa215d82cd8e15d01bcc7"], - ["1844eb77044a356885d20df7d397b1daf22acb88612db507ce0874c5a7a646e243ca96e52300000000086551006a51ac5252ffffffff7799b64c6b10cc6a44ccde733895b8ab90ea25f4ad7de40cb327739e245567790100000007656a6a525300abd883acbd8b944e4717076fe8f584f310b7c56cae467d4daf345a6472d755069f8f36d2e2030000000253abfc40b8223a41eb2100bdd108d11723cf1481f95812c5401c75d975d8191b2c639abc980400000000086552ab00ab65ac53ffffffff02b5f299000000000003005353f79c320300000000086a00656a63abac5300000000016b15490100000000000000000000000064e674a2b26ed87cde7569a56aad8dde4ff4bcc6bc9676664b4abbb582408f66ffd8f64bc0ac82afeb8066b22601be915f045925c9b41445561667385c2841edb2bf690a57552739d7b92901e5f1cb5fa4b66c8e9a862611a30dcedb2bc85eb100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000623583f9c245ae79a99bf38086d1d9d2545530b76a2ad2243cbe39a8f41bc291a985b3faae604523cb14c67546c16f9f470bdec10c8ac17828ddadeaf1fb05f79001e43a4b2ff36260e8232170015cb748e7d93789d94cffc1ebc0df57f0428fc9cf3a7362e2ac2fd7a245d09182fa5a2762397e4811e1ccf85f16b0ff983e70022110c45da1334755c6845fba465c8a42465377edceb3363e8e39f74c3ff60f240325d939b881de83c9fbf96444e845b20ac31e8dd74f87bbcc1337ba3b77a500560a2d5ae4abdfcc5390878e72545e94541a10d86098d9c76b77cb390730762c65a90c8d55e70ab3aec5738e5861f15186b9bb98062762f8b5433886da56390b4b4802272e64f893630cec45b6b46e74591571b21e67471aed2c3c86642fda855c0338032204cc747984319cd6e61c2a84747709ea862c7dc71c7b9d7cc937ed6c223cdd032719742cf7892d372b33a2e541e1bc581102c863050326d8be8628fad5ea3d5b0328a7cfe1e1d7d23388d34d88984f8cc16eb410a2df2a65edcf0306ffa0266f5b0212146c3eb1ca53077c28d7ac23ec1413eb1b5c39496a17d6c217d0bf467bcfafb84e3052fb2f41b09def5c06c5d313aa9db9facfed8bb76e4c9c9b7bbf71584709f2220ae1f8d4edbd1f046ef2d05d586a2a795d9586ebea37013542dcb6ea077a6291c5c3e02d64782bc5b2d6c88ee21f23aeb197409f86eac81209e65ad00066974534b23b8da8f8ba3277c4821cc6df2eb769b449bbad6a1d8c67edac6cce8927518fe6f4b2494c4a8deebb744992af16947a086b1cd03520485effe4bbe5d30bc114e841740bd92118ed98a419c050b1e6911030911e1200fb277d76c283f032070f5d205cae1f96ef0cedea8124b95288d13c71e65852374c9098c3154086f0ced0fc72b30914ac849f171a20201e65bbfda64bdcd7f5e3a4bc4d061002ec716458b49643a4ad9161acefff0e4c9ecb8da70bd80ede51259c70da3a290e4b74795ac609913ac8766ca40aa7344375e288eb270793d0a544fd1817aa5c3e0f89d2ff558e5251a2c3f83d6a3bddf64023be8969de0d23441fa4e3a10a4f34947abc5ddb4c22d22dafee4eaf59620b3d3d2b892e20318a4729ec6e9904b5d7c0f7a6a10950643fcde9dea4e790f585d6c8143f56401468418fef78af88b60a3a13d1288b0c7214e2ff04f136df3d5452010d2af16e32156f41b7b1f48f719d4992db8f2c18c7d34c6c828da2dc0c2dfe08957a931005741b2b95c5bbfaf1d0100b2e735b96c9fc33d5d878b6a26fcfc621a62a73bca43b1352480e611e26813ba6b1fb074b07d8fdf8c17d9445b226625d19fbf8d2ee348c43cd58f782fb6a02d3f87ab816db6ffd5dd0d687c14c3307b6a9b792386be0e7f9cbad14f1bfda7e97394861d523caca4f08b85650dbffafc2178a517ba27ab599f77defb07a21858aeb0143c169abe80cdf24fece0b917c55185048fe83f1cc8e5312fbbd0633589340123d3901dec87400c88d118c01414c2098f4be8c47a1a1b01656f768e26a6a144f07b107c9b2f33480053991c675a95475077c0d26f2cd602c84bf23cb86f05538b6cd3af77a706bd9c680a289978297e4322e9ceb76388a0a37fe2cfc250e3ca667fbf91208254ff60f6c5a6ec718521eadb74361dd4b9d9585cc02ea5670fa80aebd94d3d9aea06429d8301cb70ca89d5a828c9c9cb194e24b6e270d8f5b61c5e6206680f6044c13f1ce81018aaefdb08e2ba2cee4f233c2c6652e9b1894930c06693c45fec9a5543b1a702ff37df7436a03cd592f8ee1bd98d5a8e9e51c071b195ae308b73ac377fcc85b91cef3ae84b6b958b005e76bc8616fc9d53d0a9c3be697a09208b9653c72120c2faeb3624799c8576eeed1593d9ffeccf248448f1f26fa696ab3051a0c49ecf5399f38fb30e04ebedcfb4e0e4f022696d8a53e1d742b9cc36f9070d71c4ea28c5cfe45229491c0bf138c3fe5c605d9d1e7b6e7c29b45103e87375f0c5c11a3168c9fba3db9c291c7d47132f1d3349fbb4762aba067df20b04c4f89f4abe0ea09420dd256cbe36c8c2c59d5c3bc77f287f4c38756b1dcab58c06a607b46ccdcfc2d3482d94c3110dcddc295411a04d75cfe0c583a6d17381d4431693379f71ffa574ab2da15d9852a861ab6731813c49fd06dd62a9fb23034554553708761136f2ca7c3a42c55d8dfe56f1633a7df1d62a4969cb16ab6d8596c03f540eca9e09837a80bbb598e8f08616b2889ef026fd8f1a5abf11cf7509647d8a79d70cde076f1a5bc7d89f4c17c6cc4ef6b79fbaa4439d8adf6d3bd31c71e13f91fac87179e0a35114d12b13dd1936bc3010d7c3d245c2cdc22315fd891f4d5672a73cf34369180d0a02d697cc3bce87d521e822e631bf92c02e11548aafef2ff6a758fa76496970f", "52ac51516a536a", 3, 939494798, "0cc1c75c55ed572b62d93d95faa69b82971f71f69f3fef35b033872ad0093594"], - ["d0c7fdd802806f7925c45fb9d42a514532fe7a16e1fd1d6b0c2ab1081a9e8f081afeafee9c01000000046a516a6370310e30d06c88af702aef9ae0b9711ed9e91d5630bdb657bf541ebb5a70662e658e10f10100000000ffffffff044fce5404000000000652635151ab6551884703000000000100daf1e404000000000800516563ac526500928407000000000008525363656aab6553d833e4fd", "5151526a5251", 0, -1112764220, "f1e168d185e3ed217c2cd57f729a5ecc427bbd7973ada07c00a65e7612159106"], - ["38fbda0203d874f265c6ee03c28a4fe8b71dfd8fb00a8f4a920541ba605063b8fda1c8f9d50300000008ac5365ac0051005338ea37825fd9ccf602aab90700a02388682124da8140039f82745a9e1eee038a5ba4b8230000000007ab6565516553ac57cac3617241d072e65f2f391c1008887739288119b104726c0b447246b4d9dde040526c0200000006536a6a00ac0088acb7f703046491050000000009536351ab52526a51aba6ded7050000000002526a88ec640400000000075300ab63516352db0aa67f020000000000000000c1c2810000000000ac55ef555246a722913c5058e92b86a23e518b6c47a9d68e422da0295c2010d7dc73370a65398c3585531fb23c940b2b41248484d5f652b7f5f2f09bc766e6773cbf48f800118d186f52a48dfa3ef8dd9f21a9565f0ad7ca82dac19eaa81025200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b9f221c2289df639cb4b7b1fc9981d35d83925aa8a0459ea766c053d8a1f6492024e6d34dea6dd6178319dc51e573869b90332201d5841c53c3f896c48b4827a3b22c14e2c2982858b1e341b1a705c74c1cb867b1dad111c5e1fdef8a003cf15f2630628b710faeba0a62defc021f649ed15281fe72c2768f77ddc0f0a5b8ade031c995a7081c1f3e819d642e81da79d972e071eaec43f19f204db62568394304e0202d14751fbe990780c63e02f837e50cd8fae7393f51a70e6df2787b091297f6a0b1ebf55acd038e56fe23c88376af938972e3aa9d83defdf6df2c9f7445663e1b40d2d8df02e5349a27c0b65b4d449955ac4c261b80735f4379e38cf1cca4919d4021fbf6929c6fda8170bc5de4f6ab529aaf4a8012ab8c01e01239d413d9463c52e0209d38e27467d469677e87459bbf42524d98ccde5389dd8d57974efad6a5cae9d0306c98690d930d1adfb4f62b812acaff6de2bfe083f394d87b157a8fb792f82260304d3a9763767e98d9a3c2464a8bba418fd2c2c884631f2f495a7c80b72ef0f080322aa40b4b7ffdde46758c4c3c1813c3049ea2863fe6ba0595a77de02ec36196d19671070010d30a0211535c70a67b525ff4f334998186a99c04f9fa9d50978d573d005d475dba359efe64831e93bb57cf6a63765f78f93d356d352761041525de032979f9aa42f2805440b1cc503bebbddd70f24017bdb49c11298effacb06d8b7c2171f6b79593102415e98ba8eae37d6db7a3a2535d4bed80107affabc694d9417b683cacca2c11dd50c08d16cfd494d420ba2df51f59e29c6380725e7e67cce117ac0527af53f9c0e85e56db0649ac7d798bfc40bc89bd034f19ae7e42af712aa1bf65469a346b1de39d3dcb58fbe7aa83afcb4e8046154b12dd5061eabcf4943d8806700557282d0bfadc49f59e92312e030b65ae9f5604d410322cd5006df7975d8166f98c36128b86d9d168e0014ec1e90d80892e88463b54710b5080a7751253c37e8cf58f77a84f24d89247d5adb3ac698ba92edd352f223c99c055f032edaac846a941ed130f51bbdd6f2249b189cc634e7379bf87076b7a95c2580b99dd13a72fde3d1691d178b0769930d948a5c9e70f977c79ecaabae7743da6a80d1a7450787871f021a7d5eac4610534ecc9883c0ed56f2581ba541a89db58bade7043338b39ad8303350d7a5bf773cf9f899c4a78a2ef4d350e4814059944867974ec64e07c2ffc5c1fdb49c5261824f6fa356b28a3f2a712a7f4d0fff047ebb4071a5fdafaf1a79cec03a3b0f9c36b2c62a82730b09b184850cb09a71ea47d4ca06dc0c6394030395e224113ed32581c253708bdc173c9a4efe26e9f8a13e397f159fd2c0c4646b77ec9bcc302f579b1db83692f6923200d8194c00233b2da4581a144b4e695f69461205941ad81f7e31b2ced2209e489f60e19c97f5e0ac01915e58a140812750265ad40ec10276cc9d8be4b50fb0334c5dcd51b81750568685748c1df8480994ba8362e40a48db34367682519e430b58fca1450142ddad64f38c1f57c4e85384b80e4a2a28d12c83534e3259953e288ed7431482262199bee33654d290c8263b7864fb5e7ac892e3bece78b07b34b4065e33233a7935668698915393e884473ac4a47628019925949118e5da91914b730f811d4c92b91e001a2e66cae7d6ce4f06e9168f400b7d4ab39b8fd2770d946ac4dfbef190aff3b59f0c5d29efaacb0371bd137c21fb4860a6ce0ab03fe003186592b17ea1c347e013ff3394e73698054a4799997822241d9bf315a18d46429a4b5ede907f3dca089a4cab5088f660e7343e41260928050656103a48ae086e1242a95907c69dc89f35cd006a4943792397df9e0d7f36298e73e7ec33564934283672946878456765142d857c5eef63918a064fb3c47df65f9f8f6c47d1b353034e7232a08f7ad6d8e2c1adfeacf1234aad85a6d501c36895c8c5c896e4b35daf59b2f5ba7d2221a3a2faad7900aee9b0795e5afcaf1146541424988a2a7bad3ad61f40050b4ee2118f8dd770a3a7f9e8e3bfe97c3841e2b1ba28aaf61c7ab0568314343fa6538ba8293d55e0482d1ed0560905d42dba69f4d834de6fdba285fcba9f521673b5e9471f093c0418813b7a95001266974147ce3e58c5210b87a75963029276a66315f59963edec6b73d79a55669d0ab9405825d8ae3ea03f47229e6adb1be51155d7ef28d565626852deb33b64b4e20ca7548b41683756136617597056c1767e652204e125d2d4a1c5e1cc46d80a086f3deb7adb0000000000000000b08b5505000000001b18d552365a7a80633bba4221a24a40084d9300e3ff1da15424fed2b0397a11cf54bd578ea86d7277f0c4b6fc17c221939610546e70986d03aefa4f9798f513d4f9fb3d837c63f6f51fea32b75a0d9100fc5bc5b8413d14aac3a9f389c9769100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc89746a8a26bf931f023fc62be7b9dd6b23aa273ea38c85f80670b5b087a3e3e34ab0ae3b308868a7563b778e732c1e3c0401ffba29f94942b751a9bc810c667791267e85dabe8cacd9d38f74f6259dd6007233197c2f0c04910977754ead549bab2be1931c99bbc6905c50da60b615dfaad3ab6e63dfbfce8f320e84ec2778032b30f9bf009bb8b1c8416f490d2116e11211d4bb15a4044f4f249cf5db0a8dbf030339841f3785ce307b52c425c48b080000e08ac10bf25e0f3f34c1689061d87a0b002f5c482a576e5b44bb04bc4d9d9c55245c9da067b0b9c3bd762ad8c44e3eba05bbbb9db0a2b31643ef9d9c760c6a659f17455209ad839aad02005fd7d88c9f0305d21726e0748be8acbf675b3f9ee264163f41a3dee23b2562275db06442d4b7020d798832bdb98d3ba34dc39e443b1f9f50b14a33323d57be2b5764aba4af93ec030cb42d993f3fc3ca67c51cd280bb13456894730ba61437207bbe3e3c62485954020b79e548853b32b53faa92972082bad0bfe39ee6e161cf292df35e67f2cdd309021f1791a87d5f16aa19754f407e0e8c779b24d64d67f9e5c97b1ce99701aacd602b744d7d573bc4fdcd334d63b19377d2b5259766dd597bf74c37b459f7fef0b916d0114cf592626a40d7ec926625903e764e0ffc4ea91b7723c1ab58d81f4c4f2420d00e3cbd3729bda824c140d5c095050cd16963fd00f7bcd33f367192d4064def812a0deb8a26bf7e71007ea6542781ff70133fa8eec8377cc88af562ca0938455319b310c92224a7b6f8e0fb137a589a4ec0bab6580ce72b18eafbbf0f24d59db5baa462772a48d0aa62778230d6b54270f778f8968775cfb69136f8eebee62042ab2d3238cb07ada37cdd9f8c428eeb9e016e244338d7ce8ed47a461e4ba30a725609bf8234d584a7cb527e8fd0b81ea56fe8424052e77ccbb79587835c7af93be9493ae15920292b129fd086d9e0a4a73a5f8f7849a109d9f11af380c60386f434ecf40780ad3200a3b328fcec397bb9b87aa7d27eb68da7f53a83370a60dbaea07dc86e6ae6647a1f53bb93607f8ff42760b0710035d6272036cba7e789bcf7546d5d6a2781abfd95e9e6f25db92dc0dd22d3dbf0778ce4c9da294d714c268317616b2614bb297b5069eb6d9f7b1aed36cad5857a0977d7b6e1eb3209c02a257f3010db385cc698cd32e56c7b662c45528f7c2990217cee41025da8d7334e986cc4203488255e1357195375c7aae7d2a5f48db7142594dc625aa409eef34fd1b2a63fa3e57a0c6bc8e8f01717a162955be986342d1d3ed1d3ebc9a12dcbc22cb9db122b11e73c22620745dbbe1b770a40e1047b9faf8b2328b3996bd620039fc00def8711d138a6a7c45dd04a5f4ff09c80897be8bf492d0c7c67180590d333409118203a7e030c028484dff0b69b91de8eaceecc2a936aad26b2871da17b11ea670837e256169287495078e7c93c943e94b5858a564ed7af789fd3fdc6676129bb9916f2db92e9221948faedbfc547cbc9331558ee73dbdaf5f665b4262ce3257e305869288d6b394d59c95195f3aa9ab0f115d491a2aa151785aab2b039fd5147da7d765e55f594edb1293086cfa52901e7b87bd9d3f27a17e506f38ff9c8ef03e811bae5a0223d5cd818ebb99c024cb438e0d239d667da10b3841c61b2986a1359df1453caad5492f4af8f1e12fd9f15e06288fb7f5bbc0d42dbe12a07d60c0f55cfe4585496367349152a957f4e2d92b473963aac3a10e4809b1c60dc6beb64fc08eecf9cb3d5a17fa88417e34b2b58dc0df819710d410e4c329998b9d0e31b43743a730f1b381efb51dd182dc66e4f367671c4a065e0c8414a8bbd8e1050dfba44c9fcd7c3c9b52719231f35d19936c4105d60573af6c76db8e7b3f0dc58405071618a6342df9d1479a75b6b53521cf2f1f01603b63020e8018666b08e180cec60e5e88b3bc9753695cd801197e815805d9f4328b59cf03fb6089b0531104d158afeb09028fcf2c8a47bf65f08d4875df175e6c39da1c1257b8f481d439b5d6d27c997ffe969d6e921301af3d3ceb5b8221c3cbebf55ee3f48a634a108d49cf2c6255c807faf2cca1f88633539e1675a211cc171bea643e56a60a76683ae118cbe4e444ad84dca519d401793807216d4211efc9337a0a1be7012a1f52adc956a5f22a0b30f5678d75473ffcafea2ad68433bc2d0b831c2622f5252f6dbc4ccab9d9931b6d61e20769b12d4c5132749d93e4e67e0bd409f5d72b4c03c34802934fc7af23946e3f2acfbbe87edd2559c6bad08b89859a384fc2e9ecd7ba99271f83f324779aeee6b94d18477b23a9c82a25e0f92eadad30ce161d4467189e414e88bda9a1b9638d1ec168d06911781226dd41bc4babd5407c7d45a73543fd76895f85b5673b04b4dea7f2c7e0f", "00", 1, 1254601664, "2058c6775d1d75642ad4c832027972d0e8431ece85aeffb5df1c1ed8f1da08b9"], - ["ab0494810124db8b073039e4f4234282f0b6106e9272b71c204380eeadb6f14386705b0f13000000000163ffffffff04693ce60400000000016affdfb804000000000965526a516552656a53d6f85d0500000000085265515363655263cbc1460400000000076553ab52ab515100000000", "ac65", 0, -760664371, "326df314a309ce6c1282fb59fd3708ee9ee8bd4d882050cec69935b4741a7aab"], - ["f8db671e019d148a0c6150f9b948e5662ea334688b526a6d4aa502a849c10160655afc6bac0200000001ac20b7634103c605d70200000000016a8c682801000000000078e3b9040000000009636a6aac630053536500000000020000000000000000090e7f0500000000845a6132db739b9cb963d669dba367c3a3bf338e974161967c07a87b356a647bf26283f3514acff9fe5477b88266c37e116f09c9183f1a41cc2980567aac7f35130b5bc7ab0f3c93d5df13622c0ad2fde0b6cdfd484a4958fea372b8d35409dc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b042efebdaea17572004c4946c1cfa1e6aba58fa2fd4bce0edec9ebc661f8ad56c2fd27e6e299f7e7992c1a4119f9ea422f2eab35e47144cba85b550c71e169a323b51c56a2ec1384b781c8b9c66815995ed3a56eaa8e19b69c1a76b97bf311f25df43a2443e9770bae3439422439ad5adeac555fcea33010347a7471714d3140305d47483d376e47f9ed03b0e7092471f29f8421bcdc4d3f9b1b639aa23033b7403121578305221550f0c7c58194f9d5173cdf50e34fe860df036afda2e9b31afed0a26418a43b414ad303ba5d0d4c3522c856bd06aa40dd7c3646642064d398f1a390745c940ad32b72d9ab8dc795e55412b1a843845c08117999ba671dbfd372a94031dd5a0fbdfae997ea3930a172983c8bfb79404d35e8d95f37e9c3feb604abf5002169df91308666f5fb042bc0bf6af6c5d0a1ce0d812837924e709afb6497ade1f032953bf4f1a180ca87af39241a6467293ccc2a11104bc57596facf11f22dddcf202059d32a5f4bd8e6568dd9418bd1e19816906728525457a60b4768d8b74c048e4030ed2307429164774b69b77389784b1511e80b1d5d727e2e1f0deed2e1b616f5d41422d31b7f0bd9759301abe0ec77b99d630250017acb509aa7b10ad7edc0e592adaa58e744bb60d1d35e41b7f3536ad1fdf99f2751976f1a30570264ee87be39b088f908a20c0983c2c7a32297ae5721c16f7cf25c28b94ab266dce59cea66ff71ae229bdcb38b9d86597d2b6e648c2e479087bf0a78a34fe0e3e318b9ff834e8243b0294648c8c1b8e4882b58b92a784968b655c94ebe4e0101e95ac8fd1d8dabaedc7508b64e4fc4de32444f0bad0bc80408c8b102fd6fb109e8becd5bc74d7cb93e1b91f5470c2723bdf7c8331e47360b07178af3fb21ed43808a7cbb3a17c7c7b53d0172b813f2675f8a14ec7eac517928bd649ab194726c867e7fa4d87398e925ac669731209444748bbbca85c1835ff427ce6081c1c22d6aa0ceb108937205059d24a85c4a7bba5b1bd45fd9b00870f3c4bbce71ad95b42ca711cf68c21205dbc79a2093cff6de00edb3eaed80f19dff7c7e633fb3bacd4400fbe6f350ba877a44b2ade8f7cd7f6ccc67a6f43256aca7da94e8b199b6538223134ec97f6620b59c3aa22a4c8ceb052906200250f22e11b4072bc33bf64588f870fcd64f7952b0a2612ea68e31c4f6fdea23105eb05629a2eac11c4344d9deca1db87853dc76e326713f8a4cdfc726526477c4b5efdb986359376a614c383bfef93e2858acf618211406e40c65cec79c61d8b0583df795d4ae8848b353525e964431ed94eef17b91f87d18b4c2c8edb61ad427c8af243fbb15f7232c628412df7a964abe6a6609529017c7a6e68907b250268360bf4639f3ea48cd3fb46fe658b9f3a44306ea0bb4ca0002cc223d73c08913e36bcc518bc9485a474e80fd3278e53d70f6b40a7218a527996af8abb5cd9879d37d05b69f3d5b1c3a42109ae04a4982b509b0e84cdd07c03f5b264ee819d932f8d8279a15b7c7c1e770c05e269138a5b1489682c5285a860110eb4923733f831298b8eced48d3c79df6d946690d7a74a0e9d57a171beb0d7a3ac29bd830aa533770eea1d393b5d90a2810bc4f103b273dd31589746ced2c1524f554b84fea86a154b17b37cff1529381cfa872cfebb070556181ca10c157099c8f464cee195fb7b45cad27d33677d92ed97c9f1aaa30abbf2b704d44e90e7acbb6eba4482a4c49ea6cd32a246da18c2476b45b3df3bb6f9506e5c4ae985f56bbb0a9898239c3f106577f2e67a80c4115ad4afe2e267510cb7dd77c2ac61ed04a2dc86a5e423145599ab8cfed0097cf46a11a41e2eafe04bd6c3859e9a6eb6c6c91a69c1b61349b4b1d5663b799cb0a280b53f3a17ff6ea628a3227a16c33dc1eac5f7df4d4f87a0e6abbee58126a4ac37324b4d11730379d31e8e043d42f8cc32f9283f66cf27733f885fb9f996b9475e45ceb0eb56b18b246620c52a63d0505a3bfcba09e65e3f3496657f56034c69cf68fed8e97dcdc6c9df5b2705151bcd5c70dbabd16dddb9de1c1055c6bf902d71f87455a79e2dc37247fe966c426b47ce6816e3fe1ad2b6ce3434a1a915221f8682978cdc166c16c2c6b8a6ed21ae5ce393a88b06583945b6eb17c51c05d1c2545f785f3975639d66d3bd4b2f916be0d961df3da089bab23d4a7dd6808d7668b648936049ac151ccc1df197ab2d4961200901cdabc861b65ca0f8af754fe094ea0e39bacd4e2ec41518507c171c409f7da4be41816a4f917fc780ec0c00000000000000000000000000f65af88ada05ab7f4da0c7af39b00caf10af201fcfb8199e0704d9df89f998ed37e87c5d54e268c1d229cb85f006871197307b8c442ed0c37c9d26802553581b60d1e9bccfb4aabb5491b9c4cdf12db7974b62806841c477ff14877125bf1508000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d9034cef9ce65b5111f37fc2a5e4a5cafe8f5fe1b076bd8ecb06a369bc9f0cd66abaa5b565a041f8368d8a3ab5a43a6c1b5ceb132c492cab4e0b79e46f93168d83c2cea7a05a379b6e99321e0c7e4161cd74258460e164fcf8d0d15e76ae3889033e25dc2515203b9f23b583e2fdcfecdf89afda1b2665eb443ca3c6c49e4fb030fab8af4638ba46aed386aeca90affcabd6fc2b562c09bdcbe0c1c2b0a6d0b43030080b36341cddc0df0272fffee738bbec77ba4f2c70b2457682fdd76fca8b7600b04929ff48947e6a96964ca373b9840aaaa0ee165d00c68a0bb0137a9e8de65fd2a041a513a4a151e7f2e5831442228de40ed3b098982a310653811ec5c58689b02252736df22a1d9b6f322129e126ebb2cf4f4245ea4c8978cb099df57d039b891022842aa9ca489ced4b4ade94baff804037edba7b286e64aea102977b8749688cc0323a7b2c5bcd1468e77b27117c7573fe5fd276e4a58c7a983b26cdf3c8837499602084a00b52fe6b03f26983379527db9f26c43c41230967c18f1f3b9e6aaa3e7090200c63130f829b0f8a5aa4d1e241bd0c5a516a3faa4fba146c7281a1235e3a72914fb7fc4a7b09ffa4bad97d04d93d7e214a52873634f921c8fad0a6f9b99f03eb9a0f64d6a27a807c725ec179b8f50709da8b8b2cecba100a5d5b30e05c1a715fe10d865076f186b6f0dc254ded9476b2b9c3dcf8548062b8c221bf24138aad31dbb116a92d07b416c026e9832f8ca214b7a36d91f87436d8cb92ec6658d17a624fb6278f65519527bed24ea0fda6e07f99edc462de3c1bac9c7f7f0cafb03beddaf804d15b3d15e10755bb8b1c4ad2c363eaab53a86b609265e3d3d9c7c9c239c6581197144e45e8af8936197538c7187dc76ae03e68e9a37b5a65b718f920593829fe3b11c290e43bfa706f0a7f28d03edcaaa47918db7242effb71e9dfb1b72d5b3412bd0a5c8d37806491b447fa86ad8bd716f166aaa4df0680c303eb6686fca09371d00bbf56934d8744b9852b4f9c7b73cce89a62c922299b8648bab48ea4e555290d521e4c548b6d1af968edb745b2b86e66b14e80316c67da718ffe1a440a15d889e148cf62caa673ffab6236eee1b73dbf3ec02706c55cd72261fec699ffb2b2abefb01eb6e240ad94c9e79abefc8e2dd3bde4bf5330b82cb03d476b3b535ddf727bdc6eb3f59102ad55bacd5ab259f089145c5ba6481af5045b37f608556cf08f22efb576f07fa7dfed01242aec9acc8e2cb2f7eda4d3f1fdff96844a02c5e54bdddb7f30356c27ec8287c3a99f14fd844ce0450f8f4ea42e33e44bffc35a128e4658cec355c512f4254d471ac4a733af62de211660c678cc40718c25e4ce0383486e82a0d5cfa3f666af5a6a61ecacdf0d78efd0b807cd54b7c9605aebda2596170320866736d52c71a2fc71fc5ac51272347f252e14e0131d464ef5efc982c0269c4b8ab3dfabc42457219226ac8a57b0816b11ae88258a6e85fb383a286d59839ac6af14f6e85df6c22d5f2bbf38013fe15e484900a07cf14126eec915db36b319193f8338312c3c956f275e891d7fb7239b2bbfa8fdf24f0a30dc877c52f153db2bea04c0c29493bfc1271e31f9ceabc27ac8f04bb9c16b808e6ef6c581c4c403dd7ab1cab8ad6e541c956e54975758e07af349a59719fb3eb12279cfbf8bf70497f796de0f6f74d19b7ade33faad935dc0df69869a9baaf8ee81ebac550bb934d679ac002c5edfc56b5609303752272a979fa6c9390a6217a6420f93ff5bdeb9781eeb8a1abf000a72fb8c273cdf693e5780f2129994637429746443175a2f0c80a0794fcd55c54bcf106536fb21a68e39ebbadc76e51d7c7a453c4ba4cb294444471b42dd8d5a35e2697afe252298c5a01f2448039921f9ace9adce8372502e4d8dc551a0aaab2d2a096b831ad410e601239e435efb257c99cd91012a0ed45e29c14a152e2d05bc573d9b58918d0845e94bf6a9558a5fc0858f845d84be5ee45c3cb6f1333d8b4b20d6099f24525c1b6992c5635d521bb81ecf575d83aa78cf54e8bd60bcea0240f6ac3e25f81d7c3f534b9c3300bdcada0ed71df9f99b990a5307b375774016c628dc2cf096c5e0e00acc222d48b1592f0242c3f833c919bce31d4ce00066b67f13bdb2f668253846801b0ad1fd95f6cc1bc9b40c22c8a3fca6f3612d58c223c9e3730753f171de70ec6e36c5b2505997c6538f70a4ff575aff026a375660842a842f789df728ab5ac8e6ed9f7c5aef35f7db8aaca2643f40e2679b90837888164159c7fa682b4c478b575952b4106aeeee15770b97517fa5dcfc342cddcab3bbd0d9460981d7a5cf8af49062158e1d21082327c040205b4f5b6dd615b31d3c83a188e8dda1718c3f91374ad4dcd8ec89039afbe5cf9ccf4aebe2cf6b4c3783538c009", "51006a", 0, 999335528, "ee0239e5c9750c50f71933f310435390cbdc95504832d69b595ca0dd0d71823e"], - ["84024a0302613627dbfd7a2111b8282ce01c56eeda85cf10787c420f6f47ff149491ba22100100000005ac6a63ac6ac08eb05b2ca12680d05a71a6cdb90eab2e96b3aa6596fbb0010ae9a274cb48769f05de2e0000000006abac65acab00ffffffff0350da22020000000007ab52656aab51009ef6100300000000006b67ea0200000000055263526565d0fc73c802cac53d02000000000000000000000000641a722676a9cddeb37a19886945971e05263dae7b987cdc1fc871e3951bba034f9cab588692a665013edb0ebf303ecc9efb0eb6aa5297ed804c81f0465af8b1bcbddc84ece0fbb4bdb428713cbc1cff39c074db71c952ac2b207d650912568400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee6bb6aa3c5ee6d417edb7dcc0dbf7417b308b4953714bfc1b8d46e6a7ac1362edbb2616e1770939e1783c9901638b4b1ab564cd8d62a678f62481200035f4d488138a70a0d6c05d8e9793d1929a73e6e925c526e73b6a69cf9bc7a22e4bfc937d07501ac69101fcebd3e17b523b2cbd12215d590e15cc0cf52d07d0ca0ef22c021ee427e9223629bbb10db41361b88b304b309fcdd5065b3e04d0d0aaabbd3b9603114f06b2fb2516fb863d9df537cbfff629877cb148245982d26f34fbcafc27230a3056911f5ae37df8e59a1be69c176c5ad2db117a3939ce5c1f50e825e405aebd0c94ae094843b68f96e624431119ff5c784ed92265186b58bf1a52988ee633dc031117a15cf0824e54b7c470caa643ea8f9f1908db603d848f3c173a632c1f1398030345e3171c32e591f197bacedc83aa254d0e63e7da2c8d249f77b641acabe5230316158ff6622521a30c368e04d2fe311a8fcf10d1d4cf13e51c57efb4a7cdefea02148211996a347f30b3ccc6da4e93b9394e11136a0dd3c4cbabc4c7217765b3ed022ba217c21e1cdb672b5535b942acf8f9ef56db50070ed431e37a81b9118fe11203f5be2345408304b7499ba19ea9c8a75b3f7bd2b9b1899c8fe7794ff99e16ceb564d5a550ebc924e0bfdf7e65ab913fd8305e3020289beb61deebf41bd58d23cc5c3e933c069b3072b993b4a926a5197163222b262a5921aafbf5420ebb0365ef9a692aefdace19e9009a753e5475d2578487a374cabd0ac79c7866c7ff2522ca1bb523f0a2ef6e07f1a73621b1793901271e799774306da19c5c87d5dc5275c15261b8393490ccfc169ff144b3a369e7944ec3286cec95adab4b6b3eb43f7cc9da79a0f3fd7fba3ba1073dc12256460bdcc0e1ca6760cab4eb200e41d441e34c153d1ac8ef2a728316e92a4970a4bafa74b75589eea6788454187376691f47da33f431d6117e9df78070239a521d478877d627da4edff168ec6d352d45002df3307db2f04ef7376c93235c5d0a2fc1def4f3153e0f97d810f318a8330cb50115a16e03373514913da93810321cf664587d582775131bdae096babbc435510f72aa5f3b4b73ed83d949979b4a2d5aaae78f8fcb4f603c330c9a3cd3d52237181daa2bbe45b711f56f9710b7884517f77482918d2bb2a2bc952e64ece504e425824fd86135a56a225d25997371571126cea94b27fcc15ce8f5b30ab9c1a63201189187ef5ecfefcec21940a4cb59db00da6487356d992b6b9a6dc84500256846bdedad57ef128e485cd323110685b9a7ab92c164558047d54332e1e9d12086424b0f04cc8536598546ae80b5a5d2290e8b7984fbfd83f31ad2e9cddd8eef303261d85cdf8f3efd7ee436a87ae51f7dd3e936f70c11c01c7af3c7b5dc8aaec9f41a5014de23f8e4c1ee272f5f9a0c70b902e2d980ea74d434a34097cdd40ca7b904d6d1275105c4ec41867678e2415736ef21dd81fe6547069c99b241463521bf9c29d89151047cea8cf3a4605d444e44b398cc742827e84d7cd0073ed73808e945beaeb54cf40af55a5d4c5b2c29463c18cbe42248bfca3582727772fa096be69d18b3abafc05bb2a42ae884c945584642c4dceec30c47b82bf9bc58783c2c75c0f44f848456fef540f4584ff1915c4269781e78c54bc4879c4c6b84671e3eeb1ccb3b0acf877fed6e9c98274c95c31eaf9a7467311badcdc78912a80d1d609274f10c5c3d5312060c9a3bd9a177d39f5cebede1e70933a09e1ad415f14e26589b20334cbe7e1aef51c381b75cc2b13981d4355ff52814a606c2ccf44051ca75b4d33e90c4c3956c32fd13316284421efba00f0899632a66b6e05e76d9b63c066964525d24d472e127d9c045b642269ee2742ccc58b3b4c08cece3c25e011d1e05ad3ee36f9269a7b26095446b6d108749ac2e78a9dfb2358a4b61465701371fca37d27e447b92b268c767f8af0c9a0aa684b1a065f810bb3804bb57c0edf98b4cd46bd1036258c444d512958d7613317de5913c947fcfa46f351f0410638b60dd796def760249ab65c63018d8cf14882df240911c341c636e3da6edcf3560a02d7c9fc376c1ef4ca536a0cda22295316eaa5ff09361b62d3f9a69c2bef1f0391f77872b38d30939633d14eaf93bf0d18ec5fd067d7e1409ffc576e864820426f20d0b149afeaeeee05a0e73c251a0fd1f4d641a7ffd179a7840554be247e881a85c22dd0d546b7babf4b78d963dc4216f44946a67b2b34cc871ee56d4c8a0589e941de062cb7d75d614ba90b7219345ca9e00000000000000005f05080500000000f0bb3f7ba71435c8df809d18c163d56796a850e4daaa06ac3ffce690ff8a72f4d568df140aa01a6582d4f05e47e92f610595cc7b4b41277231f05c38a49bb32b02053d8de28f3ff3e1251b01333ebf7fa030d2b1b0178fbc4450a379cd306ff700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ddb18cb6062ac5556bb9c7ecae7fa6c027922ee0918285841f26dd60e79dbadc3e420bdd80623314845e85243c13e8554b279bcbfd577b3d88d69f7bb36ed51a7d8407d0a17b1ccb39b66d253ba556e03516c170e48c1aa0e05a57842bc9e35d5e4980c27ba68899bb53e3a0a95efab1d6669398a355a4fde8cdc69811e54902179f31d6748cc8989b69564eb39d4fae9ae1f6bfab87b5a53d46db2956823e3b02223a624bc9a0beba20fcbe12bd8535a19d37c9b79f56d38a1b9fed0828aab42d0b20669ce1cb9dcd5f5d1416cfbd587a7e25e20930e127527adeb285682d27c47b108ee05ec40e6e45eb337dd022fcf3800cd8b8378ab4f5c5405df89e908ed73b020843f298708e8dd70294d7f1058982097b592a9c42ded73fc36028732292738a032f5366fe0f91696897b7c157e5b827b54fab9090f99bf13a93d30aec4c75bc8903093b5bd3200d012934903599e8aee68935ad80a18d549fe0b0407c9f12792154020728c6d0faa1a01682cd22775dba4de0df1344abaf2f1a26873ebcabd408410d0316064c1340df92c334ed7ebf610b270ad161bc45db7ebc790a29edaf21b1ecaf6267c69676fdad49f95402013e0e5009c24884f1f6f005d51fadbdbf510263f1c10156e4439f93b9e90a3414277c03b2e3ecc8e9a54a5a1358f52138e67af1e718842d340e158f35d0f24b42281415e4bcc27629466cd042b2b4774c0ba7422f2703386b9f2510e98d43df5057d16eaa1c44f6c5e27930b6fb764592dd683e98820db189e6f33f1444b4e947c8062c4d25fd22c6efdb8f86371116470525f2eaba653b9d88c53228cacebc0ae649880185c4ac32667f5354534c572202f7a56d2045410a8551eeafa07d1c71599e382d1984c06b4b8d62eda49c57691d283566176f19e9003f68c717fff61037524d8fb5702b25d20ac36936912b8147a98d1af1dbc87acba9a73bca81571e7e2c38910a0396939ad13d07cb64f8b5782bc0b8e20bf235e1313f820081465ad110c6c314649ee670dbbc7a8ec37aa7a95f30a74d395611ae897a6f973fa9dc559e8a4b3d226a6a5cfb6e46712f74ac58c1a3e16bed926a837c65d104fed90a9ba0111c9efccc9240ab3f2128fde759e309f1ba5f2b5a61289b9887ff31bbd3734ab6932dbb3d01836fc2234cc9afcfe35c4f47f089fa1b3722799765fb2249185b28cfadd4d455cc0a499a1e9ddb5f8c5a80425b05997381870b8d7fb2a6b0fd43933720b376d3d231ef1d7886da2bcb687c0856607b75362c370566365998903c3af0b7cbadc1e6cc418e9bd933d8060dcc6218176d8d670062e4e2d8fdb58b66ca3736f82986c76bafdb03c547cb8e50181499989d6ab1a4051e392341b339f6f7bc7fcc761c9120a31f96748b903f81e3c4820f78bc9fb675c3585bf2e3b9f67d8a4fe06b481111f5d26ef2c26d109d651c00405e19af517237ca2b4bc352ac5fdfd15aac7ffdeb135783336be74f89472f7890f6a62a1c2c330d02873fa21f9c6985f1cc5f48ca8e3fc70736b597cae297d5a3f20ef10c76aa5097660d5ef1db4aac69796fdae893d20eb7339cf812031b7ef3b242dc14156dbde7f07ea8344f56cc2c52fc17a8a46ba71c16eb56363bc036e3cac3e17c9b88dd0cc4f1565b1067974873461d97c60e589e44fb35838f74891aa50b02c2ab6e6fbab875058a4a5c4fbbf8343640a6a6bc1f3df388cc08bd48efe1e563f76b150440bffa00709843d40fb22c1b21d93be41a12e2ae7d239bfd096bffb732d66311e5deb194f04c57d5193aeb117904713d7d820974831fa8245aecb7f7285b7b65ec9815f8e9ed8bf4deb0f2a3e5d50b446518e0769dba83255efb0dfd6c2d3c485bf7c7ab8324cf57d4209af4339b475acbab528739defe4e1cc29c9b4645c2b9f57308bdb0143937f0384cdee7e18cb1b15ece7ec510e3caf492e07bd388ffc877e62b4c9411c367e85b25d555c6881609990c50d10ef701157b2a04c3ff83339862f2b9561a06e9d0cbc7c4cdcbb4ab158193f864893c8a6d4a647ed181697fff55fc5ff79806c5ec08da0e6ec842e4b353bac6eb0eea15a5f415cc03b891e2f85b699e837f51af379168a3df4b91bea9b3e2ec42cdeb68b83a1b99d7e90d8977afeb1ec13011f250a7e93c3382ea3c73c11b7de3957cb867d73a3121b9c482b09a2b412edca246f6ee922fd74cc39716ebdccc416fbd72705b4f19244328961bdf964371582a4263383659a76c99213902b8b68988d96342b05a3a40929d982d260b6bc8cdacbbf5940c17ec2b3252cf54bed6b00627773aff0ebc0143b6884ec5152381bd2c85cd8afa329ec99a105c1234069a6072ad82b254375c103667e5b179d8cbdd8498b9092753497658cb890bde2b97ec074b723874759eafb4a397b1d21e2af2723e06", "5163ac", 1, 905166469, "c8e54310ea27bb773446d007dc49377f04eec8094b83cbde39765c025b7f7018"], - ["981dc2e9042e344695dc6f651cc32ad0b4249feccff073f5cd0ae473a547f4f8e59f302ac103000000010082a6611959e82ebff6a8a0c5a8e14162038dc67a3be96ffdc9ab1feaf657b2feb382a0830100000000ffffffff050cce30507d6f5e7529ec49445cdd917c1dbc5c9c87e4f8a678f43c192350c10000000000ffffffffda1d27bc69b4e065109ab3632ddfa2bcdcf9f12efbf4ad659bd6b4c8653de29d0100000000ffffffff03e4f1a502000000000463ab6552f2eed905000000000451ac65ac27d7c20400000000004cb02484", "ac6a6a65", 3, -1968106151, "91b1be815e98f8d67c5b88a2d23b1ab0907271c867e450c174795a9e6c7f87eb"], - ["01e595fe01d3c0a2c4877033db04ab6bae6d8e291a54e15ffed7fe7390852e7458585e9e60010000000551ac006565e3b79d6901c6879a0100000000016500000000", "", 0, -1003443996, "85a22598c21a0bb31e50726f7802bc542efe3adde91761eb6f0cb748ad85ee76"], - ["eb4f6d8a0442ebbab38afbea3fbb81094ba5b531e7a5c70a011295a7f74f46c35edf88614f02000000025252ffffffff19dbe563eae7ee749df597f559f62ac5d1083cf415d5289a273e29b332d1fe7b03000000016553b0e9fdeaabd5aa93f83bb2c77bec29bb65648976d80e553ac77bdec9451a189598706a030000000463006aacffffffffef525986aa8177e6ac03f9517f733c647be7ac54a22cffe3e2a2b8e11d80faa7000000000951ab65ab52516a5253ffffffff029b4e5a020000000001537e0417050000000002536300000000", "51ac63ac6a5100", 1, -1773057003, "dc4a423be4bb076455dc739dfbb64d576708494cdc13a8316b6e94017ef76c63"], - ["56f490200390740fcffa10a3f5d12d47eae473bdddc98564d2925b44cb3f22153a15c6ac41000000000453ab006a333bdf387bd4ca2ecfb818ea8594acaba1c6512068c191784afa3d8fd2c0c7ff37e1b32f0000000009ab6aab6a526552525223abe04e5343a3f0e200eb332ede0d80b9de2112b40e14c00da6d2943d84772086340932030000000165ffffffff01f8b4c602000000000463ac51530cf2e4d0030000000000000000becfff0200000000fde7fe5059457dc35fca53db46f1fb2993fea794c478b26b2a5270bfd41d6f85bc0e16d98b26154712602f9da6c2be4069fd319d5c15a0464a731a9b5df451e7deb4901f2d645e0b8013e13af87b5b3e9fb23709d768a90ef8f025ba78c104a1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8d8dd6964d0827961ecf8ef7a268c322b867c70654c4d2bdb0c3ad5040cca329c7cde5eab6f1e40642c50d09cea3075c4fc68d5f7a21d9a66886a6973fdae680902b334ef47f1deab203f35b84edab809d4f5c9718ab83dfce79e468e62a3d8176bd89a56dc25783eea78544bc20231a2da97c1d2c55c58edd4231a3a21931021dee03fc5525b26a648114b542950cd14571b55d21bc9b0043422c17c5f6dfc8020a821d7730dfbcf62bf57a3f4b41ba65847e91efddb2db1f1b773c198e4b3d830b1365474ecc286f1efb2be142c43e1ac5787f966369dd4c0d789132690340beb90302002de830ed0a9cf00b110bd2849dd2d5c8cf78ebfcde5eeebd0562c82874030c94ee904c834b15118229c90167ca19bce875c672a200b3e67ccea7113cfb1f020a203bdea9df97fd8faa01198973cfb93607a4ccbdbcfa444e30bfa19af168ef0228c8906b5f1d9287c9e5a93f22b0644a25e005b5fce587c2554370eb6ae70f00031ba01aa00b7790167ee8243dfe419cb4831c23d909fd881c7b08d502854e8fd70209a8769f5e2a411b12726243aa961a5c27cee49408b75a2edeb7e3447b36f5cd515beb78b71126e69f7795d7efa4bc1a9086d61f568f971b891bc780cc82ae87c48ce245456af0c3cdbe9fa45d6f809bb96a65f86c28857ec8a8412e83fd726162ac773c61b1801be55eb7d680cf5ab285d054cc8fa4a53a72e7a0c90d0879ec52667b4de9847b9f647e3722126572e681f8d5bf4d6823bfb980250f940195a10620953baa5ee5830237d4fd66216cced32d614954725dc844475010b6652d339d84b4186a92956b2c03fac21c3778480e721a43628ff3f40a85df5829a80bc25896ee4d13599fc6f6a6b874ea1dfd037d485b9983f6f67db2bad8ffb173ba0b72e759a4f7c5dc7b6d9ffdfeb36d0b1bae3864e5a9b236fd2d6ebe042a9096f2fabe7171d94eee5db582f6695e56224e9bcd96653def8a40caac2af0818c700c3f81812568cc70338823893d7f8d47213ced64228f3370fda512b29020d6562245e034ee248e96443a14ebc49b5305a24785ae78ed1af52abc5318a20c87bf85168f2dd962e8bf9c153cf808c9aa126f0878aed8c4b2fe28a94923a77772e74a2606e56276109aa55a396cd3aceeace59e347c95e19d9169b5d7dca67ce5a14e6726905313a19eaecadd1e3110234bbd74a6ef548ea55c1244e14e5d5cb6ca0db9b5e3a53c5b39e53e14cb0629a4bb046576ffc802e2cb0e92c2d3d16c0f8b262283888d02e89bbe1f7e822bd3dce02f7046b6c846739b20473cf5786e6cfe314f2a36bb9bc31f2217479420844ab1a8c26b8db2c3b62c4fc389f30cde2c2d4dcaf99ff18dd9b5a481c003380b26213cdef27e6983b3016e417cb72b1669a367f299d2818866805268bd17c0c013846d684bae2494cc2b942641de48fd2899c3023b836311da831a1e2804beabd2555c537eddb14c2f695c40ff2ad2599329fe45779ccdb51b9ac344d43ffb0ddc356d4b697e88d6142335f77b8bccedf6e184ccd4007bb35c6eb0980fae29aad201b8031e0fefba1cdf91c66e09056dec76abce6a54eb120899903c09e2e29f0e6cf19cf4ee839ab184dbe6219adb5773923ad39177ddacad5b6c4e4a25a396395188df87f20668e407fab6176cfc055a43dfd29da56151631eb4427969a55db06f6b391933aed02728b947e0e52d17311bc5eaaa32ee53483e050e074e5f56561514260d095f224ecd1872565244bd47712d147b402b69ab9d1c377aa65b358ecdead83c3b9b497df88b2cfa9eec0c15f96d8b0c573d0df03a1621fb616355e06fb75644acfb3812b11e1c04fa7d68b5c3a7b71c3a4a2bb6bdaa074841a115531b893119e03144a57c5cce0ac1184f525e8000aebf9b254366b32fcc170c210d4df0f6b876a75e9dedd54a24fb393b0405e0523983bd62e88bd243605805153aee46a26a7fb5203e2ce904ef2091e3de1d2a9458f1bcde1d49dae99d053a912e7bc5144d17d435eae3e98074727b41df60958e46c8456040cfb90538c50182efb4db807eb0e1d1f90372ed40a69f45f577a4a483a23f433c9dcb5dc573644857dda00f014240d3700445eed2738d26a6cc0fd93e7384e1e61e6358d1d6d922797f65161b9b52ac8e038fd6755acd6b0ca1fa6cf20dad3651e8597b3b2b4dd3bd0474c89b9fcb0e189185ef867bb4282b65546265a33698b50a54ea8d8151d1ecd4a58b028c6c4ea8b8242cd1fee6cc376d7b6e2faa233293c2efa476133577d58b4ef5d2000000000000000011346c030000000014908dc91193ca1a41b7232496889d6460abb1fc390117c26acf36441970113a411bf70b8f7375db9ad8eec64fb7c8f4b51f754940b0065a589e9b8ffe98aa156ebd82ee8c68ef42e486793bc3c744cb910204e655c54d102e59f806dba14db500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f56c22207dee24b72cf6060cda33d4b2ccf6f6a3bd4b0587d123a74d524cbb80d12f5474b5ba38b1e2d95feb4423f72c12949bdf5c72798498c142d2375d74755cf8af12ac8a0461a697305e8d5b133103414cae99a3762b1381cc74044fa6c6068066bd374543936b9f98724decd11fb7cecc622636853cd78cd1b1d5f79c540229e6a25a5f0530e9a61da93c3e3b2254f0962a236e939b3dc03d0898c2d71c81030f0f512ffb857b5e2e939250704b870f6df576f2215463c2737f58109b8f66f70a0568c2e6538b8e9310b62ddf628a242a9e59ada0b3d827d677af9d74ebed1f152bde2d9b70ba864541b28dc39a910a62ac933fa08bcaea3f36f65ae12239444a0307ada2b940131824e1fa980b37e5abe76f5e021369ac971a49c5a96541cc8047031cd760b3ab8d1dfad91b1d3e385761ca16850f8766a6ef49ab081d86b5ac33d002158ba59cf101342223b6c79787786586ee9c237e2fc49bab20276706c4a2fe100317f45668626854856a5bb72c09167def7aa1a2ffec5f21c1c98de1070bc14a86021708eed123648afb661130db518db66eee67b07e8fbae8d74c390a86d0cdcc2a58fda7f35f2d67632cdca4f8074bc7d0813a4d2a0bb131646e1c664a2d5a4ce7ede62cb15180e89ba7d9cf58d5ab261fcf9ddc40a5d08bb23e32a244b62ed9065cd3a276568dc1a9d9dba5135d58ca6d99474130a5e9b3245b1a8c91801b84419800a654a666b2d1660c23afa65a87fc8f7d01db89c063d3cc980541ce66938e7986c25ba4b9c3f8e70fae1c84dcc1a9b47ed5dec411ed2eada62410c6cfbe3c90316726c1e69ee42df49e6a27bea9725b7dc1f4fe45ce58d605f32418c9d31f936fde48d7671e9a343649ff2a7ffdcd1c76b21eae1deb2584b0ade921f8085693732c6af97aeedb2f9e42d08cb8a7f011b7a0ea46682dedad3a286da4264648af4b55a0b9ac8eb9e8330506eec79bf5439d2e70cd2dc5d69ad5eec033eb80e307f845786c7d8add06c58edde06e2bee21bf29917495ba86be989614f5a993386aa28318edd6d7f9d22dda749aecb30cbacb9a23116cee9f80c6ab33e6bf5d89c41c040627a2865e87f38e1a130a2c2ec9c2c9595aaa1d9caa227290acaf7cecaf991eb09ba79d20290b524c6f0115e95420471bbb0502feb0eb8109b59ed8c9a4bb808d16a6ec85afee6f3c664f48e88990ff45e1ae3971165c2f25103184dad0f5afb32d2c4960605a274416d01eca4a0f7e152ded086ae5da135f4fa73f5a606e1d01587c826f1ee17b2cd9da99d0a97b2f769c29d2dab589e73c64126eb01766734287150e4afd3cf1e93134f73a76ae7469963f31bbe556db9f5bc3fe5878e10e8b929ca46b3274e73d1a9dee1935e0c7264e631d213fce4caf27a2b3a951b19102f205319a5b5372429c307d222a7e98e50f41d16cd0dc20c42442c77b170e4a17b70bc765697565a7e4a1ec0724d2a2706905241f6387d21a45fa0f0f8c8bb6888c94c58cf8d64580b773aa465416c191235a4a3d018acc476c7de545b2a1ba161a81dfa619fcf256aa26482a923b2a4de3d287949b083f51d477b675e860a05951817dc3ae5c69466d2699d8dca407e02edc5594b72476d1c5ddcde8172a2d81845aaa885cce38fe02ca819440c92008ca401cd4815a33f60c781e6b393e978020c45242e286ac7ce098ccf453dfc96f415422cc55b8a1a07c90d7a1785d8142b5034ef65b3483a6a685d5b9a6795a9ac818f4e096764690e5a72549d017c85aefd8145a5c913da464646e94d968df0346beb8a5673f0f65e8c7e4fff8e6b4a82105fc8a116b0bd5ef2d8fa6e52a36624dd2b660b38fa3e4a643567c712f54a8d54cc7bc3f9091d2ed80d26a6008b925c83714298807bd005f734ac70e7799554a4537b14b0bbeab7f315b6a987904268b9f8e49029a49159f962f224787f7d0b2b55068632cab87c5608be4d30833a4aa4e9d97bba01b0f5bd71921411da55e624ff63b584ce1288be09a133c11e19c850bb86eccc40d8d7827c770ebd085f846f2736a988e0bb73ee61b8eaccff6d75aeccd95604d0892977e48c979df3e8521ef75d6dda7eede990b226141a652ca671324c89ac7f849482c2cfd5390443cb1d97e673e2eadbfb4ef13f2b52dc1fe8461b8108f6984847136f3745e6f892bcd8f8202ab356f646f96857ab99bb58a2c7587f7c29d5cfac430db5e14e9dfc91f116d8ec0c4d8ee4c9f37cb5cebddd99fec19c94c3e30f718818cc088344c5ac155c6504c2c25242ec9ffa9f0fd0000000000000000c5003d00000000004c2016a7f51853d1b86445a20c969d2f58927b8adedb8a1ce08bb6af9765876869dfb7eed75e4f713a2ff7db77ebc7db333f20f10220a38817b043ef2a20f54c1f2949db43d58800326fd49618c51409e711c57848e4ed48d281788bee51d85d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aea369f9d3ee43c36b1b7c19ab5ed33f7786197816d965fe3f765bcb167d5a341014c6e5e08bd1a8fd117eafacb47e9127a817fbdf2c61fbcbb043daa1ea15e64d9c4137f5fdb3e71e9c04b9703b832d5bdc9dcc62fa7b490862410fb1fdf2a56422bc2c5ccf959177e61a63559c681651852a9da432230e9075e23036bedbd030b1fc4d3cbff010b09a83168ee0c2f0cc3f5acb6cc47c4ffca63894e5a0565f7030003eb2cab583295258aaee7f18f3d5a77e2d6e28b04243791999abfd93366060a0d38426eaf1206da109726f2711b0ef4325f06c5ffa522c4ad425b8a57da593d1e9d5875b605b073b6a91f1e2ec23cef6992d0f1295e30f8c882b0a9afa9cf84022ccf8a305c7b1f1c34474eed90aedfb4e0af27c959cef2b3b3aff2313890477e03115146e9ed3bfbeb1d3d2c2adeac5748360c8809f932d814343de8eae45d797002021108e7e305cf8379c68f97e302fa67fccd7f60810d2cf2a0cffe352d71e987022d3357c9c310e4267a5916720fe88143a77eb2253a6a2e3e9519aae58ebc3a82030afc897012656adb51b82973ef40d72d0c6e44ce062614bd99e0da13f30512319fe2d01ab12b5e3071f0eaa495cb0eeb1a76016ad6f0c20731f88f20fa7ec39c5329d2b94d353a05bfde4a1c5de3c2ccf1f69ee9fb6ab13221a8e61f476f2c8fb88f8c382abea56956d3450ef907bb15e33d3df72c924c64701d534fa4c0f80d70a513b15c48f8c8b2ebe07038f499390b21e792b8d417b5e35d42755972bab028a37f97d591f791a50addfe32f87aa2e4d61ce494528efa917b2f1e8bde697ac42744614a3fd70e262a19d3391f7cc7fab8bb20d7aa179e5c7db9962313ec1a0bcd06a5976f7ba7716d89c2411d4e1203aae3365db161d0cb815800ab71d289998317a41ea3ff398d21eeeb692bc1cb7d33358c879522de429aefa7654949b494ffed282c9bc39d51611d22f7534365a8dd35561abbb527dad82157e2a059f22a82cdecca60b13a96b1700e94f7d4cd6a61770bdccf027a35876d56f8a8b19dd1caf702be5d720ef81b4fde82faa8e99e1a08000ce09e3a7425592f7743584f7fc9ae1838124c74cf93c91cedf1a6b002fd9cdc1e1dc2afb6c54ec27528f76ef7696834ba89f8de2c7e212babe3a8c54f1f3c6b9b8b2f8715a3713868addf6d8d1b5dc0c0b268aa79745df51fde9f94e0e37651377d056714097e206f483791bab60c06359124c9338be136bcd2912b2b89457bd0d07780ba8b81ed7165f398811a1fe891468f5a3e76224250739efd6f26c390a1329b3aad806f7a21d829d34172cac31ceec198f249792779a5c69bf23f4a9bb8895fe6a8237d03905142938ab0f33c9fbb926db4850c4a96274ac49a79aeb42d35f9267aa96120519ce985252656ea5b1a2ef46677b2de59822f982810d31a8a01f3e66e422979a126443e88c0afa36aaff9ab065cd1c23505e4d5ce0cc4fbcf8eafc3d959ec0f4d6cebd47d3e662f5b17eb4c769844fe76441885ed3087caaa768a8e6ba4506b0446417dbebbc6ee1bec161ba819488921c47fc77042644968d6d1c9713061920c092cddf88c357e5571d5720cfac10c5ca921b68d596e8edb6ed07454ea1aeed8495eadc87a1e294265217df1321396b4147f4c521ebc4a5b887d9a7e7c71d57b284662c6d2c2c4c0aac96da4dc0de2d90cc88940be2f648210551f201b57e5bff8f9e41c82bdf5175b2a39beb6c0ca9aaca6735df9dd28b75a1bdf8b4e49d38b35858a5b165810ccacbf4344f6316f52442f5f1f7fb913c7683723e75929edb1cc72b496a6e29aaa0f998005714222e31ffee0da57715097d15b4f0be78d7e92e39c9dbeb908b3599d39c0c71692ed03915503d507a16c7ed8ff6dd7f4c1fe5b6b9929f99862e6bc1861d5ffda10fae7f4abaff08efd89f60cd7d26e317adbfb218556124b129281a39e097b3413471d669ff6198c7e3922502dd9b894b2b4571a8abb3387994204f3f231f333dd25e254d8f0f4ed09399b56519ecdc4d3489c5b61352b6dc2dd52bac7f8784521b398a2dacd0905d47eb80d632216123d259a8266cfabf07f84806c66ae2506b842620f437374a4d3207ab37912ab1a451758e04431ad96b1c0003e658e303b3aac11a30eb32e4052591f61c01487c2ec9f0e9099f1cb33d685b37cf89115eef563e7719e4c7245fbe50055fadeb1a6cdc4475f865c0a6b45137e39c05e82c24d2762e78164f401d39cbeabac1c0d0d14fdb1960dbb10602abe70d6ed1ed0f4adad1705a469f0a448132cc9b01a40f02154abf7b96bd017da845a12b910ef7d47ee496cb99958b384a46c257fff70337caa110b547e6b17ae133559cb3347c774f392b0565a8aa2be662ade6e3b869a248d0a6f2a5f6c4f170188d3bc762618392f012b3aca350c", "", 1, 1987178934, "f7add204e6f9230a4d1e720c8d3b98c58c543e501a1f72f2639ec9ca4e5d3031"], - ["962e1312036d1d23047fac3265917059a56ff70cb37c60070a520ef5ca0b2bc57b401118b7030000000851ab52005363000000c5bd8c7b98762ce634ab24822598a9563a5b93d2dac75860153694baee4eeaf0da7ae40000000004515265acebedd6a5fd38430c916b7794791751d0de2b0f6389bb8873c799d7dc02e2bfb44dc52de70100000003ab53abffffffff026e31c2000000000009ab6a6a5252516551ac75024404000000000093d812a00334dbb001000000000000000000000000ade09504489b7965f6c5fb81ae87a155b76e3c025cd0fec1f063741fe6536be8f824e747d0998f9af99246dd7814ccbd7df6ea6767c516f31b1d6e6f2149f1f34d542ba609c5e0d4c8da3b4e4c1262e6086b764d3a86989bec7877f646de007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000606ec1c2dba4804b42e1178ed374a20168afd5ce9ce90de306302326d899a0a509416d9138e619a6da46bf3e8c564898da492124aa84cf60f25036296e7db55c097499acd982325bd60a80aabcbf85407979a404e066adec57ee8cb226eb2af98a088caea941a64d57ac9d0ab962060e39b3c4138f2baf35f8f3496a822ba8c1031973df3dfa9c70f91d5a9e82f67bc907ecfd3757714062a8345a5878307347770210de995d4bc91aef8efb2e35a8f348dc3417712c7d333ceefa70659eacdde7e10a2e6e95781aba2b6d6a33c2bb6da0a9d1662d58dd54e0cda3f73a53a58223655622859948ae0138982e5d74e4dc2705b05a165eb1e548ecbcb973893b1085423a031b6b838249a84edf7f12627ef9654b920e00ae8fe6bf035607696dec14f88fc8022b8f72c842322914cf4752c8f5cef86609fa1488a862e857b719321d197411200219078e526261e75eb176c54720afe86aaed49f548faeba6029dadcf3f7dc5224032ca7f4272a18c7ec282e1b62c6063e8cb2f0407173f7460e769c18842c2974c9032281b388bbbf812ce7bc239132e21f80410b67d86cf5c381eb90443ab0ce631b78ee61c21f9cc1e86bf341602bf76127fc62d32bff3a111d38cd156806f25aaa7e2d6ed2330364469fc2dae0793b88ed3d774d0c413e2de455333f9997e2316441413e734f870b8f44460161c33b7e5c2e32d3fd7adea0e0a896167f9fe5cc94acc5d180c05e6e98742f3682b27819d042d7e2b6c1b11d85ab437e419e860aa7672e7728ff84eed0e9b66d2de6f33d575e8e2f406ffa6a1bdc4342da13e2b3ab092d96d26489116d50f86ccf6152315a1b32f23281ffb0185c676e6c6be6d241d3b8d4d9957184c9f1c145eb03b3f283e7471328c39755f5e00bbbd032d8f1cccfd1e90cd794421a95aa1d95813ead916d31c4aedb67c073ca488ff7d02a5d91adb185649de39ebd2a63658255d7308a0c2ba1e707d94a2c5aef7efe1e150be9c54d5e00510b53dd9ff70c0fe07c524f3b3a3b56ac3bcc8873ac21da1cd830c725917e21f71191335131552656765afaf7bfc82d818496853de7909752e8f17a33f133fd8b1cb1666830c3aa46bb22630efdb84a2b41f09ebed1f721578177274d92703bcfc2950364025e535c8c7b083e98276a05e0f482270b439be3dd44f0e51abd28162ced2f612ce130ac22896ae415e37aa32ef7bc4877efa05dfe87529d8495f987b66cc6f7e37de30a303c42fb524ef02940e244e1b055b6e73d5abd993baa92166f0a1a67e07c4b78ff4a483c73b8657c2b08480d1177dbbb48762f57612e7a5b18ff12a678f90b2abe1348d365f8fde1efcf2154885043d4a01fbe4dc1e6041801d6479b00efd711b64aba178cb8255009a54329ffcb4e14f0ad7a4f5431e4737bc3f86c6001b2dbce0bca671cc04b2c57ecc835bc8ba373afc2c88f6b7f69fe601c2262d2e6a269ca4caf1dfc77a5c470d4307ebe0bda45ce8c5f0ed69910122ac37b3fdefa48de9511518ec9bc09f872ca313810aa68d576e524deac20108911cd1b21bed01081a39953356639c8d9523472d678b51239614950f6ad1c6e87da3ebef9ff030cd35827ba59486123823063df4840171d0c6535f956f2a54600346619dd9bea3da2e1a449e262b64da4178a53537ffd0e46e29bb86d9d25e5913f1d4203f321d0338f824a07135ae44970f7dbb61083ca3dc02524e05b1909a8a2b7e3b687f5d931884e25b63254c411e38beed2fbc344a037e2823450dfe2d5da596b68094114f695372e3a0635b29276d8b0bf5bee3d90ab76de1fc31327ab0982fdf5aeee341759fd1ee14de5ffe814c103a5a202583da56fcc07ea1e5c295e75dc9bf2c87d0ddd8ae24ed046bcd1ac0219a650f2753cc394569ea61967bafeba3980ca5cf72d11ca2927f69ad708d5edb093522bd57d17e0e6a8574082b94afc818e11c8bbbd72579c1700c1f25a5924e05e12dbc9e5f6cb37c6814190c113ac668af2bc7d9a0a28de5682f0c9831ec0cfd2238577f30d77c528e354242a1e4ba91334db0be9e0e1c562331feffbb0fbfddd298b976180c6df77f854260a87ea88a92e9dc860bd8440e0f92221167a9d18801d16c4451de7c2f78b0c546abbd8e8fa632f16bb0f5dd7c4abaf296c9398a90de8a5a9f67ee45e4f97cdb760ca7f5c90334f5171830e0bbd952bc37c7bd7f3228d02f6e5c922c44910bf97c72b050043f60f762f62da1a7c65210b95f5ca4bd90667de10ac9c5e0848a1f5afa094df1abbeef9a5254b348d95000000000000000051e0ce01000000002cb97ba23882ea8144d87fed19eeb2feb7bf61628c7091a03b7e3fe01c4c4ab97d94326dced2d938c54483e8b9670df6e9fe47adc6ca46b6cd2a5ba9d0f13e53a8c309319bf6c8aed7e4bc30cd2f18ef5de971579ca12eea854385425d59491c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e0ec680f9783080a4949c33aebb683f4ad4b2084ccf5d68cca49d7742288a925601bb948e72fb87c0a7500faf07f0b88591cce7ec0df7ef55bb0608713506847cf26a51b3d3ff4eab4a4f6966de2686b6f17041f46503ebb41dd7ff13e6475fa09fdf06241926253e29ae01e7f8916e638804080c1d87be644b0d88c48fd036030d04877befb470ace2ef0a477eac5abc62f3ff6c409cdb570e84e9b9940b73440313aca4c8c181c43f98cedcbf6651158305cd6be12633bb3a58c116b150fbc3410b136aac9b79d40bd305cae0057cfabf45deb793649909929b11a719caf617fe99302948d2688bfcf2d21d41f800ab43b9b70798707756b9441f2853ea203ff64b03119258a2243d7b0823c22110230f3997c5be50b52dfb7d33a6cfeaf8a172f89202179bbb16bc1d531601456687e939e1f254eb31621a28606e1b8a4494f551953202292e616d69fc91e4f60419df665f30090bcd8d5ceeb75d6ececa143f5696298f032ae6b91f062471bea9c0255abb0a4a3300f5d53961c9f4954940096bc0cb060d0305236b877b74e5dd944d82771af95d45d8f5792620614bf9991589e7dae69f440cfdd126c16e60d840ed2c75ee6d406df9e3868d83a61ba33d2bbc88533c33edd1df47941fdfac19d775e10cdf692744b19a312fe73323cf27f961b21432d727ea9ebd4e6a6b858bc380aed293e930b3942832200b68b0a08c1abcf8ddeee816380b6d24e5cafda1999669a8617bafc48eb155d1dd3c8104be7ebdd87099ac529ebb7667f3cff6e824908463eb59c01fc3212340fcda28789e40cd6c78a366b257c1a605edc4b65cfc158ccb7426f0d7954485b10ba3acb5ed3bdcccb201723bc173ed5faa1a4f09f18fd17a37ab230e152eaa7b6e40f0fad889a72f0817ee7376c24f820f9c0a7c779a2ff138cab82f2d6bc04b037dd2c45f5f22349689a74d8710f68bd90ee42734f082dedb8bb6391c85eebd4df9bd8904e85e64735e435d54e693d3e16940abb8c45e942308edeb4e623ab38e4e328ffb9d211028c461e3354ce4a13f2d77b87a786b54ca3166ed868e00aac36146e9d04344ee17f5de048d7467da3b6e223f57e5b0b7be3e64fe412cbc36df59c7189403dffd39027260a5287df6b1313492a504531ddde22b5f009308f802774a6182d767e5cc275b74ed607c7e37a8d1976ee4ff780af2ab0d93c9fac6d0a3fea13b5026ad18f23b6f3fafb39d120c6dcb005eb598fa369e20dabe5a892666352c4a184cf36618a41882eef4752cd73a148fd7858a3a5e6829b563e2271b75dec2df4e3d16eb6bed5280dffc9dd0d67301588ea2424d60fbc1850413a276d09cca0ab32da2ee542bbbb2a6ec71a5770ff80d05a4221d5ace9a41af9affb255e791db4fa0719d08aed5da1301a32070d1bdac2ef4ec9af291d0166df97f60bb2f0a569dcd4e7c907c3087723c49c2c82d74140a445e35aece76d396866a3d6a24f6a63efa0295107e5d212e5cbea78dd1124ab0fa6b15084edb2dc8274d7548a6f7ebe238cf3468b7a5be57e35b96101c9502143879b737cfe19d511cd50706388936a6da60f83de534dab033ce31a42f4d35b9261197ea16fad312c7ae26e4aa2617ea31845a9c00d99a3822d616ad3d14c7d82b2a30d7ec0c4366e88333c348e832335609516db080303c886765f10eb35862e70545d66b57256e432d8255b1d80bdde73420372f1746e2567384374235cf17a33babddaea4e2754b5f440d16b8a87e35f09e88c77e20ad8415e317d5c7dfb16f1c90c4d26ed31e2f57ef57351c966fd7046360b79a54fa028d16ad51135d1c6bf49f815e03779e64fd4476a747183e68e46a4ece5115295727882b18524e9bb6e0cffd1ff7a859b5a069c60c155aac7f35deb636c1fb7890e897859c3d41c0430f680857d33f28072f5ce87fa3bf9e852cf4aef5d589e293f913d960b0deecc6d163dd3159e809d60b723f94c1db2ffe23171fd78da5c74a55b192d89cbf23ef543732c1ce8f9f7fe4d4a787b86beeae55e418fc4bcf886ababaa5529372c6d96980a3c59fa0494c83362f9ed5e84db38b65ad49fd4d867eb372bfc039dd43789947be540287f42d5ddbf002543afbe985bbf721e13a4d107eebae67267f443dcf47883f02e3a2b8f7189e303ad8046b8a13e9cca3402d96ae414a88aec97f3b9bd5b153a3e133cbdfbb9b80d7e1c38f76a18d6c1dea754d31f34e81b4b290fb610e475378a384c7f4194cb20c76364346cbd2d7346609faa44d4283a172474de2921a4ca28dd9878506000000000000000000000000003d3931e72c3bfa1c10b1be6db6b35e708e8317247c8e0e2148986010e6f1ba14acf7a86d684630f34a2cbe7e88b9b96fccd22e26f913db02368d89efd85fed4be26c188dbf485c62866fb1873424ba217682ec30b88c8fe2af29d2c2cffc77cc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067f1231f071b8c71ebc6887501d749e3d16f20ad33a980676f80ac33a582e9d0cee51e50b61e5df5ddd6231a93b1c47932fb79e80f727150b269dc36b4004b068587ed9ed7e3d649a009988fc707abd32754b32b25ae4592fb58706c78e1ca444d66e37c67e31dd486827044bac821a9fb23d1da4ee09581977f71fe67d398f9030908fc017fe5a8ff5e5fda0cbf7ece450051bdafcb8f1181e57080500cd6aac1020c748e5e2e8e1b7415f0a5e3c2f08a11442fb89848479bfca0704d72274cf0d30a08b6fe5914020bfe9b79a578ba517846a121eafb93322dbfc0f01dabe765e9261ce497e22f50e1095d64fbfe9b388709c530ae5f5f236a94cb35ddfb510ad1e20300a64c286577ba911b5f57af8844ea8606f03bb5f54a6c2dd02021d227a224030321ff811b329136ea47beb76c6d7e1d3370aa9ef2ce34e2cbe57f8b29d3c6b21c02202b3d69170a73bf81b5182692087a453b8fa9284ef3d45d13559b19f38eeb730303bf248b818c6cc2c0b213a7722cc1fdae51ab1e5c4f40f8eaff83641765cbfb03220cd2381724d691080355dd5bab5b44f8d92ec8c2dee3b2cd08ef1a1efaca730ffbcddb2fa617f6b8a70ca880c043f8bc201036e62aaf8cae2a4585e642c94858b2489c0c00f130ca3e9722426673dd6585904147b5e01c9232f09ddbd30b03f8ce8e62d67e704ef38dc1765965062d20bec4bd275f114495cb56be34dcfcb2b4b88912c48a75cec809a80e193216ca55474e7366ad164bd10316083db06a31c122b761136fba55088564c4370cdc942950f00c15fcff92ee161f2d7ed124a6d0da9b8bee8967f4c154f97888d8169ddc8fd83e724dfcd43256048bffec189e6a91bc13d70ca3da0caba5a17dc1aafd85f562e295da6c576ec0563c412321459e1b011a4e712dea677deb4e1174ee701508de5bb5a913d1384f0cc03dba444f9b628d30616c55e2360a17bbb67d10dac320d5a21c76803371f5ccb8adafd6df2174ffc2ba3027d5bf61df44290eba87aae491f4e342ca598190dfba55440fe4b0dc9bdb298f7e8c2ac815d542b6b8a632dd4c6c76a3a90637acd95274e0d73db0faee820a97c14eb9e37b5fb13328fdf7309c9a5c33380f1c9bffa1d77334c5001421a20a5775d92ac5db531dcb3ed22dc2e2b7b0607d40295b7177e95cdc50694cb0cade2d31397e3680f3ab765454a01a073050c550a0a8083686d531535839ef88a5e4191b34f3af3bc48502ef6c6a5fe76bc3fb99e322d2f09e9d57d35064f075be1f74463f5ec230d8f6149044310d1544039ec0fd6666f36a48a0f6fabeb8fa3a4eac7d950446a1516c64137d81c8a1b10d478d2f555b3946d4dbe5032d940ddf57df8c0e335d9466ad68f639b7178b3f1748f6c6a0837b1a68d80a41820440cf552d59d0ad757014fc5e43f142f7bced1e0239cc70436a6424b49c1ede32971872c326a661d27c44ada164b4dae44b3ee6dc2ded2b1f2c843c8e2bab510f9eb8e050f4811f9be1e8fc8685f2d7f6cbf83ecf1a4db9414ff614f584f36a6742e3a16651b45fb711af84441dd76c308467502846eb1a4e313ca1c97dd3761e434ebb8c899b98baab83fd14c4fc45b134f2daf5aee3344c32b94f4ce6a8c21b1d1dc86ab03b13fcf08cf70d64241b0a94fbb3aace31f67f4f937427afbd18967f04065a938bd5b6ba8caa8dd73977d0c9a308a46234f3ca51877621525a6fffb44c510a3f4ccfe51d9a09e3f1573ef5b09ff98689100d6b9741ee82bb4c7da3f5db3734c23f884f9f3522cffd9dd490abd86f8386066bf3aca91541422e81a8937e6b2ed0c1d389e24a433e44c130f125f22c44366f78a9eacb51690ddd566b4621cee8b3509dd8344b80601f507cc7831da803d7e06d40353104dd50b65f7b9a85ced4e4cb9f01323af9054e26d4494ad828e2f3aa2d588229e9c1704fdc8e3da12bc28bb0a5715ee17342e21ba63eb0dad83b9d61644f985bbd7df578eb5906e6a32f02bbe081b8d4800b3bbe3544fe0558d076a90efba46f15f45199f2a091cbf03bd57dd49c69a21476652b6ea20a54974d64f46633dbec9d406b9fc2b13460deb4d30ee8e426efe663bb21c76ed2439c54b115476889febc3be297d6ae6ce526585964945cc223d8b421625b499f995b4b218f696e7a72c2b97b561f70e94e60a2c802680ed56180aad956d89dd95cf93934a55a4a7fc56261d4eddefd7c46e061bedadad576146171ec50040d770be04a8733c98659ed6b57166ec0823cab31838cc77708b97646d3a5916550b46a6326961336ce48c489842a254f2a4375a69d22ccd53fe9ff7ff887fd9762ec6b208b8c8487ae84730a48c6b906aed971416fb40960698b1b3f618592b598c56ed353fa92092a627ce7f8eb43bd3ba8dae41af682cae4611ebd9c3b074307", "635153526a", 2, -1612124312, "c59cda5d0c13d7c2d43709c6ca3d8e559fd2622396317781441eddf4d7c7fc28"], - ["1f6475c9049b26acc3676816dd3aaa647ff904c54533a8103ff528ff1dca017865f64295f50300000007ab636353526352ffffffffab544ad4326bb45f2cda1afd6900492b0fdc1f8c5e28196fafe5e652f5c424bf03000000008767a3d33fb3dfecf70860c0a1c060a78ec22047f85043a23df2b9f85a294d0e12b42a480300000007ababab65006a6affffffffad3ad4a67e9da5cf09c9f6277a79c5beb9c994dca91c6d11a2ee5ac537a27aad0000000008636a6aab6a53536ac212057603377e3c0300000000065251006563ac705bc603000000000365ab63467131020000000008515153516300655100000000", "53ac5100ac", 2, 1025636861, "0ce4ad3390de1442c6b75dca298a3a5999093629a22198065694e913ae7102ac"], - ["c94f421b01cd130cbc590d508a01840f938d221e8a206232201671bbeb2322d95e86329a370000000009516565515100abab51dfb9d9f00328f9f90000000000026aacf5b41f030000000005acab005363f9ac260100000000036a5253acecf299014974bf010000000000000000000000002ac31ebe3e9886310fcc1b3b34441cac1f4a1cea46fc3fd996c6b63d4096a15f087dc6b200b94d46310d8e3663075c73f7f3d40a2cb9bb74fa68031299d919d6c04f659902443e17bb18f1157ade0349960fa91383609ef8a61a36770cf865ac00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b42769baf0fe750e1e74527ca0b7349d81cb9521b3aee1942f32b4a0c763f7512115e32ef377d0d421fd6d0026ae9f568e9a27e6da38f079baf1f59f0ef84f95f3d35f40013c94602873ede859e324a856273d4501e5481fd9f11906e26fde7e43763508c32bbb6d08a1a4f703059f0f68e8faed927cf5eebe485065aef1e511032f3395523cac35d43b1b0e869a026d972b68d6cdbaef1a5433c4c7fe5af83f580312fb4a868af8efcc4a1bd55c3bc071a2ba6c40d81d8572c48e9209b94494bee60a0f44837fe10167e746773393218e6795103b1bac7d774849ff4f3455e9fa13b603c942e3e2028388052c08f7dcab7901c8e22f11c1e729646b34d4a7cc36d67f02002c4a7902198dd796621c1712f7ad1b718533fd9a55b540f90f19783e9b9fe602128ac1d87e2985589f060fcfe31548db979ee1fa4e0c7673e1bfc7a11b152559032552cdf68e5391e91e467b35b07ddfbd88d72b3442e56eeb7be23fd7be3aa6ca0330639194317c3f9e628820185593ef004f49359b4ec0e1b8fe54fbdd5ddc6ab50223da9185f89eadf8935bd830adedd7b9436163c6d8999f385a0f831c10ed61850aa1dc91fba1c3a7279f09523ea4f28406b21ee7243bb2f7f4141f09bdc639d18aa472f4251ab4893e89dfd9e265a9ac29a751f15fee540f4702f558c151493aed1e8b7f82e47c808978b67ace721b73a4a23291dcdb8e45072d8c7c747b797c4661928324de4ed972a63fcce893b367fdcfb2179b861e5d79330fd57ae13071d57b0d8de7499a234f5af8a453ae4082cd32b6faef6ca7e8683e936fa39fdf34b37d06a775c5f1fbd5c9638d4bbfeeebb586fb5edb73aeb1c2fe51e53424c2f28e089294cee1dfba9c201dcf08874a97bd5085898bf341bf94c479a7e45a8ae86a2b982809e23e4abf96ca5be7776da77126905a9fcae7ffeb0fef10d6a071c245c2c6f83095d5f9af76aebfa339954a32fb3caca1bf45f4b9b7414c85771ed7501c0b7eb94cf9d86f27d5560be3486f17b6fa38c1447f286319a9ade7b294ca744859fa8220a7419f72fef564f52f09012d932934e1a7af66fc1d93ca2ae692c4ef6ae83d1ff0c5e567177f823822391df780ebe024f822e09d749fa3b6107d4922e32399822f0663a684a78c22f75efe0c0bceec6a1429fc134f166ea605338a3f71170b8e5949a5b8269a0381b7b76c9b96e2d4e328089b619f43ae2ebafddc43905677a11c75f80416aa81f4a934ce69f9e680d62122434417b487b3122eac284885e38c07ac6b806a68f817d4a0bd5e9171ab0097f18e7353cdf7722da22f9bf55f50bc9aaacc9b82d21cdb58b1fc5a37a9a448d569639dc33b9645aeb435c74e89bcc11a845c7be147dd48f24ea99a9ad8a521969e6e76663f35325b01a38c79d074597974f91347b4b0758781f68095150be89f30ded30d6eeca4ca61e473e557eab5e9449a3114a1a73034bc6db374be65110d07fc63cbbf83a1fb88b686c67ca6d450b41073b252307cbc88c84654fe7d501a727339d1785bf631dc4452b2ed5b0d40f18b146b5e1126babc811e4b41b7c5440795985d9bc8f9f87d5b4f3d80fdee38bbb45c5c06886600bd2699d5315d7525c77ae10ea28351d5895e9a1653d3b09eda70a9b1f25ba7ca0b948c90c75e996b7ffa13b8d6b4c3324adba89b81191a50ae045352e5f5a1a18cfe3e7e1ff5767b327c5f69f60a19b5f0fac21c89641f06c0f0a02e035ba77ff3e809f09dc00be454be86ca265fe6d6d8fee72ae731e9dcc5a58f45f90cd2af88593df2dbcec6dd652fc526cee2b1babda8848aa102ae0ed1db1019451dabbf825e6b5674d84fb9094bef2a5ce201866f54cfa038675d85efd1c3ea689cbfcddf2fc317dffdbdc31edeaeec2d628e585447590d2092305ee0c9a4a6869eeffb950ecdd636d2f518d6ca5af6b182a0625b4769d9a1bb98456a907fa966694f5eae28a478d5de8eccbad07439a4a16bd7e78ef36a9e19a1d1fb64564fecf2baef045bc67c8f1886ebc6d5d3c41ec331b701eeae7e1b9c8adb67ea50e54cfd19e1959f4c7c866920805d9bfe87c58e65b9303ddc34a5104a3ae49bbc923db7e9ed9024eac561f95e635e4ef5e98ea8ea71eec9085368bba488fb127631d6185147abbce28cea705958e36db3373af693d0365866fdec9ef546a3c47e21ff3bda99b695b84273768aa846e7d9c9d662d95ea8a2f5a55c0ec11a1b6dcd0a4539fc588a350a26d15c0e6109d7da3b197c1c0a3141e8ac9d71b0d6753edb7842aa718c035b68efb6c8480dc3a6431b72f936f9ee867255a2c60837d4c83e8fe1b888b99c9b9e220b9d56ba7cfde69e4d9c3f47e396fb1151f3714c0ca05f74f4a1ea0664c11ca9e255f67ee310b2ebcc48e3d7dd7ed2ab7d088810b141ea453408febfe7930b", "656a53", 0, 107611704, "a2deb721b45673d45ed38da59a17a1e839b2ba6a243a8064616bef2edb1618a5"], - ["a9f3a5510467fb857674a3f5c1f832394f6b14ecb0f33e13fb47e1a295a66bca126730740f03000000075300656300656affffffff17166f3f106590a22577002fab710751357ec61fe2e75433255670162f1b5a6b02000000095300ab5353ab525153654c913e7d8bf21efab8dd424396ebfeb1004865d445b0ae1d836efceecb90497a81330600000000026a53739d27878853a44a4bbbd07ed256907d959f8e19a89972dc03075d2ba3507c5510bfd38c0200000001630b2f8a1e03ec5e2d0500000000096a0053006a6565ac516978c000000000000263ab9035ae010000000009acab53ababab6a52520000000003000000000000000076dcfa02000000000e884a785d7268409dd4d48b9152a462c7c4d9824e3a7c6d972ef541467c24372f3cf5e5d8df9473b660fe0dc22ab438559d3c200c8980ae018ea2b893ed5f90855469624e8936ff5a35eb302dee30f28cf2ed2cbd17bf8cc20c55a78904b9520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020becf193bfb20b6b4fcaaad1dae0847e1e76d134fb6d8c28f3115f25d01b03437ddafbe526a8ca9f02f97ea11b3cc85e7cd8c4aed6fd1ed04c6efc890b77c5c4f1ebb6a22f224715c56e7fa1a976388ce0bb16fb86c649f0ae174982087a7447e0b97bc6dbdd88e42f8c364cbe0c1e4b8ada265d186ac0ab956cefc290d3a63031254ac12a47714bd2b8ca2484833858a5ec60007344a09e86591970d20f57060030539e3442d7f742c706d368bb1b1e3b566c0dae1d490e15dc04444359503d0d40a2fc8c23821c5a65bc5a230a1fab25b43e57fae7db16cadc82bd7661dc820dc711de1d4b0371f2fd92dc7a7723b6873c6e5964de2d0a20c43ad8844772ee460880201092a8de45afa52317bb9ed27d63e3634d86f1b3c6dfb79c4621dfd2f31f2fb0200efa867a6ebc27cd972f2bcf19431332df0c5fb4251783e7088e57966f2379303059c7eba743fd6effa0a1cd658265b26eb18c658f357511c4df30e0cccd8f97f020426e9f7a2e02825cac9fa771e253bc1481ea6cee0f9e4ca3ab4b75dfa1d6bc8022346a5660025363af68801db5caf06550c58aac6ad180d66ab0d32891478e8d01acf3593530cfb26579267afff040b0534f655c00d150e8073c7d6c46acfab84fc77a7a640a75ab680d769974d12c854f1e9440d01e31e537334817c64657da90b4a1d8f9a1707d4e1a6e7c54b2cf5505f48a7b10f27552c41b2b865cb0a362fe3fada94f8a037bde6e12f9e91b7ada4ea1616b612d6a76bd402300362677d011465ad63569e66350458d822ea0105546de26817bb7b5fc5f9104c23affae4b40209a5ff986f2892d138abbe9b2138e5edd4937609cc084d7628258a7d042a182fcba317abf91f562dcb1286abdbd851b435b40d3dfaefc055ea0bad69add1c4d8f37bd70cd1cc02c3122e2c49f487f1e8f4800d7ea677c2afaca05a3caba6686dd857be2f2d410836afb01ad7e65b51cf372cedb320cb1f3fbe06f4ddb154393b98d2fa5b6e5d7d7b5c6ed432c2aa3629b85a0dec5c849b580a984df9120af3f94bf3ee6077875d5c64cf6ced1d40458a329b6e929bded890418a2ba12b0144a6af86b967181ce0f5f468032f9b3bae4ec37673792cebfc2dc7b2e4ae364b5055f9b331468951cc2dcca5bc0cbfdcbc9c373abec2c2a92d81c902a15b8c397b91d5dd12bf2a003239fd00b393f929da0f431314cf654ed589b3cba7d1228b5a9b62d7c3170b7da62d45f86191885969fd6356f890690c8e9747c7e7c79873197934f7bdd699dd27c35aefeae27f717f222c6d1d7e3cdadbcd7e380334d60ca55a185a108e9105a61e154506a3be44c16e57d8719e04aa4fd01ea58e7135e87ed08efeaa48f64c7e2044674578d149cf7f36926e06ed4455d8d4df61a5c718b0d3b1c4eef491e29463ac145aed6319899ae3944b923376cab70a570eed036df82235181e187afaacfac08596b47d4c21bf7d0dacaece79a3adc628287302befc9a5d51b4e27c66675e9f0b79f9077d262535fa3d4d902a36bc69c9670955061a1a4cc280f2546930e310f2b899abfd020d1fab369290babe262d8cdb4cf233e20c988a251440ceb1fc3e9e6caf20517295c736ab8d43722b17b3f8c6705d907daa47f4e4dd95c574d235789b45da9563d4d541a3274f8046ad0f318a1f25d184d5386a4d31475b649d4fabc743105388fdfabf53a0cbf702776d1f16334fbc0cce2714c48f93e9682eedee13e0aea17130d999cdf9699a3399ca9a4311b243d49a8f11a93f76f882a1260ee6709546290d3d1f48a531e2936a3564b86cbbeb81ca76cefb3432e2ccd0c16f0e82a31da4e8d3d76b473797efc1a13dcaa116b9d732874d18b1a09737d6f15c272b80fe3ae6399a741d1355b24f7724b87323a37551c2710f5b99c8259075ebbdc3c1cb0dd8db2a49fd732503e75ab2fd66bc8339d67002fea8b40c6ac43580c1d6e95508c87449ccdfeb7b91b66e343d0114a563fe8b58b9897a54046dfa8cbf4f43db40557658d2ea9f5322384fe81cac5f2cabd8f2d4bb14955851b0115270f54369bc887d2c4644447bd78b648f28bf0e646339ebad7cd9c7bba4b23aa130bfc274ac9e44757be19388c7f8604f9e89710a71dbd863420c69f5a55e404c49fa675abb0aedece428b69306efc5dacfcfce07873fd47a47fadfb307250bdf2397534e97b57093ae3399ae0a79970f37ccf574b435b72ebe15b69bd970a9337102fcc999169cff84c7c265373156c89761ee939011c368e9b13840c6ee8b6351714c3a958a610a47d9000000000000000000000000005aa19a0831ceb3f3464d046dce7a09f8100c59520153963f91e71d84adf7e176af18532330d56206fab71d33f6edc9067a929aa52a84c7abd8b37db08c5eb2c93d8623285e27bf87c16e121de204281b74b66a6745ed82ba0a75c660790c723f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c43d1877f2a46ecd981b319e689a3d2bdfe1c5d0356ddd30909971c46e3feb809b5087cabcfc53f062167c74a08f1960fecb417187a93b8e2a2da5a12c4386b69fb7a1791ea1fbfd3ee807fe1d4de10b0ffbc4104769f21f1980f85f479a4181fa185a6061c78b764bbc088e010865ff198f15a29c0a50ebcda0ec8ad8ecab903046b58a71a9bf4f4c44ff4d7a8127cac3382f04e4d2a4b8867379abec5fe76630221992b8f041ad268ba595b1c4577cfae51ceae93d5ba142cbc61a7375c94cc530a094b1bff5a081b9c20cd03964d248ca5e8ba9d7cb00fc96cb4ec396b16cb14272eb198f06003d0724e5800490786139f61cc88c8c083a7dc0ce778c75f8250a102029dc8a9e6d58f27dd1f4d160ae7269eead42d710e4bd0260dcdc4c2cc4fc092031624573ed98417c56cd11212343b57cbcbe831b47fab301e7776be83b2b8c68103075227c95b6b56657d715ea01cb18c0f97d8be78360d24b080c23cd6fb61b403020ad49256ac29079227a9c256d6a5a444532292e6629bcab35e2e0f7795b6d8710225813af57ee6d595aac92405f1416dedb44e3bed61e2802c0f73051d38f597b4498fbefe4f30756962b7eb0147bc795887c366a7fd3be30e8c78cf18919893a6768d1f7f0f4f9ffc3f08a9841e95321644249e78658731e8905be0df875dbe2ad27ddecfd9af2ba578af5ef5c17ae088cede16bf05bfd888065da4fffcf903458e8181157a55a6433e2c062a5edaad0533b9a80d096feb731b430f943e8cc36580ae9fc41cc1d8ab9b143f0e10abcb62bece9462e49c907d70da7cd54e9d7f31b439394cdcd9be06a4bf678f5e0cf3c8ff181d1bd3f3dd8e0659ebca0dc92ffad1ac06d372918ed68028cee77bb7db1b195bd0ecf7dfbb1a4a1d10c7bbd91de1a9fc3bd41468703528eba34bde454b3584a51b3304cfc78bc945e0b18247690d104dcdc96294d8603d674a8497bd19919b7d86fb2c90d1e9c9ad709663ebe602184834ed5751c17af5c2f6aa705e713f1543fbeddda82ec429a7ed8fb216a3c744baeeb698d8521bc34985fca48e07288245252f8f19a3f0bba8dc08e599d2f459230f6f8acef52ffa41b14d74f84addf92216af570d89be887f1fb459709100abb47abe5043fb70b01ce8bec7deccfb7e20886c2208a2e288dfb806b0a958648ab0df13480fa7bbcab8cc878e0f28dc6e85233bb177aa081baa067f4ce1da17591187d32c6a6401de1a79b361af6332e6a32e62b01a36c8cc18e19a529c3649e7c7206262f616cacb57bf94303bce4f6b851289108265a65c0282c7484c7c5c1bb04d5477e931415823478733644e3d8aab559a9202a70c9e1f902fad053289c085b22cec380c4f4c66e4a3059ba1056a80c4f2bab360b7235763beecc55504b794cc7fd4e4bc1e8dd6fb4e0a441b192d0465127679b547d3b2d37012badc74cf6fcaf93756732e68b5efa19bdcc5f023e947cb650ed9d98c34b50b019d87be6c194dcc6a3ff834f73c4bb61a96b928733473a782d688f019eb123deb5cdc558855fd0c1ec6ad3f8aa0f55078e171bf4f2b1e2326e4acfb5657933d37152b7ea98d2ef48026afbcdb29e513ab3c7470a0031f6e2d0133fb017b2fc328db1138876323cd34013a5627b43005ce3575654eb3ec4df78ae86d372e1c46adce40aca34552eb2737a38424e003e7b5d7284a6bd9bdc924ccb31015b5cbf2767c8d7a7ec6026053b01175cb9e026d005f40db3ed028ccfa8431c3bb3c62842476a43169ed48bd2942e5f2d80f338968e9114353d6116bc9484a501b01b693e05282be7ca23f8384395f58ec007d2d8497fc02926f899632b0a9e070313194a48d4472775160bf80b88d928041446c9180a0ddb3791c557dea165576d6740de2d0a4cdccad8eb176a011d64632079d6d96280eb0f37c0bf35ad8572d969f8bd9848703b85be758dfe4e1135be346a14e89b1d12b7a18a5a8e16fa1b1b331e31ebb0d70f00ea3e0bbcdab7dbc73eedd6dbe529fa9ed2fb4e2441733694b9c79e53d5a0534e69d3efb958196e301239e686bb4e486188c264314f0bf7a87ce3ac4f65bc7139106335b43cb53f8a36d05b459a56fe58e751ceabc26a882877a3d66b5135b3d11a5fe7711e1ed2a0f57f34d7ad403d3c356256015a48b3dff6441fa585b780ecd00f2ea1e6385675ed5ccf83e519f22e5e5e3d8bae7d5f518eb9f8cfe520694d1eb967093cd5ac1d3477ccf44e8e1cc39a216b5c70de7f7d5e80c3fd9876bd02219947b5d7e430422a684bfcc69fdac5de49b3103000000000000000000000000d2af3bac5ad4e758d9380c8befff8372d6a3651b935a015b451a7fec50da9b98cbc0290fac16822f7c9e095b4fb5ae69757af271dea9926b47ba5f42056d428610cf9d9b8a94ba7fcf491e3b6a37e37fefd403cdcef2b22a5374e626bef2e91c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d32cf40b382a245d821e0f5197425b8e50cd02ef27da641bc6e51d68c3dc712e5979835e06cac53943175c79c43804c886ccea09c129cd429acd10d8fdab61f2f10802ee88f1babdb8ae8902f8a8f73c78bcdc68da7512ce6902baf9b8ec424dcce37122a1991af34bb5174f7665fae46fa67e436606e0b4d310e40b49ea1561020e05eea90b9bcc517affb8ba97785d224da332bdb1753e290aeb8302bfe75d68031666d94be4e3507ad6bf911040831f9fa3daf5a44866189ef43448a1bcd70a9d0b21e3b5a22b9b4472918de6b7fae452db4910ebee92e1fd1fde10bb846456a7b023e7cab89ec400ba904777cbf0275c0e24f656a423af7f64d1c84a7fd046119c0322496f937364eef01d7ff28e78923af80e867d644ac46a4c4cc2309a2883a1ba022ce21869651a5c9ed5ab8a59c631fc0abb5713cb90afb6a3703bfa3a34680d24020c3d23012b46fcaa1f3b0c4f4f68835980fe9dd20b07e2972725b8c21953933003141b31f69c651f131acb40a27a8ec96d004126d3e80f274948f5d1feac5e55f80217edde51b5821e25a57f74ee832c5d6b97e7b2b37f94da00f88667227a5e895971483e4a38c50e96e97a8e1c5f7bd1e411f27b52cd09f5e547177820afe2f8085c6e514616b9a852cc334a5735551afd81462b41b6e16413ac4384df417c666f281fe50d18521a006133b05a51d75a6d18decfef80f5d8bb4047c094680c9948d754d76019a9ff70e1fcdf34586e706b02d751c802676a4cc3b976534de54cc4a86c15aa42a0d05ea64924949477856947be20809c3f7ccd37a326526197216f0aa636e3c8d931f03ae7ebc314d9f98faa1c2647b9395a811ac716ecc2aff9342fc72e93c0820c078b33206dc7201cfcf465ee5b39e8f7ed8aa2feae319afdbf201e7f2dbb6307e52332577c1c5a222ffbf7e7c151dff4a9014a607972fc2e0b0e5f20bea147c68dd7c24657cb47ab428a35a4264736e589fc4019aad1cf7279ce9914a322aa7ec261c673e810bffb0544e4ac5078528b969ded45e2ddacf3c3980d1091d6cee3fe63278ea2ebd928d3cbe6019c08c51f960bfbae01266c98b98dbca04086dc497ed9fbdb05f93298d57e2b709bf8032b3bc5cf4e6ded70ff3b64056e3c53c283924c2a31b4f3734f6a3f660fcd5a5526e31348b2a8fc1cbf1125afc99c35053c390aa74b863a900d998eeb6ad46967f4ca3454f4041bb3593c513e17033e69edd0bb1b5ca531b0a6ea2247d701b85ec07c7e2e74ed68666cf4b2b0d205aa3cfa04c7b8a1648f0b820bb280ab3b25e2c452bf06f3c03db2f44f94c442ef6b7d1583389c9e4aa76abede6ae01c22f992ee3ffc0667ac733e11d33d5fc3ce2365f345e67d57fbc933ea626958a9686c8047e52561c0fa8d0ad7637dc9e5a446ffecf86e1109e829789f6cddb139dd916e7f483a27d7bf61a0b8aa07751c8261f5098b672fcd061139e02467f4e6d550094173bf6720d014238e66f39ae7a14a72b440d571d30420c216bea74b7ee323739cb9b3c7ae7ad4008a7766cf9b2d7d1b4f1fe36618c01c11df4711e8d6293edf0e7accf1c2620a83c8bc2a426d19b1dfce3293029616f758bd6f4fd51c9fefdfe4e15735ded92c552621bdeaa7a51a80ce6c229bd42d4df72d34f13d15de9d8cd3562cc910a7e54a593bae1c02b5928335083bfd2134fba464d73e3b6847b520429206edacfa1e5cdf88fea5245a5c2c394fa82950330c4843292db137be2e11ffdd5c7a1b128789b6d465dff69dd48e0a802a2e9090a6e428dd75665e944908ebb8d8ffd40901c3bb586d6982245fe15285bc1ada4e6b91f9c164bd998df7dc3656992bd274266ab9f2ee40de28e930e2d073f3b76d8d6dae5efd4ee43f2070ea2f706e448a9c0d4f5268e5226d043614fe06a975efa71f63dc92de5a97546dfbc003a70849ef4de3e93cee20277c067d72ecf3864815cb439c55e8ccc409acb1888a1060952dc0b9b66a8d115dc23c40288ade6059a84fe852ee362602dacb64eb3a20f2a376812f6cf4ac6eb058a6e2c77d5cfa66e4f429221cd8a32f242a1f6f2569aed7d5d2e5497bf391d0f16ba462a5d18f600485111cbb7f3edb818f60ac910e39c1178838527e879ee913d39e87abfdfa9ee3a3b6cff04ef04022753b9ee68b36086ad3816c722be81b38525453f12df9588dcf032e23b0eebb2a424a61e3b37a85c4b0d1dd78689fc90ba5021e6b21875a9c6bca6ecf452c57d3f870a8832a31a3210d9377f476fb7cd810086f687ac29fb1ea9823cb46efde653faff3a2ece3e3e1c82a579e01988f1768c2cf991aef55150b47b351f9e916d56a9430cf171935edf964568e27f6e1c10ef24a14809f125869d8741f28cbd35592af334594a0d313775b976999a913ed77d042d88069549f348b6c490a", "006a5163535153", 1, -1278062566, "646573a74f95625ad6292b67eb2e7b3a3e47c5c9a7a039cb077cb23d02a9ffe7"], - ["fe0d47e0038da737989be3e12a926e1f43a0c27e01d34d3ee8b358b9ab0e4de6692fffe8ad00000000035351ab2948a60516a7e96ed259feb50cd1ff62e3858900b1c1c9067bd32177b004e1c82ca45e9501000000016a096080e72436612083a7c2e66e3add1c1521353ad6ab9a7d029e6cb12fac6e3864ccbef00000000006536a65006a63c41634ae04d709c2010000000004acac00ab56945f050000000000405ff2000000000002ac0046814705000000000553515151525bdcae77", "636551ac65636500", 2, -3340207, "95314e3d1b84e28648f0eca4a1f9337f92d5fe652c5b3b178bd926a077d89362"], - ["c0acde4704aa909f5d532fde665a0d52c3904d86395f1dcd9d12617bffea8352451ab30480010000000252abffffffffb524d9765785215589ea2c6c4ebfa9b9e37e5301b5f97a0a47c08c9033bb25fa0200000005006a53ab51ffffffff2cd213338b767181caa2c669ce8cf8456870aece35e5d85545f66f4259bd589f0000000001525e77af7dd0b88b8a9f793ebb044647e537cf63e6e921fdeff4e49338f6465e8274492ae80000000004ac6565530baee77b039abcac020000000005ab5365005374252604000000000500526553ac0418c90500000000055351ab5251dc994cdc019e061303000000000000000000000000475d9464113d39e4862d69ce3f0f3381ce2623b70864ff47fbb3e3e9fded64cf310b76c45286f08fe7ee837272384d22c3d395081f43dc3984a3c5962048e9453e56707d3005c4dad15b0f4501109adfbc5f3fe61b42e0ca2d833290e133fc7b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057c07ad16c27fd386d7d15d9aa317b3d4547172d0e61eee9fc6d8829055f741d265e335c90b2b963ad313898d0aa5d568ce834d59b67e4b36a84dbae7b8fd2914f2283c44f6b472b60241c31ab84018c8c9efcd8a68ec0c81a35483d0bfbf82fa42f90c8258f3521b64d7761824a07069a19ec25fd27016b7ea27ec3899a7d2b030a23c1cf3a58dd0808514cb700c71628a36fd3f3eb8b8a0c599768eebc98a0ba021d5e1bb84081f938a86ddf00a1170b617d33360d48618e037e6423516126945e0a0f248f185279c77a49316c6ce8ceee84845346bfc165bfc42517f83150da8d050806478d4a164ca53aff027fd43b97f448d4bce5eeeb4b46bb73a40247c077f40203693f7bff18bdb1032baf95df80850b72411082a0cb36cee3e6e2e2636e318403213c0de3239a08b3b76c041291ef62cc233fb9b8d3346389addf7b882d07ae89022b2c195a6d73ab415c92d9a716b326e334de20c1839714def1d0aaf7929eb8e9032faa074e42b52ffeba6f0c654d5345c1ad31ac0afcebb75ba7fa6ccf0602622503288613fc12e58431bc529657995dd3f40199cf37705120a9ec231bb21c746f993a54e66a04bab7cc9f81bbfc40c1f008a349f656a1cbbacb290d0ac33c67579ea313df804e9c1dfffef1e980a93ac1de485f0f16127eea137b1e866c6c2fe47dd24bc8f2c6522f9d4ae0ca685c5b2c5094cca623866b3aa619dad4b1c01f5c2b4f893079a5a56d43216eb199f2cbb1f0549f296cf850cca330d584c987c13b7e1e0ca2441ffec6c5d7a2727ea417f87bfb479a691609e0a8525cac51350c3672b50abe0c2f984e28ac28cd8d8d79fdb1d240ecdf8cb8c8b7e2159737b1607b2c3d8b29bd61e80f7c59529a2327b3e0926b50df31417d4e66d58363c531ace5d007100e5e97335b212c81700db0dabdc75787a29c848f81e81231d6b24c93144e85e8f8182b32fa96b25f0281790ae86fd9e7af7e528d6b81e9d52a803d3ecd63d167740c70a0c5aa3b1768133e843b890d9f15162a50592f1c05105faba435e765dc8357fd0fdd2ee9841f4c8604fa55e46cec8c56258a7356a2af0e8577dabf1b7351294d7236d62e7e3cb71684cce60b4462df8bbd7c54ef2f5a977df4f4d8a88cbda04a232b2d48ef67056e85a8e2400899ea26ba0395c3e775d0499dd6ac1d9acb5219f56651c414c24e28cc150bcc48866b21064a8757018942adf6fa3e2e9dfa80c69758b19a3197008035b43808ff69b34b396b5acacf164b58f44eb101c2c92035f7f0f6a34be0641cfd57c0e4c3bb5b36a4f8871968cd61d87deb00f34ed049db2f40deaad873acb6ac928b49da68a2941a1bdbbf81570722b6ab3cd6a2ae8c62fdc1c0b80b800566c09c253a991430fa404eb35fe9dd7dc08ad6a17c8c71c1468711a238ea6585c1840ab916f90638fa403f529016adfc3533b508f3b7eff073011ce4957bab46570925e68c24b7a1d87b11651dc3e6c4b7bc2624d82bb96d32630c94b87415338453e172c0a2d1693b87b122397ceed81f84269c4d57797816a30d216a4e593884f571988cda75d2cd64b3ae7ccfd8145846d9dd052a9d9baa688ed310963f74c0b1a5936d382508ea8bcc01d80458dd740f252ee90d1a7e7614625ebad3403f3451e22bf026d1d6b4a80621fc7ccbc61ba879d76f3aef58cf89494d91f57bb57bfc9020dcda8a5dabbcbbaad986ecc475aab897975b30902cd00a362a1a27dcfecbda3c497a3a4d143b6c65984ae36cb44e7ee5f542bcc87a619c1e7a8d9af650f8316c90ec013fa5b1f0136e88bf4231d10f364fff3a02e1f066bc1546e62bab4317aa40e3d1b661d1c30efc30c55315f26bae4416092e91bbd403b3c288061d0651de3b411484c1a033542db560fa34b9b2f2b105e2fd47a7d62824d23aa8d9142075f5a5b9c9be6f838cfdfd02cb25f922f8cb7d4973c4cee88bbd69ac0d8f85d00d67281a4206c4b4942d072a2007e3a6a82a706633f839250497673adfd0384140fd7351644a4f5ce320ee0d465de7607241ba5f9572105d71479468936ad41d2a7eafaaa05fac6c3f8e41bce13955d32d43b7e0fa478a4e32bdc8573d9111810fc737e81b1126352e219ce5b91b03e3211f2d7cdcafc15965905427bdb49e42a5f71eec00d74c192bc2fac12879aed36043faacc3901a027118bd13b4ec1372536b5ca916d2623e5414f5fa0aa1bb766ed31050c5513813d98e82dd0bde22599a51ca13284452cabb604ccb92cee0ee0665c0c8b64a28efa51f7306c4c8ed4f02537f4bcc8eecc3d670cd007c10816fe4229420fa5abbba567579788eb985bc728db4c7f0a82b15ce5b096d46d5f2aaccae53f45f3c77ba407fe394cb26b720d8f6b61a8d5e61e8295be1c41ce67c0624bef1b02f580fd925f5002bffd180ce4a1108", "00ac52ac5251", 3, 582941288, "4ed0e37f515e78a8084bb281e5a6fe3cf07ad142b706ccf0fad56a82f12f6255"], - ["0256d2c6035ee62983e4a76440fc9c4236c33ebb1956e2662d3ff6ca4b091593907d210fba020000000400515265ffffffff56fe1c3dc85c08614c5ed393d6f14dba7c883baa25446c16de0d314a441fc0380100000008526a63526aabababffffffff4ab4361603447a992c8279b1a04fc2bf0eeea8efaa8236835742bf0e2185cf83020000000152ffffffff017af9c60500000000076a520051525351a5f75b64", "ac5163ac", 0, 124548875, "262e7b1ece99e0a5c8cc08f57f047a3332a7d6adc45de3a786a7f74be016bfc0"], - ["471f412a04f7368ebce021a19c89f9f36eed12817cfd20a8cf593daaf46e2dcabd9838069c0100000000ffffffff11afe59e938ab1c93cc8e93cbdd5c1029b2b81611149d19551d3aaee02cf5729010000000565520063abfffffffff28067031f7c31f71006cd2f6771b14f0f9ab07514c7414c0bf6ddbbf43083660100000009630053536a63ac53651905f68bef104cc28f7e5fbedb18a9f9931a1e3211a820c95193f4fb9d8341099d342dc70100000003ab5200ffffffff04e4c80705000000000865656aac6aab650079bbbd03000000000551ab0053510474210200000000026363c5ca690000000000045100636386a87cf900", "516a", 1, -1234865985, "972925a4e858bf237b225c30f94805ab76c437e5cc4e5808fc505756d816075f"], - ["2b26c277034dae93473cebd38ea1f5ed085c1265c61f1fc61882926311cedba8dbe56211220000000002ac00ffffffffc873a1081b98749d2b8a2cc874cad76a1281b8a3b28ee718c135a2b9c35a4b7b01000000036a6300ffffffff69525d5f8fa7817ad5b70eb847a1a12a9f1e5e1dea492fa8d5857d63aca0b39e0200000008535365526500abab322d659d04c85b2a040000000000c245c100000000000165df9b47050000000009ac6563ab525352ac0082d6c802000000000765ab65516aabab00000000020000000000000000d3a48103000000009137d52223eb9618dfd21efb5758ef35fe95b0f3e68f3dbdefd8c5f811cacae023c277ebc8e40b566b93d1a665bc8ed309b2215880a8211af34ea7fbff6775799d0d51b7416c021e49b98a76891423a0d6ddf44566a0f90a95926909f8ba1ae7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bdd4d10c3cf8bd0464223935e6eaa72cc4265d90b19ca04d0f6f9199e2a4ba34b6052ccdb08ec1bd294fc5b0f4294f056f111c2a6f1830ea5deb3c6fd8c30b38685ca779cc16dbdfd4231c2dc70aecba9a6412be1038631a37e1cfb44bde160342e7fdf100cf93164f05fcf0d9e4708a388dc8b63008248448f664bbced73f7023013d2d3e5a152f034c236933146c7e8eea5835aca43dcf8285bf45f15e2cb6e0222c13c77bcdbd12b35b028a2fbd48ff850603c7ee917234ec80a5f15e6ebcc420a05cfaa3d9a76e6b6fc99694658483be11aa64d34c2b914fc15f533635f6ac77e27baedf8c52a49f4f2cdbab3d7d6706215e77b7995d03416b21c51eb3e56f4c903190aff636953d7a6dc286fc53dd8c47aa59a447eb6ff06429526356234e936ab0314e1ea0d8b4f9a6e304f478711ff2a8591258bcac14acc9eff24d9740fc4aa8b032929c97b7944f97f361b87982cfab1b4c7d17a3d246aeaf183e58bca2f782fe203238921e4cebdadb4015f59772ece53fdd33184907d663f644a6c3eded4cd1b1c02063a837bb1326037d8e0f2cfb2e07fdd0a94343dcec72bfdb3e31c2c7ac6f6d0ec091ea73a8221c8228c4c06c5673819ef3e33d648ef0a3bb4568b9debd9841dd38b772cb59b8ed3c3475f1ce392e9092ec8469033e326abff655f9d4cea5f98460e4efe1eb29d8b9e593f4222a6d4887c5ea55ff0335af6e9e6f40514a268a8ae1bc88fba3c3a2592692d7b4af427ad2c1d5ab32689b1485a66751711bdb045b84eb09e46321b88ed662ac9996d6cfce9c56418c52ec8830fbb5a03deb087535b6f84d0ef82b936398d3c96a0487870d7bf451f7a261e29d3bbbc8ae624475b5335ac5dafacd132adc3d7778d6a865c33cf154cf14d0925fd97c18584be79e31ce284d6168f45fa083c68dfc49b731d324a22e86e29e97b5a0c4d76e14f08772f94d228f2565f5576c111e8b0a3f076bd2eaa3277e63b28b9885f8558bfa251b6b3a99831c6fc35be9e249ac84a08a277a21250e2c9ec59211f0a59b6cf76f68180e0ba03b08e48988b1e3b54885550ce478ab325d231d7505700a23a24f356b74319afbc1ad24a19dcdf89adcded1c540cb622fffc1c5e2121f5c1f6ca34a7c9ede9418b78bdf837281be6a9862c2043ac76430f98374b23251684c551953078db475014a11fb3211b507104beaf0970db1f0e480d32b9b295a61bc1368644cf054f8c3a88f5beed17cffce4229e2136c6debbe79030e29cd4c0ce53a5bf9a85498659b66e2e75db386287c24b1e85cc91f890a00a9fd78d3ad8781c71a8b01201cc1dde3791514d7a29a12bede3bf4968d41c30bf93b3a9afa095d4e70afe19501a14bc13f1b53c58c991976cbe5255705e974d4df367b2f869bd41f2ca0fc7393a8c918dc57321c6d1acab8c06809ba3252a99bb2f653a58e2bba7752ae41d12ffd7f04fe0f0565e0e41c4cbb9c5ac1fce0be2808beebbe52a2f5a4cb4142e8d1ea48f17c4b62881dfd1972feb93e21aea362f00b839c183ce86c3276cd85e8ec1c54fb6f3471ef79ac6241ae875282ff872585330e35ef504034f60ce84abd1170c6eba9e33a811aec5789ee564ff86ac958aeace6c01600ea57d35d95cfb2bd84342fd0472b6d001dee47cf5910ef2c61b82cb59cab5db7d0eef8f0a4a6fb88fdc63b1d1e8d52d3742aa9e68837029e2d727dd49da035ef88d276fec86c6d331650c85fe10cff3c9d01302d6f6e89f3e050bf1f1d87f6500a3d21abe9449072b51ef814a9d2fd110f0cac538bb55f2ac2fba00029b0f9678d04ba7d7658f3824669b7ff54f2ea98900276a604cf60343e786cc9390a06b2088522effd5e743ac6c16b15b33b5bc0b0ac3c17e3436acb7984fea6b82af2829ede04b74e0b3a1680f0957603229fb7b0ff09d5de03d8cead6d18b96a40aaafec65d62bd1d9222ccde1e4b0349045e10190ad0b350c89cfc4e463971adf9326638f1bb7f0c207d4f873ac3a92db58d31dd29eb24162d1c27b3f13a908e3b4487290fcd4f2f9662dafe6355ec2e8d8d242156c62199ec65787c6d94f4aba9332b1c90522db67ec68e35b193d8e01aeda90abddabe9cac765e47ccbe6a205a767e7023851565fa4da45c9652098715d17a4211765948d00c92c3c14135de645354c5bce9f43f55c7a336eb724726959cb73eedd085d70a28cee19bbac87cbcb5e563af0f8dfafc30c0083d75fec9f45cc47ee3fd64999ec6136dfe5935dc8907fe5ea271c2eefd84a27a1d499596243d682be2ac607f9f2300000000000000008c4b2e0000000000983fa7fef86a3b01f612d7d17f30fb78b910d86bd2b3e81a8d95354b689d4b87ec5f25c7ed6336921836adcf92053509d015c44665af7eea4399464d5f7302705d3b5237316df2c717681eb63276b31f9ea941e62a542661764ca2e0a895b51f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004de5401343433e0f4395bf0a792077cddd495e78957d5340f8ffbc9bd8f80c929eedb509521edc69c080f336faede9aa03e6e816dad9d387f70d2de28f07bef882ca59ff639b9355596204d709cd9c38edfc2d61292cba3740af91e8112ee0f87b8f2e52a107fc7d62c27b3e5701bad70ce99f1e425a98926c1f908098e546be0229e2ca399fdbb2fb53e4082b85a5bbb13e1f5e6c9185fd530d4e7d42d941f3ed030944aa06fcec643fe660c7de5669e5dc14ec8ac8f81f75006dc703754345b09d0b203049589c78b1ce3673a44a611723d3c0bc87a2c21bbd0c01276c457743b7f616af9cf8e17d4f2bec0ef71eab373ccb015efa23fe2e2bc304b3c09161f06ffe021533dde12fda2934bbef35431617b78a8d096531ffd1d6dc825e0bd9c312208c0307c9d0cd7c3a427225946876285e2435ca55936ab244d0fa820402db2212067b021ab8fc644ea41adfbb8a4fa138355b74fdbe060d921a64f738657c3c5c2dd836022ef2af93511688cd8f848be9838294e76abc7514bf056681b6b19b4a6bc81d6f022199f876314e5ad8712b6eec29603344f1b2cf5c158274d0c36bc1851835466839887675c92e21cd3daeb78e902298233a827e8197b32a845c3af7f7bbdad50203c90df34c9becb8166e14ff76dc6843dbaca4e77a0dee4f1598f02da3ce63f0ef72869a8cc348b4848f8ded91131eff3949e2eb1eef94a0ea74664687b2a2b088cf77f9d2c62fdea5aa41a13379a702ea1afd79d4e987e104f51fe82802931837d57b18a754d822381bee5c1050e578733120783a180072b05f070b02fce4f5a0889d862a9d132c26a76c64631fb3ad8ba8956e844e4e6fe6c53e114d0de272dc6a5ea5400fb1e8bc4b410b0de7f1757a442e59644d2149a34d8ebcd32f13684c1af261169dde8aadd6d8e897182a40352f9e66111cfaa2a0821c5327bc588a9831804c82c796221b426918181fde162680151581532367dfbb5318e16d9af81c2606c0ff678285414bbdd069a9145988b405b3b898ad1491b8d8a6501df16b678c7de54ef984ef266ec6195b5533bbe3a23ffdaf76d302f050d119686c10d46fe6dab67a51a5f98d98ce06c156c8ebe87d671a9abe2e4d135dd4ea6e9c007bbae4318e1b7c9772e6fce2e585a4c374b4410b5fa8af69d2ae6842dae95aacfcb7b30dcd9535b53f94938619c4d50b377764c87505cd6031912df1dca66fa892358687a2f034acd83c1d545fa6b7ef41b2b60f5b64971e19edef278ea5a5a8cc1149f637a13ac7aa710dd1cb15cc0283648380708444d8b1c6a6fd12fb0386f8c4ece7e681748289189b617fcae279136f7073a47a3f6d163e203ce4c2c8ac058c6dfcde3c508d96f586a1a0214da7f10e947fd085913ce46aad953ddcb7a2ff445599f71b90aa3152939a64ee99249a5a65d19ec530ad8e607af6ffa452988277af7b0bab822eade9606f29cebf72e0fdb2886866210157095fa45dec7d1a179052a862b9aff8ee1dc2c5a0eabcdf7c43593ac46939cbe8de90782d1f55f61753ef9290692baabb0f1dd2cbb8a3e91e3083c942ae3278249c697195b6b544cb9e09699bfc72d7b336b37938c3310eee4134f265b6e2154dd861917f9d3082b447fdc433a795524858b427685948a5a96196995b078ddfbe7961773393fcfb9864cbf851affc35efefed7a714e2bf1d2348e5d5117171e42ad151158e767c57cff9a36553ddb8908c4cf66c899a657db7b491c9eb09cea3846a51946508ae78e722755f335a7152be98b02837b41da186f0277da19e5ab4e0f714362b4125a8bb911249af4b9c3fc7348764da80c236be08239eb9ac34c8396748c545450f4d998d5fc0c3ce5dea4755d82b2d2ca72959a3190f1ff1adcf69b07dc42ba00439837cd817e9ea5009c1e897d222034773460d3f109d1a11a9ed16127c5b207551d143c4ae2bd1876f58080ecf502e59279a7bb41db9a26f05cba15ef44e616971a712cbafcaa595475bce899e7386841ad47e7e31b46c06ca6ef04193fdd96a48067f8ab87cfd04ca64c191e6c059f362e2fe8fadda43f464b02456a69e695899a02bc30886423895db9276602d95204717d0c0757f6c1fb50cbb10f35b2a92d3773cf30112568cc0f31fe394dd394f52c2f0d354e3d4faa2be0e1f6664c165e7a767a35d621902c09b108403c25ba381d159fd8815eb5d6aabf573f79e45e34139b1b6ee3dd070bc08747f81dc6d51dc5a9061fb6f602a2ddc19940330ba582a8a837a96ad1c64362b549eb35f9993cae579c1ea50f11cb3240330da6df383adf548bc9c75b1cc3bd4b2d288ce95d278d15f7b99cc8ac090154963bbc3093e9a7e6598ea597a7309cf0188db74bd41f33cdff09165a12b17ebcb59979f992895d7b46d5acd014aed1df5502e9c442654eee07", "6a6a51ac5200", 0, -267341217, "d2033ca30e40bd2cb89ea9195c732a5d065ccceeaf266467f78565f66a82b95c"], - ["eba18af004bf8cfcef337a5b833472f7744773ba90555e97b42e4b8bfdf6e1e02d0c26ebf3000000000752ab5300acacabbf69caeb0777cf70b40d31163fc265d338b388e04294714076c6e2582a3287eed224b4be0000000003526300ad36472653341effaf59fe698a70180e9ff1f24f468cfa2455dde2f8b3cc17ba47a1ee470200000003516352ffffffffc05bfe2a3da09c398f7487b0513b9f45efe969052f962314f422a4046cc186dc0000000004ab00ab00ffffffff0164f2af05000000000800006a63006a5163958a358b", "006a000065acac", 0, -2090116042, "5932ed1e27740a1810c1dd0cd1f235ff8bcf64d2579e40cf502e594d386e4ad3"], - ["fc4d72240382b4e8eb87f70aa50773203c5643f6993837fb8634119afbb7e96553d9d9c4020100000000ffffffffb6467961659e63b8441e96cd5eec4c5ef8bbb442826d3a419650dc055ce468cf0100000008ac00520051ab5352ffffffff65a1a0b0bcc1f353499143455259ba6007a289eec9160e84f6fe6848286631ca010000000565536565ab9d1d5f0401beecc3000000000000b88f6419012a583c020000000000000000000000006b887428d35b9f57beaa10a3cad2e233c57ec29e44ca4531b271ff4f52b2d9fdf066663253eef81ffac867472775291f235d913677731090e40cef467365a6c90c59f39e1a13e15257b477098568a2d57cdc08191f2122975a4cd4fe3d3efc7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f901f1685cce76ec9650e94e8983e29eb0195a5eb5ed56c8cb8d314cfa309a6e564cac880a0a312d46ff7beea6c916eb77a927a22ecee1e03bb029a7ee2cd3e3c9d873410007dc76788fd27826e87660ed8989f5a3d0bce7150a4b209435a43dae7d7245f71a83b3661b917e211fd4735dfda69bf29241c048bf90e823c6cf7202103edc6ba683be3d97fae0de5430a5f8e87c4879337978a82c289e8f40d0bf1f0318b80d4039530ad723003b0527496c9f3c4322814934384ad27015d45151f9af0b240ada9efb3d0a35ec117899020ee65ab1b59d2295deeb7c563bf98f965d61d02c696d6ecb078a57bb130ff92724b954c924b0194f6ff36a07163b64ba42cb6c0308e17a4da1a157e78d82d135dc9c74e701741e56dea8ea6ad80ae6f110fff9ac0328616b2f31829bc7e506cfe3556ce2d7e549ccf9495f7418a4ded8cb35a11b8e0222204ca9d155f3c78db8e4ef6247ede93bb92925796f5a2b325f9e55314b06d50224bed1563db2c1552e6910e37bebc5ff30cdb249b09e085b1041ac51941b5be003202d7a22165fbdab3fa7ac27bffb5a3844a44e552b5f8c3330d7646d6c91b6603a2d717922bdb52244f1abd956928cf98ff8cf19a7e32c75afe90cbd028159cdbd0ecd06184adbffea2777da3b5fcbce80f7d7445afc9f91e2b0c1a9b6390436d7d7d5d4dcfc18b207fe0d9faf38155364af122c015bd32fcab3b7ce2451ece32531a8e792a9e8cd55a317c38e737b7b8bc6d942c2c7bcea43fac046362dc11ea9539efc2068ab4c561eb14525e456f0b4f63275d217ee3d0553485f00781ad7578a668e3bf93e586b5e7c53919d27c15cdb705bdfcdf2a6115d651c78576e78a84648a298c91796d57aefa36e9f97106ef532415201d70b49620c8ea4d9660837b7820fb3cd4184ae37303343f528ad846457adb486925301a4e0783146831ce860116f2707a9047f54c2adca7b2b5886cec503d9213bdc637b99d6b88f1f3c2926295c4ecc00a2098e8932f9c08930539fcfeaa86ced926935267c599556cb44fc44f8320832545f1e5cf9065dc7c5d6785fb650e38a1e49b8a25654a9e538cab841eb861ee6e1c26b5fb181d00812b6c83de5d48c110bdb646c9ea3025cfa45f4e1b6d4ece4273887dffa460378b2c606534a3340c37c62b738fcab1f0d3c9c694033fff0fe34eae94375ccbcc617cb2dea2d4845201637d352416fd0e2c76f8a5855a1da9e4598803f3a890428b94347dcb6876bca976e4050e083681306713cf62780f691c44b6291f98c21867e19d70ab2a2c55b40a1e882be0cda1d767b6938a70354a2b55f01e6ccba19efed93f049d865804f91cf87f8ad708f7a9525340d1dd549fd207a459be175a4b88951f75c84e225a8587a8048171ae6697f7f6eab71a4331dea250a04c94091a73e68e58f2d2cbc17600f2df3d488854f0bd1bb52022c62412c1022b4916f68559e8ce4b6a954087edb85c346702c4c704c10bdb8e3284baba107c095f069c3378791dcd5ac25a051771468004e349ed0740c3d83ce5269dc3e41a0445565eb69ab127e8f74fb6de22e73457f5bd5650f11db82ee0b4406d36376767bb57c5691544d1421dbab22027779db272bd9e29aaaa571c14599f0a5c01aeed2265434a9826e14adb8785e7bfd352af93953c6238cc092eb48ae2dd9b78f55a4e98858a84bb7175dcb3d380513067b8e95fa768bfda4692349baa8bf9572c3056ce3d702bec634162f377cab605ec1bb9a540478b623e486c229116d3d83afd483878671af63d1b19cf74ef864350e61bf151825d47f14cc9e0247d51e4e8203934ce33f3d3614b2db40fa349983a18a3a77121415c241f743b068f0ba36a14f1d577fb3d49572b1efc13d920587a8c7159169e895e50503509c478c83dc49d2d39dd5bddcf5ac04672fb76db6708af0751aa3f605ab775293a730ef3cffdd7c1cdd7be99cb09e657474542544902f515eb6e2b4e38b329f38ce602d7c083b12347694e6f4c9bebe3014b3281f68528a5c3cf139d9d3c91d883c600a0d56bd3b9c3cea32d1802364e3a5f1b8f17b1028d673caab6a3c6562a57e39845432ee79d45b81ab764cc436eaaae773cd44acb61a604f0d77cdf44e3ae44cc5c1f85d619ea99fdf0a4e92a80daf472cb6aacb0589c690d734f1585b934438e96e69ef675336abc4c1da01676441e307237355c331361f93b7d1b5dc57ff79def4817ecd27e2e803d017fa97f431492a55a60136f8ea88ea0628e5eafec19fda43abb8c7cf166088027d8673c618f4fd7d6a8accaa72fb5155dc9204f44a8768b504d4717533370ee79015f13b2c0d6b9bc21c5144520208c6da4aef1c90895048da5169a8c06b4894eb49bbbd4dba5c2084f751416f2d92630d555e2d17ef15a6f1d7c9cf0fa5c759c100", "52", 0, -1488314322, "63f5ac3840448cbd4a66fb2be6e822a7db7f18cf13b7dd3d96114e687c3790e3"], - ["372b960002945027e2e089396934348f923890b4ea27e086fc9072df4bc2e82f2b327ffe75020000000400536565ffffffff73aed46dbf129934ea2332df8c4215c754060ca5baafd83a295f3f396fa3156303000000010018c008820294d17b030000000004ab526a65f4a1fb040000000008516a655152005251e1a2e7cd02000000000000000085e2990200000000e8f046329edddc72c97f3d1cb7aa717ccb79731fbafedc182c62daf227cf32f71ef691a0d7fa6367123df1df8dbb3acc23f3be25a62f747adaf70c6505363f97df0acd2927471abe78a75053034231166d5cf6e6db98022446b0ee74deade55c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e7005cc04ea334d37d2b90bbe536dd35e3c7776ee5605c9d04e4b5f7ee606cb2281a5c02d5efd19cdec31b0c6e1f997df1880adce06ff99ed743efd4f2eaf1042179b009fc7b7aa00d44c59f995a0783535624f216cb5211acdc9e7381aecc34bb7aeed9aabfe26417d6cd194866a7f212504ce07c4d99eedf370eee18dc3a89030401ed1bfcfc32bd0c57cb271f81385a7dd85725d9a7fee7e64177df098b3cac0304cd93b58c085f36cca709dd8e0d139ac29640ffa72aaab2791c063f7c73ec6d0b2fe27e352df4b584dcb4764ab2464e84a9c25cbd6b06dc1b868ec9d723f183bf1d96b972ae79c943d27a15caf399fb286769fcdd73d0ab2431a19ff46d89f3310329adc4e42216895976b341375f9e2f77b7ab7f6d235a5e1c53354aff4f1e7a51030d1220fb573252d9db2fc95e2e672f70c34c2cc7644029d90433a15ef47df74e030764415b82de00258c9b30a3a9a294503cf365c9b4a9e1b26a50649c4be6547702125b3e3ce89bd004b507c041556e8ff7e4cc28502483adf79ff32bab360aefc4021d5998c80412a1bb0eae381aa209dbdb6ea1e4da1a52cefd13d9328a24868a4642077e14e0b9148d54d5425003fee1739e15027c9613d13d1d9fdb4592a7685603fc573c5ee8d78a44f20c3dd8ca6502737e83c1c491124a60c1bf01467734e387119df6a2e642a8c473d96a8eb386681551b350d7a3d088206befe2bddbaf04948c13e53b453b1a931768a46120d002f568eee2f9e847016d9ed776fbc4914db7e2875eb6ac8c5f05b505c38939b0389233ecbf12fde1f489f67f1f790bfa7c68b9e347ea0311612917d6c27cf8bc5989d2e47f55ba2f28f508c3f7b220e6c2b97d99e49c990780ce37b47ec991759f17e14fde543e0df04dba16afe54db0c2a6bf8b2a911f6aa2010635356de93933a9afbfd7d0d02d1b3beb431e3be893f669e7f9f12cd5e141e1c3f434903cf10fff09226bad66c3dbe13d17238cdc69a43c53559546de2d168f099c9ca84df21ec0daab96dc22c9a7de792f888640d1c8083a7581acc46c5358e188e203f580029b52ee3bd954db4a3f03c5434db1e8a24f18f393a01ed48efd5819c2d37e51e34292c0c2126bedd3b9b18b9008f517ac6d57cb23c4bfa2a8e7ef81b04de94ef6d161fa2a29e7df0ed74d8ca34b44f0a6dcef58ed30fdb223826551f056aa8d4565536c5a58070067dca102d0c11c5bcfe3db4b9140e0eba87de2cee18816ee2443490e518b90351ffa9ad3516217f3db675f253ef988968410ac81878cdd01f206dd9d76c5a42cf800b7e7ba920fbde2dd7dde4628b3e4000873ae132714dad125546d1d8c4fd64fda02ec9a5fdee87bf5a5c785978f38cb1a3ab34819ba29cdd5a4dc3ec5ed0f3bcd6d88b7fdf0eb3e7a565c1792c72348866abfbd1cbe460f055077e35a313aaf06505da5dee699680190a41dc64802b2e366e5eae8bd71149bd46d010445d234e8b16495caacad0dd90631daf9af5aae20f61fc67ad58ce4c2e32970c790755600dfa48679fea299dd4b38ec7ddac5adcdebaefc83fa0768ea695991a5e0ae786f752b307fb4468c231b08d58fc23c16f2032bb683c94251b6645e13482bb291d65e8252ae72c0d2bb2aff32156d67a04c1e6c14deb1b75a3b81fc15d67ae5e598b90dc69da4bd247adec8dbe39010de775c1fd887595bb2fcee3a6cdf74e4d31923ab865a35d79b378cc30a047e8457b108e39b189b25a65ad630f6c1199e84aa707b270d34ed10904fd5b014c70ab5733af09c0e49003f6a6fce81e70eb07ca7f536299ca0034a7448ce1d922b9531fcb2678a2ec74a7d4c287d5011016162a6fff2be04615a5f0ca6c03b0448247b96ef4bb0486baca9cbeb7c3d03342b4aaf94991db77cba2f53fa10622684e3a7ad697bb30709dcd147746e5e40a8f930f3415786886bc70ec89e1473701ece4dc8f65038215058646a68db613b22cce5480c96644fb46ac3a1a73e8992020a387bf397b848bbe6614101b44fbf46c3eb501363d2ee816c979ade40620f70720e3807b9ef2a22e296e121138950f00f3ab918cf5c775e9973ce5120c49ea74db15b4c4fa2743c41ac69a703f1c78a958b2a1bc6bfb704c0a94d2e79b7d10557e03ed847869cee9b4ea10b4400dd3f37b0a6ec07642fb7bb69dd041ab2aa5460dee54772c193f25fe4a493ab4ef7b0570be2f3563b926a120ef17417e415e11985aa693bb78f15e5a997e4b0deee6d34f209add737660a4ee3af277cc8ae6364c6977d785648b7c3819ccce01f4600000000000000000000000000da50d9bb6a6441e3ad5a83db49f29b487ff32e3f72179651793257b1f0df2f0cbf285d18dce0bb70d0fc634f5af99f4370ee834e36eae10216a0fff7f0d98afaecc34e2a30cd566328fd3889bf19d0dd66bb17fca14b600b6cca54e8f77e84430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069e09b3d3383bb896acaef245ef4481b8cedf3c31f6c2245687af062846433bf788e3eb23f55fe9b1215e1c933a0583a2f2bb178542b5fcecd0a7f30266eadc64e54f643a107e3450c58642164acbe6fe693f1d36e214c9f3a8f7b19305ae7647e138e11f84889f0234bac9af7e9eaad0f20ae7913c5aff9672fdfb329982501031057e9ecc1808efb4a9993f322cdf093631c5230ce53b85072c65e97a1fb2ba70203454731381b05ed3e0dd13d4c01ed32abca86c83d4640500d2280da6238cb170a2d96c6d7fb35250bbacc20edf287ed61797358a2b5721186f6c6ad90ae7671be1cd412dffa25f857ee3f28fd2159e6a149de47f251ff2533e90a523ac2b2e63a020a30e7527bd5c3cc10b192c4aa0fb83f958547fc2c9dfd67c5b5f2734ad91d8c0202b88ce0fb768c3c15010445335fd2cccb725743af5e66efed6f77487433e6b502116c69c649579f77bfcce709a673288567bd058c6d140a03d2983ea3dfac89b9032a8baf4564ae856e6965a6c79a95fc8db27f30152eb3e8f3f1eba4a1a6517c40021c53c6e8fa76bbfd5f19f0fcdd1e1276e5125afbb232d3bc4452bf0a905690b214691056b91d7c9d99ef93d9e4a1cec109a505c9d58763fd57e76883b54a299873634245050f86c02006478ff92496ae68f21639b5ae842422159edaf2db7c8890b8d67c03316b5a9f87082c02ef988f8d508e0b104a334f8ab3f211e6f0346c717ac163bda0b2e29c13dd5cc6e7c139718850746f30613a17665a947a76b42bbb34c7bbc003f4d4d95e1d0089bca9033b7df0e3189a79fca3f3cbba5526a6ff73a7ba29818b05fb1ff26fa9c844f54febc0e5930726d8a9fc8410ee40869ba0f202414973932988fb007e4bb6b4ddb3a888f72cdee3e1354c0ff1d9e5602070ded6a71b6e78e72125c22b26b16c1b0e505a77b2c4c867465fb25254e8aaecfbe59956566c0cc695b016cede6f8b35a0ff85a127f5b595f778fe0471060a1bc78bc2b1a11bbd32d21a758f6c1e93397f4a584e71f569efd5c0cb8bff1ef334a53acc3ceb37da82a206dc144692fa79cb54fe45d347131ac6c5e0257aa1ba90a5b85a6f460a1b39ec872b9da66d077095b8f72dc83f4b2dbad4e55a296917ae910e41fec2bfe4f623110aff2af8d510b1c45a900e6e209cf577a5e9a39d6e998ee6d7e9453ca04de7d5589189bcc1cd0364f1803bb7650682fdd35eb59568682a24e09d534a9ea4b79614bd7a78372ce6f152d7780a2a20fa2736a121c44ca61ca6446bcbd2b246c4ca8e773304c0b77734bb74e90da62dca42fda7ddb20d326a31caa5ac52a9ef4806b42e5a52bbea41fd405a5b83d99c32f6d1788bbb37d69567a12b5c9431150755babf35182b897c6c7063e17b8c4064c7c102c5d11c42d36f79d29e20f48240e8d3f9626e01aecd76f71166854b1e163dca591f02b012a42324865a5cfd6b9cb2461d670a46cf2a829c59a9a60c9f3248e18057a52da38b35cfeb169e2c9573d1c6011e8aa394322b253ab88cef5d1ace2ba7407ece52534813dc49fdf7e1e380f079f494f666275d503c3f4b907e3fe986607fedaaa63e83fc1d52f8cbfa932e1d5f95bb3ef63dfd834f1fa5a16dd4e8b68fc5927522385eee26dd0b546a4eecd3f8083e28a3405712e30b86933fa87dcfb7a90ae8a9be285e1acb53dcd2b214bfd6ea741b461fa473ac7bc199a0acc331aa02487e67f0802b1957aa0b4103b7354d23df199fb64b0ec1e4a6e384f6c0284e47cb5fd86edd4f2904a8411a07a7e957209d80fe9d27510039c4da15790f53a0b83ef70613f575afc53701d708e3689cb6ba4992e30189c837ccfd33de44d0a42fb1dbdc94ddd553857bb14ad077553c9d08b4cd303f7b181d41e4c8cc1afa99f7298eeb1fcd40fa4e31443e883bf51b9fc24248e37a36a21469d64299463164aeb7333025646a287bae8139ffb38976b1d2c592421c19cc7d5ba97de8c22d2de902d9a8e279ee013e1addb877a28d8cf02db24cacec82f805a4897b77d70295136b03e712edae441f68a29da3f6c9db2f6d569bb8940c7f4f044c699f6650c733777f706c690f4bb6408692ad0509949c457a5f397a7ec374b997d3f42d779f839ca634dd82191ab4f7abf3f9110db87619090eab285e82af1b843ebad66bd68a882ccdccf4426be0335a1654ba58972cd4df85034a2289bf46ea9b79ba6f86abf46d6667e59052ae55db52cfbd96e66bf1afc189df588a53325b33c34b9069144c2fbe9230e68b356b363f0052355a8646707bb95ccbb47de96978f80a49a43849db3381f66d4e8d1be49a1c356e8fb842206e5ec5ec204a83d57cc4d7dcc1b4313c48f3a940c05fc20c3ca5f5ecd5f7747771905b4574d0299d72aaf6b696d1dcf581a4b940f957bd3f01bb2eddee00833c75fea909", "53ac526a65", 0, 240217027, "e628cc1a2e8af55a8f84b8d6fd9cf7377fc071401b342e32841a0f9f2a9c6862"], - ["eacdfa310328cc19d2837431469ddd858f0aad9a05db01815e6ddbcb4689eda8bba9926a5c0100000008006500acac6300acfffffffffbaf50bd9d1150b80ab7628a9e5d404b9506677bca9701d29f886c26d84bfbb2020000000152ffffffff3290b89a59fabcddd03bc83ec49e61efdb51c3f9366ca530f78397a4f29032750200000004ab516500ffffffff01f9fecf0400000000055365ab525311035cf300", "ac530000535100", 0, -388087160, "cb3af6e0c9b4c5bad39e608da939196f5902710f9b75e8cad500b07fedc7c024"], - ["1b8ec97b04edb8a0683d0378519d4562df6e8fb803a5e8c001a24864825b59d9b754a3dc2a01000000026a6affffffffab66c4b59ddb0c5ad9bdafc5acba38f2c74760c020b99b1846a3dc5b9a8c58b90200000008ac51535100ac0000ffffffffa874f87fe21dd2ae81f42f09c32f8cb0cb4c32e7b41326813356919b66fe282b00000000046a51ab65ffffffff29c38af16dbebd4dc48ca087614e28306be0a0b4a522eced4e10be5f57231189020000000800535265ab51ac51ffffffff014db8ad0200000000016300000000024fd448040000000000000000000000008d2ac5312d2f1e03e8d1999df1f028e1e0e86b5c89903e3cddda4d347834b6f4f6d3df3982bbacd1fd9aac9dc34f00e7251c2fd0f206c4bf52fc65a3d56ad60aba0f89e8d2accf05276bbb6c9c28ce665db4d4ff456c87b55185c54f50e8e2b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cebf1bb3c04a91ecf43544ea54e0cb8116a8ba2620e2f600bb6449c31571d10c396bdd9c493539e9f4c45db1c5df74d3b27fe4c8b67d5bd17598cfe6a35e7d93ceecfa887de1890ca34fe8bdb542b6a84571a45912deb7e430600b956113841b6d5ebc1cd44eed86df20507902f1d6430e26ce0ad8ac724ed68cba25ff0c356f022f63e8efb8cae3bf3393fb95c26e872341d04da0a8eabab94b22ec25bb62608902025ae4bf0d96f99796ed0e924e846b6cc0a1c158d5234f43cc8f6eed6290e93c0a1b31f32f3c319ea8ecb599285010523355966669994d6f29c5275103167a8b292bd3fb20c40d97d093ce04472be01b1205b93d42b36a9dc78c9af5179aeade9c0214ec8c8eb9a14c395c04c6de8d901ae7080e4d3600b28cedc5e6d4a3b2abb931030da6849d63a4781fe6324f400ac496445326eee46e4505fc69466c6a88d4d450030ed4882f557ffc7bcec5fc47af7343222df10d722ecd9ce6026b3c936145e749030d340257db18176a87a93d2ee462f474a34d39dc20a1e23c6d9912323c33fc14022cf63905a4304fbe489dfc5f759cda91b4e7744fb5811f03dc4c11f9796dfd1ce3d5bb4bc6eb3b879c1caf7626780a2fe85756aff1071cb9a1d1458a8b82cae9709a5c8c43a550dffda73b2222aa11c2682ea7c5c98785fb04157e161c5b83f08039adc2b5bef62f4d3ee68929e616b22a582933c276a48baea6e1ce053142e45e6c8007012d3ce36be2c2c70ca1c0f2fd772ac421a79cd28c937a0773669fbe3b5d902419ff68b56901dad5f908f272f56d096593a67fe7bc9f0ff68798e100e2c3c6732e96f27c730aff0d6ca9da6e3d1c98f7b1b2865d0ae653369a6e7440dbfe571e73aeadd2a22fd6dbb297de83021abf8a113c261f8873275853275f94e5442a04809474e44c708e976fdae6e9d949e43fc538523360eed0d032ed1d6d299163c62fbfa122c5838343dbdc8a36344dfe45dad113694fc9733fb71c743833a7052f70f2a8ff861694a264bb14b1f15a9b79cacc03ac3c517a9495cbb00fbfd17ce25f36aca1c87dc65799e3ec3fc72cec85eeff060d6d3eeb512514c39a5b9b71975d500bfe17d38ad49f647008dfda3e7c751857e85225282f8cea98308ccc45a6ddc8da9d368863c030904c3a6d5b0beb0c6de49e8fbdbeb81c151fa324eda781d4ff5eca7fc1bfd7bb0a8ca2b4628afc76a67ec5806f8a7afd45f9447d2993802cac9dab0cfa99a16c0a5637d4a49c03fb84c7a81006f4d60147bc32253a6a0524ff176c772fd2ed9e0110e9c409c1de854f134e32869517315ca38f0349e5367f3e5856ad6765b5a0dce300c1dbb3cf1c756aed64d0ad1d134593b6e4120c07871fcf15a58f6fdf5e0210cc63e05f8640de77678171fdd87e88c9b921c4b6ee2505d682e3813ee48a6bc0029365a9d1756c405a90c2cfdd42fc9ad48742cc0a43196977bd4cd900dff7a2f3b2e289cdc4fd77b7e36760dd54a0a4ff22dc8f16990171465977dcef8af925cb2626044b8a1889bf1f06242f752402312c80bcc61c8e3637e9bd301449d491a22ceaf83a4e96b060dde6b78f361ace3393a5d9e8db7617d435403da768c0742d6bfab85d1efd3afa3ee7407f5bc20a7cd77d71ac420b9dd08c308aeeb725fbc119075a9299088431431cc535c128be983ed6e7e2286f347d1283987c4802e61be54d02f2d8833a463f451144c8f4ca505f84c43d3eecf796585ba08680f60417ce143ab6eaf3c357dd89fa3d66dc4217d74cdbeb8443b7aec0cdf4669fad309ea08c91a5bba7f0bb1f0a136cfda382b27df85a33de94e29ab39c531f7567ef3d9440fe32d64c2d4d4f5b9b514d7cfc3c84fbd0d99d0e6a3e9d4813fee24bdb86dd93203223a673d294a1a78110347789f72ff2239495c3860f8dd596f13530d07357d11058a5b7afc22ba9211017e207e5707cd93c209119ed6f95bd733104bb905f10580897e08566b4f97aeee9fd32e235792fe3bed7a3101fad5f7491f68a1addd0362ebdc5b319d463b38460c6b529c09e9d8b63b672457c1921e641bb0d9dfe8a83dabe66607f1526b182a81c8b144cd5650690f553ab3609cffd256c22388e7e3667794b406a3038dd91f43e21882f4908102fc71be42c87ebe3f3c316ab7646c240c3a9d850303a4fdb5a63f669e6d9521777b92ad30d42ef42d7e86b2c306eb943bc45265aca6b56e85060e2fb470050c34fa02eccfd1e852628a4fd0a2a51f8806a57e1613fbdb7239ae87f86434c19842914bc5676e8c998acd7b22a31e68b07020000000000000000000000001e4e75eaa68f232a43bf34fea1065a5f22ad5d2cdf0904378de2658cd0061046a2497622d7724ef6422ce1d0eb2cbdeeb7de4d5cc9bf916bf53affec92cd5c928587dee1956bd12f8b67d0a5bfeb3162db3fdb28feec1b3f183b20f20379c26b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e553c818d3e2fad4e2c4b39f7fc6e94e6ced344af37664e1c12ea8ce4dbaa9786b2e263c5f37506a46c1dc640e66454fae0478594c4fecd29b2bd5845464af0855203b6b85e1f59d1e1ec2cd2ea79e1e07634b596348333a7ef2cfb340f2e4be300539c760885d3d5d1d5e06cdea1f7ce6dcb690f3325aee5717db03a7ffa2f4022236aa1abf77b53bfc2770f2849d26ade3681debfccba8d147115232e33437660317aa7a1ea4baea378d5fa09af68a92ea0d13e41b1feac2f20b4fba68ed8a42af0b17a19b732aa9ba8cb7a0943aa5d4071deeab401423e864191b2c39edb034b94c1ac0fd6c321932b13d170c90ae4d6c621478ca8f771a8ba3f362d72d13c2739c021570f66bd9ac2c8fd3499b0c082b95e2e95a2f8b880394c893adb022aa636d44032f1f7d436369c052037e50f1e28fc499874cca2fbe88e1befa59ca9f1d13b2c6031f2cbac5500f8b436a421f5e270569734a90c31cecc6e06954514cbcc3258874031318143003735bf810dee7ef12bca2e96b1d0a5f4811a902642091400adc9cc9020de26e61ce1b6620a273e0ddb2f47e9709af5fea1f590b954b64b45dfc973c1d6ca869287deadc35588e4482ae981aa421c7dd97e48c57e12c84d9abbb541731fff8868703c1d4831b7932d53014b120ca0dc094d3d2b37f7822c27a1ccddcf9136a77c0e4b4721fae959ded2d07bb096d107826f8e7a0b037f51fd41aab8aae5cde66e1e5a25cc9f3611e833deb18196d7a289ed6953e7a582212678a5a139e7eefadee46a67ad6f15391b811be9f175531e44e2775c5a684226a44dade8f4b71e5ab79a493479d0154466ab052f38ac04763bb9386e07ad026802097cc6913844587e74e5ca4283616a4379f2e4b265c880bc13387596dfb37da8fdbb58a20887139edbc8d96ee28bcc5dbeefa95c0291275b81a381e153069d92930b5f3a089ee8263efb81d2aaa4de15898e71d7ef98f27ff5b6107a5cac7faa6c368511e1d4483f8feb9e9ca81981af4125b48d56ccae3b0e93ef8e8cfb7abd34ca32a91a56a770fcf4e04c62993407457a73e9aaf1cec49fcd8bd28786c73b17af38f685b95c765c3830fba88f2f6dad192ea5c38e76f35baa130e982ca161534e53e54608e117358bb75e8dbda97ab36af10f1d4138fc226af0e1750f18188909807e352393beb15e482d7d2358162249ad0415549e00752e02f62ec14ba2c70a20abadf55299051fe11d57d0ddd2b0be10c4154fa3743487f58d1275ff3261ecf701015160cdeb483f9e2d619734765f94a84b0e1c94aae781a5125828706dfb620c4e36d1aeea9a30908016073ac242594bf63afe9a155bc412ace91d790ac3020d8724597137a8b19ecb4b0ab9c903d5b4abffa613abaf4470e2af39bcd85129e970413d94f3d34cf548c1a1009021832a1097d67fb3821af2c9ec7b0d08c15e9226aa1e9a6227258358e9e24d7b30b4a9abf265a579e2e907983e869041655e78f74078ad23bb46d9519a1680f94c95008c0bc28cd507b5bcf2d4a7ee03bd365dafb2c211a41db475fa6bf04d44240d0915722c06c16e68239b7a30a8d227ffa00b63595aae14e3fd65f32030ae0bf41265a172242804f3edae4587e77359aeb4001394d2ae7ffff9cb20a070cad9fbbc347abbb0512f861326d1d67d990bf5313dc96b31e4688b01d079d07fd44532f3abfb7d67358378e29de78ddec2434aa637a449af881e8a6ba259f96afff6dc984b132aa180eb28ed7cd502fc1bf83d1799ce1dad5afb6acf3baac859b783cb4da30e97f74561ff978be0913464170188aee3882f696c55929add4a0f3f835d0a2a026b23f963bd07ec5fef6202e858c7376c2efb013db759a4a09048d1f5a7a5c64b0867299509bb1de8ca98c129689f923d7a28cc123a260c58cf6440a5ba4fc4d56ad4ed80a862a630491632399feb2700172ee5b47481bad36075fa1abef7a70763a72f34cc5defd8f2bba95778a6c054b0cad8d6daf636853fe5f8aa5b716217498ba2b660b55c84020a236c1dfb33320c599ee107b136e1584f53821809d362b3c307d41c5aa3b14c8188231c94f5d3d02a9e300db71a1c17efc34820a8c86cd53c9b42e24d0f4ab1e5f9878a94c7957b5fb799ae1f1d8faa3b55657fba6898b382789fcadf5dc2bd08e6e7ae47f2e36dbd77e8774da97bd1b892727a288118bba4009b7de816b708fe8a64ffd705b8cec0e089e9c0782a4bb9a087e9bfd5805e40d6387eb956b2978a3398a6a5bbf11aa43feeb66751890fd312e27ab1511b7bfaeaf2fc3aa9a9362ab058c753fe8a59a93870dd1b99ecc5b4ae8995b6497384755d4a030943a0702972c874245e443036ca512c5f5ff1bca4074b06e5a2a42f82ca486903405ef23d406dccbaac8e9ad390f08fc22e134ead6419c6d86c204", "00ac5353", 2, 1904815369, "07014e106a35cede24e90201532009d94effaf6e40494079af5df1c1a8562a61"], - ["18118b2303fea54ced8c8bbbfc43887d1caef7195c69288ddcf19c0d43af2cc973db549bdf0100000001517f5f2fbf1ae9751c89a98e7bd8026d96c867a1cb79111c73f665f7c11c57a28e8cf8dac101000000090051ab65636a6a5252ffffffff4267ec3067b077544458022b1c4db9629c20d32b369d1b81bf308a4fa3956f7f000000000763526553630053ffffffff03e3b76b000000000000909c570000000000050051acab65e1848204000000000465000000000000000200000000000000008fc41502000000003765cd32f84bf4e1c978c168bcce6a58f63f90885de19a5efbd27379059cc9062d50fe63177047f544f6eda54238ee44f0b4c9973de1c40e743d34fbdeb169e58c134f00463458516dfad656477faecbb6e7acf38fe5e75f42d8965b870bd34300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4c452cf9b43d0a076682545b8c5c61fd49b70b803e64a88128f6ce150c85631e925949ec68f99ed1a0c21d5b62c059e7dbe7b0f67584926af19e761181d997a9b8f1e133b5bed02a033824480693d58c6999e33dcb4cd8f4225c2178d30df9a831e4fdc61a4a1be958eb1c52f0b3757374a23a968cc3ad19b69c0cb737ae3650211d92b99198a4bb2def9b73d3d204c511b2b68642f65a39488088087b97af61c031941b8f75b8f703d8f0e5528807e1b058f6ceeba3fe9b9f42b5b48f4f0370dad0a26241587fd2ec36ec831d4e814b240883a50cd2c3637273a865712a4498d50771f0e6ca9e8dbfcb20d6b9e9caf95e5f7f1a7fd0e31b50e684deb6b0e24b97475020f425a0d46787d40969a35ae6f9a530c2e7fafb440e293dea634383f90ea915f022c221c628fad7d1ffa5616a7006176a924ee203ee5bcc6d655c6dcc00661312e02157278f5408f46a6db1193eeb3c5993231188323db902345162a6ea5f597172902234c8fcd0468567b2402a18f122b5b6133d4f606177e22ba7a18398e74c05025030e6dbadda52b8ce3e81e77355c55b4da65f9020a90130cd2767e497ce4c5104a9d8b766367657829004fbc7dd344ef3116ffd9e66f9cd30c5f4facc6f0b9252a82120330a26a6c060df5a876a65a241dc0fef59d3d42b6c83bafbb73456f22a6414b289ea9853bd8938960aebdd0b3839bf27e4610dea7bc529fac977e81550f2126b47416b4fb485260a2b6bf41fd14b9035d7ab893fcf7a76d82ee7dcf3f1c9927ce81199f63e91c40c89ab1b1c51c4ba7197ff12a3de6061eaa79f89f247f5095f8224d56eb6edd9b378599629be3bdd616464cd0766579de89c47e4f22b2c48115da5720ebe75ba9282e4dfbbe57530c870507a5bd969ee9f9fd6137970e5ec78fe96078ecd3fb046460685a8b22382f5b404d65ed13b4a1db761d846ab3a2d9cc7f9ebb125f617a36120924166ae86a800e2bd84ff81b624a168c07eb83fc142b5b3a0aa4ba666d20c1ba50cf4061528729dbda7bf2b80dd5b713c7367f68902ca653f495ace37bd45a9c9809b7720c398aad699c41a5591c3e6741589b6cd6926d1c6cd25e0bdd6c38f517b70009dfdd1c49d563a20734075cbad234c7cf1816c74c40c47ae935ab6096db1fd42cf90fa61d63780efe780fda02ca27001b5e4414283fe48125c68a54e82e24fabb870b9d54aeb7a0b4007a7de15b35ca6e8338c842f818c657fb812928cb312274fe3ae83f051392ada2fd1bddcc637bcf7cf75eb0253b202f67a6271d830476f6074d9225b86617826e329140c4eecaac8e6dd608380bd2e010c3238c503283d16185da94fe4c8c10d8b75321cd7751bb3c5d133cc7e132c6783f4a05795cb9ea9b23b84ba236b6f97a89a4315f3c95337a24afd9955833658131cb9141ee8b2a8c43832a13b60e968c8d088aa938d11590b036220025d2960b7655d9d792624e289ddec33b8bed291879c3e3e7ba7fbfccab8471b977a0b3cbaef409204395ff59b3758a71ae5b30469afa9290592ef36bf9aa0131bb32bc5b0fad945cb4db6be26cc55a632a4ff45aec769c244a7c0d6804bd021086a8e5a6bacaca69ff04fb18d4a53777c45882bfc186848080f93b58e39f2e6bc36497779f01442474e4fe5678e13a516afe8b75e023b73688f4fb2a11830e7d33f69abc12b755af166e2b10e145283fb3e51e42cf1ab76cbfeb3a58bee5f85028d371900c36277a9ce65b36d9a483b3d2e8805f8d7212e350073e53f2e0f3960d0ed79eb356f82222633a17a894eadc4ebc36a3d1d2ce63c445ee485d73afc2727b135bfa1083c23565f3d27e61738e53bec97f9c0872c0f93be3086aae9b1c0c173613481ead1d33c8e92de90ff00f8adad49747331a7a979cf1fd30a5e611e0ee4d088d710ac38c8e60e2c305afaf3714e45f773eb6cb408fe511ca970e5824482a092d04387434b1f10c76ae543435296c02c55637a75ca6d25d2e56d778582eb5e127cb19513f20dbca118446d4264b00375fe2148b6b088086b389fbdc0a456c98265bd57a0c8dbf906f5a30416489a29d9673a6e43b2a9981e271662c5b1907aa24d951bcfb6a86cc4d4f5f6de2cfa3d05bfba14417e3e1eb608d2f3e6da8aa2511545d74fdc107e9cd4f0b9190a4714822526256d29c7e0dab63bbcb5298f2af4949e9fdb33f18b50235c481d1a3fde7b40dddda391d337bb7a6774d148a6065ce0612bc9f09fd91a428603161541f7409547a585ab674f9fd3403378811d3b6cf15bfdb4480a3d661bae50500000000000000000000000095cc8edf7c026b70b660f7945b47569e2bbf37edd2fe3fbc5c03280d9cc348dc0ccc366a7bec5d764ee2cb1ff330811b7d3d3bd0ff8953d689ef3e8b11494efb5335e689f90a1b4591b5b739c218aebddeedb82a9fb15af1c3e3e9bb9e6fe02d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e624ea378a29751f68cd38f7fd128b3d641768e3a7f424f2302ae38fef4858e81b0e36658d93cbcf1a6be54f1705cd83008883c77499bdf4bb576e79c92ad6c1dffdd8bf1e1895ccae2d9c68cc7b7de05705cf959ff8494ecd953cb12424a5a91271fdb099a428c577faa5a4fdc62e7c87198dae11c5060c535c32921917ff0a02018bf15b93267ce9655da6aa9dbd812045b936a6bb1cb006f391783427ce64930209c0651acfff916447961db7d220fc1029e952e7fb268814f666fe67650f59890b2e7e883f29308324ef26fa25c16362c9d14ccef9a9a6588b1c7358afc3f2f606200f0e7034795f224d9e1938d175d0f38f8e3563cbc50db677de8553ec091cc30320fd2d0794c56253ea8b7d41f95c3f1cd79f2340d3f7ae4145b1ca28c50b87e8020403855aa882150b737e4689f25df841cd53d98dc29945538f5051b406bf9005021ad98cdcddf78dc3aa18f377ece7a7119c8771c9d6726ba47297ed70a23ecb2d020c44dfa5df6a34bb65f4fb74d602eb0e33f5272e9d6eed3e34970e8f45268d7802106192a050de4348730de0c056b626762c0b13b2eba91e683a0a170cf90b63fc9eb9b34dcc3be05bdaf2aac35c59a346a8c08caa3397362bf62cbeea8223e7e3cb3251bce400df6d944c86819ad47dd21fe156ffe01d288a314449238ec18e28b4e76dfff8c92b44b599675d8c34cbff48314f9dbf9e1d315bf812250e02993aced8a12f2fd6e983800a64e9080e79cba63562952ed64c0cf59ade27ad076058af2efe19282e2a449011f1e12b861893c71bbb33dbd2d0875f32c0ec4813d865a2374b5a30ff6b5e7565b1d8c6a12e1c6274e1b8984eefa6f56792aeedcce37f4c2968fd0905cab4adf50504af4f5e9dbb33fb18d3efbb9da218e5f4a0a815185d5cab2f0d93866906feea2d690301908f5ed9e6a869d1278b6d6181af3eccd51a395cbbed754bcbc5f2813bafbae7bd5e9afd20d826ab682bbe8c0a5db9d53524915600a9710ab0a27470ac46510caae9d510586bd9b1761efde8e37c0f48793ffe56df175d2e7ab7984f29fc1651326fa4b96b00e61363ccbcc0d7cf4f45f736cc200f649ffb29781f6d811570d2237bfa47548e32afabe45d1bab65b0e2fae44fea81bb8a094953d480dbcd5d20084a0895a094076d3a848d77046de67caf24ae81fc1e6d53a00bac31a5a3b462b3e2327980e8f8bf4c89f806b02b8185cc4f2205fd9d79bad2d8cdb3828ce52ae7d11ee1e06cc17b7556c804136da4537386b96a948b3892bf60fd751ee0d630c1055d39a44482c568a20999caa9d618627c9297232dbc36cddabcbf5aa816aa08df16184aac40a2a3e13677667780d68bf1952b16ac29b70abd3f48c176f45f428625064c47f137138b9b1ed4b967b164a41a2372ad5dacdd3aab11b250121f07ac2845e2a0ebb3ddb94f3c059d5b1fc534a9d3767c057192014905f29ffdf70bff450105f88a1c95bdcd107966670559f2487880ec5b9c47b450b82527b33632411794e38ecf37e6e0fdba85e17e47aba82d6f2772e4e2816c9091d2f91c75d5fcc031b7dd99d4cce29d0466e7f3e468b30e8aa218d9f41ba6a3bf0c7b583e7b3ab37650e5f77cb66947ad4fea733f32f88621c925c887bb27cbeedde9283d543bde731a933d6f9a6aa659c98b07591a082b4274db41b4c437a15eb598c01e5a48b71512c3a79ae288bbc8351d2f65dc40430cfb354d79721c6a4e38de1a65cc0d7fa5b0c12749066604dd7ba02aed20937c5796e6ae6a651837feec5003c7bf46f52d5f1e73b8980c34907cee57b3e9c5fee3c59a3d88a2e695279ea3083bbbea64cdf5e562e48ba12ce28e7c6594bcbb2c8ca30643b5f314ab2e677718964118ccf38231b4a588d4371e6242d299dfffd9f8c043e6c94855feeaab393e9e8c3607ba764c422b5105029b5e54f6f48cd15c63cd96854c7147269a80fbba22ebd7aaee15cf5177bd01bb9f65a7284981261462228d9b1126a4bd3111b24eef7c13c29189e6a0e82021ed090046ad04b3a0752b4650fd435ed356a0aa96d1f44e79269f578678e07284aa5e2ca39c39c55f457c25ccf78a44e84b70789619d9e8bd91a35d074a38006e0feffa290b8de1659f495c72b800d0791d6f9914fc6168793488e3a557cb5e7c246d1b2d97c6c7925b170c480fd83fa6a0be3a56799221770d71cbd0cb319a9fcff6e7ebfcc08ca65f03906c21f8b2360a0acbf0c0de996044ff05e6d1496b0223d665724b9ba0303280a58f01010a17f1fbcc7c3e5190b5367f5b47c1c6be359a89e11f54d243b4df53175c8cac3a1e92f4b9c0d88725229523085e818e3f67a72162c821e25bd48d87ff6385bc2ed18bbe76dd8bdae85621ab23fec91002e48779a0a3bb3a73843222823ae158cf12fccfaf0946d1419804", "ac6352526500ac6a52", 1, 98842182, "581ad9ea6b077080c32b1d6e218c700b82af807b454cf63a45625a5c16609acf"], - ["20aa2c0003e4ce50af6b557b7ca2752b85222d751132028f9bb64d13723013033a9098fa4c0100000001abffffffff28e81e0d68abada0e6ed36ee6403c541b8704fe672b6a7c894bb567e4f25ac38030000000765ab6352ac6a63ffffffff00adfc964a6fb053ac9f89381c3bcfb5aef9124c29dcf21f45ff966d8760aeee0100000003ab00acffffffff0481dbae05000000000152a08e72000000000003ab5263cdb10202000000000152acc0f8030000000006655200abac630000000003000000000000000012e74a050000000094e6f7319ee360653a391c70aa79053852206575be9e9da21a7a4a0e824c9b5457ac443b5ca28e5fc28ed4be8a2d2f707144019ff2efcfd6ff21f6d62de4a058dff82f6777768edd404a98b8ca04d3addccb29946fa777ab0e49cdb903627aa20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021866e74d23970289dec464616b765ba5bd4ff9936d0c2e43184da8d85f31543410190313ecaedec6a4ac255c309576fb4ce8867cf42fb064a7c723057d9f565ec2e47c620b0bf85832fb8f0947507297c2f9e21593f8ca512783c72d45dbaa51227d8de85044c338307960f3ea3644a63f6b3afa15041aa1662bad6399efe27030fd22b30db0e2d39e88df0a7300f1ee556daf6016c04dc1b3612b471ebf0d5eb020caee1404d81bc52bea65ec4fd60685a58816e0841b0cf6be8257ee05cf5cc1a0a1906c9b4633e74371a7a86be16df3533cede4fbc4b38de869c9374ccbc3c09a32662cee2d9e5dfec7ce3c6abed33b1e963408fadda299cd160bb085a5fcd59930227c85fd26af5db4bfe81dc89163dbe3e515d62ede33675640c5b0af6a2c609300215f42fd9d4c021ffb3b87a272db0d371bcbde64c6c483cb35f4683bbd1e66215020e9400ff10513683bd1909786d3db7f3685f1797ed83e0f6204342ecb743ac6e02179357461940322a63c7b2ee325c8b2304feb40f3d0a62bc547fc2185742924902066faf0465440325727a1a7eb2656e0394fd8b7927f44644b94b9584063cf4dc82599afc03f48834804333658e2764bf6b4350a2183c5b7cfce4a3f4511546f4b030c5db3cbb9194acfc09abbf7666647b0bd578627f9b877be6fa38825ae845e3270c70c27d7b2ff452dfd791cbd266f11a500fee056b2079b71ffd1f7613461531b9a4bbc6760496505fb1fa8b0dfc80572849d00c176e0fbbf69cb709c12ef2230d4ed586a6a90967120650dbdbd43912cb686b6e6a917c3cd06aa5a328db6eca47819a5c6b47c8643a055e7a2188b7582a800eb0205bbb21fc7bea7a45c1e2320ac0861c3b5f082529798f54abc70aabd5d3f9562910e2f0e8e2e3c4d342a97b3202b1400a1828ddd43c73025996730fd9614feb864179d41880e88173023b27e9c35a46c9cbd3552ec6d0775b9fcbd42dc7cef799deb74c8f16695a2aece9f4b0c30497ff3b51c894735d7f75ad54ad29dec49f0accb24f8587ce64417dc3f65cc84d15dbd1ab6815ea4f83032f9fdc8a1ea10220d0fc8aded10f5bb9cab10c8ff47ab1d41bae0ced760f45f672d745cfefcf05a193545be4232df1e099d61c93a43f288fb10f7f2e7bee3074c4f6320fcbf703f86dd8001e3355edb84a62cbcc4e22a1f4d58c12a2200aa455883b483677985fb0683928eeeff5a378fd43fd1f9daa6f3c461938e0cdf9c54f63fefe1f8220b8242289cace97165e7e67a7ead3e7e96e905748e82249d63c36ec7a8b1338b73eebab80121922041c438544d9524b2e219535616bbf6efb49f61ad0809893e7ecad1a235980e593c3964a7f3c611762dce9563282d7711438b1f647741f081948eac8d3b25259aa089b55df3c8938f65a5de94d494a102e41ec3ebdb50a112d28f7ea8285d5544d3f6e351a5f85fa39865a73a05d815637975f1004b642d43b354bd58bf17d3bd9098962b0531257b6621008582a660a5d48b237db74345c3f4cad7a83020b7c3ea271553f6c880789cadb73f046927c1f81730b8757779be3ebedd6c4925fff1bb7b1b9a2c24913dab5eafdb4bccdc1680d5b8b8a1e1ee233cad1e365832cc6fd3acaa5eba52ee8c9796643eeead58c95b07808b26597bb92af695c5766a7f2a2ff7d82b79a75ea19a31b75b53e754b8e48623d64366e2498900e1f4de0f412de94a439cbb8d535a2ee0567dbc88f4d5407b33ed3d9e6cd0260e579aca7d0a2ab6f693ce58c5557a5cd916e8fae824467dd8372b227c2d3cdee7315d0e165db98c920c9063c35222973ca2abcee17ec3cb439b0bc5f469369e516d63a47056df3da38e758d75a1bb200bf540db0f4e3007d56fd7c8af9b8b38a6cbe5afc4f48402279a2ac3507e1fc7a20d4c4b74bfaf8307493a44feb927eee938a46a8c9f162a336bff52e1980da3d657500397ae387481c2319a5e526827788e68f3992d9325f0cdc464733a963480fbb671eda239e06fa8fad59a426b62c935de587e98a68d75d3402e7da5b9918fcc0f5ee7c43ccdbe0d508d99a58264e0f2fe7c4cac6b5295cbe55ab927c42b66985a313fef8130fc9e78d30321365fce2ec070841e1624bbfeaf1c603582a3af3331c163e601a5e32243132e7e2d6d3dfc1e286f6b7f5c04f8c13fe14e43561009664aaabc4c507f2cd14c8950d16a49d4ba83b8e04f7f48b5365e8edf41e32c234d43d188ad5e0c9e66a638d783098807ea23a8dfd2cdafdcf20a7485a4ffaf855844dad089c9e5d2ca83e0000000000000000cf8dbe0400000000204788050782feef909a10217cbdda364e7635d7032966a3780d99fb693d78bc570a446eccbff38d8af11a942a3a47c7b86b6ec29f168e082d4d94bfddcca896dd34195ae2259891cb16ec7d05029c74b78331716de3591477b04464a29be5290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091b9b6ba8536b7a39f45552c9fe27e72299880c2975871e8cc73f959c454f23e2d0c798161850216b323126e7e4fafcd2cfadceb029c5146b8837aaf0ebc3ff18d5755727d134ac8b130b4f240ad62e966419ed4fe8f2333a01492a9e0efa6a04879700c43e2792682aa5550916b0c1a1c01d9e3f297e5558fc756c6cfd499cd020fe005d7c20f38e9913f534d8400f9a089da58bbc4c6525b1241d49ab967873803279de6f3afeb97437af3a9f10edd1a0e8b462ce294fa3c18f13d194174103a0b0b20463ca3338c3a9facf5910340214daad9e283b2ac974233b8852e99a36057f012a2e13abbb65d1db6d440b3f0bd1efc9f264cd3bafd88530032b39d339437240207eb509744e50c0ec0acada3e42259da58d6579feedb68601e13a66e070799bf020257847ef166a143ca1ea38de422a7690991732884ab89e82f2144212d95ba720322e2e8dedfcdcd336dc2a97cec6886da0af85f4ae1c746121278657be8a08ec4021a390939fa5d7d4c88ce4227a4b3666acdf2f175abe3b5820b2731cb6ac76b24022880ecc6c586125470de4f29cbaaaf1f5c2c1638a8d6824a52971cbecdd4ffbe2f5ed205d216557c89dfab4165bbe485631fc21f818b7b29d72e54f4e3b3bbf0d4b391290850d5f1461b8b796edae50b40144b33338cea50462ae5fff4c519ec0b631cd51f9ebbdd04eddc442e8fb6432c4ae1e6dc576b44033a46e4db87a85bb4ab63d144fb837ae6261ef551a2c2e8c85922ee04e6d09e83e14e3f47dd0962c277004301b4bbc9ac7e9aefdbe1e94808a0007be5bb05c1950d901639a08068fefcb5a783c6910a30ad4d6a7a0951105b5c6436e774df310a40a6120eaa36989d0b52239e6ddef11d69f2e13516c0ee0fcbce5851fea083e1d6a7f9f6cbe1b473dc3559a510699a75a7ad1185c696ff6c343cf0b5f6929082dc5feeb70cd34f509ed38de5bae6b1b309d3f012e5119c3b132fef0bf00b9d6c7d6fbcae6449fdbf36bda76fd394a7c6defa80ee8747b8825485a336e2c12db9322b05ae751de5b1cba45c0f2515ef88702adb95633ff0f3163dfc747445cb01675152ef72b98bc80da5874a916df3270805a6094ebf08ac160f137e2884d4c0821622f299232ab412c6728b9769c5bf3774f461a800c6a63d3577099ff315fcee7b08a23de0df66e129d78ddcfaa68ce2c6feb6aaff74fe63a649c953fa6147f5390b48aee818f49b362cff46f6bccf556dcc509df1ca5a1a5393abc9b08fa78476698e8fea1105d810bbbe9ec9b0783ce1f0c2bd74c1192f3d3314b6eb17c60573eab3675279aafc6685e7eacb03a90e80d7f747af0f7fa731547d3a4df71628dc81a1319f320460318d62225017ebec32d3146aafd0560a38fc8dff559bae920669767753469e4457b0a753ac51846dfcde9baadfea8311e2653299c1665fff67e8e145e77571e75b849c2d1f5d7edb7c7265f61a5f57ca2d591a082bdc10e86ab8ecae36153b0d1677aebe43fa0e374580a924c1582ce3f1555f284d9a015125e7467b274994c1c7350a9d0178f482c7f983c686ec65bacdffcba6b12eb3ffe8bf06eb47d167b2f51f5d2113e2f5a8c84c0867ce4942079a70277ac4cd7062ac9fdfec5b10637630ec2488a79b014aad77ba787ef89062f2a9c72e66c3b92da3d89cb00726049ae8b80aef6035249a48432b3d208cca4d3d07d29478ce035f9f07da278ddb5ac5af1ca87fdc0e407d6e7fdd2bf14bf82e20488bd09f781f5e55ecc78b142c89fb02198a91f172b77cdd2075e1c0b6bcceea43a7c39f1c1afc8f0ff7ef559db82d18b2cbda57fae883d36c50349a65ca80fb62d9436c28d33c538ad02b5eb60b7f0aecaee51a540696242712234eb1251bff3bc871c1ecfe1b0adfcb92c5a5bd25e2119e94d838c43fd5cfd8a6d3cedd15152373eb531b487485d140460e3c504b71e8eeac9aaed9848bb3844c625831b5f2a76541b277f4e9bc52c76294e0486b4e15f63e08957a32586a16e8d72ef773e1ce919f0a0c1c1118d5a1bb89721c2f90ace007c0414a7534aa146c9c1411a1759d8e883ec6f0a9fe9c3ceb8be986013b5063ee51008132166c0fbe2740b31bc98aa9b73b1d62ad48beff8b3ca2cbbb1f1bd7df8955eaa9bce4ecc7c52f7676e8c6aafdd6eb81ff05441372805692d232c41bc8268700ae9d1d138c6f7cfc61ec0b38a15a3ffadc2d5c82c4d1103ac632e4decb1ee4d489feb3ca042145cd9bbe2ed34b4ee060e01aaf8ac879bec08b470342915245477373dea2fa3a39ba4300000000000000009f5f8505000000009f842ba0255512379ea8478eed494f94570afb8973f87ea4a7e91b2887b5c61728ec20f1df88e81a5617841e4bebb037c22790184d95db097bb5e42f2121bed1a3de2a4ed83467f6584af18f46c5ed9264c51dd66a0525e410b3d0835bea68ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3a2414af1ef0035bc0663503e4830b3b3fce3b7f7562ddaf5365108b94b37d2c824dca061c7509a43d1ff17e7a1375bf341452c2f0521dfdea97158a1e472b89f1b9d4ac852a82e15117d40aed9c9ea3ac70d0481b45cac131a94a71dba668375af0158da84a816507538c5759dffad9cd9bd1e243420d554b7460724d97d41032df5ea050489f570507723e32f856f78040e284f3616c5f16f790e6de0fd292402030b846dd4dc4647bceae6deabfd501ac9109bee08e3694cb988321c59e608420a06561e0d6efcc68489ab818d58aa2cc5419c807363aaa00a1bfa66c366ebc1da1919e3b0d0555eeed9f934c02074d9a80c9e8e21f8b9efd3fb417102960a38db032d733d49277532bc2d0953aee95d484a22c30b09756d0e6177bd8b617a86cb9a0302c1ef8981933846d8a36e38443746e4ca327a3267945d6d5057d63bbb0650150228c3e64373aba70916f751522e456e3dcc4225d97f9d37a4d6fa93101f9d2f130307b65582539ce38ae8c9aab5e76009695b9582e6b622231d242629dbde2883a80309e031e771b5c59247191332efe6b9c60fd93d800cc3d993149c5dc7216a031a98c880d9cb068f9a64a8d8b011a05d0d3105b49e4f2f96c6b889c448491af31f740cf8a39375d5c0f1ae45f5ea65ab6e3de87639f76fb6877cc8d2268512cf178200c24db6a7d4f9bd0df019601ef362fcc20ed395bc0fcfc4048caf5247385e71b4139e3990769bff266e556acd870745abdaff6bb19c200847f2fcc55ef089e7473f46e0457c9becddd9ab056bde83b8b233cee8f13baf60114f5deb99424ab7e6acc2a8becbd4c8255d8e828a2da1402e2e051c75456fec95612f8048fd3a17ff11ff3ca8ae780888293f68d10666c9a849fd6b3b5d960e271e7d26bb8b8b7ab38ebf836cbd22eccf5e9e2f6d18d9525abd182513a3bb09e719ed28ee7c2be7292018850166c9ac870605006ba951b29cfbe95d3962d55ccf5dd117ae58cc20a5ac3fc87f0b0cd51a3cab0d906ac0ca3eb3feedcff2089f7487677b13e6fe453d74166155903f3a63dba03599ab90e9e653c65c38e44210835b899d7246433541130e1cc7d5d7f8d66ed19c282b04a91b5af890edbe28b8fbeb0b47b423d414f447f06e76e144348c18b2e2119bf5ef1dd35693d0231f42acd8dc9f7fe74bfd5e696abf64e991b2a1098a640ad0e5b44edc4422c9827e267765a1350d72e665d2d3fa1e6e85232dfa11bacc2aabc355eb58287fa9f95d8980ce726120265a412428f858ca7eb16b64b764c687f4c23e7e312104e28670c504f85176a2eac32a0097837dce1a7fbcba882e54eb8c0f3880ee27919307a54d93ebd27e898cdd2cdfc0a484083c900fc8603df05d22ce7e12742173e012a3a9b5bff8d2192fc21b74be0e29e1fc1c051404b01acbd2fb6ab8b037c826842f487aa63a4fe09429c3e08f2891e57cfd0fdc8e06ee3ecf6300041d704aacedef452026a0bceea1e5ebbd8c5e89e23d70fc8c9f239fc1812304745df0c7fb0b9e19abe3c84e31e85750b27a562d4dbc1dc7decd4968a30a218542a5b2601c05c3dc199c40ec835b42fab2890906a91ab5a5a4a76c931d2918048d94ab8b6517b921b3fc8b3e8400787e8d87210c0ba7a096b5981545bc83f0bec8ccd4dd05a3b83be5dac8cb7b51040f58540c6c3e5c5fb467ac4af6cf6a3f32ba4f6536cbaf34c9cbfa2e2c1c078b3ada7d2fb3d1186f8d4989a00f9a019ac24cedd9c0dc043ff2da833078c74a259d706eae3fcc5899c454d6dd88663700c611a8e523a75bd7b2709d1731eec7167637c6dea13fbe8a197a784aa9c4b39292c5e549c8d3765c81edb09c40e1dc8964c4c2f42999b216e2ad738cd5729001bf95ae7ddf6e905fc119b0c5baff276bc74450dddc51fb33a44140ed88cc8e94ad60b324d49a468fa52980eae83350da444e1af6c0ef60b18266476fa06c79fa7997960a450389f4ddc1ef369f0202d7992223c1927fb104ff450ca4c653fa435995dca4f9ef6b9013e4e4af41ac6859541eecd5810212847206749dde0c1314559ce75eebe421054b330dfe3ee4855c31a5ee127081629e343b8acf580fb5a4da7706811309ee7fa8324be45f0dd7295e21e36a124c147aed8101ed4f0ae5425dacbc1e33c50a63388706cf7befbd8c390c8f3a5d27ef1b98bfbefd7d385524e04c078956860e1780bdafcb9fef85c9a91fa5a81c2febdeb255527d2eb0dca64f91a06de8c9f05155f286cb442dbd9c5a9f61937f6d2153cde1aa39da9ed47ed01b9b69c93b490ea2f36218a1925e940601912b133f39c1fbec782b034e07d01f7f72affb5de1a748cdeb6683c1876c64a5480570b36f20aee910432ce614b6efc4f06363f8103885e386aa8cc1c1f07e919035897b10863d972d06ae34bb0da90c", "ac", 2, -1372283481, "59b364a42de9c1341712329772482c71b301b4966396934bac9859967bb24b65"], - ["71050a7501a58c8f0924234484267a2bc5161d45ec76278acc7cd1f7f2d6794db4a62fc61c000000000963ab5252ac65ac6551300da93f031640f104000000000853516551ac65526a0f7c840300000000046a6500aba06b2e00000000000200ab229adde500", "6351656a00", 0, -1864018183, "61a699765d2084b8b954c3bf9c3cb915018702c7195420a63f262be60647483b"], - ["915c7bd201374b15277767f331337804b05b5d40b3d326ef1a7cdb89b20b4e741787aa89c103000000096500636aabacac5365ffffffff03e50183020000000001acf1246e01000000000553656aabab40c7e00300000000035351534c57863c", "6a53ac5163536a", 0, -1095091889, "071d3fbe623395be3550c456ddc164cad4d35636760730b5924b736e8ea2ffc4"], - ["242bbcb902e8e939bf1091494df520fd862f4e41dfd6de90f4f735d91aa62d32f0719e0f5402000000086a00516553ab00aba27790c24d562d764a2433a3323205556f91187c82cabd28453dd1c2cce5ef579c36638c0000000002536a0f169275015a9909000000000005526552ac53d5569a9a", "5252ac", 0, 99349162, "fbf374afd532389fad9edab612fe371be40c255062c75599ff83470ee5ef4a63"], - ["65c9a2e0043a3e47be6986ab25b007001ce121a7192a6a8783a141234381b9b59bc88463320100000002ac00ffffffff308ea3d3728cf8256155f6f88f96277f1ee319319857218cb4f924fcb8051eeb0200000009525263526300ac630079bb3bf3babd3001364109f96409989d380f0dafbcebce43b6085b8b1d97bfc66c61dfd200000000076a5252530063abffffffff9a29519905c81595e98ecf37b3fcc217ac7fb5142824810df839be90898bb7690000000008ab53536363ac5165ffffffff02b7fd8b01000000000653abab636300c1921b03000000000000000000", "63656551ac", 1, 596457409, "71b022c1cb29faa7620aca470a6db85d6c83d063db3184c5bc559e3edd00add4"], - ["26b33cce026f7bba1ab3f419b07cde25c0f1f7bd7a474e31586397e91f211c22b0782ff9050300000006abac5351526361d7fff952ebdbc7d77b9107222711495609e1e1ae371ef9c7130c777ef6ad984e98cd69020000000265ac76dcfd6501eb67b1020000000009005265536aac65526a00000000", "526351", 1, -1070540843, "a95658e37fc00a99045667b3deb458e478a8cd11956fa18226ba404ed06cf9bf"], - ["7947ba71042806084182ee486d3ff89fdb674d85c91cea0b4fa73e7a4be5965340debb786002000000085200acac6a000065382981eb6a108216df4da7079bec0baaf2050abd8b72778a2fdc000d307eaaf261f2cba50200000002ab63ffffffff86bceb91eb764b4c388a546a8e877b3f3b16066be429925a60b18c3becc5376900000000066551630063654958fe3869b2b4626d8b6d0ac28893e648893c35aa612e821c71f9466169e4e00df7f01601000000086aac526a00ac636affffffff01f4084c0000000000035300ab00000000024cb7a903000000000000000000000000c2786419a62aaf7ac7c1788a1316e2a392b5be2d76f362a7987979e8176199130a690fdc5e876895cef176a021aaff601266b00f6c7b27d582e17b2054840a70a6c466ff5b40a76ea1972f90fd922b4b1b0b07ce02c1c89c3104d9aad715801e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077e27f7a419744c162532649be1c8098b6bb9b704aed0e05464afbf8a6bc443faeb029e8436cf57671320295d5c09c89b943b6aa7edd3c8957649fabe128a8a9c516e95eda16c5372a61b003983fe1e5f1d42e03d79af2c7f7f94d106066e5c1eafbaf201f4db8439654abad5fd74ef099c98ee519184a54e06af6d2c43d27840219846815268b58ee6a384d1ad940630c511bca67ef94fa3dd57bc0daf3d6f0b20201511c15417a563e21b3f46ac08f210fef4a468afcef494562c44e104a0ec4df0b16cc79003838493611720c11e942b7c6e081728ac0d150017a7a955ab4cb5c1e29e2c19a4aa96ad9ba614ee96dfdae308c390335f08e18d56da742fb52b58afa03055d34d4db672d43e5e95d7265e1a8a7382232db42dfe1031f13e3d49bb8ca1d030c343634c53022cea4f16f7ac759dc47f6744e77482dab5ec4fd1cc998b2212b02252c52807cdd86dccafd41e1468fceb924a7eccaa7b45106887cc912038ba1ef031fd2502b662622cb6cd015cae8b953b1916b0ee8c8c9cf55bd7c28b87b14a2d4032b07550a5d1ee3e756ebaad5dfa356cfad6d1425312e98917d0170d28ed15184ea539e90ef7a497bf3b33a09a0b92d368024e92a7f959692638e8e1fcb6bd801c58aa3ad73586fce6440452b79c1b56a14cbc1b2eeed6276acb9609332311fffd13f84d8b6d8e16864e6b26b8a21620f95cc0ea56370b961be167a67e7f45c0b41b2d620d17752e7b47a3f79bbf66297e76a0327912c5f8a1b9229e77edf1469816f9f11135c3926649355735a0dcc49169827c57e264e93f0c61cc4b0786b9f7d6ac6fb252f9f5a1dff30fe36463a6f3b122adf2034c6920ec008fadca34696d3668c20387f1eb1027443c2c4672ceb94cf03cf376d8cf21d9eeebbeeea54ffbad474a59384f5da187b84881704a2701d721c95c55d4e03a66e6a25ab1824cbee4fe693cc739b23d585f9d1fb369dbf38f4e2026e11ae54880878f66f3cfb571776b49babde1e6d70178eef8903433b6c377ee8410f2f30a76501d3b5c6476051d3f859e08964004827be21491a2481a507a6dad4f6be6ca30621c98e0677012f97284a148f8f911789d3ab2b36681db7e56ad1188b7648a144f58bf865f5a578d9633180cbddd393c33793a6664a76c72c5ea23ab50f83538cc0915fca91c6cac55b0a9248bb9dd3383e3979f685b58536d9361fdd99baddc7371e84b891e0cf4ea56e38467e8cb50979518e44935850e162ded64cfa533205cb367e638dc1362571dcd91e4ff606c20999f4880fd1075f3c7891b69aa0e521ad163cdd69969f119b2ff2383e896502406515594b4e0496e997c272eab30881404df602daf5d8f37aae41f8d4ceaf8d15320d5d41e0176f4922650b64026a1cdf91b71c004c5f58bfa0bb1c4275716bcdc7c59858d5ab509688f71ed732d1090a87040355f50f06a12e79c37fc6593d2ffef7df45c3c46451ca02ba42c32e7c93b1e330f5e4f1afa9139dc77a9dccbf5ccda74699dd1c63d6b751b64fd10b556f1be930f0617e21d5abfdfc9c883edad56af0a3e99677725d3bc53baf64a73f5c9866c8226fa157030dad27bf2c1cdb3d9a3eeaf4e141890be563de92b47626690ade55f782ecd88cb01543d4e10c57e10aa8252dc4d6a0f602de56041d7208904480542bd220ef7febb1a82013cca9bda3ce7b891bf996f14e74efb2a8404a499d75e256ce75d9f61ab6470da9c5827b41dbc23dd275daa1e6659c790b20a8c331a8bfd2e333999132aad613ffd923877b21dc8d27b8ae9b33e4838ea6ae9cbfd6dbc21e1d80d5ba3d04cba02b838c660c5d16cf6934735f4f49a91043580fa876b4693386c1355472dd21178c3b3fce9018cd9083917dacafdb9f6a242eabbbbda3f96a069626d50b9e863d1498e3a74c02b31e7b4312fc8b10349c2d527c6c3faa68f1efbd438e68a209e4b36c9535c97a7781e40230dda11325aacd43cdedfe49f737fbe56f985258e9195f5621a160fa9611ec9e59bc56049bb446afa7f0346f253d2e91d5f76b9e869202e53d8a1077d49cef1682b9f4cf2020f479386a3b8380ce878d9bc4dd5e456f8284362259d8067a57f9f7caaaebc15471fa8d546c6f24551bc0c13c36785d79efde73f82f247cd5f738a9271af701f646e928ac28399ff03998502873a39e516508b4c76b40e24dc21c16e916c550827ba7961bba74af1431bfea1c2725f1a53a36aa77080290712b8824d2a791ad528b3fc49e90d2220f67c67dc7ef4f9d89b276be72130b025e40fbc00000000000000000022f890200000000b60f439c1bfd63ecba78779b261ae6d9daffec0f4122fbf206a14607a7134fca27f5cb81975589f2a8931729e88f322d82b649f453675798fc9b86848f6c1038aba87bfa06794b0886accdd81460e77c39833067d650b51c2846e9c5187fc09b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070439d464b4a06ec1c12bd6414e9210ee34ca5fa40aec3953cd6b70c6353f4c7a8d659ecb74138e73acebc6274a17e79efaca9ad833e16bfeb156b0808bfc604f07b58352fc7a7cad0f7213448ee842dadb6352320f696ba433eadf11873fcd128b04fcdd9fa0b24287ce2e2e0ed6181bc03fb6cfa27645bb4b9c684c876ee8d02017075cc4a151ea3849b6cdd482eba2e2aee9f076d6a63bbfc1cd3e39526fd3d0316e81f1210eaaf529af05d18be446668d5c0cddf8f99f85e71a00a84b18f46fe0b22cb46821583c7eb03d8ef7b41d07858afed30f7c274abb10e614e988abcfd4d11a0644e4e9fd40b883b05ffd26588f2b98aee192d70248b93c89bbfdabd6dcf022ddcf5beb477f1d1dbc57c9ea89d83fa18549b159d8e34179d2b06b49e57996d021a36dd5e47f4a490600b5335bff98bf8b935d3c232c31fdaf8149a0c66f9542c021187330d31014600e3d4873581148d36a2e4e8576944b2f3d9977fbe725d296f03104be871a018ea55267cb5c46f1e683f2d18b0eb383e6932d1fe285b2de84f82022ecfa4cbcf2f6b76d5e75bef16c1ea994355bcac1d007a16d49fca5f6ec30e0979c2875b8695fbb6c072363c9ff124ba87a4e0eb476d942cf8f50d1ceb6b93f2a4aed7a204c1f59a345e60bd45e84c2c83c813ef15f42870ee4dd20f9ee0ed6d265a4a350e4398c5855045b4c7b343fde80d9be202889962882982f4e1fbf0bd613b2d79a8784de917eac794feb85f6e0618fd427740adfaf2b9ae96c24a8ca873ebce199db9b0b15ce25c5d773eb4c8ed9da3180eaebecbffdc241de78b7e57de20ebad5e5b8bb378accccea235083951c29ab33f3e6f6ad1845983b3a18c5f6514fc96d1d4ea379067e73bed25e01d609d38b70c0a0f4399b95601518f8b56ceda71f46433c5da864b4ea14cb3e94acdfbbb425af383ffe9c83a20617dd7ac610a5c85d3a7f468a22f63a1240c015b093b9d1888ede22cf1ecd8a9968adb9136f789e0edb45b55fbd5fdd7a894df09a14265a8a01da4fa466b845126821418adaa31ff87e18fb6ffdf30b2963e04879955868cd03e96028ad01f6d2aaf9c6df7c5697f79b3758fb377f014664425ed8573b6da5aeeb5a9d65d063e2992ff9169394442ec1249c0504e4c0d4e5dca67a8b49c976a8a7f4f06022adeb40f47caeffd21f607f30f916999faa514c56c1f064f96b5c61b358a78f01b9a0b5a9762ca5e6ec6e2d6988083185260d2f8fa89f6bd67cffd3eb0855e04c58d00ecb982a5f46a87eee48af58ca341ff7c6442a46e8f0039a89542cd234ff5bc4fdc700de0db25bcb45f02546a9d0ac80328bb0f065ce484982d46fb8223d849699de551bb08d07ae8e616431199a7f735d02a78da12843cf6ac482308b2003ea605f4ca0b16076f9ec84895b67d910f2e2372bd111fd65415593992cee426fb6642fdcfbdb7a3eeeacb8c7809b2bfb34b9439c78dda8e51846cf05667e4d1e780dc845708c59e8baf5093267daf79cf888511220386c0be053e56258a90d99abd57b2209959223c9ea2bfd4c0e39b021a27e077ed97afef87eeae4d72f9657d47a07c55ed8aaa0c8af5843cc4a97fa7460189d87abade83471da35656b6a2b1178a4d4ba001acfba54e70f77eab4441d7e8f93ec750dc8a4f67d5d5d56068a7a20c3e282b20c0dd09fb2f55a8a243e9ce3af97bb6612f4ab266ffa738051fb8fa680971586b9578c4bc2cb7f3b510b9c57f2158cd41d1dbfc3deb43bc10ee32f5ce1f001cf8395839769a2f0b66a3225c6165721eb6cce174441661229b1281b2d49bc39e9e3c55da7700cb6fcc0ad5ad5e73c059f9f24e6c5c67dfcabbb45d21dba81663f471bda95b5772db483832787b626ad8fc02107c3c6f4c5c99d8b9459ae9ea83875e1e2d27a63f08f8ba90b42298d7eda032c035a9068e2f23e65bba9a78e8fb1ed20c3253ab8543965f28b7bbab033f1d209a569c51bc13d1f9b8c31d990af73d4df03f6cff72a4eb760b1886db3802226fedb0c4700f47bc7e61b9904070aeca79a68387e5c8c2e0cea572986ba6ee1dbdcd9180be185b136240cdb02056585e82a1956cf9232d3d138e29c3deb1662889b2728af2f85fd025359c62e8c41fb26fe1f287eb22b47e26cd4db564176a91aeaa36d8d3e8688c6ba62c4b35ac79b5408b639dbb6dc8b4dbf020f5f9046f22419ba884dab5ed8350ddf4412f747c7428cf58309e4450b7b4636b73e5ffc20ff224172eac07e5287edaf770731f713b5efe81bc924e3667fbb19f0e2335986f0b067e43ddcdc6462eada5734783802d33507463fe1ba2c1611c95b50cdcd426451cf2c8001b7bcfcc87894d4da613d448c3ed260d073144fc0c196853c1d289ee97d8e9893f211af0941d5daad2c99b7623e6beddcf36150d5c3e1c4f420e0e", "53", 0, -1676254180, "96f55243108d11a5d44638165ceef6600e21d320462b7873aff4b6d60d0d1254"], - ["878e93bf03da8ab76e0290eb35a10717485cec2d64997d405d23b63b98d56800a8ac123cb003000000095253535253ac6565abffffffffded8f49b6c83c8ecd821d4d29c563e9827be40e0b3754b556edf3acb18286917020000000163bb81ad97ce483f2fa49ec39505a6c162aab7eb87f9d803fe0e6046f1a632c39d8d0e31680000000004ab650051ffffffff024c3c150200000000026aac435bab030000000002530000000000", "516a52656a656a", 1, 654153698, "22177338e483537aaec208b340d798531b3dc71441e0a511985b12a5ca131c40"], - ["a439457a0180964b4016102711a923ed926d4227c875186b2bc24313f1de550a49bdff90f1020000000253006f90d107016ce172050000000005636a65ab0000000000033db9d4050000000000000000000000009a8ff768b7841bf62dcb5f6d42569290591f12be16385780ba1ed26a9a1d39447847697c118a9b8eedede49a0560c92983fb7c7079bcbf8b04aed3d638bdf75f3f2bf8b986c8848594ecafe28ab46716d5da43f2430ad9f26eca0c8077d40bf60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000089032c5f850d5e98515dc1a12b0e7587f2e7f8e08aa6f89c87ab7895f7a3b4f884c1be66358b54f171107ca193dcffc5d17fcb1a9af954d8f3272bf0f4dc0f95fd8ae138c9af028df7931f6252921a6e87383a281c686a0b8ec32a552f54d0cc60ac4dc7a050ede354da7339e1826b8e505ba69f1a77831ea141eabc34737251021e50a34d3bd2880bf4b290503ec9b3bded96129823a97efad8ffa83d83754b080324f76f42d94e445f3eebbc01612cc60bbc5a061a3150d1028f48e6f3ab36ac1d0a294e2e94a71918c922db2bebf00d284acdd35fad95cc14e64d48e594e3b3dba32ed990fd3df8c4619a6732cf6166746c72d5237d84f57985f3cc25902a33db28032fb0a46ec99f53a680d165f0a2045157066fb3a27bcd71a752f1c0e96ca55751022f69678e44d3b55c6638cc1973adf184cadc95d2aa95c0da84a5ae769cbaaef10319d07e1be12f3572cf8b530b4fe324c3c9a06d5a22b916690a8a27776598c7b30312279d9eb42e73ff789cf3dcda44f5f0afde88bcd8ef9807045a8aa1b82b7a06032309228d8e3777b20b0e6fd90dd4044dae5de0cb1d27b9ec35f2e91601bd22ed5a6630abc9a9cfc9d38c1d36f3d67daff53768dae8d0de0e84210ef34b5c80574b9e706db08a87224206c72eb5ca0b901b7dbe662061b7ea83a4b2bdd0aed85680094fc2edba5a2dfe0e305328fd27e1be92df94d2858cf90e4d869dd79965b6eb73305bbfd8cd477f5a06fba9655e8627f5efb833aa70576e90f5990a01bb4ae86686dfe2cce5a9295b0203c3e6142a4e2bbfe86230d3e21b7bc5206274a3e1ca0a8e87df7ff88f9f74b91edf2a6e94affbfe844f485f9c758ed6e527b5ff7a7752abc355db172b08a84c373d2e03acbf39ebf6ce321a4112863af4ae09616205268544ecf11f546acb4976388cabb74e528e8a648610e39d6e3b9ddba99694d596e15189ce2a9036b9f0bf4789aa94737e88f26809ba6f97be31da0cf0667fa69b9ae92d9e44f3a192016ac576b11eba5542c38d365b340de2241c2ebe55d0906c3c2d0ea9048cfd22aa290cc2ed21a48a774e6f9b1d011e93128e1b4602f18e0544ff4b77a7f82cb1a80e5c76fc62366ee754f7973232515562564de833cfb6ba360406a4f753c5e39986acc1c8061264389f69375f179229dbffc576a47d290480cfbc780125c2ad135a8ecb4627a26f404b7f8a8c9a09b2a69a7c960504ea5566a87cfc0ec235051008d19a71244ef72fbb39ab54359b1b97a210591edf8bf5c97d488a54393bb605bfe66c5a34d0b4f3427aa1bc29f170bec4286aa56d678ef916a361ede7740f47e53bf0066f6d23c3779c2603ab9a4c0f033f335444f0bbdc22c60edf79cb90ad9e62024f12f0a5ac6dcc079eea6666d7e364b73d231e25a63129449a0924794685744935d19c2870f66a9fb5620fac95045809aaa7dbf347c2e7796306c584ee61f438c1ec843654d67e25b103a12c1fc8ba8a49fff4351c9f2724ea49cc4717d80dfededc59b522c98b9d72058958910f69379ef6a36d341942873b7d4755da87c599eca42bdc3bc73fc16680715260ac0ca5227a5e89d49bed3facf7d37210abe0f83778fb9f850dbae508766e4adb879bbfee180d951b201d24d3a2a9054eb93f2e46836b6be7e61db100a2f8af52eed87d1afebee0ec27f95ffbc5a403d433e04931e15df496dab0e02084c05322c77e82b796961ec9ab1b47b8e3c5bc6c52fec28fb0c380712cb5f226d785bf6c744dff89d0853bdb4da71ec6d551b9f6e40bc76fdda04732d124132a5b050bd8553dcfa37231e4b426c7805130e7b6617f1f65285b867692927b5d324506919df0bb66ffb39bc332f7ede8d2ecc4aee87252e19b821ec9b3ab1fbe91d1e8bdd9c0b0059e09183688b175ae143365d93470b95e068e8621714354aaa6debef4961fd9f2ed54901e216fcf04a73ca606fc7731c0b4244d081fbdc6b2ab17872cac740e2d103586aa3738e7c7f727330d780ee26c74f20394cf144f2f3083a24b5e7746b881762af99dad2b7ad5de057d9233ca5d127f48049d0d2b18e2cd43abe48c38ff7230eb6571e7f3a5c8fef38e3a9d1ff883e60cbe6ca7c525c849e42f6400ff8988a9c394992b1ad50510870de615c9222ef5df28e69ca0e02f1ab5e1026453772c4b31658b78d41bfb13438cb9e123d4d213835eaae761c17e2f1dc7967993261ed721e7f1185cdd6f34877fb678f5c5ccae4ec3cbee8e2e4de9ba28d5fa200c08ef376c3cdebc09c7b5672fb1105cdf6c2a83f0633fa003000000000000000000000000c1f8762bbd24396b1cd7c42123d9b58c9b3bb43cb2c1b9529cc4f40fcbda2b3fcdbbdab78d9cff090f2e0b8951230c99f62d12b11ed3973adae4a1418bf9b50fdac7cf402b0fd7f9d4f0940054ff4f7aaa0118b04949917d4b68ef458ba89c07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006218e1f3d49084d853570ad68f43d6212c45833d5056f9958ba794100f730d9bffa98a38b06155b63b1ec514ad6cd044f2a679ed46ccc6b6770a876c0b4402950ad36272ec9c6714deb6798caa1f8be56caaf91df415ade30aefd49ca2d0202bf6327d1e8d1d33d048a7e71698d4d9040b794cdec46d42bbdd51308e9d8a5797021ff4f128f5ff1f674d9e3ab8ad0b636d09a31b82fdec2cda9e4889c4e96c413f021c83fac2a6188edef19e19bcd53de4ceb4f5b97377593c3a502ce99d4a9ba1f40b1146941dce85d04995518d9d9736842b023212f8194df567d99c78c6d3b8976f032f49f3e302b94075c087961d4b66ff7fb5832773e92a26615031d859ef652c0321212ce6a1790388e28bb7e60afdb6c8283db7de1c25d9b8c407e111845afad0031a6c5c60ecec70ae3fe8316f2b643cc1d0639bed325258527e4a6cdc0158ef21021fb2367223908666979ad39a86fedeed3a9ca3b06bc7e2414ace79b022c7d5d1030bae5deb43e9e26ac1140a094a5c2cd00aab64e99e2bf40dd6609a4a5bff8c79021eded15b99f507a417db2113bded7b726407c917fde30b63a53c3928e1a6593ed1eb64a3f02aee3c172b98dad2807e19691e526493f42603e437e8f2e30f3a4f1a379814683dbd2a5deff7cc69ad158e18707f339370b00bf010b5c5c4679934c03c6408de0fa5dab2e4ed40f96be80c3c4fad7ce1c4d365e421788010f2538957d5f774cb5cac8a386002de4c370dbab19cf9369daa5e7318f5ee07281a844e5337a19a2eb98c160c5931f0b6eec2a79fdc5f176c17e93eb26bfab8eda86b8a6d584cd271f41f18d9046247d4160805a8f2fd7048218d3f219a4adc939c971024bb026a309057f938a1878166a029ea0e5f66fe17bac953ae89536d3a2f9051cda00c9e282cff4347bfdd56b783e75b7ca8e838bfdf9f72c1b84133dab0461b53ef13a8ce6ba262c613771d1a7e39a2b6815fe6155945f4a95ec8581ecd2ab60c7894cdc4b1a58a5e4473fb77081ed1f3533bd06cef78bd866825335fdc5e3d180039380ace265e4538a304e930d4180c31452174408ee40a06b2ad8496799b1159dfbd6e8ee9981b6cdf3b400cd8d32578784946311da4bfe81c50747248068d7a7fc0e5998c6c46dc4143a000ece438c20917ab43ae0a33e7e7840db9b9b13372048716df912409efd95cae2d545b9bfb165aa3da500a019fa25398081e8900798db73a144efc8e9ec96a990c77438fc1980812a96c1164d9b49326c124f0ed1328c23ca897aa47d1ddbddbb0c9489bf51e6f6e44e991f59c72c473aa53c7ddf0350df96858906a395349bbf255efaa9e067db63554a6c9126e9d9119bd27c140a6b15e89c10c4d65a3e46938eec62c7c29284e6bffd8a68bf89fe81543dddf3323e1818efd2afce48a3f5ebe7b44a8603e43127beb5175ead4eb048aad9b1920d28142377ada59d98e9755fee48ef1ca9694654779c611a6ddb3efb1062e4ac3b34b4c8e5d71888dd1848fc43e9bb660c24a354a3433de4c639259fd8664fded42422ee270f2624282a28251257d490bbf699f8cdce1f8f2b29bd27f3ae8345b7627b74e2dbf7000e8afe4d26be49ff0510dfdbeff4ce10ea59a526458db2b9083d5de0255b9374e1d0aa39f2d0b37670bb683a4bb061a058687c84965f2c527b8e2e19f1a110dbc2778b5d4942ebdd8773b5bbe0dbfb4b24c5082153a6b0cf5fa7523716d2196b82949ad6f7a8ce04ec1cec561199148b56b5548a7b2b4ec8b9c780e94a7cbfc52ffaa082b15be437edb7c181cccd0376bebfe0907881079828c9dd328efffd28421f810e39a2e35339de2c4a8b24fd4f591fa2bd79fccda951dc3f98c7098ffd2a9ad2118514e6857977e535eeb94579a91d15619bfc9239613ddb2a960d8423b0d2e12814a2fed1e1e0d1d90dd1c717055675cfb18d5dad56e5d14b1c07be2ae76da9384bb6a0893876a78438c7cf34eabc03a7e981f74687f5c86bc8cc85d6965fda9b1cf37cf8e69e89447a2b611609bb1f7ebac7404a03d4e40a1d86db91b59439ced38386ac024eba3bc5c8c8a914d34f97ca6e31760afa9ef62f72fc29df0cf0da7d58426204267e0558f2b57dcbeae63f0d43438caec44deae52d48ca503f799cc0dad26c8055bab98f88b70738b5c50902eec3b0010f5489ce2a40a002102bb36f12dc0e0a59b2a48da217f3a2074426c79466fcff8ef11f01e685effe675ceda137975f6ef0c3a8b5908f80a058fc301d73c5ec771de0437da7c89189f3efa3e2fb4e24200000000000000005d72e20200000000d34b5fd577b8cc90700416b58b4f4d456e7ef0034ac81205aa7c9fff577931194755ace1232b67dfbafa74025b597615baaffb87ff792ae2b4a0c69d492ca64461a60b9840855c2610fc8f69c9934a6ce3005d15a568a53115946e3227a7991000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000acfff3e09420cbfd207fbf54e225f7e74e42c57ff1ed40a2f7f286f1b3c3ca004b64bbaf98a93c8a2786e27d5c2b57b4fe9200a962550f1d028f75decccd15e482aa5cd2e148b0ca4e7c8ef1018d25b33680952bbb372cc383e567eccbf00cad4724dbe34f70da58b6f7a84ddc263ba011aac5aafa11bd7827077a2de381314402104cf46c26d3c693c1bbe7568379c257adf2e65eb60e38ce9720a4846b336bcc0225d91a68f04f55f9fa7a96155ade1c234e2c3627c2702ec96390f961aef9d0220b2dc488967af75020adcb3d90d0e6be3a0ebc7dbd028fc1145e81dc8709920ff91aaead93df02b98e5e0df7d9395a4579ea217c1b1916ab1bbc51bf5dcca3036b030408e2dc5b837d512c4df658c414af4feafd360541aa53e61ee21ea5266a10db022f48e34f765592b1575f276a55b9559251b585de585e2b05fe2575b48098192b031c9b0096ae75eec0ea27b87d527f51325f21e3b7905798363854aa0793a1c45f0229584d9fee2c020d5dce4fd25c729a86f9647313c2c58899123b273eb7d945c10317fc08e5f225d5ea0f5d6f3136d249ca162c06b32cdb65de3f6b9560ad413643c0add073b2a3d1c74445c561a666ad7347ed5d5d44ef084a7b4238df1e9e8c1621ccf26d622ef87587278ba19d7081660ce616936bec2786d4b03286746ad1ca3e656d8506ab1c396d01a7b9f3dd7d72564b5b3dd87f88a228e4a1136dd67a30666f8a861d685edc1e6d0c51d0fb7e68b2593387fdbdde724e1350f130510d0553d7d3a180c61395720fa8c6eccfd33fda460fa19611eca46976197ef61e0739c891f85ebfdd6a00ea38d192f98778b3601f2a289d36f8d04f011816761f7edbeadfdfc07a0b19b0c805c02df94cbb56e45e666b97b2a8114346186a01b51b600ae535980f316237db9d85fc34d8800938d3d4db495c42567272368a332b9dbcd8ebf0f4fdf9ab4b5a62784a739932e8ef3ad5cb91936110a165657d1949930ea9fa211fcd0280397a3e1925955b9448eca4b38d1ff19268fcf886316af987fb7c48313be16df9f795ca348d9b3f34350c790f1ed377c86703d8194a50aa4b0fd3dbb74cd836ff2d26028d8d8a97bf99fa98dbd4de6d844440a8a31c0948453245e755b4b5882152a6f631b43ba92575bdaadc0782ef602049c5630282bddbbce61e2dcf89635b3aad8ef826f5729122a4377f92a4f7332f6d79891ceaabc78f23e8a01f000b7e09e7ac0079d007b2268916bfad25948d12a38f092310f29d75ce45a689a7dbc437d3fa699b4369cd1861adf6c9f019a40265cca1c8e07394cc62928dfad1d766a55fecd3e87606d3a0fc6ec0b53cc70370b34e9ffee67da868f34a308f7f23e8a1c0f9053f2b9881ef1f261e1dc22fa8826d61b259e7634c23a1323f8266d42322a5a34b8a53991c9f85a9e003ea82703aa0c34098dab089acf5691c3340d06363d95e49cc7b6093dca9d07e95cc34e79e09d9815733cfbcb5706eddcd8324836a1c2286b92cb0c663a4f2e13c382c81372a16414958f155194149e59d79b8864db508956e0da4ae6e5a035197e38cf32a9018b82164ee8c4f955c9326611b0394d668bf3529c829ae3582ed2675396182a48412bd67bbfc87ab8cb809fcbdc9ad62f84c0718a2ccedcb77e655c6c9ca4d98367a7a8844f8573558afb6cfd7d88fb07291f9b6be3176853cbbf745b92384dee2969719f17fe8fabac2194c43dd4d3080378e382f8b8aecb4f624f98c57b61fb3f64ef822dd96313d7541526aa9375680f3f9a47fd0cfe43449049575cea45a644661680a63aaf8830419023da60df47d68433c55455bafa27a4b2f2af5949ea5a8fd2d0ace54d88ef0072c48d36c497938c9c7745908acc7d2fb16c016f9e8c0c2b7a0b5c57497c6785eddefebdf109780a342b0f6230531850a22f27507b16fb900c1233ca69cb0e0e54fb134ec050aea0a074e6a1db65498fc0b5b4923a63f2ad2264443d53196b4e75d4aef91bf77b4e701cc941eaa1fa6d2abde8ee01bf52dfc88392a6333d007ab3fdaf24cb2284ba59bd0db9e7fc1bf1924fa56eb08e493dfde21422d95a573ad883aa4e193c9259727871bb3dcc34bb30d5cd63df39bc15af3ff0de8c6de5bae0d4fe844735e2ca7375e22c4911ba8c2081bd37c8f3fd0f4ef4f95d6de830a0f05776f8e8ae25bbdae34218a360f93b9f8254ba785e43de6fdf2555230732dcb20f3b3ca9e267bf92f9c698f6bd254b5d429c8f53b8a776af1ac4e28546531d4153331030dc29a88118f233be3c57a3e4bea25c00e18c49007019304f1956ca2fb84a8b7df68b354fe96cf45b610c75c8fa35e34121dbab78e33cb15ec32b21339529ec077eb19d13110321c942a5187591f9b08d2e33f195b352de92fb2972bd1d16971c4bc05f4e209ed25fa07", "", 0, 699689189, "c15ae46c62646892a265071051de2cef71842bb33ae9294cbcf8896c34398630"], - ["82ac9c5a017068bba7ecf380b207d33e93612c7db339df73f593a145dda9fd32aae22108f5020000000153ffffffff0165591a03000000000263650000000001c3c7c40200000000000000000000000026fb1f241ca9c504f221e8436e535bbb714e2d4bc57ce7c5009dcb82ec3c02954d31a185dfe73a923b357af54834a1171c8ea5a359a0e77b917e3a3d46705825903cc7d4e024e9f6e84033e23010e202cdd01a1be1216672f59b85449a4b611a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d687d4424377733d25b3ee860123d78a939a4c03b488327aa8e3b3020bfda0d481ccff08915404e7793c93d2cb0ead38f96c28f1d6178e3b612e8f93ad800626ff05cca34f7e7c75bf150496748bfba43c0ed79eae70499d5bf09bca383b09cf2a63c014a7a5a5dbfaad28c85e012416c7051a32e23eebe9097efe2a5894d8032c924a07295c6166d4a5cc60021db741b2e41147f7526e8cb7a58512e2652a8d032ae6e6f3192878bbb40851570d21261cf5c2c6d054ed123c8ab376ef588a28dc0a132aee74de075677ddfaf7ebae085dae65419c5e9d55ac27f7c59528482eec0524872bb3ad544592e1b9cb90203fdb6da9e961b30ad0ededeafb3b9b0f0c78cf021976dcf9b9c3c7d9d807934e1d353d9f7b12224f0c8a857bd0e971ef0cd44cc3022b13bd143df5b72718122efae6bec6168bc0db7668074ad6aec24818341c27c1022e17b8c25289e3239f19da3eda2e53c5562653a8c7499b92a153e92e0eae0cca02083858b18d149d69c585dcb299012768d1cbacb89c80d28c3681a18e60729dea0221c7186d061e9ce05954ec24a56045a0095ca7b447dc95abcb413980568f6c2440d985c9002a6c16471bd2c7c3f9aedf68aeed8af18be62cacb5b4bd1c1c4d0ce44380a27d3233bbf425582aab10b8c52c048e48c486c1978cb40be8ae1c8427ecaf9f035b595335b30beaa14660f544fb181c25ca0f425a4ee61d7feafd67dc947fa8603fb3e3210f163208f1efb889adbabaf109329c61f00498d59926ca93e3da3fe151388ccc2e0be10e6bdd301c877593410ef1aa2b9fad84a9556ad41c2af0c18771d2632879b655bb9cd718399461ac95e49baa71a8feabe5eb8d3de9447c357639db284dd4dc4d18494be8614e9c52a68c25b2d86ecb17124699945bdfd8707c5159ac3a2142c7220d279a386a344a0af02ff32d7f97d5cc5bb1ed900ddc6d37d19dd49b79ebbd6a7bf7d90245324cc52e6ca0e549e21918243d1daa461026e7232d30f4514f2d423f6627a6a20a67df3b3bc5fc73581f071c3b25d1249971df2f8f32889520d84a1a07bdd09070f0c7eb126aa7195f3238fb6cafa22a402d8a9edb10b562cb21d6e87d49a670f9f9062a08ca1b93deb17700361c8ab6172b0d9a5d13c62831cfb2a2d887f3ff1f78ec2a1ffdd7c2b7b6977788220d3996f1b6393bd1a801f3c8e7a6f91f71e72f1cc890129216fe2c616aaddc58ca30e2ad1553c9c1066eabd614a52bc5b75e2183ea2515417490eefabd0ea8c68b18b1695b494008042d7eb14f3eef8109440fc6b77d3d0d15de5751973e4c50afe1dd2c2adfda3296843dde41f432916410c21af9d0b83baccd3b978d8fe054eb649bf9c8de50043841dfcc7de2299daf362d5e350cbd95f4c43112a805ea94f0ab24404b8c40a3396fdeb46551ab50a73dffac2a478def97188820e0ed75ea89f9c923e1469f61e10521f5a313d94bc02671a885284b763de627c9dedd863503dc911e73c5dccf7e649bc722b489b845a390ad21755a6e6ed4f1b076e86f2a05bdf1bdc55bba7bf10395e4463cd84d33c3739fa2e23de4baace991b1e549dea4adf736ceaef206031df8ffd301d579b51b4ba7329319fbdd389e79dd8e0583ea2e26878901d126bfc060401d1d3edce03215ffdd2996ce1d8652aae4960b767c089f3eec9dc3b77dd23c6de4266ea712144d25e0deedda3b24039c32d26ddc3a293ef6301b9e33ecef62315c14242955cf9477f96fdaf189b59c823566703bfc449c02e7b4774dbe996a01078aad6afa8e9ca0d8781facc2f4c601912742e263df5653d1f2fbee72cfbe215d21a7388ea2a9df9785f65de0d971df18d50ef06706bb3719ef2aa6b9f817228db71a1afc62a96499629238e7c81c4d5b421963138f8cf455a9ff9d8eb9e040781b92bd6dd9db4df02440f5979d4d968600ef3d8b8fe391a13d030f8864f5c517c9e2fcf5ce29aadbb1d76119f7622111b2228767b86cb7cbbb7b4ae8702a0e316cca9728006ad9ff3a096c297dde9e29c976bcef839e9b8748b4abbe1db1ff2d78b6b9275433e5eb479016f7673636ee9f03406b928f3ae6181de100be9f1948b0f9e9fcd5c1a9ac67f917e35f82cbc3c99ad1a739e8a1f609579973c82c6fe77f65bf05bf3e0d24f0599047cb13515c1f32b16a3c29c5c3f37cb3a43a88178518f4c6e5990536d386e93d691e323cfcce6a7aab3399241db9aee4987dcc3fc39077899d6ec9e4e09a7a6a40277b02ed725b2c66278b5de89f0160cfc56fea8d0d9b6bc2e2f6656fa6f5afcfe3905362f45cfc2f153215126c84b6867d2626170a32ffd2b15d113f1bbf4624052df7ceb599915a10396c0dfe82864bbf92cfd52882425f7d76fe9c999a366e36e19a68e551ae22e2daf171eec29161e18fca032b3b3f9e6e00", "", 0, -1856072120, "c13ccecd01c3a55cf6be70b12a9b8abf5156c76bb4bb1dbc3517d6d5479e9a28"], - ["94080c8304bd8cbc25dd597d5f6f90c45738d968269ceda7e0eafe4ae40303ba87ab255f0a00000000045153ac63ffffffff0d1025e21795004b21b9ffafde52bda8bf00960bf80d8f50063613b52a5d640801000000026363ffffffffca2f7580d22e2505d888d6218612e0cd8da6be34de926533051152cb156dad8c020000000453ac65ac5c6163500efdb5083517d6b9d481f457460c95f373cbb0546744124a14e518fd2b8528b800000000086551ac5365536a6affffffff01244a1e0300000000036353ab0c8e4bee", "53516a51ac53", 3, -623078067, "1c52caf592af9810c424958d6b4ec412db104e244dfb08a408504322ca9c5888"], - ["55b531ec0121b8a708f5612bec69987a38adad2e368415887a0da8061a6085113adfcd74b7000000000965526a526a65535252f69352e503bfd6490200000000066351abac5152385053050000000006655251006300d81b770200000000016a00000000", "6a5263", 0, 7550576, "83dd52f7402ff4b10f8022e0014cc13c1cce863bd224089eefeab5b8bff79047"], - ["abbfdbc002b7476778aca611d376d4fb6c18222656258f6cf646cdee1405a4332e98af406e03000000056563516500a4e902a0aec3db82928332decea4b6c1709d7b6125c4288fd98e176ba05fb0c819182f0900000000025152ffffffff012fbdaa01000000000500526a636500000000", "6a000063ac52", 1, -744043499, "00ae05cbff709f588ce4d2479a499dec122beea0ddacca0f6c2fed90aebe58de"], - ["782b043804cd2719dc75c897c26ae980542a641a328c5b5ea0880c7a355f224eedb24b0c4d0100000008656a6a5353650052acb011bc64e9877a8683e00f425b81d6d412585509de13c2a14316509eff5ccf44f34c340200000007656a515253ab6ab90aed62df88fb3ee5f4c1e08131926c740f8b875814cd0e9e19ade78bbd63855adf545f0200000008abac00ab536553637c56a0c60756330c0ebc3521f6e62229787a2537613ece765d2087bd98c579ded6c229a50200000007ac63006553ac65f98d1a78024014e3020000000000b2fbe8040000000006516553006a530000000002ed634300000000000000000000000000a12884ae0b2adc5b56d9899e4f9289099d00b37b0df765de03901eada8a42a3dc9f4f35375022fa3d30cb5281782e4d5b287916878a79db72c8f0eb8dd8fe31135ee1eb41a7ba742d0940d64284c62fbffc64f1399e504a1e82386561f1cda57000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c96f5f2fc62759842b8811deb269d470af478b41424b71b57a63ef84995063e1b7c73fb96025c195131e8a4871bfd4c75f7f9a7b0fb405004e45dc3be552507f27e84ce35f560f49d7268d6632289c95069286f68a36de0c2bc8f8fa502cf532fbbee671ebec40b84e1a485300d2d5333bde69278cc5a31721038d1571a5284021a41a0fb85f614849b87237420bec97da85cec214c3b022409c469eccc193c48030c514904e3eb1fba250583b5177a4c2209c15cde1b53b4ad5d50322484deeb850b0bda7d206e791d0c9a3dbd844c47d3b3dfbd9d83e42a3f34e563c29d4af18f4b2ecb8fbdc094565c6697b7b0ccb2042068f8dd25d9c25b509dc9c1b8f583cf6502058c14687338356e76bdde17d7723144e73ee99ad127ad0c63e07a5dcbfa47e5021ee4b83ed808722df2eaaa30e5dfef12cea21296db26f8f3443a4937d668790102233d467a209d43f956ed927cb2ae881dca203a3ec6b7e5396f3649a889c7a84b0312aacf708be4a59670965186f19c552536764aa70d3109bd634511a751b3f0ac0203bfaff9af00b0d9816044c66a5f14dcf10228db14d611c91e7b3ad9038f0e6aa2a41b7a70fb5e62261180c33d9c7a0103df99ea4a868e430cc7afd805c2220f7b7edb867426fe060da4a6a61429d6763c54ab40296752a667911c465cc6d9eaf2292ba973715795ec0757b41b43e5a7b471eadb4d4a59c909d92936348b33c12b68964309db2b4c0654e68570bfb55e42b349a461123bfdfebea511b4e323a429376a24d37d61130370000d0b4b763efd8e7b3118cbd7817ffded8913cf77c7fa23bcfe4aaa80ddd347fdc9340ec162442b45bbf3448136c926debc81e3865065e87c11acf8c17c1b82396a1f75f0e2e216b5669777713a6f96c4509ee4fe46af19111f0e29787c5e5c8f37a92e4a878ce30d0daebef31ecb9fb01836dc9b3866ecaad0e8c1bb1c8f947254cb0a5498d2544f88de8c13c46f54465db8d5ea1796b83ee5434d412cb024ee562fe2a90e84377e4f34aa94ad7a98b2f5a698ea4a88c09ce68be2624a2ac9de9c09cea50356d9d270360c4cb291120f708ea1f2079c2732ab60ac36adcb97febd8d4378543336f0f2027eb0a8c34c274a01c996fc0d782abe95627d4e5ae6e61f3d56e50f3d18bf8ffa083a67a3ef188ae02a473bb5cc5ba679a7f9833f9b9793512fd0172f5db65a10d420a5c0bcd1f7dedf5178dcf6d84fba0214c1d5a4377617d98e31a18eaade04ddb868f9b58f1bd6a9bddb804c7d913ad4d0e70fbed68722d9250c1a12ba6c88540337165de435eebcb3b5a3866dd5cbe44b638702fe547d20ef2ad95239c85e829b0754f71a6722ee17422de2173425ca33dd0c1d2efaf9f59075e35148bfd05938c86f89b1193b35348078d97384789a5718b23aa4129e69f1ec86a76bc59d512f37fa16382971c7a3ecea4dcbd5a926e00565c7bd73c256985212c748bf33fd7f104a675909e43e99e4a485442d56d5f00b7a5b5e387a8960573b33b74e520d84ba641cd2f2dcf82dd39605d7a8ebbf01ec0e7dc4e28723e846aab9c65e3b3ac5452f303eae1549b65b6a99710b2f7ca64532f137eb631bc8f695c37341489200e189fd3af02db94d7b746bef89a3df23b9d22607daba3420d957814bdb632a1017a9612a143ed8abcdd41c0339aa60cefbcfb88fcc7f2e0aa4f56d0cda9683c0027ff110645d432444ebc3fc034efb9574422a226fe113ed1c2807a445e1ef55e4138ba12db432ecea02d5ce7b622c907989e7073b592e22a75b00181478f9a4c96469e0d610b89c6e515d86ba62d70e9ca9b66958e722fc56e1ac1217559d65f79418f5c07cb036c7ecce8ee09a987fc8132c2c06e64d34089cf3a5beaf506b42dd964be1239258f52d684fc6a4c04f42c3c94988e0b86cf35d9de7b0dbf5e17e9512102ba1137c8302f9cf8031c57084976293e29556e1a39ded12f08e54fb713619c5a6169f8f6302adbd4e22566b0fb26d191730cb33940112f4b5e33fbe2aa84a32ca1e7207cca876a8e3a70a0ec340edf49211523cb05d65a4c54ed544315d265690565ccb9e701659183d090df3ec02fa126b3b7fcf54266f2ecf0df1342b9fef554221bfb3b96d94b71d7e07a799a96f793500f91c1cdfdcba02842208312f1b07435b280f3d4c20bac4e9be6bf6a37f9c9758254ab895a36a7dc37d799ccdbc14c29981b6dc405bf94f8322c1d646ce75a74707ea7bba9282415e51e153db997da721fe57f835d40a498ec2e860d6a71f79026b25dfdb00000000000000008d652a01000000002cd5f6a9483d18ac91e2053553dc2e4d7c62df545572523db3bb327f572fee4cabd07ffdf9596c6abb558a163ab8b5706af308eb390dc9c69fd3f2ae1a88d355518f58db9b7b0db9e6c5aa57184e6d3c7a6abbd077f0a8fb01f25502db15d71500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000234133c8fd12dd7095c23850bca3afac86e077af8eac230ebce11e547895eb513c56d1aac5eb2318f950daa32665f0e5d9373117c8153da23e08494814cc6d3f740bd5ad166d769386932df4ac11b38eda6eb6c2f87a679e2429b9fa088602dddc7f28f793242cbef41ac0a4bd3028eba809b5d6737591e9133c35f4190a95cd022bfef8965c734c9d08b8100c4fb396501e0ab083b603a18f4752de095b0dec4d020a2de9f382564421045661b7ab331ce292228f2f20ce72225699a45bf9536e440b0ac87e20a676bf9fdd3c7801fc87a8649993f98b452914dd1de7f9dffd7b069b0393170dccb833e680751039fdb230b8625a369663ff19e542aa3937307a51ad022c1062ef9c76ee29394fb84cc46ff068148ae545281e99c4e91f390df8b7eb440300ae56b3ea848d2302b968ff02c79be75eb79a9771ab6c105e2a96fddaef15f9021d28fa6d69d2601e23c3488ebf6c9cad61e8d99a387ebb81efc5d8f6c45cdf2c02015c5d5f4d6ba2a9e86f9ff4614aec9f55c8e59e250f0f7a560eb35930437f73032617e43788014ac1e19ceab5ec8f1e749300ff73b3cf19f583d3c3ec9f0e5e419dc1944e6eb6670beaa4c4707c9a4fc912215fac4016ed8c9c5b6eb66259a12fc8b4c745c084b247431b4ec1c342d5d900c2ede82d7eaa68a659ec7a21c1737a95b641f2a1dcbe4f3d119854350f9870b4efa801db52e3c72a24272dc91b6978d58739374c5ae0ac66bd4d9e15c9b66853fb706dd016cab802dc6baa379ae717cb397d53e9b5dc20401b785fd362e9675558fa5eb48b4543978acf8f6e3152e3b1f55342b6a66a3b4480777a72a5f69332d306b8d016315112412564065b06264c951e8f36f796d4b76092f7cd6411e2851fc57c6e919484adb824ad47168a2436ac9c801740b4a8674c375cf6035cf9e8164a4b187a1c52422cbfa051ccb28350137bb9ce0d685c42e06be256dc3d302b7d61013ad03a71d77c43c1050d6062630905d261a5f2b199755ffd5df03770fc2ea38e7cc3e8bf2116ff72688e699b65189f61a44827216ceef998f9732413ce09f132648f3a338e7ce7ccb630ebc69bfaf0a18a4cbec2c0a84832569177414f6b1515c824b7ffefceba28dcdf9efb5e4d99f43b09131fd1a3a7d838f32656c294b3282750ecce1bd51451d588f641825f68df25642558aaab76b577ffb63bdefa4aea9537636fec9c0bed441cb61de618670c27764e52594d7e832eaa7d04b6c5ec57d72f7dd81eafa2feea78cbeec0886fc85a2f94dd4eb947728f585b726247f92313a6811b6e5cb21d4ca96cfc752bf3259bee98e97cf2404eebaccad53024fe2fc01eb4d844614d213e019a8d1a980ef69a30438d1ad1ac57b2a230085cc901c5fe1cdc1688819594af5c96b0f1745f1599a341bfcdae3f2a703f9ee4d033b8691b05a1a5f271aabbf53ea07c2e0407af579b0dd8d46f2f1d7092281bc19e235283e4b438dbbd398dd2c118c1bcd045cb698203aab95faf1315715bc084dd7ed0b773afe404bb222cdec8dd52f3be63a0a0cf20a95602b964601da576f3b65e4e61a50cbf6fa3c75447e971b13a1c79f028c713fb59197cc98fe559d3f72ef5aa19498e3a9f88bbb7eaac67c6a37017300d8d8b4e251828aa9e6aea80f0b5bc30a4eab370083e9b8cdab23b79cf9a25d030a48f31c20eb574139c0d10cb867a89ea171993c17389a4bb9ae1b151efdb4f0e67113505708848d99d6a2265af17e07dcc9452cb16061c74d8a573810675f820f6c94c2f9825b25f62e862ccca8004af7f1df776788f12c6e5fa9a5398551d5561ec8684962f3ef3ec8042ffdc5b50bba84b823959e4dcf952cb2115a387414dc3412af87a42e6e9fba9c92545c6b1d7bf83ccc3e8786945f62fb1210924fa2198172a12e1dc782cf0140e4c0d4d2db65c821fa4a29e035424981ac489fe7a7bbbdb6fc3374027ff1cc073499c824eff7f8e0eb29d680f6024b1e0169e87742e895396d703fdd01e046f4e9d7c0b4865b57a1b1377b0c1f1aa373bf0602e623d744bae475d893a5d603db64453d15ddbe2abd9ca27b4fa5a95ae87a4e70a7724894555f2145c8c83afa5a53ee750eb458ba06ce67e2a52db9137ce231f8ad7f3f907ca936d7c052fd0a3fbe95acdc57ef2fdf42641a5d73ab9aeeb1b713b96be38d73e5ab81bca2897b4a2ecd1af7fe15cb692194aa665d11859445decb63aae2a8b00567f27ab0b653eb6cff08f9ade49b8c98cd2fbb0f014299f179fb62ef7e9a0fc45af2450a24504807d5cc32bcde02d82c2527b5ce094e5e821744549bbb9fcd8c0bfb7b45031332146b8afb927a3ecc742b3cfafb437b6df47e1658efa614352ee24f8f4b5dfc5cff29abdae18be451ec81d266030eb7c62542362fe576c2a442b2c954283ae1b51d907", "00ac", 3, 186612117, "f0e8d52bd7e6330a2923e97ce8e33c815d90acf03358a2d7bd7a092a3a1c1d56"], - ["6c88ee1402d257547566ad4ee4310b85d079b4b6f1da8e7efdf65764b10e2eee1ce0250e9b020000000952636aac6a51635352ffffffffa1a53cdadc18e2ad71a1e81417f55eaa12ca18bbb93365a313ce989bff7aac3d010000000765630063006aac3808196d04c1333e03000000000265003e9abe050000000002525285f31a010000000005ac00535163dc08f10300000000046553535200000000020000000000000000586f5a0200000000e1e5f9e35e83a773e7d4a47228d3d02c228e85aba23c39062f256274e60bd501981134bee2128d405f53c871e2ef1884821757819f8d21693e46f0a9a8bd70099ed000ace9c34250e05d127086c2da126300cb4aeb691726a651451ba02b1054000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a4fd2a20e2070c47d513c98c107db81e0618e84e35842fd87712abc1039aa21cd11b0c10e04013ead56614cede560a67c53f2160dcf10a5090516354ef1d5470afd55f45de81db4a44ed2a6a4016a521e85e88344c59e996556ef243366d151f1d63f03f31742d83e784e9abf503bf04549390b65c7ed7b83a1626298eb3d1302082619ce99e9871b0377eca8bbb84575ef3320cf76ff4514146b480a9cac2740022274e6297e3b3644dc967279fdd30a19890e09f5d83b4ba9ce67f184cf1e15d90b29b77b31bafefbb9ec6e2ef9a3aedf866beef71eae4d510cdaaea5551a6590741517f44a70f21d6622625e81ed82345e2e521e9cf3d580a5811cc2edd86b9b2e0329280769f0fcb87df6f41d34b1877b75176dc40303e9d0b1e05f17fc595f7cce030691411d28bc444b47c7bc8ef037096c2583f431f1472e85a7a06947ffd955a50206e5036152efb2f527fa2ab53461f25b9ecb0d120154d0d0a59529e44b2cf3e70306ea533218a1b7bac534926dca28c82e4599c5931929cbf0faa5da65b4049bc902168aa686921c1182287c619aec53dde29eec03f93c86a468c62d219df6d5f49b561aa29968412b92f35216355afd38ebbd531035347015edc34cb35cc61520b41d1c90090e6555ddc40394b2acbca49453467507a63b12108349dc0ed62df1b0f301c37424dc8a81296d48dc1aa898b0660d3575350588e25ffa0279f3379715a3202faf7d7e3d1fdbf858a380f46d815604293918d6994ce998057dc1bd7ed1e6fc8351944669bd34a6f33a921239fa5fccb0a279e3294499f30493a75ec58e6e74bce78ea9710f2fb841d88305643596d00d08c4b85834c68a1653c57f94e8fb8c8b538356cdd8c311b44d184a5273caff90991b1d5a218da1db9cd8d534f64d037a29ad0776a6350bf16637130808f328806b01860f997176c22e7918a459b59efe6b79577fe3e2d09ad63f423da38db8e1f09ee2cb2dcfd20b35c2fe2e40200aa05a615ba043cc57a41ecc74a088b85d2bbed097d362cc0b4a19fdf55af2d00055e275139b6f60c5aafb95d0ef571b786c73ea653bc261e7842ff618dc6483991c193e2bbe1fa5c06d198e6ea7c799ebc0e8ed34d3395b7e88e24bc0a5d28662bc9b257113b0595ca91edec0e15f2071cd77bb66cfb5e743681bdaf3a8892ada7c1c31805e830618b9d8abc07609922fb10cc2e01f4a62a95b8a982b9dc1c288a4dd5e93b5e927acb67d0b742ff5ed1fa8050328204d5930037d5a9234d964646d0fe37687643e40b5c41e02ca03580262e31e6ff02c0adad8b858f65705b393d2871f559d7a941ae1b072250b8f8b20ee5b22f067aa6f371e0fd8a6da440ffd1345656ba08b0822bf04b46fc397c770fdf8ae4ced8ee7e664127a9a6ec6b57cf8dcb74ae94cb3d957a65e09442aa7a87cfdd65e119a49622dfc4f7d8a79885cf7f66e9c3e9fb613e0ab1dc9ee9b59675e40d0d7fff097cb83c5d83a175e256ce8664c56309f5d4ee0d97418869654e57a19005abb0853907da89e9da83c6f90480fb85ec87ca44844527cc74a8f9d43f98f4c9df2f35ee2a63f18eebcb906655cf3af689d013c5354a2c6550df358d4fd8b6b1a3da1da8bdc4f430f709e8bc6034c62a8f55fe10d98ddc148a142c374e702b52517794c20027a35b6b83e8a96edd56989feef5c7073fd48ead31d7110b61ecbaacb7089d4cdfd05436ce1c162118bd8cda145b742fc0e85a59c26f4674ff35be2ea100e6c5d6328bd86371a166accbd16d339d05936037f59714132d2183e2ffc0ce2c56b13d118772f269a3a14887a64a743f71556a273afa582472b681c2262b9ab58cbef99dd55392c7a29001fd49c9eb936c75519166d6c9fd0b53586fb9bf1e6543bd4e11293e64fdbefc58519089b3b8636ac8726d7bcc8bdf523761df37568af19a67f2c46135ae54bd4468be46c84b3b4f66894e9c010646291bbeaefa909756f744a8bfc01496ae6da05aacea52ccbdc384bc7f7cf8ce8347b178b838888a200e378f758570ab156fbeff226e1de615d7e395dbdb64df31e4829bc4a3e1161ebcd78034b20f735481d46f40440ad6e9437334b8da6681ab46773636f5e0ae6f32674cf89b26b2283ca0b65399f06e1557bbe796d3c4269bfea420bd1de629ff28341bdc46f9866df813c6a3b9fcf7454973a967010797b91024b3ed9e1ece7aae233d599d245b95354410cb5b7a17027e1c6b9f018965faf5e12e6ff946c4d1121294a092b036f708841e2b781bc50d3d093442f980ecaca000000000000000043a2310400000000b8565e3af17e83f3eafc1821e71e5016f3c28313b5432ab47ab1f253fa3ae24fb5103348bc92b987166bbdedd83849617ad0993beca9aaf91fe5f6b1842af2097996149b4b05880f10cb1e0a5a7d9f4107ae240aacf4da4d456a576402991c3a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077141519abc615aa49841f0997f1e759f6f4ad9de39fc60c42f4b6683fc084823b9b7774b098f13736331b658b547833b81a9b0841b18deeff453aa159da76c6171f74abccc0cb0182efa55468776a7ba7613a90be0cfe72313d051b0bf1c3a8a7832050e12baaf823c39321acdab268d7b648f5ef1c7c958a04b6ac6a89a36a030055d998748eb6cae46cf10019058ec0935725ffbc8c5f8921aa41bbc7a987d00321fa2419823e3b6ba17ef475181e927d57b8cadbb84c82d2145fbf86f4c5bdee0a17ea9d21fca1e8188d2c937e1f3bdc00926da3affdc525195b3286c29da62f03101d0fcfd8b612b88abaf813ff206f9b1cb0a8f915ef57c507376e58007edd2f022042790357c2a9017612776124580cfe5a9f21ba886edea1851eb4cea422f90c031f5ed76d265851de53f467e806b965b1bcfd3d06f03fc035c38e017a1cf3ac2d032bfcbd81c35d56d7c1d25fbee6e9088d8b2dc44573e8f49b746018580892bf50031866355570d950b90f35107493b70405ed35c24f323d5c58abdf263474d7d23b021e662bcfd93feb218b13528e7c6cb492947da095e8884535c4385f8708986922b1820bf2861c1ab2d4e278db70a6d2a443909730d7e373363896b1c66a8032b60544a35ac953b0d87cfc2314fd5c55411eb611499875056ea42e59db48d7eb9c0740a021197c36272d807fed6932aec18befa48feef2963ac7b0b14b3eeacabdf2e9addf191c8b92ba5f3211b8161cf387586ce1b82b58a8e394768ceeaa5306c4a787202d18f26ea8f853288c6c3b61615a656bf5cfac0423886ed6859ed01b045d512eeadb868d1daa880e36fe42ea03b61265c25c2f15f0be5ecb21f5b90162e54c52049f3953cf0eafed28ed069f722606953177ea938d483cbd122a456654521a0c9245eb144496db685ed31d897099bfeab3098900f890cd637dad15edc5a533be9b3560a2ef9e877954a3e7f5bb32511d68ab01dd4d97d08126c81ed9da1f2e6dec61a780f715fb806ef5b86c3940ea77b1da8b09f2448682ce986b8a8677a07b5d358871561b36d89b24d789e3290b9aa9e87e4aa231e8596fd31136cf09480fbb3c5cd73956e35a1c9b06095068a42ef8c7e370a4715297c615c32d73893b6b383a6556cbe9f9d9a4062c5b8172e9d57616fcb956cb424e8a2161f07648e413bfd2413142d5ce78493746c8f90eada36890657c5b9035c00460288320931664a63cc99f658d32fe6079618f6b8ce7af484d29677480d9d54857da5b67e02236d51f2cfba1588a24ed04d8363d9196baff8ae4555c346aea7fb0900844c0bbb9b54278f125c491c2f95ececa9ab455308942104e001b4fdd8b972adf83b200791dd74fa2c50039ce109f4a11a3f515781c8c88f5f0418ec078306198a857a89096b3fbb6aceb08eedbe60da75a888e9c67967e42d4fb1d3d4291156ad09540c9e4a971d6dd2a913bd6dfd43e1973f3371e194d77e69fe1e32ca9a53564bc498c1e6fef4a8ab3646b287601d3a3496866110499fabdc965944e0d5de9163bc37d53a2fb244879b1b842e8f298ad463ccd7dabecf9aa59e75ad8faa4ee73e219a9aad514302488b3dc433aefb07797b85ad1bff5e606778497c97e85f6a6dc04fd592a5d233809baf199827717e62b03a9689eb53df77ad9ec3817392ecc5cffb416450f0f994c31333e0bd11364eae447a4cd4454c2d850a54e804fb4e4b3379b56eed814025b2945cdabb382e901a007966326231ba882e880cf2a5db8ae3c33a12c0c702f724f3ceb9118b1a9dfe323181c87d28b69b929665353980fd70f765896f1729dfa5dd84bf3ddf142c85db1e5faa44bf664ab4b8e125e0d8a5409a362d631b8c9f77678df757fb2f89a4e2c86ff47dd20015e6b6bff99b2bc950d15e4b49a1c9960761b55dd6fac0e4730bf8588508724a719825c08be9b40b2dd690d55a91cd214e18e1b94f9916585ebeb4ac4c199318dbfc1c02503b316dd49c7c78735c4bcc2671f5c6a1e312e3d0ddc3ee0d182d50d0d934e9c649d4d9dd9b9f6ccb6629dbd26432f36bb23e0a0caea401c943a265f177f5e4f1043f9ed943f06de6b1820b0e9cfb651dde4b68b775c42d3195dfc3aada9b274103590c9a6995af0f5b2aa912fd85f04c06e7a7ed508dcd849b971da83568366d37ab10f44b3995d732bb36a8c8f8ea5ceddc824322db147a077923c809f794c0ce4bc315ce486243be5a4d3c0cf7c1746b65ff05f2adfdf65883a296464a4457812a4f1c1a930dce10c6103b496bbd316d541ef9bc90182fc36ad19c7b21bc39815737000f4ed21e94a75597ded0cf8e088aa3161d1b5eb90cbeb3f1c71a65bbd78791d0f0b06439c843fa8a48f3784a04be50589750d39d991e2ec1639dd5b321c3c1c35af21a6710b0c6ba8ad7e43c6065b0f", "526a", 0, -1414862612, "3af793667dcadf98fa1f2e2b8d94f60e0411aea57ccb03cedd41fe26b480985d"], - ["3ca95a6d02f8432a95bf07ee5ab11fda7c17981744eedba824264c8c944989ebbab728cd7e0000000004656a0000ffffffff33086fd4a3a13b8a9d2de07b4c0752e908a058a081e8fc15ad3d215fad5b01fd0200000000d76f082a0437d19b040000000004ac5163657fe2dc0000000000020052faa25f050000000008526aabac636a6363425a11000000000001ac0000000001e94d540500000000000000000000000057a9f4f35e0446d3bc60b6e02c4a9aa051f0e6d99f589f74fcd235d8664591a31880f03320fae5de86ae9f99643a04b8b62df6e8be3c49959d3a717af3790a33dd7a9291b708f8a2ebca0fb9e700988bb809c268fe20e44cd8b5b831a2c88c6a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5e66f61b399612cddc698973e12016d28df01c87876c360f71acfc398ecf17d12ae1b889287bb42aecca1c5392aad32c885b41f30e4331c8e8ac2babda17f90d74fcca7992448f6e9ae1663ccca2833ecb02a15f80f72a5a9250f25d8660ec2af6e7e73da86682fe16a34370488fc6b780d139946c4691495be93d7dfa26b21022c5668399a0cd94bba355cdf8cacc6c9da6313cecb5821dff3d97d2f9a7d144d02191a29406437f2f0eb87f55de667673da2c9dd7e9c766a3e5414f4c9f5fcd4ce0a2b2abda53502b32201a5dcdd4095ebbe7614a051b1126882b26fe46f635afee510396a591b7220278d427ad806e0d8d99d9438c74aadc73db4b7d933647e9b060307bac21bacfb1eb49e184e373a23789b2f5bf6da0a2636e0b068a1b5f9e5439b032c96226acae45e454b931815873e1f5f56cf6c11b6797da68538f542a893b26c02229148076b2177b7edd66e0d6e58d50207081d673cdaff6c9032bb13d93750b302254b2c25f11bca5bdc421cbd937b68888c3fe84da0fa16e889ad47c75c0b82950328a59ee0567dd438555a5224eadc2cde172891bea5f40aad2aa1f5602c7916e50dcc683bfd5754a01338b53f2d37e41f2f0391c1bfd511cb4d97e09822f30d9f5dc613b9012895e054cb67c8ca37ecea4c5b1801662cf497626f7c0d1e8e743ede21b911ecb8415e61938629cf2f2a302a75cdcf78214d0640c25038994d2f0eb02884b6518530b117144f0c6ae3973dc29e06e983956467f11fe1d248a48a6e720081e6b9517432e9e93c456499ee84930c52a8a9506858eda9dc40529d39e65517b631c861092cc8b31cca716f1e6ac3c86def98704515f6297c3e1318ed2b62b91bc8bf1c8c2c2b794c0a6a8f57e7d2a0c011e35116f05625af5446dd5ff56dcdc5e509e0b6f249352b48e771d7e3f0b006c003f2394139386cbf7087e44f92dfce6365f301e1aa3b3b7e7c2e221f0947a24fe962f8b0e0c23a1e28c16841535ff2247a6cdccb3e698ceaab98c0ce3fbe137faad2c34bf1b26b3c32f0a1b20f3074f4fb287c9de6916cc91d23e8df10f05b2a710579fb660f2700c9eb159e1b82a1e44fb24f7db459c3034890d9b3625b8543fe313d71475b88bdebc2c0f774b7ff9c206c0a1251c57d811b9e31e2c0b0288336e0fdefe3095eea9bf319348f1374a2dc5bbbc1c837ad9d6885fda8c17720821be30ee7259c050deefe6feca0256820c1bafd17479e6e7a5de07bca4c7da7a6a105b7fe1527527dac3274afe93447c54dacfe6c64e50464d792aad788c255ad005ddd81f1524c4986bf92bdbcfb9f8c7bcdc579d5938909e3bf3b40ecc47a88264cca4cd63c25f93f7e61a5129ba525e2582c74b524c49d63820b4f4c23e08059c41f40c5491f25a00ef60082c27a2f19d2bb6a18539345a137a1cae8841ab1d5e58d2201f752df12a9b41dec3feba80e2fefd9da99bd4921f3d244dafc437083146a6ea140439c594216e5f7ad30fe52b43b6b4c63c591344ed8efab9066362196299726ac47814114808673d8a0ed9b21aeaa967dd1cdc95573a6ebde90ebcec60ee97b2de0d7e24fd1da4a799756a49828c4f078e56f0fe1125b9da9ec419c05b4a87f616e0edf8e30920540fdbc9d71dbe0edbb3f9f78b005f2acd683760f0abefc9f70c4af0483d85b66fa8e6382d829aad4a09fee0c4e92dc5134ebac4057ba227e436114f4df8241939670421ce8eb3511188cb39ae1a93ac3b148da17d2a625df8684856b005bf70baedecf34f9501c56af94b99378b4ddcc73da0dad4a551cfd003012de8671182f487478e9c5b67c735ade31749e2a32d8fa6345e0a890a0ab2bc84cff11090a8e63207b752027016b31e919fd86bf78654175183e2a8a95efb59f28de33677d293d975c7918d6a7b97b31d1fa0d15183c0287926e574313b8aead31cb5cf8392b771c9aa9c83a281a0b6848f362282dc9d9fbce30887b1f6d6b8733f41900e8627f0ffd53a15859eb573fa333b862ba5df86dda49660351e952a8f6b4d92248df5a90affe25865250a1d6edacad0d0eb29ba86f4f319283cb711b1c765326e15c0be98b395a452c1c05d77f41a1a052dabcea18c784cbaf77395410eaa585e08af7b99e941c2d9b33bb993f98f53e86c6314d2ff45594ef683111431295594be7a33f7e527b9516cdbb069f53f2d911542c176ec7aa2ed4aa1bdc4316f9dfc5eae944cbfe8d172d0d7c89c61b15c75d997a46469d0ed3c858db3240662b29a1673dcca33dc561d42de5c2763ddf0644f0d99eaa3eae4e9f82df7c5256fd416e0ee40b0c1c007bf04ff9e3edb3685157daee4feeb8730e6e3fab274d478a4cb428d896912189c37f9b402f866c92ac382ec9a4e92aaf89fd788ccdc0fbafe1039b468c8c39e4dbc19537f1e19c1b5fc39104", "5251", 0, -996058480, "3a24fb41654cb80953f14d345fe32477d61cf219d3f1a6978a6d72cf73b66b31"], - ["1a8d7e1401448ba3d245cd61a697dfbdd0306a6b6e3dc6c915447ed083a5f55e16a9b0ad8000000000055365536552d1e43fca0394aebe0500000000015290352b0300000000007a098b010000000006ab65636a51ac4b93ce39020000000000000000469b300300000000376656b641009e8e60cb7863eaf1bbde4923cdb5a8f9d34f175f72f9d351cd1b2866a64c3fbebc85c50805e9ac25f114d627d3feee33be4f919905cea6cadecb8992b5d7182f74d218d2d95d56647c5a52f2f0014156870e6a03bebfc576023f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055a58d728b85ece19cb4d43ae9a1727b4da487b08fd769597fa334f102ba6bef52aad86f0c95d9da7a545327b6bcac456e1e6d9cd513daa65b50ec78a9004470fde11e4181c84763c14550c1b44e1ed038b67a74387ee112547981054855595586f7cb40f0c2fed50f2b3e4a5bd8e16f077b72126dd92fefe698322253e98cb40309432debc6d3f919f7d59ee4e411bdd12f21d5f93d146a08693f06378792f459032f2ff67cfe0ffe13fd6a03344a5465292fb6ce7dd5a9dca2776ced87d844b04b0b14fb67db880d1cef19981ebee87680109e72d7cd763f45ffa851e46c992b065f0870d705ca87987bc8eb446634ae563d4463d47200742e33644d3f8d2f28d1770204efa9c3bff0a93b6272ace3dcd5e6676593678f65a253c8e97020e4f64ff97602060eab75dc1ebde481b7058037022f27630a94e76e255be80b194f0c32469ce8030cd60897e6741528462ed56395fc188855dbd03462735b8506bdd556be367eeb0309d0a52fb719f0530bfea9de08cc95766c28630a04f5143d5613a59d583b101e032022b939ed71bc0e61a7480d14336fb6613c1afea725ec5dbc7cd61b01ef8abd56ad04fe51cf39c39392c5a2f41f99bfabf27776cb19e8b9230828653692a9fabea3a63a71f7baba16bfefb13c0f54730c6f8625acc87758dfabd3310bf28c7c57a98edda826259f27bac449899873c014faba24a3a8471f39985a6dbc7e76b20d60e3c6767dfca6d28f07e9e1e6db7968cf59d747e389df7c2c0ec16a56e186fb6d94c4cb0dcac917562f9beb83f0a4a0ef2dd7d5da4f48331bd21bfe9cfcf989de0c9185da9ea6abbd6765bf6809f91d970d3b6ccd764abd851dd87663322988a0782ae918f7b990d5da4935d8b8c4cd39398696b62c70b957ede530f45bb633eca4f2f7d815d5bf6eda269b5dc354dd8535d3d290f9c07d2787e74930c91f0c7c2238ec82e9aed4be68909ee30678daacdcf21ac5accb7b525831109a168e3b42e0aebe5d1823fcebc495707bd9fabf7d56580e29b67abcea2476576e5d161a7402059865c816775d06f88a92f4aea076f3af12ace29e6b96d68d746e938c2a65c894b903d7c5df5b923a8d620a4405238d4b3c86e6eeb0abdfb7519de2d9aa7c872c99e56f0275e04786eb916de5ee4261d72b68bfe61e3fc80fbf519927f4ac59828f1625df73b0ea92645c852822cebc781888b86ef28950ef1adeeaf29f7dde0489f8fa0d7de9c91cc9d3ae1971754e59e639f1c27d13810b5fa365de562e8e915da05f3be417f8ede21d642941f1644d47e0fe308c00044d4c9585d93e52083c83ea53c6aa56e47ec8149f14bed3ef97a645077626bd34e922b3f18698bb6e78122bc89591535729d59c54a17140fe5691bc2c292d31b607c053bd40f6f496e95d0c9a3c147945eca827d067e8d0052e13431d9f63527c15a200379e42eba647166e69c096877eb9d1b2c98b3f84be6c2da70b0a040ff1c77855fb952e8bae6b946c6ac580473586833236d0665ee3e2fa49aea44356cffeea34319c68368e2dbd802761d521e3115b225e4655be4f95ba4e4b368f6068ebcac7bec92868bd3e4e64738707d90ac3ba359e91e2644e87035b158fbc67373b79391962e1be8b68c29ec4965af29da47a28cdfcb66f50f0ad3c244e7c4a57f689b4e440c162a2f2643360af631e2cbe304660be47cd73e08a2c7b82fff4a4163f18c1d86896fcb86806f6466de2f3f71ff0be76b96d10fdbad395421354836bb057fdc5228f9c4d89c7bd955f942b2a4f581430264d1d03f10790a296eae5461e7f79f5f7acc930e6ed9824933c64ddb98cb7c9c16bd7f1c0d329fd511d0cef0292f351e87fc74788f62e4f44e5f2c2e5497f7ea10dd5d5673fa04bcc45e452d3c5994b6a373a59dc83f069138470adb82534496c4701affb381b4611f43039b9be6980005950546a635775a75d5d7e77eccfce284a9acac02aa4ad7ba21287311fc9c6966c270a2823e7a6179d47780284cbd179b7362b4250cc7024a32e0eabc143232dac75c39b9d86acd47370aeb56fd43f33ac4a4c5d28a795ca854d99ec540f568b7e965c8f799715725a26fb0767f8585535f93179a5aea3bbd9de54a7d76e08d929b796456420b3ced3d119186fadfd9a1b68e8f789b48edcf659e341b2d5f619a67d70aa44bcc3719ebaa454b581c24ce8500ed46b4670d1a2775ec078235464d86c949d8bc174b25036b7c8e8d4c4cf03bb7280b0260b350ca017153a1cfa544e3b0893e84795d79c91ad2ddc9a230454f46daa0100000000000000000000000092284c2684eec78f7744b520078494438d73381f0a36668d84cb4cdf595b01d259cf0a91455309dd0c9139076bfc775e2880aabe70defa0317e3a1f4170cb22548352555e47bbf0c1824df8e8dbb43aa38a5a65e9ce3f8cef4fc5f423d98d7c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c657d8d763b1894fe063e16b91edf90c6987b03e7c08e68286f842dc4fa7c8dd84c093d3d8def9abd5390210427b2431d0ca2ef6c0fa454ed0269e0ffb21987472efc2c6779d4cdb8d82e17307abdbca8c1b7c1c05af1fee40058a6361dfd76c9d64b786643aaa6c3a705f29eb6a051ffc48026725eb929d0c3164bb565ff7ec032bcb9db05179f1b3c894a47e4b6f1d20e132e93c19f0e9c278e23ca91ead475c0319b321103458a599c122c6373dbff98f64a58a17ab307311408fa68e64813a370b15dc71945172f6c80baa335bf73db5486109956f1e691ac1f5a685bd9bf9a4570045f70bba3f7b33173c585bfd19ea133e8e54c76924e783538ee6d7440e48cc022613ebca87cbbe509598f4911c754ddbf33ef96f8725f2d3aecc0177a955bf5c0304d820842e10584654a70a91873914a5ebdd70c8d574ebef61365ada71a8ae05032e3194b9c19d1862079d8630bd820289041c792fd04ce9a068913009cc67306b020793d32cbd048dd544c1aa9ee2147bbca6eb920dab578ba57d95d90706c6a38e032357c66bc0bae220c19a95f4a9ff8c01d5d559d1ef6a53cf96063c346118816527ddcbef53d34abf71324677c519c2c798851f965167917a2558d6f4af4bd900d05870702c9adc41e24ec4ec2a8d63e2f9ffc6d3cf350e4bde10d03868fe29de3fb402656040a839637dfa8205b996543fbb7038d1d37209f89844b2dd98bf8f67a37a29f35ee9711aa006142578d6444d19616f2b741392bd6397c94d2265de44bbfcb6308d3ef04057ada134e701bbb49c67032cacf2d33b32f1ec94c11997c3e1a57b935705a466053e0f71793da2eba9121b10300759c66c239a77af2c8ce46ad4cca19c44058d7f130dc6dc9612b3a4dbf91d01b0a95d2ff8befdeab4d0be4ec2d7ab90b4999093675cf7651d5bff5fdc9c7b04b33a23a72669f30ef2a278622f811f84b131f8b4141b77272bd7995bd3772dcf2c5d7667658cd74786ba63286bf6ada3161f58830066bf04fe75327c81a94a22c05a6b5b5a72ca4cdfc98e382db937489fb2308a4131d5d79a6ab4aaa0c0840be5fc0b8e936177caab45dcee29ee81b67f11f1c35dc5f3d6da566b14b32968c4b8ab0c49725e5f6f995869fbf3c5fa7823a0f55a144834f4c5973f859edaf2539eca68f107111e181902d121c7621ad21bc1c515033d62204b66b9718f2d39588ca92cddd72d628d007ac0eb63a9856f1d71322bbc6135c9146c56a86b93371da8af58ea6bb5867271ac5e2371c084ebb2cbf629112340a7e172d054cdc06c862ac1ef78ecc5bfa128c8d3714d4b4973a1768179915c5c76b08accf2cac83058aaee4fcbfe8351a51f03b0d2b6a2051f125b59a138c4d59bb3432f815d85ae5e86ff47d758c0aa4cb2cd1bacf1ad0443ad76a2c446705468a077eaa90f1457f7d5568408d954ea995345d553a10f78a5877bd33713ad4fa065825a5af6c4dd7578a54cc5a1a8d52f163105eb9deaef9f45c521659d63a00e7982a57fdfd46e98a7a33d2a4a846238000950f0c2c2335389dd6461438fbd18cce85164e6668e5281d1fb5d704999aa4b895dc1b6b1e15f7113ebde33c77230671ab3e9ccefbb4665fe6f75396f304104e5573f975dee888c94cb3aa66ea7400cece9b2e4ccb5bdc9acc5e7099f6dab63c624727cc245f77bf115fda2389628e887b556d0ccc82db76f57eb9646831c9d883642031b9a9b1366700db8bdeda9857f9f44fc4ed66c75626f41552629c4f78b839df719b32a3b318766c4dd4e8dbfeb5f90b2260d9d208865711261511528ae3112bf8a33f937d4168ef066e6e00f1b37f03037244205f4281d4e47fe7cf64f83325f057fa9396185fb5f4254f790569de20d8eb2264696723c199e1909be5bc2088001cc73ed7846263561c6b707cc8a61810921b6605990c145d63f6299eb8dacd28c6a668ab910c186c7b05ccbcfbdeea220b39f758d0688acf94b4c186514bf2e47ed95d4e28200743b6e5e0a96919454ca6da032136771c9ff77cf78cbbef5c3ce8f881747d0cf0840678af94cce317f25d1c94177536476179908783ce9ced6aa5370ea6e9146ab8f96f77241558cba57ee25d21a7723b2b9f0a59c1a99cf9a3797673eea2151d9bb5e8e1d60cf9960f1971e831ca840cbe19868cfe7557d8ee692b1f93b0664af0c04fbbe8423f63f434b4a858b09468867cedaf56cdd5fcff0d03278140fa384e530a9d6c813889652872df5e42c11777df7793ceec8db5443df1e6c6c0b0f9bdf3374cbc054a4d5fd400daa1c030eb105a93ee365e3c31d0f86c16172716788e88a786e8efc4bdf66ccadc40c444405b448646b8709606078a507866632a43f19d2cbcb1828ba7bc224010f56832c96f9193257d46a2cd5e088a5dfabff73ad5688153a2beb04", "6a", 0, -511879882, "e5202e5638f254d1b7ceec49f4f1c6d57f53a49460e93ffda5b003f3359320b5"], - ["938d360f047bf0fc9a8c43de489a76647b8ea4b6330e60765bed346f2299ecf76e9e4bbb0b0100000000ffffffff9756a836d5dc2148e71fe4f668f6c99e9b9661c48d5d3ec91202dbf33cc4db990300000005ab5265636affffffff9042ddb7980d7d647392cddad9ab0dcf554a830724fcfb5974cf65c3a46a2cf70100000008635263630053526affffffff8765ac57fa4390b0a0782feac8bc6ab9fcbd7c8f19853b146e6e6ef806eb88bf02000000056353acac65ffffffff04f95375040000000005630000ac6a50c47c0300000000066a000000ab53552f45020000000005abab53ababd63aac0400000000046552006a5f22fb9e00", "525351ac", 0, -1493545131, "1716e3c8c5a7054c89ecf1075bb253315812e6961c49eead1097094ae874b4e9"], - ["5a4a0491012189274b61ea652441ed43ac2ce6a30e931c24da5e35a4d1f9511282d649985e0000000006515251ac6351d8fb126d018ac7a5030000000007006a635365536a9291e645", "510000ac6a006a", 0, 553396675, "5916d3804ccf20ac520d3b330801dc095ed3f39f4748cfb715b78fc3771e3262"], - ["e75601be04c08fd0453d9425ae549e6d5a3c1ea51bd0899bbe61b9553f98baeb28fa3ead290100000000fffffffff11f1ec1e4e673218323ed12824a0bd1bdadee2f01e663cd5ef1fbf9ed0ef8060100000002ab51ffffffff5115df8edd11b50348abf556d3d5b90da50d4ab51fc8a5eedfad91392c74ce450200000000ffffffff16f2d298eae8f67161cfe0ab898e75814d54f9ad953b0c136d1e0c419b8d0a2d0300000009ac52535253006a53acffffffff040fc3410300000000066a6a00ac65ac6236e800000000000551535100526dd0c10100000000056352006353c8a9e90400000000036551ac00000000", "63", 2, -1316286187, "5be63e47764a59805ac39f0718a82477bf8b620f4b2bbb5ef3913436f4577da6"], - ["8355e829039dc8e259febf68b85cff8431155baa7b8c9d91382e9da6e5d5d56b218914599e0000000008ac51ab6353ab51acffffffff4504add04343e67ab5891c2fcbe2fd2725eeb42a591b95e72ecb4af63a2af14b0300000000ffffffff6a3ab9c8686705023b123d95b44562bc961e0ab02ea91d92f54819186edec8fd000000000251abffffffff03036242030000000000638ceb05000000000863ac5365635351ac5874f50200000000000000000001000000000000000031f70404000000007d109a6753a11f0108c8dc11c584ef784bc0d2ebe4bb5fb5d3f71e841280e976eceb8bdc6327c201eefaa6f2ec2a2740e493af0eafc47afbacec7490921aa3e39bd6e34b74ef25349c857fa4876be8aa698998ee2dad3ee7131c474beeda394500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ebb0a23ef75aaaad7030105452d7c98c3d62b98c79fb328cb69fa52caff6dd0dd1243ea2b35340620da3010c93a1fa1a5cefce4db0ec1925bff3e9e2f0a6ba7d92d335821ddece12c2a9a7a09187549432761c80142e18df00577d1fdfdb32134447f98587339932ac78dfe85ad0d0b8d8c378a2ec9e01d10fc0362036e96ab1021da595cef654480e06ed63dc67b2b821245c2ecd371fddbe945997e8d2bb3168022774c4555a2d7a6c08625206668903dd898c4b951c3c07ddec7d20b4f29de2ee0a22393c1971ee0ce1656253a771a52b54afe61d73b451cb7675728ecc9c2f8cf31779a6dd6d966e64a57756b1ddc187417ae55f45b68a80fe20b8877471177b7b03104c1ae3f56dedbf316bea7b5dc56d242a5fc242b28d421ccf90b9d595beaf52031a4f6b41f8d1986afce5dd772419fefc15a60314fc3489b1970dfddaa13802400220ec12b2af487b5fb7b5712eb8450c46864dc0bbac563cf5d254aec41fb67730020d0ca24178edcf28b39678da30540d8c612be2e649a78147b03f267ea2139a73020d35caaead85181bf128c92e481fb025999f7f1617cb320a9db02f9071f423f8bbc54cef3e9f6ee9a169a1c22c265a9f46b685b8ee1300ab5f49623b967a8be8c683d751113e13ed2a51ff8c72b1360f4c6958fc51c1dc540d9ade01c1f9f925af277e1bea6e6acacae4bec6b08064ee79e615ac0306c9ab83b2728fd493d571e250a230ec749e1283911a00aada50cc57227ad4d1897d37b0baf573ac1919e322a28bfd5213f8d5812ab489d5bf17e1651eaff77444afd4fc2e0fa369a3346c7dc7cc26be1ffbcc0c87f5a48c264f422f07d07c1a3ee678f9c3cae3df58fb2ea5b5b68414a91e24afdf28fb7d73440faa20c7d83b41ae205cebd7fd87faa83cfa21942de3af9c54914459039de81b9ec230fe7deb4d097ef6c66ce590a724352a67822d81067a129aebeb3ef903a6cd5aab9998c379a9fcaf43f09360393dd37ee4e38bf0fb747ebc15239702219df33107e8ccf35c8be857d5b1b45166b0e43a4f39eb3dc9f79d25679ef12f4856a51eaf18f78bab3b427c2cd9da2ff37050db49108c42b6398e671aba41e78f1555b837bbef5a4f681ce293228cbd1aa62bcb2da6eca52477443d72369c7e80c28e4c52d96410adb73c9b7b40949c02be378aa25e0934d91f2ec7c90a856cf17b2871972a51ff862cb79a88c5a5ed5b03fd662da5e169ef63f002c5831504c7ae8a39e10adad3ebed176651ceb0b0f9cf3aee24d1a82db733a20e81b1a24f4938e6cba0e3c2205b4dcd20761b299e69e659b7697edb1bd911509d49985476665b05f888ac991dafeda025aad0707627be0387a7acebe99d8d3eb749d5cb6271dd6652290cd66683c96e2fd5365b78d4ce005b604fff3fd833986f603eebf2f0a2ecc94d26aa1300292773a2d9b20c50a7ee9d9ab4e6e4bf51e31009a6136581dfeb739e511c010485c387bb2fb34b5696b7f16953c238c066ff1c5f262ae70ca6d85578e71524f0fe4875ee4bab1e0cd0fd662c8914a503994f3a8f20ee20770fb76f2137b1eee60daa62ea71c31f438cbb1fa03c42d0eb213c9b5e7af6fa88559170ee921c5bf88c1d1aa1d2083c48d15980f54983591f6c74cc70368f412782989b5a1fc3a289a87f4df0e88f3c53994bd6a77096b84c455c2a4676fa0546073947983bb3ca48859b8845b98c580111dca06ee47a466651433634a3b5ab94ec55aef721db6d49680776dd001b4f685f14feb1280eafad571e0e986bc5fc8f69b562b7bc5e1b5488f9c7e2bbf1d2831f42cd80b6a91d4c36696135562ad445c2b188c22a7f850946ca66a8d737854fffd84bdce4e98939b7c8cf06e8a128c864b1d41b34b5fb5b5323d7384a5c8f738c4cffb42ad3c7bf7db04fa6d741097f483e7d7a65909c1fb18802a8169f684bf5e8ef2c546f82d4361e254d31a5d7ac3e4ca5860451ba19e2557c1bbc2f4a347467b32eef24253aced18bd4ae6ba55581470636c805cdf74824f6f2ac115fccb0d780f8242415470099a6c4bf9f9a4a099a77aad77f8ca1d97e1dfbb943cea6886253e5440f2702a52aa7e0936391cb467916fb03d3fea0dadd2bb93dde7397b6d3d30f93c72505bb4b58d503dab49e7b3efc3026c6ffc76a135647912d872b1ad70c5eee63fc0669515a8d69e873a110e98874f99bcd63e40c14ca0193fcc3b243541cdad8bc3d48aee6c5a67b854d417690a966c45f8a2b45fe19becdcca2a2c403fffb7cea41d30d0a2c546d8bce1854aa6fc10e81a9e7dad8e1d3f2dd749f93c5f97b2edc2e3a0f7709d18d85d86383c3452f8d10deb0b97784f15722341f9627202b1c92cf7644bc9be98404f52fbc91372f14d4778fae28d17aaea6ae52d61df7e5e1f846f84df6363bc076dc101a5b0c", "6a52ac", 2, -430810237, "997a13abe0950ec34d4542cb9e15f9f01aa6dbad3939c9970fa4271ae6bfacce"], - ["ec901df603b4902b579da5f6581082be2dbfc2df8ccab4d24109e30e81fb7b5da395ef1ec202000000026a53ffffffffd8ca09bd6124b57a122484eee81504d1a76cf293b7fbe0800df0a82dd5ea81ea0200000005abac516363a3832b3e8aaed34ddbf9809985c2cb15b345ee02a7e95f7f2d9c2eabf3295df38d0f3d960000000007636365ab5200abffffffff0234328e02000000000024ac8b0100000000036a000000000000", "6552acac", 0, 450715887, "489dfdd063ceae8705b612d8964571944472a3b3cb630fff143f77438534f978"], - ["3e643690034ce1d533333f2088999104d45d2bc2f2c6aab1a4439fb647e47bb54d219fbd71000000000252abe7466df6603cca03345785de77913161b7fd49f2f575e4137dbee94029ff7ff3744b222303000000026aab1946b07ac511e0ba02cb348c05c51583e9ddd4953bd8a16f1f6701392375d8804f8bf72e000000000100ffffffff02d06ce303000000000265ab52c53d0000000000096363535253526500ac00000000", "656a515153", 0, -2059040994, "a6c9f7c8ecfe45101c6d5d07c4eedfce8ae6c0e0ab33c22c0a192d6887be6142"], - ["1ba2d5b901cabc5b109893102862294f5c1a5c913e46cb090dde06c393a71b4d8eaa1e58250200000003536aacffffffff0112e232020000000009ab535263ab636aab5200000000", "536353ac650065", 0, -1595492331, "6b24b6f05c114b3fe35f5743dc8eac4c391c5aefca24f550ddbc709c240cb21c"], - ["8b705149024141121cf42a3d68f078e91b7e5e30ab50bbcb5a3311e634aa15175526994abc03000000025151ffffffffed920c4bb906909481762dd168027e3ecd94d1a0cc2cfa09b472e23beef43fb70300000001511746e4b801ce40d40400000000070065006a516563e3569dae00", "006351", 0, -1842010233, "2922fc423915af0985b5e6a0da7f85d84aaf9d5ffa82301bd9af2ff126839b7d"], - ["c4834c2c01ad2bbf6a65c9d4c008fa64ab8045f99f84b89af7497ff89072047b6de7a50a9f02000000020000f3dc7018025139c50500000000026553a243c20200000000015100000000017b5323000000000000000000000000003b3815bb8b45066a14a74817063db54cd47226faabc9dd5235603cbc8bb804ee1dfb8159415b38c770ff0ad6525dde3f4c1332e60ea481be1b232d9c17affd5271d6f028aadf58b5c8dec4f6496cd28d69c66ffd9b87bc2c35bd20cd6c91fe9e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002aa7cd7982ac2b396279650fa04b9db535ea845a24a9c95e65a95fa877bccaef04b73b72a71fcb213df953b3a491e38b7559837e9a94e5ba55ee7c45c41118350eca2c1e9527322dca8535de51804ccd2b8055f542267e8761824540b829002803d96e48c26f1c568139fa5c0ef1e64cd2fc9376fd641e2319c3f8343bd3758e022cb5b268a5172265fb3ba28cf565ecff8e3eaee37c28e8662f7bcd2b5ccb065c0227e9ad4c6bf6612fe57bfa147d6835f905ae8d083308004b74d51b3f2775b5700b16a06793b4ec39d5824501f0cb3ddb51063698ec41b34c83eb282cdb65c625b922dae72851987c91aecce2dd893428b3f790ea04b464c1305a216363222c1af3021c239ad75d4c64b8f8fbb5498186f2f6ffeec91c173bea69dcf4916d4a8c67f3022f9162557ae4b17562c4bf9e0b68273612d8680e0eebd6d4a0e002793078aaae0308fe52a9b549dd9f31021cb6b6ae4e200f2ea0f133fcf229395a313dffd4ef950213d29ba0407b2d1e4a268474fc7513bcaaf2ce3a3caeb9e142ee2943a109234e0314b49891035b19d135e0879f91862c656a92f8d8b5ff4830228ec80181dafb0a085963dca5fc3aa171f9145188cf104404683e09fe7cdc6544c4e00f16c7c48a8f4012a690c438357ee9d5eed6fa6410fcf01eae9fd0e420dfc5e5c094f802e6ffe016fcb32c805d48b1059de10e6493ad49acc1f6ca1f090179e5f9045039a8b7ebe57bdf32d33c3edebe6048de8b34aae8848dbce3f7f1bdbd9353d87e7aefe1105a392d7f0f18684cbe744902d0a79f81dcbef86d557b7b268809db11f6f5b3b8431d50e6d75743df49703d807f6a98e92b3ed28955b7c288c3adf8fd008f5365c912f1274d314bf299041e84282768b165138bd833445a1136fc9a550ed84c95bc624070115cf347e9c50bfda6c685c5eff59296c575dc28d1d7033fbf9a738661b73794348b6684cff4bd953b17f7dd460b91a348bdb456063f0332e00d226759183b681169fee93be59a51feec7b569b0fdd523cca26bbec795a5a31e5af46285fde56ad88b5b0b2c1d3e63e0a63b3d0421660219bb5d0252f54f1f5d3ce858817e19c7721a971db19ef599711e7d95e35765fcd628c92e69210fce79eea7bc036506bef0b75f5e25a135df859519a4482313e5e5cea83d34fc007e003a3deaa9eaf353f4a55dd41d662e3c6a8d152610db0be23ed6578dc748e28bbec24c8f315af39d7b7dabe982b072f664607cb1bdf8c18d935681c11a568c8bfc03c172378279c47b6f933306cde3ac9fb4eada0886f413c7dce3ef6e2fe0d93eb20fc0d16712c37365a9090b6eeee3a6e3f7b251734df997ebc9567725691d59f20c0481b88077e26290199d82da9e6cfd558a064894f73bff9f00247139aaf86587783ba7176b716a28f1dbc0f224ad7ff0c01a5cb957f4ea60dcf184d9b612981028b9dcb79c901fec9d46a3d940ededd89fa3275ac13ce174860eef8d0fcfdd14f3af8f9b3d7043107e10022818fa97709241a92dc2844dbdbaecfd28d1ca8521821d8196c87d58f1a43177fd35e59d58347fe628cbfb87a1a90d49e3ef721683bd01a8382bbf8a0d44bcb132970bc49976ba78f58d659793b7b8bb124fb4e451f963052acf62b1beea278c1d84f86c66dc4f39c6b5136055d86ad96ef06a1da94c51a904e316d2077b4d509cdf433456284c2496aa664734413026e4c5fc5e773d738912230d106c9865bfd4ae001c8af37a614c13813c25355d5470356355af37f5c8202564f21582c480b07065d0d6ee0c1c2a737bd577c97634573d31b0c910c0f23385f1997361d40a1ef4536e38469416323f17d8a33da5480a35ccaa172bbd515f1c4e3cedb1dfa56c5786da6ed52b772bb0bfa56fc06cae527d098751bc8d2bdbea3cfb94e8f169270227d67177e7fb72918904bb293dacabb021c90d86a1199f6992fdc1d9d240d303e56746eef689024fcec83347d620aac00626eec3a089f4e8ee075dfacb589e9a8e1e28a5684094ac479a83019719af1d2677ccef2c1dc3181dcbe5d868405423b302e426924b8d44e0cfcf931f5feb34fe7d5a17f9b724b3371cab13c0c9f62b65ca7b97ba79a170b378786bd1b191879564ccfac5429a521b5f0f9769e504e32c30735632ffa083f60208e855556d53529ca13316e21ab78443f57898adfc312f87d8965a95c13e4b7221124d3eeff5a0f44f7426520f683b6de4d641cbbf83af509ee9da5c1444791e856a976910ee88141cd8427ccd401da827086bef2017cfe35dd9c9991419a101648caaeb8ea88a5e661c021de8cac68abde864d96814f500c178363f09daee01a5b6c05c6f997d87faa75097a49dd693f8d6209cea90f7af2dbaf348a9292b1a5e01a5dc8bea9c4602eecebaeca7f9dab6946aa941da77db304", "53516551", 0, 206226581, "886fcc8864af8803d33994cde84834d6569275963bd029e0edd76ec273896296"], - ["684d93ea01a1659b9f7d0f59b07238d5374ead4a5494f8763464060b22141e72d5a6b0d2130100000007ab5363abac5263ab5703470116a9d305000000000251537f8b57cc", "ac63", 0, 2017936627, "2bae93d9b47803022976492f9f014aa0b572129d0e40c02e14ce8549cf617138"], - ["3612d41f0285c82ef5184bc6b07b0e85e29792b5d262df80f38fda77b204c53d7dab31ec2d0100000005516a65515229f019e1c28538443daf968295914d51fcede7f92b08875a3a4bffd72cbe8d850f04b2200000000005ac6a516300ffffffff048c64d90200000000016a1cafb503000000000763006a52ac6a51c7552a0500000000066aac5151ab6522e16d02000000000452ab52630000000003b0383b05000000000000000000000000d96c24349e5626e4ab9ccfb0923d4483e52a6f220e5197ff22271089977789a5add151fd34dacee6685b1dc04e7da1d5edfbe5c933729b72aae63f8d961a5fea88253a7d8fa485b5743cffce98de6128def93c2c2fcb3f2e766f09d50101f1ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000376799c9583cb23ff64fc6a6f25cb6d468375da59e032597f665240d9e80c666bbd3edca08045f7b19a68faf322d2c0a8a5546e21724d252de1f1ad026096c372bfa23919d443ab04622f97ce3fb27bb20f88bc5b3fc23dde7c982a8da2f6a670033b3cd0afc2e3228175d4961e15ec7972123b69c0c2c3193aaaa193eba4ff20316350897eeb070975cd13fff3ddd3a59abaa40983bf778aab196b643ce4ccd70020b25784c0a843af1ad38952ff3ef96fee58a705b58a160b8885953943563a5c60a21f67a434b87042151a6eb9f62930510ccd4e8155fb24ef299f6825816f3a83c152fb4b8e0296f37b6237ac72c9c1e91a870c25c804a753d3786308280c9beb103289c7f6f8b93203ed5c4f83e06a566515548f2c3ebe473b589837666a322d9b903058580fd6284e4d1f3de06fafd7df6b00cf5c20cfcdc25ea9958e6f4a037a53d0221f6227212b930548b0099edec210a12a84789830543c3392a6cfdf144027f93021a61d301bfbb1d63650c60f6a955dd37aa1a41738f7fa91d62e9a8811cc4b1a803131e9e8437669fce089f8e952e1ea4ee6429e294cba3555ddac8b25bc0921a15dc5da86bcf048d87133a053213bd5c164f6ce0fc5b5f05085ab30fe8fa6ba686850ad85c0599ff58cd025af20407b558097144ae4a17ee497947ed0251ce4fa6e2872d9b69cadd241e8180b910a0a78a46fe19fabbb147e1b5c57e98705141b0aff785871e1bb7d7d7dd7df7294a43771686374e669101c1583950259bbbb300552f270d8061e24adc64d2422ecedc04f57c7856a87f27550d22aab5c3131e0c782df51b0b296c309ccb9a771dbb23a36d8b6894cd74c9c2c4fc0a0fc43a66011746515c6f0ffbe2d908111d1296ffd2b908a9686914bb58b4f25aecaf9257148d47dc2791daab91c9999861ea2391104448920d5e053bdda0bad13b658b47388212d719a2a8c96a46c1e5d1fb40fb5707b255b1c3c2a4c1bf43946bc091a9dfee37ec429b7242557096643f7b23966e9ea2e76e45825c9cbf1d8be6a93df225ab919c3be57b6d7dd82d3076211c9d2efdc3786cc72ad57fc603b938c5ee8ab363ee156a9ea53785a10fca7086d8438e0068a35a3e3bc5b60e14875038224932967fa0c9e8293647d6a23a9cc0f007162b81c0fecac7a9d469f96c539e1d2a21129a438b9d9ddaa5026117c2e2bf3971357f48e684ba382113498d6138e6b0887d88b992383c212ab1ade4328eb61e5ad4df9c5c57c6c52051c5165e2f2210f8be59f01b50f542428ed348f1f476427012bcfa67ead8b5a19c258edd9484173c4e9a7580107967a261d2f98bf6d27d80af5c18313297b4cdcf7d93762269f109da9b1e3588b59ef72d8b54557a836c5746794b58ea92e014217ccd9298e9a8c946728d67b25e9de798c474a29bb17a04d9a63bae82ba09380fcdcb3e35f5959b232668802ee9042c37107bc306afc84dcb2d548140b01cc9da34c658cb1131e6711f0a004aaf4fbbf04f4c8e6b80ed2938426450494d37b1455bdb2963cf2aae78cf5858d825cb6668c2f5f17e3c01ce16d47f9893b57482e6b5f744dc16fa97e3c27381e3d77cebf838330fac2594574fb7ee2575bde11e14748eac71f12bfcd45f9cd86218f9dd6e5b86c3f18b6e38a3c6e16205f1493f6c19274d173dff18d243668c6418f4d842b50dcb4621a95d35407598d4877185e24e8802cb12e14ede93dea567fc9e307c54dc9d84db5c368727d76b0fdf8c9e4a5bfed139899289d45ca174114e0a5781661d3af15902d3f680fa0637be97a28f9481ca77f5971e58cef8f05c6f807c0005f6b14f2d2d2a93cb43a8f9ec8bd51e5ce0b1d9a478f55051caaccad892f6571e2c97a28a02ca8ee0b091d2f74dd7517f5b04035275b163202f5b465295536730c07f23e88088691443263493c748a04e587effde15584d7e7771af5b071fcdc0f10702c661d2e0ae75b11eabd284af786bfab4d0b6501b377a094ee65ba371682497a64bbed7a6e780256623f56c064431f9053bec944d3e7b488b72c35281e7b25f1a41c6f005931b4e09cff327f2dd6c622bc89c52ffa3767457eeb15f12f349ef1e59f89d4e5f876528017229a0d4d29dfea75343725ebf2ed2f6b1202a5ec47f20a4f5c4aed5748480ff42a0fda67307aabbbf689aff8eec315fc636aad84c1257ba7f87fe5cc5f1c51458dfb35322a0dfc5de474e49e956bb9ce53495b7309c2a30b66f28b1f31fc06a8f0fd668c9058b79771fd4604ccbda2a606ffc50829b031ac9e0d2fcd839cd0400000000000000000000000006ef216b1d8f58986ea347c3e17ad660d480b80f0730d99570352e034728dec79f3aa5be3d5a5ad2a5cf77b708f70ec242845bfa1a370e30509804d6a3d75b0afc5a6b26162df3f9c5fe8702bea6b7fb80d1a2b553c682167892adedb788435e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eabf3e6174d6a5e8c0357e41d891efee65aa6deea7f5e6999e7011b8a71a71468811e1279100bf1c8f04ee4e0852da6f7f1e62485d2b687ee48f7ae1566b3ea4c04530211d8f7ef8e2cadf551b98b49c20055aa85ce35c9ff3cbc52c15a1c036f475dacaa715b8cf0b3e8ec2e68c264c7ac6de795d8c34f41fc55874f3c39093031c6e9b1a0738433694177c7f47482798610599a54c20cf0d61cc23dfcf279a4c020b6b8c4b1c0a427ad585b888cf0e2ad8f490d75e4f818d3497e0169e7d17ab510b031fd77dd0f510e440fe0d53d36f85b252f3908c009a8a651a4dd15618b8c45f186abc4493518f5aa0e8aed9bb72ae12dfce479891324bc1718bb53d0dc2860903036c74f42f744528bab76e0ec68263ccc836aeed1317d26628cc4feabdc5d2fe032a5aecce136537c52551a8b92c466281e513bfd741dd023f42dfafbc5f8633570322e5a47b5aaabadf15c5f48f85f78b7a750a39e4856328eb406c7a09d206d461031d09aae96fd76af32568921273f8bc7691234c3cf4a91d7678fd482954a274dd0217694ba8925f5e687cdb6f5f7ad814a6bf48d43d27612aa99163189d291d4a61366000d294d6dce16af640c162f0ec0b9dc406b7bf2415ed2e48f1bdecf5fac8265c9b8055e10434b847a3c8c10a99826e9051d1880caa73401dc652fb80b6666f77a525a2f91845ac4993e3fb02e85df0815996f941ff908a7ad8278986351533429509b24a1a56507884a95466f7e66a61acf5d63d6e75b2406e1c115cbebac990dd9b6845507b5adec0565499fafbe43d84e1a345bd69270d54c9aa08ac2efb0222f7ad8f7b375ad3b79275e29c14bc076e3ebd41ae42909aaf37fcc5ed95ff0755a1d470b6c29be5d96e8339a6296844d1dd53a776cafcc9b2926a63742d91bcf18ef9a4912ad926a4f00b950c119b84e5eaf4e0003beeb38ced6714409da85a53ae505078560958a57b9a0f8269c615a905c72c0ee16f9766d9668944956103dba8883051d3c47052cb201c0374336c3ff7edb8c19558c6a216febe9a1c4a5088da068b3b8fe095960ce34d846a8b931dcb3dda2712e7395660fbd651aa22d3e7d072d850a8031c8beed1d14aa879899eb0359fab7eaa9fbf1f34ba28993fb347f04dccd98dab5fff00fdf84392a962a9d1d43031a4c1e436da7dfd8b05630c844f2199067dc511e93fa145b66472ea20613f5ee400e500b60cec21d235bacf6ad50470efd5fa10c4cbd23e39c50bf1e2655980425c9b9b1883d661bb3a1ef514bc57d1acc30322fddcb98f70004924ca1ac3f6f7c80ab96da12cd53425e37e402fcff340f8261c62d9045df4afbd81ee4b11d00d21101ac20c4958e518bb1ffbeb2e8ec31ebc82f5f6fef921460938e69652a268843ae49362e4f87e7a1612b2ffe5d2f71732db8660903499376512adbdd207cc78958d66bc96659617fc623fefaa765a9d11a6ed40c221a014bdd371c58f089a5254e30a2497c62c7be4ec7e015abc49162d4bd9a4e7b863fbceca6bb8e14e06456c335d2f3b4e4952a0357cf93350137eab108d39c51e910a4cfb28060f4c134ee78a5c79d8de4276670466e44bc4e523d6f6f0d1a207aaae81c3b52f04fd914e8d357ab7ef2b107cda96e198470f1799fc6cb258d4b9ed2bac9451300afc6ee573d7d6f7c1ab2256ebe8db586a5822f3f70db2fdda352d3ffb03bf94606ca35bc25f58976e5f125e36fa67a5ed42d49c74b1e121fcd59b19b4659b8a47db13474ad29e0e593b6fba91402da9079825a829c52cdf6a3e9769067c4102f6b835865b93a82f9dfa409488c30399d4a4bede539b0ed8601498e9cf7fcc196aa8f99174fe06838205e3a53a4147b0ce9bb0cee98d822a22ad5d89323b8b8e94e9750624f44d66897983a7917c8b865f189d92cd4e583d5876e1e284a200efb93c43c15009aae2010b4ddacfbb9265563e5757f451931049d9256f637e607e7880b63d5546719bfe0edd5676690688dd86f06eaa0968f16eeb6aebd831b1faa19377233794b84832d75bae6e4a99ce88beb21aad573e09a85f561d7976d68d8a1ac605f65f1e218a07fb09f86124dae26f1d9ace65ae09d6dabc4d65d1c764cbf80d856497be0c823b25d96b434d8ea2ff0f570e0bfeb965ff9fd6fb063bf6dc0ab95e32a83675d21f3df6f660814a796baafe376f2646d26519fb0b896917ce77d867e999ed0becb9390c39a62ca8f2d7a4499cbe808929416dd990f338f87218e8d554b2e95ac725ccf4c2fb8b9f5661bbc6704d58a160b33b65aaf80000000000000000df49f40200000000a2790a6770039771a6986dc5346581ed23c91a2488f8fc57abd56d3c05ea807625577a70569f0789e6b02bfb8c3a4c3a47d20d364d6cf03c3ea71d389af67f32a39ca6406dbc60f2e091358528996bb150c88804da4bdb84437f81364c9ff20700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dcd38d0256fd07f7b4aa2263c0c2e195d921f6713bfc938a5fa7e8611228a55fe88eda097ae6a76b0312244d3653c1de3390875d2d4ba4a271d18debd66c8d87154577467c1d820f4fff7a96ae0f8d9c99e5932c90db83ff59ffa46d4abade94025f4833ebcf04979e96f20e1e6f0d7beb2374147b295528e27ab114b21a091b032f298b131b0bc7ac4f8b0db9827dca0cf536ddfd56fe7d97947c8cd5cf6fb03b030053842ab1e1d9c1bc2cdfebfc7b9784fe7b4292b516d96b59ed4099851a925a0b226e57fede229dc05389fd5070e0ce0d0ac8e70acf4bc486b25505d390aee354094e3613ca04ecf29de5461b07a6dd162a0990c830931bc82412eecfb211d875021686423da6fe1fcd4d1a2fc983be16616c09788c5b42e807e148d1f5c134609b0326c46b10b748659ca9c2a0fed60da50eeddf97c06248217972a392b2a5f4beba020a09e65fd9f830445cd1f0f5814cfd001231006d0c15db5d75b6536a7c23c3890201949e371590d05fc0ed7529dd00759ca41453f8a1623bb5c3373ce1052924e8021984d524238c55ce8a981d1fa1b2f0989c8bd2511fe95e6feaf1eaa7cec5b499263db03dd9a6d87f6dfda68bbfec4eac42b01877c36ccb59d4776a2e3b8906094575e6d9fb4027822177b9e31dbb6692b0a3d6f09f3d87cbc313c1b919bf9e3d303f336c6864434bdabe7be97e215ff6d89630433090101e7ffcf34b68d12277b1410bd98c45ae33f8359afad34515bd74bcc7e5289a37b0cf86d2b29460b84476824c5717bccb2754fa8854606f2f735d8093de341af991b702fe30919655c10d96ae9174dd6a3bfbc3d3862fabb2066027b93f45ccebe8387407ba361136c292ed701dbdf06e7b948b5ef9f658caa2a0caaa93fbf3b1f4cf2caa28b1efe39136273a8cbef15e817e23ab612617ae4d59452a08987840a32d8f2e5c72c764bb1ed5d1fd466d7ce8472e6b9383a4614b80cdad450dd1694eeb1047285c422f4e95ec3f822ba4f6eab351607d9869963eadf2a5fc5b37e65323e60dfca852b4365f695807e2c0cd62fdd4a8b14aec15002df2a9a13bab395ab60c358747d620df39f6dfbca8899dc5b34ba840175f35d4980d9e5247ff277cc0da8da323ea666fceb379747214b21a2335d96fa9ce331536e4c5ecb30bded3609f0d50ff3beb8231a87fb3f7a7bb7a77dbe81cc0facdbc84175821cda388aee08b014c22e84b4b4a3f3262bf87fa516ac15635c7f5039f4d17150a32a7363e5fbd85955528c25471322917f05d6ef09762bc290d3cef7c6dbb6ddc86c8cf5983d5c54353fdcf55dd66b0c2ba23b03f583b4c69b08e0f859e4c142086e367eba70acd4239d502499795bd8b36dedbef41874e593a4f13357f722e775f026530513356c60074dfaa2623eb691e84e30475f5c58e0b3b1e1036bf9f787ffe67f72e2beb08d9bed687d920aa12e96482c7d01f412d195c832e847a9b1e79bd3385b1fe7f4eece4ca232a1af870a57a7fde59d46a4eedcfcb9b9da8262dea53546564721d7da6af5abed8889a969effbc3437470a7ddcd855feb4e9d476d47957d5d8690b95720e3089a4395461e782a84b2bbc10b5534473a71aa4f92b4f4ba83282e00b7703f84bc8e4da5ef4a20b30448178ed25cc3ea49db556fbdf55c088235dafaa001b5743a23ccb04f565fd22c8e7f41e7b1012e6917abda884193f1c61ad611842348941204ae4098f2b02475ba779d82a7c0b893fb21e9a5ecf03d4883a1c08ef3156b378d06c1295b66ada5137e26a287bfd986385180927ee893d281fec541014cc5e4e2a3a8713d5d8b8a63bf88425ae1eec8623b1e796acff1da6768671771a070b899d189c1fe471d5eff2a4f69de78f60c9ec6d64325d7a907338f31a40b814aaeba0a49f970b7d58454fd7af7601cfb72cb4f396f5af2b290be5d29dfc2382e1035b4e88fc2f719fbd77bec5f343b0bf0ffed94101bde6281541a0f5f5c2274129367d55995494eb5318e72a41723466a34eed1a297dde4ce161490f689fd5960798e73fb0e9ea993b55f0519f6d108bbbc3d59e5b1d9c64f664c74d7015116c235c6cc8a812cf263789d2b8632e3cbd99a0c64fbd325b4cc03b8406eaf4fc48d564a808f4844524b7b88fe013b834f4db0cd2c7bd60fe8969c04e989a7d173ababf3f5b34a6f75ec0f07ea193822fb4f41ce57db9bdf625c025a9d3a86e0b954be1575992a8a32d4c6a1dad7dc5a128cefe8d6580cb88a366170263e065a5a2c467e043770f89026d3f7864af54525203f8528e3c5334e2fac7e22b74f17c1c639d4b41a00162ca6bf76ef073aad5675e752b476c180045c647af021c4fbf3c37084b05eadcb1e05fb5a41503cbfe44f19cb42dff5772f73ae2d6f623ae01bc99612ede7a5dee373b6956e59c56e90d98720a", "6a", 1, 1293760694, "ac0cb63a22e7e6cb72df175f6c5a81d63aa55ec87a54658742bc8328fe7c5a44"], - ["eece262e02eec80ed40445027c14808eba8ed26e499c4d6d00ca539c2f2b5f52d8f48278fd0300000000ffffffff91a0024a1caee7f299f3269a27c4874bea468b411616f9a0e8a48dbdd618eb65030000000852516a6aac636a63ebb95448046ce61f01000000000851ac63ac51525152522c5a020000000007656a516a52acac6e0b1e000000000007acab005251650098776905000000000253ac000000000100000000000000001a0811030000000066b99442557cd6012ec4003f2de2abb4e0c0adfaa3d14c9fa98c2338142cdd69ffdf37cd25d80bda98f620a1c3e879966a6dfc035feebb5c9bed73b026c56f2cf687463310b8f41d5c20f8530a17482c5e59c7e04c3010e3e29b366285eded3300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bd51d7ffaf70ffe9ba7557b3ea1b43c5f585137559617e7a65514bdd216946707b4fb4d109f87ea7c8f2d38578d5be63b6db3b1705c9522c8084b9190bff39eba0fd86c062f9c0e09740c51414cb59eea57acedc3f0fcae07b888c4aaa11f58b4cf00e29dd32bdb5fe7bad124d9c3286ec70e438b1df7b2f2c5916bd450d8f87030d0f02d5a96a34986c164d272720eaf8fa58ffcac999f7e0a546e1acbd336ecf02186c8dda946fe4e0e5e85c476474a72b2390d4b84ac568979f432760c3474fd70b1d2cc4b1fd3c93a42ab84d8fe5464553b517c040214b8e98e2c2cfef6d36832c27f34cb81872886e91325b1a5e5f2fd081c9dd809e75445146078a13816d204d022b3830433f68556fcd471920b19aefc02f05e55e3e1fd68905c64ebdde2cf9140228af8a5801bd56292546cd703994280f7e5b91a51cd1477ed167081771d7ba15020ac1bba9080686b5e1c01dc6c5405b67a54afcb3347728956cc6eea1d8f4ec560323a533da2456c39ba92f825600b1ece71de3398bca6e0a77c0736fba74032b74032aaa06b4b791dca9e1183435cf8c7ff4b5e07afa9d50a87df552cb41e945f7845075c6840dbb2247ba536a1ebcf377bdb6ec37e5414ea20b930da8ac8b0e9b2e43f589d4af81726cbb6aa31c6f45f99492b07c2c0f5d22d64828f3442907f68c14f9c35c271b863c2617273aabe672e487369778471792ec2b03121607e0dc0ce56b51b403e4d62b336637dff08951f1ed48eb9d281634ee5a51ac17f1cfbc074ecc79b8e714fb3d85a7e2c814ad78d88fcc798fb645a5a16d6bd7006ed2cecf826a8257dec7535cc93b2c54debf8d759c2fb41504afda271a0f9fa4ae35f7909a89708c210d4792f344f1c346e9e777a6bfe60a62446066491881ddaa15c2203bd0ddcf338f6bb0d1b4182c067a7fb6e7b72f157ca2eef65365bcef676f4503edfd3b6523dd348865610f6179605236d5673903b48790c1256f5af44cf0c1146b03529b47ac68203e68e78a2114b85b43ebcfc28ba5c0049457bf48e76ad14bb2a3aba5b9b5dff8a64ae346c3b897346b9b64e76ce3e102053b243ef92c2d105eedee4a2a0571bdc9fb3a9a3c353b0991ade7c5951cab70d49ea28a07ec8fa7002e8d3960ab5ed06a201db5c28bb2394de44bb34e3e74b61ab183c7fb1e1b9760ed362474e94042fa0bdac3d7e95104e038f7ddcb09daf662ba0d291cd5f8fba431af54b2e5bd043089a1e618ec396ca39a587479dab9c55473f266bb0314cd544bc4a08f3fca80c8bde5e54acf91b941aba837369e15e223e358cab15c6216c052beba164e9752ac149db8e0a6debc114706720385a248042fd5689405b4e4ee95725f0ec4b3f53dcc8c121e337ffccce9934b9b5d05424abeb97bdc1cfc620e42902bc2c482ae70921d4cfebb7dd7c96d27de089982cdbc64f6b2a9cd92db26c9824f9c7b6c9b36d84b642ed9164ae1314bf805c8b9aa7d7cd7e370020a290c578414fa7b2060455f00ed26392f89a2b6453c059414855962c0422c490ce0f99544534d3a1c5746039f725f4380a335af4bd819e66809a6a48008209b5804ca7f8c51a6cdd57c8fee0a2bf032b615ac402f782980825284817d0ef2f34d80a34259e2b33fe8c075b8c3f7e81d2daec5e49c2ef2afd42f3c94ecc565cf75eae94ff6b56a84a8f1bb92a63109561456b0636bf471a6b637fa30db8092ff3de38dbdbf4f899eddfaf68ee7da56f46e25d36b50a6b7c505369790f38c311a4f9b4d9327dd26c61733e7a08baaa169d5990fb8d06600c33e04dee82d4a7584cd9885ff66f6e973a151a3750ff05c5ed6a75c352e9a277161019a335e4848782efcbbe2e9a6722dacec116039b7ff10dba5ac1814158ecb9f4c0579c2953d141a1d4dd71dd5c6a0caf47f9c5ef748b3f38bded3c19193c0eaa6d037a529c9a4fc03abf9cfedbdeff11633fa44257152725585a76639536a9a216e4085a2ab7c1f322276a3cd01aeda71eb8096e739447314190bcb1d5a475a89b3cf841576ea7d5bfa2ed5af2fff3e5d33217ec2ad386583aaedb518f58c2467b80470f06a84ddb4d43d3670b49bf48a553898c5475483492414dae64b05b6f6dc5296e3453e248793c8bad4bf32ffc974d35141a256b9bcb9c07beaa8e37d14813fb8c9255d7462b59b62accc189e796c1e4aa4d3c0d20b123d3d73902be459e4657e6a9f0d30f3fdf1f92420d4e48bbf14b89bbabff953c13188fcbd31501d2d94e7581639ba1ff7b6a769593e20b359e3ba4aa2f25feb1c24fe61778dfd06318c587e96cb626698990bcd8fe9eab263a095a714e89ff18a69c991da4b29cdadec00f19e5a85cbd367955c4a48c698bb52b411d2316616d14cb4e00a1fd608ac33cb612783c463d6160fde6dc765af9d8ea4f65427d825180c", "52", 1, -1324892752, "d1fddb093cab147e9495581c89f66a95e4cc353926734dfaed61eb4ed7089e96"], - ["7bf1f59d031a4c7611005d0e7eb54122bf9fa05f6e47fcb54173be032acc8b34a59ae2e4890300000003ac00acffffffff151de5fd6852fa2e97ee6faf21ad823c587dae6dcfc378ad50c1f7f95c7b8fc70100000001ac5dae4c0fe37af888e621ac1862077511dca4fe3449cd622960305f86b9b4047a2fbdef65010000000765516300515365ffffffff01ec4bc0010000000005636aac6aab9f893a6c", "51655351", 1, 425065340, "ec8523774b91c4331182e83838838700ffdf795e34ca6f37c979400e9d2fd60e"], - ["47372d9903e4155ed05d00f6ad6290e2a46ad97a3b36bca39a5c49c50a1cefda89a3ef18b30100000003ab6552fffffffff7fefdd9b5592af6760040cf4484c09b7f66a34b9242489e6563d20e35363838030000000052c662f4a8075826482dfec36ed04cdfe01f6c18c873d27dcfaa13591fddd5e1dceac664020000000351ab53c068b60402ca7232010000000003656563aa6d19040000000005526a51ab5100000000", "52630053ac5252", 0, -1051898593, "8b45c956be084c427cee98f23d8283a39c313829438f6a6c32390b16e9282c39"], - ["7d810b2701a38f4afb08e340533e60458fc57a4b05bfec7010e79fa5e61b3d163cb6a15ed301000000026aabffffffff0491bdcf010000000002ac6a8e5bd80100000000080052abac51516553aea09402000000000652516a6565acf850ae030000000002ac6a9e7a919d00", "0051", 0, -222753988, "7b88d845a3e71b5ca87536c6e11662fa20482d3026a3f1c181896455485c1619"], - ["90c5e6e703e52f954758fa5c3e2c98f11a8058a87288bee1f2f0152d4ebbef913af563fb4301000000056363ab6553ca88d176c00b6e462a85b3724eac5e06f76cb503df0939ea83f08aebaa1c80c6340b0d2d0100000000ffffffff62e9c5fa461911dfc8d8af64b95e1cddcddacb578fdb208fc37e5cdedc8ee25f02000000095165ac6553ab52636affffffff02a4d86401000000000551ab6aac65dbeb640400000000096565520063650053ac00000000", "63", 1, 1870370869, "b2a524dd96b919cd782ca3eefc1d6b7751d69382306e961ac9ad341226dc9433"], - ["6a25676602bad87485b576e5d70433f94b111ed3246fbdca46bb03813938ba49a1965802b50000000000b339876a073c755458d446ce903d699999f2ac43ce29a02dbf5ef7070ab6ec75d633080b0000000006006aab5151533f11197704b6b95c01000000000600636aab636ac209c10100000000066a51acabab63edd11402000000000553630065633f61960200000000065263526a510000000000027ee6790400000000000000000000000086e0ef62e638e5f3db785ce056d62c02e35fd946f8c4b002ce723ec67be0a44273f51167a2290e35fae54db3bd06b28d2f9e431b7ace13179387a14d41e1258dc1a9572a09b408aa34126f3b92b737823c02eba06ba8e739107a43073cecbe8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9fa51c57f034645c403dd4219a63d8174b7c157e1ec4af809525160a238197ece7fc713c569711ca407634aa4e5056bf5a15249da619cc4c568a445b4003ea24e67c8d2aa7e6574e57b347fe4ebdaa43f3f52235e0913c9960bbd93c95cf2d3dbf1b625509db0fb75ed6599f2d2ce845e5d8bf7730c9fa3e7a38fba14472e93020926d9c2f62ca9d7d200f666a89ceafedbe3ef7510810a45bf246c5b1acc2226020f864cf6984f0fc0cc99b6e0d617e12ce556758578ed672f71b5ebab1fce39b40b0c09873e890144db3f951fb2ad1abddcb98ff80de81609c191b32debcf159b7718dffcc86442522b5ef2716b5c0124e838da085a4fd11d6d520ffa7923e422da032d8bd2c0f52ffe9fe420b5c6675f9b9cd011a82b7ea2929942574bfab4118e52031c036dcc33f5770df1e820293cf26000df88ea4a9e357060a4ec04ae0aaf6ab9030ac960d5fea4488f8bb54336e928a932afd8e9abdcf8a6690e551da322665b8b022afc0ca590eb98d837ba03c8a22000b98c6055c21b0bf5cb5457d59a588654a902136044e7b571aa68d6dd4def809157c35406e87c9c80a1188d73ffc67bd611ddac9bdbeae79af3cf182f0482e99f2fc97ba2a33b6e895538756a1936361a2f49225cbc63829a6e742001b31167863fbc6bfcb2fb9d530a2e8692762b88af8740b363efadd69917dbf70ac963a6a36fe820715d46131a65dd00152399c01ae806876dfcc18f6982c4979526ad68575f202d2581cd0e99e915540e572d222ea730ba8afcb7c2e07f34cde1a61cc3f00a64056fc0ced38d44a2a7638fd54e57877682b07e1012fd9464c25aa41dfe3beff35bce6c54fb4a4b3d451bbdd288114c7e263c7b4346838e5b62bd7b8054b6e2680ba633924c97f7722b855f0cd3204a6e570dd6b5d31edb8692c31675aa9841a81d2c728dca229e87de0a3fbe9307e3ab47f0601741a7929802a91c727dccc5dba62090331fd1bb39550b96e4790495d52aba93bb43b5dbc557a0e7721dbd6df75dd22db7e2520c5dec62700ddc87e92d7846ea7db1cfe167c6e5c60e7a3b5bf065f66083317ea4d7054ab03303717bdcbfcff5e7e7583281aadcc9432318b465d8333ec8b4439a81184db3ea0111b0ac42fd70ee5c63c37476607663b48e59db124752f07d17058e7e144be4b34dafa9a1268d93badafb342690a7517a952c24b065d0afbe49a638c52146b27dd25a0b3500fb57a11247fc253fa6eed727cd6324f23c898d1cae95a6b4bbbd4763e2c1353e6e2c5a32b35df37ed9f248e230925ee236f2ee2d3d66ccd4fec61b32e10dc990bbe7fa9d371fd7e6409d8485367f12833954fb4bfe584b3161de5b70fdfe999aa704f48d3a71b72580745588879042748c81f7624149e8ceb3d0d4b1fd85768194423162ed48693de3051b93a5e13be2cbf96dfb683f9904b277d2f10810f0dae57ce849e1bc5cf123005b0b8463c70f1e2a8161c296ca4d52c04a2ef150b7c895ff4c3f6b0774b83522c325e5a43015e37e4790c938e18c04c4a47105db69ffe691165434f42b741e32c697c013fea99fb872536310affa3cd25d8ab9634c3461fdc6d9a7461473cccbea6bba5bcd1ebce5b1e07b24ac4e1dd26840517d964dbdbb7ed310ea1b1d93abeb1e9a842a0fe10875376b854d5d7d0b03bb28f1aaa8c7f09281748069a75267f14963c88a3b8122ce616622bc727269e5ea318e174400a828de584b5d2a8309db4818e11142fe5d80935e0a464bceab1f824d2e5552472e85925d187b79b223b45e587c7aeef09afbf0a832a9596054ac9cbfd4cd0d25138d948b33ab93be9897cd2b7bc13dbf273e4a7807531c51d33c472da461a1bfcca3b35aa36d29cc54240c395e18785b25900ed62fb6d2e645f19cab084057e749ab8fe3510eca710c1c7a7a4fe3c02618c2e2a79f9991a9d84ddb02cd517afeef9b7aba405126d6c98e750e6fdae4f6e107f67674ff568a85f83237cb1820375761505b143e4c2d7d87b8a65a71970bc45f4ea8f3f7e3352f1d3e4c27a48802a9430309ace9d29fa27e1ff0b12142268cfc48e463feb93f6bddc87aa391fb8390411e18773e3a177a9720a1efdb79ecb04f7714f3521ea12b36d6df60be9b131c9c714d4e6eb74bf867003771fbb0ece57eae671819906e48198f05544e3044b9f134eef2bc237f541278e824aced225a68d149055c114ca66a0bb77c566b96a90e9b7f7ce2868baddcbb04477575ea9b3f971386e363f3c450f2e3b205c5cd9dc0841643ffa97c00f936bfae622600000000000000001d973502000000004f2e7264dfc63686b303330a312c4cb0c43f416b57bd4251de6d879b0a68520c1d551a7b98192e697cddd80399e599d0b5513f9b94956c8f30f6040d8f9ac0452294986f87ce9a42a3ca7b67136abe7297ebbeaac06c07728ead32a30981e47800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d30ffa8f60985f835f55b9dabf9a9566a033692f5a156edd533203ac97d548200450330a5a279c81ee2c9516e2d32de7659c487532dfd765e16f13b0b5253f8ec64a6f8d033db8afbd3e407df012ece299188a8e2454daa74c2517bcc2d4eea3f4ce450d99397ac634aa5e16459524ac2a229982b5b5edc4a2059063ce50a36802244f9da19db48ebb22c1dcb3b4733b13309d66b7da871f5582141652aee515a0032b27e05061b66c7f9a1146abab440f86f9715322eda1f83d8e28f63769d6b5410a28ac369eeb78ca7d7380cad4e9822b5abbba6af3ec78d84971c1385f16429b0a247bbf35576cceb96bc39006ff97aaa52a7cc61fda7cbfe0f790b3773d9b3fb90314683e687d70932be8a847959144a07178409ad248f8a1ffa47cdbe02cd5ae26032e901cc7d2dacb81b975b9201c55838b11ef473c679af8b3c90f13f81851ca0902054a89651c935fb6488a0d9321c6ff631fd8b1843b55c1a488e1eafe811fd7240200f5e5a0fa040a4e788248f2cd69241cb9eb83f684929f2e4cf3df4b33f8689803299ac7ad22dac4ccde1249ff807d4d1370d8163ee6bde392998bcde91f5a7ecf729126f4867446ffe1bc4e1c02379088ee395f3ffbebd1688bf86bebb16e0cfd02b3020af3adda9948ecdaccae48a182fc2c031d259ce498593fa962f36b8e51d60b700f932d83c7ef15ababe32ff859df0faf4ff1142d3b30fd900f70543c1ed21a421b87643353132a014a4b8f7409964460d3341fe116d7611926f1b89d017219a2c5b2dfc8fc5daf1891a2a88489f3ecd201e80dad62ea0a264663f06580f322abba0c91ee84703961cffad0b2b45c9765352befc7b2a9a6ba7a00eb6858342136181f25af6103a17f47ea8eeb351e487e5464524e42c6dc63f7011d06e603f052f072133f90caac696be70cf278a5768ba164ac1f7fc16b684d4feaa3302886818e6790ff2564ebe28880d63ec157149d919a0e15d46e876ce9b2876c378ea0da1e5befdc6908cc877baac4af3cc28563f5eed3ba01726ae71756611a1429852aa8254133dcbd42d0384ada1b80d909d34833a413d47e406f64b5e414cee37908e950c0e1ed19267f09d5268fcb48f4cacc367e12316c4f741811ee294f2a748bf45b79e5f2f98977427f003e5295ecda97455ac138036cc8f774a0a3cae81e5642bb0bb2fa0bbc0abbb2f2dc3274b80420bc553d327456a120a108f4868368ee13a872dfb286090e5686abd4dc9ccde9f3c330fde39fac30b1a1f36ec4cb73f1c1d7357c2cde7539805edab0f260cd4bd860e11ff08eacb5ca3e5940e02c3daa4b24809a2c2ec26773c85f0587e584f115c4e5d17913a5ab6145fb0711fbb074b013562e597bec9ec9b41e248fb2f9fa2c5a009256246a67529356b8e66d267217f6efaa6fe0cc8aecc450a78df22ab6318fd9ce36af9c7891772886b18874395ad591bbe9ab0c0c957d8d78f9d9483dd7d19b089cb633b9b3a4a757dd44c124e88038b18899c27084a9a3f0b689ab7fd7c0f4ebf0eb5e15d4f5913963b2fb79e4d1d76d0516b9a70a141baf65a250ab7bab9a23780ce9fcd3fe89b11c0d1ca61a7d620530217d39bc5b131d167778ad8eadd3bb29fb06c31c0ca941c41339a715396d88fd8d83f50ce54f4374c4cb586e9e65e76cc6bc6c56f5feca88bb75d9263b90d561de22137e29fec6ee93ff45d04f3a4dd7e0379d5f12bdfaf033292a16c100226cf0721a83e12d4de5321ad0d1be4d3676aae782c941f14a80072328c04516ddb89ccda584c483a98511403d610ddd05ba7da5605026937d8b1641b29041f59dc4cb9efca10a7031f76e0a79732625da2008356b6d76ef74a8950de7cfe166f85fc548a3bac17856ad276fea2f1f26cc7ba3fa50c7d18c9932e8e52466d437b8abbefee2dfe27b17311239b4efab037f406ef4a84bfda8916bd0ecbd25017e77e5b2c35c29faf59471dc655c2f0b4a21d781353783b61ff520eff4429c308c8da0f8cada1b206b51aa16f6a88388738a53a3d828b123dad55d0fd20772fa72f3ff8595ca8635603455b3c02922ec3bf06119637bf4d21131885f24c33ff63066a2c98b36af64c883386be47b4e10dfe28e1457c8771686442444a42786731e6c786efc04e2a4401dfaf7b1dc26e7da5174317d994feb05e428a6e14e3efa27b05a43db513209c5712a433aa568dea8ef87ef6a47fc31fd37e98038aef67331d29f03beeb7d1a5fc54134dd531ba4d0c588ddb130b61b5cc406affe54d4a8a0b156d73b502792769b96e6dd5b2b71354e5c4baf97215697d9f27520bd55662694ee16c8e3275c8785a603be64bb4fddbb5ea59f95ba1d3b7883b81d1387a2cc754101ae743b3dea20b868af11e1d464cf2a40cee2a0f96ca9843c5b8c0f0e64c43ef0206b69d802ca883c0a", "6351656a", 1, -1755215588, "8e5d14df724d9255629742d57866d0345966942eb175ba1f6a65786a78c15a43"], - ["56f61416049e5e325c552b4d5f809950b1be84cece2ce171c9d305d59187bd8a2f722cb7470200000008ac525163526365ac98e29be1f2e0ddb98e685e8c4160f10bb114d761720eea9cdbb3fdea49a9f7bcf82ae45200000000045352ac65a0cb9d68aabd402754d73e1d06cb6c30f64576463da9478765aa307754c45bf74a33a3c703000000066a5353636353d7b5fbe333a990c0add81ad79fd49d05f943ba0c9c6fd0c0b8fc09f5ab6e8e3cb2fa865a000000000363630078b1146104598e5d00000000000100b31389020000000001acd31f7902000000000700abac510000abb8e2b0030000000008ab516a006351ac51a83e661c02ae7971030000000000000000000000004ba03020c4369724b56d0ea9600d75a275b843e81304d622e2a81a65ba3d1917cf2fcf8d6d0bb328cd49a5cb6fa9367b37c9a85124c824340cf4a9d2ebafb611166c5c16c8179fa9a6104af44efce9d3dc172b23e417dc10c8cec0ef3a80da2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000302b31e098a355845b9fe39c00b7fa17cd39feb8828adec95158973733f4f7aba32ad02e277b7ca23879514df2f7e6bfe74868424759b81bae105657163aac843b4b3bf9d0ae8826af2a922e8dd5758d500d4ffaaaf57fa45d310e4fa0ace17b7fbb1845aa1da3dea4ec5d28836a22b41f750516ce34cad3b754dfb697f87a1e030cbc038353ba2f304734426b1b9cc04ad7395e6c63d1e7eba43be0bded5c6e70022523aebd7663d5e4b64c514f121c545bc28b6a03c4b5f257bd214639bab038d40b13024c9994634ab05c2c7117dce16aa7d28e68a40453863f3c331a07864f9da60b48dbde01a16576604fac9369750272d513d6ab38e7995fff4c809481e56a1a030a03e5d75a8237b32b348428f0c13a8a84e8b22f6f2e1db3e89393b30d49dcd3030c52debee305924ab755b4dcbf2d6d29b927e6efcdb6b3d36e74a231e0cfe7760321790cd5739bf88b00f0df464d44883dea63a014cd4dcffaa2c0f2664cc69aa90311c334e2f2a3fd4a7e1d55f1d6fd2f6b47be998e8acb458c122d7bd8778447a403276904bad1a3e8a37b995f1c07198e67abaa0de6a6b38678f9daa501b150896736e31cf9e28fce742ef9fc65f0e88822d81e7f6a758c3d53810e3652c510fb254c9dcd191f819961db4f6de0e85b37c0a18340b52892297bc625e15f5b39e5c216f2b10c4a6e20385b1f406f0da7470610939273bfe28cf0634a78e602bfa7036f9575d44f6f610c1bd27567d82cb07d6dec67eb22f1950ee93efe603615692adbd1b2b4ad0475e11b7e7ecb556acbd52aa9513d085020e2947926d7d9048f6c2b0f554b95e241d87203e1aeef7b7522c64704f6fbedab38990da57bfcbfc1221d1302a78d5b07a78e2ea382a026793618f75f891ec28fac6257082e52b0558a14e5c2a313123def81363f28647156a82897c3687f181fcf8521935ec8d9fbb3a8822ea541ee7078747390e3ffb95e6c07f3f9c95a0a22eafd8d700983fd04bb2a502f2d07c01a17794ab79ab017cb41599aad4eac5c59551693825252b394064fe821edff395e1ba4e1e309ee98629578d29062921384cac55a0f446d657dbd7d662e50d309a818ac98bb02fcc38de6c5672ace54bf163c726bcad506f014d8bbd8dc21553296313328dd7fd27a815f0c5503ea2678f44208e1b3ea3133d0d9d31c5b9765ca145bf0e4b232f6daa81bb6586f815e1df02261505e4e9a372978c76f938eb69098a76807bb7a444e4bbab39543b2a20b3c711fa7f321d0d2bff290822eddf94f4a6c4c806bd694242d9cce3b7be95bc5f7d3b9945baa8b913923ef7c2d03c78f22279c188aad3aa8cfda5913741395a022e1881099265c3ae70058477e3e2af8f8a4e763c3586318b56e7b0e8630b341689272b9249c74e482fbf4c9442abe80fe700815032bf3d492004766bdd5ba8887ac452035a4861ff24af7bada58543d57a3bf925eb65a4318f36967a77dc1f4ad37374903ea9b5e1b8dc87dd6c334265eabd9b082e9a6c962c622bf77ed93b63d6c904c543e0b9a709c2501869d2755489c53a42ff547970f76b24fd0a4c294cf7f0bfcffb19f5f879482355e87efad759a7d5ec929a365e2d76ca10efbb03f05c207f7951376f86205bbe5e320f52d692aabf8208a54ccec33ac9c58b2c32a17ff4b60c1af88e1c4668dbc30731bdd1ab59dfc77a454426affc3d7d35f272f626132c6ed44d4f509f4ea05b2cedd2d0a811c3c36481dad4214f239800d8a5a1e6b9225d5105186ebc4fe633ad07e2384d603975901e99361b22e070ca47a559ba3f48bf490b11aed1064394dfb093a5e61795e15b9acd73c05c844d435be3ab7764410096313ea14cc54e891a7e888e26d1682d7c99a4b44fcb7ab9e33449ee82d0f49ca85041bf6c2440fd8bf5c8c4bfe714cf39f9d1ce8f3dffa285de1744be11748fb061811a69efd6ac29bcdeb07e14daffe8b55a37574239aedf9b767cad3c64e37ecf24f9e128d3b3dc788b9a8eee2ccccc62b83307b52673d235051445cab2f52deb69adc2e4c99386b1c02296ac24be3e3ab0e761a79706edd81f1e72c269cbc593e3ef3d92b30095feebcdc4f29a5fb4a3dc1a4a180bce812017b1a4b0d3ce615ef64109b80be3ca842c2d4e7780ea30e7cd45914e0fab33e8591caccc161fe2867ce092194a1a245616a114e35dc4bfae41eeffe1ecb543bb30e9257b1d83c75453b72e79a940e1710d3db079817b46a36249c8d79d8c4135cc9a46781ec42358fd4c72c8c56dbc273bb73d3a6bd61f4c30dfeb673013ce6c8040000000000000000000000009b466357f4ea93f486bdaaed388e31d7c367eb1ab67ca479c4cc7cd840a4b5e23cf06e5478d8991c7b0c53f82fc3d402f58d93533726397c64e0440a0043d942fb2121727d5e9f999067a8ebddfb29fd2b416ab3496c9182310c43f7a53f386300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c71e5a979f5ab7ee272ccb09c2e729eb8b9086b073ac9f81fbfe0e5720bfd250903eb4a183d45a4c816ac293c097a8046f889fa98b3a24f65433d71e2c849024258730bf403286cdcf9362315e6a500cea1d86e54586114f81f86379e4ac6e919f8df2a8f67eacf88710dd18fccca5ecb664276237da99c3622d581cfced3f87022dd944332edf84a87075756849dd74725ca194dd1131d84aa4c1a79ddec904c4031cc061e3108c235a88e4cf002364aabebed1fb3675ddbc7a7b22f318e9c8de070b2908793a214f021c26d5860b7a4adb4521cb546d0ba2bddd9955d63d3cd538fd0316967c1eae61696b74bfc79e06e33beb89787bf26c8629553b247373ffae5b020d7c97081c50cadea9f53015f70333713dda75061f3e6eb8968696472ebcdf4902024f4dd3db6da8817a2fe095bd94766b1bb06325557160440ca4d33317d1d6bc0302110889542b73cc0dde373769e716f4c2d04034aed1d46cd6ebe19de84006a0031e79d9739c4b011decbb61aa78193deb2518d6dba7c85a0d003cfad8d51539ec021bd906a4eae53d21a33b99077991f68091958715a4bd8ba9b4730a9ef54f67e5d2ec7e4e8a4d1fc16d7ae4f13dbd75ab9e9850f1353eec17b4ea9e4f3ca662df427a8ba832670d0fb02b310e933c80d381296b854678053df71ac3d10cfa781fc39f94e3b98d41e96d8dcd42e0d797d54c8b528ce681b020a17954997b0023e9c05b5b37456b50a981664c885db0179ba91f60e8ffdaa4f9b9b9967cb6986f891d234d6051726f8bde5a7ff8837c37060997effe0ffe066b61085400bef8ab2295c780f9ed4f4aada2efc9c071f6f48b249a3d88c75df3209cb50ebcf0e20100012f6396c49cbfbac9b9979dfc55a3c42bb586436f0ee008e611656ae167507ac2a8e26f83d87806dd205b3e4ed1e200dd2bd50691812ef7908480aaf2734ef89a44b19542ab21f0de4dc69f0a0f2c44b0014a89d2f8cb48429a438e92951567b839a5ece3776cdd697fd92715824e2b5d03262ba3ba5bf03f60ab1ef177c0f6e957d0edfe2d0110952168805adf022e16462c3463c771ffb75a13eba23e0f7ffe73729cfafecba603e79476e1820e0c10bcf964e96ab398f309e478693b02cb2c8cd0b712fe32903ccb3a06855b69150aabf93d8f6be400c3e1722e266416ee9f6a231ee8cae54f5462e9e5e579ebb8e10ada1d9d26072478f2ec289118ee39f9e7ce81de296f61224a4c1e17be395b7e3c7842fd7760456cf2fe9553d32ab83e74442f2a23925278416310ee5b600cd8df2ba1faa3cc5f88c90d389ca492098f0b0eeeb4240d1395fbafdba43e089ee54384ddc0bfc81ce26312a9b7c44a4483f250ce15026ef7bd9a32250577dc44d760ac1296c3f7c7469662feec83ae7d69afe991ead1551bad3d564eaf0db7c6cd24d2a51dcef6acfabcdec64a57af741694cf3b3fe93c59d020bb25ba8208f4a482d7cc8dc0b54ce7a80a9fbf459403fc57812d2a20b14069ba30b99111beaf9589bc7478fef9784aeb5ac5da00a104a2a3bfb6843cff8109f7ff036cb1bcdd268e95bdbd1ea4560fe7ee1f2c1d689e47104b5bedfbe2f1359f38addbb24b84f045047ee9752a302d1c26e75f1939639d7d9ef9649ca68cafc9a090cd27cc5f2fc397e13426bcda935aa7f6401d7887f432f52348fc62cdd2b813e8b198aa300a07488b485e7989b9ecf9e30de8d11791247c06336c649afd894c56502963837923a1d2a4113e72eed675c68adce6d897479372c2481d4b86ddb63f45521a51a0ba31d29fd5a586c1e5b5ddf258afccae8615bf5ad1b455c2ccab0d77d497424e3dd9692efbaa7172631d76956d38cfa80c00db401107b210e0dc911c95882ac1a539568315a5575bd9147e6a155cadeb17b6809f026d328160f0cfba0120be6236a821d7d4f47f76ad19ff0bb6d006ddb6a02808d2b8b84484c2dc27f575e0767cfee2a073d8a162ee2993571402df60df9e6a11772dbf5573aab751f8032e5cd2bd60a8ccd700bfb1f26d5f7fab7caa72f44fb59d80412f517c04659897a9cd907caa092702121621fbc4693792cb8c4cd96da4ce57995c04b2dc64fb0da181c5991c2286cff2ec0f79ac4dc094973bb53ed58dd7cd311ec9a07de54c4fd557f802e84cbdfd408f883396a4f7adf19af38934e0adc2f1d26bc47e1f89a0c927204f3b6c9e421b6d0955adcc0904e950447b7b39e3314e2f16359b918880c3d40486f0b34ae95986a1612b866b75577a65ece63c78f7119210b0f7b6d68d53316d67cf0333d678ec66f96275f17deab246cdba4c4fc105cbd68f2d9eb2f1b7b14383473595a5cfa84195b5d66ea4ef76a6829fe8a6ca1ff3c43c605c1127bdbb9d21fc0b942bc1142a34e8863b1004cf4ca3834ddce99c5f34cbc23ee3f3d19609", "", 2, -387096437, "0c594f9104cbe763cfc0c0b01856c19236d204e1aff05f1c67ef7bdec54026fd"], - ["7d59287903ead37eb1114f34c3c84ba0855e377b6339aed82c1e8bf58bcc32f3b23f40d4350300000005530052636affffffff7a21b5cdab674d88b4b625cd8d4903ff6c5f39c46fcf7e8a04e603e70f49a2be0200000003535152ffffffff70d2f99594aa6f0dd888296a2fb9872bb6da1547994fea73a38188b3021926ad0000000003acab52ffffffff030245e20100000000008ba4c802000000000763acab656500653f7429010000000000fce6f85f00", "656a535152", 2, 1730337781, "d10363f7d78870c1c6fa9345ee058e635db2cebbab570431c817cab2c87553ac"], - ["7a947e0e0407485fafd7a03e8ac64e6ac6637c084ac2481fb50c9f05a374ba1e3844c4beb50200000008ab52ac655165ac53ead13a51424626955569b4bda62af6f3055a9106fc9a6f1afd846aab2bffea63e142388f03000000025152ffffffff15941f33a9a9f1ca9a3d4c97abe99753fcde99dba8646647028e97d492f97627020000000951ac51655265526aabfffffffff098cfdb908fe5e09f0da59eab436578ba9e88ba113c383723c2e631fc7d6695030000000300ababcb9fdaeb04f1e12f040000000003535152354aa2030000000000f91a50010000000009526563ab635351ac00911ec8010000000007abacabacab6a520988139800", "516a650063ac63", 3, -1020794756, "048aad30e475f2bd0cbb166d16bf3682b1851dfb1cbd7e3bb8845ce446ead925"], - ["f6577da801949a2cb73406a60d1601244381ebdc07504f4463c3d007e94c81f0410ebe643c0300000001acffffffff01e76a4c030000000009ac63ac6a00abac530000000000", "acac0052", 0, -1242433645, "c311b0bab09ffae0b660ff006f3a990f0c1a0ecbb4f87b9e18f7b44e1c5d3528"], - ["0fabcba203876ec086455014fc07c1b585e012625d37a342ea975b47963e274979d82ba1b40300000003abab00ffffffff62c17bf0ccc1b6150af39f4a0f87923ec0455ae84c25f8561dcbe486bdad36bc0100000008006a6352acac5365ef9bc61e7e34fff6e5294657883854df1bd62255452b8ced8b918d0f30a691929441eccd0000000000ffffffff029a74d403000000000963ac000063536a6552ec9dcb030000000004abac655200000000", "5152", 2, -231833641, "507d8af51deb25658ea60a1f380090f5865a6a4f8b695a8aeeaba90b3b613779"], - ["ecf12beb03025193af2ce2e17243076f2a88fd32c37b6a47bafc56e716bf81114a8106698502000000086553515165ab5363ffffffff25b637d477cd53241036d89588e36d56c1e1faf0ba307221f04fc1e520517c6e0100000009ab6353abab51635265c93c729ad88df5e763b935e1dd9cc8e8d1d64b6374206333af277b9e3696bfbe0da733fa01000000056a65ab63acffffffff016590d103000000000165fd30e034", "6552", 0, 1706991474, "8efa29c7ad17453fddf17d7e52ee315cdaa44e0998eab09872305de9653e13b0"], - ["8c2f48c6022fc922383992ddbf84c4c6eb98e60d4b7263ba3859a5009480f0b89a4c3c982e030000000553abab6a5311ffafdaf14091da0ec920ef211f766ca8a0df8c9095c3f898b2574d646ca40a61b39a96020000000253655ed1397d04a152a505000000000563635353650ca5fe02000000000351525150e4c4030000000005006563ac651c1808020000000002526a6fe89fd1", "", 0, -1230454624, "24a4fa6c9f2644cf171a6bc02249c8601f25b98fdf224df36da6573d1f22f8e7"], - ["8f98e62304ed74ee854d7fc769dcc20aa8ee29a92b737aa8a5a61b512e01d16a024c8d7f410300000009526a6565530053ac00ffffffff1fda9c62280138264fab7e52bad0a35399ef1c845a70bab03762ae11f4248a3b0200000004636353acffffffffaa88b4856def669ccda1f24880069f05bab490ae1e54656be926b8d23279997c02000000002ee52173f8a8a0101d4b46b68c68855bcdb08692d11778ed5bb038c7a77e4fd482ac14600200000002ab001bf871a704ac876a020000000009ac5200526a520051ace7a1d10100000000002d7e1a0100000000035263523182d9010000000009535352ab5163536363140cd17f020000000000000000ae453c0300000000a09cdf53aab2b36ead5af9194385d45ee6f22ea4d34491c499ff7ed6c46dbddc01c1ee344cf9f2ae6b7aa10728e374cd0210a923710e89f4294fcf03ca698bf9148a425167c704916fb5256d3355dba02cb913c93cb70b977bfca059b01c7998000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009346b5fe610bb7be8adb1268f7467db021f42dfad98ed4c63ffb5b98c507cd8b98e7dd404d9d7571d826a74f555bf49d3d40581ab548b36814409c61cf5d1f84d8442bc7ef453f044f3eb5d99aac3643f03a081f1646f2233623e3748d5f4c048af44b1933851636540ad93f074529ed002c17d1b7515fd452a9b53a289f4362032a05dcf3336c7c2649df837abd95d8607d2d9355c14a1f818b7a7ed2a88ef665030d9b0d7aa8b68b070ad129bded178332872a3abec762ba5b8fc1d2e12bd500c00a00eb2b31d281980be20f46a3216e746252cecc059dc0c095e0127417f6b3e3ad0e84b47e655e790fae6a57756217dbe11f86192a1a02658d72fe7191420abb4f031e747734b2de1d299c54de5f6d367683d9e1603816d11c96f69b04147c7c1efe021cc2942a07b80eeb9db65290f3b82ed454ff3c549d3eacffbd04df0ef1c67347020741fb2356b47410695daa809fd20f3a5b50e3a3b4b11ad953e3a3c5a751f33f03190b7c89742ef19c04c9fb9363e51c514486a2b935020e342a0c5ffa786249e503253c5da0befad18f8e1bfe8fa17b7fa5b56da7397095bc63b286f067ef5c36cc1b6fb5c40680e6ade0842bf529f403cd1f0e0689547dbf929b4c9579956b91fe5f53e8d6f2deddfac52154f87023463c43f282a7ece27629ee7c0f654dbc6a26b12d0f8c61309dd67d38fc8f7db738d9dbc266b6480abc1d8b88c4dfa24c74ffb5303b2fd5d5956f3c96e8f02d68b13995b5424dfeee259b9261891983633ee02b4747d4175701270bcd67b8b8e96322ec45ff7089f1c93fd4cf5c78c547736cae0615c1b051e8bb1f9d62868034f6d446c70243d14be9b78d5edb309b75c7d48f712b954e1a90b8b8f6a45570088db42a697d52c3daffb1092427f58b2a0921e29b30a625247a8b84bbe576905a062749ef83f0d0978f681e355413a9525f14f299b49ebea103eebac836b56fa9b55e9a6ea15474d50c430b5dd6ab4b41c0a7c3e57430037f13ac40b2bed95c31dbab1083dbab79c0f7b36a684f31f3d8a9dcab8629ce300950f01074d1b86871a3104640fab784451b90c487743a8f91101bc049c4fa480fe0115833c2b4b53026ed12247fd6adc4b1d4b3c5de2e6afcea620bfe12e4c8f99c5a7fe9911f820914075ccaebd0115488da6f65d35b8cd77ef54dcf0ccd453c2857423b0e576cba6725587e3cd34bcbaefe5edb73628c5282a89e15b8c45bbbbf355b39d5fd28994bed8c3bb944f9075ff61249ab9696dcb1342e89f7fd32cd418addf586e85996bb7d6eaa26aa102793807550567f45ad3605f4b77f8e560534f7880ecbe1890e43361f53c455a080c71f031409755cf48367e3397db72da3b1b3069d1886cae24c2be1392a42b7b7cab0bf5e083f85c08fc4e26fe6e8e0422b18591719df56e403497005f1b821027bf80eaafb96953d2736ac18aa7a8b703bc83e2ada1be4dbf9558f83b313a36cdf1c1e0fb1f78645bd4f4fd277218ce82049bfc161b5273c128054d13c7cf0f53bf490d825926a53f349a564376c4d689967290a53277ad3b585a1084c262051cd384c3339f7a25d76448390f488245a1f49e37432d75302f3aaf877d96fcb66b57e01c136eb8fbe4d47a786aecc17e9e8f349c8ee59472679c0f728087deb9d487dfea7cd52dc4114148860d9d7d2baf478357da9bfded61dc9b1bc42baa0dffed114f605228e21eb0cf0b0d5616f9f0b4f4e10c4ade900eaf18f25d675b8a5dd78710fbf426c72adb5e9aba47145ed089db8cc0c30044f8409dd44076cf414b2efb159627d5a04adec5756cc86458acd2ec89c9d037ba825d7816bfd4a59424aa6adf53bf1047555ad4a4f93f56695d286fd1ad534b9bab2f003e9bb1b916796d9b2b8026a6f9e67f4ace7cdf4f7668f5a3df7568a8bc7b4793b10afe67db2863d946ff142fec6415570d83808c41849d45b33abf393cb1b20f4da892ed494ac4f73b47cf128607d16c40c63e0e5590351703007a6e7ce189745e313da1a22dab4437d45805a42552892a6670f9489bd97809fdc74af3919465006983dc6b07cd93eb56e01d72b039d556d5107902241b59615e539b2fbe1af39874688712fc84ec7060945489107b1fdde52e934c999d6487c543ec4e6bb17d9ebbeaa2533721e2631406f3bf3ce55859e3e4388d5eb14c3e57ba802208e2aa6d7c20e45ff44891cc73912230fd97398924b419de325a30532befdef5e81eebd77e5fb80bfb5d6945bc3abb03735d46028cc59196cc626b97d4ad40f24f536177a1a8045050000000000000000000000004a11e9c70d3bec0dee63977897269a1ad97492e9a43052ce1253e1554f96b6b2efe482a52bdf363845b36aef62f89f96f74981191295969341064dbdbbb9ec000949c9dca8912a7721ea25f27965cc5abedbb1961c55512e83cf96a934ff5431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008596e1099e37715c16b714432150a5de70b5a7c811d152def3593c1ea30d07d7ecb83366d4e380af65e3a3b987c8037a9aa91d022584cde4146f82a5af5d0e03b9e50e0fdd8808b28ab253ad2ec4c0112954a537d8af7ce42f68200e8f4dc1ff0ea56d882b0bb219f4c93eb84de9b0026dc89494d74b97cc33ec3521e1be8fc0030782dc9df794364d62961538c597c3f8246595edc231d5281efdd794a0494149021f07334552a608cc8e99873eb21b7d0ac3a5500c186d39e44da42c9d409791940a2e4b83fe57bb7ceb89cc38d178684888f31dbd18d3b3cdfc542cc9332b2616652b832d9429e1b47b1d8bf147adb32bd6f4cc7faf635dd86fefdf8a6ad3a8a1820329f8cb5e934fa681e0e2d542f0ee8c179b9deb9bbb89d1bbb16788fa3e9962ea032ca24b85d007df6f32c8291bb0d172b508c5611d6508c5be98397926747b8ed80221fd678dedc7cd5cfafd910236c69dcd7566dc3556920606432c86109563a2590208ff401d054fb526a1b39de79511d31c8d46392e6587565188e61b17a862917a022c12274f152b186bdd29b2722b92ecf101b7b3677cc37dc024dff6e0b182efba7ff5edfa87ec22850481334cddce03fd794c626fffbda760ed63edb43202795ea672650f07f7ac9c498ad2d7529d021f92bf07677e87351ac2e1fb5ce7ffa26b65d8ab67cda166e18f6579dfa686cfb814b9d6bb07a20af435e2bf1ddc7b81d7620634a91c6245e103ef3e62cb50ab4e60292409a877b01653f5079d12d2f296c8e186b7dc28ae6245bd31f72db24334f81270542ac2b33581c4dfc84518888c3fcca56f3def017a30bc7a8c0335b6103c632caa490bbb8eabe34d707332dd1b19e300766f59169248dc59f2cd1fb82c318f116b737924866f47fd9bf092c193db010cda003f23c7c8b4948eb90bd67885dac978f37da63ae9feb63c4e89bfc79be6c119643309db8a5eeeeb3b44abf064f6b92d1e96e8678b4ea1b17fe9117d5e13e35a0912e2df0236e4737bf0e139b20806cf2a8f8b6a629d45a26be86bd1086c6bbb7dc6af4b9103ba4bb9f76fc91e080c13d949d2aa9bbcf0a81fd2c9e6e82130887e43d670ce9ffb660c9733b5ec0e1f9ece1d270029ef560340cba9e70b61a589c350a07a49482a42688cb60bb821f8e92c716cdba5e68bd9a43f22c0ab8681adac5d3273a07a2325926c3293647b77e332cfe0988c6fc72b076a50ecec396f4336214d1ea8315fd4cfe8b159a1059aecedc9c1b9755f154e70463c81de9f772548b6a86538578361050d293677325a86009b53ca55e5ef9bda13f148c5b6558e9a1509f4d1eec51b4925cfc6aaf64923744babe1139fef3b84bd670c3cc626a57654d52fe3fa2b66392d1dd53b282c836f2ad783131e08c6719fa997c1aeb62a2db02e2a81f50573076ecb1d95b521fc7dbb99f98861c30fa5b9b4b072c3347ddef71dd9cbb37d56f6edaef7e88799a41e74a76b123a069409ce4526ea1c0de032dba705ccc88612bfd0d0466fc86131fd627e1225dfcb3ffb048354841181e53bcc56a4b9cbb8d34471c5b54d0bd6ca9d47c4c47bb1d9feb2e82dbe351e0ff3de674614887effbe140d4cf25cbe3c87c31e41b8b5c737b9026bba770ab9f9300b053b3e3079bfdfe3f075989bd303011d1017e98c4455add242fdb601838f1a8119b9372bb6e7f86abb7a160d4b0ea41a1d2cdf1966c9d99eaa90a17afebab42ba11a4d7b92271809de7fdc090a8bbad16e323f194d61f5175f45639f5fd54b0b72ea931e613b1e4ab69a01550f26ce05e074f161188163aa78ed106272eda7ef60383334ae2404819f86e14610841c0c4873795ddf1c646374eef2d5e5395e28f251540128aca0b4ae1a0d7e95e2a13ad5c008938eb8dbc2e1c99b6c3326173623874d0f5643da268f8668fb6e62c82cdf3c1758c8a4fe718a174721b366c5476cc71edf4e7dc155f29627a314178c8abf6c05af86eb41bcc93b2ec3d26510b2f408dab3f6f54c6da28ce8ae677276831f5ac8c3cab5d61488ff2ccdc632854c6fb2c80a819da7279325fcb57604504f74ad86e219c0b27e4a13c6f35e7b2b368fd5163e88c261134c7e64fb067004948ea0c9d4908351bc0de2331c65b2a999787094b57deb89f9ce72ad6a601a934689faf691dc1986ab4a544634f0508554f3d966a35ce5d319cbc15e014dd6c35861f22b55e8c20790068957788ab2c9f9406da18b5ccd974c9b57c905bd85592b8c2e6d59cccb1d267f9ec94ad89db04b40f29b62446893ef537f838a2abc835e3f0571a14587e2f8456b03bdae757556e6ecc22477e64432a499c816f1bb0686bb692a6f0bb596616c9bf83614479ea04314a218d0f1bea617554d065f60fd168f9d912361cdd56d54bb8b512202a1ff4350decf38928f897cbd370b09", "52", 3, -677808630, "084b6c756e78d03e5a3b17bf372962f737c29cbc54fea86ccc20f109efcf3bc6"], - ["6b791808011b103bc1d2c94fb7ae97b441de1079669e5c78edbd6f60d4d85c29373a3466020300000008656a51ac6563636324eb1fe20205914b020000000001525e76090300000000055265ab63abc73d02290200000000000000007ac2ac0200000000c294010d4a3768e2c416c9488d17c44bc7320e1d6aee5f25a312e7a3d4420d1f166ef704dc4db28149ab1c1285e08451bcdf35c6dc672ac351c7a1bb7d83ae0e374da923c0123e52cc9a2f7c90077aae0d7977628bf7bfe4d76b706aeb2773e7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f0791a86e318910f88216a120c6cf4c93fb128ce1b206560efa5c1896be6d97d7bce8a9821de90e6983b3698b6540ef7aba9995f782d024c1401fd37919d7dd4e17fdc88e2b4928681b05b277c53e3e1da255cde979930449c9f280c3c29e633c3f30d7dbd836b39e7c9d19b90d75f706ed8554cbeb0fa2a22f9d0a3a39c1620322c20bc4742bb8847373e91c26e5a7b615dca2cd270659eff85997898f61ef4c0212a519cec850480ca01d50492d42830e86593c469b77bf24e5108e5ae2e0b0000b08bc1237acc34890987121dd67f7406fed90276cb5aff6140d2856c7775cf4560669d993fcd0b47192c689b129556e4ea8f649ccc493100409417437350f1929032fe7dc6de416f4bd1fdaa7b74d5f9be988f829eaa8db3f88cda768f6a5e6a455020ac6052f09d25d8fac5eee79d036470ea6379ade7f2bc516d6adb913757d5de8021e6f29a403411d254209adf2b750bdbf082c26de3b98a1b0bb171dcae903fb9f020c8cf2aa06e2eb34fb69531778645bc53db2848f652d144642053aa27f850e430202e554102367d42c5a175a4d6f16a685df273f8a2dac980ca26f496debfb515bab30aeeff3bb21bd781e5fdedbf9808d764368de3607b8a4061b083d25fc17fd7426973a4fbc30314adcdf20cb7c97427eb34397bbfcf6258f74dd4d1493d77e5761569527ac7eeeba6151ad5794d0c5a4d9e8b7b7fcba4f9ce4c9faed6886b13cde1c7e618475bc069688e36c3388744032ca50d9f9d498ff20ac6b30975a9d7551bcf90c08cda4b0d3bff7142c31b6f7ecce16454b69c3814ab0016f9215242d326e8f25e9c9f8c45f7cd488fc66fb59df728dafdb3382c69ad390cdc6747d0e0da0a5a7fb5eb417e0bbce8d168ba538b3905e3cf8ddcee430e331f62b7011b61bb443504cd7238becdfdb1ffeaf82c67fec211bbf52ac94b3d70ba164065ddc732896c301337d0a419b91c730c03e1ca13267a6c203c990ec35f4480558b20de2d1575538d8c729149cc3e27ed7eff1176f76b06a561e4d406448a93ce461bc375d33a4f8878fd79d2a6e5bd07c32f3849195fe2481d1d7d3b5b215b97bc0b4dd9262281cb98c2233292612b0daca1dc068f879b8797678e66cbf7064134e6d2c144cc1961b3fc144d42b8d52e26895b6d565fa37f3018830a59098be18464839e6c5c8790917681618f03201a69dcabd91d7e9934a78aac63b67d630b4521b76c4765b29a1a2c42f75e44dcaa81975e16972c5aa1844aadfb38ef87965cfc0d083e80888d92a6f84eed23c19f291f4d4e6181b5e76daf2a9cb326bb84567f8a994681fa1e59053e33cd9175c35699ccba45a8ce792d74bdcd003f770c39843b709f95ba9e3ebe27b30fbadf99a1ebfaccf18054d43766c09d894dd7bf5e533778305f28a42c96d7c4f1c6b9e0b82ea60664fd6b18fe06ce1cfb6259ae9573f9bd24be1c4037170a88018255b1c4861461eedb95dde67be569cd0255c7e2901f8e79f7b83aa90e2e011356cca96476993897ccb8f90412105b3a2c78b0930fcbc3b7d22e861cd50ace4aa38c7bc326a5c101cf612e083dcbab92e4fe834aa2d4ac88c9e064f75dcc3af21d19396d24c589a56ca96c0e51cf9d04128b13cd81bccbfee08464121acb4b851330ee1c180da2e3dc24228083df688ea496bfc9173221fbd7803fc326ddc756fa5c5843f92dcdb594d34bc3ee65d46162caf05115c7e2679e2a82b9cbe450f884cd4cf44941957ee931194d8050c4069dca67ce8f166717019dddfdd8064c8595604e6de341d5427a881544f820263ecb9fcd4261f4d8e8d632de9d2b6926e11cb8c205798f1a03d4957e8c1cd0e23a20e27b51d7a880be11d3391fc12882bef83f912bda3c76936b7e98615e8fdd279cc249b75d37c11f6e3fdf802c1c1e4b6c5b07f6506aa3c7dfb3e0b3aaac2d5dfc07a05f431d9b7d1e85c9b569e4a604220647b30ab8e0e9f323be5eded6afa7f6f5e8ff3fa1dc531a126c0715320e2e9426c78996dc160149ae99dafc3e03a31d98c0acd8dcd06e07c06a3ce3a2342ec3e745798e8aae39fdb41476665dc0c9b82a48ae08780a26647d89fa76e29bbff605d27f4bc08bc55d563ef0bfaa8e7bc642899f9daa8f3c15f18c7392b78a0904d4d26892125e2d256299c61e8c3e48412921da54f57c6f6b512f27e4a3d2d580b3f4445228bd10992879f9799d38e5cd44366db154830d2bb96ea62cb223a79e70be3971d1fa535730c3e4d6d2089e878fcea40d7b420cdffe22fb2719153dfa39b5a9e67c49b09e701000000000000000000000000bc6d1ed50e741067aa02fbd3ff51e7e363940ed582023831bc5300afcf0e16d509a8f08f224aa67e317a1425f88ade3f9263b969588b1dc0b685915b3e52c509052f3c18d250c1f6ca71c864ae729c078e763fdbf44b56e211444d96f21009bb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009529634b4cbb1684ce396021455fdbcbf4d6e61a0c3cdef287404600e586370229aacaa84423dc1770c0dc8b447eed1e8499adb172fcbc6685a40e72b2b82d502932b75a7cbb0a260d1466567115270cb53d77ef4aa728f84f454af2805b0515eb424ab82387994dc445cd83919b9f0e8087db37181871529ef121dbbc7ed1ca0315f68963bca0ba9964f892c7b402f7ee9b9f9dc045494e6e35c7fb74b2f7bab50306e0c239f18d11c276552261b681ae2ca0f1d73b78750adfa351ef2e8bca48630b1e8401cba05a8dc6b326fd66f3009c05687a0fa601c86a8f774a8171d00d056c158a54f589b6d1c2b102983e64088f205749258f6627b91f050eb26a66f542ec022962192c58d47cdc491f1d2ae6c2799086217353dee79221ee8a3164d108cf79031f8ad5defa8761668bbdea74ace95f698b88704f68b6e2bd19d9cddf0263c2670306b697f6037b80d59cb371cb5221fc3ce7ca3c58212547983f164c7fecef9bf1030c02ded10afccbdd4677320f70799eadd66c284ae4daf339821d642c6e338d8f0210e9908cf15dc28d3ebbefadab1b3553144938506512d247400de3cafb7e5ac9dc9f34795a7fa2e46f304105756bdfef422ffea26c18fed1980335660e7b8ad54d102012a860b1d6c376da2f0bde0376320507876e6a2860f1d5e374411ab3279e72a1084bee1b50c04b8c81b3c2605937fb37b9d7aaeb0bc4cdd93215fe88e126f6874e009ba721b63c361ebb9eebc002b4744939215ecb5aaed0239ce26cfa2db0df98f775c8592741c13437bd929daee9b6323c233901472b748e018c681ca75d634054afa3447b8544b0b4dfa8a3d60464d9ae3d508c42ffaad2faad66d4f95d90d771f8363d24758b0763395ca7e8a4108e32aeb225991c4529896358ce8612d29d43c75818610c5224c41441340a586ca790e2d05815e03a5144f4b42e93bf7bbf8cfa952765e9348f6d1f744895bcad0baf7b220dbfa259478ca3c1ee32613dcf1f8201ad5c377afd5a71aadaae981b7d3084da68af0667c51170f95b2f096771c48b91d400cb0763cca8e8f182b426c16cf21ee241b86a38106c07c0c4ae7ef191eba885201bb8958435b3dc90bb1936a74043bf0a5a8b3ae7677ac2dc4afca239df7653d09cfd264deafd8ab66f4b02338942c1900721eef45cf5b5b751ec43d6bb93818bce83a58b601202adca9cf845188ead8d78b8123d30aefe933bde822ab425004013c1427f12b81bd15fa45ec791db504f156fcccb14477c1a9437eb14d0746becff253dd8c897611596d7fe0ad056e86771b29c03e78a912aa94602f77c9a9ba4359ca227d46a831a57e438870762c7c0c989da1ec6b0de4d3db028389d140da81043f63e6951593b23b29fbc4cde84aad7f893ef47820230d14d73e55eb005796f6c9d4f5f0ac9df94745729171ee86c258d16fb29a6b7922d99b1770349b89b6e988d8d61186a8fa2e93a81a15f2c6a651168d0a2ca2af3d493c7f3520a40c6546d7f739f2bec9587de489d2861872ce02bdeaec32d8f1a858a019bae413260fe65a7dcd1de9f8e572d28a906f4c6077331d7ed3f7f87aa7761d88ae76621edcba95b3c575cb030716c53037c376ad149d2ed32b02d1aa83d927a8482619c63b6b39ed062f17cfc10182739738d8fb5b8d0e7ba39fe60ff47cc617bd4952b0b6d6066ebdd4f99994d0b27d0bc797d7e57b6619f92b3238f735dc98c522d539a99d6c781cd4c783bcab48673c842e8085b48432a269e5435a2f5902ca880388724a1c1022096f96344291cea34c0c4abacc6b7da60f6f6d7d5a5016e168a10ce731b78f65dfd20b3430ada860afe257aa979ef359b7dce4fad0d2c3514962c8c97798c774a82ed86a8b9b9003d0422cc0751e5270394a916094de63b08f95ce027200a19ead2b93299bcea2675f1234f14bd92b5bf6129745d68a884a7d0afbaedfff9fc4d4999a7db2e767e3777b7faa5d5dcd5d71872a81c4618731c34d21baa22eae8f5a81598283c480f8515397ebde7793531e4b3ad4b4b4cdeb594328549187e01fef56c8637f863ffd0e678add35049576566e2b98f5de0f80aebfdba903feb7c52c4230861065927068245f45d9496d8bd46d724c5baddcc8dd9c5f94e23d8d51519aca82706aebc9da149c1c84cbf9a6f3cfa1e3bc2f34904eb8ef7b344ad3ba0547f0fa10f3b938fb1b2b4834075caeba3ca538031b490f1a3747a429d35da89afa3f97bbb2f66e321f68074999ceb2971d2f1fa2cc97e4fa2b4cbfb7ff16c972f49c3df4d8d8687e5bd67f457507a994a5e4b3c8d9672b244aec81d10fd36b20528aa1fb5eb6d5bf8cd515cb3f908d1e487685e05c60215f2d168eef5d5e64e94fe4d2d88afbc38af7a15deb31ada74571b9f3598953ae55553db81f0c7bfb67bcdb803", "65ac", 0, 1298665457, "fb640021de7cd35157f1de86bd3a555051eb85a8dbee2e7b453ef02cab3f057f"], - ["583fc53a0479012a9e0330440f130e23a126cf83924b571f2ed3d3c5b4fad568580191e30502000000001ab528b2e9246ecf458413dea34b6c6939c4b781b3728d507b0573e7d31de428ac2d22820200000001abffffffffeec3752b1e5891dfada7ec63aab8675fb35d926a3d32120449b2e16fc907c483030000000165998e8d07166d49703cd04aef2cd3bb1678e1771fce1aa2005b17f4aecef5779c66beb6560200000004ac51abac3e47dee5030d1faa04000000000151d13466040000000004ab525165971be00200000000000000000000", "5265ac6300ac6500", 2, 1123439229, "55fd1cb17c2ec68f1d7fca1f13760a1a9c2d633c32db3d8b1f59ce501364ef0d"], - ["c25e076703e122a89ddb750f09f942d0cf25cb532bf2d2f08482ff79104c57a96600634da70200000003520065835b0d9bcc2c00a4d15e8efd69471df7f08d83e6d51d9e72f59b531307100ac1f99cf7250000000003525152ffffffff91bc687f6e2e517a924bf67136ba12bf03e1205f75dfa66d1c6da534dfd491e0010000000765ac515251656aa42e68ed0495fbd30200000000065252ab656aacba314c0500000000003affc4010000000007ac0052510052511461ac0100000000046a656aac000000000296519f01000000000000000000000000c970770b4ff56aba303e943d42e2a64cb8723f194f87f755a7b82e241e57d9b62bbc71d341add7773512502f562a7e509f6e7f35fe2a0e7c8f9d43ba4c27f0b3e7060b8d7f84ec0063f6b53bde73f0061184579f634a16210d34dc54cfb99faf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046860a5debc701ca1e6023129f844865ec0d969d2a7810397ad2f03daf1ea3760d2aa10820dc4478b8c8336c192d209021414b7833821e18229f6508df4ec07e8f11b0633cb3974a0668d2473ea4321ec71e138c369165239937cc6f19969a289f5ac077174b4966e7cf26ce5f17e5469d950967a492a4831b1b0f194f1e3f2202091901d1c34cec1a995c7da50c3cdae30439557a286f3bd63fe66b374661d9a10321c3cc68185483d8ca991751365a5fa1d31aece3ee1e7dbcb19b09a9945a786e0a2451e8f2c7ccb560ede72ee0c9aa99352449c4c13d9d49005726c253eb30bb5a2c06d3eddca104de42d54732e50aba7c4996851834b2981c5b6375f49d2b9ee90300e3ba06049ae326a0dd40e3597d1edac9b6d96bfd63b8bbf59e130dd855ab7c021a5ffa317cdcd3d9caa4b729446fdebafb36044fd7e60ef646e8435d1aa47e7e0328e1b0eeba02fc296e2e56a8845ab9c599e40f66f1a8380bf98e29d3576c999a0319162b2f5b3b3f0ef1316778a7c0b5327f1734625647ef8197680b8f2275ee4c030e0ec6dab45b9d745075d6eb3ac2e7c73523cf84fe122de634661c8384f81bc87a484fff2d249b3edd8a9f06b15183bfbcd60a39b1e129135c789adcd0688f88701b4cc1ba453d02f87842d95dd483e5d900343c75bd5b882d704e3513a2c5f921a32feedf4b61effc114ab81dba9179f9cd14a9bb1fc1138106f2a41cf406a2e69192ae77d6db1fb93990152af10e40ecc8c5433cb26debacc10d92f4df403a4352ce1d4b66911dfd86a5b68f0994576e6ccdc689e153913f50ae752d78aec8a187aa8cb29d44dd9838bdb5508cf8bca229126c8828241353f69b0768cfcdd6395faf90881f5ccf5da41f05e25f4c6a3dfac24f6a3c8dab513cc3d69fb9009a8594cf9bcd5cc273e2e07c402505070f3d5370196a7a46f5b64a844310761336abf49a9a32ad5ec887fae6c4b2712088d9412c0dc2b02ddad0802a34fe6d13487518bfb81137c3fe0c7bc923d4a96e120a311f71a725e58a452fca0fca71e330099de64f8e9ba86102ea082ebbcf188056f97e78cff9c1c361fa52e3f42e612ead5c0b9c33fedec3b311c0044d08b2b0199dbf53245a1e5a0f64560729a92a73d96b7c6c890fbdc19dff5fa2464cad15d5632b034aef13e9dfe217ba21e5e7c8e5f2ac9261dee61c894be8d1cac778e8f1f4440b85d3b548351e326ae9d398cbcb74f13a10d66023d461b5e3ba9ca1615014968ada2ed60ba00e8f1552fb00a49e2c7815b06398c93af1f593c5e0a35d3ca3f0d54c501335da1159a11cebce519bd5c412ac3c2fdc1e34cfc76c8dadfedcff86f8eac554c9650ee65eef07d57b61adf259126171e89847923fc8a50eac31c70abbdfc136f53d12706ffdcc22c80107e146b2900b2160a4fd01a06c68cbc3264eb6dbee2d404a9fa6f8d717a703471cae02ad1c1582a60ae6f3f623056de10f62d49c34d0a6cf23050ad583615b5a19d0d56e959453dd7f2d2e3fab92619c3866b52c718d9b17528373ce139a084955bf156eb0dc294d2a22001c8f4fbb7a869c831712aa89e243c976e0df44bc213308f4ec4e27ba62f4f69f132ca931f08666e91e2f3c686cbc3c77e4fe107e7c584cd39e95e80db715e24d30ce11d3bd843babee178ffa3e0bbc936ff82e2b3f0dcdd8bf36d8f12fc7299d5eb01963cf872c816dfe7ecceab228321ab4a9145ff81eee37c09c248e4a5e2738f6e39166a4cf2cd639b5c451c8a1860f72b4e1c8beece360409fdd6b0b88dfb29417128247e14fd0c93f636059af0a668aadb77ffd78d311722fe86dc4d50f7924974d15d409e51f3266895586cb773a95abb19fec022c35aaf1a15fb248ab03c5fee7292b6efc43f50aa9f1bdbcce901d6a1fdb960091dbd5ed33ce2e013bc97a622e0af9e2274e2d35f7a7edf5d3504e994ac466e6c05b54963454c3816326a73b7538d991573ee1648c9cb84b1b59a351c671e08c3f5cbb98c9feb62fb3d3e29abffe7fcb8a2c27fd8316c907a2d3588679e80d59e7771dcc9aa1cb38e4ec6ba06b72255a750793d18da4e16bf12f38f425630ec11ff33d52fd30be143bbe795de920cbf0d0764ac25c35c211e79244ef846f64abfec2f1e9d26d798bca6726f4bd89ad97390dcf61c6fa0fe334e9d6b518273812a97b0332a3f8ed9e09e74010111829a5fa99a27c212793f18cc749809c8d091f7902078f46754cfffe4274db100d1a5593e9a7c3b304f9a5522193cbe1f199537ba2b3ea0229009a0c2dc3ab8daf1400000000000000000bd8f80300000000f0543b0ed18a378b59cb7cab73c3f9615c3e51869ec61b551b4f419a8d6d55da404b80eafa701e5e6c8fb68fa6a72aaaa2d6b8a856fb3570a80533966c1920c2ec82ebe76d5fde7ce0c0a4ef3a2d9e722bee12a10cdf774f24c3375ea776262a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b399f600f7a36e83e4bf3f5d14637f9f42fbccb4fc28b40b9a298964ea950bfc2babfde36adaf9b47add9be6ea932bd01233f63d29d1ebf373d15376a385ef638bcf382eabd50ed872c659447a6d12f1808cf32986be62686bc3006cf5fb1789961a3c157ba25be02dfa7e886bf68a96aae2d40fb7018141c1fbd66bbc824bc020575de58cdb15f6b0d4c7d18301b0f363936740db405153a2dedbff4bef101c4021d6686b2848419017f1baef950574335f893f48923350c9509f2c9313cd4c8940a26415c8eb38f34e29264252a1b56eb96996079fa1e0594efbf1f5b29b6763c7c21bb9f6d68fcfdb78447cdee785fc1e901673da5318b31a02f2e9d02193e01cd032f8992ac20809e45fc3d2102a170b7b62e1c9a646fb907d7ae6583b02d8101ef02064511eb7c4502533e51185a61e8e28776f5fd4fc0828d53a5a6ec6d36c7c14b030d8b9ce7d13088f053f9742a299ccb7085d1e153bedc2d029bb18c19cc7c8e5b0319a78e90039ec1a443db987d9cb2491f0aa5649f403996f41685a5a88ff3c7ff031e39fc968346ee68f34e9246493b3dd001e33485501c23dde16ef4ba239535195bab95beb1f972fde6689b5cb0c43c0e896128b3282a4c0a0e56ee0a733a8e48be596b6801a9bac3dab41399996017e658a06a90247b0e01a1246bdd421e36ecef69b501aac24c76c7cdcf77a5ed6bdde93f46d4f37d7f85d117ce03115a43c8ac16f62c093b6ac797b2e416ba5459561892369b62bdec5e6181b813c4a513fd056b0988182a6055f18f2f41fb10b3b3dec7790cf5d9407fb527786407ea182bc7634ea133b31b3278f8f39674f4841560a21017c8dd20f9a955c1baa9e6bd2532652410c30b7056043cb97d53a2889c44e74e1e9fa28fe00cfdb724cfc280865f18087623fd4916e7772bb4c3e9dd5bdaeecaa424511d9863d7ccbc5665c27975a67a4e32a38b3a4b4f794f34616ef7c99b50990929ac1bfe83288b39c5aea6b02328e217e6c1f0988e9cfbf354a9b2cfdc8e27cf0ed6ef3e489dfb07de66869ea2bc7706346418f4882f53d3a5b87c5c88e73fb09e2b776d44d84fba165620633b67d7c53c3f6929a11b3e590280f0c5b499360bd5cc95bd5c991586be10482efb14e518bf6654c183bc5b2a3955d24024131bc001bb63774c391578488bbfbf91795dbd67c1273d61442e380e536e11b82ad04fb0d39f821a7e7d2b5c5a3089544c448177b21780299a0da8ce188ffe95acc3ae332b07edb63bafa1a931920edf73c3131133f9683e111777b4ef19ef6b1b50df742a2fccb09c631b9097d1f518cdb78e299354feecdae71442c01d020c00b2a6979bd7c031badd90a8710aa4912bac081819ec8098d185592a77950644db0d170a3ad5fc74d0e35c42d881422b02a724578c547599259395ddb6767e6f2ea29e2df1fe57c5fbce458bbe5850ddc27ec33cae574d3cbd8bcaa18ea23b7f12c2a2a28ddd04a6b46b31c484e87e5aacd1d0b8ca8460159d3a5c76dff3bc05924ff9f3e48abaeb2a9f3b98711b0c47cad069897576f6464a5dc9868e4cfe92e51d275c847c4abcffc6b9bf2de8327f3b2f0b5fc9cfb66d40835fb4403ab2604a9b1f3158e19c8e9eb72cbd9d4dbf7e05cd7aeee48e03f4d1a5fb736b5bd45d469ca918c0192a2adf34ff328c82cef96332b9311f2a1c45edd24df93a5da0c35f1409265a9a224e0360d97bfa07868e6ee3b159cb9d829b8f98e5717c92cc7c0fb16de2b99221664797724bb3cd7bdeb674dceefb978e3825986e950d805eb0c92bfe8898b4192967ac728a3f8028fb0fa9e4d87babf48172d536bc8946ca29e79d06e71810193c1a0e367578f925bf07ccb54e63905521e3ec38e7ca71fe32f53d6e0a15774c331ee799357d5bae9501fe6baf3321c8761ea2d397d70b7fd498afd69684c0f82ed71ea047d065f3795966033f274dab1fa00adeb478d4c47d6036d8ef82c6c625fbf7791a57b6a340566eede2366a3fbf8d85e33248bffd6251f3c2584f714676bee7456f0ce558a073dc7952bce9c9403cfa0ff81ddab9ad989ed9c0ed5779d4006b66d214ef708cf47de9f0b34ffaec3ab9bc4f7371d839aa7204cbdebd1802b80aee71db38b72f13051ff954de122a406bca28ecd97ad2a7511da52992009769a2e801b3c5c5262d7cb18e4f9e1786704905548b0ceee18955f2ac2583d8ccda391ce8d59f53e9dc9620b865393211593028b4e3e4af39dbff7fedb02e42b2ef48a87713405909fdbfec597a5f545273a38da06d6545619aeabd2303cf065fe4f4e13c7ddb6a4fd563cada3d9c7a0c6f81f30db8c29dbcdafd7e8d2834fa3ee4a14aaa79fb6054e65a368a9ea780763faa52cf7ad9a4249439e0b2bf3ed1bd7d701948d3fc99f67ad52004f9630c72406924cef9271802", "65006563", 1, -1138087830, "0dfdd17d9153ebd22e8142ea8baf4fb86a30de395c335032865ad81d36c0347b"], - ["c3cf14eb04668efab16b4575c7745340009a2d72c9a724b69a959fefd8d6d3c9e1f2e5928e02000000086552656a0052656a68783a111ce036b399b6111b1ff8f1270b3944826a1efa4639edeab73f8af1e24f3438d80000000007656aac53ac6363ffffffff149e779af191ea7928be6dd8a37b6f4ac42e5c10488ffb3ef4147bb3d48226fc02000000066a6563ac5263ffffffffbe78852b579c2d15a20c3c2c467e9c78757c9103cbb3f5382f4e298efa2094cc03000000030053acffffffff0144aa0b0200000000066a6aac5165ab00000000", "", 2, 1379973953, "387e127df56d79965bdbcefbdcc16532159c46f2f0496f97e275dc11d08506cc"], - ["32c7454701d837c1a6c63e0ad8feef52254baf18567720724baca6117cae2ab7fe51e2ca890000000003536551ffffffff02d4ca900200000000056563ab6aabcb0d75010000000007ab00ac5363ab51a74dddba010000000000000000394a2a0400000000f434862b65ff451ec5ebd2df1c1fab15115af597806fe2d0fa2f5fc1c0cbf2edb1fd0ee00396db936a9d14e097127fc9177e1e02b2aef3a08e79b3efd0afd9ba04e4a26cb7296b96b9eeb81e3897882f351be120873313733dd512b309b5a9f10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073ccf4e7f61c0cfcaaff4c6c01cbfe229a72b2fe594a274de0e1b681ae44fe0d9bd49f1e23c6a9ca38c216b7258b0f72920ec9413ff0b54c0324cc95d023f0052ff6b30f37fa2fa4743dcf08081f24e91f432d0e1d2497b32a18e724f3026b071e08a847f8c2ff8a96fb414462c3081eca0304e9aa78bf751c0a853025026313032484a229dd2d072e8405d4565920785005c3dd9676addba869d18a420bb8c243030db83871b9820ed44da9385fe65acd3e2a22c0f169e0b7e752a814b4cbca78d60a1965689df7ecdf5ce1d131d2ab11bc2579e68c8df9efad7436b3b88fff42192c116893333d6143c5d31f123445b756d9b0a87eb5b8e3b52a348c03ec8d5d9bdd0316aeaf60f49c357a0aa92d184c337947f41f05a3b5c8ea7de28dd816dacaec260317702dd31e518b99da81d9be364d55b4f8b8ea91a7fc06c428714b0b302056db0327a72b5fccc760214866738b03d63f889b0efe7099f0d7ca39b8fee69cfa901c0210c61cfa4e295a2f429ad08c7eb4b86964080e9bec2366e8df334c2dad225dc3031bb6c582ee8c7307b47bf59fc472ee1068bcea63fd87fb36500faaecdfd3615fb3844656aeee665dd11d833663ff4c70ba0c9496f271a2e7a71a1213983e18eaf95dec93d09c3915baca3092118151a1d22bcfd3675c2e8d561aaf3a019ddeb60ae55d2126f29f04587dbd0d6490dd300191cf17b4875d1bc2d73e2e4345c710c49cb16408d5935cc92c92002f6d3a14363727e140a86e6f2afc1ad9b81e354b2ac4c6f6b96d69d0a0cabade730e1cbb3371162d2cf750c404edcf7e3581acf9929c8a61327e2465997bdf88f5af34d6f1d403427c18e05764fef335faac04896502999b5da8466e3a88e659733ac38919381ab05b03854b24e7b7089a459cff4856f4b9d2a9d59fd07131f3c2b49c65f0b9555b33afc7e2898556f7fbba8a72736ed8494ccff5a3695b2f68dec7fb5e0abc7886464b20f54a3884bb99ded51c16031fcbf40a92eb2f8c6595b941837ff1a36dd672dadb5745f872f56c27ece6abe53f2520385a9220cb0fef89e995c48ada29be1cb01e64dab8d05d0c1fda028073fc031205e391324b020bb032723ef19aa4a3620401bbc447b6b93d19cabf566fb53e41b4880c0964a668dba10cb2902564a629a91099a20896754273465c879c1c9f3669069f006401088de690891f970ff1085edc3cecae41eafd154f237c1749a164e7cbacf4b44642697583a87978c186d73cbbc351915f58ab63254daca88932c0bd66835005e6cadda0f8907051e64ee77c7856c42e73e6fd9861d6a2e07342c22992bdace74669f75f22cc0393f00d947f304033034817a7dddd6d8c326fe0bfc853c9dcf229d93b64f856eaf54c694a5f07743a90b580ea35b8272bd01a8058dbff97646428abddeb0ab1061309bbded1c3a95a2e021fa1dc2cf926c3d414cc64c2a652d69936727ec46ce8131d83c34e8223fb46ef0eeae4e4f8676cb7508c2dedc9d8d1fd286a9b124c81a4311eb890cc7ed84f7a5de5fd6c5625b86adc556e4c077991c9a8c868d9e003b3c45e0531f9819455b93ae5b55cbebc7fe4204e1e5483c921fb15ca2b33e0700db4f9b4702f347b539bb4144a89353a9dbbe290e5562ca001af505e6393d24b5f3deb5c257af3179591d078ba9cd474a5ffabd5daff7946926ede528fa6b1ff38e72e8b812e370976b00ae85ae3584274dca57970b56482f3e30998d62e2af96aa4f0b3562b0b66df6293dfa9e16150582f97e534fe9f9e5ba4721bd36a52918219aa2627387827594cf50423acdb12dcf090cc69d2f686953eda253683ef5d38d9660739227a22bc3e1c2fa223d192557be4b56cd1075369cd40817d1389a28e12e7423ea75fc5d2466422690454d592cd931ec29bb90368348e0072e92d28de2f0f8251bb4582424a0a921727e2e966e45410b955b91a2a4ce25185c2c224568e45370228a3daafdbc11848e6dd55fc82b69282af68e375a5f84eb92b4f97b5d6a567653079f9e29679cf862b5ec3152363fd41a513dda25075def85f623b1f78121f074967b72ee32b325904d53c3dd998bf64dec2f5fc2a3d4bb0a23a65c9b0eb93106c57f05c4dc53af52bb7d37aa2a9d96eb8a90fba4932d56daefcfc3ca127087586d6a15c0cb07031cd5c9ec6e7eef24869fb1c839728565603236d5a00c7426f3fbe14c354333629ce3b597a0d29c2c26a3015c787020c5532deff20fae05e02d839e946a63c23d2daa039d7ee6f587c822775e0ab78f9928f70b71583007b1026aba5a53524413bae6be80a6d2cfc96b0870b0406b6cbd46805482770368063c8bcabb4348f3012ef2efd83cebc8b300bb1b64125c99d69755a43273f1376e7e6c60a096f7be23f065b98e8a3fcaa0e2e4a3cf5d70b1dc3e2abeb0e", "636552ac655153", 0, -1236282920, "1cf4363e83d55e79b5e658cdfbbbfdce529a2bf93b19f95c3b4d2c7f4798da10"], - ["2a58d205022ccd0bfef60e16566246832551140f251a2c5e2c949611977c03d37f2721adf90000000009ac6352ab65ac6553514c074bfd8af262f6385f56231e9d00f14f1758db062d0b2dbcb46f31b1e6bfa90ef36af2010000000700ac6aab636a6a1ad6370c0116b4bf0100000000002ddc08cf020000000000000000bc5d3d040000000037db541e54fa4df50ff294027fb9359706839ef98dbca16f407228d609cd07f276cb333b7c41202695de61f9f1bba46ff1996795d3a98a7398b4dd5de6641fdad982ad68a5bcf6b2b22cb0566d25c6dba0b0f8848a5913e6b7feda2957ee450f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e12f6dc377b17bd29a34aaceb0ef695becd9b7d65779658b0f19e7a2e87a8590aaa7906ad03af5bc415648cf0aa71724982ee6d3d7a155887c761bbf03f58de8893cb3833b3955b10532c54480bbefa844e21fecb5d81d1890ee950ff5b920e92855beb609f39421f84943125b7f23ba5af7956fdfa49e4e0da8c78d0eafa2b030149820e7e51a55adc1b82c7ff54b66e19616a67b5e1536ad84b5eaae8ba9711030dbc89d79dd1c817e0ab85f0ecb5cb7288e4d33a4a27b3b1b0d3eb355eb2464a0a2e00da61200911e11af147774beb757f6955f3951c074b96595719c53463cbd827c9f0937174fae935445fb538309b1cf232f9d92b3d37d9dfd3c39356be4b8d031cbd6d82844795af9d2be68546a1ac4c1f5a12750d27de3f2502c530520935a602225a1b9f074440b12207f35f7e89402e06441bc6e48e00f2878a5e6e99390693031537028fa08e10f02436fbbb7f0230ac265f04a7ff8e6c61f4fef1b9b5dd17ec021b6d9c635fc289fd8dd437fba8e1e99ae594c996b6cd3601eceb72e0adb61710022eccf05ec66e7cc81f6d40100df805cecc2768cfb35d179bbf8043caf254b429ab278d5d51fc2cd68bb134a5bf8c4794c8e8c0362c2c0beaa7d9e3e6ceb7cf0c6474ed7843b11eaac34569108e80a18bb7c1a85a31febe630f40b4d0c0692678472c0b49420adbd1d8254086ba864efbe88a7a55d0263fc7c2778a22ab914a5e974e282fc038850d5d805d6350748e6846df44d717e2d2d6e04920568e460058ead6e78f8ffc0cb7e68dfaef2653416cdfe2629d1ee63636bdf599ba2eb22a6962e71411d5f17ab3bc326b7dca72e74e3e8d4682bd220648562fbd002e923c0b29db569386e106f1486d8a71fbbc860bfda9bad5518f97dd40d54eab7599e1e1adc10aa14ae43ac11537ec866b2b0295aa8e9182421da1f603786ec9670aa9b08b1f741d8b5affb23fce2dbb5da25b118345a39e1b8bbca75fc2ee7d06e4bc5380d0aa7f0c8cb4665f74ed376c6dca841c06fb8792f916629c67d56e45ef2b428a1c61a8fadafa7ae4884cc40c6f0de4d59b630c53632217ead6fba39cf3712cba38a0062e54b404dea8c5587368b52b4a3a51297434429c09870a08c204419bb03daddb1e84bb4f4131f0bde10608ee3f7792e6e7bdcac6acb1bb533736e1bf87c80e9460f07074ef1a8b018f4e95f9b110527ebfc0c8e761d158cac83c92e08cbf677d5d094e9ad8ecc0f460d7fa6a5cae8ba6c9866c2d2bc2513a792a991efe75d1f06dd05c106d53d6c02f96fe8c49c129ecd26ffeb91b6ebf2065acd9ba7e2c9ad822d6246f3b383354efaa89c90c921a00881d8acffb61a387a85067fa2fde090530f1cec6159196a27109da8e1b0aa7f6ffa75f3b2bbf1b927449e0f67b34f8fae6b2a560ba396c673ea43a9dbf78f5d7085b23e92d8b69c73cf0f77abd98336f1a9954dac238d34e5ce9373e33201a19739c32f41e0f53015321857e7477ad3afef2aba2f84b6bc9cf3329f6de11e67fb21411f9512b776e5dc4b583e712825404ab23d1173477099d18c117603d9d1d6b27288aba26aedb31f5695c50244d85e95dd5e3d398737309184b7200383bf761cb2282f6257dfa5422f425d79ebbeff73606b9de82224c3235b19487b75cc5da3a9d23bf8294b9320da1d2032c9a6e58e1a86d1a170bf02211e27c306718832145efc474feae34deae62da5f0eac5bf9534da0515208b60d6759d6820e1646408f0baeae18f502dae7e08f1d6e17e1ddc03c4f84192c3cf2bb4d8d8f43f336066510693edbcf4573a83f3b0f09dbed7a68c896b246a6ca118dd32459ce55a15020f909dc0f417172487a7712eaac82aba6d8bf72ad85f0e201b6ce79286ef98fedb67b310598b31ef0bb76b4b66e8b5d7dfaf0155c219aebae498dcad7d059c2acce77213329f1fc8d913fec474ea6bacbb6e2243cbdcc78b8c35492a3aa7f12c01edc810e98af0374f330d08148f0d749821160854dfa55a249049196dd3a25e22a552fbdd3a20c20b6471f3bf89c426880a50cda88a567456e19597415c873552f84caa9b4467ca6902e281255337b6944f6dc47d297ddf439abae203937bd45667b082de32c0add1577eb8e96a6db8758b12fdc0c05b0d3f0367adbeb893806516688eed3d439222fe7d9eaacaa84c279e8401a37feabcfd2f312607329cf50ea36e8c5af060f68bec415b65544caa378e29f55f9d5031f0f73c863d608d44f396aee4ed9b11fcfd8d10d790afbf55da03135ff63b65e8f3d2d757200000000000000004e32cd0400000000c391545e7e9a44e2c6f59aaf88b956fca4513b4343ee16f5ad056604fb5000cefb228edaedb153a10c522d65e446e14771b0a9ef4545bbd5b2e8e8c7ab6ee5f4b97d6ebf239d71a3f6f6d1bd16629d424bfda2253c71540e7e0afdbb4f20467200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c33b2117ee1bbc87fcadf898ea510ddff4f63351ee78857fae8df175cd96bc8836c6175578e482e4934c656848b882b90a1cd86fd6452bb546e56481bdf2527ea7aee6debbe0861a21f27e1384c83d0da8b81a8aaea7fcd040566d2f8b5d3795e386e5410913147461d877b6ef68e605befaa9a2dcbae2664dd8901f224bdce6022c8d497e6f3864f86c3b38a39be343c5dbdaa5f85fb089ebaf08b2b3bca866b302281434982b1be726fcc689e549ebf3665022092db6f7e921b54df82c8f3d2b1f0b111b78b0a3c824a82ecf8e7e82e2c8a11da231cbd341de5f2a5f331f6923c0d000c9b684bc72d4aedc0e3fd5b7e19aff01427cfc002658797ea2922bc335c9ca031920bbe0092361e790cd303cadf2306bdfcb66b8f1c58d33907d5808f27563460329867b41dc304d528d6e6e45c9adcaebaac7405be5bb4ee33181d4046bacf0eb0303dfddb43b48db9fc9da56386419a08e8f47bfb7588f188d536671942104108103197008c83146e1a84da8935ee5df0ce105f8c8b43009a1600aa48decf24c2a410319e84d6dcdd91be57f97ee40d07d359a63bad1179593927876ce7176db6ebc1bb258db352869ecf9c41ebf589be2ca2c130d14d66b33f1b6e1ce39b5db2d7d37b907be600ffbd1b0ee336cc823593dc6640e1465b5cd2ed962d5041755e4c300a5d9f2d0f433d6f08dfa7ffa959c12c8358adabf4d2df16299a564f8f33bba6b2b5884be7e03dabc7d8fda0dec17f95ba208e8e4ef9455e5b58f4c4e02fceac0327581ebd8cc1e2efa639f2178924dd3983d03b255beb82641af32bfde8c558f299ee0bdd15af49e887b9bcaa754345e683098efa54ed11d6e08606b4a41056dff329c7849c079fc49db8a1c3b63054a5efe0b3699119c26510a92fd2e7be8ec7a8f2cb1221c2228c62bb4cb98cc9997f95ab551dd05d016ecf280db5882a3a587888da4303587dc0ced74a91afe1b80d401686092a26f4ea0ba39d05b9668f1db9df20f2d345e85d4490492efe11bb874bcbfbf7c194b9aed4635aa24d548e763a57febab6631d525403129354fd5f0793beda34af5d50a4c0fe3736eaadaca3fade8e0c773cd39d6cb7c78eef625f6338420c47ddd413c05cb57b44328ed7619ca30ce55c2527173a9dea8f9836cbba691c956b40126a2249952ad42724c24597e48ec6d0cbe785381f74bdaa403da97b0d0373d9c850c38262324238871bf5c673e3b43f5a42724e98cd2245814d3bf9c0fe595ccb7fa5bdf7cd811267d2120e9e890c971bc7c92f69bd901164c641bf62a34a7bce3cc5406e640f1090503efd11e223fbe44ebbffb5bfa5c9a66f39d618e9ef3eebeab35a3266418d1cb9835cc52038f069a48f9f8c89ce46554439782321b4b7dc5bc89e98c3bdb81220f799fbeea41676647f06d8732d22adc0156396b3c4fdc37fe77ad1c5be2ece40a619b705d513e78eeb0b74ee905b30d8152758d7a00153c4de1170da68f3b26707170ab8062c917e8191a42929a19a8b266f4099adcd15834814ade27918c989f8882b9b1d14c694805ea92376ff54c0d334a88edae2943cefa97b6ad185ffcfc07691b1136dc278a9edbb4d07ee2ac51ed4163a264a6ac0d3fd041b85becabde95618b0fb5d40ad38e60da1746e103c8f736c8315096ae6d11230196152f773d1d131804992dc8c42537360c505869a6bfd4e7cf005e70abb7ca10605fa1a2ee481813f7b47e9607c47f29ddd22627fc051e0ca0c15d6e11bf63f61d52e5a9cb43d7d246206f8be0ca03ff82b6d1c79cf85a7d808d532dbe91ba0c5ddb36296c191cf5023c47de93235831ff190459d61dd93c435eb5e7e5f4011e84a64d8c78412970a281478752c4eb094ebb076d6d8ee415756c41f448d2a2e119ae7a746e97d7355fe772a84738ec667dd17cf4519ef99741b5a4b46d019cf4a2de126d9866f2d13a235660efc265ee40dff14e111e43798ceb4117d5bd49f8ef2864a2970446ede1829f4421b4d95a271115e77fff567b760bd6712e74b46387ab5249f591c617e729b4615d8d61b650efc48e186e98b110a5da0bac5d2cef830b91ca41ac25c827f85252619e251e2823308fde296c31ab7a036f89087a6880a6a1339772747f781af23c74721b4fc245f203bd47cd764aec4395427debd7d9fa8545939aef6d912b330dfbd6ee2975774d16364cc0a1e94183b280cd9bf39d04728aa6523a1805448514dc11e927de5c53383bf0f9afced39102aeb50d35661817c55b4f746deb9d5927e3268bd288d9fb497fede4cafe5919eb5ef3b69952ba359369602c8151e78b68031f752ab05a265188271005843e9759b666de37e571d0d9c5937e31a02f6ff174c5bccee10e7c10b8c4482d26899aaf8757dbdfe72583940f858730bfbdc99f39b446ba4f3e72bfcf4c0c", "52006553655300ac", 0, 809922732, "35420a3c2aea4dcbd8b85fd458fac620a1d2fefc956bec8ccf613750ad155545"], - ["985643d304fd3f7b5148143b11e38306cb3afe70b71b420dbdad8ef92214c67cbf18ff8bb1010000000765ab65516a5200ffffffff0d82a105f6fdc3ae9a6e4846563e5e956eed60b6c27ca6230ca0222a4b8c631d0300000000ffffffffcc46eddbf01c71a777436c1eaa281f7d2c4c7f2c7e5fff5b01e3f5f9bbf3dc5c030000000663ac655200abe9af7e1550734e46ca4e69dc3b3fd482a13e8b32bd009244a92345138bbda17c18946ba00000000005ac53635351ffffffff03063481010000000002ac53ccd7a10400000000090063ab636a6500650002d5b703000000000400ac63ab00000000", "6563", 3, -369456481, "5a322b00c2ccd5e9f8586be959731bdfcb2d57045ec30b3e919ccac2f65c22d1"], - ["20be07d40265da8d5c54f55a7bea15a675fed58a9dcb2bbdc43778c37ceaa64c6bf4e0e0f8000000000865536a51ab5265acffffffff5c45c5ed5adf2cc99e4bf9d3af0ed2ac9e589e175c165c056ec051fc06ef20c203000000026500ffffffff02b92eca000000000005acac6a006a91667d03000000000400636a6581e02dae", "6352ac", 0, -1051900195, "724c4f8f12074a37c786776e4acf21eca4e9af89145268421c69934cee759be0"], - ["e9995ee90148e2a5f994c608a99fad2d3c7f025c355dcbfb13abee7046cd22f4e04433e1e10300000005536a63ab51ffffffff018775a6020000000003ac526a00000000", "65636a5163", 0, -2014976053, "8c986ba7d59f348ddfd0777587a409b09953e0e8eb57a83266c129b52da1603e"], - ["a01b61b202e199a6303e713d52d83ed7e411dea967b5816f87ae860a021e06ef72f1d3ef740300000005005300ab635b1a4311d651dd2abaea78cd7c1e9373d385e150b5ed655a92b7b26cc9838b2c8867a9600000000006000051ac53acffffffff03c224c20100000000006696b20100000000096500acac53526a530070230c00000000000352ac5176c8881e", "5352ac65", 0, -949295909, "dc920ccfd882a8f18cfe4388ee7d4b01938fafc468825f51d7c68ba1e06d71de"], - ["5f2ab240014a46f9c266c131fec2eb5baf6105c9f0b2a2d30be9446f4e274108c14cb3b788010000000953656551ab53acac51ffffffff043aaf29010000000004ac005165c5151b020000000008ac00636aac65ac52cd198f04000000000253529bab8d00000000000853ab53ab655151520000000003f0b9d103000000000000000000000000076b4d8692631b9f23466ffbeccb5cee7fb6da895960fa7d80fbc2bf203001fad1eba6aa79a0c878bc91144a0d51152655475ed417de7db7c569b452d6c5a5f2c05dbd2fa0ff5251e0391a153599035854e376acd65b12f4cd5ee2cf789a0e49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c5dac04033fdc341b52326fe52edca136204bd075c95e8ab44ccf33f502a590d3f5c56bbdc27b0c76428e5c5ceade78388a43749abdce9f2402252b554a05fe3d991a2eddbc0d9b0ea615541a612312c289e0ea296e582b0eb244ba83f9b9ce5dbb239a960eb3e75e237f459130c6373285e85227d8a8d1e5c08e6d0170ac8802220063ff18428ee19e55ed7c216424ee13099d0109edabe7c2779aa8390a5fdf02091119539d35ac8444e2dcb0a9e0722416f9bea1b538ec94e9ec226489fc79f60b039f08c6b2a2ea20c1cb15e51909c67cf68c6b6df1e20f157c068b5ad4db944402dbb280361d5be624fe0c11f615fb98b017986dd19919b66b559edafa6149a40315fc9b700c51ad5547ef5e3e4079f7cdc11578b6ba0f29c36f626a5313042d930202c7a1aff43a00f5621da4814399989e47cbb62672e1e8c89e915f7983ec893003066795da7c3714f2ac8d2be9d0c858407d7d077160826a90753ca1c29e39767f0311304e038089c589e13c66d73508ac49e87fa202136075970a05985ba25503c4032a005254957f7c59aaebd9560f5a18e0e169181f20c9b3f7d5fba0998e687f11f00ebf573e083b436d4c96ce25d0c0a0309f3d57ae9770bdc0e911f948040a79d919d7f9c19f136bdfa6196a1f06cc0c3357bbce41bc46ba2e4fbdad74d5f1c8886ba09fd7fb3d331ce57c2ada02aaa1310e63194f38fa6a2cceab990f2955ce45f4c822bcfffedabb5b6413d0c6c84507a61c0dd1c759acb50784a39ac1f38fe0e638d73c12005f129e63c8e78512d1e5ed3c4dddab07984c16463d205d359b50611d75b1b30921a7d0358d925cb2be25e2d1c1d2a1f7fa8143527a6458a1ca33dd77c05c1f4f24b3679c4761137719fe36cfdcb103dbe192b4a4e269b08b2b6b0d88c336c68c7241318be80307d57ca4c4f7cfeeb540931083eb59925eaad52d4c2aab85039ee8d53e751487007deb00bceabebb5539a4c83d4aa9c5eb4a0ca2c81decfda933d8c265dd993ea2e4b7449fd55b820ae84980fff6d73002993386016192ec321db34cd1ef4931c7be085069170e68563721b7900b6cb8c1e68d1c162f8ba627e73c151ea88bb5a5ebafba8b5c3e1f9c0719ddfa55f602779df78bd15b6b56453c0fff6fd9a603e479f3817b637102c4490f6a77732a3f8c76ebbe90403bb25913c813ebea65178e55dc842a8bfaca0143f29a7fdcc233b20899a3112ebcc849c299ce6045d9a835b68069294f5e79457eccd4b4067f59d4debba7824f265133a8953670972603fb3e58dd0e88a4f5dc5d05be39820203551c25ca2c2f0ac4be60ba8794f86d13b83456f1c794e2ccd1f03dc005e37f6f3244231a11c835664661aef56c215672046646e9070859ce9d7f0234a6278f0dbe33c68704b20b742fffff975601f2f32713b1775ea1f766ebe7af6ba98446cbe5aa589c56a74c159467fc2a768f14d6e509edcd1a427f0923251495560fa00197877a8d78a47cbe711837ed6e2eee937965857cbf9b0999c9c6f8fcd3d5f892284c9125bcc80aeb91b5ef2fadfa3345e16dc9001b729ba6dbbc795a6d67f4a6e3baa92ed44a4fc9e474646629ef37cf0006d976262596572a58adc22d1386738b930234d830951005127db6b9a99697852b5674c82c0eb7427e923ff63ef6a558e4e3849f18c5130d25076bd17461abfa10a824def5a34cb3418296b01e5cb32d42fa4bf97f684b60ce9be74b4a30fcd377b71158730c083b094e4e2b5141f76dd21fb94b33359bf3f651f81279116d76006c3f0afd46dbe4cb0692624287ed8457b613d00e7c6696630a985f4df9d47a79dc22754aebdf46da8a63a21d93d35ed56aca76b3e95faf077982d10076b72ed46f8aba30de93bd42726bf0b1ae801ebf224b062ade3ca617f033eb062af41fece7a77ea6870a3fe8ee67eb174e2ffc5e8d56226d754821764eab45126e42cb118f8651ccf3e006f10b74c08993028148cc0c14e5bfe1e2144c1ad0b1a0f2038724adb45742cf28b36f336758c5b8430e206ba18de9c303319a78aee477ad5916918e43b75be626b8b62c665602be16d928e0b4c5b05f5c5783155f730b32c27cadc684e61ef4723621544dfc488802be396452bb9bfe1941baca8a71ed94fc85846ad3e60465f5bff550de6b8282cff1ba247e2e90a64d25d082d7ec87db6a73a76a7b5031e2e2d515c31d22739b27a521af0230f68bbf5ffc8ed07a95282436bbaa92c4792b2e4b1c3d08d74ac35a7325957300dcd5f5b3758e662f085cedb87c5f470000000000000000b4c2000000000000ec93c8c10a9a394a862445b544e257acbe3efbebd08747a00e96f99449974e296b6ef8c9ba349f8a7a24904dce2f34dad01360c0edc8123d8e7860cf21ddc3c64a7a6c14e53daddb55106ef330032e526d1260429ff2410be1c41475b82dbf1800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034dc4cebcfb3d80b241491307a4d4048d1ea9d216d0aa42c79706f21caf1a9448811874bfc0ec151d57c47a9423740786c520545512fcbd19b1b8971e4fe43e69ea196ce059cc6b4930de85717a22559a9de51ccb0827706b5c395bda3d1e35ee8c1f32a0344918cd847eaf1f69f2e5f5b899d425832ace74d3931c0db9b80d0229d132de73304a29ba1798b6f0fef80a42ece9875b2d64baf3d96e4339552be003088dc053a05bfd9f3eb380bc5d89b70a2667b5f841c27996bb036d48a0b787060b0adce2d984d0e7915d6cd3e9d3b4459029abe618abfe325a8102763cb9029b7c1ae6dc047c3c91488db32d81ea5fb26af415493e1ac96fd050f70ca6cfc7b38103212e1d5088b09c7c9a47338781a737da576ba5784126908e3860c42d1f7d52a90204d40534f1191c58f6c2e553d3a1ccd5e1caf33084db1fbddeb8d967f2204b560310dd2e6df6c1aefa8c5c8cf38380438b17bb2f0580881cc6cb584dbb097338450327526811e6fd0bf6ceea5f09256bc1effd53da8eaffd072a1850ba8ce2fedeec0225aa5061df874d16f589ff31534892d1eb4484820b9f500e6ca89c5338e03814fdea9f8167d30ac5f21cb5c61f2422bf10313fecc8719eaafb81c221c7e1a2c9c99ea8e3bae44370dc6411e32ff0946879357b6bbc5b8c8d87b81197990e1c8cc7f3cbb22056e2ddec2ba6aebed61d9e9fbca27be6b7b8a34c07fd751299bb64f3e9a4a9f503b096cd8c323cf3b2150af1400d2225f9724c55cdcabb8f4c46eb17814795b070916567f94e1dc5e42f6fc0c0e2075b4ea248f144d8e3f625ee95e45334f01e9365a8949529cc670bae6703c94a6eef3ea5dfa9a950de190d970acfab90726a2b3510436e4c1ac4a701e9ddeea5804db00d481a71ed0ad284baca1f533f63550ca88fd9818500258f62f0b7377022e1965c04aaadd7ecc46489e9e369e6b07604bb14525967297835b944b7cd1c1eb7726ec4f14c6501a1472aca4972a970b65cf80d70b608d3930940152ca233d2453413cd9207c480ab5ee848cdb299354fecaeb16e548c1597727e34224b2a73b4c5e63f714e64b4a6d053731d9574bb1bc2b24d8e12d9a385a4c7358e3cc0230dbcf133aae5c578c40335d4e4ea25a5ab33365edb8702ae7516081b3ebdfc260c7bc29695a5be0cc05fcb3dc749cc2b3bcb5d07ad9d49eeec852cd52c029a513b65730d20f63eef18e0b9a7838512c15955b40a29f20e57c5375846abf15e5b0b78060de5ee03347301b0a6cabbfda63120ec0ec9c76ec11a9ea9cc653230ce9abb35d93ce3714bef5b0fd5595e17a9a7a1e3f7445014070555a930bdcf298810714db6f7897f4dc089061208f8fd1f86de0fa1e0cb9845e8dddb2e79e42f9aa4ca0bfe217758d97b7f026c648cb4675f029b0e7286b7a0bb873dff0439bb4e3a9fd28162ab6d2aee43eb08df39a6a4b38feac42c8ddbb7dad5efe12273b1bb88ecf03cec56319b3430da26d0d83e71dbd61666e9b90e22684800ef865d4285f570d5db216eb5c7fe9ccdb52e6ea2d179ce086da7fb772a15423b04fc6df56385654b6f7b26d3dc21c4c88efe5ad581ec6cf9021d90114235eaed8c9888aa5272ada85efed934d01775d4605d2d51f6040d4ccc608e545758b285cc68c106d2477c7b68d875408150d746c5dc7366b2b206ef8b81be992531a662179b916af6f58140fc6bfc5d5d14e6691b047944a2da3f3ca6b11d1a53cce315dd6a33d7ecea2a8d6eae2d101a252dcd140f64e6ef3df693ceae9c7adfb13af5eb7b9945e91b1273f4ba9dfd5721a6334af4b31fa4729c839c42bd5ced5eaa8c708d8d0d659839e184fca0dd8f4281ae598d8f8c1dd9da2f9ab9043a71bfb11c3d97f87828113129a6d43507d25fba8cf2ce354914655aca9165a18d574aee1e3872f6b604dbf89940fbde84152268cf150b8c95913b94b4f979f85b0aac8ec2294d6579dfcedd429171191cf189a27d37de48bb35f3f4fb395d90dbe75ab6be3e652967d5c60a0c125248a29e7cbd18efbcdf8a874a144501054cdf3bfd71bb16620eba7e56bc20e25e0884f5aa7fbc612e4b570f17ad24c4f0e16bea1ec7502acba19c7db9b548588ae4a0e67d8a76290c37c719d1d4b97c547d091160c0ab23f3a95db9dfe8dfcca5486b9b574f0a701b368b1cb8e3becf519187cc84014f67d8f25326082d8c0ceca6e48d18d87d685e0d4e4ddbf86a0fbffe1b1c965bb7f82cc49bc37c41fcfc945e312d548a624aa01e5558fd7817e7787af5e7105134c249010000000000000000a379fe04000000003cd42dfdbcbb84317bccda3a0111ed98eb96f3b8b3357af6bb4cd199f2390830d907a2ab4b969dc2c97e6514ebc59e7b9e8168731f397885a24e347b8c026ceab1c4dbfefbe0b9570c44485f147b74c7d4f5146807ef4a2072940af0cccac7210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087d53e2fb7575922c0dddb73d96b5ac6f8a3744700f6ca2fba2f037a42fd8a8de8628ff25d25c9a6c4ba6fd005c6444dd08b03f45f271d3de14fc924d9660437ebdfd742a972b7fee14ca5cc20b938a4ccebb5b65d30599e95e045553a369077a89fe1c9922af781ee79319e2669525fd10831fa9741cf2c78d22c36b05d28f3020789ed52d26b70218b1c1fd233d095f2e96544dd7774529a169a8327e9d8bc6d03124549075ac9118192901ad76a86eda668329cb31036bb751aa85fc266724cf30b1da73f18597cd96ea3734b7be0a47bb784d2f6ccd5912864c7bee025f04548f42962c51f064a8cfbf3eef4a94c1ea0b410132da71ab0eaf4632fb6e2932202790202642238103af65349232011ef1bb8ca7d615c25308351d7ff17c6a56139b9ee0200168992f6cf4a333c357a80662b9d1e92f7005248bd33f7110e435261b3dd76030f933b6120171d058fe73f02063afec502a2246326e3a5b96d2053d9d3c1aebe0229459a6c87f2f7a515f32f24c08f067eb53acb82299e75e97061246dc5931f490227b77faa8cb5991e399ca4983b77395ad377af1c535d58a91c72bfb2caa1cf24e81dd5afaecdd727300b9cdf102678feeb72fb22826fe74c2ba5738272a5bcf6da3b36d51f720fea702e3f787618b67ce3fd57ea3308c1b3a8980648acc3b8c9f4961e26dc53e2027c2ddb7260a832b306ce5547a798135df660b3fdcd4774d96b97c435af2005cb7b57632f01c05e6e5c83a89192baba5e87210d819efe5e5d9a6d1f2f86818b3c861ea8df8fe668ba938076df09767bcc02f727382f59131b0d28cc76ef9f1b2ec928820a70bba08d6abad05c17bb02a1cac4e53ca8397297f259e97c0b563dd0d74329db4b46a112130592f71cb53e3982a4afd6ab6a5f22d06a044d7297ab58f05d510ac446c7d68838ac71b2239b9dd8a1221801b5c6e09382c2d56e2ba6688f9c51eeb9c025a10ddd37ba4b75a96b668d73f982c1a772c287778cec1796bfd5f7935331a3b902c7d25ef683441e9699c2fe6ecf4f4b8053c3eec344fe92de3d0a17ffda2b5d4138c08e85f04d50859cb111efdd0cf7345c078f1acc169ad66b8150ff7264ac54ec6150ade992dadb7bdf5cde037edecbef952eb6da264d15a7e035781207e86f296b803dc124a8121812b8dc8cd5c44503d3d451ea241657a943d42726e42cf656d9d3d4565b2f714393128c000da662d0e3f9d172733a3560a00a4f5aa513384c047407c844a9319dc0f6f69de3d0b37222e0e36b754b5fd7b3bc71c4fad8c0895a445910bddde0a949d4769797b24b1b06862d8eaaaf1b7339f59f3617dec9f5dba8efe9a87ce883421a731e2b56500a762243557928087f4df0f9ffc49b964b5a8e040327ebe78074fd7d95fa5f5e03f2bc16681b0704ad7c019e1898a97d24d1d548cafae3fb28c6a4880001a73e7a07e1be2787b74226f96842110694c4973aba8c3052a160b674904655f646dce230e1a9a0fd6700a5e88f191aaa406f7f0bd8989fa984ac1e4a6ba7101405270e84eee07a9a034aa5a59d71ac8b406af478e9da4eed9b6913cf9264a4fae29afa221611118209dee641622ebfdbd6c68575cdbe560762a4a7fd96db910a25a9dc9c063c400eed5aa9283028f398ed7d09a0ed9e51350abc1a535ff598b0a8356cff87d0a738c821cbf46a2ca8d81421a01e1bcc97a3cba52b118391c59adb4298d60bb48bf06eb1c1e988ca679feeaecd0e74ee9670a41e89449994c7ea45a427b3b1735d641ecc22ff6268759f488ad97bbfd258ab3d36bf7b7fab3448b71b31bd4dcb39892b27462652c9dcfb3e4f2ebec00cfd3072706079f07e60eed857d1c2e4f11fda62244133a171139f15605853d3f5e269c9a496b667ce750fe48c48bc25eca9845a4329d7b1e914a897ca39336bd715dc9ecf714e0947ab0e4adbf9ec09e68ade53d668f6ce5fc6ce3ba54c8e6be6949551c31bb3f9ab7b0e2d9599ce772d2549f891a1ffa4696c1eceee420cea36ea58e9c5cd3462bc9566f6c4a62c5591e698c0fa2749e6c61cfdfe5072c7062b1a16798c454f2b132bbc464becdc5910a0f5f12f999aca68329912611851758d470a7614fd6a050f5053b3458d44f197458e3eb5e98620f8d94b9cf593560b921a3bdb3ce5e2640e19e42224de0ec2d7c7820804170c63c470df57e6e8e74f7775c4019131197c5fcff140ae1ca53de98522c6efe089a2b8847b72e2e3d7d3022cd26bb0c0d3b8e05ab55e89d12d75a1780974daae8a58fda3c38a68d623bd0e08fa02221dd66dbe9014adc93798b0bdce4e1420b70197e5317a70b2294c6c4a3c934b88fdd1037a0147e976f88ff2bb158553fa74fbcb6c2e3d582d15d5ab5720652a9695df97069b697eb9ce63fa49a7d232736918cfb6a9073ca8c104", "ac6352", 0, 990198618, "51c43fec7b1b86df20aa709eefbe288b262356d08665e7243c5525235e4a30c3"], - ["b068d6c904eb4388577d82bd380448bba2d15e912b1bb098487a56eaa4bc49a71cbd5c21780300000003ab6352471a76344d4e192cdc549309ef38aeec83d7395897fb8d1546f0eada72fa40abb6854e0c0000000005ac635100acffffffff53202ef478d919fc114adac3614099882689b055f346c61ef84ad8e4bc1442de000000000963636a53ac516aac51ee96579ccefe3b10dd3e687bb153de7557000681b01e93575c397fb052d26da6dbc7f79f03000000086500abac535265004495c76f0120a47c010000000009535100510065ac53633904d6f1", "5100006500510052", 1, 615824480, "6c893f0465c9f2e782494bbaea7cdeaf83ed6a40faf590e0e0285448b3453146"], - ["25c769d804e5b5fb2ab4352bb144582bcc1e158027e41369eda9cedbb59f7d979dab70b760000000000851ab52650000ab53ffffffffbd7fd3d989c5a9c9b69e1d7a968e41621f8ec374fdae031fe32c937589e780d600000000035163ac2bee71c8f8e363109b8462fbbb354ae753fa8ba9a138ea174caee5aa2cbab4b1d1b5020202000000086500536a536a63abffffffffe76b4dc755115a40ecc465714a3b848ca932f31d815fbb5a1ceb6f61591458f400000000046a6a6a53dde536cd01f8c641050000000003526351416c1c50", "65", 2, 605436556, "17c248b5e5d846d5ef1a34a0d877334e0d2c5b17ffcd214f22e6a2c1bf4a489b"] + ["raw_transaction, script, input_index, hashType, branchId, signature_hash (result)"], + ["dca3384204639716f2dd16258075981e85fcdcb404216090dfd490dff1803fb5e005f2274b010000000965515163ac526351536ecf8738fd6d32dfb19ca38c1493d00c4e85d3fa70828c3ff922f41e93cc6a61145267f9010000000200513149f7fa803e6e2d31eac862c2916a2650e3762d34bdd1480a00d0d54f69423689df54b50100000000ffffffffda59507626bee042ecd1b53bc1f94c8302b861d397c30bd3e50c6ded6ef077a30000000000ffffffff036a6334000000000008ac53536aac65656370e85105000000000100ab294b010000000007635352005353530000000000", "ac525265636a63", 0, 817108351, 1537743641, "dd12055e149394bda8b82386ac21cb1f786d5b6e9ee17b81521a3243718cbc1e"], + ["1859bb70037d5be6d9066d34ecd372791bb2eb3a828d0fa2c6bc538816d38824b55dae4c1f01000000056a0052516aff955429ca8ff9394bbd0e758ac6848c245b083a94de4641ae6e9c466c28d27cd8888a5002000000076aacacacac636a048924740ccc5932636f99ea4a9261fb747d1f41416f150aa6cf685810403ea76db2addf01000000050063656a52dc8ae957015e464f010000000003ac655300000000030000000000000000a869180300000000bc75ed964aa683b01738bdc42a63feaa96a292e46835b04bd6b3321cdc205947f6f65309097dc64c893d3314a94c87ef7df29063b36a3d7d1b5ef9252dfac8d3c0e4b89ca6baba25e598efcfbe5e09d5634b1324f220cdd7afcd1ab5b2e92da4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d7a0addca891a28c66cd327babe2320a8f438a4a96df47bbdef18b5b30aca4b8e11ec38473656b2c3f3ce1cd485be138bb2c4a2b363d9db43736811e5b4637278394d352981daf0b9320fe4834429167ec04ca8d1cbd3311ad387c94d7f9a35b1d59fa4199ab4a80c8019b4d4a412f24bdac0890863769b90a53333d86eaed9032e12c3ea4984b9a4de6d3aff2d429d386f14f73b564a3b90d3e53c4d6a0f15e3032262b1bd4e538b2dcf14a7d6b67e4126d52801fdc6cca92b49e056daf29eaacd0a02054ecc38c4013789424bcab28eb1e6a5f112ef48bd41ecfd0edc03dec94cd590c12f83acb663f9ac055f482041a37a4690bcca5d5c68d73abc1d1074aa4c7d020ddb814cee7a98e8a46304d64e2cd30cede08a30f143ecd2acdb9c19a101092f031dec114269139b85b1964773862608ea5e35d5e43b5d4622a65c03318cfc59060212212a236b93ef202c90417764a4315782b3ea6d5aad89eda1ead1895a572c16022fd660a2a04d2af4fe8570f916092389e3b4c5e73805a5b1a4fdb8a607d5ae68031d99e96bdd239655c6e3b7c5f30aeb2d5447733455a631c0d9ba1ce358d69dff77b958f933503c08af4f4baf88fb9ab16233ae533f24d331505c2e5c40c603615fcabcacbdca306cbd59c7f11d68b3e63b6a3c8dc091fd66625fdc55a80cb8a5a5d0998bfe5fae29d088af5e340e92d41744c73aeda4eade78c2caae8297c06f192ce4a5ee924d202e2b454b6e17cf56108c18da0f32ce141989b95eee9d63e1b67078f8a541cca6ff23c5ebae626cde0bc6a19a55ddff0f291aef0ec1cc34c1b45af11d29fbbe1f2be43c5c40f3bfd7eabee751287dcfa92d6af552d61074b901a758c3ec4fc291dc9dd64d78c12f1c9e406cae10c1dee2bb21c891ce9ec845aa1747d9d28b669fe44360028139cea1e77c159d99cfd21e68f82f41d53c98de4f9b9acfde1ab370e5fe4255a300545b506305b71269550799485968c7f91bf6164262679bda67ed2adaadd8ac7377d5f6a190f449e30bb28431bb5e9839560736821eab25d24d9127e95bb691afed4dd74aa1b07a90b41cb1751a6a3a1da402cd270e6d4621567a8595c58d597e14d0e4b86919457f028dc50f566ff7ed9b7a87abc8bb2a08e2a1332d8f6a055060c6bba6d7ffc334a6ad59860af54fddc1f6df7dabdaf63498d524d0762d90864bdc819bf90926d82fdd120a558cb51b1ba2ecd5dc273efc98cddc362a60de49e036a1ddea152e816433e551f45a13a517139d1eda2b524b27726049ec633975ab99f67b3b3282a8ce4d916691fe485acfa79ff8705bdd514f42a9f53002bd9ce462a274eba868a6ceda928a5dcb59753af9bb12c7fbcab61d0c08b67d320b238985b339af637d310f657d9094302b2f3f784e336549ecb764ddfafa8a5ca03bd3af3016f82aae32450830a4fa63c22c0ef7935b928f5aadec9e5c73b81adc43ab53568ee514b8eae8c443155f520218b621f46ca367a681e36f6fc7ea9ca89b83ad51be628c0c57adb1b76b8ede667776ad409c12d2802d04f26b3bdd0b175eed84f5fead7262a314907e0c9fd0522369004f79ce0f4afab40e5a8717fd09e849f519515845d8fffd219a2a191939b7cd891ca6efd3c7ebbac6c9aadfbc026174ce241d9a428f5bfd92533b1fe5d95d876ea940210bd6f81e563b1f9b3d602674024cc40ff459bb1c178a4c098481b4cf130e1946604bd875f1c976bdaf2d50c6a45b0d89e62753fead3ec2741fb2d8ee9f64d8a36a0d7a0bef4ad3e2e404e59208211a85cd48b2cbe6e08c7387ace7ccb9ac0926dc4fd4b1d4217f84977cbcbe9151e781afc8ad6e6693a26442a97f598815ae23ddbc7a734e0d94b8eaccfa49d7e5fd79df353451c51d4cf88041e2c3af543535ccd807a72f03e741646a06143e5353edbf74838279eec7295b9c2fe2789118d5a5c64569e67ea8f4e65e62fb15e2cbf5ff58424a7a518f062e6cd0886ee2a4cc62c18f28a4cec954fe9051764fadd766499802114f2e94047b912b181acb2ac433e7dad86867f57f42a203ecc1fc43f8d616cffeb8ef839e69093a458aa2786c6db389b965217984633b5cb3346df7fd0834351a02cfa682d9688713f4ecf9c93a4f6467d10771af4736af7e6aeee5875fccffad3eeeb5d31062f1b286feff7bc2e2afa384fb7d28fd2858466a56764e646b16c212e1737888b0dfe626b63ed7fa300888787ef766d9b2ee483e53139e3b4b93c0aaaca53a6f9d07aa88ecea30fa5bc27b48d3feceb2d3c32718d4fe64602f04000000000000000000000000778010feed260d8f1494cacd6db5eacd1ff3c452d2b016f69a20d074793ec0152b41c52b97045db5c6d587d008419824d25f7d1989a1931cc79bbb38fb02625741bd9536c851ad55a1f82e0c893fe145bb56f9b3f9515703fba2284e4471d5610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068a17eb955b828e084430e226a8a39dcacad98690ef845ddec93b69183341a8b0a4256d3d88cd8d9327ba7f250b277bf36ece52c624cec56d4461a9a6968570d18a4c66fee3a0888aeadf36255e6c4d65c5775b4641a5568ec68006d77d503463cf202d48f67b5b8cb0692e3f42118efe080ba3f80d8f3cb1bb2722326f1d594022cff8ece8c377a455ffc05e9bbcaefc113bc2dc7a6f4d3c15ac3b2656ba596bc0300d8101954b7a7b4aacf3e9da13dffebebe54d60b6164cd401546571c662abb00a065fdc11af05d29ab71d3832f359f47becf46a4830d4ae9120b65502216541f1096e7ffc1a65c254995879aa5fd37e6860aa3a611df9992f6e74b74523d903dc02026d21cbf63c7318cad17ad40bcb90f60d34125bd45ad8d6c8462419cf03f8a003298d9ec50b7a2d8f456e72f7fbf5a350693b98fdc7fae7c690e1a7e687ecc339020d8964bd8526bed550c423a01c15b111e98c426e3be7ed04e5295662c778b6f302145b819cba89246d4b84e267d7d5a9e178a41075d37ec963595b93cfabde0228031a9bfb988fd70c4b50a0da69e4088db24780b4702a4dcbc298e454915b1ad2330460b9ad744b12b0abd7eb180aca3d6bd58409dc50c5898d27b982a9cc2b5ce228065f101c08b9a8da1b2579d0ec274f886c6a1144a50b300d5178cf67081c9589ab2c11a63028898c1760fb5196dd78d6538142efb3e8c180e8d0443e2b679e349677832b36a7688f23ddd5ccf0b330294bf76119207126d1b2db4f1ae4965a05d6cd9c3bf93ee2c5cfc12030849639b5ea3073f38dccdc1814393814852e7abb52d3d364f441a24aee1c31f43c36282c0a5de397666125bd68b727b46e7e82c898e00d23f45c0fa019ab2e3d0e96e7b975db6f5df602677c91a0b52bf52ff76dc1bdfd4c77c3e29bb273a6ac75cb4f35c3d5861cc2a155cd7f6cdaf4a30d2c959fce83d06dfa03006e3997c9f5b5758aa7165176eee96babfa96db207e84d277b66976204fad33141e646fb5d0e41ff165eee9cd663bdb93d025480ef2c483638fff8665a79873112187af8a653bc86e379f736d4f67a2b2371dc75bfb48d52a4bff0868265d8c46e0ed6a507f56c3506e769a7f3f9c019d0216c4e1773c749a3be84478f0041876a9829704d89c92afd96929abe0ec67cb882fd55209a4ef8673f9a077f9468f33d79ae33a99eb1151ea52a48711fc1735654fd8b25f74e6507b2feda57722ac17e574e4d4c286da7374acdca6cef5f79afb6164e8f4aee18db5c11a0d783df9304c13448c4abdeb5e54127372e9b289ed8ea3625f55b3afcf0f358dcc76943426dfd937733a0480cd62f88a0dcaca939ebf53bef7416b0048d6c292f5858b5a71ffa915802584c0595e8a29097759c77fdbeb6118e59f196be19d7e1ff04e42ef38d0b237ded5884be3ca3b91d980e0b9fa623b9b24289544b1d8ef1e9cd2a530b1621c2763d48638838728aea7bedb5f960051180355ab6118cefee312c130b4553870d81539054e54921c890835c7713c833ccb7a583067b5d135acc93e0843f76f72f20dc27b52efcc53b594b82a1c67c616e649982cd89b777efc38c07805f2afe8ecc09929e9087e913f6a7b27ada5c9b492e7ac7ade46d4d14c520f7a4962908a8991884cde3665e20ef9dab75d36804eb03bc3167810cc733305d1d6e758a43a99e186a7588a1b2110508e8122151beb2dc68edf46699d52e8d070133085c3214b4900e2eb84701aa19a4daaa288435bfcaedbc973a998a24fc15cb64e30c08e4ee96f96bad61d938ca2427ca27d7941821b959707b1212edc2db3d59432715751916eb8c12c511470d971b1e8d15817aa9852dc3b1a8b13cf35902955bf87b2152233cf9cf9ca75e3ff1da45dbbafb63ebd4deede79a07b069046072b914414ae4231bf6821b7a7913e4ca628ebdc8d1e687a4e6b04678293bddf426df027be35e4d027b4ac19cb9b637b0145c01af91850421f774decb5755763304cf9bc3f0b0827d9dcd11d864e350de39cfae008139451ad8619a9c2618483db77e3efe54d943e98655ce884a26c1295edd5b85f2b5101f4fd6740694f4ab151265bf19821c1dbabb4d307c38a6b487cc854c3e8b900375df4bff6cbca14e15b2ada6c4b1b48959d31d43d366a92d76300a4263c9fae1f32b613a26be1a88032b12addfbfe2431a1c1812171c4674255c8f84b3860b8c661a36ce8babb3d3f32b7c2a320917161c3267007602858b8fbeae1fd4328bf5ee049c6981dbe51f3a929a16e7186a3cd7365696682b90500000000000000000000000052ef3c03a00e45cc39473d105065421c659c27e4540817472a2dc9aa2afc75db67061a25cef45d92c65b2e786829f94cc36443c7ab52cd3bafd8ab4ae41f20b991769adb81e3f225e1127bc7ac625b92a27217efb98ef0ea7060e0d443e7e623000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a602c28fa48d410fa29a56cf653dd3589148cad41ec852ff76cf3c81600756742b486bc8fef08472bfb65cb9dd56f2d66b779672a27856cf1422312fd26f0e506ff5379317e22cf56946059207713c8b1b3768d80aa856b9760d43446b9571d3a70ba39ab4d32bfda4a2ee917aa36a02f1293c9abc658bd6bea2175cfbc6f9e03301ec6b9a49ea8d9861e72d4c5f285feef8458272a5952c63c80fed320cc39e4022f61cda6d211bf60377e9885499ac3304f8e9633209686fbe2bb145836e16f610a02e37171baeaa1962d2ce89e6c29b7d52e7eed9b4a1be7c14c790204ee895dd625e72e16d729f150b86fcbf91360c33f6f49ffbd530390952e795f510da1c68102061a5e7b3be7d6be960d8844116dd6fde3eb2b887ac9b1daec5ed2784edcf77f020fd6a88e3df9ac217cc612c7a1217303534f7f98e7f793727ebb22c6087aa8b1020739f727be16bbdb5f6fffafd94313d26e3a1596689f6e13817d7c0d142af425020180830ddb9ff6e766c964ea8296deb77ee95608fcabac4c2483f33fd2eff2e70313668414d3d133cc0fdeff8db3dfd088e0a689e1fe3e7f2d689660c0ebf9410d0dcbc68a16fea2db3cc91b79d9a5f79eae450d270016c3e830acedbb0415b4912c60e9ea125022221a6f76b2b8de281ce9f1d4579b8019dd8db06591a65818a3510d481806a6cf522d7e7b07906fd9e0150752bf99fed94201a001f662b26bb1d5c5e28c55bc30a5aa6e55be0d1341af6ee825424b31cc115ada73fd863dda1b5c9a9e8b568be846aff77cd39f59858528c67c9f0d071d7d1133905141c4e4ff80c3b8d2dacd7c324e78ea38d3d55db070cf8facfec23ec8b26e7fe963f08898bc181c6c4e8497770ad31dab96cb04f57db458c28c20a40fc134a279c8019db2fe27aa7678571557a52166ff2dd910c8edf0398f80bb0e7651f057ef3c378f672e6cf6c3d9924f7a72d4e052c0beebc27241f4271d41734cca074a46d53ef5f548ceff7d611870ecb14be93382969b8b9c135adb9a9e03a0b09141dff270ea6f9bc66f409c18ecc764f27ef35988fbcfe876506b75d66238e4737ea538008cdce2420ae2f9333749f73581f2c6385e9451bcb8edb7c369e0d2e7304b279e03bf4d6304bdf4e3c2cb4cf1e26c95a66c7e41091c13c329cf782af29320fd650a74cc1bbf583b4ab47c6bff64fa635b51d5ca8907425321c046a4a62336ff158ace90b965c21889f2458face0c8663b34c2b4c00c8f41e0a679c918052a05d39f84fd9b6de79e72019c6a6ce82961da6f5693bea88506800f7776124fae37cf0dfc354695db07164a23b7e6d4e69fcac9923dc248edf8a535a8a92401b49d9bd8eeb81f2df73abc7ef016e5605de815894cb7910963c5292c865e53d6730fc8f45f63592c7238b73c79779f1715176b2018c01dab4184ba4fda4a98c7670208f6c327ef3bdb9a982b39da43493064ebe92d4140c84b38dbdcf8d67072b395cc0b3dd63a8dde74275a50023e41240ab7219997912e5761e6ec796c6b3376c2f6a6e74bc46e04b06c136ce3c8e32396568405778e8fbc2aace1dc22a5dc393fdb2b7e58cdf392fe32225bbcef6ab0559ea8c038b86abd6903571a61d6ea871b5845fd2cc7fd9f809930add4ef802c4c83afafae7a11d607d68227dcc82d94c847c0d506062cad0bde6051034ff87637f450ac413a4a5ff3ec7b1c6c872a531828e35e302621923d8ecad3a15d23a3fed0cec1976cf0757737a6a7c465ba7a6e95f88f104a7981e1b69272011e6c92029b6fad850e7149676c20616f8cde9a4b59e927a23a59d600e4b9c998146472bcc275e10b8165e59f616255709a68471967b5673a994ff463f85213615100523353e85bf5e29166eac27004c8d92ed1142b44561d34d8008fa03ff9eeec0b44f3f304dc6f6f5c971df83b3e4e91760f1f1b44a60b10d02bb6dcfb3946eec602165af7162ec23f9c36b0bf3a0f22abf92ae8214798845aeef5e70c1945381ef30a5c191ec1cbc85ac4bb291709c97ece83456dafb958b050f65220accc7b08707d39c75ef04e936da5f2fbd491ec47fd30da4f825c3f6c6ee213b6034e1b90657929422fadd0b5fd8e97dc5551baa00ee00f5e1c6f3eb20bae18b10fcd582b6777be509dcac66ea133cb188edc4032b2012d3e634c7dcdc495439635dc9814140fd457e43a5634d1d0a028287a88e8fb8621964659670e996faa12d0a1425d4ac60cc2e851e3bda13849679b2eab73c8b0ef9b50f9ee30f2d2e23c8e16d87e51785809adb65b424dd278034c3eafe611340740382dff8350d0cc3bd1e979954c3701f0ca5e21bf3ca1ab7202a96a060033ec0e2f9a85adb3d2a1f17ad32bf31c83c4f96580fd1d085215c60333b6f26c757d5f2ac7172a98c30037d2aa85b98bc4c2e025c001", "53ac52", 1, -1333470626, 1537743641, "e35d4a3244951fae20589f51ef73d77f119cf8e4d9122606fa39db0692b9b96f"], + ["90c53b53041cb3fabbc7c88f2a2aa38d473444b37e6027e4b9e63596663603f146f0207baa0100000002006a275fb1455284162a4c361614b3038f649039a8b97dd49b9988f13c8aeb5b43f533d2a6ac000000000963526a5151656a6a52ffffffff4dee1ad730042440d831e0ad15f0b647d367ef80dc6e9817effc1b9476952eea020000000552005100ac1f0b79a3188123120eae4c050169cccd3414a766ef605ca3af2915a52c333e65acbe03e40100000003525363a065ee71027080bf0100000000076552526a0052ac161ddd03000000000951ac650063636353acc91f52e30100000000000000000aee520500000000a8d3ca3fbd4f54e5843caaee354c8d4f994897f65c1392c1c4b62eb2cbec411cd3fdd3bb0ac9fa526579e6b231a96ec81ce8a8779af54ef7fe3af07a52174acdc653103c592c464a337d53874113dcdb5c671297a4b15b801e6bac7c34bab12500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c103f48c4155a46c706b5f8a4c8a91c38734cdcc87d1fab9507f782569d6d0cba302c21bbcc27c28095614cdad8390953404daab750fbf6cc95c4cd6f64e0a26887ebfedd35e125e5eb8ecbd95037d285a4e130b0f17d42946dff13d4afe229109669b490415f9a31d665bbb13288069f0056625ba4ec2fcb57b56cf2d5a35550205445ee821990625e33935f930fa4c2d697b2baac299c9ce5472030151e9b561020cf9b690e544981d8836c3c83f8be354bcc5c82052cbfb7c65272bf1b929158c0b00140b2200f63827050fc5dad9866847522372e75c8be94716bf8596659ded8a576f47a1917e5dbd6564d00a9d672d6e1e6fb8ca8dc3db6f3e186f32b6bc94a8032398a954b10d6d715cbf44db9c7ddba0922b7e9e5cc1c017a62e1115bd0548ec0206fc9d04260d90e9841878a77fcb7328b7a754e7ef7ffd55409baa1b8e55c026021a2e1f97a8ca871c90667007bd6e71a0757fe759aa7b812e9bea7cfc9a49571a022c28d46f346aade2d9c98526283d98a90708f48060f7d4888716f6695e2801d6030c2557ad6e198e1762806fb8f211079ff89f1d468f0eab7f6ba2f1f2be9e82ef14125d2c5edc5434a6eed6c2789ed1a9573819b67c99f936058facadb9c2f46550710b627d19e7a5df91ec3dfd4e113c7d1399f73e10027721531f7283af25d54c11a48b55093a81a88358b4a12fe5893f3d11b36513483cfa9a24c0b20f4bb725a0e53c3d9a20ea4d387934b87501bf171019a252c84d66a62e43511ed96c33768a979de269a6d911f34c90489d2bf35035b15ac0b94a40fc84eb9514251230cb38b4043c2672e357d9d760fe6a761d83d41bec15012391d2c2b7623bb35a9e688a4d018348a21e04f81117123326801799a482685b0f9ea46b4881f8f7af3705d8c0be78a75ae09e2151185e18da8c12f34e7379722dbe51727864f576dcad041569c375fb976b514be32a5fa5aeb4da2f674742101622594ec2a797d8bd443dd062d676624df606d6d5a546059c85aa352658185b8a6eaef55a3d7e5a852af4701fc30404bfe2158fc9eb1117d92b4969c7a470351f80f1ca98f0f97fdc286e2812236e4a6d6b43c78054ba1b0fa8c60683bed51cb0cba8646b583b88ea041e2f6046460da9bb1d1708299dffca56ec3a032fce45b81e9450669fadad8ac04899afe9bf47f21b17f2edfae000e13f1d0aba317a4e9aeefbc62afd0a1adee76fea6a5336eee2925f3eba004b3dc6aa81896bde60616029343b73abcd227313d0e786a9d75b644591b1db2a3965b78742bcc6f90db45a3b8809350a4432383edd9aaa56075d35134b89486bbc753762d242cc97905d9af478fe2545811ec97f790a63cf60fb1cabd400d5c4f66b3a29d30678920e047637c898f40d00de61c3698f258cf6a8eb6ee8609554c6a3bd4ab15bd6d6a276bbe10e86f8c505748e5cdedce3eb10c8ee8f5aa58f1ba49f5451d232cf750c257ba9c1c6c585dcafc7e4adf0d0aee6ebe758bbd0274e5df308671558475033b0e14a0fe416aff196f882856a25d7b447d2a3cfe22846906b121e67152a4810918092a709f39bcacb579f84e85bcb79cc424fbc4f616ec9141a72945d589593b89ecf7dc970f5de83003ed7ab58a79e4b36a699e177ab49abb2d41126f7f66b20e2812b3264a2e99db15fff220d49d4404af007abfc9c9a5abc6040c83f50fef292354da0072ab427582b3ad0e2ae6374ffb775fae55e0c1832a67c5b7a9d467c823633a2207434e16dc03ac386fb7eb2dee11c5a65d272b151422f91ef580e963c185ad74793fa00a840ad9ec4a370bf7a63e5b8fb917296c8c782e820e081792105b256ef4793a93c8a3e104645c94966e337c31ce7b08f6a525b41604af1c7d88e959f5d7f703a1b1a24f52b539d4e3b4b5e6752e3b188de243154843d2d23f1496d056142754caa200647a700ef00fdf83abf2bc8589b8e653e3a4d4c51dd739cc46bf1448623b059f44b15faa7ead0da646cb0af67576c1461962910f2c6e2dba7415440b50a5a975e8f1da4e80b2978b6b26c286b37355173e23c16b007c8ce4f14b46eb8d9e6afd5c6738db553c46f28472968300735ae4771fc4f6e2cbe31920929a1cc99d1acdf6d3b88cc4fc75a765defa562de7e4315440575b101da3fde16601d122ca9061b1a18c96234e2b6cc8b51fc3b06b074cd45cb66d959c5fe4c3c137c579a564dd6a88c7e1b67973e9aac4a6706804cb905af84888a0e996ee57d47af3b938d044d506b62130725b6e4a5889ab1f9b330ac38e71c014361c1e321d9e40a4ba612ba3d1053244f1caf63b9ecc433a0c90b31fbe2abbbc0196f69fdd5dcdea4c7a3c9994f66151f2a21dc3f7ec50326e8f541fa6b5aeb8d62b929959ed745a3f77ea26bb671b941bb4640a6d7d6ec2b7d7a1e09", "5353516a", 2, 1546077898, 1537743641, "6af8ec836267323adc3df4ca66f58ecdaf5017e5f7f6477a9b17ac84a1f7693c"], + ["17072d580320cd8651c607848651fb05338e5e6ac88d6ce4011a9cc4872d1e3b1fe76accfd010000000165267bb2d6c475029eb01f1edbaa1d8aaac50bda5f8e97f90143b57b562e9df3ec3c53b4d503000000036351aca0dc343560abf9ef2d820d64c4a27179ad76287cf385106e7a4fdff56c64b52bb355e54203000000096300635100636a52519b786f8603c0dca80300000000026a6a0cffdd050000000004525163538dd5d30300000000046a515353c130466503e13dc2020000000000000000000000009a2db7a78b0ec4690c409871aeb90ed0050aacc5f472411b653ea9110e2dd14d91fbe85411ef33f96efe5a801a024c5a02c8bdedd95349ae08d83a87ec60c572770d449f5b374e28f3d755b3b163f941989c5d16c3babbd30510b9722b7b439300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270ea6b2430630ca87bed9d38adc84c8275862e8f5e82da412fafe230e417b39fda0c00fb933765e19db4b8bc3b50c7daa28dba82f8ea3f3717bc5e473267cadc1f36c77cc75ce91c3950f617294a1d6d8bf935baeeaf2051334422faf1535cb771402cdbd07233dfcb389279e5abee20351124dd25f1e3b05b8ae1e9994a90c032af6bfe2e6cb991d29fb63c450aac6fd2300574206314fa6f2bebda37dda9e57020c48f245ba03cfdec5934eae31c5dedc41b63454cf0218d0773ed283730311a50a08247fb9c2f6e98b85c7f47759726fb216f1eb242c087fb505208b0948ead9026056bb54d16171f57f59c6982936f27de3782bc08104a0121e21f8e16cb84246031bc4c2ed68b7074f1b40d6839bf3a11c40346c67739bb0e27aaac132c5f8b0f1030881919956284a0aac482b9ed863d9b39169fef9774805cdea784248f5b0d0a20211a6a5177ef3878db7f6493d8a2ecf02ee35d290c971b8a31fa983013335fa65022e13e863735249cd5bb8edb3f2e9ecff5f24fa415fa8f3f89080eb9cc5659a65031a6a6e742ca418fd28a8fa6025a4fd9da39746a616457a7c1bff0a2174aca5a098be83dadb23f28ed1bd7fb4fed755b9a285ccc4d3b002215ce1b4629c95ce1c1a823dfeb8c6057fa2f97a8ec895debd1b53884820ef9e28cac6bde7dafc2789d252bacf8818344c7d5dcd442bcad89bb7b8a756967bdfd1a3e24b9625a09641ee11e19e5ebf93356a95ae02504343420dbc5a83e6372171f520e199d06bee03b448a5165621d0e1feaea4300cc712f6090b30c27b20dafd2e846f166d0a003ba15c0fcdf00c16dfbcdc4ff918fbc95c1ff946fb9b437cfbf82340c54a3341da8117aeea9d88122916c32a3c16881a84fb56e38081bff09605b08cf11d74dbd3a047a5d99bab8cb10fdc3644c5e282d6e0f34b4b7020305e33939c9ed67d1b7ced6f7d8f736ac3ebf40cae4b294afc89b1f9caa20433007d180630103a6a7b5c51b817f195f4cc59c52db91bdb69051c88882ad0c030b80e91109767dcea9fcf564eb0d4bc6aaad7615b32e52b182ca9b94bbb58b9991ef51f648a71646e7dac6d85abe53d688cf15f2c83095cb122bdc112e581240a391aecf9ee96ecbd20ecfb19b6c4974234cb395408da490769cdf899933cebb4a153e1103a1b6afe2bbde8ab1a43cf23ca2ee688de3a1edaebca0ecf36fcdc522e27b05250d24c8e92efbaae9b2174393a8948e0526434288a73deb20a70501335f4b8a9394a2caf6cb1aa679190599c11eed98916b3cb426ce3d0a90815a54ac2dc202978659927401533c7ba652f5034bcebe58b96e5078bbe713c33ff8db8f73b3134646dbbf9529ab1f4f5c7361cf62ed31cce225e660febfda6da10fe70fa0dd1c158fd481414deb3a2725248ee89636b9d3f11058ccdee70f5eae75b43fde9191942bfa15d9de7fb591c23325f36c908ead1bd9592d2886ea633cea9afe9f0c20e2c97046bcf640e50aad9bbd2c7372f1f7614884db794ab9d61cf379e475efc5b5680c7d3005e918dc0d61ff322266a90ac2a07bfdbc1b1bd65c3f2d6ca71280b577e8e22784a63d3e8e5f3253dbe98f1271045c903ddb9c3b58b6ba7730c6c08b6139d2e796431a1dcbd97876ea91a1f05e025ba38c5a93b7c4b6f9f77d27b9ad405147ddb97e0ab8a4443cf9ce2099bd774a11432c379c23015a30fb6593b192f9a52ecf26ec6aa90cd7abfe906974714c55e933f1d7bbde81d7bb7d6e128fcc1984ca66d110e3b15bea9a09417fa0c63701e0a157e0376e1837a119181d114608c6cb0525745cf357c45c21787f7e6db3ae2f7beaff44c5c549bb0577e3d6c4c92844e6ad4507ff81d6e37e1c9aa3fa10355827595cc86454fe6caac5a3374651ece45c4be24f51ad952590d4fb1a12dfc4499cab8cce74e8406589ad53ace6d784a5d3239dd07cd5985176090a806bff60333da772bf7aa91c08911eb67b19124e0bfd7c294dee95b050868977edf5fb806c90f7115b8191d961b8bef387c9985eeb2d421c9b8acad2dc4c66161428c7327b41cf3407b6b9092585c0e04d8a79e61c6f73f75ab9e409c362ab206f76cccb1c89526a0872e16ff1f5ba1ab30cf71463bc40e827703ff87074612fa97436a119605d597d1e8c7d57e4ff671fffb78d2d814a27d905ee63e40678e2215834b04efa677cfbbf33c34b12cee71b84b1a6f25dd7d804a1498b9a3c6b686690074dac6265d2c83c4b36a043ef41fa71168c9e0c8a8469ebf6f4d76158fd24982ea2b9d9bbe3e0a9f6717040000000000000000000000000106392021d690fdc6cfb1e2240b4d68f7f76247d8b0f1f5f12fd758f1a7c8a964b72e7663795a88990d51c2284f805a7e94b9ffd00ac7ff8540c9820d082c09cc7f2682dafa817d5577613be7eb9be73abbc277fb3e49c9734af4cf288f31f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000524d3bfd7a0d5adf30223570a34a7b69af20f6a9694c108bd7ebb0033351245be3ab44fae8c332724789474196d83da0cfb700db2b7f023c96b65281b6abe0b7cabf8452d20a900935111ea95c482dfc80fc02989123db705002bee58e9d1d9f0168e531c8c28127d78cba2b52d8d6e015808724f912d164b6bb6deef293c6720308ef6f4ac93a13e0ed163d6e59cba84f5596faa99fbb9758993d59800bbda625032a4d688690dfe8aa62aa37f5c57ad6b038bc0c2c817ef0ecdd73788ebdf7a26d0b0326ffc51db8c7e10ffeceb1843e3ea58d667d4366223b308d29037836c64ff31e8629bcd877dfdbc82fd6db9233c7470bac6c29e2dbecb7c0156ee2da211b0e021c526c02c8bef517ea4c1f18935a7702fc7b2ad20f03ea7637162f370028f0b4030a4920c7173696a949119e897c2b3060df747540358ae6da97a3f72463710ec8030af5bab214c31c3ec71905c18aae1d5a0eb86546978519ff873921462d54d50e031d8d4dfec191ec9cd4643ce5f9c025048723dd3a4599ae86e59f46dd258a9dec02020f23d99938ab5c4cd70f134e01bcf538b17ea0be405b20e817e90f31609da89cc7dd3c95eb737bafeeec9146d6f78aa6201165957b23c3ba50e62f9dc3886d39232d07e5c0621d55b216a4cbd3f918fe5aecd6b82ed1963bb2c3a7c02a2634d42a88cfc98ac5c867386e6e559cba7fd89b58bfea945dd9679441c17954db96d81a2c83c84478a7b81499feacd066b761c7fc4d30735cb1347b1126455381cfdd08e48b09a1de33b220fd05433e4085bb001f9e2a21994193772223880b5fd2fcdfb125e84acba12ebff7ef28267773e579aa828e7d7be9a4e427ba6711bc5f4b4a7dc855566437577832fc7c240df897dc59a029d4ba15f21d57a71f2bc5b658d1d40ec7382852a6be1813b486a12589323b97e9da884b42f2d361dfd93c133f16bd7021d530796b86a273dfdf1d4da95c84208bb68702dd1ea1e741fd757cf543260e3aaf94f0a22be73492fe2f5a417f330d10cc09d2b403c73e893499c5a236e93f42169acfd0ac67fce29ea5a8327b4843ff1bc790a4d4959819751c2b0b13dc2cf0bcd82292365de3d776ead9b77edfadf324680d12d4bc3f539f64faa3dd9f5a18e7d4f1611ad3b1621f58923220b33684298811f7ca426383ed325afdf277a9a8a1764364ef174f53a08fc078bebfd321c2b9d81bc1e4cc4be628365804e2f8b3e09cbf344cd4b9407f6c5d442bb4242f0387f6cb99b76b2f1b64efe6c06e36bf4a66d22aa81d577421585b6f1bfa3990f027daf86dec17501332bbdd0e3b249202599263309b63d7e56dc5b2c505ad934994275a25fe6b0d5ccc770a53735b28de489b09270a5a1ec04098ce5b0afe13f0918c5897ce320d231e72ae7cbb405425a298bc0e07efe6c536429e1a4533fca0a4d3e0588f3577eea0d314679912a560b442edb36f6171f249c4491ed6235a293eaa0f536220fa2ada6ffbc95c84d5a5e1f79bf5b34bbeea8d630f84c2863c173813734e7a6778fea9a3bc3ccdce67eff88108fdfd4c8629921a79dfa6f763d9822c42d5bcaf927764e32769779c659965bdc6a5c3208bd753e05c6ebb494232e74cd4d09ab2ffe9dda1110477207bc96a9df9635b031ae11ddf2e51a4ed0092d4f425b83a966db2e966ce2daf23aedf14b6154a39e01b09200ec5ff6a3b4052e8eb8cda8947a63fab1278d2ee71073294d47e149e6199b6f641299dda690d179367b79b04cbae6683c8cbab1309d9045e57d7c0b4048a867cf5690b70d09c7672178a4de6e30efe5341c8a4c187fab9548510fb6e0600cf329e70b19b82ca966360bfe9599e0d1eb3b1cafb992f24fe6793c4de9c586755913cf3de4a66c66eed5f4d26696100218af709bb58c5fc7dd76759abc2a767b790f44ecf6be851e59395bb6f0f86e991ba831e676ca697dce487085e863e74175ffa00b36756a4b9f07e6f5970238a35d6022eab479267267d8806b30350488f767c2ad710f8b388704267f328b78ec7562acb23a7f010b76c03ec122246b2252458638001ca306194fbbdff0a17e5e49d0765e9d92f85e866a01dc4c5354328534865792d0ab289256c6da23024f9ab555fc3a8c542fc3a2dadd559835d23adffc9e775b65550a93928d9c05b653a8557f70b25196001c355c69c4e30ed93363deeb773e6be3f694dcc4605e8abcd6e869c0b9bd6b64d5a243af7f5014574dc9bb9c2e5f2cce19b6073631b3ca4f296db8cdef978a49dc03f1ea4f1d8093969b90b71db000000000000000062dcc705000000006456c0f624bde7618a677a4d9eded2cc605c208d925dd0b429501da946894dda9f4f59f808b7529196a9a0de646753138ba2c1523d65c2e61b924a116f3b93aa38316074eac1a82a469d8f40613994f9d4b16cebd9dab6a67c9d971512e73728000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a50da206fcec4f8c8a89a6e28c7e7e7c4395b5715c4c4de4c87f0c7cf9f62d2bf175dc05e1892867f0cfc0915d8738f9598810aaf45445cbcd12fee715eb638bb1c504835cd69cc8b8545b77dd285efb0797bc65233f8505f633a83483b1885182235ab6e1ec35f05f1932ffa6b962790add5505347f39c6e0141d4f0ab1b12030079955b062af44f51243234d895574fd584842039d2e7e2208ea2f61e344e0c032c63973b6df88e3723e5c2f4d7f2c626e66fa580597acc5667e4f80611e4b1c80b00b849e9538f4542ae2430ed5885410ffeff3324155dbfe04a2b04bbd93c26214c3ed8fe99935ad64e027e218834218bcd0c3c785f118b5988f9d76cd057a07d03044b5bfe6b03469adf1135662f41144b3e53df3d32ba420f03cbde18644d2651030095afeec6ee1d057650f28aaa1616d41bff61d424050ec9fcbd34009b16ebdf020ff24c585dd4980fefc0ff67a30b4a9b0a3c8c69119ba37c56b04c68c03993ac031d41fcd19bad18476419029887cff6afbfc66a090e4180243a5025b8044ea9ef0207e678bfdee2450575a611802b16d30884e2f152260f2fd65ac867100d659ed7c42d9243986757233405ba227e064561c6b4df740eddc93020499cf83400f4221b8d9f30cd2332466da7be3a439348901a218e9c8ce1fc54c6a74dc2f30b55b60cf84c11f9e4c132788da0bb86ff1135d206b6797d4f42a2ff67f65b7d0815196e1e5f9bcd920c48b0d577ac36d47d4c2ab1fe6faf16c7882b91b28972c63c64cba88328fc48ec029b3d0d69396f0ecbcf2bbc3c4c78329678787ff3f540a656003530a7516c8609cb6e12f0304c76b84b796df18363ce7069340e31a64588f789df6ca14a38057b82c3da6b20823e65df8aa33cf52e614a15bdb2cf713ee8a9e174d5940780fba2e7d619fe1edb0e06afaec362d61fe9d13734ce1c936cba2a30b1741981a7d2361a74667fee1ab06d7ae6f0ebbb37f482575b9aef66c2ac213b22b84ce2428441ab842d10cb5d47ac591ebc27d7cb2c8904a4e9491e24c3c916ca5717c4d435891d99ce1efa24dd9a83991971cb096a11f692690a236b7382c8e84aba32f7fd14c449ffaa21b951760796c28134d2b2870b32e31708ac7c6227a89c39ff6358f062e8cb87baa2ee8967baf7e8158f1893ad666dcd200f9f54f3e0d40bd97b0b020efa54e7b47b9298c03810b8e9f1bb0b48b10881e563649debc2abdb8ebd49310f6edd2c1e216dd9496a52161fb59f99c61a57aadab60001b349845649346bff38134ee3fe3364f185979d3eef073aec8e0290042cc8236ff46db5b21dd97fec5e8765b3370e694b846b03eccf9b139e6a32a45c2536526963f4f32cae41a952456befad2ab03aaa7669964bc4c3bde4cceab0b12780d5066de1cbaf0aa4c610bf3555faee2c6a72866b6d5c84c5432f807d2fde5b29c0c67817db5c6b821e97ce372bcb10127252fa029446e8b29bc13171a1fd0df5f8f0e948d2893edebaac8fc55e0d6b482a47fb145b6e64f6a5f79990e2ad4b93824ec13e1fdebba33b7e3198dceb0899e91b3f7ffafb6ba7308c9d2ef722a0bc19fc3a1b265077fea222af5fee996b3d47616ecefc7385c86700d24a663ef43c37407399694d72cd46e75453924812b7f560e03a2cdc54152181dd37116a8eab15735cf321ebf1447ce527d9fe3b3f2fb7ddbb740ffe7149d15eb2025e78b75a598337accd1cc41e670222e51d2b141b9bc5ffc4189cd5a03632c6fa929c04be1e7ca882de58ba7ff8c2a4da42c7bffd9b7d8c5cb17355a3e8603242c76c6d2fc43aba369cb2709b86df7239fcaee4b52d8fd242c1470a36918b81a62e951eb0deb098298ed05138a59a0288e1c6699b2928e3c6b37e75f5b7b356447bc7a7a5ed8a976970ec758b3cd72a0ec26344f8cb7f2fe92dfe6aaa2e5d1554cf88c602ee5f0ec7bba718233a602e9879b6c36a31023953906369d05d3a4217a899f758beeecf75947958f59c3932b19e1025e50b19b034ca03e4d4f01b2444d15349108bb42deea7e8972a02644ed42458bb1de656b7d6c839a5262daa5c4c5303302bad3e0cb6757d11146e74b9a7c237f6cd36342d8d4274f99fc73811d0e032cd522c2f7a0ab4b85c8c5d56e0d9289c28e8cc5c53ba4aab0d26a942b82b935e9f8570a0877e43dd5fff71175162340602a6e43b4505e2b65cbf06bcf866a2ccbac80380de5d303e1d0ab9abdb7cd4d2e34a50785a675f65fc6d5335a5f345d0c11607d7867a6d48c73bd54474169f6945f7f21796f852602c469321e4d4b49e29148895bd4517258db02fa44124f215dbfe3c9333facd1d871f09f6b36580ef4d5aa859cacd657d522e5c22005bb6ee8207fef61fa93ddfbcc26494d13e96eaaf24271bb453c852cd95f1bce1bf7f048d62dde54e00", "5100", 0, 970543965, 1537743641, "a6058f151aebe5b53b57287c02e74ee55cf464f19408d656668d4111c36619a9"], + ["83e2f965039b5f55bbbe32ed9f0333b922a0a23995d46f5fae602cbe1eed6fb75f9637afd400000000050051516aacffffffff09014a2d743eca497fada29ef727934fd68d50a9178af8779cf0829f77dc7bd201000000090051acacac6553ac52d2f0b4a88d446916fddf4c8bba1f80e2dbd8412110fb4cbe7f1cb3edbc34072fd429cd0c020000000800655351536a5100ffffffff01a25e8d03000000000452ac636373332ec800", "", 2, -2057996197, 1537743641, "3ab7df21a533ae3533479871924bc0916a1d6bbe9d23a07531927f363d31152e"], + ["29dbb6020252a291d26f565e3582f385faf7e1a853b9ef7911a9a184b54a3b00c67b2a043403000000066363635153006cf1ab756131268f80dcaf16268265f2a6a5cd504c57cc16dc40eefc38c5808949950e360100000004ac525151ffffffff03d550bf0100000000086a52ac656a65ac5375d29402000000000263632f962b030000000002656a38db086700", "", 0, -442102597, 1537743641, "4d600511cc4e68ed2c5174717803cdda42712089c1e6c99f37291772d18111a2"], + ["030000807082c40304e086bf8400dd6ac5fa6bc135c1c5c8d84152158cac8cb066d3e32b37204eb0d20300000009630052526551006300cf36ecffe92fcd2edf044f16a85dc525d86231b583629495833ef82697ab45d6fafae97b02000000056aac6a516a122a24c0981469bffd2c240fdd0c8f8ca5752ff15f6322c4baad867e0ab1c493586ebc8103000000045353006a2e40ed70ab8cc8cb95b2500e4f1e4056a390a36c46c1c785ab49592236dd17098da4dbd802000000065300520063522b18a83b048e2dd90200000000001cd392020000000007515163510053acaeb7df020000000005ac6365510048001b04000000000151cc5bd106966c9a6001be6a26020000000000000000000000005772b9b5a4ee5ddff75c5ed710d45325d7dc354a126c270540cbaf86bb36c7af77d873bb93e7240fa3f963e5c9d8ec955d3216054ebbbfefa0fbed4dcd75bbe5ce7bd80c08d11a81305bb19d21ebb325a52474083d81141a31ec332f58c02f9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120bed51946b9c476bf8e5cdff84980de93629f6ae9cfc43a72e2b5d74eab9101db023c5bea1543c0d70868bd282bb88c235f647cc26a832d61d4b1faee63041ae64c638479d7d2e71f90260dd7a3991c56dc7a61245cd3ad226168f65a5c36412eb0b571ac8f16963be4aa64038312017b7ca2e80950e8dedf84bdaf366fcc2031036ee603535ea325862defd163f7309d1b0ed6fe114ec0426d037d3986b80e60206f7ee4156b62bb13e677e25d391fe29a1c4fc86a632b453c2872fe0cac8a60b0b0467305c018943384a1eb9b2c914166e03355cee4c5de68022e600ff01de4836fd9ff197f37fad5eef4df9ffb06646e01f6534fc6385af604e458ff7f8c4c5d7030c1d004c3dc45408265276bfb4f063ccc3d511c3e1389ae1e10a3212d1c9176f0329993af8bec40f0c590f3fb319a72ee232f8d38057efd40e9996a48436e5303f022d013d68a3ec677769e07fe89eaf1d9790dbe6bacb4062a54eebb929c131d2e403087602812312e5ded235ffe6b1f4bb3d466414dc85c9956ca8bf592e3635bfef0316ab0757fb2e87941db44327ba327d346c13fb92250dc7f21dd488229672488409aa13350fe4b0726831ace84637800c51c313566388d53eae116c0a951b3761340b801572896cb3231241e63e790629f080f18c90d136e4d096f592ee288b7ff0a5a85b9b8a32a7d321aa012a8ba3a970f0661cd2643610fbfea4df5ededc7277cc441643c03331e27043fb6ac3482a6adc0fda0a8a48c716365415a1c5fe166563c809f911fd6db38510d5b4874cae7a45efe87533b006f4e760ded0cf028b8dbe60bebcd87e368cd8af63ea032310a7c4f46c171b111fec1ecea00ca687eb18bc13a23b5208514e73759220e1cf553139235d1d52b71a37ce863857f5c7a5d80a718d12ac0cbecff7c6be974630291056e2d17e0d8e593e02edce73af0e125f9f70adafd62cbfb28579880070510ae028462252885837a48a19f0b454e8f0e03944e2ad7286886d02e4a654f0dec1767cf021c84c70b1d0a08df12d78425f3c1ed3eff52f182053676b7370443d5b40b03452fb9cc30f778a67f4eb63cd68401aadb4ca1b983b2e4e2b59512ae09380448cabaee8cd6cf8a5f53994a70e91c1095b37ba9d4edcf5c28c556519cbae8ed3773a92ecc10c8c67c85a49ab5a65896ff0e864e10414db4515257bb102a89152cc12974cc41f489f528d72f65354f3248555b5cae5ba676959eb61dadefb926baabb7b84545fa7b60f395d7b3e33c9cf12fe4dd262502a21b23aedfb30c9ba8d6e980271cd6294baadfe8b6df27c081c1c756a959b707fb57ce2bfdb02a0ae354d5c315a711321a8320fa7690a1fcde8f1a3a68d31a84805d0cbd1121420f4a37b3d7dafa1e10d1cfc7b53e6154c0c5f692e722dcb84713a584810551d427d6aed66b61a041160b784e5751ca3dea8cc519f3cec8d435b75523d904c50c5ef04947321305f477c00c3c9c16614bd55b885b64e731e2dfe2d0a1dc727dfcf0d1bee0e097c4c2a85da99bf69dc2949f928087ac936b5e6f11eb354fa85ea792781327e03acf53b55d363ac9c7daac054575785dbeeee327c8b3f9c74e2ada82b78224bd29b06b26923a72b5aff1c9dac69be9ed715bb9d7c8b55707a8c3f42e960a562db72658724d4565cb0fcd7e65f17c6a450a4a49bd42780ec5e9dfca59b9b44a7e83d668a25f161dbe297ce1ef0ba15e96b6dd0227a3b30006c754834164c27771fbb857bb00a72b3fc39ba77925f5422fe8024a0d6425b993a3cfbf9a568186b4c54c44e31d82a84cd981f757f445be52935956e880b5a5dbea9410ebf57c8898972645c84cedc3c0f733b234ba975c5b1171b3607c7f2bbbe323b9bb4645ec5b044068ef66c85efa3c3546cb214bf1a6b329a475e8083ccf5a6d64a25c89219a2bd92a22376e32cd8c66edc8f76adcb9fdf569cc50d1837dc1fd76714e66cbd854317eb577fdd17b66c8cbecf4b8ba9c1998eaf666072f233f5d1b5fdc1cfe8752402bf7bc50d07038502abf0bdddba26a3b00eb8dcc380d027e1d53cb4d29d096bb69950906e8f6115e239002298065f38312be6329800f52a76706b5705bd09cb900f25671876d43f767319e96f96b89287cb4c46c41c77a380765482ac4e1aa15e54f4a789c98ccca37220a1ade4150095925de747c734192b1204c3fcbc611963b39ce605675afbcbe4fa46e7cbc64230fc7eccbd390fe012e96506c88cd6729deee306f1ea18022e94e1de4e78509822eb53dfdbc2a5ecbc6db3ffa7f35165d9c61d9d5e384f516f6916fa31f37f5e563055a65a3248c7332326e8a115c240a73297da816c345fc1a12e3fc979ee9e22f48eb64b52fe0987369f111a21097ecb1c7d01944a742579da4103fdbe9e2310851ce5e667f65a9a21bb0e", "65ac5152", 2, 257261756, 0, "5afb6c16590ae338a8d1ce24be89b8414532caf87ce3fe0cdf117de5039e1726"], + ["9b66f93a0218806da33bbc3b184f77821eadfabcc458ed5adab55c4a8287df23ae5bc52fae01000000066a000053536affffffffd2b3a1d7dc201dee5270bc7cc4b991d6c3d0d7c2159a16cea4e61c00f77b7771000000000163256cb973025b7ba60500000000066a6552536aac2b76400100000000095100636a5252515265000000000100000000000000004d4cef03000000000583210a6fa19db3139288b5a8bff1b4531d7d7624e9075b78bf6fe5674061ec31e9fdefb29099891c6f7cb63505a36f95ea4ff243830295af4430d9d85ff37f0b633b32e76e8a1e3259dcd71c3c1db19ee02225c52fd7d1d6c29127a44d6a2e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051175fcf93fb2e7287392567269fae8e61f04a3932571ba7fc74c6f7bace0c376f4e283b8d4af1c577d60465e667da3b10e7352d12cc4350dc66ce84385eb06be0a61f6ddc977617733c6172ab3137a30e29f5f2cc21e3d746ff615078245515922adc63105e65c153b9358508173bbc81e482a6117626002f896aad2793990032e0e722b64ca38755477a172d01dce2887284cc60ab1d28157dbee901975c9b702271c30608e9d0ca559f9b76c1f4c8d413ca426d6650588371d383240a89f5efd0b03f332397a248f596aa6187ac10f3d0e0dfad6c9b571367fe804d67a480dded8aad21961e43e1c70df96be5d8901080298d9b8e473ecd3d90573750534a22962032e8b63499dacaefdac1208c82258b9d81b82fb6a8808403e0466073246ad9fd60200544461ee2a59a9cd8a30856d202da66dc4e2e68fa65ed22b9c65b4c94ce4d2020242d4614f1b996367c37914d46bc7dc51e7cb2644f26c630f847a6bed624f5b032a51f417dba790a6137406fc9290816b2701c5f4f272e3d1427f228132394267022dc71e9c608976013c8b0df3f5e64fcc2a8d0fb28bc3288686b4c1f1d5fb8e415e6123fec49232c47283b793ce4e8bcd6ba5614b2bd24ce0d6160ce2ca3f11304b9077d9e9a7c82c7fc6a2fe436da441d23e4ded8c24b12767a5a102a3bec8d9f2e9ce308926477baf5c18762b70687f5590b98fd72a8ee5398c6280dd557f75c4672c60c8f23dede4bae0ebae771cb1fd469d50831d4fe5c7a6ccdc2e643d86617f46e7fe807e0722c632dcf994b0235cf1ab768f44cd56892a38e455b09cf6c02683a3f5b954485783f14a3b71452f0d9d5b4c8a54ce0637a0e7c60f8ebefad7abc17a2533afb76281fe95d5217c8934dca8dbd711595074126393caeb3a5980033d6af333b4fc06bd1b2991be34c5b5181378581b6843ccb0bba815c46569c5935ada8fe6a176dbc8a1305c2c869a2b1dce7da8a715b5a3629c05384fda1793d98b568c94b6f65a9e2aa040571597b23b495d2ef445a9c5eedb14aa3e38b84234d055893a7e197eb4d02142b77495c0f662e4f37231b45119e95cde422844cf933589810d253452c42a84bd19a5084d6d4f844efee146fa09a8c588963bad111935c29b3393f9f868ea5e1af6d6f6ceec9ed3ee72a95d3fe1665a75ae3679143abd3dbf5a9b908f0a1849c9ee5266973bb25798255196fc72609e6058fcae35c4410fd399be39786f7f335ec84bbd251ec9014cd920c39740daa51ba6585920775c1e3cb023c5ba2df90316a753cde65d6f69329a7988742924934b847c86266f537fd76436a0e4db131cf7d70ae7196bebe7d7a9c011231ab743eb24656aac1a15ab5182e90a4ff4ed20ffeea733bd201e7721bfb45b409ee889ad131700fbb050f1fc23f56fb82d30b59e38454b0f431ddb5ec18a87a0fcd78880d8a5ce1582555982737058e6fdf1144b2aa3fdf9d2e4cac6341de6660f73b5f9742d94847bf41e90c3d3d04c057297ea6e2f050df4e0f5c18fb321a66ef350c9a577af0b22c923c8d67657a866237980c17abb0bf4cd23bc6c8fade5b83f922ced20852ccc0f6fa2fcbb74e1d4416ba09ce1f9993708692ea0256b3823abcd10a82b06589a3fe6442a6c5e34811b273e3bdbea734c33530af94941ade9daaa9d94dac07875759e8ba4385189bc1b598b0b494d0ae60b2abdad9e892f500a2100662918d7ead3dc3aa68dafee49ff490136b8063310b1a941eb5e8a5f234397370bd8cdf579879faca5c72d5c11cff7314b051e277197d1225c30e0d8da1564e7d5edb5ba4afecf1d8908184a08d8fe8a1580cd7ebb9c19ba696bd1298b9ef05e47559df2ada2a07de90d8ea90abdc76c4ccea1b393a35b8902830a926f4e0b42d363c77b3b5a02586c2ac7da55776b4b14600ae0f7d0d88153145a438bfe3f386593f0d7cd9e628318dc1c2ddeafe552b7a64a424571c828079cd1b8fe350fb22c75f148ad69c767aac1c59efe9636ecfd1b3fc0ddeef1c00177eed424e8cd52163d2f8d84492ffb1ad7fdb2461f80425f35305baab32cb02421be561514bebef85b2273b12a74dafe04c52bbe694110b5ed9fdb80df0678fdd09fe1f71041e0e3a18a1b5a499b0c6938809dd12ba6d39a0fb3a8a4668a60fb5f4ba5eaa504e8be525d9b205109776d59e50ac51e1efa72b27bfadb32b86479cbb21633534cd2d446d8c0ce0b7062ceff0ba7d3710260b80a6d8b0d828d8f690fe3a60c95ab6c13c8ba891def12660d4f55b68fcc765cfc754b19f4606e3e11074079fefd4e2489e5c9f51b45955d63e2633742a0a18c22ea262a03c88ced0e6c47f64930cd390d48466da477d55cef858e519babb18fb42f5e72776543ec1546b997a42483400c529aebb7e0539986925158e221ed10057e2b760e", "", 1, -515577429, 1537743641, "e8dac40a791db463d3937d323342a073ef3cf8709c8da9aa58ae709cd06d70b2"], + ["94ba7d3e04fccc8d447527d871d88ce9c3b4881eb085508b41c0d4140504b5c269b8f7d044010000000200518c4d895a2a5807dea1848a158be0d2210e2bc29cc3fa09c89b250f2d9e5a11cec7be00960100000009005363ac536a51516affffffff7d3736661367cc111e4cb8191669700fd1b281fb116db85fedd91fcb9337a347010000000863635152656a6365f38f95e2892b4edaca13c39a7b6bcc5d504eb0a1c05a9ff409a9f396d1d02958f652d24e000000000851636a006a006a65ffffffff02dec9630200000000005f4eed030000000003515365984f64c301463951020000000000000000000000007e76125e8fa2f4ab1529bd0b6de977d92771601cce89ac1fbc3c9415c68c7f76ba5c825828baabd862e682de7f5acbc50422f39e30a773cfcbea5f0f4a29fd00751b05535e21590da1d44ca6a42c18ffc606af8dbe0a829f0aadb3555e9c647c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf074f6eac949d639a99bb1cc5d3ea59bb502f936080a44a189447672d6bd627d54e2795148916e2f9c1210a99b200642b0a8ef48b0876a323083eb444e01dbd949b5840a49ee32a80d66d395448cc072a5570ea36c7a76853940a9a7626492ed73fad93603925f3505c7d2c199d952c19f22e779f173bef8bc39a9a4a518ae6032b0781deeae1c61edfe232414af6955cad4cf0dfabeb9a0bf86f444f0c4ed745021fc3cf047d74c7d72bca0733cccab0accb1545ae3dbb9aeb84af5ffbf41eebd00a0389a8934ba8a046707513d8de3ac5d394d28c7646f81540ab2477b2731b1fd205bccd7b71f35fdfe222076cf8c1e93cb45ff20eec4fb2d7ba74141f95e9691c03257096368984d7d6d0cf3fb752b65df17484f5bb3403846150670bd20be737250307cc76bc14b192cb34d5cc42c6f7897ec7ca2c78cdec03d84fd0bd5a52265a180301151186df167b6e3df27026d96402b4712937ecaea3c05f887aefabbb298616022eaf9e661c2eeb3fae0c3ead42cb5cba2673e1a12fe30a3453c349ef9726683d031ddde49d859deb954be368266b88ea3dcbfad257b28204be6d388ff7dd1e67b278241fb1dbda0e7ea0e916667338497e654c57b7c529a163dfa032fa18d8cd66a30411534f03de906c52903e579a11f5653b00b93401d5ecfca96db830e67f83ca88c9e5ee9ebe43c98a5eca2476fc6e20f8750c1472bc8ad55e346d1645a14441fbf1084f7bfa723610ca0592ee260c272b3d309696fe86e6710aa2527cb74b2864f0daeefa96f6338d072e37278ac3070f98573a29991a797b275e821ae5b99368239f7f2387c20148056e5cc42d4046943112c05d61158a48283bf34c9edeafdff88f45712be946a5935283e6718fdf17448e8d62dfd771d35fc3ce2661ce04ac33cd9b6f299227d9fc97d8d7d0638e3cf67498118397de5a53d3640e54e14586c68fb87f0707f15f8b3618b5f85f6cf5d27a93c8712a4dcdbc5199372666af56ce3c09f917c54f210427cb01ebff775d9e2e3f2cd9132df44ecd5b621cb61624af68b07b04e9fa5d9f06ab716c48d14f6831c5cdf668996135929d27e7c52648463db30b0c9efd15f5542ac441e3c288103ddb991a0533c74bc31f65a71723ac4b33757adb4db6d9835f4dcd2d18dc58463b112abe6bdb0dde17b57db08dfd73a470371e0efe7a2aeed148639791fc903ae5f2933d2eadbb17926c8e6f9b8fbdcdc3dbdd5cc97157d622724ea414ecbc6932a2be8e15e41d56b06c4099bdc3d2396b571040351c3589c6fe4706c96937e211c8f7c704b9e7c7e7b412b708bfef648b0a54013caa53ed5dea54220dd3c37b61c55ee5e09e3724896dbc9b4fdd0fb6c037c3c0746af52c26195e947ddb16f6d2df21b12ac6e368edd380cdcb905fddc067a59f2d796a10bca89810daa6271812b7b2cc3e67aa2280d0bc00a2c1a1f3180fac954fa0461fefe153eda11cd68e23905c1328dc202eb74c13ea57d252244dae6deaaee8fbe884a62e28f5c71237b1dc0b23736b8d2969f1952a2030da700116e2845afbc44c064f71cd021e491941ece675df5161e98913dfbff1ab493afccde48218af312df2916fcae41fecc52348c81361dcf33c1bd54138c6f9a65621fc8b101100faa9b1bc77bd62ec6fcc4fc0193baa92fdd13aa9fd6b7d7d51f41a45c2bcb3109644f627d5771d31998a218577a52fa0935a90bad8939183ea722387afbca66f4d092d7ed1bbb578caf0fd5eceda9128497e6fc4d6583baf9d3cd389dc86764a546ddeb818270a1d5c865beca38192bd3c5d9b90a7422f93cd2715985e6867051088ba1f951dd57e9d99189f17a4c3f44de1d3c103c2c81f6d9f6f7e8d1765126b0f7fb95bfd2fe0eeda6b6f6b16165a221dfd03b6a794b8bed5b623d889f74192642ed6597f426d9938a1ff584a1ee1db7fb95b5891ffdefa4cb1dd14ffa9d8a8e06629c9be9df73b8dbb3b75b017f8285b0a9596888de8fb924661016c6c8758c244d999715d1fe3d991fae51a4b14a9db8ae06eb19165adef144b42493b432a7d772bf5a195e5b708b21251382d075fe6be38cdff6bc0dff40f2fcc2d0d8a4a686d1fb3e482f4a8534f5998343589ca233042aa73c885dbdaa02ea4315de4a5e3ebc15e156442653b1d2ab00104f697aff72c39341bc9e63179eb0bcaaecab5550c26da3bfbf2be6ce9f37b8de758648ae3990c4c0cce2202616ec426614edfac3bfbb0066b01c1441b098617446498832ec5ed15cd93b47487fa35e19e969426485d860b9be2ce0e5393ca136fdeab6f620956fa1f77879f5a203d376664787b0c066a78422c5764ff0f470c1b8c1dfe7755e60902d12d7d08ae4ec612e2191948fc5d33f8d18187b9b6008c355ed0571ea1a2345d22278ec7532adf07a747f17bf7d1fd6e9601", "525352", 0, 23847538, 0, "50a3e5653c1cceb744124a27b3b4fac9f88f96f1eae543033ec0888ffd80b8ba"], + ["030000807082c40301c049c55b9382d7d22eb2e8cd353918ea4cd32453c250c8564edee90eeb724a610100000009516aacac5152ac530093b14f3a04c8e03104000000000563516a006a1022340400000000066565ac635263c11a4001000000000251005dac150000000000026a6573b57f109e0c7d6d00", "63656352636aac6565", 0, 66388475, 0, "504f05b47a82f3e7aa6e81060a5bc54a101c2148b2bd6c75059bb8c09f0892ca"], + ["030000807082c40301503b9dd029ab29c99ba5fa74c1a3e22dad1810be3d208f8d2f5ea4c3d54c10a80300000003655200fb8f4510025d27ed0400000000055251515365100b9502000000000081c33dbe1ef791420238a96e000000000000000000000000004331e795dfe815d0e7afa230aa9e167abf86b7bf378d8b4b8a8b179951e92b462c9a4955538b05379c66ea6a31737bb7421f6d59b78af3b95260ee8e83c0d9e82cb2b24137b3f47f756392864988f90f52e2c4f70b6a4984ab3d68ec17ba88eb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8798052ee906082ede514b4690f8608804ab7bd6bd899917a285f0a69668c60a9659354c693dc0d7a77127ea47e410385fb02faa20c783cc5075ac725797acf61731b7a998d759610bffa277f1b52d93a656498ddde651ddecb1a724274e0fca987f95b50b1329b33e10a02959ae08742bc415febdcff7d7d6ec7e463bece2e0329e3098b5f0a7fcc4604dec12dfb3390833ae01da1c3580055b7725cf189099d03111ba7989037a91df946d0d45024c183dc7b8e1f752d488c59231fe7a56651790a06b220157026b1afc6067ca11fdf1fb99cf2be71c948f5988fe9cba79667956599535fdc37a3411ac1f16d9cdbd7fb82d16e55fddb0e7f721d4a8137b7ecc514030c547d7d4144e24b7a22604c413974567380b31ec4d167e37d51dd5f30e4e8120222ee3ab88d82d1f8b8bb73d34803d8786134afb5fd6c536959037f7d39f27d020220e401022c222fb39380a5234ee2bd900f22d762ff068b6116b0a16c3b1c88a9020521bee3f22ad2c35e9c0910484e1c777e0aca54d1854cb74e9da1b05f5f05bb032ce10b1d8b5bba9c27d4540affe549c8b7d4819002072244a4ce1bac021a93d778707bdd70cae61988c22848c2b89eff38fd21f048163e163c29bc0fe4783d83066c13d97a1647d82bc0bce24a87fecf8be2a800b6dee085a5616eec1c678dbf95c097f204e276d16d485bf6e62b23b79f54beb17b0b2202f07c306872b8d8115c7cd18700beadd7f71cd7ab1d3a7f154d58a38448c4e175ddd10aba34e62cb7009b87466b1165c86a30deca06fb158457ff6efb0b10a073450e81bf3d720d354a9b752956470fd36a63d67f7b7a89ac7fab39cd9a80b18c3877d04d36d31b1795c9fe6030fb201530ca4c06e17fbef5ce7f68c07e5917e5d8f6615cfdcb8f01e73e3574831acc7879e81d36314a0fbb0a178c4500cbbf1274688cda428486939961b6adc52af7d490c50d5bf484d6e637f5ddb4cdc31739712ac08e4d8f3c5c25aca7927c1a4b4aadf48f6dc9c6f4fdec94fc82aced9fcae4794f403c2a84a029c20fd0a492a2d85d66ee6e78048087b7c700d75922ac199846faaf911c3f0d1de1b39c700ce61ea3d856cf5bbae3bfacc1da0668d0c7a0524d5a2c2c75f16f0d070cda32a296e15d2c22508aa61a3c30b69b423d2cfc052d63ca49f7d4f63ac1ce6c6a1286c1f80cc1318444172ed744a039066e6bbc971d1be0c84c7a1149ec44dbcd8f597815893331eee4b61e99d6752e6ef9e0d69df8f1f681089445e87313eb7d3ec4c4534440c21100c2ade3b058babf16f56881b45037d198aedd613b4835491e64ddfbe3c966e500cbd7b2c8149b265ce156637a5c47c7b919961a2564d2cc9602e5fb7148af75d4966d4bdaf7ab2f2299d26f4cd5566e1fd221692af9e99ed4a2a1ead554b12a8fb264601fa879e657ec49232b4a0c5ca6f28a9f7a4f5b333b388ec425e8269063c8bd85acd8caef655ad0388dbd0566cb2436fc59ad3cfbd450b8f0112a8e28207367f5627c564bae84a9e5017116ea4cce2755bf454fdbe7424f13c2a6b2b7703cd27c2c12db4a42def06047442d28c30c75d68728dd536c5619ba5488704c573aa24afe33430993f915fd7d3f56cf7c22cb92fa705e67460a8bf178cc77f0191435cf1463558bc318d8ef8079c5146d10a4c822689023cba135a8ff7b20d70ce2a37796bc410be2c5df17f0269c202d5ee1e5e5aca76834a5788955c0f034d570f75c4ccd8b91fa88729ef0eca3240ccec9a0267fa340d2853d8d2ce328f0af6b3ae74eb79b8f42b8b2abb1cd6be89072986b2ba37f3256f8636cc38bdf3a970e6d58f1d7b3c0271879d44c990004a3a423510c0d132839414fc71ec82e6d6731c291c048188211b9bda8f3481f199bcad9b0884d325ad9fcf052ebf25979949d1d0272dbd161f2fadf709e995b031869e5bfdf2dfcba54d3473ddba9c627c613533a455c579cafae1f23c46a5daec395aabdce80bf12fe7370efa02f71f2c3d4d679aaf5578e37d567f0fd613f42b6235ad2968a29c321048fd8dd4fcdb1a76735fcd62a0df950a404c66104d5028967e91de68b5521068f660b6b594cac916147c8ae45dca8d37cb733f0397bbea7916e35d55b430652e3494c9771b9b30ce21b323e98f2d2cc69fd05312e9516aee3652bc255ee6641e8cef940377f9b7572a0c11ae425e4d12cf0a23fb7161429259a17f539c95f9626d02e8f971da507f0a027ee483e7d3d8c3beeac12a859d0c84202a87025a7433dba18d4e0cd055f2d0e9011c200000000000000009ab7a101000000002ee0cbe81024386a6bd4feaa5170e8925c2e08345ee83cb88ae815aba131b7870336e0a521acb13077476a5b087df6a66a6cde994153da5205db29203f6ae9c3a53ee5cd9bd0f93dbc34a9130c409e958532c07ec6a140677218b8d52abc342600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097cbe29a649959cb7d296e66bbba5375712b6532304212fef044c9957ac8488fa3ae95cd76f8609493fcb08aa615036e0fee8941b721662d085a082318e68e23180e0c338204d3525732789a1783f8b1fe34dcbe73eda96107c05a04713a0799bbf2ae4d9a39fb0ee994dbee89e55b623104665f1a7a14b41db0919e16dc1d5022eb31e69adf5b8f6bcda7bcfb182a2385bc9c7851a0694566ddd021ed0b88aea0311ae13ceb74f32f6c582884a87ad41e8ad9d79a281d2ffb3b13c4f03e26e1ef60a08792ace9c17a7fc5af0784e074835cd43ff225c76069e13e6cff9335b4e3372871145be37622c35554ccbc9717e68a646d05640b6bf44eba2d46d120e0fa3d3030ae1f3e3591106723ab5dfd382834128007d7df049a59006e907e8f9371bdc41020fb8845067f37e0e777e179564cb6004ff77c838e0bbad3730d2505b7ca18a1a0305b08b1f7f151ea32732ac92e69e39eef2a9d0923bc3c6d9856f271467699e910314e381bef95b03674427c214b0e83c172d9f37db5f56c119cff58eb3bdbd1b9e0329b981fd064d56ca045ee695f25d198c69f7ce5fdf604f5b165fd6e54a7ef941393588191065be6ec043b1032d0323bced5c65d4aed7a26d31013626f296cdd026b82c958350e9927ba5603be8ef6311b490c4aa755f0fc94b46b4235d051ce5651317f62e3a6831a5b3e820f241cc3168c69a3f5ba964afa9dbfd65e93bc269a53b6355f47fbbe48b003d80591cbab5fe1f8aaa5f895d85a0f9712ec3415a3f572aa1bf34381472dd8eb478afaac09b84829147f5b67e5602aa9c676dbe06775be5ecf97650c779b63ed1e18bf1a6506a87998820cd5b451b4f6c532a218c630c991d9643d4f91e64555263d97e702f68e0f136c54fde78211c5cdb5fa5007b1953a8dcf5f57d165b34eb651e24f67a987023b890356237b0464ab930e29faba350a49c8dea32eb895f534821bf42aa69b66dd12e076afcfbb9ab4734399f982fb827ad8e4fd1a7545b012f62ba6218330e6f6ff333b0ee232314c76473b14a601034464b0f87bc04335de00f6dc7cb89a975b2b552b02b4f9a01bc0a6157fc167592e4edd5099dceb695a604f35280c79e848a76b486a142ef4dc0f0c95ae78f6d3b4d4eb0c6f5270bbf738fc45f0bfb065574e66ca2a9955922b6944613699c146cd6adbd3737ab02d0a2c0dcae05af60edc10e417098bb6d72151d90dbf2a49b61babfce3c256a12bc4f7d9b7f4180ad886ce3c81d549ed7dbf33398494b56692611d116aa654b15d213ac049ac13e64f8736ee3890c1123b248a593119c3cabc0d2d0d91748a7475632367b20026411e98f8dae7e740c73e3bb51d6c3fbd1c4514baed6398a07c588d9b0024d005646e7313b99a1fe27717edf1e5bbec8f0d4af6c3d734156f2edb4a977ab7fb84ced94c72def3291df7a02ef2ea835488f2beb7e1e722fcd620b4408a499648d451c871a755383d712312e0bbfb07d6c062ee97ae7df9a824cab7e132e309f39d0b20aba5f357f264d06dff165218e22ba3f9d419ccba666649f5b2dff544ad80e660eb43f06b78c63820a05f270b7de7bbcc6c29d9255b2f5d84b8003b1f602b8f830f1c4f50c08b37e782712dd5e0b46335f0177339a1e3e3b1fbf8c21299319a42ffeb33de27bac087dedad6031a9bbcd7f9f08099867d65faaaad4d1f24651b15b526ac589a024b81d848ea6a988985d6791ba5f764acf1637eac749d84880c781095e5312012dfc988518b4910cc0489110d881fa79d877eb10467d97e199aecfa972de285e77a923d9eca02290ea21076fac4389513db183d915aa305c29e0d94825c0c7d6861b521d72b0cf1bd9f077085b39e49d5ac3e75bd96a46564d23332cb8c2d0703e9bea0364466234b5764b61efbfb668888a09e5a55db34b5294ba198f964d07fde9d4abe014b7c56df48842fcc5fb808fb6bf144e25e4b6da306a8c1bd2d7b9b464a2a3be0d48f413e381608ba21d4b8f23538d17cda975e124815bc1c1116b0f9e19d64e606ea25bacde46f68bc89cd403e381cd562d84583b0dea378138df43850dd7e4a11db48a445f132a9b742def8ba0a17606801a2282657c4cd8b8e2dfdb9ed07754d0cc64b2e94051c867b62e6b7871c621cafd4cbd283bd3681709dcb8771c76db42117c7bad43d18a7e63b3bbe4bfee514f5d3600aa4835a93a439b1431f16dd8b2c203ea9c0538bf278ac7ef7f037e7a41435a22ed6a9d05c9cbea39611a0a5c514df2593a3c337e8cea70e3b3b679722c33b3c0ffc42b04f4779afe1acfdab8f067036d7cf8699477623857d372035f28f32523e1964d6ed35d7c93e9874f61eebac3406c934b57777f75ca76a8fb6581ff21848e22b7bd32d0140da0114fd8a48e3af9b02285e8f74de79edd3b203a6d75c708", "0063525353006565", 0, 1157052904, 0, "d7917325a9908858e96bc5d374625c16da1038d81b7fb105cf35da5848e5aee0"], + ["8be71d300135e51740ceca5abd5dab38e1b68ef95971b9288ecf28230908d75d0606a17beb02000000086565636563635353ffffffff02cd4e010300000000085253ac6a00525363921a8f0300000000065265636a6563ee4cc3030252c5cf010000000000000000000000003bfeaee61790b4470a2a0c0a34a221c35c7827f72a4ca90a3af3ab545c030bd5bfe3e01415032e85b488667566bd1e15032c570b9c9ee4bf774e1cfd2fdb414030d60862212860b15ec4ef3ecbf83832cd6fe8a792edddf40bf9478d4743a73c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006dc4cb4499dd9532db6c67df2b3b8d4171ac9b842e94bb0280670c1b696c64d65d7ed7228c24eb876d0af70d12679d7fabc2ee67d0812670464661257a235050e7181f48d4abae590c959c1a0682b2bfb807b7c2a67a5e4249e145f5ceca54f677169e2a9e2a8b62fcf67d45d1906f81700f5da9ca6a96dae64fdfa0ceb85663032d0bac670e98c291fd18d4f01d2eeccac43599d3637dac1b0b8e71fa24a044df0212b79e577046c158bc099251ca887f51bf2aba2f7024824ae1acd4886b1a46270a054b23cb9758e6b64f296ce22425d96b6a02db684b9d1cda5d5718edd56428b2668873010ce60a65b28dd64cb97901742f4c4b94e6c39c68fd74bc99339525720208b395cd87f2e8239a602a8e0a357881ca7d64639d4d86916f3c696752fc3e8b032530577c8447cb5d0a431d0896b046fc1a5bbdd575eabdaf2143c3131dec477802286c40f4b288c767ba8d40e687088875ac03607202794aabddbe277539c875c50213ff658f2b85dede1a2c772b9d059c91925d6f19c740e54c9b8a0b947e3cd1f90203a7285035c3447a3e55af908b9abaa6378d6591fc374a2cb4bff2e67e61af2ad6b7b797b262af081765ddce06af275990824682a3d9c6d80cb7bfa13021d64faf99e219758b4700d040d4b1fd1fcad726dbba99b6b7419e014b83533f9353b9930a42b573472ecf1f1ab5ef0fca7804d44cdb8e0baf744b10f6d8f7a87349b137c9c30cf6b51ca9a7025d21bccc74477a0318ac221a308d7a6ae7204f232684df2b43ab3c22c517c616a45cd326b260678ff9597e4f93e4500060d687cc5f88bd259686ebe513d1433344b86315414e29bf781e66760ba41ce5ec45b53e2d16f563af8f21337660b5a59d85de7fb7f4fcafdf627dbf2b99b702ae1612cb53834a50e114a8410dab9891e9e9848ca29d143ec0039ef09f80290486f4bf2a457a00ee30ae82399b07829c5bbfd113051ecc237b07d75b55f47915ab5710c10c355bf02bf420999f1d7a3d28017a9e39e066f6dc653d868b6ba617d44bf31bf978c27cd9fcd5c777d8dff1ce5b8948dfa86e17b65cedb4d24e6a287938b3e0ff0332922df427aeae42d25711d5ca6a84367c10c97cc16a6057ea452d1bf411d868fdaa5cc1a55570611fa1a59f9b0f773e0ef4d66dea2ceed33955588335a7383991114a621e3e3c31a39544ad574467a7c0c1de7df20b893c8c28ea1938fdbe5f6ac3fb6dcd66f30bdafc9952ae9fc9d9b94c3c699f80ae9564349182d1657d3f730001a645b8b82bac262daa2afee3c54017afcc9d0886b38c055b93e9189401a358133de8a0e4d3039171c046dcf157c1edeaa0027e41a66b5a007091a579b81bf76eb3ed5e567f23549d0f6c12290236a6d872d9724a14724b3f681531271fb651a2ab12d33c3c4533e7085712868b67cdec682758f2dfdc4888b564dfe17ef76f748f24c44ae926477d877b531bf5194877f57fb265cf0298b0b564190d8f4c070d6c2a27d2c9426f0d717f8ac59ae4f7a69e7662b35054d190a786e703706ff3955bb857edbf8991b657bc6f1407af3cdc2652060a62f30877d75f838f529e2ad273aa17dafe9241794f9e7145a9633e9faad5f94689ebdbbc84c10dc70797b4983b821efb2023559fdef121cbfcc398dfdf8234dbc0c2c84a0aeeadf2925a2a99cbbeae6cd66c1e06d33abe7caacf52f3cd9b0dd2ddd21db1628b92e79dd8ac709f902f8493371ffdad344999a560ef4028a7e696dee3bee4b6a213d643c819a008ff7155bbd785f473d2fa9316019fbf435ba8c2c7c7d5aa43a3366345a8d14e183897f75feb347ea36946e1b203b84e64f981e1fd5ff4671b5ce18ef2412b58bf15f2b272ea59ae34cb4c3f74c634819fc539c6e91129e27bbaae11062139c4f20ec1c178f8a90a3a80e629b3603d600ec1c093cd5cf40d35a09fef0fd2307a0df39085ce10d7b9c5febe5bb830f2043fab1cea31b2f5e35e1977dbe9289001c3b24a64a9b0d23b6b6defb43c824dc389524d4b9a6408cd1b4bc66e23a578e9a93ce0113a41a3f7434f89f0ae74d42f657824c1321c8901dad104ffa890cb4c84476337863c289987ba6e8d7a1f2368c16b24d91ee924d97dc7f3ef46e2f38b9f9016f6e14ed8e88c58309fbc053320e366ad0ab2da19605319d4299ec53d761fefd609f0181be1f639a48580d1fa4e1f95aacd5a9d4a9a6864446fa8a6b28447b93c0c0830ee20b7e3da3cc853cd6fe49584321755be8c829d847170ab2e3fbbe537453465a3f9b936e14cd21ff1c8561e01000000000000000000000000f7cc88490d987817c46e88744fd75653c43b3cbd5f37e5079e9a55a1ad00d7dfa1dd8d57f97b0f54cea3e128aeef6cd3ccd711430f22387e6b51fe5a5886595e5e13e8b99bba7570076c725bea290ed0e7be011e32f23774a58544dc6a203f4600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a61389626b8b19e6d86bb099b6b802a856ba603efb29ae2e4c4b66e438c6151652e557eaa7c6cfda78fe7fd46e057483359c42c49b7cb67d95b233af26475e0d81ad87b99fe9114b4239818538af1d2a16afbbd3f2636ad28f8a9b4d91d8cd11d613ea5c54bf5f163fa0cfc7d6b7eea2527dbaa1c08ae4ae13d69ad5e80b6ebd0306b32940a32dd03043904b9ac0b3dc5d69a58e8ad06b73011f44ca5a4bc7c7040319cdd9a1a9b887c58313d3301f02b237057bf69f44531236823ea44df058c2390b01c01016464f8d9ae36dca21283bfd1a6a08bcae6ce25c9e730fb5a216a96cc827c4c903b3643ef0b63cce5b103e45cbeffc026249fdca06c735122bb38ad9ee03159c28b6976886e8778a2f18beb73b239ebf8bc824c1cb24e736336dabe4d162032fd9c3a772d8e35fc2f0db01ad6ef3d134e0f5f769e8bd9dee373e39b87423b40227fe865605512174220e258f82b7f3fd49853db26febf7af0ba82af7c013e3eb032944d4d1dfa91ac4fb6fb53ceab0ffc8d60d86819606bda45ed4e31542a305ad0319ce13cfffb48f88cf852e00fb0aea704ff6f3ad571072ae29fe7f45938bb91fe1f2d888e0d6363de53d840f5ac0e9d373bdfcfba91da9263f2ceaf66d556d071d4503c5131974cab98c30d8cbdd67466a59b8d4fb7fc2dab0ce5766ae1afaedd0dfaeb8c99ad97c3dda258959d707d160d77a7f201024c98112d8abf872c0c8ee59d926687527e22abf63ffbc20c9b0dfc3952e3edca83a4ea20644866217a716484eaa3e754c9df6d8e7331e7ee69d247ca4a877cd4dae857f35e52771a915d473b6e6a03c42e25e046939116012c92cd678e9081f112775dc231d0a9e9e597cb8727b337ea6d32af30448221d68c2ea2b8ea1fd2592ef28407203d32f4c20861a86efeba20b83a0550dfa667790fa8cbb2397930dfda79511d6e998c636002dc6940b22686fd4f209348ffbc57f1ee59d5d1a0f808ea4832749b3f350fd0a09f1e423e14a6f7a1d43e4c9273fdfb794a14f56bdcb963aa13777e31d8fabaa1f8e2d7c858b361cbe08a98320707e8674f68b5edec26b96339619c8d855aba9f7ee2d99440b42afdea5bdcbdab1dc75ffc8879e0195c7df07584524574be216d89d08faf4e75ff5e0225fd03d28ec2867742ab9bc4615a55aca0c6507958145850efb461cb7f90571c98b4f9ad954263cba88c5b71ca4f9390431ce617a2e5821742b8e53af0da27b7ffb5c47883ca6df44925a1f0a499486d06f13bd078074955fbb12e4076008ea9cdf78f8fce7245bc9f1e03f754f0fb9637e4a7ce3f4f7a07c5a8f2c985dba069d6dab5ecbf9d273f8bb52ae526a2208aa034aa35f10c779feaa46b4e507e25f1ca3c70b514d64d39edd5e8f215522ca1125f77cddefd2236715876c6a6959ab472afb8417262726384c03035953f296e500909502c08fc4c4d8f3dab94d55479d5888baa35a8c695fade4638d1f7e8b706d5bf5a83716c2afcfeaf2e3465741cfaf14c8113807cd7657c5287a30bdc7690cd229b6e9d980072e5f7272a8a73743b815b41b9de3d943b78deae8db5f0e0f53f16e643e7b2d09c6fcd4724ac2c41d85c2c9e7f3af8db9230e2dd6fe69766418a25cb49772d3348972b9fd19dd870c3b7714e991cdbf37ebd66d85d9407f8e448de158e63fab66da5a448ceb982e1d5475d8ece42fbbf819f2ceae5be343af398d58d3640da731eba0ebc05b4ee8b62c9cee41d800f3098123b5dac8438519cf4922e09f138511f3da560bc1751c62ebd21daea1b4b79ad651e4bdb96abbf84338b90784f6efbbd7410a22ebe5c2ee4367b35fef814fc7216c9506f6bd7d440c7580755a95af8931910d347005d5c407c03d9cad3b639a44c88c23ab996112f47ca605220e522f049aa6640065787aac6c537b6f6cf9e1e4d2d3ea7d926d08d5ffbb3ee75806fad33c949567535dbc0e741424e20aad8bf917201e3d57a638c596768f68693ce7c1978015673240efcad7fe49b9402a8ce06b71cff975fabfe4ae9ac84711fd4afb6d3f72cbf6425defb64ae47f5969f18857fa18798a18c8dec1b4b1005c771329df5369cc1807ef1f30d89fd8fb68f9f50f8c58b3a6637f2e1698f484c68d1e9a796417d69410e3ba7f88cdbae1900c37b4969e4ed62bf15a41408e447f67eb4f1e097843ea54ce73b36e727036179018883a8842bd6c8cf1e92fc86ae1dcfcd5fb8211c08b21d796486865f3ddb22d1c49a183587a3c7db2084b3d1319f8f2a6a6c83e1f0284c98f5a206897422640657a02acc4bbdc2f54b432f3aaddcdda6cb370954445df3c06ac2cb57c4c9c0fc9e4524e0084000acca4799bfbf20b910cde84830403cbe7fee84765aa015772f9fdd25fff03fed4bb4a1e58634c65becee01eb95c0c28625c54572602f81706", "515352520063", 0, 651253559, 1537743641, "8cf6439f29fd7546efe07bcb95b1d5450b93280efe8cba6d4ed90eb585d1f2d5"], + ["030000807082c403035b0ee7cbfa73b4a7221dc145d8d691b1b70c2b101f51706ec33259884b14659f030000000563ac520065a6102611af9401352b6a17c34e9259d53131b40c80d57824a566168edf487c0f8044a1e40200000000ffffffff34a106e8f24ad22ea45fbcea2109f377cc0022e983a9402d35c6466ea65cc14d01000000055353005153547871bb01f347f303000000000552635352539b699a3af22ca2c300", "6352", 2, -467320790, 0, "013d164ab23c56453f9b1dafa2e17dab82570b483f12cea8b6a338ac3f5f47c4"], + ["916d733701a0b971fabc2464c13fc261cb3b41c592b10f8e8292403133d1322ab33f05a28b0300000004ac53515230177917037f9e8b040000000003536aacb51a0e000000000005516a00005145abc8000000000006005352ac536a000000000100000000000000009607af0100000000fd84613ba7f705a5037368da6b04cf7f2fbb27aa0815ddbcdce883d99d90e24451b9d1767244abe36a6192154d1b7406c3de9617589d08abca78b9bb424aee06544f5e3fbd9c6b232f03a0950ae32af07bca66843973df261f40306cba13c8da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000157bf345583551f1b7002d4edb8b3075d756417b6e6ec9b1aab384fd92848a0a53ce2174dc0814a6894e679ba5b395c9d598aec0121141e57d22b28b6aa622abd346a22492766e0de13549938d7baf5522f5c7f1179efa103a41dfe9aa0ce42acca31a725973a363a06317042efdf2eea4c72d2127f7b2912e1d8f4e9738f230207e175e2fc18f1aae1b930c40867ffc3f8971ec87248968b554abe254c0c07fd032a07a7cb2750573df30388b230e9332d961d845fc5aa07b63671f5e6e42c705b0b03ad0819a901b0abdc40ec4583a23fdb631af17e2e41b8e91585eea3197711f738e7cc0ec6bc8d8ee9ce9c7c319e966899c949e58917158efc2505c755a75e4002293a535d0e490dfb1be3eab7ddde00b6e023940133bba22e114057606a1a92240319f25215ea58c972b17adca8e011b5d39d38aeca753bfd3ac9dbb80b8146272e0322a5e70b6d3c91a1161c1e251a7a3ef294a5ba97e44307247ebc72145684c113020a6085d7533b3422bae9c2c07357858b2d67d5415dcedbd4cd628cf60536d069033038e4fde7148e35f01f808d62867041fcc4bacb138e01cea69e58d82a1a1d193e753ac5ac236400ec23baefbd00ab5371c8abcd85902af93cb408e7037f734e7aa9ec86e7d90fd5c3aca11c8dae714d6cc7c6a9f6651800ebce0e949aa139b1bd140d68a4872994bece3e78584f3d4fab4a3b82f68e27c6fca3300da6dbe667c9d7c958b3c4bab6c875a422ea2a20f3a861f15b67624bbf1cfb63faa359a88c5ab123b7477ec99a5c282f78e250f23e1ee6f7b37d9d7b9cb78127b391965731ff6f957b7c9f4b4f2a561ce52a3f54c39663a2e4d633111bef22c5d5f38e605cf556a0534f96e2e677c1183691a851b0c9bee3b1a3acdec0802211da8989207969d1d44dceccf06afcb074afd35ffdb0ff32701619dd0c81097fa90c0884dfc9e6477cfe0110ff2afa2062ce4f65a2912febb454e2bf890550f58275cd78d6272db7fa75b7eaad49766137b2a0f95975567443c5b822fa71ebed76a9037049954438ad5ddda327af284ca619132f9401169c8b6186c171a37fabf395d48dfa819caa47e7262695fbad16d7b4d0040cca1b7c98c3ae4062f5bce132cc1915ad45ab7bdf41b0587692cebd8edaf43f2e0b2de8277df79f7bdebf10f87172831e723fff04847099060d7653a11045b7611c17fae613114807405263be77bc6466864cb21f7afedd1366266a7ca47bd7b6f00eaa956a08fa10772242ed061abc0551fad26c367fc0a0fa38a2a2a9efd4aa9b36dec6061879ffee3afcee3c0cf4da212e9919a7d9d610a5b72290b2d68951eaccb7db572d069d4bcd927080bc0587d685ac5342cd29791f4dd142a4846632c42983e91656a9cf6f78362642e614adc1ad479728321884a195f552336da52c870bc94117e0bc135cddd31d36cb34511c6dc7dbc76da09f285b793c91f0aca017a6b50d9f887c5a97db1ca246e0d3a8357f78f6bb6862090afbf16fdd3757a41c7915e00f76d7373975d10eaa0e32fddd433f0abfed3ad84d5cb444c6bc8c6097249e2432d9a8d3c733b5f8cedcf8c678b9d9b7611f302ea7f55adaf02426c56e78acc848171da483040df4223cbc77fa0f288f19c95178e667358c4ce46839d03a29cd92c4e7f4c8a000680abc32d73941d969cc6618ee26da5185a9d688d77517fe4d199bf93ce087f931bac65ae44d998efbd0b5259d392682ba39e71d86f036872098fff5a3704a4e173f9d3bb9c12acca6ff2ffe21f1eaf0a897502e03c5ad010e9cb0da9722ee15ef87e1c17b0dd833bbfe9fe60fe18c3790dbada2d11a8bc0c38ef1e9e18d1451f7373d99ec52a5379dbd9becd5dbd60c2d303f40a83d83dda01717157eb6707e6ec1fde8ef6624a388851ee8b708512b1ae4b6b3383547f4d1c9d094e37a263e69faa216e8dbd740fbe5197ddba1612bdd1b34dacdb6e660e57b8454e9f9c1210829ded00c2c9aa43e18be17733937a86e4f184014d23fb8640fb8623585f5d74b544da76c7dfc3bec9201eba10d8dcb68badc82256aa87be050bb97238522ef5592742937d99b4ca8f6392f5b9a02788c51c2366bf555858cf24e34334c4ce6f4c627c517a65f322e4b7f113731f7f723701f85ed5386d2d3499cb4b50afccd5aea2b4d9fd2b82d69cacdc85c4628bdafd0d93685df0bfac66ae9a001bc1bef1fecada2467f9c53783d650cfa74ee7a7b7b0c4b4f5f5492277590f1de97600bdeaf2f0896882378b5bd210da8a46b5f216a114a5b6ba3aa3575cd769fe5cd02ff39f3b5f17087680e2c759e84aa18f77f2bb27db59e172a3f8263da24fec234f8ba0d32405c43d61fbe3f8d8506c72b619fa8efe8e85f2aa3c9d0cd8290d2e7dd20574b725a6348c4758770257a611e2856a9cdbe0e350b", "ac5352ac6a6551516a", 0, -83645321, 0, "2a2fc2b80f49fb0eade3e5c65150a114d967c3b11f53d347120487a72d57b427"], + ["030000807082c403027afb1649e7da510190abc55b553819c561eb68178c4319aa66615f1922560daf0300000009ac52635265ac63006affffffff528c78ebaba1bcf26207a4098b200c62fc9207b20b8da1a5fa18075fb0bc14fa0200000003536565f4c3a7f1027258210500000000076551ac65536552543e8705000000000653ac006a510000000000deb4a361010000000000000000a6183d0000000000e7ab3e106e3598a892591db109a0f41c22b9dab5aa76df3ea75c59ab8feb36009b2e834d861295321b99e77af91a3d44edb62326685ba5ceea7f03176031fddbe9a7d978674472c29f14c9c4aa7a417712ad3788d78402a5aed657854081b707000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009451601f70c9e3601525014aa3ea7c8e6d18b165c1c383c16796baf0dd36c39ed100a878f3f1ee9ea5d780c38995c8b392eeb14916e8f2fdbd5868132bb793fd132239999932dd16af9729b14399f58619f2b52643095707ff73d8a2d1804a6d56a08a3aa7203ec876dcfcd284584873dd0e9e04a4cb936d482e5d3f4f821d2a03147a473bb064a0ed93121c083aec70bf2b36e3e9975996085c5b2a7332345e5102062c1d87769890a918c2b782f78b5ee6849f9ea3806cae8a8f8b677c8787f3510b044e5bda129fab05abd1da5ea92515034171af20a5cb9f41e14affbf87f7cee52c036fcc9e234e40dc86b46afd88c46a5057a4f81f74d101fa880b24ae806265020f9d07ae18feb60dea33486b873507fc90f30f11d53ef381915d3eaf0f71afd2031b25a00daa7132d33ab74ccae753c8b2999fa1d55539ed471be405f32b041909021238063a391d5d592f292612b1398bbe54acf4fd1e5ea9bbecd9327a06cbf4700303ee627fe709f5dfb387e7271631d03d7ade614cc4b78a21a8a74e4cffcaf8750309f019dd2aa4d7819faf6db8e1eb42b698fa2c8b9b902274d82dcbbc5a21e5f5952debcdbe24ac027ac8aad93eb52b99ceabf7d7178118eb018be0bb3c638bec89ebc7ee739d29c599da0257ec196af4f4f70b3f800d4b1f80f384694d6a5eb6fcc7fbd4ac6d7a14360ce63c1890667eca613fce3e16c12935ea61fb66418bb994b1c9fbec50278ef19281efaa02802dd07e335e24c9ea6dbfca7bcb7dcc6b8ec524274de779691df33a51607db2175616e762fae79ee2672b64e3e084f6f3df3b7928f410125366c6e2a4527f9f7df5e38fab1f76897a3f23d961e110b0ca3ae91266af9f34028c01ce1a1a18623df195c7f3aa95ca08812ec906f459b3ca3a2569d56830ee380d52f4caad1b05e18f79b20727ddce2bd6057a961f57b1414ac6085ec02f6b66809628afa8b2b82075299d3c12db2494cc3dd6aa84cd63ba6e654da0e27ab7a35f32d59a2da0247cf011a19fe44101c79829567bbb31faf0a702a7e487f177d3186ffc265fbe9d067ceb44b311928d4afc66dc83a08d20e9e2f29f87b976fc42d092a6f6552103ffb11d6abd64f54f3781bf6b8b5e6916d9f98fd4e816c82ee9f92766350e05ce631c3727d1f68853a704443d724b2a279650ab7a400911ab8ad418652dbaf0e3fd857283b6531e99b3242fe7459982067eee484dde4891882e4ee0a680833ce8af9c287dae3026c2567fe549dd7832324aab3a9ce61ab089bc0f2c91f6cd894c708714916470d593c54de6d5476293c681cbeb21ee7b4e9241bf2161fb342f15d3f106ae0cb2917eb13275c6d5e583f8eb893130bdff3d756c733c0157bb558800adda7f2bb504871ec099e9c365788a4e6026d7b06ebc41ae989752aea68d3dffaac8eb7a32096e4ae38e528f6e3b152b26f04fa3ffc5b58ef17f78bc687e863fa15361a2e4e71420a1aa2509629fc81e178ef13417d774ce99d79a5d8bced1ef02005fc66c3f58883ddedda04743e78c28b6c3f4d49f51c3bbc8fa2137db5ace5b60903e1913b8e0ae2344983ec051dd1e2c2f57862844956246472044f09c921917ef6c3ce7442298b8dd36c736687dee6592c80148441f724bf83ba40989fa00bfd0633647a592cb8ad5a754d01a32337933ad2c7ca8fb4e468f8991c633ef1fab32e4abea798261d5cc6caff382b172ff041e7b382ec02490e438dfc279b3c8df6fd4792f383eb4aea32c5c8155e410c39885a18eb1e7da6a8de83aac21b7868c85efdf867def47980eaf17a2d2cdb6a6cd9d38ef89f87a9f4f347de41399b1a949fbb91970be9c211a294ce838ec8793ad477046ba8b809a69a8b77967692a44a9dd47093a2efeddcf5709129d3ce587a1d9ab9d5edb0d369154285b7eebf2ec04835e0ca3dd9fceba05781bb0c79a990bc83903e921f68d5ce250df955b54af70a58c9fb0365fa5dbf70bf8cf2fa0c9ef70363c7d4c8852af63fdb03ee1598e259fc40a814dec22fe24ceb46577b2f820f7df9552e63704f04ca512f374494ab4e983dbd7fc4e70ff2c679c2722fffbcb23f7333c632a1469d2ef379e9b38ffebbf8cf7d0490dc2ce02a8fd681735755240adf81c83c3c914b3b6c1fecc59040d6e0dc30e72767170cd9cefd3223afb1db21973d578bb4440984f53b283c9ce4cb5f9d58c0153f6410b736a321211da6e3bb112b4ffac1a5c6370c78d0617958497045a6f8cbbf4151ed5004caa93701b6d611d26e4eda82c39e9412d4ee8c2168fd18bac43bde409d084b54d822414cfffb4adf11e068643224688c3a5c93a5c42cf5ebc6ff8e967cc71c7d4f1b1f28390ee8312c24aad3b71109fcba1ff71a98a90bd4a3fdad938df7b2097ee867a31e46729c353868899275a3fb060258e00", "", 1, -2141711051, 0, "44e5013d0bf41a1f872777c78dbfcd51881b656996b148b4f6d704d7c08e3f02"], + ["c019f33004ee8b83bfb96870c2112f6a9633167abac3c3c930f6153a9e7d2605a43cc354050200000009536a536363535265536156f27ff2180ad35d9f3ba768224e60b6238e059791bceac6dae6e26e9ff946ea3cbbab030000000152ffffffffe5d6f63639e95b77d815c832e142a9fa40241df42c5397b43a7905483fc951d303000000025152ffffffff942ec8070e30e12cb114755cac080bba441e34e4c09e1f1d1857381cc35071e703000000009f30af6e041edc6f05000000000765536a65005151f8cd380000000000008fcc4d05000000000800006352635363ac6c547e040000000004acac52529365920703982dbd00000000000000000000000000c56d4ccbd64d4f43e16a6399fa81bd54d4f39b3b3e3c4711094b61ed7d393684b5dd80df4333faa87b65d4c9a545c90c44e2b9e2ae7943b409cafd1aa09c2481d4a1324083444d6929847d897044e8164ea4f243da07d66a866d8e7df15d68420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c2c3f333d4fa407a78906cc9fc8860a3c7734200c78521a9f05c7ea1ee083a9f68e759f2a7c865fec0c87204ea1505a6d4b266c1b626d73ead1cf77823fa1dd030a25087807f74649e4535ea896e97106e608929562af0178c87bb9cfa1168f305f1bfd483de808a9ad99c406dd4d4f7480cd061a85a511017a587a852b7270320230720744d86f6a04b10db011da288f6697ed46f81704fcde6ce0a3d0f5c3202216e0efb5880c740afe4f7a10d4f661793a3639f0921f35a5461c4a0b93bf23a0b00f0f218f0ee9094f348f55ee9d674be88888076671386d516bdc47edda234d9726700649600d7a4120da86e09cee022aaa9803e23423426df00b7913b87eaee020679ca2c8dade15d18089461c51c5dcb1042b4f71087d93ad037dfb6f1ea7e030216864a1328fd2c159edfe27cdaf03ed98d5a97111232e7dcfcd2dabcdf58f8fa02146e86abd3d18362a7d7e37f29757769a55f68a34fff7f15d7aa2da30a7c57c00229ff0e24b87261c4e495d95661450933c4494621deeb9595a6645f50152adc08022cda1645c327f9407567709b9b047ba9dbc0289552692ef57c500825ab0ba09d1b1200ad27d14ee8801387267ccc8501a2b657c301e2c982a6f0e53a20a94c66095cd5496a9b35a6677ebb054bf357fc91c6001e19d5c88652b9cea7d6cce557ca90d55e4d05871f3ad4061e1b8378791397fe428c67de2f4b1075bf55c08e3b3fd674f185779481b48e60bbe6947e2e017be0b126c98f232580d7640f1b0e1980be533dc17442217a602f86207c3a036f99cd7433d18fbca3df0036d9faa02ed80246d1e7e51ba1bf5909b160d08badd2a0a5eec96505c451923f16b4d74e898b757cec36f7b20cff068898f529cf3db828021a5094c0da387d953a74e2ebed784c902c1d3a91fa1c88adba72abccd0f8aea5c22be0ecef2dc30057bed34024765c229a1ecef49601d1101f859d92516ca1e4e634bf41a57cf8043a449318aaf59611458123e06abad14ce077a2bafd3bd54128f3fc13cfd6001c04be0ea371f0825e4805de4cef93a3328e10132f9901c388864ee52c59a53920cc51b105ba953eac77e6f4b73b3e106df5a53e36197e87777a848bdd2b49b70519d4cd79ffbba1c7c1e4c37ab79fb4edf108e2b7f7ec05243aabad3597239bc3c02246b43ed718ca3e44105a87903a0a7ed9885161e854f0da68af34d0eadcf5de126d16fd25dbe1c8b6fb4b6b233b315523753fd0d71f376c61a004c764217e2fcac1cc74c46e17840e854c507fec728e8747898434d3f9fc69084187a5d88606fb495afa817297498f5849f0185669a24095b7cfc11e2134c4928d4c0023f5111773a5f33261fbd43dfe865f784727822906ebaa8dc962b8d9d82cfcffb3812c9dcdfdbe47087ee31483fd005226f799bd0c4a57374dd17db5524417b27df671bb6c01cbe41516e4a3caa21fb892f64b334cf9c0467f60c7dd78527b7137ea8dfcd9024275683bb3c38fef90856eb8414322ff135a04bcf5491417de490c7a44872a696753819eac045b0e68d9dd780049afed4eb95d4e5705ad8f2918889c1f88a179e05c0921b2dfd52655fa34758d0d1b939616ca7233660409f5958fdbc18e2b97c424d88837f70adb40a2ad018294301d5f26b650bdc6a0dc9904c7d852acf1fbf8a4b5e23ffc155cec9255c1261e2fe66166828dea8f955c4d4970834ef63569bfb7c451dfede501a66af2dde4ab88c8fc9b7503df1f9aba3a492c7742ef37f74d705b7af2ac9478706f9a448084bcdab5217f58db3a16e191084b1e7741ea775820bb6d110c10380dbf738bd875c6290fd42e776c5237819f333eff90cfeb799da7705515bb792ce3a862a0408e1ba86f95bc120c39bfd41d6a63d579680980ebeb046a831ecfa25c9f4cccd6f76fc4c1450c04e655fa9524fff29a60b50b5a483c97b11dace933df6ad040b77a43514abf35e1c5de0d60bf61cbed115dca2e0213d58927f6bd2fc0c0c1752d158744b54a351f9da327fdef239c23a21f471218e6c432014d4f234221869cb2efe834a9fde2fb87d3c015863bb08e69d1858d3f8fcff69026b492c5076837d81decbe08e37044e988f9bc083268c59b261c42ec338ec54949a46ef8df97c975122194c4af620c147b84e525da8f7672c103f719b868d303b468dd9712f9e0228575beea97417eacc47771537d32bd7fff91ed0c1f78f698b3915e540c381dd113e4f1ee00ab88b87fc4216da339706dd63fd12b13c8771018300959e3cc3be7c564873c16740000000000000000bfe4c205000000006c5969ba6b0b90eee463cf247c29dc25d7ea476d2313a9518d6461bcaad4f24620713dbb1965fab753fdea279237733a947015cb2f88fdd17f835f4f0d2170f5539620f4372511413f88311753c86d3925ce96aef166e5407b8a04d80c8cd58900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000462f754f74832955e16b57bba7cfd84d89c1e9e988aa0fc9714713df58bb82b03cb6f3fb90180c8d4bb7388603de19a928bd6784c5a1c0728915fde821d73244974796bcecca5c860e51d982e082c5fb9e0d0e3b23b497040649bbac0fdd75e87ae07ef32c9f196b4182ef02ad8cad2f4cd9385dd0a6200478b35c89ba7012ff03184d9ced2a9643805d3e4dd8d2437975c67758490ed64b0e5c09c6691606db34020ac42a10abc2bc32d3e9b858f1d07c421c4a67d191f8813e3b7309a1343771f10a03efdf1dd37f9a2f59b36a73e5a41b00a1896a643983d14c587c4169e9cd4effdcc5831e41cf145c9a1d33a4b67e8e8b3d0632234482d5bbbffdd78678e4e771030a6ce42d5f9c1771b5213c8ee0cce59905f5b9f7ee290d8733ceabbb7d2aaeb00217aea5ce9b76fb324a30448357dd1fb2dc79bff8b1a0cda9af1d6ea96d1656400302af6552652a582b2bf1082c3521e2cbbb401ebd82359896e80e753387a605ae021f7510a81137f492b69f6da3371c5a67ce468f4f47c5b16861f4e04c4f6ec950032a95578ab7eb582187dbe142f7b522a6f5a4dba52a3591bd2d998a8e065ff8bf5cd530f6063f58c968bf5e58153d9659c896b93b054f0d59c6d16d90e46be7579a5751433fcd8da9411edf6d819f780627c8d504a273abf15651671a9ec1358070222fb11a86fdd709f51db59c29c991bafae8beca17e779d9240033e8c7e90652ad4be255d697d4236d1f9a3b32a640d7b024e2303d62e4583eb4beb996d9b8a39c01f1448821f8bbdda8b27dd8ea3cb6bfc0968defc1f7857d888e09057c92ac7fa93361e7d2cf8c0cae4f560a0e30be87574d12d912ae0385f1dcc6f0376f6dd7b0c88c19429b4dccee467ad79119bc1ed66980748fa50c3b7d92ca022e99c9a36e95c8ddd5d837c08a2f668a1822469ccdadc9c477f790b7b5cd950effa54db3156289494805f3dad6572cfd0dcc258ab02381be72c9e3802f331956c762cafd364314e8894f5e211a698dd25ffb44ee5f2c84a9f41d735ba05a6fad7c2dd5d3fc1f131cf1f7e29a3f7bf435e0200b3152545d7b8e0708c166c171391fe6b3c411a1cd0981c2883535abcb09d811bc2f842d6dccc9861051bad30c061922593aab1571c39e160faa2203089f97d43614ea572008a3bb2c560198f3c4a0bdc970922ec367b6ebbb84c8ec880090c2bb8cfe0edf898a240e40a6a6b3782c17ef0d01b5d563e01474e6168d216e9d66c2cd52a4d5b952045332010079f43b0c2327617a297408ac96247f5cdb0068e85e8b62963dd76f9fe92c747c2b565acd0a1cfeb31554dec2e30e96df947ad4bfa7e6baede6bac0d568d7df1c2c506d8d6f9737f81a2a2d6725f7375df9c25f698f9a71b18553546aeb0898d74b9077ed5d295e5217a95171c49ff787e423e6708694e01a650aa3f2b895542fcd09056128b309335b50925af6cca46be40a48f92947a26bf97b2264d7e06cb8e5b48d97985520690717d736c1c9257c1ca59a247612ff035d209de74814128e16f9078e50f1bf4c5230e66a61da9a832b64b6d3213367a8bee2b443c4bf30cd939fb3938c86886b09faa1a0fe67d7743c269b4a7715b82cdd39274813395cd0cb7f691b93cb404deb3d2c3cbd306ebc8cfbeb4284f3003f925efbde8601012bbf3f08c11378c2c45b46eb019b5a854f14849959ec39f087e619b84f4d2696f72e605090eba47be4ee5c9e21655048aeb099e36933bdf95f4c71d4d726bd5ea187e782bf3fdd261a30fcb11e77dcccd2ee29900b9e8018b29ef79763b1509f3011d04e87969860d550f65230aec326d776e500d764795284b5e371d627884c7ad26d9ad997b8f9dfa7c23dcdb3ce386ad290e4ded7ee5f415a9df016fdb598432722f84aee9054e31784d143e363ef9d2b55c1cd6daff78104e08ecf6d908395013266bf6cfecb233cfec05b0f109e6005d1ed7d7154f001533d3c4f3255b0547a6651787ab4e0b8b8009aec3869bafd86c231dfc7d14d5cc4b8e5aa1a4377d2fc74dc670b30735bc9fffa98d595ea49754c36b59a6e2756d8f858f3f85e8087c69f91820716db4a68ff8f2f2b7e23b1dac4ff68eff76199e938316b5db0b919f03d56b1177560fafdd3e8a553177b8defb82eeb0af3744d8299d0dc841aa05ca2253a1bc95b2d715eae88fa67cea04c586235b525a589450cd8b4aa26e4e45020dec46d47473fe2545a9dab0e3407d96414ab6a978acf399517561b7772b0ee5713d7b5f9a06b4e93efd8b331243099c079488519949d2f16050000000000000000000000003669cc45d60e1488ae94b2bc59eacfa1c8c7536e173420ea06b16e0222c8d1a888258a19445cdef3a9ad073e79525f653a98a049334f500c0edc09d71fdff64e069bc9cdbf5b4438d99975bb001a72f9a0463f8d714ab671f163af3554a73ac800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e16ba8fc883ce38d91d995dc0121d5aee910ebd577a6246ce6986820591b235a6c47fac0d652ff5c45ec03eb46078778a1cec82b712b4d305b1fe4a7b3cddac092d0debbb40d6ba901cc11fb55e16520b864af64c97d70dca988593d496fd0c47019e51d0b4438f448663ecb9bafe29ed0e9ca9d7d6135e9dba7402761b34cb10223ddc6a2f3371795db914d9340096f8f415b69887435959595afd038c44c37810302ba3556b2632a90e0bda8a3924c8a856acbbf64bae2a130a2e7449c59b14e6c0a05e57cff272427a097edb50d34ceab55f30af008db96435e62a4cc45b877200038212e694480a53e632cf01c78bbb750d19825bc2df308313f0d6a74659632e7030c521956effaccddfeda6c01e57e76381cfb9d91513d40e97d66353d884cb14a02092a7962d0564e7c561e4b706c04e7b0f606b0ee9f04ef4fd3ef67ceea33f2f0032497a7d90c18f36f8ccd623b913b0cef0077165af7a9608ee34b07a9532ece55022f880017d72111016b03e1cecb2c942064c7686b944cb669d9ae0da40c76a8e4022ba78b8b948a1cc51ebbf9021941c5ab27d6c113dc72b435ebeb3216cff4ffd73492ac7de7563c124282668cb264b1954574191adbab3b6f19a266dd64525d3a91da9994c699c1c05f16bf6ca68ebcdbd8cd53972f50b265299d5e693a9fea46dfd83c3772ffb63309629550d06958ee1bf61ffd29b738ebba58a0f561f90e669854615196484e870e6f67ce625bb26f29233b7ea23054963d31142ff11aab3bf7a5950aeb002b8c9b878b86f7b5f14916c5d5d43238683dcc8c44bf29570b3ba33e72d8bda66072796424a676f9125bd1c17f7585a627448aecdf4f78124f1b979b18a6ac29dc1dd876b10541005dc69fa46cf7f90c88e27b6a93111f0ef2234855c5602b28f5ac3c95d9863c8103648fdb78f718ac555b26bf5fd725ec8bf6e73881a0969c1e2a3854efdb99bf8095c85b5974f602b7048b4864658672e54577d4702691be3ed049e459c288f33abe27a9616e91ef2c79aa21338e240cc8653a76feeadf6ea1ebd6fbbd696b40105c7771b605aa78cfa66f1fe265133fdeb9e130544db586ba2e9ef21e43cecb962eb1eb6a24da7288cf1486407350dd7e43abb0d97eef5c5f7aae9e493e482be759dbe006ad8a2c8a75cd744a8da97b54818a0c926b658dc9fd20f0df2a91bc1c533b4acca3aaa0f280709d6530c67ae56630b9ee152e3b22886cf6ddb16ee72e7b1a0a3ff52bcdd9fcf3c85eeb93f02a59f80089c6c503679712ee673382ef37e62aafac57fa149f8748190fce722e3226477f4c5d8cbb6a23d23116b1cc5f58fe4eb78f3a5b3d2dd59516f3b112305ceedbfa80bbfab69dfb386d0a2ef9e03d9386effb08c75f2af3a33336bed4cb262b24ea56eb3970e940847d62ff1422d212ace06c41feaf9d1e9db73bea1af5c622af8028232b30dd15e75394e8ce03fef321c1f1e99b276ee42f1b2731d21aeeae1877afa1c7b407943ba2f6df243d14b211ae383e87b661ea4f630198609c5aff51953ec423547e380c8db22653659c63761402074018754001dc04623abf2a72edaa87589e1fcb41e8007e4caab89939aaa405845dc4117aa37b6d4a3f895dfc8bf91ccc4fdddaf1bcb3b0f6b3a94484ce02b755b933f0cf78df5d968395c577bbdc52becf86a21a8d45475e84f8caef9769427b5e730014af072ab430953d4097bcf0f29c7d91cf76aa37490c2033618c32ab7f4e33c238f2837f9d1672e9f68a14a86cfd8ac4f0bd32e4052b43db416f15f84234d6118f342e64d61fee54fdc479c0c06f86097b03ea62ae1eb65091c963d1b8350ec033f6682265469684b07ef1fa1af084e90848f3bc305169480d036c8a7cf2a8e5ce88f850a692e4cff300f845565ab3e3f8d86022c954b08cd2f5a7da9c898009e4a788f90eb86376a2fffab6ff714d6fe3556883555b8657b51d9a5e89864ed6790e53d86caf873effe60a573f517b1555472c031acaec6fa3e3d733736cc0d1ac69fea5464a33a52373f61a5020cc5804ed9ef0e85c21798dfc7f02f10e9b06894367fe33f7d21f83488fa851a0ae06710b6ed4b8055db1ac9e8aa15671dc956a3f83703d46e012ffa8977cbe35169429c04cc5a8f0d460dc273bec4e8084f289a37ac1a4e34e5dbff7f2fa36d809b89285a350d0bb18c459d4b1fd0c6d823aeac33dbdda057b54a41ce778fa8c368d1bd1a1c74c7222eb3fef16109e55ddca482b9e1734c2c9c25fd7e100adfee0cb74450489365e051e47887126754947e3c8b779cc95984e3c63c1810fd1d2c0f3feb29d78cd18a914000126a054260e03918c9e5a8a21c35ea7eb0247a466074173e5948593b65e45f025c14180f895c2f677e3643bf653dc225edbfc0cbfb4c858f8eb0e520ad4e7ec0f0d", "ac52acac6aac525200", 2, -718278866, 1537743641, "619c12ba2914099cc228aa7c5db51b91f81e114147a7666e36ab75c82f307085"], + ["a1b9a05f03e4ce71b428782acab93adc4c751cc1d3c85cb6d731b116e511fb449256af13d203000000056a6352006afffffffffe2f9f0d3505f6275c34b994fd418188b7350c718d1c87a606ec87b06be3aac803000000055365635165ffffffff2038bc3713c89dbeef6953902407d03ba6e3ad3821e293d054ec98834a85ddf8030000000070a0aff602de1b330400000000016599f6470300000000026551e97563e500", "ac636a65536a6565", 0, 1121641278, 1537743641, "4c25f637e1a128bd010c07c0fbb40420d12f606d3e7e891273efc83f7c47d985"], + ["2d63410304a3ece37d4f56152487b2963404e2091be0bfd9c7ea7d4c792a620b622d6c621701000000086300515153526351ffffffff8d1c7ee59ff25d19e7f51588bd80459024e120c0afc22593d5b137e45322663b010000000400515300ffffffff84e2c25ab25724221121b88cc967e31c8957a6f65a888c78a592c0c46c32aff103000000056353ac5353ffffffffe3b523f811dec65ce76e767de6c00fb469ad5b16c13a166a3ca3b1617142d6910200000000ffffffff016fd7070100000000090065acac006a0052acbd1b679800", "53656a5200", 3, 1908452564, 1537743641, "d015de78c2f562b7f39ef2f1915a58534c8a17e430d146cda06d7054c0d06f4a"], + ["b8a9224b04ba938e83147c2273d9e92d88d52119d3bb367b15f7d2419a1a7cd9a1074b874b00000000096a525151006365526abf5b5bbd485953e47085ca5e513557dc0755b57759dab5418dce31f875f9426a8fd6ae7a020000000352ac51d6058cb9474aa6697bf3710d612477d0e871a3bfb2ec8bf3c378a75c7cd096782a6c131a0100000000325aa67f2b73e381a91daa44341b5f4999c1105d3dd3b43e7846df317075bf4f7ea495510200000003ac656a65bea7c204cf876804000000000252acbc21f20300000000075252636a636365576ae3000000000005525165ac63baa2a803000000000163000000000200000000000000002d0bd90500000000e27d6a9f76900a5b737ebd949225e27d2d0487b87a86e1adaf2e7356bcf29537896b7082d4ee63c1322208f970e89db6149cd85f4431a0b1e6d87c8dc0e427c80e45f8b3c1e6ea30b53f310857018a2f54dd322728c9138d8f8d90e10fda9b430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032c3ebdd9adc2299ae005fcc6c630f04ae6934b25f5f0a0be27c6d1cfa06f52de5017989e52761da5f1b70168490bee094f517a38223d8e0a2c7c26782614f54217ab16b99cd1e71b7b75ea9bccf054c0a734d3c9b45be42028f4b3b40926c78ab6a1b968b473b97320fcb927bb2a7427937e4d80115f8bfa87b96238d51131b0324addab649dcb401c1439ad03b2d97a1de0c94f8ece3712d42af26f44a05415c030e2e703b55a76be6e6647ed7883d4f91fcb9c0a9a7d5fffea95baea5751654c60b0146c8d2c4a6364302bfd6de263d49a14263bb0ff3ba38555b7b00b22832a7b2cfaf3921d12dfced2f8fbee123f9524dd355e5798f55b47ed00bfecef400443f0321dfe89460737d72d25f7d0a2cf6f7ecca78c06a0f4a67341c324a850012fdab0303e060cde9178ab87fca883a8f30d752f37f1e3706cc82390e11394de9ba4116031c47d0afc2c6e267ed16a7401bbc90785ad171bca62b693f2b15b4ab4010e9d403206ca6e59483be5c0e89a61a7addf549aeca7d887d7e650d95ffa89724fbdb0c0201d482e1d8380dc32cac78e489c2976fb6f2bc7b9370fa77caa40e0bc5d7376a07c6717fae391060962910a6cbfe7d1078c1b3db287615d74aecb4b226812637f42bd12d8dd24f2eae939f1078a564933cff6b11b85f65d672534b3e853629204c64a9310de680f0e3031e9903a162c9b2a23e686421566a33320f590104a1a7d4e482262d2d69039d6e0700eee95afb2463f135101c9670b86f815aa16dfd88ff2f389c3d57d42f3f827b29f6eb12327ed157b1a077cddbd7a4e95f150a41c3deaf6eaceefd769db2083d564a5c9418c7ad00c3cead8418454281de8c9b842944a6f18eb3cd9c3d6e54a24ff3a6ca75589d2c6b03664607e37f7220ebcfed860af6807bbe73d3c824cfecb09054f126c942a92b22d886b7dbc687add53f5d33d8ce98be65cda86cfcd8b706001fb35ee3cc07289a2e8561eb89bd4dac355ee95cea0a86bcaca9259180b9cd0f25ae1dd26c76a0eccaa5ad1971d56de758141e0ccbcee00148826e218eb54563824ee063000e23af07d6da45181c3348ae9ef535e8ef9915bc6258b3d56596c265a7e67b72b66f0ed30f0e90e6d873f1f566b7c9849cf3d38d709cd332960ccf33c3fa51eda315004844097e93856d01926664dbb98c0638bbc915dabac0f589341897998c9eeb09997576592c170a5ef671a77331bb1c53ca2d83480b27ae13793f564f4bd2be7dff0aa4fd6af4b5182f11afd092b225424d3c573c9f6cec48e8bfa64f4391ea3585f837a3474ac1b0dcffb69567e565a995f9914865da8f4419420ff92abdc6dcf2ba60dd3b6477d6a735e12d42abe979a437e6903b7c158286e070a8677a423a8089c37d6a186b1916c56f02b03390c474ba3d481828c121042dac38aba4c7480d5da8c3c87d2876e196623ebfea3262c452f964a3be50d67d324c567e62fa6d8b5ea66e807835a5b2199f76a9ced70cc96d34f5f513db56a517d610701891f896f46b867fde41e29d3a7c87557416648614ef948625323af375677f8a819d6326a418752b666ca2bf50fdd91e8b49df33dc56665b2576d4d5f955c9e6159680c1d7b2f4bca1bdf7ca78d8a10ff8fc7d5fd51705ed5187a052f96b841dd466720e3b5adfcc5dcb74f6a38f5495df125a13e2598d926298c5062ec69086d0848a19701a54bfdf46970e8b1ee6af4665d80936fece7f6d63ab0373910fc573fb34b609653d6aa66f10b879ce549d5dba9c442817139ab5085dc290532fc689002823445d352a903fa75b13d5cd70fd2739c42c784d9f21c802c71119a867f5487ae0729ce60f9ada1aa52fa12baa13dcd13a364f8b729a47b56ad06ffae86594232a52edb6e608c9496bb83d9801fc87a51410326e4f703b1acc34f1a6f004a347787cc1f3d663dabd682612e0139bf28beb0bcdb4ef10c02be935a3cdf88e3b333b2293bb8c49227b3834a918cc20fa4ba59ce9339753dd70b228e34e296b89157b465e6b4561cb584ef66d0365f7a61c2873bd5a487144a03eb63c0c406806a2dba8921d159f8623055aabdefea6ba87aab5a3d67255f259ba1d54c3ed65841013882b4e9cc991e333d0dc55d731890f02a3052fdc0efea4d16d26d2e5770e18d7b06f3b8395cdd4befa529ac0febbb2bcc29189a327a4249610f40aec9bcef235f849a22b10831c8a76fcb34e6077273aac90e84e2399d0fb56aeea9604eaf60d49c8bdf2f03b32af3d05a80842c1ced561c32387ce7d49e0a160ec59718fd0000000000000000000000000001c9fb9d0ca9ccbbca0a1a99b5e04765dd27c34a70693cc01b15118e22eccadc5358c2ad868b492ecd552431144079cbd595d7a8454c1428409d1e525ae19345c5267ed07c7db3491fb9266433165040faa6eee7243dfce796e495d05a825f651000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a77b67a15cf7f3262feb78d64487d79c6c99f1e5aef71a55ff0d864380f7589fb1694335e82d799a4ea1bb5c2049a3103d1183fbb38b1fac6ba365027a348a447887d8d4d64d6a3a67e31b5df6bf874b03bf251f8a3d24c325778e321fc56cade71dd3da6458e9da2206fb3dc981c6b478c174ed53c89522211d7fa86dbeb31022e956cc225acd85b38faad131050f8d8cc5cdfb54c913ccf2c99379ff33d46e9020c1ba6bd9ce747a15792051ca67b15356cba85e2e15d97768bde60879ef2fcad0b07d3e3538f958dd0d0135ddaf050a813c10ddf1b55f499eb30a793abba4b83e4ef8f8cba43c06ff0cc11581fe83eedf85d63c106bf21774c27a245d5a03a3f0603023731169142d26a22332b18e4533b64681591eea325f64b143e1aa184b4fd0103095b6f51704badce16706169b2cca1fd6caaa99b588bc57b1ac4df3750d4ea9c031ddece06dd33c45d8a749c587c314de8cde625afa1d8b5f04fc6bc7cf69cadba020b9ab24a5a6a422300764d5dcf553f276a507964b5c3a918c2dcf9596da3fff9022fee396e5441d9b13ef358d1fd635d5c371790de69dbc62e6a0c96fef54c8853b58f8617a08adb4db31ff2dbbc37f6fabea7c7b8aa403c8b74491b62e1abe5224faccb8fddd410424f823972b56cdc658869985d58045a0e17c36df516e8fc27250f5bb0f73af5db41d57d6051d25a3b774728be9fb1733a49bcd598209614fca62ba988e9c39e8ea8632e17e4a2a895a4b2f6e0002739e347cf0c9abf4d83c51e363fcf883b0377724039082fef2bb0b163f7b1b97430f3e97f7a96fdcc7b579cd5cf5a2b8bc68324449aff8c11ad766785f20bc55f6c0601e9db8af9b42b3010b226eb0607d1687f78541c906708166e27b507225ebd0ce8ef138fe18391e81b7909518f9cfc01636869102156d0172b7a9db08cf098463bcc704d3dc285b67b7b4cc4b0311d3559dfeab204ee57eff422d55930a512415eb15d2960ee02b2af18d5a715c901c2bae3c67bdd2e4939ceca1829108b79b812dbb7214af25575bcfdd59932c69d5cf70c7a1f7182e75ffc9fc98cbf5001d88c4f2aa6905fa28695e7aac4256c386eed1b1320d1246a7c625977d9d84c5b3d33f4b39f6992745e6fb79d3f602b31534cde23f6b22b3d581ae167426ed168836739bab83170f1d7519ead888ad83c9de19d35234cd87a440a993d6797603670c2b8a3ba652de7b97e2b36f57ab59395d92364fbb927d14f9732fdc90d616fdd7f1a876b7c8e85941f0108d499469cae6f2d4430c76f648942c12303c7efe77e9e8a991a2f2c9b455e5f063a149c40bbc9757cc75914b25a9358533548b5338c0eeda6069d5d614e62e86f2e4f4d2d760191aefd59d27eec55204075953b1d33d2b231dc77cc1ae9bebb6db846e3654b2fa81f8120a51f8e8805f7fb502ae25112ba02a1c3a439e2fd4fc2c1a1ac4b516bab18592f1c166cf00c68164c09cb611779285829124216bb418150e61d1acc08e72558e9adca899a00ebf7af01e160f50d431261f25d099ee88068dfc5d6feca3a8ccc0cceec4e28f69943ecd359eb46c1623a688f8e2756c4e59827033f2889d698d923ce23a92768274b5228ea640ee6f4e1fd6329b648af3c7030911bce9a0aa8fec59b6c98a2adb6037b7a755a6ff07e9a24b61178985dcce71122b798900e59cdedbc186faa205ebd4f5b7f379ce63a6d9780e9648731df0bfb2e8d43b7549531506a047deb649a90370b88c0f0c1abb4cc0cf861c85faad10983646520cbbfa15015e1f98eaf6a5891d93d268cceb51ab4e510a241c4fd9efcd016d5f03e2555ebb4dba179b033ef41583b8c4b89a5aa8dd6762034963f87d5070ac3fb0524aa087770b81ad4c816c7410c80d3185c1660a63282876ea6fb0168d3a70037bf61a4375470a879707bd49745b9b3102547e07d859fbe225ce7a8b6e8b76a31b136a9c4c9fb343f09abd430eab05cc5f789af5c93baf39a05ea6e5e26edf69c4293cbeb536d2d020c2c2e073ccaec849d2000228097d2431b9a787519dffe7509c6db23bd42bb77c25900aea430fb5cc91465bde14ba60fbc6cf3905cfcc270b8fb9b35775987894a7475c0701848287ff46fccc984fe68d29a8620f14b8753bb4323bb97bc3b5d9cc127ccf732e71df2452de3f92584c7ef00859fbe4ce0f08d3c0d14450afc6dc08e24d02453ddb738b8c2bbe76a36de895ed1520f67a8491b37978df0f8547fd725acd156e75df43608fb6295a2d4f12edd7b8451ef9cad908d94e4aac020d11bbbbf694631a920cc8ccc6b890f1afb6be453f93fa63e3ee1b415a131da263a8c66ba94da3c97d7ff1b787cd9baf3cebc7a32e11c2d080c70e51b6814738a72f7a06276e093899972bd6e588734642a29e9cf4c2f9fb4922d8a69bbab77a10b", "53516a5363", 0, -2079140540, 0, "03d7b925122aae2f32118ecf94da64dbe3d3b6bdc11094fab790c2c1f529df73"], + ["030000807082c40304113367e7682e7c3cbf20edfbe1f137827fdb7072f7bdda6ebbcd0a78d78723e2010000000463526a001223d576d163ed81a13bbb620cb64bc85eeb3a349c911a1140c38fa86418267c94a41ef102000000066563536563635312e0d925e2b3b6b882fabfd38e6fa4474b4ee196b05424588770653f332dcbb14a7f940100000005515252656a78db2c7a1e3a6fdc9a095b5479dac44f26f7dd3b6edd970b59c6b8c13a48e2bf8a9ba3e000000000055200520000ffffffff03f257fe040000000001533bc184000000000004526a6a51830ece04000000000863ac53005163536ad37f1167197655fe0300000000000000008c10770300000000c90ccd65d7e7f8032ecc311aaf5251e1dbdbecc142071f8977cfaf04ff06aea5cbb892bb6485c5af5c249b0b94aabe8fe453897dd3882b9a4d2cec27e61cc292562a1166f73cb5be503714c85e6c466937a14bfdbdd6cbffb0e5e9a5b466b28c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a67cca4e27824f5d7497fc1233f9dc19d948052374ceebe9b66b97a04fb3a42f70a18132568e01aad8dfaed9cf43cf5e7a43b237bebebc1094c5582241b8743d59278dc020c5832f6293c8bc85b6015bada2d84374b71626b837fd8597616de617ea48326750338d9636f0bdae894c27ea5707c822fe342e7d20be379286f62021189a452d9e76913d8e223222dc2154df5b6eecda76b28eaa8ae0cd075db1170031cc814266860efaab00af1542d43c1c218ec3c25f866510c90bebacc563b57ef0b0417c38f471314ee590d89ea902cb436328d3571f3e3610961b998116bcf11becf6a66260c0f8d57185032d0d47e8fe4626427a0cd1597074eae81fcf28184f9020552a1dcfc04906bed5e8a372c2b494d2bebd1146b5d1c1c7da8e8413a0280bc03198b434b7edd8c320c64a9558041d6f9706f2191092a97fdd98b3e2606f4c67b021babdc27359c5f0126c0ee5cda867478af3ba1e3dbfde2839d4ec3d505ba45f4021105ae219726bc392d2787fbdeb8bba7e49d9eff8ba498e284d7580cf79b6a01030173c47d778d528a79b690cabde1169c5ac611637989372e7ed703efd453661786e877874d163fed64efd3cf15cb5dbfde729eb1949f3447ba643116d0a7ce81bb96c338f01a9faad6f3316edbc4013aa67c2965a688dea87f3133177234fc43611358d87d44403a80c35b4932ec9712e92b1fdb2f5f2a81f4a6b0f38a3b241ac7b26ce1a10c28a3546f9b07d96c04e9a86c6674ab4bc491b0c8bd75c9a4b7dd7c33c9b65f995d7511ab5cf9a9224495e56a5f55b108df9ad466e182ea8062bbe2efce8154a8b1dcdc395b1159563466dbf1b0d52acdc95f163502b3946d28eb33e0d128523d2110bf70f3ecb6c178fca3ba5a8a3ac515cb5010f640123cd9321e38acbe80d8f9197c0dbaab02339d291628da9d8fbdd0b4746c161ff3bcc7e577fdcd3a0c67dac7cb142c9d92864d2b1c6e3ec31ebecc045e5f0efc633ac12f1c1bc5e45bfc41330e629cd27adde32795e2d33263069e191e536f179661ee5ba2bc47698f6bf5b63ff0d47a8bf79d8fc308a5ec6e9756d590a3fafb9c63a6e9ae1c372c8ec0b185a6cf5cec756134214b712658815fe8b16d0163b5301aebd0d68c0137c21bf3a81471f64ffbe2eb5753e3f7968df2bdc40a43663c0759d146cee661e276e20b7dbe9916f250615a3bcef10afae3704f988bf065aacd155c4f2b84ed32b1f7e61d896162664cbce94516c205e4873291f48e8d5366e423e76c15003d843adfc1cf50fd187ffff4c4837ce3f631afa3b3f92d635191326b5b1a3f3c473e9b7535de4fda8a20e67c6f5625a7841a8f11970825a8914741af0529cafdfe8edd7e41ee237ab79bbd0c37aef7a0233b3b690f23b9d3acd0b9f5432305e0674629db8b3a464b5d5ebf4432332ca66b1946e264bc4052ff6338feeb3897a98b77577321c20632008701f10a9d471184c1c92677ce7a1448d3b74a298a38b1fc8fc6ed3b3a7240d71a3c10850e13aab75f2dda69628072b0ecdb192e8318f24a88d34bc97a01f603dcc085bedafeffa34ff3d1ed1599e71d0e1020b98020d4f4fccd21fa3eb76315aaad5c0d319df0e605350891b63504a93d19f4333cd6217e7f7029a9f576469d799d3ba5546f9e2809790c9c76d60e68ec80483558dee798e90266ba9a9d6e98f86cf7c9f5d51501aa119900ccfe34e5a6503ad6be5f08c7fe7492c994f6910b967d9691029ddc2c2b44619810e86a57e149313cd9f12c6a5db661bf4c378e8783f93ac5d3ab535950dbeed76c4cf947652061bf08334a48bb4a2402ee7546dbb7a0cbf232347d293f2027d63dada139dbd733fe1d7ca967ace50e53c6aba9b5d4fd8d1c3ea0c8d8d1c62079d785be7ee2444b4f6f80a4bbfa7fcfd14d875538443abef986a2b298f668c5f2f444df545b1c6a3acd3db31f2a8977ecc9089a96226faafee261644f38721f9daee91fa0056d9eea8b33f6a120e9db9a23ed40695ee5ba65954d7efb8dd83e00202052f681a3e9cba2f59922611cb011597d616b646fe6cd4332e93659ea8b3194dc16259c20cc4aa1a9cb0c002107858ba04e468dbb62df4063620e3f128b422660b118ccfbcc1005be55e514dc81625549e520d114ec3c34d2513380253d7cc3fcbe11e4ce72e8585375d1cbdbf81b28d066648d726f4afa241358aa83ac9808b6c26dd895bf513a75b5a9cb401f83ac18e072aaca4dbcc446a09133da623685f96ba8e8f3834a8c3a89b3e001c755a698688475db8b805ac46200000000000000001356b1030000000016672b16cb7226897669c6d260b77c7c9f7d6232064e8654fda8774812f9b070dc81ebec958a619922efc1090d54364937ef1b6b27f2b3ea64ed81aeb679da7915dfeb59c535934bd7f1b583f6f55821c9808e1c467a60fba20b507aa608e0f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b05bbcac4eccb94cf6bc15b312967fb205157e97299734bf74a39a851ba513bcad634e391f8ba521e6b3d16e5e35c6ad0c3ea663597f16d12aa4628fe26b7e841e329d137d722d4af8b382f055b335b1eb7d2154c9985a113d3da09e16d38c56c99e6053014ee42abe3b036c31bd1ecfbe6a479474b1d802a2e35895945b31a021bb111e63ff198f93fe4d672e54d1312cfc5e6feaf402feb61627743f54f8f6402012f9e6331311d3f0c83de8ca8eb5c2fc8890868c9e51de4d2932b7dc673ed8a0b0100d5d68dd47390e52240d0a64f647b21bc118dc008faa0ac1efc6721f7737af32a188e056128835b5ef1ef101746db335827347e91c92138e81ba2f18d4ce8022792e59c3d90b30e6493b28edab1aa53a1a8f60e7b15478b606da365f0801bb1030402033d5794e3353be274186bff151095f13d608453af0761521be5793dbd5b0323c210f8a4d10887a9046350ec86ac8c89e4d7541cc9d86b68a5b6b31cb6f4b1031117cca964c2b60ca6bf631ce26b594c84ae040540e33a397063918078e37de50315fbcf8e8c7b20b54e349835cf872e08b944c5ad857f7503377035f4d1dd3d0081d216ea9fc25f79a45e814ab3b8eb8b0b2fd0951bc66e113222723f8505bd57d751b99afaa65a328aa11d4af271421a4c6eb525e5dc4986f2b9ae6316f61363bdae1007874884fc2e56715d3a85256089b17489aa98f1e7c949b45065d6934f10c0f1ade87451d7f869ccfa93c43e971c1bdbb9ddec77f6ae0f5d7b0981a3c3c33d5e8d9bbcb86721d4898988ac31a54b432c20cd11039f29946fdeca9f348a2f7eabd04847f9705aace7adb9b9d3ffd5121abe2bc245952eb2385e98a4d32192b27ab42c59c55c61db4a7ef78f14116f50155c56adc92c05909c64af8d10211a54b785e03120e24eb4be48650b4d4e7fca8ef160cd3e8bdd1c0297989b9c0221313abad84b3b5750530883bcc11c79701c2888a0a630010c91ff9db499895ea41a70d39cbd8353405d7e070032d4eddcf0e1d69320e69e5e2d5e09d81380a4a732f8e39ddbad29ef9989b8dda20e24068e23fac2c0ed12547ebb5ef7521dd061ae6929890d1492131c5a9a32bcbe5a98cdb95204518a7b487e76c22d2d0daa13e7e985b6d74ee9412be87db69bc4ac70b4ba785464a9b4bad8054a21f5b757c638a7d48d05d755cd48a00cfd18d88c9486ce1d17eab6cbca72eb277c2e8c87fe35db5881cb113cb741a77c9f4a01e0196c55e13289c24bbfbcfa6102e543d5c65feb66bb83f94dfa4404ab2f4340db0de3b92f47b0ec52e249adb45be5c91c1ad8b2e21e9c5fe96163cc88e21f235ab1e96d9c8dce5a84ec174ca7e4e548de14c9b0867fc5a0e5f8ef7317a5077b9fb6eec8d6f533899c5c535a9ef2a921fc2f3321ce5a7e0455b638aa9c98eb622fbc111ec36724407da0221eca550168118e2318d4c9eba238a80e05d0da60be72ff605614f2228d8437ed8e0f30df79204e3feb30081ce9448056d3b9e8af572dd912ec7a7a4c4e73f323a84d95ba34ad2c9a65f334ffd1f18bde9e9659b7a7177fce15ac688ecf3c3ccb361869c7ed77e5d745cc1d8ea0efe84fe2f75665da596c0e0522ea44b3e6931f98eeeafba921b60ae983e33347465d24ff9bec4c86ef558a93a6d1809d17881383ac0fdd558051022d12b1b58d27b27ded5abcb86b1dc23741da7f7bf6bd2b6aac926350a579ca860bab4c469ec38f4e9f485d651036c208926f5ef71e87ced9e662a5348a42ddb3851768a95640e7eb05ef82b8ec7ce3f881ff9faa4fed1d76cba4b07d99c8903cd5c8a24932c70560e9efb1535e12b2316787d01f7fcedeb68c4a7a60a9fea1ea0d71c1c8acf58d2dcd0ed45bdb481eeb7b34d742e0f2add84f9a6d68d53d2a96c187026eb6a22246dfa77ed2b9e8544b2738cc1aa87a8e80cd34d634c78f5c36e8af6ceb3f595761024fb760f107c6dbe8cf8a6aaac9189f5e3867f85462879bc22404837f1ef3a01a5fd4831f4f14383635994a016fc53f5b08947f0449f111d872e78a9826a35cb98f459a55976e926ef64bdc8615ec9831530107f09f01c80323c1e8128eb6b5b5dc05da7ed234cfa971cc286112c21a49c98bc47f3e184953e8d8f236c2f63863b631d91451130eaca82b86ca51c520a88810b9fa643cb6621295c52bc9b5ff84ac32d8506ac867e2e584079852d060e4f8d4625db7e98a47b2c22fef6bc026c54d2c8d5b9fadc96641733ceaf8c0e82fae3cf14c0494961cb9dade540ccf01297e32f430c60d120000000000000000eae6150500000000045f06790a046c0d63cb8160972d1e1e70706970b5a9089970c9cac9f6dcc5e1cf9f49341c57559bff4878df169c4c25c15a3824696e91a87d49d877dd3227579f08b02d9b13bdea0cd233fb0295c94788f615d5cfb1c6f74345cb4ed9fba94e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a971809db8634dfdb0ed91988cb11d40bd0bd15a327d6fae6e3cdc1618234653ce1af95d9e8d88b555ea91429757f2f034eef6697dbd7a74c9f9727a955be860345a7b888a84b8b112ba13e2e3f47a3092b2b451d8008356362da3efb9e6247b70f6026e23ae5a220adf3908924ce6b0a7facb1fbcc04aa6d17c7b95974888bf03304322e770e60717efd9aa81654c0bf4e9218e3170510633b4cb31309485ee94020ee0240a6770a10f0980eec9d32fa120701e880275c8cb0fd6288f7cbe4e0b3d0a04142eded507ddfb8b2e7311288fcba32330d08d797468e6811eda57d45eb5de96b1b188496962e6c444c30d7b5f05375441d72f067390d620ab1171aa4fbfd0032d9724b823729bf5e4e52464acb085b2a550fd9f42865ed8c1e0439c403dee9002281f19d780c961abeb468eb0c6815f06254ff700c20a1d68563a5d8a837f86c7030aef528e42856d5712a12f40e331359a13863c685e8b72555accbe157ddcdcaf0218ad05caac42c00328d7001846186fa5b1b541c92fcd247aae908fc0256f4be6030492b1af935a51bf3fc62aef2d6e73da56243fb723637d5b8f18f723ba0a7196d53e86cf731a9671a42c44a96abb57e25b5fdf2f255f450763b641bc76114c84dc55d8db503695100af2646af29218865c9b4e686c079e492d7552831073b52df6b9b536eb675770d7735f96b999bc1de7ce8ab19aa5252f5e50b3857edd42e04126034ac741006188216aa2d8d486553b114bcbac7dd5ad8843fb76194d12d973b657d7d96af4d86116b163a9108dbc2f785c112cc485cc52b433c5a147d1ce1ddfdd924ab0b0e0e8e28c3c2080de3aef93dc54d9b08505e4125aa95eb09ef4610bd6ed8d3b8b052be368db225b0e0fdf53a90965c9a365ce2d4adbc848738dab213d6b4795ac4f567ab28ab51fa73c921f18b1db90bc87a27c9fec1c1b2d82fcf5c5077fafa9718efc7ae830ce5dc57edad6e9f0d875055c16dd8efa2db7a110e50d760a9e28279fa4c6276391459686f648674ad93e8a36fa0f184c1ffaf02d8e04932a69d83ae563c3180dc374ceb446b482c1a6b05bcc5c9278d5aaed70a8e8df8c5052d8b968dec819d6c959a61829a478ec367783aeb36a696d429d135e87133de5f7b84dee3fcb85febe3769d2b5f33d735082283a7a7d3b037cef5cd7cb5c85fcef7d7a3469e61c2ff6563d640a426f9af9a5c59964595a29e4f793ab0daa6cac57871bd2d5c3099a53a362eea417733775a68bd5844afa1d6e319e428749f7b80b41181806abd7aa38c7dc14f27d8404960a8cedefbe47dd8f6a01b74f965ba354135f9f95cd875935366828cf00ebcab1c7525e0b8bc6fd8c3b19f45ebbcdc9c1e84f516055529f7a8de2f0178c948adcf90d99b99a48c6abdf2b69d3edeb3208524076461c624846e7802f5d3b12b98ff28268a21f46d2313aff06e111cd009d4efb22f6e9c30fee4c48d48a5ac6215d968d3f1bc5b61ea17313d8bd498924e5865972286abe2717280d2ae3901437d0970f782e79d00dbd3c125e50bb99edcc9324837b0a17211ed002d8307b542066ba81da031a389164f04d1a95826855cd0b70374919bf519e68516014e54a94d8b756ea4c8f1bc295da11e04e469dae5ccfe0c1757f6f38326d47a0f49760ae2419d4d1fcbd2a6cb03cb990ae4e9ddfb389a714aa2df9d4ff983fd27640fe1867e0a12bdc2e0a1d984424ef82d725a3837c0fdc0475378d04b417a8ac147ece0f6a33543e1f769f19be418083f9320474bcc99ae1ecfb8b705a50fc71bde3695d45ffd5c82fc6b7a08ab3134db0bc5b07156c362831f8b2ef6fd82df680f855ccc98ca289f7a7f8c38a236a63457ccadc33b46913f4346846bfbc937c5e94cf428e23c0e0fcce5c90e952543a3ce7f507e8ab2bcfc8ad3f3158006f46ecf02bb3b4bb75e5f3a861878f7e8e81d2d75922fc6fba28dd30b2726b315fc102a55cacb639973411eefc0bd2a7422a7bb6f91e77e3bf42f955bb7a2c7b020a0bb24738f59edc72dd82b813419885848f06bcd8dd4ced5c2407491974de2faf0bc7ad0d31e1ae42245f4d6b96b6209544eb1c7c44bf9a660500a4041763a021491df575e673e76b14a8c6735d5a2935af5f7a560ae54674971e17f9fa1cd0e1fed532ca1797098f747146eef72308d6c4feefd76151dacfc9d9a0203b7b4d2ee1d40bfb73e353970d8c1f63a5cd0f1bd1721d400f11fabcea8cb6e3075fbe99871672b9ba9fddfddd24a71b286e7746ce5c6e198efc9c54be8f11175775d70e0b03eeb833eca83771cfa885c3fa72ea2a733da9b2213b258ca7a0e0d7749485df74f02327c8ee76c47f8094814ce03c36f7496f26a758908d4a92a61cf3896a001b48d53d9569941b48d33f774af53302a08e79b2b80321702912a9ffb6ca00", "6a00", 0, -1835469658, 0, "7cb5aed9c4a5143dfe582ea79ab19ab09744f291f165b413bb2b8d48c4d81f1e"], + ["b8052d2601191757e15d2d48831da44dd44c9a7d6aebf477322462cf3d49368e17e8fb01880100000003656aac250c10a10302dd7c030000000000ce0993020000000009510053ac6a525100528b692003000000000700ac6a52ac63650000000000", "6a65", 0, -1140675683, 0, "3cc23fac8bc5a958d606aa28990eb82d84cb2a761dfae7cd02135d6d2bdf0069"], + ["030000807082c4030128a3c3f781d9915b83eda823889f2c652368891fe1b0501426645f901513466c030000000153ffffffff04bf5b7e05000000000563006aac6a52a5f101000000000365ac52db4be1010000000001655c644c0500000000076a636a51ac51ac9098a6090000000003e5502800000000000000000000000000006c7b352c5a00440b1b78452d41307a21e6c9c1bb6e6b3e3a8a133be6038d9d709da0cdccea3c4974983f486f439e880a42d9dfcd5c3476fa41a2a201de9a4702cd5b457cea8172e0682ce9a8c5edf367f00fd4367a4b853576f3d3231cdd550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054dbb2a2aa898aa04c9eec3cff86e4164c721c34a4cdb5d82f40e411a08f8e837e6363b5f9c27406e553bac96703619ba5f686da518b9159a57038bb57f22fda49bd24dd2283419e5112ae9120f78cc35163ca9c2c28ee11cd81af9aa01fff2ff8515cb2e0b026afd9ce0a171ecc98977f3a8998f02c368c636141ccd1f5cd9a020dba7e9d88cc6f1434c3ce55ccf6c598086bd9bbe890934b75d76cf9735cc68d020a97f1ca7e56cfeb788851497c05d8a75a4276b1306eeceba5200be887ef34d70b0783766ff3a3fed27c570307414e8d2ab314b4bf1a7fe7a5f78668681344f20d267db3170e4b4bbc3422a70517c32a761bc1698437ad6ea014a3916fbfc216a2030f6ed3e1a8c63744ac14e01bbf6feaed4f0881d5138face4a5b3f17b1c178d1602279f9f6639870267fb2b4a405fa26c3016cf36cf0076437979316b846de948010215884d62cf80d0359b2145dbf16d934d6054fcd132111c3617f27394cacc9e2603018d601f08613bb6823f3dc0f6dd5564939e3584dc8af5ef486eeb115a46aad7031a8c723223c008e2661001596bb53ff367932c9fd058200f3424c1abefd713880d6ef3dfda9f124c7248dea1aa9483fea901446451c5e6e94accee7e9c51e875896ac526037649f9d852970c53dc5baf141603db5f0ff4d3d0a9d7b05bc21c9eb0ed74a349dec5e5e7cf249f134109719f1ebef7805ad76349717e988b67242e24503e2c61554f64204a44a807d872bd45170f68c5e2ddb9fae5ee373d0714cc57c761f5261c279411c4a5788ef4e774c1122dc9d8023e889de452476497719ecb808c0b2628061a7022fc96cd7728bf96c7f159cf6c858355db914245224440861afeef4fe0d5fe2c27aae79c79e06510c21894e97fd056de9a6a3db7092530414573ba40230f9b812fbe36dc681756586288d5274989a1a70725fe677bde10f0f4f0841a1ccd9c1dacc13e4e99b16cb30960f438eab648282628827763f1c6ac0ae44af4f9b1e12043f7731621d8fde37de0e8a5fe610ce8b3d793480bc37c7451283006150ecdcb400fcc52866c2ef1e63e1a1f63506d5251426ff607f49cc495c51a28fccbf74c0e339791142cd8cebecf8c377eb4afe37bae25d2363026b1347b0ed9e6251191ff338d0488b9f393902d6a50df856919077c01df51214f77700e39264f06cc1cbfc9ea50ddd996f603052d3bb75cf24637bc0d58040efb369d07b87e0941d0563447b036dc053e1c4381989a527960215bef8331adc600bdd5d4a2eb064faa0c73093575f52f69a505e60f108b128f0f725f80f9e4455956b5d890fe8f74f6ffc00ac240c9b96a02fbff6d710a45108578f1bfc8c599bdc0e20bcbde831b5fda3e9188ae78a76d56e482dc9a535215624bfccd7787cadd56780496e15f4deadb09433259ff117a2e6ee1a041c5f2f5f6f72cbf612337aebb2a2adef15e3cea8cdfec81d1278de4890d3538544106adc3d11b386876315e874228233e198789d974ea20da56feff4c855b97e66b440109163b60320ffb876ad7820d2b1d7c0c23efb7be7439e2fd45300e9a12f6eaa6833bf2c3bdf849f6eb3b75f272c7855bd40596ca4fd37a2425a38e4ebf50c6cb5ce7244bf2d8ae1778fdaa48d897a1b357edb803c10489c0a1f8632ff77ae576eba4941c77bcde0e20ea31e47cd1521db5a59c66e3f30ee5cb68eb34cb6e8519346e5de127081d1a18c32035abaa2a410e4e5b3ef416d84b97e2f76659da399eb5a828f6ea031e3b92a2a3bc364d2853c3cee3c50baf1d84bda0156120ea17f14a583eec10a04ad87a647e5d22446760eee8ac64fdfb24ab75d7bff140034b3ea2d50e9bce9e27ee81bea2c4e43be268fe95a7dc39457b47e5371fb4653c73c76b66526ccae33ea08c5d76046b9ba6f9287b186027e5634eb386991893ef9c93d78a86e4162a06c0b8629dc01fbee9f3b2fe74676ed58cda3fd7e45b7923ec3e67ccdd95fd3407254b3a4c559e47819863a2f7b50539dd06dcf307e8a1a8021dbdec13bfa8b5bdae61644626cea597202258c6fa8727c39bdf5806314f6bda884a027df9207c8471706b22a26c099ea889c97b430c338698bd6e04cf2d039d6b83ad227c2a94254b3747c2b160544fe52d691fd4a4ec24893b79f40386289e960820b26573d5cfcea320a96b0d609a48c7a00ea1359e76d06b6925329dbcc1097d1a300ea8ad1d5fbdb978ae01e130ddf1eb9dd14488e06b2c69e76680c840feefa902cd55fa746288beeeee197d167998c72b3eec9c2e58569344590002000000000000000000000000fd6ec2ca6b6bdddb3c3f6b4d507582d34d2a01c6844630ba7b27c07afc384e4ac85c01f7009ad6666c8e2fde15ad2b350fc1fffc8770ca610137fa4f3d31e42179f5e0f455b7b54f4ffcd966bf3f656004562113d079587b13658b0f3fdb1154000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001269ed6c67d4901db194bee77dc15134a971c8aef001b8ef5948bb433fa6dcaa18fdd4b24a9f95a433845b48bec38f33d0dde70759b709564021aa3061005d56e534404e2ca2f96921dec871b568757c885edbd498941b1a834e602b6fa742bef8bb1141415409f78f7d24af96157a5b8f5343a68527433576031c741ceeb077022ac601ef9fab471b34b8f225492e3cdec117c1d2ae831c77fd029c6e5ff7ac1703011783a80e7ddf2f18dc4ba91737c4c71bb529e2fbd950ccd92ef326dc6acbfe0b067f82ddec8f6e505dbbb1344b68889ed4b2333fe1a5e1ee911390431c15166695b22336a2e996a3f4dcd4f8046f312f9c05f3fcb49c48e2c5f6b6b8bdcbe616031026029556369c24fffe299f3fd0ac4cae2599e17ce252c1c3b4b171b427c2f5031cecc71975a70df121ef983d3f480873b3b61dea73fb29692417b13c42bd7841031c0a5fbbd46680ba183d2068f961c4d0d3e875af75a7f6b64593e969e7fd92b80304dcca7921256c9beddef6538f6d652a04ed5d4799a2c9d61d6d9ddd3cf8197a032b3e9170cacf9deb224431a7c150bf8d836fecfbef2d0b6612489efb0145819e2c03f6c02b2ea766743952739249a9418e0514ea3ebe847c20d7592c81fefcbf571bfb326d102fc1b730249ba9512bdd4310c1761dd42fa6b141c306b8ddee69c785439e598a9d9e917c6047fcea1bf69fe3c73d6bf27c524d018009223fc19ce789ef175bf3deb1cd21093593ca3b4fe9c559760efe5b6b4add002c65ed2846531dadcab129e3ce2d96cf2380169f9fa64680e6e582a10aa35ba4429fa6b17f4792e9b24e61b243963f390edd038cca65c0acbc80853a780f8d355aa587cefac25b55385a71cd5ba02b947c18ce5645cfd85ad63f309c6cea8219c13dabd8f25b7b66ff766898dd5d506a1cbf8c04c8d2708833fcb2f5f029f876404eaee4d74447839079f60b0f17a7994fd96726e5ad24229a1c4521d16d0d72c9d32fbbe98a8f7877aacf4a0e9bc32dc8fbde38fa31be98c12ab901b97a592dd0f828a40bed703f194cc615fbc94087a32e3095f14226a4c5aaa999cfbd0ba7af1d22fd99d94991c4b2dc0d07d0771701d2e0046e2246ce98411f8ee4268f30e29e295de37284de622d516696b64ecc623bfff68b9b1431aa805cb2438ed45053abed3335900f0510a17b8584b6ac68db771a9718ae9c08ca4bbce57466cf60ebd5096370d5095f63d859001b2f217ce0a2348e3e772b4c2d6a6660344fff49c3333fc948de3149571a40ba54394179beed4c889c95f5046a0f47c9a32c1e7f4fb5bcdac6091a89136169e9fc9aac469af7da5af5d4538bcc05f12805517f30865eedf6dfe5bee192221670bacad9299cc4236087fcfdcc9e45d3ccc6821026f1add3ad18af28016f75772541cb74b175bd7c1c959f35183328fd72339737d76dd041d245da4b7c3b1b6b8adeb2996e462422dec652b4f51134158fd2192dd2fa0df17db2a4c2690ab4a1c5bcb4e1f8cffe571c472b23de06ea3dbc855b66e2d6114f0a32727f2f6109f0f5c33c4061f84196f73ea2ad5105d7baeadd3d4526be3c269c7f18b16f206d48b470eb427fa57bc92691d6a9fe8467c3519aafe918f207bd286b6817dab74852c1fce5e51bcfee0b3f7614fa4fc095b22a954450641977bde3e36e3f5b22a469a0c532b18ea30b2d13db4f7b23856477222d1507f11c75467ffb06b3597022abbcdf8c695e2d2d517ba2178a3e3ef0644d91d06d8362cd4ca143e0ecd0f58d0971044448d475c42f398ebd7ff1a1979372bd8d81feb3650b5b251db9b17479ee936762bb0a85bf308f368cbd4132e37fde2593fda683cbac92c6c2db7a5004842787d03fbe8a3fcc3d15559fad76cd76749006572044d84f41970432644527e5123cfb657ccb573bf7071db3d8f091b805b25d81519c32b104d035aed2de91fcfc155fedfbb0dcc064630b4f7e962a1e4695b23160a749e64d657778f0ab3839f92353190b6b57879b96cc49f043989f01e3e0ed78527ff08cc3605b90b228fc1b06562ad9bac49da60b93fbea3e526498fe31692c38faea57d08c66edf29915162232c917d2d049360a0e54f992a190eff6b89a1e49b82e7f913dd5ba6fe8e4ab2e33f466ebeb4f53c35f61ba2414200b43a6ed6d8b256630bcc3ae43e8a281be87632fac6adbe463784b5ee5e47c05fd732e3031645b5f976e96df99d18834cd0f0901893b88c38fc6340d49906574164fa1f8afa45ffc0fe291d644ec076e9a5894861ca63f9d7c69cbdd7f7b55030000000000000000000000008071b81bf40c5aad1f88e98b3cd2e4f9e5f16df425c6b343153339b289fc7112f83cff6317564a7df841e19dc24802895ea37f089d4d1237a2457dda4dec2ea8cf471115d1f5fa43fef16a8de42424f8e61dfc395ce16bf3c4f0218f9b49ff630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006aabf91e55930afe425fb46d187d32ed24880e081141dc7e17b29afab234b69726a3f2b7e13c022a826cd33bba37cb3fb3dc1a3841d16528dd2d5b8f22924bce61b030b6e4725ea4e03f74c9fc95ec27fd38de3333a4da01acc2d647d2e62445721807fdfd9b65bc4714ff94a97da897c92e016066e4a5ad02704ea92e6369e0226d432436f9563e528bb1df666320e8f9e59377553b26aef79e13aa4d7687dac030c2a6720d5ea636dc8c09615bf75797019a0005ae4b4dda93f16f63af669b63d0b00a057a6046c21b92985c97d7201c4fc5e1b57586a39f5a079264085dd221618c9f5393117aa419984e53475c159c57810c9e20eff84b4413d9f1c71c467b48b02043c05ef06af537e3081f609a332611f8d48fe7552f5a93317eeaf04f7f8f6a50207fb63773d0927cce08943c786407dc0bff5b3003d9cea4c2aba21de8bad34210322e264c9756c62c2b9a8d83d8b593c07a557b3cfabc21ea7fa25fff58ad20463022fd565c60dae252244bf8f87a137bcaf74d4323f87e9efced84c3cb3654b9fdf020bb4339e014ae5a8966489fcedfd0970e67522577fe3209d86fffb0b1fc9a3e93bad1fd3ce3411275ff8e9c94fe00e54a006ce8ab5f6f8a21235ead2544e15b9b53667313f66571c7803a10fefc6c16fced786500f7e77b3d769f3d39c14ddb7aafa7b48749833aeb3de47e376122d0e2aa58ad10ef819fede38962dddabcd983d4e64cd766db17b8c16d965cb79122f6bd18332e7cf613ebf3ef39ca639ca2cc7f7f482c55407cadc05a2b268ae3592b5ba040ab015fc1b299cff5ba784243dd254b67e63269a8ab2a2dc3c9c824a5a05df5a0b03368a25e6bec29f2536781babb56c039e313aef4db9d84e37331ca7591bcacc6a3b65cd3e4150bc3cf3971e0f1bb2fdf2654792021597213d1ad7f05e1bc13a3347583d85cac87455d14eb0f0dec10967a7176a2b348e7f02f96d785926e9b5dcf8150c9ef3f6012639ef8825355684553eb699ba4cb51c0642444cf6135c5f37665ada07e66dec0da050d5d908cec0d5d9a9e4d46a3119d4fc43bf29beb8dedd3b3d862459aa6fcf0ac5c0cd47bf0790da0d72aca8375e1748942364e5122de3063bf0782afa3d7e5cd2c9cf36eb64873381eb9f2d2447aabac7bf3323a96ecafc708c86cb10b36a2bd4ed697cc48096a43a79c80fab1fed82c6bb50a364859a6f7dd51fd64a4132233c87055e378147bc983c4b993d90fd1798da113a3282a453208276ace388161b6e6a1ec374881f226b685045fd7759bdd5e023ccc9e23a47ae0aeb5f3cbf8c4d9c5b072448874bb10b3466c721373785e6470541882bd9694b21252fc360d96f759178acc534e1d462b4d5ebaa4afbc0ee9718c9d12d9dce525bed0f77ccf5e9bbc9fe097455db53c095349cc92cae3daced0f06f27d42bc89263673de10054b98d4a4cec7734e365123a6986ff74630b8d4dc81c9043faf82141fba04b1ec90f8563b156781ff0dd867e14a6c775f183621262d99b27a922c36f8e082159fe0598b2c12423772baa9e168404e6463e53f34eea497aad910b5b97b7966558ee481ab0d84f827f40f857cba038dad15492cf994a02809932d0761b67158fef208958fe16e1cbfd5fc8a78b57d1b0735f74f57528f1663411e0cbe497d393af917a14c283ea873eacc26e3edcf4f49273df59343a615269c52373333beabfc935b697929d202b5640c1f10454b2f77c53304644182f3fa3fecc4898cc3e3a965dbd55ddc3d928e796049f9a75eb51f078307ff4cb41a3c52633fd6b5ab9fb5947c886e7d8083bac708424f557c804666d6f86cc43c495106200012ac118751463523a7cb3a93d8fc62c7bf1276a477533e245db0d1697e678ced319614eb366f2aade2fd810f12076517916a13d17867bab2a85d2b6015a87daad8270d37b5c8ffd4a7fd4b537ad0bc2892d6e06d0ed40f63232ee8ca08719ec6321fe8a6480c75ea037ab2cfac6ce3ed339f77df8d24a17a9cbe0276961bf21e6a274c5f15d6368d70c8c34f805a4e07dd276c54c714a0f3ad40987e5cfef746e51dcb19967b4c2261e211df59584b69bf9e1bb48c87a4c3cbb4beb3cb8eb613c1a60082ea577bf5ff09a74370620462d48afa182a0481a5b25ea5cfdd6107c4892059bf298aca7e22de711fa05efc4d3484e3876774d0e527c298f6cff05409f330ea89a9f0a9d04cb97bc1bbb553a0bd237110ffd840d6aecbea02df4cb028f0d4851411b7c5f9b15324f2415b716bc19ee81299c9717ee5ae973d9105386201e7a583926c0565ade153251d74c57287ac44f990dc88623e20ed29d0de103577f8aa753bde5b7ba2dcfa61e8a4e263fb83615abbfc23340e19cc64e9458bc46a0f276d12b0441cc1104ca2da521e768d50148125b8207c32d802", "63636a", 0, 2071402406, 1537743641, "72f2cb02ef471988281185b6175de918e7c7c876cee818dbe1925dc45cd5860f"], + ["553d522b046cc2f75dedeb8cdfe8653e77e7a5a2c061cfb71eb51ee4be2f5d662903c0db1501000000055365006a51ffffffffab11751d4c3f70bc785f7f8c7223a560603f534afe60c63c8b293f17437a84f70000000000ffffffff9b61b322d7370c6049743b6770fb2d88d56fa41f97954ddd8379ce1642bc20ff000000000663ac5300516357422cda104ce580e1586b02600453043324bf13a1fe7941fea1266512f058e3155ea3ee03000000016aa8f696320296dd5c0400000000016a15e7fc01000000000465526aac000000000100000000000000000c1f9a050000000094d2b7dcb3cb25b55ed1933a82a7e75ee7302f1aebe90373ae294732483ecd9eeb7e0ba5d7e16033af34a364515b6875cfd4bac1c7fb30b4c75e80bab8850509f1c45c9f38a6f5f7a3505bcae9ea020aeb95c614cc6bdf3edaf4555d09c9882a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002ecbdbc6e6fc11031a4a2008fa9be7d61d382e135eeb739ec0bec1cafd407ad1f2f74c19b09089d108b474d11161d952b55629e44c8c6ebde0cf4e05e5c19273474447ea5df8226805bee2fd3a18802cc3c5f41f68cc4c70fb625c61a26fa039278542688555c46affb1ec91d4a5334948593a57c6e3f7fc866308e23724244031beae445b05b297c2339aa66862bcf7781b23ad1b312a1c0da57173a50d8e332022cfbf275484d7a83f5457c2f7de79a1713d88cc7536acd7d5152dd93ef4d09e40b00e560a05f9212ecc8aff66be967eb2deb16c74bd944e1926364b2cbd5aab43e5756e2bcdb7dc6e160ff7b574d44a3eef300dd8cf5a07f28022bf07ff89e27070320111ee8d9c7eb1e761164cd1a5087e4b2a5d186e267db58bdb3c0bdaf46b381032c7939ff16261c2940fc64bec0fef123d1800398452c435f59a7b55afd6f3504020480515893bc113cbd201fca55cbe5244689b252c1339665a94fc841ff1c638803248afa7cdf9337ecf5ca65422ca0da3a359ea17d49030c4fedee719d33fe5d9e03274f5e95bb889a5f5db6fa64b066e9bfa93bd3ca76b8b0b93538392252e8ae120872f1ae502f9734b4747c6a5141b3bc07cdc83e07347fdda1237dfe28c86117053306f8b068c006568d15d424d54587152da2d3fa80e4711728e63340dfb785304d62b77837f930c3d2f5054fc6138560eff3477e2dc1e0c29ad40eca6e178010d8a7f0bed71ab6b0d8eb629aaa613c929080a42fbab43904b8b51333845e73f078ff1c318e76792560e361e67861feed9a1394f8702cba913d371f88619ba894d48849ca92aa24c5c647a53f6d9af80783dddad0969905815d7bef3e619ab0f3203edf8d576fce44181d76a3f3ab0706961b92a3bb508c020e4d4fc434448bd3600cfe0bc9c35c0b2e9165eb1d95b1acc18c50319cff6c88368d7c8114bdfca9247206e76973e0aaf506344b8983188463a45235e400f8efff1dfc05e9e80080be68777151281f559cf5f4dc033ab4290260ba5c2d6d13dff151e27bfd9d3453a9dde8b808193373b6e276378d76b9651a217d381a93cd280adf53f7cc9c02b83ed4d46b6cc8d4ef7c792e64326b5534f4b3e6c7551aeadfd571989844841b312ac427186c69cee9b6c515e075f8fb71fa8be9f9544f11ee6fc0ef7e5d062e4477cb1ff81b17e97b7f366d8934eb3565277cea36a9ce9c9849d03b1a92bebd6a10c09e26762498e55f964cb51a0a83fcd78a9e8b64a80ed6b702368df51d9f6c9a9ecf553594ba273b64bc7351c2621afb70f4a09579d45df6d1231c0459b97b979ac574c1d10f4d318b1fc1375a8d0e7afafd6c435c35c49f4fdfc12ca80e5540b26080e1cf31de79933f004e77d3c9ec84b7254164ea67bc3877cdc0d3e344de54617f8557996cacf0c2c0ffea17bbf82e01457a41a8d41b40e0326f9582970919fbc8d0a4e0fc68e4666ae61f564d758eff3f1d3f6e48a53d9f1ff2d25521141e6fad786d411d28bfaca3cde6469b93a2bd834133d63ea9bb8d1f39f230174233527e14deb799be62d602e12f7578ddcefdb9da588d39998c60453a6981a004f0f3412d18d5436591cd96514fdaef014e6bad4c853e9e39ba392c1e82bc5ffb79f0848e0ff0f3295f6e510af5cb9caa9cdf00059339ca8ec4f6fcbddded1ed246cd20c177e399fa1a272d62a6fc0c7af3d8075393ee5f15b3a84c5e657f37613ac86da040f191dd8f6d5bd4c70779371b5f8241fdca3091ec4cdbbe5ed3edd2fdc767a212949cbe64926adc78795ba43f7138eb3b4b6025937105f0d4d70f859287395f79bff6dfb680ade0f72bd4c45caa2f343f5ce5797a3fc7f3cc98f0c0385ffddd6caadada18cb4033307c722add8ed984dafca0367daa489973f81d50afe74744f67f8eb158ac52a2cca4b68c465225063825ffe324fe9c8bba14a4833793e44b2b35ace837ce06e4bdcae0cf85e2655c8ac703f4e44609d4d46919342ec0a233e923659db5f47e4b49c268a3ed818f6d7adac2ca000dfe595e08da98385e12bb7621ab1bc02ddd46b01a8821c53341f3dfae8e181269f67ee3482cd4b57cc3a2213d0456c5baa7e11a1f8db1c6e9d67057f8353dc4c014fcabd85cc56bfa3e7f32b422dc618ba95351ef1821415545281cfa8f9732c185c2252222760e01161129db59b0fd55bd38ede71e6ce3ebbfe50ca27adbc17359617d49d216eac32519c6b8a0c979fee73c85450f3c24acaf86c9c293a963fb74d28bdfc4b4971331fa6647ea1d2448453304a6cacb98c2aee3983f88c5af99381f3260840633549e6e58db6b365ecb9bcee7a81f449445e2e903412e2a176fcdc40ee2444c208cde996b4f59d54e09066f40d904e1ad996c15fd51ffe6236f561a889516574787a2977759e1cf1193d4ac87191109", "52", 0, 389627320, 1537743641, "9cf4f22e6829300703f006d20c4100504fbce151444240fa504565777233447d"], + ["555e006e03348e6465bd736f1cc04d7abd6c0bd9a9945dd17e1bc02a5fae0b48c7f9b8c8fb030000000965536a526351ac51acffffffff9552b35092ab3294f3ca07629ecf6a9dfa4dffd9a005dcd2ed682b5660f033b50000000006536565655300ffffffff483f4c0de123c4582b60d26494bb0d5c02713072891e0be0ddb469c868ad836303000000095263516563636a52639fd62ad30106e6aa01000000000751630051656a000000000002791b01000000000000000000000000001b82b1e8e19a5fcc1441dd9bf65808a7d24ddec9c53a2e53f5e9be4cbc24c07726c662e6b0d7b71b77ba39bbb333a53d25e2e8f93bfc1bbc70ed43798ef50730a33751b467044f8b0a6b728d52fbcb8470ed4f73d72f041b9e889e60c366b47000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7d8752945dd6c301249a0a2a7068c0e0782fd44215e0f4138addff052032012c929f5be6f3289c3f52b94609e3c6d825bc11827e59a35246a784e5344dc712ea63fe328ec949a61e88c6e706ebe591f300d0129c7d20f16330ca116d3cf426bc05ec46998d329a1b20c9096d5ed4e11e4a2c385fc6bfc873eafcb05cd5174550208b54e2aa26ed1375bd0662eeb3f468790e67e5be7bd690d8ba008c20e9559b102208dbd9c6cb31b15e3f0957d2871d47b40e7151698787873ef834ad3ceae03310a083fca660f0344e6e696a1961cd859711de934b6f19b21faad145a506b93f4a3f6a9bd2c7be043b2418f89f2b36813accc4d571b646437250f283a27f5fc63a3030c1f23bd1ecf9c58ad7bd903c4dc2787e1f76430a63ec1d8da26cc0fd9f6de240222e2a00d03059ad65d7c35a4720c474793a8cc0ca53a645928c70f3df65a351e0314a00bbb4411d8a31c1b192a160532c1b9dc09f7adab40084e661f292e3a7705030d8e32a6a2d579beb74ea66be41ed4845567cc798eda64066192bafd5732aa5d03071e7ef36521558901b69d379e19323840e28eadddfb9e5485c588ba26cd1a32cafc1b91adbe8df95de5e16361be5a4a146f4d02f282811eab4a682ba9d2432a20b224e1ca03f7d1c24d544e0cd8a237173ad03fe8d38235605777a1ce9faeb68a9b1521b9d48d8fbdd3e73280b3b4fdc73f50b9a72a1100f161d96cfc34da24c29f65776b1c4aee48081a863d10545b1c63ba87b9524496744cd58bafc28f2bc1f772c75773b56c5d100e3b1c3ceb6ebf4d0337e9493a9f973b5fc74bf35e99152bfe7076220d0204970958e726cc80227571f5c8e45944ddd9de33bfb7119699c32395926ae4d303b0b9b2a53ea3473403558ad8320b34ce82d1d61bb4aee64ed71fb4af669bdce71939758c8a9ecd4c0cc4bc745cc01bea598c06d62abac982a4b146e442b686eb028d621532d1d50431b67bd7e1b12ba4636e7ac37111301de3afa4496d777c3c120d3d523619173c232de0b420a4990c3cb5b66c57281710ed160bb33c53758a550e38b809742cf8c76e060b8b7d66f7896eac4df0113554b18ad420e5a9c5f9b1d0a0387291febb25b863da46d612bfce7e419dcfe1143ac0b7bca99543bf016ba05ff0cd591c3606afe51268fa9eb38ccaf6b79d7d096db67bbb283d6b2f7da45c4d497b09300ebdd08c44070a09107992032e27e5ea0527438022c97c131f77d7abc41e6eb85396c260954b67bed60493a9a75276110335161887a117206cfd7c96e76fc115a0e27885311b538f3e354df772039d14058fcccdb1de8c1a38253ecb527370b9b0dd36b4669f1e3c1a517a821ce73b63342c0f529df7cca6bfd53bcfe16d3598775809eaf08dc2c632f4f2a3dda88f8d2343bf330c0032ae51c0aaea7099976cfdd040b4647547e53e021ffe6fcb5dd7c32263247642c3d1028f3339438205877ddc6816e29e6f780efeca868ad04de883869bdc07996e136a0695c029b75cd73a0d1e75d8c7caf4ab0995041cc46c95aaa6db7119f0da30b3c5eb2d527caf754120255d33708d344877f73ead498de4759cbf3cfb655de36869dc864cc901970e0b36c4b6fd8d7b6f643836e515839f3cb09b235de9001bdea57e1ee442b7f02d7ebf0dec891a945b2cd710ede483ee3e6484df49677b4641fefc3ca53a9be3cfab3d4c43e020c1d6cdf3a314178f6b6c5f279d6649b253ee0eae6e5f0593c2790307f6417a56b127bd2c207fc2443e0481e5ed15a6676b0e0bc26281032d64eb3ddcaee120e9094f38cc1368fc108b0aa7f8f8151da43b238261dfdcd560c0a9248bad461c0766b75eff8d8dd8e1852e25419fbb5405a4842e4f1f0eceb3d630593466c0a606930e540c9501d1184b0e2aeeffe4bc7abcf31281f140f88bf4869f299439e3e628fb77ce1a53bf397fa551fe9e7fa626946ff608e9c1a2227da5530a16420bf901ecfa51736d9b71860b45985e8830f333b8f937948a738088b3bd0e4f8e158588be71891a3b502cd095dbb79e2ad06fb0f0b57a7ed00855116bca259766a66e68a2255e56257ccba0a080ff000411ae0d6e8207e9b0807b6c37a905de4d626be4201be124e40e405438139a9a1f5083b2b359501fa3436f2335e5d7e0a77b47263b6aee5788e15ab2510df2e442b2c5b5eec93a707c5ba8e34503b596da236e4e632d8d0006e8b29441dc775118aeac5613961f3b78c944a09170b748af111e2362cf1e154fe3f3d980d8862f8543ba7a2965b941f2f47280844f168f7a010000000000000000000000008bea9da1e5eebc8eab56f6cb089beaea072d6089198fa63d18c3d10c5cca38e7d1b3b0aea00b7a261815f80d5002a88f2cd950a36143e95fda1aa7b36eb3d5186e3097cb40f13d7461cd400ae66cdb3ad50fa5442531b866c4afcfd398b56b6c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087d1753752845fab5810f37590162cbe81517af33f18c01776b033ca7fb4f1b801ca2135550636b347e76ac8e08d50ef5159a65e4551f8f941d49bf364214b802328dc019ff0c46b8c8805367d93c38906576950ccdee8ae7a457fe44a20dde1e8b41c712e0dc5ce94ffb44d804e159e75949121a9c31df4968c79cc0af3270c0227047c493d35a8526a8c04a76a3f420739104b4b53803fd63e07d474cedcec660220a604677a89008c469d860df4bd1acb639ff0224b18ba6965fc5e5230ddbf410a06d5e13d7d64b170d83ab7df3cafbc8c19b75528aa6b975b618a84eae377f9e67c804f5677f74206d2257fa1124e0270c69b9288545b8eeaee1d49c74dc06d2d032cd912a059d539eafa646b267dbe4ed9565ceeb1bafb7b697ffb1db3cfc0897903099c54d0bcb8e1ea2d83eccf4d2fb16cc286ec39a093cb0006a58e6de0526ff50317ba8cfa09c7d408df9ca14eef70678964c1b3d74a29dbb5715da73addf9cab3030627d8c6bacfa5b0b20fe7af5356daf3d7235f2d2af1ff5c4bb1f0a376873c1e020e3f478494cdf567d1665ed1588a8a607d7925fc3eea0504fb928e1f107560dd6be4a864b58246cd4f7b228d8eefc15b22df4bfa8e0a7141a1647e75681432cfc47e3e47c2aedce66b41d78ff2e97a38f46e9b71b60f16679ff6feb77707ca2cd1da75181a63db09f09d6eca5c96dd7a1aff9757c018dd39b6e04944b800dbfbd46d677c4ded1c0965ec071248a1b6c669f7bdab04ce575422088009c26a4dfb0fa861a9b87c19a78356c43230138e7d9ba28436a539fba66a33cd3236dc42c4d3218aa1588c8e1f04eee336c3f8157d6229cf271fed56fdd3405af9530bc8a825e28b8d8a0db06b160202c66b2d578e66144777f087ee0dbb2a95b4b861822f1fe9dc41a05c717ca16a1ad3e1a3e137934bc70a53102788863a3d371491ccf28aee1851bbb31baef89a785a2752b712418c1f995b42bbeb6fa9b1ba09ff4aa3729a0bb3995747a6d09c0f6cc300a143f1088761a81caf0772b921222c8d65f90f67d2430754a68ecbf527d011dd6770387f980dc3c7dacd28e3847fdbb35fbbf2106cca48fea63115a54aa64da4c5852ff859e9433ed177d4ad9b39a6008b02ec85979b122554d0449ba9da9ee9083e97990b20c19818fb64bdd62f01c072d7314d4f53bc232b1ba7131701985c9e759f13141a4863bfa3eb92201b9d40ca49b6c09862f0f7fd258dfd5047af517b76df4d7dda05a514f7490de5aab487f7de463eda1a971e3c2028db35ea9933175cebae6014838493d7d11f792b2acdfd899fbbd57a8eadf21d19cc6cda3aa90c12766024d818294366edd9e937407719352294ecab3d521b04c2098c14eb910019691a5df22e6b10bbd6dc471bd1d75debfbd673a12752fc212bb64fcd5c8a4a92e8f54f5c4cc5dc3ceec38ed007e77e9a528b7227f81756dd98babaafb625534e33f09c5084e77ffe961206d4d6bc415ade2d78b7b263ac0ce52927116aecc535beee79111adb37d4934f04a11dab07cad7b8492b9bef68089ea2c9da8360fa82837cba2b102d1dae3f44b726a7012b52679cecffef5ea22ca268a27305109a9d86baf4174da6d87bb4db5910eb07dcba00d606fa5165493d06af93725c5e1d4869a33ea22bc2b55c751353b8044566c16abc5e57137b2b2823e3d98ae4824069b03f5e5c71886f22f7440649874cc29aeae0526e71608bbabbe081d274144c8f25a29474791f7abc614af7e3b62c448e73e1b24a9e703010f2b27070885ac7fc1f8ad8feb2f4bce8ed015d06bdfd8072f553c47ac1de11d4f62d2c4fed8f2c570876c5145444b2f3240f285cbf342fb4a1fc2f2071d12ef1a7e8d9b3f356cf54be4339b7756afc54016aec6dcde7e472999a7f7ef35163ac9961bce128b83e9aa0e9b05b73bdb60adc4576e7a3282ed31fd5c3cebdc438164987afd327350d526cb1faab15bcea7571dc7bf7e6c6f7b222aa80ade021d6967f3147e3406dea7a734b265d13e070d0da0bb61fc42f1081da1174a2dfc088e29372bec587bc308d9fc7331be6d0226f398f6713aa9459ae56ec88c4955dfec06d42bf59ec219fb25c3af9747d563f56d257946d1950b51ed5043aa86523a70947b1ba0e0e0e3cfc9f0bcafc54382048e292688777dddd155fda5786a6c433a6a0117f6199e41afc190729a4722f0268f50399ef2642ae0da958b07dfdbf6db51c9710afaa30abd3bd59ebc85a915f79c52fc054ebcb498e0fd7ada6120a423d0338c90f96cb7565d7872529990ea035f513910e584d2a9825602471b674bab87e4fa8acb1aa0d14569fb0897fe20ed0a54e2434848807bfae161842f01e4743b3236d354f09f81bba947c7be740f937bd2699d0ff3e73161e3859bb6d1dcfdb0e353f1c3d2fbf663d05", "ac", 1, -1005560772, 1537743641, "0d5e0b02a9c23e1aa5cc09570ff5c0b8dcc8df80ac73660359e85bb334720842"], + ["030000807082c4030408402072a9d2ebf6ca8e704e795c435b70d1f79d51a7446fa7571b8c95eb038301000000040052005187267db2d3e487efa704640d84aa788f2019781276fc50b0c6a2bf41b28a617ade7c2dc8030000000165cca66f22ddc665d32a7c37309aa77ad47f40b189a521b33acc88977007c5f898efbe32a90000000005635253ac00e8563e42f16e76b700c1f5220e2603f64b7d0c46941db778420378dbc0c3f992301045a50000000000b07dafeb012d4d0d030000000004ac6a535200000000000000000228ae1700000000000000000000000000ae5917d4e76db29cd980495c34f7c311277b3e01be985dae56bf89f33b98de5c509e3a4dd386e56ba2f2aca95504b11cac3b2183beadc53ec688bb7860d7c561403fab5813c56341de020dcfd4a5ed9dd82a926ebe477d88e3e3bc1db553a3060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037acb81ade6100bb29c389cc0be68673f191405374eb676f86212bc4384a053d69db6173ae4bd44484e1669d638089341778acb05eed0f79a08635acf17703b77d663ad9be017fe04a2865c9722d6e562384e564d90092499593d9a0200000216b9cedef3b0b49f66b0576b9920b2537d3a3546dd3b913764ac8ef1acdf6a6bb032bb09dbe4ae43921bcc74f872709f26ea43d862e61f2ed7f7718f4e5bfec31f5032e2118a1ec0db4c8453412d47efc3141e23db3102a3da672c289061ffca1f7720b0294ee9e1e854c418d94e36f182b729af30e566756a575206fd3d0f2f420cff30e2ba3c604169ee172ef8acbf53f37fd87cc84d745fe48aa3662820fd372bbe10228f8529bcf876d925a1bee24738b493d24b3943f6337e19497173e575385f92b03002ffef2e3464bff65f89534d91bc52ac4cb2ef535661faf66e02442af227438021bdd2df508f4979c84919bad90b465a6c56913913bcf2490f695ed041aef44a602119cb7feb2710e50ed12b3a3033e4507ecc3e757f692a83690f9a322849aebaf032002678947be4e322638e627832badea199502319a780ae7b043f5c7d92602201b70864571c04bb7d82698ed9e71d5b5559ece47d0367ebfff34a14b55dfd12e8c4ea51b6ab4cefbe5f7869e835d6651cad497c0a4cc7f0e9d10c8c1a71e6ef35a2da12645004dae32f0d059e3dad3951d9fea9ec22539afe4a44d08e700d17e3f13dc98af6fc32243a8a967a3d86fc23ca8e7cd5b240a6309efa72816c57e99412b470a33826280dbe18836cd3cf425d786835be1e3a877c88e5179c94d28675f8caa9656aa0e584dcb3ffd7e0cbeaade8c261371f36b7a2c34d4135d36905eeb9cd48da2306319e6d0c13715b08533b64021c89b1a5f0d49141aefd15a4867d04fcbba798844f0755ad9420bdf378eadfdd206c8824fd94f5081fcdc6664edf426f548da7c89e6ef0221e621b5c008486e47cd9db44df5d8d6975958e60cf3db0f898aee7a2b3d4656dcb0f16832fbdb2d789ab8e9ac9f577793c12c1ad64b9bd29cabe182a83440dab1923e40adf11dc636dba605489d50c1030b238b0d6315e56c7312515161f2eff86d76b86c5bd43ae8b991ef01ad9405c0cd135dcc0ea3fcb7ab011f8c82918b160e37d25ed8976e6c56f810d236153aba2d67b33937e4cc767524ef036405ae8814708af44c1f2b0a95e326342456aae18730fa4da64353e734ee12c3e127e9732665cff88abdef4d507d96373c35673837451de27c63fce82304b3633679f8b2a2bb4c7b894a0cf3bee38e8231b56fabafadbc8b750dd18b9c75fc1b7322c15c9b20519e8db606f601c0c08d0eff58f92a046534ee495e9607eeae1ae3a3423667d5c5138e0735c91e6054c87a63a224c9f86240dcb1b58c8e2b8e5da4184d94e1edbb5fb6b4900d914729cc58f974b9fa50c45f81d9ad3366f6702130144b4829436a71b1db1a81a41eb7e8b45296c7d0ddcf6aff65cb5729f28d49c60e07158366c472acdda457a024070bbe9bd23499d6b839bcfbbc59bb27a76a839691f130768295fec23d6dee106b122e97194e02a3ec2dd1fa74df62de8220fac6df39f494bb8c1b902d4437c6fc95b62611d66e33dcf1413ab4e85b73a65b36328f2580f971bac1f2af60a35a87378863549dd21925583a8a487b14c71f4288d56d8b5d384384b818dde26d36b3ec77bce32082403781f93116336b8fb0415cbef474711c927388a55acb3c693fd12b540314aabd485a1cba97370db4a8cedbfcca3a7fac99bf36019e2420fdd5399bb1e9b5012fb748256b3ad5b80c3cb1a7b169c29d0d0178a2dfe4726de4689f55feb89e0622d5d19239e8af25b0665171f6d97b3542be1509ad410615824fd244a988f68989d8f073094608b232e387f2674248652b5c650d24a8caca91131f27f2e0eba6658051533f71cd11870f3c84d863808cf4a6e631f73c6d1367a9119ba17e3fefc1bcfb2c31b10ff2dd431b0a780245d27e2fa650ef2bfe1673f0b88319cbbcd11f5f5b1c044b719de96e012ca5e590aac1b3c9111f242414176e9a0a38837047714668133f272eec12f42923c72753892ee28f54b89a5bce7019084218168efee298b37e25c587617e10d6a506c8d0bf5e18c587e26d7f716e2f087f98233abbb70bcb11fd60a773510d2837ad6b7c497e93f02ba2c2b599961a0c7d9c5241e197515467d67e73ba44923da43907ae600e538e7e8185fc94ac38ebcbd60991cd20c95743722f9f9d8b6bd6765c859e16bd83dc719f91e78b3d02000000000000000000000000cb0c85a8afaa9844b8f9b62db4dc8b971aeed12e03026afbe0a5c4801821ac502cdc95e7bed6a8f7e02e7eb744c3a800cdf4fcb2e63ab5e74941335d026b2d86bceceb77fce18d7c643fcb6039ae02654ff78cd8aabecae54426ea48cc032dd900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eba640e740704bd0bc8b1f3169262934e11253590055ae0ce796ea5b879b49bed8b0a52a006b3a829e39b60d0175007b49818c9b0be1aa748074747da296e7fc36b68667c8718ba7fb8100299f9b126b46c30a6861e59d3e820a95e423cbc52bab3346c15f171e2868aef8d0b1fcaf391e3ea8bd26976898a6781534fd5b8e2d031536e0431a94c018e79d891e510cbd35c1641dc16da57b02e088742ae8da84290206348ba6941ae9e4e3878c71129e441553ba0722dd60527df9abe1713639f6d70b08aef0f513deac16d436cccced8f44d58e6c9448508abb1a269230f25e997e74ec2090c9555ffd51697afcf5b83b2e691182945e9e4e00d481129114a137bcda0226f177d29421c583471da3b4fb93df0ef1821d543bbae6c3bad6e03b341677c8031c41e3979502a475ce79aacc2c858e2fbdfb3aebf67e2b838677004334a5a5050328892176a42a1c71f48a3fdf5492070be9beded8315a0df76c91ee067a915138021749461bb7e4f1019b61899dfa524b4dc0343a799381bb40342ed34486b0ad7c0308ef4423b7ea636a306e36ca31ddb167ff315121171bef2790b0c7f6767b8eaf24d7998e8220605fccec7acfb2ecb28b91fb1dad75c18e83b666c264b4ac0557f7e82a2a18412100fb11aa6868fe969a54d251b8b6d571126a64fafd8a0b5c78901f0827d0a3fc55fdc23136967f233c1d366939a1676c9a64d4c9c76e5283837e797d018da54f1b2f599f8b4be9b75cc134bc0e6ca22c596d324bfc3d7fa316e38980e712cac8859aefec82de471f29e28ef707266d2b5407e3507c8d5b1a982ee7ae000a8f90fedd4926fc2dce6e06100eec4304c192e124332eb89594e8306382eee4423d345b89e65b304daac21c224e777fa392809a8d86d8798b7e7a8baab63436c32a381ceef6ead6b978e3d412d134064e76f8a6b530d252514651dda077f1822f14f7d7a0deef27ea7a30ef819feaaf3e614e1ed7b6b67f9f5e70f16840028a9a235a61de82d669210b6685bdbe6fce056f25790bcdbe8ef9634bec73568653af778858f0e180798709fae241bf2a442b3181a52d0dde6ddd49bfe0bb40f99034f965d1a08b112b663295f8e38d8c3022012eeb3309dc52d278950e2ad967fc1237f045258d164ea576900d7ba3dec328fffb1e5f9d35acfd6a74504d63fd69e7aad5e72899c7b19066bfd4c1141b81bf9e6b50be4eb20d794480097d7c30664117e42f79520f7171ecaa80572b56287ae5f88f5a48ad9521056d3e63271eeb91246a2d3ede7dc5076f1c886cc3968c6da6f56ad86909eca239652ee6f06fe09b5a77cf9f1e50d67266121faef9160be213a949989185fb9cd0822a0312d45f9e95040f4aaa75ac90e6049d68117f4e3ed71e56e889de84aa16032db09607ba0c8099cffca2727f1e9455b95c176178310c8aea578c658514a2ce5e88cb54e528231b1593caae8f5ec5431ede25e7a290c98522f03aebaf37da4dd1e075c62248c128cf5c75ec56a5e4fefdc196d0a37609f9eaa6d628ac9b930e8131132f9e51ef33c6afd2a267554ba42ebf478c2ef66206017b4b3d93d2ccf17e628bc79f59721586113f3abbf2f28d3856235324014c71c347ac366cfc58c053bc5d1d4871310b452414b90fb24a24281c678142fb2214b9e0a06818ae98e88b7ae519ef7a06cd256e360bd2a406855013f561e4cc31aa313a6a41bff81920473d4a7145e946b1f26eb9849ff6dd835f985c9b9ce88c243c6eb5604707cb4d2b46e9e7c36f9552c87de54ba9c6eb8bc382f6c1da32d06f2a5819ee3bd1293fa294409099b10f305abffe9caf9d5d9436ed9c27a45fa4b6e5cd61c2978abc243a3e496f1c449ef54abeee420d57d101f897d794057687e1724025b92a5bf9949096a05913040d1d9d837a3541b89092b23e84a3618c297ad8c81f106de833671de9905037e8bb25c086e4f54824c88525e3160c7241692c8042047bf3e71265b341c74da14493cce0aa39a494e97b43d46c16247c56ee46bba52ef154f00de20a80023f12f5d58ef27a0288c9e0e2c47faf066e3684aea861306e87444e5a6838d35cbd50d246a35bd43fa90baf20f09a549efc56379d41050e048fde3b491adee61e28405b8b31cd1e35b7eead93552647521d94db2996e78679bdbed3dcfe33140320b980d9bc6c89d994e9558954d23fa763337f7d79556b62d13f738dffb3636a57e941a001491339c854e600e9bb42db9342e8b5dd8dd1d7f80f0d6b0858375f91cea06d3fc8dc49a61563356d9cab30b9620d611729c51bd5cb38038e43c91ae619854516f028c053a9050fed567eb1a8803b093c115838a1d5630d403fc90dde5b0136cfc1b21635d27294418e77106ba4e84f9c0cb4771bb4ace34d6ac53c1f95f72fc66f6a6db9815ede92cef60a", "ac0053", 0, -1903954703, 0, "8c2127b3ee43738181ef4c4cff3e2521427f60f176f8ac8255165dfa88f0f665"], + ["030000807082c40301c4991b102288778bdbdbedf423274f8d47203962842681fc87f5f1a181df64c50000000006ac65acac526affffffff02839779010000000005516a53ac51d71bf40100000000066a5365636365a23571beb53934f6010000000000000000756d5b0100000000f62938816000aa14a3e2d975b5640b5ddd47321b3de2bf83a9a4d6dd2243b0e852a116f1982acc41efbcb8a7552723f5c56be6ac22d3f026e6869212eda73f0ce4314fc9d14a91a346da81678b30c68b81964e79b7a0dd6265a974d713a3e9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009800d48f83cc7d95b8f4f8757e7aa6f0a9059fc7314d5ed81f29bfb77e15c9929a572e1b5305fcf007fa76226c4c99febadfef244f336921294c2ab46869ef868a1a837b3078947e34746670abe6792ceea2021dc8ccca4b2f207d8daa45e70bd81341cd029a66cd84bf7a965039fc6d60015abc7b7ba5711104d20de51a090032a334fb532ca72eb4e35e769e757b1e0cdaff571d8ab7b9a06ae4ffbbf1cb97403274bbf79d5546ea1806396eb3c7c8d99757c5662fb2befd5fbe8a33d6d665a0f0a07ed55ca233641be19a5ab5de69f0033850c3ba7c2fa2c460e48af287e66245cbd335cab7f2d984aac5068d557e890554f4f98a57221dd919f85f445725e49c4020366deb89d3d5792b76c99bfac32c3e96f7436ab66ed31ec9105f9b4085a1bdf032d9f45ba9c65b8272c6687cc3d179de60d6619814c0931b5b3a91bda32c4b7d8032bff49a62f6427b2c3743bf04c6768ff1e25d27a16510c93503ff732dfda1e3a031c7844a542a688b049e006e8fd93e6faf025b0f34aaec76bb264a2afd4837291020ab13480c75ca27ed9b7e80e6389bf9478f70fb6c81ed014fb3e7114419f374c39bce8133b38b50c241300751f72faeb87826ce701fce5e214df9fc725922580f8f2701329f4d9e54bf86409ea6b65e1f8d71433c493b6c5fd4fb3a8e5e6cc4bb7fff9ad6e09d2080ff8b22d25faab774a35a7484535c87288d35e823d963b29e4502ccc3509c62af988604a9551ffb49ab5d1f9e9206635792ac41d275a790eac95c16d3126620ab66a7f85190dd3073a09488cebab30ae451d917462b138a2df1ef575da0dee4418ae6767e1de47d612e3c92b48be0514169f0e17b55d553bd35ef55f0ed8b70816f80d108b48622572978f438ab39d6a8ec7406a3b9ec25f870f56d9d488e7c335b5bcccd5477d1dd57163443dea611f8e330d592999f5ba184888f4d5291871790558354053410ee7ee43ed72fb44ee5c45a9decc6c67aa284eab5cb9924ac822baced87dcc20cd1d5d8f01931a529744b1ddac26683b05825b193750572833f46c178ad74cab6b72aef7dd46e7df4786ae8a409a0c34292cb177f4fde172b46fcb01dd174103367840c9c194d0635650f15c05c90085f5e016bd822c51b168403573371f25bee6495daee6aebe1f90b42b28302bccb081c3efa7cd815ae8fa42db63a0d24b3f2b1e441078dc916ca00141ae3795d975bcaa2e66ee9670d728f33aabe4587a918d94fe9dacad320f1d619c33e2dcf9369fa3ef6ad4edb25bc797d888d91339f9d5af1258045289030cdfe1e33b3708a3fb435ce115d909fd515701320529ccfd35610562fc521999046c7e3061870f815f968b53d071ea1d013d6ead7890179e658cebc26cbd056cd61c8ff51b38667362430c77bedc14f2381fde331243cb529c54c92a4aacd304e08a349ca5dce6b184793305e523210079bbf842df1588df66dfb6b3adf496da4ca6d8292978611ce8aa8915ecdceb78a58fbedc82e3540d042fb091e88a7be0d30ebcfdb54cdc3e869bac325de86238faee08185a2936d6e6620ad93203f4d8c855536ac0a8a343bb662233d24bf4defeb16bfe80ad0285610edf72bfd294d5dcd5814293e656eba7c5c52e0882b0ca59422021a5daa039d2017f303f04b80438923fe1bedfc1166dcf5491fe9b733aaf0311147a49da324e2c4bb6bc8c7f8258186400a835fd458ff690b34a2a953aba8f42f5c6aa2824983bd42398a13180a9a2ed508c8e43bfee6ecaad4077937ac5e18830a404efba66443e270e686b50625a0a978f8f594d1f8c89dbebcae8f6f2617e40755d9df0d1d17ef2bac7728fd5b8c1e8f93555591d9afb868fc8d586c667e6d4204eea3eed0b783277767d08c6df89f64a07fb78af7cb47c4eb4b877df5f92a1597ddd0188d2815b3c2c2a00bc8b8c8c17450901d52f2c3dbbf8ac09500d0535f7eb5d9479df1f60974b5e8ea9dde860646a43e0fa1f5e4080c159eaa1f9b702d6024342e79e39eeb9cf519e5f861ce651b35cb4be187a81d0147157f2a2562f6dadfa36aa775dfde5cece343807ecc591e8a6f25a1b17839b02c702f3f036e3e292c3ec5818e4655078044955ae9378f5b358c693dc25387bbe21c5bcef59c3b1dd4b2915817c820a7efc12d4804f4060dad5ca91460a6795377ed2c20fd216008755e5b96965190110080756812297582b27cee6f93d0baeb4447ff3bcad75df29b397f51717e625a196dd41b48c461dcfd18170274a020471ea9908a4d6c62f5547ccd97453b654fbf70628708ddb2e98371f5c853b299b7b7d504ac43853db8518dad6628cc333faaaef697d5b9786dba7b1f0c01ba39c8781b7051e1327a8d69ae1c1e810d32cca59f3e65c1497b15ae18577184066bbbca20ff02986a8805f92aa258107", "", 0, 709561226, 0, "fac2dec401fdcbaa67aea35f97bf575195e0445648537b935a226d941e9c766e"], + ["82dabd07048304632d14f3ed51557c59b4ef3f89a5178ba793b667ebd27fc189d301d73b2603000000056500ac6a51ffffffff3f2932ff5f3a296fabc21f7ded3f912be1cd5404c136a389001c45808e735e3f0200000005526aac5165fffffffffede4032921eebc8239eab11817cd0dc2e2318e8e6d466df19f488a940315cd90300000000ffffffff3b545f52b8b0cef665228ed23e8b9e926e75960710295750ef372d4ecd64aaba03000000002b01f3f30412f8630200000000015182ee760500000000056a525252aca5087900000000000353516a1b1b97000000000006ac5263536aac0000000003000000000000000007eca40100000000db488ed07c2a70d3cdc5462d9e5cd2a6750dd25ac5edff13078a961b97a241771a8f585422c843dc307806e7b844f68cb62bb867c92e2c6785539614080dd32d494244b6ed92ff5a17fa48d171b411135cd95014582ebb5da4d59c0ecce29ea3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001dd593806f0248201a3d301241f43497f8b1debfe6d08a1959ddd31082d1265f34df90b50af872ab26e3cc7f0eeefe4c98fb1cf15bdc46a8555aef533f3437dd6fcb4e6eb71dced25ece07eda51304a2584a2b97abe547f4545f0d955279fad85d5fdfd04608569b51792b71b92eb267ae5ed0ec4b582e3ba73e0769465d7340020a20ada02341b21ad7235b7acee3b25224ecfb80e751b1b08355b179330e7989022c0af29a310cf531736b2505254f7d7ba8c0c3433f811932324a6c0a283268460a02f8df21c2ce500b08ed247ea3b5349e6bf2d97d4733677e232846bd06b5c055b432a6ccb3d87bcd75375c62e00b92b3482b4abbbe395851d546264c2043841f0207aa16edbe0f000b86a18c308ad0b5c5b0d3310764f9f1f8845b2580d08314440229a8bcd67e780067649ba72515625bcded0190743142f427e1dc7bd81d9b24b9031aed4c18c01ee8376aa80afcb4337a33291a0e29ea22bcbe4f0d1d37a94be11a0210571fbd54d1cdaad5ead36fa9bc025a587f95980d3db6a12210a3563a088c9503285acd281adc97e3565ae6dcc557843f4312bc8740f201ccdeabc9b3a785bdbcedff4308da59f3428f6715842e08da5c3ac75d46cffb1886435e804270c4de26afaba93d5b8d76737db0fb29373c92b11e972e4a3ce6a38ec60da5da9ef45f523d04a788df4ea7beaad3ab6318bc1cc9ca39dbc8449d3747d3460ebc9d4e11df21ecf94039e6af28539e47e45e2c994e933efbc01b8ec214879c485cd3d679ad06f4d03964beb0ac1eed1105e8a0f4dbdfe5d9a09a589f585ddaa3bd4ee442bb81afbbf2625fd7d4adc38b7755f98e80abd8ce0ced62c124a8a6c5d9d22faeaed0839adf715bee06022193c9e87ac6a9772588097857a88528ec67bff36d3701d08e7013b0992d9e9abd33b8ada5140887ef2e154df63f174de41ecb87eb506f07d1d8dda76f1c5f0657c5bb4320112cb08ed88c170e92d66bef3ddac8f54df1e725c434f72db4f6ba958d130dfafc1f09b4873174e8f084ca94a9ec76c382aefa05b274e31c5ee09ebc593d01f7838b89a5632adb673fe52c59faf75043045dd12eeb80861c3f1895ba3c50e2d91416707708acb6e1c940005eb2e5e972f975c54528804f1cde02472a564e8392d9f2955cbf7394ea4d0136809e322df2caba928dd8f6cba0c956c7fb3cb46f507efd0b89c38248379b1d117345e3dde3b5c41198e794d60ad6fff2a51923ed52c77270f9418a9e2b7c5acee424047a4b3185a52049e354ed30110b1024f335fd4a6abbca648832afa43d52a9f9e45eccbca46c2644c8743345073ece35a32a5229c94dab069aa73226bcd3af72e149e23be23d720f7469f0d6ce21a97cf7378e0d019f1f30c14ac940e631682bfa6712f428cdacd80ca33af18bd791d02c0e29e0b7ba55e0522ec79217a7a48284dbc94284f271a917dda6e75faeae7d3873814a0a89734c5c842aee24f7619b87cda64ae3560abbf59c776bffa309a09492fc12cd197e992c13a1eb6cd5d14e6a4bd8b1581b8615d7df4227ece762fc1cdcb3fc96efc9552fefd6584d469e290c8184bc49d2d2e4e4ee13792af953720f0ae75702ecc77d937bdc50a7dd050f0072c30b611c69a7a8a2152dd74dfd1ea90afbc6df837461fef6f2f05d31dfee7f252fe46f403222bfacec56f9a66420f101d1b57d337e4f8f60b40454a93d664dbae9c213cbe1da5f23919e5e2f9082acda466392cb6fc1f4bfeba8bf988792e3902a0049abcea01435a083c6257899458875b2d0ce44932c7d59f0c7f23dbd21ec61c4225c3a7e7c3bfaf1a5a934dfb6853e077adae71bebfb37d25ed13db9e2a7fc0c25abe4c20775f68b1e30e7869f047bf54ff3abb19d330f7f775c8e2d1c93b60f4cdff178018f9c989278b15b0eca061a45ebb81075cca761cfc6abcb11c1aee63b3a449ccfc27c5bb99533d70b42d836a728dddf69cef9b27465d2c28d0b749999333d81de4b10dec597bcd3525239917a692e6ba8431a8796d64d1504b0172d0b71bf21ed50bb902b0abd4ab76364e1bb818c368553a62083ef18a2b170a681d69a64c4d3c9e54796b811306d932065a27eda3d14f80b4eadaa859c4178265781e26357fddab1f6ce3376f497b06c939395f1a40e18d291a380522a3c461a955ad462d30b0cc22a9d121e48fe1c83286eb1aa36ced9e55b00cb85f986a6b1f7192aa5920c51d4c2eb23d4a736a9fc14ce1de5412f25d7fabcda835f99720f48d8150841ee089c68c18c2f7427957c6cac10be00000000000000001f27470400000000113df2714b44c0f07bcc7ccda87638af7d7768f4e93d38b7d86d24f9c21e26da3916ce1f6d15ab75c34afdf51f832bfcde63cae7197970f70f1176ccc42070c342a2959c894a6ef89b028ebf450a93800aaab56642330e5b9e5c9e588f54764100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab2afabf5a0746a81cd446bdcbd7c0beaf8ceafd87448ea683569d5f239a7a6c07dd4f6318d4972b4b0e17cd2578159b0023adc0beab847fc393bf3fae53c0e4e3f20cbbef60712bd29ebf22fdc031334d4f3b58ac5bba17ef4319693ce8ddb6041073ea1b9cd63e1c96420b35bdb5a1dd88ab51b7308c4e724d6ac49fc0f6c9030c5ce87ea0cb7534bc8929da31904fce03d151349ad0edf65f85dfe060ec3a47031a635f58defd5fecd29d220238418a7c1605da76dc9a2064878599262058ae200a06d49215a82648c14b789572bc9b4430b3df3f06ac3b116246812f91d9628358532d4ed0e0d905415fec29b60216430169e6fa2a8bd9b654a4aca0d2b094a54f0207a09f96ed59abd7c5506e2540600ef16d562c8d9bcd91e5f919ffff84117f43021e2cacb817bd6f7415af49288aadaa076af9c547eabe6573e40520214fb4abdd0319c539674127239f46885cd10a7764eeb7b8dfd75d15946dbfc7a4c18a16e8aa031bf01fe1a1189c700032c31da11f30395e4bea6f52e59e8a5f3b120796430dfc0202f8c56e75d1cbacc8fca186c78e0f40a13ee061374b42a02666a34c858d40a9e59df991b8feef51fbaa1846ccacc0bab958e1aa03a1e63e7b8d4fdc6efd2a53f0078e4c39c9f81beff0bfe9b73af6edf1520981701c1b9e7b8911fb6ac78c96c22a0f041d846944dc39f4a2868dee175393a2613dc57abbe912beb8b22aa279c32f9e75dfb09670c12a84e97d4a9ba0c8e8a1d9ea5785bb31038350f44826a1441794b3d81afe8f8cc1c473327450aff1e930eceab8de2cbcdf4e6ad40516ced3401b7110d3f57534607c50fd6055a386b2a2e5e67429881d6540f3abcf783074ba678eb90983fff841c25e132a355c7d283da3c5e86ab0e6a5d43c43600c57f37a43f4bc7b70798a080a18075ad7ec9be80574d8540a3316767009bf39f73162044ce129324e2063abcf1dd9b05d3318071fad667aef5f8429c6e3fc5975b3513840f2d2811bb285e5916fc81809a7b93be5fbe7e7acbe4933cd7f09df627e25004a2b002c65b33329103ac898fa654be7f08ad9b35130c923648a4d16605c01e2e0965a9ff05cde9b01cf45412df85369571a1030f18bb7b3c495178f230b83d3dba0ad1d28f993bf6acd86542ddf88a9ce1e158d0f0cecea420a2fe823c856401fe906ff3abe805b7b12e4e247d5af679ac63b9dd519c398946944aba606821ba76e6d935286f979c56e66f8ce157f974edd843f3cc6d40f6fe9f9d93dceabda975a64665906f1a543a0be0c244825701c3527b6532dfe19911373b765f0faa835304bcd256eefd8a47afa7f1cb36fa4fbf163fe720e7da079a86996b6661c461ea3dbc4fceed45e91033cda4b9338b07291fa7534cc75fb75f7e955b43a562d860df1da4de9c0753005b467917a3d712c2f511b49a89993188a6f9f141237b4a9eaae5ef905845f83a1ed7452b902481d4ab614c132c29a93c73dfca9798e916069f0d3ac2978a97cdbf742394319f42bf9b873c8482bfbfc0c3a085e6796b4046e6615049fa453fd5b7cf17f33a92c3e894645f71fb970f7bbed648c94aa46bccb91405136b5597427942c8df318d0df2f36a1753f8942cd19cbd5c64457b85c216eb2219770a98c6ef45eacab5d2560a4be2f0b778329a2a66debe965a19e758c17c4713cfbbf8527ca26cd4ca71bcfab944d228928454a515cd06c7a7e07ea096696a8620c6756483755cda3a0cd028f37b73ade403a1a594f4af102aa718f2a84abf6df48e8c379abd66c17b5cf2fed257a797ccc67ba7e3278d7997afec71cd16a3788da72ae222688c54e50ec468b43d7f46125e7c99f3b836724f532cdc97ac87c75327b532bd01bab5c26728a909d6c62c77575baa5ff792b05a851357bda1abaf04ae2743b1b81bbc3ec6a44be4f4f6cbbc9b1d212e1941450fb83c4568b6bcafbb874502b15821a7bc262a99ae4fcf4b8036d525433aa3492fa898f0f9b540fbe438f9cafdb99a0ea040ae44bd37066a6d707c0a4eac5df94e1b04ebf24d26821dbeee6c8dcaf2a69441cfa95315dfcfdeffd88e3cfa0a882a7af0adca89320e856e039e456509c6e75205ecbcb2e7d00d983b7f10db85655c7df377d8e7960339ba2da39020233604670aa4d1665bf9484290ccc1519d480db07a8aced82bfe586ea859511356f65ef1f234f0cc0a74d0ae8f5371b7b30450726cd4661c69ac44eec577e21e5960150a051408171884739d8ec6b99f80ccc7167960c16fcab9447d529f2971e724d519095654f00000000000000000000000000f68be2218d48d1681711bb7e42841b973aff65895ceb3048ce161c929e042a1adfd1edc4da4b6a1e12f93f289058762e54914ae464e38755967f2ea5b9e9a38509fe8e4d71d357a21f3efd7e9ac8dcb3abc9b3ac0522def9b78cad05e2791dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087f6c2397292f6135b17bad2525cc61ac7144b368eba85ecea3cde8eccce73914175e33841cc305222ad1e57029454c5cfbab322ad7c4dec080598bd7a802b4badb8d07c18227e7ec6fc0ad4e583487079bdd0aacc31568dca1d15f8f1dac33c690f0047827d997491fd6f644c177105cfd1f263784461388ebbb69b21e3aabc0200e360dcab9937b1336e4bdf21d44bbc05c5220e85d26d03a3c6b6dbcc56f617020e442b4c9ab6232fed1a345954a8194d0273975e4db8259091c3ba7ddbecbad80a03fa4421ebac94beb8bbff071bfc5e3272f746cfdc8ebdb5196b0db0333faf2889842b95246443cd18215e0ea4760553e17d05f5a21da36d3d0368199f5f83ad022d9e838d695f4d6ef5e8f17cd57cb0d53ca2eaeadb171b09f499a704099b599b03298d9226d49ad675a6c05312c55f6ebaadaa27cf72768df9538bf3d596abf1030314309b3ebb8e12218aaa7af49e30d9079d8ea56c58e21a5eab5699102331b4c003154d3e2f707f7bd0df381593068c74b9d85ac90bb46b96055cc86d0c638bf1bf03243a90b9d4253532ec1e41e3b3a0a50eb6c34dc9f0f303310c3e99a72be88120dfb8325a5d0a369345bfc318e6a1e8294dd9b5b9b8e177347e39b6c9849b1471f737f0292385c6a2695dcd6ed165f189e064cbe99090c4a53942923588e48670edf813b69a34a2f3186a03641dccd4402b6f29436ccc172433784e7e67bf1a6b7c1b301d64c0f034802f44208f993309cc262d933737bdeaea4202a5634a2f87f570d981b3440bdcafabd3a14e126cfcbe6b2b3fd8c8fdd361f90c9f9d381949e4b320928932f20d7878ac355b97fcb5a326d7e36393f95b6efe7f98ba1569b6919daf6f3c644e16e44e327d14ee2756a0417b34f35d51843f55123088d4f5c9b50b9aa42a2b8b319dbcb3d803ca4ff10d4f094aa268b995e8808726dc64f86a30d61e2b886f14ca53482073a9359c555c82f188a3c0c30f198a6657f1165029679f83d4212dba8247bec87ee77341b819d59dd51f457d30d4f3637fb890aafa66bdb1d359ce7a9ca13ad5ff35058f899266bb7950dd903d648e96c4ab012a871f94407add72dfbaad9e1253d4044f44197cfda8780e36ced7a0466df3772594e511b16884f902c2ae9c0a6e384c81c6ffe8bb3dc3c62bd8a4b19f3db6a041dfb45abab611119021c8e27d0f2bc8c2008d8f75c2bc2ed5d28bd54acf84f8b2dde0be4276807cc6d61cce60fd51498c5f443836d7afe180bd19cffc4f2b852be017a3910cd37c59b58231f67c86f84a3f6dd87da5c515e1f41616badb595468468a29e31afb65a4b19fffc75f99177f0a4ef7abf069e095a122c7adf26dce1f5ae07d4425a49958f48c264a96052100842035338de217c870a31ad2e880ac22b24204f824c0ad99543f34b68a0774162d0a9d132d2b897aa6c0ceea87715c4733e71a8a8df79547ff3158a865e6f5ab5e0c9d893a0c603dba1a35788056e4877e4d5af22d442cfc9d3320332dae01d4bb5af459d530813781f5c3f57dc7681854942bf0986fdc2c9b584ae208abe990c0e2c08bee79a3d2dc125b93fc5a55e2f6a4d3c44d3be3c796919692a3b0907b0aefacafe9348cc90e46db0ff70d234c9a183a47fe1df509a3d91ae5b42e11b98e9efb151be7ba670252f4eebcdc8b341e16125094180263291e78d4b0974a0a6504d4303db9a31c52fa70e9631e10b3d182dedf03277591d26b14497e12f91c20da495035011ab50cf54d0dae365111ab7e2b5ccd2bda488f33db5a7607bb954087371bacf9e300c0a23c074358c86fd186fde37bc9b82b9523286e86a2dd89f90f396948becc375f0fcdaaea029929e782baf5acec61e5a8319d5c12506ac860d2dd57ac2325c8b92b1b5735814d45105dbcfb200b5899a804186b2dffc010632da16ebde4e067f6008d18d60e9cb659967e3166220a6bc447e224b86c8bad525c7bc77c07a4065faf7acc50ab208520dc1196d1b230897b2fcdaaa8dbc572b612502a374ed52ebb31e08f5591b65b9a77f7d8c248c56338f45d15daf9fc2186f1e7169e26a5d7d0b78248602c331e5c8280c7ef8c6819b465c155c96e8c8244416238f5b76573c3a898ba37857161f40a271ed89a0af25323ed7b01661f89f03119ff401bffb23f4a13d180c6872142ade903724450865925ab6c280103399678cfe9e53d034c2fe54e9c08023735d4200fd0455c42816d33f134564104b4120961330d07068d117292a61050f63f88e031009eae29a01df39e9d39238fcb84df4df23ae4d39aca3912d8b1eeee20eec49a8e4725bbd733425e78f53119784a6557bcc4c0af4843ed833853b01a093c74b2f3e76cde3dd83c2626fe8014bff4fa23b9fd962dc951b39b267696384494da045618182408bfeffd12b28719bddf5c0d", "ac5263ac", 2, 1903998239, 1537743641, "e1a1325329c16cd46ae975558246efebf2060ba29f27e4133d15258d67ffa71f"], + ["030000807082c40302f204a7b43084c2a4a905181f1199e583b88bfb0bf319c21a3b5a5887a813b5d7010000000963526a52535365ac655e210157a2774ae3310d237b3ac181b7e58a20427ad748560060d4be846a788ee2a75153000000000463526351ffffffff046bf26405000000000600acac516a0005934705000000000165bbdac0040000000002636ad0a8ee0200000000000000000000000000038796df01000000000000000000000000192a95a07c9cf9f737c1457cc762ba7ad36578a1cfc36f8538c9726ddbc589e921f471952bb44913ca105cb53b9957157366dd94948a2c939a572d869056aeac52a1e70f8074a634186cedd3218323bdbad6c1a79df1f31421ac1e0d597eb77300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000859e45933945f2973ab875c616cc4fe27dd0f10e6ecf6554e28a3fe1257548554a02e40649e46a12dd71b799ff603150f8b6dc74ece84ca9ac2e29848e9d9e090fea6e9c8b9102d09d8123b6120c7a30537a6c459b0cdf5b094cf4706871d00b92cf5f004333de995a60c877c015252a62a56c656baa92eeb741c6ff4d29bebb0317be14ae7b3dcce7775cdd39a5d33cfb4abfe7925f472d8b0c51057ef9736ba003136f7f37bd8d1cf15039f1b3c42d7dbb14bbdf3fdb899d12fbb710bad5e4fdbf0b019c17521f2884cd67c0c1bf57690bca154c6ddf7d6a50fb83e61cd1343757e89326a18632e0643fa1fc535ab263846dbf7433284c533047d930a299c397a8030207027db708fd7bfb6741dfce68181dabe08523c0efa9d4eba9d367629163700c02270d1533495fb4e7affca80fee38def77547f1d2400a59b4cbac490802458f5c030af54400ec390ebf760e296b3cb4d7977bc9bd3426378352864c27b18df446a403212f0ab2c7d2f867e120f6b77c83e3c2a7c3631a0242f1b166f13abb8ad0b7540326bc896690de9dd1c169b709d3b4649a1588d526610898d0f1833ffc3d4e877806ec5882fe9f6197ede1f2e64bbdfcf36f4bce05114a5ee483325c666bc668e24ef351a4ecfd32d7d879728b396968d620026f394167fab500feb75022af4254c09e45a70d1879521aa86a7824e56a41a4d0a76ea9f10e07d0dedfdf027a76cceca9b628863d171f4b9895f0aae0ea8b64e35bff8a435346d9162a76ca2cc63bb5ac43bc3e8aa73e00cc6d98f80451ed52828c0e771e4e46519f0a60d144a7c3d77ad5ff906b9253514fd869b8ae2fd06796b01843c699d402466c64261dd982a7a87ceaedee68cf92308f2e2a1fd4db21d937906870ec392dc302bc1527ed47904436c54e94578357fa6265730c02daf8d2f979c37606647baf0e58dab173a53d7ddd4460a8424c242a5229be55e3a37d372f88f10520d015bc0481741596a5a3864f9642603fe9f8782a9a3fba948c184603fea0e9615ed954dfa4143318388e508fe39cefaf2d9b63874b0040a05c1cb92265102cf7aa6d4d7f0760f9ad6647027963a1641bb1611b4b088adeeaced0634905385913a2ab33a846de715908047545cb3292f2ac826fe8107658d347683ccc131605358e501521fcad4ede87cabb2d8fb94fa199b0776a3a67de581d222d5bdc49cb62c0291d62e63393b570c5f2e474007bce5123a165691a05020e7c81183ce4d47d5d057a08660ee0afed91dddf19cfe733d8d21c609451e91af772fdab8bf72748d3d3819ec5b2ecfa604fce96564aee84d36b9e44745d7728f31456f9ff7de9a123ea95edd927b78acd191b8d23fd8b05253213c4cc0b8b9de95d76b6e31b873283b8c6eb56951bcbf9b6985cbd8e4a0d356b4864d469d573bd3eb24b0bd94b0cf044aedc42b6c4c4a194cb9350726ef7fc4c24fc40de1537823770ce2d05e793a7e33f67f79ef8322ed41cfaabefbf69df4f4fb2003b4d4be6aa9fa56f6f27bf564fe6c12c83c597cc41efd83f94086fcbafa026c099dbb1317c5523136797953728cb6ee6d9204b257531cf76e84369a115e83016c7d8c0585237b666880a3053a52e2e54a4819b1037574d6c180a966dcdd8adf5271e836e681887f9c297d8f61db972d5ec218c2a7c9b6f9f7adaaa3b78d44dfc4a9980926b4ef102c84a30e80023727a04feaaf99f3ce4670f1a47cbdc02eba3dd18ef71c8b48a425439b7b827b786e3acb392cdf0c3d67d871ecc3d431a56b97689ecc21c72228aa3f425e41867c1210d7ba9a90bc267be706f98ed6574552a0fc14cd1eeca8f42fbe20ddabee3d01e979a037f484fc1c0c2d537328733397585f926f8f214afc3b250a7f83b078147d67e66267876d703b934f33c1d4110740f0795628d0d75748b9ca2c37886575edb58713f409a1db0d196284525d71e5afba2513ec81ca929cb765445c7af3526fbb1697404d1117e4a07322c1f483180d06dd274a84cd19ad6e43762977e40e7961fbf8823b402be5a51cbb467ebb285b9542b6f20f89547662304f719e6932c3c06e2bbdf0159d9f8636eb58430e78069a39f8942bbeba2531ded5fc39d5e50c0342283dffcf5d750e656831cc76152ac9ef967e03b35bbaef0d46ff38d29803a84233ba75684b19bdbf2717b05b23d096d6454759fb1dc2baa29faf758f62cdbc1c544166de1efacc6c1b7202da5ac0f5646ec5ec21e69b9e746809d6e5ab64aae16459347c5235b37e91ea8cde02f8ae646badb2100000000000000001faf05030000000077409d1050aa834041bc92e5d1fa287921ec507b0470d9044a2a9c649106bced5be416faef72ec0d9ee7c5c72b6e0f825f5dca3e453dc25f00d4e28870803acac0b18afa1f31997439e79be85c09deb4127b07b29e441983dfdcfabdf4b9c38400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d33ec3c27a11af88fc71c55f040b02216ed3b54975d1c239dff3023a6ab6905c3ece9485edd6c4db0bbdedf309c7ca04e10ea82aef5c59690f6e653a71378ea115b1856dea065c624fc7fb48a662457824487c18ab06f121d35ee85924acd61a14d8db6e9baa0ac40f1484a9d6431c3458e13beebeff173e8f96f9a1c8d694d503094aea6d05784db6e1b8a6938805ab97cb51652db68a1de73ce543e7362a1a17020ce82d72d4028b79d2fdf1f0d2bd275ea4d10f48d5eb6cae28c0a2ec756c270b0b028b658c12361e7650b878bdccb8f5fbb072d60cf43db3cf56c0ceb2a52c499a55879917919da04da30af9d63c8a61f504e470aceec1e1501a5ee3615d6ed88b021e67197f097f416a976fc1c1d79b91d5653b6869c4df4832c0bcd217fd232dcd021aa0e3d5cdb7fdfe47693f7a29f07d32eae6217ad47a9e9e816a2306782d30b3030a76c99479d5130c0ebce88c850081bcc31364c7936b9b9cce2b9c402c36dde20203b3552372de857b6632e8efe0d0de6cf0efd2282ec14626238f8adb58a4f211032a033207b3e7a573d7096a93b8483872012f9e27038bb496f23e0af8e6a552e43d55bd1a9fa44701b665b5e4575f5b280a6ccbcc49bbf95a6bcbbbbcf8c7776a4c3e6a2cfb1b25bf47804492e85e0c4b9212f5ee598ffc0b4c00af5712cfadb1176e25ee008011ca9b4fdfedd773d5792a08529faad245a72da92b9adca63d64e6e1d7a331209da52b0e23a65133cff03d79f719fe7e54ad7f6b5aa295b4a99ed5928d1726c9f2af0a6f58229b6081dec3ddc69b8651b964fa217ca777c88dc51adc51ff8fb9f62c5876e81e8535cb2a892700a7f41fbad38c294488cf2ef1141f5582ef8b951cb1251481a5f2d4755df1ebe29ab38bb4ac117648d5fc812e812ec6abaf424f5be60cd4a398d3c74e1db80d5f6cc0837d1bb1a67c5c7962adf9e714dbdc08e7d29fbdf44ac49244575e01f7703017623007ea7d142e36d7c6d5353138b03389963fec964b1d7e33d64aa94cf7df3c15067b8191c2a4277bc7e6c3384ffc6ecde5246c09dac1f748ab7b15a581e64abd487010f96e22aa7a13d23681f71fdc1610e4905f3d235a4ac6146e4d35c015de26e484e53b081974772aba416634117d2775f795e51c5c539487aa5dd53c5e93bb94b9873beac81d29d82028c829750a9bc7e19b267a53c0d92dee9c540c9a6e2c92c12895eed43062cc98e7388d7d1bd700f88c9a39f89c2397b54c1ebe2ec5a82820fa03373df0ae1cb203892b108ccfc9df9f81e1ef8dbde5112caed80ef0c8295fc63c553f4995c1c6bdce5eff122397bedbc74e5cdf8341e17b14c1ab6af595283340deae4ff00ff1e6971d99939b6b667825506fd93ca5541ac45379eae50cfe898140c97e4daa1d930ca375f50694e8096dd3993d5424cf14166ba430e6989a4b8c37131374973852d89b6091c0a3a94bfcd019822657f00bb2f5b2fb9c9b23e9b724003e98f073c1a9c1decec8b4e3467ac1501bb2551d095795a09c03831639f6a610dd9ef3a76db3f49807189723d894c48643b98a8537c9f3910906b085d43352f4636655cd9decc4e776b5e3a4469401c625a90af6cb5098c54db3cc1cd30a340ad03f75472e3f83ba99ff05a9e9b4269f00953afd6feb073ce2f5b66905bc9736d27f2dd4a29ca6f7ba0784924b009f19b150b5ed5e4af964b7be4d4cb3189beaebabcc2811b3cf1d390985d815153d820ca29e1e66228333e45cbb2e3fdd5aae771b17dbebcdb5984e7c6e4b062f96194d934272f19a7059199fa39341063cfff76a23c17dd0e79694ab610a7fb7cc75f8b854ceea20333fa5200540c4af29afd15b2807532f9b37ca93fc5f5332303d88dee8c5ecee20bdb73eb23a9eeaa113c7098f59181572b9fb533ed3097bacd9fececaba0611be113172ec0f4b7596e8f3e0e97dbf9c185a53c057ba79739faf3ed11b08d352bf0dadfb56839a4eeb325f6912f4636317e4b001bd9be1fb69591efed9aa2257331ce00d85f3cbccff121a2bd7f2d8dbf6fca11abbcf8e6f756feb5913e69a916e5bffa754af948baaef11d8199091f688a29c150a841cff281d5286fbcad7a1bc36b1b906a823a10fb138b4ead42e73b44dbc0d28bbacabb29732f8a8c52eac508921fc84bc38dd7fa5a2275d6d987ea6c41847b0d7a4342d4187477270ce4c56d3aed82ea1621a9cb32f8630af876c837415a77a54396842e5fb0baeed315b5a50f211f096c4ab332ff56b25679fdc337c0dd7ff82e2014a9eb1f9ef924a00000000000000008a9eee02000000000a2ede6003d3f0b1dea5de85d9e8b600041da0683165439e2ab7c05f778d30f9a369bbd64f2478f88cb04f5c11289739d9432f50eda87256e96d0edaad1d4398b097cfd2af180b48672529a4c588dcb2f69507261cad61d80e42c6379de643b800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee78ecadf8e3deda93e5ff8d3d0f61c90cc0ab7f091c3bead3dab456881e3ac0ab2d617cd536291724cdda4d51191b0cc51882bbca5bad7bded420257eb4727bab7d503f0ce3ebfed811d0beae61938368d574cd006dd29553f97e0a9d839348677e11b1f10ae82592f250826440411c70c0624bd6a9677fdd0c3edea2bfe39b0319c5fd73074eb924fa02105eeef35e8fcd7a29b1bb32a3ff883eada72240a91b020ea834e86501a13511b59bf960cdb1af0ab73125eea229e7c0d8c3b3d2508b530b079f595c356b3b3d51c30fd7bc226134bcf83cfddb064699a943809057d3939652479a9f5592c461b5e90150680115f64d940aed5a8a559ba1824b6fef886297030cc8928fdaf7b7017b46e2318f80979bafda51dce88f01c5105698199055c436030f324215808be96ac0f1f50791ecb36c52289917d11354a320a2069a76ed8856031f63eb2e7853f35eaeb65bb4d59304a8756bc1bd85a5b11ed1b496a525ac07dd0315a89e3c3915923c937d3ffe3aa12e2fdc59f4d55b46260ed5f82ddb743ec111032fd0ed1c0f46aeb69113f4dff45c528d47261e95376b9439efc5a85534384ac432c2131852cd9535956bdb27322bf1417da538987c7d7977b946ddcf636612a94b80bb5075dab661d84dd8c70d32a753ec1daccd88504d2d09986a858d0dad2c962738f3775d916ddaf99db26d8ab66de9be0ffa90409498e1a3cdc348c1f44a67c4640a915dbdc7aab593793b66344b4eadd515e9a64be2a3553c93e6b3074112eed923364ab9740a1de745d5019356be8eb0cb6146046e1aa9294e83ef0fa1d9b49fd9de871f88bac4cc7413192bd8c70443f83f1b57d8b3c5cd8f3a4a4fb04577b85e44cc69daddd60b4a110acfb3fea0822d3f2d73254982d61e37ed96c0677304ef20bcb969e26f3e53d6a9391db13d1f0aa76d1e042a2d4c448fa1ddf2448615467b658273823f65db363f74bb5415b83f550cef7f55e4cd3a16f96d10e0fce0bd87e8af4e1b78c0c097af2951da58a78e2b6d30be3488a8b6e08c915dc419d4f8c202cae63ad5cde5ce822d80fc061e6c97f3e5f60b92ffeea8b400d091e7fe2431e91df0badd8a7810ab39218d5343a8c5754a7adf42d859a1b20d956d85fc7bd0a2b2235442314019701569565a39478cf022d3611d36c04eb0b5fed0f5a842648dc1ab3771d87a5969581cc00171ab78bd166c7fe4fe1bc3cf00a938a0c4ea8e32b987db80f182098354c5c9542af58f57f91beac0c2476b7d8c12c92ba0bac4103753b22e73ccb99a5d30fb78677261f63493d8be69497d7b5fe8dbc3962ad9bc0172b63d838e018690f5c6914a9357466d2e6b4ffe4db3a5a92827442f5a26f8b9311592e356a49f6948f1c093d6b536eb143530f1b0868986a5ed86282d923d949903bc96759ac1066b016eca98485e3f66559de9f650d763d4be76304b6ba90953cf641f451a3332fb16afb1d96a9aadd0805d8838d2b774721b5688a1897cef08d2e79376b4c11fd6d665e24fa73c6f6c706fae6d48802bc3f3ae4f95324da1968d9742ca46a9f6fd2513c896e80c0ffaf91484526d9a74fed7944775173ae65df22246bc5b949df8de5fa9008575090193be77ba6b290bf5d9ffc913db5e6984065d3b5e8b35656b95da1dd97881a9635e29c15f60de66e8c3bc755658da163491a1e6b4309465cb73e12d38c04913c1a30b90a76caaed0902018fb26d03aa7711dfd141b7e3f24f4e9939f3d757b30448d929f8f23a0a17813c0595b02c967020e8b44e52244dcb2b10eb916902a673a93b262fbf1d456b1496af4635b4766c2d2fcb010ee9d9a4fdb3952043803235be91fe5570f34c372026a2a3789b7a8ebf43e10301e9b7fd14fd6f827a60fbd641e285c023192a9046232b61f6a5eadfb69fbf7800dafd98d766dc9b2e3f17c47af1b90cd38330bf1ceb833f0fdb0c4d8732a4916c9f496b5c63ee64975915c531b55ed1ef3c916dce1b882d4640ee8b71128eec3c83642ac2b654476c90ab7ca871270bc80336ca487c83f650bdbbd62d5a71197558f26e317d1e3f281cee878918ad1c839840cb0e2ee230082f9b5f77d9ae4cbf941ed95f3667b59d9243a737241323e63569419af5ef08e9e226a8fc84790a8fe01c6c1b5176fcca8283cddf2afb2195ae7fe68a81396a7bcb10fc1e130fa5b19a6c8e0903c467c2f66a3508e71e13e2e74dbbe8d2d7ac9c7729b691a77c06df414b87f5ec33132dbf47b45be2a27ec2804d4119b3f2be9e351969b051a00ac72ab4a6f01a9532b5e742a0d175346cb13b0c954a1ba0bffe7018eb395dae11858605de22f7e22e0002371a118f9f191e3555c771ab3c7868e1caf9f1f38c01ca03d975d10150644af2a857bbb3d25926bae680d7957587237615f96207326e2e9d0bf53b0d", "006552536a", 1, -1289411036, 0, "c9f083740eaac8444117d4f56919da4348bfdd3b5472fc6671f21383d357bc85"], + ["030000807082c4030465ded46609a8709980a645daec8d18c186abdb8e845ca6b63f8651b3f924b7af010000000951ac53ac63526aac53950a60539c70b4da7a3474b9dc78da7497d696f288e49799ea91b5f654cd9b6935dc5f9f0100000005ac6351516affffffff73232c414fb34e55ae08a8a67951f6991e8c7bc1efe481838c090b8e0bb77ff900000000076a6a656a65ac538e387c1957d3819748b32dbded1af9ff82afbac2af8bfb0ba9388bc9a0eb788296755cb5020000000551acacac65ffffffff0255e5c200000000000400ac0052b2e26700000000000551516aac5300000000c5d6bf58013b69fc0300000000000000000000000078a944c76ba3984ac9fc138960bb654b6f707772229603b977b051d67b73bde398565723edf88c47f43649eb5db7ec3cc51ced9591f7a84081e19a00bcd75c2dea506c8e8b8666c56a16925631f21f2316be37e93ac1d2542e6c83c1b5c7add200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000afdf7036dcaaebc1289621d94ed38ea280829561f5e7d36bddf2097d674e90956a49c7c306b27d0d9d9441413e82dde38cbfaa96b2071742553de6bd5df7b4a91c08c35ca3fbf8a889d87c8265f33f91d57042d7021f938b42bc0c43a5f9e7fcd4f3561f737fb48295c53ce4beca7ffdd0ed8af0072099145eb6c818f7d3db2e022a5e9257c706128c4310f4b9986cfa00cd71e195b063102f15f27f40fa57a1ad020644e5c39d8600bb6976205b4e04990cd64959499790a31aa63955b18b034d810b0918937d47be67ca929b067d0534a011d5fcf61641154f48d2fc90278e9d23458c4d5d451cf9278461939b6c0ef5eabeb10ab51595b6731d5aecb19057c6f204032cb1ea5c2b8dc402848f20c8fd98d8f84506ae3d7e2a30d013b4d693805ff9bc02108c3ec6ea9fa100fc4f8b711d82fa81217e19e59944182afd94c8ff1bd991aa0216ee84bc76193c364c5a086fff6489436c991e186744c73ca3c1ff2eb44c35490313a46c16c01286a767daf02207840d37e7500c153d8b1486671c5ef6586f180c021a05910ad5a84f16933018966f88054457481467203a97e6ae3c94070668212b3eba1eef44f44166481687ca75702ceca0cc626ea8fd7affb9fb958b4df09593ba82e21243b8b6d110777e375c5d29079f153d2daad0ff2ac5a34f5e24b65b0c9b7c5ee70cc6f58a036cf2fc22e7eb7c2df7dd73da0a0a02b6e3a1891a579ec501b62cf7aa858bae97533e7403ca756e2db8ce968986917aaff8978c4e6b9e05a453a225194a9610c9a1aeffbcfe8454c04135d2615aca485bfabe0480634045c50a1a019362e6af401a9f3f5ea7b9948065bbfdd77ed0aaf851629000947b4fd9cf8cb1f75db01cfb7dcd0797c09a5f97d2752fc39adff64a879d8b3326f4c9ca15bab482dfc182c483c914342cf1b6a72764f6e5a152c535e3a5f2cdb11cb65bc5fb530dfd799ddf554404a6a88d2a629fe7aaf4eb701cd3d868fe3e7f93ce4929c0147ddb0d019a0281b4f2bc4c276c7afd7eed51df761af152f4334947610d4986f6d0cf052f79da1b2997799e9a11f66c210d4ba7b160d4963747d75ab247bc3c1da2679dce017fd0c030bacf89b0479cd2c84dfe71516e8ef1b5bc0bd153bf6cd30e6809b920fd4a76669739df3a8d36515acc1dbfe79f3a244adf2027120b9314e1d828b4a828e3ca7139de80a2ed1a0582cdb2ed2320ff7d050c04a7972b735414b8cb933d16247a8298f0c93c4907b561db31470db7dc2871e4409640b93f8252a0e0ebfa8a818406fac1c2184f7d7e3c720698208cef7c262d944222a57be0b480cafc3cf6810a2a65ec88650acceb388310dd05619eb852cc1fb838d29416103cebd2bb99e12d4cb4de5d8b3705be8b3476feb082f81bdf1ef4ded18070f71a14d29d067955b58186eef7239fbd7cc208e60c829952991d550d03d17010924f646d0e7424d98621a14a03ef4bc8eb431663e4a2667556ad9121dd59206692f5176f0574789f2ad7c97ef2f372c709a2cdac773aa7287d9e62ed42c5814f009111fe6b80ef59cad14297e6ccf3a4b0f716e5e7da901c9f7dc26fd32242cd782cc74752dc076c19c6036054e13fac8c542d86e46b277ac87dcfb9ce431679caf97191697813b1517ba8e2968f1f90e280f563fdb488495aece7195c0163531dd5b6acab2b7b3a9b6ebfbad82f0073a5c072afd6fa396edae4587896e7ac4106b8c632e01da608e718ca922d844f38ce8a1b2b4c8b9a3d1abda16dd75b56ead37934bcaa5ec9e8b1e4bc71e69c36fdf34d0cd2fb3d078e941484772299489f4069ed7680048b989da3d8f9a105e74fe09a046612aaffa851ceb0c1bd9c6c6da8d62fa73cc32b8e327aa88a007d6183699eada939708f4809534f9221bfd0d8d0294df45eb766c327bb616391b27169cf668832d7bda22019bdef2c74c4e790c7a8f19a1ea0fb8aac8bd0f37a69e024abcdf566653955e212cfcf05c0377cc2b1e9bae4ea01cca3097d26dbdb8ba10b3b6b62c2d6ee4978ae8c71cea2f96b2594409ba1fc3730ae3841b3727dc53b9e201593c83d9c35554ca6d4c08e64f3b408e225418ffe7c6e49bc837074c9b4e4c26a77e76fdbd5509e9e7888f671abf6d3a6e2e69027341dc26170fa18c8dafe463a257e8b97ec95838bf83182cac644c1fe83000d259ba32b44969228b99ddc7ca04adf6294d1b43cf2b4840a442da6f3d66e82f53a7e68986e68bff1fef8fac18e4d2ea111f97bbaf7f720914580f70bd8c5fb48e1ade46a072da9fc54116487a258a09557ed54ef90c9da7858b29fd4681314c0fdd4ec21d9cfc40804dd01b6c7bec7d10186a3d0c8c7f0ce36bdfd5df9c762ac6c3adef377a9cabdde7a1079fd7baefc99c374761eef5de4bc36ed3813e97af4c990ed6d61e1c8ed730f", "63", 3, -298200912, 0, "19fc7275b14f8775fde4ad94d3d8a9259787378e91aa5402cc15288b5b4c4f0c"], + ["030000807082c4030395b9bb86810e95b2a21c2f7b95cc19b0e8cba3fa09c33712c7c0e9061bbf804a0200000001653baf9f24434dba1597374eb1103c3621814a344bc3f57d9e3bb3f9d68e8f5070b48959380300000002650015d1c34c7ea6989bbca9abbd10e7e00292707a0ddf3087a9139df51e720812051fdf05f50200000003656553809cd9ad029c3baa00000000000091f2f7040000000007656aac655353acdf81f6dc785aa311034916fb02000000000000000000000000bbbb26602590fe5708d258bbf95d20291b955c90202fe8877905c9cb0548c4fe3d04a39967d1353e3b12238cf4c896f9be7428a3ff0da87fb828a011f7852c253edbda331bb41c913d3c2839aa1cd6821a0fbf6fe46da99874fdccad0834217d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b90361b03ee29ec3f7c0081f5d6adac6228bb2fd689bb5267f1828361d13329b6a005b9f124d79a6d4ce759857b382919b3e97858309bcad4c6153c587dcf8417fb5bc0ca410fe52fbbc0d33188ce71d5f5ee40ae1a6baf8e11b3fc0df6dd490bbb018f6c8b3e7a3508e74d07d9826500c65b2526ffcbb21019ea469787f5b3032f5d28f44868898304876687ede8462a2f2cda970ab4bedbc2a63e35421ab78c0307f75ae0c695835898d383c254dc59e0f6c40315e96e072684439ca3ed9a37c50b04eb962f24bb4356a8bd19d80c647228ac5a6a3460bf038449deafe39088d2479114f26da96492659df0334b9793ed42cf2fe73c6e55c140244699b5bbc33f41030f2b1e18398965edac831e6b460be8d60e54de1ca755429471e0978848d9a268032638c39fbcf23b9e24fcd9e5d025d4acd8c94274123df87d8abc3a8096482b9b0313e96527d3f3d73149472af58d7c5b365efc90b7b675a0eb805cb1665a2818ae02118317ded582f7441c0aea09888df7dce4eeab9a299ecffb20d150df213036c80208c551878acf2ff110db0c9f1ddaa13821a0083897a827d9cb49bbc256d8af2aa889aff5da41e161b1e6aa864b95f334fd66a1285dc566d4dac729ee7784e407b618338b1def3a431d86f19fc2dccccfd44d0f19b355b97c22cc8deed66357a2d40b175aa6df02a945456398f8b9dd0d18712693eafd5020af63da25564fa807b6816c02c683760267d6205b96f7502015c85ba4f39d63e7f016ebf66f412d4b050517dd01fb26edc8b51902ef8b9f9a7c71a2065ba91b749e69c63408a3bf5acf3241bae02cebeda975283207ce2001ccbff24479d1980ca08918848cb42cfcf69eee86496e75d7702a7f6206bb26c7b65542042e8a7bb8cead8a604c9907838a42d96212772628cef4ebf2abc378994f87e1d8ced5494ae436d92e29d632e3e19e063dfdcd7a92985417f6785f957b7850fc21757472609f80005757c702ccc3e36530503d4aab25d87f59ca03703f091683bb1b315710e85176902dc837fce30486b29bf14e7faf30b2fa6900dffae5ce179dc486b5cc4ba3e5bdca1925b2d809eda336a1848398d03670564fb142176aff2fc187d1acd86759401529a8c0aee1e0e24e8aa5ad73ccda748dffe7661febee64e9416a732f53ed6a5db3263f203c8d9d86c6d33dc6ffce222aa1e138d25051ca0431aa9e4b98350eb053f2f901d0bcd9ffc60ddddd8a09ee3a86567b904d0617b8af6c1741efb18907abbf573581e92c55885265d97a6e5f9f70670972cd2ccc338404a20d8313cf9cd1ced4acaf0e9b50b0c63e690166fc393e52bb71419523839251a0416b67cdff78e847f3236d4186a28578f40054b38a803704855eba34ef3001dbb4055682e555f6734a1ed72b696ea1c1fdf5788291f0cf0e34e5c05c62630ebc3b3609a66172bba19d34dff4c195916a48596a547f60e80720973cadefc4f4206d97b32a824204db7eff53a31faac73de1c4e0793ea9c8503472c7100ff80efd3626cc50c8753a7966bcd09e6f2c59eae77a8fe1fa50e4f12c0fdf257cdc1106f1261a693630c9c7050ead7fc9ccc67745dae84e5c3b91a83ace14982ec3f60dd8c6b6bf5d42a1212cb893cbeac146fcbb34bb7d51f63481b62c3c7041ac2f2bb035366dae9ac0d2c16afebb132ec7ae799e3062099d4373fb699f1377b76350b23845c8cf26d4aa760ecc2dfe98d3e2e90437115700f27b8fe3666fef76b8cec3ade9d7efaf5d437c3dc453ce8adf4695e3a2e11c1b9447e8247ebf46f1cca2d43575e6a87952172ed09301a959af7c0621719aea399ee73a3018fc72c9513cb64f899d9cc881af2f717e32db266cac67644c1dd3040ed08677a8b9a8ff32a9c163984ee54389e02ee0776a2df9aacbacd49d9547734bee18210b1a5bce0266d81b78ff201d4a4c4e5fd01027d36b098cbb4a1d19efdda6ec7c94011d55ceff1ff9b440c3d48f6403b325a693333b9ab2d8d865471bacaeb08b385e2ae0836f99a4e7f5229d0e55f660564c96b75cbcef03168f04d2bc15833f1e7def1f5341fe1af75acf4258ceb49104954579fc651faee6fc75b0d48f9a8373cd7f3d16725bd2a4f17557c192bd48125fcac5107b0afedc47062e686ce2b5a19bc815e436a1fa28657d36a15edd5303ea27b2ae7d0daafe16c03eebe103982264a180b997eba701d070c52b0d0c956909ed14b71cfcf79d971810c84f8850a27036a849ecbfb569378caecf5b0a5577388fdc63c9aadae55d5e4b5086f7e955ea6d040000000000000000000000003e045b53d7c3c238deb67464ef80740e927e295946d36710b6bac299779d636e0dcd10350dd05e0232a09c39bb6017dcc26306c3da117ac09870bee1323ae9b0bcb310e4216250fb2f3e945fb69c00307625bc54aed49582acf5c74b79603ab10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083c728af444d83eac5a637b47fdb90738f5e9746c314018b0d0613ee9c12cf12b6bce0625ba22b1fb42d7f5f6ffb9fda87c2476f821a9774fa02ac1a29a1e211abecc45901444cabdf037189d30f662d8334b207290e4af5893cef386f0b145b5a42c4218fc834b47112a0b166a6dff98c08d5eaf7e83f60e590fcc2b23efcf10304e5fd4735150db68a409939b207b878bae5ec901da720ab8f9b651397e30a920326e266ca209d9ecdf132e5406fd64e5d1b87296380b4361cd9c795e2b6517e120b06ad529c803d01cb1e3c749a0fc5dc1203f9bebe3185469cb87aaa32b012f26480401b3d781409e1c3aef3bc173e27bec9700f642f7d5467aea340233bd89801030e52b806d6a5dd8ee461640139508d3cd3a6c94713cd6452af7f947ca734aa36021c7f644641a8c807677c3210163cbcdfb7e8fd97bd74cc9674150070237b2efb022b7905cef222ca63bac2ad6632605d3df6d2cb438d73a243889bbc30d5cb4a16022e4f617427c185cf9e82c9a0d4dba42561d5ee7b12bc4048216661ff4a2128650220d0a6b7dc0496f8bd2d0d3700551730ecd6fd1d2dd10478aaad941d9c26528066ad2628e329912e0162cc157f468ccdcf41032476ae5c06d5cfd00159493b2e5e7a2f018515b34b1618aa64f2730243106945965a715b7b3b3844dd702281282350309b73c6efe70812b9609402122525546721e30793ca5b6fbac9c7b6bd237971b363f70d1f4cf08c57c9e194001bc04019dc9e49256c41404ce8a110d057866da28354ff7c8a380f32ab0555566dbd89a11db52c03ee46e0ab445ba61f3ac322182e9eab5d71dfde338e43c1721ee1ca849345e80244d15fd0a57c13bdae2332c77704069f3078ba05def37717b4563d25434074465e6905aae7e5326ca1a4ee06f8c10b424914ba7569da952afb17145561527e209e8e3d30e15924a9cdf93e6fc39a0ac516bd724dc7ddd7fedccdf639e8acbf4d4eaee55e311c554c272ed14340b9b5eb6f8196edf597bc41134f879e5747df95a2b81775ff2a3757a299e925c4c4f23d0bfaef5b994e7eeef78dcf14908f4b1b53eab8aee06e46808c88d09a2a15d3d1330522e9c87bdc358b953c267dac08b2459438137db7046269e21b29ee096730e62b74a86d02286c1e9b076ee303e98dc8a2227bf7743177ecd04fe7eeeada2d858b221a8b83f8cae1ce683dd9dc5633f1360c392198dcebc9361f9eca9f9ef2ae2ae2f833d8ac80457515734883a00af829486f1a500bbc1ae28a355dca9347a5076a1706bf0b5bb86fad59c407e6be57d4d54aadfbddfcf2fd64a35038b6f209e68730c982b108cbecdfe5ce1aef21cf8d7e95ec7516464258fcea7c8aabb2e775194e2aff515fcd404c54b6a4a284142b4b32d1aa0ae2efead9339e8c5a98e28a64cc5e2192527f1787123c6ec9ffcfb080999a5ad47075e4696a26f86485aba1f18bdc97bbbfa8a85ef413e0bf6c19a4d3a692c49f6a6651b6b6ddf4225dab5acd2a78a602836928f7897a5e742a1d50ce73eb2c839024adbe0b76b4c320dc586ac43e001c738e0bbc53cd4419f2841a2211a5f9fcfa3f6a26a5849dc99439cf9c225c09e19f19f4f5614ecc4c42eeb5a207526287f6d942bd32b7e0166b5aa2beda37fdf016bac5b0cc2b8f02a66431a4a7817e60d873218784d36545ddd5dc88f16039d0724cb6134bb26789e3161d66e84b5f4dd0c5f4d4788f536e90b568d5ba5869e81c67ebfe975a1ed7753745af32c6467aae083b34e94d1506ebfc859f6b6e42b8e2e30f561d4158e23dbb79d7b181634922e11defcc56926d4d09680a86dbb5df20c5181a54be111498b1ede465c3c1adbd45dfc660a03fc789123cdff2419f16dcec78ceaf0a521b7a93eb201e196197fdc86d47025ef6204a18f4b6bbf32d875796135465b8e42d93153a3fbbbc89564b288faa894b4035ab7861e11b5272800fa7697e6cdc70a71c5c4dd1451ae8f28d47ba9f44ffc04694971c99f85766327a09d9b0d263bd39af7ae59bd585106859744aeee94384b09400cc9e63aa98394a0ea6ba82bf8cfabd2257424f5a01521aa911d6da3bfb64a321ae7d732ec0d881c4a721eb8353f18dec4dd8fa9e4f2465090a89c50e321b903148096fb9df66c288654bb1b89a9a0c0280508a4f0b439b3e14a73b962211e476aeeca9f79fd8fc82a54fed32e966904f6a963e4c1f79ff68109ebe2b17b51f6951e4b68aff16fca8afbc4f755db688b991312bde2d9b5189b170d3ab50d4f28f1d5482879b13f1a815fb0000000000000000b926a60200000000430d1baa3ec5f110cf0066e3f59c99893ae1dae6da3797c196e7eb1b2c1190e65149a7d75a362e6c0f24b4689adc5b3fc9cb9c004c592029ec22a2d0039d5b2f977570e07b9471e18528a08cefbff69338d0b6e4de04c10ec81b638ec48c107300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000411cd6cd1486323069d3db7a559dd99faeb3a2a23e9b24c4debcf1c343619a9a30f92d5807a5c356c6bcf11aca46405789cccd0f787af0967152d98006be760c5da9fbd0e2e4a9371e66870c5367071773e90b31c051b66c6d8aa88a6e9659b1012b47f7ab0e137b0a3a5d7f72bd07ecddd4bc9d0112f9926262d0ee82d5ed93031ae9ddd35e697871cad0d80c6fe219a68d0754d53e2035808e35738062d59a09021521b4aa1974422f306a67a5b65e8935d3ae72559369b92930fc1fd67039b1a50b0831e4f1c0e273965faf5767b3ca6c0c33ffaa46555033006237c65062d8841569f03004b1176460a18dc045270d4eb87456591f707dcde63458a038a7f4d0020222dafaa2358cf58d88c6859ee2c235e18231396c9e5f34ff61a6b360578f90be0203352648c6714dedc8e0080f122c6e0e9d161a78838e9b411f2d68d4e898074f0321a50d5ca8322e6843d4ba5ba6e12590214c25e0ca42f56a93508ab1e24874b3030f7bbc0b89f2be396ce528343123aadbd4a4705e9c9a7029dd9d38256bfd80d50225f7b3bd79ef583163257732dfedf33410972a73da27ee308866037b1efbfd81da84b1e886fa2d91536dab7dea51377ff929d5224c2d9daa081881c3cdbe3d0888bc7b22b64c48fa75c450a9de20f89f57ba02e7186aabfdfac4acdf9dc8647e0e7fbede67983368c0b23e43e3501deb75cf5ef9ca06e9559e2b8d0c09012b95687d5df5a161d22f61768a0b87c038aa3e482219eae44113bc879d40e8df20b4e781bfccde3716f206ba96b71947f31ed5f8dbfc631d05c26c7292da5d9025b85c49d33b818d04e4740b142a7e94b35f4747603e96efaa0d48b92c5dea6e692ef3bff3405ed2bcfd22814e6bac8f6c5f7d311ebff9e7d88ffd2ece9ba509572e561f003c88fb9df61f02fb8b99af8f42b909f794f9195265e09fca85dbb9afbc61c11e9a6eef2dd793a40c102b2d4bd87fbcb2201ec43b5e0f1aa47b8c1f976f5992447daa7ebfa63fd1567068eb169292ce82ff687ebc3f943c644f41798f5d1242296f2fc9e2fc47f8a713a907a10a922c4473a52ab09c54a173f2d05b99b6ecb6eafc9221deee3025bc9dc0220063596168bfc1a7fd890dd73300b1ef3df3eaf805d0b6084cef7191516a1dba8ade1c3878e622a9e314264aeb40bbb07be18d902078ab2bdc0d94e5c5fba96c2a19b5d47612e3ef8acfc677977dc6572c25300b58c4a9966bdf8c47f5dafe3201586e498a64046b6c37ec688108777b1191c0e384bf57b594bf9b14e739b3cc655b1b636a465d6d0b42d3974a9b5454e748b766f65ba13e09bf3ac2cdfa12cb797b852a2812774794224da158e4ba222ebfb4eaf7858a1973ffb72deb98bacbdafb336d360c09883cc8c268a21a8c35ae42cb37debc43875ccd6e3da73ee0a6bea61b30585b8cd4826463a7e36e23fa79f8dab5a7cda419cfdf1136e82417f9d2904db6badda614f56fbf7f5d1591962b20a11c64fa43c942b4c1dcb6c66989fccfb10b2e94d631c9d9df4853b2c724ae50f20fcaaf44b4cf417f1946906e370794a090cfe0aa68abb173721101fc71bd38914cbb278ab05aeb2d4c86df7b1378941749a3550dbe8e5c96660e15a5a98b66f04af9b906840caa8ec673d5525b86e0bb72072e8a8b6621007ea28043a72b5e32b980833c4a4492c08e39f3be8cba303d6bafc4e49374f2868216df8ea444f22ab2f6ac5872b01f9e997d14a3fceee0d62318d9ff3e35daa4e9a6323675409096fcf62c8d2c8d1b45492ecbcd134fd159a79caaa6d1b563200f796190b1f2e9ab846adb40d33d5ea31533990eef576d61aa39311f391883d583a5b939f2a1e64192c0fe5e7c953c26e6248ed92d5f3f9440158a1a98ec091247954105929db3373f69189d8eee9f55790762333d8076c1b1d69bb1c4dc2a428dfcdac1b59cc4595d7b543dba01adb519e30bb8dfaa1d019d0b04401c6bd269c96215529b642be34061c5a57273b3aeee580cce5d279533e945b03cbd43f955ef45cf56d04610bece4a188b8b1d416f65b085b58407e500cb2bda5df6824c16b50c04ed212cb2341f4a9180204b20783c2e01d597fc1b6c5c71d35e81c97690599d6cdc349b6ccf6bbce0c01e6b3964110c25b85f4168820c5b21ceb17fa22ee341821bc147785c9a577929acc757d53f5ae3f7dfe78ffe0b439d74b0ebf4928aae0e9c025cb70a887319b169ad545fb1ddd779e010692a78c10b2e172faca0a774d4efbb4b659173fdb671d42dc7b7788f9148de62a58e43814e0b8485788f7f1507bf11e58631786b647e719049e4bdf6c00a9b6a646b6edc86abf9e73b8b63fb90cf25c67cfe56a54a525b794dc46417c3e561b392fb9aa06d64554c90836d64964a5c812c647dad7d2ae3a24d7a9cff83965713424c0e", "6a52526a00", 1, -1462065816, 0, "8f88b1cf561f5bdeb05408f7b54e45ce91283b9525aba919d35c899d5f43d3b2"], + ["e40a517f0132334c42f3dbb977527ee0f2189e2236ee3550fe5e2b35ad39cd4c996cc8f0670000000007636551ac636300738819b304f28ebd0500000000076352516a5351008ddc7702000000000763ac63005153ac93d62f04000000000963006a00ac00535365f4fb1d000000000006536aac00ac6a0000000000", "6553636aacac6a", 0, -332937932, 1537743641, "772445e3be2b6e48648881b5739570031601c99f21362aff73699071e59d0228"], + ["030000807082c40302de406aecb97242cd75ae0d0408b13b351c83a5784b50f6e06c679668fd3c2b27010000000152ffffffff5b3a845603acba7f1db429079229b2ee2ac9f03fe3f1c826ead70da99c2e0285010000000653ac515351524bcd471904acdbb701000000000400005263f8955c05000000000365acac4803570300000000036a00ac5c6348030000000002005300000000a8403d78010000000000000000c88a5a040000000001fadbe2aa01c8a8597177136833d3c4df62ade77352104491bdea594195d238f4227a1630e87c39d07328dbe69ddc77d51d51e9cb2c04efac7cb425aa8a2a7495f62431fbb78a37c548ac7cb27a369060126e6f03cc25c04a7d54f0515f8d05000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4dd9207f76d3adc4113caf9c39d314332a63de9bbba625aca0a445b4dd2feeeafa7dbb6c6457c606cf20f31dc37612b0f08283d19646ed25fed4fa967a4a36302c79b90a84090671a808244884522b6ff2ba088945bbd2fa833170f15b47ee03d41ea2732febd65ed8a1161f3ba480cd5480e60499b094a5f6aa435c214e1f033014c6bc6c67c72b827b1bf437d8f8d50f9206425903a94574288d5bb3c722d4032118fc2f89848de615c03a41dd3cb70626fe8c7e1f5a375b178c0ba8927928040a077892221e2442d0403201aa6da53a8cafed1377d4db4f049ba6f7a5fae9404799f3eac3757bea064c3b4b3312a1bde7b8c24651e4280596a357e09a2b35620b0228d51947d4f402955c2223bb45c112e31f9bc4ccdf9d67eb0cb915cfa4b2c9ce032a26cae565b672b026df772375cae842f56850be63063505bb491e81d6d85a49032972e7f8ca18f58ff4230104e9b7eab82545324eb4ea3640775774789621f2f80323d41b95b484caf2efdacbbe3655cc49791e0d140cf3d7adc3adf2182ff9562d020917d4d1a20453010321b27383190f8316ea39f6480035df29ebb3a30484534fb579ceace1169ca6aac283c3a509d952d53db6d502c938455b8800a4fb8bb6976032c82243e259ca59774fa3c6f014ac6c6b9207d79dfb7bfc7fe0ced17ee65ba882580168590fa42662c52e0220bb9a519c7caa39765d2133015087e0964320f3e943d09b44a66e5b86002774d5a97d966a2a11301ca4e05b39c74c1897a3d49970a58a7e1d7bbf33d499a7f21709fa84615b8db9a4b916dad7d17e29613f4b0bebff5187655957761319575e39cadc91c95f4585d3135a627467f80949d50431e47ad887af139363ffe2ac384e44f28619e7c285655cf5d7cab044d308b05a37cec05e7fa264c0df1ad12fb084e4ecfac829a3689764cf363567b8ae3a7cd37ad19e6f715f9617a2b9778d817ceaaa1f80b77ac9ce1061f7c9d62d811f6887419a8aba6d253a1269c7ab489d8ab3a962e747cd219cb7b8ee7d3c56d631bfdb3b238eaae81f90d38d34befb7547e7e0992c4a40e9799188aa18d5c2959a26016dce75109140c0b6649d3e896d627e698b4821b677a6eb77107b508f009a9465667b03140d2fa35aa4d6ff50a2a9ce4949c82f3b5c67d698bd05a06166444f81342ceddeb32cb84fc040e97b8321d4d12faec6cc47c9bff12fdad264da7c908df172d166bc450d86204af3fdef8ae1c59b6988621170b1da2d2f863f5f4ed9e71934cb7d233afcaa3dd028b82c6aa9c8d5f0e471f9813a7a971ae1d2ac583f104d358afde48620314cd8c346e0f5863a13ccc766eb0e16435c13f466facfc2dd702db6b8edec6bc52f1a317c6aa7c4578c2cfa204c61ae0101ecf670cb2ccf052da660a5ddbc1b600961b5738c0c0d99ffd3d4f37fb0584c3f2c2e165d41ae077abd2262e19eaea4fbc45b1c4441fe63186f1b1616d5e73399b1699b7dd56061cdd59501116b20dbf62f5654e9246be8040bcbb8e5fa109c6090140b8d76fd2f0355104dae5406d8875e1e8833a2a0cd960c554867e72afb03f51a3a76fd35bb2759086223b8b74b1061cd310706da02605ba8dfb69e04a29e898a736769c6f41e9c6ca6daf2e7dd9603b520d0498c8a17a593495da897ef6eaa06514f588a484033681450e7da9d5e0ed7b2a0cca609776073272e72cbf9e19ba9b7495a3d313c23b81204faa7b41ccf31a9305768ff58acf5cbdecfda5a03518d5e804d9c3ac5087ee18c35dcd5eaae254e10cabc3ed1a5e901ba1ab82df97a7b3f6060ad3e8fa4ae849af597a7e482d14ada168ffea7a8344254acfc81b071863661ff5fc3d5fafdb0c9f25213484e85beebaea0cff6f2789f20e72f1ce944a68e869014367bf2d13b739cd9322cb85d245efd3a6a2121fc7e1963562fe32d0d86c9d9371be025ca424212c0ff565e7d24f5af45f0c2a706197fb9b7ef0b5a4b9df1ba74e956b4b61748bedfbb50547a0840a61801183eb81324cda3091a18e39e2c96f71b33451c23ecc14a471e5098d0ded298b51eca79709e974958d774dcada634a7196ee2d8eb4ed1167da02dab9b25697c322efb6af455e84f3df0ed161f700b4a99a8d1f9fef1f81c4092ea85971a288b100dd37a7e49cbb7eb95d20db23342488666841b3c6a4f0772ae6a7afea38e33aee6c7fa545deb34f0be46fc268818d481a2a4ddf5763bf1b2804479f8074954c54fb5ed63c4014ca995890110b23b93c9b706d6567cffd72b512713dc6940778a2773bf7704ce365f73274e81f8b03ddc2f53e0812f64ad82eeec7cfbe30a5bbd7349ef420dd0d89c5a28f181b7731d19336c7967c094df77dff58cd6b6b2a70147334e6fb9adc44fc9af40ae5ad21ad5887d98786ae5facf48033dd99c6b5599cf01", "53", 1, 764638258, 0, "69bb8f7dcbe3a0d5ea01b24a01254eb62557e8d706d52ee3bb7b17551959a0f0"], + ["f697f05d017fa612f56f7c8c0eead46e6db8e511d4e97cb69a174f55e3fd7df1feb253c7e000000000085200636563635351ffffffff017044d70100000000060000006a6a520000000000", "00520051510000", 0, 1837266794, 1537743641, "6d159f9a8942ff230207ed3718a60c554ddf96aa57e6e5e2b5cd4170f944169d"], + ["030000807082c4030250affbdab0ff6aa3c3b0264461e24af180891feb7a4fc4a2f167cba8493a3f68000000000752006a52516a63ffffffff3a9b1108be3d0eb0a1a9f0b3e1912b8af1d2d6855107953a77243e3a97ef834a010000000663535153ac00a178f841046a17fd02000000000038eb620300000000040052006309daaa05000000000651525353636af7cb900000000000050052ac650000000000000000000352244a0500000000000000000000000011ededac36134169d441d0ba40972e465ddb1961d9dd4e1c4d85446c3bba1f3f532120ff40409ab616be6327cd7927758db06f55e3449e54a3604f361be62821c44dee4370bdf479c6b6a397ce9fa8b37b7042b239fbebe9a0d7adfd8bd667840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055057d602729421d781ac5bf5cdfae41b30c78012233c9f7c95f7a21405c2f227258de3608cae9cf3644740806b5d78b3bbedc589103f40c896d12cecf0d9a299e055e22ec7993ee7aef75b5a762bad287ba6789b8e5b663a2d3d9a5eace13fb1bbfbc70ddeb77c7ce3eca9fba989597aad6b33c217dbbc39a1b6697923747970207b442ee433bfd13cc484bffea80d771e906d7f04db45d18d217dde16fa228150220c05170707e5827c608e95bfb3d3afe93c4f58891dc82b999136d0ebbf2093e0a022fd07745881491bb29125b0550fccb8f740c6c87b2570f3099172c18134f4053d3f29d021d12e078986afd930712308b2d887fc9753d07f83fca88e9a0047e021b30f3041ccb4a36ed7cca652c5c9a0cf1748f49caae3b3b8d851e8200ac70da020336190b6247806d4a822b46a6ceb86d3ad672e043dc2f02f8a89acac0ed515b032b4b1d2b82a24f1ccac5118925e41862def539cb2bc78fe1016d2f0c1cecf6550222744d7c16bfa573345a06bfcad2bff3131d14293e6e24f92bf7dbf8b0bdbeac031a28c76bfc0b682db3cf865d034b47cab641b00814f99f8c31a8eebb9ef9485b03b1c47cc7f65491b97991b28dd1722d20a64c0a48f30cc3ab3362ee1158a0d19bfb3cfadf386bfbee94131b46f86cdd96130c86c1293cdd7c3a5e2cb7086a333c7b23bd50533b2ef654d4f4388a37b2dd8278f7a8694b3ff086a9070b0c019e84ecb67d8dcb2ca07c06e1f199656770a63023eed30de054f7a09b88176f5bc485b0ee9f141cfd476717fda41cf20e5bba3d7f80fe8741df4ee6dbae9c225ababe02f8f543dac6eb3e7a1708064120f01ac0dec4a0b74ce2fc5ce868c7796ca5fe60418ef170e8f755dda9f14391e7bdf1d37da0c00af94c9b3eab75dee0d5b45d080d2a02995bc4c14e2298a523175e573bb103b8461e1183f7003feea0cc154a243e43aecdaaa1a1623101f5d49fd2a91d2ccff031ecc625e687ae1c39d1d04145fb4987feb058ca3f92dc5f4811ddb86fc32f7c4dfd59935ad42b890dd9037aaf2aee1fa4c018af84877103ca106dc63d0ecba240edb291030dbfd1a7ecb4176b038e83ac9d194aebab8c34add0adc8fb0c780d697d9d286df701b7a13162222e0f36b83b0cbc6a100648092af63879ee95847cd8b35dab9869cb7b6bde244a07f567ae1437595b03344d2b6f1aa0592358a7d4a3d2e2d6a56465ed030291a7bbd27cb935c5c46490c1b2b4e728bfd9b9bf3949e3db269897960e5e62e50d1eaad1bcffe1dee5c6dbb9b7dad8adb1a79d16a8d7951b14fcab20b4f149f7e8bd5f21cabcd876f52777ede1ef1e4cafa3f5b911900117100fe8f342f9d5bd77050f2cd4d2a561c01aefb0f33c402ff329e9debb647877af1691ed27695a2dd3857321fb822a8019c6fa1de0cbe2c66b7677e06c01beaebcae5296cc35014d6de183f21c1979f358b7931ec9a229ae5617876e48af31c6bfcc8dac57e1783e2e3b36fdaad98b0341fad00c6e0a2772f095c155ef9c5d01e1e7696e2306511468f84de3a0745dec7bbb8597cd6ae898f98b383c46eaa2c4c561796212bd3a23e5ee761cbd19a6068051bf250f7049e7560e2ac98fb4b2d57ae0e8e77b08ddfb421c93845fe79652345c5e02b940dcdd6fc76139286370a334d36659834f44a3e26c7eff1b9aa95c496194731fbf17ae6cfe1fcb0d574eb5849da115ce7e543495b985c0b3b987e67f4242fa90a24ed666fea79e5404befa449fb79f301d0581afc15f44bec7359b832a87fffbcd74985e833d00e41adb3b379d87e9e8cbfdfd5742038b7a07403c45756ffe2dbb2347079c81a11e1e0e9a20672597f333e4f9ea91687a17012d27960d885e73904c7705b06e32d75fcb7c89290823d9a3a8adf1c5f08cb5eff789db222a5af0558cdc505a3e4711bc2f267724a2166367af7b8a7ef71a500e9bf5a22808adaf51a5a47e4b751f0d7d1f7ab5cee89e9eb455d46123675cfe036c16088fe36dc8393ef809998b5bed5d50a9c2848241bb6df49793a60c2fbae1e592cbe79bf847f47fd913f41bead3c9985580d932c23e0fe8965037f98a55b63c228f8bcd0df01ebfcfc61937b19dd6608c682ba0c81137268204427499c5ca607bbcf9e122a334284aed708a3c494aa9d856177cdb2b6c6e64467e9b88f39a2df84e2ee8804bca2038c4907ffa9f4c858e44ec119b38cf46f9c153d27484391d18774877213dc0dfbfc3ee4662984b6688239404973bf7140fc7faa493498fb9b446815706a4705117329e520000000000000000601a6a04000000008c7bbceedc88e4b5c0654f15d093c6c323cd77fd60b06daf08253051903bf37f139dbaea51f85c8d3626fc78773775e60a7d6b2875f914abded43d003183671528ec3f8fe2564a662260dda0641b43df44f81b5a834fced4e19d5e704f0de0820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072cb6c8f0253efb0064c8c3c9d899c306f89df1e53523ab4851645a9da85fec1d5e9e98b8e8e50bd31ebfbccf0befb39983a007c335b912a383747b34b13b20b0e6f1d3d91c93533c9bac8775d9eee9fb5685308df7c2a8ddecafb98f9d295d7de0a9e23bcf27c47510962f27e094ea75cc07d9c2eac85c0da064586fc40a76703112ac74ef99cc958f5efa4a5a6ee7e2faba58d856b88dfcdbd8fb6dd6246ab5d020417ca46cacf89aa285d02c6eff7a21da4b4491878af5ee7a3a851643be06c530b04732588fbeeb15cce4b97a9886b7c6ae81bae302d557fbd4857eea374a53f371f46fa03f4ffeaf9c3489156505b513b19dfbb72a277990cbc3d58e49e67d49602274ee941701c61a31ae84f3804e549f076a1729e19abe50e85cf19173539e297021a8648b314393f13b2e64e2e6db459b11f63f1e03920725252339da851e53375030c18d588148254d423ea37a61792375e0b811fa00c47e53155439032efe909f4031381d22f0c27fe71c1abce82d400bb5f39b4812bdd82410c48f445a037f4c2c70210e32196bc2368cbf4ba5ec4abb0fccb276af1d13be67c417086cc4868d5157bfa0e9e1b06ab2fe5b0bb5108567b2fc91f407f2847814910d2a86a2ee23f2ccd9a49310d6481f1a977bbcb9e46394b836c1f6505aaab3b67535a4f2264467ff4bd99ea6a04452a34757b99a6de500be61a880099361fac1de25cc5a991329aab754e25a9165c956d1c2b76d2b7155ce50f42143f0380ab4dc9668a2428909a73d71770542fdbcbd9f094bfc18d259d41855cc45ce4498e4eef54873dce2de21bab8b54b4721197dcd97fdbee5f17e82fb9efcd5c32c24915fab80d2d908b57624ca05aea863ab0bc2b980884a40a427429b4aed5392b28147c1c1fa0c54c1e13a24a72e35cc5089711b3b1403923f24c80b1c832b6052c9058474dc22906bb24888fe461a1152150d1ca998cb9d3228c885e6e00bf57a740bf86d52abf68ab0e80ab9791c1b98da269d04ddb1ed127f24cc619235551f9a14c5515ac3073324cfd2152f615ef0501d45fcfd2fa3edb39787a83818fa5bbc5bd4938f2b23370ca73fd18079df5d2c8c0e96f1781c6bd53adc1632985fc98efa8457ac431ed696e7a568faf8795cd881da4f962198e53edbb60333cfc4a02462171e49c6df3da4df875f8b42e520034e8cf7aad8d385648b4b5a195988cab733efd76e6e3ba5f067e1f8e39185aea1ecd1b0f6a56b74469772b1023932125c983b84c8ce48c1003c75cf59594647947192a91c45ba951b7c0e66ce875629b02b8e1316c3f7369edf61f6b397f87e1a219d65d711df0b7047a2829fb257860ed2b4ffc9e3c00545f9a23d772efed2cfbf1810abfba1e4c3e3c896586ae5be095dff70b1ed9432ec5997c3da344d837bdc31e361bdbc7623f425435ba297fc86d000418aaecaca3cb73d30fec1504cd1029197ef122407cc508bab6105c302ead193b49c05bc9f6ace6b5debdfe1f25e5d2056230dbcc63f41450ad687e0470df023c6b0280b0ae7b6ad05cb39bec244a25b5ef70eb1d694ee95525208ed0dccc4b3287aa4596b06d650068bdd4108e1c3625ac3412d6d691dfcd16563fa4fa0359952ba10b0e709da037729d8fd53cf1b9ba8b166ac64da6ec8fef1c5e94b243fa55b8e23e5cca5bd618fc90022290bae5da3acfff06ceccbd8000dee28b09c83e9489796042231a38421a7964464ba7c77a47c078021d04c25f0ed737ca019230a7095c0e1dc94a9bf13f508631703d249064c3b181b614b76b136b9731384605bf1422dde58d77e4c3ad0bd1b3cff168d1995671b4effcb6f344c0fb467d052fe232b44c169875d3677d7fd1ae2195ef65c26d3d70e3475154307398966760909436a9443a61179e44ff6f37fbe421fe152d446a51e61ed4a10add50ddbd3262afbdceeef742291a1da48790dd9a882829b08dd6c7762fff7a72d38ad6095234ab7eb3c7f96ad95bdc0dda253cd922f86aded741818764df2674fd7d4c0908e505360d61238b17d081304d6acaf3ac14160328fa7dd24291473922d35b258ebe44ccc6c43448e59d099a49ba0642f7f7c2526b1542424b0f1b2fa8eb45a26ec8b83a30ddbdc62851ffb9b3415bc30fef276d10d7b381ba1284147d0afbda40f46b575c5def525586d27cf0df30a9c4e50f577ff6ab753cc929ac96ff4b84ea46f7caead6ce33e26618c7934aae33242768b757eca62136a3b86df8510d9cb0d22466ef44347898ae90a31fda12a721b55c93d7c7298045470a7fcf6603000000000000000000000000096c41e992b37ac44cb8b1cb34f3ef6e0ed7c6ab61082d1223e07a8dbc939df5cf81cac775fcce57996ea326e5b7ca0f00402cda14ae6816dd17c0e601ad0150ece14c57db685213615854954d8bc281c632523def7793e74cff54708cff912f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b06bc33ac33214896d8e018c1b4db3f4d64e7254c33f7e1cb757c979473f388b5a472017a2bcab904ceb297cd232baa7ae2b93710d07c87c9022842845f8f6dc3ba2ff054967d1e914395be79107ab1f95d4545a3650e249fb564f399dffd36ee236c9d54dd714945ddc5e7b61fe80c28c28ff442d4b6329e36793e6bfa3991032d90549a1e8d058929876ab059cb6c4f78f1d691481c84ca11798b44daacd1e80301b07a4f3c83c8db75a4bc435a0a79a0297c81a440ada3c3e1e748b518f485350b03f46cac43ac48c15a407c3827cd8460a37d1da29d7fad5fdd2a68ec800b3ce3a375ebecad18db81a913e02500dbeb41e99b5e3cac5ef45a1607ecb926dfc476030450ee643c93791b252acc87071f19244f287de724d2ff8fef21db88efa02e78021aa4c0d8d9de18c6728f0b6c06ba65230039efd890c6c74d7df4cabe3ed28769022ed50ef1ff06d662bfd1bba56925b716b4baa77a66593114645c0c0322d9170f022f77bc7ca3a31c38a827226dbc731db0aeb28d76ce1b9d4b0e1ae093481bfb54032aaa4f4d85cbadd1dfb166c67f6e2d1a59fa1ffdd4bd08a60fa0d27cd784c4f84cd486a076a0f0908eb86966f76f628b8c63fbe82aac86239a71fb870c40e53f8d8e632a351810832347e1c702347429ab36e3f9fd90ee237d0d7dd96f5ba0be2fbfe587655fb8700203be328c9833e07c1d437992d760ac6e8a89123f818b0db9cd28894f5b506f914a32153cfef90c5e3598e54006629de39386b4c8e3963b1516e44dbe405bd3790f00d1dd96d3b84f5571872925bcad59846f472b40522e6ff38287e15a4e5617dba37380f1727f2e251221b780c7d65ef30d38ed0ac5dc6d4860e7774d884106e8c33b957c8436b350c75008bb7a672fe021ea86481f290b07e3ec0213baa3fd36d8fcb7291de7e837d6bad5a79e9159eb89bc03c1a2eca04411b8eb794c123c63fd063c7bb48c7b9fcbf8ec13e7d20c47f270ca0f478040dbfb0160afd9d1bc01c1114fcf85f0a07438d002ecdbccc4d50afdc46fd91bc68b3b00535e81fc6dba6ab2af96927c424c5839e1975584c87962955fb1ac096dc7c59ec1b924578e8c25ceddcb59fa138447693cc8b21643630fef37751120e0caf920c689342df4a4e8071ab92bfe9fff4cd934dbc718cf66f21e4af68d6fd7af1ed5e513696301805de107111d87a0acfe2b6ab9b130a1b942bffaac7a2f7073d201ace379930d623c8560443ddb327c6af3e9f3741a10eba345019fe14ddbd9774bd58249eef57e6e42013b5b5eab92167b0d39062e33127e6464d733926d1c0538fd4061a6376e2433d8e8e705d2dcf9a00f77702e100dbda91dbab136b5eff542a6d41c457569923f164f60ab24bde4dcbba2155cce2d2b56af6a4ad8f9c59c4b451b319e5539859baa65c6d870d8acce0bc73358aaafdccbe27ba29dbe833abb840d33d87e344939a68c47137ee88a7b155a7a8bb8917e5005fef444a5c278768e39e3758e30a9c815ea1f26d0b67f662f004b199a31621b3ad25d4b1d1c77cd0fec9ac0bd47d992989da0b0c64690fda765f9dc7c64848dbc36fd091eb825c2480149e5c575c882704bede12ba40bd89984e47fb060c5440b863c6c3eae34ce07e3b464c3df8f4d9eb5c502b091b1fdafe0c6c1f15e5cfd6008bb0bdb7807882ea0cb3cf6b037c7597f6eef22f00bc2337dee366cdf1a6e56c44927279a3edf30429e389d27eff4a148ede963a421ee1707f522b56d003280ef3e5a11857fda140842679b53936ec7143533626c83a1cbd07e3953b7e62fbcffbe7ef66dc8d0c9ab8c75c559f9715da66c6df515fc0efb64c9b6c7d293bbe78f51e2c2b746116be43658fb4d5aa5ef03af1c978d8c0603479cf087bc1371fb013472b3993e157a9d80c807dfa4dbe0957bb7b33c04040a8e54014750be7883b2c054b271d2c12c2b6c3ad4919e051f182dafa84efd1c7f44345934d3295d627d516d3fc972c2f52b4fea11238a1c47a1ae6271fce47998ad178d87d327dbfa73f95aed92ba881328e4eb464dc4fadf6ea6726dd5e1c7a608c55e5b0bbcb6632c9a92bfbfd78f86d95a8d6cad249134ce7caeaccdfb7a4f722cd1e8bbc92bbe8e19b595ef3632f33d0dc99d969902f2b1792a5e45332f87a55d38865a2c9585a8f55321bbd07e098918df4e4152ff811595b7d5b0af0e736509936ecfe42e74494d205798ad7b76f2d09b79b3910b9681d584dbab1cbe88736a2511eff25ec2da97c7705bf9859babc5b93a7aa235cc5060ce29c8457abeee3028d10de5efca909ef3be0ed05dbd1e2c426f7006676fea06b2b0fd5e731db8097d22139e8cf3fb79b22380d94374034a223147fd999669cd5d6558451c3d9ea437f4d8e9ac70d0774792dc667b43c00663093f28523545670cfd08", "5363acac65006a", 0, 1134508940, 1537743641, "c86a565e4ec458487c8114a21c28ba00473ba7a7591d5b876e58c8b4fdbc55a6"], + ["585dbf0f02b374e1c5c41dd906f54007ec01d33db536475c46b98634a9080a3c1a13943545000000000953656563ac00006365ffffffff3d62446244e31f1e636b5f2ca9be27f3a5cc646ee17a014c9d369984a73033070300000008510051ac00516353ffffffff015ad95e0000000000090063635100ac00006a1ab9c26902000000000000000029c64e05000000005f2ae5ba47c1fb6df5ccba630f40c579d9613fd4e03878014dc89b5bbee621983d6d9e831fb05c00e5722d71f7eeed1b4520dfed3aa8836140fae812bc258302e4ac521ccf2b91fa7cb3a6c9b720cce682a1e708da0f167835dd373ef5f276a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c678051ca646d7a19a8327666a5ef31ed76e08c54b4ac21622e4e35f4bd90b31328b925eb164b9007b0bc55be8325973d6ae836f7eeb90ac6fc4a0769750a73e88ca6e46ca13be18e20d46716507edcbbd10220772f18780686777f8de9d8b24e5d39b9d6ac416fae70bd44bcdf78e5b38436052b410d90b349e32a3773187dc03032adb222af0ac4d6986d46fcbdb25a1252cb0c090919fd2c64b88aad70292e5031002963e4c308497406eebe295b84be28a30208ac7dae548677bf733a0bd7e640b0082871815d13d5fa0863c6e3e27986334f4a156f2f3c29f216fe0151ae01d3bc414931170af6c4b284e7fbf5ba599dcbd11b9307993af9d82085d2f094726e303115e6c330eb983cd83d21e469db49752867bfcd2b2e49a9390d8f6d4bbc7ab58032460d4590e4d277a13bf8d4b28a5a969338ab1ab893b48e946c9f06517b82fda030d09a5f918b160d75924facfa37ffbcedede141dc41c1648e160687ff3c0658b02117bee42321cacfbb1df7d3f8902ca81bdf2f3651299302afc127ddf1c653e71021efcddef5c5ad1f1168912a65676211fc70cd0f2de0d542885f23a3cde5838310d5a78c5162f3d9579c7aec3b02146931f343cf1a51efbe5d7175bd4e878fccb7228ae8ef7debae995e6e39946efcd1698ab83194c61fa0dd26afc3a5cd21971c79dd8da92a3da7dea7ac601f60bd60136ab31645f2ecd9fcfaad5b60b1c83c13e3abbacf48a40d36474624d4d3140a3f976afa53e676e4bc839f2108a693f268193bf648d416634eb5e021d85dff2f3ba9d6f007abd9d6cb2239ee701aeefe0a1d7c509685bdff6c01a79e3a0a396c215949d6b7e01780170372f82cc4a46f5aec2c6480358a5512c18f4ad05f73938b877eaa03f02d389e9206a233e1a52480ab53eccd5f2fa1056fb1ebc711bdceb18ac58cddbae9f5e22a073339c2d2d334c8b5b027a28355f5c63080a0c938a1603e1bae50da03fcdeb15277e4343769694e6866e54bcbb6f43da10c1baee96d3cb8b084bf7a7c2d1163a72294595a1c86c541ea5df6808707ca8457ed9754fa3202d863736a2a8f13d43f95c97fc900725b47abc2db47e054853c4ede25d0455553e6325c7fc3f62a53a35289dba589a5abcbbf52e83cf60bb0d7ce4f6c4f1ad29e49f3bbe5c7d9bec90f5196030da0ae7d2f53012ee3da57a1e6211ba97ff628c99bdb970f4e4eef5e5d9876c7fc745eba80eaaa0ef0ebec9ad7d5843107d9010ce3b16ac6c4f7ec3bcfba69e837c1969684d11bf8a84e73f6daeebc04172a59774981e063a4d1f96c034f10e5a2530932e316dbabb094ef385d366adc6181af7796c968a5fa4219ad1973f85ce055a5ee61041a41cb6820df114a97376ddd674cddc2d16f58afc6180d297d57b1fa732b99e5a0287925417d1e0f5294a734aa18bc916a96bbbe546c9bbe396bc544df511f759199dd5eb35a6d142a9e6c020b5cc18742dc7de148a7e256b514187bcee7fda2b3f1f72a1f76bc781e8baa6c967a288fcd0dbfaf31b6cbdef85154d524f11a8f71f72d5324a03ee73a2e40addf8a1c2d0736b758892ebd85550c6c435c778683b8185d4b9679ca088feaede12cc420d333de5b496716d9757d39ec7766b32e075cae6c28d22a39775529dea89df549fdc4acb9024450bb0363568f886aeb0e0ada8d0bee4ec6778c09c11a41a37b4b7f679587b088ee60d9fcb3f6721f2101398f3a24642dce0d6eb644dcfacfd6acdf4b4649963a1b1c7d3305ea96f87f5d91a40492ab20306e8464eea669abaf954229cb9acd6a203ca1726a41ffd2006f64a8a6f82dbde57528e6213e4d367d9903e7d65832dcd5150d2e24d430dd4b03cf35f430309fddabef7223223825fce4d7070108cde61fb9cdb0fb03bdf5e5cd1194b668406a9a2042ac09f72215ebd7f534f350de1711e5a488c916e9587c8918e4402c7b6de7f877c6d5d328c73b9fbed972698118b15c8acd7a9ec126f09c4ea8c23929d415285cc61ebdf9f639777ec05e71de9b27f4e84e06f1cde546dacd142301508ebe4a72aa9efff4b6ee9992eb75b043855c37f2a6e636c4141572e8b00e71f26321a2d635f97ddcfe257f12020f9ebca4f0d61fe7f249c81c9c9e9b024344adffa6188d9e9499c94ade384a05c1644e0bc26f4840b5d599f7ed68211af6eb8852cd35c5be439925e2262b5f02df66bdfcf228c5707ef9d1d32bae49785b77379070a547887620f46551beb07219cc0adf1150ddc5d2f6c52559763906b6807ea7e34cdb62d1d2ae58aac37f11c03000000000000000000000000644769f7f3af64674efe9aa3f90d38b046179a06cb1b94a2e6c49b2fbb84712f1345687bff3a42b9505dc8565928fb47930bb5fed23b3f9cdf9b395f08777d739cf1940e57ed3e91b9ffa5d588336972fc7ad5765c7c7d88c61ba2695d8856c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7866fe20718db6626767dcfd2677e797dd94b100b44b04d7338f52f90d21e6e40ec42d2618b89c75faa9fbce829da3c734003c4a59f21ddb749f64172ebeabf42a4e6e8e948315445114aa8c06b020154a1bc8cfd4921dd047036f56c409d6024c14aac6d1e17d0c5e7a49a3979529b42386e3c7b09238b8f9c88838c7a3a050306da82057474f31301cb61f3837751eb91988ec5998d48998bb1c9829d911e1c02159f03ad724602f6647dddc13db23d796402d9408804b61d5692d99268b6ff500b0890c98594d2fe6dfd03fbc0c036f23d639277d8ac59822db65692a3c30284b8cb54e9bd9b13e348a0b96d8f54e2c70e5b6b7649725c15cd8b868454d5a2dcc5022fc1c131e0265fafd765a7d9f52c5f7e5bdd2fd1a97da826c25d2c86f61da03a031920dcc33ca92b1a38084f5eea21c0355b7ab913fe649dc9f93998197012e16a022c28ec88250f4e6a0ffe3d7b0dd157177e04e6c3bd577d63c942bab4bc20c192022b007a8462eff8956021ec77bcda2f7e1d04dcacc55f30d28da72b2b0902700f021e8eb87b521da1c70a4e0941ac8860c85c80c99d02a96538d1d1b96ab076ecf070edcc288bd453d58fbc7954546452e30bc2604fd10e84c028639279f2f691dca5ce208c722f723b9fa3b9437597762888189dff10ba1ea2ec83544e4ca23502ada4bf4bff776e3d92ee529db9776cdc1fbe24f59ab11ad3193774dd72c30469825dcae5ca751059dd9f1480843c1c66d5c4159226d6eb559de8e0c92f17c1e65b1111bc72edfab48c9b24e3195a807f80d46336a1e895df7e2229ecfe213cb143a22d0b536414c7887ac5252d20f80389beb31490268b2f781b55433456fc15f3be908213a1852c82810dbf399e67da2857b25d29f715c41d85411e6855be5a47163882d0e13c4508abc8e5a92cde8e128dc6c1c4a056387b8a951f245970bb287a8dc55617be08c86f4c42ad42a10375f9ea68151d457b108e7bc548157d9934107ff9381c0f609d164cc4ba6c4cea99eb2cd6b7368daf377b743527e67f05321b14bfe4dbcad301f1eccc8d963402aa4829a5e4986d7a5d6f9a5149820c8119ce365c1f7129146c19001789d5bd83f58a51533ff7b7721b2a172c59796ad953b5a36d394b5a7bdb697b30b22527f14a22f25639d21e6b10987906778fb4dc59f441147abbf99574bab02b5c4ffe6c91610be127faa0d025f9b4fde4b1f20cb9fb51222eda38f318af5899c18240f0bc1cf1e4a33da5c705fbf3c224f70f8507b3cd5367718d05c9e019f465120e0e82a214fd43b7e3aa2340a2ec9b668462f97d6bf5007410bc56a52c122f3158120519d79a2ec0e5cbf70b71d480944e7365772ef839b9f834c7ca96d1a0fc3a1573d283cb078b8eefe042bf852b2d646d52e27667ee6df8d125e032752edf9cda8549266249e6473937a89295ec7fee41cdc940af2f8c395c362580ebe38f4c6d8c9ea0b5e5a1d6ab3a76e91ef55f5eef779473d18047c44a4c8f31b9cd3984be11d7b02f35e5c443d9f230134cc45a04a189aa4c415eb29593f9c43b81d0d990ccc11624ce3a12a897f2c071704ca1a9321e1e718ef22451be33cdb6446aba264c59504888f07db9a85e52780f9a35f932ca99c26f2e21f877f9e490a93e99f6e4404810b1660c0317abc54c3abfe8c3bdfa3cd68847aabae9dafdad395292fbf60bd67ee6e2e0b0b21930925f612bc18020d17bb6fcc88965eb1ed459622d1a692023c9426ff7d48131b1f30bb74fe42333f16a311c911e900c0de4a3ef681a667b0a592b0b96e9512ce028f12a322c6f2598c28da97cc3d1434f828077a616226a9ab71395597a94b37b967c51dc10faae95197f65d1d40bf41102cfc5a6c6b1039e23435bbe1afb8fb1c859e08dce57bf5aedcb01de99d873df07721d27777af19d11f8ee18c8e2a317d863c25d23e5e41b8a050ba7ed07d0fc1618a158df7899fb2cc4e0894a40f54e2d6abe8a24c3be25ec18020b108d97040ff8e45675e91c36d29961b2b36baf06181949b3c441e1e6036208deff50688de72e6656533a148ef94f5b3f6f66815f1c9bd532733553560da2dff5954b7557fac88afa217926c9215653697819a5c9e3b5101baf989ada1bed0b483ae4d00d9849675a72d99b15ecb9492b71d0bf9e52ab88aaebc57fbf2ee3c6bbbd1b16b8b3912fca00509aec8b5fbc343741e63528993052011cf587a3f3ad4c7ac264b569efc4068eb35dcb357773d5079b77f21d7859dc0005d210baadcc9c4f504cec51b202ce39ea5b2bc5e0a94fae6f018c4fa3bd52f788566f4b99e527d717bff7d412930612fd12738db8144268e96122330b67bd6cd8ac18264d1efcb03fda5c0280036cfed2c68648e62cd8490201d74fa6269525b2e622921d5f250ee61bac66026a0a5f3a0d", "ac5153", 0, -1139268744, 1537743641, "cad766ae30a5100ca056876bd4c5920709c4ffef8a2fb74a0338b03b07ec14a7"], + ["a8b4e7090216a3342a6083093513ca87d71a894f17df1475975f1de165c5e58f257a18bf6c0000000008526551636a635163ffffffff6fbfcc4c231d34b57ae621de6a87d5554ae9ead8be6d5543ad0db55abe065a6300000000065251ac6552ac1ddbc63301b1b2d001000000000563536aac65cd386b1d020000000000000000e8b05b0000000000d80926812c8acdc480494dcaefa9dea9767758b7f87100486f053d9e885875b55c7d4efc60f28c99aec626c2979ba1d22e77cb57cf12166a85f1c17fe25e67aac61930a9edac6690f6c71f516235af473ef77da32a236118fb20ed029243f0cf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063304edf84a36fe4d8d4c4a2b167b61b0ba08f16b633107559ebbc47c065e4035cf613be2f4bcbdafdbfe76dd913788eefb4b90f8a19fd835682a214e9c4914e56c79f6f79768e8e1c072cb1e6986199ec4b60dc98365cf19d3dc9f736262718e848e6544be6300ae1cd14a32064361a9b147c2132c486e766e21e4c35b9adef0300de851556ab453c928377a1f6bc97f426fe18b091d17500c12207e0eefb41cd032f79a8b224a135b70d603b2ffed2514f0839703a71bcec6ecf9d133ff17403b00b062d8988599b496cbce2311d75c0464d1047a551e51c84a54f090ef3b6f11d22dd28329100ec7a2c8c64774e57fae0bf49b79e0d2abfbd78dbffd237324fd7380313535bf1399f5aedfde9bb6421dff896ec5df603b90d8981b60a3da9222d340d03240fd7bf2a4d246b667517bce0078f7e474edef0ea9879154a20ccc97e28f290031e2a76d279f887b1bb1d9bd5b760edb00d5293ab51c0f89540d8a051e92ecf740326d1ce9f06e91ab0eceba92fe21d35daf1c4aef6cb559e69458d47db9e57c5150209415b54ad5cc81da3869503b63be7468ca7f0524a3d406aa545bda352280452836acfcc38bd7940f8400685823d216a8c2e8e6e51a1134e95dae09b781950f930e34a7c46b968511f8eedc755734c60d0802dd01203df54eaa8856444bc9617e774358c87ccf7e493dddb1475ab455bf68535e3fb870c74314e70b83d8d471e5d3759aa8b4622065b7f4586c5ccf37946891cf8dc2399d9c3de80eacef6346cfb1d5527a49061145a8ad5048c4d893a0e8868c51fb782371cac94a4b01b8eaeed356250e0de21a5633285b870e9e8a8320dcc05d65a5915ddee279a8dc6f5f7816640f2df69601713828126c980a0741dfd4b4089a75d59083b63f16c125b3bf1cf92d38c4e3a996511a281a7da5b63ec41b1013d8fcdc5b8dd567a05d730e5e51506e25eba9c3101e800907f222a42c691efe84820ae62dda9f59b9d442f2e17f02efbe78bf7025714036bf5f717e7630d6681fc6fb4db2c4fb091dec2fb1da424dbf9537254684d8c0519e1b29ba6b82e010213afea1d0ed55293e85fa5a55990d184d7e1ae7820827c1ac1a3b0da941a370f4a381e46ea28692577d561d4d42df3f9f0dc5d12dc0f8a316ce84608d1eaec9a146800fd7a0a650eb819f00785e29462cee087fb5eebf8bb2315681906c3d3a96e1e9ca554d67c85eaac9278149e39ebd503a1b8aa33a9507f4fd69083495140c23ef5e51a5c16488054044206d9b5008da73cedc32af0a4b8cc4638cdeeff2b0774b87244d0955188a45e9bde2b2bc05579a5441d5571cf2284b74883c27f366c96ac058d0c8537617be443d4d68adcfbb622bd1e64f2fa807895ccb4d4591ae42849b98c9e88154b9eb54180aacf5bf5abef46e870dec2e827f808d69343e69e1500c9d6b6119b72defd22f42c83b2a23b78e3c77c4c6271541669c8ecea5b0cbb64d914515b5bbc69a2a8f56a6aeae7c9337191a03cb1206c5f62db041effd50872bfd12da0841ca41273d3d7438b10bb479788f9316e2a34db48307594e96e5e71a5179eed52293460d2b1db085525abff0398865570c47fa62def6e011f1960a1e1738b5ef7b50c2ca2a874a12b2726773f8aca04c18e9f95f5204146326888316ea5cd2f4c5f05568aec7f8722e286ec585fda2a80f19d0368cb3c9eaa6c9f4712a62ae127969071b886f18911a1a17f4162cb6885c6fe08e4d8acb66dd20d346df62fc6435c1c12728ad0de287ff5307ba76fbfec6dd9e59005665fb9958647ee91becb3f8ff890c44fead96d8e36e9af7a348a652acd17786040a1a4f2d70293bf513eb15fdbaa24ab5bcc85aa2a4b8c20bd847b8b1474589a81e90de25cb2d8a543cf86b0dda0b60f7f9b55bb43e40221b086db2f472f67fb8860219134b62691a3e82b6233095f671354f346ef855fb3614315f68529970ccbed0b35096f18655ed4bf855d4f197cf498faadbd4ba313fe5cdfdae3350a48277d4d1c4261afa20179e8e0aa1d8bdd958384254465de5176ff49fe4092b1847227244d6cb9571b62091423440f8050fe0ac0acebe20e02c2ec4190d9c67ecf4fb9b170a3aa40cb77729c9467c86e382cc113bb85735cd6a6e42c9433aa423396f3fbd9d7c56207f471f94a71622a4942ff0f7efbe9fadc35f683a9ea3e836df5ff68e41947f622e851061a28d41103b57e2ba2c12af716864936f2ebfeb09e1b14456c86c658bfee05f3484788d831bbb06f89fcc1e4626b71d0da963a40895b0000000000000000ad2d5104000000005295c5b78251599c221178ba565c51c64e4391ab83fc72166755243737367e6d3fc5ee9a80865abe1106458db464beaf17435b889d306b8bcbc9228821209f0176bf9f00152f85148a1e1ce1d7eb1c83070d0c9246964b5d1a4fd5a61a5cbda200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b7c9053d4f79e46c23efb031a1781732241d0728178ea28815e1adae178e00c0a8d53efcdc5c7e6d89c159b93b91e77772d072046f848dac84b43a6d257a15e11041e886781550de7aebf9df3218c0e8155b040ab79b18d8e72cff15f1392e220d5b447937a911729f8cb93299fae5b714a92b365b42d5f4edcd8a2e45610c6c030cda499a83c126818c82ecfc0af93bb04da72334679a229d763fb463ceea410203066b05a7ede0fded6d29e3f157acfd508d350317f40bde7a32ba81f43abb142c0a0289d0227c89f45cc73d83a66df4b686f927330134194e45e860693ff2d7fc89e6ad8c6e69af3869b8b0171201e3beae799b659dbd806bd07aee1ca441c630bf020915d245f65ee64895dab13c92af2b5d6e58ec9c4cc420bc982b6429e7b1cb1a0312afa518d101164e7d900d3519b57ce96d8a97679e593e7d1743194d3ad44a22020fcf72c05e8187aaf39f6d0819b6687efd48ef65425d37a1a6be0225b3d5332f021081539814925a8816daa2c2be229dc746e35a5ac55205d60672462e66149d730318e44908b4313c935d86c608314c36ef9b78576055d9c0c9b2586ad8335d846362069769cf23018ef3008a0ad908140bee2009c535ccfd9a53d1735eb0defb796063f46fc0fb86704e54fa76a324c0f33b8c1eeaaacf116cf589e2f5dee23ef705cc75d2438ea7a137eac222289d7df99c291adbd370ec904619b75a07ac576268e9f21f2b25a4aeff7995be7fe3ede53c892a661558bbb2b44daf836fabe4bc61bf907c43eeda2556a2827382da73863f78be822215cdfc234a310d37d49515331c2283b8351713a5eca2e2f138d4745fde0c33d352b7c96943c3164b28377f78f46e303048514099116b09c385cd4e8b4f4d44927e491fb47503461496215359cbb742b6d06ca64ebdcc379e8d7227b361f141783698eedbc6589cd90bb60b151952c5d5b4658e03023b6c701042dc84ad836a3440f8b3b89b16812bac8c1f9f9cfcfffe709ef4b8a99a3cd065f37390bc4a63a0febc0fb5a0041a05b3ff64822a15f86396c5eff0d89b1c108604fd841a6bde1f027462beec88d4658dff9cdfbc61ce3e5b348592fc97536e5a1dddfe58905006525f648eff17fef3b24805163c21d7be58ac7c95d463675f5d02480ddefbe3f5df26af6076978149d12f614292e608ad8d9706a4e973dcb5e90fe0d026180f72fbc577f4a4ee6a39ebf3c9bbeb8f9f60b9464fcba99c7fe0991df3af66957559895b7ff42412fa0ecdebb3ade5659b3b303bcdbc7963a28e5d421e2538c13317277d0618c5a01c8d56b95299975a5c53934966f03838be6c80b4e86db65428e9ab90ea2099c65445322ca135443f6a06c8399584f716670a4e9dd980cfcab10629c2c0b6478ad36f3a2ce63dfb2cbbd229ae11e0cbe843bcb3ed0ecd5d39c47df9b48d056c5065abf0a13a05c934c3c5517b7780cfabf39521b6be25700915948646ec14d15b0eae44c7236f572591203019dda5b3bf572e0a08bf2fa262e7e08cd3fbab5da71a65f5da0c2083a5868e16183429d1ec078ed6644cfe075c7f9bea5b1ea0f25777a5d979db6047963dba1be6f0943605fb2addc95dab5169b58dd6dffcff8b4d4ac30deb0ba43ffbfd6bb5b21df174b5a185f994f46174ad378718d4ff07cf229b617544c3f24e1dd1a6a8bbcdb0ea54569d130c1318195005c63eb5ae02c33483e1ef7ac438cdabc0cc13eb9baa22db09f19c3951ec9f5d577be3719d7863a2ff121912654e042d00ad91dbc48d9188f4c704ca7a5dd6884660735a1d5d041d0b283a551ddacf0bcfcf1144c18c369204571e43e0b093adf24ef5b3e1f869acfe4e2d29fd7b2bffb0f75812d2ee7725da1ab63fd09eb52b1dcf9a39b0de25960ae49912725c3bff7efa854f31417fc225d7f93cebb87ce66b5049cf967948bbc64201548faa7854d79d67795380959021ed2bd0f43d59a7a43690e53deba4493065e71e61ab5055599dfc9498825f6607c18597c1fe1298b0426e6c402bde3a9868b30cec8f89a2c0507a08c0f4bc09cae0868947f1f7a8770d52afe4b6fa36f4e221863948f57ba32ee2e2f932f63cc50136b04f344f29ebd585aa609eabf1e1d2b6f292b257cea051ad14603de45e70b875b4e6c5b656214fe75c831d84dc7e7436abff27ecb6c124e3e10efad2c79eb9be3caf1440a1a4476e8064ca912aa2fc333dfaaaa748dac491b2361f8a101a0241e6e51abfb4809d839b302759621fb02116d6cb0e7dee93e51696636af76d10013a35aedefcbd45d02cf843081cfa335f74abec950f4af0d12e367a9a878cf7105f021624144e243fdc818be5e68ab52885adccb866c9788583f06d938972d1f7f26ec3ab4e5eb6646738c37381f4dd706139a314c7876219fc044ef999a3048a53d13c01", "ac000000ac5352", 1, 1854065456, 1537743641, "20677cf0ea37e1ebac9cd7e46e88a1c92e9340e9fbbecb89b5febf5de7704d01"], + ["030000807082c40304293d4f1826d4c0fcf647f50f9ed5b1b7a5c129b2db2e05dce12010daae3d28ec030000000163ffffffffdf3ddde0245569a885166a102171e7c97c9adaba0bdfef6ec7d1911619c0fb16020000000665ac5351630011739205120621faa7f0e925e9be0e5ff412133865cca7979e8a81c69d2e89bd2a1ad9b103000000065252516a6a51ffffffff1c1a21a09430c8e73ab26ad910d4c7bf84ada735a3cf47a5d05e0e936fb5c6ca00000000085151005265ac5251ffffffff0331e51b00000000000500ac535100e14ec5020000000007525251ac516a521e4b27010000000004ac65ac5100000000f2a7da490100000000000000000c4c79040000000000f09a583c940ccb899dedf34793607996fe06c393e9916c221e76a22c4dcb3ba538a60184e2ab2c0c308218f516a4221a43288725dccf1ce75145bce0628bd67a3b968ed339848a82cec728db80600423370f9629f84c1c145e34bea8f3c5b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014321a3f0608e46cd812f5167732d778f819c362f7f51f45b200ca4d8cea6ce3b7528232d0476f09ac4e9a2d08c392252d35ce10562efadc4132bc841b0ded148a016ccbb0d2b31cc6c2663e7b41b07848114852111ea5edb39253112f23cfb724642f0ecb71fa9e6d4326e7a310c07a070a8d53480be259c2af15f43e27e0bf02087f3936adbf4202cbe862db9515180193e502f4a6750dd42f7ac625b31cdc04022d14a51985080b1ed2731f99c3edd24235326ca2f395abdb58cb9eb76ab9715c0b03fe01d404ea4574b4b51a063b70a93272e9746efed351cac75452fdf9aaab972bbe07e3c6de3cb38fbf63545c7b8712c0eb5e8a67e233e2e5ee0f99b2ff1b08020a52526ca8cf97b90b1f1a3e2c91bf9636f74ab3af223bb068df16eb394eeeba0210af534953e3713636a3a5e69ee92a10a9889a2fc8ed080522ed02b72a2d1fd3021c675b5fd8f504bc2637cbda9e7ec8e36d6d3c4690971f2128cbfd5fd86a1bf7022d44b5bcbf70753c3707060892247fe05e560f0662df1e7d45310b768f0704c3030df476ebb6733383c3c2d6162ce680f718ad0f0aac4ff7a20ce1fddb4f7dd1474b6396d99c839e8611e329c3856c2fb51648340aa61e6d6c02aa6faa9e1844b9a6d6a8b3d094b19b8d27bc7763a26ba541db7b50104b0c32c08a7e0b903d0a2e26a6dcb893a92dca61af9e480ac929e045e43c27a2b9d64dea43561a7dfe15f12d27d78400724ae3bc085bbf6b5ff054bcce0f673adea9494cea398afbaf38fa2676ffd433cc2af78318f763e4d136a224ce931d995e30d6ebaf690b9a7ccc1e0a7ae9c31b6b7b9384708191deedcd125d85de21122e2f09c4b23a8f10037a784910c4b92315a9ef4af46807ce2329937c5f6790fbf38431ae5b3dd3e73d09d2968674cc66c963995b2cbbdfee4409a46024a07080e63cc1d71866c15fdae4d18d620c2de40cc5cfc42905a1be7bec7b294a93b27e27adcfb4b66e557b524e013ae07a1f3969ac02b133c6bf90c3481540fa4d42b8b83bd88a138021689ebd8c2683f01af2c29d15b419e8ecdff230a3f9e6120e3e3e38b46d5a43e96433e02f8c20ce14e94b1a58ea69b0f3a7b2b71be77415f4868cffe89326c15b38611ae121b4153631945f4b1bf89b649b54ff258386fe085dd8d2c7e43a26d5894d7e175d00fc66bb259a2bcc0dfa26f81c39b07be96d391dee1590f19df52ec06333c6ee921237d5cd6e5f9fa705789420a33c139a7adac49d9e586b8f6cbf6c75229b09fb8ff7537e2bd74fd16a913caaeddf53ca357532ea3ba7426214984b394448f809acbd6298aaa934697fde7c9a9cfcdb6e4a6ccef3acfadcd750da8b7bdf324839e58622a2f2c0edf9796131f93f1e53d8413aa6568c1e6228a672a6a37dc8fe8eb39ae21eb25445ef21914ab27807fd1dc0d392ac2949e0e98602462771f387c1c47824d618d7d851bd798f0e18a758754a5e471713224317630754c2bc4ffbb10d93bde5b756e091ae1c45ca233b48fc1da98d9276a5fa04628d1bf38a56bddcdec1fdb9283ca75f398fbe789b387c7d6bb8ea8f4e99d58093cd4feba919ba4db43ae3a748cff1fa733b86bb297a15147f23c201bbad003393c3e48ff00c46d38c878f3083bbd7cc8a47de425697e6ce75c99bd168bc44076a5d21cf2af3a61ad193cf1c6873bbbf644f00f628f2048548a1150a28a5faee49e1963bbc54ee60ef41d808ffd79cfe57d28993159a1cb61b71780f011c8d149b3c21b548ca128324bee0a8ab8337f10993efcb7b177cf8527931718e29f01a9a62314a38f95c6c847fa703d935cdee5e2ec54f0b47fc15ac55c4d0a68ac4c0f2da65d465603e71d248a9f0eac9c5da0afe986f538778626ac869af8bff63cd641856e8e6e8f4560f19b60f92a9ce76e7a62b5e02a7fb307c8d162d26016037377121f9eb22e7aef27ce6706f6da63185fc02d95ee349e3fcceb4dab5ae7f3b14f9fbbbedf4f461e034f54e4f2f5fccb1ebb95b0c7412cf63172a82aa1ef4550fc0bc8bce2f0cf6b048e96f4b86572fb93d66de31bc347ded49d57c3aa7dc40c9dbb787cca7c17dfd10aaa633d5eeb3549719bca32436e1f285d480e42c5b28e7c28b9395272b4d742a86b92b81e4f066bd7edf76f27a5a8c83d99ff88b5acb4cfec0f2551ec220f26fd273858d607fa5ffdcaa50ed147a228be7171dbeb7a27d259d8143475b4fc867256b6cefe586a5b251b66cf65fede5b160c3f37dd1ba0726a0f1573184693f045c276ce18238c045dd71404d7e7078dac6525d533fbd9e82a7d92ac078872587973577d7e83370e1703c52e41b6877307a82865842ebcbb7dfd446e78243df14643225a98eaf554207670797c98adec683caa42ed6c84313c0ad6bfbcfd7773b203d3f6385a432152853acebdb05", "6a63", 0, 1286360618, 1537743641, "eaddbaa8e3eb8b047e124dab59982cde3aefaa11775fbcd86144b578670a8d42"], + ["030000807082c403031632d64a1a4a9b83ab8d0411692ce09513c51fa5ca9984222507549cd5be307b03000000096353535352006a6565ffffffffc021216fba5cea403bc8cca3b6734dc5a9273be1bb12fabe59aaf18bc00a01800200000003ac5163ffffffff232d349f157158eb27ab6db512577b7a62df71934ee1d16c4f090f94aa33ab2d020000000163ffffffff04b39f5a0200000000046a6a00537109d80100000000076a65526aacac53e2b69701000000000553000051ac2564a9050000000001003ae2777a0df4022f030000000000000000d5671501000000006f2b38eabaeda60038a28ba81bb8a09831cf0880bc83204459711003922686bca66e798b0d8b2a4a8592d359dfab729b7a823879735973ac0530eaefc3057284f6a1ea61a037e6c5740504edb1511e424441ae38c29506c325266e59892bec9d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000791e1aecf6ec3cb7a3dad8bb60827d4f5b17f5c95b0e50d52509c55357d06cd22dbfa359acdd11de9fe1af8a84305c563bf333ab6a2d167f53faa4e3e67cde6f605acbfbe21049edff393da3f1cf0d76185db402803086374f193f0eca5e43972312a9835c60e1fd21e55063d6ff3b261c654b2d4619ca34ff81e837e035cd8e0322aa6880cf4e64ff397e2305e8910d73258af16addb359ee791e0ce9c4c3aea30300b63027ea634ae826d82d852bd70ea64c23f61010a4b5aade8b2091da583a0e0a0043a32a01ce630cd4c719ea95ecdf7e566f60f2ece13dee5b0407203ba6bafd9800ff945d35a3841f4f3cee48e12ac397687ab6db920aa1d92228b0f88c34bd022881f9394184e8a94590356d02c0137ea6d26f8989a36cf067e5de33923c9f5703205224e27ac33c1875516191b0ee53f011a7f5f85f02746d5585fa707a8c7b03020f40489dcca6e3fcbe1923488435a402e306e9e70dc19b770891bb112736c8ff0204f001e2513c2db8b2c0e9e851623d196bb941ee778e98fd18cef94d8f90880d0213c86eb18ec65d8a18a057e37d5a886795bb32d57eb3317490cadd13968a3d4ed2bfc93884166f30b65497428ae54078742cf280e5726dddabda75aba9e45a3eb07498962b15628167010ef35f6f74ba13659f5a81507c36e5126b4c98e0b3890fd1860efe5f95a9f765d6bf4eb9f9bca03b7231b1870423ca5211fc0c63da3a4559ef209ce4df215626ba5c8b28d9d75599dd9026fa18988824aa4c3cfd54ca694eb383f01c867f7bf1330e61ed222ab3d6df39dbe91a38cb133fa9e47cb2cdc65251509bf14cc31ea2c17327f091e9f14c346023fb4b2eefd5d8c4251615c1643217042490bc31610232657ded1e858b45f075349fe071229ebd918ada28517a9df56095f08c75a9b83415c4ee44039128fce982c7cd3cd701a68a19569ff1bf59770046451f8fdd13231c8a481b5fd3c32ac9138d58afcf99542ceff959e57214a71858b57bbd47e59d32c4e70da1c2aa3efa8b881353e0a515e16cddb8ed1d2a4a3770fefefe727e96f95aab4632f32c7f0c8c055b2805b8d345e8d66d64af682df6ee769cbaff54999fd95845b2c340a1f76839bbbdd0dcf0ab793457175e0243c7695820eff7d36ef779f1a3a07378a8f6f8d32a7473b217586cfd7b934e31904384b3e1bc720b0865822c3ada77517f165435cac5e07e2ba27d955da56028e4ed9b5df2171e3e71d61b6619b8f921f5588a8857a35087fb522dfa56e9aed001b78ceac9813719edbac574e29dd1b26e3cd5abd7443307cf3e17923408780dcfb6646f7e3110fb0e10c6a2b3af9ca61623b3b5cccfa371656a0f444182f4cfc9c84ce34bd4d3156dc6939962d1e4c6cf2c3046beaf8af2b62144428527973591d0c0889733c0df4b946924cac8a3da7abe6aeec4942d5a49eb5f837af46a3abaf31ee47f02f849146a5ac185475213279b764aa0986c98e340fbf12372da982dd775748c23c893f5ac704ab3250418e04959997f0c96d2a6ebbe77434fab2f8aa5feb080cd995bc61e7914e5b5c222ab3202ef334598dbebe5010c7874cf9fff58af6dea498f5b8d1c680903aa84fe885c2112dcd1a4e7112abc4ce3be2404b5fced6a5ca48494fe332785056a831967b0f04c8203b099fa8683cd50a42d6d497fb0537e647e6b62e745e517f7cd575340eec46bccf6d40937f87eaebfdb2f71f85ffc60df986f62a6d0478adfefb57f0862a22a5caf1c70d5b08817e818a40740ac2b2d55bf6831532432765b7340eaf3ad8b5a1e9a2c47ac4c859c0f28627afadf47b7e40b21a9551f078019deb15e5f1f0388a05e88c65e2610f850f9494182c2b7a0ecfd55449b242d65425fe9cbea89e61a3e0999fdf08e1e399412ce6e4a2f7074b3a5a2e6291be96a33c11d49e2ce09c6a34df15fed9db657c256c51e0a949d9fcaf02fc4a24db31a795323c5e4c0fd53bb16110a3ebd85329845950849b5cc53c5f50a21d3b591b6f528175508582f42bd12dcb78d58d70ab01520487f218d2c3a9c25b48af9172736b0c4a62e6f9169f43dc9c39a312b9ffaf95a8b1237f2b0c13fa3beca126760ef411835dfc9dcfadeef6d5daeb46f2972956a52178f3f08481fdbf8aeffe3f05b8704c99c1d78b2abb3ad8cea4e84313b4a92bc5425d363a2315192a25cb9c98605089cce0df02882249406f068982298a249f51b9be1aee377fa1b7bb48a1f0bd140837b633d469f78825055116cc6b349f8e499ed7210d901bc96f80f3ed46dec4a0000000000000000980e740500000000375c1a08b2ec44c163567d9265d99f347c69302cddc2c55d6dd4c03a576881377c6c1a6bbda7d47f6cd86ce67eebd96bd1fc91bb38797cfd994485099c39044df86ac6231142e54639363b853a21bbb31be6139daad3f01342f760d1ed3b143200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2f45aa5c70006186ba9ac82686683d11bb71c1bebab08a430c55a0c723a4759674c5cba6895dc8d01a8636a6a902f58957f9dd8e72e9c77832b8b85282da3382824f83c1acd6d3d7e66ef881a78d2b8d6b1f983d3c0554fb2b0ea4509f9cd2a803ffe7ecfd1660f8b2fc5e7557c875e5ea736dd7b297e24544d640df99131c5022f62ed6fb7d80fc81d6f90939f54b3659aea7892efe48d5dc229ecc4463c0d64021c149c1a87834cdfe14d2b8fd927e9548e829e754f64666df92abf4df97036390b01eaf0b85f85bfb2ebb023541aaa50f96018c6686550ed2b313158ba6676235fd495066928f624da6f3b97baead1f344c077294c67df69cd255002eb9c0227d30329a088b6fc40c72ff448e98994bec7a20b016f5e736c15674ab75a2c739c142903035873fe706dbe2b254a5b91965f75884c4bf28a8e464867ab66e3903bcb5dd903117c99e1368c27dc3ca9382d1432390ca778b38d7af72bcc4ebafadcaf3f7323030bf582008292b798413380de9f90d9faa59155203cfa19c5a2b0babb7545fd5303255b9a44488aec5119bee76f5bdecc8dcbbe42b1536fddee5f0fe391000f44ea455081ccc9df7f15015bfa14efb3aac74c5b15fa272e88e3109edd75b5ab4f9a8621638f9c14946267e9cfd2770bfbb451fea7e6ff85183c8d83c9f2a1b37eddccd2ceeaa808aa9a57c8651afbcd094e14bc9330683090f4b96c5a0cadd38b5c5ad9ef6297441c75547d58d545dda56d4c043a865188d3910984e2a82b79911c9f008bcd68c1169b68111397156a18c42eba5079a0a67d32271fd744177b5968c71246ac79d6a6c35cc25872e27d69b320e7161a0495774815fd4ae70698b5af863d0a2dcf197acce4b784fcee71a17e631acdc281496c065af2d4862bf8615a55f0438f4777d6a7cc3754dce443a4de1682fcae594bea333b5ba19e032cc8ef8e09c76fdd3167bdfbbba18702f402e183bddf53e0a41cf2dd2bed3d60c7d3234b4f277ed44e4e273b7ffec5be086881eedeca5acaf5e4605e7e03f72cda26ee648386fa21e2263d356a92bd7cc4d107aa3c5b906ce102af91e8f1488b21c382a01c8c78d97476fa953dcd081645769c0ffd0f9121f0b40045c10b34963846031e2a1f3af8f8307e032803a4e42f973399f7053f8094d97c7633815bca8978e787904a1debb9ec6760b5334cc5fdb6bd1f12a20f85c7e097abac8bc3e7aceee829f77764e03dddcfd2cd22bdfea22b94125f966a4ed162753558129b52991334c4e43ee9dca4f00744e9379a1d4e71dfc9736c13cef5be4ccb6f240f9fd8896ee1c92855cff87b4a0235b034a5f70345dd76c52255a43dc631ac33e7a82e27a919db5a4b35b6cd4e619ea77b8885db9d1f06954bb90320af6d6954788b4c1e5572f837a90b2816c0e3b267103c392765951effdc151ef81489f19a64fdf8648aff88f67c1b8e190abcb8d1719c55d07b1b4ee511abf0a2dcbc310468e5263f5f604b73694e129a88a7291e68d34a29b371819db8152dfee6b050e8956c5379148bdbcfd7823f9d981a91db82cb1f6369705b456dc6adcd34182ff32d21f13f97790a9bc9a7c89c47b8b3ba0cf51cd1a6e8525c8f577fa55cbcb1ed32496c88da153b4850f521e71be71eb2d6c025f6c676e93363ddf523b572f1d5f48a356175549d30bae932f71c10479390341df3283cde762b56c4784790be6677c04acb465dc864f275284fd82060f89f4c7c0c5dfde4b84ddc37fcc9c9738ece825306c22538c1ae31969ea34a965bb55c235b15a7dca16d37a6fc8a4db13944656dfb64f17defe5e8c67b52b6673bd6aaf21032887c893b5c6087c0194232b7aa1a97a2d5d897272362943510e6d529912f28297789c64c1ea3c258185b2e9d76774bf26c5d3abeb182ba622785c765b1c201ae8a7b7837f91d4656fb9f1a1b5f0b589caff8ff75838e16e93403fd5080a31e675f495b65d7aacc36ab2a43dd5dfe268d4554130ef9f5b78f668c4e94c787b5c5d7dea7608a6a0284de08f010f75ca2d70235fa03965718aa257c6cbfa0007f404201f29b2ef1c942fa8c52b74064d2bcb2848b6604f8c8d19e4ae89ede97b55f5a6f1dc75324a920ae696513f502d7b25401fc155b9c7e980b212dbc34fc306d851be51be144bf7267f2692bb32bf22f1d29af2a496a4da8aabcbd39c2f618ab38ede643b2ebd9e663ddb0827a009a096b0bcdd6f6c892690b113706ea6aaa394708fd0163477b86024c828efd2e6f34fc10ea536843be06c24e4b83ff5b112db32a82756301000000000000000000000000eeb221cbec58acf6b6e685a4c8475cb6be534bef4f5edd3c71681386104e7413a3b8dcce1333771520173fe00fe4029b0632c90c40f528c78fd5796cb0dc23b4b7713b3f195b6a00ddfb1af6cc3f19c915755c6d95b6f693d5f3f42d29b9c6420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f5d65995809389d8556ae6d45bb196b2003bcee9bcf87efdbe014ecf2c24dbb712a025619b67eb8ca071ac1b29356ca1e2e800f2c1a5a4bd9a8c6bf9672988c2a57064aec9b0fa0cc863c18da24293ac4127cc426b5c5b5b66c9a80e4a55c4472c19f12d06685c0a41232dca5972aba1db67fe65f41501e2134a9bf80b6181020ef179894dcb5c9837b159a4dbef1bb882cc245917fd0a26043707c44a99847c0303733548607d9eedc9d2bb0bfeea688bb9d44f2904935c9ffe46d31d112b0eb30b008e13b40f943fde66c126abb040a9c0e2cdc115b5eb646876d21d64461c09f4227678d659a0e3dafa919fd4ad4416c7bb6209f2b13695ef348bda2c473d8961030f436c68a9c835bd626e73d89407ef1c6eae77c75e2e5811806f7daf39d3b148031de846bc8b4b27d81da6ac8c42cd668092f38584507ccfa3e189b4f64b2ee4c70228102c47c301f942412f4cd7427ab61e0423cf7630e3c70401c83b3a04df680a0306cebbc5fc37b0570983a8f0a6b7315793c39f5a8976aab3bb0438fe6f0cd60d020241a76e925c87069150a58a5bffa71333d577c38b2cfcd5d20543d12b5587cdf8ea44eb7e36b8ec27d8307c7db3b59f96a9eaa4d9edf3d561b92f3d07eca5bb0383da71c9b80d37f9f6aa823a603feb192dca8a2b0fc5867e6dace2320173f19ae91fd598c8854206563cfba8890a626fffbb892d2cdd5e77a026bdf8d7bf129d19a50bc9026c3bd9b9008cdfdcca8446a7fa4e322a5239de4d573f6330ed6e79b34b0627586f35f066afe9c32bb0b676dcef9aa09368e2dd5633c3fb65d616f8081fbaf402d4940d0b2c40398c6da5f4f575e18c167760fe6e0411259a859ecbe3a3e1305a1b2c2ca6e573320eaaf8155c3139488f5ccd132db435bda913c8d54130e9c20297c72ca42ede9d19871667e7c77b806a9df92138338d960759498c599e6d0476c3f6b5cbc671c2a883a44ca5b9490063864436a03e75e6995e051b18a0e8a52a4a1a3bb9471153a30f373ddaeab57a732a7e90e086f20289f29a56043e625ad4570cbd16b2854cb8230b8786c7cf74387fd10d68407737008ae662e448c95d09f510755c5eb5399f0aba321be4cd6f8ebba316af52369fc84d072a5cd41789d823becb0a1e8e4d0fc8e84e3c4244601b2a9cb2b2b4d8977ccc36599f17ca6022e312643339eb7068f527073ccb0230c1b94d5771949c74b4b0e28c4348775c4fec467e97e2d027d72f8829b7261089a872dbf5b61593bb7158c13d7f2baef406faa990a144249cf4ac35f2f8ed3da00d971acbed7186aadc2b77f76a5f10bbefefc07fb12f6f784a00cfd1ebd6ae5e03c6826dcf4679a08dd3b3a8be6be79af787fb63dd023d9ffcdda5def0ea312709909d6d9fbb447e5eb049e8cbd0de36fb1a4fb15ed082ec89c7df30854de6a579e35fafd881c4b35af14bf9a68b01948b1ea6fb5e6ee162d4a370ec06c3ba0ca42bb574d77670d81ff2af9c0aaf45bd1cd0e37ee5fc9623299c7f475363eff3f379eba90ee2dca5a8793979b8e35743d1c5bd486ebc3f173ac41b2793e719e58ffaab53b29b6445cc692f8838c9bf783e8a1b6eab5ef70b5149b06001df97c1956997d71c4fdc322bf6c386a10d9a4aa2d1ba34f7374acd8d707428cdc454487edd60695fd511ef7694d2470836edee4d0b2e31fba0d9568f79a1159102ab73099935d832f6b4a4555a55b71b7ac33575a738ecb50f53ccebc06d922de315b8373af2841c6849c63c4e3c8a671d94304cbf88d4017c44f485a133156fc366878073c5379ca19464ac57e21c4941a56a91a279cf4d28933729b15947024c6602db2bc2e2f6bed0a700541c11233034525e860075da9e79f06673159bce2e388b20ceeff0702cbc3ea2722131f150ce9322e811387ea66f1ef60f6b57bef12c7ba4aca9b8bcd61d00e89e8af250f105e3b9d10b397575a249dc571b88fe9d39f8d7da032d4e26b005a6eba5f738bed3aa037580838c45e21021837e88b0e9a6995e1918b3c9a0bc007fbf6f85215ba02b8654eb9d9132a52277211310c3e5e1e2841a191e03057f0bf86d09cc21cf2fb500f5695708c0c3f8c402575bbf79ba5541df1c52d8b68f6e826b716a963deb310dbbf979d55e4166c3ab6361442e9af7b52a5a486c710f17d4cce642c6d5388d7596ab8136eac45323655f90f4be5373b1b995df77c73b96b8218aeee26e258b7331e88e9106714394d70c27524f0fc232e629a966e89286fd4fa106ad04df515686924159523499177bd174ba3fc72eee193cde8d41ea357a17ecfab2c3ee89ab3fcbb3be3c03953d39eb3b0751fdb0e637e895108d35c3ded67d6863188fd9355b7eeac5dda1bd3b312e86cb8c7366534a2fd4ba3100626a7b5d7015c91417e1cb96ce5abb6f8694788c3f0d", "6a", 0, 429089975, 0, "194a7086fbb7b0a377ddfa403cfb20e502545089ea1e5a38a3f8f4c1beee076b"], + ["32580e17037a65622458d6a31e425a8a4d9709f87bcdcc65c7666904901f6b031491a1593801000000025163000d214d778cdbfab0ba415a6f686265e0c6b74111c92fb7a95fb1a39b2c2a8dc4195ba3000000000751650063006300d4330582d4bd655236690ff6ca3089e5d8acbdc8488704cce73495a11a8970d428d4e05f020000000200523f2e657a03a98c0c0100000000050065ac6351eda652020000000000dfc9ae0000000000030063650000000001a9b8b1020000000000000000000000007721e68b2ad6f5d0b0e558c2ccfd5201938e26df5cdeb45950d9e3909d53cae6e53ef60873b1aa63309557c9245a0370f43f483ee22fb6c186876f6468ef22c2c49145ddb33efa737257d1ed3faa6b21d6cf15762ffc075ffa3f755ddc786cf6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005964d979437c76fab906b2349a82b7511c7a6fbf38629b34ae9ab4be84aa808839783b07c1487362680ca160b5262f9d7db69a6c42414934721d3c69c497a48496c2894c96ae86f6cf3dab79be25704b78cf4edb1e618e40f08fa0e679bd6851ac48c766bc1491a8a191c08c2fa2774fc12315e846ad9b49bd4cc735a8699b2b02299b6c0179f8f503bbe0ede3bc0080435b31908a4d1a86cd004f924deda458d8030a153fc4db41874d67172b9a0245f93ad12843644ac27d47077c953bf803616f0b04d328e44acba87dea46b2f09de9e14afde9202cb9a9539efce78a1efdaa6e45de234f1f160d8697139abd7c81c10bcb8db07ef4af0e16d40087e6d5db0c67f7022f739643273e91ca52bb5b68a859436f34d279fca1c4aeb5354f18b59056a4d3030a53ed837d39e270b90ed92fa056ea28e7f4dbccf1437e7d35f29861b421c3610211b1b3d8294de90af5428d218b01558d3cd9892378e36a9fe09984c0b4c730a2030f9fef57345567b07520a90c08b00fd36a16ec7b6ff1f855db45f12e2d4ebf540219792bc7c1f48fd20c0f28ab3eeab417bb9293c6ed0a2c1c90c0bdaeb68cc69ae3a3da8f26328fa4324ebccd1a9adbe5804cd175d3dadac14be2cd3746328b33e114ccffe40091ebc8f4a81a484c5686af2428640b4dc8eeafec5fcf8418cf398bfa208efcc74ff3ab88e53537a5fd7048931415b6634f373cd13e430198bd3a1d0c1fbe2c4211aba4e6efed990f70ed313da3237d036bafa4b4095818d78d8af3ea6283b8aa9fd4a42b6b196333f0de66bae5857ad4306d376697cd54582480606e6be54972f2bfb6d220ca77ce0a89dac5a06fcd0039b78ec479586a6dbaa0a7f4335a932977f27112f3e931c9cbb61bc1a46e0c4fbf1ff1a67d346039582a836929b2369bab9c615dd43e4e4d1030e443e1dab6af0f53120c0622b97f54a89aff538f5af0c75c0de660e9d4e2cb8a666d54f60eff9a838cdd53d53552e1f31e745185a88e1cd149ff1be15d1eada86eee97b74a2a2ce99e85c919e515c0f4eb81606fe378e23d7f3fc2985418e879fbf9500dcc5c03d57b2787351d8fe07263ec54ae557a8bd057ab0f7a3934fd4c8ba164a43029c9cfbb295b77e27ec7643f6439cc1369eef35bdbe339908ab7ab15de964110805d35013ace3bdedb4b2cbc9d67ae1e13a5bc69622c88def254d7fee8d73d97a905181afbbc01b0d39de9c0b598dbccf302ef264fa74d4e901bd612cebab0c9f821998978f50eed23a32b0179593dbc8e3fb5aea3b3c5cfe9a5d630b699274d7b3121afa73d001d0ff3e48f2fc5612863cdcef5f5028e067d8ee72e77455fd7b78792187d5f5a9c41c52d86f96cadb7f468cfe8900aecece2bbf3db4a91d9920f18853765a33df0200a71dfe448beadebcdd1f7d6a9c726d0f93fece5dfd220a5b8f8e02c40d7193fe9ad4d41763848464d2d05741f0262c57b9d31abb26c596cc79b1bad3fa12484da1c85ceb654b8a1e1fd757398c056a3d7787394b45a99974f290672d7f5d86d8c91551c9274718d81f275da2e7dd6cd3065811b25a0b45d0c6aeee16b369aa52c0edffb1a6e53c50ebd58c195381675cefaaff8601017d4e9097b5b7b5a39d70cd75f529a219e52abd84889079f8d9756b3513f0cd8553d1edb597b14963b60db6080389f9a003497035545c44cc0e4cbb3f460862195c7081f68f580108494329ca18909dc2d00fd5076f12f071661b3f5f763291b47a4c7fa68ca60dbb9a1ed3fd03156844c536af471fdbb7fe407c0135d2798be602f0feea4f424f6081e315892bd12222d626dcec7c79fc82cfe9441615f4c3d77f38cbbc25571e1f58728fc67f13a07705aa8ce4886c82a00644ad3fd95c3739450d77d51d38843d2a5d9e354e80576a94f180b9a80490c5511d409b81c4ac442a2bcbcfd6e041df4612feed9248dbaa43e68998ddbf5564001aff573857c19947a45f31ddd84ed5a750abe5343efe6389c7f91b4f30a2522f8b304e2e95b7ee0e53d3ad1a52c9532da78d89731ca89d80a04de60ca91a2b1ef2a17cdbf61f035046f7fc414503e5b745d61b4e532e673d31d4f05d7e3cd5b829231abcb424f96ecdf85e4a2548d9156e816b41614ae39cca69036bff4592ec536fe42085ff6c0e23a8830a939ecb3c4236f6e4c3b58ccafec95a2012a345524d1ec11855f4f72d482eaf0ff54e9791316073880d488cc7a6a1c6ec0b365337811a4fbe31bc919e1128c1003c250f282ed8372b708c54e657260cf60d36ee606f9e1544e41f9b3776d82552856374f145fcd1916440a541afaedbdfb32e5960027e393b319c036c80cbbbe5d8e2ef2ddc5640626a83f2b55b3bd6778bfa17b318af668b11d80a3137de34bcac58be037bea68adbb37cbd3077c524a35ef4460897d6790a", "65656352", 0, 1061033422, 0, "ceae4b1823649e6718d4d38c245ca7ccc57b6cf3226f5444e4b94a6754782daa"], + ["030000807082c4030378fec15c8e75ec91cd861b49cdc83b25a0ed3c6f9138395a268541554d86f615020000000251acffffffff784e02658944a10d4a3608c1d598db3072f24f9d2a894cd0a3188abf2c8a41930100000007525363ac650063ffffffffff177ddefd0a15a93592206ad8f96a6951c4e57dd8e4cdeeaa14eef4d3fcdbda0100000007acac0065006500d5cd3d380146a308000000000008535263ac515165ac00000000b48ed1b300", "006a6aac", 1, 1254699060, 1537743641, "2bfecb8a24721cbce09085a6427585f8e758da64e8952e689471e7346f8859d0"], + ["c058414604bd2cde2cc35bb29f2f1ef59cfa4045b3505b5704b4d90886a1820391bcfdb9250000000000fffffffffbeb78716102a8a3c044b4394ee13eb97a2263f020352ccd75055b78d6c1d0bd000000000083c5db2464302abc4262ab5c02a59145439d3705a143378abfb0745ccc19a136ba2d7c530200000003516a65ffffffff24a947846c8ca82d92a1732d3525591f2116a2ad900e80f2348c88eefc7155a403000000096a52ac52005253ac51ffffffff023239890100000000001d1425050000000004acac656a0f056bb40100000000000000006df7d4040000000046a1900395ca086ad8fc2460fdc18dfdbc3def907e408cd5999d34addf42f4605be7fdc06a0fe898f370583430812a64e48ca4b67b468a283ea577df16ca0f20f3e2af08fee914b7cb2c6c67a2f245cd8ce1ee260e77b9dc0085f69da6c34ac300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5a96655661413bd4a59ac30675f8b10c597060a5cedb09ba4da58561710e009ebf29825bf76a1598f7acb42787d8f5bc8fe2c4e027c7c7c6f932fc93cf3fbd0614ffe70f4a6eac00fc584b98302f467c5bf5c4ec19ac27c434a69feb38805486277f121bffb50b4a15a430464fb1bc3514aadb76eef6151976528d0e76524fd021267bf4b544dc4cf3165f5b3db1d0d87648b26335e27710f89c3a14a499afe400322e7c483c513e4070c3419b97c74da9bc74070fe7183003afb2d1bbcef296a070b0029d15d66bbeb8d47ae02b632f31583fb01e609acad89b236b96afcceda3f9f6cf365020014aa98c52dba1513c6f3bdf561336b6b01d039a2caac5c70de696b0306ccd31f1bd7c3b0ea00230e826aba16dfff46cff644a12c707543e3384ee0610304ccbb8d897e401aa65f4618e00548f9cc1e922758fec1e19ef3402036fecbe30224ca76485a58c018a77165341d4d3741d4eb4979b837e2e9cd1ae9f0e3f67856032d6c7cdb7d04409ff687b707729bc9b57e5419ef73365e378be3443ec1ed7f8203042739bbfce95117363d730d7cdf2818446d4b17cc32b7b88b2e0c3bdb02d6ed7faff6a82c3e675a0dcdee1cd22cea299688413fefe563d6ac370cbb9c7bc89471a1dcccd02e219b1384288867cce9d6bc5179fece5216bab7f9bc2d7313abb5fcf2caa30f8b52b682f179dd31b74d22a5cabe2dc024f52d4fe3b98b4a8cb84652e4c2d042e5214f757efc91c284098124e5478a7c8565b9ec951c20508df95f740cd7e4cdf8ac4268376468e240a00b0fdd2f01c3416e64f49e555b8ca645f66798497eb497b9fb785465a879fb92eb3d9fa24e598e6552306ffed4c197425b6c1da0117fa42df18570d3c2c61bfc2fdb5f994c697a6118683af07d6e94382a1215b0688fed0635c9ec64f26146fc097b4fd6129fb6c2b9cb1c7467f16eaef51c4e8b55b467186578f588ab0559155bb0a769954927506acc7e0dfdde573ab2d192b2a00b162a01a9b3cad080f97b1f0e435aff4b34b64303dc7d1f54f422e80c58839bcef9e50416f971e1fa0fef43085c8303a3a20967387320a8c268d8c8bc778bb90e2fd16c3d7847a70f47c9394f8bd5ee35a9f29f2172201876ffc6e6681edbf96c809baca4002d76b43056f17c9c97a3a454b8775bd50be7e545bd39a06f999b3bae3445e6667e0fb94fe98c873e4ea842dd22145f0e6eef75a058846f2619e1a7a7490813c92e6e20d0bb2c19ab870a731ef7592f781a7020d2826e639e99d05ef76cd10a23c8094bb08b344f47fba48b6756f8ddbc6b77b2afdaaa6e8841be665eb18bd270f007f047fe8a6011a66e4fd9c73e7a873455ba58ad85c2b6a9848b72b0543423c5b8d2c85e243a22375c50460e358ab8400e15f46dbe26ae69197a2ac2b81bfb3399059d9fa634c5eb46c8b1cdae4531e7fa2ea6c18f78cd557fef5e5b1e2d376b4867d7ec44d3fa18821d57c6119a44ae73c3878b58ff3fb9a10bf435e4b8d09d5d6ff8a822e88286ace6770c922e4c02263347ba1a7367edbf144cdc9cbacedaab6a582642cd23a0522f5c5a0952761c5c2cd85f8b2189dbe250a9146fb6c517484f4f1dcdf472534cae538474103bfaa7806652728c5200effbe4164bead0fed245e9e7d26d8ca43dd5906d9fa35d7d9c5104838349caee8c89be941b4b1a9e516dd7724c5043137646185a4da6b297006bd56f79666fb5d2f4e1156369b4f2d6e966dcbe0fc5508698a6abd4eafac1c9fe026e3f19605863698a5dd896fb140aa5ec91694b759a45492092ef7eb0cb09e4e102e106b6b21039b45c4cb296f5cf2e6d6b823a9967d41cb30c6fb3a32b854abba724002045ba602daf3b37716b36611fcbc47498e9ac10dfacd86a95d8b087c1868c45007e9cfd060708f96972a9b489ea9af43a21874429c9ee987351e7311d999f3b73a2cfde57ece920167a5e8ec2bde88b565f637f048085c9b7a3879d3479db9f07bd955affa3270630c2a4a7bd983fb8deef487bab855f1103519272fd6b3555c28c4132a23cd945aa4f9369b616a0224e4b32452343e3b0a1df02f46e6b353796c0e6d8499a54455bbb54646687ec7bc212916d8baa30aa0a403d31a362a17de9c464a648b2b1c5126c7524bcef17d9d8b59315d9f203ea3696d0c56da3846d505f5b985adcae75b2d668055995e4d7268b0a4c47ebf77fd8bc26a9700b41be3ac48295df93e1ff8733ff7fd091e882c26baee6eca3a5767ea3a68496bafa0aaddbb9e4cd4ccb1dce4acb17cb2939f89abdf23b0c738341ab0f0a1cd9ae66b9d8291ced3691f8dbd9106a44a8c3d56361079d4aa2f683f3d5615a98bc0c798a322c38d1d1c5a46b0412a99afb88acd1524a2ef2c00a55e758b1e6196eb5f6607d4153a6c9926a858f9cde2018fda47e0c", "65515200536a0051ac", 2, -1243808973, 1537743641, "dc1567e9659bfd002fadab9a5c950316b3ee1c4889e3282f5bd062b25d708fe0"], + ["1b71ae410168ac71f33785ab3b67842d368082cc0d3be7fb9ca4c6b4a50362b5f926e51270020000000351ac654c398b0e02f9a9ec00000000000900ac63656a51536a537b6d8d0000000000000000000003fd458b04000000000000000000000000e7c465ac97838f61aa86accb9fcbf4f1980c6950c00f73220118d07092000a0c72e55a42b840ded10a2f05558ddab57f4548c22ca451280bb46d0831354572e75a997a0e3787be217c5b2df5dc1344576b48cb8b8333fb06729bf0e28d2a7cf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036ef93e8836b43403f5f2ce383af4f04d82597971c67348d99a4bea564358cd0b06f98214287da510ce444d803fb4c00b2be379baf7a2f89aab8e4ac165ae002ae5a3b6f5c993fe7b4d1018cc2279bfd8daf58b4acd8a05b9422c2b0df1c4a0eba7028b6d050d0f019f3a4aea40e8881a8042f661a7d1d03d6c86bb8e5fed8d7031746b58887f4886fd64b25565c7c3aa1f3653c333784785f08e6c18cc3e1d206032315e1983c1de45cbc9f404e900e451d9fdd474f2b19853ce6772e5b147ab3ae0b076ecf20c5a44d124bb35f8a9d04978691ecd5d8917f47eadbbcba6db6b81037bcb4cf9450d2c5dad14bfff414120e58d7a3e799d5f7cc9c09ef9ddea267b1f5031bdd741d846eab5f47d7535a2649ae537e64ece3c4ac766f61bf8c81e6a62dde02017db405b0373dccfabb3da533763e4f784064cf8f40907845e70159359827bc030d1d9b5968e68800f3c990b0f3f7efab93135b341e77f0d1d87112e2f4ee65dd020aa9969ea39c2527ba9cf7e997236c67ab5aadbd282a854090824e66d1b689610207d4b44e7e1d3788ae5e0765682d898b175e19700ef3bbe85ed6d68205f4127687f5bf3d7d6292a13cab0d19eca9a03496665b9a892a88574f2638386d5220c6106fb3ab6a55e664d9d4630a48fcf2663ba38b3e391ae344176f611151da205a90fc1185335c5f60d5c81e00bccfff90bb9fe8c52a771ea575ba236d2db7f381e820474317cc45ed9a2488e1040b7c69261c8ea80ea4ab2a7a923001d135e07bdf55cec6c1323d5eb431609edfdd05f58381711b0a322bd578f2fc13c6de94c246460ac3117d4f913761e2b80133def481fe094f3499249239610451d56244c7990021b4f7aff4afec0150c9d1adb78e671d9f6dedd8e4f4033afc994c42cb8b2ac264d7c90eb118053083b45627f7a775ed185e676b6ca4c799ba9f38ccdfd20ad9d580f57fd5820d1e47630bdcd8e8be4a1ddb202ced7fb6e60380d9e92f2d7f95a18a4fa80d02fb9e97bd89dfa142d2664f88f0a569f8db40903ff5bd9ddcbca5f55ed2fc2ab7d5803951c879125fe5d84aa06d4c2b954faefbbce5a0777a5ab1614065d69f69bd2cd708a8ae2ff5f3a63ca9a92486c047cc0dc3f9c44c446f5784b3f090814c5ae7dbe005b7056a84f3deaec31e88ec3c4910a5fd58e13f16ab9eeb0607bb11001b6a16013fc7aa84328533cbde283ae360c0a16be16d41398b1d5bcfff43b69225461d598fff8c07f25d51853ac10a69db0f0482243e78d7817ea215742d3d8242f457993559923ec085b3c3a30fec7697d64bc28c48777112e93e41c2680aa3bf75a1ac9883dd81318622278ced67df2df0ed2b18c65309a2c9e664752cf65fd619665de472c74cc09168e54923f62ae3621a851abdd6682802653da1373ea26f4ac42a38600c00c016dcff85b10f9248c3ee5ef400ae64dd4336bb1e374e3df01d0814c4f2c7e144d595d671afeea7bc2dd7320859b82e8156ea024db4a33090799e30ab8b1c98fbf8f68fd09cc8a1c95365d20804edaae606a69b518559774b36e00578bebd9fac30bfd220e0120d0208d542c407e70c7f2955223b78ad6fc95f1652dea1c3ef3c33cc0c543b2641bf0798c88036b24494ebdddcd8a25a3de91a53ad62e78aedf02447f8fc77978ee206abb3224ab66a4d7355cca5841f9496c6359422d6e47b0eaca3f90bca18564e521e63c8db0b6c6060a55d04888147c95bd1d033d450242d989c84b27561d674670a73d19f2024bb3253586bc693d6821156e314efb666d60cea978dcb3c0b02ccc879f01a7eb7968f7b5a1ce0c94945fb729b77bed2f74efe20320812e7bdd9b576583fcf964b9a9a626b8960a392992d614276fa3110bfbf9945e0f636f3a4ddf2f41c0215c6755937690efc120b55688d4b903111c83af2d302b7ee5f6b83c7431db83151fdeb913476d20b339ff1bed54b7a8bfc9c52ff684d8ceb907eac915d5e6915ddc3911c3facbded1ea6e4b0fef138446108ca4ed5a888559e376b7f25457d95a538c281bd1f0ef1aa8cab6c8cd78b7555cd8287da80b9f8165957535af131d2ac579cce9e650635efbfe85101c35e8c48a47da15b376fa2a0cc3a0d2c4ce151729180fd7ac019e3bdce3b97190a07204307701bbf591ad106efdcc9b30ecba7de906eb56ed3668291988ad4a9c3a659b9a5736b1c6bc0395e5884a5fb35e1cd6e2f88cc5aefbd415448b87195cb2b341a2a291db07b44dcdb73b081a65873847950563b896aa46729fae4dd6a7ff228535389b469150300000000000000000000000008eabd0da69d26e0c898d9c0da14af0e60653329d9c1f7ea981ca7a32b8719a28e7290d441bb32573181da2c8143c5769b8e03934a4f7414f3b0bf7e307470191a62cb58856a676acf348a9f37ddc621f9718bf977de494aab8a7bd7f931128b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2021e3147611e279b6a1f88a88a3418d8e76fc3084994f6e694a5e70d1602b9af6343e8e80fd472c14726f31b4597f4d444480859a77badfa577d81da8c8fa580f78e56b072503dea39cbd24b7d90c50ff53c6b453cece8b956c805b1776fd9915faff0ddf1c9d83f03529c35851dfbf71a70cc84e371511954691460c3fce4020088b767c35352d13ae7db8a112b579407d5d54bb0a9d4a34ac5855429b53cd6032a1f05db82313c5a7d773b0c537f68a376a4075e9d2f7e2304311ef13d8341650a02d16cf182070377706a5d1846fe001ba14caeb3c18711d58a65cf8926b6cdc4a7b6e5104e8aa168d77dde20b31d3e5df6ad20e2e8531f6f5f595a55a914e5fb03140e6a708c4c1e3ade55aa14114c1cdd70d47f8cada726c2a85c0ce5a5ea945402148bd4c986b54d4414e5866252fdbca3965e883fc9d75a8c57b3f59e1760a6a20211c3313c25048da31759e0d09ad8361258fc82605441307f3b0418a2365cef930201d93497c00cdddcb8df6125bb98cb61acfcaec8bea988a173f9af0555bc385b03231392fe5cc800d0a4fe032dc833f850d30d8d6d5fedb2eaa245e52cd74c93271b63cd4ebe5590ee45f20198d623a5b77b829acd6789f79f376932a4c9347d3b1f5d875269a950518bd4783f0a1dd5df11e345ebf8095d038d6ec1546fad8489cdbf0d4dbfa8f5323b6baf83c9a35ac8eb70a2911b9242491964f5d5da52e364cc7df5057c0ac7778c3f14bcde1bae70a0e46a1200c47b609c9158c202f497fffc5cdff860c2ae2de42e6859d2dc782dfdbe7873287166c7c7b0e4f226bca13d83725996651d78195d4d3b0ce55bf5fbed2ba4c6bebe5399bca22fcf7a6767ce66038b563477086918194e8ee04bd7bc478bde43fdf915fff1dd6942bdca226b8d8777c71fdf14edcde63801e75a21121798fd26f44bb7514ec6fde2fc783979f58218d63c81e20df5e2f7f7095f3f01a19527081a99acd428ea167e13c3fd665076a8236d5e32df7c8aa0be21f225c812d3de67204379b1ded38206b963a89235dfd0e2ad24b6cc5255dbba6b1e5d08c9c7334711ae94f2b7dc0bd122e73b2011f9c1c52d83bec2751557aa2b92272ada981ebba4e9f2d080d2be252c1680f271b5b5132b4b60405c5b640fe1fca585837219e356b712bcfea39e740a8721b8dcab7fd2decd4081326b5a5cfee3f4072b595bca4d07f3c276ccc7bc8383f50e972e1d89d60250f2de9179bc6a1358301c2d48cbd76b01b9fe03e55f55a6b44c233bcb49980df04f61294fbd979ecf2636f958e1301cb19a69a49f6b6530c4483b5218a04a367db099887dea1e9b91b1642dc1781fe94e9f30c73396c481da61b8d979aee09c438d9edff5bc9ff8e185c34fae08e89857c6afe724ae06f28cecb9467c22668521db620840938e396158f478893046f06cf9bf3ae90344beaa5ca60cc438d683e64a6d7eae4ad27b0a76cd7c48353b3f3f8735dce997b3759769f700f218a7a6a55342f119699f71af10b9595eb50ed466f0321bea398139dc412450a47f5427ab3548a03e27d3a7c6e5648d6fa7f3d01e71a588b5329abc2a7391ff368cbea955be5b0d7c880d67d3f578f6725e61ff13c02d0ace2125568925c027a3aff207f2397fa78fbeeee0080fd51da4d6876a0dbd82d6e6362fc53aa5deaf817b28471153c900bfd5b48943b37e708fb7878ead98cd4d1f7258a246dd8a21d0dc5f289e61342db02ddbfefc43a07715d217b49314e7f1b20ec484aaa72db00702bca10f6bf29690d5061def6221713d5e4d3b23c2d295a1910e0abb100768d4f4db586915c015cca0f42ad83416bc81144e96e38336e035712199b87218620e046f9b51dd3206d021e2be8b85c42c64487fb0969ae5789099c34587a80337dab1fd3c7783a17471ff1f97b2fb0fe317b67408de889eb17ab2a70f29d7baa6f5255df07b85c221375e42571c61a77d0e42e571865f0deabcb88c55a508046cfbe7c91abe40edad757ea1eca483d9640cd2e8484325e0e8cbf014cc4d530cc396b063b160decd01825c499014037fb4201854ef1eb75c82b7c4ae791a85cd586cf7aca1f1cf96264d2a738e5762e9f39052c39d6c176a02beab22c4dcfe40d1f94155bed151f2b7f79f40543609166c6702862e4f2557ee912f5a5c2f50534644956e77d244b0e7b7c275223d23d9c9d85f527f1b941e255d71eeb931bc334d95690bc253ba2132625d94ecdd217738c6e3e3f0301af892d1dea294644b26c293a0c752934df8150998b96809aed11800000000000000005b048a01000000003e504dc0c84b698cd1be7cdb91e879e07d0cb6ae39f2170d9d640433e8b0ec5c4bb316278fe836e5116c96d4d82c9fa36dce611437660688c8f058ca9c49a61d5bf484f07057066473168645091986fbb4fec89a2eb7ce8e4d01b604017cca6800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ec21809f5193f748813f62e4dc4cff446a8f709088f20fb721635672bc8064570e0245ec05e2f3756efbac86846bffb282ba90ab2c78887eadfd792cb001cfcc53545f20b63de2af682eb389a7c230fc8469295301efce7b8d68ff9552ee5ca3cea3983ccabebbf495642f1287201b6d2f08f9efdfd026febc21ba23a07b5c83021292ee3b51723a3634e0c2f3760285f8841bcbfa741802adf22c0384e43fa64d0215517f8eebf001b770a61c4bb40609a5c168ba6d71f398a4ab2e9a6258f1f5920a04006505160c46433d0c0b64d687e1367176c900953a890609ac36f8ca2dffafd90e8abdee7ca8cc0ebeca35ed74834a31dc4d08b9ce5c2c3beab097c39cf3a3031b0001560e0da5d29fb91e1887618a4a4411e43260977332c64b6bd998d51d25022c354f8ddcde315a947f1901f830bde97313f2aa2a782e108811a2ebd2d5a79c032f267def8b7ecc539ed0e9a1846ceeb3f78ed99a40838c0678804ee4a1158cf4021f44172d9a038358874e43ebd7da8c38ce179a4c1c81d2990981d462240d46be0204218d27f75cdac577c68b72ab8f16460e4827ee137293772bf6d17e620a9f19787b4aaf68cb4d4e3bb10a64a186c360e1e2020e67d8c71077651ffcd3bb4e8e018ed8c7d12699cd46dffcaf88826fe73c36ac499a573dc437564525bebb4336dfd18dd6e7fe50b4b1f333f179685a21f5b43f105565eb180ea3eea30feb3e3dc8858347205da0c32d4706b28bd7d10425c727e1d75f748efc3e98c38aeab25ff41af5b8ba0f2d0ea14b2fe4a73dbb12fde6655868156db21cb5f7021f79de42938f2bff6bd09e3eb82c6a9bb5bf9ebdfa6346a93ee64b135cd9b810986f6fc61baac316fa0103bfb3886e41c411327fed02d2c3c28575c1f9c58fa40d286e9e4a220d2170b606c888a3ed5c0f64f1b79982e5f7fe55d728ecb0986ca298c167c3c365f83e7e7368bd62dc1e3cdbca03a82e248b19b84b2c46f06e0c9453e176210535b40933c52991ec529e71008ad186bdf9f96a8f13c78fdfff6849e67baeb86bcefff061522df27a6407158ec0581403b335e3fd5ad37757edd75fdb19543e31909186fd28e9044e2dde7222097c046129a4c5b08cc2fc26dcf311b3ade9a0ba0f6e4750bf181d5b830003933dbd94c7392cff1c967fd16540c21efbd0e445b2730d0ebaff8e31d10e82dc6979ae7d05bfe3f6cd188f6212cf926f3b1adbe039a3b77bc43af6ebce84720b51ec943641448f254e2fd99dd139d87cc3d1818602ff87aa4beaaa7dbef30007ef2020a54d2cfd4bc486cd9606108ec7b355ee626c4539c023d15e124017a124e945852d2bf79a3cc715610c92cb09c4386c96e5c5821dbad360d2a7d4890977107ec9296c378bb4ee25438ba6f37a2cac9b2779b074d67c6eb73067e93e25ed72b96229b19e94b552debd32d15a032bc89fe7d9b972305d41c88b83308fad5b6cb4fbf42d2265fa1cb36a02bfcd194b84b3e79c7c42f13b8eebb233a4fb1f12403ee1ed15cab65d6daf9c3cdee285b9c29d820af5d169031ba6b9b0b6d1714e1769b69d1d509d2a75c9b3532c92784102c0d32375468d6c6d82f9a6bca26e8cce6466d0932ab4c8ffe8d02efc7d35510b470424a1a855156c2ebd93137d03a1960087c12c14202df73ca112a6bd876850b170b3db6e348cc5113255bf2f5e5f4c352967d8af04d375a8140763ca7ea2f96f1936f547fde74bc1f39976912ae97566e6337af85f1ea20d7f03d7734b4de682878cfcc12fe445cb3342391d9dc14d9fc681ea81db3ab3a7f3afd0ef2f9888c783ac6595d81f264fdc1df577bda2e9fb52ac33f0f4a69731e8f741be1ad091704b2447e3b475ff6b6225f9e0df1070cb968b1a101680f6c765a07dc5720f8d9557d0e7b73d8072aeb3451c395ce4df029484b932da696f9f6d6ff029a7dab952b1cde3eecb43f531bcfdb2ab0011bdcdfc0f748e9fbf4674b1e036cac0bbdc13b1fb8164e693d34db40c15c09f628d90da2149bc9455c8e1928db5e0e2a03c7b829bce539655d37caee979f0a49e5097e98fd7e0716f02aa125b031609929c7b97c7db13148d5da1402f77b26a2152204e7fbd20848c5cb27f474f3e2afa64a0dd5f80aea6aa49b2688c3643ab9ff92c01420a2299d915c4bd9915ecb4cffe16aa2907afba977b7d09c0b5f81c72fd451cb06521588230f0f342f74f5ade4ca305ef61b74e31a15a022f487fcd35c000bbd617746c685264d6d9c735fc4f6e9e02cafea05af81df380b40a0b00e01ce6ee20cafca0a9898a1acc08bf74243e5df79e6158dea1cdaf5081c9a42dce4cc2debda0f54749ecde6b6602f9b94f376967c56081c1016eb3094ed27ae1ddb91b9822de46293eaeee3efc700a1fef3896d7622c417f7d8b2988eb6e83487b54b8045e0c", "005253", 0, -1359006412, 0, "e718a01910c2b7c019fbedc158c4316907cf7460152bcba78d794485b70a5b0e"], + ["030000807082c4030199397d9b6c72c1bec0171aff492a5d2a5c2e33914a62e0a928199cf9ad524743000000000039fe028901d48e7e0400000000065153526553630000000004b551aa0167a742040000000000000000000000009aea8b9230339b631644cdb3e413bafc400bf781bae83e5067548f48cc5e00b6d15d0a76b3bd726c70be9750cdfd3e24dce4cf4002b6a922051ed2e02e179449d3f5d08806a601389ab398d325b4be0deee126d65fa96a41cffdcf050634a8ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ce5b58875c2e8458d628d68655f3ba1fed1bde21c27a37b63d9aa9a7fabe3b7ea654495679bca48eddb00e458ca6e8881e89d78923d4db41322b75507919f84d111d814c4471ac69aa9b959a129b0e24068523c9255cf3b89f0e5a1c4504233fb4ccef51977eb2b1057ceb12574e04adf38256257eebfa23cea68a13ff51de19021117c4c569b35ae92ab3b8f4fc1a7cb0192116f3c1f628cc9b3aafda48b462a30200ed7688a1fe3280f75dfb522be9c5096e79449885cf040189b93cb0aa4a2fc00a087910a25d82490a8091ba57768931c8b64d33c807208b96f3918cd371685ca8740e3895bcf0b4655fcb31be25eb87bdc34ffbb9da52c7461b104e788ac45c59030dde433919fe49c8f185fd417f7a6d4f89c0da9eaf9b0de97d87aa1cbf876f3a0312ace8f5e02299620461a95f57c4efe2f5ab687e0c66b5551bc4f30d6821a7320204032049572cf65c9c09b999e9c1eb160622ba19848d5b9cfb928a4b925f76710219c676b64e0dba792eb2e1b42838ea99957d6386a672a1505986c794a13f4e6b030d08f7f02df2f2ef62677f758f1718a629114a29ac82ba01c35dc810f9722ab0180e46b33edf82994964e5178e358bbd660df2e5d26940266e37da172e961ff069134e9c15b67a2f31800a7bc913e384eb6016212a894ad43d0bf621b883af2afda43c26b68e196f3a10ec7352d285065c232797689f76f31a6f482628e5ceef5de055a569d29b4411f73773134c6f286dfe11f9fc1ae4255fb2fa6b5766c254a83e1b5e736d945d22a433dbd03064b2d6b417966a8e8d97d8cb5618b67c289102139bf7dc97056693155db5d8ab7e41940127f9f07dcec2cdd145b8ae757be3cf3430abe1d714b2b6ec3ad4d582dbee90a49de5586b4ff338e702483068b44801b47e324164d9aa342abe1d68f7c2069ae3c08a994cda4740e70fa23e27ad5ec1775e8cc0f6ae6d0a584f4e415ae7c7f2640bd03b38acebd91e0b30cd47044d1a80ebd575a9eb0b97247af2057805fc64a1450488c3dd739b34b42c55237ec4c8b8ec538d47f108f6ffc2638c8ba3ffe4950835a9ef4d4ebf4c5f9ebd398b28884959e0b5309df4151b32248f044c73508484d6d160347f0f4163cec4924492c6c9bfe4809cc5576d9b42bb18e222d8c3a47ef03c17c490f7266593514d0f1184b65511e30e882557f6f3af500824f2194ddae330249a35685fbc1437ad85687f608621ab2b6a50d6cf66692d0162443b5c74d6113b53f1050454fa7a1b5add53f702567a2b3842fb7383e2b93c05567f335c1d7a5dcf8b88c41b01ee648e88dcb64c127d6cbf32e0bc103b8abf8d23e15559d21d9d03ace23bcaf7d16f1b54f43306329eb27ca7c9d3849849778041f41e5e6747c365d1851bcc7e404b4f6e95370b7f4261e5ecf271a898129ef86fa04b1464d7e5bb9776758c0a566ce0081bae35644ea860063b46735d41e28ff210a05f912a2027e7aae23d1335c4be7db3e31fae720c3a28671d40b6f80938b86585fa58e7ef377e0fa4545ece1afbee9a0a4418006872c0504ab25203e944903d36e4ddd1df167ec31c1ed71789ac2d03be18b1410c705d647b69f7fecc112b06ad719e9b0acb8a3accd0bd87055230ca41620daf9052afc8b8f4f9d050cadec1ecd2505bb431a761b6792cb057cf6c1f834ee67e0fabc463e262e9e1e248cde04fa9bb481d6b86d5586f5c0551ea752ade038d4473aaa747cd505c4c080559b951ac5743131eeda08557d0712cc0ebb086b440bf5a3e8727c1870671a442bc9e4112e1494dd058fd8814ab28c45c20d7c1206c98cc593c4de082ba32d0655ba4a0799bf8f4b3e3e5ca0b59f27f63beacaf50ac4b697605b72cf5f189ef1f17ce33bf6933321051a3a6ff8e2a9fd155f22551d0d9063dfafa368dbb7c09cbba78f5dbd3a35c62cde7ad287c202545d6b867c745855791043f372c94291494e6e6ade60f9e28e6ce44af2c702f2457bbd9001ab2dcb2e5899ac359874f956e3620b8ccc8b3e42b49532a21e69b035980157d8566c383c2674519e2011b9fa7df5d7e69a8761556a002de4e6bc2f1c008c90414823c9599b719e1be9e56758d9965e0f5413579fe9fa736fe2218fbee42c93699c63e519642f83981c8d30bfb2bf48edbd6f844c870c0d43b08d3a87d5ea4d070785b7fcdacd119c7d97e6106c52359b4a51d1cfe1ac909bfa2f62e6625b80bae854909b02229d971bde2a0339982c45e6168913df79f2e7d208d127d0b6d06e934777c2fb76f6fa715166ae4117ff957c0b6c94ac6e8f8bb0943315cc301d22528af3754ccb4e04afc46a55d0dded5b9fd95c66288c013ccaa19e358d3375de9874cdd0505e9bbc08d86ffff1ce61ff9ed05308f3f937ca6af828cff1ab14871053a79d80797667db6420eb1db7002", "ac65", 0, 900788221, 1537743641, "5bc440fadb31f26b0b07e5cab8cf4ecfbf184b066b983f6a9855a2a61bfa087f"], + ["030000807082c4030204c1b65454948a280b6989dbb6c5fff6fb9d06f67cf6b8d32b110ff159868d64030000000365ac527d9f3f7ba560c6573d3b9524b60a7a2b72f30affd983287b25c889c53142d1b35753ed130000000001ac2760677e0216f3560100000000035353535071210400000000046a5252ac0000000056ff2bea00", "510063ac", 0, 885361454, 1537743641, "611779e165b9286d21b283a549d15193e3a7c3a75859a938723cc38432b9fc3d"], + ["0e68a01b04e6d91a97818e3140ef31e44061e75173776027cb6eeafb72b1cdeef4f01d45c20200000004535153009fcc422fe2ff3e4d32fdb5e8159d718737ffd04e5795d6520523c96756457b624c1ef92c03000000066351acac5253912d24184d5ea52d8ccd6a8dc3577c9a5e0295ff6494c9ac09326e4c0e1b0b72897c9c9400000000000f21345b84533d80c45ef19a57c9d235583617b955e07cec6c93afbb3faeb996770579120000000008526a65ac5251535300b27ff104919928000000000008536a536a6a51006a8082cb000000000005acac6553006ede8c0500000000085200520063535151f53ba80500000000016ac82619fc0300000000000000009790a4000000000058a7984b35ccb5a3e4f18e2f5c66938ba21961340fa8a95ec673fd6802050d1eca47e41e188a9fdf95d722b763baed2c5ab1fe491ee11af80f730552c6008dc36c23b4691f59bef51e4ce24fa81ffd26529e3e9425b1b0b998af02f9e641b3250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d9ebe83cc462d29c3ddc9263935e51e18f9181e307466a0f2b0cc20de08627e6110e1c798f0e730551ba95554fd923f06a596165157c597028feda01b83a8b78427689385835346c3693949fabf03c9ab4e7c6cbf065d09ef4965a93f44ebc0dc5865b2ecbf550bb899adf78022da53b6de7fe23df0f503053a6ef147210b2031cd42071c89a34ed2de351876c9060ddece8b3708988d1f06cd62f29ad9f378c031ae69db41692c043af4908b9f488a7ea1879cbe7c6d03074584fc5ceb81c64ae0b03ef0b4087536e64e8cafe2d5e1f0b4e12348a61d9e8b079d925d3a01a729580ad813aa2e39e2a6ae3ba49c70274bc5bcd2f94decdeb569a94dbf11caebea5b7030be221cdae8a8fc623cf3cc2a3fde096cc44128ee6d468aa50dc914bd56949380322846a6025888e0ac97b16f3ab19c361e0115af25b2fbf5030aadc28a5db05e7030fc69477165a15abd8d83f2fe674737ac9f69f2bee33b3377d0f22228e5ba099032737654295a0643573b63dda545f2692516d5897e52d77d46cf4a62e8156566d032db67dd0e5be61f5ac73f78cbcf0a31ee6f943a496b5a3aa5c766719778fa453800ac8bdce05f61ef1e485f65d92236f7dfac979a17b09afe203bc11c7919f8ca593e38da2e74ca74c7d24a2f6defa16963bf20c180ba5068c59fe3eca8bf53a9adcc85c4247c59c3df0d95d398037985fa065cf4751847373d0255e171a5b13b808e29ddf0d9facb645eb245672a46bcc165657388d1e26f122b5e6b1d06e95f66dfa4dbac45793df9775341069e0e008ca143faa223d19f0030159c6148574b9cc49ec2e0c0c12f4d3f6971b9ed91e17d43174be2b3ec7ce8c3eff3db28b51ad2059d90c35d7799b56b942bff1538f03239270b89fc8cbcb4f8034f742b5ecb1625737664c73069d57558621e119672c52024c2c42c85760d4ed9226238d3f3d10ccad965a20d32317cc0977a2af8d5fab89fb2d15c0d03239cde33d8ca11339ca4acd0db2abcf2f26428cfdb9814020f88587df10ab5b1291ff263a589f60eb8e65ed0e4ac6b324ae162bd6eedd5606759b24f0e1e719cd1a042c0414bed9c62d01ada2e57f20006fbbaf7a7551934f079117519b11ed7602effc4d5d248ffcd01d9d1f7f08707d57bb300c5cb1f636251a2aedfda4974be07dda44d9b63d31565ff56feb6428fde26e99c54ac435f01aa22c7dc0ba9b5bc7479e2784cd598f4f9626ccfcb995a37a85b0aabc1f9b507d15832935815e51bfcdef2c924175d4430875ce00e283ca46808c003e87d342777f0a59b51ea0903482e8cba2fc782beda9912363a997b526d754fbb32efd4d385694d9d8c4383969ba77d749b1617c133dfc7b9108b05629294f6c3606ef6026b51e15d31cd6373238a72dd43e5a0ca46e68a4a4ba27499abe68ddc0d322761908c06dda01ad9f7f1269dd44947e34a4773b4ef0285c24c0b17bec5692b7fca04c3258f812ad8dc38a06df4efb41a6f44c92ffaea444f2a573db16ff68dd86c2812edae23964c3b7219d0f36a3e2afb5f426d6b8321103dd934395df11934ce40ff25bdc57ecc4d204fa18279eb70510c43d4eb61521f7bb166adb915f8afde1536a6654e291b0dc63cbbec99555ddc9a1facf8998b73f03832a73d940d7d6329e9757cb3abf0f80c209a573ce3d05c626b5a494368fcded1cf6a14d7146b72b3023e2733367f62b38d0d2fdfce5aba672382ad0f51b36e9e66153721a93c47055486bf06d394e9515cf6291650e10a24e1a224d9af829b94752bb467b6a11d86e6363e84c3628bafa6bd9743c52bed7fda69f27758c243f3a4abc7912d4ab384efbaf33f659cdeef80b6bc8477da7006e5737c09c62293a86c2a552ede86e01b1c7cd3669a3a229da3b28cdf15d99b4707d66ce71dc4abc1741e508d5ea1f8d59e545004fff5f183e967fce133e46d5e84029a61b66d70e6728a57463a10e2fa0829e610c7c52109de6d01db359b904ab5f0993247e1bf056690b3fc8733b9cdbf12e154005df64510a9499de2e9b251a6be414d28e0aa2545ebf46ea3ae0acef81c2f23338879ee272a139b5460f3f648d72c32dd9840155092f2f2c08be6c8ec08ac415ee27d787719e1e372589a3b8991c1a973ffb3892bb105096f0db96b2f29e19b41a878ae3108be056e3bc146bcfb8776bfd76a8f825b2c3302e6f1f482c5cc03947bc2ea80b86b2d58026afb1b922491e61b2213fe6548ad95dc2801aa624affc3943712f8b7116277e78400f147a884fae69ce57d98c094d20942ea69d8a02000000000000000000000000163ae9979e83e4d9779219979e8bbecbb8cf824c05ad5a9ea913c2a42cc37ba11c44bbb248bcd0058b235e67eeb2405219570f0b0ecb11b9950e9308f57dac8fe89d271c0de597da1924d4d329a3ec552337f111ca3a06a47d3bfd2591ef3719000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000645189f5c0fbe198edfb047b8f722998f756cc462dc623832c2af42c3902193a860ff0cf758c8b49d6430335ddc60df686faee56a124af77a7acc667eea03bb9b4e0e9cc0156313e0f62d9f034adf2357e8e2007a7c37257be90f8e7fa4262f1fde92cffd8f819a18839988a9a63a242db23f71586300d622eb26826eac86100303137f4c3c94300fbc7e6d3fe4c19a7056f3b1f051fab059d6492c92ab3da9a4022203a24b5e064608495531a5242e6f4d1fce0d559aaf5b81457ccd0edbf321280a0055a2db4d487413d58348f0986d3219e32eb453689fbd95f7c141522f19f9f9a75c58d9343dc8322624bfbcb3aea5168fb97cd0bf817cbda87c2f81f9200479031cba0802f3693055e129c48178187ab43a0f4889e9f01be3c08ad73ddb7d2938031579339445cf15cf0b1918fdf62116ca5ef7d044a0f9ed2e244c4d30dc35a99b0307f7d9c8a4d93adaffec7fe1afa4043a8dc9b4cf4d06ec9683dce4d816dcc6d6031d4dab83966684677d88853eafe6d1ca563a36296d9c15cf15042d1d062ffb82031eb2b54ab42a17331ee0daed28133d71c053979daf2e29ce2b00a5d9ae367caa51206a29bda790e55d6a1e77175c9b7baec4709e4bada7fe80b2705479c5c1e26bef389b803e402a882981c29188a1b024caa781c8a1fbc48e15ab2ddb9ae9d3cd6af739be2aee8363eda87c72d11650850a272102b67995337407457280205d27416cbdb4135dabe0a02536e4315649997d6681e2cbf71df388ca3fac3d0a3e587027c48eb6ceb8becb933377c9e9cc0cefeb837288010bec066810a7d1b544ed8998e1ef159a37e6996a083bd1011f10bcdcf30507979fecd2700cf25c0510e445161d33bf21030eb25cf168402c58de96c32aee903ed3b404092f438b58f8b7f2ead0ff13ba90f5983f5e518fd9ffe31fac29c5643e835f2d06077601ff9ba391b033fd148958de42d4892e8aa31b2b44ae92b48918a138fbb8d01ab261fb0d421d80fe002f0c76c89e5261c707153fc360a52b90f60f0dbb33d16d91b038f1d2901c872d07e6cacb96ea1a8dab67749e31f2cf3cc056b50ba894041ff8787c2c76792a95d781454899ecdb6cc69868d8d34d08017ddf168247363ca889b3ee6a60fab584dcc8da0e10ff449c3a4ec50ece9c970e07df600321970d70657406e37f72c6a71a1377b3b4cac7dd52617feb61180d9bc1bd22f53c7cec677312ea718888c9e72f215a2ee26e6f6cb9914f110f43859e93399d147c384685502d0a5a8c5f2019950f915659ee75b0ab9a73b2420e67e9ca8e5a3dcd4bfa5e3e40107358092aa0e6c10ebb2f986123374c055d83468a70f6a3beae2a33e9449d9e1c99b5356ad3dbe246bbce163e999357755c0c900dddf8f4cf7e2b4ec9ff1cf91b27889750db96842c5aa78c4c09a1cc40aa0cce9ec3be422783a25d8a37d4c43778ed1a3905e96734d08ecb805937d456945b6f5d374e33d1715bc902122c163926279ff55d054c7276b4dfafdb20d7519cb4f6bc5e19ede1a6fddf554f769dd30fb2a7569740b80eb31140cce1206bf046475c955c63167ff0e91ea751565ef1243489d7f5e6761469b68093f033fa508b4d17320c8fad2bb7e22855d4ff39abe797edab5dd2a2dd85445a75ebb2e07070cb70e5f9b5b0365a2ccc182c100330390fc209a1304be8ad68aebe1a0bf60a8b3ac382dcae74f338fb060f4a14d0bcb46258f7bc8b796ee6bb27f9ed4d5c35580c129441a3f96b5c7be8e9c533afcf1dd30795e2d6efaffc3b7d5a3dfb26d9e97c4dd78bcf8d9810a79b855d501ce22dc0512842ba58411ad8dd60ab5b9721e5b85dfe04869916953ba8cde5008f08932be1e7c755339f02270d49d196e7909f17567dec7baea4c59b3cfeb1805adf149afd3dee327c11785cfbc3ba156abf3cc53c3fb0e6294a46258ace64c3c3667d48266911663a2dc4fd99ce4b48c804914124144659c09f87077e08ebf5b6a8a341f3681889d3b154ed867d5c865b40ce29966885d39b8d4ebfd139a65691e11a1970212068ffad1f4e86a99e1549a41ab7c0cd0ca3ef74c2605d8977baf7b67a7a008c6ddea94124a22c917cd4e11a1a248648800a1d0b2a4414f21ece0ddc1e1becbadddd9d8abcd1f34f0e2979cfd5b70d3cc4b69bc111ef8ce2ad28014f2431ffcbac4a0c0824f2986807030f52d320ac3f2ff9dde907f57d2572b995fcb16d9e97bc91374adb62fef894da3de8d4cc54ff5c124f590ffc34c1d01dacb4d08608e53b72b15eb1bf4d04b49e7b5ba9d84662010000000000000000000000000a48490e2ab25988fe482316e16836ba1db25782c79ccf6f9dd70c8094e118cd7de9598ee5ca6de13bb3705220bdec4320168c0f0c1caac447afdb4a0e7eb2531b2a4d5e8ca7caa85dec9dff4ceab8e558a4f68bfc87048ce7a6530d7341be510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074fca3bb82ce116a3defb42a9888a11cd9e9bac061c2adba2c908f399dfff98b25c8b95396da262de97f94a40169545cef5d3c843b27ed8468a2a9736e5556b3fab479a053965d7d322941f0430189b867f99bf5eafcfd41cc867838591a47968c59763dcc35cc71804886ce8c28799048335a65d813b08a04c88ea9946648df032e1aad8f80c4e0093af5df96df4035f7fbc33645ac23f4b7d8cc5d640959fc00020879b4588734f7b6d04f7896ed0a43ce122aa29119267df34d9039d4e8fc05520a0047efd0065b7f1acae831e6e6015bcee9998dd8754223c597d16f1c378defb2246820a234d507ef637227bebc463d349521234f192d46cd82e2d6efd67981cb0201095fd9ec3737fa52ab118406de89e851612cafa27f9e48e2b6931c453dcdf70325ac829706dff986ff18ff6e35dab2fcce5842bca358427c88399fbdf6a267370328f14de78835fcf9e0addd5b1513de77c94f659b15ade4e6d8cbe58d34266dda03052b9bec56dc5e1af7d6469e0277e7d65da862deb2a1d0f4cb275ba01c5021f5020210f951a07d329a3363e037965b24870f7d922812feda26ad5a376341a337dbc052d34828a06f9d1dbdc8907ea203ef3fcf189effd3d2b37c536421f2e20deb554e0687958cd8b7777876c09eb18d71e9a0db1bc72f258d7e01226a2cc42a2c2812805d37f32a4008bc5d605f8a004e82351f745e7679f46a18a281f4da1dfca1e0528136ad9ee4e1823cce8003769febd6d5055002842c0809ec65351352dcca755e1516df3898c5846f16d4d6c201a4760b93a45c5c67d77f8c11862d5b6eb56ca99dfbb342a1fa38735ce32f69e45c59673f0e5f2270eac65775a2bfe6617ad236861116a70724b2a7da3fda4610140a2f0a0fc6b229a32bb7b8dbf48561dd3ba42c4d50c0a837c686ea2a7f169ad3a3b6f2348c178d1804b6b5698c49daefe10fcc4641e8cfe3e46bd5a30cff6c18fb388cbeff8f0e261ddb3b92cc40fec219684f4f97429979cd703b1b201effd99e2d512db62dce2e767cc646b2942a72c8bb78ab446b708332d5a46eed59de97fbe48f7b788961d0d68bf46f11641dc9764e075db7bebd97cd565c5b417e1878349d66696fe9896c8817949731be7efdd7c972d5edf90c9f787fa72d1761bbfb18135f60b927a8162a9a7eecc788665ebc290437c8deee22d4dd98f8106f2b6070b5600475fbc055345e96e4b61f06c2c89a0b7a89e305200f213e8b8fc09c2f8a50d017b182c883c7d286c2c8b451230e01d984fafa0cb513f91351686700604448aa55c7d3d8e06413ef57418e3ccde262c57d8a2ab2bdfd98b5dfd4301c890741f89311e811a3a385569f32ec0917a29afa5fc48d643ae0d4659551022c82f6bf6ba3e5dc75b655afa4266564c0c5d25bea46e98da52c262da628680ecf15ca13c0a0f954662da498e56a94ac792c33de785a4e57260c68c69ab98c8c12bc2282d39e7449c0d6537e62b8a19552de7a778abe90b98a82a40deccebe36c2da5f78bf8d0da7358e8a2c6aa3690565f86fec332421ecc506e272ae02844408da847f0d6fcdc5e8bb595423a5d6556c825d8308b815933d990e8644ec3dd20ca29918afbf94814c420935db0efe6ec3677ee1381012464bc93259ec911f4cf6b2878f54a68c2e1c59e7b042d2a6540670ad962886f554f52707e050d9cd0e00721192693aa1f96a2caa5a2da9b63a57becb33cec8fc8dfae7e540e9ddd48bcb5610dcf76b63d4640cf6cf9a0dc493854bc54249d30e21c7024a4cf1442fed6dc4d446552e49ab1c551df91aa32389610c8906594b4dbba8b9fa6a1e47b258c616dcd5b565abbf838cff34c939f113f81597a855befb89109e282e2a87a89335e357e368131b86cc0e1375f07080efe7a5f124f848531a0331f4c5dd1b51f3147d628d6216ac3df943ab55481104839ed1773bd59155ae4e16919c3efe22afce443fba216d3744507ef958b9c6c655bc2d1423a737272d02cf6cd451c74b87250e560cb802ff263d2792502e5cda17c71e8db9fcedc0c7ce973ac28831a7e6bfa9a55018fd3249ad0274f3d745d718aa2e19b5dca47ef89ef0ed136439abd34e574a5eeb35f4b98c93ccf0087a2c44d7680601bb9e58049221da31a095e53e8816b5403ac4de747ae7758babe3367ce08f8859ff78e53181ca384f35642207470748fdacdf33101e746279ad28943b4e85f976df7487e967355dfade7d9c35e5cf424008aa3df179589ff19576567a3c3cff26728223a9374c243172015120c4711e4b49330939c9d90100e97f9e35f15becf5d08bec18523886cd0a5b958a6f024cff1b525d28d490b48f8383ae0e3a102b6183385ff7d345a9f2a5c46b82cf00164a74e4c125b12dcc8b367d371d41b1691c22c8ff9c001ec6d33b278e63b9070b", "6a65526a6365ac63", 2, -1493272850, 1537743641, "77a369865a7220fe5242db03bb7b6c539181943e0fae84df56cf54c6e28d1bcc"], + ["030000807082c40303f0c5b727572b954107b2a47e5d2b6fbfa8d8c9cbbc8dd37b5a1ceaea6c99cfe401000000026565ffffffff1f530bad7c338eab7e5274b74c8ec140f6d545df60d4bf0f35accf5a1a294a2d03000000070052515365acacffffffffe6ad17c58a9a9a308e245521ec4158f0384d36ba852d3c09ef1fc3dffdd6c7ff020000000765ac63656552ac576fdfe40381b4880400000000056553ac5351ed96a70500000000036a5153bbf2f4000000000001512f21c2fe000000000291b5f305000000000000000000000000879aca3bbafb25edb46688654abc9d9b1c497383acb95f3e75bcf4e8c319d6d88eda997028edc91692e452a11b81474235eaf2fc037a11c9249dc54af313527fee56a397f305a89b175069d165ce88c61c594aba04c013e777041ee3820d543d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7355b05de4799fa561fbde6fe7d7a3eeca7ad0952580d38cab916768b17b2cfab3fcba33bd9d8da2ba08b05b20e587825363a108d27312adbf8506962464ce4ed7f0bf8b3b0b36d32e3549f027e0d761070bb90cff1bae88bf11418bc918c1040bd2cdbe82c10474b3ab8f7ec5e6bef6910e46d3e62b4e80ec8d9191bef07bb022a3795023befd2e0756df4a072e6358eea6f485187bef8efd590fb17fdb2e93e030b1e6498fedd869841384186a212cacb4044932fb2b00c5d1e5868babb091d970b05cea399ef6fa79d68d244506f2c521a6c734c8c2d325f62e3580726186438dc71265b2f6e245bbd0b0654242fd7f40c2bc793a09503bd2c713dcd27c6226a890315951d2a54a65112b34fff8b0cfd71fa38cfab8bba18f1d62abb0daf7138250d032a1b88b22e8abbdb455ada2fe9cceeed7421cd63926254d2ebe8df4493715bad022ab61b88c6311d0b1230c274e565d7a3fd0263cbb5c14ebc116dce260209cd0703209f287359a220cb01d04dacafc3d81cdbea19313ccb1bc48ec9b3d64093fd0e03108b6d44f51ed58532c4d0cb08dcfc999f0f025312d0e1de9ba9a696e30919087638d2d2b2de7c90cd8acc475ebb8bcbfecf37eaa58b65255014f43c46b3aa85c20b4399baaa4f8f1251faf0db8691a04d8d1f6b55ca9c5f11a1b31bb02f7052f8bf2c1eb3608e19bef4c266eb1282e11eabbc331100ec19504658496498bfde93889c66f7e5562cfe736845552c1cc5919f64ba7eea2b233902599d67a0c1db201b0d59f8e7c341eab037f75d3ff580f57254b3a9a8c1528bb344e0cbda9e9590a73c8d7335b3ccd676be188ddb8f00c94fd0859ab2f9e3cffbcc4ab1fb65569345e376e3f0b1e13ef71c73c634b3852b0ed4eb99768fd2191e3675402a7b4f62d0b96051ce30df89bb7ac5310235270bfdd0ec514dea92685471623eb85ca1765596917461dbb48c06a1382bddccf0732da40236f0dc60f7015acb200b6aed4c877955426e33d69fb2e5ee44beb3002824b2748d6f9bfbca70816ee51a92618fe021774ea7ad6643bdb3d5f98fc15650833e6696ef9a63d4547e02fb24f48f4b66cef7cdb0b392a0ed1ed28a2a44865887602c5bc46ef0dc3e79ea706bc46eee83535cb842848056f892d387e85b89564fa54dd37b17ca36f522861ed92febaaf229bc61c3fc114c6da97dcd02fda15a2d2a84238e67d5c262d5f677c27d4b57fb8908aaa3b2ee5cc5294c24bd127cebaa9babc30b2f343cdca6db97a6cc2bac52d566c8c35942a147f193616e96af2266b6e182eae85b993f84cbcf82f8d559691549881a8a53f1bb73b97efe26e789b538870e362f89f53e3322bad099c39ece53c1bf9a9fb60cc619a25ee9696a812fb5725eadfefc6447124fa472424f1f16bddbf1dc5e4338fa849d69f8bcdb25eda32f03547191ac4e1411a8682823fba96ce82dc1f78bc257b253c62f962a4c89b3f36fbefcacd726110f4c63b8d6c3dd7d0c7dd9ba09bf8e05bfdef4b74d3a02e5504719a87d5eb58377cb27fb65124dc589ecaea0565e764923cf282e6c1babe17ad9d5d88e06debfcb7c82263ad9a1c608dbae635b292930bb9ce012e58899c138cabd952e89ddd166ea851077125faa14cb5e9bae6a9fa00e8c497c969d083cc31669f04a11b467c386108c4bdc29a38fc53f4fc9d23f8a14ffad6e0bcfe7df6e85d44a42fb25704044c2c8cb0f325c5540a08d6f4c3237f93a403b4e04e516a3dec5bfb05b74224326f6a4d07228a524aec8d5d7fea3024deb56a9d5fc6849f224c53d781f24f561974696111180e5078c25346de70e2ffc07f6b9623035313348b5a0ada264344099c696da92584da10ff4e63d55cdeb3d166b0f46e003b621afb9cb35efd1b45e08dc87df7e5a6f3c36c5bcfdce70af93501c183d01e68bd4ecffde506cedbe30c218774d5ac7e89aa20f8ca34d4c2f4ff3d8a9f9f534de88aeac2ec54a88615b8ef0ab6864ce77a3359239c6f262c8f2b9f00c4d3c05a03f6948cf2d54fdb3e7e7ca79681a12ec4c4446de0ac50b7624d9e3b6fda28825e60547229efb5e78de8ba712017d210b4bdfb6cbb5d75b863cf62240f683cd554278be27ccde65538e90132e590be3c368537023c5ecb3c5d4a6a60997c4ed7060715d2d0689ac89ee4e2bfb90d0d9a154df3d4c5fcb75357c66339ec391792f78f5df84b365941d835f42ed0160c90d3eee490b7548362e614adf98b5d65d7c920e210677e682664c88f163661cd0ff712a14bfca6276aa8ad45f5944b2040000000000000000140b01020000000056bc8110e084dbc7619fb769cf933bfcf09e37fe31d1cf4d625c1c501bf32f0e63f0acb2592c8c6fb6745f74db3f6e0c1432fd57077f1ebf97d98a26c124a30838609dd5ac27de061266456fdd0d5ccccdc2b10c7e8ea16deee6de4d4c5f7aae0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005590090b738cad52e2c0deb7062ff00af541c1ea492a3824ddc7c69ddc71ddf7751b873071b36946806c6c8beaf0cbaa6c47f71857edc9dcd52e7b253abe3b4153ad64a0be1a848fd3a67a06fc703e7f3c3658453037863a27f5a06eb2baeb329d13ef8987a3d0972e12a0531bd39c1b1ccd21a127c04c9ed064af7e00968e6031aec46acf74b4b4c3cd714e63f9779922052784f081cfd1486d9f3b6e12a57dc031c866297120e368a05c4b4e7fae0964e21cddc02aa2c71ca4b51a266a445aed00b06d0ab34d3325c65b555233130283657100c0519e613883bee669815722b3efefdaec7c061c0899e2a85112278575965980638d1b7cd9df514ce753ca599535d03026104f3781d5029d5af17568c196bd8af645489da9c6062347697db856fd18803161697a1f72d91aa4923ea8e534e6f24a3abbe043eefc81d4085d5503a9acaf9020f3fcc7a63dad16108a5706a8dae6791bbf9cdb125d6aa633d7695c34e7243bc03178db95b595f5fe22a0e2ab6badec02fd48b82e3f62198558aa344923d83460b03182dc634b8779a3e5c5d407e4e2f890be97c73b198e195fc12f9ea6fa029be72d5b788caef59ce95d3996f9a0ec4a3587e47803dd03bd59760daa3231fa41f12d92e772448061cd9e38594996ae6948380efdf26713934b19ba23182244ecba6cff671eabe4bba985d3ef5f5c69c65051218d97612fe42c6a0179f9c1b3d37ee8a0b36fe60d93110680c3cb681890a89b60c907cab813996fd5a833db48743539462c0fd9812af9d5ca1eef3bc2dc4f36bf8e583dfcb35487f8bea322bfdb879475afd3230f6c12e963095e4928aa2bcd599405a17a06e3aec2239680acf8000a6bf4f17689a7cac79dcce85f7d29a7009e4c93375a3706237ce40f18aef60b6a20bc50bb03f312fee5f60556fa7b94c47d5d41e272b32994fe7e08ee3bcabadd9cb721a8768674fb97d4f047ab9521ceedd5ec48f9f7a46862f6ff12fad6f424549ada8e605aa162860e18926beb22740e5c51e088a1350392b015bd993381a04be90e04e10ef243a1a1b492af10aa07e4764d722c593da62498745aad4ee93de156d5dadb29dd1ceab94fb0ee0852c5a252c45eb037647d9cbc515235f4cfd66f2371504493c325089bc166964fd2a98962330688df5200897d8efd1d6f56be1e74f0d753e393461b19d6087b5cdff497856373c115123dea12e2e044c78f343c7850359357654bb253298695cfe4fb21f7033036dbf83e25d99168dd813c57074be14579f907055051aea172285f9c1bcf7c6a3faaa5fa5d3baf89d49e13c4f28876e41e9b11687082e7e28df17cdb6815e2be75d9845ec3cc491e54f61efe6efbf679d9ba48441d1e20a10057ef21d9da9504c7ea13997ad8fcdf82fa1f8efa1de988b8d06a75cf6ff8c7b9aba109d964fb8ef7a5dcaf74905d2c7c8aa1c016afc6cdf5ae8cc638400e74b83fa8046ffb13607c1267e777c12a8c9dc1554570f350ac0c9ccf4d368dcc230ef668320cd81fe04f2610127c7f6a53517d7eb64f357b8d858bd9c90050080f38174b7dd82a6dc37907c456d5e6b29ad01847bdaddc0feda06db3ade1b3312b6e11696fdb3f9dcf6bf683ee2daeab53e451fbd610a47907c49bcaab5f3e4740ddd24e793a215a9e41855f1fd266c40f37d5fdeeff036cc81cb8a66c55332ce47022d3e52935dcf064db392fdef0ca05808e764a33345a7705be0ab4c196970a60c7ebe056cc4ae8d9b8fa9dfa9c38d239c4ec99583662cc4d67c4994126b040346a5a340d164a40f21e093b10db0689fb291cc0c737eaf19ad24e2a3b0260794bf0b170d51e0a389968f6e201223098f84334e9388f0264d502ba10a184ac250993892419ae9365af344cfaffb3b21da6e39a545d58746a67245ddb1f088a92817efd501e0e37a9d457900036a11033b57b53a8a1bd19d3b20b4022dd8e754701badc64f25ed267de7c700deb19b509cc5d4a72a4a02415d696aa90710f42f65fd0154c463f0dd900dc59647dc215cd6aaf48d00313ae7b35368eb2a88b2fa580698f72abf4b3b2080ea10a3d595b54c954d7c906df4f24fbf687037305dc0aa5159d622938e90ed20dff7a566a496b7d4634b10ed0f48bec4b1904c41f30e36e3874083b69539c8754a5bc487ab54a241be5a9c70212e29aa0bd0bdc5db9412f128a17b313b7afd432796170c4e8cc0e29f28469c5d7ee9c87754f19eec80450eb93e864cf3e30e4ae4ad8ccb8241c92a03ef9e659605a692dae500a11f854616ce0d582ed5d999313b4b35fcac0f4bfb22680a95f2cc55e68b05b61287fd8052a5f33e4bc6330c0fefd5a2975c95327a0cfd955e9c086a7db5a6f07d2a967b52f2cf54a6737560d1e9b40f61eebae29da53b56e24cc688f71f0ae483a1da832d739ece0e", "", 0, -1220965910, 0, "b81e17209896bce8269392e7b415042da0f86ea6f9cf08e1d8444118ab0efdb3"], + ["030000807082c40304ec0b0dfdf8561f67bce42e11568d27b34fe72b04ba9eb7cb64820e4b0dc3d9e5000000000951ac6a63525200655313ce5d3734e975855fa75f6231c5ed5ce96b6e0bc40d635cb002341d655800469b1853c000000000036a51ac3bc8cf03f718ea605160797e6faf9e33930c9493416bfff094ea5d9cbd3e85a8179983af0000000001acfffffffff95c7d91ea63893f77f13d1c81a3d70cb95bcccc4bdb1d76bf0b8ac3ee039aac01000000060065656a65002a6df8be04511a55030000000003636300089f7f010000000003006a651778eb000000000003006351753d4f050000000002ac6300000000691474e70300000000000000009ef46a0200000000317f0b68537a41f31f4ca1e4d86e74f3f92020410697080e9362a660f63be18f1a76ecbd0ad9652b93f81e16cdace9c5b7d02750739d55984df5bf6175061fedebceb9a5987213cec332bf9311ab8fca463ab85361129b7c181233f438ecd54500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da87f8452366fca46ab3c971c82fc82d5020b9859e49598c38f286a9001881c0f24d5280d967b54ce105269f60c60c170bb8b3d7e1c5e5949797eb090f3601d82df0ff64214b9830578d890d378093d2674f05f4aa80ff93ef25e9b83788f6c294829ca74f97f9a82e3042acc16b2cabc299196983c2f628ce2a3fb864d38634021d1f753e38c32a651c754d87dae4ff4f4cfffb937cf3f1fda261bc9cbac947ae022e7cc98a65fd172d027225a149e1b904dfa089abb659e9715cf58d11840ecfbf0a000f801e45c61ecdfe302292137dce524cf9069cf0c10ad07dfad94d1fe3580b8cb30a358c6d0768c2ee1b78cbb4022f7b0a1df7cbd8d1a18a6ee12c15a175bc0224975ee67243fac5b8675c3b8263dc8bbb0c2af6dc3286d1d75c6da88438bacb031de10d068a870f66fbb9c1994a59c0619bd078cdeef53af43068159a6830419d031923142317da6334e174b2556c5affaf9ced816ec9561be526b95c7ae81dc508031286c32d3f54faa24a8dca95c195765cf64e0940013a821af8829ac089176d30020faaa9ae4073f7caf9ab53185b71aac6b9aae1171a57b4b5aa399983ea06474466a25123ea650b7baca13a361eea018e5c6dc5e4dd943f0520f336be28ce5606f80afa18f08df3a904c03447ed50ff81ffa85cc01fd4116355811fb4ad19f10db56cad17110fa170de742b1e7e85aa52f2a245b51610b5790d1d38f101e84f1a0bc05bcb81071c5587b44f8fc8f07ef6ef9c372a2313668d70a459b8e19f4ebb92c7c7144a48cec17051ed947cdab4f3684abe0037261eac3da8ec33ce24070fac599756eee3bbf93556fb3fceb39df9f2c986700fb680aaa40db21ea6e372aca19b0ad0b58e1803f1ac9f2c96504dc3872d03137889b9096f609bfa1a6a671ea6382da5d84a9a1fa36e8abd2546870e6d1f146053be18bf682e5db2a39f26bc9ef3f040a1a9d5e3fb5d99c466a08c64fe1f64f2cfc0dd39d13334f12d0770b814c73ee45e2d0f15ecc8d42c084002ec559f483595ceff89207deda43a345a2f1155f8ca147e7b6597400f5ccb3999d98bd2db8e576d01ca49b5f5a13eabe9b6e7bb520e204cd5057761825ddc44fb5c08e0b02b8d16984b7dac0db4a5fc4d077ee22d5ff8fc36594f4347faec4caf0b4390432480e92db8b670e044c8634fd8b0473560cb4cd58e3ce5fb58d106dbb2fe28de52bc3664f67c4870ed602a5f4b39ce8c715ae8025ecc9589f80d949a0e8a0452844dfe06ad3aaed28750fac2e6cec84617fce95714e500ff8975a91ac99f113f87506618c2535a3a086d1979b46b25c8f96f111ca0ebe090da613eb1786ab630414ca12511e738c1f3da20d4e332db8d60822ca39d0425f30aa04565788a17db3c6ab474a2c587e32782dd5cd309cd97d563d98332362c75eedce7e4f6cdea0986f95527445364e885f11f89dd5a71a586401d0dcc8d6b3466c5ce2d019e57384c037ef6ffd2bf8d6aa939d997b8febc1e817d0f0e61807240d27cabe46e3461caabb7509681479d1df1ae413d53c78dee290cd75254f19e70cff23172c8281e4244286f51f43717057240f5930bc5c306f6a7812b93f081ef65167fbdbddef91ea9d58c7e602027d25ba5b2be4e57761e82cbf8bc341ec0c3cb558fef045156adbf2fcc441529043a9e52580b4c50af80c54369a15b30bd04e5f7e782775326f86f1c571eb40dcfd48d2223463ee06afa2e8aa1d99d2804c2c6e11c5aa12e7abd4778f8a8164600ee883a383f0d0b3801752299f2fb7e361e2d09bbb0771d76ef28787927998b4dc8c781fa40d251ca5b4cd3130e2004ec6a11a0f1430526f76142f66f25342e521e5164194b3321306406e4f2be53bcaf2d004b06808c88752fccd13d7eca2d86365c64790f1f6dfe7e69407a7a08a38eafcb3850c0c72188a25d2163cb979e43526339a92076f5043207036b878abfa6cb4990b7488cb3ad8ce74aad433a15db42ddd5e423a6bdb3fcc45829e6807169a251e66c43c74ad379d817f5a78ac8cf7c6fe6e69b2b311d694e7eee80aaf1ef1df24d2ad5d62c26aea73446f4e40b160e31fed2b9e784c1644f3533fdd95c998deff28d0089e9d5ff95c25c3446fd8a75a8124b63f99f8ced06baa4bb14ab42e10f159cf63b9918039e5456d73ee8c7c0cb0ab6a746221c2b6fde36ba4265aae97c9733557817cf041730237b0e8911d3ddf4722bb61cb3301a365c61cd073377acb776153b86332d4f351abe350c43505bb619b3fc0ffa7df1f0922e0ba5958f995679abb3800000000000000000cbf6e30200000000211b3305cd3aeb9802702c7a31ca8599b7c433d8dd5d8da786ee456c8d162913713ff010e134f5197af65caeb23dc94470a2465fa59fb83e762e126f5a1ebe2134cba145e419d9ef37dd93e9b65ae5a883e42ba414c894213a8e5d6900c0e58800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000605124ec34ef74469c7d42a4c4307ee943c0ad67898b656d19028048dd8130c12c83bc61eeb9256c1372572e188808bfbd759a05abd4c8a42c245d415a11dd7ae8bcd886fabbdc748a67d15ba30834ceaedcdc4807410792214a0938f59b5736bee9024b6b91e3dffe2b56280fd9857f41f2de4a8140029deb779eba0f1e3aa6030716b62a831453b646b35d567ddef603f5288aea108d1fcbb658e046125cf1d1030f3b14d65bcf360fa15326d2735bd40673c2fb6fcd5091812bab6e3f7a5ff46a0a07f3cb97c452224e9639660a8caee0d11519563f4d8591433a437e6b5dc23d2ecdd3f8b5abcc157a71cc0ed8dcce58071dd678c0c45c7015961db6b3d759779d032d05ca4490f770c75d4b957532d5a456eea8eb60409ebeb807180bbca6af9511030a4041cf7c2e2464d8258bfd3771b08a30220eef372c6ad1536be6420408f2d102095c27c54e32169ed375e5ff8803c33892b2ecd6f486905d5045878178e09eef032d12ce3f9d4b0454ea896200a1879ecd153e69ffa5ffac44d24116eb456dcb5e020858c06027cf93236f6e083adea1a003b88c9827293620b784f255315a5b7d8a1d948057bd0f2994114eefd16a6a2bf0493c53f1b0cd2a7aedc05e8fb2d9e70f9dc2a265a527d1ae2bc2c189526199abe724d58048e70b82e8442cb7cd0bd9fb7e1323045df625df693481dcc30f709aa3ffe5322b018badb8aed3e8c07809d55aabeb1f52a0e1c526cef0e5751e67c97af590dbe589b10a6fc03859709119be2016bc3adf64c45cf092e547f967e55634365a2a9dc9de6310e8c4de170a5cba3ae14e6f7b727acb0ccd63a726b0f8e45650261a8ec1d74fe93c069f3502f822b9cc95414f418d47505add8a00fafa9fa2a0c492af253beb92b534c12b035ef525ba0e13e9f8f3b63c574d5b8190cd6d6bd607e1f0c3adf48e049afda9a020118e814d6736b498cfae41bd723c10b35b511ae3f4bbf7572ba01875584547c0f96145e94c9b3304e2a8a6af7ff30751983e0900e82ea248f19e481e2d18cab8a0427c6ec0f760675fe2a8f1cb3451d91d6404d4e0321c3b648ad73f05594160a9ff31015014d27f001c3b74b16b6c5c7471ba817272ed86a34120e6648f61522a47800cb6a2f5c211d2b408d866d189f69e4c6f7ab07bd76674d813e019b4c674be827f612cab1ff49a35f3e95235eb864951b7deffbfb71c16d4a4f5ac6e90b2a23c517a8484029942e70e37e00aefbd55febf8866b78dda500b842817922da6348603cd2da21019043a0cca8ca0e4293b276c6d59a3306924053b585839874434dc3ebce997814468df54738addb9630c2e1c09e8b2401294368b7b3e827c640813e5145f82cedfec241f68edc360e463e9becf5312e12c671232f946f59b5f6ccf5437652c26ee37bc9a18aabb13363ad68d4bd5b6a8a26aac048221bc61e65a686ca36df2c8ace01b8838ec3d55ce8bd67da374ba797cd7e1ef3cecfd45de36fc9b8ee0dff7c04193990d86d5c3f20297d0bfbe6d0ee688f42bf9c473a48b8ab1be0972eb6b63a5930d5b0f41d7dc2e7d6386923a3962871797f4b43e0cf50efda8509a243c278854ea87f6a4b8c2092a64648d721bce072fc6153ce2b3f75d9bb9b6d4753dbf8ee909a32d3b21f3a4b85cb5290d6dcb2db85a2faac2e98569fee5e3d992cfa1a1436feca5582477b5c0dae6c56aa11d36ae512d6e9a1f28ab047fca72d361abc3900b024d5a8b398295dbcc369c763e4ee061d8c554b1e28092d14c7fda7081104c957a40ab75b4de8616f658de921fa9c34fb84bab2c375fefb089329355ca67682e44a34db465b609346c16fd7fe3d73def56c28abe856d723a2328d4eceed643214a189ea632616e1d0b7aff30ddd0780c5fce514b9da97c909934bcd0b8a42fed7d726dc050fee5d53a4cf492f30b3536a9be028094576c2cc5fd2017d9ef25cbc711cf506ada0be9387b103b992d8362e3e4606dc0f18161d1e83fdc490101b1836e5be76aa1db00cc193cde698fd81a800fbd143d8493a7041aa717133ee0c142a472733cc86726e6e68f01086cc99bac57a1329ec35947ab67bb122d5339ed15eeb578de6466e99a3f2377c315be7ed09c23c8781797aa69fd7a3aaa307d1762e38758a68af7d67419679c9759b49c193aad38446c33195a46091cf896e9cfb31db1ecf18bbb4d753f7cd1539084533d24aa1bcd24ca71c4e8e1cbc2476839f758b7a16dd31a264bb0fd75d7d93db9b131c11c0490a10e87db26d481b4c8c196420eeb4bebdabc6fff01000000000000000000000000ed4603d80f9e9628045e9b4564e8fb2a3cb13e0d9e054f3732790beb5dad4a6798230155be0e27721fa033ccdefd6d4e7bfe996371fd3cdfcd46cebf635eee8c02ed46f9f063b227092afa88da8ae680c8a8dbf55adfb52330048b647965425c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000125ff4cf9f5a8534ba8f72c9995b016992c40fc411a1178c53c2b11fec3c1c429a0d64e7cd1d508543b0bb3e21d5a95a78d0e8f2b704e7055704c6dd6163720e06ebbd3d06e71b4e31c2725402729a42d0d00d250d31d2c62930aa2ac6d4a8dc169776a493d0b0439456feea36512d38058814fea2a421ab6c1fcae390fb565c022bf08d001ae41d41a68d45915a31c3db84d1f52e36f8051d4d134a89ec338f900308039f6048e656c13d5daad3988911ee68b2105f9ea76b208035b1ab6754db810b0704274a564d08370554d170549208e96fe4c41288b7c3d0c0b2d19a4dcb6869555e8d4e8335a43f89023dc6d3947b8ba93d3bf6f2dfbfed1e2b22312789776503209fc09e79051fce1de77658cd55c2761bc2e7d9bbff95b80c36c7bd7dc56447030b5d5d5dcbf9065a0d141b46d0f7ba91760cb029e43a0fcf58380ad6220be26d0219c94ad19f92fee099c58c3e2d9005981cb847089c9dee3f59ccf563d2548d48031d168a44f1783a10f1090d40f4d64175063d91378964b2ca96a3f8836c8f6380032151da995d33b38ba9f66f81eef40a9894d5fb63e9c0f81645439989f59c88326ea8c253c0c8a30e1e4262a6a6a19cd219648e4521e684b1b9a7663cc3e1f242f508ffe8c89816fd92459d396248f46572f98c5bda493868131efd58efb55b90927e54dba35cb75e7cd08ad08c6b87b4f08d2990cf081aa8adaec6cfc2e352b1de61937c7a330a9a8f184a615924ea84617ff359b4cbb73ba6d5d8b944a31d0c4cfcc358e9305d37dcd2c5ac6fd7a73bb7ab2ac2a72166def7a5ad8d7935cc152aa6f1eb63293e09aae3e6fde0baa57553c18aa1aeaaf936e42d5af7ba9d5199889b6983863a772859a3267dd2d8a268b1d2a5038e41768aeffa4dcf55a189eff8209ce4d80c3754d87eb26e888fe5e9c3f34559ee32fba4da4cbad62520b1305aedf16f81620dda5bf0f71df9018ba71f2a0aa07a1a48dc68ef208b98e45cb7c8b14cfe57cbfd6bba187f36baf0b5b6ca930f91bd7b79f648d12e41c8803aa1749a94a7df8ef305d0e3fa23f41eca39a8586968cf938b685343c0e79c244044d2fbafc44ae1e99f0d9b59112b69f43a1c0c29593060b0c63e043a730f3420a2b17eb6df4e045cde42b85c1ca1c9e8630d7f11a469067ce2d478c3c8a495b20ddbc9396bc2dce02bd0dc18ba183a259df5637633034c9caa13c021b612a55d57c73ac65580a8484a967aff1e5b3bc7a8c79ad53276801f3a538fdb7a390ce953d0040eea1e20ddcb977c3e4393fba2d6176f5b696f862c8d58505d696bf68d706313dbd7c0d99f2d0d613f5d5189f45747d40e94d11afa6bcd67d28f62c2f36c6f3053b68a8ef7bdff8ba5537a223716a201f05f58a026b09113cba1f1d3059af69aba6a732d2ee0d72f0c3dee58a3ea199648ec83afe65d25c785da5a2c911c165dd2fc690d5884d76671d48abf8de575b11203bf2c0eb518132169102fdd0c9b1d1c3cf56ffee314cea986d2a335be85a1b237790a7d7b62d05f8d8186c1aabd4b3bfa03e6decb326d78042d9b4344e10a25b0f60ac370bb179c6031fb45c873b1ba480dd5fe1cc7c6b4828805d00317b739f3a32a0a403671c73e0da58f1a07acdbb7b96b5d5c68551f4ae6b5fc2d7ffa07e47b40535432902d88f5e41180ee7b07c3e98d6c334ac997539ec15c84c95281b85efdd81bb6e4a89d78536088f6c1abdbaf77e235353fb7de45fb91273148c6b212330a31153535eb32040f4c11098c0c7aa08f2d5b8928e2bb3b759c847e0be816f4a2ccdac898a37facf8f1bb974223b3f4665c81d31a68bfee9ea3fc7e7c643a30ef00125638490ef314fdb3b13fc165e642c9dce1d5556c48ff20823af1bf6a15ce3eb1806bd3a92e4a16b75eed4729f2843e00b0d099a83857b4a2370745308e2d2026f07a2aab6bf7a5c4b834712d4a061e9965efd9fb9403e522789c92a53590f381a1d407a1598a0166d7e2b2e137cb1f9657cf2ef075af67d1ba528fb7b131840bd8e3dfe7c6b64052482b769bc3239b873852a777bfee8f559483f1fffce943acfff836bd4d6f71cf0942ad1cf788cb60867d5874601e222e4a661a271e8780c7080418afb4fb09dbbfd809657fd866ec87a46c8ef9c618dd60bd38c553626f293733f49dc937670d1924fd034aeeb353a29e0071bbe6202895090c3c31f043e42cac69c396e6e29cd516e76ee18501501932d8f539ee23407622a4efe4128c1fbcf1638db13511b60fc7bece2ade8baad64ff73daf95d4beda37c0d24f15b04a5029dc75a7ebb67a44e95c0392f98ff97bdaa2d726f025189918bb58b80efa0cc64e485c5a80cfd8ce060d219953d2c4666afe913d467f08c2c37d239aeeaa4731e2f0de6ea53a40bb2fb867a9ff189a0bc63e857dcaa05b0c", "5163ac00", 2, 1533195145, 0, "83f24879bc1b7b87f271eec21b233314b416f4b5f8308cace50352611717580a"], + ["66caf51402bc668a943b00b8cd0fc2eadd34c8799dbc532aedfb9c8ac098c5cfab3e51354901000000036a6353ffffffffe92116922fdf814202a638057b264fd025ccdc6f6bf569ece40ac0a4df862fd401000000046aac6363ffffffff01e8a377000000000000e1ff705003000000000000000052ff6e020000000003d7f3e152d7c9f64a02a41f4ccea972057b997bdb95676211d374401ae2cc48370ff9752ed04723285b757bc36f5cf5c0f0d7b6fd895ff6ab3fe63e77c5a0376168bb5d048cc7b932c3a0b8a26d390e418416c1fe3053df88671a07f5d6f80b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009383323cb1b69b76e45c09007d2d3fab8a209a856f7e19d2df38f880ff6ae77da47c78fd17ac11ee280b6afcda5b2c36075519f86402e208030ac91edaac38f3c46efb6ee7e911427f376bbfc7c5beb672197dd633d7c1afff15fbfe2659b1d23cd5047413048ebd480d0d01d8b085cb1e254c7e86f792ab4e746b486fc614ed032a69828afcfb502f2f2ac8d53b3b7a1b2e3b3ba5e3f34836eea12d28afbddb82021d4834f178b24a9b3638dadb947a49b9ed20e693a7d549b89bf5fa7c904657b70a0809a791c1869e85483f1826070db20bdace2706bfbaf3fd8565f367974984ae2c233764d9ed17bb09e369f597d51e91ee928efe31396a0bfa26d23e4441cb7d03025c6b91310a630438eba58d387cf4af0210fccede4dda97f57e91bffd91221202151598bdc703105cb442d89fc5f06f72cd9eebc23df9b0cedb82886f358420a3022125bf040b150fcfe43f120aebb22d923a438cdd820823c6aa14f9d7114247b60219b06d251646dbd3065403701928fd3350473a1420016cd180843dc64fd2a230032e3dc9ae25a51eeb9cd55e33f4f2dc0edffa6e7997aa690bb9967ca9c94f6a52687561a59c69569aef8dfc080a02f965a05233b203fd9bbbbae5ea1154e14f1f913528a53976d64e44e93f5c6883109cba6d4daf8d55a73ade88a2fe127738af6cce526d4aac8ed5a4d03b81a2ade37ef423d0018772134bd59120f34d367a0510d3b34320b65d41c76432687697ee251ec9b35c55992a48e472efc18b0a66b10dd974a2438d3ef2618cfce8680220edbd80ca43a15977e360200c080af5b1e923698d3420ed53bc3a4e71508fe84f811c12f498a4ec3bd8268851cfa93d33d1ba0ece32de6d4cd97214f95767f4a9447b97aa0b450c205581730e045ec86591497aa27495da978e8371141e6ec48bf3577521499d27e8520790c2107854b5b08302b39a800c7d35e48bf4d50c7b9807de7604724cabefe58200a983526d15e62fde36bd45b535b62ad14abb4d772cc401f327512ef027bed96d4782375a7426f65b52cd45dc46a67f1b6b401397a35e67bd6e6ec2e7120e3f622f19a6fbc610e1fc6db1351c54848fde7023601e4ff9d795702fb035813a605130c78572d869c9141245c8e3fa15ccf7a40ecd0219701f4bb4c7ccbe63fb1fd1a5bc4a63ebebdcb9b87604965a4c0458bdd152a7e76f7edce1c4981ac3f5626f53ae1fc90f6137595b7f06abc0e330bf623babf8b6c5291c1fd10d30b04643f2b2f7eb0dc99f724294aa4bd53ec6cd3c265b7f357c9754575d755556ce0bebb1bb455f46ccbca0878dcd393f52c3cdb2e520b16da53241bad8ac6b4fee0e42dabd388f9484fa98ac1141a033a3ddacba2d75f36ef1ba7c0a90ec32d9b3e6f9c2c4229a6a89766fe84130f55633d5fbc5f60fae84b5e2f92f1e4f502c9459e1b8b3cca58f1c920068320140fcb77663b9fcd4f3d7a7ef5d9b029192ea447b901157b9e433d2431b457bf807abd12451e6e72188116407aec692176e04f5db2e7d8af9e99accb52a58e0a3d6b4436af0940607e3928517dc125b947b19938c8feeeae1b01f794d0753bd85d949680ecd84bc653fe87914650d8fe4b98cfc5c874c40b24f6d5837340f8ee9934e599008f3ac293474f0a880dd4b07ddda47f5198a0e587f2a96b127ec675659408ec5e6a6350feb5c1ccfa816d8be842d17c8dd50fc1079a585fdfbe65796895da6335296ee87f5b17648052833b7a00fa28e74a1b39a66d10f8606d52705decf4b6c7966e49c9fe1d179cb6d3dc8f8083fb113e0437418c8166ddcf1413baf50e0e7647c75d9a900f00eb8f5dd2892b180cc75b04e6977e2c4515aa4a8446eb1034d248e9bac3dac7efa537c24658a2858bb4df4f453261bed4faca63dea8a8a62a4ae3b314e6dbc0523cc1ef033a9d3447ee262aca0b2b429005ef83abe9257f8780feb0665d7ce935dad17d3bf606d18588b5e0ace420e3e907077514b7e1c6218ccd4d9eaf7cbb7fdfa459e4f568ffbbb8e875f4a0ff82ab03519f4390cb6ba621a8e579cca48033afb5fc739b1519249c6e4def3453b6dcf929f84400e15b37d6c89cd8353274327ab4361d0806c536e5594e9105df197f1dcbfe079b6dc62331ffb9a80b2ab51e02b76ca789606f9963830af4663a9409cc6336799f39bd2d50e0dee181bbcfb9da1e82ae54f84ecc1c730cc920f2bca5aaaa392d3f17952650b4fe25adc7ce5882d5fd07187951845d7448c61f2b1a167e02c374f693ac937ab12c729124a0d379a28b148b6010000000000000000000000007a59f617d956c05c5178804f5ecc64cae54e5aee988976761df592bc98fa69f22c414f43c020cfc3a510f5694510bcbf902ea00ed1f98e0ffcb722cb61bc39a95abc9230de56e830cfe8fe832c312cc2b2a064a2ecea2924273b83bfd5693d85000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001277f24025ed92754600d7cf6171360bae2c0eeddab63c32e90cd8f4d8b80636ab876522cff30cff268fe26ec1a424808134ca62f1423d3d1b070b59425dfeb566512d20f0b4d215b39708b545be53e5e756132818399891f8d3a5ad81129ae8ff174743b8e60d71d18eb51d834a8d96e16b2a68f4f6f8ca7327a96e78a30f4a02154306cea74671cf390f6e0bd5877302832cc1bf534fd61243bb1a941279506b030d3108b49f6b337a84bfcada2d0cf143fa81d5f726c028769d2e02af784e5c600b076176b17c9c10854c5b63579cd9aa6d494b3a083e7c6893fa2f80cfcc1795abc221737c113855fad4b5e1750346c9cebf443fa42d841b837dcc1ac3d121b58e032295edff309fe502c61c14d720a9be8f22013648539478ca9304d92fe0f993d102253cb04a7d73b9001ce4f2f39a63a06ac2f8b5968aa2b59f20ef7f3d2046c4f20215b388d48cdbd107f58d5cfae67c43ea5713425d59e476b75c4303a865d2eb68021ba2146814d816fcf9b5b29e9035678f410213c522ab0a8148bbe55354631bb80214e0e371ed3deb76dcb9bdb41640950f9496ae4087808f05261f72a3b354536a03515a9d8d1417feaa6d182ea82076d3ad319976d31194e2ff94fe50628aced86dfa921fbbfb9675e19ad0a1372479d9f8890d203ca1a469fe6ac432c564c8fdc8c3607ae40c540f8c6202f27c6b0f527511bff5d4bcff1155dac04ddfb4da1bb786832992f54625e65633e956cf743f251679eb3f72122d3fcdc38df84ae2c372747de6d0f0a72c83bcef43af57097399a57eadc695cfec14c758cb903471cf5028dfa42c07bc10ef23952c1ca2a259f5485853d1c14e4687804361bee18e492581b8cdc5f1884769c76e1ae89d53ea3a7901a4f3805e55206ebb13d9022135ce24868f9c77d18a84136f17dda1b5537c93a9df7c82570c5388af463cdf634582669c4a77772a1e3997276b10db1cd1cd859e180d870722d0d776e81d67010afadd5b01a5a1fd036d75ef2cde498886d87a7bc5cb332efc78620cec0002c357d8460a7eb9f1c8962616f365b2bd53dc1d952fd28ad7b52839f56fec6a13b82b4aea69159d2882f2c7dd6c875aef4c4e6847bb597682db2908a748d0331b9102e968f096b13b013df04b29b6190f0f7b40bff3d3c49464da2b58a08465a1212a2e5e2a71e3339df128b97a6c9e39b984fe99dc07c99ba4c6623894d08b23fb85d2a353f6d3a88e129f7ebdd8fddcdb64d0821ea8824cc5281841ea53e0cbbe90656c590c15d0c46a4ae95569cfbf2fe941fc643d3de9ec2e16ae16730d00952723d58e38f8a7bfd89ebc2a4823052382f14c7c35489de99c6af43d33943582ee42062de97837d9b29ed59dc94241e5dcaf4a3487a52f8e4d4818ae789602cd1c4f2293214d930a65812c9aaece05dcf0cf6c83cd58c7818cbad9557e7fadda702b478452e46228b1170b50f59bcb82c00315b7067b0d81838203606ffbb18fd521c810afdfc9f3a3286829523c3f7b46bcfb5433a5e89b4d1708356f2fc8379ea665711ba53f1aeeb535ef354f7bdbff1be5bb5e42abd9ceabf1716392e918c4570f7d6f1844fb45af1111726b0c212a324e20d54148bb6eeb7af1c4801bb4dda9f8659ab2dd2d7ebe93160266107768d07429b89a37a08a31a885b166bea5d1772343bcee9b3bfaae2e73eecab3136c5f71c24539871b20319e704be25e4609ea3b00a068695e90e0df07934f1bccc86743da77a94676dc0e4a7793f75045487ef867f43d3b9d6d37b8b28b85616e429a362f8bfefcb7e2c21e00d820ba2b9e3b8a38f073376f84037c3bb8febcaa61e1c858968f346556d5f6b76cdced7708acca684dd22182a43133750a392c4b71c03898a88e342d75bd9c552e61e4bde119318a5a1ba97ddc6f67c0deefc6d5a7016048eef0a7977b96ab848b1261b636f3952a68516d02b866f0fde7557f23ad3b0218d82bcea9ec0a017ab9bfd88f8244686363483c8f28eef4273709dfb5c623d079ed57c54132cb19004d667552fb6ee3def4189a28901039759eda55d576578a6cbb029603e076c48feb2ff6eeac1760004aad54947ee9ecdecf550d6fa291e1f6d9d523e89d791984bb120b83d4965cf574938be4000d5f15aea8cbedc058a6b4c1404e5832e0324f972f77876f64f60190ff189face8c86b5084ff38f1f2ea51c62ea9064d2975912da6834d93f101ffa810d1208bc05b173aceb35a0d7fe37f339a1dd0bcf3fd95c61d273979de8d0b2957b2ea464b27be290f643bffcd2fd91e4505000000000000000000000000f97f387f73cf3c0316be5000a1d688321576d114db135229ecc513fd5f040dbd911b5b2ca9979ff6c30fccb113f10663b911f78382911cb2427a58ddbcf4d62b8c4225aa3a3b9a128e073048f355877c6ac57a377242f0cd64bcb4a0ab6c12280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023c1c121d1e5882b2d03302d45c84ce52d27ecfbf331014a7cdead9355b1473938a0b5e314a7eab19227f2e8cff1a2a5479243b6d4bd0de8bde094e1403679115afd042cac388d71c100095cfc74e33f887b304aacf7f60e80beaed94e23a828ad15997ff3e7150810b0498be76f524c6b8593752c0a00f2991bc4b68b1a740b0302cb7c61f56b86b63e6b2adbf2f617476115adbe713c1ebe1132d09333b604e8021a49e3586f92c71da70c581f3918a2ef01b95a6ed40b4021a904ac280edbdd9a0b06bba89ee11f0c73f3ea607696fc46ac2dabccc23fe720a5cfb510db739494cd477400a3497d7650118de9225d4bf8dfdf7336614dcdb16092706e66b5b71da103259b631cd56e298a7fac4864da73d76c8826fbb09c050f3888d776aaf86176160319e8aa7e085b4c7f1560a7aa5c4c0ed73aa6aae08cb675140c6b494d72eef3de0300c48c8d66f2cb4a2e6c12218e8b99cb43307cfab69449f166068f32a4076ada032ab8083f4f25a1712dbf906e8d33d33527200cfe1fee90c61e8150ee26c37ec203100c55386c8fac531e9c8241ffb9af49b0e6a93624cea0242da6cc49c9dd0914157c571004f153b7b7e9d0bb630ee2c8c3710be2d0a35886c01e553c036e69922bd181d0a814c4d50f9e7c99f91b63bfaee523853b282c755f6f78687e60973e23b823e439025bb26a05adc1b445010559c1d176fd4fa1e03ec1bd19b1c41cf286918961d1f231f1058ad9d3b79a7790d6bb0265d7e51280a68ba8c36ce98b2659638b10567941fbc3aa3e34af081ed071712f86ee7224c4c83c41d4cd985d3151d7aa847041d343968d28b7fd8bd2cf278544a70957bf89a47855e84e3bdb30fdb3aa5b4da67dd1fb6bf1c4d2abc3e65b585b3538123429d38712fbe5cb0a8802f0793edb24544b3c923d408743abb2113704705b177d0cfca4a653b04f56e87cfd7ff6c454bd379303a297657cad9641b0d0e9fb51da67ee76cf6e473cac75d8f2b6678be09b6147d5b7cc550708d1d82115c9f8b0d25f612abc8dc007a02578ad220c490af64e4a0b945ed84507c39e0f9f01cd0420d4e5c00ec92d2d7b9247170412bda3465e5d61e74c04aa25376f8a164f5309cfe3c27ede8a780ad8abeec31d2057e2a258cea754fc0a3352c0ce3f1ae28d0f3fd634cd3897cb4f97a75d6647d7d11395bd0c463bea2d3961d5c6732c78ff4786ebb0178e595d8a78cb4e8a1c48c7468cb258354ba90a14b2c82ca5f130976e7a7650364cbe54c789665d16334637ac03d6e2f7a9c2c606ee8d6e5469f7ace775eed53b904a50201db33d932430fb140d8ef9e767f61f4a11cb775db8fbbe1fb7fbd81b4cf1819741dce9ebcfb31977e7f1774df5ba8e1842add5a9c61e3a03749f1c0ffaf03c4c8d5c23b71eb584ba81a57176dcacbdda1c9f6837d99aa8569092c7e683991971a3fbd1a168c8309621d26068a77ed88f8fee61670b2eb076e7d38ecf2fc73d80591a9446d4651651d247a9a3c6de2b281000e2ca92d87e07ba74d7a6255369cacb87308318ffacbc20d8a0f080cbdf7cfc2f598a9b6c33c3f6d944eb3068dc07ffcd29ad4ead8302b6cde0ea9cbf2c6926422c0aa48a1e542d97ed17288cba1282a08fe9f016763754988f968b5250124a38cd58c668b79307ed991255f5319516e79baa77dfcb361d3187ad86d7ebb6057047387cee9322c9287399c8b745f9f36bb1a010ef11c4966899f63a5935d0a3da1ff61ea0efc817ce276997282237ed768e0695e4fb7fe6c4915ab376fda365b278cac9a9e1d1c854d7616926ac931bb8e6042b10b3c4b072b053d4219fce7e5e2bc1933264212eeb7b4a2ab8fb8e8672c21f43d249ed164176e8f2ca2ae47b42946e74ccd9d8ed206bddef567305baf525b4d811c84b8d2afdca042d6c0ce9eb856f2048e4f470b761215a7a2b59d7afe4a2be15155cef7619df22da8be898889025d632425f7774bb81a384f03373279d1cdc2e7d2a815e5a1584f6f993a5be01d6f0f4f5848ad0c6a77ef15772ea8f8471da5003f91759bd8dd131e8ca9f06335d2440fbb5c8ecb99f67ae8cc9a512d60a99cea9cfd4e0850b9be4db40daf7e8847e5c00b3ab001b9ad4a022aac6c55864acac669b7a45a658fbe21fc73a198192179cb3d423ee75be126ee875808a25faa3860631bfa5578c7d67599f9337d4efb5d0deca9c7575b8a039e42d598dee1568faaceb3db62158ca6a7fd01479eb498252baafb82f68dc213f50ae611587f50fa3acb33c1c85942aad5e19cb52e83a64f2964871704b25bd4c326d248f416b93078c6ed352bf484f1085dca22ace064ca414c04d03c758bfa72054dcb75bd682d521f725b928adf0def913575d57e20f90c341201e98623866a3fd039475c52139a55cfd8381759977099e54ec1307", "63ac53", 1, 390593626, 1537743641, "0bb17d5650a3c35aaa2e163ce508980879c681d70cfd41964002da4f4e881cd9"], + ["030000807082c40304b3ca7695683f07e6b5030f750d39e07cc12e9f63fb9a5e9d307a4d64cad430240000000002526affffffff66f882eed6fe190588a6355c12e227812b7a53f494f8e8f658cca7f12cb282450100000007515351ac655253ffffffff892d22220edf1e4a067a91d2088106ba0e1b058fb48d4142b6d4ba08a3d287ee0100000005536a0053005c951c097d09cd2a12e723c82d8250594b990b0aef27012c0fc84f994bf26b8c8183c3780100000000ba7a73db02502d3b050000000005525165ac009e654b050000000001ac00000000d802cca303000000000000000002e19503000000001ff3103206e72a5926d1bbbde6f8c8ae89360244bdd7834dfd07381f74956d9602496d93d462b09bca017a1d836d74a8ca4c9e37bf71e03dfbe857194015ee4a946cb4e040a4a6a1ce13b0920475fcdc8ffd522a4dd5a51e0d648b65487c484a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6426671fbdc0cc7e7574024ccf2a0190304af8f0a0f07f28d51e2c76a05943f3085af78f9410bcdb0a6bf7a2a4d685fc59fbe705873c699824ff055b477fce367d4d1911bbcd753c60f2a69ac015ed5c63d371b8fa9a185b376df7e1c8e231870cc05ac244825516e7a2a152e006e7ebb0e8f1d701b8d43c1a5dc45fe487a5f020392c7547c08687acdba70dcfc345af383607727c94425abcb181ac08c41dcb903175c44ed7faa01508a5537ae2989eefdc328e98edb73c29675a1f3341888d7610b02ccd5db79d2cf505187ff1d2121ed619e267b887eca1ab2f98f90054b16453ca6fefc166990f0e48e7b6f877647bd2f4aa2fa573d310051a33476313d07d898020bc6a88b010a263fc954262e88f3cc4f339d14ad0b9eabae62e6142f139c426402053b0809a4089cb9cbbb0b25180406d0ac66ddf708988d36323d48dcdcad64d80214b0d8f9526c4f5cc720953857b4386793d4be6b6999ed19592ef2cf2d1014fd022bd9d1666d9869958c587c210d7425dd408c7b2f1e01fed06926dcb136bf35df032441cb61303184bc29909b87670114b59584bd9326991a6217c0b4fcd50039fe7df799942b05677b334280512134b8793f5a7b06029502f605866a05272da4140d82e35d8cda0f15318f8411bc03e9149db623ce3f3de24d57ea09368f78c04d032bd4e97b7ee48c5dac74d4b520513c5f4846cb972eaba50b347b045781cd260e3d8cab6641cbd97f36e77c07c624c6edc35d3ca7dda0ee644d74129a34e8ee6af8dd0952b523f16f22129a9b23e399a5f5abd10ec5fecaabf9cbc43b4f6bd9e4fb58b5be9f83b712c2c0b164376ec6b621d83e151c2f8aad1e41a838e7f0c300c003f04aec6f997a44fe25c7b09d40162e1801f52a1e39c39eb4398a1afd9e0408ef1043a637b4e93dfbb62cf04c3ecedc3ffae87cdfd0a51f4b9ff08580e083648b6bf8e5b5f87a83d3d42a2d182e761c840693009b69f365fe618838a8244c30bf879a48b70d74d562981b41732454875134165a42b1c9717416c0728b3a4023912b49e689ea15c99192e26a6c9a8190b58ce6b65da16956780685552a6e4de4377ea651dc2b15d8a94534b8a4ff104db85e8b9918c38dfe4bca2ee5d0fb27de2de393b6dd41b2c98419e260fe86a24ee645a6cae331e9c361ad15e650b06b77ede7ccb1bae3b26ae483cb9b73acbb7b5a8542d3fbbc49c85936ff655abc5aff1e571df1f4463feb066aad406d18cb4b8f3027418cd1f66d0ff86a8414bb1478ad0a932a43e6a79f2e626d049275b7f048503f831ac9c91dfc929304cbb0c42836e0d5f6b601cb03a16d2523e089d0c3bbf6c79564acf7e7c3879296f6a31ae14c7ac4ccb1f6dd4448587479c25c5e519df1ac0a7283502da032ec657920518e15c5ca74359d730c21acd05380325978ecf9be4763c0755e917a994f37206c321c7b5e7fd26dc5a2a299b338cc21cae30dbdf2f6fb63ec4c77bdc13eee091609d6ef1bd5452a56d219607b4b6cc791523124008a49f485f4f010ebe6d0eed8df7f64afac38e562bf4a43e56497e8d94875a4b75c85e0a17570f9b82fafd24e84800b9b1be41f9641b9de445a24be4f3d115c9f7ef951b89e055af9966b60b584b03415c8bd498ee2b8b6c0efca3f00d1dca764a5f4abd707cadcf088eac6890f00a72480038834164acc3311157b4dd593e17c9d3f899183d33fe3bf4693f41b31f2cbbebdce2446eb83aad31ee6d1425ef681f21b1d69b96bae61b2965d049996efe5dbda9f803053265a948f8d6619b802ef4609b9738af3153e641c55f095d209afc445f201daaf6c21d5623fd88b00800ef87e96ac60bacf8a98c08d25452e2b88d35e2e3fb8259ff72eccd1a26854f3df264f61261da3cb190888c8e2e29bf198bfed65c799167ff8f6f34a888cc62376a33b22641d93d0bfed5a91a219e47e22ddc1e77526f3d2d1db179436b60e85449619072220fc3a428ac4e6c5e63f371fe75f52eda574382adcb48a2d1443300dc77680e680ac74d497c86ba44f0ffb8a83de8b7a72a0aa785c45de8b14460ddb218bb1db40fd2fd59b62eaa3c27f767132aece33afffe00c4e80721530bdc3db7f3441eb11388e7a43c004e91ddf5898cfefdc3375afd943790aae86c6b9de7e16baf15772760a80ebc97ed71c7837333da10ef9d2a336f79ad2838ed1b9a3479ae0de214a3ea3ea05e43245589e3d947fd31c072a8c21e01bd2cf7dd0ac84151a9d48a2d1039ffcd90659f348424cf94ab50f902e933d4985e73cb9e800000000000000006a39fc01000000002dd906d212b4afc4a86773d5a7f08a37042bbea43c11cb6916bfe703692183a17341268dca74cd1254fb5b8fea7832dd26d68885a25f48cac04474782d7058fd637b12d963e80f7ca137a6c5a78d14d620dc583dc02e9e5d8a59aa05eb3f4498000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f5bfccb93a65bd348cef41740781f9f7c88593c3f9b252a4604446af913c8c12af99ba238b902cc764cf8d8bba40403f3260325646c900714503cfc668e99b059e454f8bd3421b29a23af7f3c57e205bff6417fb967d53ab154e637e8c2343ed856ca3e6e88f446b20b525597baa25cbbf50fffa00d620ae243a6de7716e5b502138c6e33ca5b093aa2c967d9e8092c827f80273f9a6d7b1dc612577fe17b238003171b8a842b5fdca1fce0a2cfdfed09d54f47945896f03db8c0df9e67bc5a925d0a0798f710a1b581dd884f3c66cd221f513d1d9688ae87d2310d7774301b55a292b89581a9a8e0411f20eb115ef4cf4e40e2c46d615cf49deb32c36b2c53fd431e0322c69441c78de594f1aaf4ce3c5ae20e863702867b8bd0da0ba33cb4fc4fac610206d175541dba7edf730db99cb6b1e9097e429d8748b2de53e89efb6d1e3f140d031e0392c076c5bb7508322028e8e2000e10ae0b855fb730fdf87e53168b2a85a5020a35cc2fbdac21df5f6485d4148666e7d1cdf74885e7d0a0af8c8d229e580ec703155ace6a9e0a36bb0e456c971c169c073d3dfaf8833a04aaba57507af64a25d519ee1cb72e4c0148088569b6cb91abf22d5beea3df961c7e5b792dede5201d25b0e01eaf1ddbfc8c5a6094b5e056d8bafed906a33369497fbdfcc4687c15ad9498b203f742fbe86edd07804b353f7c665076367e4416c8d7f2f91a77ef524925ce59cca151198b20adbd08e99a94eedaa617ec3cd39b1e6463a16fe078405b535b06034cc97f2c4a36f144d9e268249a9cf41028ccfc8a9e71ab207104923ea5411bcb51cb143ff3626da14a56fa053072cefd5fbd23962f205f13b353b0a2a1e02618b588ac0ee388df86d923b8a0cb405a3b6042952d0c92e43bb121a5b1e2d23a0feee97167ca5684e3d1066100308eaae217dbeb96be49f274543f3a4e80c11cdef64997c4554826266fbac3a241f007621733c004496251e670406261ad8ee2950bcc9471901c09dbf4212a0ca2196a66eec83cf348d168ca1853f6096d50d31f02b3fc17b5d86a81585bee5e5b6e5eef9b3d98e6c3914b0f4b7b4217d0d9539075dbaa12c69e70141a64b49650aa139ad73e85cb9074ab09cb5a72b4487e707cecc7362a956ca867664ef7937d2fa51f0dba204da6a40cf697e46cd7c93bc096e1f771ec188f75cccf81d8954bb9ae281245cab7a5055edfe258acc103f11c166fd2fe4d2e64022b7960a3c946475a6463b9b2f0a9d7eb64e6b0ff49366ca6f57d3d6a15bf1c86ae10598bd3ed680fce4a4ae025e3f0c3d8ebb69b7bbae3e7dc2fad2c60ba33db74200f162a3a59aec77b0d999ae5957a1c6e9e2ca812b7463040d9966ab6f1c673bcfd71c0536c32705cc6483543a3cc8bc84cc7fcdbbfbbcf17f0f8dc79634be7735609b1f4b2804c5444af57f46132f2ec1a2986aa2d8e440ae909941f883f9f6d97dae0db0fbed1c19d953d427f7c85a91c6e28d4f6a6bc65be4ae14cbe066df66aaf22a399b2823986532850ee1c5f90ff6144c79ce9476fef5a90e05ff57f2b24d94d5ac0bce3ebeed15295053ce0b2506f59e9bfea5e3020bde8a0c45c252e7676b5e28761d8c1a2037f24250f729727d261afdcc3531f49d3958d22af19dffcf76ecad9eef9edb0b3918622e8f0a28651bbb7fc493c0d932f7161df7ea9cb800ac7daa78f10cf046e1184ae39b4d6fab545d34b4950b5a73c52bf2317846c2252d755a36ad3c1eb7c4f31cdd40e0cc5600fa67c72467009bc8445250a49892e73f364f1fa3fe40470548b3930db788495ae615288ff5680ed7aae5e71f1a5528134ad026ce44b6d4e40d56c02fe56c83a7e5c5cc679b9d7561e19fead06dd16cc0ea5c780a58cb5ce0677a86f4fb8312f9a78160cb9d287bf55994dbd8a889ac10708345adf1e6219815a17ad5eac1681322ba8df92af323567212830a5e673170c8ff832880cb896b2867f11f5a32c56899c01f603fd1093b784f2f1234005fb71b41a09ea1530db0477d5fe1b6f2f6279b36e23543a4ceacf369ab8fa92381c66c379bd9d030dc9bd5255b6f1482fca2030b4d2b2131e66775014d4ad49625ab9e6cbe71f1df06e863361176faa9d4f438b224739537a97c949f61a609ed180855becb7e1595947e57d6b1cb259cc1ad2e06df00ab615217938d00a54f2ee34d0590f81f2cb823eacccc43fb20d5587ede7bf55f18be4ee9026d480028150a7c3aaccc333bcb8209832b719d939d907f95f00d6ac0e19865e0342cd25420de94e86ddc90000000000000000724378050000000022c6639c9e02435b2b88c5036d31f6fe61b3403be737bc7b98373e84d31bda38126f20b76986ab6f36a7a92de172f61e50e16ff7efaa87c252f5837c46ed7e8355d5422a21c6aefa826903059c8564e3ef4f65180ed49b85b0a699c4eeefd3d400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f156242ef060d01d40d397348d4cd7229ae0287f670aa38a648e264bacdf39b1eae11aa51e918bf061827b042763edf6394f9d6b862db8bafd98cc31011def0a40e7e0243d53a796022e8882698d6f3c28035551c844a5fe2cabf96c090d36de89395a3ef9357376014602915a7a52cd0288d05f0803741aad63fd84fb9b6b8d0217e8ba28b053210c6b586d015eb495fa9ad6ffd6f4adfc599b10b3e28547e89a02234368a2330d46c4df89ebdf340ca2c94e2bf9201375b17092e2c343cd53d2240b013f71edd8b502136c04de4b1106a6badd4ba561a8914d4ecc5091e4ed6aa9f0843d162c02ccd3cd57d0daf276e487439b433e51955fd9b0590366f09aaacfdd02294c980b55379fd5abec3b3615fd9b552643c16ae28c23a61017f77791526061031baa25eb7aa9b551e4be4adcdd16083920d2abd9a86226260a494a4e1dd4041d031ddea1888c08f31003bcd9aa174cfc0ba20a4a8abbd7b5d86b69070ee4d132b20300e44d7a99f2e5fa6f3989cac39cb365548f9a1ed653c9a525c7b29ee0623774022efe3960e8e791df35e46a2542c76a3f196e2154061151fb4dd19f759759275076be619aa304a89feb93c7bbf0004e1bd387820edfdd779f51ad399e039c63daef654e57db196a105d730b6028a264e1a7bff2c91d00e13fd57c94daaed94251acd0a169b4ade5ff89dd58bc2609d17d94be82d3299165a85cc23c82d5e5bcd285eff0bf3f5cf47a84c804b87df7fccf1dca280d48c5f29964bc6c7c3ed7a0c75adc545bf99af39f10eb68c1486e910a54e2a10a704ac0021d5925e6b8127bdd444e02dfacb77cd2ea24e1a8e8fd8ac4d845af1f3f88c1cefe8e800fcf0d5da7f07da3d241c36668b07aecdce4c6c6b3532f2216124fc6531251a656fcc8b7bd5f1edb93722e9ecc85c3c7fbcebdfda0f013e2a541863c173116e5cf70d81cd5463e448d41167f859bbfe1cbfa592fbff260e364f9180d48b4aaf02d77ed13447c89c89edc8432a63bf1b78877fac5ce4bcfc9db674bddefe3cb3a88f5ff3113bd4ad8f57f3002d406ec4d96512d747a3d9cda127b338aa4354ef7ab4090ce37b074208138d81f70f96acb3702132daa016eef96526bc01ef4d22349275e2b41bc6a4826aa3e4778aa5cf11291dbf8dc593514dd6a016d9c7571e43ef9faeee1eff6c5a516a003e8e72cf55320d93f784335735bfd5d13c2d23e440714169c684f86a1d40628301d40ffe7fd0936384c2bd23d80b59b880dcda3639ff29694ef480fc8559d8af735177f41eafa0836b92bd122a49363f45632c9d2dd8c809f263cb8eefadeb8a99c69fe22912b70205dd341092b81a17083dfab257d42963655172de0ca380e79aa5c1acc2ae9ab0eb4eb126efbd31da6fd01f4a0520ccadda09ff7802057870b0642d037a2888f60d98c2aa5cbd9d758f15ba2f96e72ad3e417edf8ad3f675ef06adaf2db90297c74ff7b33625dd3d3896b3ab8aebc77626fcef2a41874211596a795c21295bb8af2d2860f1145f27133edc86a1352ef53a0aa1ec0a9743a19ce9ea5a16540bb98ef9f466d19dfa00b07f17fd01664030f633103c294684c15681563f2c50cdd035df838aee80709740c1e81fe32846a50885aa88945c738b5886aefb1dbd6021cdcac6f6bcbdd8e3ece8286a9971e7f4f115f5288f086247e408470191c01d4aa14ab2d7658ff2651132572b06c19c7460bc5379db2b144ccae40d8d610e3aa32dbc30359d46465426e007b7214663ef8311e6fce64f38284e357b250c3253b72e6460879b836c01b6308ad88c0b28fc9517403f3520765a7ae202a388f07f69e7eb926fbb6c217069a04d1a8a80230de0efc8f39678e2a6bc578ebc40fc4fe17b1804757abccd75ba2c24668c5e7dc4379c6209e3d35cd3a171fbca87e50270857346ddc236cd65b50a2db0b2d458c2524e67521f97ed215f5efd8d41f5834ff709466d8b7a05e8be3f5e5a2c0c94a6e957b887e0cceda8e4b4ec1bd94a5c9fd806e6a1dde5c9e2db822b4a03cb1da8a080f23dd55ac72f1e76e414e7c4171797187ddd252640c430723a2654b2bfe1e82d529283fac038bb26c8002f089fc1ef52e6299f385023b6fd066a4645caafc9e46cf343619c434115d20759ad5885357a550279d72a191ca49a993c8f390ee1f7b74bb9f47ecd9532ebaba1320f6da12ffd1d2cbe5823f8e4db2d76cf5cea220e555758d75d49e2d73a73664f2cb359ef9c9731515224fbccbaed10f91e4ea57249482a0e09a99479a1f6e83887e525d6c9d0cd7bc9bf6a4e1e0aa4772196366b98c81f6affa2442935076a7a44def4706173c0ebc75d51fee0202c860afb25e51d7aa291fe8e374b19df9d4b41a3a62b03e079593746c79779cee8f86665c87c5c30c736a77a57daeeb02e641bfcb165f001", "6a5152", 1, -46403995, 0, "45fcd405fc2c872663e0b5c7d2ac5b5ef472d6fafb309f36650a01b7f565019e"], + ["e53ab34a03456d762d7225bcb529167e2dc8f76c4968146907364e7e7a8930abf9198257820200000003636a639c6d45139c4538811e4a40e46eeed756e59539c3fa3b662f135398026334c4d47d91d63b0000000008655353525365516ac9fb6986fa59a157096c988afa052624fcff585a2dcd3980635d9846b1e5797a791b17380300000007ac00ac5265ac6a48fce04802f0a9d605000000000452535363203b03040000000009000052ac65650000650000000000", "535351535152ac0000", 1, 1344936635, 1537743641, "58c4bf4148b33f1516604c625dedaff54eebb087e236bb8d3de05244a68d8119"], + ["030000807082c403037ccfedf0dd7f3fd5b346443ccde2d27fd51760f98f2e7f7b74e6bea7314dae620000000000ffffffff2e0a532e9870d210aac6026d34a340f70f2e59c4e663d1e5482f54b01519216f000000000042a9bee852e4b9650540c812d5ce3ec6678432c313f1f14991afcfd293bc1c9d81c0fca60200000009516363006363525253ffffffff014335fd030000000008656a63516a655251000000000000000003c75d26030000000000000000000000001179becba7097ff91cc2966df45b52b3bb73810c459fbc96a6f63741a3b92113549b9d685c6845656803897243afe9921e4e56fd795a6477d2c1338fd10f3d5b872ba20978770edff1d7adb26055b3d8e38e6cebab69bd8011f43180e2de17fa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017cab231ddfef76bc1320cb9122abb7ee14aaa968b507503a2b07dbd5e04ce6895017530d8e8ede9aa8eb58939f21189678013f8713d7844eb8fb7c329565f00306bf0f9e3da3bcb484a040db7517e4fd96db322d06ac0956883f2faa532b87a4cacf5a759b5a8b8cbe5812b864adb23342895788b0c7115fe8552b280ceea81020713c5254c453343a147052457e44cdb2ee0cc9c5aaf9cf2f43bd6f7cb8ab7c30226d70c43a5479b899e580b59b34092782aeb6fa8976abbba93de4d998975c1a10a016403f3981ee50595b695cc8005383a26363baedd8dc06e7cf2eea8898e2d0c7588674f070b690cb89f3e21afe3eeb5f0113cb736767c28cf85f10ce9425c16031dc240021d72e54abaef8acb6a15cefd1539fdb281cd04c7d9a822e5baca0989032d2d3e74c1061de728d1794ee1e7c18dbdf3142edbbad18d0b15269a1a57df1c031479749b669785889aad0e01c1eb987cacd1cb8a346a7545b363f143d84ee84e021bc1b659e70e2799cd16399013ca7eb952ee422d431c104ee9dda258b39fc9180210bb13c449339bc95f72f6c18a527c97190b4aad38381774f73d425b9e469d7793cedc862ee15b7e67281d6ac9fdd8a7d25a0f21ff4e7e703ecf0d31bbfd0827c5efcddffe049f5c2d7c8049819687805448540214008eccf59ab653de30e9388712ba2f42f747b4791067b499a460424fe4c61518212313c642cd6c5e401b24e545a71d66fc14f058f0f2b4ad165cb7dd3c5209e42dba34a4a4e09e1be20b5cbd29be4b47e7759275c637e08b072bf3c58996e14770f515b3cbee3cab9677a7e1c7d233ff757203161bcb8b0a27a7628925bebfe6abb19514a56900908d32ebf966d74780409bda50342ed08bb9cc2a0dcbb53bcda1991a276d9ae472a7fa0b319efd7781d7b869d6f51fb996c42519ae6904411971189e2bc92f3436a7d915822f0bf85032442dc9fe96bc229d8017ba90419084c662cec99777a032bf097236126a28b6a77dbc629277eeba814946c6767c98d3080b02b3181efc3337ac38b9839393566720ca2ebd32a7f252f73f6301af65cdc19001922c6fc0192b61c598f6b867320f3b1abb8f36dd73d1264c9e2b0eaeed94533c7b2e243ca8dffa30d8632cc9cce88f45644f2c8f17e2719d2ea0299177857599fe57bcb0ef963ea1c0c6c2f4e138cf0a1bfab75d41d4c98b4411bf25de34013384880e1d19401fd64fb41b229c14fbb15125b0548dc611307e4794924b29f995aff765da09ab3dc43f0346a95eeaa4ca7f219fc48877c85c69f53739109daf2cb0c584ea1f8973bad2c1a73ee5b54dbe92495974b6a1514af367ffe1815d65894262912e090ce092e9a6bbe5b4e3356dd4298f04c01c99ca759b0d0755efa2bf9bd9a01c360f04b6b54863e7eefef3bddda6baad1cd9d28c097fe282c750e46c50602226cbc7c3d21a459d824ac4a8f0ce07af09abe03bd6f21da0e02a84626300d2da13792523209855e0248ad47d9f80c198c3bc74b26510c0b138f9fc3ae81212356a962b23d45c31aa064aea0986699ae038250500077d930e67917e480d2038be5d0da19fb57698d5f28b144a24342f2990d2be26d970caa51fa7a7df7ee15681bd8e9fce7889762e8eed338b178ea739c4b731ed7a9fd43f61626e8cd63cd0a02a29ac3c930a0355efc7c02e0170068556593b44fbfc80f1ae8dde80b155c73e65e5d601ffc61f95f2960c9aa1e4201b7305f6f4f951382ee4f302e21da647f4d0a7f531682917e39e9bc4ac1b194504660bc3ecdb57a03b19bf8e58287540a01f1cc954291fd7231b5b8b071e4ca7dbf124d2a7f52a0f0e9266780f9e45be5c28fc2e9b09bb6001cf9d498a4b3e739663f8741e1c5363dcb947a60527daa290f169479132467fd52169bf172656aa2d0737a1df5c6a78924bd8a662c37610b7b3cf299136fa782e27ba81da9b5a10aec4112cd7e492d8056fe76195cd39237bc424f25ccb7de8cb9085838fd51e73386e2439e1560cbd1d818f84c23375da504b314638bca55e59ef04e516ae9dc23e406836d80a1b63edb30c991f3f54378e4105dd88a458db6c35a4b0372dd8ad1715799acf807f8339c0835c18d476749b2bb1eb94ad8559a97ea82e029a09d33695c5272ae699c1957986a43b2d2aff69ebab4488bfe7c8dd67012ff7ef4f825309c9fe267697041f192b86de3ab2b7d52bcf4c2aef72c91a4100bfa1f7a57b67059edc2c7be17808aea10e3eee4bb536e199b1abe8725a5cf25a788793fe02543ddf959ab7c7530000000000000000ec5c6904000000008dc9ce6a7c7209476dc3660584b50416826c96ed54a6322babd4ae2f34bd3f141601b1735d6329ed6dc2d27abe5d1b3c587a7759c92d8bb2eb3d52eec88774a48094d4b999e1b6020994464b3f0e9d00481f7fa356759d3fec1a082fba8fb3ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000155c701a4f301735f4278a43028c1037d15ea391fb2fa6978dafe8c87e0660a5863616f000987cbf4614c72da25575a560e4aaaef195fd1c35dfb9ada85f5231b1a35914cff8e515a591c994dce883096b0ae225db3f00080555a534dd3b257d042105258d29f40cf9c86ead7a6f7559f4550dc4adb65d7857bbafd1debf46bb020a2ac1a2671f2987cb9ca4de927d6a8b03ee51229aa81df4ecceac1862fc6309032ec79325abba864e1cc95ee2931a93c962f03debde9942dcc64f66a5527be4f70a04da76ae073484e5175372d71b75ed99489ea64ff7244c2957de33f5a948935bcc6dac197fd10ae2d1fb2473b4768b7f62bb922ac0465b7dabb56ab727b37ab5022ba2b6c5686e52bdf79d562cd9449abae8dcb5790941205cc11cc41f2feb815d021447f662ca024da127bb41a175a8f14551cf881c3f84fa90888a079d923066ab021e1460ed4e3c619bd6676a2bfa1de078416c0572bf0ec53283c5c0afa02710e6022ec46d5aeeaf96b3233874801515244fcac47837d531daa9a2e146e9a7075ee80220ed17f0c0b828839169668740fc0a11dd057ff5e1c5b98b384eee0a5cf385b2edba4e59b19ec88e1b2b627fe79a4d7e08127881008aea1d84baf8b8b024a0fe51cbc91fc8a22b50f393f46a55b032e94975f9c2adb00fa45403a6807dd60f76e4b20f5303dc19d7254340ee7f27df19b953663b6aba901862572a23893f639e0df3a2b5309c39ef4f3d74cf5a6e43681214f1e2daf3b7cc99aad453b5a9bc3e351f3e05939f0e5c1b818f5d1522a1b4995c6e973243d545b83f046c8a98306200780ab55f2e5a096436cc1bac86bb247cdafba83f5c2cf715cab3eb6c75d827e015225bc9e3516e59b1f474591e29dd8f363b2a5110b61d61ac5fc8d0d8d0e0aa303ed6405bd7e87d649f58622fa2661ff8a12266d38d7ffb4ae86a6bc8c88fa19be09d82eb532008d9fbfe71e4ab6b4d13dee47c9cd66c1c530bb2ebcba0dbb5955cec08945a8b2cf2dd2ef6cdca563fad1f479b9c2ecfb0323bf8eba211302c96af8cc2b9132e08e45a36fafa0463cb75430303b2a12a046165af395c2bbce26e377867c8a8910c823ae085b166f1bcaa5054b9792b510e7fda995ca18739bdb6e2b273653abb1abf1114c9526f400287482fee8350865b6fdac1cce54d2da5fd2019af6d9734568ede1d06927083e1282f90c2abaa3d3047bd1cbec583da15ac40ae6552be6fd8ffee7062a95fe39913d62e1459979fbc41a253930950629e0598417dd8ae47cecccd4feae4cf4035c97656f6e52c9003d3ba8d612056e13cad0a87673683889601d4f5f8c90a1282d13b69252f48402ce0fa21cc16271c1f5a7de6a4cf3098de11a68b85a7327be93ba8591f8f02feb2bd8be9bdd3b3afe26798f57abf5d8521d9fa4d79b67d6f74c1af28d00ef28efa0d8cb39e0f6eb8e774d1a1b28284130e6c244f65946accfe60edf19b057ac4f0588465c2f3bd9eee4706a59bbfaba62a1eec0bb033a4b2099409fb5763c6d3b4e8038334413bed4453dd27f8cb59b603a95621bd14b319f1405e22514f36a1a46310ac7b71d3c227e243634748248c657469be8745d920ea8d3a9e527a51ac94c718216af02686360dbd5254f5b4f309069f3723e4b264dfabb548ecc14b865846f180950e09aae7e5c332965d3ccba65d7a060e8e1e782242a7554d0a443bedc746647cdbdc0cd4113dfa4d9d07da310e117097f4366eedb48694a7d128004c4cf643265c7625f6726c61aca65447577e5c261d6d04257d5edd42652dfcd1c642b69abdb16b338e69779b16f7872273ae2f4005807529ae819cc8486f68ebd05e8116ddbc385f5917c28cec34d2b024950b08189a290f8afecc33c9724c1bc845f6077252aa0d6208b5657a1b2a2e4f54aa41401aca67e126de307214d27837eac7d0e8db33279d7b8049b50e877d66462cc1022c1c65ab9e8efb700eabddbc2ff2c2d9429137972f4258195db4f1f01db4eeb871be4cdbb2f0333975f8c2172db3e5026904516dd65d1f4262493e35cd0a775a853cfbae085fa81b1445908753ea94a62b9e4d86ebe19edde9c82d9f82a2bb93d1e70ab88a1622ddd3dde66fc4306bae557e6c5a5356890ff823ea5d5c2a22b497daf941d66fe21a79b26a4d660708a0c66c6a1dcdcec3c6b1a8d17e408e53bbcf84a1b77ed8a6f021e074924fcb69ad4af7654cb77d2aa6b26f096e11c74c867bfc9638509c413f02c3d02288e9a5b5b2999bb539db5651f4265c6d7b994bdbafb7d34b910000000000000000392cb204000000006526d522dcc14e8e725178939efd6e65684a71f144b63c2dde1b12cfe8716dcccaea06d18939bdc123e822aa9a56f905f3011b7154f123e41a9271644b914574f78597045b2d6f5c521f8000abc2c153d68dddc8501cb684ef372951c16e778f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6253d2fa882bdd23477f3040107ad029d0dab5f3009e9591876239bc83191e1cf72ddcd27826b3dc438b3478ce60d05e7551fdaec8e290d02d87f0611e2d5811f7deb7cf58e5e2981710af2d8fc8cf58dfa13ff1821783e2c0345900dc58c550978476209bdc3022cd3e45943d27c2af28d613efd4a6700653bb82f8023242c0314e9b6ce2940b732c1b0e6ae83d4db5207a14cb4d743e7ed10d19c92f909c175022ea3331ce17cbe8a7ffbf702c9672752fefbe24248b9cd44588e4997e713f9920a072fbc818fd3b8b290a8de7c65a23f9979023f3d7cb6f478540d54c9f709112d853f2d876a04a0931bb54d8c94b7a6d5367434c05ef0057ace5a77e39f3b63a80223e63ef35e8b81dc3cc1915d9ebae03bd16d84a559aaa91a33f30e370414ae2e031ecb084192c5128d527ac39831d895d5f336d07c34e1f0ba5243b94aa2cdea52020283a545daeeba9ac0acf612008604bd986183c2b04ebe87501354220a118b23032631d377d0e5bf229e654ebc8bca099d7209f9b87c98ab5895486f25144fd6a60303480e9f3cf71d9c02566e6f1634793ae6a1ff615089845192356d202a0b5bfa85b16550c54b42bcc56606e53e72bfbc763eea536120132402a649375c46869ec5cb849810afffcea3a457a5227b3082e9b4dbc6c933e89dede4c8833cff188f9f9690417670361a93172801f0289a11be6eab3b9454e1f7e73a290c0c111caaece8dd47e95dfb81a4699a895e737af0f72e466c1f4481c48e4ccf3d2e28ad454ee77193fa9ccfd3fd2260d00113316974af607f01072c6428e1255c1a8ded3a51e40eccbce7b28e10de8202cfa5c32fd4875df2e9bb56fe8ca39d4cf3a4e0ab64cda4a1c6b604256f38ed300e978f0e4889819b606b8925e3975a6278046d3720f93ee6e5762ea44ede50ead00931e64d5cc9922245cb082b827821406fe4f9cbad2c7fb1f2f30ea69907ff7748b990dee5ed0b23b8b40b0055c9122da1ee3d1aed1493d7ded08115a31dc4469b0ad1731547e4a92cc071535e07855f5f0fcad1430efde31f64aa7d30cb2e16846f6633ffdfc7266157bdaab56ef198f2138b4234c6cdc855646a4933b51a16f17555598b1122184ff59f3c190dcd2fcb870c314b632dd766ac40526037907bd1fb720b5b96bb1e6c91cd7543d22246f529cbdef72708ee80633111d858cacf83c2133f60602f290e9c3dd5530c3e4ab116e9281dbe98370af9b65f2af1b14011707c823179f6990b3a4f0b5a755d86c9d78c5ec8ddb31f7489872b4f234968fcc514d97d4cf4ec6cd917495d7869ce9fab98bcc6a831af66b1354869e83663a0bdfcb69a1a4a054cb2e7d86fd042ff54e33e53c806617f74bef4f201c01fdc2fd29afcf35cb7c7171fac742f41e3285403a59171e091f2d28f95b76bb90ccc1681c3cbe982e7ae90f5a3034cac082a59073927288efccff18be379b7fc8a711897e5b317f3883e80214075c2ebbcf755fd359a90a4e667ef03a7aa58a1533d3ac95444b747ef376cac42434940634c135d6eb390b54b5dfb0c70ebefd06396c43279aa775a412b974c236b56fcea7809be372f3c817b7587eb0e2c9e5f2af4e51548169916e418d24882904b2d3a71b12ad30eff89b2404269a3076693e3f8889357bbd7877b5619dd7d1027e9d4bbd9f643431d7a419322ed179f786a38af1afd755a220e4cd197fe9e91ca716f9061414c4cdef91620b8e48e7ddfeaefd3abbe27abefe41fe17e0464d7d35b9f219cd0ccab70fc26e4e60df95b8d2d16b09d4d7bbac812092b39343fc89c8707105631f12a6f48ef731d61062895329567a973a07606cc42b7b8ca4ef4038a33c3f43468734f7ed55980183b36cc9e8c4dec09e3ab32da497b661c7c2d6ea9cc860adb4e5c5b41cdb6dd11835766211e7d5fc06643c5a64668ca088bc4ca55eb25f87160ee8bc246d7593931a9e81d961de915a4cb5fcd7de1562fc7df26597a3b6028c101e522b190d6fa5af055f81d17900e634c7e268808fcc8ec7700fe6f87f6abdc99da0f193839e8a48b06f57940e314e5d8945d48122c188d446e61602e161843225a9ebf662af7a27357a8cc4b836d6cfddb35444b57f4aa739f07ac9e949e42f61b0d0d29ef20cfa2f9c5931b29cbd00d7ee3e3aa55fb8e6d8a979a1c87961bacdb83d7fde24a40e89f7f5a4aad8f5aeaa43a599718c5cd2047d0d96f1a781f9906d59fe2fc7363fc5607f89cc795c33cdf50da0dbbbad6e19346c1898825e86265b5d9c6e68f628c139932fa0f7fcab9e820e9ee297faa8d2eba204caa512d0f2d18e322e5273526bc8beed249dc539d4b70a0b9b72e5154848c5609025faa63c1529e13fd5bb6cdd6bfc227cc077bd3a762f9632dfaa4c12e6a856faeaff5027336b0be9669d9558d0479105362c03e0c", "00006351ac005363", 2, -823594623, 1537743641, "b846743c2666e949ae83e46706e87fa287de0f7d6ece56c2ebdf3e516e35ed70"], + ["030000807082c4030195db4efcac8258532c868926590224f6b8defbeee6a2ef60ebf751e4aa8789c902000000036563acf4b3754c042342750200000000006354820000000000036aac63e82d1f03000000000400ac5363dd7340050000000006ac51536351ac5e21c4dbce73ef300300000000000000008e25b90300000000166640231cb668153ff6e4285ca4fd045c1cc5edfb694a83a650e6dd734163a4fa163fdcf171daa0a9dc0af3ee4877ca20aa2de1563c799e318ff740847dca83b096f1d95f1b6274dfe1f0abf26d5cee063b220edce05c6f747a99a54612665f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000119cf472dac6ef911052dc7234e0e3b5aeeda4289aa458a61fde596caf7cfb644ec87ae2cd7434c511b23dc789dde6ff5b410a7ce58caee0e8bab5c5ff574a69da0e8570cab5dce749882a507528919807a1a62282b753500fadf7c7271e856421b66a8d2727c7c17389a4c9c41731deb7f005ebb1079d68b73e7562afc8a99603243baf8873ec44dee694bb21e6b9dc092b7e22ed077e483484bf4f7aae10d2c202265c309bc36e7f6fa462dc3dd11dec025f1c97ef445468b62edcf8f1d25e7f700a0205bd857b28e9fb8873ea053b9353da37991b2871d9b7adf798076a98e60f75639fbbad5ca9e4a9b843bd5776ad19d05ff32119d2dae63f5eff5181651b3ec50212db8301ef0673c652b44f92ccc299191f828fd8c64c4e6874db5feebc13bde303231dfd6aa6990791f7eeb8e0c5daa0160639d27945345ff1dec2b6f49a2bbe5f0323053576887dbc2e78e0fe472f9f8797a114920a644567546ab29f05e683153c031c49d8bbea3e436af5cbcaab3e864ad78568166e0384419aebcd6a0e3ac537540328ac9e23031cf729172bc104eb410fab665a6f36cb89c038c2ac9f42d47da9d5bef55a2461caec56027393c4f292c903c8dc902732e10253175fead36cc74a20e172a936c203955eff13028ebcbf55e78ce7122f6fa07f03c303983e576bd99dcc91aab5411219bb50d7547dd30e00b28d74dc51e9b6f3dcac70d01a80e36f5c231c84cfe45a121baa048163ada69c03cdead62e3d58cc3b571fb20c84e293e7bf2b0060b691eb4800752623ddcd4bdd54ace47b0a8727b458d4eab42bd61078fba9538e80338a0a33c189be13f3be47fbeb1d5e6cc7b56e4137e93d041b317a022fe8215eddfba11e2014f134490b5a1437b92c91d2f605890e356b5c3b50c4cdf5a43aacbf833fed008302cf5a025c3774c963244261edbc60d7c46c806a248904e218e3be00165596c71c29d73f47b84038cb9ec47cbbf8c7b30a5d45062ef15905b07d4535d0726bab4717c4036551d286960455650cbcfdded70d406c3d77007273e75f8dcb5961ba941885da851c911be95b3b1b34fb247bcb7ef5349c924bbf2e1e16eca7ec198ecfbbe7373bd71167b4b5c4010a2414cecd46e36c228af47b587e793b4a9e32749ff94cc36995d5eb4a34e2e64177ac7e39bbeb9ec9a5f4c2bf9572dd476996bc8a9fc050349881bbaf1dd1c16c8093f88fc30e2abe8e24a95302b69cfe2ef246b2e0029ff71f240611b6bce0ee91385bc29acbbce7d3b6556e6c200f97cd95ff87a6ee6c6c70f5191f9f4156d4559f7f32128d233eefb0e21088eb4a7b3ce1761e05af58287ad67e1753fe7f2222d77c040cb8167bf5abfc58e1d4f6858f9653a0193dcec4b30553cebc636fc90757e4d5d8853456bb494fcb7308aa0a535aaa2e2bf5ed8ee6cb380f2fb3211f979fd25f5ab62225f793219d3c0cccb0d72b821a66bb289fddd2028f2bfbb461966c2064cb1050116b46396cbca668b21288c5c3c8e02c3fa8b5455ebedcb884367e8a759f0cffbae4022fe7a5ea32f486fd94f5098b849952afcfbd0b72d86e0cc3add5a344bfc39f7ec0a551f9d2af8f4a3108fa6d6d00746a62b4dbf23930f376098f381dbb739d059033d34ee714ef6940cf8c2ad17052d80d37083c950d59d9480e59debb734d2314112bbcac64b6c88281ec82d7b706abf72dec4c64bc443566b19ecc65814d9153d10fb8e22d14b7b2c2d39d96ffc54a836c9d85d5783ea2a2d4bd8f9bf641f70905170533a06f865db065b4f565786d80b8410497c1e671e5325e7c6272cc1bc50656196b375f458669755d3b4221b49dbf943545f33566deb998691a9b3551cce845fb34c6a6a422c4b17fba273c9b5d0a79cf941dcf45928194d987d03cf64dd7f7c4e6ba79ad77329ff0cc89bf7cd29cd42b666b4106bb4de28b4a235f4fbc6f249f2a95b17f156accfe76f601e5dd72d63d288fb546f8cf9f65b6307c21e48b010ff70e3003e7ef6226fd3bb357c60c72bca1a03593f2828f5827af74cd656db01347b939217f58ebf4c2045470a1e7d07efcb0924996c359b7086262a33dabd43f7728fd1dffeb6ae2d504c91c4ba56cec1e7cb32b83df8d9a6d90619978456a4961af12c82648aee127542b5b22511906e9eeaee7dd38220ed31a9135569acf7fe8cca949c09bb0ef5cd1408e1a4010d73a959ed2ae757df531d17df6fe7c829be6cf63a236f2217f38e6d95d7be759538dcd4cf2a0e1cdeb996784fd6c0771cc2d08b596c09f20ab646d06009acd110300000000000000000000000080df0912779f830a655773c3db093073b6380cb045db9ada941399873dcc1a938011bf997bfff4e08600dd347bee60df377ed55fa8813a17fb57de0bfd1b021fb866a69e19213da85f1956d6c2e094bf4bcfc0faca5a94f5e8c774f3c7e39d5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ed63398ed48dd2de12869ecbcd6533cadabeba66c06dc71ea4d0771b8242206ddf70d6ef9b3b44fdefe814a83f37578d2a92fe9c2b508ee77ded68ad132245d3b08665280be5577354fbf91cfe6201aa38c8f196924947ff79b97de273498bab6b0e65117f1f44636c5616baefdfc459176ef7f6c2a55547e304e450f4c71172032acc87e99612eba02f713f7d951a739d90b08168ce08c0153b4e78375da675a40326d990fb635a2eaad2ec9c1429df7c84d443909949cb9188699b86b92ecc65930a030d378bcd8daf871679211bff39cfc7d671f43809ca61b91ab08799d24b582a107f8ddc0b90753b2e23336be502c662579aab46f34df3b05f4933cab2439a490213002109fa84afaa4a5445cbaee9e05e093efff3c748968eee9bdd8c87b88725031d7653bc14ae09ee29c63c451cd23c6bd9583d487df5ad5c250d747515ea78b30312c736fe5319227c25533f45434d0206050ec18a2275939ebc06e518f7c8888102293ba4060ce7104273195cfcbdad0c32f08e9dccfc70f111440df0de9afaa3bc02170d708c7a9e0a96513ea38bcc8942acc7903523245c75d6f3db413cd6d8d35fe09cb47820f39e2c78f9dec91c18fc00a7195c81e8459fcca97efd7b4d51fe95236e0132410f7004ad5a865d27f21834839c5ef2d37704826ed3d7c14347b122be8df44a1898e763c693a8ea171a884229a22b0639fe0752f6faa553c2264ae2f63a914264ed6fda13404de0dd6b871ac9fc44411d90a536c01e04189ef44967c243b2954017faa3ad6a003d87c41475463977631eb9886996976302d2273e61d273414c9b0aa3aab1b176ad8e59bf2d1373deafba6c50ff3ba7043d8fcf9aedee395ce0c6c1e3b43467027de86605f140d692ce8b500d00edf9548c505d91593ebed199054977f2dc047490e07b4af56fe1fcf0e16c3abe56fd858902318380b61e63a6cc144270c8e0383c87d1c9e847ba4c8b00e169d25c18c6721b976bf5ea905521700b3fe454e4660908d4069dad07e1af1ba3ef3e74d0fc567bf3c808d96c4f0b8325b13f9b7a9faf2aff5c108f2755a6dd5bff28a9298f0098a17f824f536127cb8879ebc9ac7197c1767b24d5a4e10134664538d0f9d5da89cc895e4518f0f84526e33ed098b310f9a9d28383c1c7ec9b804a42bafae5163ca4e426debb10e7044933bf95680318bf5f87d77ddeb9b8b4a34455d738023e5e326b112b29b0b96e7684e21ffb7ee7941e276dfafcfdcfc5ea515cb1e814ca86bcda12f7d1b42b7285ef82ca761329e8d6ca3bd838fcfd01ec7be18a54ba98550e3a901235892791f85d5e146362e7b18c341d43374a035be283c670127d8e42b87713efbf0870a4030101aa8757c0fe03732e7a38c7125c7ad5d1ff780a946dec27119d4c7355714e8b493a21eb58d2155b5036e8e4de879caeff434219fb32cb69e6d64bb3534bd5a290de4f0ab5fc73231e56166725d44d301dbc61bbb066d708ae1075af74b3cd7f36a3f38b8a9a33cb5f487b6d8466ef60d9473924e4d280b0662ab0835684f2ede5e3be3bb7abd2b7c284db3b09d68e8d484b503c59705a0c5d2b7983dbcd51138016c5ad53b971c54f5b7092de4edcb483bbdf5dc974240c2474d8cb12e75fcbf3a85e237add37ec9230b5a56223581e41e6c4ff6c09d0d2b285edaafccb9bc28c76fbb3247872a86f60de2116af2c19291d851181f793971297f0a2217c8e8f93414c043fa85e34d6ebea6ba9d9e0c3f2682dd855643fff55ade89a2f58d43ecec06119c1ae5de0c1c8672c1f3db7d49a42a172bae9626f3cd1e07259cc92fd895d63951fa55aac6395fb5217192876ccabf84ce5d430c509fbcfd7308d653623a7e41ced0af262c5dd42cca2376d9e966503ae64191f09d26583fffefcb460a83e2fcfd384c2ad39a53bf0f37f6e95e00c97cc76f853251fa323972ffc4434cebdd2318407e65607470bd2d63040af5a6ab62a9ff5904a2523e9afe266f97ed7a7020cbf9560988882162a8c5ce5e1cb92c1bf286ff86142388845a5713697f6c86e97390ad53c57d684210468cdaa5fde842470f437f0ebf09c0436c460398d7ad17e330994562601d968ba41bbf413a49eabe43fb343694a5ccb05a999c39e529e4b6896d112e640eea0bb5673cd2ea95fcfca0c96b9621b50d4b8dbc334d815c4aac39434033f4d412c8e41ca1b70088c371c7185a1dec9d8500e1ac37d3d648a675b52b60bb73885117d109df53e943898d86b1c16f0426fb7de4f08c01de52ed0ba2ae6aeba19f900000000000000003887130400000000db48be28a5e70fe46067576c3ec777f377062ce036687ff8c5a43b7588b1a3d84ac9e294ad7a64aef1c7d9a0ea6ce0548de93f88651fa1233cb3894c0503155eb4d466a04134e653491c6c06dcd1cdbe8a433192525376986900b9c99179f81d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057db0e45503feb2d75c2c6c4cdf2e5759a5e32bb54f74fbdc0b98753394b4d5f49a6c3bfa0b53b0f2130d2f7c729383998ae4b90d1360a6cb66a77e4b7d614fd589fe99f79c9f2e5ebc4c222b069f3cb32be799998ebfa2f24753a16a869b679b9f253b71f25cc57a5e18c27c7e37586966dc0c54f7dee1075e66235a901eec032533cd5249e4f511621ed41e4cefc7b91ec9315449cc238c48c5756418b804a0032e445b643ed65614eda0a0822e1aa3fa453dc4531209ef5294e89974c845d1130b00a054eabb9a4079c0cbb56aca0061a92bd2f918b968893fbdea52263d5f638594b0e7e7de851ac7f13e412560593b1bcd737eb0b4053112959ad40ccdfcfd460223d5f2069f8b54b75cf73c6a162aabebaa0b3e02696bd4bdb751a96eec375ec00203eeb71f2d54cb4b73fd0056545adcaec904e1cb570adf31e7b3a20f1679edd4031d431b7a5ac11b8b53b74c50695459a7c7b0af17211c3a7f23c1a547f78169af03130009ca1c3d86b846496d00de3a688442038330b5ac30a19a9e6697c58e8c1c021ab8f83366cc4ba576afbdbdcfd339e669086e58e6d92b7d438a3514a876c1811e2ca7694f6fc07c0319ec9370aed1c926111a969bf1243efccf60c6a3c5a1f4ca5095f389c50054b56e096799926da771eefba8e56757a11335436dffa8261225340cac12e6082a1be2bf1ba6df0109ed77423e803e9d73a79e94eb3bec49e0583efbe46cee12103bbd7c01fbe21b601f02e5844c42f9bb7459c15f00b1e3ea9b7b612753e45657889029c852184a302f842039289f6e2b273bd14e45cd5547d3d342b5db3ce05555706484652f9bcebe3e26f7e6e0792701fb057b123fee49cefd384b09c2be68dd9b3d93b267479b544d6910bf02ed09199632bd5bb4035d60e8cbd3f9e8698f06dce380af0fa4dc3869d8a8c0bbcecde4cd6b6df2b49dceb147dd4209fcbf2719a6aa29256ac966d91f1e37f92b1647ff44aecc022a951c2363f26cb326c0c38b1b7ad78945908caa708571285cca908e57b5c4d3b640f479e0376a29032f55e6564235bc68040ee28f450a6545b9d1969a86ffc40bf615137e31fc9a8f9fde9c1224b24f044f404811fd521b7b7f7a6a886a205139ea03c46864b45583504e9e749c6e2d09a2749068e957bf8ec92417789a6bef16b98a571587d3ea442d28f3ee098eb39de46d21fd572acb30c69374bd272cab66279698f8ff69e6e7dbb3e268a995c34eead10f2ec3e72706a94c9f6d9ebff485c26370c16d16a31c8939f415dda9c8f7b25fabdf9f4a38fec9509b3960fa55276dc374b4a238e0f41e3c8965a002d5d28edb5abd99473d6b44019a2c2f4f6300708e7c2af9f72bddfc259e0f30bac6b50267eb0e4b82529ba2dbfeae90937040b71c65c6a835c5ea0e5b0cd0b2a522109f53036fcc4df00da151bde631c1cd44c4072b5d139c5523ab00361d9aab093956936668cb3032ad36cbf1531c1b6e20211d75709dc0058747a04e1cb1a9563dcc325df6f32b2a9f56999dda86548e8f7f4ccf5f22ed8b4372d6d8a553aef91700a580f34238094905dd853c235a3c5b9d92a9bf569f80b9ea5441b625845eb0da39a44b8283f7343e47dbee056ab318115c423d0a4e8a39c643653a0ca4a423339a6eaccb683c667e709be6d70761ec22ffadb525f92ebb121affc837d5bc004b83c3e820d032e3b7925e58c52c7fdd1d9ec87b9202c96d81d9810e5a1452335a70cb7d2bf10c8dcd14f9888b6b5439e4d97b16d9f93d7b19424bc732f7327cff05b55e46364a33628199a513f6c84f9134ffebd0bec1edfa173589cbdd5176c1bc775f31314f2e860efb853f0aede7f0d91f96ec5a34a22feac15a1be3f877d4e63dfcf951e2e7119438b38acb1b06036526c8774de7729bf66d44b206c4c2e6b84c6748b2ac742651fb793f67502eb95c6336a0d893563ee679727e4646b2c3d1ea269b3e877b5b53f1a3edee391f1cbb943cab0c94ea1c8bbac0cd26d3b2dd2257beb97a2206c664c20446ca91ba796cf3df31af52c096a6bc2f996fd040f149cbca1451018d6eb99ffd5c3d79a83fe77a47b296c57835212b1eecf3febd6cb06dddaa267fdfe74dce74a0b61597c4b55c6c18466810b23a7d26b44037a219ef758369213d71d20bd8af7848b6a290acc5c9d9aff05680ecff4e749e7afd4fe1638d61433549cefa7e45e09f454e8b6a2f3f46c56c927527ca712bcbc28ee61ff0f151e3084c97d1ebe3e03fc03f4818e62b141c7807ef5c48bf78f2eaebad844fbae688c48460bb50bfb9f8dfaef921bc1f981941bded180b2e9e1374bb5f28a7ee8c2f01fdd083cca9a254f8ee70c5bb3906154175aae78d21920a2c749ce1d53185798c2ad7f66da65db44d14f9b2e6a47d6c590d8b4bd0e1893af06dba4e770a", "52ac006352", 0, -416817208, 0, "8348e6ff714f148d8ee444a2f59a20c340e9f55efcf0f53bb557dd074aec32d8"], + ["017d3a0f02950dc516904ef21d59d27c6b0fadb0aa89db6917e6950294fd4086ee75a602c3020000000151f12201b41706808cd82eafa4fb0f1cc60309560b337e496f279fb0bbdf6f257732f5c834000000000263acffffffff0200eed60400000000036a6365610834040000000007005353ac51acac0000000000", "6563", 0, -1523851633, 0, "10043308829674390bee165d00a39f331f9d59576026fa5c6be719a4467c2248"], + ["b2e7365d021ea84c408fd30967cbf7563fe9210b5f51734c6b44c77b4314396977d219c9890300000008acac536a635200ac67043709b63660bb059929cec649c2f65f2c6fb096bf56dae7a7a3646d906794f6c90f6b010000000952656300525263636395e172fc0418ac4a03000000000253537b824c020000000000f8de950100000000055200ac51ac850c4c050000000003ac63002c2b7be700", "63516a", 0, 1871467588, 1537743641, "e527abb1d4e309b8521af0d8d9845e9844336f47f370e5a08172a27300006ce0"], + ["36c3a33903e80a2dcda5c81da86c6c212207ef5d1025a3df94f7286a9b9d10ba6ff50921de0100000003ac65004fe8288e6dcb9257e1cd2a9e71f6f40bdf3a7856128ff151bdd7c308461f8d63f9811904000000000352ac65ffffffffb0ca6f0a196faa9c8be2268876e410840ad45de2b7404ec4e434a3e2e14ad9c50200000002ac53ffffffff01720c760000000000076aac63516563650000000000", "", 0, 1507027457, 1537743641, "003461b1e66d65040039b7dbe9115e889cac5704a12e19e8daa013ec231b7d29"], + ["99000f1501cbcbada130c15afefec025f50a98ffb7801d9aae48f51cce7649e8ce84b6d2f4030000000365ac65ffffffff04905d80050000000000311f1c030000000009ac63525265ac53ac632278a80400000000056a63630000255b74010000000000d77a9f7b010000000000000000384db901000000002dfacb286219c724f70e1cc6db1daaaed15be68be6108fec3995a39cfcb904d678ff11113c4981590d959ed682a39fc5b8b57a2d8f9f940cc590c0ad984fababed4949d7ae2b44086059aeb069a1009edb9ba2d3e1f052f7f3febebcd3bda33300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d5abe50f59197c4f11262e3975d22af4819ccf2cee1ccee80d5ced1a23d69d1b9ab6dbbf3f427323ec785b4cea28f8fb16a7d2ae66308854126ab32d054601517a2a2f2606410891cdd994c084364785a6a618390955cf9927ebc7fc50143864e0234905581a60cdf52eda2476f88f19aba22ef8f25a8bcbb98b665991c9b3890215d78ca218b90d5339ce7944208f1670f4f873b17dfb11eb6add4a03956e39590321636802d824e0dfd072911593f651adce9f50286a66cd943b44a8cebab42ace0a0156f7de650e10a83508a7f22d5f65fc15013fbaee558c6e28708d935193f78170d03803ee9b0ff250b1c369fbc31f66134b01c779c0570e5bc146daaba4b00c02018a8d3acbb25e73e8c1e9aa5bbdf400972001ba25aba7657d471c57b89144320207713975a3d75253df9295dfd2b0b4144f80b431c2c7de80360ee719428b140e032a9e23d4eb5c3743d1f8d4587e6f5a1157f788a5b97eb986e71583582287489d03000d6992abdd8011799e86a6e71a2c23fe3af8b4646f23cf20942a4e835a486f0305668f797e63a6a52b21f402741c2bed1fc3d6ae6de9c93c06a8d4d10f771b46f0ff9f6fd164b620c2f6f7fc9261bf3bcb77672043ec960745c50c0bed888d24c7c4326e008f2405097a500d8263f78347a081086b95e6c4b91da48c8a24a74daf0f1c981961f3b94eae735121d3add17d389a456c6b2cc3369f5c4cd0aacb7bb0b377f7491147924c08211b30ff36488cbea84f308f30dbe1e60ee663439396a9ab1edbb2513b9e1b8051b46d7a76edc0186aee39710d05a40fdddd38e47103a95f941e79d6b3ae7458c8b4b4c621a74701ece0e386eb9cae67cbc40c8b2988fcedf987acc3142b1cee83d4bb24e9dc3020f9a5da8a9ff8783d1fa5d869ce8a3f3b9a23e08d33581e6119107078662c3a9943e6fc5e1973a6f5b86c75c2259a175e6e4d8394cc911f1e15e75984ad6e29c71d8a2ed5bb00d19fad93c1820aad67fec07451d250be470f651c4b57d680a250e70e3a5bfba28572c0e73a16be07941919af17601475c1b5e433f1c4c45cbb009aafbe317ba40d36c74715f972e104c20708e9f408289948fe20e4cfd9f654246cf4ff567a74c7ea0c71665b45ca1d6f8bad6129efe6678e6010f74171ea1483718f8ccb95ef51f65dea1f24ae1e7bcb9762e056a6e63e4735c7f9db5f0eca8539bd5077b9b4c75dc3bf93df91c19e33583fb0d4e170ebcd632cb803de1ae0ba62e73045f6f8c85150797a81fdfcce40be382bc09269f6f790de4a4557dc6e10f59f1e3e2283e7d0303b5e39e6719653f21fab4646d87f837f17d51fed54d5ac4c655b5ed365a34529c8e050a931863fee9f5615066f52f5d66d839150e020f427d7636df71ec120d17b2fb3122f510dc58c793bd68d1ae73f86abd8ae22070337602fcf46a2f06d3ffdb53ee355a00edcb6318b376d89739361274e1d89fc1f75a994ae5f5cc7a6d7dfc297e2ac098346f1c9b866dc3ccfc3d08309563792029264b7fb06139c9860d9a4e125952a717e7a56e428e8176685bad5aa458a2374cd3e5956c4b39975dcd1120842dbb3cc7ef2811d269902ebb527880a3fdd94a9defa17997647baf2366091ceaeb2d2b143dcbfd474b3fbdcbbfab7b0b170b2c9a197e0cecb9fe0cb9be071f20e798ff38b8f2527a7c62a1ebc889110d4d7096deec30518f9c33466730f7344a5495868e330b34957d8be81e402d44823b2fdea724139c91c03e6f8ea578fc1d720c99ef750e1faadd7f684dcf8e6644ba417a0e7c75724547922ac7f0e6fb60d4864ab1bfca8da169ec0d73d38a073f592bf4c232beb18ae56437408e95d867b6b6b25a5fd7a0d5dd634860655c4f14453f67b2de61976c66c45d7514f7735ec7a73cb2815efb18e858d9d78af0462ff8f2a2674da1b90830a191322845a4d9924936cb58f81964f3616642354a864d2760e8c91d2d75cf787ae59f7f34f1eb6846cffd0218ad79f003d6ec2ecbb7164615e2d7c52f5a6ad71ab8d9da47bd10ff239675ed4017efdbd73fb648269086096ff4133cf9c70d1cce006b6e60ca3c68192721ebdc3b6976d6c72774783b5e0931193f061aff5a38c3e74be63f0cf78cf496fd15feee4fc3e99e41ea2b1f30c1b8be7d14c037be2fd771b5700cc894c14ea6cff27da196bf22373ce350e46d512ec394821450f7f3151fe3b4d2f07585a0c97d28ccc69a96d0c9a1bd869817a17eb106d5fd0a8e715e2402a14b3d9720cce9c51ee4cb7c92bd3ac3beb51785eb79bfbf20d0347e16e841c51f79dbe0e18eecdbb94a8997acda8e1e5c06d53667e69ad3f885759a18dc44ba1f3aba817744535b516edb7c3787fcaf28fdcd1dd45574884375b649f24f264c2e522f77ea45d62ca6ef81b546290c923ff99162a9d8a0b", "ac6565005163", 0, -690841074, 0, "c31c8e70ae41f95054bd21fcbe4380a0385f765da437efae96e0fa3324ca3448"], + ["030000807082c40302b12611fa3f6441f2b8e2e55f6754507fae7b71a3dd331ff4de9eaf2b2b14c1b00100000000815fc6bf16a38358edea41b729ee3d56cb1f20cb34c0b7f3478976f2c783af33b9c96abd0100000008515252ac5351ac6a623a880c01e0677b0000000000076a0051ac51525200000000b0674de500", "5152", 0, -1069958644, 1537743641, "ef5904e0429421046449e37d92f7e43dc7793430c1dcb32a1630ec1c3c8348e7"], + ["82b9603c049ffa02dea415bee2f6c695c5a6138e31dcadf4c26fa48015d9f13e5445536e2e00000000026353b52fd7676d63fa5807757de64e03f8448ccde1189ee6743b66cebf5f626aab5d33567a43020000000965ac52656365535353695350973895a3be4bffd61daa4e9ea22ef3ef12029992b368c936211c5a55504963f82b01000000025351ffffffff21e0dc5908ec89a0cd93c845e9772ee0c13ac9167c9507f93fc3630ae50d4eb0000000000952ac5363ac53515165e5eb72a30381e7be000000000006005351525153d7df4201000000000700655163516a65ca17a30500000000016300000000030000000000000000d124970400000000f44cc7f723e1faec63b85c7b218406e4bd6240a959da7ffd38c085728159ed63fd475073bd569da6bba2a42016454f775d4fc19ed5b633c416f62635a1abf318a351c7c05dccff6fb2a604409b0308b9c61c3b40f2934ab4dfba09a0df49297900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f61458ecfcf8312f7934082d9acc48dd2b2b95d69d43b3e38cc836972e438afa116f2f5c19eea0644df892e8586a81fa12f3150b7cdef7d8d939fa9b118ec57f8cd0cf078388551c24d49ae193408848b17f2882b0a68bde6936880eaa9225728e3ab6e3df6010f0b15ca06e38e5f40230cd0168464894d6d93f3d5f4ba1c7af0212b69edcd7c34dba6956a0bb5e0f751ff4a126a26b65607b3f4a2c62d5cb1b81020d3c85b098246962bfb5324d43d9733d1c2ab2f7989ac78f7c40d6a53e2b38000a0199f043123e9bfd7550c854e2a09aa4a58bbe7122de210558e15d62812c5a09b9e852fb95cb272337da2a4548c04f1c3434e37a59af12993f531be323b41a5302253b09e3c7937c47165064c475ccf449980a52992718497061a066e2779d43c003015cde4fe0776873d90d7f0db3cc95daced053c604b9e8b8d135efd9a39833cb0311f01729ab1c8b3146bb14c5492f798e0183fb77ebbaaae9298e55f2ea91eb450228a3dd5c88e0746d8db750bf8e3d34f5f7c7dd8cbfa07dbc89bf8284897d3f340301f052a8e087b840b0e4981e076193d11cda7a54f3e8a455010393fe3ce42c6910ab3a48969b0bf76c7256396f6498375b1d9f2704ce1d911bcb15b71bf53998cc3f8c81825002372958b539019420872ba23285a4a6c6251bfd8dfdca41bff6e9fb0377373eedd2a7bc24fffa9260206ce9ee60a600ff0e87e4021843e086a6c10e70426ce22e3097b2cd921c498b6102dd13604541498355f504f911dcf35d16e0cce3be265842128bbf12927e94e375e5266d3f90281b1705decc52d3002e9415d8009790ffc7ee187530823bf020bed1a27d0e656001d5e259f8d005d082c15c4d097df2b76352f149cf6c88eb2c9e41491803865186f780bf14393ae804507970362ed6bc27de13e6d85c0b11e146f5e1af7b36e6eb37c756195df8464efba1feca8e889eacaa89dac7fe360c691b0aefaefed59d15365ad2eccfd48ba251631e01f39587524cb9a59b669481512e76198e372c34d0b6c9bfb5fb78be83cf14349db7de554775a26dcedf5f2b3694fad61159d61674627acf948113f14c5b900a2017d6d7f1317818d780e405c5fbab525a3a923dfd9d0f084675f7ca2ba3e66aeb87139900f97b79f0402a5548f96bfcfb249a24f4e33930189a8ff4c7c49178ce512d3523894ac7a7df2421a9fd46b37ceae47adce98c93c8e7988a0f78e9694851c2df1a95e25e70446ee7e74f0b2c7f4bd1aa144db90784cd3547b6437c88296439693ce514b2252397931d2773d18eb2cc70dce1591e2f589459e860dd9f72956927d421269e7d383be05e85a535499e5d6baf4ec6e7e4a9e7e08abe1adea6c9dff58bb23887cade29c3d11c950b349b917abb5e59c6dad7bdc9090451b7166063bfd3a7f4ad285c0151c7a204283f2fbd65e0b9452e74e5290c505576f16323c322691aad108cabe0c28cf38d074b5aa427f15b9838810a75e7950e0b95df7a426fe372d42cac0166e5860782c27ee523679e79980d2bb577075afc22b561f7f04f40e074d006c709b2fdc519135d93adabb331abdfd2912b21ac320b08f30abadd217976eaa8e60a3d6907c82bbeddb43ef56e8ed689ad432c428a894e96c0f1a4ab50e913960b3ec75d28ad9fbba6dec8895291435b98d94d80a4155155573b0d359fd0f0eeac82d661074689b9468c5ea00260a55f8384e0c04e1de441a991d7cab7a52c2e1029878de8f17ab00034de046cf2762875454f18a5c75b720b6615249312eb6d8014cae38f2a141646eb0fa7340b5a23173b11d7d3a2ea252e9dabd67cb175749e4eb483a4d6a42bbee74d9dd8ff75be2c2fdd7008019d4ec61a75e83a838cb1a487d388b901721c451034a2ce97c8cfe8565245a05548d614ee689d64cb32909a570199e7842f5c4e1c3d73bad89b0338bce8939bbf2833f58a23c297f5fca59afa500e767cb3ef050a18c441e3aa2418154f7097114c8245ecf13d645a67dfe5df26ad0edbf6293a02b6d000366a28f7d53aec14e12bdd674c9946cc51cbd12b55e4837c8d9751cc47339fcc3a97a081c6b084655d669b9703db6bd111f347b335eb53f9173e4d45bde26301306df82a9d9082640dc9ea14027c14bb6e6d57eb865f21cd2fc74959e4c0ad737cba2fb974975aed8d5a281477b62aefd330e45412013c45b03bf5140c296be934fb446e900963b806106d5875c8a89f9405ab37fb62a97336f826a0e7cfe2acef541e259919232faa734864bd2a1cfe34c7a88c61cd08e24a0000000000000000c1cd390000000000058f0c115f82ec83c6f7728b4a8d1f70dc7f58c680f1db57ead7e7ce3e9a15a69d2ecdb682ea2396030729fc590e1cd939d2b94515cc9e04891b95a7f21940ebd672228028555d9cd633c5287e03dca2de1ca29e156d94460702cb843787f23f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000685ed553242cb58caa77bbcccbd8eb61c18ddb55b5b30f2a56654f00fc7eef2b87e94e38b8ebf8052c149b2bb54a62021f319d3aba960dc45d0526f9eceb10fb413b5f0a4396f7ca497e0eb3d457d57874e5cc2d3bf0c778ad30316064281c1dc4758ba08522c097c82b7c616242afea1949c0dbc6d10ef7ed607ede632d01c302201972f8fa79161c47ea0f85b8e83e4672cda31bcf7d672a03f46e4fb1a3a3910325ffa41565385d16b22dec2ffdda0189ba9200ed9647ff52d51a27c98038a73f0b05bc00b386226892276b055a1d44ceeb642afe74271cc05cf1de617195422ff224129edd1680d018fb8749af95a8b703c3c92b12287c448440d88bbe8f0b2a78030557c441a2ecf0aaca224a2590ffa3dbf994ea5cf98180af4b02d12745b2ef86022951c805af428904bc39ceac98de705db5dfe0f37282e25f63251606f92063260318299356d54d813105698e419e10439b3bf35d1f10248b8876ebdfe752e36022022531b1ec9aa865a768ac7059a9493101ce15ccbcaa57c10fd0d43f89624f72ea021b9e19cfaa8f53022e45cb054e10e5ad4fa0b48295db52a506a2527adb40c5f7e5d997df5a99cdbdf1cb2440c685d81f7caa165526e209ac591ff2044d084692b8076439db36358cc200d408b9a705f3aab88a4233c29cbb04d6abfbc2411a345b6270886c6d4d2f72a752d541600fa16ef48b4161e461fe72dbb314542cac5299ca22331ab97eea0a2857aab6d466df08d2bda1b878ab94156a973fae7a0c253afdd72330e9d2b2348503fb19b61fbe6ef88da44f5651f10b8010358e2c39c9e44da7288ea1f4cb0bf8df74a4978edc5eaac059357e4b3892f745f9d212a5c7bcbc9a7f66b7a61221c5b381a9c49301654ade52244d0e7bd16c97095b1f5529668f428c4595ca57b08f554f1908f1ec0fd092ce950220030b08056c45e2275192919105b30bb4d670550840c735a747434c8f5bd3c236309195e2a548a0fd5681595ffda2c8da53a1a553ea5c2207e7857bcf12564fabc594e2ac44f0208baa51fb274d2c845f29d9af25a49da84b4c62a8b819628b89b44596b09ff3352f07cb4d22ed55cc1e9bfbd8cc74b5631428286bf3e346e1ba312e0fa5c892f992e4192e0d1658ce9f07436847f5ea8ba496056b0d5436a3d453cb7ba3d20f670c0d2cb70b7b3a0d1fae659ffc375807cb51c68a9959600dcce0cc3da49c36bbf23809e46d8698542a496316164596d8b8e32a9e2d47471548cd9fceed856840327d07d646972f5469a88414754a82f43e1e856d2459a4930209ce85e026294e2beaf18e2da4e42894df0d46f42d3587a25fba207b84e6df1c2bf894b128c6e4ff17142f9fe7e746dd2153fb199fa63b8d10d709b51edfa99073f2fe4af47d7a76022421e0d85fddd185c6edd54070f739377c4d5eb72eed23e7ae7fd305774cbb1f40bf465b8f51a729245abf20d809a47390fd0326c2217e389c072ab43647152928366834dcc71098c65e862e6db8f68b78a4750cbef10a53452118527dce3a38d3d339cb9a9ca0bbcae52fea76d0bc99ec0d174c8b8fbb083712ca31506aea46d51d0973bb87bb483dbb4d2471611640cacd2274d93653c86b8258950ea86559a5c9e5bad7242ce8ae40e1ab907ccf3fcc42d95aa5659235d067b7c9b5160ffaae7f63af2f39ffd82b3a349edc6858176e8e052778e5b0bd929cfe518df302a093caa9fb27853da9763dcb5a4a558c601b690bd0c82cb1964d738d3c2739e5e1e7f7728b6d6fbdf2a33b5f62800aaf29970c4dd17def5da1fa0b09c9edaff7039e9f601141624a135323092b3803cf9b90132aa5f996096928f1ed5af32e537d55dc4795c86ce5b13ea5a532ad1134a38d7a21a8a89427d565f133cac0623c6cc9d02a38a05655c42e60a0dada8c955cce7b3fe3025bde86a354d42b20dfc4c2a0655b8df79bcee8d1bc5b3c75899869224f80e4884891a08bc7da5681dec34a1811702d5dc83d08a1263e8a963ed20cdfd5b74b9e5093c0d39092310edfb8b4177ce3f377dae0f21a1c05def9c9fc9c9db69997a975e97c753cccc08308dbfc47b3ec4612a7cb906643b931a1f1fefc5b075748474cc3a877df94232ff25e0d076e77d082667ed614d7e29c3133ee742437a5b165fdc3234f79638dae2e602991f9371f00e46779af2d2d1f592c03244365d3263f1c6d78941a8b157b8d762c2519221e96c96716de1b7cc5a1f8727993ab0cc459a4491faa1aeb8af855c56db4ff0ff3735b9ee0f19b05bb0048fd12e14700000000000000000acd6704000000008bb3c16f983e8c33e58ccfee8953783bfb8e52f420031fdde77461611614be9117907371a1e06970057b0f5249acf9279b8f97c4fc2b9e92646d2efe580d74658de24d1394decbc3420c652573f3008815b8839f0b82a0302a47818446fc1026000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c1b5526e1a4c8032017cf269e634480fec4eca6e973835d970a0fbb4f6bc9febdd31397ff34dca77546f7c85d31c4590f02da199803b797b9a42c8dbcfc3be669637b2b3bc87a3b2bbccefde4b24451f7e4be377fa6c6c024119b7545135c25eb356581f91de69031aa4baa916ce2488031e3232ed25d1499a2c9ed75c8cf46022a32b6d5b896a5df308cc92099d3749dfe86e94f5abda1e4c6c6386d271d0ab2030ffb2e6b6b19abcbc97241ad0aec7f14699c62dcba012e151768746a823b79ce0b067d569c0d50445cc32c5558c21ea07cd99b387ba79b98f1c86fea57d6efc3d81dc659d370e37fbe858304ab038ea2bebb2c6154ceb521a5547c3f4372da2f7e0225646e850efcb1c6142326e25733ec59b89b930a9ca35e57290fa2887c49743f0230387a319aed4ec1a52a4c45143ab43f4daf1f845dff99a01f24cf0d6c49d0ba0303b339ce8bf2c6bbbe83facfb115b3ac46a0878bc07f81792f7151e2fbf276af021fb5f77f688f9fe7357182bcf9b924c9178ab9230ee403c3133911f5d678d048021df2a56ecb0d846470cbddb9d42ba0cf2c14082056d4d0b66ee6f436a336f09f64226160188e0b5d19cbf06a241d9fc42ef1bba619685cd0f961bf86a28c27e66261b1fca52f0dbf2e3aebfb364a828b1ccdc81c54edc867c58ad52ed8b13b77446d80deb1737b6585fd4748adb007e4998945f6973e79896080653f86d9d4e5a30a08dfe7deffbef1db5be0a4a84d6c65d2f5c8e4c46ce162f86bbcaa2a3ba97b083e1ab65deb88f3c1e30bfe68adbcb076fd7d8c591dc6bb1e9765e47d7f65925797664ecaf91af8a56ff2a1f6baadf9d34ea24b93581b8ef45809fadb6907d16a604d7df39874ab688f807993608fc91f95dda927236b047fc7443eb5808eb7d2cc4b444c312f05eb150e9ee351000166b15d56948eeafa1f6d9de8387c936d4f18f6a33e80ecf780c9b25ae0af2c9a89bafd37e8c6b930d6381f25e3a80551cc3211d21d3bf816c2611a7c55901bfed51a2f764ac7551c8cbfe4973cd65e86fcf4bc79ad8fd7adda6e55f4790a770a7b5fc74740a07dd342ed7c412cc98fb64ba6de4c0f7e66d840a8b75d1b023676aa06bf1c1108a5e4e192cf80c230b08363d569a5291d4cf6b52b87d2981a6bf9b2755cf7c90e04984bedc262be1db11469c6ddc28470f0db97d0d01ff933a404388ea5043f3187cd54e74e84b57d51a5f60e1c35ecaa79d7b4e98a2123415caaaec4fe359686e04197aba2b00e4105acd54406a580b69ffbad95f7760f53f36f65c1e31487640fa84e679664a316296acb372152950678ef941249b6a2e26a0b1ff58791eeb6f005b113b741887fb58b3b9e92c783cb8f5da2d50a537572ee20460f7961471b62583ca35544e499a3cb430542a7d68540a0a282581b202f84145d65f0816242a2fcdba5b6f2814d38a5bc009ec46bdbcf1b6b0ab0f6c5bd26b19a93f6ad45c17dc19329893c82084d18a06dcda812b8f19db4b8b01688a5672830c23775570ed2306413f1fe3c0d3e2d844e7d3a96c366ce98eadc5801b282ccf72743924730a9700dfad5a60ec12d21978162dd8b155be32cd7cf1f0e57c82a97b5ee8a8151914d81f02d8af23b83136daa29b0eb904b6424637b35813368de54d0151cf8ae92afd74b7991a8652762bb4b2bd4332b74c30ac6fce1d5c0ac6f96576b863d95cc06165a21164c08fae622918f1ccbfa3d570f305e5eabee9a55a9b6ec4c360d3e11c4256e1d28747d1e7b0088fac7109f4d8305c53ba82d18f3d4800f4e6189c01097e335ffa3e0f12ed7d823392e5f2cd548fc14a466a6d42a02e1bae1193b3710e2f4fe1de3cddd37ed8e6e5d6df8078333467da3aad9784d72b79e81523273fecf6dddc74bc24b406ef1ed83d342000fb06f99a03c96906213a79079b74f1cda993474eede678579a00fb3b6a7d5417acaa9320f3bebabfed3d18aac5d1997c6a5fd9d729fe93cb46e66b0c2caf779fdb481775fbe57cd4a5bfa19610f8ae3fc6cbbe5e6f04b37275a5b04db0a98e2dd0c730f4232f13bf9ed7341012ce8cdecd6dc27fd272431f77bf7b3a0bd613352a91d48fd4857f38a9d74f807db8c17de2b2482daa92383633796deeed2243b644fec1702e81d9693d8da39b4dad72f6aa3857f367af258e9ee2e2dfea59cf1056c15fbe366bf3df3e6f98b6402ea82710ee7626c7901a2e1097c3053d12d53cf9a9077fefaa0fe12a3e0565f879cbcd58705ae8b27e3f94628f6ca999837e97d0b99d213ab196aa812373c4cf706e097fd2004a786fb77f4525df1fedf7674adf51e2954cf81053bf538206a93d4d160cdc2051c91095c15ecd867ab0ae440d6d26ff21e791fc72d96553a0f6fb0aef1f05ce8c550dd0466dc183e8fd5473070eba9e87dc2e1a5c204", "52006a5163650000", 0, -1166786770, 0, "4e6d139c53ea6154d27e844b5d8d314ca6f55700781198ebc165385608e401df"], + ["ad96cf35021496c73457409ce5cf45fb16fc170e5f69d5d75748702c8ccf75e8105daed78a0300000000ffffffff0065051793bbe836d47d9cf15eda20da736cca8ec54428bc19fb3f37742b5a9f0200000006ac53536a636affffffff02836b4a020000000005655351ac65369f2e020000000009006352ac655200acac0000000000", "51ac635352", 1, 404611999, 1537743641, "5c9a0a45434f121b30def013e1bc3bd1a9a5094781d773dc10879b9a4dbca3b1"], + ["575b4f7002283e8ad486c6e0415646cd13355c7db3137bbd15ec1f3538e8da80a4eeb43fa503000000075252656563006afffffffffe128d774e38ebac0c0f8bd7a2b2e01a81b631dd0e570f26a2f52a7ae748391e01000000086a00650053635352ffffffff04cffe99030000000007ac5163ac516552c9a6680100000000015363209404000000000800005200636a53acf61b9f030000000002acac6155765e02554105020000000000000000000000009047b5a3602fb7c0ae0982a6e1bc7a6fc8d7efd69a7d078950c321ab6a414b0c01ee8461f8e1033afd561005f41705f1f8df8d07c9fddd49e4015d44a824e66eb1c280f640015c50563ced044bb4d314bcc147e4387b22e8071ad769f72e3ed200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000566d6b5b2941cf28846b0a02499b50e9f9338f90e8d4d3fa5354a689800618df26d0100c403978db3846741e3992c31fc603f764407a0c1f6ea38c0643274814dc11ddfffe51ca12fb91d8d84ed2b6930ffe46ef89a8686a103ea55b9e21543b093f109d0c23bfc6c0a5eb8eeebf7c329a23b4bc9cb6a0cdb97e43c5c3a69375022001fdeab032d4d8d7e27df5ee04cbd7ba883098c5caeff22329417455b58aa2020b93382cd85a49ab5f2b3d1b808d9a65c1d0c378abd03d851efe6c07b5cbaddb0a0782b23e729d04e861360a46634295ae19c344a7e730a2d58bc2dd56fd93c33dc6c85adc4bb76efcdefc83f1e90b68f83ffaf7575461e59ea0d3c45838d1bf0a0306924c87e4414108b87eb6f223d62d54ebdf90c256ca39962f2121ccc07aec530216ee1b2f234161173eb7a241a5d340594fc24607da84a0b0ac6117f2f9bececd0223b6b3858454d50d30fbd8fb122afa71d79d7ad4cedc36bca28f365074b7a56e030a3609aba875aa610f41b9e1636a7caaac4582a3f45e18d4589f4d9473863d4a022f06693e5ff27eef7d316dedd3e471bfd8ed2bb68a7cfb380fa3ec17c25da053f85dc8153a06dba636bbe92725ae88c603eb4b6573fda1d4c7ff73f77b6a2b652ae86eb96aebe1ae57383fd569db9f1ab09e396d6818b1e0edfdf5fe9f5d69755653822ea813dcbe56805ec1a8369f37a15289825748c92592859a8fc54cbcc1b665e65ea6c1c62179636e46f3b33527f210ca9e7ead4b43d845563bab637c99b518104fc5e9c9355cd6343c47f7b0e51095f31275ff54cb9f6a644fb396340fbc8d3e01292d48090f4724982d89160421518334fe6da730a13477dbd848c79eae433d9b19f94a51b66ecb87c3bfd4ccca759d909a3e2a49beca75a4059ce65922e8bc6da7e847fb2ee9442da73033b27cfbcb94b3009d98601e81ec77d5ec70487f59a2d7cd87f1ab7ad3d51086223a19f5b84d7941e226602ca2aee170eca034f1c2ca059ddaffb26f67902c04c3fa815d969ac5c1a9c6f3d8742b265d6b9d8b33ed71f4d96847aa7bc998ca4559b25404113dfe61bca86d15bfca7e8a9ccca755ceeb9e1336e471aad86914f7bb50ff83c2869fede378b3d218e8dcce4e125d1668b299e15163a7af966fd82097cda45efeb5534f14170859ebf65d03b04ab0e817697d72e4add2b2c0b9d9c3d6c5b816f6d6dd895456d81cf795d5ae56ee8fd5ed8775beeeaf47ac81fdd3b5b9c60523cbdf399ca2456a7410981073a7eab4d79baf17b0f0416ba5ca0487023e34e1851db156283cbed75c4a62271cb9e6121b527ad78bcd9307fd53686fd3bcbf933758edcb112c2b3b5fa09cefffecadae675176d98eafc7e022fca26b911bedf56cdf9580341e78b9d4e843228b3b28cc06046b2621a3bcad6452b2a9e91f7d26ac3677d99f5f7b886bff9755b10e31e7792a1e19fc33d2785053e4facfcb520622245c11ae7d33064f9a86b53c108c62927976a8dc5ade5f1153bb8c7af2da6a775335f6e08fe749e4ac7e8a80a2562bc96c1129cc113584bc98033e8d3628d3cf71ca63c2ee47579944c17212c35e11c39a15348e2389cd7f312fb9f6805210eaacd1bf6cdbb31e81fcedb0ca53da775f1e0b7b68044cd043850fa33272401b424973799b1407f83b7b5cca20e7e8fbae5b50805b867e640bb9089151a4826cdc2aa79a1378f146d779664fcf42d942dc3fa4c2509b31a11d97b26e3e7ccb36d0a16c48bef10636d6b5766ad47344b40df1997f7847a207bf2e75ddc6932c2aeea24ec2a6acdb31315143f987d6c008eef44188951ae88ca358ab91dfc6979f98b383cd950b3135f9b0b4e1fc2c2a1d81a48fec46a48fa1a7a903c30321e7304d4c97fcdee1a52471e49820e9b08be8d5023e24257bc5c72cd30aa6f8fccf25872c714b2801818bb65fe0f06c8a27a8c615162d284e5c7d4c29f0b50de25d3077be79fd0a1bd122790e85f8f7989b135320d108d5d8fe62f50fb4bbeeb90945c8d4f9ed99efb3efa996296eb7ffc4fbfb6896997d4982516bcb5f2ca3db35dfd478cda2e955647e39568e6fbf843f55b32dae1bdf0b6415b6e1468d8c6e131a88cfbe7fc6d5ddd8777140ea2333a57b628d93b1337bc574e4c7fb88c8e05ce679814c6b306863cc262de4498ecfa1c393082df65e56e83a5743587e37cea3b22cfb52f01cefabcb4de6cf135a08ebfc714a22c905e5b584a6f0db6c07fc7d11654c030c7cf4297ed5799418717872ac8667886b65f485de64f9990dc8ebe5af30166980000000000000000000000000006d2da2d0b224353f4a0435d6c3514c2674786e7725078c16767385b1b366f6f881ddf7c382d76c2a154608e0a8fccdd117898df94db440a372d2f5315df4a28bd4e43d74bd0bf90aebdff9d25e25dc44f3aa922c0696fee2dd9e33aea4c0b99f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060e00909b077b3cba15f1663e8cd5b87c629b824cdc2e1687e67afdcea8c80fd390d9386a3500d038f0a54fc20acc4e672468780ce61b2354417f1e55aa199b0c6636791a4b5e1f8f045c70fa7ac431486e55d8cdc229010347555b2a30ec5b3a14870f222a6efa5cb1eda7a4c6a440a63837599d938e356b5b6fc94d3b2ab0703004e7b7367378718175a41c0f60bea1d0d772c74c93b2435b11f2ad47d4d65ed0210df9c84d1a356dc5404d500d8eda502dfcf235e155554983b52a22ced867b650a08f2f3a92ab9e8d3849593c33c75042010d109864aa454e70816b9aea0ee1fadef948f9843cc1971fdb2dd625e3d579cee26646c985cceb629a4057bec08c3a903200410d82eb42c3c4a735bd62fc42290bc403326518e144e67d351061ec459c3031f73b073f3f8b34faedb439c94a2ae7cdb73376b348c58bcc1dc7362630c255103087ce5ba7a9dd9320c0dba496340b8fd378817224d05a40169893f9d48c3bbec021ad0049754fe85b74355074ff379005bbf2c13566c15a42f20e5229d86e735bf03045de1f4e516c5c5d55e4874b0fd9df70cf9524fd952edeab634152b60956234c152a23829a91c2781e5f50d567b343d4676d25f23a7a1374f42cf21b473f29df641af5a1d83f346c8b09e667aa0bd843884f54929892745ebeefcbd52c6381dd84bbbaaa588c9c94b4c41ec027c9a082a093857d9ce726f095982ae8fdd010c0a6f510f64c7dadf993a43be38736963e58c4e85be6c41351145c309360c29f6d48516145fb91a7800f12c9acef85d36f566a089939074706489f71e581d8dc11bd1d2dc8a4c20d756ff5e2b4bbda45ea3ebb3f104a259b69cda1b0bc6adccb2c0f27603b6227b1ac30cf5d21bccc7de6b9bbf2cd1c01190bd7201ab75f455731da42f574964f2ad5e6078d6bc00cfd1c3a1f17b93b055e8ec3fb891e9849ddddc80335687d97b7b4e2211899819ce618be43e4000bf487872ca6b950a319dfec1fe3847c74e23ebd5934417a904d9d74ebb7e5096a7d269b8f56ce1eea6745e87379c09a2bf56cbde8519f8a8827f218606634fd68beb66a48b8f5387084d734b4df2733e35c34a11ac2e083df5e0258ee02ad70465bb56c4d438dfac79be0c7413e0823bdc89fc30b9bd63b7c809ca8176d146c44fc3d0aee5dd53eb4fbbc222c61fc5e13e1c479cb69b33e168dfca7a2a08e8fd64fdc8922ed89cd0b607741cae8537d4edc9969f7089409bf6d84e0aa3f3bb91eba327ed5c60a0b1b2c9ab89c2610883d2a270c8fda168708eb7b97fa8d5acc463d6240f1ad7fb3a1f1c1ebd844408dd1221d6fd911e88d6d9969a749864727e460a43d80b8a8f5d1882975ac71265aa4a7013e10e025a0f1fb1893f58ea9b158bf9b02d2e70c594a641443c20fd93f465b907c762cd5f82e72cfe7928c7d7338909afec0aa59327ac73c75170b6601ce89954a939e34f1c406cae0b37bc11e0de50d5642a2c57db0cbef410487947cb2b3eb0c199c230ad42cae0f3792814c1911daf19e2ca9ba109c9d356dc827555b8c747a55a8912c94cc519659579c48b0818e126866dd3e039066446363565ddebf219aa1f36503469314a2b714478483bbc830bbdcbdd0ec10481e28c17811ea9087694f8bfdbe23e50ed43b7e98cc3d8af08d8d7a9d4ae7fe8945e198a5d284c619ac7ec98d5a942a05755f0fd8a84168b2e110c5f7801ed8e1b46d70fa0ff36ca75a266408d07aa74962ec9c85188f80998261846a92a8613f2ff9bf614fe2fdf674bb2931c17720b2878d60a0e9e718e8c58f022ef21e93bc0646f1a6ebffb939c1026250e3a62def65e1e2bc75bccf07a579f9d2e0fc8cac534257b64930f650ed986a2e8bbf05192f72e7a126ffbd1086959c3f335507df58572005d6efaeea2e861f98006d41b968198aada4378a13bf892645b1504f97c6bb96653cbd35e5210d7c3795b44dcfc12832809bd206637c8685bbde3eaea25465be4e10d943fa06802d65546dc37bc0b4694ddcdea91fc6b3a4110f9a52ac0d2a970f4d2d3691680d1bccb41d79316d9ce560f9d84762aafedcfd54434c6f8774885ccbaeb9c1820a96fa9d4e0be0582935b757eeb8708a0357b381cd1d06c1e342e380f68cc671aa43d253089480c3eadeac3bb211a6a5e283a24f15ea00b18e3916d2b2b3cde399141c9e37f36218670ef6128232ff83170a27abe7c7b20a00ef46dd37e91bec589b94dc1edf3de41010111a777449ceaaa2cbc356234a35bccec032b58f6f92517e49cbe883495b6ccb1bf1aa6125d1fd58c08a275492cbc81a36aaa65031107afb277b3deb6457287d417bcf693f17d5ae0b06fddfcd6b8a73c8eafdc51c69e164efcbc242313b149a5d7a07516d62e9fb0bf4d7fa8e0d291d8319dea280fb85bd074056c2352810d", "5152", 1, 306691663, 1537743641, "3d157217f4eb578051c61548f6bbe8e26dcedad993f68b4ab898ff812c77f111"], + ["040a3d610407e439c56ff8afe4328fed74e274de9c8a10e054e295eb0721cf273e30dde5b500000000026a6affffffffe45fcdfa5400fa873391de764f4c513adf5ff225e16640628fd17d1e5d3aeb660100000009526a6a53ac536a6a6a7594e9916ec68b6c971ca18d867136e0c45f1549b78248717b52ed698e87b692c2d6baa902000000025363fd28fe1d9e7231c33f5c11a93242f9931bfe9ea8dd6195a99159231f75e13b9fe5a2d6b001000000065251ac6553656a18c82c047ca1410000000000076a006a656300633553320300000000036a52525e132c03000000000851536aac526a6a0036e259030000000007ac51510052656501b93d1500", "6a63", 1, -770469476, 0, "d2e7ac79fffac6a8fe5adc3999ccc0ce83849fc8469223869d40e754545e8495"], + ["8bc5717502e3090d7af50f3c4afbf585225da07988ba035b903da797704d0ea561dcc7a16401000000046a526a6aa61b378d70132ed3bd88ed190b1f68ef5ef16371d7e8880caa82e37eccb9a5a5806fa4ae010000000751636a53656a65ffffffff03e481af040000000000f4341e0500000000076aacac52515200a59ad305000000000653005365ac5100000000010000000000000000c8958200000000004f161e077aa6eeea39eec383375aff5f782a0efb6a89769af2c617a05c2d1715eb66cf773dc5aba053bdb1c59a5f2d90a607a00bd4074b85916817076069fdc81ab7f6878dabb1ae46b2b0fbddb2f66001ee983fe481ad54ffecd15f8a65d4d8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e855dc33d6bbeb7734f1ed0ed9a6cab18e529c23ad6cf06961ec8c7a085d9357f44de0f1741fef7d1bcc19cbcb1f9544e0bd72d129126e2fd5d318c57fe95738faec54d3ea549c9521329b1f5f9e75289ee2dfb05c06fd44e8bf598a2a14ef08972951f3049569cf50215c7b673c16a1b542fa869991a5e3e9e262372b58f99022004f375ca25be218b5f484c68bd33aa4d9a327903723e3d58b4c61548c12b2f0329ff0a29ae2f2f302f30c4d043b7ebe4cd953a3ce58f86ae3f9f8f8da3ba0c240a0154d8d36e1a36d74cac8b47e1d236b57af7281ed06c38cc8f2e4e3dfc4661824c39d6bf846a36afed1f7888702c3a86e8931a90b7ca28f245fc0ba0f21aff720317d4e1a2de148fc75d6207c6871126790bd8739a14a65dacf8b04f557e8665f00224aac7ff496eb987f6fb711baec801c82ae64ef6402eee3a3bd2856d9310076602171d110cdf6b20847e9ab10f3f09dbb13c3f5d638d556d52d01d7d4a6d614f13021024f87dffe73619da1b96bc6834b2705542bfe459786d379e862c890f2d99340217c4f7d938f00beb0f2471e705a720ead64f93dcfb48199b017e3d014ce76052f8849e1b762642a641b4854a1fe0a5c3171ed0affdcc4709083a4a3b2c8edd18e4edabe9ca068017f4d1825b782f59fa0a32ca00dc26f3ac61406545de685d51c212c044da6151cfd079b95360aeed00d0e04385a8440d4adea759b71d245f08a05e70085710f6ed3c1a4b209d42c4dee6902f02fc0012e26abfa64246a0637fafceccc7f87a7f38f0bda7378284f745f3ed888ac3c305a8ab53950e9a0a5dfee583b61e38d2d902640a4b385eff94ba33ca2718d725b7993de2ad51dd5db1e0af360b1f46e45783e078607d36b099d7de1bb65605e2602f8d59634210c8629515ea2c50b9c5bebcb36bc3bb4d3939faa0396118357716e5d6e668d53d9808c4294dcb2ca8723fc7079d426165720a82c7bc72b340ae7625ece87c4bcfb242f7dd9d53266ea5718ac770502ddada9105ab36a77be64e471fe522ce01dc2d6e4723df18a05e2ef897898c33ff67e0919b6c2bc7a58a493db8c90a65f4b8662d2399cb9e2886b0d3133842887f9c63c2c9c37db706e8a13b2607d1c075e31db67aa7466dade541d018269b8aa69d91d4eee8bd50728e18b4616ac8652746e3194addd3535cc2204e9e2a9f246be62d318257e1d619168a772c565c49ba65b92a04a38f7acf467e755bd8dcd61aac6e8d71bc1365b31750c2872a13053722b1afc176b242a0b9d91092545b6c56d7af50e1c36c99391822fde4afe3b700b99ef19b6f8eae471e700905bc5c3e8d4de515a15107668525e60e950e4a3dc353fbc47bdc2fc83d2ecbc16c55a68ada476ad331188bc02b3490b4bc26671ee3444a89395c1871157dff6671fdf6f22b08f51b274a7dafe29ae8db0c0995f0af2763901ba2fcb5680a1be276e11ff146435fa1383b499b41d545a8e74496fb02f5edf3b7fbbcfabe91f91cf895c9b8470a01aecd305417f5f28f5c8ecc4c2db49ceb5e033ef363e36f775af9b35592d23ab1eb7adb4a65607773a6db2e5d07a9e8713848f4ee737aee5049cd7dd69a4006a9248c29aa1c93f7fc6a648547316a47a9edcf2da777519bc797a2517d3a62598bba9e881fd53190fda172bb823259dd47601a948b712450ed1d66a48190360030a9b2235286bcccfb684cd61a0799978da27277176785228bb855e9166e41bd9c6b22ef9fe07d669a9cd27868d69ed984cf24aa2c421a26bcd18ad6ee5c0b0f1484378071fd995c89b59efe37d0c6a19f6d88c67dcc555478831032dd8dcaee768cea016fed5cdb0709473c5897a6388fc22ebbd635431db29a700e112c2f8897643bf52345b9498f7d065636508b5d57b6a1b0758934ea53336e4692d4bec7ab66219b1a7c40a236b964595ad91589374906d8a0307e980c402f420be7b2a865a7a283e8fc1a8b5635a37915879ab345327bb106098175f674a8c8bb4e0e5ad86b84d88654d1861b175845a234f5dcb4f78e9af24fdda1e0f794cbaa5b51e60980f8e398b94e2e2bd9e9eb61d1e44e4f00b6b3e4c814b49072ae246a3e045fd77ed398e4bc1f079f660510fcf02f97936919a4347f8f126b376e2e06db65de1a9c350180dca886bb161d078c46e26ccb17714590fdf3142a67523a055f1e0b0580a4849bd661282e74b80b740667ad2d0514c61aaf3f2a177677c234b8c14c1e88f3f92115e439636765f7e153be71e2f2d16af3894b63d21c5c9d5b4bf57fac75c48bd7cf230ea87412c93165c42b248edbd8c540c77b6edcd358a6f56b00dae595c3a9c0f224004114c77e7fcce8b24cdfd1ad8e3c53516bfa63cd4d15f7cd510625c2716d26432e2151fb9a21aff73be6767f886a209faa9116fdc217b0545d8d2502", "", 1, -144406872, 0, "d7e7097a8396d488cdf8a37ddd02021a80a710ff9662fca37422299a00843837"], + ["9eaee13201c6b8c59dd059c98ee5cb1ad200330de6052c8e445bf32a51118df2770dd8df83000000000465636553ffffffff023055b302000000000853526a516a656300825b4c020000000007656a63acac00ac0000000000", "65", 0, 899587373, 1537743641, "7ec0231b0f240f9474e858d063498f2c84ae0f51ea7d0321afc55c99190fdeee"], + ["030000807082c40303c8b05b7dd8bcf5a632a2fe7955de06ea2911a19989f101dc550654982ad2be670100000009ac5163536aac655300ffffffffa42211b4aa46eed2ad9ee2210c4b390a86bcf0a52ec687b1475fe7f665a149ea01000000085251ac5265656a0064e9c3057692cf3d447b808416090748a50d34d563b2fa69defaa74fa7a475fc919672710000000006630053515251ffffffff011b0a6d000000000004535300ac3ecb70280000000000", "53", 2, -366120767, 1537743641, "388c6dfc57291cd4eee072f7ce4c291c7033e5aaaa89f8a7d68121d89d54b443"], + ["030000807082c403041e5a839f58657dd854841b917f0c691e6f8b5c4d098a184b4de94db75af58092020000000953ac006a6352536500aebc3ab7fe6631f2006f2ccf992f93ceea7267003298a182a7765087e599be25a557ac230300000000413eca586a0c036f480a80e4e0e421ae5f006d0497db648e3287d183bbd3b3ed2c8a5e9701000000016a9c38b0f631b5972d16f1c56f85a09fdbe51b75d5af2742d3f1de269114ec7f4b9d7b8c88020000000100ffffffff0340a8c9010000000002005278a3cf0500000000015326b0b600000000000500535153530000000072b2b0a500", "6551516552", 1, -337421895, 1537743641, "a09a52f8baddc3ce1660228552678d98ee546c7583c3fc1456d732f79714eab0"], + ["1e2b94600160e71a0ab14ccc3ff8ab2e8cb7224c0235378da40faa6a6d92e519adeff13a4e01000000056552005251d72cd4b501667bbf05000000000765520053635152000000000367332605000000000000000000000000b34b95093b31108d6191a2319453cbadd86beb2d544e24be291d2283037a9407f4b2d123b97598c42d8dfe2d834b086d852a70f508ca76a562b8a79aba3fc4cb68e198d0604014d9ade129072967c16214a216145d456b419eb8b665d1a9e8d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca73a5141d878f62a9253034588d9985f9c9429aaad3833d071715c4e5d0c9b3e2cec440cae521c5681a3f623ec6372007c5b9bfc405af89fe6a9191ab6727ad6ec873e9a5f7be980d7587b5c972e3276dd995e3b59e02d0255997dc722ea7c74038297eefb3303f290844ec7b9160128ab3d7808be1280510acb65e0488a6080309d559ab65b80864100bc019bbae50be2a255a72143297f3a055e2240cd6aa04030f9b387844fb8c2d4402c6caa3411b19b63b48e766df08c0a156f96fe688854e0b009595bcce4a4bf66e4c5021571eb43b6973437f1688e7623a729086854e3025cd382a8868ea8a5a384c93bf488124a967e6cda4569469d7fc71571ac649c54e0228ba16a940650273b995b657651f85eda63bc8bfb594e5abacc1863eb3f6e09b020f1d43fc6ca29deeab51648ab9403f63c9978dc506c874ae914d536ae7a6dd9b03294ab01306aa0103dd28685d2ed08db86d0993d8aca8fe578a7fe4cb148ada8c020809434b6a964774d53f1af28bae2da490f26f7229da0fdbde9550a89f1df15c0227ede5ace93ce3a600465bdbba514f017f112e37c6dda852ff1e1fa365ed725070c52d44751e1f2a39e696491c4a17217b3ddc5b4adaf80e5c682f31e47376e938050b66040c1cf9249262c05b8a982a18efe08d29abc1c085063c587aea61c3ce2fd1748e2a637b7f11510f5e6e9be0f05b7285d34124c45b7939cb660ec91ae3dd5f32768850914d44eb097505745946b55dc433b06051ae6cb782dda42e215b76536f0e11b7c1bfda69f7993db41e71cc112642b89382166be2872ea914117b05110f37b1fefa1533041144437eb11fba93a2861117522363d343c02abd6307b489a0707a256e464f0d6d84fc30142f313ce58a5c4198084cf29b64f9862267f7779ed909683c80370aae01a2b3e4b0924d49c91ae92667c7c3aae147597345e0a941278d1f2cf3ddb57d44c33308c5b668bd058bd96ac0e7875f02ecf74744b8e216a759f5021b3ce71aead6f03091295c648b7db739f29e94796d9e45bbe25c2aa59ff0152bb53f976642b1b6b4c43f4d2d5aa56ada9e0ab30fbd117cfca9d8555c9dc7ad476f8becf80e3b3d9ff1a8b101c9ff1fb4a8eb96ef39a9cecdcdcbb62d06dd015526157e53841b84c6f344a04995c40ccf35689fbd3ffd572c3864243e16fa257ce491f3d1de08cde227f782a96e5e1a29278394b54f488c2852c48752cca149f5b9809ba86fb31fdcb340cb80018c9db855a90e967ee4a8c275891039a38e21bbfd9ab10f911cff3d0fb19c50b456b09d7ff33bde831f87296c5497a1cfb26a255b88f774a06de05cf32eee62bd0f7671a325a41e294a60e4c87d463b0d213991238df751f81634b961345f356615f8d841668acb50c6063a68c8dd509fd915a778f9a164a7189ca06a7ad5dbba31cbcf84355691fc7d2d8c5074a5f1edb2f9bb3119f235c0daead9e8dff1a4c96b4ca198441b95dd0414e1895304b8a33123349becc6dfc3aa7368fe633216bd83578a382bbcb5ce89e45f0681b341936cece49895c6b1e0942b5f885778880d62f2629261406c4f50e0d8cc4de5d3919f29120f727e33b966929f6bcc472e78b1f96387480a3363208d8d51b7ee0a0350237a56425e2888e9f73ddaf06d3f21579140e9eba47415388c24a51e58afcb0b82f1076ec69663394d1ddac646b9a73ca8cf98f0f1b1958d7e882232da8a8b1e859c8c1ac30d5cbcff86dc6c2bf2e933000c85f5dd2ab9553e04997c5b59e69e614c09c1192b6f8526b0fede4bf68b2312ac4cd4cea6baa229c5d7ac76e4f4040d084ff687b993348ace79307be36844bee131a64f7ec2709971ae528ccb43712fb82203ef86e76f5afd48133e137d3575b6b4a7d6273878d2eb9f21695837aa4c616ec68120f8dc404946c6b45941cfb54696e6ad0f8edef1e661661669d937489aea574050810ce3d2ba8a8998c7b55c04a9b12ef63d5c7569798d9913e97e50a46d06c25abcdd7b755fc0250b0005a378d9f2f8fa58b6d8716ebd939d46fc2683bf13b037d532fcd5904e64e75e99213bf5edafcff7c93cdbbe618ab588df43f9483bb420fd158fde7276a4c68650bcebc5c51b12d1cb00a1f42ad9511b32087f3b6d0130c8c498336c13f38a789958204d26a3dd5ae08d694d2ce02c4919beca140cea5d5498ea8d0812e0284962995fc4cf783b8875b528813c24ddde4e2b9a8cc73240cb1b82f6f67d1fcb29ca4f35eae494f2f52a72d3a813c4df398b1f05ad017908a7b5c217529ece3fd404000000000000000000000000ddd8aede857de69dff271a70ffb356700b534359bf3b927f14e6c48fc48a7695ec00a1aeef1d0023fd397eebfde0f4a9b186c116eab20231da729c9a7b466fb793163d51b53e0c3fcb7c4ead1dd56e7880a35ead458d4a82d0c68f954399273300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e936ae4b72164ddbf1efca88e762f1aad4a2277c351470c5ef1981aec62ed13743f3911aab835a89035534f8e32b88ae0da8a96a6bc36371fbd8d9945c7f2ab6613138e74689dc56cd78a529d4ae7a9d76bae32bc406f6b147dc9644f5bc74a566c3950a667213eaf63f11ae77109ba58172afdc5d71a7d177978a607f5c4fa70306a04a23fba4d86702e317a7719af5e981f0668206cc0740bcc18bcad7aa6df40227c42d68b2ccf41773c6e23c4653668d70c35ab92ca9f84ba7c15ca731895def0b05ee68ea3eec8a3083ccce1bcf631d750cf10385323d67ddf0b87619c96d2f7e8b15ac686523061d1b96281d132b70720e1895764a1ebad228af85756e7b2b0c03087fb9104e62b1729e269e18a263462d33a222827612d59ad47a4cae1636940703002e5c984051ccbe3892b6159c140e01f97a0fac4aec461081fae699ebb2b8c3031378ccb9e79a622093fbfb275abd07ef6eeb4df7795f9065c4969f185997891c03297e13454e2bd36b907cc82055a252b0a51313d65aab8238e2c2938be314af030316c30908fcb24c055428ba9cb0b068cab21ced68e0d4f8d6ad0c4c2f9a88e18376fa0e625758c9ceeae410939641626daa840be32102ce2b0b4b61618c9c833788d4d2c70e09884850ec46d0056595dd9ec6d1da8dc6a8f8ef0dd57715334df3014061b364edfd3966b2e5afe4b88ad78e61c5896ad46ab0fe927620f2b0331871a2c1cf38813c01e946432746d5bd76dcef2523cabfb16fe053c1ad351c82defa1782201bd4a874a399f0dd35bf8d691210c39020d9b2b86decb5809c0820d634035dd181e65601aa82b6c3c9f5c31176c74423d4cec5f9803a6cf02713fde3d83c0f17ea0984f0b68c8a62ee31cee983a30bba020851c3384cefc56ed387eaad1bb3975aacd7cbff8ab53661c01dd57cbf46c4b5fa14bbfc3d6ad2172ee056726a12f9c61cc7f6c3e0c4172e18649ad9bc0c03133a7f95850829726c57fc94d1bf5191ce2e04b757828482228af653f436814f3c1acc8b9bb5e7ebdaa284d2d287fede0376d8e93152512cb6ddf5e39299fc7b11c17355281579a3654df30c40ef0c21ea5f02ffd49b094758b5744ae6447ce81e76539db0ed9dff5369b7dde15a6bb99c7f0f6757d428115da3f837d09ed248e24de19ab4079838474b47fcdf3947eebd1af8c8ea005a97730eed63d70e6a24bedb84178d9f26acbf194b454c73416b4b6de846b3b4f0d695b418fe4fc8463b70728f8a6c3bcefdf804a7df7ea6ea6a9d3adc74b07613b71a2b7543382c2ac31d858f7991740422a575e5eb4c84e30a5ae6cce1267ba4e5e2f9e50a2019cf154abf741dd541b57ebe0b4c586dbcd2c730e8d7791ff606250af184d40af45d2ad134a1d6feffbccff5e951211a930b98e87b833cebb4e189576b85482079979827a7024aba435a6452140dd1bc0c8c5ccc8c34485d60cff44050d67bb91799177ee476d7b22ac4565e27c6d124a8c719f481414e59dfb536ffd1e3c8735c70a1f955a9b22545856d1309912c97dc7cc0048d19ef16b67d539dbb2dbbd607c8f4b743ca4ac795e8761bff64b4393f526a2947b6cad370dd36c641421a77fb02b6a05cee163e7413af871f17a44c6d090b4d180a923ce8fe7425f1594f75da318db9151eb85b5a5b775863e03c0d76ed5bddffb5b33c6ec2c99327641aa77de35bc4c51187ea89348b7d2557ae305c4b75621b8949cf2fa890b34695fd1c834c7c50f307829e5b767eb541925b760c5477a05d57a052d16c0a372901d01f4d9ac9c28a6e54ca37371f4b10407d2571f2cf306294aeffad54211bafc4aa2fdfbdb0fb8fbc5a5d47c81890eda85f71cf0149d9400bf807a37baaa11bd73e3ce8321cf6422573e967ce5c73b5dce91a652dac5fecb04025d1c39ec555c13bb8c645b719a301b39836df6be04d54241a9cee8101650a7692e4d8078de745731e3d9daf00515cfee731d4c1fb07a9947e2c48ca0d75e49730464c6872c27b16b34a8f05300c2c3c3454a4300348dccb0a7ea57b444ec1a75f57089544ce5bf3871839dc7bb859a6692bdaedfd994da91d14df4dfcb7d56d10267513d40b287d67d0f921edea511d3dd94dd76333ab0d732f8f6cd03328aec9410dfecc926fdf585817e5d4b7cafc6f0bf46cf5e7ce23bf1f3ec14b5c3607356288cf8e864380e034ac31f008d4c71f2ea5f3a44b7dd133f3b1f3b050dfe6f70267ee3197e2b7154707e043593b0d2c817d8b132293e588e136741b9999573c74ec50319da303574900000000000000006ba5670200000000fa23276100ee17e970847d30e9ef8a2af36b581b5ba0cd44899eacc1c861ca87e620c5b19dd6519f31213994e3598f14deca0ac7c0f4fff640801c698f5543ea7ae02956aedf0699aaa94672f4f2b108c65621476e7c8148e79955d5a9065ccb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e6ebe1b8fe5701520555f9534c2c6c1f4d1f92a835c974b0298175916f54fa716859c315078635f415d6138bc308cf6887bffc1e9473f959d91d8759fc439af02b7d3d1f8ee5ecfd22d7a06735f981ee8f815b7b02b67cf4494b12480db928b3160bd0a1a180d50d4f76ca78a5c4093a133c9a49fcf3e8ca5bfe535a4e160930325e98e09c61dcdb83e25c93651c7731fe73dd71a50e3cb440a65128a6884a0f40229521e875e600624287a80c2c363f4a5e00d3c0d64ae26e277515b1a1531086f0b059fd46a61d9ad2cbb08d63da04d1501739ff2b1c109a8d224e939513d552a703d4f11bea27aed45f502a01db244213b408f9b0324f1c0dd992b90729b4165f00320834bd1637cfc91a5b8dcf261f2eadfbeefe28df8ad5314b7a23cbcfecb7575030fa08e96bdec8c1d2903acb0f17ff63aadd8f260c01faa4f90d318ab30dbc2a102021714e7b8d5aeceb560661666567d2124931ae489be5dfc20a51ca5d63f7cc502205fb55d9691ec5e892c7e15cdf5b1520030061c107d3447425a4b25eb38f49f02149395bf4aabd9ee1c2df0add4e79db9966cafef2efe8b6726886710eef698fb6b5be5e0c7b5ee2c4672b7798d183713dd21a1dc03e035e9cf41d0e1806638d0c8444c02e749920f458f97b2abed507c8732895ddd24a1b35f7fd6d1ee0b4c9d3666369047956e08327048dd75bbf962356a5acc0c851101dfd8c279520441ad8f8fca0ba9faebfc6ac7931f269adb813c85138a89de6fbc9a17febdac2697bb3ff0b67c2530c0a373ba3022b439cb79321fd6e44cca29e3e0d1ae38eba05a676bf2252fdb53ff24ff28cff11198f2dac13c9cbb2cfc8c6d4951c5c7a617cc5d6294a1204b79af5be5cdd805d89bc0ec48384aa52d4bbf7e7a975a697c1f03aa2fb24dfff429ff40802677039e85932cb5a17f2ca38b65daf921032b9892914784bc42bd83ca5bbe71017c434ae232e04efbd6df827cde6f1dbac59edfd84727405c844c7d88911bd485628390561ebee4df8b3661f44df571b9a46e7b26399b288f73ebbb63cb5961b665c6a9329f28307de416858f953adb730fc05c92d3f7ea6da5e287fff3df8cf015a95a1c2410c8534db87267a4f96c9adcdbc1d8fd23582b8d2b8b0972deb06615c3fe328485007fc6320de9616f9ac9093a14524612a1088fe20ad9793d54944bde966dafe8c269c7f1cbb7f9d5c0fab767fba39dcfa7d9b6f77d1fad2d3f55456da3ec6103de5535997ed1206a1f31e3be00aba0bb6cc43e9e71bfaac2d387ac5ff37f8abbe55438ddcb5544b7082fb7f18b5121abe5ed9a6d5488b1efdb7afbae776d6213642a459498ee6c576c164582b28f12044e99fc9ce5aab8c482da1df7323469a64e2f6eb7301a197d652594d6e865632ddf29d5408a292cd9599f1975fa031525cccdae1affaf9b4610c6ebc7c55e27c598078db308ed55e4473bcd04e79f81ac7d1e291712c42ab71fc67366bbe51042e2741560315f8435fddb87fe478742099b928fdea0e54b1f447ab6429740b47515f8763367016e61bbc24d7028606537454e543d7fd22092be8190d03fa4d3e1a1fa95cd127ebabb199905dbfbde1044b7988c7b10ede629c8a6e7902c0ddcc3044d0c3b452bd1f3c777dace76d0c25853846d27affca244a88fdfb93339dede4ca563cf9697425abc9f620e17795cc9a38a9f7d002cae5b048caa055fca89ef4dec950c145c80059f893c3704aa30730208f3237cbc4de194c8182ecbf18d68347d148e6c5f697bfd0053711d61fb606dccfa4c873f20980ccac40a28bb21e26918dc1f21409dd29478edc6f6f7a4f01a1bca506b941fd79146aa9a6a9c66940dc8787de07153e94276a63f0c38aa5d973ff451d59adfcfac3eebf509ae777657281fe4abec2832affdfc951c331ff7b0cb1eca6d7df3587ba07bd74c273aae8308a132628c55a63fb1b1037f7f8d61f6544f86e0b1fa58eb8b34882d004af7c547a234a61382cc44974cebedc5e321b534f3ed205fdbec6ffbd117f08ae3222e9cc1382aea3ad30564867e7c35e7a60176be733ef3083ad7f8668dae63fd07f29ca8ee459a2e4724582726b27986bd50b33329e92a16a01847017f3e4a433355d2f9025511bd62be2ccafc02e83a8943c5ed16b90449fa027b9485450783732e60c7188a8abbdc6e064db91505df3cb02ac2f2849807d85c64cc7ea35037e7f76c8b74cbcf557e6bb3449ff9d810215ba8c02f126fc5da03ff4271e67b64a258fc8955e2b28d39ec6d54ad56cf7c739a7cb8cd1967d258d5cf4e5d99a2df8a28f2bb82dda8a0145ebf901f64587fb3c37e65cfd6831ca3fdb8dc1856bec90c335b079c6b13a2f1551b9695f8f3217017a8770279e173a00044818f9f99d832e3a63732995a8b145bd273c0905f0a197105", "516563530051525163", 0, 1989934335, 0, "165f611ecf21c9dbd4bc07fc526c7abf55893367982d3c1903ce4d5ee7d99c5d"], + ["b4dd23530332fe76dfe9ba0a6d90d104d38b035e3baa01dfa187e7d46fe5730c0e9c6bec9a030000000653ac6a525365ffffffff607f485fe6b8c898e2a91f0c0825c75f4c0c27f431ce577f20f8c94906c100190100000009526552656500516300bd241ea7fc3ac43b1e85360f222b189ee49dffea369aaf96b3492e216d0f17b2c5e7aa800100000002655311937d400222970304000000000265ac0380e503000000000765ac0053ac656a0000000000", "515353", 1, 423769690, 0, "997dabc362750faa48304d97cbd2975103cae785213f6f702f9317a59438688e"], + ["0bb1213304674222a1dcf78be33c7b7d00723abfd7660ab20b3667b1f4308cdf02ee671cdb01000000056a005163acffffffffc56d800b713a5cda35cb3261eb187be8bab3daa83c079d192498f88ca68114e8030000000400ac5352e0e2353f8eae579406edd13378539c9675058ca44c68881efb4dafe02da6d1907feec7de03000000000701247b75e90f5449c067311297547d3094eb5e954ad2774bf58adc9491c0b406311e620300000003005163ffffffff02e9a05f01000000000163074892020000000008acac53ac63656553000000000393fb0a000000000000000000000000006948bb6594ac0c03b693cdcb4f4335e1ae44c8113fa50de602ed69dbd13daef05d928034fa5da178afafc2d6e43737856a2a49a142d390cb4ca37b546f8283159c49ac223251877e268d1a178dcaa13e5f86cb8f0363174cb3429917db2494ad0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006779b029ae5474ab4eefadd082543aaa653f6c673764350e1411a8d844c37599ead2ee62747bf591c54823fadd61f512933d1c2cfd8d2ac44ded4d299dd6123752bb33763d53927550663e126163938d3a32721988bdc909dffb566bcb055d60adcecdd7db8716dc5d9048f44aa42fce4ee76661d64aeceb8d8fc5d2463e5db0313e9c33b5f8dc2b92d06024c4ca13e41fa7103ccfd1c0e72373364f1d74c24e30206ebcb1957123e0b8817b84c4bf81e5adc58e39dfa3bced6380b5b5a719c5a5a0a02d6b68c41f9e5001b395e7357a0d9980c4300d4b691cc9229e9ded2d83e3e7d011a8c472d7e167053b4b2c2458fda8ac58e6c7cb0d2a04315cc1060f44a95ab020e04d07f63f5afb8e02b945ac055696556e853cedaf13e758c447eab08e76a3903208f5e3fc2fec09681a79704d55551404c0f1c4060a11dfa4119c7f909c5e6eb030420b8cf59e3e3015e99d535b78e7c826b2204187278be7519dfda3bced5d9c302295b1061f96a9df93c954724dd1b385e2afea2adcc03f9f66c17af807fba0098032ced15d3e9ce2423c22b9d5e4bae1b0f5328e6af67ea452a7d4936b92f3b350e7f0797b9eae777e2ac7b24beeab1390c739e46fe0c0b3e8e6fc2f8c7f1b527c50ba1282df9723955f564d09e19f03772935823766178aa31a77e4af8e7e64b13fb4cb2a86761ecca16556d1a03610287eb79a2dc1cbc53a76837457542629cea69029a9af516b84e0f013ea22cf2ebfc40569ca1108816758c54ee17c4e3d9ccb560878b4b03132c43b382aa53c757f82fba2d1d67675cad73f5c8f85b63237e9e3af8772e739db6ea832818b1303167e8e58c93a0c1b82ce7a95591499b35bb8020cbd638494895f1eae229ac3c1c2939b625ced37b793e71084936db94ee779125caac330b3f72d5e50c24205ec365e10fd097447cd610075ec8d3340616ee5bedd6600a419c173f4cd4a7d89257f90d684c7deafba52b658b49a39637da6da0d92f6b0d636692245b24ca3f20d32018a09ffe3fa302fc65b384f97d24389807f88ac77de8f354a1a56379f667cd3dbcee11362a0e30ab219c5fb5a78f829d4a167751fd0d35a3e286c90a1e18f97809f1167794c67d73b9a189919a44854d43dd26f6b1aac13a2aaa5684619c9c75f3dd5264fd976062c8420c79f92b9a84b5f88480393bb567526a3a78f6e83cd74e6d9a5e95cc32d2693c56d9c47858efb7ff6053eff67ab8bcf0d8dc447a4e6e91e7bb82f290bace29a50343460ea44c27720daea92e74d4e946761b57dcd1068160faddb96dacae23eddedf4e41c8efbe7a1af68defee9947113890800f76d714fd6b57d4b2c2fa5ed054bc8d87baf2d077893e17d9543a28de0475901d5524b93078456710b84dcb7b39be3a17a117a4936ee0199e9421abd7e3dc7efe12ff7a6ca3bdd04c7272d3dee4932e83bb1051fa3b416e599d44dd422f0e2a9cd2170ca8c960ad719f68bec14da0eb574d1dc76c014996fc85c5bf6ff379ea034c6abfb4483b8a35808e68b33af50b41fe6b79a3e6d2e279eed46a06fda89c0a0e306eb5f2ea6b73e94ac6fbe1f4656d560f029a4e5e4a30c4d6af4a6a695dd91619b24c0f239b73122f44868d33bbacdfa748fb47aecbf1796f7dec38ba9089821c4df326ba4518fe955a82e2f2af8ae92f02f936736e96473f511b3fcc86dbc6a458c952c384269f3b7444cb96277726a204bb1e4e3e8052699488fc9500f4f257d3f43e95cc3bdb6efb5af689be200ddaf8357b80416cf5c66467a326bf3564face99492174e06dd4a53510a7cfd3e9d0ca10dd0975806b2e6b2240081d63303654075bc84ff70dec00cb4fe0a5f7141853189316c042206cb3523f93dd7683747bd5be42fabf922f4b4949443e2de77e4268f7d1b75015dae58401ea20638f701ee52e42a7ee06d0b1516d0244a9add4f6d581643e9de4b58375d13835063574003d3908b82dd61b98dccf0dc5f9b683da5356a83c99225925de16bd04e94a88408402a6f030e29df399d0515f69efafdf8db5c66b261b5f31cc4d7736e31a097dfacfead19f9ecbf53d522ab75c65eeadfb5f9741b6e200b6052cb006cb12ca3f6beaaf43f9353a399c6c4d90227350693873f190afde040ed2bc8e9be7fe8992b344452612be6b4b816ce44393866d89e6520796262efd45b1915c0070755bda8176c36d0282e518cb5f2a3f69fb9444c15e53b0e773451d0f6d9197b518e17d27fa7a5e1a68d5a3fa29e92048269d5f84dcb52c91be6e87392151b2b0ae5342a1000000000000000063f6a10300000000c9062bd623acdb0e821651aaa9714cf6afaed8d8b5a16cd67f209059d6e27592543d22b7809c680fe7c2d201b4d94770bfda7f3af6e289236cf383500b3472742216d940900d09263c1229d8f65fe1de656edadbc7e7f289f38899cd3039e07f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af42b0586b435cded5b945072f667be1f75cea6e6c7989c348441420e48d1f3c8e1909c55fc6c31a9435f547aefafe9495bb2b04fa665f8e39784867e03193dd3ec3b77548b29024d73d2dd63deb1239196d30e94335ba286970132a422e544b29cccabe162f1d57013288096c1d38f71ac7cc4c7fab271878cc4b4f91a0b2fb03030f4801308e627476761530da86339bdf9708ef1572fe6017dc42d573f8df3c020af071a0786b673334bc04268730fb76a2581c3a257761c36b78c32bb776e5d40b05e3093f7124cf37dff11d9083609c44e075f4af1dcac95e3d5b5ef67a42e375f76b0722d40422d7ff82eaffb0f2fdcc8cd4b59e09389232bfe0f286e02e216a0208744ae1a602c6287ad11dc5e307b5eb90df277df5115a40fd5e9e9cda7618350214c5acb50df817266634ef4b8047fe3b1f940501c12613aa70d9f8a2f6331b8a03113e443245324c8205fa4285093da6ff071798ee2888c5a545e5d719e4b8f5e3030261aea7d7ed39cf0cc06320ed78f86cfd037674a7216971d0998dc8e1c1afad0304a027503e3ba0e2a7c43913807c12de435052985ce7b8a9b4e78d0962fcd1107f4a6b70d76a4ca8944ff98e3dc2aa3211ea7788a3a85c7f9eead0bbdb864bc895c4ac7e93ff9fbc7c520854e09a2faa8324e556724c1d2f6425313f0785a069fd7d17b1ff976cae26411ccac48c286917e7d7ab4744145386b2c8a04e649c81dac40b2d8b5a7d4dcfd3811fae9fc4efb6c9e85dd0d615ba5b91b1b221f397e3001e2917ec3a1f92de743a49c4bc561efd1fef9fa71669d8f60aef28f425fe908f4818e0d1ae2f890025c879acb4fd65405b4356be438e3627d897d5937bb2f2aca61184418a2f8ec9a26228fb84a659ced8bd8d82b75139852196e58af2679ee82a567b9993fd9df26b7833e40a7acfe390c6336f433b939c1d7aa3a397309f85f1717fa070f4a7985dae31a6ae08a4979b675b09f1083ffae8d61e838f4a7caeb51c5b5ae659fa07443eb05b3452182579c5a8990b9091f0abaec7ac06bccdfa6e2892d4200b5582c069f287ea126ea1e10f3316a8a9e4e05f119db85ad110e161b152a3bcb656718f4fd0a641b8953f8e5403bfe333c2b1ba7f5a4a762f0551cce3262026734cfaa7087e39766e4fd3a2b25979f02d48e46c8465f624e563fc28d959dc7c74738cc41e397950e3db8b7acdf13485052fc41baf11137377a20758a67ea1b9da7bbe09f365c9c470b7bdb33460b4d100d1e805d0bb70402270eeb4ea9fd655b8e038fafd995017a504a5882ea5b0f85c195189f10962cc1f5fa5462c2486bcbd445ba2acf381f106a431eb2051a397253174cb0adf0e0147be1a3eeacee59c9443efdccfe311636da9df25d193e4637380cb284fb6716efc1eba2d66b4d54af1006569bf31caf97da67c8e029807e1ab5edf058d5d10b8c495734bd94ef581d4864a7d436613067dfcfacb9712a3485006bf3aa1aece95cf93a898758b71d5e1a5947c08ce8f388d3df487225ad7037bc89cdf176af9f8e283efac7c3ec2074a028ffa1419fc496a12f7cb3638ccee18c50bf1065dade437e79c5d57de787795d14ed65bc43ad9e03515712fe93f89c7584127bd09d022da1f865a83659de30a45f2e7e5a6ea57fe7d4be20fa0731aadd5ae1c12dbc34cec25730f6f7036f6947c42b4142a7b5c87257c3878650db5efee096e7c95522d07ba2fe270a86d31c867e77aea6b845e5e8a1987eba0018f513a773d702317883644553fc6c09a52b55a6124cb852e6921ef54a799d8deae64be104794e59c224eb1b50568daa4d910697a86bc1ad34bfc6efa11a587d6b377100117acc6b5ff99815bfef97c1029eef52a8e3638940dfe64b09c6d55db64e7aa700ea784fe7b8e8e4338a9ace574c3fb29db97e6362ef86b44d60a29cc98ad5e6a16b0e8efdaa48b5c8b14451140a47952fc74e9a21149487fa27e62e324a715f25e0cca5753b115327615d3cb6d2b88ebb1a274d7d6a8d037e5469573ba038447fecb6a69e2969ef4e16358fc14cd9309902eb8c7ef48bfc7b583606f375bf0ef520ebdaf18443d1c15af88386a5007d727be106d96ba98e886f74109624b4ae58628973ead3813af24480b07719887b543115e75d92f1028bdb7eeedfd218b79a311a1a4dbda55f60b38f42d673bc2f73bba96862c1ddd20aaa5d6a67ca7a010a5ff417e58b9d597137a86a6ec08dfa37465a68abba8b4daf74c5b5b267287f4c1acd591e3d17abb4efc7cb5e933399539d96084da696ddf9b0000000000000000c2328e02000000009f7829c226e829379977237df58d98d89cefcb7b6eeacc6861e3c3aa99c6bd00ca33da0051956994301a22ca056ba4bf4a656070b590cca2f408ec68f3294a91b18cca05b49f7a49092cd6991bc7be664ad4eb42c64ae3535147d995d59403c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ec825b5dbba8b32a8fc3689fdb8ea3f2445b752ba7e4997a89c810b4cf8cc2d908e34805717b2fe12fb58d9180b64a1441bbfa0023c8d8af70615d197a85e9b39c05c0ebaf60887e7940f0ec6a7c571cc45020dc700fcf8bc4d413620c81b75edfb4a002cdf157323951910aa21f4483f2c9b46738658b93885cdad76c97945702143954d90dc853f53b7e536caee0ba1f7232700a05277d26ce962f117d022fda021952e4a55ff7e4441ef6399f03b947e5107c53402d8e8e31a50cd4082182bce10a02aa028d0c45b69989acb77544b8c041faca3154286568a57dc4c1a18844f5c3075d5da740097303ff4b9d9f53ab616c1deeaa1218fa446cd95cb9c2e37b96dd022cc0e2426a2f624211aeb385748876a6dbf6b1dce2c4767117e0e1b461ad45e50308db31c2d44799ce6a0d78e5b72c3600e44123da6ed17e99508ff64cfa77c7890226b936ff1018a3eb545e65e3ac22c555beb4e984784ad585556f2afca3119511031130c84b2cbe686de21f68fc3d6eed85f4d90fb1eafd7dad942ea16cfc2f44fb032ab8a627b477952a3c473e71e593911828c45a48f26aa80403fdd48da182ef1d98e7d080d81453a60ee1de05e4739e457a308e8321c83db7d2092434b8d398a02bbde0d94bed578790a2741b7bf97f531b4294890a20db4661ecaf99e7aac7ed2cd52474de4457d99aa057a6ba3bcdb4fd2fc553d1398f336227a4e9aa3620943c644f21570f259cf91dc26b95f820aa2528d37e58613a22ffa2ed665dde97929ea97d143690f2c3a5562aad4bb765770f635305720830e68b31df6f4b1ae8b14a30e191ae7ff5f23cd0ac0eb394c993882e0391e1a934dea878f5cf93cf02fa14ad0cf01015262e2143d39da34d7612dc0066dac459e0cca1c9d6ca757af19088d3b33e32f9fb75164c11b18919a6783ac50786212cea717681cbde88f0c38e2f0aa367bec21e5d96d48a60eadf9acec0939f35d7965cfbebcb95aec3521e67cda731d13e0bf5a2aacbb1975876f038e2dd70970d9ea7de565d80b3b7e3e74fb866f0c838f901d17ddd64be0f112e951905ba1bb22b4140756572ae2ffb6ed32f33f865058e640b52060661ace03bbc9177874531e87addaff1aaba6aa47b69d0a2034c425ba9ed125fc223b42438af37fdba3ee5fc871cf06b3f2fdd55651813651ab3d5eab8ff310322292defe7daf01b0f3f6369127ac9b0c22b0f9f793ca3137c7b319d450792dfa4275a03ad74269821d4c3b24c5aa4697c3ff49393fd52fbfb651aa77782e79c5608af9d69aa8d9c84ae03aa90403185cf221ef3ee0f1b8a04682186a09e260a7c9cb402ceab0004c0a6cba544b106309f86531c90db9d1cf5b319a39a36f068f9f0059ce225af2eebb743dc1bc33f884e05b3b633297394572619c13a17da1a3c72952da891c56a9d78db5855ef06521d5a0a6af9619c27afa4054538f9c31cda00886f3e10bd642df628f2857a4bb581a96ce5a4b1d0a4593423638b7637ac88bf948e711364e0bae32ff11f13c20db1904a240766b0900fd470df9244ddff9eb781c328d36828af66912961faeb3c9be1dc91ca09d4924a50d6d6c1edb75c2a617759b83ffd706c2b0cb35d81861e2416aea48e61714415dacabb8282290848e998dc9ceedd1e0d08308d2badbe44ad287bb16df460826a8c7ae83c6fe99f8a5ef521f81d30625877698a93edc01476b41008e3cc59c37b5dbcfed19f52260e5a979ed6e95b35449a14dfc7086ff2df6aeb3758749ae0e377d87ce977ddc93544055ff499541d268618abb7b8994326bdee934c9046b56a8ff16acfb3122cecbb31df9f27a72ec016f63f7dcfaf46a42245052780687b668a0ca90915c07b78cba345a91351ff3e6ab6d5cd20274f2cd062c0a641bc894d6c6980f18f6daa302f5860e12a4edec5bb0f9c8185b5884a7b64f83b60e4171f36a121d85444ec2f6be4d7f0f2ebe7b0d765a703653d7fe82819b562cc4f344cd3ed3a33a2d7d6df624afe22928156152824920e3dbc3db6d6d5e734dbc7abdc729c51745b1f19056f06dccfe5dabfaa45f6a581237f2fa8cd9c4762c9f3028e597c586e0f5f44607b269611f4b21c570850be61eadd76a1e43bbeb8a4c031d9688fedbfb160f5b33b0f81209bc6de188dc7b2d5991bda2005c1f52b223ee650d6e18b77d0e9025000afcfdad9502c8055afc690113d2d049302f5c87f587882076bbdb22d138f0359995c91a0dfbc73a93983520fb50c8f4f598f56f91465162ee89e6a30185da931206cb3a8bc0f7eb6446e58fce5e04316f5eb77a4dc4b4a7906eeaa2b3ba948c3883dab4220127ce018b08e4b341f6132e305427552d97362b7b9ac331f14ebec61c65cb980dfc36f5fb2e9ab18cab00c43edcdf76f61b3e6e03b0784578bb22698e04253b80d", "", 3, -1282780702, 0, "29534f6e4cfd75e2ac1cfc5236336fdd3efce9f621a651a3c4e22feb350bef98"], + ["030000807082c40303cb7f7f0424bb532696a9e08b08db91f83e94d6aa801b8ba43e3d83daaff8d3e0010000000465ac51ac63df1c170d501fc8715ee5aadaff334b972d049af826733c07f7db20a9e6b2f25d2c267b0000000007acac6a65ac516affffffff294ec8b48e77507be6a762f7bc51c3bd9015fed36bcc14f8ccd159155a7ea8110200000009636aac536a63536a53ffffffff03faeb32010000000003636aac1f505c01000000000552005253655ef5db0100000000056551515352000000001ab9e645027f3603050000000000000000000000003476bce1006fc53fe8b757e2f3fcf06793cb28ef4e08e0f011d66ac981694db7abd515e2a2f00642f8c25bc9024bcb46eb6fe751e97935428d5c610f4de52a97f045923635223b1345ff5faec43e588839bcf702c67ebcb8826aad4dfc59b9a90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034ee4d0d34b4d79e3e777321a5159eb13c1eb93e7f87a821998dd4644ad1f64fd51a1f27f937613a36474816074e77ecd45667b2e0c8518602efb2eacd3543698754b4fc542c7149e070603f4081b8a9b3286258f7b183e1d391beb877b76179dabc45fa7594e9f87f62fbfcdcbc61116cc004f280936bd2947475f259d1bfe903088810463ab0152b7defe7fb25cbe10b38645225670c585610750529704eef9b030ede89175b4ac1af5f61ace40e25181399ad5ec20e960d1de0b6ea51d99e09b50b06ed38b452f07c3dcf88cb91bf300be4219dde4bb8e3ee7513270fed8b56c366c1c287bacc94929873e8aa1bba818cd20c9c4c107cb13fcf7f83d36b277a3c4c02060c317d4bfe7acf899932f0608fcf413bc551b38689d199e1376fb9cefe827b021c3414450a93f07865d99229cbbb81a22ab627ee7e4386f35789265a50be5e86030da9ed6fb8aa7e8cb28b9fde8dfd2da9780b3904e58be0a67b5c72b7aaee58d50219899a553abca9bcba2cb41635d4c9c61f97e4231bdc02f4fd19515675306405020eb6a6fc423b32576876a34bde39534cbc30d4a280cb84b933ea98f598574f0dae36ca1043b0c46b483594f779b87864dafd09783a7eadd57a7ea86d7ab068734fd66b0a175351df6dfb9382d67412584e3fdf99f4b4fdca2428d502613e33c1afabd1de92ffb4329e70c26370d382241253858abfc41a5c4b3de9512734501cbd13ef6ae25b7effa8b7c7222b9ed4d39672bbe79ed44722543139a8875c2a340b7ec700d29eb8130e1db44809e31b914031c97457dcc70976c488f8de82b840e3f25c1fb02380ad12b23f8c878e1d88ed04b58d68cc4e370ad80f7a7db2d6de48cbad80ca552725c7917bcf36aeb9630b15cb030b1cf3edb58977d3826ff734350aee9dc3fc4a066d13ae123454c6599702f2ee12e3f8d4ff3768cfa62b619f7a232e8e84257351bdc38887f64a763a73e5f1330ca38abc0e875c31bb4f9ad678befbf0ff639633d5e1e4eed6bf770be952bb7a8ccb48db9f26d98aaac05d6392e293d29fcd6f61bf8403cb1ec75553f7b6106756d5501fa3e6c2a19d347a0beacc782073da141d3dd1adba19baf38a8601be9b7289b2b057a729a4726728f221c8eafd27ae368956e09a4ac7ffd0fd21fda87454002d6efd6e81a0de81375048ac9544944494f4da0320acc0445d6a8f2c2a30cef4794f1a85f47e0ed05f03bb311839745af065406229a830883a1a9f6151cfad3908eed75bf8c6d147a6cfc057d8da56a114be147f494c68d2506bd283d468014a877d1c4f8f0ef1e85b72866bb1df58376724b3b3a303fcbc8bbc8a4bd2096056fd8faf5c33f4c1b7bc378c860d22407c6a006579618b72ea06c808202ef47930f415b90be86f26b9cbb8b7d755cd590bf78cf491baacab39f5e45abae9e6aebb354f8b16253d7ef14ab310a8c5f231fc61d906b9f6abc752f947a9fef803a13af4388a25ce7472cc064f7882211294103bfa907a967bc1403ac4005b1c393e00d733a9d017d999e23a246301d750ebce3a0f7d6506799d52384a8729a50fb788a0ffd5db224ad92f6f128267082574d9fa61590f2ff233ffc4bcb8554dbf126f810735cee520b5ea94e2cf7fbe39a1ad28ae879b11c233c34effc5efb085272691dce730ab116005f90df34582adc7313d04e3e737cb1366fdc4a88740b3927f795db604836824297a02dce55102ba8366d3223cbf18b82152a718268892faaa20fe6ea4c74e65b91150e01003fb377955ef5425997e266f4a271bfcbe76624a5a0ab650cff5f7c098a474f4727429d75de6d134f0f2186baba75be0f0f1f9745920e73bbffb03b554490903039c64303113f2f59e619dad6a6a5dd8ccf60d8e2effcfa350cb01b93e05b5bbd17c1301e7602c187468ed81967f3889f09536141cd0554e67bdc5ede667ecc60b30675d02f8eb873f7eae06394369b7325a5ebc618b360ee35193fca317f9be66a3f0668141dac9774dfcf1b798d50706d223a758fe12d54e838c1546e950e5c4b7ca1beb7f26741a2884660f9b4f6bca2198945f0343e8f65247542a6438869e54c9ff907d8976f5d5c0b0b9848ee62990b4600fffae72e69ad98f67309a62186591a3aeb8595056c8f855505b5d7d90a1e560f4abe37692d4f601726d5ea58fcdc513eda2f7d6189c08ead9c15f7531c67fbb8b14e9ce5dfeb411aef14444158f579bb2668b8ad1de519d65e0e813aaf8c4b05d763bcc1bd00d4a9100a06544171a82a7496e4eb60a6ab6ff5f74d8420483030000000000000000000000000b4284f3e624a3eb35034ad24828f92b65025c7b43dcca8c76ad779299e2639e54c69dd12addf41c2e5d44c1cd6bf358df8c9927d465465a63ba00d1c008c539f98193e56eb94f5afb80e1632da73f097cd6557d127b87f4bd1e50f207f19a4e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bdfab69aa3b3f967f68421584195cbd388c0eea53b344a97f346707ea3755c4c7c5a49c3bc87df0114d376c3da6ddb375b8b4c211a97fbe19ff7e694304b9d07dc97c06e8810ad47c79d54d94cd05beacf7e10b9ca10bad260955151324f49df1daae261954febac55772fcec483f648283234f786e1c1238b93922487be8c110316f2e01697a6d63d8c5d39516ee461496b7fea072da5281ede34b9c4d17f63210326ed426db6413753d66631d4e8b762d929c8ae0034e637199d6a1c1715b658970a012d7c7a64a9908b7fba3359eacc6eb878645901eb2e56e7c01e28a91827712f3b15c80fe94cea8a2db9b7e504f59cf1f9f94a45c6e4ba09682cbe166cfdb724022c2fc650501d3537dcc9435bd4aca73079111bfc02986e3e935aef51316bd263031c23416faaf4482c4078b772d474bf6705a20e69a072aab0b4ee30d0489ef9f3021c5e8d9944cd5c284302b9f85b32557520ef8f1a88c90b20e2f5915a58efc1e8022a86ac7e942935eefcd54e50995a26a98012673a74cb9fdde899450e55149fe60313b2f588a00d75990c18c92506444ef52d9db52094fc313e8a7a0b04b9c980f0cc39a5c13e126185661f8114fb8a906e748528ac37da897d31943a794f527716667eb25399f12ee1e6611414d50d6750c494c8f804cc228010be5cb8ae8f7bbca1c9b9e78335c987e5fe17f3040ee82e3b8cf0994d7ce778c0cd2ed9d941563df5cbe1fc765d4ad3be58b39bcca2f46b2f6e9508a0d9d26cc1f394d5490d7aa967870af100af7b158f58c0c73bfc3d380cb83d928642af28eb03ff6620fd0b5a8cd2841b33a4be03e1dab52cd5cbb01bb01528dda9c279d1e4c00d0d8ceef7b9203daff9862cc9cb5cafdac988c1a9b4490e928b6a25f575d0950e9ac75407b106c4e1fd7b8b257581e301c422407e612c43be1794872cc82f02bbbd1ae839520f2116a3b85ca09a8b2774a7483f767048ead89263b51fd4455b538db02e2d2c36ce61adce8d33ed54d259968911c2a6e0ab53606eb18b768fd9b752b77929c5fb7b3e11f2821d24d39d944213e8afa3e9b0ae1a2cc97156da2bd1a526801e15637ca583cf6b4c597abaa7ab9805b7dab30274524a95d491c6a780761587dfc57a6b248ab0dfc6c0194fa2c7ffb526ce1138dad609ce19d8e5574bb0e37b6c78ae4ec3d856d88f706a84dea479d10883dd6ffa76b040c7d9d21c59ab0651314fe6755bd32a8fd597b74d91046b7e930a02b63259177ba633634b7fe0588471a5eea2458ef1494efd74d145598299b366bfb29f67bc9ac77753ed6ba54e7b1d300d3c6e084064caec4a8c241fa6d318c28b4838a98586688407b5dcf69eb1ad8ef055c46312b28bb59826aaf3020c0728ec737171643c82e29953ac6f5d0209fb7ade56b0206106b73eaa282543e398242bd62ebe9416de3071258bbfc76652abb9f22e6e92cc5800aba539b0d6a474563956ab9a1924bfe19bc15df4ab050273ba75668a93bfa30c725949ffad84f42c201eda5f1ad2b7a8bd0e7cf7fc1793dedbdf2bf0eabe03775e5214a1917ed8a20339cb70134e81b93cc6ab14f6c55783ff26d0f66aa0045030c547e55cdcd7df4ac70b1a1fd7d30aa39e0788fd6c6841adb85ab504e1442cc995365283034c97c856ffe64009700087f0a3f40298e83c6181c3c6af59d91e949a026cdb2de0f095a7410f8fc5891983c9fe9916393e3891e0ee2ed1d06bf0ecb5918ec6702e7d63242acbca7861b0e45eb9cdd1fdaca016a8ca3c96f4754501f14e752f37fe14c2cc749dbc0a25b4ff9b5a0630adfeb354d28f5d8a6324256f78724acf0d4004e5e6da20f45b8f6ddce00ae3504ddbde17a47270a7a613b4facafee221737f4323c7343d2757441f1ba1af440a697a361c5391bfc3bfad415bbc1deb095451d93aca4c33995900ea362e116ca40fa5836720d56bf91d63b633a40de2eb64a4507ba12274a81b1346ddc2b7a7a643f91b43f4f2bf10002434df4e906d5b539393c587644b186bfee5cd05b7d3aba6165c49f4b194f0bfbe8db9a52fce3a19cc50de40337591ee5707518dadbe4ac5301e270f400e1ee6a9e153194f28f934ffba236bccbe57927cf49d1312462b27c403f538bdccc77fe910d0ebd4ce795ea1182d6a0a4baf8da8e7ed57649d2335578921bd7b2897d37d9dbcaa22693bf5a222b86e97bb3adbef524e337b49a046e33b826256940d13a0fba69469940329516aa3a5af4c592e7db685bb38a4c38b55130b5ed58c06a70c19f05d1e00dceca0f9029fdeb9830a68ad5c45ecdf1d7f0fced594942b033dd28b8c626412f86c070239a19ebb85c91981053ff58f155ee265d766e16f61f720fde61c2c852a9c4e675752bc91a8d64241afdf440b19589aa36bb5bf8ba884b56a73659c4e0208cd22600b", "00ac63ac52", 0, 1260068403, 1537743641, "4e227597f48b170274c41a1a20f4195bfafd24531fb400eedf4ce09cdaed9f4f"], + ["030000807082c40304eb11fce7088f604ed9851fb6c9d519e130fdd647c8849fa8b619d1088d8e412401000000026500ffffffff893cd3b1270063f0aaab44d3545a304ca208b78d2b35deedcfa0cf6d4aa87eec0200000002ac652cfda3b1c76c08255cbc4f89796c58cfa6398cd34830c4b9e324b84e2f007b42b14865980000000002636ab3868e1dab477a69d8b0d09737beeb0a293a6621161dc34956ca4e9e535487908d361ebe0000000008ac52525151acac52ffffffff038aebf8040000000004530065005932910500000000095300636a51636352ac8269a203000000000353520000000000c97ed666010000000000000000b880ca01000000002048f2e88d7071d211045beb4f9851927373c9762534e6ccaa627605aa6d5cf03adad49cc6026722c4d93cb6fcc4f18ac5f29092037d028a366341cb734adfa03fa043982edd846217f46c9e72471c1cd7bd8f7abe81c716102d40bc0e4e61b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000430d9438239318cca110cbd5d91142b8cd4b5bb4141670c9a303ca9320e38305a382bb8cfb25cf5579a8952dbc222d8408514d2ca989f7a92c81e8b6e88d585e841b0d7a544172190c3ea681452ad96dd437fe396f1b7e9097d577376ddd60aa268c9a4193b4098c4ce10bb3c973048505143aa224f01ca983e4ee5b190a3af4030145702a5d36a081eabaa24d09e2a8d1b38151faeaf448ae47e9d47f20468cd202275fb5eafc6226a9ff7f89ae75ff8a3889b6ad6332b11c3e8aa70dffc914186d0b07f1c1fe057fec1d401b25264400521f3cafab7973124d2f37ffa51a10d4cb630db057dfc4be46b9661bd46b58ba73e06b08b4301ad45d54044284d43f0c30750203ab89eed50f7ff137d1dd6edef9cab545463f672a024a5694eca610235be8d202264208ab38eed22f8c6e720c3d81184eb059d9eb2a51c5f445a7108814411f510228f90e14729f28fd7c6dfae647eb6e7ba39cf41c8cc1df69c9740159ebf3b354030e25bd7b4dc4f2f789fd8bfe30c5f988fc3ab9b29e34cdb148872533edfdf2580225378f04ad4130b64605c647f1eda41467c4cae51a94989c861a82b21f8b334bf1735bfa383bc46b7db6552be261b4d16449ea9d4c37952f96e56faa77fa66612fd0f96bb9523b8a7dee197fb6a35cb228ed79cce0d0e5fcc36a3184644887bc75d33f76dcfb77805b51c77edafba5996b4e98ff43f5fd2924253eca3b4ba111f714e3012f20ed3e2e33ffea98a2f6aadf3d5edf3c637569e4645166f2344b6ec5f104d379a738683ff9b9b9b60ed899e57f503979dc6a5cae863f2ac59ab5a806f03d17c242bd8201b1abc8d688ed1240be08c91fd50b7a286ca44b97992b82f15636db85bfb9c84c43c9f5f7a6f95970ecfae7755b07115955b2fcd1479425c9e109d7de525b071dcdd5b30c706ff3b494b9105c4d7a062e770e670b2278a12d3024d5592016ad7fb76197a9227b131bbdcb2dc8d25422283f975e7e465ec950f828d52b8f52815364fbc531daca42268b61b84d656fc76856805fa3cdb5ad339f8a45f03a3cc07885f4bef7ca9a6a76ce6fbba01de6789c2c45f27f9908bf2def0a8476f359944f3e109b30569f29d87f12de4cc6337a580b64ff4720e58785f06586cd75a08ba6419c6588ebdf7696a099a94c2fb9bb27481c3e15e7b57579444dce9027fdaecc3ae12b5615b03c9c3e9e9ac04d0c09fa812cb523996c7cc991df0c5907d932ce410f5ab1331986661cb413867b398d3aad720296c970b96b983759cad28025275ae1641ad158c486aee4c50f3873c2a72e46cba3a95035522b4acc877860c185985258c4cc003256c6681379f792a2d603b84ce12df85a89541c80de9805c9d43fc05b11c4edfe41fce314bd2406686d4ae6b305cbd83f96120f6ddeb3f367ea3a8c0e337a250a59248d23bb565dadb8f736277afb060a459b6215e48c1b75cdfc5a8c7a16aeaa6841b10f326b0b9015aa6aed851494f3b0733a5bec4ecb39b69e7a34c5955b2e90966a8925e5c9c6585a7f475f2eb11b6b8128808c7ad8304b93e7bc7a51a337a0c0a1c518dbfacd2cf3811e807b1fe041af54af2a4fa2d2e61515411456e4d3399c9b246ddaf8db590b58efb24bf9ca443573c41e1b9770bc877b381fa00052221c78ff525ca53082fce737b1e1b42678e1a78ba58e41631f44b69e8b878f3068da10ff4024fa8471337b0c0131a6392d10fa1ab562008cb190c00c5da7d327beeb3a6e778c348f66dd9a5e6932630149b5da6dce78905b7efde5191b8e2984efd54fa6485a8995b47cf98a11fc08b89901333fd5ef3b4ef4f10f8af619d71c54394be9c459763db32f1b9e145e4b94032e0f68ce8ab3c2bd8b8b66c8f6484059afad0559aa2e0c3dab99331b011816eaf6c4e78cd8618812497bd0b87fd9f85c2ad6371bae7a5cf3d352e2f4e53100104f99651c3c539b93ee1675edaba1be432598545b6503316a245c751d3398448fd2c25f0c64263d81b0457561979e3e76788f7a49d0a9375db8955a71c642ddb2a4960b6eadf9cdc35dab9955bbdf08409ab29e2301efe091e59b7d81d98b56ce0d5eec9e2dc468ced2225a88de6ca753b57c257a1ed04df5d77b8feb19d4b54ae6146703ad3f30f3d876f0eee82b298f6ea260fcabd231d035d086cc7679a69679d9b0e6f0b3f362e6e05e78f59d2e4c3009ddf5e78cf4b7a736eec2ef3bb456026cb669eef97c7b6bbe8298235a262c412aa0a85e414f4a3875239e92873cf408a3083a4f4fea13a5d2cc1e670d374d963c85270397646570d966ff8ce64249908d7097d126687cf8bc6e2c188e09397ab2322be0ebd83cb729e6a362c75242537834748ef04fbd4c2936a3b837a408579f5fcae5596f038b56b609a911ab42d89f8f77b66dc75c5ee36ce7f14370d600", "5200535253", 3, 53398968, 0, "4185196f4086ebfb114b56ee364570361438af19baa7b6cbafb886bb41d979d6"], + ["030000807082c403049e5588c7ecc09d34bf0562cb4542cf2a9e196498a6e6fcde94de7aeaa515254a020000000865516563535300acffffffff8e8f39171b5ffa2b4116bb87683ad34bc8c40a5d9fe709ff2b81e2480d7861e1010000000300acac32df8622ae8948d79a3c5d12a3b129185d451759370ab03ea188760ed296c9a089c0a1780000000006655252ac0052ffffffff487587f92787b5661bba83339a48ea93a5c1d1c77c8bae388ac157146eabb62d01000000056565656aacea09609f01f251a8050000000003ac51533753cfb8a556886e03c70c8f05000000000000000000000000cb3590f7f10d77db2566921c6631471bb63a47e65a23d2fb44b3e3cbdbdc8b5a441677685b645b76073f5f2af5ae4e2834c175c0c6cc038f43c4e4c33251e5d7b43c2f5c1c8c0211e246f89df694129243bef733f33e39c2cd95011a6b0b7cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c855a474c1b46f50ec509c8d065071d228c7d73ae1f48fd30af60ed542d4ab608987ec60f3462d37e4b9a0cd1f420279b0754164f0462ef90f3386a388463677b08396c5415fe27b14707704f860625cc25c274c669304a0726da9a7da1a7f5947ae6b5713c8e474a34e725b915c67fcf84aa9f0958063f988dae8dbdb73d34c031e4f97073ba052961d695b3ce5985065ec6166356d4d56b5b1d367a7eda144f90216d78c4b10984c74bd46dc5ca0dd571ade381e508fa46427981d5f4a4263ea340a01e0e72dbeb3b51284d6f4a911ea53b7ee0cc6a72d72653ff1203f862e12f17b1c369cc3705671099a7a3625de4ab22d2e60e5baee763dc058fee359f143c03102156b2aafb779e6f59191b9f04552d427531e46a8419e931a1bb4c67817b3334e022111e01e1245fa621272c8c72ee73b29daa3d2dc32f3837f41ca2a52a0a0cbe30226ccb6777e743dcc2f681b8e1570daf0629ce67e6b0df642a2558ae890620534031d6c86b806bbaabb51914f87a54b0a8b5d94f124609065298890351ff0751fa2032abb5d9bf4ae139de11648b3a1e5fa7f14380180da87cbb0c6d715e9fb526998d7e4adaa3b1692ba2a7b866edc16ad8ecf62c449bfc62285c8c83893e102f8ec869a49c623373d379f61f3ce53ad6f9fc92987d93aa6422da9bf803b675cfa64e7c7bf87d661d07163a417cd597ab206d3410d42ebc82b3d019d676db318d3e1eabd7c21adbd89c62c69eb19fc6b21fccf1a326af175546cea6942231fc469c6b11b3e47ec58bf44f20d8efb69e6c18b177a633e0dae0c4d9b4e568100705c76a1e05b17e415f16494fbc3a8505bd64a0a5c1ebe98d7882d2f53347e8e0598e79fcdb0e8dec2f1b15f36243208c4d2a3d8fee01e73dfe7d6394109663b40c58e1e387621b5ffc48fee473eac6e6b86a01631714347c0d4fea535744104a6a45be26f4efb4d09cb3931fba2d3b3af5ae87c53470b0f4972cfcce75af3b1df785a3037ed8fa83737dff4923a51b955b811ab6cc2670fba929fcb3378b89b3d66f2d82169dbac7bb0b1ae52e72b8d89e31df552ce98ddf52bf748ed0ce6b52ae201ab7923ce6f51de69b961e4c6a1d0c24b732d8e958d674486b969703ab9d25e2233b78ba46811e733510d38fbe6997da27467b44565813530b2522f91a384bfff9adb686ed8ecdc6a1e35f714996a0a143f991b4e2e5a542156dbe4a50df3875d5f86724efceaef3e027f35f02530683d020d653e88bb26c2210df0634c648ad11657f99677475901bb4e2dde211a7dfa93525d189ac14e8817e27d5b4de966a0292168773b2a84f9d3b43f034303482594a58483e4e7ebbe2827cd981d693b60f222ffc53f2193656f784c65f0255783bc664bcae82c50241c091c24efd97de09160c8662972330bcdb6d2b202e0d31a50b4ced953eeec1e6af16d7e804afa91637db33de76359ea23624ef1628e0f57930a49c9b8f83bbf039ba8e84ecf1f6a4b4087258aaf1196e8041fb8abd7768c474e3ee9d8ad542fe411a671ddbd7971c745b99880839598273ad9f1116e058b0e06557901db41667d60b9e016716122fe5cd2705a3751b050bc125e0c444395d47ea682b88a7389cae9d94350e4e5d7404c1119ae346ef5c6055c1ccaa1f84c08765652a347096d8a5210c9be9f5816261a3e1b1b2b873e8b7eca013cc8c8174441709517ceef2b674ea1ee2ba1b1923903926a14bb2377bf28fae936962a5289fe3cf5942f7df828f9987d89b32e72f1fbc03c908a4b284a3b2e3e50c9ea2c0599e175150c607df1ff80c99c7e5a5e9f7bfd3ae9d803a13c48bc8eca22fd9d6798697c3fa3ce6b4d9d82c5026e810a100bd80ae3979d34f31408e2f4a9b28196aa3bd800c221bef798fe4f593d3e6b5dbefde230e3247647623596b5aafaa4108115ab5af892872f49af5eecf5acdfe8f5e8b6ab8f0beb318b07ab64b297ff2ad642862283af81bb07a54263e49e01dab42947eb4e5666f138d6ef4dc1b63ba413b5d85dc6b1ae73c2e684718f1d61e7a65002eba3b5d446753934124e117dcb08560d60cbe7cb2cba0503a7875723c13ffff6458655df110a2963254811b32029580225868805f63b93aaf9383827225053ea786965687321f472543ee6066e41152265ba92924402fabe46adf428d618f28609dba3ac4f7abd6240ba467c4c7a60c37854c1031545b85e34c8e6aa19e410b7df054932c346e777f37cfd87ef8ff90e45db38fab4399185ba8e303fa16fa8abed24cb004221b996fa925759e99326fb3b00000000000000000000000000e414dbbf62a0461b8467768a169e8ee35b2dc1876d87e43b49bac187abf0c0eff23671337b787cdea6ca360f68839947fa69cd925b320cd129074536bf857f63b4c942dab8ee3c7b6e3399ec96134e452c91998a33b5fd58926381d2bde1cb210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059c72892797e28e1948a9076d49718b4c17e0ed99d550b3d7f8289e4e6efe67c8b0693b8f20db16fe28a50a57275686c234a8d1f55dcee5f78e836f6ee4521ac9fbaf82776bb98df9814f5bdd9d9cbaefb3a189491d15cac70a75bfc0bb1a9d55815688f404b62660c4f86b489429eee990f22f1845da4f7c88abdb8b92b0bfd021460deeeafbf7547bb9dd260a5822bdbdbfebeed40d0cc3309a924b4671fe0ee031e78becaa180c233d91d04efe33029f28290b54cfd23cdc0b56cb830c453c5b40a0652fb167a26a5a06d082674126512244df0aee5d2a42c3dc893136520af0469a1acff89f208033d68546dcc29124945e627a34dbafef3abe98bf2f26075a3a8020db71b99d4f3479a8f1f46338cbfc268e341e740bc24c99eaa643431898354270205992995ee6f7815671753324dfe5c6142ca8dee8d28459d20928ddf1d25a413031fdae646103b6bc61c75dfaccf47d73a057b5fab965248ca5c8093fbaf6d18de032eee89ba74add508bbffe3ed6f76f1022f8affd33f2d90f89943cee420f9871c030cab86878c6f6fd9b0f5526af9938702bd3f776dc07f084ffc3d7eda8125170828e0428d50277323c7529d740a92e76cfbb3da1bd88503d5259f58bd14a160cc1ed2406617ba23cb0f9c0185344360ca280ee2e29ceb9aa025091cfa704b44a49b7a1bb3ab4067eb58761b99ba915dc9f23084ea760b63a6b677f5148985c10d6ac120124d423b06537f7c5495122c6904ca5d71006b9e0ee831f639d11c13befce0fa3713cf63a42afa8d8e5e4ee70a63321344572e0d4f38969ef40b22dbcb005ec55f15ba77aa9885be699f658a781a559f4ea4d610c4af05a4686b0d3c4603f62b8a4f8b68a56818314cae3bcf4cbc3a3cf0750fa77ca714d897039e5340545f6eda826a8d9e5c825817568aa65158003eb4583a63db46e7ec566e2a62955c073d5061e7c44ab8e12e04c47860d906e49f0faa62dbafe8ffa151a166a93bf6ad3f53eefc13d0c429bbd11895c80f2ddfded62d5a3460914ea9569b796498cad3daeb67af1e3f6e6764ffbc03f9a3a20acecbffcdf3ac2553a8a51d1d7536ea3e9c2b6ff9a01cdef17ce06bb57414b08506b1c68c30e0e9e412df564f299df9dc37cc6b0d6470ab08d329a4b24342bb4f9f2371605039145407fa057bf541c2e06a0f76ca52dcd20ec127f06355e1e9a15a406ba618a9c09f9ad0c2efc20582840723ecf6f7636034f768bb747e8007fabf1f117de91079541d10fcd0a0cea93b41244122298e064c09f13d5cec4fcadb503f94d0b7f69ebc585ee9627a755c1fc6bcc5fa986a05f298a62764a6d881158b30ef59150db2d5a674bf923701bd5055ca60fa138388e256d5432d275e97f906e91789d708fd8d58acb3e9c1eddda081979e8d321ace095d0a49f58d10b1fa61a74452dc3a96024d37b5db5012101617f15bc1c664f1ca9d2854fe9fafdd27a1d7159fbea558ffc9b01a6640783af54cb23c0a022ca8b8d56caa73aede85445bc620474a7a00fac7179a08ed6ea16112ca1d925c3b4000e33b5873d9b25edc352245bba99cc799a38fd1f0b510219605aa3740f70dd088eb0386548429f2005bf7c74bd4c51ed3b512eb459e54735557662bad28c7c5234fd85c98da2b51282686b68a999f33e96a9fc6f94ffa0c19e544e111d01efb44c89061a5184d8e0132e1810c70f73f86e00021e6f7ac09daeecb1b7e73aec848e0e88db80724007e6e422d58e08e0bd0a4f7f323e4be48c27304d1404534b2c135b4962028d2ad783c30765e3ee464ef611780384b497f61a281c176681149c738df5c376333f016ce6b6df84655a8deab788d92ab8cbb5f090e3d591286e21f4ff93c374ee9f76d384e4c7d8b4f432c92a4ee77c88fe0e1752dc790dfda3cd84b6bddeb7fa96e363bd856446612ad64c743df8e9f046cbcb874323ec8e184495ca59086718d00bf4ef5fe78e60a2927b53dda80a0b4f641a1b8aeab6df02fe79c99d23a8557308be02910ddeb2f5abf35cdf57d0f230eb15d0f91af2b1fed10e00acfc604ffb069fa7b1f88b0dd8851e8c992430867ac7d63ae639cc599aa5891e7144e4da7bcd307ee907560b251eb2bf8f5a949cae961e6d0ad656739b67af9890e410cc5f523c4f40461430671d40916263bee990bd863db9b5929d367c8a902a12e90adf5fbff44ef022331c4b79e5b3077bd7f6e33d505928bdf8840992045f879597907fbad62acf9f03272dd5b3f95033430dc565a8343c5336ebee77d491ac44896fe378112bb02000000000000000000000000db7980ab21d73019cefd4c7e43461e2fae9a356b3fd9d4042b715002046388c751203170354722ff271f315ebc5626f6e30dcc390ca9a863ec9d99e75b0de89535fce20c80ff463b64617da568612ff993fbfe0f2581499a0c6bccaf4a6e4e8a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c937a52b66913e7a66a0519fb02650aa45ed5ce5c6a3aab3722ca7e0b5658c7ddb4633172dc40289b4845233262a14d686e67fc0a7805278723c8a22ef6c803920da18e1e3c1016c78dc4a7c7f62917c3d26aa483287e8f3d5bbb339de04fdcb4eebe9246ecb92f1dcffe6977e476f2797e635acb0659c6d45a9f41902bb6730307f383079729d7c5ce9838bcc65f397ce509a77885753d0d45b6a260cb152c47021fc46f3adefa4eba24b814da8f5af6fc1e2735aa50f42e3169806a94472310cb0b078605aa88cbd5b2818b8fc9caef0d9a4e09bace648802b689c15643deccba8325a50bf29e8688d69f68513ad982365ce14e7893f1d8cdf970f9dbd65ee5ea13021ff7cdddc8e954d022260f73b9a6ed41b987adcf177d9b9b3d11683f370a163b03082e342dc23d8df77e5b7a03f5792b68e39dc4c6ff5529de5e05ca8c3f4402de0301be2029b0d0a223c931fa5bb17d2ec9cd2f8fdb4ba74d4f62e0559385373091022a1757f74900b0793d80b2e22d92f1245cb4784a78f89f3c51a85bf514467a9b030b4169460b1a3491280bb568e775e67c1bc37bd7bde8e62c60a174abbb57bf07a819e5a3f57931ed97256b5f84881ea3453dfe5b00596d4e16a72adc394393370fbb9c663363a096eccba7dd3989f149cc154633f248e7eb6b561d0fdad6cd732e3ce4e9eb57d8265b7782472ca83e8651d06a616a569067b5326765cd8c8cb184e4ab202d8b2cfe1b0fcb80f493b8ba0b08fc488eaf5e5245d1d858be0d80138eb3a524733725fb234b15fce5177a616c63defae5d5717bc6213079dff4cbaa4ae03f5e55e4f5aa4072fb045951977dc28555f70f5a4916444100c2d5286a62946e0e6324b59f6f3b3943258310141c1bab9acdf4137428266e4ba5eb5b89301b01ef50e05f8fcbc2f7858a4475232d81777e5c242ea44a46f4eb864ba425d655d4fde2257ee93784c07cba203b670d51b2d72dca72af0bf372be3d4e8c56bddf0233c783fe773287744781750b17c600bfc601eea9f3155b63b0d838fb32d4b963f00405cfa6ef7b48450257bea8fa0d560f9e79a5d535b333f0e0ed9096ef9d3e6ad95c73154c4c1c41f457f7e22e03219c9ce7e98b2bf2660935f7b11ef1a35b286251aec580d492da5899db1370a224f450d9127022f415f19d17c78a4bfef1ebab11ede436a30fbd7db0580e62c716deb156b32c3fa3303e04c37bfa747ec7098638aaf11add5dea835ef416d5160c4546760ce959c8f7a1057915a3248efd49589898bf0f45a4013c31981130554e013d69181e046e47be56d800ebdc553ab51d9141150907eb59514bbf4e94b1b0521ecf9b0d641c57de0016844dceff13f137c980f6084262cae2779311f107b830734de3dbc08386af1a3dcec5e42443cfddddf55e466fbce6b60ea5e85b72f68f79c49d1d3d1bcbabaf2226ec7a9a575bb182de97b5af9c94767759cb8fa40a9878e4cdb43bb26b769e2df13a4e78e5e6fd3b6448fae32ee8c339c6e53f92763740f39b6077238733d78c0af97dd5419232a98a89fe1a6ca3b47b7c8917751cab16763797d498eec0def42bdb4c14d0e6c4f53ba237da34ee8dad9913197463295d68a1728f46edaee1fd4ddab99eb389079f038ccb55af97ce0ec176fb3be58246f9926b4732f9b703fca26f7d44a9fa8b98cda902302dfb2dfbef0b773198a2b08a26aaee13cac42ec3322d029d018e39f3516d2e4a2100aef4f9e01308704896dffae8f9c98a0c6cac8be7cc9db33acc1e145f8de17af39970923f27d9fbafe7e719a0f4b59d12507f76b324f58f341f38c9e73af528e6ed7f40666f1986978aed26bc56d64974870f26213e93ca4d54492ca25946fbb0c284ede8c4e6f86a32536fd833d3a7b117ae708971960a32a7deb8dbab024c0e1f8bed43698cebc6706ac3175e2d5344e8f33f30ee2c9bb1d3d90874762c6f037a383cf240a7faa293235cdf41dcb072184fb6bd786d8e81a209a81421d7aad6fc70c4d1d98df8864ca485689e4455b0c80a74f3ad312ece23149bb7d4676cfaafa4fcce3330bc3218a29b4ec022e0e02a37b4aef26a519a72a82c9753a546e17d306acb1d8e77e8d9883150b884474a8e4b68c5e29697a86846b9fd3c1fa685344c60b98a40048153274a326a0169bbf28edabf049c17a2fb5a9441865ff79c6eed2fd5d1c766b61918580ced537c2c6dc2d30dbd068876a3f0222e066ad1d43e2e1e35868ff6a7537aabc2b6c165a0ad2eaaee983d182c429c2adf5a270b1525195f8aae6ee9a40ee86d40f1a1ca89932ea6b829d9055409c75e62b519cddadd30a6fa976228b1bbb30585489998b258ba0b1341648b8638114e26d0904444d62f5da9afd0d666628bf556cd326f6e2e5e7291e0293cb6a2b31f01582dec4a624d743ccc1f02", "ac52535153ac51", 3, 7037365, 1537743641, "13c623ea1771d30176d20f4c18ed449ac6fb3600b777228fc80c7962f63fd480"], + ["12d6ae63012449c2bebb6bb3bf82502a0eb6ccc9225bbb25ca744cafce4f403e8a585c728301000000070052525300ac63ffffffff030e79c60300000000096a6a6a6a6a5300516a7a8221030000000009516aac516351525253974b8100000000000553636353ace5b208f002c8d7a401000000000000000000000000c44bf5a1cf240428bc6a9a3a91d01669e3d28495a7b61ff26db6f95722f403942ae1c0512c110abf1c5032fd0ad36fe16c69cf152f94e6a440f03fdab2d3565af66d7185d016cb0d8e4a174381c0fa998f0048eb72f2717b57e7030a3ec6aeef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013eed741f5745d6cf35ecbf3bc6114108cd4cfd95e022dd0011c6d02d32ebf556174398d1174b981563f60222d74869d0fcfed128e87910ceaccbf33fd4566c28b380e7fb78047b0bbb0986ff3a9b4a965698ac12c12efa5425665a73d658d1fdf580d20d95084c199328a8d0dfd0610f7c75c68fc8b0bf706dcb964a9eb80a4031bc68964476e1388aeecb9000f9a3ed0d586aaf970e5ad1cebce33b2fae3b53602262e228cdc5af9c23c976e65e1e22f44214d5aa1cef71af34418a968646dac1b0a07cf4185dc4d07c4f01e20f944c6d9b2154fe89b982301bcb1453a1ad173ef394739cb9ef6da4dae15ca9a55b40f75991e35970c4f0bf358e31de7ea5e9b179303290a01e3acae9f8e56f644b83d0479ddc5b44f6c194df382b8917b82eabd0724022feb9a3c8396539cc8fa5581d3d2ac03b8bc107a5b04fb9c24ee545d8d63a38d0312cf5edead3ad3b0ae2d10c814b21d38d2d18951d288a42424df892237efbb320201cd5924a7d478738af4eb788f9cad11e829c940f1f8d879730b713eab0ec1d9031623c35b6ad752eb10054967ffb86df9e7dd20917874d6804e5384a480fad33d01cdcbbc7cff3db3111e8af3645c5bac7d8c296c612a0ba4eaac9517a61753d4170f49e002d773b712e93f6c56db2c708f72124d5f789edfef501de296455033a4dfc7e7073690ac146c563c6c8c16690c0ccf14e3a28476665f44b8230d82579f9a7d85ff64c3a8af3d2e9ec78c139adb27e5ea4b0e347d679ecf31c9644d3f42613aae261fc080b87326bf15649032251f4b2875530053ead60e393a3050b1a69375cb73b608357ec46301e59ab8a34c0710bb0d989733b96a74446a3f5021bab8c00f57f2f768cdd940d6e685eee8f134f42534b63c02d59b213d92ea38ce47d327e268b29cfe52484ef1a07c7bd69187356c100bdc01404b40f92eb6e42e05f87be2e383de2087f33ff8d4a351abd195cae7e9924811c02540622ea08835220a4739d1468f32ec0064c8e232b79b38151bbcfb12c355beab7a4dfe98ce3cd38f5a159bf3bd2dd104b5c9c7251fa4afcad85edf25c99f26c11e4f762c7d3b8f4761ebe3dd498dda7a0328894f77d7fc81330579469b5eea9dd303f0ee711e96b7b8fd7b620590707a2759d354a00ed38d8c30d8159bc7b529129781c9bf9dffeaa092889b1dde2b0ad9d47d96b560a779465cbd4ba7fedfb0d9164844ad6c6a442acb3516a83d3aee9c197abebdf6be3c6a33621fee8d6dccaa0a9119fdffd7b3791fb1dc457955f51b5fd80024711afc5e0d97af8277938d00e6b5049a90e3ebac241136cbef0871ec87f6f0c26f1a4b51c549ebe9f4903ac3f6c4d108098f85ede90e19f47c1969294c0314326c61708cd446b827efdb22a6421ee6d9c72be1e6bbad57b9d75ec056e64c8b0781b0b39087c6f6d68c88b0e148c40c9030966fe48311dbef81e0bb1eec2e59be68ea37b1381b9d810efedb029bc5dc5df80165465c249252a8531a9ad9bd33342bb7822457ec9e62f985020f355ac4b8911d761b68484b51f5d0ff2cbb59723f112634684a471bc9e72b2ef50ddd8a4e2e0283336093e1e14378e44de6bf6c9ff25be35abc46bef789e057ba89dc5cc134b26a99805c0a79b6d0f6d0c07d3b025087d8e8ac60f4055fbbd7d9832d493ac0e3340986ec07aee807cd0175a7ba0f0d5d5d0115a9a25b5814021100fad1ac2db11f71a751ec979163c45a8368483377aa6331f8283c229ee036911a4e1ec8af5ed0090ab6c5d8a5b694e860460d480e1d1091f117d3e566401cd445341cb262eb77969b4d15a7b8fdafc87beb43750d1140a863fd5414fe101eb97af20a78e9e66598a4740bcebe5c42049fa9f929294dcad4bcc3f0d68880daa3c14ab916b070452425d7d12e77ca1906d27dc6a8c7aaaa90e22ea743ac2fc19a9154b033420deadc68efbc685d70a61a1fe51881f7e4382e34cb8248117f74445669195a58e0bee83874568a4cbfbccc5f268f15c41a89b98ef68ef75fd2ae913ae605ab338b9df864bb5309f0dc1121d43fb994a5431ad4844e7dc989b7b6f876d533bae63ef5ce096929e52bf3d70e6b839e3b87db0cea7fcaccf5b63a6b36282277746112585c9c9decdb3e6f647cf839ed1a121181ebcaa8025c26513b86daa16c6ded49f3f64bef9345bf3a5df42e0c7028ca033bbd68c97930559508cba589c95dd8b56d856b7bdafcba351d5a2c0417af60c9fc8744539e38b47a07f32591c180bd8f7270577fd86c04084847a38a306a5579c471b5010000000000000000000000000052c5fef9f9f557dad6e8b102e3542b6fe700e9e5ce1f3d9665babaaf3ab34a1b858b25cff06698b4f496c17439cd2aeb34c4ca96cff0878ee6a0ed61613b3f06285823282b77621deea7c9797dac0c49496408f793a57aad8f912e7be9ebd61e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5ce2d0b5ee13f8542c21d47ed6b5f12e3afb91794a83e306f9d16df0edce92626ece9903816dd5b4314e0c42589d7ca4256c19743ad98eb72e644b06c21e247a9b0f30ad9cbd2eefc7ffd7532fc30a644d127847707ddb21a7b4f0780460a8470d132a4d93f931d3b3d6566ed44ce84693e17c43bdfe8b786f84cb6bbbf450a0316c6ebd2e793ee3ee3317b3058631730495c10e767085d74e3c02c6ce400b9e60218ecb269cb835d02cb392e8351db87d733a529c92bc0d6cc12a470b49e407a520b077b9c181f7974f1f918d72aebd424101a9854d6c643b0fe7ab5dbec80a9ec0cc94bec0378d8d3e593ac3e1c159c7f4700c1beeb7ec3bc6e54b3482be1796b9e032a558122fa35cb2c6e94214f6ae66a90e75365c7c56c7d90daa4f3c2c43ac352032a5f33a86171e5010234db267a5ad32dc58690135166a66496165a9a2ff45fce022b75e5add021a810b2c8d78eef58b26726453c2445af62acf77850b85fb4f4b3022399976e458e5268295f506994bb829b3c1c73646224a5d313f756d442020740030e293c07c1d55d4fe4fd972a2b7dc3e4f323df0ca6a73a660385cb149d43ae385840cde8e2f93f9dd57c59222ba4032464779e00fc8ac9f0ac1e825b7ed87b3c7f6cfd18e13d18297768595f671ee46780ddfff4f73405c8cd751e938d3f6d3c227f34c1d02ba486ea77f112b44d0858c3c72c59aee5a1db5c9fd16414d0d9f505c6a0b816301169585d2e4b0ff0c56ef6dcc882748b9881d42d67d6a12da73c9fd408602ca7ee4b3fbf64cc1912290d2b6dbafc91aa920150a1b6d6128f60d1dd2a2346fe171f81da397d61d6358fb2d3f373d1f6443d0f201ef2c1e75d63839134b0a26ce52a34cc26d72b8d59ba3ddf12f75c01125e16a4bdf848e89f7d5d5c000ad3238ef7e14f17167c6f22cad62d3289c06babb696276f992fbbda775ce4d78c1c011275cc263d52ab76c2b57b1f0dc6fc75e165778a3ee79ac1bf8b30db6feec5cc44b005b669175497a80e213fc7c19f7a1be1c59e962bac888f4912c0918d06c24cd9e3b2582177bb944df440e1b8f188a8bc742b50045d5556cea70e4ebdb26123e6b04403cc5d4964f1cfdb9e9b72b6bb04ead82efe16e07be8a454c7b0b375e0840debc5292355a4fb94da0b12e0873a4f319ad5656de6b7528192e45f7fe904f1010c9c6e49fec62f502bacceb64dfebff46151548378dabc20bb82558c48e0ea0a4756049b4f94db703d193e08ef358b8ce805b13ea9b6f0c18f587fd12af59fcfbf725619f3ba45129b135e20a1ca9035e7fa1ff7e61b2cb02124ba73d961ba19af652d32ecaafbf5c4f4686176cffbc6b8ff8bce07aa0bd5d9ace0ffc5fce06624542920d5d1d7f178f11dd8cc3d5756b6ffb10d2668a892deb25a48c6d455489edc3af6cb6fab3c3b87414e391e2fc2a799e621fa9b8b6e45a329169967ed5407348eba46754bb53daf51fc8ed841246c2417d53c7386c533c8be85cbc9ac00935c63b3cb821c382eda3d7269f22f02d7f952ca6ce24a1169f876b115c6367b0fbae4f08bd27ee9fcc75b939c4d3c758f119ae19768936e44075c274513518c6721c158d8581cdf5dff534d39c72a6c707c439bfcafd3d3e0fd46911f0e2168af4159c922b7cd8bc53030b3aa1221f9318462ab92ee8530d2617026d22027de476138ed5c82c3332e5356ec36f20847b38dca90dad34bdf22d5bc12e7b6d1bcef25436f349f3281c9408161295710dcf03e8dfd76018fdbbe14d2a62301f25fb79635f547bd315e191cccaa65f34c28f40bbe4726fd9429f92f6277ae93710d0c31f6414ff1ccb331e76bac53badeae7e62bae648f5362fcd47b0733cfb8e776d4a965a64973b2288e34b2446f46ace967e857b53e7f1602636bea3db77568fb7102634d188806b4a35dd3db71d05bd4a99f78ec19f3a9092a3b16b58facd0f71b706e5466cba8e04848558e1594401da1193b2635b682404bd2d2efb1a555a3e086ff1327c46d4901ff69ef4b5d138a5526cc840ac4db61b80d9b0c7dfeffda718f761a1ea5b1691a746145b5c97f65af49e4eb90c8fb2f7409b1766f897b43509ee4a6ae7409bf540a5bd278efa9ff14289e4243de1856efb699823abfc67042847a31b70bfe342b0810dd28122fcfc857212906c2559302bebc05e78b1f91bfb2a2c66a065d6db85757013f7399966174d11963a0e1bc3fab856955d608006117256b1b2801690ec6af2c222831d241aa8e1bea0e9f620530761a067fbb2c7ff620f6ffc8097be661e3d43b581ec52010629456522ebf19dbea55d6750ba88b7d77be8b3ba297147719bb19e88c1d95c805e622ec615c492922b01b6955460974c346f7d15d363209cede1a69c61fd0294e255a24fe9eeba0920f2159b169c8fa5a0fde8976fc908", "53", 0, -392275141, 1537743641, "93d61de9f2370403b88565fb1c691b8c3b481b210f89654301a2259bbddebd8d"], + ["030000807082c40304d7c8b42d1177cf2cd95b2418a0998814e111dc760cadcf7d821d614a8d3055a00200000000f7c69212e9a8a99733bf464caf228ffaa0987873bf7a895cb7bf05ef585aaa531ec2c7f70100000001acffffffff639e49d1831c27d6a88a95b861ff1b8c41f00584adfa189a257ccbeb26d40a440300000000ffffffff42885f5f08cc96a90766c915ec4181d8856953602e40e814ce9a7cc52282a60401000000086a6a6a0063655353d8838d880188590a02000000000900526553ac51636a52000000006efd20c6025b15d40500000000000000000000000006acf58fc4ccdfe6af0adedb7abb30984d1de291a945540508a35d410c11601ebf43f49533758156e6c1417023d8e14d064bf22166d9d0481e17e7d0d9b7025688427a3d5d2ac82530daa66db203058f02d7f67f5050982708384495d0550b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a5b72048d64ce5db8ef86c2fc901101a0dc7f3a7a0cee4295d1ef808b02e31c0f27ea72fde68b7c30eb5fd1c12bd2d98bceaf02f71b00f725dc0ca7e414273b608902a5ff10191a195cb255d0c9e535110a22b4deaa97c3c40ff16d5ec4cf52f823d6698e6f2e4500865a624c5bd6198780a57b73cb96059d89075ab623d46bc030e707cb56788cc214bed666d956e242a08e51f20bc91eeb85493a4f2ba54d98c0320754552cf7911016a5b3c912f0126098094e62dd941c198ddc4efbb78f39a370a08496b437bdbbcc6129696721fb1ac65c2fae0608cd5138de4a50c1d1fe062bbfbdb0d99fe5e0e4581b29b04a9cb897d585294e059c2d42860c6d6b6c3a0a223032a307d65d196a8622fb37a01b4e1577c30670d1b4f3b3b2f84e13d5bd0d0cab803285f9bc8ea5267ab517393cdd21c12a503391b60f4eef6cdecbb1577c16aad180317a45b6c2d9986b19c2b1c3392a69f7e4161a6111b5163891d864de09ffea3ee030893bfe532788abde465bc2d3f80cdd6b76398a84a9874ea1f03f3ce3eb4bfc9022d500d28a58dbb3fa8ae463687899cca4746576803e9b937b1e889c2ca20194442bb009744c46173c38882d2355be44f5012a2fe0b370f50142a618599ddb2bf74b3f44d85b782fc724596f88835c78185cb1838d46330e746794bf7d0049a17bc9dafe546e0900be1815842672fc862a3cde03d41fd82f2faf10bc65d5bbbe757dba8c1763f23b16298eb6436941130d23e61fa5647988bc4ef94c0366ff5dbaee1820e999ba62ae605c7cebee21d94de143ffb80bfcf5a2a9d45fa1762b6bbac014e6797a5451a863309545cadb7077b334a7a7ad1c80506aa297505cf97e031acd08c82b29a919b82efb662d7f53bada9352b5a2855d62efe1eee77fc55780df017579ef2d9abece5eda96782f63e3fdbb22670714179437585b1b871be5048f18a2f225587014ce1a0f61832a0acc18122c677de592e01c6ef692297ca3d0ec8353e3350b970c82618c20425833bb9a641f8e9082340135238e1a5504615ea223d88d894a70ce0b9ee763298b19ae120335401760e651b7bc0dc5d1072b0d75bb4f22620ff862e87c38060b790db969bd60f735585c07a288e73e6674e40708e6f13555e7d7c96cec1acb3280d8424d5b48627fb3205c733cfca3828f0ffb6a27844afa0ca614aa318a90fec171a0fa4e8f80a041f3c60147950665efc02bd90719ca6ce4382223a2b21fd69f1e8087f26b4329938ea01918ff75cebf6e7393fe4753259ca286dd503bb806edd6eacc00a30fb8b18919af73e81d54561f8af0f38bf21e342f530813316f0838f96c4938bf8d0dd30d0dd032c0f1be317cbab495df12f164e24e178949f607d80002169dc36e0aaf3ad0db685f60850d7c1444791848a95c8f64bd693a4afcf149216b0ba0cf2b490c61caf3d14f5a71b468ef58e171b9d9eac2214c51cf75c897b99560cb38d879af3453101092a1c361c30a50c60974d3b6ed7676cb1160337578353b2f1c144f45e41ea11c98ea441d4c27374e4f3ba0039a2776bab45f07b32029d225d24022702fb9f9ef4be43da5626fa8b4200c6881b472811127be7ff2f2f5dbf93ed6e7c042779c59606a47751c73c5a313727913d19f20b7c4d9431c37ed9a0873bd7cfdfdd90442d0a5e8bfbe709c96a7ddf0e08d9cbda530295d43858028e13a70134cb7c828c7db7bb36e6600d51d8f938ff7dfeb2571beaa891412f89471d070f7b66868e4e90ccccf8552ec1f1060d5542d55f0db0b8b9a8e3110a73ee5690269f0267bbeca76f729a07c49e5efdbde9224f6761d3b7044b7e7d3c78cccef1061fdb6447e50d78e7b3f49585cce9568438a963cbed182e2801e7cea366fb0084a2cc0b7f49c84d25afc621abaaaa271a432e08ba2ca4aa5f4b416f89efcdeca65d53ea7ec5568e4a0a88fee5a7a8679d1379267d4e94da127307e191934f76d276cd999edbf47180316ba1600ec0df27bde160b21b2712957c01c6ef53442a181817b8ad4973bc69498970474c579f50bc1858408344a85254499af11b548e920bd02e1234584bdab472d93160f329e6acef203cd2ea0c27da73ec47f024e0edb5054285893dd8abe80f5a7b844e1061a164ba2f2920d653374e9d86e038a8d107e7eaf1d89b449cb1a7b43dfca4176ee02d0280038e366e35542b50bcab7586e3f07b17f5732865d00e5be4c38b5119bbd069e89be21ced9e87bd731cafd9c8240e9fcd99019249cfdab8c9c6f843ebb6558957a80f69146b6a108d00000000000000004b690503000000009d9b2df488d8bf20fa846aead1c8f18839b36b87d59973455d290d8d821898799f9560cd72fe98b2680ca04d94ea9383b270175b28210453957b792ef27036167d44a1ec53c2b4a52273b5c959a6f8941ef01b0a2aa526ad88c42df4efb705c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009adc52cb07726ed5d80ce636377bbded2e70480f4f8548ab2024abe6f2340fddec0f4cda9b5d82d3419243fc74f58b3415f53a5e3dc0329691e7c61f0c74bfa302c9b6ac1fce9bbe8b51cf9b747eb5002f74695c9186a8c52727dd9160b7ccc56ab05fcdfd00aaa49889919d1c872f0a1d941718ab33cc2a8c3a6607cb0932190204930355349106b3220a54b7791779d93f07f15d6ac08de877ef8853acdefedd020dea58138080de24c85301a104e29ba2c6278f9fd5130ef1b1882f36549aa1060b0388d333c50a8d8b70b84ca30c160ba4ae04aa7b759ada61a6575e781bf57d113e1ad5df82a98a63c01917b15013f9780dbba7409946cd84fcaa26d44e5192bd03281be7df1661e6039de716c13bcf52d5d2bee7560c7e4258ddd6bfc865a36b6b022cc542a562cf93051c2e6ef0a5b084f80002fbc8f690907142a3153b866bbe43021817b85cd15f34096b95d49301b431ba6c11507768d52c21034bd8ea511f67f002275af86a765c20141a8e2714a563201a40e9336dd635231ffcf60a8f687ce9cb020816d5ba852e5b960d2dfc220d38bc0bf6c4a81b70ec9809df93248d4bc521bc434a823a792184a284fd7507ab302966b581a6204ff6e52b0b9b6ea54a771714a35a1239be49e869d49346ce8d66eb5752215ccadaf151cc9f7371d7d5c2b2d494d974f18022ba96e123e15f6fb7591415520fff40922afbab5452390b4d8e1a877426904856afb9d3eecce1186c378a65b36dee58729d0418e4aae08dfc6401ff72b02492c4ca061f3511e31575641225582e4c6bcbd9e34e4a1185ec06aae0930a198965cc7dd868cf8bb00c98916b6c1e7a2c7d625531acde061908b88da6c4619efba41b03878ec3b86541bc7eac2a85166acfe8d91ed9f09469ba7bf2b655629724b339d59fe816a125e379f43d78745b24b907b9b039c8f81b0150c77a34e6ce05e6f88f7a122fe7ff579c4d3b5a9e6f08c51a63237b11044429e47bf631eb755eb5055cbd81b5466afae284cd12ec4486627454a09e3a7f1dea51543e90f9ce269768662d6a1eceb80fcc31351b47968fffa30a2e6343fe62241f939ab0024d3290a36c6160ba8b2d9133738bd88e965d90dddde576a3f598c03a97dd9b95fdbce4c5b6e487cdf418d396893784a1e0f7a81060c7df5a694ba54edf7de0cd4ad50372f9ec3715af28a37bf3b5974b6b8d08fe1a292d2a53dcd6b25dd6438a209131587a36067acd5756ee5785d9cd966b0ab363773f2791c174abab0875694bcd69f9ea362d3369d3c547049fc363f90fcaaf6abcc45767b29d9e884e5cceefe4c6f62a431bbe527ac1ffaf237cc111ca8758ac2ada0ea62f6616c7c044d6d3cb417c8724cda8d23719d2f0865c846a41c94d9240532f647af286ef68386231803a1176df654fa980c15c033be00602aae72f9f48e95a408d996b1a4977034f0d4147844d8d268fc07f948cf43c3ae5a33a941652dcc67f4ff6e90700796726d792aba1974e7a342376e95f5e11f6b0d003c224c007682176c32eb0cbdc0be06efb91d9b9722c3e3c88a271a5df97154b3ae098d80a292386aa0354a07dd9eeaafbde374f3e2b2fafcc8128df337f000a868da53ac2c53f78f3c7ccc545f2cb3aea9b30e3c7bde18d0720885423476085be7718c19a67b24e104c7ba8a7b502ae54083dad51867d7b258a35e8c83048933d7aa663604cb7b2b95bdd97d52aacd250707f27248e36b5e3b81244a02fed0f2e53fa8041df8a10ab29da7cff0d56beac59d42910003d9c827ecf794126069ccffddc2f95c8437af666822c667bee68bd45d97e858293174de3d5dcf597365d1e0d046910c3a1742c0caefcb31be7e37d7c6fe0512b9b51fb7de71db8834e8da24dbe6be2aab05dc510b081cecdb9fec17980e4330e43af54554523c3c4bd4ccdd1f9faff47d79d330c8501fce5bb69ed5c7a8a9578389b586a814f610c8ffd1963f4652ba8c3ad722f63738ee7c9e47cd7d63415bf3f4680fee8df627de813bdbc4f99f5eda93ef0c8e1155f580f77db85e02c4a2b4d77180ad321d557f1681533f6e6480ac1af12a68d070a62d3ae9026d4c730da9768019940c8b59373699153803bd31e93a6f73f54b5f2bd51dc00c758278ffc33a9432c0a5c5be9c52425a354cd92a7b55842f66b40e27c8b46b0398514dda12556015c6eff2cff5c34a27092204ddeef8649682f2d865bf792d97e174211ca26c32d960e4b81fb75e20df08502a2ca0bed5fd5c1ce84b4d9373b8eab354371fc5a1d718dcd1b4ffa7bf94f43cfe07756c3754d284f4aedb5c7e0597418b23115efd51effb6afec13794b477c27237bf21153bcdc19f7cbcd1f6c089c1d7a8e468ef5a82cfbac2dd2bf3326b46286a572eb02f92caa0af67ddc52cc3b6134ed6da741eca4681906", "51ac526565", 3, 849022614, 0, "fc7f06c81adeab84768b418c005fb1a4320a61a9e116a5afcee70d5e21309b4e"], + ["0b750f4d0161b66a98e90509cdde9b9becfdc76de4b1d7fa1ead0f3482db4f66a6b15e60c503000000045265536adf7837cf04825393050000000009635363006a63ac0063195c8d0200000000056553525352c474a80200000000096a5163ac6a526a6a5318618c040000000008ac000051525163655bd5d0d5013051c102000000000000000000000000529d16cc97952076ad96f709592fce340ebf5f27564285a3b279bf26312f859a49cb7cbb48cd1e9a2234e336b4c1419afae5cf08ede5e9943f132d172cd35cef5a0b8509c694002624549fb22bdc6f34bf55dec8206aaf32b670b3222eda839d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f695866daa5ce58f375f0e42ac35ba8c3cfcfa4a64dfedbd6835ea11e80e9d841762889ef2616c83c136623e28673ca78eac7e4900056bf767fbc58586305d08aa3e11fc2b33556e72b21870e1803a115eb9da1998c262192d24fafa10ef57691bfbdbadbec70251c75d244256222fc22fd8951e783e079df45153610e2c64031e4c34230bf0f931eef7f57e00d0c2323e3ff9cc43ee6aa92fba5ce818a1a1fc02010635a77e5888d0c9ab396512ac3ac428407ed4aff42900c4240469a371927a0a04bfabd45117daf4037537519616f2a6996afad37174774b4f1718f985d05d35fc18e305332168f3dee5b118a6382f1a43bebd55d7d71bb2300e0c549014d4be030d42cb88a1f0597b3b9c2c7cb61d42d4720b61ef915ba32adcddcc7bca1d494c0226df7b9cc33aeb1e41fbc6f2d7f510f6c4d69cdb35de5fdb9223018b426d0250030dc24845087ff32ef44c73c2bd96582305144bd892107f21aa2018295a0ec68a032c6bceb096a57451aec28fd846c40b42bfbd6b2acef7d6477caab1bb77283077032823680024f4289e827ba5f4c9af050a15c6ef977c052469fe287cc828a3959dd7d9e1f6b654a1694c95bc1fd283393f886098abb8c121e2ad81b40de7af47d1fb8fdc2266dad70c9f1b68b78465d7940cd13d0d3b5b1efa901bdef612692a49240187013391d2dc178c741bf2128985b5ab3dca924a6859fc1e62a5698b8f23afe05ba95f69830fc317d66822ec493252346eca0643d0e0303ac05ff7cc56a422d0e4003265990c3497b5e12a690a91598327203c617b9c34268cb5291c5bc2beb1da26c4eed383bbee10626116ec57482e7ad61ca220527b99a2012d078ca6262dea743bdaf2eb1106bb514b94699dd5829264d7590b056d4e0c1f001cfedeca6aae76a519adc3e9bb21ea13e42abc51aa580af74f6b07f9e963a48529687917e0045035bfd45d6821421e0c4dfaca97564b957f750de2608e44733927c6937c06241f77efc40dd89eff4e9336bfdb8f13580ea9f340c1ec3be4e0ad3405e44ea4e3be933e6aa967dd6205466ea1f402b48ad6fc3b1706349b9927572caa20e6338de8df78c3e989bafb310334dd3990212ab9f85d2c9b6823ba826f45931a3ff84180b1ff59e408abb7ebbf063181e8367ea59750adeabaec62e829c20768b9fcf0b24fdbc1fc6487d43c6c7b888acb61cac4679f50190e5b692809fbf82a646f67660ce1fceed6b46a9330819aa7ccb8eb3ed85e2bfea18b0405085855759d0a722e9436c27d2295dba0089fbe5acb11bec85c2e23f97fba05bfee8188789858244b9689f9cd0ee8f767150251ab1de8d27c027a15bffedcb2cc476f8ba076b67851f7388b48233508ed7b14be70582339d7630b04b22dfbc99e0b2e69db516f145c59ab03bb55c2c6e12331537de527e1ce66ea04f92b07220ab1cf422f7bca78356f3f1d6b375d3363b781e0886a490a617fbeb1b6cfc242f112f805602f8ad2bc61084fa75c4e31499980b5a49853a2d7ff9f0f02afb8e1791eee3f37f70145a37482d4d3133ccbe88d29de5acb312287780170b37fa35051edc803b7c36f11fdf855b2f81cefc428758399ec1ee442c572ba34dabc819b14eeda33b0e470117fa0e4b463e6139237003cb175d23a67b662ddcffb2cf2e5fcd94c711b2f82e07b183b2877549f0eb7afefcf1ed66eae16ea9ff7eef7dec4c27a1dafdd33e1455b00a6720bfbd28bcbd32e0c2c5f5340e5736635d6363795d19a7d1ae04c06933a4e6e8c91d32133b98517862e4bf85ed4fdaceab9b8e13db98f67903eebb31ecfa56a7537e573e362400f26dfaea7131cb047e4663748caecd709fb0961ec743d65bcdc0886f191f166e687a36292253a1c75807da91cede779124b8615947ce1b8db009607004f982a68ddfaa752b2c596d100c3857c41e4970b0429c5e48e60be5ca3ffe3fde03a363dd8fc7d47339221aaa311da4c39df8f57ebf56f29a2128e666cdc2dbe448ac788b11b3a5a6147e0612eebc7d08b624aa809bc8bd7c981447ccca767c10589f9e23fc81ee1fea7d41b71c82774536e4bdc172b51bae52c0447813329d9796482147cdadd3f943bbf6988a15c8fe264c71a3a2401fd3d46b1db889d9891a2caec54a40ff028e828a3339b31af97bbad040055315a1ffda3282697f57dd28d381cd513f5889cb64b49a4d8baefcff8bfe40451ee8daf47cc2393a4b8c941b4c593c6fc2eab6d9504ae68d3add49f2537a1a81bb7510efc26f93a311627042973855af13a7a0f3270138b09f2ccc60729fbef75c49b9015d6a94aaa3dbc92dc9e96d6e8370db55cc03f07857083949ac9b782beac9c0937beffc2678803a6769d0ffbf96e9e86a3856bcca2a918b4ea5d6f75ee3437cae0372fdeacf960c12914cb0b08a39509", "ac6352510051", 0, 1271430395, 1537743641, "ed1c370150f46c27f1d1f7f2afb77452ea4d134a84f8ad7f59f66a7c4aa91947"], + ["bad8031e013a06aa8aef741ff8dd0a98c573f49b8c9b4c429a06620eca23c641fa057deab20000000005536a51516affffffff04422ba7050000000002635308b126000000000004526a5353ccead80200000000095263635352acac5300a2d12202000000000452ac5263000000000200000000000000003ec4b2000000000001d3f6d27570dca7005f312f0aacafb3c08bea5abc97452a4f37ee41fefda31a9b1dd7086eb0a10cf86fe77198a7c61c8634ab1274a6fa217b54ff924afbdf28bff40850128f4c5ed953b92ee8031a72e981287d1ada5ee6a3109d8ccff2b2f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000330db90af3f6809e44a6baaefcfa05fde81fe32300fbdc1284a415dfe77abbc0b0722b3d2c32d262d81c64378e8bc685f13e20691312d4ef76eec0415db4c390d4f9ccf95ce82e2f43459053fc8520b3adaba6bb0a1fddaafb2e8607ec000b4e39f10600978ac8e2155f7a109af9a9da51adeaf35a51fb8f3e060260dd1ca06e032a38fb58b0a7bae01a2564f2ea5d3621ee8f7b37c606a47c5b780665ca641dbc021fed5744032a9c2c098de9444096dbcc5d8546028275d1244a653998d2aa0b370b03bd71a7a150dea22247973f00cf1b1cebf4c7790a8bbfefb71fd9c00ddd6f1dc97d6583980fceb25f037760ebc6d57fa26c09f655683aa36da55c593eebd41c031bf2dd329592d570428c3fce448fe29cb37ade519a132f744643e994f91dc705030e3fddc702eadca33768aeb760fed3c17aacf69605645afc6cc013924c8084230319bc899cfc6042aed784b42850aa739f239ebe53719f19adfed3d4b8c16a3bb902005af9ffbc8833bac5d70543ab2064a427f3d4388ef7a0452f86ad8a8c8cae8e030a1983e5142189ea434003db4823b9a63ce5f56ca72e45db4b4cf177cd04823d5fb1aae8194cec8edae3cd837313b94f69132e5114c55d88488229bba5cd52cb2bc24bb385685abd67c95262f2c95aa4b02f353f50fcbc5678cbbd7be7e4873c3664313271920befa38d02cea7d87ef554316c65f6a93e5411495e7a824beb671a3f1553250cff46f5e57b2bf5f5ba4f537b03878b4b2edd068c18a3a57401d58db51009a5b64bafc8565d2b3b176dfb3e25483ddd8c76d30df32f5881c25fa08e31b698f11b36ba808788a9ffcd66e99d1c3f448f889cd9ea3f8579698af95c916d27362787aae65efaaa9fb584eb7bb257daf474c2422eb22ea2bd21e7d5e666904d91325c46102921422dcdedd42992aef315bf24e18e2d0f92a299a7b0dad317054671431a811cf83073e44f3d4bb0252e47d17424d34d10de9c35b92722e9fcb1fb52acb84b9abe4f7127c319a232afa8bdc9f07dcd5a23a163c7a950764a2145bb564face6ae8d36b8ba5f56aa5d6a2ba02c4372f1470831c2305fa867b44cf94a3bd773c140b5eb74654f899bd0282ad4708d08891f0bc42229febeeea2bbfddac335b7d47c36103493da529e81576a57a54abfa37fa1f99f8e5c947d420706b42801b9d290a1ed2eec7f7dd28ff4149216cd45821e34b82382044b3133fd3532f4ee22f58abdf8c80eb1f1ddbf9ef1c716c9c2f23d79a6c548f2f194af5bb5c29330ef02a1bbcd296e9bfb7bb5e8c3d50395f5b280ddeb1a78dcc4217a1f4454ff3f1740d051b47e4252965e354947d435ff21c29373cba567bcdf431a3601d310259fd9837733dd08a4259965a566aa6626228506d18182824beace94f87e4a9dfcd3a7cc926501d534beefb3154df941c823d55f48df1f224f39a31ef2e1ef1f5e9cacef5da5f34a4ba25d0d46ca210444e2b60ffd1be845d27ddadddadfb9d6e8fb5042fdb677eb9c9b8fdb9f9e108fc51e074d4fa5991186132a271d946cda2044dc629c2f07ec6abf6d4db15e85353bda23b9598dad0819a81351f2715c350da8d4a9681eb70b6bdc72959c4d4e129838bd392a4c5f3aca1d7513d0e29cb4db2138c6846bd374bd8e53e8857eb9634f192db8c5fa1a9e031f872b294a2234df14756245251fd647692d4e613b7f220b5ab747ccc3eac9ab3c8c920f01353f147b9c239a0fe969a113b6b9e4afc35fe99f08108603d380632f1f538e703bcdce6758718137d40a5b7a2d2035fb7e4666082e9b5c63f3f2fbe0fbba496bd96bffd2126d10a7efced2184a99949d45ffbb347245aeddda080d6c66010e8935db2fdc014add583d60cf2a3ede28e0ae9c00d8311577ebf33c07b40ccc4462593cd6ebc1b3969f35059ae13bd3cb14ac99c70db455798e92e843a36ad3bd6edced494d4ed7990091d881e497e7cf70ddd499e4d0713d4e3889534d3056762d1f9da6718979b88ecdb420491fdb46c460dc0f790ad4689cd64f12efdb12b4843d36b20d6069d4b8ca6dcd27618ad173ac0831ae36931ce4ad2c3aeccc4e48da4c3a05bb0ae30a56b545f17f9199f0443262dbfc4c3cc542f7d3db1d72b26dd1675fc6d287d4ccf3b09bfbcbf11ea0610d15a7ca80de13cd6aadf762b80c1891a0cb5621e573578e113a29cdef32e4981818519e4cbbccbc5e336694a05669c8ec9d569c242ec315843b5241f835e4d83fcbd5adb13dfe2a4fe0cfebc68dfc2ca3483256519242ad3aeb5d8a76a40d00000000000000006c2c7d02000000002c576033f690ea1522656ee762d05c8d14a04dcb85b958258e1e819364de9998d358bb3cb3475ad8cc8b345640ee7065b4333c33648a0cbc0d4216685bb75e3d4876cf2c0aebfb95dca508884239a79413856139fe34eb3fbba0e0f77321761100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a6f23163c139a7999180a53e91db67ebbbe030b85913fddb2152fe45d8daae84bd75c98b443e4362a8914690fa7e8a08c3f441757a8e52593cadcae21fe5ed48c3b061004a00c1a3d9c2d0ad48e088c1ee3f5d17df5d2612c7bf6da5d8a9a8ee6986fc72d64084db4806f849410c71588d6073aed0f15d23f48fcee6ac61ae49032d11108f48202d0b0b89c5ababd61d97fa4922294edaf59d9fa4bb080d6598130325a2b514fef83447f4e3943d4d3b503b4e3bd4c256e55a7d5745a6b4e4222ba00b01ae0d7a05b2994223e5cef22329e54336e16fd256c299f775560177c93cb8296401c599ff5e6a79dfc6e452158bbb5aeda3d624566bfa9bc99bd0dbd8a4d363032ffd523f4a2b049a0b0faa7fbe133c8a7c35d6911f2751bfb5bce0ac3cdbc7d00222a84520828d01d6ed2df7a42363770b179665e650cee5afc69c35137af7b14502234bc47844206e603193aba8a0cfad3b7c7124f862ec7899119cb9a2aeacb634031ccb143b3c7b74ef394c372bef938a06e883fa9a0595d4699e706b191fc6cc0c02301102fb46bb15b7d09ed2948b7ab66c62f12bc23694730cf20e68795f187d9b1bde503b95074082946360a281592d5f05a9c9c5044df6cc76ff73baf6edb1bab696c3f23c92e21995eb4aa7d965dfc761ade7ebdfad47044a03259f8a936689eef8d9bced3910c236cb6e1e9cb43130c57e89f8eec05fa88e37964af058e927f5f556b6ce587558f7ad0924e85ee74018c83c459c6d554ab345cf93719eaac75b89175b65047e77abde7bc47e779411ba23beb38dffcaf5f3d94595aad358cbee18e7d0c3c7f0096c9f399707c5cf10d1493e97aad3551e5444b989d70268fc3850ed5b3d1b00ce273237e42a84e59666528e4b865262371590ca25f98b0c7a94f2a35f04f63ac79b210c73ae0f8ec6bfe21098aad8b90e7f880f20eee17d6010a3035ca216ca8e99166bce77657d5a114ac1a6a794d38a55e0fd1c8018bd2b49b31dc683287473ffb9987ed31fdd86ca304eead7cebaf8cb42a5a9dd20dd9ad6ac4301adc660599933a854e68813fe46ee7dc091666c8576e199852e0b2a9d506e080495abcdc153315dd5c2c6c40e40c5bc200de9e810cb2fb038f37ce9fdf20f98abf7676ca584b7a50f08152982d8dfe451d6140364ef7729f6610d55348210dc75eca3f8a28169cbda74f86bac9e6933c549e69d403b71ea96a2768e34969877c780687b11ce3cc31450483e0d28b7dd5e54620004466acc99e0644ca2e5e9ac24a7d5df90245f940686cf7bfb82a0b5d4ccb4124a27c43068674bcc770b9eebd447543c8b5f807c902019179f911f73e1f0223a37ae42e1a2fcc1b56c90850d2b48fc8fdabde05c5380a89d78e8f2bb4a8af6b59ac30ef53cd5a654bbf5a9fe49069d51ab5d3f7fad898cd2586b16d815f2e3efe4726386db8bcf89656085c0bbc722e3414201c457b0d5e8e823328d1b7e358b394bc984b2491f57db9f82c96dd9fb540cbc9fa63e528c7fc52fd0bfb7cddaf296035e041334bea306cdcf6b9b276ccf504b63bd876e5d6e9098acd7a5766b1baa7e7fc586638d7e35be197c500df8c1c386fd30efa4ba37ac3dcfbd77642903254ec2c6179399622dd97ef4de2a5a9744a861952ae647fd301254bccad54a597923204b0cbf6c064fd1278938246ab5278d8714a72313d02b7a4277c8f48ad0a069e711d37342aa4d19ec0721875f923b464086763c09fed6552f6491e5d4c00d640bdba020eb42c12dce53ac92dce5a345fb6d0f371ba6582dbad66e024febf0d320e30321bf7e73889e0e5f106e0a7997ac271154f97e1911a961502233c3c6502b586a46184723676f255ffeb266cc0b798bfbbb782cba4d327cd6ee0ac4bdba733075c14e138a0a46b6fe2edb8acb0cb38ef2e92fa3586ad3c6348480d86d263b8208f12ce3736349b3ae08d9f091516eb46a7fde98d8bd74afd77399558d478ec6afd787d3c6a2e93249579dc62cca347434aebdbf4a426cbcb196094028e0f9265a77ec8c4d06836ee3e5abc82c700de58d976f5d2c6aee0d7db57c8002988672da38272bf204200977f49311cfe9f5ec4064a09805275e21e763392636d219e0221d0959bfc006372bb8738fdbad57c378ca3971be7060007a55de15e8dbabd69dd3f3d5fcdacc9b13676c5205adfa78a1f4428d9f9d48ac21ffef3682d252ae2ca53cdf3a0eb3dff4ce0922740f78774aa8f71a3ce54e754bd319e97fd64d61e6e597128bf2e567b9591a26970b3bed19801fc0ab96d1e7fa6af882945c5894af64fe13a7f8a48771240b3f2b5a5ab3ad2e423611cd7415c6769eebf3cab0f63fcc49f9ef771e281783f22ec025170dfaf2c098ea5721b49517230ed8cfa7f14fce5fa5de6d9676b60e3fc1fff0197804df96586dca0d", "63ac656551510063", 0, -423159274, 0, "9187470b8dc2fae865a4b8c376bd89ff7a605624717530b4489ceade401bdd09"], + ["fd61516401bd94b3cfef12744c05147526df75345334b048dd2231ab950b50d75f3a05ffeb010000000451535300ffffffff031dd485050000000006656565ac63526ff6ac0400000000055353525151b8c309050000000004ac5263530000000002910d2e0100000000000000000000000036aeec530ff4708cdf8096a04a87fd0c8d03687d7eb15d444e2177319b61a4bf66422eadcb2a016906a9f2e5b6ff9beb6176bd8da6ab861bf230d3152d40b2147a1308afc4650d6511161e50b532e09af057bdffc723b8f675edec44466e35960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039afa1289e36654268ece429afe31ecfcf88309011e223673dd48d98394fb7b77ead572e4549e67d05a7769a5029e40d4ff1cc914f42adb76f322d44e57683cf6510e9cefb5d3cf98e3a1272a2a6a54cd91f102f84660479b14a0839599da954cebcb938fb6907a48041575d824e9de124d6c31fa937b6b1761e194a797fc2a7020e5d451a65b3b10bbc28278a57f837a865796d022a0443e894d2ed2fb986b10102200e9f88778241d4d2261a9e250381c38aab6d9443b140aebee72ae63e61d8e90a053ade69ff9ad010cf4d93f1a0133457803173b2f830e0d50a03e372edd56c8e2f679cace3b642110406395b42391784632fef09816060852963110a1b881c8f022d97d41cca57dfd9e52555eef5f3698d3717655c074ea13b54e7e74e7229c972022487c75bddfd1a0c13a956c05ed82390563de1fee8e50d3997046bfacf2e4b20032719d30826f6cd5a403cc6ff665688387873a53e3074daf493909ef10a740fec0304354d301edd9081c1fdfa603f69d2e1323bd510798a3be41771ac8975d4d72903258c2e5bb88ae1a4dacac268fc5023508e393294bcf4951c86db24ac765a72e5962e9d3cf22fecdaa032f2a01c951cb32751e13e7aec8c52382ed5de7febb1f62ccf8bc0f7218923700c71605761d0af89c676375b31b13d12ac96d33c588ce853e1556305c5203a8923ce662f2ec91207c221df36d4752c7852f0eaf98aa07e4bf94ff139c48d921b12b0a5c59ab17a526409826a99081698d7ec518526d03a72c1271b14a374c07e7b22ee75ebc184b1e9aa2a82b3859f600e854f7cc80868905f005bab0d47593d412231a5db8900576eaf8a600cfaf6749bbbb70ce5d2c6c7f34e33d3321468c34b0ba0d35e017edb7320f334007850f1245b864d1ac5185f0a1cfdef42c18817c1a60eaa9e29fd2f9d0ec73ea74834efe22c3853744300bbd559cc6cc669fa5bbccf91b3ecf6d10de2f35184c31af9326711e862dd02f897a1c927caf1ca19c74c590b28b8052556b9e3e506e3f9c86088fa60e190b1244d27d71e6d5f1b116f9dbfc9d588ae5723ffb06bb7e1de033bd3838c09e185a158e93e1060b3526b14d1b5047ef4de11d6dfbea29a5a58b6400e844da8de2e88986945f64b3d449f828293d59068fdab961afd83bae6f4c01b65ed8393808d84df7c77c61b02226e98ecd409da3439fd72b4ab7c317e9c6147af6ae07ac0611e0b18651bf620444784830d004812fa389f7c2f56b0321d430bce865725b7d36a45a8676cbd81ca07b1bf5c4090c375418aa90066d3a010867ade9b5261a354e257ac5dae53010ef443dc72458bd5fa46753e5a29c34125f9a9319fd3459ba01264b0eeef069f4a534160618f39db1c0288380b7a5953d7c39978ec3924eccc24632cd7fa76b1454961956d34b7ac529baec260f688742f13a93934d879ddc3d98f97aa071817d2b4ac6aef430711c28a7540b03ec66e866a6e73208a59a54271d4fa7989d896b6c011b44121c66b0df4e769b23e9d6a0d5df6721f7b62068e2b3f48c198f5d42e8b19843b77e1516889d9fb90f81f1ad3e4170617dff9116a364a4a0049a31f1bdab07970eec8e6a5fcd6fc04ee50e4af0858be388b79e04d1d789c33163216e755b13ed848576407a12ade28852bd7947daf5483531a2a42edf94d02aa46eb6f76e9ca8423a3723bef360fea29bccd0d9f80e3c141da81245336d0bc81d2bee182e46d73822ade1f56573887e3fa37b90aa8692599c5e32b9e38bcfe87cd44f9485cceba500a2417393b00cde9fcdc0d53a6a27917191b484f6809b0983e490bc81800537739f4037261d10673809a4286aca51314e6062504ac72318a896b384c2f050515cac415d820646e588d44a2901596b1af6124ba98ccf0185c6679f835823c7688db1fb9f5fd8c2dd213f5054c6f23243e0b0d50198318c9d213f4de84794e911f4d86e4c12d735e2f3e8679e6e3d1f3c7217e75688a7a4e160db3a3e3d131a4a57e5682cfe53ba10c76a5b76ab9d8b49da14dc45611a68d5f1218d2e9c1bc7fd14c023ce979d4452b21d191bef5a9229d8d9233c1be0758b8de60e0e689a3fbb61de91c691f68d4b37abb012747b9c0ae14aa590f3faf1985cb7b4fb1e502f2414714f490b87ea00cca7afe3682af845f47f4df687d1c3d6a9cb4bb324f37605e9babbc25e73ae35a88e3f51957c4b93f7c2fee7df0244659cba92bc741110945ac617f91b69a0dd5fe8416293fe852154ad4e691e3132979217bcb15b7fb3bbd166c9d9a420d0000000000000000c978c503000000003febcdadb52ae74ba0b564528523b9e8a3b43ec5d03124b3e478e64270123c62b4853f3f274e466e400c7ff22c5abf1b32060a1dfb63e4cb1d7f6fe629b6cd1927528f7b35fa4ced26d7f1df03a974ff73328c4b256040af5930764f33ca8a5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000845da597e305ac9f0cd6a894179b4737ed32d6a5121533382c639dec5a5a308261ddb3b4e11531051d0e6c307e3132a77c32915530c01b8a397c5ae801eadf039c432184519ca20e3917f3b841c8e90cf5ddd11f08f9d619ebb09ea2387973d10a8bc9ede727913133224ace1c5077dfb32962487fd6aec3164dffdd264dedaa0205c098b61f3011398f0496da56e08c18e5b00c236d662728d58a1e7a4830f4dd0306f6c52d35b5e3761f5f7e9d4d7c2fe204dc66180faf92fb6d03b86bf32481640a05e3c931792a0951998d33125d341e70d444f2e0b92f276eaf6605c312b380605b4b9cd999eeea208e4e0fe0a3850a8de5bee079b41a9d7d7ba386005d8e377303270945fd8fda1cd1d93213c5e475a9ff2341bacf045427e7367c74c0bb41e877022b4c4ab86f1be3cdcb0a4a7b5d334db2bd48e8b5995eecfe6f7a38c9bc51af5d021f959e36fa1d9446e719b523356143c59c39370a29337234f6f7d857e2655e69032f5922ad5a94a55198359120521cc88b27de8306c0c63a1104a65e639f3a37f3021bf248d41ebf9072cc44ac2c05cd3769ce4659ce1748f79b3581d4c80b4c7cb5bd35ec7c30237387d8eb91b1186c2e634547e3bb53e56189e8b505f51993861e46f010184163fc6ae9ca0be5f70bf1da57e29992b1d7d81f42f153060553a0bb812288be43f560ca3ecb20973486755ff45454d22686dbea8495d5aeec78d695e291f75b99865cb3923546d4deb52187b1002d118881513daa8bb25ca0cb36e3da1c401add0fa381f0ad987f86479f7b2a744794379361581ad0b8926102956fcd9d007ff3c7206f63af5e74984bda7a9b394736a400c58eee001921e3a595b5448bf1844143aae70abd3527a7577a5bb8a8789c95812630b636f9a1df8825eca8140e13bcec3e29ba0829c95e22179652f4ddd0d23d3bd03ba78ae52516282d38e2d1e4682732b9b844af92d065d2d5b259cb41bd877f98399f991153d35dd6fd9a8cd89d647f1c48f10ca42b69bb164ffe69e21131229a435f1c6b656a8379090d1f1a5cd2a9c174ba7903f130976aa0ea31cc225222d454f8e1727b4f4dac7987f488afec851115d060a27046585c4fc9ebd9fb4376579cc1bcb937034752563063d74d0463882dda0a3bfa319169327dc3baea5f64e55d300d05281e1b79c2511b81053e8aaf602ff50306b33cc91e46d7442af2683ad6bcd7c9499124d103c8e469121a40a8c2e99987d3697b89b5e1c9cd4a45729e79feac294d32cedb07e170c5d2fe7e4d563b2d19010246a82c38618610ff3737ed1e089ce633a1d19f43abcd591db46f20008e8633508700776932f422e744d0c96af3cafdab4ea3470408dc392d423144162326b08b3d3d23e0a116c0eca7a9b4a9085fafe86f0b0a3424cda51baafe18276c1b307d0c60618ec5013a16b8a69b26e990e986606b7997b92345a7696e52db7c33d21e90eeda8a18c05ebe1a6a4db82704a0d246a72513fefbcb699452f1c98c539321e5f4b865ceb4667c4481f928fadea299a4fb4ade66128144c2dab526a7419a90bd4d48af723a6db0e6ad1f6e137e22961cab6a12803992ea34db492500eb2d2bce464a06a72f41f7cdd2d66df03ba52fd4fd1754c5370a5e13b04cb1203a5f773efee5a0ecdb4a158c8fc4c6697e35c0d34b9761cd447285d7178c92cda202845485d632f0d517821d4a83c4152f22ab4d8ddcec42bac4f5ea5ed251fe47f17c28f412cda80f13ec1de08be70f4331fc528a835a82be061681343488f3ad59362a97f04a2af0cf32ed638aa5374f83173947fde11c0e46a888953c22f4adadd3876c24a84fa269eda3599cbf04ae317f0cd39e88dc622c200c065ec05aaac039715abaf1367df8e5c10473516d5c8f1f6a88846f6d08f13b249cd927e285570a66fe35a40ed8c1d718ce080fe9281b2fb0be2a8635ee87d056a320bbec5b8099f6d57284501e73c500856e34f385ed31e3a53a941fda9281b7c82e9dc511c7a4e1fdddb29e6ad6f91c0676b52a456e5adaea473abdd1a06b2c2bbf916e4c4fab9889fb5a5d5e2c8c8094b84fe30777279b9672498005207d057314c616e4bba808c2291f84a49bffaca23d8669db51a6362c5707d406a3b3c80bcd8e08379651c4a52eda717967203a56024779f501ec7e8e9db221e6468638fb5187929dba4a50edc051141c743775a8bb3dc886199c2bd2e3b0b06bb40b9dd4f971cb45682d57ef6f72d278c812001382578b1dbca4d06f7ceb27b4ac87600c384228bc21d835eacaf7fe05486134de0777c925d45c5684b5816bbde60c60ad06fd941a4e93d7ae158b01c49223c14bcbe0d1a7ca7a0e58a06786d23af93f09518ab671bbcedf7161ad019789e13597ea0ecc19188d9455ef126560d03a7971403b217f891c02048804", "636363ac", 0, -397200488, 1537743641, "dbeb9f92d9318eb5c7e3af6b0cce138fcfa43cf7f3ffef3c4a2e7ba5ae943f0a"], + ["2c08f256010dbcb68cb8daeb1a9678d23df67e7cd695976107604d30d49235fc9525b2aae901000000076351636a52ac63ffffffff01cdab58050000000008516a656552630051917022a60155d9fa03000000000000000000000000fd37b62a6d6fa4a3387c7b4679bd0f1ce364e029be858566bd57109c971811bc65a89bf33f01c21af480beb94f4c81bc360e7093228aebefcbd8a192497cb3c15ef06656ad4975250a1158015bac7e6a7f15c82d0a94dbb5361a33dab8c7d34f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004816b8f6f599ee7946ae5688cc70179716df457c0ccb81ce97cc60fdbdb7f829b1711c51a99d225630bd8b02dfcf34c3fc3757b50da46bce660641fbb4153b6917462c940d68330f95570386d4f038725662e7c9444a90f06632683ad7c184e6c4217a95c773994de565e0dd77d28b623b58a88a587be69f7c382e662646ac73021f552e1b93420c0368ac58af5a51893c68a0d4a430e0dc65fb6b2027b69f34b903163ca5417dd836d2b2fd6b11bf2233f4b4198a132727ce74b0527ef829e7d2e80b0166afdfc9027b80a5f60ef8812634d76bc58e0bfb362b662847c1315068ffe110163e8d9b22e2ae52694030b027494c265ef62f34d5190d851befd468773821022634d12c6900972a535768be192395d51350ec3ba75db072326a8ce124413bf10225c38ffa8a245c7e5b075ac5346eec7da0f7f38d42a47fcedb7ef29f8ddabc4e0201efda6dda9a47be254d4284d9dfd230fa4041f5dbe925f67824df37ef2adb13032b3317f5110a5f22870b72f6d65aae374514e3f0672b453c826bb4c73933403c03240baeb9d16ae70a9a63e6f43c006491b24d291cd84dfdac6815f7218b0cc80357616b6905bccb8f03bd72d0e84e5482fd0a0016a21a779f37d7de65cadc243b30ccd0534ce0a31f48f6e50a4813bf3ed696d72df2359bcc872909362eb6a3d3f6064bc6cdb5fbdcce701d25be0c524d92e15f365ebcc0a28217236fb33faa24dd24e9db4c58ac9d0f654ce987d3d76aac390ee37373c04f69bd0c7901ae4e82f860f349b17e5ecc4070b5770b1bfcb03f6b387f2f1e623f81785e0675feaba2eca7865d7f994f77522f1286762ea82038c019901ec245d53e1a8c759462af2858ce0be9ccd5b689dc323b6967b9728cabcb660b135e8d17e4f3761966a75026a25c6548993e63a0ea6bb1119a6cf478cec704593815fbccd7065d83b1d1eadb5505419237c82da1201dcccf6d0bf1a2271f32db8925bcfd8476e4505d1c74da4dc700290a116b771d77189bfe45f55d56d39c039c59795f5007f17a4e60b5f0e00dec6124a23039764b60f7d0fedf7a70e48769ee127378eb3b5dfbc1ecb70b13e39650c22ffc4f44d2f51c08872e7e75fe62d0b3b428c6d9e99ee68f242c1ac794fa6df6a9399a721b62e35772f2f92a52542485a884b42759d27aa88162c19eed72bc8b2e7007d7429e4e831eadb96faf85336564b33ad5e04e07d9a4e7453116f0fbcc1a780901903475a3abc6c59ef33d7f7f966c3b39e6a3bd729a4255e315a424199f80713daa684df0ec97fa9f28c5275d90e981626a4af49b2f1e6bda731ca924d28ce98eb8548140279873ac75848f0ece6251f12656d74b20a1ccc4fc9d832f58c6b88958024cb0b31a4f259e2e40b3373706d3c45a8ad7f3f3d81873293956536c7f59a9883d2bb7575a48d690ac99ebc295c8316c7aa507d316dd1719230d1554f38ee1a6a90b3df95246b6652b7c6aa12e58e266cbbbf61308cdc09b5103fea416389e8f855eecf3ca1d054a268f8e8b37ef27999acd3619972d5ab1168f65bdeae7009f7851a958212c315a58785acd1f45177fcf65828e4d09a32bd911690da069a33481429927daa2105111d753fa245ccc1a99771c51a6cc8b23103d4887a6951169bdd0ce946a9dab256cfe3a1b727bd3b7a6e04352248b685ba2a6436b981305e2970c9184cbc36298772cc40a9a75f4440dc5de5d5d2a686c0702aeb205237b401b48d00475bc977fb16824448f654fa336e45b38d5dcd7c5b6e6a9b8f2871b42995efde1dd2103e1068f3519fffed441c07ae8b16ed8a0e1af6ed58cf08a766d64c71ac57d1b637a7d7226b482f3148e2889d920c7090e4d1d8efbd7c69ca97189f0cf7d89f9ca68f82dab05b6454cf7d1f797e3ebd99221c98a7fea046eb1a5152e1ae7ae0797b2522c5ebbb1b02a6b32533fab678d682094101eb67051758f5098de54a236d8402e85bc6039ae3fffff3b18ee21662aa58754b6b6e36b0639316eb2043de720f32dfb5537a8cb11b45c45ea7dfa64ad62faa57989bb62c10d4fb6b68f7de67552b23665c60f78229a81a0310149168a9943737c52e39b300837980a450c9106c819e31e7d827d046f8d4ebd63fbd56a5eea53e4c9b567e7dfc7a5724c8efc552b041eb7035b6fd3f74825f2952e04d457c668e31935d5483fa185c8b06f5d8eca4d74222eed74058c3a4cd7f694a4239396b5aa1949217b37f13cd60a60b6ad91cf17abfaa7c25eb984b9ea45d8ca1a8b16efa7376cc6bc19c0b3bb4e26f295303c0ed21776d88d0ecef0dbb9634d7a7b0eba0e7aca9114df55bf317d5538ef67a1375e57ebbe71325ddb70d9c7ecd2e405477d21bf089f63c3c7e4b09e67f8df361cd8196f72d80738149f723bcd86ccd0aecbddea713973686d07c543fd01", "6a53005252", 0, 1890921588, 0, "7e44b3c01f6087b30efb179bb3bd2464820c885cd33dd53fa6916d599e6f6fe8"], + ["e355081701eefb986e9c5f371b74380809d69a64f097a3eb02773fbb3809ee0894ce6ee0d201000000085252006aac520000ffffffff0243af27010000000002006529e4c8000000000004520063519ecd5eef00", "6a5365516300", 0, 1535195325, 1537743641, "a751134010fab2d732cea859817145e4c05b3447681302fd8abcf853a8f51ef3"], + ["5f553349037a9220911b90d97daa797b3787a9d411db0c1be552b40d4997f51b38ca82a3070200000005636a5252514c45d1d3728f027422b94814fedf55bea646c203bc48ca851de1247b4321e5604152a9e0020000000552650000acffffffffddcfc84651747f37b53285685ae5ec972e77dd38194afd3bdf5adb34676b41a5020000000852acac006a535251ffffffff01cc338f0300000000080063510053ac655100000000020000000000000000cef3ac0000000000a4e975ed1a2667538d3a5aefe6e8a7a05dd69df79ffb519bb777e1e66fd234c15a1f77a5a98becdf0ac40fcf3ef9cffba284298b10b7b1e50872c2578f5c725e4acd80242acf84c3dbbbeb05ee0def65d2f65b1a822a5575b1bccd27b0ee4e8d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000896a282a0fc98caca92c1a3aafb0cf6d43428d65376282e2b615cf05fb0bfb242ea9a40c6a525135b81ead5226729f6f7de4fa90efbdc1a1f10ebdd98ccf5de124a9266c6324c13de10770ca7041732cc609985bacb933d373b60c4dcca69e8bea3860cea8ebf80138622f473120cd4bc367acbebb193dd21f21421d3e587c86030fee404e9bbee2227fb7224fb9526e9d39b9aa1cdadd9666d0a781c99ecddb670219427fd173805ae905063c633378200c524752140e30515bb33c1f1f415cfea50a02c7524d20bae3ddff3fc38e3fce5bc8232fc2d114858588641cb35ac58da851404e85a5cae90d6ac78290031cb83133c141557c00031f543f69b7e3e735d754031b5fa80d7d5c1d42ac13181c688b0e784d0754abbd39d1173e2b007c7c749dec032c25b0687eada83b831f89d937ebc5fa0d3d7636bb1e519966022fd03d4c399002019b4105d87d6697ce224fe74721ae737576c7fcdbcd55a71d65775d17bff87b022d9cc4a923949bab631209a5303085f432468419ff57f002f01393e5f9ced335032e03866b25e27460c77e326590133e89beb3a12f29b921f3f2267591c2902d8df6b7acedf51fcfa1b6731dae6176fa928f982d9b55f83a80d30a2c92c2bdb889515e188b72cb5b9834b2b4564bfee515c9012d29af16443d562720ed355ef024e80984e7869afbf3c9a190ee5761ea66c706e087ff7dda7d1b3b426a46731f26c0a4eaac1d74f7ddf31eae55ff587572340c64a0be415a5db6566fc4ca9a9f53d6f732b7dd633a949fcaab5fb14f976ac874ee89837a0ec9eb66652aa65b0906b01d5f220ede79eea37e13079f8f586fedd0c33630c25eee5b1770d02803b04834490e9b7b4a4de50ae4f04feb71205b5432fb32ec95d9a4b47a9e6b0ca10257751d244100e925104f849d24ae4846823ee3f572e8aabb912aae0bd64fccf73b8802d4d98eb33cd4b7b4228b64807ca0d57da41d03adf38470fe5d47a2c694e1479e9d77c0a2f55aceefc37a6c04a70125c57896e9b544ee4d94dea655e3f7ce1f473b89fa3595e15a26613f2bdc3981367deff59ff36a17b92b9f13ae9d07b352d463336c8023c0536b0e2fb11157c81d798f216d5fd750a6301646c7f39f282ce2f14902ad0b7df259f261666085cb9519dc5f2c8f826daf268d009bcb460fdfac8f969eee01491d5786022f73d05213b4aeba4a912afb99d467d8be631e5d4d28d25357358d3360a39818f8b153a33b464ff50ac8874e0b8bd8882893811862b1dd1ebeae0ff7b5b75292b66bbf65d528c9b122c5289395c1cbe10d16d2c4316543df3be8e886505718aef206e6e836dd658ce4d16b89dc190db699d12ea6da2d045f4866af33937377abd60cf1b1b3add394f011ee775b568d6f16ca9d18b3e6cda5caa594318335ee7bc3107aa337ad5a0aaf22d5320a607c66f7af2ee332bb916dc465f2e49d9f9a06ba50fc72572652f385d9c7b61f4ae6faa364cb34359275516765d791fbdcd952599cdad4784078fa9da616e108b90429dde3e11c331899db319fcf75f9417420d78e7b3e8dddabec29efa9b6343d2a8649dfdc26f1658803b28e254a5482f4ecfc813f0f281b92dc97a60694ea48b35ccb98c5e4122e86e2caf775dbf616bb9ab1fb417936d8898b71d468a2e64947c096114828886591206bec92b4840f6e62bfae44b7aa11311b6f50619a39c7aad05658d0bd22e7f04e3d36521e7f5ec42b618566288e4436ba5c3936136b876b107deb4593dbf4992eac731e385416d33a70f49851f28fb6908b904a37930a9296f55d192b2dbdc5780f782f73e731f14842a226c549d14bcd9333a32c2c6ac044b58ef771fe04d5a79c220b93350980a1e00051751d1b1b2101e6e4543450b124666c83fd5ebf641a6396a43a5507a7435a15be78122f69e44813a9fd307b954027c51ae1cf1c3bf4746d7ec7405bb7e0e0ffeac1a8652d0771c22f07700b190b3485828cea64bb2fea8969029fbca12549831485466c821e5c2d11a30fcd98890496b14400559777c2594220bc73531122cace4c9a1108fdc0b3abf79bdb700b29136da923e959ec4908264cbdc83c5bbfcc29a3526665eb8585919718d7e2c576659c33f7c041cc94d5038c696f428736c62a5a43064531ea5b7d1859a29989e352c2deaec9412973eb3c38c53097a0fbb79511bf7e5535b067592c1dc36493f4c933c374eb8574931569d8939ad490601c9a3297ec556e1606759278690b95ca3560e44088d69458081693d6ee8a782075d662ae950000000000000000e0e28e03000000004ed1f9d90ec1aea9691d06d8a150e78fcf4966d4f1676914f1c1e912a9f94ff27c4d63385372e12b9388f63a1ac3106b79bb81ad050f08e9a7e0051ea84df826d837ab16b210bff7e6585c798949bc163199976d254c00df3c2511e763cbd54100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6e6a04ebea5e2f93f659d03d8a82d709736e1027c9fcc650e815da43ab88c71e8cc511d641e10ef77175fee4c3c7733c81805c876f75ba9f3bc190b6a2901348eb7f7594e4301e12d77502ca7889eb3426f027dd4c56e71a9ed05c071f7d1637f8f89d9e5e46a602de0614632971d3d0748133dc5f1a50e514260f94f2732e20212058cd1da6b8c27bc06f48354bc5ded0dc3a51755db916bb07d1adc7b213e9b032a3d510665be7550e7781b3c29775dcb3976d77d4dc20ee0a8d7dc3ec55d5cf00b0833c6a2ec070eb2db3a566092bfe4791c47cd7606b16a986d82f5038438fd3208ae32e871dd259b9195560f7c5aa09c6de668ba78283dd55c83fe2650cdf7dc031b55577c7eabb3e09a8d472e1891d1c10c6ee4349593297bbfe09164cefe90800218a4ef583f08f274565026e134d70a1a08fc6262eb17e8b3490c3bec1b43ea86030ab38b76cd57461ca63c5f88b2c961dfc4f636c1b69f83fbab2a5df03440e906031c2b454fa80bc10a15d94bca585dce14ac260ee0c05d16e7556c5ee9d0d06ec702129c77867d51d7d866bba69b8ff113abd873fc2eae0f547bddc5852f4bc9cd22a7af2baff325bedce2a49628ddc76a7488d2e1d43669c5eba452f6b0a9d5a6f8f0698bb2c77f6fae1f9a48266fbb0e0ccb5df62b7357926cad4250c71869d29d504358bd3ebbc5439793268337ef61e4d66892d6b4accb987b690dc09ebb9053a9bffc1c238fb45df4ca4a97c12ec3dc302d87fe8b02ea17bf0e6063756ce0b422965f8db7765acdff62a788313179025cd74a8e29787309f7f5b8976b9e26f23660a2a78fe89546d5bbdcc2ed03c526e23d460d6d52cec96ee02f33f61a942262143b6bec63faf137c346ce4941620637ab5a4177f9523aea33768f475c18fa1f306b3b924cec6ec339f399f0c5f1a962bb395db6a54058e59ff115f5ce1c38b3b31a41fae98ebfb0c742ca78f958e9190002a105fde37c7026b6f35f57f6b5c4ad2e650e6085a0ddb8fa551231c4d66aac235331e0b0a0f686b2f0ff3a841e9b7351871fe48275b901bea31294334d4753ac66510265a42e44cedd5fc941299483e0d77b874c23ed6c802f4e15a88ae1b56f3f2b6901e3ed1a7f4809ca526db3fd93a19bb51c7d7533a187cb3c1c2fb94744f2e56569e6b79634c48880da50e8718209af856403efa6a74696ac0dfd3030386257a30eb9ce67ae7a702f896fea4613dc4fbd34983ed17c918bf12c8f3389ec0e7baa36d40f631aa127ff2f34c1a17174a964125907ed4e6f58f43b8e24979ac50a052af67b5c5701156365f7e14a25351c90496f87c886d0646d67791de47f6a3ab9a4af72f74a45572348bbc34cefeba96904c6b7e8b03780222e4f4cf4898ac7d6a053ff84906c50071f1c0dfb6ca5641f0815c20d35afc22505836b6b02d6bc188c587c7755e3b31183bbabf707d1f68f968bf1c311c51b59381be485eaf81fe0bd2c9ef6e015bb4e76ead089d73b55968cef3ccaf939c75cb3a983452333332bf90d18cdc885b9196d94cef6d06252d9459a2cffab4818433a67fbfa740eeac21f15212c5b2adbd041f96711aee8a01f6ee894808443c43cf368d10d70e8cf4121bc11be13ffaf381c254157f358bbbac5243512287dd5bbdf8ef053caf9f69d4d99db8839a57883cd3b5265499b05d1f0198479d2fd5d8245c3033c44e0127c88ba8722e28423be63e07244acd3c5421a58684d57a8883e089228abf5e70e8a2183fed9b75c4b54eedb40517d479661db15ae361b617ee2df097f55b8ce0e2e7a5b9e5ee5c218f7e17a24bfff38ad8d575798162d906bc0ada32e56ed22b99bbbf446ddf4bfb3c83e865c6604b0614fecb00f97307f9a0ac0881e37cbfecd396e1dc186d65cfb15f520188aa401033e23cf4c86bcd21afc0455c324f690aa0fcbd9f844304f663cf019775b5b05de68f2543f91b313f6475faee888b3c97858ec9c338422f51e9ca7a3d18268f377a01072077c0fcf6dc70953f09135dc1dba0e210989e9c89a5a3e94d0cf8e74bab1a71ae25add885b377e90cf3543f1b612f3881ed32fca5b2d99a6b6dfbb46276d1ee857a0a83a9700b23882061146a5958c4a8aa29eeb237691ef185479bed6013252aacdb32591d312189a57b9df5555d0252101c208145198e24f5dc9416baced220ccd10c0036e0964cbdf9a2b2d4cf9869130e470193acc0049e58aa957233553a8d0e84eb70334b654e078a9773668a95ed3b6fc4d31bb5af2b7192f9fdab770c7e15c1dedfe838579df8d568edebbc4261f7671d170e78470394aea40196d51d5efd5043aa3b5e1cf9ed4e61588f267514b58748936b2195aabaa7544d7d0ae63a6d7aaa88f35f0ca8c8f71018dce93af6c6474069ba6d6488d7b629a1f33a0c86267f7f68d2e90e409", "65ac53656a005351", 2, 1504723169, 0, "9df43f7e8e22f3d969f7237a8055b29018e42a8a0a9cf8c9d443a9a9d4360b8a"], + ["030000807082c403049a69a1eaac22bc1a94c392d0af9533612015d81663efd277e53a4f8ad10cd21c03000000090065635200530053acffffffffa5b072bebea55984e573d85494b60923ec07eb8b14bcfb1a9ba2559e1e4e29a9010000000400536551f789f8c620942bb006af5ab29200698047937928adb08b3a76adc12bc25d504c306f179400000000016380620b643a3383c6a747e78b9d7aa5a4d9b058cc7cd59d625f3ab1cdc501efc732ae57e20100000007525263530051639671d8a902371b8a030000000000cca805020000000007635251636a63650000000005b6534500", "5165005153006353", 0, 447425695, 0, "0cce7c743238c2c9d98db252b1f1c4259839d04428ed01d15448d37986898a56"], + ["030000807082c403049c0037174806b92cfd2dfea8ca7b117413eac6d48e6c8f79e25dde592f3feb5d02000000046a51ac00db39331c7443fbb76418fe33b8530e8ad80a375bdab8f0a73ace73a210efa47a7ded17f7030000000453acac65ffffffff3fc4d78a47e4e4e23e9e49a1fee6fa6bba3ec110550dec4061972a485d8dbb89030000000465ac0000ffffffffa097422d0895b9bf2d217e484aa2960f28aeb9c468cd7ced9ff2fbfa7e29d5e60300000000ffffffff0101450d0300000000000000000013495c010316ecb9000000000000000000000000002adf1ed6187f6453b43c7c0c70a85a4ebd935a582c89f63a11ceb14dd89eaa9f87332cf539cde006f1d16ff53e3912f7424f7422d947c9af90ebe03759dd33dfdc992c7eb3d780421b4ba27a5d7116adebb3ee2f305327036e58e93ffcee215400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000187c97fffe101db629ac06ee105e0508a656e29a1bbd479e6b87cf7eae81bc78089668b748845e77715668b98d549f2d6a200193aa24f10895edc02dc46006172c0dfe64f569311a80fe2dc5a4cd779b7cd1309446686af59ba009b07f2982d638438702bd84476c9889893a914da00a0b5bc775d886e3b540ce668b2b3ecc560213f3b5455ee3b11ad4c2fdacd97c7b7de934c189eae24ef9f56a46069a96242e021ce5ef2835495b62e25ce3ff9ebf8903c4bf1c806699239ba131c873b482df560b00c9b3334efc9ce5b8ca80d282154d36884024cf63840284709b7e1e9108d32e84e8b09de1934e2070234b6f21912ca1d7a9d11119ee8176f84edbe5732edffe0205e76f22c336b12d42ad25fec1a8404a3f1e8d56c3e4b65ec640a948f6189a4802157282e31578eda44c86bc9dd11721e084bd4841a4d99d82ccd5536f07f0dd9f0313d9c207c39386604c30f2235437cd567242d5c76409e235f93b3cdc3d5eea06032b5391c103f0657224ac3760836790bec6de9a38aaa268e518f6f6b1e1aafe2a0307898c9b865f25728a754caef3ef73fd8bd10747c36974a15048158f3550ac6ffd89edc4893a52586e43cf564d148d258cbf00901b0420e2a5bb64db0ccdfb8afa4faa0d7748800c0a7a262bc36b5fcf9a6a97e237112ec0dc58269423686d2ba1b372711eeac4097dcc5968af7f5b37e07adfec77eb289b5fd440ec0e7c226d3b9237760dcc9865a7a70f2913ac9d2e411fa2b21bc4490405184896c477b3d5bfdcd8c78a3e221397d0752672df64854061ed98a44032aab22bf6bf5744668641329683508445635c18da22d1d824b6682ddd9c206633b16bcb3f3c2c44951226b43ae1bb9307e465851519688e0218ed78c5e390cc49dba7ef88c33d89f5b8b65636b07137a2a7c3dc0dcc990ab1c956d58c9375176433ce581a9b20992b782e7f8f157ca0e62b12b6ce95f14c4e0be3149b9a47a7c11a2b4b66f8f97c9ce2fe5d670f2b087b676d43c3c1e7d0113d745d177038a4a3262bbe9df110939d662f169467e894fc18a364bce66d84d81b0e6301ea1f20cd5f787c275158ff41c89147893ded8be240f999e74493fd5dc3b2759183e57b749bf9cb42232b8be9b8323c62d47f8b99ef88770c4323ec1b3de57d16679ec73eb364d50a8919b4ebb72c2b1c0318b8401366943ce4a8ba9cb302590820b67941741bc4781c05113b5235c49b2fa7aefc8b21b0ca30224e25724fe59d1de51e6905b1fa0943c176b5285dc8fbd36db616cac659afa88d505a524c44808b69ab04e2f38fd761e95ddf58318d3dbce1186bbda9eb87c7317c7ea7e00a22d86a9944657fe3322ecdb6dc048958bdb4bf36f612c5fdc25c65c451ef576b62ba9857af16c58ced6f9b391cb1a3d95322b5bf72c5c68dd13e770f2866bcac747453ab0c33bfe304946b146c26f6c1b0d20f00db8e5af0e6ef2212982d188685a4e346abcdc66ceed109a58f9e5f40696286fe529ae09fd05b2df832789476c6b5fbcf8890b9f8d7caa00c626d3d3dbd4064788b1670caff9d31068384d7efdf3fd4fd7197ae4781a6ade4c8965fac11b8528f2213aab72e2d596572017c42c14af83a55fac85806c8f3fe9990ab55700c88e003daecc772c3a76859147c6d25aea84b1dd6d5366f044c95b9db1946d270b5605ad8d89c9ab190e187290adcb4d0fe200a1fa3a9bf8f2c0f40e1a29ab359a0d8c7eab300761ce64e2df051411ed7e19beb6e60d05f7919f6bc5d876c073b8fa3944fff2f86771527d18c09068d8acb281769ded8121858b79fafafe5b3e47df1214b8fa442e5b12da6b97e0c59c84c7a9d7932cdd85e0fab63aec9627664119a68d6259c304a6abaa81dd5bf882e890ac01ce9dee8cdd3ef946b0fde7dbcada7cf63cf0a50fdb409393d3ddc652b5575b8ce71826cd916327d5be7208d1c7f8aaff8540b7e6687a37ef4891843c55d4b12db669ee548105125b24815071a246a48624c2cf4eb32c48647861cf5cbfc92fd07942cba48974c1ea8235045469d39adb9cf970620c0fe76fbe5e0253a72975f0187d2e001b6b92632a342749d51bed85e02291f710560ef05b30eefbb5e084e2464d4fe292147471a1d25c11c5c0df1e544c10db4d944002a6afbba7576ac4bff75b9dc6038dc5b88c6d20f55ed8754b22c47078d307cd417ffa32f080db43131de18b75d5231dd48a117d0a0de3d7840cc5bd13fa2c23e9aa88911c1c367e53011a281074a899e85cdd87575590e8a50afc4173a594304e32c1257a6a504000000000000000000000000b1a12e3d8e210f41a24f3ca11976d57e9a904a4118c45e937d82ee7181e4840fdbfffb0a75dc9a7f8858e0a95fb2517de17496542e4478c2ba67f006a76d5aca83c1f14fdf7beefa49968b61070a67286aaa24974679d250972fda878eca725a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c95d442760828e54c6e7fdb96677e584e1e119c6fa9468e4684e6492c7bb9a9b590d7ca38d543ac28220e66be6bd655b70ca6625dbb95cb707c5f1fff488faf7a62cdf62de3447bc89cb4fa1980649c82fbc4bc1dbdf15e2c8a87849fae98c6075925b7fc87fa300de6f9d8e14a9f8c72122c8661c30f76e8ef19b7206b538a0327f6576785edf08c451ac78ec311e206978ac6aca0ae0e1abbae8e9cf61cdc6d031debe0eb1379573989460c741b119e88af7cf059a5b03baa6170ba716ea9e8ed0a089b47410e62a8f36ba7fe47d2f1274cf96ea11ee3a551ac94eb5b061b69c7a3f3b3be14426025e1da6daecc162e6e3431eee55a1aec0312842c2e24a8e3f723031d8d64760e3a94ab9e121d369cbd6a7bd1314e2bf0a5edad7ea570c85fb6aaac0314853e1e4b74ad301ab79c5f6fadee61b01e625244d442e0bd50e5b6c577df04030b8098d0af83b166797b26e3a02733b8137785fe34536c16d0742a7da9026e0c0224a0b38e4e05a672349a1689a888e878eba3b5e04fbe8bd0223de8b68fd1213b021d8a8f7f90fa9e4e13f038d2dc34d8892c33d97cce858811d2db8428dc29d9bff532e56b139e104033db66c5bf4e4fe8e980cacf9c70463edee4dfd0aa19cf9b9fb0f1ee1497a8b1a9cd49759f093d20dbbdd8cee7c964a1cb5050b69dbcce9d258d3948f42ae785c91be7ae5392ff10257dea34b9d49f101179d6ce90a27dc7138da419400faa07b4dd8caf43de715c8b9f60672e9ef8617e23c8522af96fd241c1ed824b4268b61076996d872706498a8abde90f211341ab21728d53ec805534cec88c2d8fb50d9e07f7b495d33ee3a3fd8ca676cd49acba6d327c86365e779f7e342ae19c1d50320a828b2963bfc982a988b533923187b7675bca0c3f3a5156906635aa74d593d4c15c25424981db85616e7599d90756062e9a3edae33095a1d0c99f30c439cadc70d2ebe3cccfd97bed51f304c5e6304af2e8fa4a8e448654e1174960115094d15bbf0acc5274427e763b5362b66af2b13e992c52b2c78fdd3573a0d4efdd9d0b91885cc3fca3809b4b6e40865f2d2494734924f38ff0e5cd3a3201c1257ecb8b39fab2647335df2bef13f619d9e9931d4a99dd692ace21216763acbf0774358c871647ca598588b37b469669be353a4afa9b78c86e697f3b68fbd9ec443ea0a6babb13e23f43d0016de577329c1726caaa2657023c502913e421aad5c39f19065a6cc8f5a32425ed099357ee125dd87b70ab65d3b6a858ff0fa015f968486e49b9ae5ea22949fea8f8d65226e633f5a71c312b1b8d364daeb806071f2af345b82787b1dc7fae53c7553870b72cf18e24b90ea3f77415819732c41ef66472997477a44fc89c74ee54bc8b03b17362e7eacf77ad22f71e8984631c1b8cfd7168e56465c5099e5a7f43f6738fe9e2fa15c4b93f435072c53528ab255c44b29be1c40317173d027b0a2323f640f7b63247f9c4494d474531d7769b74811212a21c6d211cda2060b744741f45294aceb32d2bd563f5fd8a78ae5fbb3a543fda3c7dc86f622943751d9c4e30b83640f25f6c53a83a1ddedd228658c30b7c149dd059b5008b441967156a342255b699e46a73a9ac02e77dbdc951609b43e83f2c0ef5e11d84c2c982a977fd342bc07d2b7b14ed193bb5a13745c21a933dcb4a34d4e77adfd4833b6f2a111a3e201296d79d0aba2a5f9528661814fb0f6de7fed12494fca36315104b7dc5f0de2be0645cf71a84b958c3300cc26b4a5b76ba63d5a863b139525354d0fb5640c976c6b49a9c75ec93081aaf63d4da2a5e62c1698df6a6605592831cb6735c47411d33c3e7c6db13bbe21dc39d0882e7124f1bea9d6c2535d0011d42aba16e0415cb5c452880d58ae5791a61d52928ded062a84aab9b1ad2cc62307ccf866ba76d09536bc8804dc043478e860f920ac300cd844b6dae576f4b56ef2ae59527013d0648b9325ef6c7cd497043f0a5eab6ad07bcf2746086cb4cfe01d53478b58c716ddd9afb0a9b4401f3bcf65e387c47bc5e12189d754ca226860680f278ec1176f61495a6e37cf7820e8595d0876f9fa957f16b158345ef8ab5e0a64ad2982bfff3733848a6b31fbb830f9b55bc8cd2c66f0745f0c77b5c905e9d5984d938d5f300abad59c265654d2ed30a84e3bf15ff102bd1b979207ac6d85c45ce8e05a1cf170531175288842b46d01cba853a701d3425e0cb4933dac9b8ddced61c5b1f7aa89acd3a822951e66f6bc9e268dabcd2984fe30d51f69fc9b8e584ed2a38eba30000000000000000b7544104000000004daf62f4e875c34c76761ae013ec727b84d0737445f5ba02de460fb61b539036cfae2253b44f9c8df09dcbaca65c76b3c89e8f0aef17863a4ec4b6c567bef5ecc429846bde72de3d65d6b88e8b6c8948dd47de49916bdddf23cadae74cae32e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000141294a1697a0ea79bc806500f9a352c6f791992c5706a9987f9fad468dcf08d9739c1bf750c6af86bfc0cc38839297b8266c7d551fe6ba3a9c1493c2a8be721f73ea5b94e3602782c9e202bf4062ec4376cd75a6e91cdbd6fbbb43d030998530434d422d76a7e672ef3f2aa020c054d113fe78a36a264ccc1e6754a0207dcda0311ac1d0a2cc685ae8950b91025896756e391a3dcba21aba1fcee4092baeb1c5a0303e82065f7d8c63f4598b2d9ce44967ecfbc206e777a7677c49daaa8567f3a7b0a0910766f418147562d5c241382c23abf8a8a046e165d012d88feee80073dc3aeb9ad9920315636152f3be418901eb624fbaef0f83215ea83f0cf1ea6703bac0c020d7a3e373873e29fdf0020e3bd4716977a487c4ed40b1ecc3d115bcb402292ef022388ec547caa786a164664329eeecafb467a5b39857c143ea947b4f1fa0e49d2030ed41488736e798e35b8984862cd7a494ee260da60a4c2631fe0e8282e09ccb00214304252256bc88cf09271f87f8d2dffc87238514907165fab307d6efa51d4940225cab71e9659feb4623d32e7484bec20d070bbae6f64276a43b5c40b31051838f292add8546514977fc70be5bb3d15441dd7e466f9258b746b0b460abe3e9bf5fb96911ad03d4ec733daa654a847c6840167bdb9ba3a59b3f5ac1edfbfe23f93b712486454c904ed4d858437b1eff2e5412533cbdd3d521753ef4ec15b2e60cd62436ee6c55d420481f4f51f715ccb0f350b41b24af3e01b2639cba84e3d6925ffc61616ac3cfc4e034b02e3ef17fc5d74baadfb971365cd6893580b2c2cf306e2229084ea4b6923b7e35e2bff021f4411f1251820e90823ed7f05f93772d2c24d3649259245227126a8a72aa411fff3c6dc66dc8613609e1421dbd6e068746509a58e48221a34dc852b090f854ed4ba3edd2d50641f41be4ad8e2bbd29e93a9dc3e17375bd8e8bf77a5b2a58037cd8250cd4a6ce73a12ee6fd98a85fec232c50f23a8e2abeb4be71f77b173da871fc921fce59649fc89ab3e3181d6898bc69de2b1960d0810cd0043cf610a9f3bb0b724ebcc57c7645341aee8fb2b77202b119fc5555bbccba06ac6d20d15edb7cbf90de6993ee5c2b51f1541fdad5299e1ecb1b4628822df08e16b5c8aefdeb13ca5c3b284ceca10ba8591b6c0c759efcbba3c149fdb32043b5ccdaecb0b44f0a976b0db56813c54f9094e21bf0186993523706facd70efb8b848a2f70cfc33ca29bb54575e3d7dca16a436115b86b6264af78418ea698183db96eb343670a460eb8e6708c41787872b4bf662e643e467ebb15f12ce04b95b29805fe413ad3c80b307219b0a5838d0ebbd3044fec6932836505a7fc39dbbe990e363417f528751cd824523389bce6bb7019c76c3ea20da3aa0ce43086361226da772828b96033a90d70710136929d9c9442fc4c9baaf16b7af2988111abb3b42bab5be66d7045f5c962ce6072a7890b99cc40ac0e665f687eb5ab8da15b45d4eeda6003412efe13ec8691ff3885d7bf44a5bafb8409a8d0f71364b67fe10a1f2fd9a174df773761b2420673399f2d8f69757583d23b31d64fc2ed927a5611afe9e7a5afbb5722fd99fbed18024625008558f41d5b3666e9d3b26ec86f5a8cd9cfbeda2e2a1133c63db9e69a6e5bccbf964b40f6c12384f66aa264428ee355b3928b7d69beacca96bd361449612a4e9bd85e69049d2655477118e11756830182318ab98f598fb930031815756c5037f73d37656c9323b97c584ead1e6d3bbfcb8903e64dc411f2e3eb7eb7293989ddcc2e2723268d62c32fc8c97527912fe8a410aae9149914e3f48b745333a07808d108f8a1a7581e7ffa498a29c77d7c75bdbd393e6c79c8edfb183033afdbcfd1864f16b42385f6457fd8ecb9c5c86a8fd138809800e1cb185c451e99ef0d4068920541225ea85d518bcc477f113f7b06aa6bb82c813cd518fd889e300473d7d5eaa800786c92909fae16d4ad832af022602b3e9c6200da889c6d4ddd27fabe5d9a3bc056ef008fdf7b919f5312f72f8d8906dd2ce30cf55ea01091ecfb919ec1ac6a636fc75e754813a4db05f90e70939b2b85d474faf99020747fd76f8c7089a5ec89b79a4c103c1d6aa7d22eb60a38cee9b22a6b76091c8ad0b51f517407865f78f9a26d81bfb6f000785248dca8f388846336fa9bdc92fc5208fb449d71633b9f7b796cd5e42f7e12fb444a7083a9650d0dc80aece36f426f99b366bd59d2f71144ef5ff90983465460cb055cfc9e93edfe86c9235fdc1fda901690fda733473e982a260573fb3551b00bb64e883cdb255b29ef5730301c918daae8fe6d7c2aa6bb8f65d62503b7bc63181957bffad54520bbda3543749956b5159f6f701695b0cf89a92d993936352056864577135ef7d3beb976296da22c8a0f", "525252", 3, 1327450234, 0, "aae29618ab79cced8ef5ea1d3cece2d9929fc785ae40b6a180718da9f8e6910d"], + ["030000807082c4030313563d567dc428474cc4573d5bdc469f471fc852041ed26431708266764fad1e01000000015190d3938115e8b929bfed012cb9a0f12e736a19798c7c2e3d094701f94bfb26b48117f84e0200000000ffffffff2edfd5d9a6ed5a3b342bbabdb97afe591d631d83fba1a1b5c4fdec81fa8f7c8c030000000100da7e70d202c75e1200000000000600ac00005300c509e70400000000090051005263ac5363ac000000006c73c09f010000000000000000dfb8d20000000000aa3109a2ae0e9990db0ebc9372a8bc00675cc5b5ab8bb980cdc12caba58b55f30d0f92c8c7efb57080af134df7ddfe9e0ee76317c54c749587fa0ea287dca090314676757d0bca5bcff25fe2c954ad02d3d2b835cd7c9fa2c363127ec99a624e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008712b37312f94c93871c1cda196490e9f82d642bc639766a7b965b8560c287eeaf9020b80790a23762f1cbf0c05610349884f1da8171aea7c696e80bce35ea9f56c53ba8a3f79fa462dce8b70bebfe31ec29818e7cff42f7e057a6227eee8f485df4d29b81e115e118cd4ba63b3e9be2d30338bd59663cef6a146de6d8f642fe030bb4d8bd4db5c69ad96235d45073cd026bbae40b0300e0b59c3608a83dfafa6a030e72dc28a231eb1846e83a1db554777032cad758516f604c6e7ea7579d6bf26e0a0214e559c96b2bddcd8aca1e028b36ef0e7647dded52067cc6b25ae4cf83c41550ed71a9b09605fce6f6c270b9dd603c6171ca708ca814357e6d098766b9bb28030a9408efee7630b0f439821ca5611e90a41c1aef2bbac4371a080656de8e18fd0304511a817322aec59ce28426258c21c28677561c563a7e8e11ae97f00c39093c0227bae9a774fa5c82edbe22b8d000b516d0fad26030a19b237f81e6487a07b54d0202e765038655a080338bdd946ac0dde64097e69bce645d2d15522062772fcde10216505b847db39795bced52ee21ea803ccf6fa60d7fb2e749b6c99f66ca45f660a501fb5c6d99d0d71dc5493d8096cce71ecf3d86e0edc83f53da977e1d8712a68fde0cb79e0aef8106f30d83a9cfe313e23dfd072ccbc4f55c92ceb4721e7a62266cb55783cf4ca50d2913808700bb74eac7e4a9dd58324693cc0d54011854223341c20b6d85e64bc724629b16dd0d19e96cb67527a684e036a5f7fd65c96b0df1dcf5676c9f2010e5bc260de045fdd804084e4810e1f5b1bf5273fe33f132528f27355ef41d5c88f512b546f9e2c77da879b371636a41e0d211b9fa5c22a99c81c8a99567bb221c645b447f2a93efb987732bb626b0cc43ce0c85cc1ba779d91ed0eb67769d4278bcc9984150e74d854ebcbe461386a66da7138548114260c6a24b0db26bb1a650dd2b53b1a912dcbb30b18f18a1b02984c90dd314e10bed7411d6e2dc38070ecff44048fe0f3b2766edfeb65dd609e62fcad9a900d3547f0a956ccaa098947b08142c452b9e72b100906425e32bad478c3c50ba5d9ac555cf6a003e01b105003023fac70fc02cbe484647ef31590216bd6ec7ef28c309fceceee5c3963977323146149f3234eecde361c79d14d8b2739d155ad5eb0c17263631b011c6b942ef048876d3e7ad8b9432bd1a0c6d90f80a0354f57aa78fa15f8249d1b0132d8af8b2c931e518899025747f6e53f56ce8a6a7fbc814c8924a7b38841f6bef1247030280535e6a6826961f76b2a9e49fd05c257b04b5549b7c1c4519b2e1b76856b37b195ba417a988d22a021b18456be1cfad221031368af11ad6c1ebba6c2f7611455117c571f094bb8d6ae9f7b9b7501f673dfdf2763a3cb006946766bdb86767d5bbf02c0ea859bbf543425977fe35bcda7ff9d45d13608ab341e139d43b9038440ae249e677640ea5ebda8fa660474931ec07b480bc0219565081d6a91b41880b130923d9b0c48d668d613d8c38d62a5b4c28e2d49a03761fe0d8841ae7f5949030df338338d75e48c3d8f9d7ccc42642f66076b5a741122b61aa1b20fd8d1b696590ea40421adb631843892a443d8fc432fad00b9e65302c47caf69c096b9d81f93658db016f6daa0e2a74f01bacbd944eb2ff67ae1f198556ea09bde5f6af04d104e8622c97dd7c0173408f7d94e63e060311eca6537135d2d456c98fec0ac90bb0ecbcac2b7bb0a80734fb82d362b7713fe8b743e5cf550ca3d3712ca28e5fb5f273073dc67d55291d729ff62558bef65c932fb58db686f02485b443200d6d6e2b0c3eceda6009bf92a774290e6f70e7244cec48c78a3c9a0ba69fcb21060e37648f60591782a3a452b77096183dfe9b202cb547eab885b2b31d5a739d0cf6e54fe71b0de3c9054fde1104f8bb1223df57644dc85c767671963729b579fc9e6d591298c26df758f8c009368ee9b16fec4ab71d6368c109d19b2efefb0121ea4eea97be39dfae5914a9429f7c6dfa188523a737583a33c85d91c42040dd1dc0e3cae775a3b9b85e13ed65747666523aaf78ecfe7d69f5a7556ed11ba23be6982d5d1bc58a5aadf1095ae2cff2d3573ddd0ffb0cb043bd58fab87ff0e112936d3f710dd769a0fdebe74fa8e3c7c6d31376655bc72a2daba17ca94ddcea6babf4c4b1e3c2138d4535cc1a45f174870a01b253495ab86ff82eea6578f6a3fce36517a39e68e03acc263c8bced20e4501b8cbb4343e0b996ca01d6720a9db655e424a2539ee521749a04e6d35893fe769dec10f19c91c02406b5c40e78a69da5e402e0b009485f89c59b092cad27dd036b264d48eab47828ed2e9532f1baf6f1802ed550cf4056bc304b5c9e2cf80293e9bdd36c6b0cae5695bb724ab28ec6b8734c1c9a2c189cb6e25da0b", "ac656551", 1, -1180502046, 0, "5db3f2065b522ce97ac4f83b4ce825034d77a3f0587a742f98dc3401b610d237"], + ["030000807082c40302e7298875be1a830d27656070e045ce9ef526c838ff456de8944fe6b88d00b144030000000953530052656363536affffffffae6141e030915b95b03113dda7f4bc904bf63d0df8eb11526fc85488ded01d93000000000165ffffffff0383614f000000000003635152707e720400000000026300d195540100000000026a0000a0fc65000000000100000000000000007e88d203000000008967469374b61751dc159afb25dc81218566818a2b78becf3fcd43849587c9772d5fa09f36f83d4e761e17bb49f52a6a7f1f9847f18307ce384e7ad64172ae9c6035448c1adb21b096d78b655ae1ab35f2f01d177986b07704bc345b9b8030e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e78e71512c2b59f450c710a19b7d543e70ccf6e5a16347dd9baf30ee740c26803a60578fa03b753c4faf232aefb87fbb2cf178ccdd7af2644bd5ad9f372047394bcfd2950d1397a1bf4722832d46880ce227e457041c6cb8b5c0267573d8812d7130dd1ad0c3bde03e0b2ac924f831c020e2dc1ef5147fd921e50459c67f6094030d1367f373ec94e2bfe4d63d257cf9e309afa9ca78a8813cb333a5e487e3a10403148ec8e37b6e4dd28051fbfd80bbc10f63a5c18157843bcc4087153ff20813e40a01b63f8a2e8531807d2eb57ffa7a54d7d71632870325d149a3c89068571549801905c74f75567f73f4c276caee0612e1d43e570be60fd08afce6d6f35dc9beb20217ae1b797f71ab8fdb069085e22198ab402a636dba289dd496568e3275a1009e03057908a31d14cc13d9b49679a638fb70f1328b15a9e78af46650f49995f2ffc1020e198717e795ab018f0a1b477a4b94675fecbdb80a6ad700d6214817dd8189fa032f4bda07da8ec7c36fc627ed9aafb1404f22945f74cc460606914659c79358a6021219f92eda9711910533de25834cb15c4d026499b31ecaba3d77ef3da654aec0a3e332847bbc28161a47f81d48cd2f10a0edc6ae6b7fbe197b532304ef2a03ac7ee86eeeca51b2e38906d3e5d3e0af188f02e83cec3f5d8cf585b404eb1abb696d4c3d2bbd17449388b7f568be10eb8ef632e5a66999b62a7650c6115dcc1c747966a86e332b887886bca4c9f9681029c3ca22b31c39afa083b2f586e55399bd0a10814cc7707bdd1f5da2b214b7486efe4602e0c0a5924beeba0e28b578f195539e7da27cf8a370544c7c1d5f6cda6724984cffa32c0f12d8dcf566316e61fdb28d324cc23a7669edbaa857b1bb319af06700f30b1a80de8889d15f9e2d47e21791075db8b58514782e5acf1008d52d8c0d0e5f02687590b1d27e23487a4e9fa4d581c0a4977efc17ac01e5265f934599b3f1c5ceec12ae23e8b6bc48e5a2a1764fc79f51fe87dc3dd0c89f705bbf59402a04b65bb506536f747a8669d44e60ed35b0698c0f3f96e618bf9703ae07e04d09e0f844979810a44978253107fae3b9b971563b15fc2af1947ebc10dd3742188f977a1a36cfee4f720aaa113fbbbc5fd08c8cc079b72a3b32b4ff273d1fc2ad24caf49b83115385f8698b7d69bca2e69230a617b4a17b9193afbe87b3fe233942caea25e9dddebaf701b8fcb3a5e92571ebd874899f4493484d07db0769815d30b62db8d61a8291f65db74ad89d6cea7a744a2140f236c36589ba4155120951ae5ca71f0ec55183f04e89f06a9ba09925794b75021f12a1245df54b3fe5bd6aa7d9b5972da44065c4f4c6aafc2751266018f9356d3d5a6fa48bf0dd40ab70b177aa6325e6234850b347795b1f9efd5b1e59722dc75d3ead50fce5b5cefb04e423d083bac168204e6f8d128d765a53c89e18a082b0e792e044a9dec72d4b4577fd94346e91892a8ef10fa48f0ade8f7057146be39ad1eb0213fe052b473a199b76e840c312837b197b142eebd6b6d4eda7841098fe54637cf4a871a3cc7b93dd27e1cb22833fe11bc9c4d7bccfd4b66faae1b043a7cfe79bbd350c6dfd5d67352dc086cf6a1a97dec9e84f81b1481b59367a17c25ccfe29a25d0f0b00d0ef23358f2001d37e151797143eacb5b375b93d8cde1b5c874085184cee5b29a6b5a5b987aea6a365ab43c171ae7cda89179221d38bff5ac18bacad1bf69ac05f5c3f7d93bcb6fabb254e436fcae7d4062a839c8378ded1d2e6c961cfdee003ac0798d8970d6203ecb38cca3328d140d54a4e6ba8f2b4d22e5f2bcf6f4072cf85d8636beca94fe4452bf8e87924a5d9276cea266c4739f72836a14b5b6e31a3e7eb9491e80547ba990107041a5307068a58304ff3e13379ad5f10df9440180dd5de4711a290ffe1c81124b44f8aa3fb24cab216f1fa506ee7d46bae17aad459a9a88e747f9acd324553d3e878804e94af1680d28c90f5bf42b8a63ffd615b427c9c131c195d7a965eb3a19d09bd16174f01b50d7764db283919bdc51ab5b6200cf95036bbc3a32d80a17bdab06d11391675be87b4322bda1ca530c7a559df985e60be841d03e6c71fa9c3665e42e332d1dfb9d717dda3bbc0f0d4eb653e667a827a2dfc4e870af7eaf7cd3e28e1f7afb2c2879445affa90f2839c0aadb3bfa3608e5c94a8ea70cbf43da40b98bbfeefc7dd90388ec69e81cf7d99bfbf25befae5fe2a1e4e640b567eff9b6f4a7992a4b6b733f73e27edcef57d4d94c38171ef842c9d52026418f7f52c69669c82f97d6d55499044906c92fcd806b1952de09a4b51606d10ee0041a3c175c5ea4f31c1d95bcfa247426d0f8a9a225decd5d5d10dd823304572989a4b1f1137c07dbfb61251751746d387451a82031623601a9430050a404", "536551635253535365", 1, 1364084365, 0, "8fd0dc44840b2b4c50f886ec9a25b1c334845a0eda85908b896124dea9d6a097"], + ["58fd6b1602a5dd117a872a24dad344d7473a348b03f67e51eafaf4d944e669e4e986a805f90000000005516a6a6a63ffffffffb0a5357f718ffcea3919dd4aa8a7b9af22eb45d86971cfaa40b3ffd72866c03c000000000752525300536a528abb575104d09e6704000000000452526a6a0f667e040000000006ac535253525321788702000000000953ac635153656a5100ad28be040000000000fede8ce600", "6a6553516aac5363ac", 1, -819439571, 0, "241b86ad733fe63511e956e4f2f515f3351d4b81b3e9e87bc59c7305cc662d67"], + ["40758331015c6866d80311d7a3691ed26f37910dc92d3157cec923e6247d85f53e785c447101000000016a96b0d4d90376cced050000000000289ac7030000000000ada7560000000000075252535151655127d72b7d00", "", 0, -93875733, 1537743641, "9caf02f36c0eac4e95dbff0f9def401fdc4f7fb663e73f5ee21e3103ea5c7799"], + ["4f40cc5d0329e0cfe4ab44bb51bb68736da005cdccb3fbe87d62286a09ba5a5015851653e50200000005656563ac63ffffffff11c8cf2d8202601d8105a47d95433bb376f0863b0828c2ec4032221a3a583b2402000000086553ac5263656365ffffffff92ac7ae4849bc2cf7c1fb621ead48dd8005f8545b13ab0ff17d3aedce19cc5b50200000002acacffffffff04b6a2d10400000000076a5151ac5163ac4d355b050000000007536a65ac53ac5270ab52050000000001acfc02e703000000000200650000000002000000000000000001835d020000000082e5ccf352ac15385bbe97f1efca7fe3a7a15e289d9eae7e04c2805afc30d82afed44a925bfa2f42dbcd7ba7df6f04c4684910be53edcbe116a4769b5f1caac3d70e30384ca481d228ca2bb55a13de8bec5c3539c95d83d3cecae83b7fc0d52c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000363067eb424d0b3669317c9189180d360520fe5d17fe0ad64d1a7c2f685e23f70cc209eb4fbaaac68b40256490d0ce3459f98678f2792185981eafb05ac257cd039ba7b4460400eab97875ddf0694f7bd1258062de12b0bb64a0a1b6f0da4ee27faeceae3b7e326789b368cf3bd6f2d6014cc44438de75a4d0ec49d85bf610b50315268610bebc7a1c9e122b83e6cf07def15d771fcfd783ac9d2b4deb8ba6f022031ae4f87acd8500e3780d11b9d47d65521e6840c3a9484e9dead618d330d35eef0b052248b4aafb96d2b5adc2c4834b7fa580c55ac31cbb97de1152fc5edb3a8ad7eb2a1e38d85e1f1479ef965c7a34803bb0cfe03e16ae6785c9eb28ffba7d76a4022caa3a5e2ce3469e6cbe7051bf84cc6e1da6b10ce7efe7adfc519f3a89a3c9af0203083b6aca32d44a691b66f154c81f278f57eefc3a6b9f7052532f09c0840b930324edd26a97c6d71d59a3f333054ec970f0de499d9ea69a27213554a3e981385d03212241f1ebe4c5e4b05779b56cc948d3140f1af4afbda6556c80b7d504dd3ee5032a26f3bb38286c62065c4579a4adac38a17b312630e9f5201051c75f031092e167b5adfece8132dd574cb4ca2ffa4088876f7070a25c4013795a57a1a2a2642a9343dcb5437820b9d1094fd71b33803e73691bb5bc7fdab7e38f18681c691b1ba0f0b1e1880f793305c28c1e9e79969b9f2057007bdb96d26583d0fe94c60fec5b21b95d8b58fd42192bd49d9423c3b69a530a8409844f26ad6db2cd638964b93ed387c618fed709ed46ad05fa2e87ce05dd73cf473203e131761dc5e177ad23b002c6bcf0e61894c85c174e8bcd1964f65b99a9c68dad4df8a79e0a754075e544c4bb4e23c7336d168c091896e1e0eb077d0495284adc118ae5aaf55a17e8e835c977cab3225802d7216ea4db74b5d6655403032f0daf83c62c96e05dcb6c2db0bb01c8d4f3817787d94ecb6156e45556a3e322c2799efa92a5901f448cf3db2335649ce88f9545993c17e77a932b47b393826ccc82cf5eceea64ab426f22bc8c1cbb4c414bd70db19728c2994fe42b442e846bd58a4ceca586d010f948a96319705811b56df8dd61db7ab4fc6004cd3c73557d3e290a7d6592f649fa46d9504a1183b7d034ff8c28649f0aa36431cdfadf18fd3f133af7a3dbe228c87376188bb1f6f095feda1ac7a8142739e0891f98c3b0cf90df6daaebffd7f8c248453bfcc19417320e08141ff2b197a40fb99ab5ff23fdae8608567d2b2b9eed6397360e1ae23fb2549c7778a996b9abc44fcc7c79ab888d9ae8b70d3a0b2c095d7661a8fa3727d0e4992cac3604873a4bb782b130c6e18460dbb3d404b8b746e571477b7833b424ae7c2263e678d2feae6f409a2ba679fbaf441e745a2fda7c0381213922012acfd9186ddc3d428908b25548e87b7d9f5544738fb5e6e6167169b5af3d78135de6da25a7454b89486f21cca1adcbff14175724366151f63e6f11bb9b61a701666f69ffa0bbfd93783aec394533e2cfda3ae89af6abf3ef05d4955eb0d95be0263420a98987c5d188f23460518c272622c52e1e9878bf9276c4ca9948c37bb19574e96ee8381825f8bab9738d5840022a6bd3cc9b5bbfc2a86d74380ebca2d6be714b18999f951ea7e525a1c31e88e744efe7516456b6ca4b161a97639a7537c1dc82ee1033e4a9ecc4f7323f4456091c61a916694b772b8eb513abc24858bb5c9df29a58fafc1f8f384752733875040b074cb515d9f611f0a2595b1e614c0535dc38f8f6ec7d984c4f6c071e7b86c47bb88d13c292bc6bc66986f40f45f2b0f79bc319ab64d18fd032c14c31e832ace7b110e5e74095d681012ea17fb263b77679bfae06a8b412373f4820a94561ffd5ac66b7547da29a0b48b95fa2c0b44cadae134ce441173a1108ea21bf6e5b4a3f11bc1d883e3e7dc4b6d643688c39f2d1a6ed1fdf481dc120ff51dde19249e2910520a19a2a7d12b6c735d245763a65b8285ab069ff5dc160f6908b06535b1c1953d43a4058316890a945da3341b20dace153fbac41d5b67429dc95c070b15f4aa0c7e4aac18882b3ff56362df36338f6575ebe1fa1c6ec9703056ee04fa1f78ab0c23f90a793ffacb74e86d8fd0bf61fe0d8eca7ff4ec76a65057a81017e3c343bb878e732fe1b09d69727773b27f1b0d2017c49fa5884743c58aeb5034ae4b7b7ff4c2f87a39daff06260c419921e7e42bc3c2f8ed583ebb06ad3046cb9e12ca73d47a7cc6f9dbbec337e61692b37a3407f98dfe4cf266de8f30217b438000000000000000050d19b03000000005d7593425ee04864eba8626ca3716d7463328e32632efddc5fd583f5042750869b7b1042e56a06c0376033fa497daf88a74fa0b306ee28ceb588219cf8337e2da33f9b702c2970ec4eee3810cfa3334965e820214a6c0effc05e6faf5e012bd2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a63698e09e26507838ebea0459745f09f42fbcca96778d02bee7292aaf2dffc00a626be92531c59a99c4824b71669edf2eb6007f2eab802463cd1353df0f1fdad4955c515768085dd0d2897f1f21f52ea4745f7269ea26c8e2543d4eed8b4cbcdb8b12f14b88bd15f8e5b3b92876af3e3c0c9ae0d51c30d6a3c56e139bd23a3032204ccc9882c1b4d8134bdf41677733e496932f6b66641f9704579f3e0ea2816021bd53720c05e8a7c97766b5fa043614c76a5c79ec63acb7040239c493bc117fd0a07e0cd7ed4501f1b705aade9c1f43bda6e8b789a2615eb68cf1694ada0c8122d97604c7ebfdcd27938ac473215fd6ea0286c9150084ada92c6ad56f6098942c80215078eab432182bb6c4d5097e6114add4383c7676a047c92adce008b47f2286e020ad5cb62dae867477b7357f3b5e392683f92e7706bc983c885a6ac01edb353c0032a647f4ce44bfd8cc57755813409fb1a76cc310f616b6d37b17823e5826b7c6703303afd347b3753a7360307cc1a5a40f16595eaeb588800a17436602dbd432eef032818de664f7b987c807efe2f17ff3b63828edd8e2ad83012bf14d1bb0f670480482bee432f2e7338ccc09dc182df3a6f0c7e6e19744e51f8aa9093ecf033adc2434aee56465ae7c0d483a7a6160c11925114a2602ab849130a9aa3a9ea782534d9631f8a991fe7b8695f09ef6fef30152fabcbeb88503c38285395771fb949bbf3ce798b09d32f870659a7621dfab9d80faa7bda447fb86500352a366b58ff06464d42473fb0c0d27f2a57a37903aadaab5b62738f6974ed716d221dbc2e7a2af7595030f916a3763584d585bda7b5345118aae3af92b06737266085c50bb68bd8a587205d50cddf12c263d44bc9dad603c292d53252b8d20ac27de131fda70bd6c9e138cf19aee28c11b8a1e1d653b624277111473b36ebabee404ffa5ca5fd89a04d9177ae443ecaba6f7153c7e722131a75a7fb31bcfc4726f31ba1f03a13fa1e47d7af9de1e553657f393c58ad3652e93a2ba641fd8115231f02d9444f19c6387726ced89caaa0b1ca31311311057d050248d9e433f59bf6f859b56a18672ecda718c4bf6eccf2bb31982edb65812be1ad6329ee9159f65ab7d93945f490e696745e16991efd11b61dc25403516e7e39a4c63457a11e291fbc58c90f7d6b26b92e4f2eb50f67af53f89023d3556788f7bd5b844fb037d12f19e26445bcee47dace863da143ba4e2f1e51200b7d680fcbcf62216aec3817aa4782df2428785b89658aaf28fd0ca9b8676e0889c6556354bde7714ae9e57208af7e14dcb329f91788814014a01a3be6531cea888b9bd4476a4c8673dc83549f574cae5e397438fad7b9114f1e2cd1c40c5c624917ae4d777d6d3318550b7b92ce849acf9d67a9ced843f807da7b8b68907e35cab7db0330c043dbe084e58468b29aaa2f9a0a777b4cb23ae0c9d0c5708885b255ea80edf8a789f8376f83da23786c9673ff9f3027e77449bc8509755de38c36e88b4eacae748145ed07b6ca3c96b9aa59878b46fc15e32dd1d7a986c3671b9e788a0103fd35d74cff92cd111bec33a0c988269fd9fe5406dfe6fbb24395366fa03eb6fdd38d0c53c6552817b226eb3f739468cb78a8782e83fbc602583cf1eab509a4263503d2291735131c92798e578aee55b362f0308d221095c3d2f251e166a5d24237133a3e14cc3bea168c5893e1d874e6c417ed9245d48ecf23810414d846553c4407b308c0fca487f7d87aeab2412dbbd4e2cc9f5e40b4382401052845efa1681bc1d08efd97a557c09fdeb6b83e0b42185131bf6c3c008bd724f77a5677847719f217ca11cabb4914fc09e563b64c9a598ef36fcf48e8881f11e5819c23688355146629827f64fd1fca93bb34106eea9101c92526927f32d986c834e0ac1fbb324fe3fb21b7334dfa804d193eaa807b92cbb2fd5e4ccb14a5cf36aa02677ca9fd05e4f661e702f15bf80d22568f60ad784303c24d9a1f1aa4dc3cb9af203deacf393400fc953b945e7fd5ec45853b90322e8de8e3066a7a905c193e368c92ca3c08eb844ce85b89aeb5d873a508eb37ac13161e67f6b40910ea7d7f3f81367df9c31a8fe090ab6877a1e163cae3660e63d8f749f3766aafed9dba90b42a611554a809b34ddccd9be84ec6ff84f8c0103033f7fd6aabb8012b5080611332a5472317f701553f29b6422e7d357fee4c4c1f718d563830ee0c1fc0a177e6bdc7e500364ee15484ec7471a4a083db143bc232984d51908be51f40bdcecf855112176c6983c3cfd0d881dcecfff0d2281545c99db89161bdb1e97450d07721475595e388e2782a44acfeb2fc5221600abe26a2135ddaae3f1c2bbb91bb75964cbd2af6acd16ca21148f93e703f7d5d2deaf1e65088dc61bf6c5bc90b3869def2ab3103", "6a65536353", 2, 454520553, 0, "1c7bef69bb7beae814ca0ce56d531ed715bce5c50c685bd3cd692aa08faace6c"], + ["030000807082c40302a3c06a7459aa3717febf09a5de19e61ab99dd29ddaa2d0c0c135941a5be7531b02000000096300006551000063653517205bf0d32f29f433650d5d414df7173976fd39f71910e70f422daef073b6ea7b4cae0300000000ffffffff01f6dba10400000000056a52656a530000000000000000030000000000000000716a3c0000000000eeaac65cfacbac1ea8b63b3aecce84488caff719003fbb8201ab0291182feb9781710b2f172bdc59edb8150f25e2fc56b4dea01ecf766d7c303cba13c7f050c201c735723a2ab56e9850f18dc7f4a95aab5abc07a0174dfe8fc4f02e783d2ae900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000643109701f53593cfbff8f497cf881a5662cbe43564e9066346159637b1c5b142c20dd9385fc7840072b326860f9288a0b8fea26f703974234fd777189dca89a0bec8b691f2c7c2b379359b1c67f0e06cbac14ad1a5bacc4fd2e5d7e2943a093ad0cc67f3e0321c39028e29c50bf2183a4badf21ed5693aeb29e2070dd8dc1db0317896564c650f9b78b17a85cc67e8056b4bae08cb0a7030b1aeea8dbc69277cc030751a6117ff9fe324916152406f20a5690d1e584d24084edfd6c2edef7b16f9e0a0245b5e20335e68a47c54a07004ea5d2de7d66b4cf1179750c089b24aa718ea0e7bf23d77bb8768216f89b5064a6f000e91b9954de2bc3468a6eb91010642bb0032496a9e088a8f2c5422044c765a4e2ddc7b7bd3984434475c24426bedf6977e3022606d54bad80bdd44cab03776134ff546c53a097011fed79e744a3c9d0910b06021f99d90de96d0c6f3fb697d3bbee49dd2991f354495c917c7d107e1c51cb69220309cbada843f5ff7b7a0fbaded17356aa6f8493763ae6fcb5dee84908836885030200b4fe943cd9954b3f4417564da69fc519449d50b9d931df11abe6027722ef262ee892318c925c73a6c4eb3ca572e3d0a607f9a33d010cdb9a0e2e28fea0d11e3baecc7ae6129128adbcefcc742cc515db855f66e9d8399e324d4ac2fda282e8c9f96d4d98f94352d13e546c4b622ba8f34b8f611fb095a344ab87f2f7121b74d97886e0f80311f7b422cd9a1421a2559749695a289bd9353150e89410bb38250a42bac265230d7ab12aa6ba213dc3f8dee3f2485062d6280bee5869065400ebad466c607abe5b535847551d43bf95a5f0a35454f1759dbfb056f34c87b73e0744ff50b32d035757aab5f78b8721ff0eb627d1dfeb1253e4aa09c91c0ef0fd45d16a7727b9ee901224a72213967ca349162537ea810e487ef43f135a04cba1be7bcaa09899605007d0f51b9fa05e5b43bfdda92cd9c43ffea8caa470143b6804b25f0213f603061cb17eefb955fb50784288d7d5e3cf7830b8bb452bb3d23efa592f2a04ecc77444defad0cfcb281dbd33b2db8226027709a1f4c5a743052f7c9406f3b15a0e85aceacf83de01ca009d86f2b18b8f5f7b8f3a7e1cb11b2d87e3f157ccdb24fd25ead46b5e40195277c02d6078fd745c7ed084472f78eb2dbae0993f5dd9bb208750eae4a1d339395bb0bb29693cdf3f5f41e053132e7addf3e82b726e1606994998b20f0220305e76d7ee29e6d5c74164030d219899bd8833aabe18250a277c35aaf1c98f436ce25ecd08255b3117d3391d67d86e3db935c5f0f2c76720264b51ee77fb203d688da36e06aafbf9006c745b61a5179268a4e53122b20a73afe5be244e7d6f5b6d8ee605160c739826d3a6cced49598e91322d2e42dfb5dbdc5dd8f2bc4107395c26b0e698a74339f698b2d8090bd9e048b27a7f647c67228f94fb0aef939c2aed5a0a7c89bd0331b9d6a017be56076f5c17c2a070c2e99db4466ab21d3b1c7f13da3852a52d1f59c3d9195b820f17080d97d24160188a55ff8693600b2ecf751ead8f994a61fa3bd41b9b0a3edb3371203b93f14700ca25b202dd985d18b1844c76fee71392938016bb2724bae89f29137b7caa4066a07f9548db00fafb4dcd9207c8f8b7bdb38a804ca84c5024253385976c4e938210aa5fd540fd81812c1c5aee269ee8526e041390933ad3641990a6b7533284519a34f5069e4e1f4f34546a9a6b237da0dabf1761fa4604a7b05806b2fea7cf743be00ba1b0abbd5e0f7f31c3edc6052db409635fd30abbc20c9369a7ec7f8fbad4bee3b8648fefb15a4107fb1498738e40324cdaad8a1996dccf26c2357179c243a2998bd37cbc316c35da20870511c18fc43be1fd51cce94b534ae8a97225eb2890189d16cd33b557dd00ecb4b2b3acf8b953ee5139dd490d69eb98fa74e94d567f52127085adef4373b4335808ebfb7b637a1c825f228f2ab21240fc39a23fb26b1f4b5e07ed22cef18999e6a9a52e7bfd5caa6e7e525d9edaaf8235e3492c47965623c9df386649ade415fd2565145661d55138f651d2b62545d41efe8f2fb910881a0027f735ee5707de2edd7d2622940a34773022a8b1a5f155c2a717d8b8a5487aa999c2ed9d8ee6919ec8fef95aaba2b5d2a315728c90430539013b3f534115e42a54be001321c2d846ab09b001e2f3f7d35efbae5164d275429a3359562724429c456d421afc5c34bc29c380df1ffc730a7d8ed34d277b021bae54f772582c1bc664a47a9b183c7618b568fd63e171020000000000000000000000005ca9cb8b44eae2b5e29f050000d2e8b8948edbcbfc6edf52b85059996956ae513535913dbf01168f945674e270b7a52155ebe23c928088d9802dde7c3fc4a56790ce2112afd4a0e07e00a4f42b9b7b1b75972e8d2d65bb6733fa375cfff38abd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000abb897459574b344db21f1137a2b180272fe826dd260919b7c872c2aafc007028ececa5e60a03079952abd745284e8f18531454e662120f6e962ccdf6ef64072478b86d80c300b1df6dcfb90b28bccc73b5702e77cb1841ccd833184f540fd75504a81b344dd7a7ca6e111ff7f3410511c70c838703056e213b6e9661647720022aa4d7f71bf483ff46e37570b9bcafc3e62645141a9859579fe2b7b90287fb0303283b2f54e736235b3ad6940faeab153aee11cb8d3e1ed7a9a998fb831260e7a70a01a8c80fb23a0682e5f452238107ea87affabcaec7e20778c267668ffbdd3404d30e8ff512320b6911ba43de5711af24defe24ac9708de62a532c7cc961e6806020749c499bdea63f30444d57d411326671c29d405d4dd7263208b0401654c8a6e021812a63e0a208a64f5a8f331d74df9cc40f6b2b1fd3c2c565855d4657927c99c0308819ccbbac57cfbb161b2ce7fb3f17b4df80a147e1488e185898fe3fa55105b031083d268f0adc13f2f8b6dbc03efcbc8ea57b89dbf33e4619d0611bc01325fd603184d07ac1a329e7d941b3a7198f4ca272ba10b322cc1c26eed9148ebfb8e8218c321067a1e436df304366f91156249e0e5f0fad0d9dfd5716070def6c89012bf40478c2ed318e976e4d20880074302ab6e75f4e62200859c49b4707697bd0e3a7674170e3400d30f8a9f33a9cd3d932520ad6afa6eb873a8f18906a848462a56df2609c5de14641457a51c1ea0a58c758198312e62ffa0c1b4d9cfdc2f4ea5a3d6fe812a91b1242944863816cce8f781b50e96154a17678469c268c2026bef04becaa142139e20ec3338731415d22344b04486b7428dde9ce498bdca0f8f6743af94569ccc2e3a1b2d1af6e817a67829667515ca82529075f493f834515528d0f7f55240fa69ad97551f7f3e1e880d38f7d05c7fe1f2ec710c7f5653dbc7ba4d02f4580472664b52cb23510f2ee0c026c8ebcb171e141dc0bde79f06455949215d45a344d11279970d9922aaa3385f854916ad96d140b737a99c44e84df56fa4b8c69cc3964a6cf709316a9a7b10b5031562e473b78130be5adeb30f483ab9f15f2cda2bfa58238e813e4c95dec20011e0bd5aaed63a61ccb4bee1ceb0c487f6b3e44af536b3ca18edaeb1f5a7ed943d2c0173935eb965797886122f7c1cf094a107d68fb9391e7314881ee29e4ea74b01e9e944a9cd07822dec6068280ccfab88de6320c848ecc818e7df24dc413f3cfebd276033a70e8b45d6b4cc89b0b3bd9799efec46af4177bbab5779e108fb49e4d9ba3c1f9b940079d426e0d6f9c96cc4285ad7c311876edf8ab1eb52412337308375f94516102c210b6e92f8b45a81e08acd7f763e77474049ff9d13ed3dd453dd4651d89c4e55c11bfcc9ca8bc79988b402d83c793431344975114f937bb42eae7e6e468a00ee399fe3509fc3e140070f0cf38dfc89388ff5bde540b4d9fd896f124f2ef0c9f2446e343468224287848ea78fb23ee2e8164faef2d67a7f82c1ea18d8d3ca9aae9c5b9794166aa333ca2ad39e868909b2ca406663197ad9dc4e42604c2c86ed6b9ff36f4ee8909b3fc0bfdc9a61539b719482dea07bdf8f078fe5d00b7cb814b843969ecfba1147c68cb09c7e111314db1b761c345a30aad2585f05f03762b930bd09b0140ec7c209f61794f0bfb1ed7f23c886dd26b27cd424e7ddffadc9c57985005452547bc2a9df6ae09636100d4f0cfdda2d19a4cf44f142a30325b4f5e304a52ab35cc181fb580aedea16a12e4c2d2de8ae368adaddbb06c8b91727cebaa3daf5fb881ea169999dae417d37f58f906e72b673e75eb55633ce5fa5c42319b93fa4e5d0344a746feda2df891222a073674509633a22007a555e57b3d007f0b682b1bc39b5e0d61937d0de89f4dc3c4d9340da650ce9da8e098673f7770547e5c67ffe53f900ba82397d27414eb0b0014495f3942579f512aaefb4ae6b503cea36dba31fcc4f21b418cbfb6b62e467619c95519e58d7575ad7e7dc73edafdce7043ed86d35a52ae448017b67494838dfb9c9bcabf79b38a98174e3c1ff7c628dfc912e91036224bde034da892200b174ccc6d7b09d5e83963f3d5f8e8d6ff46cb0db98f7f46835de0dc27383b4296fa8f4b1db3bfa218078c64790a333c5dd5fc49fb92928b9c60a1f3dc822b069d2cefd26fc7972d83a5b73f53bdf737e9ed03cbbcbc73243b441aa0313dca7908abd152a80578f81ca1920a05b3ef54f16cfb48566768be4961e4cf76d122177db97679808fcb6b7447a55db45ab030000000000000000000000004b143e7e83c36ceb4dd05557dda837587742e83e4c2c29daa92161bd2d465604447aa656271b72878eaddeb45f48ad0935e3015eaad62533922467c0e7c241e09bd804c1fa63dfdcc1922a88198e71911fcbaaeb3f75a180f4922ffee380c25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000baaddf5ef2ba42e80d59b7bbf63f675d665da8ec92805a3f89fa25237f439554552309f32f725bf02356520410c833d5b653d27c5082f762c97297a391106a8d03fb2b1296e944e88246c6cd7278f74e7b638bb54acd6dee9663fe7b33a4b295a1a45258ba2fa18059a9d575c76ea57dcc175b73346fcf1cfbea68f75660b03a0213935186fd960e15197bf9f3f4a19801ce1d52d16756a06912ecdb0f99289d76022c502e6784d1231271c693f0950e5e9c5c742180596f4d56075f726e1cff31360b03a6268f525cd1d5eb4f97d9efc619d8b8eed6f0572ce6480376f47a1dbfeb3d92f87c6eb2342e91447e0e7fa224d85d1e1ba2bce61a3c862daa877e2874cb3f030f9b3143af7bbeafb9e78410077e72037312d347f1f3418b80b289db6c9dc212021e85200eb94e1e75161ca77519f33d9904e0bb566263d657288ab50b1068ec1b0201d067576067b6290175150f9346639be6e9bf131e6e8da1c3d12abea2af85fa020d7a6d1bf95afb83bb0b042194c08142fbe96a1eb071fac71528a49580bb8fd70200326ff21560fd6afa1708598bb1c1f30c40ca69ea77a36c3b7385e29ac6364b5aad66c66f2b22bb906dd3f379b55461eb7ac4bec83175312283bc0e0f464b281b25a145d84e1ca6ee23ae64d7042d2148dcbd7c0da89024b2d9274560e1569ce90b64ff29c205ed9951b575b50fd17a9ed42f42c069f8b3eb8e64e033bbc83b6f22b44d6472c2797421f5bcc8e5f457552f649fb4eb03d0cb6d5894e388a2211a465a24a2bc685908e00036b4b912aa74bb8a14a9f3a25946a73edb7d4e10f6f18f0d3bfedfe4a80bb72e9718e93fccde1f3df30d5f7efeeb2add242016ce4a388aded775f504f82aa93911b1e7b966c7540360aa53a14a268b7e2961928aafb5580370217d4ce8dfa8df81c1eb29007aa2531fbd4332092573366e6a93cf4c43d5efd12121ae791a514c3291904baea8560d868f3b28a2c2411e5baf699da52e93b31ffe46c3c22a7778307ed94364ca1be2e003fb1d29d8cc0ba7d55c05eeb917652f66364e385c7cc2033ea2dbdc311ca59845bcf2c0a197568f764b9560fa9368c3e1363a61f2c37e47ff6e9d3ac55548c880594876257695d06d16330e43049f536eda02b449e907ef381cf8b3c302c5cf0697dcedadf7b29c5b998a1db62bf8287274b88ce60a6f23bf348991460b3201fef8bca2ac3e80b9205f84b8845fe26d4370424b2d73d3bed16640b3f1d50dcbd8b485021e213342b07a6d77c030b8a8815c7b0755096e313ff8c24ec99e4cd45357f7d588f9544dac8c686490203b644f61b737651712db17d00b2fff53a5991038e70d6f0d34d3735595648aa8f230390fb98441724363645dbe251123ff7f0c4e2140f7610c9201c2cab7cc9e9e38eb543c8818747612c46541649e0c26127c5f8014413fb422fd120ebcf5b0d42ac3836f4a948288e1aaff74f1d4464063c385e0c3808196e5d6ea6249fc194dcb821ccbadf9dda53791476b77ddf527dcf523648c452a605d2f5acba49d4421f32c0853216c190d7ffc54f46031278155eee586f863ecd74cc05e8772cc3850a5b3f7b7190c897b67d8272e39b015e8b04b471666e99f4e5dd1ebb088fe071a7f92519c3fb91151fbec59e7854c53362c5bf612c37599f751d816a1363b1cd33f533ce16012a97c78b567de16991a414e9d23bb718463940fb12f8c9e5ef08f8e2ec758ac2c9bccdf1ad3f17bc00f647e7db6350f3b580fe0eb5fe33633bafec6afe7bf35f9ba4fe528f23df014702e3ded233c3d93f80e6aca5f4d8790b24790003926854954d0fe26d2bb40442dda5be9ff4c7152943e4cd1561c163c2f4b0ae99748a4f9cbbbf794cb7b0988b8c1e257e749505e54585748444a5565e35abaee4ee723e4ad1eb5b07b06d6f19f09da93978417ec37a7beec0c786527ab255079f1ecdfc045a9ca18bd315d321df8eb07b6cc8c3a1be7e381102c83b2882562a196ae98f7799a60228bead6e0d4c089db2b6ba8f694ba9e468200e4582485d35953b766f15b6e542c66905e94b6bc39795b90aa591759cf3e3323f20d70351bcc84a1853146f894879193ef6c76dc54f60a67718c2df50f8a2aa7cdaaaefb47e05bb9764b4d9f6aeb8ac1dbb69e89a823cdfe538123ed82632f6bffbaba80ef056d624d15fcb6dc7e82d85ffeaa43189fdebf0950725f51564a1d332c0bab122299ea335d625a344a4579c8da3626d6e6a0ea9b26ef88b464f3840b2a1cf069e90a892c7052d8b63ae296fb56321fb7a0138f1ad3ececa81be26cd0f6b72fe18654c9bdc2fd5faa790f9fe69e99a78f95cf8b24fb9bb7e09159e537f870c58d26e56cee27e63bbb49f65abf5a9c540cd857ff35fc80067bc6c4c918a6992c46252c05b9a7b6e235b6c8484d5d0f", "656a5265006a6a5352", 1, 163497046, 1537743641, "6b7c8aa1a2240867e404c60191eaeb1b0eb9aadb0202fb58152ff8c9e768441f"], + ["ddb7a80d01b0af6bbf9879ff248f6bb203da4d406979e6b1a1024141aee90af0d922b91417010000000465630051be75a3d7014e70be010000000009535253526553635252000000000100000000000000003ab1680200000000d447a55412e915b403bce456581550e32a110178e29c564cac9c8b9de87bb4a6328113fb8146167485f82d06e83905350348578c871206f662cf4926c0686c4c1ed1fd8a15ec74d2d6c260edcb7d7be132535c1995d055bd1b752baf5025f05300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d92e281822a9293628ef0c7004da309976a26673072a3180fcd47992f4a492a984005846828b2264f732a440c6d7ccd70fce9a66d3e33a8030630c861707581176119e8a6853e3c2e0af41927e7b0f63aa4ea3e806eec13d07fbc751fce726fa27ee33aeb4c292f3bfe2346eb3d8807d1e106b684db8f5f89be6bfdb0430880c03209f67c7bafa5aa00e2d40870e81f1c0ec641caed66330e7a1b37aa8abe697fb02253f38ee75be92fcd301220da770d2e4f2d17bf0dfd8ffe09b2408a07310149b0b0300ec77563b14c54270b7bc18667e0789b692bbe3bc86016a31c0af09643163b7787c69b1bb6fed04e6e0f30e34dc53938b3bade3ba1afe4dd7ef2e25281df2022a9066c9422b03af44dd4efa22946f9a36ae126ed82654ad6e5f383e8c947a5002023f61f1bb485b440e18a466877b19aacb225bbc4a864e3cd2cc1aa35090402c030c97a1013bbebe90470527b9a207585f1832a7a70fb02b07a53df154e4a49f4d0301eab468980da8f4951e342ef4ca3a6cabb6ac4645342fa96d7b74472df13ccb0221474251f886415781c39a59514a84add1467336cc4717dde828f5b181e1cd642fbf5d9842795e5a4a71b71ddb69f130737b841545e525f3c8941c053e0a7b5ad5c00a80c2f44191fcc73e57c8b6492b4336e1d870008fb00507d3e4dfbd6d81c23b40929a982cbb4499860332f4435322b0197ab0ba6a863baa02cd68be20875f18a9bdea384f47b848668c2f4ab32ed0853afea74eaaa0dd860ddcc60060ba3f3ce4be3f24e865bd80251860601522e35f41f5e7a28696112db53306ceaedd739de019df47a147f9ff3e045bbf87510715279b38827347696e589c357e374217698412a676e9779078f8dabddaab2b903bbeeb7181cbe36d7f20369ac1913b1ceecfba004b9919437e65ab8bb4dd6f3d3d9b1929b072723a658729718725eeb7aaab8011f989ddf5ee2267169bcbd279985b42c29cfab53941fd5e1b317d1f1b1c8e6bfc4bd55ded6a566be8b277abe001faaad35b37d1ac9e3c7a342f26eb81eea7008a28773150e081e0f1440141cfe97b94f4f2f56bf57ceea30bd29806fc51839f1b55e3000590978bfcd4fc076f403bb0e3761de54b9e731329dedb711c4af5852f22d338f2e6d170b4a2d008a51e411aad1fe1e93da12c9abf02faff2798bcb0b8827b2cd191876b557a90c65b5a27e31cc754f791605ac9ee278a7cdcb27d928a1e4cea3bef83e4f81cbe38d46c787c3f29c93f39e5085056f6a475bca2c43539497c4705bd6d63cf54c766ff568775703f5db52173866d34ca2e2a124e78b591cf8817af2cb949c5e501264d13d2fbe8b3ea30a3aa7cf01f94af0cce840b7c226c1b7b635936dd2473f7afa4b41661e34d90a5b5603e5bff8d265e41b8fff8f82aad4762603fa092b042d5cc205696eca7465c5c7e10ca5ffc669885ef295fcaf3a6acb90d9a1fda9ce78f8eb0877c127761619615e6f325cad160353d84ac77ec815165654be6773991b7e6395d5ce87af03ea02ed0038f190d09acfb467f4e2febc58888595170df3e710507071b2fea7c44780732668e1744b9da45c9d2d36584a2fa7cdfaaa3126a497311a451f65cae4a6833f5a5dbda8dddd28946e75e7bc387ec1e184db8b1c57146efc292f4826a7fc875a6b64d4327b9da4749582408fb73e70bc6ac07f7431db1f6253d5c826ce0f868b9412829ea218d5c5d63c8c8c18d948d336f8c26a4b3b5020c85d0afa799195fb94d94e7780b6fc2a7bd5e39757cdf38bbed630474276bb657acdc435560d813b5fd6146b02329fc0a85f70e6fbb2e80a21fbae1baba07bba558376ca5866b8c4af7bd34caa186e6379c781036a085707a287f7030b3d45f5ace7d4362cd30e91e70ab3401326413e8e437b94df674c6562067eb6d2eb93d618239d16b08d6a52c40f9df8874c7ad2ae179179ac91ee524d75e5832a35182109ec156d8b115f49bc5e83a0776d4dc8b774f6e1c3c56091fc96df6454e4bc6b217e3e75364de42af7f50c0b825c1bfabbcb96c196cdc9ee5ab869052d29c083d09bbe3c99aa2eff618a901eddc7eeb4845ab29015b72d6707e8c0b40b5529195a6e401fadcd324e6fcc48cdb9926e60e698136b2c0294824dd8db55242e6de40c36758d8c2ee44aa9d75368a84f85f4cb612a8479907720fcb031b94da6bdfd18c468cedccb8251f6381af143bfa1310163f0db046b0f0b5e3a7879f6703b8312f2d1dfd1f1794b97d5210d296125564baa33844f6377583be690abcb36dd78551e6733381c1c0b488da6fde368714a6eb913aaacf326a121f682423be49eeb6581d31eea41db6ad34faffce83a3d03abfe788dedba6aa952c442f2add5aecc0d674e79a062f1cd969ac5b4f3960f8ae46a1915a210be4079719dba048ac06", "536351", 0, -158921530, 1537743641, "3620c8ded84de25d229172ab9f56331a0ac9e6fea65bd8a42abd8c1ab0489c9e"], + ["4d54744503251645f026dd4a2ab6b80fe4d0f38fc4a535ff0dd67971ff8a6854d0f4bea2a600000000050063006a53ffffffffc75befd492f359191ee380cac3e3a7067d3ed523ed56a06a1910e83ecfaaa00f0200000008510051656351526ac25d92294f556b4482de21f8eb8471acc05e5db39cc1265a25b2e8eb34cb306e998a1869020000000163ffffffff04cdfa270300000000016a50fb8d01000000000365ac008f0a95030000000008536a6a65516a6a008c0f630500000000096563acac6363535253000000000100000000000000000a48e201000000009da54701bbbf8f51eef7a6a078b0154bbbe175a93b109c3cec7544d6080da499ad35ed45b2ab6c5428ec485e4081619c6a34c70f4781bd946d67d75538676152edc7cb69ae7981211de405605c395d7ca0b6e5d74c4cfea74f85f6f1cb2b51cb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c81b40e0b8d9162651317fda2102e4fde2b6d983eedc83609baeaedee56e768650f6133dcd2ba62bdbdc9a150af343e4e03dfebf6a0c0ef1211dd0a9b89d27542ae7c6e68f6a1f66e4b345a14405afb64b3da93f6a1e2c5d89d036edf91428b0069e4d2c2b6fe2662d68d15ba0d9c136db91ca6799765f006c77ccfb224d9c0031108965bb07a085a5472af2fe982b8cb956da1e62b9f53bfd5fd567c152c9753030274faec23ed40e895b02a2bdba9bd4996718a379f106147f5c609896d1cc2000a05797040ebf481d228c123385808451a71e7ab515faaa0d45db906c23b1174a2df7b2da8c02d2b84e891b41a4e34cd97cc5ba0d3c3b8e306a2133c326b5f802a020a62b4ac86e6bf664b8d9cd74e9d6f4f9b705a3705a757fd90f8892136799a36020e81ad92d2ba60739e9917ca119a68cee1020cafbd4ff199ce25bd528cb7ea3e0227531092f825f864e9f4a6c51b5d8567145b05d254b52c2ccec4c831b445dc54032b9ac56ab151768286301589329a49ea3c1626b41ed01c887fe8f193c3b6eee9022275542212ae69049186c1d594baa511b36feae3ff5254da1c55dc10300eaf5805b2e0c85ae8e840a71cae5a973335d26b77b95648c73fa1987fbeadefff49fb75c733fc2b529ff9068ffadd91d858c42df583a9a504f0f4506f8efaa7bcb6414a753b3fce0db43766ca40b93a14dc81412ba3b4df24bcae4245a6538e81a4ce8b01e20b07a1daa7e1e7fdce139058fc38d69f10902779ae9cf8250dee4bdc44be4f1f03c42a31a2b98e6951aea158dee11ac15ce7b8a5a251b80129cbe92796426e6f8a75ec29456b6bbc7658241acacb296f0c0bfd48e1870f16dfe73323c9bed35725d2a4377420d4ee80cdfcddf1e2d708e0231d811c09829ef1049755dd31419aa0aa23229d620ac7553dc5783387c682a486e70799d47c4a816f340cf4fd303433d06816c7b56ec333cfd1ac030dcfc93cf354782591570c20c4211b200b8eb078fc4235e16e7802b02da0fbab0ea33d51da8651f9c243fcb4639372882b4a736ca35d3727f968ac8c8c841fcd4a4b4d402a830044f71d2e34d834ce73b157a52cd5c5ad94cfb11fa91d343387ad43816ecd3e8100b1083b01ec5e3963dc665799ce2b82804d17c74b38f4ee79e23ffc55bde11643970900a2bebf0263ef2b1a131552908fa88ba0dcc65fb978660100dd03b6901b239200e96e39e73c14d98da9d128272f8c8c0838be0c1977b202a316162c1f1cfa6cab3964732bda1b8c9299f93ad5f10755fd220feaf9821218a77e4915afdfec541c0cc74689bad07ab6034ea1b3f5decd3ad4aaab03ed47a3ab12707eefdfb05b7791d7ed1aa676cdb16780adc9b0eeaac56e91fbaa24ff4fd229010292ad5ae65cf23472ab8ff58f1f76e320727235b0b5b5af37c71888ab45bd24c176528734cc901269341a1700963285e7ffdf6bcc991fc28cb51b249737a75d30fdc7a5a59c7db885c77cb1a64c6a351123b67ddc8840cdd7a3a1d5aa62265e91fbf65322832d8532ac7a60fb45c07461c2062e2953782adb8520495e970858f055dd181b2aaa2cac3a436c0f35007c34851c4cfe0476f9a267c69d936acceb7aab138a0ef12e0fbb34c9c0f7fe1eff67da230700863c0f27a9c9740cef45a55e2eabfbcf055856f9afb5360e8d22fe4f099fc06a058d0b307228a40b85754dedfc1fa54fbf55d3c0b2c45b03e6b14a2a55533624af1e0437706a7066a1e8d9480826a2f1c0bf80ed0531d2665fdd74e662c5cf3ea499404b3b0f011e665d76ff029edca7e390c0edac6d2897fad365e70008c4a07dcdc1414c4335d9c532a92edc75f96d8b61473a4f4c24695ff2ef5dda0d7f4ea7fa3e4503df5c7d27b121750839e54abfea21ea9288994ac7fdb6cc0d713ffd0d86375ae93cf4de6ab6a82029a56e959f6ba5828c698f2c3161b97ebf7cc19341c62b962ecd6d87ebb065461112a8f5698965396b1afe4b4c2ff5c5cb9fab0b27f75b2c73ee76adc01adaf455e2b6d2a9c1d1b1a56bcd6cd23ea69c73c23c682011b4d3c46007e68d16de892c0843d2cc9c98e5b35a86ec1eb3ecc0cec678c50149c892fcfbc984d093a3c9535ce27dc3b0ed24d9076e0aeaed5803f3e4e9ebd58f79c94b84661e4893bc6f5dc8c50c813c90612abc98cfee558fd8dea2b18618a9c85d1a8aded1b0c83fb0cc344efa83525753c99ec5ff3e07958a66ccca8b601a7a08917b6273a5a1c34df40ccba27d159d1c4a01a8af82ba766967c7a401b3f43262f62f10c8391c383ebb7d46ac6811b46b313e53a3eb40e9167e064ee835738b98b1fb679738b327b4149252f733ce46acef219569db070f137d4d12ec4e63b3ff7e3a2ce9272f5bd250480c94bd90ee6554c96f92ec0a465dce8e8b8e6b02c2ed8de3d80b", "536351", 1, -671021817, 1537743641, "963540cfcb0d91bf34f5107cb6d476627bd182bf6ec5012dd0687d489faaa224"], + ["2e6b696f03df66e8cc85e37c7589774955bc77f3ddd3916890bdf1d77ab2bbac69b0648f600100000004516a636a3d2e795602c2c534a19b9537d76897027339fc538aea9687f886168058df1946b211759d01000000025165fffffffff97909b06a0536357af6772040eca4513c22dd6f0f7ef5cc6977b7a02fb64cc30300000002006a7369ac8e037f08490100000000076a526a6a6aac00ed5c30010000000009ac63656a515263ac51d34ee302000000000251650000000000", "53636500525251", 2, -1560523293, 1537743641, "5eb40539467fb8b917bf8dcc84eedd75f5b861ce8a9dd4556048d0043a6ea2d3"], + ["724f167302b11544fa822156dbf879491f786670ec9570ae95b63f93c70c0e154c472e310c00000000060000536553516504d63a38b6b350e46e083c95015bf13da719db12771473f9a266287a37e34362aa0a9c0200000002ac53be41f51e043e51f90100000000086a5352ac53acac6a1894750000000000090063ac51ac65635252c6cda2030000000001533989b80500000000066a5163ac656a00000000017310f505000000000000000000000000f4073840fbae733578f5c5f02c33764dea19aad4c53549533b96f2e81a88357585a99a5d82a8545c18b504fc5ec308cbf8af257a6a8ccd1ba4ef1cc2f2927880f04554fb62acdaf6c6ea1156f7ccc0de8fe5bcdef65f44488bc978157c2c8a2b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba29392c9afca96582f84c96b58e90a31f7428849bcadac55073c4b02d7d154e238d36287a7f9507c4ef93833e6fe2f55eea5e1c23b9f6a782b882b9122cac398a00f8718f0e6f080270bdb2b05f5e0b64b5f860b3ac28eea5569ecaa605c26ca112dcc42820ffc47741a76e9fb8aa08e74546fcdddc1df9b884cfa6a0dbb15f021f2cac4cace83dc5b3ea347f03e09c5f90d42fd8a47f58fa3e7c697cdf0e0d49020bc130a9fdf6a3597aee7f321d88869e242a875ef48a9a64cadce94aece512d30b00293e8b43a1ae150de7e373097b7654fb46d36c3a0054dbf518d2c8afd992cfef24e2b8bbd31b7f2f5344c147ed46a8943175603eeefd7fbf2c18ea3ed796200312801eb5ff785220af955db44eb8f67aadfe704b42992187140b7e9fc2bcace9021a15ae89ea02a833fb92b109bf6975ac56bab793e5962a97c41bcf41bca12209020cbf8e502fdfe5486f7471456e5922f6039df8b64a7732891649b8fa0e11ba1602032df895dd38fd6ac567b20c9047d45542968b2906a48a559f86801ac50d34d20229b06b18ea35db8c8ac5117136430830cb3710a8b2a335bfd2cae360d8990da1c13cb887e9758127c39b0e68e895261dbae10a10d10008d71076ca1622cd301a1cce6f3cacec9283b413b79d00f379c68c6765507806d380fee3a0dadead4f67e409b6c1290a70bd356396f97f718356826c82d8268a82855fb09162816c3b76ee5bffca2ff169e9671b8ee07abee6292ae0599941280725278ea0d4a1d0a7eb265e36e1009ba9e2fc4006b362db8d95a4589619459bb40e744dc5c48bb17616c3c6cf24b8bb6ae0146c6f99f5605c57b0f23738f17f4861dcb846ee14f255e47dfd1cf3de213ce0c2a5f2b68993bd4788c3bd499261b9fc3b203c95dba37a4e5ec32922593acd791aed9d03abe008a8f9cc6cbe95d05fc0996eccd9643ff8df7da9b9f249dc7d690dba98ee85bdcc52675d7f1f3b15580e02b084e6da2694e766150fea4961519bbe0bd02c90af12544b6e59abc6281b895336c4095f2679028aafcd198adcf2b652a1a1cbf951b1af6b9c4040426c04c91b53eb033303e7d6955f74a1e562a6335f5dab0defa8922f7e657a8737298d433c09a4b8c8fe7f89c4aaca310291436dcae7bc4e01a631015001e589742c3ee1fab397256ace24e64ef68d9478706e9bafa2e46349671d4762cd4a11fbcdbb433cebdf29d61af86bd82cfb2e6cde9eeb8c0977b6b40d2804f142f86578fe3605a6a4a2a13427e10539e8306f2d3e8ac08f8b129dcba6a58537975f7eb46c2c62821760e104fec47b5d4f43fb98ffb68c5e2e223d4a3ccd99f2761682e5cea46a0b4b472278083ecf8cde23de70aca88b505cd8e1572b66b89880523e15d9b5119161211a5e9e9eeb4c1590d8c86e8281d2b05117579381c24f3cc613c1e38a3d26a3282a4901ef38acaaeefcb4241f8173b2ed7a312282e8f4a448168b08a69797fd670bbc44bad7eb15378fa8c36d0d613669d0c9ab950f5d8e5d5ea56f00ed2bc8a229cdab2e5d50e842308c972284b8aa7c682241550c8841a41470abe6be00489fe487658534989d64869378bb1b8d0ad3cc89545b2409e881a69e2e8cec6350515cf02178a1ffcf6a5b76e177b33fe8b01831b27cb68d3edc4b6cb8dd979084bbb1c17e68a51d81656e31d92cae0b63d2b9ff1a48a14e90b6234803aaea084d3b1518c3bdf05a952e12566570120812ed8b533efcc34668e2e561a5d6d6b87ab59fa058eac8576b9c571c11c38ecf469273ae6bdff72e1dac3d1da04982aa31d91100ad28d9fd8870042df3b15aaf3929df4c24ddfb52edc63d3128f977604c88948e8ebefc3f3c4f9e8529f274cc238862dce7154cc2a9c742d5a13b3c58c39e22d939d13a8e3b55ab6a8cda1de20a9f683c10df6c36ebdffdd5a3504cef7ce8e30422d0dadade60ec8e645df1e88a5826cc0f90e0e31477b2388baa78fcb64e795f99c212cd5635470b87fe7e75196ec578f05074fcb3ff16f3a17be54dde526da6819895633dfb5b832b7ba106e7a90182640bab7fdd325ef2612dbe1e9626671a063db96449a7bb7314ce9ae4930797408477d4f483f0d843dde6700af1862ef037e8db1e754d4dee946eb58222efe1b4dcc2a7e6add065c429211dde38d83bcf7ca54e50618cae0a19fc4cdaedca06640c1fa1cd3c4a5996e3bac620ffba6191bbad1c06bc054b7d7eb62aab8dc436bdec585f7d671365d3b186da7741a6466708c0e5e4f67b1b8aa942142e852920593db677b06ebc97952935206eeb8d35e2a2f031e8dc7fec28cc66df203dba9793eac63d6bde5a91a8700f74cdbe2edbe62b5e7e512aec3f69892c034b594e70f618ac6dd7103cad45a2de74fb85dc65f8f47615658b90675baf1a3be72fe17cc49d8c21450c", "00535251635251", 1, 2039130554, 1537743641, "ab3e859b67f65f7615dc8ddab9be3f13fe262c6314e88458b164161808c226ec"], + ["030000807082c40302a8b52e5143881e37f6b1fbda6792701bddf013e4e1a8f7f2f50b5810ca490c490300000002acacffffffff0bf45e0df179afd04ff6c08bd38c3ef35a96be18be0863e01db3487fc4008102030000000763ac636365acacd23d35dd03a6fa85050000000007630051636a6a003480a80400000000016a46e03d03000000000453516500000000000000000001f4c18605000000000000000000000000159f35b0a09f29de1838d09ab6463eeb2777251b49033899bbf851d863d91debe6c03a442849c9f2398ab8f82eb0f5617f6bed867a0de5cadac66534832a08757705e511817c9fd5c5bc436ba13aa55ee008202f688f57033968b80ea1575fcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d777caac514e6041a1643cc795a1c59a3551f64c1edd557f192a7a11d102a8aaf10027f6871d441be126c380ed71e635f29cd15280bf89ee92d84e9eea1bf06d78ef5c50f72a433c42fd5ef4a3d2299cd72fe54ff59cd22aae20f22ecd374e6ac6f10efa33c29bb2bdca1a8fee236e9a773a48b6416621dc95e4c7646438a95031f41a6181a95f29934e5bd94cb43a31dab65d96b11e730d53e58bc1ffebcffbf020c953a10f374a283d0852bde39d687c24cc81fe57994a08a01c66f696108ee1b0a010f765283a9387cdb28e5cceeed21482cab15f4070420859447b20398918e8faf9de1a4b97fec5d31c8d994533c1c31b8026ad1115ac202eebead031f7d8d95020585191f80455ca57f7b276539ebe955f8b23ab0742e772d514888fcc027b7ac03078bfe941bb277d3d6a2776736d0bd816313cf2c2eb9a9420327ff36144221c103028a2d16ab6fe92c9862730fd38baa78327613122143b67e00ef7fb73b7f0f1e0213b975aaeec9b25adaea4c1a13cb0b3d05f2485f7add4f438d3c29f898d3881b02109e71784899fa2c7a839244e4c0585795155e85f61d28c8b4b314bb28ac7c37e67ac3b581db95d4f840b5023ca1938af72a13c2ac5274cbd9afd384c59f9bde131395258ac90325794f1a8d44af52a281c3d1d564cc10465dff5d1d1d4778a15e5519df465a4135acd38055234296f3428e9ab12cd0e8140ff7d6e85831c185af0e748dd3313c6d246669afc1f33f457fd30472a471b0185f462a2ea5a2bca920bc529249f52e950187e9aec3fe9d3cbec4ce602f72bc511cad05765b7022181497520e9a563173260a4c2d44f5d2bcfe2da105cf3669c0680aad23ca17ee99311b2cffcfae67e594af57793d0574f40d02bb39164a6861eddb70ae52af21062a8a22e1cb8331fcfba185eb1691cf49f7b930024f445a6739a3d7925ec742f7b718aaba529e2468a78ff0c6da0bb817320f756cc89bc1dbd9ab0bdaccf6ca136e09e9953e65212c2c1a5691438d26e1d5ac662e74ca7795f69d6c69b1664a3bead40b5a1d3722d6ed4a65d1d90f0a126adc1929704120bd43cd2ae8c6bad51394f69212ff9f3e4e9847be1cedbc8eab716f00577056c23da364d6bdbfe1ef0cd134e69f8a35083a9f4e3f8fb851182b1c28d025f902e36067984e4f9fbe780eb0629164e822a60fc44528dbca6374f1dfc1e4b9a2561dd1bc7576068736ed0bed415a0c35d7d96e2efbf6f10927f38079ff37736a3c74674b39408acb5496697088e70596b0e734f010f9855dd012b31c2d46d9eec6e1963a0f58e8bb36ce525658b891cea0f15708099869fbe6f605cd6d18bfd96e2e78b94f4c7cccb513dbb50f78078e0cb6466231b51ba1676413ff48622bdb5bf82b82c8885dd7098439c1b70d55238c844f7c0ff2a23a58cff827141df13add7a277e160414a594a3dbc332b5aeda5837c2130f3d2be088350d9fb7b8cb04ef93a85ebfd8cf3cadf2a78345e75c6bc7a7ae6834ea76da304d3ac110a9e0f1bdccf087a8d531dba568e8b8fa9c720195b96a35df695abb5c39a45fe70279ccc19529c50afc26a77a430b8bb488f43dd3c1d6f95b0df91031edeabbde319fd48494a52bd50f42e3c4be0bf6094893406111bb812bcb36bb709600ce62c1515b842edcbb46ee1f0bc960382a4e48b19d9a87071078d157a7e0872f1edcd8c9aeeb46e555cddc2014c8081b511bd87c3db815680891f72c7f7a2fc9f0892aa4c908f6c7c45475409360ce0ad91ff7433be7d9c65866898418502be43c65906bc978bb7b94dbafb0e96e61220cb384f7f02785a3ea0c6bc9ccdeba888337a1f320cf33fa30858ce7884fa58d1d3ab47df4242eeeea2ed90dc8e4dd47d2ecf8d83e1b40fdfea24881a658fd14e2df64ba8f1a3a93c5db2b75bcfe171b233e6358d732402b90c49fa2ba23d4fb585c20ed7e3ace680c79db90cd2cd34dddafdfc918476e803bcd75552a43a4e89702f1cfacd679c9d457e3437a00d1f268f0808d62bb803f8904bec59f2d507073f4aedb81d2705aaf69d4290f571acac862d5a942d3446b6eed08bc4b044fbc60137e6cd7a7bedac09ddbe9c9fb4d6b35180f75d088906204a32453b2666a90272f767588d29c365e802ed388eebc301c09dbc3d41f8cbd12c3f68c014f93e240cf08166612ebf33d247213ebf6a6981901b3a960c97a5a1798edb1da33b856ef4cc876c4d8b5b71ff75d631d1b4c46d7723572b82056b3fb9e3f915134da3f6cb69c3a27f0a1d9de1aa8a7d4ed63f1fb651dfc8c95c39686bb44b160d4bf8fd41ac5ff306a865ffdc4e2388862c0f26bdb0ba40d3ef41e147de947c4ec7a223c1003043767cda4c86572685be88ec33e4a24a115b5cb43d5cd2594e2699223fd5e56d265439f34c533d9c7584e6a11cd02", "5365525300ac", 1, -886154570, 1537743641, "bfaab46a5dac8d8d64e4de897be74e6547604dd713a7d1168aa6c535c967e30b"], + ["05690b1d03c0312cb53c2a3d5ff7366ec3e84e02ce607577cc267bb3f648963d92b42d64ca03000000025353aafe420dd112a2c947ef700dfc236fac680947a813e8b4e8c0f6a989c24a4a3a17e571f7030000000100c96a05730150768fa818dc53e1b69ef441f94310a928367233b331256dc3d6eef3629f8701000000026a002d2939ab02527a480200000000085152536a51ac5353e4dd5f0100000000016a00000000014fbe6c0500000000000000000000000031d3caacf9325bbb576034b8787a15bfcad99e433651aebbca47d70c63eb27c8dcde5c7516c3acc1007b65266c97d0f44d224da447abf34ef361edd3662557bc375a30cc7d109590afd8d988beb33a7303c960fdbd17f0bf58fab06babb0b008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a31e081259cbea16fe5f670774d79bd76c932bed961efda23598968d5faa68ea93f5f52f63fd8de216431dc73769b73d30b2800104e5467f137f445a541ee177f8d5e58a0df0150c5199b488456686e044549161a482149621289cdb5ec96556b7dbfb8f604ba90dcd8697aa89a029c4cced26ffe005d655742186a276eae5103255e8f54927e87099a5e6b0e811d3d06bbeac2f55810dba125314aa31ed496d5022b00a2fac567c0570f666a6efdcc03ce59310d027da5746722f24a4928e38f6f0a037f8acf99d1ea002b4a1f6dd486d26798efc5d349b66a579c95d629370a20a1df2192d7c1f553ac486477ce4fcd336f8a7c2b6da8b6d56bab5ef889b0ea123f032af1dd5c155ec2a6158107003db1f2239c40319d70d2a7a0126ebca429ecca2e0300c708dea67fd74c58b359869e49e30fb126648086f76f40d88b0ccc3f4d6566032a0176dfe7b907e9c67e3b5cb1b9b5a17fc827805641b6db8bcd0070e617b02703271b5ffba20ed313f92dae47dac3c94a693f50b0fc6a15080e0fd0403819984e022612acbd93d39d94c994a602de6334903af2ef8d05bdd19cd42facf566d05a4f0d9cd6c7bb6161b5060f27c5694d030c2245d58770f4a5168ac5b1754884f3836bdb96089b38efa56c2036e004a6c55ab26eae95f61be493708fe3fb6de7997abf70aa779849f201130d4faf241e1937cc2d03b909c72b30744b1dc997fba26abcb4b61e2e3353ca6a8a60af1b028597374e109f950b161fe6f665f3823d2cdc9c440ae5776fe21f4e400afa3c7a1f58a7bd3723b48fdde44334a27e9fc7ee1db5c533597c26bfc94473d3066968d0d8c49f5dcac6489ee61bb447898bc1d7db8955c2d342dc7c361f388692cf9060afe5e745fcf89e859e5fb4a9434c35751d544472d30d9f47ca4054697bd42c1ae5b320b7146d55df32f2dbe2698a5edb34e416e89910c7ade913ca7a0b049a8d55134f40d18c0c73f82ad8745f0b9765b68741d9d4cb03de377e9bafb14a901b8279ac29affa2b0bf260caa1f48ba6ae154e714921957a345e387989c300828415c305f998e4c93269934fb830d23335bebe30808df6c6e464d48e5a702bdd664de99f88dcbbb7cb4ed269611539963d450209cd9da684825f2541bb09675f6d18b9daa8888b51f9cc1931e77c3b2699afef8d2e2fcad23f2dab432b6b9e32fa8e313a7a0cb20fd556ab7edf4b5ba69bb8aaeca65099c6b2cb658592d66d44122fc903a013e8c48a268f8bd012b854cfd5dba69e0e1bc993ffafc2bfc097ece81993fe712c705a958f7f7dec5f26ede6ac812f5e89179eff23494c3a1618797f4cb6571b8fc31d7c3e0a88fddccf07144e21ab6289856f0d3c89d1c7b949b2981457bb3b70663147fa992518422c0a0c86d3db017a07406456e83153084738475cf7c27e984592a6a59ed163e5d526a3615d734cbcaa5936fec76494987af50519058035a3c0356a2f3be6d487e19e4e96c7760e26ee5deb0d8fd0d7815ea229ac7321e20b485f01562c2ef026d3d690413f649103f554723cfb132e067747c4f190a53f93d6287784a3011cc5ef6199ad14c5287e94eadd293953d26f600a6a003dbbf4f09780d0e9534f16ddde35dd66fcd49ad8ae097a5f0ab2457f14323cc4b901926bf987e67fe057195ef147ca1087e4821193bb4130cf3f98f89f679a2a037e5565f269b5035388be8cb3445501ac0f0579d5ce1993d94d5ce3eaa7149a15bbad441c58633805b25c3f839f942bdbfc2f4c7fd367a111b48ae9c13f80ed3f21294d1b859eaa9e9ed065d40665f39a15fb32952d9f3fb690e69bdc4500a30a671b0c75a74b9dbbdba1b954dcdca12677b6ed540ddbb32bb4c1db07e0d80ad0d9afffbfb96b74ba6811270100a7f093b027886b0a61e9fe091175a35186dd1b822be341385a000d651567f5f1eb92d9cdc74b6ded19213b44998c8f0bc05a083529adda83cb1ef68dc7d3d1d778e33f0fd7a13db7b7d5f2ca59fc310003fc977eb0353d0fff81193a10f13a8b6489cdf5c146a2d5397cff49317c6fcb29eb3f327a82244f0e6c4c5f0ba33a9e16eaf6f462173496ddc00bd0bc7a3fcace9f070ae6f1bf4f2b6baef282ac5f5fca0810ae22c08ff90d0630a3b32d0c89b0992a8cd451b2090b6a3be56264e49b0d9e728c3219ae8b7b8e411cb402581a5284ac05deea700bb54468f5949e73a076bc855543f8f8e62f26f2558ebd265f337fdf3ec001ff898662925861464b4d9903d86c3e4b7658cb91668558509f980908469b2f6a01d952f7c57407b777df8e9840ae0ebe711b4a50d09bf98a9329a590a13545c1cfc9da7790448aa5394f765cb3054b8cb1ea51187bb941b17774319e01501c48f806af64068fd6266c548a6a0ad6bb7c1f6a357a72ec280e8152a8c58f0d", "525263635352ac65", 1, 566654117, 1537743641, "37b459ff427884cefce0e4bdc084c53773dbf1bcec78ebe69606fdfd24b3ea02"], + ["4a3fa20e04eb9a5790b97bb7edd9ce1224dcda7a48a4ade7175e365b53586113bc4cebf13e01000000096552536a006a656a007254b67499a5e2a03b6aab39f7792fb175b1db5c1312914ae927579d7ff818d839195b290300000000ffffffff25a33ef5ca3c68da40fba3c3b47db2307a8aaf0e8693a59a632d585dd4d5a4ff020000000552516a53ac39a7b8014d26f5a7ce68668ebae14d30b127ab06c8ca2ff9ca71a15ab7657458f3e553c500000000066a6352006300cd99f42803add254030000000005515252006524bd58050000000005525100635210e6e0040000000005526a6300650000000002c301980100000000000000000000000051ca70eddcfd9ff945df8dff4403aaa49a6df4045d31820a5085432dd10472bf3d558d272d3e85d5810dc3938e4f152d1cf30a5d38b281d450c4fb64020a5a43544ef63bdbc10825e1a6b71dd87abaa6ad8d804f6fa553539b37b8890b84095900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000599749e97bae7997d00d4042fb8f7f98c160d9839695a5c4b0cf139eb43074b31eac7a02b7be4fb3e6a4acd8afe6379aeb26691eafce9352966110c380c90e9dbe120a8ff355a5ac9d8dbe7b66868e6f99079676ae442ebb3867e87222bab1bc4c069245f4e5314df1d372a9883bacf4ee375b58d0159e78c1da6b4eb50b0432032b0133db8313492d32152049be84d2d3b36933e5c2a746da21cb34d66340959b032f17dd12d1ffbb1d87679c1deeab7241e73d23ac22752758a9ac040cf107a0910a0753668f5797539d4a9c214f170b34f9f252ea6630d7af933a98229367edf35cb7384402b9b5dacef2c4c1b8556eb8a9dc21a2b6d98859e1c7d8c9ff95273fd8021c668371067010a449ab6f3494706017ed80ef7b79612d4a946fe796d6acfcb8020badae97c3b167953bc154e94de9ccee67921e667d89d59720031810f7772a4c0308abd1763c5e62098ae0da3e20ef7bd58958e6e82ba9d69175bb2e0dbaa70d220309c667eba8dbc6202afc22f0baa47d14b5b7aebc297d4a5151bc9b592c191659022fe5de79dffefee22f9c714ae50e9debae06ab02c81f3203592b684df9693b37e476a2cfc9d91daeda5e42a034697ba8b74840bad34135bd93618cff2d1380943797d5351b37ff4d94937e25f2794a1634e3c6b0e14c2d0027d51dc4d35f9df95efc2fd7bfdd6c085ab83dca5ee4d808a08ce63a0d6391dbf74bb2ea154cc2e3a0f518855e7386c9d6d390bc77d47d16cb375231569c452c8f942f690c868e678366646c2ea64ece6d3436c9f8cd3e71dc505643ed896b6518efb0bdb7e41c79ebb845c54a4ccf8067828cea16bef4b29ea57bf08674a92071cbd40bd77ae1b7d654a6cdecdabdcba77abddc6aa479a580c70c2dd11f7632063259f5212047623afafdce0abe31353a846e0d0521a98df7f01339008ae6fb16639a6a1902db8e9eff0af692e20418277730e01331ac22d3109dd7220991cdf50fee52dcb82c50fc5c9d2d7125761c23e61e006ad38c15078dd82fac776b4c1cd9ef9110094cb7ae71baf0cffa205ddb6a2a44a617dea7a27cf2af400c604cb21dc40f1de0267bfb2a7045ba8c5f2bb5cd66184209aa0dfb4efc4a52a128925fdda6ec5b501649ce16a83d9f1a1cf7a2918d6b1b21e9cd1baa7284c273598af84994b273ebde68d470c78c31f73f17717bf2ca480c9992e0d01c004d3ec1b803e7261f3baaa1618d7621eb07a38ad7b3212626b0fbd14278c2e2500e5217f9592e2bcefc4691db207db9e9ef43fa13841d8a9a647c2987433eec62cabe40bdd1bbae65545c398c330151de891949268ef486fa122c4c6a6ee8c02b1596f2c431665cd1f509b4bf691cb80e8d26e0575553a809385323fd142117a1fa6496c817f65dc903a23302d96d04ba16b03340d8c2b9178f28de258e9195ab68ea980508114f6e0640fb6d199ddea9fc435695ea5f61af9c850302ce5eb401747f42a2170058231d87da960afcdd678606e72962eb7d6fe5ed1445d37cf05fa76e26818a8cf0a9ec0151f6c67794c3150d6fdc61b113952b79d3062e648e755587e738cef0d838f779a6c55e7f9b971431f1ce533112893e533d6342754b01c64e2224c1a805114ef8f36debce30536e0331bfbe9ff77f8f149694e86a3f5e7d3fdf1627b12cdab42f41f4bd853b02615163e042af2cb5fd9f7ce29946e6d526de4fc02198935ad9016d5086642ef0c1b6deb59a1a1d1c131e55e48351d9024bfa723114b8a4c97ee106c991f406206d19d898bbc75ef63affe43b06e4df625781ab9bf7d15c8b0b4d0beaf746bab46c9babdd7cab4a26e7894e46f2bfa84a2af4d0feed367dccc7d3b6937974655bf6b8d5d87782f2fe64a03f5448bc971c0dacf0a8031230bec13296eb857f43c51d39b094fc9c0917388392633ef6ec3aa323fe63afaddecb5241b103ce2ac94db87c3e70886e12370a48a6eb06074d5d507ade5965c9b615000d9f760f415f4b9ac51b45430366884a2febb16a099267e92dad5fbcf767ec798a2d4d124405d0bce8b3e8176b798749e315218bffe61b4d901e5e6610ad90777e229b46737354765e34aafdca869f7a68627562a59f4c8c704aef56285e239de6bccd64105bbad930080e7781e53eac434bda050b7d637b4b20c5c26ca7f4da36d0f7f768a4f3acec572066aa3111397cb0dd9660b7f31a37fd3dd2f3e546a064b1df5b44324aa3f313d86b9348831dd28eefbd970ecb2fcc3ab2dbfa5104a6513a3fe21d6bd0b3576da611d8790285af05fbf726000000000000000098a6b90200000000b6e725ef7e856c6958b486162716967cba860a01479833abeaad6daf147e2669215c77a01022104effcf4a8375a121a27b1db288c40bf0f7bf3873b84e088d618484c66ca86e213f90d5715c32e8729b6111b5a2594f11c08e38c2689369bd2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa7a243061019724a92b2dcc7f9adcbcb0bb2ea8e0cdf03056b6dda2e3be7d5cf1e6abf030048ff4fcae6e294c41f557539486180786a652659d475d2ab679ce3ffb0747f611342aa00ccafb0f64737856adea302d33d0eb312dc10826f58a9b2999d9b2b69745073ef039803e1be0210f8c061d39603c79f30e8786e1829f53022247873c840dfab6f9f8bade3130f151dcba4d57efc68a041621ae7d28be15b0022bdb41b24724defef3726e6893f3a4c0e5684bd755d8726f9fba5833ac0542820a02c16e3a42af8e8ff2d7c69f08b92553740dec860273a5879edffd2ceaf156a2dcd4f95dc8953f137b6e7e71c73f716e0b0437cafe1acd5403d798b488eb57a3032451b70b387cf3a0481cfed35eb31f79f0da068cd092c9851db943155cb0b17b0225802ad3d19bb74c446fb86c388d42470ee3f3022d4a4d7c8ccbb33c7cec6d770211780e9e80815a4e0e37464dd03a313659f6287f0c7aa746fd50f649bbe09fd502181c1e80b18332ddd4ee99b389cf0b3100d4340acf597f3f1d9e5bf07362be8703186e5128631c040fbd7218a3d2f7221e4d0fdf2744d74c386e58a7fc0b90bfeb08a3e743b7592c38a347a2b9374d5c987cdf4252bf3efe1718962d25fba8dc3b966dfef089d2ff78423e42c7d7825f3ad1f66258c7076730ddd0b3c0814dd4af1b33c625b38c42b2679eea477105784ff3f5837cb268f54f0a2949bd6e56d1ef3bf7f4d82cf63bb424f75494b757a658de30836fc7db0b23c52c7ccf6022fd6a65ad254964e5fd412de9636bd574c67f5b12e2e3604f9e3f74e6c889508c5b345a92207345715481847507cc618965e0aecc032d2616e0060f3a607dd883350b65901576efbdba3776b7d668ff5c79e0f1c1ae6bb451e803de13bc451e1bdcd00cdb94162a84622811d8258b162b05b9173eb3838da36fc3e26e1e6d05b5e90a170a99fe966b5928f56e5124bbadfa1b01ff33d134783fd173e50f149a06edf51efad298cc718c622869dfab919a048e5b0be479107bbd82ba7179fb0dc8f9a79c28afacb0fe86ffc11fcdede7bff8ee40fa488dc6064deb4184cb0cfa7424380d6c04b1c12b13bd0c456facaa0dda8b8bd3870efe45d4950a4d69041d31cda257eff84221872b9ed2f25f3f1666722b68e5a270c9f939ac3753cb36cfbbd91a5a5c42e8fe172bbb5ce528ba3af8035d70dd003bbd7868407ae2aa883664ff9e147b0c6989ab1ed164cbaf320ae5890bca14006eabc39e8d37563c245e33b283539690fea44f894be2ae7762a109aafa5330011191fd722961a85ca1063b9c440eb8e21941e932f8bb94fa7c93e3c2475a11d8edfd4dee1a6e83ef2060a43ca5adb7187f2065080f5fde07d14c3f12c3f07749fc6ea7e14d6a8dc72cf97aba24db97e9d77b1bd290d6bb8856ff4e5e8703f7fbde2f802ae84348d2321e9c600eb9006adb6e0bd41d4a94ee458c60d3dae2f7382cbabf69d7a84ef0c5e4b9e932bd4c1ac18b0d60153dfc0ff40845ff2064d9c0addc0e67a7297641ceea49c76da7ab5326db78c9b98c5572f8ed6c97c29d791c23e4217f49a192dbb3cd3b8e9aade3a1c99ecdebd7f0648298a1877d32aea17e0a9c85ee1d891dbe2116b2995d764c2524e7be5fdc6fc96da305c14aa025cc5af2192e3a24f0c0696739173ee0e306a0912e38109f4ae220736567a454f4a3a2bfa0ca45c1b18b3f0e8ff263afabcadefe21ea79e6d8d9c689177362a45f9ac91bb054b8cb15071daefeea9e382a9ef58a52d454e0c2138feba14f681065d59d042379bc8112b19321b1125979a4c8c7fac80668acbbcb726688f4ff0fa9338c4d8195d78f3a3760a37c6145bdeef5a2cd9cab6717e884e72291b9ecd350a97999fcdb21907b68b171aa8aeee11755645e14c6167abd530b1fea9354f4a8523f4b6130a79a9e09ffeade00121b75839f348f82e384367da85f2b0bba47807132a9c4e21a13d98010baf01ff6cdca1225a573f7947c273c27e6421f0a333f4f5ccbc596d909bcf9931b78080927e5cade380614912870a254640de54b16c2cd2e8dd084658509e92de70f77c02d748c257a6ce79bda6f4335b247c01863f980ac904bbee3a915007efb942b2559b0ddcff9915bb969933001b12d03e9a0f83e27a5fde20157484f25794b1143053e3465e6779109cb08bb0eb1319a56065a0e29042b1eb48422e17e9e1ca34c8a16875517bc097f603910799fd65e96ddbd1a8a5201351b60e2581e1a89d49ee02f00109bdecc00bc500daadea8a4168682c175009d6c206b82ecbc3c63abbf00c752760ce75e6829a45ffdc720b01cb41c82ff20e5b12841bffb141a96f4287822784796d979bd1ea4d523ce3e2d5925020e334249756c1909a52f0463b19fd7870eca1d1061d57125d369cd5e989f7a0807", "535300656a5200", 3, -881347552, 0, "e5305ccf2365cf6bf9bdcf0ed944763dc8a3de5ae6eeb03bd54bea51a92c5d82"], + ["0e05400801e255e9a0d1f8f499c6510f1392e7919c4e3a0c9049741e4c6300460013c2cd9e010000000965516aac6a52ac6551e154397d033e27c1000000000003635352064dca030000000002530053a9040400000000045352ac520000000001da5d78040000000000000000000000004ffaea1b4578c918d6b5fa106505959fc7f31a323e396e18e072acb127999bbf7db000f411a2f34bb35a0a596064e0c7649ec786b8e734fec144bd1c45f01ce81cb1471231fd2f3e2e3771b15f7b2ac1afa6a1d3dc29dc07b81cb3812f92aa84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006bb0e0be89c11191d38467fb5c2101968915ddae8e525f9376619ba7aad21a2d077a4f03c62e69da9202a67a18c205b75f303af53fa98be4c3b58722e427adddae5b973c36993d35e814de8680f69222313dd55ad1885d1abdaf5b48649a970eaae1e271d949bb6bf9cf7a3ad8a7b3ce16f8a19656962dada5d73508318881a5030b576e9eab2d4b9c3cb89fdb1df5f6ad46163aed3b6720cfea524aaf585ef0d00312a3d45dea26466c46514967382afd77a4fabcf2bd899d25f0b1fc96a1fca6230b046d4c309f8077a7b3305f654b88704df2925662324963dbd15f6f777aaad08801bda7907e4ed63efb2a9d3e3fbd739e62724cdf04bbd417c9f346147c5cb84f022d5fcdca72187009fa58221b29a8c4d1dcdfc91c015228358d892566b7665e07032b00bf42ee92fa5bdf6c848977a4b95707b35c559a071da515605267c75397fb0203095761edfc4bd9402ee1e173b283b23cbc6b9cb49d262dbbae69b6382c39ff02152e6809d1aff00f65efb90dc7c5b93976f641a04302a37d2b9f9a1cd944956803091c08caad3c141a03196427278cfc3a45e22f419acacd731f17e4bf4eef15e0f2e45fc6f8f04ae79374d690c81d507eb9b8facae99bc66af925697ad0cb5e3ac2c63077a598f1004a5d4a454c0dbc4271a89f8000e9fda75f5ec8440b7aa330f99fc1b2619006dbbe027299bc37f41e76c82abcd29080d86ed7b1ed9e3c40c80fab6f4d22bd172b50e72089cacc3bce787ba032a78fd3370e5d8f35bfdcbe296c266f0935d3ca4b7b0477e9506879437074a06d7a0d39844e693edaa89037ba1a4f2a507dc00784565468e33121652175e0ed0a2443a216c80c5d011581e64172d914fa3fcbf1df2dab36f3943f4e5e8cbf5e02dcffb5148da255ea2b200cb8c6b362ab774aea4329ae33029c7978f584f9cd54f44305599fc5d6121a15bddf19865f7f0e48fd7139378359b581cbc14b9fe123e3d7148ca06a3d14cf386720f2d401ae8615e1b6b97c3ab763f8d2b04ffdc2680312d934ded4f4502e9d5ca394c9bdc55247dfcc819926cd37575cee4868c86f03d1ea2d8c26cf8a469956d0e4ddc31f64055d7669d91818b5ec8ee675dc93da9e85a1eec9a7a7e3e3a270b84744ef932b4c7ac4265253f091224d0880a21fc95c815c93f3936e48bc8557372d02fd59885dcd1c2330f751b51c58f21ea5b6060d229478a7d0297b2ae645e83e8e347f919ade1383e95b55b92433c8013cc095fa9629526e37ea2045d3914e3ea2b8acf4a9a58c77a8e93689ea1c46329984c143deb7fe9d0a4c81aa9e23f4b0bc36dddfdd84884f499470c48cd23aa46fdea7995224bad7fd0366d3dd958cb3c221918af0735e69c740df164dd56a439bc30d5b48b57e857d0ccb9e5892b55e8dd73290df9c255f761d2a94124290b53c32ce9cff3aadf8c41ec1a4331e5b4933b8a65ff6b6db39c6c0d61fcbb09dcc84e537590537eba0255b5c18a9398daa74fcf9c324b3299ae7b6a5124e688b632e7fc28bf51a5cde3f59af81c335429ce3b2b362f5b2fbf2ff5b1817327b896207bda926b3541feb7f70e81e6787a3b7c39afb91a47fcf194fb4aacec1d40a7326efa222de9423a32e0b9a40f544c32e82bb247b0482de2dcf7eccc1eeeba111b380e055fe691974057703b3b475bbe426cdb0214b0f18ee079462a252df53020d6cf1f44ab17f03b2077bee18cbd2a6d6a0b3142a961ef1450f16effd8f8b0ce90b9d4be3620ca757bc950d096728472183b207550d6cfc99afc5dbbd0314c13e3980618def545fbde5cd5382d4c2a26c3d076e2b4ba2536ef665956bbe9ad36e63b678ae2b017b0c74782cefc1d199a9857a567c57e836088b9e534a8db17730e0ec7685111b958a75a397e0731830bd7b67a85df28fbc715dc6a0532b602a30ca69b3e645083e18b5c4a4dd4ad4221fae71055de24348e39c8cf14d8eaceb483f5316d4b6e84afd19ca6fc6e6275a4a5643c7f0ee7ea75588b934375f8f7620f0c74131e6cbfadd67296a7ede83848d6f7533c58940b6c3d61ce0fbb65d223d49318fa7d81959677f5d85cc2820bc26237a3f0d8b0d2778f4a3b0237f82722bb655576c49c2eb6178819e3bc301898dc977f7de8b96bd43f502793aa31d0dabb37cb10a64497a25c144947dd24e4aad989eb7216936210989f59d5d06ff579602b173b35edebf8c766c0dc620c96db179a03df62055a16ca13b3b0b4e3b094a33da84f61d5f2e376cb10e3cca008748fb258b32a3e713810cb1800b1a9c7ea6b1c3c634b59eefc612c018ed0d0b42d2fdddf1ae460c3dcc7cae10563ab2c071f73ff94fe446ec3b6138fbc8d8cfb0d3cba5ce901b65c712bc257b17644ab8f4b513c8b233cd2c9e0d2c96c51ced77eabf00fd39de29fe801fda7095c19fee0e", "51630063656aac65", 0, -246848956, 1537743641, "6b304a56710eb78c13b8656f3902862cbca27efcc14aee61a12f8d43f6fc62c5"], + ["030000807082c403034ca865b3501945ce0d53c7aa53940a944a94fb5ef440a42cd4e44e61e277cb530300000003005152ffffffff43a60ee0d50aa3ce074005f54bae981e9996c5fa1f4f4d3fd515675e4478900703000000026a65ffffffff10cfcb3e2dc29776f58dd01993d4a355ebf1b000ae297d924ae21faf63a801c603000000055165005300ffffffff0135e865000000000009005353655153526a52767e221e00000000030000000000000000c13fa701000000004fd98763a0d6b6cdb304011e2a5e693b63d81ddc05478fbed670eb86dec868910069e309176713e914a806916a81d596f8f7e9be98921c510f095db4674810146aa55bbb05ad6a112dc82c1cbe60a836ddd341f883c452ced12d7a731829dd9800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000939c909707ebc266c8624dab2af3dc245319ed3cc62260490adfe6758a49e7e77d874f0ad8743f647029387ded100b14e5cc3c210c0ffb121ae242e1930b2877f9481e3cae0b5b76b864a4c55eb68bc5fa4767180f32f59701c5249eaa51682a00f68858aff3e380ad060cfb503a694c8e06fbafb90fbe41dc07d50fb579cec1021efe85c8b41607fc0518e811575a2055977131b8eb7cbb0ae270adec91d8136003023e91e99b64bf7036ec55afbd589b95aedd3ece499b66e9409b4f9043ddf0940b07143ed981d2f0f616aa79e2642d583dc4eae2879b49c3ce3374e68a6add286c3ce4fa3e5caa0fb1387816458018fc4106b23b08dd55e1f9e554efdaf73df3e8031a1559c067327241220c6d67b6a94176eb9586abd99ee3cacb43caca8c0bfe34021dba2371f7517145090167fc3f277320f642530790d8e638fe4da61735e337cf0229ee33a4d56e79018738b1c514e91b54e72d2d838b3a6aa33552b93acac570c1031ca27c110e6717c9f7481e9fe40ca0744b74e5af3638eecc77317377d88b7b0502172bbadb4dda03d4eb0e308260d152f5df3dfe291fde0f2f52ed04bea7597b653f34bbe89815170fb1e8540b12d7efa7b4a840adfd2ecfea5d9f945b62532f37be67e3a1e7e8abb7d137308eb374a99ee10993a3fbe71e78d7fd5928d174f345737312aaa1761e80299d5f031d14b5946bb0edac5b61cebfddc185ec28dce44cd67d4a414b3a0db4cfbf9ae3d7ea164e2b0508662a9252334a944e8e15ec03d0ad91a2f8bdacfc93bff76ee0de8d504c0241818ad0371796f72766bbb283674234d4f5f831f06cf6e199473a86a9421218333547a164bb32902a08595ce1205e709a4c981d2e8bbaeaebfce505373daf494dfb559c4c7af09f0663ca527c3d31e4e0aa68eff130f94138576b7239b3c9a7c5ebeb9c554d0eb12f9a356f2f13e0eb89bad7209e157849ad53e118f8158bd23aa2eefa7fe8581712c85cb4a2e2609130df8476a5b4749a30f16500a6f55381510d0226d4d41b5300fec7b49c1e845b8db9f54f192055514d14f521b90106d7506d84d00c2930c9c3e6a3838a680f2ad1a1a78ba7053dc9aa6cb8e422bc558cb6162cc6417430a25bbb53ca5782c78bf6ad6f26954d6301dc002acd993037f4f6ab461a0b3a2457178c778850667652172b30226d147d700197deab4668e388ab0c8d444e07af2010eabad680631536a99283463dafdede21e904b2a9535c67df827a2b8f1ef82c8c9db95dc0bd30c2102c323edc3b8a436c1a29ac66b7fbc0116b9941f5579424ef90387daff402bd96aceb8ec8b435689d9726e226aee063053bbef37ca2af886575922ac499284f1b2266c0e3f160771332936f3d5954efd69b49e3a4bc01f4e82c465365a0de8495bf2f6846036620a02ffcb286df82bc153c5c5bb76e232e88f45936493149945bc00c508cb58db86c3ff26d39e5330f42b7a40d3fddb75df95883a7f976c6cf068749228f58260e474fa014e3a81ab75fbce9dedf827052b76bb6e98f2ce02a875b9827c0060b4bc46a5ac9fc11652dde450a642d5ed151727613b62e9db9e389c640501842182f6941cb3fecdff464fbf4880a1daa6d7adbc63090be3e1539636b332dcb7e495e9fc81d76179e35092a4dee0581417ecd351599e2cc05a36ab4c99e5bb85fb4884fb3c411d1b04b4f523b798b886a8d55e7a99f6f37f8d5533adcdb720d8d815e3ca7ce35a1ad381e4fd4816d41c1155f22c3b602d69e52204965b440778dcf0de8c81fff9501fcddd1a4b7349680d0980bbdb107b3464aa46a306f94197a5ec3d65ee3121b7c0c56722e50fe25e6e3a551e14c23305cda750e1cd41171184b0e5952b380f5a4df706c5a8fb8c83d83463417e1ac44c7f1fe499188d007db914e20cfd0b4bb06e158703837c572001da6a65d61fdd17efacbf331e7e10b8691ea11f977b32504b3f5d94bdb80e586db98fb463fc10e3dba7a1653ad818867a7fa8e02c3b34567394b4dabb41bd983db3ca3c02cd3b500499e92404a3850313b4daeaf3ff458e972a313b94cdb4258b0ec590af414f53ec5f2573d0ced91b150bd90199b79bf4dfb79d94a8cfedc02a16bfed3bde11bccbdb401bbb1f07fd6d2da99be02629e129023311d1e0f023ff1ff03016482a3515288ea5125a1ea8b79858d977ae025d003589d6149668a804d853e6f8cad0d7d880829a78e5e070b18ffe8e3e4daca779d889165e59c5b0b03a30de393d8acdd3af753207eef60f433a7912b31e2d9e75ad34304cc56010000000000000000000000008c7cbae74e85123fcb5ec59691fbc78a6876dc00a548f14af8f27c5b6be85fc2f5ecbab9a32cc49d19b05ece11e0d2becea09d6554842e9b83edf764a2c1eef1f9e97a9c137ae380dcf6b6d20bc5cf863486138539af290b32dc86cbeaafc758000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b2092aa0060051d17a82c8e2f5fb65f95b03b94837557f692bc918f767d96651224da972ce08b23bb22c86585f18b23edcd2001908ae2d4997b9c21df4a6203e463008a28603b35aae1f7e437289cf7b0b6579de87b1742595cad9edf72ad660cd42bfa142eb738ff72cccf3af85a865a090984ecb9791bfc5ff9b25623a95f0306140203b0d100548d2a97934ad69c93b03a88b84089d8532466af86e6526329020157c9b91d357f9727fae89e952ad007f6c93f5a4ef86e66d28b7cdfa035a43f0a0451afd0511a5dfd17be5f75a9bc2fc49fd3eab752188f856d51eb26d23eebf23ea12064412a2255466d2205dbd51b09f5d7d04308d6503c92c851a9e9b6defd031a08b27d1b3940af684fe445f43c7acfe8f2802ec5f097a73638a3ed5a2d4745022b1a0d00a6ad99c41f92fc43638cc54a78aa2f8cd42f66598b7f26fd72b4026303174d57b3ff2dcdee06a39f7bf6fbb7b6c973bb88e7ddb4fc5db71c32f854418a021e7bd813496ed628b6792d75b3c52374840dd9104818cb768c8b7e6cbd7fcdd20203b2a9ce184d292654eba4e66f88e9b7a7d4958bbc1094b0dad2d274784bd7f049fb09877db1b51b83ce6ffc9b7a2bf48249f26d4c053d319c224752c50e422f6c3ed659ed57e4831f7aa9b1465f7369475f81651f59f79290098fb458050dfc96297ad3634832a8b3e60806a76ac0c4e4d9933671a09a8aeb8bcbf13b0197ff4b379f89841ea77581ffd8ee7b9adb3ba63cb1ab6ecfd2317abe42a30f3bc2e28c92ea7b6005f6a05b5ae457302f492529593db41926e9c5375feb78bdf1ea03f45b69e3ad876f4d7f6ab2a10ccffe61c91ab2de221a087e7945fe29b4498eed048fcdb9d2179c17f7aab22d526a23a0871f5140732cbe2f357afa51a13dd0d06652d2114bdc1239f9eecbd61d47dfe78a33bd45c6737e1b354971fc655baacc3742cf72dc731084ef4b813a8840f611d28ae73e59ec51d9fa66dc19596e2829ee554599fced207f01921cff69b9ad65d26e8b423362d8aa62be97f613fbd0b4d2fd9b08a486dc2d5752c4c1c4a89463edc590210de9bc895a32c8a288836b4cb2d22832d78eb9f1e35f699169ae9fa72776aa2630b5dc334d081aaf4c921f6a5aedbbd24cea52af215ae256583e4db7f9d580ef8ac3cc786664f2fd7712e9725b9e02d8a8c0aa592de2cbb7e82cdccf45017a79a512e97a8f750a76df77958294b77e3af4185d5818825062e4b0964a247035e72913eceb73f89dedb5fa097e8851162a9ef3a1e8ad34652c11ed7a52b997bbfd13ab68a518023fd3fa296cf806b848485d9efd55a6f2ee818225f54f1fe87e9e9415f9091ef66c0b48558dbc8d413bf198844d2fb205f94e177e6be3c65e23f9eac6d92c9e3b8dc90404258c1c5424b4de2d35c2c9384d59f1bdf8e1540a70fa95ea06bf16582c0a1b068042545a34863e7c5de7f16ff5ff831b2dc6f339254ce9b32c70004c1f6e7163a41adadb9a38235966d18cabe7bcce48711ed747f35eca36eeea775bf9e73f4322dcde4b9840890ece9f183f3fd4ea4d06372ee43cdf25e757467679c2a5b4dbf0e44044097e5331b9d03199d75c93db86f8115fe540f3bc05a62494037990c46ffaa37c6162116144cd5ebc972594df5bca9700c0d073b1c9fcdd3eb642d8c31e7ff6b975bd364c5cdede4e79b64159dc21b7c3ad008c7e0e9d4f8b22072d6faa65396b2cafb7f3abd17086a39299ecbe0eea43c1e3163ea21e6a62cf99b817a485a7c53205ec3d861c0f9b6e4d69e04525714fedb1e5b68fe93a15a7cdd9d5bd4b6575aae3ac26c2214c55e626b4732a26b8a4b24a83a27d155cc0a4a456e12b328f322a85c06fae087bfb773043814f33cfc699a8d35cd40f9e85f0a9a830c72b76e29f0aba1e282c47d85906436dbff4edfca3dd9e5fdcd33d057daf761ee407e7fca390b436ab9ace8e3b5fbbb04e6da50eab153f022c984a8be7d26ea8a863ffafc46de9f984f186707ba80362fa645b24d94febd3157d0a69e2430f16ae5bd49860a1ecac9bc8ec2208f557065ba866718a72e3e2f09f8c09d90b763b595f1627aba32e92ab1e601633f8e983dfc55d70d6774bb2113b84cc5c411b487a654165f4952ae0dc9c65d5f2b0addc9af0440b25804ca0664578f51cc858c296a994cdf7c7f04f5f3ef7a3e664d49a1e8e265567149f3f8fb9db511f007c9e40f531f9825b58ae5a163beff524b3e6a45f7a10cee2c656490e98f616793cc1127031ef1900b0caa61c6cae5a55ff21dbd79ec1dededf020000000000000000000000000485316fdbdfbef38179e14ed235387e5e5562f38f08fd205c2aaa135f2c2f7ccde5a0dac877ed76553ff850d260391a0e8ab541e69760ea3b151901d6869097c7a0bcfff040fecb7926c364fffd4d906cb384ff135bbad9cfa88a63edfac2a2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007044972f383f08ad8a449df1bdb6b0f1ebd472fd3b5f0e3bbb886896747983622b3382a5a9a384acd546a0872ca9e6054ec405c4b4e2a74aab3f47ca1315007f711dff4c72eeedad03b25b9bdd89bcef4c9ab2ff82a6b2987d97da93a70b3db25f92ed9ce033ff8bd08a018264fdd4df03a9d40f12246dd907d421baac838952020305ca35183e6c3f6055b146a4a6ed8f7be977852b6d70d276ed64348db2ecdf020cba3bbaea73d9095fba8bcb0979419e209756c80a23530307322c40247aa55a0a0552ace7d23da034a435a25bf36c437fed992f7866c058ff1d79af09fecb89ecd1926deab61889fe9ee19bbf929d4d54881f58810db87a91ed536a8baae9abb4022b19e0156e617bbddf1c17468edf1b8a1449f59a88dd4becb24fa990c55b734e020139f06248c2c16c98f46e5b52b1ee655c5abe6c7b88eeb990867a0fa7978c5e0205657e7bf8d790c9f8d56cd58d061e1dc4b7016d82d0454eed89eb507183cc3b032ad70e80ad48d95d30cf64d79d05139cf1850e10a9dca26f7f97d88b9168e80a0218a918cb398b53ba3df932b0042201370febc61ff12fbd2d692e6339e3a2228eefc2eaaf9e94df53aa839c80a091338157081d357f28f6ea6e597c4db697d56f0eae228702c82ecdb800ed86c184a32f8f4068692d43d940bcf7885eb5169ea3260f9a0a8c521c3489d72427d6b83a527ae496763daa8a314d2a91d30d3832e375751ededf144c7f646bac07f9bb9e16075d8261b17086384386092a14a8f587cea75f175d9b22a9127b2f86ffc9d1a7cf9a6b6442c29540ab6ca646dfc90d174542fe94355d64534d0a0534296de7a5e146c4d1485dd8b19ee7a91dfe1517a69e824338cc965d9e999d86fc5e33d7a2fb28789e4fed46c397a285b1f598156ccac4fe5dcda5ed7bf29a27fced7890098097bca2ea45085534a79383869c30a25d1654a360a159a06bcc4d217bddb00b61959b14c01d8f619572f6e50fec68aa3243ce7f057b0d42965721803ce5042e6d8872ac0de4c4ce96e3babeaa67e41b1d77071107ea0488bd40409cd8d43f802452e64f92e4d05ded375c5a26e41f8f2e0037d26615d30124ce664967a86901b19aaec7d947b74dcc000b49258e7a6b3a4469097a2b3068af38896208fa44c97c6132b1c43d4fa46704d0a6d53a7aa555d7d04ffe45f660f159f9cc0e82a5c134aeb8dbf62d60ab2ed80a6b0125685205b2955e5c500f83db5085252211cda34920f970c5eb2da8919e66a30bf2cb79b9db349703693afa4305f8e06a2cf3309f1f130705324e1544b846c91a575185dc6a5db0267e8fc9eaac245f202e6a3e8417c64fbf56f54e1629c716cc2698e850a4bc1a5c1771defd532ef3ff633a9b5dae8ac2bf199f19c9f6f4f09f1b3861a9402322f0d725aedf090ee9c5079cd42e87c27ce5aa0a2af2cd0ec4515a0ce58aef26bdafa224c54bed1dc103aca91946e77b51190b4446c390d0312112c280de6b6d9f723edb2fcc1fa95b35f02292f87d6154a7eefb55046f636de5c9e08edbbb17a451fe33e6413464bd512ea8cad96b13cd5f9a66a4c5bf37d9e5d86ba2ea2d1d958f243b655736cd5857e2e552076d3db374a457278bb8240d240f37411d40b558fdfac7caff9b1149a6375b3663d7b721f85935f54fc3607e0472ea547bce98c9b1552386fa7e7cac860507c7cee40b1643a770a3a1695d79da58f2638115862eb63d29229e7e41a86b0f858d55085c486c4a70ba8970728e3ec22c81d9c063b56e58db84352e4479f5e4f1963a7c3562e27b4905b433c9495537be42565f670cbc9528844c40e75043e543889a30d6d30c0c24a127eb08f06c2287de8b9996532c273b9d375e92ca9155030be0bfa7c0151540233454eb04a62d6ebf38877c8530428f5d6730aa47c29d99b9c7541138578a0fc3cf7cd8fd6fa82ebe823dc497967e3682b41173987d63f47732e0161656c9d5977c4059c5389a959e22a7ad39dad183ad6941661e7462dcd868b306e8da4901bf7bc8255130b071f2168ebd3565821ce4bcdb1a24f98f346701ae89bda0b4b58f76ce63f63ddeb1384cf79164b32cc7184385f49b717e02b28ab2373e9cdfaaedddf5c178b4e000dc154dce428f04d97783e5e8fee232a735f9fd91415103cd026381624ffdc25dd15d6348a6f77da861a1b3a05c94e51aa3fad612e1ff7d21a335245bf98974932ee106f42bc9105191cba8e7c08325c04fe9395b767f311a1a010ff407a9e61093fec9e243d4c8aebb9abd047af50c30adbf3e29d58748f1cffaea05fed285bd19d98f4ca8b03225b4c8cc13ca42b09a2041687d609fe11ac533e01e7611a535d55eae4ce8c6b06ccbbeb2b067c605edaf87111f70e02d576fc823f7bede0877d716a7a6c3985fd7957d763754951c9b055d09", "", 0, 2118459688, 0, "3b0706ab7d70416047ad839bed798295f2a3a39405005ec5a4bda32b9ec1bd04"], + ["d7d3ba3101c64c4944fa0a1087756a1a796831f6d47357ac10caa7cddb91ee5dd8695d3000000000000553ac63516a0b52c0ea01d8b473010000000000117d340700", "516351ac", 0, 77313838, 0, "098e7657a2bb07ffc05849bfc7a59f02b3f4024cbf853588ea48eabb3e5789fa"], + ["030000807082c403025d6c6637acdcf641e82d3b9d6fe507776e75a8ab4ab959a6be5e9c057c56695401000000085165535152ac63acf199203a491f76a78d2c76d09befc994413e1a8d03144d687e660024b36c302dd6c4e94b010000000652520052516affffffff022eb1ae040000000001ac869b000300000000060053ac65635356924ecb0000000000", "65530065", 1, -562238084, 1537743641, "f94476822df5e209cb08a6791e6d0260041219cc0d62ba20fc9602017a1a880f"], + ["030000807082c4030389f0625f94d65b62a03f664bfbebf5dbd80c7c3c5b99b4a5d5d641bbfa1abd8f0000000006635153655265ffffffff9bf5d723fa799a599e2ab500fe0368e1cf0f0b0121e7d066e330b76ea9f0d13302000000096a0065acacac63acacffffffff0470f81403c90aeb342bb91c17d4e83b3ec35af1fca63bc377a04e35a760322002000000003dd6657f036d7cc2030000000003535163c51b7c0500000000046aac52ac1e46aa01000000000553526363656631c618f31af8a500", "6a51655265655152", 2, 594957091, 0, "c01132901397b50209aada1dba4f2f398383a2d039c446681566a6c95d548f1d"], + ["d8c6484504ac1d91be3242e30d7f60179dbc2ae35d0f9bfe4c83a6c98aea568412f619e6670000000007ac51515200516a9813dd76c50be0ae170ce155cc84935a92c1d7eb606930f6dd80dd6ef87e1b25e08dccdc0000000007006500516aacacffffffff240400aef0bbbce38f80596ab22402b8cf919dfcf2172656ff2db01af7bbd3d70100000009ac6a52526a656300acffffffffeee1d46431624459ef5fba8afeff7ecc030ef394931d104c75ab4cdb1ba19c33000000000552ac006365ffffffff04a7649a0500000000075265006a65ac63985b9f050000000007ac655365535352678e73030000000005526a00ac6a6103a5030000000001633a67d7de025dece804000000000000000000000000c03f61eb17e859bf6cad227f2b9c17050fd90ba57d173a8557bc08539f97111a6ced2f0f18e6e82d15c20a7d229307ec7bee78b24af83b5b6781ead029ee8dfe57aa82600cb1c58e08884911c005f2689b31178b6895be6d42609a7a89d8a3af00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2780ebba592d930cf791443f7990618983ecbbda04202fae95d6ccb1f27e540bbf5b883e10fb3624ab1ef369cd3d3afe3cae5d5c52d54ce66262e2afb16017acae4b7d5917f093b257954cc0c1218c5697796e2711baa45a504e5c5a1d7478893ec716e9da24d0c8a07e7db82147daf1f717d59394005e90ced3b1168d4c6e80303844219d0ad4cb8c87f482b07eea1ccfaf3c4129aabf689db5b2dd159e1d47c0305be1bc2a07b5af851c1b88e071d0eb55103ffc7483c552359853381a1d484f20a08f0794ef3abf358752c6a933e3f7bd56fe979b462d09aaf8aadf9f7c5260d33cb2c983d8ab82693d2596a5a9f3c5962c3c4692e7f63660f7b3e9f13744d81720223ef1c98325c9d4462b561f6e82af8abc1c84ea9a753cf8895a6ce6e8059a3cf0223ba1dc5af61e6848b0435e65152136161ad3ef0c538b28b9b0c26912f57cfb1032ce7dc3b9b3e9822e689b3119135864c7d6b97ddd920323af862685e1cb9abbb030b025b7188b9a44c5573744a3ac88d3310e09472fe4031c27ee9e034038c354c032babfddad6c32aa487a421ce592e3590511ec95872ea7924ecfa3bfa347613309a97f364eb6d91e25b51db8f325ac6c660fdc53aa05e65de18f8701ba9bf7540e25cfc6b73d809ef1114485390fb9fb032c1c3f6a34069fd75267b16555093233605a55f8fa91bea4b75b23941c301aecf4a4eddad55e251ab1cca1f11877057c6b7655141c1234868464bc405131d81dd96c9292d166120a8798c7a0217d3dc65837a181eef90608f053826701a5ca09f73f7eaf66c1714f3cad1bd87f0121997872ebe2a3a9c5ceb750e4930c983154d3bdeda1155143bab5c02fc6c3a4c20bfe9d7a771357007f404c3a4eb4efa9f926d1aa6d9bcf4b26a88dbc4a48c3f2932998763fca82c08bbcdd41644b421d81845db4c1515468806f4abf436efd4e9ce15fbcaf0be899f95b6bb23dc5ed2767784d5dcb3645ec411c61efa0d47723d3952d3d5cd072fb8cf449fc71f39a2166b833024bb60fb58a13bee90139c51cf97506094ab960accacb92186590b71cb19ab88e2bcb0200e79c86a6fd2324787d27f5e01ecac1a490d5e265fa4f9ed8a48f34c2104ba84fe46207822b912c7e65a20fe57c02f991aacf947f80beea10010ca4f9e9b11cc050d0c3b5c616db22b948525a52eff4750021e2b5d0601eb0ede3ec4c8ff3bedc4ee2fb76fad1bb82a7969380841192de76e393c810361b002fb70f2a8534a27a5612b4a1d8c1193feeb5b87623373997e5ff0e50e54c9999bbfd6cb4061ac74d4fbcb7e49df7ab190ab566d9d93b84305e5b267c26b139108a4ff852151e4bb2a9891030692cae64bc320ecb0c3044a71f0eb738c5237969185148a70cdd1c51f6cd5a80c4e12a7d19eab24db3e4d9442ec52fd5124a536d9e64b2ba6e8506a97525747d467f2525d403980e5a280f8c9f6f3083b4640564253ab5bcf8926a7d711ddb9bc106f0d86061ee58c075cf5388bae4f6b4fd2da43c9f3fe5ff92d53b2edea729a5efdc64378a0205d690d6662ad1b7c579551897bc2d58f9e8f1cd20e4828a7908d12f2d66b7925011bd6f577387a9f8c6a061d81e1b935482de0e0ad042acd206df8c3cc3d9cbcefd78b6513d3945ecf9958df5ecf69e2eb2de9c75e511548a98bc9329f995fe663dce2c5d753c69428a0fed38f0d6aab06e11815fb0cfa622bc6832f83483151b74e2dcc8b397e785a32e1ea09e6554806ae22b86849dbe300df0ddcc001f4d419f518590f72ff38de6764283ccac68cd2b3a8da4ce193f8ce61ccca376828fc294797ee553f037039b93e172ebfcb50c9a67ae84639ff6f45389afc2acaba69fa0ba03e94e1dece0d508efae0fc73cf2919346783f0c2a922d511d5023b93a4bab1ac11b4d253e3185d01c852d048b0dbe8e9a03e46ab9dcd5e84c36ff9bca884ccb296e11e3a6d86bc935ed8c915f0366de72a301b68f02c924d14e73cc2632212df2b7c175f8b0e00ff6fb0b37f8a7148d95931e78ae136d84b104b05b9f419ca289104101ca0306622f5fab3c5d230906acca1359180cfddb0bec4c482866c7068e711b2272e56aa153a67be80b4e29fbdf9346e3d9fdc9ffe030b60242e9fcd3cfd1357aa8dff5c92131c1c4e24c91b58d4933d1d2f2f015b40f3561118134bf8d1593682f080e77badf4b0baf97effbc7259c39abab0b0d47b9939c500a62ca0c6d2693523cc2cc2adf5ed825e390db6620cebab02e39e3c7287ce30edb63cbb2e642e7ba876f96acc2394603fa103000000000000000000000000003d453d88549b0f794d5b9becd1877ed3ee97d196bfd61dc4e13f739ab22bc2328cf1b97b29027faba41af2b0ef4833064bbb7c79f0482d7fb45be886417b341435e081397201b1fba867b25efd97e28112676bb81ac8b55a4abe132d779588d400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a55e747eb67ed2ce0065113fc35ce10e72215eadc7e59bc716971d16b1062943d6d8fcc5ae724377cb07565cd66fbfe34934f51ce6093d69c948b59840abf512edd14d70af1a774b09dfdb25182969a692b4efc4ca376a9c253e9557acecb05f1bc1c2ea41c89b20e307bc0fc58df62b0fcd93c035d12f77993fc23eb295e6c503246542b3e8332cda22ddd228d3894b524936cca6afb33169c2153c2882d59d4502271f08159fa1d3721e0379c716ca9d7a4facb8ff37649cfdc1ad113d12490cea0a031fb3b561da875ce25a0a7f89279d809ddfef5ce838b2814b4f89cc27f5ddce2203d35e5a495bbecddc595e1f14f29f7e66cfabc454dd42051baf4d007f4ba00214d0d0f2f9033e4964a07cea6ef6ff9872c2ef3c30b9dd25dd0a0e95752561bc032acadc67bf1b1927609b9730e28b1962156ad9a17a34b272d6b1c1f836d349b80200b4c60abbb47e7edb25e15310ff7bf0a344603e79f07cc269a3ead1a879b5ad032eca24e26e306b1b239dcd865d7ca6ea0e2e056c0d3fda158d4559154f013e6203105ee94a59eaa1ec48da051d53d5e9798a0ff76eff6e739e88fc21f2ce0586ea014333bbfd45e0361b74daea9f3be1b7cb57be9ad22b78322ec6f23868829e139b55ba04ec4f809512509b9fa29875879ea3d083fa4c5c8d66673ea58feecc26fd57f9d213a4a35c24533c16a6de88fc812624e2950dd2d56c2296513a4d326eca4546e158971d267795cbfdc3056258494e85264c1d5aef37da4cf2ae0e3be3f719960b200f2a7a9a8ead1e594118df34d07838771a92160ce037de7f9effc87ec0ae6c0bc101bf7cac524b11c81164b443a2334c4488821b9a8868e6497bf8256c33d0fa59421b1e5a507cc9e5b330269c0582b3ddac14dde8479550a3ad2606240fb8f0f6d6a88131fc981f64ba29503d9f307bb8fc5beaf3be40cc772a722c4000364f3de5378da81e60ab3ae5dbc28a52056c009e384f20cbe3f024c3475521ad443038d1c85ec8d3acad930e0d1554aaa29a50574c0541bbf311f5004097dcd53885d6b7c8fd27f589e9fc1e86367c74750e75f1b48508debdf273c31b49832de7dcc87744c442f44de1bd099c86c48041ebcae8cb2be7bfd91d753ee7783546aebc1a7b097c025bfa02c12d90427777a0704570ddffea27072da526c27e10d7ccba05a91b8310fe2c3f9643008f561db3d3d9fbde728dde4c39673d33826f516bb671e2172576d0f010fc858de1b6ec299a0153a483e1fe62b14f518671519b4d9d9fc40ae6b668a00cd907cb0ee3a05795df662a52782c5a2b96e2038e753c15aec81b6c2dd303cec79f45662088c1094408b5808556409abc53f51819d4eafb0dc4a9dc477da89a0916f29bb7c705282e9770f7ec41c5a71e7cd6aa800a1131a0c13f0c3538a1db7b65f8b27242e17f8fcbd7b4508d72785bddddda2abc52814f305cd3305d4b49c3622fae088edeb683961a2f150290346805211c03a549e0b3591bd6a31e463830d5544fe2e57f0d71f2476ab1a501033b28bd97451797f5e8a71b7d1f64bb150680e31d06d994ec18189a4ead572f35aabb630a4c9b0741c6b38b97a40cf94f86c251ef0bbf0d32df28bbfcebc047cc7de7277ee179ecab65dae472b73f9ee1a2b37408912104231b782381ebeb0fbbedca1b4c842a546197c5dd52f502c6e7c638b4df8577b8c671d40166817aa66fcc0cca6485b30ac3b8be14b8e7bf456baa0462ebf5fa40ec09a4a85d04c25e7a0da627cb6817f5a1259cf4239fa3cf1f714461f4e78d322e2c7fe0993c0052bbca7b332f0bb7ac73d2881910c8c55b98c021aa5570703ad10ef19a2c96590a15c78933f519a47f679c9917bfbe3c561c510f4f6b2e2af09ab855bc1430c967cf5e86aa51f6737c1121e7cd73e717363de5404a5c76f69a03f2504c0391d47819d32bf5acc9da00e2c536965f8ae07ef3d7dd05282ce511d0c59966fd21ce0c86cfeb8202bb977d7bddef3869aeb959b0c1e6989541ec7ebb569d5c0290f56f158a3188c329f20152c1b50a7e9afffa77a00044a46ff0e8834b82bc5ccdc36122d05ef3760d914ea5baf881630c47944e6840cb0abe663bf4b20374117d886a353b61a0613b708b04da1f4bca8ad8b9fce8e7a0585d343c83755add8ce306b1992bd9c3224a50954adba0e68bc2f55b38967b31da5181d485ad99311b45820ea85d018e2802fda76416aa1261e6125abbf9916af4020bad3176e03653c8336c9fd92cc7bc23100c1600dd7a1700a00ff1b4e54df00bbdfdbbd4bf774ce346d19cbaad456277403d1861e0f5c655dcaf1fb0ec5b572c031d5369a06d905dfe81d427e2ef428c88aee0c2aee635c95368658aa338479c8076eac86eda941cafcda39646dc27d0d6ad34c9bc949fa35893306aedc5489a0e", "63ac005263", 1, -1316560829, 1537743641, "fdebc6b24f11d32798f34f3dee8494a3183cdeaeb37af0f4ac923427256eca42"], + ["030000807082c40303ae87d28d87bd798d3c4b995fc73d0da92973d1b264859a86a1bc6140aeb14b8f0300000001acffffffff23ebf4247a01429173d15284961825c8a5d2670d8710d3db0538e0dfab5d633103000000096aac52000000006a5294460cc2975b2b8c32c51b3ccc309c8d8739bb6996198ba173536a9e99a5109f0b1435b903000000096365acac5363635251ffffffff030aad330200000000096a65530000630065acf7b166010000000001006791420500000000016a0000000049292e5f0228b05f0000000000000000000000000056929e595a1b5e81ac6569bc16adf853ecefa11f646bac4c928289e0e426734dc74056fc0f5d9b7c0e85b3570330d4e0d29dac8fabbc8826e0a8d013d3057026c5bead8032e31ef31d388e83138d00dc63dc8541cb7d9d88d43869c9ca9f432400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0419c7bb0e86cd7b441ac6a2177c27b50cfee1873f23aa85e2451a17a511cf865d76d3fb9ffd3cd8a3ffdbc9442055411e19a0cb25c51505623700babe4f41db8dcd4955edf958046ddfac9939babad6b357f51128c0cf942254e1b9ef2dccefe737e6f52462f652af5b30fbe5a857ea8e8b4ebde753f87278c860c6d8c6399021de7d040101a5e52b9c596d45e3e3c94557b2c8c006b4242ddf0199a7d458c9d020a3ff06bf6541b11b7104245fd3d12fb135252381e79154291d4764f716c0db20a0743fa518c8746f65e25adb738680728e98d9e753029a5c1d858a3a57d8ec0e1a61fec43d48c2649935143c83c188b53aca02e3d1ebb8654cff587b6bb5474ed020dae634b6340a577a88c25e7dc79c9b8b69fdd17b7b87aa870dffc9adf5d7e310219e1a67d8d4df97a9f54a4f7764e6ae3caa4d86b4eb56100a901ce5dfda415d303295363bfc2473b9f409fdb39bec09d940886a7948e8ed049cd7d53425c28866f030216ba779083d4d752cdc202540e252ea19511c07ccbe4fde5f6481d2cd9d5bd0310a22878e4e5fed3762c847fdde57ccf8ad882006aee96525678149f022a27afce3532907828e2900f0ba912d6909ded4a639e78f8f54a0c7277fcf2ffafcfb1074d57d9d847ae7090afb5e6fc2bc474e7b084a4da9d8bcbf57c14fc7ac8e284a9f4fe916a1ff74281c80bf8fe0001fb1c976463bf8c71d303b564fc48c22521afb4bfe5eb45200bc304630573c8b6f52f50bd0f550826e807d25e04e2a42c657ab656d4176c08ae2aaadea3cc3b4b1c73d45ba1acd010c34d0809337dd3223fbf9a2f43873aa4381da19f4e743add5163022263c19d290603da7b05068565737977a14d2cff3939e459c39b60ec89ed578bc49c72608ce74d8c42999475ea9e1bfe4675ea6c52499bc4a744d554ef7dc80729bdffda66035f16f6849e4d2a29eef50fa90a07daeaa3b2dfefd3561d8dd5a8a2e81bd49f0774217745e865c7707993edc406b2ce8aaeeaddb820ca74d9b4492b0d222cc6219f86efdb33f86fef2aada18ce297e59f9ce9e9c81e709727adf38b71bcffdc29f2bff483623a871205c5bd54e5999c060cdaa31a86e4c0481a633ab396a57ba3f4d1d893c3c2f7c3e73352c52815141c165d15911c5ae2b8f5a7cbbff08a44c0e9d7d08555a728ee5827ec711a5d60979b251b8cc314487c767bd28d4bbeecd75793573bbd02a5b1faf8ac86a6c2b68c8e70017be1bfbd47fb482d588e61be29a4f6147602d551df02ba7690a70fda966dd787908a74c15029a76c8ebf2cf5d4d9349f26c36568a8a5e1b8877faf0f24afff5e885539d126ac9365fed1d0ceb09965f6370a40f93ebc3dc0f7f8b59e80d862f3291f323e661946200971c7af77dbad492f39989348f9896055fe40d77004919d6bc8ad33c27a10ee6536b808c71c1c50fa68450d060e6ba369003fff2d8d78404d342b67e0b5aeba679ea4633fe7344b6030e0e7471b4d6a27e0377462b7622bffd52616f660d1e52b7a4ff2b6dc48afee9e7af4a9282db352c661993d1c5970a9f182f40fe05075aea599e008c46e481a47a19a36b7d87046342420524c36743868825a1c90b62e2320d0cfb1686b12ca46badfd5a0f007b8b3e6d1ef980afb295579b6aec7c3f3160904f21e9eaf19fc671eb3f6c919695405bb3ce7d772a50c992db27eaa90371121445e1e3c61d3ba510a9b1161c185d4ba35600b152f0aa3425feaf18574313b53111d4b682836291d36870e39b638e814757365338717f81ae30909fbbf0ebbb8e4278f20b7dbc59f4f25adcd064795712f58a3774c6c5bbb8706b6be91afcf8a731d3271c1302335a2e6b11f0c3be4f76fed641533e13c2bc3c65d0e940e25e013de7035fbfcaff61f94ccc416e37997588920d7693c610a2c083a9e84609291d953223b7f6d87d24debed75f0acd1e532e3c36e4c6840553bbb04295a189d31822c70144ce70bf0cfaab75c9bd02f501d34daf5e4983923b50b227fef856e14d89914a8fd2ea83f8378776f87e8fe68e50446b6c6c968a4fda7fdb463d04abb7501a3628d94e0bae3bd2cdb9bfa786b307d4cf34addd083c2c50de45a6283ca09361444cb0606dec2e35ceec6f5885112817811429081f78ad06102599e8b3458ce9dda75035a4483559481246114339a052a454af971ea90e07f53bcdf6eb3b9c2843582db24f18e499bbb08fa473c01097ee733f7eaf4d67d8e0ca5c0b83d8194a1188f06b6efbb12f155f3f040d539996051d5c2475a816e94b8be1ce14a010000000000000000000000009a4fef09e4870386bf84e38da9d9cd820b982d6f62f07f5d38c7b33441ea68cca7382029aaf31ef254ab9ebf8952376ebe3a747d532342b61d6962762dc93b03e8b641b25c96675c6aa978923496501b5eda1d8ef7bfff76890f777c358c3fdc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000baa97cff807a1f8526775870d0c118b7995f37456f1bd66ed4365e334fab57a08bc3c9f9d6d5366463ea676496f8927297b12d49f23ae4493d4b67bef93783a555967c0d5b8d6fa197ff48631c7c4be57674e078a9f14ccee8e440940cad1533c902514f537badbc1a660bcbcff5ed0784cace2373475544e36896981fd94a4a031c347915789c2dc872c629adea110d24771f6a878bace84b1f75993db3fbe656032a06ddfb3732ebcabc68dfdd337330ac92e72b93e55b8c4168c6892c1cafb3630a0157a745164ab365166c34791551038bebe0900d186d099a0e7821b45ec32212fbdda2717d7674397a12313cc7789e317d8d9cc7879c0a6d8e59f1d375fcf850031d8f9fac930bd84a61b125ea54a99e47a4788db6b26b257da1c1c2fee453c01f030621a5a5af6362f8a9381f4781919138be214b9c3490f36e871802167f6616d60329e38197f61f8952467610bbc72ef94a2da03b9a0190d89abd2d9afaf15c1f3a0327d776405fdb9f549b3bd63bab545f4ade0e52dfff13e40471beda3cd8eaadcf032159bb40d66b16f267a64b87aec8041ecbf565aa28af5cedc02d8e32b7f86ab9030baa6fe6e2a0f9270c42fca4477f554019aa6e7e4fd75a33f6eb2be3b3d680fd6d2fdf7e121a2015a1c51b8f93dc4915b370c84e07e3ed3aef7f279bbc66def9a0562838ba5e44ec05513853e6c68a165853c0719ac7d8756aa7382b63d1aa7fe61ac90e245b3d1a225cb96125c36ec6ac85137f5246b4752616ca05f5d3db8aabe0578601560e448c8d8d492de2ad165eb091f4e2db48ee333424c1be8ab456d23b7a798e16ebed6216c28b76f63865cb51d059f82ac436301636c189e20eb19bf65ff4bd9f4d0ff536a47dc30529b41e2247849de7ef75ef4cf972c23a85e5777171b143be5fa879ebcf6d2457cb1ae5d8e5914daf3fea458dbc354a18cec7afb29aef8447210b9ba40b66ec7be3071b8c3e162feff556c3a0155e86acc07dcd4c53d0476fc2e309f6761609ecd1c8dd8b4d6d4e93fafd9b10cf0ac1559dcfa3a26d25592286459c0dcb08766197ef67fd3e7288844fc2719116cf57fdc407f7cab16ca095c05ee208840a18d9f2da3598376ee83041359ce3d9394dff409bd20b8b85b77406cb85408a4d77c8914f025c917fd40467003000e5b507ffb91f3f06cdf54bcb9be2daa597f26a4205a8f0a010cd2e19fd4439ec6e07a7f55f04414ea4cacfe27acc2191d2c730619c1d11729a1d0679ed56c137f7b87777394559dc7bcae9869d36222da768f6e7303867b90646dbdc861d0023e1921bd02fa35ba02279f0c0c975634e85ef65e4c601e2af42bbe8dd0ae85a7779b126b118ff96c4de3f54ebb4097419b0c9dde2673c949e73d87e0811aa2597a03af93e05c5fb06bfaa39dd5fc1c799db09b4ea25cd90394655ba43ef0e7ceb491a998b4fc0069f35912777d017e322c210f8d515bb238fcc402de15e9110a2511e6a1665604a23f4083daadcfcaa1602c8b41b50d9da0b8fb3c6c1d02111762ac12166753edc07cc7e43c360b6df9de6bc2e6d89681345192be9de5488e2ba556706f527cde41984f3f60837714e6d75f1f7ca5b0a2ae5cfa08aefdfb27b145744f8187c4eb918b29924c58fbadea874bf41664a5040fa0f299b89e5ee5a0186a50937a71c382e40b6516ae9ef4a9a5c6a8c384d1504a886c3e7c5aa68326e5d760e08d6c5233023a896a18ebee48218e5f0369e1b2a8236825f0ecaca47478c7f0091345d09ad38471f5799b4dcff0d1d19b5d337554fd4caa4a74a1baa9eb5862c9870fc0804da9eaa4f4426deac8c4c15be489e6e106f77a6abda759181486f2e51184881b07cfe0a69cafcf1bf2873011a4093c89c4b55408613150dfa756b0c00971a5df62b0e5f98d5ce868f01389792af40d33f400021e1365aa88103ae1a86f34ca7f79316a8fe4f8ba04317c2170adc9f80f2dd3fe352c85df077949301bab88adfb7a771755c09064fd527651a7144b8e11aec272070cd80a9f54a1c3b14ddcf6beeb5a8b81c3e29967ddb8969de4c8fd2a477e8dd29417e9949a134fafae8d7d83c9eaebb5d7b0568ba7fb6fb31b98ffae248375ca54f62cf085e71e43179429f6a0873d0faf23457456c8979dd04d07229631559f91566c661796e49fb04776a7f2bba859a98b4b3771e3ff27c7ee3bb73352605dca5eced1e44b9fefa51ba718c1cc4ac38e17b10afa8b2cd8d7ce67b00f91a9e8c345b95104ba0ea3ab5e36726bc2aaaf4492a7edf771d72d18ad0cb813be2a129fa81889088d9825515b56a8ff5d6c53e514a1d981933e2e9c9783d36b0fcb6f6331bc93d826c4f64e134e0491f902f534efb6bb092609d5198dbc818baf3d28a7aaf0e64dd72c430597c45ad07352e80923a3906d02dbe7266c303", "525365526a", 2, -1437686251, 0, "5e8b40e4a78ca6b071a19eea9a75c73c94dc881d4f79885a2e21932ecec3be39"], + ["7a2a4d60015c20644dc228e31fab4b4506e0a0aecb45c1b0a0d3cdbe7ecda5723774b4658d0000000001631c49b96e03e4d964040000000002ac515fd7d6040000000004536551658bfa2003000000000463acac657db894ee010000000000000000550eb700000000000d66870f4ff17af083cb8bd3bc4c7117e6887704a86847588ff145a2a7c4c4d206b1c75b7d644ac43458ce9cc7c6f6e14c647ff4774b86fe1b59c8c9db2ba88a3bb62a74fb1c486eeb2fc077aacf17ad0e1461ad8ace4b20ea8933066010fccd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002be84616d125721edc0ef8d300e2441c91e372dc45f699bd2177baae044f6128dd9f9a5ed3ad9004e9f818329626dc9b9df6a2e4ab2c183d567db1c3fa0ba1cffd1c21ebdb62eb49d142938ab42187ce190f6806d58c6805ef34870216806c9b8a1931f827ad5a63e2a2be6c1fe1d6403cdeac82276ba61c0e93d7c531888798022e28a19eea147a5c9e1ef4532354f81aeb4ce4aaa20174f3ab0e57e6c35ace9d03094e3f5fbbe28b48cf299947367b4f1e7269714c8f729be2a535091388b8134b0a00799e6a02557aca81303301a865945b131035c34a947ccc128a1181959947c6e044cf5f6783a6ca902b6213f5e4f0d017e68d08b49db3b0b91a3d4e09b300fc032f7e59d7ac4f9f6deb532e3c311f40c6b302f125306bff25175051360c67bc4f02010ded6765807334a55dd159f0da28e4dd6f6e99431be08abc6e555c29ee68690221ca87eae0a5cac0b80aa353ee1a4aba1b3e4c211ff4467366b8a4fe0b40f69e0202190a3043c67a7d41f4bd7e7f2d1c4dc4c8c7e785f8e081541ca49172a9ae63021469ac58e53143e38682d130f49e47d80a7d1a38bfa0bf3de83f21fd1f82c75f1f3a5157a49d6403f856e5d06bea04fea067a547a7d9077f6fce3543c950e4e9a08833eecd2903c3005f99f4d64bb9a7d42c4adeb48138de727d3e84ef6163ccf05f2150e3a1b7b325c0b0d19e8e05e6c76bc1a18a2755d78f7cc2ed2002567a8045d445432ed10e799be1f56c87c447a61185ced3c8a42177dc6e9d0f2dd6d3b9222f2ab454d2790b6e16ec4a0faba45f71968d13d555566c0dbcac1870bf631a1d1dcab9b890bc4db236e6d3e76775e20391cfa34bba031fd16aa952bd2b1f525241d15f1a0266029b047b86d8b06db48d17665717a088736a5e0aac0207e6a4e56a51e300153afb2a7bd4b3e5d8e13143f48c1312efc86745f11bb45038f7e2d26dfff3f380761f97919d6ac38c3ddc033a8c00c0948c6000ab829c5d7633e9c8131241a0ca7ffd6aa55e4ce8ec8b5c71a8c0bc919b7fc6b02931bc80726b22669a1b9527c43695dfba4d270266a301bdd3a6ebae09e191185a077cb3435391102c11acafb3ff117654a70506b07f567c0c25d99c22a7aa677ffe09a00661bd6c7539fa14c67ce398151d711cb65e44b2064fd86beba9fdc6a9cddd3249abd7a249bb2ac4a6e64f8915cf728f190b0f591795b33dd5554b3fe6b35905f9af3f94cc71ab7001f848d88190617c27944c4031550558d2603b847dbe61d720515ab73e9df75ae7ca98fe5d4f8da4362abac6850fc65951ce88634972ea28481888cb8e3b6f939352871683f03e920eb865c043d79e603019d0604fda43e71cbbe503a84ede22d0419c061749086f412ba45cea01af20c91ef77fc82063c6652679fa1a8fa6c42498b1049d58dae0ad07ced2cbece6cc93c854198724d368af97249ecad20fc2dcf66e3767d73ba7cbd84f1fa886858ff94bb0c05defd5291ab285906c9c6f9e6f53c7e9bd01eb372db1064757c35dc3db90c9371033d5ad5e2efc1e3eedeccc7195b48ea6a826489890f79aa1fd0e1df1f32d4763620d35349064a4e547bbd15307ddc97c2b6940ab3e4b06ac62ccbd4718c77dd41589f2adc5129c736f1f3cab319306ad311e5a2e6bed0ae926d461fa11a64cd1e16a58a0e804d73f94f4dd1deb14cada8124727640ddc2f1f54b62be1642e95a63c7834ab488224514f22304cfb8d71816f9afbb472b6e798e9720d4da7b4c963718e49e54f570ec9ef146ba4ad49b8bd8767f107edfe59ea657a210a9e722eae2d416461e5311962fd0380724895b34733b5f18de9984bc8fde02f1bfacdb5728c39f3b97c9274e16411010304a66cd1911c7c7553b014cce6b173808065f7cc22d2e8de3a5ff1a88edf93fcbfa73507a9499c4a64d589327e0cbbe8e8c5927a2597f4d033582b759277ef43b012de1b7505ed9b2c943f6053504f5e1cb518abac4b2e15b78b96cd6369ba97aab8387c9560081e9cdbc02ef56da579ffee9ad6f749ce4a41091488f4d3f1e5cad5902c0f78dfe85df778b0ddd7656aa3623296c5571ec89105a82c5ba161b9ad9cd0ac9bfb4de167ced10b811fc7b3bbaa4ce36c2d957bdcb94930d6ebe4975a2ddf6c602806c04afe4600c70e99822a7939880b4305b859b10d3b9534745574a15a23ea85fd0adf5c8f4a631ca488a5ab67df8d06d7ea1ec5ff4f86e548c5228ec9b0e80d66277e9d5414b882919bcd39a184d448f66b62f18d6a33fa1982fbdaa72a9dcf7f078207f8dfb6fee4915ebfce496185f1562ed1f185bf13e18442872c1912b08352578d89b710cbc439d83f89f88c72c071a0aa8ba94d18c3cb443770bfd672d314d704f82c381a6d3cc8d9bbf3755f2a059e65fb9fc75acf04075d7f64c1641bb9d7703", "51acac", 0, -1552337250, 0, "ff37ebcbb4ab9db4d00fd8e571bc2771ac064a185eb9e9ebef1ff86730e5a57a"], + ["030000807082c4030153306eac9efa5977214abaa5267851f2ac1adc336937121fa481cb01ba2cb18803000000035251634f47747b03624ed80500000000096a52ac6aac51006a65e4995b02000000000700536a51ac5200da081a050000000004ac51526a000000000000000002a36209050000000000000000000000007622b125023373c93daf719d15aa8e78b79d5812036a10ed11eda032a693ec6e3b66fa22018371fefa807c2db3fe2140d594a28cb5211b61de6f8f496daf64670ca4d4d2ad856700788f970b63ceb5daba1c92b71ba4ef71147f2b78bebf01a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036e3e3ba257a974cf871d9920965500d1306665ffcb58c88284e68c85f422d6a6d4c0e2734dd20a1a68a9eda07c950b3a794d2f44566e02187de1ca16dd8e6eb3c617a7099bc8470fc358f4b0eeaf87599c603a3debbebc893704d2402e4f83a1022b08cd1016869820f101891e15547d6638476cfa8847393fc683fb8e93c0a031324981dd61c6db3dd15c3428e67f615762a04a52eaf57abac72c933555e6b85032f930d988617c44e10fd51b5a07a79d1ea554e48cc51dde5fb5990d94abbecb90a03ae22cbd8ab4132f49b089d0648da65af55b1b011acc6faf1e47c15bf4942d6ca64a807152db93b99ce1b263f5d95c2bd099280a174e670e699455aaaeb541403208935aa66c296fb3fd97c8ebffa9ae9e0f108ac70b31079df93d962c9ee7b03020e5d6a24e99e57a73a55bc49f1505713f4b7d5ff4044f88b9511ae7900914eff0226290136111b9e5ccb6d6376cbffdf3f815c5c6a477dd1e1bba7d750032039230304b0f317f822ccd0fb68a378f4a59150c218b2b371d52aeeb2171f6847396ba4031658e2f12eeeb1715180378b12207fab528b2325aa132632e5499500b16e0462739b348bf4faa65ce0527717def1fa9f2f84bc9acec7e942c12abde345e0668e5bebafd37ae66c8c10a766f9092e8d7f08209639c7cb20634e8ef14689dd13e31b444db5def1a88ff9ffdf4b6ccc981490b7a97497158a90f9b18f3f4d30ae16459846b49ec55ee0af06436ce438aa78f7f0e47bad079143fb24ea5a86a2c47ac6893b03cd0b2315c32f553d956b6c8580b30b7e14cb25f148d1bd07481958ffddbcd6946bf2209a48d156526c4ea22f25b6f962b70b206e6921bb7e8bcfa29d4880931775ce09fc850c9711b2ff9cd5881fcae453a35b060fbb86650650f971b2e058387b74a59740f3738eb8499e168ad11ce61267e97f580a522fabeba68e2c97eca95bcb806acb7316404f085c29d3edbfea2eb9f74e0c892a20d9f6f24af9882cffd45b5cb67319e7491d397bf41a64877e60e23d2ab011ec85399e98a8c96d10d095002a466e69ea7a6f8155f0cd89b5b1c853318de181df95840f65f163d6971b79ff02e060e4437148d066520f213145abb369e438f2681c642bbb81ffe3829c8b1c12f443349a8d2214cedf75d14fa4796618b623510a67d314b5e8c6d3069199b2ca0b8198da01a1d502cbe5349be7bcee31b4917fb29098d22e7e1fec1643a008ebca922c692fe81a12d70786da1ae19181d6c5f49a1277ffc748f523a3508d59274473e4502e14a02293f743792c916919c825084ca9508711a32ec99243b187ebbcd4d028a242180fd05118675e038d2eb0b19b1dd76c68db8c30f15309383cd7f2a88c28cb30473014f6c2f181f13871b688fdd7422352ce33e56b6bc2f6ab206dedfa63989ad0f75e24899937cfca392c0a0011b128730f9388f866a76d562dff45b9b94cad22ea49a1ee5927f28692d715d24299028607a51e080956f3ff73eca7a343bfb35cf0da29b64100b7dfca5a9003353dcbbb4837064171b0d91d697422fecfb675f49da66743ff3b2e30a35dfa2b5098a7a9738383d965e5d3542419ad56f7e3728e30fd7bc32d799679edfd0ec0702ec9923373cfd94e9fac40cf1b604851864505b52e595d96e99d87ec93003b0b62a203b256d13aa94336cda1a001bf9645ed3e9dab12668d2632b6887b2c8942f7d84c0ea1c59f216374b42206c9af616a5b2a8064fad8e69e99f7755b18f3758d363a2b87998a2e82f7d87ce68ce7b3eb5cc36b96517d79d761b2fb60a15f3ee23bb645611cec251e578497265eddeb8295398f135d92089b79d8dbf1409070cd386f8248b534919fb5091913c144ab46d6015f5b092efd872224acce4860cc43b722c4636cc899ca66174c9d9f3f37f0cb1d7cb9ef3bf9713da27e02376fbd19276351caecd12d98dd08b8b5368b94c350757d4c41c712deaafd7e56c68ee5c53304472096904b2884e9a9eabac29b431a795e3d1baae201d41623d6b44c1ee914212059c0c93384c460629274aff5f45d373e79ecf420f1abb173432672b6766dbc52d4863a518c15dfa5788c623f187fb30907252418707af6a9b1b50b07e5f100bf8873e558a9448c5907a148b9c5531217bc8d6e8d5294ce5868d25734155f088d8aeb5d58735a34fc1cf28dc4aeb6a58ac31d4a54877101b7f8521d5371e985f8dfc18ec3f7142146f44103e4095ad30fe6f556a712c89de1ffc22caab231c976132e2ff19cc129eac5b3feddef7aae936dd2b33637d4040000000000000000000000003153260fdf06bd816c30856afdecc0be98fa194afe985d724315dd5bcc262e350eddbe735c402ca81f225fcd63532e94bbf74f64c286284301953027a9a04d6b85deb61090d39dbc689703683a380c25333b4915d9e0213966982d5cb2f151a500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000685fc13d559845f61c6824b3d61b08a8d911dc176c143ab857b05710a3416c7704bd4b33b2d5765bc51dbf73a9532fd96b5e34bcd9c7ed5b550b626758e1ccb6a1dcfc0bf271b637f62ff895924da2e96c5603981644aff58af47f27e6998ba4a3f34e5b3dd7a9e327aed70b02e5a956f88d76d5d17f6a176943dad5f6b0f48e0329d9282f09065a3b9ca1594023576de2cdb6e6acff84d43b9d1827f63e8e40df0217a44c79bbb0f4ceda587b48e8e27474439bf34ada853a8c3ba87ef60c0febe20a0549f2af1ac0bb7bf1b6a4b7bc8a131e4bd42ccf22805357b04c117b0527a75b23fef93e9d225653919e9eb6cd1cdb3aa9886bb73fcb02b1f05c83b3331688c9031682c8f23b3448e16590bf4b316a6a99b18e34108dc97cd38073d70a5ae597d5031730131b63dae7c0802e04902852f44e239c410b94cbc77d3408974fbd3f99230207b1b680427a40a50351a974433f62d6adddee5e2b3c281ae07d92e20b5ee277030975e24828bcb3bbeec4fc746b1c55b7422bb5a6feb6424c48ff6f72726ecc21031588f25aa155f753e209e109c4de0130e4a4f0d1779a8fbd2f32754018cdd7e87d2b665c5fdbcbe9a6f9886ddad9b064fe2e305f4c0d7777d0febca1df67ae2841bed999df874fdf70e331c7adf33f756c02f0501b35e4cc33d55718182587c1b6abfb9fef39833635eceb024514dfe7536669ede03f0d654e0000ad33f52345f9d9dfe7d2b8d5d142421aa83d75d07779e372140635b527f4a98c3fa8214a17b3365be5cf7c4662e7d752f2f1468ac93d25957536ce7be4f41abb59d25c50f92880c23194d1c588a69049784bdb53cb320d0466c0f01f8751458afcfebf1e99f2fa8a3d5e2cf465bfb3c2f5044ccff094a383fb8df91666582814de4e528d98e1b95e491df6455ccefb32aa1b14c562836979e340bfeddbd2e7f08d8643de9cd896ee83816ebb0931aa06adfb9e352c454a18e935ce0d02f2c3a540513fa3fac82f5a3d93b43024625d5fd3426b0e223bdf44f7d9b2bcbbab3e2e3c2b5c8d74bec90df2a408b455d389365d2793914e61f63cb5c207eea1099bbd08464e938ca98a029618a1f0c621f2dceac7ee6dec4ad54fe9b2128c79846d32dbbc3adc713af8f3a93b60ed2ca13c02064ad456c8724125e9a3de5c1d6b7e5d92db31f6e8db4dba34868b2267e8ca3a0c19409875e2473a918ffc9ee571c8a5f0fa7dedca3a0c084fa49303253380ae8381d869eed9534e61cc69eb91a8fa5877f687a9a24a7c9fd51b78b9ea287ce2079fe22f7cb24adbeea03bc4808ba516c47b62e08813bf8b0487307ddd5425370e9f91a8f49bb411eceae5cc52710e9ceddd73add4cb24a505b4553a7ff2090a89181e3e200718bdfa35215538130eb7c475f125645f6d3ca96f1b4a127400e7f9cee00654bd93a19c39bd8f58e542528be439bd4b0dfd4100fe072fc78da9999381be3ab82d9592ed98c755858a23d969c635598f279217606de5a63dbd2f32dd7e33903560016ec6c10368139b54037b39a49595c2b47f0e0748aaa5347db89a2410fa89e3fc4100eba796068a13949ddc9cecc2c9ed4bc4db9370ec48124390e6bbfb1388e8c7b28d4b1dad520968f3b71c5e531943f0d9653ec488320500c9c1f2b6fca1321179f131c1bbbe522ec11fcb239b255b9a0d76b4cd4700356ab903c633096d73e0ae66cf93643c3a28ccf5de3996171737077f6895606e9280658e5a66767532e9554c3e9161b5d4066b5ca434b3ae648a0012705ac426a92f464fde558205ae46fc02abfb62fa3b6ea50cc4ef01af1f127680c62732f2aa3d4fc8163ee4d80c028e74478a237434d8787233dd150eb4f49c2b6568fe3d99383dfc5663c6e18e1171f0c70fcee01d041a3453410e827c31ee88d990e4777e2ef3ad4b272e3ab4ce4e1d435e56585360ed20e363feac505ca249018d8668879208c1ad47684fb18a7edb67ea3e12f583ba4211b18c7848d392af9410ccf6aa895a5dfeadd66882cc866e05802b74fc4fc953f86e7f68bafb67d782552ecaab8ecd825a27d5bcb418b5953331226d0b61aa203c52092cf2341837b7ac84aa8f29d3d0f6855872d46f7c30518967b9dae053361f43b1f0b25da68b71c82cf44d2a29180cffbd9fc922a6e261f8554b0db52e3d1a95ad9e9e8a41eff98335e071df7dee27cc75485f3d065f1b2e7cf1d4662db4c642987f387908a071a5c723b6ec172f9d5383e83b747db1c5c43b66067ce85cced6d2c41b7d2b567afd27289e35744070b71e5ecfaf4da45d6bb344ede4ef9b0ffd6da5d4b405e1d7a332595a951da1c3a161d253ff6b09ee041f0ff554a133a0fd1d53db6f80c30831b28947aea2f66b9d92493855f87d429db3b888eca92e30cf0b9a753211bcfdfc1e299440e7ece142d87501", "53525163", 0, 182308742, 0, "2064f5a29e47adcfa9d12f6afe91414508b1937781723ac21cd7662268449a28"], + ["030000807082c40301560cf8270314fbb298d506d603b0816ed4c5fffc5121b2a8b74e0e8054d0fdd003000000095100006363536a515230ec62ab014609ba020000000006655100536a5200000000491663be010000000000000000939d1b01000000009e5cb9ef3d4adeaaded3a1a48418735968a9f8568a9345cfe4c952f9ccf4da041359c9749efab5a3b10c4113a8af1a0f2654a81fc5fe4da295615d1cfb0d53d31ffd64e9840863b7806862702e245b9f5260bcfccdafcbc2e21f8d1ad4b38f7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c70558f2659a25500fe4a42fec1e72b8aeaa3995b01dc1c74b1f4233a79a4436611df037d8c4e35be79e81aa3ef650e67898011a64f4e4e649edc49eef476b4cd3da15c4367db47fad008ed5be7dafc5b132700f1ac545d33583348282b429c4c5e40b922f1e922856c3cfcc061a7aecf72652ed4e456f0a29fe2ad3f190eb4c0212b6a0b2273b15de2a59895cd56cbf329468b6e373d30a812e717ad51079bfa50325da8ac25e4411078c4fc4a72fbdadab556f46d5e6a18735d83135b465e15bac0a000f6aee396062e38e0358459ba111ae3d1bc4ac3327811efbc223ef035a1cdb30e8ee10b88e7ca1fc2e89a288589b65841d61269bb5c31a7223a1dbfc9d34ba031b3abe400d4ba757f4086c1c46da22e4fd1011bb35362e41ba6a7afb98053d4602141a05f8013a5179401f36fc85d7bec57b707e6d41934e77c7b20d50032208d903004aeb48435fd801867b034bdfddfd1d94c09743b28e5f2191f240f839e274d402240fd6d223b88c6df088bbea02ea9129e2c7abce548fcb4b9f5ffc7719bb456e021292f9ca3005c99a96f665a3868f45c683ec214b085dd1c211310042665293a7c6ede646ac3ccbb16bb6af003d6cb8e6b5c3ff95c0ad7796aa11fe4c8057b40874d4d404a3829bdafc305fccc3a94c964d1fb5b7518e4bc92cd76215f95539e707ff25e76a2bf14b67dab10469775877f7f95e577aa66c6ee05ad9df4b885bb244daa5b619f86cca5354c0a52a9ba821e3628f0d5c61c2ca855216bd03dc66fef5c3cd743d8fe36f0471741be4b20e2b2d3dd4b941e5ae9cbd9aff715b4d6e64a46d1480a5efef60726ac7cbb8808d9b7f7003461edc629ee536a974a0618f7ee9fba13e57e129944f47cd0a76e11fe88e14f601d450dd59bf62915c088d156b2109446c75b4d4b3896e763cbb7d4b8137f19789188d555ec6baecd99010f004bb1ac7fa1ac35dfb8104966fc54600e04ae9d427940eea48b3d952c9f06b2b39a8c78553d9e4ed37144f25484cefaccf1c3ee6dce7a352b5e9857a3686dbd7e01bf6ee3389ce9c62d3a65698d69770f8459689afa9e42922f9ffd8aa42d1bd7c4d185faab20ec344a2c63b9474a639607151390257c35443a9d824be42f15df158eed97507911362a3cccf68aeb4a308f40306586fd770642d06b6098e9e0aef35ce1afdbd67231a413f95280054be2469dd6db430af3f63ab68c2d1a5c4cbc2bb564e30d84294699dddd2de956ba88888deaa7ddd0f3759e879c12dcaac5700c35b6d72cadab34675ae78c7194a673a353f88a30dab9c1d2eeba7a144b41c9fc112b7b763d8fd86dd8e6764d859d92d5db3dcc081e500f9246bf1d034bb433f4a89aff128d70a7c26b078e5110d76d65a7bfacab7fe607dac0e392c5caf91655f159b7307e162c165a056d87c56596f782f0f7787799fa91dc8c7282c0cbf882aa3917402d879368d4c10c3e9dcaadbba2ddce675bf5e7ff001e943d761940a8e7ede1380b82d7c9b43f8fa261169f53224c534a306285074fa7bb059d0d25861b7c64960c3f6632a20448c415e020a87911a3ded54308102b82822a45b0694a7d3b42aab6f35d07b27ceb4bab39283182cf17d28be5fac55faa53e409c67869c25de70f22d7522e7d74875622a91352ca4ef4029be184272c0948167d6ae64b09b80ad4cf652d85cfa31f148bae5e62b243a874b7cd9c0957d91ad0467c1d79839c971a12f0d4c3ef34116d29363e962c4f91920608301b2a26739a86c7d32077fdb0b21c974bba98fac995ad48692d72cd0bbeb3797674d581e7c7355d8d6fc77ab7d4c04655eee37891af6fb8fae672c3d5b5173a0a46449ec8e1305539a50cba1ed34ea4e568e96fd1846bab4ba470136958583f96ebd6b40613258cd60127653838f63676f5075feb59af5a28739ffe1d11fed008a0a2e63b19d44ef21611bc4e5fde7e917ed7cf96e349d2a9db35433c90afb5237326f2875fa39b4cdec9cb4d2c5835eb2f54a6100570fe76116698617c380c905633929c93debb2dfd9c36ab0b524f75eeff15d5293f2d84f5379a117d518919061f06a8543e64d96cd6bce77d5169c2a4ed446df2d2d7aa0158aca48ace0ef6308cfc2d4c22b2be576c633c298509d06efbc7e2b00ac9ea45b35a77932aa3ad0f88785dd85662f784a8ffe443058c47566e7cdda17a6f8c80b34b061c0adb46269be2e3e63085b81d92bada4597ff1f845957f1401e420dbadf15e6393b8051b0ecec066bc774010b8e508aa38db1eb17f6d5649fbc660362e2302f204ef01d97cc78049f9380a223c788190e6b22b3be9175241c88c2acc90ee0b5ac6ee0f5254f532ec65274054e52ba301fe513236a3db23d2d240ffec176f1aec0e4ab5b0a2417df8a6743c76f779da947a8b1c209e0781e8d2a69850ad0e", "63", 0, 2145458821, 1537743641, "acbf3d2002709797ac22c6c4fef2ef9ee98f30f1c5b4c8ad49944c9a2217f7f2"], + ["f124d0560356a500ba8633610d2e48e4b7de0e41c0801b4f021fecd816179136a31d4c927b020000000265acffffffff19b7ff3d853287e877130b3ee3fb46c34988c5d03f7090fc53c61792fe3716880000000000ffffffff0c1b5a05262b7d3ce6094ea6439662bf0402681839728ab2da7fba2e17c50e3a0100000006635300ac6a652d2798b50382831700000000000165045b99050000000003526aac572b7d0300000000075300655251656a33e723e1025bd273050000000000000000000000000bb268bfc72c8cd4b0309846716453397c484be4d928e2c756ef6003a70b6986d01a6c2d8977ec699b9bf8a38d1333f4921528b4a742276758c319d3c99d062cfcf05c8bb288db6b1279ff115067b013f96b90d733b0b72af309306fb97f8ffd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081994af0f4816a4f7232840d0d6782a4a5c05703c4550319524e2108d69482614e77d2360066a7b46155b8ecc7c5b23ef8808df9034dd1cec062ad85db2985e99da5a4b208349519ded3981772be1c2f5cb3f3b37bdab6a283a95f50d42779ef1e9800445f971a15b6a850b863279369f8f976d93d87236310f23cb477d93aff02204d876f213fc2c27f72123232c9380f3c71fc7be80b3f7bcd604be0c375ec210201d986c23d28451c615bf20826c74f905b86b635f00154b392bd548d2bb41b2d0a02158c1f4d769c5886f2425e908e381ded8b303e7ed354db388bbad36a594a124e4cc7abc45b71f2938e7b9eac7d7e4f98a7ad74ddee4b77b097105886db9b3b021e49e58a608e0e305a23ccf655870e0dde4bec450c47e14a3301fb5dcf0364de0318cd04a232feb840d180246d450e308ef533eeb7cb15282d4d463be5708dbb3d0207f60f0019119c45aaa940adb782ea425edecbed4c4de990baa2be795394756702061a2b4b9e86d5865327268e5aaba95e3e530cbb06889ea728dd4f7c2f31edac03058f9a3edce0957c1505fa1c85ef9532b4e25311437e30e51b9802a6168d78a46d944b77218b4f7cf9e7cb68ed0c409bbc31f7152071b1805d3e65781a710fbc52e9b2fc7c0f67ba2c47a4c569a95f95c6b8b2901d15728f76d5ed678e78fef6bebdd9819b4f104ff72f42e6787565aff180dfef42e5e9a113e65864054fbb82cc67c3582749f93f99d951f50cf6b424849fe5c4dbf67a485e6965a93e81d1add8f366d2edd77fc8a63a138fca16886b2e7d971b2b2d83d269c66935a1a6fe0ca5f65b72b1f6a452e93950f584e64d6d094f44dc08307cb57d1159a0d2df1f01f6d2e012e21ddcceaa08d4832df99f17d6d1681b9d0fb7f46ac28e8ee8e9170234d363bf7c074574e837b654b74c5200879ac9a81c543d67b96c6f5e4b2cc76cd1c38a379a3f68f84dc737d2d7706b29f89a0711261c9dfd28d83da5c98ecea3d53e8ad1f777c716e9700cf61c91256ae103daeaaae6470fb63ae6400c9fe963624d0235320cc4411d73a8aa755dc01663f7be166f732f2f94fbbb5ec6d84cfd9711723416bb3c80791dbff009d5b5f7bd3ec0b307c72e11defeebbe6bdb23a05342128c8c5ad9f6e06036f9a01a14a28c6b26a75396fc31aed9a2be7902a30a631c50b6578d2ba379afddc01b14a9e7bd0056ed6edf5437db7c5f2cbda61dab4124219790ed13c2c7d4d8b76be34250b4f3611d0d522876b793214ad4aaf71857349d0def15e344b7cc26f8703050a9bac9920e00508aafe369209b922c05b081f27852e56ce1937428bb38da685c4679a5c6a12aa3454ec1f0503b34f1617b765c50288ac144d4e994db4466b230eb098bc56710efbcc19b95a80660617e9c3e1ed490d111bf171dcfce1dc89d271a35799e3df9aa21f5f9e266a2dae36928d4e13d2b554daa4ce3b61c4aa45542fcfe8822f32c0ec0ee50f1084d4ed9f71ee6d5468252214c8ee6dcf3d511df911eb89bb048ee1a433e3556a71398be57a64d142892f720e1f10a9d468d1bf8fab201c18dad72c927da19c506bd8ed91d9c689db149a89300d12dc2d2cf3451befad4deefd12972c49b36f35accbd390e180e7f849f8254a97eaa6d74c18867971007fd8b8f0d3551f7854168b34fd367de54507eb3ac31f10310738f29e608a7c8f622196922e94fc85ee5e1afca7819ecd5a14188c85b1dbce94df6a3bb5b0ac1e26dc71894174159d4b8e92f4e4b3927351b5186863ecd5c1c054cd6a3e7e1c5548163bc6b5d642d2142805c60797f5c64f45d99847416329d734b349756cbf029b6ed7a55d320a373776cca2da65e64a5b6312104aa72840729f31a5f5cae9a88e46c6744c763be1eb2c58df5c8c40369450c0643f7d1faa2e88935eeac3abfcc16a51d0995693d0f80c7d5418423102e09617f9f44049cac106767fd4a214531d1f6e5292734477436cabae98cbf2ba2b222e4207d6ece0649e72dd6beef99e99bc2f58b1d5211b0eb26855437080d551e61dca4e8cb808015f967b73aa3ec083e31ebe931c5b75bb60793718622f90bb0e0dd0f7230cfe53f1ddaaf676d1f70c9ca9c648f87747943b788999db0c247e58ebb8b8cf95c77e3839850f6940cd1b3a1991cc4bd25a578d58933f179992f4992b0af00cdf78b71497dcc6ce6ebda464b1712f44e214dda7d97b4b97818eebb2a43e451cb87d20aa3b7a5b376e6d1d133066fcaa27c602def2904ef4611ac67029422e5b3f3687c8d12cc22296512520000000000000000520cda0300000000f87e9ee26a2318d7da1a943b61139a3f6349008fc2d82cdc4d70fef5f6e768a7f34143ab8ee01ed31577b2662740ab922aa0b47ecfcbe6be3dad9475ed7477593e0b0064cd54eb0ca6eef01ddf62f17999abff5e706355405f8389f13850c818000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ebdeeaf5ec8afeabc4098020511fd46c48fbaafd64716760159329cd083d7516c58e18a2fc6fcbd39146ebdbde2526f7f317a79075590f8ac6c07ffeefd9c5d076494cc47f6f90e7edd430354cbe45efa9324cb0068737f5ffcef3d242e1a156ccfdc69bda84fb4fae251ffa26e90121c03df0bfa2dcd31b05728121aa97aaa0225e531c3513e36e00816fcc838aacee339fd621e4d2662a548951ca01ab9605b0322454fec6d410e1a11c9893b5bd719dc6417e1c56ba9021928cc095812d643700a07cfc1f0cc4b97f7a1ffa372355b235e8ab146373d5ba15e49f550dfa569dd4c0c761343ba2455bf0587d57395fa8e9510224cf39efeab2bd6fe204ae9e47ac70223562df4319f1610ce8862aa0810e5315ec9cf37d5e0cb75b03b6ce5f1708518021aec55d05523babd0140b620d6bcbc46452b2698fdbf62dcfb7c30d9c83f98b80215baef080cf91573f27bad6887c4a1e2ae09f24f1d6006a9f19c359b9189c364020a349fe14704811c0bd1c6189b586d9ed14560f104b21abdcd3761faf224c512031d79f29ae951d777bfe3a9328f113e0b9811d5488bd03025d756faeb567d4b80e1af90e4e7035f4dabed67299eb313ae5ec3297555743ff433c1e08bbcfe0d81f6d527232a2ed33997117863149210f19238b5b210f2fe1a26486275fa914ba0a1c56de9874ab504d5e038d7ea84a69bfd4da5b9ad56b7013b5862d3a8b0a4d6a6182463b37ed037074b379d76d58faa39cc0d104b6b8b3d698853352e38e18cdd963919c5a810f5afef99773d0f4ce6618067bf5bcffd262485c1ad5784f63b09a637beda153b8457a0f5e120ed0a43a60cf1529663b9573f4ee00c7a0d05ea664d8034343c55b872a72f49d1dd795aac01082bd4ae9024c929102d4fb0f687457d64a0139bbfefe04788ae1166c2ab7cca93d5687b91d276315f000d886b0bb408808427bbb59c123782039cc4c166ac785190135bd5d3edb0016074696b1fd1e224a456a9c9fa4aa51f3f13abe8a94f710c4762deb074cc6221a381bba1b87e52da570df2d8f9d48221f19aa0bd089643cd170742c01107fff43c06ff82dbf44c6971b11b663aaf15858ab27ba3c4ef540f9bbd8077289fb616c699df02ffddf8615ffecd7da1ca8d983733dc5f296d041ca619e6510d2eca1a54242875d9a06f306456b24be2a579d3138e087f95d57dd962324ce8d72922f9252207d20ff2946c1fe34940e7b6e3899b3197023fc8188ee470ce2eedb94387b06b3b016c75d7bf8bccb985db059e155246a1d346823b03f902ad621275662c14181da1ed462f0574d97e35dccfe16a369c3ae7d3a9f6e0de87317b2f11dde42c6b2849f2e898b60b09f2ee912d32eba3240eb66a90d8914be12075e9e744e5fe3e667b0381711cc769ffa6dd375cf2ac840d02541832f851e05a03a136f625b3747301679b5e34dd2bc07224bc01a7f6c185ecdb8b0621c52c12aceb81fce67a9c7c6a657b27f1bb2785dbe4d7c553ef5f1567780a21d91d826536a66c32c2162b749a1dc19ce982e9cbd61abc2806ede645d33f432bc71a23ee09ad0e2484396a2b83e3eaf460627c424679df026c112456ecb3c1dce0aa9178c607ef7a534849a4f5ed1fa38902f3ff35bbb4c8e4ac7afc90f71294dda36bc44880bf5921e9df4c181885a15457222e3e224e1127d11e49fe82ad22c67ef4ad65b572ceb69a2d9aa7b964cccfb3903d2a2b698044bf29f69716ebbc807ba36a0c1110de66e6bb5f0efb16d06e9704c2f19084d07d5e949dbd84be33e9a0ba160f208e08f671c5bb49187e905dbb333164d27c20b2ec50525b560601a9d87b2d9b6a5432216ed8eef4bd9e5925233874bb83f7a8804bfcf4f82411f1be764ee94b1343ea07dd9d1da4c9c73410158f0e0b795dfdf71f7129993c97f729b52f8daa831c81d8d98deab3523a7db2ddc7d8a18c3a7a7fca94eac4b85e66db4c2f43e809b569190c5ca6a7409fbfbc0ffe59556e7d66cb74623a09ded8191fa98a1bdb54414d2be0f05293730abeb4f13cb34a76b4dd7f8f8a0072543bcc84477fc94a99e02ef76de0834786587d88ecc1e10949cc1b6e20486c4e9857e87e1cbfcb951985857596a124e63223658ca0203194a08b59e5c2fa03c4a8f297e88571b2128baa8e4b5466693a141b42e4ab7424fb6d41910fafc98e6ec568682ba3d7a0e15017e57718c4f24af85f2b4c018388228a15adf0485bf6b21b2fab7b7ab16994db5d401b2d73d472af503be946c1fda3bb6fea253d1f757ef8578f741548e1e5b9d6637e614e0987936fcd45d34fa108a8d472681a8f053332359f47a9293d29cd65bbe7eaa8b4442dfea3979503b46014a3111ae17bcae4728052269e8211ba935717c9efca0f9214ddc9f09159f7afebae8dd14f48370e99b10f", "65", 2, 1881656414, 0, "a1c13e151639c6b1871780b62f5d951f9480d785cca855f81c97536409210a5b"], + ["030000807082c403049add25b41d0769ae70e8b500fc4c0719fc6060c5ee85df8b8ce56e990bbbb43003000000086363536563535200ffffffff05791ddeb372c9e0eb0f86337d3e77ecbac88a45b50eebdaba633957b8cc122a01000000035200acffffffff6341d6adc609f1c9e2105320ae077d1fc224b4bfe326c81fe1e917ea23bdac7900000000005a2f44292025411691000874d3b2222bca6a5905c2f6c73cdae147dc1c61fa40de3230a6030000000563ac6a6a52ffffffff0189d3cb0100000000025365687df5662b19e4d800", "6a51006565", 3, -1823706795, 0, "ab1e14fde2fbc95af20358b6c0bb769a37e8f74edb0c2cba21b7f7485e893aac"], + ["56a913730161de8f060898900955a54b4932789a8a734f02b6734d6d87a3d62fc54618b00b010000000465ac6353ffffffff03fe3e3e04000000000565526a6a526f4fa003000000000300ac63ea66d10400000000025365adce68cf021758ca0000000000000000000000000051a91780b999ea9e881465853c95a5d24e1cf0312562730cfc696c50ae224310e28dafc6c11be449d0847232a582c119d935fd4e127e6e0bb54dba7e47c97cea2b5b1bd682b45b409e3d6453753c531110e09a5814f74b9360419f8855e69ecf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067bd35a1c1a8302831eb466a4fb6969c25cf55e246f7de897958d9bcc248e2ac71377969caac9f7ce1d22378dd62a0169ed590b0b110550c8cc454b4f45533a8ccebb2c30918573044a7e1fd82463c75e2ea3211ddfcd88fd5579347cbc515e67d0219e2c466b1f25935768793df269c898b58d37900b0cf29ad41eda89245b3020723335f0d565efdb7eb2d129f34824471817da66cb85ba780e51b318a42840602269e35b867bc8aaa8a2b7ca1c5a1154876433c1ce2d23414e91f41e0ad691aa70a009556a5cc9a7a3c3818d61df2cba1d7a742f10525e597e2c6c3c4456e46f93bc7d0d2182f03d28b6c4a8a117a28a0782d868119362e4be4a7ac90ed2ca2bb74020dc53f11692aaadfcdb08d58018b71c9f89f6f5a0f7ffe012152d094fb7aba20030237f92c03d7e498b47378341cd0617b1ee7ca730669379b850ee18cf64b880b0218bc0805e975ee49a82c15d681c3467fc092213acdb41c5dcc3bdc76ab046f2b020dacaf254356e6fb1118cac893776581ea22cd37dec33479efb230dd654c849c022859253bcb25da7964cf7d328e54b42b4505bd15fb96b6e5685080f30e6c821a5849467a880de181d8ab8429b59967b4a377b8b7da4c27c5a82181664416e30645ce6c15914f6f80d8853fd5b229710e0d267c8e2786d0600ed80e0171d867b1c16b54489aa35b9c5527cb20d4b42d34415887c2281af8da76f9c8a8463ce2ccbdaf4a719b10d56a35eb670a0a3ab15215dc78bfdcc78479530b24f23f71e83ac697a9e8f5a192fb62f60854332095b276ed3ee346d2c4d5971512411f851a013d08d9c9c749c557c5bb4c785a32c62088979b3bcde2648a076646adb9ee19b14910d334dfde7240128e0167eda2df36e937e0b73148063392909c26051448465c8620edda4c19260aeb8977c7a2828e7f31789b1be8a0329a4149754050ad0c3a4e80f6b5b28e253ff072183f89c651d202d349583f5dc96ace8cd4adf81f68d44e375c258652b7695d538e3cdcbebcfb988d78301e5ed540c4c1c670977b8a29433d87afa97d6b64a9f6f374a040ad904245324cacfae1322039573e41c6af5382ed8bf942cdda4cf2a3f113cf3ed72c222daf2674be969725a2030ee21196b97e91542a43bb4122109d0b62c4df18cabc844424b224c077e88b17a243bb5c726c15a2f2401fe4d28c2b0173fc5a9c4acc439ba00286ed875cb5f55e917dc9a5564e6b6b1af05a88fa79e02f9210bf3eba7ebcbe4ab80d660936965ef8a473bd96e4ab5385ddd0dd560399928427cc1951ed30c8af1a824d3feddfd2d70d910677edd411411e1a5d006b4f6daf701ff3410de116238741c862e9a112e46c55fd4f2085d0601ab76f04a188e67c92febf6e00f66b231c890f0eadc4d6cbf9f5ae1f635d0352d204212fb436a140fda358c83f586aab6eb7c48c15ef0817248b8104c91a8b4396aae5e42109bcda24179ad66f85611aca9c1fb86877f0f296e0556162d4b4be423298878cb38b2610535636d005065e78591ea8aa0f07b19bc79e91352034c7c5237dbb66a057ba45e88b84708cafb385e5116e2ba676f2c2cccb47c1cb5efae7a0c703058814e0b9b02d41e8d65c086999d1d3e7df108cfaa81a87bf674b743ffbd65adbda442ed7d42cf5222bef71ced5def6164f468fa2444978eca122dfd8cb6d6bd69ec2c3bbfdaeec436999e2424f317f158140de8f78393bfb61d6ab95f6373bbf548a718bbe4eb8f8becee71de470e500867d2b285c257266307a6e752794c3c7f5ff14559d7b127726ed01152ac1fc6681bb6299dc2cb51e22685b9ff31545ed1f374dc11f4556963b743ec67aa69094c67a2a839182c107faaf22743ff0a54fdfe6981c887ad844071c278b112d1aec575595ae856b4c3537a5fd62ad5106d42190cdd0df471fd71bb24b3846780896b4d268d94b6bfca78e2ca6e46eb68a872c85c68d24ca60e2af56ae74baf1efafdbc7892def6ca8d19de7708ff8c5e0ed5866c2ce2d1994432fb98f39276c1d06af57b8193ba5414040ef601e0b71820aa54f337ebba2de2b52e4ae6383b3fd44c7899fb64ce331a689251b12623975070e4ad78087991f704cf4075f9a16822083591ee671c234f648aebd17cb781417b640f7b05abaf26fceed9df9194a13dd054f7798fa1e388a33e47e0624cbdd1daa887fedd261bf4863c8c7c82ac164aef7557330f7fa13b8b9e256a9626ffb97bb8a09c9fb56de0052c018858bc86cfa2e484ed4943bee5b2157bd8ffa5f77c67f2e8cbeeb4804000000000000000062dfb8000000000074ec66939bc2b63c58b4b2fd6bb9e234d58f3321867f6eeeed315cce5f68b22ef8e09ec5fec3c71087d207d54c928118314e1af17ef4edef58cd7b7a58bbf1ddfdf4f1cca7767d46cc9d55a9cf7e2ea1b12095859e9577a8d536ff7416299776000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008fd387249db5d6697c5cd0195ecd370424fc50ddf4b831b3a8dc68de86f5576852920b6f41cadcae265c5da7978947883a21db36cf1cfa00057148ae6a5548dc4a6b5c51fa6a9edf4311b95a1e74035b692e330b2a4005003c8fb9e3809baf3a550f002f3f25ef28165243a0b48d31f30a832fbb0ba30dd631d85ef648b983c8022132d020713d1efc9ff442c40f1bf4eff1edbefffbfccfd15c57e183b007468502272aada235cf4c299fe961ecdd5259eb93d777a39d9f23a624516503f0c31fb80b01560f523ed0cd7ff552e4dcba12deffbbebf18a5010367a8dde62a02f0b818864194a634030ff4ed3326dfcbdc04a21e3c3b70d00f095f7aef6b811f2f5169e031a9e7bb731d0432963726f0a44f8b5f6f9bd869ffc28641d62573e06276f85c0032bd8db51f6937b83e4912a9cb097a887eafe7acd537c2af41e2707b831244ac5021714643437fd33363dfa90a38f6b11257d161ef5d649db238bf0a7fac0030f4d03280bbfc84b62447390d8539728e007092ff5a39abdb01e409fe80c9bdfbcbcda032ad87b0934ed2fb2b40933dc31e03ba88825a4d52ba24349979a253cb5a7e3f09ab130d046c5987301903440ef655fc24cf30e5091dfb56e351b778a501244a4d4d5b8b865e88326d5d68d15a98b211639cd7953cd5b3e8d03b795da1a874dee8f5f4b694fb248b6de75d02169ba5e04de5cf6c9fa6d2adb5d13ace1b84c6297a57a724acd787ca30ec10980b2e1dee0979eb2d5dbf34d67894781d11753c7ae6a909f831bf48efae27dc5adee9680959b561c75b4c733c74aa716c34507447635063cbf123ad445b47e9795a1847ffcdc0c922f4388168fdb74c091f14ecc6bbadd938fdaa6097157c0ba9477491040321de2d8df1538d8ecf6c590bfcb5f047ec05ae8080e0ab19267109fd21e21f000632722131392720f6cb2356c6b59879653af5f1db5d127f3f5369c900e792112b6b2cab9a27feeb049b585af43497e54cb22def39475eed38b9f2d6d14e372a3b41b661851812e63c1dd6b0684a9e54f6b07c0210dca7334e1cd6adc864a0d71a796f2fcbf218d6448c3af39f1fb97be3afe59086b52589ae365a1f5aae95abcc9ef4998c79c7d0a4e2857a7d150c5a5ea4bd430fd73f9ee4d18977a49eff427f73cc1e368eec6b2bedd9794872fac1532bec118ae9e4adef95b54331a80da4e8dcc83a2c90c31cc25485e6250bc7164dcc0dd73709ff63e6edda38d61e1a95362420225489726ba69b8ef59959dec5f2143e058ac8a6aff1fa63ecf3cf349886eefcc5ac90228b82034d3fe0dbd38c0a643f83f859fa0695418684845478d111e8d8bc1273c750f0e5c96863dea07b5f4b4ab9218a79f1b90cab3f83178d89f9a30dea553a490540e9362b89c5b2b3a6e03c67b52874ea8dbb972ed96d432ae80135421446ca6dea73ec19009bce8f5c225b48a1ce65da6dbcc216a1b126ad620f946c692dd280d859b92dd2bc173f362cb367ea662b3e4212a629584ec8963528ffe6120fcf3db5447fff1a282192cf9e65bace5e935939fb599e52d9c80aa834a8bff59989aea78aaeeb915d5f1a0bb371460d60e96210d3507d5412648f163ffe42406ee3d36fa088508a6053fd96e57b90d2f1c9c3c7e970f1395a7f0a5c9114403ad1fb9fe84eee8e46ea957290747ac509b348e952035490489cf02d8f16b9b717808a028dd5f611b7e7fd6ad0d18f0b2f2085089503517d4eb592491f5f41773fe45e1252b79eb472d9d4e261a10d5920314919de4f460252abfa612cecccd52afcbe7e029b4e70c1fe89e3eb8c875696d39002a0a8f25a5d9b98e7063b7ed445b67bbe5812c5b8111bb139ef43076ded10c201b126e642241b33036e9614baa38049ae3f7abfed2879affcb8931b3b9132708ad7d25f46d7d0a9a115085b1092134ce84ec208ce05d9822f3aa87edf2810ac56b188f558f97065191afe533bf331c66d802bd8f97ad26163c45225c2c06a75bcbd8e54020c402c2827255b9a335d1f0bdd2776f8e732b87eab85caf9e8d0681f81ff0b37408284ef898f2a0f22751dd998e8e60c14f62655de74dc6077b8e97e4970e11734d3db8261bc07cc23856b717fa99dd3f18f6d05c30caa395078db6cfeae8ff2d79600102c09a127b5fdc128cde6d0b979eb48fd7102dc538be64ce28d33863339b6f1ed97acc876c9e4d5083412ca68843082b3ff5821085f14c8ee297c24244db23a29892bdc80a72ce0710c5dd1d77ad42840341f65c105e744ba39ab86eed6f84f3edc3cfc4ca4b4b41f63407f5d8160724aba9dbde4f718c164da404d4a6c82d12c3a1f289836f16f66e2c4ebb76dc312de8d6a92e949e675cde2a8b0e2e4c3efebf691d873446df6433afb3060bea5bc58cac9a53d39057cdcca341395ebb711e1500", "6a00526363", 0, -19753095, 1537743641, "e9345b013c00465362a8395223779212b2e2688869c43e80af20c9cfac156d10"], + ["fc9a062f023ce41e360a245308db283bc49b381bfa73c8cb26f9bedf26dba01a80591e177803000000085151525265656552fffffffffe1985637bb5d9c4150754f496c0f327a3498ade44d54ecaf0e13148d38b46b501000000055165535351ffffffff02e9cd6d0400000000076500ac52656300af1d230300000000016300000000030000000000000000ab082401000000001d6e1f578e911d972f70b8c1a787ac5ca6e85e4a81e279772d387ce2b185bf02a82c2005f08e07a547e5afc77339fc1513ebeb3e67d396826091d19bc9b6cd4d796311351ea41b71738666079544893d29cbd1e2486e02a2d4d421baeb033c0d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076ac90d3e4927e69cf3711dc8226f62b2f68515b62daa08b97b4c3de9c287be239f15da0b3b9e6d07d5fe8b741435177e9a6656754b569a33f3b35d4ab5d292706920ef4e51526d0d7d785da417a1a01b1fc08fe77dbb5e702d3b2f0f1ee356526c62257993ce8717c35cda6d9f1b53e9c5c433c12f1e726f5e5c7f0ea0cd20e0203bf18289c312f986c66217eb143c60e43bbf54c98c21406ef273f85b801d9b7031928855e53c6a65dd2427c98f29c9ba931375338f43f535fe16c91114a7812b90a00eb311341135cf70417d99b10f6bcc10f58c3147fc8f0f4c708905bfd69a5166e9cb8ea54ca745cf1852e64477d221d47736d3a206c3983d435626c7c1fa055030c0abf3e4219fcd72de754ed4f2297aa27936e89f69fd2c38dce99a2fd62e974020b70ab2be37bbfc9905caab927a51c4d7f12a1a7843fedb9c8fd35259afd1dd00324c210f10107e5e99875e0337c2f15c1111f1c980b656dcc2d7c3a5a3c477b5c021ec7c9dc9f7da6857cf228a3f47fc8114f75a4956c34818daa5c9311e91c870d030dfe16ded4c85f0fad81a243780b6c5bc46c89852df7df3b614d1a749fa44880069652750a75aacd0a1eaf52ef2e4d83ec69416886c1e120d92df904677c1cebc05450ac50c4b72c7e6c86e6b2663e14d1a255758c3487ef7dfc22791add3e3c9593c86646e07f7dcfc035f7850a9e53eb76e9f9b14e5299ae5acded5750a40bbeaf5aced7f27e9a4b9de3bf3aa6e49adff9163f8c5dda23bac0e39709fbabd757e4b85feb7d6709eb3214be98cb07cbfa5f0881d6509ac740fc38c98a5df46f14353b205fbd449f13b00892083087be073bc589ed5d47ca2056793c13fa1b96d9d607c3d5fab2f4742870431568363f36a5c19a3cfcc3998543250cc37c284e8111928fbc7a6be359534298fdc99957d8774e306efa019ba0c07ac34df1aeea46e8b38eedbd2849b68badd55beba57aebbf64958b12b1241fbfe4bee090a44687a75f4f81b7156e16f33805c25003769066b87e05078af49e1863e773cab22a596436c822f92d631dc082157988d3efa308a1730b673912354a8e63df6bafec1e459ac773fe293fa40a70ad392790230ed96ffe25ae68205eb5f691c40d56cffeee18e8ddf3a668920933a44af73776568eb954dfa6142bdff9f63e6eb9b8ed2ff4427fced22fa8537dc370e840d10734a0a6f6a47e6607f3f272f6d6f714227ef3ff2d76d679ae96a83ecdce90b6819fa21cc1c203bec2a01118f82673d0f14bcc15c8516264ef1270aa8c72988483aecdb1aec388e29dce6fbf4e93c588a782f3c1a64b49ed326c9b1c548049124212185f865212540a7e4c867885bf1e95147d3585f57644e8e94844f597d349ecf217542ad45b8045434b2c11d1e3eeb965427abac6efd756a2eb58cc45b8e4de557de383d41ca1c0c01d82f400e36d29e17bb7019b3ceb4863003eb9948d85513f634abbeb735d60c757d15105ab6d8785efea2a56015eeee5df8b63c0b3d9dccfa895f5e7464632daafa6addb44874c968f4c26e705f22bb98ac6038770e324b72ee644e34341729b871e76b38d86b1c6642c44a95a44d907e15c7df1743efed81d8858dbbd717c546d07c4bcc825b32906e5cd3cb690bc38d3399df163fe6cdf8ce2ae6200afe614b6dc00856d817f843899d987f592100b65d18640e993b714d3a462b571437810daaf3c89713f4046718ceb86aaacc487d3791548b91e9e44d84c59eadbb289b3894e8badcc976884ac756c8fbf146d45e8162edeac0ed37476035ef611a237cd256a2c2bb8750b90c04ec3971750b09caaf62384c823fdf2e267039222de16be87a6b77076ee653db432b27a70b1f97851d58cb97549b735f67d38750948e9ffe9c2b5dbfb9dac20877756ddcde91bcbe86f6085ac2e80b92da05bc917f3d47f80756f84787f707ae8870efbfdea0e194f02593e1f11120d7132df76d67487b533361f898251bfdec92b9f7c514ef7bed7b92e6ca755d573b10c60fd4e3929375cc3e64cc7ec5cceb092d5e9208a0355cf895bd2fe70f24a82864ee5ec1cab816744edcc4ab1bc1baecd3bbd66d00094c2c578e8d666f1bf76ddbc89da9a137d1c6ec52c956a36281954dd40a6da783ff2489e6b2e933d1fde844427ed850e663cd8669e8ff0e097571c32a1edf7804b0fb483a5a0cd1575665a5369d5d06dcfc7ee3836056e1221c53620c228748eb49b8183516f34f735b8d20d4ffde3037d1e5eece5b56b2f736118753cac3402bc2028e14ac3ebe3dfa90000000000000000d8de8c04000000007437519bf188dffb94f47ef16d2d0a12921ca6a427422d51654f9417c179fedd1395dbd1f2cc3b2cef9521cf855e826ef2a260fd47d4b4b7224153fcbceea57e9b2008d612d21dcdb07dc348e4c3997d3a4bd0eb63619aa93bbe38b7a391d25600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340ec0633466241331a1bc6e83e175f6e0c7d4e8e09433a3100c31f264983f937436d578ffc651375198acd0d0089a81e6369ddf892693e44c0bcbac95ae739be712c764f5ba67ee4ddaee7fac5f952d5f015aedbf2a103f43f95f833470d1bcedd1ea1cb0a56480fe6b87772d1a6f9dd56f3eecceda9fffde32ec07aed798f4021f29752a25958f0eb4bff3b48daa3dfb4f6c803c43b6bc222d842f793985262b0306bc988fa77825108cf91e482f93ae34ca1931f5a0c2af661580ef6a421de5ae0b05d1c25ed87dd1466499f5969696bc2648ab2395227aa1fd5a6e97f1c0b24cfeecc8ca629b6c76425ddd42c03584d27ce4ca0d6abad995d366e6650d54ddefcf020f4ce51ef992d15f78d1d97ac0096b28bfac60edee075de3121d67fdb8adc9d9031dab93ef2c9dd38dd2a347587e9490c5f53d3154e746a82c1128b43a054333a3031cf7f02de38eafe8fcddbbd6b61f65b8d1c82ca8318fa0564795ad4290c46833031c567ea21e8042658897a6f07a3f0271d77351e5e1d6be0a02db1684ddf1c8e0020e17a5d78a4153f5d0d2f5df4281850f538a580d687dad5666ddbd02ac139268bf801fbb194247d13f43337bd69eb89f04d9e5551cc92e8fb0fd04636af0358534a4f5f6605bbcb6c9925b4fd3387f0fbacd071d258b41db4133d876452356553768125e42f0751e56f2774a9a37b7931c03b289d678551f6226fceac8c22e09973ccdf9b21dea6a19613a89f7f63377dab9bbb9f0c9e0719206daf2d9285d6d9a0f272c59ad5f123a8c4361911d670301c64d0b96f3f01d753bd2ee70dc359bd4bf34f85dbe3e9eaf1c6c7b5e0bb88adf6b8d13802d3307ba0d5015c9f1ab6158aa70d77d214dd959356762dafdf8bca3878100d0b9308759dbc1ad1894f23400cd48d3de4c7d68ff9360deca2d01a6712f22c2f7a963526b8a2e5f2bc004615ac474abe0568363247c35c6cdefe2775124565276c1ce748ffd819c1c3d5a3cc839eab3fe5d517cd39199604a4fd3b0a35c6c6023000a8c50d0af4c57aee282ef8368d711437a0989ab3ccbb607625494b0951ab14420fa5c31a7629077fea89349bf589b10b068d6ac72e3cd6e0110eb70463b4a3da6194de6d803fcb1f7f74d13c4660c0e77f3136140b8358ebd586f9c159b590c776594ddc03be0a819a46874d229f8dcf8346ceff3560f5697c8d92cebc974aaa45d6c1c51b14a5d723b82a3ff35322c29d32220cb549fb0efba2f821dee36973c5a2d0119afbc934004b943dd1b265fb9676f279e4b28b1875a71efe9da7695fd343ba06d4a5e6ef088721c72d3312920da4d6b77e340a833d957c5143afa92949f317b399b8eee260de59e83fd4b1c53c79a28a23c10557fa84693c95a2d3ce4c1ca69c5652e32104b696a843c9a7b4b9cbabd1498dd6fcc16b9cc18c3e23d6ce398e8e87afb6a8dc3efa1a60f5e7dffd1bd289419ea2fe66229e0ac41b7d77278ebcbe193c0d763be93bddd5928c23e3292c172d595edb8bdd4a2fcd13dc887f19d18b3b6177c6c9d82d3d5a4214e393f6085a7f3bf808c144973c1388881951b982dcbf9c7c043bb7d3cb04c701bf5bc3761a1cfb32fedf99b17f851d03d77ccf1bb9f5e66ce25e435f3532f86c241cb0c363330213acbd132b9312a340bccb0351fd1edca5ac5cdd6851548802c287a421189eb482da16edce94e812227dd81cf6632c39a0b2fbc8380bc39a9cccae1e4b9199543761490b02d7850cd08ef72c56127000b34628f02616ad95cca771355d9c733c7c9c98d2bf2b96278ac6aca19fdde8ce0832f9437f1e3cc0185626488607ce150776e2a9354b82633fceefa211dedcf2d668632a025bd739525baa4506b24330a864f196e99724076507587e5a35f2b8103dcbc958fa69fd4da0781db63d245483feb7353e31b85918e548f41c6610d1edf3ff136629f1a6a0abb243b2e2de926a43267e8a7f3b0ebf41fa08cce5613d8ed168783f00b1614f40f7a6647c2ab7537a4b95ac1c65163ceda2e9c7e847df628758e8a1a270280806d81c60dcfbb78556ea2b583f9c1569df77a91298d30620c48b1f83fd87c5e7480e47c0a691d427dc8f9126d5388ab135128330ba4807d64716e98dca0b661681b3aca1ec069cdebbde58f09d6f77c5d21095240018063425d053347f10b0de0ae1fc6b053f0ad6a14dc2550386d65f66bf83cf396c2424bb723d42c1fb74307d63114d44a81f576a31a7e0e3fdd97cebf7f388c346181d3e0b61d71759ba544829229a3b3610ed5788317210000000000000000eedda40000000000b64af53cd3cbea06dbd30034c1a45d06fc4ddd1855bc253f39b5119e8e6a4a7d55cd80bbfccfadc53754b65573366b986c3e0d02fcf82c241372cffe29dba36c665d2560b86b2b73fd872afbfd9365db8bb152b5cf4e1aa802fcf18aa549984b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008945b32867f86fdba8ad457cd0c1f061c1eed1dd52d6cce440024fa70220ab87c2dd97e9ac79e8ababa1fabeaaf74c6d3868747a1d3279c3b656832f31da2666b117807378d66ba830f398924a47531f4bdc7815685b597065d0344d41eb1b9b87ec06da982854ba2797a6e79d47b910e2e8679eaccf83d79af35ea42af075b6032f9a408f882cc11f39803e8b9426c3074819c7f61f906a6b9f517ceffb9a004203248c0a3e1f1ae3fd4b4a522394e2136df2b73b14b1ff56e92960e9cb6cf89db80b06a018d4e7f46c77e5d0576a5418b1db9ef815e9b13c304514423bc0d7e0574adef50c44fe8a3d36c352f4010a346979688f10c31ad5cc1917364c53aab4374c030cbcfefbbd59269619fcd0465a19d1297f4dbfd5f4f8d4d0fe0b72b3c1db3a650211512e4883767432b2152b6fa524a4057e2b569d40f3a51508b5be4d8f6f265f0228882e255b2f72e1d0f012c654778a97cb8c513b48f21cfee15c41ebf1bab1010205b1e68f907ea67662cc17f5408a46dd2c23c1f76b3533e715e72acbf574ea850313b18c5dce2f332fac022a9ee7b4bf57e4913f424e3d9f02fb6bae4d56af3fe56f57f0a461b1b51aa7363861765cfa1bc8415e4f9ecc6bc9bce0ccac3c41fa4d5490138aa2450095dfe0ff05d80a5c2a03a232bd4682e5132700d9a0aed6b15bfd15485dcebf077ad69941872a39c107520dedfe64a66a12fe08aeae44a1d9538a930496df9078fbd8788f82337026cf6c48aaa6c1321dafff73702022bb10ce2fe3670ea989a148f22d9dddfbea0faa6768e113988da527ca1608359bd09e957ff346dc9d0a97945b2a1b280db2b69f28e91b6dbf92d919bf08a3095014853a6e451ddc4340bb5b79c78759b9e74289192890efcfb08eef8eea1af4c2752fc3e6a3d3ba7e587d64a79bc643d33ff8e2a192aced2465800cee6b84ef92364f0a303261d059b9bc0de0c9b7a7bbdc0dbadbb395e7b5adac447c88a01844cfdf9a52b98cb3755493faaca012948a940ac581569a2aaf24899c88f2ce9faf375155c77e72c26badfe3d2a07820a670e3402450404586312f0866bba5e1c87dd33a4cb16125d0ed60aa105cc1f97277d31d98c839bf55e4fb412c055d9829be112679274507b83aca6eb7bf5967afbd5ae935c2196775050440c7d1c93873e31c4dc3f2a961cc2335cf23047163dfa2118b7e1d0b436e0353bc62bd70092536c6fc70ae9e4ff4f254b712109127d1fc7be78231913070ea8c1eaac8eb8bd6710f6f0aad32913f2b80a526a1b0054668356ea439f920287755fa3fe1e9481383cecdfb8a1b5040937b5cca65577b4a3722fe6dc96e74e9990d07f1ff60b4a097487436e730ad710794d38551a630ffa0b8369b21530b39e7e95fc3b1becf99f15ce10c43476fb12286fac0ba27721a4ded4c47d8c81eee4a4a50ff3bb7562067d0024dd8f59c942d328bb5dcb2a9e0251542ddadaa5c647aac0f212403a17264c8c5d5551f27222e232c1972be4a057ce583601cc506ee00d32899ba6b3dc147ebb34b4417857934fddf472544d2283e2924e574f04b46957175c7fd54771067b7c7b1e5cbb363ac3841dbf83a9d79a5b9d566b7143c6dae495bdd821cfc27bd357730e7b020fe095fed52281ec84d12b5e058ec16824e2c8e397667868f1a49384ffae8cae75596c687dc80a9617c974b88f1953234b2530cec459bcef8b1aae31ab8fc9c25ff6bd7645dfd19444a7ea4c8fc385d1f04d28d90b86be86e466e69304aee36c4a30e9161e1175fb771772c2fb864c847771a7d6948a08edadcae6751662eeb92b863ea11036122bea3e81160ff54d96323d92e47d63e88c2263ec26e9ca9774df845ed1913868a94991034c83bcc35ac2231855ecc4bfd23e77d1216ccaae6294e3b8c490decbd9ac1279fe0b4f9729a2a08e8de017ddf9bec5469849a21abe4e031d6f22cb69ea26b14e97a1c2b370e93dc9e7fbb0bfaaf7c619efa41cfc25189ff40dcf3dfde04f80b57ceeeae2f2b3ba6c71c7e636301033fb49e86ba4cf92da2f1f33d6522d26bc9fb7a159ecebc135e1c3826f4586208bbf83408a3b2f28bfad37f4dc04505e7990f3b4382d773610232bae73a694bcf9a257b70b99cfa91fb5e3569cfca1041c3762275404a72bd8c80ebc19fd8cf8c8c38b207bb53611da1e68a5e59bee953b4a2aaedde41de89a0b1314ed8e14de31ea735d9cdd754f6a9307742ce284ca3cff616f7223c0a6dc8b1a8bba68202fba2a6db5f2bd5780fd96818095996cbd9268a7e213efc2b4e6c950e6e8ec972f3570db227995f2ce65db57574ba35b7f273e45f5b6103b11fd1b8bb3ca427bbe75931064d79b92312060a29823dd45523134f50cb1c6df2b507e302ed9ea48115e36f8ef6b61989fac147ac5626de90c5d25d0d93803", "635251535253", 1, 79634240, 1537743641, "64e805ee7db6678ff53d0ec444e1cc1555cc2ee5f4ac5bc753edebc014078bf4"], + ["3379ec270157cc12778d39967f82698e53a65af9481a1e28bd29b15af8a7da81b2ed79dfca030000000163ffffffff0201bca2020000000003536a00b17ecb0200000000075352656a65520061c9d76402fa59de000000000000000000000000009c516710862f930ffebc267542a9b159358f2e46f392bb65ea6d7978ecd5dd150acb09d37f0b6960f64dde216cc548912f2a1e769d22850b2410fc8f12b50f622fd913495e618d77fd4025b99da1cb919fb819d4c6618d6d00d79c8d2d896a9500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c992cc2b235e32e4c89e4de42c4665c65bf8f9e46d837d1ebc1a65b93a507dbeaa3111e0984170c99943328cf772b8a23b2ea1e1daae746704702e7e674441280be9f188710be0c408fd94ef2a26d8f3f5c223b0265bbe7507e1f8c5f1c9226fa41121828d8506b1242f25a50832318b3bf98fbdd4d200e70adf1c5202d7c12302219616aabfee9c5ec8d0522b5db87d07fd1f59b83e6741d579c5f0573a417a9f0206035e9ea0848d8d26320bb19eae9a347d71bebbcd2902a28ded5f38ad265f170a063b95003dba0f8d7fe526bb6d64ac45717ddf0453f9898bfcc99eccefd6f362b5719a1c4aee111ecced26df8d2430d28fa85fa02be3f6c34d990c3c87243496021eb6b7d94127347df2991c3fa58c3526e961f06c97f9d778eec10f238008c3f60322103a2426ab147684870472ce9e385176cb0955332d71556a74948244001412020690d500231219dc98ebc020f248001a463decdda420aad66b1b9a861f84adee021d4e2f49f4c3ab5ed2abab9234a75e3e067d7dfaaeeabade38da6bc635cb38e60209d3c1bdc1ca101a68f322bf08f634d428f8cb582395bbe5e9077ef542e015b1e82b20048415f4aed89dc1e9a3b330b3c1acb1e13f078a137fbd8261c6fec434a050001d7fc906c6af880ee8ed551c1d2f8290cf849407ee7c44f3e5cc09a92c2bc1f4dacaa7a5969133529cbf716da49a7755c8636116a36b7343b1cde239b099f48afd8308649ca45fadf155e6dff1cd4d792fdfea888b4ea981f229fc95cab23fb286d276ae1940322e67bac6d5f4e147df2228c532290024b7970dd077dd7af87f4bd41982cde99941e18c57e08227053c9b4ad8db7d0e9ad382903b8bad3b68c642de6b0e19e02d0507ccf5649c7892cf3d59991530017e8196f49524d9e61cce4efe698eb17508689f4b807d093f72fd2ea29cb58a9136a592f6b78a8e4f8c3fe96269b5db31abaa4c574c84925a53eee7d2b44e0ae978542f3af1c39408dc2cfd8c6ea2d392f847f0aae1b5d848b5e62701f55a0135150ebf9ba106a608436e7ffb4fab981a9f4e384628fa782f939d69ca0a821ad985ffb11fa5b8ec0e7c9f5feb8cfae3dc8c6d661d5e9978155d9e6871fb0e834e57294fe702e7edc5e72af05f7d05e7b4fd1ee5b1862963a0474cef93d6d8f549b0f2fa185de716f26e9fab13faf4be6ef9538c02b7c84ca9fa96b63364079e98249a911c5d59803a64e1ed2ac592aec9ded3f7d3e899d95bd09b7a2b09c5bdce44d56f68d12ddf1debb39f8b0be07550cc29c55b1334d51538a5099491817293a36196de92574d8dc472b0cd517ed7cab52eef2301ec173e601bc5f292b2d4839a43e1c8dacc264c9eab5c0eeae7df491bfda904213747ae823640a4622d8c9cd70a9ecb8b29426b96c8222ceb6a0943afc3436e61c3d63d75b85c325b6f05809f7c06542d782affa3fd0ea6ba7e90ef0d9cc5a54362ca6fcdc651600b6f9f2b53c02a2ea98a94492033d0cff8e3bba8cd3adf0df8621f2b3f45ac18441b00a7e43648ad3a3dbc2d6ef3fb39e81409e8b77019cb5ad24b270d9d60195df6c184c909956e027889dd8947472a820b1ab7c79accdc1682ef6d647e9839d51c989c5180308cc38ee1f4c45b17212c599e8b11f9b2eb926975bc5444aff364d514a867b2aaaf42cee57151d14e0f4227763ee3d250ad9de690dfd2bb66e40d3a87bf896779db9661cb727cd044108c7536d8632c15ed106b7bc8ccceac5155bba64e1085e1c4584786fed5124450bd390e4e49d55a5ac3ba047f8be03b933e6cae632841ba095115ee14a51d1e7ca698655d09e40d6ed6ccfa3f35eb7411db46e214bde351565fd883896ff4ba096c8cba25dc8ff5925021046069dcb513e6628704eaf203966184793acfa81ea9659a8b0d82a4ad64196770ad79cb6cd88b338e800c951de33348eded31d9a090b71834e29c098112895ad24445e4f6ac174833ce690e38ef931b9600b1f89fbdbebaffeeed72b88c72662bc6adf1f85f2f0599064000a8164d7ad85f64733c530b923d3342fa13555207843902a977b55bd0e3181e2757942f1e6cca23d97c05b43e056e0e4538a75e650f5e0625463b803f1cd8da18c27b1e4e7629c6ab5b3631dc9ef3d8514ecfeb99f534e4f4b1e8dcc1506a3d81906f90bdfeb5caacf39f929025360545a68844dd700a7e0df6b210e95a59e5e17dae80927670ede3edccd6f152acad9d46dfb56a079f7fb08677cfcca6e879ddaf1900f272b923955586d11a6e6922c623e2bcc2d2a07c0000000000000000fd22800300000000c0039416b34adf2b514329c66a8095debe583f1cbccd1fc20c849791f3359f6724aef36bb0f5283c558c3fe961e461d89d5e9df6479aee3c19cd26eb73fdd2e040e65cbf9bde5be859c97fcd1e7a3f26fcaf4282dd5471b1c9a1f1ee98463c8e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098ee27df6a54e4591f440b3b95c06e8a87efa7d095d930a8a2d96ecf42f2dae03f6675f04f247fb76414461ece5638ac897ce74354722e50e2bf845d860bb902af600d3f4063be4b163409319bf7faf0eb733e9bb9bc9900b404e694668517a369ce0e321007452efcb30f5dc926af959625db41b1176804c3d35f34dbcd708003290b71f4c6eeec67147c001b63546edac5d8e40b21c0d3101de97f72a4d6b7da03278661673a867a00b66c661c3d0b8770ec9afb93973870fb16a25d86aef332ed0b00505de9491440ccc6bf8ea77eaf69fe21dd0f237502be6d2ee0f40866e9fc9dd7237d1925898bb7c7b8389c263b9ed56bf828f7c07d1017a60ea0676dc4f61e032a2889eaacbbe20a8cc17a14cdbd4e980d7c87b9e1a39f43f69fb546eb45ca410220de0493a2f57aa7891a04ad3ce7657917862203ac0ec02aaf291b71a063f20403165a6b688762c6b42d9aad0d93030cd8564b4ad24f39f2a835730006301be82c0210aaab6fb99f0e0ae7a8f469fa0630d09845b09a6607f6a15347406df1694893022d6a7a69e0f3987b7568eab424f431484508bcb427de1d08d3998614380a7c14c44db67384fe74431a1e39c50f89dd7427ae022e783166fd1efce5778250e6952b06a30b6285cc0730299adaa4933d12e6d0ab589c3ea80e7ecaaaeda82a98843e9aac3ed45598979aab1e7b6627540482010d2378dd6856bd34969344faeda375782d6660651121c64c9c0587aa1dfafef00b600b2acdc4ddaea336a1998a79af12db928ad1741fe7738b00de56cf687013b179d4ede82591f1e52bb5e35d1965c21e78c75fb584101e2eee3a20f34816014b0437da009858b808a798fe77ed904ef0536dc2eb21a56090b882aca1cfcf7e89716baee463396653ddccd1bd28e96c720072c81ae7ea2b6ea6868c739aa6059541683d28d178a575fb08bf8bf1a8f638017f64baf0a1557d3356369037106ddde92bdb9374094cd9f15e4d5d6d2079fa12644b55bac1f67ea0b097664894c486ddf7965462d0b03cc9a6cbd49ad2881c4fa438f7867f347e11c81bdcf22efa4e41171c3106c28aec0e53c66ea6c21f7cb2373b8b06d2706f51e4c11b5256a9d6a80baa924c655cc6c8ecbc39f01ef9976802f5d9b7bdf5d4e1230df58f7cf5ba14e2f15a744ffb39441b6a2a8bc25c57caf9506866b66a2e0a061addd12b6a696ba50cc6c1a4d9e3fa4f05317508717c796a2857892f0738ab88afdef4dff1705ca87121c309aa340a10aa6052d728b738486cbffc89ce962093363e1fcf2fa912777a1c63d34049a18615517e0aa23fcbc0560d0971641b9e5514f81933a7443e44e6dbb2034803ec62d43a840a7b9ec4df1ee3a94102664d970deac2fdf16402a4327d2c63cc2cb3547cfb60d3e4f145ab3b6981e25b024eaf95697d6aca23ad53e4fc07f3c4708259cd39cd110997bb60fe17e72aebeaa16fbb8d41cf9758bf4ad7da98a9ebc8ec26fada19180452134d3a02e928fb9c535cbf94df606422773eef01f96af7b39ada6e8f446db73325c3b9831df2c442c17b656243a85972af6af9b1bd61621049c00af3984a3ccdd858c92e6f49e6e6a40932c83457f95850e6c5d3ffc6f33e6796ce7a05181f88bf196b5dc34e064fb3dad2969c5a94e047a6981284f48879dad1d4e0888573a2631cf79528a1658ffb52fc87c8aeb90d73557440ae9dcd05f36376448a6ceb36fe64f4e5fee7271e07fd99a0f23ca5b52fb7b47c7155ae3756f6088a2851b40f263b531a413f5ba8456f0017faba2a4363108e754c956efc314c6c61d231164879cce469fa3728df935c364c2ff0c0fd77a4c0e21d4d000af31e88a0c50cd46ea67ed716609bdc8d060866a0673c6362ce46c6596a655c681b3d3adf5236ab2a58b3df8ec52a1cf291372c8fcc65ac003fd0a667376936d541290abae24ab996db0ae07dcf63f105713a02c6ae926284be2907f669e4e299bc0d006ecb69db2df3301135fa60c6c8d0615ce72605287542a81d6a24fd58463712d9d2930e237059b7e95c896425f7b70efa059f0046e0e3502727de63d3766007e06545ad7727026e77d0bc2385bb229ffb15b5ae264d406fb3971e32d7e73792d4eb5653f2f2949d3229976ff39cead98702b16dda27d3fde13452fd78e31dbdd9f47645c140819aa5912fe42d15196e54cb7b5a0a6180dc778a384fc19a58b088c2a9407d291431597766ef9d5e8d99c47b926d90545591b4fca3a50b9f7711934133653597e764e158ae2a4dc50aaf735e6cd14e2e29db932314becda4805796cfea1bcdaaa1f0a0d130a8b121f5e967f4ba61ffc334463db3f5e1000424793e033422f6f3f620404495c3fcd3a8ee896f9bfa3c8b4cda4c19f4ca4a6ab0a49f64cbc46a981b3acdebb678788b9eacf337277803", "515253520052ac", 0, -333550652, 1537743641, "928b94c4edb9482569c911012e307554755e398b0bc5d772b0f8a21f13c696d9"], + ["139dc5020260caf5d8ea2ec7a469de3da44455c03fd9cd21d730ba8038a22b8063419e52de0200000000ffffffff5ed76cabe76d825d11e48288ae33d2049686bcd6fd8d35eb533fbf00c136280302000000076a656a0051656aa4bddc150312c1cb03000000000251524c91b7000000000004ac5300526a0ff7020000000003635352000000000100000000000000005ff14401000000003ce1e7bf175ee60c8add5796d1849833343452e9da1b7909d6071a0b1bb06c1b7b33e2de2a6aa1b40fc542aca7edec4b8ab6f30fe7aca91db87fc1889643c3c65ad60ce06479359740e8c7b1a1afc8b6fea097a746d4272afc504c58834e6b9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b1ac537f54d1d1219dfff89308b0a50c501a53ab88610fe3b522f12a614716dbd4b01cfd621dd5756b5b81c3fa6cdb1db817ff49903277002c9f4e2e5f0e7e54b65734df110db5dc2e6df0be47f9b9129994458e6915c80d704853e203bffff3133975efbb49ab5709de7f19625f7343cc0ca6e36b1049477bc8ef6347227031517b75c28fb09d02f5cf81a30f7a16dd44aa81b63071495bae6c326b52bd4a203084e5362d09811f5e97baca2808df414c28589eff7c54169f683860cd74bf7130b082ecf71d5ff9a7a6489522e1d51ff0a9851875648b67dfc5f7a611f5732489410335778be86b568c7306cb453d284c6c50c3effebed5f0954567246c0f0b093032c2476f18df17c71a5b8f479da59d6ad8c1297f87f169f75e497524be769181b032af5e9cdceaad203a77a61da84e7142649251c9825bdec6a7eb379f4babbf663031f737a2d2240aae08f36097f1aad09103b7ac76d1e6278a2561210fb8377c2dd032468e1a1ae1c9f0f7688f065dc7492beb385c326cdd21b91e841037a370968e1031f10f158801a527b7ac0e8e69e6a40cc7fe6054799239595fe1bc4c73e36c172cec0d1003ac9f4d93f81349639e36f5df808f4f12a0d5d00f98b698ac2b2b4c5791e6db4e4f18be656fbc13c7f28759697f747668b1628bacbf15ca4bbe84af34bdeba0c6c48327742c49f67adcee3d5107914a48d86bf392f7b32c8073f60557daa872d9b6a170b3c5457425e5719b2cc78586f6a012dd043b07f7232732fef84e8de907901ad17d226ae709ecfa2f81b34ed1aa481697b5459df4c4a6a3616290c35ca73ca2811e55e1726e62c273f954a9b3ad71114d7943a80230bfcfc739512c51082b99d03e50e8e7d80b4d06cf1d185ebd4212850debaf77a6c967665d09f6ada20c43a4569b86c5ad6c23cbdcb6886fb113e9d7093f13d7b23e13edde1e15928bc5086ad3e5dd2413a721a989dcde97d41b4e801ddb867af46a6a46075ba14002a9e22dc77701712ff69e17da831577f539bf9e209ae6acf0986c845e6085459f0c187dc7dcb9d670f6a5c5a9347840e6f9ee87cd0be64ef749cf1bd2c181f25a27361f56e20928371f319c344d006f27e4f7b2be0b48c7d3a1b578579668d7252380866587cbf5548dc2d2c5a284f90cd48511cf18acf4519627e3a4a04ef612cb18181d4018eae847f6bd5398b1debaa1ec300e20d4370e1075d3f43b8b608fb7e9c09b4316fcc4374b2ecaa05f5eea3b1b02db2042f28cb239729422a1998e9fe4e064930259a5bdc785d9170f554a73a056b34e2f920fead872b0d16349ceeaafa486ec443377e6c0966e24e47f5527dcb771d86b1abdc6facffad4e189c43d5ff891421e0e07ccd58e37899a12de818cc0b4a9a73cfa81a88b57b0b16c5c3c71fb79afcbfa8afa36b5b3947d98973dadfa99ef2b93cfafc456aa06ecce88766bd2e293e24b9c2741299bc36bcf60e8df362ddc235359ce978937ad2ced5629cff9de4d07c4973db06a19fa17264b72a0c54f132ff30c7b96476119ad25cdf5863a5a6728971dd9c8569e6c09db280a7345bc219c2e6dce2da1748994a4486507e88fe348aa1d09552605030ed496f82ac6523127381294a77a70b740d14f37d33a65b7aed253322426328f432c16977080f63d60b71c809d03aa8516dc1cf03f6d3bd2e004882f1cc9cc4baa6342ea07bf86c1923862e054fe792be45c74872049ed1e61821b7046ad5bc12ef6238097972df4bfeea5949be5cc8bd4a80ee5276ab376e7ff3bae32a95dc19b3d81eb83ee327d5f3cad1c0a369831e2224542fdc3caf12c6bafaf970fb8e8a5161ad23155c4655d62e154f8636e480bf9f3b6c355d1b2137825739c365aee2c7767c03a666b189fad3c98fc155481877c02117fdd46e790ece9cdb950cbb8fb82de93b52be005de35feb4a898ee46b096c684541cd122bb74599761143de3ba84e806cf132cbb397402d0a87fbcdcedd714af058c9d7363b35214831349a72e85045e4195859c77448c5acd01414f444c31507262edd09d1981a3755b7d2a029760443d74a9b0a3e42b790633b195e7b5badcc4b7720743de30b58e26cd496bceb85dcc52872c43dd1725337e34e99b8079654365238fc35dc4104c55cebef30ee9977ae75174131c51dc6482c3bba9142ffb989d3898a68b9bcefda72b67ff100cacf2223c5df784cf41a6ae24fa739b524bced27da6d645f271256f45562c028c54c405ca4d0192473b814e031d6fe8c7429b9aac46c2e8711548a18d2c5a6f168150f9cece6b7b2b7a7fbe88aa4d6a82fbd31e1133be292a04c58c264d75de505e35ff6aacf4d7f0bd1d69fe14adb46a3d780a12858559bfd430d13d78c345609cecdd1e939dd7c0941102d68b240d1366196011397b71aaa749020af0c", "", 1, 1951606850, 0, "fe29a02c4fec29ddffadee7a78920f0c90ac573c78112f4fc1b1f59d15d5a95f"], + ["030000807082c4030109e00f361f49ec2e61b77ed6226155d97dcdbda912c001b1d04d3247a21629840000000006000053ac5100ffffffff04f41f81040000000004536a5151996a650200000000076a53526a530052e2c1d105000000000600655100ac00b73ec20500000000076a00006a6aac650000000077d4610f0300000000000000007ab08b020000000011bb0b1aeba6d30e9f085f3046180ebf68291b243e0c94ca5605e53b72a2d541438e43374d0052b2e1a215efa80e802ee712314057ad383abceff77fec998b894f99e242b1e718f030ea42bb7c58bd062d6c57eb45c0f96f7ef0bcd62e3308e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c04345ed9442cfafef8d63cc060510c9c43541c8fa929140e926b66673f471d9f7421e88f0b18cc5f7b7d8cd4fda3bd6503b68a2ab075309359d5775efe30d9e49df128e3c3851ddbfc1f0960cf52bc3feb52c3fa452cfd8055dcfc846b52ef649aa2082096f4871b7d095d60a0d314ac737a83d5b8cec223102db3ccdf6148030f8f861a0b1c34d8eefd6b94903f4908dae15d583619519cce84f9c421030f8303070e79433ecd1a2672658eafe2dbdc7f3663f3581ff2f4259d119a36f42147400b0441b1ea9db26b52e59321899471783480a55f80111c2cd5af59da7c0e21566cc878064ff25c556fa6ac03581ac76e8436af0acd6385a291f1c97e5025c0eb790310fee3f16a51cf6753c9b0beb9f716dd78cb24e7fab6b81337a2aea4dca9afe8032a635e6e593f5c1f0d90fd69319937ea2436c604c03e0f202b05a347fbb8d2e202211496e0a9a08ca2e5c31ee9ec7230d28255fa85a3f40decbc2b2d9bd48807780209c87cbea4d8cf2db13c045d78207eb50875cc65b2e87fe27a239f107a4ee77803051a27c07427f531d18c92f54d1c55e1bc2c417406d9b2953e8653b48f90c50cf1877e304bfb2e14b7cece58d63dc0ca967b2fbc3f4a604ffd6aeacae08fdb5f3cd0c9e30f874034b039ed775e54bdb68065519011372034d085a5258ec572e7a4452670c8275c04b715968f28a8d0941c99c89b7d64c536532dc474257a88aeb670efb8eb228b9bdfbd830a2c61e188378811a5802c920c221a7a6b4762250e564fb766166759f7205dd08c843cca33e687e7f5c623d2f123479ca96454de3beb977fb0e631a38c81219dbf03d53177c5bd9de18ef0552be538216aef86052adcdcf75111fe1353835a746d3cdbcb0e65271dacc5023fa526da948f78b2cbe2e00f758e2df76a5bc589e69f1a0373c98bbdcfe1437d24cd1de665a25b4580806745436ad4b403c8d991694725392cb4d6e54f11e1f527015194fc05fbb169860959ea6f238915c044d822fe9fc7a199bd8564cc443c9d66416f08d7a87473ba07ea663c46b91dabee295cf22ad20e360855b5b576757fd68caa63b5e11126c56d35696a845d2f5aa9b3e368553c26b0e70b98490dec7d9632b31c773a408580faf6fad6b97283f6e171f16b0d4b20ac88a15fc041df732261aeb0672c90acd306bc42241dd19a3bcd995d3406679cb16b8c28ce0a88fef182e713ca32adeaf63cb186b46e6b6c1a7d533a724383167583ab94a756bcd7f73c3e1f7617898bf873ce8269f45edd5f5051d2f95f2eabd5130eccfa71d804b8b979cf9ce363521b8d950f4a13d98239a32d67d2660b0cf83a1cbed9f49641aa07de1aa121ddd0f7f81eb3cfe38a8414c6a7759a50c8651d83a09a8f4a997e30811e499aac67276dfa3445704122a1db113ef0f0a3c70a318995631fdafeb2869629af6784855a19e330f76fe2bbdd4a8f309550a1d373e3e92a4fd80063d1b007789d582ee4b763e03db85e387cc15a91fbcd9631a61ffacd893e778d0d9744bdfaa35ecafe1d8ca8460badb5693329adc0000bff226f737d4c98a3cd5da1268b91e1f11e7600610e847d937877553e6aee5570914e08a711f8fd0608b62cbe5bf851cb96e05d701d9a008369afc4c88e3b6d095690696462166566af2a6ac0da9188bc511c13de618397a57d3bc574d1cde7c550499c6b3b04bc7e52ce7131b5e9b9be3309a6e33c804417bc1947431243af0f2e9465f9e7f8dcb5f88f1c5a12ba24ba95af169570e568133da994800846509df90241f160603f273192c9e2d058a736432b7c3011fcdb9d989b7f495012db299a54bde8377448cd06f2f890265f4b7cdb2294efe11165c9fe1451e0d6488f490f81da93c07005dfac6ffca8fd2ee3e228eb038d02935f0de79506e9f17ba220e21e2d8ae1cac98bead1dfd6931d27cb06f59f889439302d06ebd6f909989b45768d0fc57eb0146a634e44230ff39ca85df6b22af0a2fab726bb6d4ff37c008b04be8dd740ec4e0da2c35f711cebba2cad1c8b2fa9e62d9fff8ee41f54032b96705274002a846c10e60ad75fc07b2340f7b51542c37dbf83d0b022bd8afc4791675e1bbd6af675e7ec02075488779029c52c55750c13536f9715d975fe85516c0719530ee8c2591f6fd5badd38eb61cb1a130be05e0e213ab55741ea08e0cae9c059d8be759ef5fd4d82aa68b23afb583e1285cf3a56b1169761b917987c5113f2703b0b8a0c777d0a619864c80e5504a79cdd26df7d4cfdd5e2c517d02ccdabf82e3313ae230000000000000000b3e62d020000000056a0e208f064b16729561fdb85ce36122f46a1a7adc3c8853cf713b84f8fe94cbef9cc43d00ddaca32ee9ffcf7b7ee05533a3ebcbf96c7664f1cdc2e06ff4c0f1beb1661ce3b211e2ffa07372fd803b1790cd4c405c4fd9332c1ba3434e4d98300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000823c97d24db76572ae4849cec1f92bd4ee1ad9644419b42b06d178a1ca55124d7090d2c500972186237048a5394a828f0ee45fe42f71b05cbefdb37daf603b95e9062b934697ef8888f1a2affc4e09a1b8fb76f25bff215cab4cc4c266fd096444725ce06927b9ff950656b200fb1dadcd2efb41f653a23ff1264c34c6001c8c03280589e3f6ea22f6f6172bd2e88335cea2b5268815ede9b0de48315658ed360d0316e2572f450b7f124944b7546c31ed6392ea7fc20a96025ad311c015ebf612440b08149e4808eadcb4ee55995e390b39e8e6fd4edfc0923fe6f32f8559fb241e28baf780317f9729861d4c53060558499cc88b614a306845b20588117045aaf9ab0311a3f70f7fa5626818dc8356e66566c446aea5106c7285bbf2355b94bf49252a02117d28a73662cde57f5547b7610cd11a6fa365a06ca5597fc6d5758e2a54bb850223589d62d4516c7ff69542b1e7d07daef07dc205157805fb86989bdcf122ced0030773f3258abf53f7638233b3d9a1cc1c57d97875c46999530a4e91fd1a89b3e00229de41c804a072dee4002388d238c0873b0f90a948569d4c14294cffd462bda5f7ae6bd08d88b14097c8cd0003f5d08cc35fab73102011c559828207f3a65b39c38ce776565bbf543c6635073553aaed8d95b557e645693e028fc61c790a8cc50168b133367e589a8df3b9a3ac9975cece5f2ff16266ac314d9dd30df727702b321fbb7071ec0bbc1063004cabb0480abfd88119a9fd1b075ec0157bf4d406ca71587c68ff257054dd4e6b0ff14b21789defddc9f34ea03460e08b6045569a44b8d884e1d53882dd98fa43fcdd28149322294a887207e975aea380c283249837299f864089b1669ee12228ed1fa44daa1f67acf8828fd9064e366176ccdbe7a9e5f30eb1f08e65e18886818e7670345ed77676738f334789b8da352d783171ea404209cc88b4670f60274df6c89968f0be4fa3c09dfb8c1dfb2bc12d5eb7b04c6e0bc87713dcba530d42ff4be6c9e6c9d9a079473cc9a0f945bf41836fc182749c510f9d228d0219def6d2c9de3b12d33986f32b159e632db19eb160d3a62592255156adc7609dd5e53e43f56c6e3735351eb0296dee865b6ac51328c4ee6198582bee857718633c44eecd64933281213307b1f064b6435c0492270b4fea729376ff4fc30e2e33c48d62018d4b067ce1bf22a205c8aef031a5936ddccc6f1e26ecdfdb5c4b52dce662ecedd874e4ce0ddd532029a71da11ba00c8ce3b41b6fdf85e76f471d2225c92313f7ea804c6e9d3992f309ea3bc64c3c0046658cf702f5882322f5f465ffaec078c0e9f05dcb3d8c275a4e707e617bb5720b3b12cab8fa45d26261d44e39aad2f4a0a4930c218d43db7422b74376ac0bc729b9f18e22c417c525b66a543bc97fe84adf881a0970e6d3449604ae5b9566eda66465a4e100bccf3bba89e70e487df1d55d8229f52e2b4c867ed6458ee1f1dbc42a51145f8f1fdcd5b3828899c55c528a09653584ab9074f1160eefe0f5f90f89454bfa55c4f068e65e142f62722e5d13680421f5704b21d3bfdf8bb56e3ab074095bd7c3f1710ae38bd3313eee6f89dc1a61b5154a11abce90da880d6dcb2631e78c47bc15bd9ac9b7f93b141507a6636f99f1a52557cf9ebc25b507191a2a0440cdc6fd94ff0bb113187cd256574b3d47ddeef899d0563a8f45942f17424499f52efaa17bacd7315c360bab191a67107eb1cf417945e3ce56b7a142ad3fcd9ab6f0fb89f14337c5580106981e687bb02bd2fb6c6b68aa60853485757acc300b5e1607be94992b5f1f5721b30cbc2b072d23810edc3649f0f054adc8477e96bbcd3a4a488c0aa99cb9708f201bed48fed88998f33906498a4441fa339e10f6f229c42be5910e0d09b80d15ba31c182b3b3b0710f5eef120e2259f8e7ddd2eb73cfafd15415be59e8ac8cd26e9f981329aead2319a77951177c6164bcb6c0989a0bff7f2c53e9cd502c24a90cedabae574ddb346c274b0d27d3e66cce57effad8f4df23dcc9588f460ac942713f49477efb61a92e34a29327e3b0c25ce733a47fe0a1f2f7659d2286df3a5145f05e2d74d912f91c1e0caa78fa3b69b1161cf6a4d1498500cce798a36a535cf06c709319cc27c334330530cfa538446e2ba6666015c4d8766732f224a6f21bdd254f9f771bb4c642f2d9bc8b554a6f5c48d50d7550a32ccb3eae86665ef7156bcb5c053b17f66f4cc032de54e4d99043ca29854bdc44bd79e24c2259ecfed916b3e97c29ce0a97f483404699ea0b04000000000000000000000000dceed4e1f8ae53f427f71fe0057b8801c9d643287616b7f2bf0e3bcb98591726cf0d35a1cb1973a0ae3f363a5b31e3f0baaa657364e784e1a087fddff82cb5b73244b18da28d0f66734ddce700710ed4f03a425f8c7344da6df185db3133c93600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d65accb1f5ce4e4ffd2025a6a7f2e248ff9fe304ce3306b5aab66e7bfbd2317700ca18d2b3409c5744acc1448aa14f871d932b4a58ce6a4f45d5594a6455b6196dc2323db7fc6fb8a7c7a032a1a252a0c1a0623c4eea50f3694f1f81f8921ea6120900cf1d9dfd3d431a097b28175df6cc5153c5691618680815c8350a7565810215b71e92292735944ef6aef9573600384dc2ec9edcb6311004ea98320484753f030a3ac47430dd812663e09d64cbaac6a7a37df0fa2c3ace51e81dc3e0b9f036000b08dc5cc80956b670013122329b8929fff41a10bc8d35a43003ff9e18bf09f2148d3f53ac2ad8ac633436b9acaca6bea25068f6ef151ba53f8e8eb641946f951e020d444e14cf945c1e601d7be3106c41122f82f3ade594f6997df0a138eac394940204493d57c6ceeaa1a4fc55965d1af83eeed7d6099c3dd6d8267ebc1aaa9e334f03140a1a0859749fb182c5f0458b9f88fa248e0d85c4f77cb5b98c3e58de969a9a0220e6201431ec75054557be48e6b08f3a4656d54fb35458f9375a3ecc8e8c58e7032149c2165bba160704e1e767b6c11def2ab2d7916d58a20d25870e97069eef5eb33240cedf722cd4b5c4625c5bf48241f03942ad0f7a413e567e627d81fa811b0f460070e54e167fec1439d7f89213278d5fbc24712cae965648076331d0ee8d43d2e0bbf709953ab0c14595f65dac997948045f724636d0cf373495fc1dff31ed969ab5817a7741fc3fea630e6e5215ad5200012daf86cf6fefcac63db0f6bef4771dec20d2df85c4a7696b6c0dde34990eec3236aa3bff794e244764ffdf31c007a67c02d6e11c48ce4e0e1a56b1a580bf50631373536ac38e863f87aa8d9be274e7aaeb58cf304356ac44b672ae5aeaf545f0555b34eaf9818ceae868d47bdb34b9bd881a01436b752ab53ff8af10566fb507f33c898d655a4377edffe28570e1de2cdc6a0cfc5f4b4a9cd9cc83f7fe6f04b530cf79d793d74e552ddf7a4262552e070ce413395eba34458af648d5b19dfbfdc20dea8ede9cfa8562b505fe16e5bf478fe3396a6ca468ba1412dbb04eef164acee29433542c48a5c9c1596f509d2b407df82f2cfc62c397f5bd35e3b309e0b596cfd4845575417111143cb94cbbbb97000e5d7c9eff4b4cdeaf4bde0137e20672ddb192fc4b8c3e4a9710b803a377368e08b5582dbe3528c1c8ab7fb7f1755ee6eafa1a026419407e6029bf874be8d6d508f5e16c52698b8909b070fa60f2b1edcfcc0a4ac3129b221d99fc52748948ed273980c424730b5e5b2eb20cd850cd79b0f77c996477e27781ae7353d3c0e5981cc23101d4ef7ce975b6f85b31c83cc62ec49602bba54c45e02781d6f7d12350b1509773ffcb838ae155a1c35925f2bd03b2df9ce16930e9f4193f1a0275e01c1465d84dc0715a8ba1b221f353a34a82c0d6723fc1e8909c8c702f18b6488eb5ad4c1d562a11082bfa37c30b958f9f6b5f720a5b74385f09d59b71e2edf133c3a3813ce58e0450ca044d978ec18fa2f2c76ad15b9080bf01e516d7cac595fff98f8f3fe2e897c9ad871de1d81082107cce7f8612ca5cd05896418020f44e33d6101c9de9e4ef04517ba2695d22cb3e16ab5b468e556360d8308236ac4bfd5d70532054757f17b648db6fb08033c60fa60f1e638d7a50e0e3b9599ec276d0c3dea3c80344f411b07eb03df14b72d231bda5ae063d1aef7be2d571bdab370d4a0e3db80a3c96874143b6836afd3432ea0de4815273b2bd97b4170d6f03f596f61b5cc6196f913b4c08c45fa1f56080abcbe7e34086f9bf2be66116c7abc9e2f14309ac693747c8ba35bb92a98dadb76b54d82eeaa23fc89c21856eddc680837062a62555d792869e17ad69d5fe724e0f78870d6cca11ec9f7390931dfc3c7e1eb3b5b56f81700a4b2f1343052e7d3a4fb4077a057dfffb3d0eb640e857a3b6a10061c39264cdaad54fe1a4215337516aaaea05d27ced7569ae4ba36090a223fc1867d28b749588c84e07254fdf59a58d5b86ae1f310172845a396db5c66e77b08b457cccdfd9b8356d5c03a7faf9f288f8787c948e9a723caef124df9178723a3f867adb44c740847ed1a9a88536c95ecf7cfb3f0d88339d231c34d9d040815fea6a39202d115d6ac6e3485e772b2af5dce985394107eae2f6913f7bdc6e7c2233a2f21af09220c04f2fcd9eb78c71af8cd9694217b7091c93f68df3ed6283e23fbfd5224787f3670de09c6c85989b402202d625d66d3805810d0664b8e3a51e0a7573d988fd51147a56aa4dc1080e11c7ba3f077e2454c1488f6f4ecb2bf7dd716b8349ab47eb3fda4519e20f114191d32e635fd0d17a67d9165279ca31d179595e6c1c67fc258c29dd166bb8a344eaeb173100fd6014d4eb3b49cc1f476ea95ea0b205b40a2f2b92c65fb9d90d", "006a52ac6365515252", 0, 580907261, 1537743641, "94230f15cf0ecb445c9cf68d0a765fbeb35370b8b1095255ae03f77f80e755fc"], + ["f79ecb7403132376d5d70aa8abc678307477ff301dea58110d326c33ce13c55157600643b20100000008536500acac0065ac0d8961694e83abbc03e2a99eb54ef505326fa46b7ffec68678f65fdd3615bdcd95fc747000000000055251636353e82e0d439ea6e6c37e3f6c2f6d915bc50e1fbb636cbc953d12fbf6d172a6a6e92dd0556a02000000086a5363530053655178419a8b031dec6f04000000000952ac525265636a6a651ede0e040000000005516a535263857af003000000000000000000010000000000000000c9086d0100000000409e3fd3b013b6fb50410665269e1ad8cb3421a87a0db67181c75e7b9603e8ae6c30f1a18320f95f59f799f0c3509da85a62401fba352041d7f29ef2d83198808485608de0d878b0adbe5954639cd873c9962d7ddd807a76f985090504ae9119000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ef28ef0582f62153b64b62515027971722583d27efd5a0fca56c50cb242c99291712031af7466db618353420f8b5b7d46111a81953f4f8dbe328bca954f09414f322caf195cdd6a87704a8fb8c5c58397118b8c478318b2988b5fa2fd2141b480445ba782a13414f96bdbfa991db87b25a58075cd5735a4b38834a48cfafdb4021809c572e8fa75d3060508e402f6d285d851dc0aa2eebb196c682d1593a57d81031924a8e028521f681853fb73ee33debbabbb3e0c5a1c4e9babbc57dbd1f1cbd10b079c2351a0ca2e339e3ca7f5b6857595810d4d44a0e76a853638e4cc5bec46607644643c0ee3fab195db5699bd6797fe507a62ed290b898adca23c4a8e76c8f10322bcf5f6fb351c9100f2eaf403ff69e0e112e27f6a3630fb8bc96f72abd708ba0220e554d2354b98863e68a21234bbdff1046f11ae572fdce6688dbd3e0dc344e5030ee54ac45a079d22cbfe46bded8c53e2d2ef4d1d7b8407e2200833da18a5d9780309f327e48df85ffcc26858c0244e019cbe3d23ee00644cc661283af5d427c2240213483ea903946b66aed267c28663344f69b47055118c7c8602eb6a5bf7645ed6220bd3f3cee7906586ad445c5498d3bde9e50573f9d42a1ec0b25677e3b0e910b10eea1e64ce957d4f220969aa7325277da9dfdb0609a3b4b98c65e332c357f72e7ecc1b754a0e75fe877c06a23a6c845760fcaa82b8676cf309ce05bc6b3e96cbe3f99a86c1fe835e0b592319e829a6bf64f72cc331d5718306e4353523a82940356abf81d2fba427bf09edec9f44548b6abdb2749368b892c51300924258071366c7bfee1c99fd03fe8828f3877a3bca22ec7e6123c072d54557afde0375a429a049c5990e4f3311647975f1c74c255faa2ffa02f5c3d1560b7825d350934b6545e7aed971b9c7cf4c8ff22ab07d63a7ef41b012e848f2da55fd3e95a87d84b8618fe812fc657fd68eb68bcce6fd8fa677d4b36c5ffa113470f0bad78801a9d0f808dcea511d2f0210d4d6ad0efec3fdc8e711fa8ffb8f13ba7ce19f5cd52efcd5218f886c6f645afee5eba6f1b1155beb2b35afaccb1630af6e333038a36f41cdc0c52db43f8cd48266edad6af243be59848fc61c836bd460d1c713c9bb69269111eeccf79ece5a0a340507d4f6c015e29c834d46d9445d0b6f7f9b05ef451030f4f23f416c6466ddb2eba587cd3d7a6249852a0229dea83a8476e060cca5ed976fc45dadc77bbcff42c73eca40ba6a3c7e46e664dcd637e4118e6aa09f77acc646f98c708c102550e0764587fc21825b9913dbbc4d13b292a9ba698b1c46637831ab296e47bf97bff6e269be83735e112d021bd3120bd4310a29ad2ed0caf0e7630ce86650ec2e6a0edc557c76abe4a7b881ec886f09645cb2dbcd651c31ec3ea88a21b58a57d598c534b0550c9ba7895f4974835afeec3cefee0bc8b6966dc2fde08667f1b5b3b696cac8a318fa3143d5a918f0ef3f29398d87172dfab95192e70bb342b636b807f4887ec43e74b9db2d7efce6a596be409413750fe108368926960a21f475a213cfecc09287d6b866b11458c608b5d35855454aa5bdd61b114d2eaa17a086d0ac4f9683d2d39e0be79ad20d331948ebe6dfeffdd2124196b1af6cefcb097cc3d171c82a999d6849c06186aaafbe03084d9ac2597f92f86712667d7db84eb676b53565385c2a99f15967678fc213c0b3ad19a5bb2009fe3cbbcf7f8823f94dab3803132d2b8abb64c9bfb2a873130c594c6443dce9d06b5338c27f09c16e0d37729353d5adc1ac488960ece0d8d6a3285514e6f1fc137c5db8e204dd0aebd6c183bca475426fe167c4157e4ad02f3d74e96abc34372be965da57d58f91acd244357e005e7c9487b38edf901741c2a63325bd5a4fee26ce7c75831b3fbaae15af62563050123747f86a3903f002c628bfceab922714da4a6dca84df32bd96de54eb76c29aae585993af35278e2797f403a75e56483f19c8c8503103b182d8b19ed9947d71c4f94e281a90d2078417b280aee865764237c1264ea12e63ab317de52acdee13235691d803acd446ce3eb67db7fa1062e6a8225eeb2a242b505b34b42609291b378a9f1d569ae517913dac76eff075ac82cb8210a2795b414f5b8f516e04d4749ad158b6dae868c29734471265e092bb529f747cb9f14a7211588a08456d2e506d28e3eb3ceda5fff6c50406a76b6751db4472bb8ef51dcfb6a8dc851d46d139d293ba83207d022f1655d8bae5c79ea921717d56c3aab4f03534b335f5a0db02e2819c73b58965a126eefce9dd94f5e02674e8abd494365b7592fd2cae3fc47b187ee6d40a1946619a986e180ee622e3e238ceec07dc26a57f12e1e653ad0a75e9108db03abde2aa56cfb614d4cda73b1f4f73d82208fedfa855dd10f037b59d645b78bf0c", "6363", 1, -1165762510, 1537743641, "ef66437f30b4eaff53db531155babd7aee6c5f2fe8c48141a5f6f2f7f35d0d62"], + ["030000807082c40302b871b03dde4d889378a1614aacca208d92ecb19a2dc7e29c7ba316105cce21a3030000000963006a5351006a5263ffffffff8d7095fc1c21a17f2b46c2f1749909264afa5d71e92330f62d79ec014434186800000000085152006a516353acffffffff03f8de4102000000000252528fb8dd010000000005526a65ac6a96c14d05000000000353516a5d0bc9a00f05adf70200000000000000008bf63005000000008d6a57249ec322e5170847a8240392214e8ff0f3adeb8b8d1020c031cbed8103eeb52757f76b7ba26b5c7eca9fb2a149aaacb673169d024f3a60b1912aa5a2c1fb7ae1c2b32b76114a652df1d80062305f56eb6f3fee9c41438f7e182988d2860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015cc218c5a2db4f440182ad4f2a47063caf58c18f315c860a8dafefdfab397e7c62011308bc402aa3a476b2762b0a5b9666b0b48b0078fbc8968526dd73ffe1f3aa92fb5cfe2b754a8f3b3bd886b8e8246e9a8fd29145d5f36ad82053c41b7736a879da833c59c843ac4b0f80b18a2dd5e5473ac4f025487e2c68979d214a37203152c5671617e779d4305a8f4aef983a8348523c65025e12c7c581b5663e6bf81030e36a55f47e9b1cb27c1990349701b92a9cb3cc5cd78a054c9cc9d3262eec2140a06c005e080d804ecf21099457090db3908077c5a028f0495b9a0716c758b569db5dbb6f603a00bc99daf0a942f3cbc05c0b2cedd9741e2469f913656606da9380315223801ce7860c5b450df89bb9150439083016f77b90243cad7c72c4e2ce6010321eabe578a7fb72886aef8350918ef85e9308f2a28006f8ed389a80e7c55d4fb030272c1ce359d73f5b44dc87f914856edf6b77d28fd8cc1e10c5399003cd63cb30316f0d17a6cdd519df47f831a38e02eec571475ae36a2ecc645046347780213bb021a8a4c1c4457b1d04f51a1b9f8ba5e926e11009af396699ed41123ae90fb528497427c791a14e109d7587df985e99fefeec6c7b874e366bc105a06a14debd24998526b5876f13dc78f6a8cd65f821c07b8a7f5734076df51aee58e8701772247b6e4e2835bafe100d374ef664f4af991ef55c7d7385e454d8a34b1d484433c51185c720b70064b61fcc92fdd76823381679d2012d4811738d27b22d85f747519afa246c6a21338a6314972c4af561995cae8858ea3b2dc456848cfd897262d83156e08f8cafbf3cb60cd1e2c0f7f7a03bc4fa8f6b446bd3182f63129815417f5eb5bd817bbf767ab542e69de931e1826f93bc75550049969ddf7da631802bebea82a72e355b6a010b9036a36401862b03764551a36a48a8794b271d33c1aa6580f862a74908ec51a13448de1bc812ee40946c8f85ce49b0387dc213a4ccae71cf1b50105f095bf0ce3bb3fed0373b8602cac6f23af892b71833b74bc907e40eb23e5190c886ce0b132e1c6b102bf36e910b8b83ed365030f3cd584e9d2ab65427cf3d2cdd9a0c5f7441001ad8c6f38c7f815d2460281950f28c5a751da9c20448a4345ff326d8e0535d5f963d1fdbb4d2d040e3c7bf1214ec9799668f787f6c5e5e675c2cca231ddde2332ab34b358bf00020b46f48e8cfd7a409522dea34cd85300f3dffab9d4940e615d8cdd55514a8e7557467a5f798856535bf487ca2893fa54afca01e0be369a5ab8109e5cc0efa190eb08254285fb30ff83b3bf3f0238fdbbc7cf0dce8577ccb79cb05e3b5e3d47ebba8547d9708373d3418b7ab1bbc52ecafca542deee1bcc9cf723b08771378bfce389edfe51d453197baa90193c12814da995434da7b6471ce87f224173a0df1ffef204e87d83345d9ffd9883a30a42163c542bd56cfb571200a622fdbaf104135983e8751c3b8b429a42f1a431901b817a2f9e58d28b541b241422a6aae18965103fbf7ecf0d38990d17c30fc25eb9eb7e604f49784d606786e0c4f5c3d2542e27ce829f60e948acf67d272ecf1c08535888d74218d882d6ccaf3b13026214bfc6f443a86647cd81a106f81a501168bdfaca52068bb1ef9127a362b3da8b38af5e9a246c536624306208dc86ab89049e9d5cbbce5720053c9a94d0b51a39e31bca1c84208a1829480bdb4bdf99796a781a9489d26ed142c560109139dbe9da8fd6dab03d06da9a4672ddb1aa79cf7cd1dad671145433c44101f9935d57a785a19ba0992ea1b21f99d0f399491ab56b22c980d653382d599d8e0fb916a83cb9db4dac50ce389e9a8b2a3c6aa88cc206920328ba3215950420f014262e5ede3d6c0f1a4d873c5fe7c08c75ed38ee118f3bfc68ce243c1156092c895791a43dcc22ec3fbc4061b18b2bbde87f7419e26873d9dab6b92e5f17607d5f20222cae55f3b8143fe96d194b66445ca5988763c5d0f79aef28e164ea3f2d1c8df49662681276a3e5ed24a9aec9d9b64a5689770d5afdf216e6eff280fe0c80e1d28d7152704e4df9c06040645bdcde54847533e7acfb738ce2e7f1341f06acd451cf7b2e6b910c2382c6501d8ee46fe57e359d76ef5a2a94d4268a73563acd2feaaab22e6677434de8bc77fd49408ea4cfce47d45569a7a79a00e62adddd2d37285026f0dfd41fc81cfe6fac9326a531f5baf6deb4b05181d75fd1629f53d8358925a23c0d94b50d2e2b67af0b6e843172f1d602115b7f5d7f1101e9339a20e6a11e640a160000000000000000199bb3050000000098d17014e561ba1694d1988c5dfa619bed5b4e2a88b4cb4dbc289f37b979139070afb5190b12450079abbf0a33b8df46504bd4f2747920f00c56d27a74d0442c790e189e5af6945299c939e478c28772108f3939b88676241a3fc8a08e40895a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009254858330484f6f45083f241b8e616c3f60cd8c323869f7767812d555096437fe2dc6aad326d0dc2e0c0dcfd1ee449222c4fb4a794904260a64a6fc8e2d900f1373a4ced9bfdd7699bd30c627f827aca7d962b14aef4a23b5512f3af247679083c9bfe3031a00c4d2af2cccf4cf2d7b9ff1409bdc3f5123338fa96347a885e6030623168067eb38976a0ed843594ed36b24bfb7b8e91fe989965b9c21a629b2e6032627699a3fe85873316476389f18c683edd1172d45b0ac95f4af502455bcb5270a0411590e877e77346fcf0fa7feb4dce4c057ab97e0cca619dbbf1b10715052c7cebdf3499de109013ca5b3af620a2b90b4e1aa9ccb41a3d87e23794ba12ad618021329ad7d3f84a98f5eca79053373aec327b2e394722da1ca2c261872dfade1a70213f8c0f4c916b49783e5c772ae7370e23614dd48e3187a9c68a9919ed053f2b9032a8b5d5550a0242a64afaec594355e504b5529c1761fb4ad45dfedadd055cafc0204775eacb4959454327b4549a337a286aa8dc59ccf7c89f16940c6a1cca7be9a0217ac999e7586dd4145d4dad98724a53b71bb5978f51789f629dabfbe8eb17a7a9865ee90a2162062472ddb7f7c38559be4f39ec38c04c712ae4209f58e6b4c1791f9d6145cf269225f60d24725dbf7e15e5993c46a845feb5f29f87d52d09b352d6574c4df90beebf6470e777849bd1bee190c5b3a5591a2d53cd836558a0ff05a585cec7f3ef7cb025e09c7c0dfa5b0217a5c0cda7e31230cf780c3678d3dcbfd29ec3b941741f251a402a078db6c144f6beb75a5272fa67cf3cf83dfce7ea1f69aef046c55f96471f949e6b7186bf45e479d3cd6a135f9a8ad85415acdbe107fe36c52c3a69d5b5bdc1eb2120aaed9e2b778fcdc0622d7c312b85b22a1cd20ed5047b4ddb389669e6f4c888baa0cdc51fd09cd5a6d764ad9de33aaf735b9b04858b0427c91a2291a5d69fd19f27bda3ba60e22e3f30afb68b578f0274c172ef200b998888f9ea2f951ae08d7b147113940ca676c903f29292efe7105c3404c12313b0b8a1e4973e71cff46ab2275f14b277e7c840437f29e0f93c31a8ffb158d23347086aa53e2b39a8d4a4fdd997f7f3e9790d37caeab13abe783eb8677fe42b634c4ce7ac9ee293a35cc83bb838de3f8998a6921348268727bb215b5f4955ffd2a15f7a52d4ebffdeeeca17b62991b7231a9edabe8bdeb5b0d2dec1717066717b3e0ad9a4e52b2c88e5812659150c70a1dd2e9fd325538d1826f99d0ddeeb1269ee848c5bf224f322aab0de200998cf1ab307913a8366e2f89b4dce33cc4762c0dee08146c2e0f5965deb6d33a845188888e20c6e04d215be6825eeefd1f02fc8c5bce8b63592490c2e6100d3948fa220bd8be7ea1cc8a8502d1508a4fcfaac68328a81c8fdfa2e7d42d8be579aab55e7cc5c58dd23b37ce14eb4ef6526ea194defc967f670db60117a783e7f139162602fc43b2d89f18528842d6f18a98af893d6692c7cd2538b562ae94b77444ad344fe74a7fc8dca0f3e487c617b11a8b677f2d68cf6f3e55110b77d95a18e3e34192eeadba38639289d4ee29a8b047582d59ecb8780de0484d11339c002607f1b39b538bf5b37e5d06beefe0b0a3eecce9c3cd5aef5819cd85ba7b22f596dac7514dbdb744277f443ef3b0623a62f1e3f13fa6752a0de1600441ee234a250d16ad9db33ae1863e1c55c7076fde7a5cf73f23f909145d9618fba8c9a4bb8dbdced427fe9927d4898cadd46feb15c12c23578926aba368736155313ed26554c54a7631a6a0b7cfb25c9387db4ada090b44a740cfbbfb59671ba0e480de51ca727a20202718e3fe00bdfca9dc10cf207ccb2dc4339f6724fd036905150053b5f9e2c6fbf5ab35cef0ae0f9fc491eec2d130f3a5ec01ae4fff71bffae0ba9eea5a899d6b0682223720c5827c88920b1bb70d40ecdc29b0c6f84d54fac30c2603a0a07f4cee100f5799a4fd6810133b91512c3f240116f7196d8087a3eabb036ae0a78fcbe8d580cbcb8384863e8b0681b1fd6f987dacb1e25fa1dd9964f4bcf7a09dd9003b8b50df46e8db025f896eb7fc2cd8e0136d897d4025e4b0d5d03e2adef94bd76bb09a5f6b47ff4b310cab73ceef8a115fb046011c2c5172748a04d585ab6fd2c29a700bbbeee88f0337e318fe0e9e9e510bc2cc96515f33bb1895a566faa2a92b5c39bb15b4b2205f8ae12f248eb64691146ac19a7e0b49300b175c7d89d900de62a368aba7449aae9ad95ed0092f47ed5fe160f0eaba1998fc778842a75fd4bdb4c3761326f38d2d0f89c82ead2b768eb61f05c874c36f808b2d77e74e575883be91ca05cfb6ce92ff3ca9a05cd80f81bcfc0dfcb41aa5e38f0762d4203cb68e9c417c6e56b8a1ae63ac2e62adc5c595d06c1f66e5611759232b358b5601", "63", 0, -243327454, 1537743641, "54073895d4b34713104970080fb259bb291e531b56e810ae9d4ff15e50b6cb2f"], + ["030000807082c40302df7ca526bbcdacf36bc4d8bf77f235fa11eb6d9e96322d3d78f26aea9c17188700000000005145f80f873f3f5cb4e2fd854090c86ff55f7c8e171ccde0fae4be61ed19d4fdf210254700000000004067d1e50460ee260400000000026a51f050690500000000036565652b31c402000000000700ac636a00ac6a9176bd0000000000096351515100ac005353e30e1c2b0000000000", "52", 0, 1575417702, 1537743641, "f5bbf119ee1b62e12f8713d1edd786507e1c4ce0f5dcb19625ed4fd79bc71b75"], + ["ce57a95a0391c9df0c6657060e73d5bad973cea76ac07cf9d4207b1289b2f6504c636e696c01000000035265520c59a2990752383f04d3e407ea8d0468b5cfd584be20d2c5c9d30bafedccb56d70796f7d010000000653acacac5251ffffffff112b25f372441f96001724ee70351fe304c719c1897ed12f76587557bd6fc49e020000000365526afc356649013bc62a0500000000016a9d5d646d0100fde5040000000000000000000000006686d74c6246b50d7ff3d06d1f3f7e38ea63d39617aa60503414bc924acafe55f14e2d0c78cb13bcffab75de9ea9cff4e2010fc195c3d055a1bcc2d8072c5a08c371525d715f5d9a3081eb355a4baee7646d219032637ae0358edec2de5b173200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d37f0f9b76930d59fb637886048b06a6ef0c12fbb480e1c5a7315fc9b034b4b7a46a812bd779de2434f31a3e2ac875da36c0e8d447d356d966b9d79946736e7267f42ca3a7fa4541575ade9b81889ca18fcc7ddb5c2591fe24bae146abb793892747847bcb370fe8eeb3cd9e7316b4763cad68a2844122564065be728ff5db9b03118bc12c353af96b23581cb1b12674129eae3b1dcc7ea2dcc880e09f08c6a77d0227f5cf4deb88492a3aa57034c52224cf9f54d579e3f114a58ef9e20329d619030b076a0e819137939b026911a9969fcbf1a84ce09c7f137768a0bd878732984a25f226c6bce4e9d3149a9c3189a45cbec98576dceb284b2e1ac54a437f5845db08031e5ab20a487b970b770fc4fc39eb908dffa1351640f075900812328df308f56b021cf34088c3c675eeeed4727ad34c4e1d4e693af1437eaa8e75174cc0d8800f8203011aa504994bcf5dc036152321514f542051d09b1422b1aec323e6c52aba01b3022d1663a0c5c28358205099f7b4835602267d7bfb89eeca74c39067c7d8696a6a0222a20d24e80bee1ba4871cdd3e1dd1f9e1e7e88d5c4f13e5f003401a901f97ceb26f6a643d63921d62bb0e4778ee62261edcc7c9c0bf491f62bc9d906dad13df319a044ac7bab8084fd23c99e3611cdbd4fd7ed6a97d844db2ddcdf09aff82075af3bfe6f12e06696d5ae6e4c026e0b4cce68d0f6a1b36e7e11d2f253681eeea8a405854e89a42d50010f732b98862bad341ab6271975f1d667950f6c00b0fde8dac0cc08f16da39c3b84529ae8bbf8eeddaf42aecbf0bea6a951e2ee495d2fcefa22b1cf8f53ceb616d3cd0a5bcdd069f8fe45abe295c9e9d1861addd4e9362c876d1f0f3edef9bf3df40bc5c2f4a5bdf4205db8bcb6cd78383ecec4aa48623de4ba996abc4dbef19d69c7853dcd3667bda45816dbd94858626107b8dcd86265fa35e35e00c9348bf3f660f47b09ddd2991e2dfe2ba4e2673bb5fff5fc3224c1a5e68bf44deb5de80ed0de9c0c265d9fd552e6fb98aca15583c91d07ad7ba4e813b67bb6671da18d9143231058405470e894fec35d7c54bdfd7f6ece510c787ce06bce2a2f375de2c3dc77a3015005047016c46d93c8531bb1652bbf195d488e091db6f9957fc2ed640b42db0a08be2dcba07bacbcfae12593412d08b0a0bbab1f62d7886d80e39780367c762fba27df37d9252679593ff5c0ca7ccf65a880d0d640fbc7b9f4aa7b459a7dc47cdc6f998f58b664c21835da54879500b83fdb1812d02522043a355b94610695c8f6601b56b104e2fc9f4c06f6e29157136e9dbdb7983dd06330fb7a00607e15691e4979b0eaa04fd6b928a7c25975ff8ac643e02cffb93bf001b9b547135e6ea11548c92cc6adbc8dcf367b52b9a99faa1faab3d358db80c50af521d52ef4c3b9af42cf1734f1345e7326601cfd6e4830c5578558e2ac580c6fc22b098c7cc94cd4012b06853cc38b30be872f8a57935959dc006516731043867940ffb8f40a0baabd3e6931cc1b8156b4386b1d073a55242bbb421dd1e30277c8d0d585bcb22208fa07ccf9894a012888e7c12cc0bf80d977f49cd5b9567238e54fdd15a1499da4a2916d7df73c93b98d881c21791867c13e9e4eace818f9b0d6fcc959fb2da3e18d623bbf52aaba71c15d9ea9f13df667f4056bd8227da7d5d353e6afcaf58a5547dda0b4759971dd0879c07e570fa2d9710cb6faa9cece7979afb767db43d7b1e873b2c1b6ea5d3031b51b302140990d19f0a31eb8caa28f51a29b33dc0c0321447c69f37d5396b5f40bcb8a0ed598eaffc26b6419aee39fc13cecb6e9f4b08011a21c503b020bf439f469a315fb79326f71b460ec2c0cf633c3ac444d590018fbbb98fb66fc48e320e4092a09a51a42da4927da7a91e036d2cb1865391917d0e43fb19fa9b2530fa5dc4ea831e0411e0ed6c9c1712ba88fcb32524791fbc81a0c92e1d9bb05c432c607e5f2686764f539e0bb9dd55721c9e8c65553536fab9120df9dcd28a452cc713ff9b5f3319e84dab5bceb1f8e7e5c4ccccfb018de0645215ac15aab0cf0ae5efbc7340978c8d84f5753d29a7da28f66601bf775ca3fe81524d54dd70e433a99abcb713102c4419655baf1da2b157ec1d6a506d1b6b70e62f7606114fc115c44269f4be390a37f40578cf2bc1693038a7ec82e3db942ee67d93be8efdd17f16ace7ba2f61b2172ee19fa5a1d8c5bc96a8b5085c1b465cb52bbf893295b0a1779c0f9a72cca1daba61e70e8b7023e3263f79c232524e57da77f254995c83f6e4d3383bcf539a42a47d6e410041cc377eedbff85a24bc12ad6a5c8f264368aa4d5848aa314ab716e2ea450e9378d628570d6000165f253e7b2ad97e82336df06969453cb69a8ae1a4853ccc73f8af5921051b03f7fbceae17befb03", "6aac006565", 2, 1508316050, 1537743641, "ee694798863654a15dfe1e91b38ee7a15e4815725a3ba83a8aa6dfe8c78b9d11"], + ["030000807082c4030109a8e5aa8a755abeea81f38273d72c383055c202ddbdaae373eb4fdc304fcc7b0300000008ac52516300636551ffffffff015f6f2e040000000000fb4bef1e4938106700", "53ac51536565535352", 0, 2145876141, 0, "10b287949f2f42275bb8bfa6c08da04cd06fd29edffcd5f52e0945dc6119a7a1"], + ["c53f5241049d207bc2188fed33f4652344052ae04183735bfe9894b1ccd1179c6a7f0da7a600000000025100ffffffff8e0df3986056f1aab7091aaca7e235ca11415a3343872af15d17dd553c4fb8a302000000095151000051536aac00ffffffff320b6f784ca74a4272ffae7fd4bd2140a42726284d869facd6027bf36985b0ae0100000007ac53ac65635300a3a2aba7bc4151410d90dac57aad0350fede1923b2cf457551ac29c61f04184d0b155dc10000000008536a535252000065ffffffff0200572f05000000000452530051509d62030000000000d200e3dc00", "ac51", 3, 2129491232, 1537743641, "25059bc63d1540213c9387dfa4a6eebf5cd64cdc270494347efb4c99f93162a6"], + ["030000807082c40303ab8c4d535eb21ab7810de9847c7fe97f95ee72969fb35948cf76f8404b07535800000000026a65e6ee9917f9276cd6f1e2b886061dcfb3afb2d91506ea32f5aa9eecfacdf7248f724136f3030000000265ac26a996557d175a2e146fa4ca296fe48b54e90d0a8546e0b165cfd3f308d91d0780649d6f0100000006516565520065ffffffff0145cd000400000000046365006a000000000000000002d0555d030000000000000000000000003a0b8126fe42f7690fbb39a63f528340fe473c9fc129b85478812e72ec9b48fb45a027f134c6c6a2e2ff5c8cda88621a5ecbc1c9938006037e1fbc5b926abc6781af7ef37c0372da2280ec1f1d3f0ba1d01c84d7581ddabef4ffe4a248562b71000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c35945384ec2134f1603488722eab532c0a9da97a4409f5ec3c43fbd3f61be2e9f0d2f0b7a0a88e85c40b4f5a015a5da6503b44a7d21d3b235e851eb503c03daa226f3ae3efb49dee7f81fce1439d2e1532b02a6e501193f73578c134aea9a67e407a649b434fca2d7c453e82d70bc3f4c49289cbefbef0909110a39b74be220203285869ec3a1e19bb5a041cd6ae62815b6f68db0af80ded905054cfde276544021d2f7a3074df50b2d94eafe4e72de801f604bed672eeb2e5c6d4c25b56a5dab70b076213c07530fedcc8847c3331479473b03a2d98752289c4b2adcbc681765b7bdab8889a2580abf489d03dabc4c647c4fb7abe007f46502348ad43fbab1d06d0030ee49cf42fdff8c930ebefbef4f7dbc51d880fc9ff3e60cbf24751fe2d07aef603176e2cd71b1e8e59fe551f8daec64adaa3e12dba7ac8517739e482be3160d9bf030b77852acdf7bf24b13e6cc7a430cde236125d001bc28f884082dc9f1874d43b021b0b1869089557578fd8600f8be39d0c1621bb076e5eab7d37c464fdf6345bd70215867d053863be47d010cafb13d177291286308cf84437568d62427c67a1a81958b5ebee51f25fcbd8606f1c3c4f22ca041e931f920a2704f32ecd75cb1414d6efd8211ff899159736b437a021003fcb69136073fc2d9a54753d1c41b830a20759e3953e29631d9cdd194f29fab3a841dd7e3ff5acbb4cba644c118cacc8e8c277164d9a1cef37abdab007bedbfebe744728e0cd738431889c44000e93567673c686ff9855c0864063dfbce9dec34ac7cfc8a8ec3c556b4e75a53d0f7d873010b44b680330a8eed7dae98487ca9451cd879dc59239dee513df0e0ba8edc5250626a1b34fe933537b602ed8fb0b9c61b999635931fc1120a874e8f035ab2ad8ef83e3e1dd35288badc117c8a578b9a1094bce6583d25f59fb32f37b09e8b890ce4585dd0f091762ff8395a826bd0984b4deba26212abde9f9030bdb6d48c660414279991e085374cdf6afe06b60df21d2a22b747ed6ed330c9b082c496bb51af9539389b810156e5429d51d42108703df862abf86e9e396186667f282b33a8c0cd9d9395e4598a0bab539a3f7cb83a979db618e24e4cc1a2f71a1ee97fd2642c6ff85b17b307380c93cdf7acda30a77ded6782fc7aa819960d9fb6abe138f400949a36ac273f1d5f4f1ab598faa1d9ff12e5a882bbb339828fcbc27bbaaf0d5893b02117c23361c42556c6b55faaafac2b73b8e2a7a74eed02204f03bde1feb94941254ccc5368744078a0545d94cf6d907df5614ba68c30aa2299ffc9d00a5ba8eaf4653c98af677dbba71567fc0d812e8115283b10a487e0c22441b17c7b68cbc7c2ad5d0b34b6c15417f49977ba2be9c91febed47199d6269d630e93d2aa9adfb59e6524aaf8acbaf7c4ad29b2dcd3caafab56b517b012a7e21adca298c8fd830e75eca3415673d5b76bcd7436d1614e0b495a3423ba90a82136ce4534e0b015ac4973663eb6a73b5ba387903bcb3cc8f76a218181ee936b512d648aabb2a0d23af2f45c6a2e4e4643ebfa07ca6aa17415360d85440476f64dc33ce07fc1c1ca5ef1d3e7ea4bc48414204337642a0ebecbe90d7cce2adea52a8fde387df0937b8fb58048855fb9228e4e7ec88e4d4e8a9618cb6f1ce4691a4b108aee2b3b6a2b97cc308fa3d49750777a094acc7604ffb87fbf5c90c8370d5a01cfb221693a565ed6f9f585125a8a024ca2323f7eeb4729f0975dccf8d3af5bdc622bbad9f59ca6bad82b4be6e5c79b90f49895618f0eeebabdcc6c743da7c976b7c31535c5b4b3dd9ebbf8dfe54af95efc3d1561899cba43a2ae3049ade19954e33847f13d0d2c9a891dbfaf82ecda64e152cb6778221f0da1d846c39075d8ec2e2d64d517c5456656362e9267e7e58f8b9ee4eefcd9003e3ed6e5f39ea4c60b6afc1c835f474bda407696759bc91a4f0c0019e28f4dddf7d14a2f83848afbf2f342b3cdd5874a534dc2b87f9fcc09a3081bb0a071493225e8f492a5c1da8499ae6e401888451ddc8353f89050aa12b367986ed49f34e73872e566d23cfd1a5c2cd4b26bf24578c404e723894bc4ad85056a66dd006725929a596e39315cbac19da3fc73a8be29d4800845ddcf37df9684fc50091c0c079c6dfc3ddbc5359af9727ee59cf7fa6e3d19c2e7d35243da009f4369d65032bf08542c530463e1e6f7acacdee4a84ee86e508c4591962122cafaff8ab0dea0bb20d6758153905dccbe7a62270654a24f6c4fe09868388a64bd0f0a4d8df42a22232ba402000000000000000000000000da719927db953dff47392464724e31c7ce34ed57d069b0ad228767720dee4294133b92ac12f90cd8ce35638afe2e7d2b8d98c0a62b85524752f0b3502ab5a817d69db11f18aa6937ed37a53755e8ec243877b5e3e1f37431acf16a3c37af0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d6d7fb93027476c2ed5b1cc2282d3ff494b5bd4b3822d5b1c1ec57f75836d0d0c88365fff388b523eb9e4875d15b77b3e5a16c47c3c7b7a59c6f354aab5c669f35aadfbc39fac9722fd2c02a1304f359b2cf0e1740ce184db42f40b13fb15ad70e1594c64804472b800b29e1b20a26d4f218706ee83b110ff87e1bdef3f4064021c3392129bf70de3a696c845f36ea39e45503b97de937acc32a085039cdbb0bb030846ec59b933ce92af2548773170dbbe68b4b5f76b771d3b113507886a6fb9ef0a0234e49acd9fac3255866d3cd4a2384439c817a4f9483e4ceb9ee435e47a52ac35de575e2d25cfedb5cd0107aa4c0a52b66d339b6b84730a3f3ceb9eea969a4f03023ba6d4ee56471802d4d13fd5e62886b6287635f0e8f9e0891026ed78adce9b02183b6b60fa7dcc69462c36f3b3fbdedf897fa99c9f53cb5564c81a6336176f660324a90dc8e8bd56ab51f86fc58a12d6e2ba74fbd530e7903795416edaa758e8c50310c8cbcd51f9bb781c2409e405f899a6628148feafa4a0aec88341a275ddd6e6031cbc4613450894e240c87de4ff102ee77127545980365eec75cfa65c0223a0fd84e27611ba23d2f17c6ed4cf73f8c8b45e5fc37ab565be9e354ad394fbc2d72c45cf659ad3ab06b6482820cb6935bbbb80ee4108b050405c666b0dcb8df569889d23067d441c9786c71aefbe485c89c0ac1e75228b09e1ab0722acaa751d1b6fee9422e82322c81fbfe443911f42511f6dfca0ae86c5fd6bc3b8a9dc055ef0c370c238712ee6aac6f33598074612eddc80f8c46334a54945e147a2a23eee448da3f5326c2e62a7dd6e3792120621e4e8c47213e83df1230f7030da0f74291d384ecb390eaa0eb9c06fc64e91de971f0736d91ce8e7835d19f6840a4a222288e162bd411523f90b2e3884e2211ac9794baf3ba91b032ab0070d1ae2291705bda9f5faf87d47a64289bd6af908c4fe9dfb74bcdd21eb5d3963882db285178a28bb4c1112a63dbeedbf862bca871831812e727f0e0fe588e7a3ff605061c3033ac73fa9a20bc1e9669faf1678a43cd5dc2e18da0d3c2482b62501c394baa89bbd2027ab25a56c855f4791d56c541221ae7a8ff7eddcdf239caeb004190cedff8d62407e1f46a5567dd029b4943320961647c8b0e11ba9cc7b7e02c912ad6e25161d516067bfba196baa50248ef85738b4a5ac5bfa027fde72cfbad965de69851efec5d4c9b4cb0b0e0dc516568c1a81ac45b242ed447da3b93d7a856615a05644d11f128d7bdde63d1f1ff129496539d2fdb2fd221202502c65c160b125c069d06731b00a4283f11cdb0a47adecd6bcffd8172d7cc6d5cbce3eee087810ecb7b0bc214c87b33ffb79a657da042350a2013531ac883c0af5c3b2a930089168eda3190ba6d75456d8a0edbf4ef5ef1b3c33e422b7b7807db61f5fcf3d51d26fc735e6a1ad8a20998a87b459375f7a1ee9a5c1667be66bbbae80a58a51422c2d6a66487e65c51e8740e23b4eae042bb84677a615051ee98699e13f0a0a9abca64d58409d460ee1b15236ce3b956dc0f730ade30815e90765ff4bc42aff7c02529435e7b335fbdb330418a2d0f031f0b3554b921d6cb552c5281d1ca3a881b7e3ec68a56b142914c4d643419b105836513744d7f78bf809e96586f2eefaa0c3a923229d8e3c3904389ff61d320e3ced1f146e4b687fa29a320595816c74bd5981bb1b2797720420596cf9abd67d907361ef6a6d67f3e0212a149755a7e8dcd964f960fcf4c2b43d26d232ea3ec2e1478d19715d0e2793170aa9cd7a7cb39a76dd8ed340cbd3da7922ab6054795aad3d5513e18691a591c35284213d29bc7bac78e71d7b5d4b1effc096f4115d325e46900ef80c3a30f30d71100a2f5c3e2d3eed71667eb50fc2e3286880f2429012039b4f3f8acfb2d9f7e038a333569bc4af34b838a28972e6e0711800d68071eeec86cfc216f2fc794fe93b3ba4a6db8a7c5c57461ca7f69d3289c35ee3beaff5f8a59c2b2c383682bc33063f21a6de970fff9ce56299a207e623221f6cba341f17427105cd3c5746ad2cad29ea96b62a4c90edd0b8dd91ace4be17f4ed00fa024183e42aa3e2c083538ab77abaed1abe266777dfd352517c64958dff2194cc201ebc5542caa3a24b23b91b0334708866f5c110ff8905aa2e5aa55d2247146ab3c14951e25005a314de8f1a928aa92a97ad64c1c65d4038c88c69a04b70ea55a1817dbef7fc2be0c26ad5d023a90e36d34acd4ea1d1990b9689ebee672f973417c709291d95e901a57a664ed5753620f89d0d5a00632325163a51c0ec70ef504750a33066cc5803464221df3e8f62a5e519faeb34882ffd16d192433133d787a970adad5a3c9e39a98a3d2a66fd1009f28ffc4db49ddc524be875225ae84649218c2ccb97697401", "6300526a6a63ac52ac", 0, -358475696, 1537743641, "af4e3bcd8eccbd4a101021782f9e1f1613a39f005294ebfccdd279dab7df2930"], + ["030000807082c40302c69fb5cf9bdfe5b50afb453b3e765fc194232ebf31ced7c0515960802b76e56301000000095165526aac0065006a23e7cba906cdd9346d9ace4cd264e4550b4865a2d2a69a0b40518666b9b34a6ef27da04603000000076a006a6a535252ffffffff02d775be0500000000036353514068c70000000000065251516aac51000000007092ab2300", "", 1, 1739178220, 0, "99102056daf1a690451520a238d7cc9ad24431c6dc7eaa5739e53cf951b6625a"], + ["030000807082c403049718a1173d63149aa99c0feac271784fb4aaecbf3535be5ad06683271570eea3020000000151ffffffff0e2cf5ad5168cccb4964d1ff9fa59bf90a4e645a669357d90ae3124d3e7e4fd00200000008acac5365650051ac7f31b137122c8739d01ad8a34200cf7258a8f48d91c9d105393d8b71f3b13328a99b9c410200000004635252ac01ae21cd30d8094d8527cefa6193944dcc9e10c35d01cbadd4de8026ecc82306070c6d23010000000563656a656a1385f6d903a8af460200000000056500006353d60efc03000000000151db4ca10500000000056352000063000000008fdd4ad200", "6300ac51", 0, -83611747, 0, "46f80b51efc033f88a236307b497a4ea28ffa20ece936e0d3c223120e91e556d"], + ["f8de3657026e42afad213d84fa90a041bf6c9194afa72100e5b80b71d0c4e3bf17ce8841f103000000090063ac0052516a51ac68d2557d57230a46336781b13de1f425dc609ac17667dc34b245958a8c0e33b1056e38710200000003655200ffffffff0499f1b50500000000002d8b2903000000000084442305000000000165749aaa050000000002526300000000030b37fd02000000000000000000000000d91d56afcf6d9270295a25421eda2126af36bd6c19ce6a7b245a517e63a5d9b02a5b21b41c9d0595fb35eaf7e3df3d3424d396fa9b1d85506f5a218ed0c8129716748c6cc33313dcb1aac89332d738dc70044b620279f15704431988c86c765b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fcbf1d91f34bbd9019c2023095ad191ec63e2ebc81d835ee410961a2eaf03035dde33e173078c287d1e8a04831c7da3b1bcd3be7ca860571088223af156ffdc8cf60e70c441b38edc59b852131ff5a95105fafe85ec084796f530d2dbcb92b3cdaf6adc85579999105c4e94b34326b819541bd7d4af021a0ec0611af63d3f55031c8819971be6de083b6ade4575ef5a9884734c080d0d7c8388ee02c946172cbe030855f5ddda17d5b00da6a10bb6e9269817da7eac91087faae964db69d3fc34480b044baa84d80f842afca858a79131242e09b6f4868935e58f7135ebaa42562981e9562104d292e4ee6d10a383bf96bfccd62a32c24afc33be2af9aa48a08d4292031cd70f85c8f73effb9527a5549e4adf200ee5c7aebbb2d5f34f09ece75219bbf02163d13003a96ff52c53222b5fd64fc7e52c2108bc995a23f539ca857626f25c5030deafbc2b2ec0b456d12b1b2a61c6fde90758ca7e25735335d50980f827c9fcc0327f1304bdc5bf458473e3bc0b983c98b762668a36edffd7fe12623e4cf597785030b20429295522587a518c69a3886788d0dc80005cf099f8ff774d7c3b9ad5dece12011794cae31c1496bac9926e95b7e90a4ec7b88ae75970465e427881baa8286e24122f0a440afbe51b72fffc342a05b461062f980b7853040e7846a47e8f3eb8bd753a1319779964c338239c2a26fceb38938ed3266013363c5dfb737110e02fbae76da4574b313d91a8663a00db5988446305fdca3cb634e49b02d45252be73e3ce04746576dc97ba846a99110ad2628ff0cf16dd174d8caae7163baee9e8df2d4ab86a94127d4a6c944f8f1dba2856d844e6e0b1172fe54f448cdadbe4c6bf5249885add180f77f4098ebe154c77faf3f776ff031e7af463376dccd3d2ed2deeb68fae79ee3bceaf4cf9bccc0834b460d8bc7b147a3ea97852d17680c1b34710246078682ba4ba9e7b9bfb7c7ea21d5341eb3f9cafbfa8c14d11dbb9df932735875d415f954c4cff523191e4d961280c1e8304c06e45164d38d460b70c1c7aed1ba72b4a33a37c6e5e2742901add3bf6678376af3ba692bf8fb90441fc3ecb76a5e1d380bec99e419cfaafc035efe704d97d5147677cbab82f9cb5f989c244bff9445b0879bbcb4a03539a3d76095c924cbade2d9e0553ba696d3d3921d81e658914eb89abddfa39263a23e4dad42290ead4d75090943eb3aca8c1c5e0c08ebccd44dda2143cd39bb92192d2f1e70f6f945ddc3301d3f09251c283af7b09a165830011226bd4f326ad03648353cde0a9f5228baa29c2b0df0bd7413bc07e2bbd739eab54a45ad81901a9f231deee4332f6f0d4d46e5433f8e709ec6fe7b4130a051c804e1a6ad7e3b534dda024c7fd9dd758362025050575efa64f6c925c33979a04f9b2a8acab7351984de4a1df837df738026f2237da5ec59cf74b490bd3c5ef10507e5484a0b2fcc97dd58a1f9af32d9b0c4d6682cf3cd332326d1f8e2b4dd7fae145f2659cdc7bc8c5e19aaaf718a34e15830c7fd3a268a1445a90be34f9b3d686836a8f9067fb832ec54875908ee6657725a024f2add9e9abb2b62b75d42bcc38678ef064547a5029ae28207b043673185f4d62a8e5e9c23d471ef3d6f950cf7332f8aba15a0b02da2cc28d3350c07c3fced466de5b86be612c2662b0e1305a2dd3bd5ad933bebc4d248cb9c2af3c20fbb1b729b28e8742ac627e764edc22bd29b26ec594b88c5b66e2f46cc3857abbd7c1b66d3183890df1f5e0598f99cb9098781b52e53141338df619a305f039b9fd7eb361e01246ae38f39247ed6d49db677b9365b2d2473d0c232d1192f22d645423bd24acce12b266782f05010eb5f7a096da96f72542228a2126655d4f0e7b856089ad934286dd27d4b316cabc38685170c64cffbb5c643fbd5f4ca48d4e27534deeef326cc26f56a13bc04327139dc84f3ceeb1b0a1f503edaa5aaa08e3e3f5f75e10070d1b979d8f3f6f5882dca0161ca5e83c5eea93e1b9cf8b59bca8502fab4f92b36cf9847fe43a672a137ad228ade40127f0cfb1eea60bb6846bb2232a8d757c605939711b04107f631c940eeba68fc36e3c682284e26cb35fa5dfb5aae1c07cb8663cc176b994c755272dd42b1a533438d9287422cbf0d3258902e3286553bb0c38c6b1e0c3c8c9719730cc545d10f430864b85d8f007c138b5c873c84023ac52542696f7472e7a7a35a353710b70a1ceb9434accbff98b393b38cf835b0f779f924acfdded8129de7fe8e26c49503629f0f759ef449bef3fbd66aab01000000000000000000000000e203b135204122f249806eadb8229864b926b7e3e8babda2eeb5327d8f00e3122822c90cf262a2b76e83c312fd2953d85e19ae282fcdb6f89098b63205410ab097e94873624fc2db7a4d161afd4e86f25a896584cf2fd15021ec9c6a260e363f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002163b670a099e1b2138bfa34d5248e4c859169fb9a43f54cfe8320b258d79a20c9b6c10bae386823feacea371dbe00df5a8cad332e3d36ade9aeb2bbb217acc6255fc2921315544b5f2c3c2e8663d22beeb0d4bb430c1110be9f3f002e71220ce62a1b6df7cf4f999449d64aa95ddd92a1bbca39d306616f44bdd394e29eb9c40210046610b0c48a29e5baa3330fb0b9da9f8848f87e3e90ad48bc78b4b83a2d530318d5170ac5e9ba4c430debc6155a78ab00805fd53faef7816b2999034aaba66d0a00fa099019f2dfc10329e3a82b76b5ec745b07ef9a145b54425f99e94c7a042c079eadd47fce96c707678c065b53599ac58eaf16710eee51d17eee2a6c7a4726031026d14029baeff01f20458dee16a86c04da823d81eca3fb39a1fbab49af78ac0315687ceb31913975290a696a834bd13810365cf6281ccbcd3e310665369ee6d70212e3565c6188e5d5be641462364f3293c95b6f6b78ea189342e6e03f8e74cb1103103372340eef50623d525661b5ea723532fbecf027b8dba0f4660df61f167d910317785a27bd5e6db8cb0dcb04429859f68757d97cbc5d7ccccfed80b2e9f0619fcf69938d339c7f3e1ed53d889efb5e79d3c4a7e0a9167a187097485969e12d8b328424e71f4aca62ea2bc04b53a71a60ea59ae2538de4b22ef7c1107f01d40c08fbaac75b1cc023f3f8538a72624aaca7f44b5ec9c7186497d2c3b818695265f3ec5db59dfd9bffed2964e5d805f92ebdd42c2d8f552a42eefa63848a6167c24be738679c5c1f2055a6e4acc5dd51d8b85d19d14a6102a80f4f54305ae9976bd2a46dfe9490257e726d20b9970e260739f018b330c05fc39c4c4c85e0ec306ed914d1e324f16386407b340fb6e25a76f037c49b7bcf4745855545cfd02e0f2ddd56427e8890308050040ac505017a534aba0af6711b2d25e0781f260a9d6ea1bb50f7da0eccda959a609ffb40002047ba8e584fa4e47857928825ab9bac89c1216b6beefa527243cd3b735b69cc2481fceed9cb43e772656cd5459c37dd68eb355385ee455d4c34ebe09d322c0bd6564c63eee5431438ea10eb188164ab47a21bd3a8491a813a44c91bc43c86b366983e5ea7eb544ade8b169e932246fbd4d3b8ec162ea5709454b27625521f5100ff4110473e8fc60fa9210e6f3c54ac579c95c82aafc446396eac4dd7f9fdc95ca224477be270984d3ab15806777c56d483d840c883d1a2ee61bec47f340464dbc8c4ae571d1b268b1dabd17421617d8d980f258e8b375428cb12c6ef4e864556c3a7c7823d454ba4cdfb138b51cde14cef00330ca07a64ece912ead94e3c9e3e15a93e4f90010ad8ad12c335bd66e1d0fd86dfaa65bcbf3c1591505b777e250e9543ffa9288f3366d0287573adcca5815ee1f636a5b0fa448261914729cbb55f0b45772cae652e691fff024d3a37d898f8ae1c5a6b1fca1b27664eec1586b40c60cdc80b7c4b10fd626857116e4e533e56bc0b4af891ee3d8c6827c985cc446bed92aff80e9ad9b56e002cf14be6074c3944e7d59394895f09b01c7d995e17feb5fe05834d76b07036f06e8f773ff07b1ae227500c50a1ef8458966db0eb10b1eb69b4d83d97eeb970579ba6778dfb0081cda6b389e1cea841996239ed00326a8869dd1899fd5aac56c7fbb48ccfc8858916c5cb4b6854ac1733ab2a3b973bab630502c23b0ab6472b6d2394203f330507d32f3f82bd66197ea0c3f3f675578f59fa6739e9654a34647222659a75cdc282fb2c869bddf50a35e6796c478f7ee87855379a374d0c9febb8d6fb15880100664fcdd6412bfad2908690711db4c8e3dd317d2da4837b48cd31ede39087749b0427fbb6a1b6ad5a36b9b01f06fefadb01c7580d17a42ca87f561d17eab8845a4a90e2d85aed9e6055124a2f348486b418ce3541c073c89b40c140f51f06ef27ffc2966d2620652115b068fc4c0bb41167ef698a5f8da720e0f661a284c1365db7535f46899d74551138a9b8b6424920134e18a401d7d69f739ce898405c10e43b6c84d4565580695e6af3e2d2262fc09f2c870b3bdad621a79f6b4c6b62539bb5efe0f59454d6061c37bc282183b962642306ba5df1a6d50f1c9118fab286538b199c137b38e247de4db11979dcf6e7126255a4b5cfa2c1ee08eb70a3f6a18da80f52be530d91291dd2d22efa6f2c7a6cd5cc1e250e0fde674039c9a2bf88bcfa1b5b2888612246bd96e813a8ea6977a14fc16df88a554b9c66ae0fa6763b8e6084ee4a59f7bf102e6098b7c2569919264692a0000000000000000125f4101000000004de3e5963a70786b3cc58f9d7b1441b1b24d33b36c6fd533f4246533692b251bcb448b446ddb6f4c3e2da4f127b3fcf559781f94d413a308092219adafc917c7bbd0c88b55cd64c679940ff3dd165c70e486185c93947822f12ef6d8ee1ba85d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f333e9622be256b57756a1596f397cd3bc67774202e3b98bb098b541fc6c7486e74c2f98f5e7e13819d4afb5d8cd5d813090dfcbb51a15fb649aa6d125115ddf5d64e56200b9407f2ce8f7e18f05ca5c9257ca1e7384b8b43392789cb63c2a849578ab4d3188ab5626f08638e806dc16e8cf5b3687ca6de491e6ded40b2dba8e031136a0370ff786764e49f6e4a1ef8e40b0dc24e98deee74761ac86fede14096b0223b1f62e78e852141b5dbf8ab6fd2f6e9ed06bdb104d049343229fb4b2a01b7e0b02742954c9902266f954e2802354811a7d1b9bef7f8873957f1bb2b7d42d1118e17607b1bbdfa4763afd637e82a00dcc102cf2196c2a21f947d5b00309a23db00200ca295a0264939306c7f5b7aa62ae864d6811f19ba4330ee99ddecea221e4ef020d625efcedab0d938072222d8b28e48e8bb42629f8079cd635e3866fe9caf1bb03075cdfa3fd1e20c2c7ab23cece80d0ec743af405162bc149dc3e8a483c0fe19d031add98eada81849727435faa1326688536432ec7095a7c913dddba16f63e84f903167e79123cabcdd16f21cf4be6e5e47a67f0be0ab58c1f76bfde7868931364285ee6919c2c7c1dcdc91ec0e78f204e2df8cf09ae1418438b731a1cdbe0bc4176a31531598f16abbbba12ec2b6b6f92f5ed772b72d3a26835b0d84f4e941920635151cd88c24044c00e777ec756e24ee2e5bc5d3559bb9b9cd3280ba2d04e7655b36add1f277f108c799e201be0c1949fa424d52526b200d65a591eab969f1a4f66f90082f37a0bf8f93ba53d43e1958ac70a908e531a0d975592df8bda03a336908629b465eab149c229e357493867a887e0b3214cf3516eb1979f407ae29fc2ca7c27f6d8e5d39fa0d49752f5c475945b44818913ab2b44644d0714fb7845530de27c0fca8e46d95c950a1138c8a2f1f3e1d344919f4640397104f9cd7f73c445fc8ffbfbb93f1d24b4faf3286ad7d972230d725ae1bc36e450ae634d1d660951e3e198b3c9f19e11692a69741887eda6c0415eb25c750fb29473a1aeb2b8f704051e1a9540c9d46d0f80d7832228cf08346b083e0dcd5931785d13442c8cd9f3cbca61bd7289331de6caf4101103943a77cddd5983acbd6ad8231df51a37e8e0d3113116516db8ccf5d9626c96305da6740bcadebd463b8f03ca1fb61f43a514e7453872384e35aba599155d68e51c60aa7d9eb11679b38033dfea2b65c853ace5e9cc0b5507abc9ae59273dabb0dccedea8be539ca5b3eb57970ed921c541711268d170ab345318ee9cb5c4ba2c2df207fab367e7e5afe6bd982fc34b5f415b4b9eeb9190c666ef2f2cf72c30a56c1113979ed499cc32ad60b8a843f85649eac23dc7e4582d18a529303f532470ad833731f2fc958d1bf9b31244270f84d058f358fc2aa77a93211b66b347419178908ba411b313fe3984559713c51a1a618cff134c6d3334775bd5a20f0f1bdd63f31574dc5325c50db0ec61d1a8d6f76930d01709729d10171699096a926447b41b8b31669407cfb679a6bda47854eded6759853f39fbe9fe8704cf4c803862a6c475198d9f49512c7e3134e0a1880752754d59019b79406c42baf50ddda07a403148646cef526f14fc26adc195e0e2772bfddf4dd4a751fbc4bfe4eeb7017343e0ef1fbceefc5f5d9bb171dbb8220a38309c4b977b68e1231b9aca9dde6709c87416ae2bd93f1a9ee5c33bbc85c5106818b54179fe67f6609c915728a511da634ce0a113dc84aeec5690effc08beaef8cf8500eda3967fac400b27a33830fabde35a12f1c43f441cccbef245a7a33cceca9874bcc5e0cff2ca5a4595fe0b5aac80b7f10dfac7cfe048a4f04359bb376ab8b44621490f6aa15c4773177e54f5c8a79ada2fe1b882ce4359ef0744f332aabe68de8a0cd706931744504c64b4dc5c6e6e62149a42d06bdc941a3d72b5f86f8dd23034efee81cabd253b2e2ad70f080d1a01f13a89a58f7a349ccdcaedcfa0738f3847b6513adf42c36eabeab92ee9059f12bd4f261a18c221cc0cb0e79822bc60fa80f0e0f03f683762247a69b7e0d8839634fa9046730d38d3adcac7353ed5214daa5e8f28461bacbb507535afbcbdfb4d948ca9e11c6e3e71ff2cc319dda1ae96579223b4c22d9924713e0f860b1980ae9084708f7500d5c28dff2a862e4ac083dc0722125513addc136bb593b9396303ad92d83d0fe2da462d82af37cf97e28e4254f0806d77abeae2b921f96299ec19f99b5f8624f5b5a55a9ba27633b4cfcb06147d96c075172c8e324e517caeda87ebb9f036a74dec00abbb111d965599e929c3c24c0b1400e31300eb6695d0a428c08a251fd260eff0db11ac1bbc7b6f6cc882e8da0da701925e9130f3a533813886230a943179b33c10b07b4e28534c6da774e8a653e30aefe5f79ef935930f", "63", 0, -1652976456, 1537743641, "471fa18ffb2ffa9378ad8d29fce897b96506ffd1f680ee46c3ee49ce71c2aa43"], + ["030000807082c403033a1c1e29e320a88bab4ed7d1cd852628f37c5aa31a71b38c5fb0c6516cc1526e0200000000aa0734030595c8332c3ed0f1d999a7cfddaddef59b16ffae8443cfcf4b56b3f654149e6e0100000005536a6a6a53fffffffff5f9e0695f70e3a42c8db46cf682efc08b80d93ee6d216b9544b61eb6e98e136010000000153ffffffff036259350300000000009b634d000000000007ac5163006a006370645104000000000551515252ac3b869186a1303eae02417a8f04000000000000000000000000487d8d0a803cc27b3f5c8842c164d57aaa4d3eb9ef64cc618ffd26e0a5ca58ebab166b05f9a4e4c4d9bdf075d8b2c8bd5e5429ee847e112e6d1ec5e920616e65201384aef6fe018cae3965ab7b8a5a53022ca31f217249a9f87bb4f9aac57e4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c33764136aa5f90a85ed50a61169931ebdf0bc527b8c6c1983357051b4e3711ed2759bd0e5655abf8bcfdcaf1c1343f5d263d1ec16c525c70247f91d0ff924de034b35319d08af1fa21384eb6de0396000aed27d3e11830aba1e349852df3f4ae0fb73cc4f47d3fbe84af3115cf90b88b6142c93edbd680973cd5bc0f290c72c032bac399a918ceeb2e7023b91aa85595c7a2b2d34acc942025776051e5c04dfe00304ab444e23bffd8e8cd64715500e848dabf98597910cb8acfdd9a0405775876e0a000680f158694ce9f700374e50c4c6cdef7fe5701c8db1f3fc78a7c83664e5cac7cdf900879f443b624f4e3ff960a89e22c29e2d0cf7e479f2aed6616f8039890203184835c515fef98115c9926d6ee547f904101ce137bbc04ca3fb20aeb75998030050c85b06984623daefa2288897fe10a2deabf1f2e63c07c73d429d0c7ef8ab0323e36774ae58b72886b56828da872a3d5916109c63961a80b088138a528710ec03272035c33b229e6a9fc7611492390b5c7bb6fb10df426499a83c45637b4d2ef202218233ab37ecdfeb4de394e151481e9052fe49fa3e52888e849ead02e14c1dd9e004bd1d4d62cb8515438a387010aca469d349bb994b1f3c651c51140b265d5bbebf49e30a3bd34ebac0db57509909b824a177c8ec04ac52cd85d127c26ffba82587a19f5f250e511b5093ec5a9de171c037149459d74a4424de260bc1b3ccf4465a4f40446290dba88a922e25a7ab838d28c3c49e6bbb8b80f479853e8617fd12a7622d6214886fde03205d4df8517c9af8c7de7b126d73ac65cc0775e3a9741880be8fb6943097907c3ca4ffab4784972ac52afc6734d0699ff652c13621130296ad7af4baaf97e693e2720f65912a704889e5ceb34432027c5a6065e8be9cb96846df07db10a318c3443e69fb784e02f22c1b498b094c03bc9b950604826860407e54fc805f78783e4666aaec10abf3340e740657d47e848d5893bda9a78e0ae461ea789d0f4a56d884b8b7e8cf4c7458fede3d9e7feb5844762ae0b738ea67909d2314fd5d9063874ee0fd2991c51f640580bdc6ed1c57b29333755022ca493d65819c44e5ccc970a64ffdc8da208082e90f76ea7e6fbec4edd101e4f139245d5f20510d50789900db9be15193aea10dcc8a51db249066a0f1fa10b82e42538b960d5213193c0afe3ee4050fe2f3fb382410b929648aa6581d81e2570eeee088f186e1baa69ad2c296d3adbfdcd295dcc94ad3f52f9441f7bcc173dd4f0074cbb2715dc5ea25f2def03dc1a9c133ed49df4669255a3a104020b0834c473a393bdf9c3a95ce1442ccadbefdfc49db0c44c711c7e1b4f59cb7d1c1703f5a42364ed242b7ef73b144dbf160374970360a922e7dabf891b211ad222a489e33ee648fd02432da9b24b66541b452f4fd32cdb25cac70745838c3bead95f4ef7d43dd3451f5c10fa9b1e3cddef4d289ebbc1232add8624c97e8acc3a87a5c15cf23aaed474ce97cc07fda8d88f99b6353d1158afba9b36ac3cea470787d6d8ae39a21914336ccadf958494f28dd92253fa7c42780d90faaad846adbbbb9c96f872f404edc2954f437d134051c492d2ca61250365a1ec16c279c3b90dc5e4cd47d16ce1e65f16eca07b0998d780dc5dbce80992e7178da120358eb272baa57120c9ed53aac3688ebb1dca7e8e594a427a0e582bbf8506fefcb162cbd537d095ea1c80c678db194df0756c535049c64154602032241e7297bf52988e264b747bc7dffa04c36be348c350ccd3e5877214283b703052517cc22178d2f52c5d99a83801a2698244b284fd8797ce19363c666dac1bd091cc276dfad7f775e7b8da636751eaa043d18b4f9a7adfee66bf5a53ea9acd217e1ef3c1f259edde206ad52e4fe1e83bb1a2643fc196188277fae3c3b813b1938c6abcb3b0655720c3bf7f2ee2bf171aafb0ceb105e0f3b434f77ad911977a819fd62f31a6f867f2d76c53d9dfabb1b546a8fd53eec6c5b71f1642ce38a8a780c495985961a09541483dd00a81277aa665b7b1531c3e7868718db491b95f5d923c3219bdfcf4b1b32bf64aa70d4d99f5e30530c694b1a484583d54a4658592ee86f3944cb1e75e24aa1ebffa11484930f01b2b2962dbf421804152199a82d566d6355079298f3ddb31d42247869d28dfd028eeae6d3eaab2aa9fc97a81976e8aa7f505e1c87a7638be6e3a83541342e6bd16d7c9823fc38ad13e25432ec47eddf3c1d4452baf622aca7539868b35efde93a7c829f9168f78e3466637d5f9ac2700000000000000000f8f90405000000001e88bbc7dcf0cc85e4084bafc5fe8096cdbf7b84450cb8e9d35861710cd150fe0087d1ecd7ecf67d45abd3592f27f7203332db44c3173e3f909aedf2df7c4351e2c5fcebaaea31fffc26a303d29b5ec198ffd29947bee9a6163aedff5b34a29600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000515c2c402d39cc553bb5746114352bbe0a3134d8b99565e3f086499d76756c8770ac9f0c756dec7bebb93e7501ab7f768a8c40dddae982f4f62114802a1f914b01f79912a3e7093a40594dbae53e72a2f687e89e5a281b909e2a04ad2b4d4e897086805c81cb1d4d95c6489049802c8f8d115dc87d5726a1ebc94baa96ae6f2f022c132c0f497ac9221ad1e99909dcad87d113882084fc0e4297a57fa4542d6836022884af159dd432917ce207ba5ad824dd2155292fd5aa31943aceb97d444986220b0061b37731e01cd7e97e279415cecc09861adb9025d4c665bbb6f4a181e0828411bfc13c495b42179f4b22893aba9eb8d3d94d0e1a86dd8e512d7b2ca47fdf8f0323a26690204856571cef35e02c683f9155be306e60d8abde09a3c65cfb81623403182ce631d0b813458503365e008bf2b68840eb471b181ac7da21572622a840cc030f90525c2451a5af084a11a54b477f787adebd0bf5c0226a2be834eb0b55501802113fae9de14a283f1a6d5529a49238da9fe29d087c51af1cb18e5649e237648c0328634c56b57fdf34b13b52d8f9fcfd9535824ddb1ccb3309f895c573a73873941b66451f35944be5b370f2d01c5981b1f64c5a2ea88981dfa79ad2d3633233f098569157202976ac197b49bdd366501d7fbc947bd231ee9784888d74fc0937cf8597a228b16033270439a272e9b6a596c614e7194382c5ba23db01544d4232f1baa538d7b506775752668d17ae1fcaa34052b4a5b6184fa66c01ccf6b94bd09a3bfe7d71038c9c0c9df2b4fffaeb779b7e7c54ebcb5b3ce0c66d4637c29d66e9790862c0215800c587354c88065b42fe8b56fca7ae3fbe0396fb64b3d8780188a5a6fbccb26106deb6fbd132cf1a8801f74b01d8fff9fe8aed315ddc7defa64fc7f5ce9f1c42b096ec96c4de8cfd3f560436f66006de09ffc7f8176b0f4fa102b3a0a128e93c3e0581e58c5019a0e9eb02cb06d5a3aad36ac68ed5da1196f5e0902cbec753fafdb51ea88affa7e02229285c3d41c30f0b727c19c28b84dd50327e76b810d78b46c8337ef3c96dce57091a87ac7549fb5de223acb07d0e347baee519c28d66e77a88f34c4afac82be83cec1d5b6df646829775a824dc8894a92c9854d702d467c408a2e1ca59b34ab49395408e70f40b01b0e493ec9b8e8ef1355845ac9f08a0842992aa269fadb35251bb9066dcc67006bafbb4028cf600b3f6e084bb67aac98e42f4fc631f33b08c40b42afa15101aec69eaadf02c0e8c78df8baeddde1f8058a04798cdd938efc0d5f887bc48dc7902445b16bcfdbbb4fe3d9771f9ce31accf2244fc6908602da416bb10c0a7c9a2f5de00911e58a0fef771935cfdfbc5a814833d771455a52b78f2c8bccaa0ec57ebe74145beefa6b0fe32c40c9c0386843043fa49ab9b40fc56421c4684631d682d3cd301eeffd05dcc23fc8764cb277ccec21df4e86b015df35fe83a9a3555f44368fb8da3ff2e2cf8d1f400fd05dce69cc7ffcd7e76a66a50c3c366bf10406cd49c30d995c152ad4f268f1cad090bfe08b5ed55086c44414dfe957f039a0120deb659e8b83caeb0378b062677d89e8c6a0b03d61b13757d906fd674e8448c901cd4a0db1c5731b29c11712032dfb80ee62ebf5a990d4097053f2b9d1ec47f94b697426c155b2ab6fde1123f40285a605f3222862e6e6d963cf461c151e447c057a6d26443e7efe23510dd82fae63ea72d966093db9d95f055a47bec75aa177e1a0b415339764b834146c17411b6a3d3705592a935e619a692f7254fe703ef174f980a5909df90ab6fdc253e9d1a7eb9d528fce80c189c816727e3e24b3670801c1bfd9784108408e0c8581e61bfecd2e2aab0d66b5c26edf202bb68eb23dd1c34b3b47c464eadaebd85f261fa25f1e547174368e6998e4471cc6eb6054e222cf33b8fc255a144cb067f7b52d4dc09a19c440273b4aa60c9dba34e70ee3234319a2d8d6612c864076b44a11a42aa9f96f4ad8ed930167da8d047827b4053d3f91973aff04eb9743fba4ef3c8094f6479f4f84a9179a643a7a3e761b24c58ddda50324406c289df67081ef6710165be7ad6dcf9e11b1545ec449892a2c9a5df96a2472f6d64cedc98701201e7ce941b313720b6f9b814ac0e6b1fbf2b23196b63f4fb8d241daf9eac48a531978e245fe4930fac7e665f50982cb23337bbf5e8d37e1bc0fb42c761ae69bca5266b3a3d860ab7ee2dfab3d318095f9ddfbdf8bd17bb5493f80f8764fedb95fefa985ede1e7d402a9208c03986817463e666e5c7aea9dc29f90869aa5c56140895e0dc418bc3cfe6fd1aa194db7e599602bdc0b4c2094151029e97b1e248c88f78e46d074ff196aaef599a6eeaecbae363200fc9efe8ee0cc0b06c7b2cb77ec33b33676e0e5ed589c58010492ebab79f04", "00", 2, 1911798050, 1537743641, "7557868315272bbfe5b895285d771b1e12c60923d27b1bed7a4c90e9615d3521"], + ["a68aa32501c0bf5d6bfb4b106bd041cc10eae4306c93c1daacd5040b3bc0dad3bde00aa36801000000086a530063516aac5231342fe00291c164010000000004005165ac0e4d510500000000025153000000000117929301000000000000000000000000341b2ecb21c14f42cd14ba351ee1bb79f1cfdd4c346dc04216c5739da4706b1d90d9298fdd948ac5b7477653e1253a019405616eb4d4b16d62f6b7d8865c74764eed2f8f85fcfe672a019fcfcd9f9294fe4e519e79532cfec1ae66cdc6b7e73600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efa71e6dfb73903970c00cf3044c098d1449e39b92b5acd6e27cec406a6c3474dc9a99ae18891d8b224e7c6946d9e4d169e7a1f2cb2ce322a3547ad9c0d021144ba8ad4be65b199a84e68b92ad2f214cda8edcb37bbaefb8493da6b16dd9ec3bc3e16e38fbe8179d7591906b17e0b66449c65e18793783c41f0078412d8ef160032e01cbe82116b72fedac1fc98a06c44f812043c7b8834960b3e19f88953f959f02284532a6f62cfc55b362b133559475b87f1254fc4c3dba5de3ef3391310689a90a07162f699fbcf169d1d1964c868ce887feec9408eae609cbdcecffc781330e1474a4fef37280f56ceeacf25db6ce7ac4101cd6d5a07d7d491bc6d0dbec3751090228a46efb69346e6ff4c332cf3cb38518648951a14561c4e05f978fa46cb2f5860315551aab847623fd4007046a16a434278582fa3b7c1b3ba2e0b8b05b211bef090309fd3106f84941b6830bfb5d0a4f761fbe30ff4b2171329f941975d8269fb015032ce5429a3d1dcefc81feba75f8fdd95e1b8814fadb733145bd9e7acbda2073aa030afb45d4887ea4c377833e39b2b6b55db909c2b381ecf1078a26001208d76678f335ea3b14ad99b42935f43f5ce5b23af525f597249f8f345cbd643a6c9a4ccc5f4b48f635765b6e9f74d0c2434bf25a6e1bff0f21a74344878fc610d5d5aabf4472565a117925e61dc6e2ae5b3e397576201a203a3b6001094c80adbbafe93bd00d0029e8f445cdb51f1e156e8586326bf5cfaca59bcdb6a8bce04d0d118236f78d5628daec0479220e6cb1ad8795bb102a2a6571c1ea034dca7a388d16a401b1c3ba6992ae14fee57f7387621fbfb59cec628d325324ee37a6218bc037efdfb2140d70d92dd18dafcf126892921c4558b336228bfe28b7a11acee3cc1b971d16e80af5620b59fb49582e982a453b86e788183ac0a4d72e19b82c386a42f7ec988ebb15d1555c86bc880c25b17a32b4b7c1a643220602056703068843f7bc8b561649853494e19bca7bc65250b294404233c0217e45afe4b7d32ba38a057df6502f5ffd2a63666ead64bc090d8d1f93e3df41a3760e5c8ae17948d810cdab3ceaa19b9624560751e323d648632d1e5268159de5ec015b73a450ce343651bc9529959f7f6c5593dbba2e59369550d808151ba18400db53dc658c73faa5ba3feb2da8b770db9598850a40e76c77c655a3ccdfbf149edcdc00924e2e87ab4992924ed9dbde5f3e3d533b3993b14d2b94924f84ceee52e355247c4b7502cf12b8bff64e9c2741b0913bcf748a06135a461c4a24c8cdbb67c496b99101e834c9154938afb82dd6e35e58cc8e3b74f09ec14f5458c5602072bb73fa8a50d1b4f364f9d1a831ea68f726685278a7bb265204c28614f86e25cf17e61ed1a856e8aa6476b67b89c175ac7c43f4d680c7ad89cad1ad83efa2d702a629f8389e7992af8b4cc9235314ff911f32cfd3d1d5a069f01e7052a8e66e99343d5774ff5c98ea887451bccf4ceec26ea97cb57675480504c4a7cdf7771f306a5edb2de25143b07e1daf0b88bc599a3632826b39cb714f0e8ceeed9fd99b1171a7524b904f795d7cc1cbcb5482ccb4cc171d559e28c101ace3cccbea0c21aa0122b356db1c183caeb17e3ab3b696609edf3f16e7da3dc33b5864cd8c1e91e0b969bdd5c0a9c2c79f0b2fcbe89121af8d4226232b2a9ebe043f15b8b646459586a8feb8ae51097fe8b1a69c2f9b496b7103da7aff98889fdfb2a811cab77aaeedf010c8cca09b0daf0faefea96ea1fac0d28319924336fabac38c8d59f77d633690f4f9c1096a2bfde8ef087b8f9bf525c8a9bc615093394ad0b6cee4c700de5f9fa218b7e81b96c6870770a81bf5a720f805d32512c096f67394ce4ede900293fbc2f24db7cf6651c6a613e8c3c7554126643c907c59b6e51a3bfc42ad008332e57ec005ecb7bd297eb008c26fb4b335a743a46b32f402a6c028d79bbb2c22b4fccb88cf1d526d044821f8f5e3909f48a8d1c63dc7d8e4fb412c671d7382df5136fe4bdf34638df6ed215b37f746204ef05aaf38230e0c00fd4549d48d284483d25de25c9c759edaed7900c5d6696b293c7b715fc75112f84e8d7b9f517b87fdff9e5c2e3deb6b22d2b2fe8cd398e44c8f262155c528a807840c1f5ed96804faa53d2e2227cd2286471e72759cc7862e274a364b4e2cc79e1a1bb269f5d5c4a1347c7559d511280b058a75d18f5110d8cf7db68c80b75f83d540bc050adc1ef9c903a795fcf0c125d83a209f37d8521b140952978aa11d8df3d5ef205cadd3ad6f0a8b23cfee7a407a87c70d67bb52b4d4e07caf93bf97da77716f268f66a87aeaeb3c1da2db44654959d2be72cfa38a629f2f81b7a66ed7a23d004ad7c2564b0ae4dcb646fafb072d8f263e4089d5fdc7a6e70b927d285fe65909", "63", 0, 1410329287, 1537743641, "66eee6a7bf6dd65e8941f840537fa1e203c53f148d150724cec273c6f96f0e52"], + ["030000807082c40302635927d1259c4430639078341f620b9a723e8a76b9b04be66e58ab3d35793e0f02000000096a6a65005200525353593b86a340a794b79016edabdf6167c5361c5ef2e10ef723489fec0163e020c857e4c3a9010000000151ffffffff04dfdb590200000000045251ac521e11bc0300000000025351fee387020000000006ac00656aacac0b7757030000000004516a526a000000000000000001c4435605000000000000000000000000f5d3b729e3c5d92c30b22f4222025d5db5741b6e6ed106b7d595c0c450b156c0a5c84c36a3f352299eb1d16c2d1fe7c216982aac67f768353ea3bade4b91b91537b0d5fc1e302cfa85a59f9588b9e79ca3c2b795db765574c96f4cde2b391ced00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000db7465e8ca59957d7cbf64a0a2474ada1e12dc4737ca1554e551c6ab1486fda818d12c4a0a255f4f1406d088eba105e27c040dfd6026a668c81f969551838ea3d7d57258bb604801573c20b13f3ecd2e302ee0b2180ea5c0d66343c15d8acd456e2c906911ddb21c43a1f1ff3ed8e41472445c510df8b2b9505e83146fad114e03180852dde921e49d2a6382e7281419b664fb866c6799b48f977496cd8ded6c5f0319e2438afbfeaae214283c4b4148c383d86bdf1eeafc624c53e59b4557e3c33b0a0290822299817f70e998605c83b87ef45bc4eb6f960d41f7b177a1d29e748925f30cb1ed38e1bf6d525c604a688ed03fb65b0aae474d6e2ff151bea7b73c284c030104d33a85e92d57337eb3aa811dcc526058374bd9ddfb822e8c57b014fb8f8a032fecbaac50eed6a7c0f9d4df4d3951ef85dbc9f7f37bde89d56edbdbbaa67bc7021eacc608b039f8f99760f8e7a4b5b3662a687f0a13000a64fcbdb3a15fdbd93e031065acb2686137cb9bb4bc82ae9dd6afbcee69bc5be25dab597d4b66935c1a3e022f36349940e87b4de6af61eeb8a28f5ef32ce297194d79a05a6f8ca11cc4716ef206005786b82be3cf5635c439da911952c67efc1528b3e97775660bd3fb012250055f36d8ac6bb4a20b6ce1d3d49db5d3394265d3ef7fa66114bfd7f869de60849ffe6d5879d1bd33616a1f2e3eb2773a3cb52d3e215dfb5c89454ff9e9ebcee469fea047ec84ece279934b53c99bc69927a80d1bc2f00b7002fc391b4cc5069ccca46eeb4507314b6de82960bcfe0350a3127073eb10e2251052222d156a2f5013465052a7ec5d1b766257b703551a35f127b12f045b45f96c91f12f658baf92dc514364c9715a071d6aa5ef98aa006aa2b432fd4b63e001ca784c6633eb6455df0e0a017c60d53954ceaf609534b498cc21dd05b74cd3bd5a51c1e14705a7b11bee8405dd0fd93a29f8d54aedd629bca42b33442e438fb184f0b89c76940fb8c57fa7310daf3299f3378a5236e5c1611d93a9545272c479e69ca37943bb39bdfc15995ccaa21ef11fc772c3b841cd6d53d7b5ef3dd1ff3949c8a7f4d5427db9a58446f18b7f27eda2bc661806f9c742506f549056b5f46d3514b94c78795096ab7ea1bc7f362d42b4721ae6901fbb4237f75cd50d0a25effc1782f40759ec4557eb13af7e61fc543e5739dc384ad8542908859b19bdd8282807635c20e3cde3d3cb9a807aa82dfa6f1b7541e3d5ff9c31e019cb047b7642d3d92f69a702ba449e87cfdca76c8a3ecaba9dc563927f96f7257457043cd24abe39a3578bb064f2bb17ed25cfcfd4b394610c23284de21a70e901088e22230347dac0c69dc65d4250bb80b46699e17cdea435118895a0169e854fe4aceb66985bd3fddc76d4758138e0bd190568ce35ab96da84fec244dcc51ad648c64ce2d3b0312869e12b25ea2cd76c92da8d47d6bfba517ed9eb623344774e82f3c2db14f392d460d2c6787a58f6e9156a658540da86fbd08782306742b5545f1c96609081546bb02531d6aa5b06e1430b4b7eb98bebf85700344f11604060dc4912bb28d43b6ca1c6af71d76c4585558636a883487617411ed3b0c31c803d433e079e3c743cd4ffe64e0683ff9a18a2026fd1d555e569bf313919d2f6b5b89d1651d16d34fa1d4f98aa5e1d57522bc23e6af0534f63657b77723fd63570866a9cab44fa034ff52a0cea8ecda51e64e1bfa775526b44d93d132b10f5ff88267fe8f0da9a56c3900ae70f65eabab2669a77f53fdd4f8c1b67ecfe5dc7a46bb436882eb868f4bbd56a7cca3b146837a675dbcf6f38e9419a2a7fdb020ef3cbad5ee245e0c7e5581ea72ed12ded067c13c00af7b2336865ca92361ef0c4c924d6c9e306eeac09e0c12c4fff582661eab8c24ccf571480dbcb15892bce4a230283b9a05e1321e807c5bdf374f9de7cd0ed2ae94619d1f6e0d40bf685f0f64d37c4504ca683fe94cc8ffda355532349b3a9ff6a9bad189842a7f53662fd2bf776f172ff8db8e7fb17b0ca59bb93b2ccb0c7c0e6217463fcf6d241a23d529a49ac991187474cccc87719dec54586818b1e373e2bc2ff33c990ac6a0d629a83bf5fa51226f513dfb2e16b2b014e3998dd0f54f2c02d069c6aa8cdf19bd3758ca3830fc02e501d7461e2991fe09225b137f275ff975ae5bdd239cb07bd2db6ca68beb1e4b26bd7aea57c417d488ac9355af12b1187e18490951d350b97800f99b85376d88d22fd81b71d7ff811037bc6f5ee2ab497df5abd4b9e69f8242d6a1bb3d91fede585507a8ac399a83678a9f20af894ffb04a146262b2908596151cc51192ee71ffac6be04a7274f6cff0c74735931d5ff4c5865e0279ab05b7c4631de46c00ba147f61561dae651f7e4813a2950ccfa206e6e070e4f0e76da590c1b808", "00", 0, 1761313659, 1537743641, "18c911f9af55f4ab9bc9494bbeb9136e97f0cf3bf237277cc241d19cfb666a79"], + ["d5406b4901da41cf539403460aec01553c086a02e92519fa871c9e75eaa441467cf4ba3d4b0300000003520053ffffffff03202e2204000000000463516a51554cd200000000000665006552acac4b23490300000000016a000000000300000000000000000118dc04000000001a32c546ea7af7ed28083bafebf53160bd4a28e86be79a0dbcdbbe3102b02b5047ac8d2f4dc874ad35c748e94195ee773b833300e79dd808670494a1cf21fd128f7b81550cfe82fe8b14a96038a9e5e7e8263f51b194c036e5708afba291208e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002630b1f98fe73909be3a210ed69ab293f5f19a85fa692d3690b5b02ca24ad20846e13c1d1702736116c92fd456082a9ddb13fb2f2e9555a84101e037c1ddfaebf02acf28c385c2a7b30d4bfdc44ebc988aea04abacebd63aa5dde619301b858ac56cb3004fcda0fb527078c5c50144545913ddc34feaf3dc62d46d127d58b7c1032ae964af60d7f872a91d75bc2b714edaaf29a54b9693ad25885f55dfb34dc00c02201a9eaaa589077df5a6a592a08985c237a7929ce57854bd33d4f928704295280a0283254cacdcdcd13aef8dfa1d741f0d73b7e5d467fd14e1fed39216cf24c7df995bf266fae9322f162b413a0bcfb846701d84f8f83c859878c52a75a61eb0090216cc6f2ecfab4e353baa7344db1cf92778cd251240b0dcef5b7d062977e2643f020cbdf54e28d249e196ba2f35ca410d7547dcc5cb12991667a69681c52f7f793003117bc5adbb6a1ae95ee98dfd0fc964de9be577390026d3e5c353d4b4333e1837031ad0e665774c813f601ed6807e09db19020a5687c0c485db3247f1abd59ea9a1021b98aed4872d0c7c4b14cd5c26ddcf0628216f82a757347fbb03c47b9831d9d21891bbee9002d6b869e9fc211067a762df9db1907ebb3654a155f73b3ac09608eb3a3f819a2caab0b351cbc66bebf62ba607327f28e7425443b272d9056953180a83acf43cde159ae975b9c6ca1c2316fa178674ddfad24c66f08f87cc5de613fd251c2d01e7eaf7065f06c10c44b041433949f6f58652e356fff109ed125d3fc34558eeb4b9e7d16f544652a62329147ca8f2f8b1e5ab3b1ef33ef238c85b9e40b2fcc1b8c65981544272aafca6ab5b454f43ae9848babed7bcf5acfecce3969c87200755211f67242803d1265fd79c2432739c36dadb0a3aeb38a5e9fe65a367eabe833c8c53edf9b6b1ed5c5d48d5b46ec3a6a49985561e01372b84668f53e7a72f0c6aa791b7ed0008d04ba0e34fdd4bb7238919b0388186d449ab53ea11982c54f6a4648b32e609fd8b39bf974c639053ac035f0d69570757d59519cb4a9cc39df7c4a2fffba3b66e443a911642b1c156c3ca04412e27907a47609300d9f92316472a888e51691342b565011093f63bfd107f030368aa062973738c48c2473d0fa7c885aad4548193a8794a54a6e0d1fd437a393657a19d10dd436a56bbdc2083664e73afbfd5311cfab807c8c99ebf8b487754d5ed1d9f0cb883610784d020e4800cc1892b75c867a14b970872f268757730c3073ca73e11bb0a23822e8ced725f21d932f3633ef6f0c839f6c53f865f26a31f279d7a3be5a6cb22829493b88b1401f2bae033b24440caf58e18b4cca03024bb0d12049db7cf7016cbeb14980440156c65f8502e222caf4770904caea4d79abc5d42ce075a19b22397cb080118b27a7b7a2f2f39badd6132421cc95db38f113f70aabd03f984fdb583e6d7f3d301c5300d3e87b207e621081af69c4298f2adfee2177f8fe141ca5a270614eb95f72f747d6ce3f0c5737b20668fdb1fecaf8e7e69817106195bb80bc47fc29cef7aba783cf921716ad68201758372c533cdc9c7072e5572af6013f0ba445c13e4778eafc44d9fe149daa770831d9e282dc94c8c0be8648d5b4b921f6d24ff78a281585fc5fee57ae07cf5de6e390e686ab82e6a7fbc1933456809d3bc7660cbf491dea7c0f1ec76dc9a0e5294bd33af8d68a2d01808f7772bca3fcd9e57b1ca7c56f6bddf318e638026958e498b23fcb148d0db4f53ad86fa49dbfe2d6eb9d62c57675b21d65a3c346b820bf71759962eb5d2039067e0a019619fddbcfbdd88168d3637afaf6f102fcf496ca14681f22885a12aa1a331f66add75fb992f35239583eef7add1bbf1b540e6bbfd4d463bf7b3ab1423d690e01cb0b451204e33d7b12e3e496418337a4f66220ecd0c1763158d69088477ea59d617a4be920dd127685ae4e5eb822ff12c561975d4f17e7d861a65b847b70bd9c249ca5d0ca956cb7313fc9f3a32858a947868fe89a56641657d0a9e67ec1ebe1109f1b260c2c9c183279adfb97c477feea88de23e3b50d5ce49acb9599b917a75c6e94afa96aa4cebda9b4a10b7640dd19b5e3113ab480f33ae30f5b4d3ac0097bd15f8436c7ac42faac4021f4deaca3739fc90942abb319861da0e20ec7163a12ec05f8c8bdf35d1fb253cf428b2d2ca56c955b4a740a0aa7f37cb60166edd138a7bbeb038101471a21077ef3fa26d67039c7caf4b7deede53950e9506bea9e8188f94ebaa9a9ba85c8846c79908df91eddae11960adacb7147f020000000000000000000000003ee7b8d9fbca4e23176b5d6d71e2867a1da7552860f1ee11e77840f6704d224a04fcbb505d2bb9c249ae08b3e665e2f5a688e4b09bc4f105c7222636c5543f11e02513df439dd3d915640e529e972b582ca98a873e6daf06061931a5b1caf37500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d431dee32a6ce46085a87d338b2066cbed93d5a5f952ada82c5226d2a5afec47b0fd09bbd7148443613b55785561517a1cb15581aca2f455860349ddd7eae8fec710b4a9ab812dfb10b9911f0637369e2f7faf60732e0e8c38a0209af8a6437a6a895022366d53d84b9707dc7035834077d44f94b3666b9ce70ef417cbab55cc021aa841e2ebca89a1b6a1607c8a65d86bd2161eb550cdf07103ab8dff2a4eeaca0225f1ddc9fe9e2046d021fa4c51ee4d6eb816de8c2fb84b452adf738f302e0fc50b02c2c9ee9f658430bab196a63f38a174ccbf0b30e28a51ff02ab4a8fc5e40d352bda61106118d7c8ce01323db544fa55b9e4023cb5f9371eacfabf8b1760bc0d022b21accb5a8491b0f608d54a717ff05741294e4ed3f0dfe097b152c7fd58e6b0020d5aef03e4ec45bccd9166bb12c92683d26d729e5c94dec38f657ece7619d558030c715e346be63f696aa00982c66510d5b0970bcd911cb2ba06561782eafd4735030138378fb267b2f9d18b33592ea3a24cec62d5b58ed9ce18aa89bf974c84c414021abd38e6caf8d1050c6844c3b1ee60f3b27144a5e406bf44455f88037cfd4da43294bfb0e09e0e4b441688642d70fe3bbac53ee77b9b53ef6097c2f7ece50eecd3c0a598fb067540c2aade8b48879892b29ebbd89259b8b94c577d0b3750b0e2d07ceb9a3f96b0742867d7aa8cae4c6ca868b69433fd085b34cf5d7527738a7a02d27509c4dd4a72f98350aec863f5ad52754f8e0a8c6b1ff6c7a65fe9980397ebf27994d70ae9ece2ab3d717cf9f598e2e724ac340547286ce78b7732a3d9070a22112f5c96e095479d536bdb09b0039f6609a177416c612660ba858cb7000452664c6fc8ca2e3b900740da3b52a72c43213f5708c05dea084b6823222ec42a4d132bdbb604ea7ac5350d6b524a9d10bb6094b9d4d4bef8c6a98317bb14f7678315f21a8e030a90fa721a23fc9c73908dda934b92ccdcd2accb398fd360bc66fb125075170d38e54432ec9b01444224e5075c4bc8faa8d637e51ac8dfc6732e3ca0a20ee98039dc171a8d91fac968e795658b1423295426ede1fb21d4ba8357036aa5f73a380553fdc4793e4da04e5b5365e6359c4aef50ca22335651541a19f2038d2518c780cd18ef004881792ab3d2fca3d4c79a7e769afb83033f906f182083046b2b27c1e5f6b599f3b1975935b6fe35756b49c7a4a3258430a4ae89041af62ca838a22e1e6b0a19f75529c41672f6c5a5e06d051a8c944b583a7af61cebaa7f1c68427ec9dae4331d5d4a6be70d06b065353358c6894bd85a432c90e9e59c136b036ece01e4088b7b75b41e2e27a3d895e6204addbacd471e53312bf0bbe3b3b4bdf56a4bf390aca23e69980aa905f01d7ae74af54e39cabd15648e602674511fa3e771441664c48a0419478f57e0f5b0c0f5713dc260b3340f83873ba5a0d2d6d695b910c69f049b2a82e1ea2ab2fcc1b5b7e120c01693629bac77864d3560f5a62163e0ac539944b74890a2d60857739a60e251ea23a70e6d79b45d7eef26782f4e03b69222d13d0641d83daec9fc6b64a0151be8f0168ce24fbd10089e0621f7c6698f05c7e992da0a9729079034be8d63d75a3f041aca3e9e2ff27dd7cdb9d1fac6eadd8bd12750cff31c566567d9f62554de13fa6a97958b03ffebc7011b31184d7b1df1e32e9aad0ebea43541ddaddac340e0ee6c8fb7e3ee3995de1c4e3bdad373039f45a2b1f0b2ceef1e5f00431073771edaa6a7040549c1af19f86c70c3b89bdbac1aeef9efb7b942ccd072e1fad3161764f99e4ec763be04b9b9cf76ffbf679e1755cce3679a3f72d60f513de64e565bc68bb3a0c4f5875fb118060cb0e4925bd810e79184e9b7004eff9d6cbc7f8b6499b55c0a34108492fa42022c8373d5745d88ef0e343101d0aadfdd33096c491aaf5f8cae84aca4ba587101e1478b2aa79663ac9077a6ec0826b925b2f5e2e53c51a377aa4024d2284ce00e166c44306feb160cdbcfd61d5656828a6be2fee8888c3ef95e2efcdd554dabb4c3230f3d6272eda33a7db943ed94554ca7dd65a5d0a0c7a21834fcb6749d151be2f2d372ba617a056f6444789539c9069260a83111146fc0aff3cfec648007b378c019aa5fe170b97b6df5f3ff84595986574ff88efdf7b14220c54fa8eec161e644cce744c9a9d3d9913445de21c1f8bf0eb96a9168dff0d9f0da3d8711a76415af4b76b4edf6f151f1e995d0f98dec2d0b6f4529d6922f43cdbcd9b573b5bf45abc6b5ad54f892925a44f21559f966a001000000000000000000000000350623a9218ab5969108188f01c7c4c2668e49bf9a86d80b1de519a7928fd8caadf7cf5c914bc8b598aed0c320f91bba52abc18e106ddfa18452580071d67045a58bb855b2c496bea31a9b09a4948c2017c1b13484dfc480f79e0fc01ae64e3f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000125d2a7663c369b7ebfb78bae9fcdbf89631d718a10dea16284ede564e7cff47a8de64df79d287bc450fef9bf098cf2d9e42332dc8d2154607de7f0bcac6e0b5e1625a2827c9ca196d296654e56f45050158f773d95d02221814236bd4960ed013106ee466226a988aa89a2e491677170810b453e28ad423567fb38c19595134032b610026f04b536e88b015f35a96e4921615a5c59762b8b81793d31fb200e5d50212da5c887ff81895574505c1b34d148eba7d6e0f1f16c95f440e4ebdd154a19b0b01500eecc46d26e621b5016d396b62e9e3d7375255105f614139117555b1063301b918ab6b63f62d1f06dc00fa610f56f9f2ae18ac94f83e228ea03faa70d2f6032af583e8b42d0dccf1871b4e393a9e766efa10cbf0f77555ffe912339c8c9644022ec78fa9d86aebafc8b6f9421c431c7aa50c67efc7e6f9cd4bffb1470bbf527203032a59a735b6723d17585f1efc159a5edc3c6717ef53a52035b872622c1fc6f8032750d205d1785354dfb2a4d017b076530548b555c754640235264fa795512d81022b0a1c8947e5352c2c47866413fdc2c6da9df68da8a560bbdfd91775d490fcdbb483dffbedfb5d28a4c789836f5172ced89190637e1bb7c8a6ff677f8e7a304d32d930a10e1d80a6df13bb4a9f65cd6c409943161f1b6461a174208356f418b78bb9ead7d549cd21ca3e7e413d9e73726173e24887dcfd69936ea8b3b891f5bc3f445bee037eb2adf9481e829641e7e4d8e188b006db9376d00f1df99ae470110f9a9918b4df05a77a1ddf085d3c66ce8414403ae2ff8633c750cc259430fa74a912ecc4396f58f02b3b7a0b1925038577f29ef923f299313044bd45f8bd53992c597e678cb274ce8d1eabeea3431039e299342ad5a990f9eac5f511a5fffb67488a66378e60075e64631cf6a08fa68f9f34b2a2ba84825dda32d6cd6a3fe92779aa7674b15555533b33b415559d9efca55be92b44d08b559b41cb9fc2a085e03bbf12daaadcb285603a1cac94169a846fb71cb2b40ea6c8d998bd9949e03aa19cf584edca475dc07d3a6a5db79173bd7c7d52d8b3415cdc61ddcf2e5728b11fc6e294c04bc16e2c72ccb689140374a7fec69436db9da997b6830fda8d43bc5023bc323b7ae2819c5fb4f4bacfed9b7b758ca134280889ad3beee7bfa651b1a8dd3dc9cd34b4b73eaf03a9478ced9b348d2b99dd1e8ce1d7fa1538cbad9aa8c61de487b46386661b310074f080dd107bed9b4c677b7bef303e964811531b9289c77954f4bd07ecf3d309e2571667b3816a940cdbe1878a1901dde939bd8a8c0e6f1fb252a9230235bcbd91589349b376de24f3809fdab11123aeddf3b2ecf9859da3d7cc5db59f4fa68f6be59a3546b7a8fb90d249a9853a9e67c59e4465da2b3e3883cd9a951b6a244258ef5a1205327299106f7996c1d268d8d5916ceff33f5b8aee2b3b41953554df4267396e5c91c68ea9900d8e2c701be05e2434c8c66d20ece95e03713834c2a1d6d2223bbeaca0ab926403ab2c3336786d973d3e18a115be2c2de321be7d2a4b293459e6ac336ca3304cfcd11e53e401912fb747c52e145bf053e055e2e0be50860ff6f5c37e052d1100ec05d6cbaa111dd528838e3b50af86ae5c195f2c997c8cfa00a46e6eb8ee1c0097b44002ce6e309a10038ca29d24badfd94ada15433b447ce8c5ff11110e08fadb156329cf61a1470fd920ecafd65dccc2646431c9c12cd6c3be755deb669d66eb55ea5beac19b74ee9bce51203a84f630632316d2feb52875a04cc975c5db5a969cc64cbae9e621a89f44d004397736169a0b9fafe5dc72057dd0ea69ba4ded9e1bc209b970fb43c2f1741aedfcf0bf21f0ea7d249744c6d974374080ba1b4c9095815c453821edaf4b77ba75e37dcbb939cb1988b581c49f433185b5231ebc7c1ac83b5a768cb06106d84d8a8e99ecca4296676d3823123746c6021d81a9077246fa566aa488345f7b2c3c382dca435354178292fd6b2e2aa0faaa5d7373ab41f338bd8f18a8cfcbb7bd108a339099e1b592deae075c18e4d4619eecaec3d16f53a6e6668b9e54a5c3e071ceea3273fe8f6f55c82a2bcf275a420cf2b8530dd69358ea32059deb451a8b3a2b617954e77dc05de3099ed2d7d11eb2ce757f19307885abd9ead2b6174723b788437074aaddec0f5ec1e342dda78678addb1c193d4608553e19d2e366ba6bab6f314a70cda22d450e025faf09a0933b772091a9f0c7f756dd6c86153398423029946f9eb1703f91636d6cf85cab0a55b105ac449cec0cc23214ac87844122296b44012dcd96550276f39939b139b24b3301dd99e4d855be3e6e903ae61109248df6a7790ea27620f06755b3cfbbc0feb54e9e3afe16f7d011126c07e11ab88ffb73d2f68197d8aacb477b1f8e625a588a07", "5251635363", 0, 2118051687, 0, "a30ba7de7b669a3ec76575d3b1ffc2f21c9468a64ee1750e3fcaef2ebde44f84"], + ["030000807082c40301207ccfdc44517eb59f67da923ce209ec570f7e4ef08b7bc9ddcd53cd394a2f3d01000000086a6a65acac6352acc8ee4383028847a203000000000463636aacbcb618020000000000000000000000000000", "acac", 0, 242773124, 1537743641, "bb20450698879e86147a37155bda8c90fba5438d9964f0db306b156e9f06baca"], + ["030000807082c4030380c561b076f927c99b0d5d8614e0ef3303a5b45d6a099b56b52ff7b0b1a0239d02000000055100636a650235873eb9742246322efb7470315de96e2e2e8c63b00bfb0b1690452ed8016cac81247c020000000651ac51656552ffffffff7497451167af1c35b68c17fe1a7ccfd663e077c8076b9424670b10fe9b6da19e0300000003ac636affffffff045ad0dc00000000000265523680ac000000000004536a635318cb000400000000060000ac006a5342b22f020000000006535363520053481ee18d0000000002c0e2ee030000000000000000000000001d2a4acf7e5eb93cfbd9dca60578269365b4eb99d1330fcc1aad169ca8764404539418a20c1a6e1ebcb9cea85dff8a538308ec6f4a6ba5e2317d884b74aa07b0400a14b5b73aa9f7ffa04560474cf8d0f17fcfea5f48a33a45ec68642ed99e9100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb88505215b67e07d4d1f35c025db507632c7d8e0be22229701d0584953d2b540e170fa1646e1ed4ac81a384b15cc609be1e0be7b76d82e5f6e74b87d8ebb37b4975b4bcf5937a623517117224d6c0c801def1d121a1b9dd070ea1ae1d54548e747343c8805c3d959429949df1051ce4b8c1ad880cbce2b169ca8a3b729d0ed8032c67d89271015b7663b2f5f389f57d507257667a07454cd99c59be591f1666a5022871bb6e5987929ee58fd88cfd5d1cee99d823d91eaddc5f62354ab18230c7a90a03929e5d1002ce8308cda70c5cebab14b9494c759465417dd989697a6c5fb3a3d19a55fbdafee55ccddb8578b4f41a746a7de9b6b8862cc000c0c6db608145280227ea04edab0350863dbe8c1fc7f8018b34ca93cd30c7dab3ebb0a954cfc55c0c031e2c75bd8028799f7d7b98d09c871cecc06946889c4a1f2f4776f0d503d9a1c8032b62d51beb9143e239df4b7191a89c26a2500a90ad75119df7de98b74af891d203195988b8349335f4a9927dc05659d7971bd4f5bba5dad294cf926e10c255796b03096352a2f4ded1959fc4ec83c461e59513deda8f1b0e87ba22bf64093330e7df8947abeeb5a769cf256c23c07e7aa99217238a6b35ec6ad56943fb32d5fe2ed998c2c8dc89f54d170e97d915d7e2547988bb97b52aee47f627778c432d978e1cdb2a2bf0115f970bd7a67d0300b291a96e50b8bbb42fd9ab368cea3c04e0124ff874900ca66f88823570f5ebeda9f728b50c7c6765942ef78e229d25f462ba299d2830918c45922a817def26f1f3c67268c98058aff72f8714a2978c720d2386ed1386e7c74cd02c009e1079d5f97e23c3ad76d1b279ddec9de44e6c672e99101114db9d2d7862e3f5cd55d3af7fa9ed5cf2edfedfe74798d4922142ea1a60e0d6a8557d5fa458f57cdd65d6b108a1e7bf628602020c9ce9bc0a345b98ed5fc7c63247a057b8d705d1be8290beebc10fef63462a5d0b08d7c46d3367db3ed78e81c38b3951dc8fc9d61c8b6948e5db8af9ad9c4fb4388926fcdcb0e0d5f87ee8b3a2330b1e812a9ba8515635efc7764079cdaba1e3b61708cdde61b99ce8df7c7ddd89d743e4e8aa1c2530b5835aca6bb07f98412437ae53803d0a6bdeef7d4616020c180a5062dae4c3e026de49a409c414295c380f5d7de6d233c66864075352a95752267281e7f7c570fdc3e67e86e281ccf4dc316123210493ea75e726e11e327630f9dc62b47367c7fc5a0b5b0601bd70dea6fff61fe49535704ba2debc1671ff3ffff9fa9369b24fd12db38d39123ef6576cd246dd23d587377d0693a65b31eb6f53b95b909b32546d45a7f4971ba44d91c6298297c1ac953d8fc336ba7241b9249219139793cc49f79dbc579b5624d4c44cd9ef4d96a6c62553ef191c5257732741974ea3d02b34196a13a28e6b27cc851f959cfddda304e15b0a428c721078f484821bfd86a30ff5eac1af4e597b099720e3aa1d328876ec23519643798cf600c6d1e0e93f945743bcbc63158d339e27118726f592f3b72e39fbb1e3d49584949ef795a323945255ed1cb69fb66914724f66a51b3cd9012a6a6df436316fdc4cccf415eb64769cadaaf54d905b58a069f40300a9301d9b5c4e9e14af0632e0f6c00f49c70ecb92ca2b87b1cffeb91d572083180c699166dc5003efc4684dd01705e175140b4e69d6873b0aefcee732268474f59e04192218ad24a45830cca8f7d2260a03ce51a274426229f8fab454a10998a5ead3a0be583ca8f2b49401c9c2df4378997dbf1eab94e25d4d0c31984cca5e56edee363b1a0a29be08de240747d6a2ce83da9a31fd1731bd9950f050e6f46b93ec23d8dc8c7e5559b616f78104f2ac941c8a29cba2d9f299fa90603294ab7165920f85fd3ba398ca1410e517991a19878b4af4c11736fe6e2b3d960074428a0fd422ec47d230217f6c090a7f5fe84f742225168bacc2dd3688bc70f596f745068264dd040daeabc01e9ab7fcbdb552be5784c8ac86d56eb6d3510f838028aa06ecfefa23c729968a3514b10718a4ea4be26c01a534d7f0e67c0d96949e4fe1aca698de351cda0a3d707475cbba7266cb6b28e159171ec99f2bbf86a5ccd2e882a727340df93aa4f84a2169f15a4c7bbc49d87c571b4029a6fa404c1e7f0048b4c0eddac99ac7068192a559b6700fb121b1faf0f06d4a48f90f6e4b900d2322f3653bb9db7385956c6df9597728ce8f210c05229371cb229e4c0ec61aa14f92b74802a052220e7c023146748f2831851a8f292118ab2301af0482e100000000000000004e213603000000007964de940611fc75642454204ab1c75e2af9846c80991ab6da07fecffaf3155d88e08c096dce73bbe19363b3ebadbc4c3f8adeb3590bac20f173f7eff772d19abb8b1df8bb33fe56042b5a4fc15281801d07a47696fbfda06e4895e68df11ead00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a7a44af55481a0cff19e57f2282739552fed296521b4ccc340e822c19f6502d2971f9bd1e16857d6c304cf331903caf080760b166579d4bbc48246436bd8d5352aa5c340a45726b79b3cd11043b3d53d09390244999b782289e3d7dcfe6a6967d1d7cde3e6023a520dfe7fe6e256f6fac5c614cdccbfe98ebfcb755c8161db1602025c586fd36f435c2bfd144bfc7051a92d7df5e9b792fa2c1e98424fb07e872c021b09e6531c65bf5d8c0d25740cb6b051ee3c3ca3d04521229cb0dcc0e034ab520b0897deebe790616976dec61d445469b619906ce7effcfac6fc0ff13dca07d49e541a22be0f07655ff642d99694acbbea7702f1c30f6c969bbd876c20b086cd290311f858ef12d626fead052013094323c1ea2cecd821dd4e907e1aa314586986e802297e027527ddcdb5c044cb61bc5cf9e4dd10c2b2e2984620316c3a04f5f782d00328c1ee4503541da4a568a93dfbe4721a838b14e7710b2e6c145d1a7782f4d12c032a50ef88f3a2c293ca7bc7af4b2e8043f7805ba57de3b9d03db8d38a919ee69802282874db021c1b7444a2da96c6cee38b029b9f02699cf23c9666f5f692b4ee1010d55524ef379c7a65530c748d4bc505ff4fda693a574e788227dd326ae4f99af7d10430d60ac6738f79349517bb69fb1469fa681e7f438188a8fd9b6f2587bfc644afbe74145c36801b503b14c0d1d7cf636aa09bd38f9857ecf3460e3179151a2a5aa2470b740246e2d712857bde6c83cc32d80543a178b06474ae0369a7ea0a852547ee9d145e373ee4fd21b7dfa6e50632954687c04cfdac4efd91045bc0d344a857a9ecd5d6898673d6dc97d3b0cb40d2fdf20497d9f6bbc31ff5a6b85e1a09684e6818de533fbb9037015abd3cc713b3b0ffcad00a0795d530f1c413ee635d94ddd7a184721c2827aab3fb70631bc0f670cf48d1f1393a902df4d2708b004d465f9ada6401c836261deb8df4384e08738fac81493ed6513430427038bbbe309b36c3d41c30447dd59796e0b45066fc60936602346699c9bdae4d30ebfbcfd9f8c594c41bb9d6a001e7955f52f4b6750b73fd6652e756edd594a75efa253d63ffa8ec68505e224a5c8d04adb7403b8dae0439c40ea75af7cc2e66ffaec6aeea064993b0a9f7ffe984084c8e7092ef9b9f06e97ab07ac3f4a77b86fa41372eb1f78a67a27c87f97db75597eca6a6901b2ae9374f9ab49b608c3aec94072e99e7ca34268b9adfb345f98914de2d0762b67918fd5a6dc3d79b464c12c144fcaa63c9d5d4515a825af36124c669e3a5e9b5d350544e3232d9ac6cd523e87285c702ab50fc37ccc64e5654e2d2efac9315e3d051c34f66d3667481ac800c09b475d06e8ed4bb644645c58ba5706732fd0c94d59926af4be0f68be2d401f4d6e094cd7af29c5a3581608874733883e3fd96a788c6ad7adc8d6f071ffcbce1c1ccf81ccd820f0557da956d87aba693b6c5ba37dea9a779463b20fc54392c96b2541f122e518a40005e848f155f95780a1904aa9b917774bbb96ca090cb8603109aba1603282a8696bda4d3296fc51ae8fe9fa4a027d4bf9bc5d359320b4780c72e4a656cf23d6ff47530529f127afee6cc67753ef7a62baefcd37fec6322dd5d22ff945f7a9cbbd38e1eec5c1adaf42d07026e484b2d9cd49cd911bb83d3005440af7b9e1a1c87734dfac29e1538fe3e9aee377dbff8485aef1fc7c88cbbb7da821c5c3cc2b535b3c558bbe81ea19cf27fc0076c9130ead5fd8106ee5be00365c96ff8b881b4538ae0258c21cbe4eb084b3e7b9739e1a2894e0a3884bab1eedd5d3fb954da6588c54a59c4a2f92ade0c6d8a64c1d4077fb93ddbf16de30795603c77b0fc608627ab0d0cd477f251936feefbc8d9aa62fbe7c65858fff109d69f4f910fbf97b9f242a23f57295e78928b8664c2c23cac0f976345f5c834fbe60be705a1fff7aba4193c62fd7023d6bc4bc5f036c8a0be7614b044d9b5a767b5a07e3aad88cf833a6466986705efa6ef890b2fbb79d4896a5abd29a0b70637ac5fcc6050c5953044018b623de9b00c55dd36bce8f5d178c4e54be4096d721862ff4dd4678e624dc36e6be5fae491d6ec1f77da47eb6b50f3c327314a6a55395e7949cf7631ac45b2cb9836e4c540d134a9f3ed6a0179e2e7318458ca863447a2514665d649af84727e2a4aa9367a6ad34068d176aa11636e0025aa9390891dec9a4a31b2eedc8ab99a9d468f3a50295986cc41e32d879c21468a275465b1cc8093f5a8b1af2c157c61420b8132a8ede9fdcb7b9e70b8377872ad1b625da24495988975786dacd7e4b6385df89b7d071f4537ec31da746dc2ab3038c76c39a07142a90743cb49ccb79fbba82df05e263d98eb737d1bbf623ac0f3e035e7f94cdbe4cc33afbf92b51120895cad521ff298a900c703", "5351", 1, -845608365, 1537743641, "c9931c176ef77b9ad2c709533b4c2b187a65bb6e6a1592d9378d3e7c53f6463f"], + ["030000807082c403043ffbf61c7f046d55a0ef44ff294f71499f14403b530a9ca0a622ee49759cdd3e0100000004005252652fdb2f7a891207a2f79ef243c5cd312208737d541a81e548d97198940ea3c9debb289f3c020000000600656a5253528c381d1c0c0a74a992dcef5d915fabc5039e1a1d29d623b58f190f59ab9ce7d6cf68f2bc000000000663ac51636a5148bea6a47dd61e35fe5d873243681e9dadd5dc91ac78b53be71ce2a3bf403399fafc83000300000003636351ffffffff03eb70c70400000000056552536a5289f7cf050000000001527ccd79050000000003536365000000000000000002d299e102000000000000000000000000cc259c128e83ab2e624023d64f85be68c460c03a93f67efcd49ff83d114fc9a506f4ff4b851ab9093af8ca9c1202af3e13406eadb23d131ed6544d98a276ad1cfe929ad28aefe697923ba01e13dbf08e8fe334a70c4d176271a24f511512e284000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009ae11fbb6952f576a62b26b05736e58910fa7716c05325499afe3d62d35996630c95b7435886b0583c06b4c22aa135db1d913e334f15680e294d0d6e503ca52bcb8052e48b0b22a86040dd9e98475f314653422989204c312fdffd3aa0a7273b4bb37074b23a9b3a93c421fa3cf2d637e72d71d3a903a11c50edfbbe603b5129021052c166c55a106a45fc5353c839e4d395dc6ffd4e8ad865b711df0c18060393020345c3f5217598013de69ea581c91fed0a5392cc34064b38eac28268327590070b07a759714543e17bea895c06888e5a76cb7b5093066586cfe0f8f23f7573e4e6140658b6a9e844a72cb75da494c1b98ee4e842a9af529ea81365ab6eb8710b3e0211544fce9b3076d68417c172a2bac7b3af0faa11538a269bf6eff5aae0eb0253032ffb9b38b58b6bb23855d1057f337c7f32ec2ed3dd360c95fdf828900d0e240b030c01d3c91e2e8eacdbabc3a94b555eb7553ffb52b45b873ff61b0a12322f1a04030332e3fedba358b2022ef4618df63e862f8a0e2ca7e597afdda6e07bb07e833a03182793634d26044ac69de1be5a74e86984fb20f7a120429032d438cc853be5b0708b1ae79d852b40472fc72d13d70eb4d3658e601b1956fbd44afbcff773256ae61c812cc3b9e05ba2d25f5db0ef62bd019944da87909987b9924b3a5ca44a1412b30495d6bdd106ac63361293e1005953f75c5d094b9f907ce6a94535a9b5a895ae0f0768031f5cfca6b9d7837d05073f6b474912ce7584f9593f2874154d9e1454e4b654f9d2f565f5dd6fca63aeac9f904608294e55175ca2c75ac2859a42b1d84a29dde727325907a9faf8f69ca7970e19a9ac062611b0974cb8c291d184bad7e7ab981e19e4abf8598f6a19b36cc602102f951596ac39b34be0018b6cfb0a31fda38634e6ea31557b096662e0d7d170e843acd48db1503fcd6fcc64a8f48ae3a2bc7b509ea1d3cacb2e217b527c96af9421d5e3491497481144f196307b6fc2061d6364b641e8a09a878cb52b953736078883718751f06b2a8493e119f75e720230821dda70b19c9d8208cc298cf736ed5c98760064ca6b64eb2453901f8581169023a1ff396e8a6a049d36e0467505a3e2134f1d9507b8991ece65a7014c3482f83ad1214efcdf37d7040357bfe6c5883aa4ab7760e6dec827e54ef91471826cf78ae594a2da52c3049a6d1dfa53cf5106463f41ebd651449eb8e3df359ad87f9265b3009e6a354320108e4e86150678961be45388ee47bf0ad5ecee63a498fba1a1b0e9f2ca7c1cd5593d85a14576dec13df9f705b3b88158cfac56762ff82434dfc041e6f2920da766f54e6833daab56ea13880f534b418c13b97b62056f3ea94f1fb8cd902cfd6bc77cf1937e96da3d9890ef62a2879d42c606e7a092eb57712d27fa9d0b192226651049d2be1c1368a70acbcb61a41a1f93e0d6e9f644c1e27984ffb1f6f0b42e656d428a5adfef0146819d14abfde0ae89f03e9b649e170c462199e6898cb118d7e56620d1dfc3235ddb6c01f0008e6b875678f68d82913763e3090d4d92d92bcefb4d001aabab80e047677bee45332b7a3eaa68f1551e0ca022b95b059cef07b9d4d462b5767444d00c096d096f4b947ca2be60562483fcf5846bde864ffce009339815a4eef07310b0f9666e232fe2dc4d0fefd85a34ebed00bf51f6260b3984709c7ba1f8fefe5706deb87b846ad56095e7f86544ce4dc57682bdc7b8277352dfafdde27b277708e82d44b452a96e8dc60650ad71a1c59b5aa664a02d9affd8b99cb082d404c6637b45a13dc16b9800726ae2bb424517dd849d5cb49086c8c6c56149d2c0e5e2ef11279fd7cf030a67ba087240a9ecbfb3e375ac3df682e18db70e4783658a70d27775443b7ec15ec8e4c19a1ac7407251132b002578d6c1d37729935e2101a0522b5effe49cc96bde875b64c0b9bd16fefc91095e03569ead4f089799e930db503a37997b44a5087f446448b2cd9304293650ec78a301154d6d2bfd222136dcb3d9e2936cf1612a114550ca333d3baeb5680d3b9be5d119ed4912cb9f1e2b85eeaba646c076076865a705e1d10f5cb782fa3caa9085d8c6654d2bc731a4dbabf5822249972a32cb009b8419cd21930b17fb0a461e79e9e28992598f637bdc5c36d7836b40539587416d1b9bfa22b7bfb7060c2d2ae1d607e45f2a2bf3608273fd6946b16b9af3fc93a3c79237c540852bafe6d6f0ff07c88e3849d2c01d0c78208ae7eab46eacdbd1eabf55c4b51eb69d242a79db1ce12f4d6eb929f659ba5c03010000000000000000000000000c41c2a3e88890078613bedbab34b4c35d389d48828b8fbf962ac0329c4466bc1117b257b7835f46b8d74bbc6ce5a663036a22041a0e99abb84a6aaf213c5367b1a553f0f9fd07cfea62d43b02a96a8cb45baabf6fb8a175370e8f61c1923f0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e071edafc72b583b3e3c13ab412992df59b1cae1863b0120edf6a1d5c11260b8153dc790721463b6a6dbbf64a4f81ee3d42d3cf9748034f837f0d5de23a089420cde7795fe06fab96124f8ed81ed18c01391d1a793884989522b18fdae0e005015c6fc01e2a05f70c6a3f6668ca7f1f542ef653a6667b79bb2c3de09744b90a2032075387f02b409f43911695d6407c2fd02599ea3356f33db2a1452a218cc38410301652874e846c20b4c923b73bf589c5943bfd7ba2564069b9c16696f343ffa020a055fef7d2a387ffceae278820fef5a97a7fa8138349f03f87182a49a59899388f497629a1add9555f5e20cb8463f1b87efde100670283f13fdb6f74abbc93317022331917b5ac6b6983dbd6a881aefb11e596983f504ebc159d8e0ae2bf7ef5adf030a04b3f764a5cbbff3da1f52304074050104fb3d7a0ffc3d1024d346ad97d80602135d46593ab0ad13fb0bf9f30d910069a5bcf0863bc4b5213743f715ff1ee762022ca93f5e7a7b0a560f5592980b67599037be723503fb32220aa9ee32105f25050313c0ad39a6efd5da68b5eca945eee2430de1c753cc3020b1fdfecc652a32be3c2264dd9e78d4675ec7b80019e91e52c5022bd743f09cb086fb68a27d2f7b394d5c3bd600f0f6d90a91cff565f2b31d66141eadba69544bc04e1e841a9eeb7a4fc01683dc7cb230047f218d7e70db90718f0ea76ca35a483d295f84cea70c937436286711abbbc8178698f36b361c9ea988cae88e3492f456c66da62210355857e7bd78fe7bf74d2c3e575ff6c639975e2042bb6e24cb38a104528039c7ddf69ffa48839545a69f9e02737d6557b659f0949ed3a99b3a88f88f52b9e20e8ae7b1509aee44b189ce0d3866c3718a89f71ea6f43e19f8d06782ee4c05dddadaf82d6972e8b29b892c808aa374d016253bd3edf1a93740ea3aa9b955b9d072c3f5f53551988e31eb0a9275f4cc8b31b3cdff713fe01a3d6baf355a8970e945459ced5248ff1da2d0340ae6f694399fd6f358cba713e74ba5401e7820165bf67037f54a66e6768d0ce8dba2189421ea04dc9b1d1b2246d45b0e8465d73bff0777fa851bdcbef536e42dc644e3f141b0cf6201ccdd39681e4c3a1fca9ab6dbddd95b58cc4b04dcebdeaa342717ef677e422de92619a163cfaa8bb332e28ce4b746f58d4046d2b94023073c48c2bc7e5481c9a83bf68464200d6c1d3b8adc403a49183d35bff351461febde6f844cbbecfe225a56c864e6275c63f0b7b15e4b33aeb08c03302d465fb86ebb674789624210eecf606a24ae50a4d037c1a73860a048d7ffb352dd00f3b3c459c70fefe347413830a3e028b9e7d9eadbd89e26edda1c78a004f0df6fc56317933316e3343a77a02b2524bac21acd57a4fb731e20baab5ee3663460af57f626071ffcc12a66bdfe70b9004a490a80bd8c93308dfbc2fc1a2a48c05c470c21d8569ec0380a9cae043bbb3f2d6a43fd3b8c8695c35b003cd3f75ac25c62bef6574435c0180a47870a1b1823c8525942f5192221d9118b8b837fc7013bd099dd9cd91e258753cc2086a373b745537427b00115fbb51fcab09a2d97e46259a3deaf09447cf19f7c840386f40c559e82b57e8ddf217d92b6a27b7b083b635464f0f69b87643561b83082de8cfcb9f82d6f2da7d551bb01af03b1d3bd33bce0cc20de7229d9dfe327f3923b127baab2a6a8acb2a213442ef48f4042f16904457910b54e227100000d46738ac06694491edd0549dc7939a116f97d861b0b7b7190a2b5ed039bd253ed3921d93f242047584fccbad54c07c2005bfab6b85ee33841a2e4d840caec72450f3121b0814fc9930ab48a0714f86471e0b4fa1b18f9c4254551f515812d4d60ff9da90c5aad123df7b7aaa6d81268394bd15d37ed718131f7f68af2895227c64422e3807653f7368f060cf02904e33d2c1ec0c335bdb3874bc5fd8b56a0b63963a11de5a54a108ad2516030325a6a68e025314c37385feedd17b424d4f489281b0614a58f0ffd95a3dc656905db1b6aea9018151478ef75a04a44ce77b13af9a0640a07b27e33b38a4ce227cd82b6d31febcaa166711bb38d76ce81ca59e0012933cbe72c3bf477be0e36d783fa41d3614a94ae070cf9f2a009395f1dcbd2385706e0f9f49993eecc0596b52f70a76f2e9f412a1f929417e50a63197e9b7b43f72546eb5c47e040cd969b98dcd0c5b8aca0e38270185883390478bd3a9ffa5496691b6ea73c1367245cb0f3c946caabc5f3f519c17048829aaa10249e6f8974fca56805365442dcabe75315a7275f7180c70032f94a90536279739186b36333c839e87bd36a36d27be38a35af65992a0aaefc336d4a14a5fd0f74373fe7682d342b63d8a42d30f07913117b545273a4f11398e0bdffdd768111cdd8b6bcb63c0dc8754407", "63", 1, -537474924, 0, "4d9cbeccbe61f6cd29609d37327f7855a4f7d0afe48db438bc5e8c7e97b6ef1f"], + ["5604b67f01963e10e1aa94d4f83afedc9bc19e49b591f387cfebb25dbdab42c076d3179665030000000353acac0c5203be03aa2fb301000000000663526a6a6351ff90ef000000000005515265006a27089a0100000000066a0065ac53000000000000", "5252006a65", 0, 1630946853, 1537743641, "438cc62a94d6df1a707d25d2b925bc37aee5a8ea2e97dd6a836b8c5bfe4b7fb0"], + ["110eb45b0214e1632a8526b3e71905c5174225e94edd0e11b555ef39d4a7683dd6e85908ff0100000001524c310f209acdb29aa49c04c6160984757c900a752b4618bb4931164c8ab900b2ffb6e3d100000000015306d7385e04a8bced03000000000663516a5365516b804904000000000652636a53ac6321bba001000000000553536a526a388be103000000000068305fe300", "53", 0, -46500627, 0, "b64b4cace09576e00cf0a271388c076e77c22320b44d933484ffe5a32ca6a39e"], + ["030000807082c4030216d394586799fe53412f565ba2d669779cd901e38313f4d77559ee70e5bdb4450000000006ac6a52526a5107ccd4ba666a1a777d47e8fecffb904760b63f350d04a3ee73bee3e419fe9b7c7cb8d4940100000001ac35fb0d7902d2186f00000000000451acac002242e202000000000963515200636565516500000000a015ff32010000000000000000e9aaf30500000000ef7f3602d0510e09be29b32afcac981b8336bc2bcc6a7dda89ab8142b28de2637a1b5f7bae7bb36a3821e6694506cfd0f0d027b93e62995a91e7506c4eca50be2caa647581683d17373dff173619063655b65d741ffb44a4ee6ba83bef3a645d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b59889b130c30173b2c26f999f868ed1abfed77ea8c6f5372d7e880edf1dcf25cc610456e6a979b805ebe2857c74c63d9612dc92c64ad503e773c44f2dd92530da046648797a947f6ea94042fbdefe7a070530b7c2fa4e43d5f06b54338e12695802d239f856e44f36cdd908404cccd7aea293b19791d31e11990055aba232f021f0ed27637193eb4535e39e64d4875b3fedec7882e2a6d54d8c30aa0477c9bfe02107f6f84506f42d0f9acef5e5f375078128589ae1ae839dac8c39762d27059890a00ca7424f97a2b347bc4b2b156856a102be439f917ff6b5fa6fb2f8219f035ea39ab61188a9ab6268ab5fdb4a08cebbe525cb953e2d039367df3f61c955a2c1a032a4ad98e52805d25e11d285fa80a492a11bb95320fab092df2936976d13350250215766318c0ebf040b6402772360ce1034f61af259c82f85d9dba579f3eb8bd9f0229a7597b90f6141e80a977df4cc9f708018e4a93ad04643fc6b9bf38d043e9b003286229bbdc2dee7815dc57d5f77a408255482de05bf617199af25261bb9260b8022c0004448b36b5d9b794304d1a71e1480fe02f43b54357f21baa704fb8769ecc40282653e702e55d4167cb64b56dcca9f046b6b73f33449567ef0e56bafd76dc7d5e874a141158ed25e847c54b1937f1fe78acb3e9a15164ac46615080aa93c1bc938835b98fb1b842c34be1fdb9564c17a12d0635356de221aea0e12334128a2ee8bb24412ce94be144229be0fc3c2c03823b1d84dc3279dacd2e5db725fafb7eeb1399bf19b550a49fad6a49b105f58577a18fe3eb5c7973d6a0c87e6048d13680e9b51fa85715b36d6bdd0b845038d9fdd689dcf05c263350b3a468497f7fd3fb2bf890ea35f56bb5ce6a1d9d95a24852b4a2aa15b623aa5b166a643cf5256e6eb744c6d7e19b0e4e5a9477694243139056518f4b337c76a20bd5ea62c4450ef38d5820664bed0b601429cfc56815df97e71158c3ca8e51f163df33f988781e5afac0b44130c894ab255b6d5a223fa28c05efc463336a9cfdba1b6b4c16130ae5d26c9bac78aa0dd1287677005c3162ae1c92f1344aac419409a8f280915dc720a805ee5962425886a6b89cd4ef400bace6efd0bdbc5e910e068d0e8ad8363fc48f15fc0e68c47ef261d6a90c8bc8d30adee61712c362e92cec0175212fdf8bc7e8f210ae527a750ea665251425b57f04e6fbe693abc8d709d283505eba707ae7661265b418a06d7dd91f069ee5d2827d7165f9ad158472aa47b5664ff3d238ca6b16dd519df7460a640af892aea0a5f5d1928cf30f7de445559238fb6728059a94b109a1e38f8ec026373c515d8e7fe92fcc5bb51fa3aae7adf361f3b97b48859fadfc0d9197d17a99308d1128161a7247540c8a80fd49e3b587355cfc7ee5a87756468e0590a2d181bc704d76e7b913457b3a46067db75497f3964e368fb24cc4fad7bc422519f7181f43c1b93104e4010dc2ddc2367fe19c2b4a480ad3ce79834cd2b4e456b49fa56fe4610755830b35db04fb90c22480e66908f791bd44fc5c89e3adbad51e6a527074a87ab50ba0653eede9b01c92bf8be30ee3970db714763f4f7bd54250f284796069824db51b21330122636429b17693e917deb0097a683889986a274915e75b16c395e55fe0d5161e64420a1cbb11bdb4b80fd72c5354b4a72c3b960acacd6635ebf557f3c85d37ed88216391dc6c8db6c038a27c223ed92518d6c1b9d7db944af989050e3305b7c12e4e0285d0bf5fba2b35f782c2e2958cbd0c6ced57b3142941aa965c9bc4ab402c41b5ca2dceb144d5c7b007355e19d5fad606086a461232f94a112471c9ff1b0e72519160dc3ff5c4524e40b5a41e633fed9a4db945b1b56895d28dc4380385e128db170f2e27afe4c4e8ec319b9752c84eae1520c1ac34ffa196425d40d69b7dd519c7945120ec12fac7d2d014bd7d45f1c64813b40f254038b27b655f49f39fa3721910c630e9be40c7858f3cdb1a204ad9475d0e560f5f60a2d8a9b9245c31a8bb61527765ed294cc643a01e4f0fe66271411cde1461683cae2f11ef2bd178726871f5ec841c38d87d95a0b32081107d6c6a989d3bf01641f9f650834f41f6e4d1fe29e846e897094d3bcd2f8b053501af8ea886b46e6dfd5a10c0f83b3e3c88a7e2383d95dca6eff11e811ad5a32488e5555c1706e9a86d5bb77f9e1c45da465d529d4562160f9ba246672c3e1f17a13d6a17129f165e2b16b7d5b82f7f4a0bc3703bcf4fe961ab638086949d35f75621050f8c2a06274c070c12c6c428e1232c5d8f00a9925f390f76829f0a473ed6760c52a933842a21608b82e4688c62544424e3503b3ad1f0708b83049e2f26c490924a1d123f412a333e2c1c64a09d045e654400a69479a1266741be5c58f9017015a8d6a098fc7e01f008", "65636a5253ac655251", 0, 1869852744, 1537743641, "3e62909079e494eb875c3e99804abf4427aef6bacbd5fe9b46cea5774affd3a9"], + ["030000807082c403026003076c9166e07cda969dcdefdb683448b4a2a6addadc012bc01fd746a58af0000000000952ac63ac636a51526affffffff24825a1a5e2a9ad86e545a09ac6925a47515ed4e9a566923c798babb103d9329030000000152c04572860161067001000000000363536300000000bfd9378b03a392e201000000000000000000000000973fac2a0ddced06115d04dc4766ad4f14de5b8e1f7dba522ced81b0bec94c20fc74f1ee0044ecd0562d5ab2066791981666bc7abad7d4e21ef24e9bca26bd14562a7bff2586d21542375a7a325e3692947ab5b0f47e8e0436d62fa04724eb0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000479536e59e6023f53f6a4c0e23becbc0273d3dafd6a13b67c05782bad08ebaee2272cd33b08a616bd3f22acc1f8be6060883b58825166cc92cd8176a26f397bb17dc8d23e32db6903c3bc06d9513df339bcf6243a84322af2ca215df39ef2d5a5fddf9d7dc292322da0c8754a94d38687040e0e551df7e75a3628e798535873002087d000f03d9e0a13ddc01f5821cffc013dfbdb9a69ad49aaf49b2b00328978803222fa22d0f2908184342644602dbb2d062fdd1e0c736373407987a2f8517ceb70a041cac230f4f6a330c4af3b576b32ebbf072a6b533e3bf42223d3e4050f6beacfd3ed96aaa4469a9a571e85b8c5430ee63318a02e638da40abce1157a966ff0a031f0154f694d9cb750feedf8aa37ef7b98f397dc471348126ac75b5e4d60ac3b60210451599142db3eab9410ffc6aa486cd510f74821b3be7d5c45b70b89abda2bb0223b319d71c28f98e3374eb4d8297199b049a10ad223eedbcbe8d0c86e17cb5fc021beac4b14b5fdf4a5d5cca29bdcf21fb4dd9b47dab2bb55d7129a76de264fc4702029168d24c54fde9670f4b76d9fae00423aa64ad87d38bffc00b7c90abdc98c1c71d0d1270d336f177bb4afcfe03f2ab71983ba7c8416b19af5a4cb0a497d8003888406149433cc9940873135dd4153b6a9560e3523593bcb8c0b698a9a88664db1aab844b022bd307cc0d33c1c6f1c3fbb63136cd5efc7cc799cb1bd552a21a0cd401f8ff562f73b7821a517789f11af6b66197415054e525feff5e46b554514c46073461df7e192fb48f416d61afade1cdc97dddb74f4a7ce73d457a2398faddec68e957766845b78028bb5d329336ace1ac4d07b5b22e9d1a506cfe424c80eb5accd18bc1c4172cb203fb456a9f46c857feda272e2377867174b8fcd1429852d26f4822859e7601d45cf966e9e98b5ab93a7e87897e04816184c44fbab97d4d8bd283eae39f03fbc862ff4593e8da5b97dece87ccbc3c247c73bbea74c5e6fe19dc5a65191c61036c4aff9b4f6cd99f76554d4542f8d6c38a154cc0e8ece1fe309b5f8451e820d14a845de0d0644fa425212be4012d70bdb1117019f03ad7974afa71e872d7be36bb81c39ef0763e773a70ae3df0a9b1a74dce97a92594173fb07e79848a930a5bffa333c8a7100313353c71a3e2023b6e3569090710decdbaa5b7508985790f1e70357566ead6379ac270c003609c057a00892320f24cee38d90db246e4d9461289b1d0e58dbccc87c1be70ba70158de8769d8539dea00ba26b3692f1717ff2dc99f65955288d7e01570586533f6a915686af74e6c730df8fc98ba27b257654bed1c9fda660349e4eda1cb6d11800b793ea5a898220a5c4c02e5ae78d154363e1afd357c5991ad3a4dd665eae5d9cb223613b7c9ebfbf640f249ec7f78b0f1348f1c931c50d820aa4ba04960ae076d7926071985e447b67e9c6d29c95dc39df4df1acb23e56f59cc4eeea26d7449e802a36ec5d0f9fcfdf2e49754e110ab84f6cc0f292c11f38d4594dd63f6356e84ca0397fba74c4af1464ad6ef26dc1467e869e9f5d42a016f420d5219cc840a692985bb04e472bad65bdaceeffdccb453f6022a354fa3c5c1a0922f321f7cc0fbf9a7eff1d2ec566ad9393c7f144141b90b6208b1dd214a677a222cc2b3a3624f4abddee1df256f619e5083d282dd84ab41cbd0998d84b1d4b3e561a100b1cb32b054f3aa702ee50be5401e98392bb3b7114b195a04cbadacc123aa8b5295c59b7bc886531410d6853f10827192d07ab1d672611b56fb9353ff3803491d3eec166db5df1deb4f245526de9967379f3d856eaba556924f4b0ba9fb6d0b86097828f166d8a7448bd260a9aca706af00e5ecbf449a09763048fcf0be0a114e646d92a2632fc7a5bfa3c6714a274657cf4e1f34b108bf56083a0cfec188462f26ffbeffad6110ef56dc82cd963a6cfce1f4637ef621357257036b0b802f8859cb56ad53a8cc5643e7d58b3dfd05a80540db61700d5941d2658f754e61966644b3a85a64b7c8a937ff1018ec6e8433226cea62075d73a3b22224734a51c6356806f081358511da3e2edcae00b960a85ac02cd7adf2b94fed588cf342a787f9b8b488620293315542b3c628981eef749ebd9a301deb52b4e34beb35b878aa1748fa7fd186a33829475bfceda2a94c5435e0971b69e68035c01a68d3cbccb367fad7cd757cade529dfbc3aa7976f26ddbe84e6ebaf46a9bfa55cb1de082792720b063f00e038fba534e0fecf87cc841a0919335f6a19d41bd71af331934d70000000000000000ce12b30200000000478cdec4f39dcc18c296aba2626232c95db672e2498942333589b606ef3f3caf6147364cd5c60f18b48405366e23287eb8e4c4456dc248b00e6837196ad504fc7fe1f747278fd3df2c3ad631495b3ee5889b062954a7b11317f9b3aa5568dc030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d9b7a077a931390d4c48b1c19d30d28637c0a5e749d6edbbfcb433ff406f54a8bc79ba747212d3df68456a3347d6af12f41eca521a54e2506e170046f745de724ee3681a735d8820944d0a6a9e46ee9d0b3fb0b9e8c3356f9857196597bde95b3db518360b9645ea0d7eb1a254bec164d7a531ba362a3617af30721822b2280220acf2e3f360beffbedd966d6acfeb04a845d7f0c07da5c4125528fb119113e6032b30c2e36fbc6ddec0970bf2f0de00cfb71beed548695d47f0c652ce647ea4d70a01fa4371e332c3ffad4db86fbe3caad9792b17740cc5f915b4bb38a579b472a9f3a8b8adc7bb46d33ecdf23f6c9f6c82a46fddd7cc2437138717508bfb716441020d3e1420ee22d421e8cf1063aea7e911b20c6fe33b2c54673496144c0ed43299020cd3d197419ac501e94fa26735e467b301b1ef0c5aba360c5dc5e2abdc6c0952032378abb2540369c7e190264d94c32574075177f4563e5fc3b9c31d77a5d4ad35020c5f70f121883854754f5e6220cc90cf35fc6c99d822e840ba6fdf9fc9663f3d022d16581fc6d683f2ef33d873eaa830e2a5007bdbbdc78cf108293d4728f08f0b1f9c79c35074040e4fca01502cd8a8b63c4a2f5d02057551cdcbf2504caeb4fe790a8b28016b688fef028d62e4150e729fb33cd6a854cbac4d8d7cec8cf12d42b62cc3de0a6b17be5285c2737c804936a862f2fa114b2f568f22be88016ffa526efa3ccc271098bc736616bababca52146d385bbb8ae2113291803dc793a84147bfed73a3cdaca94ef77e935cd0a5bbbcb2ffb8dc822f1fcb8e2bb1ff7c1d2dda5776a89246cb204a4020c29a78268ce2e7ce7468d55c4d2398df99c7cc8ebe84d54ade88f4ea7009ad4c4e7c421185a5f84a1210146f1d0fc056aab88e1303717702e2fdf1135ff8c683563dcdd552471de1ae06a28456caf0acfb8721e59f3678282d5ca39d561914b1e078656464828f040b046dbdbb550f67a03a975e2034e455f47609083889fd0e7b144cbdd0431479566aba7fa7533a8b48ff610827f98199071b3223a2d176b44d4ef38b7451362bda80817abcf53535142b935d7d3b541f7668a64360de4dac66109e7ae510fdb1abbf2d8c57bcd729f8d33e4d947a8ff35a8108c9e0d74da806b842cdf00369c5f038ccadcebe5269c77b962d8f5a4797f20537eee2fcae397eb38e4a7fd964adb80d31faa151e074778b0ad29826c1cc5769346d1191b8bda02403d4a1bd4ae950a0c638d80ea88f5bf0ae239ba35bc29b431456790450b29031adb5460d7183d1e5f5af9cf1da4040e31c1144482180e411b84fa1061a3a31253f64717bd391ef542478ce7c1c6f69cd13b11611ba37f984a7a04c7b2f1f8a961f1c94b72161671376d7a3446f9de3b4a3b1e3c9b615601fd4d95b502a3c37bafa4ccae1b01f46c688464f644d074832f03f5b20d853e8357e68a707f8b8119db316d458c37ed3cdbff6e974d643f20fe5c04b9941f1fb16af48964f32edab83c1b2c4e6f0cd5335db7f2ed052b7ae6e864b2b9ecb69a2b5257ad388fdf50b338baa84fe0737bac9c637f1cde4c4994d3ac73f44190ae98637a3f1324e4114b164a7f5696c2fbe804622efbb84819d16f88c936a62ca85818afaddd7b465a316914425e40cb130895900bd7f025fc448becac2c7d15ead3606d08e3c9ab2956426d505265f1b11e04ce5ffe70a850576e06d54a65ff0dc9943f3b6ae93e10f7d349aa177c7b7480b0a8668f6678f07507e7ad61b2342e94f348622b645a43d4552d8272f910965fcffc9fbb820ef5b68464c1cb3c055b46a0430883d3263b02264409f154ad594198ed8c730077a63ab7f3a4135ca50bca6d2dd8fcab893f0055856c0a54333ac924d959b0ac97b5a954bfc39b91757199676be83f650e5210f88137e6552e937b7bed90e734b43a69a0cffc4d1675f379ae4828dccc5951853d059ea170c0f9aae24da73d57c8ce2e9159e553e69345b71c4e6a7113e1e640dca43cbf850c6ad079f2fff7362630ec294de0357547728b195b09fb7f482e8a6a6789510afe2dcaacc44f5476cf06f6242d7ce32283b9728ba5074815aa67ae11b85cb645dfb28bb58f479a083794786880a18e0041d070947a65cc0b523ac7564d7954fda9c0237f903e51e92b7a2d7f8e8c7c0c152aab49c970a65b1afeadf64992e84f16cdf979055d4bb64b5ca2f43f1da3c3130fbef4d8b072901fcc9524f6e7eb294116b74fd0e7fbcb307c97643c5b5d4b8400b5d6beb09fcdb3dd08faae0fd5f3be000000000000000028324e0100000000a024fc0b36713ab82554bcbf1c84d9607a951c4bd542d24226e2e07f720db34b3a0307e778847cfbb8f0d1119695a14553ead5f8a8d9a6c8c6397f1860652cea29254e9044cd20bd9b0b4bf24571603d2c416cbfe1005f38170ec6eef74b5fd1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003abae0f7736200f36b576c70890c329d687a8e78df451690db9319b58c844ebe6022e1b05bd89b909da0c43d00f6a87647420a4b84049290508b005d8348e24cac9ad91e6fe9e3ff8c63d65515895c038e758552bfcf7ec1aa1aa3b62f10e577fbac8d6c1d0c18c198d93bda5b6ede248b68fad32ef398ba2dba867e805cdf07030a3e95ee372bcd1ae86477a35a80ea62d0a73b2d062aa3d1780976c4c674b83402041b3bd2287416336eeefbdec979c82799b824f19efdd77793a2727822c905300b0423164b0b685d00ec779ef4d4cd3744a5c6afe57f5fb75f0abe6f8d0279ee7519a862bbc2cd751eebcefc4878280f10b241fbddddabf956745f9c4d9f44fdb002280a94e18020ee3e243707e6856e9417a56287c9858bea90a825f6c0fd2c6ff7020f8f85387291b7864879e6094ac64bf4df282975b81a61f16cd6e837813194230224ffbb45a8d3356528df66510ff96341212afdc1f26df445f79ced06276a602403075b085dc77d99a5fd1feeb17668e4d2c67cdfa87206fd6bc2de1c22a8670ac6020f546759363da912cf585964b4a1079aee23c4a58d2db35154cf3cb779ed667a617b6484a58113127cb5cc625f2fb163799a7ab40765ef8440fa689bd19b4a606d2047cd5705b922b77a26aa32e4fd10b381b5d36bd11d9545bd991bd6635c3a3678f80c9154a5e9082748aa0f54b83185dc5ff3aa8176ce3c8f30f5ad691397d48777162cd9847ab62e7ff2085dac59082f9271f8374246aebd2ba8ac2349a0e12258aa8e9e7cdf8a03174d60a1ce4869af385f7f6321580747dc6d8ec7be4cde3f77e15d62ecf94e365b2e7b910deae5b5a9d6eb07d7d856324bd20c5b9ae27d2d783534a04765688546b9b4ba05ab3342f0007f9e88cdaa23cc1b7ecbdb88c471c4106cb05bef2f48e47329a82d728133a51599f4c306edf15291ba17710b908116eb033cd7655a9511a3f1b529dd01776321496d00f25b6e6d8e76ddfa2eb2c50f8525984683c3b6cc7b9d4d07c46d6882d25ce60607264a490d33027a3a8739531dc0af36601c13fcbe56ca246ef1dbf086dd4bb17ea87aa6fe1c6237a0642cea422393ccc4792f19d70ffada1b380a9bbf42c56461f7902a502e577caf1a8ecca1f2eecce1fff1e48c3e4e9958606e39a5448ad1124f210af3dabadb0b260830e5962857ae0c05cf67f0d6c0b972fd69e28cd79014032c50454fa4320153a2486c8360c15ebba67687f7220ce73b640fa9d3aa9d2ed40a04ebe5bcaf55a64a7be103c50a7bf6b638a027d446a0b9e7f9a96ebefcf2f4d33a2e8e3783d417ea4a95ff79eafc78cafc5776126803eb8c3d2d158d37f768100db7e8712707cf12ecd2a8808bb1dc857e3991c9961126cae9056493b3bc246306399e7b36a56e6f9eab30a5c93ffdf88d0b0002e2cef6d35c17a85b8f9c0209f8c0f2d25e7d07262228feeae99e193a9c27eb012889fd81f9b3ef36110cfb121fe8bd6e6ff69c5e3a348c2e44b03d1d97b14f2ed7cd5559ce9289e68d90b118748eeb4a43e2dbc1976f0110c3fc2f16b600017d708ba8f53cb6274112fc1d5b91034e4934c6d90e028e6d2f56f79886e83bde14a63a83cae7d3aed98e9fa5453963f441b19ebc280095b0cb7c9620a15f74f6ee75e0dc19449ada25b273212d87f80a7432a07adb659d99ea6927bc0c112f93a831d7c9a17cb4eb02c5fdbaa700d7fbb18c28edd5f571895efa07da151f875d4d696f53776ed9e7635990a6256024c6c26b4bbf039e850aadf2e957996aff04b9235e5ea331ae01357dfa4c2728ee3a3560d64643bac2697fa468c5053b864378ff75ae3169ad35e90f6ff1489aba2cd15de2908380f583b96f522a4ca9ff84b97451be5654ebb245c2bf2c50d9726fe62f35d1ce36860aec2d125db20cec676055a1948b0b8888af9579f480c3858b4453eec1719113a7238621487d4f0c4dfe4025be9e370be79789e7c492613ff22f53eba2678d6483b404ee98a48c6ff7d88df44ece9044e377faa7ce1109113235fcc71b4b7d1a72ef5860eb5178b8efb637c1f7fe38d781681811acbfb3a9fb300b60b5412c0d965f550fb809d59c4e9c8121d78727d6cb08d5b6f0ea43f25b15d5056464e0fdd41524efb6448c8b95b6241642329e6c9c70fb8f5804cff1348c7949e83b0a3057b01bd6c9de4b86067e916d4019388aed6c60817cd795ee16124c0de9939e66b86d750aa4f4fd074c471a2c8f08a7451ae5ea3311b567a3a609525ebce409621242175d1b05564f47254d60a02f998154c8411a57904ac687863b50530e82173211b407fe0753b7db1768b462f90ef5d827ec68ebc800c97ee1637361fd3921b19cbf01386fedb2978caed9fcc4e116c2d37282bc297e0ff115ef94bda76a48e9b346c9302f80a7cd6a3274120e", "6a00ac6a", 1, -1411250569, 0, "9538506af9d91b067afb99da7f8823da1c579575b0ad97341b62067a724a1251"], + ["030000807082c4030136985f956a3c7df012c58d703fcd7e94c29bba802df5aac5043cad93f4e37941020000000165ffffffff016732e201000000000000000000e4bc5e56030000000000000000fc75fd000000000079d407e6cbcd16148fa4743281a27314f9cf9f99e2ad74a579aa931cad7c112042a91ed55fd170bef3a83409ea6e513c84298285cefd202d5c3b9cfc1a9b1c2d3976e0372bb472f8f784e990bec574d7c2fa03995c848a78da7267e2ca0937e500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d34e5e196cf531e5db97ba72292555216879aae08c57245ab4cdff8072d168d01839c0b4c229920d44a68e5958759d1cf8ed7d67244f8c0f69dd18a1fe79c65f4424f6df67cf162f1802d3911577f6ce85f7cf752d1141da9cf43e087c4dc988c0a269b6c11732ca656b3407b82c0de0eed72bf33f5dc80024524af519e0afaa023056c0e252d6c8e3856dce442e4b458063647fe5c9682b4cbd4f4439fabf310e021d45d03530f8ecaf34d1d9401ef516a0c53a6f477c1b611b8cd678a37de54acc0b001d95339917870b4e4199c3238aa80bd0803346894cc1e41a84ed58d6f18343e8105e445b3e22154dd66f2ee8e3136c5e745c6872c280007c020f1d97ba998c0226f2e1c7db19b330ba94a6c975ef54418a0b3e5b0a58d2eab4b0b0a3a57e6d2e021af22d0ad44fc11b222a33f78cc153052a1ac2aaf0e2bac5a05dd327e9c04ce50304ad0ed8e2056afc24287a7a5bef806e6cb50f27e4f4405da6e0d1548a4763ce02222b88cf670b44bd073da6d0cddab7b16cefb2a2425b10ecd7d140361143fed0020816d2afd7875bdf1492bf8a41e18f8bf3c4a993ebc5223c66f067c197e04a71d9fb958c40a4fc704357465c7cb0a03cbf4ca2681fa0c127b1154b630d2e9ba13568aee789182899acc82f1363aa1a995e55e8b50ea1ff5b50f0081a750b410055899e2dd7a188f3b535e47aed4b5e1e964c4807c1bf9ab545aff6785a7d7758159db6781b3995a9e940193538e1b6734d276799bd752dda37a748548d9072aea50e8c8e948d65e2a41dc8a2761bfb54a37b5f2b25b8044177ac462764ebed1056b757866ed6903cb4389ad6d4a0193275b96c63d042d9880e835ac7c269975e550ce540c98c3ab95ac91c479d2ad9d27582ab56d3e973fcad6d785c1edd0c6480a98e6f1f40f03f2edfaabe83c51a03e073a301e6e5d7730e3aff4e88c7aa7128a1d6b0aaef82b80867c9a7a293a7c9b9513960db730123a782aa916dee1ecb31ab7456f9640c4d75fa5636fdab5a53a1551f1d5d7e1af43c0473bd6ccf5fed6b7db8338ff3d6462f5d1812cade7efb7e02cb3bc17085392f47e7ea1f9031d12dbdf464ebf860b71a348feb1642cd5107174988016ead7edb8f0c6bd974c89a662cb0240bda7ba71a9b78e8f15390f31ff357916e03d5109d1b14f16aec8da14012d10dd3f31518fc26d755c447385ecf125d061bbdbba7669d7ecdee083daa03f4842c91d95ede53aee9a1a86036bc717d1fdcff6cba893641aa141c8b3090823faf9268c4af076abea7e83f235505daf31376986b37d2f54a04edbc0fad1569841b68a7c62d12f32978f88cebe52522bfff2b9a651a6b340355a745ecc37ce89acec089a8b7b87145edd495984bc3cc38747c8e029180705f5c7761f75bdcfc602443e99dfcc3c64532e655bae8bc04f3e199d91a9d067cbe21c4ca36f0c324087026aced085fbb9afd662375239a42d75c3a80b68a31d4b4555fad58cbe9c5573796d424e09dc0b00010cc49701476cfdb4bef86877cca6576573115a883bc11a592e8c246e5ac51c289b5592e0938ba4ec72494d841b42f09b02ff62c4c17c8f5e1307a3040fcae4549fe796ca3f8f0bb1db5554a8810755e397abd3da1d0fa7ff8bfa8e127eaa019c2ab7a8ea678688bef3f0775d1014203de9fbc3f3d82b695f5cd26cf427d8467e62f9a4af332c1f5d3a35d0382ac0c180f2d221a5d6757a8a88f425e1c046bdd5ff402087576ba36bfe9f9ce7c78ac514883f88b5cf571289ae536ff33227fed342573c2e0fbf124764e2092bae9e0fc8651cdbc7ff99bb6400573f8775b26785a4985e0ca847e9f9d31dde4c2ea2caa4a65b8963a5defe5d147bd929408fbfd571dd687977975d706a99f2b63ca7a37a5c04fb9024de2d385aa61f414e95a28bdfa4ca993a1274fd12db6a7eadf9cc7e971be8febc0940f137dfc67bc8c94a016690d91b25a4b6c91483074e9a11cfa37fcb409bc59e61e04c360704e0767cd67247c9f59e052dfae796cda01d80595c626435172105eeae6d856842ab9a0f6f2de6e79a192ed339be290b0ac6e41de366d7ebbf0899435b0f0a216cfe5dda8b7569b3c42dec3ddb6b0294def713ad6a4967c08f4a243c8d80a689a149f67e42f8341b037cdd2ea48b1b77f8705ea51a5e034ab71261d02c47353ad8bdd3f9fb6fafaf746aaad674b1bf87f805902872b8f3bba474064ee9dd95b93e86c4e587b05d762bc2385a473917a5c0e70b750d94ea9a438ad3cbc7077a1a2796106061f59eca140794940744d040000000000000000000000009953e7aa2a7c038528fe023c5dec7a28e2bd3c70c151dd29aa1bfa7a9db9142dcb8c44cae5d8e4217459eecf42eab75b68eb407353ad69bd74686f2899c5515c826a18b16d4dc376e5e6df21692b0421cc2315b0a2869cc76f2dfe71073655b500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f150a6de09372439b9f4d0e3686200b584669deac1462d97c12c12576bc726e4bb655c56ad294293288782ce8571a8ceb69edbf5b895aa9dca164c42c9431a1325a2fb1011f5bd99020fac4a3783a259c294077eb2ce2d6fcf401a20552d32b4fffe6d0e99e3463831014ab332345914b81928bf39ad07f32d90ae280c10be440225a2f8f1463ca251f37509d22f496c3f4c7be717ce343433fc9dc00223026abe020b14d9a77708774f21db51882857dbe0035f0b9cf38a8ca8878ac82d36a35da70a026df115e31c9bec24e87ce114315d2b7ce9e90c507075c300a0e1da16e350d27120d0f430e676a2be45c4b0a4f8e10116c272f13f270b0657d0841aeb2f42bb0304c805a4566068a9c8bb9b0f89c43df54f41a2a6a1cc5c94d9bf5297cb6f8df70201bc5be1b483fc791943693782ecb6704b611a7e9e2dec0da25ff87b86148eb502263dbd567ffa01d4156cf1b642371e11234f6b17a958c67d1ada63c23537c2e10325113d7afe6a1d67c09805f9ae43ff36ff798704c32f33e1216868b2d0bd43670318b65878d9268dd10a6204d29ba25d20823b7e030dd6d495b9b7c1bef9f5dd17c38bfd227b8bb4ad46e302ee054f4b81e0b13349efb6131e93e0c37fadf048cedac0e0d7a7ff504ae307d69fb9510eb47dfdbbe65f0e0359044be83e8d56f4f9243284e5c158b9e5b945ee69b4612cccc133c316918a7094fd4b87516ca57f1d83852b64ad0f04eb0d69624667a1fb4796bffbf2d1b81379d69d76dc0ab82482bb3d20a60866b064872ea4b908306109296b9555421e8e9643f59ede6c5fc8ecda39d94831e59a33132e0eb9c4a7664bb0a77605d311d93ccfeacd0b6de4a9e5d3943b4ed0f85651a182630aebbc8ce72fbe53f643476939b934429f496fc897e3ca9644de2f0733f9eab383bd625a988a0cd2c8ad571a2a03422a392954fc560cbc1122a84c5db3dc6a03d9a4233c5ca0c7146a4b9a5baf7830c34745685564dcc40307fb8d24e27b641b12f02c44ca9a60b9df7a8485271fdfb8b95f54adb2dc4d35d82d7ed5f6a63434773235529b3530950b6e0493441281c4e56fcb009229dae0bba966b465a1eb3345174a7946f2e290df93cdbdde940d014af99c77cfb0c6fbf215eff76c39b2007f183bb02ec909c970e7ad966b06f7954e4e273664e8e7b711386c93ccf243c41c3e3495cab2e4438b78eb44f05e5a657f6436184f08819e89a26b9fbe2fa221607b13999c7c18f902317de385bdc5a1035eeca546f8fb3272e55411a7ed30651332252b9d4d324df220e058983f225b556e5dc543c3f0e7ea0cac9069b0aaf11b2b35a45ef641e54a7e5fb1a2ade08a2194b7de4588c82834ee83422ed1bf0d869071ee47fc2912dba534ffac688785f12041d308d1006192da434b96b99aa4caa46940803863c2fef9963f61b90dcc59d8ee5f5436dbc6e1ed98007dec7b42343f37267322ed8b5d69cb43aaca5aa470d7c81089623bd2b043523aa46abbc24d84e3e17fd5504fcd10cda1a7088a57e7bd2e08d65d0453e467ee29a9471941a08fb17a9ff747288ff25698b1740499d653903655dc763b152e22d11302f15d615377d77ac795c46184097334586a429da2afc4dbea328f3477768a97c1a64cb62c0da3d07c0ac9e5a2a0773a8a0e0d14529c2554fa9eb172c3133bf7be321c820ab1441ed5ab1d0ea71c58391ab1ae3a8aab5d5e7acc018531039c78654ef50313bf17931374b58f0f3860fd57161375c15e95f55a8352f9f7e60efbfab5b9f57f37fbb8da19519f25ce627b92c63d72872a3b8bf43fc4a11cddfed17a2b67b77334ca9dc84bdef7c54fabdcd8aea28be78b981f73c08290b265d65fce6c85dbdc363397d88007c93d984a6bab86460c706b8fe50422456f9282b88f3117d335bda6b7e9c214d85d2926736cb01e72062586e8cd099057bf57feaa40d017ea707b1a73e0e427b03bdef2582924ad0b51690f7fdb9d4fff0ec4aa4b501a3ac4702bf03c3e9afc2568c43a2934ad2b5cffbe3a77b33494cbfd7837313664ebe40b904402e203a344300e9a252154910cd7018f07302d01a3e2488b3fe4c23750b5792106b1b814b1bce1e27012fac32756fb83f9b89fb8acc37572bef70c0c9f61e78d50159a9369b43ae2991d1fc1c49f457e2429e2709444e5e869a9f3cff7d6254a6a7dc749d9a0b1a137760d4b1705a233300a0c3b931634c41b685b4b6cd2fedff59fef1145e33d00d78b9a908713919a2335773d7c02bf2c1469240e725683fb8c7da6d300000000000000003428b603000000002d4d4ae6e079f27ca70eb3b6e706ca4967716b3d3b1ebda305930fd6af4574d30972205fed172b2069084698e36432187df084e3ad02b04f4855b8a54075b5c9003e10255aec31f46acff7847dcd2b14d39e2026e1c84f229c2863e6b4d5778a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014afd7b6b082a0e291f8dc490b2ce26baced924b486f3766a0b77683847f000e202712505dc794fcf36602385f28a9d57dacc620199ad408dc59501016e75c9c1c238061451986fe3231e0adc214e25e8767ecbebd79356f10670b2a35fb14bf0507b0e7f5734a81555dd02f2bcac8d89ae49b10be4b633cccf7aee924578378020cbb4f097efc6c6b3d938f50b875dcacd6440f2577ac166ceee26e17fcabfa8203108a90041fc14605e0f3f2667b6be06e830836f2bd6f8ff0472ad2681e8a22a80b02c0fddcc183ea2e54783fb83dd7ccf7eef8445ec5581bfa0562f5e29142a3b6177983aefd2c6f130ad7728b021bd68d9f1395a8cddcc921bc0c570d45d49c6a0212920c80728a5dfeb5bce19b3b0101cf22e0380cca509d275eabc27c78549d46020318b9e4a47fc605fc934b0b214d9a98a8d993b130fabd8f4fb1401059fba3e9021c7dc59dbfcd046326bcdb549ec69f0c4ecc9587242271c7a46d764199f0c0be032074e85b80b778620ba346a359d15c45e66d02ccf68d1c368932abfad4e38412031ff281dbb560468fc61546f8408374ab564d7548424da7c256e4716ec654e5e0ae78dd40eea73e86d1240346c600425401de71f72a4904a8191ff06a3a387a7cb07096e00c7e85e86690804a4ce304caaabf2f81a446ef33556b6c730cc6a3cb58686759b10f31392424721a40153ca9a98770326baaa1d37c63472940b4621ee3b817eae7642e0a79ac47a1337c393456bdb36b83a3fdf29248f26fab95eb04e20d69f8113c70cec3853086fd47c0d1e88908c6799f53a7ca86b2867a9253ff5d6931c5a6954527ee93fd2aee15a9748fb87a17a44c8e8c941f45be87971482b3ba05a6e4d61d1d754517603d4a6a5f01a60d49b6f26d70e17f0602aa2dec5d3975db10d1665bd61853a7a368dcbb4b6392c77e1aa23b06bbc38ce7a09101849a368aeefa3cd4aab101f67bf6e9144d103e5ccf8f4453c3086badfba7b27d0e8518330fbf3f0a28c2b0d9f50459808055f55c3f93329edc2760b5e8fbc778133c6d39afeda955ea894dc31ea64472fd08f826b040d9adb452e47ee60d0e67908bb8bba569f2254e4ec43d17e2329d265702f825b251ca464357dce64b6714fec1db3937150727eb9ed8a335226a8a3b49bd01557926c756a39cb3c274d18971e8e49300bdb8f69f4f497294ae7c4a4abac85ec2ed59e243b11b63eb022f8e89732697a063e78715aa97b5532bb1572f648ee7f683fc0e3d6c97a5edca0c3539b2d7bbc8325660c0fc1bf39fbe2f97101a7e46c05e7f4aca5a8f826881d59bd1cbafd58249db73add4cfbeb10a92ddfe0391134c837301b8bc143b7d4e3a8e0f69eb6c1db1b31c406f39376f47d505e9236452eb1d5f7713a330395b7e36a45962ba0a7fd412545cee9e7e4831ef09447936e03b0f54e182eeee21b0975cb41c25387ba77483d860b7953f4d8fe194dab3fcc069a77a09f9288cb52adc917bdc1ba092f045ed976db1be70b350495df4278395cca0fcbb9449c286a5f58b104e450549180c2cc70b058a56fa0f9e2ca556677bae23738eff22e3b755e64545c08013a93e1efca77831dad713a8224264a6d4da4d7faf1db5c8ca4143911ca76f6d519554ecfb802b3a5343335cc45fcc7d9056d21330446e7b31cf0d674c4def8d887b650fe77c67666d7205fe0014087f25660626e08876d09ca0f855ab0923d02e3652affcc9b36f99f3ddfe3145e239ad5ceb3b7e31fa0644bde59c86db8c7234bfc8abb8c5c4b8bbec554c7c9795e6ba7889e3592a2957c047b65c3180e3dadb2614759b791148e6fc8db5e3a44445c33614b5b1cf49dc93fe204f32cf19fe15db0930d45d14bacaf85a3a6b035f66df97c1ddbfe8fde9cad5ddde2182218335f0ab041c0c2708d4a608f6742e2e6f1d104030d7b6f2651ec27efc6017695c8c7fac04fb59eb721cdc58ad114b29556cf85a6b10c54a925b1af2453e0ff50d14978e6265c8f1e1ef79ad54977c6791504f87b03ffe0e79c9744ddf53aeaec7bbb81cf20b098f0929a86c06ecec49089b2e0ae0be363477ae9f5a0adbcb6f625f1ae9072b7bc43fa44a019fcb2cbfcc4596ca39b3632ade9570f309937b69c052178ae7f984a96a99e3b51b82876a897dc0ed1a47b540e248a992fa1b0aacf54399c87b19583b28a3fba3f578ebd041e8c87793804cadcd4be0e13262285c6cf6c9770a65462a61344268cb031e1179a67ad6fa6d35d5f5b2a06763f75e811a44d68d037c99595f773d54f90e03b180fea90679670f5b14f9ea3c506a711da5ba44bf161aecb06b8e7f11c7b9ab15db7708fe2a04c716dcf7164ce30ff9fc45f6269ccfd0731a41d521717711fc4b847e1c20cc299d1b8677dda2ecab835f7b24260cf195d6c1a24272e19a34b9e06904", "526a", 0, -1598401905, 0, "47e2e9d7aab4e65db4301ca078948d41cbfbf8e6e1d66293649e81c245192d0b"], + ["1c10441c01c260bfc49f41cf0929a714c85ed756b12905de777c003b63907dc74b356f6834010000000452526565a8a48674023654390000000000026a537e535a00000000000000000000020000000000000000aa389605000000008a701c8c19cd76ca74b0f4608828bc7023dfacee8542351ef6ed827e7d9c8fab159d3458b198794a9dee6b948eff984c69099e1da6613fc7905037fadf2226d70c5621b1c672340c308720c15591d64dbb30df093713b4adb8edd7af2eadbae400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8a66894742d700bf16f855346f7fa1c7c3b126dd2e1418e64d09be565f54fed45f7133733b6a2ff913357164802405b981e8a2e7f35a23c8ddf48cef3d9fc8e5c090f60232f8799e5bc32f93f85784fd842c7ba776af900932d602a0154e8bf415790cd197de03ae1f642548fd200fe6136a962a80b9a47b7830f114e597b610325bc04ae1a82a6df1c67647ea5f4377f966af3a9e915c1c7b33e01c6c63ca4bd0303c0183f3d9746d2434d33dd2f735f98c1a3358d2143bb1edd4cba5c3e5ccc620b00ee3b5a82404a08b9f91e296de3f2fa607dcd7eb0fd4661232abcf282e175ea17c946cfe3f4d9d152262218f044d1405900cb8cc0049d4c2d2be4dd178a046a0222d98a0f862fb3274c179dca6b2bc53f7ae7a6472308545b08d45c03ec1b3b1002043850c755d7bb4391dcc11f8ec2040fe963421f7401596f8491d71cc4f6d445032dfc6a24931705787946af47d97b3506c29621ecb136af24847ad71ed54f306002231f38709a78df6df05e23e7050f201f62c4cbbbe5b2521f83b7b20dc505d3f8020f60d29fa08cfcf43c879eb50aab6aacb5863fcc26afeb3c56c0d89d1a39dd556b85f09532c22b1f26d25989e4345d8977fa0e9625fd4bf515f668cdc3e1a3d0686b303f9d07ab33310981769e1e93186cacffc3b0ec492bafb14573127894a4cbd9a5273e48f2598c4e5d8a3e2edcc360f84e6f2e2bc1ed99c03f7ef2114228d98e1bd7bee10505b5388f38d04a0cd102f1584d81938d7cf578bd2d938e90f69553cfe316d73a823c6022f2f8421a162243ba7baac8c893041c73020dbbee4b58ce0cc8388e220661b077967aa67fde2bae6fbb5857fe2ff777086996c8a5cadc6e944d5e071dcd8beb51455c7aaa88c7cda1ada97269e439872a955b3c80b1c408925e2f421820c334600f9420c00bcf0c7aee6ebf8b15c09a73f2f755ef99f838cc80a1c1e5f2f7a001503e09f59bf929d30af53f20c0a34b8b542bfcc7f26712200689372c1ba2f1d2648b04be31ca5af5a8382ea772c6bf108a8d728a15a280b6457795a5b4d7884aa2c3ecb23abe6122587a091b173f19c4ccd32e940e52c21bd0d15c36b88e1d6a12cc0d0b20494f737af0cf8e7afa7fe34feeb2abd0f8106635c41d4c07d3f821222be15e86d2ee0c9bd4ade583d60d12c99a222383fe16f3db1941e7fd222ebb496c11009d0a7cdfb14b20393e31ae4199590c4e057c62c8bbd472701657e871d7556ed789fee90cbebd60294729a7041483cc887b639bcf9a9fe868f81a2df242f3814aa3fc94f3dd0988e90f908b158fb92659fdc59499f4c15b12c3fbd3e4da18adff1a63c1e2906a52a5e1022202ff734c38e21a52ad03badc4d8515f09e4d9fbc6ec24433afab979b08a8d5d9e17db1d737fec71b39bc5c565960715f1402f9b0b90ccc7cec0cd74623af4f9a838f317cc1a3a0700d3f22c0e9d635149e69f80d5f1144d181fa7d2191d7a12d7d1af69b904d3801f87aaa9cf8d9a88d76476141bb7fe7c1c838fca9fa7a7fb349dd7a7067f7328610215b9695655c5d4214cdadc34c66198b9ba9dd29fdb795bbbc593f7e6bda0bff9a1c616b9e6787e7417c7fa7c0471afcf3f239fa42e8c236a19eb2f52c2881a555d3ca0f28c218b1502d4042c56c83fbd514834632824e07d5dff201fdb4f966d6660badb86d8cfc4d5b6259159bb32bc7553d40493a2f9a741303a8d4c1edfc73b8d08d1c5163d4841a261dc200b9f38cacf4c3cc594efd418558ba12cbf818f6e5891702d7558497019ef10cd87be27372f9cb92aac294830251876d058a01d55c735c3f28cf46d6e442aa31c8b29aa6a385d46ba2b16a3c0abc19832a682149f56e084791d51803c1ba6f642c35f71da6320c703ceb08dc50e1885a88af4bfd06e503b332eb038b93d2efc554e8191d2b0a36eed06bc45c5ac2f5b6d7d1e6806d4306fa835bb753ebcc19486dafcfaaf26ade1d0cc1f1c7c8bff53d77d36a79a0e194ba897c459e8df876a986e0968c9082b33a43e144c856b8f30734ab1bfc52547111ae20d647f49151ad672a6446ec2a10a0f170e6644f50cf8a6e3feac1e43f43d73aaa86c809144e1b588393786ae75926e79dd564743a1deb9a879ccdd3df65cf3a5b1098e876aec3e74bde35b5a892d4fd099fc297c788d89db212615821899c35cf127baa607283b3bcd8a82a8186e110aca38ed9e891f21dc6bc8207a0b82e4a764722bc80bcc6925b79fd07bf07a1e779a2038a7e8d8b4c1297d2d2f9bd69dd443b01601eb23cf64300000000000000009d55e00400000000099165f1e28d01c39ef9635abd036078d77c66c432a275133d9fc6ddac2c1adabd861cb2bb2196ac128a4550d3b4e54b561d82e88f63d6d139d1d3e161920735943f182fd9ee22b68035c4909139c4e97bce7b54f84f72d8040b16609cf687fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047b0b57b87d14a782a398f14469658153a05ba40133e43dde16200865b4beb66bcdfa8c8f1616edaba196faa67a71e58bb0538ffd715364ff4ec7b3ed19df4f6fea69782b671a296d8c094f4048741e291094c0b4a0022b01f9b583279e65ee20e2b1a47381a2cd63c0d65d937ae65f9c30d1ebeea3231692d9fa91c434e556b0328135bfbb468a8b9bdd8fb634b38f5f9b4d345d085003d431f49baffb2ffac72030f6d960538c2fe0bc529baf09b414c3026b0aa9ce35e50d6aeb008646a7760c00b022a87eb16a9b24f377169c99feacbc2f6672cd802107a5e60e8410f14f66d0afb1c13049bb73a3f293b7be8be540ad074e01580bbec660d8219de7ee33add860215e88a806de0851f5c2a78a8768bc54c85d724253a9f40d30bde3b0cd99bdb4002043210836ec617fc90fe9920455956f1f92a5f3b5688d671fadee7a528f1ce7d02107a2949de46e18fbb229fd331a33653bf67f36302f9f8029c46ced4edd7508a02070721394669267c915c46f129be0115fc7afd9cc2385e5765560e8c82fe6e24022c4a03b67b85a5e2024f2465c3ccdb85249ba380303ee340cf99bdd66211cf1dcb33f5809046274c08a0ac73ecdbee029544834ecbd6c4a933bd77ea37d69a1439c610352f46ed90702a03e3ad823064f59406fcb2f902dd278c2c329c745ced815ab3f3ee0313372402098f84b5b37706aa5e3c22eeeaabd90ae0720a2b4833be96c411af22f1b409dc932a64eb00c2123af86153faa4f8fcdab525157dc8a634700baadeb5b26a5a44e2ca300c624ddb3eb3d04b001ec8da32522b580833da7199429451a996bb61ba3f8e405fa1166b51791681e856c1b70fa97ba23817cd5a3576532ec6b5282cf02fbcf368959be9e553bb0f6b6cb13e6edcb8f7927179e1c25aee01023f81c1deb13f72d337a326cc2399205b3f8e71c379e43041487fe9f70561f1c5af6aae7bd4002b561f1aae7968e02a6c0f44f8ce9870c038f52a6b9dbf7f1a50a16d94581c842b29d115858b3ce4b628d900024f603cb44d67d6eb731ec49955ea69d1312f6f9da81edd74d52ff4aa3b744155ffd04eb6478ef492f62d9a99441fc8e13481f1a0085d708ad105dee1f96f1e03c777ce19f86dc0b8bc4c7fc2514f62c4c89ad2c31f1572e8b5d510251cef820ab8211f66b965fa6a1243033bf9a7c137c586710f55ad93af20f2037c4ec3e056cf10d6b6a2a84179fef6395b03f444658d4a4ad75ffafcfec855fd0ca7f25ee59c44208cabbc072fd3afa6fd0e034e3d87c485e99a89b5c111de0f3849183dc69d843cec81aa6bec4577db5b9d2183d78572aa0227a3ffb39caed3b044f7dffad5713911dd2a85815a882082e4f117d82fd9a894ac7bad8a6776260e5ea466ce523ba04ded9a1e9a1b4a8d49ad04dca874ab1a684616be39f022fe453b824e54af08d733ef528d1a3dd6e3f0b54253dbbf6d774d4a2958623093444fc4467c9f9721dc4324cc6909b6147963607b53a9dcdc88546435c9684d4b91d52f2ace61674acb72ff2caf6fc8aa673a6336a752acbd989f67270668627d256282780d4773735fe0d8e095ff5bad30071a382e1514fe576167d6e547adef028693b8fa921aecb499b460e5f9e2ebbcbb3f26ff1481d81ae45cd23c0ef5f27dbe4aa04a303cefbd37ab1c1527986720bb875ee9b37d1fbb374480b87d584609a89dd8a7193325eebc603cb516d7325bd007f235869c0af7dcbd0e991f5fd00217cf9fa04e685e47ac546370110042bd5a14db9867e37611682b5fbe81432daa378d165e5a31711557cfa24177e3efdfe3a8a903d95c56154b835fd348fd2f6affd1bb2cdafd1ed261629c40e988f182faf714c6202215ecdd86e1175651439ea607df627f334eb6d8d36100a4c3bf1a0b02f20903a6c200cf11990de1355c696377cda2f2be3c0184ead222f3e5f0e015c45737d20ad429739b96755a1314db07e32c23778bd383461b99ea2f4f79ff7ac7b15c350abb23a9beeb14f394307abdb435b4648f81c7db743a03d7d1da73353dda45dc915b3889d18646f36fec84a45e2cb430b34a238982c3fa866b7545c11515346e4df183508ef7e8ff193a62b882e46a80c6dd29856d80f0161e7ca8873e0b01f4e983d27749f30c11a46ba83a6c9a09ccf6162681a4e883e0927f2b37f343e3899f2738fad90d5d58d9959d755df0611b363c0b6fb64bba0306134b68c13a5fff96320b0bea00a38eca733c96e56e3f5f8ec914dd57349fefccdd6efbff8d4c4a627f68fe6577e97dc831071b12d6e606f1f79ebc1429a1e1638bc396c6de549785c4af5e24bdfb2bdee34d1bbb3a93074c1eb5acac86d7a094e75629e57526fb2669c49049561f7c8c15803de4876034353a94a7e571204f9a3e83f4df5793d3176379c237fd72fe00", "63", 0, -1581468389, 0, "4058dee5938982e299c457238effd57f96c472c86b1ec48702a2128830902046"], + ["030000807082c40302e0e26a213ffb0cd23b2ad34ed7da5bd4c642bc05be23454a75071b7713c2bc4f030000000100cfb67e1a878e203e9922a54df6a4675f37b10187cbbffc80fa4d7bf65f825f4e0e2ae44a0100000000ffffffff03f402ed0100000000096a5263ac6a535365651bcd910000000000035365515a8e6b05000000000300ac520000000000000000030000000000000000ad019d030000000061bc32b4f67ebf917718188043b2a3c285f4e861e8ebc8653d1097514333f306f79eb32657129f2a4551819c5a9646e1e824ffb5d5e3c8db312916f81335ed10da8297462d73fcc2d31cb685e90280d828087ca7cc80fdde914f3d3114ddb2eb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f1982dcb8d26dee453cd7a9c4214d2e0ff41cd9f24ba6599d33d5df91b1f62041cb7b708af9c41e86ce99ffb0fbe78f94c2c8aac49589e74afdd98a9a78de0ef19ba997a8d45bc9c793b91ee55ac3a7d4c55e872c4ef2a78d926251b75bf329a35c6d4f55dfa5cc17b6962703f99d3b164d51bb5ebf3eefb350d0a663975e4a020166b41371d608bcdb2305d395e919e18db715d0e0b76e4dc1e946ba0035fd7b022b0588ee3493cde583c15b04f14c068d54783cfe828d0872b68cfcec259782690b07c6b708286fe28892afe5091706ce9081465a387652927a9e6dcad24726eaf2241dc99c8672fc231950ba33eee86486330e2e063c6aa71295a082d808adccab0324e15e268b8359d3799adf605ffe83932eca7346566e6db5e569c1bc0fc973d602298dbc1fe70efc8c971f019b7f5f738aedd2d85e1beee6db95d6ee625e2d7a4b031e0c5e78e3429998758ad564e16e4591cb7b7799f9e54a8e9c06dab3f3b39e030230574a8d70d19903221e085ac3d8baa019a72f915103666d00b91572304b1317020969989c10d587399606b6c589e3b84c4f491d009b7f84b8f906600b531553555ae6d897d42d60ac01d8bcbdba241c58a6b1568131becaa1ccf4d3778901b9a4ab19c8d7ca7aa07908128ee5dccdf9484fee52214b8a6bd2467e21c82d8969606aa3a84e8b0ef62e5772147440f7f4b2d62c631d46f2fc810026453fbae3591f819be27c0d82a93b5a578689f764fcbf5b5ff71baa53e97ac5cb09e1de35910962f36b947137d20a84c67d720a91f89d182d661a22dc6f33cce96e9136c4416725961d69a8abda1b286dbe9ee9bb4d207d8e2edd4f73551bf06da6e28ec0db090ac97707d23eb1738397a6dc45ebd2591d0acfc8e33a2958b66cf5a64fc4046a145b3dc5b949837a572a052ecb1098334a074ac0b4c960bea22ba1f995078d7038c4d610b0d4084a3960522ac0b772c4202a3e38f6c830543208c4cd1a4a8bbcc62492c0ef6b6af2e6b18228a574337d7847b3afe507d13fbd2cb9b66637b396ea04224cd38a12b9041f44c28bcf2af01dc4729bda771cdd820b0ee664acf760d5a7f9aab9d39a671ed03e7dd0ca8991786d6e80b669a4977b90f1f7ded029fc26261613144885a2022bdd9011eb653bbc2189cfeedabad20c910d1badd80fa928d7a44838ccb6d8a309d84ad8f66f7d667712613ba90ae47a785608f8a571cce09d0ddeaaaa17f835246501cdcc0b651885ff01325e1d96ec6ee39ffa9479b71df443546aff066508acd9933dd6fb2e0f5e82aaa46f5b6e6fb8283e8f20394b8136eed07cf545453a48e26826fd5b24e600707552e064523c19f2c6f4cf4ef47aca9a8335f2b5f0d20a66049a6b1d125651532dc357fb90886e73588352575d326444d69d5a2a9f0246494665840212e22944a19d2918a27cba9ae29d1e5970211cb0342092d9b47e1b3823f0f04aadbfe7746deab245f906fa9a6e15cdb772d84843c84a0f23274b080216c0e197a51d42c4308096fd409394f72f01f140789fe9b37a56b2ea7a4714f78e0124bd68c480c3d93a781254aeb5f5298694c3082d886f854c460e61c13b45a587ff058ba309edb801777ae577ba0ed5fd2ea88311e45417a651dfacbc1be29778dd23272a02c3c38fe7f078523baad27d8c17e05c1c07c065c9ff7221b620de442646a0930b124634ce9333748b268c4db6e5da45bac2faf041086e0873d0f10355aa0a9dd3b7106a35f874b03fb45e78fec3329bdf68819c7b4abeabb112ed673aecf0a80d64677c4a4098eb9af8b28146174f5654297726deae94d3ba31ef507ef447f12e7462be7cffe156fdf8fec6535eead59d4f9d1d8b27e5c7f86d7e94bddd50e1f34c48359ac53356c5835c58959912416f03ab0d1517a3e5cc73b1f14805c7dd842421cf3810e5eb8f5f477992c940dea508d0a439d9d60899c08280ca7272b9cbb2f215ed908a6ddbfecec4b38eb2c738f71cb0721498f7532d562c23f07fa1d20f6720c8c3619be3f1fb8c5c23db16829a4a415704326b9deef940163a2af85cf3ec5f9f3c6e3d8c54eb1e4f436c2565ddd98580960d75ff65591ea55b079603a820d8d857ae3cc3f2c0a29eccf0fa35b9183b4c89c1fa36abba170edb15188161ea39253bd7687a48021501db61bb192787e847f9e62498050a0db225f7c34688ae504c7c2cc0ff3cf7c0a4d50525ef642654d6dfb9073e2cb7300e3484c7fd7a72dcf62a2d463fa7ab524f6a3436fb9ea13233e3df44f204a478250f0565395af58d01000000000000000000000000aaf62a26f153009657a025ae9fbe972c0ac6365c960d27e7a3ba331d54d1995d1660da6f0e7c824d4ca589d01b69dbb8af3ad2e3eb3d813b9a4a1d01e0607cb293c7bc288faf3e35e43e486aab9acfd8b2a1379921ee0201add0ed4c25ba39610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084a4d0dd822870d41f1c5f6b68e96eca35d8d689f6bda531a3fba058a5f28d1bfd031414cddcb95c04299c25e4fa6088309d591bd89dc6a04fe71e9cc72d27f3578672bcdd6517e244d4902c4a426cc2fca980efb853090f7c4668182338099270daa41ca087b0e0673b7570f9ae13ae0ff3a867b0396d7590e612278e1359270215bbc32eba139d65e397decf6082b9f307b4f16c5b75c155f3bdc8f3445140ad03008da7b75b40f01d73861c8ea713db633701a87a979660ae010570cbcf35df320b00f161ee653a0191d4bf961d7783a8f84257e910aed41354eb2f6088144dfb2921d72d99c012861c6369ab8d532d99218ff5fd57cd2a3f2629b3039dde233cdb02210df005d3c83c9b4d1869dc886517491f5660dcc0d0497955bad60e760b25f7031f50f72f550c03d137bc4974dfd5629c8994cde1164d6a178f03b5d8705042f10200a06693e004209a91919c63c9a246034a6daebd7d7f1826f9de9388effd4c6f021607ddc9c8a0ec33b7348c6133a9c55e8190bb141cfa29dc8d0cf7b54fc3f378022eeec72659a80d6e7ee49512e4a8003396b8f855334974345d3c72cf5eeca5f6765350bbe6194c14587239e5467e0910db4e8f9d21b0c2ab101d06e77202ea8cc28b8bee420687c97995393c925fa87d0b8afd7ed28ebf518ab5c2a751a0ee2d0f85cc972991b3686fcf4a7e6c209669f25fede74ac8f2f0774d1e568c4cea5bcd69e83456fabec87ea861d4727e0635ea34118d61194ed2709ad37b071f3903a5a435fe882dd6264f74f595aa8d0ca34b2497b3c451a0e5bbc04ef1798f9c20075f96d5bceab4c0740475f3523e81b0883b5777be43ccdad3a9e956c23438d59b41970a542f94804067978365b389074706729b61204dd22ff7525fbfd31336342468074fb169a417f8a8e3a3926a3693ea70224c2b3a75349921e50cd15836d94a3ec40c10a3ce86c7c0927b63faa3786aa4d29b7c1dcced3054d6c62ec8d055638ecabc136d3f24197ede81c279832c2b1b8110e601ee751a3dc25f909a2e003fd86710e90f0a6d3160e0341455ac7299cd4566f5d7f0ef0a3733e1184aaf5040b015efb41863ba178a42e05bff8775c611f2607a8407d6457c8b2849cdb5d43d0c1e2af303e356165de9f6ae4aedefe0ad078631de2042f140c2a4bc3a90bc5188f89a93b7f566682a8a1ae61d067777290ece2979104683c1fd7ed585d9efa8c3c6ff25b22975bc704470007e323602a091bcb2e5f4dc68c5f20f92ba18435eb046acbebd9508a36ba7e4facb4379d5283479aad0140d69f5dd0cfba017ae2ab21268e8924b185ffea66666eabaae7ecde70ae3de85a956914ffe4e7a3538fc992126d6822170049f22539f009b020eeb7438070db0d100c3b8071caf0acfd3e2175695af945d25dd4a625b1a2b21cb401e24b25d8936d20b84daedf28a49f68858a97a1f3bbd6a2848af886d6f0c6f38d4bfa5f69fd2f8a07ef7a4dff299b3dbba84115c779a9ad37f6f3d69fff6a53858dea3e936347c1a1df0d045274e3451d9476eaff6f1c38f625c49ac67235378dcfef7d40a826be5524ed52edf0143c16b45ac70d2826f1466cfac9b71b848238f49276e03fe35f9acb2fbcd63b582aa20d5b3c50db677265ad8acf0162edadd2609b47ab1cd903479a4bdbe767e622f5479b548854cf07ce0b0af54097f3a5ef03e3e6ed074a833ea5f1a636c4de62510d7c987ece78aa88457e010c7e3461300cfd98c241b60eeffeaa937a08601f8224a0c5602aeff4fab63ce4ecea65735ad7871f599c4da63e8a2b3250c1550546a886bf94c0637d1f0b7818a9faf6062fa71b95a2f655ba3db2c6571db10bb8105d37f33a7b66ad0da6c0d13b68d3853f9bcb011e14e881528a3086cceeac70fff79baa2b09ba72368b6fc284a0b63bed2fa005f5023927def6d9aeb46bb91c20b3380d178e0fa6cd95e791394a2e24409a197ff2c74cee4f97a1c87b2cb6b4189b21e9aa8b24b147c0d38e696a2b71b909930cb471f2e63aed127a06ee81233db4679b917f48122f8d0d063e196676aa9fee634ee6fd28eed644cc73081c9363b7b8fa214a03a0425133ea038820358a8041d9b1111c6d898d76ed548a3d950df70f3252af3f800607d7fe05a63048338d74aad8ce85ed2e3d178dc883d33e17f654a6b9223612c44efdfef242f6004b66aabc7e392b330623b2023929441c61ed334a9d086216848aa3fb9d3dd887ba483bc116e130a0a0917077ec7896b5b7c3f58b35341191b69cf0f3f380ef49d8d22050000000000000000000000007a6f327ce4f7f519698ac5889eee9aedd2417db12ed8e8dacbe4070ea7bf31827c803ee90a43a901eb0e5141afa53106a1f7812675af21f31a7c3db0d2124b04d7d65f636064ca6c574f135eda2e1e11dd66427cba1c4aa08de1619e446992e900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca2bc8ebe7d844edf4027bc35efddbbe7371c2351ba5b99b6731edc204e64e9eb17501c63957246c63393dce8c802858d2eb76dc91377b0ed72cb31fba4009a40393d96eabd02ca2e15f5b93d6cb01f79a6ab3d2c6328a4cbc65a0b2fbde29b66402ee78439ce8128bf3534203b2d9898697505735a8b6f6b8110134e710b1a8032b2cf4e8a381991b0f9cac30d212912a5ddb26097c96d2a88cb1fd14b659f80803236a0bb7ad01d1fd823b5cda3efe547372fca712927263c4b6ff3d44f246195b0b0028ad8e33950cc750be2d0a7889da28935184e587caea996bf4d1baa14b58360db2f6bcaa06c254b6898c41d722646c915339ca1041d4b9fce7a56a75ddb4d703119da5d63a688e6652f741b798ed01b6458a7049e84d59723cbd7d3548d48818030209312387061ce698769544b9e815a971926721a38e25c7c31def8a3a8052d9031cce70797112b8f17b5ec08ac73ac44c466f2a49ee24e1e9d442638d4d0cddd0030a62a1ef997a06f218361b1af398833f4fa4820afd0bdc8b1a4c75d28d09e7b803146249480c15391b78160127c1d75c1a7ca21f690980fab2e866f8f0af6ae12e664d1cf43bd59531586128a630aeb59cc3f74c3e8ff1a35697e725dbebfb1f957f4ca1cfc1bfa4d82799d528495c5f2523b719869241d4184f530da51c3c9dd00f6958d74dbf1b00f13c11a136d63dc42ebd0b0151111540e8cb3af7284d702eefcbd6a0b019eb066bcd513f017447db11d8d423cee7507df2f950dfc3cffa59d944b3ec74140a38782b3ee99843b3ce1f352ddc6628f2af5165fa534c116855f7ab121b61f0723ab1198da782b1fbbb15c1111b3511ed6042879313afd1f38a317cc05893ec21796f44120350ae9cbbd73db2b3928732d97dd68b236f030719db7fdd3711ddaa3eb34c84e43daa44f9fb4aa375b96561fb010df297420f5b22e302c4b6d286eaffbf012cdf63a2f3768d4db4e0908d9b17aa18457a760798c7cd3e94cb550375b1fe72b1f9763be97c0dc4dd41c4ffc9d3bd36450db13dbd7ba64ec95e86118ad5a81cb403eeedbb72aff90f0fb8a0aa709844b1fdd4138b7d3f76753f09288ab0ec3124cd78ce4243e47f129d5e689b26d68f7e026960c9711e1a0490dd0c66a6549c94d1cdc27634977ecec270307eee9e07b1032834b9e76e951a1bf30bb83e193dfe64550c53b6af2ec2f381ab37416ab7ce8c8634bb7735144f27019fb030b915583418c21cb77572cede35565d4ed925a491f743cef7f14e765cb57da6ad85b7f3e51a203e837d32dcae20717dc8eedf8b8a2b784d89fbcad1b25d147a0fecd3ae18a5f3a56e4873844c97b1edcbc44b28ec7c84e8b95afd28445f80f5718d4d97c4d6ae89d42abf3198e1238f04e81ad4ccf4954a698ae2f06d4ce767bceac51d7a985d4b27b548576f567eed04e79690f4f5d1d3052904574ca38f34e47442bd8f5616b5245baf6a4bc07036b396e020f668f81e543f1616a462505cdc0fd3c362bbb912b93934f5e75d9fc6df7805c4c62ecf029253cf9ce837719bd6d0d336ac56a654a1196da3ad0ed0e041d42f0954a34c567a63a023c7b62ccdb82d7ffa3481dccfb251c77299d957f7328b1f365a2930a656607a539f8ca2a6112a4d80f1f260f88843cf2e79823a1a9ae5d9c9396ad054805c9f98d8160031f0963b16857e6de5d3476415dddb66bb2bd496b615f4a949f1c350576fae04c663981336958052eea35154461e0fbabfe468bfe3c3d64244171d55998ad1fdf98d59696d44d142432679a9ab771428d1fe1ff0fb5e934e9d99b0ad46003511781ca1041aa30fae42e36a817079f30eabdfb77393e630f86a812a468fe0aaaa66d1de979192138cacdfbd86f189f3e630ddd1381f259ebe0a08e0dd6142e33d282a0a5b346e2b421b44da31b647d7ae910e5ac841c52069414cd9a4950348fe45eaa662d7adddb6106774fe20c7f65bffafc4a788da4925abc4d336719935d4e01972b836d3629220a9b8dea25eb97211ba13600e84819358242bf37fcec1488a149cf385931d530d6b2ee11096a803ab0694fa52532342d59e3973907fc68c1bfea9235722efa325ea589b0324abfbcc29394d99626baa832e6cdffc7f3721d2a4c03eb3f125bf3f6150ef9911c83922bbc450037ebbd2a3ac21838cf75ef4bb8ac90a862a1478f6f74380f66065591b1cfc98ab2189badcd85fc8f2148d1034c56dc8360b02ac6685e828333bcc5d9d07e73aca58e272fcebcd845f8103c3827ba3235cc5b4934277b788cf4d8927c20e62ac3d6e8e0e046a0a9c69d3bb3590b4ad66efe33e424533f6cd93a6afa2f6100b6f50ec2ffef5a67426a1d4057d1d54f6a52f4d58b38713c6aac779155c30e225e7748d80d1d9b3ed4b3dc119ab69c6d320bbb39aea287aa50a", "5151526553535153", 0, 1919079238, 0, "913964915651ff7c48d5f03017431af8c54ef932d9454c870b183ee3d289e333"], + ["030000807082c4030195dcddfa5d27f1f8c219b10bab3dcc32ea93092fdcf7f99f118ad92c6fb97290020000000163ffffffff030a3558010000000000cf44dc0400000000003b74200500000000025165cbba46c0446e74160300000000000000009002590500000000163c564f89f2b65fc37626f2c00f382c631f8af4d279af29edc0932422191db8a0bb6df940e4cd20c45ee91fbf4edfc4061a8f60297e45d77b7e808cf5e27c413dda4cc46503cc8039b6c14c0c23c8fff512e8422971a11b71198eb1d25695fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f697f39a47de45fc1225a3aee64ed2d422b03f512dd6a2b4f74addffa1f4db0661350b62010825cab08cfb296e6b35b24df5f1577bea258397405bb67f582a7760e2824f19fc319b676d7eaca1ddf6b963e580a99115ab03bb536b60aa96489ae8cdbecaf70d8b004f3da938b446ea994e48b507b9b7a1a471ae22e682bc35f030c28859de1535be46ba62e455477a4636d1929c10f28d40a43daa9c024ccf3320300ba0773afe160ac6661bc09772608dcf1871e07c11ef212bc55d9b5cba10dd00b0657cfb5290535109731af26377969d32d6b7615719cf8d0022e966f7d4db1a8b840ebeeb35706880ec7c8dfea7d8695f0b438aac25be857365dc47129bed0fc021561dfe9c233444158b0e3474483d873e5b4c325d8bbc9151087cc8fdcc229000218741de04d88a46e0c69d2f340d0d1f6425c82ca09f137aa47a5ab8f8e887985030609d31ef3a60face7ca57be255db042ff12d1f1eafe6ee0b9016f4a94497208021c21406e9b9ac064f1d031bb4df321d47f96fc582753a39ffeb3bd032c0f2e0f020453a61efab2a718da92f5b7d1f8cc89a7992897e776a9630a5aa80e8bef8233fa335893b3fd6912507cb5a0d240c3baedbd44ba0759c39f396f20ff28031c87b83321aedf244a66f8eebee7025d218c06b52328bbbdeee297da592529c50ca1ad19b7dc5a94c98c551a3483d9db39ac04ad6fd8b1fe544f5b0757127ceb478ec415ee08ab9b88f0466d478a310a6e2644ba2afca672e8d8eae9d83de9ffd77dffb23cd9ccc554500cb0832571d4cd25df85fa49808149f07606d0a399adc7ff723067d7ae42c5841389c18c8c36f37743c3ffdbd8ec0c5062add31612a69ac2122d097e3a19f7e431fa97048348c2da652de53de83fc8dadcfe5003993938c1ca7aec3a812d79c4b79910cca2a4a12712496a5d65ce48abac878d25fed58a09899f3e9f60f0490dcfdc880c2bf4f2a1a550abd8cf8d8064503b8ebfd0a41a9a77b897b336722ae064d23255bf5762d6bdd183edb091621c5be60821ba00af1cda9e0f9226f8fefe00135e643f2c7a9b824cf98af0de406c9bca87e9b6d004cac60c2f6a6e38df3c790115b7e9d3753a09d549a9858b01b8d81c556110604753c66c21808b6cfc3928538ec5bfe276e3e2ae9585932cf0288ba5f8916261f705a8db853091be65ba77479973556d04c42416f03c136c8937673c43bd28ec038776741024f63fbb83c89d46d00dca3c2eb1bc7f5c5b91136d550e541fb8210044f2304d3c05de5e5572f8a66f489d58f9913cf623d296c9048abeacd5bf3b9e1870bec7ec93b8f8ae09ec3c34a5c26d74397bdc03039ca36e882b9d55227003a4cdcdf504fa95751f3ccb0f57819ed27c5af02786fb793c0395dffee7397cef5c90abacb6b0c6ae64f5e6495f53cdbefbaee346be0197d06d68d4c9f59cef60d1fe1da8943ca99167ea9bebb3d3dda9f3000c2e19316b6ca127976aea20666ae6e668f565ba7324a79038d3f8f969910b487731cb3b4d119f4f0c74af26d4bcde06b3352ab05ad9818087bf4197b1d36dbdb9972bc644133330925449a115dded7cd1e663c5062c0b99a43fe499bbc265aefa6cf55696403586bc3c58746046eda7183bef2ee684ab20c8b2e8567ee3ffdfd25225263fc280822161f16647f012fa418f4ddb5bd467bb6dc3ea5194869d2da04a6a02b509c83a4f325bc198207c3f9d9f1304373825a337e885637c80c871bf597f145cd373c11a0b8c9b6decb30cc9255fd54d2979b546660f61cd5463c73c32840fd18d483a3a3615a6a233c1026eeece4fbf5c6388184c73a9dde937126142db42bdec733d42ee721807263cbcab9961d633e070f7f6732fa3595a06437d162dc8238749318e34fdb1232f4ff90d41cf040c6339e7485e727c3d84c9891b88e860bcdcac2298160edf0c8589d1f5d3903e584e799cad0d220661f4ca77ca233a59044d3dd0308c6eb50667cbb0ad5e99a45dbaaa386b4f64c23dfe9306a9cf4fab3589f52e67761880263731928986af39eff920f8bd786d714bc8b3d048dd96c1bf4768db24d16c13f68b43c5db2fd57625866b5244fb0f3755525b348282545895d5403d090139c90d1e2b27c063f02c2e4f84692d8a85cc70c8185a284b6fbf3bc029422d1fd045ab729b9a424bfcc438873c94d717990066f267def5bb8f33e7a720379e4a0e93c7045975e2f1afe6d5fb27b20da776dbde9e1cb926a18e6dc230adfc7ac5332a6577313e07cd8fb80baa99333c238349c4972eaac2402dc4010000000000000000000000004eee78a6b0cace20564dc3edb4c69ff9ad2d2b128074e4ae68b909808f394dc5f43c8aa1d8c8c1835e0e97a963b5416de907aaa8ee7cac121b02d11fb2c33bdd2588d9bcf74c6cc51b2e5613aa41a42458be37269301613a5066775bbefae3f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a726be2fe05362ad73f5281c34d98d7487c4b1bd9c7891c6c564bf57e32cfb754c85701629ff1562125c7c8bd7e8247990162c16b116002b8b69f64dbb2181ded38a483741fad64e77c481fabc1ca3f855e2e480f56f4934bdeb98a6438eb96c40df571097437e01dce5da4b5b5a255ecfecdc1f0c0084f03b55ed7b527726480222f0bb2308bf927e72d6662553e6394a3a31f64f34496b23cb9f203c27fcbf3d0203f6d572157beee9a85b5e5d07d91da1ec3db737c3a1f8f148e3773cd6d3e20c0a062806855eb3ce4eee64b2b08d70e614472db024e271639da70eab6e11f766e98e5584d040ed7598eb5afb49be3f506e706bf93c6b9c33189bd0097111f737ed032f3b3f69b6eec686e2a550ac8e823007178d4fad131adbc7a3354719ba82afc903225101a47aa2ddb5d0ad54b97e4a04393bffd6515098c619a6afbd76be38f2cd030ecfa2987e29d95fb88049f55daf24f0f2fe6b6a97107cbb90a9356c95000252031c22c563083cd4b39dd3a6f04c52b819a51aed7ac9c5bd27c54be40be4671118020d9f80f0383f0d18ae927047c4f43dc36b5cbcb5ac9c2434787fbd7ce84a957cc7d44da19ab1ef3ad1107bdde113b168aa74beb42e73b598bda9bdc62f8565d5015d4dc8ad1a8cdf65119c6204edb2f31c6f195f1da418bf9bd2d365dc158c5dd6a9f7617802a31d42597b8e7ffec0e94f0af90d460b1f369e718c1a2b60dbbbaa96256bbbe0bb7ecd33e7c0caf769b85d3de622ad6d6e239c878e98aa894b2be961f5a29460c5b6a3e3adacb0c4a8eaf12e661177393d4e86306fa6c0314d2965411e6b391211995d6d1070622e9f6039acc8c396e17676978ff0812c2e5db0e5cfa30883911c5281e964c7354859325bded4e234e7352e9ebc8eaa14a6cfe6d47cf44be55fe71007e197bb1a709d8d69270c1a3a8813beb47bd1366d1f97845b7736ad8126eb25c7f52dbacdef1ffff9c73ac948b722901bb24ca5004cdaa9cd4377a723a92004c8cba9e441004573c92cbd1462dd5f9f8e306c897d783a1e2997e462b5c817558c82b4a4964fc589a383160eaf2fe70de958e74c72283b41607d67f9405a65d7eae95a6411195d7fd2cc98196dc3c8738b970f14e194bb9f9f70fe0d602ac70db4d54d6a75239c561f1f5132cab3e24165dde4fd995347baafc7989daf891fe9717eabd73a4b4d36a3864a99bccc1e0ee4251a2420559129d487e31db62d91536eda37d8a3804c24648c2b87b26364a4d96ddf8cb92adf9499433e4903c237a4be5713534ee388cc05254c18299f68edf9803d1a69ded06bdc60a23a7f943cecd87d64c61f15a1c0a4dd016afc76a78a0ff3d2832d5348bab169ac0635b7aef1451cf641ee5c6cbc38f1f9f8840d939e4f6a28bd69b7ea05d5d2b9c4029a464331a1172e666d09d21e046cbaca3f7ea9ecd86412db24fbbdcc6305462e5090c77d3b53fc11ddad38f74954904bee2bb694e19a00a127c7e0688d6d017882c964e896c80e909cdcd125d4c5769415aea4a40a15ecd1647369fc443f01ff32db069a9e248a41eb4cf680f6c6fa7335aa031673e0d4f55581ad41413c8d7fb50738cc9719051c9896328f7dd7d4f5acacf2f499a05df1bec9bf05497dcadb186ba3f0e70ade9e4a22b246d051e6678ee7252c9226af5cf2704fe794c3f9e7edc41270ef4c116b7c1f0d78426ec186ea909e221cfd511bcdae8c9432f5e6b6fd2a6277cc287d537e110eae0686b82921e937d612fa3570de22b23034e67b442c29fa9bd3e3c8159fa8c56019f0209e879f93bc8d793c2c0b6126e6b0d3db4902d631b042a99039145c3e0009c92219a8001f65f5d8fec1b7bf920700e759f25d4870432ff486fbcae055865b7da95c71375a45106782c6146309467b77efa9cc74eef4918f1224968e054f7503be8998e66d8fd1432a48c5f3fc10de8d54807be2aa01107bf4df1e6a50140e0c6c6a2f2b803f332b0891573b9f587745d198bae4a4ef476ec17181b53168f99dda3ad95c522746f7759ad5fe7871e03e1cf804013ee9187ed8a833f0a5c6d568c43db130e5d1c5c01961830d30f1a4cccd751240e71a314e176f9cc7f2d5b836e788384e39b0f2d8d8930435d03a239cb2637aa2f01eac34b4409e6402d6c01a7ec32fc02df4219a11a3a3d045ea679073f7ac1c6f3ddcb6637bd5c5921cd5d32f646bdbe17ddb90cf19fb091b211179c451275bdcff319062c491c0141ed3d5f95ed49101a8cdb94294a4a5a3a5d05001245788bea25872d87fea81464b6d327e7e03000000000000000000000000ceb8c70edda1cf151797be4dc8d4ff480d510b614ad058f0eb58d1c773135d5dba3c2526a206b98be1b3bfeb7c04b99a5b048bdd44e4983ca09d870fabe002bf84af03cf31c2c0b8bdf592dcb21439a9ba9e140cfe7a326eca299589fcd8a89b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb2eb7b387ad1d2fa1f9157340c2bba41e9510c6788fe9b31eaa4f688062448c45a62ddaf3a5747bb1c46a9052ea7fdcfbb7b6f1c52b828e6b42cc33a2db5d209b49310d9f4b55f1c02cc824e1eafe300e2afae94b5572af8d35e34a5deeda9b19a404838f4ba8d915500426b8bb6f97bf67cbc4be7a682d959e89175429f833021e17c158debce01c9cd54f41f6372d75702a76bd18debf67b73a983c9dab3935021d934550bcb13d9beef7da826e3a70b348dcc1346276ebab9a08aa0eb34976260a069e19044480104d1c94b2f328f802c7ec620f71b9246c1013d899e3e40aa5bb7df961de86994a40666137f4822a67619690c30b054e12d4adacbe01812059ad03117cfb541d8a02f2de25b09ae74d062cd0bf54c738e1ccf83988e36a174925c10328685ef56516265f1a462376055500cf8aa481a92cde1f219ce59d3180017a1a030ccb1585ac9e30d4c387d077b9f88a5b919dfd8790b68b6aa3deb3d6688dbd3a0312ae3f3536f74118c6c9488504a50b43d52eedbf7c8df71d453fc16f653da29a020881bc530f8ea198307ef98d1cb875eff7b9f335ebde2575eebfa83872263f6ee862ef934a2ffb2020faf22df7b00f7cb8e475b92e9fd82574eb963f4609c364d803c58648a2ec73cb6edfa1b52aca6df4975008d33f7a565267f7686e27d86e6e5d4c44778ca98c11fc24a1c8621f1b298d3b70072506cd08da4dd9c252fbcdd0ff3d499ea9763aa510ea098757ff3de046d3fefb0a3e52ebef06de943e135705ccef0bc6aec7f332cebd72a04fa298895b94c5b68401454c9e9d15c199d0e5a468f0b47903221f223ee7d9b8cbdd4e1ce37c860bfb12ae1e2377baf054225d52ba7ceae7ce95dcba99e4e029a56dc2fe2bb81477c700afbaa43acdfeb4457851c16fb6238083a016635598c5017e38b118d494011bb3751c3298a9e6a7a3556a6303a2f4ade37f56d4f573f217b6b0a58257ae3ecbb37a36eeaa764fa672d59c8ebd0a9764488d346b439e56b083c4bbabbea230d226351508a9e7e68084e985ca4d180147973e519d72553443e14ff4d36ec89ba61bc9505a0682d56caca5877c58c33e8f93a75827b316dfc484f30500e8eaf6eaaf2645571462750bc6028e4b1eedee114f91a60a193675c456ded24adb6fea2fd522f790380516c0fdae6cab073b4b1a82ff3fce7dc8d8ba98fad2db2d91cf69a7c4eabc378981be85374c493b4b34d402ef1295e1e236d98a6caa5d62c8d41f4ac5f1cdf45f02f9ef0320b7e9693bcbd6f04fa35d4da76bf8953da23685570c427f1138f71b30c1257d3e86770a500d11e5f4ede39fd34a02a9cc7ee57c2e55445d8255218fe2fe0be4e4c9d929670d2b121cf5f0aba50f9d2fd3ed09263e371a958d0034016963bdf396d768e92c4797517f569ff3162263b53617b750fa2744925ea77f114b5ba551c3bceb4c0aa1d5c0317f1a9057d132f30efaec6cedca7b7df3d3cd999cae446320c1f5676078bd7ef71c8a723dd6e887f4f096b12da4d7fb025810ff3a43f19afc81bf90943a1b2c5ae2273e63674a2714eef7a75f7ab5bbd61221dedeb2bdc559e63e0ca70dfc64ffd3a96fc510f179c836254b3837beca1e52536fc592a6ca3d114a34157f1221ce9b1e4f652d698a874103164fca580575d246b6664f80250abe9de98e913a366333bb37169acc2e730da0d16b9cfba777ffcc912d1bc7ca06fa4e8984096152ef838bb999b59ca13712ec903fb7b9a5162f553461ae15f87e8f7b673fa57c760ce8b95c869d9165db2732a74967d3af855b2a90f94c3880c68ff71258660d6ed678ed00af0a240a088d8cf85d122e47957ecab89a5c9891583a0073760b558fc4a483a3a4d9ec529339d3aed2c64cfd7dabf0228e7bda08dacb98176f2ddcf76e6d46ca6e640d06f2fd00347c2916cadd690aea33f17b4e7d87f233f7cb3bc854e56805f9f34219988e0697210d394f8b78f571332cff709da60ca6ee55485b057d3f4df8fafd71bcf855e1951def13d98bebb5b3f165ddcc4aa8c6c4c9a2e828433d80fa6e073ca36746878de89c10e3cdcd5096b571cb39ba17ecd7723660b31ff697915de4749af587b7e890e9bff1e049d91734fe1819c78dc2414cd6af3e5140ae57022697a93171be164a94da95fc7d2f24d4ffc7e44e28de5e20149dc6dfb1140c6e10d0feba5e87a827723319dbb22fbd38f394adeb064cbe0759cf3818131deb3d97d75130938a7cadedaa8ebb36e22417b023269508c63a49f663821a336326c433d0463160069468f44255f7ce2c688f764854421fe00d998d3813603d5863445a0aace85b738efb62b912e4651692ee584ff176afe6908c93b084ae3a404117acfa3c6c45b2f895c5dde7d1852fd08aabc02c6698da9f5775e3f0d40890d11187f96a04", "63656553ac", 0, -874386906, 1537743641, "de3a02d0be1467862168d8e0d5fb5a6bca9d7f68ed326f699f362f17c357a28a"], + ["030000807082c403029fff46d7af8fbbe250c1196bd9353d9f88cb714194b9e57509b0eddaaf45e8eb00000000066a6553ac65632e7d3e836630c41827647b04196a69abcb11b8e4d3801f04eae89b7d17672fcc7ae14bf00100000000ffffffff043d67d105000000000852ac6365516a6a5178ce7504000000000452655152aa1e6d0300000000080000ac0065520051c884000200000000026363000000002a6e110b00", "52", 0, -1183916109, 0, "57b50eac61a80809f8a06d855fdc9581633e4cf86ea6a3589e45999a98bc8a1f"], + ["030000807082c403027608d7e0cfe502aeac644b07eae2c5d90885195967c419f6bd59f6af076d742d02000000026352ffffffff44192d67b4a06d7aa66d7c07ed266f9eb6228235cf6b839cb4e69f9e2e9a119d0300000000ffffffff0464459c03000000000852acac6565ac51652bfd400200000000070051536a510000daf4f50000000000055200516a51d56e4b0000000000056a6a52ac52000000000000000002ecd99c05000000000000000000000000547f3129690e9db4e3f62001b238d1f9a04bc14c7aa70dd3de31e45ba7ba78ef46f60d3d9f279c18f111817a85da5a952d20158151c0d32b581c0c15b1386393bf74f4ec4c51a87913e6e99a7f94e00b9e75c7636179b0caf3274d791ecfec5c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a677172bc81bf498c4d916c9bcaa6ec3a57864d2bf8ad6c351c6a81318aa40881ce8159be35bdae6a372867ea34b312e461876c5940e0c9518e7c89529a1a4dcc422c68815534547fcc0e5c0b244bd9d00cfed2c5f28c5439d07ea682858942379b1d307a854bbe20a7f4a0214755efbf02501e2c4c9a17548de0b1c05d7be360316c462c0c088028bc5a6c972d7dade1632b66f61efff9a7413ccf6604868616f031d5b9b133a1c861252e1454e370a17a6226c1fe64842acb785c9d9eb59a4897d0a051b16ed3e34838759b8408a8c66584ed736daf4601b16ae1f1eee1c387c47a526d24516f41c0d98f70cad434a01f1c181f10571a66968aaf55dc40aa7c6170b02020e493aadb178b96896d0012474b1d49a2ab9b4697884098ffe2b156db8a503021c0644fb9b93f6d2731b772c58a347d63c383253196a24222abf0189620ad22f0313152c5cbccee68d4d282247ac07edb868b985b4771119cf702ee31d9964a2e40201e0545ec644bb708800649a4d9a6311b7ad0950cf00ccd58b5431c6cf4c8e4a021795270e097d4789b7a3d132991759263092f5b2848dec63ccdfd481773770c349460704eda4bf29869c22110afa5bafd434642eebf707fbea8d2dbe57c9377df0682bc72d8e43c9353c498fdf2410c1e01c53675340dc8a461adddf66d16f1b7a0c9df4658a0f9fb66769b896009582f0d1b99784735f5e6176646fe144154b87a05e6d8fd53ab773e794af10e347c3e7f48710be17227505b8b38b5abf154ba60ea588522107584dc371c6e1aa0b7ee0ab3ae43f01eb63d350063870648ef99d8ba3e5e1d008c77ea93dcebdadcc740ce72339ebfe313e8a587a28eb0fe35ef7120f2c73c98ac5bbb16b44fe813c4eaac0a16910ceb806fb7da3772e95dba2fdda168538258cd00c5bfca742695bbb310fd74918fff7920cc116dd91b01edda50e619300c99d63db66f791d800bdb4dad0eb7bd7348f9baffea3386d132e158e24354ddabba685c808dc7716b11f79a0c00836280450d7d4c838b50e296a309cf79123885d2b91865f5d40325e0341402245c0a577346c5d8f51e6b54c6f0eef67ca026ef35952e5c07038e1705462bb230bc124e19d6bfa75630361355b9f088111cc2df309a53dbc8958e8ee1b3cc4d662061b552d7e1d4525dd39c3595c92d5a9e923a6d919463d7fa018ef8062a1d0e9341019796a3efec36e4fefc7cb0c1dca5632d887a81136c6d24d2c0ca0e2a1df61798a3428ebf2976c0a30c16c1bbe9b048432061743c1271eb4935ee73c5c0d21d358b096d9cc05516ae865b20c8cf66adebe9627121dd74c3d5c9af6d046d83708458d580077371710ae406d4f790af7aaf853133f205317266affa92f403c6ab35af50a4330499ffa784d62ef46b35912261bfe5e9b6e56a390c6317e5e5df2d388eefefc2d89e7ea31e70f6f3e1baac68a4bf72c8a7e64d88c2ac36881108155127fced50790816a2ff3fe41a26ca6fddabba991bbb426b8b67e17a6c7660f91569b126acfbf61ccb24647a5a1e0fe1442774f90a9069aef1e3fc647ccf1a86619da9b3dd27a052b8053f5dd8e297878008a301c6fe9088557413181de18574d8fe159f9be4a3fbbcfee638243ca57784f5b16a9e4874afd582ea10379e202eccd73ae168cf87a640b70c3d94ddd2d3f648369010dcb7ba0e1a81d5dc0652dcda05b8f3b52114775f3ecaed7f5d5139cc5431b41a3205400e875c8315b10ceba7193f86ac4cdcd3531a59fbc1f48dfafa4b0f0d1d6c1244ccb48f48d9a9af9bd3d3433d2758165d68353ac76c090a757888ab3a61af37a295664070c34a01a1121ffda3685e581b3a8693ab754bfd165d20bab2f4e4007bc4215dba8dfbcc6d4e75a828c3c724172d655facd9bc6401ce603262c8631defaa06e44cf9e61d072c9ae3eb81f1ab637198c8ba20da5dc4ceffc925d200fc57ec1aa3036b31b7047c58091c5f58ec60f86795b951b840fca294908cd954df049c6c295ef476fe8d9a71bc8825b92bb23d1d7090b2453d3354928dfb8d9c007b20cf07fdaad79ee7e22bd0822348f4956db6c7ad872a6bfa6008a7814a99f5606709556cde879ef57f1e5badd5925c44dcda879f177f310381fd0e19a91c620aed6f15015924162f742691bbe48648c7da014acf2eae548599987435858ee50dd04834412724d5a7a5473d812dde4fc380c9722d1ab4f9b8e729b668213efd9feb5812077954ca98f0082d7d5f180bcd2879e02ce9053331e863462d738c305b65bb8b7464a0000000000000000484c61000000000064e62aa5d9915ec031271c92770216c3cb9d8e91f0b0389d3c015d88800023f3bbc6a3d6ab36c5c51f27e5dc5cf19127bc9ecd32e4bfca4492c0c5c98044822e96db2cd749990c452b47f768a404c11874450f5f1a57eb6d6bb05d9d39a825b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a899cfaf63edc1cb7eec126aa9aab2cd57ab86dee06ed31f67b059e076e10925486173913a488d8c076061a11031feffd89016938f8268a09869bc24671aecab2264c4e8d5c1663717b250737965fcb7ed2cfd0547f6595d054fd66119cd88fa0f81cfccd216abf11f0a528784ba14ebe9085f512d1a91632737c27745c8247031ebfe8d2495ae1815357a887ade78d80c64e84395b55597f6fa05fed1e1f32f4020042f53d3d3a52770ae1861ffa06c8f6f2e22407ce5d954969a6c8c6b5b825b90b06ea395a444ff7b6984ae4a396e33ee86b63761d67eda0e43f945c5c65cd8371778d84ac0a91517e38cab043155043f0c27d3a3a8b6a666bd8a8881cf7dcb06b021ef7b03fa1b83af17d94688df8bf8c42ce611c0fc62f0b214541c9c6bc4540290315ae9a91c5087680e56051e43928a2ab7a0dbb62ea5a0349725ba1f170fafef5031776a5fe344ee52622902c4969daf12c89316412f1254dac88c99c8315bbb8b10214a721b5fe93615ae6e1126fa108a28bc77edf065414abb5e3a3fc00ad7fd32a032a11819f35a39afc853ada688c76acd091514720361e10a79244064b1ce8af20691d3ea21fa58a82b75503d9f2d6d639bf94a932d13ce7c548bb34e330aa714d6199aaf9d7cfd81767366e16693f46ad09aa60b2c3692cf3b361a119a55e41b075f5e64aa888a729d72bf47cead33fdf802ec75bf59ea986bd81118ad5409f6d4023b3526ece30ce5cc97ea128c2ab7819aef5c548439c9a3e1e7dd7fe4ba116cdeb44b2d1e0500289117f30c40be6eb9e3443e4fd3e201ace0a7be9a2345ccf6494782374fb374b52f78172bb927bcc152a19e6377964de13ad876e12f5eb64071bf059dbadca56315b32755622b701843889bece6611252d179c401c6fbbd9d1110a2e582ea3e5af2f34a35f8373e3645ac80cc736fa06171ef2e3e5f2afbbf1e565aeaf66e72816ca529fe0ecaaecff53b20e806e9cc3e6f265ba2814fbe5a4b9c14d3afbaa886c3387c35e77a2cff5263eee087b547a5ea6610cc6e7cb346be3b30f8fee7e63de8b7d7e49fb32c5b9df7eeec57e215116101110e0c6b522bfb38ca699b25b310728419edff9a475c226f595933b5cf1a17ec21957a9c6b99d538da2f65dba24a98c0436b4b687802211a8cfc3c4525727637a5f590bc65e3909c80f0135b00d0f4ab4c7fb9d66f35e18af91637568b0956bdf511dc4104920489cf4fc425998f5dec1eda0ecb533a042f524976661adb4def84cc0b5b84f5d732886b3342f230bb8cb6074c56002691c0aec3d992f331b4ce193ebdc799437bdd6ddf033579f01a10aa9015ee9d14dc84a1e15b76feb040c980eb27a0e7a8385719c65fc591493cf03064c3a6e188649daf9890497fb7d3d620e601441b7ad8cc25ed8cd3ec1fa466e08421fdc86af6312f9ca1626489ee99ca3d120a1eaaa864d94eb2c7f5c2c22b46aa8497d552ee73356ad2a663576606f01ee0002a979a5132a266058e95f961f8a0bfbfbf718dc9db7b9823ade5d97b6a55f9f79499c40ce0e75121e8c22f2899623079aa8febbf346b35dde3112ce15a2ec2aaeae04bd39ca6e2c685932494d91d694bf4104810183ba3b8ecb706aa12f8bee109f8d7a48111ba8f3d86bc289d4b5dd5e7ed69a1216ad48ce759ddfc538c12ceeae8d5e7c13676ed012f233636e532570879f0b5645cb415eb0716bf450e08ffec856bb3e0c41b7a57b2f6fc995e54fe8375ad6399fa7677e31611af27c090e987fd6a58eefb250ae17c4bff9187131f8cd19abd6699f7d57fc3d105248ec30c59ccb89a08d7db15f95abb2a7cd4ecff51d7ff71478e3c377311e500d529d58f81633b3c6251e943b21c6cbda463019ca6e467581cda08c6b7a219969067010b1cd826ccc5120560ac405c3a85b92a5dab1d27383e2cd9ff858e58c8b11d45b19fde20115c0359e33df1b1018e6bd332e810e7bfffdd2fb73d3a7f500505de9828dec26efeed41d1c771bd142c105a514faa5424f6e7dee0987d0dfe7d2e85cd8d0ccca608c7dfbc5fd55e3b2e6179f2e0f7bfe97609b803e8cb3d10a0c85d28eb9149502aa7411d7a9af3c6818452f303f3e2c686c3e51ed3adafdcf0662d73a9181a6966a724fb5693851c0c4e50538a5db57cd4ecf61dc147fe6939f17356b2426b56ea2840018a48b6390cff4616cb07306c398422415181644c129b09ea5c6c892387e5f55528ff46c062a8f6cf7b6c735385239545b2075c90e34205a7cb2ca2641a0fc91199ea686b81a0a6465a8014512b1c432761e68fbd83a561218d3adede892cad82ab5834a3c6d6cdb34d5f4fb6a572be9c655047e4966b544b38fa53bc3a3eaa280df7f99fb1a8193a8fa369189589b1b643990c1fe896ec167961ae2155b2db58541f913905ddeb10d06a406", "526a52ac656a516363", 1, 672853410, 0, "1174411d4ae04d2632fa36a43a98429a761661bdf4b8e3553327f40285aa0aaa"], + ["02f505480318db37bbb1be98996af503917b3c9a3ba6c956d967bb12efe6e8c531fa45f4ce0000000000b8467d5482bb87e07a9f02e536fe594456ad74009b4828e4c620d81f4433713e571c394601000000055352acac63ffffffff2ee04143042fafe9aeb6cc20b2c221065382597a833d1f1a3dcc900cdbb001440300000003acac51ffffffff04a039e90300000000025151b619480200000000045200520053df990400000000035100ac1d11ed0100000000045300005200000000030000000000000000d6ab670400000000016969c0982d40594086a02774e58508714b797e56ce736a1196b3a4c44f9135899289dcef696c7eb1553bf2cd4f5d0a67e02ae5b74bc07d88438f570990c516042d4859f4acdd65c72892c3710fee4df5262f243de7da045b57dd1dd484d08c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304f03894ef352d27c499bcff74fd0042c32aeba94e996c5d53aad697f8f86f3c5d6a78e0b978375872259a365ccb6af701ca8cbdaea120da9a16db8619363784a778dca9fa74164ccb9300dcb653b1b32bfc92a6f29db9731429db0ef4cd16932c7190db71c81986338f98060ab54c64fef88c99c4b4c677dc6818386f5dcb902144ffa56014ce120dd5c876d31d184cb62d08c5123b86c24ee9748300667881603295b5ea1afcd6c241176e17d2c96d8e29e00df645cf802a96e19140b739d25410b014c420f2ef4f73cfc5c89737ee9c224e8336b512382841ac0a6a98c5503b97db1232a27de9c94f0c89671c60c455b4c027a196f564d418dc92f037acf71922c0216548cb539be50bc3f07ed86133d1aabc1daab3a69fd37227986ea841c36bd11020360ff241a33e97871e7685815e21feb194a631e266b0d391fb645710062e303030bd393c567ca7d57c1932d3802fa199c81f65351bf16bd16c4fd194b095a3efa022c7a64a78500cdac7c88cb459f12cd26f4edb2afae750894aa7938a5e3ff55c103142552b4053c123ae9f3531c694693a7a3128af125ec91b4bcf4c5130f342a7264425708a29e8cd0db0e35234377b7a588783797ac4178c9ff6210b3bde2e7f5c0570387214920402a5e58624108c3358ea0ae14b97b016d450e217e1fc3ab817f460ef9a15c2a1b84618983aa61d3933b8bf3f65828901a83e4c0ee311284ef57ed4ca56418883188ab0b144a439ff0d1de763228bc5538276765c567f33227600fbbd988a9d433c4fe6576cb874b6701755926e122fac17fb01bf36068acb13a8e4c3c2b81c8cae591892338100f4f82384d905c3796c42ef96a708afab2566683816b3f1cdbafe5fec71002457501e03bd59886f9f222eb6b1c2b158952668ff3973eca598169544952db129d651852946eaf0c94aba0874c682145848ea6932deefd38cd46a9db7202cd97c25eb4d19205225cce7d6acc0288c74597238e079e366b771a90a0c0d7944eddef2da0176747ac7f7f542f600ab59a9ba02b5c9917c7abe96534b5fa6e159ede5630eb539293296520bae6aaff2e76f532549e9b74865590e82819dd1782bf8b910a26495382a4d8292a985bf947364069cc2ddeab023452288c22aee0688c641f00357643c3bf4c61304072ec42bd8c69a9d977015e6116723bd0ac8a9154cd16580bf072a32b3b022cc9e87b122389975e22202977baf9cf3e0632e0e614e992e04f6b7458f6cef1c7c72e2a55c7e42b5a76d29a38794cda2737a6bf23f2d4b5eefb767b5e06b65c3c2fb62bb7ff43b573129e6ddfa7bc9b8042d76f738891f835b6f8bd48b2fda5809844d0f323889cb81c8d64b0535945253651efcbd98e63a6cb3433cef803f80ea7ac2f23a8bf80008cab08ca2b665f88352840005e48c46d380603c0c14fd76a3ba70430fe33f9b77da9d443b17ef4c98fdfc5b63474e06267adbf8fffb638ae150224873ecc2f79074dc0747ce31e8a21aa0908ec4d90286a0a2f29eec0eeff135e11079302ffde254b1d4924e8cc04f5c4911d529dd8d7d17e7edbe15baa901f48e83308f9b1ca3a81e724f70d8bd173f8943820b189d8e178f7949e447d9b7ab8547399caef42f824746ef07e0f9d760f4bd632fc014df035cc607857842cd49dd0b9b0f5ef89b931f4ff3d6c0793e967c63d6614248d2003b73ed5ff0099eb269dbd606c3c2bf2bd24652db7067414e81539bf984facc02a34017ab9b5f583afe8e8663707e047dbfc05fc5e48606f6f1413d24dc197bbcec9582e4209105436eb4a87da466974dd7f5458b5c882eca29aff2115f977fc084ec4658c4fa69cc83b4169e704951c09e75cc8aa78a68532c6512365877fbcdebdcba56d2df4b558c796acb15dc6de8ad4db50e7bc1e6a2ae2f7b15c9a6d8359bed6e30ea705bf514504c83cc4b4aeeabc7aa8dc1e837d681a2fe32c00ac4b994e6ad8f823c47840d5c98cc561ba7d18d9e40621475db8243153269cfcafa03ec083a6ce6adf492133a3360f92c89de0d5166d152bd2df9392bcd16b67c360e5fec716189a8f4c71a644e0432b26be3798338f00aec35e6117769e2f240a27da6e8da8f43b90d75cd6bd14ca6720afc285a2fe4b4ad39336a13fa0483ad59f79501c18d34fe9b58c4d35989d3fc6d1ec941c2c772c4a66587c26326d65e27a75e640f274e28443ee0e51e244d71b3ffdf119004495e158503026be5289534e6567320fec980a817d8c5d2b9832f14eb652c7d9fc6fe5260df5090ecf74c0e0306d1ed13b040000000000000000000000005c4dc5172a739a3d2c35e6a063f624202ffdc161cd07922477b4e15d17c868f30955086ded36f46f6635332c2622f41199ea830aa43eda8d0b37567e0bde88cfb7150edacc51244963118142e682f1e23d56bddc1ae1fb0c041e61c853e0be6800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000abeda43e3d36977437be6057a862695f8abfba0033456fa9ad5e8db033db363d7972c3442161631f9129c3f9d611890710d0e05caeedcbdef387f1c92d55b0c375335d4b8219c0a98134927441a808688cf337a466cfd189ed52846a868cbc7dac53635a0d9e3b0c9d9a174362a86b62f86ec2b37548d862db1a6bb14b43255203172d7d343a7fea9b7b3671b3341e515e1674b259e71b6c09a4fce259c77405cd031c328ccc0419bc04cf5dc845bc57e8bd511365a1b009393a741bfb29d5bd493b0b02554222e45384040b842f2cdd3dc3dcfa1e1c7c609698489b1628a725b70e01d0ea679199414a8ba4ad2aa71797479089805f6aba65db72d0490da672435490030c66cebb6e4e0c31caed288af8313c5a0ca783dafac9a817c4b2383bfb97eded032be6c82137c33a984983f5d85e4d2e0a9d60e40083d43512b0fe5f087f92482f0322efa9de1e3069dc927cb69d582c9d291da913f6fc4911e03bbbbf0c2ddabfa202237c55a86dc6d39e4e648c9b1f0bee51580755bdfb48fee4b5e51c03e13a4d450213dc1f9667935bcce6cfabb0e3f3e67955c62fb85e9b6f6cb5bdb34883ebfe2c02e36523fee1840472c50e7f984a770766f91b3c0d1fc76f161e312e7fe56f573bd266fb33c8c1a157eba9403f07f262c31a5e3a4e92764770ea33009cabe981f589407e722084ac70505eabe0f08a7ab2c17d2e47189f7f8775c015471a58d74b775f0dd79f70c05a27932685e29cb8293f0042ce19834882be18111a9c0390b378c533a28ad169552dfcf85464e1431996ed9000ead87997d5469e584f7d24f7f2dd962691e8a7f088710effed2f958ae8373526698879087ed12db11f2cf86e43c35fff2553c6fb49f05f567f97f9a76b4f50cd9704bf9a2e6da3b15a389d093b91722c12bd35b0620150df064c1e81fe9d4d50215f76303631c62f9db429a65c2dcdbdc01fb646796be00e2576e1d867c6c0f49ee4d2085b45990dc17716848e5135a27900f6af09130cdb7149352f5a0a05076599c9cdf3ed5399a2b8e814e15a014007babb638497c21805d2ddc34ba28cb29ddf12b51fec5ee09622ed055f03c147249ebe2c5c19e064cb1102b35e6fc5c52dd778ab85dc42abc416eae33fafc43b01a992ddae2fcbd6cf3f3b1b66b0f6893c85f1a397d946a572a9ad2d2442db9dbc806d02502f255a43be7895f77cb08e894af5fa81573423585bda3d648459074d12908eaea9a73229b55e53b1603f6adfdccee5e9b1b7afef549d5fed83bc7f553fb4258581f15b483f2a944d8a891635c02ec604c0aea33d002aca6d8d57e52211f4e070f1653a8e3960573d4f5d92be65637dd9a44dba5615b78203d2351c005d04d3dcebd5459e91226af24d28b526120a24f78a492174eb98e1fa66131a5f6d3225c8d4f0e071badd1e2f6b9c17c74445c3ae9799a8d60d0a17ef05de4c7d4ee7525ca93421d249d6913086427ed2cf70deeeedba1937ef4a88a32339923ab0b120734dbf5c70638b41023250df870e333e129f57c57a243c86bc8b8b5d62727ce7e4f802e1a3ebb5482d6c5c14f2cffd919b47e352322b189ba6b73f2bde9ec5db7abb8b0fb129100ae12fa3e65e3a49a1123a83954297e2ff6df5db874d8fbc1ffe9d9c7a1e78995f2ac5e2d89a87dce7533c935fc9e9294760a84cb586217474ab1f02fc62040854743670eece6332d6f87c83a35036ba35f0fabb6afc7c6f91a3a2e69c4ccf0735eba3e7ed4de2b76e3f9bb0ae17782c3afc1e48b47252387ad1a6edb7160f643cf6e76732dcdffdb3c5d36f6a4f02169c81df14fd23f35b9a778e5e81b5b85894d67bbf30f942736f437d4e9162b07764ce4b2775b5d74be1135bd91b93de1781c521a45b16f5de2de84e44de3d2f4b55f23ee96727a341ba641aaa409fd45b4a5a531ee4af1af8ca1539be29231e32cb6d5b0dc4d52c0b648bd61a58c41e35a6650a8efcb85c2c8ee5c2838d68462caf1532f64be3adfe186fc5bd6beb906652a3eb9e4b00fc6270e9cd337355f1682ea9676b4b521b754fba571f5912b849c4970e1bef766d1ef7b40ae48c220d1653088dc2977c973a98d8ad8b71c1b8503e4e09c6cf6b31b9d4ff56a19e349828cb1d1a97710c8e299d692df0de15220b042f244412dd25412b8b3277beeba04709fceb577c616a397c9efa367ac2f38427964c670a2835c16f6309028d968fbaa3c336802e571acd101d3064a5e2247adc0e434d80e84133f7fe18ccc210accba6d0d20b0e6bf77c4d152d47070f08c72271e56252050000000000000000000000005a2d4eaf11e51783d9d6a1479f6536c0f2773e0405f8eb49f9f72888149f357a49821942748fa0c863d03d10d08abe7e99ac66d7208ed3a8861b3cd1856cfed216a04d14fc61c44b3d01f13479ea5085ea46778be3ca06a8db118fc15b10716b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000217c348823b999be8fa94457dc6cf31a1344318f4e77dffc3bbce2f7e859b46ad99c07d0eda58138c348ede6a60be407ee32d72fd3269214724a036440d010d07c4b7929e5b0d011696fb8a3ff88aa725d51a532d3e9ec116c709186e361e605043f87fc909682095c088bf149c2781dce5d901bd97ef68f4574024156f4d67d021772194674ba9157f2150b51136217603707ffbacb7d4f2bac3778e3ede24aca0307b45847b9c804b5b70a67a50867096b517a36263009739c005bb7bf180cf2990a03d3b3a988d42f932e760284b94ef4f38eeb186fb391e711fb5279546fa8331e256dec68a937e879c7cbcafff51dbfd37adfc266a5e922b94b06747fcbe073ff032583d9b0fe3a1f53fab39a2d462aebd388aadb41ddb88d100dc088d03a5c6c990201bd77a34e0eb639c35a6da4733aa4f5a05edf2c03d874825edce2f0f7388716020135f370c19a48603a8a43107d95ce59441b65b3e7cb1a07676ced3c95c7bb5e0328cbdb753f3685527154a806156e358dc60f26d77015f192443c96e0863079c20316adde491dde3eb49592814d33ba10a9c7229ee0c2c2773f030e342a8c22069d3adfbd02fc8c207c7aa7dc2f65dbacdf72e0df41f38a621deceb4539cedfa8868ecc4126e9179e377ca8552c7bb1cb62c2deb55ef72240161e2e7a6b95b1a581cee11a8f77574d45a4ecc8b4fb1ce5c1c0386ee8a61e916dd357cbe98e018b688c1bb028a5e5cff3f4d50dc78fc1ffb2b245b1633291b349791e628e5fb1d5d276434e5447e85e6cbf92735e06b9abc28041330d6c9352eb76b07bb3ade60e8ecc71bc08c80d1ca2419e723d0e273c9f84a89a92041ec083d9bc34b56d65264acdcab6239b94144900c6dbf35e9871de3e5fbe4e9d4b7a4213687c0933b62eb8fd6d728f604580ff3bb02de36aa31e98fca8ef8e7efbf1883ac2f28dfd305fb2d3d21118809b1bdb6b7350019ebd3d52b0782c212e84a7e4a640ac53031e057b01ae871b06f788ec15ebf049ab18d4d19b60c603d06fc50326bf325f08d48b32d74449204f8fcbaa1736040841133f04c04f0eb1b8cbc294b99d6d2af09476b92e1320a1b22031fe09bca70b4253de5057dcf84505ae4354400d0f72090f546405e6290ceb5b0e793554a41e2fd551dc6c5400ce3afd8e30cf9592d016ba1b8d96d88853f3bd42c3f768cd40a261d1b077d9e65cca09369305357eeacda429bbc0b0a530ed2c13a99a51049d95ad832d03c509d5e921a17cbe0ebaab4d2a593d8403a456806357560033c47fe11ebe2632b2e263782ceb38b83e47ebbe04a0d08f00910bd874c372dc654d4417c2c9acb9e90479d484173a29d6d472e69390bb4e93ca9733ca6ab891840f511e0a9cc38a467962faad77069e616480807674b5d8c486d1bc4c18a42e74eac86920c960b17f26766bb2356f063575c99fe3a0a900525c0b3ac3916ddf22c8f7dcc4075cb36e55f862557f0ba2012b701cafc5a3b075e96190be1be23c48651a03c651609875020ecc82c3b5fbecbcd544a2e1dbd98b79727c64ac0047676369e936faa8489a35d5e4c4b45e45b36e508aa041f0b57c1d10a4b3e0eea0d70e3f7103bdc6063af5a6e7aff6d50d5999029dbff5be23e3f55e1437e8654a818fdcc6f91e6ff3e0ba5638c60383aa4946e2ebbe4e52f90a487cf01c8a18d137c3e5b3b9653572e25fb723aba435ea5b03190a9993816678b03a5aec28528fc341e52ab5a4aaf6ccb998a1586d74bca8841accbd160da0be94f23ebe21fb15dce0011b8ad64f37139c26f8504409cbbf1a417e7c409033f95741ddacb1f5f11606395ff8abe72036f55167938cd9e26aaf19355a802112a09247ffa873b6252c69bda5ef57823d2baac530389edbdf03098cbbd1b33ead46efe24503eca198d0d8a8b7ec9f25d100755dc68c58a5478d5c3e43b981a88c33b566d2c8abc6019afa7ffb10424e41caaab8ecab7030bf4798555fcc6014e07804902525922363c4749942d45df6ebc3b8411e0c67e742afc1af6616bf5ce9139a21633c57b5159130bf798081ba88b84d73b390c90d8150c9c869f930d7035a7c1945651a2ebe86c3a18d78a5c2385eaf5c475267a06c6d9365529fb266cb2a63dbec2f47bd80ee3ae7ab797839be596b28680303420ae189a44ad711c484c9abaa4211c852d5aa0a126274a8c092d5f505cebd822094a2d2b15e9af6fe3b1aedce2578cb82a8b50a1fce601788f34e4c320708579fe9690704b4a2aac08ba7e85f98994583672a9069f5d2b68ea9ba41c8c4293be45076ec4026f8feafe3ab61708da420b696b196a03a5a6d7dd99d2b0b9e7c45db139f2e277f26dde1597f79e41481aaa2b4bb9b5b298afb58237fd298a2eb0db0149d28d3b040b7a3d01224dea4742676a0ba436530c8ceff5c05", "6363006565ac53ac52", 1, 2002522136, 1537743641, "792d2706d74c9007236a7bb472e9af632e9a7d587515c97d7c1dcdd7c35b5315"], + ["e2e50e730288517bc8989cbea5e67021233952efcd8e65f532aef0cb8f8dbc495433c24d5a010000000452515265ffffffffb1f62fd41113d825e96e02d80845fa3ffda2e9daa0c3fc93d1730c3e653bd9050100000002656afcf2652003c9f6140200000000046aac536a68e141050000000003acac5171383f030000000009526a6500656a536300b201668a01510fcd04000000000000000000000000bbe4a4cbca92bf76dad10a1ec611366150b327e931c3f232fcb526b743c224be0c0230d81b4e35c48ebc3ba571714e03d5fa42bca8338eecc158e1a0f5d620ca47863287475a75c931ff46d47d70cd218bb41ed00e7ad4a130328525bd6a4a10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ee3793c6114e2b10b9a328002f8ef0d7db58a7e40b37123f1c7ba5348c717ad4c31706bdb66f053e2451cd55aa592242105582a3692a4df027a0fc5075ebcf5ff252d972805f5b15821a55498f8a67b8fca5dbca5d36f1b877d7bad613445badacfad7060846b715c6272a38f7edcfed0c96ff01161f65b00cdb17aae32ff2402006615abc08b284ccd85347958b807ba9f386be745e3028ab9cf7d227db224080327b4f3747d20a7ac811aecdf7d8cb7091b9a4f67f72f64eab4e41348238f585b0a06eb7c8c552cdcb6bb9ae64e30f8ba3c7da6a5f0aee38c18bd2c374590b6141d8c1dc86f8a09d3ff8dec7b2e923ff62767ce00a80e2331c0536315c431738a0d0316796e3f1b4e80bc7d5c4f33592f3d918924e14394aab292456659974d52e5c8022e0aaebcc11ffa9a1a62c0631e77000cd717b234a9820cf782275049ad9783eb031891689f18850ecf320aa423f4a22bfc5e19d449eda2363f95efd16f41529bc80316638c3333f081ac1d48b1ba79185e3871e5b268783a95855481ae0b7d8c4b6a022fa44d7bf60bed73f01b144e057643603c4e347c27db0558be01d4716025d5809b1903c275a8899bb1329aab4a914c3ed634899222c153f3ccc9094315e39813785860998d60bd4a689a2a2e8487a5e7d82f9c382c8712496cf29f4dbd640b6288c6eeae806dd7f6b5229d3dccf265a5c338ffbe6d9858d3f8d2587a4c7cc78d47ecb919a37f30d51c19568460f50adf24a6316906d147765d1a11a84da234890f37a989a1697cc59f97a334cd1313cdcb443f71cd8824a3df607d56ff2a7262c321418060d5b99e19e6859150531d8f8549d364c6e86b60e6e8b7e6bde0c3ce54ce4012f26a8567d7168fb9811ab23fee14b9a13e47f57e7bab107ec4c2f62ac96e57f7ec5e9f3ee32c05090fd1b641995c422625abdbf562558f3cf934d7a9381817ddf25492e01e7e05fd99ea6700165f63edb0ce6c94badf9a4bcacd888ae6e887342e4c54a3de521fe9a80ae04abfb7a1cbd7b2812086231972fb3978a8989add3e772bf936f6d1d10bb8b834f4be0dd4416598e6b0e40019c0a759d37d4d7b30924fa4606c7a5c74a594007a0f71cdf2e8b2a282b60206aceee313994eba4892031677f598b4481490d930205fd7cfa8c7189bec1dd2f4e13ddf33bb78d4b332ef85ad0dad02c3f691b406192754a95c50c7be752a1d54a0d9833585f50126f72fa3d47ca4d471f7f267f381fa144a10ecdd51a3fc222318619f587e8c48b383061157b4a0040c9fe6b2f865a567dca3cb99dd3d2360cfe10c72f1f3f0667161d3e0f8c1f9a22c87c2dce3163ae18eb5679fe49b4e812af88871675c1b47f09d451210574b250b64720d37b09d86504d1350e42f72b3e02679a01e6562f990dac81afeb1fdcc91ab3b5965f7d2545c85e7d1932045ac576001877f830e63725862128f47619065edc13c86a395ff9079115d9f1c4126628801ae9f37b451785da16d2009ccb20fbee49c6d2fd58a9a5425c8323314c72838b9989d56164aca1f1b5201ce71cb70719d89e11e7061276d46bae83aa913c6fd2b3958b7093e6a409875dfacf3246263f6a1f94db0edeb8c4613adfcc14d26ff7ffde128f7a10d8c5cea729e4affe5bc48a55fe0c79ee91db60d2421b07cbebde00894e3b05229a835003dfbbe5c619d369ab250d0f8568626f869a77fc708ed7486aeccf93a8aad0e48cb0deb893e08464e33fa8315ee9c09cbf2dccfd88ce7430a795054a70785a3f8d9d96c80fc8a5d04721c039a982f12fa07c42c873ba0299d74f6600dc1a47b9703a66616bf190a10a6ddbd2dacc82c1822ba9ee71fad5b856627a8affd828a06795ecd7b2dfd8101d3c8145a4e2e047bc096c0a612345573e32cca3a83c676e2c32aee7aded4b3d193fa6e6d3dea74d3a6b168cf91eda32eae07871d66efd1afb27dca7317c5f62fd4d200936e5dafb58eba86852e443d02989746be3120ff981db89bbfcb1ea205a1978b7d2e9e85b554334c8c1ba28b279f83fecd291da2af49900fbd82326c40ea6116d1b8c441dab1f19ada290f5d4957605939073d5a4bf5a138341e32d6971ba3bb0526133c362e50e4061e6ba61cc10faec7dac73115581c9619a96264f35f40db0b4ef05f43a33238683677f55d6bd375e9d1276a61cb77e4304176f8917e688c85868292c09f2c3bc3912284fd4e39c1f364b4cdad084989002b2d587314c8a520ab8b2898bae1055fa822be98068437e046d5f6c84ab31a1bd032a2fe0f010f51b23bd14cc49496f7f3f8682b3e32629ede21bebadb3b0597a613096426a71217b7632e4f7e3396f5a2b6c43b94b7b3f730a0fa4e9570eef4f85eb00d96e2eb7762ec540c1ed142cd6049dd46e104dfc64a2e6689de2548738824a13b23bbafa90d", "65656a53ac00", 1, 71011260, 0, "465a4d075a407914749c32e50ff9b13dc7c3720f17f7166ef1655ae1d04b67c1"], + ["030000807082c40301bfb3e19411ed89422fae3aa19f4bcde3e6e66a65fe6bba2c250768bfb6dcf90602000000026563ffffffff028e050701000000000751516a536a65658597e5050000000008535300ac65655200a53c223600000000030000000000000000847c69040000000045d4e58594a9e17af1d93f5155de89121a6ebf55980feb33a0a4e340bfbcbb3a46f35bb37852a32c4453bb9f3bf3d160fac3292eb0f1ec5d8f3c4ce7d20c136ed951825799c146b1301035461a38a29d64cbf37236863831808901b6b6cb4d7e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dfbe315d4e822ac2d78667d73d9cb2d71b49f3aaf9833d580543bdef0e4305027884a5179bce1868a13f3bcb0f4c389a9f8c87badc650def6c70fc3e515dcc813aa040e33923a2243426b630b3c88ad78218419d3b97c3b9bc7be05ed3dd4c192ebf5f1b58bf866e72c6db6416dc2329cbb82c0f877de9695fbe24470fa2dcd0022e4da3780e37b1db6ce679b6a7283663f8b835ee7925ad6a437c5eec85c01879022b20a19f3d7614af878d616accd0c65f61308cfb2dd381fe51439d25dec000890a07652215cd22079466fdb231a2c64453b5e63b8defe617787b39f8b3df6f65f5a30536416b21b66510a003d36dbdb6c49a41889a16e969c02a1c76b2e7af4922021e9885bc5ee054b3851cf704340ccf1de8ecbca601bde0f88606b8a324df6f120204bbfdb7432692845e8afe43a1c21f5c6ee5434aef69e0f204b0b3bf50cdbbba031559398ee6852bf9540e7de9052dfd1965c0b60b48cadaef7a3f3cbbdb24b015020c84fae2f898346b252866ffd825954f8be7bccd6c6846d72143f1ad90971382030adf3dab321d586ae556d30d6e44de188a88d5a3c6f456f449e0c9e8f7daa4817dbe2b348ed7091d0f4d6585c9b97ebda36156f3ff801c96c316c1b5706cf967acc64aeae8f297785217995e76daa0ba1a1af90b38f5b68964b2149c6cbd668bb57daabed20775da5b11cdfe7060e72778e1a86ed94d8a4c1261eea974922baacdd67bdae946b5b78652e68427a7f8b0217dac0252ef2d868f4baabc97d7b49dcf4258bb6fde017a79f1f4c9d2dc972f1fc5dcbe77bf803f8cedddc5ed23e8f595c5ed226dd55405433ef6975d7e67f74c24decbc7adb58c43fe6031000e0f413dccb6138673653c0e1e26fd80a18beb2987c2e4956d02fea945da11928f12adef9ecc53ade3cb2b8367320e94aebdab46c65d3b359e9aa308a6976e26d8527ebb7516c8318566bee8bf9e4e1f420305d6988cb1556dd907d28b524304f1896472c403cd2f3b9b1ad423e054bc87e6e1da0756ecdcb6e527b2ed0f12884b1f269109a0d736eee1d1c65419454bc7e68afbf5333ee65cd2839cc3923b4728fba08c1bc764f19009cce234fdcdc3fe7cb2af4a80e46a7bba3a0c69ce407c778347e87437a7b0c63d0903b08cb2f2d1faa0430d49a76983ea7176a8d27f2de809d67ec1efa8db52356a962d41220c38fecb702026ea7f5779eedd0502a828a3784dc519fccc555b98319097894c8e76e5cf51fc99277eeb1fb2c66af709c082d0b5737652ec6582c272f1f817d3afb9fc66fb29414f21383c72ee46ac5a489430f01cd000321e328da14433afb69a2a87ceb9b4c63a74fdd6379dcb874518abfc29ee025a1edf8b59462e9a378c9c7cb315aa7ee1298429f3a237cef169059490202e83045f827ea64293388b81c619019441cc5dd6468302cf246a2af0875e15c79e1cea57f612867fe0997c7aed135e449046ee0325719f11a3311dd3802fa87b48066dde4e365daa54dba641b85d0e60a1c8be29dbb46cdc1835ef555ff169c4a3390e30c68ac73cb2543bb459d26ef2934b58326e5cb147d41cde5e69041bca3c7f5d8e7963e201bddf89112a3266b0f380cf1b6d6e1e65a9be3061efe3f2b6101b78b0eaeefaaaa088dcbffb3618c980382bc85c25fd1472804bb4e6b4ef485956b0f4e5e8fd8b44365b81ac0d97d23a96b7b529ba74b8b29c3082cfebd753b113cc73a5f8d7f87b48eda645df562d967a91aa889d88f87b012589d05d5d7a39bcd73abb5ade2da4238f2a79f193962cdccf4fe711b8b0505f3e7cda86b1c4531ff5099011fcc514dd05b63f4a26955f736a99dc8eb8c1aa08c645cea1ce6ad406e8862ec02868b5df2826b5929e1cb0c75e93efcc69511ae711d00ca929e446c276b18f67319a2533408ec273f7f10b21e2a6623ef9a6b3d252e8adafb490b49f59bc053e02ab6893002fecc10eb65e7c43b23fa7275351deec060a0dbd6e423c261f6d850852ac3b7dbdbdb5da142092828ba03b6faacbffdcf2d92471eaf5ba67ccf4c6096101157fee88db9cc921170dce877e5ceb14318b34bcfcee54663d2efba0b0807925dd69e076ebeca1aa4632ed8b6e8ed1d975a7ee8b396054c0e7bbbe5aca85a62c00858e131de6a3f288b05ca6227c920bc98c920a02ef0a852e4578cc7ee6143148a843ca66f78dc8332e91843bbb869975afab8fb7920a8a849d553d33fcefcd24b4cb636bcfb8e06a0256d556773ec5efc810b2cb3ed90e4ddf691bb2911e46577ce602243bbf572300000000000000003c0fd40500000000f01de062ea7054f03553cf9123d085569a71298ce0c0b9efecc93c4060dd69211c5ed21e20c8e4fda6f1b53dfc313af978954023440336689b612f4935c64f0791eb4f47557a413768cfa5eeb9bf9bcb3c8321b5f7b23b4108e809ae2b083a960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000068af5f5aab5cf36da90d6837499f81bf61e8fe6a41e6e4f7cb862f830d34b6c3a1225553814a783d04e6b1329ca0fefdb51a0a9de37b4f24d79d486bf5f1f2ac3e16dd9f5b6b589b87dd6363bc6485e55691ca8bc6e48912dcdfe96d42dd29cc6c88c3ffa2b3758286ee4122eef405881f3054860751aa93936d1c579bed9a1e02153a03f7a21608af819b713c8ced0bd62d39c05445bd1470f12698d46570a07c031bf4a1d60ec5027bc0a207de8267a5fa6798e23619971eb6d06ba9a7afbcbe6f0b068b6f4e2f3c67aec605f9e1a4faaa536f119eb67f494cffe8bf48dfa9edb6f02bccecf3b9d3e036c0009d977136e7553b2ed9ede1fdf315e4e9cd65559f2fa6021734a616d21dca5c260f4327b745e5bda069d14db3f3dfc4c074e824a9bd91c8022dda58387aacc27af4413140597c48fb5a286f7296cb4a19f0a0115da1510d57021e0d1b17cbf8c985e0661313dea30ae2ac58a7aa0f4345d711de52303cf6ef9a022dfe2f3dead1b02542b6992c11c01c5ba953369904c6908f1b66198d9802042b021c65cba788177b8c96f8d9b676f0bae0d2d05094edbe28f8d42d49ab5d8d1da409f7baea9230002ba53ebdadd90a304c01eb6aafc48c3f6df2abcb1c34ba915bd1de5861f2afeda34fe92e20c05d76084e4ed84e6dd167a71f77bfc7c4d1f4155c8195c4967f8e619a29c9d42ec87ac2408ad42e244e33efc4e639bde139c73ba109284b79d8a7f9379056e24ad681e5f7ed8fd040707f0ea874afbf100ce6b37faf2c2c8289b6b2ba614d3f8cbed7e54d68d4df10b24ef8424d01f8a0cee12a6446b0882ba12d8f81b03b6bb04768d7512110996da174321d1a7d79a5b00761e842712bed67f8ba405d57a64782c090004da3d04753214a87bccd6172e2126efe644956bf09e1aeaa8117212d4725e16cac480695db988ad9d07cf107721fc5977f8ff772514e6dc9fbbcf850b11928d4982046cc55d7c0cbef91736e93ffe9e5ef475c488d6409be331981ca4668abb106cd934399b3be7d3755a524145d7ca3a74c99c2bacc7cabafec17f05e743ef431cc3be66c06d91b9155175059d0f2dba5a9624205ef5ac6b202f626112f21cf853c47c41ef15e2fb77c484618a9881d605458d1305f062eb188abb0cb3bef63197144af2f1dd93b978b1cdec1d82581e98c62104466f7f88e41055c01a5d8a726ded154e88401a5ac7a784e32a7560feacef2efd5edac916554578682d1491bfa82fabf46e9ca1eed381004872e18429129a91b22d39f5dc142445f5cb86f04b6eb7af32e2f46b625435fa4ee8293bc9c6f5afad3c90470a8410c8dcf6fa505dc65e0e606decb7d2ace10145fae8d2a55c1e9ad8516f133aac3279673905a75a94ae76104a37cded5088426b0218f44363789a1a419f50f2d101d118bdf606ee3b801fb09d5b636986050c85ed94532a93da00726a96080b9362c83834a88741be022676d5c18cd2722106775d664da0497be954cbadcdd2aca7df745e668c425f0516607ae3415034af76185142e4ed6737c4e5d345e9ba6a6bd1637709123017b71597054fffe9c67153d44f9109183607c258b02601add87dccf316fd013b4072ed70aca8a5546d0a5f4918934b1a6a9252e21e272f43a23ec6faa8d025e04e5c91fd5cd90988b631119f3b375981103f53a8b15ab491a6f1d9cbf9d4c8af1d1532a0ce49f436f6a9298703ad5c692a1e4f8bd165774ac93c5fd6983338ad68cd16b0cd64d7e99bef10093bde29b74d127f106eb1acd443dd74e483a00b40b84ab467107cb24ff315bae6a67f7c1202cdefd2a4aab9fa52b80dc8b8354f2382cdb5f0c5ca95462418fc8abcf3c721eac151654f63714b45e98fae817fa940a864373bb4bfcd3f8d9ec65ae7d10e3a3e445347e9bc590748c03e1e476896d415c2886197ef1105e821b89d442760bf4967a908f96cf7be94b51de79216ba15cf6e0bcc8dde73d0544246a271aa720c78445d73b3baf31f38eee645c8317c4ad5ea0c36776f7c24bba35218a9345dc47a0daedbade938038482cd5c04f01ee6a03966c826cb5017680f24a2a644c2a4cf44a5a87e575445997c7dc0bb770c8e95beb2f49146604a968dd062e53269939446e5a4236a401dd4eb618e199d0b1beffb49810af41bcc262462bc063df2bec0a0a5b378d6e389099b84e049e87ce8ae5c0a197b99889b4324c946d2e3c5879aee8466fc0b13014aac53c927f4dc519877c82f67aeb99dfeebf0e816e289bcddbdcecf0638f2b50626013b0b2ec6c3b2fe66203000000000000000000000000988d1e16ccbd95ce114d0600703215f5201107d5f8633e20e72f5e47cbaa6b484147daa0d2fcc7adff1504d9c413c0add809f78be6950959498a2fcd921b08413bb488595fb88b156aea86172d40514c95adc6ba43acff43214e831ba52385b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd1a1b5a537442963928217a6493706ebeaca1c0d63eb68ffeed54914ae8f344f40bd87bf9aebf2d6e221fa503c57bd46a09b2024443c984d7b7515a0e50c79d20c087bddfdf6c08aca53ccd755d18d70cd005f1f8cab84c37da97047112bcc4a4e7513aa15410790eed26165dcae54e3732e132a6bec4625bbea0d9cd9ff83403291138c8238711b5fe171756302639c15327c6830efce3664b010e4a3a95e00b032e6ee10b0872a38ad6ddc541d5f430fc0417a7b7108c6d5c7ba74263557f96a60a061a45519928797af13f4ce8f17025bd1436a467647c869ef691dc5c91e974806d5226d974539c7015e32969f0cac0d3ba3b435ef2250620666b5533101d691f03060d5904d5db2634e7756edf1a16a59da2dcb8d0db0bc2c1bcb63c575a2eacc4032b7f6ec91eea2661fe83c96900a7c2c558c3232ecd80fd41a05e8242d59c11f60327235a663c022f4455f95407c9d5199839e2ab94669e6923ee90eb1d2616169f0226eaa0c8e71da2bf43ebe8dda0f580151db75ed0b0163606b8ba52bdd6df8bbd030a2aeb021e8b4c586e1db135958b6b21b448949eb39c89c0e3b03b98ca34abe90f4a6fbf9709326d84d83be114ad6a022d9de239f9bb136128c8e4b6be9473468904b7244822af94a323554e722e11285b8750f4ca81ae64925b911a47b8b5913b7dacd105d718f600a334de3a34cf73b98b198fdfbd72a917db49c914e17617991fa08e2be6b1ce64a87c940f9e6ed5de9994cffca79508da462f0be1c55f19982aef4367f6e06f378cc0c19e52271eb518399ec5e9af6c0b2cb94c572b80642acfaead32e07275a7e003c3d46f9baa6de1de6f3115e86cf266ce1686c0424aedb0d5993e54580696daa52bb181e6af74af3a1e4fcf762022055efc8ac243ec08915fb29a142938596357e3ab0c6480dea98deb181728a203cc2544b13f2fd8b8d7ffe02f43db29f61ade021524ad978b1f419b53be4ed2b2d0dbd5b852f4d2fbf0645c83970fb97272acc0da9bc9113cbf8e346978b8c1b768266d661b9ec860f2f1c902a709a88962b7fa53ecc50d0d5c468ff200f22306d670a27047cbea1a307b3e88cd099f0a36b60517f526b21f6b7cadf906bdc6e639791c04af6ba1c327c31ff317a628b3c6a77f9913b2d39d7bc93e3d758bc35e24ff1a7e8e33d5ac2f005b1a5b7e9bdd5cb4c913fb8c00b3c5138de516c4e5643f3c980b8cab8e8b7e02bf9bd56fa3a444546c3fd3ec6287d64b57981684d7337517b7aea137b2b02aa87ee68ced6cd8be6195a63cebfde04b1d806dcf2a88225fbcf9b09e853b06ee43cb6ae627ede6696863280612494d8a1b0b8116b4e970f622d8b923c261631fae06050360a56e9b9dc7255ab8e25a4c6cc844bf02f2feae5712439410c72bf03dba89d9d07da675870b78b01533c27ffc8fa2228fc5bbdc4a81928847a670f0d74659937422b925594f75a42c57b4b6e31fe1da7017a4926d6a3e5610e95a9df7581f1f3cc1bf41813866f953db6dcc4b7e25df33a223278bc98208279c815e4c535e7317c2f2c0898f9085ad54b965ef5fa16cc7acfb397d1f38c80ec8eec9c240a1aaf729c42b8bb0321255c7fef4026d3d2a4b84dd83d35617bcc62740477f2fc3876f0eb9bd02003e8c437c912e2b9d626609cdf58541bfe4652cc843c92817df1cfa0f4aa97a51dc308b6c901d5174c3eaa4e66d54424cc4f98ea7fb60eb6b75ed1752188f8b5dcfc62859367ffe5504a15717e8d31e2c962ed7d3b4faab912b017641a8a2683fe90a293b895ece870cf187bd32109d0c871061f5579592a1550f367c77810c0f8c40912570148db6d0f0c3499bd1482234c80eef569eccac3cf66bffd8a471a0b143f9f9b450760f7d801c496c296c99e964e94994c9e75d1a2bdcb8ba00131b6294f06a5a6b02a0148f1d722a10be762b824196a770307438be1b74e7d126e7df324a347137830c372d153f98f2507659353eb7851f0e29b8b7e697a1a3a6455fefffc000c36b8c511b4d2f649f089e8877d958c830dbc154ab58617a1d44c0c545a636cdcc1bc4b4ff8290e455241140f2946895ded188e71e1352ae8ec3163e049b8097a097ced031ec4cd9f8ae57e059a0db5ce3957a82ee731d325a0b1cce29d978eb8ac33d2f8aec9af58e1ae9e69e0f1e9b254c7c04a7df363d7c45e47b679395742880e80dfe4e3071bfa12cbcc88b62ca3b66624f648e49f1d9496c42277de568033414ae71eab8d372f0bae9f3ed475eff3752f62e27c31647e66beb24db61c07193a35377a13c6953246f098b0b7aa2637b4876ea3e93304c235bf76004b5ce6220514c324bd752a399143b3d12706e76b0e08aa21b8a1d591d81e042a06ebb9d3f4cf2a6ffa4a382ad93f6def248691994c6bfbfc6ff6ed8aafc6ccf4089af0f", "6351ac6353ac536a", 0, 1619596157, 0, "5816be60acd5e37dc1464621b2237d493ae0ce17d5897c3c39b319a2e3d9dbbf"], + ["030000807082c40304947a6aa557e8c85d852aefff26d615ff650dfa2cdc411cab53c26d56812a455b0100000002ac00ffffffff440735e53772cac823395908243adce21fe99f71f2e8bae60e6334177c6b4fa802000000076a63515253ac6575638a041b64862aef35d435911a78bdf5178534a62a76efe44030096296042291782f2c03000000045152636a2b77d481c44fecd5155b1e9eae78e1e9b581023dc5f0f4e7fb8a4271acf41965c5fab71c03000000025100536dff3c036eb10a0400000000055351ac656aa297eb040000000006005200655265cb813c0500000000095152656365520000528e2f69360000000002000000000000000057a9920500000000c4800ccc94c031fc93428a1fc353a2e92cca8745b223279d0b3ee62c91452e2297cd887e5b61fcab1d0e4d4f2c0b58712e6464640a21bbd517c1a7b1c0d2db60787fe984346b0eca48823052303033b54545362c065569dfe3048a1b90e7ae0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a47c88f1ca26cf97f637cf432c4e05cd09e115e1efea7aafad28106c95f94075da594853c3e6336381b017a069e8d97be9da4a3a471f0c09ba401d5a8cc2b6ef6feb0b843e48eb8c1269bb1071a975e935bc1f4255c96e2d9a31d5a2f23f90c588bb733c750992565b2a9e0f9492a049d7cc3c562f37647f4dc78e8d57c8d64e02254b7ce143405191a4c6165519c649c53cc8f4221b699c130a8df1e271582edb021574279c5c3afde2ea08733faf6d368d588ed0bede00d02c71316b20013c18aa0a07a33b60e5a22ed33b22beccbdd6e3c52c1721513d325a2095edfd409bd6ee4a2bf6203bc36be459a48fa4920d7a4be0b7ee2e0ee08484d6ebc7f93273ea9c62032acc8de2bb07aaf891b2c37aeb225433f2d451d12dfb42b4b303b97557d0e0d7032465a732569570ff24d52e314548603d788bdb3b9cdbcdd44a0b6913407bbeae031e5e09243cf6a64d2a46e01cdc9b8a094f9828ef01874f5b14f48a52af895e9c0308f6374fa3652d8138a2ef9d44f3e05e40f8fca0efcb13a0eb20161b70c7c10903285f2a705a709cc86716cfd09a7375b8781f466aa4a8b743706633c4b55943b66c5f70cc4839e074fdbe1c946ff065a3d1dfec05b01398d05d40b758f2818fcf6495d811e7bfb4419feee9229559abf3201c16bc7529813cc6ff147c2abaef9f8d6491c17a78be7c79873a3fc6c1acfa01676096075efc6dc7789866277fe67696bfc8efa7b415e60763d06dfde547849a585ab4c77cd5c3a109979c03b1b58975f7f85639b473b0ed465aed89da78e8e8e4bc724ad36b02bbd7b0ef7262a580a47fefe0da7830c09f1b85a9ea392282ee973663ce210a525b164af7dc5adf246308473db5f72b3e040386a2c640361c9ee0b0410794e2ca7ad03610b8dde3206c61bc0f0c927b21df62a5a28366f4c7200a5384965ad960b6a42b025f7754fd99086be6db873d52210825beb702d5947638dcc4554d31c851bb680047be864811ee15a408f31396c37c4ff9172957d589d12d9ec4ab20dcf230cad39e3d4dbafdc2700300a5084ee3f4a662380548843919854fc988dbe61dbc091c5f24b98a751284c491eb55acb65422dff1e13737923da85c79fdde55bb81b8e2cbdd7191ea20b9c0ea43d75003e6c2a0acac4559e77ffa9165bac882c3972448ae612c4e7133b38057cc04602c26b29afb12430a0528b17c4ca37db40e379f4892ca8c17120efe68779ad9a8c509384f235df5a648c8791dbbe461b0c031acf58bfa85f4357aae63d5af2ff7b843f593343ce736b353a227532a8b1351d5dab0248b1aa0656b8c6c0239ede80d4ac188944b688c8111167663a82f8353744a09504b211ff81f282c69e2b63d92e6d6be103fe5520849ed8f61d4597397a6c3265be03408b41cc4c6b611f820be4b18952e4551b869411e3347804a561577d4c85c385e5b3de89b800552af08f2af18620638cc1aed3f775dc6325a5817a729f06729c1f33b46522cdbc4f28846538164b2497c072990964a38e51a04304e6d70af9dcff0c3e9ecfbd3106c6fb16ed364546ff509a650a75fe417878bfc2d0e89e77f59f657b0c74e6b6503503544dfe947de3bce884554f35a78e4d5c5cf4b051677bc38a9103bacb1626a800dec8ab252261bf25492f99c309d859d320df885790dcd4fdcd0b706bd84f5b668cd1b28d7db7930603fccdeac0b37af09a083c34917af0a03df262a5511e246668ddf0b5757d196968723d9b4842dfc261859cdb073862f2952fe777c42c879c5d30a97e5dce512af03bbd9fd0c6df95c7c7e3f98a73ac887ee5464844a4185f1d6acccbce28943d391932f09d86196a99f6dd7cac16e01b23a2cb01e71d383df1d6b5c853b7927419d062581c73343da47f3abcc0928d1d7741abcf8759b7d01743294a3f5b7d9c13e3d19f36975c783a8bacd6b17033ea97eff6b4c0ffe727492d68805b9a56daefe10a2d676da6da81e4a471efcea9cb2d312f5b6fcd6c2b00aa1b1c87d34b28b52e965712d69a5f7ceddc8f1515de3fb6514201643db7ad302e046a7d96305d866baab5f42fa54fb322d5362736e6c0a918132efe6c14a8d782dfdecdf984110d5ae887f360d3b673977b624920a3ad78e5455d5417a52e5386cb07d3bf222171b7c34a40e13982b59493a10b80623f2ed9b308c8ad94a1e7ba86f8b6c9081d1d695b19c2a360bcdb835e1fa184429676653ed9b0feb6f335b6173d4770c7d7d09dec530e9d1c2acea9306203e8b81fb29c218f91ba6cde365fa29efe8f1e55f7600000000000000005a44a00100000000ece5fb5fc145ba43655a4bcf60fecc764925202165ee5ab96fde33830190308d133e49d167aa6f40c5d15f14002338026f4e1dfc400d602c4021fcfb71fedd74ab2d871dd65a565229952739368588f45064d968968c6c2597b33ccd76609d7d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158452f051a6d16c1e2ce8b151ee8a9eb3f70777e18b660e53eb3a65ac258c53d367ead0176f9ecb6480b5e0b1939036fc08dc91f6a964a794d06a51d8bfd2756b25ff4aeff15009b28a9aa6c47cc7753738941c051c0eed6c98c2c102a82a4c4b42a16973394ad3c97a9f2c99390a3c8f3fca4290cb3a4dedadbc2172eb30c4030e02898d67f884884a673c5d106fa9b3481cc0c6d5563329135f1b3a7a6b5449031d9eed3e5c082e0c401666aacfb0f8101d12b73b75a1cdba0acda0d9132010570a016e709d1811bfe6901749a13e578f12ef9c32768df3e0c223f916d163675ef4746e7c6c6face87170583ddc57617a1261ac77193f610142fa9952f9e399979f022aa5ff46dacfd28e59ce5ac31483995b0c3b6cf0791429f8fe066bcbe18b8567022de2abbc41637f8d4712fbad7b5163cb8c1cb0dac7ac3312772492178a743a63032a9febbdd556326f52655fc8ce72138e90f5479bb9c8ffc670b424c4d51f0925030c336dbed14f99208870db4c8ee770f137616877254f4c45d21a94ebbb9c04860305c2ff736c2189504096c36f3963485d2e07115c86df8febd6f83e1268625408801a02fa495df1d9e6c3a20b27d651ad6885ff882f0b9eab3dc8d61940ff896d82ee799f27221d684b15f8860acd47f510ff185393b38614a91faa71968d5d445726f73d0aa01ed22203449da9eec3a98b6f982df3c40e0c6f3db5b6d03cb745181ecb3d797091dd31a40b3a97a923fa98cae6236e56fc588a38a21230a8cbb283755b9de91f1c0c2b16514fdd8931430247800389f655c170c79872183602fa801e1762cb0c67ba75375d3f53ca2bbe561688b17a6a2059d9c453aff4495c641779709dcd6450cec80dd64702668b606555cda5481b1602fb7e59167443b5dbffc0a10abeeb7b3c94cf750fe0bc1b22a5b658d04fa17688f867630a9e8d6c9255c46766505d054e66fed460971fb65d5c44d01cefe774fe5cd92b976cbf3dfb7178ab6c88c7191da423be3a1a606818fdbf1551abeb85243986b901e29bd72c850cfe70abda4f8a925872360ed1bae23e58b36f4dbeb468792559f4b2cd41921336bec4b9ede066ff9bb6e10a8423c830659d57fd19b7eb51ef7b1882caa127ef75b56d93cad261e8029cba7c7fa36ca3797a8eb1abbef2198db312920a976811af64501f032e38eadb78acf576c1b3f28c8ce1e02658f2c992118528a360dfc9d715dc677eb285c01aeea0a74c5d7ddc4cf2c099aff0feda509d76e8a928ba048fbfd85bf0290fbefa73a434166105950b9c9a58117e37f25e79a22c74efe0c6041617a41a84bfe0ec94088b07d6c28b80376d6f6c11629036c5511b487a1c9a37f94ccee9abaafdf6bbc9c8ef048e78ec54e2e117ecdfef2e9fc06bcf444b99a6225c742080dcee44f4af729914ad5fc3d8e1d40de20a1542b9679d52b622d2e153e4ddb3fb6e267cb4bf5f170d7a88149e9e2461e3941eeaa5647a4195a22de4d27141115507ec55c916607201aa52a57e095d2ccdb6ecd41254bf6ce168630f851c8c058bec854bbfa5c304c9d3346f78e105892adf79a2812d0be7b5d04092559475b53443829a84435fd513cf56ee8bb801b7c3c25bc30cb63ad0ea1783164312bc5dc7099eeb2d54826534fc3cd6e46eb4f993fcd350c7e739e72db99784f46040e84471cba81cd8c2cf113ad0d132d6b8843ab7d587250190f37b1ca63e51d9f4c606c2f20bf22419574e0ffd8f5f9bc36b9d883d5db7adf7c53f47936bfb7ac946e23b52fe6750d679cb42386e4402a3ef7979bdae2112f44e0ac35a34f0c78b9085c0e20fb6477176baca581c5d53a8b03c0c9963a76f375cd31dd167c6f0c23dc30a6938d2b59d0fe41a9dbcc5f535141e6ff545469379bd79637494a181bfd08c1e1ce14f5c81a0cf2675c68dbc7aec0eec5afa3aa2965585161cad889764e866ef37a53f0818142e883da652acac4718aae1316d4e763fae90e8bc4115cc731f4acbdfc9743e7eb1e128cd528267a4a653f1f3beacdb9a5bb300da030e404dbd9fc248e871159a038e902965bd32173ee63474d016302837f667348128dce3f558dbdc3998a9aa35104adbea60db6d0c48b6ac57606e63f4e2f5687aeba6784761bc4e94aca2de06cda5bb6435b9ce963e1453efb28704da056ea839a8be648ad971840bf4b91760bfd0f6eef72b079bf68d8b32b209b4710fbd581005b6a87a1587fdce690765f8e2d1e049376ee91d4cb3e0dd86adfdf7dd18705402ed7cf302f582098f42f5dc74894305b2f51147a9dbd90c301900d97eacfea3ca3be3f9c3227381c3a1d1700fc1041aa1385075318236baf7e80648d3054ed683a7a365af6184b542d8fe3897456a3aac20206587d6da377d75c7f7967e75c1450e9ac948d1803ffd8b72d2614207", "6aac5353656563", 1, -940298160, 0, "28649cc69b357012f7e3e121f68f9b8112180a1c952bba7560675dc7f958fb58"], + ["eed4d36f044b9067ff1bb114fa5cfe43929876bbd0c0c4f33e5da0aa4df898eb9b6b23d60d0300000004ac63ac65bbdc606ee75a721784fecd13e2ff62cd60a1dde68bf795be4dd1636901524e9d7fcfd5970000000000ffffffff3474997df409466908b2f988a9b86f2ba84b3b35f515fe4aec85ebf5a5af95660300000009ac00636a516a65005350dc953b00f500326c6b6dffa6a7fc3d93ec3e0498528cd366e6f07633cf09429c8684df02000000075151536a6a5252ffffffff01754e4f01000000000551515351523ea108b703600d3c04000000000000000000000000762178fddcbcabe3a9d274c87a1fc0a06ab84d6da9c13e11733bb6685ed7c6764a0cc8c5c67836268c1a5f6e7191e663c38794ef123f23a0ad6be5962c13736dc18fb951924cdbdbe0a47965d947e8e9623721979d94042bfcfcbe8c8e2cb9b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b7371ca50825f360e6bef602cf8157ebce72b2ce5c84567d3e7dc982f5fa701250d1e1ca29b254cb7eafc584cf063c9a59290276acc0a35d9b3735dae66ea97896efb96e6370dc147c905a8f1340de0c403548f04c668e4304aa35dff8aeca6a89471d05b5353c309b5498c05cb8525324409072609ecb91f826e06a2b7393a303110efe21ed184b6a07d94c129cdbe03e03b20cb8c3cce3e143db19f2d6e984480324c74687c976448e029105916d681501f058cec7c3971c8b5508594da55234cf0a07cdac59dd9312adb58ae0d81078033abde8cb81e82cca789f7562650570b63472f3fce5e509759a3f722137d82f3021d66f5d5dc6ca33c2ada5e9289d24a820031398c107a88c7331767b0c62486db25386206d10e435f91f8bc4091d00063aff031bfd45bbf8b2e5a8ebaeb9ad91043205ec54c86457986fd0756a9950f6639335032cd9bf226ad3a9f3fd94f1ce76dd973a814371ce083c49ecc29d23de99a070d40311052c0cce7bcd251b16e7bd5c97803e9c818b43870a24edca29e1d53a2d118e0323f146abfeaefbf669c82965c05ad91ea94d229a785c045aa89cf5a6ce39c7139a117b7c09538137dca49c18f0db89a14c3bd2f030905f0dff01bf65a3ab9feab01578caabf3d37a391e289b9d14f9d71ba5d2e70ccf8f40984240758e4c5ea47fb25b71722606c17ef386d14ce8df50c52cfe9bef7c5ee3eba1f27c075dbcfe612ed84d59e7f5758f5bf76cafb9c90b20588cbb9837c5edf717a47f2c61eef0f1116bfff0b5bd611c299a6b1fd332025a31e8153862be1343baf45f7058cfc004287a41a1c02776fc6545478dbcf092b77538065605613a18e17b8ff128140d8f46c1918955fbe1d0c3e5bd8105a61a905e460ee7b86e74744deec3ba5c9c2f5e10cbabd69b7d8286320b94786fb2d9db374e709ca285053654a291e35ef1b9e1030c1f1786921b49c4a2a9cb8f317fc62dd4d2c9323ba30c324ed7fc66cb559692654608e6f7c7aec23c1792a221956392595ee59c5e76d82610009cf84f77d1b631676b6990884dc95d912a8e433c1fbcd8479725b75f233f0b6d12a2fb1676f5c5028682afb8cc6015909f722f3077d3b608bd5d6c5f9e2092288c6671fcb9134c09b2fedadc19484c4f9070825dd72cdd8fa4558006765bf9effe152d573482c0300b66028e34afe9e0b696e6afc3a8e96508c7fa354bc0955dcf3fd6fcdeddcd9c4f114c617897f395acdeab52589b76b0b7eda832c015744ee761a9b86f2f31a060c3952ab7c49e94eba6b78f4cacef81cf258d724ddd42f068d3e5bb8f891f4ce1f4b0fc13e571a05ba7e79521cbcf843d94d1ec978b0464c2f013aad279031cf3cf7ff6bc384fb46903addc34a4f0d3f4a41b26be77589bf750f78440bc73d267f96e18667bd50365321e4b6aa68c204aea96fa18cfb1679326d5b4147888ee5e36edaf117571a0e6de8ed3cf30855b480abd7e0d5f75e7b1be1adf6c01605afd4ae4cb8e662a9649b63ecbe92de13572f1c137d9a998a564526f16eae2c027d9d2f059c05a71773be78322832100d4b3973ed62220508f1129f04bcedcfa4fdcdba4db1a1ec1456fe374c4d601b6a4afb5bf259c16dd9467c1d4ba1ed87eeade1335bdbfc2ab8aa4d1742de185a8f5b95e513e2f2f441809327542437501bf18c28c3677a27a17d844a8cea95c405a5202b9a017c7fc836fc8c54fdd7e05b7f72f1836723c19b58beebb2a03fa6297e7d6ffddce2ec18f22a8a7694e811eb78812c8f35d7051add4468c7068ae236a58ac4e0f954e78bc12cde3daab16aed2ed621919fce3f668f3ccdddad12d72c31b78a596280460fafe80182ece8cdebafb6ad0f29dc5538d51756965f8c5fe2bd7c856e146c5b855f75fcd1e8942e2a02fadbb46191d56f0bcda465d489cfabca668da074d4248468102b791a70708384363ef23a61364c89ef4109a27ef5c42452d5e5aec03db1c25894604f5f6001c94c55afb9bf1b10a7e85a6c9470ea17ec4cd54dc06bd680d1c1193457fa3ad6d62207555af6ba63d676ec740d0a6a78806948221c70d4a9617289ce75e4bc84bd4d615475def002d1b967daef2bd4cdcba71af6b8fac4faa7d0dc847681ad50ee406fb6a6d18d4603bb65136080cafd5fd1dfe1c6132fe6d98af8c4dc56d42d5e37efafb1f9b3de346b46ca0b102a3be903ba76b297bdce1baab8d04737fc9e66fa5f61759944d43ca7fe6488581b538ede7ab1de289b313a0490302c1d5595e3af586acb6f4005b6eaa49acf2b94b129702000000000000000000000000eae543635e80bfc39ae6cfce175bb84ad69b017897a00b9ad587940c854a16cce28dffc47caa0832042e1205ddad1854e89cee9c4f2bc3a8d6edf0d477b516d2ed97d15fa7b0d94ea83449416ed89d0cefdf83b7ec7bb128f6131ff4b7e0ef940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031b3e67525ad0c4abc5bab0c06450c5c80e4cce3b30e38db7178c2bb3ac98ada1fcc8cd3811bc2a2026fb8434be5f1cb4c58ff8307912c42a65ab8ed028da227a02bb34753bb497d5b615a7783b2cef3da87754f61aacbffbbf7516e91288de0dfb2fa5f5564f712a0034ba5c2d6037f2170642e90bf01198293eca36002958d02255d485f060b97f86bcb132a1a05a2f0ebd79f28cbf0dac57cac703736bdccdd021c549d28116cebc84d968e3c912e0cf096e464d422e30b8be6850af272107d240b005e20d4f467b05a4a797511146620947db780edb4f18c1ae8ebcc1f6759fe545427151de1453003af6f68e9eae846b62aec4b74926782cb279aa6512cd174e80302d2f88b33e80bf701e384acd969a477de4fe521da83de70b6a903af5a0c4d790228b8026814380626e2a80abe9439b72bc99832f8567021190741c4f86fab69be0329046894c930cc1e7fe112b3bba31999837029bde91ab20943e25f404e0a10be0227513ec16d8d8b1437bc874bed832b30c30362e940ef1e01b96b5e013b0f88d9022cca7e4b82400d89877205bb75eabd5e8a8930cb201052107db367c36ed635f37d3ec56e78401e7a3f248e64ee1996ab5788457d81e4a63292f5e16264ae89ddd8cbbc95648d28e471aee86ae5110b451dea77aec94d87d6cfb36655e995d9f3d02114704093e42e1e55399d6e08ff25eababab44bc855344c883902c0837449632e7f9a9832eaca50540c82f691121350faa9fae1cc6f495686fdbc7eed449d245d51ae51f454f8a50674fded8eb5713257fa9e88bba41836f49b7820b6ccf93a5181221ad08da206b6b0270a6199171ba628b70bff8eb2345a36fc80ea1eec43f2ae1b3a0c7c47e4c1c0003ac077224b59f0e73d944c6188bd5a7dbb41e9a0d03679a480fc018abe00b3e995df16b55e815ab2395f6b04b601845cdfead3de3721e856f577d55a8915d3c07cb07e9a396ce7e7b26a567c562f9897d5d210a3e2d204df5e6d6782863dfecddfb807c5d525e8bbda33959ae89b7914ed660456cf271ba239314152027eab5177ffb29cec68cb7873a223d00a222fd1e429a62f03990aba159b88c4161467fc1a84bc67976d1b55a8b44127c346d1ed8e2924cbef454e5ba25013a5af8c2369c7760ec426b6352b03506e3e0a4929651584142486349a2fb5039ea391b992172df2d19494e684d71ea72ffb79d56fdab1f80544d47458b42fddc6239dc1a015b4dc750d6236e62a6a5cbbb16ccf7562e0cab4459c974fee35c3b6bdf6e1c5c87c668b80daedfb61cc40c287d4bafc6d81d48e43f9a70116ec427b49c960dba332b6cac84ac53bbeaf84ec75223741a2f0d5b5e9f9a75f3e35de90384557c50455e412ee18ed05a408b3f055876fb3e5ea825dcba0da72a705f78143e0159c9bab0e2081b56732ba546862e9eb7bd90e05b4021474064bdd6df5edf3ccef54051fe282aea684dad21e813fd033ab940f69707c866471811f45bb211c8e3fab683e11ab46183b9c65a0e51d4c05a4bf698a35a9e850a6e7cb42d39df7792ff0f3ecfc46a3731d5509f72e4fd9047c2a137a778ab64abba432d967f7a041581016b15fc55a22bd834b05632ec57be52dd72f3273bffcbd8f654f0fe1c3ec9c04abe7905668742db81b8da5aed3b4d90efcef770efd84166e613955801df1f5371fbed7f68b45b10c743d3e213cedd53e5b0fda7d7e8ace1bc3eba3dbf40ad4f6f57db58c1848957a9adad80daf2c891b98695cb994020c13f6b0fd06a8e6b33ea46d32fec0f62f8124ba0977b5d9fc035d8fe48094aef0ca113b85582b3a1c9212eb994301aa541708bd916c4b08e8b55195fc8a0dd1c9b1b9805a6388473b742d7afa0b1585897bd05e60feace5ba53ccee36e36243ca9add69ac1e39f85693850b63ece17336609cc7c86769831d5236a7c75325a9bf3b23ae02b1b2fd31c0a1184f6b862b9f82af7f35471bfc434621943f05f6b160f183612246d01b1e3e617bc4f37316a189feed3f3dd7cb1a9c55d88418aac6a23e3b855507775e099806896ba772e70c05d28869d7ad1501b474c9a7d380d633a537baff376f2dbcbcd44121e4b34663ebf42318c1fa9082a4d35cc01843dbf215bf3535cb896f6f678559eb9f9ee04ba7040d71b17e5423f636db0f08a69d0314ce2523a7c1f90c1f9a77d58105c5efd24f5f1f30004c17efec3dd6a20defca72aed3fa35888cb4d010006382cef18647cf3b4783b6afa305d7f19e1cf8a0d2744f55c6be4feca1fb45f810a8f4503f0000000000000000e58e580300000000200b1866a20bdb1cff1e584a00b400f111b4d154a990f6c95fac95c422ec71f2809350e4668352ef1460bb8263604f2e764b1910199d551fa2ee4539a77106633b301874055bb988cd38af26d4676ae6b27037baac18d5f61da11e7d23a56946000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009ddd281ff65fc587b80c63fd7e20ba7484174539df7a127fa3b99739745aa144c78eceac5f632cd22ef36871091f6a1694d886d56a241c6aba33b85c77c5bf5b4ea83aa1269350e1136844f7440df3f55e5b7ef7ba9ab9adddf401c7e5bd38a55f87d03d748303f445752f228714e6adc5aab836bbb085b33f39ad34d04be33c030637339da816daf1d88f113c1339ccdfdc22e4bac8cc3cda6d72c08609f174660323a0870abce15a7008abab929aaf9490fe9883f53d84589f6c095c89d5d77da80b01099fccb9401fc546f60ef280da500401a0097ae0495f371b09d1b3356edbbf4a35e74f023200520c77798d56eb4e709eb5cdb863cad202e02db04d13125ea3022643fb2ca339b47a7c938f7d8c0dad05c3cfbbcf0fbd81440df396232a76134f030b80114ecf4d9f82d46f44a88e632d4bd6eac3ad72d42814ff40737b85e68f1d02099b8ec4ead014dd4c6936cd134a0cb0466afa06ef9f511440f5704b886552260229e008ed1b655ed4b7b92556b8d60606a0b74cb56a6a3cb0ce5bf02ebfe293ca02221277eea4303aa42eedf75209c2007e79c83ffd87826c7206a68ba1ee669acce853b550fd5a679ba0f022c881c3b861b61f7a80732d708613c67feb2e57fcc8818a3f80a0db3f00ab06645532b1730648bafb12a562ae16d224efb5498f5fdf408677e0e9e41bd69f3b32972bb025f477f36fb3ca13973168a3f58732952c067b3d1f7485a2acc1759f9c351fbc5ec8ae82adcf3e2e460eb2c5eabc9888756027700617baa80a48f84f7fb86b12b79b84591244bebe088e3f299bc5cf6eae410111fb750b70d0eb06e1d7590ec1b9d4215e23fee09fe8bdfc1fb5d65dee119fd2718869e28a9eec8f31f3cc532272b24d7e34676336547bc0b01ec0cad119cd37ddb188a97cfe9a15b6152f5eecd5406870ed137f36024a4bf496b9ae07dc4f24111d9026bc154fa15031c75da71181240d717b1c2861acdf2d50745651ebe374e7f523fdfc895233cf3d305959408b403f6198d1cbee04766bf549238cfcada8715683e847b7f8d3fc16b35760d3f1d8b4b88bcc0854bc3b9fc6f6184f8257be49da61b228d48c6f491c9395b73b949e2da8fe79e96198969e0e04ef180874e9ba16f3e0c1ceb53fb80c4f575b5e3399a732081690840ee1112591f0bea02529dca4e815d6032fe90d80295361f4424e1446f3dc4a6fe58f1fdc852b783c55fe80ccae5b9f4e3ac3a35782f8bdd4c0deb88f18b8e93d79b08ffb57172f683b618e2caa5f017209e3a668e57dd56d398e38d48e32c202d66baf5c565a9ef64d1b662d83ca7c080dc657d5124fd06d8105005ee7c9a4338cd60f84cdff735fef32e41331af09bcc38447acbd915c9fa4fe91d1eb4341c310cc58cdbb14e44669830b16650d722b1281a3899b8f0abe85dab95a768253111474b25eeb1656067f40b5f65d51d1f35d7325aefbd81d8c3c190aa43015a752c3ad241130384d64ec3e69caeec61cdd4becd88d9710768c6ad3e9c5a5bfec39f68456a2392620cb12212c08a9e7f230337db7964242339abd33d5795c8136f01aba4af23e9da2db39764a2b033be3437ad258f1a9a320824f3edc3e34ba5eea3c85f4ea865fd4908253e9e4d008b4d0361b6d904f39211c467ac431a580f4a08f3faadbd1e1f1dcf1819a6caa04c6497bf904a83bdcc1f077cfb8ffb82dc9ca7532e0ffba08496e0ded220f012a5c43f86eb7033b2761acc3b66bfe645d2b0f5265ca5e4a770a2c800c0bc61da5657ecd8550299ffa842eea2d974c41c3181f664c971a4c9da896c2075ece11107697898c0dbd275f251faa3dedcc2e08f006453f3bb2b58cc7e2e0016240e1f238b30dfe37d32a9c3be92f8572aebed315ec950c925abe914f9790a00e81441fe63db302984332a75c62ca9e4da83b9b9bbe909c7d6c517d445dcfafcdf897c0015f82a2395f3f1c8efcd6743d71911459f15faed6aea77f890d22e5fa1819b8eeebfdcbfd06691f4dddfb8487536482b3efcb6be4a0e1821f535b61948f833876f1a81c4c107c125a094b1785e3d9676d1037e150098eb569f1b41ee7c48996fbdbec406cf5e30be13ad6f7233e55e979ed30a642306f8097546fd8e74d826452ec6c1672c4c4522b5fc347ad105ec9986513e27fab76d686b0df88a5fabb62d04961850f02b04e1a5e84d72f5482f5b0fe0b1872d50e1ae517ec6fb85b5b9c17c4c0f891c5c31f17235fcc2bcaeacf43f0a7b32d9e27d59f071da50482cf35490ee46536ea4f3417c4cb5bc764f2bf946e96060a1ec2215fca73380703289518b1ce55a0c095ade61de07d93cb6b6285845e260a8fedf0d40ccc18b4999dcb2d859c30f1a838a7dcbd994f3c0687d2b5c9229559bef5e4cad6e1e58a171f21f977c49c44bf4e19314ed45c01", "", 2, -1742820425, 0, "4e70801bbb60b699f8f2e28434393966bfefe88593feee509c4749ec527398a9"], + ["030000807082c403023dc86c7e88f7350b6e05f50b79bb53c82c5ed548e8b2df04867fbf65c3b253cb0100000009636a6a5353acac0065c88e03ea8fc550f2abc326c5acb9cba781c0539df33651b9d96e55f46d96e2594563ac8401000000026300993985d2039da7f600000000000300006575d8f103000000000263634081cb02000000000665536353636a51ae475e00000000020000000000000000a8df0d01000000005c65ecdae516b8e0048841834f950b83c1e957abc3b9d6a36407e9916e3bdb97d382907651c9cbba297f96d09ca0b3df4ccc15895e143bfa23cda368f014c35f2d8ec5de48b8aacce2afb26d8b5f2d316bd87e64dd9eb62ab958be84f3d986bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029feb207ce5c781fe622bacd39d38cef90f354f8eec027e7b0e009107faa3d7650ce6e0678790ddf5006a1f2c6a94d86a75e5533bcb2e808208d007f363d80db870af0ae03c75af230d79319b93342fafef033f8b10cfbad995728b2e222a881e0fe6bb1a41b45637b3b3ee79162fbd41219ff4e31147bded97820d2d7305e440325e655ba19e8f50c53e63e924ac30c07e6c37ac04dfa3108f407226a82f9f5580227ff49f8aecb927d7589fd2b8c4e3281ae045459a84e525192a6dc7d1280668c0a08b73927d97e067c9913601c389d97016db529cabd6714f9ce25827adfb94d84bb1174bedcc962997ff8e557834582c02667355f822f7fb3d7b04cd2bad66950031099c8e058c0de09025b03043fe6c03f9eed93bd3d228a7017f07c95ca72712b031e9587267034e0133b8ab93b02d158df8b70814f59b6fdd31a3223b4a7656ba4021c984fd8fadcfce684c66c4725ee1ccdff155a3a65ce89a15975c59219a8358e0208e9a6bea387fd7901bfe0355892a2f7ace8c3f786c353beac2c3e9281a2337c0325befaaa2e1a2c341858dc4e4c32579477482b67dece5edba55ac4334f190d6b37871a31d9c40694b44edd4834710f302a8a65b9e48cd547592ecb904a6e51e8dbb0570e67d93bea5d25403589105e6b60666e8d81bbb7ac6c6831821a73dd8e20cf1bf9b791170bcfc9b3cff774cd7f95a7ef6b27d38e1527dc164634fddad316acca2ded1f37bf18a2a018d99e556d19030c396df0e4246c5c742efdddc51d30a9ce55589e452c41afab21d6edbd9fcc78e0f86a1b68109d85c4c85573f3cab80b43f7903a347304554d51792af8fa910219d58d7a94635f1cc29978a2ada3334cfe92635a49dfa4526c5f955a6f8fba97ece0fca7f93f5568658b224f8edb79759d3bc2f61a0e8f523766d90dbaf22961966d3b2404a9967cee8faa10987af9692a5258f7915d601f8a30f44d8c39e030282bb0e95f7a0e277605c9897eafa8cd7670c5d55a88779c59d507b17719881557ae3885356495472f376e092b078357952bd747046158852fa151ad6dea970984b6ac46e474461b1c2d74ef3a6550b952c655404031d886672f324d71a298bd6f2964d08e2d8fad32e37e28b704021c9ce37d51d05ca9c9c8e55b9515eeb4e0543b57e18f8de6cbb6f864e9d7e82e937761ee6630d4e56dd9b46104ab3ff408302ee2e1e4329b61a1ffad8d2f30eab2c01274471a75f9427f3850760002ddb1d865ed66deb553e4d71bd963ded857c4b429d18bfc838ed2d9be0075db796580cabbc1a79a01b7d6e8d2c588d9b20033038a6aeabc801578de40aa3feff6e4f029629a4c55c822a80a633dd60bdcccfec118a62fc738a87fd0cac7db1a5e46c109ad2f5971f0d97e63afa24301c6328f6abd0f41a02d2a8acda7582c9c70abc1d748f8eabd7cce52462b29ca17f84fbfd8d407e6715ad44554b9e55b3a5ff2ed1b9b871706ce92d7c6c229bf735419ce045d98df002743bad56b3f532ea315aa26cfc717b69d560c482a6bc3b0c0fc06635a77ba547612e44767f7347c2f1a942598d1c61f8dc897fe4f20b85dfe6926550b91c605fd64321b0b9399fe79746f775880572d9881a03f66e2bcc0141cf0c84d8adc8549cf7c7011ff9d70cae003cfac6a802d13fba156188f43af263192758e8e1abd6b57b6e7a3d2e45565b5d72cc96d0949ac39b16425b6599d8bea316bf71bad6828c4f99f9953402b66f14d3e4de96f4387a227a7bb1bf672b9086b4b25f836a9a197c56019bddd3b1de1a0d2607c796c01baa35def00dcbbc900f18b052f3bf2f3a4f585762446eea072ea915a6e7d80501ba070bd0cc57b534168a01be637131e11aa42c7c79d09be51b914a67e4efd99978c7a22c3b5c5d9eb085313f21eff23ae5c490bb02af90b64f7292c8d42c175ce2ddb3a43bc15b88ed492302f230748dfb9f47a10b74f503a95385774e5e25454744633e09b7f9a764048afb37e3e77c0b7150f3f0da885360587901263b177cebd9831f56d0320a8cd8272098de7540f573ca85c49fad1e8824cb24d9ca7781499836d02760fd21fede3a955bd3ca2726e40dc12407c85e899f12319642459059f969cce3a5bbcdb1ea13871f33e0c8058e8618677e1ac3f5a99ff408f74d83425a343c354f9ae10c0858d75accb3599e3ccbf309ae2a365caf8f8242ac11260716c6e8b491ce02b45b6ea6edcd974680d0bee70dd3920d6f082786e7999431c6d72e4b41b8927680d18c5e244f06916acec862e22adaa043c9ceff001000000000000000000000000128a68a34441bd33725e6500a0d2b5f3df4074c71749cbfdd0c37247507fc6bf19705b125bf2a400d92bff09a2a160f42cc894c27fe44390daef7bbb183df95896e07e9678bb8d6f0e9ea8019a4116f621bc1a437a0a01e075f32ea7f126670100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f1dfb773926832247ec6d44d2ddabcf8e062e1e4ee79cb548cc7349bbc184936783101eab7adf7389ef3f99c9d1a12babe1e516dc410cfae5be79325f5182e82e1cc7a3d2d99d9513ba5a12e378e0e9ee8276e44ccb22605ed65c5ed2ad5a088d938eec27154106eebd868628e70bfc4df11d13cab72a18b7188c4bb49c4cea60202e6a02c13282f7bb1fb13726c6e17905a9809a406ffafe37956fd69e6bdac2203207fb5a10e42f6c8ee6857d1ed0db34ac8d08bf95af185dc6704d273d5d370c30b03f755f548056755eb9fe1d9d7399cc3c75e564538e463cfa307432cefcb14a47958e89f5c4ad5b8db9bcae6e0de32cf1d6bcf5d87fac96c8c3d64c7c5b9a7c7032046855ae5fe7b2d91e2f862248ce146f70f2b1f197e0a17d80b92ad48ace2d803225f26862ce3272f909731942f8efd785c68225dcaf967f50e4a782356ee823503197e6d31818b6d9524ac5f8a4edb73ed628f895de77468c7fb0d8d7acf645b32021d9e19a0d1e69b831c80ec1fdd677cf1f326430ca262e84879142dd20268fd02032bf31a1a00f20f5b2ea36fb38dc2a4dd221d6f7bc119812c6bd5cac7d0a52a9c44e1044799c534f8f090a40b9b657b24aa1c7c1efd0d7e2609bcab3763eb770aca3490a8b2a76d51c1ab97927bbda48cc4c10167f70108ab30d58958b1cc18ca4eac3051a74a1e3feafe16d3dad4b6d081e9344819dd1b2660d211d9363cff9df287c05dec97d3c2f206142b09fc60b19d7e8198899e2193b9033a75a6dae7fc6dd30a0fb73c9ebc1026b57279e4d8a16016291da9826a9e5824ef960acf64d2fea69baafe6dd3cfb5c549ba78b5e0d632db8eac78ede54db492c2e87240b61109ddb67637bf90af4f127bff06be8bf9a5f4d65ff4c7b0c3cebc9cb26e90d1c65fae66b9ca50e73c19e9e9b297b06bb7b08562a3dfe9896c7bab4322b582507220e2af5b4e53b5ce2465a46f74fe6179b70e1cf54d3f7897705ee665aac4f503e58064c80fb7944b69d73daadeebbc0af21c75441b91c0740c8cffc90e2c1a2ce16a6ea06e18702cf6b28f5adc0ea273abfda7d8cb02b1637777173f11615b41bdf6027a9a73f05d2b57f656358ec777258711b9f8b1c1cc1f2575cc24f87541ff884df236bd3ac4feade4e656d7ed5a5f7438bf1fd0e2eba4f2ebdf11be85c2d953da4d219676c3c9bba04c12f29948fe8878bccd02bf8617bd148d409c65f1a53c4324e41e940ccc5f89f7214b1c3cf95205e00ccda28d82c51a471c8e6f4d76e218eea16e2e78f7b0825ea9391400f0d171fefbdaf46033d016b4d89358b2ebd31ab2615111dcd1610046d5ceac1cd9f25cd135a05c98cb08d6ef98b76594971ad93555c3e26b2ffcb88a1d562a87c3dfa52672d8af0ed4e34025a0e987146550ec89d5465ea57c5987e1b4d702138274bfd2a7627b824ac6306a62574f70bd8d108986011861537ef5a06ac44d14b17194ee40525c2a765f3c0ef6430680346d46c9e5566e8ea8838de539a9d8517d66e84f2f5be2c3e4743f0b98b66f10041a9756c41de879a2c5238191ebd6fae5b63d30d6762fd90e6292183e9ac8da5a1fe88bff1d064568edda9527be223de3d646228d8decfe8e01cadc084a68280f1304fbae8b31ddd0cac09eceb59e0f5328f3b9c4bf429250b6e8fade496a432e059faae16e8c109ed0d9c7c92b664bb5cb60f346cf08da06c756bb91cec31d2976606cf14c0476c34aaa4e777e9acb377c295fd1bd0f4d16f907b45ee94ab46aa5cf6846093705952ad9b26c9ca083d2f8c934149df68707eb048fabdb6b15cd5d349f1af2ab5d8bdbe79f9af43d8036d6b552e44cc78b750712c9b722559a577be868a96e7c3479fa04c812fbba1ded01f24c14a4edfdc53cc71ee791e7073016ff7a141da55fa72b454bb3279f383b97e24593f3721d680ce07c86c432c08c2643360438b47693b684c54168dec664acec96045a200072178cdbfa0aef08ac5825b4033af4a582c3043d09cdfb3f25b1bb4e4acf896f51ffb8698476dc793127801fb24665a94f5dd6e0387d9954acf3f8b51ba30b252a22125d6820a7ab68766d2f40b079f65a8f67dff6bde80cd99df477d64475ee7d3be869c5a12c48cceec27fafc262c4ee180e1962ff8d54365b7d5ab651d21223b792ac676de0fc07bf8d6cb892ffac9a2ee9e515487ae9f2089a32a330e50f3f20274b31658eca836c9eccd5f166c9406ee41aceb0dfc82571b3225949f85c4590283f5a1dac4cec69f28b0a719bfdc363665910e5275030caec7879af71a074045c04ac4946ae4e219a21b8dc723889fe0912fea7aed1dcef4eba391d50e6bbbfc2e51c7b6aff11ebe5ccb1c0927ae23c8614fada4ee2db8eeb27c28d3ebd9fdd14ced942bd48a97ac964250f54f5a4188ed5cbcaabe4ec05", "ac6a6551ac", 1, 714134217, 1537743641, "17f6a8f062d7b78cb529d9d59f4ed1dcb51b2c68a0de6db91b7fa55dbf7b6b24"], + ["030000807082c40301323454a81c892c4be2adba2e842831b7d6521de3a408100bfd6f33d9e3d9112803000000035163acb040581002a1ff7f01000000000453ac0063a09d5b030000000007635151535265630000000000000000010000000000000000df53f40200000000eba195044417bd13060799d380575181741be826860b02d8d79c8b41026c98cfbadfdcd5eade947146fcaad1820fa364fdbadf458edd0fe730f635e1ea1fb88885e1db7a1cc8ee13a233c87bab64a44da52c3d4da88dc3ad2da76fda1d0664ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000674743d8f8da8e9f6cd6fac3efe65f1232190fd8e18a86ccbbf24e505ed95ab4b3951453c7778176b451861b5aa1af004c060d1527df5761593e91ed8cd5dd9526a85c7b2e9dff6783dd17c7090ef815c50290dc3d24dd0b1ff14701936711474fcbf61102506a4f617cc785fd330676e1830ce6010049bc259c5d199fcf10f0021a2245991615a5bc5fe80c69a15720d2a7dab83423cb011f3029b1016a1e8e9c021f13bab0e6e5ee51276df2412627f903e3edbf00332650c966d1010225db51d70b0689ccdd9307b59c67cd362b71071a38c83a8ee0a1f516f6c3d88d3eb1d511a1c22d6e29bbe239cc998fb0ff2e8bcf9ff394edbd4396c2167479e249a0307831020fa3d1a65765fcab35724051f0a9fa41d91b93f24d2889f6f9872eddf77f0648031aba14195a13ff4804ba4c0f015f18a7aa50a3d3d6820ec6df5252d4a4091c71022d0d91ccf570012bf04d7f8ac1fa039a835809b819c2dc18af8f99a38038b90503111983352dd11e5cb30f79e87c3fe3e117ec43b121beafa6f2e79d39d2688c2102189cd5f477ea923ea4efcd460f6bb9e0f4f920260606553ab3fa593b3d8ffedcebac457d9200e10935b43002571ad3649de4ace83bb22d4126dd3f2b54a75d6aa9f994b52c07c448ee14375debedf6c1a6b86524cdc493c1863be97e59e281e033fe0984b5714ca1ff049c3d6a827d6d164b91dc467e3ff87fec13a08ae16de693e2cf7482870a64b62c5fa617a56cedd1de075b140182e02e68496d78fa942f213cf1b078b5971cce282c67effb194d30b714529ea89c8d60f4cee87dd399bb0c4e2ff96488bb25240e62d1c2a8f9f0c0f049d42bed33a37f8d5e55156e94ac5c9194b93bdcf06a439552cebab0e7bb7db7712162c131273cd5ed294a1760a130573233d912681a901bcdbdbb421512b457cf2eea60c0d95e11f6661a5c8187c97b0814f0dd1b810e946c2823d454585a30a7279bd6266d1dce30398e8ca4e4f0f17c8ea29fc5c724da548866ad5ae7c070b46b0ea3eee4f1bf420573fbc1c9db5b20d855f5bbf4ba92b25e40084fe9012f4c1d6691f2fd017928f62facbe8abf39967a6c1903b035ee70be88dfc048c2a3f036a2b9fe6c956e3614db350a9841183f24242022691fa2e6eeea356fec0a7e5001bee7b365b98cafa3141ebe5f12fe42500fe5d17944d215ffccffed8d19fe4073374642e958b273f2c05aa9818c2fd325f474d3a5af698d8b7123c66f068078f08d1afe48999043df014e0efffa7c3ee2c2403d674c39fc59649c6689311841abb3f3a9720d8f5dc0c7d5a3a3a58a709fcdfea35c0e7426fc690458a1b0fe21f54e1877c5ab6ad5afdd0a3746e81f5e0e115c0956eb7c0584fa218939da728c07ce89fa266515bac55cab0dd0b4c38975b5ba0ebd6b87b75a77a8a0b4d2b88815c82212d9df8d64266d6ce4898cbd4962dd40708138afc9f2a4eddc912f0782cc8ffc12424fa8ad0b02404150b048115342756dc240176567b88f453b2e9dd6b16ef1561c8278bc6a16031a1bc1193b15d7ef5c5dcb26d5116ad857e8cbd467cffa11fcba86aeb6b38b02abcafb7c98c021b894caf7bf27bff372d3d247249c5e2269a8c96deae37ea13c16ecf668ee249b424231db40a403a897ce13a7725c02384435633081ab3f711bb61a321004c272977ac1cba5138eccea1cd6b2f8d493191ad61c19b242c8b379827d62705300635c685caf9c1fe97899f3b77fb67a9d8ff779a247f1408e9d530ddf87c336d033d678736564785b2cbeeaf164c91de1f19d13e98b95e422b50590cd0359844e2417735b6c89fe0455506cf3bd2948c857d2d5ffb7318507c22e6ee9f81fe1ba3d651042d9fa888445a63aebd4073ab94925e3d9e4984b9314f08bb9ccf7d2877495bb8adfec98761749398d6d56ff65874b51140193eab259fa74ab0e7078391a88170c6986f811ef56d20c3e5134e2b2e76d8bfcb1a898b86ad8558cd544c2d0092eb2aa736466d5059b3188d914b150ed7652c1c52c71848d63f79e39993ea6a1042abd7bd44840bafb3b6f173d9888e2b4cda5500b859723828643b1f3516a8f2994c6c986ceda244114b5250cd28d71af8d56116e3f177f9eefb7aca44fc4fc0ad721b8deb35d6ff9eff9329910b5f27baef2e5dd873d5c216e8399ba4cdbf8eb7de09750ab93a589e416a1d31048d5d7e507872e0b81e707e105544ec5d04ebd11323ec6cf46cd61338622a2f9e479c133ee8ae027e0cfad134b95036c0627affccd4c605fe199e2a8e2c50d26884ee677629d8eccaaaf8cbac5d125e4f0ed3499fa860e324b790b38d8dd3488b81d0d95282ee0a672a1574f6a4cd1c12e76d91379e41430ccfec66e442bf2ca063c2b0e89f446896b2d156e3318d1e6bd5b0b7c87bf6ce93e8e0587b504", "ac63006a63515263ac", 0, -323886620, 1537743641, "c1bed08e135e72cb08899c11849fc5d743a293cd911f25e55fa17d7d941dd768"], + ["38a78b2e038676c3d807709c824052bb1a966b32dd0cbe9a06971ba5a489ef47ccaedc7aa70000000007635363535100000d3aef04b1d04bb67ab5200bc97454bb8c6b5088e77be3fd1ec501c8317a3c355c96ba01000000000563536a6a6ad8531d772e4f92cacf5f5d0bbf2ba455a69d8afe7c49287703ae167715187fcc835b7a4602000000006b0c905202cfe6430000000000025200a21d7d030000000002510000000000030000000000000000517a0f0400000000b04d90b069cb96569f5032b07f733e12865d998af1a47213d79d2b9ed19df75b2dc7e352304f7aa8a93f6822d3ce6cf9dd4cb7f3b8e256af6fe1e9ebf230e86567d23a2e4caec7c3ec0d54878d6707a797d4a7604d55c06aec8da85d82feb76c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c47ddea858cb841e150bca736f08c8505e45e532153a3c336a38636470cd2fa19faba1bdea39e45e4feb02f2ca134773c92a314e499148048498784371af860569cd239332230a72fc798f0d160d0329cab8e7662eb5890ea274d08ed0be7989b9d75f9060e36fbaf68b5da5ec12c9fc5e6bafec4aa0334e96456ec004b52b1031a470107cff1c43440475c2e258fcbd1df7c6ad012fe26b99429eebc0d2fc4d10304e496d9569b63954fe4bd9475936a2ce5d2356d3a3c18573bc723d2a98f459d0a068c97c387680cba1861ea69419b5488f618e25e68e08528aeff25bfa0a46d0db2a79e26df614a2456829dddad1507451e60ed36d9156640507979a9081e61d102239d9f266e13547070b7dbdaebb80eab93278091936a7566e555c7e8f3b36adb0217cf4b266b08c2267fc8e25ccc256455f92c94f3d71b81e0fdcd0f8e55f798ac031190d9a4af33798dbb91f0064910c74cf581508eb5720d490449deb6ebdcc7fa0229dc2d515c4447dd44aa63ec98c80cac01ee2b51243139b6cffddb8cf7710afe02060482b34304325cb4fc39d14d7997d163d034b4d6711c1c0522752b985d2cf7e00c0b61f4dc0f7602def2dca1e77febee12a9cec44e1f9ef280fb95d0b00261ae3b25e03d50a26a0cb3ddc32a0c71cc5fefe5d8aac95c7d8beeb4770d50c3216bdc75cb69526814cb9f46a1df695d2c5cae5c793c63ca0bd5508cd86d947024cd9a1ca6ce66612c08e435e2b455fff198b7e92259b7f503bd421564ceb7441fe2060ed8703d36869a65aab297ac93d19324b97b353ecc8f5cda1685c3cb51c642850db0a6f130ac6f9001ddfab9a4931aceff8bfd0a36d553e0e4029c091d0b11a03eda8f9610dedc283fd31fe46b7b6c9e71c0b73e3f5c74691f2b5c480bb198128d41b28105cfe2eb9f2592735b50b5694d00070a37d5c194e95ed35814c49c52cb008627a967162fb4ca846530ecd5c9aea640082c941ef66f2fea22e241fe90c7fcf2e94901173762d166fd4e39ec4c92cb2d28f9933028ff12247d86e7f5d7833698a6857ed2da06343ccf4e99cbd173315fe361e46818fb6e6aa966d3863273c3af2f8d3c61bfc811bdcd425d552da00d846e9b54b4123305d63eedec55c415bd46167cb9fbe08c995b4878ff8d818bc0ccfae0042582fbe03fedbc384e126bacd9a6317041593dd505930821e1cd4bb011f708adfd63ecd8b01ac9827e3a1034de3cff5869b78bf40d0d883bfec22cd1b37e94b2b48a4f95643fe55f007f9e822f73fdf64561ec56c1a7312718087f7d7a05c5392144b33d0afdcf650b58efd118678e299867fdf1e87daef2b3ce2b6033fff75326fb30400412bd92800ace7df02495a1cf092473e77e6917a81df9037b5d33e00fcc7903c49d2262385dc9cdd23b89b2c894f75aab0ea0e796ab8a99f8cd2f1bde64bcb940e5b2f01c47807a581fe2806abace6df1ebdc4cec938981ad212445906ae71ea5b5ee98f35337fb9585c10726e957134c8380b885c5ecdd4fad2bfc19d59fe06592a1c0d3b6df9ffb3b305c80828a95adadc15f880ce19b91a5caca1d8fb0ba37e96bfd6be6cfb5f09c3ec2f08a6d41e0f550075a7bfb741f9f44d7ab1138d50e31c91f09b14d6f2af439015e9c5eaf12b640e5ea381a11300bf395c279cb5d1bdb1d3172ca2a652893c9d0b6c32adf343b6386eb132a4eaac258616a58d52b9e9f3e49725a5bed985fc962a55a3bb7ce73af0b4c523c05c0449cf2add5322a29c01bc45fa3700e9e0fc51e9ddacb24235165c7a87e09226a64ff6c54cf9779d5e835171e362e929e5b33182a67b21fecf67618d4d029b3f52568fc77532e44b090843cc1122b2cb3775786fdfe8f0a4f6cebb9317e55bc35e576ea9b3575efb3803488e27697e91cc51d5edf6911014e57eb3bbd615086813b244eac96ed8c7076856fc464e7ed58e6cd67770ce2bff78c3eb62468d70a29aa200d88957e2e08d6615115d6e119ec2723c703a08f2db78e6e322a6174df6b5fb320b3a24d25341e6d692cc1a328aecdc757b0588748e11dfae4e124e8650fee909c377dabccf246f87da01db1ab7e4e89947662e1d01fceffc38f8644f36bdf3f251c530f67214e3be6e52dbf8b8ee3acb51391ed56d97dfc245ba2dbe85b2b26de0e753ddb9b31e664393b6e8d90dc620df75db7f484cb575f831eccc7c6802c47160480693ad53df43bab729cdf9a811c70a2a4624e91c9dc143cf136f117fc7ce719ae99a9f30af825e97bb6ba765ad023be2b2384e48a8010140000000000000000f8e638020000000072a04fc7c437503405c6aeb7a896241f426f8b9815a8763c48834415efc933251b57aeb05a65fe81c7fd91175ee57f0be0927ab584a7ffee86133feca4fb5f0cac691f11fbad123d3e7b3f1eb662fa1dce49bc5af8b7c2e0e32ed4cfcefb6dd6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e43687bd6e54c1f83e3c0e710dac9ac0ccc186f228e35558d0dd7e70c33b656810950151f2c09e5ca08cfc0a4f19d8ea2d672f5d3c868571e49ee7d870447948b794c1c76620459394ce4bc3723d10c08b075f4356a11d2d4e3f935af477ab3ce4c707adfa2504aa74b624ce303d1bf2d0c681dfac0b8988fe9511b4fce2c44030eb264682aaae26e6167faa74445f0aeb42ff15c1100533bf7f625e6f73ea179031ebb8eb6cc0579e6b4637d5acf0ae21fb017d0d18b843baf3ee2e1a591096f920b08686219884fffd7034dbc65c165a7df3de5c24f89c02baefceadd02ac976b38e73add3bf0e999760039662b29b326a1c2ce92ee174eb39fd8260096719e4f50032b02adf7b6932f59aa4fa01e0768d579cbf7a99ee065c6ca4e0a84433bc678d3022e75869e03df19c7ee98d1e71b8e44a3be198c647d0c5661c90b1e68292d9e820216404adc943da876c846b8725e3922343b941ec03a73486f90bc11a9c525c1d002205fb0688c50b1e52f8330a4076988858063aee40891d73fb289d7e470df0ee603293e11cb5518869ad8f2d8c19f90a8e9f1ed41eaf09ab4cab4e21d53ea4c44691b3091d2bb98fe8ade0e9d4f699108ec32517075655ec89bb3cd4740487c445da10e26dd5f6b56ce186df49c24d11c8706e6ef573d24613e28110b2be9cd9b0325274ce7b18498d11286bcf32288f3c729d84f70d82ec20ab13bbe9cb0835d84771f32b256cbb3e96d76c6faf6dd1932d4feb4ffc76497a5a79b2595099fac3c7d271d9a50b54ddd740bd54a729944cb7c248de5c7b10f7c9665cce2aee7e142582fbc3f96643f5d5b4e1f65d0c9130ca85936ec750b24e963975215b32ad509a96afda4440fa93cde0e4019e98611beecb12f5bb26f1781f6445d8723507db476ca7deb51dde479dba49e80b271edfe4ba52f6d957a9e4d8eb3785f9f8bb1468ac4443bc0790664324841407c69d6231fc69fc772d7e04eb6981b1d194fc0d729a0c74efae8b9af41d747aea7fe3df0a6b6c918bd455dde72920ce31991fcbb08dc9a9357b3b06fd9ffcf93202a6108ca740e3b6b68c07e43737ab471974f66d8c8c7a615d87f5b2371dcd90174c9f36ec9139db3b319a252380391e4bf34e04e44500d74199d510800a8bc8e8b23c143a8bac86eafb47680823a03ef87119712e6c7b8246a58e64ccb55742e0034b0b6c1347d83cbb9c62d910490c9b9f7913c6a2f902dae2f02bd74cc8c20fe258d25401a775f0447b222f82b3f0540da07f33a5d7a9187c920bf654348865119a2f71f7d747717635e7038a9475af56460dc367d9d2088f224a5dbd5d90ab7ddc2b7afdf8460c49a1bb04df326bdad6692e1dd2e85272ac6989514dad7c6ca2ed18d586d579e741fc95dd613f720c3676616c9c9fcdbfa528e03aa34ec6c38697a4090110c3a2b8f1d47caa2d25b6a2001e862e29ba483952f06cfdbb6759bf0fd97b2f0206a0fb98719c40d80ace7544f319f7935a4b39cc82550f50921a041a8ee761bef264805f0a22fb8b5bc3beced39b9899685e8bb9d8565b588c515bda698997e62dc9e71fb71a503db0eee12e0bcc60b9fa16247a32ad5387f2fb5d53b6c44ab7d8e509d98542635be08ff8ffcf5b482c9e79312b3e44e1ad773eba3f3fe5ad30d6f15a49c211fc4682932aad060e4281f89eb867935c19a930d8242999fd077da0fcdffd572c874d4f134ee745b5127133fe66f54676056e6f65b7dbc92b2ab46d1178608d791b5285427726922b9e721ed98937048175171d704e4619e7041fc7a1f0839425948ee78c96f3312fba6b747f0ca7ed99a3999b819b4d5beb55e27894c65d8c01689741a221ed6bab4d165d7180523f0d4f3015363dacf53610cf8367f1b78671a627c31cb4a6e5879c0181b49a0f59919aac6e8aa34eee90043df65bd26dda3891e4b37b4560d9b8f070bf1c033d6e5785933aaf1ebcd55a1ce76cbd3461c1c7a94666243fd3c368e5555652b1945a537e2a51a470b681d2ec1bfb02fb06024d7ab8d1532d13e7026ec94eec266c061a329580bd60ed4eeb4054461c5793cc2897e8fa5075b774895187926573c6ac0bf5994c922653ba1aa56a7f165d85ce2acd62740d0c7b6afdf8bedeebc38f303e1002f15e471e6f17126c2e19fbd2f81216e16d0fbc9d8ebeb811a29f3808b88c9eeeffbeb7cc4f0e3066aeb890228c39f05f694e12fbda3516ccaab82ce871720a82244dda822a089b876174e71b46a501bfd6333473a24f7c9bfd939d9a828a7683287c22bad1e81215ae30500000000000000000000000051cfd4205460e48b5ce21d8ba2d5abd1deb1ebf1a2d316af1c46314526a2c8e3dace4fc0d22d594b25aaef75a3e5ad459014c10fcfa07056579ca548349d6235b2bb22ea53b8a52df349d61e05c10c5f48501cf49932efbdc385a1b80b5c2280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a2e2d8244c864b07dc634f679fbff146aa1ccec029434229af4253cc233798bb8309fc03ce8ec54c52190189f96d821c0cdaadada4e2ac12a2c3bc7b11a58bdd69cdc1e4169ccf50930553865a385d882494e3899f77539c0bef58d9cb5e326c532cb9452dc3e5bdaf6285a5b1e1865b318e8173ba7e2e88251ad2a10ea54d70200658ed2c57e548178128c00087a7534e163be7b578f8a58b95afc122640454b02026712f162ce735186f8c72932133bd6a3e8885b76b6d5b45d51cd9758690bbf0b004cc5736b8f5cd464cf361a20893a4af45dd1a9370a95c8324d0fe68efd3b15e88e7898bcdb173eab7a95a5517947de66ee5beae086bdae0af83e674000337d0226b31ecdd0c1a6dc9fbab54fbeaee72aae39a31f40caef6edade4dc998906e0d0310fba542a6e44640aae278692948f5e78065104282cfa8d3587350db1fc1dab20322aa257dafde9f56a149669cf41cefe3bde677f910d8b4a4e4ce270071dd882b030643a178c35a885b80386b26090ec27622808fe7eed0efecdbdae5ca7733e7300208de90697b27e621602d7f489500643c4a198accc0f8078b894834bc1553634285ef91f38a7298a6230a111e64c42e97f11c3cb9455861b71075927f1ffb0ce74eecfdc8a372bd89d88705907c656e38ef42e333430fc0e81ff86d9ec3ef043276fadb3c17f7c77a0a4e3bd70ebc5a26651ea43804c8c45384a6b6082ac493522273b43168dc905572cb90a98dbde88f3892445a8fafa366d6821721d019347a0001fb580f07bb3d8e73304472eb909bc75d845e37aea8a03690ff6bd213689543cc5c7bce88e6dfcf5900c25499a680afbc293b205ee6e2ad37f8e1e02f8242b03e15fd7c3ac0cc07af3f15cf9487c6e6fb65fc3808d6ae8b86a87360f2dde60a54f17914c6ffbf13e18e6d3a0b5e35a3613d2e58722f35478e9af03b59eb2128c48743ad2829e34fbe27a5b2e3034f5ab83dcde2eeae02c0140b113e6c829b43b2b9c212a2fffacbd4d69872c0a896245a51be299dbe2fb07a1cb0c9361578f266a8f092fa143e0ae1c3409456afe9aae95b21fcdd5adbfd921dbc5e2e08e600a05aacc3954ab14ba8736364c14f39b91c0710e96b7c1a5157face0233d639cfdab6802b25f4fabc6cdf924738b6cb0dd750ed104d0ca3f48a8db50b2eff6bef7661bee53e0ff2f4d7f114e245f865f286289d6f1e98ecfd179861c0c7a95a6b98f07b1dbde89519d6806d6963a5af8e489705b45503df1db903b37294d0baef1885c0ffb4a14c7c38e0fc57b50d329b6d5f1593f0ef877e43f9d1be657b7427a88a6a6b7e7c0f224ba0db85f8da126e5850a5c54e95c674fb9baeda86bc7829bed8d5114cfaf0db9823e64fdb904a3ebaf286eb5966b08628b39e21d02fc9aba3678e9330fe452684d2eed28bfbb98fed70428fbb59386c140f030b9c4a1d1387439a4733545acd931bb438804c6f387fb39b2d874b10c0dc88155b80ab8b973f3b1c0378cdfe1dd3cc4d3528443371cbdf5162d5d1f11a16ea6fda4e812f99156f45a78e216e15e1b6f484a341f7cac4f4c522c46cc362d178977f2651e6872c14f2744dae0be784a850ce72cf241e5942d19cb1edea781aaa22d289a1d905cea38e916300045825fd161747b661aef4c00747d20e6144c77ca5a0d17c22810273736fc5b66d93cb04763298bd7f591124588cc4e04c7eb2bf9668fa338c9ebfc4b0cdbd2e9f6b4cfe9bcb563306ca9484e0a3313c040cf095de18f38a2924bc69e63730fdfc4efbc7e9d810c0cf607b0cd517cfe81519fdfbd90b1fa6272cc0e283f167fe5c8588605597f9f6302839d533817bdf02b17e24c9a238194aec4c7ca5dd3747a6a4d1e4ff77bb693e76253c1313cb1059178066f0b4c19936b3af395eb72973a8e755b0bf1ad6e786e09e79259544549bbd2367532e64433de19d2a7d4c2f74bc9e8c4e1785e776ecae19ebaca8103dff2acd4fc3f44da8a7b7db1eee4d2a9e65d0bd46df3416b3ae085bb7c13fc77bb0224181c19f43613a8b64a837be636536167f40bc4a7e9867013070f13c86f443ceb11bae3edc589042bb9d1632d66bda68d84757135680825da99e9c7209948841f8d72a5ca2d8813f086533237f4d182cb2fac35fd71e82109be76cb4723f43e89b35af60cefb8b57688679a8ce3a4222371223dd8df69760286bfd290f46ff753948c705c7028cca248ead3d72e45a8d166864049a46995386ddd98d91ccca48350001a52c9906a9ff2696c09d97f06299cb771b7de0cf8df7c3a78deaa921bf55a4be8c4fcbe9b9e860d22c9b37a5e75a5400e283cbe3837468a0d7cd9b8652faaa83b736f5310b3114664fd62261a976c09b608da95ffbd32d5ed0dc9f1c1fc33fd210347defdcfecece679208e9c651aa0b7b996b5a8a03", "ac515300ac005352", 1, -508906326, 1537743641, "a53f087692eea3847fa20ce6aa3eea8d57226ffaa4f1f54b006ab96ae8ec6bd4"], + ["9047211e01d20367034d47dad57f7070311d96cfbbe1ff78f3249e6551038b77f65c0a5424030000000951ac6500516352ac00ffffffff014dba15000000000009530065650052656363b944bae8024ace2f030000000000000000000000005922df4cb6ccd1416df4d4217bd1c24fd2101603a5d06f0d8fd75af0a75b40441b44973d974fae65a92069023c48cf616e693317886bbd5e611538d3231e9f14588ae6d5ebd0a43957732dbb8250979d5c01af4fbb9d1e15b7150e167bc7b151000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b23fea1f1bb9b01bf5db753abf818319c0cab6a9235eb86df9c4b2f309135c0cf59b633949d195b14394a0f2b538ca101faf8b7c90122876dba9ad37a9338fbf353c7514e0d67389f5467f3615e9b124de24529b4855fb66504012e32cf6ca2fd7a9693af45d8e3830770a4913f5341298df63bde447bee5f1beb29c4da365202055bd64afd80571732ac4da4d99c834c0fb60032de7ac762c1e388a74b868b3c02219896d1f5ceef3ea08574736f218ad91eac19ff564c2d1d88d0782ac0f6b03b0a0263d24d1dd786d8f82b216aa2342ab64856b3243ebbf18aeac2ad5186be833a91b6af3ad9e601e75961dd7b76df20dadc6d5a2d2158ece764d867c57edf5a48031c67836837b03948c3c50c6d7e3c6114944720f12fa3bf12f78e62d8fe41b7520213cbde5fcefde6b14dbe3f2ce2383727c06bde604a1d7c360dc6927bd2fa74020301cd6de9e859b2f25dab30462307930298cd0a9c6c0a386b6bcea3749569073e0202f04e826db8b42619cd4283315b161c8d1b811ca992f131676072410cc47e01030288ab09b5144c52e7abb3476f906c81e16c055cd9a345db6a963ea830b5daf7d676848001bb99785f4e58c9006c287f36cd09e3d9d7e850f1f3ce4d2e18dea3103a8b20aa5ed6001280e5f2caae2c53695050d444ea2a0e9c8ae683a7155084303706e66325c563c75a4885f2848eadfb96cbbfdd22c91c0aa84d2837370bfe476f18ccdcc2e0ae9baeae1dc4f87ebdb94e61431df1fea079cd934d7ccf609c710fcce6537cdbf5feec3c405aa44fe579bcc2e6dd17ee52a6acaba644f509873eb71f5dc333773118c92d8a6c99c9eb42fdd95e3b5ccbc77015ed3cfb56a152f2eeb2fc59ee65dbcb3eeb2ae7abc96fa820f59bab0201dffa94651031c51a9741bca85e255722d5c3ec45e7598decf981bc709a6aa8077db609e3e17f97b263e374f462571325aab37a127d428b24b8101b06941da4260fd30b6c3ca20d91876318bd248a8d01b6376d706a8569e7e3d995d444ade62cd3827a6ccf1ba358dfc3570f48126504d82eab74b1be5fe1d16ef234779f3fc78bbb26a609880caf9e47dcd0adc126da71270fee202fbc037a92b22f704454a04053fc3d915f4d5534fb60708e687344f5d9878ef7e6f3c96df058d484086d8447aa43b4dcfa9dc08b5af4c4fe2181be5d8c1cbac31bee0e00f65bf7e756536e5d67153970730211801b03e2d4f5966798226d1e408d2bf0124ea34131f7f8446657181bdc3280103977844f874baeb101761814a5530343dfef66c20242dd2e1f5d20ad03b95ff88efbd68a9db1efb487848b451dad280c29e668850031e324d5efc277f03ea2c2e4b56b70c5c1f9845e9ed1ce05204636015e19a9dcc9206ad31c5e5f7734dffa657e155e95619c70f4ed42dbc8094799967c4ea01ecf23a503ce54d623582c062b393b7e54791644992a0928e33b7714e5cb5f0d57fbf335009ce16d26a1ac021ac7222c54f5e24223576e3defadced9bbd5261e52a56a8804b3272c2ee26822930b6d88a2d22c960094d21aafddb1cf562d477589e2739c21c82692a108729c106055b2245e9ea4c76f5792c7156bbfe1410ccf9037d500bf7650e9b9648d7f88e326932365743b06a4d3f6d70f552660cdb45e3a3de575bd2a26d2b4daa7b4d35c5881e677e758ad442aef97b931f8650d8605ce2193360a7c28cf6eaa2c694801c03457c3fc17e31c2c06e890ece40c3c6e2d5f199f9b11d0619c34504e0a74f19953c99709490c476daf1b95db1a120deb2fb5ddd0fe515c17f0a4ad5420f5466f34b004c0f5a170b4bfcc420d980cec733236d42e9e617b22c981975d2d7b1236cc42f7348b6f80d64d0347d7c9a5dff185bbfb5925a4e57d9cb92482afe5e1dd7b393050c723abac0ace48510542f1e54212a7b42507b1acea1389bae5b1b4af95676c8127e95ee4a7408a3be4a8492d0892fdc4fdb14d88f7738f2ec01d6a70774e1690f402a752ad69f58b866b48515a483b88e72d76d1c3efb41de6545236d337be4ff0b0002e49e2f139578a6df329db638be957da86122196a79046981b790d655ecd4ceee4268682cf4d807208c779d3b4586deb754a98266cae9bc2885c47bf6ace5edae1575416dfa9946a45393fd2333ae0cb289b56d96a8f69807b7b1619f070634890056cabd9ef1152182818bca10d84eec730fa5bdce47b4ccd662f6adf371e496f0898a9ac762fda01c8e587a1e354a4739f9652e97287d08b0d6068e35d86643bce520de1e1d65a70addfc2020000000000000000000000005722d2c8fe62079ee0ff8ad21857f8890251e2907d1bce95c6b908970b5cde3b08955e2d1998caeefe724a8bb7d2aca3de632faa9f946f193be2a1cf2fee63f27ccd7a78ec02238c7d5f2b267390103a955cf78ca0d2512436a7360ac7f4fcb90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049f9d8ca461023e09ee3cb4a9b4403ba75e37ab906aed894941d9026e1bd39e2c4a6cb181ce55128589dfe5f7d0a2745220ac5c734d4867202803df09756a7cd7315e7d7b23f9dd9d297c0b5220b1475e18aaf9accf3f7ae888b3c532e4d1cf5a099cf40d6e705ec1e84057083416a3bd29676e2a0a19302782887bd6b312c4f021e71345372f712bc29136de1d8a83d5474fabad84f0d10b94b80b67971a98f4202015e09d9b9b63c0837eabc9f204ff75e97340a1da8f2660d960ec83e1589c9190b0278e11c6ba883f2b89db31656ff8ee0d87046314cb351a81d479f36391ada5caa90c7f32c00f9eda80da8bcfcc56e1b6c23142d78337d42f071057c51781f950224803b8f9ba1dba74a727f48b0d0435af2ef73b887d35011a768cc19c40ee4bc020019cdd2eabb471dcf0eb225e95636a2f23d3d58d400a036526a9e291e8facf4022825cb2cb2b2a543a6015c8520e27d88e21afa96a3e6e4c34667c7cd17e21cfe030c534aa0ee6074a207eb4d98a1ba245c1da049442b94bb9c7df325eba6edc2b00307fac3e2b8c32b5b981ce2c5f1ebc902ce1ccd6a267580d24605ccd1c5bed200cbfc168ae991412dd52c0e6645b954977a5f3b34aaa158bcde146ae2dde754acc6a23d3e95fb9f214260fd1b9ddd3018568ad0cb66378bd845b15d98de9d79ec8cfbd6b068569589c3ca1eb2a45b52b7c7488aec9576e0a67625bdc22c33e89d7494df4c28835aa3bda4be6447a232bd9d48c88ce0c5e7a31db785a29d1a259f84fbdbf69fd08fdde336b0e8d488b244da0d3d3379d69d8b6cf8b962fb049a3691719ae89a3d36bae709297b2afc21c25ca2d9a9b0cd84566ca091b4ed54ea27c6d68a29ef1190502f5f6523d40f35f09614f1d0e574aa13a81c07e2bd11d1e93e08b79c5dabd3724221c51967f452d48b551a32382a3566bb186c12b067df5ea152ef4945653ccfb6c90fc105d857160741a921bff680bfa7b92b2f4ec45b81a8e3deef3f4dc2077d2ca28fc716b2e9c377917b6931942548454e3687fd9cb74387f5ed17d479e1d4ca19d705e806a495e612a604bb42f57cdcc6d802025c1df335f1bd8825726f32014204a46a47db4a2dc9cadaefb61aa88c89eaf8c9ef7fbab15662c71ea396def6679ac1f193d7b3cd7a862538f8895f779b79863b1a4ce170669659c66c4f62d892e75bb73e0444dfd4cb89c3880f4b95234adfa024ea2b6445fb30f8d419ca20d1979c48e83fc5364789c87b250daab9c2255a1ddd53411e41ef792b493378374c6d3474990b2e3f30f0c592202fc47d93d9b5ba5052f8b632a33628de71891135ea71a9e1d2df60aee0e3540d5fe103c09da0693276e6b55796f26acdefffb005dac9cb128fb30f8e390e3194f2b89d720e2d21b07a896e20881147e15cb3f32f7dd0cf92c9a2ee7769d9aec3b573f9faf7886722b926d825bb9abfb655f7518d5c6a28ca53033f32a95aaafa2139e7e2ae1120737c57c23bc0deba96770f8323d1cd8fd7526a6925dad8f139bf6ae7cf5299937a017071fd3d490890c71b67862239b4e94158c83c6b1d7798987b3a4be3a335489267c83eacc9ce2efd5a7188a76e211b8ecefd906d955eaa2233b681f8f8a97ff2c29b28a74e7fd4655a6456df6c6312a8b8b486a77a47edb4351278b474bee76369339173aa9bf1fd9cafae1ec5dfae77e4480f030d042c3187ee2963d5af896d83b8c5417bee0a31925fefe4f669855f3b4b1992dbdfe6bcc5732e28b7f1d00dbc66f9e30302f9acad7b9f0b1af638c73ea00e1ee4aa08700ed356a550ff43e5393653c6dbc8fb16258263a2c39c2edbf9030d0c81c8d65638a0ee3f3e82f42d53fa8bd6dcb49feed818621fe6c14dbfe5a75915e7d0cb609c02123506398f8a02c28aecebb046ad1205a50d2baae4d40f0871c08360910fb4c72ceb848e2efad2b1bd5811f1824864bfc889a2b8e9fd8d55d2f0d8df6447b6445b4193a84396049016a92b12e6f2e875e9ef6b418cd1e4e8eb5525d7463280d05ca8fd070d8a93ed91d63c1eacab786940292d039be82575c00985def482d4dbab019cb02baeb625e08e403582150b001b71a09cff42388cddcf23a931f393feb4726226dcc67e7122beb5ca1dfdc5d63a2d3fa27163921670c1f50ad73d33600643e03b42e0cd63e1591d4dd91a8b1a1e1294286c16dff783bdcd3a71588a2f62cdf256adc624f3819b5451e0e98198c5fa01accd8fc0cfbd5116683c78bb8aca4d8638a1d4de4107a8ce9f75d08ae982f69d1691d8c6efa2811daf43f6825520bb3e575bc96c1d71c993f02dc21f903fc28de0860f2e493da33eae990bb3b81c1b319787c090cd71a07e858ddaf479131acf5aa8bd6aa42611eedb74dec22be4512b2e93fd946fdd438ca33e02020f05c5822f6eac300d", "65ac52526a6aac", 0, 1579082880, 0, "d4e832811adb075b817033569e6ef1b3ab1c56666378f3977c7801094f0288b7"], + ["a3f49930022232123f07ddccc9e3f2c3cf9bb97af1d474bb428c0258457fe67c197e64faa50300000006536500536553f7179350ff2239485d3aa94f5995493d2b6a0040e07e9e2018d61136a82981c73d1f6e5601000000026a6adbacb76c01e5166a030000000003acac6321b16e0600", "6351635300", 0, 85048373, 0, "fb9939d7ac7e2cd4b073d1d79211e4b1ede102a3ede070cc2e84855fcd7c6ebb"], + ["3c4df75702f5bcec7e3c0af5eb1d55e7170aac0c3eadb2cd2acfca9401443840d6c490441e0100000007516563526551652eb00c6c1c7e318ff4c7b9ff97d451512b86b2668fd55519eb77f443d209657a23ebe39200000000026553ffffffff04e643a500000000000952535151ac6a536500950a9901000000000500525100ac15d09d020000000003ac0065d3b83005000000000451630051000000000200000000000000005ac9610000000000a3d5844bd251c74850d36670a4d704d7f6f9720609117f4a3dac53282fe386a70ca393747c88b3c160b672d80749b92d0534ed735f8b4fd50620758bd78f5afb2268c8b8bd80d9c8bf70bd1d5755e89c9e536a5303d3a48062ceea87d2783fb100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6703c66929f9697e2d5eeab9ab9e51336e01f343e9a17451e031c4e88d664b691671ce55274beddf2e9a4d16a15178e175161f40d63cbc8fba4fb1f0944b3700ae79c771c1e7610d751fb77352b090353e9189ef8066ab96cc713531a3ee2a46ac5f8a1d723886ee4c95fadb174cd22d4b326b82caf3e43b34cd4aadc70b38f02100a4b4078eaaf51b5dfaa6cbc2e98018c250ca10c72ca29e0f70a230b5c0d18020473275fbe4ca2bcb5598a4373d980f49993f917fce74ec36969e91f6fe332470b0439c4efd5447089e816247588c4e861fb1a34e49d2e60bd0024b2e78934947e02550f7d35b6888caffdff9bf07df769ae2c48cae07dc7adb7b639b0ed01924c02098ab7080d7e5dea5a7245a0e73ba65785587ce492e8117076e4118f4cffd91103140dd7e97bf143885e2db6cdfdd9cc0e57a5f99fd8767a9baa62cafe1b23f579031e9e828e053e4012a0cfa17acfef3edf48542d765bdfb11b8ee892350fd6f0e2031038890fe337fc9806ded284a2866b936890fcda6c27a7a28c2492083898c4bc03067450c849085cb67eb232b9755d13bb77634e46e3ab3ed4106bbafc02f538a75b7c6da2479863826af256649760cac7711feb390cc56c760e9d64a59278d76cb180c2d52414945c44b846c1cec48432d86ec6c6cee2f58f3eab88a55f59fc86f1771d30e66d5beef64c3ec368fb09997f572a1e451ba1695ce74452a313015f99100ba144f74fe1d953dbfb4c15c3165c441cd9fd20169121f106ba9218efd649898d81b53da821ac76a41af74072c5d4aa83ad3b29815a4ade35a47cbfa140c9487011ed5a133ab1e2905abb9783bedf98773888ba6270c24513f9de44050bbb4632c614b1d146cf0a6fb96697b1b729618b916a1b6c2a05ff919cb646267e9800866c542f4bccd7876e7cb916c3db7c3f50cd1878a73cf09932b2666261e5b21d899c30f6099d967000425796fdd7a3baf6e0401813be06a22be6e368804d855a03bc048df3181179d59d3f3c9e70ffb1f2d9a60cf2c246fa902da531df63ab7d2d9173ee150c5f1af7044cf05ce7088cbd74c72b791bdf3899b3342edd8f0334600e9b3f46ce4ac84cb443853f7d647bff6a5933f0f4a2be62a835742b88a8bdc405a6a79b600253cab902309c4a81411eb40e227ffa6f969bc24fedd2232b7339a3c5cbae75d1b78a8bc1f0f3de6fe65b08bdcccc135d63f40bb059e2cc6570a89d98b3e1a35174fca15a94ce5a2674573772d1053d8e401ec66bd09fa6afc78beda46cbb377c8fb3bfa1ea7282a81f087ce2b77f9a574d4237f0687f6821b946fe2eb71614a47fa91bec38c943217a8cc3f765a2de114813727180bc97a5b777c618e8ae55cf44daa3aa0b9173136ec48719d5082a5741d5fa641d82f69c816c61a28962d4586261c748a9c740b07463d2d822b71f360ddd1e8f1c6e8fc1fbb4dcffb7e8d7aeaf7741bd172de8d3d0b499162d0f216dc0a64863f784658b228a96c12362bcacab3f2e2935796327b2e50dd2fc6356644c6faed61fc8300a1bc59119e55ad559e5e49a55377ed41fefb38782ca9b16b0269e8b2463a98261d1262123815e83b02cd0f23e469f2544d8320143f3ddac89c96e67003ecbb130cdab2a36707f741c2b24c9d330fcc2f0e4ae8624c77a05ebe7822c20dbdd871e28646b5d9bb40939d11b010538b2c24ec1647bbb9f1cd97c72aaba602efd77b68337bb8a233d75ac783536de43d634505ad7cefaa4fdb68ef209a0988e094f11b03078706d7ddfc252d5db3d8b180c6432632fbb6a461187e8c6cd7d55e0ad22e65e0f3bc6cf1f7830091c595c678caa8ee8ade51bac7310b1c39f59c0c0c31e5b799ca3504ed171e8ce0a4eb858a98950a929882d89919cc5843ef1263ca81964b4552a801881d869133b30cd56cea98973fdd70947deb16c51abbec0d18b4a28809c4aeefa6c17c06fea980dba94f858aefebf2d0ebb8e82747d1de64a0429635394307b42dd96c1905f0c34f809aa048767b0dde494754ee05a0588966cce3e4654229445710134992790d835fb05a3dd202b70ed747a5d5c71ad42858bcb5af772c9271dd2b51fdbaccc27de5e307e41305057ed9cb2eaeac0bd01dbc049d0372c94a5ba695ebb353c4468c94767179117809ff556119c90f6c3a3caf2cbdcc97a795ae023671877d6ccd891d908ea97e6c760bececde1490cf3ed831b7c0ec19015390b5d136f4fc9461e4464b09e284f30b7ecd36085c8bf5375f538712f5831758960eed472a82145587bd3bf720000000000000000c97ee40200000000a4df1bb92312adb6e56c31a5ca26e91a86e5940f88c8fc71526384fcfe1b04dc35855061c25fcb706e70d941421c1740c5ec68048b0c934f769b3289452d1d01ec153dca0992f807ab2e03e018d37298a9690c531d207be763b7c94d5773d1840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014b0375864fc637700b6af8c8eb7a326af36da3eb07e919b1cc5ba82e5df4e45de7c77422821ca7ebec66e9a78a0eabc2f39e872495b84964fd5887db2a9320d1923e4aac867a086f6ea0e0ec7e36e9fbed330142d0b2fb123a3e4f5f86748e30097268e2a30eb1369346310ec5eaeef0537dff70063d9341bd4d11094dad3d7031878dbe6b12cb3d4efba6a8a63977a4dc660b5b73c4aee94fbedbe0df39ded3302204627b0b028560729e467df592ba838fedac53105fcc31d369d8a2dacd7536e0a032cb068361e9f4e04f8e101efd2a6a1d6e25a0b584905c954746a0bc3b52055989f1824628a621e4cc9ba79aa0fd6107a9aeaa987508ebdae533b0b72c7d7440311aff2928eccf5b9bcaf326b86035f84a05746697ccd96916712e7112b0f72ad030349a79736bfe472af0df9992e5b9037ddb5df5ea04b1d2ad9f4826fd12c292302123c6c9fc6c4514c2e9aa6df55ac26bf5e8fa5d784b68b5d6af3947068a16378022df91d6495d8304a1f641696b770cc3a58cb4354aa7c88b22f376421991b6d69030e5c3c56e72073b7bd7bcf02e1651f03626e67cff0b0643e5fda53e8f57c2425e4f7d52f07f43603c780fa088a41aec2a4bf541012f3c42aac759a2b58a998ff32739f1bf7ca4305826fea77ae9516ef71596291ae59db67365d444dba5de08d1e24c3adc0c7b95337c4ecdd2d89bd2e0fa84bff981f5d3d060deb8c020f0c90ab86bc913212e1eb61a5a897b7af90cd7188e303cfc2cc51b7b86f2821b864a992d2d01df6038729c5b2e427bf21aa7e76b6dd7428fe84ae14c553e6e24f38452bb20461a5d0babe67794d9b6a684221338a85b20b52300c074b0a0cbdbcaf40d1cd65f9500fcb42df2ff62fd53f05d07cf05654fae6b6740cb67ae06d9ebe9655bbaf3fe8248af28e95f71743423eee5c833254166ee83514cb86e49524857d5a1605818b200a03073e782bf62f252a74b290efee94762b9aab8ab38c390a4cfd4e1cd56fe5e8c241e306a27e8a32cfc5ed920b608017dae205ea5b4970ab9b7916c1cf98f3fd602917c8f68dee5511bbd5c3db0f5b2a96c07c107f641971c667cea625d2f5dc2a9b6bfc9f8b7211c3d9133980bc230841067eacbde0ce164c4c516a3830dd65b422b38c2449f6dce6c0d51fab583fab406ad6077a59698d1ecb43b6f054cf0f0636eb50228d6975771a23a459e26f1c8889cd0c6c9f2019a9a031abfcee859a2b8fe7eecb31c90d42c17592877e95b7f52649bdc8015aa02e5a6e07e459acd4c01536bfd812ce8089fb92e9acdc1e65b61ae8b4b803673363a90ebdd5897a6decbdd2595f18f1e66be3819db8306dd64d164867b6fc245cc585b0ff20630171736832aa14f1c0f3438deda9e49eb91a0dcfa09a23cc1241e2a6d38cface47a9b7ee13f7d14e26ca54f22f907e112e167d17f0871912f0f1d7401b035b740461ab6282fd95c51a5fceadc62b5aac447aa3193d3a6c70fe150552ad382031f749d899200c2e07c7cbe88eea6f731eeed7479f4ccaf6e8236f7398c96475bdace06772260675e1efecff54351b24e44d1eec0436ddc5754fb731b544542c189cb10c58f091f4a8732c3feb791af5fbd7dad6d185a3297c44a52d7f8e7605410923ee9510cad72ea8675f31e84ea1421b21b39d73c8c52cf7bc67aefce9238fd5b0d9ba9e432fd20a69e4b156afe27d6fad04ee90997eebcef182ce3967de9825731a7bd85c63a3f27e83f894dfa4be0f0f4a9b8db2e6d30e2b9754ce3983f02bd6b7d0deeeefc9131db5ab9466009cc703926c56ce2b9ec50371ddbe0c8671e703a18a26c75279747b0e59f619f39157fa04a650838deb7795ea1ad472eaa14f117e94f394ae73470e765691f05019f7a0c309fe8d636d1097952ab13289730ff35e6dc8797bb6f486817c91db3119106a7db934be035451f5cfbb081a57ec625bad191b178a9c5ac9345e81db59e87debd2ed82b5968ec24f8b3d08a6cc8eaba4609fa2ca366d6827fdac447797029cfa30e0963c79a01aff5f2973da287d1941b3259c7e5b6714527c8e21786f36cd99a531e16dcd17dc0477ec3fbcfddc3fc0f1141999196959fb3d5444424b271e9d8727ad45705d65034a640ad65aedfc3c2c0dc97f74c5173ba188a6c2992a5ce5b350d24918ce99228bd8e422d53bae70410f3a2193c0c6366650fcfbece2a1802ef49e001b77087c506202a623ad3505075f3598e1f8e19ea60ca8d4fdd12de0319e95c57d20c59b80428077d6e695c7f76bb5132a396fefa0b3694a79c2ee8a698771eddee3143f2d569e349c482f175f54d0996fdbe1e18cde1b61f0e79e0f226ab7ea95563e9edf8403cfd2d130ce994d779d70cad27c0dda4ce28b80a26f7a1a32e26e1d69e5b662914e5a94fd508dda71bb54e492f685bf04", "636a53635200", 0, -499873455, 1537743641, "b27b028f89ce8bfceae30111c2766965494d8b96cf369195df28ce64def7c95e"], + ["75639a420312e9b901e4ff27ba83d059559084bf32552be8672e457a07781bed68f5b638080100000003ac6352ffffffff388583892645a1efeb3fc485111d9ad421e7f69017a7fcb552f9749e3236147f000000000100ffffffffab1d6cbc0d87ccd6e981f0f176418ab65d690cc888058ee1570b52e9c4b1c67a0300000008006351ac52ac6300ffffffff03dd8b260100000000056351516a65bcceba0100000000085365ac6351525252762974040000000008ac52516a63530051512d9a8300", "65", 1, 390016172, 0, "2a76800a0ce6dbb360a3919a255f50870482aa5265868e606d8b42e7e5067270"], + ["0b07915204c73a57fe9da0d2be2efa1bcef1810c1a94c82e63a7a73a5c0d35cdfd78a1573903000000046a005253957f67fd0b0c0d6099925c976e15c8c4587301b2b8b134158ee89570738d725b612d522d03000000096aac6563ac526aacacffffffffd2a392f4da6f2118dbf01fd26ed32c08871fdb776b2a46333a7f626fa98e3ecf020000000753656a006500ac6352b6a4c0aa0d66ef659fcc4439949e08e7fffef7d5408eb810b98e7dc468a8435647d000000000056a6a536a00ffffffff04f7692e030000000004535200004dc60d0400000000086aac53ac63656500abae3f030000000007ac5252526a0052cfb2bb010000000001ac9c8a431c00", "63", 2, -843804767, 0, "96cd37aac21408ea03c4103241cf01970af79fc807e8412f23c34ed09f6364aa"], + ["030000807082c40301d03d0f5620ad22c0d571b1ebaad91a9a45ffd9e17d9d8330adc2cef9bbdc2f75010000000165ffffffff029c2fc5010000000008ac6a53ac51516a6a6b29e00300000000096a6a516552ac656a51a172493ea594d43e020000000000000000a328300300000000658fccfcba5e38e2efb45a17bb5ecf58cea3404392a362bdf6dc0db9429df09e96b7e0921cdcbfc3e8a7563c33b4166fb957687279bcf65fe7c180bbdbf59dc120c4273816a6c2acbb03460e220e0e7f28aefa03c10bb26fe22ba88ec8ba604500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d998ba29da849c3c2e576a04905d010a112937c4fc8f7a3113cb97f24e475f2e1685ccf83ffcfd5717749f1d5ae5aa95d156e7dc11582dc17a0e51a374fb743ed2ea48e43c3bbe6eaba1877a153989fffa7069a3b5e5d9569ce4a1cd3995aa56aa31a4faae106e98205b3f8649b321545926840f7fb57882d27c632d453757e1030f771e9cd375d30c3bc395854c9906d18ad4527faead5f59766f68072ff6f3da0323ea73a72475d01544fed4f014c9860d7d3672843dd25db8cee2f48901e5c0d30b04fddfaa085f32630d50044dca60d47f514a2d9187f8f5ebfbf03e067897a7cf84ffd10fb836f573a1fa312a8fd060e092a856c0a68f8b27d32a718301cbbf1d0314dab4154e48cacb84a3a062ba0fa5ff823821edc27d4010b5d137c386fcf4450230347d518a9fea09100d67d0d822dbf2b03c5b9dd670ae9ade7f4dbfbf3f60dc031b51dc330ccc4663b0927fa9cd61d7a77db5f4735f94e0b2bca2ad03af13f2a3032c9036d36e0c69d636764769794a661ae7dc22b7bd737641c4a39f1f35eb62280210a93d321f6299fe9ff4c29f78106a38b9b78ec89e918926d11cc77f285ea4f827c480d600c40a42dead3ab65ebb4e790221e8aea99e243d8b1a750f359cbd3577a9dea4bc3072657ab15888df637b6b6ca491e4765fdd91b803e9e08a363873a47d1e117a97b1c57f22487b2b2f404e9b8d70595d506ae7b4f9bd6256f672bc664e86ccb2afcbea5814c7d3d01fa912945cdce14e1eee9a961e003cb9c4227c59d0c6f0741bb296706d81afc748d73467f737c2ea5d04b1a8289782d143f07070b56c972b5866412b018384d44e6cd1cb9940de396e3897204fa06f189e50a88d07234825e95d9de86d0f4e28fc2a788e3775f7a186ad677ee74fe0c3de1615dc69601986acdb6aebb707afb5ddd9ca00fc35da3aa75fe1330189f3677f73a49d3eeacf2a30474451c87b92dbc2fefa8e35b6bdc071910c75454daf4c2fe693be4c6c878d62ff1ca158abda67e677c8ec87785452e3113cdc20510510286ab5a37afdd7e1dacce93119569f6f7e4947ddd1aa67e7cbef13b8d8aa66a57ef80205aff412137b0d498598e5677834705ab8a3baf1f429d23621ea23d044d881eb872b1757fe83a787d18ca3d6d5945a01eebcd7086fc7a1db4ac354d33d43f1018d0d7c57073c25579a5e779e6292fb05cad3e905f561be78c3c472aad78015fd4b8bb40e823d9cd2f1c4e741a3123aa97cc107f1066c450e47568281b72718976409d5d7c6ef58fda815bbcf2deedaa16100ce1299ac53a920f0e09e9dacfcaf052f9990241ec6926a47be7586336ee38b7badcdbb0187fd773a02896f485dce9b0cc4c04b020d465fc822b08d82cf4c54bf44e197f062634b87b05abc4992acff211362c04d1c0723d82c0310ff2fbd08eb69abfc2d2173658c646644815e879f142f5f81c04321bcd15c8d942cdb1cfb7a3851e31b2105c89e9c187c794ed91af2dc7ebc23fe05564bdce54cc8b5ba4611363985fc576878e356ad77912712ae9b2e8c0074f0c031d3e42de1b8c9e9f73f62160cca1736e96c568535ba484cf378345ed31eaf76fccbb4ab95010b903fcd70db23e8b578ac0dae1419298da7b8872953a22a533a3fc0f37fd2b53f922eaa5be84115c0d4c010fe7edf44af62fd8f9f19b67f30f06bd9f13684eb9a7539c0bd02fa99d3ef62e3d7ff0716208caf08de944002e1a5ed4422cab5eb5ed25874aa1877fc1c1586c4d81f00eaba3598734a94a166c613819ea18ad537281cb69e962c5d1faecca61f32f7b3b1645e2928fa987ef77565183aa11829381e3166b167d975523502c8a86a5032bbc69ab431ac3c166a2d7323af5658969832c0a49e7a544da13d367fdeb57e22942b32cf3f8fcc5c6bed4d93b5d33ea95d2084bcc8800c5bb68858cc83234e5963db37b8d163c4edfe080da2e2c51454fd80e92c85f03106c5bccc661978e99a718149291481c3e65b824b0ad531ded53a0074b3cebf985fc4e3ff161ecd8742fb634731710cfc54e09d9b948688638692656e4d504de60c90c68b67bd6288eab1bd7db1b469a286b024da9e22cd53394795fc3b0311f5d48000dc615f1b8b0e9020a080451b8a478a2a2ab5b7794e0f1bb98484ef9d724fc30d45ec3138e0a496098545488d01178ba5b53166f70fad7af8fde84c720610850518b8b87672f6eeed9df8acd49a6735474aa33774c70ba5e4c288e77dafe6ffd423f5b8f4503febf2a99c92fbc06830a7addc362a2351d92c04379eb7271104000000000000000000000000fdf4f2b093b91d5a548a85749ddd71eb27d416b938294dab8760c1fef76a228d61161e82e681aabb471fdaf26ef06e9997ca204811d0b7e128196f99693a133d1ba51c86904efd68d61a357547d4ea7b7aa681188eb6fbe26ef98674992f3ff30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043ac7e6db40eeb50b9038f4264adeb4c9a5b79bb03a538b33f9d8a7b0be442c634b660da028322606fe18126ac9aa5bf5fff629f1b573ed2387d4b26791783dc921bddc470c7f92ee3f2295fe70ed8edccae8731524f9070fa631adff3401a84230b8df1afdde08a924e5c7657e49ef7fc1a03137bf73b2c27def21b983d4a63030372e44509fd3b3193ed9f1ccbd60d675d506318e7f59ab41d5f36b524a84fca03255ff3564f28b18789c507777c308c02403d178e86a01cde04bef698859ebdc20b01646bbfb147085cedbdc7d4851c5feb1a69080bf82308df5388db2df76abbf45affc808dceb993fb099c646564ab8f7d753f8a80fd0b3d2b4032880bc023b4c03168a2c6599e1eb5c4e47d6d127fbcd69346e64f69fc0a69e40779518aa5ad3f20301bc395748d37968f02410a94730346d205a7b95b683d9a0493b8ff9cb326de0032fcbf98a19979181e25882eb83e543fa7af5789c3f3ae962774d5bd505013bca0227964cbbbe45f6006447489e80cc3fae70a7b720a2c3961d36fa8c64bd8c3ef102089dfc8fa4389d344331f0db6cdd8d9ec0347eaae355c69b83178facc1e293929d215695ada9dbfd4ba35b4606a177ff847c57c2ddc316d48f8356e5afc67d9f520cdd9df5b6b396389cc929888c2924d7e255c5df33b946deadbd4d90ed5a2871ef721b1443cf8e10888d3cb2a33d6875f5dda485d8719a7d2829d803a973d5e9739374fb0f5b9ffa7b9f775ab5e38d25e1eb65508e2fc2baed4a47e7249f69479a2692771dbccb6ef645133c479b2d9a2b0f830a75db3a21670ab48ddd7f4af2cccd4f593c4e7cc181482b54e96ad12b525810fe8c8938829a5fa470d09084c3b165adef6d8368efc72bcb8c78e8630e0a4dd6d3ab27104623458f67074dcdc68aabaa432c1e66ef349a4e5e8896cd9e6cfc015ffd476cffd7c60e079b011c46bbd706fc215451ed7921be07a8ddfc12e289c59a8249e178cd4cc85ac115cd1976dc28dcb78fa1071f36a4630e31e666b1e28b31c3cc45ed94e030dfa9a184bed43a2f09ad50929fe45e00fb0edc721dc4b69949c8696f174bd705af9bdcfb5bd5fea0636a9ca26369c1cb24cf7b0312bbacbcec963dff476ef71e5f7ce762c887cb5321e3d9581caab677692115f662a19728fbefdd15204b86d820a199471a10e3e2fa6cab5b77557ededb8a4ec0a5f0c1859e0909d27bc4ac38d11c60771c863087f85732413c321a350d2f97f80b49bb31ef635aacb3c03561f4ba8cdb6c7c8c6f56a59084ee308300e62ef9d9ae45274a7cc4140ca018cd048d785d60972c84bb462b2b0887871f23f0888b7288f0cd477a3a7acfd0f0d111bc88d10006f198f3a585bfab3abe5506d7b022362dfd3259ebfd59b1b5306d252f895b390030401539bd64c6d1dc060ccaa5a89739ad439cf433f601402bd1f0872e9e220bad517e5188548b3a52f56ed6a9f0c2669a78970fb8fe5f7e861225a2c5f58fca860efc96a1829b03c1ea28671f32efcc1211dd28088219ed4be33bcf6c5a5a724b2a0748c3323e2b5148d7a18d7ca1bd4f026622e6169e1e9e1820379ff7ddd1a071cf680bd7ebb9107b6a4855dd75a1e8092573601f8532d29980ed39570d9c235a53c61fb9f20ccc9f1c516e0b710dc9ce3267347e45d415ad6ce448bf1c21880150f0cb17af0e803f2780456cff926bc71c0ea681147f9f63412ee6eab8104e69a113d0b6e80efc9e6010b27e0107ec98a62a4577d5a46533a5c4c354ac57cc83a1147189f6241f858dbdccfed0a8b7a2d010befe4f2c49f7b5d0685a61161ab41b5550a9c9e1e5e4474bf1a9c5a7ee16e4bef82bad6a3e8819fcc17acd7d325eebc1bda32c518beb10c607fb951484543d97d63cac6e8e0c8cecc064738343cb4dc8cd9d4f0dfa6a25f65a997081beea439d721945eba3aef5dc3642bfe281adfc1af8546cec1704a482740ddfe992a335f07bfb3e44d808a9cc94f1d5fe52fda6d21ab9d0d40bffda7278c681f313f5353144a1302bac5698d8e15201c70b43991760be07e0977a328cdff906d44337cecb5e0fd80dfc7f9ff256eda72b4f139b010707c70fcfca835eb1a0319df57860add175b9a9794842cc84df055aad0e09c855bc63ab80f2cdf1f9c2e67b348fee85e9d267f6bc60c634fc5c3b2bbe09c8d6778cab8df945766ff6d58c2f020444fd514187b014bbf892d3aed16226fcc3f895a47a927e3ba91ec3749107c3cdf5796f51c3b5d1c059f74427968114e4cae7577aa82d9072c3120cea77b257bbda929e76f81b22bf7be790dacf568546a64dfef2c84673f054a3820f3f0a781ff3eceafe784dbca32141f9c2b9d04720b3369b407ddf76d6a0cf614b8ff2e0bc779f1603880ba7a00da6d832b845d083e9c374481443a7f9e7ee3e68539e0e", "520052536353", 0, 1088406930, 1537743641, "31739c6edd5b11b66b7defecbb7ba0a5d85822f8705e18b7e8bcfd769bd3fe3a"], + ["f515592204fb960bef2e0f66e515d3e47e486d52b603e9567042c6aee4cc44c80945379558020000000451516a00f1f27cc399bd14aa62e365a95abdf44051a7b8a87252ccf28b3d814434c9a496eb24329c0300000000447245735130f7394cdab8d1be31ecd384a683772d77839aed9bc704385f238d23679b9b0300000000ffffffffb1da7ca943c7c84b5eb376149ed62457328c91ffdaae3afc25244be5cc1bd53502000000096a526a515152535252a2d9234f035f9c02030000000001ac39b6dc050000000001637f7e810000000000036500520000000001000000000000000020a0d40000000000a91f3ef37c20af62f1f7d7a83334fe46130059a5574f63dd9d1d203d88141e734ae6857c04abb1a18a4616c63f62cf8177ed4df8688fb4e7376ef2cb7705bb6650313008e3480def99107acbd3d9a80046fa20d3d4d23c6c37c753c8c0d9b0e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f854b313c3ef84565671c29e5ab336677cb078214839bf39b11d3cd69964840799934384a7f7b1bf6d1510065043f4953380c4a32cc8dd48cb43e2b6f2a799d37b7346ae81708cbe829d265a8bc75cfe1ab960f5d81d972d4853c84f6cbb57250efbde74af3962b356f46dbc1fa8f72c9c70c1e2a66fa8bf8bc40c57296884030b7c884d2481260bdfbe10cee294ebe441ccbc530c3006888a8f82e3b95393f7022b2d6d5a5786b11a82de8c9f89b927081a0353782732980b0dc3f91d0417469e0b0466ecc7a3312cf30dcc9941afb072c628d88891635cb9319ac8121397fd5bc7b19530a04e67e1caf55d93f1eb39e377c5b82659854b6f28359b768cdb53a016022c0177d840e8ffa3ec87c020144deb0e20cbb3a5c5e4e897da9b00bf471097ce02210ea55034c32e66760b18ea7c5bbed6da6b5bcf3ff329192608a3adb0b6e9ef030d49b32b8a3134077d7963aa4d80a7750a27e7a53bbf5cef0f122393b22ed81b0205c00f21a116c69c6413aa9d51364b0f2fad341a9fca5e4701c00856e34707bb0206d7446200174959ed1381407799156bbb11b36d46061f208dbc92c5fe03e8428ca84152e702f9d9e00ac926999f6621f6a63af6102f3d2010dda80eee12af4c17f5bfc26e4f55cc5e0669b5488d81bff2f1ae990b0bd7132a10f0b0ffe27a354b4b543c3ef943bce17cf27650f25384142857cb438484152fb477190ca935574f0e25e7e1e6ff8f794aa05cfcf07991034b951654c7014b4a56092a0ac1da250a7ed251dbd16f83f2fabefe9864b2dc22808f948592ebc45a601188864e175619fb322227c9f7708489ade8a53764d293ec5bfae29746d90857d5840848314d36129d6ecaf4bd0f2666fc452e1afeea4b09ae41fe2e7ad1792005dbc9dd540acc67e020e3355d3d548278f7c25966b42648f38c2c1ceaebcccfe04f2874f5a06ca98abab13597f7afcbb31e72c9a53f4d32185eaef8c3241d51d34715620605556258a8fb2284e587834b8eb7db20581d721bb78c72988cdadcd331b58a259ae7da54b1f00f5747daa9892d38c0494b2b182e38803ef20abd3951e38999b493b8d75d3b7acd1d3aa406e7abc98f468d7b1186657543b93460fe2a96a7ffaf1e8121d65125b359f9de0146da4ba3a3611a6bb55637690e8dae0a441bb1d6ea500019a77963cb88b074496c96b81b03e0595976cc9f0f8901cfdb4bba0ce0c4035d6307922f175aa479fa81d2a81687dbdd211464bcd3ba0895dc85142c874f0a1e502caa175b4f33a9083f59c6009717366257964ed67d2d2620f71311610b15cbc83ef69d5b7f38512fac23c2f692e693061707123edd58c864d02f6a5a9aac4179900a3154656bece08f27747d20b309f6b236b60f3189a7813a4c685cdd77ea05b08cb26ebf0e6c9be8f39e1386b792e49ce618c1198c0d92ebad4747a7df376243aaf457e95b927794b8af3cb801db959b2c2cf545f86556478166931e7722ffc28a3c6ffdf680846ff00d066e31a1f593cd08d925165ca94b632534323a90102f28947801e610c9298297701e286b56063f4a7ce3518e8f9af2f08bc5a696861dd087580b1d7ed48c1d31729f5b8014ed2bbd945c63e47f1db13269f408d9c3c837469386b937cf10b7954b2bff8cc0299727ab1aa0bff11d44bd27df29289928b8a36ab36d1f88679806ffdb6542afd59d8bd53333870553c354fb01cac98e1095fd0b5af0f6a6e3a9f2fae645c8714682dc7940b285bb52ac9be146adeaa4cae3f0af6653014cd423fff79811df4a4ef55f7d7e167b223ed4cd1402e15f51423bb05be4524b7e6de50688f1fdd0b4de43e8a2a2e08c1795764a9e7ada3e543a16d4c9719747a5748113112bbbc2ba86e2e2b68c9252a0850029b01235ea367434ef6d4bbf7ffcbc3ecbaf4206719fd7d6b245aeb7e38d32d759bc452a76b1c540ea40cfaa02f59e7f502f24b5e4442b7f4f849d9a1ba81b334fee9e588f7fac63eff63a60e4125f5aaa53b670fd87ea1536be0ecc075db2fb17a20f555e99ea0f62f482630836242684494a40d52f3547935e9cc1f8c0b08baf766f74896f758ba4bf7ba51b273f9cdc13303e02f828946890fea96cfdbfe085c73f8f909132f8315a9956d5ea3f8cd83b6b6c642e2d480dce4f359c42c4006bc2854c9318bb90543e6dabdb5c9c02b9013d5f13d265ba98f7f48a2dfc6927b74a5eb83189fc12a409d898cb8b3350bb4551c2acdfb91c4d8cabc770b23ca1d02dceaca51c623f9dd0f1bebb25f68cc658cdd4dceca977b17877a4b7482e0e0c92466098329f6bf0abc5b957395be6717a90d041a884c980cbdbedd5eb348e1f2bbfe2b30c7cedf3b199053b1aa9d11fec83c17c838ec63d0e735bdd1f7a220a87679326ede58062f6493fd32b7b27c39a2fcc5c06", "000063", 3, 1558932383, 1537743641, "3142be52c7c29110c9db7f803178208f206c6b0f9825c06aebd473c9c701bc7e"], + ["030000807082c403025693df0520e4051660a68c72c9aece09973a1eccb3bd39d403db999fbfd1fd3b01000000020000c41d53644c9582baffe09e83e4eedf8c7ea368235599d78f3e6578bdc146240bc3ec5fd80200000006005163525152ffffffff02aeffe702000000000300ac51e4a81b0000000000035253ac0000000000000000036266a404000000000000000000000000a273fddc5f823e668b336abf917b433f033930a91c4fcf0333f5a08db18779060bdf6a50d7d66a50a21826b52b3d4c83f34e3bff4b1004e5186d9e6be8f0047a59999b772f9dd10482223a871dc44e83beec055c42f5cc6dabaf4ee476e4afd1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a232dca8e83e6ef79ad8f0f8bc1b8d1e11cc9df7ae80e98dbcba1163d86db5207b664958225edd6886d2af3d2072a4f5eaa853fd0462aad9de7074cc320b60310b7954af21f396387af28c5bf6a9a0220a6aa9e7a82f14e6b3b5273096b846f1513fcb5009dc81a1acb8a01b74fdeda8e45efc4f601e223370bd777a5285f88022889dd3f7d61aee1a599356ad2d97127623b098b142546b787e87618c17279270313ac9f71f54c156b4bb4f33606bc7df7e4f7d7470baee47cc3c0d2d9106ea4b70b03a638aa73c056e649687f18daaeb713ce80d86f6205a483afc8794f8f7b9f7c1cbb5e262aad2ce45b0868d3ca88461b16ded2811270b508a247fba4123ddac1031805b51f378025e8299065dc6f4f4914679f9ddb33a3b1524e41fc6ef407546203054bf685839718e21b6572b58242944f648e1ddc554c707c72a8c3b7065f49bc0313516cd852c638f9bee7a6d1a7ca3b593f32fa530635952a37bb39c1f839c0560218ad514002019b2f538feff8506cce3f440d559488e2b84b6f68f0816d7539dd03093567cb0d880ed99420dca8c49da9530f4c36958fd8264a2d6ac4bbd129a8f70d4de13a4fdc3c8d2f4e1c7b8d95dc1fb9c4c6e632b3bb39aa371788243d477bceac58efb17dde025cd6df83fed60bfcb9d05e51be002d79f97911bc621fe0378e79bd8e2045bc2340af832df5d0fdfec2493851abb27ba556e0dbc44f48e06b4b78078ed6cf5d8902ad54eb7ea1277791ccf7c4bc6b7fac0f3871b3561de9acd3744563cf6de945d3ffe7cc5e504fbe1e45a6911ab8cfeb559734e1fe17e54f79dcdcabf0251380a0222711e0347e415b44ce8d28a2b963cecfb7d54b7b8426cef3f71755f58978607f5f176311b5b435ab67261e22c16f7355ad44b77ae981e872a3aeecdf71bfe612c95c9b86b2d3ce4231e56fd640f0c74c572494673b4244dc31e42cc27811c730c12fad2db630d4f66a0a908d03973c121a91abe02456b6536bbcbd0519648352452cf2573f8fea5c9ff2e8cc7c827195aa46915076a680cbfb852fcdb08302c1fb3518fe85c7ca35ad6fee364afe821da8fc2f70393db3d0f83e8504fde519ff2c1a216eab0ac04806f34bff0288b8541840f7600a716e7a29f8ce25ae7f9b18467badda7e7f08775a44ebfb73c2beaac0461f043e797bb1203722ccc84e1e685754f3b23dcb184b87f7d2c62f679de929f7472a4a796f32233a8818be1957471d2c0d7a1f74056e33b75d865d58b729e500bc44b521589777e9a70bcce4596a56ec4b771148cb2b54958925b0e89ef42b394e1cae736ef433d43540fb16fc32b02f3acf9fb7fc1d16a8ed11b83d5b15791a73dc8d3f27e34c067ffce8335579cadb7e04e44e6c09c9f908608bb682d8d3b4e07789becab758df8bd715501ac92960b02aba830a0548d40e3e2b4a6895b67bdb8bceb6d528e74b9e7f2caeee7c9ccacf20bdbb1e5f895590dfd25c8fec0030b17cc9ea22cefd3231a785f24fbc78a3c1f77777b9e5415f4644b6e6da4af1114aa9d2ef842eda7c427c13fe3ea735bad6f6a3bd0b1156d40949fa16639aacdfd5d3499e9ee58d59e21d8e0595f0f5080aa69dd5c5d3baaa5d19ec032ed6891ecb677427f49cb6e717ade6a8da66ce417510113fc651bdb8ed652a9bb4fd0d55524fcf88a8a33c6016b1605f8e5c98a8a3e9e3f92d99003cd9e1087b68254586e8e965ba5c626d21a167c34ecb4da681a032ad3b933f758dd3cf99247c7ccdf0429970160bcf69015f3842d8be9f20614dfb43602f11f91a674aa915b30d96cf1546f024f67a507a0ba948783d4805984b631a4b20fcd6710d2a92f14d2160794bb769e94cd473713d64c03ccd8db3b2347c01d29ef8f384c52484830a63781ddc16ed3141df3aeb07c867499d751d6b30b2221940204c990c90a174f8346463c6b132e92ad13e8a565fe3e1340674f66bc30a6ef0aa1b80b3a57a96178277c562f6802203c0e086f7ad98d8e9aa07ab19401729fb26e2e16b9162f6d07cc76221bb3c05d2210fb977ddedf90e284a5bc7275603e256293e8681e660a8bf94dc7202b0a8992225e73123c7b117c4369130cf682fff1fe53d732b1d4e7de5ccb190341f15c829aa774ddffad886e46075f40e0d69e7b49056ba8f5fd48ed6d4997af822e3b3280a2d58a366d6c0e86bcc6a663541c83a195e645243b6c620250fc2d60624cafe5aa5e934e7aa562c9563e76e407a578f764dc5f644c7c6faad952325201763acd25c3fd22b7cc275236922014594b59a00000000000000006216ea04000000008e49ef9dd27759255eba59c5dd6de3bde7c3eea048e54fbf60a9275589a9c4b9079f89776c10c7b985653b5da26bc3a87324180bd3ad0d9eef5a71499f466772e4c5745e12212a350b0708b6eda20265e7d97847b71dca8e275deff32d5e828400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe065f4a97f061d8dbfb5b33285da9fba7cac35556f35d01868e5593de1941320f7165fe016c226986d6d2ae0ad1c7651dfdcd67f5c7a1829741ef83fde9c25e7ca955a1992e7dea57c1eca6bac63cd69c5e7be830f38ba551e828c48108ee3f0ebd1249439b0b7962c5a0e2194ae8d4a4ae7be89984040e33e42091f854f3a402240168568de0b2671c1eec6aa70c821f9d841e65dc1a999f894a8d34bb19603d030eabed1733a02a8d83e2f5bb05b37c093cf7d96a34ebe8119d23193a70d21f1d0a0351fcc4cebd577706b40e3d8f188179e1a40d154a15aeb77005ff9ee2d626084ed5aa98eba5168d5ad56f6977cc0be573b6c6896254f2391c0e22524a18e8cc032621f1bd87da0e5e3da62ef80acc2397ac1254eeae6f52c4b6b9cc8b4633c5f9030ea5b0f904e22a58be51a156c6ef59304a013173b4c9ded07d1ac7d26405cd8c032131221a3c15487bd76d6d347d82d977448d2dd4be2b3fb9150f1007a7fcd0e9021265beeadfabdbfa1dc0477f9e3f3a4de7b618fc0a9817ac4e99b0453dedce2c0303faa48830d82570e6b13fc291b534481761d69bdb035b4d50c7e2734211bdd72d8cd7014a81055308dd17e391fbd102cc1012f7dff6c6d395fc230570b4d4dbaedbe9810b2aacc93579daca029a9ed39301e6574220a1ea60aae647d25f9d34aadf719446d1df7c5ef282ef5ba15ab84cf23deb556bacaf9a2ea072617a027926ad494673998a5299bd584f327c29443901785cb43653eb822bc7e202e6c5bdc2b9f0bd8b33fb84e2c166cf4a3ec8fd85f0784a343178e1f72234a9490b1039a762eb706635e1869761524e6ebe6d6bbacecad2cefdc83703caecabef8b462593cd0d016dc452012cf7de643e5fb659a52fac541bb075bee3d97650d7fda75d112961d4fa80cdee7d6b5ab73aaa19721f44bb3e885deafcd2361c22dbf56fdd5f413650675aa32ecc6052b4f24cd0a6848938108c3508040345375049d01d93e76aa32b6ec6c8a65eaed7d9ce9d95d42998c3f0c8afe1ec550a067aa11b443a290e052ad157e4a60289a8f804d212a0d3916dcf2c2e08b323192b41c85ee48bd88b20e6ad01bd7a5e8ebddafa9d9a66563285c1433385c9b6cd924d8be632d1f00f079921778a798b34698ead6bdd4b4f67c368129f5dbd64543d6a1c8096b3e26de041d934a4e27310b1893f518d2bb5d40b80a06db88d0210f64f5c5f3a666d67fea40c798c71418c14cd9a80567815b8160c4a5a47fc3bb2ff41da9ccda38b9b9245548930c31db59035d94f12dd61e62e83bf6cd09b61550379273cf58d2f0ca965dd3b62c5a6b9d153ed3ee560d9780aaa7c6fb3f2f3bdacf376a58019ef7f150160cb3a467f20e6db6ea0abf4974209f9bfc4ba62295a23b0718e0561ceadf2e797be2072e2758d68cf6f2e9cd704c13e08ee5731b0fa90a4b9183a25154e2c43b09f0be3b1fa48190f891d4778ee540a2c02d635b897fac6d39631bd29ac8c48a6e113e0dd518567aefe8c2d13025faf287a357d187e60a24e6f93912d6fd72da869989a38f5df8e510107bc6adfc92aaa0f31231c0a3433849849ba526f0005b8571a9667a087df394425977cc8b5bcea379a9e7a4e70f075b74116426e2bd60c824015c0d99953874114a484c3369eb85e320fe6d9f81ceb4b995abd60d154e92e3a40693c9d9b06e814f416fff1bfc952cdbc7d0e99537e1636f31aea6b97cb53b89af7d5c77fd411836a1dffbeb5a149fa45abbe768f7f5abcf6f7aebe975b576e8ac18a2a3586a8d41b4bb8820286c9bc1f643fdd31da84246d440b0820d2d252173bd674cbb3a26626117ef27559002a22620bde9c58cabd6533e45dc9802d0809c403b6ae9dc8ddfb3a5ec447fb3e6714d949cec9bea86058e0b3e44b706b474b956f592ac8cc407a3a7a7c7a911e82694fce7f60d2aa153fa3bfb134c8d5b3929dc78958e9ec0a2706b70f8fd15036862e984f275bb30fd77fcd45f953b36932b8de5e3480f87ddb7cf4aedc0633d6be39dc576a5cab09f0a3db2199c0b9d6d9026a8df0b243953bbb183479ae3f8f0df32c3973b16a0b9497f6daa4b090be6b792f4c1c6ee491b07bcae3d036803a23796f7b0af3541544c26847902529c09a4dfcfec029682b682a37e46d393fb00f75847902d75effb8b4548020af7c5ba62cf668de10047301aef727af63c392bdc328bb132ca74db0537eb3f2c68a645b3bdd043c697f3a87e38a90301204928cd18aed7ca586e19ac8239a21e351e060b6adc26c72e0e0d4f38aeced9304000000000000000000000000ea1440970666760d24c01282c380e5e4339c2c2df87590d56cfbdbd68e6ba76aad24962715c9045675337eb8c6c8c93e70f8591462d1d957ddb8d504792a16514eb5c459010a2cbbe6b6bb3ea8c189515ce8a36d4dd3a97e4526519b3effb82c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c38aaebf541cd20d6ab1f3c8ea55695ef65b779616cffd8110e4ec65992d32e1a3456ff106cafd376deb5d95daab5388577b6fd36b7ba3809bd17ec59d847f9c8bb9d06b09f7cc25b20ee2c7cb7407374778315a0d3243d4a459113daa77927c0c757e4def05711e73f7824c19ddee24ce17c3aad99a9f622d51564bfd37c96c0309b96b5acbbf0dc313977b1378e395b9c442f5c21c1a4a06270d359a2c127046030960a98fbc4f0c192e4a5dd1b92b1737801eeeb6d5d3fec160c512f23f1c025f0b02144c9e29be0f750a134c9f7c7c3ef9777d0ec9e217de280dcf7eb8fdedf92c0a3c32f90e38d84725c96010d86542f80940d2406e2be47ffaa821abd5960fcf020e76a51212d8cda35482104685fc6cf495d0b3d54edc121e9a0c0b427b135f52032594a6125e62bb19d32fa8f5875327c59e3262d3acaa586f1da3964e5bbfae0f03014bb8f047df8a9b667149e8f6d28c1d0f4c47b8c76d28c6dc113ab9e358e6a60227b92c4f5d83d086e8da6a2dc1ae9f326ec5f397af5f1e506e737386b5b94d9d031614249d3510e63bdb93e33e887815dcea886823937be7e7220f4ab553e88d8bf8c48e74e696f69540523a89f4f72cd6070abb4fe65225356caf3d516c7318735ac4dcbd0de5b7b7bab8dc0084d7e467b95c642ba392d5128848207ae679485f051a8d3fa71e3af34806a89cf91477760593f533236ee10124f5669d929a4f601d248b8ff136cc1a852fa406bf44c12e0808be922aba4b85b436d0400499c9670588ad3462dd793ecfd0ea8c9049bb5c85a10a6740343a8f06cd810f1ff193a7c4c8b3df79cab38625797a2a253d506be0c7eb9b9c91c58de4983cf97f2217ffc46fae830602176af01907448d4e4ea82a72cb004e20f656cb735dc9c0d7ca9b8feefcfb16c5e3464f18717678ee7d645c24845bbc7b9a907afdbd21203237e30efb5d40620d873b9f923df24ee927d3d83d53eac163d2fdb0f930c1452e6ac3b18319878a9e4787964791257175f629ff315a906050b22914c9a727a7a5788cc87b49fca75637411cd70fdc471f90188717f7544fb9e5f753e975ca835d69be97d8b03a18a0ca51482f02afa64a0a4ef83a725555f70d1ef9f9871ac29be52d545381fdacebbb7bc9846cdd42734208173b4f5fde48f9806a8772712cc50b2f27d08b05abbe2584e870b2fc0017cd1cd813d7dacff797fb82895a434102eeb5ef3813d527b9392a021c244f7ac92544923611345598d20028dd65a45386273f5c0c798f92f52df72db7714314213b415044ae948f223f2b60da62a19dec3a3f9c64e3888e646348d5b932ff5e61f509013cc8108b36a6b30f4e578ae60e3a994b2084707f9a6564544258730cdcc047615aa04618abb8379ce4d7a9ded902ddd5f495207d818bfcc4f7eb71ff61b4631b6cdec957b2d884851b2e8550ee909b56ed1f74547a4432c56ac6d62a6e3c40a7043debda85d428c4935182fe30b876e63d8b0416cd6dee14591e8b51f47a608084f959622fcb53185332e86415574c18f85a79768f6becdb9665e9d8781743d607c6e4c35baf7adcdf76dce54f65b19bfdb092eacffa94cd7b760c8e3e18a2996db243647b0ccab7b27fb2edc062b8522404b0d40b54c5671b0d699b49d77284fa639b2d02341e7edbf255fc234b22bfb031983ca3abb32620c74d6dec97c247af789a88f44ec663c36a3760b7774a53eeb9499ee491095fc730143e7552b5f2e168815d4a8681fd4bfbefd718bda83d2ebfa25ad9a408c51e16841e50a04c333c2ed2c5b35af13d5a008d5bc104a5d9918549ad0a55459cb90d836d4cbdd665c2de7db43d6c8864da6764943803af9b23075ea6384229f187b8e9d6bdde66ca73b5d6d65d818b5d553ca857415acf4fc76e8728eea09da3c8a8677de237498d230e2cfa1ca03c462ccbc42539ca92be5b2618a44501ebc50349012ce9dd26ca5af2357d7c9f92da9f9e5d6ea815eb68f135a3484cf1a6a54a9b05db48eab08bcf610a4a40ab9c00f784d3a7d849b2f4dc6538824671d8ec67d464c88922fcf49ccc8ec6cb7b06af25d5dece6e02c9065cdbff7a39349d312c9192f0eadb6a8b93f2214f33d29f193e73e74a811b41002f0c9565dc8703bfd5b9f1a9ac27dbf2122920df30d6cea0e97ac3f6587dbece59306ab61fd868bc8af71587acc5461bc37bcd05b4698dfbe46d93dc964cc8bdba571a416808997c6a0fb55acece45142555858b415ca13fe35831b76976a0b17669a6e23b8dae175fe01c705c9b8ea9ca54a27673140c47c93d8d26f0d2fbe638d123df8e2007d6e6d41ca4cd550ec33c7669f8620c13b6018df36075629da7054b3047d80e3d5911c8e3ae7374e59b538d72881debca7f20184cb078eb8c6116b53047d9f52f3ad2ac0fda23b815fe0c", "6351006a536a6a6a52", 0, -1988452841, 0, "40d84eb7f29f084cd3c8abfc1c4fe2e3e019ea0244510d203e5a87117e864e7e"], + ["030000807082c403027e0d13da5cb6c012aa5c5073de53cea35a2ac24237e985a23be1a6d32ce1af0d0200000000ffffffffe7658d959e7818a6126b0e45c27abeed23428162a584c49b54ed9f9877bd46d5030000000152ea591a1103d4920a0200000000066a635251526397f7c90400000000060052000063ac511a260500000000050051636565000000000000000000", "63516a63510053ac65", 1, 169255014, 1537743641, "94f73cbdfbacb27eb9e52c5795a42004711b543fe966bb0da298b6e02e37b6dd"], + ["030000807082c4030207492ed69c2c0d73bea521f51754678912e1d79327e4fc98b1226af5788b57c902000000096a6a5253526a526365ffffffffbc02fcf56cb7a36a9cdeb82c4e8e121a9f1f58af7de4c8fef418daf855fff7050100000005ac635100512b7a1b27029c64920000000000046a515251ca237b010000000003006500cc16684200000000010000000000000000fb55100300000000db90d3e9b05e2343efbb70b41a94b58cb52add27d94d198309830d1c7670977e3839ac736328db242fb052deed65831c8773c7fc4d4840b4c5abe03acb26ddfc0a071e151458613a7eded35d8dcf57e7482aa9b38b0dd30d7e91b2a7800309f2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a8530e940e7a5ee48208999291fc4759de86b206c29f5d6bca1a584dd09f6e26ae91e06ca7bbdeec69ca2cda03c5d950478f47ba2bc59f12a9ef9a2170f935f36dfe4498c3a354917642e1bc4e0312c09a7e2da8e848b48b5f9e6c70c7b99d58f8e183b7928e0c4cbad6abf3b9643fc12cb2b6c7458f7d57fc1549e51a901f80315ca6160b066cd52ff64aa3592cf9b19c9e210ae311723424c47f4d9ac3d4437021817a55f6e7eb5a474297fc730d5ea748aa7b0659ee745d75969eb2663f994080b02b99c837acbb64ec585ab22ab1e8dff6b2fa81bb5e6049276024f6b261455307765f022f070137f9063d64bcff18427897e6ce680cbbec33de646c6722a7f5a0304665774a1606955a1063ba3784f86b1c1b49c61dfa5fe075009a56cc12482800222b3d2b2c22ee10ed9caabe2f81b9bf5620fd2f76c18fcffc6afd3fcdafa7078032af18676adb3d3326f413fc5ea4ba9125b729dcf90ddedb128fe2333abbb6f0a021327225be2be470cb697a9057e888858913f6b5d97d630cd054b936f01d2a3e00313786fc5ea45e46ac8878857dea3b836b5463d99f2dd294dd8a27b84434cb71862f718a57bf38339ffb74cfbe79781a1f11dc278d71f459ad09ab8f4589672f8f684180a9bef6610a63254fe0516b85b0071071f296ee2375cc9108c9d2c337c07ca5f82c3cb75ec1e3418e3bd6a3bf204c2f32a693eb820f19dbe325fedbe961278bef67f1cf4ffa0ec4e20b9e7cc20cb6b716bd37db3d7d312c21bb1da975af6738d225b8f32e28d62e19e72473d99bde8f3e3757e32cff736d8f7b9aeede25e10145f6a53c2ad5775789f3500e39e09f420e056e6de743d9073321cea8d18f70891edb5061ad4c3a33acc4f235ff5463a311cb9a04ec3c59e5651d44368a161f059abf9b5e4a8a0be83f22fe6bd21b01d81290f1b20834bf04371579f3ed772b2f2db2d6ba52b328ea8bfd32146f1948af1df830424ca6073efbe18c4c3a113ad88451d6e0c160978e2d694d440b77ca27fc34959f74106f06b998288dd5af64fe92c0cb3f79786c8f91d0baf03fd5cf60bd6844fd8917ae74ec847bcbb078b5ab1f032609d7e178b1e6e297370c58c90ba308e1aa3027ae03b4ccaa5ca5df4d3837b1a588fbc2db32b0aa56bd288e82e0af994fe1ee8f6d4e522aa82375d8d7f1ead1b9c9583bd688ecf04fe77c8b8cee3bd250e5473650e4f5b93fab04ae4937e49bac61d7b0aaac261fcae8296dbe3ad8fc74b6910bcda1ab61fd3517645e014c0d97bccbfb274aff20fb5a8ea540557c207b9d233ab5cab2e9309ad71d4180885e42b82afe6d7071e9f4b3c813edf27d4d3006d0d238e0953c3807d6b6884d5ba77270866cda6661e4671facaf922bd9e9a9a338c5435fbdb4b7907c2e9229f96f678060fefa4d23ed7b1290744701f35cb57642875b68ca036d04c495b9cb7fcd8a15b9cbdb3a2afbe034c1c6263b8edd345b5b78d6f1947e3d0345d8d9dbbd8aad95041511e14e2e8f95965147c9b8c306f2e920b4b3e62b5be99194f439a072e5a61da4a50ab3b39b1371ce8eb9f29299c338ed1442e5cca401a4cbae64fdaaebac5d687b7234cc8d5f15d071165c0cbf4657e9d957a7c6d509e1496c3ba42ee2330f9e7dc3450b87e541ac182b0be6e498cfa88a688c0bff270b525133ea858dac6cbbffbcd0ecf7e99a26c0778a21b5ea116cf7df9b7ead42f58d0ebadeadd75cee96b22978914fd587388decaab5620078bd9f032a060afe7ab1c7252d8acfce6cdf0d9df7336be1f92a660786e537df17925a2452ab9522904c517791f377ed1a5352e86e1580cb1ed877d935888943243a7bd68e49385eb9158dec322ff560272f0f0d573bb7cc4f5d8b23cb8c4aa2a2fc15c741aa2f5b2d301727884f1306c3f916644d53bf19031033462c21e098856153f90189d085a95cf9ef7b5ddac52f5ea69137e5c00b48eb98cd2dbfc6524ba6e16e2af14ba0d0af2fb23bd8182919c19296d53b42498aa39c6e60f263466e3100743cc975cff3fc33b6bea19eb106d92b46afe5f9580af427a18504de78122555c39fde49beba58fc2b12b05587a2fcd6ac06b5028d0227d0dab227fd1ce4efc007859d1bfef38ffc47aecca8ddaa35916b0722429b642ba75f8cd993185266ec413a54c7b3aecbb7a6a68ae13d21ecdbd4f6557b7d9548fbd42f05c72cf53e161643fac6d8318c7c8432f3f28e6cef9a1ee9c4c37bf4ff8e65c597dabcb6dcf5d2691363bf85ccb9dd18ef181b7c6675a307475f9b4060c7f91a530b815dffaff2f1b88bd3f00aacac013466eece8860de48d8b611447944d4d9eab0b4ee7b2ad3ea0147425489a947083d8b3712daad4e02b4176d90d137b96511d08f2ebfc0a46ec4fe72273ec49d7ae2169968374634e6048fde297c307", "ac006a6553", 0, -473169853, 1537743641, "0aaaf4c4326b705e78936a2100cc9eb0a4a2e0bdb87313224f1144adb33d165a"], + ["030000807082c403013c480d691b79f265991b30ed3154c72163023d7bb68f24d60af0811987b103210100000006520052526aac414093d701f184f00500000000002a4787d6000000000318b6c3050000000000000000000000003c645d29b2d5fc4ef4d62a2c74eb8854a40cb345569a43c1e957b579adb53a08cd547f94be0a9e29ed3e4ea9ee686b4742ac1990b1e685699c09b9e256a6811e0608d0c31961d4d69ee3adc9f465c573bcd716dce359b07a3bfb92aa7262ab7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002723248e5a6cd2f8576e2a336f2409fba20b858a3a976f204014bf6854bc1b2dfdcd62194867ee2af08c7c2d317803998c986878846bfbdd383584e224fd2961e37de7ae13fab0f1312717b0a6256224a69cc00b067911f6150c5e46c5d701b770525e5917f462af0f906e4db9a721be9ffc76278b3fb238deeaa97db86fa743030123e8f1b7ec3a17afd25686af3009785ea4edcb78587490756d38fc2fbe957f032752f03dcd306c0302c33925e9e1ff084cdbdfeebc5de3674c0c8b2c3857e7f90a0074a9c0b568a34321d10003f71e7b94df5874061d2eb751dae101a65527054975a06add6bee0e3dfe6db840a631fd52a61610f71cdde842436515643918439c02293753f2b24478c5d9b53f898cf7e6c06a0c47c2409dea8d73a9d14f8591543a0214235ccc9e3cda94dc702b3774cbff624914a9b087882fd8bae104a9a62291500222be6257be87457ed58cc7be7ed2cad43fdd7edb2df006bfa251dcd1cb0e9f580220122229ec67d283f6676b55392af9306a516b425a4cc037fc9e2b85fde2b34d030a246a9605b374c55a0c249bc0522d75f5c19afa25c673b742e5798c988e2bb37485ecc583a8c489a02607e5737374677662fa9185a46987910f3e0838f8beb2a002062630d537b1052420e0fcf808af910b81c2ca90b725b6c8c293346a1f1004717557ab796272ff01f7bd1d3ee99722c0dd12ca7b4c66925144a9e7ba3b301304aa9bee2ae17a013d47a8a8a85f3441ff2d360c3795495013e98894964a2eec0331a86e999fc752c5e8ec35fee7aa84595302848a8cf5e2fd4fd0173609f77b0265752d39f3c05f51e8cca41ca968ace5ec0c7f30293f2157b5f556ff3f720965c2b47507846a0c8baff4579d14eefb78e3913fe2e6e1d779fe9cd105ce7de526511b804f19500a92efcd6b319df1f27803aa91a66acfa944d9ada134ac5ef50751409c4a780e94b188f5c7e321fca11cdc16bde8930a614952b2921c46bc2aa56c0a37150a7b1b10d280d8f117dd3fb55a24a2e5c52429e77e781159f9a83268693d46b2ae121e9c624a4185d1c9756f2dcd610ed7fae0ab1fbe3e242926416bfe949731a80dfcaf1866132f5c5188aaf989fcd38c9e0348fc675308262d77d8342c81f62c65a083142b1bf4114642728dccfcefada9a06d4074b8d768eeea5cd86f92af5d211c54c7d1af23af3de99bfcfc518599e58a483b2d4bbb614ca0ccc8c8ef924edecd0b0cd8b8c13e45a3c4efab1273d65a5528e94958d05a5e620aaac483fb55e4a5fcd0d81c1e7eb852c23c8a1491710bf3c2e85633c87bcafaac1e978a9cb19dd7aba321e7411a1b78a680904b7413a87a6d7cf4f7c3b11e9dae808517d3bccaf901523598b7f473d4da641ddeec4147f88768f0a050d907f96a36c49f2032443cf47f62c0115044b47cac34f1d4ed901a61466a5c3cf7c7adfac80804a4ba9fe8bca4e508cf5e7070a64c6734b4eb7e451ab4045e8287463cb8d93b01471e5792dfd7a2ae050dee423b54e4dba27df2c93c1b7e8c00bcf3880b528241cd28472e00c10361eabf45baf7642183bd61709e7d60081d4f0625acc9323cc0558f52de9d8f3c224ea15de9c2b01516e49fff9896bce377d0e881915db0aa8e0fc6de8074865b02a686577a8e86d71a8e857944378931f2d7079c7e13a05ccba4fc906bf215d2e9f61e2a7991ae728598c5c36f3be8c78aeb11b59798562e35d0372ad578aa64aed4ff2411e047df05322813355c0e3f26bcef01c66dab1df009917722e8c291adb244d55b0f636160e85c5ece6ca286262bb2a887f7f84147c71f507234d529cd86fcea01cc250f7677be3b0c9998985e65df96f87c880ee1d88ddee3dca9fd684e26c0ed56a8cf4264d0e0a3e98d60eceb6dd0ae7646bcdcdfc5662ad65f7dcff229a438da7ab66f08bd38470442844e535395303bff3a2602d76f6785b9b57aa28bbd4020fd12b83bb5787811e3c6d46dbdb66ef4e934386ba204a61d2c2aeaecd066d19d20eca761e5913314761981bf5ec415ae8f1df66da18859fd8942c37e6dd37cd0afec03b3e60f941c61ef0f0ff3bb2ae8391aee1e679c04457b4ba24ca38e20242c71937c695828155b38ee4028564f053776e752f8d8fb2444356e7cf89258d63aa113c24a5cc529454628f2e0f0675ba899f16c62129c1b0316790e01f80d584512d2ae41fc962b03049b58af31ce8f3c3d6bd7bae2b54eccc4032895a40f4598f4e53adb76052696ddf494275a207a0591c2a0400659eba90b4ff08af4e8c700000000000000002c5b850000000000293b561e239c9cf56f8035cd66c6babb057fefebb10c6ab48c379ec329fc5dd273631f7e611e874e66208e3b3f60c276e9a2cad1e11e00946c8f40d931eac0a53f65335c55ce311d243ff172e7c8e67ad8820cf677afc55dd6979304dc865d2c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8f657ca7bdfebf8a7032dae85a15fc9e91052e39542d1d2bf4eedf56ea4893e46b7c6693b25732e2127668abc922c5c040069427bad86c388c73ac317d3f0282edcdd9ae670f642a0b7fb62488e9fe4fee6d74422b84045410d732b288a4da846ecbafd22f684de83982590888053130dc1541b733622a6d1af402c0b1a0d4030b3568fc2ecc8280d4021337d30b0522586670bbe41c511a941ed658f9e2100d032d684d78ed1b6ceaa07c1844a82f7c05af44def8b477974b6370f175aba3978b0b0924ceace270d3cd58ed886dcf2756b95e29ca6c3e86ace32437156e7b5a4203631d1bb9b360e6a7d9484d534df64fadeecc47c35dd509b34f5fadb9339b6c780228b340aa8d080363f886c8b2f8a35ed147dec1064f813174074da563c8cd341b022d92d201bfb0c72f2287e434d47c2ab0660ea4b0f8b88ec628ebe61c88c3365c03094d5be34c8287b2a1a06967ddd1da3a2b07f32aa8eba03436f078ae90833b9b031ab3dea0d55b58d6801b7d1f82f98dfc1b58fc485dc1c976207723c7911446380221bdf512bc49f1d89c8382035ef6e294882856c8d0481235627643e0b2e5196a36fa324c1cd2bd04b3da79d6296fa1147ab9df96b63f7c27bdf8b5e76b5c7ccf4313d6c91262ec7bb8457a3474dc3291e2d729a8a61724b2e1dd431ee8e24dfe3391d57b847467e8ec0115312b9d82bfd2f00385d8f6655b1dfdec33a799dd3064a4da578f5cce001f1b747a0f08af98e746a0d4631bc10cd623507dd495a073c36d308e43e260545960d39ba4962e380e8a3ffd8230cb72b362deb2f364d60e6b616d20c015c9d1922a17b407bb18f4571e2aa3cfc7fe6602b602c699cb7792fc223ea236d8dc71d335ac1c65b6ff45a570c644f7a0ba3ffdc4798fd6f05900d3ae0c7c8c2855d8d5457a1adf1eab819d8a93f6b155efa5438e61dd99547163aa8d112409938f185d4cfbd53be4b5d3fb2309005037cb339fc61f26d7aef3512fcd86eb0ccead1ea2e5f533dcf3e65bb262ccf89603cee4ba33ae868cd6e7dcd99e302334a3c9e4a42d677f7183d63014fab1733b59b5ef4e569290b18ad54ae26c0db941863f2aaba0b13a0be38f7e31a5e01a51e3d804acf6846e3d1e04c7ead9e8a939078e747799b30d2881411cf268547510c474fcc5bb6c2400a70225c9273e452648d2cc72bbbd12a94589ecabbfe242f53679f818395db258746b181295690d49b8e8b831638bdda2f0d6fc4d09274883975d6cc2922c44842c7609ad117cbbe0a37d75829d23b0dbe700d3c5707f1de5f64973291c197ebe8623ca0b16f884228f4b6b131870822d11ad22570e30cb5d573a186de77f9c8eb5c350b5ef9b880206234091e2eaa3c9678a0f1051d55db0472342ac9e3500f07d80b0a536542329359399b346570a0c1ac154874dbfe4bdaaf5f82ddb0a7e06c83ffb633ef5fe7ed77926410b97ee697670db797d2b65a5b4c264bf11429ebf6714d22a923610e62c85913bd22e5842186bda65f2c6b63468af84644f32935ecf45600c295c2a8e81c3eadb5b2aadda8cb0a56af0085f8dd782a622d8c066d275964f30bb207726d517ec36abb1206865f123c6870b01fdb18f3de9dcb0329eebc8ac692f2fcbc1951f124a76fb84ed9b2cca7ff2eb776eae0ae993a2df5d6178a10142d310329070ca725670311ce5fc603f245d477962bdd89d2c3e573e98322fe4c981565d8e4acf273fab459d771c6c11d9f651dbceb12ede3dfba3a901df843763b685bf93c1b3f0f1a489cc02386af50659395dbf5b8ca19543568898b49e1f9500807b4d4c3fe1d5dd29c5df7d9fe27dd90cdf1dd75dc7e41bd494e9bec429475b8641cf8e9c470422ccbca4bb309b962563123b2ff34b8c44e1bd0372317f1a1c36ca72d72ad2396c788285a1c3ab3d8ed454d5af65d0b5d5fccf47b5e705ccdbf1efa5a5b821c69384fff0846623c394266256c69edff8f18844e95887be4431a5c45c17c029f6fa0856eda8090449756f25a26a28d7a3a0b54aaaff9c2d23669600ce3df96ebc8e8baf797d55d9844b71857ec7a622e296734726220abc61b3584ffd6595a865afaf3b04962c499a88c2f9956047a59faf810ee4ad7d10842f48ac147aa349c7234d9f90eb3893ec61c39c1aaf90a4cc0a81409004eb6283aba1bf1c25a0ce604beceee9180db20343d49d092465bf65023521a5d3deed3f811340c0e10bc74918b2d18b979e9447becf914f9c5aa78ea7a56c2e726f5965c2372f577e9255024128b543f285d2487e0000000000000000a0102702000000003594550a6aa31ca0781dacaa05f1c8a4b6e85160a53d6df1b883650ad88f889e2f8aa6db46bc8a0020db7e92261c542d4c14ed7d9eb055c58a287c58306e7778a86051371676d7a72d7b7174686a5a3066504ce64f959b008e8c282c8213b9c200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b35b37b30cce8ebf72f90dea9b3164b6196c458cd14feb70ec14a195f83ffddb9965bfbdc4647b60d3805f1d97be70eefe9edc5619824cd81e80d4803826b8e3553bd63b21f8a5fa06e66151c5106a7c1dab0cba57b4ede802176bbd3d1efef0cdc69835ad68e1f5e116315a09a3e9b646efa5c3a6beb697a4e03a6bf807a6e6022f4d701088f6fde382a77f9c0ef2b2f7deed5e41d1b2b6ea2cf5603e9851ee8402190540313ce4a57767dab896ad444ba1cd46531622d93416e0042572b0c7d8be0b079923359fb616389b589983c7f1ddbdbebce361f4516e76c3a63f463eea6da33cc02318731b07ec12eed077db1c908ea0c4c7505c428cfbc5c7389fd17dd97d032b09551acabc2b7f98f084d191135a069e0dd5a491d1a5edf6822d9eabf7191f032d546d31994ea70f1f6c21ccd485c0f9da191d3561b2553de1da26f2539f08a9022d91ac5416bd73bc5f129dd9aa43148a8fc9d3868250d0339e8a335186d4f17f0205969501a7a1058ea2c67ad849f56c74a7c9229985eccf39e0adf35310ea23540313373ca936eb9b753c0f2e8abefe5c0686d796a388a3daa123573d88517838771e52184b3f1c922e92d161e87fa1f20c3937b47e425d628e55ea9c0d429b51ea4b925fffb33e2b9c55c9e760565ae118c36acd8723ad1d5ef3643313bc0c84252f21833bbebb654225c93dd12b56c66e89a317c2c10a90c2f0d5352eb25432d3e2245604846944ffa83df417ccd4a1d5c51028b1768acf7b198594e5e06545860977715d8b0b4605d9fa68ec0c691218f61f1c236b5be35bbf61d766ee7775654f9de89a18228353c00042e6268ae796df05cb167fdd996eb4533050e3d091436e72264d0ef19867ee06931cd3e3b1bb79efc92a8ec757670723ad232de3b2ecf0ba0128e3eeef08ef5f9c4f8125907fdf77cc1527f8413248a939fa39e82ec37783d61d9feae02b2f185f7e4d4974185e777f2826a8ca29102bc6fd6c1cd71719748f9b75d198b73051c2047f0778d5c818e8b4e3f0099f205a6af071f698e75aef9a085caeba80283d8a62705068a4dba8f70985b7cd495665057076858ac1c4a38ffa792dc36e506bbaf741bf8f19857bccc3e0f7112f0abc476f32585aad1416c834a98b24a45056c52a756fa4aabec85bacd38971b2b5354db05c41359c1bd58461ecb8e6f4e4a2e86d2d22e30aa54ec5549e3ceab879ae526ea42b888bc68627924ae0fd75f26d1ae6361fa8d0a2dcecdb1731cc699d27e0e1e6c8c7b9eaa932dd10bc20aa942b0541cf9b60a6f54f3c490e21196779aa9b9e5f8037d8bc8f2a650f644c7cff28da45b7432113dcf7a5d997b637e0c8b5c7f8b0cd6729e5b7c967835bc70064f65c55a27a384a6aab76612ab6c8c89be7594f429557e10f4492c7d26804dac870fe59837d32ecfaa32a814f34bdaae50e0d344a90d8dee87587ccc60a7019fc579f46024afeb3c29ff4c32db70d73d3044e0c0f24a78369b587a46b8d6cdde0af4efd98843fc0dc0694bd51589bdc540e4debc00df1afc5aa5bbfc398187b5ab0e7f6ff262781dbb79a69b9b87a3e7a8c46d57c3447ac3fd787c90f255ef46f3723983cf963e1b30f29dac60097d48c174cc2789eb7804e903de375f40f024950166a056425ac4bcb5496ca63315172c25ab49acc31c1fdffcb5b6d6b2b02e2c09b39e84d3a23ae9749b6da3ed28e7facb387cfd1005e7408f2fec7d04426ca7c5567a33e734e2adb3c0023e8c0ddd5d206f2d7dad29bf117f6061f0353a9f6901aae2173f670fe61f721a6f7999d84fe02a0a6fbca32390ccccfbfa7b9b0e000e4481340057da2d3fb15b2a4a4b859cd64aca8d179065c4fc2c063862692e354a12ddfa22cabc99500132e67f736784c8ae2faaef56a40ea55ee5921c679c16539aa9440e07614ce6e3efed4f92533b18e5edbda0ba6aaf00b66ae675ceb8c1ac5011c39e42638a007215bc606e3e4600c943fd3e5eb0d8cd0a6d167b0a5fb73248008e22022da405eaf31a4b1f15d7b2212cda1298463103713d9a90b7be6bb96288122ef37f184adccacec9d2b0332b0cc02bff1208572554101be76f28f640682d9916ce60a2d06f95ea87190277d2497759e44abed689cc9a74622dce6a5594772035dfd5e8d57d0cf11b41511b36c4f6fa09627db7ba0b336fb536dc815e6ea85c7519969e5941b44db5bba0964d822392e50a9a23df3760ec1746746dc0dbaa6e2568881db699b3c4ed9cfaa42fe4b522fa9aef8bcc868bb134a0279f02fb9cf0d9c4ac6194d8e47d0792d5691e7558ada10fd3e4642aa95fc3560a959ca78fa2a9066282486766f39dcaecdd903a488fc605df1fc5689a5d9b2f6e017dcf15734a2dd3ca7dc48ef5f32400f91741478971d6478ffe80e241f3812dc3432c174c9d45f1701", "636a525163ac6a6a", 0, -333825940, 0, "986d38340a4e5eca99e8627a5b30a52d36366e1ba1487e4409c558cda2c7ca46"], + ["030000807082c40302273712cca9ac6533c494de7fb7a2fcee0a80bad9cd8d6a6bf81e4d1ac3b9943b0100000003ac51aceb4e914b4861d992e680dfc6fbb6366d0f5a4acef71f8ee4777d5bc7ad1089b9565f044601000000045100ac65ffffffff03aa49870300000000095152516a00ac53006a9b51f202000000000900ac6552650053000073b8c70500000000065252ac6a5163000000001e6191ec0200000000000000003bf484010000000036d9acea80b5c3e0c76db0634861d114de3084b353261905fc0f40f4f2d61ddf07fc9d6f069fbc4b1ec9ef7d75c53e1a1af9740fcb1c73a2b3142c8508df5d6de124df335109e20b879c3a839bdc0c5ac7d1e0f931e4d923b9c552dc65151b67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e40f8b829d875d26335402b0685047e5cf3a0ece29719137f3d39fe3155bd74188ef0b756e9e129cf521750e0453c41d196f14c9a099f5f77890870c6c83942419d6309bc4e7ed73b41ea8502796c124205015f6543f5ab30722e86ee992102db1290ee75b71221eccdfc1127ec9510fa27d37cbc6542ac8ebb5aa139886f140301f25c690db9d3de063aeb2278f85db3d53a625cec144e46d7e294b01fcab26603185c073868f5410b5342cc6f7ddbcc2f6defd194d10e0c82e860a8a161a7cd5c0a073c46b9fd7192e02278adb1cdb9dc00bc0b3d4b7b8ce3ca2ae8e2a70d96c27ec1ad3ffafe0f48cba18feb33ef82ffd74b8338e4486596548607f7bb11e2538f032a78618537de84dc6047e7d20677664674b0981e96e97c65b5db306a4c5dc20c03154efe3e71e4f4b33cf811d41aaf06fbb66bf55f84f3fd4ff921b20c3e859189031fa1f2b86f4ff57e0afba246d33c514410603eab0df72ec4ece2ae7752930c7702033622d4daafc54b2bd8380f789ba9e950882166da0af8ad2f9a3b383744ca6702147763f1012bd250f1cb63d4d3be1bfe31bbc050bde2d7b40572555c787f2439d4e020768706c8211a1793d705419e9fe5beab3eb5f9c572b315b67eda6ffd043f6dfc9e4ac6b8b9292b198fcab6b339458354fa8fd015fc921704c52cc0d7932c2cdec09fd94e11d80ede08e5bdeedd826da9f3f643e671498b0b022f39e6402194867d833223b9c698bc255d4cfd8b322a36f3d50b913704b839ac3bd746b7ff281f4ab500be36e696fe8c4c9dc73a04ed5f51b1a6a5fefde6b82b223264fbe7236fdf62a316cf1925e3c59a9e5c5af7e13d9cc44beb4734874f581c969398d48af90d7e146eb4b16ee16414fa95c942ae7687ffe9d0f7ed7fd7a66af673e56a65882253662fc5edb54703c97af4b58d3ef1685ec6e1b8c14a10dbf8471ad8f55c801a78018167a41cdb36b49d8cf17a29a51646d7c301b81edb366483c0a56afc6691fbb65228f7e84702e474021649b6627d16177a31ab444fe55f5cef6bca5165be26cc46d147bd30cab60d5db907f8271675afc388def6d146980b601e0cd337c4e80cb897b53919e2c776554d7cab453d91b7b3c66846fc7cdf0a72a7ed58b724b524272d01b02b71d622437f7350e702314d3d49a02120476727953315c48b4fc182ddc810f61efb9d198cd6a71db20f1436e499cb0c1d431afc8be6fca94c5989e4d93b92aa6154fec7853b91e72834497a5a2324578446d4c04265489a2213aa6eab99a93fbcf68fa0e3fc037d2de2e5d6057399c3eba7e5dbc63b24f4b0841e34a5b2e0c08a2f5f96e741100f7772f61d1686cffa13240e18c2af2f3357635f8cebb9bae9b5a78032abd122c99ff5aeea0a02675daf7d78eea7cd7854e9f1968107dfeb78c319796ec583cdb50a468c06011f273fdf340ba2f7be587adc4b6fc221652db89b1c9f247790446ce0eb2cedaabb88b56f629954f1fca8cfccf4b2b064b6effe7fb84ebc4bfe1f976f5e432482370ae735a25a68c4121222bdd800a3418561badf2f66854196d4c1f2432ebeed07731e600847b2a7214359761bfca00792d8c33cc3cc31a024f74b2542e4034dbea4b95d582289ae1367d6dcd9ea9b24c0f91085eb673160f4ddbb340f496dd43ac9f2efcc78857d29278e81cd4e395934da4c86b32050fd98531985bbe8de1fe7ef189868e5593130d646ad93783addd2eb86b0b456e38cb497ad9be448f4b9d5fce67cdcd498180a03af7617af243455e9560f904e3fdbdd1809f936b679c028e5ea818a7a9c2f5191e37b882002af7c4337a06ce883aa1b0b4738c942dcc46f89e34f7ac53ef7f79f616ffe341786c41cbb2f13ee7d62fd51bf525fa82b16640d720970a50add2a30135459171146a1657f4346cad5e0dcc6d4e58978c6ceb621f200cf41081ca266ac418e7a5821f6465bf6b7d9801b1de317b0ded07e6837d84a543437100d6aae5a80f2a84cae00b4c7cee5a21b6d8f381310b3c2e65880a36b25550f8d46f992f0967c27d3a3594c2edf1053b204fc9c4fe6614773527ccb06723eb0a2055c1b52ee414069894a584d242b5d9561a7fb1aa0ba0dce715806a339e544b61cc6e7515110975e75547cb2d1ba8c93fbcf991e38030d58be49715bbca733433d825c45194e7ad21778316e3e3b259efbad35fcde404494f6d4e1a7d1757f5458997d1185dff089a892191af698743c6233ce5fb5f202cf9a82739a6b25f786cf2c951f5fbc978ba7a6d3f2f5ddbce3599a70560000000000000000193f4e04000000007f0e18f52c343443f479f8baf22440733f9da39612f0a9e70923d31163027fa4edc71b7baa2b937f3817af19c276993b93cdbb9f2eb002ff4b80de77faa64c9428f0c617d55bc55df32e9a799aa37006a6796331c8f4e2a1f4d53e98e81bdd69000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c52b5461d9fd4608a4124bec04ff18e1248223e78357c15ed140a3435d30735c0ed040bc6b7924ac16958b1868dd9f1c5101470c14d9c6436a5fbc9d0f0f1e64782cde3b3c7f228a0593ae9ac4dc63f93d8ad517fe8e17da87da78986bfbeb672e2bdc8296f8d22ced1aa4f887171038cc96e9e9b400725daee9089d520f3560311506185507e1034ec949b09717a7cd1a2fcda7bb386fc87a3746487ab6ef8b00214ee939659d12ee95bde924ff3ec6d9de3b4d7d39595c17708f8b889e8ebdfc80b07ca415b8f7e4bc7d633dd983270318084d0cb0c46c08b9932a67774b029017e27c3330d9949ad80a49c97be5fd934dd7b1d21283326061dd0369c719573da5703094add6b321f17d93fed1e713955ec7a37ec46189fd9119ab09d9d5c47a19cfb031a730f1e96ebcfca130b6efe79626e1ab76f208d68703fdf8aa77650eb69a119031d393edff11114b31514be679a2e993a2d2ec7f4ff9b6f251eaa2ed2fd85c3f7030799c0a5d9e43f196d2dd4fa39ac36569927fc6b2cf2d453942ab1c373ef430c020e9497cdd5dc069fa2ea97bcdc631ce7f5be51fb0e6dd1075a3798ca32a0e83651ff45d0def36a8d97c80100e029fece71afe6dd088d1dfa35ec5acec205094e1d125e816c2e9c3aaf3e4fe6948362a3957a50295610fe9e84f0890c43b56a4a6bd36148d1733cc98ff73d83a2278992f22ea8b68ad24034de003c76c2f0a2c18ec0747c0580e19df2cb6518b8f4d7626088310c602c477e29a91d4cfc5bd0a12bdc56dd9c4b00072b7e9cb73b500127281ac75debef631954da19e48d3996b305d0acdf1bb09f662d8a9584e759353769c7c80322c0f19083e5f6774774e01eff6b7d6d3f40fe05a6dc97dbb2e11c239a5122172a0b3d66713cd80bced56d9a44016a0e44552a52452dc69627060176541f2e3bada2f37bc926e2642cc73611e3aa7baf603b6c7ddb67a63e2531e515ea852cd0b1cf5db57d1e212fa38445104fa3ebfc48f3a6c2177f7118dab2298987cdb90ec68e98766244e2b588d1ed7521e54c78bcf9eec23f67c31f686e5bb83feba2af745cb09144398277547bbdc9e68c243c63c1f176aa5131073019949d6100c80298c543284d71ebe85f3480187563d5f39820ec1987cb59de8c798be843fc8a572bd4f535dea9050aef45564f6820a30cdb5f8cb5dee2d50298126ecddcb4ddc3798477a52b83da9f4382567998a802ce0608b3b1d5b2a120262f80fac8fca047abdbd494ee0de3581b661fc4521a2443162195cbcd4b02ce8c8beff437cb4c5d87129645d40fc1d93d7c8e23f25ff53eb0c32b865072557c6967729cd1246a63294372a93fd032769022fa732b8c2349a6349458b1d21db6da9ed09c0458108cc7f42c3d88ae1188deccff4bc66b5c5fc93fef60287aaf502077c5461df5884f838a1d09fee2d4c2a2ca59e5e50af162c849419fd5b998b1fad19e0fe39a5b806d9bb40904785ce7d3827e518c36589316317fb6e8c51674f2095686d6e0b40ebffa018c952de7352838d6654c22c1520289517c67d55907182ec8bffa43e6b7a39bb2adb66658738b4f7b7f25a0c68396dd4379431f023f5e8a42a0ba835a50f95bf7afd94ac8219b1f4ef89eda570cd4756b09a88479adb46d4e7dedfdc3c47ad77b5e03f2c51ec430f3a4a7af1a432bfb4f905656d245f22a4080a711c6ae786964341b082117be057bf0cc2779ee7b7b885e91f3341969fed556ea025ec4dd6c3e73fb83b708140909a0c546b5090f85bc8f5ab4652c8837b60900eed598030bc7aae5c3d54c9c094cd05556b8a36158d52ab0dd2121ff1e9fe73a4fa3248b7c9a7525349277a445c8fcb6a6fb86b00591d495b3d022ad08e3f8b49c85d51f0af6b2ada644f87dab0e55ac0b385f11de5632cd725f3b2e59c0263924e051ef62422efb4b884da9c685fb83a538cbc04cf4b7b26cfdbb4311f87d98777e19f77a91f078b44094a3fc2fe136826dfe2255d598b7d5f040dbe60cd66e4420033531bbe767c24a08d2a191468d8aacc6a659c849133f63c0d1842542c20df7de0239b62b50d501b172b448bb8217d00ebf051d14147e160413a8fdc8cb2dafaf36fe6e15e3b4e11dae23417810ab9820f1b80a312476e128b4d3364dcf277f8f578633231aa47cb574277d195efcaa79688241ea2c4de7f4b59f8dfb9169d3ecfa1d55a51af3a3d714783e0fdf65cdd69029c0b7eaa230dfcbdeee5428ab0217d845c43a4bd928ce3192b3925080289321993814002d0d746d03e8b38cbcb955139f9a091cd5cf1cf7397e99f65bfa37d42d0cf84ac1fb8d9a567bd786b33317859a325a16ac2c54bf65e80aaebc8e23b44cb4c088f582a7183af9057ee25ca17f82c972eb7a2d5ac8425f05a6ef5bdece45ea5ed5797bbefd12d94a1b0d", "6a0063636aac6353", 0, 499041583, 1537743641, "815c1021f7332572f6de105ed414892e37c88395e118321abb1384478370f505"], + ["030000807082c40304844a25d3732ad254fd95fd210f4ca1a04c05747307265072c20a00089888d95a01000000036a5153ffffffff0cfeb90ad6e3fc9ff3e30e9d13eaa0af2a8de808b33eca064262ec9476a345f2020000000553ac515300d207bbdf7b27685d5dcbfc889eec262692b608df601759671c9fb193c7363afdbd5ccd57020000000153ffffffffc1438abae9a75f41aa2cf30bf8c7703fca0933f1fa19193fb53ba3ce9e93a9bd0100000004ac6a5165ffffffff028b905300000000000200acff61d0020000000008ac5352006a65525392c231ce4087c95002bfd9e20100000000000000000000000099fc0c1f16b671a5bf494c30d4c835792a2eef01ef998d329f05a0fe2ded90f0d1e53fb2ffacc86cc81d530f81ea65665cb6bd496a06908b755a8538b2897c6a98975f7ac7a0a44e14ceea7e887867d7a9506521829a2946b50ae9682061d96e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000072062255a0c46846b345fbda53f320b7aea51553b40d85a35a629fee01ad74a6a09ba99011fc3f8474cc530e4c5c8c3815aaf8e73d408682c82bc3894136ea90827337e416b83ad25024262ce0fac14b6a19277a39a2fa4907a1700cc3840977f08b37a690bdd2844b46b48bab8ea596f6684d5f6cb4bac91f0d55c416376ca9021777b781f1ee46e4ecf6c2722d97d49d53ad77fa262ea01af972ce3c7484f0330207acfa862d9fde64a5bf30d037ccb21799dd116de02788ccbdef94269b3fb95a0b05b60fe4f1cb6d8d09262c6da2094af299bb81d29e164728cf6eb94ead5235a5d02b19ab18ff8b37b8ad898b4e5b8b40af6bfe7ed669b0f9119e39bbe4aec0470302c1159673325701b1ca86eb31d240d9c9dc611990b9066110fedaae9f697bdf0227db89069415cd5e8c720572bfc14f059c1ca32cb804d08808e319310f51ebbc021f1e0352c59bc85ce191583f90539ccd5e3b875c03e5b22cbfd74ccce86da5e8021fd4545a5f0ed44b8fee61e8926b822bff8b30b26e78f1aaac3de5effedc39b10329710af0b66e68cfe041c1836b6ff9cd23e5805f4823ac989da677a41b1e469f20859ae9fca118dfff7b78e619b827a34e8f620ab58b91c82818cffef843918d08c93ff5a258fec0465649a58e57647fb0c434334274b03e869d8990c55d5862ae69922dad665f794e4e67d21c4f835cac686d6ccf67748e61d71a1a26353a586d51f4b3284c5caf2a5e3a6c93a1670aa1b3102829709b0dd9d7e10a3a6da8dceeb572119b460f8076b53ee16889f62387ba8991643aefef59439f493703d929fe2eeb316e34125cd32c2191c0ca58e41a04c3b95861ba1d079414791383092eb9fab8ef7900dbca92365298ee7871015bf100005f1870bfff0d5e76c2888845d5419d73352b8530c38f804d734f0aa5317cf658c892e9f708805572d43206a0248e6d1c2f31b0f09e3bd9e504b1f60f2df5f0aa28f71053a04397b50e8ce3d99afbd87ed3652dffa36cf8a5bfd9d21d419d4e68da5c297e1db6f27af2592270944670606fe42e7611bee95c7df634355df0d6216fbd6b3a79c0bd701a14070122f0311027f15cf1e517a7a45ab224b92f5af3b38a7ee1cfdff0716353c4c4ebf90481bcda67ad4c61785884a4f87bfe570832726925587116b4db55233e13593eac8a99fae1a02d8e6179654afa893d60f3a61709469b0c5b18c729c0989e6dd4aa5a79b7ddf178e54961c7c9816bed8b0501d26023d74f9a8e3d301ff48e494a3ce9da6d20b2b4480664b3a9b3ebcf559f2a018c48bd4eb78fa1374c7717c0dbffb9009c0b2f31a5e9470fc0afa8a0e3516f57ce4f3137c8d39a7722fb092c3799abddf32f64d9c0f8f4448f9bb9951d85ded974e06caf262b4fee552c24e17be74ac86ecde81b1f71bc9f2f5f212fc4b7fe0dcc528ee55aef40ba5034955c9b931057a5c35c2e26f769790d082378ce52371f40641117b9b8b91cba1d09ec62df809883a1cc99b84eec0e1e3a7806ab76676f7323b59761974c5f1f95789e13d3089d9376b64b7c5335288dbf75d3b143ae52568d7249ca344843e9560a08240a1ce816376a8e26ce95fc9fa31494d6b1293634cdff7da9cd0d60a804a629c26b6e162c503a8dffa2518f998840e4cbfec618039e234856731e23984fa1af2c1e2fa4562ff7193b9f5dc285effe9a805c15d3e80ccd738bc549e6ff92bf0f65d7257cc0d905ab72f3cf0ad8b02eb867a1efc7f5d6b86007f0e5f1c2aba970f3fa195a8443b0c67be98a6a985de1965e1e9dbed6802bfde5f277be70cb20b8ec9de5da2c89106c184508953f2086000de18e8783d84bf39c261a3c3576fbda7b9d9ef423b84bd0671587b98aec798c51c67204c2440de3b90b9326c21af7ef54ac52e37d66a69a66bc2d349739589634d4848ca87b4a14ec05321292df3d968e870f86b3f948fceedf46409ace3809485fd312a4137c154c8b125b3e9892b29c41c43dde10e0c9fe44f3c3e206e882a64dd621915338a98df2c6dd1ed15bcc6e1f07f94ffad282e2c41630b432eb8e09e8b5bccc337ae122e17dfd4d14799b4feab79748ccb71f6269cb608a054024628200a1e80bb7aee87c5180f33822ace278fd5987ad631e49db5015ae9fa67fb83b88b2c6b4cb5019721b3ead386e5473ccf4624ed410e06275edf69598e26cbdaee7c6092c5edb8177e44eb3645f7a56daada1ddfcf80b9f0be4eecd1f72185f3ff170849210396dc13e8eb870c0ef33fe91ff4564f4a1bc910b54fa1231c05ed4a46c9f010000000000000000000000007b8690c7a169e9f927768b4f5f3b47c3cc7b52ee87ed4a5f248d4bea43d9d84544a846b16e17890d57fbb4fac33df46eabdbe6c7424eec514a11f02de80f9594aa8c999c3a50befe76bfbe0b9e4b0c5b90b8f85903f579b199a8a74938dd1c6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e450dda5dab2b919ac52312eb1a56004db4aed420ae06b13e553ee65585bf59ed32b6ad8c7c8107d24fb800bf280d70c29b8e22e53918b3c0f6ddc0ad192a3db30bb944470be0190e15e3f1eb6549cc03a2808c9cdb5c036bec6f3290dab3b1089e63ca8d8f2fa90a09093edaae70242143a516006933a3353ff0f90c27fbed90208a1650356a347e739abd9c61801c1d65666fe81e1f22ade595c206051a8ac2d030ca849f41d5e4117d87a6f83a8ec9bcec2a406733e9de1ec6b7be2be85c733d70a05a68f23c40e6af5e653ad54f388a415c60f7ad76431b2ee73498e4b571f93cc6313d27c0ffd94af288d09b93edc8022fed861f35dc2d39bfac3e04e436894630225e5a6b0833e602f5daf6249877c8d03205f97742e64e4523b40a0f8b3228ab9020913265a6e28fa706684f058ff9a8dd24d71bcc264aaa05b4c57b3b08c122093030f204010058e803c02890abf953851b43f7fcbb71ef833db38d1ae7f2469dab6031b215e700f7f6118fd30ea4183cf07ee0134c175df1b3113714839ff69e8f059020e51947cb44bcbea7775071e63da377d149885584752c5bd6e17f7eafb7b4c18b08d7e8d9e02f695ce7789ebf08289b8345960538da3f47d5e060164cbcf38f6bcbe7f4ff737c78c09247ad643c625b2a447eaa7efe96ec9ea2c998fb93001c371641421551ada646273567d54014719924a3d0006fcc9b6a83447756b5de2ffb241cb24c7b65a81348a986f2b64a8ca31d72798c40fc8296bfbe336bef9d7793b7abf3e50e0b331631caa2f6ce2ff27306e572fee1e19fe7552331af664f36e88794d0dcf65fcf04e9a308c6e4e29d87fc03f6aeda05956b25ad1872d5f66a047c946e63508a56991ab5613dfc70edef4bd1b9ed6f424a3dc31c8618f2d150e2d08d049f2956356eff4054ae37ee6269f680fc62899f03ef678d9ec82f3f483cb5194d11ef3c59039d83367c599cc16d8cd9484f53418170bb993406b2b68bc5e9d8fc5898461c5c6fdd816bbf9743b0968459e77df5782c6c97e20421c4932b8aec0599fd082c38c442202b283abd8db989a77fa6ea97029d8beb98365a23a90cb1f646794b169be8e6ac33400c2ecadc7f78a875d91150e3c0aebf7e5745597ea2e33ff211e54726a5a3f5ddee3cab9682a03e646718769498290fc234fa8c6a67d6f1cea97b12d2703fcbe6e4acf64fe8096c2fb078e1b34b841ef0676eb675f85280eaaef3a1ed6a8cc2923d450242e2eb319e2d4ec20d6e6a3995fa768c5c2bcdac27510e5759b316a1ff86b6c905b06522b9226df12d174cdd0305fcee8c06e804e8373238187f5c8ac6e966601a53876b0d04bfdfb6723f904fb7a792590fcf89931753c13971d80d209c3f728ef080482674e491dc0943a832380f8eeeffc54ef17964516a2e49ae31b5063c36db0d0854bd187a0418ba6bc08db32e973aa4a2beda33f845f050826566bc9e25275fc33ace34fac10aadf0058f8601595c11b8d87472a51c843b8309ad0dcececeff95b1806c1afb6286bb8f77ea85b49da4b5d958a1152bb473b042ae2648412f2409f81e4b93cf2dc38c3b5e426037168289a9cb6df84d52e87911538a4a03d4b90ecf3156f117dbf51f75c8cd4e3930733d5ba2d5ea041efddca950b447dbee215f45d7c800f12c50126bf568494592fd447e1fc1e1f482aa8bd1af5582965b39de13739e56333e8e3c30a67c865acadea32f3d315dd9de0c6d2f4af41c711f453ad419fa66bfed70c204abc13a54f699c1c9333ff7bbd4a3885b315e2edd7e80dfa7f3ae4bb96cf49aa576c6c8fdc08c3b6cb19033abf8f1afbd842c248be7aedb1ccbea4b131d8a3544bc2ec4703b16865d41a4d9173df769cb8316ea60da42658e9fc652d4a54997c5ca7fbb58251a597b13747d21ca83274aef5f63124aecaabb344021ecd50c6ccae0703d428958ac06dd9dba18a38ef8ee13288fed64d04a3dba97783f19974b520fe01206f93d7ad815b35f4972420c37d589735b4aef25254eda3cb72d0e2d292477f26d6eef80ff8655928eb72cd9980d28c1538a379ed8250eca9131cf709a59465286b0a194ca9648df3f763db1f4b1b18ee43b15f8301cd4262172c83641ffa94bbc96c6d9cb8715da0354319d4768cdcc7924f3c51d0de2e660970cf16dbc1398121e35cf8b00ecddb640f701d133ea3e45dfe4422b6d0bf2e79aa1a2f4187964ea247d0b60cbb9226ba7f65754d8e0caafd3144b7ab8bc8ac5563d7e8633951447451cfdd770885dafb344a8a7ee7c7e98db8a37e01b16d07119984f0e2b6ef4a1d3e9a1a449c83cced9924b80ce6b385ee0efed804143253aa64cc0a07b73ff4331dac3de1296ce9f0b6cc0190cd9e9e1ad08950a05e8a5669e9fc2aba1eed2da75777b7eafb249427ce79915ad19c2b03", "00ac6563", 1, -1259523388, 1537743641, "98f17fb78b2f5a34a54b6a9710476bf829ab7f5462f2ceb4298183d52a38c13b"], + ["8f822e45013cb6fa0744d034a0487b6ebb38af208b4ce0958bc5bceccc5b721daba95781450100000008630065ac655263acdd810b3f01265e0e0100000000075300ac00516a530000000001000000000000000006d1b702000000001dbd2f5c5c8c7e2bb8dea687d7503f975c95e64fdf46a9b8bbcdca335449118946c0f7284cd47fe15481a192290f7cdbce8fca59c3b431a36552465daddd8a882e507d4b9448f24fab3325cc35dee46cfc96d002c983d7ad646ad5d964d685cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8564e7b5542a381b574dc645ef8ce3c58dd0966b24948589738712c9bb4ddba48979ff1156def8db470413bc9cae2a8dad8a0a6d45e65e0824eb6d7732e813659dd742ef970e7c7c0e155368e131d1ae76ee4273b57f69c36559ae8b5272e25948b8b19b33ee424dc2c053b1e08b7e480e5a5ee2b45d373045c375a1326b56b0300f705d2a9ae6066d45aafb8fbfd5b2a2955f322742f4e58f67ffa02d7b9576a032d05e243a11fee87787a25a5322a121810f5ba34387a2fea4615f33eaa3deba00a03a94c285a3b637fccc6b5e2a1f92ea2b0f4f725e2b5f9ba3d4d54ff50511a313c7c59393c5d78905ae949fc1585aa3a4f4febda49857a3f014d3a9c8ca89b3b0220846a20932170390f6b038055211df643368d9cb32e3cdeaaa33853d9237cb103056d3d9e94bae1ee242e0dfa63f47fecde556ec032c8b3fa672c4744b8cc7491021ed9ebd9a84ba5aef36965fc95b84449ea30ad3de1f531269fae36d3528e77fb0213e8fcfc68533d49f805fb30ed91513cfc39457e95451629505169d3102a20a20223a3291d5c81f25e8726fdb0f8eb59998b3e104ca7ebf3e652676a3df45022fb298ced0786722165df5c9566189ea5306f00b61c3e0ea149f17c6aade38b2d853c41c72ea5fc53d30fd9d268e79652195269fe235b723b44af0d9a380759f1954eaba5be1b1fe6eaaa1e15eed1c47676f13ebd620020b2f96f51f8a67897c50ab22b66fb2ceb78006cbfdd3a12754ea06ae8b28f7af9e5ab19a6718f664cab50369e3fd1caab56a3fb4175574bb049d1736722c2b25ce9dd38b06e26c44316bb11c3f16940b4d75df274131054236c53ceb9473c79f8493afabf49a1d883d4c2d697d54bb577569d571f74e10abb4cda3b2b8452fc03f7cf8247f3bcfe79d71d59bbdeba2649cc77fc596b0e05b8c79365124df1acd36c203e69541f29a6c7d245000c86bbfa4ee7a12ae32646f9e0a0f3a3a193fec3c26401c3008204b3f3d25415cdeb85369210c35afecff3f965d3cacf682565a2707d32f471f78d7d5e8cbca95af9bd4a11e766569224ad17b5046617264ce0cad7225bf5b52187bfe185f097b8c075a8a20eabed343770c63d0c394cae92d9bcf0e22d3407bc7bb356fe6226648f058af2009bbd5b176f3e1ab8c16ccdad42328dbe59d446ac43efa7e4717b5d40d6222069f128a7c39bcd636d1fd622f40be9b5c0bfd5352d405e286086a8f8bb1ef4ff8fefd92b2537ca8924d915d250f9278133ea04186da4bb38581ecb87938526f1a6f9c0760423444d319c6472df6970c74f26f0de785a9aaf12b6b4f3602992572b2ad24a0bc0f506e759f06a6d212aa0bc937696004c17ef96730dfff5517bde51b1a47812f54b95bc27828bef833f6872f25b806644979b7ad80a9de0812a42fdb5b26c65d9cf4c3610946d65cc191ffdaac961cbf6a4ce5dbde9af85527f89b9e2fb3a1563efd72a0d5a89bd5971b17f38665e145872f73a4e4e7faab3c284b0d1d0ec46854652e085698b23d7379716216bf09a1cf42bb73b5e6d1efb873ccf627aa4b8913b3da13944164d471859cf0a2400250757e46220da87fb31a78fd3b96ee8bd806ca5b4dd8ab8f2d968450bd11088c4c67f4b1a42f24da7869079f7de502bf2c1f74fb7ccbc08cbd2a0524f1081a56495f6d6d7c93d1781acffa0fa4696ea75ddee18c14554ef0fc2b52925781cfe3523d2d6d114f75e4f532e44d204672bf9112c71a5c73f82c30b775311539ff6d8f6348676be0d7c1fd2507511294f9643b64c457bc291562cdf30fb4cae7191b8fed5ab1326bc8d81db4ead56ca9522175952e548e27227d546cf211de7110b1aec29de2ee690627fe07af68366a31aea6512f082a02a6610053fb7b04dec602c7fcd53f9de3c3440e59b89e13e3bb3aab345c5e5cbd5744e1244e2bc04dbc13e074344ed93cc74a495971b9d2dc1f6c50c783aef31ab88dfeebbb4c6bcb9577db74d5878f6a41aae7c99e485b39e54f74d261dc0058e93cbf49902481831f20da9122cde8e37bf874c7064204b7d87b4cbde9871c064e13d4f10e66576aea9ccffdabde0911d07bd9f03c2897caa6e94c950b8712e637e8eb891add43590aa80b441be0e2bd6db746240056e2e70de806f3c0e7623066d9ea7b55e674a44f76e4f816e4a72ef0c75028289bc6d8ebfdf3da468b68ae6895bd013327314a2ea08a588de82af2ae1b9f570baf77b4978969717479747cc1fbafe3b59dca8841dc4854c724168223ccec51a89734ff8774253eb9ea40439941440680cd13b714d708af5aad638efe1c1118f9b79350912e806e700562288626f914899687790fb78fd95f40ce5dec29591fc946f3247361e1646b7bb752c9b4ec03bbf59d264f5a92fa88af10e06d91a28e41f5cf2a89e0a1712b47a1d08", "005363", 0, 1102593987, 1537743641, "e899c4ef600dc3606cccfde3b515cfb8beada1e540ed1392a003c773be4e0442"], + ["030000807082c40304bbf7d08b9f1f37513ad2bb4f9bc8e3402752618ebee85d1c7e64c159318dbec6010000000752520065516500ffffffff797e3cc1b6bb9addeca1b04655024af32b1898e4569f2577c3592296038ea30c02000000066aac5200656a646500506dc84b0dfac5af6040d4b418b0e931afa60bfdc53dd72a686bfaa2a3085dbf9201000000076a52ac536351001164f03a438b834a28c7af0f7fd672bd6bcb4087d54ea1b097cca91fbad850217fc6f0ec0200000000ffffffff01d04ba6040000000004006552ac643459f00000000003dff23e03000000000000000000000000566d9ab6ad2ffbba2acb015336a6c3dd43c7f871ea157f6f13a7d355f3f85fe14908df4de7bbb1a6445d0991ba71ca09967163afcdabfdb5e1c4fd8371c5d7bc62c62373683f72fff347ba4800c701adbb206a284bb3a258396f9ed8b0da441900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c884b148f17f541f5907ab3fbdc215d7976c0b941566050da6c28bf10d7ad5aad7efc0fefb93d0068ac1c245b8e833f800246ed32cd221c9bd4cd2f8bb53d9029815d01a33fc8f800a0977239f56355eef519160aff3647e60a45d67e1c5eba001f2877cc95642cbd2ac514ccd118afd88e0fc92262c90b32efbb38f3884d547020dffa581fa5babe53a4215a4a611ffeb5937ed42d8f8a0ade4b653dea51853a70223db4116783cbdd72f21d53740677748f5d3c47be889dcadb8d3a340e6d969960a075c4c629739482622da111684aaecf75cfbd40e5cf897a700942f691bda6aff16f6d5718f612fd55b7c9fb6acffe803f31a1fdd72532dd0e4d3bb9945bf908503020ef482aed0b2dcef561927f9dcd97e88deea629e12f3b0b73af0623597b70403197d37a9da4ddaba73ab95b7222413ff1cacff47dc7e7f82629976e60b887562032f166427c09c838c8fb88affbed59406ab9b206c4d2238f5589b5f1ded4fc142022d833f821a9ffa3894609175cede536d132a623c46266ee77318ccdcbc064e5302217bb82e45a15781529913cd297b2a25967f4c574106c89ffe93ab944fd2c2ca8142247e04ea11836fa9dd1baafccf831b730a6481d5a64e2c2d382711f664c5d10591efc6762f5da4ca8d72d8e40872b8306e2bd1458951f3477eff0831f598c57db5646b9e578b554d954215f4866cbbf48a68ba37b80f33280377a78041ccd1cdf6c96beed1927894966ab63809646ea2514d52e4799a5188b420f62697311f6ddc301739f53b1035547cc15a74a4f736420ba298e073a88a855755c88433114e40593cbe8d8e4668fb5cb75e8d6016014f2e4f28f769f80ea4c045d9ae84f2b3ba5fb4866cda5a9df6d444b457765e3b988a80d14554aedaaef4795bd6bce25a27e702cc570a441fe090ffa396a99afb4d33ec99cb299a98cae869924525dd67a893c76f2edda8d5977bce6bbf4c1fc1451976311b8a6b7bcc2f7650aac8b8ab187672f48d0e517459a1b40c6205a4dbf199d99d25954c85346854c17f93221d92583576310837aa1ca5370ad9bc3069d142ffce7c565aacb9bdb9231074d85c4f88a08d753ce52e1925ceef63aa1be9189c27742a0b67c461bd87af1f4d42905b5c293ec535d5ebd65e66e0a809d0a013950e1b06d398aec8492541c044672b7f64fedb8f8cf48508ce94eb6edf3ca4d883967439f7898caf668cee3a5ad0ddb8322024577027c3d7a5a354d8794e6d87f6362ac55166b97dcee5db6981c7622f67e96bf34a1c0d42f11d9df756ac0d48a02ba1b57261f28a9e91c09ac489bbd4b32d947fb08afc415a55801eea5cf0d2f93c23e1fd1ecae09a904af6e7d04c882998415b518c3cf9f148dba6d3a21f457a81d93d01ef6b716c998b1423e39991a330582c61686fcb83326fe61ef00de4ff41bf0846915a3aeefa7b1135f8294685567509ea5892316bb1ccde5796d1366c8d823f559ac8c96f0f1b7de9390f6a3f07ac8b6037becb672fc228effefc3df5193a477b00759491ced1361065c6032ee86f54a931d6e1f99088fd69219f86afe4a93e841896d919f1211eab4a272b4cdcb8a8a22114a4536d4df112a321aba58ee83b9483f15d65c6452fee7cea96501df70aade5312d3d275adf50e86fe5699505e456810035cf2f81be7acc181893c51cd64c677f19a29f7fe4a1da352e518d00dfaa49bdf7a0eaf3170c51ee1173e43ef9d221dbc70fd8e154a23e6ff605cbbd7f977a9a8d232d0073c37afd0f857df838960786b219b65838924e47f1bd7b8e0bc687e2d06690eeb90e82be6a4245e4395ae46de5204a0f49f51cbe4fd056ccff4a703f12bada0208add2f7977360695cecb03f684c33b2822e830edb68d43107b22aca33cad2bd78c5510a1d11bd73f87a979395b42fa6691ccbd0f83b886706c2b4783dcdbdf4df33d6b40844e90002f3921b5241ad8a594324aa7ab008ef0b11b0ec6b0b345536a74ffdb1b25bc6add0236413e28366c12338c4cfa4d8589c479b718629342c5115870328d752dcb8144c1eafb5c7e1291399c138edef27441f9b5d1c4bc11c1992b7f532242015806f6fa029524302060efd5e28861b52a95b099f7f074a6a985dbbd4bd7b965a63af0db10dab10e63377f65e787aeac991434da3676ddfddbfba3b4b95575225f20c40e0955ba1481db5f789f0efe45fb67b944e23187f77e52bf57589f7de0c0f61cd214927cf69a44d503020673fcb7194d2f69c88916ae29cccb19de8d923cb333f3045d0aa445c5fb46a0000000000000000a294a705000000005f11cd3a3df733f018c5bfcbba192fc4fa8db1c9af87bc47eb644506a3225de1d85f7470a2c30ca4501eacd75b41e1374225c7d85557a93a77ed684e9b66e5b3ade473146225172e0feb1abf0da1d3846b58583d532c668065bcf61479d4686000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247758bfab2880973336ecc4e71ea7844bb2739808a1ef094fa049d3781cb232c11f31df645a3a0a3aed18a8770f44a7c02bad2f9004c7202815dc8c8424ba9f09020f4c3333ef0d92f6ff045278126b4076d746c20f7564b3f0587625733d29f3bf5c6a2d26f49beede3dbab33d535ef4a20703851d77287850c5f800d66fec03043c88e95710f974f996b7836f268d62e8a8793c7a138409851439481582d68d0224718b2c994cc47fbfebf41c2355a285e92e76429c2fa5ff4bd7912194b051870a065edd242bbe2076a43556a960b193baa73b07c9d02fc30413e543a55a62671fb36e6f22aa7c61b25c29a54a9b0e5bf6f1267cf82d8ac61fd253aea947b35822020d83574b5181fbd9bb17bdfd3e07918f041062cb14268f9f7bb40d48204865a402024891737dd2984c9b995f758efc2ac2d6e8f24b12a349ff9625c9d97b25005f02195bc195519d0fb61d005bffd04bce88771850bb30b9f4d05b82ff1591ac02b0020f25684deb2952298fe77b053dfc0bc184221e225110a30268723298f14c6167022dc3351c44d8aabb470e2d8f5e84170a255cf97bfb588c654212a2445db6f8f93d18e1d95159ceb9c525be41e0cc08a26a549f7fbff01867ee5ec35d8ae82df9add5fc54a32472bcb1e630c6c80e9fb314d503ec0ffa8432485b79c2590f619bb37aeae99fdf3f9fc21824398672bfe23949708ba6dfc9edcf91f8ee0acfc9ba242a17092c9a2eb4a593a2a21e82a8cfb71b70284403b10dfc7971ef60137dddafc8bc001d12309f6c17cd909102df038a90e87bfffc43b736f08bac57d413c4e3c57c0f78c80f624ffa2426c8fdaa59ddda50ea7e0ad8196fca7e0e4700d3abf306f8bc70b421b094ed06129cf080a736a7e1b4fc925f5acdd5b48a0fcf2deb0ec23c689684f6be427a5200317ba1d87a1ba205f87c132285a983d862f82ea2769b486d22b571bad459ff9596730112567a454be2511e63f248ab505f845c5d54d6668d0be384ac1cce190813ab61bec13822fe622c800a87c755bcb8522a0f9770bd58f52c83b59c0caebfded68eb83f63e231a4e5a234ff36e51594c605d8b995f34156aa6a7f210af54cbde7d06b9d32a5a6aa8ba74b1f0b28ce4d6ccbaadf29f3387bac70991cd8ec626b2c89e2f5e0de834185875361ce6f7e89b7e35b4d8af710d4cec00049ad3a5d1a8ff34953f38337707ba586c6277ec338122c586d3fa3cc03171a4333c4d1931b59028497fd600fa982e678583c871ebf5cfc0188e6d2c683f0bc887ff42eb96353a08ba71ee6f25e55bdb4aa7130b87a4ae1e3f3beb9066889e3d11432b5a3c5c3399d14148fca12648392c9d03015adfe547ff146fe5a36bf8d94aa43ddf99327192bcf256135b28270d309caf4d9f3feb583f019dda76b76dce925be2d9c91e86e479b30b089d23a26d7b1e78c17c51f5eddb62cd2df3b4dfc61b968f458fed755b1127d647a0f4500be7c07e56283557e50d3d42205ed0c72bc66b5082e396edf4796ce583b8a0e1187c8cacbf247f60d97f47757a24c889c64e39c75229d0ebac992e859edeacc87b66db30f4962647255698a997ff9ab0b0ca8f18425501227f2084a4bfa9c350264df84665b2e1f75d763bc2c9f5f59f038e90db611eb045d3b2350a421879b97a37b53509febceb241357e3762eedc803db13661a865a25644adb3643de42533988ccc5ea1aa1f5db341b49c3587895fd81817ad64c795e42405c2aadcb30c4b0ea28c6d3e4644c566f45c7a1262a3a1ade8f71dd56ed850dba1b9cb5c2811d398506fc510f6d078d7ecdd861e3e272ed97387e60147bded0910a2284f3563d8cf0e769abc57ed71ff872820f6b014ca2c6b9d682487fcb0afd8f5a702081cc0a5d09b2d30a20b08310d5232ae0b969420abb4cde2e5df2eea880f7a46bd4db7a36c7f628c6560c1dd967a81dbb5d944cf805113a52cf3028e4026bc66372d4b00e81a5e4da7e5afa13ed62728461102a387b8b1dfe1ac56512681c2b6ce881d917388e7a21c66c621d6f416004aa5beb8e01871aa7b8a3ce41e66d552612cfe3d3d7be905b652389c598f5db19e7e2d6d58902f48a210f0e45b744f56850c4b6112d5770444a23cc034fa845430f98a17ce8aec59505fc41bedcef1060551ef7ffdf06ebb75cc034e534ae4022a4ec3e3123a37a67647155e85797d3ddc3d8d91d05124e58a69ccfb7e98189a3e7861ea0e3b51276e58f3acb2cd615ddb6dc105bbaf6a8522fc839f7b09d1e035095b5d8aea712d0796c01b8a3f86cc2d020000000000000000000000007f1afc1751ac4597be004daeb51165ab0172c9b514645af78924cdaa895f6babbd4f990b68cf516febb1e5b1174c93545290ee9eeac0fffd25fc2d24f69f732b7f339fb930ad3d33137048f93e0abc7b833b1036837f39913a2f4ba7a777eee700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc171c87651861dbc79f60b0592d66e24b8bfbe1ee290d82f5c215921c7f4d52700b362722313712240e26585f3ae4f7162d7940467e8ee32d0e529766d6f9f7296458840101064435cda8bdd477be74447720d87d8a0ba8dbce32a366f34c9886ce758f6abc5d9608a60710d2baa049f9306ca41f0a3307be011ffb8acd002f021e6179f2a377bce54c1731aae1e04f1cad70acc4cbc91f6421d69d9e4c7e7001020cb56a7f3c6d952688e53f70259d39f0dff420c6e59dd1c5fef74b0aa09e309a0b06f000c7ab3bec8a74a1988f113da7ce6989b8db9232856ae80ab3fb442d4fbdba3e5f7e9a43a77c66238a781a3a20fb12a62e51fc81cca0be24e5d7d5673b9d021e10f70727d404fe71753cd8ee096367ee2ef3542c5ec81b126d33baa775630603189eddd6f618d1bec04139539c3c887e9bbfd29cfaaa3c78b3948b4740426636021b5ff02c9ecf59a4186c81edb26e1f5c1431765c9a018e99efbea9178222f7d3032222fb545d826dfcedd5512b83956686a16a18c3846f373c6563880023ea6d2402103f5c7718ecf401255ba0377f1e70620bedbe48c197fd78549bd27b4b059429ef6a9de0c4ef42b4f94096fd7eaef04c12ea1793fb4d52267639db9a5445dccf0761b38ec7a716ec60c4b9f6b8e058b57ff7a610a77c72c7271f982fd387c4f4dc290152a4c3a3b916fde09b00e09cd394bc63a4dd866e6da11c62dc584b5867302cbb17782f057e584b777b72e5a395c6dbd04586996386ea6d3e7f5f4fbeba4ba7193cfe62902525fa0e34be693c002bbc21262985cbae8858a2b856ec2530b23e2776334e16ef20f1341c1a7e48b725d9f7f697dcbe32ef395730ae30dfbfd45fbe5dea81f8e197967ba6211266201736c66ba7b8e5721961395b1d8958e229834b1b57014107c5b85008fb1c80dc75347ea8eb22039e4f850d1fc48ce4f64f0e2d256bfc5b3935476a559f4762da5aa8da48806d1ce20d3e6ae5a6b08290774c9346461b8ef2242a009177b453901f469076b6a2f1ee09edd042a3b614d108e91146a60b2ec58741006a3abe80902b0b88466ceb0481d0e82af21a6ab287f32a15549d1ba7f00c35cffc58f91f12274038e91570ab2a95af341209980f6373d0294456de054c270124af521ff5f1b7217f3a699d1829c54c7c26d17478280d20c2ef789ba520f05660e12b927964d695004aa311403f91a08666839f369288014e05e7b2366afc1df0bb213a933c7aac2c947290ddbbd0e25c60a802507d0488a4009ff319a14ec83c84f68c7666e1d8109a5c0917fdf18b492180b4bbcf217198c0a81a56eccc00467f4adf8a255b1057ab79241a5f55c539fb117455122f070442a958f1505f946b7335d97294ea602fd4600ac164a90e88ae4fbc1f9955da451ae1f58c48de57f1a49f79b67406f3e1a2e0d3e6c7dfab358adbedee5e8b47e3d45bfe0357c30b61eef4e1f62ed3046d27c321012325e3a1b67b78ec5400730f814568ce2b262741dbaacff80bca3a15f6e9081031d3aaa769ed856a05ace0e77ea8814da41c92db85827d5beef55734f4543e62d9f6596d739da89a4312d956c4e746f5ab790ac797618317ffcb60c89f4b55abfdc740ed5d0f374cacbd38934d11594a0c133276e1b759168780fb597b296c0af8a032e93a4967c790e33e3c2928fc1711843a88bef2d420327c651c3df9e6d7164421d6986506cb1dc40451009304d67ee59f3d7d7a91f9c18111bbdf7e5561469b9bcb34d4bff63a83c1a2e5cae5167ed45fff33d106c664eafc1a57d9cfca7176a82f9f3c47f476548f483c944ad1a530e7de88ac864d6bfa4f19caa5335993548c2f031b9058d253ae0d83e617c82dbe9d8873b11871e0d697097e519f80c3952d56695048109aa53f21c9807337136666d64f84e71b2ad51cce508edc8d50b764b1c6411d748d414fdeb375076911c1fd5efe900fa9e3a5819375054a0b823ebba026fba993abbd2fb43096fd312b9c4e3cdc99f32a8a1574d76b4d785bcbfe8511578e49b435491d2f8d5510ead734427d443c09da0040f40084c77202e33a9404f9a585a5b021a082e665275a09e9b6598cf339914733fe171127276283726c663adf896ebeeb0a90097fe813ba1f49ef09309ce3969ee76570bb1c7d63dd0401280781d769e0abb28bd324295a8ed81f0fa630f7d637482e4f975806908cb0099cea6de9332c3b57aee54e4627bc5dec457de02fd3c48d123ed47476fa32dba17ae3d0ac88724a78c896bd40ef1f5865e4adc7b78eb18b29593cc54f0fc926a369d9d5115c2f94df31b33b96f26673059ee971e4e8ed43873fcdbc0dab9106ad3f1ef2892618adb66024c73e8be46ba384536240f5d2b8e1dbd14eec1bd74923b6fee23ca9ceae70c33135c33f2e7ddad1ac07dfe79f06", "656351526363", 2, 1770261637, 1537743641, "2d051b41d267955a253b92f06a67adda341aeec674035ac6f6e88ecd45053260"], + ["030000807082c4030419586f769d0b269781b5eb9c10a7148751d721242448a270569eea5fa9a89826000000000463525265aac29ff93b536a30a17d0eae18e4fb57ae85f0150fa95665e48e282aaed3b19a1d59cab101000000026552ffffffff5b9cf02c35859e1fdc801c7b6d74e58bfe6e1fe8bbcbed5aaedb47607637cbd0010000000853ac5363ac6563524fdf0b4754c5433a77ac14c1b501d8bf03d51bb86e9efc37fef46629813b8e2ef6e0ada802000000026a5318cee32b02ce11b90300000000025351131de300000000000863650063ac51650000000000a549bcea030000000000000000ddb8b900000000003408ce630135b305337f08f4a56a30675e00903b3dfc7c1a7178c2a52ab92d890fe109ef12a5d19d3f0afe7037965d67e8d60a2533b883ddcee9a02e5d1ba7ef789563aba9c9c00af0d85037193d39fae70a2531969db81b5fcb48e0bd77acbf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000862c7a70f5910301468d1e257f134c5e186b283140ccc1ccc1532b1f9a5cf5ea7232e2b151737d59950129d99276cf85b71e7720867c5b4bc1388000fe3a039431541a400656a683fa0b1e03562adf15f16e7f2030970406763321a139a69b1d58d0a33a38cea74799981c1966f4df51e97e4f65565acd55536ad512dbfe702e020446b09ebf0d8bce20ee359d3480a2e84a1a6c7b989c1242a68e26290eecd2390313c56e681ce586f4f738f0113f67460fa1fffc6d44b3db7a6277f1dce1e5fd460a076bde26fd592f86d825bbdd62af94e0e82cf3574035df80de0ac9d7b69a076c070a0d19fced5a3b9c273968c22e0087443a3caf89649b7d3d24c0f1d7df1f8e020147f35b84934c0cf76c2c9f877572c67cd9582f65b52d27e30fc09671e5c635022b953b0b4deed2c5229d8602675c583ef6544229eedad1d7f1e03d045f7b0094020f5a620a8d2c56750ba5810da653559eed5c98719205607dd6c9f0f458a27fc1021d38b742f97a6e4da8e80eb72c0ade64c14013dee3b9837625539918ded6225c020bb7732d42437322f889ed8e1f45cb3f1a75c6c24e5a4483de0aab4199ef61795fef1dc14ab4a29216c0f31502155e16d4008b2dd21d3b5953bb9e14b61fe2f193b958f44f97e18b961a6dbf9f3491ac8bc7d168d5ebec22a4b73c83e2406adb66a099f44554c0ec0c0812b47e39ff974240c293b922183c7230e7fcbb0c8e5414e1f8ec61c88ad3e1df2709c12880196996529cd94819c74b24cc1a7cd479f1f3482a46668ddee7d8ddc8f6867f8dbc3a56431f45e0a6634d46a04a72a5bba04303babe2b0755363846d7de124e91f697feec7e9c172cdea9d44689b19ee0a1be78e2c0ef246135ce04298d93bb20121d66e732bbd1ba759d788033123a90cb43c0d75a6d5e4d9f8b557549b4daceba6e096764fe3ed911e8a79f94b3bdaa7f591b24e7f5d0bbf635583d7e7351ed369bfd400899396ad5156c1e6bf75d38857bce71720195131a9ba490474dce35375327948198d4b4d506c63222e378c844f1fee5438b07dbf010ad219e658c662c4b3e35e490d75b38821dad5dcd50a710a4b228a8f880bb3adc3b0fc57505f0f613f1f83f9147a212b6bdcd334f46e87602a7c1193af9dbff8c7b8b2c435a722cb5df73d798b0ec84206126e22ce39a22964f785ce6d2fef5f5f75661e9a87416e4fdefffc450df1e7b648cf8df1ffc5d1ad985ade105dbc221678bc9887172f6e3c730b2a948e9038da4f9e3bfcdd07a85621604e617c7b1ee796c91a945311ad5f86ea1c4bc1054219c708a97e1687cf1ff15747ec123657a24598c83f8aaaec824e38aef19c6fdfadea171e7cf65c2921e692c361d8f73fee12b8a2d0ba2eb733f64beac27c96f577680ce474e24a8af63ec22a8b0894f983072139ac0aa3fda18a643e6b0177214489552129169401aa2680955970ffc6a4bfeaf39164183994eb648995039f77ea49a3cc700935cc01a7842525526e44f4be91ffbef72ea8db666ec294359005c85ff36720815028f91867f417fb1c5a08876b6e0c3172fa1aece189928d1a6657dd9623cf0eefec452e0118e6c7b6f0ceb550edf4f9b63892ddb57b5ae334ed39d4b6b87c7bbefc0918c3842426db5971002e5fe33f7ba9b654f87c79e9c28f4747046b7a208b23dc12a3bba0d5015695d0b1bf344eed1df724daa129784923ac205063db4c8cdd29e14b64e774cd05bf43cd3774400cd400c6de6e00c414abc8bbb94f6c55307e5d3abea25ffd2cee77249c13a008ecf7bac73ab1486aed5b53ee2fab1895b1f49264a78ac7b1e7cc413813ba47d423f07c09bb4456031159bea09c8307964d7826cfb660071e83dc4f4661a9c8d17b4fb95df4948720ef2078d2fa054842235dbc46c0034ee41f8046aa6df2e2ac9a5314974a918177bcee53b50f95b22a0bdb2306ff3358655451999fc2cb24d70e8ce0aeb95acac6b9cf2f6b1d53216850b78c000c304944926bd7e1c5007dd9001c15973d0ba815026b34590e3984e6549475e08479ff0f67e575a1954cbbb786e09ae83c53ae4dc9c1151e45a620d528f20803b305721aebf540f9b9e8382d800722b0d9be56bce690fa24ab01a3eb82b7213103cdaad72cc9bf87a017e6d51133843729c74ae0883353b7e916f734bec6f6e303ca26dbcc9e43d889b13d2e3eed2a0336bc61b712fa383a4b7a7d28691b712341db536da064680d6b994af1f6014053d7e5752a421f11efbd7a4c43d122418ea46c90b1b65617958b3557589277b14999cce04000000000000000000000000379ecc0631202afacaf87d08e7fe1d1ee691586177e1694049484f109c835cd528819f4727f5094b1933313be3a49224455c46363cb8ea1008f21d22c2e6763ad471175dd19399fb5fb6392cde087c6f5e143ba530f8509c6687ed70632ff9690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045bfc2594b1251d3ce06b00e85bcbe4ef22526a8e0fc9f6bae6fb193f3084cc5b26092404a9b6b6b20fee39cac24e213f483b167e5b88982eea29863758a5b8a7a8e9c247e044933c9484437cff84f66a28c8e0849a74b788c4660e2f3f8ab163b440e242ae3906446f631b86998f5c72627945ccae4434e95314c23b084f866032a45b8fd2cc11873465e3219f1c139c2abd19658514358fade6dea962f0919c8031255adab5668faebd120340fd2efee7d74084dcb4186f643d046f9e92a8aee1d0a00bcd6ac77b1382885fe5cd60a6223ecdf98e11cccf8a6a64f732abe17f91dbfb82cbd6758e90ea1f03301bf1caa1370fc06c3e751cfa1a214e9a8841741450e0224d1c7ac01f818c571c597fd4e0eb938ff49e78424b8b10f05c9d50a938e66e20310ee7564e26c8acbdc4b4d678ec1633d254e40ece9de5f1a1f8119c38d40327503232dbe5f380198d3906f0b7577836aa2124b09c06cb556cfe13135ffcdf07065032afac314a8ac5b77318d0c4b1ae0bdf2432df231c5712f1fed273930b5e9a4350226a570c99ce10ae0d72cbe9decaaa65e5f843c253c8ebdf9e51515243fdad58539cf983f9e644ceed21d87b9f5d34380b69f2d7db797d7536b00d0986f5048f29ccd76aa2a4820dce993f086bfdb7ff218acaf67e4da5901d035cf7321671851f63a404054b88a5d56b5f27d36916f7b75fba3128474911ba830f41d0881ea7ca06c7a07ea29e0b7eb78927b3fc79cbb701234b1df979da993407577f617c96f049e09470c911c540f313eb645ecb5da4e55a75f69564e3471bfdd3bfb6ee49897b7b699ae787a55f86bac5b4a17c849aff33efd8069f9ca9d039dea8b9b8fb57a8ee40a656bb152aa930623c8c713cc977f71745b4c2cd5c581e5632e4ffb6f69db9cdcaf7de5156fd557f00ec5fdf25e4d265173284943618acba7022dc355aedd48af56ee596257346b26551af1477caaf6d96c5ed3b43ac5a0e0840a21934bf82859a6a420cffac49d7f6028a51815065a53c34f33a810fa148bd2aa8f4936f14be0cb883e3f9cd41e0a32999af0a1c53cff93e1108b491e1590ee6b863cdcb3007b2a3eaeb0a7bbff1d3e8e9eff79abcce1b79556af91ee8d0dca634137c7e9eee11e0ec1d8907eb64c90b92017c52e8d27a35be09f99e8591f07e701fff93e81a5aff4125b557abfd758ad4f0ed2e1f84556320c554179a404feda43e8104b55468222a1d3e80c6afa7b00a9d20481dbd76d702cd4d5106a0b9b1e080b2037f223254fe12a9c413b4147b7d9051c32c46d98e83b51b871f2149417c689ec9c3005fd8da886d52362236aee7f07ca9e00a973538ee5c1e7d071aaf40b97bd98dd25b82e597d2c460d6069728425240507c0f6359a3e240af9153b5d6f362125639f8baacfa48ba16b347aca0be58f44557d6d909d61cddd890499ccdecb35cd52378209bcdc50692569681acf10d95f34bcecfc7cf364f079a94a5c98cec27982f340c9259295721db68325c9e761212b38ad3109d7a09046bc5838ab89498f85b4723ab6b15c11ce2cc42f2aff397a62b106cb20e29d56b7c6bfa78044aeb98302f5aa632c54c144565e70a3aaf965c4a83f1b161c249ad2a0a0b35d6dcd039ec3b7bbdd3c6e20850b88d3a7ccc0d8a0478e2d2aa732e47647403f3ca237fe995a7e24de0e5168d93ba2a60140c93c3b28874aeea2e375bab493fa0f0e8b27a5a29468d7d77c22f4f6c4c660c44424777ec0e24200bfc8c0daaa72283807148749cc60b2f0ef28ce6abe8c2ea5442597dfab66d06c6621bfc2f8dd995d225cacb45e4ce7651e6e90b5ef1e9d9e8cf8c776ca9ecc7cfdacabbd8b50b8d78cb1a1e34f98fbca230a9c4bb6226a9655a060d39a976422ae0c9ce0a7821aa519988088d3d210230915cadd6e468d8f0ea02bc4c42a4ecde09277aa84878e63a01f94758cfa2cdd3b08235adc70421e82658cf5861aaea7e2d7da7796b6a9b244fdbd95b3ec463c831ed3682e6c610e19ad9e8f79190da4671567d27a6717707963ab5fcd7f5dce4cb82f7981ac7bf01348170dd98a71d653df364efb5841bf45a9b72980c4f1bc5ac5abaafca9c4c4b53c3c8ea2e2b39361b5e2001ff81e76ce0da4de9ccecc6f61e8856131845a5ab163d09bfe1f37cd1a733dbfe6a13eec840f9c5a93695f4caceef191f0b4323c24b172768708ad07716f81a15df0c2e6ae6c2ba7862d19fd62b5ceb60bac2d975b6753558e03c8e6a5e437424f325c0975e9b3873c14f56a0ef5e7b002d44056be1b0000000000000000c2b54f01000000006ea31b67e662af4f05d0886ff11bdbd6daddaa56193df904a848097c42149a46c27117b1c4ec701ee555523f457c4b2789e773195c54767ff8f3f8509c8925c5275fced06f49dbc8915be2b022e9a6ff1ebf31162cca220052603c3027cb8d5a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066f53bdd0211fdba2514aa4da4f105233bf2c0761b0bd7e4713c077583f9507e7c8f8d4cb7160b9dfe45bf28bdc00145b0eca46f2b835ec3eef6bee0ffd0247ef4adaacd8b3dee2e24159ba3ee57e6dec27672b6323917368a6380c543c700c13a0eb1cde78d27df6841fd3f9dd1686b75d5a7a5730d633396e1ce750056045e03067be382de2558dbf6d5b27b8a406848599ed85ce56b1215cdd0bc12ec89edc8032e5c29abfbfccbd97777526da65738e22b3292e9e77d7994a32d7a11e82f410c0b012e2a82040409c635941d10754fb475b52ebd92c7ee852fa87d53de3c80c9eb880a5a5d9a3147b154f25997d17bf75d8e73e6ebefec6dbffb4d6b1bf5425994032fa5b3e4da2a85d849c1c47e99edd280c7748246cf816a74f2ed2fa22c84ed01022204dca1774ed025bca78c154328d61dc78ecbcedbffaff3f55c5f3aa91d66c2020774f0734367f4443a86c25867c03235e2096e805572365d0aed7604f2756ad4030518d934a6fe596043f47aebb932f972e36f72dec134a06ca222ccc840568b70021dc7b58913a5a431b5c05f2b3de64e0d0cac546a8b2230219b8d4594063b6c68b08f21569e77707f3bdc9673ed2783620f886dd38b5520ffe2027bbaa6e4e7937ae466a40f55c29d17fe53b47848910a816dd74989b85eff80e2eb588802f8d79a689ef512fc94d8dc7c614d1f87fd3db1a2f6505f2403f7440d0d41a8a3855c9415953fc49341b2b4a7f9c518b3aa812fed4b2af01e4dccb30826ad07dfa58cb9cd889c354d1176fac6af6d10467f0e1a37a897833e17888619c33c3bd772154f8612715479ddd35aceccfe57e1cf7f4fa166ecb57d41db06eb48404534ba4d3575f3259239cf7d15791233a2e84a59a7c0a5e59ea7005cd3e1b1edf7ffb65f44185211cbcc0924b5e406f9e3fb5d4ab302b72af07ae9a270c2e491948390aedbdef640bf51d1452d2dddd51f940a4c6b3c29ad670f6d115702133f87a28fad7fed7bee9c305c9ce86e510b46bf9e40b619c0f287b407d1de3a27936cdb20c7bb2bd6f3ba97ae8b63e818951fd1b5862767f2a794fc7d84555a1edd282f0eba6f9b48e03cf5731a9be657adefea0ba3a114e9010ca574325f3f2100796d16da745d765f68ee878a7d9dbef68b493e89babfc8efb2fafce6741df0803edc881a623a3db0754af615a4aeac1ceba02b55d6d522ae3b5d417c0a92e3d77584d50e474815b0731f7a26887afb38f7531964cb11c960587cda7d6679040f7cb92300c1a29a935be8ab4a7f143f82783d9b1561de7440ea9c0b6f5cdd76a42c9aff6e2f664ffa30ff4313e6673564169484850e0048ff33467770f215f853952c1c917d5876debb0a0092344a929023b806fdae7606fb971c69a1ca41ddcdc66473fefacb4981051629588afc89ec591ceb78683a5b3129b296fb8cecf6882da0ba0a64f0c20b6a93b3d3c293e686c781b38344c4cc53d93ce0306204980a8b2fca97df58313ff182724d0f21b7c8ce1b7574d1e71f7baf81be208fc9eb0eee84d2080cfa55cc5fd25deeaad28a47067314650fbd085a70761f4d26a842df33172d69c8ca5aa547fee70df441ace74aa56b0e748e8b44898075ac0bc843df0bf6508fa77ce96c290509107292b2efe30305a29ffa58258a38d6c214a06aa5dc11e4d7cf3dda48d99444fefb86426159ee33181547f0fb65eb9e4a077fb6a14f69ae0f6bf59a59fda5df402c3fdaa90e3851ab95e573826579d441e351b8ef92a92eefa62830dd412522f76084070daed783da6825634d64c5518656c5a3f9385e24bac199f580a5b4ce3517204fd1c704e6ac9c029e251b964691d45266cf5750822ffdd91a133660abd496a5c783c9ae866ae9bc1962d4a597b6421d4b1f54bdb700a4ab68eec4194e3fe51a73a22000e1d920ea3a05d4dea2a30d1c51974f699cacbb73a9ef7b193d404b1aa9a0119c53078c6d3bac576a2041ab1678975b3c5d8825a82f86f65e7935daebf622e81ed40ba0eab851f8fe4fd38bacf529c498a00cb999f98af98dab8c2bd401449701cc6484b4759b462eaa9800fc464c214f32ce266c31b83fa789e53166ef8834d47a7c7e0f82b0b8bdc0c3ad9b409567c1a359559b29bf0632f99d1995be721de150cd5e66b55aa8749b049c611911ab3470efc0373e88549a84dd250a5b5bb73450c19ee75f8936322bfe803714b2710bb110a84583eee6c248bb2cf2b9df092d49c3b50aa041f709943b25c20b26b1e7b819cc5d28988e5668f0540d001215a2abbc25ec51912e8476006661771b62ec91ce2b7302f2717bda99e1aa704cc51a1c4e94edd2ec0d1a0ff0d3b680ff54f888210186f3116002924fb88f1a212d16c13729011e7ff0f2ff4eaff514f219f94abc0b14c667cb18f3bda0488a35b0d63c466506", "006a525253516a52", 1, -1642059239, 1537743641, "f31fbc4612090c302d47c3d20e0924c4e432e7e3e6bdf873ea35465c7b4a5934"], + ["318d451c032d02f58585bd87fdfe7d34a3a132625e5483e191c011e7df858c1c40165530e3020000000400635152ffffffffd6c7e875f2b53f1553f83b5bf191a2743048141fa96d8b119ebfd44af0f785730100000004ac006a53ffffffff0843762cc311177530ca4964339a8deafae245c82bd5af1aa1a47f964968468a030000000665ac5151515139cfdc9e01176fe50000000000066aac5165ac5188b3f0840128e59304000000000000000000000000b6695e2c64f37b422f7ae4ed18b639f8092aa14c5469a8f010f13c634438d9c6527dcd43614cb8b5eff669bce275b9192f9ec3af1705f3c5ab031de8cb818cafe998780efc605f9d52ed4c23f6a612afdd308c7748ad8456a38bba4eea7d5a940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027b1964ed9fe7d1864596ac80920207ef566ef8231aa5028db8f9bffe54189f0ff111b7c2be0871a814d97e8f037f15cbbebb39bf3726733913eace33fa2d8747902cd85d2e00dfb601e04d3d5c6b912ac0c7343cd3c11edd4e0450e5893a0ce3ede1eb7c9917ddcde9e0edece6bed000ba17a050ee42801b29b4d746ef834c303302e25f92dc69c4eccedab8715907b2627703e5ef50e03d738538abe1b485e480207f6dc4cd8eb95863a4376b0f17666294bcd45f5801ac31d02cb2203dc9f25550b04539cde62d0be14218356fcb2fbeb387d5d8b0d29959b1c82771f975628967295dbceb35003b202a89839c78508a624f6966587c45e8f4dc2e2ff686dc44eea030459498356e9e228a4daf2afe1d81ae102a11f979f44b8cfd957926742475511021edae7e64139f5d4f7728a705795597316b522fbceb040ed3fba3c06226472e30204bb2c9b82b1429c6638e0aecabc80405810d00eccfb838c8d8664654a5dca82022899565553a7d9658c70ad684e1868b0cfe42fe31961fc7b43ce620d954d19a00215df43cb50266430198fe038037ab3f6cb9cbb6b9cf581d8e0d2af2fbd9b28b9f3a23357b727aa8c772c027be5f39d07c08a0562ca1c4074f54b5d060c3b77d0bda511e4cd2ce5a4df87bb53dea1e325c60296953c4f508ce920833c5f273612cfab727e61504c29fc667e245bf6125fa6a665b8fcd6809a0ddde926970956b19f8e2b08fe74fbe04a25defefd38ac9b6f50460d7e00cfbfbe6687c3447547fc1b33fc3cff070766e428cdbc0e9c61a24b78acbb9c845702dbdc6717c77486210de49c14f302b915509a32bb9a0158402f3fda2a45865969554ea20de82013b09b0cbed364ca0c0eec9a4ff2a6127cd9fa71331c259d4ceff91b92f1b6c5dc9f52860e06dc16873f0815317c6540ba9748c7f277aaa626ca0dc1e01aab18e18e64fc87ac5a6af810413aac73af3511e9bf22614fdfc7c31df445e6cee581e375d0235d7b5c378e183984a37e2a8c4177d77f61c1e2e14a6c0b54d009209f643755964352c5b5936c2083e9be252f8989d93d4741ad5c8d6bb464d5606962abc8a4ac557ca7f4bc9c39249c4056711fffa4e111c5482fc6e5f582e917561269220b99a5264b50c95e0b4638a08b978abfa0cc2bacb701193bf97b70f065aad177f3f50cae2e9ece9d2e0e39cd2fb1d1b08e1ccfc880edf744d63f9876a89d4e2431822d2a7a543b84dd5ee080a09b64a432e7ad9ab5b7ffe9c68698c31f05c20bc95904c2d94b7360e381a37167f820284dd2447ba660f108be8e77e93b2968ddc4ea11f4d9ae148292dbb9d75f232f98755f6b6b9fb94645d0bb37b783f8d08964884ebbdc9f15db5e458bd7ca3633e3ee790c744ba6e7bb8528eec5275e7c58fbc9680c2a105011e5e22b8dc14f2c626a2e4de3b41efb811a56fd30a68691a6d21ced269a2c90c146f7bc76fc3c60bf4886c5908333b4035b114ee9a923d41b71f93d48f8e304f5a605be28d2f093a6aa1467d156bcd148087fac7a07423c318073dbca227d45af0b8322028fe71782c1da074012606fd5f55ae538fb541a8cf157670d7196e2a1dbbc4210512e54f6d238638d25160ffd5c8df3a2051f1dbf065419a91b38802206b1ff5ee621fcc321cb98bd215d76677d26bf301d4dbd6931b7228ecea1651ba2cf19abb9f172b1f111c2ea9728ee518d98e0db6b4367c4dcd320838b10dfd41f6c4e50ee8fecdb8713f494c91a93327c3e0635808c044a821efcd5820ff951c3ff7f3b1ac4182f8feb243df163832d83677d97f2d0d85621c054f491af8cb84824b226b27f3d739f654298f91db20830f46ca46c3af8516efe4d8af070e2b5046dacb878fe392737d88202f2b6ee6fad1cb3a403e86f3772b09d2bff25d4e04149d2a47475192bab657c123741fb07a53ad2fe39e7ed972c629dd2a69bf514405c23fa8a023c40322cebb85254a35b935d0f6e47d079ea220c2dd466a17372137f14a4a2caabe81d7791dd181dd6522070ecb4cf1d9025585584c1bdf0a3b14cb338a779990a1c0c22d5c61543f2205eff575ba25a2c8914f1459311df0d769b6314db916a96b7d9c69516d6a292ccda8ad3445e30de8a5424703a64dc61bf488c5ab4ae7dad24c7020b46d26446bf17f2f9407f80accae9062321937924522ab85187b86a1fc142550a9d866122ac5d8d0e8aa442ebfaec962a38034fe47df96d3944dfa8895442227e818f56c167df5e602a11a5cc86c1fdf13f7e004b820bcf24181332110cd3f5920949d5a49063fda52ff4b1aee63081ce5b6185e7ecab64f98f7566dc6a42e3ccbb7affd7a9a2c259032b60edc3c358cb89abfb9123b7b64749d933b1813e88ea55da23116cce8026e19c54d7f8482d4f73c4a3a262a198ea7010db1c2c3b0b", "6a6a63515100", 1, 923629902, 1537743641, "71eee6f1a293bd9435a86b8a353ac9f09c2a84d7e73ad206a10936255072939e"], + ["030000807082c403029fe906fefa4f73f6dd8f3cf7a1da1a66c7a712424f452d2b9e5c25817defa76202000000080065ac51006aacacfa2138ff9bcdcab67164ef0d14b1bbd12596d3680b80a194c46a7653686e33b2bb1768aa02000000076300006551ac63ffffffff04ef7b3502000000000165154a1e05000000000752535365ac65ac5372d3040000000009535151536a00ac635231a202020000000002636300000000000000000200000000000000002c8b910100000000b43f125633d5508153a3c2c5595ffcffe2f98602673c6919677a16f0ef3a114d347b905fe7dbea6909bc4a9c29904a150a9c059a085cf1d83c638b6eb011adc8327f01f8e275bab6236a82d1af3ab74e4a43beed634e5f160acd056bdec196bd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004efc346aef9c3979ca803ca86a2fbe1f8d1760ab2a4941cdf78306344325f9c7bd318a497e843142b739818157c63e3a8b1703381fef955cab1af2a8f73390f35b26b23a6584606a6491c80098c08c0f530b31178b6dcc651f690045437c71e33d482a63a5a7710434123ac592981633172d9d7def02e46a45f578e00bcaf1c021394f0a2341a31526bf8571a25bb93e80282097a991978d9e5e457aa43b5688b0327d61fbfb46c14c1e03c4623a8b0054b9da00c6031e39e5b2443c9212249b86e0b049348bff216f972e048dd0f26c308a6260381453748acfb45efa612f7af5eb5f901c69469c08ac4760b87aba15aaa222f83002c090b75ab56bce95d2ffd7a99031c138a983b9ec435e40b2593bdfa975c30da036024100e4052941228777bb9a40214216fd7866ab5840cde5d029cf6a29eddf3ade5aebf8fb4558ad06f49a7c39d0300006024df3430ffa5b45b2e0e1e0e965bb7e26dc866b26495c15a0f7617e2a9031bd80d405fde3f4236e0e89282dd40ce2123a87898c7d261dd77236cd48da390032162535857f866c2f884f898f749cefb718f3960cf9cb22946317f477819be1e3e0e4bee0b9ee94fbcd8cb2382cd85f762343353aabc4650835002c77f6edc7ec62fc84c747724d9be6e62517bad65bc348d1ba6a0ef9dc0ba78ead1d082276f1a88255daea9cab0666c756ee1879f93808e7274c72614ff79923b68a15ed88dd63c65d53c0aaf4486992df31c3f49b4c6edbb904c77cc06ed6b2a9873a1ff5b6915ed3dd08c584c465f4196635ce7c45cccecdabab331345e5f0ec4681fd17bdd26bb59bd15db190c1028ca3099fd04d8ce3adf1cd255b329f78ea79429011cd774a6c9391d9f52c54f369bf5c9f1565de8040192a9967b8f71d3d44f37a61b8eceab495cb2ac6537e90caebbb90af9fac7f209ba2b780056eaf1a14ff2322a0eed5728a9b4b39809382492b9898a547fcbfb2fcf40de21fb0b23661d2216ce9ce00aef722785d20dcd6c58a1d9a2be880eabe8af42f90f2d3cb6cb254abc03d45f25a5afe94ffbba722a20ead12fae12ecd6ad414b3b9c76783a47ecb097d8c9e6840d869d9505a75d7ddede67afe6bd089cd33c4fee4ea4e5839d32301f77a3c7cf9f973c6b3fd056ab8f7beaa5437e0255dca2638bcc92b1fc84f30e8de7c4814327f9ef7b4f420e133d376b9ace4370dbbc52cd8b6add99a60200af7429768a9071f36c3ad1c1fbe4c1e1431cb4de68966f908ecfb9d9ae1d3c5ad7ac2cecd6c02349e2fdc85a3bce5cfd45dd59ca572c761322205642adbe5b88ff1c5b078c7f5e5556ad68c0e1a38432e934dd290e2bf42f0f086b31aca929a5e302028f80ea5a57c4ffc3618716f0f0522da99653a66653a455fcf59beec3c5b68e3435219fc25e7633132d7a37114d9fd4eec77389ab1ed265b37c65f36575cd3cef9c3667af3609569b12d0463ff65ce86f692fc32bf42c250b45d1ba1bbd7a9a7ee0c5c6674f7dffe1384c7768ed7c27de43cd6d70a1aff4becd67e0a429914c2128fb7b1d8dfc5b04956fc0898553e71a98b0b96a24e1b89baba9cfe979ec6542982b5fa2f549f1fa2a84dbeb0399e4efc04e6649c65c442ebe60b4690402e4032b19d6cb774e8f8715c0bf28b7e073601766d33832288019df1261ef31bff3fc5d9262cfb92846bc5768f04e82f8e32d2db454c8003ef39187a96c3847711bfe69ed6e9fab016865045413de6ce67687dc379e97754cadb34860519e649be171aa1adf993fbf16019fba5bfb22fff4d25b2052438ef00ae89debaf3a40a7cd576081fd899fa32773fd863f28d5f4e31b8aed349ceab60cf6dbd950511577802320c4b1077d32e6ea7164d89218c9df2e21c3405983dff795a5f797d726f9afc19df599d2a2029c78d75e7cd3a89d59da63dc05245096ab4a568a17a586e3feb67c123f6d0d73dd5123122e113d749852565ed73d99f910758088eeee1ae0943fc5362c64f497f120bb978635a26e426a1462c5ba8b0fe8bf266798a2ae2f7a781de666b84986f056a9c791ed082fa64b047b9f4d2ffb38a60d86cceb558bdcab22681250a448846236a393ff353bb381b1df108ca18f1734a368eab609d4d02d1f6f636fbd802b8e3c83a217efd27c01addd8da68c48b0748609432f4f78ee9b191f0dad0479d170d2a85262ddfa5fb15661b0ae92af4e2c2cf73c87e184141dc1f35134dd047b5a90ebc013c9bc22f3b070b9082de1d7093a027ba148d9a787d17cce08a46832b5df5c8618933bc7da24fb37edac020000000000000000000000000c34eeec8016a89781008a3e90ed594cc4f7f56569698e3a2b88794cae1724b4d720240441e8418d42865df49e3b4f4b06824b93347210062d459697e4bca531d457199df56c11ad93580572522217253eab437bdda0bbb9dfa09d021fcd4def00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e05b25ad910467f6c40e6622e6ba688b10dcde4e4d431ffed7a0632fb5d550422e9917a83b44d45d75ebfaed2fb8622585cab9045dd0c6801dcb6fff703f47111efcdb2cbd94759a09367fafbafcbf7b909315706c3bb3976ac6a6212a67b6308f419d44fae1a636fb278528faceb29695abd579221592edaafa62ca3c1408a00219db418fb85acfd30d72e69b646c419402d6854a036c43a0226d646f58b4c492032773c3809c7bd18b8d74d5c1b5ae1c208ef15869d7593d8f24e13bb39c7527500a056c8cd33c73cfdbdf70e72787f55c6325c043321a683805da6937ca4af48a0058d980eaac96dbc54b9c8ecc7c1b4ecb0b16741e8402d87e7eada738c00f54550311ae14dcf7742d4773f5a4c00411b93323acdea1e3fc3c5d40cf319788195b6c03070c20baae942a2f361071d9fa7619ebc78f9a21dc7f29110ad5ccfc6ea474e70201dda5b627a9a1213510879cf74066f32da5dc14d904dc956faf99c0aa5bfff2022a6276d25d36cfc007944dd286d2c69bb822426b176b57e79064bb700ab7c4f1021d4e082fa6b0398d9bf06bd58b676402e93fafd8f950309284ed8f452d5722850ae281c9958fc72b688ebd713a77578592d83d8783912d5790ec9a22c6b94dc24274375a27c448c16bc3d278d72a692cea3730300a44fa0ac75a12da2f2589593052417ba0745eb25a6561f9ebd37cff432105ea5fec8fe75539db04ed36606a0a2540158764515d5d50964b13a3ecd6b6934c80a28fb164f726b0d3757eeb9f8f5222d7968b7258e50a475bcc191f5c577b03bfd7883561f23e00d7c024d01a8ca2df60cced35b3c4eb9b50cd5d7d99c4dde4e803eaba7b4964edca1071a16de54f92ac80290803ffac81d2733d622675d8f7907f81848cd131274daef896f183db115a6cd0f644b5cee70cbdaad43f0eff9b2d195506af1ef8f5b93e17274ea0d08a209b3a054d354f044e19895f0825ed73ddd16e7083c65e80751e5abc12702b9f3653eb73f1749fe94361ffb3a77d16fbb6130223beeed393d0937660231846d6a6cb9065d09acf8e2e51b7c2fbf26e5eba498a0b6ba8096b4b8e1b4ddd2060001063192a0e72e6cf5755570450b611530dfef668d298d26ab4d14f4076d0e2726739dcf70517f2e88867ce4ea2e6894d3938127135fabc6d31a9f54f1ecdf02bce443ed2632bdfe8fd8f65696594f85c039a5d84d89d334099773ea184731dbc9f3bc9c3247e27cc739300eca0e0e262d9e2ce92b879e38098a6a113b36a906e9c4af71a05ac83c7c6e7a4d9aed9597e069f40ac4d941451c2f2cb8bd38f28c9a0dffc0ed70b34981fe4556a3e4bad20b91695d04b8ae0d9ad10c794f37620ba56585924b49a31ee78c5299782fc77aa27de9076cdc8989773ea9b3c1fa7a40ac741def8fec27c4e09b385976d900b94f10b2e1cfa24c56f421fe9f7603189cb2989c484e3d8b97d5a2201003ddabbf7bb55facd7d820258cbe2d42e925606cb0812672a6f187c155a5fd6e7a7675b618cd5bf59cf2fdaea3edc03e36dc3f820ed8fdb195d9fe3e783b3fe719231cce5c19c8793090f7d43f26e7cf540d7f2a16659a2c9819d27e42daf59ea751ef0ede3fb4b4febeffa56e90f5d8a1b6810d81ecc9a41e34f8f1ad17479c2ef22b42b419b2a81fa7e5d8e8c5ac0f9d22dbc891ea53c03849f56b8e724361fd96cea8bb37b6d8de6a193d5640382ae8b35a4ca61a6b459440a1de34f831984e8a2e2bb69755792c934f7dc2d3bff8629d9b0ac0a5e983cda7066d8f03d48e510c4068728eb25c25a6ba58ad794078c9f1e541dbef9e9cf0372608a9cfeedcdee4240d13e290f0339b7cf73800e227ea2d61899d5b2260fdf3675347377eee9828aeafd4fcbf84b8dbf887bb0f4396b5e84e5f3305bb29e650f5c35538692edaba2133ddcb276144401888715ef0d02f19b0de2f494c1c10d361c618ae04dc5f73dbf3191a3c5dea6b2877c7b8ac6048889304ed24bb574d9f26ce5f71f9f5a834d6eaf87775abbcb235dd491ccdfa1648b899aefa091416b0ff2a37731d5fbb67f839756b090ac452b3ec33061ef62a052559c1952663ca0e62fa6f953351aaa75a6708d5249ad445e821df992e2521092d06c2d5c584ae8a09c80c25d43768cb8610bda6fc385e1409ceaaaa46ee41618af50f1e33128393b67c6fcbd0cbb5894d93ad70ee539c9f1071bedeb5fd42b86df2b49267a16641a5204b8cde63324494be571728812c02c132e0e2de63dd4f28663c9d1d6c72a20ec236aadc3e09a8ef3f8798862d4b31aa46dc39faf1034d3ea1b6f41f0eb8f83ffe2388369b5e7851483c7d1128c56bc11f690bca433ff0a80bf48aabbaee55c18207442bf8e230c1452feb4b65813f485e2538710f7511950ec2555b400eef5c6434763e82cb2d20c", "536a65", 0, -712243267, 1537743641, "1935fdcfba6dc80c8c6c58f31081e27be38e26f29adfb7435e163d3ebada414d"], + ["c73534020173cb4c8787255cf5633c40d15cd24ae9d8e05e62b4d949adb766e5736a1b2be801000000046551ac53ffffffff04918153020000000004006aacac644110020000000007525353655252527ff63f05000000000952526a63535151516a0e8c070400000000036aac000000000001000000000000000089f8e1020000000081932c3d591c2e08a1ce45865d8948864974bf7d7252dfa6ae85e8391cb0f8a9e93efc169f3a5b7314083ca72df4773f80e762aa588398d343da755ea0369c27eb5374e50f934e5078838f2c782304e0230b47b67de3b70daadf88fadf8c25ef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000541b544824530891b4c6f05b8a3a1501b468ce0f2b75eb089459e073a60080d8e7fbe651f12940e36c48304904139577910a81c5ce2fbb9cc63519c82f2438ba6f55d5763f0bcf47fa37fde4c4e6d8369e9a410e7abc882143a7b7acf8d1fc88e4eb523842698c747df27bd371ca6cc43104cde932f8942842c5ef5f270e5fea03154d6016136fa2fdd6e32c33a92b9417a9fe813011b9b35ddc49607197682ac5032f3a8746f51f478455da8fa8f6574a3458c492753951606d19f73c537fd773430a072adabb0429369ee533de8cbba5c38fabcd719c5fe422526dccc023b2c0b7af70c892226bcdb3e8015547e5d301872be8871c0e24eef6d997634874a8b91d34030d9ea3c35f45d509b70a9b9e4d0bd83ef32d888fcd7c8bc9091a6e1c15cf5e27020bd4ec6f51189a11bbcc211a131b99b1d50fcb4fbb3bb72fb7bd5a22d2ca454f030586804f555d8d6373e64fb2c5754cf2e8eafb162e24931759d87f4ed9a9b7b4021a417a4f867193078ffc9f56341824bda48ecac2f90651f41619c1336855407e03235cf4533d49933c80c0633d7d692e67b49f6db58015f1414f18c05f262e96a5db665162ed0c2eff400f7d72f531269f786ad55594e55415b7c8461f5346103abaee30f04871274c4ec05e4344f80c2556b16834d1a90884116c9048119bd067f8d1e1ed7ea48826ee6b77291fa023c4253ae338bb1119a1a8b5057080beebd31f53f8b63a64186d5b8740fd6eaf8e8bb5ddf2d4ce0d9b4b0d3513cc42c42116e93487898815c2b2b227f654a1e7b1ea0483691481f75540fa074a3cac82254d10e576f1370193f3e4a444d549c4b687b3bd2f6ac625ea5af1e2bfeb60823351787a71d5f93744c552d094c5caecff69204376ceada599921ee8e84bfd79cc94f5a166e31d4b2017e96f8c9443765cef86e665da2ec50036a00d774201bc4a1c94a188f438c5f885e3cbed28b343a17e8bdbb16b116dfe6b06749d55f7b38b251fc64423f3f3d2dcbae4f194fd9b631152fa77f7b7b9050bc29fd621c0ff13d68c5ae3e056fd1e2baf2a9c4c6156c2747f5ac2924bb9cf3c21ec6bae17934231dbcbb3ee268fd79e56a74c8e030c451bef32354d97c3d4525d10423c7e2a84ac2a386189e7b2b5a8a7bb7259d429af52119358b63310d00579de60e0fd397c819399c7673f3a033d46968e1ec78638ae36e9d9eae5d2506ec9905c47522d19121b619bc4ca605862ce07bcb88d59ee2ef451ff59a361fc98444b10f65cd8875f3aaea6c5f0a9e211ebc77169b0310a5928ec93e94250a7827173870d69b48c0204a48b2f0e0c818e5a742e134c08908001bd2b72e3f73578a2f0bff1920ba8f9038847da9072753dcaf3b1997408989e494a0f9b0c3847ba634f5b3bd33f9072a37a781e16e7b7fa31b6ed09e08d7c4440304f01963c08a5984f57c10fc5e2a52aa58ccce85353a9b99965484f21fc9a8c35e66c3d0cc454ab0bac346766e3a18266956fe853a885dab341ecaadddc5febb8a2127c0f56d6048e757fb348384cfc3a07a22ab03be5e02f3384902102375b72d64cb2e865f221a459bd20fdde303dfeeb386dc0039da0894f56cacfb26094ba8f319ff057498cf4a3e5b5dd204d5a453f3522aaef90d053d3eb7497fda9090303d37fce7f704e06ee85ead6e8cbb2f9c684974b56b6e376a148b5afdf3fe18f37d99979cacf75ee6f753338d92983360bfe112d3422f15523a2be4df5fc8b61bd0e21ebff094130023078945deb0f3015a1e01f1360ef2bfeb1068cb987b9841b6b83aa6173578e22fbd46aa6788d1c92e5118da8c6b92610fb244de2d9099992a2e01de0c37e461d601e1bc9834715dc1c4470407b872e7d5b1d8edb8a486fed2d9db6c62f9e44a257ee71b1017c14505b8fc75698b47e164f60a6e97080e03ad83d10e4a256539c3e9c0ee2f70f098cda65c5003db0c61c1715f0f52e5fe7b9cf81f9be383e73e410f2a8879062125e84bd958f00d029191b2be99df99b0990a9ff8bc1718790d1c079f56ef6b45227849346c5f208c6c2e963c63ace11d6b22298a31e87e9562c9ef00b072bd2c99b8a59820b3df81d397f2efb0179227ff8144d157a44f6bc4f55643ad8dd92d01c98370df06a0b7131fb902f793c438cbe63dd1f9d42492d5c3ac28a4a0b879bfa40ee649d0cf4144a270c94b254dc01ab6ba4d0a8c7e48d5992ea42eea7baee8bb46bd7a0c35c4a0daefd27c964feda50b56ac9f9b45fee7b0caa7c5112f4dd84c5b2877ae346d647d7c29b85cfe01a10885c624fe19046747af6be65c70e7fa451b1192494d3106c62a36ca0c9e0794a607d7e66097d34bbb319c602b848267e7d5a67836e2566360f3af4be65fa9e0169d8af37c77fb06c4110b2e05100d27892d64646ba0d63a2cf362b21025207", "", 0, -1688897625, 0, "4aab73ad22fd39cb77ccd6629f32ec29bbf211877a43b607798ecc8f40dafdd2"], + ["030000807082c40304f33fc0efdb9d008851d0443456d286a6cbb0f679d6bac02853f0c407ce13fb1c02000000096a5200655352005252089149568a972b1d2a40c938a2402e42fa7f59713becd55d623781adb46ecd057b0f6c250100000009520063ac52ac516a521aa8074534c48adc8e83d9dd4782ede9efe4ff3692bfed02a57b02ffa2aa2ee4d127ca3e00000000025163d4684ba8daceba1813e62f8dccaa68f39c23a2a462941aa135bbd468f1a2f8ed0c6c384301000000096a6500516a63536551ffffffff01c639010200000000056aac6a00000000000081c44acd0300000000000000001a97cb040000000024d4a35c7cba7ea431ce32c4e6627511fb9209a8d7d42dd172f024d4d0d8f94613da5ca7f5fbe4d53383fe457750571fd91a0b7233ba9768a4751c6ce31302c5515084a5906b7b4a9e93fa4bee97f201e95dd085d666134842bdd92eb5560d6e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c4d162047d3224d8a0f00ccf9400171d789a5a7826013ee503309f2ecbde818c55676a0e0d5b7d11a97f31d29fa7a1619c44729cfa4a44d102a9f511f48372adc99ab9a3d62bd57a66784bbf114eb66ab0be43c4f97b4516104efbf6473e0a4b0b6dde2feae3685f5b1a89cdd3cec54a38241a616d49ba8c85ea78b13af3e6a031baafa53cb749272e0ce597ac46a56fdbddbcc507d90d91e631f54ed81ff47a60213fb3e8197e74687c140bbbc1e4ce284b72b110b35c4932f414f3ab591698f650a07533c3b144e100a90419079895a59b2280c874daaf09b49cd9a1b464548fc80bfc482b39f84e782ef3829c5aeaa3ad1a9bba4562f9588c1b628c36e8130ae4f020a36a75ca6906020869bc8fbcea803c7ebe2d4b7b46f745486edb9f7b30edcdf032aa18aa37f338be6cebe41b9b7a863c300a41f210f53a76ccbc00e1183188203021e0097fb7519107dd85af9077f3788039389c6cc7b4aec6538c3a2204ab31889033006facb32447fecb680f48a4c354aab87e3fec121d294370e3c2d8c4450359002083598c65e7e4ced6eb3cc0edbc9eda6e2f78e19c49e26257f80a695fba035e0c83a409a17b3047fc83f13c94be0c77c5c05f69503224e31a83ea765024a95bc555326601ff620434b4d2aee2323cba8d8628287065f903424ca9c1327675b3c9893f01301c6d19eb5225da4efaae3399e5350d757c241dd7149daaae35bb1da6f06f956d38dc2083680c47cde541c9e625a3684c8af2b32e5134ba8552626ec8f5c51eacf117989cffa45839cedea17078e2e0af2673c3e00e6e1a15d8bb9d5d4587a4c7a87a5c833ff7f20061dd33bbe5861bb67e28a4b71d5b13a5ba58b9129b1b9659dbb27f5fd52a14a359ec5ae38ac2540cad91d854919689f51cce3a5ff3090b220e6e560132230bdbf51a98c33951a3fb35b20ce3704fae848327a15521a2abde0defc03521a351cfcce8886a6d5198e3907f6283032584280ef14be27f1616d79a694b3408cbd43f1a590792ee7d8813f9cbbe2ec2bfc1df1e0dba7be9f491f712e2b3c229bd4090c90726e2eb0d52bef736237bc07101893c2457055c8c93c1e35e3b6f27f52b1722775dd6729f2cbb4f84f9bc8b34ade0663cac0e2d3b1503cff9432c5625b84bce917549baa2f41dc7815bd5a2c77f056441293aafd03dc4e0247a543f6278fd5494457569eb3b0cbf692cf03e8e224ddf1c2810f4cd2709d99b112467827522a3c158923ab9193e25e43171cdc45963c7cb1c38de4bc3502c158d1d0eb0e5f2f27112901cb814a642757950af311d3f08eee27b0a6e8b6bd42c6dfcdcdcb15dfa3a914f998e0374b934034227a1f8351a024a26271950e9e97570e48a2c3a5fefd6933d87bc707df965be3d52a4730567c0062270ad5ccb5e1b6732e3f9d885011137fbfdd08b48fc851c66acca797f4ce7ba731fa5c01e1a41c011d6c1038eaf7b22f4111201a5c8e07cd535a29e4c18f45e65ee1f62e6a5977cbf159392950b0355b5c5ea8cd7901a7a0255593540e32a20e4209e7f74eab6c62d2634eb32bbc70aceb731827fe2734111c9e3942df7b5a34aafa30fff7294610f76fbfa75c386feec7e648900f01122e6188ea456e6d1531f64604e698ca8ca02fbd8c5687d5c1345c63cbc7787a28ff96ca07d36d5050494f14fbef535830fca223af40c8ab2b81dab21c9b6d97ee7701204e92d66d3ab633ace557cb8ce569a373d24ec7ea9cea65bf809c8527bc44b37492bf8e95e232354fb83d6ae7813bcf442c6e461fa7ef64c176e16d9cadb1fd87422da8765879d572a4b776e90f438c5a6061f26e34df605cc7419aebaed6c15fbf0ab91dfc3bdecdb145783bb69ed9a878daa0de3d4dd410521a3948b47a2d0a5a593624698b86e832a9e16283852c0f201785833370edc5ddc22336f831d4d671a67aa4cd03ba89be11bca7139822af4a7a399d14341f8701d3dfa61766e1fbd577d2e39a1833b7b3b7d4793eb1a5397a08a43bf631acee1ea6e623077dafe122df69018174b11721039ab1747bf32f0d47e0d05ac0ad35565caf548ef22c4c2def3945d960b9edd63ceb6239c6e35bf50de88277e264f3f8bf1b46971fe79c95450bd951a5c18a15a9d5017bb665bb8d6ad230e58d27136b757e68b98b3bf1ca96b4b683c5c62ff22fb66bdaae5735e03580b76733834ddfc230b8468703e6bccee7659760975968f43a7f1b12dc59ac87790e3a1ab25616ec3a31b3a64a6a4a8b8f99778d3dcf7387f2508a908f8c8bf60122670399af0000000000000000402e7d0100000000dc859508e1ffea21fff911bc203faca4437dc8277acc898829b61bee82bc88beb8e0ff2eb165770767fd22ce258388e69c36a37510313a75d165cacd17cc5d7fad1a96497edf76c70ef9c1c5772883c2e13ec2a04d8bb0976021e5ec20e802e4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009aef70de460ea87553bb5392ec3e185606edaf5eb99af50f95c6e5e211d923f22136498b7b46cb678e7b0b34ae3662cddcf14e065afe07494035c79503e3b77dc20407831be261fc2bf13054495c5c2a85bb84522e7ce32585eb98c4dfbd10163ff57fa290efb61c9411d159d74d29bd8ac745aba8b87c44ef72e19ac4abe8720229ea2a1b47d4b1ff80c69b0f473f3cab134b6bf0c03b8df5f09d3cc2bda670310313e2164d096dba342597b95a7301aab07756ffc5f2da8502cdf947180505dbfa0a09225dcab918272f9413ebd17a84da8b430b62b2e7e6489df870a299c58e219edc39f8980f61281492db4a5c72628efda2d6cfdbb03c8cdb93f780e4373a8c8e0209801ac3a0174b16d7756e273348eb51f79a4f812c370ff4bb81c15c612228b6020426cb95bcdb45cfb0e19c2455e3fd3cddd8306de5001e3254ac546af192600a031704f4b70cb573dd210fd70da1e1d271abb34577533b96894c74c770c15649be032d527c0632618b73a1efd1240be3cea8cc425d7a63944be9df51884b32526ad40227b4c06aeef908b5f764cad49e74e6757c6ae9241aa655c5c4f67cd90586d20c3f8bc6771a4a0e7f330f2c8055fcfee441af26f21dc11f1e05006632cea0d1dd31c3b08217c166430cec80a2958270c7ea5a73e00de35ac8f0ef7ab6e9cfda264bb601ad61f65a4eef6a48e43659a381b4c8148239e1c5b58a4473bce3ac8e06a80b6835cbc8fecfaf3241e4f3c81f204bf2684ed8a06fb7ac5d93150b275be3639b3e5a530af5c08d50374179cde0c8d421eb86345168f62b948116837ab6d69766216edfe992bae48e4c198be14510e152d7c96f4bb927a9d9edf7401afc5eb6c2d1a2dcc484cfcd0128eeb576e5ce1c93eb4421e843ecee3f5880e901f60174e4a2d215949d6d6b03f3a392e9e35f53ea8092f8c914fc359c3749d9a318fb16186696a14d1d409bab9233e0544d3e2f90adc798b888be45cc3b3c5b4f05a978577ba9c89bf464481fdfa3614d643a8d5f27a26c7c6abf35242f225ae5b5d7a14377ff1adbdb18377e943c24d6e56f71c3eef2a0521c2f20ef35b039e7943b786c1106d81aacc3dbd3a3f70dc2f9bf11e0badbe92b09834c66e93fc47ca84dda642d144665762f7afa5028a89b8b7f9f5a6a7ceeb4fa0ccf221153751263765f5f945e3b691db3d09b5550f7d1264518c3a44d62947abd16e2554f4b840415e0cbe6ffd8fb052d021d839f3859ff0c71217f552695ce151f6bdce28a3359f5de64a2b8fbca1df540ed2b24d4f4bb46efaca749bff3daf1cea0f069745fd9bf24e8dd55956985f11e91ec32b51fa6e58f0d60bc2b1c7c0c51529c2f532d0555e7688520494d3dcdb394931302798eaddc9b412fbbc1c50d39295a7c421232478e0ff8fec1b66813bee5c0b873075d1f98eb9e99609953e445ce2a6a48e4e7e57bfcaaf2e2c2decde8f8c637264e4a8c7feb3df87c2211ffcbcb044e2d01af5fbb02cac4e1eb6dfa31300786d8bc18a91c91877a6cbd225716723f0592d3b54b5e5c4d6c3e398928774364744e490e12ec6dd24fef9ff48325e0e338b00903e7f24f5f0051eec3f257a563a0638bd6bf5d352674d49008fd148cb57d5b9d7256a87236792ae153246c2a3a80897a8a100d57440e2b1fee643eefc4255ec242a080f688775e819cab1a2aa90314e943260c48743e066a89e8fcce3ca3d53293b25cb07cc70981249f5671c644594633391fa7b6ae862e1d84be39f286ead9b17fcdac1880c3c6bd8363772ee1d666b12205e69a5b506182dff09a125f1de2bd944e3f07f669cbd7d046a34c58a4232c6793ab0cf9bc74c37616a96d71467fa378803c3f1948ded325f2a435dc42d05266e8b271287e2d34837743bbec5849c8b7e9f6ae585f2ff0a2ad1db267eeb2e54d3ec2372ca63ddaa863b6f1113b9c25330298bd17ff334baa32d9d645767de755648fcb6b2ffe8cf9e2568da1cdd97db48990b691ad84314dd4884705b3f2188021e82bc69b9fc66fee15df40d0e8ded58bdd1490bcd48c537e39f0da738e9fa9e38db146fa4878d8847a0681104c0d76504f82c5b7d3bb2d4caa833947c0ccdbc9dc81bedf63fb941724e405c94a7af29f96885687cd8898efcd489f967e84578e451aa30739b7b7467285c554e6946db266a1b2ef343134fd2ec88dc8566d276778bdb788fc0ea405d8a4def86591c3f130944e5a6384da5b21bdf742fc0956481cb14930bbd587a2d099a549149d380491c18910909835e793aafb85760a49c3a90000000000000000cb50430300000000cdc7684fe800e86b09fb49f62b5fdce57cd4911f68dfedbefee830e0a77a2934469f6ecc4a3a88ef9dee3a7ddd45b9300e79d4184b8e6e4103e4867ca118fe10002fdd7d50cae6caf86bb9b2945a4d4c4a91a4ff2e50218c60f8848089a1d90800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc9b540bc241ad2659dc334d30911326fcff8c84343adee4f9b8255ad6cf6fbd5e5850296f7e446bd2615b21d08e91ce2498c8a9f7599ddf21d4cbf13000593bb902a55ba110749a96f64d5f1644d2a6e9c248da8f55f8c18c85ea9d64c7eec35bf38702ba6a8f3e5154d54ec47998dc48738fc66c27e5f26907cfa4bd0a1fb703062537af42ec143e9421bc7b43aa736cdd791aacdd52d9d630ce90154fb1d4810211050b1e0f345d0ecddc1dc7b03be6f8e7087415ccc9ec56c9f335216cc22da90b073edd443ef352ff75a9fb24c4e6bb781c7fe2dddb79a05c819fb648f8b3214990f2672c512dd49a1e69602e8e5cbe52b9c9dfdb3efb4ef808bc5ed5c9131e49031c92aa4829212b7a15a6e9e6bf56251dec8afd0669f8dab0a0abb64de141d908031f758afdacf5398ba07dea9715e6ac39b0ed5558be44398ca8577d492fd8623203151a06e98fbbafcc05111630dc553b8a0001c6a7e1ab6e3fe9d402f61403023d0315dcdaec637c2dcab43c43d7c04f12f1b147545da3a911fcf0750eee0eb6041f021fa8fc933de4dcc53021b38777112f8daa86581b1cc519b5842c37ad69b6438251eddb39f1d2b9597202524f5a36b3505a9708c8c258f973fd2e4436234f551b5e9ccfa008308892333525fe58045f7c577c01d70d184eea484fc451b1fc95bcffc614dbce0050f051176acce116e162dd69b5952538694c1ec28a32b4a463b5dd54b5eeafc149e38507712625c0746d66546012164c5e6f2fbb98edec8cacd68b7b21b5d54a80ac0755c9a06d8fad4066632c007a0dd5f708cbc00092b0b105d0f70546b87b8a703084b1a0b73ad6f8538a02c85525f09ee3dc6741ca562a74f4fac6060fa83ec791daf0e0fc2b5a2c64b79e637a71650712e0dbfcb55a35f67680d5ad45fe89911a17d650cea61cfe373036b41165629a053b22a70860d71d10dc3c6eebce827918c50c7a9eaec255c0efef071b5952db22272b94200ca781622d16598e74982d4898e6936df4183474524c0c56110169b0581be42efd4e4b0e7ba971a31223d526a76290259587770890561f7fe207287b6ba2c05b29c22ef49bf4198c66c0320270bfbab718983bb0b8af5b3c593fec228caef42c1358f0c44e22eb683991d0c7cc7e463ef45859c0538f616df1f50314a543f825e41044f7015b381ca0aab0972228393b9fc9ad387717c90b42152b25cd4ac9d1e6bf4ea5be1bff124dba17566a5b7ef0437efbba19a977f625bf515bf9d378b5fa2df4614c2a3629b3815b93a1f91aa4d3bd8fba9ddccb1e2391169269e9ac7c49470d58591a4d13b932c0925139c409b71b2fee3e6d93f2517eee4055e8ed608a2158d6cd9696ebfaf505e41250cda1b919a07b2e694b725a873615e208d4a9d79c922992c5143b3d8290c3f72dfa425ea10b60abd2d3432d006fb0fe20397ed259c700c81e0424cb0afe2b1e951f5923e422708d341c75e9dbbd469593ea3cba5e16f613918c127aaaec2f857284c776586710f1d1ac7de2278405558472aadd1cc5dabdc5bd658f3668caf995390dab0b25fe0659e6647669b03e397a80444c7f491248842d5e6ec0698dc3cdac9d2a4e393858d31946f1ad69cc493f9a61d291589c0250e090481678e1808204f40e146b03f2820f0d40df89f5e4bd7211a3202267b54557fee7db7d2b1b245d339feca9a28232ea9ed01dbe0581c87a6a88563c62d38c717bcfb152a83796db91b6c7aa633fceda0a222279cffb479c940aa5e8d515aa680fc698a50f04abeb93474376a6eb7cc9121593bba1ec8ea28ef5a988838e340afc76940297c84bddc337f79b401fddf6912704a0745590486856e2f1a22d35da28b969ae54314ee6e7fa07df67cb12f800e1bf8cc8e6c96e9893749a97c9480945c79db93ed08d1aea3afebf1643c1705cf70f9ee8684a625817c0cac0d7a27e901b72eec5e959cc38cd02d084f06b745c57c53f38446a6ab9222137ba219f680d6016906c96a506bf607c9ca5d4ba927d0c3f8a8c78bdb3e31959d51442aa960b52e208c0a4187bce238ee35623a77f917f4b7f908ccd518655661fa613e8033e91e9f5ae46636d41fe3dbe0d324ab6126b9d1c4c25cfb368d63572461570b90db7b0844e7eb7c1902217f5300df2a2fc1f2991fb8292f097426827821eb935b88f6f9f1dd7d636c566f15abd6050600a60bef8b1642cbbdf6387c8f7e768b10ab8dbc410c287d48e65e286583703c0cb2719347184c8999fe10b95e937f146894eb9c3c921c236ca9b6aa8ac4ccee213d5000f522918e8bccddcb4f32aaf52f90305ebe8170280e87b0af4316d94a4de0f94063500a4b748793d351efa8fd92b271c1a9d6e752a20c260705c9fdb08aaa700a7b21da3e90b533b42cc361ba6ff5ce9e090e04e8ccbd71f287a01", "ac5352ac", 2, -1598984668, 1537743641, "7aebf228f8607965b61f661229ec01a68377cbc7ea698998e8489f376f3b191f"], + ["030000807082c40303cea79b40ba32cdd967437a5398c4f4a47f0e7cf74a525c1f1ee2e27e209fa5900300000007ac5352006a6a6affffffff12c64c53214867aa693404e801cf14b9e72c0296969fa8ea56760a28f5b7f75c0200000007005300ac0052acb2bb78421bb4b2ea23e3ad695c7d270d940a5cae4d9243c679fcabf0d65bb28f56ef292d030000000600006aac0000ffffffff015d3ff70400000000066a5200ac6552000000000000000000", "00acac53536a53", 1, -1148597380, 1537743641, "bddde3d0e6cfbb2fac078a9a12082387d7a45c77e1d5a529b233aebe1f8f9265"], + ["030000807082c40302cdebd9ed8036faf39656adfc772b82b425fb1d16235c1c2b9c011791706b92fd030000000300ac51b2732acc2681ff382bb74a085f2b675ac78fa2542375002605a55160a5fe87829d329d7b01000000036a00acffffffff01197c5d020000000008ac51005252656a00000000001da38d6e00", "51", 0, 2022922069, 1537743641, "7f7b8550d600bcd23ece3776e840a5717c2c65aa818c0b684cd7bd8a2aeab080"], + ["030000807082c4030173ac7c1b3d0bc7e21cbff9b8c503416ede9342273e90782c1d23411639372d480300000001538206abe601a28caa030000000009516a6a65526a516353e671de4e00000000010000000000000000161ba70400000000d2304dd426d45ab894119d19c405dc1bcb60f093cdf8fffb0686e7d96422feda8952b99c3c80f54b1b73542c913dfce1df6dbf3cae2c5367eb68ad8fb07f4d93408e9d5c1b1950b6b0b15c51457dc49593ec75b96462ee6ba30dc63dbd5dda40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d1f7e39e799533e56d2cb5edf1e3903cb061d2675d5b8a574c372d9d5fcb1b4d2e7d604fb20fd8bdecf5c6b8de281f965d4a902ee336c646282efadf533e526c64e5e8e831264631af4c08db1402eafbd7f3d905cd95aa6161ea8db5f0e13b8502b53ae1461aa9d6c97bd0215bd765ef87dfcddd6cd6b403632e35ebaa2a2d4020158be32a2ee08d826431f992a8e027bb963664c99dec2de10bb7f9c8261823e030e14471f4e95dee47a0a6c4705a2cfc047f8124ef939292cc047d5e5ad22231a0a0921a2e568f6aafc6c4f568c15696998959cc30c798ee420418e6659e8b286123633a74d6230a7ef954ee922d714df51ff18c5f4cb946479feaafb706cdf722c022c0be9a5d791bc6a0ee06e5f5aca29c009a083226f603e455f399f520742287c0220536fb09b1ef0217536daf974a1c04abb206db7645e4ef3a602bfcd282621e3031b678339eb92602945903186c5bcd9cb01d7007e4b8c5407c413522caf2b7148030635906c28c4633b186b6602660bef74a1fbb30a167101deed9056e19199f87b030c83f235b53d3bbd5560e206cf3d13cc079e700ea0e8e4e8b2a2dc1a73bb4c2c48fd17e52fcc821ae8716b953646bbcf595636ad58a83e1d6ab4f85e9ccdd17fecf837e03715d2b5e66ee9983e574bdfb34ee4ff37b2471526a7fdcbe9963bceee480291788af98275cea780c21ab9c9cc74daaae0619b30c3db1b68e41a0182874945da202e596526c0a9dde4ece116b55f8402a52bc987413ed2f4aa500d2c1c3936726e6a3831260620c48c5b5fe26a9d2318ca16865b2c90b577d1e8e127a618c7c1d1034595a392b66c995aace15a47b25712c8623c9cc6d5419a742bcc5cbdc8013f0f448d29eeddecf9647242340e1f566c08bd49b3ebad56867dce8393e70c06eaa7ba1897037ee09c39dc3e0e097acbf63e653d4a383233e3c6a882789ae4813372af0226d7847f8cc98c905a3ff89447348bfc3674b6d9e64591556eca9725d6f261fe7e575fc41aa52c2aec77d6ddb31845ca974efed48aad181c8545a3f558c5d758b164539850fdd7d00716a05ad8a6f3eeff1197cc95373d4fd7090e98d9646d30ee9d192137a0532232103d6e9bc199b39bd7b366b1f94a7edefaf77b753c5d85a7426b0b0de131758d526f71cdca9aaca182b1c8c9d4ffbf2dfbf170c36c97017de8a78b596bb31e6709c9f0fc6a2cde6f91cb0eabc59be69d2ee6f01f9d56bb455e5ffb0989400873fc12804f35413110301959dcc3ff73f90ff713c9dcdbbf117805c4e59dda7b095c6b251452ce6d7ed0c4b8b8b8196c5060a0eda7a47e45d88bb9466005e0b4259509a9d51c38d78d347f8b43c02f6f108ac884077c02f97e0b609fd8634f224c9c168e559ab7e370e50385bf393337372673b10bb466da889c3b607501afc77ac0cdc96376f5ec9c229d88ae35baf598d5df6395e6e02d36f593251dabce039ece3f3bfa2c4d1c0d92cd5a29cb7f37de1237912068b3f16512cc1f6f1a56f78043f1507b47d9b66a278d08caa09436c2fbfef75c413a9c9872895788b79da6826754066243d6f515b225d2e9f0706f1f3e560d0e2d1d1735e761e513ee7a6de0561e87f989ae9732c5b70121fc5d13f26e6b18d25502f33b4116678a9b28a07bff1ff55e1192d5b4950fcb828666e33a0008806baebf439a36e7205eaba9c06071e89a8410422f7516ffb92cde1e223261bbeb8a685b4799fd58669ddfc42b918716284f72f0dd1dba8531367575b81e994b84a68c1111de4c9bb0e11c639a3aaeeed62b83360d59f617a3e248e4891ed0bc2c462d9c0bfa96c30364e1638a1a1b2b9f7c046309eff942373738fe1c10dae8a41a8da35924d20084a5eba9b28627b1976a649582317d4bdab1df7313e64172e3ed70036b95c013518d51443676e41a5ce7a5f49a95163f08c7bba7b74b3d62b68fabd1198c0ec7440d5d8a6867f725514de5f15f046d2b2f23d41d74957c8d0499d67bf00f709fea5781830688bdda84e37d45ac2c42b37d6d6f441827fc2fb4eb058e22366269bd58c009a4b7a2b7625c4c5de83d946fdaa64048640e6f78c7af2f4d71f5b0a3d440cf1289415609ef2d1bda0a124da76d001f5e33d2e9035280cf9347f9e6ad264919d3af6a0c6780a0e33880f2cfc975f2d3f33bc26539af83293f1e2b19d5a98cf1d4b5944aec2986c3dbb25d829e623fd269e9a298ab27afde94d4d0744e4aab674abca42df9dba74e4c5a99be8b27da75ec08b93f39edf4df4263cd4b1a59d4a4b8846b8f248a7df4511ff644c6aa72f6e5c284bb3a9a605859a997d6936c5022d52d321d5ac45e8f7146a93d7296d40da666e94d6465ded0202a1c74d0187cbeb1b24cf912de508994ff6e82d91904f054e7d010bf4984c88ea0362d5c4dc21d9218b308", "006a63ac6363636a", 0, 1231309953, 0, "fad09a2944ffac6caf2660f635987ac70dcfc443f5e22f1b3ecfeaefd6c3115e"], + ["030000807082c40302ff0533e0bcef4dc0dbc4b74defdaa8e6163e2be1e06be0dd151a694b46a92e4a030000000165ffffffff256be1950c1618d7cc2c64849efc6630eb91731b1fa29270529cd03723df2535000000000153ffffffff0426807b0000000000016a20fbe9030000000006006a6a516563f8081f0300000000008f62e6000000000004acac5165f787d11c000000000307b96c01000000000000000000000000bab1801bea583314650c7e6992cc52368507c700244f4dfa9b066df8bb787eb438ab807f363ba1ce806e991f9f83eb53a3acf38430091319ce12ef9cf41d7e9e18cbaa530276288882443c8ee1c268050298dfd892a4c7f7350faaaf92fe254c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000321fec77fba7411666ae03b40d389d18749d917d0d734cecf8cef997d901b695801edcbb091c0a263fa1bb5cb9a84ee4bfa0f245dda2fdc188fb3683f2de348f4f42fdbc2f7dec432ddec176a8d98e16b57cd3fd59526c1df04bed9e9717896f7c8437d4bd77c7e4f6ac23fe234a4c130f092b646648cc30f5c5e9b0a4f482f1030acdcf9d41ea398d548386a33c11898c93507fa3893db8c5dc2b1381a409f01402293bb047fd276ac6cd9c2a041d3b8221d7a68e38e0e5b52e9bc07b971f12067c0a028e73d255b22a81fa4d2584592f87d28830c20409dc66121bc090c0c07893427abb6fc7dc46dd6d622ffec31ee77fbfc57c9a1c505cff28919bd25d6ee97f62020d6c112b29b520b6a7773b449d4b1f295a1a3ac4609ce19366dcf007dd9c7f920205806d11f0cb7259a1190b75cd6cec5b561d2a9d73c1152f01c219e5d95ee7f40300d57b842c538ca60679eaaf5bfee5539a09afdd88c95ff5e70de541999128e10312a72c9471d176370790af97faf8a83d4c78e29e09123cb5a335df2013c126710326bdcec86c4957a309c3164e63a42c44a4e7d08038b1b5020f556d5adff20aa2ff27b95205cf43ff48e43887a6620dc70b9b1a0c1c6bd158043c80f0defad7a8e37617615afe6771c017eebf8953024ab6384a4023663b8d40f3e2a0e15a87ad52aca48c2a47dce9fef2e3eab50fcb64feff938d8af1e612d1a425753336c65ac2e1cedaf6f603cbc7efb3c3b7ab8aafd21a6706bc85ab7fe8a842e4a62100ca541bdb82657e840cc0081a0c6334ef851047714e93bef390369c0ee434d54d95ba867c5429f927fd481957955d4ac88945a148e194751157c017b72d21f54126a4f2acb99503613b000dbb9c5f33fb71984c1e4a206f5fe75841664e2736892da67f5cdc603c994b1b586b63cfb06a16bf77bd8f7ab625cdb9e09b6d5466ce64ccb946b3cc1dd7ad0f136d586869adc34e535cc2d541ad257c443d032336abf55a1efd6eee62af4eea67019953ae650613acac1be40c0591e19f2c4c5a7c524549947ef0ba77c6d58e050642b53d8b076ea35eef4e105e60d6df259e7ef84abf96f99a43f169a7a67b944be006a51911bd1a07a6482904d36db15d3913489db88bb87ad14a732f194844f5f499055ac07d76ee8d0e1b2c27b48ff247e1ec67dce706452b6ba3a8292a55a5d2ddc80c55dbe83ed7c049db1023bcfda2f85d9c695498b7e78ffd718144a792808088312499f4fd8958315f3540fca486631f4c94ebb629d1d4405bebadf48506f2d12b47b6340afbe95398aea3434468245d176f9c831cf859f5e17b4c5163017b8b848fd2db44200a57b7994824e43cb50d9b0699642252b6a608f55b83db317550f13ea460562175085ddae63ff1b41dcc19da593d741edf96490752a2d91ae902d1365ef5dfd8e2e8f90a650d3bd3ae50a7cf40b4a4725f06e4294851568aaf4ddcd3480f5d0e4ce6d14a9be67a10f075967921abef83b329b8febac7589bc7915f60a3e615eeafaabe340156b01f510e5d1b0bf103b9b81bedb4871622c96d6640c2004e7e272df8f28fcf5b1d760cc2114a80a2e46a906c0ae2feb48fa411ca5fecd53b2cceb37ea18848b6e62fd3a7f35aa9f2497734243e2dc42a5479306dc2d9fa0c922b0872496558960c750cca12c7c8e9db3e3d937e1783cb53e4a9e377f785060c5766eafd12f03bd194edec3d78ae76b107b9b9fd2db135e91d3eb3b03c7d7bf7375a9ffd7d166cbdcbd9c026e827c682efeab4d6dd2b063a54b45cd72f72e64b276efd37a0113f445df7863debc0ec676a8af0442a73f8a8c01819d5ea93c7d4f9e2e27117ab0789c8f3621c80d27df8270d3636ed187f36d60704bab30c5adf4ee4254ecd221701bba09d83d33d34e4e31948c9625217e07d87bcc240beb3079f7445aa3a41f0ce7ed411b984baa083e0e361ce7edd9fdfe649bfdfe4eac51d006593c298a33d9dfbadcbf0d4524550596f942b7409b303f7b5613580e009abc0fb722811ba24774730e326aa06282e0ab3ce9683161d8fe29b767b3324d612f5c03fa27f85168e9374466cb54b5283d2a65584adbe7131ab80472eaa7b0fc439b9cf5857e28535f61e0d52bff7aeff05061c890d5914a08f94a11825e149bab892e719e3704c9a0745074c3e4a6e813a2203ee31b400ef7368154b197d37c24d2bbdf7f0711a930bdbd7c75ef8f64ebe367c0ae825bdd043d6e2472d5170be218910caa6e224605e4a12a626ed25e36bf04cf68aef6b5963458e102b54eff4859202000000000000000000000000695b0f5130ce6d8482ddfc87ff2aef14b6acbe40a59b2585ffa78bf7b8e724a77920d6b836c489f25738be56692c704ae67a4d553ca06620cee088a90fc99580e75f21676c3ec2595d7d5ea3949989c79c441f4e9fcf882c3afea51e56933092000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c8e738811ccf021d9d2d1c0a01239452623540f9b8f1b04bb248e839a9a4ac927f569c444e9f33a1e39c7c4f72c451a5c39e29173165d389387c58a6250c85c442bf75ba00c93c247ba08d515099195f515a802a49de0d2b6b2d94be63889f7e54b7977657b5a91f1fca9857e31bd80710f3b2420d4eb20515a29fe316ad3120209c7a2e29c494b2dfcf3269a8482b1104054a5b48505971b458aba0907b1ac5a032a61e834d7a95f1c442c57b001d4fad373caa606309b08e5c11ce147a1b6ce560a002b58f65d9dffa013e032a4f47c018c5c91fdb45134d0a30a527f5402d05c1d46256a46b2cdb4c81b312ed70b6bc6503592375f28244f60db10b749107f0122022b8122a25359f6ea0032d6e862f5bb7482c67a690e6e21e9f9935ad2f4ef910703205ebb330d6daad7f101b0f7341507f4f27744f6d4055318f61ea6a716fb58eb03211949f06d5c717718465c9f3b49f3021df0420be9364377d61450db5f5809570223d9e619fad2ad938c2449a501da0465b85eecf90352a9b3225d815066331b0d0208de3b97cf4edabeb3be87b1afa3b2a7a76fd3f25c5523cf48e4e06c40098e3f4b090d9c5d513af869ef8a8d109343494dde474972f4c958b19e2bf114fe2422f0ec8230630f9b16dc4bde55dc3f46fac6d2cbc7278c9ae08d86f9aa55675f7778310734a01ec97c534428988ba91ff7db0b53c181cc0f3695d6ff420b0cf97358070ef3d39ca9cb3568ed757dab7e1e61b0ea0ddca45b19e205abfdac974fac2a2c3e64c8c0a6bf23d95b6a0bc1eefd8c14a34c9342b21eef590d27938e6dca77be95509cc07f8d6d3cebb9a73310ba037879545dbe4aed1f18e27727eca8a0768e378d9ab11cb066ecc73b5532bd4fd07aa33ccf5331db01f392dc59021ad7be5e66b903bf4e201382949e0b4870e003b25f3b4db7dd54fa914ee5e9cd277276874b0981a13b4f4065f265338207a7a2f0578e6aa82f5b1aee75df18bb537a01446d6c187e4b815f0856163b36dea7264903e22f4210c1fb9ff5ed48ec00ae595c5bddc9c2ca177558f8a24ac3a0005d3a0dafd4fdec7283fb1ab8d6100563e7598266e8cb6bf52f1836ea5628246791f95bc4ad09070d2f565c7ac604af4a87b7068d456d6d64fb1eb0cab91e79e4f26b21abeefc7e9648bdf59697712c04a3e4f4549f008903fefefef3ddb2d3b317f78a6c7e05a28e333236826dbd64ef93165bb8d2f20ecbf4513302583aeb852b4a810d354b13486d1798b3a5895fa2ccc8124f6c389caa61869df946d3f88778276474ffc41bef50c13dc5c6f9aa19eeaee6199ca46ce6fcbdac49ea397c861b3b54121020d60eb8fde7d7d55164d93f4d014634b99481283e098db1b0ce505e62ef24560b1fa1d79330d9482c4ac98882d7776449ea5c75dc3e6203112a0f11ab6a7ab1cf10b9f13e3f974a1c3e790b455d9243cf541348873cea22983313f3538b0350bc59d5997a727e11cefadeb41503b3fb16bdd116cb77c5e3d27fcecb96cfe01d3bc055e72e70e3ca0addb92a38f355813e818cf0a4c66d626c16c5ff0d3d8722058e167cde4ca5a69f1237e17dcbba29bd8258f1ecb0b2e3958f43aa1ca7b2375354b3c523d79f2051a6e660ae035c439ea5b9081397ec0e871de964ca302510e8098d3b4ad0a284f7857ea81a29db3cacf4f98929e32ae09dc6e4caf542f563a5c3e12db2094283bc4db2e485a341880988ccaf924b55044d1f96b5663204a50398b1f1d724869212d2bc7e5834a6e4019f10788b1ddc4e52f5342b7b2aff5bb1fbc34617f31bd6409c3783b6f891f77ad899476129536faa2327415d7fe137884f57c5a21b05d592660bc6c4cc49e783118bccd4df7665e44c790f1f7d6f563220f63836d4c3c16c5b39c1ccc45095386d91a5ca010d9297a371ae2b17fed4e2429205c3a60148ef1733e0f6a4f109f58b56c4e3650e7a9c16de7ad2b31d5d9db5a6d8b1844ba63370cce2f28e0fb3a958ee76967539d08e2ed06abe1da1f23426bcf7c24fd5cef29db935a17e4a68dedb02db38803635ffdd845763beaa410993e92b67607babe19202f92019c00115bf987663ebec90c4613049040c5a7135835fa6f85856881f85cda9541a3708e8228efb9466a21c89e25c5453a56d02fbdff46ff40168f474df36aa678855a3e15e5dedfb8fcb631f0085446873e7dac14a0d017e2231387f3f98c34f73f1cca39ddfba929a63f1d0ddaf26bf1e8ae1188302f9d35413ae3e6c406c8015f498120cddb4f5cc28408afae6ce190000000000000000f106bd03000000005588b780999bdcabb63379ee239466cbb0f51ce58cfca4d6a47013b5d08ab4f990de0def1091dd78953df5d7942a0286ebbe7eb232814e7ae32ae309ead30358051d72b9545453ebee8490dec885536cd423dac4b529b1c7d7738e7b4cd58ace0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045222b95dda27b849b51386fd4fc4b8cfd5f0e2773b3da8eaf702d9245d8e6404c0350957d8426ea0258bc1ecf2d0e142fac7e72b1233c70b81b0b85800eaa0a1f8d7da3aed6278d30b08505a20355b524dd168e31ed10ea87356a366f7ccce078547c5478a7f3143b13265449edec61f1fdacd20542efe93bdf7ce384a799f3021c5aafe6d2a8263252d86eb870ddc53620b967632d897448e719f889bacb07ef021b824fc1c447e471b2711520ad402b439980813aa3a1bd9e470987c1d4be33930b03d0e992a478eef2ac9433fa89665911bc00007748641bc1a3fabd956aca84bac1770d65eb09f7c024f4e19dd40220a83a387cf90b56ad0b808f0143943ecca1032d975db594fca234b2a48c9a769920e22ff8e16e954d3d63375bad736578d4d2020661259e702e712036246cdc6c6550fa6f08ef15b1e2c8b06bd10475adca97b0032f67a60de36617eb38de2d67d002ae5a149e0a9f6c7c05a5c956600a95da2aee032f547f4b9ec09b2b13def3aaa0964df0c8337c68ab2325f91922c912bcc6d271030d57af59aaf2f3cb1bcc0823e5381c16dd2c5a0e17f41b2caafb33183c3166e7e3be7b09877916d0d7a46b2636d10c79b1eab68a771aa53cef3b8133d8e6f24e1ec325168e89b2126a9aeaec8ca15d6c51478d4abfbf2c495d00e9560c7fd518c114726d99f478444f2706d92d17c343991cb0980278336283daa26c001f8d95ae32af734709643c379e73f4a265e82aaa34dffc424a162a4c43cf7211ae4bae99e0d6eec85c078c9d7aad7facd880e71819249b83d552d2046206003b7658a2059b2dde35d9b0320f130cc17f9a7e6a9ad208753e44cb6eeeae29a31e1b5e97ba34818daea2a31f455ddff13a334bbdd10896242411dddc666e6980486b89f63d576d9be22dbe91864531bdca4eb75837fc7087911253d5fdd5a59fd253b50ed61a732bde97641e02f9418033e8cc35922119bea8977d4640420bf9d13a2d6f8f7f92dbe4c4fe13a67ced22052ee11665ee3bbaa24afe463a1befae403279fd927cb2afb7c833a3d724aaeab784cc43549a5716e29cc128a1a4767f9a4d65029640449053cc71edbf3134d4c8a5ccd3d86efb1ba6cb6f12c3c55d16f2a48159a674d1c699d396d1e712936f19884f61f85bd63ccaa5c1fd3d7174aba4de931e8de310f092c1c9b858ce3a15e6dd9688569d1619840572df29ad8c1714e7b6028374371d8077aabd3b894f320c5e5f540a9b6a22f1c3329f53c347902c9620a4417542ece2c43dde0674846c46ce14c6893c0f290d658e0803d4f0852921dffe1d7aaf6d947234bdfc91c3ed7b964b4748be8c0727d31e8e67fe16d86c39c69b0ca32bcb29e9993394db1ec734cc0badbccc2f6fb8d45e859f885e6d68488c1cb7c4680b81c447252969affb5f47c0f762121f77035975933846802c04515e93d7cd86b3d88e4be3ba3264734cf2d2289b01f9e7af3cc902f46a67457158d9ec9f349133ed748eb4791607bf91f41fb2787f8dc6f1b26623bf53b371d00a3007f37179b67ab15cd4df9ab14e2c711c1fc8ecc43b01d20df18c9d313903f1b7e4ac7165549ca6fa75907a0b328e8ad39f7c2ba70502b05e8675ba5edeca61f12ce4d1778f38df6000ab603770128faf5a9a76d4e2ae0754ba5725cc758671e9a111878d282a159ece622fe553389aa4c7b3b9cf652ee473aa10202828de8268a485f40c2630fa07488fc7b90bb2b51b9647bd932e6862ac62a77d26b48bec274cea6e3b6a02626bd5607acbc0d1ec3ee06f2b70f7b39b4d9154782cea2e2168da6dcc011fa612d3aa273b9957d596931c08babaf556943e9d0764e15d4f37e28e2b509c1709171e6b50392d8a34d38dec14d1a8cade6c7c0784edbc49bf851a9a2dac3acf8c7f620361ed34b71e4383c8c400abe8d15bbcd9cb90108725a719d88b81b0a7321e4e8005292914ebb2def737fc9fb2456d08fe1baa5c144876a99a4e4f272f546e4f8c5b6f5069ff5886298086fe2fe29f798c9217a39095ff70c0f5cc4e3fe2d6ecbecad21f17db19c5e8f3475cfc0c13adfe14b2ce87c866b5ae07222a92e54599f1e2ef31b679f02df76f493ce01cb96550bc40a8d5eb7eafd2f55e35d9a69167df8098a19ac51d9b1ed7c27d2a95057bd5928ecd71bbd31a5284881876785e306623c4d51e830a967cf6c28adee057020457b1e16197c59f4d2220f1861f103db401d0c2f23e5bd34053439177fa9a63e358e0a92ef2955d4191064740116cce3bb12f1de99439a143a6c8b28b1b54d6f8fef24c48b2559f8b8e72f89a380195378443f21ab6037993f335940785268a3c7ccf7d31cce49ddb1f6f4740134b8c9f7d977f8471f9819bcf95342892a5600e7080c885a43cfddae2a446da716673218ea881fbaf4b200bda09", "63", 1, -999075092, 0, "ef8a33fb595d13ec923c3afbc9f0e093709e8b1adf4ab435e53bbd4977d6a665"], + ["030000807082c403035b5155f6c169604d7860eae0047d7cab4c2a56f30766fd11a2614141c82d4e350200000006006a65ac6363ffffffff83999df98cd14497413ded4580d271a19d0c4f1233799d99d2a011c193011d8f030000000851ac515153ac006542b58f4738548d90c3c53d4167fa8cec63f9c863f3fa354581e074575728b3b55769fae80000000003526a53ffffffff026ca374000000000005525163516a1ca3350000000000008d891ed12e49e37901cead300000000000000000000000000086b2a7bbfdfe921a0a2224c16ee848144f9a45510c9fb18aaf40cc5671103642ddf7a92c9142d1bfd10fdaed0e1c2249bac4735f1d1aca0f6abc0747ff846fff39b8b0077dff04ab4cc72a0ee993bdcbb31e571737ddbcd22f75b8e4bbe1711100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be18178471cf47075b3a53dba146117f50be049271c555020dff4a21a2fa20290800b139da2117f0a0901b0279408f794cf550bcc283d1cd62eb5a6b115122e5b0fc12d21d18e72c406e7905c69867d29f20299da5991635603dc6f4b2709cf9ce2cf5a2849bb928bfb6d3ed1ea2270ad5d511ab1680cf55ef5c2e4c78f1ac930304d90fce5a6dd3eb5fad835b889ab10a12168ab9013de183b52908874a49294e0315aaf2c1494a613ecafaff1eecb168d9f4770c9ed9ab3a6151da4ddee256d8af0a01774b719739a5c40b70199d8d9cdffb45c19bc0edf5c5f87bcce73c0c118e1fe88f5b7dd470c42783f47df26cfeeb016c7b855f3b761c1a31c2a96aee05f126022103079ba1b0ea42f1718146ee429be80f256c8f50ab7f3a46c55f550a0039910320f53d0bd016e21b6423f1911ffcd62d21038b1d604880df380651475a03efd30317c257e93a78599b953530021cb2740915064901d49f38b105d3740f715f6871031164264ca0d1713fbdc8a84dbb68690c1d5f45b9267ab3d4e5e203e48bd3bb39021b1dcea0671c009724ece82d695f7c2085add350241cd02bf3ad390319ed75aaf69ca06f148b1f3267890548abaaeb00051c11f07b8c3f0ba643eabe4268e7d866a3ed75e3259f5628bc873777088f4767b3a2d98781060c5b776a3105de51e1b97027b6e4e8dafc9e8727b63ed038a36eae207c4668e53d30e51cb6feb4ae0433ec91420a8d51161b620d9abfdd8a370e0ec1e0dd26a1bdf2fb4a85e804281c898915154c70c3b92dfa34808dec752e713530a7aff6edc1d8691d47954e9515617061ff3aaef80ed00b9a576dd211973a1e3139eb59b828d908099602f30ca364a44f8090e5bf02f87fc51fa68e4face16757615c9b9a9bda95d28ac0b010f097537c575d631104046a5b45d40e26a00babd33f4b13170c1d3e899ca736dd5b25153cee3a51628d7d88c625d69229c19020b3df126f69cfd9fde1e9f99a859ffae012e0083d5286fa13e2ceaac298b30efb84e3aee1c771f89772b0bb135ce53a99c9cc684dc7a35add6f6d593deaf52941167218ea2b564695df5ef8888330e317416cf91db80b7e4a5e208087950ebe3eb2df2a2edc54364ce0e4db1fced26ba650ea97a8c2dea894545e3864566fcc6c0707f0dc8f759d78c367272b7a28b953467c5cb408b9b077637c5f998c3dd98c3b82213b1c4f0d2d1b7690a12f04e1934f7c5e7b4892bf776f9f2a98425c6e607c62aad5bbbc6d4c02b3eb62715c3962fc9fd24e5b471d95de0b484e652dc6ca4207a1d39735ca54585e42e8497014f67564712112d7d6d5f54ed45a0b9a5c12f4e032e0ed4ae7fd3a3a2d0e2a2d60b9285ba531d63abb5119b89a1a4eade9f748a780c58c3f0e888c8ca7b5cf0e9914276fe0c69e52be4d7252f627148e55614a27db09662cf49d2e7634ba9c799c7ab9c29d448fc54bcc5411f17cc8fc66808ec4f711a2ed581d88e25e93c1b0ea9e623ad7ed4f73902b488560a9d0bb9420153bb6b12e1e7bb988708bf59d6951f2e6fd25708d0bd478edf785c4d95256f0f47ba2a7f026110d9bc4c3bc11938562e938981df8a2536485c06e6398184e170889021720a9cec3a5656a84cf16db458771fb66dac454fcfcd2f7af812e25aad4062d450e3d8861ade315e39e0ccbbbd3754f700244d8b7a9fa47b4674e16dd643a35870263dd02f10fdf4bd809166182f74b0bee160e0275f0fa4257221e9579b1d9394478f4fe70d3837cf6f749acf42f2227f4d4303037f1df97a44e152a563608e305d6f454669ba17287c58f734c8e76887b86c8c7aabd6042c06be74cc67c0e67274b0a63a36d6b5a69df8fcba93035c780166930eb29f1872e3e701538f9496c64d37e14ef2f34bab061c2d27282d1e9fee7b2b86eb989d1394eccacaa2e4092923ccc2ed4cdd15487cd450a3bd5ca1a32cce0defd86734f67361605c9a433c277386f6d6d0cfa1f5130847c7b8fa62203d2eff32a9332ba833b2bb4503228d65afd4b423a09ee9c371577b3049aa6d6ef5714bee10af1404d2751562bf70f5f76234053d711822c3779669bae8790ee02059a476e8ee97106b3c5945b1c2ebad0a5b02c096cea5d60ab3ba94e035598c7305bacf7e3d979c709c1c27303c186947b972e4079fd19998bfc6481aa14b57fd72e2508663aade7d3cc850b98d6d69f89a9a9b9d61e320bc7d4211c92d91bb6b8aeee32aa945ef25a3a29fad4f4969c3e1c628adeb52249c2d81ab57c4598eeeaef47865b16b25878b8a8d8226d2492d76715443fdb070b72cd42d794630c4647a1450c08980ec65e6b1bfc9218354674aa6b0d200e1da008faf7891a2d84a450c35338fe3e03d56a9484377970f032bde019a90e202d8a202541b394eb97e03e9f059f747d7680085d07", "52ac", 2, -740108740, 1537743641, "d57fff821842dc043fd6cfed77911deded89b42d3cb705fcb216d41d2b6e3e62"], + ["030000807082c40304f2cf6afc857ae11eb2716b679a0806016cd497542185e597cdafe546e3d6346c03000000046352ac51f2df84f5609842b91808e69244f13e6b9ab9c37cdf58551064f6f04b9890f2f5d3bf3afd0100000000ffffffff388a7a94c1febdfdbc0b3f06bee4780f5675b16eca298e5b7357396932cf8a8200000000065252ac655252ffffffff6d8b968a52a82863a8fdb0758bc670548a8de6476fbe431d2ecab1899a30821b0200000003520052ffffffff03c8cde00200000000009cd8a100000000000852655152635352ace989230100000000003ae6f7f860c1f1c502956f3e05000000000000000000000000202a175ab2f2027bc149b97571826638f41fceacbebbc8e30e9b0debe38250828d6a4a8e1c297ff6203c6bf91378a8edd050ece87d69490c4d9970d30304472bc113a5ffe3c75dcc2419a190b3f7e17ff8e4a521144d6f1977b4cc85158ced9e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081b7d1a33bfd744b1ad04f59d43c228ac8d32d99c78cde7d91734e8a3e85b47d80ab1f79197459fa5695ffee36cfa2fbe22e95ce919bd8c4339e5b12ee44666050999172fa3ca932212eb9de029c404a12f5c6b3c45f228daa5b9e4f03cf5a7392100a941964dc614773908f41bb7a9f1d5bd8f24e696d592a95f8f465507cb903025acc968603e6746ff43f3ca344c98e511a3fa13879506ace27afb987275787020c67525a8338907c6a49bb21db09ffbeaf431816c717e20bb78fa97fe9219b400b04a11c155f772819aceb5881bba99bd9d54f1c5cd3d8f517b50ea0143351c025bff03ae3663fbdd5dac3aa44ea1baa86965b6b0713646bcecc4e9ac60c231c5b0324cea82eaeee12bbb6750226f2777749b93ee0ce4e28c5c9c6fc226f0efcc852032662f955d375670f20acbf1d1a879fa7d45c6e58a68fb45ed5c5355c007d1b34020628377982afe4b22145cea4a175341bc71986d137715471cd5567a7bb2ae1ac031c77cfe32e2f28834b043eedd21ae568fa14978fc39e2151c5eab64b9fa9b9a5031f3671eb08bbf99d7822d6f8e2e2d96dedeb681db9fc668b566bf0edb1a50a807350c66b56b3c6f1ee4e65d6b992a9c1a7b13220b50c86b722132a693dd74e5f8fb00fa952e419ff36520b84a7938df73733b7c298a5520ff322961ba2a69648a401da9dcc4715c7277b4cf918f437ddf9da587d0340de1e136655b67ab51417fe1da646c487aa07663efe4215cfcf7dbdebb1ecbd8fcf0b4b588f44f54991b5d4f9349021a5fc13ba3ebe8f44a10a471343e7b1cfe9f17fa80b94058d68ad1390457b0cf02ca44d0a1db53eab2e6f30124d77200fc86f979020aab06f1dbc74352e9ece2c95b33930b6a82b665b203d84ad50edb0f90b5b7cd722925309b6e9fb3ee8e6fa6b810ed29f53d4f5a5239925e59271b7efe5cd1e9c4352fea79821ac48e6641014e4179b0f7f334527dd30b525359ba2c12394f5aeac3587621af6f05845a0183235d209f2d7014e3d81963a5fde3b9c1143a5387d1587db208d3907347b531f415b57d1e8ba19d79faf04a6b5b868780a862ec33380f016bc96c7101f40f173136360115440cba5d2978cc62f11d7c1f2f4a0793ae06b99c516363c68a03ad99e5c11381fdf86839f646bdc98c07e64c2e64f6a00a413c9c9d9d2ab9fc6c2d429dfec958716da6e1c858acc17c3cd2dcd7483a7f0cb6057c1a2094bcb9f512eb24a3ec49447ea7b7b70d0301024fc25333ad3eeb6604fe80075a3cbfecebdfce8031ae47dfdc25ba56757f5a4452988dc64b3702a154c91741df62ad7bbf8cf199a30eaa0e78b890156fd8ff0c80fa7b8ed4adfa162ceb56c6b082a518bcd29f0612576a007b5043284cd8ea1afed5bbd21ed60fa6446064bc1d9b96465f3f38d63cac078f6ff28646488fe3a58d88b8c18da185620e169a27530f6267249a5002c0775cb9ef5a2240a2f95f5c67f92b2808ac7ca161b9a2801d3ce3af98afcd80079016c3f6b623c7f4841da6e441124dc4096c0e219ea85fda777640614378a681584683481a3f8f93783d197e47f3bffdcd5f39d458119da47125886c092af1b46e14c9dcc52e7c0d642801b9b8b6678628bda9b7c24e180986870e12e446c6fcc5f1bb11d66c2536b88b90a66a6967a4687aa76877ad3dc15f999f61ec0d58aba4daae19d583f28fd2f89927fe8f040228e2ac1e03819db3d482ca16dc71038d5018e0aaca3e106bb4bca2543529380e09c6d3700e744a3547285c74b3dd25f91d450f85a86f5e364f6ab55b26337f8f77a28a6c3df53db6ff9524ea6c88f9a01a847db419c05fb281d80624b89756e19c417e0265b323b02446c5018a5fed63dc97f4e5dc9c55bc63699a411e75bb06e9671d5bb40cade0c6ba35cc442b9c58bdd8f674f891912089809c5f4fc7814275da1c6e63597173de8b6754383d526ca12e4232e9867b63924b1d448391b8c39cb5a5f273a46979655e5a0cd9f31b8d3baf7abebc7e0c53f188e9eea385b02b82d850699de4901fb59a556865d8b63b101c89a0ef34db9c0f9d3f8dda866d27ef86c629b790553315e2bc93868770f5e579a8b2830f1f15acb0bad494a8afc6dac7fcbd1a9dc8a57782c6b454895f57f3633b46493d44e00075896636aef97b684f2027d4374ace6a3370c2eebdfe9fe3c72e6c6a0572223b5802ed9b7416821036433051e6f41005b9c796873e3cc923b939802d5f20b9be50a2171a8ce7e99b767f6ba88d2508550ab504d133d5d14febe425321199caf513f20971b04000000000000000000000000c16329707bf6ec0b206cc2edf0f17e9523d0c63a35f97b84fda5dc18c6afc8f234f08f57a2be145bf0a9a7ee2d067bf8c9f0cf9d91c563bcc96f8380528c5c0acd8a994785f856e046e975ea7fddf67c1a3c70ab1d568a45a50af52a285e0e160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097f44f9caa593c5fd966dadb4bd2fffa62841a94ebcc5d830f4268772fc3e9fe33c4a60e8c988e610144f193f1b733c7dc5ff5cb74f70b65e2e7d61895c9353b701a5689777804c3815309cd3eb479d0c72ec513bf8a79a47cdd7f65223214f712630a8f188f1d3e8d427686b9b7ef620a8fdec2bd210b6acb0384467d5ac7b70314fb410d243a0995370cbc4ac876e7b2d19332ef3cd83beb11507d7d714325b9020c667d04dfc25176e71141361b1f5e5e284830a613af9c2d8450fa5231d44f420a081d45174f7d23dacec1fdd1693ba3a1f14fee8a50f8101e09980767ca628aded8ada0152b2aed1361ec33dc893a12a7eaf839d84d363395e6e41911db88b31b0314d866a425f87daec0c41fce4e71a9237d53a5df67e4f65ff9ac885a0f5edec7020dc53f606084b953917c9a1b2076e22888d06e968aa4dac3e041bb70f46e15a003169c6ccb8174c196ef632bad6d4766a96f8c18648923c4561fac7f894c049829021bbc83d9bbf0f607d712cae1c8cd67c8f009c5423148ec0520016c4ffff20fc2021e1e80d01cb9ce030ebc3a4a59d65b17296920b3032526007cc1650780cec70f908d2ef7b845b90a29ea5b3ace2c1d022233cca795050d98211133f7ff0b1c39d122523ae25cf62d99a6cde1bf58367b3a9470f57e31c8a810f23173e90c6cf096a29f82485f36e6adcef5d67b3564ab11501300617f9f749f5d156964e3be9e9e158f373b8c248e9a0e7fa7f8af69fa17610d9562bfed079511aa061b10f4d5dff3deb60bc75b07c579fcee3bf4a930a806cbf83bac7f0ac794eb38700852ebddfbdc97b38c388df4feb31ddf4dcd8a230436c060f980b4eb43cc53abf3feec388f3b3a8d968673240ce02ee97b36655bfd2acaa0f3e503a0dcb244e8ca2d315642c68da11434d9311cbe9627cc024e5e9c5cd601626143b44a977dbd3e639393e009ffa2720de57448812a01b2e250aaf1ce8695f365d18ea87fe60d1cc333a47724813d927e3896c476d370311db44b62889d627e58139ee68099420b051d52655f37fe66d642a319f21ffa92a3c2e34bd90771d55c54e51592174a9d2827dd484ebb2c4b5779455e86714edb22c661c12ec7187cf9e06e29da07068151c9444c4984aa1cec59aa6f8e0d2311d09423e6d0226655e28fb34d98a5a7bd4c824f66b218a709042a33bec232ea441a08b2b58aad70327f691958b6224b3ff06b94d80b4c3d46a7fb290aa439597db31f57d097996b0752a5f9fd5b5ce5d4058a02b43fe92ca5eba799fd5712d371d5c71b35cae8171f5c014c80ba0d834d2196716e62b4581934dcbfa286c1ddc51b4a142695e99d496ff0d6d92d7ca16ada1e953e1388c02c9fe819be1eb9a0e76b61a8b53db6b1f33a91b1ad1456a457bdad7fc2bbb3911d86f1b942cec457cbd6fea69484d17e7721ee08b3abab3a82a2d2cd374bfcea7e28e074ddf2e1d81c37c22e6d1cb35beb1437aeb9e4c814d883f3a07b74b9a75491730315ab6302d23eb270e5490849173317cb8e11526c9d56cdb0aec9d73d60bb8490d9a340f90853eadb484227fa7f88f39b658c086299cbf73a023d904e0c0204d3a38490bb90409eb93599674c4ec638b8e326a95f6717b0a5f5bb91ec7c03f0e393cc50b0e85da1765e66581578fe9aecd18a88604b1771db53eb5128023da63c890ca690d447e29788205d04040227aa187bd8b449e1d78800bb379d9277d36fdc007298bc2c4d89d28a3cca3b36a21458691330677668e50c17b5cee6723864e63f7ee080dba7d039de477b334ca88caf7bf950d36c4140841c360cdb4e0e9cfbd2168feaf34c74def97d7546888e40b02525d3474efb7ec68d2268ecd5adeab01c8553400b6190ee031b44481ebb55448eaf0067cadb12fb0b6456ca6c890a88d3144f75e5b16639d668609674835cf4469c5b73205891d9b57a6915901e007125a55a4b3a01d4370257d1b174de39dba02e81390e04ae2773b922be1797061b724fb11c1777943620ad111d3dc81985cedc2f22aba7ca9ec2229bd6764c807a95c3b01b6928d1296a9a27e61c7b776bc64c29b4a48e2fcb835b2b268710ce2397da37ddf2e71c3ebe1417bf0ea064ffffd93e15263f7bfb76e040d2b32662972e9cb3c4463fb270af0ba031964c36a47051372d37b1879c89871d6714fc1006703062a8b315652361a8a5e6e474479e236b8f19f293feaa365d5fea0e6459248cc8e8555f53402f5dcb329d6a512f5edbde7c24a0d98ba2458a740681b9765e37775f046d2a49c731ca379d6c0f02dfd21718be94bdd968b454706d610bfa3cf1eca29cc1bfa4434d0b74dfc1c1074e120ba6448eadab4aa0bc406147f8ae86b03ec6d6691d951a19b4b166c57a1a60dfad954679c2d04fb688c16cf0a7b0685b709742f14f3c0e", "51515265006351ac52", 1, 1929323119, 0, "03c1e4522278fda7a968414b576e3d99c96bb763bfca39412becf69ae6386133"], + ["5da89f1f04514fcb100927dfec0713100f64de114bc8930529cfcf77a6f35a6b4cf694a26e030000000151ffffffffb1708b85f7bb73a93b812fc0a84c0949d23dfc230df4ea78315e9762f93dfa2302000000066a65535353acffffffff0b35d56932af83873ec9317444dc977fb463c08c84d264b53094f987ba4cdb0d0200000003636352ffffffffec5c65c925efc2a9439bb224e54c7b93ddd5d5f0f460156a908f69bcce7044f9020000000100ffffffff021e2823010000000000f618ed0300000000010000000000010000000000000000caf8310400000000bf70db30731b4c4bc0fe598d514f3b9b032e5da448e3becc9c2e3ccd6fe3eab3d65b21325b3940e44dd5f1b42505a5372e0df241934abfec2198d9fe743e80abb015f281f47929ecc88e9d0f25af5f741e99d2de27a42cbafe59119874610b1700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c36e0fd4c71044d1b00d836c546345db8061c7296ebfb9e3a290183b5abbbb4e9ee5ee2fb7877e609ec9425d0d71daee45acb59827d08df145000d4fcbab1e8e6a3aca7b2acb1c71c704c4dfe85defd39a12228905d73bb048d821a16318c5a7ab558878307cc4a5e54f7c95d76b20b2f042e1df4c2c9540d651321193524e1a030adc008f5bddd4cd08314c787f889ed2f6520e706a96d0dbc946eb7bf937d5be0220f203ba8e30ebf451766d1a420f13e0e4602d9dfbb4974ce0dfc2ecce4979850b07b74198ae45ba3c2d77d28c6b2d841c39ab6a3a75f60f20ae9aec4fee41723290664e11af421795911e54cf64cca977369f5f68aedd3380c82d976f4e38bc84030d7317882df364be530208a062eeecee2ad9383cce7dbdefb32361dac9a0edf5030c06d7cbfd80e8d752a3bd41b4972da891b132f3b51d5eb66ed5d337cfdaf32b032f77620843780b81384bb0388b1abd00eb52fdb0a6a41ab2883ef0ebb17ec411020c55c8e5fbf52e0bb96ca4d591501f9d46de5fd0626fb826dc14e30ee977af650312649ac776f7fdae06fd3bd20422b1716e28e9582613b1507272ff647914a07f986ab8334d7cc05f842080367be9defd40ba15b2fd922f4cf845c322fca006d0833b1c225065fc3815b3d784b947ee6cbf6dfb9ff9ea337ca8c972cc75fd281737d4ac7a3b1af695fac0d1199e85ad2d35717906988d4e5ad615677dfdc343eae9fa504c0c9c27f1530543a95031dcf7e11412ecaac1d04aaf4d9a4c873742c11b1ea55e18ba5044c6b65c2504c578708051f9bf16918e4149eff2a415daed03c01316ef0e81a4f2bb4282a30d8d6442ba464eb1468590b802c66aa78885f09a7790d2c4357d5fd5101e1ca39df7dc81bb0ae80f1894e41912a0e49dafea7b19c5464d4fadd5d913066b90c2f7c41dcde59c180e1f360a6d1b495e922c652b06f4d9de7dcca56672f6248a07c9914dd5cbe939dbc315127ebdd3d9b12b326a932eb359fcee3671885e40b5e5d479619b58e44db62b0fc0d22b0a1ad50cb554f90b15346f587ad41fbe9841880c842405480d31406c27aa5a49de368e41346a62698cbdeb0cef48d6a16af896f5260b3ff8dd8a259842292631bcb6285ae4605329d0ad9e19cd74b346a8ad6404ba691e3455f87c7db90c4950c36b3aa618ec4b254c11ccf1c19285aca53dd7cdf70adcc5d9b2d10b9fdc5fe029662db519bf495849015a114627fbbe9917151a89f13565fa2c149d0edb35fc5e522d1e31a2418ff71d4d1df28802ca2bce6ae3b41c863ff05825c77f851b7b5bdf327522c8f874a201374370e98c9e5b1852d0db2fccb07bad4b5ed65d5dd9137b75b7d228f22717497f223eb538160f5670262c6b0604f64a30aba51baafc536d8fcee2a77415728f4e165ad0643ecc33dfa0ed44801c3db25a8454235119aebc32db1d75116df238d27deb89307479d7d53695b079f2828e274ac23165c2ad91ff26c0fb61dbb568f982b76caf6261908f0cc524d8b8a98ff307273923a5609333a407e4f443642dca729671d92baaf4c4c63b36923701c6829bf3202bfb92ff089dc2c535aed47dc58cfa522eb2923e1ba1e4d0939d539916f2be55d8a006b4058ea28398d69eff2cb99e2d746df31ebc9352a9547f5890b6e0da4e318399c09183be906239e790e8a782aeda0e3df12dea29ae7aca8ee2b12b33472764f99d45582543a8f69800c670cd90c703dbaf6a0c532a51df7a9f6faa55aa8c935585c3c29143472156cdfe54bd60bbecf8c740d6f55145edecc133242803769f833eab0fc86f9157e61ff317e463b666314d135ab69db4b0b80559db5df6143eb914e0146fd3a3f8a5d8169c577b9d09fed8ff533651bfd54d7acee229e09fd17ec0f8c3463a1511eca3d0bcd71d00fe5618707cf44c921d2ff6f422e491ca594c3085c495221b334348c5b56314ef0b4802a9d85d36564078b6f642306dbf02236d7e1db28130077ed2b87b4cfb29d97f4086cbdb6c034593e30f66aab329d4f638eb5b0e02715c00efefbe05bbb80df61d1e7a09702f8af4c5618c2ce84319803b47973fccb384875f9cb4c6cae1ec9e5855fb410b71a1f6faa63202cb8a90be113a032e303cc19ecad6df227f1e6df922b63f2476f8005cbad75e2a699d0ec2a69e2f7c47d05648ca7f66b7305bac9d3a6fbcc24019c3ec403dd264b2b559c121cafbf501e81325cadc3b7f0a9919c5649ee43ce6abb4fe196ee7d90c43c40ebeda20a6422170b67d8163bd950e33f1db1defd185affcdc3e9f10dc3dce02456cf5046b3aabf31b65e3b24b08eef8daee25619734b2dd7a3fba54009d57c186f28338372f9b011887bcef9ec453f46eabb662a07ccf8921b747c6275c4dc9e78308331aa58441ee0042ea46f9d8b3335fe61fb442c5c30a", "53ac0063ac51ac", 1, 1527985764, 1537743641, "a1821fd90ce1e40920bed3d5152e11d89d928fa0aa6c262edebc229c53be8b8b"], + ["030000807082c4030174a93d720d06477a5538b04ed763e1711794cded63166828ae92542ff72f3fb10200000009ac51ac53ac63650053bff3092d02b41f1903000000000763656365526565537ee50100000000040063516a00000000a9c0e7fa0100000000000000008f2d4a0500000000ce4412e558bb3d1735061073729f08bdc63d5a1b7c4b0896b36c5daeb392f42a91a60d0be4a17f05337a61210bb43a213afc55e8a7cb5e44cae25b2f066af5144cfc47c4da636deea7465ecbc74ade89340c690c785d38a2b9e703b3f209421100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de98c2917707da4f46a04e16667317a20ba5662f30001f3b0ffbfcfd8add96f2d7de5af453636077ac5a90ca2f037e38c12f799cad97d872c217a7718aed8fa6ded80f75f91d390887f562433849ace6243824eae90552d035915269cf9cb759b9079e7ba45a54d1c7db2b62f85ce6ceae5eaaabbbb77f4fa36f2ea45248fdac021c0eac36577b58b3f862b1ac6aa3bf3a0ae5022377228be0d9f1c58958c4d65f03055bcd193437c950e9a38317d276b4450c3f16c64854338baeefb9f971fe31200b03d63ef9d429b5a5d724ffa71d47d024ddc4cf7cdcae80b1c33504d5a0855b9bc2becea1cb9e73d0a6fe6401ee0ff41f8206eab07451ba361afee21c0e2a1af50301924bc7b55833f2fea8e6ef76bcd6ef6a9ccbff9757508cefda160fbe7b604603253b2551424edff355710f2f5444bafec6715a805689d24697348faeea91f519020a7fe4b81169b6d2ae17a28c4778008df62742a3835570e106abe870c7c57a66020a1f4f020d9a6fda47fce6b31b527521b067a775ee49f9072ba6ed484427ace0030731dc00e9e51781b0593aa31b2a90fcd64b83eaa230ace5e64cf19b61cf90026f802baf5d98b00a12efd890ddf83aadc1b73fcdbf8d8e4e28672d8fbd37fe09cf6633d13c211ddc0cc4bf875f40728c7aa91497046f121df63779986aada996cae1500fdcc1c0cd808320c6d7539a68602db0b118713cf4571dd2da2e0c52aee49ac0e65e7e44aa9f7705fff5c8dd1c5701eba456723652a22aa2526e200601a0c3b0d80132c4d594db9935fdf4afdbb996fccf7f9bc5b53aed24842e6ad73763601e0890c5b60139a309aca20970de4ddad7a7bd7bf5498197528b11bdf5aac1f771a00bef1768565820faa5a5e2be26d68fa4d02a0cd3e96f5966a2e2be6a338d7e9613097617652d0e5f70a2cc5cef18b4219e918eaca9a9933062a01b8ca64af4a6a62cd53d7aedd746c17fc2376ad088334b3f32aa39836d66251821cbe85f028d15d1a785e7471fc3b30b8c6605322151ded462023f4d97383c975c17ba459240fa1b29bcd3fe32b0c06771a86e26708d3914db4a383ba32b3fee659e57dc9edd3970e1ef9467b9ba9482afbe25360f6d872367327617c25e2c369cdb81ac5fd8c70bb66df8541c0b57b71229b51e09dd5a8f016ddfd20c9f7cba5fa0d74f5b93509e81e74c72992d56d410f19c3b371f0fd37b5efb2353bb523d868e7b040bfdbf049b40a75c1ac133ec09a7847a3ed99159fb78e972a23a13797d0c99efcee32dc704d332eefc223c6db8168aa2bc43f33a4885ae2a195188e936d1c854ba6b9c158e3522c4fa225139357a8dbecd964f9ccabbfd108667f88bfdf3292d740a948136b43d689ef0447b34a9b5c9fbee151d761c09f83ac2312e1f1438938ae0a037fc333de705fc84eb61b1bdd14bf45ff5ff59d3458f1354346b662efb50f136104f76aa9e456a1f2c9521e451ea8b9b32981d01f8b3131cd52f9815f9c90ae3bfc6caa85e50925e25301e97461c94cbe44d6409cb056abc532af9badb0b03a69dc827824bddf280f584dda295f8301510df06939d81b6e0c8c97d6dd45e34b24e579063ca9c72604b5bffb0e1ef8d11b81336d427a661902ed4ab113300815cde7ad6733323c67037c037e3b3b11070e46dc1ea5109ae298acfd6dd644645064e4d552a344c5c9209d786529c7714faefa75e65e91c992871cf62e636916104d907a4074263ffc30ad242a130b2ab00eaabeebd50d82feab961269afd913fad665ee13364b464c8558fc0f689a973d349bf364bbf611004ec7776adba2ad68ab845bd2d1f5995d7132e8ed344a4367d7864999ab5de9992273dd7946886c856ce30b4b5400e5e0c635b2f92c7d4f188011ebe3aa4666b3303eecf3b556490e45343e0ba421ca083b7148688926db734b325f2bd71e12bf8bcbd339c748a75776ccc53177156338485b14dd7d39b3c4c1f69c9421b8eab42f7f5415aaaf0d2a3fe57a867a9ae10913ac19c880d1931f834cc6643912d39fa4935f58da845e80932d1c7ae5bad9b90e42cbfe61589e64fac841dbfe32fede8791d48638c48d8adc2f22d6a122bad4dc59cd31b45f234b7a0e867557d7c0d59479d3d4a5b15f27bd8fe340e2ae89f1e403b29657b974663021433f2aa2766b59a6bd97ef76da3831b356351a17340f94e107cdef574dd6625233eef46be1905339688e647d463335874828633b20d45bfba104d1e52e0d50ec94b5c441c7a200d7314fad25e4c4d712c4d31ca59a8a59357d8f0e2f1607026bc957ebcde75d16231a2809ae7a7ac681d910615e3e964a95435d54208f9013a6456c62c5b2f3995150d6efc7161fb2d5fd47f50b703c79511417abed88aec5a99a4b7c53fd76f7b7e2208a592b09982e5600a011ae3a7e365e8a804", "ac65", 0, -1094666649, 0, "f582902984d5fb872e9ec722f7b5d673ae01efc463772a6472807b98c79ef1b2"], + ["030000807082c403021455ff10b68c7812f46fb6d300875b18d1bc1c0f0119bdf89d7f4834b6c1a200010000000663acac6a6551b0e11960feaa425a1e02a23a008a9a73486bb09cd25c3066be1764dfbd22ace3b55f715902000000076a65006551656affffffff03107a2704000000000263ac0b8642010000000005515252ac00f9a50a01000000000453005163ff65819e0000000002ddee2f02000000000000000000000000b1a0a09e72a5d79fc717fc272d47670b4c9fcbda08ac65478b01cfc7e2973217c21b6e31ddb52ab60f058732773487d2a21f10a06687cbd989c1faa37c0cc596e82febe66724ad8c08cf2a13fe8f481455d0b9c0b18f7c2cf2a36488285f3573000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b82b4cdeb4eaae89f5df1498a3f34695ae334cd6159c155fa290cd7fd9f3fe24b226bb73477a5c6a0f0a86212787490bc5962619e458b6a3ea0ebe6c756a4bb6a5a64fc85c531764132ca5e0e1b2ed4d38d1e31e2f4836c4606660e7d5d8629269a17c8eb467c015fc6be00d165c020d418bcd2b3dac63c0529c4de6ff57654030102be61b1701fda0e2d560dd1e5111fd8221e594b31a22801a7280c1ce700e8020c3730592d8ca1d894c45b3f6e340984a9813f7ac082321f12438b50a29024a90a08b9c1a2eb83c2db651be13894c5af49c78754d4f42df84ac01842e842ddba24ee6f2f530aca3310de72e102b26a90d14eb02a3d07e8df929472b73e906059880303d551c7b3b29bc3c4cb7e790bd0a32726f44676eedb985f93ecfd5832604cea0321e304a711709560a49d070e320444e709e04243e5052f7f3b48b3c5c6b741ad030e0d17ff61d41b85532f72801775a325876342d3d94a0023a1245a71fee2e073021bd230925bba218641ed40b28250d6936f400700418dcc4a8345c51ee70186ca03060aabed464a6f19ed2001787a76154b17aa6326c70a644f0a155d848c7c7d96dfa403a2114d7b3ab15b90a3457e1e5f09043365bb7b7a64831f1d65ad1f1b09bbdebb76aaa918d654c8f2447af561c3c9a46ec2969151fcc575a5939474f9c561c54123f9479e3084b2e6e0fe2d757237db1730ef6e4e32897e408b0ead9b0d05f416fda3ab966f0f3fec08db538d867466eea007ea24cdd56d7ee5cf0f74c4cf7bc4ca31a1a723ea28f36be6a4c2daa1c877c798ccac67d82a499b8e9d75aae08c3dbe5998f777e9d58abc00dc0c49a01db9463debb226c61cf89a9db150c5eca4c77d1b2938d741137b304b57f2b2d0c0878bfe0b2269f720e8a22d880bd8a25ba3f12ef1102ae28074277bc4c8a0b19388d7bfd0c37c3c96fadf670b9fea0d92a34d4062cccbd38a1f46eeff412f4713b4ec19548804c3e3c3aff14b412234cb376785e9f5716774d2742c053fd879c188b01a7e297a794a4efe74bd13c72fa8d1c871eca5c115e4262dd7f476d8a89359ec9b9dc107a03dae82ca19305475cc6760558f7e55467c9698e2ed556c64b498f6c01d286f109bf7c0cc93bd5024c7bcf6645a50f842e90d95df0bf9f3b8af8e83908c7e8f1578284f8985cad8545e889c5a544f9b75d2afcf06cc15998259887df55a23cac399f47bb6157cda42742e82289c4cfc293853b24fda8e71148d8936543d069b5b6a645dd3c27513b05bf7456d04bdb47a0ed6a78620df48b642c8887a63dd90ea34ee8390406418652f6109b91cdf25769224f19a2040342a87e949e970d6f7f999fd930cc599d0b1320eaf49d0f574a01d198947802ddc6b57e395fc30926acbab944d92532bc069b2641e1947aebe5d471cd6b1b1ff9ca545322c39dc51ee1bc6ed30149905152b828a36abe1cbe4e5d1f4216bcfd3f261a30789931ec462036b052d2894c19f67af0ec1443a457445daa26233efdcfe8ab097b05b1a88cc643a55e9728957b3057cb0fb0689ad7fd88d9b6e405a6af1d083bfe3c507fc83af23b5fbb11712552130962f17ae462e8c4be7799f8c94f9c3236a17ce9c55964678fbb4294564841709ee9784f9ab75a08d02db512960afa3b3631be2becc7d2082b107264d4178aebd24202d205b322826c55b437405cef8de02d0c4ed1360553f531662b508c3e4fb9981fdffada79751d0eb201c03e33d46e9e76d4ba98ddf195610bc8dec63f15391c91389585ce2adf90465ffe1ba502d873e50d2e07153b40ccac0ea058c06626017272a30a8b23d915b1f0dee5b9d54543b7d95e3667d2b05a280b5340ade15cd5064c2c4974d19b5a3a95004c3142269ef1effe1ce8cef68abb6dec0741d37b7c6389e602cd9cf7a3237e40cdb363764c57822bb190057c05b1e6869add1d9d84b7fadbb06b468ee7b2349cec49a1d25c06289958e30a02c000baaea95ec7713ddf0a266fcd6d37f37bd15163aaedff3e77a64ab17138108491f5373d8bb6a4032ea2181ff88582f0585f02c21188999d8547a5bad80b95e83e763802facd8a4f87cf27d186a27223da9add473b4ac54b457e86eab48de9065c7361428f6e6d897c279401a57ef3e977f9275ad370e8ecec6403b4049738ea1c154cafa6257ce453729827fa55828cd922c91c69b3399d25287b8d95ff0c468c8d99b4a37b5838193aca616bbfea3f814d861d6dfc49755a317ea942e11746599eca89872868ce9daed66e60373c20bc4262863cfc100000000000000004825280200000000581efb9d1cc41dee78fa9d80fc87ff53976c434cf4f64f2247abd6d55c8ad9add1a4fbf6268e38b42f472bed6c862bda328e5700a268ba982d9c9361226669e6843701258b212e89c8488885c547fcb1fb47002d6e793a4f78467f7bd90d54cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028bc573400b4adcda99b519804bb7a126a5be16c0d4b9e94052eaa4e8b63e441aaa5b965c3b3adc779e7de84c499ac700d01024ec128f8b994b2c67f48b1564be045a28b2d56d2c358d9615f8bd52a49a19ba26cdadf5a218d93b6dbee8991d274ddc2db92d665575eee8e0da54e61b08c335136f55afeca3d18353bdcf1c9fc03172c58b703884eba9ceb2325c07bf516a7fd36fd0219c94a9a8d42b9cbf21ece0201711f983ee1dd775ff8d3d737c5c74b0439e17fc0f1a98ec8c529af8dc429aa0b07dd6369400e2f014152a4694390eabfbfdfbd8b6cb8de19e742e4979098c87a8401357bc438663265a765d7942a5031b46bc3cda8f0ade982042ee94451da080308e20274c1cdd3d05004ad9c10a7fc417fa12c4bbfba96c4aed4c1d42287bc82032f7d154717b9ce98099b7142d39364c51f3427ae277ba64c2d54f6e8c6e3493a020c31ec6763d9c93981e511b2ed59796290127004d634923dfae2b11f7f80dc060325faa75a36dd4109133851ac91533195075906982a35712383be51d20a179eff031ef69dbad37377d668d8c799a0ee3a67e4cfdeebb3844041c21a60cb5dc9579314b0e70b23c31eec38c8de4a8c63d61b988b92fb91b84c1591c0692728da5c310eedcf5156be2883f85145ea3781d6c29bfe7ca2392622ae7b4f22a3af5d470d27f53785939292c68394199d78fb93b5156df1c79802ef97585e5aa5f498dbe3a32af4cf8a888636f6c34f7f8e472b41d97adb78950fb749ca1e5376ca6c0f82d14f48a3a1c32731e28c441e3d03f85836cdf6794cb2799c2be07abebee2f592ffd4d964cedb7c03ee2eec1aeed141d95197abd82c46960945a8905c7a93bb389f66f434af451539d404cca953637aa583c67653e11a862243f3fed6effc0c0fbf2475d658fc671b53a5446abf23a132402670a6d72e7b4fe55a0094af9bea9f01e7674fbdf9b35e732aa89feed9c1ae73572bff3a751e7d0f3785f2ea1e1a465bf94aa61d954b2f3e709618f88771e82ded68e58ed39ad8682665cc42a82e9efb4616846643df65f37f059dc07c03a6ef6f67884c6698f13a9d65ca8fb3f6184aeff66790fa852824a2ce3faa2cf6b1df111aeed04047ec82130d7a5936eba09a2db42f6270cc5a8a8ef6d8a2a8201ce07879760ea92827fea0c767b31286509d9896090b1c2c5ee86ee822e7300098515082f4b143bef75e396a1fd04d0ec2f4be1b20ae67780650ffab3356d10d62485f4c83e202fe315de5a9ef880455de0a6d26c44c47c131071bfef339b4a7449eb2a56d9a85c1d6c6357ea1aba18d3f45057cb591b2c01f091fa9a0aebe32871775948e7a49fea7d3eba54db9bc82836403561794332794c32e4d4c34a5949d83aa82aed3078468c7fffc83256f81e05fb0edf902b44439f74b10257f70071c19162f03bc7383428a42d7bbbe426791f0b9ac0714b4f427ad26850fb7ea479f2e99c1497fff6e06fc994bdf1d805048b534db2c03928d0bb08e655726ba99ae4ed0cfdacbe82075dafd4fe875a0c20753a5a5fb4e58aa86b20e543ccbcd5ade7fd0f2ffb670b8c9148fdf0c18e1d4c507c0414a127eabcb0c1c9907b9b431dff879de55afe016b2640c22c9cc4d375b7c27e266a745dfbda1dbd0ce648045c721fb3facbfa8c5a765c5febf5b9332c39e91a7f2dba4c02c05234165031f06d76bc6290fdc5a2d2a02a212173c0abecbce1cf0470475c4eb2b9bb07db52fd8725669dfafc87f3a26ed063f40bbe7a561aa55bea67d8e1fc042648cf3b3232a53ddb3960e7aa98d965c547d96820e3b14a9448224e0b8ea247fbeb1047059ac7098c982f6eef4577ba5a2e152364222d48e3756a4103980ff34364a111a74f8dda6d45cccaf5ee5fb9fbd5d7a0538cf4c61a41a177021ddf39501c8e247326e15145bbbbf32db785de6256a7d5f96083a25197ad2d91817b8d3ff0a8f0f642b07f7495c40c1bc8481e6a14e6a5883ef89d3edac71b6a22656cb374c21a137deb16a0aaf3149d4bccb6b382857875ef7e4153ae9da4ed43d92849cef21c9795855d278dfdd3d5fd21788c81d368f15d9c4b25b8af95aecfda15bfc93ff51d33fec73f4145b8acb4afd8f64ef26af129b1f0e87de59fc6c8450c51d0a2e5923d09987443a4552bb6df5e4f322b84088b69215e20c077362acf81dbf5a23363c1273bd1e58cf52dd0bec0717e484408d79af4a9cb7c52f9b72c71a83b13b04e2943aaf05915ec4122e64a75aa81da9d55950af459623cd076e87c47404d9d614d2cf0d48d54f1309deb6f26942cc73b503053ce40906adadf0dccdaf28f9278c8bab96ab84c612ad796d78e1ef5a15b964603f3dee1483cdb77bf7d0f055b266746575b3632d530f462fff9babfb81fd892ab6f2cc53b3ad7a20feb125eed8c3db82ad00", "6a65ac", 1, -1061482661, 1537743641, "2e4f560cf98ccf7c43eeee44bc344fcdd7c1d289acc005cab1d125b07d826565"], + ["9ae98a6c03dea91e2ef43b0937ad82e64e290a4a06c5229760eed9007dbfec0aac0c9f39c600000000015149b455dab2cd566ce4c2cb8ec3cc1882e267a1b13b9e8a744892c165de3d8252856401e0030000000863636a636a53005318649383b26efe9f7813ba2fb735cac31d56de146c15b780856b42f3f67b4df332321afa0000000002ac52a2e7817e04aa16f00100000000066363535251ac898c750400000000036563656745ec020000000005ac00656a00ae0f1c01000000000963655363ac630063536f85994f00", "ac515251650051", 2, -1397139905, 0, "1284d0a0342cc8612e18a30b9ff7975fe52c94237da69b2841c050165aa1c951"], + ["030000807082c40302026e5f09ceed7f2bbe34c4efed827fc9cfec2871384b3832f59d95b883284c6b0000000009656a65636a656351acffffffff20ec34899e3d864e686d27b757403782243662233872ea919f2a390ecc83e81f03000000056a63005352ffffffff04831626020000000004ac536565dd3fb605000000000863536a53520063ac6a541e05000000000865acac51526a6353ebd319030000000003ac006362f147cd000000000130ef58050000000000000000000000009c9f5aeafff0b1475220e2b170da4fc368c3e5d85d701640fd7e400cb79cc0b172295e8c6d9ca7dd6d05dab3e72c9b285e892e7cfe6e438946c2bf9628cd2a6ec363491b8ec14549d45eedc65b4c8d6598bc49565742aa96945f863c22bf75eb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005aa714aea8e1d4ba757e9d19992ea97eed8da209eb93123dcf0be9f1d797464bbfc5943a2a4130c58a34a0aaac3e88cf0e4c6c16f7988f6fb1da541804d4053f36ce9b6883660556a115544d66cc6fd8629095e915ec7fd9c78d6e7bfafc2a2cb7bc2accca569bf1a343ddbd9979997458ef544c180a780712895ee6c5ab8cb3031aa8e3aee28258dd69a98d2a88fe2dc5f88517d798feb0c5bdfc682783a38652032fedd70f7c0c1d39fca6dc6cdaf2c5c17d279afca6c355f9b1305aaa20fb39060a08556cd6f05bfae1c4a1a22e090f835cc117f192ae384055fa230ce12160299f1e2f1d60a4ba4000026850912d9c9557191f0260c0320d9b91ad5b7dc4baf207020f64ad348780ea5595edc8a9c48d0334bc8178eaca3599893f0eb81a4e6ca875030bd06b1f3216694c0f77e47cb35bf3b9cba59100b20a84bf4d5f1582b6101cb00324581c2d81ac09c40fce0c0c0ebd8d4481fb998ae752adc5661765319c7e612c0327d201b75cf75e5a78378c09a6c42344904751f76fb53bf44922bfa00846ad740303a816f44b963f61121a23409f830c3b9228e603af91e5020e6d037d628a4bc225b5a2bf480a53b40a85b0b56d7ed58582ecb16dd6ce029e9fbbaba47a0cb5c681cb1bfc87a19d80cc1b2626da51e8e9855c8eea7b3463e867ddb2e9aed1f278abe419dc69f127a2044d9d4fa20ab7fe8e9f469df8886d0496dd3aec8a25e73f66d2b7df36e05aab256f6070b8d120f66ab051ada8d5f210aec6487005995043016422cc2c4d7d08d7baea14ef40d4d9c6fd16d302ca83e89e3e746f9a95ab4abcc0da8b157b081e6f14dd65611c41a90513981fbc97c1e6d20a2910f58a63d45d8b280a6adb6ce7d98c62ebf4df4dcc30050d9a11cdd7569b8db8e155b5d783a891ebda96ea6d558c3982473e34c4f2934e7ecbe267dc173d9be787664cd2cc2a50d5f3404576f7c17e64c37f3036df7a4bfe28bbc2ca45b7086b3bf66f1675582627dde3484e1889eee598689597efbfa6aac0bc1cd22ca7e886e1985f873f2ce24cabb0ece867b39796656182c3f6f8a726f41b378b876a6b90934fb34c4cbb93ce29b3e86145aab2b8ebc26acd47631e9ab750a1562c64929769c622fa7df27f99cde24039f77cac14be0f0404cfad116d1c90d266e3f4718e05d585d9bb056cf5f380e0ee7e5599dcc0c86670288f2c6f42643116b8498d2d0924691881634ee853ee557c6074f99c6358b236d0db1cb2ec0aa8ff6043e41cd9bab468529ac3642f27a8507332fd7043516b8ed7cd1e0983c69e198dfef5f1456a100c6b6dd5feacd601bf0fe52cc4afc9cae8252d5dd86bcf02562b779b98a879d9166d30958c7a7cc69cff05390236de0f3d95b97abf35c0859fe49bd4977920ebe52459ddcdbe13b399a36f2e0e4a93e052b63bee9d61672afc8997902a3403380b5d00f70cee7ea42e2ee093d853f9dbf2d88bf6c5b2ca8c6d04cb9ad7e9c8940426ecfcd1d6293acb77dff2cbb995380c156c813cf35b9ea40a9b3f3c19a3b7ab669d27820ab2aa760f19aa7cc749765f14682aab1dcfea7a47afb024c6dbeb52670ff0d903be58bd0b451e801bb7352d8c2998484201a1effa111a8e14a9c5e5a7c9d618df7f0b50f0ded3165de11c6554def74ea0b110603f5e82327378d510905324cb98fb6678e70d6b4e54d04001a713a570fc57ab8d0a615812658ac0aeae1af95f32f3eada9132575b829d9efa073355f799c824fda54b671fdbd20dd433a57330383a924ee091953e0ed47a1cc3e27ecabd6e69e75ce51a26c0b4583434249a95c1a2a92561da03be3ce4237547e7368f502e371ab834eed7ad973be33011ed67bd3d9d9cfb42ddaaab65210fd45e32aa842be79b4baab01f751591e32494e2d735ef2291d433a5426cc668a32f1aeec74ad89345b8a4ddf3a3734780cfc0299447d09ad26c9fc1d31f476a893aeee6ac1e7f807fbe27b1eea24ae79649e3d28878c80106e0d13098243d57943e0c2840fc7e67b68a3fec5fb370daaaec7b6fbc138515b1c68859c13338c1ef7f8d60171d17eba6caa7dd4103bb5f63613874a0fe52b5e63caa71a8eb31d5829776cf92a51d5d2c010b8cf33698c0965c1468119ec60c0a895577d779793973fb1124850c2bc7b3631f388d29eb031928ac6012c9e5478bc8b9f7baca3043fad3fda70bd438585bb83f1316c1416c857b4fd52f96b2f2a04146a302a254bd77e906d8fad3da23b7e6ea3b1a28e64aa6433b0c24f97d682266dc42e910798efb5728becb50f0621a517ac801cd64013e9008a0d885c991f0058dc760f7d5c68551813509a88e689956e66cedbeb4607583720b85b3964d8a5533bc6bf0a54e258e8373d0c08820eb19b50b4f7deb5e448ce1b964073cd721675254dd8bde556ca18305", "526aac636a", 1, -2137542490, 0, "98b91cb008c90fb041add9e7bb8e49156662dc5fcb23f7ae2e5c381058b371c7"], + ["2f9eaa5202bb4ea03c5c0ae0286d7a957314912db050e3789b19f61206a413926425d2ae0a00000000085253656365655163ffffffff088a63ade88a071c0120548d8407db0116fcc7748a648ee1ba07747fdd902230030000000765526553006300ffffffff02005b96040000000007630053525251ac0af5320400000000035165630000000001000000000000000064bb150400000000a7cf8e8aa69ef68d3a788451fafbad0eb6601dc1dd6b58331ca371c5bb38f7a6c6133cc1496526c0c2259118ff3dd8572c4430567e815849ead0bfcfd1aa0a5fab2d752173e7636d57e6193c0a00e426eab0ae46991f403c4fa5f35acd82182d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba2c87c009ffb1de0d3fbe1b13340ccb4527d6a6d8b8acb815d67d89fab0365a455e35d072a159c60bbc60024704bc20a47d4060de350d2f3050539237d094a5bfadc875fbc5931c7a4456ca621c115c8a0d2e98d138dadbbf9cae1d373ae6256287a3ce9b592cb8f95c380950408db91ee763597b9ddf96d6063c94408fd900021c68eb08b6f28a1270378de8a163c2ba416ad5e83796b4c2feed27433af35ad6030ce1b184f7bed5c2ddab0b4433427ec7ccd79ac5f712be3aff12b953116934320a01e7ca45264ee717dbe519deb9217df1fb3931f850e7152a1ac6792f3e57db92c6f8f1a6d77d397008cec4e5d361515261bc26c9d60bc4144f88277445ccf55e031306ffc5346c5bf2d17afe9d197110ce77243d676d975c1e37b5d54b82b722a2032d0d6f2b49d6d847f8b06e01004f193585d74400e9d9282dd095bafe7fb71b41020c83c217303d32aa708916637ac91217ee02d0cd2c1f9f7a1ece48b28889dbba0204ac91ac3653f7b26267dd5232d7b40d88fe67b7a1277dba917ca3af170e5442020c0f4acb660612956378eefa84c2cbd255abe7f465cb0811b7bd291096211b9e49a65f091b72e3d120c4735977c869a79fc98bacfaa3ce545581a5fed2c9cb9e97e67bc7bcf6a735c28b05c5ba1e0b5c5797639df86a325c6f1d3e1af8f2794210f2b6d02e7a4b12bad936f0b6c62e9e70c88dc8cf3a2935ab44e37d70610941360156c145adce4d791e50569570e2e1b524306761a4ab591be049071a0906d529b25f461cc136e881f1fda630f8eea025e3e1828d5a0db5940d2530f5bb01791dbf1882836e6f81c06ac03c8c23a3a994bcae6dce4dc553fb6700b0549332ba2eb057e15662af4070edcd9bfb2bf5072b8a9994edb32d4de7b7dcfd56bf6585a50f511f63ad4de4a2e2852a4229da91c0e8d23bb737b38af42489f53df67e6220cc792ca275b89c34270ee6a60dd9af03c3a28f29ed8bf3786e628995a9d425f406c3a5db62fce39146ced1b28fad6a3ed2d2ee206143b01a64114b53dfd7314abd4305bc6a20d7bef4ab3ad37408319a6697046e80a75000b0687789812743f3eb53e0348002e2d9add701751d11dbb520e96e479da14cd4400c97bfd888ec0806b74f521f827a958211a6726e08394b13eb8b6d3084a46f7959508f6d82ed6fab8e96b3edc66c249b5403fa0106ad27512db07068a1c0c827b43b472506b05d696bdae5d18b3e2c4dc09f50f5cf7f19008fe52055d8ee73766de6f37fa87101d57274b43411beadde884775a1dcf17e82e4a56f5e4885901656e5ea808f4c23366082f8caa6c5447f97d09e6fdcebb6d4299ab225cb93b44da3124a00393ff3219f832f033dc1f76a393db4d90f6955b4dca0490ba405b852df471a5ccbed8bb20816e4b4e5b4ddc726770ac922540f2aae8b18b51e4015a02d7f3c531e1772d9b0d368bcb819a67bad79b22e6e45d4be81035bd128019a243359908bd9b1c50dd894b29fad5efd3ee7e7b3048b1837e622486a0fc060869181c21c4af5abb89335c3f94aa103a449bda2e61a26bd37f19dae780d2a863fb9f85e5acc26c98a086d1764b848b5cdd01590d03b5c0e884601697e8971ba197ecfc805661b1cd1cd5feba76bfc0e08af2bd90873f07753cf3c46bff6ac390fb61bfcd406d2bb7d025218ba6bc4bf5ec0d8b90a1bf8a8f4b5d03fdb1b6b8e9b34ec9ef634d85e31fa1b9c030670d9ce254361d7482e882d8433fa1010caeae5a707e588fafb516c9c2da6ad647d19cc2da48944e19aec1c5c78215527143ddb00368fdecb9d9fb1ce0b3b8e65dbb0181f3f0058c13c8530ca635bb247debb319c7b318cb345c45fdcbaa7eb6a280fb22086cbcc9bc4db5e0725ccf389048c775cc71d966ac610cb7903859a9f7d538c7f97db1be866cddf598ad8a0500b9f8b863bdc12a27c8cffc952080d1a049d8190c9ae2d5fdf41e0c9117c361966e95743ccf40a29ffc2ed60283774e8969be5aa1a13e61a3825fd5dc2e95f751a0d866706344672d7c9a4cb08d0f3e339db28532a353756384bc865a6945891043feb055bbdfb6c5f80b6cd82ed867922d5057a9005be6649b14cab2ddc2a3c9f8eb62ba33e98d6278555a0092aecddd36b321eb428da3b4a8bc50f3df09094b923ac77746f758c5e2c5ffc308d1469d0c8e9d0d3ba4f461bef76e5a9ea94b3b69307636d5878c07e1db35e2a5dcbe6d0a7d2cfd6ac1048bef6c23acec04f7b461abbf178c2d38e0e0bf91ce791d6272add4df5d2df320bdec7a902f618c293559144ae2bc7b42978babcd7ce51024f841faca77ef316370ebb7312c1dbffb0858ee3765d6e1f55b30a5ddcf695e983fa88b77977f29ffd9ea3851b30135a9634459dc0b20708c0f629145252e4cac9a3b3f0771b37a9b22b584106", "516a636353006a6a", 0, 1823461283, 0, "8f8543db77a3e02a6532ff83d167c92cc41a53038addc15f51c2e0da3d8e476f"], + ["607d5461023be04301ce84d198585f995f1c515ca00d5a60c09381e9edf83e367b1bd743e6020000000553006351003458eb54c656df26b45fdbcbbe3b656128185035b4df240f153ba2a8efdae8b1c864fe1701000000025300d815dbb4049dcd0900000000000452acac002cd1200000000000016a75b0b900000000000251ac6bc1780400000000000ca3377a026b764b050000000000000000000000008ce102ccf3c8b01820f6bcc697b2d500cf9e82af568218c164dd89670519c7d0ac4d7b4611fc4044088e92cc5c98675f6980f05ab96a030f4b209283e28be5766bde96435ac2c0337d04ec6c1832fdfbda2537f5d3c0adc746ca6c29ef44c4f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a5d87f4416d20a1d323164e6199b8a401777bfa118f107107ce1bcc1cdcbaf9b2a7a1150ad306a2f09bea4b13eef591f1e1399ab9e2a59a755ca0694672e2b53c6daec661d56247811d82e2720281cfc5f978b8cb0b2a490164c33097932cc9a0078e30fd5e2c611f490542c4ee720e3e25b0923db84f86c827190714d025dc0210ed8501a064ab726b9a2470c0877613d440eb378287abec0cc5269d7be4b188022d2714ff1a4de0550a28646ea343f0b319ca409546179fe1a4cf691ade980da00a03b1291a4061fb70dfadeb936f228b6bb19fc725c05ac902c6bc5cbf9e82f786dd86baa0ee8dde5e10aa12fd04eed988010654bd772a252def0542a3ed36d1af032c8687222f5959ec1c0136719fa1ca195ef5b860db7fc28f98ddf57f7af87d11031ae2b1d291371debcd6315cd221b191ef65873775d3bbafafe1d48eb4a8beb1f032207a924732b52303e2429dacff5065915a95c246bc633ed68f410568e82ea4c0227bf1149ee80730dcad6b9598639a88eaa603c9e7cae9e881cb1f8c0ac66c93e02071451ec7789baab8cef1fe933b0cef5870bca5fff07b1fe7a41bcde5c8536a2d7cc0b2def05b30330a282a40e3e06a5053be146209e33aa856a24ef767797bed15e09d60cb65345154ba3a4beaee39aebd0245d42cd14b8c6bb75ec805948a661e63e21a6529ac735021e3e074334a7f45040d2ed9444d7deaeb4ab935f24861634c1382de1f2763400b425c870083894ee5b03cbb0072f912a0d4e0bda35d103b00fffb35c44653d41d873832c9acd34fb34c8f1c22f18a7e42e4ce8ff94057255a244dbffae10c6f5f1297fa7958c4a122a3954c412e1ee084989d8037c0c877852a9dc3bfecb7695f773d20c970cba4369b3186a266c30b9f1545ac146d9aec474c285a7f9f9d50be0a7e8c9e63aebe293b3b4cb664c42052aa98fa2ffa65474c7da2f2c9b980014255510755df47e4a88e5647388524216b9704aef71cd6d003d3d0f4bdba212117e5ac2be7a66f8c8d2bbc9cd4c29a06885add55d90dbd89ddd21fd42824ac6c72e4ef5f1ac0740893a2cd350df67f5c120ac4f86cbaae86879241202658b5e63b95ef7baab97ca1b135b554a69ffc775ccb49842dff12e0e2f4d6b7e77fca503aeca6021bce474ab86ab398275a5c7c9da8cc87d401a1284a58f8cbf81c504d48a62f4c289ba0ec143b51e870e172a0497e8d4397e6a0211ed26cfa1c4b4154b7071e4fc2c5fdf16727093bd30fb3f9f12fcc8b0b12be3095ac9fbc1aef316b332efd92df5ff985558d9e5d1958d052a2606195ea6997d3b06dd156a9a03c1591e8dd4fcad7f8c708523f2ddcdd2721a10b12372c117d2cb74790e39f7c9a97ccbf95e9128a3659b56ea8edc3fd29669160b5f6bddb958b4bc08bb82a28569dcd2d128926ea205cde1371d3f42e1a3bfad4aa741755e6f5dd444baf809c3a660915ad474593685f0c2c9fad3a7327b0a519286349aba2a3abd1c4f8de10d522a2949d01eb8c3b14b938f1cb7d1de4e6475e233277028fcf17937503e2c31a00deb74621f7e504dff152c7147b6687bb72925f0adcc79c852b7559f451911fb95c01d95266f40e67cfc3a48cd67211c3977d575ea2dd8d475bfe9d8d5f119b62964f86a9501912f5fd5980af4c672eb8a4967b4698708a3d33af4207195b25cf4d8562266b3fd280e890bc47f4c9f8bb2cea18cf1ff33239e8cff5889dbe1da52534a5eb295b3ffec1b73c6ac48d3a04e9b6898d8cd96f2af88656a5cbbca78f6cc28c55942505755387012980c003ef7eabfe2f2c6cd239c5c2b09a050c37d08697165169fe3263b7ccc262f2bab3b54e5c768c3bd2dc87e5c4b1015490bc8f1ad54807ba8d18913b19919900fdda1e0334c64b005d58f080b4f4f2b25b52109bff7b6f2dfffa237d785560737c2b5696b44fbd4d541666fdab71a2d2648e4654901cb37bc6608b4944ab7fc994323e7f2e6cb36207e5c9396dc89c81654a6473eaf8f90aa81396783fa40d7e3be3011baa2f052c0fd7df53d1cb13155f7b70fcb69c63a324eba49106cc94e4dc145d5f5eae47ff4745ccabd8f829264334302acf19d4ace5e952ad6d0f5ade73502ccbb378f15dd088a4027b98b0b3f93ecf9db5cd17cdc8c8c7323022741d2813cdf3d4e74289d0a86fa009070906edb1cd71af9736b33f601a038d6702078a634d160cf1fbca7aee30f386925495af7c13241b350aaa4ea3337f6d2fcafa2a272dfbdfba211613626349bea01337fe9a89f0148eb4e18d5b0271a94da03000000000000000000000000b62daf8ba0e2410489722bbb81e74a8061faa38e1cdd403b44ee3c7ff3a90ab997eee9212206aa9622976f6e6f3ba19dd1b0dc9acc66debe5478e1b648933851914863598260fca2b28b2acfda99173523f03d97bf650c507d0d8fc0d03ffe680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036bcc95da2981e883a4fb266d7237d6f5df1361335588aa819d07ce3ed868103ff247ccf58aa0782c4cb201e4a08aed3075ae60d5cbd7ab0460b353e7c55a546dda57b766bfa8f67b5421a7e9881699d2f1cec8f9d4218bb51c7bd3004e2ce602d17b13f822d0f3ac52d4abce58432541fb52646f0c4fb15655886cb6769c32a03223b4375c5098c8a893df8cf97e6f5b26c7de1445ea956a6e0eef849a86d591f0315ccf5b79259a2e48a3dd118df26fa10abaeadba50f0400c1be9443475bfffef0a066a662e379dbee0cbf6c9ad96f337f701b6aacca3b239f441a6ad992ddcbe454debe55df6c94911e2f7437cfb5d080f9822612a9c60b9b164e3df0b73d7f4400321d627c567fde0a21d882731e724a6e995fd4f72a8373cabc903a104a28f0d070206a5ad3b6f9f5305f42e1fb0d47a4bd254b1865782914ce594ddfcc0522b53c402057397e5dc42db59399728740295c05414ee9a52541224a06fd81018cf66488f0214c98c8d4c0d30cbe11103922098568b75085c053ac6bcf6a6f181e498b77f400303a6bf5a34a42cad1419606fd3fdc533bafd38b113589d99ea0490c7bff58787ba2e2ac1a3ac44858017255a2ee76c79d704040b95a8a159ac8662393ee4bdd377998c0ab36c9376ea2f04bb2a989a394364411998fc657e85379d0e59c79b141b2f4967bd2055338ffaeb87b2b803bcdec98dd506c2aa6012a42264b11c15afcfc608d42b9233a2dc60ae693e66c5fc69b7683d2ad6c0a0361346e32d0bf4380ed1fd96ff2a8dda3d9fd3d23fe174767189a464e4e3c633f5aaf14b5beb1599a5a239da575765868a351831530042cd5e17a2f8a31eedee2664b56dcbb0c9d62954a293dd53fdce54c82977d37d1c344230cd3d37b0f0eced2092fa484cc92b7df78ad501074b83e2aa537507ea4093bb3aa6af11d97395a95657920e0cfbb3ca6d61e00f779c502b47e002ccf46262ba3e047c7b70c24e7825c4d48adb2340e35f3365fc9148d86baccd8778a7d3b723dfde4a07dc3740c41929aaad92ab635afa2ac9af0a9ccced5b40f454a145df78ae0c7c24c2473704d26cb2f84f69b3c60e95760cbf695c8dec5e7c4ed31a5c678ae0477bfcf05371a57dea517e023efa5980178be24560ed3ba39c455f5ab71a5cf82a09295bf616c739567d9a7f23017c4d2ae63900c4a4ee1707b86818bb83786acb6354240015e0562f529eff84bef9b011466edc8a6adaa5508cfc6fcd68df5c5979066b29ac5cd002842052c8c078d8e17d778547353e072a8e59fbbec186806fc5e99236b7b4ae90f244758040368e2d351b3a9dbaace7b390eecdcdc4931f7f01895c1d30010eef5aec9010b5849ba81bfc528a895e5542aa19dc8f0a3574d235ae045cf586016ed2da5c8f0a6f83d416e3299c8130e5b46a748879e8e06128e27b8ee3c1ef18e1438e18123516e6354ed18958cbf662db7e82b5b0267241ad6d2d5e074b6ad4c932a21afc8de494d5676a5a458509ddce9adfe555a149909a9bab71afd5a00094ea0d6d3c19c5b68795424cd6191498ae121716e80d0787afb895795f949104a1d16ada31a252534979a48781f7492674284993a351a00e4481ec26d7e03e955386e7de5a6eb31416457ffab5be4e5b25ad0d649aa63184359d9841ddaf9db4faa4c1574b3e258d9d22666736da6570d482eefe33a54fcdea6cc66a987f2c4c8abe5ab531d6c9ca139a630d59d15a2b45b40094b5acf67c629ba4bbd72d2fdb3acaa180f52dc8db58927c66c4fd0677e8ad97276b251b8caece38c9d4a6bd40dd7569aca5c09c7286b51b4efc41ab40b5ef6c5fa9b65d63e1da655528aa01fcb89cbc5a46a9cd0b6f26968aa84ed68ffff18f9b2e93333c905927b0eb201638c5405ab3b553608e7fcbc245b45157363f0cfad4ef1a97575175bf5f93b9fe217751895f0ab8b21251ad6190db5e4ef8d9a3536d3dc3a0ed1c31c9a292c2ebbbb55d3f9fb213cb1ffab8e2d8bf59be46b68982f8990c0a23585ccbbb57452ee4eb7021d9933a7ba8c259643c50c6c93a2a278485fa9e50ed6293c04773ad119c19399abe062969ed1dd3887871c7639919027e08394e08bbba6523422a763401825ccf66ad38c85a2f084a1b4b55bc0f57e6799d330327f239bf94a7408588b4bd2c1ddc49840a1044f63edf1768f4c14506043c4df36679d98e6ce637d1fe31f5a73b82aba33cd790e154e01809b5af0f57b2ea8be5a10099667516b6f1272277e7cb1b90bc685e5cace6e7f02dae65587e7f10d77a63ac743dd1137318c5e37a4cc8c5d3ea06aae43a7085bc995746aaa14ca57f987b55a77da9f1db365c44b27d8c4dcfccae3f11d5eb69d619fbf44ffe5eac130d60728575afd65988dc907fd953770407d97c0648f3c089d5ddc2c1e3ea795dbe05", "63000063516a5165", 1, 353261683, 0, "c6708f7348ea020fb1df9965b191a82dca940b26756989c29ba374650db26fee"], + ["a5928e0502e98874d0a436eedbfe91134f46b379fa03dabe573981c2c6b86518ad8b433305000000000752005200636a00e1b63fae2b728584ac3141cd0f1b52b04e8afb1652fb1f67b0508b6e334e9fc0ac09e0f9030000000863006a6500636565ffffffff036c51e201000000000400ac6a6aa1dab0050000000008ac656565ac516352e853e605000000000465656aac80167ff7020000000000000000b7d28a0300000000c5a7443181a908501934251887fd65687aa94a5881d006f0266f823cdb3b84fb2bb90a32ffe30bd822e365338dc9265b64432fd33d81919d0594296d419b462f2176cc39f9409b4460ccaec89f7c56862db2b8ef8d989bc6fe242d4c063d81900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043a8349a97f8cc28307a09dec69e62a7bfe411a6a9eff06bb37494877da6d240d4c8dbce591d99a6f6467896366c31698ac79972a908236cfffb3fda4fc54e1e61111b47874fe58dc012909d1079a28be703efaca6cd63646fb0a93ff824b63b302ea797e3a5772be874ecab261ee7225a28551919a75e5b5357143a3c32462f02155f1651c1d3b9c3a5fa9468c5ccaa1d7ddec0f7871081e1978cb57e6645441f020a89be40619bf6d0c7b4e45f1bb56a7b570599081379bd7553b43611f1d7e2e40b091fcdc084980ab958e94daf03ed06462ee86122dc8a791798c7ba311ff654900db7a5e6bab0cc6a6b340046fe8c2f2c30b09ceff196ed68fda7d0ffb47b6ccf0329e7ff8b0231743371f76c9d5d45cb3aa22234f83e890d7153bca6b41b0b9faf020a265e43e2e2179069fe5c62cd8b4961c7068a1e35aa725e635c3c73295c2fa80301ce93acd29882474c24e14d064feaa55d0ee12ad1dcd9ba56813093aa77ca2d021b64a3ec7cdf57bf1ee4c81ac7e248c8b966e4e41523ae6a4f00c03ff515689c022a5b3b80879d5874d676117b1dc88817a30cf2b8e8f06af13cb28a3a7f8e469320f140d51657c36989f1575ce4b8781f24d87d285dd168b858c23a3235308837466c485011b96547b057d4ff9673040d467e0f52cc2410bb4b0a465df4f27b7af9482bc7144f6a365f7b9fa6184dff92e64cf04ab99b0eb237d289895be3a0d3edd35b8bcec648400e9502e54441a3db860f759788d22591d5251a1e938098a931abcab52604b784689883825cca3f5e8b8e8059fb0be613d9a267b4ced6a0b24482852d1578b9921d70997e10dcf9042dab7d8df36da1d30101d824570e86bf90825c8d8dc281340f5c3a5df5bfaf6e9c99745546d8590be9752724d2ecf4d5ce7d779bdc7b839f7d224daef404f2210f5705605f02c30fe61acaeff639cfa7da0c49884e05fc3853c519c08836f743ebcd66e9fc3ff138b04949147d129502cd08a0d459aa97d7a6087e30c2def2d3fd62bfff8fd77d5b959dc8209529c2c211f8ebe2d85cfc27dffe3caf4d1485e36828a9f260d62af2b4d9d3d72182abe632d99d4b67c870ef2bd431625607d46dd463410a6c76c04b2b88f1576013b199547fac4ea318d7436e03f7c2debc28c15a131e7d61e7971901ce9946295008eda972d581b2a17434107a5c9ac07ed36b75ead9eea4c05849fed11bb54fb35c186dca1f5ac8327697cb99fbdbd4800cfb5b2e1aca5adf75dd02f70794da684667b4a29bb372a8a51eb8e721455246a0dcccd76a40a42bd961e3d075f7c405d1328af70e0c7aacbd35858057594291bab5c87cceff84573b9f707683b275f6f47281cd68dea1491213fca8b7abe207a8b6679f254b94ca5294c58a57bf36a82bfd60878ed0b1bbd3796c0ec6f05205cbef21e0eb2e4b5a79ed3bf8c32057d57890811f0794d964e4ae0dc392979ce3f757795874903e583dfcc27a4a115d66aa83805c73b0127b882ff133cac17747b4d012a2f04aa698d5f34e0d5df7f7a30ef9a3254e551d8886385c98c1bd42641e5b6845f92544a2388782e58fd19787ccb8f051623ca33f71d72f21932554f5625be0d6b0856c7b2f430bced37daf223d9852b9fed5c9ede655044c1578fa41da0ec4db837b991ac98a27cd2e0621de02cc77bd4737ad75d8d209c53c1c644922a0536cd5675a17ee6fd407e503f4642e50e6baa2b1755562b7456398c21a5e6998ef8ea409964219e810cc0e76eb1b63a17ac500bfb12cc52bc4b9237975b124bc4d1a80678b9213481a48dbef6552ede018b9576ff806bf575707301ecfa4a831b09065c69a89652a162f9a83f38ff5db6a08a2bc7df3021da5781a1706a266fb11cd54dd22081c8a8ed0981f2a167a9ed1db741339675c4f858bde93f588dd1defee4bbd8047a5efaab7c8247f0d2bc08e208668044e54d75236a38a236b31c868bb55688872353e6c43a83423481326867b22780cfcfa5b962dee87f7c7166e05535867378717808e651f8229b2aceef3e26ea78b327516f11735912d6e9fe4493116ae91e01d0bdc1bc20d9044e1085402575f1e1642a3ae39895e6a12b923a77e237a5a99d82c27c042b6ab60adc3d6a062bbdc10a9b5f5d53e42fbbad2ee7bd70c245c397d4e0c27d53fbd3b68a511e3540b6492a9a42a5dabe049b197ab0b587361ae5453a22f344ee40bfaa68f555a1d1be84b0310a6a51a89e6f9182012a179e3dfe2e34f9fc0491544ff4bcebd695752c3d7f5218ecdb94e2e641dad2e2530ad9a050000000000000000000000005922be6635611545f2b34c29c9b53d64e2962f3d6ae3dfb82e0305e5c63a96b727138ab7cbbe1e5d75fa0a51843bbae2cb07893de10b45b03b463c3682d930ed69d98c91aab6d85888205532404d90136a1101865c1b3581086c34d86ae9018300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3b12c9b630d16516384738c5fa1b1df2e6d508ecf6e05509a00d442de2d2172b6eb4e44556cc26609d90ba23293804e6de426ce4134b1540587a2c79360e4eb056dce4a0424c7c981f8873511cad08834132368309b5f1e4c58f63289a4d54638c03b70f368bb8cb8108d15747a8b38cf795b339f85882074b93cc3d943df90020072336aad3c8eb527c7c5bb040c7718f9da1cd04e653d57b024504c9bf1450703289c67b4170d885af39e1bfcb4d245ee34a4f853a7154fd4b9f238c98e0c68220a023712f867de3d7dbf2b716d0f1973e3df2b85daa36ac54bb0ff4fd42be1fa533f706f517547a82a5c4e0584b5b85628427299fc000a471f98a0cc8ca51e7a8b022d6fde23bd8a96e2a495fd6646dfc716dcaa370bbd8caa99f770fd96ad858655032a355e9c365998f92ab5c29e6c2d4ba460b8b0f3b8680ac294bf77d1ee983c0902269e1cf246acbde4628f126462042ef52ed04c5228830b4dda2b9f5708b0e31d031bc3f1719ca256ee7ae8bdd7dfba5468e0806e087c9ab1aa8a0a84bd8da8ba5e0210d4df9ccba9a1eaec377b1af59ce528b267c51a6768d3de2c549d8547d96e4f98d742227c0ddfc41d1ad0d257c59516d04826d1d12d430a6210a1c432f8d95ca7cecbf7e532621b889186aa91a871057cfb81a8cf77f1d6fa978b64faedd051ed4c8a6bff87218fe4404451719f3305f21418a47193c2eb4abe45c4ba9c9f92e60b09a5428d3912c767ad0c2967c3c9d94c1c7ba7103bf4bbb381d822f301fa9b0bcfe8ffbcc211352443ccdf2b18ef1f4a8b19b0300fd86c26e3266f217bf46c437b78b77b23752e7aafb90523dfa3b8a1d68f279a6a5b600b270a81dafaf4b03edb7657ee98166bfd2b0c347bd9bc28139d820413847cc21924c457a5e9725ed6245cd012ef2c19fcacf9b90958bec4bdfb3664820f35deb108a109f3acbf9f303628693fb8728dbd6e47aeb54f47de81b9a12d6433200deffdfa657dafa799c288e9110850150379347124fcea65f8bdd5ee06c438560bd2082fbc18cf1f0875ceca05f026aa84b45e4e55c97d671e4c60335e2b1d69dd532bcbbbcf06f3552791ec39151536e7bb5fe5514feb572181bb2200571f1f9f39078c6a393b02c628f2291e14ffd74664db3ce9a735434e4d00b254b104839bda260a94f29b4730c9c6579d1acff7d72f17277bdbbb8ae4e413caca99f0b08a5dfdace64c8f22ae5a4e244022bd231f29043f6f6159604a4c8d9600f275df51adfd4d385d02463ac35d5bb16a8c0fec297a0a009f37dd9be603ce2ff0469b6c4a407df7217425603da6300e9f82c9a73fd54e6f6979571ff0f23ee9b4d62f91d4973ced8f1cd99a7200e5a11bff50828a2881a5b7e4e9572324b13236d14bbb2459b2433fdf20af9bbe89d27b4a2acd76778b384c90a2540d7154d2a5b7301362b0958a3af6ffb70377016b488f043bda68fa6bed66e06ff991a9577fde36bde497eda07cb424e505ea1b52c1f76c76589a5945594bbddb417d56fab741856dbbf4088950505dd1effce067d9dbd001dd8de66a8dae62587428349b3fdbd87be9e37fd082395e5f3d27757fb9b0ac72bcc4b853cf54301aa178df0e8bf59950917f011d4b8e788f737acfb84e0886fc1fea1cb29ed6b89e9a550a1194b8b72312f5f9ee71f0eb2fb3b425158711669e264972ca89924e0efe5c289d64b91760b25cc6d8a5063cec34f40bce392da625b862e1b32a75b1c1011b2280d18ad11abfccce6f8a385b8739f947c7c62e125016a7cc2f4aab873afe622c63e79d1f205e6e47d0b8a2c83e3c5f802c6329c98545cc7bfd9f002756dfeee01853cafeb40f8adf9febba7ddda24ce63c335c5dc9fb7c13d0449b29189a98899a680b8de29db88ae1a2c65c46337d0b16006e2fef791b6351de064551da5775c6e179279bbede8041ab13d02bb234be9b9f84b010a55c95b4f32dcd2b1582634a54ceac14828e4b2aca481b1c7f0485f4ae08f9f34f9014c4ad6fe485e99efbb08d79344dfaa7634f887876916ab15f7d3334249646c2c75d24574246338017ab7d52041b1928c42cffd01bcc961d3b20e5e7fd01b96e35e6b9a26cd136f2271ffb18fc00abd058a26cd2fda75faf38151c33d3e047e28e5da1d35c29f10625a7dd878e3a12aaed6652c39eb2a0d335347b6befef7d39a180bfb9702a3b8b4391cbad46bdd7914628e3ca3cf194c24631c6ff05d928f8cd490e1d52b44ed01a97c201c1fd4801b9878528f7940c4c0dea258974bc06b87193a6a622de33fbdf6b44aaa710e959ea1a36b55a235e5184b81c87c0dc0c3776b0ad62aad255118e4f81f85b7b668712688b255239b6de5ee2751b43c327c2aa7de8b2938e78efd819ac5be3ba7b71aff524bc480c17e018cc8bf1015edd56dc23681c45000c", "", 0, 1217284831, 1537743641, "5f2e98eb044ced84c44d317aad7b99a446585449838ef73d052e36259848f826"], + ["030000807082c40303cf61ae91cb4b1203097eced4fed61becc080308bbe99ea15b8adbd5832189a470000000009526352005351516565c0c970c72b64cadf0c9f817e70888d19f7196754de18c01d75ff996ea859835327f99c3f00000000065153acac6aacffffffffe29f9e19af3a5fb29c714940ff84691ec75070b671b41c13ea628b2f1428f304000000000500ac6a6a53ffffffff02c997fd0000000000036a006ae8e10d050000000008530000ac51acac65f42a21ef0000000000", "525265", 1, 1436171982, 1537743641, "4826c3b3ee9741ba34ed3c849113d184cb592da8f04f735021160f4887ca8a11"], + ["030000807082c40303673df78e5cb0d6c91c81181fee3928f9c29b86863e848198158ef43dc4e466f203000000036a0065d0b7f754cbdd2e48d2e9516bdc3fa0618e8c2bdc61b0ac6ea360c2843713001790aec6010200000000ffffffffcb6735c54fe58065e9e24e63c853181ba28ad81c8a34eb3390b059f07464e5ec03000000075253ac53000053ffffffff0455c51c0000000000016a54938a03000000000352ac63a80db60000000000040053ac53ef14f001000000000000000000ab6039b702db79a602000000000000000000000000703a69bc3b98a1a9198a7d443686304a922ded01e93513e4b1d8452615f7367bcb99dc955dee43a8db4ecc8e4a68390157f9713c21266113cadff76636b68826fa5f4cedeb38bf59e4827727f56f3da30d0fe09084039e2759c367820a09a953000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006510ee13c42b440d5ff75245230cc8ce624038ff5582f8529ba7cf609dac169e96879fea7ae94b97c37b0b9d8525a0042d33e6e0d6c4295dfa9af5ed5eec391d39b86e9ed194f29b53b4020dec2db362fd2a4ca64e5880335c7d88f9ab63a7af7290db1602053c83de1005059b30e9779f365ea44251f1abac001998ba50613c022368445e481f45ddf223662ee5118b6fda429d0571ad2d4b4150cfffcc96afee03001bba152a1d7544393436595157a8d4a8fecd68024fd5065ae6224acb8afed10a06d3170d4aa96cc0606352fb48b03eae81198c7bcdc328a08ea629e8a91d96c912472e80601360c41be58941ac9ddfd516c61642d5061e637e9c37f01d2a408f0301cbd7fef3b4c50ef5f769039ee4c848c25c76d0aaa435a1013d508e1155902c02137e1e75140ddb4c7744e3a9b0bf374e585c5c120cf404491b49680deba16c81030ad2de9b568462af4853b5c087a1e9fe846001c715a2c2bdd61c664c4d1f9ae702303c86e20bbd73be2a1f35735f55d16fb470ad22ce879c3c6455899c99600f83032f7b3245ab10d30f271337cea40716f6e3fe9e46045175b018cf72f5649f832e917a42b500dd7294aec22bbae1bffc8265808e12decfcd5e04131ba556fd3cc32e9b91ce6b18a67aee01afa9debd749c63d96acf8beca12bb5f44a5519041ed772fb47694ccdb1f515014113e80b5e651f737a3190a5fec013deee01965526979ac3d0e009d2f77f2ba2003d6547d16dc4e81045b318c9df4326847779877b693ee4457173575c370382b296d0a49a68805ae0f3c2879a8872dccc8f1165d71fe3c89989c3e6907157dc3b6f34ee91e03b1133d04107740cf1d3a8ffe8b0de1741edf94317de2be1b3d3991dfbd1db1321c21d9fa83eeac21ba02ac175504cd42b94aa15c6317b2c39a59d9c654006ee4bba4dfbe680ed29360ca8e8261a6913147d872ad6845f8dc1f9e4c4cba57b8caf31e128c73f92b19a0ed95d30ca1dc5fe83b95cc960e7254db5fc27080516dedcc57e70f7e2a8eae6bb6cb77de30aad32ff25491a16d996ce9db6ef3342f3c283c7c3303d640f9be07b2a78db37e2346a2d628d86692ca2d6b9f87a379c866724a2bdf53bc4aae9c8bd1fb0725155a1a2ef56868efbab6ec1be550f0e3775a17e8f6d97c70d2e291abc067ea9db783c2dbaf64f0bc6cde385a5efe6960fd970be88568f1e8721f1a4af50ccab1f87b214ef6e3e837bcebc53b48fda157e948850ce85bf48bb6c9ca6ece48b3a0aa695d02a0b2684a751614c8bcfed5492672a12eabecc39401b02c37119576d8cfbc2fa642cdc7eeb489cd1eaf595b6afb8d3ce5620e9c661b6fe748ff53bfdadc170bd651e5aa7961560efd4afd1099789b7acc86eb394811b8dfff373d4393ceac8fcbbc1c045303a6d6a6b440e9afc9a9cf9ab612d5e7569eb5a1faa41023d6bf7745de62d97c53311b5385e5c9fc0c09783774df497b85a1d723d11a2f3ee313dc1d24333f15b3c8ffa9e4f08776a6635fdcc0b8148731f1609b9d5335ca5327ba3996798f6091c5653d6eaa964193effcaf1cfbd4a92d0752f651df2808aa111526e4c6e66eea70259b201c965f0c70f91ec329ed2d102a534a8482d55eac26eb53af1e15e116f391682faa9adb367d1e373330f969293f1772cb0470206fa58b81f925760941752470549e5ceebff052ae07f8c6c286627334ee11ffb17b3a25076aca37c4f88cc3b8fe0333900f5bd97b1775c5ed3e8acad444d2c0967dc06fb49cffc655368b29e628cc93fb4f0c2cf0eeba6257c9897eb7d663fa5551bb8f9e9f510b63c86e3b8cfbefc01ae6599c511d7ed4709f8198433c48079dbebcb93d576720dd8f490626711ae10ba49c9e60373bb3581b28c36ba2e09187abc1795073bb503f0c4198f3356ee0d0eb323b3ddf90bdc9bb545e9ae2cca5bfecad58a0a5376550868662b2412f179721bd1a574839aa5e9c0b36c3788dfdb4f33c7852d5aa7e3d5f52c6a094d3558793f0c9b3ae84591fdce7044b5004e8b2705346c59bd6e4d11c6021965015f09df4976778128ef828421203c2681329beb3c4a7967a6fc67061dae40c97d090a1fb98733154a2eee37dde8cc5bbffc23871c0eb716496337a179d305533058db8141eb8ef4fac558258fd97a33029569329ea16303e056e5c0844ca02e521049b963d11dc54a8e4009d686fcd57a80902580bc90e1b5f5dea596bb1f524483447dab54563abc49a2efc6966cfb43cbe41d8fa1b66ab533b9ab852b38721dbd28187581cb450000000000000000e752f50200000000368b0fb46b8f282d2d12a00745be97df03a79d862bd5aef4d1d9f5f1d4f49a4da7503eb9e8282ff54eded3757d75c3a967785eb3329f0aa7308b7f333d4bc7cedc805588dd662c67c53bee2ddb16f24fe76e7632dcade2d5dfab2b3fb925b43e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087f6bea3384f217b553fcac5efc33b55b837994183876264526e9e944050058ebd30bce5f58bfe71cc26e6b78c22f48fb61034ba0af6dc282fc53a0487082c8e1963fa413bc439f4eb3b6696f3b12cdbd7d5bb87ce8ec3d5c4be57436a718cd513fdda01f51658dba27b0d44d857d9d0fe6ca9ba863fc72951b4aaf5e3a3059c02217865d365b541c2828b235c4d211bc3229cd88368d0a738e7b2edc1ffffcd7a032eaf37643c2275554c39bbb7b133d556abd298c5e75e99e8345aebd0bb37f8960a0526bf6158e8111043e3a15a92078df6999bdccaefc477e5e9d18e0c1b51da1b27e59f563e3b34ce6fb3de18f89d98ce86452d4dbd71b1c53570c26952bb0a6d031f940efaf30a923783f7c761a965e90a8bb6f601b6f3abda960e1d0b98136ff9020f54e5ce117b5fd2d49ae7bfbd6f132d7c5665a61d83494db0937c207622ada4020f9163321c94f96412c008159e24bcc9b374bd427aa88ae7712b144826029c90020cd33d8ec7759f4ccebd8c7b93405c7fd4e049328a7e7f1f12030ae19deff0cf0201de62b43cc8bc7cee1e37ee2bfe779fc9129e43cbdd7613b1e8ec1cc12eb7d26537778d8ef1df58b34be3915cd89face57ac54f12d0f4fc5a62b6d0f1c3c1d58875f0c6fcfae446b69a7247768bc540dfeb179a1e37246ffe79a2ad8e9e9f0675860ca0420b93fe5ce2d073ada94bb1163d1ff7c45e86cfa8d0d07cc658bf2982b823537d5763685965e73ec747fd01e49c81136f8988e9c7764886dddec10c34098aacc9b06c93d74d861d89cd531707436cda7a97881026d0342cb0a67e2759d96078b7a29f76627e69aec9eb58a3be1552d875175f591f7a306b1922a0f0ead5ad8ca583253d5f0cd63feaa92a7c3fe1052460d4ca3b7e01add39cf607ff569c741f2dd95fb73c592529c034b06514bbff8d7d207b757b41ce2c03c45fa57b52a7cba94ff7f66ecc712063b97a0a5a160cb352008485ec575e305ed27fddd5eb5e398c857be63d5fed99a58078976d5356cf2d5b42e0535ee8edc9bc02c83237c5999a0eebcfd35703fb2d289fef28bfa5e524ea1d2d66d2823146ca72bafaf96155d9cafb9818e4e556c356e7a269862e15bac299057de93b58c708fea86c978ec8376b2a74f10f2971c928c2879fa1ffff59669ebb6f1710d40fddea8cf3ee49d01822117054c43f1446aa34f35c66b7946e2ab59adb892a79a651e1b4a89093e8d84639941e1dcbe0b799e4c599e530f9f24303a398c602c21439a268bfafccd5b93d060e4d153db9fe522034460a9963047a647cc44af94fb17e592edd053d3205285c165386ce2d0ae5859c6579f0748769ac4075774265d46589dff30f1cbbf4cb3a8d6f7d9f5b894817560fe59b54791143a7b9f0506ebd8487d15a44fdb3e346e64cf51e480354d408964dda3accd1bc42532470427c8281b56793b51bfbfbf5fd92c00b1b63422ba7b0999b23f9cd79b6c400046dc789f133329f547014985386f35e9fde151c0eb899fe3e423c68f9acb117e4e1566423d79cb5e11558814e1d92cf6e84199210841712547c24e48e6d27d0ac32a4f008dadff4a0da407a187cb9b346ed249a2b505a3a363c19b30e5785a10b0c74c585b03b2bee98ceda8dbfef6f247f1e7f803926ba49467d2cf293974e0b05ef0324e219694211b49c9959d4146f383b91dc696323a14cfa8c93bbcbd1c1a56ac5ef897381c74899529a261dfc6bfcdfef9ca62bfc7d23aa56233c8de019b3c1a522d1c236cd5bac4d49da0e2e19e42360d9aa1f86fcf957250e3700b103476b317a01817ab0743f072c5822971d5b80193d55efa1f902ad02e2b3bd0e96fb4b40aab0f47bd63f17355c02def861e7653fc5fc0895683b5516bc4caf0649d37b8fdcffa21a02eb340365d65913c96b4ec792552c1932d5cf5ffa3de36ac229b177e5d1b82c5352a84d675d9ffd3822497b6cf6cc54b2ed1a2601f0e4078f3c88cf83e682037eeca8863718f90366cfd8cb58ceaff0609b5b9f05c0990f4a0cd540be672bae6abee914202cb33c03c6b25b5087ac7878eecca4a90cbe93e2da120bd74cd0dad2549b8c601e70d3714386cbe916cc512950d05b9b923dd28e062047e9bd0bc42a9ca791cff00141c9911620851e11facbfb9ffec4b8c32a5091b12134993dcba55494f27db8dd8dfc0ee6e1bd5bb8e957ac11f0a7670086f2401f1b3b8e5ec25ff4b0b1c1bc17d372ddbc7fe03c8c94dbdaa48b0526aefb4668608e23050c97e4cf6772c32549e607abc071d914a88c97f5a538da2b91061eb386cf807732c2345473b8631614f849c79c9e9e14b05c8824af8000f7a60e247d72ff3e3fce46515c2f74bb1e765c37a4e7f03181547f6af6a6d0f96505d4629d4bb8df7713c3610accf3198a700bc3af151c9b6beaec00", "5252520053", 0, 1547416838, 0, "a38b854668c61d9057d942350a21099f88050b4ab3a5e2f6fbd975938ce9bfe7"], + ["030000807082c40302775d1c5b3d560ee9b45af3847059357e6b14bf42ad04c860642ea59c81f31ea903000000016a6c7056b9229730857636ec659a8ce40c45d79a62ba2a10d670a8195791a038aebfb6648100000000075363516a0053ac537b6874027e36d40200000000095200525153535151009dd4fd03000000000353000000000000a8bb61e9010000000000000000b869e10100000000e60e90577ce8bc27120b08cabd62a28e1a1333d4834b4e00d938403ffb5e8208a9fc19b012a5c64751ad429e5cda16a665d525caf58d284aedf96cca2c04e54c651b9e1a8170ad47d62c8ead30fe0dffeca13b08923ed126f85d6fde352f9b1e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083bee019c7d1bc0848641aaffd3736ac64bd94d1de2e9de7688af5efa58d02b40b7196e531ae97f8dcc8edab81ba653c4409cf979599f982049ffdf24f42159c7f6596d5656327fd89d3a177ef5f414cbc26b37c3d11a65613f7bbabdd047f1f30b9d96329699e398a5292ad9a4e1a7bc1af22c48dd9139348a8086f91818abf021263784d6d7e379837febc37a42048435872c32974e3e6e3a66adbac68a8e9390211e8c8ba7b4870b091148b841fb941158978ad55c8f896d0e29efaa68bc6965e0b02bd07cdfcedae810766cb2a20f75f1b0ab9e29325a96ad2b41bc7330dbd42816e75aa9fdb634b3eb04228997a1fea9702ca0d7dd1349f62ba4cbd4f4ccf1924030eb21b139a493739e14d1185a00e2c1bb4872a533ec52ea006a96d5b499e36da022c7c0041f7997d5cfbd0df383b46e768aa5b077279d5358dd647554c317c6fe70219225446a6979f3fb3f569de22f0e11ce9cbb9a4620156faa49d6e7ab0f04bd8031a150145edc6718a0d6943e4057d3767a9d4379054736ee0ea0d8981f2589b4603212ca719e98977847414b0cc3e52ea48b89afb7c3ede3bc11edd67a93a4478242f39dff1a4de513a13e79bf489afad716de0fbc58af99f1e95c8cec321ffc5251fd0c653d56f3249125ef33d50044c9073ac5bfaa0b5db9e1aff002d24768009aa10d11001eb62b28feda6bbd0494719925d05803f79ee02362045650755929147f1d21f93eafaba43506e24b633e48b47b904b4b3f68f2b0d63ef418d91909d906d823e6806795b0490299d5ceb8273744e51b175fb8a653c6452ef15d2bcfa1558852cb01ae7fdbbede231c52c7f675f3a187ec353bb4498608a61e3568dda9bf159b2a6b3ac74b40b0e7a4dcc8e60bd107fc026b37342b26a7eb4147350691643b228b01d5c170f8db3663949eacd6fd7ee7489e6383f2938fdb6d05378c814578a9e9c171f37f95956f63f9e4f7186eda0b0a55d4658250e93c90b18334200c101a2b7ed84cd87da150f8844f1a6eb55143f16313a2d4d84e5d1ce16d8c879dfcd5abd8c866dbaedfaae7d8067e812d75b54f84824352d0a8cf82044f1a71e83fb115286649ca4532b1ccd159e61b874a8849aaa78be3df2f01412030f741584ebae15ec20007539ac3d2e4d169a5aeb1c1cf8a06f4d5c0df984946832a32779c08a629f83af9f21494cba88ba73f36e1765b7df648bd2e87e2a37d4e3fd3f8ccd4f5caaf1c3f124a69f0f3b7e0327e37b64434a4dd0ad71b92dfd398d0660f1780d894b8890c7c687442d5b180ee8ba29ea505999862ab9d732a1b455ac76f89e1f1807e81e710fce6f8ca62380faf1be18e13ac460ed50dc84124563c2e658edb8bd99f3e574284afc14892d50be8074d8ee3df5158b4dd18161cd2eaae7db4d77f7ec344914b0b9880b5ced44bb5df14a40edbc7c18b95b690470d245e9c22a0709b90effeb693bc9dad83828c3481e8713dfc35b8923554494a4823782e8540e984aab63bfb4eddd9019dfeedfab322d5ab617bc405c8f2e39cfa02e59ae9cd333bb9b9228a0bd2da4cfec6f4a8b4a6c188febd6f6dc01578a5379f5300267ad2260e8efce7c53af31bb210784ef252e09d6cc75e9db356724d6d125e8f588e727128da5ece1f4186601f9e7d2625cb52fc53ea946274251583d51acff70d11ca8dc63fea015ee4283a1e4a5d96c96aa7cff8e0cb1b7884468c542ca065dd7f62de520aab68eba09e8325bc82962237a35686ff8b25552173aa2f9afa5535071c15523f1ad18bd5a61b66a4edbf3859c12bad375824acc840f876e5b193a0da0331ff6f341c4fe41b76534a1568955f9f3561009f79bbfa62cc4c246a867d5fcd0db59592f321fbcf7e5beabf0c8cbe259b2dab5f1973a6485ac710ecbe17cd31e266d3718c7497c48e247b5cdc17506fca51c061080144ece1948bcac6ade7f227c1cbd953a2ad5bbc83521863fc5ddc0fa7ba20b63db6d0145f3b0aca6b6d967807548cd1931bc3de7532eb8dc524130410c2da78ee827122536669f80294c468b2991f31b942d279d7235fd766568964c353e4baf8b31a1b298b77dc22363fd8cfc55b462f1952db6b8ab01a8bb31e75160f226683f798e8f556c8786920d559d9436027a146ca48f3d669d545bcebc0528ad8bbdb467554d0d560cf37f58fd90e7565dfb99dcff735f25370e3b7392de2d2b7002dc2fba2af3663befe823ca16676935e6bb4b8f03d30be8a60efdff903fb941158bf551c65111317da6689b78d6a600fbe96b78e9321bf87a0c968f1640a4824b772303051d6dd5afd596848ccaa7525a302a0f2e464e63805d6548c56a07051b0bf4eea6ab0e1d6787527a01b7c9187057e32b6d436193cdac3810dabbc3df89c43bb3b27a26776e21231ee5fd2c1e1447f0c22fddafff0c", "", 1, -1439560012, 1537743641, "84c986dd512183a8f7924d6ba4aeb4c9ea714f5801a9cfbfcb4b566f06fb7bbb"], + ["322184180230e968d0c5c27033bdb870c514f80b2139cd1d880b5fdc78f4cb31feebf835660300000007000052000053acffffffff563166be9fe55de8e245aa70c28f354e400f1e4b3703998c7c651c92ac1212b7010000000853ac516a005263ac7b4d9dc602c44324000000000003655352822403020000000002ac65cc20531703d79cc301000000000000000000000000f35ef86b1846b3526c54e5920b60811383086a08d4ac1df30559113fcfb1318f5069c4641a67ad144ce5942cb8f5ecd2d2d0666eb675ac4fbf55fadf0ff9c8722915ba5fd42dfe0ab03fe6bbd81481b640d4199ace7bc7625003fd38f8950447000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008e59cd2f521a46cbef0e4f492755338db85b86b2934f54c3ebd09712292b54bc35ace246cf4c57dcdef1c3475c08dc12f502657412adc15a1d8efbd84668b88e299234a414d5d82aa2be6bc70cb5783a9988a061bf82256cc08f1a937601620e902c948452c8b64d09d18c295b1a351e9bcafa6f0cc42c6f6f0e38077a6870820226ced571d49b0ed831ea3f6ab72b0cda74932255ab759053ec4a070be68562e8032d063cafbde24ba2cabfd82c9d6eb80e16c0aecf24cbaa2c9c0ff53ff766743f0a06d9a5a151fb881f932430f809144092bc64b5a470aa6c68bdb59cfcdf4868c9cbe474231ec18128d15c3d9cc34d5f8652af79e83f0e93d440991f659c238046030da69dc9b99df2e4c1ff7041caf624ca7566af6ef3f6633e24bfeb86faabb7b803281103911a1abd0a987a9961bc7c7f8fa081549480dad5f3fbdb897d29326b8a031f15b5cc0cdedcad0cf42bdaeeb6e174f38059e14561c5b417a502af40c4ba97031181d168d76ba241f4d1f36db6742461f6fcb02ed2e4a908bd8b06b3ebbf71a5030f94cab677b02c3f710998807961b26a0fc37a3c9e5d453cceea7a935fa8f16c150725983af09064a5ee12c483ea91703ee4534347b5513d63ad41b85c93c829f706746274761ff1d938ca6dff4ca5adc07f5da6f8ceb6da08ec0cf38ca9f0ba49643747a19d6e902062e68d089a0b7a440a9fcb197aac7571201eef824f58d9097cb5501f21db88231fd4aadda6f3571548063e9ed30ecb1b0e1478cbc4bd51ae2ab01ff6a90acf2ff9838b153dc5793c0409808a0ebf32a789a39acea5baef80f82f2c97ad22b1ed0153787be0221885f38678df06a2a95d0cd014189e49aeb71867b9da394714adcf542e8cfadb6e60966450c97741888f7c73cc08defc1fa8ea68d85a9f696976bcec6da3edb5fe741fd95a6cea69c212b32d1120df06beef05f1551b1b2677033e9bf8662abc76a6fc1b9c17202107c94e48ed4729ff105e66a2d5115281b596c53dc6dd65591bd9eba6be9638249afe2cfe9ecbee619788c57c35487630c3efe01d32f86aecac6e0f180312db89f4875172dfbc9741635cefaaef5e574ee21905cd1ba474d032ad35a6fb21b7c2585ae6a0f08d5c8ecd0009b7de2029fa508acfe974e249dcdc74a4d6d035fac5fa30175033204eba2672bcbb55e22e23563a9ec238799987add3bcd182bc444ae707139f4023dc8819586bae4c13fa09b6739705122bea7e5bba61210694f3b735cb972a1ea32d1efc80474e3fbd10c1e2d15d1a58324eb828b9974ccf4d7257822a8512f31623392fd31d1bc2099a72bf30b887794d9dfcbaca7f5a6b4dd881976db00b4fdca162af089f34226a7267b9acac01adae06b60b9fb60a00994717b6e0e23380cfa520417dd130072662cd5d1ed7613bcfc5939b9d57f79857310f3ab5466662975c9644f51e82177ffbff3c02c91bfa7bfedd9b0f38f155f385c5c64f506431acfd4ededb39a3446a46b310e2e764a39708dbdec2af36ec59dd9c77c642cbbda7a66d30a101059dfb9c2c0ffdd26d9b63adb621b629d66599811d6bf09f7ef669db69fa690cc87d79ce42c31549aa009843a09fd34dda8245b2d3ac3178e656789cb8c7ce9c1f730a4cd9aae643524e5884291d27464b69672dc385cf0f303ee603d2b65c6cdb3aacf5d18c130918671f5dd73fabc30cf314c5e8873bd608c03736c4dc44cee85f67f8e3540993bdc21d763f50e39977b9eb1c13daec6f3a5cbfb6c2b911360820819562157eda4440685095ad4c7576d763a41a2498954d42d239267f63cc50003d4109c2f5df9c5f227c4306e420a8996712cc917e788faef8b3056852b64f545f45ce248b62c09f605e9ccd1e84a3b3ffad8d4e0297b0064731323391d73c87de75efde69554014c4082bac1e3a217e22be5431866fc642c7fadf067dd83547a5d81d7e67c93889b6670d6aafdf7c7f17c705c48759583238446a11b61280fe5c16568acdb3446955cf0d9d58215d931c9f7f37569ce332b63cb635e759cd8bb44184859175cc1556d46c6210bf67c4d855284444a032ad4bddedf50007f41002aa5c58752d3f3c4ccda5747989d9c0a22838f5942ead8d57960b9bef20744926d13621b9599bd0062bf011c2da9be1fe3088952582abd634cf90fc6080b1e7a78295d01f20921009744948ed8364d4ea461545f1da1ca2ab4d10d1131275ede985d84feafb539639287fd571f32a01411ec03c8db1b38bdbd2480b20885b78c66df8c467646a17e1622318bdd900000000000000004f85270100000000b041d8e9f67ec8239df202385de8f605964382cb1f8b8fdd106afdbf8a7b7dd0c6106cb742c3d592e95dd84a8aa6b586cc1e8880ab3609ebd705b01a2ab007e41e6229ccbefc59bdf0945602ba0812f2ed362bc46919b871303c9e60a6f5314f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f24fc75bc56766d7994a900b0b1ec45c14c98f979c15c452eb776efc019acfebd00fe2cdbc1f73c1c6d99cc2203907b5f3a17b923db68b1889da5ae96c033311f4c456ebfd5d4611e3c463f2124f46e16e4b84ef859a312f860dfdab6233bc2abf97ea0a1604ee910eeaf6eb36ec4967740f49d28de1029a5f16a3883df5049032d30e4bc7d222e5c22cbc7ceb6deb0e24de062233026f5bd433f581c1a3a2002021d5ef506dfc7a5c9a96b14ba3d21940b42a0a460db2bfeacc9e598c38b8995b90a05965db1d45fac6415506ef37dd999543f82cd4f0977fdab04c6c10c70e70cf17445c9f78b89d181700fd996eb4639ef606ce7960b3beb12cc71e31b980875ae02136f79eb5e6040b4c59a1f4fae42e12235df2d532aaa37487182ce4ea2ac7dec03151068588951695a36267165bb45f47f9e9725cc687b60a1cfbd2fba726da4890229ac5380eeaecd483de2f8e247b5702edb1f06fa4b9c1dde1b6f93c22c7c97030317b0f2ff220a172999c26130c1b077d2cf0ca1f6b4e8d0cc58e5272200cc9038032dc649cfb5149cb9c5c2969d97a7b5e3f560489db211dc676131628757291e699c89643b5ab3e98f0fadf1e4095794252bb454fc83e485c32fc6de2fbf9fe0fc2bb58889ba0b9d3235aa900f81de251699984c1b882468627534bd78a2f9f0175520e6f922445979e57b4d51316e5aeb3d682932bbc845ab8224ca872fd63f64087486b713d93c020070b755e50153e3ec30f5c9663d0f4c967352fa093a68454e479bd3ecbfb2b9eb5f2c540b4b541a2e459b22b70a2966b4bb43604d12eada51cde364823697e18a9e82af9e35bf443f5ca48d7edb28aab7a45168eea670158899c98ab1009f21e7cde37f90fb0d30d38fb4110125e04d23246a665658f1f00a19e347dbdf3f3b5de33212bd68252f631610865dff717b392771b55c224fa00c40d427a84f29f95bf7db6803d35b77efcf93278d125afeea7dcb076ec3bd5a88b115745210eff317c339d033967f1ec6afac501100be059793316dc40e0a08d1edf8765df14fd217af48905add20ba20fd038e4f1242a9679f7605a59a4896e283687d7358af218973085e061a847b226026c04a5575e41f8673052b78f1bc383a875e0ac6c7b47fe56f625039dd2e8ebed071740971916f254d5d49c90fbec1e324aa80ee16cd8abe03abb7e19f853eef31e618722490709a43c82c936fa2dd93cb4b42d821c16f4ceccd8528b73aacb0b3281cb66c1d6347f93f871a7d6e5c427a2a40c08b300f8e57718baa0d38a319e67016d860003808a78a392acae5496bf9e7af9f0552612c5cb402d914246df2a4b13031d271d60804f61a0b7e4c706fa50c0e25e715269b1c241a855a1821034bc1c9916f0b674a3a234e72e1ef8f2505215a66ef7ed0b899c569342dc13255459f537cbd8b2a711c52c9a3b2d5c149d3f1a1c93bedae3655b448e266ad094df9ac8b465d08b36dda0cd21148b14703790653ff086100534637ebdf4539848048ae5b10324780dc8d87c5825cac3d69fb1c068c8563f129424884fe7aa9e2e0bcb3fc6a0e14345e6f311585f9e028cfcc7c5d1da5e366b28a2d686e60fc57ad8198e1981500d9b5302527e7f5ee5218a09dc0357f8f9045fcadbf01d71e0b1703f5f4342ed85bf3c565f9b8169f727962d96d6c898acefe0e5aa4ecdc4d05e94a820af17fc5a5243e307ed38322fea3107c4f104f6d0248068e2d9451498c43c402ec226473fdcd728296f8e67eb8251188314b767ccb67c3becf48b4fe17da5e0366d45a86f37834dfedb540bd759ae4b2f965088238213c534b617aec1f35111e2ec370d51846646129314fa5bc7524a0fb54254f65770ee63c07b98c06610c9c7165e916f4feb38f76e2987938d787159453f6ccc5ef272ce2c3ab0f1977b2999eee60424b245e3f9b4427eb2d5504acdc812b3f9f4f4c764550bbf82f730ae28d1147edcc939972c1bfb1e18fa32859c82b93d0fd25282737698a5d8cd3959065c7432c9acb202fabcdcb63c3e023d0c6f78dc8b81948cdf4a388c681486d195bb13b0ae450a17cfc8a91f484de669684ab60ffa9a128a80c8bec5a9a7dfc49878ec967cfc1c94f6ef5a332b90e6b30feca3525ae82fe0d3e7ba1b1f72422291ef729853afdef7dd86bc80586ce15bd4955bf1ec46628427471135205896161e68b0f06231d305900229320f5832a6feaa5d8c94477ca89b5e46f8d35ea9dbc5f027e1eb149e31adc52f86b2f14199916d60a29b46a5bf927b98d3bb0c223363202000000000000000000000000e3bcc9dd883360c4feccd66025c3a8fd23b5ccbf620216bfc31ffa0ed0deed84e3aa89c0b93810c81ef4b09347d22e6ff5f2f91ab2c1d56a7c23bea4f450b75833ae1cbf313f25e643fb7e44c1e03ee925b37b4d78f61c7fb16dfe2ae6ca60b500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a82958887eb12834190fb0c8255fe628a03f3f36e24c8ca362d2b3b4973a1be5eae0fb9d56b3b795bfc2b2889a9050e09c51435d97ad09fef9d03e218a3e11062184e60b98c8b754f4c00d2c935aa95fcc9735784d7659d83422a595339d4635d8f8c23ae6da194ab145c338c5b19e0ec27f60b02386d7e9286f16c31ed3be4702025e0f1c9ab7119bcd82a7f1c9ac4f5bd38f52d952c6cdff2fd9a800f4169ce1022969a4a29157db8ad1e20eea7099cdde71635c36d3d57fdf23927e3ea603d3d70b03d7d9c0fda2d71efd1ef5f8b0f240a2f96f8908a3a0a1d8263722f488b83a35f79e18261412857d09ba4002c3ce06c877a4344aab8667b495fa4afad9110c2402137748e2fdf0fd334dbf2263750da38929cf0270923e16cb81af8b25cd3b9633031915d7309f5522353a6ee9aab9ec73e20e21c925e1fe8f3d8c196c26c823f8cb0323d765c02280f5b27d7eee8dd205656eae6c73f4026cb165c0e0d2672e230b440303ba0336d8266e3e3ee07545ba07a0afd9d3bbee34a29d651845774fdd78e61303013ce13912f4629c44997ed5d43432995220522d5cc1b828f89f00652c4f26d93dcd8cc31b9b6a8b387fa69f56b9717dc7c3ac6c7664f5124215ea83646d3d61aca080a0426020d596a623e29e5ca57fccb0e89d347c1c8df3ffc2629332eaa751431ae2a8a08cdfcd029b7a8e0d106786c1718320b65fe118b7e498ec9641eb26422d13be6763c90ee9d71310ce10320d843421a7b001019c6af2a4b088d1c579edce799e25e3717c66fe4f6be5ebee49129ccc23b08aa6bafd3dde090b93ebcc9020edaa4917704be36dbb4fd91080eaf30107b14972d55404f488d9ca99bfc463266a4ae863fbb166281b1a4fe48a0e98dfd1b60672ebcde31db04c8f023796602feed19eb935f4f0bfdfc4a4252197a6451eb4ead33a6245f9ab4f3fd964a4cf0b1d755d56116d1c445ad795e6c80ccc2e97acfb748513a092cefc83e822be1bef2ca94a7390697d4bc47e09110a60c3c65e3365a75bb3b96f2160ce85fc82e6981d5ebe9a74ed0df58e5ba21c4312c358c6429e6db0c88fc2abbf907955fa1ca29dff5d8eba3f209173a96e718fe14cb026a5019dd7b3e4e58a3e6fff716a7d62bd779f6d7aaf274ae79d918cca09ebb9ddcd91a4adedd8393f6b606052c11dfb9f0759f4a20d6e62bf462619e4c4e86e06811fad31cb341e0bdb209f012e3f7fd13ee9ba216a011d2040ce0fe1c48b232ddc1f12edee33f31b7dbb20d3ef9ad98aa7fc5cf835833b259487878a83158fc509e8c2c3f189e7cd026daf1a3aef74d35ce384f4a11fec5f73c102c8f05fff28b371264029d8d1719fed81270599067a629ae28c65d6dc366fee821c2b2024c89ca3675b747dac4541ef4fdd8029dfc7708613ff57fe7d82b7b591eebfae32c9fdaaf160d78e6d0797e8717e47023b18824ed00f7e0048ff87889d6f977879f13564e609c35d83094b10066c5c832d96bf2d4c5c51eba571cbb76322c1c9b01fb04d6018b5812d2a22b908d85e5b5255ddd551586d2f4e4e6c6fd0d47ac7047bc55c70ad560cad5352c9de143c9afa61482537f7f2d00d4cabd9c8b9e82798e8e8e202e2fd9bde3faea78849727b85c51b9707ec74d75ce3b97d72ac46ea8e4d53797f89a0fb998d206a0c90a74014fcafe1d5c8f66ca8cf0bd003756b9888a2533c92e5e4de657e5d2fd300d72dce3d66904d2af898001a76333bddf83f7a26ce2279a1ebfec0e82f1c202502304c012cced77ae119828a8e0df6e7fac6853c8a52564a9fff6dc28970fde7fd7c0a61229031fdb788786edfcce2ee58e43a4e605981760f49e41c2ba67084cc666d97e48f44207f0b7c4c36dc866528f1dc8054d296754f9741fb190e8fcaf1ee72ba0b2ca23c390baeb7a73e5a9f3a1b46c6367f85926e20ecd074f0cbef2f4404ed016107981177f2e3759cd0c6538eb3293249bea4926b37be824de7bad2501a797b8e55139f876984361e448ac71ad8ad3a47346a873911e270bd624725d502fb46cc3f03be26eee35076c99c57d44cb18035031a136045bf73b8500e7d065ce87d38ce72bc6e7a691a7ae883b61350bf30539ebddbeab4dbf42ddbd72f6a1aa6c8282f443ae04320295d22fa1f2a6298529982b0b219b4fefa3ecc114e6ddb6a0af9ddae1d457467c2925fda7f9e6fe56af0b8f0c04ad4a4dc89e8790ddf9b0bcb494a66b07bd428073e2f52c6062f7430be64d388d47c2e83a2d95894bcd51a26a049c5c719c29cc23bc92d6e7e6a8b25411bddf6bef414b851c271bbcef75d68f5bb1367485d0fd393a9c9733e7da85b1edb5099ab567530159049d1a67f7306e2e26f0f48a759447a7673fda840bc84c6409c5eddeb987c6ec5378f781cf97f704078acde6b6c4fb0b76efb0d", "65ac", 1, 1352377622, 1537743641, "790c5b5e528e3cf8c53d03d13319b276b24c95a505658522c1cf515cb947313d"], + ["1a8dd4050218fa5f6bc5dcbce22e6e86ad688311633e0846fdb7d82b53995c36bf760b06010200000005656a63526aa17f9428bfb2cbc8caeb81a446e7842ef801a2d21ad2cef35d7b28d104bf5436fd40765b010000000165ffffffff02ed15e401000000000100f798f5030000000002526a2ccc513000", "656a656a535152", 0, -684260667, 1537743641, "aea686139c018e81adf89089f589da986bdf0c18c60ce140abf61088fc76a78c"], + ["f067753001e785b5e4d69a594a97fb6d0a3e12ea3e567c5e6bd06a70bf74c8b682d1dbb99e0000000001650c05d8a3012974a0050000000008520051ac5300535100000000020000000000000000e93bd70500000000c6b291dcb8e20d044a666e21b9bd6bfce53989c570715234416bae25c8a6aa243070e23db94c2f94530e939203488f12325bb37d5f02df4757d8a76f3e0410a6e3fff1d18a2e5cca9f44d91adb8feb421867637ddb4d1c17cb67fa1867b208ce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008890813d53e9f61a644b164a82bd0c62ff071e6498342a7502a6cf0dec34ac0abe1f0f5f330753a1eae562a4c38daa79026a7c88b2e00b3a3c068130c76c58ed6084bbb5f8cbc25e66a625e105d5fc8489dc135d2b23e95d920698376a3f12c66fb248a1b798c66d32ce022a9a896e0ea6f87732b4210d0b33689a6d8abe7aa0031d88d0fd0e41fb5d7a8a38bd586c12677a24e7df41f99718d159475e295141db0301c2ee572a223a034df3503697d13e14ad8bdf989b8df7211df6d3cc2f2a23660b07cc26905435ef0494caddfe4c11eee86909aa80a67c65d1cdd0ae785dea8486725cbea2c9858f53901d0982431e02cb52307d053656d6b94968f0b04db845650229793d7fdee7390f6205e5617345345bdf289dc4b6d954d079d1f88e8702c88b031b0f58538d2f3c6118595cfcb6675e0f8731823a4d0e3478be863562ce052a8a03081ba216121549ffb94228ad7bfa8786b41cf0d33dd3d87174c96d24d6d1e4910217cddcd45c03806fe6f8ab0ac8d649ab8c056cf6155705d2226c407b564f620c032522a81daae7cefa4991252a5cba5bd905dcc11a7c4fbb663ddfa3cc3f0d1b3e426e4f5b36ea414ea8d99b287d8edd5e80486f6d6f231056a0cdf6496ec4491ed25f0f96116d5323f9086d2ae2212c36c008608943f8058915d4d83bdf2dd1450d2dce122436204eec9f28861b962865e65f9b546ffeb5f3e43127a6012cedb4d20cef9559509d2bc516b95442927ea2c24ddb323b35df8a872ccd356f87d91d6b10a2b7728a40186bafc7b418ec87c717b004d2c2c5fe789a3e0aa0d25295a28a0edd747f2aa38185acab621e4360e58e3cb781380a95b20523b417b2c0a5368b80482da9372ef5e18f12a22cfcc6395ad7477415557baf7de30ccfff156e93c3a88fb9b22b973faab26ff621c65822a0ae33e3a6923bbd2b140db492bbbfd33301756c3ffe393cc7b4118809030e0d03087fec6bc4228233bcf3d29c2f8b8c737025fce8f0bc731bf3e1f2bcda5c248e7eb9c647312ec45eff5122cbe1c90bc6e2bee9846236d1601ebc77d66182f1536b47dbb708dff7693f70123286077a0ab4955691040aaef1a6d4793912c84c85f686f97f88e5c125c35c043098de1617088b90e63016608c403cbcc1c87eba8029e497d9dc3c9f3f287bd01e858a0df828a1c820f393ad0d05ced1d6cec6e0cece688f4cdb8319b9d8fb7d9155b5c48cc856a1dd5b271be617cb3e4cff115847145062ac47bc47f82581f042a3564296b8669de71b528a75446f23f10346698758480bb01445008a37044a50f53ad482d77a39f5cd72eba4abc52a8cd65c48b01acde9c25c5a1449fca9eb540e1c942bb5d3f66e07cefe58a4ca03557ccef140e5a9b69d4692af638390ce784eede20b59788732acf26e81b374971d57136bbcd3c5ae5d705a0770181e9b1fa4af2ff05c9e4bc55871bb677b0260ee06777459b8b6924faf100a99415498d63aa71b771291565fc847b20beecf05bfa6a12ffcbd7bd108feae40e70d3fb77f5c616ed5c2913cdcc7ef13d71441f52da209b2bc9b3787ca14a2e109d6c811ec07a7d5af6e5c1d8bb8e850718388808df02497b9b17f8638511ca1ccfd0456cf6c0fa79c392cfa71602b3fc2b85e5edad79b996c8036d3b181a9fca2398898a6f150dabb21a1b998e23880db1b34d20e74d74be70e84644c678ce1167eb31fa2bf2b1398664a5f0e207e09c9d26decd4b26604342351f2d84eabd05b0d7afc2b73bb98a4aeaa6211d83f44340bc592d569747f061e2a80ec03c9bda06a1a300a6c968e6d81f2169de43c5382466d7091d3382397036ef11ce17c8db2f8eeb14a030d2b6e85b6b7571f6a6d3cd03db44ae60fd402ef7a9c439644cb741ab59d31f68f4cb9d838f5d0c410c851491477d0f1b908bff229cb6f8c992408f88db8b873c5f577b617f503ef2f198ef9251dad3d90c6705e5cbc833cd29b8ce84be929f370231f93e85f7a42c9635c4eecc7bc65f11c0eb2ff5b4a5aeddcfaf2eb90df365dca00636cf89567dc5ac00e2a7aab1bd5dab0f696aad5f84409d2ba0c2ea170010941753d7b7d538f4921748d7d83ec80b27a742ed9cdd637a77cb09a5cf9e5d6606a575d207cab8cdd200e0e0fd8a9635f5361d8b68790f8e6fde13009d2ea4ba42f4181e4633de438f6c7ffeacfa1f26960e799fbb4bfce82a58cd4f8223d8e0998bc802a44e74bd2cf6cec7d619e5526d2728aa534838c91ab477d7c59a3a022e09370a942749e60b9aec6498a11ac35029e00000000000000003901da0000000000a6dbfe8a11eb7afba35f1761df422e40d2d30d76f00c6b1432b8707c4bfdde077ffb35ad71c69622521158bb5a43f66ae38b01e1556a0784bcd99be6c6141633abd997b06ea2e3f77f1ad72010fa06d9c11aa30e256f0975c7fba43fcc8466ae000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e0b5648958813428038754b24373dd411eb3e25fce819119e3cf55cb1ad0e26a5defca8816217b8dafdfedfab85d85ec928e7268b8c98cf4daa052894e4debf66cb8b46c985443d675d6e4f6f13222cec8460a857a99926730ac60d6b4d397a7b748951aac97ab0b70c335118d5099ab14a62820e6b29d91ee55eb0f53c2963030222b09ab9f8ad23e75655bc909c88fd7063064b2a5fe6b8f298ace142bb6eb9030f18f5985220c57ff90b44726fba4b3968f7d3509bf74a785929e67ceb8bdfac0b00e8b5bc66aeff024b5b8db6bf8860e10c36b5d0f8975f45444bae5eb56db00d258ba5d76ee829213badcedb0c7411214e50530288f8b1295c9f1f0854a9ec51032a31e097a64b4f33ce55a519bb89574575a4ff9733aa95befbad46556eee4615032346e7ce5ad2f7ffd7cbcb1c559636839c0bcc2999a94642b33c8a4c7a925071031a690e7c96dd032b4055537cf66bd42c15788d82465bc82ce468578ad09ae6e1031950f9808d2941fbbd1381a70a6a320675cc332ab9e2a3183a73683b7e237c32031752cf76ff6dda4f3444af17aa03da3e69aa425e92ad0511b581cc5344d53a5c150f257fbe4f4def602ca9be3e3e2e942bd0c7157aed4cf99c44e6e26ea9ab2ce7b05bd39cdcb5fe8243f1e8148d2b3c92cec482bd45ba803baa0f5360745fb7e264ce43783340a5d5562fcd800de3d44905e13a506e5cd9a9268fc2098b88755f6083a19fa0ac998473f40e1ead3ddae8f5502e0eadfd6f7e335e48c75ff45c49a8b107b92aab4219dda328b77276182f4a7608b179d04c3063ea00883a7a97adfaf1d918240dbe1cb80fd2b8e52302fdc57477d07e6878bb33ddc408cf285f84c2544fd90bdddb7d4715e919f45889d0ede7b0c68eabb59b9cb00689d2ce5766727c2a35abc6df6079e04cd6a1725dd6ceedc274c08236dd761b2c64bef1b6acb163f84bc6e5fc617c989dfb5682b54f99bc7adcba733c791a2865e0a330193b43cb6937688abc86b59c1d9b66bb51cf0951d4600bbc7db4d6ec0eac2f463e780c66489bba2f094df65059cc13b474e7908f5b8ebea4fa295dd0dc4695eccfb6eec40a74c923440a5745a8ed16dc3f5f87239ffd913887da5b0ad786aa7a8957deb9a652f3d22c70b468eb2bb96e73171549a2533b33d9766a2fc2c10d0fd7fb3810c24a3b9e7d094889f9bdbd3caba9619b1346452892bf492b5837b1b80351195d2cd3a6e94794943d7a867fae2bbe9e0f2baf82312e8ec20c5877e9c1891fec299de458e1ce77d8c8acd3f9849547654e9ddb191bf85101dd39c5a84f5979975b5368ddf7e9bace8dfa6577adb219542dd0104e4a8fe0b96f2b56de9df2734b1c002e2c85b48d0a1e3e9c29910b016b3dd61704b885a8250b379df979ec9457a228dc08f7bde58b2c3a8304cfd5b7032dc1b83371766ad9e1e2f3f8c8d6d3d7926f42dea4d4e86e26be566426fc2616976e1ea690d9d470f682fd2ddbb8f9891646f008219bc83896902965c1620aeecd79f5805875c147b2735deb505ed8ded71603af8ebd108d1278d0f4ef63c6de3fc5923bfa3fed3d68f7bc3a414eceb3c145d15b5239361a0c3a9a6f2a98f58c0f48ce7f71c4c20ebfd2b41c22c23a150a35c91e4099070fec441c308f37a608621dccec4e8f8b4e04c3acf4092ed2e9398859b1eae0649114de2f6f6bc54916fd7d96a036a6abc37fcdf9e94d173ba6707f04c71ede5d892ac4e925848b994904231f7842358b9f0ca24c78190a9539ae7007658052019edd76b22d40bb470c6d406fc4c1602f929295576bbc4fe91b970f5e3c1304116f1623d6951ca6d5b20a9ca48bafdbf81a081ee9b3f3f224ecdec7595c530c55af1357450cffbaeb42dfe7fd103b95491edbefeeff09e4cebe8323dddabb56b4ca10ea829657b50a981b9acdd7af53cabb43231afbbe6d4e29c9a78f8c73ad43463e6ad71b7bc8d9fc7bc8c46e45ea2f08d70de3f497de0a19df5805c055c33049bffa9f808e6f8102cb39b85c979d90f5200cd58e39268cd16cc7aa7edbe94459bf389759da12565547cb3acfe75e01e8d8c4f95039955e4809609ea4efcbebc0c7eb9acca6d4e0ab668e9fb6084bd87b8011bee793c883dece25050e174da6cf0b791dee147c0ebe7e344238ea00a860330ab680e5edeeb48a3a86ea6e741b60a473b0f5def79186a36e936dcd9d764ba8c69ab7e983c05c4f73b34f04e797a83e8715cdfe10924d25b1c34e03edfa5c708cc88a5596d77984d5dacdb2e485888311e5fe3e617e1a579d499a6b349b2b80434cca32669343cb241808c95ee4254aa36dd6a9a4e235902e99203387be6dc08cf3441cb3cbc9493502c9cf8dc4a3bedc13bf249eb4b07d43fcf06f4f6c79479f0fdfbb22a388d49d7981db3eefe46adf3023ef416305", "6a6365ac", 0, -1488409917, 0, "92f0b98c330fc2f3a703695ad9c55fc63e84b2d3c9f79c2b30b0fae7e9f761d2"], + ["030000807082c403028f0db90d9fcb035f9c13ccb71404853d651ee3825cd7f9f83ac84d9589b008970100000000ffffffff8d1bed0074e5bc1cf6b7f1167236fdbe68b511b3ef6f6f8d76e10c336227a1a301000000086a5353650051006532bed09a04d4d315030000000004536563ac0d214303000000000753656a6a6351653ff40905000000000463acac00ef1ea402000000000451535100000000000000000002000000000000000061cbe100000000003ac7346c7a696ad487c42626e18889b07d266e5307efdfcd0ec431aea093efd2c38cb702ce743299b6634d998568615c299738bfd50cec5bd2a31df10da5887f293565f90c1507c7cbf8ae7a2844de1432a860d7a3d95c496bc1ff4ecff25e9b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf4b47dc1d63c432b8dba76e69263f4bde294608a3a52b36715923b2b9955cdc07cc26d6b2c9cf706f77ade0d1783eb2cb1886915eade80f1a0acaaca5d9c5847de737322e547d5c73395f73da7892271cc1d0916f9898debdb6e6b8349e187e3bbe4f39d2cc66aec176a15a794326b60e71c0b9eef5e0353d410c9bd3e4e9b2030a6898a4d5641694437cd4ab18cb1604d45130bed0c2b03d2d8d56c47157df5b0305c2bab0d22b8b222dcd2bd67e471c5238daeaee8a3e2fe1fa967a15f21bd5b10a0834c8b7e439f033f32b87a95c0d6968a547ae586b3e5e3dd7a7985db179c7092634fcfc8d05e9b3f7916c260add294c37a842e5d878871169384e751432f25d02020aa17124eaa8fca88a2ac6a3215dc24c7ba196da3825a36e5cd90cdced2e6302178c24ca44496039e85dd2cb0a5c5b9acfe44d769254ccc632db3d1c55ebe19f020661d1df80bb0f4f7191eda986ea34fa73e9fd7f0286010c3f79a51ffd1b837b0204155cda6783b408878cb746a6a57ce82f9950e2762e8373b28ab53018f487a003087ef763700a601c1a663d1d037029c0f1777254031c4b73d27f88d524fda45a0e3732a24477a4421f6b750e01fc9f597eb3fc88f29d2cdc90aec1c9bd2d393e083faee31b3d2ecd0750f771aab7e8cd04fa2841dcc0dc0b470f233f3778ed43cb6ca9178c789c0963fac99050a6c32f4b66ed0036504745978ecf37045392f0576d51f1df0e7eba790245e40f316bb3fb79a3d0da7493b876a07aaf729b22a9528265c415fcd04d93a99f27a10ad532a15bb1fb01bad59f4a419e6ac5f0442ee0f865747633db92995e4ab9ebb7134e2b22827255b8c6b5a2364f569ee2c9f792d8a4b90c07d00559b4c93d3cd328460e3dd33b73f3de3e2245e3cb1fd3e1e000c4f71996120631d244ac19feedbf4bdf3fdc3a4547e18e29192a18586da4ee64fbe0bb06750942facbe32d9ad48fa6eb3473ec51e3c465fb2b88494a2cdf9c0b800e0600552c70e8ef1a475f316cdd2b4bcb929828cdf7c7616f34beaa1109b751029a34dcd5ac53b35052370062c57ecda8a524d325ea4ea109bfa23c826723f5d03e7ca0752add1796e9ee3ac34043abda2df158f217412615044aa1b18193aa531c6eb14c3a8f5b1a7c41da449b2b9e4c74fde5296777cc2b929eb2d0952c372dd34f0e67703a84c86b313138eac3294cc2b4b956561c696bcb4eaa4aff578226414bbba9c1f083f48b976b9b45383eeccbc25c53fc713cbd661047b14745e5a7035d46f356e2cae48f10b05532174af6f5e7f5812ded43d5ca56281da5c3ec9b8e2de55ef498c1daa0fa9d9c5b08adeb4c904b5e15c9528c8b01b0a8aa7c6cf38b9a3731ece3ee5ee14737a12de088c025e929a799b9dd303ea089112f01222f7fe09d0ade615f7418f185254ccbb92925fe7473d788e3b3336f0a57cd5dede0537807415bc67629ebed0968c7a7e94ac68e7a54d52ca7f9c468823d3022f20bfbfe92faf027acab1b8b94e1e8955582cc02ebc2bf7db81f10ab3e3027c426421f2239eb603bfcb31fc3b01456c54b84f29d771128060a4df763aaedf2221255f452258cd7e3af0b8d8c128dab8dcac8443949f02e12fd395d03ae8579026e0a2735f44a301fe9ca600af410355b27db4aa1b1bb4a5ed06ebb41ea8a6dc0c201dffaf5fa7c1b0d07ef336b37f2c429fd5349cd7a7df33c7b9aedfbe5bc572a5b3e8324a02743bfcd9e185630544124baec999cb06165da323a68f9f2d36e19015eac050a30f97a6f303687a1847bc49f83420bd8264f12c9213921c24ddfdda101e3ee99c75309f6664fb81bec45205b7edcf3877e3d20d6c9c3ebdaf1c96d81d282a1674865717c4e8284d6e28307760dea4203c7cc0d1e4c8164221146d0efda63b59933718b229cac8e832aef082f2eb66606fe8fefcf934fa32d0b3cd3df3d3bd245e887429aa6f007deb1614fcd18b4ed11bb634a0e6eb879643bdaba3117b819dfd11b0d05f3bc11d12b2009b38b500612c358d985fc39d10eaf17b4244a53f051ebbd09bb019051a09851c11bb7a21f9be5d9cff9fb4b1ecd0109532623d357d1ded2d3a270b472641abaf7893d7cd022680d7bfa913db2f959084cd436ad086b4c4e7871e45af4f174504ba0b9e70f6f8006a1c253e581e061aba223af369516ad64721e81e76461def49ed7886a256970616f3d9df56c5d7bcb75023cdb4d1062bdcd0d9c6e1d2ac2f9331ea8e7c4ea3f0cb4c73ffadf9647a974be56d812adf9c0adf86e7a9670de438424915a030000000000000000000000002ff6a50564924da917b29cb696effa00644b10961a0e02a8913b836087c7ee284fec7e378b3d71240d7f0c00fe7f3e64efe5ee297645352f5d0abed31d028d5f76339f4463a9f4d73b0d9b98b0e66603ac1175ee6e6a875e4865732789dd9a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000634bf52a5716ca38e711faa4c07f974d2616624812f16efe8db906ae0066764c116a568668e019657a10e7d5f4e94dd4bfbd6c272dbf5206530da74da873989cc265fc1a1eac02d1deecb35bad50cfec92ab303efd7f9b93b54d6dd3afc4c2c08cad0fa8a3720e6908a1c2789fcd16e47892960090cb2c5d7a5a77c6c5f4c210321c66e3c7758dce464957de305109d843152ddd085fa98baf2403aa83c82d0fb03281ebb91d5e17887f05b74683e5c9a04325000c320447ebc2a6ed70fae9888590a04b0251b11c6eb72e1e877ce1dc1d44abf0a2ab891bbd775a9bb259de322ae9af4e210746171ef8f6a26961bcea4289592646c300580ac1acae9500d26db03e8032c81472fb7be00e95701a3e524d79a2167b9d5821bfb15dc96246f00ff4e42d80315b9df22eb99d3b91e46e679609d35807489504cb354f866b6bb0cce1fc284c1020d6a9d9eaa0768eeeb7f753b1f84d54574416df337d6273a7395fe3c30f11c1d0319dea5182b608c67e625c983eee4dd48a1be018ec19104d10841d4e6764f739b022fdab6f42eb093897c0d77c5d3bf9efd56dfbc4f6d8e05dc7a9e34910b9f391948547a18d8774c877160af04d271fa637de7e49665c2a53f71d8f87ab809d25b49eddab2ea1298e706ead155cc10b898d7dcf017c8b647906664bd270abc9d0a6a536e3779c8b5f178c916e968e07378159bfc0c2e88f4295a4606fa3933f2a432b1d0761ed9dd872decc07d30bbf84365bdfbbdd8a7e0b19a8571696ef27ac65c9d6ca112ec10e0817a562c89238210e1ef6010c692d687792210bb0a11bdfe7d8f5ce20f8f83207799b653a8319b7efd797975a41c765cc1afbab0a03a2d8eb1ba7382b9a96e6041415bcac73984d4161279144910c8847c27726c508b4b4366740fd59742cc4e088afce87e33c1c39e52d12373923f5d24efa9a801536ec1012fcb78d360dfbaf63e4c33f382c07fdb03d036790d408e19bdb1ddb3976f91e1e1aa02c84267c2e39d64dd7571f946ca5c6590dbd16a2f339c7479db27d2139a8373387c5fdd995c2c6fb1c0877866e0bf70b0aded5f9c5edf5ef49ecd236f7c2dd988dd17869a566eed9bbf1b2695a1e9c9088bb41916c94cab38628febcf9bc2033af08c6eff48e7483f2f9428839f0a7790007be768199dfba046c34fecf6d775e3967b48b7492f4be57cd5db2025c3471ea7ee89ed9ef2b3ff141f562cf27f4fe3a299c53bad633b6e799a13ff74e94733bff48430bbaf7e0924a33fb79ed9109168d30bdf9d6cd6e7eea96c121dbb65f17d9773520e424c83ba15d11fa9a8db7cdfb0ed41cdafb89cd3685994ab965400ca6662d9f9b548664cc3a93f5fc689449aa8bbfa989a7f70e92986a6f2de37cdde7bf06b3388c365185b208b5883342dfafb0aebff8f433d54d03cf1467d8954c5f635844a988e2a30e1648afa3be18f80c5d759f6efa3ee09d83f4e0c62fd3fc531bbf5a47e658259deb799448e70b3eac3400621bc18d29908566a36ddb5983c468ec0cddc0f67ebf8ae38712c1c5912db57553ae7713e502d01086ce992e2253b0fc65795bf7b4a2cf9f6cfda7194a06cdc37e61b4bbc6147fd50affe87eb89b9258764d7101ca54632c0d52722f54a1030c02875a44f22c57c9a56dbb907d06cf4355ab47367a4f3b6f7792c904cb6910db3087305e244c1ad2377ab79c600ff2c254b00d46a82bb6c278412899e2abb428881ecd39f98d47851bce409df2f1c6cc148ac32e5f2f4ad416f6b09210a7778c18491bbfd5e2a48afb284d8b797914c23ab7d287f46fc12350cfa7151d3647de577e50dfb1d260895a11becb96947b16c0ff7e87a4126c1b985319a77796d0408a04baf9c57883f02714f2ba83db128f29f5c186387c5d0315cb61aec2096ef8d4004352444f0a552f4ac7d5be349480ef7d141106dedb90df01062f6807c22c422298c455df7b35eb7fb04e6e86522aee1c5e8604d1d29000859a41e7044d8ccbf7b9af6c693a03f0d539a3ff05b428729002baab0bffc85533a9af995b04b7be60a6e717e0fd717f46d5d20e06ea02339e9458f60d6e14e2d8f7f120c708fdf3232f18d0d8d8a454a75fb783066ef316d7b6d3605c12b51bc65137e36ee9ad121213acdb98161c2ba39094e5dafc859b2c92158f48ff19682da9a3b0332461e00b3c0ae632c43163be29236e388cfd01186d70e1475a3388b20a15e00398e669b42e69c83ae6671c88a180c8f8c8dfe196f6080226b9121e2bfbb4f40d5348fddd21cd31360cb8258ab5d9f8c6429af64f1b8f46f4637ac55de0e41c5c2043ff0748e3dc32ef42ef014cb9bf163bd7a08e1f30f1b24e8d99c761a0cf5826a6bb864257b013effe3a2d9cb24a24c0552ddb3365b2d39f437001a5c609a71b69929f9791ce9b9aafb700f", "52ac520000ac51", 1, 806868455, 0, "e22875729a316e4fb28c943ee87208a3481ee5efdc26435c86f8c54bbdfcdbed"], + ["030000807082c40302368879cf418f04a110b2e6442b36fef990f6d720d6300cf0c16f4a554799e0700000000000cc5eb367614417bbc11fbfb5b9ef84c2e5b0662f7798b04d89ea99e44eb60bbba58e415f0300000006ac630063526502f897d4033281ce010000000007516a5200ac6aac825dcf0200000000036553acd7712a02000000000453636a6591b96b4b0000000003c44225050000000000000000000000003eea18eb793b2d62d0e805c85dc965d6bffe01b6c6fd7fec8a077ca6674ee1bd0357a1d28f3b22eb161b216e641e86b04fb83d7476e00a939f7d6891bc2a4f3940095d8889b102b485e77bcb7d559fb6426d672de4d9095b1eed007ac837fbbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da5c9bd1543eab8467c640b84ad13c8931a0952a5596101ebad65742a981aa3a4cb1edb32cb400fbb9d349988c464f3ed636ae92254a8bab2ce5819839a661ea0984fe900e3b4b66704d9da7c533788240b01d1020a0e08980a4c7f402503b24a7882c86e22aecef28bc419d55b12c5f9406ed06ed3f5aa8d5cd63b4899f246d0322d7f412030aea24988279aee51d0821d27227dfec392ccc4a7d25feccda095f022e6d7e6c756c659eca336649c5d0a0bf73a01458a5767fc15075f0831bbe3f070b0807185d05e0729e22e29a32ae01d7e0fc88f8e7636e23c175fb4d113ef9519c97bd0250fbbea537e1ccc09230358c241ddec4dc679592a6d51b3c48aaafb8390226c21fa5a2dcd56f47d3454ce5b91a67040ac4c583d0575442d7003e3b8acd2f03192057eb8691d6132cb0873f2ebcf46128c0b0a47dc8cb51f402fdaa696a2e69020caf2bc400af366eadb32d4554ceab3e6400addf6eb2bf74dfde56b1fcdd46c20209010c38b756dd61e7c93bff30ce895dad3b00e2038a131c3ddb60dfaccee581022bb546403dea8469cb4517813549097efdd40d4f51ea6f20cd41fe267731fbc6d85e3d759161176af8c5db90874ce47e0a281f4f63cf3b6e1cf47beb1a1ecb5563c79977d54c1258d6634c6752aa64058b6960dde52e0e19f8c0b98a81e45dfdbe5cda50fa40fec2dbf3445195954baf5ae3a363c9aaf92180373de877ba999740bdeb6537cc073bde658c99ddc223b0e60a8fa34fc8848e53ca409ed341c5cde9235eee16a6ba55b872bf1901051181b2c1d569fc81e6fb8115a7c580f0d5115ae7f9bcd1a980cdbb910c8a37caacc57e8020ffa1d29b92f4c4529029922ccec4d81076ad67b4bcbc6cce1af7cb6d528b782717449eb1faa11edf7f82e64c8cc8a2e5f8c94e22f153dfeeca0e3ad98b892430673240f4a2a5977bd437d5613d4c2e8f81080adda13c6b4b288d962fd8fb3bc15d89aa60a27dfc4a4bc0ee557dfb1c731552804dda0fe8158b79dc2fdf3fa370d739921735741b0931bfb0518e89ec6bbd395e23a93eb1a5fb65087f179f87951d7dd3f543efbcd95f57f5dc9f23b0ceb63826de36077c333f35247c1df5c3ae9810f347e84505ff59118aa7194443f44525ef5363d2081e1e787f39427bb5cd8a8f20e0ebd87289cbb6ba242639219714b4f14bcd4749607aee94b68e8708584f90d08227d7e01c769015fbed389d95121ce145eefbc917774d934d28fa308f6c969a94e0cf4354113c65fe008a34dde61922f0d540dfea6c75f9581e73e199e45699b69337c0c26e09f530a9b0f47aeac588cd42773ef3546b73237da90f72dd333ba6b81cdec933a65e44c83289c52bdcf40da96ad3e1cac198d320521766032e2aa30bde417ac1f574e124cbc962a5a0613f500aa76f6ee0b1102f294b8d2c200e72ba2d0581376c339d2a2e7659af6b7a619394d4f84619a967ed631dc6c89d6a5b32693545dcc63faf9aa7665896d5ab855966263a9d16f62ed748b4623649acad68d19a63e9e0d94f27c34bcad3872f2daa65d64e4129c84fb4160a4b5eb39084b120bf7ec2cc3e2bade97460703fbcd7621393e8107ead1457a2cf9d525d0ce270d07fd9408133157641266452d9ed8884ce5057f6312c79321c4eee64d1cd3c193ddc262a25af4a021d4fa0dc0abfe2615057c3208c098b2358e544f5b33ac1080b9d372894cf18fed3e37664f581c397df2f72252d03dedf464d29a4bf07a2f9e3b8e4365b210eda61fccc1dd6eba31697c83f010e49adf130a3b401e31d60ce923353ae0b0dc0afd27f7b922f797b7df889bb2c6f4992e3aa4d475f6a13d2eada4ebda883d7d6f53d7a57699373b9acb678316c3ade0d0063955584c0cbf8b2db1ace82d9dd249b3803cbbc604ede2a6f7e8f6be4765865eda92b72d810e9834d78456d97ca2a827e7c3b5a9ff7449b55e3ab8c772e4b8be468c70d113e3658738ddf5bc995df8d190f1d3c906ec9f25b5edd165d563ecd80bf95ad7ffcd99c72916723ffbc369399ebbca7aabecfabf84e73c9603f2841554b7bbc3d690a1e64ba6f91375e82923fa7046bcdb108f05b3b89bd24de40e36fd8e8ac33abb4c30d8d9977ac26455db9353b5466543221275f421fc2a8e522bfa7d9851488e3440c9b15e4cffdc110731ce96b40d3a1ffd165ab51e33f932f1626acdd894fa416ce324c91b245c006cd0a152486c6f0f1019e9beffb23b760f6959644f0683cbc66d623305ee9c8836ac57e933df50685d1eb811d164ac4def54100000000000000003dc2d400000000002f1a55e74ca6474759efbd660caf6d4d7440dad80bb9199e4ddb2270f927d2e62fc67837452cd1fa1605f7cf647800468e13251dfc826192fda4b8c924242e4581619b3d710d59e3bfba312d38cafd5d6e72e9a223dd216a8fe6283614818ff5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005aaad6c2cdf0503911c3a76b909b31c9cd8f0a5992a5933fb8c5ea1111de8da784cb550c80ce42d55fee207f1e7576d6e16f7c4bde8f7a8d689724bb4e429dffd97917c1d0d7b81517435c342d578a758e786201cc97b7f63a1b81ac02964821fa17262920fccda5c3d27d82b3b833c71b7d84397c5685f0df0ed1a4c940b3d9021bb14224a5f6761190f329baa312ca447794e58e63460726f4efc16e8541c6140200d5e63949f0565e9bc545142bc7faff43bba48382ac418c2cd95d3cb03507990a00291be988762d9c81bfc5ca082e47406c553a403ef387d505f2bf0b95c1258927c58be902cc39d116c06ce263b5c0d6d7567a844619f3ec1155924ad877c5bc0300f2ce0254160d67c74bdab5b6bd105afdf6da80409f6b3b4f6ee3865ba6251e03257d8c504632c98ed2ab6a174ef0061265126091312dabe2049ce2c238c9a1520201ab1f8abf33158bfa77efa54341a084f0ab29e70bfec3e483e93e647d86ad15022c0486a9e60fd537addf747877162909a850444c3d9713e26e0ae02253adbf3303029385cf7d8b0b816abd621ea268a743ce0dc022804262adf472c4222f2510a3f21c96776d6cc7b2d6578bf946d06454de385b2ac1db017e93d1420f811ce956737395c63c98aac070483e8f75299e93a1a0e46c6dfee34369eceac0960745ce83f63be55ae3f96b9cc4e9e06f729c438a47f2abfe8b63d194ca55d8e02f8ea35171f375bb3c9b3daaff1fce2159455d33260fadd7f3226a540d2b80045ee3ca4c7e74f64153116e5dd6b36fb5e18fa3d613ce931741e3df917504c7295b085dc091fb6674955ac337a3d60eac33cf12e9be485e36a35816c3a2fd56bb96bd3998420ffd824a4a568018a090bf8db7e427a9a030659bdc06f5965720c354314d1adeef488f57d7d323defb7536998c8efa7640a925d4bd3d0404e14abe66aab97128c820f277c9d5a70d01fbfd57842ee482e5c193ca2a4d46e625d4ab968b07de69589ff97cf629a3cd97d9389470a71e03e4355815c1dd0380a7fc5c717e2e717fbb4f3ae18278724f2ce46f7fa23b3242f77506f2264b4b143582f7bcab5e0f93367a2426aa711e7f3e51f78d8626ac220c716c141323cab4ff473d0178045b2fd1fecdc556a142e00b5a3f294afd7441ea4364ba5bbbc93b86b3a0ae3b3d42466350a1f3ec2e98b61da2b7751610f497494620ec297016cb09203e51d6b04d3f0af0d5c617bc4cbce4abcb71eafe28938932c67bb57c62d7cf53c0f97f7898533d647ad8d3f55f3e7bb6af9912fcb2c5d9a36c0ac3a61583127470c1ecc7a62bbc4d82b0e5501510c58b759e71d16a1dcacbc4a3cb2c32208c14bb6ae65af68bf19d5cbeaf941712532170aec39f2f74985e466ff527b716cc75eb257dae9bdc6950a4aa8dead1e97556873ca7cf47c45619ac42d26792a740d7aafca83e4dfad1c57d5758b0eefe20f1ad5e4ef295cada1a696c39f9fd6eed10272521ac9acb1898df6eaffb80410eb9112b243337c7f6bc3862d23f9007b398b2636098f3c1e5799625c6475654eae63e92ce86dd6e9e20743d33d413e721129cf3994067f7211eb73a58014ba2c74b126c57ab879bfbb47aecd64cd7abb2bc59b879f679e6f9a4dc7dfc21f078eaf68f14b07e26360b3cfc767b0c97ca19f4e146431df6d4b71dd1f8f81bdf81cab414b63d7c88b7f87e1c9bfda4cad402b53860bb4309ed4992fb5627d00ae891fa3aeaac4ddba0ec72643dc3af6ba371a1b73c5bae92f850db0470415eab8ec47cb8611f082170603ca3338ad28f0572e7a171ee21845a4c70378635b487f227a48035f7120d79b020b3ee5163ba3d1f724225f8dacf6cb6062bbf2ac9173b5cabdbd9694a2f0ecab8e09c2d3ea8513b1f482c609aee617ca45ac1d45abaeace3b4f1a44b4e80590b278a11d7dca35cde53adfca33ac601b1a5b9b07b6d9c834d896f83092ba21aa2f71194e83adf70d759a3f22b6b3df62ef1d642f759e2647d0056b3e8380c91c7adf26ad68c52bc6265a1b8d4f0357b2067d81def678f46e35e4fb1a13960d5ae597b35fde26c7cb0633c37c0c672fda01b33f5738599372456b62cca8bcca38b4d63a9c3a40ffa57f522f5d0d0615e37cf28e2d6d9526563e85e66dd32d65266f5ecd5e7b3be5e389e23e326b6bb25f38f4f7c0f7d3b79d3d874490cbb975c1550208ba55812deb2288d2ec236a57751901621ea29933f8a41f94090aa4ef33718ffd031c7c7a074f468d947bd5f5beb1b899cc6e7085c9414d56818964b40000000000000000d94c6d0500000000f902bda5b63225833e5626cca7c66f4d84f25c2b194410df472b4efea776adec729494102a1fb826f5e5f683e359b97c900aee8548b9baa663cb1a45eb4918c1499262199f42ba5c45c2298e10058a6088ec32835bb5f8ea12c18ececa224edd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e986f6ff7dd6e61493a0c9947b21c45432e344a9e61484dfa43b040fdf6442d3c562836d83b417c161940ac9555095426f3e08c794f653b5625adde6f156b145cd71f1a8944dd58232adeb2977dca69780c2cc5dc40671d48c7ff97d6d278c936cbb49aaa65c9d597871e76384314c2ca29d79c39fab5a7670f1982a62bf0190313cf3bf47d0be2a3d10258bc63cc7b77e668cf157041c2664b3a3818d928af10020d29536a7283c1f4e9da3eb3b7f24791c984d49ce1ff43864b493d93afaf03150b0862fa1a0a43375b36f52f4e1ff47e438c8932dede0da6fc9faa31edb428cb3d2b6b80eda189654eb64f960d7f5ae2543904dee4645564c21bc241ff97db28d8021e52351a9e46518343f4b239ed176ad2019e42d22ac8ebd436298f32e797b9aa0212382d044b4e3d87c72fcd324d0e32972c4250700b4ed01c19d125c03285d8da0212f62df597c253d2a049989bdf0e94b1ac673f04964c76ee72f678eb5e5f63a103118d8f9b88caf8fc4a7ab34aa6d7c1afb503d6a3a30705f2e319cf281cc03911031016c70aa1ad435996be5f383d9dce79332b4121c71a446064991fa2f7da527abfb55b65abf1e1d2bf9d4e96db91fab713397169b28b27a484050607c71c0b450ce250830925091595d511a912356430e9d5cef4c3b46271959cf434885ef0a52f200dd69a3401fd3937d70b30ed06b98986a3c819da57187cb47206427bd5ff65cbd3b03a2771409ec52750994149d6a7bb22d2a39f5e3c2541649f04d707f05aa4d22cbe229dc0f5dd601161f6a2801e2190cf505c2c9a0ec14b5196cfd75115b11c5359eb59bdc807abe0af18aa62f65513bf204f41120ca05cf46668c01ad9278cc8136fd8b7a6c8c22b826699099a449c41493b38da7a0426af6622e7343355e627da0bd476c5d0bc8aa2ee923e77cd534df6369ad560b796f2aff08d9ed4f8a9d145f0b94e88b85bf252f14ad3d41a91c0d124b614e2c306c4b84aa5c2761c88d166480944d9f5cbb95c8aca1fc75f0cfadb1daebf4a4522b333acbe0f5320582ccdaba84aceb26c4bbfb41056f40b1725a874861dfc2fa6eb0958806750d954ba7acf01e1995b6e85ace711c25ebae04b0438c783a39b48cae8cb63494f0188f44c305b23c9d9a3ce9bb7bc8a500cdd26d4bfe0506e5e43c890e4d849a359bf1beff8148153ab0f7d8579d03f01b09bde998353047f241643dff0991359b594b1a8adb100429d816baef4433b3af78c77e73f0e1e61a17f13f3d75e7614378f805b8fb755b196a6d46c77fed7cbb18a4e427bdc2e6d212e841048a39adc7fddae56576ffd5a61e850906e568504f261821e9f6f597fce339ef6af8eee95ccde9fa913652d72619bbd955f66aede88c159a86d48693fb4d6cc1bb4616c7faa5e48e7360fa199f92a323dd0fdd8f5baa818d17a91153d17e7ed0e3028440cc8b46c1697e66779187002e3609c01b5e9f35176204c8ff3ab10fb8a1ff8cd7d7981172e24cc2b125ca5a32c926340edc0dffc146a8af26e0adea1cc50995f64a8c8cdebfd0054a06828c3bef8037ded974b59779ac953f04973708f566585b1634c1749191d6ab02e940cc75bb541d6447431cabb20b469f5ff947677a156509bb0619413d99a287ab014e30f41a434b02483398f6e21e49ec39e2d4d3b363f36585c6919f66319c45d9545ad436206375a1e271c2cefdb914aa662f77b824023f2938a591dcb0c16ca31c8a907241ffb04380bbdfc386bbcbc4b2f3ed77ddbeb2e4277a95780f2f630b41b265b5e550ac10ad5d59b12ef2b1c17421fdc939306dbdf5972457c10c2ac3117d3a2001b9370ff8c469b77a8803b5ebdbc248289bfa46d53835607775a82d46aed2cacd814ca42f46ccf9da75205d1e6a36f527c63a1415b3696a677cec35adccb5a2d12606f5d1a33a3afa2706fd5e6664db65934c35f1cb62f3ed159641674fc6f25343187b2740775fafda368fa02993b158cfbc2adb8a1f14c153c51774924754de84c471731242105f50cb71fc92111e5ab4c678a30d62729a79ab3002f47c6f027b2503ab1c1c2061f8a7fa0611f606f2cb7ec05065b95a80a2211cd03b41f74e7642f2ad7deabab5ad7723c8fb0fdefdb777cbdf6cd3cfd9106af75ef7c5157d9178351de8a73a64c8e161e6dc7417b79f3e2be0255e0ad5b1dfd0349915fe5a88e66f0a22c935e6f950492397086b8b7235d242fa3d9b65c7cf6fda3b38a0b910875f60c5d6855c56934e8d43ee202611ff0a80db4e634cf33be21e355dba483ec436b047388a47e8c25ab939e864dd8cada09dd5999752baca296d7d03b3fc77779ccf24c02bfad5c4ba109a8230c956a5e2c14decae9499b50c4a4693d54755df85306741b229f7c2641581dccbec957f2bcf43f4f7162dcb18af23ff373bd04", "ac", 0, -1461451764, 0, "35a6e26039e9831031d396fa0cd42ae1dfcba1efa15ea41b6e93a9ca2bd29c66"], + ["6a345b4801551b6a3b97f67d952f325b34ec675e0d90ed916f5a2386135a28d6a297979600020000000963ac5351636a0000529010ba450483f1d803000000000700ac6aac516353ecd8320200000000095252526a526a636565bf121e010000000008006a656551535152c72d2103000000000665ac5265636548903ebb00", "516563006a52", 0, -1232720034, 1537743641, "fcf97e3dda3235c8e6b51dc3c69fc0d65b2fa87845f4eb02504ebc0097ceda35"], + ["ea5f331802292071de582365ae628963460dda4062bd666a726341efbf27d6e730c3ccbdff02000000045152526affffffff758050af707b800fa0382273cc5746fa370d1f13bd3013164c27cd7737ca13e8020000000452516551ffffffff03b23dbe01000000000853530052ac635352962a1e050000000001001841530100000000055153ac6a5200000000010000000000000000435465050000000042be46e96c6d2a1b3d9083dc8542b9f3a12af4a79561327166e590f28d33578c17eaba232929517bde4bd2179b652749f2c19646f5f0490983c5f8b5c74fdbda1fe65a588e45b2d734e8b49c789b12e652f005672196f45d184339416c51c3970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085558324707c65a9ab738bbd0c74babb7052d1eb6c7262f43ae60e3c71112e6b5e621b90e8722eef649a180e8008349de85928d836d8f6c435179088796199a582ae8cae96a6e0e77083c67f657819dbf374b3c79daab6cd45b21a915bede4acfb55e96d32cef7c01d1082524da93ce0c2c27d788a6271b55f420311f4064754031d8197f3f4382cc55902b0be201324ba462b944cd71da99ff207d66df89e90770213d8718c8cad5694dde828c1c67cce317bd68cc6922cbb9a5f4c351dff747d880a06d31f9088c06592851f8130d97359d32ecd48fd6532b493d295c2a62c7eb69e141d9d2c7640bc23e37dfe21ea2705ba3de8d7cdac8880af7e1f8264b59f6df9030c4fd56923e767b540eb95f8097cbd1d6c26f7ef3555696cd3ac9636c56a62a30223e1fa96a0d0f30726fb031bba2d1a22b6a1e51a52cec2463c4919c04315e2670215139bba33b2129fb717e466bd468278b9f976f7362ebef1fa53ca14625b26530218499b921c8ad4e62d07e1e92b4f155c86ff9bb1d4ff34225861f8f711bdd3bd030be62bc320c932eafc21fca1b17a1b282acdc3d1d76ecc0b82c7a9ed5c0a94f0d6f0898be40c6a055d983e985b14185455c24a6c2ac30051acda7a3f8528e691e08fc249e84cdcc5e504f9c0d2da6a96d7e4df319998de3905631f466c1d6cf0671b5676f17fca01c806eb1595dad9f3c21b5d2f3d082cf7ec415e58237b0c468bd43f10e0668d3a94d03b3acdc3a57e5959f92144f212e20f2f5d13451e0ed478012dc442331e49a8e731b33a0db3d633d6531d7edbab063a4372dd088bb92bd67a3fe67f6da23177adf145b7a5a6d30411c4fcff00343642b1db72a8632eb38ca1caae6f54b0d24e6b2f294738f95fc569dc4e76fad01bcf6a4229367aa0d031c1bc0751ada21e0d83c39b698f5f027a4b3ebfebd0fc695ed4b774d6c11c9878968106376900f5c10ebaaa603f3acdb28fd74d728a7e187213f3e05ffb8ab0bab00dc6704703294e35c3c4de91f665f65da1c418f22991d8156c25160af3d4e645fd8c655a46415e05a98db9bc3ac8d9186877128d1e40999ad38f4d9e0dd176b7d28cc810cd46905b4b3f66863ccf8a42fc6875e3962fc2619d6b37de442cf5b4caf2c17151a216608208bbc242c887bc51cbb2dd84d4b40db780a22e8409a8c4ba924a2bd5398980a77d2bd66a0c3f1a503e6d03213d618b7b89fa8e219035a117a1aea1d1d1c32f7b7ecaa376b712f784dbad2bca61d2897e3e21365e81c04f7d27a3d8b8ea2fcd9a2d4c2232187ecf2c0f66ba9121986398c6919aea806bfd664800f0202f7b0213a6851078050a6044403e20e03b6b178af3dea37ae82b5eeae0f1120c58ccb3fb46c0e3a17768969fd5ff4949029ef9aa0c6dca5942208b9720a9a357035120f4ebb18ebe58195ba2426d8ad44a2f68376a79f02e3958445c01bc7140ad0a5a7ce143919b75e235020a3753487c63f9f9c619bfbf9e25320ff5c2c92ea99a8fab2b7029423bf57a6a30d8fa6e043e86db6fdd8305e40ebf3ca615e577f3a4628007578678549e16697613ec9097dbbf544273455b493e379880e64e78bef824dd41eea905bde6738318a79d07fcd223d4694da6e7ce68431bdda8014093653f9c9f69f55b46fa845f90bc97c9bf43be6c3bc88f207043706127dabde5f4a29af9443cbabbdb9bd2d4d26bcc0a80a4c8d1dd133bef710d40bebb0c52f881f5228935d6e7606f22d95e226d18461449f394f1535f5d83791b5ecf7351c45677e3d927b18f3bb35a28c97c138a2bddc622f87532df7445bec208ecd44b07639be390eb8eae246a7b07553d212430181d21b3ca2e18ae08356894601e40b2a06ce4cc178e7b2cf00a642c0bdc1dd86fdf30c9a835b69a05ae33a5e8a84acd7e698b876a954cc5b130605bd86c7d595ab39b03f7763c04b99dcb73d7383ae6d02940eb6ea5eb77b11c9592b7ba69d18463b4e9eaf67cf66cd3408798ba1a7037c48075aaf09e15c7d7928be73806ce8384ef415576c0c2d05482403d0e0056152d2b190e2ce12590bd2388ea48e3c2eb41f97cac0f40e90a6c33b871bd94e3e873480bbd7ee8b40396a505b305b84383c39e5cf98464b04580e73d96a1b83a442163ef06bd4af89d3d65c96356971ba30b835e35a090ad1f0b92497d107b847006258e38af9a54fdb89075a57f6f9f2c132e46bdfe196908053ad1efc9cac9dedce57738049f37efcbeba739c665a34dad08842b977f4ca3e711bc4850026cf8adf5d1570661e52fb7898bca0d97ff57a0fb6c0c7b24efc9ee6a8197b8613d9c13190dce3a0163d6ec046c6b87c519320e73327f4bf7ebfcd2fae7c36fb84c27af34a58bd9b08162561e5ff12c6a0ab0e37ef55ccc592a92d5094d1d949b54742584f1e6feb1e007d708", "005363630053526a", 0, 299713053, 0, "9e0f6bf668a3b52d63c1490bd1e5097561a40b03743466523ed83052dc3876d5"], + ["030000807082c4030350ac85754925097a9deb5ec45a8d1f13802a004e51a8039dce252525229eeccc03000000075253526a526a52aa69bdd496c117e0b42549d5f891f0b9b366879963519dc9e037c58a0963f797094796b60300000008526a51650051acacffffffff9954d768080bd6881278edc48869b12f604d3ca8e243b7e752929043b9a3f83a0300000000ffffffff02bb076d0100000000076a536a65ac0051b49a9f030000000009525151636352ac5163000000000000000002e2274001000000000000000000000000954fd733cb814f3f2b9c25b4ebb3daaf8845e504048f2ec4e8fc2e9f9a9fdd79ff3e62956cb92cfae968e54a5e0f9a7fbcce358774d7453253e22269957927ffa92b775663a2169ae647c8c6b1c0c150301e1677a94638924ef7a21cb2e5269400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b20e7ece78494fbfff1cbbadd78a9b959bca0e4c61b419ab096279d832435e98d6d3a9dc9c397d0bd32a20643479156b41a28868271200d17285292d75addea0ac1f55f2fff8013a6bd19046477b293fc14fd0e004345edd6ee5f8e0346362d2bf91966c93259d1bcdf5744aba85aef90aed6245fed8a17e8283e95dc9bca24e032de3adf34fecce7a7530c6c6ed483878f58c8a1a51ef2b8ad66e1e04bce0643f0325c74626eca125dafddc6ca8c244f6dcb241d55c9b3bd505d998004976b0fb330a08d5d82d9dd567c96761e2239d781cfcd879fa8dce5c9453af7e3e75b37a093f76a4bf43390bb13ceec305186ae38c004a88436c3b6a025220f029a5f522fa7f0218549175d4ca4cd7b39652002ccd275ea6d890c4749ca6360c072ab04c30888b022883ccfd2351b21461747d19f4a6b0c4580ac152f1aeca8a6018aad1ddcbbc6203022fc7193686728e27e4cf9dbf8159f36ae9b71de73902fd2dd08b1b2a4091cb0213db4d657635fdbba2bcc21c33601f8503a66835bc101c193c1c1c77539429220204ec481de86e6ed22d2084f74b358ca9db98c2494b58448ac385738561f04dd68135b70481fb910b12dbee29b745b99150363a82e5be06948274f235289a7d25e7aef46fc58052356563dc953e1cc01dc270a8371d25173dbf46a7644cd6eab5c3f8a08eb7a488513ef9502a377d63620aa76fde11b83b38d7411ae396ab0a089d83e80ec5c99cc3be8fd93b19304d8709c51f66c4d0b13ffde4ce6320a8ecc8647b630f31081eddc28050b0050ab0c026d84fed74c3e73c7cdaba48fd79423d5be20f7bf80b368a835fd601ef72a8304c2936e484f628784f77d7a585d16a0001f229617a497bed7d7604d5c02c2b30cc51b6131766b10bc726a4023c73b72b5151874b333d594307daa6bce50d80b2998fdc5aa95901c766125f75db1e4dbf894114fdf5a6e81f72d8e49553f9a6ad05981916d4a23691aa0717e10471c84753447931721cf66e314268ed6e1a68146c7e0681ac0a4358263bbf2109b915a83bb43deed97405c17bcff5d7d45bbface2cf5774442fc2d88b49285d026bfc5e0649adfa9d6028666d6883170ab8f749daa36accda091158e12315071df96d33d6b3d6b75e2cfe016bc0ed73debbf35519f7c936c3249ae195013c52a1b11a448e23f57984f4796294dce76b41937123ee1a02e79cc4be40d5736a9318ac5ecf736cd683b86b715c65f26dbe9556fd74f16de540170700a462eb474e0adb5772958fa601d17fd9f5ed33cc01cb5bb56ca860bdfb1ac43e9645cdd0367d3b582f67f8e3cfc0e46040a4f7125515232c950cc92a789abb87d833cb41d8ae8d0a90ac3419311990a6ef3de2c528eb1ab0964d696eb7a3bb29da6b7e6ce04d0cb8b6f701b8f5e6f05ba8b5bea570f0a6e81a4fc9cdf8f117e3f2be14f02f1142934b6100a9a52a2b67b82ee418123f9b829604a31868e29d90724e0c0df77f936269cdcad02a98fd76d254b10837ea7a5043443dc67050033ae5da5165c678d0103ef0e00ec4d2bfb775152815fa03d5f7d456610a0984dd1d3dcad9aef53cfdb23fe1e792673895b025bbe6e8e39922d387c657694af03b56348c9b1df17742c745e4f359c45b826f1033a225b1f9f11be6e4b597b4092b316da4831b64a195848f8489ac7a2bd58d6257c279bf0e9fcf871e0114e5ca1c5a44cc7d2d8b3ea2756d3403a3ddd9bd3b235e2e7b2faf3123a31c825d847dd3e410bfb37a18f10c5cfbee9459768538915b0fa458f58e17cfdc94a5e758e63b7468072364c2c79cd509a5e7812ed325b9a83926ba13e05bf37e61e78dd5ffdea468782ca522e589b225c4138967ca02d235f0321401b38a07aea2a5562cfc652aa8dbd23fca877a0b23f6a82fe21a1094954ee1eb3ed5f63605b61c69d7f4fa178ebf5fa93da982303ab52c5a456bf95d3967d52867f4de08df4253e6146c28f26b86f8ba0a66e3ef794d568c1d02244b83ed815f7a2057ab2c275eb56e5ca876770992734a7ea3dfc764732a06451dcada21dc623d1c9933d2eb07fe5fc71e6bac740be9131023ddd5fbe35031d26ec2366f680ed79e5823a7bddf81696dbb2cb8443bb12a5a1c872a01ff528b02a8cb77cedcf43ebd6175b0261796a93c2cf2f0f81763480afdf2782f32aaa29f4d65ccb681d280b78bdd9658e7da8dc9e42ee6200d2808c683e79afbf7b9267047e1ce19da010e2d4ea9cfd20116518ec027458b72fb2c13b00bbdcab22d6d2f63ba90fec7b872fd8cf01d9144000000000000000015685202000000006dc167c0f02b58ba8f8e800255a5d89f2093296f2c28e1adefe95b4384f8bb4336dc2cb9f80d9dab96e2f66a6612abb2b8abe54ea96bb218135044057f85ae8b9740b3ae9d1d064b100274edcb6e9157a152be179c1065ecb2a8ddc624ebeacd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042a449b46f6ad534eed9c52fc119586192b4a7a755765a24533f247fd53ad9f41a4307943098ca4f699b9faaa6475241fc7be3758180c9cf3837dc20874bdebea7152433fc250de3e2a95829f91c776aa79ae0fbfc6358b10d66c89d901f86fd58552b6d3b2bfb6e568cd5e2417db46a4306cfdfeed7b9ccba7ea8c0d7a6da480214622785e4ecb460995f4df052c53d50f75d8468522e60067849f865c78f435a022079116063ff0592d1e86035accc21c2ae3d5d47dfef9a58580441df6c6a8f4d0b01ab37002c3dd4742ed87e2c292b4e0f3ce32f540d5a314257a13a096e03426e4b96472c54e73b19b6efefd4bcf3f801ea91240cd9ed03e8060393ff66c2240603294b355f3f4c853ca4fb9b72408f78089e7d4650d4c209e265b434c9fe04918c020d95495baf6928cb61edb354084eb7d10b19f63320f8864ba7c1aadc7f9068dc0225a6ffc10fa00efd9c8f8340fa02db6b7c236c08addfd61a8528a8c5f57858da031502eb4e99e45fd0c6367b89f495bd6211a464edfe65da559f4cea58ca57259302244e26b0b7589517fb07e2d0d04f6afc89e06b94c76aea5d3f7d7aa00703070518e39e071bf0c518ef08863ed6f27c66281d0f5e973c34cf656601592b22dc2dc4343a9a3829697701a6759647b5fee44e33a9a2efdc197fd0e641fb7a20ad61d4ff6f9132e04d79268db08b49a017265ef7183c2d8f14b41dd08907542fdd02305b4bb5749d26b7ed9bfedc5d49e761418c0668530cd61e07e7a2f955603448ad9131de6626ea5eff57b12a0698b72cd58e9997d17588aa2a87ef52873e79af272ee91c52fabfe6aefa8a1d051c5684e1ad7434fa7c5512f5238d37df0dd0afe655a7a07bd93d5eff7a93f73d1b7bb55456a4d35766c3a64e8b3ddc0abe3e0ef0d8f01cd38a277411a491c17bda5937d4e00391e8aa3dee9f8b44874d391d6d948a847a8b900882c36fddc021a9fa1aced720ef27388d7598a2131e0807799ebc7cc8fdacab38694c8335570ecbcd80b03768d6df95b36aa64ee0bde3487713e7abdd0df7a87f6094a2fe722d4ff9f5a98eadd7346ddb7cb7b47602b49ed425934a4405733dd58baa00a7b7c9c3d9a562d151356324a5e4e643b6a219d01ff9f55b6f89c5185ee9bdbcca38427edc4ca8fdc689cd4dc4c9180fdca9152cbbcb78b23338cb01559599eff01ba57b963032c03175722172efa436d39a9055d998c6177649843b419fd7b1ef9b2d1eb3109e2e88e96daf1ca7ac5ab88fb851ac26eb5b6c1321ae7cf6b8d85715ac5ee804101e76c07de7ebca06ad5116d00ae4ed92d74d114055d202d9dd1eb8e3d4eca564e764fc33bd2fb2e27d7bb01fbaeef2041ae3e9cfc23bd1e6587108c88d840accac160ddbe80836c9f5534c2b0de08766253fa0b69ae4fc001ab103b6b62e957ca8db85f76860fe1e51c905101660320d56db8f141df4b973a1f747fd6178d8a8d7db9552f9647ed9fc4e268e2cce0c75b50c0e482d6c09a40ecf2303cb57cdb6d0dbc8fa1ae38e698483748504fee01ff2538695d7bbb79fa53c8c6f194a4a54345a42af6b2f4a8341c176615185d6967d8ad0e7164245449c851d3a6326a46154e711a2d23a25ee98c26a2c7be8faa5722270ae5944d5dcfad0f80e9d7a22375e40af52d0c871273e9131bfeb09ce9ab0733abcf8e68e1db8600a43f63957d46579c16a6e2757e18fb2d05a6ee2de59a161a569d01eeb20d71738e3ada842263ed4f5c2ac348d6b207eb6878211f6b90649db6dec51e49449be2ca70fbe58b64e4ff513651472180c3ab79b2b898c88930051c02bfcdf4f58342e01fbf0e3c1e265349a110d34a2b033f252ed17460f78c03d463ee91a9fe880e78f34b00c8b34a7fd7cc18c7827e1f74f1bbc06690f67b1ce31923ffb82aec22bf8e11e998611a438578f7425c21ef99930f62d72cd0cb283519790975592e2c46bf4cd573887e58953794ab2cf4ade8407cb7392abf2fc917615a539361f721ea133ab96cec67159fd5ee7fefefcf8a47e1b58a6b472054b966a02db9d944b23f1526af25795652c278aa3a0310cb2f71245050eb923730e1fd271a9628e069ffef4554c00eeeb60bae5d7388423f6d1caed60ab4ebd35135933397f72fdc3548582864f70c0a4dc5606231983355c8e50984542545df1bb3c9de6408db2b400ab3f8ef3310e8cc9db47ef9a56cf5b5abdb8cdc18712703785b8a99a93040359ae5041444b4ea5f2b26986027fba93d5b6b8e6b263e017d5d49ff3d7bfc1b769f68f899a7c4608d8e86aead7fccccb17a7c4969937352f81c32f90b669cd5b1a24f0c10e53138a0a3c29cf3b5cfda1b5eccab4220579ca3291641367cf5a33ea28777ea8ef6d7bb9d0edb673a634ced65b332ca900b933acbb8dfc85d3f1d87122195bcd6806", "ac51ac6a00", 1, 1596960850, 0, "55bc69369fa744276ba89fdaac2c2c6987d71e1401174bb9fabc7f0b9557c5f6"], + ["030000807082c40302ee53e5a06bccde1523c4e963e443b7c4a2a7d19ed96243b8566059ddf91e3ad9030000000952ac6a536a6a525151ffffffffd078f8d895e2575c00c2e1e2035139ab34a1e2dcb36f7a978bb182f01358d6940000000001537f15198c018a037f050000000008516365ac52006aac90c8fd6b03e95f9b02000000000000000000221803000000005bac2ff9dcb8f50fce2a281941d196cffd3ee602c002a0d37c87ed7d30d207aa281952422873270e8041962a903870d2054d6a5e1863bce2bae770cd3db6fa3e377285eea0e72fa501215041da0157efe1cc86003ada99b49e2c379f240ab37900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dba818a2f0bfe5fbe82ceb53b7a3a5e9d275f02cef20721c1a1c19cc4278115ac49e07949bf1614c06124731791c3062ab64826c9f773617206115c203fbc5043677169f276ac6495efc882e9a15cfff75504800f3e2aaf444a7b611f42a09a031a14e9168184a7f7b491b1c54a337f6b14ad829978516391f1e4bf2286b09d403069bf53106b3addabc9804d8f9fb1bc74af5501255e6793c19602dae699ebf390302f971b4f9e03c44b9104655643cb06ee19798d2cf7b2d8c9e6a45c4bce753220a008d44654caa2d1f1b87fb3fd1257d45074eaeccdc3865feb2b0923feda9a557b72bf40768b5e7efd09d12de383d2df0a4d24cdfcd472db772295eda436f4c9f02043cff44b4203525f5ef17a1e350d3816f4f7dae62396d69e73b5b819aad625a020c9b0a5b2695b0b830aaa6ee3d48200740c2f26350e6a6a12132460ead4d4de902269c6f98cd7c461890cad8585b5cb5eeb70b491bd2efa0efe1ed13afebbf548f031cc6df2e80e32ac2a974d60a4a24fa80e72b1e29c1d8372a70965ac0b9e408020321a62ca95859e7038ba562f4ab5b631ab92732a632ac468f4c2a99b5e9ec0b5310f65526f61cec1b0b1f3d3b974545168625c5e9702f12a83933773d9122742e7eb5e870caef561cf4f8d8b5b710db8cbaeef6162247308518e6be8f7f40fde52f4c732a541cfc93e585568f4b1844276d4e6aa78429084c03e859f1e5c98845745e5e0ecda40d2617db30af89b2e7392af2cc0ebcad42dbba19532115f6cedd96515ca778bfc68d8286247b9dc1c3cf8831bb146e2f93c0528c75020bfa34d8d4f986c231cd7cae82183ed5d61767923dca7d306e360f7d3bdf1b33f61599cef24504e65589d87950ff2c95e0a6ada8f4ae602b21b133c86460b59b43206f25049ed63575c821f53e345f779b1ae238a062ffd5029ace6940dba7251d609de70179bb30205da12960302f90ea67b4d850a1e407af45099d83b7c12557a64933448c2b34b0ac7c8fd87d21143ff098875bfc0fffa79720b4c57972416e7d86994e9e12c419a77f608da858c8fe8b129ab944c4791820465e05105c51972e1c77df217133de1946507023593f3b7cc6bd58f4b645d282f2d0fd03db62d5c5acbd61b927c26d73138fefd73f5764f14382e133dba2842ffbbfd124fbf40029ba34a6665dd1657bda83fca45e02759b424796d125d732b2db5d74898e049a7d53316c25606c3a79c97c950924a658f80ce73dd76f34933e7379248e08322fff23cf8e33b4817e4e1bb603d104e197159326f9b7ab6b876fbafa81e831b8f3f203cf4cbc5c6feaf0674378e6902943067d672316375d3d0a6989ee00d682414e496514d7fc8baf552cc284f22e579ce7cde038a369e9e6d3a4bdf10ccb11af94b9146244866704cf23eedc7582815bec9abadeaae791df1f6228417bee9aeb94ffd1110ae3cc6a300bf3524095a98732cfeacbb3fc0911fcd6230eeb88abedf43bb8a57117e55d5ae06c5cf96efb28699d59b84de69bfd3b1b82e591c346034d7d899269caf506d641965c75adad862e3327d7092a7c7339a3779fc5ef5e25376eefc77d738983233f33e9dea8097d6d0783aaa5a16406166642b603d4f7a32f5cb129386a45134bef18f87e28cb7ce5161d03db7ac8c4cab92833a237f905de9c91e134a4ca8eee5ab5d582e8cae3e8ee76ded9bf0edb15fd1a3a926ecd1d237fe50503b17965359a3f581bdb3574835652bb1ecb26f57c2e94758b107e589217c7bb6d3507ae35292c1534fbbb5a632ef98f7f008565683c19dc52cdb0961958d125f390324c26365f304ae6661b812947cdb1441f3b8a741ea4d156dbf3a252c8b657538940e8307fa45e1e5d0f87c91725bbd0eca560ef1773048872833e1fe4d7cbb82db6007f9c71ccb77af19d1899246daa62d5273fb618c62d02132d2fc0de08e837677d6e7968020a4748814c1d00ac075f84818d798918c322f27a5eb677c4134e55f648dd0a3077fa7ddf684450e4f4a59f2132ec14877d7a16f627620d7f30571db05aa6bccaea8e463ccb5032a5833c311170defa45b4803e966c5a1719627b60b07fbdd492f391d6413e796532ce789e077ab4f92a99c9735df2ac9666b1ea3bc2a213ad2e7866899f3c81317a2c0b295a3190569c6a67f1cbcaf6fd39c89de120d200e4f77de442b581e966c2b23faf6e82f0b9138310fc421c2fdabea7c822e92dc668851a86b71bdd8870583d30c0447ac69efdc9c8fbae197462ab3d5c5ff3d09df4f590eaa86bd2f17e9800000000000000004d4a930100000000afa867d24f3afe53c722ec62ac0104c7c7dcfc3d3b09f9ce2e0390618b4acf3c2d4b9789c6f23933fdb98a360fb638399da0bf76e6fde88409ff6b1c7d274e5d1951e33dee7bbfa4451641aced18072b057b2ab62a922b01524cc5e66a62fb7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0d1d1d4292f0404118f091c881a0611605f572ddf62a2c5812c28e2dea888d8a33192b7aeeead704900a9eb306090cded98ecf2926bbc60d236a2140718fb48fe3721186e5bea8328c083958b76fb94dd8bd11c86c4406e78684825f3a82ed785aaaa1d3b8179867d65d51f3db1c2969c4ba1b3ecbfbb329b4086c6bbec48c90208cb83d1972c64d71fdd2e92a1dc017f6adfa0daaecbc2b87c1d96c202c0d59302031902c5eb82889415407e71a48308c439dfb237efa4a817aa477c3151e1274f0a06fda1dff7e56f0c571bdba00a8206216ef4c9bd1a56204a8df5085f0b15be4597fb8dbe323a45130a0fc1c4415eca9f86625f3ad491d4c153eab2e4f31f76e7020232201024d34c32deb98a4f0e241c76921de92500a2ae2b30fab3c24f4d9b43020a878d72d196253cfe629ec55784b118e6b80222c0fa85f5ce5a361f280734a503136dd89347116c594aa3dbb031fe88610853b66468408099a30eaede8cf5568b02022718028ac18585b3749673df828a4b2d8f115b6f6d8bf426636499f94ea26402105d9964a1e8df9250a10a5d0f41dda2e882d7340d068f52c5d53d9a26f2cc69a66b57983ab8f6dedd136344466a9272f73aa6a6eda3b035ca1cb808666dab72d42c941a9fad84238abb696b934a91fba5ab80b96c45dce75557ac09d0cc15ded3020a26ce136cdf8626ca5a11b497874d9eacf31087b85cb50d0969f9c8d8202f3e33282d8995c7cc0bb4eaad36037cb2613702026e7c2ca67f58aa63088bb4a929a0b0c075194586c1a177266595b1bcd9c2467753bf24c726fe6a89b8d911b3dd3dc23be7561b1c38eeaad28243d17f21cbcddc9dc299f3c3939de654c5dacbf0713632e92d7ca3b41988a8bf80556aa6e304d98167a16ba5d3b1eb5b04d5375870ae2db070f812843b5f3205dfa9007ecd3f97384ad6a8f84ab70978a81a66d4097187a089ab9c12d34a53e58c8616370e9f7f983eb43bb54afaf869eb113a6e48a27abfc2ca607756173e5f028fa57e70bb30adefe206f17bb65731e4a0ccb6320fd2e01b21f3e16d8fda5ecdddf0f8a1dc1ddac7bb79e72f7655f96360341faea948284454f614d475dfa9028695a04f43be995e5e9f7bbcfb5b9c14932b448febfef79b1736874c467c896eab38c0ba3d88edb77eb022c28e382bd6c885d0135c205baccd49682b25b26719b755559143464dc3c4a322ee90c725521e77406d65923f3d6c6e01427a9c1d6ee7423119ef2bc66eccbc62b70e19b69dc3dc3fe7977f8ef38b7e48c86648e70ad686b73b7eca980adcb85e556168d91e25e6252d9dc757fd605ea00a3bef8655ecc5abfe2d17e843be20a7c61438b0c3c7b8852eed390bf3f1d593aa0ae637c92fa7ba8dd9e04a3424624a0d57e8bf5b082ccf1ed64b5f46fd2fa1fd726336dc09b308879df43c341a00dca809284b7c4cf0b8bb4b400ac51bb088b11893a7d7e4187f6c9fc8fc3cbe41d6c939b2a9e8328eec66c9928f1898be9de0df554027214df3bea5131b4821ac0df3ad8484d252432a1768680e62164f23a134f4a3fc9fd86e52b94505f7d64d331801832d47271145ea48ecb2e2dfb3598e7ccbabfa8ee38d44101c99ecdd5e1002e8f021ead75306795af24b3233a105e55bd6e2a671948e3eb473931465045025b570250533280b9d5e1749a6fa6003cc925ec4b4a66cf2a1047ea88ea0c30c4f71a201d69f22e6f69d7b79cf59bf46fe52254b49cda93f24c7ab9685810d83fd83a06c23c5e64c165785be6bedc47ddc456a653914bfbf96e6adf939cfe3d03a155d12ba2b50de07da3042d2a80dd05aab4e19c7f750674ffb6d25603e1a005270e8eb88ebd63fd7ddbc46918e8fed9414f57761254768c9502f83105ad932a0d012d81dbbc9d35249876962d6653ddfe125e2507533d670f76dcacac16a0d3678a2b639d6cb0fd1c43f742c8b17c7fc0275f60985f609cf482d5653aff9d82ba226e6991a24d02e441c934d8fd51dc3122d6974a633f519033afc6aa6ba3bbee4d647bc51897db1afeb8d795d365a8ca8d9183a283cbe1a06b93d59357186b53eb8529a906605f3a5a77b39c75c11670c2476a1492c1d0d5e19a120ed2c0b3f86e4210078720a4272c7586629cd86f8a17b4d801b05402bea321faa939938590163e42b5f1394bd85b1d27f2a2243bc003fd837cde263481074d69ec9ea03dcce375504020fc1c3f715fa33606d5366c2ed91988de498f553922524774c49343bb30a889028d76257321c0664152dddf711cb4738dda3959963a2f4c6aed8cab13ddec7a8205b6c80c6d99528480dbc8c6be358a2a5cfb7263a6bc639efc69b843817a87f40289ed4826df4949aec052ba61a851cba83158e329e11fe00cc457ef86f78ad6a1a26e31c692608dda54a78c43fea66090b", "53ac5365535365", 1, -1509103470, 1537743641, "2f9f7940d85e006a4172c6c9765986c8b030fa8a29e63477d5ec9119f42b9315"], + ["c0853d610468d4eb527a0a242fef86eca4e0eb94b3b25c624fb6d7cc0ef1150280195506280200000004635265acffffffff4f4271e6b16d08eea21a1a979803182d4d2eef83497d55c7045a73b09ad5dc250200000009536a00655153005265ff97a34573852fb46383d6047a268d005076b8cd8067d156c305a85d8bdbace142ced3550100000007536a6552655300ffffffff90b28ff77fe736349fb2ac24f947479cb6b891ed994dc5f6f1c1a2d00587b96f00000000086a51ac656aac5151ffffffff03938852040000000003006300c734000100000000046a65636acf4fea0100000000096a656a5252635152000000000003c8ec6d00000000000000000000000000e420f76308566d59067988d1f1c0e84f48f96aa0943bb6592c6bafe64de3d11ee790146c62a401822b9498c27ea6084b3cffaccd2de7e6a82ab1ad52c4a3352a27bd2bf037da0a1a9a8bb02c58e77928bd8ad83bf9c44cd19c213549f37ae9de000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001376e7a28fa416bb05ff04a2fa4bc83f5282364ac856fa23addb81d90e43003431fe866a8afc6c5665be795ec24d86f81c5723df1c45cd941b4e2e654a8497a8694b97a1d284b52230c4ac9fd9b7a81d0c84e51b72834c916abead75b798fd347b340cb57c7d5db460d11722bccfdcb6546ffbc5453ec0a85ca13f62772ce61f031096ef60acc53e0ef2dcc9e740182355f920308b29ca311ea0b04f3b80c0ae570227ce140cff026db4e4f29696fd635865183076432e429ec732a419215c8d2c190a0859042e53eded2a7ae880a508e9c63ea77d0f8542642800a0320d32e9b70f890c34030e9f593b6b06960766bbe0b6e0d024754ff6f646de4daac26740fce5b202182e0398a2d2cd0cdea9b900863e7663c04cf28ab74ceddbbbf6aad45018ed7a032504670b6a26ad4a23528b6aefe86e1b70332867c101753e146e3244084ad01c03185e4538b84f2dfbf3354ff4984b34c20afeff6179b20435ac161d6255d74f51032f05d15567cd2e674e6cb00087c7a1cdd2512e242b88a37a98b71e7cfb7012de020a7d31efb28626e1abea679503ea51d94ea5402086defb7fc91a946fd43f4393c240285222390627bd7560a46b4fddf1d195cb05667e57ec2f66ec3318612974b8f37547297d655338d5312226a207b9650ea1e92e34e64f8d661a5983941fc9bb41d11e100ccf0345dea1b811eb692525d567ad4bd086de344cd0bac3aa6225252b84f700a5838a025ce5580e995eb128edc6e0fb71e1c8dd13f0d33d8aa804811a762a0e3a389ca7f02c2ed6b287c8975ef1ec1a962368929832653477b3fbb4dd736facb429e4cdb9b1d68cbaedfa05a0923430959ce02d01c964d7278b8e6d29e889df25ad92e898fd94f762f0b5ab939a1b42a4583c49255db5fa0282b6ec3751428b753873a5f24ccfc021c68ae5a68683543dee7e72f8b0efbf42c10b620b61027bd01b23d19b612d74bbd8cfe239b591ba26432b0734f13d16866b23b636cb6182a85356007e4a7f828f57679e502f93b6e5f2d67af25a87fd41023c83d404f5b07996a3eda495f1baa9a22e7dc5982ccf7fa4165bbea00c3a484f8ff579e06334ff3c367654e0c047cf5560937070652b40f6c04f9bc19424095024239a89420ab80258f3bd8a1d4b6adf4516f0ce21d94f0778957f4bacada975af1a02234ca90315d5c33ae471514d74746e1d22c003da1f76249c363c101aa4a07e1aa919ac05edbb84717001ed250dbc564f0dab5c5c1c6efd9332b0c1fde0996f44cff5d1591da644a2f3872709d335922b8391bcbe5232ef7f30c18c29445aa32745ef38e3e10dd28cb4908fc0c80d6f5c016e0469054941a00c558786499097cdc00f7dcca7ea85e1b05b97f30ee13a0c0dc37410e0423a8b1a6a634909fa9461a92c794b976930a72922fbfa402c4511ad07089a3251149bc77e20759a517bf91038b1258577f42c6d2baaf1ca43de9b637f09965c3c6ad19b3b7bd368c881019f53c119d139ba754c48bb4df0c10612e06fdcdaff09dce04a55d2a56981825b3d1494848eab387c517f401d80dcc3fff94fe178275b2c50539cc5ed1cb886d5bcd0b4216ec5c76ff79ab3172a346353acce0bb3975689b3dacd1e43ff7606f6f9200e686d6c83c98da1b1173129727fbcf6422c7d12ea9b2cd34a4d370d16b6d5dce5b14151bf7556c5dfcc9592d206fc670bd9f62d150bc5c9827868d0d358433c629f0548b754aa50f6daaaa7c458f285078d261fd926303830c0b05b91d73678e6474e6f02bbd37d42f614be361cdd33222f3d5ebb3a734a715203aaf26bb8f363211767bd6d4e1292957d439c8ecadfd960e39aacdbaa5a883cd897b25c1a69e863be4fc76d11c7cfcb51b24eb5eb07633a7a5bcc6adee4ff45a57e1953226ec85d23f1579f399e8aefcd0bb58f976406afecfeb2d9dc7877f2a595f3a28d14c92c6d0bb61d708f4bfe41a3d2ee31b6c11c2d7361d88e5543d9bc00cb951ac6f529fa5e580de4718a8fdebb068848d14229fbec74411eb82b2e061f5f0d4ca86bb61e6168e8852e5959942d0d01a1be7df4893fcbac6f1180a9d3bec76b4f7b772549b3509913979d6d22b850a4fd0a3297e45aec9cd9082efcbaaa5482c9a11076252c89c18a32b8f8d387adb6010633e3f0b5cd3cb04661e056371a2f8d45e4acc6b899d4798bd55244ff406b2f94407fb2bbc3f550495dfc3c30d8c4a7d637bd1cb04ea5c81376a5648b96fe0845befd8ef968607e30b8a30e6f200f2aeec360314e67b20fbe5cafa98fa3960000000000000000b5b0f70300000000b84aceb4251a643a98bb2660372e3078c852ae0fa25b8f5ccd193414a3406a4e67bf127fff8c9e1eba28f538566e0dccfd6c8cf1a6657e98ca91cff0ee01472e6448b9d2dd18ff99ce589839ad21aca9505c556633ab232abe3c9bfd73d9542100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc9c4e6230a3baddaf0ed752c48de02c2f45820227ceb649ec9a607b6833417725ae8f2fe5138b6d35a901b79d4911bfc7470f75694228f3309bdab47b68649c8d9e6eccc5238f4717b7361f0766079895cb4e5431a082b8975d5781430ca7f152ea7ed2472cd881441e83a53183f2122543cc29af8a40b5d39f5d02e4e2a12b02260a68323b3878d74af8b438b10268ba04f07336c31022b2853884cb9f17d9ae021bfefc1d0c3d3f4660a94f27d9d537328bd3e3e6a2b17c4a0bbc3d4d22c892930b0797a7d9151c99d84742f47f9a9dfd0542c6f11d08c8e92129733484bf56188b09ca885c295ad46914d96bef4d38850dcf1df8a7ccb1afd80b21feac2a858d11021a2d34b5dc9508d166f5317586550d6558b67715224d1db478e6c8ce9809b0710316950148deb62d3d3ecfa7a4eda0dae5c5217f706abd8695c2dd1fa9a936b399021adca3294bb0faaca0712e640f3ff3c68987284f2afed4a8c1e96c9d0f684bba020107af492a77dca9e656f8073e6d011444634439839e3ee4d774378cca21e7020323f7a470c25bc1df7003fed0656a577c6697335b097f737651d7eddd3450b7ce39fb4f4f0643b0653640a244830c8b622d27942b9e325b022e85d05135ce1546db6cc8edf7cee84c8f5a3b4fb8fa7a54ec30f697afd3b7d55fb5867d4795d70e7a367eb10d694cd9afb61dca5de9525e22654a6a9682c1458c37800da37f25283df1b66ef31b7f5db4c896064258721c7a4391a79942259242ff765f4cd09b66b5d79fbdab8e3017a933bca6e79a1120afd60f7def9a417d80bc451f08956c00b74166ef3343f283905e824cacb4f237dfd86f4f8904ee9efc80004743eee3c382077ab63825eddc78703a3f194b2b617366101eb6933126bcfc71b0fcd3d89c374cec275f370e01dc6ab5e396042dc8c841de8dff40f11a09c598756c25904f2e24927e2d54a0a561ef477d139b102bd4b7680d28a4061b24c9608eb6215c984c4b271da7f54da86c4cf72e28ed8d7e07c7a7cbd7803142869b03bbf86d6913b4ddfa860d9c04bd622b43f96c51f00f40adad46bac4ca5616ec2d6b08907b58df0648b63eebe0186c5f8bf4ab8030134f116921cdd5e81f5b9d2dd88cdb096a61b6f1d58cb5cebebe59bcb9804b3eda335e1d268e6d3a1bf8bc9acbf7da4a9f7bf0d1d2780f26136408beed5e61e84fe598204c82cd5c147a558d726e7d1f24fc65a25f334872afc64aa8972927799047b3563a3d3df8905206e2eb4fa7cc8c8328785e81d8b29ce424c3ee8de10aa2f98dd377d1aca6fe6f5d8adcc20690ffac327d6dfdc9ebe6b311560454aa11d18a5496724dd01cd6fad5e85a1fcb7d810ba4d41f52bcc8cdf6a194d46d47dce3fc4a69a459a08c6bed7d57226bb45e986306987fdac412cdfe15ad298341707f46e5d36c481109820a4bc9bce9df91e401db71d6f5187498f9b6b6b8cf762ded20fa9b0402724ec7a1bd997a320f18bf032c984c8b4f22fe1d0bd02d3644311091c01c9655d28966507b7ba335f60057f27df10723389c6ef466327a318fb4071099edff15fdefe81ffba9d104df67012542ce8b67079c1f1800280389cf760bad845cef6ac0c96aabd478640064c3b424c9a788c8ce4bbd03b5898097df12cff86fdaa00d180acbc3566abe7007df38e8722a005f05d0d2199b8bdb90b34fc87341521bef9c0f63903f75b430546453265b91346c194f976a5fd9cbb57334a6cff8a9faf21b2fa4433aaabac7194a47716405eff94a5059df39c63d98197b0b12bee426a151c8a2ec73200e6b6117f937046d7b85ee0e8fe19b2bcd7a12ae7bee7905dc4c3251ea79b24b5a05b745b906c86c84c0de9fbd73679323612c1634a23f2976451a8e04ffd7de615cb2281b339d87dec033a1dc3485d343b254153a8b2c2f3f00305d389983ef5861a34e405b4aee29bd24993d16c448e106fff6af1db9acdceb0b66dc8affa33d8b7cac844a7024b68f10697f7cb00d9ff6740ceff874e62b41c129e7f21a4dbf3bacd8e23e856320aca94f59da158efb85a659bcfc609c2da52ac781cad9ba18bbe499e739f95c984c83d6e4d9637afa3cee7638801a3102e4404ef48004168d577524a36b84275bb6fd45f0d78fa87af3109c2e7fca0e79af5ca91e0f0ffe11009fc8c6bbde16d32e3af2a4aede75d9fd261fb4538319d8f4532010ff255e902c541ae964810c9a4b6de5aecde7e606d94bee0f73a6d881a7aa6416adfa1424f34506f79b741d1e104c8da6b390bc8aefa0c2a37d36570958040000000000000000000000003bb12eaf98e63e7ee2323ab9d7d42781a136f5d3c11982598d043d0a98625150cab2ee50347173688e206058c469fe158ffea85e2cb2e114e66508b11110a9ce79bcb25efbe3c6fbe07916b4e3ac288212d24c7af0b0a44c09323227eb93502f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f1596b0962146c70973ef3e97edae8577c70e285bebb8ff83157ef5483248f186579064770fa955b30e99fa416a29dd47d4f63a6f457845037feaa715673921dc4ef9e9dd738b5bc551375142d900416f9c1c4a6487f6da85fad224cb156766bad754c3c0b9c613f54aed2da8cf70f7c80e8dec7e4a6eeffada5f762c3c2ee4032b7f88479e8a16e787c2598018debaf909c5600217deb033fdc17941b0ef47cc02210689467461f90828a87630d7ab7b7ca6cde9e4325a36498ce1e14b3dfbb4060b048a5c917c1ff5b914018ba38a1660a00d12a5a911862e55f510015ca4b9f451c414ead3f843e0e7fc5d32a94505e8564bcda2fa9da32ba77eb1cc94701d4acc030c238373d6157f39bd8a7213afd7a2340d50d33dbefd81a0409e85ae1337d95c02011ca57db8032821ac4da6c7af92a4aafae60e36ce5b3a5367ef5f9e72b2a7a50210fa65aa9792426c15ba0067c6658d29f3855a43d9d6de26345be102918c6a5e03189f100537094e49deef18a56580ec43842452cb0291fc0e48ea1f90f3180d500314281cd7d7d1ece65d015cbb72f53dc724c39e12387fa3e44ccdb40d9af44639d52401c36213d0862dcef8d760c62b67830490974a956698ebb5a2456c2f01ee3056fc35407c2eb81c2464b5c079924eb15b726fb951e8c9cde6e93ca96e266d74175791bda0cd1290730b302eaffcc6c8270b88d2ee64526c36c00de3f8a99e1e180d4f83e2473fe6c5da08e86a6e5c96374fc21722b1021ad4374b2f2939838d706fe7ab5d69328e42252df283bc57bd3cdca435af7c726b38672fd6c5e92276629b96b809ce42e28f3df1f8502aeb614746d34b99d748592b33d678801b80c051d1989ec4af36815d4c802d63ac62c4c64d31a396da922c4aac2a93aeef3cf44e3ab19e3f9f5ea3e0a90003394087ef8badfdf440cef35f7a3ce71476089b1558eacf207db0a26ede3930c18af69aa5324bc97f3a43bb3e5bd14852d1ac664a540b4b1139e0afca1917349ad281ba14e6e9fbe2751bce2547c8099c9003dd8812da5c552966682d3cbc4698e62d9c8a42cfada1b7dd37d49018588d18b4b744acc5c7b37646dc07743565c412ba6e6e93cb9f81b01ad27d8dab8e8e1b94201114080ebf1136ff7b70c344d2e3103f6e621d831ed28214c4d82ef38b733d999abd963b88162ebad6303230ddd076bae33c538179029cb4c7a0063482aef0cd377bc2f1f525591e617423c0210f9dffabf80f39b1737e7a55511e64e13ca8f52e09a523bcfe9298f4d0ebcc4e5213a6379066c740341d8f283fe18902f4c44ef2645db6112c3062f58238fbfdc02b2a73834cbb877d993b42dbda585023554af3bfb2b1b1aa3069ccda5012dfeae21aebff4eff6082e6f6efbc187c9fb4b8bca743e556a655e6b904f1b2d9c2e56ef4609bd3a447265fccf119e760e28161175e6c83f5b82a7c6bf82067dedb0655e2918179bae367e9d826c7bebcc68cb89a904c2aca19e3b6d2acd09cb30df3521421a83f035091ccdc7fb087eb366e9e879743836f5fe7a10a9ee29509755533200463e0fe3da6021d1d17acc16bd3c394fd2af2d1b003d0788c75d5d58fcde1874e056c19deefd97fa2c365274fdfcdeb885d2744088521b49d2b07cf1022422a0dda8ab13e27c2e041f371139f0b7c90f1b5dc03c80bd2d2d242c65e9b939e8cbe63e0f7255335c465094625e39c97ce615dc42cde15a2dd3b27b0d01683d32a729ea8cc398432f1a8a8e3cdea06fea93599eadf7b3c8a20378ae65dd0d7d5590a6a454d7c75906b173fd7cc85fbe9e43892802e6b150c840d0dc007434e3ba911a76c9d9f360048d0205204f946364cd0fe191dcba95a9ad4ae4f13c4d6742ac5bf09dd14be8f1b9606cab7dfa501750df4ae2bd39afa4a032d382a1e7bf2fbae57cc150455d74947910c303bbc9af95e3cd3424bb04f1b7e45ed54ecca0cbb59a651ed9f423b248f225f40cec3a5c24360dff350d7196c02828f41064af346f6f74118659ec057cd299b22ca9d9da04dffbf651055701a192e1f120bbb738e8aedc5af7e367fdf6014e20bae49319a3ba98577f57a333ce26c5711bbd69b08f90266dc7b870e892e7af11e26ce633247848006f398059647bf51e32985b13d1d6dd7da8eb6220bb64c2b49d128c95e06b271f633ced797f0698b6ed52ee7a8b15298c5344eecec4b51a425d40212e261cc2a00a90ba643da65a41f7350842edbc2cdb88d813eb583e34ae16ff60fb9a6ea2fdba34c646574542a2271ea9ea633e6b8bb5c0dd6b87f8b4fb4d144c79af12bd92468b219c7e7861bf56dad89d78eac2ebc78da5cbadb4650d3bc26cd18b43c884b42f5ee62264392afc47d9ee2bb375896947e80630435f4a65544a1520dbc71657d5461bcba30a4b89a6033409305", "ac5252510000", 1, -945032891, 1537743641, "cc6b5f5459a8116c05003215d256446d21a7314adab388367f0c01a9adbfb505"], + ["030000807082c403042d2e865bcee815db24dc3de5a11ead170b8f596e5a49c30cb6319d923da8d3e00000000009526a6aac63ac6553acffffffffcb4d7623d82306cebb5952b89e1599041ae8d659d9594c25f57ac0d5feb8c5e20100000008005152656363ac51d656dc19477c7b2a3eed9615e3c5f8a690eef3046fac803a7ed046083ee12aa074204e0d020000000851516a63536500ac8406fefa3afa7749d82369b416be987094c7cee9b4574b3026ef5021719530257d508201020000000153ffffffff016c7207040000000001ac000000003925a0c20178a4b60500000000000000000000000070005759b8b75fecce091714aa5226969ee3f7d0b9116fc250853c42643fc84601ed5acbeefd1e0d346605ebc8b6e9b482345a39d6f42861c853be0255b52eecbb59b6ca6e508ffe697935f4ca96c70eba8f9403b574608bb0bfd10ebe554e610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051db51357b034384109f4d268d9c12b96bc2d63d8d8c00d53bcaa41d44b04286dee5e648d6c8fc40d8c45400d6fec8bc412b30f04f467a3638c15d47e2e415dc31978684ad2b7f9ee516e95fe5d10c7eb6acffc1759f28b81e662e1633f3704fac8ec97dd79ccafcb6c12da716d19a8f05445e6ed11803083b5459d518648d3c031b6a98cacd3694d7fe80b2e96b749f621ef7e1ef61ba841ac5f676465120a4af0214ee9573c13a727143a3873d0063be0a7c1ec2b7b611bab601fb5044efd22e030b08e4679dbccd7ad03ca9c883054440cf36263b3105f40a76a1f98cebe3438b8d9a9557b84b5cb212c3417c648ef9c1e41c3ec208e1994917ce0e6d4b831f123b03077568bfdd566093261997e764a1aac7900290d52430eb028d5d90038867a30d03238f388302234dd8c1834214dc0155555532bb5d3bf3ef6692adf02b88e9bd23020f168ae403408a8ca5986dfdbddbec3e61d3ba2e0521304750ff18a7d586cf7d031062e68facb013ef1974bec903c3ab2a34404ce0b11ef64a69832a4c7de9de2a0326119c2e663d683c27d6e8575af049cba5769cf1365c86352ce01ddb5a8f65a5b3f36a940de0a207cd1e514c163b674d0b237168115daf749804be992278440ad8bf2fa1ba3de9f833875ddf34a9f33147bcae4afd71dfad4973516526e5b48a5fabb3ecebfa58e5fc29cf2987101ed064f3208b0e06fdfca8806192889740effb6f3e48813a5d58bb549e58471e86dd66aa8cfe7d0ec01d4f0cf145a8aa48e35e3776049dc116863ed6402ac0cdde16f2c3271d6964e696573234e76bfe5d6adec314fe6955f4af84e965e556f2a056be924b1504da0679ec800726fb1ff43aa72b2b6da3a11f081b5fc5baa396fcb890925aebbdbda11ee6ac99d4eda0b2207d59c47babf6486c9d2da6f0264760527d064de3842277a217228612d2c5a5d1ebe89d393afd8797c9caff1cfc968ffc77d6c6ae2c96f8a6712016c339d0b5c48092e5430fd3011ef38e2e79c11653b97e80db8ea471744eb941909b83cb2a3efaaa9e4105c9d3e7baa876a7a29a326ed600ce15c6f48fe2cbe38676d897f34f5e8b342e1d66a3c66e3dcdee7d68132b043643837000ac16ed357ce478524389a2a05eb82ea3604a1ab98d20d3444da78029f4628e76fe78425a3f791493bb9baaf8a9b5bc9ba1fc98b7a5cf9d50308f0b07f0d70260401f1a52c2f0dd450ead2c9b018bd44972232234e2ecce34068739d26244007a9d922fcc83bbe1cbb38098f8d2dde27aaa3b7a4ecc743321b6d5449ea00c7719ad837056f9d7026cb3ff425e28525d0a5fee678c1f43137e727d057f69d182965a00fff6965087e5ddbcb68121edfdf74ac7a1f9a73f6698b28366671e3ba6744946f727d76741a1990914bf7c897f8f08a73bc96a758cdf37fcf55973c2b6b0551e5bdeab6fd4b4dc4ed7dfd2f2e3d767fa7bd666335d3d6b91be3cd82525afdb755a956945b0970872f74f1fe8560d590127f24930af21263228ff09886c06e07b9196e8161577ed20b456e59b15d6bf7066dae10dfe328dc206c2f707b20e50234657d590818efaab68b8359543cb65ed0e6385b3ddef100b340adfef6d206eca112d6db7ae8a9dc2026ce5a27ba9d3c0b9da73de30ba8629a5eeecde1649ddba11c45c0b0e2c7cdf655e6525ddfa790b7bdeb353edfb200e623672c1fc4a5b2708f55d2bf10524848e898283da62984aae2e2875dfbf916dab0b729a5f63acee47f4d31c0b58ef888ee7ec102a20ba1ff14637dd9dc87d73ecf090fff68be91d3f14e99c790ae779f99376e3712d8e6c895d595cf45803ed5339c7e7c5b3f3bf6209045a3b6b5aed6f63749df50cef77452ac463a849b1fcc59dfb08d52ea53f74d6233076354070419bcfe52fdd65153147086ed1f02a0a23522736081d2ba610f6805a54aad895b7b554349e8e4998613257d37d14ee2b130d74f5704b1bfa57c7ba6ae262cc734605c19d1461789d136862bedd8b1ec029cc314c1552ea9f8d88ebf3544fbbd448dca54f71be3f1a3f0cfde5d797a764c227dc57be3ac4f4ee0b91703569592d80b99aa35c56c85bdf1562ebfb489af8ea22fec36484b2499c36f6ef7b937d4a4bd083889f54799d52c1db1a4e6079a72f42a70fe0e28554e0c0c1d86c8c052e66b00f5a1e8da59790e71b5fa38ced111c39618968032179680fd57fade9d6ee27c74ff2e2fc4daec32e36d251494ce0a2b49bf264f2421e8efd2eb7c61154cbf4697c2df8d60fbf1d6c9cfbc2273e80645d345d3fbc7442688b1eb059976e96b9fb6a9a4aba4882fc5c698df313a9732a268f4cc84bd1ed0f144ad9d73ead1faae2de14080a8b3ede769e91068bd9ecd0ad03888a9cf1f89485ec97471ea69fdef72d0aa1cd3384db9a8880d2369fade503", "6352516a", 1, -2078586765, 0, "2d67074df94fa9dfb7b9fb61855016694e88cc8c3274a13ca9e209a8dd0df65a"], + ["23df1d6f0233397426427ee6770aab05e88415373843370831b89bc6076c69c775e2b5ed0a030000000365636affffffff2154396ec0b1a1f48e2bcf462d0506434bbf57fe5fd29f66097204194f1dc0f1030000000851636a5251516a6affffffff042081e10000000000035251518df6d1040000000005ac53515200c67ee70100000000007a4e0d0200000000076a0065516a6a6a0000000000", "656a6a510000ac", 1, -56634375, 0, "4a75061d37186e6948669ff36c1139c0748968e18f8f052e43effa9db3dd60d7"], + ["030000807082c403021f356a7682fdd348156a1bc6f2bb26f9eb4d739f4534d429a76d60b35b592b67020000000400520065ffffffffe2350896b2b9d38e54ecb598d8cc14f575ce8b2ab4c203d4f509fd2ad73354520000000008655163006a535152ffffffff0499e527020000000006ac65516563638d9e1a04000000000900ac53630000536a515d2473000000000002acaccc19a20300000000036a63ac0000000000000000010000000000000000dc16e6020000000030e9392d363cb9a0d7f821de1ec97e86158ce6769682c66b7edcd623eef84780a5a1c200a385ca7eef4f38908b3de0de85a0d9f79dae35aa7d1ebd01f72e087a17065f68bb3c7a5b4ea12ce205b53fac235208ee25d01ac0bd33f2877d0f670e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b277666229a8fef0d8fecc1ccb8adf2900fb124ce5f91574b1ce6eb31b495381c106a2477ee7a844a9d03e82f9ff02797a6ad1164eabd872d89c0ec10f867c95d2c6dda707ef4956ab1a7099fd5a8e67b8a89c2aadaa4ddbb6f664025635634945d10711ca1b7b2d2812188a283d65b35a0d8e17e65fa6a7a031383b6611826f030415fe9682b15e65a040005dc19b689556c22d225b50c0eee5ba8c199c4d61ec032c30a6c6707e5120bc2d4a11d750f4635154f37ee234d1f26684e28093ad53d90b079cfa04ae476124a848734ca4f63908a6526e8f9145b3448e10c4ad0a3647fce13068de76a8bbabe19d1343fd3afe93e198b3c6aa8e3efc677a8ed0bb1f8cb5030d4ab52162b9b99f9ba8c16914fae6024d30020117db94da6d25ffd2466585c10226df1c9f9f646caae869325ccd23c2228bee968f2eda561e661a3a9c2d412624020bbac9f3a3f4223215ff11a312684ffadec8b4c96af04a3f7f9457f104e0f160022256aa890c4965eaf32cbc90f64379a2adda490e39cc0e7c02e644763cc337030317176cfa2a6c0f5c55587e89684572ac77e06e48163485e0a598076e845769a448fe537755aa7fb90bcb3ba6cedbc64e2a8fee5a925393545efc3c52ee915c0be76db97f81ec75a1ccf7ad77b3cc0180b4fb125bc328eaa44203e8c9f87427b05617ee85398266499d9b730f88ef2e637658c26e1395cb51ebf189186f7012db1be45b3c8aa604cb0100aafb40d2a68562673d273d4cded5b1b60329df4449bf4ad435c3c3352093151db38f8ea77fb328075b35bd8f096668323d02e2ccb97be36670c90766e008d5f13b3ee5d6984cff019acabdb28988ef1ade103f936eba9fad883a74f30fca5524d41328d39965ff60fc66e5ece1964a2ee723f306a6f3c32dd3f28829ed8715fc525798793848d0f8c1273e43b3b4d174de1b586488fd44f93b082a518f4a091d8754ac2ba3320e49a9de41df1bb4dca7f85e6d46f8b6b3826669027e5da61de832518273201716c560fae9a1bb5d80bae5d45d9653acd81d06a101ff48aa7425ad40d8faa4d92088064b6ca74ee2b3227dd9b72d2aae28133fde9a7a81deb30d83a696cc3f95882d957967c01a20129d29de3035b3bef5441198a95c0c9c37cca47e2e1f84a23fb07413427b8690f3660a6c5b0d7273758a9c2e0bc78c06bf68187d0ca7bcb14bfa77d762d3414e7a6241e7f2168d73729fead945294d28b4e6d052094a7c1c48238fc636460ccde49fb3e5a6c7a4a5d57d2c6ed0e55384b895f2b3353055bb3ed6528d5fc12b548c120527595fa2fb0e44046719e90dc30ca357719afef51e228eb36cd942c6c72f3d4c085736e71f029a4c84f41655a3b400b9919e847c286a22aa2b3fa1da542887cf716ac21f305211f643330e4ee094e81b72d7c8f52ba8480696d03f2ab5e6af4bb94e360856ba92d87111c39f2862206d9669d3878a94d33570602ec5242eba1ef33edf74f2559ab81dcb3d88c09aa46657a67dc569d67e69eae18eea5ea47eaaf7cf7fcd0a140ad658498aede06b1e4a1bec6ed73d67a7d9696723eac5624caa976f91307d3317b91f841862c13cba59686f53abf66a71ef50e4ee7829dc55f40bd7672c0ad5a48f5e63d4efadd6338c75855284f0566124ccf57ee1bc80598d6a9741db0d275c83018933d0beb6bf81ac63740ced37105d1d381318917c318f2a779073a7cf7b55ba1fbc96994a07a74ca89541fc06989c36d0523818fc4a727502b383f2f9784cf8cfd668b603ae2673aaebb1dcd5c2bee631068d9a0abc7b353a46581bf351e317fff8f461eccabe7836141fcbeafbb509cc4ba27975378507dac711684e3e0c6bcba998c4bcce31235075a79e4f8da29ccd3684ca22ae91f7303ee195fcbf8b330e3a94f33e34156d3b36ce752d784da24ecccf2dfe1d08d6564a100403db576e53c914b1a0f22fc923121d4963bf43803db17bdb9face99da614656752f21922d0518a0a2a62dab62d303b74b8eeb90a15b777881c76f058d649dfcae8b023f582756e6279ff19f5e8dbbe53e0704cf2f38b22e37ea89c87f17f9993e87d6e0ffb80a2bf0e3987a9b178d66928261ca2bad12cd1791fef73c73f447e908aa979451f5938f796aef2892a9d7eb70067f9b641e39929d195022a324a702203ed93d75cf34781f9a45be8cb71154242fef86dc048e50abd8f9826f557baf4435b3d53ca77b7214244595352a80622583d59c903442c76f748ab8323b4cde0a0afe7f39e7f36fe135f3990c2e63d24adb75be3964972efd8864317185e0e10f70aa73d168b59ffa6e937936a42922bff94acbcad5825a39ef33d071ff99ed5315dea6c2da4f7fd8a96113c719d0441383aedbbd860212086b75bb534d92bdb7b0169b405e2471c9de295a896f837fd0b", "0000ac", 0, 1778545437, 1537743641, "7c2a9193f3ee46881b4d669652dae4f9972808b23f75ea4c3f5e99cca3ba21c0"], + ["2f41e16f04d349f396e38a90a6e3fab44f4c9c2808c8c3443452df87dc88988e282fa29a7c00000000076a636a51510065ffffffff7127af2238487f2f4f34cda8f0944e25fd627396cb37c5d36eabf9f1db3461550000000003656a63869498654b1f8a54e280b57cb1bc5a39f2c3f9aae82d69e2d507fcc5ccfd3ec6b56c40940300000009636aac0000536552acffffffff791e5520f1f75d6af9da5e8176a5241552c951a25e9027f7c9a288ed7bb84a350000000006515251535251ffffffff04627f52040000000000e9fc43020000000004ac52636aad2d6f0100000000036a63acde486003000000000853656aac6351526a0000000000", "5253006a6aac6a", 3, -1452687354, 1537743641, "1f24265b13212a05c0dcb16592980f58af3752fc51dbcfbb0c7b0bce1a9ae556"], + ["030000807082c4030311ea826e4987bd7b049a8d68d482be5448ae90909b1772e425e5e5328eec4dcd0200000001acffffffff663ba66b1cd01e1b5a7cc46422ab0738fa00e9387c9dabb62fdb5672c803308c01000000030051ac32362479fa97019113d39641188781b29484a7354706fc2cb74e662a549dfe254002a4a30300000003516aacffffffff043b53e60000000000007fbad7040000000003515265e6a8760500000000025163ad268c04000000000263525b2bec51000000000100000000000000005c4e8f02000000005565d691e4ed4215ea983c23ad2690f5356c6f7f5dc1b7737f4d58f9875fbf9d4dc2d0cdd8128f67d0db0350f1790b5b8715c71d50309c309fa98666d71643f778b9ff6bb7df31d59fda221e6d8c213d9da731030d73a02ac175b4882e9337e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f9599beaa4372cacb119590b9f4f64979002bec8f4ab1443deebee41b9bffa787e36bb671c76098c45a392aaedc34940c2f642b78d1d2931b31fd163fb88f271993586f3c60a2fa104b46a06d1f0401751a3e7c39fd4742bef67649c6608e7109322b18825a156e68faca93eae97f2ee41b1024059a77b4ea616a41a5c2d90ba0223f2a19fb4426015a0afe14bec2576c891693847b3d0809272413c6c463707aa0225e20f5b1b94b0cd3f3e598e8bc087ee506958f3eef6a86ca2b5c6ae5ecbb1790b0723024a645a8c9fb57dde1291e124a79d609ea685db44443db740a83b9595f437f570dd8866c1335f15a0bd1fcadd8858f03cc1bc81ee3ce08961f2f7466016030644f99c73035060a1408aa7e8a2b7ba2fc040141e19206e2b01085e6cfd24000200c61cb46a4804d038fcb2bf0d7cd2d0b448a63065f7adc72d9f7e2b79687bec020f39ff3b1ea1cd96a38afba205e204346c0503cd4259d5f617ab4f4fdd004e76021157347223b7c311eb706867e421fe2ccf86f3d8ca7df91b7e1ce94f7807273402146c935749b01f1485e2f25c25619d64a5f1c8ad81ab06685271cb9ae0cb89abc8a9a189d15aad8690ac9d5c78613cf4debaaf8fc32bde24d7511279037cedc6f229148954a8add89cfaa9be1497d25a7375df5faafc6f3ad2c7bbed969cdc42c9738f196cf426185e972065213cc60f96ea07eb3c5383eaca0cef79d53c56dbe01cd7720d02e027d9fa983218342ed5a0dfff59fc8eb1e7ec83135e0f468be94ecc4c7860adf80cfbbba6b9dab97af2f0067e4f71427f80939eec2e593ab27d857cea9d8b19d34439bd17012cf7a5077ca0842affa677ea5078e65c93f6867d5cd04f230ba25c2c0dba4bba66f82943b3018e79cf7cc8b60fed109de3114f117efab693143a8495674f748512f3ed8d780c7af874c2dea908e0604dbfefc35a7636c653aa1467bb1f8e889873e3836a7f8edae0135fc33ed34ec4690281c0efd705a12c079805258c19a7b445a148998bb1141ce302f186a5141bb5dded404928c0d005862d9c61c09f9674287371bddc8737827b7509f395eed39484e3c4fe1cbbfc8311489395e817730dc28d7652255cb8c2135fb5029318b18a33e6ff8793da09dd1dbb7f3b54d40a4ad1c39abfd59aa8c68b3a51f82a549e384507cffbffb803271761796ee4a059b5c9ba037377a34ba80340305161cc53ed63895c96fae3f9d4be1b61b656e682aa219ce930c1d65ef74ab11902ec42517c197bb2b2ae9b9a8e61d09d6f9b64b5e329ae48fa58b771f74d5a3281c675921361a99f5f597e4e15e16a10c1e511fb8368273edfdc7c0468220b62d9c54267fd77d6279e417f7b345a01d9c6dbccac17f9ae4a7f44190d81e85fca12ceb3f5585c94db1247a90b3240d70aa3c9394133e9cc7134d5605c07b095aabaa17c8a502ff2fdf5c44fb8869d0f35fb36025f31d4598067804967c5a06524d5feb50c4c2d1d0d45839d111de2ef7c1496feeebe438f86e5f485306448895f3534a71c78f766d5828add91b3d5d7f5f219c1c71135d256c3d3c75fe0c970f818f9f6c8c482c312d5791d68465006a1cfe124468f214537ee3e0f4cb82d2044f98ad3a720b8a6b3c50de29906e2f83a41d3dc1dc03c561e6e05e1d924269cd9222ba2969d1a07435473732024282b3c5216ade05a61d1455f87059b373e6e3ae383bba5791bd1b8f0893ee1b13b185c692ace35c413c210a32ecf772d8ef04a09ed51376779baca3b100b25c7c30fd74f01e504212ac76e732b573353f735a2c0cbe4308072593843d47102ace16b22455641da07c03a77086ceb42955fd7a9da10c51403c821a51cba1c5eab515a976036384848899f1139e16f4439cb841528c8f962a19536ba35300d112cbfa4be1a36840ae8ab43b11745812e4464e8387d7c472a5b93d1e8cbc4fc3e749c9624d4b0ffed0300c414f6e285e3f54c2b5e49def77fbd92b9f8479bb1a1741ab5ab21670ccc58c01c0767fc9f785be60d79e4dbe7a9660e8c37209a5be6140171189b7a6f68f37c286801379fb3dafab62a2425f6e09718179546b180744b201ec8f7bbe279b2285c71922fe8864fae808c1bec51d07ec1dd2b8f648068f28daa9cb3696ce1d926ccbe29439087080d098b81b009ead62cb74cb7867465db5b4aa622da6fdf69c8cd72ddb62fb616840d56eaeb13af4b7fedbddad44893a08e559338758cb55609cb58e3f4588cf45d1f541d5d9a75fe6a63fbd2aaa9c844d7b40dca64c9c3d0824ce997f55c4ee7976e9834733c521991f9c8156327da6b3f7b36339ed65e41295aab16450dcff092a52b2b82a4cc85202f80167ad17cd5d680495daa4ace0009c79a4464675ee02371bb740c9255069c6b9354dce574b1b9ed9b3fcaf45d78e7e989b8d604", "65516a", 0, -1320400433, 1537743641, "0fe4805543af44e350a97c123508f01f2beacafd1ae77cf5a6bbd6fb99baf450"], + ["030000807082c4030282dbea71a979db913648e5c4f57a0040f2b5d22f9dd5ae6fec6f141598f74b9e02000000056aac536551ffffffffd6fd840356da78245c32e332a7148777c04668ccdff3d622c388f81642474b170000000003515351ffffffff015aa656010000000007655265536351acffa529a60f75e9c70200000000000000004bd52e00000000001ff56371344c1daadf1ae1bfcaa01f14130f4b0f0df72fd3eef89973103e16fab4223e82dc528c23e8795715d9be128553fe6cb3b89f2905a271f2e1398cfcbcde0247cf2c1305a3f6a30ab4c9d090af4b8c4f3310b45b4bdeb0d1bba2247a0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb8292885276a5a84cf8c3917fe38e8b188de808c015f66260aa5fe3a6639e3b1377b17320ba6c6b2445154f9d99c857c1434a3eb8ee2a29d48e0b99c4daa91a1723fae4ca064f7bafb651e45011774aef2a96b888b0b39f18c8b3a26418d0dd4b37d65a43132689f75bf14e22732a028d51b0b53af0f2a604cc52675cfbd8590313a8a37f32ece894dea82c943b73cee6952c8869266c39457d53d67fd3c702c2022c5e54d6a5decea24f8092b6d034169a66ea34fdeaebc5c5b5dacfad21ff07210b0815f6e09ceb376b3285f7f83b6801b3974d173d9324e21ec55aa093a25b0994793786282bc2817d98a026493647b702834525b08799e94e9e77237e559d43710220b507600aeae4bb5e6b3ba1aa24e070b5df902586bc238be4c44b2bc9ec1098031600d8e4ca90f5249b3adfef1ce3b159f4f13e901372a347817f0f627fe4f41a0203f79a0f91c9a314876a4a8d95435111b773f557e477d5754ebf8184e31233fa0307b2a585b2c1c81051eb851522c9061ceb7de60facfebcf9be5cdf318fe36d7b0324509dfc16e351441e44bba9ab0337c7a7941c959f29a12550d0a6fd7b213b616a80aa905b460e644707e8ab715d25845490e0d68ae335e49321a5689261e29508852ea3bec1cbb799433c223549dcc96a9d3b9cdf40d202b7677080c747836519c2b4fcb3c03a71eb28a288f31b6902545e7378443cc30dbc3793f1aea526282896c38679e1378f68018e5a678cad408541fe16d4a8d35b56adfd16a1bc48943345a609f65a6393e0de5b8e21c46c53e96418474c3b65a8e30f2b040e9c852aae4643b5118ec7efddcf3d2d1c601240f3677216034a2639178494e2be9f8c043bafccd359c7f7ea1c2a28dafcce3bac8596a5e57504dbb6b015743ef929ca2c00ffd114113b9119d49774da3e0be28408f81b13dd702cae194aa93831980bb45255e7160fb88bab2220b4f9f72d9558405724028b70b3770f602c138fadda7c9bd3ab0e10aa14a4913f71987ae323a8752ccc034fab6d4a43d9dd290c10135dd1e1b492c38895b2e64cb760b34db55db99b5416faf35250cf0bc3c1e65046a326abf3018259b039c9bf47c09e01caedade63d6e0e6915dd5c9270a240e7f8a660c01906152540c12d14afe996f26fa5bf965a0f0c18f140d6c33cdcf71c9e227e673b805abbcd820a65c06892198cecfa8e495cf531ae216f039721660e8a7894e8b41c556f8a38f27a8644689259eb1b21449f846ddef648f76416ff1b440afab67eb21c07a25949d084cad2fab7e974ff8f1f47e1aac9b895ce4617b6e4025185c7bd09b8d0266052716933a19797ae1075992d8721c621f8b3418f1fcdef368d64951511fe5abcbe99663de750a9777fff7704573058baa3467e40c4dac528e2a9640dc6f303df44a83bcc129f20fee588d5db3f95e061559c7ac1854cd387f6ff68fd6525f4bffb1aee0f66207c1b0a4205b19b2d5aa7534c2707d6d9c16ddff9d4a859784d0b39c5dae41ec84018eb4e39872449f5ec9dd7229c5b57ab0e60d37b5e1a660757f8f1f8baa859c8e90384e45638d0a49c32507780245120a83caabc457cdf24bb8e2aa9bb2550aafb5d1ad589143e829145ee40301f7828ec0790f3cd885d8a1a968dc78bd48fb40014e0738debfd77089a5d82312a8deddb029ce11a24de737b49c150ca32098497d55454784f6be2815b069976011d5ba96194617ab5fba6bb1cb973f2576d94f7f0194e1d730fd94e5dbb14b6352e61b5af70b48637f5ca64612c25c65502dfa1202b45c3007e4900aee6f6adf1312d84334f549753817e4870909903f19f159dfe67200acabf8f46ed8a235249c5711ca53e9e0eb4562f9ba783578ab365e654f6b165818dcb03268748f4f3c0dd8f1abecc3c7edb92f5e7d1b9f4789e85de92305f4b319219fa60701a5c157a4b865f224ad6a297974a8129bb4bf1e886e600be1d731024b6b352b6bfdba843c22e199274638d2cf939f47c9455b529f8a9a60e8688fae2ed6ad2462d0312be6b754807669b66a1d32d485b62be3d7957f5c28d154fddc76b144ea9fb3b746325bcf9eaed64fdf91a6be19b91f3492768eb510002e26506ae050a57faa4c2de8e141fecf3cbc8b96215637df61aec65e7ed9f67ea8aa1b3137ee9e065a6c3172b601991905b9f806de452490707aa344a35c8419104fbe057a6087fd509d8999e88c4ddd4e721f1243bae1663f2d568e83139775707bae9036236f8b5fe2a0f2bb3be1b76ec4ffe36632af782ef3090de3aa7fc9fef3d0100000000000000000000000090dab05adb2255f63125f4f6f582814fe2a821d6b4292749fcebf0cc7837a18dfd02d153884d9a267fe1365d58d9a9ec2b554be2e3cf4b5d053fa30fd0b1e2e463c978f783d57ce4c1cf168ae7124b4bb35eb3f155b687c06eb45abfcc17593d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037b20df5d1c4c8560e8d9c1110fd41c02bdaab5a8bc5b407d729f44eec3caa1e36fa2f77e4bef258c910461f3acdcd63f0daf361022d5c515cc2fcef8c7c893c877977ba498e8150c2e3a1972fd5a18854b393bf9bef6e01126b9a3422e86004ea90e0dd029a16e3202d2b1d466c04e1ce8c539c0d7d53df0d43203c4798b28b0315eaa530c3f9acf7da39c8142c6ba9a5fbd0cfb6534edf902e7bf235e806828f0304689c86cee65ea4d0258857ae7c6a4f5d9b98f16412b3699cdae6c132382f100a047b0592660e925501fec1a3a4ffbe9435ccd8d70fc434de470b756c89b713d62847dc5ccf79f14bc3f919bc074ef5a8be0e04989309f6a2e198458d4cd848f70218ef44d69e65d82ef931b51e74438c4b1f068a72320fe022174757f8fbd370610302056a7f4ee0bcd2193b8c73c844ca0be1151bac7c8ce556c70058b9a273d8a103078f1cfb6d861025789458eb1908ef318da7b8da578eb6062fd3571ef828b7880223ccbc61e527449a0950f30dbc61c4383e2a8726bef15f9c6a694491e459fb29021745ab975541f5824e6f0c15458d35d9403cbbe761d42fae8caff4ba00543f7e807fff10174477eecf6c4f95ff3ba42eaf11a852af7cff1be65a879a0f688d32981b2fee59dacf60480b5b72f9b6b3b9525b6e2b47a162391d96270ba1ac3bf9cc8019c62991fffe4d4b4e720cb3f2caeccecc77dc37e136c02326f1516f33727414a9df76c130153a61e909b2280c12d60d1eb7e2b3cccfb1615c04a312fac98476e7f9119c036475f67c6902d3611d9c00c92fadffd921b90cb67d3a12c49f977156b5e6288d112531a6274df92657664f87b9cc81f037f6ed0b0e6e5d128b4d6f0e355cea1d6fc01d73437c04e072ad6af4f7834081ab8688fadc9bd8ed058a08b53578f4f91205960c4b6f677f140b1ea7642c334422d19bdc1e5a689bc33f1b9e16ec6a6a4099d08e2190e7c0c0a6a1dc1203be462d1ba61f8af960483b6d840abeb33c0660dffb7f50185a1f6c7b7ebd9c3241cc906b1c57801f56c6856f12e3abb77a641f5a91849f2f700a8e22117cdcf62c4f51ee5a2aaeadf04f18bd60b7e4ead8e5a8cf5df4f602cd81920551faf616e9b84700e3d1ef9df16db3e05476b79613d6cc319fb720984190dac96fc50354a49b8c6f358bf70cb41195c6792657bda69505059c6e8b60085576fdd8879c119cdf41d9853d5fc3e8b83eaea5cfb2d339119286fdb41acfa3f9b134bb24bd2acff769fd1968ec104f6db9e908d727ed2d27118fb1fbbd69a905d0123481a9a8789973b9fa94bd0eb8a8e521e173025d37eed002f279d1a15cf6c9b461fc8befc45ab8752ddd910d2ff3ec6eaa5c54a4a832487901da9c8be2ecb3868dce6eff3bbd938dd2616c28abd010fd5f4e4bf6119f7cfe5d6faa8264c07addca7260a9538cb17c04704a45d7e2f73879ae8d1097e7fe4f9b8a839f460df3f9d4d638213bfe1caa9748d1a562484ca6b03f69573c2baf6ad46bd9a1c1076f416dbf466cf07c6bbcd4588a6a8cabbbd2337bc372e19be29bf46d53731a8ad2ce021c7b794d007290fe630cbd09e30a5a4c683ad2210ec9e3c590b847db37ef922f0b388aa0ed913063c59818401a91c5d3fea4deba9d0151ad7644ded438220a3283ceec17c7b69839615d9ca20142bbe590278817a9dbc64f4f25ea0a56ecc680f3b03ba4fbd3d3c4f78a4619757529358b2c67e9bb06068f73300eb46310ae10662adaf02acd020b7178d25e0d4938a2e2cf6f3980f93d0d252381663dd79f8ca95077b0630d5c2c89ba86b47ba2d45c509f9d92dca00084d25b175263ad667fe5ce20164e5ffa6dad22847bf647f5fd1d30b0e97b7929218be0fdf3d573537a8e745b8ffc4ace81b14657c345ad9f8fe95215090b8e2287b12d78e72b7dad87dc3080e8ce5ca5bffed0b7f5152f6ce4be4e7cfc6b60ef742f7093c967ac1eb39eaea6c433059ca351df8e8fd64096c3fa7b42f1e7cb1d2d0baaac604d61d1dc2da951b0e54c02dc2800308ee76654d358a793f72dfd16da70128972ac28ee412db998a6827da7835b9cd9b3035098d06de337a5eecedd69bf0d536791dbe870f221c669980321adbe5bcdda97051078c613791baa4b92123b01e7246bbad9fab28f7bcae531539b22c3bb30f68c973803dc66c50b447ca9c70ac7bb8b3335444620f91e54a0d4d78104596b5059490b7d411b306f1ae983326f47d3eaa499c1e74d983862130981e916dbe0ede4e5ddf783009480ef9846b44c75a8ee5b928ddba971ef5dbb9ce54496519560153d4b7ef9c8de04adc4749c741ee214c331a7a5cd789985201a9c4f65aab6e5535383fbc387b4aa33158891809aad2de11c3f7bdd7e158d4ce3f14349b3fbd1076cf3021b40708fd866b12722be4f9e042e06", "6a6500", 0, 858850649, 0, "9b3e90db2ed7769dc90392e024d9a741cd7782c3fab0f6ce9e54b78663b2e722"], + ["9269560803b39df2ab9d275584e4d6f2b7c5ba977c59c9ce37893baf44f2ebfa92a4066ff70300000000ffffffff2ba1a49f7d815efbb66e152e43e7c56e297220821277da7da23e902f15a3656f000000000152102cefe7b63d0919c18035fb284f59c9ceebf8426420f76b35f9c974fce095b7c088444d0200000003650051ffffffff04e7bc460000000000076551655352ac5273b0590300000000010070d6b002000000000153b6b9ad020000000009656a6a536351006a657c86cdaf030000000000000000b4ba35040000000088c4cdb60ccd69d540db24b3bf551f1768e8ebb41b038ef89466b3e93a64b93f1f1b11b4ebbc885bb9834f743164f0e72c4f690495d7c01483e38bfc3b4d716629f84eba528d965ba0a4a4455bf18daf38e9f7c561a04e29bf8bfefe843e34a60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074fb68d6afc4aa9d46a40a54937555a94831ba729795849511b4d6fadac84fbaeac2ec60b29784cfdbdac27d9d81c18c769c8c4fce1cb151d38afbf5608a1d916e736d2e9005f874df0c5cf84867ff594295852e7bb4a82630c44c2855f60aa2840a2c9aae0773ecc8b4e0b718b4a4ae51fe82fc6281725f6823702888ff4c3e020b4659b8bb03d52979329f4f0506c916eccd507c3a3c80c7b035e6f5731092eb020e0db9bb6eb78a015b78645c13daa7e65a464b7addbb53b08c04b398348c4faf0a076d45e096df5662e55998f7fb83d1bbea81fb27a9d763678c62205609c3f8704cdd1a992e97f6c3e7163b5311e2600fb8d0b0636bc5d95ef68ddcefcb6b591c032df8d5a4307cf699e67fe1b0edc2d78d6ecaf8ab6d55b0c8423b0ee3ced85d1e0216bbb533cc1146e8083be32a589fa13928e7df7f4b8ddba50962bacbf368dc2a02025e63a0fe5a332f2a5c2d9047d4b348a884d2bf77d40e724a3fed6d1a61e366030f1e01964f1818096ea3da46fa9d416d33d6100ab638c1bf0504581231a87235020aafcada081a8d809b4be39344179a9733939a06bd03d5a0916a86df028ca1c0c02a62aabbf7731b95a135f41bf866edad43eb8644230ba5cc321ea2545aacfafb95b8f322ccdcf724ff691c12fbbb3b42895d72cd606c27c8f0dee112d52558ee7138119fe2a7a3b447998fbe3474ec4e92039e7f3b9e1890bb92b744f11d0c423d04e0069986ed10eda54ac5798a1208090cf0e02580a85d7549382da1263d689bafa08e3e16cb13f93229b437b4a9fe956c39fe927d2ddd8ed67a21687d9e728e2992d446c2fc415b0f46d1210309b5d8aeffa4193a854bcc52ce20abfff4cd919fbf1222215c8c4498e3d0d660b3bd95f921ea00811701e72fbf358ba540eb3dde21b36c39554bf9494c8fc250243053ed9adecc868371215fa4c9fed0113160d56baaf923ee99ae8f446ef01441fa0d3f0957c6e79087b728434ebb0b9381f4551d701042593966d236034190d0295223edac52773aa55543066dc66a323254f32d336f96f23e6e031a25e381187fd733e9cf62ab63177f536fca579d8eaf56d42475f4bd64f860c0c5c5429454529899dec3a8fff54450155d60b7cee4c2ca48bcf8b357ec344199b3733041ce06eb94dd0fc6daac041ad3d37062f4e873387af12b3989a4a578adcfde108278033fc58c1c702761dc246ca8ecb0135cd0dc81bda0f2c280ed03236402d5dcb02ccc671995b1777d2cb0e9a109ec3fa781c58ef59290c93932c1959985615fd8c23ad0e2960270ad8a15e9cc98e9f2df38902398259dc8fb83f7d699f9ea2711239fcd49966714a48757270c32829bd51b458e123bd0d0cc791880be6f26eb5e4ba266e8e13b86bb366ae7a4b147e16a2d7214e4a698502d447a8ad0c6afe357dab455ebc829e0ee1d9407f2248ffc07b30ace6f951f886f6df6165ae7ad99a56c2801dd07cdeb57586f2d9a3bd367550bbc99e55031f7051d330a7d59eef94ee110b537e54d01411d102b0145d496a6102ab4f7dddd490c352214b2632e1718b7be2ca04d7df1374d4252cacdbedd5dbebf0eb8a12da58a87b9210efce97589e33f0b104796548c2782b6660746a7bd62192261bb80a33127fecb6aa329a1dac48f808fc9e77fb23059091e6d8c6fee13079223df97d758218865bfae263b5a2d0e22a6de5deb2c3b2b27de2b8774ec461cf93cbecca575148c3a109ae66eb447307dc1631a9c4b1ef7d2667a1dd97da9297e54a8ab19afb30c5d9527bfe2f4a0cc8e9bcd4e42c8efac4983434271f43127e71aa01fd7d69a9fe318865899ec6b3bf76f07646279ce97955a77603ef51c8ebd3d226680b3d8263de07a3230fcc595a749919c75b55dc2979e0c6e9353ccbaa265501a1aae1843c1b3af650dce06012bf2fa488e731cae92d2c7e04ea3a1d9c37070fb190a5994aba5d4a5e4ac87e6af584f175b345f6da543e004ed9ea751cdacb30b72fed69f108c0c0642e20bfb9d37039532ddbcac7927200cc42d2288880f598530098c591bf505488e5126425dfe96b3f8e4b6da7219c88170b448a1a0ad9bb57c6189845a78ae47114661e29e1337cf7849de8b6c51c8b051820b9669ff3165e5b5d6be10b99fd7a83fa6c65ae58d781ad6beb0bb1380b78ed6d786a05a1a0ac90d08e36190fe49d78e0d405edac46520f1b91f34e26ec532bc54b14dbf617ec9cd41540a58f7ef4a0f657c96b6c8b824f545483fa24140a6038cf7c896101a000337cfa7cb9a3e20bf6a91000000000000000074dee203000000000200422ae3ecce9501b50c039a1abbeab60379a22e4dd432227ebce51e9e7cc0dd1c884befe3b3164867e87d4af9da030722c2fcad9d8447ee2f72b021f0a3df5906db2ba7e901a7a947b9fa1fee650c1257dfc661803ea95d42684e2665c78e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059b25524ff53521347451283e5acf3594759043d61249bc8b65e72b81ab5cc9557423410203045afbe7c102b86e754d74a11d5901b2cfd8d11e307b1edc9c33e9e21bbc1eafc4000f3409af0c02c8d59cf1245c757cf5f80f21b56f222b3bb41cc865b8544451ac795fd8b9384aaa40b9c0b9f38f0056f888667e837064d40f8022df706d62f0d524f787186840b111d0d583cdd6f49a5df83dd90a4847b707da8032e924f7b7bb96f8f58692d9471ceca66edd9f8bf4bffa3fee834924e7721f6450a03dcaad3e87da338612015a70585c4cb1985f089ba8231d0f1b264054391757c9ca93fea97ef5b5888fb4376ded11f88f35110cb06d60fc662ad4e6050679a90022f3e7c0011e008897a4108c13a520998e2f38c9bb937545f59c484b9840aa99a022c98f5ebfde7e1b9fd2f8bc766131ff91e41cf49060096bf026e6e09be00220b02157132700385da7148f8f097da54882e21b8c3143603f5994f51c27068e4d5a3020254cd4c7e8e35a3f258cecfdbd8efb9f2d7fa76a8683f8d1cdfb9420d036958032f4388ce73b16c9d3eacb5be566d3da97159e565aff5d40a7d28880601a44e1a2511dfcee44365a9b10cc7eaaf7e07b50b0633afea83af65dfd0f1b9b47a816f80e21ad03384a556947fb8b436877908671b80dcf9ed637cab436be5188de3d1f63fde362c5b3f1e05546552420a0a210550390abeaf5fbf7a927a56d61a24db3366d4785335ad94842cf997c748367e4699633948df77e26a1459dbb1653f30a53b8f8c386aec5d1d75c85c46570da6c3dd4a0d21f57d2b58b274865f12c90688a749357a66df112a1b745749118b2b89ae6083db14012d69a770b11401a5477d9a4a7f9d8ba7b64276f016a2b1ba744b67270eaeaefcafa820a8c786221a4f652a449a3078d7f390a09c9f8bec86ed8ceb9ca5706568e5bee1eeb38bb99371490bd6fbecd787df1cd444c97f13511911238cfdae196c51987e5334c1310ad97ddf174fea7fffc8e6f87daa3887d6dbd0d65a5afcf95c96afa09fe482cd4eb8d5fe320e9c577d8a82762d6fb21b907e245193b3d36fcad5414c7489b84851f49680bae0066770cebf7ce35f77081691c25fbbb908c59aec1d0d60ea821a284a2eeac5999d62192cefce736c9f548e05a5eea52d9457ef8c740d5291cc2b6703bce611d1d1ce6a8897ac0172a669514f4540fdb15167b61a9fc694a3f705190713024c0df36b429bb38f4c3e255c39a812f764c47de9d0e1c324e65367d661ef421ecfca2752147eddee90593c476c2606ffd60762857bf168d44241a1320ec480b24ac2e35e54d9e44fa3d6a62e4c50a9e7698fef41d27de57fcc589dbcbc1e93b40e1b1bc4739e6bcc1afb120548b21dada33fa677d5057404be4250cda453428b0c465facf8bcf550c0ee4375879b10360af85e72c07affa66128c330d22c3144b1aad193a7b504fe4cd4fdc1f618d3f362c83ffc26de957035fafd4765af764ac2228a783930ed874b16e6f10b5440b0879113405194993ec5190389c52e4654860793ad61b99826aa3ca4f8be99fbe3f7092e5a82f2889fb3af6be386be216915c20fb02603b0c2c403cb56f0a1299b6b92ffc7837d721d69d76ead2086097abe55c109a464f9be9f7e0b6f836b037cbe5e79ad31ac37645bc8ed957dc6aad37b98bc85d7c69a45e1a4519a04090bf4b577c404fcb3e5ebdea8f975047b71e52dab0be54dae304fb09a32a4355591b3714f6439bff7be211d1e5382331f26a5c2ddcb6aac4b26a926d4113da587d31db01422637277172e69184b48d1f898438446ed2c66af54bd54b42dd0c55978519628be2991fb1cf10a6871664c87e9dd522e0ec72eb96e0f80daa1ac507eeca6bd8e399ab44d3972b7b0ba437b3a62fd93b9bb252ccdadaf1babfffe506002d53cfec2e30b6a88d012d1631b7fedfca92a425d465c90f6124d6090729d2d6cc23f8c134293727acea1b7bb4f5194c9ad18df48eff9577c8fab751d3d56525cd09a1eb32d24de047ae3186207307ba2aab8813698c6f09b8e2b026fee55019113ad5fbad54189fcff1126e0d9e051a5ce14fbd5205117c09a28cadd39654c0ca94a6b5eeab6629040e91ebf7f4e248ab17885de9180f495cb58256e594c668818020212128ab130a07c3926d5900155de44480f485d08452da14746ba30e47bc0ad4873a8d232e306178261a2e9780a362c2d060f6ccdca03efc6feeacc709bb66a8d53405fb241a83c2bcdc7ad7e35e47cf1ccbae2e3aa1a028dbef03590dcb9000000000000000082fb5805000000001e612bb8774d2583d3db6dda6372db030596609346227211848141ad680be829f2ee3d6878e8e6d104b119f59a3c3d010d3c2b7de0fb87338b28af8ef3abed531c4405e7521d45e7ed1fbd1a6e57bb86f877f83b3fd2f31aeeba203f45ea7251000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f8a79bc3392acb19cb48b9c5a5ff85c7044f5c5d293225860c6ba9524a6dcc2de4b87ca2bb445755932754e168cf8031078c09ac634d1b7a2f8b0f63fa8c734e69aa5225e4421495d7e0c860b4bac8e8a80a2d028d419861479d8dc8ac78f43b4bd63532a93e29e0c1b6eaa9beb2294a42691fd001ef6e55e04fa00ef4d6e14032cf012ad39ff8b716aad7fcfaf8469fddd77745cdc80de8755af4ee2bdb82c49020026e2f63348a552b2503309856a69629ffde823f177039ba0a8f808773cf6620b02dfe911b900d90c0a2530caeb91ef50ba8f05274536536b3f52f29a73bfee87a5288460c99ce8c13d2b4970e8ca06d838c8e287a913d4bba388e0a4e4a06b52022259b3b21091c8a07a3ac69c247a79b2c063790764ff741e22cc8f1143546777020486b9eb41d100f45664d1ef0a7ed578e4a0ac694f47f9617a433f5b858406770228ac20fbf9e5ebecfe464e2706e93f33d097f1797706bd37e68a7f3abbf53003021d22324dc966de902f6fce2feb1481f0ad6885365d57ba4c2d8f5c3cec5395530219de8dc70542ea9d386076cffc6212616bd1569c525ace0ecbc1b247e197dd05f42f9171744a994957795874d5224bf2d59cfe440d1d527ac879f49c782d2810be8f9f301390f74811e384658019f717efbaffdedaac40a7e17a04fe8a0fd15fa11d30e3e0d81cd7122c397e309436fb9882f8b9963086bf8c2b1aacb95f4656c383128c2c6237d6d3c10d589c971f3634e5f539983454c4fdeee389041f703e05cb01a721fd354b536144f13731b3ca1d0b94534e9b620da5624762a98a414db8bd5fd4044f98a44908782ccf1b7f69c8c4fcb864c128ca52f489bd5a0bcc1cd20652052b365f9006a6ce2eda0f00ae420e8902aa91bff3bb6bc765d40f728fc8e9074f74db0e4747f52f4179181f0ef2f9130c40dc02663ab68858edc9992806f50bda0ddbd95b319eca64bc0fe36f77ae5de0a19c625061c39b2c964d1d3a221c8055de3a002718a2208f963029c0d5f12f763e3655ca6297cd46a793e64eebc6b808f34e7e4b6d89a445d4921f6a2821906464a08feb4510149c5455dbd32714ed8428a21c528a6f05bffcdd4795a5001edfcfb275ecb2ecdd08bce7a6cc5bde5dd9798543f84b9094cb0187392da005e80f5fe96438e1dd2f5a01daef1afaccefd93f1f16545726dadd640c73bee7d089b7f26d242526ebe831f43080c1c08b1d2b4163aa0af89c51a3d54ef5cde085ccc9ea2543b60112b0aef035def13252b8c5708218c6a26103b1c7b24b7835b37ef95c7b2fe159c03b60b5f2246fa561938d2e9c8f3e7c7e613a7aec2531003a42af500943caca1e74025473bb8a6237f020346b1f8892eba22c3e910182bd5accf7cf03a280aee45afae18ab7dfb18c518ff3532ee57a90c220b536fdf22a6a46488c7396911478faae5d2d2221224e3ddcf0af8db7a44d2bd49ee3269aa8c54b589b989e0a40c7eed2cf91f2ad8e6e6444ec65f34719ba6d16d5609e2faa55e2ed91ad06718913ff7b2dae336d6eca6ebbe9b84d5eb89c16d4432430db4e0b7422323867d2d7f3f395a7bb1cc17f9e4cb7507a8cec7ea22426cbe2d3faacaca80cdb46b9ba06b3808288515e349a780f44382ec9adeb0f26961751f2fbd1f596a2b27628a8f5a461bef8325faba6be0d158a5b694bfac66088b883b8a8f12e461270fb28b41bf7d1159e89dfa6eb1751ee3888059a2fb418a83220a61e5d6afe8d2149d72666e79b26d30e7354eaa0e06ab4d96d2887d3f55b7ef9e106aa43be2917d4f35b144ef9b1b4590f6a50a33055dd94fa6d640c0f8e534c4c071d73f56c06f8d3553ded891f15907d81672b4eadb3b3b3e779b914cfbe5ca3b61dfcea3d68dc1ee63b8c0a8f43e95d1ad6c4b4005d97cbb115b7efeee426466911afc24d6eddc2f4cd7d9e2d59dc133cc1db325da9e24ac69c7e8bf23cd6c0dffb03c79f0b3109a37db63f546e14f71155ec307b3614b7cf1a6064fcc032d40f188e5a6ba04c13a2763de60bc832502edb31a570d9eefbeea72a35f9da6b0297a8152db59a75efd0ca77f5b4744a66dbf82cbbb07c846c9cdb6add2089c6f9fc28235ea06105913e5af202102d24080cb199281cf5af66f0a1703c21fb652f409d32c269fefde1d06f1e50571483527baab5efb0e1ea7d2c0cca89a62b195cf7f738c0c46b7e2624c932bb9ebe457961962953bcddbde31296c5e4951a2c7df1dcf7feb31a76ee552fbd5e419c9512760f6deaec52c4ed8ad03cf95800d28c6c8ae7c9b2ec4a6047b07552a4454a8a429f6e5900cd2665d1f6a7998b261d322684db4fb7441945047e91a7db3848a290f877e2004caca7a6377506f3b4a4c5e03e54a2af295e9b90b902989e9b28c31431906bcf69c246ad7d44225b246b6596b20d", "ac516553", 1, -889140828, 0, "739b1a2f48bf6af7acdd28d053264824e3aa103b6bd9ee11dd16c30edcd4872b"], + ["5a97da1103c5a3c812b6cd566f057b1f291484400585889a185021728647be1f33ffa6e0bb020000000863510051ac536563ffffffffc626b10c1d9d3ac62e9fdf0faf51bb81037435d471ed8cac0420c6bddea2b6aa02000000056a5300636affffffffb15faff89307674d8fedb61272a0a48bc3607451ad4243687ee9ce152b994d7a0000000007515251ac53536a488817290499d054000000000001632b66470000000000065200535351532610a904000000000700636351630063f52e3c030000000002535236cb7aaa02584184050000000000000000000000009e72daf6f79cfcd56d62b2b7316ec513b5cd069fcba49d8b47cd422d143c1164b29462e0f735dca46fe5764bbc9e94f45e3291244c79b06d38209fc79c2cc98986098e62b68ded6a4062a0458f0d7e94ff17b3c4560377583fc2353d7c65d7fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097bf40ae43d683cc11113de21413fc344c4a97c43560043a1d270109c3f6d7e77674538174892b34a4f0a8e698065db5b2b4f5b7ac55dd5b0c3e610a8769987f231f3b71a131e187f848ab979f2b5532ae6790fbcc0b0392affe3f0fea7f0c523356f273b3da8f8a7d72db363149ec3419b4bcba26dfcecd865fb9c3ff1aa442031b97208fac96e66d47b5a967201f2fd849638d45165219642311cec0b6d12ee6031246da09277d5f7745d80dfcd876ae765fa746ac1eecb81d96367ef84495ba410b0298b9ba31e56df3598b84123fabc78089da3ded56272cb5023aed675521810a7cf8fb82eaa163db91b587017956ba0e08e034e56b999add129256f7d26d20d6032ed15ca89badb626da4524a59d4bb2ed3f9f51b150458cd7f0762d22503aa066030e07d3360b82d58b7b458fada8aa1a8c8e9172bbec57d743c4c2e2e684fe507e0319ff2f365b03738e429a1242f03252f33a05951e55acf291f2cf0f2d8fdaf43903225eb63a5dca7f4d8a7794b2c4fab35017db2b5fa4368f40524b09f14fed12320228ca6acd830abbba113444e188d03cdc3ca4e93c4110e10582e0247351155ead368cd8055238b0f4e129a70a0d46bf9a4cbe539a6528665724c5f1f0a10925d289d848c2746d553b214eb085e23863cbd5af4ec28f1e3c746b59d3ca89ff1dcd837a9d9b4962fef5a514008fc98f70778c63a8a1fe0d04b9cd834aab4f5427a6c7225d2e93fedef8a102ea78ae61bb44d4bd9e4950155d7bd8688980ee8cacf1dd3ed00bb2a0ea507bcbe8bf8f5d25a8977def47b3aa467f132171dcfae8c5df8f9cd3447a3feac6253fff5a541f3cbad7a96a8e33231deb4e8dd345edfc3d0947315d77a611b5eb3e3719e1103e8859c2c1927982f41a05a0c250aed7381f2441c9e2a62574d30d14cee930275c5ed8f62fd1aa69512ac36ef701762835e356e33af4cd3b60eaa636e7cab2e8d1ef23c0b52afb7b972b33a2f8a468a079a9f758bab7b76750910a7e3449d0e0fafe7d10483c6773c76811a1ab313ef6eb85fc0fc47adb68d7bceef19871518c2184d554146733d45ccd677b5bfcf2d5ed6c9d72fed77c4f8b0ee66eb964284e86f4850b6a142b193e7dedca22a380375299abb8f0634cd7762096cf4af4cf5dec0f2714c2d6860f8b8d57716c8007be9b3c688020918c6c014fabbbfd275c58e6f6e9b851cd8700195d85098c9336956397e3e7ee9b1e0fdb097c7d3a574413a3df2510869c848f03fcda9ece0dd2f7b925d3f0630ea01c44012eccda3cae3e997ffa82eb2c51dac26afb4c432a20f12b25caca1e94464a8b0973453b34e4f3ba9025ca01a0c4ee11a4a6d8dd4b465416c7b1153c2d16abcdd2efe4b1f5dda687226b19b7ca6902b5eea9f3cdac68e8681657a734a0dc0fc788772fe60e6d4be9e877dd8fa057c70bfce80948f43d8db6b09331180cd550c29c7e0cd947f6c40d6073e57d7f2c5d057a38d35b8d8810fe1115459d6a416b4d06fba4da3fe6ed20da27976f858386c8bd42b938352a17bd269a3648a391556105447d117172bbb0972fcd034ece421465498563199c10521f297aabd1a2b174e280c4b65daaff784f5932e55276abfd6f2cc8f05ed3d63113f41577492b79844ecaa36c12caeb89580b2bfed0447f4d5e24f986199af350017a4ccf9b4d8b7f1cdc591669dc52af10bdfe7e168c0dee6bc0e1cb5ca746a1175edc49e2cd0e2aaee22d9541326d6568c7526f90735e20df36ca6009b4dbce63dfb71b71918072bb905532068d2787f1654f8496dbe2a97c070ec86a2f201601350cabe5dadcafb61dac10be80d3bcfadbf7fbee84117fed9bf0e447df77408cba4a627d28d951b35b8ae65106246d2f5ca4f5f1f96d5c65ecdc96c555a42b576f05dc2b674c4dc1c4e3347fbece01027862636555de4bc9be116b081e065eba7ca5c6c90bc0cec98e33fc518315a99e2d02280f126cea6080ff9adca81e72851a62b0a35abd361856ab1016912341b760a266681718dfa16d622a09b20be37457371234cd65c6a988e15e223f843a6f6f25b4a5cc8482eb132792f56a09b1e18db3feac476d26a6358aaf66c5c75c61d4be7d2ba870fb393fcbc84a91a70be58278a304586cedfab67ac46ea3f5c96aed77f511cf70289a6218ec11278a3152bfc9a793779816ea228821ee4c4b2ac527ea2bbd18b610b873909225f77a05d0fb7734746cafd492f8b06423e5fd96092b66b66d463db01b9ba4152067206af22c8775cc86c511190206b6996e9dcb050f29c0660452010000000000000000000000002b13257704ee3919cd230c7a4966af62f1a90433f045ec9ae6e2129fbb3da7fbad04b0b57ce63d3cf7a1353b294148af8a5405d4f9e78db0c11b4e9870ac864161a297354ec93fd05cfb6cd66325d0802f5760963566e2726e3777aea758407d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a76ef1ee54018bde846cef011d9ab1b223496732db9ec72e4793bb6e8634462418b5686695c5c3cbb860c29c39f012ab01627ac5a4cea8fb3e90b22a271e3b9e545333660d151f74106b9bbe6f38f5357f6d8643870b81efc146a6e80d6f34c07bd5b18a5863df33779fdd48789d7441428555e93f906e4f376b290576300e2021aae290fad0c4b652d201fd5375c0b012920c79f42f6de4d207b23693fc1fca5032d64f8464ba7f0bd650e658a2417af78512d17f73e1bcad4cd61a96c055d97c80b0530c6d20ab2b3597c17e9a574e1c41349db4aa03ddc9f278bf6969b1c69d901a08a2d10d087ca82c71a6b5ad03aac346f2ec9a230d473ac7002644fc2eb7adb022bc6f3e7d0fc4610dcbe5e687ec36126008a3b32ab20e6ef9076ce433149537b020cc00ba74aaa3d2c1f4223fb1599ff769561ba7c91c2c5f749ea179009c47a6703254180852bea2939bbc040b5de6e78c85d2f76fbb35b7cb6cdfad85a1b358aa2021c1c6e4460082eaac0e6dc1c046902d2e629d3e02df5504125ac8aaa5d67a24d020e535165337e84dc3effff2b2cc7e6801a6a444c095ddb3a98a8696cb67ae12a148d7fb79201003612f9f91cc85d8b121703e505901986589ab41e6c07aaf776ce19f50f4c934dd6ed1e6d4a98ca104c0e9ea09bebafa10a0362ffb9dbe6c6f84891f1bfdd52b30b8124dc462ae3b2de451d8b5111d1b1fd70e88e2b8f4dcc9a86b10ee74f1d46e9683c37e82df6634bd66c5b6ccf3e2aee636b99740a32f64b5bbd3fb72ce381740575095236ba5b1ed5837864b5e3ccf7bac822aae04a9cd7a5e7926d9e2cbdcc1b080e4f36cf5e00c7d96ae765c0a02ce297a3660d73f306233392caa4a53efa12bb5c0528a56575e140c7d2124880138776b848ab7676b76a87b18d90dc48651333e495f3a19e321fd6b132e31ac332056fe03bff43a7f0b8e699ab851853b034ecd9849a2a1d7662d0a914a9e353c279778a0f9b43291fa286365c5e18d4db29981477789eae822336fce18bec8a6d8be954c3dd6df3d6b65ff960036bc814b4f49b6e3a098c2ce45ca83d47955190c625bff90b556c459358d5ef93185dc07099caf85ed1d253b65f37a3bbbf84a4ac97d29a260f36ef1e701f671f6736d7b2859a67dbb36e288999c890569834a7f33c24c7f3085273c24c5e3359a371a7a1592830a1a8a6420a43bef1376a5ff25bdb9d25de7a5e588f6780da511a417be647bf9f64d1d48302b0dadaa97c1c9795a857694bbdcf77bd8df57d24ecf209807f9570e39eb8210ff7c98a251e45a84f2c4c20e2d5b9ea904b844e8d4bc36171dec924d2cede0342302027df476847159ed8d20b300e5a624756d951dd8d2a1735e335d526ffd52e82f58cdad0e5e734729072d87452eadbd7761ab33477145b9349030a28e4174c5e21c3dcc3340d1761d4d68504c5dac6706fc5b896caeefcd449e5ee1b2d79c887e0fc594a6c4b4ba5aeec0be9255a79d6e2bf1661485eed7b7ee5472413dad290f7f361db9d8e0ae3538999a300edccd30e2fb8b6302f5b77a60bdd7558627445a5370ad763938433c368877623c4971cf13c597472b9a8207ad9bbb94370cde20ae41aa4b21d3e5f96034b5a8f219003a8a53d5d7abcceed4882ffab3cf932ae639af6ea9312ba765da15b740726d208934f1a7c1b15eccaf8a16ea4b5039c91168dd283c8db5306cedd31701aec283c9400dca52decd529fa53aa44694cc006e68233349c6468a47ab1fb573e1d6dbafba157a5c5c7afc4313f102d54ff879f64f5daca9b1b1f1e730bf3fa15db66622572860286a43a1fbf48712307664b9c273c9a5e176630f0e933b9f1c5359b38f0d52f5cc55c16bcb0233e2cb6b56be5a22aa5afe23ba6d2fdf68a6e576e7517f784f25dd663dd6e5f8325680bc7c0afee464886355cc171c66c92e6b09087c7cf761dbe72dd055c071f4f993735ad2270589b97b7f0f0bf2082516b294637760b2d964920dd9ee0ba07e121b1e6b4f34d7e69f403196e50d2549c368b5ec9e7ffcf7e6f04d0c84afe893a0a05178f1116ab1df2d6cd420b2b0e674fc5a4a43ca76673b344ce7dc771a5fdb81e64d169d4365030aaf339d6acbb3d944aab7ca129daebd95cd4b1516af3e299cd7f2fe327e5b8dad83b138aee7cda36fc21286c38926c0e84cd894def4b359b54bf466fd8208601e43f214fdd5062f237b949fd3f7f51569362cbe437574c0b2eb0d3bac11fc9b7a4e7f9e4306e53989e050a27ad0c58e8fca336b829b3843923a74581af97ada3055111551414f393c4badeaa8b981b1d32795384cfd8c35735f227550d3fc74e12c25e8355fdbc517e6961ee6e2bf67c5db4cf6755fe287a0a3a461aa37442c68d5ff5dc8eb89631d3cea395145d2bf55cb80e8aa163ecd4cd7cf20a", "", 2, 243579345, 1537743641, "e19bd85f20084f9f562a0fdfe1450f06834866f9f1ca273373a00edd7fc14f2b"], + ["34159f61033fcf5e6d20d98e6b0d64c0e61e0dba913b7659936d24482356ddbf53733a98c402000000085200526a5200516affffffff42965f6dfe3fad9bdc6ab26b80dfe679274a4dfebf90372b5ad4cdd1bb6df87e020000000852536a52636565acee0178d20751a7ebb2b410261fb7f46e7c6c69c35d8bc2396215c0e2e75ade86bbe1ad670000000006656a51650000ffffffff04ff12c6000000000004ac63535295b14a010000000009635253635100ac6352e941c5040000000004525300ac017f56000000000001639ffc559b01f6773601000000000000000000000000ee31c0188986e89cb5a01fe8b473082f01b6afa771823bf527774d566140a8d78a49b1a3f811e8da0d3e683227345c1b9e39d69e4eff1d1d254c9ee6b52b9d5c8be66409938501ec1ec51849666c77c0c449f9606ef5c3e3bf2ab151fbcaf8060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021dca8baab206cecc62de21ddae8972741b5add4ad7bfbe1a65b743e735e791fe39c955b4c25be4f11937aa23ca904ec9e59a60b8fe2750f4c3952f701681c27d0f1fb503b08c0c88930a1fbc4845dc2ff238a646db212fff465bea90531b19068f8197c9d39f0c234ff4ff17911b1ecfd71bbe8d5baf2e52da5e8096716c3f3032f8b6e2f5451266c729b74d1bded3cacd1188021ca33acc35e4874ac55813f95030e570266f1437fd7e495c0eab63f94a8a816f1eb4d60c4208229bdec7489c6710a05a9f60b9d9614e2e831d46bf29cbbad2064edc8f390b1a8c837a1cfc82ca5daf0a519e2e1c87251e3e4eaa90416b794fe468c047164b7f91f5a08a03d9cc255031798d09d3006413e684afb3560526627a1285a0455f6fc5475ea70f8696058520322afabb95bb7728c24e0030bd5173de5fb1cfa4d530e1c3cc822e2ac1a61dc580301ae006f313acd966bfed637cafc8aeba9b6a9dd9cf0acf8f295c1977385154d0215534fedc41d89d08cfabdba30b85aea5349469fa1d67dc3ba33a900188aab4202062be8cbd2ab47134418065ce7971ad2de150ef981f5cd7dc0224ac95698f5d990e76e6b8c757ada6bc1f1f75747bcc30312083e2af79d9e76360247cfd88c8deb273c4c9c83abfd27275cd8e821b413ba6634632664c26d8df655291062dff07d931dc9f482453bfc0d2d801f81dc74aa484b31d216eeaf7c2527b7f5ababd0a47df131fe5fa7bd0119962e382dcd8fa32c770768eaf7487ee2ec97ef468d50c8bb89b1890548a9594644501226ee2de257e7594ddf449e1ccc7a2a256072d3d91861013b55859146df9bb90f5e1c9a2348718fc4a1d33ebfc6bf1b4c08dde02176675c229ccc088a0e313cdc5e50ddc56c404abd94b9cb8a065701a0a17427bc268e5d33d819f5e34209ee881847e8911eed8c5fb04cbe1a4ad32af88519a5bfd30bfed46b79a870acfaa0566fec8baa1ce59858bb8d9bf43d6edc109f89bb0c3839eadbae50f16e4c5dec49d4193fe7ee8fc5e6d1881d88bf1ff5af5b86390e97d2b9403245b944da414c717d82a96fd0b7caf0f9c045a410a06b7b3066f669a636484352afe607fcb1db55b438b3d0ff9e5b5a15750e4408094a4c01ebc0363e06b0e3c3f624b353c6bfe6925e0e75d6c62c70c6f2bdd700f4e2ca5529f06c498a8bfdda337d47142d173a7543dcbb4e868cc3de8d3cca319cf4d3a368636a85fc0fa1856b71a6bfc7695e4767e9925672c3e84fd38a7639b74e72f6bf3e62787cc7a416028cbe84591b3b01b8a8da201feaaef678b1731652733dcd00eef6c5176b95827a74004c12243b8b744f6cdeb9ae1c308bda543db2ccd1989c94f01e700cbb32f0c3e11b371b559e8b37f54f2fab8b6548c7f04ee60b352e26670eb85f536212c5807c7de5c053c86c62a2995c16f200415a6e844d12121fa540d1b0f71e4e5acf018f03ade409dccd806688c596b529eeedba955effdff30cfbe2c40d2751f05595c80f4bc1afb410561b924b674316fd201a3e431aed092cade35288bfcefd2377610e0f9b6225ebd201e5d3dc65aebefba3a763ff57abb2323b8d609b2853bf5914c830200607f8a27997bdf26a568eaaafbc2cd7ec999a157eb624715f73c995b3297e7b62ad6bf1ec9ad536c004ed6c9bf5781100c8809d29153fea9cde60cfb3437f84ea50dbcf4ec76689beb5cc4c1a07a87f489ee475a09ebc61671cb4612839bbb30fcd0c6b0477389f9b2e69afb859fe5be4f792ca5cfdb3c3e91008a3fdd595b0cd47d787a4d97cc9621501eaf8130e6a2b069acae89ede3251f698cefcc11a672702bc505a0114bee7684c4d1fb680d4d8a250a951a26fa50ec715f6545625e41fa78331ce618af864424263fbe56bb1e4db799ee32b0c55ff87f034a6a067be34a725d091e129b616428fcce9fcead4ad1b79c61d1e10864ed1913530e037b9280c9eb40066373709cea15fd0afdee4d81ebb31aeaff2c408b1f625251b2020e6c34c2e0de6cf6e8ba2f0974fb1c359a9bd784d378d26aa811885715d8ab1f35ced9a61d973d3bc271aa9a3003538b1772c8526811f66e43aa0b2a05ff78e95a40948809fea0e7299eacfab5149045af39373fef3348f4b17e8d84b0442b6b29dd1d9f801d2bee08227cfebcc0d0cd04f5769faf2fa81b4936d0d65f90125687ebfdb40839db11cb2565863f9def3051a0c73adf7552931acf9e1a743e9efd81b9d1560e1afdb5a0e2454446530b0e649feb7c6c801598f25ac5125bb53491e99ec31e2036e1ad9440e94deb8216bd5b2c90add5b5f79203510517f4ffe44803075f7792d796ff06c2a3e23930736f594e948184d4eea78598df1378d5c07971ca16cae506f66a228504944eef9c46b9345a5a186b6f7d7d6df874eadba322f66aade6b3d0e", "525200", 1, -1941464378, 0, "06391925e7d0e6d1eb380031824df0eaa9235a1178b00a1dcb3054fa38588879"], + ["030000807082c403034e0ee83cd69174cdfa9723b3c59c30c5e6b83929b77fc345e15e45bb27630f490100000008656563ac656a5365ffffffff6e68dd8dbce502cee4e26a9b1ef96959bc7358261afea537c3b0f34b68aa80be02000000035352636eca3e63fe27cc6fdeb8fc33514cd154213eacc840c9ad7ba632f6e1de45b9a2c678b60b01000000086552ac650051acac15f8f952047e7df004000000000163280e3d0500000000095163005265535251632bebc002000000000452005152ea90160400000000055365536500d54714a1f6098edc0300000000000000009010140100000000674dec17afa8d9dc73dd38de2aa21cce63e93e5d94463d89833a47640b672ad4c056319b454d9879788b13cd422ddf51a6539807c2efd7a32286ebdce9292edb0d51bc9d6dd22abc281ab62e723eb4121978c8c06550a3a3949d80379debeb1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b42f95b2a1419126a257cd654169662e9db4340e872240da3b3db7ad1e32cf2ab5789518878b14afcd3fea6df18f98bdb4cff097e79504bf3242bfa76def521608be24ff85b645ef0ebe21d2c8b41effd24be9ea137d4a1cd7773dc77ddc2813cb0bf3146cec145bd4136ffe4dcf24f7f6a25fb59213c2c485e31cd6f5a9dd7603015bd39c27bfc0bd932d3285542aeff60e3b6576a88d036f8efefa5bb3a388b2031e4edb273c559cc6d57751910e15c0d200a78c9a0824f97ae3b807e0307b8d970b07d9752539d841ed67247d879d6658067030fe13618650f68c606cc4baab32ff9601da6aabe14e140be2db90df3814a2663e3482e16d15ac83006c8dc9fa28a00224f20ef495c9065f9d82507cb940bf2c4465b532dce26e5480b5ace9cbd0b575022a5ff78b1456a73e960c7a842307dc6a39a4a7bca60cddac2f11e992d754dc4c0316ac8eecffd75081c64fc3103a547c470959203095877af052356510c59a5b9b031556253afe275368fe3661359d5e7d2750ffbfba6e1257636631a6166c75c446032457abb090e7278b97e43750166519e4dde503e4d278bab63de8808a304a8acd5dfdc7dd58ef9126e4a2cf2d63c3e14ff44a4d77d97d1511be783e9e09001d8cf72c94cc88cf918b0c90a68cb8ee32c936b083a4208e3ea1da960f3f7ae9e80e6999484fa1d108d6d46970feb13a9765d6b4ff6c1ad126ec45b07dd7ecd97daf413eb7dceebab91097fcc6d9131304ff0ffc9593e66abb1901921b35378cc8c0b80ef26dd58b5a577bad51ad5690db230ccd7248fb01beda77cb2e5bda8ba39dc22ab5a6a80a3023ee1eb044a68361709b0d6017689c9e1c17cf95c20978f84a7317a99fcbe59062fb2087d7a1eb56d85628d6559ae7d7e6a35ed4e37c3c4851bd2fdae2b656878930916eee17e8a4dea400c0a1513ca9db208fc6adb17d59fb5d7b6defb0668f30977bdfbbf3ef93380c00d244b2bf3a6f256ce2442af7e42a4b43c2f5ef1ffd1118596777f508b25f7efa29858871b09b8233bdd82902b5b4bf267e301347dd854c9c4a49272830315906db373437e90246bd2cdaac13ec4431b1a6937dea6d669a45923fd9031a1c0363838e0d7265d220206e78ce8951c05b605ecae4b8c5a2246553f238eeb0c3ce810dd04a7d923f606505df36f8c21b4941fe7c42a04076fe698119eb29a3b20f1e3a021aff3f1cfdb0ead9a19dbaff27b8e0a00d908be58e869d88d403ab07603a4cadd1ce4636b18d58a9e42113ec0431b2b0519a0bbd3511558c31bc01ae20b69562fb7ef5693cf878c7293cae1ae62713e6535c5821df32f69d53c0c91e1b14227f8e782e4cba04d35b3d154ae027f5a8db52dd6aac2cef38c521f52bbf23922ecd0ae7e4c3cb37e16de69bdd4ca67a284677c4d148b14156bb2041655886440d8a72ea0c771adee0083d45054ba6fe1502accea883757d81c8f34b49ac67252d268255de57d071998e34d1aabc36a7c2e0abbf90ee0370b88b9074045bcc73c40ea9fafceb99d704eb6ba459d9df0cbfc8579d8eefe9091a0764311a7fa8d6c620c4ede1e9291850b19b55b72dcd6e96cfef6a1ac82c97b2f9bf44333407a5342c15b43406963b091516dd33e2ea3fb64a4eb2a362364e2bab1dec605bacce521d1e30d802a8a9dfce677999da699f35d3518bd4fc71b4def3ef87f5e04fc70b02ff4f9ec887ed0407783210bdfad4dfdb2f484ffd748c03d671915b79dd7e34c9ff0b7a5f1b74d0b34d5794523f4588e62cb44939aaed6841390866eaedb7425002dd3e637995f7e495e6537c0e6a5016ad7237d048d952ec09d0d116fbb44028ca23080cb7720d22d73905ca576547aee21dc4a5eb72f930f73c4dfb2eea6ca62908798c89d2ad75d6f2d2d97dfdd80290995048ff080f617f640eaf4483d1b68edf437d24a833332a964576330e40e6d25e00fd6c34094e24e0d08bbe48e63d4685cfe1dfad12233cebfe8f5bc4542072503d9d2814078dab0dee493195def20137d22249c2e3ae46a093c63ea4353e2e2a22e3423d8c7e979fa353eb5e9cb0d8e2dbd50580416a2804a5c4259db9f171abc16b069658cb610d97bea4f4e5742ef37bb935c732d9ed9b726fac8b36cb052019b59366ccb2e51a53694647e56d313a3c5e0ade104d8c9068d449d313b58a0796b711175ee3a35a272833abdb9df05588c53655039610ba2c2b1100486a84b7dd71125c9394e5565cf88f203128ee0b6ebd26596d9755f42b99ac0366e55c552b4bea1ba7222cb485b681819b0a4c030000000000000000000000006e90fc39f0bc8a464e93ac9d25794148fe5ae653cf49811cb0c1299a45d16d9687ee97a5d18bfe203f3ffde2270a004e28edbd76a891539c920523546f6b88bd51a05334d858f10430f5118cd59a5c3505e0e76a8d8985d4093c48fbd1f82ddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d14d602b46aa6b6cd45aa0b6cb0ddd33f2745569ab5dc6fee57ca39bd8004e7da11d2bff0ed4556e7cdaeba0d383416decabe3a5f71d3d3fafed886066e72a137224d30055faa17df725ecb9630580232b867fcd85319cbfe8f0adf8f64f3041ed521bfa1283f4b208ef183a6eb9dc5e2239c2d61f86b76c29464ff96119b69503139e711b7104037cd1cf84520f5a52ed5f3e8ceb290afe9d7bd810a959aea57002149f96e5375680f84949b6b376b185f1a20e575dbd19b034cb010cdf82fd79960a085e2b0cc175b39f72ac08d29510ff7f760c3caf407ff0a84365d00f7e70444edb30d7adaeb2d5682eac42da4f7791bbf59e1eb4fc3e3fc4662f5552b8d82eae021d166a6da809e5c1f743f9588520ec69217728436c08d2b1efab3baa7b38198e0326ef61c180e2a6f1957c1109e2ad520b879a7f9a555652af1efc4893164f7038031529a0bae5685c9cf3b7a260cade9148ea5a8263f9efc209eb07055aadbb18ec0226441a4ead162bb12975c9b6271f9e220533f5ce0aa5ac8dae354b8e2de12c0902154cd473dd4598f01e8013230c85ea30f15fd9873abc5e11f4a1d232f58c3a1d8a086fa6c296205771dbe678b171317ef9866db802861dbf8250ec9314689a0769a9dde430631471984a03950d682f7fec5a1c558d01cc3d38b97a71964698e461e8630626460d46e0040d31f39aa57fc660f603d1af5903d30c0bc1122e5db5e5e9d25faa07cedc8e1ea8fd91996c23a13088499330abf0f1038032b226f73c2b696b09a77a42cf4ea83ea334de781571ffed8cab7ebe922393092e89736d1be533d23d7530779fbc1438c0d626afcaa6aaa9d6724d7322a57b9ca9da5577d0bee44ac7a9036e6bbad8fff78ddbd73fe3f537c46f57bc7a085c8ed1b08b339f0ffe06bbcc419f760d3c01bd2f70c02c42a6cf3e3d6ef1cfef75f452cbf0edfeefb8059a06405fd27f92790d4393542a86d67de62f851158630a997a278c90993b73fc5e7a39d09bddb8b5994ab0ed30e36f29f5c682c8226cb0d1d92ba8046d3b2593b883e58bde2f827a2d8744bf3d59c5fb79cffab50edcf2802a8e8311325601ab90607190c6247634a59766013a67c3f15947d67858a054488bbee9f7695eb89ddd8983e43e2912f39835be898df0a1481cc40fe5dbe02f940bcd94ac2917cfb50d0df975024a7647e61384b7f3c031f0233151c806954d650c8d44f281f91acfaccecae26837e192df443cd29087b075296d4a1b783627412e84a4067d847feb468a29a9e9eb60e345abcee21000e830f157cf353060e5afd52db1d66476cee7703dd31614417cc11f33d08db84f6bc804381d4c424933a75a02c0acf37ebba6babfbc4d4cb3f15d8e43143d98e0f53074a632f526c747c1ccb4cb47e2e57a86bacf5a11d6ca638b76ea03ed9b3eddce6f02a03b118f0071371fa8e03e54df416f5f811fa2513c2dbc9a72223cee962241ac04ab4ef092b8ba1f88625be9852c7558e5a2caa8d3f388f01dcce4ca042a88e70471a2cae8295b1ff8fd3dcf9d4a46a435b636e90f28c1c40123674ae187a17d88fbb27ced6f81696e9fd9134991376c9bc0c331f65e28fc51ca27a2bc1c5289c30a2cd5f4509debc95b98a3f546753047524477ca7874bcf53726d89bb250eeaba690e4ff442432a7bd5bc712a2e72eeabafe53cb4960eeedea232c4d68c2576910d5c9986b247a8fd9f2584b823a56a3c4392baac6a79b737f67b17bc2086a1a002b39b8f7f21d782f3ae642b1bce7113c398a93518cba3087f5b0b53d823b14f8386ff9af039201088ef0fc14aa1997dfd54f34a17b8f7e8de6299c532fd8964c6e40a7951f931086414a5c80231263b0522c461aafa137e978316436aae9c81174528bdcccf628b94d0c5add848f609b681b0eb316d3098bd81d05f7f5835ab9f615464aa92ecda36c4c01bdd88384ed8324d6b083151614b73f5d0e1e3f611b555728d894c55393ce5964df64c460a43fefab115132e468e6f921dcd0a35fb18f96208315870714c0261d717f353214d3011f6256b5d5a168f124d51d6c0d2b4ad18019f532dbd2f9918d2e0301c353af3d9b3b335bb72d6f2dc0fcbc24328d26cc16ba711b100846185352571f44154593790c8aeedfb56d7ced86598d5f057fac68f519675d8cfce47f24bd4f85e8816dc770627f08d2235191e4cd7ec545a76dea3fde65e67f35eb52078c2f0a2972f58c500dfcddf48db22c299cb321e824a74126725390220ae95cf508e1f62b6a32ce6348e4283857214f0000000000000000d929d304000000009067211c1de6cd01f52ebc12e47e994720fb8be55e8543117e6278cb912de1f5a0ee35365dfb30fd8db30f1a11fa5e1b059b764a1bddcac364d02f97a5bb7b188f914942ee15d90714af6bc76b59d187d30d186fde9624ee6fb057c153ac8a10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f362c8be2ff5d5d6f1888c57d35913d77744e6500b25df82c20f814ac1129985bd1353d8aebd73c8044450e1609640ccb37219ef72c191964ea19711f3deeb91a84d900e97c1c08c41018379564b23d2d951e39ccdebfd8ac67dbcf5efdf481325101b8ad616dada82289d164fecfdd46d6b4ae012789b8e43df8c6b5ae365a022f1911ec5ad3396907ac76737d1b689480ad735e8d4574f30ea88685a8f70faa0213aa0ae32555f8f1ded176c327902231059618e8f6119445dcbaccb26a1fd1750b0361678b07a5937670d8b6828665b0ddfc6f7aac89832eb27a9f0b254db28679108c6c8b01d86dde6db8307861941bf3aabdfd4ee6793431b32131ed85334d6f0222995060b0cdfad2e352e45dfe3570768a27525285a0830a3585980c6c1442ee0221f27dab916bb26c93c53d582bfbfae85a56d2a954c53bd216f9f8fbb5e3467a0306042ff4df34527286212522a244aec058fe31469deafc745d59b31fe4a4936d021aa33bcd71bf2d833afdcd248ab7f296632c9a37a32b4c32120846db5da0ad48021450c38bf65ae223a8f800685c7ca4f650ee906411d21eca780a2c8c4e8e17e0e9fbb50288961599c4f582045c9c87e91ff3c98b2f5371a63548a5223a494b3a9e8cb4c5d49d8e1efaf1b733fa36d71afb150781069843d9b35cdbffd5665e3ef7e87289369dfa4a64d9e6a0d92816f2c66e841150e1754f7bc3e98305583121662dd3e9947b272b7cc0582ca7aec540d03079609efa4da66432c5ae37e2e0f4c14689ea424ca2ac7b5bbd7ea358f3b7bc3b3a2b4e8c1258d5aac603b717435ff30f5a08c9d20d264e4a3184cb06a07ffa5f771c9cb93a744f9fa1d9cb2e40be053b3380a1405f5bdba4cbe02bbe14199914c34b58fa4573b4c94cd42da3124b516b94a39a25d343c46e525ec4790ad964571e702115297bab9c6e3e82587f0b3b60afed328c471adbb3b783449b45031fa74126dda0fe9dd2ac1f07008cf656565eebcb9b42127b07d39ddb1b4f96f1bec7837a3f3d32ddbd1e55c71e5c6c9fa107d63743b74e90004972b259282714e141f627ad94f06570054ba11afff8539fa0cb6879b750ec0ea9edcc15e41728dd2610dc735e8784ce358a2c4c8fed2052371a2eb1b61d399ff8b978692277a0852f77361a4ee7f743ac48dac877d6766073390a289ade172a6426a8a11b2df22e45a182ca1426202be7672556d927a8a14be2e9977a36261f3c85735ad1e7fdcbad909af183708ec714c123b5f5fd197c55ef3b122dbe72ad254e839e89c9b2f87d8afd7e07b6ed932e85d38635d70d17426801ecc134d9859cdb0edfc67affbd26633a421f50a6cb05781469635b36e1ad20a270b4dbadd4f7908e77ffa0b31cd016637ed7b7f7ecc51fc59fc00791a04c0154e3dded7c16a2df94d65edfaf494a085a3dacaf8768b7d64ac3699cba898017d3e24a75b12496a26b369159e5105f2daf6691ac59c2206e98f4d5e7beeda94c5f5b8257c3fea59112664572c3f20f056e33b611514e0d1dcc896b419f53bb2ce8c181490819507caec7ce3479765d215a7d09b85f4b941740b782673640e0bfd0c4c64091c90d23d287f0b87be0d0e9e9eb131a13ead13ca5f59748e605bf5c4d105d74cf2a3163e2d3a9f7daa5eecedc8b98256c677888a1b5d7b1ad89eb76e44cc5eb45f4862a7a2fff3b26b0dfb470ee3e649c99ba19897c64c8a73f4f4faf7c8f1adfe1141bd218e707f3eddd5e22b5e4c658e82885f6980c3f4a22372fd526d6733b7a5a5955457cf48c58880eb819752da5e433f802c8654a2519c43a5be8ce821c34ff693431c794d168bcb572d9e4775801c5a0fa9b855468463af2393a5942a768b27b3b87a47c19689c11e1586d9aa5d2f5feee3e61707238e47c5b8d9fce63e51d98be83c89a656bc7c1f388a37c735a32c92e0deff866b8e15463967a09fbeac1b8fca230d036be36d29e40737d365080df8779ef329cb07fdf5d2c41ba974d7736627cacd6fa5e6b60e8628f19fa4598e9548b888184b8c0ea23368b6dd2b87e7905fbf73152c34bb624c4f28f118b5d99e817b95cbabbcee5d92a4510c7f86de8cb813831006c4eaea2a0c7b1514b59a889fe3ed3468edcf55aabbe624fcf030dbf8ea1857fff96f5e186f1fc006d199b1e89118b62d65b08155e82a24d696930cbd4e86f3f29a42bdd83b3cf4f559877acc704efa43f7632747205455e20a59d87a211d919fcc50b61c4886c0f2ffc79dc933a4c39608b484405099e7e0da5cc6f2f9b541ccb50f9b95bb363cd024292ab169185ea7150c616ef0a015dc15d92dc378812224539546a1c401dbfe34a41cf13e840faaac9e13762a502f3dd5b30f479fe4e405c512a0ab94e0cd32545df8eab52bef1fc12d4251f19becf84c6a4bfc2c9794a090f", "635251", 0, 1857423729, 1537743641, "5e4b3795f131c18af14f7a2d3bae1c0cd59c08ea812e74785195c1678e92833d"], + ["030000807082c40304f1ea2f997b3471c07f92ef2b775d96f9e0589ca9a0b388b514719cf6f50ccc140200000004ac6553acffffffffcc43e0035ef0b96ef53ea8c72e0ddefc44b3e31476655b9733e30dfd9619eefc020000000700516a63635363ffffffffe8adf488be0da743d7230f6427b4d3100dee1861b2a8cf69254c7638b9277ce70200000006ac535253005230e04d330bf7d6541af1b9d166cc78a41a6874eb42ed0295b4455298b368ea78ebb62a91030000000253aca7c6ea30010b2df502000000000251ac18fca6100000000000", "53656a", 1, -1751386165, 1537743641, "fa30c6dfca2dc9f0764b1e0807885f83dbc7b9d70f47933a15af76679a44d5a6"], + ["030000807082c403026fc588eab305832dc7a8f2bf1a6fa7a7979b3aa82969eafad88b7c41e345283001000000085252656a6a6363533cb1547e7eab97379e7d412d9d65d4f28d3e8b18e067d77851d78b55fbe88c9db18a34f80200000000ffffffff03a6006902000000000765526551ac53651e6b6003000000000365656ab602d20100000000085351535253515163000000005294ba4b020000000000000000593d720300000000a29d5b15e2aea406b1cd3bc9c4f34b98c88107bf1525282dbbdc19e5a5b36b698eed86e68bb395f77d377bf5cfd93f89eededd16eafcceb9d4f2e3e4120d69dd205a22aa25ca81f371a2383d8d049b9635d94a10045eac530dd59f066b5119280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013253c06a1ec2bc849883f454d8d714bbe291a0ecb3d29ffb94e9b14a93d8327548fab10ea0255c099066cd00b75be28004fcf1ca9c663442436331e06de15d1c6ee6f44cbbd32d6306d0c3427f300084ab63d6f63e771f0250f6b06ecac558067070684f44b89b9f25d341f740602e8c58522970724a295d9d60f0fb4ab2016022e353714783ae333b560a88660f8a49ea1a6686485c84bf1ac961206ba7e2e16031dc1ecdc9d0603be559e8f43c909fc02e095561f8a4323847255c6cefd8175bc0a030d7c730e0c6d714bc36a9f7357abf112d13ba022720d8af8627a39f38b3b459092c892acbf15c34ae1d03f556520d0ae1596bc9a2e685edd0579de701adb4b031cfe887af4000a040ed66f24efecd5da74ede1f89b66b8d0ea07e29bd123af64022035887085fbad82229725a7f81eb12cccdbe4af9119e71e270c96a06a757812032414682c587637841eed431e3359958f8580c0369de0d32ec9e07ed9d00a487f0304aba5959f05b7125ef1afd7cad903d984359a8a8e559c2685bc73bb0b51966e022c75cdeea3ac5e95097f6d74f1ab84d4709e67a3e841f2c8fe8a9f789644a6625beb638289f05bda51f425c7abb4d8ccc1a83bc18bd28b3c8775a1758bcbcc7e9745c3adb89f4d37a144b568eeb5c06364fd1f6bd14e3028c65fa22ea915529a5dfff76a7e77a0fd67b3a86639ad16d2dc5a1d91c83afd7267efc948f1742c40c521a6386748eaee5ce022e517b24f7ea198721cd7f5c582b08f354dd49fa36043350d97b30709c39b755315adec260c4e4d6843e10f57713b705446b28d8895ea5714faf7b8c771b95e6da5961135e6d7b0ddda75a16c1f3f9bd9bef0f719d6bf70b682ffc2496ba5b22b79dd82dd1f2ed98057086ae9311436a6cc3d1c2a23697f4391e2c5184da198ba1ae457fc0d865c47bf9bc0c0edd1274270fc309aba4309b23aa29f2780a1c5c78634f95a7d9c627394024261c38183978ef3f24739dfd3286ac0e6bd28b853821f29a3d6e133f8dd3abba9c4ca44e956d80e151e4a09307f2545cfd2958673b9a41bf6c4e494fde25822cf753aa5c69c3d302c400694ed3e1320d85603439dc897b3c6318afd2c2de5b5c491f8306d22e51da33f9da2844637e1616d18c2830cf55b8eebf6212990b28a73d41eb3a05e4311e1e1bb26aef49ec8077194c86035b4b2b0496b980b81678e6e061025d3fdef03b57062aa26f6bdcb7a48e6c762bf950c1fb716c9160f6f561ba575296f997b1ca419df09cc400f96683d7b0e31acbeea0d0edbe4c09a4e8a50f04567a238d0fe0a326402f9431f997fa2df593a051fbd41a344e9e043ae901eeb91993426ef00a44fc32f786294a918e6dd4685b9171382f1895407ca7ceef31e85dddfad0227af96c83e34ff8593094c28db6392c3d322c4856b7b23915e06ec257ccb9c6fe1c87640b83dad8b0af3287041a3943681669e7187c4b2f59ef1a0221753717b3c69a9123a618871e4e682d857b75c86521881b9487e2dc3e32c380a1d5f4d8e42797580418491066486c6636525366ea40efea311e8062005b778cfcc2ae1703c79a3bc65de9c08db26fce9b85f4b302f694bfa3b8cf1bae98cbfbf4524d4db5bbf33ef538d0d72b090a645a74e04f91b871f7bd68d9174dbfe8d292a7b2a9b58dda4b84cdc68d48b27e06423927b44869377f90b43ad6b95c029501483e54abc19ffb919619a711ff83fbdc13dd8ed27928a2362c4c7c3a2985df4502f96d0b8812c0cfb41e1605a713be2127d93cb5c81a42ece4fb9b3fbde10bb5fe5a1bd4a3975498a08d76f6c544cbc64dfbe414aba1dacf4f07ce294d74dde1d2470fb1673d3b5d962c7036376b00dfa4cdbdad277825883e7e440c0925c1e917db2afad3a53ca5ab8af24058d48ea164833a165cdb3a7b0b5685042236c9cc78638f3624326c859ec9aa43044ae27a18a45d422bc848a925ca10f88bdd30ad57cf29df68128c67a945d18cf44aff425abf895158aa9116ba9bd640b5cdf495619e44cd057a857c6db4e79ad37775781225b33026a5913175ee6689f545386c3470fb1a43be4d5b5c170b25336826b8e1c1bce11b74a1e0633a18c2699b541eab1cf55684277a6b2871784fd27b56050c40d5853901e88ce398e77fc6560de2aefdc2ef9b8dfd71976541d58eb6ad43c37273ca7476a5379600798bd394f17443db74744fca0de794ece75ef2bde9b9b0957347305322bd773666e0a7f0c4612b8f3ab39005cc50d8405cc7c101e558b0d0a493bd373f91cd0764d320500000000000000000000000051aaf11aaec97501588f4a5769f9aa8f8c0779d4c7a703413f6bbb430c31e1408ce5cc48724ce470a3415f502c9506fc6395a57be2537be8989260a6fed255af29261290a332a420138c8ef7b362b81f17155a0f8bb0b581e1671ec50e1f185a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032bdaa42757f14d3297ebefb2477fc5fe5d5ef85f12bda462f0317bb654c72433f9ed14462b0c77b42e004cbe55b1cc89a4f94f21135158d98f8f5d6f716cf8b7a7019f10401537e3f1cb7e213cfd089bb9459c0d8c2831141f63558e802ea0e0106f949c62cd353a8e2a9129185cf1c9a71c7adca4fb459f26d89b2940dc93f022395a203022161b792a2a6884a32ca55cddfcdf9bebb2a0b3c2ebdb8802858220204ad413c579b00ddbaebaba18efa786213de4d54c50162e0eaa5233364535dcc0a03b990d6e4c8ac49c439d9c9fa61a03a34080d26d9cbaadd1256c9cd1ec2e8256ad8410e2da7551fc7167292ea492c8471fb063e293908be13454881a13b5a3c03014aaaad7311e3e1e6464bc72fb87c6faba40553b330ea592af29aa7858003c502058d97b45cfa67803bc4bb9df486a15c984c590d1e9b5d3d2dde8e06c6628a44030289ee5925722248871dcb6eabf78080d20f459d5e91bed77061d69d012f78e5020ce683818987fa75cbb25550981fea1811bc9b63c98736585ca373df6f063565021ab4f315649baeaa527f61a469704644ad5156a4bba50b0e4f718b532e7cef42b5ee4784512c7166ffba43264af6d4a6f46f313eb44f7fd0b016b9eee69b434044a0632ed11972dc022d4a37852637bcfaf91608aec756d9ec7ca4706659dcd54ce7e83d148999fe40cd2ce85a280ffa2434446b406af34adf280b93cad853a43de068a2935102420c90f239903ea8cbc9af774ed730dcb5b3c005bbcf3d9252626b0b8a54c7e99714be235c60ddb98cf718722a23671547926dce67b19be29ab393fa125e34e96bd0a3c1f674c39fe058ce0caf83c59116b5b38aeb46f5a3368f55ee629939c40b71f9ff8570ba8051027cb22591d54c3187d8df1fd034066d001fb946311ead3b4d561795739e04f78322671c90cf3101948c7822f5f7cf9ff040e5e88c5b6fd27266523cf3741e16e3bb34e59c15da8adaadffd2f03ea85d0582880490c82d007b2608f83af422a8dff75186c00057098bb9226fb627dcf3dd1982ce639fa5b14a9b91a5e0140504fcd6aa26f66ba0283accb5ea8dd7d539d60eb8c0af8cfe8956e51894c88cd654c9bfaa4cb8269e41210705f8ecd0411d798b9c3b67c3ba7ef0277a0221cd32ee42d417ec31fd84be996cdce8710d623afeb83bf2b7a0e39dea025dfe31f8a42cf7a702bba0881ba2ef3677dabd78cfb7d4af3ef7500942859fa19b293f7752cd0ed9de3ddf469757f08867f358d7c8f648fe1b72e0e2ce1f1c57de3c5cf74835ab1a22f8513726489242298c0c139678768513eb4c4dceed2d83248a13df98c9af7e47b189109faf50bf9b14d0a3dce86f64d15bdcf9822d77aea8fcb0b6147451363752e26d60c8d1856555bc49c4973e0cc7801a779ea4fd595f9a503cb1da6115ef628f5a64d926c6f1a0bae693b70192c92059b274d73811adaa2662b3a82ce1ab0fb8c52fc8cb20f9cdf4e389836e2bb0d63affa3ae684eaaacd1a71655bc11f80c14f45f734b72f80340d3bfdf5fcf27b35b1dc2c30d12c1e863b0a665ebf007bbf83099d6de281af9c5de90d760ff2fb02d4cf40c458e318cdd4c7edf58db3e18134f1b5a61f8a73d8a7d42ed176b0e1a946c079d25560d20c99563f0aba5eb28ba991349aff8a4fb68b29c66796f1acf9776c9ae9f8112a82628b9698138e207f6c481fb59a2e5e0e268aced286fe5666c7bbde1ec49bac75aa461cb2ac467152c4f8c0b0c4ca18dcacfa7a0f1fd0a7cf6c59d691f96c058471cf0ff975a0e6ed70b1098cc01804a178ec5bd47c4f5e5db50c6f96df2d95d97cbe57954e9cd955398bd519783a5104d9259559ef6e7b7033f694ae3901b6762830b0e62b37320f277fcb57df530ed46054591bd756bd74f64843033d5e7b5dcc05732ae7d4dcec5b963af9101e95d34fb9698755f6524bdc4267342ab47867e718ed90f0896760d626ff6018b56adfeed8df025023d2d3b9ab2a71a57d9f6bcbc2db74cbf4e8a12c034f4adb9499e81f334fbc88a85d7e913575bd15e56aad3b12feed401a3899ba596b48d818a6c59a69cacac3820917c66bceff4aeff9d57c3456374fef643e333914b61dba72d92ed600f1b049e881b5e7b6f9203da125d52885fc6e73087944067c17e11169fe4781386dd1ea7666b3d8713f034c542fcddcd1b2410c79964edb7aef3f9c36e673bd698487dda6d0ab0b066589fbca67b69142c7ef34eac849f8b80d299a1dfcbd05e5dcc2e81f5934f1b1d728d3575e8cae45f7252d47b04b098d72c207708040e5a7795e2a3df5fb54ff4fc83935fe6991e7e4e85c12d6191f0357af77d486e54f1481fdcfecc6e7b7719e4feccb6e9ee043d7dedd0e7b90f1cc49ed74fadb85a95ebc524ba6e560a8047dc753b97c0d109f4f400", "00", 0, -36157852, 1537743641, "3964d96c8c7ca7b161a537e175774c8e00884e16fa6469d268aa29d165268e27"], + ["cd20ca2403bffb1b679c89eb82be20cf9e436d747da941f5828c6cde3b69ba8ab780f45b3c00000000004d64b8882812f6b1fb4726bb1cf764b6c9e4cb255b300f5092fe694578905b3c952eaaeb0100000005516a006363f38adb11d056b91d9f801a761ff8d4252fab8e513b39732207327591b6519b1b762234cd00000000095300ac5152ac52525121975f54011e65ce03000000000352ac6a24c9f7f500", "5153ac650053", 1, 1687145526, 1537743641, "61194ed560514b592b4efa90e5f9cc480dc3bfe428d69779da8d904e403c574b"], + ["030000807082c403039e532459e25d0ed1d6553e8d7d4b141d6b9d833a0daff9a10b9959e49eae74590300000001acffffffff25ee12be25bb4c8f389a5758289b7b13c71e9b2921cc9ce7ecda87137a58524b010000000165ba17a07dd141308d6fc06cfc35ff3a4f091724c6a704c6186f173f164cfd3c9be714006d010000000551536a526501c8f129032a0f5a02000000000453536363f652590400000000096a656a526551525165515160020000000000acadb18220de3aac01000000000000000022ca39030000000075e168ed89333c6a80ed1910a8204bb7f35e3b81c2335cea05b40bc81f06faad2621df2a6aeb6095c3412746d82a07447820599021d925276f202243f1b464690e92a93c01aa0fb396e543ef8258094581126de9948bcca646ea55c90ed6215a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001315508589115d2a3014d5a8a99587c1199a88fd4334fc85d18c15fd6ed02fdfbf9d2c795ae7db421e07294093c77db4a3b2975872a2b2bdbb1b21b7775eea741f062a218f8319fc01e77608478aeea83e60f3b3df41d1e39cd9e09290ed0781356177bf8ed5ed3ed9245f6af0a9f855068e7426e579e2e19d0cb3722172d7c40316a2f69e46c70e8a60b7bb17589570bc18dbeb7609e4d7f67266b0903a230513022f15a667b7b87c606d223e3630c5e4b7760d81e0567e03fd2a04bf4c55af33240b054cdc010774bc99d3e4661371b50626c6a544e29718e4881461167fe286cd1b7d29cb93e7a6290161297fe3af663e3b8fff26279e72afbf6dd32f8461defe48032f06d726c9f023c1582da21b41aa040cd525e50b43fe30e78e973ec323a16ae9021b859912a95708f9ae36ee8caac4859b8f4bb28948bafc4d1e5076240c0f927c022a771ad84e1af50ab7f9c1d1469ceec8a9ca34fd2d5bb5ad6b8209d2caf2005c030e0b3c064701242ecb7aeceb57cb340c1516cfb6f48541208a44995815f1623b03230ae317771f5c2f0ad4ccf9ab5f717aac04c28039849870c2e47b5ec83f3638728534ba459fd8ff1e3e28817d073333f76af0e90f63218d81d92e188fa6314328c6a1a067dc8886341dfec05ec92af1c0fae61c6f612e4cd1779affb3d0992490b69f900ab5a3bd0cea139d5fe45136b209bef95ebbb099d87070462c49491af21d366334e4ffe551f7c3530820d542d67d175b61881188a1e301b8a5c188c1179bea4ae0a97c85c369efb69cae039ffefa3e051fd757ad8ab72f5788a052222a36fb81408047cddad909e9152e0b9f1be2adbca931c73c7955063f8fc3ec35d2f14a69e75993522c89c04493036ca2d3ca28f3e42a52bc5b2411ecdcd49c3f451b7e9398bac24b067313efad866997c39bb81dc5328f8bdb1c70d8e4cbe6d58292d4b0f0bc82d9a74d160a09eb91a1fe3b610dd023995d8c63923927384278620f1211a902027904792aae9359c797ff68fce2b2cd791122e0b743d921868c1c20f886c548cbe33b1d237453994397eddb02b7d6087929ef041f77b0611e543cb2a2efb88031d9f1c99a62156ed25678e4b0079322f8bccb4a5272d10d15615bcf24292a6f1347465bec1699032a698eab8983d81be9e2e32ab8ce9aef36843865c296053bcfa6ba9803dbb1cbdd3bc580a8bec0c4ffc90e678ce2a135b79927cb4d10ae7e8c442c4e5e797b5d58ebda8474ef74664dd87ed46562c49bb522c1a1d14196f0357d85edf814acc1a5ebdc7bd75fa3950ee4246d7d41ca6374e43f934c55535d9e7e067e0929655d498f4a881d96798919d65f56075ab224c2fcc95690d9bade6fab809862922a742b7120f57d4610e424dce5a5774992e1a4e897f042d72e161860f523e82d954be8f121c50351394b739bdab9339c2624dbb58e3866329a9f54b87d6b65e39a0a2cf332e46a340d79e6d482339d22a44c98f0e667637952f4ca65a235bba3ad201894d4b0175a2ece95cec36c8f25a467c4172afa22a03dcd997419804131731e432b9ed82225bfb465a93080879bdb50447c14870310cc0a62ef781e08081146b0aaabba6230e44d5966de2b4d6db906c54edc087f420fac61683d4d0a0db1ebbb2700b697651f37645c46fcde35368e04ec93e116c8668a8cdc698d0093b8926251166e7032e09dd204ec3d0e0e415c06e31f2328880b4660f050ac6a05fdd46a0825599c3b5499ebd4b473648a28374e12b4d7dc378c27c752985fdfb706df26b8fe632f7b93313d54c212c612f5788a89c33efcf71553b9c6014b22bc3824a697f830c54cb06f251bfcdf50902492cfb0efd57456f6522dc1d80615f04d54b1915d716b3dc3a89edee4e5ccd60a1da32d1372588fa6dceccc3636756ebe60b6c579f232a0aedeb805b189e74d1fd8b940f857a83136461ccfe9ed10632d938dc57be0f233ff4d7aa35ad0af515958d4929f7e82b0b0e3f9de2bbb701113611bc2939b7d38b301360a5e241c4b62ee434424038e11441d1f4742adf5f32d938bb45051cdedd5b7efb1684e050d6e015411570ab91e57e009f024dfe51d9bf64312aab68bba51087f2efb02e10e09b763e3172f87fde55f290003583322e18aa8ce7eec0d1db9a0b82707a5ba8cc44f318bbdabcf776cfc93ad11512622abda18bec5d0f8239bcc9a1c1ae52c80d4c813b6844ee347c7619700c70b4e205b95b829f4872a4308c55b8153e57d6044d0fd710a009841a83476a310138410d87aea5ea8db1597b4756fdbc2b100ef2a8ed91b4aaa9794abf1acee49177151542f718148e80edfc489a6bbbea8c88dc94ecd37809f5f31610cd2098de2d44cf57b23df50365ec636248607cd052fa2fda71c65beef09953d6efafa05fcdb1a4fb1fa818a0e", "6a5265", 0, -1832888214, 0, "b054b0a4b03f7fc224bc57c9d1ab93fdd7f17245e5081285911f94e834682c89"], + ["99e765700267519050d5e47fe5281a6e74608a777a64ae1128b1f025755528ea615f76418b01000000065200656a6363ffffffffe726f10caeffc15cb9c85b978ec7bc81cf78546b64b01f8a9e3fc9482b3862a301000000095263acac6a6a005200ffffffff01ce54690000000000000000000000", "52525300", 1, 319053645, 1537743641, "b9d8fe6d800a9393949d90b4f04f0965f1dc565b5309369c9a5a7dcf018a28be"], + ["713d8276045957e32d939a19ef3968ed4f6e0477e5f28625e952e538f547800d84d02d67e50000000000691e81cd92e1031441efb3f5217014b984f659b5323f6b6d42d2bcdd94067e51ac90ca6602000000066365526553ac447b7f1633cda21b1ffd1ed1c17092670f7bea15cc1dd93657b1977f633c2f123ba53a4900000000075353655100636aadb21c7e04dda19a4956957b6337c24807d562435952919ede84ce369e1a368344cf0cd402000000046a630051cd2ef28e04d33d220000000000055263525363c3eb1e0100000000026a6571362f000000000003acac6544fc86030000000006536a6a6565650000000000", "", 2, -1718253438, 0, "1004c354134ef3e4ce6b4328ba0d6eccbd77c024a681ba5fee2c51f1b77ee7d7"], + ["030000807082c40303e77945de79d28760b51c43d9b80ac15e06bdede7357019d2a6ae75cd159c5fe502000000045265ac6540ab8f888337966eb00bbfd6d4a14f1652ce53f912e9415423e11dd652d1ba864d6dc7ae020000000852655253ac6300acffffffff654b9bbad0d3924a25434f9f26cd555ec38c5f5feae429b79916a52a9196ba79020000000152ffffffff039eccb004000000000251ac99e888040000000005636a5153523b855503000000000700ac5353530051000000000000000000", "6a526a6a", 2, 616752151, 0, "f89175c252c64325a215c0f0826b52bd5f49c56c28e3a2d8745f76c59487d7d5"], + ["c780af2c012175e7c84273c21fc958494daaa145c172e91fe2cd695db6759b11b1f824b59f02000000036a526a4b37be9e046b152e020000000007ac525253ac53ac6af35b020000000006006a526a5365a28c28010000000008535351515153ac51327ca404000000000251634a970cda01973b7200000000000000000000000000e5fe13ffbe0076cac239ec2a91f85471917c03f418c10a0443245e1a8409305ffbf9196fdde11b864718173d9a929e1a5a03dfb805c4c8aea2b350664d4682246eaa2d98db3e7ca61caea35bced603ea7e6af646b3ec726746a9b430a48c8f06000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004dc19c0b811c2e1f67bc3235b0087590d0aeb122be0b568a26bbe97f210d4decb7771f209329c6d1cd0ae49221b0d201b5af56d93b5c42f72a3a25434a8e079a954017865682a8c0daff02dd0ca294ca89ad7e5b0c87d24fcd376e14f670eefba07a22cd02c87eff0d6dc9c603afffe10b1190bd0731485bb510707b00e09ca4022fd3eb7d39bfca30543a09af07a38cd81d13183d8b668d93ceb1818740eca945030b9f1b1e33cd558df5ab0b2adfabab48852cdbbd9d70d17133411a9e8c40a2d00a024aa876b5ab0f421596798ad7113904f4f2529e2f3f3ee482de3cc5fac8486bcafc16462c6bcbdb3bc0121ef3c924a7228e13067c320969e0c7a5c63e0c1f3b021d43d00de0f0c6a235040967145e7649a78d3a32525f088a5d605a0feffd9af602112e55a837e5781ae9980aafdbf3db98af5491d770de4013788d38291f32bd0b032d5ff27b507da724c998f7a1810a884535a433b127db3c02f4c17032025680f2022dfc0bcc6d8b0fa5d820fa67c00d8d7e2fe249f20ea0113ada97a46c57962ee90320261eb91730a8da457f18cbc403288806a165680afaba5326657b72a73165ec9b01506c68d87049add88f18195ccfd35f79c0cf061d78070d6307661f51346faf4280b41654f4c3469be1902024e2823bcce16d444fef0178bbc3f73c7d0e9cbf04fb055f7dcf98cc952a4c38112bb64a3738336844c5e89335c1f7637ae9015efc30f9e3ff3dbcadadad5d5f8e5581c4acd3d687a3b4443e621660c3cf7786758c3540008f2a3025458a424fb051ad94b3853170150bf57590e5c83da351cbb5dbf2d8e4e00e644b8d323909aff1757c98949f9fe21b6ba6cdbaafa6ec29796b6bc7617627c60ecba16a4e08b246e1f807d9690963d8d3decfbd274fa6f8b5e1c7e69e4f53297908e924e74579a717af5f30f3a13e1c987691f0c6e2072c5e81a1d5dde8dcaee754055ceccc8161015b17970f13cf4d163b25aef4a03b3bc40f7153cc4923b37b55c656632593ac5dd9c89e9d8a1d792a4d9c0f890f79bd7bbcaccf32000777b3c64c5d1296c6d423960e78c26f1b33c390f355b756c013ed9df9119971506f5fdc2a74b51884e62143c794af2c4ea125806a6ca4222d88fe725b5bf2ad3a0bea2afbb5d40404928e26f5d9124911b0ec2873256c4bb6fd4d6c1230dc62826a6f189ac36a20e458f399b55e6abaa0fb0bd3560c6315b723ff163d6af673af863399a6c37c6c0d9f6dae7ec147bd0e7f80616371b4cf20a033c1f36cd835bf83c1747011416ef43989692ca66441754ad89a48ebe489e85c5be91949aa71b0746879b387645a92ed90efa5c41ab6707ff897ce69ceacbb4d53188e54997216aa81bcd94aff97c187fdd0183794eb0b34feae11e92ebd3b238b92f2a8500fea0d97b3222427657708f43599c24ed201f702b1eb00072aa9063027cd5ddbd9325644f0c4e47600bbf76efd273557119901ceef5523c948ad90a9846fd049235f10566d29a07d672cc096b4c585e10f031557850332e455eda625a1c0ff1bd0987e56676c5caa1fce6e1cb4ed6bd509901f5cd46883a416b87ab68531e471ba20a62fa550d745843c730397856c7b66c4b233905cc3449f3adcda52f13990b18af9816d388f3a0370b57797520c11776c3d988a69cd4428ab362fdf57d93f9c1e817f7c1eee0d2d0b43ff6fc3360b085170ec8831468e5b7224529967fe3c838ae56d389359b1a600589ae88cdd19a1449bab9dfb94f2852d595334e340660037f5683eebfb79862a2451793065645ed8b6f2bb643fac807fd4ecd34b614039c82d3e68388c8cd854e8682a696d6e33b1d6fe4ca998ea944fb218fb834e3714b98e15f031a8458e55df5166fc7612aa1b77de06a9c95f3f232d21f942b725f2a13947947b30119a9c3c9e43fadeb850f5b9230be138c7f86fc26120946ac6ff16cdf250a60fe3ea6d73ab1c51e420782dc09f596ab8bd5be5b85869fccef8c411d6104e7c2104c91f5ecafa994dbc01bcb8db79571ec40563ce6f7c0f9d90c611248c1d11d19f4b4385d388ea938ce31ad27f6fc82b1ce0463dda049d83d75c7e5ad9ea74592285cbed234b36f781a91cff5c9dd497aa2385b189009a6be99b9c08b3baa0f9307b7c478ceaa199271935e1893c6a5519bb66f86ecb02031364df34847834ec35655f6205cac3f44a46b91548db4f6ba3b075fda7f04a517c994c522a30e08a7e2f5c45e73f6c61ae8a920c07d20134c6917b5254b57eaa15067ba36582d54ff3bed792a849eef56d3a1f73dcd08758516db72cd65198c87f8dd0f7ea91cf9cde9532ee440e7a7568014fe854a45d010ea55c1205f0fd46655d298710be4b20e0439c206da04605827fdf2641507f654f5ec460616cd73ed17599f30c8f5879892e7e049e1e06", "", 0, -1644364371, 0, "5037d59255ba254c1212d0ccdf49f8b7ad73aa86587c7b2821a831aa0a35c27a"], + ["8210ce4f0113d0e038c536f6ddb6d1f6d2f55997da1380007851d7979769fb45b4c8e3731c020000000652516a536a52ffffffff02a9f21400000000000165a03bf80400000000036a6aac0000000000", "6565ac63ac00", 0, 1435527252, 1537743641, "2355ee38eb1865c7156d59ece21775d4b1087b5629f6a64f1b2409f228061851"], + ["030000807082c403016df50e466e672944040dd45bc45d23b8ef8e0f88604e80cf224e74ed737e7db90000000004ac00ac65ffffffff014a3fc60400000000046a63535100000000daff0f7d03d19373040000000000000000000000002598d42cddfb043011d20654e0a0968446af0656f37c42af0e36288a8ccf387dde7c346b41631fae6a8b13ecd846e32210ae543bc08e0cf9849d4c830b02276eb22777b7ba63c72c0dc8a915dc682976d1c4828827c187d3979dd7b6272c74380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018ccadcb1b750ec46609e20d79a08369968de2d1bf595782ef7c6b1ab0bf4a9eaf65b8a42520da5c4d86e9762ed09d46856767fea85c6eed43f46f355f4a4154459a515da636174640bc1844f00804010fc5b3f2c97d81e4f47f88d900eb5de51aa88c536db64e06c9b52d7700bc17264ab3840ea466b1b36b4f22b56d9e7e17021d9de388514859a1d12485997aed66d3eee2c8a7b6f4b7ffc88870e2071559da02102bd3d5d08cfda205fefde6df575a1bd488beadeece1c3839b0b34fefb3339d0a0408037159023b05b92506b3e09845d8738dc7aa50a96aefb56dd226c59fe9bb61cf573ff0fbe3cea89e96eb7870017ce5a8971c7bf072a7084f01e5cf7c5e4b02203d3915587836c2294ae050fdcab55030da4dee7c811f713352930333c62b1202224bf4558752d465df3121cec53dc00a14622e34143d2b1222ef50a862433dd20200c15ff29eeabb88e9fbb33611f86da684813c48d53eb8c4e8485e9b25375613032a49b4bbada57cf187723f949d6ed7e03f53cef582fb3fd997f61f5333ca8902032164c6006b0407226ef436d6ad7a31d79651bccea37b1d3ee7584b37b921bd1290fdaf90b13e5d0b796fc765d141712e4f8c9245eafac9b7865700dc10dd37c2904aabc3aedc4bea963cb808c7b3b5e95f90614489add44eb4f41732c84cacc8f8119561da70987944b650400c5465dcd5af18b65b87fd38cd43a3c68119bb070bb8fbdbc04d6a295c23f00b9ce88460e668d113e0a9877557812e2d4c6f57a38708a5544744c4f5692fbd93a36d310934fac45606ede094f2411d2d9496b395ef418006e81d8597661e56254607a44e69ebf0c717b9ec2a988e534558d2550578c7d08c6e94a26a73f5d68b799354d0ec88d7890f5b303c42638c5762b7fdc81be3955b3cb802060d34d95f653bd6b8c56dadfc23d8d7715e90eea25df5f516aa482e9d6b253fcacc33024787cb6084235d0578024cc348d070bdd27e5e5af2aa3579c297f8c0931dea75b27dfed7931e4aa3a72330acebcb54a6c81b481219f884570217287fca57a5c84d494dd8d01604e857193d3832069453428dd5d2d079792135e502f820a2b1dd1e0075911866b1d56399f8e7550421c987d2d19a71e53557eaede02b9a5de192f1a890e9ca333aa7cf51004c205a3c1eb0fa1de6ca8042e7bd183557999f6999affacecda38a723b6ffe98d6860d52b7a1a560881bcc808fcf9522c559f3ab89f655ca61e0345e9f81b3a8982440d905a10ce9ea7af43c68544c3709fbdae0853af8392f303e6ab63481d81eadc9f74e5e66ab5bd1eddc1ba1b653ef448b85125208b325813f1ff89fe4556324f1de8c565f68476920bd1a7e7f429b416c37b517f954c9d0e6a2626bac292bab17bb4b834d0c9373b264f432746bd8c5f7555b7f37311f9bb1d1d070b35b57c8c21b6de39b2d99d84cae32c33d61de08947cf824ea445fae1b8c0916a8e4181cb17a54b24ba24fa06c5f700776e1c3a6f116b83ee8500a163792a272a7d1570c29c62e3aba971403aefe840cdbbf5099bbc0e1d2eb0997467641421507531858104d861129dcb003b8ccfb373f54a4d49f8824033c85dc2d99db740c92b29705e53d69cb8a49fb83196eaf8b3ef0a555ac1b1012bc1b347b631747be0a6f2c8d629b3a1422be177c254cb12c0b1726ab88c20253179c88f2453a956c09cb6d2f0b49c9fe9bc8bbe628b1bfce86248839076c7bff45e76db298b76e56f4196dc085382b00fbbf29b52db8e58d536d07dc9123bf3be5a89a0b48339003012fea087c4147e8e6bca836e84933e84c040fa0d88a2e4c3a556c0d6db4e43cc7354d0330a8fd1cb61ea8c81b394b7e0fb563bc65958cdf681bb2c55890fb79b72af214b613e024566164c34e8cc8f8f97376a55353650bccd51644fe5636532f20c0ad9b7258918d32b4da574cae34b79924d431e3b2738f2d1016f4216f1e37b126894134140867def5d8a7ba350bbdcd8f24d316669ff0e1b59a60e9ea29ddde7c1bbcdedcf827f4f0fb9ff6fc2618ca6d7be109f939b1a875d90ea37ffdf45aba55b6bc06432077377c3fa15cf59cc1ba5534024263468fa8b9c8d650c1d8b395acd83838da2574da61c9b6bf21ab359965df8d11c2700f90827dcb5e0465e8751fe061251c7609cb537b01fc0298841ce5794a24f272b7bde65133c6a0de5dbfd6d69a762c0f4a8d90aec1eb62b526d22d919656f7393917a82ac0dc9d1c7ba80d4db1bab8a032e7a4117436496302c5a605753a1cef5d026da3db5c83e002000000000000000000000000bea2f02b89899f2df7d1ea49c21bab423a00c7352b87ca18ca823c0ce382560378e88be20e47255c8c1c53f216c8440cabf3b1179bb065c47f9361191775481da3d0cad2775cf805c17e9691494ea9fc5ac2c0ef01d095b033d21ded1d42aa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f5b3bbf4ff5a04af5e4db6544425c621821e2d36a86d4ec817fd413f3677e504ff7fc0544fc08515272a5cfa7de5d4f1be8824d601e32d5179bdedd63ca0b33d5a2b7c5632a3139f290858450eceeb24ac7af4c8f7763c2b729516e515690b4ff6482172da12447161005ce56cbd25917390628c948f7217642f2f64b71f41d8020094ed5e55fb504f088a31d1a5f69a401da4fa6606f8c1aa292132d0612e3b1302012da5810fbd500e10e2f5eefb2fd1588a4775570655ba37c5a52478570878ba0b010dd0386edf1d2b291727f2085112620a27fade79b1fde454f325229806fb9a5841ab54f4db0b918520b1d0f46f8922cf3b8bb503bdcf65a04833574fd641b40311e193873a7be4ef621c548ca820e0a6ed66539b13e25d035b0c4b01dea9de22021d87b888d0ca714ff8faab26ff06c365f9de52abfbf18c1ad6e574418b70478e02277905cca615e1b31faa1064bc8391cb2a1ed25c332365189c8ced3afcb37a95020668e01dffae5402b8ca95ab0bc75cd9ee330dd8251d4415c75cf71e34cf397502073bfb069ec83773779c7e929b064df8ff68dd771cece9d34907912b8a7c4e96e082c0b970e5172129a46b9767dc4b460574cf033b49e0c77a60d86719a238b71c69c30d5e78f02505d25f6491898c10a68dd1a663580496f5e94245138415de5471fa60ef2002c2e670dfc10b4794914096a40f2fb97165b2cf3b1fe39c9d6a20899cbc8f00ac0ea9399cc7716ba23c73f7db4a4d5fbdcc8373cca933fce0ea9b621d786741669dc5d0911fcac5a9a5eec88d9f66c59a64848bbc34c923811700c430f2a2cedfd84fdf1e782e68250fc60bf3e1e44a607724424963a6adfbf37611219581313b7a8168425c99a5b54d040c21749b6795923d034a4aeeb1162f6e354f94bacac1ef7d42cf0b57143350099a2319a7f674eafc2a04f990fd610e3537b147f425e089687ee87b5e58577a8d34ce76242bdf6de034122734f700651b58ebe1525a86875d70a0f63c0ff7dd05cd1f13451ae52c3994f14fdb9d13c1aaf3a90380bdd84cee332ea7c93495cc27e14e27c7dc356ffc90d372fc5a7e17bcf8cd2b5e3fc7259cb8bf3d8faf6d05ee8ceab678c5bde60e865f0e5f6adaa6ea7ce41c04734dd020bfe0f223fdc9188dd8b213924a2d84cff04ad205064ce2b91475fe7a3efee157775fb1dc3a76e609585bf5574467c48c0edc32109f6a9824c954edb1a570c2ca3296ceef904139a9fb79c0c8aba0ce58817dcd95ebb288a81666d96a4c2da77b4338ae2955a9974752c3f4d18f8cd0d5a0be572e2e53e819e854ea7d7043c4a056e0334303b1f142e92175af48bb4b6852e5b36083a815544506244323ba316fc4b876f096e7abc78677832e68ea5eb7b136e934fda8af42543e1735ed988975a2edf034e3e982d44b180dfeb80ed9eadd40c08a2b61cb03992d0df450aafa3f461f53f35635d451155e2d415a0f3c7ae5d1c7dedcc41578466f7447932328aa8f2fd860f1c7b9a286e6eaf0efa3921e534d0c423c63ed6dac66345ebe6664cc0d34e6dabbd1dfa1b0f5a89f66ed2683906b994ace3d84782b987fb0a0c61ec55701d1c24d9207ed536a2745a19c89696449b7eb5c84522625170ad544b872b107fb92e0550aae445d19a6d48bb2a71e57bccd068dae01ee95d11d77b1ec18ca3682bac172bf08e7d68c671c2b1e84ef3e5e2d6b4df0de55bbb763e1115941dc23b2cf51fa87a86576bf470b3b0cce1bb3db79f48cf63e912f20ca7f9bf72f82a5fdbc1189ad945dfd9f3bf2938c9a541d4ed5bef30b7b967de674bfd20938a8c1cec059384aaacbeb50caec7a22d8862b20707f04fbe698cfd0a2e12127a7849006b5c84b8a34c3ee6d230b1dc91e47bd02823e6346989ac2279f86b9e687bbb6acd3de2e3c8ee745bbcf7323015d1e8d4bc0ef7dac5e6ac82c2f58ad74e9b69e8487e6a9e252cc6949a2876a1cd6af16a3083210ebd7b18e961b2c24b2752bc7c1ae38a45c48dd95cada79fd1c6abe465dfb64aac11f2c1f74a8965ec9d139670fedb54eed315d4f890f57d535e58ba28e0612fc5f9403a41b18cab2f1dcba1352e8baf9d38c3ba2a4e04c369f875ad08790ecb59d64c493af3f1a1e5b11db4cbbff5e6534f11ec0c3773cc7e033b980c6882b868e923bff6e3d0cd0b66541cf3eb484e081c5dd60d35f8c771510e1d61e3872d1c4fd91960e7bf7feaf8e721bf0f46e4c0fd0a5bd36a05f95ac4b33e13a264a7749e91200a16855fbfd4a14290b15cc6b822bf9731fd085010000000000000000000000009bb506f1700a0d1ce797813912cfe8629b1c830a128ea47cabe844c26df76ab3c3cd8a8f79be3bdb6ea5d4442f02ed07ad33fc98ccc2289a7a4e807566db71c95a332e4b621dd847e3a23e6bdf616c2eb47fa33172a18cb634b08882a1a339a500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efc0735a2e8a75d8f6a1407021e75484749ddc51fcd53b81669b63807e9de0e911d98769a10a9b0a9215a8c96b89d80de81437022f63060250a9c496bd90b4852660cfa2b2158654bfaa0018cf990c4dcf55c4fe091244a9e1c87e20bccc97803e5d51f796b13444ed1d21479a70f4264e1c2338e3721bf1630632d7c20690980306c66df05409ac8b32ce9256d51d11263ddb5c11033dbaa1c7974016e9548728021dac1b936b2fa4d9f598330a9d34473a2ec966f95d4284595a9d89052eff32850b00082f1331cb9c4f63cfcf6c74ed6ed27245ea8656e65d8fd212fbed5dee1c5229a728aeda1da055132f86eb4a88643e8a95c34a5fc1a54803528dbd4ca4e4fd0326c4017a0bedba94960b89c169b19a604305f38afd53b02ff4e5c3c5906b12b30201edf6c0c23801754afd3bbf6ea550164d716f337d61988c48942f960ee06fff030f5984d2217b768a20529429df7ceba29e227f7a2af9477169d86d178084f52303246475378cd6b44c18abf1a94b5679e23b0ec948015ec96ec32cd8e612fe409c032e512365359dde3d772623b98055380ae1c964f899987204f3fd7de4cf436b6dfaba0379d7c54337a9bd838069d3ae635a5e81ea785d53b644010c2900dccdf23f6d344c01589a8942eeb0d096d6f9eb17db8333f91793f472e2ef82f513f854b040c156a617280b3af6c0f5a249dafaa30fe57adc4050fff6583a064638e1034b26adeb6d6ef4055858c6af95127a90064f0f03e1f77d2f31055afebfd82c52b27b40c8918c60bbf5705015ba5e00bf9d0f1c02c2326011dd7d50b613b2a264b21a0d890f06440c2332085c3847380dd3623ea6176e74d9bfe6eaffa080292aae9c0e068ff64758c12b376062bf82c33bbcc082b52466fd7e7bdf4d4f7fffff1d76ff7c86e0867ede702b3006409088c0532978da702f7a681daa63d17a83bf08d287cf21aec6ed29d6b0f312d3273723bef2de071d2a243e93d3621f5ba6aaa255dc6c7913fb87944aea633e8c7521955ec589636bc2258a45f3c6b076edbd8d9233fb49ec936193e8b315be8e1ed80d0f4f9ac2ce6a13050f172afa123aff697ad5ec688cd5da6d5505c3383454a78810473c9a295abb6fe3da753aa0b163d1932810f341353041b18efc8125931cf5075e163f431f5676f9affc40e4727da594fd9cd86536ef91ea21b565f170b5f26cb1793bd9abf6b3308e0bcf47f22dbdf1f1ae4561cba146ade4d9c1a7b29c78606f30b7cf3619f50f0b24d517066cb2e357a25e43f9915593e400aa3fec815123eb9fca21a5aab206628ae9974f8a6c2310c071955250d33db3e482945e808aab81f571cf793efe153b9b2604e57fe30a1abf4ba0045a5ac02e36a597088de4b30d0ae2c5c574014cec07a5daa6781b80e9d870415cda3c71cb856b941e1298d4328bdce47af6d35ef7f845a22ea24882c2468ff5823b4cfc6a55415d1eb309e871adcf4c9d9d21a1674c0fbf4a7e10b11408c943fe436a7948e7ed6bb62776aa30bfd77498d367009254440e2de2a9d50c4afffa29bf988ded70a838c4f7ff0ff2eb36448b525a4cfba0db0f88e7a182af22117ecf4e55b78443c78b21e0742537608fddc3325cd3b9aa62de6885369761e2d25d1cdff8a42d69ff400b5f1f95c21fc5d31dacb006f44cbdbd9426483b6fb281664d507c58b73d5d38b740e6696c59d1471b2d085e28b050c72c608f5d9e66018bec2f419b0da180d8de63b9e3526c6f644e8419a52249d513075dd8277428b354760add376f09194d6be6e9558589930ab6ebe93655135dac775becf6b507647a0878c20d02c1b4e3fad2c96af5e0cdbd059c08f8f2135f770e6882e492cdd319fb2c22a388cb2bb5f1a842da95c781c607a6f598d1148f481afc386eb7ff8b3ba0cdad945814383fa4d4adeee0b42e3d27d46d9d3468afa57087da4fc2c51515ad969d02cedb54c6e00b3890871daa656bfa22d5171503191f73447546068754cd160b4f665dad5dfc519a8b1ced9c584e2ef93428db54559d54b9635398448b1da1fd507986fe8ad22e31c3ad4ff8414de8931fbff5c20a29e7e982bdfc946748e281202392261d8ea0fc47aaaf071fa4744360661689546c79f719134fff42a2ad7ec5deb55c7197fd4b7b2689b435a3ecadc310b8eead9211574e091206ef5a8ae9a28587dc46c32898f7d48238ccfed2469f362aa3ac9be2e30e6c8940d0e404f200c2bde2680f3d3227a5cd22545c9176fbad32f94cf3530c21eb1bf4c1ab9d55dde32acfc41de2375626d3d46a84e4d0e66df070a784ed4d8672beedc6bdea083e2608cdb47f9e1f520aac66afbbf04bbef5587e99b24177bd37289aaeeee99b9e74963134761a7e7f40ef0667b07eed996d95f950ee808a72093959a55a80d79069666c506b715808", "006565ac51ac6a6a", 0, -1209250835, 0, "603a903617d7e22fec9fa07ee1d281b95ec45086cb99a2f8aca729e3d1e149a5"], + ["5d18a645029609d7f163e89166303175877acfa80eea98272c4f67c8ae49ade2c0dcfc95e003000000066352526a6300ffffffff30d2aea4e0f01d3a6cd17a8efa2b2079eeb2936a484df564cabc1c624e49a471030000000153ffffffff02577bec03000000000500acac00ac8156eb03000000000463005353591869b501f8cab10500000000000000000000000052fb65492934179b90b256a64467da061ae263780d2f01e83f3543b3758d74e5810e3f4a0e01a038ce5c3e26d7cc6dd735147f8fafc10d76b4ad8d8d22c37126b56ea07a14c5b40978f6ea14234ca4718e1e80f2d1a279db04ae963f44ea70de000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003204e8fe0b6834ff168f09ea8150f1e989f8822ceede3d3abee750bd5f36e3a4682b193b98b4f0922f9d86b839c23d9ffa6ccc8abd9d62747d2475ae1c8ccb80b749fb8290fa4bf41e9df7cf65459400482993c94c4b2c9dd43f9333e3a3fc9621f56b443a100185369d5c26a660cd8fe258bf64240b9fbe298a7ac916b66438021096310f0eb843fae5f30421f2c3731d7a463dc1604432365fd04b0987dabb6f021fb49444a864dc4332425abd898efbe9f96bca979cbce8e2259a4bfe0144e6450b05084304f873122732722d27bf43f4f2f631f02b52d260626f4656daa624a767d8c7b63fc4ad51f1dbbc8beedd2cac3b3cacdf00004e2d6e574ed0bbc3514e5602167b4b24fb465416d60ef903302d98f2e1b4f44b534cdf79bfca06c04fd015b90219a8da681be5046a811b3f62ced863465bf4aa93ef65d506f100b6d64498b1c10217213b9847a92160f3f84dbcc02ce98a71fd097118a818d7df08ff261fb7897e0226a5e8e400cdf7e98fb1b3b991b98dc575e2ffe8d90d2595bfe455892d17479a0308b75d115ba03b353a170bdb86954de4c0845c2a9ee766c2c0d9a437e412008043238d7a59e7b4652d7c8e372b0744ceff4ad37e57432a7bb5ea7d22313826415fc43963e4a3fc59c15bb9bb791194c876694b63aa0fb5dab3cf3b0fa2d44fe7f8373db81622519299ec5c704828d155e9b6a0ba3fb6075b8aafdd6c76d9db640b2decab937ad664b753364ea95d6f717a2d7de4dbc841140e48f45bf41211b0b55e86a00bd538e6a1f8a9da55f2492316b8ca38d33298f62a525ed1b95387ddd5bdb8b43a40da71a40aeaff4cc065731fe5fe27cd7db650bae18fe604d4205d8e8f926e07e9cbb33ba241b173eadb30f2de80d2637f0b27f35e520c0788e3204a9ce36250fd3bcc649605509fbddca1ca33523764831e10bddcce86675bc4b19516f957a589975e217b9c66207a31044284b1414353e054129f39f787222c9e882ff87c05e4d63372de8310950823e494cfc2941a7844e874576d0b85831bf85bbd69b15bbcd0b09ed5fd1b8273e846dcd265e5dee375dac8314c33b10d8829ab161d6f57aebef9a8b2ed9258d4d71c9c64229c1677dac3fcf1f0a6e189eb1dcb5c50db2f78982a4042b5a9aa07201bf012891c36a941591055365df39364c5627a5ce87050e6359136d48a2041b8c4f48b2fe62ce304c96af601d28ea291924a46d93c5cfceb7036ba0fd8668b5cf54db8c6eb271b25c7413a07985f43ae2cf31dc6f86f9f7974a65a2c48e9ca567e4dcb6a81ee64c7833e08618ed70e0bb78186172addf1579669d4eac4c7f72c66e3f8e6addc6326ca022bb78d0580e2fc3c68edc077e2fdecda931d859a02142ca6b1a7fe86b342bedc2d720cc9fddebc29691ff8ea2f88518ab48de29ae2f97a8832b917c08416b45e8c93ada78a38f8fd394f56abb373815f33ca5996890c3375e7dfde21f7d06e3e4ae619afa17eb41ce470795f2b540d691d50b0a392f31f067816e0534a2721e53169099de84f3e6e5f3f9d35de4238c1144f262d8bb1cbed5f00af4526d96361c05fe48bf7d16b71a1f73f2d0621ef3595460a57dc6d1096b371de47383c60e0543334e2c5d1c63b932665618993a4d909c3304728f9f58dd378e35675c6d4ac7595e1ba3f2fc109dc249fd17a83ea298b3a2849476baf70cd28f147ca8c8b842bba4e1c905e57ac1830467e00fc7bac690dadbb0395db499d93ae8e11d40cbfa53a53715a8b9bd6a0558fe87b62e136ef9b739e97bd9d6b706b5365e62426992a68ac15c933ce932f7bba7e91e7ffb893e3f9cb87d9592fde386e15cd31ad049db979ebd86ae2e18090e71fbeb36f08d4c54bc987d8e24310367d2c4bebaaa4a90ec0f09dbb9e83fa3b1d02e201d2b8a654b2b9ab9e3642b73f9a373be5474fad2d8a67616f4293f5d6ac92d446882c8b479346a5c9f61c6e8ecaa5b15c25a4588b00115cf406c0f93c3d6626215f28712edb8d6d5b5f67f5ffdd38a8c4c4f976922d61b5f2f6d7457cece36f679ea15cb0bbf541549d88f4b76e9bb3cbe948f12643e05dc61253a7c9a011a094e4aeb776b3dd7c8a6f29a5a6b28631abcea33753e5b2deb8d819f3efafcbeba6fd96c2c6a642ec9f06375837b4e12593634ab216751748613ebf40c05f830c91481fbf2eab020768ec67cfd1f19215be7745afecc9009e67dee15ad7de69f400c5a44eb127b478ff14759013125c672be2a51d69637d246d3cb47bd545f9b2d0575932aa25a72bc718c88a5dcd2709b4bf3d262c9943cd32d6fb1cc1fd8e2cbbc31bff9ae0e16f9ed147a52fe5bd3dd898a47bf15f7c030d9fc5cd09c6c20fd96deab0dba2d4dc8afb002be1e7a621ee9d67e8e3af0eab7487a9d36afe7f87beeefe83d02da842d19b200d", "525353006300", 0, -1246051117, 0, "5c7693900f0edb72eaadd619ae974f01b4e39a498d9726949c712354e27768e5"], + ["030000807082c403015a0805951a8ffc76690b74ef503bcf45b80a70f6c1dd8cea2411680db2535051030000000451acac53ffffffff03b1d05c04000000000253accb7f0f02000000000563635153522034a400000000000252ac70ca5107099d3a2200", "63", 0, 1974096124, 1537743641, "859face0c1fda2ac9a4736d932c8ad2a1f6356391eb8e83a206ae4a236fc534e"], + ["e198de390220c687a5e23ac5d730cd1b74019ebcd52aa3fe35b2b094eb84d174381d6865450000000002ac6affffffffd904e034d44af34c5b45a6771963b87434dd2080a17569a7a34ba8dd73c6ae0d0000000007536a525165636314bb49e001a97649050000000001520000000001000000000000000050501b0500000000d80b32d541f1f8c830ff0fc09ae146165288363ae7fb0c4e1fa5a003bcbda6043fb1a1badbcbd9595e830bf5aa9a5df53a813c885e5ed52d548cf2f14765e2091f695c0a07dfa4f1bfc9b65223ed19232055c67efba1c1ad0319ba7f30a36be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aa06eb89fea39f33af386488013e6eee8a0730b6d6f12053eb29f98b81fa3205f37747de9a40d08e590698f6c737310ad86817fa55345c0e6613cbe4cc3477f3d87fccce72c9f083700d15900f0baac8613fed419165178e4f3eaf76fcee1fff0a9c5d2b17cdb578a3675521acfceb83749545503d92205cf47734fa7bee069c0208c12ae2df006f8602c8eec2fe1c00771c91f2fa6f9c162333fc6b9b29527dd5022e24c527b7ce9f783ccf94de7603e3471ce90b8356847f3f3aacb10f82c8be0b0b079a55dcfd0190b3087a417efa60540fea5e29da60ebd8bc0c1ebd26d81646863f4eb6e35a2d35794d69ba7469aeb485eeb45712c72125c1f2422d052f2f8e0c022081c07845c3d542372ed9b485c4d559e4008ef31e85165f2a05877ba0eceac0030f22d2522e0b91561320f17de60721287f63028a5c1e9570a07ababcad8861e4032ee5c9b701be169ea3abe489275a6e7d4f0bc7168c2400bf2e973c72eceb65b6021d3d848761668a07af794c7a0b5c2ae0448435d88b2f45b068a531901f55dfa6020f55f0585068f688ac1d070d6f2934b70eed6bc4d797a186eb9ac61bbea55859a95f5cfdd609a4fdb8b632f4cc22e79fbe80744e5e6a6c1195ba98d2406ff3ccf50fcba2a1775576c5ab3ad9d75556926b2b02bb5df3a60305952b4e3e20dbb39e1a1a9dc9e4e4470d8d9028a865118d3b8ed2ea2215cecc539bc7eaef6c2062bd5d4152fcfdc1e7ce2f43576bb015d2153d8bf995f31c01362cf3c0acee1512e89089f958908d00a219f9997b86945d298b26d11a5bae4e1e2521c07f6adc0561dac798926616d460790356d7671004a2870262f32e8c0588ecadd39da05cf438d3916be9f297acaa185e2016224cbc739e084b86e3b04a8f47786145e89e5cf28f259341bf8fabb642f28442b27974d5ba77012ea1e8f468821375ec720622323a1119ec32b86a5adb31cb7718b2aa67d11f0d6e785e3b531491538dfa488ee8bb9a18db8944aa97595d340cb905af894d1b32505142bdc757eb06c829488c66c681aaaa173e21286cf7ed8091a7b630ab02346825a9c6d43fd58ae0aab9c5ac57a94bfd8d1e5984044ce1fe364831af31406d00155198af7f9c6f939784a61bf9f7c06a4966e7c657e7c230a96b50900c80ef074c9841f405bf637d122b91ecb2df9d8dbadc9342691597f560c6a5cffd26350e5a613cbd597d4107088f06b7fc12f254f2661c680ab3a454cfe29de9ab9c0fedce02de54c7f58eb1fac44d7b182d0dd13d4de8c0016b9be16963bfa294aecd8b9dfb58ed4f3927afb7b04b17f65bfcf209b0a028ff4abd92e7cddf419a9ce25b459a59d058442f380a1453ddb01331bb1e5bfbb0fa9d326f13c6398d0af0415a179b88767b42df052f5d2353484f47fcdb012521b0e3ef033ce8f4a314fea6945ef2d04c2ecbfd406bda77d500785ca58b995ee2e7fc39b2993ae8c74cfdfdf6bd8abd6557550581c9a96e6c3d4d03d3de2cf69278be645abf33d63fd05f97737741da651328e1334d804481f8d9137a3529f148c12b17df0c8b51fd2d2e109bd861fc0391296c555394cd930bd846e322708d54f5e6d37e5c9e00fdf96ef53a894e3fc5f44b71189096b18c79c92938eb7fab8382960303b2feaef9f49bb12d8be47807a7292b204c791f73ca684a7b8210094e5f28f128998b7e425b3016ad22fc84400cf4f16262e45d3998fa8a6833f4f2e6291f9892e5133df2182924cccc31dc4cb7df364f8c51453e3fb7c8790bbc4b88e450a8d63dcf802170c08b13dc5860ccf84f8daf38d914d8dea2aa904931fd66b9081a2baa791889c260e99bb640926fbd5c39243aba6bb3c09d1d44504637d1cea9e2c12a157ad01bc8639e9a917a4bfcdfe280b2b4fb67e909dfe56aa8522bb613304f68ac092f97250b03483a95bf8967d97b50522084155bf457ca8305e0f25590cd915e0014a7d5f50d97fb687603e339f17da8a273c3fb4a63a36ef5b73a4478d5faa3cee775c57a5bf74f213cad1a037a08a70f406b95c0e155e34a3eecb47c2d0b989316c9aef3287017d2fd47cbcfc7bdb5994a5b5c1d1a834b692be684af098ccc38482efc63b7c91a2c134b784d67d90cd6d3faf3627813cdd42f21cc3bdf57373ade657c86338bb85a8b6908398fe35f2812eadc0bcf3efe661db002a91244d5512ffb44ea0458f503a78ad53d6d744cd2d52dda416ae22cba7e662a70366b11ef47748512e7dbfc8b6442bc811f508d04bcef0d8a7793dc3d8f47d5c9279225496ee5d80ebd47fdc482d670f73a12b61f9476c808f3bae6a97b7ac50d491500333f824bff2eb8a797683bb4ceb32f73f00e981c6b8b080d54295df7338455f82642c831ff7fa28329d8615b3c47ad61d2fd609dd1f9be6566f9a0c5ec99e838e89f00", "6a5163", 1, 1235525320, 1537743641, "6e6efbd55b2a9f64c6fa1b52298f5c2f01cdaefb12345be4fd0d6875d8926efc"], + ["c94266200133cce88fa56cc7fc205eb5773941db35e968de61d85b891dfd4fe94dabd0e9430100000002516affffffff01527ef2010000000001530000000003000000000000000019857d04000000000ee33885c006c5d1c81129202599ea4d2ed914ac0d45d31e8cdb6502eedc7868d379a3b746a95beaa4bf0bd21e2ed248d272e27e0570f30150f218d19df9345c78a494de26ab5376536043dd1f96fff6203ac164c43f152531a8e52729e9560a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b0f35e77c62f20185c1d2832eb41f95de14ab021e822afb35b989de9ff310ee9bca890a8a0ce725016c05b6630a9af3a90b48fe59921a3914295695d0390bf9cfeed670940d78ae0386c1d7b8643bd95a8b5d7cc8c4e692a865f3d06d5484f13b9b6458b1da507592546ac8c39159e495e7deaa800098bfe8ee41b1f0aafb896030165adc4b23cbf1cf1013a5374f7fbfa5fb82430bf514bf258e357e8def0b0a50226716a5c9f5726a0478fdc7f383255c7b698f11fdd9f9b7916a179f3394216520b081fe0d1ac6dcc11653167c47ff41ec79176c5cf029b13e284222a8a57d27398a588358e12a592565a8b35802c960de3b8e2287f97bc8364c26a891bfb2c64680224ff98b1670e4e91be5bbc78479f894550cf0f01b9046e30e9ed62eff2dcf6c9031d43400c81a4889164227a4a7df76fdea8318d33ea1578b760c3de0af1f23a6a0328d1411bf1a5132909d6f59ceae67de8170ba3bc7646c5293c9d8263efeed0930317e91f049246d5e7b11bd807f51f52ea14651125df8e61064d790cfad71f0f8e0323f98cc062e94598a10e85561acb19c119d07262a7ccc65dbd99407516cc9d233ec16ad2071ae6531c092a3a0bf5b0c27c119c3cc2a214b979d1bdfd990d4f0ac37ae96f2ccf777b915f46d7f4c58a878fe75a476a29343d5507b006220ac5dfddf98cfa5e17e0462005f1447baea253f03925cda582e67c7cef5e2f2526611506b763e11828c14259d6812b96d6490b727d28e9311a54a42aced57d57e43ef112f8e1b36a9686a40a0254c2651bf135b3eb856b98613c52fb03609b4b95e5caf4bae879ef03174c42873785aa4a680ab9f8be1b0127413807e6764f5b9cbc053cf21f4700c73bc0032195e17a7fe4607b41b4e1a33f26109427ae7ee011fdbfbfe4d7391127ea914c3cbdbf9478720023324ac1b515052dc9993cc36de1b03676c5390d439352ef55bea31a40580f5ea6faff75174738ad5eb7573e8c4012cce370a891631e9b5ed699da83e2a12ceb7e16e65d94e829e6c515d0cd8c6feed505c6b40a1df946bc06a3781ae5cdf7ec75796072df4f1b0f4c76d94c3169117bdf591a7bb0056362c0383a733f95d56f9d29b9c24d8b0aab03b713ffc696fd2330c3a19ebecf95421c5e90253053bd47038322c7d919b11df59e23a78a282f4b59612f38a8cbbdf0713b327cd45e7380aa902d4a30d0b7441da4023d164baf1f9ab10141e2ddf8c6de46aa7f1a7d9da4cfe6753c4a8d4a0fd66127b47fc9015efaa3cd905b110954d650a4d17861ed1f8e33f66c2d8c9d02d53470d28f334fd5b711d2eb33cfd75648d365c4c09ee7c5567a3ff4e6f9e0f70864a8f536ceab658b76ec1aadfb213f54b49dccea382139ee2bcd4e712c566de7493b3016163e76f5be3475fa8bcde13041fb3cc0ade52a5ed9fb774adc24b4f751217638af9a8b94cb90a2ce476df4d8774ce73bd788979a1685ff9a37c087ffe9e2dba69d39dfaeb1ca32e2bd7a14c48fbdce4db4609129f2eaf339db0e88479a8ce96467ad9ae575d9a73dec44785233114da3f9d3075da08078cc1989a259d3e65aff55fa7a9fcfc520dfa775e62fc9620ac53e0c5bc15c66c8862e9c59dd9a3cd1d0d5f0549c8f63a7e0916ae145839b20779e803ad1fe7b0080e565494cfc5d3c16f4a3f6b77ef0a23306d443bffc5e5550ac450afe4832b8878f9b1671cec9ca62f64e724e45e2ac878f84583d3380dfabf82576a33e091282d6cade0c1019cb7276ef8bcf0c4ea3f33a4a2aa5b3e8e8b7d1e18edd01c0fa3544a47f42fe28ae048452928b6d14a31ed638d97ce3f49812c78c15548acc45a70ea2c8193937e5d1fd5eab5ed0ed3d0dcf920670e18364503b2d48d48f5783808ac5c5fb216688b29b42158fce780ffe172af849172ca2155bdd8b380c0ecce95994dbf3f2dc0dc7776f782990635d22d77a65bde3f23ec2245eee4bb16b44bcf5efa2032275464613b85f5cceff260afe47cd62b3bb9c9de1e9c0a6ae96d882d7dd3ecb10648aefaaaa35f6fbe085f9a4aa7f6ca0b9e41df2a301a468083bbe1f13880e966a84fa178dcee72cdb2c34a43df3fc698837a7722e5c70da884f7b98b021260c95a71911869d3a7b7fc06f15e9207f4587052261eccc86ecd554bed5ea9968a5fd99b9c19ac292e33c12727ce887b391a6b6faf493940c3b07d7bb1ed8e8a0a2c38eb3814288c1f9ad0795c29317a49f98e3a3b6448ff9f30844a3eaf545737109f575befe6a1386f5df12963a4ec3e125fb8b705afc3cc500000000000000007ddf9803000000009cf159b769c8f7514c7b18e518f050c01046532d672cc63ba97d5da42a01b07aca69bc39062af361edf0ce1fa21183487fe98c4a5140557fe31716f7fce53ebec9019243a27261a4a69fef4638294b21a5fbc1ce209ab4d1a5dcb26c2435fe3600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013dad0a7a8bc3afd3fdcf38ae895bad10dc6e9b66192b3bcbfe69f4636b93cbff8dd72506da6a45268a16ba8c0aef8048999c819144b9a10646ebd9d81d86c3bf2c995a96dcd518fa864f424f5e72b954a8bb3efa57cb9348c414ec44fe9e87da5062bfd599155ce65d71161bc1ce90572eccd9ef8e3569aaab12de7a57787e030db6946bb2fb71fd5e84af86059d9eb76375bd0a8bc34be9fbdb3023fc44c91a032dbc31ff18b38ed1ac9ab9e19fb9a722b90b2f5a53e5253340668e586df3620c0b04458f41874c4ea226a0303bbab1e0dd22849d90ebf2eaaea396c70d1bbc40459ae4f3ba5c0281e366570fab7386f98fbc1e610b5f55b9bc89acfc5390b6e423020df4b33fbaed680f80cbef3b1d56adfc4c9d361c4276ffb930cb07f0af8e55e20329c5512e0869db1d97a2f265b7b1e03f09e2365f3d8c195edb76ab54e3722c01030f07eae4a0db973b7924a786e7ce7e9dc79d0d62e9cb94493c22d307a25c6ba603113cc1cc232bfb99687295e2b6330c3bc4a97c83c44adfd4d07bdcdcd3961c00032995259f0e6973afb2af718950703b415201b4890bf74f95ac19e8e22da486a7745e190708a0923e0b366062e22feb505cc2a24f5086097e55b1b6c81c7c64c65b7fd8a5149af3dcfbb0d13d224875373382217cc76744ce393a5dd6f3d31781748738c209fed89d6d6358ac665df8f43d8f4a777a7b5a7d840becaf24b856a2405fca6076982f43fb46a8d11a3a68651563f20b0c17f161a8a382ac04261197f3c83c4b99cb64c1a7532fe8c871c2d44e19577f1b403676ed99f49557020639dd49cd967591b624ed273bf83e36870d0526e7d14d99d553cce3bccce93230ad89cca3b9d427c3c83abf24f7124882ba1f038c507995e6b664f0b65dbab13d26473baf47f37534e41203b4cb1953a0b4c02757a48563b97dc619e4f52089d41a851b1473cc083c62dc2af253fcff4566c9dc96c59160b41b1dbdaa7d19aef0e8165ca829da3b54490e4bebbeb4444592dc0c9e771269dc2d6430e24dedd107a73ed6d988b5164edbab3ff611b2d9e53ad6e22876dd3a29c3317de8f8222b3be525a26b659e9b120aa10e603686ac1b172c68c453cd7f0f0b1f20f1c5e3d48fedffd83c469ef25fec185ff1e5f43e8f7250a03bc71fe175129d434130aae2d3c124a02a3a7efbe78087eb921d373ab2ab17f1e98e1d4c109acc064d9a5c6fd7237eceadada4dbc7d749e396afb463ca41cd5a483a17f5ca3115587a207f1db75c68a5a16ea86dd7b3e798b342acf1ff78926a9f6321ae13d396157c842070ea0e5e7ef6695d4923a725c8059ca2f15e0cf95e0fb3479bedded45ed7a0d5741e05e28880e08642d60799ab961624fc5f84a774e5213ea6969129e840a1930cac27171c300f6380edbb21b58cfd26f86cacf062c339bb8664f80de3eded2414ce59a63e9ac0203912f575308acdaa35ef8038d999769e4cdb1830638f13fb2275ad7bc85b41259e4a6482b32fd2b96db7bda27df269e867f4ddc54009319647953d282777a3d52e36f4ae8a530132da3432689916f7429153e8e15a5f6f953c0679e030272a66da8856fb96d6a04fe3096047340f2f7e5e87eb1058c087b6623a4f667c851eb6e4328a4183ec5c884e968ac4eefc8a7225f08e9f680eaf3441c22521dfd145852bb3d55346d7837712953706d6c8b43d3335422c9734f71a8b81cb9c82260af7de6cc4207af68872e32f1f5e6a384e7ccf1e8ddf2d317e0f8c018cede03175774f16d976a7be8d7f8790959b2eb4a95ab31239e3e27484a90d86f45b75851fd35d4aae596eec28994f7f210db9233145430b1d26de115367d0b73dea770330b0ada61dac22a01efaff8da0effd52e2d00ed84565d6363677b80fd957e09e9361ff6e22f02bf6cd5c475f6603760eccc59fadecfbea3dea84510975849c71b8e6e698e22b0707f31554fdff767c5372ebc9785d26666868a795bbd348177a2ffd868afb7abf9a68b18c41b72b014a3ee282dc007c0db7e9b1bcb6567c09d83e9b13e31c537b2b9a827386154b7f2ecd2550c425e0dc7c923903ebe175decbfb2cd130a14ac471df45e7fb24bd3e78310e1704ca6c5feb73169e08493892f1639e82b2ca81e6361d15f19e3d29e0143b2184785920338b828905327133072ccd475376f5bce499edab71693df74782e1adf30371024eede9e18604300582116b09bd9dcf5ebd102d48d486cf64a9abe7f55c6b2532920f3053c65ca572222f89295717bac7c095804f506d8dd5e7216f8602000000000000000000000000f40dfb5f6b0fcc1bdc3456e03c296107a47ffb6f4c8d55ec4e9a3adbab0efab9ddf23937c2fc169788a76926d254bf929be94ca39a17e5f1a381e3965780b26143467874c94b86114faf120e1f8c669d4b870aa329c096b4d3af2d914016f3e90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077d861e866e2c016218168152295348087975b5be40cbade46bbaa00bf96e836a8e3bb542f0c1b235cf0349bf3adb79e614441bdb183f92f8eff4fb0091c0caae66517424b7a140057c3f1542519026478bd2433213fa36989e470c37fe0ab2d153f9a8724d924f3a95125b11fbac2b9b9832188f2f2fabc40cef50eebfc85e702225635e30a34c757e6a8034a8d3b78e83b36098ecc71e7442d811b5cf23c48c90223c994a8900f1702f1ab1c860a6fca1314c364dd721834d8a1cfbdd81b43957a0a063b3ff410462a2623b9c5f5bdac6c1864c68972ebf364ad742d659defe370e8b01eba2f4ed9249ca86d11bd177a6d2c99ff6c8a196b7a06e515df95ee9adc810222176190d8c91f7d60b7c7c5955e3b8d4e459408a954d38b217dcaec79b904e10205d95b8ca028731ceaf7de478498424550e99fe08cb6c79a413884e1314e58530322194f6c8dd957df14f7cdd588d67e2a0517b51b7a976a8911716fde37dcf49d022b1c9e166674ec90446b65814a6399a760e16f0afad3ebd2d182b6e42b6acb8d032fb3b9eb7ae0e0fc65596eadc340c1ce0e778e1e3386d236f4928f3be86b0125cfe046a4ede3f38797262a255c729dc2c72add8ab8c477732e1acbc46b036342cf206924d1856073f47547e0fb119f92257a25d7153a10057a045862056d925b2427a0e8a77a09888fab11f39e47a4c5a3f1fe8e63beae002b60aed154bc6412f7c8777e9b8adc6f0c34917527a7ebb0befe09314895e463f4732e862c3fd03078c66b3056ba470bfcfda774b2f08b0dba37be78ecd157d1626cdc39124dde78d1cf8d0f852c4aee31038c90050e1170c65ce6a3fed3458ef3f1328ff1fc1eebdb6423b70de66a7390f4c7202e8c390d85bd375bc00944cd666d29eefbb099bcc62ddaa143a3023e2af5a36a7133bd51ce633ba2ac495c6ed13c4d05eef0f43bd9e0e5c43ee587ca2afedd65be0ee5808312f805fc8498447ad4ef2e8e24f4053a92ebe61ea873c3d53cbc327ecd06e7316ef9ecabafed8892e994148312fe8e03819fd3abb9e0cec4e8fb0190bda5b34a82d7948b72ac53be54f4c0b48210e2c462789d96c15d9b145b532b7a0c5dbc629566ddc442b01b14282860630bfb924f5804e6ddff01b2b1287b9d1ccc9f153abbffc09597a005a973132f48c68e806c63e8775df1fc44daeb9a6d1e10d72e46bbe78f435ce1a8c8c58eeae72443f40dacfbeaa5a562aa080c17167c883fcb795448b14ccf725f767c8cc4403d75d252d64d876625b6f1c44ae20b6de62b9de8369b20d58303e6378ed3fd05faf645077e8aded1763d782d46c6335da041573e99e216bfb59127898e7caee2216919b6352a245100de4188c1ed929b77e2da6425b125d4457c8484df0c58dd6866205edd239aeaf67e34e21c9f39e102de3a7ad6dcc0d73c4b45da6e224a1966e2f7cb7407e73a08c0aa3dbecb22bd4ce1d523bf008f3c21618fdf8cfbf62f7d2eb4c3aa09c58a85d9df7bd6520e4e4246d6bbf58aadc6462934c5e77a1b2929399fa7ecf9e1f7ceb7581d533a60d8382d859a6fce2619e70cae4da62abf015c82beadb639170cca867c7b69a1f3e62730aa339a54d4aa591cf20630f70cc47f2476d85104e97de764caa70277ce0550fb76cb2c4b9b7ccfea04b99f4aa01a271bdfd92dd00d872d3624114ce3ca9ea2161ad5f15600e89ff5c533e1d8cecc8e7f17e3ed88f390b1e797b9f72cef0448b0da665af5b28d43e961c60505226d31f2c126020de49c928e5d4f13bd8e59a3aa8259dd2a9d7444e3c631abfdb2563c5fcd6d5174aff266159886c9ebbeb9dc8c5e5a24fefcd4d5a017c97b5f3b4c06e4d63beee62f7564885cb1537e42a0353f437c5892de4ba46edfc1b615406095f8b018f4b4d83215067cd27bbed5d414ed7cf3b5a8af4f34f37b82df39451e5effd3db9919a94a12bdc214d6f55e31a6f4857d9438aa4bd53ae572a5aa02b3db57d84810122e9447c5be719be3b736428ec602f3b045253447290718c1b6528e532a9f01319abfcad2415e3df5f353d2d23a8227aa967fbd585dbf8809f0b2e067d37939ded9985d134617780264cc54f6e254f50cbeb058aa6c8a8359c1a5bf4dd169b605cbc4bd8dfd677ef40458c7c84acda7a257de9a6338c32a725fd7b85fb4f047d597d0e2921a7a4f698ad42940e6427bdbed4d8ea1630e94866434854a0c982e18f5bf2feab8b978f498282e04986d717e6fcddb8bb2b618e15a2370157f5f9622f1f7e547da962cfbc878e8773876f1a379f4cf4568f0b2f2121030ebd7c2df8f3b894099b3bf857ec5def50e409029d85cc2440fb997ba32d49f072fdb7fd74c7e3866598e78c82e60df1761304636e2707b9b49fe05f87ab338b0a19286527dd7470e3960bce3fa6624a2fc73080d", "0051ac51006a636a", 0, -299759723, 0, "5d84f838cf8091a5e0905ec9fd3c242f4f14606642f952649ee6c62bf4579e1f"], + ["8593b31a02ff7ec57a5884c0af5045496609e37d35b12928617fc8ce3daea1d66ff0af5aab010000000953ac52655363ac6365ffffffffddd8624db79d661c5d1605e77c08ed76f1c8c381e12299e63ff093731bdd3cb7030000000865525152520052acffffffff01a7909e05000000000300ac6a0000000000", "636353", 1, -1409998479, 0, "64087efef30e3b332cd501b1c4b94e02e194eab26a0595286a6501f9c04917da"], + ["2323a94204f29d2da0241e8f1a0d5af9f4f38d08185d5c6e771dddb40b95c818e013cb111202000000086aacacac6a510065ffffffff94294a8863b3e2d55dc24bc7528ff437f9cd4451e95f1b0925cc762b5df81643020000000500516a636affffffff210982018ceb653cce67cbc644389ac25b271e7770c90795f529dad054df82d100000000046a525163ffffffff21bdee68628be3b281bee3b975fd76357c867a6f56872a25e4b4fc091a2396d0000000000100e1fafe080229c1df03000000000200637937980000000000086353655353515100ffa25486020000000000000000181c12010000000036c9390b2fc0c26ab6ef448edcc4140ea40363772de8ce408d26dc7d5917b18e153d6425aede70f1ea590aded59419399ecf0503719471836258550463a998b50ee430d0c7782792357134d8ca7b87c458c3a2c70713f678625c7b4b2a536f90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006866c7c43660d1c68bbe04a363f68b8dc0e621e8ba067efb73de2605801cc7d19cd0eec413d919e4ecd4394f00ccf521a1fa60e8b6b89099545c0807c35704c757c91e4eb99e82d269f598a3c0b8bac93f33f8b0f17f150007d68ca847ce6b2eef4015e589640e6b07484329920d1f4bf492db1c4d5011f73f1447f866b6017e030200e7984ef3093b136d597f14c8e31bb0642b7112bfe0bf1c6386e78ea87268032b42d08df94e9b0bc18230314152ea97ec9e56246f64885a85d75447516de20b0b0861c073edb3bd9795fe739a6ea39a2b8d7ac3fd7e36d4a3e8bbf2d14ae366d2fb388ba31aa55cbdfc71d30e6e8ac6b6b46ad1900470912166f57f94221e7fe4022774e31bad4a7377c16a6d08f16856ceba8d41f8e007dac949e87e9c2d5806d1030173fe5c0e3171a970b273fadd0cf701edafb1e2990202126ae442c4b46c84680224779163a54fadea7eb99be4bb1f10c1ccfc8034caf0e34d27f6d7317bbee43f032eab307f80173697c7fc605f3d3813fbafeb622d061a1ccad3efeb352723665f02097d77139fb53c06d2758c19316b153e9959d9cca981328d3264a3e6511c09412116099b0506335cc21f62f822e385a06516174561064dd678f9346c2e0daa01e67661357a39ef98f6510e41bb28508ca2b4e38fbb6a0da1265627e74aa1dad644695f59e88088c9e97cbd8c402065a59c0cf812a3421147e8aea5bfd2da83a2ad1632e6c85f4d7c5f702c5bdda4579f76c75a221682b271576ddfc96c336b89aced9bf803d11bf7688075936ef6686421c69fff2e68c7f6ff53bcac69273f4a4345258d5ef19be98d4c4dd5d8941462b63e35dc4d8d24936e533f7ec91371f0cbaa9e24fdf4398e3547a0bd50369d9ac0ae8338492cf84bf6fbe7187e484a7f55d1daf1d2a68952ff892159fb9bc5b7c7230e1f040d3ad82f7f02de4fa83dce1a334bb6b7a2d226ecf0ba8b07f6cda7dda4e98ec9423e8e0c40f9ed98e545aeecade7bfcaf4231ed03edfd550a2f968618058a08fa16d2d37c087790a00318cfeb74555d394468885d81c1d3086ba9d73a59f1047c3114be74a92fdc69c45de094e7a29b80bbcaf62f5e78c4a845ce08904bb686d44bc519d70f403b7e0047a36da18e87a7e73e173566222465930b61394136f5b730b9f558efa6ce2a3392f3e3536e340bbb34c5b032730e2253f517ab4d3061cd6c4a9a79c9729e968f8a8cd535471a1adbf458663ce109545cc645f744186b5e749ba21536b3fa7489b366c0b793c000e42b71b8b8ef26f4bd63c5ae939ecbdf0697456fe17e38440090c7fa042e6b39a1eeccf1340c76f26779de5547637b49fcaae66bc6c1ca36cdef73e9337b9aa2377345b4a203a5da45c84096fe31fd1e7768eb452b5a00691b6b93cb26c5202bc5904047f3d24306c0d44a631778e3df3eeb5c506a86985fe2f7d92ac1fb483ce1c520696bff7fce2d7690992811f9d7a66dfd7116aa6ff54f5e9c0189ca2bd946d6b0d3f391afba9cac8ccd4fee2a089f1c57ec9c66bfa35e969c4df23379461176d659a3e7bc8a963fa0b740d4e91e7bc54b5a7ece1b1fb2d244064f957c2153e862cd82bfdb9f5ab24e7a7a8e85613d57a760768becd03af5acc95faf2f8fc6fe047178b463950dabc11c8259ac6b884bfe9674626b93db25616219298d53baaa3a85f4859a390facaba63d0fe94ef17307829cbe31278ea681572ab38eb10a2061b050c92306ce23bbb4d2eede9f67d7dd8ba74ead1e13f4690d92075a9f4d6da5b8a00cfe3d821ce0eb04b8b16d8bd3bef50cdc2fe3cec9d9a5f9bfe6595b266749ea022c70953f4a781e17baab1c6625b196bd93f654c76f5e346afe99b87dbe0ea5e9c701f0916b5bd857668c19370d15e0d83e6a0908f383d0225da40af48a96b5a64b21df49cb584aec2419adf0de8a2b112a39b7ad1c83f916e5567df2c43044dd8c6a1a1a88c8e9baaff29bcd48a891771c1d926b03f6380534eca581ea5cbbbbb5cd7c4a21cd5876838029add9ec555af9569ef2e83873f7294a6bd81fd76e1f0642610f932f8c38e9379881d240639953a8c50e0e00e15a69347476125347d33218f5e64e81c7a78aec1e37f6fed58221f6de868a7488e5740ac334b5711679ece1e1f744cb91813edbeabf4eb08b01f0d7236453cd5bc593b84ea9a36d6d48f2e0572cbdd3d7e9b82b4e8e0635e6dde9200d9dc6689de832fc709fb6b45e316e756064ebdd404a7fc75e22b58370c1bff24b3298250a52f51e9d46763c152455175375d9bc8aa0f4b03000000000000000000000000aa9cdbf299fc62b8600a2b3a19fcf66641515decd37eaa2e5a10694e4d42af286348883baec69da1c3c278faf3230e8ca44fff3e20d762c67348c16283ee7fd164b5c50f264d9e22b8a913bbaee81a52ef1b80e24b02e354edb24d29d429f3de000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009d3fb6032f9ab428120d0538f47d4d78c198040a04b865021bb8d8f9e2476d0ca333c2df441fea73f3013b97ff68efed8b38c255804791954ca5fc6a6d1c6c8253977da8bb6f6e76d53ab7f37271efa4ad417caa5e35f7977510dd8fd0f1c8d9737595b0c9ced6d7723e349a2204faa0b1d3c76d5f7bb7b00554ca5dcd9abc9c0325bda50813f0038359d91908f905a4307f538b740f84090590be5481f8d8e36203065b7b9b47e379e733ab5c2877632b6877a5f88d71ce63fb532ce068e6bba00b0b028aeab2ca9f4dcd97d53fb6df099e73402af12855d3c7350deccaea6935f63145f9421fe87797cabd295c3b6a4be5c5177fb5afe0964cfb7b8eb245186308ea021261f4619d7ea74d7c08ceb0d4bc06adb7652c44fd309730977b6decc5e756e2020c0306fc5e5f61c1747c88ce02780bc95908604d9497443a5256ac03c1e73f9e02242d51468a733bfeb6d4b4c7555c2a954277795cc6cf351e5b1e90d8bcf2c7520224626aba71ee64303e2b38f78bf9082123f7a5c296497913f7afb87488d5255a030bdcfc1c3f6add59fe43c73042dbd84494145528f7dd2f35b6d876f137c3a93807a93dd5a8cf7e27fc118398f18d3c72e88810958eb68c5187e4454be2f6a0f99805f63cd4c50ead5b6902ed06f027c4fdedf6396aa0206028ef16a4d724b05a273169ceab782e107348e34cc9f9c5626ce74cef30f04fdcf7ca24c3663dc093bd3486bedcc75ab07f2ac5113539242155b381dc203e2f6e3e2d303b44f03c84bdb47ee3880b34e30bfaf76225fb53d3d22d5b595b56abb864349260b528a6595a62864d06b995f97a9b191f422c213d2cbd11d712d1c7d17f4c97c269d6a0d0bc27d03b64327910380364f89f8390cfe367eabcba545178bdeef80991b0df6c52329ff2c9485ced0e8b143900afe113aa994111de1e2e486ad481f7349e5915e1d3bfd0490d15025edea4c70c52c9506914f0fa4c4936658bacbb65f5634b525aa6ecaf7a3c9f7caf108cbd99c06ee1a1267a278568d606a2ccc62cc27d8df2a192de1132d85095b725de61ce8e75b73a97c4a134fe7e6fff220794470dcfe3f4555a12edd52597fc891c4039ed8910a4f1cd5f604d5a5e250ddad3e0917b9749f7fdfbae5cbeb3e851e5d821067f0de54d2bcdfb3eef35d4f9dab5ee8df18b4b3315e457da67e81b6de7c437a7df91bf0fac47f25789ff50c983f077923dd7174511698376b9d7801557b3997331396b87ecf617bb7ff4fdad341d4bef9e139a9aa60a482fa3d7b8574124fdff9f746dafa9858aa8d7522ce94345e408fce12bcf8b24445d2508cb0aa1d94ca9d77b28d3aea9be0e10d04d3642bc988ab1cdd3d2f1be35c85632089ac717970c91718dfd7a3a906239138c9d022af119150f88ee59d26a46f0e1423781b623eec5a8b97c3ca91de3ce253a9652a3199f195ef2a1fcf18de0ff0fbf4b5130e10fe743fa2e594b6260c43cf673718211936754317b9d06648e1e985f45f2f7cdf1d67f7a98ea695a7aafcf77a65d6b22abf36c5401515e84aa5328552bf1ba0207c34e06a99fc4cf503c2b2fedb38b7d92a8b8b66e33eca54b708ad2a5d943a1163fe8f86bb13762a19299d6ccd31c7d8a3bb4b389b277842055f82e96a896c097ae007a05f0c98dbbeebcb9f528e155507430bfbe0d743fde24a856e61db70a87d3421fcde5e3a6e43326524824fa165a5823bc48b340dab7da10f7832b34213fa2b2507f3f69a8354dd2d824d23c6c8a70c0a0a2877a299d95e0a51ffb22330974efc5812c58105c4a39efebe5dc5573dfdf18432ad5a73ae2ca03123f9f107e1f3c04916c49015358d40cf308bbe7c59c70893fc74c47f066618f924d5b53780fd3bd97460d9e975206f1ec1349459f473455aefd11c30622459b224804626cca26895ef33950580d05ed178b2c25d1424fc5bb3b2445227eabd785c94ee112a98c2e4280aa135069ab7a96a3616ba32cc090a27db4b023ee5898db8c93516c975cde42ac2182ced5d0b126581a85b78621a53796572d0fcc32e60e6a4b0699f31c988cc86c37771c0f044bc08aab8ba49d05801df9574737987eb205ac82e821277d2d8597d90b3cecbdf13330ae3ece4a2ded2bad1257cb7e1afefd7028e4a7a28f0a833e00ef1c1149bdc97f44a429c0be78ae5168a2ec5b385c59a32f9609bcabba07e8b644a915173bf6894d243fabe5df82a504807fa445a16e0573ee4f5e98f48f4e20c5cd014013588eb3b21fec8442a411674463176f06599180d377bb747390e78e08120ae77a09d5fd019606fb0d172c2b537bc242e7bbcc19e60db6070f582da548dd40b22fd503956f3ba19d4b815af560dc55488e7eeb324e21ad2581724f43c194325a5deef3fe6b0358d4c8e5c9920deaf325bea24acd6d65cfcc07", "65525163ac6353", 0, 2140922588, 0, "2e39b76077c5cbc3e5cac53bdc50e780220169ba4e6b4a2224ff52ccb08ce0cf"], + ["bdc0300602e3c431b18ea956e29940b3b6d51ff513e496b1e207f2fbbb5877a54464f35cf50300000009535165520065005363fffffffffe30ca0cd06504d7a185ddc0b8b01dd6607764869e917ce467314219063a16f00200000005ac65ac6a63ffffffff02572b8c040000000000d06c1d05000000000553535352515c63635700", "52516353", 0, -680847213, 1537743641, "8cb179386ca061991e2d7921da44a8ef68c1079ebb824a0dd84582c82e77f5ed"], + ["4cee7c4601443f72e86b86cba58483e7c4aa963f8e3f582b6e6c24929f73575992c2f453330300000000ffffffff04049a3d050000000000d8531e01000000000553000000003b9d00030000000001ac1be4a4010000000002005100000000020000000000000000a27a8f0300000000753db64aa3e7c7f774b181fb125c555c3823f14c6bd8de96ca6f7d10b7090d03b5d5d4f3c6679a017e71d1e2c24f43490f6bc45f3036cf326402ffa2c759631fba59f7ba5eb2a2305d6723405eb5925189fc668bee52b79b5e7ea826c26d4e5700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc0e03a08e8c1b8bec6234a06e71e1d28ec34c1286a8ed1337f5ca61d8911ce1934ea1ed8eceed725a130effff95a00c60e212023c9ba2cc66bd4160bb88d8f971cbd810c378dfba8e7dfca28a02bb360a6d646fbdf6b76d6a27e8d6face3e05682e5b69048964c4d2528b39e9f93be3484de9263e0f971878c38c6057fcc0990226c191a6b7978bf58af811f5ac72b7f096630582887015022e3a20322c3761300204dc1e4603d290753579d0af4dedbe5ecee65dd9595e0c41705a346ed14a833f0a071756b2510818b5fc7f0310ba850831a85d99753de27833e24ee3373616a640502c776199b998c60a8ae6a0714723d431fc0e14834d6669117d2ed7ee78c376030dd7a97b1b3011054393fc6776f7e2c3fa568e690ec56d14a69f7fbf296541f5022082a982d55b20a3f8d963cf501d8b082cc3c23eadabb10875c50529a7ebe78f032573ca1665f31bfff7f95c0a4b8cee1cc99d08f306253f0bc089d7c7dd2819bd02198cc12b7ee7894bb243994be29431ebae5a16bba15c65eb0869cae53fd58219021c61aca366aaded833ba8a059a47c22ddc1afc310a5b7beb2e6766ac2c0d057cbb34c988e8bd104f65b55701815e8a55ac70ced620028ee3af1092ec0e7917349f7ae21115c60ba20a22f106d674f51f74b51b4a3dda84ec47ef87e3a409158392c5666343a727279869ef2348628e7c7b8c6e74b273bcad6af2975f28b2ecf8145cec6b352da78ae377bb41f9af2a016eda61a6a21de8534b2a1e79026838aad5852b811ab06a3a365ac2eb9e64f9e6ce937df48e5d82e0122562cfd87ca851a7af9609a7498ac2b5a468e85f7ab1d3ff953af11a104a49c7d68d2d39ed77554a60a66efc35f240b1e9a2db9c0b12c3022b356708bea1f0403c010ef9fe5d2f355663dc4ea58a809e3207339212fa06531375798fe976443f1828c9404487a2a95889c773b61e318a715956a52ee20b89112de642f25b70175f71f82374d8d44089b64d8df49b5378656a0983263891eb0871721edd52d4670327c7b3f2f88fae2bd5322bb59dff08ad5c0d90b53ca96e8fd1332c727d089ee5f09b859744423d3b1c8499cd9f62ddf6f71e4e1224b1e5250e62e2ac77f9afe261ceb1d9f51f910f86d2324f2e630fdb667acf27d801b0fa29690c7407a78ca5da9a6a350dee6eeb185aae655a5fbad101f5d079906f12b5add7e9b0e901d831711f4c87da59fd4449513d25e2de0cac0061b0a5b556709757713d582b219ebf89278b7292cf4608d27b44351eaf2b94871d9b3cd1fdf19d9c97bb683abe5cd1995be126666ff401c4a82b72b5400995e66947c3be44b0b594cb6ebd3abf88c9af8aebdf684ded600e5be4fc340bd7b2c5aa08b36a2871849accfc98f280d02f356b61bb584be5404f2611e56cfac94b474a74669d14e9cc3fe203b945d3233c349014e38f0735f8f15b06cb13fc99c0a3b0a56c4dcba612ff65d98592c4aa32a10fd8dfaa9271e46fe8dbd7dead85973c138b5a4c42a41a81fae1ea8020dfeac0046d81a738fc238407820027fccaad87eb79969979932da11e4715c55e1bbb1b52aa7f02ac85e102a011ea89ee5d7654402f089e58e52f56cad50139e202a5a9f2450d4a29e7b4689efb26cfee5546663ffb49de3f0a090cc8acebde00ef1f6e79d5ed894a9067293978451af1cc89fcb12f91214f983738ea99ec031601e2885822285d0d3dae60b4afe853443e54beef9ace5780d99e5744044ecfb843d9630be08c8bb1b2f235e44dbcdc48d6e0cf24475e1afe72d03ebde2d94944a31c0ca26580f4e9cd6661687c28f0d65fb86b756cbfa2b760a1b39d037bae8cccea90c474f0447c81d0ec467fed9064069c06cf3858c1622f54ed82ef5dead8e0613442ee064c53751eb0ce3596a65c4973ca5d73b910e82272ad13032eb216f3684e5ecccfa4c5d54425f489c80e2dfb24bfbb946832ae54edb2a2114593f7aa59888101002bb46c2121c3664d6e3231d7e10e4a3bb6bd69b35df5b76e6f07d16d45d360b4fb01ed61d969b8df0e21838eec70b7dc1b462c28b1ce56bb37a22b71735aedd9cdd793fa2d5835513c96671502f0cbf6e2c2d86c7a52364650234bd59f637ede06a499acf47bf499050590f7caff3c93aa062b96fdebd3baca2d990caf5314374ca5aec1fa4519b42e04b7bf0bee35cf6854c82f154740c74be5d1a6d88b5f39122c497d883fa48b3bc54e7df2d7fae02299110874e0132987e54f238df4d8055909a5fc084634b9b9157b237920f21a477a85fb32c2c402000000000000000000000000b2327e6f2f897adf583ff9e648917e655598f0efaa40097d8ded07ef48c4a2bd291f78e2a84006cedfefe28a4c2f20d8439a07a8cde7ba48644faa50a9663e8207b41d5a33f747bbd3a1431e46d8a84ae620641330ab5411268bc7904942bd85000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dccb7361fabed62a907275e9925534e9712bb63889ab90020a028c58f96785afdd5d29a5ac91ec96fa1625ec6d1b082570a56bb1790a29b9a6de31a763955eb180035b0ba30a92e7542e3f9c7b9518e6b85861c3de707612fda6a51f6b5196aad726fd77c9fdc1b2d3189ea2f8d4cd7cb54499a1869e6426dea3e4731c98948030445c826adb7a56bc529a7442ac07ff1211f5cefe316b421914e3314dfe0f785021f7f86460c89f5449ed1e37e9ffa12b163aa9ca65ea529b968269bb4b20401430a07cede72f923fad495e8967a79599f5731eacc9a3af86caa0e90c92bab9a7deed23a415565d1347840c829ab5c52dcf6005bb6da04f7246cbda8f58c872cc1a20313fbbce3b889b85b0f0e1c611a9f074fc1d88cad4555b48565fd0a4b7ac6c6ec031e3960b8509b62970b5c97d0d306509067c2ce0401c5688eb40f0a7cc4bd61dc030b15b764820cf0b90ae0c3d9747236c8b56646f0027e953f41a31cc2691cc9a2032b6ae3d7371be99292096f5f1c1040b7a43ca54984eef44a611f2c02ec02c8fc0322d4b54f7769ae60d269598ec45bb2781385b2de4fd7996736e7460902aa965a0c4c8d414d53ff8208fd91d67862d54efae0b6822ca384e40f218ee4af8c1d25c130a2818d4458d0ae38d661b7b5dce4c01df124d0216f11391220ac0f192f20462234b525f5929b7af7e85ebfe59be3f8181b4864701e02ea679037f66202e08a4e58d1bb9dbbe295b3b3dd34045c94f8d52ca51eaadf5ddb5d03d7833c96c1e578c8f7ca70e155a4e0f8bbcb0ceee29994626d20dcfbe15d1ea6902d02b1cbe6149da558c27632865c581a7d28556d9bd2d75f73024ed8c2a68f715156515f5d35786d202d09aa807abdfbd4b957c667c236bc4e2e5ef982463a8f94bbe1c2e85e17bc1d4135c23f5bdc8d7baeb55840ad9f218a0ec7db175d9c220a61438afbedcd8774de26e7e44278f3da5c3fdae818bb0affab97989aecbbdcb675ff2815394fd24cc9c2b5e54cced781eea2c4e57bd4dbce5ea8047c4a3e79b0796377edf7bb6de16b97153a4f7f2956c921096b5e696b1124bbca4d940c8330a1653d03a9177ba51120866959124155c9795ba8e3002d45e6d330bc22fe0b6544e2e950a5f48a175485e9b9e6c79173857f5fb31de2b5baae567f0687edff4b778dca6abffc92d0938a31b53cb73cfb4a313b02ed737e2f42fbd0caca097fa317a107bef246e498557c10a27bc62d1c5d47c85157b0ae5a3121c30b88e4f981517b47332e2acf45a73caefb097c9560160984292937f48ad5551bdc019a3a1790c00c388cef7260b9710ce7cb1aca32a558f04f5ebf75401389a39647fffdede118169ee0e0ecfaafc1142e68e78437d930be07ed620187a9cc8ff18068a20bf2a26b8738f84f4acfd2ea241623e6288c6a5ebb0888c150524b7a7b3695bed342f750ca5a59ac25b728c8eb114eb30867dc79f832c2f8645714d0ced8ce8f8cf4eec60a74f2284384f14f3cff2e368d0a762e8928fbad7ab35f149e15ad722975e9716029b934ab48615805666df4849346bc3c318e73dc2997e7a07a3b69d8215f009824977b32c5b49b67f22e2f72cb92fa6af797db8f1c3bac21f1bdf156fe061aebe8c57a2973563578d92ceb2b50093bd50102a4cea2c8c53afb9e62c99400e961159e36dd93538912c501075e86a1bb65b15bce829195de0ce44b2446a26067c87cd72bc80be6dd1f5d7896ceb0c3ba4ebe236b9c6f1ec4fce4e267951accac1ee74b199f4892b0734e705e1cfc41ed59ef4a00e5df0166f6e8d09a7ce18a37efe8fc164bf99a87ee71fea37315769fe6a92e596f9f6105e0bd8f7280be362294675da75f6dd39ebda7e3994a2c626d8435c839a947fc67374da7abf1c8a025991849ac73df21b31096db8368324a24dd3a958db21d668d136fc9480b85e8c7e9df708a10d6dcdd0573fffdc05f16330f54a29cf00f4d07a51b3a769381f40e43c6e9830b22deef192bb11500926a4236aa66b2cb1f57ef8394ce4552a3a9c1f27a13f317cc4a812709298ff3cef8f7a6f50a4e6c543a249d30508d3bb48ede17fe7a796d78fe8b7f4bcd5c004a6494c1104fd60bb81b4114b43bd3747e6e8e8d5bc93a914efa496507a6d36fc86c27e2302f41b5d5cb37c30017c11477456a7a620048d75bc14b98014560972abcf32468de16ecaab8cac4aaa9eb6d4784057acbab78215b9ea665a5470ab34039155fd6777d2b374bf3dee5fbee4aa1b6594549f1a94cb1ad1b7a34485373e5b8461fec8b85e6b1da30dd642d5ba31e337c955bf9f6bf27bc93552ed3145b447b8acd472d60b66f94d8667e5151d4bdb9913af2ae9fb9440eb7b3e4d119223b1356c15674a674bc044df668883d0cab68e296e178cceeac85a610d27a0a5e81df049d01", "525300655165515265", 0, 710671951, 1537743641, "91345f2c78089bd583a5e2e7321d6c23280eadf16115e43482b4a66839ab3443"], + ["030000807082c403025efde018dabfc5378dd71ce06395174e80ee038f3cf3fd7ced6d5cfb6cbebf890300000009526a5251ac6a5100acffffffffb4ff330143f1cf3284e2b4fa55a955522d254bc25cb66e30603373bfd65a9882010000000165ffffffff0379d931010000000004005351520465630500000000086351636553515152a399e905000000000152000000000000000001b6ba5200000000000000000000000000547957fbb816dcc3b367c78df5592ff317f714e2b00dcb1a81f187be5ec3287d6a110bdb273989d1e5252062f32e7c224db6d10f9838c278a27fad46180a94aa12aa965460172893197cf793f1377d494410d277a78e7233cb50c80cdad029dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e924e443384abc5953ec381001dc8d32d74ea6db8b129747a050c1a1b1bc95a95606900a92dd9a6af31e6829afe60d19beaf8e96f6d3d8ff6b0dc3bfb47c4fd7a1b7c2503b4572b320c0c534bd802f7ee4c766e621a68e09a52c899754aa8e17a7f53d2f8e5bdf812c6596718a1389d5402f01b4d5acda53249210290411b6030229554de30fb5001829a66dd747825e9321f447cac2f16e396f0ea35ca9647d1f02106c5b87e1d8e193018123eefcf6e6c4b208c53a02666eff34a8b0693efe6f460b02a09cd6a3cc720aa92bba0148e9b591ca9c816eb38724821032998be57244946a5c8b4f0f1679d244f2896ae638de7b3bb635d5d2736c413c71344cbec8062f020186b0ff97dbd785eaa4573138920c8a7e1e4731db9f64120f0cc5849f28a47f031626950a018c114934fd7a997838b243b17520d997332e2efb4a31b127bbe0cf020f7aeabefe410562309182355d0bc50d0433d69c0c543c2df60e854f0c422a320304e1698bef6eeb1c4767951efec232f30f2de2ae92dc144b270bae99455024e7030be72cf7b54f3acbfdd477fb8463f69fc78598f4cbc5477b31e4120cecc16529c1ae0b585b7a3ff79362b5803794936338608b52908fa24389a8aa6dd7138cb49c6a7960dbeaf450b7264c505ae9ab57f6e98ffc1dbbc6e16d63c9ed7f2f1674867087efb50fa47c9b7e120f35c096578c73c5d4a72c4b8e8f71598f9f3810424ee3b70f626af91a2d492ceeb00b70e3608fa2bf71ca4bfdb79c074616e9251394850e856eb9263d6b9e8bbd43de320f550016ce65c9e0fe6b146c92e66b5cdfe562edf201be2ee872a94d6d2acda89ecce8a38005358d199ffb557fbd60d19c226a3ece92dbac6789213c9b0aecdc706fa66d2970a83e0da70b133881fc9afde07de26bdf022313ee882dde2bd6bdaeeafcea84de0d997a9dea85a2c7a50c53b0fdcb43ac73a1c85d9650c31f909573eb584a65a6e4ebe68c6756c780318fe4e1265b379b0af3891b83d05ea22d7f11e4db8d3c5aae1431daa628d6a8b69999ca27029b3e819a59dc43015225535defd56264dd5125538eeb7839a883b4c7a9f5e1116f5f4f879b936cd0c93974a4c5301ea392de132e482b282bd8e3008107093fa01f24343ce14f9428a0ed365999d8c824a2e79b109f461731fbaab28e42531f6973ba5c365d277c8200cf4ea0cd3816573d95ca6fadd48c56137ed27da9d4a2628e31f5b5e48450a1c1c5971c6ff8f2e7eb61c97b98aed48ed874c95dc841370ad73a230db570f83f214adbc3846e11c382ad86d28a07dee1154a0cf9294374d471f812486f5e6c0594852b50f1cc820a7c7276c4e3e70e778557fdbbb0eb50fcedaecb2347ea8dda338260d800c76692b1f77fea4f375635b1248015b012823f977b5ade3bae231665d9f04987fc87d4bd867a14ea2352845da8216ef19ef37b8bf8b7f0109c909cce2a58c8eeece7d16d1f7c59a9cf94c2214ef105069c84434cd3983acba66d28d2fc0f54682f129eb299afbc2b1eed5d1e87942cf48cf3110fdbfbbf80af4f3cc8291c7239edf2ecde826446ce1ef53bb0ae9d948be2671edcd6ae6f1b0413eacee5f5d899a8ec7eb140e46fc86b8b36ffcc2ec3db868ba97d0dfacc4c0b4fde4ecbf8cbe5bfc99f2974f876789fd27293ad82003bab8038ee46ff9614fd3fff75f62f7fc6446051833b283fde7eaa80d9cf9bda4da4ecec266471a74341ae9de4577b31dd1033646542d5825c74123f522870508abcc528755806ba785abf3f062f60138ae67e83416597e53f18e2f59ed1bfe8d95a6c21e740d22606aa93a734d17ce18840e052f37a05933c8adfb4d3f38ec6b7c2a479d7730dafbccff839fd9fb157be616ed064e23352767742b464eaac2d36868d76063170f34cb9fc0ba676ac1ba12aec461cf6647781f4c3fe0142b55dd433bf2e7955e5e8744b5d03d2a24af6527c06e5932dfc92b1afe239bcd02eb01b0bf1db2f98475b7428e943d6e9d79ee60c3c477b6bb67d72b382f2527c4da66d34398983e97f811e8f2ed47639ab50f6eb7c3bb1568eb4b1a130019960dbe818740cc968a95171d0d71a33c338ed68fc9d3fba17f23062b334c7066e8476ddfde80f95345370f26711becb1ef74efc49fec4944b5fbefa6d99cc0fb463c4790b67b85579bda62e0f47a6bf8ce3afcdb19403bee6340615fd8a103afc04d57a2079230898f71c915e7d9ddf643c9960a2c1bcc64a1a14bb65979bb610a116e507748b478daaf337eead754d18fff463cf3bcf94c2d6d7f4793002455cbdb227406ee1ab63020ea85f32dd7aa52e433a4316922fbe829d6b368f32cf89aa4f9853e6bd42b79b6b2a3271df567a923f43de33563a423e71b9f3100dae57029cb24b46ad824521116475a286d4ba9bca0927900a", "6a53ac63ac", 1, -1344800502, 1537743641, "64bb2aab93424009560cd18c43d23d31aa92f8b729c9d7b8af7e049ebdcec20a"], + ["030000807082c403011d06838e7cfb0cca448f533343b5bc1783b2a357af4188f0e71d1e72201db6120100000005536a530065a07f054502ace88a04000000000071bbcc0500000000000000000000000000014dab7d01000000000000000000000000d2df2df13825b36adf59033d0bca51b3d946a3b84260c57438a63ae3efdf7cdcd0c2eff1ae7a75ee5007c20a8a6e8bb2611554809a42a705cd394460f2ea3d2bb8c9e8947ccda59a1b6c682c96349253a30d42a286d86aaa17817f66ab3ef35300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102cb763b8e41d99f82f95b5961509bd427318b2ef73076053002d7d8c35e9d25942e986689a4da3d0d88408cbe2569689c6615d1b65ad05f4dda5c9d4580b8ddccc6edc5e36335705a734f5017f944e79e2e5714f4cd39436f4d16b3e426b098e4e0fb50d11f9018172341b48d387940c0d784d3eb198423cc1d5cd9dad04410222e3f90dbc170da9744bed8e54088b8230ff95088bea4bd5208b688f362a3e300213c1f5c8225321a68d04534c553bbdd7dd1ab664eae8a3af856ea921896a88540a08c6fc1e2d7d252592e5ccbec4ce502a0b88291e3d807a0a9511fd2fd83092dbceca3b52d98d5ba1eef34b2f7c0a2119672565b9384a02dd24778d79be80463202261199989dddb0719e1759b4c88e2b961448da8fd1aa0a27b93d897d9c9a5354032eb777583da8b88d2c002274c0f0bdd15fbf30a0502c41bf8895cecfb4b942e7020e6653aebed92186a36a2603829eae433b0466e9435a2a34570424eb5c4742930310e911080f964b1c2fbfba534750e0e856b7525879af108763664d036a7ca0c20215cbdbd8e4b37f9aa9e8737d9f982861cf7d6abd38d6e4406a66648706f78ef48716819e0d09c24877196360a7d69c1994e4a6b213184d4ba9e388352c43dff9e39c77930854a26254ccefe4a125d69ecb22a19097e116a6b75fe35b701ddd01208ff9649b6861fe3e247b114f5d562c3dfc5684ac2d99c9b96c6485d454f13b1b428c0f53b957171605eddb66ea2a90087c00ab9b0492cfa29d00cd5834f4bee6389effdf61318f91053155f3de5e803ab5a86c67f138839c3407959e0f95097fbf987694983f5d36eec7ad5991c6b1514d518a196acb48a960b178770f392c39aedf24b43e1bc9dfa1b028e58124bd98e45fb930f43b7baef22f66f026e4303d9b691e48aeb42591007cfb08f2b8a2be72a4c00249a2a17447e920cfafa0049f4e9192cfd8461b61d6f347c2174209dfb1e1228b6a8a4943370b4cdc0166307108ec470eb778cd98dde36a9b9e9a2b2e1039527d000732b41bcf9729905b5d3639218529c4db904380954b1af6997d4a8bfeb6e369d81b8a323f69235f44c3d12d9dd88a6266c22f63d276da99b376faa03007f3ae682d5aa9995a59963499a2fe6fd76eb8901ea2d048ed901e0b45bcb69209892a447830201c5ca1e4fdfff575b23e34a780d56ddbb47dbad64c3c3992234b6fb5a8d516b2d9af43d69972a8437b7a6ffcfacf106d7bb18e12db1e500107321b1d42f804e272655c41535590344c769c7c1eee0c569643bd128362842c2bf92ffbc5f1c45b7ff108c879b5f8bc5e43150a53ff9b0ed23ce2e64c7ffd3c656082cb7745ba80f0acfa7ca36e583e2174d566f24fb867ed19d481d9da0b4937b0d74929a025b770fed50e21486bca3c483c6a45071307772a7dd491ac2059a77d22fe77a15f9ae9ee96aec567792bdf648b69708381ac5834f2aab880d41b9e184ecfb6662eab95fcb5a11da16b149d25ea85a183aa1764d1357ce9c08714b1f9782d8615375f1ab0a7bcd31d9f81e840a197db94bf897451b653ae5c68bdc0ec6177affdc4e844a7740539332432d027eb4352783653b3f994d6fc7becab0dd130b02a2f1aa97288bc4d6fc08d6d3c92f3d405e47c40f2dd932538a66d1373ecd059a81466df645ea8ee55eb2cf6e7fd2230fd93292e194a7f4e8f75cef57a2876b80652bfecaf0bae508926ce03072864134a5f4398f9dee75dbb0b9fba7658e244b67452067d195708012ec86f8197193f62722ae66c34468360e72ab27cfbaa056298fe6ee02542026ebd9508506be31999ed5cc0984dac965610f27eea02f95943ef2c9c188fb63de93a246c64541f2cdfb9cccc94eae375896e16e24e7b06f79fd8a0846461c64cd7d6d05e8ee26f8adfb4faa4a77b9d2c831eb2add18a7047a42fa24513b4ded0ebf00c8eed8f01be7c06975f401fc34538e3b80317f868329f66774123e1362a64e5e1c5bc3cd139d0509c3dfb3d7b3b9ee68579fe2b8756dfcdc6c7703a72a76fb7971cf9554b77039da93b56cef040b39e866a60ed343beaa10885cf357cf82a34839e9a9b8545d91f1b4715e7ef03c2e8d04e0c77f9ff6d151c0381849bdf9b8828ea5139414175c72e5a046bbab824c0f00c9b2d95f9f1e90872d66a526147ce95faa64639c239398112eff03c1a633f4c587c31c5b0a9ce80ffb5314e2dcf47f723e54703dc77ca137e1da2fe2d2a8cdf4c811ee561b747763ec04045ad4f734fc5f36eb54a276335899da92cbfdfb8025016c76723f7c21fb4c4871fb311ae09224f1aa4dc282f6e9cbc92a85d69ed030648d92ca15625a2fe111f7854c16f8139f9112d78ea7de9aebb6db3eac3cae1bc02827db3c5591216b52c66545aa2c82ed43edb76d7a3b3ea8fe93c54dcc6380a", "5365", 0, 515227481, 1537743641, "9d8598a891da9899e508725c2025d1240717851caaed1b6e67fd2963e5f60306"], + ["0000e33e015bde0d887c452cb548ab933f3aa026e36298f043a4a15412d2d7d6895112160d00000000056552535200c540122204ece4b202000000000953655153ac636353630638cd0400000000026500bd6ea70300000000076351656500526a9503480300000000086500635263525251df2c271c0100000000000000002ffca40500000000d31ae2f9bad16fa666b3216486d96321c956cf46d8a7c4c34294a2e6de622ae7439712a0534e1f1c96aef304ecd6abe7840a04bfe17532080d409150526f9379347a16f05411437a91a154d952853442221727f382cd65670e402f93918ca50d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000242b8b81c219d7e235c767f9b555a6f0f5140bacc42f3645fea785726e4e34a957ac80674cda594132b64f91e086d106c525382f861c39c402e54e39d441d67e1a5a3734f5a2bce76c1a19c93bf1bb0240abaf5521df11f73bef5cc5b90efee1d1a3d0d9c0714a16f1cc5b77dcb822556485eed39fc08bae024511e3a8510b71031b5e1d72522258db55b06f3002f6307d99b67acdf6d1c9a7884927e52f0cfd51021b80d9ce658616566bff4d629e94b6ba303fabbc544e8d8e7d488d41dfcbe9d90a041b301d20c1d30cb0064a39c311d6e50a0bfd30838c427f513826f3631576c3b149bd288078acf5d99be73ddf4f5da4bd42b70759907dd9d2d3f1b08f1ff71c03120f362ea10ce147301cfe070d646d7352fc18411769bedb369ee083c96749cb021669338c04ad02d7b850dbf0baafef066797295e6920ae3847f6e4c7c6a5d4de0303b67b82c1601c85027eda2a1e02d60f7482a9d164784bf1a65a07fc83245b74032e6ab600ede624bbfa4c08b33f2f8f0930bf04bec3e1b356199deb1ef0f92b3d022452a2ecf93f6a0c6f996560ff4ee9c6f74859a1613314dc2039c265c26a3e4152803c5cf94b67f34598e55da629113b41bff5d9ea63bc6b3b3531c497bee5a85292f72b3c3b4f347866f05703daeadc3c066d084b3e4a6f93c7f9808aacd27f6ee08d75afe53994ef911fcd66ec064208cdf17eb82d2bc1250b206949faceea372f8896399f4319f48a8ed9f5f9890e644b516bb3c45d42dc29fde8ae4af89f4d4150e5e3c36bb9bdbc88456c219336ba498410f1c97b07d8934d90a108ded11c0a13885331e846b1a5ffb32e97367e0e4290c5c55ee88f05fa76eeb6dde41ed692f57b13f057ea593f48a93dd4b272243f0fb91cc65967f0fc014a83a503f0f5b99adf741a48e4bd33c79ca697983ab20c5b6420f1f60625465665e1588271422d3a01d5bc5c8221940f5b121979fd76f28637df0e2feab426a9fe9ca19f6cb37b9a5e26614528b864afcdab643e6df47ad96b1ae2803b8efd8720d0db6429b00c1e46c5c6f93849fd59b5bb5e1753a42fa74c806b910d8b1d5f92d1d63420403bdfbaf8ae18245e683f5ce5c40e8bbec4c4bc25061dfbefa2856ddf7541bdd1053355d2782a7752c4611de3841dc4b31b654156bf785eeb2ebcd88663d8ac99cfdd4ddbaf16ba0900f1a63384e15ab2bc664b6c3ca8cc8d34eb23b562d8f50ae87df7b637cefe5724bc7a070b7a6211f0f3b6ac5772ca315ff45c51b6376b7b8be334bab1c8c1c23c31e5bc25d66ff52b7c5c8be584591e23659feb6afa6b06002261c9f8019d75174ffcc46f8d1f0d99636c24cb4df826198e400840c98d11010595ddb5d64d44425ffe82e0cba72ab7e6fa5b5cb85f44d4397d1ebb08c8ce715daa23b2306b7ab05bddaa0bd54de6d1b6d73f90a333c284e8b21d53b7766387baf073ffca25c847bf6cb13ee8726648a8905d31eb91b3038610424a73d6aa96d9dcfe90f146b055d297b68008824e6640649aebde5d32f115e9698b2c7030a669bb535078b54cb92dcc12a0b8066e93fb3d14dc02772c713356bbb59cbbd2ae9ceba497879aa5b469599c440b70b572b762406d8efeb34cfca7619185132f50347b0e7de9cd348bf6e53d07e9f249beba7f3bab7ddb5cf5fbbf212702d79ac33a58755d5945631587e415dcb4d7a8fd6235b69b2a3c1037855a68cf088ace87d9ae532cbddcd0024f3454e0fbce262334d3498c175b68f27cc34c7d28e93dae59720e0d11c93c7a1be0c3cda86c604dbde6f3c24c30bc6110b4e86594f050ecd31a3dd06015749c92b99d4268846319e1956d1cdba42bf588ca522badd260fe00ac2cbaf275b237bc849bca3c3ec8e7cb287963a1bb9c851713bdf51e4abf613eacfccb906c7d9d1f71f5a3b24ac4940ec067a111b0b916bf21ebd43a412c9e219a189f892973b895a150dd39f36538f88c737e0ca9b0595c8275d50fca6dd639edf23c02e8ab369d5a6e94aa621532f8234321997bcbd45da73fca3fe0ee3c29a0888e4f5ab991cb8c6fe2a0e445f2f555569000599efb1a92820c9e7140d5c12e30d38bcd035953e24ca180ac5b9fc3c5caddade7742f50ff78a524cd3a44970318a62d98e197302a5b5fddd34527939fd641e8506dba5a0abf789dc6f4a89e8b06726bb30ae82761fec111830e471ac38eb41ee267bbeabe31e24f79481472ebad6e8c35e1a8fc593fec924ab1a494062349955598406ee56e5c57c739493cb8e96b74e2f41664d1ab64af57c598fab67e1285c3bfc22ddce2f99c8e280b4096fa6e76454ba3ac7d68c3ebda7ac66cb23d115440edfda36f0e2fb7244e33f1eef589def5465e4b2d4dd7ca934169b90107d74b2055482e0f93135b3e93af556dbc91c0893e680ebfd5035afa3009", "", 0, -1239815601, 1537743641, "1d074401d8ec7a11989714791c3ba45e14db898e47269bd4c9460ae9caf1027b"], + ["862f207b0477c51c424565738c750130567d806d51c3445e3ea02ddef9ad167d1c9bcb8308030000000400ac5151ffffffff6e21038948a2c9bd2909d400f789cca09c375b96305f873ecbecd897ac17ba7901000000055163515165308c2d34164bef31a4b5e0b09dc764e794bb5e8d16c2d8d22695aef2106e281400311ab80200000002ac5306bbd9b832e5e941daf11c296029fcff22de1d91e7c31c784c124c950f96b0159a89786e010000000163ffffffff041103e402000000000353515124ef31040000000002006abe98e802000000000763ac65006553630c0dc4030000000006526a0052655300000000030000000000000000c95dd10100000000f99b6f9df3b92f18eb87bfef84b2702ebe8e1af44ccaeec9ee4e6bb9d96a3294adc864fb98d22ecebc063636268cc297d1041283c6c2e4ffa303b0f7cbdaaf41849e2be5522420b981b22c4280e6ab86ecbc0bbfb0a3d07803b3efb1f95672b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b11cb5c0bc56647ccf5145dd6a7678de0275e252261c44d9e8fc7cd124a633675827b382c175be08f73c391325971bbdf4eef7d322caf8c0accd25db04f1eae226ceb7f5ec3aa5c828b3818aeaf1b6a48baf0f8fbb14d43d13ab5e159f93722d88c9b8d9c49ff5187a525ac994aa9eca71f581908b218e3454f9dd38a8ce36403240bedbeb68748e62c5ed32c72c6573e4836dc05aabc7572984d08bb89e2d551020e816fc3258a29c62ce6e037e8233e62987a2f8b88259fc35da5a45b48fc5ef70b00c2c1b86b674e46fdaa40ec9b55ec25a782a7ff14581eeb40ffbb297604ec011903b7685b417da2dbc72def72c129921ec74f3a5b06ce5e53ec5de3b9fd91ef0300e969c5367a3852ec4a5a30f78a796aec102c2d815243b4067739ce7c3404ea02120cbe5d467f7b59303b5e5a6bc2c4eba6e07897bcbe982ff15d035036e4d6ad032d482a551cfb772508f658c08b1006bb2ac651c632cd98872570647c25871a0302218547f6714a29654643332e0528b60f7dc8d568d2637648fa2fdcecb4cb37d703145389c98e7c4560ebb84101973aab1cde01aa938dcbfec681151da205d8b21d2ab226ad5ff20d17df729b5256cc8c425f77863c53a0c9ad7c46f73997806dc47bede7c65bdf859ca2a30d92abb1e958876f33045d6a0180e18c32f0f21d0cd50d63ecf2b3a97543ce2c84de868eab750211a878a834f6d5259a3abdd0ef4b11deca7366676c1e6355a3440f12a49c62593f6b6717ac627e35362877396e49a0af8fedb80e4c4b17e743d5650c3591ad0bb5378e210cc8a1a01a48077dd7783762a2d72af1b98b3c33de7b1c27dc5fbe473625c3a5eed7cdc34cd7cfdaf960db121194562e068cb0c2d28e7b34ede58a7fdd086878c3d9d6600201b46ec3fa5057bf5f07e64950b5bc1c6b749da8862c76269218b5b5e5694adc0076815b8f4516f5ad30e485cb9127ae55c2144ab19f0197d0db4f66d84c8632b582ecb44512f3a60e97ea85c1bfed0a9ea9d8b91044beb98383c047b418d4a9f3510b1dd88eb17d69f434ca3fae7e7823332f9c89a4af138e9692dc540fba0bf0e7fd6d1fc61e86ff8bbe7e321f80379584e3bc996340146ca652c981bb2056abb2e7eaf2acea342e9abe8f63f912829691639ff9495762c05b0f0ce51e67060a5ace195fdc42e1f44ed2fccb45ea4ad28bccb18af97c52e31aaa55511716632f3c3e84a3b13f0f4387b2ec421628f2098375af81129331f4f2d6092833ea454151e09c8fc7f3b6a52daa5980f7f0121da00a5d941367038a59ef86f2cc656fc50cd185323152f317a4bacb9b029711652bc199c6bde122d184ffcebc4d9aa3b477c930cbd683042675b173a77df60b0fc09596f70ba327757464b3c6f5d4a2d01fa295001deef6460f5ee04499c349a9a72002e3d827ee193c807ad3813e8b58eec1393f622f0b66cea39aef9816c544bdb47cda50af1089177d664913193a523d6e6d3cf698a161e53b92ddba1cd8b1549cef798ee69dec8f919330c5cc09339d8ecc2d6a273cd27d457e1e86bce8c56ebd9eece3da5e9d0452527668b1d2b9f05e3086de106916bd4ffd270a102689bfd5bde825ff5d05784f5f3a042e93e6fcc254b164d9c0509b96de080166e8898a0b6210029b41ae3d38871edcf6c0ec16d7649b98aac216c31493fde7796ec4e0da281f497c08998a881519efca12fe685b5c2bc1ff889f18b573192468e9cc5a4a548d07bd5da82c1843d43922f0b449583f1980335d44071826aa8d870430a2a48ff931fc116752086a17356c44694f8415799fcdede8fdbced5499afe7a4b0a215b54c2426a395c633f5105b1bd35bad68744ffe5794d8945743947175827c60722e7dc42849f8dc1ff8a05b850e98e44757b8a32fbf9baa640a3e7a9ac0c5e18563e588a2484876079384f0b9caf9ca33c9ed931a3b095caaa0b6065c724f7ddb52a06800031a5f7c34148af97090b8750353b767ec8680c8346ae7f03cabeb745604e411a32d7a5c5ba955eb29c0f6876c1e5f3f011ec8d5c09758c6f5ea9a31516a91b6e95c5f74c9d5efdf4d4a5c6a22f321dddad7428f2897a2a0baef0550ca9573e12c4d363aae0d1e2b51b255a295f8e222b8cc5a1b2f36ceabbad387540ff95367fe049afaff4af28998c403eeca0a2b0174c1f9f29420cd073e959c35bd51c4ef7e2f2f68bbac2a3860f605ee35f2096fe54a0ce5c484e0e5d1f2e68bc1502ae5aae63528bbecec38f0faa5edff9700be8ff0e1d4dcf56d2d656c623782b9c0a2308aeb0100000000000000000000000075e63076b308882c906db98069f2bf032762b0c5bcd6515ece50c504509ad0687a5ccda6e7a6efbfb894d9905bd7ea45220d4784f7c8c1f06ae68b99f8c3217b0850d89a2834d0a35387de63b80e2a7d1d9c33e30c1cbed9682b355c5fef608d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab06e27a9a81629c70e60910823c6c57af219a2a159a288490efe9f3a324db4ddee762f909fb1e9f38dfb4f00a870e5405f81ce32d5f3a70973df651dce6acfd305eb635fdc02fca802f64c0ff3edbe60aa30399f470f602af924295c6c15932fce25974f561ddd85ca3ce16fc604f676e56226ff4f9c48f4d0165e075fda2920221d7a9ff3e4e16301d8098978bb58b2cc0adede75ad54e1fa027fcede2e1f2f30211e1a5343bfbd819d92dfa6a032e80de1b416e89066383977d1faeb3e50e84300b01b1d47d872f7267a47539bfbb10b19b237878c617c0dc56ae56884f24f6449d428af9b4e1e5d45997378a1a7396d8036bae71053ddf90a2d3b1d3bdc52b1fad0229e42cd4d5c1419346db60bce2acffaae749991d54a8722951f9161d2de91452021a74c8c135b8b5fb6eeb9e5c907424b0adb11a7dd751797790bc5a85b51a16da0223f312f7a909264f21f873bb9305c571f87b528978a23d2ee8d47614a02651310228e6a1604cb9177996633bd320a1553194b90727213c5db7a3dc4051cc10c1e5032ac15bbbac005eb76df37c5ce9548cd6ce2c4b69263ae26f6b9971dc0dd0c7e33330e341dc341cdcb2e3e84d13e1214046800bd1855d71d2d393676fe2e070021b2961677b098c458f3c2b5e572aa2033572c8ba4d7319542d2f6d104bcf0a76d941f23fc20c7499162c4f3ee7ac083750d19dc50e89ca74c95c8a82f59bd8977f3cd43caf9b2c552a8645ccd26f74b2bb1c4dbbb95125edaf705e59213e21d28aba5d88b5cfffa9bebaf18998f96089a86d1214eebf4ca6a437957596d1ce984d7de1f6c85be5321965317c4204458ece9fae887f137b968593b873475554213751016f7a8bde3f007f411ba8d811fb7b3b44d4bc2520de87e3773cc219b49cbd3328064fe735085dc4d4608d11c9c34fc95214ec8cbfaa114fd723b6cf64cf22864780e6a39a5bbdc0191d1329b9de50544c5b1c526043f1c39abb22996881948514f6b0a3c70bd13104216c15fe64a0c2fbdaf032611a9b63fc2343bef0b115dcb439222094a4d096c7e6937351099bdaec4fa7831ce1bfdb1a189ee0e160b58cf2dde510043a5fb87781c54567279e146ccfe28a2f9f0238cbd93db9b033afafc7ab9b4e4c770634c289763dcdbdbef976b5cc40c25940214829ef45a574347d3c7d3c1f6b53a803239fb3832070015b2833d60598b7f23870a1045303228f38d1a9a3edc39e5d9e844d8da0ea21cda70465ad751e6ef142ad7b84553565bf0c4b51af45db2f82ddecbc71ea5be2d9bb395b4ee7c32c4155780093fdd722053b45f131aa154eac3cc330ebb12dabc6e2b8883f842078f6ded8f8851548aba2375a86d24e72db7311372093fb960bf22c4d12b2dc7b3365e5e63137c7c12d18dd239a698e1006c55efb36a2a3cb87ef5d63343be97bf015cc896478d6dfe5106791b4fa9e104e6571b49cc0069264199e13a2ca72e815a953a380c1e6f97310e1fe7e02b6e01e7842340628e2780c9f72e09ebf2d1dfe87844d475965bf07a69889523b97cc7faa27163c2225ebb56822fc0f791cf012f79bba52924249e338155316027b875de3bbf8de605dd3fc4812fe6ea97c24f824c215c8bf51b4312480344535429f591e5645b5d25f0f4e0d6fe428ac394336396b4e7e2ae890f41c12bae1d08c06e6c0a9510cb04689d2b8137f572cf46cb34127dd7681fb58b0a49761815a4e8962ae8d4314f1956d2270abd24d7b318cb9a98ae67c12c37f470cafefcee4692434c8b38ab1d89f6511a8cdcc76f6dbdf62a737a3fe5f0665a4b78845f695d5257bc95bd7b0658abb85ea0b30da12c7b9853b988b351dcc30994f67342d17c8f1f1be193e2b97539f94297aacdc16afa0a0ce469de9bbbe246ca15ea858ac9996f7bcee35527dca655f0112b8ab7714b722969f28d99169f55a199291c1f517d771c92b7dab2680e731ed4683c3e138869f3b513531aec91b3f2ca1033dfe3e15a3fea45f9684f4a6248d2c2b4a160e899c80e1b58a26db6c81b7b2eb597a78616742577f53e1547bb629ecf166b98b1be95e0337286d94aca3f7df1588deb1ac3f381d367bef60baeb31a0f8fde0d2feccad9a88bf69ef1d37ddd965e97a50e6ef6740cea856f5bf15dcec0eb6a2f0b16424abd23ff72f3d5916bdc7b785c952588a30954d30ac86d3f993b87ec42e123b07e52bea5e8d56c34136e811664cd4fe1e35a65b1927c0f9c6542f93d373974fb6f5cf1714a1f3b4190665e036c1abce2921a7676140675df1e6ff31a40200000000000000000000000029897be972177a9e6801c53f91c4f1ab618302a063e287a35d29a8bd294e6ed05a7e61a3513b5e170d495d155593f5a37d2e8d22ca52ce09d047e48d68334b30a31e475dd97aca5be4a724e09729a61bec7714cc0ba09e5b7d6129ad11b81c45000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee7ae9f4f29d3a6b510f98dd320a3e4bcd039730d0ba30b157b26b71df0ecb57cb2df052c61d7a4d445ac53af00b671c071c0afa63e69f183a6251763a58c85ed6ab988450310d4644cb9961d5dd373963d4406a75178d2d5df5672e92456a00ba1fd3b6be5bdf18b70672052b44167c0b94c06f866446aa077d9a624382fd703188c433a8f3b836d62fe3d2027038cf6262d6537c37625efcf91aa52f637c8bd032c356c5d61c13a3f33a63e3d32d112f2c1fc325f3089ccfec96b2bc926a3d7b10b02a37bf47dc65f6bff7769f84678c04c5299be67e62dc8e0901aa46d574dd477ce1111a570a4bf0a8b7b73b40331c54fe9161acbe67b7eea9f211a8ed9cf5ddc030fa6e6c0889116508af416c1de133d8e5e2e691464eedbf601c3aaef27bd8ba3021d9845e37d82fa63056dc47a2593eba2e9300a421e450bd5f3818ec54e22c0c20217ba069d7983eebbacc32b61202060635d0d9399f001b8338b9813ed4d6e7c72022d308fd5b0ef09244164ea50df80b460f9816b8fcd70488d22192f5d4905be3503089b6f01c1988640f1f8770c5c5ddc53d328815852e9d3d6c54ce6a426f48a4b3e811c169907e8559ddcb5c1e76be04d3b6a7702a280d5848dc77e3baccdd60b587fa180077d840007ab4d9c104d74f26ca4417daa6289140e4e78ddfd15a043a469234d119482e6d54bdedb8552dda82bebac76246c887339651c1f669ab817ad23363940fad32f0f6f5dceb5f8bb4798a0527b8cf51f9edfa694012d06855f57af8ba8ea7e6798513e76481f749f4e2ea2f57c242f11b2796bcd41c0168f1da6ff7ebc62a8a59a6b1d2e73152e488237ce9ceb21b37d976364634b5d27a02c161bc424b9d5dd0df6274fe391e2ee8e8dc3d6561f9a19ed54011b395529c2aedfb64e3ca04ed31a06a5bdb882cdacb10a7c7146adcbcf7b1b325b89c5fa013d423af0927e48f3b9c697e54b9e44546bc853ce6932df647c0442fd7d193967589a0a46a6c52a3e0357681f27669a4ca77276c3f524e3309de4ccd8f3405b4ebb366b77d3eedb451d255f5e0fcf857c8af969f9ab566bea735fe29a34ae77e2d802e97aae33ccbd6ea9ece7ff2f889c70da8d06973c5dc1a42bc4b34d978b0537b5567979c94aec5f52f1cfbcf4f3af91f32067a943e986d63e727c96f3cda861dd3a4b7d5925b5cd0808dd7479bbcbd04d296258ad9a981f3c1930a4fc0aec99dcab4d66fb46c13272303eea5c8755859e2ef0a862be8b6a8140a791563e8d283d28764ae6a6e6c02b2bec7b7c9e57015d4202d7f3ab71cf5ccaa531fb51e3a9ef18f0f0d5d0b9019438a5a903bf777398c714dac163d261fb80c41710429d26303f5f2560234d0b91b01a9a37f18ec103ee8dafb2c7c4692b2c8649415cbd55f56f1bb5ed492b9de762706a0bd11193b29285ee9c6575b835ceb4b5dc780c8b21d5f173780be68ea9f5554a137ad784105038bf2571a041e8e4a629ec8814d2591dfdd8e4f356ba90d182be595bc4108aee81a9efb68c86130a04f2f90433bc42dc8107e61eafd6a61f30ef103e7c9042747477a5ec88642f87c2521c5457ef954c58e968ec9d8b0e53a424398f7bd26a43922df73565786106495d2542c1f2a4577d4f92efbfd177b67fd8fb447790662a1548d0abdae89ed56ca8b258e85b6dba25aa912c082fc71824bf50213492cf8d2a39e28c53af7a4c262f207082fe3012c5b1e33528cbf21f28962cfc267fc2a37f84ee22b8beeca84febc7400f9cf4c23be49a92296fc95f5be5b2e8b25f405157cfba0e20ae8ef42075d46c84a09d725b1c2082927ab82c917692f2e3baca3d345a61c4107a3e10d80319fb834ecb1d832369837b27c7c116cc02c39b05cc3d65feda530a3aed06e8ab47b06d21150efa14a47b5c9ad7662a41f840b9918423586c1a1bea5eaf894920df32464f91a1367b4ef9269c9d35d118f527c3e6fb2e6e197fbea87c66559653ae54885291e600fd7f6bddebaafe61f5f557a883b89933edd55ca2c16cd7efd2376afd0d60f1ce69c43d3fdd50229e00cf37638e90ac7712e1fbbbb5853ca56de8230b34250a46ad70813d1a075380a556c9f42c54328123a747c5d648c1be654f1e9b2280f1b4525c56a94d361f7eafbd8089e352b96e2afe68cf6ea0fc4c6e93200dbb4435fe2a54c158009ed489f5468a61ec015d2a4f417eed070a8b2abd7123988e0583d417d489b653d55f54a7c2839ea48f9a31b6ff588e7001c2bcaaf2524d8adbe0f8f44408ec59c4ff63cedae31010e295a1aacdb34a9e98c617399519d168d330f9282de937fc9857d1abb5f201fe3aa3fc406e140a0cc23ad5d45557bd18bd3aeb4f49ec46533991874f2b75de6d0c968217a1921e0d8b65be56e21ccdb3752cb9dea836307f003ad201ac40dd100201", "6aac63ac5265ac6552", 2, 1901831755, 1537743641, "43c08c87e6992364753b4b53afab8168868aad550b94287f5c31821d486b2c73"], + ["4e672a7104fb706b40c47d3e5c1032ac9a16dde76a16e6ec258be88e975489873cbd0f5963010000000965515263acac515253ffffffffcd182594eac286c0eba489f29a6059bce3daaa784ccd21b396ee7d0f6de5f70a020000000651536a516300d351681feea24602b53a63b141ed816f79ca6d781abf0b884903a32c3fe1299c165718420200000004526363acffffffffd36e9edeb216979d343e709e4aa777d43c22f631e39825cf79e30bc72b4d84c102000000086a6a6353ac65516a54dd3ca4040c4beb010000000006516a63acac5125c57800000000000653656a5353000db5380400000000026a517736ea0400000000060053ac636a008d502c8c01f4291f0400000000000000000000000069024f706b6de05f7a4a86060e84b38d1e22aaff1646bfce9f2ef33a13fe25934d142c780f5762cc2d2176716c7a77285bb009b877cdbb29ee51e14ea35440faf2aa55f296f218a9ef05aeaf946d67beb5b943b2a867bc5a0ac58f5bae7ac96f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a78a8eb7c94db00d4e06f29ce8ad5419bc732904917db0d572e171d56c0da859dc6ab2299ccac81cb2c0a0697df377eeb37211ecf521d4d4a984687371da7683e2f2d5aa05a8ba919fa0a36957629a24b6beb79531becfcd635950726691b2a8b58eaa0583c7a3b509c18a95d1554a1c9418dff02bae1f7ec2661c98bea025c503173090ae44aabbe61eba0cc2422bd719f5ef5b10d8fac122b868a1d72bd25dd40208052643685b62e7b11a1282a591b375a50134abb809084d3eeac36ebb5cf8480b00e344b1529c54f26878d94de3744fff8afb093e64c2bddd067abaf544bb67c5ced98ee7f17ddd79651d46f173c904aabe20040324e45a184f867ad91782b370021aae754a64214dd8899017bba62a82dafa4805f49fc04202968fce5d803fec350210b56b7c6c36f36ba8c28a2fa39a05302e8520b97f5cefbd5fe366df5cece70f02128611ed965fab821d0d65c2169daa5b8fdbf98b1f7be70df2187ff89b721534020d42876eb7a1e33d1cd4df924701f0a82f40f3fab48017781544e6cae31b10d5020b71370e9c7971c8762b7040d1773a982db22b6c0247f4a41d43cfc77325302298ef7451169cb922b2119255851410e173289e538c92082eb0c0e449133d570654f3576289a5ead1b67c97d7a929cedacc1e6299a36712da738f061e8938d04acc0c24e17d7451b63b8f95c391d7e28b05559d8449ed3f33ca4f7c82081eaabca746d006083dd9b084fff121167abb89c2749fa4be2a2a4b96dbf79b7bd7bfc5bf1ce50a6b2d79089d7538aa810090d66c78f4b3c53e4aed6d9d02d4491aa0c4f8b5efd4045817339a71490231e349a903c1a5e7af95d3200ae4e277af5f6f28e7a084df198ca84f89a4fca5ae31882e01f2dd6f64e8aa0951d20969fd921ea4acb3219010e99e1d6a5bd53abf00e4e0a416c8ba312f8fdb6efc55d5efc3fac830a60749044b8d100f22753bb4ad8c6dc778e488b93a735c129879aef9357f129cffc509eb39585b70301a072e3b8e476bf56cde37ea9fad742141ce8092ae3e807e08ff0f328e57ad5703faa65887095f51073ad3d4176753cc72f7c3c7c3ddaa6c03c1d74b8fef0b92992198893c6f3e28476a7e699109a3e20ae1a81e77b97bc65e0f41a3a7c1e4db1349af1778e14dc2ea1cdeabeee793d347ab60b0e88976ff446695b35074cbd396f73dd0048f9bebb20995dcde2a7b32c0c8ee7bf9df717f4b666f361d52fffa48eab59b1d487bcb7bce5ed6c2d707cb2dd08c04d3e7490636413a320994a46b8223ace1eb0c58490c6f2af74d98cac78904b4a68eb1f0eef85d7439efe4acc7447195160af3942d903251d9a615ad800f9600a4e2dd444b834dab66cc34e406b15918cad588a7e2c23a7073dd45666b5c21489c038dc3ffeb7fd9e4e630799764213c289cb6c1a5fc858de52bafaebf0ec4dae7930ec8150a1acae991feac6c359b5bbc82399dc84302b469a076b6a61ac27ab9ec9dc1ab7d5877654bff0fa6b12b0752fa264c051c6dd75e8e44bc740bfc8cd7dced4d5ecd13df6770fea627be8a8e4f59aeb61d7d5490a9905b06ee12d7e2a0e4c636f2eefb5e6438f1ad7eb03f4fc8f4e3c35e2db5ea33d0676096e560dc63eeac429e5bfb70dc3d6464656add853f8fef3cb16f8070a69bc29fc3469c25b74931f76841587e087408857aab1c6281bae9e2dd1d437e093a7c61747656e591947bb2aeb77f10c89b1b55e5b27d9c96e630e05670e336c57a80ff0ddfc298d7ae9daf650f3ab186960b8ad2524a95b07626a1451065d72f22738e13442ba9ebcd5895f1223c45725910b94cc60319fba31c151f08be43e5118188d312bceded3eac8142858e2b161b86f2203aa6aee713c2f2d513cc541c075162dd6a9e4bdfe7f983101120756355d2f8f05c11c6f2ed2d098f276919f101a8fbbc367aa02b9a0a1c9c9c2603b05f929ed035dfd7587d4dda905f7e9800be2d865b82621d8e7a384302fe32a4c2482bba0f6b9040168b9ec0e2e8642010b5d6a2e93ab78151091320b5d62b72acc151ed885f6c9a3b9bc266791b7c55ae3b4a3c073125872c625a283b6a9a52f134e73744ca347e1d777a64dc80e0986b995d5ce9e8b1e9ad64f5c05a8d0f77adc343529c3ff8470ff20961ac7ca57a071b4b48e736ef670ab6f9664b1fa3473cc25d414532b7d4b5a81cd0a53b8cf11593bf4f9df41ff6c2a865a57f850319469dadd18494e3bc66c3abdc552a0bad31f98745b0b500210585126dec9e7608df5852fc252ffa6efd90d90750c823247ec866052a7f839c15f8fe5fea9409b98f55ce0786af3c99e0e4e3975171d90ea03f35372307745fc62833cdcdc1c16a75d9b1696ccf692c721cd5adb1ae7b795050e04307cc077395953e23eace8a760c856183bddd19bfbb17139c02", "", 0, 289614840, 0, "07bd8b6d9db4922f89daac9f6d8dbe07a174fb851548c14c62945852806d1f0a"], + ["030000807082c403045e2fcf5c24e501d5004ab8b41c2e78c1ae87ac9b2fab729d1e8a83be9bdb1b650000000007536a6a6365006a381b9132ff208f1a3b0f8d22ad3940c2f3681eea9a74a21219660cc0e6f1f2d4de99648e02000000090051ac53635100000019e8cf2741a36ae819cfa427b90cf44a8b76bbb3e7cdd94acd4b443c280f4ae0fe2e3f18000000000152ffffffff8c5a0fbc9b676d70f7cd47010cd1ad11e3b043b3adf2145b51189e5f1c98c5090000000009510065ac005163ac51358e9be0013356de0200000000095200006a655353526362e4083770306f370200000000000000009349bf0500000000155f611bb4bba5c7a606f8d1a3f7de83509db579151be9083b5655934163669d6d1f758bd656fb604a218aec8bf5353e5b6cf5bde3ed9f522bcbd1d3a7a95d20f3c35dea09b0d6ffb6bab489264d677960fdb3810a11e255d041ae7cd7007eea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e7a6917d594b31e078943914afb8ea5351f646be9282e342fb50394cd709800402ba557171565c5ccef148096901f07eaa5656f412e3ab5db8a5811ec29cb158b9d9319a086dee44fc3862489080941f890f5368a6b90af3fba15dbb8dd695bcdc0890967ff9e2c3b1f2a200ffd858243f0f318ebfdd1f182c05066ec25b2135021224c841ab4c0409121606ccb168ea3e0af4592f6f321b92467565e15fb22121021c988f700619cb729005d88827c9da28dfda2ff2e1ed7e61592bde4a819619e10b048ab61b1f87d5931410798c3f7c5c7f6b8824982632964b54a35e03d3baec093d7f4e37b4c4044396746d952546f95a0f8008deb4e463466da28ccca5cc3c6a031e80598cb716c8ffdeb6c6c2fddd38d5f8ec3c2854464495c02c04773ea5d43d03230b2070691b0e76058eb3f0cd899f2c2c5669fa8cb413ac67533361dd26f5ae032e86ff159d188e880a468896b3f1370d9ba340818736c4d47e33fd776a88fb86020a8aa5941246eea27248e9f32804b5677aff1b16356fe5dad047ba2d4b5dfdcb03163b1cb60878cdf4222b74d5ded2f84d06f70f46b0836e458059fb3414b5799e5d264bd100b3c04d470cd9de55024e90cfc257ab726a99324cc6765f22eed2d69b466782758c12399c74d0894c30a4dd67dd38a2137814f9b60d0620056fc2f0c2d626ecef5fdaf417ea426bc0526d4011728f580a1349e7ab38975f080ff09a7de501eb3a929d23dd6863c3910ff7af95787c45c73ca46a159e0a972807b24e92b44986d937d62da8e4726375e765bb268dc031ef2dad5164ba9c1d7becc0c480f4054087c67a0f9493085b7eb5fed70f5b2946959b38f55f8a3722821fc23f11ea10716f1fd1c1ba83db2ee3cea3eb3ace5b6be6110b4fe8f5a4da47683f6e98182415e6a818066906f7b981dce88299c7d80e57f40106f7d7ab234463850e529279e13d739f20b836094a1f7004978df341981525b5225b851c056c387c1c7af67936821da32083575505cc21abac179ebaedeb78f8835faffabc0115b78853e4d680dc21ab4ae2284c8dc645c4312983598afd07ef58f2507d1b90618e05007e300bf04208b76ec8c26267e72b38234a9c17f3de8714018aecede54b784f96e75515939b92036bbc76a58e544fdb3181b23dd0baab17b3a94ca97b7c8a1a1bdddd45d5d84026340a8a8ba25a4d594a9d5f5fd450d352ca1d40608f60ced509d213e9f1c38e78a8468290e7d1ce6c5097ef695c63d1da2e2b371e4c3c7d81f9080badd4875fbacb7a9b554ff9b6f881b49ac4dd65d2649de8a7bd3a73f563d9e990f3d772348eddeebff660f7e8ae59f7efab008a269e88043b73f15178a247996194a5cf25c418066b636819f7c162dc1e7c3194518a38dd9e4be25ba803789a7b84d877000bceb192f4319a57ccd20932d8dbd5edbae2260d291d73102eb04a38e1af2f0984164f8244570bea2e83ccb0c832b80a034dbaa5eeb65f6555d56c7761db48433aef23a89764a59feea9bc38b1c94548468eaf698ef1a11cfab2ee88f4f8d8af083f27be5364721eb8c6e9ad842dcdda9150b72c9cb21fa3a085ed97d0bd06bce8a28effd811223807bebef80a028464ece7e7e4e53612937f18bd54ede10b51b6e88bf60a83d6451f44deb48598d6413a38f46c519a63c031a1b5b7a82ab82af158d70bf6b5974d7c8da8f6f68d6be67314592bcd5fa91357174842a3b5b257c0d5e834c5dfbcc387df211642c87987dc8729ccce1b7e4635247289ceaa0baca326c0a824c59903e306cdf19ef0ac04752329a2265982ae5279bf011ca65dd6b707d860e7aff6a1204ce709831c705b1d3e64f275c2bfa1d1892c9024412b623fefa1db65d9d414661d3f4e7436cffd6cc52338707c09b3786e9560316c5cc25c8e1d69f7c2a0370984fb81555f4e4a89a94874ecf2fec1a7f1aa3c27b5dec94be8bdeeda38c86f1de2bda6f709ce3b5605efcb47df116d01311413667276a74cb737cd7b760b3b7772fd9423d644de787f7ec8eac6d77a009ca22c353cb889183bc4472b5903f1dcbab4bca64bf96dda0a147f299786f0804baca2f26f42536bdeeab33d33b6cb45e6367c4a937b53e81f373a5742129d5dbce17dde54c4f0b346b3e3204db9cf5a774506ba789fc83e0f14478998bbdbcad037ae085572a4b633ecb2d141b488ca43ebd0dbcbbeef6121a7ecdfdee1eecb9fedc4296ccb37c78ee3bfd9be9d4be306962984f0b3301fa99953193826fdb0d6c4f8547403f983ea656f188aac1c71276348a195020000000000000000000000009de2d54e9743bdb28eb878ab265b49fce79897c8c3454d9e40a0232c2045e22605dd4a9b858ce169f0aadffa8e1b2db1e7bcccedd859a5eb2c097a66d9b9a18191fb88e3922876fca61328bcedf159246a4868e9f38025585193b3294386e7fa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bcf0525569ac941c1fd17c736bf80b50907c65f626ea46f859c076ca3ba4914b0f49cce7446dd85d0dce68d09b35a1dfacb659f5fbd637e1323b3326b869f06f95d782ebe18723bef7df33c3ec5d4ab84db6b574cd08c7b38fffe7abb4ef996ffae678b2643355028505da5f3844a0550e3e1508b1f5478a12f010f63284b00803304e3f5b15a72e918dfdb0d1d706db4bcc417bfbf4cbfcbc2d00d0cfc2bacec3021f07cb2746f431ecd2e52ed6949c920354f9b4a4a0968974f19c5046f1589e280b0750e35942207bc04daa06c9d89eb6d5ac6be0152c54cdc31b4037e9ac0cf11111824891063cc0305fb4d0b56d0d6670737434ca685abe579f3786786f6348dc032d2a27e31404c712e10cf744e210668ffc54c17f0e245acda356eaf2202d8ccf0313ed863b93c2c8799e861dfec512fcca3e3f2f79fc5610105524872eb7695882021e20cbfdd182617c880c87e3655f3b189b1448cf38e2fe8f91a59b82eb21c03f0221c3400adbcf3450cd16f934423520321f9b57b6d9cf52629eeaa9c8f881678c0221ce049284b74f1db34073acc22dd08bc41ee693511f2b72237300ea77734511a0433dee8c4c5108da7b653d947faf11f03e0bc2b03c1b44dee0bc60e7c46d8eea0b744d5fb009fd0d0deb976be00443b5dcc41b97c147b2d6a134281bb33848932b933e99e0a824971aa3fe5d30f10ebda869c8c9faa089dfe1cc1d08013022fb15c9351644b779724318199d31f2657fe8bf7ec3ea7393bc2c89d1d78b0dd7e06e2351e56bc4fe519989e45dd7e6b0062592a63d54ad7ed4cd7e4545cdbd40eeeb3cc2e34798abc9410d255429ff00432b2cb517ee595650dd79aea04a507acc9238750a5629827d9134ed8194fe0eb9fe39ee1ceff6471380a6518115a18a2a69472d4308cadc2e2d54575d0d954327d96a17db89de56567dd81ab7f7d1fdb19beb634a94857c468117d5329f787df2e706e4d4948a89f903c08630bc52fd1ad8c4a0caa977d9fd5b6efc7c8c018e4086a736321caf4c11330003583edd39c0b5a6e312f7cef53f5dbd399a57a53964f080754892ffc4526888bdb71c7e9153e7ffed251c6267e0a90169fad36fe936737584c5f70d861cc6a5f3f4498357b0cbb3448d0fbced61b1fbee76c7137fcfafde6618acde2e79ef97b3d275982236db739ab83fb7434b8b232279e8959ef62b6dedb03609b36575f8c18ee978f8e64748fe4648f708d6ba50c006816f24883aa858c656c2188e1739ecc4aa970cc41430f6438f53d0a183597b0a1191119d8c006a6eac8feb0d9d6d024cd218948d34cf0267e051d4f678f64922bc16e74a84ae6c07c559e711a96ae33788d965f0d21383a1c9a7c877aaa5a5adf01e00d28ae96218e0e0896795165b5a703b40ca9b889531b28bfd3a4b318d4fd41ad424ad2a30036dac46624b6c920cc05d13238b090b05e2647c266f62553d38b5f06094de6d28e9751eb5393ad8811ccc3ba6ea8bc64c81f0e6bb07a3270744d828f2a2fcf5bda016e6f95c10f854989ba9d7643b9fc6482a6c883eacb02c853011a533d190793dd58d01ea3514bd3f5d35600be1ceed1f1f89b5060752a2310b88a807c3d549963fa5a022fa98677e4ccc4dc1c08bf94a215c51dc17ee6a384eaf29b83174149e49afa213567199940c8d567b2d41b2f6d14d9cadb14998804db6963d41db27335d1c987c590cc80c02cdc1f7944b0dd871b92ae78e413736fca3895f893a317732e85516d11aa153b8374152158be46c02c97e1d13e439701ca6042556ab607ae6c0380f1df11b0cbe7cae0dd5c8c36f91b89741cfbda161c0cbfb148e068a4f39b24ce82c82421965fc95e44b972697c8f07b609e5ea5db4d92906b395a7ca3e1c3361c17461324df1e87fa5d1f8b5dfbb00ae95b7ab0f4adcca9f08330b496b7a0667a4867d2759387bfabcfa0e4e5643255b1da70b11a6cb85cf309312a37d2bcea880d12dd841c58bb1ee46b15123462143c0bf5f28c0ef38ea22a77a8cbbb40b606a5014b241cbf2062e8c22d2ba419ede388036927685507179b32907b547a00c741f89bc10a4ce5f6ecd317e261dd19aef7211628f972f5359e356121ef5f726761bd2f3998f49c1ece65a4531a73c9efe9b18600d7ec727640b9ef56df057a9a7a549a1c8fab93748ab3616720fbfdfd4ab06266b4696d4b1ca70f56f4083be5294f5682f00c5931275214482bff98b484bee4b229a57032018eb37fb4ff76372bcf8e489b36e2f9c98951184f1b05a6eff5ae18492a555f5777d277c313232ac61911d295d204edfe98d9257f849c6f7bcd0a2d2d226e9b053de004346fce67446bcac53cda15c24f58ce583dd5f6087a9804ce41e5476e26683d64eca0a4b377b75b3d2eca822885d26c4ead74eb85675dbc58884ed903", "6a636a00", 3, -1127645152, 0, "52d640156cdb73118bbd8134562aadf8c6bc7435649b86f7a28fed36404beff1"], + ["71b2b80e03a5349d590c0cb3219e07547e063131aaf446a0fec6e9ee6cbdcc5e980ac7f353030000000752535352636aac07c184b1709ec8b248c661f88be75a89b8311626c17e370fd0ac7ee4f5305ce3c51326a3020000000165ffffffff4f1491e780a25081153b75cab91904fc7e66805711632a1ddc426f11c461f60203000000095252635253526a5251ffffffff019a2bb3030000000000000000000314fc300000000000000000000000000094abd0efd883c1398d3d61b3490116b2eff66de6f99c8eb49d7af2bc20f644863b2b4184ca7419ce2445f69798322177a10513cc8c51d4009dd26bb4bf4da5bd6438f139b3e23cb442af1303b9787b3775b28fc350116f06791f68f2872a9cf100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab9537f327c3f08fd44aadfac200fa190ea5e4b59e646697d1f9bdf944aad1f996796431c8dc76340b8e5b1d40b8d0f70ce0b9b7059551b429063e00ff1ab89d15f833275f37979de791e4d9f291f884cdc1aabc007d5d0cb8022a9b0fc156fb9fc9ddcbc2c3ef2ce761ebbf3ac1cfed5250aa0a971d4c5d723c12430fecf1f4031c7818a7cffaec294e98ad75c04cebf3c8ea40b6c0435e7be0f47f67b3ad566103271831d845fbf79d69d891a88e1f1c71b7acdd871682e4d392c04d10d75c71bf0b0099f7d09dd16b0c2fade5c065722a4039b81d89d4e2b99ba87108fb0ffc6efd76156aa946b0f0d4bac7c5766afc1b93a5f42f0697bb7f7c0de8b465bef3e5dc032fbee2efb1a7a67d4cc9c7b4f077d50b48dc5662fa5cf25a9178837a8ba1095f02015680500048ec65905e5eb54db904c92500d67299e0bd3163647bbbdbf18bd2021905eae619ed0b4533c7bf0911a12be14edbd4c357046c9e88abdaa192d0e666020ccfe61d00bc1a324db9b739fb50b9971cd12cb462013e6fc2ed76d9d3d36d5d0320b492170ab84037a7711ff6f3b37412e2f550bd5d5158456c50811d4bf683b9494984d9fd33dad9de87c074aa999275b3753a596333c88eb7097e23fa595468d85a8bd7824d53e718d3cc006a7b2feb10bc33f266569252187f9246b16a94a26ffe3f56f25433ed8cfc617ca94eb6a5232ddd8891c901118702b10960bb5d81352b4b0a0a9f0c7a7e19a672033016f5ed3b0cc23848db22a3ef9d3abb2f5563843d5344c0e99345f0393f21714d4f44b48f231ecf538306b2900d088dff4dd105a1dfe49dd0137d6532fc461cf08f6424195dcc72920ef23fcf146a2a5fc9a28edbc2e75ca34530135d870e3ae4eb610a74d647393bd84b0b3e51e87a490681446f983e587d1b7a4bcca984a6675f0f45bb976dccab781b96fd5256a7ae0210ebf5cf8bbb95d67dbbcfb310f4a350e830d001a143060d2fb6805db689b64999f44e7122b83d55e1c1e3c3e9a991d5a2c49c9495816bf4af2c67fb7f3d6018163a401f86b40b9c92c2fde9ef5261224065162addfbca45bf9c27222742e79dd15bb7ec1ca04db59efd7cd48a99885dd6c8b675a8492029be04920974d2c6222840a8e65186d48e229595e1941340d763f691c83fb17f217f868f28a34a237f95d6d8a63cf737d22f7b989cfa65d0322a57d87065c9854f3640988fc7d232adfca12e33c62062aceaf7792db7993ff0e936b968e9fda50d2fd32dddc78e4ff7457347173a32dce10b09097f37bee8771421eb522366f169a0d8b58adffb7c0d569bc8e312744f32252eb70a75b0317aeebd754d650bc2db04720a96c1b5267f0c47935e30105172d29b84e04c6b3a35e9cef01d5a866e032b94cfc498835e04474687b2e4ed4c1a42a302f21c068dcf78914ae6369884a1a911c420befe89a030b77417d4f042b984392c6278f4a31f4cd593fb87bafede372d5f8f745b02912a4833a6e7a042781156b123260cd84180d3e86046bd9d67cb15c5ebf036d38d22c41c66cc8700d61ff0ef70fae33a3650d17f3bd8bb3dd0520f0ed7d08b166fbdb4f4d5f4219b203ac06e9003a0ff71daaacc5cf578d625d384b5bf164508cbc0cd8e14cb0a1498939c26e1559585b7149a8bd2fdfede950376b642aad2b01b89352d3ecc1098d67a0df4ecda74b16fdb6225313c0f708ca57cd4e24dbd4c81b1b03ac507849805949fc76385d44a4e818cd8a801031f4de143ad44f09fd4f9bf4688bd2434dc6e82ac16d036a2dbfb3c81046ab8092ee224fdf03ca71748ab58916abfebf0a9d53133c545d3d2a29b8f042d150a83f1c56d39434b2638b2ab144dfa1e7c97f0bfb62662dba329420afe7a6d283a3e5a93ff37569bd85b33ba4bcab7a40d188f7b4d42d2fef8ee1bc74c8b611cafcf37ddb9c4fa17f9c493c3af333fd0e89e570fc4dd6ec5055005b63c78b4f12e294a40e48217671e49fa5d5c19a36a9e9d2434931149a66c02441aea3499f55dac6420439ae0bc8b04c006627840460cce312f740070ac9b4d6e7a9362a946165bbee157d7ef7a8515cefa72a0ef22c8870381742cd45702fd8df60549555e0085f76886a14944fb2b05c4e58e8a8369eb5a1bc5344aeb4bef90747817d5320e5513d7459dd4b0c3d62a8c785c55f24bc96c7764133cbba019d7f24ca02dd83572bbd418757f628513e8284e85d87f8e7cb9147b0747150204079a8ee2e874f809ff3c63b00242c35482948775933b2d88441a016cebf7b4ad82c3662a9000000000000000007f6ae300000000008f1108c66fe8018256c742ed3f8e9f90c1e437da54080eb7949362f911f84189e803952ca7bbf69f1186f19368d6248a3af41ab7c92305437568534d235670b6d05c3329e2c2080b2b2892d01831c64f3c03c8b52f72b0dfff9101a398c72c31000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009808c6cfc3fdfb9bcdfeb5d4cc09be6bebfc8f72bf257eb2b43d0234ea07a57f335689ae6486a4d72a8362d272f7c506b6cb9b7962ecdcfb50e61b5c7517f21a57585a78db0af02361170a8f0158d99c1f8dc3a41c6e6c4a5c06d9110c0b374da25534f65b1338a598575c48801fceddd13f3b3d4d31d36c1262705fc060b29103198dcfe54588430da3c5d09e5f83a784aa0b428c9a192907c5a431cea771d8cf021a17add2a2bf93e2796410f482b4edae32516df2688dcdb3ae801a50220aec560b088ec6aab1da53e43bc6d7872eae3547bd45ca9aab2412d9c3ff9c75a6a5d2b9b80653a5db3debd2b3534e7df0edefc7492f615417f9fea9d3945face5ed5403030eda6056a24596319185bc63e8f69abd4fb76f575e2a12422a7abe0d0f23bc1d030cd00b561035c98d7bc2052502f61e6de29e1583e25f6a277c46696c68d7282a0221d0032a9535cddede9cab534498769b08c391b4d25e23c2e7ffe079754d5a6a031bcfc2091120d28f4f81883ef5e393c7222db58a009e7fd2cc01a1aea0856b84030c934efc4c8be1effc0f1ba580c3fd535f4344aa0c80ce4924e96558c796651c86f945647eb2ceef0d16688597301c551e4b07b8b4b1d2b63a5f11bfb782a67a8e8fdb7e3da1e7ea63d0d4e88eb14e313021c653ee49c6a46d8d1229f8b8ee9461e00f9638767ac250a9cc45a2b0131afaa03276ff447f6dcdc9d39bad82a4a64217f6eff500be7ae999b8fe24a0f8979c6b07e31cf20bcd43ae407cf6c237960336a85ec6f51ddef20d4167d004fd42d99b5560f09bf25c5ff0768ddeb595b8cabb372ef7c61e36c1b71189fe078f247b99bbe82c76ae6cd535f5a0270b65c2abc64e9a76d618ed27aa692e9aa7aa7a5bd4c13f31d596b0cace230a98de4d9c79ea20ea7f27e8b852538839dc6ee61634cfc8bee11327adf227633d2cab3add687d02b32b86140513d430d6475eb84444576d1793ef9fdb21b9f2226541624494a29c142d677275460b82f8edb0b56365b520eba64335e5a1160765ea48bd50c0b8f6212cc2b38c81222ae83f2e584bf08dbf3ecc266f5869f8ffe04891261bd79545af6562bb8dc844c2555a30abda9aede8432b7013d9c794ecd3480568ec30ded0b9275dcada8ec6c7ba01609c31a0bd2a405c7591dfc0ddc154b697586c43f396a1a1b9c6bb6dfcd0115428cbf71a03f8ae199987bedae21652d7b73bf56524f1d368ccbb4a957e0bd24c060a57adc0cdf6cbcb110e63c52fbd11e8d7e98ccb0d6980511f3c80c29d96bc19cf75411dc6016218aea884ef1de737c718b1f6c9e615b383c40af563341fcb4e6b650832f91e66c7e34be1d3780ee39dfffb8c829ca85433090862eb7e44fa2ea65efd2c286c1f27014c4ef2f3e7009772341def35255dc18f3e8b969f315ded9edd073ff948b37dc1dfb18e6f564995bf12b7955667874ce89ef2804d4fca1e9f1130ffdd23795740891bc47aa6b1b4c213ce638fdd102d91158f13ebcef6517a9cbd76a604cebb59fba90890fb3877e8fef0ac63333de1f8d333465edc6e74123734610f5eaa9620c6450d40072fbac078d44125e695b331fde7f9fa49950cbcd8f9b7a303464a6c0f4acb7fc9c8881fe2375758ee723d7535755d7835164561c4d3b8faad1131c24ea9131efdd72e5e16eb2d6c25ca056d25e2985c72168bd391dd6d75b398e6739cdfe672e0f4bad46a2f11d6792e4f9b6d61155a2c74d04203e32ed3ff9ff12df90be77af303fb18d59b472992026bc28220eebe9a09dc9cb56820ee5cf21e9ec921d27d798e3c5ce0881bb9d0fd307f3370c30cad0c6e64646e4bfc9d7d3645debf0e97f1f28786230d89e6b2f1f3eaa80b0bbcfef159509acdbd89583038c6c9ed549dd69a6940d5c1bb0cf0f203bd53c886e9740c1bab18688ee470bc96573fe8f44213817a6cecdb8e6265c790ec9ca7776316de44bfba1d8d922e46ba02118895d12215ccf3a59ae861dd8652bb888247a23397523ade7802eb53595cffa90e6bdc4638d787615e3e02a6921401c3d45e1fa83fbd8b75e8776739789568023be262cde36f96f384fcccb96baa1f7db29826889805ca615c374dad720b8c69477519340a68b51431f9479c3b438c73953b87aab352d2854a575d9af684343223d27cd64c75fc70a41c05cd0a7e7e98b3b0651813c4a0f347974df82291abee1b7df5aafbfe96ada8af5ef2317a3ba5d78f22962387493e1d67e81ccc061f4fa4c42c3f319c346000fe4ec68f70d342e7d3bc368914890254850000000000000000de04ac000000000035cff9e7b9c257bb0f84765dd027db1598ce8c6a39593bbf8ed0f12e80aa8a56447d21d2b1a105d83ebc25aaecacc09a1b8da70ccadf888a6bd49354fcea5fb081ba663c639f9376e09d78d66f584a6559ba8a19cf34ddf9981afc670f8af8360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000073c8f8512482625936861087a9fdbc3afef3212f1b3a000663445864e84d21984ef3b61090da8f539a0c7d26a3c83d6f82e3b1a39e1f6e7bd3f8882317aaf20980cdcb39b3d964f3b1f0000200f9b65ddbf5d4767f2d143103ed689d63089012dacaecb7c3d707d59dade90038dc07b4a2435a563a76d05a64266c7871c9a801021ee8704f18e23e569f7aa0a880cd9b38aa5f4ac52b7670cfd2d1e8fb54b50361021265a887b660e22fb91dc1eeae1382cbbd8a60bca0a9c61989807e6b699829e20b02488dee91ee6b1d9f19672c6ac35a1e39b4f33902ab9001e81ef7d123e99e98d32aeb3d5e12dfcbef1dc6f905f24bb7c803c168337656207f24e1f560273d270311f88d636ea09b1f16024b63f7811c3d1a8a50e143e46ac155ff2be0a1fecdb60227a9fac805d0f435bea29fa1b72ea832bfee5a7207726e4167d2cc5b3938251d031ced0bd29f90cbaa96c8cb98d852d71a7344c94b9135d44068bcb075645f039702211a3be7e44cb1d9733cf141f5559d70e6dcba3d720a7ff50fa3272aabd2e134022dfa8e99b6c07f0c59c2058501cf51bdc2199a9b3a8b4b7f00b509ea4713ccfd7143dd6cf34747d5220a181842dd111282897e787ce0f50e087e1db1b09d7b076376690420af40056499b30769fbe132457496a5e2001e1e1cdf4aac8282a02bd7bcedccfca77dfef1e89bd99a957069633b256865c799d5833114f2326534837a5b13b69a6b8fb972a53c1c316eb34ebcdbad8d8b3279334aa92f558600ec880efb03460953f6521aa40139c337c27f466a56187a62704c79d51773e67a73e41bbd3aedd29a3c948e7deea724aeacc32880ecd9671ccf2524b1559330adc3c81618c55a76e5510a2ba46c8baffcb571ea9540bd5f2116945d1d0688dbe29f2b251ae5d52dea15e6684939a281130d858c08c8085e85186b19fe8362d21d855a680d0fa4014c1d291fce0f3734e5ebbd7007021b9d440032b3a538be3785c641b071b73373bf243b2951ab06418a4caea47de1223c60ec5ad307c82fff6623281481188d49091c6337af82cdb7caed65d3520db958194dcc335df770dbc623694977472f3bc4bfaf2358507dc7949e9161769c4544b8e2484206e1e9cb80b7693766053143738f14cf2191782be7383c36e5435ad600932639f0c1ad04de8a8dbbe51d4b1c32697d3dce36adcc24fd7db659c46e8c2b4954a4c3aa465dedf06ae858f3b89e97abf307a24d93d849d9902bc6953f86cf4cdeaecf7185b9639be690229ceb479d0510f49c313423c20b7cdcf60b5d58f8d4670a222796be6b3cd531f44a248f21f8d5670a99d9aa209570d0c0c4e4c1c9d1ca87808f74c600f70032c07e046adc78a842258c2985e9fa21ea4ca410fec187016a75cf45b1cac6b07e98df2187d43d736612c90c383382e3225851484e1a504eaf281c029ad479509f571a6f7e3cff9fa095634164a839307778c37848c2d4c0fd683ba6bb4b71b0f901a298908004d22edfddd3392413b8eb2abbd45f2d8148981398ec351c55cb7cf2fc9938fec028eabb2659e197b16ae2c04dcbd031f99979ad0a90794c0b15dc5126787328fe0f9f222bafc2135ae2122dd9628ae1af9d20f2082d47926f878d805eb6888ff4e6a304e28366673ec80457d00a04be9a3f32e76aa4053c6fbacaac7dbe8b0f27503eb4364d5c9ee550387bb4484591d4b92df98dd75510069a54a46a595f33352c3e21ed92ad7dfbe367e59d7b6f4cf187ab9cdaafa19d51de10b4f5717f840d31ceec6e40305ae67cd15ae623066cb9af359273741a9b0dc3a5f56107f8ec8fa7f81d5ae31cb8e98ba8ebc48961fc2eadce74dd2b1b9f3db25f1f150964317a79ca4c3b13d5cd08a97d5816c7d768b033c27fa4ad7f3bfb5164f48be15f72834b302f75cc75175ecf39712ad3b22335979601bf760543653f5a275d92f6a7c2cf6fe5edf459571c3b5293460849c2f3522c30700100d25e23be1727443c70804310df59cad8831c24be3f4fd32a1e7d7108ca59f181a687e0372421a7b6a19e396058aaa9d182b64c39d3bf84a2346e47e96a43b191bb986b457d92bc26ab9c8411b146a7f53760d4ef9a05687e08287528ae420067155634cb9dd61723c1e2ef330d5cf22e81665832221e040ab91f532ec6904b1f05897cde42edaa1f114752f881898d2ec844ae39dcf877f31a936fba5d461f8c74cb95ba59ce313cedcf61390be61adeb4991d89a7c1dc8e37e0766f4c49b65db3ff62e6360420740388d71f4b7655c13b51d11d905d49df291d86c079a17e3068fdf2be0446499ee435198cb039f5e18ea737a7d7180711f171ce8d262742616f80539b182ace66603c1f77d04ccaf0cda2f38aabb3ef31e736a4d2ddb99ddc1512f32f54429c1b9f3230a2bd2bc6ddc38924720c", "6352", 1, -640717403, 1537743641, "591658179137a3441e5932437f119588503e9c1d838eb31ef5eda9fdf1ddc740"], + ["030000807082c40303fdb44d13310c4fd4391b696573f23ef747c2658dfa2e6e3cad40b71d5d27f96f03000000026a51ffffffff87e0ac38f41a21bb1e32ca6be16d907c61a1fa84ce9c8afac549a56362e5f9030100000003515200fffffffffc054cd9e5407b58442131246ff8ec5bec4cdf7166f90db6819bbe6a713d9e0b000000000463005100ffffffff01dcfc4603000000000465ac515225e39cf600000000026fb0cf010000000000000000000000003da3985d4cc079f9aab5e24fe0dac5b09b02ba801a8fc8c29446d24fd65bc77ea8aed5ecdb4caadcaa4c530357b95f864bb9458004f5691aaaddcbae969ec2dfc15e1e3e13df9ed9160cc641f1804eeea8e4982c1f9f12e54f19569706372e0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007274c7ce972335ff7b778780cedb909ee1323f7f43d55ff6e04a68c859be659d6f808b52450423ba1df678dd36459242feacd44c7de063e8fffcfec8518727aa70d23fc65022054a14d44f9f4f3cbd8be41146a61fc279bea698472efc5f910884444efd44b6c963898382bd137bd4f241e3e736f74f9245604e03a7551b79d7030b16c2d7880332204c5ef56e3b5b9e86050520fa6f65c82965e04ad5037fdf8202021950c54a448ef3d4795a1be40307bd097ae2649944b278ae6616746ee136340a009494ccdbc2240cb79966d786dc78486e23a66c45f31780b692862e8e61df6cd79f140bdf8ea75e3cec6fd7e74efe3797f09936c388093c9537bacfe708d643022df3e80619420695e3f5493bc1dfd2f543d310743130ca030dd69fc3fbeff56f0212e1497577e7e123728bc6a92a4a0caf835964710b1516f4cfdf722208325a570217e1cb7f13a1212f05fd907e4e0869bfd07b6fa5fecff3741f54b9319fbed930020d7ad99557bef407ae608e311c907029802a3b098c21d84a346881ba6d1fd5c2022ef45009cd645f5717582851cda547e4d3ff22c65811a8a02b36e1c6eab5d4bc273e24c95e1a3bb4df68a9e2422dc393f5b90b71f2703953aa99e37668568847dbd1c3b28c4b07ea4c9f3263f01253fcf641ac503dc4f42539e5efe63e71b68e91dc26326a7fdd32faa62487209657dcc340d61848ac6f26f7e2e5f511cb9df3e33b7aba6ce52d2b40d006fee58f59ae22a7499edfb56428380d5b5b550c36e92a66c9484cbcf7508f330a5eb731c7f0fdb705fcf6d9737cd4c40dc8a4b58bee66d2e4b453647773d9f375565318da961340b624414123d881b406b0caee8f982d125e4fe4fa7109cfa5daece8c665c58399c9e19630ec48470d76eaa02ed82ba9f0f9dd307769e8b53f51c40ff1ff21c6e28e5012ce335b34385c46c7f00af74faf64ceb27bc564054c4c3534686c76ed96156c6f8d9ab338fbc3f7977324dbb7e231791e0446c47d47091da1cab619ef032dd69361ffc955813bbd3091ffe01b7add926d0364a55839a068ee39c0903e2a4b4a2c2b13aa93b9ec3e9584de4af2fc80f49d4c17b68a828d40dc6ccdc9fab7a086e3f0eb6eb407702d3925d908cf56a3cc82db22221ef0744204fa8c8f2d2d8f22df72f186489decd8d541f36fe9836194c92c4aa7d47a2247c500349906d5961a425701800c7be07ce4f1362d2961df92d5b58c529d0715fb5ad19210b300853b2b8946c41905c72d2434f2cd9b4ceb6f482e022cbf9aa78e09a2ffef5e791d457befb162aeb56a4f3588c5672a618938e9ff8bb161cc6283212a49432ff83cab0cf4e569972c0e82b7675a16407e4a7048bc7b7b3344dd1a52f3dadd0b23d1e013db70406d3dd57b7cd3adf681a27fedc02e1e21047dc5cf80d4537a3d73e63b5a5a6db3964802c8a3f282452442d4ccacbe280e8e9e8364dcd837d15ef0ac34476af503ef22da979aa44f67f3033f7a94cdd8d9e6625fe4c465f964e7529fbd0f1e0d4e684b7bfab1c947695cd8263cdffe1dbbb79f53b240f5e6ca7d9044ae6001d589fac641fd18ada0fe5cc0882bba1659caaecc64f325c737e41dc2b221325db99f2e53b289ecf4c92ac41a5df24dbaf45e0fc3d4cac404eaa9742b65e364fff08d4467ad181f3c5d7043d6efbf2f6f959ef8504a7d6e924900c2ed479d50049f122eb73a66e25699f252197c22d23ab75d1e96537e33d1fc6ec2ad7d958bd2b62f047a28fe65543517717263ba672b6c2c9feed93d33a6488709701cac9429fe144c65ec2dfa779066dba9a36195d750fc6adaa6ad408aa94a9951d9e13386bc16a1f7ccd0ef6b44f8d349bfa056643c37c96c2286bb3ae5aa666691523db1f23b701c1fd086b5c1614c6683a5d9dc286e5313955fa87ba7cde15ff7b840ccf7fb3ec1619574123890469a586d077e0fc1875342792a50bb8d08b2e45ad0975c51d28b5868ea108d4ef277866bb56ae3b10e8f44158c9a3914d803ca0c481ba13ae7af3ab67ecdad3d61a03f4b13d2003563eb4c2e5b23f8e83a7659be74e02267050300c419ca3ebe1a0c6e9a5d915a340b96741cea8bf7cf52324f43f344b06209c000b2d4f52a734821e328f31e26a91f1de8d93769475f2aa9781732bb451ce55799af32c44ee5c4e9a0f645f1b49a269d838a0a62ab376b736bba65fb03e154f094369d55696c0aa14a54ad3cd589ad5bd38369947ce0b0eb725b3f74463b80863703a5ab0b213e371272837fbf726cff9992bd0baad3b90700000000000000006937b00300000000b045e6161e4d0ff8f7c91617b255e985964e4641b3760f8367a9ddd38ef47b99b81e6ade676bd0463922a51743fde534b474a18d34b04bfd57bb38efb9ecc2c5c3103b4d8a863042820b09d2905872841005c6f0a03ab02cebf4d3384570f33f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147173be7b4d928d785f67004779db31811f3c4be5a263a5af0ea40ca359f4c32b17d7f2a645a65fa1faf925b96ad2fff8c9e2d78fbc267ea6027115dfd41021348202704657e7a1818b7e7293f51c2e7d1264b92789f8eacb6f69072d1b0cca077b8ef56894c11916a187eadaa64c651dd02f0ff30181a15eba0c1fda2b8941032b9c742d5fac02af8eb44d288372c0eb4b25e8bf2aa569ff747741d19c54b7c8030f00b553415364354379b41fc22b2a57f3158e1d89de5583076e731f86fe5d760a016035400ce042dba3b5d253723cb267db7c3b56e8c1a876148b3858b2b2413ce9e3bf939958b71b2b40cb74ae05bc6ded22bcbe26eddb74079dc3329bfaaad902136517792f60f320e83401ddae513c1466f43509db61c14103b04e13d19c659003153bde51615cdd1d884a2398763d5428322620b647148da9590a9e3661833ceb02010db99ac428ca120c25b38175030cb6bce8f40e09b9b4f9439e496f6b9bbfc3020634ce79010c2f57b44361f711c65840737126de717296f4f3938fede7bb35d00224c4c33ed2353086a94064304a47c09e9f3f650e7a7f5f86dd08a5656df38d198f4e81fa5311f7dcdc0059efe8ef797bb2f88319c3978bc5148622f4709276a27b72657f5f15e55eca056589ab159b81914b44f09cabbced7245b5611b4484a883511281f481d8e1da593a16182d7f5197b8e52cd5b87cf7692531046bad4e356c4263906a0f0a8a170afad95db50bac2c0e3bc2a7b6d6f11d1192b10ed38a5a4a36cd1efbbd7e3089438b1da3e1af3bce62b168a2d444095506b723c763155c9d3ad33a3ae1b2933ae06bca00c6c54c514211f1368c621a7dc75b0041bd3d108cf5c42a349f27787e02385f0dc3ec90d5371248446fa0831dd9d52acdd9f4b6c9d8ed27e9f384b6dc649b16e6bdd34be033985bb2862abc0bb81eb40dc8cac95d82069fa87412cbd22ae36d7f8b1dc7c14fce59338a767c733ad0d65c9217216b3c921190d01ab0eee4a41255c4120897e3109d3ebe749fae684b7162d3696726e01ba13c7e32e4fbff22e0841bb21a98da6ec7df7e51ed8b23153f488edb2bcf54d63e179eeb7c2ddd97c69823d8b51081217070e4081e9d3996e45d7b5781da51fd55801420bced4cf7dbd7742f98ab342c5a9e7698e839b75f28a68b82e12ea2cb44079a6adc12c7b2108a3f38582e5d038ac827f9fd448ca4934c75fbdcd6e77aa0ab3ddec9e623c24d856228f519765a732a205950a78b3d922ac2cf8c764851fd873268909b6d858ff457f6dfc2d3e8febb3cc36a379511ed0a5567b791f502678b5402c00d2e51bb13e7ee62aa9b898c92ed7a1f65adf71ba2b8b710a2912d5fc6fce62c9dc72c349cb82f34cf90c9962d9057d6603f66ca4c1c2023911f927f524962207f6126e7f0795b8fd5dad12a2f0d7895a700e96f584dd56a4bd0ab4c48acc981a5324f345d5269f57abd51995386ecc0538571d4f0d794627b4775146976c079643efcfdb421217e1a5057ecf49a904b979b36baa7ad79213d87bb7524ff27b24bcfe6209e25ad5b019ca7ddbf2f4635d5d1f7dc70590a4024e66f7099bf10c43fab1b7d8dc664dfa846b4aea236ecd1bf2f338b45c5946da688d8a3a59797c5c40aaf0af5a2625cb0ea8d024c50bbc381019f21f9419c2cd96e48e9088a6f9da08f11bf616f2832d3e22f2b15a89652b157deb73b361228961f86bb11c92a7a891357ec74d6d968170a8795d8a0e5995fc338a5a38b12ca88704544176a251607c132a4ce0c74209d0a404143367d86327e418652c26bf8983dac26efea9e6deab808c84b5c70c4d436133a1bfd7003aa70f3fc28be8e0cd31cfc3d0611f991233dff34bd1e0dd0541eff7e321bc956ff385a01babaf3dac639406668182440be9612e65d973d5ea44b4ff78bb4b36e9add0b7c90f01fef9b236924831eba55a9113145cddbd102fb22b38294f1d8e1df64fb5e8bc9b293e61229da76cff80e24d1756a63ac5d768c4e466805c0e4e8e1e831accf1a4ae7559d09504374e39f93dba72e0a5e23ad72bf3e93a868251338b93f1a5eafdb34c39cd80a71b0df2588e9b85fe9e4497739dd7e3afe9e8f48cf61e392dafaa7a19f106c6f3551ac6b10c8a9eec09b0eec3f31c5e327a4480fa1daa836cdc54d46946e4a859cc47123eeaf6f89dca7eb5649072135a0c42e94902b8977c2fe3fa014f69e411fe10544a21ea7b163f893c776ab55562e6891801a7b89bdc7f3cbdae0a887e1df14a4ac5e59e67e8efc627ff781b86d52c6db526722b405a5b500462f2861f4eb944bb0d1a8a369aeef0f3f9d677bc4b4f1459bcc6909669e2a654656a3fd53ec5a4d94588720f408dd8002084b281263f191e855d72b2b3a565c6ceb71df19ce67f48f93b2c6b2a0cbbbe4ae05", "5263636353535100", 0, -489642415, 1537743641, "ad15e8799f5b484b23391f78f35b8b1872d70e15ee973b2ef4015c0d04d1da0d"], + ["030000807082c40304128849fbfdc3c1baf71e0d9fe06c66015e05200debebd14976dc2b94cef4c1fe000000000451ac52acffffffffb62de784bf9e213b1a101adeeeb3b61d2ebb8c8bb5d417a6c2bfbb8b6b9bd556000000000252655501a777db8708232bb9d16d5bdabc06766977c6da40486d3e4cd4decfc4343b1adc20870000000000ffffffff6c3c7aa7b69a102479a6877a9c9cd83e387cd92985c4f13122578a157a42ce7c0200000001ac6cd1dec801323fe40200000000086a51acac0053ac000000000091d4d04402178b0a03000000000000000000000000123658917cd6c58aeeacd645cd8c37755eda80995b8d27b66aa63e75c2d5476d11ceb7645118ad29584d9c91f46cee5d9d464ed97ef8f7436b6fc1e2de2e699edf46208d722cb108784f1673722025b07a782f081e2c5fd5a8967a470780f74500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000df5ea280917101851328954f8be4219058cdc56685dfc1036b035b30690a1bab891db61c9d96699aa7608988493a0e15da0e672def69215236193f4a4fd13722aa239580ffa9a898f904b6dd447bd321c6a9ba8fe03455116be93832c400541b8d40fb99cdfc6c092a9698fb6723d9c844452e6f0c5fb3d348ff27338d375b7b020b82817af2adf9195476b7a34624b3f5d195a9254b4d2a365fd65017cbbf32b203101bc21a2fd5201cb73ad9f9e8521207f4736d5b79f32e54b781c970fb43dc310a05c39b2164d2f2585d0cc2d86196f9c8f18d58de257982d90872d78fe64d5ec8d3ce62509c697e28a2e900b3755c3ca9c3fe322b810f2af7f3cc59c678eec0e6032a9aa8beda1f29311c1dcc428a5d3eb250e6c00db77e1374c0106d8b9d370b2f030f0bebebfc8d4adc17be79662afa1235fd260147ab046a0639020591f48aaa0b0205c8e354ce5a5b25f99a462b552802a76ea3e9a3b111cf88e7fa86953264624f0326cf57b7aab2814b3fdbf0fa33afc83d1dad4977e07d40cdd89c724a435f047803002bc73ea376ad884383a56acc3a08b42312d2335d5bf398213c214ebe248dec6796519a532746a2e53e3ba06714396c104edc59bb2bc3b4845dd91b5a880e349665ce68c7a0e78788c73b37ff5c7bb35083220b01a17a94c3ba092e957db30cbbad32d7de7e312c2c18988763fc4a8d3a4c976b617c29601068c4d0b82ea966aac075c6e204e35a94f4733f21962b55705593fd89147638c8f97f12a5354af7c5216fe398be21b2ac19b523dced7b388b554584f08c4832122cf59d7a166e21729fc044cd9dbc190c77a9f9f1916289486bde4bef1c91a9904fd54b9eef16673fa055740b7c12b0e9e0f1cb3a5199f7a57e11a230525df169301693eef34a00877e38e8d05ab536679fab6a6540e7ac65f076ab7cead440287d1d634b3d6f87bb9b9dfaf082718a7cae09b450a88b5f2208472ed7e11fe1acd8a3b8f612e7549453ca0bddf3fba2c8dd60650d0edef98f7c810801834f15a5c7e1de74505e70272f01a5084f7e8ce8b4ddf86cc2869bdae83173babf468ad5391e8022e7a24456a434c690a2f89817bdb6e2be38aff2f88682d3e3e04586efe8867d2ee13dbe4ff41a6a01462c3491bf8a53aaed45771e9e90b8f61029c57b09d819ba23ed3ec4d8e2fb18ce507b4a7304ab8795893956288fff3b263ac61609d9f44711d9a2c7956ecd793bf7965b9746b9bf8d28dba787d3ba621887ae21b0cc0a94719e8ef131f923521c471467aa339f06f0ed8cfa618c97ae09baa185fdb47468e9fcf6f19c841807d6622c004da8f7452cfcbbd5edbb30f18c154ab8001f60cfd49ec0fd70e79df69a6a1183c17fed94df2384520a254af14f6ea6b2f9890f71bcd7b077ef049aa3c8b51bbed6141b6ceccf2b024ae8deff79bec2ef710da564a5a4cf28bdeb8b9269153cf0ecdb99cdffa98bb051b1d701ed18b137c2f2eedee6ae7bcedeffea2c2e16ce8551caba48e356637110991d35b2e5e9c3594b4305be14fda3c9bd0bfa8d8d2bb4db6b638cc46fdbcb2029212d03b30882aaabad5cb679ca8e946d7a913b07a0cf3a93958d8832d940ac3c57bc0d6e04fee270fd3aa20bd165ee06cda9d4dfcc0d9a65c68b792ac226a20274b6469bab522b2c34df39ff6263d3a7fba0d1a6ce9bc0d8ca9c1f8a63a5366e01b7af4b4ce0faef306d31e97ce6812381cc88157fb3551194709953f99f86e4f06894ad6966da093f635505d7c2f2892ff6a8ec4e4b42a27e0ae41d3d80a5d90231a0730985890c73315631f99aedf05260fa2c5ff79ef7b32db11c3052107fa63f8d006c7af40b9756fae82d09e7e12051b317e122c935c60d0ccaa248f1c7079511bb1205c61c11e73ff780adfffc2790eed14fe3a7d2bd28b14470ef3fb41b8b86d2cd412d082a51ad4e1e6098dd8d495ba0fb9d237c05dd31dcf501c4f0e8ceab3abfb36a8960ce3a4648f9ccc907f7a9f602542a28efdcb8e73478f28d286bc065c0696129df8bec496022075c4a6ff127d191b754dde7a84ec0f0b8f54afb27407457473c64b80ae6696f9f6c61d88c7a63462f223cbd368a9ff947700ec271e5efd886bdde1a92c1ef2148f357312c78da2a39b1865bb2fbcf398f0779350a6e7ca370d6b7af6e37be2a0b11b1ea3b6387f1447c92febe8846f70e962fdfdf69fec95b66338c7c96194843d5ea318779acf98015b7d7d19d8ad2a10e46061ea3f60c43228287b8b4b6b68457835c58214acd74d774870e77c76f4c0000000000000000b9c33305000000005b9ee7d96bc9c33d587a83a486c28ceb2c89785f268fe56bdefd83e366b62064da8e0c05acc3e8e0b89263cc160474a9e44489976124a0652f3f2167bfc2caef729778b281c7dc28af2f4d0c63425cf39460045a41b3829a72ea2e9ce8e2171800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d96a51c8ca8996bbeeaf88a5e694f85fd24812b16f5574f0b8d524edebf7d10dd66dd79f8a5c21d4d0f9d4b1ce125973a8ab6f08ba889d3b918354a64dd2b74df9e63011ff8bdce7115e3592a22b78de50401e1fe00cdaee4352349ee68467734e7220c7da39085fc040595a8b5956b55403412e3f45f73dcba7123de4b56d5b022ada67d0386bfa4a93a6a09762b2f2e95abc27c558d10241a06510d5cfee6b62021a0e00ac0ec8a113813db99d6a936b77d4f4f6ba559524b08c7cbaeb2328ca670b0337087500d9fb15fab1fe839b133126e959115eb33df768d61fdcad5679ec8b1aa870f0c1c5cbdf8755f061057b2b6d0d90c9471f2520046bd287a331b2c6a2021f16eb2647c4c07f1876727dee04b46a3e1f9ef9a469b8bbddd39f850c95cc6a030f13cdf899bbc4c68a08d95c9d824b63c06722999a7f43b385ba783627bf294a020144a2bc91b2557a646cacae67ac16a642f1689f535fee82364cfedf38da49980316c2aef56c21353539ffbdeec73e3ef4de5af1a9895d1be345edc9472d5551c5030b7c9e93a48f809f084cba18c62f577d825399a283b440dfaf3289e239d3c94e7c70dcfd1ee534a35bade280858d8ec51096a539f765d498e6afe0f45e34c4860778f3bb7837a04274f39c51f438206e1d8b8f5d8dd2f431188fb986f9afd65387936822156af7b0503562a5b15f811684bc37dcb5876acb4e394a29fa8aa61b931cb9a0a8e0cdcc0d5ef2ba7f706bdb57b46f9b3bb0c6d8863e5835e0229b0463661d74b734f05ca0eb9b601f514985c5dad4a5c661f1dfd589d368e0d7fb8fbdcda3373f81a9c153915db71ad4b59a0bee04671f06becc6bd862a6a14c3ac42dcced1a390f39bc2e2258a6fc964d791d4d1c71597c6af60cd08d1eca357f37a5915574c7f480ff1c58a7c9e36786639a203dff25d0064691fc769b71cec0fd21a9e586dccb9edb95506416c6a5c8ce6ddc4cba57d38135bf4bb33434f955eec5ebebc1109aa406d1a9aaf8a734727f48008eb1fb4129b7b8231d496366adfb89d0fc037e7be02a93d9a071aa2474bf40af4042c8aeaad4edceaf4e426753c6614eac1123b64bdb612a4351eada09560d6dcf88fa9af8ce3040c34e0bc830168b954f5df7f448f45be998cb74a670f32acdc61d9180da815ecc41b0de5896b3c7713b583e4dd9e7142412065a13e01b12ca6e2a6e9af4ab20086ce0952a5e240991468ee879cc7710ecd6af35d9c4b1f706f6a71f69c945de6317fc13343311e000964e7a04c586978953b1cc27abdfd6d1fe9e46cbfa3bbefa47d042ea7f7176e0b03986ad1bba87e5a569d5b677a64483d602bc2101b871769ca194b831ad7a863f7ed6e42da68d187ca8f6f8ec03530551680d8361cee02b7c4f12f20c7c6ffcf28d104dd3676cefc8d164d76a0db8a82d87d703f20efc66663d80d1bcd64624de3ad91dc8d54effcf878666bd4f0622c40164356033f2628d715df1e87bf67df686dcc8e4bada206b82cbd9ad8ecbdeba9f84f7796fb25e5ba05438648921977f1014b41b6be12b63e862e7d87ccf54bfd8f1495229cc6460ab2efa0d8ccdfeef5757b20456f9559a4d63aac4b64d2681f08bbf221dcfbeb7093900c99d253e08fbddcc4116e361709562fc7207e5363ea15e17a499dde1fb50ab06f30c5c102ea082c510199a2fdbbd4e5d49a496a0b94c9b527174d57477f0ea12c91e1c9c93152b92ce58cc99b0ee5c7e9f632192ded603de4d870b635bcdf80483c238184f1a5dab955dcc1e606fe90ce9bc3373d48c4a6a2c890473ff755d45d35df036f3a39450ae2552df1837f1df252b67e1d9bc87906bd567cdedda96e1cc8478957aa534e5da5641f254e7321fb8138ca4f5caff811135a29b89fcef7b5e2c643920513ae0314336d3a6295a5c347008f369f238108e04e3cd336ba6665718adf871e5f9b3d0f816eb2f60be883f4e1dc496aa5f741bbef9c605ff630d38a7d9d26c85590e24124ba91e2f66db192b27e3682e437a74903ec3e68870524cfaa17fa41527506f12cf213634067d04a80999c10a874b0b54d94b221acbc7856eda83190640f0e55b76a500f8307455f28c0aa70b601bd7a48e4d1941f838ff5d65a5e7d148bb382b68f44612e8997f7d6c043c1b94e29a6f2a4ad8c1da2fab462f1e7c676ba9cf7b14bce5304e904c8bea90328dac505075a720393569fae632c2bfaa3b1aad65356316bf6c7c3962900b31f410204d67c2adfd7884417ac0c076e6b648bf5232600dec83869f1b9da1a2088d632acbf3e9be0044d4eae711094f3007cda77ba0d4bcd86653d41bbb70d86d49478c755400db28ffd53c45fb9177f64009470cc8064f202afcf0c2cdefa8dec6fe4014938e22433c3119517a3bf5f94c08a99fa2d8ad371b9f88edc7aaa100", "0051535151", 1, 860576797, 0, "a06b8d443227e2ef06fdf53062656e32048ca0432b9b5baf3310268958371f25"], + ["030000807082c403023cf1ad2fa43014f366ef6040bfd923b5a4aced432ae1fd5e87e2bd340b98007803000000085163635263ac6500ffffffff58383abb65de0444c374045a59aa20556df5a3810a71fb8dcc52f29e512373c903000000016570b9c3d602f876c90300000000076a6a52006a6351ddddef050000000007536a6a536a5253bca2c9260000000002a1bbbd00000000000000000000000000724bd4333a168722303a9a74dc64fb28d6fbea3d96eb4ac95ea692bf6c540312aceeb0ba69dcdc81b2a66953ce4f06a4de3edfea224428e3755f8b95aad6575fd5ee33f7a824ebdaf06f2e7166ed2bfac73ee549469a947065599bbada09a9bf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002886aa6014f2f9635792314af2d8f22554a83b261a7daecafe2b072b5fd9d47aecfe6e91730a4e3b1b3eaac628688c4345ed20e03da4ae56e088a7c88d1ee7965d6be74c4df109b21bb1c00a1dd3c4d17866f16498ae8d74b45366e6bb59f464311100d90a349c103176eebd08792dad5e7accc64d65e3fafd0e9f70f6c1719e0227acd0f6ea81894b6b1876c7fc7629ddc210c750c8a589a443c18d8649b38cd9032c491f7ad8c60915d5886948fdc3d68aa37f4cfa1aea39c8b0fe184f046caa6a0a048d9f53f2a6bc14aa6316ce5b2d472085743d51b23f238d60bc75f1dbc53d0cbfbee89d48d6969196bb51408933a8791fc6569dafbf992d611421d32c7c4a6302159ed31f8f4559827338724c37c67aca5689c9676154b23b2a8c4cb0fab00b3903064cbbec44182e857a713d3a7982fd20e33c8c396b62f38784048ac673fa810c030a91c7d0f787956a98a541c50e758aae1a96bfbf94aa5f7c147f0f8c976aba0303285c276780ca4d0cde7f57d576b6c71017c6358ce784fe9d8f4e2a466e772afe0224b0c9592602b76e0a02ca11716799022f2f962dec88a9eafecc76f1e86a9435fc2eceed8eb93cab3f9444d9e2c5790c1491e988bdbe81560752c59979bdbc4061963b6666f037a88bb4749045c4bceb07c29ca6d6f280578b01bfb9c96ff3bcf91fcbee5afde900d7f4b4996d6e581f10d7f512e38f1038ff33e71e38e762e44397342e0f3a7f605c1c8e3d759eb32804e62cfbb3ec1504c5697b3dc2e18fbc162f23ef31d853ca17383596ef9e31ee75c12cef5d4b50fb6495c96253ed8bffea70127a72d6b30f85c7cad324b99d606a64bf686b8230384d13730a52fbbf1027c8baca50763584c07c004a7a1ee84e88bcb7646324c27f178fab910a1cbc6414c35139c64de7cbf1dc279fb4aba2fae2aff2e833d71ac2e47fac3df4bef189522842420b5eb03509ab9c7997fff1f574d7f3a4b20f1b89ae5fc332f1c484bbd8db44f632bc91df86c940d5c14e15765122cbbf72ac24947e07c7aaa328b2f9900a599be7461ea8ff738462e260a4661bc8c457b144b6e4d14d34075b0b2d10afe29d0827ab48cb9324485134810abdecb801561d622c8010c97383c30713c8e64cc69f602f18da30da49701d0cfa8a0c8e2da7c100648fa92a0a9d57ef688d8d26fb6c1cf085679f60bd9f069027c257feb89426002f3c21348440e1617e89e65c161d5258e71efaa6377578319b081ad2cc3440d1a3d553c90a9ea2c78acb916f2c1b082fcae18c2804b852a28ddb0f477d50ca42ad225357c4167983c7323c147391d367757bc1066295bab4858567824188a34f96a647f60f4889b8b00717905c44bea63045f91a2b060095f552a2e1960c1a8a893c0698d871f3ac52895778c418ae10677200439373c9eab19a13a737fd7d46627c5da5e0b654a260c3e45e5f78f642aa400db0d27619878934a13a06d4585cbdb29bc2726ce69c629794e5c769b7b45e8e81e6c2d469ad48fe92fa1b158231dec1855ff255ff76709a457ea0c429fb4b9b57459dffe41caee516dbd3d75805e62722bd7ef312b76a34f45b79e75f94f6ed34bcd5e42f1d86098be36aeba8c766fb7e1261c598f7bcfff2dbd52ea0ddfd243e93c52b95ad4d806855d8996eb11e115f600d565e764b2ab009ffc356166baa0c4655da0a70b3a818744cdb472297e665ccefe783bba0d76e29a9c33a7d07aaab36faa836a30831057ee4f09d48a211096108b0a6f4fbced0521b400ea7fc0cfb7b8cb0a74503c68fee170bb6cf0ea9fc5b53bcd471d459d95ef49878ff4af1b34f56ba9e2116303a6d31c4cf8a1a9fea01eca2aca01216680688b7afa9b6c3d0e4b64dbbee934d1f4775dccc60d27d4476bbff58bdac17dbec48cb3fd973801adfea2d6934ac06cbb7b1bee11cedc386c7443f1a1888977c0291068d0238ef8e468a3ac23dacefb683c818910b7fc27d383f15ea2efaa8556cabc6b06d92e6905833e1c71e83c02a9ad50ba891eb1a924c690d2ced687ae9397b849086f49ab21ba0f6efbba6c3aa15b0d3e0a2736d30e363b8b76687dbd8197d8e433e0ae597eb52dbd627e27f6839384aebd157f50378d7e7a93225a48f1dc62784ceab0dd381265a79660318ad65278c296b2491d5d423cc45309fdc769c5966a4f4bf243d735aa5d70b822259959d2fc691e454b9a877afee60e9cd9cf0e569e74a180897fee81a8cc37a1d0fc899a200121387a4002a6d0a16b4ccee3982aec4ec9870c2e2d5784052a1628861813264010000000000000000000000008caa9f76d0468ffbd1193ff802c2c2a2581ce996b010aac98468a4638a1d9cbf8dac78eb71e7621f794fbf470975ea3b534a9610c13914831364e10868dc56acdfc5dc08083734dfcde57d5a600249555e9e048ba1d04cbc41f3968da7aae1790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040cb6df9cf5ef0c92323ff25d9e89c67f8197021249c156b27258f942f018b18c999373e974fd7a2d47db266ec6b1284154c9904d6aa240e2cc5733deacd49e177b48a01484aa965aeb74d20727aa553f42f993b77b48ec6c6d4a1d93207b6a2de6a16e9bc2aa7af1c8139afc53b91e1b9f22d86645afda9c5e1ced008b5c2420322f88cbabc67872a6c3685b6df801ab2f9896883fc667ae4954e492d731f2e1e0328c442eb23a11493ee5befcf793c510a0a1accd2074ce8e3ecefc8022f3c45090a003695335a3c4a4ce84c458c5cd4a3d58b98ad2febbd2380f080570f0b3113782e27084275fb6c7fd2ae2b3da3eab8ed1d1599fe130808f67714c3e1ffa1b70f03091da76a39aa2356300c1a31af2ebecba83d4140ef3adb254114a0b32651c3ac0212d7b60fcacf37cef5e5f722144592eb1ca83464660ab648cf2c9c920ba70eb0031141318ff949a8b0c9909f1290109a59c29b19c0b6eef7398eeffd8d886612fc030bfb20eae0d652583e094cd54c17b3249ec30dd9a9f7ac36ea4d04b5b0b7b0bf0327ee68f5d1f9051a9fb1502cff907e8cc14d1198ece623189490dc8ae5deafbd91420b4afa93ce75450c7e59bef0026e978276b42ed9e1cd29b635184ccfbaa651c6d011918fa214813178e751dc32b8446a9c83a1b0f9104c929ef14a09bbd2f0278b3832a1aa9f82b5811836c83d8002b9ee10689c20ea2a8e96e7f01124aaa4af3610f4ce3ecce8342f2e1640f14a7fdcc74b0714902891c547987fc7e8045f2a645160f8b85317c6445b132738f34c10fe16719e914b786752be183298965e395c403540f1004a89be3e2cb346aece44bfb4aaee4a1a6d69b56ef9186daf7ddfbec72ffe9ce5ec8e80b9b30759648dedf5df73aaa0c610d42d5cf8d8b5df9552afdf01440a68677ade687a4bd11d2107f88358b98ff4f1e1f311d82ded364064379ddbeed041cd1ae3ef9f53e60ba1c5fd220d61ad16ea35954ba79898d09aa18c3a21d61acdf32cea652bea9575e31145b95bd443715b2810271430a2ee5545813c816026b55ba5c9311b354b7e7b7e5489ef1ea25c55d866a1cf962a6bcdf3831149407f7baa5132b01d51abf4492ff169220a553f2a2c87330b17d835ad18ba07a6a38434d801fd1b0bffd215a5f1849e0026d6106809891daaa6a1dd99187a692badbfdb1cbee80aa4788122c63387576362f4a66e448751c9bda6ad8375fd41de6b88516f4408a7009880cee25ca09c1e735d4bfe91696aaf5d747a77fc4d47b6bd82d6ac6854ec7713cf76f40cb9c17bf12e9cd3f4ceccb1c712dbbab3cb56d4d34227e279aedc7b4a396b03c6605946caf46dd8810005132b3f5a0f04141118619905a1a0478ece5f3a21967654093d90f22a98af45a5c58a94bd47f4fcafdd7f91d20d4a73e5d72686a2dfadd5d6780e797f8a990cd6712acd6e57b0d89c4dd94a810536d192bb1f54baf587de94c84080b63c2297b0c5281f4a0b4d233e62ca00e8b0b1b7bc06e2785ac0c17dde6c9cf3fd7524374350be5fcc8f651e0f9e09e43fb62b5605b597a87da3764aac218d981d998454da870ea02cc7037eeaa657abdb52f682a1fcb21b6a87f54d86d37ee21ec7b1f22f4731f34363e83f779be8ba458bc452b8266443663f47eab329926a8d7a001ffc24f0c9aa78f1b381bc40a170d3e8c43ac110abd4175d086eca4c183248da4489d2848ae1f3e90c789d04772dd535ef8ffb97d8eba9ffb3165fb5bcb51b034dbe7432eab4f72bd02aefdf52fb4740f4deb07b08a223c36b917149990688aaafa212ce3dc84945c9240f65579fa599de42b2523f3fdbab036e35edc544d05ec217f1d7fed966ff4e7647d4ec961b9359acc76661042221b8a5a5a5014002740a7059afb7f884f5015374b95f7ef91b340a29b0c1f8ffbdce32719d9c35cb650d5ce4a49bb9d7feb5ac42bbbb29089d85a1ccb312bf7b79e1566fbdcee9f48c5a8bdf9487dba8041cb35e0eff4683bba440998d096cef9fec906b91014c147f3fb21155a2f0c6c2e201f644552473cb317ae495539abfce95637c362e89f9994502dae4fe4d09e112c7aa7bc2dd40091f27f11eb700c216b56791bc4d36602f35b4c109e23e1f43993f4b8f66dd8c9c26556df9316f3467d502839e05c31dce769c353a426057b7f5a7f77fd2cf4d1dcea6c81ed4a93ee53f9a6f5353b3bbc672d0481fb912ed17e74a1b1cd9fd221661f37e2672d34bdd5721961c76484393ac9fdc6fcac2ce8b70f9167bb4782211a84fd852360551203bff0a9db6151fa1e154cb73ded6c8a89eaccfc26cb7aa9ce29599302f0d34dacd8ffaec8ee90d189d49fa3fa91cfcd22b382889fa2f67b16c7378db24c33ce1b953699b3071f8e4b7b41132978974e355787dadb22059f78b09cd93f2608300", "006a", 0, 24039051, 1537743641, "dfbd378f65b1d3db126d57cd93cf830992c220ec77570a68247f184e7ad89694"], + ["030000807082c4030168e495307f90dcd30c4409458456cb215ef24dae80622685b8a30edf0e12eb9602000000090052515351ac636a522d4101460197d94e030000000001520000000000000000010000000000000000e216e00100000000951739234bb641442194466836cd0cf61502bdea402ea576c97814039c11fc598e38915a459f7315cbb8f7bc2393556f1bbffcb0f462463d777157ecfe4b54b4150fd169ea4665aeb424fd6b2ae0c61312bd955efa171f9e3409b0d1b15b72d300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad7815d28310be564a680bded1bda94be2223c892cc85b69f9d22e82c2b8b048cb992e283b85135d6f9f235a6043dd6ffa05f7d6ec8f466045725c0663cd9dc8868b9fe6197243ca31fdbc665db66ee3691152550b12c3c28941a6180568307a84b1cbaa3d6b0933e6cac1594b7c170f4bd815f46b9cc98f887d6529ba73a98d022fa6aa3cb945340d4642a208f439c31a7d4befe773eac07785577e544a53f11c021cc2a8d39e29889869c32230698d7bb9eaeba7ae2d7e5338760a16159b84196a0b02297d76ce22ad209327b15cecf073bdf81a8c1ab25c6ba29cc1a7a5f951c186a7beea4cb5b53885528b93c51b142b872171a0b73f22295ae34e5039dbff2e2e021feb9914dffdb2657543f53e1e2a011f749c9d682923cd462ddc8d2afe435e600228eac5bea68a8dd3a4493c0e61d0504c08d60d8563e636feb788d1c24db04220032878cf11e89479d8e211df64fccc09ff7fff088515bf622569cc6cd9a4bb3cf90213e1243a2831327bea1a4bc122f244415aa5401d55c3a09fe1a069565a94a787020154778107fe44bf88d963f3329dbca06cd9f2a85e42a964358cf9a1f8095e1a65de964652d4f1df0a4078a524550f3889513d82fd18972ff7740dbac9a02e00e6f887e022961d6a88a2894f3358ff3adc1b2bb8b88da5ebd1f592c9fc78bd46c23ee92dc93245d1cd45931f7adbd7bff63d0f6c4a4ac05d62cf5a1937ad41765db98934db88e4327decaedc32e87324cb36a9a5b811d69fc1cc88a55bd7193303d4b0a05e81a6271f915b8c32df26d609f673fa22048a2a11a2ec03653ffa7fdc1d1f1d727638406df6686f78255a499675be4096b28271346852ad3e6a92318fbd324ec9eeac8d2dcf1b2bcf38d3d4f85ad53755cf527da6d4d64226eeaecc97e5ff092efab0d00852b4211c5f7de8e7b4e5abcbce6f208a5d510c0def68dd038b834f03bf77147f3db0cf5977c5ef181ef8008117dbefcfdbef56059d60a578714573a253b93bf723a9cc0412e56f94d8f6c6f595de1613aae5a495b9d8b75584664b18ee7b35a1e9b1a9727f42818a720712955fd8ba3bd18c546539d6854af7ac05c3b9b3165556e46b9bcebc0fdaabba56eb15bdb49f89f32b5f251afa4b1bc04a461ab925ba07a42c430f262c82452eb4df6efaff623d24c69da22ab44d84ad0769f5216eaf8153138e15a08b515d7804f2cd48f11ab05f335b1fefba4236e08a54fe9c44e31155466589fe1e9f939e276505feef39fced7294eaf4586ba9192769be24b973a9c71f1cc9c8a71a8a9a2ba92ef7bf291039d4e59b5a92bc48375c30e29252fa722511bfa7c1a89ac07913aae09665c5251124eda6b50861a41de213064187f63561bc853380ad40d6111041d905f260cc378abb421ad719154c6074856805b4715d2586a14a6e15b0ca76975d913a14a9055ec6905dbe013abdaf3f39c67f73a3239a5e0062d867f74feaaef91896bc8631d26539ee0b1cdfa61855de6810ed9b42b5330f7bc2d1d7ec5e12c1fa6763b6f5eebfaf47cf3a418a54774cd931f20a92ae92bf9299b166c5c0291774029b03d5bb43a24bcd53a01565d9471800bb8513647162744037a124c8bc3abceae1c4b327c369674783436a53680731e1fa0c792d7c09535f5e57e254ea380fc8bea90368265f2069d233f8e49e5af390eea63d52bd58de49f38a1df81fd52d67fd3d840d3274f0091171616632b88d2e1fca654a54f1bb69fb898425f91cb76b6a51301ce6cac4c60c5e93201d885a6fb99064a10322566b0c95a850fb2a496acb318d10d9b3475d34238225553b99439da3c99b7c4628810dca68292b7538006a9ebb03ecdb90fcf82a974bdb4378d9eea8e844e0ca3f58e2afd010b46f83d4e06ea91b051f3a0aca1672305f414b2d354b9107ebcf4c56656b2717de76448d0757816577789fa0604022d39c095e6703aa92b43ea54c4cbf8cc3b89258b6ed73fb956151cbe16f5286881e03dee4b92fa4eeebbfbbf2a77744795c5628c9b741bdffb2330526eaed91eb3817411c0dc7988204a0f3b2680a95da515bb164fd1e6cdcdcca8c81bdeb971d5e5e423de76bc803fb64426e82600533d09fb8fa34d9866ba2d2b051e80731828fc609b92cadfec3e12fc0e36413031d576c8b8074f10de1ecdb4ee30a9d07bb248e1f21bdf1ec263458a6aaf06f5259542f3e37f729773e5251b792a249b74d178fc3f3eec7488179790b3ee4a0c434c7c25cdfe4b611188465a80cb60a590a95936984c23f648cac128fa76d541b2e03724d60758e7de2e3ec4ac31dbfbb317e8cc607359b8ccd1df55b413965c04024c428ad0005a75132ac9b0d208f22bc37a5380ee9034925a339dd028ab20355dbf726fd69e2ebde773bdf2a98dba732a8473437fea038b65da1fa8b04db0c", "5100ac5200", 0, -382385243, 1537743641, "6f78622c386f920336b64d74c2aca1e5bf208c968a50cba9473d2d176c0ff571"], + ["7afc9c490126885824a337877ac2be4d53f7eeb5cef0d86a749cab7fa2684b9be7848b28c70300000006535365650051ffffffff0124df1304000000000253650000000000", "0051ac", 0, 1082198691, 1537743641, "1acbb63e79f31de178407ad92ae4e8848cf20413ee43f937e4e589d8c30f5ccf"], + ["286cf26703732379d143f5792aeec09dce0e05780dbd4a5ebad11f132b054dd62b9ee6f51e0100000003ac00521842bf3cc1bf3ebc4d698f84f5b3f2be93b7fb0f31aaaab33262172d7c5931d6320e34ca02000000086300516a52005353ffffffff9c38f96bfa2527fcc0e23b1419818679c0bceaf4b734ff7efc802f452b3d3f610300000003510000ffffffff04b06bd00300000000016a16349d0500000000046a52000030ba7302000000000952636a5153636a636508877d000000000002656576e7315b034eb89501000000000000000000000000268955c1189f71fee5d29c813be63c0229ad79d8d806f4a902e5bbdf60239b0831abde403fd42b766d2c85a388e652342b31a0c51c6e642bdb47dcea610859dec1a9b07a1b64a122b5789eda93b9bfc4dfbd07f1cdcfd030ac30d02e5a9731c1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009222882a76081191cec9ceaf4a22cea62e60ae9a975b84122eb97de933ac41365a1a0830a5fcd3ce42dc99ada247a17d1ba06bcd172519765f612bff5134fb0e942eea9ed9285052fa17dfb2ca6558fd20250e1b40573e141b324ae3afbac94bd647141c86e48c79b743d2ed5e6329e15433721754c155920aba3bc3f481791c030d83d6db2b8f60d4a5913def8000ce97ee7b3e0e6415a2470455f81063433122031161ad67e85450851c5efc196511ff6c706c6bfa7b5256e2da4f952ede6e45230b07b0cdbfa745ac3f4875f619037a43866f5ea7449897e57314a3da1d6f5b1c6338e3734ada4b4fb419ef14b514159a9ba8be028fb5040a04710d6a629a66d4fb02088dbfeb0106484e75d8fbf4cfdb3d1d1a0024575480ce1d9cb373c2c5892ed20207310c952c21d78734fc158c90640271199359d2a01a423a109fc4266f33abaa0323ec7b45abe156bb0687b85f3449f35119de9fdd3ede2f0880783b5151c8e03103092256d562c9528a6fbed2412532ab52e4836c32b24783345ce16264014e2d4d030c2ba0bc0f8203f4bfada06b6d9fc5760963d02ba8d9a7af0e3e06b32d218f72a13ac4ec377be8f10bd5cf2c4f37f1a897e05a6f1851e2aa64fc8b6c4957460910473b7dbb7f1852571f91dedadbab52ed5351b0add205c5ee76800c98221afae017126315770e239a30d7968163e81f73007d7191909300d2fc29a9944a0a8ee8170a54de3029420698a51d6a18f3d0342a1dde8d3ef781b3f9e31cd83d01baeb9a8973fb9d20621d7a97f8afc188ff2992ca74024327678ee7a48aa1bea2b718a34557b425cb9334703e6fb1cd71f322b694ec773fe14194eac373e2b567dee6d64c057f2c200f8f21a7b7811607f98c034ca17ea331b1c70f25d15f0cae261b71cf74205e8f543f334e14f686c3a507ae4b47fd9213522189d73e54fc3369d8bac2e01ceae1b963728f6d9fd26ce9c681493ad61ed1642694a26ddc70371a7919953657092c90d105ec62ac0d81e15b498c0aaf890785a88eb6fc347e0ee08cd2d756da38a4c3d873ab69aac4ab01547035b7074e384bdd3fb203609d491b801521ecd3d642251a1a5af0d8c6f3df3ccc94bb667235fc55cf690caf242bfe52ba092bea1416a355441bde093df23081eb80b2fabf4bb9ef1a456f5e91512849402df614d421ef3ea30635bcbb677eb6d1275b1a524fd1c44306b9553bd618e6de361d677ed6872ac5dfe2206e94e1cfe33a8e59073ba3b44a00a35c09468aeaf12e18be3a6734ffbd22907f00b6b0e02b6cdb69b191e4535317074b26a3fdd68bf7ab1b9f4c3405609c6a75c63e41ef41d40c999a461f332ff871ad53bbbcdd3da1bec393b494b408d33b43f60e0668d70f22adfb0cd79882b3f76a3eae0fdf356e6989a10920429a0a565d9a2b145324ab6d59904d32efe7592f90d335d3f26286c359f5f1627e19ac0154eb34865b7fbf7ff45e2adf23aaae215c99b7584f0084d11e1807215755af5bc9d885db10b2c2b5636f73dce622d5c7f758887cac5ba9f0852570a9f1ce38cf38de5687386dd48681c796e7d1ebcdf235cdd3ccf8e96477184181f33773002448ede2ee8918918a82cf089367450abedd3a648cbd28f7b11f6120b5a5a9729ef8180ccc86d80e4d7ff491711846cd80cb3c9fc6873b628fb78b5c00dc1e04c843a5ce65aa80d77908f5ebb405fdcc7b70ccc0722637422ad23c77abb7499e94d4f0bc0c0ffe2db68b39a251922e11e0f086fc93af5f6c20730eb0cc57c8d6b1efd82f97e67dd5a92f11e269c43038405f1c8900cae5cbf54afa9312278309bf18ff28da44ac082d2f8d08806c588e1b04de8ce10d4d1474a5cd638f0d06fbcbdd1cd849b55f28a8ebdf26fd74aef59c95a6c175fe7d41b1a266d8495dbae1667d7dcba5a533f6a6ecf82bf3a6b33d6cedad4484a724a6a33a25a87ccf2685831042a0339962cd4a95bcf1dede26fe2ba4f480634a2da04c380f1c876fdd102f3134bc34909926de96133add934598e702586aba8222a09c87530a9161098bbb9cde054d002facb43bc4205f976d78503f1b0611a57d5e24d04527a8176bba2104fedb04d6b02f392a28c2d8edfe3545939298a902dd31e5af9eafadcaff1e111ebe18514e7ba397b1c889de613dd44ff18225fd7f36e5f7cc0f848b0615c44228230c2969fc20b64b9cd1de001156e4b691836db3cad4f91f0616bceaa9bed6cede5737284635d04f429535677d19c3249083c9ea170afd07d6faa2842fed69abe7c81a89764ba3160300000000000000000000000075e7b84269445a52de6d0fdf59cc28afc0289c4c6a30e05c18e9b288a2bdae70a877d8b842e42e73e9a8881848dbd0cd9a83b7af4344cf547344a2492e846a779569ced4920cf1ae28d3447af7bdf1b5d85208351d62fbf2ab7e36ad7022f317000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003663dc0168b8dab5f2f0987466a4241e6540488f0a8b1858bcbc282d3d2d45b23fa43115ca5fa0400f4b1ba4cda55b509bdb6e06865700ec2d52eecd928cd269444779d4e1d0713a94c285dd66bc3de01825605dd9073998625ffc1407391dd5fd830deb6a8646e49fbdc79fccda172a8fd584e609d850a6323eb7f4ec520b640227e65e990fe61861e9aa08eed05f93e0a78e2350fdc416504d65678158cda81903115c6bf684061be787a4aaf60d3f168c8b33a0df275a3b948a36c68c7509d4290a037f9c1b3deb4b30255f6b4fe05ef83921c1ffaebd833fb62bffe745fee6de9b130b69b8b2aa725f3e5633d4b829d59f686afec88efcf6e7bfd13f3b3eb0b422032c2f94e76391f2b70a3015ff6100ebca0d720fe8be317bdd9be8711b7442df86021cf4535aa2ce2ac3361c9c7c435e10985435de9d7781297bae3e5fbe58a58d30030b81c2f01baaddf99aaa76a7ed09fc9b39794d1ae07a4c090f800a2b5d9e4b410325f1c5b1cfc4ebeb6d80b7c12e5f1c1b27fbcca55987c0591b1bd6cc084fd703021c51dabcbcaa29b2335d93f8f30e71509692eba5b1df83f38964aa4e861f1ff8cb0653ad09ebd5b66a1a4c0b415980fb790398c30d745f9618ef10b084c402d30bb954de81979dfffe8905c0c6e436d71ce93ec886520c1a261bb5ed68e5218be0dbaf2380fdccd621dd8214ee474cb286ba6ffc23ad3d69493d275e08c11105f040fc19e9ce8289ef8605fb433ce9a226495a465f7964f855080ac118d6676371a2bbbb2b4dcbd494d7a20b79d4f1947881ba6d5a11923110aec41a5b6d0709657be207b8bb1c1f28aed1bb894e7f0eea45d308323482f77350d8ed360cb81eca8eae84590c4acfc1213e65ebe6b856069fddaf036ad7b11c17739db89eddeb4530d32f7087a0b9d0b45e03965ddaff325934e4e0fb7e8da3a54ec180698db3cfd3e6d5bf18035927c8bdba08142f285a346949453192f2c329d00de6f5be124b1e51f0aada80931533bb9c23c4944526a2bc56c444039b24ef2231f42e61c5d171ee3009681615ecb47db6173ff38dc7f04b0a8630a50392416753e7613cb86e6e06ecb7807e42324f2c295b12840b8164bcc9e8e3a92d66735096690ec0a1b76239f34c0f25c6f7171386846ca70b16df28f3c6586090de3603ad2101d4c15862428241a34e816716464c3ac7de119b5eef2c39321f5de94366d078113ccac220c8c8d5dfb0fc2fb5d2007469a1ea6b2a1b65aa7fec9115ade7b74372d1f510df6b0967142be8904642bb145c91ce58ba2cbe9fc77549f85596fd479234bf24281dc05e6c749cacb031de158d82420c00db969392f5fa12c0050546466f990c5b6b884e70d6b8637c1e9783871aaaa76cdb11d2c6caec227813a6bf67f6650637279732121c3f347c69c5fcc6338802f6b8dc3dd4e98e98ef4b10cf22e98ff72164dda77593d268885499cd67f404794676089a49dae25c8e52834af40df3f53aa2df8e7da488be717b7439936ac98c40f6d5965243622a90e9d4d3fd80e388d4d1f7d29c774bf2d1eecfaa4d520c01023b74b095d42709d38862caddc482ef0bd15d4219f663acbd9b3c64dbedd02dcae47661b2b3a3bffed510c4aa70b88bb77d4246ab600a20d749c8236ae0f4afb25829e9965d932006bcd3963235ae40c1e52793cc78150a42d6452c42cab4c6cca68614cf07a6deacb8d86153e25d68b12f740b74089f98ffd94eecccca5397d2117570829f4a304ff3c2b905ebf87db30da7f911bcf65a5cd3bc0b4fcfa9bd6f4cf2e6478a1c9fad3b1b36a61f551a520d6686f6659fb58de9c886b603ad6a116df231d5daa481bbf087fed614b530d935382b734ffe8bdeda11b926222f92deaff7f9bab328ed5e290ae9bcc04bc1b10a65981b261a716c4f861f744de8e85696461ba0bd29d01c1c4d97bd30e132e1edb92e1254ebd6e960cd5491d4fa0d6b8dbc1142a512db51826b1f99252d024df7ff0aae4651a913e7945aaf40a1527fc62605a4de2baae5b258786d0894a34daa35161cd158e70f96cde8eebcbb1c4c1b4a433fdb7e307412b42456d3cbbb86ce49c8db99da5aecfc0b1b3643a1e9b75b8b018f6b1beb29d57d7e13abe753c4d733ba2a758d5e1d4aa6466ec4762b04223209dc9b78312a484d4c211c13e0bd7add13a4d4cb44a032d9d27d8a9dec5c8c3172606bfb1333e4966deb31a56b01c3c8c89511ad7bff15de82ba88d6badfcb43ba7f23cf06a9c7e30ed79678df593ab1b1ef8b60a53deed424333123444500000000000000008c6eed03000000006eb8371f2e21ec4ebc600402df9caa89bec36d38417fbbaba344949f96fedb864cd362f408fb5858e32b40ce15a8e4885cc43c96228ef7e2218928e3cfa9cb478a1aa8fa432aaf1892acfe3adc5a11a524f81b58b7606236c5c6fd857bf0209000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eb8712747c712b42dcf70ba558b319f351729fff9cf4c29f5e63347abbf1c37cd80831f9fd93dd65bff6f330a2d2d3b903769b398739f5f59035a1710c8860b328eb5f9ab9ac30e53badbb074202ff1d0411a7eea8fff3b4f2d0b6bfd3dd9c736ee1b3da39f1ade27abc0f8a450b1297daa2867092213ed0d5659a5e8dfcfead0322a93007a79f5eb6555bd74ea2e09954da1c071195e8474d68dc85fc66aba6c0021d338f6bb12f84873b97f839c0851135b2bbf74f57acc2ff9247c63be23204080b0266ccb98e301dd88af5c866721ffd98d40880546678770c5f2672faa14ee85451954f16412a2eebb6f71b70a1fac4a56cb74cfaa43abafcd7988130e54d55250300e3738b9786a3765a41d3846a8ab0aaf6b38610567d3b90e944dad6bd7119340319ccd0965a8b696059646917f06ccbc32f371a1580303fa126fb0384a700ddf7022409c7ed31bd0df634388e2df41778a20397a593ffe45c0e19d779ddf088fa1c02222c7c76c46e9b13c1f05b81a36fd5e9a77601264f99b6bf37b9447e44ecfef002108b6bee19a15bebc322a33ee619966956f10f8905ff48eb27010cd66b3686d6f70b7f4b8baea24b90a2075ddc4548e614af30ebf5d6bb4965bb3934894daf2942134147ced39dc72116910e38d4fdb8ea0922e6156e67ffdd9e65380965fc4e1beebbcaef861bef562ad0a1ad9647fff08ea3c1f9461826c0e6f1f241fed553c3d31026913e594a1a11ed9446470657450abca73cf3eb15cbaf7b64d496c6d2f30e75335318204479044ea555a7654b7e6a04bd8a422a7989620a36745794e73f85ff6256d20d498a1a917d0bca0b43e24cb1356dd6410c840e9cc0cbb5f09cd4d6dc34072d5edf564cc431ffb2f9e9e55484afcd60914c389f25f0ba3f46284f942c4ffe65a3cbb7ebbc5537c76582604ca13409588f9d81e5872a32f668d9d0de4d952f5f2e296394c1dad34ff6ee80cd1947d887a1db8698d08ad3c69b3c6bb0e66297a6e4083f3571a1dfeb40cb1f63871497097e6cc2ed64e986d60940ea7c3e1790f3c203a24144646562a496f5f51d7209d741291b0e14dc8d3c0b2c99a8d24a80d65a01dea4e9ef98c736d6364534670f4f11c659c03438e890e6f1b6b8b46bc1ce6e7d454a4e55c49abff60cf52d8f06bae53f40ccdb1fccf5bf84ec5180a034dbdef59527ddd47bd41d0b1bbc261e98c5fea4b4f03e3b2168f3d3606c7d12f87b7ab468438c64acf08520d63a0cdf29ac3d520cb638a1bbb3cd541b5295d3db419669fe3c7ce1a0676f1a2410388bfb0deba65a3f1caab56107344e3022afb08fc18d5d3e41d8f86b991479bb7af65d6d0f54b09316af120de473fe9a5a5cf862a2cb85a60d93ee0c95d60e60ccac06cb0e1f5f90ace6c308c29b50cef69b2df0007e188d4854d09d35d4e9347ad28445b515411ef280c50a981e2e813703b1b93f211d7c3b999dc2db77e010f4580598aa46525966ac090c80b91cafeb9197f515e4edc59846dee1953b2247f5aab81c27ea6207303cb128ce0b87c422220da48d03b9e8206761dca0f8ab1344a69e554dd2fcf459fa3ca068d69104ba446a3ac12a97dbb0062808d3090233458da254b7ddc254973df5b79a4cccd3049e54c46cd65a9097714c08ed21a3daacd6aadec61d1aa5bb0f333bc8c82f3c155170102735bb9a61f116cf9ca78d6e83c1e12d100fa1a13d3b282d799d2c06724b255875a360b327c3ba187df81378123b6bd9c8d9872ef539ce43c73f6bad4294b9269d9516d2f326e89558b0905eb32f31a8f74da81a669c953ea9058dda538fa1182e6d45474dae5b0675c4dc32de9dc3324347326d86300b85c1630cd7259787f4b6d68b8e8c14a202f03718ab2222a7b643058a0cb2e68f36e81cbe38a28e1b5d29b393d4d847e884c8e420efe58c29ed8554a0353e280f574ca73c178b257e3caa7a15335035faa2eed8baa35a62da4ad13711212528991d36fea0e5de647c0bc8167a0f5dd04f0359bebebc1e870eccc4a8a2245c0024b10e672ba91143c899dd4c5eba8659df479b267dfa11eb28d4c1fcea0d3c726932e8c725e54d7a88f4c73b6ec7f7144ba64fe51bbf25f9a14a9560b174cedec2c5b288ade00d52e89908431449abb44ffa2734b592215fd1f675555fe5be0b286d04d96de3ac6e685a203b21c5c718b0fc5e81d80befeccfad049f52766dde1d5231451414e5ab069b31ff5c88121695c57fca84e0c9d55bbe0d966c3f963d14cdb5d175092d58ad13265f27f1c71c90f88faba85c84dee9bd2539341f7549374e2c493209838b350a2822497387c0ce3445e845489b7a0e00ae410ad21bd7f962554d71226d6706edd0b76160426c1a60a0adc127f8dc565808d6665ed42215cd4a267d2ee05ee88083bc07e4ce951a836afae204", "5152", 0, 2112136949, 1537743641, "eb92ffd5503693134e31a5c6d4f0139efad8cc7798a65f3f8ab3d5acc4a5d5c2"], + ["a380d23303a1263e6c4097a36e4927ce641f94b14c72a0533213c176eb8411bcca6f3eea5a00000000070000ac5263acacffffffff0fc105684c6760ae35c7930e9714838ec9d09879cf05db5e8178e1ef89cdbcd500000000026552ffffffffb665de3fe26c627b49fd90eb2c6e38cfeecc4516353c7c46abaa9c30d8998e610000000001acffffffff02fcae1e04000000000753525151526a6a2f7ce10500000000020052df167fbd03000000000000000015ce3e0500000000499fc721307a576868511138d2d4c599d2887441191b5c8fae8eff3e30acbf13be0c4dee86762c49d52a575240613d7b0fbd340e55b7b83a408ed7454ff4ab2abb2e4b734b7178f8ea9653dd4b5bc0721051e9bc6632681e94398de2e825e660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008007ec8027bbbfae7dba3d330d1febc500f1a591c08e536991cdd041ffc1a9c491bf0443b1712c8f9aa42c36546af1f94460df76805730f890e297a9ed818eeada4926e3f5b73553930134ad6969476d57fa98d80842c522b9a0f75bcc522ec356626dfeb61bdf2fb6a4e8ed7d32d84851d9f05b109411225c144949774589a60206dd79c4a47cc21f945f4240ab9718c034c891b1779253a4325736f743b95ded022f59cfa0a8cda5636bfe9fa8e5a2bb91ef839821a1988e86f93ee66ca40b5cb40a033599d40b3379cf15766d12af4ef382c77a04091affb064a009daf511b80861bdd862fbe73dc083c82f4de3bd6947e458af4fecde1889477edb174f9604ab7f0302e415b54ffe401bbe640e8bc425321a3f1e176454a2d1ce34c25d3d2ed80497032d47eea0d810cdcfe291fe4df885da23051127545b7d83be651f9b68e942605d03196365007e0b287804dcca9118386e7de42b84941e315775a894ee72d8c2deda03270d10ed68f8229a466148c44b79f53e7d81b2de7393363b41aefcd259ef405303078adfcddd66431b19bbbe5d106c544e4d5e1fd29cacad27eab2bbd073f44fd8b2f22a3fc03597e936fff8105421c25eafb72ef2b853ee2cf713447609d2fd46f1116d327aa65881a09a1c4fbbf36472424c4ef7e1fc9d348569ca630fa2baf7b41ff5e684db1ccc0ddc62af2186985f7735900d86b9abe97f24ebb6348ccc663327c4aa303f1eadcccbe6fb30340606d9ac479245b60630b0b96abaee8365ff9fc4c965c7cfb2e273706c776ba7d2099831aa330b17899d11f935e5eead0da3a6308de171b5646ffd35f64a2c60695afc836d6234ba8cff371077d961a050b10b97347c468234e22a8a745c9842a08463b585cd6327d07e01fc99975f24f3d26444139d4e0ca29545364adde265cf75c0d82a83da717775f63a7a4d729ed73615afa5e381252426f0ab9e1176ab1d5df564f97c097e1edf586a2f11725d18e7c94ca1aa9a801a3ee4b5680c7cd1ec8464be8d2ef98590bc557845ca2b071cd61a8493ddfe70d93ea0a2337f6d0cfcd62a3349558af22f8341037f7fc3275e469142e0d47f4777b62c9c989dd99e5db4474bb8a5b66f11c579fdfa0af046600006deac2a3ab0547540acbecac9633a03856310b5901d68e5cde68255f25ed05aaad822f50f995050bff57d081259c52fa5c9596f272f2f181384d341457adc7494e4770c3d936e3a1dc4b6671c0573caf173102beccb37e7619c0ef94868f82cac080fd75bfba635b52e3bbcebb208499ad71d0be252265aece1fa854b74bed89d629ee883b7463ad9e83903694625056669d6944281f24afb8971fc784bbda9fdcd0251059ad50c55aadc68cb35688b13da8a4af6cdd40f11660c520fbcf3e856ec1cf31880377b1ac65a547016d1841a7fa5c4bfe93445a61b6737b606e9c5bb140a72e81a75207387a7deb57c21ad8e5fdc2dbecdb99745495485ca5bc1b00ce093cc3211c14c2bb47b80b51b96f0e66d08e79b7d763665d3eaaa292cdc0e0bb80912b8665a7099359742246446a02d6b2c116d3585d084a2580794843c21313990429dcbc55bdef5feecda61de28c0c04211bf9f3dd92fb1985a38a37fe335080cf302e2e3408308fcdd5bfd2da4f2279155cfe699cd0ae8295559bd23004b071498a85fbe3db0b9ec600736e7f0b2f664ac83cadbe7bece883eb801feefb809e4f8d2958f735752ecb82c1dae13e432d4a45bb1e817008bbd1bc79c72bfed982775f8fc16845275c1a19c140a0b8875963a427439716917af20b38001f6569bb5a63a282b6cc499daea1947ae78a58d7262fcf34e3f216517c5e52f6312f66b78c8bcc7c0c651643105cd18dbaea78c3011229249b4fc32a802073704fe4d4bfa779159cb9d8f6f2f4cace04af508212d4edf5763d88905ca0c234d3193499d9442f7349fbdf1c919dfd9ef84b463d68a1e54dd27387998e809134e2b3b462e172f6af584711e0765572a2a11318505e3a2ff13dc39fc31d23ee05c4a4482dc7bd05610e73265228c3e11ed069b90b5dac09136336ccc1b1fa20829ff765c30c7d61e81776b1efd673ef1a4c858d4ea9fb748216da1ab56a11a01b32e1751067b19ad914ec5cacd47a8ace47d55ed4fea6266ceb1972c34b147ff8b1d35febd359601a073d815614f91d565401ed95bdce6cb7441dc301d0a9d1c45e6571bb08a208aa6f9d301fdf88bc16f1abbabb0853ed6ac64f713f2f1cd89c2f4f8594d6487d1f73c9ab7d14e1b630ca7cf45e6f829d002000000000000000000000000cfa69122ebf3db277efb83027ab3cb1363862099525fdd0edf427b9f32e94492049b8891eaa52ea38d8acd32742a737efb4b1140dcc4936c116b34e3f6a366bbc7738bd363fe63eb4f61ecf1287143dd6c7a476962084131cb0483b88d89c60b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009ff5dcab7431f82d540d89537f0946a34d9b774ec513188976d2cf465134bea047f02b54c6bb8bb8ad2b9d68645255968fc390d3bc72638b00b1d2bf3fcf83112fee3026cb974ca0b0bb112838b58a6bcb256027bfe0c1d3afe9389d09a100590f6932568917207e7bebc843430fe3adf9e5562be0d7e97c3626d3cc7a3041530203e11410eb80d746c2840c08967a31224918e1c0f700ff1cd55541a8e661fc000304246e7218a19331f42b8dcdea2e40ae6e693f988854aa4f5ddccfc1a0dfd4e00a003799b2de57da7035a73fb7c6d6f497fb29ab43d8f14c7e5eb307101d7a5da12d497f162cef439d061d905f38b5a557e482273c738817306c89d4851cf240e2030029007bf15adf2567e38c70ba209bb3f3c61fbf67a199d579a36782d186c1a70313240bf43523436f1dc15c32b70fd2150e605fa490240e654b28092ef66f9ad1021ba767603426934cffa09462732d1764c9f747036c6b9f412bd3b9568b2833fd032d05f200326f304a6ffc5e257b2d509c915e45ef3e6035852cfbbd7530521a8e02185f48de8a4367958822dbc7982964d077e4a035b552e6163303419fbf49f3a55981ff99e0eda771048af4a038bc932c2d0f86bd987517bb9ae94d040a904f38922c51864c81780df1a23441028bd456a9934e9bc895baab4b312b47f356eb0b1d2d42825732d0b8da044c192fa1164725a8411a5a15dd5a9d4db0217f79563aef37d5b8194b2c066935a586bd7ae681d9af3ddd3b59d9b4164a7f43f34be756a4e8811bc1cf4ca0bb56ef29a4911868c260871ddd561718dad995dc5833f0437c61dbb40a805ec19e07e5fdec12aa64b4b0a4e8c8279707ccca2e051fc9ebf8113ca009fd642e4ccd90a5329280c4a8a93765c6be8e8eba5f534747756f7bdda38130857e54c7d4180e6b1dc90a6713d483d0fa77974002e29b1d1ea4149fefed900347a7a9573f4da3b2f943686449d6ae50f8e2f23ea2bd56f0976d1b6394c502e99fc7ae3d0c4f92d0980d46a4e1a9f82defe3e271d3ca1e3d0477e31717b13613adf44a2a7f100f463420ca2c6164d7dd05cedcb710f749a5f76c2e0c6c2bb1b809b15d04eb462d9be53ae87fe1fccc9f9ecff03d3eb69fd2a8d8658c12cea7027be8a86fd84d3c66ad21bcdee665e1bbce94ccd1447f210e5dfad9a8699ebad77779281022ea9b0a60883d30f3ca9d83a4a8b4fd4cc75cb9b8f72bf656cb1edeece8a633b1ee1a75da8e8ffda1aff75c851ce7214a55635e85c8e6e48b49994733e6e47cde8eb579783124f0c3065dc39b11f97e1c844c14a3a763f73d565b4f84fd9fa428df2493bc9a303d937df1de384fee23749f599c32bbe4d5141c449a95a71758c488255a642c585d92dc9d58bbe1f65d3cef54157ea45a00ba978685f476e14445d87a9e68f08f16f8786e03956d9d0800db27a55a780dd4a018eef81e972dbbe47be7138e7d23e29601cef2fa1de11281cc7b4525eb454e8949da1a71032f78200abc414defaa87ae4e36cb125e911bade94973875d0dbe13a6a2da7a00d53ea39dc224bd56d25a0f1e56a81aebfcbb4810a2f50e09471715abfa89097d67655e1fb66cbb74b6b6a4f8c1fea7712c3d4b4bfc51def08749e83b091b76fa35abeeecdbc37c227cd57707ae11df382a55b510cc1b32191d5b3688fd89374248d697e500e539c9b6d84701720e3fe288ecad75885b8e808013ac771203494c02f87e1b65fd83e630c1cb9b06c7201324e9c9815bcf083fcc34e4456dc97df47bf3495bce1c72242f7db2ebe80aae67347b8879ca390a0405d713c9af04b51ed72e1e845ed6e7f90ea817fb69166c72ed677d2a7dd00918e7846624c28177de12b5f8fefbc1695abfd73bcf9fc243909e9bc91302e879d264d7cd30ead1e141c1f9a13d435ef92b29de4188a6dc329b5538f9ec77f27b70fb7bf03e32b8f8bf345cd44fddda75c5f0f4340eeb62528c86cfc23d624a4e8e2fcec174fca403686fcde281a7edf1f073613c278706458e073c9ecc2b5b942d38bfdc7777db1446c3ef9b2ef025458d3e0c4115c956d271f2737b9a343bf55ef0b713f28754b4cfc864a1fb30499f446789e127da0b4e1356f899c5b8e4e5c5e1dec2be00f9852cb8bef471740293203d704fbf54cf22ff2a906f0b582ed1ef5a36d2931cc51f56094da23808b813842f845e0eefb19c9b96d8d92fa9d59d8a610a9f924a2db8c6526017940619c4308612d216520f2c8927ad9eb0e6f6379c4635798bd765b72fdfc060832e63320f158b5b4a8d1da7ec0400000000000000000000000074ecb911ec13ead00d7733fe9cb84f434ec707f75565f6f5655171621469cbc64aa14ae7f2e9c4aae94eb11669993c8e55ed3c58f04207631ee81670c6079a0daf0fb1cd8d2f52d45f8b5abb0aa2c69955e9d54bda6418e1337fea368b698507000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d7ad584ba52de6557e57367ead77a3e3f9703662242b96e91b48bf9c933f9aa0b4293e38750c3bf972357e656abe5fc5b376992021001c273d8d59de06e208ee639b3254169ed821b5e5f976f0da2f0831ede6f8e23621356fd49637ed289299e2bed43f030a69f60314bbdf8f47ca63c218403d2e7ae244f64165c85277e77030e4e8da29a8a33f382979443e3b3698a32e4a4429fe91b334613ae0968fa40eb030fe81660a3811b863290c58dc51513bd8b831b134a60f145b9b230ad306b3ce70b018fb34e64c977dc557f0fa40ffb91f0f16ce7b6251476fd3f15eba192ade14b2f6515c6b93e8673467351d1facd311393e6819fbcd761716bdc0324d42f9a8d031e0db017359204a8198479733d04ec202fa1b3130f50f25d6de7500434de5f2b0219c160367e7b96d751c164108adf05d7af415583c1d697a350fcd70c41058ce60206ab10d405c7e28a52a83c9cc60f695088d6fceeb88d4fbf6d54a9225ce678050201fa8b5764fc4d66ec9441846b64e3e9bb101e2921a91b0d0febb15bfd9c60bf022c7516e39220692fcb12ee43578e318488fe56290ecf885da2b8beef7fc3e3ba93d6aef194b2d61f7c6324760bd4e739f33ca5c0688374ec6adc0e2614d1a39b8a7418e9391d3215d1d9b4514c269b9c46a90e4a2ac994e986c47735183cea3bcb741f418d1330bd805a173e0b8cd64f76530ad43db9f2dadb8a237bc4cc1c257480d9301ace9df44d8e03d657568f993e450c5c76d442ad28f23cb021fc16a93d72e85f1af1da50ee279153b1295130feb66ce9a8afada609e03428dd03a18c44cc4c791b3cec250886ee8aa8929269f6ce1c7d5d9ead1c72946921fcb8dddd0897cb095a032ef0de5ed818ff6cb19149337b5d1def75e9bcd35f225542ecb22fe7417a8e6f9c0f933e91607263c9a99e10efd9013dce5c19398b2faf912a26b620398091ce68f1e8886a5f708f6007474e6911f99173f0984d0358f38515ab8d58d72865e95257281c24e5ce6b898d3e87e1ec883a7a7c25f0636e92647a24eb3cf7ecebf3bf0ec42e793a5e4371a63b19f00dc0def7e2101344060d92b12de7330300aad36708e64ff735a9dee0a66e735dadaadd57822724162856d77c05e354e1f904ca87ec4bccc24ac9bbdad9077ae9fba4fadfe891f3515f67c48c1aee9dd11dd8bbe751c12719c5d32a0cce414e23bd72f3c3cb48d0ccb827c0b872e296550dd9f5861bf6bd70aadf406a967e0e7fbaaf84ada26593dbf62e82a30151f8aeecdfb4d443dfa9d7f196f03c7640b1f617d3a28100889a5ac5b68a303e405201894bba1910cc1e92d119e9033e382e912f3f1fc9ee4ecf8220c19b01ad5c5de5b3444c8ee9ca031891274f3e17dc86b699a8026ebda9698fccb8dd9bfd2a7e4675f0b74ed4f79c6366be4770260856f03aa187fc494c8fae881f8d1f01035645747e560b04ed0452c0bd24decc50bfdfbf64f9b3a874435e899466d83b4fd598c3744cc2ad560ab5f37d008225cc84d6afe4bd1c0993f175e10a1cbe3061e24b815e794e22b8208e036d39b97e60d0dd0d529415037970dc13232708de19c6bb30597d399ce95ad3e4ea94063ca347721b3c64adacb044f116a9a8b99b850481a62a20e65e2a07c2ac580760430a40f005a613469f20a8d37749270f83c8afe29dbeed5420005e0d4f7b12d92533f8ba818c5e9e2e2fe4a91df2112b67e2f159cbe1db49f395b69f8b8f7d33045ef0a96dc364c11cc2919b08cf4f1bce9a494e131a18db962e964321fc7851615d63f4de9c62c7392e781bb970a8fca76eee7f475ce232cc8d10b53adb05fe34d3748e217015f60aa93b638f7b03044efe23499cb727f7e267d93c076477c5072d250ac13cad9312ae988b3c5c5d6ca101c7bb66fc97c3e848b2b964affd09d622d289bdac594e6a0f120e5593047c53c9af63a096fef60da24a9686ff6b3641995c42e827ea3bbc7e5a8cf8d517b7859f6b98c1af0163ce45150c4572c39005ccd6462d2ab73a448874e4be8d283842ce6f015aff10ee2f082c0c4d4bad9a047aee46bf86a5c8d680b3f88bac9d4c91201cd2e18e511b85d7159fa7e36b6bf797d67573260227d75e46f567143761e8f6384712b576ed887115c6a1c9c2233089234c02713624ba6c2b7d88ccc6c872181212ca1979fc853e852424f5cf2e33f7f4fb203bda01d19ddef3ec856860982f8ccc42a594d3a5b3d8974756b36eaa1fde703bebd40ab86d328b8a15d71f7abec7a5477a6b6bb880792968bf7a965b5fddc46239729474e53f36681c9631049cb0a45069ba48c982f8d51a018b58801c6da306a8d04c42ae401835a775f8d34cd1f75a9b70aab34a747c480725bcbd4e7d06c925c829c28ca66113f5c04e593e051749d0573c53bcfddb9d1c14fc057108", "6a635163", 2, -564800263, 0, "86eee12cd8433397671bece77beb312f1002d8576a4451c7de04b9ade1a8b723"], + ["b52c6a2a033d1425b0148dbcb8ae5bb2544a07c3c9d9b0be786469b90f27408d0b17f10a1600000000020063fffffffff0c027f56f4cc7aeb872e4465e8586a978bde3293fcd3b79ee8b73e9a18ee47b0200000004525253630e134e2f8ab98580b5ecce51899c9c1282028ac3e3b0523d4b32298b3790b14bbf18ebe903000000076a53636551005392776a8c04908413050000000005636a63650007c232030000000003ac5153846b1402000000000153d578040200000000075300525352656a0000000002000000000000000018a1f80100000000af769b41d950b8dbc56a2893fa610fd6520df6b734f07a0b607783fb8a1a32ff344eda042f4825ab130f4a2c12bcbc591eecad19bac652b2d6c912aa27727dfae93e7455fa2180bb1c0dd425665414f76cfd4789712e5f6801d17820dbe136170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064ef40898d37aa2b129e9a15f74a788ebccfd23d45fc344a15fd2885669899f93aa87cd967570e0b402febed0455b2f08897a247084825a38cd7570edd7ca4470a6a0b626a56a5e663e1bb05d58b27623965c7f941a31d51f9a6c54fdebc738528b69026068b6adf7f125180d4f4dbaf6c39d131e7dde3b68f4e7ecdef2a167c0305c7ed998e26f0d695d96c2a17c5ac1d32bbb471df64ec1e188b73fa8376cb2403145ea0b54e265ee6621a5d24a5607a875387aa3bc13284788d8ee4dca344faf80a03f2f6ed7492593878412bd853051365b43c18a077ecee10791e6f7abc4043603fa080203efee48f24a81cbf2d35864fbfbf8d3187bf72da81a6d846d522112a032335db8ae513625cb73a4774b5d50445f98f35008c3d3e2fdaf3e4dbea42c6c1022f0656be2c9654991d9ad9e139cbc4eb6f8ddc8c06dece3f01f4210ea924b818030dca5827ba8c55534aff2adf13885487a4f74aa9d49c28ff8638dfd0438751bf0212ea895c19c0c58d0e494eeaaaff64def30bf0ce72a1598111a58e1f2842720c0219ee768e76ba8dc9546e56eb78c89607d9493f9747e7fadd0fe26dbe6f3fe0421bf215c258ecae35d2157b6ecd350e1d88a7fe6b7f409633896bcb140d925af8d290a09a3d1b3d4ae3e60a87c93b8e2a3f8f7e82a491e7823c9cca658dd1b70c128aeb60c5881639a36e0701bce475147f10e85091dff7ba82f572c467c71133cd3713843f446e25dc2a07503c49609b01d24592e1904f61f132664d8cb872b9b78740ad2b6a276a838a8bd439c5c776352bba66a7ca31960657137abaca952effa274b13287ff6a9dfaf6647dc870dd4316694a6ab597dd28d60b7225f2d32b8df664ed2ad55e3d183a0bf96a984441af0e74a7d5568fa67cf25e484d356fa7bef3453705435935b39e4189832e4bb1e28bf286df986be218811313ab69ae5a73ab7092e4453878dbc4f427d98bf80d94d18629335abcd27fda111ab12822ddad5d7a931cc40925660009a65f08764d4457c735dc7524ce1f35255b5c379bd087581759c3630e1849e600b8ecd3e3be6d8d1fb90b38b69c0e2de3699a9f16d963493b22f66476f6875780f7f626b48ea140dbb21020b3de5a1d09d3f042e1be3304619ee9bc62b6970654dbc42cc3eb645db5080268d10acda687b9bc7fe90b2e883f01d2e6146a6ebed79b6a6d57b28c3fe1a5160b746d9ff83cf5305a2a13a8d544f0bf7a84a49eb91d36d1be332e0a8484168ecf5d52272a80f95b98a3364464c7d57a99150b3023d2c22f6778587c79a4b0b5e16b6adfc1b875f27915ed12f66a1e5a0688c82e326542e858bb1adbd75dfc7a6f57a579722b1eb8db7742f083f1843a802f4c59d6981d8e1fa6e22b15bb433ecf32f917e0cd1972da85a6d7c13057df7771b721e47f187b2f6f46b8612b40da87d7d5f53b610bd17862807895fa465456754aff040319f63e01011562c831e76b756b97ae64ed1d8edc1de02c55c35675fad9527f5dcfe5ea4186ebf9611f5241578e6a9dc81221e6ae4b05e76335f11863dd05ee818368cebb0b966c52fed82f3045dd0b2165a03146614e9e65f7dc498e611a027d0023cb3e6d262e5259495b0f08633b6b9b6462be4785e397da802b7570dda76febeb6fc9762082da639b85814f7851cb134d77b7d203bfd0ed80edd292ac0be1d1b7453508fbe1e0a1471f5b8c0fda618a610862f45782e7d77778743c66845486f443622293feea20a6e9fe0415d3fa8782b695dfc52568352f0d15c833c2b72e88abfdf38f948c5a8846a61fcf17d06bf472929c41565de3668ae1dd978ad54269064c5ab715dd19507e4fbc91e4f0f5d5b71e031799755154c20d16c83e64f128dcee594f49da6db6fca769bae69c91719791d02cad0e7db09680b2fe10c14b21d2412cc95ba7294bfdd82b64b37f8925e52cc36d72cc514e4b0df9a36b8086baf355c18b0f8b2b121e2c141d11562ba351430000123dcc8c8375051427de9afd64b9db38c19b05ce3efdc74719f9aa013d252aca221c67b09caa782beba14cb82f8e85585949f53240c6320c6cd1ab997ac06c1e83fd26fc70f4c3f902b4d9db912d34a3681e5484076ee543926f0cb3b3a4db80387a457b72659c33c6a3d79f90ad5fc619c5c50a062dfb77f19eb2a5e9398ecf7eff033ce5ea2c5bf55e48ab10a32e0ec590ecc56a3f1f1ea83f71afd2f383f25a2d1d8904d5fb180c36ca1987e01de38f3acde5d607aed7552eae0a596c75524328c63d602026a082f4f82372bb3946f0000000000000000025c30c0500000000bdfc3b8e7905a70a6fe7a79c6858a624c04ab7d3435178fe6b38f83b1e3af8bfbc1275a3fc748f62ec38c371239f2bb2dd590a780d4ca3036b80b39c88115a213f9c8eb3a54708608dd102bce8774076a32e66e4488995c45f4753d057605e9a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000067b578f184ea433fc5c7124952a34b0f14ddc4c42bc3e74c4fc7c0e6a4c72a13ed0d6a1f928edaacd8e158d6cc6bd8d4230266d79ccbaffa14bf98a559d9551e461170e536712a0c8e23325decd439e0dc2cc514ba71713b50c9b7b67109921660c0cae0b7732ced3b8e114ea60ee953f0dee26c3bb8385ffb02821ed70d520e031c6790edc826660917d07113430ed86e5a7ae820e8fd7bfe379b57634960b1a4020d1b7f43ece669f32a96da265bb8505ef93dc8ded0b15ceaa33133c1d1c198b60a081daf709af4d4bcb1987ccaaf0170284d3901d1efd060d7922e747391379e121c2295a3dc86742355996d97c07c3768d2d35a80e602dd6607293204bec4a8b003021dc0f356f1bb5f3bf4c5595613151dc05d8e775c739b5a9750b1529465108e0302e4eed6ecc36f508b9d258bbb5ce8c93763ff120dbc50922d5fe07b6e75a711020a41ace7e881a149b0b831bfd7ee6ec6b3148e2a698d966dc8e96dedaefdbaa3022d53f2c33e2bd288f54be36f1ff444522f92776961c4cf84b993aa9128cbbf89020651e8d9df510a6329db607837d9df090ed9248d2c22f4622546de186314ce9edb721a2514bc34117b0fad90a18857a73f8cc851acda2e4f5db46cda092ecb7852a5aaa921c8acc6ce6c942a2c391101329986b28ad179060ca5db75c04f3b81f4876e51124659d4b2b2992ea276eb80e5a22c41bf87d9bc35be8cb1288a9fc9a5ce85c2cc92d1acb1eeded4e94c24365560c36a8b3d77257c4ff94ad3781d8bc93771f881daa2419b12c3d19f0e0b96bc79e015463ba5a4869a7cd5285551bdc93a8e70baef03c9ab1763408c25c309c64f7c529747b5247db62c94a7b34ccbbb34ebe932cb3a20966f0889440aed8179d6c5613bc6d5cfd18401d11f1edc0d69421b4b9b70439b0ccefd855324c17d293577c5e83a503237e75a0eb9ae2238b2e4bc88e7de3bd8a51de56811659d78d81d44638f4a75b7bc1e9e883d123c9bfe56f18f1b153584c563dfcda647b3c0110e21980cbe15a171b68bcb1c73c9252fa5059a9ee743ea4af5ac5b8457d7f741e28500cf590a9f102a6d500b4b6c8a991a246c5844060703557a87872beefe280cbc6b5f134ab91b4e5a241507a8a111e4d39d0a44b38089584aa7b3b9f6af42c1411f439777688b8ac67a15b446ad834199c0d6f5a83f48117e295fa290c8e4ac0bd59a27959faa5054c4959e58b430e7a701c09af0436803680b081b4b2268bf7c3b2c0c876a9f58b068656b0ed084b92899cdae5e46efaa6a06d8e3d194ca06c0d88ccfd78d9abde92b33bbe87aad023a5df78cd115666db0f6256aa886f3e7e35ba16bbf6ffdb149090a6c5d422b2fb51a4791700545e7cf32e8031d5b1b1b3a18b5ba60dab6d11bc4c24b2c0da28a469bd8ea9b36ff47b48471d70aaa8630b8e5022a2335da27fcab2e3cfefb47f80e970c6a6fa39006ff7c85506061facdb4f3b99284c3458afe6413f8a75056b0eb3b6b3defa54a496ac65ce8bb0201d2760adfa5f138bff074977aefd6e0722314bf629286bcdb1a677fd2dd2ff50e722e4dfc340a069b3fbf03f7f34feb80327af69c19f82fe33efc04e5d2d8f0207729d60df007ca784b64194ed2123a916ebf2a7df2af0a6f7475a4dc3e8c9328f2efc82bbfce2e320654138a8ccf3528806ba364a861f478c86d1fba4f358013bb836e68831a5d7138f4ffffcd17e90a3782af445f0d08ed99d1f5b527642f34dffa02c5c78b5af4628ab37974eb0039923219816c097bd3ac5c84b28ac0689763c942492f23041422eb20bfa474d9129fd62f08d1ee3581d0c157de89f2e00dbe869e9c9c8ccaf84e0380d061b3ef15bdbbd17f84226038bcd55daa8706727ee328c2398e1a60aecc6564b83da82b9e0092877dc077494cd0787745001e0cb6bcf3d9f1490b937838626220b74b14e6cc1f1582f621a23e686840f1fae0c1f9d5f57d8b3d46d1e93a4997381aaa91621199ab0d73e21041ae3556ca51f3324939be069935642b25f944398cc52894e5ba489a4994dee696c247741aa0372467dc5f034c72fe4fa0f40d07ffede8fdf00df1d46d8821a6a285bee97b1f0d93280ce77b60217cccd261ef0a52ee12ca174a189404ec66a1dab9781b00e1232bd8622056175f13092e1882ada4fc1974f2ed597ec7f22efd8e9b2a4f98e16f87ea87fd138d29dd8750ce8faaaf4d390e1914c53686e83192198e8c3299754df0ba396d6213820c6291c28ac1ce9a54c0018778ca40f22c1406c03a016fd930643434a98bdac2376475f8291594e40e013c1d5364254eaff8935521a3fa72afdd5a358dc602ccc48b49accc3320e64fc5757e94f393746ca402eacc4197150305d70877365399b1e7e93c663602684aa4a0dd77e73b54507bd956bb5aab5a54e1b009", "006353536a0063", 2, -852992176, 1537743641, "2e3c42985e6de31106d186818d8f652b4db1d42a224fc1aad1ba4c7b5c631b9b"], + ["030000807082c40301e4ae05eea4afe4e78cdbd6f0caca5709ef73b061a9782eb64333a4d26a55c5880100000000db4130e80158b5100200000000045253ac65aa5905a00000000000", "65636565", 0, 1270046897, 1537743641, "5560992104bac14912996a4a692dfb9bf168583819454407e865232d0ed6539b"], + ["50c23e52011b9ff0034b3550d0ad468c37ea249ba07ff0eaef88000292b74f9b4ce89f950e02000000066a0065006352b68de66801b9025b0200000000016ab93a9139020000000000000000b461e90300000000eefc8b1031a83133fc6f8a9341a0d0df1c30799e02f9050cac71dde7d6161c0e89212db12205912cf8ee52c4ac5871c391b7997f7c9186b6e4a00a10893eabd26a05dd3d297a22dc2c1446633f66fa9a6c67c646c23249e4abe50adb922d30de00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c1a651aae9ebd8e1bc9b0f220bae5cbea35744ae70181484504554570362116e8d7b3abac066b7143f8105887702adeb1e36f40592a03e0e4654822903136b1d70bcc46cd452ff6b2240fbc9fa4301167f0e829877ead5257a1d2d589297a557451760f75fc3bb810c8c5f3b85dada254b113128d38565d11bdadaff8a6755d80314f5a21bc85921302468182ef499415b313813e1267966e9d24a2a5e4a884c0303181098a0edef6c70a7d0f8c7b0c3fba702776b9742e5f1158aa65fd2bb66bb4d0b02c9474f8a70672802976c700b2e20a36033dfea6bd1b217283a03d235012cabc1e4c149e21f486d72d39c9d4fa07cee11f512c85d5b0a23987e64bccf825418030dd61b6c619132cc14cb907184d0cd921d049c466b2254ea08b2e3d5c869e1680309046b70f2afd616c9eb2871edbedbc0cf631054d4f938bd7944f4b27c32f455031ca5908a67dcf61ef50fa36a5fdb40ec1741a6926bde6abab203ebad605cb66a02028d68ed8a3f52443d7280342be9d3a5af2fe28cdf4138cfe055125f2955a2f20317169557228f7e0aa2cf70288ad09eedb51f9f6477a1da9a1c83137c429cdddba9d87c0be63e0a329f20118e36250ce0088ac5f60228a12644fecbe8e92dcd47eaadc68b029241ec86e405bd1c4bab467e916445d6fe8cdba274073e2c60eb94d0d408366ced6d78af9a43582804c58039329bf1f99d74e13f1e760600c22156edf32d338b43c9fd9c644e709ee45a1ae33e279af4f8b14f0a9ac2c0d39190cea7448791ba4fbc86056470c36236161a3a7665c4ea75f654cd648a6f213ddc8a48381eab05d8b912cb8238e50b9b29b9622548db0dc24dc9718a2fcce20f16cd01315434e7a61fdaf595c29e63c8a7cee0aaa8a18a4a3c55d89627fbe54d041ff6593dab13771954b681c080c4117124d773a3d1f21d498c3c62fae29b1632cb4e924c9ae9bd8a516419cbe49e0685eda603b879cdb87748a5971155ec348b87f1f736a793a5f9377d4bf2b8f14211d9cfff478611b54af6dc206d80656b6ab10afb0bbc66d2ff9eefbee64db109bf3cc39511f27885678caaad6c2df808f142b59f9dac5ecabf36eb92869beeeb63aa50d1c3dbf847cdaec7ab98e14b3fa2f4ba5eb2e7840e30cee5591ba57b4ab163daab661cc72d3bfaa0b0fb826cfb485384b1f8f99cdc5c3b160eba1989ea024507ccf7773ffd7c58f4215b3c7be6eb6366138570183122a5e99c2c01203758ed6d39ed883fe313a455fdfdb2cce709649af0984c387c365d7d01e6afdf2596006790d3d4207241b7a7c15ca3b2e739144025d3514a5c98e7349ec3f478f2915f2d27ff2bd629085eb159d867557f941bce213fd5dece052239ca9d82c324707c42d711dbb3ccf4fd17ec43d24102330676e3e4d150de1f9a4607e521afe27ff3e334da6e91477c8a0d1e06c80d0ef1f083040c98cc65484a4bced464e1239ef2902e7c225ab9d9d04e024a25c23c6419973183b932c78223e2c7586598830717ab1b15ad6d5c434a5b89dcae0400375ab1f10d70f28284053786871133b147e5e70d86a662e1c16cbaaf1fb350ad214e593d20993c32eb80053ae3fa41a0c1c1fa7f818b6746eed6f499a421b00b90e689f81777ebf4ecdf9c5bb9343f2655c424894c9404f7cec6e11b1e7a55527396542d0629bacdb2dc45b2ad9d292b2051962522a0a8e923a99a8560edaecbb7fa6c34adb6bd32c1555d7528a7f6f8d37bbba363283d8f2321063052084ba06b221e32b06fbe3bc15984c50cced35bec0c4110997d7b0d08ddb7e8bee7f92f51364f685d725b8d7d8ce6f61f20c9aed0b452494e73cbd91fd1296960c5d5fe53bb669faff383eb25318abae418cf2c3cd16f252869234ed87d671cfbd460ea591019cae6acccc889d1289ed470d48b6c9921ff386ed700021b2c83acf6fc7e4ea3e23a8401643a098745be44f74f9c1552a68734fc1aa75a0cdc906d7edd0bdb19d80b8f856971c305c648e10e3f7d85fcb9ecb615ede35b2b8bd77b3302d6856a81986b041fc7fcae989276a6d822077068e23167a650b3719cdd379f0870fb05699db510a57305f4523234eb90c3691de4753a1d134c18e381d5ad017f9269986aac110060a296e134db54ba4639886cafee0ac52257443ff408812941fc00026ab5f43883722e3039d65b0c453db952be63701dfa2dd65bfe36f49e5d41fba86594bdda0cd54ce0f704a0262f012786af4dcfab652105d6b6464334b1f9a4abb908c8a8d128b249d43a6275c4b4b05458470000000000000000ca2c9004000000006cfff26e195b31befb46eb15322681de09415622c8db79a7b73f9914b3eee89530637a4352d81cf31709e3cb203fb8ed53eebc6fd72e77c71d44e2b39f046d85bbb166846d9c861c9e8229e6fec9b7b1ee4cdcaa79ae80cd16a3e9a30d11f01f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003caffb3e1e472f3affe39ace681d4a6d5f953ace2d145950b35aab5f1e201a83687425122969f0491d046523e5b06b7524cf67a93b99e3712637d267cfd1b63b51328062d392ebfbdee27dd306c96375d018fce26ee827a1699f128ec18bdc699703091078840d0b2cd51db5ab417d7373bba1f89e849ac81fd0ee79d902c35c02291dd5331e834fd4e17e0a666615d3571a1e72ec2701487a93186d86eba91fee0224a1503b82c4b60aed09ee427e4ed25a52ded8c6f1dd18bfaf86d03a930963200b0815eccc56da4129c38dcd3d33944cedeafba60d2f9340cba0326ab17cccf5704c9c542deb0b011bfea08bb5581b47e9eaafcaa4d7d486553877eef016b0920d0211e61fb46d23ba651787d2d38a5dafdeb548b20dcc7d3e0b6e909cb2d60d8a40021e3eaffc596db45177e80a26cf4670ed5204e67912d896895bc55dff5120e0cf0303be003311b0955164fde0ff52efddfd4170784aecd36c399211feab6bb0f94d030ad54a893e76d2ca5f35e00ff7437905f8b0a2029603f7cbdb545ecde5af7e87020fed1271ab7792a936b1280c0b2845d2b0a396c5de57b6c89adaa23c152a6c0eb4fa60679a45b2f01d945bbb99e68c4c0963652f9318737c69dccb8e1e4fc3e5709579a8f4c701c8c1f3cb689a265d0667773553c8641ed9fb916c427cf978f5b8bed22684ede79185ad9bc82137a12bbe6cf103824455db98f30ae554ae006f379de76abbd725facdc69fd28e5f094dfd9a4234706de72ec2d352f8462f4863459989f592ab1c4a074d65ac63e5e5d9b206478f90bb8a61febc87712ededb90f213935fa5cdec7e082d0165672892d9b334c59e4cce38efe12b85d7d6b37da0a66e6bd97b66a90a66dafcc6852b183456ff06779eb83dd10c65170b19afe4c300385b826367c540d0e5c6ddb722cd06b6fbe9e42419112d695eb89ad79161ecaef20e0f26e775ad1241c7d1387a36d9f475327cb616693b4156ca08e2834e538b373320aa8d12b318278ffffbbb9e956a1987782ad8837f6f7b77af1cd6b41678698dd81063aaa99fca16cc275c5e1986b936853e851378fda4e5c74bd17c93b272e0fdcaae667dc0efc323292aba1c95b98173f203bdd61217341d1b9bc726480d9e98e4b98aede63c163869438ec0523ae0dbc094bb141075aa3e9c8ec10345eae2d25ab0ca6831b3b303494ddabfe80df140c64673ef4e92e83804696c078e8634f07197ee4c28f3f18e6badfb1c89b95ce0a5667e53ed59e7186dae95ec57d0c0e323db2573b6be93a679f805c6fbd2c873ffd490b385da9e6613abd4b295028b65d30a9a9311646255d28cea091c4ce9eb7b2b2bd6a1cf4060c8220a8dd9eb4ba6bca3d3af38c811bc0ae84b399f0188ea200017e4243041e29f92858d8af6df71a7353a5759883370679dbb3e8136d82419584f80ebc9c999f5da64c8bbe3edb2ae6a55c63b290137b45295c6df015755d13c24be418cb8684c075a55a63382770aa3187042a7c94ca7b9b235cecf1adea37196323622e9144f362bdef473689a286cdfcf2095f4dcb9c2c2615f341cee30e75082407927a702d6f951994523c6665e054bfd978f2ff63af226531e744305860e7120c9a4f809f8de440e632f8ed06993b01540565004dc4ac953b5acf5bccfc2da8fadc01ec66fcdde5445757ddb8120ba567dc5de8241c6a9dfc13e88a9bc0a15c070e487ffa688e441f2a3c1a09c8c5a0dcb8dd070a4a4a5948a97853c9ba26d65bb98ef58e03792e04695f2d21c12c78bbae55f507909ed5d491bafa5a0d8942d51eda08dc433ed0d2f0e59217155d4a1bc6bbc80ba40ba9524a5a764d6bf0668fd1e371f1220011f096f58f90780d4597280e255d1ec8aae142637488d5e7d98c5fc60c7836f0663d6a41cd8c58e5ec5876cdc52f2d3f239d1bcfcc3952305317d82444a22dfee1e5057aeee5e44f825c2933946e33913a0d8b002765beeca34cbd1d1daa210a7cc14903fcfe51ff77f5cd96b1f9956c84469119d738aa1c99cf6e29ffe2b54ac785fec676743e46581450b87d65cf306a79391be93566a0d623694369d7945ce37ce0bb59584dfac838ee478b06d03cac454ff641526a5e31cf8f96ba6f1421f9e1d0a12002cafc84cc3b470d1f943b82447ef2cb840fc8bcf5fc5e1da982cd16e159ff7481fd6e4fad68868bd016d3691a814620fa1e2ccd7bc60f973c2e671a380359f0f6862c190c968ce69217401f6b2e6bc4b96ea199ea618266af3acc9f1ca1c3923720b4764126253622d66b1410fdb00ed7927b20f42e440d2479d49ab076403000cedb34c251c68e97431e990d922002c7ceab330e6674e08d4ca275337d679af62db9b3cabaf4947bbe21669f8f97dda982d6d8340569d6fe62691dfab6f51a4f7b616d08359eb1d6aa5256f04", "630063516a6a65", 0, 1570969214, 1537743641, "65b7113864d3245ca36cc637155c114c820b0bfe01ca4272f28f4db058582644"], + ["030000807082c40301c04861e316c8351ab1ae7a8e737f1718cb33d4a2ec0a5a1dd0cb6d786839a21f03000000026551568a12ae040b10ac040000000004516565525c06f90200000000055252655163002c5b0200000000036a5352ef080601000000000665ac516aac65000000001172e3e001f6c88b0500000000000000000000000046de8444a31bfca39659b06d44538dc99844710f7a8ee3b32287f1f24e658eec1c0443b6df34ce9bfb5195a82008b320482a26a642b9725a670ba3f47ce7256a380f523cf6fcab20a760ae24efcfa84493143f7dc37a4b4644bdf8b85988ea3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a54660e3184d52bcf3d0479de9e5c8b933ede89f2978e28b81e9cf08d24c9e4597a463f0125df82f78227fea09528b7cb1df544ec3a50e3cb9ef44ad3fc652118f5d3ebd67642f71fa38d5e3fda400425cb5dd3a5dcfc8b199b872187ae03a3bf0384238e35dea7a4295e6501e693026ea659c3cdfd3c490eae53499f4c3290803038fed4aa4b12c29bf540389480c6f465e473647c241baa7cd6985810f31d2cb032672561b3958754e55729dc422e547062c83a9e8b258634c861a06b6438c927c0a07967c0db4ad0bbb25c0d043c269bccb6d2ec0ff9769fd6017a868b391304e4d484b1b6b9009d53274b8834fb915aee3100918393470ba0eb90dbb15232157ce032ec57e8132f2d474903a19d4351c83a32c43a992cbeddf64748759f62dd4cd430321debf5e09975b99cc4a52a8fb7802451ad46bcd32c0b8a6820408e89e5f73f902294d72dd73e4c146d5030f6ca3d1cc7d253a1258fff67baa60bfb2dafe90fde00216e421a76d62b72a31863a2f009047431567bbf31eee777546de0d3e0ccdabe9030554e3756dd493d2687f6573bbaebb391dc31861bc680d28dfef982f32331063ab0690e132edc74bc21ce62f6f59cbd0b256faf173157d67f680b828b3c663250a26b0c89de7306b7c627cd4b50073d1f0d8b014fe7bfa64dc2fbab395a9194a8f2f83dc8b0a1dd599ba62fddb0f1dc78f6b8bed4f22b2dfdba42bb2943ff75294b3b243c31dbc4c02e6783986a303dcad72279ba68e2fcecc0aafcb4f8e7e8ee5e394b1c29a0868b206b80c2c2ecd5f91a0c4685e738be67ec555a20f3ee68031675ea2b2fab753924ebd2f7826e27c9760e0beb34d5e45b000ec142ad029381af1c51392252423c90126b228a1769417ff4ed9c4c8235c332ef3ae95b3d1f6358fcff0dd1c535864378b6f9abc3f1b0cf038f3a6ddaf4d08f3f650a46b00c05b9699c590fa4fc5833d6632fc6c526a3092218021720fc84cee22b65ab50a52c8ff3497ead910884deb72c6d355a48a788c37a1f9c761113aad75863a879bdc891d954ff0649894ddb3c2461a440a8429e0b7e604313bb6da4a40575e6dad70693bbc125bf0dd8ccbb02b2f095077774a38c8d769484f5364077f8b96a07a30b2fd4cda1273972b43dd1491af9e0b9e0003e063c2febc8505884fc24fd8e849c922cfc521c936a3506d2ea797604ec146f0d46a2060abac0ce220ae181c4a2693e9cef8885601b11c0a3be62b3ee7e5984e4e5b281643ac2524913e3d93b05deefdc91c1a1aeeb78de898178d95270b20c44ec9f3d650ac879988d5d0e391cc767fe102c1d6f881c16881df011690bfc2f209b44fd18bfc63e97ae7ec2b82b333fd44a3e0b377a78ec4a3ddf5cd74ea7c2ad73b8f2226b3e021aad3712c7caf2ebbd79fa3111c142909e4fc1f25f020632aaca06c289b6ee2eca5f9059d6712fff5a38c72329605bd66a44417db3b51c5822d1c04851c5f489489ddb4cd27a5bc3e19b1e6edb42da0eb48f7d33f9eedbedf12ab853628d2c69b8326bbef81d7b48f158a11754e7da88e7ae0baa240441deed87970aeaa4baaa977ef9e72d641c1bb97a83ab6c6a836d105a61918a65fe08496031891a3b3d86b7ea4885833b0c107a863dea5d556a782a49972b600dc647d17e1a25757ea4b179f04229a29b94a699428a0b8190f22c9df3fec6f029a1c7cf78372a2c75e328153d3d6cbac826fa132773a4d06b2946e052d11c41d9bbf68617f0d6273918307dd35599d1f6dda0414b6c430118685bd979b7d85eb236a91efd0aaa6ebbb65ef34a253a5e863176a427ad36d7feae1cb9779f5b773949fa3c94b7762e962fabed4674475a90060118c1fae6ebef5b486c1629f0c77a72bd75fc604797005d24ce13183b94691ba1d725b70260451cac373a39335e9c1e29ff9862892f54e2e0ce81c8632f04d9ad4d8389805293c20e7e6dd4ebd0421bae045e58853e2d767496012bef3e073a3fdec0d7ed9dd85a531fef7f3afe96baa4154c992a0c6c6ed601a5f89e3e2ad60a99fb9f000ec1e755e564592fa62846ed6cdac24664ab2e9a3203b31cc166169cde5aa75a3778b8b809f1abf32d0e08ab4c3ad1c4d10c0edb6b860947ed88faa705ca9ae0b5444eb62928781652ffdcefc55af69987a0b23ac9182fc2edcaf2c08b0e60ace0d2b5547ab0aca1c58bdfc781b7bb0733651ac1b776875e32b0247e47fba190a7b61d36533443ea55b0beb2d96dc58ce62dbd2df5d20cc3e1fed902df099753d049e0af93f562a3199f4b727b059b5bf26eb876289a1aee96c34269a9a7fb97e3a5c47980dad10704b21ebfb4f5d9b330daa97d5af29324d8133d4222ee9f3790268acc8f68f48347823c7c748bc9c009d7e033ea1647f8dff707e5a91cf43795bbcad0aeb304de237390604", "5153535365006aac", 0, -150717590, 0, "5b5ef5d9939abfad9ea5218b6d831360f80616cc21f9c42f3c6de12bfeffade3"], + ["030000807082c403030245f922ac454436f685f11926918c0ebea801cff31ede78086e85871d4929e200000000085163535263650000ffffffff3d6ef9d379087b58d527ad689ff966f930ba4a4696d6e379b84e07f2758315810000000007636a5100656563ffffffff9486974044b51945e41ff35ec62f7a3f8c88d3fc77006961c978c3e599de4bd602000000086300525253000065ffffffff0311d60c00000000000900ac00636aac6352651aab7601000000000453656a0030679b020000000003acac00000000000000000003eb070a010000000000000000000000009ae00aaf4c839ee8215f273f685ae732c5ac09c963fbccd743ceabd3edee769b937cd802e0f6fe85a9e52b40ed91baf13338605e9591778e4c410369a0c51afdf226591e0dc8ff410ee9747773d767236468a3bb71b92aa4fa8bc99d3b3ba00b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a6b26e3077af40190458f21dc0e18f3356c4157429d67b9cb62c31c9d6aa5ada1e462f440c491ca40a402581fe1909bee37a16123e2d716ab9dd81bd615adb7418bc90b32637b9ed56654fda86630bb415fb5cea11dce6d1f74b233be78029bdfbd24d258e050479bf9745b9e0e83086ee5cfa5e43f3beb52c1e8fb9e68c11f020151bfa7518952c7e599d5679cb92304f37dd1d6224e9a4cda2bd8b5c42bb0c00225a9fe453adc7c7d056c6fd413540fc74c9a074ac827330f9f197c17a82691820a013890254aebc364bfd0b40825b7b7d9de8477524afc88bfc8ed7718e152e0ee166b75b8265e7fc152243cccab8bcacfc09cc653caa4c07d690c53b053c5374f032d9188d881cb9a27a7ac191b44815222a9c338db695d04732a424e2878cfa6240312850a311191741b2ca13b767c9693692e3e8541062d3a7d170051eddcc42b8b02159578cfc62fdf4dafd968f3cce9769aa9d47efda889dbe00ea6a1d294abb6d403237dbad5b726c10f89bd80a9c8e99e3a3bd6ace37ecc2d81f8d77a6b2222d6740311ddd5442df1b97f5552547ed4e7b0fd59eac0dff542913925ede151bf96d39a28b6f49a19f361a4474de669cb5cd11a8f77a16431207aae37c49a05114a272a6334ff70e14e9f56099b07c1a1b70557079311637b85461a77f26c8a7181bc5c9876a029d9041e382066fb6cb9e8a4ba5b3aff6a7e350def760c7677de170388f5c0799b87496efcc26151353366984fd5c236c9578c20f38591219680fb43a74aa285e95c3033eeb0391a5f023550ffb907515306750a8c1c9d054c7cb061edacb204dce8bb60e8335790e02aaee62c95bf3ee1e8740fb75c021d968ae0c3cd6a8862934534380cf733b26ef698076f4fb0639328fbe977545a61c8c0dd4fa63fe8ac0aa47a2044f24ffdb057ccff5e4133c5ced9e2285e326f7928f7060138c0038bc61085d45e4b5f3b7fa5ee8ec9160d90822f9cdad524020c40fd54ef9a78a8d0088cfdb584fcb483ee022bfa37829db09856a3954574be7ff9f98c69cfa889bf60efe2bbb94de46ed7f61bf39488d3bff46ccd83fb3be6c85f0b50b3ddcb179b4071c04cf609c2b3378242935d6ec4df82986341322d3d5acd04e0ed26b1e5073d6d73dd45e001eab2c831e678d2da7feb75547f037287d70881129fa9ad5c843e490b85fd79ffeb86ecc089028b594b94392b77c8d7a85211b50052132e391646b07b5e94247923f7b3a398fdd9814c7589446da91b4ba3ac0f8c1b79f3b01ce47507e463141779bdb11fc51f3fa2c7b762f1e4286ccc855494ee10670417336a749a128b11770e51193b0f4bd68eb8f2ef69028cd1a87914bf7588c84c832dfc1675e815b30e102e09694d45d128ab6a01196b97c0dee6e6a20b75b487ad1882cae0c457dcbed0e7ae45f57958da044ce2aa255fa91e2dc55eb9728da36f4ff812b4b2ebb932467022a5ee89adf987fb7adac1c7e018faed12a9b893332fa946bc48f5d4c20a1c93b7565b4c0878ffa5cb8a4c82f2bd83de4954a4d652053089087a646aa1406f9c79676ccab63e318a956b98553ec22d01a897f53199b84ee371df86f1a33a90a295351c6f7110811de3f898f0ad7c958e8b325aa7676be5acaad72de10df94becdc6151e0b47d168bef2e1676130dbb14a52573dae2f87a082b2975f8bad7c339fc63fcad3f616caeaf4a6294957b6810a22b4e451a9f26ecc556a5529acce79c59b69846ea175e3e4139d46f6b110735bb6dbaa7ea32a6fadd48742343328debb8d8894097d37bb895bd2b9f248d95a9d08b539174343a88e2192ea07b03336fbd1d168980f191834233ee11494ef96991ddd159adade1e033614917f053f43b34f67e53756eb6d361beb682fe697ec3dfb335e22334f94b9f82c97474cbb81f5515d88a1691a6d8e77d2ae4ec506703be5e899d7739ec15d4d873c3b4b50bf418cad993b1d1a2cb6112efce9ca70aba70932f6970949c7654819e1ca60f2b657932fc03b5b02ffd381db2bb508abacec759359547697cc82faae7aa05b90c8b5ef4eefa7f0bef90fc912683b6331497b33bafdbdf01fc78076a5d57f66f53650df6a9d9aafc8c42a7f1aa183b17946e1af9390e1f44f5a1a8077bea1998a29453fb5a98190871d0fbc52c1eeb4921c481bb93c17dc51e4ce5d72b72ee38f6f8acc65592b4cce39e6d8320b0bc27f7d7d684a0e3c83591d1ed97d85af68aef2b5a0c74892d0e3fc13415db8bb974eb3118f6a2a8921cfaeb0975151bb22baf1dba01e50a497909c214000000000000000000000000003f88f94e0cac5eb6746292fd411dab3b4885e7c9fb511f944273375d1e99d2461db5c675e6696443d3b77064288918061b033c71992a5d7579e2b3607de86a6d20d362ae071f38ca7255d97b7cc9a5683af413dadcaa27225284dcbe700da4ab0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021aa4d47c0d4cfa48f4e3e9d8ef41fef2032f698911ddda307cfcac323ba707bb0bc5273f7fb4e4afe5e72bcc1fe8d378d4d7dc0982f213dd06621dfd814301f0e13e963503ae5f42b1a2395b5505a0b8ff9246b244127f93bb5572a887fa154abf74bd788b04f539a7682b1483d371d0e686fad714eac9fe73109acef421dd7032f87336c7202dc693ae997c6cb7b7abbc997e4047cd2fd3c4be9af7a42dd356d021b8010ec405de41a4658d232eafc872b18c58fd28e6594e4e8e72a926cf35e950a06c7beb25a142fdf71554dc2b1df895b52806eb2528a8e7d3b7fce95b35a0d2752bbe498d6c2a62567273bde02c20fec0218d05508e67dd2c8d8ead33e289db10326fb78502e050013e2ae2cdb1fc08e4414fb937d165fa9b407bf09e20fb67905020e1266b01f4ee89eec217b4bcddc193a80f39825a534b577f2469165e7a2ede30208b695451ffc045d2bd02b46b0d1577c82ad22fe1fdfb90d90d187b6e11978030300f3e9b1c2229f70526067c90a133d54e039c7e56defe451d8a677dc69237e7f022c2053753989906a9dddc0d1b08361ed37bb969227edc4d3e9b58603c1fd2d4bd4fac9be6e257b5add330f45c3e181ed68514b221fa6d84d2bdd7288ca8614bdb7edd2e3a83e3955934710526268512c691f86d5326c42216b3f08471c11716ee090b71e6548ecdb035dd82a1e1eb1552e196a0971b16346dc931e10ef8caa2125767300e6bba475b5f58756cf9078a9e19600225460b9e4df0765e65461ee8af065488d2295a9f1e2689ef1a86061e42fa33b967a5f0894b2333e5338698489520df3575117a6606fd38eb7512dc48c49b254716fad1f93f26ffb9f9c552fa73768bc0f8a65b94f5b89ee7365b313b04f675d1d730414af409e8339b178fb5837154d06ffd5c6d191e91eb77be1407053ec8e9729d27e67865d957b605b921d1e7a46c88c0d350955d51907a5ababa8079d105b60cb80249e95fdb0a0f09600c9590bcc2a188df763a3e81066d32a302df20ced1e11a7d459778a4f4327377f9330e8a81154d11b3d2f5688ba433b9ee8604abad13119fb9ee4f7b6e41bf817a1e922a2bafdd6431aee4d04fe7fd3d3ecaca02a3f2817c538bc501fb3a4e47733c58d157bbc0cb12edb7c823b95b6acc7db2027d1c23736224486e6a9e8faef8a91d9d3aac1e0767d2f066fffe76011054ca4d3e020e312bf295946ef8605edd35abcfab0e106903e2742e1006542ace0416965c4de3ca732fef7c5ab3c045b4fa2401719065dc4e15bf42eadc337f1da778bfc53e25a8ce8cb8b85e90a2db1601522a22d34da89905c44107408aef5b239c20df33bb36902cc262d4efde97b63eda9c933644f3ce7f42b52f089aa7bd12b659ca65bd86d2fc49f2e87f7f0518bcfdb7756a8f489cf869dd7ff38d7d6f42b3192e1d9ee3ac059abd657103b0bef16e2725902c9c2b9a479800b5b4be7a01d52bfea510de0ab0a0cfacfe0d31981cb07b91123110b5c621909103f57f806eb2695860b7cda8609238b2e23219ed59b24b5031fa8e38b17462630b177593410adf9360bfadc24ae5fa7670063fd1e353a93e3d32cfa2811b49b33e79240ef4d6b6f2d3bc9198f23998fc35c2ac98c45dfcbb22248405e51e40d9e8852489f414eb0ce03c6a6f7121c4c772fab4d619cc731cd1ee585885d4b93775ae9f7b2e7bf3352dc96f62cc0a8a7ce1994e4cfcba58a550ea9c030c56e3f59722756389693b3db222afa79a99c9bafba82f190192c7d3d446eef24846614a48590fd04c0805ae4b2fef32aa1bfc1d183dfece19ac366931731405fe2b0b14494570b86acb5c7f291af8dd1143e1d9c6f3e47f6520c219eee2d4f87dbacf0d7f81e263a5f61088622d3cf710700512995e80c8b8f64272432fc8ab8664b1dee6caee447d74d428738a47180cff2644694fd542f7073db39cad8843548fee72eee52b347e7c51710d6c901be3b2cb35ea6aa42f0f71ffc95f085c36f6f08ed2202ed03fa74a167bd1a50b9e7158cad179dbfd444f50b2fef574f792acfc7b815086d3e3b03d7e29ab6661e862129a8f31a8f26802c2b88111d7741697cb0db9808303e103a148897944651d14032e8fd0163aaba3f552f061a5acc79d08200e3d581f7c7b8a1a377f0dce3a1fe95704e6499311f6d0fba745e200efbee335fec02d5fe1d411c035964c6a7d2e9b752a5f18202f6147b84d7ed517b0b89615c0947724d0b65b44f0952850891b15dd73e1f766bac0dc0cb5bdf9b1d4c89af1326f7a18fdda9000000000000000099990103000000003b0ff05a110db31d7e77b943088fa7e7c99d8a87361dd2f38ff26807fa82fdd8f696f94e65e1ac46cdee24c64ada8d8881ee40a061b4bc9a9eb44d600cb4e558d461cbd76724a0af2ae1f7d5afcbc2ef5134c7f57889271d7862daa3dc76b8ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4d30a9c5a2d487d7be24abdc7211d27d0c0ef5439ccf240c451571d9ab55961bf1b3b6170b556cd9c2ffd60b6120c20d3cb7cb3e3df9b14542cc280f9624010102eaaf8c32fa45a69fc4472197a70e23eda68768e317274022947b3764b6df8cb4128f351f480fdaed4a1d08c2145ab009f81b397f4925c09af10372432fa5602132ad51b67b4bcaffbfdd6fd1229e586c84379b7086f2ddf787eb6379fe8c22e03167d330bbfd4df3416fba887b776f3017a78d2d5b207126a426857804d5adc2e0b01401670e2d466c1de960cdb75765c17bbceaa8e5e1334de8889240e67233e6c2cee21b9adbcd4806c259b5dd3e933f7a75af080ac8bcc6349fe0cc86d7642230226b0b3c2a2105caec234302145267062750e297b5ae1993e0a62338c9b8fe34002082a030391ef3cb5afcbb6b0ca5e5b52cb9ec1c57ffb69880dd3407459fea48703137ce5b9bbabd7430b7be0811be546730b59f2f8dab6efbfef939a5b65ed66cc030d79c3fd9eb6b68724ec55c80cbf0dac9397fa7adfadc0b980ff9c77203c456503126d9a6be9c2dad7b0ceee9566cb72368ae77b37674f0135051c63240efc304ce36a9728cc0a1c756e85a975922c5dcbdae69b2892f88b48798bbb9455fcc54adc517aab17fea992be57928f96031af03d0d147aa733bf812cbf94c5419d4fda4f23a8236d8f930be4e88c3fe3013ee8a5ba69b92a013bd0e99778fb98fb7568c6fa1cefded53bc82cac3c00908ab81cb35d825ebca2662556b1ae3749ff668c338a8d2764b3bac920319c32d1a24fbc439a14c04c4696ec0d21f5ac755255a1b2a3572fc4aa2fae775bf848d59c9f420d283c992ca66c5add47f44e18ef82b9b62f513217342f070abbea95c1ffadda137f0d731dbc73a42f3fa2ffdc4b79d30e9deeba95fdd559c4ef59ac75085b35a268413abeda2a2c9aaf8ec54cbaa216fbd72489c7cef9a76e976d6902bfa1dd8f94def8fe2de8ba5cc6ac853b409ef7f9f913e64848cd63bbcfba676461a70b15feb7419b4006036665853bf79f49d0f3f9a602c83a1842f271615174ff810e75b8a14ba4c9de3c24802a6d733f20c73f99512fd53857ad4c86562a0395799bd5d2626569db8788cd3422f196d7dc362fd774b8e5f43b01ef540e035306945b97990c8349b9d5a3e72ed9be33254a7803a9d84719fc97e935825603042b70023686e08fa1ffce5f590907b934db6c01f888b11cd27750c3f407bf51856fee8f125c7eeadc26b0b09c23d1dc58e8f46d0189b5db370d9e1dee4cbdf1f13fe5b8a5862922fb160a8d14fc40f1ebb70afa82ab06c784f7ea8adbceb52d3d285a1e28195c91705214aa44e3832852d9c2d58cbf7677894bf7d9e56cae14fb4c224397a0f23da5a123b0b4d3a8be586211b846a30e3d485c0ae76cfa9e47123cb49b5037c9fd400af41b528be068a212589e6cbb3298032db1463181e780514a23530225172923f2fcafa3651064fe72b04a4d190ce47f988e4c5bc42a9281eadbbd75535bea68bb1fa840f983091b3f220035109e80178021bbf329a585073db6aa72fabb4a8c74e79a9c538145b61f04d64e5eae6e0867d4af84228eea4be151f702b945da2492479f045d63b16eb63201f131d0be5084ae3b40c6ee6fdebdd1daf39adc467788e42503416bbb19826c4c1ed0b0ae0d8379bfdb3969fa6912cd61056a67294b39ecee6f1867a3edc5f661c9f3a41009720d6978eb0b5b0cbde5949cf88020ce06f0b749eea89f340a1b2cf353e3140ff9dc1951658725ec91763ab44f188264f63e03952078175499d7fdde2b4e5509b2488083b07bae45e0e6ce4e29492da4353f726cc1e634a8d12f3d4ca60cf648d08acb2b766aa2e9c6df5b0e7f1ab4cc8fe0cdf7146e2c1c7945f15710804a51ec300f6cbbb2dfe4575104dd95cd978619e9c337244f302ec43d4d2c2dc60a5ff59c1cc3928f630555dd1d1969d7bf35edced25b90f3255baafa4862c2f47027b11b55515c6850cdd4e1ddfebc1f9d014465a766253d772f8547e0f5356c827f0b5cfa411a1a7a54fcf994d63ac5dcfc3987ce81aea6ed1924973a85a768bdcda9fdfe27d7455dd1301b3c9593e07739c5194490f6939daa4fd08660a2bc3114122430feadb7336a3795e85351483f5d984beedb8156b94ff38e05e2dfca9df5adc4b89425b54bc05d944a58bcc0dcdbb89ee9a91c9674105fa82c74461a8285ac7f8189a1d06d0db4721432221d2312201b5115f32f7cc6d66b62dd37f9805e20dc0bae929d777c66c9b390463861f81d69952828d52bd98c24e1e5620597e8dc2e7fa278fdc5fc4d1051bf22f63da40e340c880045ac2838759cae9190d832bc490ee70dddad2a7e5094221f385a145906a9f4a5fff3def54d368625f8f2fe845145bbe997ff1a82d4a2430e", "53ac", 1, -471772630, 1537743641, "776b5e94880708f433d5b605972c4f6d0b37e204a4dde644547900e3d4378f9a"], + ["030000807082c40304b38aea5354edee912e1aca741bc7009c35c1be5a6c467f635629f527a200719c0000000000fba75fbc67e23a76edeee827b06e06da0867b39aacb174039318926ea1a81b456fe38aea00000000026363ffffffff4feef7fde8f8e1f57908d6fa361677f03682ada8888f4fd68da21bd84cc29fec0200000006655163530051ffffffff45a3f095c36a1be40fd9f3dbf2d78ce66eaea83e8401386eb1229c91d1664c8603000000035151513b31022f030849d100000000000351526521367702000000000665536aacac006d6963000000000004656300ac676fa15d0000000002f02a990500000000000000000000000003c7dacf6a62d2214fb9d6cf380760dc9767e33d367a7ac10f02540b1fd218104058c23dbdaf9515a96da1ae7a5e945a3faa4955419bcf6a625a3e35607a0d6243dac96c50ea2142070b63cce7ae9033fc15a7fc76dbf62dcffef76b483ccdeb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001cf4329654e76e4a62686fb3930349f1d75ff7fe10af9fa9f90d984e537f83b672a89ae6e41ae6ad2360051b1e5f5116a5cf43b15e96381e9130adaab360cd66f830bebc7ba69d6cd038625be3a1e47d2d595368e9378688b508fcd7b34652466709e50baf383960db494d48eae5ac6ba95cf925d87fe216b128f42ceff4714e021afaaa21759d8d1f8a7ddef4e07d537a16a1571d1840a730620b3deb33d584b9021e5dbdde7ae3f40d58be55f12283d76341c60c6fd431620e768a4afce665433c0b07d1e1aecd6959e3d531971eef4ea360110dcf466a530519b624f81e12d53effa2c92b8ef4d081e2e4aa1dae56e8e13d9186e89f19eb9a5e8907d9d75f757ed2030ce7fc67e50b53bc40adab8e7d7b8e104ebabe05c49bab685677f06e62c0930e02131576fe7acccb1db5b2e2324b6cb9607a8b600026a677e79e6458adb3cd55a8022ee0d5e715e451f528e0136eba8196a55e6fb5e82f3c56a8c220dc2eb8a4dfba022f066c02d6e60720f80b254a3e4068de976088a0c19464d32becaf9a86957e6b020e595e5de6be55316aa99aa2e29c11bbe06960fb91ef8850711d277ddfd0c7a8434da77bedd4344709266ea9421a5ed9a00533d5e2b4e4aa7a86a635a25e6348ac60f128cdd6638f9ee4b10b4c0f3c1666d51b1a93c756c3e90535e3c6efdc673fe0533d8601501c66399c6c96bfbaf4d434f19e5b7f0107f42d3321277df494c858ee812f2b152ad6f3ab78bfaedf3c1f0a51613f97e551fb0d9150f874293f9d039dc95ca466c3154a00dccf6c3dc1d08d3b66ad81f49c58e89155d33790a1d31431faed392f153ed8f38147c5988ded8c4b478d51bd0daa7f298272e7e3a374dfb302265c520034c9db9b4f3ea1b425d144c0110d6c31ee13a09de9d611da02c42c7644058313179ebc9d47bade60abc8250e6faff2b4c2fd83ed572db3e6007b782978c337847800af706a45d0078337439b82faf4294c293a741d530b66bb5768eec63e2c99d2ed7694ff2cb711ea4a8a774e5502d6943f6f5d91eee15b3901d8d8dbcb7d9acac685bb74560f4cee27df5beaa0991e9bea20fe68079d39c50334e4ede3064222df36d3cbb9558e98d0b3296c3115805bf8faa12169b674cc93ba57409f810ec4826fb8a78fbc604262c302c7e617f1f826f7baf75d2a7ae6debbc422ca5458966d3df55a2f06ef744e238f0c587fd645c1adfe7eb9f0aa57da6acd4692bd63e874f5d7f60cee161fe47e411ee94b69e83fbcc564569ced900960e6f6e84fd6a423b8cf6923e139f73e173aa203c4ac8269a4d4f486c53a69e7f4abba03b0a7c7583d7398bfdb5a406b31d5203ae1db10dfaaab13adca7dc301c4b50581452cff09d0c0028bb717bb8d476682b67c4d03ae6f414d829258581edd00a7de350624693915a3c688d069337220553b16c510631da588df0bd69e28ba7e506aff480e550a0511307cd7a296c549d85930259a28e5706518ff59c37b16df620403d91b17a6708b4d9589277d59c38cbe8ca84798c5eb70936ce725316d29c960d59bef45265bdadd44aa47b016129ada1da3144d3eb175155592c7f43931c01f3df9821b33cb36679d71a7e2be59854c7ab9d9137699795fd5f6bf46e21f3ecb0b26f09053e06f2cd8273290c944b6c2baaa75feb33adefa857a5da0e7bf233fdd72483cc5bbfa1a39b404efdd9fc183518e57c860f2cfcfbc6ce61c48cd33eb898f0696100072dccf99f8e22926b0c584ccfc4864727cd3d1a48b774bfdecf02271a58a0589250fb66114318540382b1b15793cf8efe79115fe54023b410e278966161a9df768aff561736f2614afdc19a1637d026e6681e6c9d2126cee81ec72831d2482b95327040a2e324b83485c818da1a19e42ef8436568c22b46969f0e4eef1d0fbb6b1762e98fcc234e51590ae4ede6fb6d5ed5eb91162f242f98a69a84bd984dede1295f511d3a81a26cb0f0b45f4cd354772adb71be7f5bc8bff7d2c6f62b355c39e8cfa412a777094f20de1e6d0839b456c1ce7596dd56855709900b3883722b0b88325c5be2181b13bfbac1c618d6038388a7cd5d82cedd74b80931ead33622ae64abc12bfa01e2172c3e2908e36e82f7cc0c8df10b02054e6ae43a565793a62adb0632fb04c5c0fbf8859d65bf7d611bf577b2c7dbad68660048ca5f562eda7f1f085faaa2ff9019b8b77001c009abdd6855df78d7bed19f74c6de3e3e97041d169a43d8f2441e969c831e38c1e4ffd25a009e93d85fbc631b9a29960d4d12a4a3ebcb5315a4754a3010000000000000000000000002c68df9a6ea06afdade977623ac73ee532371d13c56270c5ac9dafc7a4f4b3e447295d290f3a2d5254273fe8c82f2ee1e130e2909f9f440008dd03c3cb2ed4e71af3faa0b02df8ef81680baed3faf2f24b9d98c14a34a4406d81f9588f2f77ce000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fa945660af53491a349e5f466c12d0949dc9c854ec939e4e8caba56ceccfdeb5a48fb14b93fc25145fc1e5c367e350e27927b457fd8a7e957c670392c0b9f2cee40dcfe35573334fd8df79a2e49ef22da0bd559c8ef5df3ab678a0cae5a3d1765da655646c5e9b6ed2ac0a190f44613e63b4329426857f3eab23a042848fd1d0313ede10b102211b4af7ea1b3a3786869ff73a274b60d44a0888d1889c5531c620215d077b171505a724e5424715599b58c0e3cb85af10eae8c992c67de32d5e1e30a034654812e1ad84d9f260d12d516f2985952978249d678227b2bb0a9e2af013bb4a7d8570a161b1aa955874317b02cb1998a3b209dc1dedff3994d5ddadfbd000215f09661f8c0f5c55912923e7db41aba65ac316a7a4d475c758e47ec7de2cb4d022406b6874483aac8db3f3f45d844378dda7a5fb5455704d183646ddf6ed04676022e3f2c5556e4b62eaa64791bc3fcb210394f9c9a99258a01e55d623f817c69f20309ec73e5da2b226a7ba39b5d2c6104d3acfd27baa978eb24a05b36a8ded46873020006f5c019ccfb1f4920a1d9ee29f8846a606289f2740cddd010e25ca401dda593e2036032f8ba6cda7599a29d58b99c0d6093b133843b64dcf29c53b09e50972c532b19cb07e5f818fe7487b363d9aeb353fda42e09a55016a300d6a2d41d812f75d86b711f75b51088ade8f4b7d0c383d510264d7bd34c63f2565469a26e6d87bf611aacdbf36e9b7dbc75dcfffcf5d425e2b4e72d52a0a28a1eafddf855d5518b34436ada75c9f24e740003922634d19fefc9b3b5c2379a4b4849b53658822ff2a6e9621209fa1839e8726d36779d7902337c38754ffbd4d4d07760561c7e1a59ceb9f2511c91ac48661608ce0992a13fcd770f8464c7e5f2fdfaba8d6e6e446fa0ce143229b3b519278a3b8f1f4500a651b3b3b1d4b62684680a4c7a918a611f2b5c45e6ad4b90028051570690dc0efd6982a54b6bb6c81fa9fb4d9820db65ad0adcbdeb5a598022e42f2992522559be4768a42be232b99cb861b83231054b76fa16317c869fe462c1977ea63ade234861976c77a159936f815bf05bedbb3edfdb08195702ba051b6e8a16d3925a01d8e0db60318780b74a1cb2c92936ea556d88d2c31b2c489724041521581e9485900a585f15d98fbe924547beb2bacfd06fde511cb0750962bc852c2ec5929e2dfa2bd87474e848588158d0b65ff6ca8a359ca792f51bbd129fa89b1490fc5686b7fdc468563501cfc1d4a5691947794a6ceb2bed21558bf71ef009d63f1ae84b382d550d75972c02835795d113bf2e755c89d2dd81f2c5ed8c0c191e6096e4ceee42b9f0485616bf02decb2562f9d1d7c254c7af2786d64362513cbf7d82184b45a9c3d68f462ca55bf52d4f41d5ec1c72b688e8bd24b005385f6278f7bab4ddd0cd958720123c5251339dd2dd0de32c4addfe7356270a5d0fbc6679cf0f24ca2dec26d6e6682825788fd95a7a1e7b03c9eed34a35439795762d6bc9e87c46c3ab14377c9d42a6f12216f2488644a81e764b5630f35ae38620d75bd019e73c2a235189fa34be80c1c169a56a007689650404cdbc6a2cb72301f1bc0be7faac90d342c7aa6699444e6cef75290fbb5401b7bcd7a49a02d806132afcc967e8a959dcbfb7478287dfd0f0d54ecb395471ff9bf7b6ea979d82bf3afc3c2df2b4e8ffe90fe7b97f989999b1d8c9f75336cd30c4dd7ab33118af6b425967a7182586938209ac156d21bbe5ce28ffe563dc70f58b00e72b3b31aca50d9de7fbff8bb99c226a8eb06086dddb6fa23eef495356837deaae68a7f28456a3af7d3136200a97fe2c6a4275acb5793f830767ebfe570431ebc662a01cea876de2e23eb58839c9c4eebb37ea8d164479c5a0839bce58fea7a4c72c8cd094bbd79b225bd3024b8e077b7d1378c75e961d7b9d6685b843c8f999e2a5cf3d2291b84467df888b306b83a889def608c03b589adc9e0a8da42c9cb4b61983fbb144734b73c807dfc210cdc9902ef18f3180dfcf6bfef6f7a9685b440620d08d3bfc2ed49edffae5cdd02f0d57a386f4cd3a137cf7c5c8ae067a0cb9e3195c2c7811c937a3e5fa9503683f052e259f7530de998290693d4a10192197dc82a9344a94482f9f1cfc1bd25791732a4f412938dad397a152b3434b97983a8d22fefe5c2acb2146784f2a04654ed260577a09f1f1dcfc46b469c29771a9ba41d88211e4d5118340232cf659e8371368be038cdeac375dbbc08f14e91bbda5845c5a9818ed52d5400623178cdf10921f26cd9ec139fb8777a281af858d70452f3ac32be799dbc3972253c0d8224d3093a3b9c63bfeeecf1bca0e3fdfb3a5762947a722499f5c2b9bccabec5903c6ff5a81f5bb5a62069ac923d754356346fd0f39bd037a2d32c2c153eb6dc1ef0a", "ac5151526a53655365", 1, 1221443303, 0, "72c01073a3d806c726e61c7c965d2ccaf45965b1cdf33b8ccfdec10dcf45dbf9"], + ["030000807082c4030253d8d2bdd86e819c4bb6adb8a77d66d5912bfee923557ed8038304866831fc8a0100000000ffffffff80335fc2cdbf20f6baf9a497ffcd1c4c86a3a48adec4bcc9f76e686fe7b26eba0200000009ac52ac0063525151009c2f0c7103823db5000000000009520063acac52526365e576da000000000002ac528b26d7020000000005ac536a656a000000000000000000", "", 0, 1726733575, 0, "93fa4e45718860e72d977f41bf6723898a236060d515601cf8c6a9d5fe484056"], + ["030000807082c403035675b50da6de9f1d7fd94940726cd66324ac1ad37fcb73cd7b2378ad24521be903000000026500ffffffff354df6831e85f59303a74c677d448ff6ccbea07ab6b66f21985c9bc561d55d540300000006656a656a6a63006b160a38db85c722abd381c1b3c8ab1c3b54c7cdb538b4817d65dcaf5cdc37df65b1060100000007ac005152ac5263ac137c6b03186f5103000000000953535153520065656360186a0100000000036353531d63210000000000010000000000d9b09ffb0100000000000000003fcac7010000000073709b017501d52afb18070b2a72659754bd876b8b6ca0d05aca8fe5f3ffbc5556f6190a861b4aded81164b66976bac6bdd14b5531b01a282c74af26530fe143f5591764a98db7828969b38d6dfedc9282b3395e698af722549b6f35fb84845700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000491929598d4c0d40df2a7e8b2835b449a52e766d7ff1afdf058e2936dba5631b10289985e4618b1c06ea61805df0cdb290874d7e9318a729653902c9281528d581665bc5ebb5cca48d28215eda5aa7f5227fd218cb41267003d4096ca8f82ced77e10b44c4bc89aefdb11e8ef734417f2ec8521fb25d032663a070805e2e7cd002081732d7bfb559d429d88947c6f02f6b52555519cd81dbc83dabfccfd307431d032791331614d8f9b75fd568a87d4b09d2535ecf28d8b1c19c4ed53cfed5843d830a0326b228baee23f2e36a8dbdf76184032aa7041091ba3ca5d26a4c30e2cd2aa22b909d06415ac1ebf1c42bee92828c6c0ef816f0549af1113073c4ee481276e40317c7bdd3197c8dabe950855dd4e24c38ec8979adc72a20ee2890beb963be6bf7030c23451956e3bf08613766c0cc669607704ad256fbab874454058cca9c57165a031e25df8a2436761404cfb852f6927578b0ca133294fab66fba3c8f26d559f79f0209a6dfa43e7f1f349e26548d522789826a320cd0fe5ab5ab85db61451a26f8c103115a8bfd2d341e4024e8087896827e74b0a1d7079d5766ad812432109c9c6c9e1e14a29164480050f9ee5c583e58b3353db6f38c05c90ac7dd672c7e3e5d7ca242d47a29e61d166b044076cf76fafee269a22fcc233074f7fdceaf3d0164cba903bcfe209fa0c7c76c2e897acde79c644cf47a5a3d93d0fecd839e64213fe93b27e21b7e611067ecf87d33292b4e639606cb1fd5af3934b627a1a6b4457d47ad2bfd2d0f3da3dbbff20252f1c12d2c95c132fa89ffd5a32d1b2264b181bc818db9b592f0665050d91a067a69074a4ad810da4bd385177ee3e2ec2c18af61c41597ad0644d72aa39fd3b664bb4d71adaf9f29dc6fe0f13baaf8d58bd05810dcbe1e20a5ace349e8a533553d1e6fcd40bda5e6c34e04a3f3253bd881271404f63762115e4815e2706a59ef23e2fcd2b1388e99d43aa16024a2f8d7639deb6fbd1844f8c9fe08a696e35cfc0450b102e822a678cc422bb9b0e14f8b2a61913acec44c451bfc110d98d35dd9f7a69b5a08ed675d69f73701a0a580f4eb48b7967ef7799de2426169c0d78bb2cf2ac5afe533ad3990fd25c59b725cb69039b136d5de18c284c0502d9a1f3436877d20d6c05596e7712d160dcdc8ff69a328f810a5149a29ba831790151a5eb14b881d596b8cf17af111467db1e0f7fa792e2ab1787e23e3db99844ea4fc4edd000c6825c6814e35eb2e50cc84a8dff41d017857e3911bddb5af471398c00b36c627427940ae644caa574f912d7143bd37ef90fc304d09d10bb1436cbbb33a9bc3382543cedb7a01b324731e4fdc6d8a6ff83ba28d491bf494bfbedfabba2af1054d2e2402071e98ae3cfb9793e123ae2982838f8f163913f0b58262f399fa35c10c870ebf2c3a7fd43141524f8e02f016d8568bf0f59a72e5c76405645346ec176c17a4c21989df3c726f616567d2e0c3a88ac88a7e6023576e955955545fdda33674acea5f852560301e02e7b53d679d18cd81ee29de4c456590c25788c774839d326b87125e7f13bb7fb5c59f0cfb891561a997860a9650436694e68ea3cc649729cf5f67c1a3235f3d9b4797931cfdc14f245b4ae2f839e7a7de08e8b6097f372c18f6eb579e6554d38d80ed3954a7951b956f89c8159e481d601c57dd4518b4fdbb25158af2783fce0867a19b70f3f12e1ac60ca94da7afd35fafff98ffe84406f900c644d59c0846addeff2800111e29902768302bf9a1d89dee3f98dca9a0f70a524e48d01d6a5ed1b20d1a891417eb908057ed484daabea03bc5d7ce97d14cb0a9c42f6e27f0765cb911ce2ca057be1b1d9f5441700a009e9f7c2892d378e8135084347aca677b12c12eb0faf5787b68c47bf9f2916f96fdb80d8d7291376ba68a9e76f5209db999e1ac0ec9e62a37ab5a80528ceb5b46a16aa8be63e0566476ba47c2e64e04c07fa1cca491de4b905549d4f841f1b19e5aa5162fd92215f2d286f9763ca29fb62e90c1feace8c15315d050bd179550ae2f776610580448463e0e1f4dd9d98aeeaf58dbbfab85209ac546c6b3ab66cd57caaa533ef0ac00deb7bff723417f809c5bd145025682b73712c4da0babceb9afe664dd5820485c1d1bbcaa9ee10c12247770beae3992d26bb38e56356e8ab80f3ceaa55b7faf69aa7f4175aca0836e725830103a0fba694f78598e919c629b47273d7fb39909aab9f1104de0f811549ca24255a6783fbfd2eed69ab605968b47b781c5012e790e9f8de6b2f41c39fafde3ceda2cc869c2944e27ad2baf7397a6b339c914fe80b88f571446812e816036430bcb20ef7b96b02bf919f4216ae973447583515bda2d4ddb54342c9122b7c8961636f59700eb5a801b887c1be46248a05d435f634a92ca5899b72a02", "006a52005300515151", 2, -1471148157, 0, "9c808ca475b92d50f8cbad097be684151735c680855ea9cb9e12e162672d03b3"], + ["1199787f032f774c49b4b0e2af92ae27c4c3350c746909fc5f04a460f3c604190b03bc4f3101000000046a6500ac8e3de8b121dce3acd7a9274f7aca63b5b8001036c0597e222e9734cb1e7668b8040fe5b6000000000552ac005200ffffffff18b591d5c1c47894a644543e9781768d03ed70f497b25f1dc02edafdac7e50080000000000ffffffff030d4d3e00000000000252ac8ac4da020000000008006a516a655152514ebc7e030000000003525365654c4a2d010465ea040000000000000000000000001d6067cc3328a16d552966398b3e27557888da181d7210dec746567e8f6c97aebe47960e95caae8d333e70057b1d6ba522db7515dbad5fdb9eaa34f7c0960ba743e982119f76af994b799f6dbd217365b885302516ccd97e3f0b40ff0f7dbaef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b16ecae12067671709683720331f39e33afccddf75574059a5eba39e9e131405f965097833222562e95627f59371ac520b5ca79054a1b87516b55359a30a3a4c55db3c4c05679822cc825ba2dd34eb7be9212f17277575a1dcef32bb8dc86ce7f57276598a58a697a08beb2869a91cc889b554b1d1cb6406f9c490a24c81015a0328cbc97e2f6da87863153e27dd40473c5f275fc8b6b0b13d642e765bb313f98d020e0b96eb99454198623ad4dc394e815ece66bae524186af50391c808ad4b87d70a01c3b4d26b1028657629112663795156e617d3270f0f3276547c7e59f6ed1a69700efa987a5f37523290afb10982328bdc1df28c4acbba52e3ac74a1bc16bd81032313d866f01ef5a556ec443c0861020813f91c5aab94dcd9586caec0e447d6fb022a7f34f2a30f77d1db80c33bda00624d5f614b8e7a1ae581906143809f9224be0224dfe0124f9d2136fa23ff3fcc59521fb70977145e0818f2635cd9902d3a33eb0200ae4869a4813fc3903026569ddd9750279f71cdfff2897d3b85e2fabb5e27f002187b558c30f64fa49f9987913b2e9693a34cff49cc5985879f29ddd4d20afba827c2f6adfe5b9ce128b29b8056cc9a73f309965316a7349c4a5268a24c94f9bcd947b00e5ed99508d54065adfd1ac8e8ccd0c2df2145ba592accd4d84e3f1eb31c12e475635d883313329de682c3056ba12e116eb81fc292ed8e43292cbabe39ac838d6287679b0d68d538dd06e16e2ded34198487c593f7e827ca466a65fb1052c3a0a5033528457dafff722d8deaa87ba9d74829cef2f828a496f15138a2e4c3325c6c8df6acfdc9a28d68f1ae9165be812b870708dbf9aad0f4c9cfb0d95f23ebe083bed9c8f5989b51265b854e10e44b486c97b3ceb4bcb9f3f21b0a81aff370b9fb3a4f33433ab148d06433ff03901a6cb6ef22d91e70e19eb043db63f30b1c9cb30ca7c6c4f05984c0d692c009b19db0553daba7e7adc537db82362cf23c1e357ddd09277d3ae2dbe3d309aef810b131df24415ca26cc3bb24049839093845d2db29bd49fa191ab6ab33531af6a5dcddcc40cb311392486c39642958e587becd73f84008b824a798106249265f8887b020bbe76c7202e835a39a1ad3631452c326a6ec0447b200e5f171df4c905d61efb190e0322dccef9f8bf66aa4ba4ae18cdcbf88fc65f05956491084bcb63c56c56d8c570147dd73d9531e0bb12d535075c36fb25f2553ac51b2d9ed03e9536e8493e7dce9d7b09c54fab65be3755644308cbce0c0f14bf5f9201970a33cc19ba4ff271c17e79b5f68cd70d809952013b811c750547d5150c8183483b7653d666bb0e8e5c2ddb9441ab2601b5480eb2af8105729711bb42bc327b634b7e022e20c18033539d27940ef3a2d8f9839c6280cc0dcef065ebd3cff0a4c6480091742d0a12c9e00c8a93733d21f3f9ba3d2c4990fc432a62b8890d026d8cce44bd3131d7a1c1c66fe252d90d1d893b9fd051bb592102051803c117367ffab1b2e0fd8787e822b65c1c011adacd86fbd7648de84f4f41f7505a481339fe7b0a339bee228cd6e0613803a66a6b7c560de5cb85452e06094691de7d52d087f090a3f7b0bdaae5cd0c85170304a2d48048c49cd8a077659d5de51acc035ccc7448640ff7a47d6f5869c776e77ce7d070056b19ac76a1ca0585bdfcfaf524be92ff8dd39b994557fddaf8e45b358e284998e0146ee55a5ad1b881ddcb9b52ad79ca1fe79ecd6f56675213d35762a5e5efee2b0aafaf5a051c48b851fc16da462f7585bb99780c2e6af17afaed1b30e5ea45dc38d2adf634467a27958fc447a6e880430cfcf27e34e25ed327172b6dda1acbefcf8eccf04fa4b3803b13c608578dfb503ad0abbc5c054814e85c700e621336614c9cb2a44844ef529b5075114d088313c538994bd922567137f500b4a52473ae38c2fb16c51dcca6d284d434224cd68e5f582ac2bbd7693a35acba25bd5dd6f2519f1b231731887b3e409ed46c5f2b8f496b6ebfd1be114523161f4d8ae34a44b41db8968849dc3e68b27cc220da43f4dbc59df9aadeefa2cf40587a61fab88390e5ef69b5fbfd362096283f5217332cd35f65190ef24b01e5127a0279197e62575ce91d29bd8724c33c355f9b474d382be2072cb571e433c84fe49ebbbcd154c32ca96f931802c6ab51380b1dd84f118ee15dfe3da6af14f90faffec7271a7dc511d62f5a878c299a042537ad8e993fefa26c3eebc7c1891989d76a478f3a296899fc46b58ca361c05399d03f6a3bb9fc05eafe794809ed4d84a14b6fc1edd6fe60b1bfb3709b35d3469ecb3a75b713668e8b2c9e024edd29830f15cea620fd2caadca936ac388da9fce8f8c45003d36b89f344f56b17de89464429896167b5d519a904b6821993bf0573fabdaedee93960d", "53", 0, 1221588783, 1537743641, "b49d8b2ad1d6aeb9078cf3f93f131a8f1c582e41dfc699f2b28b19e04d73ae72"], + ["030000807082c40302ccb9334a485469de8ab7de99599e32059da5153ec0c2028c397c577ed9aaa2e70000000000ffffffff0f7cd19c37a0812cd1f2e007846b5cac37e6c079ffd9a9362aa1f36d7efb307501000000036aac522e5c057d03ffce390000000000035100ac274f60010000000001005f3a56000000000008525165ac51525351b9640f063415bbed020580e60000000000000000000000000058549365b633e38155b05e372f3e6efe74e5935247bb0394096202e0fc86bd50d321cb992788c713238d9efc012bc60de263b55f049fa1955d4b2004be66140540eca52b788f95f60a979810ff2c0c51e9d88c0597de7b90b9af88cb645da87600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d75fbd2de93b8618551d14c32f057ea240363d004df0affef2505be5c4b89a08c974028146c1eb3dfb254de760dc9a3c30498c92072d50af3bbda66a5491db4d32a07bd24743d6f8f29a301855ee36c9dbb25de64d4e5f7af30223ba5f344c3f8540e1c088ddc10bf3233c1249b7819eb4ac8df1618a0b486026bb18bac08b0c032b01042477210a4228bcce6532baf38dfa0c3f3c19d57120c43a73e3f3e22f49020d979aa7cfa1a9f2aed11c0ce7e89ed124fa24d7731c2c95ad012fa63cd6a8400a02327f1dad1a80dc3cbf57a0293aecf5d80543f7c5cf806d6357c9e3b7957b26235c836813e16e458f3829dc405366d9b7f50ccdfb74634d1b69a084af80537d020cb8cadd60d91f546ba1fff4e1192a7b39ba545194d59ae63081d5240a701842031970294ce2e0201fe6ec6f8bdbfb46a7133981e72534e83e60fda355c600510b021f79f219922d0216d82fc46048be8a8dacf76fb16d2363ca20952b3227992777022edb1b610141dd62b05041dc7cff40d0222fcc77db07f1d0fb42c7df297b5022030b4b4ecbd2e25c17a8606ca11f602dda25c28b0cc5e35041e1de70c9e5ee37fd414366bc95823569d0b61353e7d301d5e411807c7dfe2d31e4bd7afc2a1640f29e3ab1006450e8533023560e1926273ef444b08cbabcf3a32259a18ae86b6302d151f9adb90e4a1fe0d92d12cd9ce619f4c36a8ef4371e1618173c54a8861bd3173bd28cdac409a65543d2a7740b187441f260400a5056165880a093518f0a23fb1f6e3aeafe1b3b009a2a86d7b7fd3b7846aef2bc2632cd1c6c7c42c92908d48ad82c3a3002df62ce2c386d64870852db80a6a9b2b96b3818358aa331a61f8d254aaa73121c9fc96bfa89ebe7716625be1ac51b223cd60ce133b900a454c891756c71c8e59a321abfd373dfaa642e2efa519a3fb66a8fe8b0d9fd3dd6835d8b22a1acb36f55ead763bfe5b2f7c8f431b3cf41f45b1f192343d5865fdeb74b204064b0308bad456ffdc2aa19186d511029b32a7b08f9c2b8365f545322eea7497d5df2c5658ff25e728c827feb1fdf73d1ded5506a26468bfb063b2fe6d794a38579a23daca205c62aeac9ff64f0cdc0a37a6119676837ef9edee9ebacc0b07b9a4d542ef5ecf8bbc065bafcf6d588f0c193f075ae9cce2127c83ec9c459c9329ad9c436acdb0d23e32b9e691c2775292f1273242a01c56bf77a67807ae1b7e73b36b59c94d2b36d3620ee67f06c0e1bd5a7f0a342dde0c732046901df9b99979c0c33361700327e54f6e7edc2f6ff3014b2f7c2e3be18b600241fd0f251a317d18ea508865b05154632fd1d02273961b71edfe52694af4500adc1fd99eb1b2058096a32390872c87a0832dd5206b17820aa5e7a754a180420ef21a5af1deb2ffc24795ecc732426846aaf67a73e30a640acd8dc008464fa36030392b15eeb1bbb04cff097ead04ab20102cfca87385e651f62929552eb872633d69fe68399ecd0b5637c0acaa76636ae883a5ad4913c44cd1887df47993b4d27d3b3134d9b08beca14ec85a6613cd3047632d0556a73ef7fec4e72a17705fc9ee6d73ac8b0f8a0c6035d9c721b8771236b957ad80103ebf05e1cb6e553193159919211968b7b19c7aaa723570deda50f4c9b9c7e2dc24761da1aa08be614060e26f1ea497b6b24096fee53c44b67cc4a65ecf44a33c3d767accc63ed32516cfb17458b9b9efa4acb7f5f52af890bf0a75613e018ef58f078e5faaeb77bf066694b277960b87aac20d0f8a2a58b35c5838fabb7a46a32d6c8df966bd338fe00b09278e45a7d31d12d0ff586d142619dc60760759ade28878b477c269d261d27f0fb918ffc909616173d8f5fca99787a3d1e28c3eb7170abfa14d292cd47c5938309338e30f0f6609221ee49e52b1b8d97253dbcdec3c6ae3700baece1380c303866f6a7832189daf64b23e519d2d5a1fc208507dc4d7581fec9006052ec1f38d4c8c241eddfed385a3876f02d3b9c23bf81d66f76d0952d645382c50c4f7f4878ad048457fd9f145178195c1db2f80c390a996576825a15b91aae863d0e6837c24de10c14dddcc0fb822bb4adc90a65ca0438818dda7c1534d37005be7933f8e4b50bf738b94c12bd299fdcb6f5731eca31d9e2da5e1c24f15b94f28cd4e555c296e9533d0c7c06125e1610d76b3f1281317ab4a06a1b5ef6bf7537bd723496aaac11e625a5e7099bd317ed8255123e535de704078eba99ffbe870be4b507e38ae0269f2ad23456e03c8db7e240936af313edb4981ac603650000000000000000c2104a020000000038fd514b94418dd90144b02b34d1cbb614437a29f97fedfafcd50e40fab78d46dd759120b2e2c014759bc2bfaa79f3aeacf3cce8347f640d12fd8f2f24ee7b573bfcdbfb1f2fe9c0632ac4944466c949aeef2757176c9f611691a00df530c7cb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b0ac99df12b9c976c715fec1f2010a16ba77a5eb45a49bfd35658407d661286dfa58dbbb3842b1408e6ab4ef0b84c20d4a575e74073fc915eb08aba373970fd82f7e53ec189c4b60116395044057206d778f7a49ac0b3c2bc7d79ee7bb5c1ea5c6bd146062dce84c6c3d12eb4481ecad206d0414304c397702a76d2a4901a1203178b3d17f06781353a5f1be951f3de6bded7f4ba88265dde31556973462cce02032efd26afc751f3a5266b1224c3645cb35a951cf21a4ead0ce8da8397695823250a012ddbca974e84405533e8e1a7320b72f4efdb88afd7b29108685a2e014f3e1c73eb197be6c09943ebfc780c67aa9ae35f33090a6c9313287191541d7dff476203011439b665d3e3358c079606f9772933a5c2e08da8b3b92ca3d171842a5ef5e00202306653862eaf419397e2cca0020774f77031170c327f26012f1f38a50002d802117f1a84b174f78c4d296f748be0d499342fa5eed06e85fdc91ce35df6fa696d0315e3e9e4fc74f607e0f0f0b96c65f467555aa6f7bc94f0e7f45650ee4ca5a21b031041b071f86ffa3a30d6d2d536f8ec91a2046de02571370b062a1051fe6bc1e62adf54e4d8a0f9e9022209d11d8d33a2a07c8b16885c2b421c1ab133b6b630376e77be1a51d7ae4932f4dfa82826921d8fc834ddd489135890f95c4d86df45f46bf45af9e48284320fda1c0527efab44e5a48d928bf26ad1ee77749132715dd407463835deebda86373b34c12dfdb06bdb35aa17a96e5bece362fe7c5116ac1e5ef1ea976ec8dc39eaabed26e29884eea385efdb5371c0eb732553ae80beb04d9366c14ec0687b30bd4e60fba72663bc4e02e1393c28936b5e62248560bcb62577225768055652ef781e1068d82ef07bc70714ccdef34d6ed4ee647ebacf3374b68460cfcfada437b1233d83ec9fd617c326647a5ce13d0043c6d39bf3c374ac77c50399ee8421ea4cfb9425dfe590d0f66b91effd6c2055a161c38f3b7a8a38fa9c1131a476a9620b40b012d5cfb505b6c5c5f171060ced00fde7dd7d3667f3b7d8009df932646474bce5855207e0620b4f8383a539b508d8147a97a26b871dbf0be0170d1ebce6286d1f87e5900f07cce8217f9a8bfe373b6c560245acdbb7f257e52faeb9061c6968cc01bbb43a6f0991d255b0ee85d68cd1c96d84a624a3200a0e8e8905ecb8fc89f79d6ab1474e1d77fcaf0af6708fad37cbf2ef729307ac0aff2ed32d1eb4d67b385403844f9da10481d4ca8dc5c2ef630343d9a7a006ba2f89af1663925338427bf25ad5ac75e4e7ac32b974b64c21256416e4e288d366ec7d0cb8f84a257294d923844ee8121856a45b97ced9d104f2bdde5a1f321591f2f4b3f74fc9384df9f3b70cab4e5b68ebb3636205f6ecf6e616a8820e5a3afc06045166e271068ec9385ef376e5bbafa698d58ad44885436f25e416ec08a836e5a429caf0a8fc548fe6b261efd46070b57414f067e2d3838868ac943d44c44a4402264d729476fdc0740ae44221b752a102ecaed85874fccf8e50135effd5c87d19861b79a7a316309894a9cf7cf4763e16a23eede359bf6ca3d78eea1646a7cd655d2d6854347fe7d4c39bd6996b00e5924effbda2e5574788fe29df52988ed52a6c5561cba8d6cf87c3022ec989544eba2419219accf3e1975bcd762eb42a9a1cfd4cb9a12614cdbcf1e49887552908ae63de67bfd2e823ed6d780f5dc74426a3c70c4fc3a75a220cf0ba9412c4a07d498db71eedbf28ce5f7ee5dc32c1c31d1cc54c0129c7c0d9d19f506e2c0bbc8a857516325e1a325f9ccce9acabc73690c5d570c3b7580eb4c612d6dccb8ee5f9cdbe8e2667bf77746f364881a4465fd0394f3d5e2502c23232351a52f10c9c908c038ed2c247a22bd1f8636e05ae47fdd95c0a8ab16694fa40ebc8013c0355e1af240fde98222d8567f15367f2beaa2fe232467010da75473e2bd54296034186e95a46b644ea7c4c748f2ba2104bfd2138784984a13f7f75b5d7ea015e5d6681fb94f2d1a13c0e1c61d4c6881f9f89986d3197becb3bc2267b96ff9e0506f6a6cf496b630caf473fdf56317012e691f649c9623ce98450602dfccddb146fdf7b1bb267cfb654df1a2791e707c8ce18d0509660e984732bd2ee50953a9220265866cd34efc1dee456b88eb5712a55573bd458fa2a5e33f1e4a6d63def7a787e9516383e8e2e27bf13b50c7ac309218bbcf38263ac4aec4e60ec69b1fe38be2b5b8df759e8be4610f9b3fa045ee813a09621a287c7248d2e6cc58fbde92ebf0118bd47dad967ab3098689884fa9d1d6025702e2e29241ee4777ea9c081a456243e281d08fd6b49727f175d76bd1158088521c3861a36a74d1ee151fa23e7f705d7c1c8b40442c33aadc29853760e9a916a9fc5eed9b578c1648d75a2a104779607", "52", 1, 1577874246, 1537743641, "bec62a88f29475957f6c1ae2f705e36791d3849b7023d69d70995c23a0d06d05"], + ["2227fc2d02c178e956b03bdec4e0204d2380c5c221a83420cac9a9f54aeb20fe2798d5125e00000000016ab3d37bf80515e8aa35586e22d2c679a7954d35db190f7cedba83a31e0114e2432baa503801000000086563535363516a63973d52dc016910c90500000000016aa0a9260102f94d0105000000000000000000000000840f0f64edfcd0776d542034e0bcc80787b92126ac8e338426afcdedefa28548adf1b473d557c8101918cd32c020e2cbac4be9fb2bd0c6d72710f78b85d8c398f8ce01ea5b690d1dafd28cc601d47a276243f813a9b4e4ab7177007babb1e5ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f286978ea018fbdedc826beb6238708d00d5f09133c22bafcf784b15b5c8b0917fa0a4f6f4690bdd9a868d51efe0f989c8dfcfd5e91c9d207bbf221b99847e1183724ab8fb3fafa78287ed4bcc7581bf3f81a5edd96e057f48a0fa0d729460739b1f0988c67193e64c7172c7c2b6fb942dfa945e461107f917d481f6aaea08b0300a74aab9f68074e49cb5800b02185fd9eb3ce8e8fdae4cbdf5875a5675dbd6c030cd677fb670720df00392995f79e3e55dffa77bfc18ceb19f037a9a3de1757fc0a00f673ee98810020bd76dbf562f8593ee4d284e84854ba97c8f3e152178f26acc9adc6b2dfedb1578ca841f888f5dc956ebcb3f24721276a5955364be407c406020b356611db0170d270d2d5f1e6096e7dadadffaf7dd22016ee2d0a0b9609a7b7021c111ba467c03bae07ffc085a9f0ec05302755238f92818255d930a54a1a1d98032a1f36e4c61274b9d2d864fa4e63c045f61ea044c76a7236645eebfcb9dee2830313401c47749d07ea26ebd527e30e824e845d8725711dd921630d108bcb847bb503284b94e2d0d6bf1193abe45a7de8f7e956cece8dfc61e7b099006e4172397e300a5f12189007112e6fbf9b9cbb2a520bbd13619bd45008837fd23918be2c0ba5dd7211c22c229cdc9a8a659a0769f6207365d1ef09ff14ae1c07860cbaa0d75ac39bf6d38358981cb03126c888a60e27ff558495d86ae6e2cf3c5b5cbc33ae7fd2adf5b73e46b6892c4dba876f87170c52d5e4580db6d8aec93e21ae74a3e3ba564bbe679036f9f6c64de224c091d028a0764341f25d757285d64c43e2dedbdd1a74790b34c6f4aa9107b0788dc7a348ffbbabfb3a2b55e386319bef80c71616566618fc308b89f06f82e84259abf8e6a6176e56ddc93f0fdd3b118ad8e0be5520896dc7d93ff4db9a2d7e52e2002578f978c0fa375b90f1fd5dfdacba1cecef114997af4522465cea57d9ae8290a16e688a8d561de27c97989c51426e322d3641cdb23aab1ad467b4a7d22a0307f8e927d102107f1f6e1957137d2e8e87b3bd1d1a777641998d1532da03b24997ba0c1c2f209eecc1e2c6f8dbbf68c9ecd5e79cc612d7d66fc265d8b9ce769744742183cb032d0dff972ba0fa25a981a843468003160102ddeaa047a61b5dfc6e1495600a9410e303e1601b9138c1941128df11a889aed06e9bfc85ca43c7b31cab1b38d4d6fb90db33f8edd42aac2fa79d0205468e3efbc013ff91ffb7ab7008eec62c0fedb5ed0fcf752e528ec955be7e06ebead1cc70ead66128e4c599d522e61675a4c8155be9bb64607c402164d0a7d42ce626e193ca91227ea55243c4cedbabab672cf9aff5559701be6a76c9e860f9cae652f2f0028f8116ee3ff208d62cd9ef46aab5b63fcaee098ad128fd7892302ef4018f10e13a02e77c5e904858169f81330585601c058e96135aff640d71d07c330e69b69057c8d10d891e5aadb58646f4b81f35f4fd7ede1881fbc2f4c1a6b6f364d960468ae9eb1f3d45d98be415c77573d361837096f7585d1458bc3e1add785d9e3641aaccf3c33fb56eee1ead466cb68ac82ee1419d93476c2d682a13b6a6d6126476ad7867cac0acf4a10a0b0b2f64af3430566c9831c3e1f8ea6851de42be03a466650369f23839da2417aa1f048e706dca8644903986ad90e6f9ef51f508e5593936b68ca013b22ee6f9fdfc1f9f8faea7c3cac05105f813dcea1ce9a7c8beea6ca2971ec444377919a3878905e6f770504265c01f235ed831a42b044bd640925f6d35fa40523510a49d1156aac9c1d61de76b683579afb20df8f9c715b379382867989d55434b23c81edce5a995d1457fb0aa6287a340f6ad8657d67656d7f8c33c076833379f9d21543d99d4b2f4ca5045670c17374e69859d282e838b37bcf069657fed1d67bde7c090a2e407a6aff2e7bb284cc8abe6bc5fb621877b8bf0c233654b58730c08642f7ac2774a1fdb76385ca04a350cffbe2580e6b6a2118ca31842298f3463f83c5f26235d7fb4d739549c782540bd45b7b7dcfb7f466b48f545887f05e5f5d0ef8b8fa377bbc22afa84d58d28dab83c5bf1b76fd96dbb439d161da0a7c2b2e9fc8b35af7b339d82dd8d063b9fe3ec734bc4b68100d98a33e2fe4fa0dcc028d54b53e1d227031dfc97d9e20f593a101215dc39230cc82823be0e27fc19ed2b052037f42f953e3f21bc6b663221534439a70b7437bf3ce11cb55f330f341fc763534deeaed7da74ff978b9784e64e1c6eaf580e0b3eb91eda1d26792d9edea2d903fc933a1e0000000000000000c9405a01000000001521b03ebb6c146973a5676ccbf82d1f550bb079ae711b8f9eb89651e35130e4c59525e53a317fe997e6b1f18cae2819fb61a17af0beaf0b756c8cd4ae164199d3069a40390d132fe1477e1edfd198436b2065fb6a9026ee3bf1d8a48681317a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fcc2702d45a0a097ccfc5301b5140e322841a9f767bd7abd5e09778f0fd48fcd7f906f69ec2e6822f8dfc15e98d99b4ea94ce374e03a2016825239ac0fdda89fa267b8a45e530ba93a0022d1671e158133b3bd6f97bc319f8ece2af30d7095343d3059866183ec09f4c8aafd1d57fcde734760ba416d83766ce08c497401f2fe0313638b9feab0989890f9185f5d64a8fc8c0140c53bb34b19c2460d4d5c7435b2022afa31e354da02bf95dc99afe912d9db34f9645b88d68ff1b79e6f24450d170c0a0627888d4780ee8080c2529b2ad59c637c701127a8a54100931d57192ff7883506fefd919643ec3350348cfdf8e2dd6d7e31b0a94f701879915778792b5f179d031134409321b4e4bfcf7fe80eb3df6b0bdc1db5ce08c1505b09ff83e531c29108022d86657adf29bd3cb48acae04f3e9b8a2f60a022eaa79465c582b3d73812dfe8022f0d5454baed5908ab70dc65030ed6790aa7e6709799cf69e43682163b13aeb803254724fac204589db273e321d82eb213e8481e97a5ab9aeecd610156584989930227c904d01027056416d38cde4a4df17a2c02052ac06eee5502bc1f3cd4c133051cbd73e6c56de8f653b9b68ae77f53f999f1ec9c1f4b64589c67c104af55b756a8438368f6a90d5d351c953f1a2fb016d4d610b88845cf107fb35f1490000ca719c4070fb1aed8da133790e06a036406ab157a3525b7f6a6e2235a630d5ea4b0517db4e71a6f031478c8dad5ee597fa48149ebf7c2bdfc97f959e7541fe70c207ca521b97aecc2c85d1e4f4d789d5dd9f843934091ee3284e4aa1f59b9c1301ee188493b09f05f5bb6b9ea87ee61d051df15e8b7585a294de5ff545c7ca274fd55c0438ad2d58ddc503dc5ee54e583112183a49f3be925a9670c2de00acfbce2f302ec6178bb023cad287902372561bb66b64c54e372328eda568c604698457fda2604cdd9c47de811d790fffd159492d45955da30bfab21b820e52ebc70c19873cd68510b8f669ec7c06b910b2484be3a0614c995c748eff27bb02c0372150451c276402a992cca6b40d9779a5bfdbecf34285e58dae0346fd8fcf0d0ea874d24ca7015ea65fa6c0be59a32f727ac9421dcf8fa1f187dc466d2b80f0b7eb2e9a84866f90b04a2f988d2f2b4bcceca961776b36f1121c82d75a473ed3eea671b2efd1b397d9c3b4ad6f1e0da7859a6c63971ef3cb0987e3c541d6b7e966ad929e93351916213cc479b6d64094753072a24ecac6c0c4ed5513faad9c79579b83b31718db5690abe39f183ce1e86928edb1a14371edf76c0a85de52c3da84f884335555d1761dd3c09e65e5c1193cb3d10d2bdd0e6fa46de4cc7828b145181f129b328cd48d9a98574d698b329dfba59defb75837d8f7e38ace00493c4659ae20e4fc2aea24993389ecb5db2b345e546213cbf21106402bf805a7f808b773fbc396871998f5f8193de82723394243d39154460ae353e3fc982193c94073f61885868494fd6e3efb07437c1b6d02df9fe63dbc059d9315485391a95e03cbca23c06547cd2418b815173c7bac08bde5f2f53c33e378e8fe21dbcaaa004b4747d73a1a8bf39f8958b47958c7d7b22ff4a67b84a4a6e664bf946d70eb95fd28191fc6ede232ae62f88e4082f7b0725ea77ffa946204d98a6310da7c9430df3c61dff6ac9feb399f39f45a7cca9b4412586a424fb5413a0dfc9c2199c8809fd1b4ef87b1dffcfb60982ff313212344505382fbfb6df37f1ed0c3a45e758a582e4016b0d6e8dbcfa38ace34a2d17c9f55708cc0c8f2b4cddc8d9dcf8b563a59770e5179d2270dd74445f9cf12cbf11b5c23603e697901fc0b04c35294a10b40e92e7b1a36860687c4b11b57d2411d852cb38e4f947efa5b2d8e66848fa278aaa8c5ed07732f629178ec27c12076e34161e168055e901cc6e014a428eae2567d8c71f39c75b3d243a4bdfa746b6d1b65012b287787cd0b3ae51d6b32318037c750e68ca02aaefd086d3b47090caa1edc524a51b0a9302cd8886b51d4f106f62a7e068ab2f4d968e4c4f2b4cfeb93281592716e5eeba96c1ae2fde2f808537d2c90058d1210e1330bed2666bab59e7b73ff17457bc5a513f31b37539e48eaa5036896212d7493ef246f39fee2e1778dba379515eb7f7692bc92b6da83c338e6eff5e2fa59a7f178eeeb5855134f5b30660d4165505ed7929a55104f98751b2267cd91166aa6bac235fe090b990c9d18be707e146195a0608b12bbf15ec82a27c221a4182c9f6e8a9cc504c52b312a7ba970312c95aa01ccc5ae8f73228163809bafa1233a91ae1c8eaa22f737dfb1822edd74d1f4380bd1bfbac13f22dde4ebae0d43e0699d3f3a6846f6259b119834898680449fb9f27ca1863d33b7eaf6c076f59cb99ca7955203b06ac5c082b8f4c59fd7cf039a303", "65006500ac6a6a6563", 0, 1360803834, 0, "3063fe6d649f65d2f6cd86dc8d9645ee48c7ae6f7dc2c824dda61845eec9942d"], + ["030000807082c403019309719ad6c6b605421c2247cc0c320ba7e3bfbf66849166f76a82a0f55f436c0100000009636a535353516a5153ffffffff039e018e0200000000036a52515fb78501000000000653655363636a97a9c901000000000463656552000000000000000003d6dfca03000000000000000000000000b2dafd43d253c1c3a2db68a5e841f1063d64c82aa1974e3eb339eef22221e0785916b7d3e6262d84ed15466f9ad0ce2c19cad916a212fa4f0daf4b168798fd983ad511deee4f1d0d2eec66b2410255782914ce2d6ca50034022a05861dded65900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bcb7d9973ded9bcef84711eb2034fd5c27b02848a99fe6cbad7598b1f8a31302bad7aff242c56733c0245c22bcc59db79831dd3131e9a457b02e8b291330710894c16a2dc228608ec1cadf05616b4e013cd01faa621efbc5a3456d687b5e6e8c1b115c02e83d325b2e13fe55411642020b7b9c4060851aa7964bb16a8f9130370219d2c7907fbc2711c0ee769f9c9c5b2b4d796bb01239b5e6cbef1606755eed1003237e9dfc7801a12f46f7b012f8c91d3f4c4e5240609643cb01e41896bc2b9cf50b048e3806662a4ca68ad3cde81b1e4f0618f181c5ee233fa54621e67d826913eb3fe044abb35ed1efb8f9e4204ca20f5b0169334a4e74ca2033e2c6b3a6418a04020d34db209921221d80a4dd063f375f13c27232b31b35dec94991c43582a585b40324b75b4485f9a198bbede2f0b4ea3b1279abbab62b5bf417452c031219d127c502295ebcb3cf59b0603b58cdda0bcb0c01479656c4709ad68a511a5dcbe57f2c00031d33d950c45f8f56fad09f4100c66d5d6d63d99ec27b1cdfab7c76dcd44f799a03003261689d9c51d7d9101e7ce7cdb5684f12a07d7e45334378030fdc445edf68979c824905601016cc05325b6bc9669acefdc0d856dcc5979a0dc2761d08562157b148cc9f7fb9a01e87d7e853490f732756de97f021537713ae43db24e0d6c59494e761b507668ec7362df04088f6ba83ee618cacdc6754fe947404009ceda4688db88454dd10784b6715910daf2b26ec96fe4cba7f424f0361480e67a1a9bdbc93d201f9db510fc5ab78ca5be3397d00adfa4604fac5ef24a24208599d7c1ab5a3ae9bdafb4740521cc0e8cb460586441cfd933380a29e0e5447f134676a09f17b35bb89ba9c9309638c8a388cd5c12f9bd91ed570aa14b0e5429b05418f8677c58eeae83119b123e477287261b84737e3b4b36f28716e85ecd65bd55199b743b1b7c0c6906236b6776a69f4570e08143a7ef858876cbdfbcffc8d1b515bbcc9190e537bc8054c3d060eaa21b93f3b2f942f923841234656df4dc190725fb41029dc63f556ebe43059bcbdfa76a69df2cb00c432de6b8ec8cedbfa9d3d56b1a16e17b7c6f3657f5f19557baed0ac60040fcaf573d20dcae6be77b931a153122ce464e8c6e1ca9ba847429e3623c2e5f527d5077b8b05a9db8589c528b72ca06c0d500a8d48c7db939e7a1310791a8e79a4fa4bbdbcb774f01591ab81ff3554c7327aa731317139f7127f64610e499a9eddf0ff013f5b99879bb9f793b78271269f68c22eb6ecaf4093cd3b25b158de4a0bb60f078eab38284a7650f518ce5758803fca512f27794d0c49d8fe3a3442c7511838d053a207bfc9e218a379bad54903b52cdf79fb1f5244f1e09c708e7371ad31496bf14906865543078cbc0d6277d88745f27e213767513651f45c944f2ed236d49248389a91892e6d769b748edb7630af63450c910201faa7755d94bbcca9d5c4c8e9253c387f46d5fefb3a0beefb9bb43bb2e355217c6e0485964aa3e387756c94f4412daf6a7ec1865c27a312d9ddb5bf0d0183cf281c7f84b5bb92ff67782e53784d28015be65a7dfd8c7a3f99e723a759cfe3d51a0462509f0b29a3b69400786da222639db835faa967a06b333e06e700d8c802784b7824d0255f26f961e310ba866f978534f2bde7529b460d5e9ced6896e9456ed3a45e2ad0341aa8763ff7358a69d5213fe7bb325fd69534340848fdb8a1eb42167a695d3bba859751a4b07d0ce2fcc40ffbd0dcc79e95dca05215563844fad89817a28bdcb0185e80e19040d981536aa6906d10e09995f8dec8e6404fd0655d4e4bc9d5d0113108ffa9fb9874700eb37ecfbb5ad0b49b7c51534e94c9937b272fc085be620a74962dd7d2ea48caed73235b730440ecca60ffd18de4f6c98815736cf3b37142891983c7c2353beafd5f0eaf9a6f7778ad751d8fdcbca2b5c0b77e57cfc4c6bc66c12fd266d4a6b5a4de29715c8ab5673b602ae0db2af2e35a3d72ad6173c3c2a887a651ca7dfebb1e99ebceb6c10ae722f81d1c9b6dfa7af917dbd32fb7922fb8736f05f46a3c6d0a3061dbda41d444a540820f15d796849fdf05850c9003014d30feabdc18c72b09ccd1e0074afb6c71549b524d8b0d0b84ea818136e5753b80e5d45ce730e9e5e733895a56cd37c828913fb1d720e8cf0c88fd801d0a707cd11ea45777f6b68a756e9f3ae93c80adb6558eab0333c3899f08ac47531035aa35b33adddff6f5ccf706647fd292d14f108c9eeeb6f6dc8ec3b661c02a9bc81910d529a3ee0000000000000000000000000003c2ebe99f56a80a10aec0f96ed46c2262fd8b1d4291bbf15aceb8fa954e44b466e56f3595c302383c61178fb04c210d41529acc40a33d4bb95134033f2034f341b727b0fdbcc45a3d5784cce5e226e682a1a49a35c5f39ddd6e18edb173b934000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001554ffc6e5373e366b3db226c31ee638b13a53c633358ab8aa9a7d79ceb2e915a7701e79fd265189f6c5f8e4fab8f023ba7fc00dc4e9f6bbc061394245f201edf3d9eafce62ae87d3aafe3a60acded315762b17ddf5e51cc1bf2bb1f4e3e6f3084bf8f3fd3eb49e7b1f5c538a686103b72673076e82eecb089b1461752bce345032017089d2dd5e0182d5c269467f8dbe6828a40d5fd659aa20e0028bb8e8d26a602266f693b9fb1de0d1cefbdf07d32ff4db52e163dc64cffab5a44a7482a3ee0630a05f90398d8ae66fef014af24d30a30931072cb5b0546b62b6ed9881bbb61312f8fe11d2f28a85ab30be140750ca5f981e91c88a23680b3b2547bfd67938d5b27021a6646ee7a3329c0ff5f1737e49a29fa7e663caf893bcdad174f3de0a756f0a80206c9de90537e4ce3deb678c652f49892e277adf22e4cc9ce85f62f6112caea4c030792de54e4967052f056dc2c4f0265e8ad17515db764fbf176a5645c7d33dc4703222b9d6bb2b6f1db432d148bda00654cfa23caae31fc649bd70ffb1bb9fa8b5c031fc0512719d06b0c07d66dcc4bd0f9e5c5403c81531b188e7c154bf1f527c2d3127e0da6b7b3ed5ad25c7f414c5b306df67b180af6ba75dcaa51511acdf484f08659593522a531a473041925a7dc14901c498286fb81977638a5e0e7dc5769b897a23e5e3e115fd5f8d2b74654e71b7a52732ee7e690de212b214526b4d01c08434265d6597bd519f170f8c899c89dbe63a0e2c36589f871801aac477e6373d818722e1ee5a546eac98a03ea6ad5144e84e4fab502db0735d44964b31d6d17bdddbfb1abd6059e81e33adbc4d5701a37a374e37de1de315de22631982a6fc23175401381fb5ab730c4e2e3b40ac85602f1f241b04a9a451ad5a4c0e70778dc3332929e6199bef5be3e56512d463432cb5d03f9f609c99fc067dd8b637279252fee84c39e2acc160b0a1f9422320f60650eb7d0d22ec0ff7b7447a61a421c50a55d6196e6519234342f0b7e277408f34156e7fcde52c89a84fe83c46a974d3dcc65ffd87fd87360bb16c09c30476a7ca992db2f57d3fc460f47d9f5c747f557fad224329ca185900c9f2d713c46fe5b08b81b0a0efe0827bfc125f6afb90027f7f31bf1c619259d2b6ad03c4ca6dad8a9a94580f12c0b7130e7a5fa517d00b7720493ccfdc297a5519a773195c6e1e131af3e8a711a9cbe6916222e9cf770d19f2edac979ba9fe57c9d5dac51ce76fe3ae7a25a70dbf06b2fa3d1d2c2eab6cfa52cfca64b0c332e83b16bde852254e0ee9da269030dd660aef3869cd6622f1eb323e6a1264accd575b3bab06dd48499bca5f302f5f4923497d00ef8cb4b9948e31f2932908443610fa17187fff32b243546ed13be9285cc35d1733e387d77c7c14b4626fb607942b09d81d04728dbd52ec6b740ff1ae5e358724bd97a3a488bb365324382ac4314b8a7548c3eb1e374a32b51687b47927677d97bf2b9e6bcc4331ecfdb785476750992e7e61dd06c13e771455a5fd72a7f773e256a86fba5196e74be6b37e2be17b831cc763f977215307d6cb06026ffa4aeb24a5146b914454a8983631f781bba94b0146d596e08c7bd10d1d099d48031cf699e8c41a840b8ac730d84c0032789faac44b4ff2beedf11271f6102cb2fc708cb336f499c8105215e4850f16c849c08cd174d0321c5ffb8a97abed2488ce8b3f9fb33db97bcb02256507161f5910098aadb08a5c773aa5fda969cc59ba7a65f4f979b7d3c51aa9ac8b382b663f66ed9555cfaf06633bfb3f405e95471250b4feaec73fdb1b19551e8961575cb29e595f46c66482a9bb67d1c95591211e55da3be6e006bb54a85f7dc23427338524530438af0a8b62e1b1955bd8d82798996e30872ce5b69bb00e5826c33384cc743ed9c61becf4122af144f36c587d730cb7908229c08284e22128ba768660fb37b2289c9b0cd5611d85fe4868f8fadc7a07a4812fd6b667ee7a4fc3e892bb9a063e28c0db39369a16cf87a97f5b5c87d581477eea5651ac347513baf239fb36197d57138856e29bea33e6ddcf7bab6a5f81b2ca4ea0c0ec68abb42f958826416f75aee695610e063642e0e81f2d63615b0f548e3e616dc67fed83cbb5d26aa0041f282a28b25cc98f6f27b0a2055d831e606e7ad040ddc0b9eb931786604e3d460b5d804f0ad2a22fa12a390ff69a67d6dbf94d7e0dd51442ddc7f2ad35d3a982981a7d996df80e7be885142a30f7aebc8730026d5df1126fa3142f14494d52d12f293915911d16712889acf0b3d4a05000000000000000000000000e14c8bc5ec9d7178696b28ff335ee0f9cda583946288c39c4e3c823ae01cc3494547132abaa62a88107e24313c543091fd1e3b9b4655511beacbd79e6c71ad1d78dc2fedd70df84b28505f51241bab092ccbcfca16461be025e1f74e8c70d6f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf23d4d396c2740205b97eaec621bb4d7aa7ff49ffd17c8e4e2ef177e8d7e6ba92eb6341d21eddfc60ea3090b2305b588facca2f1e59d7d25e59c249bccf19c52cffb38b5b3de3b0d6ab02ec8a67f06e84bbf2b788322101e29d35a0890ce848031d9d6fd40e22d0acc091f1cb7b6973bcbd2edc15b1283b66b3cd5ab1ca73950310c9a95bf2e1e4910a6992fcfc18df4f09c966feabc2d133f80311beb0ecf2a9022206e780fa2f24e7e11a7115bed82d9d0d572bbf03cbf2fa850ce0d78a26309e0a04717df6ea4363f4211dc45662b911ab67b23caf5071c74f75bee58d468177099fd25458fc8ace48b86c13334ea905c4eab436dae839ea70d9e6107c0fa5369803075d6e70da62cf055618b3492b9165852ecf16c735328d2f1844246b9c52d45d0320371e081d60a5d66ccad47004e90f3905c073d4f3e2c51421751c1047344650031688fff7292336fa48cbd8ac0a5c0603836b01bb82ee65bc9e4423030aee9141030191de17ede6770a5c75e3cf8f354e18170a045c4de2b3ccb1f9dedc4ee63268032c940ca139b47f7c6eeeb96958514ffdd2a1dbd1018ce3952009069fa27ac3db9f7ee5544cc4b33f3df48d37f7c63d3bf2ad8f286d3d042d9e3a6513e1dd70d585c1daf9261dac7956fa461cf3873a791a2263c4ef904f34626f703eb83c5bccee3c63e12ee806b92e211bc628a3a6ed3485fa9fc24ef370cfee602f11113cfc79b802dd838ee9c2d3aaa85177eb278841f4307e4e642fb96688b281af7910ec7d23e9ae3de45587d60368dca7782b971b54fbfd55ec33818ae5f51affada54b9b510836d1306f379f0a3074941b500069160915e6cd526b35b106938d99bcab8a9f39724a4ef5976f8055ab4f1e74dea204e8d9f9c132b2026aab5be7649cac2d9800fc1f22f5235ae46fbdfc8fef8d9169937b012ebf40f39054dbb3a820c7077adcc707800f7a8cdefbf631b365f9710e502a76c2a241cbbdfd01f9120b45631508a89d1daf97c8d29d8f0f6971926dd286d64ee791b913ad4d1777e5663aeb78330014ebb2e01576d025d91ad250279389a49b49fc2e8630bb64b11ee081cd42dfd60cf424c54a2f27eeb488074e006412c3e6329125339f1e66cb7ee28ad9ae99abd336999ac9ebddeb8c145486b459a9767c6c1773da9437590de95021e48864fb52cf0f741b20ddf76cfd7ebec15a083839a540328664ffc42dfb69f56bc9d33e6015421a5480cb8045ad8a571c294a7e3c194d0348853b51f823673b08b217b332ed8019bc4e0b0eb8c0b7ecb9575b97f5da0530526a830f111dcec5b1c59f0aca3cc02f50337d4f794419c1eb3ed1af32ce7400395a9904e867b0424e773c0731ea4af1af01b8c9af7e83454ab8cb1a8ffde5cbee858092ddfb25a95788cfb8f0fc9d8527fc09018c136eba346a78ebc125f94b0d4861c002286a6f03d9c8697103219f18fcbf7f8ca1115189cb1fdad482de79209d215e41efe076f2cd030a5a03a137f214d806024a21189cb51137e3a20777926b6067be21efca0cae62162336a5ce8f06cccd99ddc649faff0f31bb6f4381a209a3e21e83c25291678e25b5714fd49bdaf13389dd9fdf2596ba036374b58a04ea14264754703c352d4cc7a3f5ddafbb85035a8904c244ab54ca77ca66e60b0c7e0bd244711b784b8ee4c09061f5405cee3154813d9a03ed63976057f235f8da3597cf1c745daaf04e2db6f62e9b4bd7d404f36b0549d717055934e70a3c822e71da516bdcae0a00aa3b4aa7fed03ad0b231d2414a46d5383b44d9336646bf14aed1f7b0452e6edcbd2e814fb64271161616d03c79332a0cc7b767a7807474e0619487b5b4371f7f6974b6fb7f324834e440583c627edde8a1da8fb31add952235957eae4913e696a82982a7cea4ce5534f232f14904cf526850dcf73c2a6197acd44bf150d37b12aa71d9049adbf8e0ba19feb32da0f52aa28472301054654477aba6bcc7dba9f7876120f59538c91c83b35a71fd751281e784a55861cfa8afbd268a1616d70c8e8c19fb6a54a9d3e0f9531dac2f865168d1759a98affa6889e5449c1d375f6ba2b6da4df41a99d1369f7e1da85c6531f80cdfeb6a214f93fece5029478c07ebe88c63ee279d8ea9a3ab348217648c10bf172aaf91770f653f74e3d0933c4a43f72e762e27c8d5b6361c4307f3646bc8533d1b0992b43aafb57a106b0d33a628aa4e996a2b5adc258117155b312e221b636a42376965bf21c740a8ddfa247f4d4dd748e517e7f4ffa9cb9c54d240c02e7e2e8eb162d7e621c6bea69c87360ff798494cc78982e29de2452c76b12599ed2e33e4206cad3b7cceb2da695f1c4ad4a6e0da6698a3ffde00dcffeb83a6ee77d801d49c4bb72fa9f5566a93a0df393132907adad0287e8a1419cfc79046a27dd204", "", 0, 1077927338, 0, "c7c2e8ae96fbf626ff7d3e1eb069d354a799ccd5aeeae11c409ea4c3f6c5eb2a"], + ["030000807082c40304572788a2f520a74b38cc82b1c27c7e52befe3b0c59719488f5d2af46f0c456ab01000000046a515265819fc518db47f7a091591243bdcd9e01785aa78b6fccd53edeeb440eeec886c682267c6c010000000551ac516a53ffffffff9a1c255d10b6f89a453beb1453da3668ed60eaf1fa54230dbba0d4e75be5d91c030000000253acffffffffcb44b9ad92816d6c238523bad785ed7404f77e1c49c3d0a6dc697e96632fd23e00000000002e0843ff04cface004000000000029a473050000000006ac6a5165ac0037cfd305000000000400006a633de13904000000000265630000000000000000039f0335040000000000000000000000002bf570ec4b36e6b5613f38367d7c6e8dbc97f19eafdbaf2dd4eb29a13e76a5ed6b96a31a0b619b7db278c22b82258567f5f5079161e2444102e403b840cce9aa778a2d3a7842576bcd100222f1f9d5cb5dc7fcbad4b8b7c8d9cba6b27fc67ae60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022bfd0ea3953f35140853d6414fca45943c2b6e5df041b85c05c4c9de43697c806834b66beb44d263bec0cadbf611ff2eb5e1d493452fda8e7f4cd4d6534d3be542addbe57734e47d58764eb0a4d17d64fc7515397710d92895cd08ff7ee47cdd25207af4bac9d96a37aea2fafe5666b25c479d3379d7aba33998579ae163beb020be8185af77a0059dbde6f5157fd234f686382fad93e4c67f35d57eedc5ba4bc032c47ed96b11f04fed70ecbe58b2aec3a6b1f3afbd066c959ead563ddb1b0dc040b06fd25a2186e69f21c58f9dbfc7f948bbf81dec968e89079e0fd3ddc6c8445dd2c9a6a0bcf76a53d2686a8dcc82b6f60f61f69a9fa6eddbdd67cd1da5782063d02202dfdd56f77da829ef55661d8e9e75d47bc32f343d07d600d60dfa8a835046e0327787124706238cc1630fdfc80847a7fa20b48634496891d36faa96f3cf1a4990316921e2930daf98e3996ae3ed54ab43e6b2662159ca7d4a84373b3b1adf1e6c5030b4087dce8b3f6dbaaa055db33c84c3b8fd66dd406cf2b107b866235497154720222c78945679081ff625bd9612da17b9e969db635efbcb22d9df1d66135846b4ec0c68399f5c0012f7a73b667b5047d0f8335cd34b15483533408f86bfd2f96830d4c7b8ab3596d98fe54b8a7001840309fb5858a1752e6379e6068ee222160c0e0892aa27efdd91b42685a23601d157b2d1c97b2aedb52a5c05cec99328873bd3a06618f98dab0d40fc4ed61413335f2f54e0f737fe56c53cd13d04c89288ca86d2491a5aba0210d1dd06058b26bf50f08918850e6017427cb2bc208397c0b0c24242b528e5654e4da7db285edd647a439cb9fb497da6ad4506a8301783ce0d5655859127fc887b25561e011c589e9ad94f3d9b09e5eb8f6a4857be699b6b14601a11eef7f4517656487dd159f56d9daec07c607bde62dd2c5c1b9375318c5b0fd5eeea48bc612d4c911b3d9b4f199929cad37db60149b00bca391ecb3ef5bc36063673d70ce840be1b73b69b73ab39cba736dbfad5173f14d70842b64e3a58bd27ed91413a21e7deae89f02c4cd18bd44415d2131f6062a95a7de8700d7ff32a28b8da0db54ff6246874c393b570858a9b76e7630fb78d305ef20019b995e206f5493a9f57acccedad9ac85a054159fd50f685fc26b2f424278d3ac480cce77945f1d3ec4f971906a3c55b9961cf7e0b616b1a2f9aa3bbf1e348478f6e5360711b657ec78f202824ff5b592769d0485641672fbf0c14271f425da25a8e5c03c2003683f68a022c99530f11935996c26cf30dea2713fc824bb66d146b4d99bd8f8fb21006ae30c78443c158bf95d207ea5bb2f0a5a85911e0c97c97a0287cf68a9e45a84565b6f621e69f4866894956d4b946f66358833b0123d8eee9f0e39796ca16538184f3f9ee5055fc0e58467e8d0ebf75b674c9d9ba2ea634cb0ec41fa359bba7df98b465c704f79c1b27a5bdd5a5ec17103665c9d36c1ff4295053c6fb7eac3442275dd2353d9e426a20739c1df076eaf07d28ffd76d370f31334ba947f0e664addce2d4534386538d64d0123c884bb6a38a573572ee8081e139a9f50020bcb3d49d9159fee07832a51a6fddbdf60c7c670a48d4c40d1e330eee1c5c12d505c8208fe35e7cfe148a9af90bb620c5c42a886fd025581a0c8fd1fac68557d60893ee103b7c60e1503047d337e3054a2fb5b7dcec33668e912d190ddc0a03ecbdd176c58db135c83beca83bb61da47cf8ff1cfd5fc56c39cb74c7f3eb22b435e83edd4fd7930ba0810f3b62d6dd525cf803ce07a8e7e192d1530cea4fd6d212e3db9ff9b9ff5032baf0c7f59aadd030296dc903f6d92a6b44d29d03ea58704b95a38ffa679f380f2d384ab2b2f3f3e3558ec5f975d7f421e9a63e01be1ffc023fd319e6d0464c66fbc2520e37474f4c6e9354d2cba35f96c169eaf78ea35eb1c486377c58de7a70919962e0807815f5b26a987c41ea0759af277200de1e374ede8245b6aab2e3819d72918eb54c2c188d6fdf0a39aa80f2a530510bff0fd28a51a4191b8b37d63e6b936f118712c02db471fb5ee1abbd437bfb2b96982be0de1e484c3a41eabd8566b7f0140d12427ff1f8a7ad1acd209632a7c060c392175ebc1fa3261380eab761a2db8988370d9db5ddf732a8f57da1a3d304f32f536b2d6c1d2f192a197639e5d2a5f16de45b917a29d7607581a8c8fb6cb9dda5ef3914e62c9ef6c4a4301f6a8948c21c119004a599bf95f522ebbd272981b1d5ee4c1b08f36de18b08fde274031dc8f04636a0db3eb2000000000000000000000000000af5c9a54e2ca5e6da4c87d23e4f4e7c143baa03256c37a8187bbe6fb8c5a4ed788afe92c8ab796f7fc0fcbe4403471a5cdfbb2de47e26223acc1997f14241a48056e271319b9c5d5131881548304a54fe198d9d6db156b612427900784feed5b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4bb226cfe18b59ad7c03ef24db03651dfc801787bfbfc9ba0d8827993fe3dff1c0d8c8b402790c60d677951ce54edec68b74db3b387eba58950a4c145a40d71e6835a8d8ebf0ee55ea060f79ecfe4e82db6b7a80f9a9b219998a368b143a4591099be96beb7408a533bb3bffc629fc98ea5e12c661f5af0f11a6b90c66b5caf031b655ad9d4720993aa5231f784dc9321ed2bd21c5e42fffbe43a0265db6f779b0312ed7f49bb096a66f11c71d1c017d24b7d8f2ee2dd973481f2f7e3cbd48b802b0b0328a1654f9ddb60f11bacb326af331420561820f19b79bfd65fd75a2fd63de6078c97c14165c1c7a9935901be7016698b3f69049807268542fbb8c1a6c3e67b02264603da04e577b287d9641bc78afe9e5f6055b32b1e9514f9e36cdc36b6549502107b64cf68916e90f36184a955bf5909521998e162e5fe9ae2ba5fdc3e2fed2c032749fcd7e9f2c9e5f5de5a4e3b63b8bda507c137340b83db88c6d521ead293bc031947dfd6b466d4f2a6249258af66f0c3ede2bace190adba5194ca386fc37104e030ef65eac777171b343d8185e22e47256ff7a04362539e8fca25e92d289134b78d6d7e616682423b8d25ceef984301a8e7e113cd3e6c728f84a111817e5e87d27c734cbc00319f9e1381c3d1ad9d5b83c446d0c09a1b298692784432c520aac1c79cdda2dbdc546ba0f6338068e02ddc0331a7279ce92e003ff0503e77ebb4dd43742f41ff6381c7fd330f64c8ec68cb806b1783acc82d8d0bae00693f22d80addeeb2c71066c870266e685b506cb72f4073df67150e8e40ff68f5399e179d46b21ae31dc038a845fbc2c489164b3d136b7e80df977a1e08b04ad218b01a4b2a29fcd6ed381e9b7e31b9c8faf80cf9945179992110c21db00ac4af1694bce231bebde6daa73d610ffe5f7043ddd48e9659d07246456c2ee79e7da48f44f0d157b34a4e4d0839c76e8c39945dd16d419aecefec873b518583acbb76886f93fcc52d744b393401de2dd7de1327633bc083250827915d7a1f9a092e89444ca8f59da86b7bdde41b3cd793e5632fd98f7c5e5754afd5e728d52698c5e15254cb01bd3521fe004cbbeae17b6b710a5f0885a3b3423b5729b15ca99cdf46ac10637f3f555732be0c2ab11ca4ccb9ef9eb87c200f509c6ad7637fd9d9f07efb374a04f39a582fdf36db3c9fa72f9c52087eb1fec21fe358ae6cf8a494407fe999543d50695558ee56a2cd85bfe739a938119d68d4debb04ec1faa245334f4d2d103b17f8e9a51620f68fe8400562fec0c3d23221b776bd822a911a7e5fabb91988b79509eb625f287f559432492baa83d39f6cddb6632c5b528d1338f21a23e5d99726d7b2d081a31bba04dbce3af4ed6a3217ee10e1aff6e853a431dbcc242815b88fca9f425eaf5e22bf59a51c34e9d85f31659171d0753abca7c17f81a0f8eb00b626d816e4cb6a0a858afd6d7b00f43c550b9bba7ac80de1aff43268babc6168076b9947ab019468f7bd9eda95c3e628328b1a6e185effcee88b052ea8818946dedda6df6713c5b150d04ff2d216261c1865c873d36b6f05470af68f0c3826f9e5e041cb03c61488e8d73101afa40d8be20840423f09c67316b393b9c071c93b3eb8ae9e8bb228db1a90c15481f03d2c26524324a714b82d2c2e0035295ec713fa5d3a27854f3fa0131a4db3f181ec72dc868411b1aa2e26740c424fb902e7f39def8ea85911f4cfdf70826aee1e7a6798bf6b499870e809e615ff1c469b49c0e375e3a48e7e5cb1d375378acef85938da7d57207d05aa8bc8a41c7d67cff6600e6d9676653631cdec42f188b4ec1772a1dc7466def9601f79b0171af704fd7016debe49bfb36bc63ce95be156f43969c03d4ff089bb41babefee5404ada905b449cf9bf583e6a6515b8ed291b0618acd15e7000280a51206cc7ed3029464f6c5b7a367d3aef22c8eaa4945eef9dd90f04752bbe6225c40cba6f7fffa7ad6a06fd97a5c12a2df2ae2361a8fe850917855f44246a22b528702d6c1fbc24eb5e2024fdcfbb016b6b45be3d05162a8edfb9ee9b530c8a701f6577257252a12f659668902138abbe8ea3b1461c6cc8327a6c2ad73c44f45b4b813fa1e7b1961a4d6fc3bd56b174f6b45c3cfea5336ff08bde315a52230104c0f841aa43ff220996972bd9bbc644aeb73f847ad91240534b204c924df8a5a9c4f2bd84238c0076c585883c6df75cb60d8354309e5b1e0fb5719d8e7ddf90d6da5f7211c1964aed3c6f11e51d95e80e9bc3812db661d64e6b8b812af7de0000000000000000a3e5e00200000000e53118b48522044beb9eede435b3a6b87dae21660c424707c9510172d19a836458c8b10ec2c467f0b7e504b7c0060928abad050ea1615a04254daf8f80f0b4d250dff4534ca53d97a08c47ddbcaa61521502b709d74eb6596235f1c392be0c4100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5fdc9b668d60eee8f5974239cac9d8077b9befc0c8d2e7fc76a17ea21e300d43577e0c8d5300639593af8d17c0345253d4b6a0b7beaeb911d87aa3d7cdb69f1947e39d5a1891557afdb3b253058cf234edc7db56d03547c468756bd9e98d2fcdcf5d1e64068004f695309a156d35c669c51a0f0b50a915d3429022e42909add0204119bcabb43f0f66327da673f0f8f5334d3531a35756c5d0535d4ffcbad2fec021248ef4a0f2b8e7007c37b19ab57d9b982d89c2644a772296274fdfc39d3fa3a0a046067f9b11977e5de244890b313d4d71ab3bee6dbef1607a6eb11dda820e76aba2f9712efb3c61bd2d43f96d31889d5a717ff43bb775b5cb060a99c8d451cb7022296509b3e77c2db28d205158464eb93791e31b7c62db6b555f2939329d8a2e30328e19732aab0969ae8ca32602cf1d1d0b1bbbb8a675e312fa5e069462554faad0318787e00f4f70a936d73ae7c69b0e1a1d69284cce68267372cd7aea363c654de03298b7c6fed719f8fd3375f8dfc509f818bb2421b9d1eb2d8207184cb7c8fc676021926eba1310b7991345bdd0744078f0e6a9ab9cbe0eb43ff75893e40fb45c9fc5dc0bde126f202b0381f3f689dbe1a9013fd7ad709460d44da11781c01565a301c87af0c6e0209104fa4dd38be083424278c8378da906c52e1b40d10ff6da46c2dda80d9064f8a11d2859f43b80223518449ab2930c4596320ad40a321296b543aceaa3e4d88b4dd77f16d0a050aa7db107dd5129f5d0a6c9bbcadf2992e7570023c2006533092e703a03906606a85ccb491b51aa69d1b32140b7c9a58a5ef7a133b98667e0f82fcf99558528fd91921c02fd50a35ab3abd01be1e4c66a16aee794bf59b2fdbfeee58838bc54f7d81cf73c35dafe70983de4a853787e38f32bd7355c35f31ca65dade45650892d2b385a3c23400376f74b2fb9ef1a82433f8cbabcae05970dbaef73d6f183b3a198929c5ea815edf8f7d27b21f3deebd27e4535805f29296f7d5f83f44a2463548c739910eefcac13a9b402b15187f20c044c395683d86e8e3c0b26f6be63bd0e72e0a1df0a78691894ab1ffecfc0057c0f51d31faaae3f4914248980212bd65ca1a29fc08658988cb364c571a06a52b1564d7587731b6cc6570b88968942b20527831dc1953e38b339c874d3da3bc855f0d236d0c657ce0d9b51e7f057126d3182e041f15e9f7b8c4768c21a914d01e265fbf777aae529bae9f1d99be63a681dd766f37c0c981fc7c9858ee81d828aa5a55fa8d4b695b3e6917af1b73b7bbd5546a2282de224eb1b577a9bf8ffab30b47a856b457017811e7012180cc55d5ff45f8db9a67507149acfd8a1d53900b4d93043ba6212ef6941b0f0a9694c607b205fff16d2b65fc9bf7aad988326e55511f32177f4afcae60db94084fa87281f91602d206a83d47c54f319e9c3b7ef920b7c3174aa269e6bd96ac528353d4738388cbe556b529b149a9bae7c0505e2a3c37fa3c8a6b99b0283bb41f553719853e1d8d6f48798b3aa2e94a26e5928ad5f63740953f42e108a54eeb7f2312203f4f46af27e37d73dc9a37314f09a01059a3af9e8bc97f59a98603ae279c6b6e586548e7861020122cf21c5c2aa0a6b37f8d05ee0a486f686287a754e9bfd02b8ef64775bf1e8170f741717a860f81fbda61ca7a9e6d8cdad5ee44798ea5db25a9fb37d66186c4af8e5978bae9aaad274ccfbd2ab742ae938d887a5691c78987417c58c56ad635d7dfd9c7cfd8708ba6fef1ba43a893744dc91ff07115c355061510859b19fd3c44985c32b2a81714035572995e7a86794fbc97e6fce208ba28fb9fe6e5e7e53ed0cb40476307c6d3020720a2a4ad4c15808f68cc72ae4f75ed0a0c965e9d8c1186f0a1362948bfb91fe7d6c2461cc18c9937cf3dcce6924a8f743bc140c1d815f86de2ce633f90cbec554875c192549872cb4f98952d252b666ba4511de1385f73188942df9dcbc4b11a72ffec3b51a806b9eb3491c022ef94f1d852ff95c6c03ddd2e07ef90e04177526145fd0c946c562ecf28534a2a38f96caa13283d925b9b973214d4104e96e7f780edbef2e8997ccdeed6fb3296b47511cf96b79d9960ebe1f82fc34ec08f8e141a813d1a58c2de0da7340d9a5539ef7aaeb3387117c73316079c800ea5cb06119549f8fbd8d713ad920682743eca65645db4a42edd53db50b2230c9838cce942c7a02feeb5a1424006d5ac7a6c5314e4cc0cd4e07ea3a0fa3b7ef14856e9449d51de85c94fd0647c0017ee867af3925029c1184da3884b49bb80722162b9c8ab10f7fdd327711128bf990ad932ca87ed09c0095831f4c920c601ab5cf86ed99a70498ce4fa5715f7a0815f02c4af8b9c67d1fb091bc16c773517f54c885ea35d245e2c01f039258751aa3a5f533ee173f7dd34c15100", "acac", 0, 1175556952, 0, "00a838e6a513a2a3832ee738a2ca9e3fe53001f1e5639c87d43687b1b139f725"], + ["030000807082c40302ec6c179f46c4bb91b6b998601fd04b9d14564c1e20acfa86f84f32a92de0dc260100000009516aac65526a5300ac000f9e63c3a324ffe68fdcef50305003eeed11f2a538b65d258baf75151c40842dd7ede000000000025265ffffffff0313f1b5050000000009515251656351536a51e45f500100000000036552521fa5e90400000000056551530051ff34e75aab91202d00", "", 0, 321495878, 0, "c58986d5b25c0fa8e6f774a85302c4d5e0d1545a8f7f2a5058ce4d90260d389c"], + ["030000807082c403030a0ffb963fb582e4d8bd99d19b3374eaed2d97a85b80519d2ddcaab521eabebe000000000500536352635a58d105c32d13779d09afa7c8d58033282fc804819a7a6646d5df6260eafda160eace67030000000763ac0063655363ffffffff69198daaedeb56cefb7c01c92fbe86c81cd6d96be7f8f148903348ab0e54de5101000000075253005263ac65ffffffff036cec7f0200000000045363636379d11f000000000007ac51005365006535ce260300000000085253520051006a535c9288c400000000037fdd1a020000000000000000000000009038276ee9c7021c186374be58849dec0e4beff609974a8ec2ff8930881e67a865e86a23c5caa30e8e78af1a12b569cbb9e5b8029de7d5884ebafaeae4a872cb2cb6a6d02e8942ce3cd2d67b177b2e191017251dc1357e6091b9d582943619c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c38759d57f775f008f25a0ccb8f5edbd7513f6d8d4569496553f38cadf4e90e94c518ee57b5cd5371d8263d588db0f590c18f93f4a1e105aad5ebe469c71fe37faabdc978919603f9e246a2a3b7cbeed9bf5ea44d1bbd2b6b746b0959cda3330d5aa6eebcba46dc931f748f9fbd6855b3b116b8fcf8acf0b642660de9246dfc030187c241915612b8c79869443d32d3eaca155ed3bd1fdc74214074c48175fbe30228de84e6f1aec26510f5bbec2626d0d85bc82bf25942a6c75c5ebee87e45e5340b03dbdad6b22031e70fce86500b36c06bbefbf00a40aff62a79c3d0fccd1c426e3909d7d34871e14165eec96fa5e486e332b9fd35b006c3d3e162646ea11d61c003148cca59811064b6945abf370e26310a64ee9e8d4701ddfa670bb2a4fa5535e60324d99bc6c1581f12b6333890c1d6d17d2b1adf70c1310d8aa991d4d695667d830330052efe217015e3f98669c3da9d5f4988246527fbb4ac644f979a28394e1009021912d563f64e33c412b0ef7db87bd54b3e4bf6dec0842581fe67094f30d6296a02064aa0252c970e07a259391d665ccf682e2cde1ad512e06c78f09c484938d267230ad01bddc5c15c3c5133d657bbc72cdefaf4e04797eee687e4467b3feded78436e4aab05a00506b1a3e424d68a04d500ee9bbe34e37db8c6b713a872ea6952b6e50f39f19a110e26d0b26cf9c6dcbdf09853fb78d7e3cc6f5c8c07f1b261877646f56f62973adbfcabe18b79736e3838689690a1561f7be679503bcd8132f2182cc9e487213cdb7c468abeff673f37c879861b71a7a77161cd576ba408387f770fe6877174de401a8bc73d410fedc84753e9666156f8164ad464b1e393e987b19342d3a0279b04f5591b42a94798cc434d68af15a41ac5dfe70d39e5a0a629db42bca814ca2c9ec5cae81335cd583e1f4a80ea76688ca5c1221af15ce046215285ed4aed3211d57e4efe2e6aff3f49d1baeacf3108ec78399ff40e721cb5442ca2d6f31d8fbffd6dac1279ba02da3f3e2497d7a466f8959c40843a6ae4eda595b073391ab13d4e57d1881a65ccb245870e0a0dab8a3acd097fd1c46400855b398d99c0d91f444fbb0453689f8e428793d99dd60ffb6695fc2e7e8939a127468b9fb0f8a9ad1e7a3bae37a2f733191852042ed58d11b247e9974b47352024d59e3cc106d3dbd06bf506da7ba1a99368e1ce85507feb20c3fe0b472f193d950e0608848ac1633811d2ddc4abdb30fa1cf434bf0df4899d7f7178b3842e9cb091505e40f90f0eb95e815d04c339bf3d2f053805147ed16b492b05851736f32c3ba88c05c49cc2a380d71148f15f70b2572d8cd5db5732a3a10a08ffa58ef64e26b40478852c9e69e70b77d35f437d3c3b63b571572b965e05faa8eb3769747041df4c8745e2e725f30d5d2be0dfa0f487bde0e7df652847cb7dd44dd85f2a1ab7d11942978cf0be458f585ec0ce8da5f236a43ef1a5c1f90555f2cbcd57002bf934118f2f52e81d3946225fc6df68a7e62c6afe26e96879b96c844c7e85f2002cce3e76db6cfcf4fb4072dca8d318ad501ccd2661d20eeecc040759abb79324da8b9144b34ca455feae4406b47d5a5f963648767c7af74499859e86e31d7663b90c2f203a326ef0a91db740a7a69bb5f5bbaefba62fa75aa2754ea28ea433fbd161564f3f62c22d3b2917a171dad1f71e16c6accbf8fd487b70337e5241629c6ee0005d7a9ea526a8c7640ad3d68a43185b4a89d1b99b1cd8c1e8c790a33ac72fb530e972302f419f2e34ccbf4d0c7ef1594635af689696b0d2855624adaac86f4b50bd9b7e907d3a16e50c4e74bdbeb1102fb4d44f5ecb610cdc29867e6603fa7d8dff10af3e2deb907cbd62c3582416b5200f9008f26d5e4c7f0f15091412d21f4a0d3f3c81d902bef8307482c1bedc5efdced5de0bb5ee7a9545d7d425ebee186e25ec7cfddd52ae33c0a2bfc06bdf55beddf81fdff2283d29acfdbc9e7c484ea2985f8c4c02d098e814165d2f75309ee544d2a851ad6449133618305cc6fbffd3570429987ed12109ecd112c2260ad72d2f3fe054699bb0ca04800b68cbf91187cfabe6531f7835480c9466ba751614d4c0aeccb0e6813ea8997ee1ffe461ae3fa0f237a5c7b496e9e4c475679886aa25b24a3a11c8ce008a197a540ca9fd68b0dfcddafa5b04beefc6c62b6dd02c3084f69c8d0604a48d434ea97f011c0aba3c32b53bdb7d74efa01f7f91daa96b2a6ad4ae133473a4f20c502e8708d6ce5d0b6a9f6b153448af2aefcb84d32d43bcfb53fa7a02000000000000000000000000350fe5670a919389b01d6bc2eb23cae26dca9e92462863c272e215c14f4ef5f51f217269159d016495efb2b1254c9695bf743830a87c837079b6253f60c0863175b757a70c71b22585cdee198e16e1a810c38eda5089e2d197516a71346607e20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087a56dd91cdbc66033f705323f776412e457aa4f2ba726179e7dc9d8866e09993139805ba57ab65a4949cdbbf8593076a865ae20739df919d254ede299895ba55717bc1f1a8428b66c12dbb50fbdf71059812195a5d73708f378ae5b8bdcb23bc44ef32ff7bf2c49bfa9d3e9a82cad747fac353ab14c87eeaa6981dfda01daf1032d7622d73bdc2741f1089df67ab981d23fd5d2177c9faaa57f0811203243f7730201f46ea4d53916a1f02b55657c5978fb4002667f4d27d6965e4a82a2deabc59f0b038c173a9c53e7d4e21ede916015a8bf951b9bf2ff8bd10a788fceb252de4eccc97e622ca1399827d5a2b840a2ade11bf376f6cd05ac5664359cecd6714b8fb703147ccfbe37491e8d4dc86b4f759b4f4b72ab94ee730f09eb26df780fe2b37bdb022fda9a5a6629dc0e97c7d900f6edd9f026c6d3c187b2397fc3a491db152dca750228da2159ab0ebe0c5926da0157ebd41065e2cb4744501465b99a808d7f3bb7ed0327d8c5981543de6ffa365c90780f6513855543690d2d75a6af2205cdabe47787032529329156a60218725d1e069d628bf9998e7b778ccf73aa732a8053eb263ccf0ad7adfe9d5cea14ebe06b45962b005b200a4dac11d38fee2583c669a06400c8ffea709e858828bcd95112d0958048159ffe2ffa877a8cccfbc462bff21f4344a8ff9001149801f97d6c8e4cd0929d762ff6270f12081d91646172abbb62d6bb571434af68721ede378c7aebcba600545cd56fad0b6c2706f439a3632d58ec40f2faa93c3ac07b6478301857f0eb034325b5f296bf2f0957e7051db3e21323c8e829cfe9e1ae0d085cd29b5a8cd79d8ff0e8f5621144fc1af206e85a267fa5020964349821094ce11f6c443675ba1b1ea4575f64f46b49e7013c08df0d2523a257d3a42f03918f2df7d28dcd8b80a47318d9e35d55b164398ed9a02319a62a372e32ba60c42283a37aae2532260e87e9f4768d5044d6fd1ae614a32b72204677f471df2e150b57d1985c2950a84ac72efd288e21d8b9750ee535e76e0c0b0c8c566479c6a008b30e84287f6223e96202ef03dfc4563e9a147908820fc09ac146e59350c33ddd10cd05a91f370bf273327e64d85461b448656dd4f305f0aa2c053d620a8dcf740f09f99908be6b250166f9ccbc585bf433ebcbf3880cf6702c437db3cffbf9c4478e0d39121fef2ef3900b5efc6a83e829f4cdd22c5ce2b6f90d79f0e2ca5a7978d4cdba34de5fa92ad2f99e79c44f3867f942d2ae3ef1d63f758ddad3f1a7f364ceeadcd5095482f64335e0d676ada2c76e492640937dd74a2461643eb1e3e90387dc800d7f44c0042b5b9776e9fa764c8f8ce35f31984f133d9783fa0f0c3ad4cc4faed195291316ead7fe9f6438e308d59b699e011c0fa258f7ac1766cd33d0ad5e30823f3b399d2a9d74aac54e2559ab9cb7118c2572187d6a0770bd5a1f331c71b89fdbb106d7201eaf4da99e8939de7d3543380da61faa19b3f20955bf397f1b52de1063c00a9ae48b951afb60619474c999f2572e1d735175115fdb7695fb695f438b1d3ff121c3d1e3892766169616d0259038680e7e2ea5b40668725e2398acb95a64aa7320d4187908e186868c11b447b8628dd0480c4e92fc6aeff3ab33691ab2f0f9499044a6bb0a92e50f6404490879a2b37ef218ca746c5da8c91c1c340399ff7a651fff2bf64f2cd80f897dfe8460d1c5a7f72232766bcbd70f476634547d279da98dba7dcf5ebd9bea646fca5524868a33c2e27d69426a50fe97a131162ff31305f1aabf7c619d2f4894d54461528d6bee0bebcd0e6e813928c88050842cbdf2449a6cc10529919d2786327727d49d8700573fc574d68e384c55cc1d306b3e309b827ee7e964e71f42a51954c67ab9daa17236504a385fef8064d7dc6dee9e879782d17d6a1e70172d0624a93035530f892fa7e7ce8421051f1e844019ec7044c46312620e30677a33fb94d94d759b8807c76eb3afeef3536f4ff342897bdd3d166fe1f5d2dee46b6f4cdbe42cd3ae0a0310c54de4b3e301d743fb7d4dc7a309fc2b701864bccd00797be213e8cbf1daf3bb6d0b0028187497a33b7c5a5e3674b20d01ae3dc6cfe0bbea30f3708794e2b6dec33182956580545b40b55b66f3f6129c93390a30851591a6d8af48eb6ef8afbec36ea014d256d6f3b994f579bb63dec84a5907f9ceb2caa03b39b6908ab2cd98bec70b1ef343fd811339566c2b34bde46da5f44ca227166c6ccd20d92142b13336c2bda5026cdf96fe6f14908bb97c976ec6ae410d04000000000000000000000000f32b1b511e1125da6a734502e3b892bd8fd8895d3e64a6c268abfd77654ccb392ef9bab3e993239364d04b96b436cf0e93a1617429096534449d7ea2a830e79e12fa467ea70e052795fd18296840198e4860441e744faf2230dfa398c4f3145d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050263c4d74101f0d2e7e0f2db449d52bddbd18ec4781d113e9ec7c200e5320b578870e0af60f1e3d66e5b9553f1ef1261f4fa45b55278daa1a141add1a809ab80de4494a49585b665d5e1c29e9fe69daf1b59a07c2976e5789142fb5188f9bc497c0864661ecdd74f45aff4b3cf90694b02d0d4f201debac5c59dad5f6d79bea030cfa3a7c9286d100e882f090b0f5bff4adc9dec6002dd694f387e270cee0d41502205f8848ba803d50cc376bacb11caa1e2f3146fe830a4d00d138b68534bd07100a0599365ebcf1792f6e3050363d5e259450cbfccd78c26419e34e18643012337a2dc2fcdd34b3ab6c82954668eb742b1e1e65ce7b71eafa9628f1f7713902e511032a88df8a0f53bd064194e9f69956eb8dbeabd37caf3455a5b6c12dd524e6e96d022e27a35807a7351ece0919958a1e4ad749801a2bd38bbb691f88fa0d8a6608f10226075831b2323321d3e2f388ea6effc8a9ed6a582d47e8760392cc7902a34e5b0211d7d1235b9165e1fd12aa9b4fc528c77378ecd71c0c5bc25d4d25dcdf568cee020e570da1ed73526aa4513896e8ef6151186a1aeaedcd1d2f50d39e5d59fd22d832c36e68ca10d475c5adff3f65ba8692b51ebb0db30e2968bca02a466766885560db7104c79910be88e792d77a4bca3bf45140b1c541adb5a88d2ad2268a811c4678c637a28bd45d2da88ca1d38a821dded489b9d11ad47f3ed86808fa44c7e04da8c834c52c91fa57afbf254fbaff298a015062e72084b28ec649a8da53addb237082137083b1f32fe944bafd9730f95e491557db94b549901d45ad63de76762d2f97fac668020a3f1da355568565ad3303b744f3dc24a3006024c46ee6569f9f114958277a5462fbc789b685a3936fff5f5c16cee5c6f2ed190b7ce6ec65f81a310e716fb7aae9e6af50ed9bd663e758fc9dbe2250f310266fa770544dcd8017cf89bd776183a29a859fffeeda1455c58482484f0254c124c120189a981a49ef0b3ea8e67deb8e1bac9558dc69582f3d538c2074557c5556c3e735047a1808cf7e305c89bd76b4704cd55c5838c43a399c88d5c6942c608a4b82ef98c2dc3e035ce667630ec1ce553ca9ae1c2d873ea8e2e258ab9b66991abc8e476d9abb1a0ed7e281e37ae066ca3860852d4bdaf1e8d5918c403a094a1badd25d8a14d5c8718cdfc10a5ad079eb2020eeb650b06fb4f6e212ae44976fc7bb725021357dcc17a3b4849f02408fd7f4134dc604f1666835ad87ddd0a271ebc435d8e5e7520c90533a2dfe845867867c72b7aaa86bc108d704fad90c306c8f7bc98e0575d19797d8bfe5c70498e42200fd9f3531f87a0c527e6b2a95fb5d87724ccc35d9ce499a0389aa3ac6a042204c951c8f4965b280e0fbc4646ecf74d671e8b854540bf60da7e5f3d40dc0b2afe48a7001a7875451e97aef139090bea738d28ab9a2908f315b83b6ca8910bbff51134f703b5fdb9177affd97789742c76dc666f2b70bde9c41af40eb4fb2058a1404cedebb23190174e3325d9bd1f5a88c04ff3746cbeb4a990499bb4f9b531c263fc0882140ef321ca252617433354a2592523400a9b049a0b1f72a99d25ccd765fee9135ac0a0838b36b0880b4b88f38294fc34049a654e4d28f95d10d29bc67657cb2198ace5f13957477190af93b6e1ed97e8f2fbc8abc77817b8132f3ef1e981565dc0818be10e1b6293dcf863fd0b9984f77a9da827e458798f7db4399eb3c0f332871723b8cd74c341034947d6938abcc47930607850e8775e3cb67b5226ee357c2cb23160f9385bc2fa445d6b8c2c6bf4bea23cbb470a6271d4cc91549d64e30ab87ddc8c3446556e88e04c4d066da939a4079d7b0dd3d29de13a72cbdce27e32c97948ccb624e6e295b8b4ef05264bb5175c7e9249dd9ffd4774b9c2d7ac6d7eb5257c74311a215f58f85fdd9cea62f961538861970b973b291102b1d8f0535e8d4a8f8129ed778d2817f4aa30c26a71b8a5074b2e967c987e7134a3453b8afb77dee5d9a14dfc4bdf5eceb2ece0c4782c27de5ff83a29bf7b4f469ce0537ec74547f9e36ac5c13eb2072ec5e90cfef78859e185ed403189ed7e4f280e4002309481d9b961a608acfc64ef1433528937f7a55ec8b6ed0ac4d47a319d29ab179cb9c15565f54d35a97c38297839b6cf1c6b27bf95b87e5082c12a8dfe161ed89a39c54fb20604053bfe8bf0c7369176b53357c78f7ca91d9c7ec63987e4f4be7b9b838b7df7d5d11de3c87aa143b5f0a05477056d889d9a01f5d969fe4bed2a8586c4202f4d5499a24ae485e11c3b2b4b28b0ba7846c1ab21fdc5bc76a3ad096dbb7d85118d461a30f608e7aff439dd13834e5bd0e885d4dd02b399a1a3d197bdfc4532ed679bcb450abd73f6b8f0ea1ff3bf3259d1469b11b7f5b0d84eeab690e5270810a", "510051006a51655153", 1, -291795576, 0, "0491eab34a35eae7d0231750f8f86d368132e105dcfec59dcde90ee8d2eaea92"], + ["030000807082c40301eeb9b1364610df379d5699fd7c6f358438a40bead2d8b09b0f687394e5be91b00200000004ac535165ee0e23c803dbea1a03000000000965ac005351635165006882c202000000000652ac63ac6a6ae90208010000000005636aac5100e42b5de80000000000", "ac635151", 0, -413149335, 1537743641, "b8db28e55f3b1a3163a20f0c72d10e29fd9e96fef8058e793eb351b712b6d38d"], + ["74327f3f010b2cfcb6433c22fa35d621e24ddb18ec9795d0d082b12d52d48ac590cb4c752802000000026aacffffffff02a13c3300000000000751ac63525365ac4b225405000000000351ac510000000000", "6a6a5100", 0, 1104014219, 0, "cec9df379942e732aba7a35b08b2ee864672a332236e67fabfda93c0bf6dac32"], + ["da722a1e02ae4ca534df85814e778819953fb92383099e75a897a71d79aa30c0bd6aa250870300000006ac536a0000531e8228dc208034f1e99270422dbc823df64a07dd7ff887cdcbbaf24d74c6ccb3e6afcc4b0000000006ac536aac5352caf11e5103131e930400000000046aac525209cf3a020000000003525265c5019d020000000006655300acac5244697487039e6ba401000000000000000000000000a3c6b24caac9320d204ad4146dc10bdf1b2fcd53878cecb6f74e3ce750838e9a2a7be36238cef7553b63d8e5a6681634a33fe1683a2f616ba6a6a9b984e07a4b2c70c8e15f52c19f6fca50cf4d91979051a141349abc35cd02efbfc93f8771c200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b889dbef37c77e59e83b033f6493d35414a86610d16f7c0eadd971c865b6909335124db425121752bfb94f5f13a287420fd7ad107a8274dfdeae5a43d634a9bdf6785a12b765262951b742e2e57168c3bbb9705635e8b64e270abe0d87e6ee73629cdf3b9ef6a23c05dace2e629e103bd94d0fe8db32386d058cf35b177a2f021f0ffbc867628b44c06a224b5c1cd31844cb7cb72877316e14814e5a8412529f031e91d32bbff0ccf09ec2840596fbac042ec7e65b784cf6c5b2650074c4ad40180b0803d49b4bcd59927a0be16b6e6c5262f144d26a964831aa454052b2797b3ddd0ad913860ac1e181ea6f87194541e71919dbe9d56094ce37c397c47ea0d817e00206cc172d3f9ec90427c5a8ed517a3547af32da828f2785cc8a632665b0ee83da020a135b86aa08ff608108ec9c119c9a8319a136d85e8d68b5ce7442ffa7874ca703078c81534afdd48cc04c5040da4920acf99dd42aad5bfdfce0f0867b63749bb2031d88891741e63cd789f673e451bfc17332314454f804f2c9ad51b04f81d2e7e8030835ec00a37b5fff963dbc805b0654410e4764292c2467cca774e139a0a76c7667c425be70371bd0f541147cb503c7699be58970696075c9a4e1e4ae3d6a8fc8304649ab03252dec8bf4e3362497285b9a7e79ff75959eccf09892dbb1206e6e3604214312aa1391d40012852e795b8fc71dfc8837cd18ca32f7ecbe1734fb34a30322244ad5d35b212c50755ea5bde752cf03b9ed3a52bfcfb01b6b6a5159cfbe5f34771155581012fa9807a35f9a3d914909a465adfa2772c479f2608652624f0dfc4fffa7908e56f6bf929c283ed0258dc38936168f994db9fb773ffe7ef0f8b951e3e0e4af19a55cdf88d26eae2acaff0746c8c5166cfcac981677976ec5fffc65ee6508eacf1e3c82ef9e2183362ecd17508219b7474dca449bca54be63f501b4c360f60a016a57684f5829266565978851876ec88b59a3222fd480821a9b09be50d5dde2bc5be3fc568436838383ed33012bc53bac300659ecb8ce3e4f9d25f7731babc79f6cb6199e118d4abd09a4bd0a31fbe30d15d5c1a2a476d42d73949962980afc27ea48f4752daa2bf6d18285440ed6ebae68e249b0a4c08aeca75f80a7687c0d1c7f193d39c8143d7930f5b566ed0cc3cc5eab42cecd0303b716fc5e55be1f111d68017e3c5632e6a7d802455ed0f0c4fc538e2ff57c618771cd462645a1491ce2a79fe81d197a4d70317ea47a200709ee5fac56ffef0af95fef7fb975cab2fe3bfa827ff636fc8a0533288e67bd9dc2333d789a549cd4ab815e0e3ee611226f35f0e11daa5d4edcaa2e91344355070f4ee9b472951e7fdf49bf582d030957bf83817433157bae79f7e43903a18d82414fb71bbcc490162ad536144f8401d255df4a6af3f0019e12e7d5c04f7afe690375ea4136939a18f5d32db9ca47116bee0f03cc951459e647c01c1d13fc58917d375b20c2ad60b5c43709212899c862409624d387e56bbf16c18b3d2afe7b80366ca29a5b66305c03b2a2008143343ddaa014aa4f3ab0d22c45ba1ac6bd4be2d1f84ebac57df48f376f8c32a77476065a17babd700ac86302fa7912f578b3b5cd88e4b2bee172980b66a8178fbdd67648cbf6c594f341f309329b5a48bc9cb1928bc67767d5a023bdc92cb9a41125c0093cf5a9258e72c26b23b141fba83deac59632a96bfac7d1c616157c85a8df775761de925142781418502d91dbdcc49ef861c01665db1cc6d15a2965578e7f9f83932dc97beab9030d58b514a88f7b76c37e18af3e56a20097e34253729084eae5ef0c5f651883feff9faa75853b42787d12d6fe081c47168aa0438f9f91fd412748009d8b340a5b8d0fcb9c9417f3ec017bae99532c5d71708be76c33d3a3e9a5f0f6c039c76053a4a7a4aaea28a0993d1599c66b4c93599b96b7805cb81746dce401557822490634a2c8d7a3f256ea805e46d2836378fa552cf0e0ec7fa07152e1459dcd009e0fc7fe640e29a628f21da7b0e7b7bc0eb831dddd9c3483e81c101328b7df076d015a7a680764b16497f5843e11efa4a23378fb4c1ca1d70b1956cc72aa89f0855d52a512948e2583aea4c712e563099468bd5e255d430e7a94b4d80704a587d484031b8c6ca30a0d07137d6e57da637eefebcfd7ae019e17ee771b2631615695e557845ae7ce30cac56a4cf8fafea67b7d6c81e74a83d498e4a59fa6f5ebae8f87dd3a9e4e2d2abb7c37f3f0de1eaebe51df3289c2f124b143c671f42421ea6f8341e12181000000000000000026b079050000000094607a38b66c814b08c4d19e3ac06152b99cf16b95cee72cc71fb3227f09a454a706ca30f46a4e007f908cad5675472d78c0d54b10097ffc423f3d8cc105636378c03ebd47624d46aa4224f62fcf97ba281e596bb608dae71bee5f51944743c300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000da530673eb711509027530be27589469a44f855103ccac9d3b3c760cbb4da8d8e95e0e07269f1f4fa505d6af1eafc07a9d12a0d962dde3d4ddd3dfb8e7538ae3be8fd5dbd1a962cbe4899478b1ec419c7b467865f134971f60dcc563a2e23e2e68785acdbf9cce7ff645fdc82929ad91f697517eddb948f0ec6d89102185acd8021850d1956486fe3bc811722a2930d29b1318e5852af8c93fa0bc101f38af51ba022b493bd85b6a457df5c0aa9792581456a671a88856a6128755f7e292d1fe893a0a01c8fc6011278225784c223151cdeb3aabca2b6fbb9873f44b9478815b60f9660928b7a40ace62a3ece8a07a8d416c96947661a365a78321d2cad994bcab0c31022bc10ec72e45f2f390aaad9c9828d8ef305dd4bd4a12368443fdf94d3634e3ce02015eadf942dd2793cf04cd456f5cd2b6857a0a58b1d83a478bfa1f555a5042f20317f946970c21b184e180372fc91a47637e7d377a6e2424a2099aaf36e7f3f25f0319dacd451e159925029d31bc9136f680fc2fc64c425b5bb00213ae4126ddd442030de4a1c6ebfca438c5d3381586358aaac31452cbcc82b66a40fd78ca0a39344b57e6aa436f3640dbdb9ef4c1fed4ec6c0835b0c116f8bd0336e2d5a981f560ff4e76442702770e89e5b17447763b60e681bac8501ce3f4423b4a5dc4b1e2c2499241e8385864c95682297e402097ff16972e711acd1bf868588fa6c730339181d0615c3f1a1c6aa4dba467359c458dbe76c4203a1c01131439d5222feb59bb5fbc0b79458b29dc1f140a82bd895875f609d51d5917e1c799eadf4439284250d37dcbd03bc2d17d45c5c8dad2a42766c990a0247ddcfd657d85825bbdf46e81a13d2e3b8fdffc29b46017af3662418debc039d4e7c411585f26e7b17843faecc444072da0b6c8d5b682ac5b9eb903f65b6924c949042273964f0bbf1b6d9fb4a83d6ad996ce6f5faa8251873dd0b5c1d3f504f4d20c847937d5379a6ffb172f9a50dd328706c55549b5585018f40692f8e0d9baeac60042d0d8d2f1976452026d48bcd9f635650f6c62e9c8342f7571099ec9d6a41091c1ca8689134a3f56f3b0f28f32aa3ae1eaab1ff70ca6e3afce2ee707af86b5975355f5004c1456275a113d3d1f3f93dd42797f8f11ecc27da769127c2996e8cb240f0d047e960c119a43ce800e0d0787e15a02aa3b8d04d22048b639c1625ef5897dda5a278ba50748a93fa5c9d3467c66e2494a08517d621099ee10152c436825192af0ecf251628c2634add33e80017e42c693a7ccd059db476d97a10de7321026e2b71d82fd047628b816e711e0bd07f29e5421b95bea45c73ae389d997c3a67bf9e5a9a232ae794912290b16245c8b33dc96fbc14254c5d86b6921be7213f048f72d7e8b3a113d5825f1b3211407a9991e6df560475bdf0979cfb2faed53ff2c4a5e82e44f58d1edf7f0ec1b6eacf842be9b96e7023c6ba0e34ac6d5f6606a39ef9314b5bb38ba5eab9543339d1bd7b7575ca902f3aa7a9a666eb0f8caf07ca5518780dd4400674b197420b82408441b97bd64a163609e5bd28caa41d63abfcc989e1ef68fe2a9ca4d283db091104e148e7978f1f3c469bac68fd79e960fa8acf823006c9f6152c736603c4f06e838655e12af720df572b190eb251d4d88f68da538b03a240b02ee9e6c688204205f98d1cf3012bfdd497c956d3a0e0d6da9eba96949e540dc95903a4194cd2c3f843f3880965711c889aa6b6c3e68d0a48319a7112005e24d71dd283808f494e7c2c34f142bd3ad4046fdda332f03dd9eccd1827ad792c2a5566866094c1bc053721370e6bd35034ea3beb8263557cc89a0af039209efaa24664bef97583a34545bac2aa0b5e82720a7a85b3e95efb4b396a534ba0f5d6cd22ed7e0c83c488d4cc53a87985aeb1eb2d3c7d071d4b682a537765bd983f058177d9d397ca43bc08221a0a426239f10fbf5da5624d7148a1a0fd314613625416babb495d8bd000f2ac67515f434a3002a823fed7c9e0de832a57e21c470ce31e1d8287c181f5767585525ce79b6a72670c72c263434489c511778212d590b8ecef4c7bd82a15243b93fe03fedb68268c4ed103a760750525ffa1ad09df738c6b6b61054ea6e7924e945ac8324e50e7a1b4aacb255f5ba2e9011bb94009ac98c37518f2ff6000986fb482c5ebefd31fe72d2f9d86b29da63e4eb56bbeb20881ef3c9cf5fa3009c3c1534540bb8f3851628db48209c44457163426c6ddeb15010281876c5be8dd0c9bbded6e5def26b26c55158de9d00000000000000001ee2eb0100000000ec6fb4eda6eb77aa5f532554972d303e9565742f2f454f38fe649c7a7e6de65bb699f7312169d7cba818037142a4a1b5820e0ebc9cf974058ea41806e2a77f3d0978028cb920b4b2549d8ee707f59b7781b74494dcc74cccca45e17d244d273b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3b906d4f93e29ed56e98d5148ff1bddab5ae32fa75697d82c64ed6267be540fb8ec9d41125551c78fcfa5b9b08b3213818fa4dd299f826e042e13591dd3f2e4e13f5cdea5efef44a068c5141bc2fba03dab5115b0a2c40aec6e7dd4376cc09867b892f4be4ecf7201212460db84270b2d4bc9a679c52d7f551ed4aa0d3ee0130302aab15638bfc47fccbe5cb10ab56cada8f85bffc18f99d815f0b745dfc84b90020b210345dbba2dbc0348fb8f2837ac704d4ea33d0b622658df88770df1e442e10a00f989e4a75160e8fc7e799d693902b4802f303ad03dcdad64b4254b11b53fc36abd6d25bb04de382261ae16ea2bd6105f65685c6e2cb3572428238a833a4538030ce8452bc81bd337b8855347d88e02fc641f6a4718e80c17114fbbfcfcbd219303027eb31d32efd20b5482178dae7f37de4fcc03b275ff92341ec85f5f928a3a9902303bb354c4471e5e9f161efd2efca93fe1772a2de922ffa2cc100a30b4d58e3b0229b0683bb6cc3e21605a3de79fce647dc6568b747be780b147990c46444b5ee6032f073000fb5d4e443bd07dd2d798f4913af4b136a46eccba43e08e61b93d2e10a23af6010af38ebfbc5a2c1eb675f9b1754734a92a7e3beefb2ca5af9c3f6437eb5bf7920f79d5782478a6973ac961073fa2e02ede5cfd8c893a2d9ca6ceeafb742655e50a5d1adc623bc15c1a308ca002892593db9e8b94f2b4bae47165063b87a9683a141e57d2481413a65963e1e0551d5c4e96e2f28798622b4edaf333d03ec53a6bf551fa13b01cb78c95b86247c6811d02902a4611dcdfe2d5b56719964a967178155f1f017870aa047188e32e1aa98cd5f70954388de0ae973ed78b82d19a7cb551ce3c0acc7f635a4f4d009b28b27bad9f378266b24177b5f17742338e3eb9b8486f81fa43bacab7f8a923d8193b5d4450ef9e1b42a0572c1667a8d9ab4cb13515a249a76ac528abd2f7c38dbf3409e25073197db5d175328d9f0f2d0450b2d78f61a79dfe0fbb20ea6e00e41afaad4146d23504beea93a812f0de96b1b9a0377d44cba8533eb8eb92575bfc512809c4138e88b121e9600cf0468608ebf0237b980a9e6b9f4982d87f4f4becfdef79c89c4740b69f93db6afa1dce9ca95c2c323125b262e7a7e5cab2cfffce74617b8a30806fe69e173fa757cdb1595a7994baef1fccc304ed627a6dd9ac29b739a09a04afe123645361516d3a615a604ec6ecee9706451e96dacfbf98b84cc62a29320368b81827f3843679b124aba2de73ffd36427f62fe8984515bd0d9ec96e66106ff31fb3ccb1f1e8ca48fdabca96975964ee13dfab44d4d479d4fecbc67b0c20e189f4ce59dd1b124b1813e1d8a9bac8b5e31debfe578e7d7b53d861c9c9ccf3da93bf6ea5a55d740f686f525da0c77999a26063f8e5be63a75019471d7b2081e02ee25c45f0d22ad7f187ede468fa1021cba7f640f33d028cfd44c0f21151523b4135ef1688c13e9ed5c43f90bbf6ce0ae929b63a3236316e4539a122596ec8c11711cf5f8dfdf137348b4e884d0d5c04b0233c72d177bf4be8756f2862737c39284035d631594ccc3792c934103ba09a008be3a4f22c4d4f61c5b1952fc32baf851b1047731a1017864d1aee57f43388d48f70e5aa2eee988d6c9926d4dde1811e3f0b5cbbe59a0b2d28537094de329dc7730de98694f7a21406eed019384d2c7daaa339bce8c579932edd138100bd01f2cb26ae5bc0b02a4f34a8d11e6e6fc4d71a3eb24dcfa643c45c80f070fe15080050335cf9f583d4e9402aa8e2fedc324e54d13885bbd92b3568264797161ba18c33b4388538c9fefec54c31a78e7085199f303c730e0c3ae0e3940547cdb79fb33759a65b2b02dd711988723ad9d604eac11537f3ecc11c3c612905c96603f0da47f70d180fed2b5a59e4fe2ff5d2bd612e2e32701dcd837997a60388180abd8988dd924f7bd7c32ca8f86637bb217e5b0838363ac119f93daa482647207bfb270936bf785e8f01697c7dd98709b4d7cc3f259ba7c891a191eeeb4dd4ab967e2a9ef44c8be729f19f2a00078e68b743f023abde99b4509cf6d41070782ad764c978a8c8be15b470643bc616bd5eb7958576b89ed8fc2162e764fef786dae7b496ceba2a5ff35f0dd5e1da6071bbf43c27e827a4b0d37328cafc2466e3f1508d55e9c01aade956d3f886e06d965eb057a61c40dafbbe5c9404516a768d7aec974afa4fd951e3f1ed4b05d3351ec0e76b5f88cc0012148ca7571fa8b70d8daf2565c13116d501738d8eb3a3a3589aa939faf41fe2f32ed751ee1107f3092200f3520c9980a54c958c5bda3be4fc2bbc45f9efe97673e5e7edb9d7ea9aac796645ea7b32495b6d5663a05816b9376eb4c262cd3b1f3c0bff2f332d67dbaec17813e1ea3fc9a971fa276677cdd70f", "6a526a5363", 1, 1954938644, 0, "5405bce2a43b96af8b4c19b913f4b03be6e13e98107532df2f111c17fe65f90e"], + ["97328f2f01e5eb739a8b22f2b3f3a3293d2c193536f682d61683b3133a28285a2392a5ff8800000000086a00ac6aac52656a964e0b2003afd9400300000000036300510146bd02000000000552516565008c0d2e010000000008516565536a51ac630000000003d8aac5040000000000000000000000002ea2ffaae81e6feb7d39ac8254ddfad877934996d7a840ebc83e6e31064952884432bdc96b9bf86d1c0c4e604f2bc6477c2c188e4315018fb473a216d39159d470f2246c631d4f9456b740aa388b4bd3240592c8c3d16e20bd9457b50f9202c7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b987f44ec24da97119a51ed7436a4ce5f12193adc6085ef978e4fa09bac4a09ae57c9f21a44000097bc6b9d90a0567df0d7e93f93035cae75138b7368db32196a8e2aa8006fbafba55df7fb08e8040d11c6b2f018a9a7aee9ff21cde64ce4fec7e390149b1b028f7827bbcbcfecde8ef5d04f1c57c2e7d8358a42af565858070327b0d360fa90f5604f7b6be3d40068672b27e7c18654af377d01953a07b7f740031aae28f7d9cf773dad3657d0d413b7c05d19b5a1e9368d60f74315f59d538f160a01c52186fd32052c7ee6048f1427dd542d0f4a6cb7738b5919ab2e31d3c5686f1b39d31c0628b18b63c9a40c01030018be44bffd1c0cca0275ddc6a147b1f1420222cc2b0d5c9bc9169ebfb00e408160bc53ef164f6aacd53d00fb58bd4f869586020ab3a83a10b6f5d375d8038386f54359111b161a6b5deafa88e5550f683d877e03168974e265f0711bc837ef871dea9916a7bf2d6a802826deddc45d03990851ef03114f8009336571408ab82ce98c631dd7691dafe3389e4fec7737c202f14bcbb10221ef770ef221c91493df3262f8d318fb7f16dd9a4dc095ebd9d6351a2d5a951fbac558adaaf19551e7e9788f547ff53ba8a67245e6a6220ab82509699f88a7138f7a84d771d5a623518c4805daa8b3a4fbb2f1aa6fa721703d5e23faa2178869e3a4e3464349e3a3ff0c034a4a1b2b8c834ecde370398ed40625f01072ac4ae654206a0f7b7ab72074e606b1f2e82902851c84c53dc751611424254b1a9a86b3202db206a32574e58735f5e7f6da832861626d43a171507c707aaa25bd9586747bddf513b1cd2c74b480ea7d304558e4c4e6ff809a117812f7ddde74374ec7dcde35b6a2dbfae8532496f975409ae286d5b32f3b8947cebfe6771814096444d65c7377cafa1180a43c898fe23441cc8c2d72c53ee8ae7220b73dd961db868fc4a5b61b7cae42991dbad19fd00ffd84a244cf6861895f7bcf1e8f7368dfbaa4db8d34e3bc85d0887fa6cd53800189ffe74e61b98983823dd004aac6d8369cd87c62a287c724accdb0571b428841cc2f0be2ac8c7e1c3d2111f26b4b8f4c6009ff92651bc1cbe3e6b27170106b813a85fda2e9e77186d7fb9d53452774960789b6ad9ce2ff54cbc139c2bc86877bbe2b4d2024b4aa84383c2fc56ba49a6b896fa2ab54660988af85601036555ceefb790f984f4cc7034007ea37d0276fa18839c79cc26915c8388badf100fec3f37be76378fea321e40b79903600f3227bfe66262d92b4231c9588cdccab5fd7d2f6d33b0d9d7295d71f494a0b565c87e63dd61c7c68b55be71ba2a1c4ffc006222e75b6699cd4c4996721dcc020b7626e1903d1f98601e3e33df54d95d4f5c280096fc695a942f4bd237752e764214003329aa824ec121ca1f6b01665fa6dd59fa762db6eb513fe6957da35e74b364b6a14c5ebc0a8f6c13df1b39e2c0f15e7803d94dac7bb31d9ce5edcb470228f7739063cf55a0d2e8fc1fe6d017d38f97689870e79fac2f9a0c7deaa7d1b9837da147298356d22d29e266b7cdffa8acc76844f70f51fafadc49acf46afcd8bb705dd515046531b0e045926180b222058f3e702b21dbfc439119a2deb1770e87a8f43fd55bf1d6682958f756c7e565635032d9b13a2ee287303352fafed76260a9df11691e90bb8460a825903390c172521ed7ad9f6dc541a3c8678036dbc964c66741d827c1dfbff96f80d2597ad0903acc1326d1d6e0cb4e5777efccd2ad2521062e4b54729974c8a015b8deeac1145d6879361e18b6ee4bf8599283bdc960869169eaa32f4d97d179da4b1ef797a5764519dbaf1928d475aec7fcda3c1396b6ffba32f0561c63a1b84199cfa851c3ef79dadd6294ff2d66a18484c7560ae2b16ec22a21a28ea5785010cb942e75ba35ef3955ed5fccb3f29a456f705727e1f961efe6527e3491707aa7a0f8da0e2ac093a6c559b3052dce09c9d6d65b181f9ae6d07976445bd251a385e4e581d1eb3ed145aa0b3bd6ab8dc014a5a80155ce0ff44d348a44db9568aa45c0c941f59f58838f54449500cd9d77db0e4fd6d26244aaa05d8c637faf1dbeeb0dd2cca8ed4034f33e09da2a918a1898e399278a5c8821fd44c6e213ec2f429a3f627944fef239c8d4a93927039aabfa579bf71f045b02b202d374ac4f45144ec27abbf78292a9302ec08f79a7f1256b0bd8baa53c06624ad3982f06a2493c2e266725cd6fafe361289989807ef433b0a6a30c4c8ca326313c13447fcc881237ef6a755c76379cfb5656a439c5c32c60100000000000000000000000008c9d5bfb2a671e20d51c38fbe9bfd5fb5cf96a572fb626f55f90a42c141e619fb16b7a28c0cc29e9d11ecee7e6185f4f10de1e39faef139ded5831cf061366f68d95ef8e7a507da9701d0372da6b41196ec499b375ecea29c04743b8ab0a0fe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000144f03419b468efb6f690587064b8f8d4632ee65218bd60aa2d86a01d394090f5ae090eae2f7f070d99656408acc21522577153adba5037c5d0bf3a0bde1934f4f0adb2eee841b1b13c9661651e755c94ad960cea19cc18f281b22a15a9de3366b3dfe01786727ecd846dd99897e08b8c0213b72879ba2dfd1402ceeca00e84c030886376c3502fbeff986a2e8ed428824fae4419c8f111577af2bac4e3ee11034020d38767334a9c1cf847bfcc06d92632bf47336a7e1fda038a1d8fcb83e7fabe30a07f387961c2c15c31bcd438e02e5c06ce54aee05e61d826e8010639631a7ba245e146496b3c685b13ddf69cd3d99bcc85b7699fc22ec93a03835bf564ccbec59031ffac2ec27087517d5ff625eca2068cd6d8c4d6d8ff67dd4c9930c581c1a94a3021f5ea7855a297c7aba4d886942d1a712fd643f4c1b98678fceed14195f1002c1030d8c0212d9ac92e7ea75cceabd6075493edfe8b3b0555e9d361ba5726567b074020714da5776964ec238b271469adf45fd55db9c2d221f436b07e704859fb9d6f7020c30e98a1273b45596d360d4da13f52ca91a9190cce26ba173c6b4737fde42ffc776476d30cfe9dbca217332de282b4e30eb5673351e46bd02dadce599e4daace8db54faa766fb905058096ba442d99e8c1db44d361a11d706ad811924c0ae2bc1d8aed930cd6800cabc9fa7f68bb478ddf919f19f60cc42b0fd9ffde82f7955cae60d689b5612f84f7e5cf8b37880ffcf00dfaa8fb1a448aa440928b48c7c1d371fd36574efe94e05a889ec29cb4f2af0f3e2437bf4d4d5691f405f26b70dbb19c2ddfd6a28746da6517588dde437d0d9f92877f01f92da7ed5a41e13cf07d881663341c26937bae79a6ed3efccf82eae8f34393bbe4f7c0d52e5b7ff74d851c28306582efc8e7b3277a95ba1c1d11cc623c684363a4dde0f082b8e0d0f20c60d5d8ff7be8c7a6f6b9eda8ab2c2431684dcb6613e76ae4cafebf979d7b0ecbe43bb8b65e1fcb78889f40e78ff7b197e6c78f03f1a76a79655f56af4f89be579ffbd9a4e79f30f09b329deac795eee13b12c7e2e1f8ec4805ac63e71d054dcdd74719efc65482fa27c4a3fa7119f722ff232881a59e6ed35a6ae0c1a7ea36f6c5aac59ccc3e88763cfd241f6227eed522d9e21cb75ab45485cb59f04c796213754963e68a71c9f68ff9bc24d9dbfcd919d1b8533938dad03a490f7aa8e12c03896a670457f2f14e87a0f9819d4ce571bf65a3df73e3cc4474b4ee314d93d76d610e8b36b2e6b38dc70f14df027e280587d14b96c9a5a49487b1b21861017d46cab69aedb094f853e2bc904fbc4d966cb8516ca3fb37e5dd1476b4076614a6fabe611b76666fd3a294fc81963817ce6b75ba8269ce9add799a02f063eaaaf35767f6e2c4cf6e6d60b5d2b8764f4b1405e2c0cc8d103638aba8b1f403effd2e05bf30446f0558b6cff7ecf3718d860978d75d33184b5698909d1e8da0bfc5d098b68b030f65f5794a1d5836d190933f026ae66d53ce848d2956ba9801eaef31be501319e06b93f096ff96bd65b850c6b596d0f6251fd9140ae93fdcfac493b72fa1705f435cc086c4516a8ac061c445617343ffbc9d78300c470250a4f8b2fa47300630f4c950a055a3c96dadd99edf3da55346c50febd42ec894dbc18bc2c5f0f281e3baf5eb3d1524fe753c98cc64a337e26c3ab5ddd30aa84bd8dc496d107893a942ac83d9dde211dc4217a0c0b88357c781d88e2cd03ed7a490664e7ac84ac0bda840c30d570b700a5c3f8d9fe4514cdb1fec3ee61630ea13745dcd853a96e6e45618f64397ee4cc44220457a980c662468314ac5850356e94763c2562b1c08722d4391a9a06a03019903a8b989e4f8c95610fabadeb13618cf2b22a808b6203c37bbf3f94fbe8f956469a6ac79a2ff8e5af0f7c5dcb9554679ff3a1a71c12319e6316132fc5216cfd4d658c4753be03972bc512d34ddb4118164a40cd772072c71ffb480cc7e609fc56939c6ca2914a990bb35f898d1aecc4cf778740ce63f2425206bce0461f382563cfc7ea3bb8dfd17d807a7c494a4000b2477734c52bb602f78588d867ebd7626d77842e6175004bafbbf4469a23b6ad1dfb2cae8cfab1ebd6159ed8e2990ac39ccb8c7819a7c305b15a0a32f3a734d89668028928586a19728e1db59374c5b5d1c7088b5d537712c491a18ce60f130ee1a9c3ae66264c8ef5ce509484153776929e869b3a560bba09e7d2cc17c1044624f13de4860f9fc2fd8d86fc7ca3b978db9686d7dbabb10d00000000000000000a70af0100000000dbabe7b0508844a7e595437e1215bcd7d69ebb16a19613a91f3f6b3bfdd497c34ada8f4451aa6b0aa0296ea0d50d632fdd490c62ad1f3582dc8f4d8bac9135c4a7c4e1828891176eb65d7272da4ac964894acee33778c34366a7ad4371c5cacf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000481da27c160d528e86164065d9418e10f0f55fcf98078d3bff93b4ebfc174d90a1387aec8e5cfca053e935d1a018a971de86200c8a8a89fe2a62b0b3490df118f35189811f089f91891228f73bd5e83874d49d13db5e2eb1a1bcd8ef5fa75f92ad1b67b55dd07e2c4a2cfe1114a877be32586c00b59427fb5ee007fe297e4bae0319bf63fc89e999093d96f8d0b177c324764370ad31ae30eab65e1b434ec3806a032c99ae8d792658862f14d3ee8606f643a2b418a149acb64e9a2bf1719ba4be2d0a00c85be13cde4db126a154fa6b8b5424eac7fc7a9ab90b61e0fdc2f53f75855f7147d939ab9c4dfa3f4ca2693aa092cc90f2673b49fc17483c5db5f8efa377b1031231644be6c3395c14d312b6ff579feeb89add5ec9a5fa8e6b290a2bc915b97c03199e94e6d4fa1ee12e0b1df3db1b42b1cfaf9fd5a1f570a30d39eb06f952badc021311beff461fbe49660eed065127134b28b53b7216046f16cbc013f996258243022ae7f7e277e459b3bb058d93923be6f64682f68c959c3b8e9e65698526e486570300b411c4d9bcb3a818fe24527ff7c80bfc8cb2b63cfa43cb76a9c76624053f665e680aa1eb912b13eeac384bb29200e78aadaa05e304a294bfbd1d94c02f16ecf5e4a96420405f4124c4b914531749eab110f8f92cb9b00f117858eaa5173bc7d7100d4567877c47e8fb0b3f411e3bc857cd2674c6690797cbfa4e042e5e03c13f1ccb0f3c4f701a7761e343cada56916df3ccedf437e1726ab747e405e8ade40fd0878f213bb7afa97fd2c26191c93138e5815d4c2041ac2c4f6708b802b9c8b8e571cc8766f54487e631014502aa53909b8fd3cb522dcc7b3c41486c8ee5964979166fee2fc9889fe309cb907bd15e1ac2d92c2ed6c842436348b0e01964ac69d4ecbe21137c56e8ffbf8b7271fd963dfee3d3329b0b3eec87c158f87b21825135439e4b55a2807c83c3f6b9452ea7fd38ae7d52e8f9d74ed248ca273d47943320ecd906b7b8746765a8581876d564b6eee2079a389cc2b4f0d77b2456da4c3bc5f600fd83d608251464f14d0c1d17a2916bc403105c6ce3bfaa251dadaf77ebbf4acd871c91d5307d84aad4f3116d01dba7e97d751434b793f15b5d80b0c4d8d49808139b20092746aee72ac9689b12af8c90ade54c8d497117ed7f28b03833d629776b75a989757c12558f66bd09145e3fe51342d50ef3e004728f9461996e4aa3d70ed8ad13962079c3fa2742e84a72dff4c8927a239ab280b3516e043bf00997046bde966c4fea2627cc4dfa4897ab5f2663e516be6b73739315b4aae49a47adc79f3ecd5f274598ae260f16d13e2cafbf71f59da044163009c571d49b1aa959678267b1ab54ef90f3c734648536edc06b17474b173adbc101a59a47885a9eae902978c112e279e0cf01f617d7ab32b61b9cb70e287552622e77360eb95d27e1db9f83fb7218c02f37c289f32cea4c2e9d7885afca51a40bd52cef9a1426c5b9411e0c11866c5e523fa8dd511754e585e63b1f0676d1c49b5aff586e79bc15d51010df4839bdb63e693bd49ec482680f15bfb62c8f25feb28e869c2fd4f88b4362ddcf8cd83db02b4bd1792e60b2aa16870095ace02e21777f2e8f5d9b75691708e557e001349d5c01acf595e4d09ed2ba6ca6032eeda262cc7860c04c1231fd223b36f75acf36ebf530dd07adf06a742b9beb3d41d2ed5261652a956142c253e91dc915a83c050f159555dc7f6a516e5e590c3812cd7d467803913c093e609133d0ac7042f776472a090f919f52daf942ff0bdafbb8b3ffa1238eb63ad1d569aeb4d65e1136e006c71187816ee9f80a71e68eb09129e82c770bb9e3323fa2217712d0d55d7c91744314e76b9162685f25b3cab1d0be2f3e7e185c0172172cb8f0091659447d8ed2e65c990f8b68268a1defb4b14a18aaf3748f7f052db73a02f75831fe655554c9f56625f59d143c6fd3c18f40e70c4961c1fd45b32f470b46e6588c5a60c3aa3f4ae70f3d2624e9cb68b64f7c8c39562293801c24c7755610102a64a715117a9526ba8c18df83bf22905c9cc1c6f58d6f7466df17714817c65d38b79b823e49ca8412f44be2792804d5e787fc4ac9163d80038ebe840da7737bb6b545426f105670fcadea9d1816a0db0ca60cf36a5bb1b1211240e1e106e3ad740427de2499b3cb844acb19a54abeba2fca872f2a9a4adf96762f95af5ceab27c84fc9f540cb15d64ea68764d32109d83915a77d23d1467bfa3cc558060af999bc644e732116c4b20f162940a26bad827b86c9431c7d9f895e732530862d7e1621a16bf042ca6a902b0eed1f69b26558607e138311b3d65198c615af4ac3d05c9f5f7a8f6c94e8d8b67a728423c77e50ba14f22d22dd978a51c6d96379dd7553c11efd488637e3df1e8f200b605", "525353525300", 0, -881952397, 1537743641, "7b71f52e8bfdcdffd88b6a25f21e9136617b96c7d0ced1316c9afc486560724b"], + ["2eedb57c02f1f4fcc503dfba2af84264bfbbe1e5b5f852c01f05625f34219670cd3f41cc30000000000600520063ac6a8d06710cf49351c44555fa07b019d971fcd4d3446b0c2428ebfe137af8c7d7b4a3cdf6540200000004656a53acffffffff028f89c40400000000065265656a5265813c4f020000000006525151636500bc2c515302000000000000000087687105000000004bbb6bd7b3a8b21d1431f306b7bae9879829afc1bc18b2ca0c45b7ac3cc4f8863b69c1e4471f02369c50c699584e1e03637f8d33d022ea4a95b350f0f5cb67cae7fe8ab64ad1ccdb9cc346c1edf79b614e596faadf787adc9031e7fe7fe624e900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2de90bf5b21ea98499155697b8b387393b666c54104790bf6fa0a52386aa0fb4d51d2b69844f4951f1b2c97af5b3485edb9a9f481ecc95ca2f3d93bc796fb0b7eeae2193766fd081ecfef315d9ddf3d6b6561d3ba1e2862c3f5ef00fc69a291e318e3db8aef29ce06c455637274ff61d044b5f7f3899158431db9771ef285a1030308ebadab22474e40ebfacd56b9c53ffc36da09f4504329f753d3b0aebd6ca20207bf1352ec9cae8244c1f5a63db338212a76606255727e5f2882540a2144db930a04724ae62fe265a93197ad28c99bf868c37fd915cb386f201ccec07e17b602d5d95aa50f410791c06c3fff1837efa00ee98f42124d2828c0cb617bddb176e3be0328af4ad93896d6e370c2033246fbf8b88055e61b8e681dcb1b0f27f6ebe9a94e02035427954d25eb93daaae98edf77567ac39653e4f1931e5052e4a6527132479b03030b050d1d7dcb444d58cf85d05e72d0040d091db212867b622da09a832a738b030677fa922383d4985b70f759cb7f257c2f05468fd86b8f1bb02fead40ead9f780216e8aa5d42cb9a1fa3231b94e4ebca43c97c531dcd507c5cc627d3bae31514d5a8d6d346fe1b6c0b44d364cad82eea6504f65b82369ae4abe4f2f3a29a551e686ac6749421858493645741fa40814a54f6a190fb9543afc5e6f4427e190be30f3a1eb5bee14b0dcbce45caac0d7b616cbeddde70565fb134c105a5409b4e8ce9cdd4bd4e2d7e5a4fc2699532fbae6ff8c64a3154fa45cd205e6d22f25d326a182e851e239765e238aabdbb958da585303336896d0bac499b4ddd11872c4209624043409d01bf6fca60397b8540c3cb958cd2bd3a5cdf5d305d95f0d767535e2a6ec3a19f7e1de77cdb3e8eee64562c5bc6ed0ac553d1eb16511b123e99473158d21c725affedebaa42910c8987fee046f6684f7b1ce51e3363fed46f56b6dc1e5939b10028179d7e99e490224c643e5d7133e6a53e1bc1bcf051b99886ab132242c2795f9990e6db8cfbab25ba3d624f676ad197abec186ddd185f10037f5610a5e74608df48e984e2062b278401bf40c04c01035eed241bd6972500c97e7a53fbaa33fab301dc2cdb9192772af01c52fb4f3cc15db9c9ccfd553ce96fc80c56b7b7ca3b95506fff4272ea38a5c08dc2ca5a38663244d5ee7244b148dbf9cdff5bbfc0ec20382690ce84ffac5cbea2d1523e1a772b6e9853250ea1fb9b0c168d95db19ff57446596333b2ec7d55e647a716dab0e9708cab2c145b7a3decf70921b4dc555b628cfade9882ae17c3983c62485747b1f06930581aa93bf2be6e2a4121e9210f27a6c1a0957f24fd78c098930abb8aaedbf95fda7d8bbeafd76bd3beca3b18fdfe84ce53c33d02396f25bf3f450ff6e23818bb360c670d94a6cc49f17151039c3a0af5f036945cd7b11f153540d0f11d5c725e0e10a6d3af09ab42454c7ec8df7f24b386cc90bac812c4c0e659b7fbc339f77ff0f2306916ade3458359f70496de690f4e6fe1e9171c3c912c87597e6be88cf6a2bbbdb2256056e1c51e6b31bdb65d5f868280bdcfe77cde062b0c7b88876e710ed0eab1a7fccbb4b25cb57780fbd744e89dfd0cac4fcba58dd33e38c895646cd178e35a36784a8484912d2b0195919f7bcda33090ae0d14c7010b07c3f5f39f2eed0c4b929719b11215d2d3d0acc3b9963adf4f960d8b16caf5c1fe821cd904a36e652f2aa384d46e9df01ca912d14447b731b25d30ea5811b3ec1fdde2687751918149ee790a120f07885bf12ce4fba1b70a836f8e9b2abde0f7cbe3df65fc4ae01433bf9709fdb2cb1de24384a48e56c3a72d64717d41e796ff103cfcb845703f881f65bd7982a0082b30f3a68f9f70c5da64faeef5ad33f2ec263cfcde56c18b80fe8983a0e68a833a8605b71c4d8b47565d4689299fcd56a071907a29a45c70b803b26ac092baebb48cb23779c074f61bab661a69e6036c18e186bb01801a60f730c1f81990458e3f65e245ade9f9f0bb28a68b0e28e303f213844cb83b48ab56b5c433c34eec4435927ea7f9d9f88587ed1f3592c5a462909b8cc55cf7a74e852798d6b8982a4f165a37635befcfe3d794428efd50d1bfa22f2470efdb6df406296d8129e11f8c124aace4a2107dcc2e9bf6a6747461613f08899469086be1f6342223641612e2c2a3f1c40abce6aecd25c4ebf66ffe5484242792ad825564cc0a51c6a7eebbe4ff61aa30367f801841f057297d25945aba4c4d41c8c3a3a60901cd6c861c76db27427db0d7c5e1d720d72d4c819225de90000000000000000f262670000000000cea4a8bfca4382911cbf87bf1dd4b21cfe7b93b353d226094d78de0b46aad8f9b0e0fd8a17ee677611b6e89313ad265aad1a8991c3b27b675b052bc6fa0d526b5ecbbda2e0cb76124a73edafcac55702104a9aa89d866ea2ed7f29baec84ce2b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244a55efadf34675e47e4a4ce42c4577671d69a40dd8fcc37c1a0737f45acc39da79d265c056457cf58249c4c65db42396d3cae99bc0874ac247735cb3c0f1255f4ec6c9f6ee744d374082cee34ab8569ccf17d53cca9917358079565f810d92156e9199657778eaa89b56f704e46cb97b9a34c71dd3093588369db7737800802303b28b607a20f518a93d79fcdf6ea75c3a2aa7779dd8ec6a8f1d5484fc13e07031f9684ba5f6c447961b8cdb2e19737f946db57b7e128eaead366fde10fe9d6ee0a082d67e71c9a49e588de1eea19a9fc8d2c007e9a86b8e5bc343fd060e5fb98954ea7f1c7f74c955caa948c5bc341aac178999d6e5f034ea3ce18c478bbac2c1e021666653b7099ea504765f0fc0e6cc5fc3397492c48e60604e0f4e5343c4762350203e0d481959f95bb482e7e0d22509ac9a7b64d98efc182bb45b26a75039530ad03021f30999e598788580bd28eaa3b05bf9bc05b1ea998303e7036b1d50205925c021ade0d01e89e6772c1e5efe7436638dbd4763b9d4c8a756b40634e559a7228a8031c843f40cb21853b3977a2ad32872740d13220a6363788d4d7e884bc912669e70f85ec7e321860bb326633f70bd4d55f36b45c4e4378602c9ac98d064d8a6953f7ec6653d5d8f463e9f373dc8be3d4eacebef24e7845f20aa1fa1f03139a98940e5cf9542bcc6e359df0456d937922a8596565248e22c3fe1954daabe56fad304546079d3fec97aaa7b2b66c86f75c3cd0ef546819d8d61380330625cd7527adaee0875e9ae2d6d3a8ecc6f01feffd8c17e9555fd248e195ba03055e3ae10408075ad3f3722db4f74503523e87802acf67a97147a2e1b333e98afb2cb95e6bb1f3b0ed886f0e3861de2e2986d7eb11bb847776d60fd00e6cafc923200fb13e17f59ddccdb828d525bca22941c87f160ad3a41b87db8d2f258382ebe4aeaad4dbee05c0d739834a836397fe7a99c7b787979cfce436a92c02ed3101a5c2a7ec7c41f4a8b2d1901dcfa6e8bb130d8817c496933c34079c289e00a42609256c4684a7cdeba4a4e723531ccd66597e41a81bda5842fb1238b6c438744f67ee7e048d16aa1921415faff8bb3c12ed9b561222f400c6a4869ba6dab225c04883ffa59f1d73d703690319633b641ab3e987a84e336bbaf577d58b623933cbdd2b3b36e7d1a5fe2ebe208944a52836683bf4601919b36e44e6853162fb60037cbe45f861f7bace1c47bb29b26b98c2730e5ae87a2cb9bed61e9f1e9ef75eeee5099cf340a070298183c8b2f554bca1a4ce0b10f0538888e3d65b477711417b9809b8cf3abab421c18911a84ece3637cc8554785052008630c67d5d13e4d41d470213c13cc1410f2ac35f9214ee0a057786e5b06c7b50d36679bf56808530c1a67101603d86190374feb413a891b2188e599e2dd2f8e5e7685630a2a24d17c0b540d942a99db867492339987c4958e97a8840f716f2ed088fc5fe1efb8a873d5772dfd2ca26cad06845be5f62560b385c41bc33294be3c5d4293ba3a33dcef46ddddbb6f048f66cf371fac7b0a8282a6d71f499a6ce7757fcdd4b7bcdd7ec70133a9ff1a1dcd336b8b0314c8d99758e6312ecb48c539238559ce1652ae8057ff787787a9d43c5a50486215e9f88550d0209c521ccb2658b735665fa45d3668fd3d702ff6203269f48f4f14d2b79e97bbf1fc2a2d231af50990c5ba0225a22de6ad0902b758fa544c9d51c9a388a7fc2b7d9320c99ebf05f4d3f83f414596cf9b849e917637c9c6baec0716f5f74a518fa2d5ada7391ce2c0b41e8472f779c75af663a54865efed294176e4c8d7bb5d8fd341d5a94db603d2ce71a897f0db9389d42a39d8e2e0dfe2b21c9b044a3b3ce55c5618a74d2d7289a6d603f55b2571759e24d3353fe4c4718c37e835e40ce642ae480476568b1625080210ada5848985f17e9ee49e80fd5bb0e28ffa4fc4e68efe0811bf8ceb9c7d61421680849838ea7fc1d87f89b20d91c1683399be74c0ac1927421987779cc334cdb7d7311f4d76b828c881dc640c5013c4655f8f3310cb10038cbbf0036a97414625cad529c20db8dcf5b9f287f2a0b75453d400bdbb33bb0edeb39dcb67d2d503d17651e5e872a1679ba0bca43100a38d7683e041b0793821773dead55a1d1b910e250b211e41179c367047c60bda540cc9031fce258b57dbdc60f2c1b181052682ce8b6ff1239c938fecd8f68b28b1c11b091b47f4ae314432c434bd38d91853cc62cd07bdc813848e7cd283ed8456fcfb0f2a94213887416ddb90efa1a7b4d51ae92eabeb15afd1b4a298ceaef2645f7fe6bd5ec65e988ac7ba8cbc31056dd4f4e9e6c678a7ec942664e73924e4ae4c74dbba9cd49fd87f1d19a39320cec0c930bb95e15d22afad720dd4e25ef2242d50637d13bfc4f6919d3122204", "636a6353006351", 1, 1173042975, 1537743641, "23c2da6086703cdf4e993bee0a4b9f0496abcbc9b769853d7e9ed6695d5c29c3"], + ["0bb4ff6f033cd6f0b5ab80b76fe4901cd436c15fc6a2b60607f3bc1a6b8af67f676d640ffb010000000151ffffffff0f4313e2bdade04e6393d4fe51a07c443eee2aa83a0deba2949ef84d08a445fd0100000008536a6363656a6a6a4cb5d6df5dc7188cb4d5c153c76b0a019008a8ea7e0946e004b1978ee30895b8ba4f3d1e010000000853ac5200ac636a63ffffffff04ff66430400000000035151652b29e4000000000002ac6aabf699010000000001ac11439802000000000565ac520063000000000200000000000000008d5c880200000000c59c3c072ee46aefc5e481b46524d36e48f18c6735452a9bac87411de2818e341f7a0eb02ee3588f9be55101f3f29047740fd0bf2da4d592e00911d266ee1bd2ef8f2feacbf97dc3607e4f20875f86b36469f60981c9357e4d2f2b06ceb920f900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028303cefebf0124c1e3e135191aa76f1110e1e0ad3067acc5a3cd32d9ed6f14d7a8d280015861c47db3ff961ad02864e576b0b0810de5878de8f26e15d8e390d4ea4485b5406cf3d8e2bc6e6da90156b5990c022de767a36f04faa34ba010858341c0a9248814bbb5b0b1a42d2e99e390bdb6a4a9bdc27036f1935c62b5c293020e4bf11123fbe0fe9568deba554e0769b185d8a405060fb3e051ecdc419dadb302217a16d85e0b6e11599469053dbf9a08927b1de7598989dfc4f9e7a54f584ff60a03629e8e40d196de104e23bab9f2b1da30c7396dc5b059b1c94671c5a558a379808657b6a42128e6a54cdbab46c1c872b0cbc2d74c00db6746dc931d61aac943031464a8e972f16c8277a1e6ff64586570551f7f8f4b932cc05a4846dff8405fb9021d38cd70f177ca052536b5e60441570796576da518c651c828ba2f00547bdd7803125f160936b496dfa880dc1e508a416e099d63e976b613c60335d66fadff1301032e4c718db1e882662bc6b725c575107e27f2c5c954c4aad066b006f89d050e8b031a336f0c958970d8ebfd67c215c1d9df51d3989e104d42fab0acfb49da77ad075f8ba0d22139913b5584c5c8b4d83a60c0aede9e04cd0df61b537bc5d558c43798b5c9dcd3903d5b3a361f7941336b1e2e71b42cf9708e17fc09bb47b407e4e9f7dbbb640d09147ef77ad57602fd2c190bdcafba1f598ee382f69e894b7c6770861f53403e8f4c2b7d37268a471ae0c179f62f4c1da9c51c44958c3453c2cf43ed7f2b09b63e996c99422195022a61bbac2f21bd786efc431ad3a44f7d9abaa8c710e9be789dafe5c68d08fe013b2f70c04b474e37dabb3dfab35ce7807716017f6f7bd84b2ee20cb1cf247fc2174d2c3898c612f1443193214deb91c20a808e07e3b335e53c57aeb424653b24865d6f7b58d2af65ca5dca502afb7575bae0d431c886c1874bfcadd693ab850c43af7c4ce72b002b897cc1d48de77c18608d75f58ad6ad4e0f284e294131d739ef1019f27a7db4e466af074e0672d80ca6c1959aa387d7aa40efab0030ce0143cfeb910a72aba85b75b36a9bc18421cd8bebf59e905a6286cc52b17b46df0a5fcc754b84161f67416f01226cf4ee8be345184ca880e71169fd9225ecdaf8589ff0af53cd74cc826a129c3cfea3d15ff453a421bdf8f42de19cd1b5d55ec14c000f77dadc1fa68729142ac9d2ba9ba282328628f63c6b06d2899557f6e4c9601805c7510140dd887e459d192b9620d323f7d00526fa72e3fb36850e32dc65d65fa0840a5a29a550b24c295af90868b6207c941a2500a089f44354628055b25a03f37d3276a4645358fad2addfeb936f72c7555831b3d5a19a6b21edb7625de3a74b95e1e7cae9ebc81a05ae7b790698aa7b516e98299fd553e83a3c6c01d0114a2aa21288faac73163436f439f122b489dbbb4fa994dc885fcf423c86286554843812eff6006fe2b57170efaef1654287614ea57500fde8542fc591b818ce4f91c20deabcf6e980b84ccdba44f58ab5ae130b757c588f92889a39ae3b7a701c0c39c027833ea3c55f207b515138348eb3e55f85bbd11a6f9932a4dfc9cffecf7fe7a62f42033dde4afa59c6b42cd0ecb148c7b48f73b06b311237f061edef1e9e13a163f243ff853f4c8add1e9604fc2a2c4274c09e360465056d51af7caf6e51ed9a3703f50d606184d84c6d1d9d0ad93cc725e69d4f102192db23a4ead0bbc240bfc7e0a4be9b3141f735c8fb0d89d1015666e7a63d358258c30f793171ac703abbaf9979bed5483d59ee85ced82a85c1a0e13646658557fec29f56902577533f30247a449064d7b4103d52edb2b158fa61f680223c1811541628799bbfaf25152cf19ac5433f8b6d1427edb4721477851322e331195c445e81aa088eb79f5b3df129e223aa53b76881ecdf802248199230a4c6db49394dae7a8cd318433166c6366f06e80dce1c3cf857007c576285b1d6e4299f7a1498ad4484ef8d2a40d592b42e238e08a192ecb1cfeced2560f5047e37e4e54fecfe361580017f5a764aab9b4eceed2d9ee7edaa081ab2c6d6957320e259e7cf29db5ef1345669f3de2d193279654200647cd09cc6ae47b300bf688de4aa67b14c8a185a10ee7177870a5ef1bdfdbf24d881837d1ca871b75af6fadb54fc19d67db9163320765f55d8f667a8d0b8d3e5d4c0efc373f4e2164b6126709858ecaf0fd15acf21cafd7470998d59e318fee9d4eb863729582f14c2224884af5f6fb224d7bc01e873aaae86328ccfd3ca4d0000000000000000bd72c10100000000deb466f2ff691167c809824bacec129d6523c23e171403c61d7717b7748247c8409cda899a0a372e2faaabdc2a629f23cb49490ddb7e65552dbd0c98a9230665124c8632b470c239d4e46bec45ade08f588ad5612cbec064156f97a44a65fcb9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009204b5c11fb9ff10e188f56e50e19ab4bc4f91a0c7f7af37c5c4cf77a9a5bafb1e84ce5c72ae12da21448a1200e9b9a135c37864ca5a84250a75c4aa3e9ac7e04f8d5b60f4e4615d335910da42e3c90c13e6d70e5c739d659ac50a6936fbc972265b74ae18b6aa65af54e651cd04fe0eac4afb1123091e24997c7eeb58ec746a020a0e8c2c65c537b4704480a1fc8fa1c0014f2f9eb33a98400ee9b618c2e2032c020414b231139faae0bc9238d29c27432fa40496c057bd76c094866075243c44e60b04233a6f8fa50161414802289a380ccd33097af3e9157dc8db3a9cc976f89afecdb4bf407b34d35c821c70656b89d7753650cd30f7e422847c4babe72d131223021997b15a95505412d6af73f61e1034a3ccf1731de1718d667a4f4e83e8aac970020f61c771d8fbd40f195ce5dc801e3abb7c75e13bb790b52d0fb996f6b2ae032903098336c5ed881bd35445b786ce030a1f691a2f04efb28b1bbce741fdb4f5e051032dccd22ba3acd7f4f22e2e94d9a718cf2d4ddbc4c89f94cdf363659cb56eb42e0218cd58ba7b1ba5cf81a2a4657cc43c2a7b11f24ba2a03f5c70671112dd5748aba29ada312cbce549a1e2a46f48f1fc5a9c29b2212ad3b64fed3c9499cfbba252712981d8b2554f9ebd5e252f5a016e48e7845a8212bdcf8973a2ffe811d7f54efe6e34c9f0eff2876ab6044c3ee53f4b73cd3e441caca6d77394ae0456dcdf29628b28f57de0099d4caf07f72e3f34ca73b8d5404745cf04ac2bfd10195f188f3d7fadd172400fd8c8d7b5de7620719b0a9267aa1e2e85cca02f4e52b566fbf2e91bd54b3cd44d79bf7d9ee34251b07d07d0db63d1586d534b1a887b813c5553ec8661de9c79d09a863cdd286b25f0b253c585ba7b2198ce8b393029d63eaf2c68f4c656b9b01df8a8adbfa5436b893a0e8f6b2c3135e05abdae6911b29d510b54b1f19de48cf92d5d7e3d04ac19ddc85ff633d3050ba15037087160fb3be58a4f05c0b4ca5da9e4d803be13c2181f35badcfd12c329c80d885eda0314a2182a116b1e3bc66db36ecff2cefab4630ea4a373fa458faaf30d3801398952250d5054aa991aaf412fb1c11c15ddf0eee3f446ab96f5878ef98cb74146c83f64c535d9d9b85f3cf374f70e25c4aa34462e1587101ef78197606a075be9050c575d31a6038553f41ae0fa6783b915fdd7958d0b10d70d51fe59e8a3769518173fed39352f91a171af04f0032379c602ee129768a14c992744187c8eca7a8bb7243a3560de71e329b726d35b287a823bb6b6bbb7d324baa74783638b7a339e27adf7be449cab1f7d446357043c443b1aa4af193500162c77da2034daf1353671fda6df35ae95dadf50454cd8873f5d6801c111f37f574420bdce860805388c688b160541f36f4a3cb94a83e5372180f806d8caa1016f468df7ff06a98da1333501845611545503b8ce35871d396a0656aa67c6cab8acee8783d8a7394a808780c6af253283c240714db67b0cb08c479b994571b33477b87e0baf3fb71e729be01e320bf8cd8f160fa7dfdbf8fb11fa50cfc0062279079742b9f8022f76a253992afcd22b869e6825decb21e436756249e754042bf17626d408b58384b69dde867455fb6f85fbf3a8ba26452bdf7a678b8fc3f002664887231faf71fd5e0eb8942183d66ddde7344570e396fd9d4c24d5aa5bc1938ceed4be9b0e0945fbe166891f8af37b1a8af9d60b749a432879eab59a505967d6b9024c118387a0538007c6e7a488e36a49b98d8ce7b4789f5f5118085fd935252244b74af7d84a9ca5d1b12a21e6012f491b56371f90dd96cec7d905803343aefccd05b2ab7390fc68f1faca65f4660d8c965a6472dad1e8e09fcabbd317d7fa61ab45fedda9152ffbb721f53f0374d590a57c2ca2b67a095d40ca1fa2a3fa25394fccbe102e15d5c54939996f67d3d7a08167446f40bb97de02cf47f13879a718c50fdb27226598d2e905ec4045cb36f567d968618189db23369a5e404c982a28c045087893427270d4c52b6f2c86f9260d5c0afda8261ee49aa93d6e3a4f0fdfb2cef432f6962445157b290d06d566b12c0adda713adf8c471184561b12f6ec49e15a2f425e4535a48c50daafcd3b601022f4ad08d142fb4a0b5274c6d47c3f33f9e374e02b68c5bdcfffac08f85232bcda2bc71295f1e2e7508d035b4adf7e88a2c403efb52214f4875aa4d889315e9044c6368cb9a1d48ef6f96e7fdf4a7e703ef35d4f5a6332bb4d6fc22f1f24b4f663ed89cbbe50c12af61aa9a8cd4c4a1d4ea55223bef5606203aa80ed045e6fccaaf7464187a6590bb2006be293aa9052f6fcd8e47c21069bebbbe7f71b2c6a81a845cadf2273ff2bd9547547e7b648c6629f83647652e43f8c8e266daec1103606bc9491477ba26903dfe820d3307", "", 2, 1091925640, 0, "5689c31260014ed91aa0bd06bc914e8b90e4702539aaf10e812b1d8b9b71a532"], + ["f06d6c6b01e2a5d0336723a64dc7653c16b7879769a8a40f86864703eaac71e792f8e19b940300000004526aac65ffffffff023f5436030000000005516565ac65afff170200000000025263000000000388ad730400000000000000000000000084da4eaeedd36c666eaea9f92b5a3154cf167479efa952ba492928dffdb8975f5d3117e6f1f71a9d43363cdcfe1e82df2c78741611940b8f7cd88a99e84cc5a63ceea395798285ebd069f540721f62362c0e8374fdfb1b5b7ba4dd3d1d6b298600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf34e760b08f7ac3f4ec6f4aeb2fc2cf806ea8f32841f8ed744c261ee206872fb97f809fb277b39887db883ac51cb25ddda5027b9fcdd0b92582b1d59f54e4d6a1b5a51d4ac06bebfa6a9fb160df281c7bb6d464a6902cc64e7011b2284b4d9bf8456280453ec9ea044e56c9d58602ecf07fe47ebb19077e4ae509a119f53c41020b77bbf0b2669a4ec1368639016aca6e7957e7d10aae8a86145e0843e0c9bb12030527e32e14660271f2ca2c4db247576305d3653e2485c8a9d5b6880543df92ce0a01b22bbb9cb06a6e4aa6b90c4f91a5de763e88467085091bbd3ecb71a88638b72896efbab8c7873fdde5254f1291e097f98afbda90e1c8ae6bfeacc0ccd4103a030e6da7d3eea5d5cb823a82dc4314a090d45cf7082b9e25dd3647323812e0eff0032357d2c3583e8b141496346ff2b2b4b531dc0ff6c05f0c72af3eba09c1f214ff030ac2e58ae1b9d645c6b0ed95debb53056ba54c583724257f14c48312eb2c0a8202210a4febbd2acdbac493f640663304b7212cd8da0c2c06788ec34358a0704c2f031714d61fa63001b74930db5c601de5213a814dcfc876e42da7ad5e31bf4abf220c58389bb9512c7b0adba57e2bb9ca5fd93ede0d00458cd281cee1e612edf7ec3ab77b2d4d732c2691e4783d2a7b5ee3ed6c67b3a58ca47023f13a7c69a4e2a3e7105fdb7cb3d47e87e06eb81d9f1aca7d3a8709b384d4d8748503cee0ab6dfdc314ca65be19903f84b8d8d9467edc921e32e767a6dde11b2822937507c7b46df340c8dc8bfc0ca5ab3ebd0782b3051b3802a709d76f43bb6cfa1e5d748540f2befa811920417271a9db1f40bed09d92b0136e87dadf4fa31d881086937c8fa5fdde53f81257de448b5e70408df078f27b156c276720a73d88baf7364903257ccf31908adeb89a55075530c54c768b8c5dfb85e21ee72aead9e02997f8c44acfbba4e42f0f45ed35d834654dd7c248397db0d76cbfd45311fe6c8b8cabd30d31564e144374c1702aba671a33acec90bf65fc4993577d44813e5695aab42dcafa99ea7c74494fa6795efa18b9794c3c237dd56958178fdabd418cd46af4e1e14ab6512ef1492e5ce4e7128c4482aaca2b32613cbc21fda8cb515e1a20bd4068e1827a48c4cd658baf1741b57e2a74fca16abc5a925dca8e2d0b631f8e498acdb0ea2cf0389fb63cd3c6a35c6ad8fa1175cde00d57adc98a20dfd179f0e650f25c6ac90adee4de149ea303ba1dc798143268049b0328f43b2b67c402aefcd8a5baa1d94f014cf44a6c0676c18f835dd152fab9c1a4551048a20cb9f250e3621bf804eeae9086716fbe99674879b1fbb86b7bb63f3368d74dd1fe772cc4b89fb9bb39eb48055af50b390606acf7802516e7f153f68bcd1e77ed4c3ac007c90419f45144ef6b385e721664afea3bd970d5a5472e271b6f91eb38e578451a46bb936e8485d35bcddf877b38fcea5456d26dacd4c33a78137222ad8e54030a96778a8c6a820295a3a4afe5a63755f86aadbeb75fe73bd8d82ca26d01c071737572a10e51cd0772271c70e08d821d7df2a63f5eb9b05cd4e50149e31c6ead871c9519d7b41c434bb38a75954fcdf4a17a3cdec1412874150ce0aebe9e7c4957f35bdfa38f700cc90ecf3837ee1647d97e263b7d3316c4f5a2726668112e8d570242cfb52b59934accd3e153c29ce9f0eb23a4a8bb923f9e7f4d4f10d18e8e5a6362aa4d171f62d14e85d7e4778a0dc6bf404f9f7c90601b1eb330458e726dc064b4e80030eecfcd8a46493f4d5caaa4ed50562f50cad1bc1ec9a9ec1f78d0969800b5b1e9de71cecd9f8ac9265f23f48702be2db82d84adf288091c3ee427461d0a65a6fc5d430c48d717148a147fcc49bb1bbe2133fd573a6bbbe3e44393c3dc4fabdcca0d6fa0cb3a31230da351af29cc11776f450543ce583c8ed2c896104768621ed8a97b2177f1427020f94df91004250645ff189196a863fba2fdce03724549229268b5ca361f40ae78eb01df4c8627daa927331714b0555a153c56ed2d00d6163273e616aeb52577afb029c466ea0275a852fc0d417e3a2cdf76975a885d680f5acadb601a1e6fc38d270964cbc08a554c3a306830a1227a795f8fe8ac00b962277d8bcf91be5930ee1224c1b105d30095cc7e61c7c307bd7e62fb386bc1a610b5c21c73a1f5aa0aa9c76fb14d887c1cd7fdb896b859b759f838f1f275e12d9f7ebdd9ce77e2047858667ba0c2a191435040010c5002763d251c6b72fe8f1e102a31762c48a12f7d139b03f1a35938eaca914cf15402000000000000000000000000d2c808a9b861dbd30fb51481a76705a6190108ab9f2cbb4d37df02fc7029a8bc1067f89e501a8a212545d01c51958ef326a7b0db02b13ddde5244781815d907a33dae275263500ecdb49ff0cb6adf2abc22d1c37d18c8fa75915bf5491f2013d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c50ae3d71a8c3e632a75df524eeea1a0392b08512ab794008feacb398da99a06205fe02aea23c5e90115b9a24f4b3a5388968fab2dd136a438b995a5f688e26bc4151be119905875f0a7d35c0ab7e381594e44543e956aae2396eecde7306f4b391f58be1dd95de944fbe5e9b436bb3b4b540b059933edbcb01d19015a0e48bd03092c5dc17760b344275d41d3788325e89bc822a7c68aeff9f8e90eb1e2a5c762032f6c661e9dea37ec742c33fb314cf91d86ee3991461a1901ee6456af01d8f87f0a04519e4d69a01fea61820f0d14e5236ed3cf8409681109c7afa71633df5e80e890768891c89315e4972afc373cc87e5f7c868bed9097d875a1fcaccaf920a87c031516d4d6ad7dd939090b3a795a0fe3c1d4c0571dd250d97cf41fb6a488712f97032475c07d76bbf44a06d3f073cd6e64c8cd71039d046cb785bbac20586ad8329e021abb7378705789be467503cfa89a86610023a92692adc6a2378616e93dc586ea0324d70de3f385154ebc641f1a7e8df7a45544bb1342c8b1ba4e4bd18f0b341f67020caee07750d5bb7b51cbe56a683c47892a54c2ac42cdf34fd24de0a811b5d3318fd7844df6dcf9812e26d32475dade61ba17433deb4fc85efd1986d121414e6b8794583e5b7ad82f0bc8551ac3f55b71ae8a85a3ff270f0d0a0c4a08e221630a8bc75dda4133dec2f5fa3cf1382b6599cf44aa8ecae7283a90a158a42db8624b6a0eb6f35539162892d889fa83349b9d03f879616a2699b2eb70ae901530ba16e444b31620544a525f142b29dc39c473ae605c94497936809cd4aff16bc5dd121014c028cc44003a7a60837618b82f9e1e613807cbed63fb86a59c6b88dbd02e2eeffc4f2956804069c8777c5e78281b2d6ad7f0ae349d58ab7fb310e819488dc02219e7fef531f5a71e6c4e07487851277804fa9e0b1cb01d0c215d9c6e0c32d04c622f1fe181725856bcf9408399575f0f445b2e3fa84880995e9a9d1b44f33246e43e8ecaf6763b3f8837bc7de1b42370f433663017dd854f7cd3e2ad6a66edb6198a4afbf50a7dee966f60b0c3b684ab6611ebf858dceda4c5faa29e6cb85b8b947bd688cd57ba64ded8ff00920ca79ab2336c97294a91bcd37af4ada74c256d77e17b529f17f6ec36725e3910645b12e6caeec68ed75027c307c44cf65323c5aa8627f6aecb0afab24289847d50917a346d5843798c3fcd05e72183cb712ced58acfc1380e6b207f0577df7cac16849f670d134f549531aef0839a1811a2e9b02da7ab1b0b8c4106565c133bed10d3abbfc51a07f22b8dcd37776b14ddba7ebcef842a360c1d1492089e7f2aba3cfdc21b45ca06b062423a89b4849b9cebddec86462aaee6eb23607fca4b2d109ff308419b2ffa3d272580c57de2eba58207823441065c4eeedd246264a7bbbb5db4e6e1c12acbefc262cd64db8554bac2b39d6f98eb482ab701d061c8eb4de5ef3f2976f92e2549f00a3f513019e44a9e0a747db64eafd3d5b98e8d210595996a809432e82376724f7e297b3e472b38f8f0c581f8db6f69e58ffc3b07ed88dda46334b86c5a8f0c07d05b9ba43ba11907e40cddd25f49c76951c4b6b3fa34df6edce3db54889d8d44f928ed5ad7b4db10b2a70f20138621d7048e7b58e1539b7d39f8751acf323657c29525b57288937b590210edd4f48ca94e6d7ecf7e0e4ad0564e175a0454f6f218b3f74a53cd065c63994ad7153427bdb7958d7ee9d7a8152151756bd145c4cf47e6e8eaae9adcece05440862a43996391639e23da141741074b6f514ddaa31212f8f93f38354a1b889c836d21f0c33f2338cc9b369e24ecd8ef8a1db42a88f959a05c3f01436afeb0ed04d7073c061bd8ab8fc79bb7be2fadc56612237d3cb09feb9a80f3b9e498f4c163b6f0b15bcd8cf90c37df65b4a83482bb1eab624278cba4122dee1a56cf806b92c0cb1e079f9036b50f9ca19bfee2a5cb140f9977870a3d62d73a4ba8d4cc48ae60e793742aee5756a63a78b76bebd91db20e61eb785d13487b6f855dae6b4819ecc2b3f156b1ac2c82de957ee9f82f6e4749e40a038cefaebb244aae0e785a3aaf7fc5010795f3c68beb8087232e38f5a2ae98fac628b21e4fd2292863ba2a7bc2dc8cb13c3af304815ab2fac49d9d83c43d07b4476837b499f9fd5c4f6017048d2dfd8609c93971ee20757fde44fc554e25ff7496dc53ae47e20d7d5b43e3095f5b0a1b71cd3ce0a34ebcd5e5d3d10f6fe17fe8f52d48c496ca2ff4a8276cb9b8d36d122a610cbe1694ffeaf18d50000000000000000de986e03000000006d74ad6d768e82517a1f8e41bc6054fd1f6219a62b42f5d1dc36eff2825886dc8ab2067a33a4e57d169cf4e56f4f1703f1c475f5e71150963e35a0e21ab45ac831942750565ec2f88cc0fdaeb283861942d7181fa9a6c0c19395f72bc4cf97c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030b4c94c15ecf201e6660b4d09827cc6e9f84100aafe39d533b9c6ae10e559409174aa1db79d81c76f412ef1492ebeabeb88c1516849ee04495cec82b61027e98c811f441df02ceb4e57cfe757be8f7048a500e27c98b7b1baeee59f729ae7d03866eb9a1e682d5b79544b5b56600b67356e41248dff0b2946f0faf0a8be56d7020d47911c860ae3fff3853074ee125d5b9666462fc58a97efb67df02799109ef2022c7e2dd0d156c953797d1aa794dcee05258482891a0fa5b4a7edbc7d01a82a7a0a0463d6916fd5b027af47f130dde592899e923523aed1f99235707992009342ad7c1e329616db3a7fe6842268ec8693867d8677c024029b6c73276a26f156197c030f181f1f246001ee601bc09f74e59e064ff06ffc36546c701299c607f9410ef90329288a70e24d81fb08c4d246e08eb66537d5d6b41cd2580515a0a6436e6d826702227bbfe3c00c7ccc03d856980d529654d19d507c2ec5fdeee16327624c63fb84030257150d3b2c5f9db8cbf5a4f93b5a26cca3bdf66361862fd013df5caf357dd70217bb1ffe23a66bce22508b5b2991e0f9342c76bb097b5a5f41eb36cfd44130ed0592479c220dc19c4f84efc35a018e6264fb1f08d40464a9dfb12fcbfbe56977b7a0c63774372d40cda8b4f7bb137a1f0c8b2742ec78c554fe7cb4c858b4bedcb8e6b55350b4e19371f3637b9450345f997df55c86678b89922e9d4433b47fe2c7ca1d0c4427d2ffa90d347dff3c7ce59163e0b0b0259eba1cd008cc52448627004a2d8d270c91521346ec3a293d9d19a277369c962d355a99e643b1055d10110fb8b02858e2af0580067a367311a2d90544a1f87077ee5b859504beaf7253847920ee57c940b5fe79923d5fa8ac251c55f3f064bc08d80c7f1b9c160397b5be662971d9a9e0615cd2f670abf877b1086875bcf7302d6191fadaa08d63caa08b027c82deccf3560fafb7f4e8a1fe0ad9442c6fc248913dd0d448c0dba31172aa366dde55d8537f0fb31e67d8568181e6c0398d220fd406165ac74685f6c2f4696695800679c3b9f0fc7235a47695eaf315e848ed9aa32fb045c830f8ffcf3a224875816474ac8c9381080ba2e889d2b37e26beb97353d5e2c458f36c16c6599ebe3d3960b55e80689f8aeb22607336cc62e96d40230f51992f50033908c65becc2401d4fa9ee455ef79c1a649287bb874f63c1d40b8038a250b19c58addee27c2a4521336530a80dd23d95f837beaa328ddded6a5cf4b381e369227071e75dcec99ef13c560f2559f5266a08e14bfc0edc11d9228696236aaa2b7b0494f837e82cba80c8006cb5995703ad73b853fcb960bc71a12e19459c036c8d2ca0003940b708e8cc4828d210d82ef3519f17ee64129f3d988c3d55f76893cc031989c0da7726a5c0a7094f2688868e14a2d412c58c4a9fe78c8ffb9500cca3cb502286013101cc69b8706b258c99ad76d6f7c58b3ce38751a3fb3341f1d6238f36b760e40146732779537e398e87fb42107bb7148b57b201a7e6396ccbd781622f1685bfcb4097deede2f85d7d6bdab4af16b14153a969fbc9077ab51ebc2ea2c05805586a84f7359da3ffcb8ae4be57682160b32746c7208bdcc344b2dc94ad70a4dd3925e0119b70543c3f5fb5f3d47c0d80f4bfd7f2ec66857fa79a824babb0169078f0b71fa17dc8f74c0f908eb575a2ba20b99f84acbd588aa4cceab4068e1c850bc2423bd51394ec6d2b907a1e91fe73c631dd9deade28e77df35ad222e25c47e9fbfd5b61ec64f547ad4e4ed3168a36f1025083726950ad5c569c3aa2ac1bb94d41c131210189d3ae811d8c42c2fe9197e4feb4d2112ac4668a491c6cc68a08579d18dda04cf8f49a3f3aa6212732f8a194c65a162ba7a28fa8d1ac158efcf25c1d2d1af826bdd4d8272d51b88fd1b2dd7d20f5b34605bc3fe7f57b5f28c1c95b7380f42f89e20b1cd79e15ee04227a3d9c056a9c64bc46a58deddd2721c73afc29c304d3bd9db0d1320affcd85be7667f33485d7eb75cc8c42dba575a118464fb7c7786589f8198aca0eb90fd8bfd7bbdd7f679ee914b4bd1e01d35cb7df03f31725bdaf89deb2cac8161e62af1670f022437fc5f7d878e0840cab1e7caf26065f0b8a0c6cd530cf86a45d5da49c8a08b2828b270fad69c4cb229a924d69c0094345f72fa2671a2501de389d80fd5d9c7e2a68b316fe4e63666a53dc3ca8f669e7323cfa816110a15d17417cee7297ec3335510de2236ebaaad89a2795791db9101a74d8c477840d8ddc502a264dadcdd09736b9bd626b382ba9fe4e8270cd83a66ca91c19578c07610470a931577dde4e48361fee22d307b066b0157a5b9715998dc8c226fe550f4ecc1e3dd4741863b7f3fb1205b58536caf0a4197b4ba6129ee124927c03e65dfe0753965e08c3190d02", "536a5353ac", 0, -1826300334, 0, "3e659f9fb94fb98a4586c796b750363ed3d336bb53451f4e308a37c5648ed8b2"], + ["030000807082c40302d6821992d6ba4d2a5cb886705828fc4404a72663407229490094474e22146e84030000000452006a63e55aefc68307907d65a831164b1b99891714b211a8e557c6d7f6e35b6aaf8b38d9c49be60000000006ac516552ac63ffffffff04888619010000000004636a516582fc5105000000000151b92c1a01000000000165767727030000000007535200ac51ac516ecf99c42b1f567500", "acac635252ac", 0, -1530100607, 1537743641, "b29366722fc28eb319aceba44484eeb1ebe3dee86788d8f17e23f0ff558f6ebd"], + ["57361001044333c4a1319975661d75fcf743815af687597fc12356fd94799dc87893255c9d03000000026563726103b3391fd0fbb4abbafa0f3d3eec4e909ba9f5e4b1e746c505f670894c29b5cf53f60200000006006a53516a00ffffffffca97178886b1837157c1df36e3dd6b9ef1fabe89e59f51a9b1b0356f662963de000000000363536344d942d4eb77a295a11f6fc4020bc21cd49441ef7855d7304fc472833ad2a0f0177121430300000000b375d1b901cda93a04000000000800516a635363510000000000021d0caf040000000000000000000000008d7d1d5deac8088c01c31444baa0780ef26f7a0429a1447f24f0d94ce5b3a6649389c777692d61cd67241647eedf5f4141a36fc8f1410c7384b436790c22e72d14f8a0a48cc2bcc57049820846ed7ad6e9e482e2ecfe713fcb5b9f6f6f01923000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d01f108eb437652ad180d55a18d19e26df3740d94373149d139aeb88f0b4c9050e82ca82d2a903926d0e8c2f97900528f4c50a7f00133e0a5ffb870b104c40f0df30fafee6d48c5b6b06faec7c89e2c661c4ccdc5b35aeff1ca667b02dc5b9e92bc34f2d0996ceff5b9acd8c6e388910c59e344363ed319ef665df2473ca67b20228264ce86d7bd45437beca620334a2bf5273e6c04bf1b512d72d6a2fe553d654021877142a4cbda327c9b1eeb8eb029d247de2802f0fc8e28e901909cad4a8de640a0346eac7803ac54bac98cdafb53d440bb76fab96c9467c8b5e2791c2b6283508fc9f3ef6e23637e6d250dcccb207ce1a1c7dbeabcc37ea006f580167cc6334850213d50d58341e9e0b2f460d2f10da6a6318cd62ea0a618db030266e18a2ecd5ca020824bff7dd0673a1e85150565783961be5208a4b9773d2b1706378dcf8c60bc303118eafad62451b0647c60f52be4f88b339f162f4f6ae9998521653d692941f130228f7577b28a5acd68912d9d7c645b017906210281e58257470d47c5ff32bbd43021e1dc7c9764c95fc1840367df941f01a811338338b601440859d04389cc59da98f257211c5bbf66a1f1235e72fe4409f9c76e18822b96ac6dfbae335bfd431cb91f7d0100aa58a0acd1b2e50ad9b390bac8337cd94b0efa727e8dc6154d22dc1b08d3b469ae4af1c3ff394c68837997dbb9499f6a24f64d624f726dd620bc074f78fe0b8bfad3446c8ed829959be45836a82a60a99d7c89f527b7a559ed0f2307d45832441e28b39e014ddfaa5789c923ab97630cea16b4ac8a9e8d97955a5eddcd5e60027511026e5c4adb685160fdb0b2954ed55f12bc4f1e87566d27c9cae7c0cf89118e085277dd01bd4b93f808a1e32d6e1b220fc8b9f6164ed3803a7884be5828dfe8841fee06d6a9bade6c8327b33ab468ea50514731221c6000c51ef2e12c049dc2ef043127adac2a96dbf4b5d0425f00590540d07b596e2073ac20f76d3e0b1dbfce8b6281dd4ea3c6021fef57c4e7966c059ef4a2aac682bd0064cfdf95a23a69aa5e1e695ec817c3afaf71236d0737e0bd845824da76cb52d2983643327e2eccf62949e77935eb149882255996ead5eaab35bc6e507fe27b74547a4842c9e6cd79653ac1a9b22cf43b9a1542762b9e186eb42336a5993598dd91607b6692dffa6617716cffe4c938c7b08f20780053a4c301bf8b6c97b1127a43fab09d36dd78a1cc84ce279f93f886af6a67534ebc33f4d1cc4bcd9458493e368f1266bb58b949edbdf8423b8ff1537e52c81da66451d592fad8c98c68c57deccc2d249690c56ec3d2f491a812595086fb6a0001fb63930845705e4b020da9594cd0c4c761657bed1b45c225f873277f3fa8446564877fbbd7652d2d0fc600f1e78e5d9a633480765e197e5f0402b969541fa8ed311c675ab7e20a8475efbdea71677f2a6a27ce87bbc93e639579c68ee4b269c84c89a7960c9a1fa31835f36fff3f991fc5cde5c4c909afa0745beb0cc55ca61f758d1fe184abf0c17917f1a38eda96c8721cf6502bc12b5f0ab8b35ed6bc3d9fa7abfa8b135c10c68aa3ac0bbce71e3353e3872dbdda6d1b10cf54dbe3a3baae4f8c391fb2edc4e02ce94a4df8f282f837cc322951ad766800734abdff9f183f6339998f4af6d6e17608592b11b4375af99e5b74bebce8365cf7245aebbd0131e34a5a9193cba33e90af11252c7de65b3b7d28ccee302f5016ea30312a62303cdc2adf210c81b68e8d0f74beb7604696c8b64dfea572e3e49542989975bde53afbd94de1c6d12d76fc62c2a56b0fcb001a53853654ea29c7a9ea7f154fb2c05d54bb4ff133e1d9fb18e8b4517b969afe6a5663fc6ca35d2c22c940335ced6cc9f489e108f6b0948a79fb0eb71a88809ad5eb234f882e3db5da653b97a822beb6e8a6a6788c68df8de8c52f97f911d9a442e64b21a33143166f73815771118dc1e7191e3239968c441498f055a37d1ca11af3fe2b4996c7aaf45fd3797d084376c8edb5504e3539924f06891ad56b11e1e9d66fe0df84bccf57abf4b0dc9aad7d3aa0cc604b174a262bf5d4d8edc70f7a7eb2ece9420bf237473eb8153feb75dbaaf07d8a2611c6446344527a66d6cfde08274d45745d444bcf7a974f0d3ae53708511c28c85957ede74b37e004e47aa8c35343acf4a28ec84ffd1f12b1b3f2c86fe1bf5aa2e87394e6c674a93e81a9682c1ba6ec57a960062f8ea3178f4648098e4bc9592290c16c8d503d400c50f0d955344fe62b87a08073e8b7ff7d9d39b72c90500000000000000000000000021fb28ac0e18c2d54d1fc6d2da70abb5184176748d8e360456be5141c7ad9125fa8430b4e23c3ae2ad38e4c3e8ab5b01449431cda90df20e5b1a9c5493f54427b93c4d30cf990391333621f2e6eb8fd21dd2ae916bfb4fd1a71e2a1a1a00b0c400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cfe67ed554f48744394e2b45e2044af1b7549f4fd86fb6201edc2a3bc0a27a7e534a7582c18d6ed1f836a810ec40ed221cf0e047a6a4d4bba6e6afdb7834b7afb6e2bfa91731028d7e138864311466c7dc158db4a51a335e0f99115648e15dd28e7bf367b4d155b323a509253db3f99e8dad6d2f4253a6b610c0f58d843ccb4a030fba1901b1fc208fbd1410333a30b8858781f2fc899c664f6195d5b5e444df9903082c2262a0a53b0fc65a469885b290c5a885d1bc6ed57ac8d75f3d93788311ee0b045452d897af9363d0b00423ee009712803e2b46543493ea267d9d23a1349b8c57711bee36603ae972001f47c4ca3e82761c843abda2cb07431ed6b23abb49480203e2c604fb5e16af6253352d24eb6f1df6c867ba4f7cb973393990db1ca1ad7102254c1b5c8982e50d07c77c79579100555622a46082fa877d47b744645cea7d5b030017e5ea8b3e7b1ef021b78266b21f03812cf0f274f0c68fddf3fdfd9e0988b6021fc7ccc377296d2e9c12a6c646b3b61663e48ea83509a4e7fa203cffddce7993030e91ed0888512ca9b3ea65af741197980b5538dde8a7eb15be1f027fa7acc4216af3ca6ffeaafa309001a4304cf30ceee2bc03f3312f76ae85490ae592c3c20066a110a1300b5942c197803bd8395bf4030a51b7f742d9eb62b5c435c2061dbd31b9ae9704c4e23ab69d25bd4691d1090634b57d54a92dd5067e0db732c1dcb7d08b43a57d7f61608c9a0fdb809f9a1e44dd6292691f35b49a83bfecd04dacc2825959a8b99a7eaa36f0f8ac7945f289fb5a4d51ccda81688c1036715b8fe761be10005b1b2fc7e8598b9968e365229946631c2ec07045bc595c371018f30d4a904c592dd171dea82a5b06177e4108a732ea7738daa152037533ab3ac9ae11b5ad43b9db67dbc6528104c19ef090cc2f5c392968c0444b4ad2dc2de002da5a636528d62ac675de9ae4189eff0330683fc2a9378cf1fcf0e0f4aa7478055713d2daf4fe20c8d35613188840ecdc4220ed4d3e5f22f9a135d7f81dc9100ef38ac061b3a421e28c88a650a1186579a23ec55b83e60d6359a5ce786be38383104dfb960e634a7352fbe14a919865d4324d52898469e2242a1dc9143ee911b580506f2f26208426abd363d4c6b80082ef361af81065fee83154fd1e946244daffc7b00e753a5fc9ebc8de603ef3e8bc01cb618b972f95c128c45dc98978342b025cb19fd7099318fd31f7463655ab8d57c6862f1b48056faa61bbc916672d33835296ca230a940230cd44e18a7347fa78a04995492af6a6fd2f170c859af425626f349c3ec680f49e05908a85d3a0146e6bb1db219e3b7451163fd94956f2e7201e8295f8b6164794b3f9af6de0e6c4592c390e501bb630288885abf5d5e556088b7ec021ef18e256cdaed79d83937cad8b0c547fa1cd8f8154a885bbd7ecc5421859693b5f7bdb17c8c7ca7867ca42ee0dfd875daa0765746904156cc0a9c4022d8ccc92fe5eee879d39b7a4cc9da284f5459f662c6dea45da7d851e1621945c5c36da0721cf4e42ac9c8e852dd4f641d9fd79c59a0bd299a388c5bac5c912f041f14f10e7bacfaa1ce1233c42e7959ca8c86ac88f42ff9b8dab7d5c9fc2b48a8522f25daca9e1e2944224914b3e5bc789bbea924d500069cdb2b84e2472675a33357d2567bb918a85897bf754ecfe7d171162cb0da45cd175aae886dd9974e2755676ed070d70bf6ff6c3cf7f1e67d6cec11fb49bd508bf9db57766a81ddba1d20e119addfc77d511423ec37baa97ba7082494d22cd53de4011c172850b22c81c6f9fbe88b2bf3013ba198c9d075e7696ad88636a8b78662241acc7ea5209085e50324e5da03e460579a0b63933d6f92a6c7733edc011d7fc116e1085aba42aa6e8863190dbd81a4e2451e702cad27e780038cc110a05c34f0313017ea80847a30aac3e7aa9978cef6242c0e2dc9d0d3832e9fe1964c511516649ec522b99d872adffb27402cbd14ba245f01c9262fa0ccd72e8d324e88ad489f0584f7b222237130a08fa67dce36215d84680afd3b3c91c5d133b58cb43d01316e3aab4564dae65e11ed577e741a063e934e9552e305cdd7cc368e6491ca34587e09ee6328a3f3c594231d219f657bc8b1c54729b2b1ee961416908067d88e5f6eb56cae30d529a219630e850907af63c05cfe9e6f49590c2dece82ea6e7a6e45d9ceea922bd95bd4bbcaecf90d4e5a0adb1f2a71f1070da7f3c8508be0a41a1c0239e6636529dffefefc9decb6bd02966deb904e56554e739b655c0725af631fb5ab8c333147c9b39670f17c431e117933aed975f30067dd20696f5ac118298989b5df22d4ad51e804e39185fb35c17343a3b086b42034f9de62cc7a31d13f988858f9407c8743cc844a7533183942fe75cd5e2908a3c65101", "00", 0, -541017162, 0, "4b79c8b4aa56312fb7bd1de424c0eebfd514b89388f6d186182072922d63ab9d"], + ["84e1fe3f03426724a61c58ce0550b1c9610e1464a3ed165d94da89255affba2e60b8b41c5b0300000005655251536578af64e4109740fbbd513e75b43b392033359b483325cf926ff249e81f3a570296994d2b03000000046a51535280ac90e3ae7b408c2fcd97109551176ee74ada93a37836815137c8f2417c2d73be2dee6e010000000952655352536a510053ffffffff026db0e7010000000001537dec5000000000000600515363535394cd701a00", "", 0, 1878472092, 0, "94bad49c811e7863e5066ef8c280d07bc4a61eebb45ebccbfd791d142a5634c8"], + ["24b5953c032b63ea0f11c7f96f9b0fa6ad0f5f67a68fdaa7d45b6e5e6317fdc466bffda4f4020000000963526aac6352536565ffffffff420a01efb9ad67c6615487cfbfc14fb544f79c416a6dbaf85756718acb794a1001000000096a536a6500ac6a5165ffffffffbe81cc0c3daa5d291a05b02ebcc76f0b57c78560df70a649b306658b297088460300000004630051acffffffff04715f9d000000000008536aac656351ac6a336d10030000000009536a6aac51636a656a363b5e020000000004000063ac240b3a030000000000000000000100000000000000007967f2050000000050d1a5c90e2e90cc0f6a85f9ae08c1bdc4af6d2bae7915355f2971a46288202d9b3ec2ddc58dd2a9bce660045a601467114dd56bae20035b8cd419cd2919bbec223430125f7271fa9ddf2962224633e0a744fe8c09c63582a93d012e4856983e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050590427f7230c91a4f6ab206b5e4733396922cda0434a129a2197ce4b3e510bfda8b64db12f3fe947023ca7264ba4d1ff347683732ac06547c3e24d9b9cca0c4cae8c2be992f0e364efc49e76a926e03d0243e2e8cec1d7d2dfec27bdda54f8551bc577a5b77e73b14ab056b4bff50aa313b2d085e872bf3fe554ac045dcba40214c7d2b8c913c0057c6b7dcd4697823743fa76e89f4b61f4697bdd339cdeb0520312a0b68edcc848119c5a902f168a3989c9eb9969150011fe8399be400a35c3890b0709ae01a0e268b666de74eb9b16ffe2920db8e91a6f0808664ddde7c32cc59ed6b25efb4f766c9163c0d2570b8393cd7df8b19b260cdf83626462471f98c0740221c475b92edf3aed2f8096c3f2f6c37ddb96a6af219739e214ed853bb5e45ab102170cfcceb5160fe2ea1d05ff2363d0f539b0f139443d99fd35dec0824198e492020e2aaff643d97de3805513d13b9e4daa335a31e1ebf42156f0fd44521220b74202113c799dcdb95785b21c04066ee5571ab4f5daea63ea8164894c4144422cf73c021f61a437e430d67274d032e13b2c197ef7259ca787645eedcc0f24820358a37af7bba97912a91a22b35c4d1d79a048634a7b268ecc12c78c931e58f697788d46ba29d1bda01b64a6a681faeae7e4fb0818b96c58e2b01e567d36088e55f9b2bf38942ef43121b4e54bf4dad58d8cf45a0776a0b92d9fa43ca4c26babd6274a0835cba0e736667c686c90c8bf4336fff24ae2bc569bc27f7a8db6e03b84b0a2a88f331c4cf91aabe6dee8dffdedc2665cf121d4b007038b4978891e4a192eb5126611c2ee441a3a38ab9925afd28b25fe5e9631fe72a52cdee750b3d1979f476d42b2eac764a689f0708325dc891b98bd191887a1cd3b09f57a4cfe43d651492362f57e6e1efd391f1c9e17d09fe9554f7fc6a6eef43d3efb87139584e5959ced96e69bfe3aa773c06204012911d4e401a730b36c5fd532f9fe6764c808b5c2fd00afa62f4627970b80e530246348bb7a224dfbfb54288bd470abd41f96795b794e88cb36e1a5f9fb9a3635613e6c861e9d17c740f8bd1b519155f4c8ab7a8217d9b4cd4d65f6a34a507d30a67a26b54a3f79d8cc5d39d21f5f6b2f93a231984dd6147119f537a8724eb23b6fb21e7bce712760e423326e78e426506d08b1391245688d8dec1a77cefc23dda54fc2124de2d7063583e3bdb424f0bf444ba4f1b785b85406a819dee436d692577b5732a51749870877b9633693cd50b74b5d87d55474b4e31ff3b7a3856abeca0aea067a6691d58a753cdb797837d4c147058439a42ad9ef3e191c892d405027bfc526f4fd7c40ace7cb009cc2bfb8e6f227c7d0ebcf95946bd16d41260a75c38007ce93793b370f96c61881b73cf9c7ab9e8087384d5d4378510c9ff94d132d02072c348c7b6ec3024044e12e27c794fa42540d6a157804d09b2ad4e54a2263aa0cfd679fcf562fca7bbf9724c80ae3f6683ac217930cc98cdcfa45f1044f99df18cfb4aac67b6c8a1e5923e9d12d414c384044ac4986e99bf80af6566dbef72ad70bf91c93d21ffdb6c114ad87e3be6a2cbbb71f5664c1750240abcb4182d915cfdc57dea76228dc9d9cace2f4d5c9b7569a44f67e92f9313655cc0b9d8e9a3781bc121226e00de447eb13355032e62a7aec9b811b0db2be0ed41f02fefaa97ab13f7ed08dcac40bad4a6fb80d9037f89a8531ae80e80f48a89d419176a196f55783c0f2c9cf687a3b42a85e6769865bd8f29a165015739c6e5d9c93e2d766fd62d1924c125cde6f50999fb5180840bb3b2b1fd10c17195590813c338f29471c9c1ffa1655569d412f9ff309347aca18f966e99129b6d84ad872a0209bf1e046d006f721c6ad457f61a50b19096c40fd30bd9a5f8ed6b6b7d5ebcaafa21afe91cd31438c289fe0eee0cc352134232ffb8298cb1c01c3a9d6c668e39d759f84747ffab7306670f402b785bde6ba11f0dd7316b716d206d8b4027f7c150d7bbca1221d31cdf0ef5cd81c74bffa68c6ccbf19e38c309396dc84ce6dc73891f688dc9d65cfc2610a8219b8bcb917eec5ae2b4485cacd392e22c8b599f05cb010de0e5556442a6487e52410d171a1035f481589b99ffa3f2c7eda42a2f2f75d38bb29e3911c7071a87dc4af8a2b2ff376b75db92275e7b3f39cc444441bd057838b8f25b3cb26cf1427a21cd245f329ec781f657e4fc6c10f1f8f7796c5591f6e0a14d2ee202052f29fe5c52c275eb75cf41ad934a6e8b70551c13007b3838a144c8a137ffc88628aa465504a832aad254a6d34346ac1675911f9cbe8a20cfb340490c5e2d6baf7683fcb914104f42ff5f10c70436bb35031ec3b3203253db3f1c727c2413510a0bc7c48dd5ede4e869203995cc0349aef1e607cd881460a4ff2e775b4fc517f0d", "63ac65630000656a51", 0, 1518800732, 1537743641, "7a9dabd283479c3227f448c8b0975bfd03e6c06402248c4b86a1d8411d949190"], + ["030000807082c40301ce503447eede5cba2aa0e7a9f7455c7e8a0763b08b2c32156d8d6809236c55f30100000000ffffffff01f95f2b010000000008005165516a65005200000000000000000200000000000000000e4eae000000000045ef69c33ffb8f32d93221248e07ce2bd7881fca1ee26e5b721f10bccc32546187003c5db2a536493a407e625fe0fe62fed1aeee4dca7b70e37edf7a88ed09f09f8330d1e4683ecaa6d18768a6926fa0773028a294b6deafb73c262cb0568ca8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004ad165aded2e3f17d11f3f0c29d3da85ecb6623bdb9831a34c365a330b64d8773ed152e3abf562518ba0a74fc10bf51c1fe3736fab0778d11d40f17fca49c8962c74edbad0e0b7f69c50609119a184edd545407a22598f7cebc94deca706e94dcd6a8aa9896d99ff72a992e3447c30976d6b25b2e2fb2b0b15af0e801fee6031032f875abd130f53fdda2078beb7306882df149b3005e0cf72deb3bae7c170fc8a0226839736a61866cb842b1d96e68a2f2ecbac2921ffe4daa032ab3d747afceae80a05ee6f941bab2067e66f7d8bcb0fa94073c4c837673d39541f8f5d3d9f5df91decd36b00bfca537a8cec836d79a49619d8ea83344ac98e2fd9535f77e5bea40c0306a55da6e6492816aa93dc165ee59532f72b8cc32e81e4dbec7801ca7e01b44f022c02b745ef8b7c0986f41c0636ece392b44ac7280988e7f4c0d7ef739a242309031b8dc3c581e3ca70c9a54237199f0a54447ea795717c34ed4c022ce1ac0d4b60020a94a609f7964639936e62955d9ea7a6557da1f0729d2e5ecae6150d663fa4fe032435fa7b897eda47274b00d219e15133211f48dcf6dd590e180034c438744acbde921d0bd84e8f9c9c53ee86b75d6ec1693a3be51e36df74264a1e56ff4bd5dff1c00987bda34c1edcb9f76c7e97ae2b26948931c364911e08ef89c914c44f9db46239f2fc84ec7929d45ec63a6bea4a87369888ec1f77629fb4fb57de7e8b37a584ce416a68511c4af2e0d879f0e73ff44a4b5c31231dda436c3e28c38eb1a6031416abd2b590a5b8b80e456a67ae6c7292be75aa976744de5176975e6d39ad0daa360d9c0a130038fd583bf8d7ecf83bb58a41dd9d75b55fb37ea7872241ab4b3313ef6ad4a507d313f92b3618387cc9c29dcc2d1b2d302fadb740aba76047eefd422bf50b4827ff814cce6862ad0743a6d3936f77c454232561200d2734dad7d563d4d5d32ea18a4ae6fcb0089314be641aee3ecc714a1ab7b234d4e18515c10eea52f36f020a927bb0a449d61a562493bab56cd738500f94095896472d7f45a2691aa650dae46753804a5969eb053d07e025c40d983cbc46533c75fe63eb2e0a15b72b292acc0641933cc2a353051bb82925a96677d6b3bd0d7e83cada5e7eaf06877964e5977f93c70c99f6eb79c36fcf04174281c63105515accbd0c343e8601a23b12c06fa1318af49c4b4aed2c824f49b17ccbd4c5a648f6f8e4a96364e2e93ebe6aac4d063560807682b033f834042cd638181c3ef33e3f10145d0e9979e19f746cb98d4db93dedc0de0c30d29287166610eee50b1645f7e1e502b207b28f75ff9088108006a86704c45ca7be6b0245941f200d3f8eacb33d8875c2961a8718220b7af948cc554fd30332b06e1c8d0552ae136ef717759cea31f97247cd52b456c55ffc5f86d7b47f93e13cee9c3b5c915097fb3b11741f081a2defedc27d6e7d6dfe84193c1b1b161189daba76a5619123bd2c48bb42affad6a5b6cf09049b0c76353191cebf831516860f2626bf9731243ad428c0dff27a5fd7cb8b8c8359af43a68059dbf96c91beec70bd5b3a886b2f9011dce12acd3d7d99b57af12b54430218edbeda89935159d27a619339ea27f90a1bb7ecabcb5603592c617d8c08579b3e1218cbc001515c1efb3ae3e79ce27a4452f3baacd9a25e83f6041b8799b37996b121e53de21cc696afda88484c0a1d5c1c38204de12b5efc32d40e2c761c56b1d3bc9a87aa6eb20d4dc44fae881407f4f5afe032b78226b39eadcd68bb6da55561d9f897f9be93d0c74e9c2b70aedccdbe431b0a771b199f54f81512a22be53f4538da2cfd474941f4589e6ec415b91771745020a46178b2880074698aa7aee149e1983d510632fef3ecef27a2b368088041336dcf4840ae4d570735e18a3fc1e123a96bd05c819c7aeeaec25fc9076742a97f0481de25ae667b385451631e192753fa2254bcb0c43936750d1f6920292940cd929102fe6be15f10653b71eed9549f85b724cdade42ff30d2beb7287c2ce17843baeb7251d76f64d0f11618c77119e62f9d6b15adcf2c13951615c4177fadedcc3b07d15de8b72d8b84114cfebf8f95162625a93d190d4def38a5d8f90e9080f9994fe754be75a99844bdaf4f517e0f35479d6c5ad4434c770209d17e3d7167d248f126b181bc8db146fd7c0ebdcf4e189e15709deace893f4b856da5574013688e8736259596da88a13b305ffb4eeba72a582f5006d7488c47091a34098774450514f1ff0ba5d5c6a554d7e6f7ddb603a7adf1d456be130051e38050000000000000000000000006f885c8302e0f5c1bafd8d0123e87cc616904bc178e1140f861104a57c015fac42642bd292bb12fb56ff40c377cbe66114dd57dd62d2c57426b8395e19ac4158287909afbd3f32d08cffee33000331307cb3b4ad99cf0b17b913989b2ad6c519000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b2ea9fb1cc00814c82902c05ceaadb8cf3caaa4d69fe2c786a25a0036bf799f6ea00bcd2ae8a13bca396b1bfc19fa51e7785380be5f8a67a5ba8ae079a66e00d286e927c23a9a6fdb28a19fa1fa7eb01c968a41071d827102f3fed09042e0a763477072d0f2ca9d6a5b70ffa23cb19d70109e059d9ab6964a0b04d4c7b9a61c0223accea79871c8f7b88af2e01fa6e7abcd486d4a8b9c0b9059717e16cd8c260a020208ddb44a15caf0c23755311586d0c6b6973c4dd03301c1d85321177c6ad0850b00cfddc7699547e8ca262713353adc1db62a992005591bb0a2ae5db3f04b731e481762e0da46bf92a519c110eed60bfd9cc2e79e3e7e3cefdf92f0f1bccb563b02272a82962f55c005a4c795943ad2863cea47e05e4396d0894c678bf35473ae4002025352ab717b7274b186c37ceac66b881b2a906f6722187ae064765f646fba720310126c400653c8a901f6d34a384862f645de9da1396c62b90ee85447031caa8003121c11654ccda06c1124defc3fc8a5801e90de986cbe4b8a1d29d200196e9813020dfb72fc25d006bf624e0541327ee764d4a34adb7158508e23f8b223eaf3df34560fa2b3e8a97bec36da64205e77e96ad1712e1235fdce6042bc868a8b5243de60312cf109c885aa6bc0947432460efb6471804eeabcec20702bb786e821e115886af9ac08da096de9610963c5f981ba053af5662083b46133f722f2912ce7bc465cb5d907c810c1ce958bd8223772ebdfff03f03e2a5b94e4e3fcbe295a91ff67294d5ee7564f4fbccd0ca836461363f423ead1fffe808a8237d9a668d8edefc47c054901fd721119dea60606091b2681a585a10bce9bff342366d0c55463c2590d15e5ec3cf628b8ee9fb9425421db41dd221a279d201773bca42c64725708cd1bf2a435498d020c5f3839cbef1d6b56411fdb00b5234745662defee21a19620aa9082bba632003d56c90859caa49c5ac53b1f584f146d48d12d37dcecedbd50a7a6b1ee6161db2027e9be482c21eaf370c7c9e73cb9c11b9072c40f7c405ff9bace51444970c9b2183f83124b21606c8d2330aeb3f1fadec1119fee6f898081a10e44522e7ceef237625bfee15e4853a5e3a7e36f06b05b5a331f66ceefcdfe9949dd8e8d90ae96da907c5d5b43197fc688c5e9a311635a5a42c205444a31227d73fae6a0f33e439c5bf37467dc0a9d861f88f5b746266df9be66ed331fc36be5966b1a7e555cbf90b81c9a114e926192cbe9140a9e98f20356ebcae8d618c367ca776e69537b824272572a086fd9946ce33bd29b8edb4dd931e875732cac3baae97422e7e71fffa2142081b96f0c3eb9240db0ab2c0d9d7da15b0293acdf78da1967cac518a981e2fb87768721917e81247a400d94aac86eb4708087cdd02852648933821399b76bfc115281b47dd73277c0d0e48ca7bfccb0b999c3c19cebfc33ef62fb4406f7b3cab532e2f53842c6ffaecee6c072f109d730060b3f86d59caad4619e4478e0c75bee808823cefc032be907c3d3a76b56ef74c77bbb9dd808b8e7fb9dc3757793f4ef77caba8d47f6e4486defe07f250b8508d7594621e02a57ec003c935aa605eea85d20b30cc108321fc068169753d280fd1178bd89fcadc64f612e9c33eac3396607fd74b2c53360a11f7a0d82241a39487278855d4f1f4a718b5d320d0490bf5ddbbadcf49c39e8e9c07df6524928ba4390d7f1060c61872974e6852f0441bdbe5459525b5788869ddc686342d47040776be79849a504c43f5e673e8cc3346868a7c9e320baddd6e7be738cd5ce6876d2d39a2bb1e529a4c3c0fef38126237abb97034852b56ac3b3e6479edf666b2ea8b86190c087b01027eb66f7d9052023b9cd1fa6339ec7caecaebd6fa068ed94cf135450e472686f7b8eb059884426cd3dd7841b13e56fe9459bcd658377b88d34efeabc1cc6540c599e15de943be2acaed572cbe76f8686a8e534a12bfa6c2ca1638ac4d66e67fe787b718120bfe02be45eba27476dedc837103ab363c31ed355bf9eb445986e4e87753dd0278353b0af38ee3e227c3a1cb6c3fb9d7c43e3130b81047c10b2a07716f8d1085eefdb5e62e41348a35ad5710c581ebe68994ec976f414dd6989ba4b1e6a0649b078ff7ee658dd87d7312586491386c6c2159fe9d8c59b84a421b46d74dec0d48fcde95445c96d71e4d4229b486629583f679928645f2832f58b9359f729b72dcf0c4dc2afd4926e085ce503b247a69c8f0dd9fafce61e28e6f711de09971c5a3eeef8a1ffaad14a0895b346901adfcf83e68dba26f7daba30617262c72179eb660ff6f8af0cb992c809ce0496f81359960133c89ea0bea7d05a3241633ea19e3c7b1e308534aa36034c64ca8de14d2196ed03be7bcd86fbe5f41632e28288eace326ce1d221aa391ade0d", "520000", 0, -952761114, 1537743641, "560b6cbc95955bd38f4b07321bed342f63b5e6722d2a2a73f09c68d3cdcff48e"], + ["065f892201d4a519f0f1c947bd47410d126c52993f5572ce80f479ca03931c462c94a97c690200000000212afde0034e16e404000000000152b1377a01000000000963acac5153536a65638c4ff0030000000007516a6553ac00630000000003df1605020000000000000000000000005a070b2e8f371f34f9270a141dde8c1f28c0841de936c4baf3762478b16b06d99b3a4029f72a3e7aa8208c848596e6934aec26e40894774d177f6ca8e1fafdb584708abb463955324cafcd8dd385176b419221a7d7eca022eddffc5cffa09ec100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a940f456036dd7c2b73371685d15561d2c9739d23a7b108ec474a43710b706c76cf07a9949e581cce87b542f4dfd34c7230aebf28dc3b2a5f1f2432bfb7765b36b0abb21a7983264e922d4ef98f29cab296017a3ebbadb8c3e9fbfd84c14d508f59a46c6676dbf3be48e24602bfddd78c77a1b37533d71c108d95046dda2054103294fad6684472858456fc1ade370b320210c85e41d7856495bcbda36b76ff6e503002ae327849ea1bb9077473ac4b4d1f27a1ab7225eb420f8e2740d399d0aaad70a06372435c83d1546a6fa6f5880ac9a1bab781d6d96d25cb6916dd3e16cbe734c0266c010ef6a9789ea70f9b42141c1e6f79b8597c686c84af62ba1a66e3662f7022f29d5fcf8931d936dbcca32412dd83e49959485815e7c838c95a43ebe993d75021686b8b4206505e1bc6ad568e96701ad7c1e4dd837bcec6523ef344b76d528240327a10fcd7425fa3e3bc1f213a5bb970bd556ea893a4d7df2e14af310bbc2f95e02253d368a2b5ba13a085240eae751cf76200a47938a40fa4cfd955fccf49d73450214aa5a1efb49e529f42601ef83b56b789d1b5c82a60bd3e642b8b85a13d1b391d9b895d5805a96e645905f643a65891d22b30d1870c6c64cd8f22b958a99466fe43ffe1047fa74af95e1052ac111b79260c9ab4a31723178d385a22e908ca0e77bc1859302a7b39775174a257645ce850f4543ebf7186740eac698c43b3bee0cc0eea971166c5a9956e975b1f178a8b3731a1e75fc057545ab248af1cff189cd6f56d7c7c32e9c64af6621b6840d9cd92b17ceda2f23f4673c452a0d4ce45c9273f5ef371d2d788d52e6ee272ccbaa819fea053cf0c0e82d64919ff37cc2179b0fe6bd0694fa1916a0b1cfa7ca701754c40eece4584d52abf4dbb6acdc76f7016dd046b4f41442fb84d3341ee83f6ef7bb1648cdc1315c1c907711d6aa825227981c285754a554f1a8313f710000a9dfde5ef1305909f71b11e7e74d81c3d47b6898fbd943bf0ffbe459c9ad325a6f27e0e344c45a3a90fd382e7bd2570d0fab5405088c912bcbb1e47e8be95cc8fefb3736776358053fbd88685eb926bd93157cca48d3b6b71cdb7f16a188df43f9792877c2d93dcc51baf27f160fcb687f702cd8a1c2be15c0d9c2c6a386a113c79189744b1cde9a209fab5271878f22104b6168c6f46c3f4ba85213646c54f25429bcdab908ad1f394c5ba651e941857f078ff68718e7f1e8edbd48875b5928fc3f09afac0d38160b0aeadefc4ae416477b2f4b41c1cd8da8856742333039783c97ff451710ed1d611bbf9c72b7b91ea468a5cdc621ea39d582d58f288118c72cf4e24c8755214d77b7f6d438b55e784b87e93b9200935131b25d2ad196aaa7effbca5c4526ab69ddbfbbf2ac7e35aa25b14ea90bc2578499f17688d407db7a31ce3d9425b0285ec1e7c674b74e93a6c80339c1efbc19417eae633a8e3e452bb6e3c953c71b7436831e5aad356e58b9201362acaffa8d10034267d2dc7d3388609289db1450931f1d836455e50fca735d87ec02279b96cb9c204f0d285020ccd96aa7b21808a8b6295776e43c86f7f6e09abc938ca9bc91020cc7b73a3645fbf716d912b3982ced0e03fdd7fc499012859bdef4d2af40c2e36b78c9b1933e8d95f92aaf32b2eb03556a18019fe4e32a55581fe74bd17d93d5020b987239ab372daa029bf3f0a18a61ae33cd31c4c8ba3ae7b4e25c34d90419d5d45662272706222d782e632d4c32d73fe61be73d76e81b71984cfc6db2a45f669e31fcbf756ac9ba6ced0f5e10783953c46868a84ffc1edb43639ba68244ee6a1413810fff98148bba653d92cf5d70bfea4c50d6b740eae25b219125e51404511acc1bc5039b2aa378419c682fd3c2cc4a29a77f95ba93fdb38ba2c1daab2574e86b99e17bc6c31ba3975cb309e817018915fae574bf357b688dd9a32ce4f415c6f07ddc1a6965281dd714622ea79a863e1c55b5e443c7de710595bda407fdbe1a94f16e01bfe10253d4e7ae318a0fd888baafefdaaa3667e5989949c8fa6b766b0e9dd4b233c01dc863e7feb1365ffd936ca0d7955038323505c7c6b16f6fbac2a43c123cb1ae6c9e0bfd5337e738f74d564495af968be10970a40a4d391f81845e63da61b6fc47cae5891151d9a8429238e1a31bae4e5666f762f024cbee65c809e2a479653ffdb89afd5b99b24624f9fdea32bb5a3042f5322fe8e1854b4f64d532c1b9ede1b1294efe234f6a04990f552b3dfdbb7da11692ea4a9687f9bee6f0c2a4c9d46d253ce6b54d41010000000000000000000000006072a9b16805f1e6e662ada3f4c7b4acac1cf26af7459c9063d23ded0662393480c1dcf2f0132f4c4ccc9cd8599b51ca3d27d4b19d3e3ae775732453fd9382025cf686d40d5c026ab808a5bc591b1d52c4038a9cbbba5d4ef1a2455a7cb96ec500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe80d18f0baa3fa04929a5cc359de182567fb8f64ac87bcea8792dcac7dfeeb1953310db6d8d27382ca619c1a372dea449e31e2110b09b5270852530138d2d1802d2286eaa9331543318594b3eca6b23853e4a44435b60b08ce1e19c69cdb3d63bbea380fd7921de60fd57841c50b6a2e1904fa80cb231ac4f291cce1685619d0223b6e084c6ae6d6aab84bc43365f3b502e41a3a35d66bf9422e728b930642f160302bfbc83da86b715e5f5bd2d4812ece6f6d146b3a7955051ec4fa75f0da3cf210a02582e9e0418e96498f312d35d6ee47e9c25f26e44fd3ea72652c24a2f8b6d1af019fe808a2cac48deda06c35158348511c3c0f30d53cc7ac91a4ea3b0ff6089030f47a3fd45ce795728906020c039667e40e16a9d22bf820a18de5e3bd76d2fcf031a0f21968e3f4a55dab70924eeb7a56e503b0d329f9dbcdc60c95f34f3dd8cac032f0c629e618312011e2b976920527e3676524f5c4a1144f57e9006b6ccb0b1ca021ce978666ff829d0e3cab143d872f6684a06350ee34ca0ae255174e03c901c2e031ef53c14ad2a46af69956f4a74122a1b5b42cf25b7fdc743fb55c321ca486648139d0b5edcb656890d17268cd7a77cf7e6fbdaa47760664d9fde5186e0a9002b80bc599edb5c776ea5ee9e199298a69557b1ca02b8671c34575c7f501cea434d9f36899c7cae8c0fd754d62f1579ca12812632291c44c68427c8b4278f3dfcbab7535b1058db6f6a48f6b648e53defb3f0b8452394223ab658c9f55c18f63748c27f2b2871ea638c8d002c84fa691f20144922b0e8ac2b0e6e6144d98078ef4831788841a33e380e94abe54412211d76f289cbf9b916150683ed94492cdb2502ccad43aa74701e427c8ab1ed193bc796740f424ed1f42be315a73677cad92ccfcaf922f3903192adb1cecf0d8919cd338b1486f9c9b0683f727a14a1be0ee3a2b89562d77dfb169419b67d6b77aa3ddf7f9042754a67cd530fe748ab058b5d00eb5da7910173652481f85e130ccf7e281cbc753cde86009895f307edbbd18043518599c9edb4650cf2d8949c19f0a8e1aae127569d4f27342fc4b2af28da34208f1fe55be006fc04a75d7943b249b6847ff3beb61adb7b9d0846a9ea9e45bbbf94b3a72d17c4b4856ccd3c98abb64bd3075f34192ddd8dbfbc961843950cce6a0ab4992b762dc00ccd3a1c94559998d2e0a6f430f816155ecb468e2d06ccbe81ac0924fec6a92299f3356818b39c1b1231cd1cf2aef909d8e6cf20aaadef88dad53f445359d4f192c90bc9c5b0fc25f4e8af363f3751385fb81ef51b6a8d702577697891d96c07636b901b240c8726bdff0d8e5552be55e15c07cf349dbb6282e767b339939b3649dc15eb88d685500ca4e2ed2d5c99cdf7c65270815a50704a29a885d897e125534c80ba22c4a34158e495d157beaca5a0bac9d22142247c60ef4c0981fb0b33176b1c5497267b88bf659ee2045b61ca53d8c72ca821ce1af6c9f2372dc4784a433e4803ffbaac984af403f0a66f13a8bb6bb644e78299554765aabf618b23e471a9d7af376f1dd1e06bdabbdc6cd86a2139f29f81ad8165085881cd97831482d306aa747fad81e812a5ea17dc840ac1fe0a4ee64f467b1c485c4d3f9fec9030ce7d57c60e82f65759d2b2fdf1a60540a98ba9acc704dd9e0ba07ed7ac825cb1911b09f23f19e29ff63d4802737ee4a9acf4c1a685324ae44dfeb9c4e3cba7f3f5a0ee92fcbeae6f3bd63c116895168373de564edaa4d1f0aab39d61020ff6205c2d3b3a2eea3ed7eaef0c9652ed357c8da0ee51db0b5c09caa3ff1289d127ce433d1d2c5d390177d88d1e17c906d9f7eb691561fce9a72baf7b3cd4390f08109e14e93087109ce903d9fd812e46aead45871e4c910064cb5a070a32dae7b71d916bedfaba7f445830e56e45deecf9b81248be9403451d0b79c889dddf9841383afc840d5042561fb21ff99c2a6bbf0bb6b0d84d91b9c37aa2788071b88ce23c1cc0cbde29245b4101d4c72bd87f554eb81099515d772698ee9efc35b1a81740ae0ed6afca395ad9dfecd3cb2a152c0faed7b0c7afe462eefe2b1460165f13c5a32e0ff67861b79a1e4314cdddb76528732b921858e9dd2a11b45f6e6696e48c1e5389a1b06b0b92fb2b20f1742e3a2f93f0f6e320c08da626eb5dea1c373292e9fe81f8553cf187622875e3733c0294ed5deb5c24bd0ab84bfcaa80f6d7fa86be2e8db46883bb2a589c514d1591e922432541bc7cc430d5275c6e9aac5f101795758ea49bc5e973e1b2e40000000000000000ad708c0100000000d0ea4eb0a5f4ea9dc6caa90d33963eb10037e8ad18b3e049832a2afcf7f058e56b843eec0aadba827673aba2c822bbabeccdee1392b34e6565bf9526bb91ab7cae01a3de2a3b42e9f26a50a8c961966bb122f0e72b72451123c7263ff2785daa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015e46c7756ed1d9f4b5abecae6c6dcab700f8e852d99f7589d592d3ebedfc31c04396b9c0fd1d78bb8c9f133bd7fb5a0ac41809e5349ecc22bb1f21d341cb5a48a00390eb7165b454c5aee4b39821b5d2eede112317d642c55c266eca9b98a13a8c94fdac3ef07db4e6e58102a2105473872aaff8f5c3fc832b10b8fc31e23d20325fb7ee02c39c2485713a7889a0aba317962b21485bd95628aaa48aea418433e0305489ecee4e1f0f5bb6c1316d4d2794d7ac5a9ee26945ad9adb8157600b7e0690a019ead4bedf4cc448193d7a3ef6251014c184df9918103095e329bd04d237f49c25ef14759f588e25314ea44606492ed09941867bf8bdf0d221a06549f855a400324b59accc537717622b0147e2da02d65724e8b527bfaf0e628de84b1506c67af030361b36b66463f031e88c8f34d0a22d7610c4666d088a3063fea31f8f8cfe55e022ffe221c9cc2954489257753432728b75b1d3fe409c27c87524b348c1fd25f520220fb6bf51cfeb9e891316a2392f28d472b2107cb4eb77c86ca1461c44e76fdde0213f5ba95386d8bb985007d1d998062872faf65302ac9b7c9454ffb6297f0db66f319462151ff9e83ae0980d04ec291c10cc3ba667888c291c8c81c056e52c7ea74968da5d182b2e641b6fac55180817bc7e4862c90e3bf61dc775428b5984353b71b818db175217c14137db9cf58a5a7c72551df141b7ccc8408ae885462f97736d71d2323b1c023e352e902998d2f8f9fbaa399d0c7a31b61c93947021e7e0bf023b4197e7eff2d73f86d4050be82e57f7e5e9a63e507ae85e0b30e0168ca8a36070737a94600c4748fd14d1b5e9e334d12a8d944f5da476e923869e2f4e8fd45124f8a9f88540cbed1f2380f296d5ae6ac266d2a4efd9b42abccf44ca37a252158f4b21bd70c196f0b1825398891ab472a23de86898c1ea3240c8e9427ac09286e09e64faa6a003c5a06cfca34fb05e602084a2946026b1e86e84847a0bdfa31be5a6911bd53d6829dc4e203a89499724a46ca16292f2444250a1a6ec31fb3b9b9f14adaa677d00f20d0e1db77e7fb1fb7ec780bf8b7d3eb56e5ad386543b96c6826b9b46005230485b792e14e18c438f25a0c592640aed5fdf88a48eda50e836bdc5569c3e81b0dd1ecab92ac22f1bc73b99f7ddb69fdf228f2f6c90e9ef7880622d3a959cfbfafbb6e88a29dad64023536c89b706dc22d6b6e3ff2b04c3df8c8a0f58e4055286eba9f8458ea9ef3dc1134c8c313c00ce86ec3db0d730d4ad81a35f8d8a99365adb67b838c66f9b961b159a50f8c632a077448b2054c9b3d71a90b7089e96e86addfe76dd51596a11656e0f2269212381847f064cea87f2e895a3f5edb9cde0ad5ba33023291779f5957884020ad68bd9fa103f08743bdef24f3f9e84f8a96299c6f359fbfb6e0da11e044867769ae167bb948af1b87b1fb2b7c80a1fe330e0f61b37754a1c6c826e71d2e1fcf133c9a649ac8de2921c856be46323a65a45720a453f5ba502eced76fd2713bc35184faf67c8ed0764f37e23fb88aee832bf8a6762a073283e0908b9e1d037297d16b7ce7c5755fba3990ec14d532cdf94b69687e5f7303abd85573f0596d56b37d336001aa209e5ea0066bd472494da03c3f0b30fd2cc3e238a590802243e299962f3dfd8d05121669541e431d5c87a3be0c262f5ec7168acb2ffe50eb8942e2dafb8f85729525e9311c2f067c83ae8cf71b60e1f401a75bc822efeeddd94006069f9099365f48e8c073b759bebed9c9c65d74f5ecf89d73a71faca0d83f4dec69182700e710a20fcd3245c3ee036197c389920e3c1b0e491cdf8f306ad32130a67395359cd943d70fa75ef969ad534cb098133202406a5ea54d6c711e1faf9ebd0499c702e0fc33207b0acbe6314096463b04296bfc90c3a8718a853ca727e9963cd7646056e938a642a9cefe65ce4fd48e6cea00385b144b48d12ed243a356d2a4060ee4be20c0cb2713c2772aa48c4f1d508f8a074d40801705e4f7e2fcff2f0971cdc667b4eeb70de5ab210a3c7cc982ae27f502651fb9441ca02d2ece58517d8671b42fa5d74b78d5b99fe26fbca0add167c3e2035eef3978324c26c8fa09c054950e60fa1f4d95f4fa32d24f2dcd912f29ab483b3dfea9dc786cc2f5f2c33893982805ad05939005afb8c272e6689d8b17795555cb8b629c20d09d32ec2e06505154bec92238af6515f95d5dcea29c6276d2b47b42604865827f13bcd5a21aac9595d4c75eadf3d8b4d7c93706ebc75f89d5f04dc9d22856a3db8bfbb00ab34ddaba07c2898672accc9e871bd2caaddf7b20f42c137e63aaf58a0741d2f1963cb399ee03bb736328301bd0a01bee9b2f73bb748d3a053124b92873d69ef3fa7d152237904b0ae8477a7ff1dd59b46a92dde32b47f2cd4778b303", "65536a6365acac536a", 0, -810573223, 1537743641, "df006e9084e54f50304b5f64ef527dbf4ac0f84544fa31cec136a8419ea813af"], + ["030000807082c40302010a3057fe70aae3f72c8f81340a40e90bb1c3d1bd7ea5979eb4e4fa01f74c650100000002ac00ffffffffdcf2ae656f5163022e68851c49c47e35a13b548cd6c35972b6dd4c63946b361a000000000851525353ac53656affffffff04dcf4a3040000000007650065536300522967d0010000000001001b9d9c000000000004006a656a8e6fcb01000000000952005351635365650000000000b3831a7a03000000000000000056caa005000000004daadb0d8ef982425cec7b3c20c29c63b2e3d5e797d69a04cd9b50bc45b27698b2a6b733639e5702a7f031d662ee29132721c6915e8d3dd60ddff1a207207edaaf31f61cfdf0b53c67586d3b580304e5eeeeab9efd4c76f34cb588706c1a7d0e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2006d6f907528732ce29fc0a414cfd81bd1569eeec21dd83caed9983ce9f0f4675cd8cb923fc3890e49abcaba7d926a105892fd0959e168fe556abd19bbd4913debf71f33c9f507bbbdae652076fea74b6bd2c978fd49e33b185c5c63e38bcf1f40fccb98412a261cc4990227951059b080aca7a154aecd34ca52d9f046c276021c7352f4ca9a7f5d574121b34f26573c064ab04259cedeca3b150f793582e3660309e2e7bc90c0fb5e861e6afe11069771ec01b0ce14dcd84c8383ab357b8920db0a02c65e8291d47003e02b7668c87ab83e6e6f5ced9d0276e5b5bfb25f7fda4aec9675f5fd0a1c501d4ee25f6022c57b59512e0302ee8064521cccb61d4e2a1f0a0325d7d8b44d54ca7db9167ff034b964f800e10a160819855fd6df1ed11bb824b002102e0dda32c615209a910af1020afb59104a0ed60addffd7fead3948eaa4d2c8022d53d61b30dc00c0ea309de654da61d52013d1d7011c587dbccfc351a067eadb031eaff41f6ef2a5b4772e0c79fc982275ec949a731b6e0d476d75583c44b5a3f2021073f84db5969cb779f25fbb9e21294b70addbdd76c8467e1bf8af693b04329d6dd647d40e1f205581da8cd4dc43d6aea3bcc10a570198b85cd4888ebad6bbbe2c2f21c32f3d658fba1a1a9dd68f198a54814c1c5208ff8c5ab8c3acacd9884f70f74b3acfabc1d84fbf4788bef87ca72a0bb1433649cade49762db34f01b01ebd1fe145455c8f70dd4beca27b48b214f1d19577465f4d129d30d21f31a10c7316dd06baf615a1e68dae0423e185d200b5cc5d4e44e3c98124ca885abeb6ca5eee2eaa2516832d62376d598b2a56f7520a0a208762fd7d0ced37ae156ed603aebace569a60aac283f11b0bef0c92f328cad8477c8bc8d41751d1b0ff1d523684c0f4a6217e1486f604ee69b49ba378089b196cc738a253c705eff9ab9779ede0c6f303bbdde98b96f2fc483320c6583725ecfc78b22050333eb5d7a1cdca13757bf5fc4ba6a434467f56247b78e3aaa58f4d1f72f4331309e3c98512ba8427b440418cd0929453956b1b7dff745d05bf7532045ff41feeb597d7b77e0f147a3ef810cb2bf54f684b1e2ddda902e7f8fe2d232cd3667555130eb6c7c5721467aae8a7a78003668c45961e0950a196aa08e7ebf6afa6b3123bd4c9c633f5f147b1dfcbe79220293bf1026b2439607c469699963841af56cd0c3226525796042d48ba610901cc300a7ecc8f1588891b3fa5b760c6c3121f45c5a06f0f7284dee691cd699ac8dbb32933b4040420a77b77c4abdf333d3759378c42fdbecd854564340fe0131915b27c901ab1813bde646f3325a5b4d4b4ce03b51a004dbd68803cc3d1690b32814d4961b6690ac082ca5bb7e34b9fc6e2c6a870adac64a5e2d4d3691a42228b951b205bba2072e06d2657f79f174418028ebfdb8fa854a4f6ad1eb48797eb74d2ae68b46104c19b6711451665b90f4ad523e8971438e7b5b19913721e487230435f9b3e9a05daeb75c472d834c56be9174bc6916156ffa7376841a5ef4bab68840943d3a1b002ef8bc304cc0cd78492546f35fceb645f1a66a88867b158429471d94ed6aed77e7fea0e2cdd4027553b194d3ec80909a5f5e23a134fce4f6829ab3c433053f1cb6226c3c5ae097595abb58a0b35d90bfea2699440f40c0afdc76a2a28a8aada8d267d93fb7502c4d83500555bbe945519afaf949b57cc9db27d0abb3be22af638ac0e8ef231e6f672e5a93420e49b5ef48cd686ff5f2d9eb4005da839b7852e7bc913f9d96010e407733a5fd8eae1efba7759c393ffebcd561f287f724b0faa1225a80f1150aef42e43e8e604af05dd55639431f56a23fea96e43381aa694e399b97bf4ed23ea48d9a4418213436e1b217003399b6c419d938bae3e97eb3b7342caf4efce98a6ecccba4a4633fb70abda84356f9bacc9fbe2b54524fec099f44c19c30d71ad054322502dde2c88fa7aeba419b5396bde30edeba9e7b13d73b5f516750329bdbcf54537038e531ac0e16bbacaabe0c4ef42214e93e3a89989dfe3087569438d551bffadaa26ce886c5255be87bec0b0d017b77af50381979dd54b4dac4e3402be1eddc461586bd2320729099809f178c1d74898e132858bfb7351c7fe91af3fb0b8f0c71f370fb9850df74570016cece66beb4ba570129957b45facb5b534231e119417ccd1261770b9a64ea9faf791f9a149486bccf28676a03f009724ccdb939bbcc4b9f29f68398206b93ee5444572206b9903dc2d1b41be4fedcd6fddf7a2c48fd0f6020000000000000000000000004fbb7bf2ddb1d3b35d90e6ab6f290d34fa766ed15153aecba158304b0d4cd3f7a9bcb24cb74d295e47cec249cdd46dab951d0ad8c946512b14ea4a2c0cd07bf727b1ce8eb16228c4c0351d2705e902fc733642550e29ed42fa525679ec99fac400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd1b460fa2859186cae3d9db3fbb31b15852ea6ab67f1b04392be616d694820be0a2a2702892a7e8ca31ddf080e035b1fa69ee09276057b38c4dc42cb92c6e9cec622fb06c61d6b0df8ee8391ec86d6a4e0441f5dc7e27e58cd901c1ddbaad9658ff964bb4120687df46823e5d9364101225c24acfb5d615ec808761b65e7344020ea406d6ebe2eb3920a88497d6a02d7509d1a320d0d40bce3284a2cd4cfbe47e0300bfc1f0155a46be0522f16aca86e014383b90a69f78976f1855e81c049dc5170b04103a5523353872b81f6ac15fceba0e394d4602b6cb96ca131ff59e332981c02a47a4b3b4658d7624128f05fa9e7d4a3ec706b961a4f92eb158fe11fa06212902260c8f74ae5a04328d5a033f4b00dab36523058f866ac1360c4e151c545d3a5d031b672d29866af76138980ee10bd00c71ed580e1e1f3cb3d34e85ee7d606a9c0c0304b521cae86312ecad1cd827205e15ef4c4e1b1a922577da34fe5f441522c28d0311f0121ca4d86cabe67c79986230efc66d6ccb93ca5b613f4f0ba2749c187ceb021a83c1544773a0aa95b3e8f3c4cde172fe7198e8a6f317c34807d7e46c4646fc4b76dabe8958130ac3767e8bcef2c3685d36b0bff52b73b32f7a72c20c81cc5062066068af854c9ef4052f7b2483eae066519228945a65b8f93455fadb634796e2127a5338d09c2b5d9cdb930419a7ef84016b8f8e7eb2ff1d7da8c480fbe17ca9901c5a79a1116fbfe44f38bdd6a3a341be29b9b50f056f243ebbf6b7f16282b12a198450799e67b67ec2f109f8163c573eb4030fe83274a5f947af82f51c66aeb713ca0b7b06041ed587a6df91248d6fc93535ed8b54992538c22d1d834148f224bb26ddd31098d5229a69ab6b37d87514c2cef37bc09e6d300ef056611a2efb46e25040d8d51c17a6a95db2e7de0938ad5c4bea88917d1e623f0b186526efd47506615c4ce42bfe5b2331ba2d29c5eb2a4c3b697e9027f4345c3c06e0ab48347dd1f5ae35ab561715bfa68922ca1c11701d46139e5499f022b4a64c81e94f1a8ccccb64131a95f628af7f54bf84f9577e4afaa54e22f68a6347136f9a5a3d3dab2e87b83c8bcdf63ba7b5d155608fdbd8afb7eecb424d3f22475b8ec58b1db065d95c392dd15862be019dee18a9f9d1e73d37ef27d2a3ec8d05c5b7166614a9236d8ffd3fa45abf662d1b25311f9397469d5b8e0699f34254d6b715929dfd8116720d69f073beb52c73501817724d089e7a9fa2cc3ed41d08db8221b703f2c79a67ce0e0f06c12df2f257f4adf294017ff48731eed4a62a24786c4b8518409d48b05c2bcdec0b78966ab9e1add4666100278a76befe6d4796bf4a4f6451404218601cdea30d82a3d5a35e45829377d17e0296dee40c4e62f15e9232d5494b0f4c9f4ecc95640d5cd69539897d04cc8a5a4ad4d4c3b31a6311995bb80474fce0faf3eaec4e63fcb19948c120bac49c7b41863c769aedcd1e0c59a0eac3b4bdb1e5b9242023fe290570b8b8c749dd0b3d956e6e7def2711506d13f27ed45fac7f302573ed7815c8dacdae86315f9a2fa538a1760a5d9dc34c9dd11bdf422610dfb6eb9eebb0fc9fe901f3cc635a9ada5dc25d450bc9eabd11435191f5e28da13db3c79ed5c8505bdff9f1c9332fcfe1e2e08c500cb92162f0db4ccb2fda920f726683617558725d6024689a50e5c5a63bebb69c206a64b0974ff887c0c22e469eac77cd8c6362ad840c97532dafd6dd711a3d9b1dbe3e76357456d14372c7c0484b31cf471b0e4208d824c747c088b3ffe410dc6df09214fa763188424559b05037ae2bdfb57dfe6c2ff1658385b058783da9fda2cc5ddfcae1210d7776fe8b53c642ce3ce4dc0de688ec2cbd8485776800fdb602461705bb565bc3662a83db22bb1715b25730ad4869ad3bafd1703a2fb287fe9186f9dd1ca5f7ef6cfb84f6f447af1386b8ab488e53a6110a603c450f9a1bbefd682b7dd614a9b15b9e30376b8fa684118b482c0e9df28668a7bd2416ff748cb56d1a59c5cc9dd03e95a8eca2f7163e6a73e9a77d2ef6b43c4a083b9b77fe4ef8f9a7933a8e062db7b7cf9ae04df1d22395cfb10fe6e4b9b8f36cbfb7a788cbcc3aae3d05b5acd847575d1b689bb0b41e1ddd9ec2e9357c8340926fde436baafeddaec89975d1ef56264ff6bcf85099448a5ad8558ae8193d19c7011133140a2852e5447fae463a3828a331ef24c3ac06199e25f85fe0dac4ce3df583dc712d286d1637fd4d7ca4f1cb34d7c4e88d2ccd83d816aededaa5159cbe68a53000000000000000002248910000000000dddea4c3d892a156383586ea7b98405e335272e0b980fab7da03d386be8d52855a5ae24ab3bb13878f703db1184d015f10e1071a5a8272d40074b9c601cb6b011a865aaa90d60d315dbbc951afdc7ee8ea3b3673493724e5c684759fa590d7aa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000291c660fc3faa8f844307ba6a49fa17a8ff3f8a8050d07addaf3e6c2eeae6f8720da35e6978bdfa9136a09171cd4a6e4b84e71c2c46289d31793d8ef464fcf9b297f6c87bc38cf539a8cee2bd9ababd756d793cbd32edfa764a966e4deaa024e268ab6d647732d55763cf68f53362c774503375bc44288794bba44befe7212030311b4de8957a3342990d5862f97c1acfdb77aa8648c6dea8aeef5d7db17d18c470201db4348e37b66d0b8d52f97305d7672da1fd6a5fb87d7c44fdc7504ec2cdf670b043c26f4a79592fa4b8e42492c60f474ceeb423c019ca281c7e123b87942e24efbb078af83f2d3390f1b039152a09fae3d8c34c497d402d821a90ef1bf248733020f7a13368184c142e6f4b19eeb6bd5ebad147d0b97aecbaa57840247e33eca22030904a733480cbb4191197be262e9ab4eed91c0d6b075a392144e824df1576b36021ad2249df354efe1247a56441aea44d905c6e3853a52aa18402ae5a6771bd3d1022afb947a61dfdf2753d31272104525895fd65def42d0968b3b658f181b32ab7403119149fa804a622abcd77155a34e9b9517fa6e45f7fda4c08bd438594f1b076b95bfdda85ccb2e4e56580f31e551831e1ff35ee857e8d2cfb39c76c298664c4747e131dd3eb478be7202425bdfea0f0a42c1b2090d90201a6c3067bc2ed830e2d312b6795e5b27b28ab19141a9d7f8fc1b257b9dabed883d5116400bede0c2743a233658ca7b810e8f8d102b3e0353cd0bc4992da91ae53780bb0ad6d06088d4ef18998165420be646c823afc3df33a3d73091737801710007833d73311afbd372cf2f2706fdf9e997ab875596551d305b3d53755104069ee179bf9aa3fb2867c412ef799566f215fa385a27dfb31608919a54b91d034e2d24eb4e4b8d88f40c618855cd11c3c38949cfd3ba1c0dbdfc1848b2ce0f13d6857b48be7aacbc187beeb63afa190d1a2f84185b0351648cd8509adb49f240626efbc7b8b9df98960575a03d1993d6bf0d93f94e0c837a07622f2c2e68cb000dc25b04de3db6694b3714fa99bef7e80d831cf908a86c146451a4952b0c37c8afbe03f8cea5b2a11ab2e107b61f1dd7bbcdbbee99499e1d5e463b0e06d688cffd23224515a8bfe1ae2f705900eb6de642ab46c725f5fd0f2517dd77666ff36df5100dbca765c0e2e34f2e50da19d86201541037ecab7f8ccc27ffad774f83cce06c6e362bd4afd6b01522c8dbab4eb2bac09bc8411d7115fa18d4dfda31ea31e962dd69a1534219b895788298cff5218e60dfbc75923420f5acd57f08110321d4da1d0140c0eaaf889192a4c68768d95774dd281bce4c64c5bf0fddca4da462b4333d3b9df8747a8ac93d1a6e0052b6eafe2fc3973077b3d0fdb66349deac277830fc8d3069130d0a7871ef5ffcb700a805bae1a02683988c1c503cdb71ca067e8d9ee4ac24d0a84a318aacbf6c0ed75c5af48f2d2bde6cb2fddcdbb8ebf532df0b0e64f86bda6d10a4953195c40ce105a187a34e62b97158a18e599defa7cbc66e90d08427d09fa56c0842b1494d4436cefebc995f7656a18ec5790373d3831e2eb8da740ba77828eb91fba3f16ea3cbc635eede1d21eb58f4949bee8dde81f1c7874c0fb70ec2bb2c02b6a0fdd7119958eb3f078e6d7c2a7abfb59dcab7f343d0ab024b1700021b1b05a160e98ebd2483321cce96135a36ba90ad5ed2f57170753fad0d1b8ac686c902f3728378e564de32cc9e0906ac37f27c905b6526373e79976440931b507d450762aefb7142f7f491a83e55ded4c161fb491364a69605dbb50a453a913ddbde6b4e08ce1783bf539c15a7db57032d96ee7b1964213b5ed98862fd8734aae01dcb3f02cd7a8a1d5fc90a4b3675845cfbb4e83569b01969433bd7756f8544c801d0a165e13f59e2bbdd9ff4531bac2b9924813b0808d2dd8a43895e058cb857f2927cc8766f8573889c62c1809d3559c3a39efb1abe928e64275d0202e186179c6e755f4a4248d75cc0913d6ee8ec2437099b4d59b90b569c93ac97cedd7f2196560b11ffd9014c690862766393e7e06834117d50057153f5b60839cee5198e6d2862a8ee55853a0b14dbc3ef2ad867b604923fff356beb53544eeb176ec5eff03dc4b06e2b8c436a99b5cd3359400bd642a17e0a7f7edc1239da43e40ff04a465ebaea561ee26e0a53a38efceb306afd86570df1b9f1df2cf835efeb3031ec054f42ccd76e0c800b1b04f880ea6b884a3303753983e0fb697a1a37f7c6a180fdad03412a251625cf1acf370c6ffe279c23d5a5ebdef910b88f792665563c83cb5bbfbaa52fbc8b1204cdacf8204640bcb45e308bbd4e84db0b3fec531c600b24e8276a21ad82676299f4de1a3fc7b0fdcaa9f9b6c966b6dc3b29e3b4dbc94d22d004a74ed3870711f486f28e83523fb8700c", "5251636563006a6a63", 0, -821722306, 1537743641, "81a1b9735cc730c6137fe3eaac8ac750598acdb0757e84153ff00cd4d0346c53"], + ["3b9b45780207f7bfa2854617e065673b807584ccbe95fd2a414d120ebee363c74488eb1833000000000353536afffffffff037f8caee30747e5145eb706966f2f59801af0c4933a8ef49962f0c569cb48d010000000363ac00ffffffff01099014000000000000f0b9e2be02944c550300000000000000000000000039c3b68b9032f186aed9353e5d879703838f573d99bfa75dfbb89015980b091fc57518f0b310c2c4146cf206ce1caa7a7aa01c50392e17c887eedf249f7c2d58756c21e0e5dff7ccb110fc0c1688d964876d73ccb65c337ba9e426df9f417f4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c09bfdf39f71a31e5f1bd1d38b21e0d1b68223216726f6d0bf0986dd5fcb5c76e7edc63c087a6a08e3844aaef764100f971fb0037c15d4fb40ca1f05eab441fdc05610466638d6e0376fb335c6617545dc7a52c2d1918463662533434c43484d4a9a0538a085e0969e2f1181db09204e63b76e3d74915f0bb2049d38201112250320e127577d9e2c50b3e2cd3f6c71b870fe0bc51999f968358c444d8dfc706a01031f1ba499a2ab260307d96dbb1ca6178e7dfddeda14e2b2f78bf79115e02d5b800b06902feb936fe0b31f1fdae8170fd8c415ae8bd70fb396972debea03f3d91c973bc5f76611db3ccfd5a59c14403a7cb46ca8e61fa30467ee0346be1c30437f5f0313ba4c9576c628e79cbc11fe6b0d4776ccd71ef666cd567348d4db971ec4ff1202248e5489b01b89d11ce1f05d22e8f9ba1989837131ac0e2504972e6e68b6bcdd021fd3275f38244d4da4acff4c7a2c616ff66c6c160e11ce917371e1a6c02b67df021fe993d7a0edbed3f0eb63addba8f9c060b4393fe127995a4b2b9a659a423e6e0312ecac703fc94575f9fc696b3b49bc773a40be99fcc96a4f367bc983adb920647ebdf24ac31d6740f2cf186e88313970eba39a5492a06137788f5343c80b32e7c884cd4bed7acb886fcbe27c6132844e2072d2001cc7a9d8d3adc1fb21969997cfd3bdd040c4afe1a28577c30c77c17c6bdb21d1bdd319f0a667b3e95f73e9c996f5c2fa88f867d4cde228ea240a7122eae1e00dc590c929a2660ea0188af0de01a6bc1f0104c415d4bd970a8fd6dbf482860e50b5086036c05fbb95fa78c0e706d5844ee34f174206ccb76fa8b7cf654582b17fcbbdf11ad0e6c4bf6928ff7a95e0f16f46c70b8d7bdaadf2eb9fc4c38528f9db2424815f0afbc5b99ea9d6e934f5204276818a1c8b0321e9b865117a4167c1d73f54cf7857898821573f7e6bdbf59b7b597a434f172a34135021a94a4f371cb69344667d0c021eccad54244ae0820ddbfedba8b1a3dae41e2c9b66629632b82ce4d0be65dc00fd6acb636f6752dd558d1c737983fe5d567430f50519dbcbbaaf0041930122fd7142f2d16e5c97bb07f1db519cc85023b9921d9f317d9aa4a1570b4c02cb9e31a3472c61f60f6a372125c000a6493624cd07c48c21bbb1056a388af5c73b3657c8826997c19184d16fe9dedb87a9c4edca3d80d75202583da5399344ffaeeae53aec52fd4f74470858ea52ddffc66225c31a91df8f0a8b3778276e267dd46758f91514295f22f6414197f847b46f976918610dcaf4e6e88972e2e978790f0730362dbfef401d691e96ffd28e3d97c881aaab58b935a22d9610d3011e76a5b17d43806fe3f507c7d68f71eae32c85af9502ea49eb034680c5e760a0fb5e0264c3fc05f6a3b20b4792f21c26befe00b92e5b23935a808a714e5731afb9483f5fd73f4dfd99b34e2d37928286a4b0af3c33825fa8aa9a0ec64d302111ec360e56d6b37d0c1112c76d85644ec8a8b2877126d9f46581009ff3ed6735a1128adbd4d9a4becc3748f8a6e7dec600d8c9631d1f1850132d302942aaeb9db3181a9bd3defb9cdf3ed2bf70b0fa3e40a3f6ee957ef0097d6a593c9f87496d26eaacb7ddcf46c976dc289c8f5acc4e56728e62d312b7182e5a919ebb050736133a2f951b237d909e6d7f5515062d5dc469949e6eed7a15821188146e8a31cb388ec2ca27b2cfd69899114bec151d06c8a9014495e19dcf2058a25192df81b202e25f5ab58ca8361fb32b6cf78779b7e3c729f1edf7981c84d2f82ceab32bee6f8aef9cf568d7ec14851f7e64ce57a112afe949b9dcda9230e7025bfd18cfca6810bd9f47aa65af9d56285166d49c8ab4ba92fa3ea87699530bc314657fb265129967c4e1be5746b8baa7f8c5b043875c2ff0853e5d71799cc19497e1bdc925617b690bbdaf492336ef29978bac3b8a622c7cbb56af785b5beb24811f33ddd9fe679d1a2063e0d5c22c08eac34141476c05a9317d557d6af41a2947f72bf8762d2470d9d937e4fc4cdf351af318bfa36415a1ae56c2d859f1f3df53a08ea53be86890c4dd0fa3d037734aef6346e14e21d549be31415d0f4f6d983de78897510b6c5466a28f14baf0cbc2ebca0348f29d7770e3835409fffcaddff6430cd50f1b683df506695c15b1b17166c07980c9796cc2f8048f26769222267a478c023e234d1502b0151f2dbbf11315eaf6550853b8472373ebe602fbd9625007a8056eda6788560ec9747e6eb97b2303c316189fe33ce18f7ca1028684a515875c00000000000000008b74a604000000008dee903af45a9da8f852526ffadd94e2fe072a23caac6277b693ecb05031d87a64ab2ec1764289e8122bbd5123da5d4b1f44b8d84906785bcb948c492a22cbc34c2da2338f67484bdeadb62c7344e7c94eaabd490581e085e46d3ccc7f4a252800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c55eb44dfe81c4d36811116f00caf77ab4f94760d918b967d81b3ec2be09c7be8fa18b67a623c3361eb088760682a917ea585f4e6f2a428724c591b8aa08827ddea321f8139e6b1c6fb8be4f92586defccd1a705139430bdfb5ef864b41ca96ece4de14831a6e1c9bb0231afdb4019e6a3f888644c404a2612616e29b9fca3bb031ec804bfd2f7519f476638364eeb95e2bb1ea4b96d9a111c705a923baa76c023020546f2d7c2dfe308eae719677523a0004eb9a85c9c60c529330c23ddf72108160b07c2fe3d575cd153431197591f30acdbf69b9b59857e01cb8c620421235d311d9b2fe968a3c0e714227199b80f0ba72ce8402c95e178d06c826b2bdff7025cae0216916c9d8e7e48d3667f732975db9a1685fa644a8311a354bff3ff0e291b26460224b1f07d93195250cf796c1d364c19aa4b01d26cb563b23d22bd7d02cf60bac7020add8d8a7edfc73b4798177809a83976dd8bc64433ba4ab84fb2bf9a93c3a2e6031fea4f407c4e8dcf160ba67e87a01cb9ce9c450376598e488cdbf7d53e3a59580305a86153b1aea95e68bbbe88905884bc28cc9e7445bb177198249728ddd35e68584cb69b719cec46b1747e89932ddfe0cbc584144e9e218a00d00f910244b89be806e0fd17d648202da8e4b3ed13e607cda2124ba978f7172cf6536f42eeaaf18750c5f18155b9195661d5d938fa4a399a0161e25426a42a33407c8abf3b5224c9cee46a81758892b15ec066626851bed4919a860b0e1476bc64468c101aa5a91bba96ddfde01395e65c09251124e7ec1b02b1c679ec64a9a0539a8fcad5b4401b6960c38fbb539eab96e819cebccf3a2e9ed0788cb265876a4fbf54d87e5b9b05ff0e47863e7e389c86be4904459bff915df428428f78bc1d1809a481a9f77ba913fab8e5254ed493126b66cc890dc4d93a06d32f85769c02e8e1fc5359320aa600a6454e1ebfb2088c6348d550f7396ab3bd091856b8152b00f8105e3c03b1d1ddf50b9682307e0840b49178d04417321b1f385d53cce4ee582ead2cb4233f9f14a3e90c8bac65046cd5382798715b6c8b08583102a07cc4a4fab529fb616594657f01636aaf2154d9e56d8dab7360b320325ef43ce3a1ff784edb4fac0c704b5acb7166985b9ce689e88d39a92c823263cc12ad7b80de5f0b22f68fb64fed4a925c2a8b936de9973e2f3d51b50cc2ae399d601cda6fd72a8851442bcf404f046ddda73beafb387b9fbd4a3badf2d39f009c7dc629880435ffa39c98738d9388b0aadb52b48a5f9dcb9d6f661df52fcec02c1c57bfb83358eeec684d2a5520e755c4f8a094f34c97f2201a70d22c9723bb21e088c4a75de0d8e24899dbd668de69931d2cddf875201e4d4e1b455736723fd1f83ff47dae90c8d13a5c795a3aa139c7de48c221730da9ed71aa5e57eec0570edd8315db9e607e9be30670799ef3f374ec2f2224b3029ab25f3fdbf0090359077ed3edcc6ac16d079d483edd5b502df88c1da932ee8c72fae7bb033486fe9bd0f34c5597e1a2cc9870d93721b9cae9b268066b16e442ba39a1f9d6e1bb2e499b85a487e037738d2d654d3b2810e643eb895aebc8c4d31c30ee1330eb50a35c850c97938517061dabda88594feb7fb17ffcdf323d692f016be0fe5e41c66dd7811163c8d84830e066ce76f349774d581d65fae89f6958fa59b5a1d97b61ac00a491726ab5611de937e258c7ce412e65fe9267304ff89981d7a6b0186b692f5001e8906849bd616aa4f7a5c1f104aae33eeca2cc976d3456caa14cd91c2dc110d777a0d846b8e8e7579e2bd5d58a5ab3bb3b41f46d83a5dd917dbf548c1ce24e3ca5ee09748ed0c6502a228c1a38bf033e743c8aa95de09b99df18d2e2dbf053ac27219b25d0f405c4be22470fdfad6eeba748ec98b0cda5d30e04a123d4f20ee0075c5c0ce4b3e88c2675a4f219844dc7e63090897ebb6075dab19229aecfc132755b3e5cfd1eb8d0522891186e81db9d721e453caf5b868a138672d9c4f95e6593a9b418dc61ac485577dd918efe2f4fafbf83f37884e2e20173aee8c79c17648f5660002a2bfb0279664999c2cfcca073da2565de88010369795c1a6aa9f72343d233fd2b7e9a6561fd823f70e94120862e8eac7c00a3e3b82bd0894e98c5bfd5a0ea78e11b7faeb1c730f4847a60640b828ead1796c670254a7883024dcd97751b55a5e2e5408d3d111bf4e0a2a7ae3927c7c7f0b7f977a26b96b65edd66a16912ee1716f9abe643ac5abc22e2e127a0f96073fc01ec83ddae8096b02fd152279cdc49a5c23a6beeb0145b91c7273d5467b3d0231811289376a7319a8da23fd2cf1d2fae16f91aa48981f6d911caabb946647d57a782e4263985412490626bedb5b5f7e31e9d07b4fe0c6326e37bef2dac0962fbab573b05645242557609", "00536a63526aac51", 0, 570397389, 0, "eb2b38e156f1b9e9fcd84551cdb9957b0b8d4b9350d114eaf3dd1714adc37d38"], + ["33aec4100292ccb42576e997072e5315ed7dfbbb6bae5377901b3b92f02e8bc82ed3ea8c7702000000086352ac63ac530000ffffffffd4b2b7310518e1316b8afbea94564838ec4e501de880ad2788622230816f24fc000000000800526a6a6a63536359157dcd02b4e8a9000000000000595cbe050000000008656a53525265635223b0e5b5020000000000000000fe047c03000000003a65d07dbbeb9a6fe3b7dcb3ded7d2ca86652d986958671c5ba67b83873066922bd9bf5015650008a3a29ba4268b234eb961cece388809566f283f7428c6e00c74245af2021923cc3625cfee2030aac22a8bb6c1403516079b1472f0b27ecc37000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f488b136fee0935335af50509f1d181ac7bfccfd6d8e063745e099bf0c7daa19e692067fed921aedf9c4afe8a5fc5bbbcff48a429d8e0821eaf2927e212f957cde11f5b468d121d5a44522c6757deb02321023154965708f33bebe7a37a8f45b11f052f51def0f6b80769e6d9d670274b4a71056283061d79f5ac4c23393b0703302f7090b48380a29751b994bdf7ebff8cd1d76852f49c412a91b99e06f2a3d3030d7caa34784a767e0d25d98844bec72b06a4b3b8904b42f5c71bc254163ae2ed0b04439f82871e9a0636f9af098fc998a3f3c34ffbdf581e506a2b7b8d8ed053c860d69571e4d98798d8be5e02f972551f5e327c809a0257b5277a70a1a6265d7e02094de109ee14310b76024bd02000193ec518cbd7401522b5968b147c3ce87d630217d040d6e68998acf1e6b2fd10b144f7b8d72da3fb542905a9ec9721b8e6be8f031991c24db2f0567649d796f34795a48c640d2e66c3a94684cbea060762090b820309022bb5f2c3909480e0d1d8ceca1ac6c8c1292107b1819df0049fab1dacf33f030ceefcab9ff14c0c49681f7a8d192351b3bccff518f2597780c177b87523df0a286434f083729779a3d1b4e6de7befab932b9cbc7c4790055bcd765688ed6c2494ae033aad4f44a0172aac4a3558abe9c7f05941e3d75be6c2bd6502fb23740355d69b88fc9dd51ff5b518a485f1e71696f6d3cee67203b6aad78d8c9c1a659afe353756ea91bae792ef7f8ba4025c4bd8fa548a19c69bcb2e801479eb51618b7312d8601be4e9dc93a64bc65188bb180e88137f145ad3012fe7eef553e405e859d10c9d465940d80f8fd1b8a58668e3872fdf1ed0651f128022b3278c2e17320135d528c23d7fbbd5ca5fd3bf9c306cff7572b875149a9197b4cfd85e4c9aa72b76fc9e9fd20cd0babe501509a75508eccff42adc6e49a7b8d70e8649985169b7a1b1fa8a8b5db1da8097a54586e36840c0731be4e9bd5f62cfdbcccd9fc4461a0b4ee88789e510d6ced8d8e2971925c2d2e0791600432e9dcc25c1e06474762fc96a8d0d34e0faa56cfde9a5bf5d04cf2a2269480b2da32ce1321afb368f478d84803742a3dd61d727f3fb1a53f07a2bffe071bcb2b6a693d0a31c19ca59c012b814357d0c873fe42c9816e49e38ace78ea9f0b96d3ae22032eed8568366bb3ae427aa06f77f1d09670ffe48b55fbbd186954f260ef4f27262e13527cfe20b9094e772f09ba083d0d00124ad57b910cb0541b7ba5164a739d97e8cf630e4da2337aad53b2a74d886aada1ee9491255e2f919665323e5abcf371031d68993e81248352c2dee1b9a9d1d83db652b84b8624e255c8ded6d2a813c6b77624a0a60d920a0b9c9192203230838be3fb35d999d16bf065de3ebfab013c9ba5e33d1e9fdbf184845ed942f445ae75c7c2fc84eadb8880f88dac1e794d97116c41870b81388e7951fdcbf501c983395e58c7173e83f33b7124453c693814664159ac398c1d313656939c9492fc80bc445ec0d76af3240bbc1e1e89362c71e418985596ae347b4b7bef683d1fd59b2fef5cab7692ad34468845422378b5f0a9c676673452010fdea17a84080fb4ecb89ed9e3e3436cd114811c7f65fd79ab2cbe5fc90dfca3c1adfcf421c33a2724a3721fda38b5965dd0736fadc95817d3df46e10cbb11078fedc3043ffb52564477c5ce695b19bc723a5881e01f48e3efb0acd0a2c2230cd94f4e28cdcf216c6dcb9ea8a3a852c0b729372079b28d88889e568e699661654cc04d10f92e965a38a7f39d0f9d753dcec374d262d1f20eb549470ed40b2ee52bdae1cd839763ad0223f4e8c9dd0ce62f431def9354e6f4ada310573bfd3ea79906d9803f6deac10897d733d870e0804b4291d7d9d0d1a187e6a1e007f97fa902894d2c37d6a654c349e4a4030ccb355469a4561d3fd3132b8bd9526940b7dde7fa7e6690f352252451eb34bb7ba5ef1246ed0197fd78c6e82825a243764c1fc5eb7c6a690383ad770891d2c0e8c2748b7308d3d3621230ec8e244348457f6050774e6c5ea505b538171dcb34ef28bedbdceffc9b1c88109ebd4448c82506422f8539bd92fb2e5b40186b22cfcb4b08a63636154ec064bbc6d9f1dabe8c53750561f3c8962aa9ec3492eef2d811a28db47a72b2029a105c0161f72c993b656b282bafd5563c14e0657e9b3d61332578ca033f41826f0afe09f0f2b7fbacaa61143f70165a7d16d7f3fcf020a1b5680684666a7fb589564d33b3797fd954ac1d48d31d8ea1dc1d4caeb5ea9c31fd3d0bf0000000000000000c81a500500000000c7714450a7ebc02035c82030c1ced7379e67a862c6f89c773a833a5740544e6f0b93d200efe841b765d3ccc4b1ab775ec85f6c0c241492a474c6fdec9409b4627c0cb096dac37577eae82a3486e6ec289c45b82728d5509613ea382e31e4270300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c73d288d6c9e8bf8175254c0eef84fb0eb16d523b0683f5dcd8779e4b46db2e133a8dc7f08bf24cd46d6d608c35625ba0c595fb2cadaf6ff947125ccf695fd7ee0c12b6072c563883c1fc135f588757f9e38870c6c4feabebefd42c55143a15726da9f10fb9f29ba5f6e401df2ebabcdc268bf10d65257c43d21d6aa3ed824f80226c0c322c0bd5d627b243a7350f4738eea59c551dbbd296102319b1151888275022bbd9327cd09f64af33b0ae5cbd2488ef5591ed2316add4f53a7027d76a76d410a0878b8cfa27527677b23714ab47b697fc12e13cfcde0131d391dd4e94d7e145fe2d7c4b7c95f667df387f6417aaad24a4859b8643d29f6c2247a3454876b2859020ef043147760eabcf31515983fbbc781d0222be30ce3ba2474f37166dcbc1ebe0219a17c65060176fbd5024208c88f163a1394a2442384474d54b7bff862676b62021c661e72179a71ae8f530e599ed891fd122013f72d31b2f32a0095e7201257f80329a0bd1e107c23c9a1fd6f90dc6674bc0c6e71ce33eb3bc497747cdf5063f3a002217c3af1fb43a282eb60b116b1831eafaa7983567997ba69c79c7c467e8e6bf46a62f8a00b691b281a52ae61069297ab523ca91ece84b4b3658d93789960e42cbf803b8498d40fd178ad772172a2fef01774e4b16025a796d092d00344631e80cfe35737d1ddd7a85e20164629d50754a02fac00247562aa1038bc42cd5260ccaf3a4292cd8f9b27e06e621b25bf7fb776ad271950ff2db2fcf3e2e849ffb4ef27d15b90c4fee537aa195cecd9ae97fc6e169c44ec149cfbf8e30011236d7319b4b2d2ccadcba82e263b6f1b4c9da86e6a7febda94dee49a1e8b90c6a3eb423c2d6ac4a051bdfc1ddcbae288818f3315c176e12858db7a5f466eec4ccccb9a69b996e8638dcbafd203c99477fb3e29971b937659ad51e23c6e58aed9808bee491cc87ebaad3d20a46b7080ae4ad21a2c9d646fc6cd7f944228c35bee47fa1c4b3d20c89ac12b1d3f2be4124ef64fb2511d8da397175613660e226ff850f36ac17fef1d26832ac55e75f993db65f287e71c06ec8db380232a090fe3e3e8883eee3df6d76535c9ee9825242a3fd659c159ef2e8c253a953ffb4f7582f9b52346038eb49198a762deb519a6b441f446cfbc37a8527e1d187b1139589252a8e321bba056f65ebf98c62f7b08893718d50045d00a099920ce774279a9daa3e96246eb2c0764d4a76c69858554a7e97d66b7af5a19c9a8c6df8a7e8530c4db1d5d41c089d051728ccdaf4518d369cf3e74891428f31a5239be8c74b2cb6c2f5dd918ef3e5775129e215bb2dcf6b8b4258c76a3da278b0f32099b749fa60c53526a644037e9e8fed4c5967c37e5c1b3e0358b148ae141536534b908c0cf7267145132537e8ca8e1905a16f762a8176978009ce020171c1b1d531ecc7c8662fa2791d75fe20f9a7774411a41fe38086361f3f42dd2b40ca8701f10055c09238f7a3f66fb8bbed16bef8ebbe1f96a4cd0518f8368fcaed8f379a5407e0b36f9cdb4ae8704bacb39db41b875ea5147005257d89f79d489e9149a7cea1d5fd9e8cccc236ae0a2790ffb58b8dad5b6873767ff423abfaad8e445c8768ecc5a54b1d8896c6d45b99733fd347835621a2e56dcc33bfd42b5b042cc3c05e713fcf77c8d0f2cc6bdb7622def9ef325afe3d8ae07e256cc024ee78515561324561d030efa8a027d460cc0e312e4b2c58db2fc359a0c76dbef8de19b13502aa0be8adc9f3034c97edeb929d985dd81ee1c5ff988a0f5fc4b3f8260dc7366fd8195dcbd08e6fa05a164a4b8716aec111af315dad5e949ea7330390be2ec1c5aa06703aece2f424b1149495fbc33f000d7d5e925f5fb96b45e07161f0d4c8847fa04894bf5c27ac6c3cc1e1e9b2da8d2e1356e721990f4b075948188327de44a88d9ff77faf1b7edad980fce24caa4c17528b817020e969a3f3d299671dacc96d266a8e65e3fd248f003c36cc3954a8fcdb3051176d8f05a6d754eecaea573f623ce264cfb9e468c7ecc3900cf2accc79729d2b282fff4a56e2811b65f1a70c11578d07d007fa9e36f8518c0b45ad4f3ba18933a7c89000fc42286de8d89f391377ec1561dde5a209e9a04997ed67a7d6b9aa8c7ea05fcc7ffa2f9b59b3d6305ad62d08ab5d5f187952dd848289eaeb1fc46434dc58628a6208e3a6614c546524253e909534adc0e2dc25f52c14b58df8fde5e8bf27b97546e619cd87b0cb9ac2ef585dd6132e87e08d98e35d6362617723aadffd80960af256587e1b1f034653cf1b213f1c14c249beb0e63085c9f13c5a43659ca40995b9369fd429f9d94af054c51d1899cacabb56ac7b40d1b6450f5439bca5524c2f0897790264634634d3d3ce0cf56587e6d70ed5277bca28b60fcd1a900a7051adc866a480c", "5300ac52ac63ac6a00", 1, -372912135, 0, "1e35ddf28f6ecc28496caa60711a52655814c31dd9826a173df24b6150273600"], + ["0d61b16b04ccabf3048e1cc5559723a04b0e6f120ba55153734eb8e63f465956923960501b0200000006ac0063516a65ee5851cf79b10263431ed9b36a6aaab987ccce5f50c0e65b6404def5e1980ae42407042e030000000500515200acab010423d7459f5051f4591fbbe5b3f1b4ffe805c4cb6c4fb77866d9c1037d9ccf36abd40200000003635100ffffffff39d8e1ba918c37dde4139bb40518b65b99cf390210ced3f7038849e5889ecb2303000000016affffffff020bc5b1030000000007536365515251514268af0200000000055300656563e27bcbc50200000000000000006a8e2c020000000064b33f8726e5e067d134b1e49332b6cffb65196636bd90ab4c899aa5e16d24bc1023bf1a490e445a64fa434407f9f6ff9cdcbfc17ba8dbf0a7916b8b4ca5825e8990dea243d181486ad071b04e4ab531117b0d8c711dfd0cf76390f56067206a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075899fdf44be99d843c26557846b58c04bd9a3698a05e537d9ee6c5df00bb2594e82be365ecb5934169751374a2a3810589cddfe73634e5d3175671a539fc8d0f57286f32060c974be7f69669e745d0effadc365436776cf7282cc694c40a7d7dd506bd61e90180651be455ec40ddaf8b248c0102b751f6b5c59a67a2801bced0302615853b77ad1fd79ae294b0a471751c0b911a8ff4465cad44b6dd258ab55930214a4080a73ac8150d56dc994aa46b635d917c88e86c5167e3c91d1ce4bf947f40b001d8b7923143e78138e460fe484e84dc9b94adeb87789d7ab9d5a19f0db94ca2cb7fb1ca56b08bdcb03dcd7798494d18935876464ec9dda4184f635ff53156e030639d183874cb57f8206c0058f8a13c311ba31007c013351f95a4682dc171125032abc72528935c4b26310be702e872a336df8ad4ed052c42229e6956b48c1a935021532e3868d147631f80f617ee251235eb3a1b8fa53289faa2a4e7c860d8d49000208e836aec7a21e7f5f2e9c861d4434007637eaccd9de54efddd97c75132dbee70323649aea9ed0e3736a490e568d663897605f031fce738648d45e78a6fdbea4f799e8138eda3d133db47cef73371c8c10e08bb7b7d2fe094331fb83661b26e2054d32abfe9a99e7f8276ad508ea9df76bf71d59bdd0457d89274fd545081a201721556ea024bd834384640e65ab995909139fda9e7e36059d489b5cfb7d11732e304dfe54d92444c96935790642cb1aba94774a905242a13637f341176823d73a39ef64e4e1bb22891a4cca24b2260e57b7e9c06abc0ab5393132c15dea5fa31369a757fc999740029df36ce5a9713a215adf1e1bc008654d1d1682dbbd680afa52696cea625ef796351b3c313bd3cb47438ed17e5266ae77f43f89535108334e4abdec622c078a1d363f6b59cc201d0b8dbd12b06164f516140a19bb78f633e21ec87413fb3016252e006c65d26224ca4459b167b9e57b210a496491da35f1e57aa99acb0e1bbd23c4d6bfd6037bdad461a0861288ca1c81962cc1efd35b065c288b5ccf741148756f65bd2876a3dde6c1a3faa8988d15d15942bf0d54f415d4d596b683c2c000c172495accbfb98b8f5ef6787f33673a528a60d61165af1d9b691d25709491a9ef97e00f9fc1239b3f47ae62a5be58a04b30c307dbfdd5f83cb0550aa56e4ff83bbb6b13809f29e53049304ac46582ac12ca2ce81e2bd2e5a9e5ba9886e58906d0c2a45799be811bdbc8820ad943cdfa01b041564d738a6bc3a3b5dda9126ef1ed6539d59a423414efe992876af5c324429223b9f35d6a0eadf79c0823c05910f6af8f01dba532d5035fc25e0fe24da09184118639ba95869eaf50332fa61ca8f827126b319790bd12b1e213d4bbfd9f6d5e3b02c00f3841abaef57a82ee5dec5b06a7068aca5942f5a2523a92301188c6a90d789cec7836604143a05329c975a4b706638733dfea6d18c73569b61bc5dc016dae3a5d2d53c5eb1f570f7fc05d7c4c4cc1e8928ba7e4cce0a500beaca957079f2e4e3636648dcb4ae3cc6bf1877c1dbc6c8b0df77f2c817844f5d63422d7e2b7bd5c2822d65f844ab32bb3fe379129f4afe4f952979828c38099cc3848d866e5bb5c877d111dceedf37a29f81f07e4a74459268b9856e72b59c42c0b61d1c2906db47bd1ecf74a17559ac9123634cb69d667269e948b36c9306ae2d27c9eb66b82e5ee37b202f5046bdeb20a6372c5568da0e74c65c541e9b54719d3bbc652ffaaa8c90f849f8f82d5bfcd21808db10c0b18f5698126469007057dcd50c15bb3af02589c136639becabb66d86c37e2e6d9e61866b964b5cd42da8f725e0d3880625542814eca6f356053b2f7c99ffb1826a931b9ce5539d1b9ffd86557664cd7d78aefa6e926ddc3aaa36d95f140a61b7f4c7e51324866be8f1541c84ac8c35983295c7004b6f4911505ffe29665abcda52f02955c7b5e6a45c320fe2acf9830c9beb6e9379ecb311bacb0282541fae11ad1800748c5cbca013522e137cc24f2d11b0d444019fa8f291d00ba2df6c3c26f03b88634c5e2763d59128f509ebbd4ed340adc54c5752e7c7b0398dd8cde4e98278be9fd08adf0f1123f6f2e952621638339d4887ca3cb7797d7cfce97b5269c86e51e89ad04d430ac951201e3680dcc7dc5d10baa139f6e255b2f71c8538bc6fcf7a8a5534ff4feedaa1422b6a41a02001a7a24febc7cbe3785de3141004a2074a7543658ec098c7df1fabc327d75405f902019e213271df1bc2819f1d6f886601711a7ba97970000000000000000a481880300000000b070c5de8aaa3477ae58fe13539bf5c624c3234ce6daca9323eed8e159e53fa4c8dc2a9e01b8e5545a9a538cefafd6c7f1f961fc7b6a1c687833896b58d14eba821b3662e7e647e6ea66598593ca8be01104e085df6225f429466e2b48ec8b11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b2b988b7a77757d0d6ba1103765cda811fd6d7cb9b1e7bbe2947cf90efd3f2bb464674a7d2a579313b918cba35ee2d8dbadf6e6c487798801f3c359d0b02959bc37134c6f8d8da07d1e003e18fdfbd83a0489bc46bbf1ddcf335683afe5f2a41d5fd203aeface4da1c11f010676b524809768ed8693e57e13ba9a9042f171ef0300c8705d955be30f965b24f5850dcf51e8eb1b819ded6f6d48bb5d6f233f3faa0325d8b3e80026649ad844e7ecc26e5859b7c997ef897e47a852b1be6a0404efbf0a02ca1c7fff79c7840588426e28c10baa5bdbc9b0d2ce2327544f5f56aa557c5c7172f3c0dd7a09ad14b5a1dcea96cd4d1eaa74679cf4db98eba384dc43e2fd9d031ea4d3dd46aaba2dbbfe83091cf32eae4daee2e00cf01693dd191e78b59d8983022fe4c5cdafd7e43398342b7b2ff1656521361e762b0aca918008ebf4c6b3f2240208419b23b6462cfe52f60feea72cfe92cc439f3674fc43adf26925d593213c3e021f604acec93ae1412ea22be170909c5dd714340e3e66f724a733201016788eab03124d025a6ed56e97e159b17af8ae2c9ca7224b165f6c1e3e9efeda9e3fdf828bd4ac410c28db253f464f4dcb2ae0d1ca06106cdf0beadb6fc708f9da6e21d31c117efdfb18fd15e5ed9101cdafcdf59d0f7c5e5bf682e9d6e13371e5b8d3fb7aa4b060f5e5e7b5cb801042a76c3fa90fdb870456435d7f6ef49230568280503b9edcd16f90a59dbe9888d9cf7b47d69b54486fa3d2783dce40d3e16a953eae01e0a25561cd1cab38185256f4154e6b39830232b7054fee75fae23f523b7304e70d4c5449111738778f1e5c676ec0b0559dc07862aca96d30efdb7bfa696df1527ce5300776e942d5dcb086ff1bdfdcaec09a0ee2cc628e58fb0f92fb4c5b51a8ac84d95023400c1deb1c6319eae10c70e28d48197b8ef17b6d1a2a58cbfb09543cda3f19e91888fdd477ba5664cb138259777226cd435ee3c9cf34b8cc0be79636237e38de03185dc1290550719686f0329b51cdc8694e61eeb531a55c9cafc27012b0a26e08249d45c4108f962f8dbdbb39f2815791850d548a63858daee825dc7e7ad7af735c89607566362983ec9728e26a6554f7e1e3e12f784153359ddeb787cecb43bdd89f844802c39c668c35a69a4a8e702e0c4a30bbdc4cec89b0cb1817b0a2f6baea5805148f8ce9dc1a81eeacd1db6f4312dfbdb4de63e0cf6ae947699f925ad1f9de4271db420c85fcea6c91f3a4619176327b0e551de96a061ced409dbb7e75384fecf336607af3624f2b7744bd83503106d10ca48816142907515137c82f0c6ecfde6fd1e2f2cdb45d18c7249cc6bd79a8ade21f21f49ecc3ee8afba95e26dbc215e56f5da6b34eccfc9a6ec890e35b50ccaaa2cad3f4ebe270a5bb3eeb658e9643987b5230489ea33e7fe41ec93619433140ad17cbab4e532a463fa08da1f48f3ea3be7741a6ab5bed3260232de3ce3fc33a7d61f1d64376964be1e79be7b286e1392c5854aa66568b883727d9041a288a533b78b36bf536b90964237294de16b2d9796132343e98b7d518ffaae981cf99d7c6e2d32f58e26806497572f4a805597c81a47466878dd4fbf04679dd76fb4108cef4e13ea0c38d5b54c4ef2e1be74b69f753ce4c5f6261b3b60312e75e053f133ac58ca0788a28147005634a08f00f59ad9257f393f9d2a342b56bc4d0575de17b33ef524e351e9297f9baa8ee930f71db03903a7450b81641ad4a3d057d7d3213abc57b3f0dae961b5a534b3dff9d61ee51e09e12c2c78cd122e8a956cd67be56fd3c4ad13745457bc4e016639741c6124deb620ca9dccb47d2d1f69a8dd009cda11d594b652a3581c6ab0a6a96d7b1651668529f886958906a74bdcd8b558a945a3107ed003403beb7f1c5ec5dc4d1505469c9bbfd1ca4bfd857b12bf66f989d4ced6f9905133a4e5870e44024b3311256cb75c2092a8804624b8122774424a57aea2d65a16448c059c58b5425cf311a22697abc90be4f1fc7228d1abbe03e7ba40f2aa8e5e58d847bf1b4e24a67fecd567cc91348f3bf55b12f432459a168b9b9ade35ad02f31ff1a299880304fbfc5123ef97667da1a3e24c5dc413ab0e609ffe2486ad34df1a320c79465eea2f3f30a9c603d562fc9d1804afa2bf0fe1afbd379b6aa004353b683bf68bf849aeeef7d92e849a0dec06ea76c591c7710042781342508492c8ce956e9226dda26185e122d274d50e01fdd10125037b239d5d96516da5099582239c83757b710c634d6b539e9b5ec4610202e40daaf716535f4dc1d080e69e247fc3024cd4cfa7e66cf33028d974fac34074cf89585de6b1fd05d4c5771a604b31adf55129bc850c481bab9c6bf145d7cf876db2714f8cfab9b9d79d5283dc6d15a69b48ffc50a124f6ad9cf0ef0996d0e", "0052", 3, -502082915, 1537743641, "8a126f0ad39fb1139a6684e69ee303553a4af50737c25a2bb9c7722527d7a7ac"], + ["030000807082c40304aab3704d9a7997f6bdf6a7b21496d4e5b3fc0b6eafff4eb6072f66a77940f6c903000000056a516a6365ffffffff54d8ec39eea9550c300003c702a2ee031ef7e26efe0013f5f22c1b95d945b8f70100000005ac535365acffffffff1d9c9b0d9b23d2cf03dc4da5256efbf52d26158c403fe4b8854e0b3b5d566cab030000000451516551ffffffff4d1e20ef4af679f6ec5d3bd8fea0dd560045eb92ec2e4e25e22bc31adfb1adec0200000000116657ad03d2dd2e03000000000100f12a0e000000000001516cf24d0100000000080051520000515363b55be44ef87bb4a30300000000000000001432540300000000e2dbc278c8214c057b0307d05c0d253944ff36f906c4c6f4632df629d6097a8d80fbd372b92346da4b8940fa98bbb2ee8dbd011466be6b615752bcd70d2c60e7d27e6a35eaeb5f19f38d607399aa85ba979d61249e41b5522c59edb6da2bbd5a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055eddbfc937ca881faea53247024ad23e84d4b9f012bbca4fbbbad35dc6f58b18a911e050ae5f4d35809ac65ae899090dd1bdfc66f0008d0897187a607fd1a807bec5afdfaf4b5d5642e0a210ea7e982b897fbf0a5257b41c3f82d4b29bf0022d934c79f8205a087515fae1932a56f4ed15c5cf0a29d214a5c2c3b05c75c1d02031062f1b8b8053b59632b7409008d439f8fdd174feba54be92d6490e5738ee5e00212b4e19fc5e675dbb2949cedda9931953bf044db0218c649777861657832f0ba0b06965083227890131220f04d871f74d4290e3c5a5b2c4476b5ac7be5f6a5880cc5f9300f19f50ceb56d15c4130ca1ffc74946d94379f421463ced3bada60e439032de48283982c1e74bd2bb939763046ac2013f9229ffbc4b6f911c0d69f7d7eb6022ea9d9ff6262e9d514d542f5ae55e937efa698ec268a7746e9acb05ff3c46470022a6464833162bc2dc0841f49df904835c3ad772b8ab61ecb4d6d8fdd5ae43ef903045e280ddb791105ddfb6dd72526838893aeb37155becf8c3d881dfb27ef66d1022be61ca87db2e47381056371a88b0e5fdf9d25df599fa527d3e69663d277e8b762db9e023778f1f7e33b84d082b6452ae19bb9e3e3668e55ded12a4fd958c36dc7dc7051afbf4c18afca7c1cbfaf0c290b16738124482982d1c08dccfdc71fc174ad3480bbf541a2d5089582206a53795dd0702e83465830d1c269e784b9f6ea5f4aed0eefaa24004af804e4386ddef859b3c48c62a9adb767613f76ba110f9567c8266df13fd0ed28558c61c38e282c37044209ae8de588010cd38b76ad90fd779a99e07966b421d64b02f7b0a3185b168fe51da5d238604e410e801924ab6a1518b54fbade1f8509d0497747e20ac5574e73d21434ff475b97e673f51498f75872701497f68b12e29c82bbbbbbbed41fc79e9834591fc56ed76246f20bd4bb19e9a87ec24c04bef3e00c95c399ed6fc15166f2b9470f533d3a58f365cd0fb4ce88506c935925cbf5c550b107b8d8436690e4c86edf48ac836c015567703361bc155039b14da54c4e0a8286c52f2575f0c1e31051c49395d9db75a20e11f8895d5d4c9e64b6598473314102538d26cd5ce0847c4adfb736d7f841b5a8818bb2d6b0bc2709ecb29505da07e550670d413365f7d5522db9d8855fd099974f3b6e3c7b5811f5f4891a6f4f2fd4be02c591a2fa2d46255ec5ea80deb0e4141a8c352308c2165bc58f3a0c50eb56550788da8e770fef508d6f987d9c0f550c8a1627b26589031690f6b5bccb6fc176845adde14fe5a303dbfab13780d9c8f5ed2eb326c8e1ef9b21095b3a47c831753307c1945a96208642d68aceea2826d7d5503cfec092ff3996837085a8b218ab6853b40a23e5233ad66080e3e79b4d6949029016b5f1e73b2baecf1c463a33c9c18dd3ab55614c0f33b67baed609391582f645aa8e8a3ca8f97804c4a999945fd746a4a844fb3a6086033932c38f2891943af9cccd3da523ca7c4d11c2f79884914683e8b50a96412ec298b05da15befd7d55c4d02b401263c62e62b47c25d692821a6d8511811794e7516bfb9e29124960f1b2e815bb7e21ab69f2d63e1aad6885840c31e0b2619a5cd5526196cb1e2bcf2c4e616a170b965e75ec0922dd42ab93d783a6c3d158306010df997dbf2dd88eca5c95984f7d695eaee63c4109700780b1eafa6c1bff09b40b85ed27d3def95ebb4292d3ab9ff72f4c2870c66a693992087532347ad41ec7a39a481b5c5bbf4204797ea8e0b650ebdd6d69c82ed8408d920ee59a9a99d857b8db85f8efb0dc4ff51144615f157f7df56aa6b7d89317469a96fe40e0ff5ab644730be369a3bd634f90c258c229fe3e352415904bd7bc91235b4232d190f9e808ccdfbfe03b72f0d25f6b6afd901889ca2b49dea03a5a091487e26b7b0d52671fefc05c413eb7437dc2ed548f14aece5d5e6c9a409df78d03142022b40974fda081de896d01df24a0bba323c5067c7f784e3b0b2c281e2daabe8603ac1138cb524eadebd412d19f70dfea251978500a7e37321dd13c12b81c07c34f49aa1ad23f650184eaf80a325a46092da674ea1e2d08d333dac730612f30f072e4fbae8c599c92803ff3d79e6c40677db02a3bde17bc12df9456f80fb3029e11547cc88211bc18e1d9d247dd3bcc4706f9ce04b50a53158edce7ce907e32b73d0e9620af1b55b92e31f2c4f0b6a0e930e7e59c0184922766fc7623ed05920238412db2c33ac128b8b204057331c2dc42531e8916f77a18136c53d5968a4f323c4d850040000000000000000000000005b1e4b1d5e488d14ecb449adf973985ffc9a507a691746809e836fb580d5b12a5dda9e7723baa85fee6c278df74f59015a387b2768407ec4ef063290cf0621e9e09187b5e954568742c43c6e901d792deaea9fecd8c76e370ff6b2781707d96f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c4b7291c6442877fc14d500a0ae9603dccdd7f700895a072fef1595e183aab11f2e86fe7f0eafce53b46cd8f3526162cf9433dcfd6aac90af0ddef442f0c636b15681e342a5877ebedcc1f6439d6c0e8051fe45773b762d687dcc6fb76eb3a4b494a07a70cf2e8bac1a0147f429aaf7d23efa827eab96063bec0fcb1bd2d4950200bc2c8a3b000cfe9746e75fb13da35953d91a47c177a4ffc3bd6983586973e9023014d9245ff9d78f5e3a528b5149eb033afdcf415bab97b83b2acd753517d1240a06a689131a0b139f2bfed9beef37f419db95930cc980aa594597a9f1fc8db6031cfe33f7eab28eb3b172c2939ce42c053f2a8ab0aed35b3310aa478da3791012022ca9c650c53945bbb4270b917f3c8da94b9034f2b9ad643786d9673ad80a0d2e020f9201e653f0da68fff7c613b9d5e1df3fc18a906d28839689c4e28396f53b7e021b67a21f5786deb1b185d9fd029b1ef49e843e6a6f1c17b5da8be34c56951cdb021e70d03ad88cd68a5acd9b2bae5562aeb54e36369ad37a7372d7825212d947dd021b681caa6d272e5905686cd14393df5178e142ad91a8f4137c7339da751adb83cd1b0c298e1e6e2c7816a4739969c775a55d536756268b0dd0effa9d6d2f84de5e966c78e95f2bb2a6216b002a335594f25033f3ef1446d89c13ca99f4f78ef19b143648b77de4c92d95db62744696106e701d3cec09d40c5afb06cdd19687a11cea5f374fe8eb6ec7e66abdf22262a9b7e1bf4ab2619711182879c63ec0b02bc50903350f059ab822dd29a46b05b9ba0d8b32f0446724764820d9375b5d8fc81bb1352408cc83b604dd02e9d255f85854cb1faf61e631592835332e4003600cd36d48910a09d7121cd1b15812213b031766c4c32b5c631bbc1303dbebaddc08f662607fcdb8ad6095a1672ecaff2cab4fbd38623f4e39cfa128e75f60508bf8282a2f7108d9d5d0db5611ca6cbb8f15288a7b96b75d5f3a0615cb28b5f5a9cf26ebe2c5c1cf4eb585fc6130202642747b8cd13a9d7b62de65bad900388ff6b0ddeae5db0c5291236a8a9a1270462657bbf7f12e714b11064f419671175e46c72a154ea2a9dd9eb95f84bae91d608a7d4afee88e3cbba160cab32087193e3db2ac82260d6b96373754685d287724903242dc41881f4763ca281cd53f3749605451cf72c8dd3079c77e5bd24a90746d1900eb28a5f9e22b2292b561382e54c4af91edfe5911a74a118bf1b7e5abff3e346712253d74660d3433c0dd83db1ccb11265a1aeeafdbe708654d1b412ae493cb3aceff51be5b04a11007e172ae6341246c722f6536d60978f05678a05cff4d2477ffbcd66b482fa14a3d03ac3803f5dbb145e65f39eafb80fd16f4f5d6538bb7b42017668d34f32f0272bde6bf4fc6c7eb7b5eae643aaf9e2b5887f2596847b8781bde2ec1406d4eca6d67d8b059feac6f78fa469c1a8cd57ba4c3688f9b485ab2bad0e548f17e86c1b0277429e4d0e0fbea9bf85c533f4244afe4fee5d4be4c3647f8a389b6a53b589d9f76309000960d98722b70ab6ee6b8b8672d514c3032e017df90a695f475041a9811267fafba83deb20f987943b190b087e14e27d1041e7e7b81cc52e9b9efa16ccef27c5f2ae29c6a8fc3de66d0a6e982a69e1a80ad0ddffc61bc765765037881cccb711eb1975c24b62f9bf10c52b211db1f199bfa82e4b824ee6c19b7e4de7adc4b37bc54d690880d1b2dd164d92cb96507a94c9af3e17cc92984833e0686fe5fca69b7e8a97fa7eeee0e68b1ef5536f6aad8592db00ad0db4c5da614ac1bc50844d4f126e8305743c333ab071deed6886b7a1cb421dffbd8c780c7a1b0c9a2ad2c0125fda3ea5f8dad492707dcc57eea991141a168ed8aae4d9863a9053165b2b01177dc2774509e23dc09662a73d719a2386eac84a11c1f3a36c62155c2546553b9aa4af6b336283c663aefc0e946b7322134293b7a3c531e5ce5ab5a0f1d6c0de85279c03654d6fbb2a916267eb224821d0e7e7939d079380441ad0afbf9856247fb733e7d875d3cee08f11a440313c35cc88e674db6486884bbff56fe77af266b6b43f1a9972fcb094a28f4469f0c96079d7f3249b710d67c0a05e0e42fc0e1f7ec22be17e21272a952f20b862fe498549e69a40095857b3ed015e5c70ee6b91b0ae4e1ef6b35dfa443f30113e6dadce0f0973d6fc126ab5016bfcd8ec4daed8bc29cbd72ce9f1dd49bc2dc8d821dc207a61da3c645aeb99481920e178692b1f25c008815d7ca681d610e9bf76dba54739ba9f14ceb5d270200000000000000000000000060f6a898ec39dfa3885c878a56040d505cec7ca2927cf185480093d06abaa990031d041551d07a02a8c317377bd061c0e2d89c48b4af72b739a43fa4bf0dffb3d341179010735d9a8688fee5b49a88b27ca96bde639261d5e5fc2ee2d6ee18a800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aa75d344f2c7d761535d966e0f8ee4a7ad8da3edff9567a8e795b371751eb3006226ba0264033b65e670c2034e6238b7a33ca9a3f92a81c278decd25f0ad12b76448237256f9cdb02fda07241d8415ef834972ba8f44f1d5b68bacbe7cf2533f172edff5271aeca300c1d94a86532f0a3dfa71e718daf45cad8b2c54aea9c00c0209f86741c05e10818d7f58a425bef69ce86701a4052a1cb3bb3aaea389a225380216ad3cbd387e5b02c50fae5320cae755f0e74226eeadd7421178a4720146b1cc0b08f9a64bb78c102d6797a59f20a0acd77deecae6d96774f9fa72aeaf53f42c61aab7c7e0794518d60c27d88a2e7f4b91ad6b12af7689823a6d90f9a828c837ff0322b5525a165bba7c7dd753e732e3d2a351fa15af0f0d05e886beae2d331f6c58032509012e715ad1c946e53acbe8112cd113783b72cc65b5e3094f5928fe258278023035b3de3be3c0c04bd6f2f92cba43117fcd1dc67c559bdee8861e335b062fd10204ccd33f1a9dbe4547c43e007d8686e6bb707d5b4b5aa00c8844fcc248243c790312cfb50a138c829cb229c227b1e3e1c7363246dd54040b009744a9790346337ed67f2ed933bd7e6e66477a37a922f2645361378139d82e6bbb9ab306265257ae4df8df1c69f4f0920cd949a950621de52f81d8fa5728df496784ded252da0be072070c357349bdc1bed6d8287209ccc90936f50b86b70198a6b2168c6d176e26074f1dc8efc3630e4437c60352a33e6c55e146b0bee634e67bff453d7860afdaba0c9ff94f8947c330b2a97b26edc0ce58dae1bf342fc980d1075272638e28c73679c1478cc4dd9a7cf852f87d66dc2189261d10fe67af8d972928e16aaed561a6a876945852228ee6d1db381608540968cfe8c4febd09a63d1b7a2eafe5afc7163ac50c37f95cd16c149d6dfe9c9ad7f4b7a907e3e0e293fd13d4f922ca6186450c31c8e22aff93eb9de025ab45a2226d275fccfd57fb98bcac099d03624357db77a8a220bb6580e25ad3c2d99f69b833e262e27d8961582b58b5dce7ade2866a47c26efd512e5373baa14e6af05fc3c1d6b5d32b1629afc923744afb608c188bb4f16d1672c2e050e17df06d2d18d7ccf9641b447823abdfdc6d18af3524b8bcbdc6164331f13027fd0705be8e86bc9e1d22029d52bf47d7983f274b58ba3124b2cd4d5be6cbc2b8e0e3c4594347c62b53e6ba00e4598fb52cce903fadaa4ca57f8fef7cecb7d1f953da3b89d5552e6c09bd60ac209fe897d41feb5f06d1783f7a4d7f2528c891fc7c4686e16518d8a7ecd7dd3482b46650d12aff76f3553608c4feeb88954cb7a3a83eb1496bf00ec25bcdd7149b385153d8de6ac2304fe92871d0d43f513674546e86eb410a7830a0755a0f2d1f4e363a422e73a57401ec216ff1ee9e3443a101ca046134c5efd3bef6972958e6492a19098e38ff040f6425b2ba1399e119944c15b6fa4e6461247004846de65d2ad12c6978a6aa385382022b6594fd7559ba6338d8e4e1053a87178de7e3e636c1932c8d57a8ffeaadd3eaa9151d82c6aa3b71fd789dfb01debd7314a1fc9d65c2d6a78b3a3293f307b9b7d60c9b5cee25dfe695adccebede6d716b3ef90f75dbb9150274a00a2963f5af3d25a0955f8db580e5902d80b39de2b7ba4ad60e07e091aa7e8ed8a0edf44008a27937de5eaeca23145229a015ad7d02ecaa302646e02f67cf0144df8328c752e46236b751892a96833a18cdb8bb871d4358c62e9830673fa3c188d7e5e21f4a7c6178e03094f76ef7904e184ce915234fee70289ebea8105ac43cc54d90f22761ff7df67b36e2b67adcb2635094e1b1507a95cc151c6e9e0af7b61b891d6248288e779bc09011fc1db3a73c373fc53ecbb90adfef90d9eba7f420a6abe7349b930908b3d995f84720f3edab064d5658a956f62950acee38d9bbf91efc883b4f0b77f1760daab69efe4fe56ea476f5e61c1de692172608de5479c26ba550170e3d437960ab0117463064fbc92cecb966908a2b063cef65981153bef57f407bf96b132c94002e28fe29e6bcdd2d15250ea5fbe98a0b0d576b821807e76e22ef605d6b9e0f70ee1709c7d5144b4039aae87afe1ae119abff38ee4693d0d9dc08635e5f1f34ceb6dc4574c7d3aca2e317ca84d341315facb9588fe11e134ce04b33fe48f15d2dbc12bdc3b3e5c76a425d016be2b9974018b726ec65cefd05e7b5e97feae87de5695e0fa8486246907a5acce734df4b026e4bb7edb0324b391d99b571477edf87f2234da90e11c765f432c7ebd9c859dd34ca14810f469602ae04bc5c9731da56e60f7b53825dee5752829832159b0b8c6eafa12e06dfe4807289b0325382fce99ff49ef7d0c5e2de99560afaa91533d4c1732051d73f19cb30a3019e128f707ac1da362cba06f20ce75012501", "", 3, 783418331, 0, "4c319b85f12c9b4076efc11626ff88e18c94075a4c7c0e8227e1fcc8186c3068"], + ["030000807082c403023a32f7e9445c6f8fb4e61c558f96e67b1de69e62b6f079599501b33ba2cc16070000000000be8369afc0e5b21c1b028324fe5447fd0b4db08261111e72b20446c1906ef41f54efdf0e0000000005acacac6a5328fa219a028ec370030000000001ac4c5e6a03000000000051e750a0fa6d9a9e0122a44d05000000000000000000000000bdad9abe14efaaa3a32fd34be42cb626582b1893042e9c400770293728c45ff1a2495298fda9c288aeae9cf5d5ec8f032be0b82fc3242865b70051edf7e4861f284115d15c64ad33b393f7f83b6eba82cc074dd7d7ec68ea560782859c4554e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b778f0c4959aa22877d57e36db223426305ed0e0e524716856cb0318266fc205e83c6f2f91a020f65ff41c372d9166060408ca774faa0e24b74ae836061e780c92290eb7de84112d5df52a9117483d4273f68af9ee23799da243eabe95164aaee0f4ea217601ffc086c948463c9e2e51681cbdabd48055c528ab1539660f4bdc0226ca4ad410f5cc2717ceebb9f420d49d7cf732ba3df54807277cad69143c4c4402000cd7ec9ddf6a047c3bdb61f91a5810bed928a034199b339bec39e975798d150b041ab103e60220074e95a447aa7db7ce459bf88b6ecaefcadc97ebc3890183ea891f56766fef8ad8ef8dcf845f6f669b6ba908c50c950f348697c21b4017e9af032b2bec456b42c340c1828d60771fbc8b35eabe926cacd457b7e262d972f43ed602096b27fccdc42a7bcb3bdaa60fbf4c4ea7dd900fe30eca795a637bfb3e160f820220ee40a943efa8fb2abfadb445dbf66926b1e4b70c4709ecbe010774ac1ebd4a0324d064b2ba6e9af997a94b3e6e4997c73c871dee67c5d1023ab32f4898be3bb7022b9db32b2d7aab79e6509ef5ce4555400503359a4f15ed1f619cdcd0f9a31c4730cabd29ac3e5331ed10af4b3cd63a959ce334d13ad87cf6f4dc029b45a133f4716557f40a1eda6ec313e98a36f1bd37394b677747b3524d9d05aae902d04f34d0ef5be4aab4aeec5ffb44fd5c2dc702d48635417e66d235dac9b623133436ee265629e4c38cf47c6dc3d845395d27216b52d91aa45c5241b795933a96b0ac2c9639515b0de747802ad12c360e55d1677be0a3013dc120c8541ebfbf4e12a89d3deae54b9d5549c82f1f7782f3dbae163f3b05581a1b78bf0b31019bb2de1a0df217a708d68fbf937e8a293b565fbc562da49c556b74b64f7b0e0ef227b85ec95f59d6d42d8cf496dd9af7d872229d94bcc2ca445ec5d42d1217d4090fdb37c1b037f34ee94fbaf0e94168b1c95abb8858aed53f84909b6606e4c43742557a394bdc8c6669dde2748df49304492c2981da26d2efff43cc483d2b408bb4b1a0dcb3608ede7cdf40acaea79fa9821d60baeba14342771f798c8a614239ba664c21b1acc4a921fdf1b8a41c765e2d4dd088c6ce46aeb618b7f7abc8074eba1fc9284476919d7ccbc4e0368166caf6e0aed01b0bcd2f32a6af6d057a9401d5dc2b5725db40630f48f2eb8949dfb6c5499ba7a30fe49e730a2ec96b29956b4fa0cc734bd5d425fe8a6d19e2e08b4bec874d0130c34c2881faf3c3c5d75b876afe01163982b98733ddc5a0589be3b0b938eadb3eb74777c2bd37655566f7f38145361ee81871d83b805895408e61f0c8b9069ef8d485f5eaedf3f0dd9de3ee982b66cda71b4728d5950ce2f745ae292f6368baa46f0ff6c0c195350b5a11d75b975f3d57dee7d2c5e1ab6c8da61880b7ef394db34f95a62204ebf140a437eae25b21607c2495a8d8428aaee60e8158cef160c8cfa15f4c8b3cd84b9931c63e8f76b2c3edcd88ae86baa1a0d475d5ccd3c35f4cdbd099489736314dfbe6ab654cc48dcc436871d82902473a1297d8a3fa4050d75cede42c4adfc7fc7352f07d39cd15fd4a7128ca622a90e0fe76df25d1048b54dbf20ad6d21867738bdc666b7eb1e1a46c286c495ba4a7dbee8b55e14d357ae49fb943cdeb1eb840eb492fd2e60c58371d7ae52437f2752037e7b7f02ac3ee275d538ecb5954a27575bf95cc32dfe46b69939679a8210b2787b1729930d95897f18ef387aa16afc5f4cc1190f208c7fadee6973efb29e12465546089673c7a0798736d2dc71797360bd80add0388990f657ecd0b646a0fbee5a7601431051045962661a68329be7930f353b7084b5beaf4053a32280b232dbf6a5e4dab8763296979940906b26a1bf966b9c534be686522e2cafef32edaec4f59c40eda2ba88df691176370bc9d3876b74951a5234beb1b89970012c0d8934a7bbe67b11d4e3497358c8cd109a127bd7c236c1f4a26de7e155935d73c912595c7a51c15869edf3c0267c8d0eadbfeb1b1eb4cacec869578bc2b1a3fdccc33eca5d64e2df2ccb121e96739ecb983d33e47628d5166fc72d7aa22248d3b08b20b711fc1f3ad1e84d77ddd5728868d40108a0f365941bed61b372cdb4c783bedfa28cf51b9f2dc4a088d6763b7ba04e20866bb17efa9d2c0960bd21275d9e937a50da0cafeaf105180f4415e16f457f33e4b7f2bef54dd365464359bf157a5fbb6c57610a9a9dc75894eb28ef0ceea860d0408d71230be675451a82baaef3226d09ac649eb4a3f21a01ca0bda913de25cdd187e74bcc43972bebf0ee86a9e46308102a488cb1a9831b9f6189fd06047352ac9fdb7693c3a31e3e6b4e9c7b056071e95cc2bbfccfe60c2851f3306cfc12776296ce9b2e5f1b2ff20efd4359334e5e4f1f6e5624f22f9c03", "65ac635163526500", 0, -401298350, 1537743641, "58d2917e7acfdb3466fcc7d850ca2f614e3a0f48a92b31ca7c26e07abc7706c6"], + ["030000807082c403039a443cdc19e7cabce9148fd66f86697e0bc27531c429a596f83dab0918a6c6b703000000066363ac526a53a7681d638218b276dd14e3752eba2d47ebf002f97feeceed2610815ec4e65f03f5a9c0da010000000865516351536a516502f8e37f9598f1bd9ad5e46313c1059d49657421df5059be6cf1ed81faa885ad7e1cda6c03000000045153510072ac1ce6038ef9a30300000000015224ebb404000000000865656552526351634e2a21040000000005536353526300000000000000000131d3d601000000000000000000000000b2418c181a3a70860891606f2ba258b4aa3adf99c7f02da6bd90d7b8634fd2c454eb49d949b00546ad3d45527b16c7bc2af51e9cfe61ef0d1ff57b4e805b3630b81009ccf6eb0793fa62dd77cdd3b73fd759491170def837160bea1569646e4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff97aeab63120490075c558de47061e58f288e26f44b6dbb853b8c9f3586b287e473eb0e05b22728349dbe641a5c34267b7c66635515d1e95247313fa486ab13ef97925d20600da9f1e6e04758ebddf4013b4830f265559aef2416fb4d5d2d2c9c3008e2fe14d1845c24ad0a95e3056a49fed99f63ee7436d29aaec48703c21d0209694408f8017178d5e6f9294c93096d945e04df5fc68cc960fc8c4969b6b55f0308e81973cd06e0721a73c46753556ef306b7619269bca2b528580a553acb76a00b03e821b6d4a82bf25841fceeb897d245304338aaf7df683febf75dc1d568ce13c67c1d5502626614479a201a9a9b4e6bfd08c9306c09f195a7307aa8f2f5f35f0308ed7314a41f0e0e60c191b73fcbd4da90f9864dc2d568df82b4ec4ebf93cd09031d7f84e45a3db1a87d212be84d7f909ffb8a81ece2c5efdc73dac200634af5f5030d1080746deb6f4ac6cb6f858a4e5d8beefb03da9771321c136cb149b8deb4a20218237ac821b288ca57d8e4df2c19f50351c25e15a8332681fcdc8ab1c321be350306686d31bf858de006105bdeb8bcc8dc70e705983e66d91e613c934839fcdec37ceb7fbfdca81429417cc8ea60b89cf3307669cc6232fb7bc96e38bf0465d78fc2d4c5a7057bbcc2c443026f677f3df894465462bcccdac084467b343f9ba174ce460b5a21c4046de3d8f723e904c197b82d63b3bd75f18852745d2d12ec6673a6c20b6b7ed53cbddcaa9652a41eb63db1c9d1bdd19e1ba8bb157821b9f8eecd1bec01d23ae8ca061ab56960d25420d0b5caa382199c86573ac0b1400c47619669a25e99f4ae455935ed78e1bac30f1403a3fc9756ee2bb4b506a2fddb7daa94a0b44a9b38e8b6455439a77a2bdfa134015bacba9a09e6dff3b8f6f0b845bc300ac8c1c9fb2ed01d76fea413351bf0909d72b54194641a8b47b248003065c2ad4dda9e76fdb30dcc81a27876dc0b03bb02a161184205559bda77a268621b30e7ec4d125c4d94a10984c4494cbf39bdefd129290551168911c2da04d7c4b10dd97de8e3deaf97ce84f3ac07d7ee3d3002578dd9e6517f3abeacb445fefa9c8e235f9d775008e9e750ca8ff93b602b0e78d7316f828cac3af241741ff7f1149e5f2a99f1f6057bbc40d34bbbe3243a10d100250a5bf3d4b4e736f655986e8aa7dc5dbcf3377c511835ef2b97a9c88a5ce96856a83975dba3bc937ba8858de87a2fda75d62e21748b7535d4b3b374142dc5ea2aabf0903ad9a24fcbe0ff2e4a977eefd228e3675b0ef26371849d22aa6f4dd923ae06d82fac5ac24395dc57367c18026eeea482c82976cc9c3e41e711103343f300b9f71d0f4d555c488b7f2aed49d9ce0a377e7d16e10e06148f27c7a90d94693ec6694b8a12a43b4f04e2a9a83804dd6dee3ad5fdb28a24a1df5066526fcbdf226a1c7bd19c9037b79ba3688256fb3c3c260c75cbc2a1c1307262b87c077b4a59110b58d071047d410cb01a4c929a4f4e5c81c5428aef52746d954978dbb500caa3262bb6557cbc4bd4de5ab92c2014de11a28510e0b99830abd4e735ff3ce49eddf7524453e9e3dcde6a757f9edf4faadeaae1335d7ed7ee731f88eaeafe8b358ac51f2fc7b48b1a63bf8d4998da095a9a25210a8f098ee17400bf55701d4b6af52ff8fe61a002c77186df794ccaa48f4dab47b8dc0a975edc578b4ee7ff020b1c47dfa4a3b35167f3c504ac60a45cc5e4693d5366d8cb5568f00c33d1095a25210e52722600614793ef3582656c0c3a92797f87a1c3862949ff7f459754dd4ccdbe4cbdb797a0a73cfdb5e541915cffc5cdeadff813979b4ca11289db6a4fe4cf6bffda3ee6b239ef893d7c96ada4b075bc414b51bcc0ec746c645363a1b96d4fe09e897cf53d7131034147db37a1ee228fc706aa5ab40a57f2bd93fdb2cdb14fcf41d9b82a79e4c4b9c286ab18e110c3fb3348a363969dddc2c9843a105350defbc072b846539db1c83f80321db619750275ca36333c174530d746001b4029bcaa2b2f21618cab3520281a5b1b8e25de0b57187b62f1968b2dfca9d8dc937fced1dadebfef4a6250a54ccd08716468c4558d22179b867f67aeaf3c4419db6f1ed20cd92d5236b2ca57b1272fa68e0ccd4db74e5cd3fbc401112ff743a5636407a95a700a50696a6c00e194a865833e334900dd983f1b2a1b6607642d5201bf6f81497af0c28ae5ae1c9de0d3e3442782658405bbd135a47ad54743c4e1c9dbb66c3d310868b6af41c89d55bd3c338446c517d77bc09622b85456c6bdbe3818d4bba14eedd584f3c98939e830e2edc2f38798e25aaae3eeb00b21ae2b667d707da55793897913152387ec9e30905e9f931d84000388b48ab0a9b5217c0e21fc28c50f2386393c53a585007dea6ce90de82b1ef942d624ddfd588e0dec8f06", "00", 1, -968302226, 0, "13f1c9a4bc1c1894ba458bcac0373e80382ba09a7db914d9391daadc2287107f"], + ["c8bd6226031d94f85fa616406daeff78bce7122624f43b804b256e80b36b626aeddcdf08a60200000004515353517ac5018189f70a50fed2aeb67df152d7e0bac56183dd9173e70d172b22b2c192adbb98560200000004515153536e28a9d8e0a4aa44ccc293d64008cf2ca7a85c0a898c2dcd3a9c80fdd17a6d108d0ce1200000000008ac6aac6a52ac51acffffffff02cff71a0500000000066a0000635365bc4c29040000000008536551515252ac6523880da400", "6300", 0, -177608855, 1537743641, "eec51927cab3cd242850933ee93cb87cfb3ebda687dfb7cc41c165b2211abf7f"], + ["030000807082c403024655c05adcaa4cfb9e3fc3b061385de0dc86b9f307cb901622726b010f4122950100000006526a536a536afffffffff9bb9a14259b2ec93bd90f7d5d6fb943ad7716d665bcfcd21ccc162e4c1ae01600000000004974e57503105d9a020000000000719f71020000000001acfc4bb802000000000852ac636300656353112f61f900000000030000000000000000acce2105000000004b32d264994957daef462c28f999489fada11b315eeb2f2bb6a43fc48b2ab257b3e7742d679f938c3e8688fbf027282db76954e22009b6f459a4757d3191b32d93b33bf1e913305fe0b60e01d4e979b6c0ac23b782ba5102a51073e449004d820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082908d40bcd52c08c64aa42e4ff0194f2ecbfec7cf3d1a08f3cf112a6f5d154fc0f139da745df1a4ef2c389c49e7b5d48b62a5b25816f31f33dd2824fa2435f93a72716c47baf4f7be348374205217e151a90989fef33de3505752c97b42267a3c9dc35f58d37495fa71599dccb3ce819395c9a6e628891d54fcdd3f953855c2031078fd81a5ef11e571fb24d69b4a4a007279e3119b6851813c50f8a37e57edcc032e94f4e790b24973f259c9a5ac7ab1b690b32cde123de5161180d8aca3030b850b0320a3a0ee9f48c3ae79f45cf522ec93ff78072855041b22cb21db0f2729eabd37552d4993a4bfb39c70a21802285c7049bcba4768d5f8d793797b2bfa5979be020d8d9536eef2df62adaf9f38cd9644c5480402e2d076cec32ccf34e28ad454d60205297a451680cdb913f6b03eff9c76a404a0ba79b7a350da6933058445b840fe03027483db522c4567b88baad552b257d7a0d635482dfc12c803a246321bff66eb0204a453a65cf0f7b6cc7b60d67bf6814f4a374af2ec0ac7e4e07a45e9a4b63e280327e19020a4873201f11e6d000db1d5c3b167cec2fa158475923b7b42779261954684ea34a89761ea76e9cf30ba8c213400dc1d9e54c48691880c1a1a3f1d2469462a17e979538e4909d8b17c4e72b7a9506f816df1b21e98a5bb52f76bf7db8dd662227f2fc0b8b3fb9c210ccdc18f77e64736168588c458993f0f6461aa35f0d071506599b0b24ac4f1f154b31087cb28a8c432cbaaaa7982654abb257f40fc6dbed5d4e4af881da6937a527c28709bd3fcdf67dcc26b8ec4524419c66f0309910161634944e8aa8bd38081dd5581a50365972f37c9e27d5c7c27a1eafe7c8087f3bb588e7cbdab80ccaa118560220b11db4e6093e9306cf0c3ccbbb31eb6bf938955f24a279d2c47a4b140f930bf25a09cf46a4b9d681f1eae137896a58e5c2c1b259b8fa83426ebbe45cd7da4008b4ca8efd46483696265b558954e26fdd879291e14e60b3e1b439444c22e25304036c596dfd43ec9ade2d4fecb62063d620cf91014cd0693fae6016bdd98c9d13da228edbad564c989caee5404b17fc78f9b4d210a1ea2c3fdc2ec6f34e0526d901ad6463e4da9c63ccd7e83957e71235b7c291844629b7a11417adaf30b0adefe79d67f692c6e10ec2ce42e21da4563f9d187fe1352622be36f9c92396f6634a7a55abdd9329a233486d3ee6aa8d4fbf2f5b1bd28538157ab269db401969aa8f18546ee5928f87612c6bf7c596dce4a3dc0e49fc7efd2fe5beff52123fdd3c1f4ecfdb219be197aa50c88c536eb25922722952cd8bebd5038445ebe83b32c43e3a64825dc6c60d928e0a0e2d420bf773a2ef477132c610586549876fdce4e14384f68ba8e1249d3b4fa985b669308f043ee57192a53bdcbf3bcd2efb67314bac51fa041472d255a2124be11366e231dc96700d2730fb568f7d249aa47eb5c13e5b939377b6ee57469f83a1602f971238f4c17e734102c1678130f1eb7962933c7a68c852b4aad6934fb13d695f01c29642c41b700a618505d7cb1f5a1266e3a6bed1a0069458e324f20bc002bedc42b877bfed18aebb69f63161476e3ed2466d866c81c13bd85caae5f26b249bf0997b90e55f080e438168c37ebf7fad3eecc25c51f1f764ed24e67abd583f5607c377aa6d3dc8f5fe5d533eb880961ca8af3a6fbc2d2d43a39a7a5d80cf8cf7dd2efed242d6174f632f78438d8578211014fca8538986b3928d37742012a093cd61bfd6086751ede751aa85e96d0c182cc47c7a323c4df39ebfdb1fca0135bfe8f7e3a14b87af85a33419a5ce59a734b50cd29b0b73d170635656db62290ca51e79479e6db37f43c17945aac24de73649d3ae40408e46c0aff89f41940f29d8194727915fae6a5771ee3938db164b91a2af41596dcbf6ad66991d70f05a2da01a1ebf84a7c07f751ac2738c029761da8fe118dfff3838e32bf87fb1774d274b1f70ec04e4762bdfe9c0800d28e56162e18cf10a029db78848dde112deeb6d6c208f9c1d082b3b3cba1aee276f6fd5e693cfad3a0374ecd7b8daac7349014619f9efce583bfc8d3ccecdea65c33fbbc8cce3d4b76d8437a02d173e93d86befb8f0779bfa5f842b5c5e007ac295c84e094e3bf50f8f47c63d9dfe2696fdcb7e1b37466fc2af409cb447fa4a837fdc3dcb9db66ca8e09597f9fc4c254f9c50000407be8709c41cbc782310183b276e8047f49977873363298ad0d26e382dbe77eda2946c352da17947ca1f8782b2d48abf780d2d2ae3c65bf6500000000000000000000000000f81d1355672f3550a352fe66380b1f6047eddf8c27768c30a838fcec0bd18bff945d72a37dff243313b1d5722b9cd06db4e10c4b4be8df28671e74b6e4dbfd83c3f5a96d1944b69fd4b48ce1080d918e23ff8f9aecac18491422de35e5d5f74e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e73ea2648a4e32ef63529b368d7c363735565e5f1699e4e88307001a4f8025e08f7f93f2e4eb2d1ff98c9b274a06f3bf57bb4cb334528c3da29a860e77c1c3ef58b0e8840a6cf00b1ae2d9290ba3b0789051beab43cda6ad16f6d2c6ebddf250c009225b4d51e3ca1d34dd7c72cbe3bf40e84e6d00c9208e64846c48e9191f09020dfc6596fc9e7e3802de92b14df48dc7a196caa967bd6fd0873d23ac87d827e10312521e18bca2744e29a8ca2f2ffca68361b5ca447902c73342b1cd0d1580698a0a0218dc5c144fec79b9e5ae2589f1992775147cb0340935faefcd816748cf694cc06945177a9e5e2745db7279dfe88f50ba3ea3198c234be5738ae2f6592c6be2021fa6a726199749e08284489990acf68024e48d04aebe06d8146331035e0ddb8e021276a285235d406c7940f15f973c02e9c19f3a3f24c19a19dcc8ad8f475a0afb032be4b92c1395f0e3ec83c398e6a70d7429fa8081943346a7040ad7c0e8757f6d0202af89f632d896ca8b4d59f12796d3de7d39640c2661ec41fe7ac400cc1a33ac0322fa23145b958258254b491d0053df255e493c0ce5ebdf2fc8203df00fc8f4df549ef505a6cf83a9a55ade666bf518e67a9f206be2bc63804af3913b230848444cde4acf72996e0e4eed97a3bf2c4124205f9def129900814bce984b1828e6a89a09e19c21bf87895423b2571417f43b304e5218771e67ffcca7b94b3f9e5b5fa511129305841b3b0ea6a2c0237ce201c17345fbe085c03ba896ef573e9dff4f7f9e52ddef15f85e4f8f9e1d0aaedb69685b542502211d30717047d7b3cb47833c9a97a36ec708a53c1ac9b91b26e8906e7c34872b07b108f78875ed9ac5bcea51c16f715a222cdbb8c9577861905edeaf677612f765587e5a23e179a5c0c5bf45bf3e581df414a621a30ec30a49a15ab763bbf94843cfd674db3608d5acca3778515ea01cc35c21c11f75425298d1be35db24d734765bbb27a433383a2e07621cbbc472d42ad30a53bcaf342645713539cd740bf5e7de3793fd7255ea42359f232004be9dbd64a805096ab821c109be2fbcbbce53d2001daa31ca82f486950c2ec237316debd387e1edd3c23d497e40167aff3d0a62741acc35416fc8f32985e3d12c63968bbd989d7023787e100df33d5c2be8e3adbb56152425332004de321153d75969560b8831989492ea1a7ca17e8c7a4ab90b8a8c993c59cb42a54bd3e166c5721665e754adcb496e62a04f2279bb98d624734f0e44f9677160d1242e47f2e68d49ee18117ca22370fbab48ce3e40a2a4ec99cddc5a84193716954602fbb855b527f78734b1191d121f0362eb3bbfd679f50f33818671e0bab869f37a3aeef3eadf094869c6f2875b83f60da29da7d8f6c3d15338523de7bf1d4f74d1010a1bf4d134675e0570a59bf4963a1c0efacdf63f77a59cc9dd40782886e84273717fdbaea7860894fdb86d5929e89d0e4832d0dbd3765b190978f46adda54817c59095adbfcf0dcca79f7a8c86c0d1a219d170270f5cb77792e3a324ac293c0e5708a5223e9ea731cd6f45e2a885a43fcc8263cda9361543aea31740a91699991f40b583930a2f32428a7d4af4a91061c15c6a0b6ec434bdae41d38fb8db9d23f387d082e9753677975951646ad09e2a8f1694c1c096da01bcc6fd94e71af4cd30747d832e197dd7dbf50bdb379d129d5b2ea0dc3d89e54627885a25aea8ca0d50909abd749b5bfbc06b33602325fbf48cb925ac4e4e21cfb6f44f99ba07bc8987089882511f60c7d7197804223efa6ff5ed808d5b57919c7233f5dc4dd25e176161e128556d08ee27dcc8c06c41bfe16c2e8e649f2e1af0eb819b4a618ee75a75d16a1a780e5961089e3c5acb9a8b1fdd2c755933e46113808281825feb76cd1cfa368ec8542e595e534e6ae3d836118cb3658b6109fbb0b284633f2c2af7421581deceaf0f680bb74497885338ea821e29ccd632a82072285670ec8bad0abfccd1221c23d47b2aa56ac34743801e26fec910fa305944044c3badec3c2ff86be24aa56f6d14b478c8eb3cd889bc22c78db18f9ba42bfc9b5246c2b9b09f8f1821e3c6d6d4743c242dacf0d51551fb8f02dc1fc063d23546c7a2a6f9cdd18a6bcaac327a256750f1a44cf722380323c1901805905a9d4419e7fa655c78b6533e055cac0c35692bff8cdb8bf15e709b0eb00443cc9a903176814cfce6fa3e90d5c647136c7336b734908dda10992a5ea8a9a0bf6198962e1d4e6d07a6aeb603456e058d4f29fa53bcf3729d824c584274f70000000000000000e2e541010000000049e249c8d7baad2c3ed7428b62b70de1420236763b041110930c9a9c591e5f7159ea85a6d8012aa8f317c3e40a5332365954c02b84c97213edf964f9cc67d86d2a71a75529e39dcd81eea07eb69e85ddf6ae9931f000d28084d96ab8968aeba900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139d694391dbb20b7ed8c173193d977f66a6497b7b50e13248e0d7c8c3298440463c711e74ab2538e9c8da72b5b25ec8883b854bf1ae948cf5be1fceee27bfd43b76de63ca5177a0080f76cb164525f3b30381570202b40a8a58f9216795cbe733bb43371d2ba5da9c72792990ee208e04e01dd5895dd9b9387f5def08f73cd102068380a04cde7b956136c71b91595c0b0519bbc6797097203a1f1896bd92b3a5021cda8e88b7350b12de50801b45e045a9c50f004fea79914b97443dd23f2530490b08b475a8827000c6c20a3edb3d47074f856f1f8ba5cbe03286333b55bc31f4c037185b67b18027ab56f5679a4831172a835465525dc1fb18548cebc93813e612030e3219b2f29918af0d821c8806e014f3f8d025eeec2c5f6303d6a5e6b787cc9f0316243080b0e1c71bc4877f2f85901dfb52b617dbecd615e268946010f7f9cbc503078a44c5d6a2857d6c0976ff9ee157955ccaeca9de5a14950371b1cb9b09f192021aeff83a5ec0c63ec28dec3c95946bcbdd67bff992aea39c2dac53472749ebdc032f3930cf74423605baba33daab9f2e55b21dabba6c5b79e516458bab4bd5924c72b52e2bbbb28c472c31e89dbc204b2144e2af496b15f627a4572984c9976ad9b6ef321a0692c1d8dbcbad55f55f571a1d842d7f098fbb7c6947ae274863d214848241cc33b0cc2ccb2220b7fcf8407fac1d62ec62046fc6ecda80bec6b1ba5ab21e7103ed695ca10781b090fd2f999ebc4553ed75c0c2943f64202975ce3a2a65872092a1d274d434fb96024d19c1a7dbc2be33b56992fe88e7f9b7b056bc1e6c5ff1c665544294dfcd7145055f51391a093aa7f6e1d1975307d96497612e17938db6cd823aa12f2ca3f4ea17adb4238381252a5f8a0098d7f0ecb2c08c049676a33e2a327c3de00a5495cb1aae8daa53acf71fb54848f61b39aa0f8bb898b6f5b69c1751ab410b2e3c0189de63e389050daf61cedeb5271399ef5e1509d6297ff45f9092efe17b50c169363e4e5c642d7f6f52aab1c95b9f98da1a1b602b0de828da7398f5c4abd82660dd33ebf6c6824d89f3a7fa303f25121f199834e056e17cd71d4510ae2714f14d8dbd3d6a087ebd0db84a781a5b597714546b435e68cf63f820ed46fc1cf49943208b5b2cd1de3f50c03d5fb33d12d5de8b7e41b3f0f9aa75640065c0de67bade15221c313cffd332b7a28831f060ff553a2af41b97291a1abc09aefb9c0f68c6063caf3e9d7a32d643be1b2fd3e721a2a7f030e94ea1ae61b55ba5afd4b209f6789e08bf849685e15e6b0a9e01ce058bb1581b0599f233aa9f4c09965cda51522c79ce60fd248497999dd4cf82799dbc4daf0c4ec7a69adef2b2836343a4ea60c8fb4e7a79252f0b920f21b1db81f3b4e2225b61665b12554c18696e186f017d25f717c6bc0417798917bbc78347b8dec02b23ed10e66ff175171bb88627890d2ff9da90d6a6a44fa724003dbef0e8c4470b5594a61879eb46da50d9d088a697c16e284a1da99e626d0590779e4af613575d3171ea3e5c6afb796756a0c3ce2eadfcf7786df6f52f1206b626f3e72ad82fe12f803f521d5623b19c896603caac7c3eae3f09fe377dcc046b5a3419e72488a0e7d439f7c21a290d59716896605bedbca9d6d803f0eebda091616d87dc567970f4acbb1b3019522556ee574dbf594040c5ee5092cf94fdd81fbf403a9402705f278769db063c4b6e7a450dfe776be655f22da4140f72cc0b2264bcb0a2bb35bb4bc4b84684c24431915297e5b4b46930b1583ba8c8baf8ad11da8407f52b99ec2c5b8e997b78ac1a67d33ad820fc93b0805e721bb36633911a517fb925bc771cdf526e6be7edecd4b4645347e0aa297420000eecd0cf7d73ce952afe5b3bd40cbb584c522596cbcf5789aa45e433be05e73980ad25e66804bbaec2ea7d9ad2d81920623e99f6af8b57e84c5d9bbcaf8b6036ff53e8d99a476ba0a71c377050cab2df0c4d28ca44cda779d3d49f9fc842097d72d1042edc917c7f47ee964e751bcb5b5ef66d3405b68c65a0d74401436aae8e6dacdba8f8b5fd7fd1399b4506c953d47370f72dc3b2af62716d1a16d35adb864f041d520fd84a8ff95a29d721a0bf5a882bff0e1cf57f4ff1ef5537261802fd421439a027c51cbc08475af4747afaecaa7d359d5a6aa7c7dd17d00afe0d987c51942c14387d9d05ef69291e8cf5968bf9cd4e9e496023b01289b3b720d0ab42e95137b4980ae063d8519a7f183b41f644dfce51c81ee54aba18b4837c4dfa9ba12ab1f3f445cdd881599bf32c08adedd2d1964653186305f73dc4ce277c0de95c1dab2e29e064029f7a231b533394bdc5f6c3da499b4ffbf768e1ec7ada0ae0ade6273e49e89f18f3c5b8a1e5f1740bbb897772a8ab2efdc6aa16b971110a7a0f9600", "65", 1, 1484102376, 0, "1d169fd5a37416746912e604f849caee9ef1cd4cdbb7e1cc80fc715294d70466"], + ["030000807082c40302b64fa2b084cc8d0dc3190ce74abc5efe310b525bd1a87b0268b3ed60fd701cc400000000025153ffffffffb000d69d826d8d95cdee4523c900851e96fa36a3ce58a018c31ed3689eb875d5030000000763530051656aac4c352c2401730e4b020000000007ac520000655363000000004190d5d700", "65635352635100", 0, 284378056, 0, "3f4dfec149f041f1d35a618bf32f17c5133a622bc45b7aab0e7ec05212f5598e"], + ["7697a05303a36b7e23fe0a4639c0b69b788579b795ac88f1509fd1798bc823fb7b6b03c9f10300000003ac5265ffffffffc583eef68d5466643fb0d7b147c090f889a05129bd3f0effa568fc4e1d1c0aba000000000765005200635353085a5427b187f4295c94b45bcad7f5db17133c6032c0177a00abe0d83255995cd4d61f5e03000000060065ac6552acffffffff0459ec960000000000070051636a536a51d9ecf40400000000065200650063530b097e0300000000016360ac740000000000090053515363636365659c20f0ba00", "ac", 0, -1849733952, 0, "8b107da50fba10accd8de476a387d592dfb55fde8b266cf1c8f52b1837663432"], + ["030000807082c40303a7c39170f8d457d55037b0bb1bf7f339cd448c5fed6a34b8270b3aaab680384a0100000000b0cffd6104eabf6464edbda0dbc588b1cc43ead8e8b6f0c8c42fd36251beb048408f59970200000002526a0699c83c4480434b08836c1c78474ee5e3147c2a5ed51ab53d880efc16d8c882ef3b6bf80300000005ac655252acffffffff04b3976c04000000000652536a516a00157f9b010000000007ac63ac5263656520535f0500000000055363655352a3420a0100000000086aac516300515100000000000000000003a3d76905000000000000000000000000ede5f48da7b3f3b29aa7889663614d9d4c820d91f1a71514005498d9726a0ba88458b17b93e8a3fc5e08e8732e92d90443c7346699a55c2e352d9a4d7bec36496c34dbd9213b5c7e43a742205d2ba7168404fa846990571ee8d9f6ad1b9e75ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cc630b836539c338e3b33f9cb9b770fe5a9c6e10369e2d4e57b614e6a35a9e5f1d5c7de94c17d3af29b1d86cfb2f7adde7ddba3055e2146bee06c3b15f3a97e704bad46448727addcfe9d0b641021cd0731cbe4b08388471dd052a7fbac8afdfcafc1155a5004460c3a3d0e311619a9aafc9da312271f7f9fc2698757a7f1c30222c39d6ac61a111a6be7021c7c6fc6c6204b59fcf2e5423f4385f1299fbfe304021bb5279d0297aef4c5a2aa9d66b84771cc01165615e78224494594043fea35880a0293ab3bdd91cfadbf35ca1bac5bf4252f5d09ecc284f9f10279b641d82a4414fd2cf8991d2013689e59b5b25395452e417a9c242eb7bd63cd8713e5fff3735c03299b69ebbe47d93468d2d94eccad7d092f8b573567ca09b1930f38ad640262bf032bf2f4e29edff7fb7a3a3809f0b013e858a93304cbf9b05f4178eaf38387cc0d032027c6dfa2fcba9ac622a67910a36f22f8e487791148b193b89cc22fa10796f203009b0931f3eee209cc24afd4307114b8923743ea4a4f38494e32247e4ec041bc022ef026ca7a084e786600a7bceea943126bf72da82e80ac7f2dd19089f9eb8ebaf7427f5d3298ae72cb41a4fb707c69efe825d134ed445ad4b576d4efd77541d0cd6718674d0ba3193ed34333bb53d605c2c194e5671ebadf6b0002a8b92e308cf49b880c2f5c187f7c76abd88f62477ad279627c91f58245542c471975ee87aea1914aff523f70fb8a5166846fc4b4699e8b05cf72ae0fdaa92d75acf46ee76a93992536299e27b224f1f0644b05f596a6b06c0e6ebe5e297d13b4cbd3833334ab477e9b47f27ae98892c8e71e3afaf6c421db715356faa844059555c2c1a37ff475774fe1735b356e20adf3920cf52398a8848a1672bb5ad83a86f762962aa8172f27b644ff00e28799a61cfb2f6dbc99f6615903af73d46dab2c10b6971e073b8ac02409e1d899a536311a9cb5d8bc03224323104f3fe823fd09b5bc3bcc234c6c994483fdb5b2a612ff307bff8426b8e6c30ebb5749825f6279455aeaa07ba31a3be88a9a7abf214fcaf96514fcf01bd9d871ba3e14a04ea84434df4ec5b90b1225656d2990ba9bc8ecb93d9bc235f6469f2f5da0da6cef5283eee46dcfa284b45bc55263feb3ef5844de7989834d4d0968bdb4a85064af7789859ae6c955ba6244495e441832120b57fd728c665ac3f57cdd495c2de021c69d28b1219aea1e09b2cb0d914595417aed4a7922b3954a89201e0b29334a742668e4c2648ffec106369ccde6f8e9f3998f026a3b4e5270c0541c8082b7b0a0b14016638d5e4ec4b20f87d529dbb5cffcbace884c3906e8268323f0ef2a44a956c3848fa01a7feebe69964886c82536ca0711b2f9ef886e69ff4083a43f5a9293306a0268e805c65dc947ab3c1fbceaf2bde07b07f0c238f50d64b0763bd20bbc4b35ea242853a49a7318e98cf68693a63267b0eb479c922fe64eaa46d7cbd70e2c06a14a05acb81e400434e427b31b3669359a42760ba74ab04edd304ad6ce12eaab28ed37071940c0db9f35058a66647b5e08c98d5ca85762edfe3b047808775b5346b91c466f559dec3162a145aa5ea46155f589d32147d58011028b3564d55a2885d0339c5cb0ed4bd5a398a1a51aefc255e9c4d918eb447043ba52295dcee8138ad39a53896f10094a686147d42bc94033bcd264e9dfc54450c4524e27a8c612a20a501a7f02a1b29f42050bfbc3c7f7c935333af44a03713804d6da68b308cf04c836bcfc7783213911480f4c2db1c989f4acc9e5d97297819ed28eafdfe2e26f865f53386bb2ca0c5d16d04552f72ea30b506f4d2e44abb9df4221ca1c184b38b993796091ebf661650ad6c7283c214b5e4f2ba23dee32525f487f6e76a208c8c32f8b4361f33f062c84961463825d4bf7800908d1bdb3f9e3f125417fbd653802e901d813eafe4df633d45e428337f232ce493883538032c8fd299d1fa3a51fbdeb594c0e975f1b98079241248e810e36285ecaeddf837e6942004acd88c0cc53ff032d8911bdfa282bbc9f8ebb89a1cc8d01d095c2a60d16252fabf8d544c4b97010b1011451b6185dfddaa9c87ee0a0a49fc83543e8f7eae47c40f2b7d824c96fe3029630d8bcf939b9a74a028d73823cf7e43331398d169ed5362cb3356dd1cb026af341abf27be9d9dbcdc9be841133fd55d0a24b1bc2d7e71fe68c5af9a01199cd54f4be0fb5e7e76ce8b9c61308ccb80b5b5297b63e068eba7640ea16c0fcb3a0cfa1f21c7394d90538251c4ed0d4819b64471f8402000000000000000000000000f1a925b483b217993485988c4cb29d58519dc41b02dbb40ef87b17cf32eb672bc0fa739a6f5beac8964c99ecb07c667db4921679e1879b2fea6df63eab83dbe0240c86e186416e4d0a584fa05ec4a7cd6b70e09c3a6824e8ecef03d24536b28d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006edad1f6cea5f0786411355db49bdf0be05062592e2a6460956fd01e9d3b6be78677a28be36843ce71768656831aeac52e7af9151c01d6637ea80bfee9dcf24b0382e8d48f6842a5c917f7a64053f00fdb306aabadeb42cccc5dc13fe1087262e649b1c0f0f33a13921293cd8c20d1d7a9741414902358c8b331499e1f53067b0210bc9ebc822272cdaa7025f3bb4142a53f93a7450a691287a0fc61c301785c0e0214383c7e04c657f70f45303c8458a7096e8e3164b46e66c37851aa74311db63b0a04c90efb4b289d2e4c6ec37eb3fe9a24eaa6b743bba0dced90d942917e1b73b2336ada7c19a25cc380c7b6511578eb73d4bb300e941b0bd72c74fc5c21e8a11f0318dcf4f14dee041850f056244b62636966349d6da825c23ce1d5c096c4d4366e020b4d7319677a86f567d7eb092eb13e13a975e98c4f74348534ddd662cfd11b140303712916925a4a8126d35a1fe32376b9d6828159d324ebd0c36099d9a239dcee022021762953b44f5cdaf2a349eed0f4665100867a136ae2ed68016c486cb20516021a4d825d75e684ec08aa3e22c9429a7fe94e9644cb2a4aafdd12f0db619bbd2adde29361babb027f4762e4b0b98eeba71f178c0ab50c53365c532bc6725b89aaddd5f8be8dfffc6ca7e50892768fda9f31cd94f05f64ee0094b3e4e8a06cc04814e3b02c94cd82ce6ae951aebbe6df50feb37fe7529ecebf113fefb08af82aa00e5257eed489152d664e29eb4d7395f8eb9c2a8b0a639a25ac88218ada6eabedf109b605da859dd6d58584a457979c23551d2f31fa53bfcecbaba576103207188a330aef3399203c7508ee3c4dcd9ca59205fd40abd0299486bcefa6568d97621d15b4bfbbba2456f8e26f7d8bc3dc6aa448927b6ab9dcf022dd816151df719071f2ab8f74128d568065edc22e05935ffc9642e078bdaf33ded87f1dd58dcfa5c68fc75cf83b0cb52d561c7be9c7aa9a98699b8b87ec40a86eabba644d17a3e7ff407a1a2acd55ab0b599319069d1cc142286f3231ba0eb59af457acda4ac6e26521bd7d0d8fe87c08354359b02b431b3e25323bad6775042edead6e1b6396c1111378119d6c076cd5dd16fd5f55433b8a433f373e3e297ac566f03fb49b7da4baf05c9398b63c8c9fffb12d55126f03546c801c805438b108cd60546e31e8ca9cb4e5c0d89afbc4f27adeaee1aa0ef91466fdfbc4e9ed0e935410aad49ec1081bfe7895ac9aa45c43eb91cf61d2d8524dfc042a1046ae0cf3ffef27b677e7c75d502524d539dbfc1383f05303de1925e75493b8ca83fecd3c0bb1ba4066231232ccf8a8330442933aa6ce94858ae0caabd983a70d85a8c185beddc650e37ddd76fd5a399beb5a9b368299a2344531deaf405813973b4a03002b2b0fc528901dc36b3f49d95c5732ffc05a661d9760e458f514c41277c84e1b91613abd8da14b094c3e971a789442edc3f10c07e527d2abf9255b35d5b45712230b47bec4dcd0f356b194c543b750b8da38172440d730ba6b1106c70ba685e9d9dcf5406cde3ed5111e7f890503d3ac40f4516ca9389381578f0c60a08e2a5787ef2394950815abd2c85cc22ff9a07f841b71ef240657e083e8cfa897afdfa7e91fa64c355f9acc7a6f702fe2b67c2c3b251b988aeb49ec1964db76bd77966c1468d33c47106248b736c41c165b6c06de453554135be55bde3309fa33ec328ef702bc058b451ee9468e5d556a63efc7e858dd315f9db77da0c7127c6efbafba56a59a2845036767949a0beaa89a96821e1223d9243dc413ea1e6caff069ebb453efe0a4fb1d69ed73028f18666f8adcbdc9ff148a7b484ba16b910f274eb9c5ae31d2d1877a93eb6923f8721b36dacdd83714990dc701f133a168bcebd50fb5257d101ccdb1409b67bea6c733a8c44082c61c5a0455f2627dec43d28f769fa61f6ab83b94a8b0caa84e14a0a0f8494d5c5c539b24eee48cc94b72194038aca64b24765be7c853474ba783dcfa4f570b801dddcf54148e59a243c5168e44e6645e23f3316feaa0e49e8db8d5a0eafed0eba2fb282e3c488a4f9fcb9560bb7cac7e03d5b0dcae47c7a9cd0ff35a400a9ced90aa6c7ea76104d7ce991ca8baeb6acfe9255dc5134dc3437f297172f24ee7b30c9c01835bcf3c37547bdf565b36ef3dcbc121f848c6b0d7d467b87706cca862e5fea0655463a204a2b1b0aed85649d32c5280680c7b2c2b4e471c1b868d50121814dfd235e29594786d54145a62ecd2df9fd66cdd125149aba02dc42c66c3c950b3b121b0b5940eb4677204000000000000000000000000a836261dbdd3db24c4a778124f382d6883966d7083b1f4614f2ab5748921e7b53f21d9cafbb8959099da47680789fb701268a34f3514217c386e41f0dd66ca002e835fd6beaf104fe98078e6ef6df181491af33b466d83f62fb9e821f61762550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001758cc6574514b6fd893053f5d6a3e4aa709ebddeaddf530abca17fa1607e54cc8c39b0170e8f0a144ae7d0051b789e7723d0470693892d133b1c70be7835f37e83470d30eb759f124726d46b5d368c92534a8a841f388bcd0ee88cc5dc29694e3c201cc770462b49476fcc05dc72ca26d81506385e62bf1062b3dc9e46c0400207b4419ad9adb5695f90d09321b293fca88d680019d4279f190cca1341f8018002126231d4879b18f5b0c49cfc86c1d8bab4d486bc8b8354df283d0e5bc63b72530b07b76829a556633acab3224592e387b1f8bbcae315d8356c48f0cab748d52b529bddfdcf43b2af23ae66fdfecefaf848416205e3c4a2223eeb9acd7877052727022a4c4639699596c9ea89172cee6ddd2e572a8cd2f5aca1bf6e71e3408bb52d86030344d02400012cdc1e3d2c2ae0c155357465d686ab4ce2a9522de3694972fbbf0318381a8a7010f7641748767374e102988c884746ea1d3db7c24780d7808e82a60214952e40da9b0ca408991f3abd1a4a978b574411ef6f2a154afd67f0c37b30ea03019a2d4981d165cf350eed7864907ee5cef47ffb2a91547e96369eff7f066ba23b020fa07ebec13ac7596c6a327a566b499875eebbdbf23a9b90b2dc61019eb7ce79c5476538a885b0c9817374402e0deb4e6c9eff3814314adc4452fa0b067bdfbf2b9bfc270c71a09e3e66ed85979f8fc6aa06cdd977ff992475572a5866fa6aaa5abaf0b0e3c6186a77bf479dfdae176b3be954fcda5cc1502b131dade8ece579d68e95d0dd50b083461cb49342f975833dd7500853f1099ece6226b88347828e93d81374856a7d386f75a2b4afd1fab85516fcd794804674a05e6f18bccda5115e538999724700abe1e575e5ff98af707e649b9852d6699cdb4a5eb5f6ff7708a3435de1ed98f99e57d9501dee3fefcc7d3b4ac98adeff722adba4b5d393b68d380004e4e40ba382dd8a4b263edb77235b48fb41affd880a8e2bb3fce558b7cfa6b95b05f2598c390a3e90535d96e29312a50f758de67cd7e469c0dd57c8059e4595c2fb0b854b84fb1a8780a95b984c5a1506bd6f4a0f161837db6535fa826814211af70dae273fa4213012a0364d0d08fb413394bd93ed80dc4cbab59ad39d2d860cb71aaa7d8e99cf89d8e71416ec3f3edcec61926211c89bc60fcc04130a1e5c2188dbb1106a357d840e5969190eb647be4a4061cc852e9e832eee17f025cc73d6a9e2e4cd8622ddb0bd6275c5ce17e263ef8b6d2698428808711fa634589068f5eca3720f73b69ee3eae534cf2d79700ea55db7aca8f67a1552cbabc3124b4842cc7b4ff5586dec1ef0ee629237cedca967643bcbba4cbd5d70df35dc33b1309588ad2657f69be7ac0fca8cf6bc167c4c5a7798da98fa61bf6d85ce404e11a36ad02829279ea63d1b00bea95ad78ecfef7d8bcbe91deacde2b1a8360f41c943afe6b0af79b5388f2739f8b95168e88d95b3f8e0f3688dc7071a06abafede2424edcb0d040399cdf1463961748366dd058552fb0f5a639c4d800bf0c231a31fefbb617f5d21e9d167c098fae6d3787f15dcfafcf85d5d310313b173eecd9abec56710f83a9df8cf4adbcb5f7a49f2626797c7741e5b840c95901f60c7d1eba1c0a6e83943558c146b657418d38ddc9d2c0b89c9950f6e976f20345b70b0a661cb187d0287613cf123b81bf7b1db3f991e46dda94ffbe864653be6e98e38d4e114d7d082d1c4857e1450f223fbbd66e905b11e21cc635529edbc4d0109a95cfef6fe0100969c32e5112a2644e3b3adf3447c550097d3572552e7e4a176866481670992ba468d71c2fd7c65bd9e595a16316a5c1f66e95748840ad71385eda664ff85a9b03d0abad2be8efe30308b5c83ab1429b74a4a0a71369d06e1dde801e14c77b40ee860ab8c088d6ffbe93e3373e7419b2aa9df182235abcdb0d7e2561f877bf2dadf7bc2d5ae1c6d28c29cb4fdcbe41bfa34470fa1185472cae882a0dca28cfc5692f61e7f27f25e6857ecfcad3753358d748a6d1948ce08f1df89b37be1e9beae092ec99a05c9ae958a67c98f7e69cd53b22d67689df2f0da144d602cb381801eb0fecc2566edf9b42ab425ea1fbeb209025dd63ae783ec989a7144b989f632b3b396305849784c17f1593e4854f3c4cee1db2d64d38ff323f52ac42f710ff2f007c99475aca87a5c7a5f74effd87adbcd4cdaa436fdbcc21f5521bb1ed9a33bbc5a2e3168cb2dcb818932ced95178dd4cc8b08c59346d9739cebe5d8671c37cff972fa87030108ce764f09e9fa2837ae3f8ba932fbd044ad485a9fe330d9df3b600141077254adbdc6ddff43a6c04eab21f43f22fac679d63dc34f252dcac8a69c742009351bb8c4d23b0e6869f98219440c4a16e0bd9f683fc742629f446add8179b9cedf8d740711a0f", "00656363635263", 0, 1025392125, 0, "c52ad4d989ef4063a0bfa7f0c13713ae3c99b60198a8bd010f5b8ba782862543"], + ["edfc012b0477d9ffce42d7013d0a0aaa4ad86e286f9a27394a061f56369e4b435b4708cb7e000000000952006a6a516a510000ffffffff8fecac3fa23c95956f712890230e4545ef6ec1d0ef07d40d98a75c7725c59eb40100000003ac5253ffffffff334558e6e611340cd30a68fc5274dfda6043e4bd94bd61e95d9bc2b411d5046c03000000066a635253ac63f5b8c3b2c7c7dc6cfed45b39a252efecf5bc032b037677afc7e8505cc434a2e082d8bd8d03000000076551006565636a9b617365046e904e010000000009ac5351525163ac00524900530500000000003864b2050000000000c6da580400000000076353acacacac63000000000200000000000000001330460400000000abb550202d4845872f6da4f2d89e37efe16ea997aa148adb7e602bae4caf2188b988c33a53dc53ad957eee363e20823824b67435afaceaefc2cd81c51a173533b32eac696a57e8f0c7431309bd12197fb583e4aeb5758701652ea36e2c373f9100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030727c0b0413663b4e64428bb0fbf4e2c6cd765c5825f8775104956861c63ca7af8ad674cd1b411ca6d64baa56cf61eb3360b5496c0a54d4cbf236ff009efada501a157005db4de8ed62e4afc52969dca17aec661b6ed07be030b7f65348de852e950580b3c60100aa845262dbe2982466f0f81ab8cab13c63d26f1331ce4a9022c787c7c94a4af1abad31d5082896e483e0f339b7243f9806ca785273c33353d031b958a3610996871541e93a0d56f9a9ac34a21be0fe521550bf67a4a67fa9c3b0a03fbc3283d2a775f973369a2ce852443ab42e1440e23f32994f8f085f79b8b5120075a87587f05c6a03153282d8de86a60dea9867701c92c19672bc2e984b962030debe0f0a5d3091cbccb041a7b661fee2cb3006fd71e8351c62debed395e52dc02186d683599c1269c2539582eafcf79c96153dcd7bd7d327347cf7e487f0c66ff03022e3662b0fe6a5b7722cad92f6cc0c786ab2b9ec096c4b39018894553dbe9210313edf7b16fc9ae5a719d86d34475f3972ad37e00cf118fafdfd3b02a435a95e2030e28a60e5493abe60640bfc209c250f29a7c7fd4b34ce6b6b4a38e06373582f026242535c36ee452ae4960be7015299d5a9fbe8ca295c891e45537ef42da84d2888421c5b2ed507d4530175504fa2f266441425a5b008fd765313420a705485b35b304de9467d7636c980659cd23c9e3f5948413cdb53f5120815a7c12ed1299f36eac5afcb71568ab99aa13f387c81d0c631d39602a5d21c10603dbd59064b237c37cde4f660c1962e09d3ff2feb9dab9fde82dacdab8291f22c95bf031dd3f7d8f422464a554d2ab17b9a010c947ba7f429dadbea570567c2537c06284b374e216ecce73e044b250513720879a104f625fd51d18e874c88a9c6ea56a6019fa1ed64ba3c902a2ac3bafa7170cbc21a928c32570eb9fef5216ec30f78a9d812ceec9ec2db192b0d3cfd1f9764364025fa57a0bf8ddb98654969806a6f690b435617fcfafcdcb5f6a1f96acadc717eff47c30738c8c03cb0ea6c4c1362fbbd224a9cd6369eda5bdc030779e25331c885b07c54d85b0902dccb81b147ef25dbaf5ef8fc9f22c657c6d85c6c02bae2a3757783848ba3a3be5385638b0e7ec7d9f55e083ee3e616fd5293670e22dbb9f0c44833e3ea85ad6d53ef41fdc447bae51a7a39181579bcbc08df0a978bc105e293e591b99fd76dfd6e90a2faba2cd73b342d696beab3238f8100cac8474d40d95b111cd8bc74f88cf209dbb3cfcfd944fe93e7d1f745a7f5f68be630bea79b49a4e8c471f3f7594d99ede4acaabec2a2547ebcce9b705d93417f1a0dbe3e385eeaa6b7d3b45b332ce5c1b0873e3dd3d2d6491e063707168034bf4fc36914fa191ad0d05988abb23737b2b834757f8f86c80371f96f804a0e3cb47a45e66abe89e359eb9f1b73f0a20128681af1f72d271ca653d8954aea02baadb2a08781f3907196e8a4d3fe7aefbbf89a90b9dd62e45111afaf8d85555d3b64ba624923497cf2bb4d0cf08c85a460ce0a22f5e4e871b5a8a9b46d52858c3de6eb1e4af8902c02dea19096d7f9c32ab9a8effb8d0c4ffd7945bffdeb79ec15549a97fff309d955be9e48be931a5c373019f42eeffa784d7ece5fea682cc9cc14c91f49c3191f4f51c9ed181320ae8cfe6c15dafb766984a7ef0931aea8e84247ff20f75fd3ce266a114fb7993e5a1015ab765ca4a6d15d0a80b886781d5a93dfa0c65ddfec15e638e7da56ded8e24205e81cbea7d860cf3387bd58f2bf8f75d5d6ed44c7108692885bf875dfbc17dbcefc0ccd3b064b764ff84b8cb50d86f77a292969f5dd81203cc0285d7ee5369b5368414bef4ef20f451f7ad0b33cf9210652b1e22e0fac92808bcfb77b77739e96ebc9732bb06985855648d6a20f23fc5ac40d15ebc0fa61404fbbd9200bdf87c039a7bed4e4a9e0e9fa336c06293a6619a48c608894d0dc5bb0c62b54db3d318e27f3c2f4221e5c4d2333d09bf7243ddbc9a46d48708c4ebe4309a60ab36e8a1ff6bc156fe1c0f70e532760a23bd900244cb9da0f6f402191f5693853a9e45ba4a44b82e8ee19836df5a3f727fbda8f434943c8221e4b07e82dba13f8a33845877a610f700b6bb88920c88f6092dbb5ebdbfb6cab9e667e25d24b6284d1e17389b840788b78ee97fa873b8362a4e6e0034b6d86e056dce1e53ed33ee049f3d7e120660e0ea2a33bfc91a02c725e43d5b6a4b65f86e3a86fcfab6896f3083b6a8b6e278c3dfc50b13fb686794894ef9be192b8a9dc0ce841282ba783b6d0500000000000000000000000018bbeb09445571bc18e806a8a9215b162a41f48deea7e75e2d2bcddd5e95ef6ed217f07ba47046d8dcd22813a6e0aaee3593e8f78f1244f9068d9bff82cd0f8fc1b91a0d741cc056297377b9d907f2e562f90b3bec429e3b971c9d6e83b0b0e20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029fbc567dcfd43f17cc078b9def8694985086b06c3f35c537fafc025d6d2ba3ad13c470af6d73a083395d2824ebd928c2ec5e4367e5d4f2c9df56448353b2de61f675e9ba3fbc34845dbbf7c66d7e0961f3ac1db2d06ce030bff9d1b8837add0396891297247259c183313fdc75fccdab49f2835d3604bae0723cd3b66e788cc020e40796537a5665435d48bbe805b2c9f40bde12314f833bca69d46652f1088ea0300a933b8f48692bccd35ebd30b51d37db03da25f0c4bc37beaa64b787307acfc0b03d4cac6f3434f4c93dd5f8ae7c3435b2a8945373e4bb5db2b901b429b6f17a208273c4f4bd3c219f36b088879835ac34aea848eededa97c2ecdb4bf719d2bad02136db36f26f72f86e2d08f5b1c919a08cd8bc003e97e3538c55bfa2eb5755161031e28697ab28610bb5227e0526bee94faee743736066f4699e3941c3ec90bc2f70224bca9c28a25432f6abed2f02e229508d46c08a5e1db0c61ec26a23f65ba4cb90304490df91447fb59e3ee8a2c06012614b298442313540c916d931723b3979a77031d8aa06f5d1beec2011b12a330e646ec4cfa7fd661bd164418792cbd221d50f2be5944a9049d47c26d8a73ef21e9e871194c3fac741041f1b943997081563c38801ac6732ac4a09a3532b8dfe1c97f97031d3b73b9d0426a6da1ee1c1a8c5f3dd4f059fa171b8cecfbcd7b1d5c90063884691f8f3c63db28104a923e9632222ec85fd381a1f2c7e891b673df55da2e793bb7c296cdcc7baebc071cca6b791203511a40aebc86fe4eff54bea6152635c27a9ec9bc1f9aee9f67b7a225f08db3f1d4e81956a0606634c51061ee5c8ecafb0e1efa43c426eb0bda51fc73279246154bcb1c2cd5a71c6e91c036a35ea0b4984d154fa949d732d3c98a5a9f462b5cdb03c56a8939093ad6fb07642ee3910469ca73753c9c1bf16d4e0114d92aa82ec5c576712923b361e9d537694e233bcdee1970bfe659d9d57f3d093d9f76d65141059e399110a4c87452020a5c1efa94576dd58b23f440267df6f95d3d4c213c46eb88216e1e40d2609fd18fe23e5a12c0f726f85f06b7fcd615d52310a5161b50cb7382fbed8c78e8ac76c467e243235da99dec702a99ea7bc714533bbfa72244679b343935fd272e8056e4599a94755933bf0f1d11d31b5bc3e05fb3a341a73ee9cffbbf160d0d7b00ba250c330c4bbe9efe0db4e7168069322f037a52c2a051188982ba2773256fce062528affc4c94367cfb238013f543bee4527fdc31fe6b2c93149771124174a7445980f57d0865dbdc9d2a968135e1c3ab6f02a200bae1103ed623bddc69d8433efa31197aaf2f8e782cc3874b59de5ea972f966ebd6956cdf27ac9f356f3b158855b1b160711e4e127c8259e6840f9a82e93ccbab2af71b956859874cbd00753f4ae151530dcf291707ec6afb7dc3995a4335b39525aa37f723bb465d4be3daf4fa7bb0fe41fb856660ac6b901afa027a049f5e2075d9d523f9cf9040c20be94faeee35ec7cdac2eba4a0409df0e82415024ad063dc38ca24b54436a723fc8326124c6586d32936872a6d212b6ced2a76ae534f180d9d26a902f4ca2be3d378ab9f1e5e89b9b3813bca99aed5d89dca34a604f20af2c48a33bf664884f145eecd5fe6054da608a53b0144029ece0cd91f8447186cb71a23ec37381c259eb6e5e852f44b310fdc0989fa4da25edff25cf1603689c27e74ce71e0c8659b083104aa101d7c89be45c6f17caa7733326e9405cac7ee3f46ef47885521e7293f87f543e1c1854a058c331c92c60c0f02a58ad94cb68f6014c0fbec171c9497397a9c11cbbeb3e34060abc08387aca11884c19e73474d356dbc83cca66a5803e2a98abd88cc76bb291e6c2d8012860bd1365d741ca29aaf86f635baa34613277ad9162ba2e3fa8b4b8524ed770648490ccff48d2f70527d94a7967d853b8782cf0bcc24e2b5a7b5ae9631f7c649fc87bc872eb3aa3fb1e194e7674a5e918c9e696584a6683b76f72b72a3cb3d276b3fd0a7b0975e6653724b44152a0c50e37db7e549b3832e578c99e6b4cddeb086bd29a861fc542886e5ddbf27cd791b1fac84c0a94cabea4fc3c952f3161a4d77dbbef3ad540eb59d23964ad34e93ddebe662cab2487cdc4e602484cc9f410eb5c26a4eca21598bae1a90c12c644fb9896b767203f3154e148af64524185a7594cdad7719f17c62ad31b21c3c3ca4572e68907a70453f3463edc0d75df973a9651bf74f4cbddea09134df935d465ed2d0eaf0bfd34b33c5ef426b6548a398bcb14fcef3cbf5e2ec0b590a2f229b754d56cdd3db32d64986efed64ef9960252f6b5e2f3c4c73533aebc5da0f97e8e6eb6e58d5794f355d3c6af85317b42d694faae4e432b5ce500e4f523e0a1fc1a635dd4eb48159ae792e0a91ae106300", "635265", 3, 1864993491, 0, "a6d33b8e6acbe8432a22027cf5ed901994a7d3d6f43b7222ebc93fbb87a5491b"], + ["030000807082c40301923dfd0006da40080c211784243f7795af15efb84429a7b12d7958cca87a10820100000003acac6affffffff0296427e0200000000076563655253ac51b173400300000000026365abc444ba00000000016dddef05000000000000000000000000e2d9b32cb7eaeff703286a4526b6fcf9f8db431cb7052223bc68cbbaa2c568e6ca6938ad7d7ee6d3e2f51705b279b7fb36be96feda6b757d4929424f530053267d8f56004be71f579c36192ee5509aaf058219506acf8e405abb64b7d33e1c9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d9c59b2f0a9dee67a4ac880ca8f8858f98089d810b57fb8130719d1a900ceaf3a8510dd73b96a314c75d1a450df9e1b86f1cbd66ac05cf81bfea7fe46aa936d57b89043d099f2ea8cac803ac57bd08273500dd4fa2cffce531db3568ab6f904a6e21d398f0b21a9973698f7e910e97c86c115231fdaf4002ec55e81e79766a3f032c9f23dc8e97b1dd01c508a4056837f5cbb24089eade942de35f955415e8fa280220e407c47fe30b1e429313a829e1b035d438db1d2d49f4da3ee319370f3229f80a0774c1406b4edaafe3f0976b673c54999efa7b0216eaa3150a8d8e77a13fe6173c26fd1f40a1c5e8bdab4ef7e17c2ba2b730487c92a80efdd9068f44c4f85697021abd0d05299d428098bc74053da509ea1db74de0fe6e13b217381c4bf8090eb80223dbc71add09b9b9316c7776683ca1077a8498b1277aa9de38bf7577dacc26680225c453c79bb4c34a0effb96d554aa387f367157559b342e4ceb4f46ebc32707c032b80f71e017d4a4fbb4367e6330569fc212e8c13a9b66b75e43be341966583b6032f511635ecd6c501ebb9e3356698cb79f8a42bcc26eff0e333ea18a09a3c238fe5b1b3d8c1ca1f24b62770b8197ef25ec803d8c6e31216aebbffb411cf2e01063fec37ae01cf6b0506358df7db4689977fd682c3dfde642cdf47d2c1fe1aa593ed27ac6424b892dc0c677857a45283a558cfc38dcb968403e49fd8280bd70961904383a9bd088cbe345fb46de6594ef3496e7dbf2062a54a531f9f4a7268b27d759537214d3b2b0b8548d724129ce9d352775172b91ca76b1fa5e15c7c66ecbe608da96db44adccc53c91153afce54d3cd7d1f9e5c17756fe764e470a76f2acd025bb520188f8fb389528d68e66c889fb891876b6e3b621ec19ab47ba62d6b748e87432ea084d9095f1c2249c365c3d404038e4d6e8b4f51f5bc7504b28f84637ed896c7bad5ef1bdc4162f5a8ced6bd045d3010d55784f5e13f6d30f92eed40f8433f52363edb3742d9333ac1180bd5a5e7a94cf2010b1921e7b1b1648124ba0c503490a3aa4cc08b07a67efd40f7ff9eeea10b785b39320e40e36848d15c8f1d8b0dd8404533624399f374e4d9c6d2bb64fabfdf0c286e6fe2c570b1b3573befc3cc89d40da59f9ee8e7f0dfc9927780a8be70eb64ddc1dd02ca05b46b776ee57684a090aa826d81001c763a34e5174ea8bf72b14ec8f8c4e3f9c96fa391c210cb7c50a4cae8c35c404ac9751c44b3b60cd75e42ea33144cf70ca46551f11b43ae984f61fedb9eeedc160552923161585f44a5833bafb2c567b14598195158dc478779df7a23d6438d5d5e922469a118846e603afffff9f2abc4f08cd0d3979b13b1c736d8323a279a0820376e7a9eb05e6bd5e28652025f51bc095eb8fe7f488c8f15c5adc3b6e38297fe7afa6065e5c4ff6e1bd12b3ca02131a558f90a5e364c6e9e39d569327080d1623908d4c041f5997bb1beb37002a089c9f60417b708c1b97ff6ceb7dcf32cb6fbb631f89ea5df665aa33b57d5f02d6390707602ff07c7e335d903539484553e535a83777e9acc6b19ce5c7a85e4fc893755ea8abf7dfc9733da06c546a05f7b6a2c69e9dced40f52940a496ebd24158983830bac003cbf67a979ad3a901163009933e241a83e44f4dee588588d16931a0e1213e128bae5f2e6275f12d550647368d3f69a4588c07660277e9c0920d239f9311c5a2212b0cc6cf6c7e890240204df472cec171a0e0b181e008b21901787986e4f748eb377cc5b1a62843128ba7f76f2a84e77e47e43d524b411321b8d98e9c01ab91bf78ff1406fb0bc2fac97c74bdef62b6082469aab62731bdc395eb36d752232c2c6227ca095cb0d3791f828d7bd4a73768d63c512ba8511a8111e3a3c4e872afedcf2d98f6c887432ef003f4214c0f905dc9e84318756ffc9dd5876d12d99986beb5e1c9ff77a0aad119b9e46f3e7b167e3938b5b1fc564a3cd8406ffda8d881efe9a4a25fdbedf91ab3d421f5b6700a8adf7c8e31b063a0af7f5bad71812de43005905068fb0b16cd910236dca7d750d768e73f9d96658b7380bf88e785a08467b56eb1d2bd819032c282e829d47451245cc8e86376c31b09996fe9ad20068063310811e26c5f278bd46bbed6ccfcfa5fde25b4f37599ab3df95613e80388fcc4d87cfd4ec1408e2c5b7f7458484771fe84f99b3be40542350ffb1ef4e111584e9e8f7430d75c4af1c4e16d03cd1cf2cd5983a5dc4fd2c01f26b7e61bd4f6c9097a9271fc7cc29a1bbb596afb982b4a415b5fc189bcdca9c86b72f112c202c77394ae910f682a133982a6e886435918c604419145774f8e0336ad15b2295ec740a60c17b40edf2962aae844257fe7ae042a10812c9c6bd33d815cc7d51135d80c25e6038526bd609c13d3e238ce76dafd0a", "63ac63526a6a", 0, 205200832, 0, "d8a943d1fec6e1b32626de0efca5e3eb05fdc3de040a37bb688a05110cdb1aad"], + ["17ac6726047560706b9016da1bd4a95317192a9c208b29e63972f9b45c253d7e1016f0e8870000000008636a6551ac536a51ffffffff6e00d18a2696c2b1a14e1fe72dac13acfad3f01ea42ad23047036b1b85b692b1030000000652536a00ac63ffffffffab7bb86c3450d9dc79af4fdea4dc89d5bee1f66cd3df6cf6d4928d9ac486b020030000000400006a52ffffffff0af4667ee623063897662b635d8d5df5fc742782adc9c7b94d563dc6abf0ea42010000000463656a53f4587f3902a47c3d0100000000035353ac9a6ab10000000000003463938200", "5365635263005263", 2, 1153208478, 1537743641, "39b149b97283c43a6fae698cc9b33c4f2d7e66cff2be143209b725bded32deb6"], + ["030000807082c40301841fc312e717c241d90e6d7cf2c9c0ecbb845234afbc9252e829ec6c965a93890000000006ac656a0000ac73c90d3b01daed760300000000076a516a536353655fd29f89000000000200000000000000003139bf0300000000692932c2e57ad1381334ac0ab9becdff4f18700b9c0519154617808bc133b8059dff932e2da76ca4023d38d37cf3038fdae85124544cadb1decfc769302f7ed7ad39deaa25b6f86c108d065efbf851051400f8101245b04846cc405e06901de400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f5b836f763810983421f4d0f71bab7e1fec17ef053e9e2e40ee1e9f169a44e6d175be4f8fa337e7f2e5a181328ddda272cfa39af678d81beb7a4a44805fec47be2767345a32c64f5d751f011dc166dc3305b28d1528ec47120edebe766a5337e1ed7db7dfddb9f84d32b86db621800ffad29bcd22542c4eed6d330e19da770ce0307989db99fccef29d31f41fa1991aeebc56d64c689112a64247bcd685b324b91020e26d7dfd758b4df3d85be51f5b7d0f50aef62ae969cafe205b70169c57a818e0a08de3da4dc50a2c686a03b7594e90fb6eb365272e7e7b6490698df3bdf32c01d211f30d0bbd97b807655481a6130c0245b963f2b6b75c76d96aa46f8559ae14b021854dc4e17c974db4e6cdf3ff8cfe7f06e678cf3de2c7d1786630432d4f45d55031d7e4f84d2841a48a3a80957ab543c2609f667a64be749a8ed05f1a6ea0f067e02004f3f8cece261a222f3e71434ea61b410d398aea5d0306f08c92bd33562b5fb020d50a12de513ed3d701c2ba0dea747447e7a035c534ad76ce40cda6016cd3bb6031721095d5336ad55a1c72897a948b6117d83cd4e9440ae0ba06d56b32395714641afd4541c6b2eec3f77ec633ef6fd1c24af6cc92cbb9016b4cff85654ac9a1ed3115449686d9c6273019b6c878a59a99a847a73d3baa7972ec3455dfad87419d950c76e2841b9344da40645add816e4ba445e66bde58dfb2ddba0622d21a9e9c31117c4c89eff717511669f2afe52c625d7673e4fe2bead018a55312516dc91151c68ceb66339cf0e8141b823938cab4361e5793f72ce4cbbb0118b6415079091bcb62d23fdaebaa98aba39654162404268c0fa67a9b0634b7557ee7fe38da8aa49db0e34fa4c349d41e0d0ef3c17813519fb89325aa0577a596ee533b07926292bc4d89085dc6d61afac101b2e031429432d2af87fa808aa3f948a87497e0dd7929df8dfc415c41d9a5df9f57df02d3f2ee19fcae23aa194c68443a2273f595195cfdb24c09102b2efad3032869a7e5ef3caa8508f4fb0fe3106e1c7046ad21e1e11eaeaccad58ff535c51e382a35081279d6be1db57587a8ed28247dcf3a4fb75fb1474ab99eb865d9b17c469927b08676b6eab519aea96f9df71be702c1440860ff8024731c6d3dad6c32fe06bd85b5cbb344a8ada2c4656523df2d64537883538b0224100f744fd729180e1895f1fa7eaabffd76de38f3eaf80e1b66fbbdc4cae11194c3df8309534cae946818f3da1487b8a8ff17267b98b9a49013a9b05fbbe1636e1f44029fa96bea7ba85fcfbb845fdd699a2ccba6ac2fa6678a4e9ed7b548d65e2596fd1195bd914570a8e7cdf9dbd1c24c60ff14a664f6361a2b1c8864a3bf33678e93543650ca98fc0cbd47450fb0e70eb1e6cdbdebe783edf5ea58c37f60d0ade0f59a27f20d845eb48da2de8c5885ab270a32eee3fd2bc165e42d989f9af61ba3b1473a1cab69fca248ac1f108088d89c2f2b776f673ecf266d6e2ae46ce785bc2cbbd921bd57a20d95aceda3d3483affabb3f1ffc0e140875e46ea290e93c059118625da6d0446e20554f46627b9462d086eb1a1aede357b8d760861f65e22f6d7aa1ed221159911292fd4963a53e6599f613a63f6968674da619e0649621f6b07d151e4c078474cfc8bdd28b0ad4a8e919d0356396265b6bec7f438ee206ab00a30088d03688364c1e09b5439472bad81a7d0a3442963c2fff95d96fe484b26427be3760aa72307c54ede9eab00390fd3c4a3f24e6143b9fd36afb863163d61b1e19103ecca5f89b789f903d82165c0213ae1950d2202907a7e3da8c3a61d1d5091b8e40296da70d57c1154f54d5ef77b07cdb4f9c38c35c38d5229ca3d82fed4ca1a65eb7a17f6b366aa504b60e0f6af3360ddd57016d1f72dfcad52ffff75965a86fbcbbc7059f11218345f42b8f929ac5a69fa3e634f21f34d6a8829d41a7b4678a058e32f706fd8fd7e99ceb02d91677a60060feaf006e952b4bb37c335c0b35853702dde94b8e626a0020b5e08bdaa0147442dd770baf66542b71da02a7eeeae85a163b8817ee52a285203bba0c3a94ca13613b39ed9aa434310456439b21c4d1a248343ef7e30804c084ab2e299cb05889dc249e500e906abe3caa2fcfae9be2e61bf781170a6a6be673af561b60090da3c3dc9d5a809a56c6f784149fbb7831914d5fe4667fd2c0039cb29dab657257bc7c677234e146dedf1b725deafa1418746abab3ecbb0a3f67740f0b77db2d90e97945f880b65ef17412a2e5aabfdc44287def8d7d7f7b000000000000000029727304000000003f5d42c851e1e4ebdecb2a76e0715f02186458ad2b6e951cf54ea8425b6b174f688b9239c83b0ce4859bdd86d8ff0a8ad6e07fcabfe1944037df36a4e0e303b2ec79ee72730a12a20ab03b389344d1ffabd8f38b013c81ab64090c8c83102a57000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b194e29cc808ccb559d67b80fbaa7a3f72d3f515200a032dd79f785d60564328249a78488dfc606b9ca0042e0136d349fd550d74bbac00843dfa6675ed03f9599421d8a4c5a2d0c7e468487821ebcd9e72b9ee2084ba8cbda7877217961f0f03509d7e16f7d1b8dbef96f5fb3b6e732e557b6c3151da252c171c3a65122457a02127f9c65893ee8e182937711dd9deae27cac6a1a400d09c949ab971aea4379c7022b25bb710bbdd40e9f6c919fd9fec21b660f85a5b2b71100ae2e0e2df71097a00a0856af97c2565c8ade0f2eb9dcad6e565412de7b6b573b9f6cb36f2d2545dc023ff343b751c540e1c9fb2c7d33d5d1d65f3ec3d6e9360bda3430edcb7f5421f2022aa72f55f5f27e99a0255706d2781bd6db5e1df969e2bb30af8d85043d1d55d502063e997293a8a0efa1c876003b822d7668a3c312e4a03c6a3a9b19ecae9b54d5030ce4e9a6f2a8a8a50464066715c0ea6f6ad6acf8059eca6f90aa492a3711f2cd02237cb13f5f117474f7f7c05f50a60f31447c79a68182c6a01188fae2712cbc8f020320ec7827b1b7f1e15956f48bef336d29265471af9575caaeb7da21a7ee3a7047ccb6164339e22490461a9b344aaae75b0bdbbfae171d1144812881da3a9cdd8497a4f781c32a6cd0c16f530997b596ae6b8046326d7ba8a9c401d08fe4ccd537c6522727891041de815dc2617caa01ba2a525c0f0ab29f5fde7caa64d4103156d5f141c95bb8634c8a3e2f126550204afe56cb6652adc9dc5711c33f7100f847af6ad294f483aa5bfb5bf417dc065baed3ab08cd3c20d26890be1dce1ed03456fb9d06ee19050ae7ed6222380e98178982ed686024032c3340a18f8f67ab7fdad0abc4fb9a0a502294904f10681349570823a3b8d1ebf4b91364ae7ae44995fa984a1cef33298b27a7d5ba576b24a946e9c3d3189da8e0bfe5ffe04bb8e74612719c0968dba6dc25206480ecde18b4d89b4fdb87c73ef9cbec35826b9f53e1e9516717f3c67478273feeed06a12aa6454897983b55e62e194c5818ba66c8c19d986f5ff4e62b97f41ba9269807abe781b80f3870098764f989c75b2eca8fd3a94c0c25ab2dfdb8fbc9794e187ff7ba95d3dc433d3a838855b3f2e099f2b41444545c3d35d39bc07e89a21be7fbe18723b78691ebd420d05bd6b7abce3679c5bf232b08e4a44c20cab11c6d5c38df34ccbe92db45adfe37718ac30ac8cf9a788a412eb72644b9e58084db4ce0aa41b342b93f4443149209b0eabd6bc80d995c073252df06d002181c4f3d73649910e55c1de2a058d180fcab3884e32cf0f923dcab2f20f8fa2aa955ae0d5d7772c4af41ec4e971cd7fcfd60cd99abe2420e860d6c18a08f543ccd277ca9c910293dd60e756fd06a71fa295c6bdac7e6413b71050f2545e8b2a4f7fd58a213e16d14cd91580296beccf4437273fb0b248dea987c33cb9403a0f53cb8643efaab48e3ba289a52036a3119584992c54d827b06bdf255007d1063b16de0a5df6f32ddd79382b8cab49a5b488577ead31b7bd53a5cf5f61a842747ebea281192f0ed07889ca1e3efa87cbf44551a785513281f13bf8413d92f951eb6956883e1c64e00f5f1ffc6c6c9004de587dc628155f89db35af6349ddd4416eb124466ef6bf8e9db8b5044ce9616b07ccc2f3d9973af94a172c2511ba65ced2cf01c3ad0dd5329b1f58a2d7c3aa0a2f0bb109f70cd2197e634a7eaf3d4c3e4fb055f5637de898c6ccc10e7c363ca01d2927f08a025d214c4bb7dcb8903115727a035ac6d1731473bb8f3993cac7e80b2b47c869dadd22d66601d1c8fefa957ec68ae48d8ab88eb9ae859e68c9d3af9eb8c7f0e25c43ebdd02e21760f09c06332c1d5fe6303470d1a8b8c3ae42c47a0e6a266b29d66957b9a7adf2439bed96f222533732083a867f943a6a858e4aff052f278ba4b9d14fb35427c4d38a54aeea979621cde044ad33a3cfbd54a2433a768b1c9ad201b858f8130c51797cd31b3915abc381c7cf172bc3f5360c7338a18aaa8c32b5d5979f8ed2a730b453a63278db415895dca286eb5024f52462ccf4e015796bae15c3210ef6a8549b5c2fce1808f05d4436a15e65b1fa74c855dc3178735e793670cada56379e7005ad603b16b3035130ec89e1f1ef58ba8dad23dfa9145712e0466cab6d4995cce05186fb75f53aadf1aedb1d916c6a6fa0b0e3ce7d55b288ca08ddc5290e165dd413f2c63a8fa645c0f64a95ea1b4fc9d2ae297f6491926488c6f88d05db1c2d761511fdeeb75a3be9cb976492f87b99bee29751d7aa316901edb597c5133c3aeb51e46f0b67d546660d8132349951e4931c2d58db635aea5619f320c5532dfb3a905d5eab41135693b9b8984c91da671e44948b126291c4ec2a01b76035f5b40ec64ebf5d13b0b8518b4e130d1679101", "00", 0, 684908530, 0, "1ce8f79fa501019854730f0d329ca1178c33bcc6270c451b6fa14d429ec973a1"], + ["a5da193f031115618f6fa2ccfaf87a51c9084bcb013a738bf9d041a8c95605c5d26b8d45810000000005536a6a6352930941dff1b62e780b96c53c3bd2561b12f5306ee4ff327a92aae3a6ad159d284a3d42220100000005ac516353ac92fc169e24f4e6527246a832e08af878cb8227289814b57955ed2d7143ee83a62b7a3a7d0200000000ffffffff039c6dc00200000000055365656551fbad4802000000000153f091c7050000000008ac52530063516351387bb76700", "0053", 1, -457316893, 1537743641, "d6ff6222776ddd7f64f46a0cc43f34e1492dbaa9e564e8f3f747a58eb49a6da0"], + ["940e020204e3e13366fdd525a1a836d15dd53e2357eed410d45f86daa1ad11d6fa5c4f6db90000000005635263536572a039ab10a12395d23bcbabb6671051acce104ac2a5ab762fc9335bfe7192ed4534f8cd010000000763536aac6a005170eae85b97f4c4be7efdc8b74f38693e530d0ecf210e118a1cf41d8b5440c10d179e8be402000000036aacacffffffff36daad406787d777a37befff3ecc645bbb11da6e9e4eeb52235fe7b4cabdda3e0100000005535351655272782a7c012cf1e4010000000001acec098fe70300000000000000007e45360400000000d7e5f0ed26b756402a135f6445bc8510fe19cf817f575c74a1cdeec93755a75b0ef88cacc22a4b3036a6b7e7d12e29f3489fb3d7958713275ea781e08b78e69f0a076f08d508e79d8ec694f0b53dbc3129fe118480f0296a494e81b6cd33a657000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d87fd33159a0eed6187f939cc3f7052bac6b0fa09be42be51c11f3e633c473b97becf4d4a358f03fd1fad2120eca93ace554021f4584eb7aafb862c94445f3fb6d8388144bba14dda7007eef89a6b339a5eec107410eecf007f124970f6f44d3ae9828cc739be1899472984d5f822021019bb1e8b1ee901a6d56d48542a403b03286fb0cb844aa9e88b30c9f3db06dd4c619b8fcf7f636097070d213921bc98bb030f092ca27159c9c884a302a6d01b0d35523cab1a78729d206dc4ad8b3083ede80a03480be7c214b9a17e5a700a4c1d4f5eb72e574e736a4de66e3261222ed15d40974557510142023729e6bcf52a2d654b325cd4053ce78e1e5e8ba2607966f765021ac7d1f72363b98807cdef2ecc094bfa943ec0061a1db15ea7a2d8126da19e1d0202f728736ceb42c6af173ec06992dfbcf43ddbdba1c7368ad62de102afc35cca0307e143686afe413e8a4a943544207dfec7bb86e6ec02f000196dfc270ce20fe1031e41b570aea3140fbc553c58fdc49f17ad0fe764bd82f2d719a995243855e31402204a62e924adc8f835b8a4d833d6ddc7cc89142bc4e6d63871b2f38f5f0f7e1b2d877abc1c468f4199f64c964046f679595727a7e991947c5259d47fe714ed6d4e2327ac7a485f56a460b8d78af776020f9a41a8a7802ecee1ac4e4386de3b60c8fdd06700c8b973fa5385b8403f845712f16ae5d12a5f681da1cfc272bb0e1d25e79f21111ddde5bfe47670eb4ce081b14a88e579a810c3374bf97099ecf1fbf81d38a64ebe6629178800d32a004762316eda403d776bc49abaf6e3ba11f5ba916b44608c1f0ba9f1eab3e52bfe1b3a71e3972aa07a2677e62722d07905ca6de849655a5129fd364bede1b7fc649df064d8dc2fa5ed7878a06ae8049df33289514ce6a425cdc923448ea3f09b686932822106849bcda61a2436948f0b451a5176f6060314e7f6e3623f4da9b923adbdb110d9e0781c5cf0b179776c9a48825f4093771ef1b880c62cc00f23f9ddba37fa53c0f5cdf6b42523414c2006a5e887e5766d7bf0a2246d6dc06ee37f54d446acb873488ccc5c7c6fa817658dcd2438a5162ce3473b644fc0a245531307e6306ace128a90b0694f4988214e24be2515d6ef2b0f29d19b287176bb53a94bea9e0e30d687e0844d0b5df6260cf831dcf8d843a85a9b875de89d50ab45e68e2e370d0dd3a832e8782c10748d12557ae4001d87c534743fd8c4d4dade9e04e9a5a709b7ad81b2fd472285a0dccfce4bf28cec32dc088aff3c96d6a3b6ae7d134a95a71461aa6602626110eda7df0755d5d9c30af6288ba80926d174f696dd5bf4ae29a88464bca17e80db127f4e66deabc638e713c21acaa2da3edc884933a819806bb8b6b0e529a2b84ec22d39e9b8fb92e0396eb3fdd492d03dfc6f4d4769f3ebb76fa580561d188a626ad34aac613517d16ec505385fbfc1ffa44e5070c9dff77105468a81bd3586a2eb3c8bc251f244f49976ed7ef01ea2e08db753800fcae1203025668ea2a18ed31733359da0409584944751948e35cb6e16ac104818e9141f513f7c7cab83d2f925b529d1bfd176b0083defd04511a9fc1774fbfc4bfdf1c2224c3b8e1ae1f6dcc37cce7b899952318fd2b271afc65f90f2e7b8743fed051872dbdd6784f38c7249819a5cb91871e0822cafb20a5c429e4089b123b23392bbfbdf2ec309419ad8131a4974b9573f50b09c24e5c1b1434a38c86b4e6efdb71884de53a69678078dac964bd94d1e781a129a4a4ac37b74c032050700a34e6458d78f2ce8b941effc03a6d34e28ea4a05a51f913ee5b686637dd236a807d7bf0b98765c9b711d2604333564637ad13d1f1cf770b27e18b333ebc91f1927a68412dc42479e665cd084986d556e8c60b6a1b7839a435dfe228c30757cfc8495de15086c8567f7e0ea4fac2d0a9246236acfdb991048bff0f82b77d64ea7e288d533a64c2e0e65270e4b333f60c10a2ddaea2528663d7fd603cbfc53176eefaa3ae5d0af5599941e5dd0517a79434a54517ebc5f5db234e2c783992e950f81090eb164cb099674c05aea81cdb0de6a66c2c2c8c13db771a3ea56ea004b2f922650a103685a47713397c85581136a569d03483178e9d5f8a067d9849598b6059070b632d903eb5bc30dba990e602d8605d561cb8df26edcfa465f3724c54041dc4562bbcf02d8024bbf3e194ff1e88794a62f457cd502bedf7ff16132080783e328fa44c3da6e4477cabc986de88ac9038c7161bef974cae8555b5dcc269ef5665c9b66d30795000000000000000000000000008569c1a213bc410d98a9e32024e38e30b778a649770a4773240baa96d5709c8532105e215567e6f9bc3ee53a8a0986b13731dd6b2052715d005f55b8c7cdcd460e002da843d435cee4b45544a69f3783e7fb3d760caca0cb102870f29cde5a0800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a74d56b508e168cefcb78a83c8530389c239cefe1b8646a1e5682e7187546f798bb36e99d3021d3dc9ffa151aee0f065f2096e4cb08482ba3781526bbd3b07ba1aff20cacac2d46f6828a409be01819657e499bd5c5e7b90901b7ee7c90ae92aff6ff610cea6b3f41638a5fd200c3fe6a1e78a80aa237170b81fe2122fc910d10224006d8b7f7533225b8d5417597280ae8a5cb580f75fc8a5a57c964c969d1edc030a9c2cae9073f15f93101029fdf60d066d04de3a412e0614e17aefa9b3655ba00b001765ac06ec1dc51a3bb1d9abbdf5016f010a1ad1d9372c62d7cbdf5b38c0e0b420bbbcc8f779d83c8ea40ac6ddddee9db8e867c40bfa95d5a79df1344b896e0203406e80a1bd363be1a4e994898391b8bf50f11b470bc2d34b0468120593d8b60229fa482f88ccf4a24e36a58f51dc5f1a973dc965bc94dc0353a2cb071ca91623021916665c5ae1b38abe5b1543ecdb3b0e7336eb0122a8b4b18185b4ad0e3a92c1032c45972d595c134fdbf328cb7adb18355a2b4d9511d3dab8d3bc390d26bb4457022e64875d93a8bef9627c4899246214b47c6a389a51d38f5ef51f8716b97d76e4f9a3cc1f33f910318070bc9ca9230e7acb6c5ef841afd88a5183019ebe5767fee15338cb59acbf8d18766c5d2973dabf1f9076b9a856abc67405f90bb88cf18a17ae3d83d26635303ee39606cf531d65eb07d5361f27f3d7c92f0c4f1230f34f7eb4b7b4a52b0b21b3ce63083df1fad9344095b7b1d0cc2ff7681be9c40135eaed51d424d915a6cadc26cdf602dd16cda2045f6af439cefd7a9085ba60a6cab3e0d7df01b7e490200a9a39b47ce56e996594e00ad874236324671c4b8b6a7ae27b255ec7dc09e37d6bfbf2abfc0d3255bccebdfaa0205118a9a6c25c64e21dd89421d5c29171a3a38f833699b0b63567a57c85a4420443611c59a7b6fbe5f82485930cd96ee8910ff226fea22cda583f44e1c00345815ea5e76298f0c7b596234ee15581ecc8a1e76285d82807abab89be805db63dc838ef070df1545d2b0ad431d0b849c71a826e8bc2b262e8dd25b1fdc7504a4b50336d34ccc4684f59e2f440f86c80dd7adaec5d95166893f8b8abd3bf06f4796a8945684033388db661e6d10384d4a2f9503529bdf59cef04b628ddcee28b7e928356e2327d5661d5023392e915ae3b18324591bbc208322c0362a9a58af52348276fdc5373a77a8b62bf9d4e1d01ba6a5089bd01c21eb703433bd944a2fc8fe39a5258ad1d2222fc52af17e3e9ab44f1bf0beded402541fd581ad4070ee9f7098d2c750eee5cb7beaec21c2ebea49c1ff16e108eb158dd72cf2f51a57c763b90f8c6c9b225d47b3656af71d6d8a2c064b0c63fc4c099a7f43a3404fdc1342e9879ef4c5c67f3af3d756f362a9a82873da8c22ec4d12a97d77e767bb22c9d59539f5cabcbfacb0f986136d77997d6d9ce8bf1bcbaf7b118b41abbf9ce0306a5a60b4fcf14b45e9de463a7fbca76ccd75c722371642c6b8dd9df1b31930b2b1a83c642a85a9553c8594e615bdf755ef4788cdfa5524ce219003a0a881b64e52b38f5c9a5312d29735062432d72670d6538649244b86fa33edb4ecaccefb129371c781f020f72caf14611ced53e96509aad8de4c2f2899dc2a14940da813f25415a34c4680d05c943877cbcec008e4a051fb99a287e4e935d3c3a456ede172497ae73df66910936399ab0bb1c45ff37b47b0e180eb53755babbe1f6b053e95b55e7c0f987d2ae7a924a8a5827bd3f3220ece463345c9b29d8281eba2fd06ba7bff11ad0b38a072b2d6b862a11f26c19f68f6741b5942ed1ec769a72ddf3eeb8fe48ec57b1ebfe167b9561a1b66843eb8f41dd87fdf9571397726c7e6c61591e5246d4b90644c099ebf4f9a509f255b573c7223e3e4cef99c16b7d4d6f34753886af2549b19976b0ceebaf3034ec9ff61aa1c6a30184432ad1d65961841934f10a52026887bc65b31f3cda6917838d61bee77dfdcf03ddb6e741f94e13e412ba97419fd7f565efaf681d5040525fa2e698a6a666b605d868c13fe674939d874340baa03c017f4486b349a7af5a16bd7612f958f15ea3686d3bdaba1e61d39277b4bdfe9512b9d15e2db36e263ff18362a6f5292f9f592740d3b64feb35c8ce3c27164514bfa235f808dd7f59605671ee85553acb54eea290891884c9ab53dc313ef7654b54f9c1a2bcf6d7fd8be5e530234cb591e32098a4cdcab9263308d3fd7847825b709349e9a080945fc0e13faef356d09934ca659523664a455cd000000000000000000f25a80300000000b3fedfea286389db922979700ad24edfb7b9612bc06facf199bc25ab330f2e8ac23f247e182b8762e33b11b204724c1802ab7dbada7765b5c32e295709a58f8ab73ca0af9cdef5f083c33b2a00eacf92afee351b9bcae800e7d7637cbab7193200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d8b21b69f3a61dd8f0654ab29564056a11940feb3351bb9c2bc384e22caa0d9f7a95a7647fefadce3a1cf31e8ff68dfb46bf1b4a2bea3d3e3aefa10289ed3571f18984fff30b1ccf35d6ab8402206a5a647fb4c68866d85c32602e442c7019ad35309b138a847bc794cd758497ed0cd4405bbc7ec916eedbd57c70c5a30bfc000300aa55e6127764c562524b81bc99dbf7922df082ae004f114b3df37ea16046fc031dc98766cf29aff8fa4ffe9737cd104dbe2ed212e7a5105e8f3f18584cbff2a20b01276f8b57a8ba9fd5d8a883ec588e8a05bf5c9c07b74eafeca93ad69d198c508ce40884214a2014934d5a3367026a560e982865fd966836d90fff725e11b1f80215466946d2204f3c4a76e5178e5269e14fb2ea11ed1bb1184f35e623bbcfe91903009093e9ea5673ca444beffd68dca8a1d5270852734d770dc77a41e35ccaf23c021e64e0aeedc2eaeee798e34b92346a627904bd2dfa526dffb53f77309f3da6d103014a67f974a694c0486bd2119df6312b93d25e8ff5fabfc1d3dcffcfa7ebba3302224ab2fc18f968d522e05a1969699ccec618e78e9907a5cf18f1fdea706be2f70c315c66e2484b1edc70960366cafb3390e750976186ccfc79d3493b57364cc3ae0a4a09d10c97c3dd6d1af342473ef011904aee467b65b61f72f2bb3f34d99db2d677c2764bf063d0ba3dd00c6b1cc0b521a14f28ccda6cd22d4bd146f95d61cb997042d25d19c012c4bb5235e1bfd249099e4d3a6fcdd6ebc32db8acf44099fd28cc1560f165e2d952a01e2f4c12e5689ea70276d9315ec683f72f5faaae8c3cee6a18d674f63600d810d7ab52ea7f578485b14e88c5666bc5e4ccb8cd6aa34c21787f4703e7e485698cd39e6ab07d3e2fe926d40bab502217eec1991580dd58914c205f667560a5eda86724ed87a53e716a1d4a9e56bcce8019f405992e0bd7033bde5d4851726f77be9456f76b74720e7c59c958a4228bd577b5ccfdeaa29103a9074e690b70be1eb7350b1f97089300924370f5f18eef4b58552f49d49a40695c106cb30803aa32b66207a745c388a8f2963f12323b00d5a27dc3cbff9c9a9fae49aafb9479b87d845a889705b8944d28aca4f8550ecb5efabb6b08771566bcf73be4089b469e9aea15c88351be013605ff650d4b0caf100ed47e7f205fb84b82baed577c429453eb6a2fe1d9562bf4bb8f85dc670e9baa9105681ca38ca61d8d84b25f9b28bb4406947b0c55b93a6bcdbd857eeef774f1faa8f6a21dbaa396c3b3f654c4995a6ce7875cac62e6ab898470a9434b7396b2865c06a8ffb303e86a18dddc98dffa5e459221d9fb49ade4be4507c5ecd3df0f9b523380ea9c4f06337fa56b120d192942ad6dfa1cd587b70919b9a114963a82e9b2a0db86674ca10d904edfb7735d16da72f49db1b3f7c1f0bf2d516379193c54024a7255c96605e2bde9c9c1ec93fe72408d264e82e73a143632d8337966e519014b6fcaf4f9402d1d8b0292968bcb52a2f63dab964f2b0ecf7bfdd8c04fb429ca3b31abdbefd2e4998fc0e62be117b3803e393ecc8a0b9192a0739cda7331a4c2550abb093f2a66f38cc89f4f28bb7c48992ed7d343517abcf53d2d825fecfd80ccc44e70b2fbcfa092ccf8bf13a4febd41d4483783ff6e44d42a2670eb777ab4f8026ef02c494d3f5f46b181659104b027426275638d3d51aa90704008eb649035dbc654d5421288e790b06fc9c3e62c14112ad5d1f506f8fe7fc7b80e9f132812eeb66480a0417483012a82a9eebb8f221183208bbd3a0b3292816deff3b9a5ec743a575d7a4e2942b0bcddc2dcd842ccc9b8d056f347d9f984d87a3a5c100b1ce920ad0759c3ae18979c669464dcc730455c2171827519124e59fdfcd194ba0b98461d62e875a5927157689438191b8e06b8cdff48c87c128d2315183c20ace5023853bc22f0dce096ff08ce88edd8d78f4015c8683f671124b7250c29559b8f7640d768df676bea5c36e0ea3335faef1ec31389cd92b86c76b2b11f8e04be8eb8094b493460765359cd4ae406790d9a683255fc17d6d0bcb1567a77cc720a89ed4673b3fe062f753cd199e0e9a151b89a02e4efe488df6115304fb86f4b98f96edbe4fa9be99eb210145858a3de0f6b098cc3b4e83d4d32f29c0d630146718955c09f0606044fd4af63cf1e710a2d5bcc38423b1ee3277105b3f5a1b4e6973c6c54e2cbe57b06572ce9cc16050ccd61d4c7a6dd17944870a790955699fa7dff1a9dab0f2666d4355e36418811077ed58b277df331197985ada234496e7718407f6182481b04514b96af42032bd616ec771622fd9aa736151aadbf31a60894bb6360ad032d068507d5c3f89294d5a971a55e32e1a849de48f30d6976c5da8878c0340cd64a381e75c654da92d8ada1329769c6860d", "52525363005200", 3, 1997281448, 1537743641, "edbea03fc1e415baafe8cd3a8a7064066e1ae1f873100b3bed5bf0574fbd9172"], + ["030000807082c40303b1289c44d309d8a31db47e3491e5ffdb62817180d684d7a94e213fe2b6d0c437000000000851ac65ac00ac5300ffffffff5ff6a9c53f57ffcfe2a08eba7ac1c687d2189ea728fd95bbd333789bb755a06c02000000046353acac7fd25c34cd127d41936d8bc146d495ee7a7d3e0f63ada3373539f25b860fe65575c19a4d020000000800acac6aac525351ffffffff03511ecb050000000000cc52260100000000004c0d7002000000000853636a6363516a00000000007953db28010000000000000000f6ad7500000000008129fd51040ae7fb6a8e3ce32cdc3a8c7ac0c17443b7ca434397e6995c127fc961390a08214709cb48ac838d0b2c9688e9db3830c2e287f1639a02fa045321d461857d6e17770f88953ee3daa946e11d5d609a14338ac63029d229d40492a7ae000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d736d4926c1d552f3a110c70ba19ee5683004d1cafd3db61046dbdc975dba7aafba7eeb5553a2e54757c8051394b51374fa09fdee4d8b7a56f4d9f922385b18b50e411cea57ef85273c93eda71930ef004a330d9cc9df5e75764d32ebbad9514b8dab0a9738078fb575154e80e74cc151c75f98d97ee5bfa32b74fe2ff28b2b02300085c4e5187e1dbb38ebe0c17dd97978b9d67cea57696b3c7e5fe26691dfee020907acbf609827fc732ab62c8c4333e5f07c559caffab0ead3ea99c8fc5919240a082c19dcb81dd215c453a28f74ea77adca2dc203887c1af6f63724979f09bef35a858da4eb026e639d1021aaec43ccd5c90a7e36e2e125dfca88c1c1c6ee653102256898d00ff2f9978f81a37bab54587791ea8c739f5355f0cf3e42b75cd8a01c02018f0eec96b7909f60fcab40e6fbae71a958746f00ae74c08519d8aac8482f87022a5fa836991084fa451284e50120c0e7c0353770d786961c3083e1ffe63b5ab50228e90834d9c4827f29564a33fe6a20a4e2daab6f54fa9cbf84763395342c4070022a7b37ca6d79cc3165e66eb77438cf8ded51024b1944f2f799df5888403c9397caaa6f4db823b9e29809cce99b6c94b41a3a63f9e2b0de93bfe8b6dced556c078ac1f8490c41dfdccec0b5aa2687f3fedc1161842fc9394c3e5f1887f796228d5e2efdd4f8c7ec4118f23184ccc173214cc4baa18661c8b8b59e0ef0c1020840a696b1a14b601d9c0401ad17aa6095b2855b9686b961659e6cdaa0235025f324369c0cfb40d58c5d6913e3456557060fbffb5afa39689aa7965eb528ba794b5840aacc3287de34d0c01ed05bf8dd5942fb11bf9e6b9c931c5836a586115a5bfb9c4798ef645bda951b02f5e7b000115ac7dadd1c7a3fbd5cbe596485eda03b21bf384ad482642697762a5e60cd5548e2e1214d32b2e663b683a2eb651da98615e15a3342ccbd5810414796e941d41fec2ade7be7700e9401bcf4ba9efe6e91f5c48774193e2b3ae0375b5e62729ab26ab1fa2febccaeb101b0a722b334a2c54f01df7cca0262f6a88e772262a7f443ac60f416495665db7de1095a550ae7c1119a1764cea373b80af830bc761979bd316dc4b0c638e9348e31acc582ae2478775b25a2d1d7c395cfdcaa5dc2d0d4d27aee8262501889b168681b80bc39d442b52f335b1355e1fcf9a2f6e7e6fd3ce738fcbf6263f2505ead17261ee17d12d135bdcad9be1716955316c098377c2b1264acf510cd7cd5b0efcb2db40685491d65f6cd008f609740806dee733b8d4efe6a8674bc06716d1b907bffb1d90cd3582dc6e2e1c0ce7a8915593a382aa0669f9702250158aad77a43b160eadae4b86d218714a3033bcb2e535311bcd29b99546e871a2d64381d13c98a55099e5b8f22e8614c74944a0dbe46a9693b65779c7ed608836a63de3a503e60904a851851284fd262b751ea22f38355c3a2060de608b14c9742986f26d7c159a4fe0d44e3b8f11c96fa2375bd6ed52d9d3a1a738bea7dd36dca90c37272733b9144d9e1e041cc5e1d45dbb7a4240c0b4d76778076797fa861cb71f18060144553da2d0dbf3a0017ded4115ddf324876d18a31ec7fdaec805d11df5d5e523cfc4f3401c12e8cdd517f128b83cba7d79edc7533cb0572710cd450db155a950bfc2c08189f3efdaeac32e1737e10acefbe82266507f436c6c8bc89cb79095599e0987e744935844fb858efcb2813f5b5f3b5be03d75a94aae7791ca95cd51d4bad40ec4ada4e212c76e8e9a6f4dfbf63b2a6d715ac8cc3420af06b6a3efa85f0cb66e3c2ea82ca49ffc42ae1b9317f8d16726c5f125a3fcf01b8e7b6059fab4c16b7d08cbd4891f0eb6d6d1f386cec73a801be41de5715b1aadb582602e1a3d7c2d2ed61dd8337bd6a7947d84b756d4a1f342f16d4da7e06d549fc04417d4fc6a507895075e4bd32e76476a73691e8bf7717a93b0a7335c67461214e3e7cd2cc2fe7d880dfba35c586549568eaf08d584a368644aab8c56904d26d663731d88a29ea77e067387bb2a9e49632b74d29f770ab4a29b71e11e11cc87e8ebca4589893551e06e5a1d5e65df4f6a899536957afae85d853f0ffca4cf9937c156cd357f14c30be7e67938d985c1612212549861e4bb66819e94177874ea4ffa6387f2ef8ffaa3ad43cd6645f625c4dd99d4b99821fd5725de0aeac499682356a13040be2199e8f40923357363d8ad321e9a7ca366304b95e36f053162272fdbea787658afa6c0532cb71fbb7134080496c10aeae4aeaa440c32e6c90662fc76f367e1657eb15e0ed59efa2948fc03ba5dc909e1de132a1f92f013a8624f93ea161b8b2336ff891209d466e6208331dfff44c29f93270dbcfde29da5f3bf2e6c92155961ad32a7e3688a3449944da6021604c0d1fc5c13813a563903d0f", "6a51656a00ac", 2, -407502766, 0, "3d25e7a73dadb321b621aac4d41ea3a8cf7a4f52c74227a62c5b9336420526be"], + ["030000807082c40303f1fd691987043ac1067f92c7b029519aad8f689cf8ac03e2ff38026cd824dbd7000000000553000052acffffffffae1ea23993888567f03b653185919a1efced3d4bea047f185fed38dc7bf2747801000000056a53acac632df04c43ca0f96f96f692632cfb9c00934557b9b5734c00344b849d0b32b3b74d87125f4020000000300516affffffff0158257003000000000851636551ac6552519f0b7c0b000000000100000000000000009837410500000000e66ebb1d01c96770feecb1aa8382dadfd4dfc725c52fcedabfd74acd8f48a33105e6040e64ffc017ca2b192e767b965c0bf0287179fc6a8bd1ba6ca266a698272aff7ad092cb0373d604c00abc356157cfe5957090c26b4801a7a9ac7669616d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fba79d09131c6cf6e4fc1b4b8cd68b6cd8993f9ede9ea37e94533c5d1e283e61a44d57e59d0f8242eb294c39a7a1a384163b51464fbf0f54a3b485d238959ffafedba2960cf22fe3f8e47783b99658e0b8cd00b05c3d5005e34f2455d8777d9178b329d6a6b31f75a593f99e426b62e29edf95646f158cb5f20ccf3d1fca6b210200257f31face31de5124d1d964d08bbfdefc752e1ce6e09999759eb1e1c425bc031ba0297c66ae298b4647c6504c1b758e29478cc5a9b0512f0d39dfa5fd58880c0a038f38243c5828a73e77f9ba3f3f20b3c226b7bf986bf992ee3651edef449c6a2e1529fecb1ae95b2050ebf8a60448a299b0909d584156c9b5e0416ad1f2070b0301c420cc5468ad86d721b652f488cbecf713d190b50458d44ff04ee4729f08950321a6bf266b576a082a3bcb5a9d428ef79618bf3ed37945c35b8cf0633451edef0325cfbe2063bd8081d3f9af04c4a43471239eaa7dfaac58aecf2b987560fc9acc032edfa3995d3a7786bdcd00cb65b7f327c94b34ae996e9bf7b597e2585027ba7e02211572f67760d3b3ffff9cb1e803b93f5ec050d4dea2f8849300dd289ef920cebcde5aa4daa84de13f262572916dfeae7e1c5140c8d532b0348c580185462173d5c6710afc6795faada88ce6e730aa084b38d0d35aec5ee5edf35e5553ca861d88d0531b6f69b9314a9792f7869022adf502c6673f2f7c575baf92f858fc3efee118ff23f49b7c47f6cd44bf872012ed3a4b8b750fa09cfac7f48233e78540a9ea929b4f036a353592a7e71947fc9b36d870006da9f395547d0d04f334b84a7c1fd7131928ec4a9a297c182f7f67a44cf9f7e1a089f7a475f663b06ed49b600920ee925cd101dcc6aaa8d28388bf461d98ebda245884e5a563fd440ad88b13fc4e62a51a24776193e2b944a9ec4d1ff88581579726554ff8e9b49520ceafe3e6726d7bbea3298fe1b93ba92022a82f7fad3dc4ae2795a920a6d676216a91a842a51fc16a5d1ae92e0d289e6c0d4db8974f8338b2982214926ae1820b72dbbcd184bf9616e02a33079162cd3acfb80e19b9e5464a0c47573480e2b2356ef829a81a38016197a118aa3615faf8d4725ed9e7039896d47a25fd9072e28a40a3c79698ce7aba7c2c8b48e8c803cfe70f307b190656039661ff4800cb2d6cd74243c04b42e2d8a94f305873bae5bb2fa351a9ed98577bdc249d9441ede0222b2ca34f2139fabecc3f84ccdbfe4c5cfdff9ea09b6ad1b732836a300ee2fb32c3b74357e321b8d166dd5d75d2d5893c0f07b19840a2580e322c3600f78f6303e31877958f2fc8767759ee80221ca5ee28859441efff056de197a36b3a1b95fe97167554f704e47d652e3d235a1c6038f2aff73f4f09de7352a6c990ee9e48c07f8386e538d5bb53a2e36f650c45e67da68a47d140d25d4ace10b0659e2b58a87bb9f22ca157f2b0e04a2c8d9db1ab3dd063228eaab5a17fbd6aeaec4b7a309754bb3e6d1a6c1029e6707344fc43c0f7c6ed1f39986fdf2c738267aa8edd16b216e62e8160bb9047efc524e856d63fd9d0acef2ec7d3ac3456c7a285add9a410f7fe7f132fb1d1bf2c34175fab375c16643af1c02e8e499f149456721c15167803b06c8d134c0784ee798ebff83dac102dfa0786f4be8dc3ae439f6d51bb744eba447298266ccfcbc9ba5c97184fb8ea6820f48ff91d0c59124155f8e1c01f2b7c8412cb8c602a19fa135e61741e0a671ef76977a8a03e3d7631977e566a7468acefda7f498de5a12fa39177d284fd383d4d656245729131e3cfd8ee44d1f93cd2bbc3f6fe4ec849952acad8028eb19a6bdbbf31e53d0c1ae66a40f69d6c94ba964a78e7f4c5cd2ed04fb37b33df923d6837d55ef741091034c7a1680adf37658382d5658df531222c92093a078ab2f1d5d07f71668140773a98ffdda40d08d08099886fa3ce93b35523894fad6cbcbc4ab2120154410b91cbb00487e8d8b95017a07c078614bae9f235897ed9d22851d301c5d6bb4d6b50f6fce9e6c752ca4ea72e36e06f1b004828bf7c42831a1c963f4cd4caca8b08200e609be1c58db846b85b61d6abf4746bde8ba040b490ba4f1176ce7189cb5133a33cca4ccec80a88ec5b7795be0f12bed344f1949bfbd299ac580b4aa150de155d081402be2c8b3ff67b2a1c804f44c7e0fecdeb137a2a39007d2b0001e10c64764afc2dabb3e47db6afdb4c7415bc8c73a447c5eae0dfc013bfb7d9f584bbd17e8fc4aa73f8b5a07b1d606540ec487d581e41d02ff6e71166552ea010fe7f3c53ee23aeb5d20957829497dca209153c5827c53f664117dbcccf6b74cc5225aacc241b72677e0681eed7ae643103129dbf1e93e913e861d7ae43c349bf199152bef0f0b78e52adf23c130c53d3003051aa32c1d0a9d76ba54f282199dd07", "ac636365ac636352", 2, -1366046387, 0, "de558e02c9d5aa15aca7ef033db48d75ed363cfbcf140bf079be804f82ddeb81"], + ["e62b8e7c0404dc6ccd6e472322b3e5456ce95cc0d5036f64828ec12b0418d7596e3201368e02000000046a6a52acffffffff131ea6f6a2f0b70ce2e7385d80bdfeb1d66b0d9641ace852c898be4fee0023980200000003516551ffffffffb55e99aa607f752359d99bfad854214896ce82290f49e67c143b045bcf3aa66f00000000056a525251535a8782e059757f754fdbd858600a0c39992736742f51afb59dcf350dd0866ba72e65d2630100000007526563536551acb5dd8b100135acb205000000000851635365526a00ac0000000003000000000000000076b9eb0000000000e5351f6136f1d26d91b8c875e1697716770769082ac6d4ad941c06475777878993082ac91dedbd1089a60ef711334e39f28b6b77715becc7e111f40f056ebbd5d48c2c8502edd6784c1ddfa1e455752a0bb3f7545dd7b944932e4f46ea3c20b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000032e34af2161d8f134b51ee041ff1c3feae2fa15d188ed45b6443695c85bcd80d0aa2698fd2695daf9182fbd99ac2afdf26347ee8ad92bef6ce136cb4252286aa543efddab2c5a1988ed566fd5b22d79a80f4264e9f0fdc9951f14ac7e63cb901abe5e52cd29d88257588ce8093faba3b39235a8e098ef7865b67e0760e046a20032bfcfc762471e90f1c84d1ec8f43bd6c9c295badcf4b4abd6c2ead376cff77930200af33aaaec1f7a5e13a0427884b891b46124e3dc082afb61cddcc12b807d3c60a03d286dba1cdaac3266914f56f23a43568f33cf2833c9e0a9cdc3153fec679f9b2da37863cd9c2db8cb6c83c6b8d76c1c259a99a7b5a3b2662462c50ad85291d020957c95f41f7862627650f5c34d51e142062a9915f045489a1306b2b31567a330311e534c56cb0454ba81c3181ed242ef188d648e01f829af4517d02900afa1409021d5936ad9701974c6f212520eb1c256bfb245644f46a56a8f2fcce3c2e86cef703064dd4720268e2d12fa6d0a20ff23d0360bc0c9415b96ac3de92eb2d3cef849c021596ba19c5b683bb49f98ce0fe0ee56ee79eca5824f1f8b0265c2a730865abd9a310e9958a2d8e1bd3189ce0cdf655f6c2ee6d50c6489143c92e866869b850d9970ba6f2c9cda5d44d9b4a5361d88be2401fa1d6b8822960af7bdf0dba67ea198bc6e30641605bf654ebcdbd2a9daf6d1d66034fd78b2e596dff55ebca318e26b56e37ab05c2d6e8d76ae75c7efe1805bc9be3cd8adef6faa2cf98b39225710cb2b37bbc5c0e2f7ae36091ab4fee06231388f4ee7840f2dfe79aa6737d2764953acb098f499ee51ac26fae9f2628d20b0228a65ca40655b2191854333922846c71e206a58df93935e430013f96fde8747506a1781fe3bb1833f214943ac7b3c2ff87294e20d5665ed01844446c62ddd0457e3c701898a3652cf06b1a210f613b69b7cdff3e12cc476ee4906282597eb767dcd6169dba312ffe351953dcd3dc4acc29ef4a8bc4bb275c430772d7513b8ab7762d1d250043a017b2319231c85c38553fd82ade74f89fb332d3f377d10114474edbcc5fee77689bfb2dcf7d164b2022cd37a86010690c858e17e7344e189656227b01b6f00b593b248afd0edc4c55836ed59cc000172fa490c4d0ab99e823d4c48092d6cb6c08a7ee8d192b5de653a35bd48ce220a9b0fd655f148dfb0cc1c436d552ff6b3b95576536a1e4b29a8bb6fc8a0a6cbba70dba5b9783fd72e1b0c879335b8787dd1138cf257f70c196972e44f6cd5e48dddfa316d9c48dd2a039d2828579bdb23171f5fe28d5da294bc1869f38dac30cc2e2937c82a0a47686a95e58d2a50a432841feee2bad454147e378163a12a5e490ef6801286759987419c490c0a06394896c24ddbf3588a7557985946f37e48ceed7976c4d3b0d860baa20a5b40e071b174f1b25423a19025ba9631429b566810aebaafdcf3832e6c5538751c164c031efa75a1f144b59278282c674316fdaaa3a1157b120e3c52ec310ead28e6c89b4f5573b84fba6f9a15a8465df90d8af08054658d037b99fff5397f80a2c206873512c3a2913b7791b3c6a3353fd68bbbdfa56a1f11294988415e01090e4fd4e5cf0ff13f0503811fa57e283197c0166c3c28d7dc38284822837800cc353a1f858f82066c13b6cb30ddb732517e04729ea5cf3160de7f89e2dd3b7c309269d1864faef6dea213a19465962efe4d2923a5b31c112778415cd9839219db6e193807af7e0885e374f4520a728b1ba8eaaf6282ba3feb595b4a155818c8d1d1651dc374454c17e221b5684adf19b58dd31050ada81e125936d952a34c47b9595af43cf5d140403ec8d7fea86a3e4b81787ccfb5b28ee91cc5db85c62735ad26b73d46f82eaa63b74313e294bb452b22acdbc4da4cd44e58300b14af07c6aefecdc8b7e253ef18a88223b92b02a147641a1371091a021b9715dd43bcfc4af132456177864ad877fa368cb4b88945afb22c6bdd38f93065d3ea7ff083e4f9d30d7b9c75d33681aee4c0f2a4dde72a5d102cf6fb3ee70726f15827a2ae5acc2eebbd85d1a56fa9171fcb8fca9b1aac7da643282868b57f323ecd990fd01cd5e4b2c9e49549a241699aa53e4b6299e1754113cf0364dc6877cf16648ef7ef952c010db0be4fe6cfc61c7639abe7c990c8cda6dd9f6ccc96e2e292185471b3894b0cd76a5472eeb5161de04791d88f50788dd40ede308f4d3d1c60bcc055393426ecdd0636e1fc5ac2216e78ce908c371bde02221b8512408e093f14abca961a1f40000000000000000520eb70200000000b0e9322ffffe4cd5bb69c06432fe84b16d6d310b714273a0589242a996d8fda771594a222cde61ebc8f8a7135d7313fdf1ac6f4b1d60214104d18430bf7c861224c2d58387da540726a3ce82aa28310feb9d260f7c9f3e72924eec66642bae56000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a187e274c65e8c71927e74f45fc163b582df56cc84faa66fc1cb162c6455e6689d16d6ddcb7c172475849d8fb9785c289cb2677718d6f07efe0af0594f18b1a0b7e142db972c1c9b87b21902ceeedc2127bbbcfd3ca9cadce074365b08eeea6c010402b98a2274386db8d5d06d62ba05921fe1770c6f448e7e8dbb4b4c66344021e208bf9dbe008878e4c561b81ec833b0c7fea8ede95a68b1d9206fea128933b021280dc32fb7a62cdd12e99612b6b38838180f3803b779c8cd602060931addbfe0a002136ab428e891d6318ba2e1fe5454096c2f2cc55072528e5421b0c5b539ade649fb5a6fa104fa5e7f91d02c0574ab32ea5b658431313ce4843b78797797cb203300bccd912c74d24201b50ba13444786eb8b481d5e963225f17dea9301424add031f6d54a62dede0f33b4794f83a8700a0f44f5072a8045a81449ef98606f19d0102255c795df750bbcb2e109701ab38acad5b6b93b8d3de56a9e609a44de93317710222d805255c0dc56c8ac573f874b2813708266d599d9f532f3f0107e00b71894f0208d3e2ef6f3cd3fda75d6ecbcfe698b7f2ba4b0bdc2cab37c89751f9a9d1bc2bcbec9e598b031701c2a4fe5b2d7730cdf035e5314e358334876448cdede4f089bf1979257ebe5a46bdd54878f2524ab4ca72080057a901ed4d726e379ef7f6071750d2eaefa8fded5dc8d208392bf0be1a9a7a98f08cdc5c3f505f8b0770cb467d13133e370c1096de923d3b52310c3fe9b29ac525a20d76040567cd0523dcbd9805f498fd292c189d2069fd3f0680fbde688b33a1adcce76e117cb87799f4add55486ec9c008577f2f20d6f481f298f92b24e352cbc1f764115817b5a11d2aa52b0c60c20fa3c86714798b8633505490bc938098391b800bc322b1ae78fba3e74ee66d4a0fa4b280b3f16084226277788f5a2db5485868cb8458450470967e606f428bd7127ec8b87752421b7578a680dd01d2e53ce3b2a7e8df8d84868d406cd006ffdeac1809c5842427317c5958220d152559da0beb5e3f71c97e448c4baaebfa2ce0f6e11a3997d8d6341c7268e97f3071b4239377fe1c4479045b59bb6076912e021e4ac14777e607b6171805800aa876118eaf7e0f6d820f0108392e0ef8eb416b80566e51e2e2cfde798aea6ddfe6b3cd57ae09bc3eb01e9b0766c37f31b1fbb86dc7d8ed47aa92c0db17b462189599e517a9d690e39567e9aa110d7bad12e02ddd410b91b475ecb4af65c32e592ff128ce52790b9f4b624f025bd36d12d7b6728f05ec94aa31a2c5d4a2739dfe5b7aa4c0ad0b416743ad2cf7682e92b7a905419007ce7038688942d8967d496e8ae641350b5f6c9c876768ff56683bb708bd0b203f5a093b70c285833d99624ae846247e223fe5b461fad77632e01a89ce7d2fb42f7e2a8f0622df5249b35762fa77c3add3cc540b1fafbfde0afcd78a0914701fb06b79b8c922fdd2c1f117c53d902cdb5de0b85c047bf28b16e9f1b244d21e09c57587e01acc2111d9d3bf16139be82f667e8f58b6ddac45e5a082d3d0588b20c9612a525a5fb68f9db9370f15562a35eea571fee1c7b453ecce4f9cb66a97c13e5f224abc10efa748362ff8f6ea0cd304bcca186b1db3ebb12ad22477522e92539bb504587f59d6103514b84302af382a71eeafef56f4a74403fb6c4f751ae6a4df7116ab59dacee9cd7e2166a51bf320a673b73b3f3cc84a3ceb5ea92a95bae974650542cd97aa7257e88166fc94ae4769ba09848cb49e7e1598e23c35c689c23d4bf9f892c07fa3053652840a7c3840c29c613b3ba5d0ae1f3168f1e0017dd2716b1fc4f81c3fe176091f1314d90a0373991da199173060bd0fde4278109fb985ffc72eb6c06be35afaf3d55a5d7e7ab4aa4f676d8ef94f9d5846a7e1092551ca3b87b437a9a17e51d206e803be59b8f551147372eda4c4e41a2e681250429ca319baadf94c02924fa42f05ea5652648de3ba4bcdca6a1f69226e49c423b3323d2ab0867d46e1531e524aefab1ffae4488e10cd2728fab6b41bc4d9a3a7f263fe98b9dc272fabeea53032ee87d6e7105e433647aaff5bd4bf2e6428ad28e4980c407fb33885c476d5f80f034ce5f38f23ab363f5b166e995378b1d4c0dc19971cbf7ea8a07efee8ecf9b5ed1106723d94d9519f743f522849e942a08ccc577e3059d911eaddef50b434d7399c6c0f894cde1c220ef8fa004df8723d0fc6b1b4e208f15603180c4f8dd13e1c58d487345502848ff29eac3bc95620b7cb80a7c242c9de0512694c3c23239410000000000000000772f44020000000043fb0bfdefaeca067e9af9a8c633bc85ac2a6ada10269eafad949ed1573af737787cd2566aea366f9431074f2c5cade89e13ce19655a8a277ce71b0280206c4b19251296a71106ba8578cb794e339c8998559881eeb3af1aa841c381062daabe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054f26d9c3110b48f52cd2a1c9dc8dfbe79578a38c13e3da40c48bfb77bfcb9e6422a89cc2dfeeda9025e410a1f9be05b5eeeaadc09d427b28942a63770e4bc5541018b0c1f46673fff9c1b28a21c21d2251072558c88e4246a94a1a90cbd5eb8736fa39dc6accf01b5daecb5357d1d396d65b8fd8e10e652e0cf020d3864d4520215a9a880870f4a9b9eaa2a904216c40fd61bcd8cbfdb8600328010981690fe250220f54fffec22f648ff5fb507881d2f019db9fd33a7fb9059b51998f5cab4cde10b07c321e1b7bc691f828339100b5d2c4fcee44f5f9adca8adcc210830c2b541764f35a0483524bd59be939c41821570c8c9a23a86b7563050f896f79383c4a0ee02264d85da7672a9822e4468bbc7ca6ec33ab9d61337a58166867531cb89f95d200321145204df87d4724677f7799efbf2adaf6b589025fc2fa7de10f08369ffeb8b02178a157ec00633bb862d88ca0b406c8e3c3f3dd62359bbd2c4396256389a3006030b931a2fcceda17cf9b872e785205c3c73b21b584df1150a492669e5f7745faf02226fda5a6c9405661a1f51af6e81ddc4461129d6094667d14c2ebb2ec9e2eeee07f192bed1a73fb915da723e2d93c1856b9d907d264a9f181b5cca22deef8c45eb8cbd5cfd3036cccc117713258635458067e0c064729cd255a28b15f50d273bba34b505dd9380f2d26e746118c54c15793d5db2232f88bf1bfa79bd09b3156b3a1e53e6ae664407bf4fc2c4178db69191d2c8644894fd03546218e78b13e155140a30266556f15894546548a57f4f6da49b6790e788653c3c650a7110ae30c47b93bb3330bcfefc7b36eec33293a8957c70bb78237082a642be85f971323017dfc529996f4915603daa0bb92df1babe4fe243299eaadbdc8ec585b034e379d57a77264a422bf3b0cd8de83eba65201c2df4179d763102168b7e44b49cd17ca14f1263feadaf6890f2c7f203faed700a5849a429067ba400d0c8b66ab6032e7597897deeb6f3d1625a0617e7db40c8535a59a8f56d7b09c6fdcbba1401c46ed3c453740edde6bf5e14565e2e770945c555302ee63094e0616f206bb6d072724d1481cdade766347bda9d5fc8bf71e69d3061ed8688c1bfee1401dc8e6270117e7df40f9be77ff20de1d72cd294e2497655db0b88c3a9d1c60222c76c61463e85a57c807ee48868c112406ac0abc0162f4934130947f2c5428e2d3004ac866e96cacf65a6792b1f4449eb2e9aa1dd18cf8935e1eb9ec92546d3130c4f29e769e3eafc81ebebd68d27642a83139ab73f3c47c5833068e03ef806bc4294ca3c0752674cc9c8bc024ddc5f75ee7526512be2b4ff85db43010e6d49a8805ce7d641bd59457f0727af237983cd15bcf5e0c5eaf202faf2352aee0ac2d4a40374e7dce693036c33d0e963a7a4e1ae5fda4f02bfa8e86629c05e82c4cd4793c57222d032b3aadc5e0de233d47acf601a45f23c7d720a4643291510006415855d8b6e39b2140987f295ebcda7952478e4a6beb1161d7047665a1f373521c2335d765d4fafb54f4e24714fa764c1bec8e94991126396ddb14364cf2ff98b2852840426d308ede9d7367869457ad2cf34d14984d8b8b6ecb9ab9c7e44a1f750b9599110e957d9c12eafd97654a8ce29f500bd44c3f99bf233a5a2efce5a3c18feda5bbb412630b72e2cfd3fa6bfd4cf5c68c9597a8c2d0a0d6755ca564b80c81589bd32d5d079fcd05ab73a6c214d95da922e6ebd8fc966f39cc2e0850db2ea419436062d47f13cbc742eac25ef14124d9b9d18ab690900e22c2d298da78470642aad9b94475ed868554f40aba11ebec0de4bc0cceda30a8853c441d98e7a89d0643783c23d2957d148b7cf012feff6fcbc1423b7829b2b28f10d87aeefd5416fca8bd96378e45a5cdf8404c155fa9d74e4177109ee2d70c2a53de81316ba5fe17bc9e0dfced2103edbefaa0bbe0e98bc64d1a4c211846cf83d2183cdcd24843b5a700c08daa2e5469462c8d85a626b68d8578c12c31fa00e43ad39f99f79fa1191b8639c066823ea476e1f8e0c7e431d7ed30de7c146fad7078c3e87f843ec2b6368df625cc8d0aa4c5a80b32aa89b2cef0b6ddda6ca7856059891df7bea7e9e681fb61a5268feafb5efbbaf43d57842cb79a41ac18e8a76ec1d39c6df11d0378ae37b439f99ae1e034f5bdc9b268fdcc5bf4a239d7d9d9c7899cf6a71abc202af34ba2d161103b38e6c6dd8cb0da96457f7012a1252c15f505010a2285c785835d8830939f3ae8fd449ed1d632864166a0c76d8ba3f2f4753ed6fb4ae3080042cdf4e656e8768a1bb99be9207fb876ec2bc749df07a0c850d15405d45ae126564e69ddbabcc722de2a19705939b7040a124b0b6bdbfe3b2c539314bc7e4a35ad7ecc53d35642da9fd92a05d754d7c935ed9281bf48907", "ac515352", 1, -365062026, 0, "c15b2aeb64e48ebe42498cf62ff9783d16ccccab42146e4e886e31371ebc5cbf"], + ["d002096b0432942d7d824c64c3ee63d550c0c398cce5efe3102cc0090ff5ad80f80590d2b401000000056a536a5351578ddf59769e626cd34412175248d22b62b1d537f3014a5aba56348dd1ec69a63024dca20100000008516365636aac6500fffffffff4e7ec7c8a3ed2e0a23f650551534f5859cd8407fd3c4e119e6c8c5e99ad904d0100000000fffffffff2b7116c643c74c396abbccc7701aabb64eb773b8ffa149860c860c5daec2b230100000000ffffffff01f224d7030000000001000d19857f020000000000000000ccfdf603000000009efb882415896d7b958749b5035dad73287608869f5bfb9f053c25248187880903ca566386b720c932d83b59c734946cb9cbc28d707553c7334e517eb89de5ae619e1fa198e277beb236296b4d19e2736d3955252415b57a04570949be5871af00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b2e7b6489d0eccb17ab67b4d26dac5a83661e2e5c009c3563a5cfb363eaf5d16114b702e6754f6b83495ab915a1b0bd27d977380e22710aba4eca799b6791028e83f929ad453ddb49b8ee78f0f4871635c5eb34190b76eddb8fc4ea8f7e6aba6ef8b9891a98134d5d4ac05af26bd5bbc5525be1e261f27bbaeb4706c66d457df021db715bb8e896c4d63274c154f97a25453601b030a2b7d70f9b761275f0ccfc8030d40d01a551aee797e27c15f6d5a26c2b01efb072d7cc9870f3b07a28a47d6be0b001dd79054301499b3fce9f2ead0543939b2060713a8cb804ee3731cb9e8eb181761dc4372cc603c99cb9ed506f4d02650d013aa90056a6dd91cbdef7bd2812d03218007ac2f9897f6462764bdddbb4a77ab3e9c87a0fed99a35ae4640a859a6ce03304cf08e0c7b8a9f03cf307037d1df2cc917746c12f4f3e14adfb0279cb3d3cf0324e7ecc3f3f80d3cb6c607290515927d329acdc9888bb09657a12dade2ea570a0223d7813a3848c32d461328d12e8c0eb79ca7d5a4197322a7b447c143d7626b7e0319c728580f1afc5912e1fc65ef97cd1bf94f516d157022743423ee1dcbf5a8ac04c363a31412179e36fad4bd16312380f18118aca76c81041efc7c2658aa50a0aa34cca1dbed7e1df1d97b4b47a6eea8bd1f81f5311ac0304d84e16c438e465f56091da6b3c4469257471b7970cc301f3d9fe3002790f00b9fcef2b3c7777c18bf58c2fb374c6b01695e9f1b2e27137a5da9101379af036e6522e246cfbe88eddce39d7ed983e617d117e9e29a60b5427896547a9c03c65d67d78241e6638c00ec371418588ac6459d64ad773e85ce09e527f57fb6a10fabca3455510282dd64bfe9fe2b168e3b8c663569301a2b17ec6591c50b2fc28c0f9ba6c3f24178ceef2fc2457476df46434b9e03b2e048c24b94898aaeca909f174dc5ce87f487e4d97b328aa785ab8c3def05b819ce18670d4be48ee544534efeefa6e7f57cdc5ff9f183633e520ec6a1d802512652cf85db9c1b182d562a5e08e066b0bf4a43e8bf29888cc4f9d6285a26a7e21376511d18de4b1b94108954594a44b134580c0ab0ddb88b2cc70f0b6505ee0cffb9ac8f570737b366250799325293c82d84066393cd072634d697c755d2e0efed7bdd303ba614344695f6f374694660489eda7842d6b51e20836bb356ae9d7716f342ba70e75b6407d4483da0380003486576638aa5adfcdd53269918b16c7f762822d98bff8b0fedd2a132d0d22c5851189110f5a13d355e21b9799746e398f696fcda2f9df1b9ed81cd966aded5d636cc40b7553d7e4a7457ba1181c2977d648df434be760b9fddab43171d3a7fe9381df1b71ba94899fa76fec99dad8278c9e9a0723a3a5bd95ed59b6bf2c3669347e8056e4f49b95b5b61c1160e71b65e7fad05d14e0b869c9ea016ece47615b48c9f456ee9446c99991f9bf0ca66c30913a7df6a38b448b69c7d3aeeebbe96ebfd050a0b7d570f59fd08b57b93d3e6b00cd125d0928d8d885a52df45b70383104bf264f5fca852f2ef14c5c05de3f380c38d38177df0c14fea416d8cc46cf5999f4ed9f2f7abfd1557e753d100930452e3847b839777bbc8f09ff7a334faaccc4dda56431b9d5ae1bffc22b318d06d7c86e3ab2becc1e1b653f97a07bf1ce54b6b161ec2e73951949f84f6cb5f87fb19044253c297c4347444e5fdb7cce616ac56ceb8b35a66e357e67206864403610d66be5702eef6ce31e80f4e111b1b8aabd76bb10068f9b3ac1caca13f2a41e318fad989344479eb27e8ed43f61fcb62e2f6658c390b5b3ea9271e03837405b4de1320a2137db62e0dd2bf236fbe4490cfc37ad5932707c7a44f51fabec01e1b1d4c0574ab7ffecd2ed0a3707e52c7dca6987bc4f6fe2f0cabc1ff397eb30f615494f148e9550fede88e950448a30ccdc0fce88bfb073d527626d91e55501c60fa5fb61decf785cf8d7a6f4ad346d195f9e868f9f27561f9b7bb7738ea9ffab97987a889facb1d720fccd786a28bb6f574348eed1cf4738805712c15259ca994cdb7a16386f3bf0f60040356c3f4202c9d5509eb43b6dfa41fbda227914c20579098acd4598c612319370ecd1fd75b1cf9365ac47944febb5c9014f0946de872a20c328a65a4cbef83f84ecc5a8c6cc95669c4e6a16546b8ac7fc50d31775bf89ed7033d9a5e6f1a9f8ce135bb7a906a29d62ce177613ed88c18ab4653b72e8b7aa0889077a61c77a67e67d86b9e8ce577bb43d73b4e5e30ee6914f1321c8ac78461ee8670c2abbf00000000000000001b9dc505000000003383fe4936add65db586adcfb7d52cb7a9883596c1518d21aa883c9991a3946ff556c96ac474da49682abaefb909c08752440c9bfb59ea44af0575618c576ae3dfde2673872e984d4c8e77345393c51cee14be84e3317faf0377e29e458899d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3be087cdc25090c4606370e8ba3ad93891ef3de797f0d816a17e4473d19e95ba87368b873310a57ee848a12ebf078fe32c71053188f91af5560869da6a35fff60e043d4cd51c5f1a6254c5234f419b19592fb9140febd43b4e85f28f00c42e5aa8fa1ce530b5b024712c713e7e6221b60d7d644ba4af51fec007f2ba1c2e4303003beca1897f7fe9c701a2d0c4eee7de4cbcfdc128d431e07453fba3dfc5b98503036f2da58a0b9e9b5ac5a454a61d0222aede0e885c662eb051495bf1cc0467f80b08f8d9dbd6daee03339c8489814b923204c2473ea0c0fb44bcd04516ab7273831836d88c826c8ab6d7d6cf04b19f4f7a65eaadb7180acd352547bfd7c231a43c0226ac6e2f2ba670c0a17eaa7b630023a07538be73a2536d038e4c9edba471e99c032e6bd1246335b55a331cbbe3612140ec991f69de8cdbf39329678d54dd770703020b3c40da222377c4668bf37e8a539e92ec847f7f9507544b45a59e70bfba16ef02108bcf3041d768f71f4d4271886c8cf715d12920919526a3804741abaa18757c0227e0aca1d7063f967115d4c86b6313b5c55b35ae39ea3f09d42426cabf4d17fabe95f9a18048dc01c5acfb47b443b149b632693c2b4a2ec783a36ae752389c04f3f6e73ef5ca16697c8af68ad5508fb34f1f946f21e293b9c6d12cbf5f7b052ce90bd50ba1f87b0b9ee5761f51debc63897f770fc45107cda4c840c9722e133202b220192f95831d7d4ed62f74fdbf41242bab1630640579e6bccedf66d30c0d5613e27d168ec19874d8d8ce387e73937153f10e1da9bc8fd63e34b6223509b98450ec8a03a92b3c2021a394d103b73d10e435663863ac69474314da39dbb399a6cc378aa5e05c434cb517c568465adec5d163edf2601e9200ac3b81548b5911448755012ec1b7be7682395de99c25b60cd763a8d0cfc4fca42d70c7257d5d24f7f3b374e83eeb4fe33a6dea204c38c4df624d5b7db694bba177b5b6a3b2bf034399e5e42ba160be39c9fd3a449da5b885ebf0a8b88620089b242bdbdf7a8062ed8acef88be34e6c10c27ef279a5bab0a28c215d15e3c782c2f9315cc825df3d7390bf7792b6b3bbf9cf38d69e232750bd849c329184644a1234da800d17c67a50bfcb2facdd1f2b57a7f46ab91a50aafc7e63b219f3926c2ca3e6f5343fbe805decc64f3c09229d1bf0726b41a2b45a9086986de375962f3159a3bf1279144929d468eae73948471bde32f4fb433ee9f619402ecaf79f4c08b1a31cf47fa0faedee6232ce0288ddc035b9ccb0636b880eec0eaff30c492928d44ae79076ad32745e20b36b30531af21597a97b14bfc2ba03a30f719c9ea6d7a2a0b437d4d5f1da1ff4eed9c03b6b4425605ff6a816abfc52b8408aae6873bbb5a37cffd8323dd70d95854fe88aac6c00133dd83e30e93fe53dae5c37be9b610b8eb79fab7811ce501f7c2aa98b935978a852598318f9dd070c3282344c094bf3d31fae63e8caf00972ca8d454477c50621651bcac829a73f5c119b924a4723852f2dd56f416a8d1daaf1b82f3f2be80e57e00dfca1b833336d9cec108880aa86950f64db4f365836e987c03a02d9fe2992c444e62674665459f48c53ea29efbdde2c7c2347758619acb504972f6e0aa088492b7cf1946c598115626ed2dde0a00b7996f47dd9956d1e42d7a4ec4af9049115f8a291ca0153afdd7db3cbfa959ccaab6c94add9e25d939afe8c877645e250f86f76db7db1cd161ee812f3d2b01b56142e388bd396fdc836d084d67099f94dddeff8de2d4e7558b6c1e9f0ebc8f91489770ec37a35222cb27a8f14b2446cbfd8347ffb5b9d611fc8095f6f11c4b690e0728979b7ba8099a507bf1063daa55dd8dd1498124f73210b563d3a87ffbbe0c03d888044e6e1c614ac8c6ce1a770a310cc75e4c57645e6bb7563f1cd443cb3505611522c7f0c2163a893443448571eb9c372b6e61d3d12753fc25d27aba802874834dd01ab9daf7b3d7d0a8409fefcc5f3602c33e62afc5b890b1a8c97d6fcb177e2f764928c29f211a660654a4822ef291d74b18a2751d3c04195a67401863b1ee1850bef3a274abb3fa0ba121f6d2f2ed9439724df9501e54353b29981d97c1cf27b18565023dccd7419a5c2e0ceab6fd14fd5e5ceab02f713f59e157e83c2250376f97e4908b6321a3e855ad65989f2befd26c6e25e0b58c94f5f6565cfc1f84cf907623291487c0cc27b97095e34971988ac97ba06a53dc7ea2c56d642d9c1a8e83eb44d05a198aeefbb10e6869701bc14340732b15fa98050eaf87b4a036d53d879d8351f87656409bad309ea7ee3456ecb5faee4f22178a8cd67d1b2a7d484bee4104fd72283b5239069699c27786dd8d6141ade54023daf94fdb5900152d43198240ae94bf31f99cba7f6bb88c40991f6ea07", "63", 1, -1375261697, 0, "73bbd86e93e8b460e755d75d498d2bcbb1be3a8e3c31a88c2b7ae957f6300d58"], + ["030000807082c403037aff6d71dde15341d836e5774ee53472e4c4a67108a1248b82bfd5494eb619c9020000000963acac6a5365636a515b3b090d89ca46961e88414a9fb6602a15baee21a7fd2c0f64ae82ff28797cba3678c3d10100000008ac006a6a52656300ffffffffdd6d21411e39e0501a83f770c7e77980f9f9b755be2afffc943d8a6369d4ddeb020000000663006a6a635162db15e90400c6380200000000055353005200e02162050000000009635300656553526a53614c7d04000000000851530051515265519e64cf050000000004516a6353d74ed7f0a08a83ee00", "006a65655153", 0, -1060634110, 0, "74cf48df48287c5cc8768bea00d38ae178ebfef92e272ae791f43c5e28488bf6"], + ["030000807082c403028ea66838d1c700b5bc786aab1bcb993250eda43856f27d9486b813f3d5dee76b0200000002536ab6bab7a76a26381075d5501b030473c0add66740bd30a41a7d42da916b193a08affd97040300000006636a51006a63d51d48f0029a7fe701000000000452635363df13ef000000000005530053516500000000aa1be45701593d63030000000000000000000000004575935a50bca74e2c951ea2dbbfec63d05be42edda804f8c1b130d80de8af116ddb4b3ea8b1e8865e8a2ab810c29b221f21e61f959693aa2b4355092a222ab2ba32ef8705f7450a574bf89b2376b268a746e497ed7a3fc2a0947356d4844a980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017b0b40ff714acbef95d2eddda0c4fbdff41cdfec2166400869cf543f9ffb04d2984ff97a7c3e705a76c7a95836045374591321e8b35f848644ab2dfa1c947e43623d340d2a2465c179f8f79cf96a5b090e3bbd6349ea299fed0f77c372a7aa4826700ae5300aa8f67f8d7922b75efdd8e564aee8923df19707acb7ec0cb350c021adf24d74e734dceaf19594b5268d5a82861dfb3955a27682f84496410dfa960031d886233c75c35255ea1bd748315445d6fc09ba7777d525a901f56f129d5da0a0b023552be7f42fbe66fd4282e23e569c303681b8c7572a4c2c97734de304889d85d2a6f4774cdd49c960efb9633cfd070d6806b4f92fa6124cb00f1b31a5ef9dc02219a7d73253b28da8e3e7724d94e35de39bab8e3a742c23b5ebb6bce7c2c460c032cb52b8a297f91fd3a39a86bba43c76821fd1a82f961e6b2eb25f4e0ae6050db021b1356f2e40b5665e53f093b87b1f18d7c61961353e707a740513560699fd53a0309bf60b8e07a485d4913438b74c175fc85be4bd5f08f3a75043578dd15483ffd030424a886b6debab0c9637e0ba272214bc507c5a6586feb572861158da478919a29605aa5f79882f040e385e8521270a90ae8c6cbba07fd63340b26a5a9d88ea225b21fbcf528bbe4f50aaa1fce94fa65292e08423e33f7682c57d259bd1ef281e6a83f6b138834094ad3b1bff2b9d8605d9a676a0f38ff968f4980e0eda22d403cc9e81c33979dcc6b378d771a94777afd02ec778eed5ae95d420f8e48913952ee6bb8d6bf4761a54e00f40e57547da7cb35b5b3ddb526a4a3a7d33a12fcd89fd4e486640c7ebf91c053cb036ffc62d424c8ccadb3e68fc4192a8041d44947cbd4cc4acddecd72c8e9f9882f12f1c932daa54d077562ce5c038a88d2251f01817a42b4e387a13e06921736b82ce4be15fd930c5fb5174346e311b719e8205fc388deb0a3a38123e7f7939e8ba58a8768b1130a000e5e69cd2903bb48d63b372e751e8ad2714a3f9456d3904008fd5d94477b2d42623870da29cd0e631b157d05de6792def11b54c12f92626d86b26ba486493b9a833abdddd14760449e680dec9f17bf1ecb2584f61894adf1eb6bbd501f08fe8740ec7af7c200762d75a530f0e1207f6518436a1cad596da5ff8379f138fa627a2afb31d6879c3a46cbb784a88feaef7f71b1672ffe82b98474e4eb40cd8a9f8171ac6b9b63c522f89489fa57968c6873f66689966479ab5964b3f94b68ec458da9532cefc4a6a8c89869e556539fc86ec3a322b595747831bb9e501b5cee9da2caaad074e748f00000a1a379ec695c2da17059c04c5bf2833922b0f6e553c1bb7e08c20cc218831b9487237a1c344dcbff2ed070c22f36ec225787a06619f386b1177d85c69e58f69172a36577a9c9ca6481396289315eb8ccec4b68217f067f58c2d03524215c326ae1c3a12eb15d60cb1c64e8ed362e14d34dca7b8431f86b6d67f2730d7bf832beab7c6980c6ee3c11d269daf24dbd2f83a19eb423c9b0e2314929d9a6bb0b9adf7cdd5af1438842dc4abe4b65650032100ec13d6875df066ff1c1c087e6398209f06b491f0fa2e5078d05db963f5c5c20feeaa82af94b3a350c4804bd1df360964eec5ab6550967a05a69dc296280c3032864b414aad89612c0001915ceb3bcb59ede8f11bb73f19b92b81a9bd43bbab7edd613c1e7f4fe19ffd8677f822c2181bb4bc640a98ae8a400f3aea8acb35e19786fe57a64273ecd995c6ff54f552d989529d8f7fe0d3df0940850316c0c1d31a14990004e4e71752eb9cbc142c5cadeea4960599a3a13bb3918254e8a084fa8a525a113ac288e9ef49a6fb3442f27f71ad00f3c3f45aaa8491939adea58bbe8d319805ba5bb026ab0790ffebadb719fd06ff3650a59ca9d678dea43976802bf0d24075942d571f65d8b284ae54fd31178bff2da7b8a83145fad163fc33ea899839af9ce50f4148f65f05d7122881ec31419659c8d4032018e42d423a9eff0cabb19aabb1c323c49bdeecc380a3a6b54d6b5a74330741ff544998c8bb348264a7df602f0f92847ff30e55c035d6d1b5cacee1d591bf51308e1e0ff9196a00c2ed8f994cd7c402f3ddae809f502eed15a1178c6b2e7d80cd11e0c62755c408c41fe208adf6d7554f9b667d68112c755bb98be06164a68ad6e8014d8d06a201279985dffd375fdfe5e060447393b398459d62f0df2e6c07e29c6d345af7a12c78d97aa8fb77ff151bd624eff42314f2d55cfde3072c3f5e1aa932dc5b0d18c14403829c726fcdbe19c5fc77200d4b8b87413d3fb3caa9baedddda955b965fb7847a2d24cf73d36920a0c91635625c95122b4123cc6a01422268152ead703d40008264de282af9f21764e2e4174aeb521458828d72323e24510335beee0e7adb036ee89fd7c09", "53", 1, 470102923, 1537743641, "4e3ddff5a15be684edfa2b9e3bc56f118eaa223da358d642f55752f9ee71cde8"], + ["5d791f2a045c02948334191b79afd3c0cb894cf662529c36dc0f128d713d8a98bd46ea0381020000000863650053ac5152659f304176fee51c19ef00a7a36ec5b585196d4ab6ea9348f8fd5ae9f193d1b4155a4efe0403000000025153ffffffffc9cb0ea46ec3ca7866aaa9b00ff38febebb5cd9d15e75eb507d06ca50724594b0300000000bd01ad7674f1d228802e0ee05087330328e345c0098ad7804a18fa193379ec2eea6a3d6401000000046a5263650da2582401994d910000000000095363006a52526300acfdf9ddec0208924300000000000000000000000000aa55278c4cf5100996e4ff98365c97e3237e7327e796b38cf2ac3f93eb7484288b03fd8effb693d64e3bffbbbd526218af85d75bacc0bf0eaa4bed7809dfab51a047c20b3e1f1f9fa1c0c76228f8aaccd99b21fb1b26951bb182b13cc4de77760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018782693001f62d0ae0db5cfb4d4fa801f66c730da2b6814196f7759e96872d83c1465c41649b94744df9e4725fe50ce2bfd4433017e7a14af9793d1ece58efb8056cb9c5105097a4e0056d5ce4894f98335f8458ea13b2e4cc67caefc6adaa71ea4e0af29b9daa16d0da7425daba9b462e42cefb87c594e0d41bbad1faef1240312ebdafba75c4720361bc411caf6c6afad7be093ef65cb27ac9f3d30e5d5be6a030a8ac67f37845343b8f20ecb0ecc23a1283a7d016cd198a94a536d66349f79cc0a07a7f669d80d0c2ddb10b5c380f9ea0fc780551aef4585157fb18b8a8311b8cb021d07d9dc77e976d9ff749e611c2447dccad67f34a9f2218b990f486bb8ce10032e1bc1923272c9344057acc41969bdfac53d3ab82a6bb421bfd54dba4de6165d02304aedabe387c008763a0632118717ce7085d73b382eaff1de0a720cabcebe610213e81e6ec6622cde9e8be3877e20be749e0667ffcbe770285a24c36ab2060e1a0318fe80dc130c384e8a3b5e12fa2c73ed86fa2ad43d05b8e5d9933a269c8042a40317f0d384a9952602d802aaa3d8e24dd518740283a785466b053b63bb9bc9db28ed10e8ca3ca7508b29ee154c2bb2831d8a5cce67476d746379fc25f28428f732a8daeb760ca5565d603d69d1ada0b3d4e18aacce830a52033f01e7234d135a993ecdfa810b5265aac70f59bbbcefac78e6546d450d323cc5b106de5e069436c4fee2a5b6b816bd801aaab015b215046ed503d9a7355a656724491316894875758e9447bda592857240bdbaff33a1ac5aecb0a512ca3265215f3eb94b19ddb2db2f50c679a6b79b360837e471ec7e8367a5e51810f79de836235cd1acf9e36f2d15337443aa6e865dc26746a72d2853dbc8df248e0d3b7d5a77393f95da48720ef5c24f1d8a754a1439f2ec879443468b2b3cd0adfe2a1e394380a57340b766226635d24e63759f3498c792d5f3789165769b15ff18124b8920d4471fab5861b5555d488feea0859f7adca1ec9beb1b1907c74a1fd8ae7f017191fe194ed0db81e2d22589cedbf3668ec58834a164f47f435ab6e5768305974c36a7e2f48966f098eb8506a57dc61bc60f6a1bbf8516a9db4ded5da9e5ce84813a5e8c57ac7671f1bbb0e4d7e57c1fbad6d40fbc1097520701b9ab374f6684fb4f689b5927139ec9edf3f0d48958a2bfbd9480352e02d6d5eadb7c8ccf231cc1f56411062776c820ebc62fea7c610d4544fcdd401b12e5a6f5fc1c6c3f89c50c03fd1b0769aaf7c5b7ef46b7d70a6368d5c7e19e0e3344c86975fb11ddd59dcb6fb0f2d2b6fff2d5e51fae6092dfeb800f9330d4c1c251ff90e31eb00d6d2b6d9f9ba8a056eb4108d0e89ed90e6060bab81f4f553a72e4108a7f3a1939e17e243a0af35408922924cdc80eac662215476ef6d6ab0d0f91b1652448e4c13d78b75dd511872590cbff09ac746898e1b4f27386688551eead9068eec6714336ce1f642735a171a3ce907ffc1ef67add712899d4853a3f9c694fc7a0e56515b1b0a0e0923bd9cd954238410a4a790ae04af9d5813148493fdd4a6fa26d90ac1c0d8b8e2d6c1a232f161857ad2deb0067ec66bbd015304d97fb1b645cd275e0a64505a5a2ce02ca9e743db17db48b5c5dc35a93d1b46e29355a55d4fc1e52056b697a3a5f5a3f62b77a70ac84fca456c4e80368db0c18a69fb77c9e0c0bcb2274ac6a9a150d274ab4aad7267133922b39e96f0fe5e10de3cda5ea4bfda67881ec9e79c1d034f348475d87687b77097a0817791bb286aae711404ae1e8c37b72185a0528a38032d6b4c46cc0610cd409e46829060935f8629e5a3d82ee0ad1fd369b3d0378a5ee9e66f5729a717d978010a470b56259100b74fc8b8a415e6f65df9fbee6db5180146558066e8d35ac9398f6f6a62aa65d3c7df8c899d21c69107ffae28549f351e5184f13473b065723fa36965e302c4981aa95c13ab349f7731d22f23f9c6d91e3624da5e8c01efb216515e561c79e4e573721907602fd2a3a09fdd53184ee48a46b93128d6dd8ef75dadf7b848ddd73b37605cb9bd9d2c09e1ed6b1922763ce0901a60d6cec0c99abee640cb2f4c71c9fe17511bcbcc6ac7159bae44be1ac3f8c172b25d09025f415dd7052954de06cc3ab7f8c631f1c79590bc937ba641172f9a0b040611102edb30da5193ad88e921cb91b9a266da5ea68b7396fef1ecf7aaecc70d6b1fa66c7c2874ee4f73975afcf16fc66e126bb00d825539d20c6d094f352a1c9d6ba959848d7ba3ff53211f7262a52056176c3f500000000000000000000000000b020ab2d89ac6506064e3ed55b6b2f773984752df79b2d96a05df1260e69ae835da6c8eaea230ff5a7b50c56ac11eae2b31b5876a0661b180eacc888ccc0f876f1ea55a8701c60d13ff7cd424289472fef3deab1c5ca27c633579b5f1c12eade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f582725da98b3e8a9cce8d5f06bb57a9bfd179a9b05422eee18cc4a028634eb83a53abe15564ff4e32139377d63e1980c4891c75e91dfc07df955c5d62402185a029801fa9b53498d45717ee1ced0d2d10b56c43801f9e10848931ffad8263538065eb3fe58c134ca118d7eccf038d0d9d6f858fcedb55edca9783b9368b9130227a15dfb474c0942066161baf8da1f454712a99573e4ee3b864da384fff0aaf6030b064c6ca070d6b57ace45851e6c5f1de77669aa7abf61e71537b39a5dcf48b30a03c1e6bbc8adedd7d5d338c8b5c3f17164d817f6a29003073aeb20e1387d0aabfe6b477356ede104435cea61ee97b66c736add131e0bdfeaf3187eb2d8c6c8ba0305cc4d1e96a93dba9bfcea99e674d4e962a8e78d31543baa933d7792aab849820205b46015d819b2bc2bc41e30e820dfd88a44b76514cc3165198c7272a004dfef02207d35fc8e1a4134056de513de5e0a338f4c77257686c664ec4717efac166c3a032700b2f44a48733ab9ef3835a18af41584252ff14c28f926da81d4ef0d3d2118021d10711b6506a7b97fe2a1102d276ee8e39d73b0b873d536e559f4279a6d80e26c7287e22717ba3f7ecef438810bb8536d49f19a3308646571d0b33ce463e0ca7b0da199eb672e58f317adf5d49e7529642ebccff39325a7f4073d87cf3399c1fe242630be764e387aa34a6fe620362f87b56a40757d8d02f162bf1df720a69b4bb33d202a8ba6b31bbe3d55bfa459a5c077a1b0d8dcbf3d5d42b4976f0c409abde1130b35259ad4e9824fb8c66201c3b7ad0ca80db6916a6b52d6cc979910859d31d20cc60a6f0dac8d6ed9b24c5283a2ad574d696590f240c402aefd0036d774a4c085c527235b83b793c8a78bb76394883e2e8e5ddf465392be4b405300a8f327f9b9bdddc8811c9919d556da28ccbc199b891ff8ceaab066c5df99841d44821378d858733edc55fe3aca37b92038afe1a41762a9ea1b321cba3099ac12cefc4eb2ac31e823a745e69e739938fd5c6542e22e119d034f62694a873c9af488c52574df4c2cd90185c9573a1a7b6bc92b8e63575fd3b20d1dbb0ab12e5e472671a74615f5eb9c4ab59b60570f2ef06f1f8ecea683eca0f28a9a07515bf69309e735f44d8a63277bd3bf2c3e3c628c58557ddd1989626e40e3cf5cc42f647a5f62fdff66ae6048004a46652cfc9c7e2b5071e0ee194e09b937c3ca67940ae827888b40eb369b4541ad4f0cce8570bbd6859ea9b7d3440fcda54d2defaa453b87d209960e4349bbaf7b1d571b582e6888780f5eefede0dd72a66de76f0d38c230cee2c15d28e4b4a70f2488a5647ee7cb12f43fad9fadf1e1a626456c95e349ad0447e436b311ad1216a184bb5b5a56e7d2e1066948a4e1d6f0b39e0185b7c8ffb2495b44cf0c9e79c9529561b8197523d45d7d339a94af4a002d2e19e84bafb4be29c78ce8199937de2e3c5cda024f96b35fa5dbf9c01b3053ff31f44153abb70ac35eb5763393222fa74d1977124c44f39abe6561feaa67152540957a3e881872abca7e29a09a27e5b7e3b94cbddc7d8221bf0d55f50ef4133ae9b34adf75d8cb231ff633fc41c476c1b98078a395f93890985ae84ae91dfbf9567d336d970d40e0eb887b1b6882ae2585f7ded98a933ff6981e0d8134510464b37271adffdb394822135f095b88da10e0da07b4b7856132609489b72687b2362dcc9899e3419581aacef589f719995979b6376db2e381bd4beafb360c58ecc05c809f53a66a73b56f541acaea08dcc17662353d3f70438b2a6db6bcffa927a576eb711777fff3faaaac70a143514b6edf5496b17b3c535d8bd37987119d18d593285579df454f8758f40e5b39689f86ea838ca434d867355413589afc4eece2e52e42c9e014956f9910241dded21bf8e25b0820c7c0243e0cf0f0e5cb7fba8f55ee35c042353c113072fc0f77d7f80b9d6921784df80478d94f3b71bf8f4a6ab790ace7c95d80b232fc011a76cc08fb3c05183c88c64da6bf787ff2714cc0a26e7e062218e82bedb26a080374155fbb4925797d29e1c76f9f8c8081d4c9b3b7b6ec57d5d88efd290bbf723b2ea701a254af76abca347fc232e20eaed13907dfaf870623b22a1863eaade4fb963900c52b959239a947e5a50463e14e3227f979ad6cfbc962f0c0c5228b6bbbfdc536e4df21d311b0cc189edd1e08ee9f9bf3f99f95d457761261d96c4d7771bea1390bf11e7e4c7860270fd38fde407ad856a7b58f3a11ef3635dbffaa70dd1ada0d7083d389cd5d32ea7fa9cf1a00989abe7ebfe76d51989771c7517f0f30dfb724a3816d027f73b58db397dbdcecd6823e07a9214d6bc70d3d704bb194d185c5fd8c0816b53eef13f256d17f491b94a517af2a4f9414f38f7f54243f1ad7c0595d5529902aa405dec507", "ac65ac53", 3, -110181336, 0, "ed4473f61e084a071a8fa5bdca186a639b7955e1718d683045437ee37f67d464"], + ["0fede06f037898444e0f04bf78f92dbc6c149da756408a07212778703cf0c98395f547f9b40200000005006a0000acffffffff05d1eb06bde7ffe501f8ad8e1cb95f4c1eb68825d52a7f9b829ec27f88f867330200000003530063ffffffff4e6907b64fe6d9a1277e0b5fa294a644cd8369d0b3233fa5ed2d36fa336493e0010000000865655263ac65ac515dfc8fd801e061dd020000000001510000000002565ae6040000000000000000000000005722e51bbeedb8560beb2a6cf2a114570be327af6f70f20987821b4546bd94639073619ca1e0d7bfdcddadd90afa981523b75453c1831035e92dd1fe45de0ff07ed10ff28b99425ed0a875af6f9bbe4eb9be7aa13257fdb0f3554968aadc3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023b83652b6bdc9914655ff8dc8509069b74a0ea116859c6e934ff473fd71b68538b6f09b88ed8efc1462a29afdb2a801dbdc0608d6f049c348d0da9ab50934bb0b8ccdba0d66351c37971d3f5b93591cf41d398ff0f3c897ee57bac167467a8c015e3f89aa8ebb3ffc8ca552ddc8d3047cdafe11ba55671a66a3e8027efef3b8022408601ababd812b5f30e7fa77795e85d02e75f3a955ef69a064f9db121a990202094bc8a6f086a9012208cb5b10f4cd62f7e0fa123a91b96666ea410857d8b0530b03b2f068ddea4941c07e7ded0477f4b10906cc1ee116d097ec6c31d696881d9139728345bce00a087f4a86dd94e1b660dc667a2f1620ad1ae8a8103775d4aa7d03052d75950412d81a04adb1d025c9afbfc25e858bd3cda76c17b337f8264401ed020cb0e79feec88ee826a43e0d0ccf98f7862fabe9671df43afbf6f7333665e7ed021f5458a8e2cacdfd7c3de8e63b47dd7483e33c4a283fa60c25f23f37e612ef3d022402f78f1ed99b31fb69d192d1205afd6a1ed32d551ce616716ee13aae0ce11e021f7210a672ab12cd3478481d8352ec374c05b28420de89868bc17a5d5b443d9eef9f92bdb871973597f1b476fccf1cedba5e27eb6daba6279fcdb340acf99ee135cbca400ed9ebf145bd190865d4d42b0f6d6dd527553176d5e5f79a713926ec37cd743d3731603afacde8ebe130f67f799b083938e3302c3405b6288a78687dc284cd9d1c49201f85bf94d5052ad6f8a8e180f6570f88297856d341218a58322d3fd8e67593dbe210a7c7d61e1897716cbd367d45a644f451b7096b5f456249975a2e57044db09603e6b1b743d8db17aa38853163772dc8a56dfa30aa47e44d292349a8cc243d006b22903694c14bfa8c9cbfcdf84d7a58b8da7d98d143b30befa2a8793015383f023667cb67a13b799fc9e8490a8c747f96564033955da066dbcc40ba62dccc8d2a93057c742820354918fd51f2e56c77b9bce534731a16afdc0ffcccfe14944bf0ffbc394b13093e126dd48eb6c5186976ccf9b227b3aa898af86bfba95a6c1ea2a21ba832c02b47a12372970cecb9ae20f8b1c9abc32ef108953cb0782a0ce77a76b52cec2354adbb304634155ee3719b8a1a8e799c17228167b3a195db47d0f6b9d3315a4078ccbf4641535f5f00ee634dff31e781fd5087a9c47d3cc5364a94a53b8d7fca150792c10248b05bed3333760fe303ed5ceb08c457bea0348f35cd4305fe8342ea6d29d3686aa5659801afbb3787c14650dc24a2525dbae0a567ca459fb3aa07d8d6730b65de63018c5141a10a0cd638e1b6e9572200269c47ce2a8c5bd8c35d3f0af47d4e7dabcf966ba5b231b06d562e3eb5570bcc189a093bd3deab710abd98736b4be2ae0cc156ea0bd3e10a5bc67161a7f6682c44fea43c16fbc4ef8e0a5fc90791da217da751fb8e708ab700718a3bc0e028df665210f3f93271dfff974e585d01d31d347cc325070414943cfbe042f72511bc83e7a5daede968c42a4490a917404f6f49d4c66693f503bbeec155ddcba0aa4caf10023ef332ab6d7f1513da59cea2c0d7ac8908074e973d071e6f8c327324e91829e7191559a8118bcbf405038eb7b437c592724b5097725477d3054fa7f9618aa7c4b95b52f358b52104f26b54002b5e83e5af0f4ff278f7b807990903898f2be4024b5a041c7556dbdf031a66e45015f74f4f2eeaa22d91a6100e29f2e57b2c0a1f959cffbf8684b82bcfdf0c10cffb65ad4c94899720a453fb310d26206ca2c261bcf80a249e866792874ac6a505ea67b10a60f0f8858da3c5d8ea05c7c45cf4fdf4aaf9fa226b55cf46868c0d90602b8e234a9778b598a5ff2fa13ad4956fb21b906c52d43ef73755f4db81ea3f5dcd9a26a4f7b0e5f869577500648c2e766b854b47218d51536e30c6e987fb8b8c65af2b1f0c370e8c5bf7a738bf8eb86ad3105bdf8a09126aa0e2074c948f60d22bace3744877c2ea971aa31a061fbf61f5ad2b2ce7478e4032170549b819964db323334839d1821e03e5e825968839e70c641e39e29886bb1ed427e30d3d5edc60a6a08f06c2cfd8c5163377661427e2f6ce87cc58bcaa08855017985fd8ebab0e9426181840cb316a7fe5b4a48f981ff4b0b98f436da6aec7b99d89e2ef1e9b522b50207851a69a09f9f17fcec1ae95fae4e6d6e34ab0aa66ddc27a2d170b9a41ed5809e2e8b4a9ea580f5025dfa8281af57b400d023a61e3cdc438be6a7ba99514f49c03f857fb14ff10866eb784f2d5e9386453e9c9aaed800aa4b29fb9ce01000000000000000000000000b5c7082f899c9cdb653d7d654680101798dd15da4b8a425e8c88a52487c3ebcc3793cad3e0389583a38bd5c2002005919780fe917a961a21b56f9f359de47bba0d837c7bade6734d2633621436753d18f46b88f98b6b0dd84a40f5d38e3d0de80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094b5bc80adfbc64b8086fd4927826c4a76d7a0cc1fcd94e304877d50e1bb3ccdd3832d5e1f1787cf1fe99bf48662620f95a7c8d07508472788e05e2738541da18fa65bf28c24c8342f2137c648ea5264d6440ed5f2489b6c90f9ae314ed0b6197cb6aafbc9493d347ca2b1ba7a8acd200536fa1c66d01bafc9d2807b28a8992f0312a1e636854b6534dd07e39f6001dfa95d6f7c6f9ed34aa7aeecc08ec6353e7f030ecabe4d56f7eba62abd88bfd4334437e73a2cb4515c268093a16bf410f81c440a06cbb18c730d46c98b538300004364700f943358b1b17bf42b54a075cf9de696015c4caec48264f7ba6bb5d071cca14042b77b9c5dd2d694cad702cd0109764e032c517206b18d999128ad5eb2b6caca3ba29c6f7dcd9dbb4be6a923c0aaea2173020c8ab44954be7114fd99263c821dd723d8366491a8b63edae79bb6b42e0cf08d031aac270a2c24f529be389d4854b5f200fa07010da679f7c37cd4a3b2562fa8340205219907b127c32837dee8d7d0bff8ad1223f3fd3af81bc7c40f8f8853ae3b5f031ec576d551e31378a78a3cf542feadcdb6c68e2e3dd208c898f5f5af7e39051cdb3ea13375cc0d7f13266a93f9d3e62deb24e979c7cfbaa6902a82b2f66f0fa0e7197cfc3e4f037a1425828a5eb6eb3d4338839dc78c31b9d245c9edf87501064b920389b3332da01af4179a5d96a14b98ad801cf86a7bcd3038144f8f8b20a4902c0b29d6b228bb2c4ec3d1c5d03a692e81810375da3a094ee9570ab59ef84637fb149ac8bc69134b7ee43811bc1aef11a7be554f10ee05e687d0d0a34b9afa2cea97e2b171522f254664ac98c347da06bdf1c9b56c30380022d6e8c7b1b86a8be572c758e5fcedb2428dbba395d27fa5170668890cd438d7290f08da3aa727deb2dddf5fe11f15410f3324ba10afca8f52051d9706646725c57d90c3b99e399c8caa0c22ee9b3bbcca6f4bfd23232cc18d47160eb4420b9b4e75de519a6fcb2a3d2854701b7e5be1642bbb03d41c89fd01ee2893f8757e2be2805ea0fd828228afd5ae710f2e89fb5ed500dac3eba8891cf3c9aeadf25e904bce0e22fbcb98e1b1d7bd889030f9092b7dba2fb5d879fcbddeece9db21cca76663d13a859530c46dedf9c22ea830f4d827c5f503b6dcb1804c234ef1c5e04def374c8c166a439f4989a1eab6c42c13cf0695767b8a6774ad9f049636227d116cf419b22ffa5a2998e576394d40a462830604b7e5e5a11beb1aad436c580f235bd86d99b910b40981e5f3b4df1050383963d11b3476833ac605f62768e6b64fa2c7cda2aab76970be839e2c694fb42244f7ba7a7055110ab0098022cef28f2a48a082b1d5b501659d30a2c6bf893553a37b2df72a46798a756eceb37599ea34d76cb380a376e9e975ef1a51ef44252126b1c225ca5059810d26427a69852b7a0427ad978be638bb7f9216328ec615b0e18b79c1542a8b7d3527204587ed6cd5bea3d1ebb881e9376d2c70b70efbcbddd78487f240f7ee9c490a86f249ceef3addea3f0577fc3580870fa15e7399df18f021bbb341f02e5261f9ea9184b06011f85f5a7b632786c05074b777461dc8e5be0c11a40dba670b2022972247ae5f7293bb84957714bb968ab7520e299e44ccc5f5da01d88406f36e5ade5a6121430fe917eff92abfe762b4326825034c275c3474d31ecfd6128b6b6552d2fdabedc4f8678d3711b77b8e750de32b6fdd3c0814535bc559217f6b36b588850eb71507cbbd0a417adbd4627e8dbb15b36967fd7f9b875df64c067d06f796d4d483b691b6992c531d7663ab4044e981d77122fb7417e325ae1e2d6c994846ef47bd33fb847e80f869fc849f89c1b224119187abac7009774db8ae02ac0215fcce99e4f47507899b2b91c6670faf7152a61cc2aafdd7851b123460aee9e47acf399c9e25e73e8fb03d0b739afe9ec893bf1f00387a78885d89c143bb0be4793676ddfd7dd0eec7920725a15f8e8b61649904ccd58332f1c7def6eb41110a1161485c0899af45ff5d5560893e6fadf874687487ff010df45a758ec537cbcd5b3870180d90db2368b73b424ab66a0ad21fd95a24f8ec6f5cd61cd854cea2762099795c9b3cd21544205375c478effcfe83523ccd4c92156b5c276bb9b4ef6a633bc976b42fa29229471bed8d99034e8aa3a1e6970e4ae7b5caf504157dd62727666f96aa48bf29fef95176e52e2c90849d7d5476818a0d73ebe0161251a0fd67e4398fd115908ec58e1b67eb76438f0e01cb19e10cfd94563e4fe4c20fbf5936c1e2748208400a64baed8af1249f299c308dd9cb83e70ca6c5f462466ba56e789910ec81d97cc0573f1b624cbf9bb5ed9d1f01aa5ff7084fd873c913ca00e2ff1d88c39249e170528b5f04babc152ce987f3f4fb08bdec0b8cfcc5706808", "5351", 1, 2061477248, 1537743641, "8da4cbf6316c42bdcb24672104baf5a06e8d291c89f3452635a69b97721f4b51"], + ["030000807082c40302e1b82e1c8b046e8d4a21af51c487aa52b104a8d4e587f98ac8144c4779753643000000000765ac6352515152ffffffff58835841be18f2c0099b59f26b957396e753cda84e73be338248c1a1ca81d9f803000000076a516551526a00e4c44327049d2b570200000000000d941d020000000000740a6d05000000000015054a02000000000000000000000000000360b3ba0300000000000000000000000001de1c80e6ec94046756c8e32128fc860cd0e744045bdd24da7b1e0b38f12d0d418ef0fd9de3f64b5bc6bcd11f075ab7c043c1222fa18711003bf3766b95c461dcea88723fac32a7fca9a508c2c13cf2c68c2f61551a08066f7e09ae68cdbc4d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e48064e4f3226ca110d0773ba2a973c5422a9e798cd166f60c14356300abf0efa8260fc46b742a3cc19ca879eb22131ed5e729f0fce6dcdbec4b0d5d66b36b4daa9f278c400900ac28b35d27b0e6c72fc36351fc2241a38a24de1804c6f5da171fc952bda477a1789b3e9a4ebaa0eb67994c49f01185fd2ff720fa98143774700309a619fe415041c08acf9346a22c9ed2aaad308b5d09800ed833ec9df8cd9d1a03203b8f78deddc816a4a75f60ee8189ca0d6f1362b7a87055cf44f54f246b6e300b0853db26aa6cf379920ba735fff9e48130d0d6d2411bfedaa1edb993ef87ce16d4cd7bafe04112eceed946ce6724e917ee058e7a6157684577fa924ef0e2a6ef02250dc6a43b516fc55f627e2802adb2d682096d570bf9e645c2be7f138177659c0205cf5db425c821bc733905d69b43318806cd9709e8c228c58ca523c404fbbeef0208d2db7212697bf69ae1b688d9779d58f4826d1f3bd9af6fdb358b4b0b4d003003287e5c3ce168a2f16e4d6f9d949503d282670f8d6a6ecdfe8ddf261d70565ecf0214542cc9b724e489e5ec6533ef974f8e03d3cc78224d56a7dbb338b4dec6405c14b3c426cf8debc922e31ecdd88443e84413a8e23b944dd801faa76197ee860c39cc1cfbafd347501e881b64aa430cbb15475e8b2c3dcddf7e8daa14efc23aa16793e7887b91982de3a4041d3f5d581b2445eeb81a6104474344811d3d829681fe4ffb6176136640f29450d3c6e3c7d4a9e8cffd24011adacc1ad1335465fb4d73a8c1ff37966257a13e8d3ef7b056eac750e529d968d5b958e9a4505f604181e33dd4e55a1d811c6c833bcc8f749e932a106045b881472bc46edd8720faf339d53129969c4aaf3d86168c413ac0302f871265dbb63f7798971c4ec7248d8f74d20895497865c534e5a12f3688925617897f393e2e851d2218c7e9b4f44dc0a2c458c8ff6a60cc08dd479f5d6cbc205d6e33b09a648e163181998c529eedd00f95df58a900e7e7c33d4643be49de9af31f3a41789865d7483409804813a90400dd27aec1d829975567891358fe55391eac0def4c4f62d4336e7f39ef60c42fe0fb3c000a75b68d73d838b0e92149a62f892985bcfaa1ab3a2e72772c3dea8433b9afa9096f4a0c885a0334ca2d33da3fdc13073aec919ba6a7a7a316a0b998ca77da4f90c9369f87383db40ae0de50d656207d379559341275dc322d73dddc2c0dc97ac1c9fd2a2784b06e84f0b2dcf6995a2fa4d40b5963c34df066c451c34db21fa54d914327657e655f816a866655b6dca5d3655d53abf653a66dfcca8fa6a3b350ab5a7d9f854256b772e5970a92e7df6b4f5badf098542c10a299092cb828ec991cf575338e1f26c6297e97b9224259cc3e7e9c17b64308b60bb228ba9008ffd984db1673a05dd20b21bdf98be0be8a8bdd283dd9e4b16d35799d03c828b5270d43a8bbdc06f4690db6c8fd5f5312312363b4005d7f05cd86134802b1900cba070a5c98b7130b35463f4e757c523e9ba941ac4980fe4c556441f3fca429de87fb0ee528bfef143fd344e2677db83d893014e0066f81fdfc359df62dd27eb0de644d642ea76b3932fdbd6534e2b1356e6197522abb831e19507c6004755394bd7042de696986bed420886cf947679f24937ceb914f5672745363bd916edd5d489fa435e8455682bd5e53ce0c812275d0feaacb96a95ca2ef02f13702fd8dd3f0146cb3f59c9763adeab243c10e643984663bbc996921cf73399403b5dacd231fee2f1472caf6d5aafcb7100f74cdf948c09f86ba926bc3a71ff3c2252613e0cfd14591a0ca1ad229d9b60c1fcce09e134c58365089b2c4880e099a6a36fee16ef01280e3377fcb265e4f21bab9a47ac6256f410f4ce1a92e30980514d229b1feabcaaecf2e431505aec195805172df725a483c0c1452f21b7056691921a086dfb39171dff32a3a37c1ceec19c79bf925be0aca3716a6f63a24591a24474411a587a1e7a4259225532970167fc4132377be28544491f78d8e9e406b50dbf1d091007939832f2c9c0b8544d58aae5b097d7ceea8dbe96758ccc9fe1f64737859ea323aab194b387c8cdc393874090b8c3005b8810ab4eab0a20757277c70fa1923c99ed2f14960465a5435418b4c17d9b72bd5013fdf6ffff28fac107e609953f2fafa225cc0cf472709a4cbf57e17fffb5a9cd76b48f4a9ea8e1374872c495a660678bdc78dedc46a674ae16b1585dc25738302961d44c5b951531ec7afa5944fe1741224ee7a620a04e42120a62e3c1af3882003000000000000000000000000236657e788ff1e1522db287312ae3e10da3654a5aedf4475d75c7b5a12ee6ad09af61d6c625b1f47468644746357169f8eb1013d21c270a56b982f04532f8afcd3d6783cd6783e92b76adaa6b603c16e62da6b6215fd54dc2d34b3073224c2a600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f3a28a69351d04b0db6bf49bcc3b002beb87a516523b3547105f1a086fc584bd042e0f4a53f020daea9f77a07c2eb940058ed6ad8103717049e556b97d6e9410861d1ba262c94fbaf9bce7ca3c8932b07a710b193d8033c7c87159b91c01f61160cae3cc46d8f28062ff10beba85902f31de611dde4f44e2c42dc1d83859bdb6032d70fb9adb5f2cebe0f771963d3d474cdaafa2ffd69f52fcb5e1873885c469a402186e5f0c6f9155dd97dd0b5ef248f61526277cc7f77d458515fd111fb39c9bf10b04e1147b5901441b67021118d5e2d130f07f3f6461e70bdb99ac47321c7020573d59e45fbde83f5357eb19b73b33ca2e4a099c1802599d01641ba000e2aced9d030d9b7282e74f1c34171c07be6263a0fc0badb99c30cb6f2cb8217881f9ad50e10228d05eeccf645c3a41cef0fc19b20613b8c55e6c995c7d89e8f16d11982221f9031636bff3e207f219a9046562dbc084959e8fb9e77d01cd710addd83a6b30f44a021518bd6e486fad58ace6bcf43c588510bea7ca16ca1b082025acb0df3637da950314014ea72d971e85388962432e0aac38134b6225aa378f23dd8aef10bca8ec5da63e02bd450d60ed24a589af819a8ad9e1207135597d0cc5673690dd866a301dd54de10a0cf6f13d0d1ae6e9dc6701d90bef46295a80963b4ff58b217b0a48e06c504581006da06476cd32f014678058dfafbd61117ad885f7611c566fd67ba9eec5b8e3be416e6fadb73ad43cb612184d94bf54f99cd74c9d954f5d661c3fd07ba56e8b82308210396a9752f5db53cfd3ad3ae38cec71a3f8f9ad89ee31fa95022031ad58bae47c59d0e6581e7ddc4624f43ff88fa7a6e0de7b3e261e82a31fb3a5928313206767202500165cb8647626c58754aca41aab023a5ead92d7dccd05abf6e4663c70519d8948ba37e6811cdcea33b0d623cccb0056299f72eaab7d7e47f397b49cfda316fb23f78f3ee6d79fdf2c01aec1981c33d5b2415fd6cc5b09abf16f8eda4303a1fed0931bfe0fb3572ec493efc6ec6d11b55e96e50545642c094d0fe4eb517661fe4678c8017a605f852c64d5f269061e3ccea2087686e13806f9f493438326d632b8ff205d2d249af6bac89128b06114a58b83a268c53b24e011923559af77fd2a7e2fd3948b06b83c27116b79ea460046617fc0c5619cf10ec313e2e3a3963b354ba97a1f7768856e1c76f4431b6564766b203ff70c952656aaa700b336c27ea83f5cdec49d27802468f8ce90d5b5d85ae9491e2e7e188bce738ab56be184d43a2460f9ce7e128a8d628c10de5fe0c5902b8a56a1a6c3de14995fb35a7f4e3adc9b1a231b34e4ff333b3f0965722d987cc8a5bc8a3343c4d09f0bfa59960e30e1ec0b16c51f27b4c08daa3f41b98f1ad56bb33513a75be5c05ee7bbef8b6ecad0859c773ba58d6b554780d9176df877becc0aef2fe16260a67073f373c253e8dc49b69d41d5b87a55f9427e35ccb54286d125f459acdf0295fe001a8fc706e864154de9fa1caac4781b0ba8b48297d9af519a2da51583f12f34d73286b17dac4c43c8abe62d11ec6ee6723e70aef86524200b270c711e5d982eca2f4d43353bc8ebc6d4e058bb991c68bcb31fd58efcd7f25d6728d0995f2e0dbf63aa522292c9c9c84e426729144b741dadc5790ab1ba630a312523c2e7921fad321836e9d4d0e0fcc0ee4b212c9190e94f3ea9a4cbbdb840f15d575c0c337f3d5609e7b3f70e7218c9a3480631bc21efe3972073f16ea149d10b307c39ff07c107a182a636c6ced64cd15d4ff8870715265ab883a99edd7d18121cec6eee8472a87abe9e8fc5e77689139fe02ac7ed03eb1aa1f49f393ee912d6331d055bb7359ad784f9b9d68b04b6144034e7d5a10ffa053d430da89f0532b82d3fccb9b0d2ad06bfb8cee78fc43b2e90a8b0133d26aac9bbe23338d08ea9ba935ffd0c33cde85ab2ccdd9af6f2f84060c2ba89ec3b8f9ff4671cba4498399ada45aabd754d00c0dd3b03df23b23d07f59c9dbb758cb00ed6a1ed09be33387bda30693c1b81030c577db0ddccf8dbff293a0ec683181e466ca4f3f03f5d646600a79de3d9c9b351ce929f2200af2e553528ed0ab62b84d312e77523b672d7ff60330c3389abca9a2901e1d8288730f6a96a5b67b72761df760f79f6ce7d43449292928ffbf23f8d3b50e21fa9f27ba18fdbefc6c6464bad105c6d550a4b8d14fb2f25a0ccea5d053bcaa89c53cdd81127b01d0b95aeb9ca0fdb7ffbc142821d074e6b1c656ba2c8275a9c68ddbc5e1a9fbef1273b68f1040000000000000000000000007fee578f23c01cb247d9474ec7029628cc2c588b0887a0709a016c141bfcc8a8d2ea166ad6f2e8fd80ea02870c03557f1fb07b500f4db683b4881383be9a3b1089610f2c101d36357c4ebfd04300febbca11e0d45362225a978ba0c87a9c384300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000351daeadc05f8fc22f7c5ba70d5f15a75f313778215d2e75586384f93601ae437bfde80b70da439b6c514989c2cfe3d5979f78ee16d8d673c68ca3ab19734ddb79c9989675dcd64d820720dc6a76a9388d856e7697a2077f487fc1149862a949d2656893053c0f46a5ae34a4a6c11e4be808d9c16c520d8359e31863b77127d70226dfc6cbe0378ff8b6818a2d135572eaa9565812d0ad07b5f70eb7ef2fcc2dce0323f0aa1dd0904435657cf0a4e03164b10c2d7efe673fa0e38ad2f4c8ed0f0d0f0a00cd664a6d17000ca2816ef34aab8dfd5eaca834657f2bda83346f1e8f15cf1f7a5de0ed37972f247e91b05f3fdac99720a6aa6337ef8a70483536e23fe70cfb022a1cc31f1b3cd46bb7c339feeb514028e80d002f4a41f1eac79f3a6fe8c5c95b031871a76fab9ea76501c07d89adcf82f60a7087a2e360669209efcb365f5b3f6c03071770883b5248a79493ac25d9f1431215b60879e058f4a0a29a7371b37bfe83031721268e5111d5782d6772cad5e072168b87779e45950ec94478ad3eebde5cd0022f86374a76f46b339b32de56e9deb8533433c53b9f984fce5ae67443b309c80e6d416cda890d9a1942eb1ad849150a9a2e6014ced485204f1d73455f906504b7fe385677e95a03e37c14684d16f77a511786d0e6752402a0de8e0c2a15e9bea2c6f451b02c40fbfbeeb8699353b91089e429cb8635a3f921457aa242f35384ba3e8742b2c1c63a65ea0d4fe2b6c3dcec8e6c794b3b6461d95cb8a04c6c0fcdb26cf0cb583809787a173ab3a4d78989e13bfd1551df91b725c2459b78a097b978b0f0ee39bdb0929c79eaaf6d873d7b3ef483894e5a2782e56e2ccd2a3f491c3bb93e8d23f6108e8ce28b3c57e51308c2e840a0f1cbc2056f01aea48bf430d1989d13e293d2f52702757eaf2d84d4e074de7193a21cdc1b0bfb970e9895b0a12cedd7d38179555b3ee57a8ddde5bb72d7c591371d6015bca5575d718affe6cbb57d483979290bf0aff1d6ee7d565533a59a03f2d921b3c0810abba2f974633c4917f40837702e41ab952772959e3567a69238b1bb0b006075447093badad368a11e6939d7983f69b693b9c2a56e428ba1f494951f40186cdc69f2eb5031d453fc861b76ee3a9514e72bc07a01382de6eb9c6514466b951829a2007fe9cbc8406bb970c8f96f01f58f89cab92582ebe2111d65c8b6ca06bcfce110798f81840317ffddfc53a131e6850e42a8d6afea45c17c7fb05ae5235c49c680077c4ef7a2b78c7f67cccf05c3ef5dc0347e34d644532493c7c9ec67db942f9018eb4f7b0afef346e6e58b5a5eece83589c77279c8d7dcb85da9c7841790e9dc3e961d230e00f549c192bb93009f2b688914e27e7b0080bdc7590691dff4256aea41059e9118a683dad8e0ad8c729e3735ff23cab4784bbd14d5bca0fd3862aaa4e6e91f054db99e77f284eafdffb1ae5ff45587ce942e2c8bde0a254d68d77701f93fe531068d4356d892bc37c8da6b43d8f75ca89f1bae0ad3d0706fde13d64127c4bc87ce631cbf084cd002fa2d9c96b488e82ec7e362cdcf675f28455ebfdeca81c66a5f06be59b35158fb280d5c74e5cd674bae40ad47cee635b6113ed74b2d916bde8e04dcdd6bc6cae4aff1f4aa93f035d1f22d399b4a42b9cddbdfafba9979a82de09a8251bc02b88115390f5e267688af8df4eebf841c330a6a331d663c61565db48644f08dfd1c606917289ea2ecb20f8874a9ddbfad7ea5df59c90abeade4764e30441ab889aec5ed95187cf731f078fcbf711fb4c56ab92bd0d26b227435288b50ad048c8fcb9c4dd28f6986905fb9cdcd4b11b4745ca860e5a9f46dabfae1e513281587bdd435419b89c2584231d9684a37625b010f32fde0efcb4ef0f9a86e9634e8d275f7a9128c9c24a71f15650a0995935c399af52df9126284ff68a80c8e8e9ce9f7962f70212f2eeeeedfad3d6bb77761381e4848d9eb44cae10992d93941c2d2510b20bd3b3499fac8fc0f92ac1757880581b9e52fa8827a5cab9f9488ddb85331b8a8a37c2c3f30d7c3debcdc89df9e3814a1cea18d20e3a4ed20305a9c219fb6b0333a4f9b47c01be3769847c50a223bec2006991b2b9628605e1833cdf64a6ecfbea1d8256866846eb4634c87cac4e7ed822acd5ac8b4a2afa65b8186df5fddaf7ab2b801746b7f4fbc13c31b5a384b4f0f1967dc2d947d6b2c3dde0c7691fa5e4fdd7d6da438b98f88b8623b54d5ac819db01c3d87c0099fd28d54f400762b73dedd456727d1fedc123c5229fd623a62ab8d8183c987b58a91472decaa794d3047b8a691e958bf5321b31aeaf18722ed7ac0155ccef4881fe252477f30f70ddf26c1adb9520feaccf25d94e08175bb92e5af568befa6f7fa47739e7e37ecb1436a2a066f41d0021f79ea300b", "00516551515163", 1, 248496992, 0, "288ff06b76d9ddf7454b5a17b80d7eee7501353ed1458bb649f38538ab32b68b"], + ["030000807082c40303f19ce5d64bb7df274669ac94382496ab2dbcfb275cc24ab5218704bd8f93a7f6030000000365acacffffffff90b8702f584c459a7ca71c35fa275857b84986cc0e94519b20176aa047383ec10300000000ffffffff4f83e5d6e2724ded5833064be86fb54dca9608166041006a2b7ef97526052495030000000151ffffffff04a9605104000000000653acac00ac6a0c9403030000000009ac636a65ac63ac5263ecc9f5050000000009ac6365535365655265f02a4a0400000000016add8a66e45e206b01018791fa03000000000000000000000000434e4df25ecaddc89bf07f9db23dff189a2c08d485839df0f27c79f0bd0d80ac533e4abeae111e2b1962f301bf31d66d97b6f6c5d440ab1272b5a21303158658c31c4eb795fbffda0cf5aa1bc0adcf302211d7d40b169fa35fb688041cad448e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a31915c0aed6989aaa85b4af2aae703ce3fead8c350842c26494cadf68227a8256b0591ef8d856879c509ce8124a2d1f193ba6c686225e3092a303bc9325a046eb99414e31fb22bbcaefbdc23c71de3f0cb6aa7efb8b04e3701d0ae4a0e2924213fbd7eb95e2d3a1edfe87ac10a2dbb1b2fec9f912c5d755062a46a1d913586030ad33e06e72af2d6ba3ef72a6dd592db62e9f2da4a263de69d6fffac8057742c030529adcc84468b741a0ff5435f6d5e62b5902aefa95a8c269127ec8b188287640b039697d61b3df21a2ef659bb415dcfe22f5f97a0d2d3494931eaa6ed4e20019ee627499c1e79056f31b3fc64a56c963362bb1d1b5dfeba327632f2f5ec1768350210f08a75a7c3fdfa09e94e7b8dc9b561afc7ee1206378ed6f5bcf1a32ebe325202040c3f0eea75934713cb8818e1ee2c18fb03310b94df553f439e5dbf1c8827cc0208a6e25f83e452d08e6237a780cf85615736c6ff3840ab011707260ce33aa9b3032a0b254aa7e7acf2a12d90181f13b99a0cdc6c566b98b09d03db92e163651110020ad5b2994bff0a2212ab5486f386f2016cbc8a91741fafd65a146e97a4aa05985ca59b74feca0c2205f65e0cca47f35d914ce7045b75249e86f3cd0629ef6395cff66cb42f69a413a65852f1936e05b9f0c6d265670c44da1379111210b990127fda2222b960735431f5aa62c0b74c8ee1f85fa1ef7d444814b52dd0e05096bf15dcc95b8f1aa7a654d322f488c4bcdbb7fa75b60f67fc56a80ed78e64a7b9132872424ffebc95bc173acc13e2abff894e217a97982eb1c4d16ff27225332fb1a3b25653f22d5e7c3396509ab39d22e8b396268d5e1f1d5dd599777174e1945cb3957780f05123034e6cf70a0f416994160ce5f3b969e31e8e103fd48d1ad0d9798e522879ad981383bd5fc06acbf4b6dd3cc0cc0f3ab20a2b1a7a3bf3d5e827c7bd989a286625179d8c36b45754078b5d8424ed3f1423e39fd0dca0ecfd09acde7a811bebc7a9e584bc2fec66f3e5ead68d36e3d15b19e037483a65f7ea05fa076194feb76f9b69a7d914c8a9be42b99508400600d733cb55495ad7b0855df1a386649afc6349b338b511cfff3384222d90bf60a25f6fd0ff1aef03cd0e4d6266878690b68d8bc80c9dcabf0ee5315894cfe41d092d2a8cbb81fce47b4f63a30e1d0d00d7726f577012b03493fd5a80af842d39a46f4e5744ea3669806a9b418b4b3ee342b5bbb671588bf51ed900b52ee1ea42d0f3400e79269967a6b6a6bf606fc84c804b9831e006dbe958c4c0ad74e177a4379bebb6d3b6c9281b09b2a73f9f8f4971c6b9d5d2e1bae21258b96659a29d95152db4532b708548114ba55b520f20636bf4f6f019472594a765f75fadadcdeeeda2b7f4f2e15877a07a0cfd0cc561dcf74ea210846aa7dd2e9694231ccbd67639b4d197ceef611baf8fdc041b6d74fd32b1d5b9648783f4820ef9354d6fdf1b5853f16271a78f5d4f630f9faf8ec2afd256ee68e5c9ee44ca26622e9813f0ca044beb203aa61f1b9c0241d3ec0064d9c753e6dbdbd1371d9b5459d09166250d86a2cafca59a9037b355b3a1335c1b74bbee3e7df72b0b4e449b25f094c6cf722c9aba72702d98d3cc9920b7c61c6179cec4a5728c711ec114d4df401feedeb92fa29400f82af9fdb1846790fa9736516da02f7bff42df5267d58b5f8ee1263dff2a049e1a4586566e5ee8bd30e1b0e764dd7eb00b2604c45d226fc164b95f8056c8299468ed5760b925e1643f02f37bc2887d35df045753334b4dc726425edfe4d5efaa32a4cfc533c7f97f6a700ad15b04035966ec32d4abd17ead9b7ea80d335a787f1b9a27052d48338ea311e5f278ad67ab2aed8949ce2d4e4198b0a4c2191ef116de687d6eecd9a5ec38610165965aef0f6e3fa964fc8614d3b470aa68d940993457e2edf0a21f6e318c823b9f8df99dba89f2311bbed79b56eabf388710a89880564a95e17b46359e346d6b295402b0b11c49be04a944e688fd25c51cf65ae619a47fa66ef1789b3c9c59a20d23abae54b3693882387099cfcd480a86f2e4309337349f55328c4957c271c758fae223397f063b23b14a1ea8453e1b1c9f86fdb4a191afc73b22e9ef26e355d992685739b4912e4c98df814ad45991f829b39895833d45cc52f0186c99a06e2992ef99010a232c9c2423115a45f1889a3bae62a198cf2b07311cbdf52eb7a49f697dd051a624bb2877e87a07c9bbf58068ea3ca79a2a19be1133019d83a7c3a71e2fe76885c076e26c2a2e2bb7fa176c5240007c430feef27eb481bce9ab85a86fc0e831fb80d91fc0dd70e06e1e7ec18f91ed4d0d240e14b7f1283e5baab67ca2891b388272dd7ab69d7e07d705845221ae134b70cd635bff27bd010357e35190a47e361fa3757490f69774dc07", "6500", 1, 809535198, 0, "9d292351c322cb6ab4f080f2e58b9ab97c9df1da9e7887b10a595b03a60ef6e1"], + ["2b714127018e080c01ad6e309dbbe92abe18ad34cc4b76f34a992e03fe2da2dfe90adfc762010000000034a66e8101910c85010000000004526a6aac000000000264affc040000000000000000000000000d485f504bd83f73184de06f5f3df3391a64415b0a68634452f183f452ffb21b3d6bee723fd8afed30ea54d9796f3ac295e4270cb16b6931de63d0de5e7e00ca3474984476519c210e49e17fb0d1d936af34d0ee73712b03324149a0256956f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000117d957f5383d219254a5098b1cad1d13c5715b4fbf7d3ca752a15a958a843ab08b6f6380417d93bf45060d4a38cfe39d4b18efa0458df1eacd5a2f9602f1c7e85f6885853ae35b615fe172bee0d3fe75ce4a6722cd18eee4293033c5b35ab8ab9d0ab6eb6b4a1706281e33957be262a7d1c2a3bc247740b3d153ebba0dfd7e2030061119689faea1b6537a74e00a1164911b72499590e8f1e9b968850d7a6fd40020f21ad8c0e8d3994a401c3e827a39895fc36e70ed5575185b8db37a51dfe32560b023a9fc8f3bf785fe67db9081168cafe2139ef1c48b3dd4427bcedfda2ceaba91072f97cb33e6a91d32fb191610d6ea056ff51aad030b2305b2947f0d10809170224d4002e59df9c7a7a17b1a7b2c8eab1295c6a598141190cbcb5574f4b21d9430209df5650074f5244792a9766dbafdb7d3f5494ec59afe6acca37685273f741e00314744069f1f613a6ed1d23df2ea960f67be0a305a5a86d547ba0231ea190de6902201f472331beb6b91a51d5025b3ea0e3caf72d06b85a60cfbfa1fc89c49d3f820309eec67c1ac679b7f4a95bd5e3b2bf009f081ab4f100ec1db51816dd992e340075e2ec2e550884f9f4c196f07e7b2afe28b3ce96f405a9da0ad70124347a0a4d102506340aa6204ca327533033f3b0f883d33777fcc273ed3bb4c9a91fbf04c155cb92d8540ee2ca2aa9166545352e96e1cd689090a3a0eba05af03893042ed3f16e28f83b240b46c7193be1d07160eb6cfcc992228617afbeb0323e1adbcde082ca27ad26a0d331e654b5c01dcbbdfe005490abd1ba4d6ab5d4c46331291cce9668da2924aaace9715752cbf672a1bc41aa495e2dc30dfb5408619d8eb464a3721a446d255265b28958d550deb27b49bcb4aeb4bd07e1620cf56a605779dc8be6891972389cd9aecc982697c9232b3dc7d74cd081e8bff392088e27f80f6be15ed19bd0e665e38962e1d205a71125fa66d9209885fcb7ebb6eb4f1857db900d7f74fe2ad229ea41ab9d621e3a595bd450806e90f5060a07e75eb138275d014a00e130a1dc3cd3790bfbe6052cecaa3cf24a99cabd2ed766d6d35c85a140872dd0f3f73a3f478237ade8631b55f1ed981291c68d87522bb161ed69c895f5e6c957a0550f1517400f63c944a065434bde26b2f3b53f1ad99927c2866b786eb04d0fa001cc9c95cd242c3d7978deecb66c09a3c5ccb1725dd9a02641e24cb074498b05cf32c9bbf88aaa7cae57739e92cf878cadb6db30540ead5df717587623336dd289b75a657086550952050a7c7198d6f70844e6a6e0f7cbafde7680d71a4e48456c9f5f677b0a51907f3d9d6eda6c88f59ac2e6c21375207f5d7596081f1ed359f22253a7b8718ed60975ed527a5e203b560244b44aa07b228626a5cf52411138784bdbc9ebd7a12f2ca01a1b4696812728a0db0f0a2ee46c59a6121ae1716369fd539fffad68cfbd6a111727d56cb0a8fd09e02fbc06862191483f044e3e44e3da6f477754a7e532a306c79bc6fa6e246bb63f54645c772d3ef34c14721885d79143eccb29cda73697f76f98a1998b1c87cf148eba605e0a08f78691fcea56d508a6c830621b296175b6d69dc4554138d8a74963ab9c7633b4c2c8a55a815c1aabfa3289ea14ae7ffc3d88e4f0d322189825f937b01894792fc6ffa8e062e0c4858449e4d8eafa564bece408e00d5af0d4a309a6108ab2f2b4e6eef57cd83b94a7efd1ad2eb172d30eb756d115cd93227120cf4c127f9746becb60a2a57a71b0375f4674617d17daa12652239cec35eecc160473c0d05bd7d7d3db343e7cb63d870ff8b912df23e05b1d859df7af469e29e5ec53753c12eb8e3401bda4ad2ca5b2893c12b6be3385773e1fb450d22136944e4fc7e1153deefcee1272a73898f7ba7bcdf211c48ab6b46acfd9329dd10689a34666725d42fe10eb9d7f478af42a002970ddc4552035235852cac86a98fe664e202fcda996c23debaab586ae74b546888ccf05fbeba38c24a43c79a00a014d9186fc4cd1bcf223a9b15d940d4b85c01d0a5c36bd91993006d7731eaaa8afd01869c10e2f682133c72b011683e5fb58491c814f26aea84c3d54dc1ca32ed126c358da5e29899c28fe804cc07928395840a42336696ad9764d1427d2aece2552b8c4d06c4cf5a0924ffc6f0b1ae01cb31ef94192497d982753a89ee5a1886d866b794239f8792bdccf9f28b63c113762bec7132ea245219c7b24a362f7f162fc6b57b79325c70c0d0b09f2a3a41d40e144819d15a7a1ac52a35baeb84601a0b3c08900000000000000000000000000324c354bb5a3fce9937acf99646837d4aec018777281ae7e0cbed89045f27f4abc2681b053e2aa69c57eca8a5a2165ed4c2be8f724d7c74e68f267bb6f54469dd6b16154a9e3534a4aef37787a84afdf6e5d407e8b2b7281882fd52ee1a92b5d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034911292aa2fa5072992cb8e95d99ae4428c6ee836e56bcc0d98fcbdb7269a7297f4ef11692b15d7dc0a023985604411af1e9da361dd2ac0a7b8e3d7bea0c278c6c3a0aeb0c60c52d39a3b0fcb020af4900648c46d454776808a3c988a3cbdc06c92afa2fda3dfc3c16dee6606b5cbebfd51064b6ce24d28973f541c6319ee2f0220aa04477f112b4aff981f63eb4989198a0b4a691268aa691e797b4605fb650c03110e71d85cf6925db4cb49116ebdbc67a6d742f359c6bcea3cb2d900cd535f000b04c7e132f0f5cdda3635ae59c3d3012759d297c51e04d63ca1bc2d0889b281cc1d3dacb9d00f4b41b3cf4f040bd656b76b9a95df66338d09f840c55bad9add910329d291c4f1480aec2ba7cedeef2b87973a94af42744ed2ade43893b81de3022f03262cd130adaabe77ea411c2a0b4383523a52b2ae7c675c437dd0102f7f4308150326c9351bebb29a361334043884ec5f1a0fb3b3ca07154454b9b44aa548a12460032021c6843eb9db11abebdc4ddffe22ac602339129898968f06a6202c543d7d60030db7d9ef9e0fdbedf00b1703da03105c1410eacbc614bcbbe11523389395a278d122509d78f258a0f41f1b986c1b73a6327d9306953798626bed1ea76a1afc71e6b45be746195038c920b86d8f0cf486ecd9ca37051a995e87a68297398da5fb9030fb89c9225b4a2cd41ad10c7ccfaf43fe65fead53f05324ce8a251ea87c9f8310e6e2d84bfa8f4449f2555635152b6d3e178d71af8f2a9457d3432aba09198085f29fe6b045ef04dd850b9f9f92dd1676c4b4d2385984e7f97a9ce06f920efece20f1fa6e606ad9208766b29bb53356c7ad647bfd0af9a33a76438fd3fa62724aabf1df6fe48c7c5c62020a68432096703e3472c07a5803d49272a5c97c6fafd76d16c4ec56c24869b1e2da056e5348a9be8ff7a7ca22b8cd56131e1d6604d83250d7c0d4ea4a78f39a9a69ecfaeb173ee43eaf9df2e62338788d634e592633ee98555f7d11905c11edba8f5bbfb84bebd6921fee9a61072ea501f958079b4e6ceb53b991fca984fa08731c1bdf5abb008f7b88515e3b53f5acb419f2642200cac5298a9238ca5634792f72074261648c6fd64489d99c25f3a094c38f7aff359d92f4624961793ccb23cbfcad4f3476a554a69089c675fbcf885aac7ca742625a91edef72ce4bbd0f66b8ce561d58c1951c538861afb5f54d11758ddfbc93565aba69ca6a320e1363b69465258de81ce2f17588b060b38d3641d8694326d263302cfffde63834049c0b20041ca5b25feb8855330bf100483b151accdb40ae7d322932984de3a5cc535e22893389061d538fb972c4a3675347952295977feb235a17e3e21e314bd23e84b8b34d52c0249f506cbf78c1050f08bcbb5ae484af7ac540ee82f22e274e2ae903976f7a6ce4513aef01c3fd5bf6116a15fc27773a7eac9bd1476cf7897719959051424a82c5f31c815309320d34454a43847c83af07e9691401ad0051b39d1c26705480f6205124b54712e975a028823ece3d5e349a85eec1a2d360b54a2af95ce9fe418db525ecfcd0f066a6397578accae3f442da29c3933c238c572955b4cd935c7ecfd98f95561a228c8dccf60cfed93c694a15bdba1142f2a0db3d6bdbf46d0efaf93b5ac2792379a489e25c48d511e5a679d814bab2c39164c03ffbd18afe61321a1fb989369b105313bcfa6796f90e302893937dc0bf322deb0c25224fdace6c0180013ecf05006b22feaf91f1532729fd4ddf00c95de36bee33d213cf3e604836bd2202ec06a99dffab0c7649cc6edd8370ec3ee4c9505132dd2bfe267974740e67541538b070d33968bea86c66f3297266f333cb7bcf8c431c731c7b840d78acf88974cb2410d567cee8a7edd45a56e6bc5361180b8cbd63f4955d2e791fb270524adf18590d96fa8e9cbc7e6baa3c353b64dd8b1f6c3b1c897a0f62d2ae51bad28ba58cf0cb995ef930983fe4607374b4b140dc29705ea09ff246c85ecd1890d0aec00dcd43e39ec3c5bb314a8bea8c127a1acc3609000344d8b59904d7e29bcee44e81cca9a7a2bbb8de4e0bfb923585163c1ec143ee3313d597cd1d4367a9208e3e229b5965f46d24b4548ac23e8cc669e1018ca801ccd8d2082cc08aa878b8e8edd17e99d1fefecf3ea73443a76fdaa986e837481b7fd75ffa0400c33917661171e9492930118e30a9a4a14d9e28de10cdf1d61277da920ff1aaf31ff09856de8313e9d72ec13888b032ba10c94efec4e2237d3a15572a5415b12b98fd72238f9191a248d33c5e8df61a970e06a473410e46b4b94f44a12bafcf7fa7f51ec593a1a3caef62b49c96c626c50dbee5348796888d43c483b83bca407d313802595c118b937e99d82b619efee460ba07a1643fa9d0c976c11857bd0324ced7340201", "5151655351", 0, -1242455307, 1537743641, "b59e779a19b18a3e1b9e1524916fd4e60b80b61cb0639e9a4dd1f2ff284c861a"], + ["1100e1060115fef90479073c9896fcb2416e0506eb0e1203989899eaa3c56b2818a375353400000000076aac53656553ac93253243013f3d88000000000009006353ac5365005200a920dbc903000000000000000077f1770300000000a3d28d31805f55764215620606bb7910dd6f4950cc42ba6ffa37f9891f348ee8fed11d16b593e99b6fc9a44e78a4c8df482a16dec8c4e667676a07cc5547eca402b1e833656a7ff79dd0e3beae1b3018ff60217cde2474617e5edea0a4d38aa2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f2546dc58b75d5966b2a75baf91c2211792c3945cf9a87ef07bd7cfb268acb7ac68895e5a35f7fec02f77e24e26a92e9901b108311bea736fac5d69b1ac6bb8aba2e368eb154cb2c2bef49f88422b3ee573a5dca5bc9943ef0d5d47cb8da4a1b1dd9ad4bf786155cd51b68810b9530b3ae512017968aa93bd1118d68dc8444603195200618e6634145dd9412a1aa5665c72b35eb5a4f3c6c960d11b91daf6fe3e032019704a53857a9e6c3bff4d35308b1054fd597461d1ce9f442317e9141e264c0b05bc2654c4f8a1c342373e33be787cb570363fef654c6d24d9fcadb1ce44f91bf20b91a0ec6161ffabe55816c3fba5ab5f787af811a4e0f64f143b83781b668f03075b5f83a52acaf5c79374258791ca777c4d3dc8aca8cd5cbbeed34ad70a4bfd030af4415ed3638dc877b32a37dbe39e19503e05466a7a6bc78e9cac3199ffd85b031d8851f75a1b452067d1df4325a00c85dbfa0b49b43cbd5d7927b6269f27e3010227e95041e4008318bd931d0d4400830ad0ddd17339a45c39b3d3d86ea8febe830328178fa65ac52f13b52b738443c5f385554c8bc293addde82eeee51aa5ecd3334daa20a3b48c3dc82cda8ed02039f1abae00b849b2d59fd2eb838a406e928a2e23f0cbd416317669e6d1dd864f4cfab644525077d96d99b1634f86ca18b28bb151f34929494ad28752eea766da03eb094f4827b719a53fdb818a5d9815b83bab78255f7555752f1d67f63dcfbe1d295949798210b941b2cd0e176f474dd0fadad147d4ac10e3a51901f1a6b2994555de0917f6ee515146de039755b695cbad1f978c0ce1b1dcd1f4c1548d8211411df9d179b9d2ba5a7605d81a432f0d3e632607bc23ff82f4a09d7080dd79ad849510e055831fe9b0f5b7bd24e7aa0e3601d6aeda058db16bcc5cc053f26ec6ef992f16231a911b9bb0e78c712b6824d8ec1248d1d65e200be59f4cd76683c76cdcbfcd27e940021b6744c1b72b4cd6654acec07d0aedd41b1ebb07c7787ecd2bd510ab8c20e4e616ab53515b6da27d4b5c13b1151b49832dc1c580a2b596344fc8bfed380509dd2fa8817bc35fd5517bc1cc487d83704890600f4787d2b97da42948bbff2e252b0e5dc4a7cba082e0d418a1211b3959651af2a501b7d07679cce60e1a07c3217d8d3d35e6e804ea9140db9607a25921f7081cbc06f222ded624ff0150a4405dac02f544a1c86a1ae1227ef94f746a2c7bc99e414a60f88c9a66b375e21809b8482062929b4f7f4737a67646dd99b275dc6da218c13a337bc105c176c777e41997aee2718929d844c82c2c5f59d04eba259892748cd9f2f7ab86a7714acc84c1137f3d67ca41c32b39fa919c893b5ad17c627e6693d7513de6d41eeaf0c1a49017a0da34aeee29232288058e1e21e212164cb14a15cf825844018788779dfea14c5e7cf90a5ba4ed49558ee0813e897bd00a4114121c74f262a4ab214924dec6c904c793f56880e136b1414e7eb73444cd8ef6db742a02a349ca711126a1a2b3921e098273f5a04f4d36ed6559a95cc4bad830c71d0640973c1fc7b54f66be553ae3ce29df681396f649bd6774b0db8baa3694b0770ee663311a11702d9c29f67e9366e35212e027db7cfb1aaf5a5ff4a19531301a67d18b234bd8748dc121ef0a3716ea822ee18014356f0ec02655fb58778f9276c22cf8642197828e2d418e99480d328ddcbb87803b4d93300aafb64241d74bbad08009f0c9f6167477a42067c41c5c0e133b2870f881f1c1b3709b696b48471f12020e14c35fb026448ba722cafd59701138ccbe46a2bdbb5aae1a35c31d333223611d4468643f75f357b934e211517d9ed268baddb835927875a07da2a4ad57c197e920e029dcf210714f4b8fc2ed4a4bea90064b3d79c227cbefccb8e887e3e816ecb461e2875ae115d618c5d1d4c767e409af4b436947357cec4839925cfcc108c9227a77abe6e724fd85b660410da28789b09f53ec0c1b9bcd7b49fcd25e02a245e18a00518b300cbc40d8093b2098b05aa008fbe61fe5a3475e6249933f03f1b03fa5b71bc0e4db90d2b044432b5c94ece87d8fe1061944472edc944e44df59cb7cfbd27e9a0953a39de68420535586cd45dd0fad285ef42fe498d8eab1aec482276fd2ae610b469ebf204fe5a1d647680558668a708ecaa912938a9e30db1b68bbc95b2079a8c19d28829fb60ae23f45a4245f57d456dea43b43716a716afba324bb7677d0d7eb0019edb27a679f6170ded95e60c45361d59a1872925901e76059ebf30dcf31a7cdbb03000000000000000000000000662e402e9bc5f786328ed19b10aed9cf2635ea1fc37a9e6038e4253fa7ed995c3483f4cd46d264c5e88a95802bd0b306116232949cc0382227251a484b77a05121fcc23dee8c2612aac096c8770ddac0ae6d855ada28b77ad3ede8e70ee8dea800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5ce8bcd326874214f347886fcf59e6dbcb91efb6098a87007d712fc67cb3674702ae8dde61a03935ea90c0ef364518c2c7d6c1f6981bde23cb107afce0b90b1a84b0f6dab3c479e17ab3a5b57da5bcefb8591fd5cb93a7cd17a311deec55d3739ea3bbe55319a384cf2929ff85d984462cf8238c817bef0d52a4936a3dbf8240326e651ad7b6fb59d93d72f340bc14a99ae5276f617735543d1e0bb24c22fbdb202202f43acbd5afa4e9eb03f46b1658d8d71583ebe98f7fbcf4ab3f7801bc50b050a08b4323fe6e7add2c909f09760487c5d77b8b53ae99b22b76921f4c240105c98cfb43a61bdf78426965f8eceb94043d4f04a38aade5514d3e6bf92f87ea4242f02151556bbe769eb7009431ea9896f08b93db9fb7cbfa6f9bc6a4e12d10d7b7973020c811a2ce6d7940fd503c108939a672901d664eabcaf5eb68f5ee6b2a37884dd03009fcd787df37d7ece59b6adf9885aa78ebe64900a16653942c2aa431a0faa02031a385c47c9bb1c5d13b5b3ee540a46041ceba4d70f62a7d37b97b1ede2f028f402176ccd6dd4fc2feb734b139e3ef1e3625c29c3a006d2e26bac167a98520baec996bd3c50988faaec9851930c5181e65d158458ab2b247cebcdfcace2af085c452adbe479a716bb0862ee56fcd26d0537486924de1ef9de885d3eb0090003d2d6ac143791b251d67d7d39e565fb14286426e400a473d5047748ccb1e70f01b3d8119d068a49a50322bbe6fc15710eeb40bd2851b4ef66c8133fabfa4f81c708636c9f84b39b7f5b42f09d4867485a80dcec2ea688e1e76d1d059d934a0261b42a76a0b05c6ef948e461137b79f0cc155b7419f6f7dd07838bf46700a1cdee9ee946fe0afac5c71cef559eaa5cdad7f0c5ee5baea1a601f8a1af64d56dfe38b56fa052c52076110412e79ad168db07dc55f62bc3d022aabaa95fc32dd3e90161e1f1cd2fcceb1cfdeca207e02bf97e06868e8bd816688a0f67ee6f9e68aabdad369ce740dc3b8e72960c1d1b51c88aa7d3691863965ef4952cfc6a3c4e2507b3e4202533acdeb05384c65050dd3a7868a6734fdd7024adf5bb7694aaf9b4ba139623cb7f287edbb976e73c6234516c77dfddbd6a726ec1fd4e2b9c47600c336d5b633dfd3d7686ceb92f20c56ab3076d451531a46fbc04f2effe512b72f9ffa343054ecfa1121ea6ef19533fb0036aef788f2e0e2cc04b00a7a1cb9bd10c34cc9851e4547d42b08b9fc16ac07a170a0316e31ffac92182e4ad433c4417bb9ea172ad3dfb618e1453a90c7487d4d96f909376f08b4c765640ff08f8caf522399ff385a02c16e7a36939f1e44df7f4caae9b6c62ffd7afd1650a7bdb2ce0d4105c791d305ff3cce86c7b2a8ffd8b48bae9435e80046ca7f29b062f6bf5c1b7aebc48b3ebee8684c3bb64e4f80abf2e9b200f0fe8e0d33ab659a2eaa35219e334e945cd25e8a23b97017957fce5e6d1859d000169df2c6dabf7c0dd35fe041b4df70c459e4d4fb6647b8b0166ed532c817ceb90bbe1340b97c427bdc19fa961a3f80cafa9cb2e571754a87f05c41b176f70ba4fca6f520fb56bda79b4bd1d772d94e5e86f6f249e989572deb9bb61e79c2bae84ba2d96e0e616ba940781f3648ac109e90aa12ffee938803d74bc7644440adb4119185165807a4c763d7f51879f604db0f32ed5093d4557ac010faee8c14b43ee4c8d803e82a86ee905ac82f6858ce5b61e277a3fca159c2e97941199d2d300f7e6828d5823fb94d4c352fe4dd2d7ad4f6a015d739d602805a40e541bac0ad5960fa566c51ba7900fd3d15d8b4afd87c82fee3e403acb0b58bc3593ad5ef5708a8694d269c20b217961fb098de14fcba8c0d3e8973f042f269175197735359e2540b4cfddb3ecf88cd14806b431d9b773dd990f47395503fc893c4aad3c9f9c94134d8690eb8230789fd60cb058ccad08fbabf9b5e181425f9a1f639d436a17b6907049085af85289190e47f671d7bb3580c4e86c12a4ef43648c516776e39b0567593f6a87966e571bf19723b69420f81a06e5623e0f6ebdb519c33079d49a9a7538688d72f70b6993d39c9895363b050d5a194cf3736232f5dad253e853c0dcf8470f359dccae658adbc00eb966b64e5bda669b1700c0af687626b95194ae86ec1ad5c36e30486107ef155e42ebccd25859dae7eca0f464041720f792a5b8ad86de865af3c75dabf0baefb94ac4134a7b0f404e4968b8113fa492543727cbaec83069e3be10f02917b91ea02a747f8e08b2d360c24295087639cd09c436f3c319cd960c050000000000000000000000000138b09c7794d5fa3de6ad420cc1f9353cf55dccc44bdc06f25d001eae2cf7b53a8dffc83c321a7afe54a044c0e4d795b9c1697920748579d37d1f7f28e5efffde6588aae99c4df71f65d2bc55e5b75905224355886c9cf438ec5d24c865386f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005dfcb3151782c188f6aee13306684616610f3fbfdfcc0efeb4fe01583de0a9f666de7787d2bc4dbd02ff5d42cd6307490113f7f4e88d2835ed5bb07a72010160b430ec7753aa902f35f3ebd65c29bff3ee252ce77a5b04ff30115f116a623851711237c622d09b805b8d030f85a291dd4a9819bcff54f4d4a4504eb7fd27f7ba0301a922464e871d5efdabaf4bea48fc55027260d337105b926d0867527c38f747032517fd886546f7bfcbd35369901bc9ef9e6e6f5f9b20327a83696978099702710a01e74f7cabfee30e07fc494327ce5282020dabee2043d3326d977faa8a1b94d5b80d52eadb6efacb6e38dd20c9f55332ad10a7dea98e3200d032797d2963aa00032accc1266666b55e9137bd93288af35afbe0097749d1e5791e197a2a3b3637d703125f672958f6515c74b2c638ee016d540192fe2be7cdcbe2bc54785b72381ccf0307eebdf84de2f3c7522ae58ed9e27c5eca6b70b975f5cf3b0be39c93525c8c9d0215a2eee6389db919066c5dabc20f4f7128f1ef91553f8e778cecc1dabbbe68c8020cd3771c6dbd6dff1e81a14b90f4f57c28ce70450c6c2c69c89f10226c44b4ff66ea4a667cde89f0e9e3b01879182459a48ce0f3e1f86a479daddf574081b9a47883a0bb5959bafb2d944c0fb03ffcf6c5f0966df9f9a9cca400e829db20b8a25d879d7ecac8c97e48796867d7c810d2340ca0b65731eaa2d2896b9d5475fd2e40a08860301a4dcc69f796e6aaa6560ba089199701ffea5b5c03129072048361dfe586ca7da0d7a6148c5cb7a74e1e8d7921dc8af24794645bbcf201d48ffaf8764f183e0cc05b850b689b78f0a21c7b319547ad52575d5255df91e6c29d4c76f2e9b31981725c0cd72a95ff8fbca2cbafd2bf0b720a2a2eda3e44ca136ca47bd5a552a91b26ad4527fd55b1f8af411ad95794d5ffb06dcfe8180c4c26d71fb3416f6673c20e6885f7311695d0490e714132d475061abae2d170458b03856cbc8b71190d08d5ff80e337e97e0e93106f618f3d4e9b609f767f0ffd28f911c15cb3a8e5a09e313fc307c174f07fc94c8aca77aa713fcccdc38e2345cb3a44c86a6789f977027038463a3c5edc79667e498de84c7bef9c1b8da0f677ac0e2b1678fdccc96fdb3ea67791a3a8a735d5a70a34928ab1d84469570925df026a2ac545dffb193c7693e25cedf07e672ad96104932c6a65232f4772de44892cb98a770760aaf71abc9b2005e9d037ede71921f9f9b86651f222d5425425093ea3aae74a6354bffb46a6443b6eb2da9e78db622675702eeda3d70fc5b62227cc805ec7ccafef7057ceb58aedeec85decab557df9628618a4c7419543a830b541a92e218ad9e6ebb7a63cd68069581db58ad17ca8978dc7216c50cc6c6cd87118c643489d55921895d88e47b1535293b72a2220ad6c6b471b77c116b75225f0ad1b8cbf07b57a9d67fd467bacf2a453401c055157b30052656ed0f9f19e04a7b2a3e30fdfe1b48858b98de0e10649eaf2df51fc0632b20dbbe0bef67fa620882208c065ada663dc5198356cc5db3ba8186e2906e99df1746b786dd7ec885e3a4a2a71538700fb8f06e8013102b4ce60971fe387762d86e76ac884a3d8dfc4979fb176f71d4bd8a1235eca5c9d3cae1509fd43c66137e0bc48e2a905e2f01648106a395526e5f7146626d7cb53d3e8a1d1d748949d1eca75a1aeacfa97f3837d159bdf5c93dbfe17870240a87346ad37dbc8b512eb1ef75dee853adfe99434be8ceee527249eff88ebecf7ccac8c0efd2f196cde255ee1c2fc3c8a309ad019bba16ede96988a533b2cac04cc29d7d4b03d3de251e731a04a6027cadd0320974912f7827b3268385b844572885386ac600af381fdbbe025870b33e603b4d92cd81ac2a3ba000413ff7df17318f6e72c9b8601d7d2bbea6702ce3157cad8ef1f863dff201e9b1c31e42bd8c630c55c7d22431a56d8921348b437612148f9ceb8c5c082c2dd7f547d20d75906e72385ebb93e28efcfb1936fc9c989475f17dd40f942f0ae48e6da6c53723b9e5ffbc5665750b9ee047f593b2c0c5f533535cfd34773e33219fee613fabe4e36b5b05548ef837574ccce484607bbc6344e1cd953a2f91836af92ae1bacd6669a14c4d969d4e040f5fb391e8429a48eb6ba13ac4f304b12eefd3175df1ba5e0c55349462b263fe8b9de8a1b136592f1cd9c52b3c2bfadf2069dcd6f9594691bef23a28fad82e0d4b03793a10c4e7a730a48a009668722d6f1cee9af8311b047ecd1cf77e54c9d90fce66a4ebc0a853b688d01a8a1bb892f063fb3b3e7ff8bcca64b41dffd9f3fc7bc30a283ba57f212b75686680d44599121f114eeb8d04b463bc4dedf4a2f95db866d50ada3b20f0dcc50b2b7ddde34a1154701a5f6e3f395c200440eee67718f91636b820c", "52", 0, -521153239, 1537743641, "dd611c3a574a3b11beea8827c883a3ca865f32fe3602a6343cd7b27cbbc8540f"], + ["9172a3390248debad387849f7135a83d84cdcbe082870630911dc6d5308f241d951cb5311b0300000008516353526a6aac529703eb94b0c1b57dce4766ca49b10ce4c0a697c2671cda22616f5a9ef596d02d041c4dd1000000000451516500fb1462cd04a194df0400000000056351acac51375dc802000000000753ac6aac6a65003ff95c0400000000036a53639c749c000000000000ff05f21f00", "0051630051", 0, 622476469, 0, "0902d020c4b4e75953319d73d972881a42a4f87af193b962f30b32e1e4eeccff"], + ["030000807082c40302f216d6e3cdd47574833e40c4fa00e7f8f12a33cf66f75bca54ac4a0baef962f601000000055263ac5353ffffffff0d013f1f31d639a653f31db70093b8ba2eb9d13f699bbf1bae1165758aa2013900000000086353516aac5263acffffffff025aef47030000000003005363a109dd0400000000006d900e2f74eb579302a7fbd803000000000000000000000000c18acafc67516e7626bea83d2e0bb5bb7bed96043d69262c4c3fb2d0eb31e6d11af153bc03e440970fb0ad3e3d830ccd2d7ff6cfe7c97d3aef8dc5e65e293f15cf760b0810b5ab6593279b4c15936a81e600dcf8293af48d8aae383cd6ff54f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000358a6b6746f7e83bb2ea7f8367651ad4721dd1ba04422a14fcfd90b3f382fa5f7fcd0ef3c58d2680fc3a9235ca017c6e7f75087f3adaf9397bcf3951d47953908d3103c49cf16562b2ff154c01d63966462fab8f86d3d13dce1777fc614821b8f413d9979c52c4d3453d9e453f2b22a121652fdc5f6b3e4ab2e918c60e429ea4030507e2f134f60d03c78a4a53ebf488b2d0b376d940ac8e5aa51e4ec5451e21b3020d92add5eb6791ed15a57ac4b9bd5df5c5e7c08a28f3d8c21684a033385e3e580b077d70b63b31565bdde190b2089f41ee6737d92e24732248d2dba5a35ffbe6e5c17074714c99d08e9f2457840b98bfbbf9336bfb0bba96979820e82e606a76160309bcaa60ec868b5366c9621646f5c2d884515c4469463b84ffc79abdefbe966b032238367a2553f16d5a31aad6481484e9dbf8a3c258fcbe2bb12fdaf6c33131ab020fd66bf51197040ce92698a006a24a1b23d8d9f303854aa3c7537be6e1cf441b0223220af4cfe3db0d6ac3797defe583e4ed1d85bec22765f054c0e4dc839481ee031f5e26bba0701eb3c728a4f5725f7df96745fcbbc1190607c0657538758a8a7d82badaef2952d11cd7d23c7156cc8bbe21de46a67028b61a96acd13170ccc69493c859d8bb068634058f2e3f68502ef6760b001ceff4449e82b35ad6d7df29a11291437eb69389a1c1064136f56981be8f40f00c5f3fa37863c465aff6580152870dda23a26a7e8c002aed0602eca26e6f49212206e3a1813b1efd5bf13642f9a59effb0ecb33026f631ed9464dd72cdf8ca7466fa2fae79347a9ec571cff04eccc3a63d417c4d8dca57d98ddd809640e1dd5c44da09750e2d015b14647d8681fd1235892c04e532b167fb8822179c2c1ce3633c0ccc988e73ffa73ae46eada7fd6cafe2e648c856187dc9f31377099c3f9751a35c44f0a43462572ca3355ed86b99bc8984a329d392d2b17a3e7668bf8ce57c5f7bdf7014311127fe2220981d1f02d6aa81353cfb377562fe67462ff85ff5dce077fb2eed642e3db31f1c0d3901aba32ac544a38848d8ca7f9672035867f2a2ed0c1f17a171d8116e6391036d0783b744e185e8d255369820468ffdae3b441e00653f40b1f800be83b5da50ca79f5b4337de286c53ac79752a5a0217a6878697f619ff897af75cef20fab627797166c37befc07d64d7bb831662acb0bc7a4acab11588b1f7bd66b1626e8b4fd718a41f42063d2b257f63bcf78c6992fc7699b28b723fbb645c1fb8231d341728336977d7a3d6680f994402bf2fd3cd8680dfff2fe18c8523b8fafa9bcb8eb962860f7e9504496d4095fab9be9240ad07565efb24075363d122d2338ecaf72a6aa0209ebae275f37364b9caf5b7356d5bcdad797bac573f70513124e11bda8fa7351c83ee26fbe4521beb737c33b139348295748642988dc8daaac812c7326c319fb3a7e4893080db7f3a3974dd44b8635a41b847e70e45b13054e6d04f8ee19b9d5d5b2edbc29da3e04ba676ae25d1ddf3a46aa43bce9d2191e623bc075def3f104c7ad8fdfe22041cfebfb338c12f92a6b978c97498c08fa881385c9468b217873134688592fd9eb3f0a6ecd8dee7da29e1c781d5db2c2cd5b64d6ecc754b5a6859d12ff2f4af27673810f58a04547177a3c049d8f6a2c922f1336c6e86708f2c9d81878b46c7d354b21146693a6ab0dbf3b6627e536ed6e8e3ab766472f8dd80aee3d75590d400e70aa64f918df8802ce5f3d1d47f70d95d7d7669000394d70d6cba766f34537c23feeaf72d0698d242f5596a219bd9d2addd9ac1da22ccef2d0f49fb6687a57112a3bd97e91a471d482d01101e3f3bbab1f6e37a3c63a681796064d68965a08d911fd431077a8512131c14749db9c00751be3bc6233a251ef08d8ebb3f336ec061855bb23d1b42900332831da214c707b3a15f321796ef0de70cef6e7efb6f79774d8000d01d92f89493a7430b6a5b611c3d1c73a1e0945064484adae5dc16b8cf015b6b6c3e70e1d17895223be90833de940358b83cbbff41802898eadb7c113ade9134352caf27087d04c745620bcdbd02b5cd060a85ec2e60c501b01fa9168e235ebf7800394300c73c158723912386d1da30d9374f23cbcff150cec9ba4c2e09e3df872d6bb786756ea153f2bdb7c8642d4c4a31f927057075773c443ea0870927f8e76aac9076a599d78fc05e00ee242085f24b10e3673f4169610f693f51841668745448bc93ef9942a3588162aee36286e518ac9d601613623849bdc59d83a124d9d491c523900000000000000000e53e104000000009cf1bf6b208b50559497a31f91732fd3f29675ddfb5e26eea7f88fbd27a104ba36e3819145e460119cf3712a219e4ad5b46cb0f650ddb4418ceed268406c84d338a48ab153238c77e73181cf59f338701859d0df790e5ca98e4702330cb5373e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3488dada63d2f5520dfb6d563d8bc05206565383f76dc613a094bcdc0b49914a771b7a7677d6ac9dad6c295db8a8f70df36f1e1475a67deacdea38c79919785645ff0039211e0b332c7ad4a9249380d700e45e3877d4ef949feeb26000c2b2ecb854746242b906edb5236427c7e5a4db63c1f63041678b2a71c9665f51b11a50216e3e151a20103185547cdf9550368eecd187f7408307c4eb1fbd20086e8b87f022e5e6b057456f55f9cf09051b598d0e3427b35a2c0af5ffcfc639259f83f82610a068a66f7630969db005142d84d11d6c55a9f6514e7ba193ee7d70c7ffaa5177c91b16f5bea3df5e24c54784276ceec4de6e6655032d8876b7efb06db30897d9203209774a1d02cbe50bd54aba976edb98d98f0e57e9b93693198b27eb0a140ed540309a1ccaabb67db479fe35e450ee9a063af5fb67bc6628b09f3ca6566a1dd4191032e5c82169d05d9c9d4839ec7935219f946941a1dbaf3a531a7c490b552cd00be030f01eb927e141e3461bd91887328642455ca5125429a8126982caba20bfd6467021e02f440a5615f8775cfc2bad35044acefb2a0027162d417190143e97dc609f0b12f01ec12f21ec8c03aae312d5e94f2f79a1ba1661053b4cfc15f9d5c909548320b3308dcad892af20eddbc1aaa770f2caafb9ed31d2c2c813dc1032f9dbb75c612e3fd06dca4e78efdf75c5965c18e4465cfe5e342d79279f4f7f6a0c1cbea8b376f243398c7b528f20f966d8401d5f61a9aac032d933fc32fd327b390f9ffbd05c35bbfdb5c8ab784be1190c02028b8f81902a73512a7372b5e91131bf924815ee2ff87e13b6d96f98271fc60408567da281cc136d68a9e3a06413e7492760caebc8d31c1e82c1e15238a7a7c33d2b91f5a34a7d5af298118227320abc216446e3bd5c776b1a6841cb8191b5e2d9d1b495b7b4270877e7da8f6e1b1eceba0274a14c146aac07102edbf83b39fafd7614bd115c036b3d156611ff2406ddc7311bbd0e6909cb5bc80ff0d430709f1a458ea880c8651d8a4c022ab8bef56a9f02032a9e846352ddf5647fd4d7eaa94e3b038584590bff7dc2b01d2fb48d1cf0e8bf6f0144b14b697a53c90dace5c5879b89ccb78bf9b90a20d7f46088034cfccb532901b7422e3c17f55f8df9d1b782dd9df4d6259bfe4c0e7aec3ec4df867ff14d66d697fd211d53f29ba8c7f30d05e94efa1396f560663d0efe8eb5ab8fa2375f674acfc65ab56f30472318ad8ba6f95b45ea402efad0f2f17f06efcecffa97c0194d825130aa88e6f36d3b8b6da5cb5bf6828473dc5a4a1eb1fbc8636bc5d62e45d0ab55c9930ecdd2fae9ff563d01caf6b32f5374cfa75d62c2a77b3f701a10c2081649d7e6030852d5842acd778b69b658f72f140b76e1598a217abd1d635765538109e876a2d49a5f681dbe9ce7641ee11248a625ed893884ce90a33714e317e6f3bfe7814a1c09c169acece2ebb4e8f88500fcdcf1d49e0165e1be146ed7a129e64b1dc1da58467c932f149079675590840a22d89cd0654cfb9717054195258aa55a4d85a06cb4db935111584ef4b1f1041faf71a3a0b8d84cf89c8f39e8d3ef6ccab3ed539a1fb094ffce70fa8a6572f5933dde2cf0dfe2d287dfc8bbc56c6acd7a83bb4a1bc82f399da3074626f7a4df11f71f929a177dfcc06893698a7340147a332719a49dcdafb205933a9230f8fa1873a58d08478b069163290b274366ebdfa17b7c99464d45690826a1bdd2b29384efb27d43f7f64182143c248c1cf196f53bc5299813cbe1619c422f8daaea5ed227df209f4808390d57cf16b96c69634a704310adbae2d9724f5cc38d702ff0056f981a07862fa880be65168656bbb233979d27ef55e9a6fa740210ce5f1e53f42ed3ed4c4aa23db839025a762d399f64b61ca7c188208eb1f7ecf8752516735ba7193e80b60ca4a8068dec563cacf3c6c9afd0986d781274b255338f643c961c81e9c2982756a8d9dbcc1ee5c3952a8423d91f742e9084f43a0427c3d7de9e32853adceee8b4389416854cb32972716a224a17f46544d8bb93681b07df1cf6be92f44ca0d90513394e56a6405a9bdec8c70d165bf526891b00f0aaefe56afc61fbdd2e6b04e7aa43a8f66c2473d99a520b166b4bb46d0828155d6f9bd565081daf402bc3c48706fafc94277b32c13d308038deacece01ba9bc4eab0281d0d8fcb0ad862db265cf0d561262a4250e670b5db52a723c97249870a98f647e7eaea2b35e36908b660fc60d502b51ea081aadda7abf647f702352cdf8ff765dcd3fcba83a3aabd8b8aded0be45f87083eb54cc514e17c8e734beab78e680cdb43cffa728087a2dbce873bdb026b41c5f2b35a5c525d84c525f9fbf98ea51c55f1355392beaedcddd280ef025e4e98153f161b98c7ecf48af29cd6477867307", "", 0, -694020789, 1537743641, "eb91b5a82c6db796777583705df2d1821b326c68b64cabe38a59884d54f56434"], + ["111f010c038c4294e4da4cb06d9fc7dc1d67904eedbb5e6fc173df1ff6fd7e87927e5bf7e603000000096552ac63000052636388e64a004bdca5936743c3c504a19fe29516c4ecccedd06ae9fe98862249fdc7d2e302fb00000000016565ec733c7c49f754562f0689280ffc81ecc8875b226f98c221fe2dd710c59dd7ee63f5c203000000085151650063635253229b6e5802249ad40500000000036a526a32393701000000000663acac5200650000000002744357050000000000000000000000004b1ac16b7a37da77528b1fe4fe2bc8eab61f9930e99eef1d8fdff92b16dfb21a72154e0add5c96842d1cbc3d0ba26c2328d73a1b56728f9ec27412895edc6189749f16aed63310662b28a45263b63dcecd62e8296d5fe968c82a86afa90804ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2878aeb3d3fd6fea86e2b4670e34f5a338a3e01ad35bf43e064ec059c24af46ca56a149829e5e2d5171e95c70c987fe3eba69f6cbf5f380ac7a8d55213af86e08b3f430c54c70a4c55cd51f94d3cb17495c9d6fbc70bdffec08a161ec09b31e45ba24b8366714a06331f1cfe22e5683820d10a60df9c4bd1b69c2d439f7fb0f0202a68efd9a948501516da64308a8a8eda001c12ad09f3560902d5e81551c04ba0302727ef106116d4a5a55019017fb3081fa1380e0f8fb8a2346f75bfd1814a5f50b001e891a54b41f05eae416bfbea56707d85db34dde04e7cc59c5cc97cab3b18be3421a8a504a718aeb2c7aa5ddfb3f828dab0fa5737d8666960767da5810fed702134215c422e958dfdad54c2a65254ad244db65b4bcddae099b6a7e6c2bebe3b7021ffc157ef42b8cc0d80d5ebd85a7208cedc4b3af4b46c9ee6b7419b886c4656a021d1e71be65aa582cbc17e3bb9798d668d34143e8ca7e2b6b1fb0d75263178504030580d2d151897f403cd5e21d6b9a6f2ddafec8230d7f86652c08003078c37a8a020735e9cdd068706771a738181d4c459b7ec27f0dba6acbf26e39559f11867de6e85f7fcf25899449f8f6990b791528df57a00f479f486a7f7b8c2936437426efad969f71ed78777486bb790da0252f4b64c32e5a847b456050bfcf8fb15390a8d6e756c2f974dc671d510c6edfe122a02e521859b455942aa54ccbe1c02ede62374dc0e203842de7138d2494126781b97aaea44d7a09069ade6bee1476104b06a796aabd95e97d9e13db960c2e43770b578cd190535b3b01b320511792c52b231a66c1a76e4e49dba99b5e67d92dec21c7f33b66d2326ccc6a2fdc7254d2e0daab33aa59ed6369627e1715a429b802af1a01d997d680b1855dd0b0a6cfddcbe6cf4f421c53dba97d63c661265f4b604db0b03b69cd29fb1381b423533e514dc66f1514c4322fef2687992b6aadaca202ded7d51f5d109570d07f27e5075788ee0b310b886c9fd62e451ed8670a18f0f6863b66e1bdd87f8d257793813d32634366e887c5093340e8caab1e04984e662aa0a56ca1db6e6e5d5c5053783f55710985a7a14878c0d92c4bef49cc6a31c7676cb6c3366f97b30221722064a2d65257617dad9159308f71ca9fa11cd2d822cf2a5965ca759e0cb35eb65ed19cf38d67d8b939120248cff48a4e6e9344a518298ee3e25045c2901f2a4e0e5265dbda8b5e3ee84fd8b6f933c776d41cacb3c35902b6824792c9794254eb6a496b7b860baa399d7a2740d8ae6622409789303972d6b42aea7d2f7d7860f28ce3eb449b038c68cb2701b526be236d0a8374950519e73608e4d869bb497e4740998877650000b8a5c3da062cf1a1e75a0f0d8216d3e44cb6470d3e22dc55987709a6120e11994445f18d6b5c83f29b8ccfe3f4ff88e498727ef13fbd39077e16fedb29a875000f687586b8bc3d8f610d12452552a6157ef1251798e61febb1c5dbd652b1dee84df4bcdde60e8fd2b78b375fa946595e74b385f87ac9f9c0f118c1f2b07d25e57a27fb473bea3b042377b7a35d2752f9167680ca4269112896986bb08f40bfe4ea1d83c1fa0aa6138de0fd6261919b0c82e1f0191dd13d9f074d3ca4f0b77ad4023028b566268bff211bf35066a17eec2eac9ea990ffdd9e2491849d1a13a61b149ad6de9c4b3147f37ffa1c2d7fac4a5702ecc4948f31cb0a41886c5f5b314d0228a878bb4aaa41919f45869a95387d2f8e1ca5674a7e987902be60b91bffe0c1a2e5c55a2130866ebe36276889cb1d1eb461fa275e798fbb41053ac6ffded7213ac44457389e48775ed39d787e4b9ab9f72972d7487bbcd8cff0ed36fcdf7c9c12bec8bfa6791850db5b59422b8d2908b5f7c36146920cd21f24ea1e4c73b4c178dbfd3d6e56b592ffd93250e022606ad1fb3cb762b8e47274cbd58b9c48ec3cb5b2647ad80c289c9a6348ecc555e257d9b863665007ac439341d79dcfe4dc6f6c4a8c4be28620d1e64cb26aa6c3ba6b9dde06b7dff73a066fb9fb2896add35130c7bd22737bd2aa0f1d778a9595c2f8fd91e21b08b441884fc4f2295bfb65eaf581cf31c24a0724ec5cfe6afeb7ea1317c339a40895c20c1e5fe359bee71cae588272ff9fdfebb35f5a7939e3a446fd34dd389d94a9d46f87ee9778e49069ee8f40ddcabcbeac1a716c6463b218bcdff59f2429c2e8ffe933bf9e5928cc8d716c3e6a9833c36defbd3efc6e0711e7578c0b5b7922db2c0e15cfdc7c9b1494cd2434c04f46d68de0ca0c47695619d7d83ebe07030000000000000000000000005faf2549b98320073e1a4b451769fb2ff4776be93961cc76e57615b55f1defd23e0acf78019a7021472dd5c9f30006c360a47d204221f17f9761a7a93a383d67a0735e19ceb0d8caa65b2ff30fe04860577937774e0fd05363a32e20d8837f820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078ab9dc457db4cbc765cc230f4c7bfee6b20f788a1241767b8ddd9c6828712c2adf985d45b916e21769fcea079c8081e712fd0ba6f0d665a7740a126e671da6a9572d54402e55babfcac51bed017508a3f60077dac980ee551fe47864cceda9d5e5d63db816e29540e0a8fe0c5ce1f136770f2feaf0a65b100edaee1f8aacfb4032d50f804ff0e262ca859f8cea40ba17ee037cbf0b38b94618c0286a8e9c89ec0030b2e8a6080d5380b076cb70d476f2fff00f991912270d81ef08b4025376d208d0b035eac35904e3e7586668ce9af2d66d4de86b2f12df90a59d4c014e335c417a1d80e721bc4d35777ac0e8c94d5ae8716adab1147fec5d9cee39500162cb4b3e803025100865c09632324a3785eddde1dac3ad1b8be69aafc01ad2694bf0977446c022fd650ade73cff124fb0b727efb66c7e3c741a0ae6e0ebcb9eb3a377eef963ad020fbe203a1f093d1c284aca5e47f54431bbb88e7b9585bc4814981f7a942f6c30030dfaf4fb530f24c32a19c13be12dae725741914e4fa93494de554874847acc20030db4c17fdcda6c3e7606f6b11b6664464d252126f4b0a401477114f5d5e353b20e68de48ddc8f80f497bcd327d6a149cb404ad0b86d948ef03952b4dbe89de7b4d0167ca7a4c5631008ea31647a78c9a09d36b35ab1eb66e08488d4a71b7c9208a929420b35ea2d520c6f5ebf8fb3ebb05d37411852bc6199438dc90ea4ae157754626c6c1adf96186a4822c049d7bdd69b0d084f714712594167a2e52d2dacdd736c5719f4624b16bad8ea63137f3ac6a0a02bfc79990204d25f1881779f8ee5cf3a6ba9f9190eb2a77cc205e43b053f53d76abf51728d4134d5e790161ab6c199931a4767b1464734db0a3198e7ead60480a6118eecc31d72166b8b150037d4b06c5e97480633dfec3bf2b0a6668751d958fd22f58f710dc4c25683cb76381ce60a146a3989453ca2340201903f907db6451759c39151fd24f32e455db687afb63b28e83c1b05ee248a1eabf5f330af5e3fe7d3bfb94e255d385a05001068d641d80929ef5e5016167f5f03b8125b25b9d2a2c6674b186af8dc77c61b455e5a36c8c760f25e92c2001af3ce16d37fec75ae0765296a734f41f03e216deecf533ade5b8fa1e41fbc7c50cbd6bb4335cf2c98dc2d114a17783bc462db109b2765360f285001dacaead0065a2ebd5ae939433ea47869bc8a02910a147ffa4ac848889c1c71c303fb0738681b5300cc7f09e08115ce87dc0567f89e6890991988cb5549b262e4ece3047252199164880523678c0c5057a5bae371a2563c3e3038a698e49fed078add31af52de9d7dea29bd664e10136303b35e0a912801f174f78d4e3184d5c1ea48d4252468f97d47b1e64118a16fb8b0d2caa2ff1387c819376233fdc436e7f9619b34160df8f147d0089661f41067d7601f905f71325ca4ed2948c1f5320f05d2db457eebfe8ea3765e025c32c1cea5e0cb90c0431a97ad326404cb16053263c4fa9e9dcb70945e60d76496db7e9808b4c276abcc8b71b6c13a84b38bc417c66b1283b2cedbb86db3bfe186409b028ced8323f07c3f808f12480b173a20421b0aae29186ece8c180a2cb5feade90ef5d09a9b064fc71bae8158ec86a3a5f6b1ad6763de825273a4596be2288fbb88d13cb7c89238904231d9487e55fa9854037c24c6f82dfaaae93a21c7e35564e2d020af9ad36d590d51583c45998de0f78dc02c96c37cb1d4e05bea6a2f9e449fa72ab48254112741259fc819947e689e75f0c87777e27e15c2c7903a5f8eee0679d54a4cf20bb7527571ba8da7b1534fe3d31ba18b9097c3bd2b455659616b3b794dd66bd97baab2fb983930002853160bc97f88601fd881c7c6a75f2f27b3792784ecd16db79cde377594aa59ae9c1cbdfc92ebbebb982b84239b43afb2d6f655f25d457b1aeb32b3d094bffc3622ad1b5b60cdecea2bde6fe387500926d235a81682a31badf4211f7c656225038d6f4efdde134e34f45ddf89d71553639b4ac4b274053b4ddc45ef897d0f9254232c78056fd39e434297f9e0bc2ff60ed223aa2dd6ebfe717909405d92dde59233afd84ad5291185a0de6daa6abb0ee403d493337fba183ae3f89fd0baf9ed07c1860aceb62f5b76cf4931671aada0c0804d7b899191c863d4e4e03e3dde5cd8e4dd5328b641c200fabb8309005747e30cd82d456bcef1f04e409c57d5a5aa7b3d64f4e89f57ef1a0f065b5caf2e32a457ef2655e5f3c0817168b4a2f19cb9569813d15943a240d343b1ff030a7d359d7deb3927126982f8d2b85fe666934cb880b1bd56ff3cb5d4d3020a22a71a3b5f1f739287e4e229e55235a3017d2d8dc8a34953a2003c14f619f234e2ca64d0f9f0b2d93df401cec64ed446a2d95148dba461f6e022021d57a0083b9ec1d0a", "51515300", 2, 1510545828, 0, "f3d48dda793f6d8c6a22ded6b041789354c98e305a9a90913e3a01e8ee7f8416"], + ["030000807082c40303d94904561b88e6c5a09505ada3d18d8c6ad8f5013e64267cc54e33e05d53d219000000000253ac0be9d207c0ec2d13c2aec5cd9ad9fd98f4b6322e24ced7b429c13dca5d4f09688227d189020000000552656552acba012766a71460e400aaea7d5f1335e05acf6360270f752cf2445075f37ed86af5e5780701000000085152655153655253ffffffff0342c83c030000000000629d11040000000006515352636a6a8fd602020000000006005353ac536ac99a33d500000000010164b800000000000000000000000000347b62e8d36a860095a2ec866b1a0e9b8e820a79fdc6af664ab8c599c882511685f65e3d9eb3b5452e235d0404f589bf156b3a9cfa8ae9b5d96995834f7228511be1971565dcbdf0989e81f5ad914e32fdeb92fae6da36fa79742fcfdc048c6100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000486dd7707b5f90e20cc4583ccf26374af4df303a278d052deb78737ccfb2a6e951d0613225634a67c915a565e212ac22b88ab7cfc9384e859fa859024aef86b6356023f2bd8bc79aac17a89d42e1ed7b90e0662d2e2edbf099918cbcca9b9c9126b370d7e7e3e30cd5d045ae1fc6c6da7b0dd8fbffdbf818096ba4190d881a0703188bcea12c7e84e366ee78d8cee6cc3cfb72c8c0b52e1c3696037ebdba9000350320780339f763a006ff3a95a0f1fbf29fc5d3beeff7e4fd15d926580839c9a34f0b084420f781a866c5bbad3722696e90d3fd5486e4eebbb2749181c80ba0e29b6f3e9ad21f6a9083c5ff3e8c5179f2f13ee12e5e8bd2f017d0a7464f79d9b3b53f032953236378e63e19b75f5d6d8ce7195723e200e8470a8b54c9f3cd2904008621021ed70ba61d6b5b457bd1d9184970fb7adf0dfca7e09fc9f9adb34f6da38c11790204c944225b6a7586ca70d432d126fcaa2890b7ba44628c303f85322e6b9f452b021d928d43c8dcde1e1f4be5a1f60bf30956125df081bf71b7fe46a386c8a9d6aa02029365fa6bbb11ecae16d533192600ffbe00b66e98777be617ff4bd5c308aa47f0549134ee8cec2ee5b5dcfba595cbd72e25eba041539d0782cbe7618170e6a587ef0bc735f8ae616db0d4803c22ae0318d3fbd3a93341b68dedbc68bda5227f9315c40f41a8c8a117c0d9ea298c5d9d0a00b427446ad4bafa8893ae003c0cabc945f582ebbe8c32805ff5b992ddb1d3482fc86da8cd42e227451621ed3ebdae7044e126dfd7278d34a27514dfd8a70377b32d27be17ea8155366c421b73490b4c72cd6cca1eeec0c8560f5765f225326f56dbce84f987e983c130bec83ecf658dff7a9625a73c4746dfaeddc34210cd3e8e545c032a3d7f1e9816a8a9803a61f4337db51d07ebe6f296ff0c4a461d7a00aebc83a734751394d87b270546f0e666fbe46b4dbdb69d989f481416cc5d4e14031e3778100b9abc98d911de2f4bae487335e60af222729f64751512d8abfb0c0e625f54201f814197ff9f9b04385000ee817275548898a92badf86e3f2ff489a57a69033d0ba18a6fd7d2045b5b228939efe1493dab9d5db61a2af685b639ad0a866bccd348346fbd6fd65810f2cc498e2d50d953c145f8eb43b6afd301bffdc6568b9fa889fb31caa609d0bbb68375e91911dfa0b560e3413dc3e9ed63fbf08c184647804abef87b336a345694b8164fc25d90cc89b85d5e3d63007e34b1731432b925caeeb82029c412588ae5a635d59399586cfd194a0fb2f3bf006abb008b85655b2d6160e002691e0edc6e301b928f14bbb1aabb482ed776d1f0becd533033a0a070235ad98eefda476f26a18d0da419bb0d8a0da61d2224299fb04d0da88c0c6e9ef097cd4fe94e53dd01c0ec882c9d8d1d8149a9b2a4c2b71fdecd7c09f8b7fe533de80ece6795ee445efc219f0528e3d614a1bc1e7dee0133d5da7b0724109fad1c52fdd69794de146b6224cced92601df66570bc1a9a46b97cbdee8a62f297bb24b72d8c662ec1c11865aca842a225aa5f768b9a3842cf307754ace6f46b0dbe5639b9dabdde9b45f8c7fb178b70759ffdaf3d749a294fc2a40926728905df8e23dfc38b0368f8402a25289b9a6ccffe3fece5408019ecb4a7a2eca45d34b091b6f7400361daaecefee6d356133b4c524b9157f2f190bcb4d7facc02408c37730f9b0d299542f773cace85265296ff1d26b7589023dcfb9d3be94fbf1385b4a10c54341b01dc52fbe3d7cf86795cdf692fde6fb6d6bb91334bf79bff0852db4dee42ecf93bf2d08c5a18123dd3330d1792fa79e7e7f532610e204f4cb7266209aae5318302f1bbbf9eff84209ef29e4ffd6c632cdcf10ab3e4135bf67edc45c1c8e834fc0a2bc96c0605869b76747445219a6d3fb0cade1b03e00591b38a5f77a304007285a6cfc430f016cf731c541811f7bf254a5a6ae7a7d76f2835f7c80338502e3ec0317b528c6fb50e4f4dd74c06f31cebaa3e115e22f38309064d20c1c158c8002d1c1618bb5a0012b774968daf317db73ebdc70d6dcbb3b0c80ae7e573311a0dd919e781926b661c9ff22a4402d0493c830a54ac12807847cddc469e229ab579bccde5cb4fb52eeaf269415e29f862c1e0a9462345ef31878634e0d4a141c5d1f6295b6aea86361bee3e38a5a8314f8fa274558b825b377a7fd79a202cce00cd4a887eb84c653d54f3525336050bb9342825a5e980f97b2dfc905ac688d263fd40f4e7aad6dd5e20d2d8b1524ae9948e53e5109a47577243e2d3d87be385138a4c70266d71b919ed833a4304868677498c1850a705695cd040329975062632af38f1b79aa87ab5572d86d3e3a492ffa9051933f0188ff21d939d441bd033be9d902970c0f6579c962dd7bd9bf9eaf449e48fbaf54df8d606", "", 0, -1338298954, 1537743641, "1307fd92432cdcd615b6a4c35128c29f8afbf773cfc0ca7e6b1062563df903c7"], + ["030000807082c4030307b7be7afec7eb81507e46e55e99b2b9c7ee259e085563aeec6b22f7144d8b7f0300000004635163acffffffffdbd521f6563084cbcabde0a8708fcbfe54a6f1a62b44d4fe9dd5cb20283e1a680000000003656aacffffffff06dbe0e6cdb71767fa3b25d3f4f23700aac746128be7b7f8c028c2469fde2498010000000953516a6a6a6353ac51ffffffff017e5a800000000000030053ac00000000000000000140567105000000000000000000000000117dea80a627db26877e83e88b2ddae72873803da7778e6240c610b69d2c45675512c3518fa5e7865af73b7ab616b6823f5ea79ca666d44e6e6ba4bda8357291cd95ec278f6762cb8c1e46eee59b141329639b8e3fdae5a2ac82c35386d6d48600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f184b65d914837561d562390305885ed18378cbae16ef4c203be3345cf14fb41d255ddae97f1751ec7c90d6b6e6e82d00af9bfc7442828615b6b3797dfacc406c47493844eb0cc7efae02d61c11edea560083527127b881cc841be1b68649d4e2db9b36916a3e9979d0db6be75695914c2694320e5cb235e67df520104c3d38b021e550ee03204405aec4a1e51610b3e8c37c687076d06241cbd12c3dc6563de13032a420e0eb05efa2319cea1ff1d2a0a2754dc71903c6cc2aa979be23cedc2adc40b011c9617e8c102a36c81f69f5ce91dad05e756bf75ab059ab05457d1a17af2f9616d187ea37e58ed91776d75f8e8dd9a6111fa88bafee2a95357450b5284905b0215970c1300a63975b660b9cc65b4c0f5f03402f0b23b7e80a800a066349ad4ff02063e38702be128ca12a3601541dd051a649913c0aa4d6c9840927cdb753fd204022b2678567f3db74caecde7478f3b847a2e6c42efd870ef749173bb22c027c6fa02077c77cb740286602491614d10f34e1de92c6703d57b91c0061ea27d88117d53030e3c8a4bc8138885def42d29ca2d4eb45470e8a59343f95aa2da0509c4d1fc8568ef4ad7119f857be19e83b15b662d93c9fe6ac0c88c60746a1c0cf02fb9db3e687236541f9d07b2c89d9e1ac633c7e75c0be75bc9000e39ba44fa5a15f976d9e910a5a709ccae1083f0d0b50cecd410a3bb581f7488892f6847d6a06a13bb3a7231ca16323e1e240e0bf74e6c3fb4da53d23c23f6239bda7202d4293a3ff11e7a5f1d24068b87580555e3eec9c077cc9bfebd9fc1da59ef220d922ba2c5b3e33992b3912687c9be79e8b78b87d6aed748301c7afac94ed59c6d8e568f9eb8416bb77d613ba48c387c1d7ded141ab0d0ddc3a777b5ce6aceaeb0d103b09ecb7a703392111fbd3991128d0b45a5705ce1705d80877f139324aae743bb72c243275ce2cf1d6a35fc2ace2558b82608fd69955642d21385effc06d208ba0363f71e512714580942c072a14f6c9396d1608b18d3b93d58410589121d21feecbbbb095d7d42c1bfd92f96cbae18da56e95b9b8964af2fc442fc018dd63095bb983a61487a3018173463811293b05890d24cd78ce2a7e6bbc9892a67b5fbb5990a0c0cd5d3ca932d2143cda2d4d2690c0c6afcb2770ffbdfd2c65922ce565e852f0d36327ff61b617a97e73858426f8737d32c0ed54346ab620ff34a7a55e26f5b367f02c3253470d1874df42ae040935537c61bf47f83d2aa76bd0bfa2d777a277c048cdb8c89936f427aa98fb410e46b852afdad7f91ebee58d1681d03abbef68bdb646e7320a3785841bb2735a3447af5ba327c1d26c9ab96ccf0e9bd26bba2fa3cf1fef1717cafec70317d32211f318ab21828f06d01e1414ecc69d74d43491120f9831e003331dbaf7bf3da483fe7b937329a880015b20c09c3c43cc64df852eaa0ca65d03edd22a17a175be4460e4992937d0f685c437d2f4f280d7aa237b7a0e939b3eb28bbacd821a6f4db61ded0a0798936859fba0deeeed6786f1c1a01e491339d365b4bfb1105fb66d734f2e2c731302e786fcfca8532fef381df56a6408b34cf826704255cffa62af87ec54735e6da018d01b72f5e2c0cfd256a8fa6569be5f5352f47ff8b359cd8a7fd81522d684f009950f9ec1759c7ef011ef095c5e916a4c23c46574e4f83b35146b6371f24f0d29ca3cd675d0e24ae049b09fe4a0bfbd35ac10090b0c2f7cd75c387b6e95c7ce2670a5f2c1799258b0ad53da4f8df114751cc02d98831db13940bee3e04bc11362d38220380e034dbd37520a6c8f529f5e45e656c95b4a6ad4831ae8996fbb1b2c1938c668a7c96b3b7e7a20cde8189a5d7ebca81355d5d63b3754618e28451eb055f272e0053c226e720f2b3ef114c00978f72699e7c422a942111209819bf24af1bf03d3ecd8014c345cbc6f9cc3bff8b576ef0f7dfb035d6bb7df614a0ae3b1289219936c512c1bf686a27023891a25d39fd46758c48201540ad36beba5ee0098edcee00cdb82b3d82b41532a3c91febf98fea5f639996ec4d63ec3e8a8392a75471aee9d859257150208542e9150a364ccac2f0466626ff5ab9b82372a367f33db398a107b773482feed0141322aa9f685ebb9116c7bef066340a5caea65fa989d7fcb31d47a292d38268d32d658fd5aab5a0d4fdd51e2f580c69829efa60bebd8a2bd3b3f3c5765e7befcdf0732c1c6f05c56f88c4fd7063708ef5d3a256df465f480212a89e8f83af3f705a0a645a5866e54f909e5cc48b979c98d2dac8b7ea02c63e7757c661e7c98bbcb6ecc4e0a7c05d28059a7769a6f57ca1915fb4f701f2e4acb8ae1039f594c8999e0bd5fbaf5ad2557093c7f72f86c668c1a15d8318332cba4b2bb565fc1ef5d37901f34c795d6b372a9b9905ae5e02fd580b", "6a52526a635165", 1, -298455192, 0, "043f124e7450a2a49b8818fa3c056f406129a2b8e584506ba02acf7b9646be6c"], + ["030000807082c40301e50c9c183bb6e648cf7115be28e8000efd891fb91138a1b19159140c492a82d301000000036a5253ffffffff04f5194f0300000000016a26526a040000000009005251655365525153f00499010000000007526565656a63636e77ec050000000004520065ac00000000000000000300000000000000003694d20100000000acc0a24fe230e4be7a7b2f89a966fbbbb9305877ee8a868ae568710c197dd371fa3e3799d1cde84e8bd93550ce390057ee244ac9f6024b90de96186be4ed089d516ff18cbf0eddec09d65ea3c71231995b1c23154d252d75b20eb32ee268262c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035d33b974ab4b1c12a84aac0da667687982c25c0fbdd481de13c43d65f1f7ac286903dac6cfb089341f89b322a0c91d3595cd7d7f2a84652caf60aa05383a9e43d07fea48d685bc83d77f9e04f769c4bf8a036ad96cfcd0aabd57840be091a32bc8fbb3dac2f13f49e79ed782af1390fc3079d8641cbb88a3043d7c228e57e19020e00cf66607b5a3bc407ced4807f4f8458552f392c4a143eba823a435db5a77d0213783dd7f724cea6373140597b5107cbc932d7f7d7f3533ccb2b591b6dddf8410b041e3e2e73ecc66456cec3196941befc59ea2ecc31a3983a78e877d0d93605096a2b72bbde42d01e56408ca6bbc8c6dda327c4a0a56fe4ec91300c4e73d3556e03239d8af96c99702dc159255e839f51c264bf428bc7e7c8331e69549564ee0fd80223163f57cfd541e24396d7fc5ce3f353456e84d76cd9deb81c1dba21db68a84c021292cd4e813817619eba2389a0e47a9e080ea4ec0ffd12f166d4887131513af40308b45c3dfec27f87ceeabfae284f6a9cf487c170e0f408ecdd7b208e2e450b7703110c35e1035039e1cbb8f2cb35639f89a62d01b0541f990a5f28c1a6050c0581a38d0b309fb2fc010238a44ded760d6ec1ca48513662fb581c196ef32b70cdbf5ee510d854f8bd41ae48d0c8982a650a6b9aa5506c922f0a7812459e24e569fc70896f58ae00b15296041f014a07c3e1c448c899f5da29c6ff93f258e3abfe3fa60db80c5233280b03dcacedc3b3ed7f71b0e9022519baf1aebbd29137171b5d24bfd456360831d01df5a4ad9280b29fb7a5e6e2d10147166a7d9010507f663c48b29ecd7aa21a011658032f4f60faab844b51c4e30c7e5e6078181071c6cdb252674a6821b858834dd81886056079c6f29ca6a5313e7822a5cbaaef64765748b0e416c5aa8d92fbc2d75c6ae9b59b3134c30b09dcc82a6f4413e8529e58af8bda2dd16bf4feea21d619bc38028c0d28ea93b66a622297a84759b64fbcaa9a01961d345cd71e87af0754817ceef8693e481a8066478c8b5301d4d4df9550dd825b651671f17b87bf832bc2f58d1516144cc06b3cdb54c8aac207be3a61391e210f86d78c65f3bc31d022eb9aeef53723eec439ca0fe663583c63afc934e86b8044e472886cbf5fdca9ed414367a7e96b898e66a372cbd92d48a2bc59ee91a1547101f373a0d75cbd473d3edeac87c730b4960622c36925db35dc32d18fca5b933897b6c6300b73cb0248ffb1efcec3da2bdec822013693f3d4eb7c92aea1511bd183b93712983bf9a78dc3d3fb9c6f91296bbb83b964a8cfbdad9c73fab1945a37518ea9c6dbc8040168403df8c6bb19e59a6cbd38f63602e72649d4e36fc58ee981d3e530885c7ef8b797d5cf96ca144d21d69585ec4c52e0d081ac4453eeb25db9a07048908c24ccdb87244f07c7a540d89c3d4725df07530f06ebcb6b42c26dc5d3833664c54dc1def0e4444256aeb12ba6bbbfae7826e2830714effa7d8f56b1325c5c802e94df6db73281821aefa8784a9f053e1f82322a462aa2f80a1321a5afef1c5aa7dfc2a8f218a686fd8dc4159f243b10e1358002b4d8706110f07749d31b96ed7f1de8620f6d637b3952ffeb1780b9fc70d4c209e30d104b26d3edcec01d8aa29398b0b48b3d8256434091068d0482ad08b843921766c8b6af3f07ef55d85ad26042c6f161c0edb0490e14f298cd96730eb363368900463fabf61effe61b9272722bd997d1b73db74286a086fa93a0db3b18c51c8c372bad555cd8eb69cc5b6e44935724c90799d2f5f6709a3a0cc017c8b687d48e5d317c6c410b4133d801cd345717cdc40e068d2b62d24c9184d23570a27b0cb9c2696799766e66f9511ae53a04dc3c8dc96955bc70d388cd36b53264d2497e38abbe68916465328dd1a89fb1fa39ce5e33165fbea94141d7766110d96c5c2bcae51abf6f6ec8c0efcd66b3259bc4ce2fea018ef99f1f0461f72d23f6742bdd82f1c425e50f93a7add3e6d9344f7b44d7db66ebfd60c009c437ea81ded7df61aebc7a55aec468d41a6246b81cbab6c5fcebce79dbb78fb22a30f03c5dd8eba950855ed7a7a0094d729d8f2859b87a5f79f0bb7202edc80c97ea6a0119c6705d4018e886dac606f052d845650300efb5bd9b95775c525b7f1d0cb306b96c1bd47176d01a789a4f1a2cc7beb8d63751e96ab8c31b6bd1f1dd8728ca7d7e105870f12e5bf734778df036056af51d8fbc962f522d64e67aa6a07f2dffc09248b1cbd7154d360e1cafe43fa6e76f566b2587389dae39ad4d0d760000000000000000d46aab00000000008ac2aef5afaa32a8cb72c809988fcee4e842dcd76d36df53097f804ac61818d6bdffc9fefa461eec0f5f372330174be2eeac31cae6682daf35b0b4ffa1f76acc694d4740d2c7bd59eadfb0dee6c74c736d57016f67b2741b043c4486f48e6a13000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c5bd84f50604e8dd7a73d19f7d82e223887d9db79a7b3a7bd90867b01bfe9971d6bee0c878c3406f6360d68ae923c76b6a1a7817f9dc5502426ae0799f4b16c55ad61950279908e2dd25837322d58d3e739162303bbf297e8c086d30c904b5653dbb2b9d8d4665c665d97321af8010fddfa72e3e73338e63c9d6ababb9c7d99022da5a4d12f26b2ee82cfb74092dd12c56d63287d7d10bb5a616838c13e566e75032794b52e59c5764217f745e6c625ce4a2af896f3081ca44d6a4d678fd7fa87770b07c277bbb8b12ac7cfee320d3ed3da9f9af51983b25902701295978970fce94f191614e259c99e032e69fa19d04437b862a0ade330fd218898c98d4ab03b38d80308b999e5a006dfae3c6855d2d788dab2d3a407bdaa018b838c354c6bbb14795a0201bb552ccd1220b6b7deb861cfe55a4c87cd4c6d30c6e0d0d745940d923c5204032e9cd9dcb5416eccca2694d802c0ab41cc1474892e7b285c988d3b66fe945f79031339bb359524b8d24d335a204ecac9b422983f6e4533fce4aef45d8fccd4c684032baf1f6451ea4c1115bcaacbc540e4a7d8a429c4be757696f20496892477ecfb00c26ecffefbe5647ec49a68587862a4f2c61f8073f2d634ba82ce6aaa5a9ad86139b921e0343fe4e365ccf199339a9ff6ba2a0e759b191a80105ba86e2ee2a9cd7cd12582d4607d9485d5f5d6c8e73d4b82c4cd4120e418c0acfb38c821117fa77159d84ed4b90211512a52e415579f824f01947d2b6bfecb10c78b1c74684df52fc4f6bfd38a412e79c10e342be02eeddd42272c0be98142653c2b7955b02c8b6c1d7351d6446fe08b412cd73aaeb28890834e3f617f6c80775628296c893d3628f4cb675e996a5ea9071737582c04a7bcdb0380a11fdf86c706292f12b2edbf24a0aa6e14426c5f69253eee6ea3bc4bd9258b09c05d39677bd7127cd4ae093a8ca68996dc6a8d22e55dc425ab6a02fce13b6cb6a50934a6672c236cf005f3f452b915151a99c45f221b7b27b7980cb8b3e2025b2692ba01f049ced56a8960040608729848eaa5673166616746c3b0a632073bce8fe014c87231abc834fc69b08dd154a5e17178c0e2d5bc148df8e6e8922e96fca04a2f22da73c71d204d0388e37a8713d597e7d493f37713f38fb216deb814fcdde9b04ce918fc8281d17d2a204732878a086ba61960c0293879f316bc056ddcfde5dcc3a2fd6a6992332142f81f96b414214734cc070251a6620780e8682af3a8762b5a856332cde5d4ff50620f5ee39c6568f42d56ff3ce82a5f917226055c34932e5017773e28797758f85ddfbc568b3a4bb2638829f8fb1efc23bb7f066a25dce4bc3641a60c83a0097234d5602010d186ba1c79b141db10b209bdfcb122db61b20d3347717eec05517c70011d487c734242bd53247ba2c79601df6f79654812f94edb0e868331ade5325a2d19c6470000d5e7e534282f27a04e20dd99ef9de3c053749659cc672cacfdf6eec8531447eda1968308a1e0fd1f367722bf532fc3991d6898d1ccfc09716636a9625c63ece2c71dbad31565131769deae96ade2abd4ccead147b33bfe40e0dae5bdf3b26fa16d1907891fb4d26f1c98e8260486e022c764181bf907ccc0c440da955928a766066ed6d813452de9d1f450e666d4f7ef4ad21c3ab7cdd4ddfc8134c9b2a90e15d86a67f99a736e7f7a612a913ccf6b8eb51ccf71c1974ccd06d1e522c89775f5ca431b4f01833970d093d937442043c40b839beb5b5333eebc6424f2962eda919b166dd2a2f393ad97b5631c941f3c75ca6a9e673293b07eb2869c69ac9957586a24ea468c82d258fd7fed61723ca4b8c512c081ca5cf737a9831814592c60d2127ae7c1897eafbc16eb651295864d08f2a7a1b09e50743117e4d5477ef4d3cf7ddf797d524f74f854aec7fc99fb1edcbe86f8e8a8be83ed638b8b56f124f93358fe4d3a3027905e257728be953d8a79bcd0da21a436d3a8e778c280a174a6585dacf02e5aaf5029fb93508af979bafe0853475896340d2ac0311e0318c1e09facb8d359ca572efd02232e79d83f0e7ba66be95b6ccd3c06371289e16b5b0c3faeb8a59df8ab00b6976ec7567809ddc7f460723107609f69ef98bfaf28f78221f43d1af72b2bd0c5bdf9c865ab09e10b5ff0782368f8b11028b83209b21c0568e2c12efa31c8ab28e32bf7ef76f03261f16eaf6f291007ecdcd5c59411de46826e7d31223b9f7751a81237392e6143ef84d5b0d1d5c6b450019d4f40bf6f3cb0f9102006fcbf8ba32ec2bb061602000000000000000000000000b256c14dde9372d25d8bbe265fb7ba97bc7758fd15df0ea55b68a5f62f467d91a16de45dac4d9f3c14965c5e27604ee8738398b8c530579c660fae00b131c933249729c4b289c79e20c70ef83551b3f6fb6d28440c718a54511b158656c627880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038ff0cff79abbd60b2dd5aed66350e37de9ad45ac187fccd452083c4ab3a297cb7aaa30a8c7d9bfd8985b407dbcdebcb0c11bb8b6040bc66e5c6d0c019139634061cc1d8ff74fd79d1bb9a3c224a4cad0ee1cb72e32050d7be986faac94cdad29bf4c942051b444155ad33da4a583c21c09cf2a0469d5d06f7d02b3e75a8b9e20228f781f04feee74c8e98b321ea9a4a5722b1b3a4d258ab0cb911be90b7b552a1022a6b4dc81488b9a109a84e507ecbb101e1b0866f3a62a9a3553652e9680528d00b07972d806e46eddb05e854fe71dea9a111506ea80a7a4fb67e9d1ee320b263a9cb2d4abdd274ecd8864062a3604377d381147693a5653a1677f9d885b1831ccc031dbf5647ddba4ba4b8558ee44dcbae8f5d441a1738c8528e0bfa7106d0261d1b03289cb64c32732ff3f77e42931e850d19a01baaab07f65dcc2660ce6ca391de7a030a42c8298667f88ce73e108310af97d25ef672299f7fcea5dbbf0e570fb103be0217c591dbc72dbfc4f89bdc3f80d1ccc2f45e6deadbac9cfc280f6ff59053d7c40305a5cf0ab65b2ef5661c9470109499145b07a7aea3db7d11e192099c33e66f6a76da2a306b3c89adc941c78fda0d6187bdd20e382676718b0e944e26878d0e1c798137024cfd01b6057b8044b149923ef400e345c5c1b806515a9dfa0e2b4a5625f99aeca8d92c56f1bd6239077c28ec7e6b3b33b4a7c715aa917ea3b16b6565d86451213f647a08cbe9fe4991158698c99b69b9f57bcdb595b7a084666f1e9930431f89738b9ebab706449b7062508eda1d6d376cdb5f2565164786cf59504cb3d00def260ae35fafd49a40eb6bb7bbad6c94038e5eb270d516e2466d882adb41d96c74f35712f6b231de22e285702467957f0c59cc4eb377bfa4e6da5a45bffbbb1984a2a0a377ba6e3ccbd7fa061ed56aec7c2a292e5d87d5cf4294fa2b72ab96be5c52678b0103d4da47d9c98cef3604ba59e2f4e681492d12eb09b538900cbb000dda2100b1cf583e4007594501b12f7fd73d0f17b69b80ab8de9e8ce65a4a7a54c8fd4ef35b33bbb1be9c09235755833fe21649f089237675be40b72ae0f14dcbed90ca86bf3b24ab9a893b2498b34729544157887560b2881c2b47fc80c11453a75442b3a4d91856bd0d04e7e966ee854c7f87aa657b0cc6a12bd53d3dc1adf277672fe6712e70f29bf8e33aeca15a706f3275a1408a1e61d2d5c607e949ace3e99231229564331ed80d65d050ce2b491ba37e63ce526ef05e83fd32fa753baaa0a15a915356a876833cc415c36bf6579d551eacb9b2f44c88f81433714b2fb724576dac2ad82c7a6cf79e34b8c19b08ad927dd995f30c8d0c75b786d5f7cf69ec0f6e23804b0dcf6ca7f238652c505b877039b3071415c1abd8e9c6169fc39bf99794e1263a457d27cc3b5f406c37461c1e7fc8115b78af0c0ecac117fc248f9ad8a0c7757fe10f295191c902f07a016a8e458a580e74f6892bda2850cacd043959b7125454239125346ee03b912e017076934a36e66768f5517aab0ab8505a578ee08f21ab4fbade9d803f80044a07a8abd721b32ea80ce446f778004a3e3ea0800f24ca1525ef59cee1a14006969695a8fa9c445b8c61c7a08ee70fa574bee19e05b2f9dc64dd6ed149769edc6ab4af46ad58a80057146a7c8bb4baa59a0ea15248a3ff623ec30992d317b273aea7d72324e7c8fdb2907575f4438b300ecdf23c14ec495e0d6ce491338757aaa7122e66a1750d293b7945ffc5d5b1554dc94745259e1b4a4d4c2e463cdc63982a7cc3fe0aa61e231b16c1d58a7333a5ed6efd046aa5d1e449f210e3c2ea9b635882096bef7d89f5377fe7b5134dd435c96888745b9c1a96a5c39e71e58676b13e2914e85ad69295803e6f997fce55650a6a7b85d82aa124ee33c0b77806214045b5cef113389abfb9828398a68baa9fada6ebd3169d26bc0ba4e766e910bc69d431f2dd1effb8a0fb7805e83c4b9825d1426c94e30419709cd772962fdeab9f1efa99c9cb191c71fa12e6fd5f61d15ad685970038ef7f7f4aab6192a7425a6a22f5a9914e9a055a8e47aa89b1660c7439903ceb30c8e788ad0985c0312b34fe25d91431c819f3645f154888eac931f1d766fd6941046967bc5453d6eceb36006ec7d65dba10820fd74d75f160d7e3cc865994bcc59e9f70b8368b15dd89d8269f537c5051994799c5b1668de2b7ecbe1a686d305c8ab89714f07680995e06b961f011da5fad8a5cda220f393e7ba138180e436033ec6b98671409e546823fcc43a3eefa8cecc2506e599fc2e1fa06d569a7dbe27be7d1741642947cc86b73b451862f427c4a38e840a6c33dba307197afbbdb06bd98cffa533da63c958dd76c51946d25d782f918233ec52d9ab6783cf1a87002a94f23cfc3f2506f3c9758609", "63655352526500", 0, 421208333, 1537743641, "81022f706ba645575b3e6776ed99f109949a662bec1acef7964711255646795e"], + ["030000807082c4030356b786bcb5066d1243d13252119a786858901ca202fc9c0cee9a83f6872cdf040000000009630052636563005353ffffffff0af50a7db9ca3a872c6b69dd968a446cc0eff7974340b57f52099ad586daaaba0300000002535156a94ee666158c0c4aa839c2025f68b4b6820e74fcf42ce8887b9a64dbecfd184586f05c0300000004636a636affffffff03a63fdd03000000000563526a005164268a02000000000163b720ca050000000006655351006a518efeb1200000000001000000000000000090423f000000000041bdbba2500417a5bb48c27b7e831646d9ea31a599e12ccb78511d5c1d7f189035f140ed0fc546d6445bebcb89a35b5ed5786800e655cc6bd87fc513320bc1568f73721f4673a970f0a8c25c39df1c855c86ed2ca2a8a42ad4a11247876ceafc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094444785875a9ad4da6225173f04d8c8a52cc0c99ef4a027c76d8c9735b88164da1c03422c4b528d0cd14488c28073dddb46129bb51f30dfc62a99d079544204ef209e7be7b45b41140835805bc02e8a8fa0b617b99609e5d423aa85181d24cb455dd7704c67f4aa4b83993e3b0cbf7990d8ebe793e66c884dc0eff8500f537a0204a362d1063de5f3664518db8c997e2b1f487613a0c01a50e802a7b48cd1ef2d021315b00313b21a7d4cd4184dd5392e7594934ef90701feadd9ac174ccb83387d0b00df2d57bbefd807d16903b6e5b5e53e2bab19acc7e27148eb348b204a5186077941f1b76cd704664508d96b04ca025661b49422f92cc9f4df5fb3500dcf21f9021dcc88b1c1171a1251d7502b6c3184367ecf3ab9efdc217b6a4d703ffe112c74020ea2d9e62629da81459228a1f82548787948f87f272001482a7bd3c72a8e9cb1031664f9ce90e8a3e536fbf12b52cbeff88b3b6293610fa7dc27e2badc248811fe0323e7666b96a513e8d741084fa936a6854a91a4267685db9f1de1371c49cbc4e20312e93eec073f32bb2e114afa9b34b18ac1395fa43de626e6317a7c9c0161c512e3459984e786e12ffe3a7b43d0700d97ba0cb9798ee3592e9b7f4db7aebb33fd88078ce3a3e0f681d21fb1b00a790d636726ba65b91b29b6f6570dcf84a5562caecf7c49b427b2e054ef3b33a1ba6760b4aae0ca0156b7cc867c09432facece5956f1501721b5d6157ceb3a2a461fbcd219e435c69e56f5bbc3f8df63cff4693df16a8542addfef8edc1df86cbac125208458b155aa3c3c20f3df58ea1216f510608d3b0a6b4e3067990dc01f896888798de833b0bc2374ef6906d375275b35f184d8101de2341312a7d77a02c095966aff0912a0a8b75e49d93e3bec151e64d67aca2dd4887ad767690eea36d99513ca78f18f1e99537cd8eb1b26f07047990a6e11b9321bd49ee3bfb883a064c857149746d7c41af8252ebec905082dfbc567e04ebeff4c0b758b9a044579675d99c5590831578d7dfef9cf4975857d8758f81cddfc2fd81859a749080ba6c529c9b0f912e808e749911cfeed8e97ca498de1367bb0e42e7aaf4e9c0858351f21a920c635897f8b824739c81702d63f2b879511ab4024bff15e264892947ad59a3f9333404f057272fbde12b44b50cceb4717365bc1fab37283188ca8e1a4ffc5785b5c7efe7a408c9767b617f7355aac8277e377a9375ce44d99bd022936fa3daaffe64b734487198bc99f7dbe71a6b2497153c3847c8cfa78b18e003c7169b7199bdd07a36c99b115a7881cfebbe33e1462c17f74fea7511279111258297b8cfe0f9f250b804826a8878b917baef4cb9d9b6f7afd474e52513ad4c9f02a518cf2d649be9ed57b27b075966b476b848ebe3c2e62838c3a742dbc24c599de7cd6906d487262ae1916e5a80cdd1dd5bcb48c5d11d6977245213846d8a1b373779cdc5687118a33f70ccf2537db5411a33a02c03028dec434eeb954a025354e35419d2fc2c55489af06cadaece2f1a2e6abbf8d8357414b33df2e5aa88b13e08656438156b5394d8710cb796c742e98d44e57a08834444d5025775e3df3c838d1644e586b957e6b470aec22a7ab9aa6834c9c600173da4ba978c6cc16f4316d9cb0d9c9d92cae217f292a35f40ef7b7ea73ff9dd49a31b614eee058f8a518ee0261ba1a670bd7ee5c93bc643fcfbda3bbe11ecf08c05ddd042ea2993860e872320152688d8de733537d3ef5497cabd203a9cf5b7eed25f1fe56d1f4f08cff166764043873ea008b1b5cc978e07c3a37564c48fab5259cfd56ba66258684f6bb0ed9afd8160c6c0d49f4fc6a3b5626744bbad384364eebe4a489e793dfdc5e417bb8e069291143b0f28389e8eeb8803c5bc0a62b8767783cbdd54cfe21e785e9ca3ec50545261bd0ca4e94fe4728bf3bf7718a6ebcbcfadebb27eb2f19fe3f8945e3a4d46217cfd23a8867c46efd99ecfc7646ae94a1af209e41d1fd1eecc388b445127ae4aa889792aa558e8bd9299c945a6615667261fa2640014a380288d9b1f34544b570e2d09a9680343403b08e5135c5e00c23eb22045a20f7a9e0f1d608a1cddbeefd31bf2af0baff87bc9bced793cdb8f9ae7d4395b8f7051f95e3eb4dba2f2a759a9b82ace6f9b0f64d8bccc937e2ba10e680f48d8942763f633bd5ec3f4a1eb647de6f84ea41fcf8cd56aad4c47526d9f5e02bdcdf9d437140ece13d29673ea6735f481f519bd70dfdd8b6095e6a7696026ca80bf7c6383eded32443ee1910dddacc407e1aea295c5b796b78e278174c8d6fe0a2ab0975e6bff323f69f7b733f7f8aa202f74e9386ddb45be9e343bacfaa0def55c78b155e412792edc57105c4360251f1f2f8059e55e2b6a470cea9e962c53cb7f085bcbed01152b33e5138907", "6a00acac52516300", 0, 1695924994, 1537743641, "86b9ae7bc7fc2e49e8740d39f1686c4f81799c3b7b893c01f4ef440c42d9b05b"], + ["030000807082c40302ad0c250bb52db2d3fd65dc251c0321102aabc46c80d076b983b50c90d58f307100000000086551006aac6aac53ffffffffebf37e7488b940b2bf783917ae37755488c5b87d1ecb577815fb2cd94ffb42f30000000008516a65656a52535359e5f06103a5976a040000000007005151650053536a2dc00300000000045263005300cabe02000000000853515351005151650000000024811f24014c4b2e05000000000000000000000000d16e36bdce7efd7d1c77fedc193ba60606d9341b7d24048e0844798ec729a59ae83cf006b5d991753dacf2627cd4bbf185dc3b86b6fe89b79661a69dd012f5aa3cce4fa63c2471fbc7161b147f572ddba01ee8cb50d4d7c2139d1b3e490f784300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d09b53dd8f891330b0dc29b42fc00e5624fcc750f05b4a0e65f9593243e7b3fe68a7d5f5485a3e15b24150b1ecefae1f985041e62e2898e9aaa85dec8bb0b534effce4eb0056e8f27f606b974c2d07337d3141b1d1ea3592472fe48a17fa1f090ee6e501789435fd23523687a381c186c974fc75745b76605e5b5b248c74f6f2030d993bd34f02d38cbbd29ac9e019b3a6a321f412de4620da6d9bf5797ced33620316c33c686fd200e01fae4640c9ded3654af39c60b3f17504b71e499922301d390b02536daabd8a7dddf9e446a2f3c8d44ae6846188bdb761ba23de3f94819fe4d029e48725c5d6ca0ab25ca8c81cec1529c9c2cea8e26a261a38cc1a198c988d52032e78dff4dd67d4bdde243324104df6d7ab86f90ef454b3b5c342299b173cfd030206878791e3d3c96467d6529071127a06b5962e88b7d2853db72908f14830d61302213424f400152a733ea21f84221e4f05032615ece35a1750d148249a9a4d305803280cf0a379a823f93d7d3259c012001fc2874e8d6f3f081586ae76a0b723f96e021feb42de981327e88aab949eec6eaeb45a1efd8f2a257b5eb73186d6e5b2ddadd16029a8991ced6abda98df411d2cb17447635cfcf1049b8a9bb59dc0e5c9d2bb8bfcaa85f4550e01e9be18529e7d9fa45a500091070a9b27268ca7c9c5cb1339d83a5f58f7cc3756979f7fab51df7818d8cbc9bf0b3474a43ab52f6440a03f602cee8f1b86bfefb6708f0870d8fcdfa56d8a9891e013e37e5f3d7238da7c4db4f5205ae87865115a783a4a49f7b630cf5e10f18e13a191424ed2fd99ae44cae1b367150ced6442c7565ad1f40184fa201367d2ac4d08033b6f240d3d7c5cabc6038d3f763c105f236e38936b17cb29c0364005d4a4b1ba954d5e638b463bf246205dafcc022807422ebe982fe55919f22cba40bb4aeb94b9b892ef46d386acda246a3a6d1144604ce7044a9b5e4c7d9d4a619f403cb60b8cc5977c03e38b36827e8f9d7c553f5a5a65031c68ceb4df4f3c253ddfd98213cb3efbc2967785557a419c1c3b3466a8b419353a8019a7dcb5b4d07593f0974c2343ec692a10c06f1bb8c0fdb2dd331046d87c4fb54a49bcf0f3b6408288fd559820feca74ccb91e59cb79ffab8fd218bb3d4c469c5c79af6c43442bc0ab0b705398d73df0212f4d94bb32fd4025b8b64cb23b2f2848ea1a6840bab041d90b723d22ae83eb8aad5024fbf266b8bac4b34ac4160001fd9889a576637e943d3994267d881561cf6bd3b8c0e0c8cff6a4956f5cbad13de772b17b96c1f2aa52b641fec16a985703f5f298d51b2e21f4272abf98f3075df54865bb62f9321943e03bf7050fd2cd791646c154ada5440aac0670cb8719c3f8bf1bad975937266f7b9c4e4f3d6cd290af5a1ceaa47cfd3db84e2787d5e7041a02546ca65e3647ba133e8da79d8a7230a20ac6d1c8cc9f07f50f4984c6170971e362205f0903071bcc8c34ec7b9c84e1f1caa9bf28c1e6c283cf9a876a96e6321212ec6fd48b00815718247c6da48e317241dcfedb5c0a6de213d9e3b46b4c55609e7129222e7d410204b75ea0759587f06dc07a2a334b4650042f6de42b9c2dc403c438cc4082ccc5b842035276cba92fa0aa5580b0e75df9a3f861c289b8bbe7bf9519c3b2a0a8f067f6c32d78618807733a39f98af4a07133c3bd6f8abe31c3d66439e92d2d6791c843b662f7ccaafa15d48a5b2e96a37fa67a715ee1dd684581e1d158001b249ff4663d94a61eb9a018d1f286324d2410ddd8cfe0e960c3b2cfc3127f1b097489434cfec25cb9d299e43c876039cf735704c678f0e78b17586e19648fe54635797a656a49b77c8b3adb92b0b20e35adf174c3db233b1d7a86ea5ab547f06c8a1ab42816e949304e4571c946f4f40799b2e07030ab5748a9517c304e21b730e50f5c0c49630af93292aefd079407bd106ff0d63e7e4247288bdcfe153dc1f80726bafe900f384f4a33a7e7d32d23f7b540b065c7ea7a7f253729b4689ef8300dfa131ff31f8b4d8a7246946b9d299c74cb76362b297322a085ddc22ec83bb06e043e46b7869e0d3b11d357bfbce0ccff6ca68d97ffbd97173735731c14203e691f784ee576632ac51fbc5eed920438e4920e28106897de34a162134176e92836271893654e37cb0d97bf1b81c25df96f9db359ae712ae109599bcd18862b4526d5f576ab9c47c975f1bb63d4401fe828a004fe96b3f34dba29ff8573a06b8e9d427e353a0565dfa2b5498599218a6f48c049c4dc91eb2b857d3856d71e622917c41befbcc5954fec819b63363decbd9f2b95b12ce1ae5e6fe30e303f820931a99de8730433e3d004272b1640993266b6f985709062830c912f90d483825225f0892e7110b18425d93501aee742eb66f83447deb5a0dad1657293c5006", "63ac", 1, -43392376, 1537743641, "38c862d902b51f32728252534da4d52acc3da86e28d32ba253a64b7152d2b650"], + ["0f3b747d03de20efba80d182a4598d1ada8158f9a57fa56adea7c51b5ef5731af1288436ea0200000007526553530063ac2cf1330d746d7689f7a29e7815408852d1cedd61da7dee326db361bb4359a207fc0acb110100000002536ab94a805c3ee5a3985569f6d3966efbeabf73249b0f7e3dcd93820939b83a7e440af67e8300000000065151516a5200ffffffff0154754d030000000005ac5365655180be135f01a2eb5103000000000000000000000000d23f041fe6d6a241bd5fe26e65e4390027f4945419d7011f4bc98f886a57c78d7f68b5b22de9c0646211477f29b3e178c62d9a886b8a1fdad19179f0e825a5ff173c4e8d108c30f67af3ddf1b0537a4c34368552bedfd9a3b6e5896fd54576ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5b086f4622d3621a38804de32de637435da240dcfe14d3b6c5335b765ccba5aff98c8f62700d41171806da411d731205a445e19cebc89d29b9f0aa1e7d5aaf20513cf0dc55b7cad730c57c5b8096131879b99a2831b2ab90aa7f1614e30ba291eb7e638d50d4451a99a46d37c1064fb673c29ddcae68b348085d15190e1da3c020c3cba1fbf8e434023fa5fa8e9db45715da7c85845b3819709dba9011b2de20f02223b52dfc53aacc82be70c1c80ea2f818a92432aff869e90f1e8aa520b457f250b00cb703c5aacd072662e57eff098494639d7bc954198bf6ab6c14c109a6d810b7efc4535e6b4e79297005257c7c99ab05ae1399e10566a6af52348087578e589032d57cea1f50b783b7df7eab6a31a78ab18c514f5fdfe08bad524dd302b17cbd6031e01886101d2f39444a5fb93f4623e95aa4db6257bc83cab1d08ef65b16d5a14030e79bc412ed12cfc6b6011c306d914b1dd596948452ffe1f76c91765aaf1f4a10322815616a44cb1b07b2f349087c4d6897fad4508c777267e208eff2376cb083602080385eb56b510f19dbefcd7926a9dd928686d11b2cb4f2320820022d7ecc2e01471d6b313d98a4282c719908777933c2058ebcef73bfb3a6dc0666f405ad9825ea30e398dbed8d46bfe016f37841573167a06723b0350559f03a1a837964e17e2e23cf32ee17750c0b986a8c9c81660d2898aa3b95b5ba69a77b924d11c713f0e9ffe8a981cf7290cc53331e08d0ce4a1cece6c2c6dc6516c9fa7e7d0edefe444abcf1cfd536fcb05c1250831a45c6c0907c65e6e3389cf6ec66b2d2868883414ee8caee3e9c5f151df845fb710d2945e27cf2ccde3445dece60814191b7a90e2a8f359e6c02b48ec6d85cbaf5b46f3a8a3858285b634bc3adec51fab97f06d5259875608c884ac59a91fa84e1db68933f24deaebec3b4954f22dc2bacd32ed292468f41dbf797ac87059673fba05dc9c4865bc08af34eb7260e011302f09f8a799af12e885355031de7a7083c0169511e5657b4aacf86b3074d0fb4cafe4256dad21323b043669975c2ee3fc3ea257992ce27deebc178666d597fe66782a9b9678e3caa7ce0f4ec4a5d4a01e9477251470f40a5d76147048f3f31a87f605e90f79045de95b1cbdf37a1f82e000fef3852a09d0803bf201f2cb1655dcf770e5a9daf86bbbd7d38d96c4621d3b16a74b7d7455220ddcb609e8eeffc73b3b6aa3473fc38fb246f84874746e208f15292b6ff997e4dc83727c1b6d653af88da5f66e02874c2de00f8d7aec4e9b0044ec4b75d7967426cc5297cf6050da84e2523a4aaa40fea08f6c74957b9a08f450f27614a877429696dd045436ab5783f9f6cb6e5a73227cef1cd4ca433d071ae709093c8ec59829ae87787cd4fd1bbe0170f4c3def9aba9050275f91f9677c987e761eb55d4a644badbea49d947a265aa30decbaa5fc6eacb140954f90c6d09269c9d53ea5a17adae17c890f52a67b47fef437212fc22e2801e536627d4dcb1f9b13eb7a28cfa082ff986327021187ecc83ba47ee3bbce119d0dd49ed91df30b6a16674b25833bb2d53f2c0b057a484a6203a8f4c0f42a2208151c1bb0abd248113a84b2054d0a52a553b9aac799f9c37781f96ef25f714d7f10a002ee37891bdd803dc897e6f4004794901aa3c76881b5eb43da55dbe157c49c134eb32d151640a3f79c134be25197e34968a02f063a4c146ea7673a6e3cbaa3b2f223cf7d4a31f00118e0f25b3e2cea11ed9ca87fbb13e4bd09e77f7be6a7908bbd935b891d73afbe95102224694827bc340e618d2d7675514426de534dd1cf03e4616ac3336f7ffb7b2fa79780115293f7b179ebcf9953820b9f5e5868a590016dc7452d2a14da4c5c999bd55f070a5b1894e7c02141b6ef718943f48c7fe9529c5ca010b706ef59635356c86d984afc498bb2e60ca5ed346bfe40ade273d3873a7644a493a7c1aac724cbe9b9c18f37fba7365034bdd7b389e90930d0f0705251fd1783d3001ef0f18a80472400e029957ae4d26b241a8da3df740f32047c2d20b2c1354450050627d2757a6d430c7aec6934c963dd02e73403268741d364670355a1e9005f99ae177db352cc4451e548e4b5b99ccd122e1d3f50bf7bda067edd971e4d444bb7f907efa8e5071527e1e5422053ea3b7002e5ba68e694d4c330b4a908471af985931775eaa614d9d629204e847442c8aa61c386798f40755649f344f472224156d34602a0155081509fcff438c38ee51bc285b21f47d17ef78498ccb4e53a7b5d677d8f8db478fadc74b7f8c87d554e31afb24cb5af7a970836ac4db348ea61e1929264126531b651f059e0b98ac1eb0e6c402fcdb083d045d58c0f7824f2f66fd7bd6aa7c0f36a1121f7ac882022c67e51a89cb7230b2d5ebeb0062f1c37a78c05309", "ac656565630000", 0, 618953117, 1537743641, "3269fa0b69b3d8c20394f4eb8ec685f662575a89d2c37d79e76e6cdf40bb464d"], + ["030000807082c40303d34b0d60cd94036af478fce5a2ef6957049a94eac7610acaa6cb4178e50aa0300200000003005352ffffffffeb4bc88a86f5398db3dc7d975aa81caaaa76ba7ef53c99f054e4d55f49a3c3710300000006516a5151ac00220fdcd9e14c043c79f74e7b9d2d25e614332544d21c6f4446348f0d448ba93b585c0a8c0300000008ac5363526a655351b67bc279010c8ce90000000000096a636300536565525100000000536ace7f00", "5252516553635252", 1, 186677060, 1537743641, "b6d93168d1d68cee1c35b4212167b86283f55da53f16dbe4c17101158657d8a9"], + ["030000807082c40301e36c2ddda3639af26a68000d85a918171b66d57aeb910cc4663c4c226cf2f96a03000000096553636aac655263651f091be2047ea78a0500000000095153ac51006a00ac63486947040000000002ac517a0c6f00000000000765510000516500a57c25010000000003520053902b203f616db791026dcab302000000000000000000000000c81d9ce2b0bb8ab92312e5aa926903c3a0de12e45befed19e125cbb800b3e4228fe7b2836f4bb6780285eb7a8372c822e1f4c27d6e083cd3f15907a7871e50f6c339c5af104e22d5c21184e7cdd460cf7ae3bd514d8e5177b44ce36f4db7fcac00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000155a25990522c40ca0331c64f43989eca17cb3e557cd37ec02208cd58553483bbcd2d656f74a8bfda5087cb796286a7d69625359a2ebafe367bfb87252d03ec4a452e02aa710eac06a8fb6fbb3b9e1f61f58dda95bd2b018abf4679fc25860297f7054d709e480b54dff297a697c3893d22720881402814fd701d9fe5561d1b00221eca0b974652a5951547f34f7b336cfe9571dc318dd4353b84f1b78792ac76d021310b071c8c8aeba550032f486400531923276ffa36faaac0e2a7220bc5f3a890a080d177d60e34ba499d560e2501476e76e463a117a749b3437a0c8b6b139361c18145479a47c90fe06517b524c63b36a5cc6e85575834cc24725eb9edbe61e6f0313c0ccff18f07b54fa314a9ec1d2b6985fda10b1f81b1628c277a33ec805789a031bac2fa2c662dc9e27ab6e98fb3ce08d518884a32658118dcc0dc81bcf59da93022647ca45f1f43f0089e00019472a33c7e9e26f5c597810a47b68dc3ac92dc7bd020e668a38d492571cf2d09e4bf91c254010d84e84bea19e30429e08596312a753021a8b084b951b32d37713cbb231a475b946d8c866f732d4c75e8d4f142a96a2a2034d4172fc9841c406cb6720983205cca12989a5cfebae1d741ef628ac0851d143b264326dc98f390ef436a0257d3a41723d670709051310c113cf385cdae7cd70c41fc25c307f46432647927f592d97aade3bc9a6a102c21c6fc7e31948a0b62423197f06d583116b00e5dda9ae078105cf6c17a9a5d989dc6a19e20ce8ae9e9dc71535ce8d0c353b63cf985adb3014b99d7b8a37e7e48f812fcf3c52b06ccc503f81a8e39f79ff3479705292d4d121f67e77fb7b84f94186c521dc6fa029fd65a31ef5d7f2388fe6c0fb7a1b233cfa985df5ca59eb024934907d8c4095eadbe779e1f6d302a22c5dddd06f20c197f7352139a832044a35e9d146861b7823511bbc80af271d8fd88835211079fb47b54d575684ef8e3e0ac04216dc7c11a046dec4d51509d8cb791b0d42228f6b49d27b5b93ba6981e27bb627aed06631afff12db611c026c39bf32f620bcb96c9f07d896c2ca13dc6944a57a3b02cdcc005135149063dc690f54fd18ea5278bf43a237ca52c47d17de17a4e39f661d8adcfbd32f94495259d593268a6865fc5332b75733128198156d8e8a631a29f82ebcc5a52b7c9ca30466896d9e8651b095ff059aea7d6718d68d35de11183b91212839bf675089aed869a9e5580a255a99949f5a2b5f22fa2f125634a1a66c48418a073ade5dd5a5f0b1e667c7ab17e64d8dff6f677bad6ffa3c0db1023e0d6367228d5866fef097330f559a531a944debd4f3848f9ab16cc6288d1cb0b8e0142fadd20ecdee5435f5bc0a3b11219c4d49f325b357b97f3470d7a0f6991aeeb3ac9d509b233c17207158b7e85a3dfac740e95a08e8db3e5dff3b153ea61f9451508fd0ad87cd78aef2258a65e6318c58b099fb499af3b335927ca72ddebdaa4e02e5f6f151b6914eab1b3d2931c0e31f8435d0e88999abd4c129fd1b5e0d90f5d1e3f5e5e187f23c9bc96b79d82582d4ceba8cc9382dea9626f62eba760e143ec8a504f8dead771fb831cba78c05ab38aa56c8c5b77157ccea77bf8f07360170215de22b2b6a0446c779835319863ad3885865d91d0ad10ceb688733740bc898bcaa0c5d91afac7115cfb5ede87594773db559bf80078fbdf281d59c591add80fddfc254913780ed7a8f59e75a321ba49eeb481f18409ef341cefc999a8eaef63d5b4425bdbe75ee96a960e74b9a301e6266af1100896d5827db10954fa61673582a853dc7e1c0b51f47d97cbc02b856a9fbdbedd978fbae8ebc999e0d5c5671a2510e3dd382ed9fd82ce471438b36fd068bb87ee0d26493558b7ec68bdcd503f81e7065e7c6aafd50b61b80d2e1d73909302639a26d9d936bf5cd39e94e3388e2f400e3e1b1b08c587aef2c9cabf8917cef0a147a95adc2ee8c1cbfcaa79f6326178212c31a36c4901dd138e8bf5b8a29adce71053a563bb548159c3cfc7962adcfc07a85b36a95dc5037efa4df9b931d3644c548f30f7aac9dd1c1be0b077ba511ddbb2e149fb23b3c741638528c65bef0e8f65f79389842cd6e3be631682c41cc113b379d421bdf9f2be7052b6c1f612e118c1778c459674093797a039cb136034720d7a4fcf6e16094de0aca503631fa66df3926faba77848228297703dac452f1b34451517390ac2cd107cd8c77ff09b85f162d999629a21b2a515e4a797525285a3df846e60b73c1a87df5802977e0bae57e000000000000000097f09705000000008506f7bd713ffb292282051bc01cda2911bad58553dff714ca083655cdb540904f1e7a655f4988f49f9bc1dff0cc9c4faebf2cbbc9895a4b57e53964619c63b8b5eb33f13445a944cfb5391e8c184161c1c48d338954576ef34b9ccce09e75ac00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000201a607b4c80c928f51ff5adf3482fe23c6a5bf112f1e85a972a9b5bc4e01cebb5429c7be9e8fe193e73678a9614b5c290d3b0287996d3d161dad7d115f199ff63010d56899cd39a90bc64a9e30fda76f759ebf6d4ba555e22324bf8288ea3a98a296b27842ac7e68e431cf6a256b2ea4e2f0f1a789b7c36aa6eed00ed702725020e96f39bde7c2803f15b61b8c8d2e9a8ff9d165201fb16f9145f02f291ec4eb90208028b62df047fd7a2f15b53ab63702dca5561a51678829c3ff7edf35b65bba60a0543195d4b91141a0e08c4ed4deb0bb363bef43467ba25f647fc7ef9b8b3286d16afbb71494cb83b34eb270e52a3ef224caaf35af8b1f9212f47856f9660cc1302290db732d87d674f4f93418dfb67a247c2babea7246373ac72637b4d0aa776f6032781cac9098d2822dc187280712985d846944ff04c1825f26ae72f3bdaf040120214b23536c0266169d0707b60bef2ae5c2b7cafa035ffe29ad8c5954fc8a40487022134412725cace425d355b07efd078f8302d842609f1c6a565eecd04005f5d0e031d4a132aea39d64ff5454d3550906546606a2553c58f7d696a4173dc85cf4be7ba28d2670411ffd0411244d0d6f94d813a2d58e3e7dee977bff83c944ae91e83f18570426e95e48478ae8dcf406f81bc88e1cbdb29683e2d36ffcf6c11fdd2e8d55d6b6af59aa7b219b2f43e00a4e15df64b5d70a043511a1eeaadfecdb29a36124d0f6e32ed6b5ee18a75c81489114affbc18b5c056dba765f7b41b1bec83b5318e429cb8ce7ac76dac31329c6bf633efbce3d924891051becdc09143525306f05f825af1e1c070a538a2b5152865fa8a0b1888f99d45f418f80c34370955a324b6f3c47fe758c77a144c913446d7e9e6e5d0e69fda97bcaea51ef4e584dfe8108e223db9168bcf113a01d77e7fe27e6fea7b8847c6d5e30c228217301b02d2874c396a119088e273d1e3699f29362a2b0f20f674bb958fec353dc12696fa0d8b33d2afe14cc256745c0cfaa788cde7a38fa891a5c3a9426355a1f01b8d168eb69cf469fe6b404161b35e92142573eaa4fd9675cfb782397789c72eb8a2175ae224435d1e0ca6242ac10199524a294f7078a3ca97a455f7aff1c567b10aab65a9665a4230f15c92a28c22fb732c04c3ae016152c3e24688ebed5ab77162a9c91701b68173be2285382dd71f5242f34cce44ff12b652a6907dc0d11377f5950887ec7b9f28fa571543cacf538fd4478a7979c73305f86fbf3a41f430b8d46f9d241eef5f5628269febf246ede4d2641140b04dc52ba32bb33c91ddf95ffc19e5ef2a8bd8a6f27f96924521ba8154ec6f7a77abf0c7d3c59e675a6c14593ab0b31ebb406644b5bb16ac6a46102cb34bb10b9da978bdbd9bc25da8d3a8348ffa9f2fb2b63e23d8acfe105243e3bf97de430c5387dbadd0a71dbf30f8f959185af0764ed1fe74462f9d30d619bbbcdde4fd2e9c75572af551e221901c906b2804674e33a7839c5315142f9517a9af08c702e239a2791ded009e63d27cc909402098b5519ea0a68c59590d8da4409d09a4fb2234e20e10ffd81c2305cd104dc33e4dff04bc3428fdfb804ce9f7ffe54ef1cd859741605bfc11bbdc53508647297af115db01f8dc7618142c292330914ed98c2a6c623256a269e371f95a44dfbdffdbdef1af4ba6608145423923aee2e2c12e0bed2bb675394f13cc805b710fc15f907343d4f9a833e46ec01caf47a062e65bdb9d7b3947e081f030cc8ea8eb08d1f88bc31b31a360275fcb6b10b11be8dad329233a38a7bddbd327031428df9a8d91b376738a58ccbb7ad07caf843e115e0b292838bccf38820e0ce96834bbbd77e92747838284cf87ff1981ca9ff40deaa88525c4e7378d0bff244a5f40a6f11a6ea461a1c071b4bed6228710732d7dfd475a5993136d705c2f458178189f570bf22e00134a7605115c03d121e84a33f1dc6c9eeebeb6f59c0db8c4a1ab46ad12d1fb5e08f6d8e796dabc36528db922394c098294757755a8620626acba2a5e2d5df7d98340e98245baab5ba7985b442c8503c2348796eb52528a631cff9c776b9d3b894ff409d3fd45c24bd79f44cc81f3dced2473ea003c0c541b0bf9dd46016a736e4f573fc1d214f0719a40d3445560c0264f53316941efbbca20cfb05d8a30c04e8c117718f1ebe5191c6eef0a0f4c37902c790df13ec6a1db6a25f8424446168c1f8ddf94f36ba1a3500ff130f5f1ffd5dd798d6cd86a2f30f8d86eb067a956ea0cecf3d7c6555af1a35b4ad83ea4e9905b8593966974f79cbaf8b30c34c15c4eb4c650a4e0da0ad0a7c122cd07de89284a5d0969b03b45ff9ec0857a37d8e32be2ced1348b042f8a3982a5f5f8573fee3b8c83ee59bd0d91dda3e2cee9cdc1b8e41000f2fff500bb80cd6038e5d9bc07", "535363", 0, -549801415, 1537743641, "bb0daae130e0c5841b47e9fc0999fce58df16544a9b9955f2a9fa98d323772e7"], + ["bfc96a2a0498b8ef1f984ea8a44323ae4f3295d674101aab59fb61dbfbe0480a6f03d1eb240100000002536a0f908c63911fb063588ba010f073b82bbdd1bdb70bb44af372f0650ece35c45cc4326a370100000004ac526a52ffffffffdc89b4b73752791d46c63b59952ab06a06bb71489b548296d8c0f1772f57436203000000075153ac636565acffffffffa2f1eacc474df1095d529a08ad356a741bf2ccf9e6bb7199a22fe320116c2582000000000253acc2c3085103678ae40000000000046a65ac6389a2950400000000026352dba93a0500000000085251535365535352e360bea6020000000000000000e059970100000000454156985a6c556997f27b60bd96159198ea23a132dff6eed111183a6ee5ffbb25951820551358b1ddab8e671ba25173c6173b049c58d33e65a750335b7dc5d6fa7d63f31396ca96b20565026f94b252882c5604e5044f979a1a5ed673b8433d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000884d82392bc7cc7c2e1db31c11dce3b10ac0e69794d68c0a18c87b5b54447e04ebc6a81ec55d946d98b8fdca9b5be9e40c46f9fa77ad2ed2b0b528e6061b85f9c85f266ef43cbd80066b65dd21d89e0888f7c65c6051a61d1a7a573e6335ff6f9af62753c775bb7337aff5020320efe91b8ad2145a40c314ecad9263965a3ec1021c5dd4190b911026eff1d051807c2f37d970c0d11c5c0256ed87df4b54a8769f022631fd6962e8780281e526dc6f966b9936cac48e92e8c8fcafc02afc67630f760a026a313dfcaef0f4ad0dc2ff38c5b28aa2168bc168b36ddb336ec8966082242d0a5389cadcbdbebf112a888acce43e2421e152495992ee022e615cf6df119733022d3e3deb796cfbba8e6f7e2ecafe9b1b4ff94c395279946d597db2a79615541203264258bbcecfd38529b271381cf7349180a67d80713a77554c86ee269ec22ab5030cf43296d3977257a840abd30c8e0038da97542b3c5284d7090aabb5749e9d0b0304faf34e374bbb7fff342576b4ac52b6cb557fb3ea9de85ef9f2cb55141446f1032e749c99574d73fd0e928b2fff86a725d37693357645fa5006ece91a561a61551752afeefb7d2985a1d8a51906c9fc14badecdfd5d251ad80032a0c59587deef02360a20909bd4ad74e6f8471774bc62bb0282dea852e11974f8830d5f937d121a30528852d0119c442aafe8f1dd444e94b12499d4b8c32991a5ce612b56ea3e580accf286a11b14219260cfedaaefdb277feb06e773846db78e14df1f35c4a5ee994f2218ea4b1a91868d3e9e6f6bac93d6a7de766f919469580e065697a69b4d8e57bcf1158954fc50966bc2ab1d07640e7a9973b3dec32c92c929485e9d01c4163ca2f7c6a755dd145174af186e3dc75d34dc9bcb91b7162519e6dce627d7265e51a52b970eb9576bf8849e0b9d7e90736ba75f57fc9a2fc97d48ca0ed85940e48e45fc908e4e16e2db4ac9e6d96669e91aa4c1419c043fe73bd63a4e3ef2e0af9a27fff4e3ec1bb1fe46d2f9293d06444362a1e8de72069adbbb252af203661e1111b11adb4d0f77bf4b210df45ab12671381d32aceec05cfad89572f35f91ee318bf9db6782022288528408c032eb330faf2533986085d07123500682f077befcbaa2cab5d9efd1a4a26b8fb7abe2c43f5187a5e91548fc0ac052e93580036065669fa3e4c3a0dbabd5fe3065c2963d0f4903b32d4b5ac072a0a2d0fda1d294a7167c00c9a22531d73a2d4027f347a46c3a2a73671ae3161ecd1188cc9ec9ba2276006901ddf24214f4cef694a3e71ec34923fd7be0c060fa7528a5bbe7c06d0c781c1ef3ea8e7399256f5e0d697e97c879b51343dda22a79425dae33612fc5b6a08c5c57e426476224673f69c94217f83a96231afd683851686f138e257a2e96f3b2f2ff426c029632f690a90243c66db26c40f2b222b1440186a3c7c93d91488ab39813f42663fd021a52a5ac79f32a135ef2b95d2a5484a3385439744d76b34c6e9944c67b12197bfd854e180526ba218763147f1916b4691ab5f9aa7c6848112e9ff751adffa04bea6c460cdd131c57b8291bddfd1b39a7ae1eb6c26ce9415d4e31cb509fc203695f6f6daf9fe62b384e5c687a9bc0e7390fd1a201707037e689c35b32d408a023b99cbf73b83d085970b5c99ba578178c4207ea07f02ad659e3c0c66cac8da3db949daba942bef757438aee7be6226fbc46088567b904c9707f19020f8dcc1865c59b229717715b6afed4d625bc9343a9429f27ece431452b9320fc5a4cc9ab8a4d789827f553c88afd590eb16c38d365b17964695c87bd7d7574e1fa8bb81d2ff01e4ca0696b7cbcc7d0be5a643b3edcf11b2c5236e10f99816585b817a417f7bd2fc6aca9a14c8850a9a2282c7de51a8daf87010dd2d4343ffc2cf62017afcefdee5b96298b80ae216cd1042a556a4988ebe2276037a694a7f855412ffdf215fb628ee11c968f55bc4ef55c219dce140258f8ab5547fe54fc5883af48fba05e96bbe1350e066ea4d8c2db865a4ad00138b6bcdb9b8ef50567e7df8079be77f753a3cd8b56a84a6ede1a8796fb4bcb2e8ed83d5bc007119f10eeb94e136caca2b0394c65462c8ecb05cb72530d2f1679f96d68dc70f99d83262835b05722fcf25d21b7c3bd9bb6496be4310d933d17dc6c8bae5b33fa6b137dd32217ce5ec33d766aaf13ee2652664034324d3a8c25d1b96890c96815fd4263aeaf2e7522260f9536177ee67af853567a9d72e2305c0862fe802aa56d17bd8d60c48c5cfc2e7f6de57d1f31d06f2e5700000000000000000000000000aed511b592259cc3b87b80905943419fac70f1de49065b46ff8b22517ea2dbbf71b9e08224638f5fb5c4c22f446bf89cce3199fcc3fb314abc11d77eb97a1152121a1276ef28eef1c00b5d5f79362e6043db5078727bcb95771791faabd2f58a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f664825f9927c6643e0f9e3c57c3ec82f0e1ee35e76f7c41647877572dd8a0e9b8839ce716a1a049130b0d88da47a855c9dec040a7c3f5304c031231a80dfe9c0b33ce517737ff36f58a6793241f2018f91cbc8d9b86a19bca37fb6c3f73778cb5ad0b59311e5cd585b9817eb6a69b942d9ca8f700b178a2d4eab2ed5d3cbeb030696b76dd53e3ef76633e2ed8681540cd6f8df74e5cb0ae5e29a5b495186b34c022ce5f1ac223d2e7e524f2b10bed7b39c2ac40b50f7efa9ff79c6bfa516b866050a0844b3b594aee64e9e3842ba578eb7b6aaee4a2e246599cd0697f848fb35a89782e203172aeca8d99e9da4402bb96b34597dad320f783e77da6e053a226fdc2e020eb9c8132445c0052a77a551d4fcedcd54ca9d9d3e87ecb6ed9ffef2259926b80322f6610314c48510dbe58f1067f8e399249866d59168bb53fe862d02a12cf0970222847547e408a63d26acc3985474b5a94b7d91dcf1a01a1f9054f141a4d280f4032afa4dce9b7f8b2608f19b9a5281751b297ae0876a04105a37f550683acdefa602166868e8065a5d48e692b1709d4b66d4276b56a779c87297afbf4201fab93929de9b82109bedd41cd7c8159048592120097ca708bfe644fbaad58f29947247e169cbc98ec1559ea347de6519659e49fc80cf2f366d0dfb46b4628c7dd92b172de2372d4442cadfa1ab164c68d6aef2102f6cc35c66d0f5ac8cc24202b072028de6c30afe84a1d2fabcb60433e096ea47c8507190400c6d8175a648d2fe62142e75ccdd56ebc45e35066f472a2397f399781721c607df8be03ba0562dc8c64f1489d04963586382c664aa493653e7e1b075853816091794bcc7a767c18d95dac6cda71f4e305801546e7589343494fdb41c40c24e57cc2b041f040ed159bdbba64883b696a7987b8eca10bda9bcb2f40d9d0eba0dff2a66199c718465cbf98d4508ba5e6ae556008ff8fcbfda1c6561aa56117ed84ebbab9a0e1053cd0407b3e97c499596945c455119a2974b5c69164fe6913c5b0e429119c243e34ad5cbfc732dc5a10fadef1ec15c7a69f7092f70de5e804a71577805d953ee4db3123a6f2ceefc2db6831be108e1916910f04d1e79328cc4243d361f6f4e70bb7f6363cb1df0bc596f4d829ed9052a3be95f43714bef41cbe8e90881033f5d5002b3f5591c84a0bcceb343f659fb1370bb3dc55236001c5ff3d27f16e104061078a1bed3d6c6d272c4d1eda26abbb8be9e165ce6f956531af917c47676569917f49a1cb6895d06e1bd83dca166513268c0a0ef1053fdf7dfd053fe415a9ab7e31cc024a6419a0c816df1a51684fb517fb506f30ad05ed8ff44f5af76d581444ccd030f37e297d151b74a279cc2dc3d3384a6ce32b7ff9cf4c78c2da91de788a148dbc9b6978b9834e61534b67fb67f4daa37427b621b50e131b05286367293361a46f6a49f74097203d91cb9d94d03cdf8eaf50b00611e6ba4f0d862a9770011dde0099e2c050aa2edbe05c83a10a34138b88630630f9c9c6e2d7765b677eaa7da2b973023e286845c60f10b0bad45f8a8820d35a221223fc660161c680f23168a06d7aa12b5b2ad88c11feb81e748b4a9e4be62876f30153ee2f603354c1f8fb092e0166f8a34a485f80c0fbb82ffaf2e81ed19dc41b2c88f8c13363797ba5848e04593cf727aed13483c024ace79f6b0dd6478253853386104b99c371d882fbce7d0a12a19f0ed7f73f67d92a7d57b223ad02be0a25da93a9b64ac37585d6edc0d2c1bb653828f823eb8a04c6796e3c4931b5f04ce18c93c0f7ade1053d064678be676f4ac767e32a5f2adc00e8b3774ab4d9b7b377a7a4e9c43ad8c0594f7dc06926570f44264920ae4ee64f51412c4c15924ad4eba83e276303292319cd2a370370ade893e8ee36129adc713069f28a171d693380316d0fcecb4ce106dcc8ff82d6d61dd3dc44bf8e0ae36b81af2d66263bf28cee502062da8b6166ef9563c2f86da629a17956489b9f218557b23c8eec51197a933725dceb856d0d4a158500408bee9684163ff37f87de37747d53543636375ff6e33342f4767e5fdb06a1fcf6bc792c427597cc7ed5555e583160e70ccf68da9738e8fc695d5a383685fe7d1401fa916a9d801cb4c1747785eb6d1e538e542723f67df08f1995d1175e2049a37159fc689f190e0588277070737ddc102a7457296fbeea8dbedb8c88944a578ab4c68badbe6ffea13a400a739224309a37118f7d57c66dc4cf9a2cfa5dfbdf1df96afff8745c2b8bd6bd9f3c9eed0814a4f8f1828f513f7b7df6988c64504a6627dc125188b66a41d45e1ac890ad5378ef1064f52a95953d272a1b0a8d4c085f92f4de9cc33cdba1c2150ba721ff581af844cc5b4460162c1b2e8a7b2159086191f26485ed68ab92a1553ac938c0938f02246680c", "", 1, -2044221074, 0, "7d851cbee08ccd71d52615c6be24383f819973286d0acca3ae46fe74dd8c4205"], + ["b866b52d040e57df909c67b3b09bd165418436d85a8955d4085b0a0ba58113f10bd2c432d801000000085100ac5265516300ffffffff5a5de176f1392540b66f76b52a86c14ef3b8fbc56cab5831cfe20d6ece805c5d01000000086363516aac52006affffffff068cd5b2d3625330c9201dbb635b07a9cce05879a428eb34a1cf2442ca6c9ab900000000055165005153ffffffffe7c82b32cef29471f784594029cd34324e157dee5d86f4e8acc03dc730e8f599010000000753006351ac525128cab918015a6d8a00000000000765536363655251ae2db8730189eebe03000000000000000000000000ef5fc2460175a14913dddada8af856dd33068cf95e1e2747255e7f1b61d203dadb0f7578ce8acbec871bd8afdcf17c103505bf792fd97bfe9ec8ae2992fbd3bf0a0b80e1f4b2986791c699517e327c64f50d3377e6826572c1efd368d59ea4570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a3d17319b109769e602d14d2fa14d1418a65aa8d4019fc93d46ab2c6f99fb199d6e22ca62cdf16c40d1ac1499be25052bfb841b335b8cecf0e99e231e3991520720d644616fc76f141d1061bee6b1f38aaa4cc7f10a0a1f74efe922ed8fa3a55f8ccf01eefe6b09781f8786b2deecbc86e8b607e3167e548c80bf3e7c5bae6021446d0086feead3c12f4512ab8c41b0ff816cf1b18120ac607fba39c047ce162020c0ac0c147470c472df2c060a6aed808514e341259e2219bbbffca8f8968ff410b05ba855f08c63a35f7baedbe784c88156d034ddf8365c40a51a20a066219ed0b79ed77f1cf3de00bb2dea381253892f97d8ebe3cf1f3116a8c63b27cc33ba9ef03185612ebaf31868c75664c3480e69aaf30cbb05e3b111673d478b8f5a63a9696023041a8fc5796f85ecbd7c6d107a3384d26a2ce6453ba8589f81ad6b9a55c11d9032594ed66efdd749e20c03f3be70df14a540f5608280f8e7ffa82a7613eb33c2103253ff1235edc39fe91329155f99122336d6f79f096938f6deaf4243da33668c90223cf741f1dc610f3ca8b792b47e506adedd5ae3adaa9dd762f0cd55b7f58c00e01cbaefd0c40290d9e6d5044be2534fcc2b4c5232e11a6f1e610a3853030dfea44e84216a97a3a206ae314382a21c4a2788fe59ce1820d2be1eb5516137873625197e59f148a882342fe63ba61e8ce713394099806f19a0159c1137d494049ea34143f8a96dcd4b2ed3707f57746d5f7aa37153e7b9a0ec081cb178ec772905651b1f12bc59134df227bc7480661c94497df0dfa4332c35c6ff290b6a833377156f019e882af5f9bc583f2a15ed1390658eae97a8ce769409beab40cbf7cf8500e3c23542fdc15455a6544b66d4088e9e53e16a69de27e7a1b6846a20b18da248610ab61ad2d74a8cfef73b1e2915af0cf2d7297e8cfe49d1349453daa66a93b32c3f3dba0fc13e494804d3ccd98483b1798de0613012db70ffa03968f1d257d9a3e33fd292646af9e65cb0f414e79605f8375ca65c4635dbb487a7b8352dd3c6580021f8a80d02724095ebb40b06ff2e83b782c44a696a15f4468b518ca6e3d401fc028217cc9994b306f6141c9d949e3adf9b2cbeaf20361953dcb4b35772e6ebff36738524003be4cdc340a3a83151a81df22b6aa79e0c004376716b4de8ae09881af893e614909fb6f6bb2be3a4b7013e1783899604b641245da164ea1eb686c897c2483204bc471271a7a5a2abd280b8b11e1f297246366845a3fa0255cd314e0b9f5af6276acd63fdd6a13b562c051c27fd42e2dc4c129ea5f42d148d7129cbc9d9e571d17fb697c5c5b016f928958a98d86a5c6488065e87872c9acbcba07126fd3b3603b5fb147a0aa75bd7ab675d217855fdaf0084be2f757740a2e1336e9368e7d6c3fcdb2bc8de5c00506900075fd5aacf0477e527f4f48f2c92a89c1bdb4ff459bb1f5191eebb3d6b5fc5b7d9be39cc5c0c2fb5f8138a1f08a7c8b0a02449afdfa3201162027e764955d3a7a34b8682d44f5a28c4cb030cb3145a4126df53ec3640b49fcfa8da47d67d3288111a2bed6dfbb1ec04c741a2232bf3570e9b07dc5d1eaf0f5790960dd329efdb887692ff903be485080670290c52b59bd7181cba50be3d0be65c4af0838a79a274f409f5caa63ff13af71e5b56c4e77f7caeea33a91a2cc943fe6a27883a174638148ab1d57fbfe70e992b0b40e9470a7b7087c3c2e9e2d47d42db1b2e5da7b108f0e74136892c3d6d4c2258d62cee556630b5fca821a8d1a7a11b9d9110f3e86fe8df5080eda4f4799eb63a3b09acf6e57ab6a3c017b0049685ff7bd3fc9564ae6f4ccb78f085d3f12e9090b0e85cda19f13b70dae6f84875c4ca2ccc3d2bd876bb160729124e95eeef82a92278831c51fcc489d54c44901c3d9ca3f9136ada1688e09646c67032ee00828ba69a40b921bb90924d9a6f497a7158ce2144e9b597b4d262ad421a9216dfce3e6e2d18e95394dd0ddcbdbfd34c356096441865c077da4108b2bcc0f2d01d5d0991d403831f36e4af440b310aadd6213e9560e705d3f0245b960a40a3a965fd1eb6731af42eee63ee7729ba05bc55177a63b1bcd642b5173b1a3ef9f8b2015064e2ac2c4b4cdad1ada1c3b281e473fbcea38ade6da37b3923ce24e09707175af7e7bcd8f3159cca7a55e28ea166838b0ddb2053604b0c8b642f1d6734259ca4ac453d690ea136b86a300d4e00a2a9aaefa7eaa92b544ffc841fb50ca6383030a2b14cde0997e7278c3a638aa44dfa2d5d00712b5df710b3d6e25a121cd0db2d7ad4ec10eb7889f03988b581998dfa1ffe31b690325935cff3de83a655ec8baf3fd54cb264275cac980338d0b1e5a3b07e0db625cab7a7eb14d219a524e1f4c1cbb5416af23ccc9414ab58dbfacf4929c37647cde01", "52006a526352", 1, 1642598088, 1537743641, "d37f2885dc97ea833fff9c52281301da17887a516541cc4a8fa5557cb6f97255"], + ["030000807082c403032f9190b82d71825ac3626cc4a1b6598359080f4d649d59eb4f426bb1978cee6c020000000463520065ffffffff32e1642faa16466d8a28b858557e50e2c8eef3906e216ea3bc9b7951089ef66b030000000151d8c567a8bf9f9f94d9ea086023738ca25b05bb5a9dc33bb1361d9ee3ba3bc3b60c8b770a02000000020052ffffffff0109d495010000000009516a53006a63530051000000008eb4834402000000000000000083044802000000000503ec27b7f78dea6cf0ac25d548aab0e36041722dbdc67bca6fa1ba95e8424627ff3c850eb96a11c05a0319821d917b89274bc57d9f57bbee1755f5d80b309b650c7266bb9682b05991313752bc05116121f7d3775e40a4f2522419139267400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000028f85d40fa176d0b3066d41fb0df060804aa7e49a34e37bd13fc0942711bc50c3217376f1dbb03a2cc4dba4702af1df6e8bf99c5e56fc38ec1ee425108fa0252252b56f6c6795d3b56a225d254dae7ae3e5dd8c87f5b9e5014a61822be0a86035700bf58542e481f70d59df692105e2b178928aa2d69b1aaddb2ace58e80d2d202175e77e62b7ee3964f966e0cd59cc5bb6f3f49f1c2e881ddf8937fdeaa06c496032957709b6efefe8ccbb86d90c6a7ea444d495331b2835ce3dc3a6758b7d74c1c0a07757fc5b5117297b96431a83e079eabc63a0363ccf5b75037b6ed63425ca8129c125ec9c2ce52f84bc6bd294c8e2861583c42eb5c9a723329d1664fcfb7f116031068e81070481ef9ce4330205cc27d1b0cff9ed0c181ab067cb740774c485992032a27e1cd514c4ae4c065abe77f8cf71eb7f1fdde948240f9c5748d651de23ab1030fcb4ccc97d55f5e9e106a0653fb9dfc6ce90d311a8055b06ae605ac7b35d93503196154aa2d594da635badbaea3dd436a7e74d72683ba2e0398e816e3c4686d250318d8cca178374610915bb60eb0d36e69a1ad515cc7326f07e84ea2f1d97fb3a933202e3e99589d1e56e89f27df03dbf3787e60f8e66079bcdcf35f1ce233d677c13c2d4ac02a70107f1bc06559391b45b903704c20d6e72fa0b82334c0322ad36560b5b2bbafab56ad3d80570fcb7ac2bccc8afb755f2ea058ffe710d4a38fd24330cdea814243f37b2f02771d1c97e76b14fe67776537c42f019e68c03f3894ddbbac806668ab0500c42883b702f634d625a518b0c47763947c7a5bad89da3547b653dbf3a9731fabbbac0a88933cd06cc5ae685e33fcb593cdcc594c0cd9fbdb1a486877277996193e6310d17a730943d56086c94e8e90856d6e54ed74652b74ff144387905c4f707024241c3071016a7b9eadfd9afa596dd49e096006b765d4893b3dfee07e2b08cc7482a8635ebfcce2d072e709b5d76db4cae841961a2fc2601055e3a43ebaf0f47ca7b30e891d64b49363b028c6550fdfdbc4dbf6870cb9e1b50df818c3368d744840f6e82372b8bb6c918113c482ce06dd60ed77e0545cf9ae6a1abe506e3d9ec52c75cb313f05b1613ff45fc310866d18c1973b9fca12fbb9e65939dbfff60f7cf4c5d8bbde8779df16fbc411a98cf74b842b29c9df5f0db83c01f24ab817f0c285ec08d3f32d85cf22906dc125d0c342e759eac6e2db3218d01552ddeda19052c0b040d1021563e8e134315f7ce57ea9a206d5965f695fa3365bb8a85cb434ea531414ccba1582dcb588c84d74c0f3f2ab0cc4a4bc4d3a808485f068765db05117ac26d171202d7c6109427281c64e8bfe45cc33c6bd29805610c852df06342020c1fc6153fa1caf2400eb85fba35512848b420488b8170761ae3caa1b6814e82c723aad1fb4245c76c58f8482ea589a09297b2bb5e51d37589f64862687cd055ff5719d512a9e9058c800f2915851a45d06811ea5643ef83fb7cd396e08365024274fcbc34fb47e0bb06561deff6792625f4ab66cb468d27ce985c79361a2a2c09b04003fb211593d32fb441559100b13a7bef9413ac71ee8a8fb6f8c2d44e366012bbea181368f514291de0f5157d74be24b7fc6a8c81b3c5fda81c9e3b9428b1383f3f9fd6537914bed70253df03216714ee085db51b4b2cdb9d29b611799711f0170085984ef1589e490e874ba635cda2242b6a1e11392f4f2a9806bfedb84ae48ee70a5c0f53ddfb293406943be6b0a9f858309e98f3551796e8dfdbdef4cbba16f9d4a16eded759c70ad5b44000a0683df109cda45486151133a95661f47e6426b79ef28bf7fef8091193c29dac5ae4e0ddeb7e5ce27af5495c937c6ffb54f01312e7f22fcb3bef33a7dde28a4682a8579b822d4d126ff700adda39d5609c89c65739bb99f629faa36b86cc8c046130663f1ec22cae05c62cad3bc067e06029b463353df6965a9903b9edfcd95da692fa45f2416eb8be3282eb9508ca368e99adc73e493e30ad1a65bb134ae6576b565cfabf0bc8b0d9e1048a2ca5a3a2f00706dfc0429419806491afaa78b4f50e646d6f44e2a15ee3e68611073f46517ea09e42d4e55ed72c5d4ea58f38ee905997c0961b9427db18583874855b970528140182a51afefb68edea747f2464bcd527ac724d114edef0f6bde4df8e1978c91eceb61b42d581e4db88eb67678d3ceb0b66e5dc06587b24763a7d4c1b54374363f882bbae4dae3b4f71d88851004e88e2ecbef25c2dba5489e323bc140d94540aba76fe7317690b50300000000000000000000000033de9c5e4829c1fd022f8e643a10d8dd25ee36159689159d1059f8832a824119c4295e0cdd3d72be02f79ea0d2019694b2d6b8feaddb528ffda0b6e4ecbfa961a1caa4211aade6ed1e34a614289ef00227d4f4f852b1a65f05b801609b3878a7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004047da47f47401735f6dc4b934677c88aef757a3300c63bbbb1f8069183fa694716a11306900ffa58b6e9cab1261fb431d4a9e8c68f9a7669544ee7f66f322569d83bd632ae9ae158d8328ed8b1add5ecd093dc5466b678ffbdb7d36e04ff0f122e0947b4ba81323fbff7a2df226532a228ad7714745e792a6d0c5e8024157420330000cc129ba88d5759f70fafd826c161c9ba7b1f41c551c47c2587451d0d749021ac9429d70d0a79233f85335913be9983567e6f3adfd8ab53bc533d779033ecd0a03639ad105585fb0f34152c07543f9cb7cdbe342d4d1e21666a858ae6a2b2a529fd5f1d75405c27ff9b809129f0f689bfc7da281634e1acb2280ef9595aaad480220080f02eed721e734cac5573c56b47a03367166f85038431176f94d3a1c1486020891028319ae99f99abc420cc70c8e2075ca87accac6d25b74fe3228d70938e8030835291d41db6866b72c8521e209998215f51fec65413643102cbccd7e7c576302188165baeb7f901084092320a6ec01d2d86e0fdb58ed30f0cfbbdfcbefa6749d0320b35f205da8f0f619dc28656e78963855239c5eb45ee73ba66b07e56ea21df26d2460fc661d7f551f541ea8cf8e8ff9f6cc06ebcf10ef9cef447f39ac64f359abab43729cf5e1ed55d547475569e356d01b9e1177dacdfd83f758d5d8608de613c6911749281b7e3eb7ce72a8dbe83003c26285a97f3b17f3796b83e3a10b43724ca2f4c91df831255dbc1f6bb5325403c808e1aa0f27650c8ec7247b99feed6999d0ad96b19f470c00bbedc790280812a8f9a15ff02fc963c5b90dc62be22e8a38590f9a5e058e09a527d1d894046480dbb9a4da16bbd2e1e3a5f5aac4a431aefdda25940f4b2745459464f7349e05c10470863d420ce2f5824472b74a58e6a7e324a9cc88fc9df3e59bff567d1837ea76681d1e11d30160bfa4e13e4bd15417fc3dc2885235393d656b5fdd90f9a269263a51a034981e481cd0386b1fba82d659a30f5a35438ad43948ab6872b29fb5d2a21fc6135f32b8f49495290327230c342b995a285f0ab7ef69caf85c7782fbba23d7e1a7f45bcb4180ae7cd28303160307e33058ee84b629abff5cf2d5475d08f632d0fd4f55783d3104be3b84a248cfda1efe5892a277db7056df0f0fc4687a9afc0ec8eefe6ca817840004039b17fef68077af0fa2c2889b5d498f1c7eebd641b28d91be394403c14dfcb0e81b3caa3d73e62591172c855829f331b668b300536c01a11bd72a13076fbdbcf65d7e18e6640509c53feabdb5bb234d31149cbac6a99ed88587fe5ecbf486a5b1334c7839e8af48feb7d4824f4c4ce59c33821b466dbe8967fc9e568c28d8da5d7e3317b3134d096b23b9f3e304efb55e5708c337e27f8628ad0fae462f65c86801b0539b70d697efb30eaa680d5844cb936fdb2229d4e8201f8e98acd9bdfae9e54741db83e8918ada9a9c216b32d5f37b4673d2ac67294ed68f921f830cef276c36fec6b8951d25d5b8560325676e1f1baec826eb2025fc4e4d1833fc89478c2d623b4d39733099b3d45d931042e14785df3342f2d20fdfa3a69a9282ba2b093740990ba5d02e1c45893b40a084e062ab7aac747a6ec1c3ff0f0b3daeeafbf43579f397f486cb81293874cba594ee78f12db5ba95e99eee3d0025cbe2e9dccf8aa7ec728fd2c09955f0764163fdf7a9aa9fce3300bb62e175bccb86ffc361428422248101a79cb6144ea4abd0406d65cfc8012866557a510b705b72a0a053c5209901be4f4838d1e8e2952c77a2b966df021df67c7c90b9bad2d6b93295d3e73791c65689248354117428f7eb924fc1e6ce81681e3bbcbfb2a77a9821a5f05fcde850ffea971f56f895fcfaea651126c749bb2633f4b37782dd31eca3f274001330cf688ff0c9e822191068646a3a8541b8b9cab831a6f6e8c05b1aeed13ad6e06a052ce365abd9e0b9d829d2971179101324fd3b2339de37213cea2a2663cebad79dc9b77a71f93c2ac257f9d05d1e97854bce9653920964e176a207da11a8b209fcbbeb42ae2d78a57e81090281d6787fe0aa4c5154300b19e698abe579b28e05eac4094d96331e92f471759066ad6d5e49f90fdd880eb4188cbe5cbc279a2616498297ca554a64b62ea23235067a6f06f395e993f3579bab5fb2dccfa52d604cfe0e69301bc6c955ac893fa3776d03ec605e36020125fa6829d0a352c59ba808228e9aa4e83caae1bc7a96cdbe2d49c36543e3335c5441efd169ea2087eba681cc5205c004ac4fd1eba322fb5d429f451dcc949addcf71a1707fb409fddfca4d693ea99de7a201a119c308c435e1af2595b0dd7d9a88582878af26249518452a96c87e7cf06e8feb15384280d71782b47fdbd2c0ed8f288aa0d1c0823480f1ec332e64849b30ba2038507be5bb218ef80e", "5200ac656351", 2, 846273779, 0, "7819b1d350bd8ac24eccdc7bbba9c1680ac3ec3f0dd153a4349212b24b778c7a"], + ["2910534703bb7e66e62eca3aad22e72939c5946b7a6afe0886679e6e278a9ff6a854e967400100000003656a6afffffffff9ceb321f05ed8956bbcaed2a97239891fd86814f45f2c6cf8517ce4f67262c902000000060063526a65acffffffff54e6fd072d4dbcf56cc193eb772addea12ddaa1d1cc6ba0df6da49c11d83419d030000000452ac5165ffffffff046a6e7203000000000763516352535263d5421a040000000007006351526a5300e7f06503000000000500535153530d17640100000000066300ac6a65520000000003000000000000000061d4fc0100000000cfbc24d6023ae87b64ad4087a1c47e464fe67af6c5ea3400661f2ef894dcc71e8406542039e0e2576a07b833da63e18d8d70f2015f28a07d912d46e41bf5db36ccb0680051813ba75b54fb79a5e05212114563b1a086de4bf88d1e547a89ff25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f884e810e3801b69d52f11dc010ba64f56e80374f6abb43210ca925b1150beb3947d477ca2d7d24f9a611ccad72349fd1768382aaab4010dda3a69b52812ccea6fce209222575842f54b8d7da11b248c4a632940bdef563dffda0fb5a48e9d6788f0e2d9051451e0e1d18a2641f3efc65fb9686a3a4ee891113753f44321c3f032757ec2f8021d3ebbeb2b5923125f7fa28a2ecef48cb88a7a38f23fb19205d760313bafde6e93afebddf158cf922bed30f0d303e8a8fcbd710a3e5f43635268e0f0a01ab0419a985730741005a069b4761df38cf6d95bf2b0bfb6a31077907735026bea666f866eda112b30ada45166cc978c06cd3d5743d0f96cabbd9c31e850d88021b5576f74c47b131142daa4725c22ee75c3e5a2b3c93daccb5b2848a34f4cbd2031066f2fde8b5a1bed5ac053e8b7a8d66e4aee3471efa5a3beb0c94d27e377a4c030938c1a3fd426718976fb2998f7152b130af7fc4e17ac93f94e54428710ae42f030284a3c66adfc29eadc4c140b813f80a0f832bcdf2c9162815d151fd9ea444b80220993758109ef44058d977fd48f7042c6fe0164bf90adac1cc9c2435703b96ef0f57d6a617bd926ef79f8e6a9064ce966fe8b53ebbb886fd45c83aa1504a0708696e787fee5aeb612d25650c6b75cf8a75f2c9ed3d97256d014bcee103a47e464af1e0468fa7262130a70472365c825cc1421c9adb0e504b285b6b6501f1dcd35ffbaa044a4f4d385da53a06eb58b1e94f73b66d754fe938dedd939b7c32964dad4b5f0af9270c001aedcc337401a6a900bbbbf7abf2804beb1f981d0b2df4ee52466f32f7fa07951e57769e6028145b686c26f7ea720cdf513fcd56601c35f065ad79fde345941ba48363f46981e41285b732e12c81891f9b27fb52b7c96c62446ff755a2bdb3a08d4089dde2fe84da1234128c56e94db85d6e6b0619b2a278ebcd9a37854470aaf81b0fa8a9427bd3278e223ff795aa39dd1d0e7dd0c7c235c78c1abde01cd71507a24b1f18a0e43abae432b548f79c513d752f7d23aa9b95f40245543d75cc6e48ae9ccb64cebb833e4ce614051482b0583c762c350b508ec09ed3cb604508c652b3478f52e149b6e4316dc094e3716a0f94c99b749f92a23ff60635df6ef9f3c4ce8cbb869e85ea38b4b800c71e2383f3bd9be22bd64464c5178f347ec79bd221270bf3fdc019e1fb96c278c03a78872169ef41f7a0ce7a7af2f5b2ce0cb13db69b4e39fee4e012cf4d88e48efe098e849be84cf98d75709b4407b637ca91cece473dddb655d4cdd6be27f1c470e73bde72996fa0b937b8c6a680694919d7174527ae2783866d3a741cf85d2ed6a917b2cfd1c22e3c232bf49db614cde4aab2de0b18e30c6d3ef37b6639aec796827d12159001aaab1697b4f0111d22d52139abece99eae98e07bfc211289559cf518f6ec31b6782c461fcda046058cdf2a811f0b5c645e86b5cc04998717f3b51d35e9b62b393ea7845acf645654d51b4d8254d0c0e81848d84e0a07d6e246e7ada9048d6872a8f02bf8f0a8b4e6c4b889b05c8f73f4c5eb21de3e00abf45b118d7ecc69d41149c20dae8041c8ad8974927a50f70051fa1caaeb6e8536fb3bc558cde0bd4f5b2eeb42fec616885461e21df911d67fa71e570b94c8ecd418c70b989a1420945bb4e33d5ff4e8e6e423a15b6b5ba7fc062c4e930e7f1b799777f0bded76e5d7c61046d07be3615e25de7d06af77c9e562f127845d295738074814457e43b193d93f75bc1615c513b050ec79d58a3d8cce16bddfe84e37df07c5bbbf24d951f469a99ebb4ca0d4a4a6bee872f67602d63f8fafcadf3894af8a662ddad5e4e9955e354608877ad33ade9018e75bbdbb4cc0aea19428970abad69bddf2097dc44f9f6857e0fb566401305fedf6d57c29db51e60af7d285e1d80b573d40323ffc478b3a1500042c1f43109e0eb8aacb70b66bbaeee552774f146282e4b22a152c4de6c2a0f3efe1a8491064ed514c3640bd7b23d678ff66cc35076c7ca944814962fd7dc38e8850ef11c5b6175ac9a5b91dc449a7ae6d9af7970f209db72c45dbed36a1d4124bb181163fb802615b10847e19b654cda9720c7be9ad23e8b28e89240a082931e2ef416d69bd3390fca18ddff9a10af5f1e26742d129eab8b381bb5aef5caba67f78a55ef7129fb4bad3a860d8519dccb5075f78947080422a7ce0627ca575bae2d72ed20c171a6756617192e68cbd5d7d6d360a09a3eb7589bb67cdac8737893e2b8b964a75aed6f844600dc192bc1b655670edfa1a05000000000000000000000000e257c5de9d485fcd065fb4b5fb6c522d54bfcc28442092cbaa58e8cc179dccc45c3d341cecec4b3e04aae8d98cc6cb711c4d2620ca3b147fe2c65e4a288541f0ffbb604310747e662832edd3489052e1830a849e142010168f36d037ce54134d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000383444f3ad490d0a6600b41e3e04334d0d7f755dab23b6b44b99e6bd1633d7e6ee3cc7b1cc67132c188ed34c4e9c9ac658f12794146757e9704f2e3aa1ddb4b32545090a4e370ec29da673000c9ac7efa02642497352d2aa738be897eb508e8dd88aced9d1a020dd5bcd663e2cfd1878f30b87b5dd4e1dfc972e1a70d65c1800030a248a2e5cb827c22d6c84ea63d953c420f055f4785c7720a61b24377ac572b102305c8535172866c02cfd4f96601cbd586147dedfad3a1b3a2d51bfb789b221cb0b0050c016fd08b0bc102ead3300e9c3c56c3c6230ff8dd98c0663ecb7116242a1293dcbbb4b5bd09c4b97c04b1f3f9e77a9bece3efbb9c5a1b6fb9823f2094c480300716a59f12f861bccdf33c59d03639d8fa8e3a12f3df013f35dfb1f757b234c030e88d53730c051e1925a317d3f9194d614d927e911cce5c1d8e680394d54deac030d9270a7d1f5e1ae76da1b42dd86100073f784c8c4c7dfb040c8a7d656c7fc3f0221878d3bce217fd5ece63852f2fa4668e6fd248e01623ff9c1ca1d7d3d3150b9020ee9d7a3d38465ba4ee0b6c700e6fdbd6ed28d956c993200cd1248bb5a0020bc0fabef7a9980bb6feed4eed4caf85822b7f8edc7713dc97be5976db47cffb677b3475889e7230d188309e0d4efdaa7c974d2f955fc8dd67440899e3b34ad95d9ea8bacc1e885eba813a0f2df5abf85a9691094dfef8bf5f4523c7137b6abfab94e9a469e488321d01a5418a4495ad83b2616e760ec7c4e29bdad7e77d8995980732f028254a79107e68e06caaac9cf635d87cf48e73eafa7538e66c74934b97cd126f1bc5987eea8f85aa0baeae0caed3e49ba737af88fc41c4db60be5bd5f631ab8de3dd34f2bedc951adacdc070641bdf5f688b291e24f69b054a8889768623ec7cc165710b8c09eda8e322557b2473418fd7fef0ebfff04feba75b93cd32358e8b10221d6bad0f92d629fb2afeeecca4680e6a9c3f5ab268a87c0e8373541c5b7412d39758d72ad8432246208ff4b250afd525d36f2e00ae516baaadaf324243217f03355b2759f7fe0148f3c9176513d0a6875e926f375a0fe18187caad03832196bffcf463bebb4f9dd5d4ae5d80d3e0ed8f4445230c407811a5cd8a4842f963bde0ae3d93d5995b33c8407fb39712e13571fd8d6e484547c2635ea0d747e2e7db643a9f73090eae631a439feff8d31fe8a5498ed576227c5535b17eb432b07dac0228e4ad66374c1c0e02864eae314c1d1c1bba658a65ef431b7d162c433c22444be1dd7a7a3148d1e72a46f862164ebaa10a07396e9b32f97d4faa7ad47b33c39fbdfbebf54a201f30e4bad08a428174d7744d8a4e19f6175a3b3cd03a299b640eec52405c5bb37f8b1457ca867d86926bb2d5e5990b7ecf5700594e0e9bc5fb8015489d6b96e57b0d4e613d4370da4a877ca7afbd48cbacd24c7c33752fb6e7a5a6a2f61b755e96c7f747efc3a4df116b28e1204a0fa675b3155ab57a42b449877e67127a6d7d98c8f2e8810773e108680f88595a5bcdf2a0f87dd8ae485de2f8312c7f7f7854976678a798edaede051afc0471120fd91c8169e2bdf2a6019ab1f530a37501182c002a8c07466ab1ef50e52f2dde4f6bca7aaa2ee79ec1e1df542df14569f62cea56e8cc344399404b27c8ea2f67c453a5701271aaa677b1337a36abbcbe7b8735bd19ef98819db13d95d08e736b40b60c016936a737894db3604f50ae2a35cf3a63c1180e172eb6a0dfa10d27dba2e8288829cbef89f01f557732830197388b0a61e65d0396eac56d953f5c70ed7724c61a4068b8dd083c9462cf64bbf7588f4996de00f9d2230ba462fb0601965de50e2539c620765f57016d13c18358da53b2ca5e70365b04a32bb6effcb0377ca8861b16901afb4f6b651b17b05a23932f9814ef3c8e50b4f8eba58ad2ddeddcf19e70d021be93bfc1bd3ea9e2cfe37b32721b393f20c6ce5471563af190e607b6a5ff2099913c610c26be41738591cf48750fc64cb5ee22ecf142fa678224fe344e3e23c219a9686a0071c3d68ea71f0d2fdf649ded863f2295cead339f0c83b96860c43f6eb94516217dd876f433d4ce14c4c0425c5663ee89f0913d011e9f983f9e6e83b1e7d5171b4ac6a9656a30a6053a67af8799eaed10713fe7b10becd40c340f6037c21eb9838b9066c220cd664a6b9a13ca01c387d7d65d8e48c643e8c69a5c0a82ffec116cce0b04c4a837105cd9962c88f5dcffea0272a488e31cd63d8673e653d12f9d1fd2db766110229eb7fedf0293e1022000000000000000081cff005000000000dcd84a6fee3979ba4122debfffe7d1ad30a12f513d71d09289005c933b17ce072dd7fb8db07521fe3571511d60046d0b993ed81370dc0a9a943586fdf8e4c5be7e7a91a1f2976a09731f66602179d0637c0135fc21c8bd0beecfba5b930fa5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e984cdae59105d756c7e2368de6ade74ce66d55cedf7ec4e8d75ab5c929a8153e0280959278dfce0478cf44a4e723078214170c0bac7e414d0668d4bdcaec9847e58cf4e7b1b653b80907817a39ce0552beb74b6a96084406e0400f7a502e4d217c7dd72d8dda6cd0f66e10a26b90418bd7b9966201c015853786534222e47d020723fdf9e6360c9cb41f06c4c88eae4d26beaa4d86bddeb757c1dbfedd9bda8b020f75b7f8fdd83223778745986e83ecb9a3762512c242ec0919eac033bbe19ded0b01c45ce157b3e4dc1c901e716013f669ecebf5e1c8db6fe3ede533f40c9afcb3d934d4e895c795a0e18a67daf961f4a2252f2dfe61e3ec09779c3e9a6780cce70215a036ab226326e86f3d036094b6190417f4d7e9d70327aba6464d4715f516d8021877e5963aaf308976cb3a92a782a848fe49ac07d7dcbbb60e7c96c904d6d82603145a3edfbb691b13eae095534c3e14d88fd669a2ec220c6fb11a42a463d24024022e4c297f601d6b48cc4789fc0ef806bc300289b801fa82a16e6928526a75491d0209f44c8d9875c1429e95936c379b9b86ae1b4f149bbcb58b0ede3f8799e78ac8ab6d603e02eb85b9ece9beef13487ad1526f3aa9a97be3a06dbe83df879d7992da03257dc499b479d537e4dbc31e04c6a70047379401e9527c7678e5c332ccaba2828302545387abcd8076af534a789c422326f12d6295bee946980e286c071d772aa2ebc43fed062e43455e182752b2b127b1b1b2b6170ec474fe55d174534ae48e9897f096cdac55cca26291bbf751bc3f255be541b52e9078d36abb8d4a51c47eeb2397cf51cce02e975bd6e062e2d21614b1c0a754a4c1c320a75498fdc4f18916790c5e028a3bb6f2cb8724b5b0cc4e3cd003f1479cd2e70d68fd2f39e622ba553b80237f328ed2fba781184ba6bc129201d0f40612b2ddc257caaa003d878722a04b97320f41701d7bdaeacec6bc2644054db2c4e4fdd3d9637b8cd3299f0af7aef0ad4b2acad55e380940681553f441367eb16f87409f5efaf32ca7ff982f787281a93c103784e7cccf468a272b46f24c43a03a5815859f6bc9159ea53ea94456a1bd497dc727e7a5479dafecdf235c775d9695cd079106b1e52b874193e72805f0e54e8354625f798f8d041642e88f98fa047bb85ac1d9fb3a5354880b37d954a54eb6b06dfcb60accd3dad2698bb918a03f9653ea7aebe9a844e968a645b2afa6e3117914d7f0cac2682d036e2d0d2db04bd7b201e6cb149a186ec38e4ea07896353dc2bbe89f91ca3e5952535f29163e06b1dfe0cc0da0ecb1850e1e80f99c687bd8e188e85f834a83b3ac9efdaafc17eba0d54393b18be15cb1073ae21aeb7d18f69de8d37abe164e399a81ad7d9f3b2e2a3c0ab1fa488c018de6db379a880b4a2c4f97457fbfae19d4dd2cad58e696ac1cbb984947d5269e7b8e4a4aecbc6ad276ac707f48400aeee84aea5e403b2aefee9fa00630ea982da9b712ad19aa88914a1b11c60d75f1224fa829cc90eebdda3c34cf0972ed3ffdd0c66866925445013b735f3a67dfb41c604024a5436f5cb829665db6ab1fb1ba372240382d5c6eef069c41923be2cdd6146e513a426f6d612bc78879bca8a512fdce7e366cd9470e57a26911ee29233e65389a4053159faed854c97b2d0483522567f1aef4ed1d193191e670e61254c48500c2c274a81c90efca8adb8ff1b6368f8b9ef612a9588704808052f0f36e8be7045933257b5647d4cccaa4ebba30133253e210582dcdbdce339fb07d079bfec0b1c709212bf30c4fd1a63136305a663a488a6f8d9373597f2c0a0594c33e8ef5fd82f270649fa538eeb055659877ba4ffa9cef3e892f43fb5dde58d35663385d60ce3c8e4b536277ae8b616cdb3c4c6b763a6c55eda45d63f07e9deb792bfe2492267294e7ea9497eecaa4488222825e31104ad975f0c6f55072a306d1f6e10275d259062e6a0aedcf3e32e2dc6b31a89d25907945b69d43050cd25056a37530619f4a5302f27b5001d2abd81268ab1e81eaa047f649e8d2c08db40c700f94e68bcd8af66bcf35269796f3d516409e0d594299e7c22314347d1ec15b553600c938063b8eb2643064053f8d3021319ce7ad564af520c4941b4719788955d796315b549d98e4af4c1911cb92909f062d497cba25f0142a34bd0d707a7f785ffc808bf5adc79adbd63566d668496e9c187078d450d658c481703fb1761a05b8b8b93b40c2889fe5ae66cc662ebf172dec73ca4cc5af4a05582edf60da7edfc86e4684945eef29a5bc58dc22a623ba88984945dda436ef2acc3a33ad40fe57a55e01ed95681d1b7f5ce2d648bd0dfb6ee9b1ff36a2e1c50651ea15295c0c3591e1443979dfade061a35afc36b8193610cddacc023fb24cde326b484fe3594d65a99373e804", "", 2, 754103613, 0, "201fc955a01c9b32a554501cd3c343725834ad1b05c29a8eae4e38c106f6f614"], + ["0290ff1c038fe4d51858e2a8368b25afe54615e81c26c92da62d5a977cafd9be3bbf76c96d030000000753656a6a516551dd97e4a2bb50b68e40042d3f07a42d15009f6f8956f4da366d2cc5f9c69bff1d35eca7a60000000002636ab4e97acbb39feaa7c5df5eebc964815e41f672bbb4b3f70c8dc0b307cb2f1474cb5fbc9200000000036351acffffffff0113d1ae000000000006ac6363636a51654711540250e7dd05000000000000000000000000ea264cc2b7f62f3530ea3f813cf91707788df27616306c0b109b289f22c22e4aece4b607eff3015715a8bc54a7c5e2ecc1799f9227ed435eccdf871112117c075d230d4a5fa38376a1b18469c7d2a3f04a02a4850ce2a785675a71b803c67c6800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000596d5a0860bbc69cef07e5ccd0b60b56ce496f3962b73ef1064f05a97f13df059b409c90b9869427ff6dbde835e8f159f83e9c8f9a01be5dadf06826d11ef0f6c387b510194583149ab55a41bd16e14ba5ec5121d86062bf23402ede3d773fd47944f482396cdcc0dcc2789031acb518ab69810750d4bb18035da74a026fa3a4020224e5a4a96a0d2ddc55574bd76457dc41e93f6ada1a836ef851bc5d7e3024e1031525007a22d420cf512f8eed9fcd24a509ddfff9012649ce37fef28d7957e9910b034720c82b9d1f23627f1d6e852940f0e44f9edded57a47da51aa77c77a6295bff74a3ac9f886205e71e179a628289622b5692f4a3db0707ac855f5e7b3ca72e020c4fac776e7a3fecd869f0e0528d84907a22615c2e3f31cb6933682b7b4f1356021d5e8b596d434bf0f67c35560b55b1663ebc912ca1723fc1329f5b3009f0706c031ee4fc23013c4a39225c312ad51ed7fc8a21c556558b05fa190dd5baf0b335a30315cb33ffca17caf21b2b88bd275af320c135eefd521a0ef712f9dac98a5db0c7022fdfa1cb61f6fd3411010e904c1b2291dfeee4a8c0a0013a98b9bc218e17392533c4dfe6cb1d5b2e41e1f6d3a74826fe766c982432bc1b0685eb594bffc39e16b9edccf6850ecafce3921509858f372fbdfaad8d5641a272f975922d2397e54c1d24982ef0141e9c32a15ee67b10f04cddd0e6690fc00d19c43f01b08aae30140d8621d5bc22d718434deeb26b808deeec46fb5e4692b4d07cf9e25f1b4fa7ac954fb1850dd1a454ce18e9c77b5cbd9e6d8d5ead045094c40e58b2cd72c88d44c135d5cd306674f1019b20f1187ceeb9e30b60fb7b448752520e4e8b013c64246dcdd39985626e416ba1be26bff98b2fe309a129b9b96b85014b9ba390a06fb638fe20713fb915dd7b337be54d008be37f41c8eee297e50f4b341f9a5c4463faa7d6a085117d5304281b7fcdfd244da7cbd4a39da3908d76734f9afabd67314cf412e2523676c55dbdd525abf50d96e2385fd9c75954115fd0bc34263d86e5b4b6e62c889fca60aeaa10c976a746c1ec259ae70d5a88cc31ce0428d68b12cd2afc7cdae9ebf7d1072f1edb1bc436803c84801fe85af8a60f0dfffd76b679736a4e56a5b70c9c71256b114e7008a8e1fc75e54ab65d7eb4fe39d78500b0eccc782dfb28f068a7d2955d526a73ac2f0c4a50e67ddab46565cf86b7bfb90b43303e566662e66dfdb9201db1b52ef286147fafda627e77ca9101721e8e6fe545077b75bf5a0a0b211e6fe3f45c8cd055fe338878a758cb174046e0ecfe060dd41754280bb4575eb60abdcfdf6fcf2042b64cd5f66acabd6b32bce6f9cd00a369351f52ba90182b7e5199a0c89a480fbac4d60b6647ceecb41719b4e15e9335f5f7bdd44f12adff01b2dd27d0940094461fd35de79f6786a1aef52f3bde41b702583720851d7c9f47063491058a889f7893ffc6b360209c50277aa077e7992ab710524b07173dbbd23aa5078cfb07a6b71c60038c56d51a259805657f79230e2cd9b5057a0ea90b16f6b4d3b4f68c4a38872d6bdac37f9fe5cabbfd5304b5cd4af6da41514a25c0f61781e353c01dee8ea5ac651f3db2434661db32007de050a347bff8fff0c50758ef3f1f4b2d2ebc58934395b6b71801a1023204f925451f1c7be62a2d42ec1edd1ea3130fd3142078418f7ca1a9f73daa8ebf4218cc695996198a64e0b232efa5c46fd9ecb1bdf9f00901ecf10fb9344ada723516881dbcc603d474e821fe39c243ec2483edc40b77fbf11341c242615f2a7609a9111c2a2465832510111ee7b97ee322589ee33ca3ef484c1648a69965cb57e9c2b2d221f12d5bec8e7e4ba5a01011ecc05ff0316b7cbdbda238704ddeab0e824965eb49b51debda115653b0757b9cdd0a3455a4f6d119a1108b366a7957953cb18383ee1ffb6e5739eb5293c5db80b73eb07eaa73eacf07d4fd5b9e9cc89f76bec9ed4927f6668c26496ad44071bae319a929a11da1b07d79bcc14d13ced6efca59a3844375d6639bddadfc7190c5cfb5075ad36b0994d87c3c2685b32e83237477358534e1b6a23b92dd41023f69d366c7a7cd1fabcd2ecc7f6bfdc3f21bb4f606e47930867c38f35be91514cc42129ffef9c911451b482dde5ed8461efda2a80adbead82b5e85d818acbbc9b632592e6f4956ad5b80a39686ff6ab34127bccd27d0f2e8c1d0493fd86e1127f94d0855fd4065f84f563b034601fc6ee747fd050005b6c06e69ffd2260bd436cff503d2003ba1c62f112bdf2ebd7a05000000000000000000000000881077e9684a2892d4ca6a400719dd0d36cb394c785cbbdb4628408b380bc66e5a9341f9cdb78435ab018fd70da7d7d79b06051c3da904a353afe056b1d5a17c9987893ac5b0fd1ae5ca3f716b71828b5bf10c475bc499b457338ed561c403d400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef958db4198c70e8febaac12900304533d6df7908e736d7aecd2c60fb128e9cd118030bbd32c3134d4cd7e1409397e3b4985184b22b4f54a4974a7d7014ccdb7efce371ffc3cf5a39016d42ace562f99d8f1d625f02b9f90c021b047e059d4880525689054ee39af2df3c914af0046375383cd1d0d9708c4b7019fd4ee2d6318021d2b1a2764d85c065a622c27233c6335c14df6efa0d6b3a99e44fede9d64d737032c5f67df7b51c64aaccb2bff2b36d6db72de9675aec9ed4c8ae8a83c4740644a0a00bdd073a99ddc0e9c689577b869e3a877149a6cbdbb038caa6059a85945b39b22962de623ae9635b6b6ea5aa9572baa93558cd1c969ede58bb5e06dfd660c42032f88f24b97baeb4e93381e36ae1f7753adea4140a156c9942f01189ca1965980022ce85589baf514d23ef731ac1c2583279d52de1e4ca89607265b7b3b3a1394df022f482c5cc93d3e637bb00c65ce7fa61b4a0fee8fd5a408f44b0cf08acedbb4c1021d1066728b528fb8d96dd1fa3f4c19777bb98d4b76e90ff74efb5bf6f2f7991d0326df64c6aceaebf965f55c45395cd46c9aa686dc49235757585d551f13df62ca1b9c7204daab9b1208a477a677bb2792c919120a9a7cfa9d47c64d9fee17c6a7bdce24ae5826b2398940f9430280c50bca8bbe4fde0ed23b0be549142806ca75cdb9cbc73bbf130d4a9e8892b0906d055f2ac8985e28e8bab1c6f18ea43d99460dc1f3b2f175782b147ac2054a798ecfff39bfbc3c719a4a1d6e7f09199586b77ed640c45cabfa3381d5126bead4e20e343f3662415dad395e5cf5d91a0716c33c1d08b32592aadb8a8b9c55a3d5cd758548a768fdf2baf92ac47dcb9037418b88a580517ca6a0432b4eb8c8ac15d8d63371928a3e934484484fc22de641cfdc7badf296215e1ede57cc248d498b839647620dacd727d2c380792ae25608a4d57dfad209917714968972c2032e3e5eb323aab25bb43adfd1da99b43188a6297e3f848389a6fcd558d6a462a185b7493793759900374a4a6c1f7a4f0b48136749fc698cb80a773a29b01c5d01c3591b56686ce99534cf6e7241fe75cd6932d8dfed1526f798d313517a1696677fbf4f35cd52f312ce8363acc0072e412d38799149d63e6721c2c17d34e3c461af9b8e56ebee1590d4841cdf379593b3a7bc8312023a7c58fcbfc30351cf8b15b22b83bd1e8e75dc3edfc330075554b9993d1e739bde3784fed4fb176a79c15a7c3348ef7d8d2c44e6e2cf07aa87346e8cefb68118c2c523a5c4867db2a5b36fd23943373a2bc4a9d0e252349aefd280f47b2e7f2b542e80c128bcbe144f9b8253b08e459eeff1fbb4624a4d9ec599d3d4fe85f781d9ea9ed2c865851983cca830049183814cf8926c03d85e3097b6b03b7ae0d35acaa5dc4353cf6d6f8bf82898e644625ecdc39c25d97d48c867846f68287eaacd70ee852e4396258cbe1982dad6493d3c03cbf04b1b93fbc972a5ac28965ddcf13b1a96f5fcaab8deb2aabdba3c348dc007047cc9f911f0608134507b694c89dd349a1eb0e56be7a0cb401d30e77912726a40ef2bc77526d4d1ddc81400bb9a53fc58d99c39245cb29aff880399e1e9a8790f546ba7540f34dbd7bc5a5a5f10e63229e8976bb8da04f3d2aac092e591749eb5adf1702018bd81b444aa168d4977d3fcd7ddf44f3db8e1e2e0d6800f226004ce3700a21dda3c5ff5aa7ecb827ddbeef5c60b787f60cf57b5918b2c8ebe8056a930c613007548115e0cc62d3e9b2eb43e7a1678e01128df19c15553f314f6f27c3fc11b2d43d37d2b83911156d9fd2fbeb083e312a82554ce18bf0454411ce52076a3c153ac6649aaea32d8ccb8e5f1adc68b2865b24490ef49cbb1b30482c58a91165e3b6dd087e4169c5f7694e3a3e55722d40f26d20a7bb0954271e74c9aceeab6ac2dcc4b22d1e9b3531c7ad05ca4a34088a0ede98706a4b84d292553a2467439737e27bb6cf01b96554f7e2df3f811ad6e1ee2dce32bb9cce8d2590861132b6844fc0ecbcb2f63a35cf1d2ad47e1aabd39ad10ebb7ca80f295535ab67c141810da136607c03e12a22bc72cbee8f5417eb3c7b87b1e1617aca6224566109f53c4a4909644efadb56046008d18f38dcbb755f2cb4746df8f5394cd003768c17618bd66342c649b87756a2df03fc1d19be9998cb330996174577201ea8056024fb05f769d7ac8fdb0aa50b7116d5b17b76b634c73159c598dedbc9c578134e6dc85f0b9bb005ef431f1542fc63e134cc0fa0eb81aed8c1328aa230155249552756b884d3aefeff33668df1a80fb61262cb4bd07b8bfa47eeff71ae3f1d0e8aac33676b2833b712f181943fd1f13ab6c661c49610a8006d6139487347d6d6b324743cea04052dc7bde13fb9b9b768679d42f759ad22aee145f91b6f9c93809", "525163526352630051", 2, -1667522293, 1537743641, "25b07dd9a20092e2a3d21e93a15b62c7fd687caec76c7d3c106a645fd26605ca"], + ["340b39670163adc5ad0fceafe7877f3d160ee968b336903b57573dabdf7925cbfc24730552000000000363536affffffff0433066f01000000000451ac51ac0e019a03000000000763636353ac6a6a147ae400000000000352ac651dc14d05000000000000000000020000000000000000864ed20100000000457bed3d12af09deb7d2d9e75d4d91587e2c4c6970c84112fabbcd0a44ea1f50307065485b9889905f61d029600b51cd1866e425e6deeb26834661378243d64998bef23197d4746a61e63e5195aa7b8f4adfcc68537c100b6816e6a78f65c5bc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000db09509ef9fdcb9968bdf098485aa9e70f8ce65f416c28eee52a10e0ef9ca294bd527e9242a2c486261e0a7af9ac5492e5f415abb74f5483da3dabe1556845662e31dffe7b2f1a5316038fe1da40c5b1c09b1f2ca81b4bbed91e3475858667c0201076f4174345a262b3264d7752ade62134c1faa81c5358b9570f45beaff6b30201b9cefc23a54dabe0e923f46912ba4c8c79a6a13bfd87e80f524440114a935e022ce8e87242223050a6d61f74c898fd6ef281144ea1e73a512f63d7eef2c5a3750a062e6aee15dac39646375ab76e80fcec48a3abb596e0eb4b88835ad70089ba3ae8f16a57c3614c0cbc41a56946affc0d1a8499e4f2b122558c546ca8c970200e02220172afe8848847a2c4eb09828725d372618e938639c545d8ac9576f2c2b46b0219defb82fd396837ab248d8c52b0709cd71615f6373ca39889282093ca2e1b8a02266271ae1b93587630bf0976131e5fdfcf2b469e61c2f8d1364465294caa86bb032653ca97d4a4f23411bbb36095de7a843d680c9cfecbfd47405c1d0552c2167b030179ff73f301bff35c9692f2b2ff88c99d8a593ace68768f8a673e3c37ae71adbdeebc6340cc778b61bd8a3ae8ae1f1ca9839395fb674425001a70d979393d74bf306d30f418e49c4be819eb81e059cfc7006b89604467e967b60c5c16fdc0717bd4b1c6f66726071e8fc3f868e7eb956b15c6a321b8868f0e5d72853bc03b5138f0e33fdb8b7ecb944ada11fe2585847bf3ed0866cb6b840ecb284a4ab627b2b414cb27ba02099f1057e56785584f4955979d2bd65a9af977b08c3c1f9bca6acc1571761aca6127525e8e65320e5770a036e0bac1c68e967795dc0eeb85ffc8bfeddcf1208a749d47ad7c0571cca225776d4ac06f42ab463471297baec9d1f3219b13eb47c5e2a3d6eafc1ad97e661c54e3211d81988cafc379d7245240958012c2b7110acbd65d99957c43bd7a579df46321347121495a36afcf353f68d34c88f9f52f71efb670dfed56d257c6d7d304fee9d9dc8373a4d430b3fc0463f1be12cd47e35c19d7eebd9bbc718f54db10647c38193693fa4f611d71ba88c588f45fab2bf6556d025ce56d5114c67c0d0f00f98b15ea9c5dfe016d738ec382bb5aaaf268bed9c2b422e8e01a1ceb17d164dcece4ef39386a50ae5f2b0a43ae0c9774c8d3e3c3a3cc206ca8237f441b1598627cd8f3e7afee9f8c4e253a88e66348cf51878366093b1bbe225df4a8d3b65b286f5cb8b7125a9d46d70339e76a36fae6c5ff7df647d90aa868ba95e53db539d573cb64b5e9f22cc30d363c883654bddb320616e13270ef4d22aa76db1fb84888403861615ae57a2a06e3769f7560f75db8440e66a2a49ff7a253ad05dae9c753a4dbeec687e0341d24927dd4653758f6349bc2d7b973dff3736885aabf252538443eb06dde75b43aa2b3903661f634dd21a8e619935aef1e81afbe83a07e9267fbe91ad3d6c548e05b44b934464ec92d77ddc25bd6a379c14e498dadcdea6a2f9848175590e16659eb15e3682e65111ef9f571365f193ee97e5e319bdd9f3f07e13f06c2c1f2b474852256b53bec1750db4be441f6c4633966c225fb301e580e520b530aab3c697ceea1c9733c54670fe63d11d62bd8d19e42808b71279916eb3bbb8b9f04ae91949056c3b9d5dcd529ec69634bab1531640966b3f8d4d5ec1178d78459981268c3683da9e40cde0cf3e8cf5ae718f889128f4ffd9728be79dfb75341ec35f5648fb0896361aadd8c66433648eb89c1e0bbffdf33232665daa9c9d905634e6bfaea96fc9d1c9909dcdc0f791b9e808be3ffd0c528ddcd7fea5d18f9412906a6079c7beb1c40210356c0d0a3b8cb7230d1741fd4197cba8cb62e0707f21895b1431cfe055403dbd782d0c3146ac2fdffd7f5cd454fe6a04551177f7ce223d7d99c76c96ccad3e656e30873e4922765182a35a7c985348eb034206d3dbce776f2f0ad6c69852cef598317ed7e3610243af394365d0f14518354bff952de890eb8c59720bffa1f4099765feb2fcc614a5830f66218c68e7d4a677524692579e4e18c74fb1c4f242c6204bd94468f94bf3899b44763490f256731db5ffdc27860adf6b2ed41a4edcfcaea189e00ec9fb497d19c087da92eef807fc02ebf52972a13886c654713f06d45f270afd1c42f177dc32f115d83637ca43819f06c1292cbd8675ee026003c6f0848967fb567a8478c2d57f19d9e8cce0cf93c6fe4d89e1fd56f4c851f7b0a46a5704b51c5dc0e82eaac99d40e27344b9e03777257d503030000000000000000000000006b409b13f52131744d64be1156140c90e7288bc69684eb04e6b7a1d9d511f897c36db957f6d1b0ef0c6443bee62a6eda571212adb73ebc728b539b4e29f7b6ac9e93865de5cd76b65617c6470c254f8d31b3565d0e695350fc9a71e94393131a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093d1d19b42d70f4e609c86ee9072ca617b033fce2db2aeac1d5ad8f5dade161fd8dd134eb4cf6954b1e1c744cbfff522b0e31a15028c16421bc521bf1d7340d325b37905f98038de79a75854cf9c6a46c1ca19c654163f984537b2a1c5f669bf951d5481c0dde3a3c1c11b79670e13f216c6fc2a4717dc5d6abe98a7a4d11a75020ac326e73c094ee31331faad31827cb2cfdc8e8fae65ea634781bd3c1ae9e5d302068d96fd48e2f767b418d0072ed047cafef7ef3bf839e028ae3a0d969be093e20b01c09c312896cbabf77c72de4bd3d689288b6c0ecfa3d74e18ff637db6c064e23d77174ba83f5d916c7e816753eb665eb61b18735205fec939ea08dfc8ba85e4020b51e588c173d3326524b758cfed60d2f0a7f0269f0a331c12422d42285999be02148501ba89e0d27bb7be0e06de578b52284e8558fe9571ec88136036ce9a27b90222f38bf2441b671934c68ef36b950387feb4677c4f1795c850a1723787fb3beb021abe5f4b5672d7161bf21605a1ed9aa5ec0189f61e8d5e881a8a6e4c7af6768b020a1f07e3e2c02b5ae3edfc0f72c7eeae1373d416e339e50aa44ff93ff9b368f80e62eab8077f2f6e883f93e8a632c96b89559bdd6942222729d51a23bd81abab3dbb232a41275f823e20f543e201352af7f239541d29d4d28dc0317a149c28560b49d4c68a87eaf7e052b46aaf9dacfe7fab6f92e1ab5e995f6d100836122e222977b02aea7173a55046e84e695cd83bffaf7ec19e87971275f7c8fede8adf4aec48d5d79f2b0f0634954d4a17faa4bda5e6c3805fef337fe351be11c12ad4abb5555be88ce830cf7e4c4e23dda583f1e229893f409f094b7377407d07aa34bbf664e12fb00b4ca026bc400b98d01853d3c09daffa95a72a63fd08cf55049be31acfc8b7cce4822c9640e1a85533ad5774cb6e90708c8d5a89b277f7cb3c26454a9f1e5220d5e948a4f58fc4f6affc6e17d29fdfde231eb67c269ababd2afba642b2239c4367759cef5f9d9ed494d22abd2005b4a7d338efdfe66bc7e4ecd17c5d79f02808014342da8dc9c81c81a9fc6b696166e312a8815f3ca37aba07b074047a4d1627bce7198e7470adbe50d0f8258f9a1ccf254f16451755cbfaec6bd442db25bc6c1674bfaf66f29c481b1ea379f0d9f1f2de5be16685bc58d51fb8ff70d102be6f72786cc9f1e0c1d2e08bc18fdea737709d8fc5a3b2686a04ffadc09a2fd5aad50f4a343a1778b7f94894443e22992c8b545d6ab6c587b182c614fc0ff57fc6f26ff042457fbdfeab7019e88848a61ba216bc22240f206423043f96141ab173dbe0d490165edcad1eee29d120c46a94319f737b1f6fb100f09a8c0e9cd17383f22653fd3e75b932ec97c07bee92c0172f6ef313911a4e2deda7a76af885824fe33f0493638fe8170b72c238f1156cad6407ca98607511762ecaf2cc10bc90a3926abba5f8142203b6e1368df4c1c90a1cb2ff554a2021a5d1f988ad4f9d1bec6113959c28fc0bc7ed3d1bf5d1ff640215f6489ef888453965a75a672708c1dba7a23601a91fcce4000b5f15a55ad582ba863942fa163935e9013a8ccd43531eff0d95509c316ab9485c389be7cb5c64db1b32d5f502b8b28dc44e7bada5f2c18436a8e6a0929f0324ebcbb7864847a62c3ef339c9b735d24fc8a5fe3aa5992dda96a2c689e4d0c1531113147b2c5c322c45d562706339fb615338d83ce6a3b6dd714bf363149567b1402786c419099ee66b8a184355eedd2eaf7081ad02fdc1f3b7dc9a0d88ef0e70eed43489b6662a8c78946d5db5bec488b0c3ad6d2523671fb1e95a42fa170bcf303cb5e125cc74a3692f233cf5d5f9f64c2743426952a70febeb4a7ecdf1cf43d2dddf9ce9f4833751fae09cccc5ecd20220d80599f25cad00958b4ec80d0de630de72f8c3470feb22f4c96953b19829b6fbd7fb1da4bec2dad739b11994d98dc86110e225dacd239013630ab72e360c3a59b9f87345c6b7c031e3fe7c6635f2ca7029edd7dd8baa878fe3a4dfe707e2dd8c809a014156b7736b37a92eccdc7a4563e02537d166c4c8b074f6c4927688f030ba42c06999d408ec4fd28c3e2842075514594be95b1ed504602cce2b79ce1074baf04a5673dd2d62d0d9c8850fee1c41f90c1766057b4a3e420205b9ca09bde45e78f5b90e3920f7c577287ef6d35dda10715af4ad4e3e6557c47fbc16ef5e07e8dba65ba297b1255686b401d18f9cd5998ba0a53b8806e09699ff4a41fa9ac08522f9b9696b91a21b90fd7bb629b7281a5a94905ae6fbf742a94e5562b675cfe78ab7fbec27c3af0ed073959b3b018ab22947cf27633a5490134ee5aad31f3a62eeb22fa88cb5695a88da7def00ab1e0953526c34a0ea1278f3e8d0090785e807269765f624365ba8ebec1203caf2d4a0790e", "63", 0, -493055947, 0, "acb6bba3534db83bf76b3ea2d81866cb82ec21915bbea42e233ea7a517f46125"], + ["030000807082c40303e85610bc2a9bf1c88bee81ca36e6128aca67206f025c13d191415e2c31d885de0200000005ac53515352ffffffff34da49ca63110934372180e70ed9906820edee5ababba12cd26bffb1185868190000000002ac63ffffffff050d77807608fc0a30b10aab5140aaaad67adcc5a20857c7cfa01d75d4adda3102000000035265acffffffff01a3db3601000000000008979e0e0a88cd8100", "ac5265", 1, -921674116, 1537743641, "08798e464b33379f2c3d2719984f538eea0164744e35a88528e6c77c412af8a7"], + ["030000807082c40303c4a001b5d77a06d75b25097d6b5ba5c60dd5628924438b553fa99725063134890300000001520d5a0127a79e25e1a8691f593dd242891076926c355e1d814660aeb3f5b1fa97f914f5a0000000000652636a516a51456fab3a4bd7c71d647d2e5c07bcfaee094159dc9e4a375dff653819ec4e258c7e4f20c001000000096565656552636553acd35d76b50430eba6020000000005acac6563ac5da212000000000003630052a911d804000000000351516539833d05000000000951526aac536a51515300000000bb815d83020000000000000000997ed8000000000078f5555e65b358105994c2fa568e8b9e8ec6c27e8e140d27803b8d02277bf00c41f35dd95317b666c66bb9ed11b3da3c1d91c9d18df4d25672bd63bc114bea9e34046f4501131b90eae6d8414572722dc4e0f134e1b6b63bd66f353be746234f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000079ddf9ad9c628e19afc5ea49c613ce38ff816697579c3e29e5d3eb8e471599dc473e9f82d84e48e77902a24a63e2be24ede89354c8db4b02c169fd2acafa11cd79eeb9c63da91e485993dd2874fe024b23f98dc3aa7a0814852fb57c4a419dd720189b32fbe1a3713a0b07ec873e2ea5373c4bfbad177b656f2ac07e39b758c0302c66c41f72ebfe1309e25b844ca0e35f666735ebd5e19015a2fb44f930f54600215da3ab2c0553260cd087ddbcd00fec1fc9e8476052c9ecf88e65f25d65a47bd0a044dd2fa04f87d5ecdc0bb2e842a1d26f83107fea199f761d210a636e17d1b50992518d2250e35d4c5549346d5b319dab83196c72e130ede8d4efafdf97d9f2e03228c3ea8ea521134e484157aa667f6e0a808559db77b7a3c617f270facd357210224a2a47e3c9d29af8e083c7e542e3a604407faf28fcfbfe6a09def8e4b7cf0c3021c179e6f92eab28de32caa091334e2ff924903c937025dd83a70e72b9ff49909022242d2d46c6f1e246e705fcf625f03e9899071eb8aecd6396c635270903303740300909cdb1465abfca959b3f0356343ecb7a210502c9dfafb433d86c77644957e6276a27a640ec9ad5653efc50f6e02cfc8680631210cdd6d85875003c6ea76740d320172011f8075f8091c9233323cac4440281a6f13da8c6ce63981ed52044088158a9a2ef6534547679366dd0b4591845fd2a6e884ba9c801f35ec1dc2a59c2bccfecf5996d66556d7fa30868f94d93e2d10bc6a6235363f5a5722b28d2f2f7574312eec3d24c51ce44f234dce5a51787c2fb5358bd57e63d236448ed27b796617a556c9fc14376c88935b2f113dd1969fa25cbd5704f28b75b12657f2b714998c1f068c067bdd483ab46321bba0a14cc6d89a241e234b7e78e8b418b022b38f489531008f18ad8ce3de07516c5c96bfc2fe9c132e94efc65f0e5e3a83088326975dd250a68ebc5db9f4ce6be6af3957379976efa9edf4ce98968ce35360be766a03d30ccac6511b9d76d2ed4fb7d1749facba087e1e795597f9ad5f783dde0b037eb988f7f91cf4572968a3a010ce1890296603db9293e56cae1a2ad98fbd6b5e72bde2b2fbd922d6570aa075c07922983d2e303802706a36752dbacce6766426b99777526b862f083a50eef485ca05de59c2d857694535cef648b2d2e1abbde180f5259b00f74067c1f8486be3507fd79335c7a9da9fd816a48236c28781596815052aa005048c51222eeadba0af9a4fdbb8f50380dfca6eb9174ace8453b363b3603b57fb70f4c96dd47a6e7ff68ed327b22de7fc99d17bda033252de31d5bdbb25e5533de5b7b67c51bcc78bb33a6174e9ea30985fc841d8d9639bb8f22f109fa4e357433f8f6cf9469345a187e29a232a41d3264145742fad96ec4da5a7fb012997a72a667a449723d48793926b598bcb94e158adc6ebf2b19c80dd77ad1af64e43faca2ca2d074c888fc07af4c2d47deea0b27b0d76c5b5223329a42010cd51f5a7c362ca23b28a478a48427abc7885971b1e1e7ad0e31705d065f726aef123c1a14607924206b9d2c53c03bccafe454fe1610f017508fa361e0ba190d7d82de9de7a6fc581033dfe7f20d908e74fd1e615b23da955211bddac2a2df8c90817641fde0cee9828579a98b3825da500e265fe3f88afb4e893c058971e2b46eb0963abff725a52437aa1c411aecc9e653fcd597688b13e682fbc88cc5827d41f331aaca9a7e2d8519026c3e46941984ccddd051634b81c8c1e1a3a40a18705df97ef535e49fcb385357c74a829bb2d3c3126efee41313bdf360189b9a9a55045e98b7cdc6f16ae7816909ec657d63b8d4b233b53eee66320db6417bfd7ac690fbdc8ed4bfcec3176e334467ab516c07cbe63c3eadf4be35289bcedd87289a367493fee0235898e7165151974bb93ba1daeae965753f76b174e81f34a5e89b471c4c853eb1ced51f8550b97221edd17959df15c6b9a7eedaede532d4ca1de2a310e913a74d7f8438f729bc8a6f05cc71f05b433b9b2034c61462f83971e707c5ae5e87c46db38ecadb8318527b41d44aa6b383125ecc31f1c9ec8ba6a2ae4bdd77e952d04b7f5ab577d6717cf1eaa9df56ae286a6a121e313cf66530d5e9c25dcae6065b155f6670da4679f753626378b30450037fc827ba2ccbe50d5c08d333077a0a3b02f76a0346a2439b64a0b219ca24ee20c8c2817485828661a4f1c047372e634bb887d90c38946e1bf25d208c0d5d5c0bd2c6860751c31eb04d62dc86fb86bb6b364a14ad911291ceca1b1221ef9b9d010000000000000000000000005172501f2e8fcb5b442dd70be8350055d75e68dd81f20a6ecbc6e09ed6fea939c6c6c265f2f9c9f4d354f7184c6fef5cdce3b1e6a992d09dc5cc812f75c459ff2785a986013a7edbd793c920d6b813e5303677b4d8c4bdd70c09fe53c04d6cd10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059cc242744641266936cabaaff7144796c390e053d94a6218cb94068482c5f67e44427b011a2d71717298dbb0c06cf224af505b87a129f2d056260315a20e71e6dec94bc27f02ab5553cf0410edd527d8ebf7cadeac243fb4a3082eca332a81858a643726472d04178e4f08347a5b4c74c56e2b377bf390f62b1690cb35566d6021bedb274a50f50c5f5fd259121fac2d5311eb47ae28692d31de233f76535c98b031bd31db02a216a9eb40548f82926db1340181259bd2a23866aed632d3439de850b08e1fb81eefbf267dd7cbaa2da90cba6c3855a204b429c08305b374ab9cda36b64be3ddd63fd2650f30cb97dd93856cbe66bf7feb0e80062d359d1453a8a7e83020b06d12a233d0d19750a86d8e7a5a1715f0d0bab9089edd8e3ca6c2f91f6e71403144f1c457d2ddf7ea2a8961bcc5418084611eaa4e4942eb4cbdde902c573ec6c031c92663709fa1d95cabd36563b87a835cfb2040c87321e87347bc39ed9d3acf9031ad0e44e2d30f8c0731c5c6b31b191a6e9bb2375018b82f1686b997f67809dde0201a67d1371e718391c68dcf2bb525add64dee0ebe653cfc7695718ca18b25f47430ea43816f4633030c3385e6de37e6753eee05a2f5280f82e754725792ea37ea9644264309ca77ec2748a47438d673159157225c3edd11eb8709be5f6cc2e9354bece5825037068781e7c0acf076f672ffa61eba650bfbf10d7b63c55d4c22d40256933d902b5df9fd733390f2c94e8e837b098a481712dd2e7c7bb100275fbcd2cb76279746c10eb849ccd6ba2744f1600e7384c2a1fac919027fb8befb222fb4ed0a34201a8b3f917cd45e3261a3913730c36771f28edb5f42220f72292648d804ec6883462ee1ff7cd1300fc456500d6e385f742220d80ba34d558702613381e4d070e7e9114c3dc5d946e5f3b862ca193b8ac672ec28e9fb13594538efecf131e2503a7ec19361cb60508ea93ff9c704589b7837f52abb2a52ee520b17e244226a39eb96f44dd194fb40785ead59fac01aa736b6a97b1374298ff7b0b0be9299e7275277525607647e0de4ae7f33e8e15e6e468e8f3aa1d413b110fde05dd40cb00aec8d72a72c15b7ad15584e4f263934eba816f127a9fec2016d2789d0e838295c510ee6be1fbe7c150d972c963812af9b5cf9cf9534f3b6fd802c9c8361537afd47b6aac6c4878b307b6806fb18fbacdc1df4e0ea75d4f6ee7484779e7ebaa89e09810af2c67142beecc5dfbc8dd3900f1388fcd19425ea6cfe4462edca63ecaa509937fa744a17b04033e1956a2602ac1db64f77dae96301b53659067cb1cc2eac7edf60d01ce49faa211ce3a9974ead2693701f6a85685afee73789c258fbf957ff622d6d12a15e34ea87fea3d6a87e5ed849ce8d67eabafcd8eee882da82b9bcc59b74c81290ca73777ef895115bdb27be33b576ac6c89e28fd1a3e233c02eb356a03a85985ad0615a974c27629fb07cffc03ce6af1f6f0fc60d9b87d6bb86c431b953c62d672fbdf67ac422bc333f27c5b1041540f7de31ba2817f864e8d85e34e1763cd68fdb38913da40f421c28189d165ba5c35c231221e49c78d08ac0400133b40e4855350a2cb0b35cfce3eb8e2f4892feb8b0c75ee349233a788d6360f888046b314937e8c76e2aff5ecd59082bb7d303eb46d592a60e8c3ef925c7c66e0b73bb2722b09c272107ebaf2f674428012bf6ab5ad8da64e333486264b55c9510b4c242f2e99a681313bd7a156d0a8dd5a8e69cefd0f314a5143095f5a3d30001433782b2672ef08cf4bd92ea5b0a9558aba7d9517164e3027f8cda3767785d1e1e1e79137471bb6745e0cdbe639513725f2d1435f18c3bf41e795392c4983951ce2a2a91911f9139050a80c46aace42ff0493c18dd8852b246e158ed363bbbf7f09a39a4743fbcbe508eb07aa08f35c12f4a6f77a0955a37431d95d1f4c82d19de2b908be6fc71874a7b7a68eb13253e9a3958bd6135179701e0574d84b5288fff1ae0fe80e1949347c6216ee7237bfea550bdda175decfda5d661a8e7a3bd9d58163eb58d607fcfba15654cb39d7cf977c4ce4c11da800d1cef7d134f370d356b30d8ea6224d6782a09c7d59da38f9299a9a47766a32cb349cf1225a210f6171e795c460a0a184ce0c4d95015c075eecf8434a2505da03e876e36ffe7e3faff14f6d2066913a6c3f6bc0453b02fbbbd07390c730813c354f31fa4c83031cbf881c93a2763457c3e05133ec6758844d60e65e80486f13f4af479b6076d11e75b82ad47a1652b3dba710d9e2f09fb50ada321e2a1b6ab1ff8e635b3eea18f32609f50dc423ae57d6e0662aebeb9a1f5d632547dada662cf98f325cf3915895d17daf7e14162be0fc9e6d3264cf7808ce2939145a4cc88a5034169f210ed0f20e5f98c613f821d5a6f25d03", "", 1, 32145557, 0, "8f279afa6d629e2da48de1fe57e2e51abe4289b0aded28a8bd7f73b03be32a6a"], + ["286b1753010a626bad2586ae6911d48968c99e7f8731ae31c9d5dc3106710bb457e3bfc1b80200000008ac6500ac6a535265535dabc60424466e050000000003ac65539f7ee70300000000005a11520200000000055265656a51efbeb8050000000000fda76a610100000000000000008f07b7000000000066fad4b4ec97ae57721243e8d9dfc801252f2d8bfdeb9a30be7476a3db519a3c7861c3d90722b278dcbfa2a8cfcbe08e2066ed4c040c678d726165dbc4895adb090f6aae5b79bd5f2290661a3c79779a638023ccbf9b63716036a7f0ac7a3927000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bbfa03bc4e49bddc6125310ab090065eaa501775acfcbdbe189689762d14ba6f0e21b3c95e27e37b59e52076b0860d462d748ab2db1dc057e83af4ab92edeed1db1857b7443927d573b1d063145389604fd63661a1d6acfa637bdeb8759ebb66a1a23f8c354f088f5c47f9723ed2c9afa50841dd298f8a81a8b200998ced61902201a311fa1e991979f7c59ac15cccb054e75232c40f2c24fb7261521c2a6f8d7030dc72c13e9abda77bb828f132fca3fe194687c15e047346e0b2167f656f531e40a023cabfbbbdbb7db9c9c5200ebc47b812a3c878b590a936aae643dafc7f8b1d41b8cb62385e3167d98cd86a02d1d59e802fcc63892cf37cf7f073a6cf493446103220b0b2958d9608e8686a974a060fb01f3fed73d45efe87c30d2e4cbeb06c913031094f40989ace48503f23b2b15dabe0dc5bf25c25eea5081673308c1089b5b5a032f9e8912226bf185dfe93cb149e3c708102c144f9af085332bbae610e52d0c53030f31418d33404eb255744fd8c3426b297e4da2fdd0f23ae09a361bbc0bcec98c022cf1d3c4970ca9798f29535d21df843e37c836298027cee41e5b32808d04c36825330c81976b14e860fe801fbff11a785ae7f8d0bc312bedfed3f4177e3604a48262ee9ab550929e53881d12353468b31b67480618a2df0ecaa0add197a1f6c720825f5a336440ba4157fbd9eef9f3aafe0bb9d9326fdd7070c8437629ef626e3cc96dcce664f67bbf6b391f0a1c912e7175c0c4247ef159330df7b0e583614d373e7075e23c211b496a8c4f145148b06affca7cacca320d032633d5c69abcef40f1774085a6b033b1d055f8bcdafc0fc76d50bffa8a590f449578fb99a6d40339fa5bcf6aadb93868d8e9ae03f5b909a0a59c09795c4f46724d8fc96571fe7a0fa24b9d89272f396366a8a719f1d8b5c8a7b8f47c5e7739c543265f7ad99d91eda0bba3f4416c0a35e702e6603e653d671550e1443ca072e1210b0ecb52619761b0af6215294d6f76d2c8d6cd8a26480e02339edde2351e86818fb8989b5f7e73034e1080fd4605393ed9f6edc6309dfee589fa769412be2b03af6ad9451f40ebd920836e75ff60e360888557b61448ac538dbd477dd3f1dfda1b95a84673d93b6b4147533c94c3ae3a8a934d80428b54adef5d1e09f99ec54191584727cd50e2a1a2c66df0c652e0904f569db8d26c8a7db1f3bfe3f7d572e29b8fe24d97c2f82da3fb5677264c38e96d417568805c599c909bb85f580198b35391dbe7e11de116db143a1c1333b98f8c0ddd1a220006c3c55866bc6257255430fdcb96be2b8c62fee215cd265d21eef118f436cb1eb71c1e39939064f26b934cc019d6bfe2e1eb75907c01424642b911bf066dae38c8d6b58f50a0b99b61c4f1b1c6592f74115217b2f8d708095353b749b6f4a0425fcb12ec8831ceda7dba6318dd5d3f62097de27b35787e6656f91f62ccc5334f9124ba3eea86a95468cc12bae351fa3cd152e46c83d27c2f422e39c38eabed8b001e10db22b93904350be65bd8c551210dd356bd75d066d55929d3651697da2309e32fa379d829b070dd17fc173b22d63ddf6ecb7d24ff532f9a90b2eaa8becb26c59316f3912ad00db16ed822b78916f731cb07af8ac35463b198199bba555c6223b03d80358a57e462bcada4a128c169736e041ae0ccc41e02d2d5ebd3eb5c37d08757e88c17ee84f9183fed050e369b5101b79a26ed01113b817d49ae26dc4540f9379675740a2940696e3de1020988d2032e82eb8f94bdfee0c5446094a32503596533e2d613b3651a628eddf87877a73010b98003333623ea167fda4970ed2e29225e1693cade411194a8379eb48177524509fe4eee33aeea5d2ccce88c2c8d0b15acc3275d63d181d3246efcfc9fe850caecb0a487cc1b339c518980eccc0d607999cce1469163c6ba43255563b092e7f08f08aa782f22f38bc837db8cc32c685b2f334b530fba8ad848a221ad830c824b31cd43e3bbeace1e1f94a6ed776a9583dbdd33a4ef5fbc88f10a4d7febd5c5461cb713bc87e9e98b33bc7cfaafa84af9aee46d736e82fb68b3798ace5bb3437502708bc896e2c82e3d5dd35848b526656cf503e30e205d403e158934e43b37403edfab8519f2d4fa7d3414f6cd129f7703c63f245f7b8c59378e4a110b8c69ff9c938e1f26487f58e3c4d587bc2e4b97145e81b57e9b7c8ac920b367adb2fc1e618fb3c2bbe2d3303e6c945ac32c41fdd38b055bbdc78acb9021d24a78d1763368dcd38e23c9fed14a6dec02746d96eb4870cc68c9af4763a47e04259031b0709e0c388cfc8ad7156f81bf04cfe22463888ecb57e79f2e017bb38391c61cec20cc1e83966eea2a75a43c220cc17c51d318ebb7c81563c14c3998ac09d1cb69161659caa8347386fdc7748579d20b", "ac53acac", 0, -1740182601, 0, "73f78151539f09073533f53d2c202904682ae9e8fe2346485214cd05f2184eff"], + ["030000807082c40302a2226d8245970f809c251ece7ba560c59f4ad657a81f63e545fb4a5cf226d7360300000009656a5300635365ac636b55d0d19a4978e63255c7d76edbd661ae72f658986db4965033d97e964527a9af0d5ab3000000000351536affffffff016f9c84010000000005516563636500000000000000000100000000000000006d39780400000000f765e39bdff8bc627a831449fa8105360864ade9b31d879c8ef2e7b93d2b05e0e77b2ef8668c8553708a072352e633d33f9176e717b517f92583f945ca08132f18d728b7d6378b80678330c2690a590e8fd3f69402a6da901153d1412c9de620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b3f916fcca540a506407f069cf12340a3a0c1381de6557bd29d18b9f30a466f7e7ab17efc8f1abf3e1d59633a54fc7b64424725395d588e1dbf57e86bc9513cef88524e8f14e00b738dfa56213db2bb4262edc10727dd3b1ac933d60b0ffa15ac9ced8a71d8183855f94b2ba3ed15718f5b61ba31f48301e00f37136fd1cc990317c20da970fb2d1942bf4c160e76c4d944f771bfed098ebfb3823dd34520741a0314008bbbbb7a6ab3d5f8c8bcb1138b77beac8457d5f6b697f16eac16b3a8198e0a08198656b457f4d685450ecd3409b70c21c128a4edcab3c856b296e121ef34f9b46b77b37154b723c1d412e70f54da3ea6cc0726420cec0c6a6656722bd71e4b0220fb3af2ec592cf5cb086a7669cee307d5f2f4c5fa7de47cc88029407b8ff468021c66fa99e354f13317aa9e5ffcea88ad4c40bbb8aefde882662ca96810c0200b022243221e099bc2fad651b207d47f9ded3085798fd4cc44b6fafcb7022e8a9ed40310562ff9db40791b9a2fb386b2e799c3a2ffc02d37da7f581685089bcd95491d022867e1639bb8fa5c197ff799ef4b93ad9d839b317772f5cf9c21d92e71026add3e2a741ccc29d56f952a371011e69464c9f1a00c5e5350c0b92deffc940bf59926306163cda99b48cb3ab7828bf09448fea1bd44770b15746690c0e01465cb049860e9b4238db23ae157544dc8dbf9c2dd0c77a4257cd94e719170ea2bbf3c335a5135275cd119c805e9d84457cf800a8f1d9bcad2bd16e95fea40c44d4ab2cb037f803f56e54b2a475aead6750dbbdc3ec16b009fde5c863447853b5968ec00d4fc6299dd37f713531cbde2ea801698d6e202f51f138564964089b0626008ac74651ae0f9fe010b9a19a8d29028c12c917c679233969ac583dafd2ab93d65fa9df030d6317541e2d89c9ce76f6a4bf6bb3bec49a8835d381728d09b86ad6c9487bf391577a981b87418209c8e85b4cfdfe44ce02719cd01e4257b82863437d13d8faa0e1e54f17dcaed28d4c353b09206d74f24c8865493d7f9b0201bb71b1102d4d51980aba2b7d352e358036f0b7a7a9a6f4c0aabe492dc12b230278cab584ad75b525638d55315b58def6874fbe3164ac80cd6e7efbf2e3d95541f1c376d45b65a38647e2861c4d6135dc63a25c8c8df1c4b53f38d556b08b9186edd06a72e29d80b7a3c8963d94e05b81afb159a7ad596c90b9862c3db04721d2d8ca7dbcf2b52fdd05100720d2b24e31704a6a1702fda074b54518bcde795e5522cec2b262569cb6564bceaee5af76bde7479bde70ffe42c419b89ceb4a54a78f600f3ba05a2c21028bba793aa021cd3c7187b5607303dece8dfa15f13e8abffeaee33267abffc25691c1d1e9bbd583b5c6400520917a70469b828f2e41c9f3926c03800e9be608e9c88ee121bc94b92551c365a4ffac09ee058684700887b72f3f9ecab8ddc216bf3d6c589aa941e8d40bfa48a0e2456f85b515abfbf7096c5b787bfab1be0451dbcaa969109a8cb34de6e09200642871cd32eb4ff8b79712bcbef4e6de1ab9f2ae67e8eb466ff1799493be5ce4f14db675b843f67474ab199dc25643ea2ce83ccf46f1aaa03865bbdbbf7e1b0707bd08e42a67e2226126ed92b7ed6f2e4d3082613a1d54c85018bb3b6e47b93ff3c094e18fd7998e0f6aea8c178efd0524c7a6f8a4bcfd7180144d969a2330c848e032d22b44dd35e91cd13190948da6ed7808ec9236f0a43e4758c1d8e42e2e2235816169982cbf7616a8c3ee87f3806a46bfed18e3eccb47729bb7cc31a68428efde611eb7a1ecfac4aea068936946377a170651c38e80902e7565452936423bf97235bd10289869b0d02658f2b9a06a5e98fc07978024051185baf30f62b1189d264e4d4734f3c7e44cf2a776f786659e9a3cac2fad925c9a887adf092c1cdd92b0654947ab275522c9a83212576d2c16bca1d26d6088ab0fbc826e1988c10d465dcf6e2f0cfa84fcb25b6db623683653acb07e764ebc1c69bae2f3ccfbbd9da33b979e00204d7c133e0772039c41e00eafe089a4e6fcdc188fcb588e27ce68ee6ade9ca4d6931162984c9678ede8863fdcb8e7e8dbe2e613475c6cb68037350b8029d9afcd3a04835e60ec52d7364397e300828d82f0ff0f3c8e5cf058071eb0a1c4fac1b8c8d32869a6fd332217c3c22f4ae2783106df0fec8241ad82f606ab64f4d8b3c26cccf58b8784beef1180e3e616a8550a6bb9bb81e35b038c61e712e44eb2b173f9c6762b57ea300ab074089ff72a21ddf55543ca185b3d6c6484e397a4634d8aca50e4a6b9313a262df15c045f2de3ff4c8a9d1a074796ad8f384924484ed48a9f95a6e8a1a3aaa4a96384003ee5ddffe7c79fa2856f4c445b85a9c9178029b41ed465deff674099fd44bd81248293af90241172132fe00abb0b", "", 0, -753011132, 1537743641, "d82d4612b1f4c212d2990c386bb53d8541a243812b2da9c23c50b715000d0c83"], + ["24f81e77039e404f1244042411210daebcc2b17657b9856a8793e33764e444c1227ec967ab020000000165ffffffff6696982821f4e0b13950eded40ef5f2a4621f59f9287e7a50c07bf71150a3da4010000000700acac51535263c9d282b520c29525831e79a12d8442e44615707eaf873171cbd200d9b887ba99d71b5fe7010000000865ac6a0052655263ffffffff034a6b6802000000000765ac5363635251a5440b0200000000086363006a53635151c6cadc010000000006ac0052ac53530000000000", "6a636a", 1, -2140714474, 1537743641, "28ba3c5c4d67474cbd78299ee4d8cd7567b61e0a0d07878fbd5ec4afe8c02bd6"], + ["030000807082c4030425b49943153fe14df58ec5976974a6642a854c9735bfc56faf9f67e5cedbc22e0300000002655393bddcbd84a5e59304ef53fa2e626c6c963dbf68abed11c1360de1d8aa83162eca878c8e02000000002c962be970a9fcc32c0b66c3d54be84ca4a30bfc03da4bc4955d23e350f3ab80fbd210240000000006005151ac6300ffffffffedd380d5db3b07d9af3e4af398defcb6dc5a695b0bf3152b211c60ed018672cc03000000086aac6a63635263acffffffff03b78da403000000000665536a00ac0006823d030000000000ede023000000000003655363286c428a000000000200000000000000001289490500000000c85b8a411e40c579710b53e4d0bb76451b60c29611a28516c113d4393f2afa1fd1e901cc6aab4fd9a4ab852b41a66a14b070f546d678493f0f8a82084d802923217bcd4550c5d5005f053db1d47a2922799e67bb57994d95799278bee30c377000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eaffb264a5498621dd8bb9e71cec09d428502086f275fdb7f271cf14a387ec627d4f54f583fd5ba829a9c83c45e1303b07d5cb7acaed61ea2feb4b793ec336a24d650ca966c125bfc0eaefd93ea54ff2af2bfc89be063c9397aac04179a847180f959c62e44f6858e821a9a8572f0fe8e1d10be1427946a482cde59cba2224f70315e273eaae94e6aea1b55d68d061b8762324507b5800e47df77d3f7f32066506021e61ace0976be94ff1541e8bf2cf1c38c91196edd7e31eb14839efa0ff0e6aca0a00d40fcec004cfaa42bdb5179cbcbad667c47339bdd59bab6331cc9f052636a3432406147bc1ee15e2d49dfcaca9ccbd2da2659091decf3642df4a0e090d895e0217cef162f3a86edb128bc0a6e7a8ddf96ba0d0fc84fa4b44dfce2f188d71b3da032a16f1a4307fe6b8ac594df1c959cbde4da4e4d10c5910d37f258d1ea5f9cef6031a1a34a9dde030a41dd58b541508cf397d425205983d64a72e1f1bf10802049d03109d5e314ccd215439fa5b48c3b6d909dd8f934e5ad331b59896f93541b06e65021de71e0fbc4c144a740d3f72663ffae11afe4b4eac8aa7673376517a4b48931b4d9510a72e1c4b23dc556a32244bee57cc1333d72e012aab0667fa6ffa95c0258612be41c20bf84205b95b737169db472097b1c3b497edac0430c907d1303395e906266ef7d85a772b0a35492e87664070e5b6fb247dfe4d0ed73413c4aaaaa5caa9ac8d8f952a57161284e937f420756401ff1cab3bc5d3cd8386bc84554ccf1063f87a1044ab499b4d181a8745e0b910d8b56402df99a90cdf1e51def77febaf4ad387db40c945d5bacfd4204c8d04a9ebee58177c969279b4801c361fcab1f5a71363356605ad1c93a8f2e9cab9c804d26ce008c82b040ad5c770d6d9dea21fea38b6871994c72a99e9a05bf34e83d74e39357a5b5ff0bd9d9b2e0813c506a0d0907a82eefcdc040e9ec802833c267b1b578d133e558b9cdcbad1ccec0140c01c535fb4b3bb4348bedcf35c4bc63b0f05eaf865bf990681f9902dd03865f9553ea15a7f39481e95446fd5318e793d7fbcfed48da7897a47c6690ced95dd01c6f3e3e7042c726c96f7accc135dc1ea615efff4a43a963a88833dd7176be4e6d0d36cffe8eb7e4cbb937c455ca5199558b2a0522202aaa63b8edf9de958f61cd4fcdae9e7057da759785459f9c2465af8eafa8a5d6702486e6248edbca2fd1c8c8d1d07acd098c3d0efa0dcc48024b4e6dbad33209efda8a2a7b63ee5216d55c8019cc69fe9485c619eb4e093e8f3f0aaaf3ad35559cdad454d9ef80ad6bf758bb9f88df16bee977f99d955c2cf72cb65d70f10f1cc5aed4997e2a52634bf3d68a02e1a455b6fd59ad4fd84556c7d241ab31595e7ff282237487b9b45f1d0c350c9dbc6d7bd4bc797287db354ce6ad13b8b29e60b57b39249216966c5cd6b0190e4a477cbebb1a94cd36c803066e750b777bc69b3300ccbfeb7e081db5f9df3f6b09a2ddd11cfe9be5bc0f73fa27086c1ca6b6e7c06546e59a9a458de09b34e20017a51ed8e2281b2cc62c1cffd24ea467e38efb536d4cbe1e9bdcf54ee79df783637818fe9b2452cddcc7da540b49dfced5c94644c87562066e093e7e6f499c28f198985affdb49bbb36882efeded8d247d47fe63442ddd23d145cb5de3347e2434f5f650078e69b6ce030271daba38524b9996ee3639ff94b671dd9fdc40b0b8200508d43ece58913219a11893f9f867d34f275ec019ac2509de7e2efd5ff9c1c3d9c05efbcfdad3253f7feaaaa3caae57764764b32f535755e2554e3edf9c778939c87028b2beb2829208adf0152638e5e187490ca584f838075321fb3fc3cb983ff16828cbf1c21ed5bce89b1358a29b730701461b1cd815d5fc1f0bb1a7645ee3e9ecf88f338f21029319b9ddb380512d49ee0f258c97e1578f33cee2b4cb2010ef3943676fa0d43cc632f4f894a6b5040c95e5f2e2f909ad43edd2a6de3a26c994c890642cbd1bc719c5f952c22a2df369984a97d000c9419763f9e09bcb1bbce64c733196cba89bfc624832aa3de6a5ca8239896e81988f851824081fea030ff539d45e464c2c2618f1a0f7dd3dd8a696450e183666fe7640af407de1536441c6d7038d975e41f6c76f69c12faf50100352c1b3835f7915b58d042758ce0dcc05326716d727e112643070471121728fb212311dc3ad3a05017f3c01cdb4589c658c5f229380d0a4c3e296aac22d312991bcc4de0261093275b02d6ccdf7ee98feb33ea2e3d14661aa160a9a64f2c000000000000000068ae2c0400000000516823ebe2897fa457cb26ef2faf2192787348051516604d565e2d43d94d33f674e0928745fd6d054f7f16d019072cf09223df25e7a8dd00fb35285993218c47866d67bddc91868b8b93c40fc52e2a8d0429d4df4a4d53e6ff1b8f47cff36bbc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d4962bd503848bdf914baeecbda162bd0b96581649b7a9f221774cea31274d24f18ac90754807766cc03d3ec38e9f2d25c373f93fa77eb952d06f0fa85fc1b7805215a6cc1e10795af6d0b768112748cb1e0510944a454cb3575dc10311cc465beb081f5a4a42c9b00268e81ec5697a772046d634e6cb0fcc96885f634946bfd03163c74a6e069991460e759c83c153c2efbbc847d3dcd0d10b0f82929a478869d0222e98e71b68829cf1c2dc36c9a4265e9a9199b7ce423638cd4c3e59feb4724f90b01db06d58ee8ead65f69bc9a511a18d78ef31b527a306ab749bf246a7a5c1cad4ab8ed8204ea4daee8157bb9fb1a8a757fb15dd2d7a586fea4c477bf50ded990020c6626d226db3ec93d501b188ac8ac480b31816f74078a551d00d4da1b6f5f9f021f20afd95a34cd0f3f3290c6f60e7a91b9a5d213984532324e14def3c6e6a5cd022e69b08b8d9147302977f131eacbf2fb15377b7af9c7a51527193eaae46e073b0203f42c2a0b375a81e9174d2ab4a51e68e956b42e1983327fdbe384c915a6e203021c21186797a3b9fcf25ed8922b969071e8ebf6d27bc617c4cd97f280627d4fb6c8c87511ba40a42063ec927ff8897a5b988c650af46e1e0cdf1f5d12eb957660a6af6a3767d2b67113d680de577802fe0bdea2cf28bdd168892017e0ee2ac46a7df47d4d233663b73c0d81d55099f9c61c2cd94d3cec2a33ab2fba67f8534c7da090e380f00bac8fd7fe98c9db4ac774f9ab58d2e94afc202968561836c12bf609a5c321b2e9b33ed6f815f3025f88d0dc491ce3f286b65ca7e635adb49cfdeaf3791c529db247ecb2d46e6d370e6134a66fc00d9d8ac0f301f4ff3c92fabe6c15dfab67e906f581ae5aab93393a2add9677fda74324d7b441deb9121cee691fbd2489980dbb4fd9813909b7e2bcfa7505b2325917d9d28dbba39bfdae3afe508625abe86ff295613258f59b6fb39d9cca752788a490be636a05b88fbe4ecb710397545f0c38ecc765d8e31d1407fda0d7401708e5f161622fc1acc5e0c10b07623ce57995b15a91db30751fe1b1520155aae733f38df2f44a776d916cb6f4f1cff5f7638e81abdcccabd72347636cc217f6d4a3cb21eab035691b0086b3b8daaddb3965023c749b5313db1f62e3ce62c71ef7d33d78fdadfe3633d33e942632054e42c0a8daadfbad648266756f3a1192a83fb4bbd53bbfb2276edb4f861cae34f0f0c607d57c98bad954a49c4c05e39df92fe5e46d6b0fc6442bf84403095eaa28be33926c26f404adecc7d0e5f545be09dd9302e8fd685ee7e45d2a42bf246bdbd7deea63539016059bd4ee0824aea6d702a39dd2826f4048bfeda93e7cc31c00e79158a33192653609dbe9728b45aa373735f0856c35f96c6923dcf5aecb2b3824c936b061b2ec1560c45e41c8ff50b4395a3766365070f49db7e523cfa7459b835a381a48af165065a0b3b4b2468e071a484f6dec6c776ee9274544415691fd06b8b9988367b7ef181477e9c8d10b7b416b1efb692a4a1166806632f7763559712925b9b5239b6004135a6f3be41f391e6be0caddfc19d075452b38ee8610357880dafaee0fe9a3d539e89cbcfd8c69ee0913a6458811d51aa7aa06bcca06ba8f9b74d93c154e4a03e615c21c75e716cdd52e08ac0eef87dab181f70cdb020bdc6ce163cbc8774457bd4bb9c64b12b1422fab66c69da05859bda1a835f3244c8be4d3e335a7871a6fd3a6f837d9a734e1c7defa134f57e4504a88af2ebfd3b798949694c294ffed3da94e5311b91f7c1dcfc35d50e3e24424d8dfaf165f3d09f794f3818570532fc07955f879c0a5e41f4ccfad9673d06f31169b45037f514063043ef6894661007f7a46fb0e3bc0c0bbb4b6ccaef8a18fcc9d1f1ad21dc78216cd04f9aa96385167de0b1b39f24d88d4686c0e3aa55a578b4c5f3ef875134a3198def2c6c12ec8e0e2ce275eda5dbfc9161537a03ddc677dcec9d5badcaff5f0d73164898f774f91680fc94a5c2dbd0e085fa78e848e9cb35a780694e1efad92c08abab5198084d6470fe48f4fb6709d82e83bd66804bdd6d0b61c3fcb1aafead10b561917ee2f70089658efd09ad37fb4e2d479fa1fad80af35d4df0c2f84dd09aa5e79469f6e55cf52434a403ad66dea774e5e33adc240bd9e8c93a48f104b25dd3bdde65d044f9006a339cb59e7ed90ecf4e466a209f20b40c94e1e9f6be8d06fa94072a2a83c8984ab8e4d18968f8bec42d796fe41c65457ff3fbd0fb0682df670e1c8404cd41cd665b69de9f6da53b9d92449988a7171994cbf0af54c2cf2cdd62b092d411d216f74cb8f64587b807ed998518933c77cbb1f2a1aee6521e12f986fd30b865715861491abaa8f3df5b93803bfee762db105e0878081a779bf5d2a8284e4a181e74edd6640a206", "5253636a6a0000", 2, 1609480731, 1537743641, "4367f3e65c4e2acc71dd0aa939de39e9cb47b216b108ff9f9d5f231dd8b687be"], + ["030000807082c403012172aeae2a5dca894e95ba7a5ac555f499f4685d86fa1f7cdc40b4fa6267d87c01000000016a5a0bdaa903a296c405000000000163a5d45a0300000000008ba886010000000000000000000000000003000000000000000065dccf0500000000e286d36daed85bc38f79875f33730e5694c6c1979abdfbfa5c9e20c40c0cc0ce4c86f865881109017342845636b75d2b2f7cb31bf631982ecfcd3663d804bfded0d0eea597d03b43d118d701b4dc1ee59943a8a3e337f30ba29ed1e6688a842b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004767ad9c78939337362d0ce517b92cf4a3a24f826d4da22c7f6ea9ddc175ac2811a27f6297a08f9e9ce2676024145f46029a37a7f977ec3763ae298d684a22a2d18ec32af6caef1b262fc7a8a68d6847abf9f83bb5e4dcc49644fa54bad60aca42b3c6e057123980ddb88d985419cb053cb2712f10b8fb495d8d9ff591a5048303003d6fb951dcf96adcb919216ac398f76afa5ff32c9f105c58112d76d9831d59021c6f02611d5c5b9d4f9be541f29db76000af5a6283676c4d30b2b4cee55dc25e0a020e04d73df62c6111e9bdb5b9a2719e642d2b3f61873905232d98df4bf27fa4a49ca3d38802ed545752ca8c7ddc692aa97e2682e5ed76e19d89b25aeb2524ba030be33582faa21521a98f9cfc03de2b8256e456547271ea3601dc3d9a1d33f9e9022bc03a4261f375684bcbccc4bc2e3b8b7e48938100db22d82c971216cfc7726002038c8ecb97f11c39629f08cbb48d2b9e3360f752a9373bc4235cfe48ff503a07021a42f74c75a1c3352900e3afa16a6f282e4a5651e003427b35afb5e95bdbac83020685e377b2021eaf3362c27e657c6976d802fa4588e5744f29848523cf06e968941730fa7e712f1e92f5e16404cac4878aadf25cee0fd20303944bb11cc91a6f310de5477ee5db8c351bd1dcd83bef4289c8e0b430ddf93ad9dab36e3452c1f3454d70694b3ec507cfeec098149675360acfcb60f5f49f52ba5781b6be3eea91fe876f7b7ddde1bdb2812a0c89c5bf45c193c7ec195575d0737cc19e041463d45d63feedea01ab15d21a90962003b8f0f2821cd7054ec543a8fcfa2f0a048c58faa3b3f225508f21dd1b3589ee417f0f3bdfc515f05034cefac80ef5b89a9429931c416ec07b50c998069fb3dfae382f495847c153acd17b998ce2d392563f5906068aebcbc7db55c1350d5623ddf623347ddb928302b7af7a2000aa486139fc8229647e0d9eb00b6cdccd2fd3d08e8708123df0af7c039782926d5988edfca25ecbfbcaf0c21f23228396695254da4c68fef78bc237657ad658126a081e59c77e9db3922dceed08c8caca986ea01c552f30e53f7bd5c32e56988d182c5b127c34cc73289318e90fba8e1852ded2515e8e18e60c7e4b38d639e92514723af493146722ac8f5a81c4a2bddb4e057ae97f7911b100b2e63f4893eb06a2a036f96777896f203dc61bb8e8bc74be103b2cc5be7a9d9e23c118fcc30c522d0c5dfc32267993e7ff2de48c5b5b7336f5b0b5c25f9b21e81b70ab5bf47a7397690d19e9ed561610f6e887ed470c46b7c044d04fce1273ad2b3255436cb9e1c37841f243c3752e568c3895cc2e58f204055b0c82bc6340c3beebe69a197626e1503b9df9cc639441f0d2b6d376f6b37ba485627923480371a44c0c226d2b620042cff946b152aa7f0d5f0cb321d45fbc925e5530f2fcfe1402c72f8bb59dbc358c6ebb66cef6c3eddd037159cd3b2692a22443a7815559b2e2671dc1fb8a1f6555622f129680127e040b56cbdcc1c1a23a8641416ba80cd385776c783d14997058e1874d527a4683ded050078a9265ac9349a43e0967350bfa6031647acbd0a4df7f0b0ec3b2dbd0cf36edb010ebed779898902221c5b3cb6073192202d1f66418de712743ec0f19beb5728cf01211a613c305c1e9447f51b806c7474ea884658b76c00d9183479286ce8a6ffa1e57998cc03ce6b2d68ea3f340e04109c8fc21d43b2dce940a4616b22787c9c691c026855e90b5a32adc4089d7726d5351481ade5a937861ca4eaf2e358f5994b0681edaa09aa4351635a8f5e06d28d22a8988407bbdff4c4612e9a5c2ca9a838a880025eb468a12206ed001eaa6abce003b1093b214075a6cbd6caca0a77ae85182c23160af4ee1eec7726be1fdc90f849f2066f8179ad53017d306a8d09e2c2f873064f82cbeb96338e6ccae82e38287149a85036b0b1fde6b59c3460874c2f4d4810fbd90a74cd93e52e0a289ec0953d29ce9fe7e6933282e31c309ac20079b96dab20f57e54836f110156d926dcb733c3702a21c1c3679f29b6dc3194ee9a2abf7dc6ff85c035aa1cc82a84297090bd3c15a0ec5a0e020dcb29ef610788b74609874eee09dfa388039f784b77a6e2879b44b8ad6999df05aab3a39875f2ba2ca037a69ae87b4c8551ab4a095f0669e46ff0ed1310759a8f3da3cc300a0aa43599d37005bf79b9262e1b5202af20f0b0e071a1247ffb1a2b31c15fbf642d773c96af973eda8ca3ceee01b72c0d1d0a0d57fec39e9852effda78044cab80d578c3d92caa298d9faad6b312040000000000000000000000009a78da2af5dfcfaa25a5e861a6ba68a704d6c546235b2172f08929217b31a94c67a9a4504fe762b11128a4f6ae49dd7c396f080a27f34129d6a26ad38fdc95b9d5388d3e95a86a2d08866b19e10925ab0a44047ec51056bc812705e8825bbdf400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b738d7d9b9b4933563c36272cfb52c9e40b0ceb940cf3d97185198fbe51c38ec26c5824e8ff0d2f06d626bd6dbde522f4f5bbb9995d1ec30d1e927a98df946139b3744739ab3590af5b3a1de74a0941a2545a9efcd153bac209c40f582a169c65e9dda63480c2374b1316712f6f3685581dc2369579c783e1f54692279b054a50325aab2a598b7917afdb39ca46741d89141eb520902d052611e69d00d98ce34600206aabbc38dc1b48164a13ad1747dc36d017d39256476f1d233659e5cec6a9bb20a0199b106cfac1b6bce896abc9bb9b385721d326d546790e6f922c9d2680e350e3a3dcff07d4f6a6626efac9ea1b907fe06cb232622ed4f52cf4a4b16ffd38b620229781512297ddbfbc3956d7ec7644801315772c1f67689f0092442a4205932090316113d8daa7d44f7731a47a473a082933f4a65f12636e39a52a716a17159c0c8032db30553b96693eccfe7d386beb4eae4cbc4df0fef4761e5ac0e5dece27162d7020a8d1c4b097fbd75769f31ea453e2d0fbda41458ab86ffe58fe3f1bf4d39cb14031d0a3eb4987931fb4314dbff1f21d84b72640c1e39d5ff0a0efe91deca58c65f077f8bfde1557bcd9f9bf4062c99c035c74298e97d014d73bd9e379b55004c2ca80eb8c0ee1b7f5472a6c5e825c815a11da9f699ce633128de636ce285532b2163c419a18820dcd954955b40d89a2d3fc05ebfbed744a4524433e1b4ba6df918b96bacb268bd0fb37eeb6bc6692bdd900b74d9d8ebbf4c31022db4ad27861ad208d325ed22057fe6ef661e4f223248424993babdaa6067c8a98deae66e3c436c06f5736cfee62e5390568a38f46a66c0f7b8dbf267101139e559c9b88fcf145d4f8ebef5754504f811f51489cbcb59cb094aeecd5d49d5300f2b9c2097e75a3fce68b7dabd7c5e02b5dce58ceefc85e67663249812b6775ec436cddc6df08586ddc1727faf8ba3cdc8e4b8dd9fd026d9a24cd6198ffcde27b14a3833f4e8e7b0cb6b1a543e38c4175a400a0f5808c6cab49fc5dec838afe95df13e265f1c540cee58dd20c241f0c4d2183378d51e2ad6025bac51371e0de43bc6f4ceb20b14847adf6aee52ca30a84e28faa2f2e65d895553b802e69ae175610d8559c6d4688e21a7a166c6695ec45c4d9af0217067fcd14624c15a8532564bb5e9e3b16f80b8d72ea79b8b82e0af39cf1e8670fb98fb2aa949535660b0f9bfce35b33f79fcb4827cc63e31b182a0aa8327c8950b43f53db79a166035323e97f1f18fcb3fd71eab90b5a5c58006589b9bc6c5e9b6366c8aa3f1aadcee07c207a1cb0c21927274426d7a5ec888cbbf268b79b9ab008beb064650c315a3262e2bb1baca367fa3b6d7c1c61adb9c4060a17071f98309ed0ab64dd5816dcd6a71a960361c1ee209bbad66ec7f51e6a0b0c99cda68223c22e1f2e487c7cbf5640fa08cdb156839e794cc1de95083f76ca8d99ff176665c43a65fb3583cd4e3613456a0cb2b5227a3b606732f387cc5df0c094c996865d71ac8829a8e105f81a2b3538e6b617b418d81e0fcc225dcbda06341a19d053dcdceb3b3b4513967b29a4192d589616818d872dc2b6f069fda406745fa5930a47947d7745272595f2c30e683c4c3cc08a29b7c882a746c0b158133583ead2606cced2dc23ece49b18125cebe02198da8af725111f053b9ca7ef37babb6d91d37d9b5469b03fd909317f9ca0d2911d6a6ffc0261e3bfa45d3c1f862065d92da6337385666f8320a6e07b808544ada25350cb1d4dd6a66a6d9ccf29f3bcc5f5de82c9a903212787b3a89ebd9dadfc6b5708bea697c05f32b00d7d6e78b2d3df110e7ca694c6b11af849cc14b9a82e602bff586a5f76f2fffbf4c24fcc3452eb9d81b986fbf68692746bb94e849603ee40ba3a2254854b8dd755431dce4a620ef9bb3d78a42a61878b69b24dfdf97c1a9f6c2df6fa5a92c08bef92a547f2311710452bc965f8e1da622569cb4dbaa712ebe386222b361f396ca45cb43e66ab408a903a546042520eba7b7d83cc05d8ecf8bc60bcefe69b0a63f3d4f40496244eebfe029187d21744c528132d00507cb1569eeb8c024f37b035d279556716689ac21209d4b85af14e39ed55419517d4daf9c32d7495e496bb08049ba17dc6cf33090c27afc07920f605ad89298d1ff0acd23861589ded0f499b312df5687e85231d3d5b26d943faf246516693d091503c20d50ca28f1fc384d0e5f7ab060e651be69c06c747a9c5fa6cc37913e181546ea57021d9a360e21527bbff4323549ca13e4fc707dac0100000000000000003ef8410300000000b38ab676314f8dabb3892a5e89d19832d5ac53e0d1b054e398f17f8b381a2f774b227bfafeb8b4a043e03f8d7351557b2a5fefca513a6116df86a4004e2dc7b071eb4b52e85679cb40e98c6ec44c92714f95f4d0029ad4764863650f362e8ced0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098c4b85c03b42537590b9fe14c2af523bb196f86354e40ba37f9bd0f4acf28a07aa287b154451617fb050ee07ad227f26662786b3bfb25c1bd1a80ff38cc6520aa658f55e12bf4139d813c804ec76f4d25b153fbdd71c253893feca760f000970f2984ac8450df2ea59e292a3621624dc72483bda7bfcf6a15124a1204101fb1022e282674ed9a8c6301057fdbc6de59a770b1a2157698717f150d8fc2021789c4021caf2646664a112dfc1cfe73eff3165b6f6dad8bc8179c5895fbee22370106610a057cfa576b3203175b624796a616243bacbcdad2e128bc8c7463c2e9393596c4630a0f7337d8bef8c9f0f41c30b599a5e8e090b50047d5adb69786b1dcdb6a6d0320cb46970b0c9d29c170ef086108727851225db9a0c45e56eb9efb50193f400c0204adf640161369f9dde9e38428b098dc65c960efe3891f28895a3de35462e699020b5e34c41f10669fbdd7c12b446dbbbb7c5554ff06334960d3b66e6c9068a55f021d44bf6c54167f432d52d733fa21743841dd0510a454cf56542d8f6cecc05219023040ace97d354c938e8f573eef81a620858acba9389910f4ae8e0f11e3a2cd2a5596cb0ed1e0a6556863e8133c9a87cafe046fefa7d84cdcd3b13f204b02e555a0e43925b4db814cacab859fff661c4a21b3296103a52b82804ec7225728652d875078a7b411c317254e37fe0f80ad35b2163877253e8f977585729b49790c59021eda07a9a61c225d291d8cf1a1765424c6dafeb9e4ac97905a56e17d916e1d50acf9e99446f512ab3fe1e905f4449a8be8cbab12af4c56ac9cf158cd86ef2555e682b23f271e75d30f2b6ad948a7f0d56a295b7f6cfd7c5023f12720dd3c9349f3f7c25adb76d6307b86ba311b8a581f37d4350fe2bb1a26997ba2a2ed658ed70f018a0bf808e88f00240f5cd7a2089ef3c83ed8b5b7a54c52d92841acfdd3c3acf6d0944e11b4840631f2606a2be21a742f0511c4214641aee812e112563922fc2b58e644e9aec16f5ba0f41ccaf9614e3b1d5b067117e52abb1be711d6e96f9fae6d8415a197af059e65a42e64826449546beb9723575eb97d95355a96cb469f5bd6ee3dcb5600e252a8b42e62a80bfe2ff5debee835032f833a714f61eb90db1fdcf816c730c9fcf3320027eb978b6e21f17fa6bacda101b47fec7a4241cf6da682fbcc74dad7c62c57d62d64ccc33290a80c2acd1052752f5a808ef0b54839560d2900e83618fa89363f7cf5b3341a2eeb7690d23733ed23eb44ab5ef8f3d07e4bd1a63e2048b7103400ed786d3c7069b09d8993ce2aad6c8497cea5eef02dbdb69fa9901d64fa8787dff3288f3fae9e113222c12eead71c2b1808696507974ba83e4571bc73f66f8f60521fc7d0e4055c3dfbca9c4d0c39e6e494ab7e4d30aa5c4440ba8f023d7527a02d002f2eeb33316563ced7911fdbd008bbdd472735d1dd3672c41b8521d50aa3f565de5304daf8656f2e95b92423a9637434e833c794fb174e6d7cd52ca91157fa2ba3602cc098e975e0ca2d94ad77ce6de51afdd4652ba021b74c7236b18db6ad120b67927f893c4c2d04147308710ca47f07a4383a15bf145377a241cdf6334b2ec6d4ce53b1e6b07c88af6f2ce73d4384c3f140b0ea557a58cb2c9a2d91f6c181877d7f99a11fcfd52ace54d363933e5389cd78b10e21936e85c1086f9d59208ca0e0748e03c962393d33031ecb9b210c898a6826bace402b520de98c210de0b99cd36694cd4294a121a3e848525ffe9fe0d6861c716f2d3e9ef50f7683984831f8aae867e9eec10c76494a8f2c9cc93d873038e71ad732bca7dc98a0ee651d5a9d66883bb2a1028c111dd40960debc3a277816389f81ee00d423780a84dc52ca17f204adb940cd10cb0482c4e6f36ec509d3165d4a069df60e157568b04db863523eefeb33e994ab3c14d30c7570598bded16efc396bf3c43577c367d5a47efd31929dc670122c87723fbb13c5b2196fc91cad56d501ad228e4fe732339928a3b7756e8f25bb6dda05ab218907beaac7696fa744175123e7f6d05ad2b57fb6481e7638d02c43ed95feaa2ad6409f018782a6f991cea7438370abdf788b4fe2dad8e8b1ef63186b00c489d92958e697a896918a64de655390aca712aa69d978f5dc212de9ca9c61312ee09e218b4105e175493372c92de69007dbd35f8776e60e7920370350f135272b9501fa3a7d1088ddcf429cec565018ffa37c4de0efb5ff2f79b2453e249d464cc832433f331793770a1c03f6b080689f65881a068844f7092626bf2b64e73d205df9c7e466af736f287d245d9cfc9507cd4868b7fa59b05647ea2889cb4cbe460c39ec1de2f15dfc67574db4a1a082d1a5c1f14b80dae94d5a52b36c5ccfcdbc6d3c808d4b33ab40de8f8855eef66634f9e4ff248b04ca01a000", "", 0, -1656043844, 1537743641, "1514c9c10e11334aaf6db08d8a157469879b18c82a9226788b9cc13a63592638"], + ["030000807082c403019a0ce9a093a3b688576a43104ffd3f3892ca65ffb975a76816ee73b2969305cd0000000000c4a78e5a04e0692801000000000963ac6353ac655353527061bc04000000000153469dc302000000000863ac0000510063520cf0c0050000000008535252ac63515263f2b6517200000000010000000000000000753bc20500000000c89734afe7701f72893ac07f8e700ac92c985c23361364d68a8862dfb88bceea5451bfa3854a988258463c5c4fa0188b5d9ead46e6e3af024261a4ca3d06d491c17ba614eb2f6efffb9e205b3d494580603981569fd864b2ba6d1f79c19d65f400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d71fa7310e14513e9db55fa4c23a4a4ffec145a5b5bf2b7be99a69613aa9c9e30be98ce2bd4a2b4547da7091410c04c82ed6375df4ececc87e9d96da7fb55e0643296ad68f73c09ffc0d24029544b48889f56988f1f630b76cf9ade3a61c1bfe94f31a6bc7504ba2a135c497f00be198c5eb095a3b0b45405cdeedebf7f16e40022a53d5c76137e5265ba751ef43d3028425940cd28ced19f26595bdf2fb33ed420306984c87fc0a71650942ff30408ff21d61cc7a432c34ac91a87fc48c1a2e811a0b064fef6918585a09846c0ffc9a3aef45fde3d24ab01b8deb157528972abcc3d8ecdd353f67a9159689999c3e1646adc687c72ef05292eec93706e79f76e7d82902085eb4b2ac66aa1efd4a56844b2af51b1c7a9ef629f755931145fc621744cbe1030274e059b377289ff7cc7a12e1466b8e4d2f4a51f5d1bd724a1e09cc041ff560022879ee17ca0bc5fcc0a5edccc350c6ee59190838f223dc5ed953d34cff6915200201275884f6f642e29b4a28d48efe55cff15cb1737a0b8979c0172164c69ac32002139b8bbb056b93ffeda21c3ade69d6af7cd639345eeb126c726072d9722c02e608b8a8b02a2e70d041c54cedcd24e00156ff39c29588c901f32bf23bbf86aabee94f34f69a4fa5515a1f7ed19dc1f57e67697c82d3cf060309e9ff6f6316968bf123856484117b228ba9698a7d7e70030291daccb62a4b78c4224deca253a836460932f906089a2bbb180ec59a4db2372e45fb18ee88ba4b1f5bd77f451e732f807b7b7890e709b786647698702e2cdb8af98908f0aac4fda74c5c8722f3ed6111ba2263a910322ad35148215203d8a889f7c2ef6ff4cfefc8caf5a92298df6f6f6ea6d1d4cc71e2d24accaf6e0bd9a7ffaba3925e210afb128128d6636d242759860ea4a7ee7b2b5356cbb325e204f03b93138937e25d68eccf5ab9f250aff2d1de7dfcb7982456887b7af51957a4fc1d02b7bf984451e6b11de7622b96a29cf956c23ed517b53b2f04157f97ea8600a493a416f2a13743b8c999f229a55ca8bff5721f82a9f687fc26355616354b8c669256d8968a020e183225aa666fcb4346793d8f32e38fc9ada3c9b2c24b5ddaaeaa1d3b1368cfbb3a88f9780d997fd30b87bd840d31be258c56447f94b862495ee7e0d5491c6f9b25e8a41c1650787ae90cbed03f8308d25b8bff2cc91c0b5b50737fd34796d04fef221cc139b153e086899229f4f016819480ed3c56e9ec19b0994391963c749b37ca2166d5a876df309fffcf9ff2b3cf136d42310267378b1e855bba1f5aa7049f993f31f1d366595860f139d4ffefc5c7de30525b95442a5c86b0954c3da0ee31582e251c5f2410249694effaf8fa4760d95814e46dd9d4e93e6b4f8ef1d9177846958966e6c85f2252523f68ff2cfc8579626cdb910af8a0019f0d8b9a54aaa0cdc98db2573b7c7048fccb0d73fa35a875a41ab1e5af56b01503101477cc0c3a0de5dc48bcdb2dd9ce50e7a7894f6d1a1e7b401bb8f2ec7bb065ad4800189e30161f05fb8248cdde53c566042607cc0e528764bb1e8bc981f7a1c57e6298342f297eaf6fb0dcb3eab8001808cc8b782eb9a69900c26e618c00f3182dd2aca3db46a6dbcc570ece6369ea21dee7db1fd11853d45bb140025650778cfa573c1522f10882c6e5d65840d8fa346c76fd4f6ec599001a8819dd141d868858b069a4c76371d0aa0d08c8e741f0cd573254cc891b9f63be5cf7cae5683515d472506bd94cb0b6166337b31e40d64e30e668875bbe861ccb0490d5eb069973d3ed56b6c617707f83ac7605d55862a2e2d005b5cb085d3967f02426c5eb3ca2bb9dcc0485cef32c9deac0987d9b132a771839e20c9266e2a80ac7c10967a9763c797c79bf728ec94f4dbe9b0061ab01a063668ca6bf9057cd429b566fa5b846c1c427cae20b867e0ab06a0b7d0030eb1f61cb9810ac687fe5b8bad5ccde58c0972dfc2e5d82578c7465983b147541a29bf7f8d898b5360ab7e1477f03a451a08d464d8305c65a2729261afd01e67c63bae0a44229e5fd2722deca420547fc677250e4048d968d352882158b4174f4446e957c407e07e488d0b1605116be01b1020ebdb8f3be5c1f5ebeae0f22182275b5049f3209b4f46192909d1f75154685b83d8457cbd3ef1b9931fa11d01d7a75402533c4725d30d08e18bbcc9aff5391266f6f77eec4d49cfffcc139b3946f239b4419b347e45b270b165ca4de88713fd9f539404b190b4e8a9355ca23890f3f662557a6fd28bd29fdaf187cceb77d6210728e87f61aa18849f1d3aed86991a07cce1cd0868d900a32296b102f6bd8bf569476a16a904110de8ff3e58acb581cf150cb79040c8a3214efb1d2d736db15672ec78b58e131e338b1a42da7ea9ef77b9e02a44f854032f40134fe0b09", "51516a51", 0, 1447336534, 0, "18a22c811cc403a0940bac2c038a6c6fe90ea13126ff874e51e83351d5518a9a"], + ["0855b14e01916eb4f771458e479e6c921c88550f53de30231190f93e287812e270acf4cdaf02000000015248f7b57f035529770100000000075165526a53005345b1a30400000000046a006aac435ca00400000000026aace64474d0020000000000000000d9b50001000000007804af560769cc96f869159dfcc185028c52ebef2adddb6cfb7b6a45f14b05178ebb9cdb425dea5d9bfae023ea97b6359e7c449866fc57346d7e1b34b66e9efe1a4ff8773efac813d99a9210140fcfe94f36ba257570a681e36a3548bab509d3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002024aade5cfd9390213ae1f64d869b350e0bbdaa51f7dac346515adc7be9ac8cfbbca86ad704fa960796d26740eee1cd8d5f6c9f0324fa0079467e9318792d3609efde9f96e545c66a86dfa5c57f5fdcfc09f83a69a7563f234e93d1cb7b3db06715774b178c0a56febf7fdd2a3f3115e382b20365deedde11bd9c4a41f5a8b40323be528d5efc27b1864e97ea0af46753a334961c944af9538a82f0f59990e85c03140e0d829fabab4a4055b9c60de118509f04596a72f25f7abbe9bb5b35dc95340b073a0aa6b763c6fda5b618255dc9fcd9ca580fb9957a0021146ae14c251473f54d8aeb56cf7bda8191eefc3fbb5b02366fb9d24e91cb7a1f747cb1c3987a00a4032ec599f192adb762fad368634380415dc87dcef16ae283871af078a797bba3c1022be6c1e26fa91f7be89a6a0f447a6f1393de986b27b97b195d47868b41b4fa7c0325c298d9db64ec66eb6b17da7e9d76821f8b5fbf53c3d70d07c385c82e07bb47021974e59ba8590b332ff356013330a3fe7186f189c83fd9fd055f4bdb09336326031a814b401c07056e80c8f208da077dd71848093f276b782bf42e59ff10f2dc037d1abbf1947eda56bd4f01bb22a0c9c7cbbe7305c432fb350b61cacc9c611a06770615b7e3d541bc8a1f232d0efc21ed3177691e20dd25d0305575104fcc93cd71b9a46dc3235a383f10e65ca3a713799471be4a9859508868f9273bd3e63eaec171ecf4944cd7b549cebec904f5f4ecc8d9619356cdb6edbecc57dd64660a2e9ce05c0d48718a8c01b683867bb0b502da3f9faba7a7dafb14a6648a27d2b96e3976a1ccb6cd0714a9d66dda6d47ed99ecf0d6fedd7afc77d6b596522cc948af1be24feda757dd1ea64f44d83cd6c655a859f95a97ca5c039f7aeb839f6b5fa894b2077b68e904f44efd51e1045139a0924c0f722285f7bbd23f588076654bf5fc9fb664597ca1f6df0f5aa3262f953899db1faf4f7aaa71094f1d87fcc84c3b265a077575e621588434cd968f72d86c6f68487e817f4695ded82489c3d3410d12415a35ff0244e049125a8350d0e721db210ef79addfd3db251aa7168f3ead348bf4eb00130214a1016d33075f0109a69aa6313a2edd5102b8a209740c8e7b31663da8e3b2c047b56f5acebf49cebcc6b116daad469caec62126c394c3a4ae47a87c997228f5c8cf76d1c2b78522b9d47cc9048fa47a1695b6bd11ddc6a0d971bb83a31309f5083cd57f8ace0935b08c29c2981cd836273806c1233b2541142432705fa987e5281a36d349f4e3e1ca19dc8869844b55cb3b8659e8404cc6fe1c44f44eb850dc92d07e8d73ce8b5e7b7c91abdfb202b84877eee6e2404f993964c7a8d3429dcfea8333c231f2ad96097b9f8bb8402f0ebec45d1866d09ff4ce56c330c67e0ad35e03c0b0d50116945423adfc3878300abea3560919dc232d73a0908aab53e58ede23c22fd8bd15eff16c64ea1667cf09a7a58b34f127bdc321789a8a91f4309799dce09838377993cce2df3edaf19b0f63c27c491f5653b89ba3d957b98c75c2b96ffd2cc6576e8255c97dc24934450505b2a9bb7438100bb9e3a4c2a93426ee5a1af62516fa9f157dbf457004aeb938519937baeab723fe39294d96622f45d60b4928930590a15703d881c5676390778c39267081d50bda50b91c53e77aa5a912dd14b464cd4554baffdb4fa0fc66d74f1248cf219fdbb97b7f46e48016a51c5a517ba3e22450a7436fbea002bc80f1dee29f71cfdac72b603f11b9448d6046759a57e93225b790c488a15bbc7e366cf149a6ed28b4c09f69dcfae07ed9407926471aa824ab0d954ec26bcd505085a957d1a93a59074283fb3f91b4b3535987b537223696d6d7fa39ec7ab0cac6f5fa68193b1c297b31b0843c90abac6e9a5753fa8842ff13d23a569c693def1cc52162124eb989c158d21ef3a9f80e9541b914816991bf35d59d8c5b381d45d62ce79e561cefe29928a6090b707d53ab1cb7c05e2e212e696f08f24c9d8f20b1fe67f64f39bb6eec859760718571d5a3a0ac2f1e765511d344d2ed61476e06ac7130087e8df939372358604d4c11a85ced82ce24c18beffef7adefb2aa56a28b07364afe7b38fb43be39bbcbf9c638256b19f1a60ce3a568aa2198a7727995c0de56b831018662991d586f52b2964ebdc1381f6ab252e8290de1be367cc2df59520e85e0d731395fc19d7ad9091c38596ee1ce7ac653db07874866602b4e4e316a0e25e845a20b2a119a15075a4c1072aab2dd668c3bc56ea876cb0c74d00000000000000009ed1aa04000000006c67838454314adb52c96b057ccf86534bd88dbf0c2de710c923a5219db154aaf6118b22dc4c07151db518a1beb7ef2a9a927044644eec6747c232897f486ef83bfc52b6d52faebbc7c9eb1f5ad06bef5621ee16cce3aa61a4e0a09125e1113c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f9bae5cde044112c8c715ef7a05c2cab382785671c5e80d0802056d51d2c483076da53031e02214d47bd2419482b2d20017675798d81a81980ecc4fd3381356edf20abd3ff5b7026dbefefcc74791b1049f911777ecb1e753cb779ac03de8bc5bb8113e236e704861836371ddb025056f663b2a6a7adef7da35cd13c5c68dc50325edb71f85e765aa556b36e3c9c26c7daf75b74d840cbe6b1dbc79afff29ebba032b8921447d9141cfab6a51fc59a6af845d78b7f914ea19a05d05b221d46ce2810b04fcf501f55940faa5f5d4e9c2ab5490dc53c04231de96587ee7e0a34364abfccbcc5a0243d9d892d08350c44c6ad05dddac4e1e61db4b984a8ae023cef6072f02247ec0b3175ad060c5077aa108e7c0dc83aa8ce4f0e9060794235ca56b0b93be032792667b7e5235a229f0650ddcfc8fd388716347888ced185d6864229ceec4cb02034833c0971ed7680a3525165fac44c771af436a8fc12aebdf18deab5b6cccc7030059220dfe0c1a583ca72924c4a4a361334d06118a87f342e8e6d68e51014db40221bbe32c6239c5c1c9611acf868ea49be917fe8acd4f25b3f28bdd64b5dc62b1c284d5e463edd4e318a5b325e9a0398665f23415ad9026928b0fcc5f916aaed4ad9dd840abdb81b0a42ab2ba5042682ebf484415199eecb5f50a320346e3c05d8c3618ee9b3f421a806c4235ae70bdabfe9c7860a8291c08e7e54f699f5cf174289aa80f8642b49078daf123a1586e23b0a2942e72c8e6bf0fab43925734bbe78ba24da47c557ba65b5fbf80287d7fd177f93905b219d86032b41448bff3364bc97dd639754dc62f3abc95007926caa85ee50e35578b3c8eba2b447a3fc2e8a1e376870f711bf6e76b925915210ff4726b78f812ebf26bf10bdd91c510bd5445e0f6c0c9731208f53463ecd5f236e79e2525685e12343476a31b241fb147f50cbc76171b9cdab826663ccf114176853e1b3d02e33b93f72e4175ea57475fb451042af0a3beba0245d7151374c1d164bd1056aa6b4e1a204c8aaee9efa9af4d0c4b98750f53c02276405dbacdf883309cae6811f397f1ba73636b021de46bc6c4587725eccbb43bc831ffb458ac6e7ea6c2d66ae458fbb039ec8b04a90f6f10555b0b398f9c82a794f067f524cd4456dd669a21ce5702a7c8dd89be5f5526d2f84601370523d0f31ff9bfa7844a377e6c5210fc4ad10a4a343df2f0143b1406d141050b5cf1b167dbfe5fc3bc94bba9d21d8f544a952b000256013ef3be662833eb96d64e7ed15d0a87e5762de70881319fa1ed8801eeccab8852f0dbbec3f1794c7605560530516b7b024a13f9fcdd26be7762c819e837dccfc998d01cfcbb5d64fea04dabab4e568063a79196a4ca68c7826ba1c54649ea63142da44356b496a3956bfa5f35b0eccb65f34e0b569f86b590156516d86ea559a77eaaf33393e3a0f960f0a936883686684d4a019b6492f85edc59988e9e3b086fc1397fc6ddaa72c8e05497ca237983296bd317d547a14119b865f383d130449bfe295c4eb7ffc41a3f7d6bea570c577caa53fca2202405776ba4e48bae77e426a64c8c087162f4c8856b6df8e69f6bd474f74372a8e55931511926289cabbaedbdcab8863a1c05e3881477940cc3a70d652df92d82fa65e1f44125b8c494bc2fd9ec9bae400e280531dc34c34826a1c899c86662148be387950d88f81a60d6d035aaaf2ea1ca9eb0b60df344924bd119de4fc745f8ec30c99239e61bb75d984498f181d3cb4db1132444e73e04e0df5ed5d97a250f40d06715368ed93e3de3a0bbaa6ec005a2e6c35b69822fc42c1b9a8383b33d114ab4f0890b5c33c2cba464b8f37b365433592b8550138ee14c97ca1d68814d73ab5f00628cad3ef6bbf4fad446b18e505501d3aecbc200e2f1d63a22e17d9f125c61230ee8c9babd8988ea73c43bca1edc7379fcec27a096c6ad299e9b268da6b614de5e0d755c7704207e03172201f59a1bbe66046114f7bc3f35054ba1bda7ac548206d102def244d4d2a0075a51cc5e83a1c376a2f4af3272995ef0df36d48f0ff6f5025edad1ce6f9f2c815d25db68f4ed0f0351d9981d158dbfb5421b2c9e56fdedb2f5acea787d39490b7d9a82df82815535aa0907683c0a8752ef08a566561a02ebde9e1838b0e5c26516c3182d92424973f0a0a898f0e6ae48e4973e4b30f3d17076903a0e9110115a21662337657f1dc159773e65824cb488d406692b3a141673631da4370ed89ac663497a80d685faafac510dda98fc903f421629f99242c1a03d4d47fbcd41d79e8ef33fe7c7f904e0890419fcea65b83f85eecf7e5f4375c32d76ebd01280f47642d42d3014a2758252bf65de5dd5001c01e64db5c1313a90036cd0141c4aec308114e6cc1b63fc5596ca90f00afd9a3a95eb57792d06", "63005300ac53", 0, 186284734, 0, "f45bc9b82d65bea7fc4063059298248de234f319bf2aac101510f7fe4e86ecb1"], + ["030000807082c403026767561a73a497d80719f0a228d294ac2397c4a40e8d22637e2f12dfbe30e5c50300000000ffffffff29c94b094f6af8738654402245dd09a7f2305be41bb34677aca4b9fc5670c57a020000000363656a37dd916101e373e5040000000004006a526a0000000023eec16a01d9ba51030000000000000000000000009abf96056b83f198926f2a80778bc2e81161ccf1c797a08444725735dd7cd178a9e77ecf6979681323e8664e4f57eff45b7979e271d797728b82988a6c7d108d6ab8da63f30b59c8bc8c584eea1da0a4e6ed2d04f6dc89b2a2a63476c269912100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000653d6a614ca327a4fb9c13d94741061651fb1d0d30a4afade460484e641d417175c6c0834c7c9f56e4c3b0c008ef31bbc1b9c42b88b2c4ced5989482adc0e359a276cf0961142f05ce3c1cb30a29e3117b3f87d4b6e4a4c0cb52ce6775123909d50c00c85b1a81ff806673e536576b23d3a38cf45ad66931110e319c7169e12b030e6f0dd7289ac9ef7b1158ee2199e24bad05ee86d28764727dd1698898db19dd03302f6d34c213ce1c4727f802ca4af8bee9564d7964558320580dbe348e6858d10a0921d586ecd1aeb2da30c0b65e82f94dce89d8dcd66a0c989e845d2a7eae8f76da51416845d4b7304379e6da8be62d0cd9833a8ed14b5b4d8e64b8e567a65fd40202b7172d58d1baa57fba806da1a097f2b1cb4a3e479678e196feb2d497a059570313c018041adb94024e4a6a7c1658011782707b88827b9161756ecb17093b5ea7022b34bffa6e3df15c5029a66635a066b21b6e7a6b2926c1548fc6ddd118a98963032fe0623c0a3b28c4d3783b13b4aca7b86227c53f45a05906cdc512c27b1f60e90324cb77604251ccb3e7a02f4f65f391d3462f3acfac83e34e404a3bdc5373ecb98825ecc652ee90cff7fd4dcfad6ada2554ba6024914f6ace2818c14fa232359624f8a346847a0e54cc4c100c41588dbab4bd0c7e83efad40d016c3c4b67b5eac0d376aa90aa48f1c1066cfc26b605daf6794017d8e1137df1cd137b0527536ac37e094e1bd883aaa76667a5deaa51568c9f242621f40540fbc7ca62f3050c0e6f92273f1557f6eded80e7e3175a517cfcc1f459a7eb32ca33cc617a1389603cbe55c0282783fbfe56d052d0880be9d0d09f241e826100344a3cac611fbc4beeee94dc90185f6adeb10a48597705380bf0dff28d3174f0f9d0b26b8d7b2759bdb5c552fc975fd5150467fbb3ac042eaa3fa58c0d9fffe0ed716ba713c6f2ec02c4ab5c7bda7c18cc6064480655cabd160124dad21236640267b8f7b5c68d9b1386ca669d5e82a06dc82492ef31c8111cf42e6a1024a307312f8a8438a696aed7a890a77b78755778ed06d7801f1b8d1fd78134965aa8b06bc8b3d6437799471bdd1197f33c09095dc0fb8e5c89777367e2a48da15c0ccf8fe78c81c20859cc306e6b638b9fc4366ccad19217e9889e08fed2e1c3bf4dd68ae2567c76a1b222e7cc2e1473676d6f892a70393e0d4576ff35815bc08222da8d8e18bd576a1026ac7835e003241e4e05a5524731edca0436bd9956db3348f43e84442bda0ac80b541451afe19d3e69782d05254df072cb7b501fde5b11b27c182a1a0c927c05c3b1f02cb9b87a0e7343daa1cc48044b0210edb6bcacf66ae28e9e2668a673e28c3e0ef037bdce4c4e2f58d5ddb504e74ab714746535e90004a0c535598d3de277e68adfa3988db054e1aaa77daf25278ba91bab5500df84b10925aa953921ef8737a0753ca4510240a1695d61d42fff9fd3113992f5b92fe41ec1ae40ef9a78416816b0d3fc055e95f62be6f37f168e24216d3ada002a787808f269ce59d02d23db346023e210a9e9e09f0e9f74a2f06321c883b9f016167cfea2ea7b303df9d637e89320480a86a47a0fca88cdf7ff6dcea56836fe044738e8dd6a6c364dbe1e4cdff047ff113dab8d9a92b2e98915d10839b70f2b3983caba80131ecfd8debfb9bb9fe6990b00cfc528a3c51391d7fab2e1e6e991a168bd3439a077bf1aa9542c436dd6e38028357013ea4f7654dac871a39c50bb926e673b87fa98969a33eb54362cf208852bc9e1e070ce95b61ae9d850b9fcec92b9cd49bda2ec5d8367a16c68dd7f71464470f312986c58dfce793bdd22bf59f987a3d6e06e868bfe16937fecdf7c1c129c93f89c85074e2503f7ee77d2e772f79ae2d3e18cc21946f113bbd30405c982422d978f88651c1fc7eca3b0cd269f2f8888b60d58b7c8aae563270d905eb7b07986bd049ff6331c09220aea5196d2a041d98c6e1fbe18ed2c5bf204ff2972453cfc368d76bac58d2c88464a01a821d1a3720c58f049724582974e42b5acd0d08487bbd6736147b96e2bc80f115fc72d22adb107068b6157ac39c7441d090154634ec96a03e92f4ad2177909836b2169258624889740bddec25b6c559af8b4c7d3907aea1eb886e56b362c777c9d0b0808efafe4089fdc322204a4b597e1ab74e96a2fde05b806b8af470c2f2f47cad8e7931d3831876a6b43ec37bfcfac3d7ee66e01adce32c80a19b6ee978eaf167f0082e0abcc039160259932ee780128bdc2b8b154a9f3ae75fd294204e2693ac7855a8c85aa940846b3f037caa5eaad7a97f0f66555330508edd0b5a2e3461245993f071b9387afb96021150a4300f69ff80f6bb1a66584a2aede8a4aacf6a6276c13b5c014df147eafe5fb57d16f1e107a8a5fa4383eba3eabb000b590f", "65535100ac6551", 1, 713730048, 1537743641, "d10ee0dafa0b2291a1c0032fd9f7c355de9bd92e366306f3f1fc629f554d0a2e"], + ["030000807082c403045b3215536956388db305212714ab011d732bdbce50d0a319e8941641703441cd030000000551ac52ac632260acafe4bb642fb7f140370675b6a8fda871091e48b7b58d5642c3c0701080c5cead3100000000096a636aac6a5363516affffffff0a0907b2cfd762f359320dabf1c2adde8bd3c7339dd5c0f2b8cc8cab2a5fac710300000005516a526a6afffffffff8a6edca1d478009e676c38eda706ac094c20d1f1706af70edd38c5fec86d32a020000000700ac65ac535263ffffffff040f3e3700000000000265ac04a18100000000000851526553526a63ac918a3f01000000000551ac63ac6aa7028e000000000002515175195d060000000002eb508e0200000000000000000000000095ed14c2cdeaf1c5acb0d85a4b7cd52c90916d843501f40c2341f9614d30d626ef809931b673a5177b6222035888690f50b91c34c268e03f8f06241422286023b665ee5b6c4122c4e01b624db723e32d667a247378513fbedbe7be26de4ffabd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eec1249239777d30af06a7ffe8582595980ef922b91a74b1c1cc4276a7a08f6fd0eb9a495ed995806e60a13507892a27f9df47428563cb9354cdd2da4db09f43b4ddb8ed5990403caf9cc7ff2e52a11507f667023b6ed0914607410285f340aabde7ccb06fa285fdb60686cd65e1fa0c11f349f9434ee48da11b6cf5d6276f220212668a150c6028c814a3dc4ef9831b79fb0237904d1cf95aa65638714118b0990305b90e24bd758382ce347c5ee9ed194978f9ca2cb1553fb769b7787d956cbedb0b026a7e43b0b75ec54c3768617708211d9dcef953ef31821b2ec2e59a3cbf8b224eba0ae02531aebec4dab2e8b005e57c633cb6b9062357c6ed1549e3ad46c2a402235f3d804255063ae7be97b397105ca435bb1e9a72333200b1c3b5039fd786f10316e78c1e07a8e12809869474b63642fa6cdfd3a34fe04e13daa74fcaade72442022471db879e613b1b9c5c152e915b2e068a79565aae0fffcf2c29d25489f5773a030a4579170d3f63db29521d3422804c112cad8ff9dfe12e811149e70961d60d8f020c0346f57b0e3cfd2bc419f915b1ecbcf7b949ea17a9b98d30bb0959671d31aaaef764895a27fbac08f0dd98e22b63e25c2c241f8d61b4fb8b4b6459fb686963c2114135df33f7960bcaeceba017a2708e3e3d25c0f6a31c548a58423179c30c9276194942728faab30efaf9e7729f0998a2a39f2721d2073b2ca68286868c75e79d6d1833a03615c7c8d63f7503396cb9e06932f3d3cb296690107c7efa64702299fa7b8e194439acde0ef26090a8933dc27eb6a99d88651545cd77432001ea12aee9e4fc68f2f3d14480079970389ed70952b25531b32f0d8a75358e4b7c9bf8e5d46f23b38ebb0fd49d31dd9e7c1da8e90e99332a54ce8bafe62e5013d07dc1a6fb49c31d2ce4c1d24d79069079d87e09dfea07bdf2fa6fd85dfa2d18a9cc17a864f3690c13ee0ff5fe9ddd11b198d6f3157b4e2852f81d801738eff428f08eeb407457c399afd59f433fc7c22564c9acbe01a862615a596ebf1ab4271eedf3e5c0b97a72dad0affb3b6f665d32ef147fd76d6c445eaab90937e7ba299acaed364626a1b37cbc7727ecee9c4586fdbcd5f1550c8498ca4565db92eaa361907171d683a4c6d6a27d1ac2bb10a4dfb5d63eba61c28fc8f8deb2b0d1795e0116af313dbca0fd1e85c194651c1576f4e6cbf1d7bf576c36844c76d1300b4ebd45dcf4c59a18ea72e1f7cd456b12b86cdfbe165d1b07ffd087a97fca614a965e202d89d113d12780351c29679d2f2db33fa1ca39524a541a71bd15c5834fdc6f16e546ddf4a8f4e95de56c5132b27b7c12716db0bea7f9a3679fabc180df4f12c39cee023be1a8fb345ee33fb8ba498d3fdd212586d16320b3f0d237ac04069287162c177eec98f9f120f44ecded074b7e7f4b2a8375ad31462205bf77ed41ca003ef3aaabdd5f5e508b7e5d48b4edd985416742db5efa35fe02363ba62841b1bfb31a79e35be8dd8e6f7ece8240fcfee6accd97b03caee02706081bb5dd205911c6e44ef807e91c3fe5d4a36f8f6fd0314c7fe71dd1c564e54cbe1e29082b450d798bb37171ae90f014fdc5d178901a9ed9a2f0e24b48b42d716af762fe855b0add24aaacd1f7dc723ca16a1c5281e5dc39c68380e959b6a3a447a17a5d0dc4ae8c7852b4f032ab9ee94571d7b71dc361dbd1a93987e03388d5cdce4875f333d4ea62fe5143f7d58707faaa6e2edda9d897eb75e326151a6c35dfbf686633641186c2c0a8ee947ac6d3e118ba10033cb4020354d1d0196ab7a9f8640d70f0ad6e8f5e886a144bb90734a68d96dd24cc1d3663fb3b3fc5485cde6f4a1737f7bb569952c73b0b1a4c6915b592b5f46f13662b15f0fe2d41f29056cb58ac66d69ead34d561a80550ad8a8908873613cedfbcf01b79f1483180ac12ed973dc2efd3276bfc1b63b42b37e09a3a9055c39f2e6b6fcd677a79a72d9c1fa46f5bb73d13b0253aef34371d04a5cb1cbac05bb543ba22d038082a2abd30572ded65d1ad79f1e0a536132bbb62e19855493791a027236210ae1ec791de1e635e1a8e09e7fcd67465ec1c0b994a4b37f21b3bec07ad97b1da412cd3330f65d59d2b453f38801d38c0fe0f4aeca1bbdae3a6bfea0eeddf081ce57b16302dab6cbae3040243ac8afbec78a31296adc6d86314947cd5f0f0b3205c3d3d10eedc32b51a68a4688bc61a2cf5a5086790edc044b641b3eccdb0d858f243f07f82d0a2a01a35367e58763c3f9dce37005f02d8bf72b167311f68133c3ad65e04000000000000000000000000169f91c62d622447256fbd9d47f927ac1d296934621feefcb613dc8732f3298ebc29cdf8e486f5fd1d86c4292be0e98329f3123a053cb983dcd5133d1d32e4dc7c73f2df5d373ca34d580b35ab0e9fc0283c3f59c325a2932d91eb5390970ce800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c340386fb085224742c22e6ba4500da7e6e12c04eebc1c5af1ad199efeaef9f4b496f04e47686a28554370183116fe4fc121af0f135010c377e64c1b9c9c2cb9cfb3ac78f93f2456b76b2375ba2a1ae76a77cbbaee088f4534638bba55879798246749d48b42ed2604c56fdd150acf6cafe93b5a8974e9ce2bf5e106bc84c80503092747810c58dbcc02e073bf49910b26dffeb95575e09051db1286612281677f0224ec63354ffcfd9a58f76334066584517ca2790d2077d2376e4a36d5fb3485a40b04b8384145a6bf6772e3c1a85417b364838b66523876b35fb70b35410fa72a403a0247e157100b491630f1eb09da78c4d71ed7c8da8fa77a539df3bba0a2b5e10222505c98258e12a0ce03a8f7b1867092827cf0ad66e8bc57857eac05a939b96b03152f63efbb47d50eb3012f01e273f80f9ad7dffd6668a0fa06d9acde07f1ffa2022ecfe43429a5de2103c699de2c2033ff66599c741a55f535b6af13b996d8c15502291130c5c9bb028a5b4cb6efed144b927eb4e5594af70247811399599db072020229895264a89001f7c506373c30dad28c0c2017d50443cf59e4daf362264aeaad9b25c2e084532a30977db54a3f7705d52db7af305785987189719fe80bbfa694df6b9f51c8946d4ebfbc042b532c3b325278f55aca310144fd484e12711e206f2aeab81e6246818eeb66e8481e242de2f88c77042a7d986384df78b894aeb976796e3b2cfce3c4484640e322b712294cec458c45f9cfa1f66d973e6e4a7c3f72adbd4d7046ca60494459005945e668db1ab725d0d8eec0598f745fd709fc8924174c899889ee669af8fc60766a5cc6d1374baa93b3234fa1902770a60a08172ec643f5c0780a9e1580413109aa6518da62a3ddac7fa7334e8d53cea3cbdd53b41dcb74f939a894d8f848e189ff1fef7645fdb6cb86e18389dd7bcca5978d9512c9157d1c22a099c48ea44bda8e74c5bfcf0d82e5d6000832b530157f92ec345a1289362dd1052a9b0155319349c70bfb93092e0787e3d88add3f8bc26c168fc8a4cbd84e3c2d200ce7979b6e7244ac7bfc18071e41c6f6eab2a347a669e5a01af8addf8340774a671c9d08442b20ba7461412cf2814c45f972a21b463548c349c16bcaf3ea0a574804c56e5e3be3cc9882502e36574138f51582c3f0b27c3d098f8c21163774e40d9ae90a0c0f2fa8083ab4a66d1c6b76a539a4cf11138c143c633d6a514eb4b41d16936ce5684adbe8de9e93b988254084267f3b0b2dec6d1c79baf3b3fd542e7a7f432d0dca3c33c915be5ac491b48393ffdabbbf218e5440286104d63ac9d45f35bcc89f64524e21ebbe8d9d2061962e653b457c4548b156e8ded9e683bc80b84eea748f30b10f21b69019d1164fb9556e615ab7afc498c9211093c5470e0d5b4d2a86294127857615b5de5eb6e63999fca8b66fbe04c5325603be6854c7bf7616a4c66e02df5e99996c6990ce6d6c8e8bcaa32384390adb05613abb4890d05617f1b363ec7f86b321cb1c0166e012afe5a217d8604a9b0771debbd81ce8ada02478a9303b7959c96facb1bba5bb20601275beb0207dcaf71d0e3a904616d9f6f90796b9e44daefa04439fa1b487a5d5d78d762bdf6ee0255661fbf83089cd596dc337efad8249ff33ef40471482c16453f0116b72e3fd66260d4a909d89733d2f9cef2ac396d9fbbf4a4e54192b243280968ac5b74cd651f6cfc87d9ec7ba01582275f5ce403916f00f666151c0d4c82c1729099680f7f6df42444e3a668c15152862730c605a1580ab78ca83e2502540971330df5a52bbe3648ff03eaed470586ba2aa701444b22e6cf7c965dbb039fc6ef84e9feb17b2ac90e3eade534efd8f26864b6cbc99b5ce0819947e3465e5c7c33e3873b71fa7324e5df0e099bf43f9f3b9ad68119332403304cc7a09eb029e567f597dd435dc200f06a69b2ce5c92d68aded78940e8827c3e261dc63809470a2d5720e3be1bdb05dbf45668c60cef338b8f79c210fe68cd56cc1eae71a93e26c3f3f521fcec62944065b3a5a18fbf3a434169e04ec3f9c93dce5a1b5dd952760dc5030d83f39bb7f44ca32638e7cd41745a0b5af52a3512e0b426b484f1930b04ca11a38f5702e02f5022b5dbf5ee10716650ea1aa888587893069a549e1780b3cdd03d879842c9fc53ae8ae3fc3897ed2377334efca187b294bed17d4a3472eba9ecd42d5013f8977cda017933c151853fe809471b9fcc17d7f00613adb70d855c597fd6c35b5fd5cf824d7f38abfe44a7d5b446cbaa33e341c7a5b975258df6f14a63a786bd691fc58373502a3d3b94644521226a81a235adc6461d15250ff38e3eb2a12417a41e4cbef55743f43dcf3ebd4fcb1b89b96049d24b7e6b8e0f02abc1c4c6f3b6c873b095ee0162e125d09ddfa4452b3c809", "ac6a51630051", 0, 1153267492, 1537743641, "16efb957df372ac689541408337615b4337d6e1fa5b532c3d574bf40e5e2fcf9"], + ["030000807082c40302cad97cdf0de4519239ab2f319e2dfde0f8aeddda070fe034a70a025e5d1c223a010000000652ac5263530029f73362df30d54e807cc97c2d6e9e0bc1586890b94cbf6fb734ab2d6e3e84c71895562c0000000004000052523aa455d20268c50e020000000000a2330b0300000000070052005165536530d9b54a944771be010000000000000000d06cdf0300000000ea13198ca341ca75c98019a114b68606abc15a71192357c93ba6250a7189b0020a631fb348dade40b628152d4931023ec9172f6811b15b6ef91f651bc6f490dd4b0af690988689326be1ede4fac9bf98369aca8ec68ec9323e76d57e2db98997000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e3cd791e7891379396a96d8e16121b3fcf925d7a99d60a421570749f1e67c0a48229f1c68e4aa47789d381804a2a1e79aa0971332c888b1dbf689b51f4e7e14e5e2ada5edfb12fca78c6db08bbd19956ef247e650cae1c9a926d076b16bf682447859c4d398d69267496e36e768fdadd99c429a358a2f6584faa22f189b375d022e82dd813e0baddccf91d5843136ba598cf8fd896616b870ac2bcb5b73ba2777032725b3a2e207687afc6cda1a10b45394c70c64ef6871bed2edcd2828df8b28870b006c51e24c3882efd4097c245867fb6dc99b53525456a2783d8e29bffd9193ec2aff6b0fa0b61aa58f545f194728798a70c583121a9aafaf34083ee0828ad8a703130143176a8ba638435c59c1803bad3869519e930196f8837b353ee403c2a835032af310ff99e388eda3c369eabb0c7441783f9164d6d282aef6f4b99dba9f64b5031a62e32b782b7a173ff8abfc5bf997cd532af61fa3668e107b850e5ce382958d0318403df29ebe414b90b694b788a0e25e876f56d35a2f4086135706751ef9bf0c030b366385a895d9e6c49c504e48ba875fafc22b948d3988185b23486b7678a16bca4d3e047dc0d0bf06867c68d73e21087e693fe62d07b489144ed3ae39c4fffc65bc62c147acfcefce831348ae63c153530498bb54f9455e5546f88766b18d7302a1c944e18a1521323d79d490737893bbbb5bed727f431ddac8e2ffdb90aeaa03abc8620e2ddf8cd495dac7be0fc2f50ce501cfb12639193764e0f0e005e9d995e4320c6ba713670ca91eec1da5800e8eac613be0f281db058360eff6b66f5328c17f611abb1a85612b7b44171c4a6575f1a8a3e0244e1c1ec734f238aa3481d6ae6a801a84d0206fb29bfa3c947eb967219d59ca860cddd407b39c813e30d25560f63440ff6c4cb2cdf8aac9e59d02f755cc5348aa05ca0a0a1187810803e29dd30e32444788072df9441b9d07c893eab97be97641f95925dc1ec6b849576ffd6b804e6996d0d1d4622aa68ae18a0673d811c6a1c2460a10321244b4215dd0b633a869929ef3092f0c16039f5b8828d0dfb64991f90f94cbd78da9aab41d89f205200222801702fc44185770b4f34ea1ef48bb3fbb0a8dc6ee1bd5607551b7a13bb1c84dd31758411711de7edeaafd3a072975bbe016fde851ad444a2ce46e4f292402e6f0fd006122450767dca454f3c65471e69a15d51486f53a9b2e1dd200dd0eb830ec030d122f11a4deca3d7fc084921f1a5c4ef094683f297a2ac4be18e6567009384ab27febbcd16e688920964defe688bee5b77143a4ef483e72aa435e78338ea1cae09ca3a19d2bcfd5ed87474d776f02ab268ede322fa938e66f4ffabd87d6a809e6f361e7ded21d4b22ac918a32a84718059e054700f226d4af77e0eec54a3defb5549145f7546a8c167d5bfbc05e351456dee8c7eee7c49c6f10ac570c61dbf961014eb1607349b0a773a05ecb5a0b1eb7507feffb12bd8a31fe0fe8b00a21c5a6af43a2b655eaf5073467eaa48f2a875eff0a9ffacf7f32e1bcb2bd4cc3abcc14bae7796022e0b848bfcead8d04cc48d96b63b608de65a274d885bd99f50b157e6730fe06463393c5c10d363eccb6e2874b068224a21a662e477fd9e221454d960816d97987058a28282f3b00c49575af918916c20a8edff01b6f89ccf079c9211905b0f4be243e31e32a209024a04e5b185f3e545ff2032de8608d842a0333199e470666b440a40015834908147f9099b5654ed72e3f1c46766bf7c8c7babc512b6fee9fe7afee551f79f480acc30da7ee8305583ef1c73350aa9f69be4333b751c5c923fe22bce0b1623a15ea4957861712e352ece30d695460050017c11383e85071610abe2849b969bfa087c321e9594b1c811878a19bea93dd8a6a96873c194dce12e6da733012d997795b130f64204c2a522cae1e526b198c5ad22767c09f01e7da74547f6cc852191010e884bef2e2c40cb55c18f119fc8fb11bc959a5301a2dbb361cd15c47ac834b0c93363a54bb474c6f7b4e17d14e693125b2aad8d04f108bb0b450ca4f96e0e39c1dba582dbac3c186a0e21cbc6355fcf9842648bc2538ad0da7cdebb0a9c6bb3e6078fedcf39d690c50c0283277763562f2a5bd91e6f7c5db8ab503a666ede1b16574af125b42b0e34a5069a320d5e0fabb3d6e4a69162a4d7d81167ae0774491723bc3926a86510f112acccfef3c262bf9655f25c5102c90132f39590a1c2706da1c310a4671b9cb303d4f3608a47498ab42d646c8561fc3aa152d52c7c6647926c063f868bd973a91a5e6917aede0c94d1dedfb227ee09b409c2e08f3a2d02e9d974a9374241c3f783df5666b39dd120501710c25811986dfdb35945342585114b93ada97a5726739ae6394e61345426a314ab988f776dd33e0d35c08", "516a", 1, -218171987, 0, "d965defdab1c59592d14d888b9d558ad1d667fb6b53b5befed361ea1648c6649"], + ["030000807082c40302edb553e2013468202ac250aaf895430c3b033c9c4ac129b111855f8f12250cac03000000066a6365636552fffffffff48321b26532d2184eec336ddb8a66206557ecdef983555beeeb8e82f4ea138e0300000002515261e640a903ec7a3705000000000553ac51ac53b648f9020000000005535265acacf863a10400000000000000000000000000020000000000000000ec5c1a050000000064a3d291d37b955fe8c175362007a35b0b4dd1d655c47b1d65392647fedf6f09095efc9416d7162c49e80cb87ea06339170063318a869d6c96ca33c75264fc453aab813e0458cf1fa0bd0e7d49114cbaf59b0282026f328b4c06c0c1efbdd81b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000644ac94e0dbc99e90236088282b1a6de4962f0d8e8dfd6679f956a72a392fc84e9ff5d9e24df52dc94c4357174bea34317aef96ec0ff442b90a5c5e683576920db3161f398d15c9517c390b709eaac9fd9523ec7ad0874a40c08457d8eb6daff312862cbd0d1e2496f39ed795976c2cb9e485de30804d31616c6fc8c4249d35f031796ec8a1a0542cc56b578f3c87fabffd632fed2aadfe8b7f894944aef776669031e773644f54c3066505735789adae1e559aa17acaaee279bfb1398ecb19f01690b01cf104c0848104c8d11b94c0f36eecd1609c84526d7d91175a40e3477b323aaee3a87721cb599d8e2ead5e098930004328f5ca487a69e6317aefaf3127dfe3a0203febe51f8ed2c0e5ad373539bf9d863246e3c68c67f78d7629fec8532f973a8032cf17ee649ee8002f5e980be8c282f0f0a161f45604c5a40f16c59405bd748fd0227f3b8f10ebc1e17a6deebc4bf3dcbd6debfc33b02e02da0491b1e66549044940324a51753df261842aed311eabafb6d815084dfc2b4c0d97c0f69bf76722a0b59032dec6ba8a57db136a91c4fec5ee22d8a4ddb914ad4a09be62a017353d866124b73926dc0bcff0165ac3dcf9b67ee76183c305595f00bae59a99bcd35a8997d1aa7b3d80797bd760e2ac9fb1127002068b9ee5a749f6a2ed13de9294855f7f71d81691e509a12dd80df21b3a6009a67653fe8132db0697a85cb7bedb97524f4d059abcc0b7c3352c8f31eef51be800fa2477581558696dc0eb6bc7294f224a8ee5f382c5cdcb5f273bd3a68c906469cbfb8f499aa08d5a202f492ad99ac0d0faffc9583747c0b237eab09dff58e543d7d56cf1ee668f3528c13ea2704c9486dabdf48fecf68a5760f0dadd86cbfcc8bbea291c19533f9918ed201b5c6dbc0ec8317c8a2059cd0bcded8eeda29373e68b52dac19831b4cd0fab14efef0a2f252bd94c959358d3129f7fb6858dde9a3e8f7a36577b3f05a87958c647688f518917e06354765bcf3d6289d0170697788300395c4bb4931af13beffed86d3315cb160df2c73a5a94cfee8dce157afdc085ed867044cc223c8247a0668c8362aebe0694464b3e13912ffe5938e1c21a5d6cb10dd4afe6422dc854842c4ac596497d67befec9d17a1759b5fe1e12195d5c920217627d75820ec5dc9d324a95e6c052170a54be45b5c171d3d15e49c4f5e83c51d71af4ed42462d1f721156a1156ca3272dd6c5172cd1d4f3cb9e8cfffaf2609af201ef21cf9d021f5253e6fcfe2997c67ae22a877423e3b73ed71892dc7155a0e8950263520d7f3ff4c54bf9c8fefd819ebc422c8d80192f6941c54c69999ba5e523ce6a75d75e41d50c21ddeffe022c042b6ef996368b906eb48626c1f728154b3de10b395ab6d55a1040e4c4e8295491418c39d669bb327318b16927c8055edede366335e5f17fb8556773177fffac8c59185cbcaaa3b7f6ba485d9b6dab99a42e885726fdffa294c8b0108709edc0389116bd590ab61a0f7360e77451e50da0fdad6161f905a987262a4ac0a12f0d6b98a8dfb0baafd5a44252ade19e1affeccbbb38f4cffc37974e7cd0c7d10784eea65a2af30c1f11f2d2ad8fc5a9ca8388336de12b7fac7b9b3de35974f8514e95d7188c0ebd9c140f277dce8202928dcbf8139185e48e62bfcbf8cb072ffddd49a1a59910f8c0a33d2654b87714dba9eb36f2e64bd37fc9f60bf226ca551a765f2ebf351b70c5cde24b221f0cf1f09a83e807dbdc95ccd0449f651f661ecd40f5c69a3787b45411233f1b5846806c578b3454f4cc53c5c0e49bcd8b021c4d5a91b79d7f0e22da48adfa196875b39f84a2f7182c382e846c637c54e6e0651863af0e378e27a5f5cdc6abcf811518ff9219e4959c143a42ec3897b27438a719f65541addba3916d35db01e114be753da33314b67875141a6f4c03b532228fea54b471c46f9a1900ce5a7eebf7287fd317de66a6a7590e84adea46abf5922a1fa27e5c1e7882b5696dbb457caabf0009bddbd6d6fadbe3d3a0469357b94028d1718420d589257bc830011749fc7bf58524da5c45b2d8c96097aa4afbb2da8c488c1543d8fa91a65decef7b6f01a122142a777b3db861409d8ec4f7c06190c40b3488b302bf529078dbf11193de163f7f1622a695666c10b1ea31aa3044c7e99c4d492d372f9a055d71b03a4f0cffd436ecb9482d3f0c6eae1d89fbbd218ad328d674d6bad52c2772217e3b57921e7523f27b14a995001ecb679b869e18b794581e6f0ace78a3be43bf513d024d54f404e3a47e5c698270300000000000000000000000090ae2254c998154a75ca2a23d0906bd51f1a10842311c6731552572763d0e678f3b0c77901de98c1aca2ba8331a36d7e29081b1d6db0130f013149e1f49a70bed56037adbc8fbf8638b8bf2a84c0e8f84ff1e3c93819e17507f00259d9641805000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003555f9517269fbb3611f2beee1f1f5b94a4242737a363ea116bbca0e46d323d2045c4af26d37923dd6a80a18b1f76f072477bed5d8a77f06b2652f9e743b07b0b2242390729fb0874714cb709d3a692139786c83118f321b5929b245666e0863a102979d581a5c5e8ef5838694c4db0c70735ff575f3dc81eaad130acd06564f02115753810b310b7b1725e4ca0519801d64d7119a8a6b12a1cc79077d1e5aa122031d3eac246bf0c5fd31996dd7b6d4a3a65ed7c19f54abab1865e4fa56508e8f370b021e17cfea34226542ffb24f46dfcad6c3964d5adcec1172f67f418429261bd3927b826a522a3c52fc6255a76321f98f1947d60ae38a059f5463a1a19f5d362e0221d3988dd326c0522eb116ea5340ad186de4290c544bcccc7138d1f78830934603007ae3000aab4f4a4d533783f265b94dd6202d8e561f23a02f3cbc946e8925ef0306ab4f73329e120e7851829805a648b9eb4c976c932954e3dae24792c0f767e503170db9d25faf703de6a29d8e17c0f09c54920888f040e6daced91b4ba4757745032c3d6c0458221b0639a6ba52b0f0b799154ae187950c04e6edf12920c09d697b62e719dfe0d6711b497ca031211bdae61e0f1ca53a4f1d15487a63314808b93175fd9a4d985927bb433130473b77530ee8ff1ae41bbc04f0361d85ffc6eeae76f7ecda3267ce16d7a4bc9a8cc42f03ef80b962ac606bac04d6a018dcf1d3e5ae640dedef9a5a3070c4020dda229839e378a810880f9c054d7346e6b677f9cb1a47fe929875bc5187d8c6181c86620bb07cd25e05d8de6df7088871b739cec58f7b266fdebe950dfc4dc7c7417efaa2c3f67be978d70fe1d9b862a8b97344c6cd2a7661be9dd9e27cb129cbbf7efca0bafe06ebaca20d46b5846db0bbe4b351985a4e3db8099aad20256e7491a381f95a49379d5b1805782e64c68aa48d04a58853b9e71e09f17e1c2dd0e6a7e4840bacf5b32e75da599f966fb8627a39fd49a2aeb28bd61a7c6a855e692b8c273ad120b03b9bd7b9b2faff2edba424eaae8d3e2537fa38b6ced6ec67fbef6d23f9f16547a3680b4d1b55379e52f33b534745dcaf26bfdac36d6768592e874c6a31684bb5b946018e3da52b91f928bd2927aeb203cdd6d6571dbd7ee3ce03b1f16bad3bdf16e77e9c8a47e4689c2fe3b8bfcab15975757a58d2395a17d8a2bf0c56b56b769d980a1fdee9c089bb8a856cb69395e9584087ad3264e87d1273f922230f0215579895c5870ec7fdd77b0037609afc90680338d99218739e9bcc408d63bd14271bad344a5e1d75316208fbd819f132f6eb7068a2840b68857c87b83471b2ce8c5735ce0dcc60e55035d5d3766dd651a07addb92a93434c6cb60b5bdee383f9f280f4f22f7a972beca3cae11d148a5668190144d814dbacde6f90d8d73ce2aca905eca71973215af04ce061913154f38d00bd9060f2ad02bebb197c47a0ebf25450e150df12479eabaf579d2b21ca1003d49465d1cd340438749a455835ff45b066cf8a7cae097bda97efae9b9ada06f9699296695b9b612f88fe9e91bfddbbe64b94553eb2bac079c6eaec064f8e81f230097984f0522ef9c16e8c4f61525af4f7f9453fa1457987b822b2a65d7ba4f618cad1297c2b7ecfcccfcdeb22b696fe8653dbf797c8907fc0c8298b8273461559956b4c1069d329066b98344b0ab42bd51687b5ee331068758581c9d1b1e5534b49fd68776688d62a7eaf53cdbcac5ade703cb7e4bf737e46f0f3c29bddb3c0ac9165c3d58ac5a7198b87c5721c07c040f4b3d3576da0ae18e1c2bead14a053cf5e21e699b18eed45509ac0dddf1e90810a6c8a68a0bfee5eae8ef7e7a49adad8a60fc6e848e8673d0b58b798f8a5d2c24fd7bae4f7a1863d292d15780407f80dd22a2347654479ae83727af9d46e7be1e717d0dc321dd2cf7c99c16847ef239f9776482e69a7bb8b52dd22e243122cd7cb94f72984d9eec0ac6e12504f51ac06b2bb933022d3bcd3d3433f3201b809c8008bf0d533b012e717d7a82dadd591ee1c5528241d28819cef4cd497d87e5a78195bdf9a5f15d45d8a5220fef8eccb498c1e8fe8f5eb925dc3524d6054a4a7ff118ea0743ab344a1d62d4455d67a6e05a100b3eb052c4719b078d77a78877a54399c10d1b6c23f5a22f46da12f82e6a49ede77415a75e804cc6d8dab78b0d7558d02731163a99a791be7628daec2936fd6f2617da25ee81d67f0c3fc6af63bef534749387bea18276dc3878cf028068145448438662026d52459881da86879373bae48702c2c7f257453f9455dfc4c3f2b93cc32cec77492dcb9a755ef9dccfc138d7dfbdd7720274d139b492c30412b37b661416d684d121042e016b40e1ffa7abc2c4b30e463f636423049f32ec2e24030d5f69610ffe90a28a8cd33679f09", "53", 0, 721362411, 0, "f1c8e9c31afe8b76df23cfaa622ca5047c70daa7151db1ca5f4b7ba173959f21"], + ["2eefed0b03836a2ea8838c901f0c319e0d0241b34ffc5525dfa023d5309014c3291b6e43070000000000ffffffff8ffe34001d582ea0ec5bb4579cc2c09adf7ee6568d64cf4bfcca6c7c64a1d85c0300000008636a5365ac6a6a531a18b974cc64a671c94fecd4d15a3442353b9251ca7199a135d5254d0d78e984f4f27f7f000000000653005165006aafff78d8043d4f6503000000000600005151005182efb0050000000003650065c97ce00100000000020000fc9301010000000002515200000000017882270100000000000000000000000003010fdbcded18dbff54f5fb7ff317c40c3c09436831fd6ad46c035a34d288f910b32c307c84edd346052ee9bafc2368e723b00dce6151384521ec659251023b42e4fa20f5ada1ad4fecde4494515a810819bdd8f59c5143fb06d7093136c31300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c01d93654c32186c21b5f0a87c93c263bbc958132e75b4ab630761fe0dda7b2049495c29bb85a006f166c7dba39bd69ad1d55cf9021a0f1a3b3eaeb4f088c0cd8d88bfa6488838c4dab662c7ba557838da5e74fc6c00bed111b066e2c0a8e6a7b6be4ef34084dc196930c21576d1763d64d194a9a61ba50b173a98e961d3144f020fab306b03b7039fa6630021018f1c0c7a07eca76698481477cdd9b8a772cf170229bc9e7da6f4ea8132b3bdaaee18563a2ad13c36f6bc6c1bb30db042bc27ed500b08178f20d82ee86bb55acbffa1a1212e23666fca870bf56ed08b5cf0b0fdb7428f0e06be0bf7fa3ec8209704a9dbef269fc5972ea4e38a7207cf8059a770c88c02182ccc2b6c10d3a341b00db37d36ae3c38e8cfe6ac56ce2ebfb37fffff5aaa1c030e41e298bc34295b0fa547eb907ecd460bb1836062cc455fe76dd9efc7ef550303069bfdddb8625ca0034a2cd26400dad326d73a222d3173e10fb72b62bbb15b2c031c28472cc8f49cd93f9725af37abf8876b9dc74e2bf97a5bc162d701944aa65602270ccc525eeb7e117a7b9a72f102ed92ddc7a3822f655a9f6566672cce5ed14512d60629f9e77b3fac4d0ab4491df178bec68fc3aca1d2374fd5ec765ceffb6ea97de44f0a8090f6ba85a9c57f84985ca23b97b6382594b4f3ed6f1437d2f860dafc7dd216ca5666df5e4154a0a9569c8274ea7dbc5b93abf8842d5a7af6aadec6144c74831060e43d9acb8b5eb851301f376d1c60fd1376c21cf2eba271cf6dd3a3eff3b7062b08ce48d3262a50a48357d08f3f49a426d5282590e854c49275f18d9f6f2701856b35310206e6d672e0a936fbc8ea2bfc970cea631012da801eea52c3c57f7aba6d53e2c5cf06eebdc0122f6d56e547031e26f021a2f3a1709dd930f7d12d4fcf4a5aa5247a042780f26460bf69fd440f052c63fb7318c6319d6e356389862e79cba99b8fedb924e25783a546e58bd9263352df3a96eef8f19e184049dbc7fcbbf16a01a3086a75d43105a5780b2a487874c9c5961c40aff33f5fca88a6cf9fc22e324eb9a682070493d40a97611f0b520525fe7532ad7fc5baff08b6d9cdaa04f7d5d8e76d20ad7ae865e6ff9ad8a24e0e82647525763d45f8af6859ec15e648647ed2b8b2dc0a1d443a66dff32a44d6e5b274a3ff3e0b690fa3e10f40b5ec2c54f1789306ae289bf7b75274df437b809dfbf8c19d45cdb816973d28bee02cf60d8618fc622f7f7b2721e80c1ee7b4048ba24a1ecb518c16484cbd4d1c96169df48172f761d8dd2b2bc90fdc7414eead944b82a59ec6d81b80270ba98fca33d6d3778b1bb77372412ce4e817007da0be73e3a26da69bf1f07061284cba8e2c944c39de88ff5c504982d452daf9768203c959648825049e1f0810ba6a40026f5f6c407f83326c4c9214c57ce24ecaa7ce41db8d82f19b4fab80e0a61956d60d64f7fd71f08538f0c827e2bedfaa49e53f2b559bd64f0b85c62a66332b57a342373c9408af6ec520cee003a71810c12ff311609beb9fee8825301247f5a37cb4b77036ee2f4a56800d869966db2258cd450ddccf3f777bf3028ff57f94391992c2231a5adeb1a61a0f74f2e8e364f7a0004eb25df2c7f79433fe928db0cce38d25ee1a6966d91b1d0d83f2fbaa57f2e8c2ed20715ca78c4ad0b5272dd1c73a91b2e8c381246a0c2293290e09b45005ed06f9a1f1981cfcad1ab6dcc06a64e2b92d4c7a18e4dd903e3411cc7893d170d9bfb476663dd571c3899ef950afeab950ad344d182d5fd83d7f0f5695ef24f0cd5ed2b339478b5789973e503800afa1cd8d4ca05207a39edceabc7dd1aaba24f9a415ed56ff89535254ae5d5b59009529388e08a3dcfa8294df4dd501a37d47768094b39bf8d61ac1fae118b167d7e040eff5a09360d517f90e957610c6ee85a49b8402f69e711d03a6f17a2fd732ef81f9a482f678d0c29334a1aa1d3f749ffac7f83f1288b93670bc16d58115670fd6d19ae63606240277e4c9fa8ddb205bf568b2274a9afada3650d8ecc91c042f29c675263ab7500a743d43b97012b2f902d079826830d3793c4222c0d659c0679d1402a72705bf2fbb35f006e52e84f70fadbaa9c6d7aeb74bc02f33fda26aaa3da1e5bbccf722457127e3137127d9d8f46abbac6aef6398504367e853d2f50ace8be97c8ed37b5b28b06b01df82f697eebf273e8efc869d513a39ed5079433c1b0b567330a11f078a3ba6d172a42724da7cd8242128970ec93fd64e17dd92a517ac1be0f4cf4a5fd2817e16a851108f0695b8b3e2c8cac3caf9fecc140398faa57d50170f1102d11d5b72e407593e070704c5f8032ce1ba86465fe1eec1589b47af1135ad631ea9bde990d2f304835fee9b505d549d85f2e5b5e9d508202c64a631b417968c01adba2726e006", "", 0, 1393646884, 1537743641, "caf48507bb96ddb779516057f8cc659fc464a1c02c6c3243fbcf278cd8df4b64"], + ["030000807082c403035e1b565f52ea61c962272fbd2f5dd6511d811d1b402d5ba563c6ed4a041fb99502000000026353ffffffff817a04ab0c3184151c0d7cf72d1cf19344a9411346ccbf7a13beda5c0b4f936100000000080000ac0052ac5265bcf28e8836739f194043b20e86342509988ed7b8f08eda53957e172bc08f10182aa068c4010000000653536a6a5263a3ae7aa3021a2d8000000000000151902f5705000000000700ac5152ac635300000000c5a93c4c010af6d400000000000000000000000000ae921f09bef61c44194e213a8cd56e4828774b9b0fbcd62c35e83e495f9936ffd77e92cf8f392b023132b72c1d966fc779987cef11d7d5a69b6c91d8d84da3061fc987eb55a75eb6598c7930af7b3254f1102138109726fd709b4bca8f67ffc5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009cb4cbbbcf702a73018ba9c9124cb96d36c8fcd9f9d122adbda9592756d4cf78bb498ec1c89b291a48544eb92acd2a3ab529046dd8a154fb8595cb485b5489e74d740e3ff77e919168d2a4debae102a034a15b2ae1fd6ef23c1981bcb0e805a7c4b05b519748e8360204286a9dd3da812cb60ad680cab24b8131b4279b9bf258032f3ce4bfeac6686b96019d4d929f7c7c43e0fa1aaf97fe30e10307f8a6372a05032d272982d8d70a10853cfb7f636f0d7dcfa0390bbc66ef363bf65758c852a70d0a06f21f30e0ef5c6a3b9bbb63995a0280ff1f7522061ab0aaf2659903331fb962f580feb5c3ac1784a6cf0d23f2a26ff82f6573464b63bcbb71100809d355b8ed03160217b92eeeeeb69e8a6a2a1c421b20f317c80db9cf7a24d8e77e305fa7fbff032d9fc64ea061d2b351d4bce411fb2009469f1490359cdd84e34c3042ea9a612f022a0f72e374a293b8d1ae410d32909b3daf2cc7b6d2808c1e7f6e50b17351118a031a16a90d6346838c4c9fd8840dd938f5d9da1e06df35434cfb9899968d010c8b0319238471a220062b9448c9649645d6d6a21972a71ca641b19da00d9688d48fd99532a2d3534fb6c33b542af10c60d7331da431ae5e40bd63589524fbe06e0317d98acf19e417a98ef92f172be9d88ca96a59341dccf4bf750ccc35ca6bbe9e43db3062bbec55174c59966d231f769ef850de60a1cf2c8d09034966ce2df575829140eabac5288dad05fe38623896701e98ad5f007dbad758afc156193260c8209a4b2fde3aa2eebca194e7a8c186cfb584be6f373dbbf3ad1adcd07d73e07d0019feb3627fd82e1afe4e5240750584e7ca38036b34671bd5f940d4ca535ab438d127ce38e78bb3adcc8703a31fdbcad5a5754cf784f267cc8762d70ddac699b363440bb681f496edeacace219ab0d7974860666dbc256db8b6b4772ec4bc83af572dcb755f9161c0afcbbf55e3e13f4a4ec35ee1ba24500818f0f1fffa4833bd3a3c7c3f5dfcfc55a66a812a422d37fa2191de579707c62ae9c414c79f0313c737bdeb215026e90796e71a9030aab1c91128a44839528ba40148e0c530bdac60dab3b4e179275978102fb7b436e877fc4230b5a14619a27dfe11663b7581668ea634bf156c5d1504f741b15447fb7cb420eec8c8ee6668475aed6e83783d67bfa28c1cdd07bf64d35c982fce558f6c60ead3fca48dbd938562051cbd39e0bb9a39ceed849a0be9d26a70e7f0c67215264a9034ab6f4d306fdced454b7b798842a89f5c54e3cadb17e74e18fa983a6aaec002ccaed6b4901c6770e999712f9ba1f9ff7e6f887113675253365cc584418a954bd64f830089f7673f343561fd0610c1581d25fe9dd59e00a0b3f603d3da3f2897a7cb3bbe5ce4d368e159197f100bab1e5bd40324f95f8f35dc2a92f18f42f61a4a74733f4a7e826b34b6aa4722d0560c77205ad7f606e59356ac230601d4ee8bee9a1f845fd9b423c0325b6d58d29ccd7f91e595350c8672228584031bd2e7fda9015a21ecd16a407f50be985644471b2bbd3df2085e490e8e17e3ae439ef085fe86015e4f1ee656688a52ebd3fc358c1038dc2f0733beec6afc5291dca70166766923fec88996b60b185775ed0e3989ebb89c963fb2a0c768fb27ca84c73252761451d14d868bdc7e58370ad8bbaf43b4cdc29243d8ec0214415974557b2f0c952f7af6a7f4a3fe182aa76a53a719961c39e88adc17169bda50904080b62fc0c4e384931f3c623e3d68fc6996272b6c37ac9c8e10ddb469fa24196ed9b3ce771327739ba16cdff98023f588bbbeeed905bd26a956085a49f007c942f147ab1850de90a5eaf7698abe2df1cb27cdaebe1945964d8c22f246a1ecb8e315a03f1d5ca65a5775f4340ca409e8034c98c2ffad79b8ed2e826b98f2d2765a8a3cd3f29021ab7276303f65f0b4de0de410683f9c69b40cedccb136f285dbd925e57a1c7920bb3f656fb070c59c3d66f6da862fa5d60107e132d77c9c3c086a9544640cfb7624bb0d09e2ac991be82be1da8547824ea3656c59e2a61592814927e357a35bb94743209befaaa5c28ab03937b2bf4db1f30707e137a12b9ce43483b654402389967b1e4d50796f2d09b510f36d12b9c81967969d591adf52ebda3d2a18fc3da6ca37484195cefb155c512f2b6d6b6f319ba0f3067194e725b3186e90c1b9e9f53a02c5a6ce30f20360ddee460dbf3fc7b654f987368c09fdcb0046fcdea5e7d8918d4e950d36684ef978717a5e6cd8e77d26b3e451f9717e9916bb14efd38d0264c3c4f60f5d255e150674b03ea8e719a0c4b5d16fad68487f3892f3e210a6115748330765bc63df0d7dddf5443c8e957c433002f76935402bdf89fc0bf78fded8a9dcac3fc7410dec94fa1ab840da6c0d14d0e9a9b303adaa64a5bef505", "655363525252516363", 2, -1885689224, 1537743641, "9158224395880878ac9efdd523e80b2b1c6dcd49067f2f75bc0afc9db5e283ca"], + ["030000807082c4030137531794a4758236d32b01765e3b5614a1490efc5a77129b2bc82d5ab8a2117301000000066a6300525265ffffffff01e470f50000000000030063653e04d4c40000000002277ab60500000000000000000000000015940f6e77a2cfd8bff3641556ec0c3c2ce61f0f948ddaf18ed38a6b53d7b0956ee47063b3710611029f4577c76c51b08bfb55f8163aa3a3b0c1e479861c22510c76cf3ffa43ed2a31a3fac510396928f099b1db4cb676542ea16c72c123178f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005557e124a21ff45f3e8a9586a7077172d91ed934978afd256afde920cb05097bf269a0edfda5d30304e6df9bb7fb5989cb24a9662a7ca991c245273631b2a01410a3f79543223fa3a50de8465fbb21017604c9271aa607c51e5be020de3118532bb3546b3fd5ccf6b7954cde81919b349f5999ff3993da63510ef468ccc3bca103075466784bf5d07801ed1c11e018ae44dae850453154cf5ccfb9173d325426c3030abe0513536bdb1fa815e57f1f5734832ba4529076b9410f5ce81c62982366810b04e3daefcfc56ced3bfd0c9081b43fefe020acdeb989675a731885e1a02466c3b47233211be4a508b4ba309cd85fca13f211f7bdb1b3bbd6b59d3589d40ca1550206b3ae98e9d00b8314020d234a929182ff03ef295505d23d7f0506da77748cb902122cd32050d86cea4ee729e54211c57a4da734c86f00b1f54e5c663f7ca15eb7030b463f68bdce98a2e6094acab324ac0196d5bfadb94337bdad71409e3e8377c203089c052af0f45b7978b7b485b49bc03cdf3ac2bbf30daf787c8c84719ee6cf0d0322e6fe448eab259d785dcc326117a9b4dba97a16f080691126406ea9d31301e348f6cf052b529d9b2e3344d5090815ce868143eab9d42c39b2f412bfdce186449d501bce01b26ddd11ee3eec1cd4b810f559413d48fc9c658d540e4e1513882b0083466dd0d45ec1a985d33aaf48aaa20467dc92cda4c07a6b6fecd908d61def3cc8d95b3854d266eb2568b5397d9e19103909796128c16215c14ce1c4ddac78c0f6bd6b600cde9436649ac5f6520c95161f1e751a45a279960aa41ab5789fae4f9a13592037d47571f1830ffd1580cd2e250d3b9313eb5ba750bcdbfca4f8d4d91f8217dd6652c877a6fee0885c8790ee29effd7d85a68f7efc06abd883e01973c4c3895d2cf99660788d6e3df3fc7bad45e241fb28ee8d370607aa71efc12e95291b98df66ad2277fa4a2f7abbab5493924085879325cc6328e68efcdd6a6ff89462004bf689863345d628cd00828d3f13c85f25c669fd4bf70b8cb0e9dde20d3e013bf53a74690ce83066b0940d940ea90f1bf1094dd6d11f4af213db5a8508fd1a9ab26d2c68c59064f00b7504b0fb847fdc3790a2ab20e3fe5cc448b095225e540ff04b45f70b7df11d521c93affc84b7b51c4cb5055bd181015663f2c250f1aa063afc2157585539009db856c83572b34bf9557af5bfda09810f4750a56075bcb13cdb8e48cf4baeb3414520af5dc7ff9301f1a91fb4b7192a151ba6b13e6dcf459b1e58e71bb0e7a93ca20293995e0129f921c00e3ade17de2d227be0737b64926541b303f8013a762852352f91be78e3502893966350336abf1ed89986065ad35f095ee6235beaefefe90efec1c614958920ebc57a26ad11ecaeb1fee1700ad4bfba62774fbbb846c9766115f15bd07c527ed70cd925350ac0c01500a41d5eded1fd35053c7e549d9249a757e24cb824e2887e703bd34f14713d0102ed5638d505d4bc4729b98844256d860232bc107f91268e5b8cee7a7ed5aadbce8f4a2d59e298c9fbd58525508bb656b49d91abd6be2a039d7e647256f70cf00569a64a22988ba83fe9616113a8633ec5aa887eef380d89d102d30be907509293a9378b80116ac816436df13732f713d60de81afd6275fc34d30593da4012fc99729daabc20e77559639da2d23f1874124f3154a1235b2378c82f3acb2f4b977a5dc23e2dbb321cc57916b2776e3a6abae1a242ee961bf7b99d04386809322d02863bd8acd3a75863eb942bd0b9084ecb9276999dd3133d882fa6f59d23f213ef203c52b055824f10e9897b2a209a5e5cf76e0541bde2c91b9bf72b30a711e2c1bd34762f8b103c875316df402af880d328dd7d31ffabcfe7f3f4e85d3c69f08bb96482f01a45e9b10f9964783434886224ea3e6a7bc4fe0b125455ea25751d8a7e5ea59a448a9e045230843962459afff94480df4ba0542c76cea9fad6e5514d7101823b4797ba63a6471d3773e7b14ca3586c8ddffcde6dca307735c010ed6cebc9a44253aec76f01390b8eb0c7d3f15d097257c0ee0c97b150cc19f675e2d005562128f202a3eb258ccb566319a656ed6076d44500dc0e9faed8fa402a6639963d14e5648cc8c27f697394f9971a027ccc702ff3ff182e1a5879fb727bc79fe7325e346fe1a78d39c0ae61e41bb4f907b39fce77cfe9d3ebaa6af1a089379513b9fa76d814e8ebb02aba9ebcd920d49e81caa5a7ab29424e91edfa07011272b06d3b87a8fe22c1038e086cfda29495a3a76049b403000000000000000000000000c6ec402e1af0f28928c1b281f9a80ddb974e537a0668e2ed20535fd5e0479787fac22445601bb77f172f99e048b9b7aa7825f5545607eddd3f8d044a588cd0bd52753b08d0e5fa44f2fb801e349d9693c68e7edef7c1228b539e3974334bd5f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003188ec129839069adcd7d0c93bb2f0b2e744ba7a2475b06d9e57c7e11f8423a4742e6bccb371e99316fee46825b65541cec3773ce9c272dd9cda5115459ec472d46bf7c20ece6d6b052fe99f983024570461e3cac3caa3961515509f478b2c276b4118aee50407cf49b1c8f2ed0f805c45974238220c5a1f12a2ad4525f051b7031849668aa0599fac36a207f12d797358b49e7f71118549f7fa16d172ffef03bb0207f9c4c0c9941ecc4442629b0a2c136e58507ab9da526ed5714d6bb6124030a20b06fa63a54dc5f19a5d134fcaafd0bbd015a90c60f599682da8b5bc6d2591fb70aff368c05305333d4f570bb04c3ba8045dcde61d41551045b40b862fc31e62b203163ee31abe7e067a2a6dfa5c7f0022d5321546da7cf4398b9132b6c779cd7d640226bd0dfcca157013d7bc93ab464031b6790d0b058894eed2e688b9d14bc311a402110e367aa1f370bfc9a41891a62d5b0e9e8df62f7dbfc4f64efbb94aed47c53b031c13b665a6e03e5a43ff2f7ef56241897b4e0dd33e0369e87f1609546f91622a0229c39c89f9726350de8d7faa742258312d1b384ee0c5c512fcf99b0a0d31c168e265d9e183eb2eb57102fe6608dfa59af984ab713771a4d9bea6855542113fc336743cb12e1918a7e289890c794ca89e190ca34b5e795e03bbf4d8c4a1b1a1b197ded77a51a192561d5641d92f9d10b3918e6cfd9a9cb355d15413b6263344fa46a83674d865851e6d9823a95e07962f53407f71432b5126cbbb48f709bafb61a90d3bb2ec9c4f9473cc6e200609e350264bc2b5be35a2a0a156c644d768bc44bdcef74c9d38b61254b18ce952bfdcf0cf87b3788a204ba4ab71b1adee80a2700578a172df9957c27cd302dee3cf1bb6e2ac5139f2cd8411d791efd49c5ea5f4c941e507f3a15bef34818cdd4d9deeba4d7e9123d226c06845976fa70a26de4ff501aa57fea7f994731d84c69635b33e922e17c7eed8e34546080ada14305466fe26ba7d1290b954d07c6bdc8ce306cb213abec9d582fca106f6ccefab7ec661beec76e400c21859d49ea0ef7bdd6daffdb4132a53a727fd17f44161ea9899c339e28052d17635dd40194b8f111717ff241b038749e4c18826a6d83c8ab40d904b30aa2fab2405e8dac93e1d3a0824dff166f4f58a7573a2d1a7a99842c312f064b8876b1edcabe6832631b2345447a1b781e395f230ff6f27f20e47aa588488a71d346598900fdd7f2b2f4ea7a174c448bc76064c9d72cc6dc8606c90a452cc0203065e3e9ee6ad81adaa12f0a5d8f7251cc9b0eb79e4e813457a1f4bd7e2cc4ec1c0d781576b06cad402253907d8f93155db3937309fa25f1ec30fce13219fea82cd64dfd0f12ab4bfc6440b8fa5ce2d4e29a1c3912409a8eff91e5af935bb7d143708339ab5246b66db720aebae59b158c6ca5c5f58ff8e6fff895ca8aae1c5854e8fe733050a9470a1e8916dd6fa1584b5fbbda672bd78a548711f4399526f6a0e3567d323ed87605edf504faab20acae7232945728acc39eb728e10db3a1d43991258886e3522cbe110c96cab4f0ed40fa37bc97efb62269701e986d63a9d97cc8ef8d2138ecdda0ccef76b0776e0e35f89c026a7dfd6886d173cbcff0c8f88331d56b5e7294a73b2d81f531f1b9d76354b55b4fda7daf09b578ea8a9b663cb94fb68800b7988ac44bc079fd81fafab847ce14563fcf3c1e9e1db9abf9080875486b2dc6f6c3bfd630bdb130e4a4bce6f8522831b0795271a75ec22ee5730eeeaecda27102970210a84f70700fe74016e8ab8e74877b221be77f2506712570ff0e020249424e1e2225e4f237f5ab1e6e3a5b92d08218f7ce049ccbbb727b63e57ce83128a5db9cf720a33b893b1b3f32da804174d1d37fd9d989186845dbdd122a57bed4b835e668e7e436f114584e1ae44dd47b9cd2ec3deb0e81346f74362b6f2aae52604c834cb403483534fe6939e3d03733d71cef44fe6bedba3bea5919e2e4a0f06c145abd3540c7658a096bb126fb0fa33a4df04c448cb0174d9fa370d1755a877c0d64072a84bccd4de63948ed5c8a69783225769aaf6ff0c39309675ad4e7ef38fc68d9a24e3bff3adfc17437f6b02ccacb8092f03dc58f63229af39610f35134766eea4a0df297cc783a7b7a6da7d9e3c418f997624b6e2792085d4a8ad4045ead8748fe5f7a359f4b8614c5ed19f4790c8c6dfdfeae17248e880623f5ad08209831d35e35ea6525c914b87b27b17ab52edd4bb72fd38630cfac3834083f221f65cd09355b137f641f829ccda0b28507204078f16422b118522d06f2c996ca1aac829ebbc180995d1225c468291a32886e4aa8d3dc9f5e3372a49177bc7a0c135f286b08541fdf72f714278ef99cd6f5c1f3653a7f0b67c35450b4bc7025210b49b73ddc682b017ca4d06", "516a52ac65000051", 0, 2062222163, 0, "33c90c3af17f0a2d300e691538dad8ab43e78f6dbda49e813135195079d5bd30"], + ["e82c3a1b039116ec65a194083e7dd3247db99475625b3cca3be4dd470fbb95e066df8c8a7a0000000009ac006352ac51526552ffffffff4109faf0b57a29fde101c9501ae2a41b6f12376afe5e8e705f45c4b5075e11fd030000000600536a655265ffffffff35bb5e47851634493bd363522b3902622b379aaaeee500523f43fa4c57ec68cb0200000002656a0a7556b20371da01030000000009ac65656aacacac63527a2326010000000003525100850b280300000000065153ac0051530000000002000000000000000057b0db0500000000fe9261e629670cce94307db0b57f1bf11e320dd1227914d364863d9c0fb395825490730b435d4052ee5e525c973adfc6438b4bf9795bc39308efea68f56417e88dcac60536b3db4cb1f66b6cd067864aa359ab7824e42536e0e285a92d9bcb180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041c3e6188a9df61fdeb038ae890a74238d3fbda78cfbfa841305534ca1f564a9d96c6525fc5b91bddedf24dfa681cc27c2a91c391628b03d5ab8fdd50f614f8e724072055769a416b551a20c512b55a74f18baf92f6a3ead29b5674f605cbb909fe3e761776b6f4106e471648ad1d9b4f2b9a4fb152f726b480ed5543fdfba10022999a2b337680e6284bc9d70b31965852c73d1ecd360af1b39e51466bc86185303150754171aee9dded4e542cffadb2a279687fcadd528bfc9e55c270e1b0d6b580b07ad779a1815e90a3b0ae19603395f1a0aaf0f7c157ad9abd7481c0f59ce0b13e656ea80d3bcb04138d896ec3b49553bdd533e6c76876784c53f237f37dc51bb021950004e27b627b5d88ecedc6f160a89537e4fcf33e772e9905511fae50e4571031b7eaa74df9c6e0ced534e65a19075228dcbd05e8e2653ac57af7f070fd2380f0229976da7d38375cfad6bc3fc39265f0d4ceade3fa969d70f88f3b9f85cc128010221fb0b03e971f544b9a37ff3ecfd1ca0b6e06c0609912338e475a180a341d71c03198090be68d560d1824a3131a795098a3af2565ae8a8888d3e20b2aa93bfe7d77dafb709b4e84025606406e775c1c84740dddb11245be63fd7bacba2a83afdeb5ab0308f1ecc4a7844d602c847cbb7e2ab0f217b4301a45b1bbd5059d9d63d6b22a0d27f1146a6cd874f6d28073b826e3cfdd5f498e4f528a05ae04ace92101f3a439ec7ad5e915e1f57cce804e6223fad0cac99264bab297dfccb14905b1c91cdd6b7aec670f410862bfd0c2a632ffd8172a07b67b5199173a4a3c27d1864f4b27ac2b2b45fef541b1e002d85767e940057e06c8a8533a617f5999c0dbbaa6a2feaad56fa1fe6b65f08bc56e643085c79f3a9b2b7a69b5ad43a0ad5191f3e4a030a39541bbf986018d9352820bf57db1fdcbbe7ad2b66cf554ee23343668afb7ab597941f02014988992c797ccbcbbcfb5c752eb3e8cf2fe77f92df89bc457d66e47202002eebc50960cc9c45561bc83b9110b40b6c362f878c6a2de40103a6166ac493e1637a31a1f8bb2319eac0a2c7f0f8747f221c9c9646ff0a953c40f9cc20df7fe835fa8a685083ed610afe7e02457fdfd1982858b7c2abe670a6180e32505efe65c1632cff0fccfb2b734528dbccae8a044bff5555751c567853ab99aa7f8a62358602db1c6472fc0dc42b05140d44132594f934e16a7590bc05c0646ae93900b9bf0159f0cf64c966557f20a921cf396626e579f5b2783482aa74b5ab1b1d5ad54e00032c5a44e3e6d93ac399c409933793d5c29dd3ee478446412551a778f4452be191c3f9e67328a0a36780a63d3dbfb47e0bd57191437de2b72e55a5a7c3f6143b28f214103e9124803e7d4bdad9a625d9bcf4f9bf0d509dc64fcd2e334a0e0438d2c3baac88f90b8f457c91201a97c0c89b03962cfe9e0cde0026447ce82fb1fe8ed8d4db927c334994eea9755a6bd0db21b9e967a5d1b613b659cc51051f68a0dcbec443069da3ff101088f262e83e037b579cac6c8e9a5a86473d4d7816fe05f3114711c3c9bd1ff58251970f451089d06d2dc2571d7f7dbbb93fbfeef0fd8eb94c3259acb1db0eebfe95c86011fca39c1724c790bee115fff2a9df87a84ddc4c7c76cf16f30d102707e6bf33e6ce48659755d2f2d2ed9f27da559ff709d1cecc6ac83f6d3c0a8b252819bbb595c6122613b86de295719239d23d49edf76744be3380f6aed9ffcb7e4500b346b9f418f7ba5ec9a9ce69e0af12b29a15c50afb6ba356b2e5d7b68587832cb350e6169c0811860a8ef3ed3751162fcc13ebc34c53d4c41c619e7b0480b32f0cdf9f6fd3e44096e868358bdf0718c64e3cc3f7dd00aa5b988131396605a1ea743877b0331acb14ebf372f08c88eb66c4c5bcb325bc7c5256bc68210b457c3f4683ffc3e29696957814fcbb72654b6a37ae10eb271ec390a9f41ac0ab7ca8d47b80e692640b0173bca08cfbe0ffe4ebe347b5dc9a8c41505c85a0716d9492c5db3b05b862cbf9e4d467f02eea192706b0e39ef2fcec80f748fe4c71468799b0ce21eb40432401aa6c18be106d95e72e84ba7c580c7733ecc21c389be689b24ecda953f85dc86e313f4beeeb230b86a0111c59f077bdbce97fa820114b104b4f30d6120478dff775edbad1668d93cf0aec3d34b5e4c33c77cd8f08fef0ee9ec7d3de408e6a87cb2f6d52ada1934312b7dfc52de6a44fcb63bc050fe2f36bbff8c062f97c4b066e025ac2f9d2932cbafbe7af4fefdd271d12c61227d55ef62b8c13e94005000000000000000000000000dad1ce45f8b108120953f02070feb207d0f50d0b3b579fd8637c9035ea6582d31e857727b58f68261e0118e6dc74a9b536c12016cee45bc7ff08af8226950ecdf78a29488ba75ccddee62683b1be3827f454f7ecb993ab8c173cf833b2ffeef800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c90fde57ea52fbac06f71e6f2a432b60a96698b3d6d79eadb679125d3bae82baa3614d841477e8077d357b701857d08cbfeb05e70311facdf1a4eaf3be16573bbe4bfcef853152f87dedc605b981fc2ced2bcaf5c73622d9e283f158030e991cccf6e3cc21249de8d3c996027390c0509a111cbde3e1e510a86e62ac782be797020c8a0390d8b2a781aa5bcc847e068ff5219584d7fb71a1e44b785087f5b1985d030ac8804194eda4ee7b84622c3e45101da771be17dc0c38ce21afe0baccafb58d0b0827222ab903924549866168cab6716dfcf98469f688198b85f163a31ed4bf998040d48340b372867a1be8997b04dacd5c121a648663859cabf56943899d490a0310c4ddb05b12ccb9464b4bd1d26cf0b0dd0fd12a88d2794969d2a53c89e0d26b03071d59b976eb39939c261c87cd23370475b8c4cf1454b64af9d8e0d9653157a2022d882367f7a65f0f0ef0d6c4c21eaa39eb5cd59bee5a128302972cd736d4c49d022df3f8c6148017f790e1c3cabda119669d77a21bc3366e3b0f5861b6d071ca1a0201546b4af9a150dc24eebeaa80e048ca9cfab2fdb8b7dd1a9d1f7616a330fb2b8d49dea9dc573c4f02fa59e8a1af7c684b66ecd22b54a519bd85620506510c40ce36ec41e6a6b779fa6c1b790af1579f7b4a605d8c0399cb2c39a0e0d67d804b11baa7ab016bfd61a3b93227b74839338a23b1eab8deb387ebddad59284350674582b640ddeed91033c817b41c29b7173af487ac6e4f8265bef237ade22d5e90ff6179c1e5d4fed87dc7b752f06bd9d59e79ad830c1e33eb0c8933a4d3ccfed839e7e01e0baf5981bca0a6ca56774db0e4d699a5176440dc0f65cdb4f6abcc3676940a96a0ee02b3353850b234a65005972c10f2c528e5b6660d9ac4070f6b1d75d16a3ffec4d3ead68fa91c03c4ba577d56b63ad7251b4d2708da6a04f25476b93e338f9ff9e441a839651fc8d279283425cd4997c5cae5fa2a26f489323c73b606e556f82f5bf0fa68b2925204a7dd8ee29b0ad6fda0649ff9a3149c6bb9db186d3fcef69904cc555ae0fb41f885c67392bbbf7c8b74f5e47f5ff8be1b0b15c1fd124629d0f9755a7655b2ce149b3b657b0fa2644627df1ac39f9ddcc20bd2c67a5431952d94c2e02595f32a4b2cca5a6c24daf917a06407377b9213319984a9b2c3afc90f1508684e157c4be015a50f5ea08de46c605f4c685d6bd7e1dd470467461fa202d7f0b000024e2a315d30cd70d56199d7b8d7bda8efb66aaef17c74c74c177cf6cc486af829ea550863cfabe931eb9df996288f82115eab00772ecb1cab1d7fd042ffcabda10a21d18efb72569756727498576265e596fb95f38677f672d67d824ffd23707ef1455b07a0cdc3bf091cca3613b010d187693308b0b1d38fef4f7be2cdf4a2758a2a7d664e03e4fd7558502e2bf95d3632fe36aff8a777caeac70c695b0b3a04288956ec23d71958dd1d6eb5064ba432b73a1c5cba0acb50fe03c282673ff2362b00702047886c8078844e2708e30fb68be680d578ca5e1b3e79d8531d555a7086bed96e2e69c6892ce2ced1fec917545b511bc05e2b83e5063f1056aeb2b7f6dbc447837c76aa954e79e5cd7c3b813932697938a78b355f3f31f2c0604d46a4a3c4f7fa194d8d07e6e9c0827341f45172ae112eb10843628fb3347898f9712f1ec26b35245bbefa2f6d02a2faa98cb068ce3af06b3f4595e0b15c1e84f70df01a36e4d5ac01827d074144a4487cc24b377ed5cfa9a6c8d14d4b4ec4fbd7f573122a54f3a505e9c50acccc45ae72f8f0d2878ff44fba1736f907dd34a30da3fd69fb0a2fdfd4f427d07826583bc6cc12fb9971cef642f48f464f97d4a3c1e53428dc8fd2b7f07e3581c0720e1fb6d9694b23135c97189154674651ef81b6cd07ab8e94ed0104cae5edef7e8daa1d1d4e3c7c5f01b3c26b81c58c0d53bf566b4a8400b28018f1cbd1c8c79520d7d2f45efc5fadbf90fd6f755d0c7ff11bd8be9026dd5b3ceead75a7cc5eec7f053d71cae4f76608e24dec78287fb74da41405c45b6c76faeb86bc6df5b848749e4f7128993d6a69bd36e6f9fc24f36863a65f1ab67c2122c544f9b88af5387da8d7985c5f3f4ebde2da58da3b91be55233bb405e7e02f5ad2f00b088b1f103bdedcc6fc0284f599236488f7ba0d4cb4376eaf1fef4a8684d46dd0dd7d72137e5ce85d856bfe9f30c3b177e47afd63a1b3b99a2cf4b536d301bc85ff6d68da14d49f1ab218518f56ba6649068f635450637845a2dbd5f71b9e3d2726336f8b7f966b8fca7d5f7b009c03b654bbba19a493021466fed5272ace2010782d4189e5191d1bfa5e1cfef0268599170cc62380c6b0bcbedb4f567f1a3c3dd624043879adceee4ecf105ca863c167889d9d01eb62de0f8cbfa9330ffc9705", "535353", 0, 1923920036, 1537743641, "44f3699542d35bc5ada15d2e5cab2e2bc99a12ba2df9b91835ac2a779c0f7724"], + ["030000807082c40303b62004337ec977727cad8dd05982fbc3136f8bb772e76293fdd911c0a6a86da20200000008ac656563656363acffffffffac8840d379d6a9022dab282d7ba0ee12d3a7fb9501cca7527dc600356e506b5f01000000035151ac730088238d7fe2794e96497c2fa9ec310fc99c14d062d4192a8c9a225b49437742f48de4000000000553526a520041c76bea014d279401000000000552656353ac56403f99000000000127fe230300000000000000000000000084835773cfea8bbda714e3ec896d2453a0af9268937538d83aa51db49aff932cda60774e357fcc9443362ba66722d4b5fdbbabf697cf1a97228717e98ebccb87bb91105a69a36df7cad6d952af896886b99762e5941c0c97ca26d79d3522b31400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000267c332e2852c9535b64c063768e2378a9747bc2e74529616aa4b161a78134ee001c6fc4543176f5ecb5fb107e82491f16de00081d138bd01f942628191745e59f76c2135dbc01da632c081e82ec0b4a7f2ce04941a67a303704e60f4127aa6acd1ed1dd0cffec86a0307c3ca4d148c81ec6f6dde07de7ac20fa2720d17813cf0310c6a94294495db7c18dae792f1a4babf50b1b1be67d59b8cc43cfc51d14af98020a730b1f949db562699ff3e09ee6e3f6da61cafa8a2a9c7a51316ea99d2ff5c60a01573941c45ba750b36e93ac0acb00bbb48914d6e58a5f5a1f7fccde1695226a09e9143da234817810da656100a7a5ee95c1d88ddc6fbd689aae57ed6e321899020602a9cfc17d48f8e24c2ded891bd32f3000004ab3fc826ee3bf16826e7b5dc3020e8c03a797f893ac1ba252b51d4583ea5a711fea1b1cc285af52853954f94d1a02113a9e8aa063773ae285f0698186ae817d631439f1d8193012c7c8e743416b3f0201da8c41502d58d8b178b7446ea947af2e64d982381f2925ca2ba63a836f25d40314ef341ccedb8ca7140427b8402d49f059eefa77e8edebf2909a90d8ee6845aa18994aca9f7e522ec789fa1d0e60828af9db41ae21a099d12512dcd9beeaea3fc5930184bc8bcfaae6c74a5d8ccc684d258a53279c8a5ff1f5b9d9904502ef855ef493853e8ea45d214b418b04192adfc27afd74f2693dcd9bdc41604862a42701cf62b0af1939911c710b3800e43cb88a6f0c3f1ca974e898e98e4b135c4a111bed0a73324fe07dad4eb1b00b5f8bd26aff8331ab0ffd9dc9400d8763d4a39b4154fe1ed76e2d736505e90563df5d7b1c1d07b51b82f0cfc8ec159906405cf83bd2494f45d1ffbdc96da9f1ef7532b43bf837cf74eb6e6f677f45e8792cad0ad2c32c7358be5b44a4cdb63558e9372dd8e32d7d9a23f26447d0ede06f6a54f857bee7fbd751e92088b16fff38abb9db1a6ba63f44804b3da318361f1f69a3b701b737cd18c0dd5607895fd5da270f0fe06fe8fb56f637865bc270de7526aae3c14e3ba3190ff9218c2b4995db2243b39c35a5c43bad104030b6c7151cdd2bc4c8cb428c17317aad4155da5843f5fe7721321816b1877a5fa723d3e95c93b5e80d3e6c7de08049d2df98a41c9a322b90da934aec361eec25ef1e215fa5f781e6ad29d1cf13e036b61b2719f87ae7a84a375101617ae1dd8ab6b0a8ad4f27fe2272d372743c98870e6005c8117ab96880b80b27fc19ee5ddd9ae441f986d199a9a603320750972740eb9b4547a3591ae3a6b05be448fb44e3d85d27b77535ae9fae7b717f8b7a94270e766a38dac02350bf1d4a21cbbc4c60b477d643bdcdf3c24a96f59c089248db1765392d345b4648ebc57d0b05d94ba65731d0702315cab8c679e974cdb7ec03eacbe1fc84388cfc6346b5e57f90f6170153324f2b0aaf80085373a52c485600141ed0efba29453ee4c044994d44dd592549eb3f174563e9d1fbfa58142b9a9a484943c4ee46b2867e73956940a14f79f0d8c2d652a67a62bcae40a335f4a49fa125116bc3b052714bb55dbb9847a2eef8eadd10cfc5119eaf6ee5b31924a5e021feb63488eb61ada72a35c213b93c694efb83919972bc544ae9659513d581c491a4a49bd848aade675039de1ca7e90cc517b71ac2d657d1869510e303ffaa36fda2030595d51e1b82ab22dcd15f7187abaaf7a8015c5c209216a9e809739b82e6c06e04b24fe2995391000d39bb1ecdce811835bb89669b8c57927783c0ab890a9a3df67ad4350648a1406d7d3980f4b224b2d8ee945c90cf9f3e993c0ed0bff1db09a0fd82321f6bd12e87edad7733be8b36a483f242b464d0d9174f113c0b7e1e32fbb27de8f228448175585667cd6d72a1a64e1138ea3778cd7796bdb66ba15ff231608d18f8cbb24dd263ed5deac3a7424fb8b4455873372f6286ee4319a4a7cb58456b0ad254c09d9880bfcfafc85ed8686f4d0b47f1cf0a269006d98427c2aaccb6fe9d0d219d3c8a4c474bb0f9a530d7dad7e974fa939dd32b62197ff71c6ff799f486d40d3003981f5e33e4e70ed23ce40d2e4c988bea40c0bebc0952f1662a01c7b5bd658be4fbaa8657a235e234fb2999479fa6aca25b29b1b66a3f6db954d1f5cb044ae3011ed976c4a78d2514931db2f589f89f986dc638c91717bdaa8a73067b89e69365b4334e34446bb018e6573eedc92ee45efd2080e07caad725b77c08c89df5e02b200461cee7fea16eebd32fba4446e61c7f688b60648ef1c4604b5fe3afa8dd2bddd7b064ca02be85f0dc78dbd8353e0f29b4fc59099596247e79255dc09c378be5a8ab712d11d5a827b098f3646fdfef8bcfaabd6b2dfe9635af3f9c8ca902ec5fd35f82f761de93a3093b610369314f67a9a28e37c5f1296910e559828d08", "65", 2, 1313816017, 1537743641, "917b1f9203bac77029c96e285c14de7fbf8f310cb895e890a2115d8567a7a3d2"], + ["030000807082c403047c8463dbc3a1464f94f591d3c324f0b5c98d152df8500dc1d869c1e918d5e897030000000353ac6aa2062c684b9f2431dca1fd74914af2ece574b43fe8a07f81232507056c4242d0585c7aaa01000000055153006363ffffffff688b00f1894c9d8c51b04a9d87e26c237895a47b1000c12d778dde2ea78440ce0300000000ffffffffc18ca11c288d2bbba2510e523f00c57f244e74c39a18f4affc80d2556fe7196e0200000004526a52ac4e68a0a80490bf170300000000055152520000cf1de9040000000000d5cb8c04000000000500516353654743aa04000000000263ac000000000000000000", "53ac520052", 1, -1889739853, 0, "462cf222dd95ba662e04a53747e8d0d777796865b61e187f16a7f277bda4df04"], + ["6095bb16028be3fccaf776acd66a922dec096dc61ff9980fcf7a7adb8dbd2e99d25fe6e114030000000753acac6a510063ffffffffe729bbba2ac24d48431b9704016db9f19fba2b4240bb38449f1b1ff5108fba9b0000000000ffffffff01e6287e04000000000353ac6384b1468b03950f8f01000000000000000000000000bd042899e82b72207af69d74f921abc84b366af14bc2f61e360ffac311b883e553fc52f359d345413d22947a030e5993b336a96192e8366fcfdbf010ed2b963c7b06a4d68332ea51fe67d338c5fefee0c5bda3c799400b17296615bda78b359200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c85f07260e0e30cb7b99dd43f4983801d907c1b2f7f1c75c2004d375207df96d8fb76730771b189e5f5abcb63a4d0a82d17ebff7ac095ee78633e5bc978efb8a66a3147902f4f215e66f641e7ccd3c55d6dea6c3a0d376a87b28e598415d0035d653ca9780e7fc845fe5050352e44d065d586ed04e152b409f8bb2f80ca58b4202167df02dbf6f062a40c8640010dd8936c16509403faf4e7392735e8d169457c40306b4c5eb47fa9172f9e3610ef7eaa89ade1ac2fdb91b3a4cdb5f46f59fa7bc420b000259be126ccf2bd66fb28c50c0e2b6160bd0ffe79750baefe4e3989564b4ff6a57129a1328c244c69e31564580a641cadf7d2c01bf9141400a3843013de71802175f053d39ac890f412d2f3de06ebaa7a436e0054fa747991e49422f80dd3c860329ba039d66fb902907d0e2aa3f0089bc1fbb55f62d58432f9dd06a8e061b0fb903046a488a93db4e6a4ec72704804e41330ec19fadbbe31dc7172fd72c44bac8d7020a90d20236abca5161b4c3019261509eefb08932b732f6e4c0b8c94a28081d89030651e1995f8899943f7654605a41856a678925c8a572770808e4cfce2245b62047163cd8c4ef829cfcf9585631c03f4323b596f74ae97fe7a8f5fa27187e3200adb26e81d04ab4062a65cad01b9e438312d2fc5924bd2f57dcadadedca325f24cdfb92458c512739a0190433f5f5862c023e6e5c127ecca5629f65b4f66fcc63030163bd811c3a1555546642c1d362edc8350daf08edd2737c6cf88ca77e8898ca577381d2f1b57738b7b86fff04d0910b05aa6edb0f8f12be8965b0822137d41523227c7b0bcde6b641ce2fa0a75f03feb990d27ebc4ebb84b0cfb5eec6634c9d4f7e18a7d414aa37409b95547f1edb8e044219841e6f92b032439f85593a7a2a0c685111066613d8b1c996969fe72078beffaa0db56ee9e340df0ad98b3b8d722fc4711ff6bd620df13bc115a6608166b3a7a2b6edb17bc77d208606886034a70a8452b2c9dc072ad0ece817427955c472614a0c5c0ae3f1d91af4d43340aa38616a567d633359aa29ad6d04cc636c2970492446573532518879747eb01521e35bb5d81a3c5a6a6e62e67c751e552033fe8872e392ca6351a2306dd9894d1a560b06f01c41d51ed389e0bbc1bce12b1c45ac58853f1233df3b4dcb7c27a6a3176289e07203c99cfffbf4f1992ce73101285d984a73cda43876a73512d6bcb42dd25e66ee3fb83ec1d80e65ef5333710addda2163e70ed7dad4c7c29f1dcdd05f927e94b0bfeb445983748d2462e237aec71e9b4d30b3368ecc8c2196b08935d8e700868e998f6824313a472f9f066f66c939caf1b0fb5d579209f464399ad3af3abca8f70252e7e330690dc392bf55c3ff81bec7b9efcff7bf00dede2684fba913121deaee9679d786be2609de1c210e4dd55014c4e2de455ade318371ff7eb4ed20813465416fc8407b12928f3a1dd54edb3b19a47ea8c4075a334488381b55657761978563d5f2447b75d975bb31f265f7fd3f271e787d8c6d44e3a110f413cc70586a20dc6c75c33314cc7530d142728c92564195185f4da4b565b8008e18c8f778012ad54da56704bbcee9ff71aa41b744e6b662e321d55e3b40c35a06fc2279ae55d501d91663896be6ad6c859b10cb3111d6ec3f5ced1d61480b18061163d2f45677f4c108ccde8df90273e5b7d1300788e8fe09d03d725b7f85366983257e49a9682ddd75a50b3a4c681d6731a48a9697d2a9b694e2b945174a1c4485d84250399bedb94ff55af15500bafd16d683a02ddf6f5b0d8ac7cfcac4f1bada762dd99d28328e76f011d9383047e14f058bf1e3d4614e934ec9bb939788d2391db22c95e00a1d8fa3f259e50c02bbdef58745ef175491d1288a21dd87e6a248d035015ce41dc706cd41391c3d387e3a7ea86570994cb222477e8a90e9dc6b4603b7977f3a5e08bee7b3777798a0ad70b715372ce6aa8f6cbd7fb00360740e8a844ee9983601c6fc8b934c07858d63dda601a6b2ddef8473d39f3250f6c1d6490e834817b03834469c9dfddb1fadf82aed925487bf9df9181b9d4e83cd385c247bd0db6a343fdd61ce27b0294593df2a1378b402a29ff445f84eba888da81f401dbec023b4f38d0111ad696747ccadfed0e7a49fb172491af3026ee00e01de5e0d85d7053c78b16cb40fd859e8afb48e397fc0933eb0d4c8d718b082f3d49b95b401c7e94bda98fde5820e06aa6c2d9deb6297d9a1eadce3abfa76cb154961a6a9cd775e9f48ea3bd651538003c1e3bc230000000000000000e324f6020000000022f155c7c9611e9b58776c650180553ad004348e8b7d33aae5c3aa2345046a662259d9d7e9b6874ba50cf7333b72aaa1e2aff1f742211ea4ae8e03dc9c88ad8800562a4037d7337c9c1083977a817dddbfab281c569ffaca8b024efd46e4a374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a1ebe9b1c40068b671420b33f2d9afc190d9719e0f6188b92163a855e18d3ea8cb7d3b0d688e69ea691177d0a6e158697718fcfdf98eba0ec9deccd15d7553cc4e8cad91f42fad09cdd36186262806c2de8176954508ce8da432deccad072faa1dd2e816c7f88f97244a7ac3e206e60a3736725e52f50eb1b84332a691a4e3603157c470f3f33463e51beb0f8790d5f277ddb9e14c7734de2590a7733641ee28e021ab8ea07e22126acf621da70f317f7437f6da2c672acdb5330c06206831557910a06e147899efb3341d99811d2bbbc061f6e95b574572aadd233374e42e25b8f2963e990e218633e96af1a31a3964516a973c10aaa086af8d59a96da2a4b0798060329ffd8ff4aabb2d563d23e53c72a1db06d73bb18210aef3460361e2b1bf868f4030403542a0be1f3e247cbe1357af3c413578773ea022fd6dffcfe407153e18458021883a271fa0d5a077f47771215ca898d022f11eb880cd6986e657ae8a1a15eac021e50af34c156d2d5a03b74a5cbaa360facd4549ebd733d97d9607c12be65d4c80313e92e4ced76c911f5b3a3503dd4714cb28c18cf053349c0a9318e4f6c31f70b8880883c7c9f972e99394c926d096598e8d319adea3ed0327bece4805f739562780c35293a19beb4b0a02dabd497260400b94e0fe6d41ebeb8a40d926844c14acae7bc390aada5400d8294e4d5c9d4d9f5a523e8f11ae2b5869bc9fbc50adf493210f7ff9eea1b502a65a2bc187bf136380ae7c83dd02720365dd7aaa910b182929cc0cf1615af3f165e8e7d6cb363da42f56b6a162b125d2d2fea5c9f62fcfb7002197f9ffb9646ffabf763a529efd80b2037ac9a6323b307dcdcf84657fd49900e6eef519f1942947e8602bb9f4280fd4cb6a7d279f012d57b03cd56e3b1f6a119deaecae1beeeabc17f55b9ef800f4f95fd226dada6f1d48f16dee4452daa4cfd0810d4cf7b44b0ffb6171c7c84e526d52b1663317bbf7f9e3a0c7c48df73bb11ca627204afc90f7a6ead177c7dc7aad248735716db7015065ae13b0dd7a75c63d21ca38fb9a88648588a65db15679fb31aea121df4dd1f14a07b443877584a79d4d6d7640bae2af788df88f99e7cc82e7a12d57ba6c1fbd4446985e2658adfcc2d84bdab724dcd8645ba483d9127066c71b03ab09ac03c4c0909bdd3836b569714fb9da6b479e1479116a5269111624263f1309ad0b0956aa3141627efcfae5e9a9c9923898374c001175d0529e98f3b90aa7d8e1eb4ec1e9d9498c63e4e64b27a8a9d046ba5e9451bd09e03defa5efffca67a88966a542ca2b5723612112bbd0402a99b399f405f625889b603bd86a67aacf344c3a53704922869d574def5ccc1535cb06a2d219184b8e4c3f5af0092ba3ca9184eae9b15383373da2b315e0e0367b4c2f6440f78c96ba7eaba110174e1482f10ec1bd08c05e4d95405957b61a179773d096170371b25b6c303635c46bfaac18ad0925002276f26ed632cba3791901b489f8c7e110fa4baf2ce313a472e2f90dcb2dcdf3e81b8e041dba74968fba6e58bba82ac5a20b5db191be6481097b5b2b8fafa3f013c4ca6882703f0fcc05ac4d5ca55903ed078a649618018c790d999cfa75cb67379f4cea73bcb72ea0cccaf1f8f34792eec73b52bba7d73ea7e215005f185822c788efafd801923554bc88b060637b9fcee3fe776a943f40c7586a9554fad074ab26ad90f67b1ab88f8d53b7d6ace4bffce53fffdf42f2934782d26f6fbe8d76b4da61ab4ba288281c54ac715c63562a8199fe2686b04f010129a4445e2a1a3cea3f0c3ae0033ad36d29dbcbd20764ece764ab1b2e9c6a43f540218d97b796da7bbab051316f9df33410a65f0f6535817c0de80851be7cf4af839805a07b89abae9cd82a8098a9ffa3049ca6164be36d7bffa64f96c14066bed4b36538f6083110e265d1510fdbee9f1a1d76c03c081a9a6a49cc21dfc452c3ee49b609f2225cfadadcfdb881496e35c5fbb144e7086657192512eab20300e1332dc1f53ae4e7d61373598cdbb831cf89ab7f679238d57b566b15a418099f684673c7e3eea5df9f74fbefc8bb9536b3a5e49e0699b5e2b25090f98badfb91df171a06167f62c372ba5f15cd59ea374d857f4a2a394bd7ab1253a2c034121afd5eb5caf92627a5f6610e0d7af5310c9051858284f668ba282ff06fb9a286eab910dcee1b30341ad398e4e4f95f1cbf2a0add04893b4502eddffb2118e60a62e520b193d1ea92280141d95d6ed0f4ae8b6f6084d942c87d2b364a51f16ee3a754b3c81020000000000000000000000003874a3516f272ffa7005202bdbdbd4520e77cb2db33b42a4ae2a5de21a2a7775f6eb3ac8dd643f336115f24bdb34f2b5af58cf0c8cba8d5760891274b38086825e811005b01d53466e28fab72752318a3da33b0f896c91eb9115a06f35a5b31300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ad0c7b985c54dd8b6e7c52c9b68ea88d2eb590e23f65b0b0fbd75943d382c57bbcb8e61d4ad2665846d7ab4be875c7c2983cefba77c3440cf6d2dfbbd6bba94d3094cce228f45c6d85354aae237861cfb46065efab0397904346112e4aedea07ce4e75e1fc80069557e30c0da066178c7d887f1f97870ce4c676cb1f671a1fc20212144fe9e0d97dc00436f5bbfe96c0e33fbc01f4198afa563072f013f967831303292acd7f79334481778bf3983739f2442b07cfcdbe6578a67a37e517c7639c950a0823141fcf36021ff127d90ea2e76bbb4a7aaeaa0c7e29cdb2108b8d62a57747f5d9e83abea248ebaf2ed8f361ceec1ec80b06cd0e92db3f68ecd1afd908ec3e030685361d446e8b5bd7f246f0c892499eebf560175be7d5eb4d2388d89a75da06022ee4281b256fd30a1820c114a97ceca0fd1250df7bea9da5df93ac313136a6fc0204143e3d5ffca2ba28075782a55765e617bac1e60951f8333c6f38e16d2b3283030cb1d86176ca43b915e43328694c8c62cf551394f1dd32f41d9016cc22c8c075020f77230b0041727105efe94d5f4dc133ae12e7492e787e642626015327b9cb48efda0ee60b72a2404e9fd1eae5cb7bcc8adec72c46229310ba7667237372c0839791ce98783b1da588adef5051ad4a57c4c0be8da1d4a397c343c6917427d1cf6cb57388886ab9183898d11a724a0cddc4e8857e3aff45387eb5bf7a5b354a4179ce7241a0922751a7b9fc867d8b463d89230a38d44fa60c4207c7cd808efdcb0a610272a9a4f91aeb8bb26051f54e013a1fdd5d20c71006260c8755997fab2f2f105cbcad72b49819de1cfca529eb78da3a60fb59ae90c5fb003db52724736edc79dc9d7ffc8424c95f6be61f308e84d0ae6570160b5e91bf5e632fc2163eee6d271177326db743f30a29d4e1038d0ddc22437b75c90fa99364efb1794b2ae24823ceaf5c674c66200179509e2ac76701b43ae185696fd5fbd4c94dff02f19337743c75c3ecad0b169a8c4bf040508d613baa04a55212122dd207361410017eacd18aaa1a74a01f6f7f3c9f935c927ac0fedee398aeb89a20f31bf24553014e7d0768f270058ced148a9d70b781354ce53e2d40d897b96d4102fb96ca6b6b6722c9040de2a6fe2094d9aae81c0668b5e912d8a44172d067f1227cdbf86d63893560bfe02f6285bdad7c9a16086b4ad113eadcb148587ac942bbded3ba5fbc8ce31719cdca1f04316360293a3d1f2ba0276e638573e3f6dc1200c2c7cce15e9a9702d743c0fd94fcbfac87e1f6702eff444a12773d8e308cc2d192bdf4e72a525adb1be27b540f3fd835073258b1b2615ba7ce6ae75626d58a4e2b44a39963975282cca42baa8079a164bc548e042cbe96e0a2f4abd2ae3a41b82da9e17ee38aff749aec3a8a2fbef2ab40323a4947a74c896cc16e84e7399bc09d315b85ccb4b4e4b6b79431823ba64bc927f83e7f9b389cbd2b5327efa280fd0560a091e0edeb2507ae8fb37e062c12275f4b68358c22b281146c5a6b9212220fc9a208803fe1f3131adda8cd7da840192e3b10c9586be82343977999a1fa1bf87c383c4476e35edc398765d4d5a08e349d51b513bd4247808459baa845823c2ba469e6de6c62f8c38f5598e9b86420e8de980bc4fc9b20770d61912b0591584b7fbe5917960a35e10c41ba536a28ca0d4f8fd250d6e62ad4a17641412e380a432666a91d6603bf65bcada900a8c591caa03077af5d511491090bd7b8640896a278a0703ad1a55c48fec9462a8f60a831658b1c77fdb5f6ea243f44de1be2a354175fbeb8ce8cc72a8ae35fb48feabee10f20c54f91f47ac814fe41788c113d1091e7e7388731a44219359256d33ffcbc54b9bdd5931f1b704756763496c237087166a77b4aa3617112dfa11c39c9efe0874f279bea433e064df89faaf3f2ad08ff319dc6d58ff09be2c2015b2cb17d6b0cddad0e90725507ea2542d83a6e6e65ffa6911527e65a6fecdbc8aa7e825ea6c9a9e6d1f5ca6d48416447b2c709c1df8850580d50b84ccad3c59d61b96a24b5de88e36af593cb8b08326265493c584ab850b9651e4b467a46c832c5a7650958ea2b9e1ca5475ec2103c92c5de3e62853c2f5cd4ee1c060523f5b2790098fe37990cc67341249faa94d7379ccdb2fc3f4fb43a113a00a8d062df62c837c465fcbe71ca250e39938680c841c4a7e761d92d480c6419422e7fcc90476f6a783bd58fa6532b9e28b3b9a0784a89342200ac16a3d9b38333e977429dbbab87a85955bf2139e6ba8f060a7881df7652fbc454fe369ac99dcb4959a5083c985017b905b3fe1fe127c347ee9c3c8dd2ff900561495a12b07f37a0018d900e767db1a9d45611cd14b797a09dea884d15c69ef01a7cb4ae0b74c1e085710c0fc4ceba5589d45c3539852603", "6a536a", 1, -1088114906, 0, "fc969b4d56646f2bd71341d0d762f9f157a751fcb364d881f69da91447d8ae84"], + ["030000807082c40304bec517e92e9fc0f8913e515a3848421800851ee377de405e09141a018294cebe0000000006526a6a000053ffffffffe7ead3cf63d8584d458e7ac762af336d32c04387450f1419b8488a9c551c2cf301000000025265ffffffff615703bdd78c9019e2a4ef38f00366e28283aec5f8035c45915ddd209acd112502000000016aa465bfa68e5b7a1557511e94a6c671534affb041c0d7a192ba9919e43b3c0c417d37684d010000000665655351526a7c5b1a3f044add7805000000000700520065ac52534b8f720200000000075200ac515251534adf64000000000000a5eba40400000000046353ac510000000000000000020000000000000000592da70100000000d4840c615069e147b7d38a2ddda50af05fa567a4259e23c25802526bd444dd429c51abce33f00dbb70dbeb4d891c03e0246aa76abc28cbb11eb935acdf3ceba42ba80918a4045913c05f7fecbeb0db3ee92d08523317f60e876926c4b9323f2d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e72b845f81683bd1071201adc9ab2852a74b8f9570fefe205068056d2d193fa0ced9f12e2efcf2bf81717bee25fb5d76eb420abe13f085e396bbcc3c69cd3da566d3f37204225016f53cbdf579aa2baf599ed7fec69444004a6fe5b2bec6b6da82210846c913094c2df2b6007a455c0f9f2d346a01a783b13c61d91ce36c2ba60215efe33c068537743832d089653c03bef5947f520868082b32c3bb6b8fbf9803032bf3a695e1398c0d8b109e3c245e20ddf538dde6696233cc879d1864eea778400a00036dd0d118e2a98177232f32a2bf6bf751b7fa74c7f5d8fa36517fe2dcb8850c3eefd96b026bc494910e57356795d0ea773e6d140c3d51484005f2d263de1403109ad5037691e7c24f393b348358c7b73e9543bf41ea15482e32abd244aa8211032b41d2716ab159b0c4999ac45d27939835f2b538f37bb35361bd936126df7da9032605b3fc79eaa29800c22972a9d3c8e766bb9ae36f44899c26b5cf204d576ee40322bf73ddd1f93936419d6ce60072dfee7e0a22da98f61054b1b3d782ea6435e30201969ca1b036492fce4f6bd74448270764e229ab609c1832183a6b2fa25b2fe2c678289640bd36a11431c78db16c73e649b5d9951a7e4c0a4ec4948b20e47e252e5f38028a4fdac553041750f96b7358d5d22d3bd0af1260c5682be7c927c2bd6a12c8cbe0b60da341641a3c4774be6f4e1ae554c1999502f5dfbda8f3b05d44616591a60f3e8d852b3e6d0e201238b657dd161eab93827147a48d2c2de832662f9b5c6e134ebd21d49755ff3ad383cbf1f7832c1783122cee7f19428384cf2a826db2216fbc034944d96013e529162aff6f250af5e976ba8410259e5767d1eb0ae06f883de416c42e8a379a5c2402e13530e3e79aba1903648b48c0c487376de15b11fce7265e3dc19855c6e4bc7e027a71583647d5ab2d18e704b9872195edeea4404a09c4a3e962accf1bc37b567d000ffeb538411902fbacabe86f3cac6db0301141c82cbe3413b45f39c33294968dc1e4e6c6b20446a020bd37489185510cf905fcbd25e8a74c48afcd02f1f242461a1d316048acbdc68c8aeaad72acb6fd8385eff25c2cd2a5d7ba80570880f8d2a03462ef9208002ca248913f19bf9e72ef75a331fc3675a2a28726841c16708c98c16b5c26d851e94843a8534e3ff361d657bb0e279081e4dc9ff12319a652b46b6e7c51b03bef18e1970c25faae68b3edca3e159aa80af830cc3839178a678f908e2ccb52074615dceeb12b87669ec7d787d40f0e762a8ea0e6d1c2c2bc0c437931fabfe6496e5a625fd19a0e7034f0d38069638819518eb643acaac0300c66611beb158fb92cc7391ea88a284ecaaa8e85d43710a4e3ceb1226371652d0b6836e2e0a3218fd6a9b6319bb4f4bce38b9ccb042cf1bf7167f18f39115925360e56923dc7ccda3216d65921bf77f1105b6ba974689612d8e4654bc04e1e3a1229481ca19b7bf542643d300737944daf8f0dc590d654d22f49e665d0bb2d45797550f0779d6d788f697f48c3995d69f5d3a8acb3aa3ee807db31f488f6263182ca57ea6283a44c72bbf9dfbe67cd42753f8f8361c25a4d3acdb78ad4c871f5f80ba66de66e7270cba8fdcacbbf122a0c940facd22a28252eece59c5c3077dc7e6587dc9ebd2eaee8d38d6b8921a7ba6c93772bd2ff43e02454ce72b2d3a290dd63222c954f7ffbe3cea90418f7683c74a1f6c3d0f24616771702d6deea02c6dfeb7fc52c1e9506c27de0a055ce92d810337071800bafcc6a48e3249f1ad8747aa735304b5700be748f955bad3b83d03835250a2868d28c47f262d27fc03f772211e1d3c1146b7161ff19435eb2a1685eb16f8caaeab124a9d05f875ea111721739f72b757efa7256194bbdcfccc4f8f339d990286d0accc618c333a0c1927c16eb83c0eaa08c410797561d59e16049cf84099530456c4ca1cd600405a325203d632613dacf5f9eea911a15965837ffefbdd8422516a6706b8e7116fd9f8f214d92e38fd30cc98a7fe60cbc94fa1f6591e6197becfcf05627e46fb967ff5fd67956c2966a86ac28d0ffcaa75781f5e3a9c555fb97f200c2b74f80689fdc4f49df43b5d26adce099c0768078612acc3624645aa42254dcd572da26edfa0b024f411d2c27a1812aa8200d83f1f888ec80acc916ef170de15ce9572aa9ed236dc921df841727dad579597ca370a41b72f5a6f73cf188a35eda0fc6740532326cc58f03faaf41bd5eb1f7963a08873282fdc9d0e420fda1cc21c1b35b5bc14ce70bf4f66900000000000000004f4d7102000000000e051c2def64b99ff35747daa63afd82a674d0bfc3c0b5c0f11f862b3ef1382ba283e0f28be55061fecd6ff56a2a7a6759ea2e28c3ab7f6e32b3eb87821ae63fb08948f6b15bd0aa16a2c0dbdb290b07a024a373f33753df9aa64cdba87ba5ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aec3dbb30210a2b7074c66237808152890d8b44cfe0c3707e4f1c00481cd765c3fca3de5926ca36f77f6f208cf033ef867be2f3eb253914b3926100078b12f119b20a67a0e288dd468e2fa497be9cc793fa27fec17856f44c71cd6fecc38069743a95dac0ce65f257ba753c6bb254a3c28bf951fa3066cd4234e935862879d3020234e8c318f2ea44fc7d3d83470b548294ba27e6544fb5a6bbc163c55cf89fe00216fff9c32203ebed17fea9e7416a6f49ced296d0db3e83bbc518bfa9f1a9f6bc0a0915292843b53595c8ab0a840aad5dfab268d777822179f59ab9f28ce03f0071c50fa1e2d512cc2fa13ad5dbb496c64da5ccdb169e578ffc1febf1500af50302031407521d2ced04a6af5868e97b0a2cb39e3c230f8f65daa6578af39ac208d7ae0306b1a6452e69b89e4e2889bf7334398afec2713abdebc0340f772f170b4127bc021cee57a19d955427531bd3f565b585bd8613ab09c191a1d173d1c8f99db4dd5c030a95ed630d3a04fac8504a347abdc5b46905efb971fe731dfc33b62ad7ea4cba030fc19ce0a619eedd515a6f161b03d731ee69ef7d28b594b9a8c1e949b64da83ebca13d950c36d2a8b29354084a0bed6f6c9e5d6b978693aef4da159a0b484ed47a9e4459a12f125652fdd5fbc087abbdd5ed422f77ec2a54cb96ad9c4fcfcec6512f3463bfcc2e94580c2d5fb2bce137792cb433ce881d2b69e6b46da447602d32fc344af3d175f6dad60eccdec2d0fc2bccd8f3d226b1f986117e79140753f9089490ea82bdaaf289ffe4b3577eb2938cb22160d1091eacae77d0c3a6a2a088a969b590b2946caaf2c3e1d606638ec357e5160daf03673ebd72c5716745cdaa69736dc85b73c7eea4d8311c57101ad5c424e1052a21ea9b284498805c7ca926c108a6c52cf590d5683dd411defdc5bdd58400281a8a94906a7f2dbea0acbbd823a6f396d8d8b21ba00a2a2c48a067ed9919dc6f9b120ce7fdba95a11071e0264764ad373d7d2b1290f90779c44a4bf421cfc64472aee019258769b85b5d0ce48a684d5084d5e17f5bce4bb5e661dcdcd9819a8b5e8eb4e50265efa81514e4170a2eda50d06aadda9a01d4ca336de58b0184764ee6600ed194175df74434880c962244f07daa14ce274a8a3c47ce619a9fd0a7ea9ae49414b575bd660af794bec3e48978acaaa8772525809c635cd39a241c4ac42d7da12f1f78f0c0886f7cada98517d10af2da021cd7e6f46502a84f73aa40857ed076c3976e2e058fbc3fb555ece32624c5437d7c64b03dea678c2c7ae804f7c7af2020f3557d986643facb9856f2b2611bea22dc7ada1876af675257ae3d25f49fdd677de428e66756d4e3ea160d11fe3961fe250eeaef27c6dd80d254717580db328de3fbcf37984b1f6d8c83419bd6648e4b569960051b5e1d20f36b3184dbac753da7a22f1b1ee4657172a4991aa6e3aca8eb59290b36cef7b8c02f5ac43a8b10cbc9c84b99e740b2e34034ffb1534eef3760129a5ebd7a49f967579ccb3d0acc8256ae6c3e43fe5c7fc62344c0566707484a4aba3436d7b561008e87660d31d707331382ea110d3f120153af5db4856fffe967d9352a3ec9dc2329c1ce9a3541fef199f298a40752bbc17fdc092ab251ddec057031b057c977edb45f3af588421ee3d6f87d16af0741005ac37aec33e168608f8ebb90f029f86d7309592c095f39eaf1edab8cb870149ca01b5b11473b0422ef9beb769f58ab23ee96844e0fbbd007b0c6b81a62401cbbd1ac855280deabd6132d6a8bdc89f57fc11ed24c4a7b1878f8661eaa0802968b8fac7ef21c4ce810759dd744139f250c62802de072ed639a05bf94c0b7276bcbd955092a393b43bea67806275e8f9c7c7887c43e4bfe87ddaab140f5e7491cf811b87f9a1342a91febc609118aad280b36c5bf6711736a24ebf824ffae6ae8e9a803f35e87a70faa537cad3da1c57b137501b0928616f9d4b60405b813ff107824b36bdfcc3830078d750ca96874eecb925b34046ecd55ac6f7d9d0748b4b48ff97694130bb26b52d9e94cc7850803d5d633e2234585372b75011ba127907600a2d39300b611e2ba1354377b7cc1fadb2e0df61e13f4a243d0faa566dd17a37202eeb94b65c38af4cc3079fac63f5f0dddc0746b1ffd56d666fa65b51484f21af4820a2a6f018b5fda0ae47fd7b2ff9fcc7732bad3750992458c8d8b3eb42ee11178d6d77a5457cd219e10773d005cffbfa4ff9e62e2809e7fff4c3a4d08b1e8dbd2a845bb67ef82e54688ccafeb44d8de7a0d33dfcd44ccf2a8dff7a8b2c75c79670ff13ed094cbcd0166a3ec5288715b57070052e1edea958ecc09530ede6787cd5aaf8f3afc9b91ce16c5ae2f1b1e92636ebaf15c6bae173c30659f41979dd9409e96e8301f586431b0abdf606ad903", "", 2, -1576750550, 1537743641, "5358980c97ce38a14320ee83dd3d65f2c4488178fd20f0814cf2ed174bb63dbf"], + ["030000807082c40304128191a7654213580c73c88c22fd1f2e8c6389213359929f3fe7d82bf8cb46a00200000004526a5252ffffffff6df8108b9f84d17e71cba507e47631955dd38fbd9ed94b892967c3e65cc9727102000000040063ac529ccdffe998a35b0d32341223ff55722a3182a02aeed8511fdddc22d6907798913d89a6850000000000ffffffff95b3d50dc22735763edd7ba6624d2c2ee4ec107271a7b3f9e18eccd531f14e0b0100000009516a63ac00ac53006affffffff0265b2910100000000006351500200000000035353650000000000000000018f92800000000000000000000000000008583a8f8ce3b8eacb58a4c2aac7c5eeebecab4fca2507fdade81e26bd357bbbf131872401f929176e95d9d7fe79c0a0e928714bfdf32e93f8e41a742ea61c66e179bd36e0385465c3c46f04765f91704ec4a3e253c8643ef7a3c374a1a5476a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f15d2ed7a71fb108f2f0740fe1ae07cfa0f94fd6aec43805427621775af41b608ab7c0d4bbdf2212739f3b7f9dab2a9a0e67584dba8e84bbf3aa658cdb06dedf16a9c456805bb52e79cb2167d974db9b1d7579694774aa9e706592b03d7ea3d0fab878c628e8ac7ec0c9201a6e10211797bab9adf80e99b2bffdd28c2a94e870325eeefc8934af8341db89ff0e745812f4533162176235be934a28844ef4ffe1d031b92ab4bda0bd5860bda3950bef065aa5719c4935a4d8c4537f91d9a39f07b440a037b6854e3c7f69dd33789f7e21968114bc8e4bcbb7dcf0a6b95647d20f5e0ed7c10f67624e30bf792eef2fa7138c7b397d84d6203feb8cd958d32689a605671031325ca231768f217c8cf8d9bdee6d4f3cbeeef08631def861b33c2abb72647270309b35423e5d561563c669720c92c897587c788c9f94d1e0bfe6c7db90cc710dc032b84ccb5ef852caed28c5665ba5422cb5e57400fd54fd86e8ea29244e2d323f4030a1b0ed9f9fb91343e352e9284acfab34eac8695af634748bf468af617880946032e1abbc5b1bd3ad7ab7a382df6ddd58b975939c4ed2c6da2e655b4f98664571ca56816cb272554045cbdafbfa6211017adefd75faf165d6a0aad75634697a5b4705692ff8964de17d69b761980c5b31a401109f3954b923b5828f941f030182fa4da1c0a548994a1cad1b951a5c9d6618e7675c37581361f31e748d6c01b3538802bbd516cf688e89d7861e9de431e99bfb6a92ab2285c019a889f37c4bc48f5d8fdfa9a1a46b59693a6e7a50bf8609232a539afec74be5373f46d04bbf7dc0e1c6b645814616f545efb2311d45bbff762c7d5643ee7b309f6f0eb327563ef7c6588ac2400cdd37e442751916cb1905258aa7f7952b5f660f81662b1e7b708bcd2728437a683caaf4fc54212495fcf168f86c4728ae34d52e291439c6b0a8f009ab19e2ce7c2c08f118c6ba6cbdce9ebf95e2fc4e5105e426fc5600838069e1600d4145561955e34405a8e5eed0dc8c1703137f3e4eda7289e79724686e4a7d4470ce63b9262a927e4f82b0cd0edd59001fe8de3490200284c508dbd917d19cc8d73a274057e77eeece1441fa41c599244b7680a8e18093e82e7d6f76f9efde5aa9d5e875a560d4dee3c8399cc9a13ab843c64c45e4e9e52e294a916fb7e9fef82506376684eb7b84f05e56f6680ee44b404dde5739a26ed7af2ac555e7f7f2e325e7777dfb1b74c60e3188d644746a4c6bb092799205a861697de06dce16e1a77cc85a8ce0df11e98e9500ca492a68449885ddc79d569dd449fd0113377e48574903336e3f6bed22178306d4b44e545104d056169bfbc8fa4f9a515a40fd843bb9257899d226ec2e7cf965e2486881a453d053fa3808a5a2bdf19b09fd3c9f26725dd331af2434ef30d4b4da7ed2a7f57d3cfda77933874db5c2a3d800532b72e537cc9394b9531e93587708711bc4ca649ca33629caf160efc6c2d5aede43d8a8601c57f44cfd473679f10ae41816fab6f3679cb6969badd002c0150ee15aadc48e4594b3372165d6d597efe0e994975b7e46f37beb00d99c59fd6bf7bbd2737ad8ecb62288bce018399ad91ac70f205a66147f072285dcd8d89714093edd970f37e6b071c936b39b443556b8871d5e450094dea3b58afa7ba5287c394cfb51f2d3c5923dc17e24ce793b17cd1917297a7328caf12f15ea189706bc1ee6de3df15984881481f0fe6c2666f53cfa199da179ac86bca9c1326e6cc2a0b04d7c90a850943fc15db1ba997242f188383c37d5ade7e6a59be42a412d7bc139cbbc93895ec2be502cc037294fdda537de78b61e84562a107d12faddb86940dc768067cced6875ad3dfb4bc8f9fee4f532bd96ae8aee1b13ae4c1db65a0e7c5251c124c908d26a9378c5aa4d4bc8027f2a58c35c88d4e43d7123257f1b7da46fff298e9f37fa202c7ad99614053ac41263314f6360b1171187fb807c9fd1c04c92ab464e8e031a9f7df4461e32fd7beeb8d9e6df93fdfd5d04a7bf52957c7cbb47ace798edcc6e1ed893fea2e5b322bee5b36eab108b35dc5bf05be80ebbb281de3420b60807020a0e4980471780e3c518a408680826f5e79f1b3ed0e9feb85d146527938f4115d11de98896625aca0cd8a180bcc8b63ec3e9d09c8b2a41dc69b7ba9120ca75ff5c1a45c91c91416f3e43268ed3702410f28eac27272e915babf004a9d44c715e881d9b76156bcc26c72ee2500cd01305e143783aefbd38d838abaa5f2ba6a09b1ad2c293345cf4b28b709c4fccf83bc824b76088e6d12415822f040cf1c3fe7ebaff9c9642e4800d2f57ef700c402fbe79c3af8f461fe8a3b215ee994b1fb8f0f79ac66316ee2c739c01fd05444f76fdf115e620c46a44dcbcf5700070ff80f15be329e92bf83507d9181ba4605", "53", 1, -1520838297, 1537743641, "63a8581730e981fd4e1143d1e46a6ef85cf729a33c086a8264823bafafe152d3"], + ["2b56864504c04a48b38211aab00cc198f99be44965cbd1594321bbac610c621887a65cb84c000000000163ffffffff6a1060eaa807eb73d6df7a86724b13b16b8c23dad84cb3188c32d9fedfcc3ce00200000009ac6563656a510065acbb4cf7ac20ab19f78ecef3837daf7a92386982d413779b609fcc296f5bcfb53c86c08c5d00000000096a63655163acac6300ffffffff676cbaee7d33ffb5f72c82fdefa42fd9dcbabedbd3c44d789696fe2de2145bef02000000004a153d30012ffd2b05000000000952ac53006a5363ac6adc8037a3010000000000000000562a44000000000055aad333d17781a91ef369bfae97614ca4b7c542562c79b793da9953e3f1d1cc59da6e7b9193a87b3f07786993f451471db5a49755a3a9f98a556f5c4b9787347814e720fe646128e5a17fb6b50a1ce6248231306d4026feb1a301c16c601a0d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d5062715c5ffce1ec42ebf81528c5723fe2d1330f31ff2f640575dc514c5c6f796f700f49cb54e73039144a47a8fa940366fba1dc3b610588afdc65ddac2d86841d5747607a666130621b8227949112d47bff166002641fc58bac91b2156838e0d69041be1fc705371c994caee6cf9357d28abbe89152bc4241cb0f135b309702259a1ca5111c42309f127604346a682b67ab84b322652b87c2e571f93ac9229d032651f170fae581d535c44b793fbd53e14d06f66c358ac1fcffd90ad7f746b4820b08a10c16889347ec8f5f5274f18cca3ad273f7701e511d3759b659db9312e0e2c13ce0875a29d83bc05a18fe212bd6c0b86a4d2506ba71c35f8bcaae10444b6c021ccd926f452b10709b9e76675e4d8070472328a4c3ea3e1f72788a90328c2f11022d422a529c3c77365a10422b1a5f86832737fb9c0bf3e7695162e9ce2be9dd60021989a732ff22957b4bc08a9e895a600e014c2678456ad724bc60901f6dff771b03010d7f2cdfe00a3d3680a950f68bd4449efe90766afae7ae4e07167ede9a64bb0220219c12ff75da3cb5e51f28379ab904fb51f078b27fd1525670d8a593fb91e77355f51c14e485e4e5fc9da3f1569d65120300cbc1fa47ad2dbee48356a473941c56fb4dbc929b08989df2ef4ce5d85e0731df4e47180ad3735c66b30387f65266f91f982c33d052d05e9b70b475258c53f9d06c3784adcdeb3a3aa2c1a926c19ba25731a24c7e220d018241ee9fd7963f1f4a4cad231da4ad43d23de19dc299fabc71f86d2d385e1eb73f1d6ad9faf2c89739c83e6aa8d660e486a632a286a5adb63b63c54a5a4ff9c63397d11aaaf32ca265c4d373fe1fa7cc8ad49e67b2948b4ec6c398756d556fd23d24c6082134d8d7cc994fef6282d3f0ab04bffbb85344feb6f29ae0ab666d987ae5c9c99ed181cb79d9fd285c6a66bb3fdf2df48fd98ed15cfb07103349f56592bc53e90bce096b8cc28f81d1cd610ed0fb55c1f5a18074a14019f3c02d44e0ff833d4f5cd56437bab336a5465c34e9ca35f3ffb6e3ecd8c9cd6740261fbbb53b8db3678e72c261db6f34d16b9ea418cf547f02b1d6ee3339796fa573234434ed8d95c5a88e449c58b03f940647c7accd8c6982d41a1cae6515f145c494f4786d2935e32f376f79126a1c51f2c33b1667335c73231fe401ac9d725b00ca7c19fc1d969e5f1e92793e2f198323bc32ff06a9662472c6422aab8b6c19d55a2116bca579771c59f8cdc01f10639a9175f212b6db864814924933966d7d77c45acb7910348c6ab2e650c144a1cbbdec1432c55213121370907014c0651e2061bd16c00c85e7b0efcd70b0d42666314431b1a0e3a73b37ed6bdd32112821a2452ee1ad6be58cf4682f69095804c8e109897eba551ca8b1127caf40b944ef69b08461b20105a6006da08a6f3d783deda9f0fe3bbf7c64991eaa8e7a77a5dfd32358a06431ecff0a498b55abd4cb65fd974047ced9ee529bca2a9b8b7fcfe4330e5a864af3a80632d7b3f442cd5c5362ed7038c88a9e2bc784530b930d2bb5f06c2249f46460a9156c57cc00098891986851b7bf136d218b6eb1c72a48c1aa98c09bc9a1008aae06f893794ca7b684671fd3ce447dd82da16defb3f352f783eb8358e8d7b08300a44d15d434620201cb7bfb7e90bedb0a7191050bb4e456dff1fac667466ff7aeb55a071919b466478f902299bb51193b0631719bed369e83f73d7fd3d63634aedb72dd4ccd207f241c0a9773a2641b8e5086c861800bf3162c7cc4b111f2ff359ff76f97b3dbf3765865e466715f3389a161a7705df54c22011144152c413f2b6c9be314bf85e64f6176ce0a496e73c914a7f20ca7f460d7f654919b1eb34b98a1eb56ad73ea576821f3c79172cde18b0ea61eace680e3ffb240cad6b1e63ee9d7da954137fe4cade5fe7cbee1cb5b2e8f6d018ab224571d21ebefaae9fbd167d9e8477be8edad4ae22820303dbac06de359d0cd2864efcc770be567936b2d59333fa7a86e714bdb0c10564a3e3c39b0b7dc9f13968216c12a4e513d859b0568f1e0b2b5e7718efb98d0f3857ac12d20a27e13554881f64e8ec762196324f7b39bb3c79d226d06dad004f24ee081c723ed1b79e0efb56dbbb71eb6e7e312643f65c79d6305cab57b9a200cda092e88e592b864c809c4978e2bbd2b180a57fbc8f107ff16725a76b1fd7eb025b50179b1bb7313afa0ee6b6f52c5f8b31c715d904239ca3031c85d16613c9524bdbcdc0d69ae9dff6f0d7aa7f2d60b2a85190a7b764ca50132571f643dd5c7ead26d39f524aa65b114e6cb6d4117764c8e106f1756623e3107d69958077425a9dab1dc72189714184b659a7b2d7eb314e4e0e7423db4995dd8b2bbfcd2eae1f0cdda6b798e7e59f6ae9a31d879c8d100340ad937434b3603", "5352ac516a", 3, 1584858262, 1537743641, "8d8698185987c70c85e8763288bc8c30e82fbeb112f52844f4490ae379eca38e"], + ["030000807082c403027eb28d3c058855bc67d274006ebf0dd23b7df504fb7b7440668dc7d2b5f531d70000000004ac655200e981bf82e31c67ce88aaa1439077ea24cec655e56a75db8b0da8af695a7baa9b7e7f4cc303000000036a6a6af222ff43038ab93b040000000008006a5365ac5353ac120215050000000006516a0000ac00286a50030000000004ac6a526500000000870d080401000000000000000015af0503000000004785289c23c0159884229298c2721b454ea3d7ad708da9944e3f308b8e24021f603e8066ce1c395a18cd6e415364ce85e7f86bf23d4bb9f40fb2d0ad01a4757d98f1e9702def2eae12cd67372c71cf238541335853acb22d8d83b8a8e1ddb3380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000053fdeac4c3228caa0aa2d97ae7aa21484c4c9c5f44113de9d9673b816201b06084b650909bafa8753b5df2b082979155e2c1100b87aec13d372925b60a67bd029149c327f8de4c5cc245e8dce28d08a1c38fe252b8047f19b8d3b7e0c3af7fca4cb0addbc2d9a97d5246b742f148e504ca1635ad27ad08c1dfe9a33c872a21a8030a374f590e064fdc6b2d406b269f72c0bc496412ae2c9ef9caab1bbac935285a020f1859a2e9986c06d34d213dc35488e030e1ee7d84e28cf1dc4874189ae985350a01172f653c32c738ff93abfdccacc12de23debe99e73721d52421c686fe6f1a7a983f086e97d22b1c0e03a93a1334083eb9b4bb581c0fb545e2c6a5a98991b0c03289736d6516e282dd5ddaf3b8d23cbfb01ce617bac93ce53316b3fddb1b61bcc022e81eaf2117ddef3625ed47a7621aa42da95a36c91f4240be50971a8f7b97ac8032fc0f6a4e2836b6d1b472a5bfdfafd5cb588ffb2fa26afda9253f4e65c7a859c03091ad5b15c546d70cddea9e443608b382010737556eaa3674b645b085e8b18790312b73b195725c1abd75d1a5195d8c39f46baa61042df85ac5c1acc084abf8bbe243f77163518ff4c69ca1bb0751d7473fff03443076fbcf156f36aa77e1a505b2f2b5d6e1b8c35f25a168a9234e5203e36860aeb4b982b941bec5322294eb6a3151ffcf12d8e132f15fcac1613f822925ac3da7fa1c07c8b735b1323ffbe71556e0ac73a67089233a63a84b4fd3c4a5a1bb2e35571c4a641d251d31a6ffd3188b275f88bce0391d17038486af43e4e809087bf916d50c483d2c162990a9b3308ae31353d98310b9416b5ea9d95cbd7623ff17c7ada0c7534cea7d181aa45fcc3e86e997932b6858e2458560fbcd34b07d2ebe7c288f9755166b159baced86cf7e0e5b85f7100e997b6c4458947bb41db3c621a05a13f0be6eadba1b471763989f03c08a87a60a94b12db4c5c39137865647a7be95d7c61f02099f7774dc7c6de49885c1bd6fc83f9d854440e5ed466ba985cfcd32a49b54e5acbbfeba1141dc9477e33c963d733cfa64699253d4d36de94cc885a5bbb9e294da18be349514ea70c665090bf2689b19184fab65d6b4e789cbe3d03e3646ce27a24af8ecd24e316051780077c53ff1ab4702aef9cd400ba041bd3d46c0a10d2be816295e62fed2483e0dbc0bcf5f000bcb62a79614aa3e3d145ce2103c5e4b6a3c1c650482005650d6c3edc3ff8ee684b7d350bd46fa120490080c6906950d7e903957d6ead971dfe3b784d79b06b9d13f5c1a62a8e2a775b82e19a4477aefbb7e1fb6b9769816f22f287d7f5937362cf77cfb9755efd197e079f4b741a7e1aac4f9cb1e1d6b865901de5bbcb530776d80376afc079b8a652fa93e6eb8963e10d6c63977e087477338b5336b6662f17502eb0f6a96aa05b382cf1da20d5e76a1ffe16dbd09aadc79b1a4e60df3d50d0b0cf1c6a0e83be0f5353d7d1c57eeed076e4d7d3752f69fe37bd0fdcbb748524f8ab90bed22770768eff7650ce7d4ee2c42c3542818c6c17c5bccd51a2e29c94bdf1b530e0d222c57f134c5fc2f27963d087df6c46c8f897685c01e2d06ccbf1d7457e9b89e7a8e4f8e384d9d53468f84a6a245fa8181b3cfd302b585ac7fbe5762e17e73f6db9896299072ce99721d551422f53eb5b35dbbc0f611e8dc1c12a17bccd6e223dac9271195bddfd4d6ec0c96584eb7d0feb831f0c8e936b92943a71e47795c099dd002bf3b5784b521f085d951c83c0242695ebed3f68ca857712f8dad1cfe0edc51b241306ceaaa84a434e7269d2f9933a77bf69078887b4c66633d1e6794c248c43a091023d92d4ee6f5e803e42ace4052584feb7e98be04944683cf40fbd55030663e51b0865172e17eb6d3486bbbd8161d41f5346d51b163aaa064b06a88ea8d2600152c8a20f1199e5903cd8c1d60afec0a20592e2bfc43cefdad511a313ba7fb4aff2c88bdf184c4f15e96e8c5fa0cb590f216c9b4d925bf40b3103040992c80855d71f3fb5b28bd315e7524c1451646a487b4e52807f310b2360205840841e8a0176395e08f898c74c44a9c79121c98122c7e0c8b930bf3ae50228592356220a6c5f0f66368bb7d6230a8136f273f8bb41ddcf0bf86af59e091d10a2fea158ae6ea2dca4eb2b605b3ce0fd5db5bdf1e7032f60e68fed531db53e5260e8ca67ed83f88599945aa30ad079e30a14f94b55dae18d6db0aa3fb9192c0d30ee04897976cec604a78ea6ef0e4712acc740a15dc2bece4403746ea0255e90c690ba60453588b5cd57e658d3daa3a92c5f0fddb50f4c252cff05b6d896cb12d076cddd36c1bdd5199e07563fd97d2fddbd5ec0eb81d1419e328802e9eb6130ed93b360e5c5258f0f21f534b860b7b2ba076bd6d1eee389f611425dc63cf3cecc5e61a54603", "636a655163", 1, -876018883, 0, "bd288970466e141c059a9674ca794e53cdaddf8752c5493e54c48c376bb01fd2"], + ["030000807082c403010e01ad241abbd99d89f0e7d714b1519a1c8f7355f7abe4c71f4065da1a11f64001000000036351acffffffff0362bd24030000000000524b91030000000004515353529dbe530500000000000ddd5bf50000000001990cc60500000000000000000000000099dc0bf0642e2eba96890f74fc411eaf33e95ae4205c501ac0116dbde44af8630703b67b6677c640eb7f2291904878614d737ef15b8684ec29581e0f67bc79edc64c63fcfc5e9e13d10233c98bff60e0afa13a70f92dded9c6d401746a5757220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aca20c090062d3e67e8d6e5d76727ee04dc2437727f3841b8c0e78b28e48d6776f152265751dc84ae1d679d1279fe3e7284be00d0884dde294d1f7fafc96ab989e4fb406b95097a93fd1c65bac193029e5131c7e39481a681822c0aed909629abd1362b2b49f308da4ad02ecaca2b826238ff594d2580307d3e111d267de56022c19cc2f475f5cb9580f09963e50b4f76cd60df071a88641a451aef6547619b3032d56770c0d509f48bbf525e2e790a8410695e10575ec29b434a8be4caa1938fa0b02d815ebd9b05c5ffc3e91d2b9b51fadf4688c6380dc6a8fc793baf931404b6aa689d7153d85a96b0bbd7e10c2d871e74e4470c1942a9eb63a9abde1952cb9a3030cf7bf7cd366d12792265e7ffab2aa222b822e105e3d185f74701deaaa3a2393021c4839b8e86bee540c80d5e6a4c4945d97a74cfb28ce826383ce2a08ff79861102228627aba0065e62f25972c9af5dcc9847c9998ae4a058b2c5aedeed5174714803094c409c96c2419568375e90e8caaade808edf77e100373e1b009e3a1df94ae50314772c4fcaa179a9ae171dfa4a871fa81ff6321552ba5447f9c3b195fd19fa9f91fd8a504987ceeadc89f24d9e258e317995951c90e7450e2f38074a7ba3ddedea25b917cff05d4dab24d0ac12c2b3133886c4f24f3e304372dce435c484f5a4cb34fd5325a1f8c5b9383b202fa98fc44ab8f43a18f3deccc82846fed7337fe9daa00047b234108e8f49cc1cd6305aa9ca1459734ece782e8f020761d37230fc1423c54614d4133e721cc320f3cde515bb92f018869f177848680bc1e9b781b33b5b1f040501a03305ca558dc8ac675fadbb1f9925e0d97731ab2a5a7607562c6efb1f257a2cd504d51c5ec69fb819fcae0b706918d94c8b5f8520ff71cac4f73cd099b99ea815e64647bfeb1f88a5c2c2e4c63b651c0b121398a6feb579ca3ae61be8c507babc1f5af2c2fd162f8b79a9e946281b41747558efbeb087cc533db2594f6b390e0bff8189b283997066a02bbfcc64903566d1d7c659d200830356dc0eb279476487a127673a39691b99f7dba766c31b7b74fd41fd4e998648463ca84073393ca7aa737a6066ea30fb1adfed6fd69527cd43cefbdbd4fb4bae863428366d9cc5de534ca3e7f1fa790b54cd96084b4e515aeefc50aa3ffa90f0aadcd728e35c335e07289c12539e62ef385ae87a48a8a39ab9578ca615cb562a3fa3ed7f288d967ba1a5755010f1f1dbd9570623b3bc7a8f816f553c4398b3a2c205b0d2bb0802aa5307082a222fff2a8a568b92b16da0b4ce376cd8bf116172448751110b3bc900fd77b528eec6160b90bc508bc0f358c70b8dbde6656a24692e58a8b1a2cfb14c9a6d25cecf031e81422cc620990d080fce5b2e964ca91a80b57d5a57f3e511e00931779259b10f9a39393e826f22452c6b214dfc480f6101240c543eba5e0be6eefff9767faf7f6d6a6fcf861762b718a630bc1c2a413ddf8aab66c538bf21aa1e040ae704a61b9f247e6dece2123e00aeb57d6c0b8e1359db7c3c2c445adc0c16cdd1f5ba20c1a53e710b103da7e157dc3509af6db022ecc9130da2e08aa1bca3bc3eeccc8d5b7946fd283f147525baeb92f9ed28ed56d5bfcee56dc24ba432db35c5dc1f59f5fb70dfbc2c654d9a192de543c577d649f52b944d6b937f092ed3ab20ca31424c9112c0e42a7a6fedcf2261196d74c972ab9550080320263d753e84e309365232b13b6d2bafffade8425af1ff0b168a6aafdc40d7a15645de8b2342679c9b723ba1fd44f3332697dcd47a570906be322e980a740e080163b93e465bdd9df1631688eb103d5f59dfd8eda26d315d3de6c1bafbd20a1e09ba22570f754695b1ae55c204e74524ce6041de4ba3ec461da7bfb70c027d7116c53191466051046cbda277199ac563a1c28753c0fc6f449151e0613a9855658ee775228e395fa325f0491f30e1b1877307ebdee9e75dff8b64aec58ee2129012a9f71893a4d870d38328d4787849673369b8d5c0201b925f47721596539c6e95fb368fed691394498e985898e7b87e1fd2774f8cc82e365d78b01391d5f6f756b66bdd5bccf03e177a745a0b4423ce909ef0ecf75b3d3af79ac2b00c2afa18a7f3b963d362f46d17bf92c8dc997c88d71377db6b7c3d8d11136c4a0748eaf7f1d96c29c9246ab526dea84a91ee89877d38b61c1dad9073172e31dbff593b653eef3abf407d93507f16ac22b9c4806345d6d73e2f4fc48dd80ff46366f372de0d6efd358fbb8300adcdab84cbcaad807cdd3db2af67c2f329b4b556b5799f42e92c554e5264b8a0e94e585afdb7eba41767274efafb3d35d3e39dcdfc91376dc6bbe7e6a5cf97e3bfd7f39f69876d125ced9d7609a9d7d521753a9879d990f5c1d9e268ac84fc7a4bfa96a71a4bc200", "63006a63536351", 0, 704890566, 0, "9cdc9ba9fd78f23f3420953f5403ea81d7ab4f1c4bd69ca136b9b4e4d4eff5cb"], + ["030000807082c403028c64b32847bee3d494a54ab09d77113cdcf2cc9bcfd3b8511aaee3c9496b737501000000076a6352516a00acffffffff0900114f53721a990f64bc1eeebd1314046f6409d8864ab1b8f3c5a1153b77f40300000003ac5163ab68a9ba01c292790200000000056351530052000000000000000000", "6563", 0, -395493780, 0, "7eb983804ac7f9d20b5838f566041c4a65e6ae474129e7702400a0efce4f4c48"], + ["0409a15801d67428c04084d95b46d1c9972de21f5fea84cd619442a587ccc79d381d603fe803000000016ab0b2e5b702664c62030000000002005391f2f70300000000026563f3ce981900", "63535165ac5151", 0, -430015201, 0, "471d8ed0b52592757d38ace04900a6dc0945d32194e43c904ee485ae0643769d"], + ["2acead59043cbc85212cdd60306aaa5f9503b10002b68a762b4d2fde0ea5b5d7e5ef16e60f0100000000ffffffff96d1d5a82e09942a50ee1bf9ea4c62e80fda035e091018f7d214e9fa42012fb503000000066a6a6a656a523f3622935724da3e91500ff766e1c7c8d972663e48f0cb3673e6445ca52461b83c95194e0100000001acffffffff25b97af44b14095b60eb89946521f1b8313a078eb6e9d4eda195828382ac46120300000003ac536a2237449701364680010000000002516af5729ab803143562030000000000000000000000008e7e3758f2e966fb777cb9e30e2657e0ffbb669cd1f69cea0bf938e00515db523339e10496665e6a79a563d2a8f4057ee7ff2423ebb664482241ca6257339858cd0a324cd66e47f697882bfce73af0a6fd86ef1d09e2664d0ba9d0bd94c032f7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008bce670bc46d35b750183398804e0bdec16bb2bdbb4e54e741b01d1fd721dec58e437ad18a9bbafb300933640147926032a6036d42500a65ecf12a3039054af251a5447bde4b2e8c521c3731849ed68842a7a2d73477882461daea75b86b8f11fa4e6e420477b61356afab3ea35fbf6236d97fa06afd43e0d441dd74acabfd9802118cbb07d62b9c2fe85360f0f633bc483ff9cb41aefb0338528fbea5294f921d03213a373d9544011a3f44d72542d7d98c9e18d078a89b902cf321514fc0190f670a0000390c48dc73b873e5a6425b44177c6cae4dfa4fc69148694ca366073c95ff867d540704352eee3f677b419505a2893870dcb47001369e7b83a812e5a4a052022a68abda310dba7abd422971b23798876ac8f691b676d97c9e21763377ee69e3031eff28b479d4fc564bea6de3de78ee1ddd639b184fd4d0a138a8762071a44d5e02057efe477eb8efd9ee113c683a0a391eda100bc9723877e18716a17425ae5e430326219929a137b5f8f0ec97de529045eeff60a309b84fa1fe6733600d2940877c031e15aa2cf30e64aad9e014ccb7b6c1f4e79e3cf2bb7f14d453aa7aa294e4daf5978893b7a7947520824c057cf22d88c5e382715fc8d27f58b4b56cd34fbd8cf893276f3c6583ff9b02623ee9070f1d2aeb95a91631a341baf1a9cdcaa24d9ab2ce09a7e2830e995c03eadca1cb47b0f1acf9d7da1383d6e8c0592074f90957197ff749882199e4586a94626a71dab75453daae4ba4ea65c29920f005421db81c1d4451f99f2f7747e8e4df8d644ff7790607011d4b5442ea583c4b961e4378e6d441b4c4776a53cac6c5a2a3fc225f554442b6d07cbed7967260cb7d5e5b62eb7e52a8143b829b363629b77ed64fb7846cea530aed5d335336fe1d72354be63f584fa0e7ce050852d740738f64bb0306cf3e017dfc4aad4bd8223cabdf14d012a1574889fb5accedd89eacb0e44a9b9e8e87033383c9649737707b19e201188d93735fbc2c559d99b88c5adbd6af4072640741cc856a1d9e51b2a6e7bda724cfae88f84c352dc442dd1fe9d317fe24efaef71500ee51553fc4b9aba756c42c9b4df9cdc733f8c12b469db8be2238a218d47bbc75250ff121440b3809847603f746253b6d19a644ef2e6bcf64b19872d823d678d88c6d1894487c162e177d27cf9ba685768e46e9db5365c092991c88c34e2a5e77b45c09cb6371a81d9725c480cd186d7d4e6500c36bb500f028db38ccf36100c682f21d264a258f5abf5e7eecd3f11212788b2b1e0b02a24e9f275fed3edf3c02a5880f75d8e4ec90d8dec9dd48513ae62562cb18bba19f561faf8f05c591e4e172e46230efd70d163a0500d73d775549a5b2df82ba50ef8091b803cb0eaf4dc31697f6856f8125389875fe8edceb6a35dcb2099d360b6a1a2d66276b2cf013095198565ea2b9879fb084b2d7f942548dd01edc91467904ecdf99cb16159ab1567d5a3a6a31d919f321ece78c3ff7d2dd2d75e9d16808eb7b4ed7c3baf174c1a6c22eeadfb6648126af9bf6ddadfe88aac7f4bd90b2441b3b97abf5fe3c22ec2a5501702a8cb555c5d9c40d1ebdb61c02051c7f654f5629c485bcbdec4d04a0899d135023f9d3a8c69d7f53c1e426803a409895c120359a6225df53c03416bb28826d807d3eddb723e189c3b16bfebe2b5b49ca99471203c5cdf71a04a1ea7fecea9b9af38587de38de00b2953a3cd315f86bdb1e43ba8fe5e2ec5914f0054702dd39f520d8e1d9c8b37e037c1fc68bae01ea2d493ef2cf50706f0b2a87622fcd54ed3963f2c9a88680ccb14e84e83d22d1b511625980a124dcf683af9ae05fecf8cc692e6c449d231071b97d2440aabf136b056ae3e7cdbf269ce545cf3697901d7367035062ed06242d61d00a020a9a679191dae0fab9a12d6dbe59a077c7cb27d88cd0a9e893e371e07794fc41f257906b8a972ca59804e6d63bd674a227711e101e5c783911c01d54e940c396da0eaf76914f9690a87e6a2936ec1886e6501e0e5b699bf19b4ec8d50c5e578da3ac1c55791737d39d0b228435641507894917ffc70a6a505d8be6bc15f7771b3e85ada30c2af8a8e25baa21d0350dcbad407349af3191e112f1732a6c6329c24106c284d7f0986fcd92ba5ec737f00ced044227763ef0e03cbdde233c151d071c4d31b8bf93d1b6a14107c408008b5d34e2ee39796952aa40c475f072efefb36707a5f5cef3f022646269cfd552d888647cb3e7ae5cfac65fe86206e131040c2526b3232442c0fe24fc09283e9083e487206b0100000000000000000000000006c334e1c9a98cba228a9e4898e1c5d6b22323591c517e0eb40217df0297be0d3d08546d47361b6b4f4c125dfb105f69348b6f2b9137d73ba0e5353fe3f2b67fea34b2842d8acb38030e5094242e39986ace7215d8773c1b15062d25212d9d9b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d85690158661c768a90c33f4eb3fcb9e35c8a4c001a5405c9d9198e93653b2322f67636e7cc56e2cdaa370eed1ff7354e3eb35f6391c27c704c6022ab6100cb8edafebf8b5aa5290181d22fac0664556ade6bbe6975977ae4d410b4455c7f4b9ff54bc48183fd422caa119431e02c3d3f4de9ba31e2cc547155386fbc57edb0325bedb2352039a0fa54de0e9461315abb3f9c20f3b1162a5f04ee0ac8f646210021bf704da1f512bfd39d9b811ede033493219e9b47ade4b39218350806e8845800a015c39edcb80d036260971c358c62d927cb3edb7cb7f02e6f5645659aa24c5ede464092c37717541cc2416ab4b479d28632ff575726c7416aa63a2edc61c33590228bfd67f220a7e5ef36b3e9ffb9365a964de33f69c1acfa1d3193800f38d78b7032d356ec8c7197d6d1181730b51cbb7f3b919136eeda0e270675cf061dacf8f2602239ba29f01971dcc25dbb0b356dec5b2de34c07f8671f09340bafa0c3c0f1fee0221a82815c4a17077bff3b02caebd18ea958391e9e8e19e26a9904c31c3c296510219aadf057e49ef4fe2e676b57f929ba527aebb0e11030a7e0347bc500814375bfe62dfaf4d29d4e7eddbda8d09f5be73d5279373a50af03a8b5447269c4067ae5b6131724e97ea732be59281c8a5ef8cbdbf40d341dcbfe954df19b7650129cd461343709af7d664a95f6a792b9e35f0381ef4c7b3a94159c743ee44ed63400852ea7aa53124031d4fc5f0a178185c03ae3b772ed4d79469b90f3f17cd13db1f9c49f7010bfddc241d5300982452d4586e38ac42329ae44c923acbf0f4eb9dc91cf78eed71aae124d409aa289d1df4e9520d1ba154f7b5839cb1c63814500039f7213f08e0d6347e62bc94c89a5a88060d309751fdf01cfccbdcf8a195b8c19cb5557c7c4baa0219c9b316b98286660a72043fe587f5f2310fd162f4b8b6266d893956854e0d7ab4cdd901e1ec11aad7de2c1c92a0eefe068f0defeab9fda562ef4037dc8fc2078ce4b451eb873f60d9a2017bba4c4bdda6fbc6cbb20f428ee64d69e14f8791257c44313eb674bbdbc3befe6798d88f3a7496520f8e08e723c9c62b91c640fe3651f689370aab42355aefba93e1c6bf07ddae66018bf0a4b626d716bde5ba4df1e4e7f49a96265d362b530e1bced5aef94c6f4800b5ab5a94e798d4a56057e43ace585ea2517b5996b1787d403358cffb836b0981c10e67deb292caec08add8a2837fef249d880739bd59acdcaa360445c94137b8be75856ff267baaee4e2c97d0462f0a1e940a541c0e6f2523a569f7836a970d92ddda66cc849966dabb794007910ff361bce1e62ad324404d6a3b3b0dd72777e6e55da531a6ed351da3a119d2b506d54c374d3dceafb52e0f973e9982d9c882807922fb311879409abfa5a1ae70254a5e2fd59d0ca354f2e5a38f1c54196eb8db521aed9f019e457c52c4edad209f09242e7d8b44c69cb652458643c56afa178e8e2aa699a1a5cfdfa63ad67d6abc0a8a1eeff56ccba9c0ed4a454ecc6560bd0a57dbcb842edeeb71fd7b8949fff2f087307fe30b65d78f974bfbd627001981fd967c6a357bd04e4f967fc85fec355bb73c635a500570d94882a1ef4d7aeac03229bd4d38c84d38fd1bcd1125a8fe49a90b925144fd66f2d8ba4fdcba91898ab419dfa2d34f83b6ce4e9301cbbbebbfcc34d8d3d46aab8b6201ca882bfcfdb057274f3ba46f39b1db593396059e9a3ce6150ba8a4ad444c2cbe51106f8b6d7b9c2d9ef7205faf3ab68bb5e0b5c3fc231fc060f747d9fa147dc18b7215cdc31bfed7b64ec1fb4f6b5b76f5a2d88ca63dc9d75929ecc74f7d852c3822a89ff35db5de928b39c464bc2df8c2f9172cc879403c03991ee14dcfcf01fe4e1d8ebd583329b57fd243bd4a6250c97535f678dee829f9c9b80be57c91165da6e62ac3da14b6c400685476ad9e7dae379b0f49e462ccdb52f888cc8acdb648f8c4f8e9860b5c0076687049c2a883dbf1ad7096dc75c21b82714530e4b21eeaad7316b9e44ee7e70533c160dce9172096b36b4418e4f631040631bf69b55f3a31aa558bb3e6f7622215b431e720694d899f623c77e29c473fe8830ea02f64b41a053f9b7062d296651d1aee85d55c7a838218de684b09cdb6320cc85f25a5f9d0b1c69666afb0e8ce3ffdb090a7358f7ba4566b2cdf25c8e4bb438fb9705a6011d283223fd69136786ac42d53f54e7fb5fdb6470a8156b6715f2d8bd8f45324dc1d8410ced449d2f5f3a7b981ff607b2f1abc46eebb3afa1abc5251a000000000000000099f0960300000000db092c2ab32ae1f2ecad853334d9bd5f0cc0d8267261ea1a6ed5b19a5376c08e0bc83176b2a4732679163cdc90f93da570de57dd4d8c426b788e0b82731b923a6fedddd592ef959aaa1c5640bb0eb6c4ee8b67c222f406c193fbe6df03f78a6600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8483f021d17c5161d673e04c914488e7c35c2011779682177b13847e8d660048191639e9fc6c9803dd5f34dc6e10139cdbc47321e63af8c4ee32ffeda5da167f7ae344a384dca349180cf82aff2286f3c38412eee2b7b5af5e6a0754c3000b23fd81e023fbcc737e38485f0c3b95271993b45c786a299a434b1c83011e18d66022ac45817c13b656af5b5031e3917f4cd2d2fd73f90b818ad6194b00864014f1d0319dc962bba7fd2ad54db39df6ee020a205acf875abde489da6cbfa31e9cb7ac90a01cad4d0685b7bb24c91b59e8de780c29a65d0e194dd33460ae7fa5788eba6bac50c01c7ca632f0670ca29fb5cd7bb2d07fec0174673f25588b366af954a8a92031708f6848190553a0f3f96e56f77ebe1c7df8c7ce507da46b18cb2309da26859032fbdd1bb87a07cb81afe6161115ca6509139944a9d40412c271638e92ce401b9021db4aeee5de5a26eed099ed9ac47d0c30f58f8dc088675e411fd477a9ea171a8022c3a4ca9e5947d805464c59e401d67344ae073667e446f77e851591e22d1a3fc0226d42884c0fdc8f61646b3f0a2ddb754066b6ee8a945b12bdb19eee8eef793ea4bae3fc5cafbb17bd6be09eddf1e1cb0445f062821d13a01d75f813b9914f2115c56b2429e63435de3f14d01a6d6e2f9935f223b979d180667a8786e86275448977449a2c49cd0f866a7180399f740fbe290dea0b08708c8f28726762ff362a43d0e45a31c8326ae84bc0141e86edacb474d51dec66c87afafd98878119a6b98ab13efcaafdc2ca535d724c05bf96910b6f7e4d00e53b75465906135735d2be1b85c72666dc76af93dbda719f7356be14d57bad9fc6e3eca477230220930a4817e5f337617bd2e2ee912f171dd8f3b69a6a8f417369f2d8b228562975fe031c6142dbe53613e37495300dfc97b9d8de0c0b6c1db77b385023974d00495b3a484a70109257d869e77b71674298d29d1785e7084368a45db5ec4ae5cea80fb5f0d2c9a39d372ed16fe5c188230d5b5b319770f695c44658668ac9513d465c5e8a209d72153d809c7fef95b541a4122535b310182cbfcb917dd6f0676551606add64f229c629712437920e9a284f329c8d68926b99413b284a5af75f2d48cd777e211bd59e3798ceec65e16624ac3cfe878de432b3ad5180f348758586c884435dbe148564fac7a7ca66c06859a410eb1f790a27db648072e309fc58e659e1850ad33e81323dd947e2f6c464d58e5f58d4f7f56f3e430c102db66d82e085b3fa9a010fbde507ca97c3d6bcd0ca72a42ed10f458a4d088a0ce80deb2f56f0739b039927be8fecb13483b3b978422cb991ffb725f198a436fb1aec32eff15c51e8747349f77fef315f11119722df9662c01c7f008ca4a9bdd183aa33c4e88323e4e08349fa5a5646d527ca269255446e45e8284926c69d19d9766798d8cd385dfe8049c0d946700c490a26653ad3bbdeb26616a8dad6f608c0a5183319bb433290db7d8b49061acbf4c6fbc5932cb30d22fa126aff94a6216d7182d6b5f348871121dd8549b55c177430725eeb8909ef736b2ce068d7fa9859087ea6eb5ed74463f55bbd25ab587d74f56b5bf6d4bd3ff851167e0b86495de0ccced166e52774325123c6fc701a659f777597c2794c653bc150be0821d3b46603254817cb6da75a8cf74c70f6d49a78d997087a51dcbe5b9a99e1db8cbbc8ac8c7822269b822d9bd18ac3692d85804f8f560f7be074654b4a0b6a302e44fb303ded3d5e941840632163ccb98feb1aba2ca472f6948d41af26b991882410f1bafeee2d17f82cf7fd4fb70f10661181eb71ad9f79c830f4584fac7074bf2a79cb37277339dd353b4a4d38bea77385c2ff6c8790c45270e49be6eceeb46beddc0363594aa53f8eca6b1f057b90e4a175ea5e13f426901f81cb0acbad82cf1d2b219b77e8bb9d01ab879e4c6a00e8783fb312bbd376fcbe21c99e3cd95b879f33edd25e73e5654403a65245344c60b3daba0622ed6e0e050166346f81f44c832635b5fa929cbf437a5ac34b6993d9b833c3110e08d848da990ff3845dc5e4f4da03335488be574b61b6be4f92321b330fc7988dd17d673349a63ad23bc4ac404c09bc55e9af64fa1d1784f6ce71da16161944e16e17bb83893fe33bdf9df6fea370b9f6d801def8c927283481e503f003f45151ab433a96f9eb4e1d417170abe2873186f81512641d42ac8f45655a1dd4ebad0febac5e2e674aa7f0935ffd2d2ef0ab87d6b3cf5e78923a1340431d94b498694c3d56023cc8b54c83f63b0e0ad7bfcd4e66c08d25c3f55fd4bbdfcf7b539cf0944f43fdf739cfbd985db60530ad0abf0f3acc33e7a0bb83bee2350ec0b5ae5ff2e6418f1ed5a28def8cafa6116dec2fa1efd98db5170ffd7d6a8b9db00542247045ef9694f222b427403", "655151", 3, -1123167027, 1537743641, "05ab55952ddbc5e431ee2a8375a9f278494f840b9d5e637206ac5432843b509d"], + ["ef720c7504249444d2dd7d90dd8300d42bc5f703b08a8bd49903db20430c385774d3ea6570000000000865656a6a53656500080d163f0fb85c938b72c70f05de60b6cdc7c92e149085043da07d988dbd165ea76953900300000001acf94a949809f35d88f4d25b55ee1118502242abc1080b5a2b91448303bbd48f87a5e458d80200000006526a5252ac63ffffffff0fe03867f6ecc14092c60d32e3d4de374227236083644e51f67eef949742550a0000000007006a5100515153ffffffff048f9f3d0400000000056351635153651fe20400000000066a0063ac52639ab8f8000000000002525197bbca000000000009536353ac636a51000080756e6e00", "53", 2, 1472115369, 1537743641, "334af7ee648dc318475dfc27403191d99cddfce66dec1449c5bcb93ea8def845"], + ["030000807082c40304b865e34f9a0cca30a1c6cfe13c9b19f32caf5dabaeff5ff12ff1e8586e996f230100000000ffffffffd1209d224737e3f3464357394f4d9fc44a66917278253ab078f6c320ab2f1d1e01000000016affffffff7ebf704ca9cbfbddb7509e57cf0b9db8028dc23ae1e0c2570663da97fc62fa00000000000363635128990280aa993aebbfd1bee61ec2a1e315c86fbeb0d01f7377429bde126f8b08714b230b01000000046a53acacffffffff0351ca06010000000006516a5253acacf3a5480200000000065351526a51514d77ba00000000000463516a538b21ebab0000000003000000000000000034013d0200000000cd032f695e6c3e1e3d47caedcf137d71c6adea7030b8dad307752d3d61fc1b4e7c0add70631e835b164f1a027b904a157bd5623c1d05f615ca40fde8d0539f0a913312ce71ef5496d66c0a381fd7073f7bef1423d50a74364fa1c59e4e0dc90a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3a50d0322d0eb7a61bf7957ab494b452a1b0dace1ec5e293142e6165ddd3977fe08b40467468cc33fa006c9d468064f1e2196129a0e4b80997434b0a7459ecd3b1123159294a538279f13f144df05a2d3da2438c4d80a2dde532247b073063f2d8b089f8c26323d1856a0a52020ed95519544e3f3d73f2b307d8f311402c94f020e500115ed4f3ff16d16d9f6a21a78fd4996f575d3589afe3934a5304eaca3030200c21675249b6960f6023237397a59e1486637b627796961cd03ee7969b207800b0330706a0b9c9f1492139bc5ec162ae4495c5a4927ba41719a0f92e9340d1d09505122438a82ab76c9555b0ccb68e64091a2b3f425adbb8b9b66eebe3dd548dd0223174344a3bfc44267f8f9d7229b5f613c0ef717016b369f7e57ad024d886b56031bd0a650dd0c1ce07bad8080b98b66ea445ad86cf892bb70e9eeda6e33a95ed00308019c5ec830e81f967b834f6bb7913a168f165460eccb68617c727c7b995c9c0203fc65fa4d9344f6ffc41ab565a95f1edbc8e7151bf87254c5ff9d98726566f0032ef91519b9c4c4ddac4fa4d1fecaf0e59a4a2418f6ca2d355e5d2b92c6cb48f47d03afb62d01c9a661338e60b45cb935793bbf876bd11937eb50d1d65df7d5d6e201bf7fc64d052151bb508ddcbb1ff5b6f66955ea8d7dc1e6b3d718a1b62a316d53f07754645332b5487b7ffd3dc538c368bb94fc9791927f09d237b59519a32da4cff6c775a98488bc990281531d8e7caa7ef11e9eef4c9beff93af30c0e9a38fac591548908254667bd81f603419444fb95a794b0962e01fbd25e13a1577f67c2d58147c85e68c217cde1c45f7c93a73854099cd4bbc50f5efca569eaf629176f1062d0212be4e7e9813f83e414a0e6fdffd6e68555d83a97c5e48e8d92046b60ba2bff8041a79628294a3740fed867f6d3ba02a4ff961df4d49f05467eb7434f2dcd35df3cda31fd79572457551f414338f60456087f6467bfffc0f2b03190b4db265d5eefb691112e20b62fc47e81380fae28662d9b2a3f30c06c1ab569d8300a6b5b1a6cd38c976fe804ff3d8c118ede8818d78154941edcf3339cdfa350815f475c22b4b15040c6d36a676af535e0096a008913e82c133b1f416fb1bc9807ca45d651c2234f0a692d46132d9315b24613fe66c4b59d4a59cc7ba8a0752ab7a977be28cfeb73b0d8edb5c8134b60f941e039773633d3c0a70a9e999c2188d8474cd81e9a3420b295b9044361f28135f39ccdf0abc8ea612e7c9705dd04620a7df152751f11b7056ae1b66de3e17e41c9e49bbf6f66affde03f6b2287f8fb92161ab940c8bcf76efa68aaec84c7e78891c85205d65a9e4ae36b4d6147b7f7d459272457031157ee4ca5d15dbcd957b2dbdfdfd1683028c618fcf974841413f31a6c3353e3b4f297eb7271634f12206aac4d339c2c8feb2df3561aaee68eb20b1bbc022a47ed663ee017432a19c5caf560a736ec09251d953a3b1156fda27dfadd70873505f72e16458f146450b1129170f95849e0bdf11dc35827e04694eae250885c6cae138719932979383d9a63754d181d9527e7c6962e17ca7eac2363765ec0488cf0683e1077560aafdec57523ff94aa33bdd9ce65e9d1c95f302e4729c329881f6b0f000ff21781035777870ec32023c4cc5d58084b81f913ee9bf3e811d6956e9edd44dd7622066936efd1d47cedaafc065574d2ec86d1332458874825289d28983eee22ef85819501a83e84998f3d20e5adc45860af464bd46c2e9be87a19b1886e016d8eabe751e067848491a00120e970852b51027a7f00f1f3c67e0eff0bce1facc9075e9b748ed3a4c3f346bc9229a492373c9dce7fb02a125bc53de912e0d96fe0138806aaf4397396df266cd1f25142668cb16f8a6727fc73ac3e398d3c39d957c807288952766e638d3ec81ad1838e2af5ec3a0bbacd9395e40a322894c2943d9c08639a3ad754034156e063df1ca7e21160dca411b473b4625ecc5ef4c7aa940a539d409a01bd523ca0c8b5b22876f1dc92e25378f6336ceecf75f4f208fec29f1384ebcacbf7fae31126a53099390cceb527ea12b267ccca3ec53ec689ff64c039b8c969714e5fe87fa3c320443b657a042c0b3969362b8ef94344030f0e4917a72e97a39164f8b4906466fb837e485a98223b58ea925b03fc31cfdba417d0dfa0a68b5a511d0fbcc05d9d05ecf5390b4eeba574ce27c054c906d1635f21ccc816d4a06113642306b5bce99e55770f2f2bc345c4f141c23ad81eb84ec22441de94b1968bda0e62ef371203000000000000000000000000e1199d80090c989161747518992aa2b8b70cc89e44db2ee4ad0499a8211157a2a021a3de94e860cc13b028210fcc55ed82fd3321265b114406e808f8f3475e3ab2cbc7f4981b4682554b5508fbf8de2542c9f5a93986482137fd6483b9f7e8b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c87950a9e9ca849091cc28ce468f6c88adb3684f86679e125ffce1e2ada6cc8f8f9e6c40e33155e892d45de67e948947791782bd72d76f68f52e56e0e99829b80b321a20ae1ddc742a4dd169389fc67eb6423b36526953169e956c7cf3392b20f71c01537ab8e7bfc8d9c075ca47966cca923f55c872f275e3e11bfd8de5fd1022ff5cbeacc967036507ad7cbec5b67f7dfa30e470f0c07db23f6991d6b6507d10312288e33a4fbefd37aeb897690c7fd7b716905d801f8bf704ec87fa21efe064b0b04b5019322028e81abea57e05864dbc446de088ada53676c02dd9c0d4bd90f2ac93513ddaf52cb0d99755c796652e926e428c63e3a3ca407aebbfbf1049b96af03156ec03c5876048b88243b02a348942a840181e2e276eb672049836f2409db73022f6d4a7da14479860f28e0bc682c03129031b9f799508010fca1cb7074ebf6930324b4ff60b45fc15711cb4f6fb184c59ad8f27f20a1f2757353f34971dc6f34e4030b8b077d99c3b37aeefa1f50faf1d7976499cacee235c62c06366be38c7b527a021886e8ba49489d8acadb4982ac4ab26a737f78ee0dc3a9300d09cbf307a96ebb5c99bfefb0ed84892adc29da3fa67f7ddef17366497d271d1cdef08fffe28d12c1560cbaaf0a8a1d8fe236311298155d8e4ed86ad1071cfe030b572097f4706ac31090b53762906c50a6c957841218204cf2aa356308784372c053c4a74ec4cc71c37fc8255e418d045d4057b7982b550c14966e562aa4e08b93a4664d470cc1647cec1d414bad467fb52b433a4e372637f2b75454c276ece098bfcbc3e37c649f4c0a2adb75b0d75dd3e6f063650dc13934a2434c876eed60e169ce1b38ddab51df4a166d84bcc6ffd13e61cebcec3b7198e34adeee3ee726bf130d390cf731b0bef27a5cd6246c915364211fbd0d05fd18aff712104d0884b933e4d038c8f86455f7be9eb40f616957a46840af5057489474539ed6cc3f5a3c31bea188d448765f941a549c11830d2f0ed72f62d2eea9422f1ccd8c40bb31ac9c1285f111d38277881c0bc38008baf9ed673747076cae4bb2637f4b2104cd68ae28c0776e50a673b6e74b85ebb54d927334eca99140d611621e4cfbe5141a207bfdbcac2b46c58faaecf70c48e2d4937870f59220d6c625fd84ca934be47fbd9fa24082b094919e49ff6dd725f7606a47285a778c89eff49befd93d7881dbdf040cb72112d44ffcc8d4eb3b7ff5f41e580525761192e39386f110265e3ba562f5ae5a4b0710aaee3275a4c75bc4bd16955415bade33b67a3365434a05652f7263b622a0b636b618478c4d2739f8c87ba793ed45503fc8a5a4520b98ccbe00cdf759716f548e500e6f3ab6269069eb750d90c493820b112656f5edff7220a29682624b1e933e5ca9cddf853d7de7a5f8d3e56660dd9cbd522b2f5a21e394a76b94651fc58435321688a970432c96b13be0ade323168572c7ea65fafd6d442498c019ef6c839282830657cefddaf4f298bace309ac985cdec5d72c3dc4b0fd665b8b729b43cca7266944f4313112e8f01275e228a9f40483eae57d628ff121a16572cd07329c7721821ea1d8d292f8eca4fd07c62ad597bc97605ea102dea662571a5bbe348c89ac4f7bf7d6c1bae24e265fe7a027dd5b38d22e8f88f4914e7faf5873bb80e6fcfd4e054ffd56311022a29b505a6337b4f93541aaa7bfd4190ace1c29305e9e35676c1b289aeea2a2e4e66ba487f823f053e7c42a146798c53c80236c504c2bbda708707ef17c068fab137b551d2f4c250084438834ec1d4e1180ae03c3cd3262a0fa4d63d403764417bec97cbbc78d6feed6d1b6f67630e0f79d6866fc18b55308f87a7ff9daeb2dc7678648507f2bfd7d88a368d54474ee3cba853e0688aa9cef7813e5c2e29d4e8942d14643b0f9d5d13569f6c633b548eea662b6e32caa403b84635c48c275d353df33ef63dac2f43a5552ea2a4408d0e6b5220fdb8276b29c4e1c624d1c63db9927a020575e23974b8e0323e87c591221cab7c27748bfbe041a9dbf4638232c7516ef1b22925c318aa28315c0f8570a0ba0588c36caafba79bb45b66c137bc57e93ef5daa0b498ec89e611642905cebfcd2c6b6967cf7907a86d02f143fb9a9027ca51e39ac2d78904c4e240e877d8f7ef7a401c4eab42556c9071df5063f565660e3e1386db31747a0f895f25f7433731b4079e3895cb2be4e8042f0b7b9e459382c188a583a94721638833d91b1e16bf3f37c84ec74c570dfb1cd6c4f04f3ffe8b55ace589d5dfb257419f040000000000000000000000000a14c2451a9862bb75e0e47d5a59e9b2b68006430038da9d4b0f5aaaa7f7f1f28309354323ccce1d0609794cb03815a48eedde5ca90a803fe0ef58e2768a03163e6441ff2403565af52ff9cf7708028dddcc9ad40bd01e374ec7a69c4b409dc700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034527c9618e4c4647423f4d82521cf16cafec3cb61b2a7bf7f2a57de4ced09eaaef78fb9886870754275f60da93ce97e37d9c391be5db7005bdd59cf2b78522c7dfb014c17696128b6eb6b1617e541246283dda417012d0f8b94070d4335ab10775698c09417c2ee9891d504f0a18776898c02f265caf12b1b60bfd1a331692030f6cf240aacb9e067a5b79270a859fd6c312d2bbab33fe92746b752914595abe031c9cb5eee80a7e13b3936dce6293be7c63f96605747794f555be008c32dccfd80a040903198271e884f70e3b8907cc4cabd2a688380e717296b1191ccd85093b060fc64e0f7611ecaa3e7bb353a4e34646e5613905800e132bded5e8a9191b1809021cea7b0b21d1fec68250af2e4a759adcf66297a5503f8957694e4dff313231430207965f4380f953007cd82f184ced4a670ee8355336ca24cabde4a0ddbed8ff5b030bcd311312bcf9dc66f7d928954a7882bfb81c4feb71e4df53fe3a83ca4a0af3032ac5c948eee6c763681eb91d5d6914036f9ec1e79423c36b1022f17b6aa69131031d6e8e45ba97bec7e99bfae0d8ad84703af0cdbb0361052417ca8f215e0662ea2f09636e1e0c7881c2a156c4d1ae10fa2bfecad82d0b7cae30b8d7fcd2bbdaaf7b568e263f240aca338f02c404d09193edb2cd6ae9d40094365316363a6e5d78fc04bc7cc4c9781f39fa126505b48821226c32cbc637fecb58a90e7bc9c22c3d4c58819bf746311441734670e27975d2d03be37b5a4ff9e5a5df54213b86b6069dc45413c34406bdbe09df4e367e83452c2821b2c503da361395dd062e025f47f7754d19db76b40ba93fde1380abba7a85e36892a02387f7a254ec858022ddb64019f47de565f5eb9c3019723f82640dab0c8ff83881dd300cb0703f79bfc141b5ce1de092e20b69bd04ef87fb8939bfbe43d7d69899518e785d5f8a498f736599deb93e980b1ff6a76bbab806a453683e81a70a630426b9b3127a6f1444dee0a5c663210294050e3acd18babb1bf9d4cb1a34502bd6f428b11f7cf3d1e31d7802447ac014256a6dde0d638466cfba57f44eed2b1eb308871aaf3ecec24a4039acd7d4a1a0fdf1660ac8c34cb83e708744ad9f2947e6b247a6eceda2d9d1ec051450f84f9a5b580ca1734cefc8deb179c026dfa2ef2cda913e3c91df24674dc53a81515f8b76e785f39cf5d7020b7de921e40637bcae2125fb1e14e11016795b3f00425a12a31fc0f1335d3550dcfc45e78588009207d7059cdb81c50b8bfc8e18a2cfe3f5b4f81e999981b0680df4bdc11d94076e86b03c365e1da17f38492719bfc7d8e97dcd5cd4ed461a02cd07f7c48f768fb8c3867e96d132cfe39a101a6d4b56c61f84312bff4efef40467ff19bf18bf51fd6214ba734cee9f5b992d9fd8218dad0c5b5aca2ac9bf2fae9674836bbea8166a22fd9a8f9a5f0ffa4a0faf64e519c0034a4c9f0b0514fc39e96b04d2b8d3ca2674604d94ae206f828190ff6bacd197118b5064af4ddb150f464f66df78d3c1dc181bd64576c97b37068bb8f52d4c439995bf6dfe40b368facc21f0a6c59f004511890341f7f477a8f86a41057f8e66a3a217603018c7ca0dce30f6144b0172a0ccdbfe0dd2a7188132761370067109b72fc74225abb31356eb3eb1a41632ebef517edec48112cfc2c6f4666c071a758ee15e63acfdb462cd5fb36eb40df0f0d11281fa73df618e51592e7f76d7cde17560d3e2b223a394b118482639c6213f8657e6a25b8c387f936d6d30aae06ecb536dc7b3953284db557a8ee7ace3129999b348d53d6fec179897fa731283bb91535bcbcd2e3a663e9d3a6e65ab44fab6e9bcede3967e538bf1e18c191e5c11ae3069e29233108a9c0bacc4770b93f3d304e6014730345790a329eb52e13e5b99d83bfd5f8cd4308e9460f0da2cd4c0682c242937a2280f0b9e2ce066cdff5837507fe83c00e998fd3eff6cceab6d1eda5460a98a1003ca7dab7ac272692f55210d1b08044f5264305ae614ae4fc2f9ae16efecccab6f8374299cdf30ef069aa51752ad342da98f27c43e312f755b8449b2cc0cdeee5512e8bfa535b7c1c11a94253dc6c66040b362f2923ba9e66755d9587672df2cd95c863fc0dad65ac6a86bb0acf7eafcf4c224ce5b7d6561560af89415c32907942fe8f4f8f053610507826663128cf327f09fa20374e2e71d71e6d0733e5c905e810b78eb65d95885a60380866e781eb3fa0c0c4652dbc6187c396cc47dcf9623affd56e79da14e4929e9c7bbdb1f0cfe3c7f49e3b98b7547477530085cebe1d1157beb111ac0cc8fc4d1bf71cf53c197c6129cce3abeef5946c0fb357053837aceb4a4f6e35b0c9a567c935266c32d7cf0d0bcb8b1e6e12183dac05170fa1d7f0b1769de32a5ad750e1f9da7d5f23d34b8bcf32536cea70f", "53536a", 1, -889702242, 0, "ffa9ddc2dab45b65b784f3b7d85abcf2278fdad228f3ed9c76749ecbbd069ce4"], + ["030000807082c4030488e6a3471cdad1c7b4b122d9a2aec4c1ddb4c380c65469b8a132d00bbca405e800000000045351526a1b5f0cb86f112d52157ddf44c977e09dd34bb9d38ca8993fe8a99cfbbc31a7f35234670303000000030000536b70fe58e04314f628f499c509dd680e3438907e4e5e3a551330a9a4bd762dce44c6f2e502000000066a6363535251ffffffff7702facf866e5ccb958b1a7d9f319b51633595180be25192ab09bc4ebe20b2950300000000779af697031d354703000000000765ac525365536aa4d23d01000000000056004304000000000952ac526353526a000000000000c651fb2502655c240100000000000000000000000075899cd7be23bb90560a5995ef35463739ff7040990a2fe262cb865973c3d1989780eebc53f7769e51e91bd31986983f3d4cf465c0488d72d999a9db53207f883942a2a6db2d16a27b0d549e488b9c5a215eafc20c9ba6e345f43c2911bd730e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2a2c433cf3c4f3b3e4fcbdb15fa8eb25a054ad88258bdbea99f4915156e7d2b4cb79984eab14d82786220844351d8ffc9a6789d1e247750b72c415c026ce976a8bd54490a97b5a99ce3838608d46b314e89cc475a86cb40802274f816e797d586247f1b8c38042990390d0d1a2b954d0875704c82d66c3d6a2cc3b5efe228cf021477652ffb1ff84381fb67341389690383345fe41b36daedb19c7a83ffd005ca0211458251daa36a8f54cf2a663697d391c84576d7805caa22a4fe5f9c549c1e400a09100089efff027a98fa7654767c3c78908d3be14b489541b2f64ee0f32fe35299dd0f939c28c6a21f929078e0e8e5ae0548024c12eb0af63bc4be59c607b64c0226348a8081b5eb6248ec9679512562a3276601ab0e7e16cd7d92454fcd6af6e9032406a294231b77d829514525342eb482441027d23247225dd47a512ffce481b6031608a95ce4f53839ad3dd3bcb02152ca1c1a498309a7c9ab1ff141a374777f13030f0e0951b36de7cc523a6b73b2c1af6656b020102c51ceb36c254b67a5ba89340222ae70f7296c42958e64909742f94420b63cb3fd829841109fa10c803cf4cb78c6dd1bb13b469d4919f3963fdbed1cdf57cf6b6b156ed204575744d58d417df105cdd10bff34edb89dcf901087c60c89c421a68e45b700f8083c9ad2f301bfb5ab0eaeec759830ca34cf9a03558c5e6a4c2f58bbc60c24d2780cbcebacbfc2cec0cb58dd6f03570fdd07686afa79e62565180d221c41ed65dbc421c6bd634c26e52c01743cd0124a8d33a8202275f0780e073f77cd6aa0da52e082ec670290ee2e29745aed197d2efb587e55ef836b081df60adf02eeaa27b268141b8914d353323f4151951e47775698bad437a3ae5c265fa0735ab20998cfc041870d81f53b9854d3f598d9a663697d0c2d2ff82eaf6e49493af18822de331b296b36776d9fc730cac623142ca3b53103a046206628e130e6a67797c2bcc2a8e2e527771f3534f48057ddbe6a165a67e0f6c692920ea0b31f90fdabab281a79f5539161611d6842e5cb4a4f8d412358f486595f3c8535945f2bb28b39b75efa935fd2f819c65bf1578a1f2c69e86b1c5453137090a98dd67feea8cfc9762ce1d0527371d8a57aa9cc1075092358283493055c2b1e8dcd77cb160fad812efa74e1aa09a111edc81d403beb4cb3d283b41a902d45d5f58b614c3f744b750b100353c7e5667190a8f951f1fe76f8595b63d81032589a5fd2ffea25437f34ea7f6a4bf041e48e19e5449ba98834170bf8a5f566cd6601d8644f0c9d6fc1f07cef4de2e8a3b27a8560b836c11f5c0216be01d3332af84b62eaac2a38810d2a46e49d1823da5ab3b2cbeaa81f4431f2f9a09b9f55e0b881e2097d12616e249c6867cea59feca61a9b1d72fa0c1a13ecc6102950fa9b1881c5d7d816f69c4809a7c10a597ec658f960b0017670a9be9a288d3c6da411e0e9dadc3367b4940e46d799d42f4ccdec09dec8cc1f06ce866c345c98d9e51750a82f0d954609e3bcb14c0f1a6052422cda82f12f0b61d242f4949d96d49c335a1f1baaf3bbc4d66ebb66a1a4a8c64ddf662520425a77e13bc586c357a22433a098eccc12616b285c54df4d06a1569ecdb9d0f768e75ef4a57aab701e805ad23e833fdef91d87bbc0827db397a043a21c2143bb1cfd54eeec3ace428f13824d73e9b32f7a1a052f4db5b7deb5ef5e34fb52e5604726ad00904a00971c265724779c910bb2418238238db369747b774a6dea30769532dfaa3f357afd44355cacc168b0e76d14bd26e30f66f6067fa50831e8b6a990918d863dfb8addf41e34e828e5fca5916e10b1613c325260572b648606d497d55d444af7183f1b658ef8509c96c4f891fa798d223a2fc58ce591250fe86adfab32526861c163636aadacf27c217df6d9f0912b312e11098a52ebc7abfe7ec90a218cd9a24677185793a98b48ec3d0cd10615d7ba2e54f18bfd461334ab21f2ae92b83747d4126636c17a3d4f83a9a45b59273f2efb1520c0b5d4b1792156922233a4fb222cec60388315abfb9e37185c754bccf786043fd715e5ab0c912ab65f86a2b3f5d812ec901f472b3b5cf321b37585605d516f470655a4d97e87a2c579ce4f1ac82d10c689b73a678ef913e3e77178776b71570bec89ac6ae2d64ad43db19513451d8cbfae0529e13dfeb76c098cd9d1c8752a4f1d433dc45144cbd3eeb00282c76614249337fb297acdacd231a88f8426d7f864b661204eb420a3e02ffcd676c9d8ac814e659cae1e122b35b05d48df000000000000000000000000006d688970cc29d456b69f098d69aabd1a72dca41026145801b7358d936af1967605258b3c7738dad8a97a8cb0529b4f3fc3957f44115abb8f29f47ecec88c547ce7d1e7058f5473ae6e9a1a840eef79728127fe05bd800e4dc42c2933e01bda7e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a694c2a0cae511851e9eae4db4a0d98187ee8f395096c255e09e26e0f036e394eb668bd166e704275d967ce2da5d9b174e03f886603840be3a386e8b0e6db47a8cf745b2f384e53396e12f0159462b60bb41a0e33d6e158f4fa93c95162ae1c4b96ae1725f16773e57ae384d13bedc68633cc6f86f559168edf71179d9380431021aaad02993b9dd3000467a54a3f7d32c2b8a78302b2ca1432086c3b1710fa8c7022ed728d9d17fa8b6a047baf45fbbd4ed35b34f3a1734ef0106332e2da7ec0a150b04a3a381b66c30ce5180fcfee2a131d3b6a8ecd77da450d2818ded349315e4877cf99eb5c318f3f9111c7c4bad630ce751f73d34dfad2d3a4ef01b2889bf1053031bbe9cd676cb4b24f193472a5b4f111f40b0393a8104d192294bc5a0fd62790c0325953dbc0052e6cd709a5e74167c4b2bd1d072116e805f415431920cf6effab90301800299e038fb5a9a4e108736a84018354016d048435a2fe372bf1d6e4d8e3a032a677c3124453fb9cbc6e60855b4ad535cfaceeead8034441180af3e49ee6e3f032b2270b52edc06f533c17eefafe87cd3139bdeb83377b5ed9baeee86b096608a433f6aef41e9f4e4ea0461d0e0dfe261f8659610d9ac8050ddc9c4b1cbb53f44a777995d3fb3317fcd4cf064743cc5be6876d570731e69d9156ff8d21f566d1b679a01e253a5db0d0d6bbac1bb3bf106aec4e72291a172da7e79a5fecb444656e11b3c8a7150f84b989555c67c1597cb3217ea306f801f34b736311a9cddc3d9ce12dced42fc188c343f526cc40b499fdd641990b85d9ab2f6332dadbe3907df75ff523d176facc1c61a81ff0acc7d7e88ebe7bf0270d7581ebfb31073700a30483787fc4c2efe6ca84db75a9d532f3b5f863bcd602449135ecc0815999498f9a8f0c10fd934eb780cc95ddb770d5cc7d127aff6797eb9b0ecab34b1e94971ac961e2492d4402dfce0e18bc0f08068d8660a6740e587fcaad43a0c3b6328337123d7f0fa49f38d79ee1e2de2365f16d389d3165092515d3830a57197d096865d47bde1ac00d40a14ba504352cc6bfd63018e61f3f00b84c65afcbbe06b8d6d0796ac7e564714b3634e06c8f767c35d6dd7ada04c0751e5e892e3ba4c4c2b1235b85f9876cf178521337b58e5117e7c0fcd1d966e5dc146a2668fb1092e862969cec7d1bacb6880aa9416dd5b54874631fbd40977402dcae03f293319b5a9ac158a431217f3225b47aec56f66bc070b80ecc3601d7b5a58ed052a69863f1086ab0257462fdef7a3d698b56f2472ee20a21e5dda073ef4b40721d63bcdc06baa00e8627a55331f2efb70f1836239abe675737f2c16128830f07ba6e79840fab4a5643279d9c645f814a37b7f4791c63d4e3abe54ee3b8130d3fb5e8441994ab1d5da7f8b13ffe0f90fbc63e131e1d3bc5c8d449f421283c20ce239f68b43b5dc6ad3a80fc1737356a5501f9bd119e85a4b7191aea98389c5ff7563b8c569efe5f9d06fc9fec564fc9241f4f30b345759d80ab750001d1946e634533ad1b062713347b83cc7e35676d208dc4b47d4cce71f27f25c6adcdaa4a7dc61b68c4a8b0f2262f614d054c69174ab2bdd91710e36f59e33e450219a640b306683b52592f95aa3cd4ced9d775942cac943af262cd7cf1f02345a20d0f0626aa5db81df662ba1f98a18b58ac140600d58b360b79c92254d94bfb2a52ba478155db95dc29d9472d93a9eb581cb3e615166226938a5b2a2cccdb14ac53a4b1d9d51c1be61c0419f35c0887f3c81ce000b1140ee9119c0d500ca1c8658967bfe377b75cc788eb6535fdaeec046a9210ceeb03c7034416c0e3006e060bb5097c644126c04272ebb09fa72afa4eee80f0a7d26e1347e24ceeeb44258160470a995848f2efc9ef0d0555fbcf52627cc244e83b76e62df6db9b4d27c8153082ba87ab186426b7f600fa5128fbac84098c640686944ad051a63d7fb56b2d19af6631d493170ea94001e1fb2c976f6f06d350e73e4305886f37cf68fb195272fc74beadbdcb3b6dad11f8bebadbedbcd8cb8616b637c7c2b33ff7762ce8c1e5ac72b166e45849f1feaa63ab87d1210c366707a0a70d493dc3435838d72656fc400c370a4b1ff6a6c9aff64b84baa903818112f0648eda4c958471e715f61f6f7cb851e1232c150e9e0d348b6f1ed83c7779ead3ad69701f9a8d12728e64c159db37d774d92d9ba5d75bbbf1752d5ff5f6841fda395e1152e76af1d1272853852b035a6c177e16a58090ea92b3d7ac827cb94d94524b17d9f001627aa27ed5153a0daaad03b20b3a5252114b7e4eb1e5292d2f2ab2d8ae0ab74160d3846d92d7e20e10fbc7565f1c4c69b444c90ae189357dd54a304b79f212d2f462aba76d3b2532c409d446bde91561b5998838872313f90a274c61ce6067d41eb5200", "6a51526aacac6a65ac", 3, 2126205303, 0, "6cbc801ec57e4e04998193adf0debe7b951fbd83db194c54b6ebd0d380d238d2"], + ["030000807082c40302f914e29c147a3619a2d6b49cd96b4f97aac4a335b0961c1ecf7f7af125d99d5d0100000007536a5300ac5252ffffffff1d6fbef690f94abc56ed76c33c46cc526cd8c5fc0de0523835ccd4808fd32e0103000000076563ac51ac515308f1230101d208850000000000056a5300630038d52878fd14f23400", "ac526563ac5163", 0, -1308679946, 0, "49725365eb94ac4144735b0ff05142ce8196f2a0498a851c22ded974ea5fc0dc"], + ["030000807082c40304af7d24a47716a21d99763ffd781dd6005a961b975f877be5da712722cf428c0d03000000015268050fe91bc1cd0fc4f6c430b3193b2ea169f8cf377c99fa42e63f014b691f6adeebc77803000000026352ffffffff988c103de18caf7518db6336d97d0309ebe908a096e8a0501c84045e370d6bd90200000000ffffffff3555daed6eaf34b1a87fbb25736191683a5fbd06498306ac94930e07a451f0af000000000463636363835c0f710131ebac03000000000765656353ac006a1713df5d00000000030000000000000000aac2000500000000be24f6d67610bfe7dab43ad7423d0c57d7379aa5a0d6ed7bc2b2e1045b6b232e0fbe8529a3af1355ac06b760d49a0001a6b83bc9e558d77d5f80822cf0f5fff7c31521cb54a19283cdc82942cb27701809eb9de5596cae32a0858bafc6ddab7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006aeb4c7a3c6e9868c7fa22e7871c064095d180c081bd90edbbbdbe24eba2bc9d2bda1aaca29e8fc8dbc92291583c488b64e5e4d44ec357c9159db25b4be001b331dfe8448095f4c01b999e88c58f6db672d7a5d4fda5c1dabd58efc3416bcf43fe5b8d452a89a43b4dc8f60948dc99bbd0203670457e622d1d74d78ff28b2cbf021677bb5171e158bf5309d0d4b2b456cf44fded13cffb98a353ac943a75295ed2022ef1540e94d3d1741aff706c7dfb345e4dd9eb02e4f6fe21cb8717fa466d988e0a079e40f4e767027f5add5820d971e1c1b5987f648d0806054bd9137b544d4c0f8a396ddc4313faafc14108a74954fe77aedfa17dafa9935dd14a5badbea2bee302297b987d0c9e398b341b383ed2cedb8332b7d5378b78470c27b63e8e7176354e02153b55461cc9a5a3153f0d9d3d1de6e6a8419d1aed08561c27fb51aa851d75cc021f7292c0432ceab119483479a5ab4e37fc9db301ffbb9fec4d8b355347e2209e02208d27a09dde3dec5a691afc72d9fafa8f178fb72bde78876fce1123946966fe03267dd6d2816cccd32294b59ccc7968364702af8f7803f9d64d4c286b9c1d4d171543fad70b68b8f46c9718b898f2597cf6e7547f67276c0f3f9c446a4cf2b1004bb993e38ba9eb7a14ba8b7913573c0bf77c741b62a54fec0f825ab6fd723af4fbf2ac8d154a5ce21adfd7cc8d90e514928892c680c0947dc343394049b90294fa9d28922e1f8c3475e5d07eacd3dd1bc0b908df8d5ac5215c3bb1c7fd05ec73792c1de4e5c6735e85c0eeb66281a4b83c3ff3b7fff760e665d5c61d9b781af415da622174ca56335610a030c87051a138dc008f13851d750d657213732d9233f4c384b79b09576000792fb64529c159861bef3700b8cb745b320fc06b503de544b83a5ec20bd80021f82d3ae186975dd0e6cefd07dd9a41e3828de7c17d4b5c0526fab5846f310202a7aef89007a89e0192968cfbb9237f38f7f979627f9ebfb55137f56465f200f70887c33161399ba21c00006aa988c595b182e51fe5b38966993d61f0bfc90cc7ac1118a4df72d465cb723f34ff4de81eaccb21314d66c149017900dd8f516454d95450fe40ad4cbde522058494e8a0ca2a4b15da9d5a21d7c3f17c96f06935f9f2392f1e8d5260a6ed67b615d0d75350db63cf32b2605a5ef62c608bb22b6d92d83cab2b0cfd0378eac3d4572606052a2b0e10741925f94915bac9ff6a3b10210c37226429213d10f223ebe19b4dcd44a850c0d875d96e73428aa6f2e9dc35c6bf97c8f103932f58b08077782bfda7fa02a614c4ffe4ec945cf0aa102a9f556e6e62c8bf95b5b7b1ae8b5713e27306699bc35b3cd32b894cb388fbd0f85e35b398f0159de5ba99b681309f2ad0c9144adf89423cea3f7e644106f8452c9323167a74a1f47c2bd190c038c37ea448cb3c47f20812c3e6cbae7aeb92e4c92d907866483dfe9ccd1e8ab76ac590eb76394180a68af96dc61ad1facfb138764dc8f68bb36f517a82259cf941633f2922cc682df1a4dc4b3796cd7ef84a19180d1e1e8bf21cea8e2595e6655674a44ff59d93bc88dec2c0b3877cfb8ae4524ff27d02ee3091c2173f4ca926c7e7ce4916bec0653da3eb5a700c5c04e961cee422d27740d7e93c3093fbbf244f633f55b9055d3d0854a80c25dce7a3cd39f317e6f8f80837e26291b205af2822c9dd7e75e50a5e2159da8a9a0aaad14ee26497b711a054bf670eae76eb4bcd78f9b3aa9b2e8fb10d9a1398bef94722e0a7720be96d0d3db133e702dd7b3760affaf12edf43a064627c272c9dea98c5e99150e2cf40765641221133436e27de6eb680f670f354b21a65b61721972e24ab8498fee147fe283e7a5a2abc3602a2774d7e30f8dc2a7a5ab1d4db7abc853b0bc0fd5ecf21577ec3b2af6b597ef5ee3f7fc9cbf0759c5e354e812f9ae3982d3afe4e60534ff32e6f5676fa9fb47731ba15067962df7d5b1d4baacf0f76b7e1347dd711d440bc1f96872367548971cabcbdd65b1a28f2a8cecc4bb9c70c569dc223546093a230fe77006505ebb948029740838f26620aa5f91300ba797a9aee753b50be09c62347e8e77faf3b342a6055d81dc60c46c18a31e134290604004e0942b2b9b990fce63ff113d7ae1e13935aa55deff4eda6064b327ffd7ca22c0f7b303aa46713d5fca68eec118c588b8b100bd80f0b06629571fe53f1a3f7e65e350df42f43303ed7d4a05868fac2fe387cadff726c379d2fac17802f05779103fc7ecdb038dec9745e930e56d0fb9fa36309dc0100000000000000000000000098c8af62e1d984a8380af0fc856fbee734dedb06b498c7525bedf6b918380dd6445b29a2ee7b6f3d4ae7f1bca9f597b2b52c9cbf0c140667961c744ed4762661940b195fc73df6eca4dbd8fd3231fc8a521351ed258f920a5987aabb3db7581c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfcd21300d218c1124e27a27f60e5793a3d4d364c6c0ffe88374f249ffdea2a4c3f4d83e841541d23f456fac2c22f8097fea3c380791c5ef01fbc7807d58ba798b4fed07e7c84a5be8a8d4eff2534ee3c6e04da2076035954e12b479ca936c8a200d2230ac02d55e7e75662fdb5cbb8f5c9c95479ce6420c0e77de0750689cf6022e73741d3eab75edf6c1b551ef8da28d61ec36855545043d2c296b627356120b0329418da7279950b69e1267a8d21fb02e721ab32d663bdb81971bf6440466be490a06f860a06c46c35e7c0e307f52faf428a1e514a1ceacc40afcd150515ddb4d8b6e0ff50739c2817f98881e6f9b624bf1c89b019c16b9875f774c41da9a49f9f1022b6ec5f4f38310dd82ae43192bdb080d12858147c1ea94567abe7341a1f28830030584fa4f2c27bb8629725009a91c7e32cb27e86ae8eaae2f647158652a3455260324ef78b40d8fa7aaecc82261292fe3c7afe879f4a3fa17f2de00ac6f4a97fa2f032036226202ca5d45d46e514581cd7fa34f6f593edf2585a09701314556a2122d03271e11ff25ad7354d09846335911c98635ccb61dbc52687bf0876216f293204cf9102c361e4a9700ec7147f3e418c3dd35bed583e80896cea2447d7cf55ec230717465a1df2a90a35cf1d02ba9185fc55479679b8e35bfb8295f006f65353b77ffdaad665974bd97afa4a7d5af43e2b8dd0462f60e3382ec9925d152a2bccb8449bf11046629038bb438788a030c083430eeed70d6b124f0b198950456fcd8e776dd0a02c7c704af6fc599d739477f57ea42266a58884b5fee7c05874a035954763d0da0d8f5755fb9dc6e1641cdecd50bb317888e0b6eac91273f95c660344df08495efc97f410b97cd980130d4b48a9472e6b299027fec106bc5276165ca1554f39e5c39a39865097b7f6c5bcca717b94ccf4b619984670d72e63a41a2a011ab987dd439e9d4fe2840549b3909723fa1de11e96fcd188b0ca0b742b084cd233c4b917c31d6a37021ef2f7d1a50dd8df90a58895fa7dde5de422cb93ba14e0fa763656e31610565d6d24a5912354213a9c97e12dc37d20022960e689b927d313b876dac4076d20ce511bdd7989eed7bb4c7934d7c020077c84fd8896275b044fc8a92a20e800d6281034285d00625edfa99ad297e515ce1dbec4bb2439732838d6b986d1914c7d04accffdc7bbb293a8bdba386344d5d6779f28289d8191e0356ed753b2f538cfd2f997acede99abbd68969b989959fa58d94af79909ff6423e39245f5612f83d7978ac7511fb10418346c03b6fe46dba353efdde70684d6f395f98ec2a635074de8db6f7e7f1cb47322937af18e42104363ba2c0258d4b99d08536dd58a898fd66f6780a587b19b4fd2f6e0671c6112fbf2dd467cc84e131f81327d76342396adf51d9266ae913f66949e76a13f0abd2d519957ba6500b7e92ebd4cb906b3418ccacbf4a9ad87a80b074605855178eea42ee81fb9e13827545673a998837ae05cec0c881020da6e0f7c6f9121f222f5e39200923bcf31a3357d9a7e4ff3987179fa26a99c516a49a0ecea8af2fba7a19d9d836ef9a8419e61a7d487823f0b8b4cc03ed288fda3eb617f7d46f8d3ad097c003ef746adfce5a1fab50bc71308dfdb24f708228275329ff450ee46d69a3450d990a61456982b3d8ab257804314970f0e3f104895d31aefe0b3941f4f90aadc11b104fd8fe57c26b61b5cd88352a0f0ce56a52b1191630013b70ffc1d817e69931c9e5ba4eca6454e5953e755463200707376e0268969d10b660651338dc9e7e137c7cbf4fc78029316e0d8bf1bfc9815be99c058e8e11b03d03b236cf6b17bdb535836e9ef104183660bb3c269d6c603d5aaeed91124a70b024db8bc871de451a44d7a60292bc983c17b865bc1bb4b9f84e6cf23410c3a59620c5910c07aef35a6adb3a0a9f963ba09e37384dafd597cab28452b727ed9459435566125347f37b852d1919ee26bddebbb09ab31dcfd5c5247cc18c8b888c5f64aab4034dc8cfac98f8a48cc81ca3f8bb34793c4f2c91db0eaaa4378a8094b060b7e4e292a78e41edf807f58de9845269e972de666d11be93163ae3225bfdfe8b31baedd44d16d2c81284dad7b37ca4905327ce0b16f9ee7ee65cc24fe77df5ecf99dfaa935d0ee18086be63c8ab8125dae1f0d86fc8ade66da8ad9e022cff24ae52621a1ac4b7e81aa0a2fadf48a33e86f7004b5c7dffc8a7d62ac196f84378cf9c0905269add1d3857c6413529b2f3f25d2fac651aec9cf34dd886669973f400000000000000005a9aaa000000000052d4e2a33246fce5e64ee6c98d0a270e73f70bbdfdd7786f2f365681e1eb3f48b3cb931cae8e23885850e8cc4cd858d4718b5fd907d935fb25d03b70123447ae39b00048078423a011b3d060ee4084cf88e601a5e99b2fad1d4c14d0a41649c900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232d3b972c252d6090b5043b6cdf8d7691eee3359947152eda7957a861269e8195f9f4c05f86bbe86226fbe5246daea997393d82ee9f90046d6cf68da2066d83b8142b6b4d5493842cdf4c0335f3d3af36c7a0ed90ffb24ab3aff674f32747d1b3f0e7afe816eebf8dc33802672a155e213a59bae8fbcf39d94e708d93d2bc5d021273c6a79a213baea58e24864ef9102e7fdde551651513042d8d86352a17c797020a024b72e768e13fa5b48f58922da83375eda0f379af188c7ebb60ac73b4681c0a03872855005387fcce089ceda60f83c8b3ae63155c20e02b7c2eae43b2b4093a66a4807289009eecb70be6078bc6e3ea53dc2872f67992edf87eaed7b9b1b45c022463af0b7bf533def7af3afa695cbee0fc57cf64c8dc96d9c4ece1521655c585020f5e76f27522757900dbacaec9feb6ef09d3425cf2af6c37971ebcfad995c895020ce40742ff45fb5aac5b12c97f02320da96cf6c7bc1b55caf4b4512c2156ddc0022f94a87b9fe472ff79e94d8131cc94fd923b2049606e62590243d6afe9d44caa020710e2f9e5602192406ede91c2526cd1b6b696afc04a89bf3998a16dafbe2865b34f05ee61707176f8de1b6a0120e6f2c743f15553eac185ab4617ee68ceaca50f3a03bf316dd1e23e2400901c6acbd31e46560f9680c18148a452cebba24284c3a5e576d5b300717808431003423e189d549d3cbe62c2c24e2c4d2cf339c469efd2bee34910b2277d85e5ecb84a1a1c4212af352c661821c538f6cda31d22cdc3428eb01401afa5302f0e299e8ca1d8f60d1f38a85facf9f42e3264012c0bbb90df206e8dc965744fd80178d5ceaf2cf0ce10af40f082af9af2cc40cf0aa001e1ac6fdfa3b6927e4d205b719c711d03cb016808ae2efe9e81382ca5430e4042ba515d8088a3811e20a7cd15a41e9bc157c29c3e318b58fb778969b1bad508e39297928707107e4271eb6885b15262e9c4aeb1fd403c5d71dbecff65383a45cddca7dfee82157680c986cab98b900b5cfe2156a0d8ce9df21a92f0d5f1909084c743ede753b3b5c3f4fd914defb97d16f5f22969b7c2ae8c846da439c7a42c4fcaa19f03a48b7a09bf943a22d40d5e6982eb06b6f61d0cb55b9d244e38b2580b2627c8f003a656769d92294b1a85fb9850493bb1e1dd1cfdee3c7d23a79d123f49bd748444be9575db81143dd99a664aefa24f73f3123f2c0bc6f952197b30e765328b370d523d5120781bce81f72960cbb18b2bb9d9a5eb7577f6c24df2cb7ef98975a3f95dc63184a7cf2662834ff2a21e605e2201fb2014ea57171809a133f956bf23f8f857441a8548c3f94c7df9cfde5338d5c759e0a37c7cbc6bb028184293546b7335a6eecc7ea5669b526330b826378f4319ba80b5d7d7ba1f6d8c3dfecb4722d6db255acd0997ee6c19fd1855813eb1ad17c2ff37d280f6f15b166bdaea570996cbbab053f949cb179f719d13b5922e2c4c8bc9e4ba108fab02d5c850628ab725e73db65c0b7a6d66f6ff8ea6ff98ee545093baf5a358bec5b9b2c2dffa3bc0ac6961fe6a38881da2d7f12f865894349cfb811658085b944bf266c3a3528cda33d573f242dc55f8034142f88fbef07bd23b6a63dd8e6c48753b7ce51ded4cfe30b64ffde409710c80b1af2a3e6ee6b7e2a8e549c13f17633d4af13d0f6d90daf64906d95f5dc08a60c032995032795f04e7873bd712fe8930730c9210a851857a1f83e70665c2ca1611a446d4bb1135db9e3fd7888c164c1807b79677b0fff3ebca9d4f7f94813fff5c2443eb7b4aeda0b125131adc842b7140b69e0d1fec44bde0ac0fdcca8b655e9684d85b49576745117a9de0283e1fc70f4654cd2e64992965cd93c6296f8f18e3b8c956bb5ae74b8b3f05cc65cb84619939939d10a4f73ce4f86a5909349e4a61a25a76723db07f70dec0595f7df4553ccbad389c8d2f33623f827d6350e21b10ef7e997d68377dab55417ece8801cb7443548b86f494f67381f19d829b157de96b4f67f3e758462304788c1b756fa5407a38cdd1754520898bef7fd85918b3ce04b12f4290c9ca7997fe97a4bb9191f03a6e06e7cc3dcf6bc7256611e83217fc4442fd4ed77e89e569fe0febe06c7bafe0bff79f53ee63894b97c4da5b4ea6b5b0d25e8007a4c6d3dd5bdea9ab877e6c9a2898127ec1f8cf12be6bc200a8cdd64573ed68f42ed80ff712e859d8c0803cae08ec4dfce068fd5db9be4f9282c68046eb4145d8fcf913955f7c5d73468aa22855b3a1431a4a4572ffa11cc9b007814551e8b492c35e53a6d0347ba6c6dede67431dcf336d8b660c238ca55073588f0b2bad480eebe72703ce4d41db30b988ecd8518f945034c887ec81564ef3702310bf4c2c21e4d902f2444c8e0b30f62561b378dfc0be65e78b9236a0890a5bbf5ebb3b0d", "", 3, -2118255587, 1537743641, "17db3110fcdea60c990a028c0d2eadfe0619d25b3f3c161b9e3410d135ed2cee"], + ["91bf162a03327d367793a4c6fd5459d63506d08136e62716298ad146d9ac994f4ce37377520200000008ac52ac6363635152ffffffffc3721db41e2adcf18fd1eb78725a215da4950eac7fd8ffc9e34136843408ea8f0100000003516565ffffffff35d9a46103c41bf4f088e67acce2282e7a362d9d975a3c7c7f012e267ae0c8400300000008ac6a005251515351ffffffff03a9faa0030000000001519c01fd020000000005650065520099fc01050000000004656352ac00000000020000000000000000ee957e0400000000b2fabdd09efbfab1cd4e6558321c3d8b16b63ba939b81ec3ab90d09f5c210275044a524464ca5b0bb2c4d078ba63f1112de6bfea96a4585bf95b383bfb9a85f7da49a3da6e43c96966da75ffa3bf346795331419866bf4a527e2404a7a6c7c8c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efdce4f295d7a748b17c338147ed741cd153c1e604b25971d40fd4d3476229fc51f36ff31c4a123111d73d43a9276e894a912fe4828c66bd0806b8a2a763eb1fa2a2d0d4e55436cb8f7a94f1fac205d4ee5cbec54c65d25c20ff059829fb77e39be9260ecb0967eed05bbd34fc1d18c06902515437c317c17334a94debcdf55403051f61ff23df7cceabfc28fffafed2e3693479c6172f99899a691a79ebf0108d0220bc06de6a43a93bb57267779cf83c67513d8bd2872abbf5cbf7f222bfb9890e0b0880956a14aaced5b5b4c6671cb440fc89779230abd94bd339e1a30c28462bf8115cc393d31704240ca98bfe4771d47b244152c2f3a2583c5df9d92c45dedc12022a498e93743c04afbb7b2032dc04f3bb1ad08731cabab073fb11021a76504255022a9ead057361aae44bc5da152a86040c7754d7ec52c4e6b9ecbf32ee3c47bb4f03066640c6165dab6f9552887cde85f6aa420fc2926a8fa1f5a8658b36fc755118030cbce06a067d86f8520fea0b00b89d0b1c0be0a8c684b05a315f6fce1063e6090227e8ff463db0579ef37f2181fed15b3ac0e22316e6974af47865d3832f7b16f73ba5a02e99519ed4e4b40abe4dffe33914af945ebe4776e57dd801651af58c89372d730ad5f86ae73e24ef7c492d6c1f1fd056ab02757d802ed4f73af07b2dc5eb80099cecab8bdad67bc63f6dbd67ab179acc7c4a9f82cb48264bfd3f5b7677afe35024b31bce184f26edf616fc72642bd6136ae5ac14dbeb27a222be2cbe70a2d3bcd36b0425ffdd7691b5df9c61e420037360cc3c6989e7098718d399232a4e96cb3d2998ce14e97b10573b48811df3eb42a79d4548c2102b7ce603b3cd71af27d50daf06aa96ab3b5a8d266077a9b14c3a677a37718fddc35c351cd63df00843ad7b82c347bfea4686ffa2c1cad7ce584e8748b7d03a2bcf3380662a84286b461881a6f8057c33cc9ab0682021a6ff2e7d57b000939f2f0bdb73de1b90a54ed9da87253ec9428d8b7a4923be980c7c1b845d041e2c61e1b67173fd2669f4137ca2493c33b2cacefc7e8c56190a30b0879d22719f992d25d0fdab4d30d1f2804b8ab89975d57def1badec67a89c3b393d700b08a33eaadcea7d52fac19d008f6a61ec3e8a72fe15155f0264c078abefee2b91ee27d245b5b57db5ea715c0c5ecbe31bf82219cc64190a0406b4858ed7fa897503374787c1ebfbe62e40599ca79516a262a0cd294dd8c6eece3c1a2b018a9575763d5cf6688b5b6148222bbdcc01ac015fbd098c5530f46bd9150706defdf2e1730fb3821077ffbb4641986cf224ab46c966e3a90f685a19a7213e3891d7b7631266c4f3353d546e51a260479aef58a5018c2f2f432c05eebbb8a89d10a6f0b312267d2810bab475e97c880e4316ff2e245be5561205c0076a8ac51ed9dfca90f9ba2e6e76c8bec927a297f0ef1116f1f8bba20ebca313aea27b10f6fbc42368045a3927e29e11fbce17ac6be56deacf4250fcaeec686c3de738c3709b4c774d66f6b44e7840d997279ff584849b6a1a379ca6df898c5f25bb18ba3aec24064485a5c3d1a671d1ce71552101abaade72858251962bbc07be04f430f373f412b6700e5bd12ebc5ec32a05cecc2c1f81ad802d4a4f9374bf0d6855163c715bc63f7a70ad80d61010ba343095b0b9e1b2dddd932e37998311730b12babff029343c8e7aad356a339b24b095863f83745b9cf3773b4c369fa5f3345d41e294621cf4a83e6ac776e03927212dd686e419bf66763fbf2625ac1681cb9cd8068f4dbc481fd5174bba0f63711f3857e93ac39b05aeacbf6dea906c615ea21dea3624347ed64010746441c8cfd77f650796a12c006f9ffed5cab14a7924ecf068de062b258e3a0d8e16e80c08d44b4327a750ecd8b2d27697ad38865f64d2d97104e2b88893f019caac195a2df8b32785e348b3438b56dfbfb3e8437a3525ffbbb46fbcace41a23e92b931f882bd742a7322aa4527fb5045b413c4ca81a8f93e702a80fdedbc40a12ffea1681fd79788ac079f2421bc3fdae524f965a82d99aad00ad5d74674b4abfed251092a9f8bd78ff339ee788cd39810f28c2ebff7b18f8eab35fa32f240bf9505ad3f056f4afd079580bd9358c24a4619872932c4f798825aae81c1e1b781ee5fe1cf429b03455440c49cdae54fc54065b768bd395c0bcadc73eb15f452d2cfa81b2a69662ebc9c4843688b8c729854250f528b79cbfc559c64a029486db192a562f3813caf3234da09bbcd748ca518e86bd717ac8d2f1a55e00000000000000000ce47601000000007b384ee5ba1475609fc4e2d2f76da71d6947723a88b9a47e421b63d59bf4c682f5cc75a6ae0f6f13cc660ee4a9a54dce059e84f149865643bf3b0766fbacb8dd9125300bdfe7b99f4c69c9ce2a0de23ebbbe2bc44b0b6897ee47ad7983277e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e5fc7b83235e9243fff1a91f092de36830b24945c4ae59561ff2ca849ed90a78b92127faf6a5de33a571e9461a24769064430ba8c60ddd6ffa8a46a93d19ad9d5b867dc166b4377a09aff8c7c207cf5b9e37928d4bafbf82202dd390374ab87e000964278b4581246e0b762dd27477e1d71b3aa8d9f86e5c492ecbe2d03b3fa03287edf0b54710b353fff8d949965a17691c0884c530a31f39b332b33135fbded0316ebafb043d8bcf6dda0e3a528a3342ad780c21c1860f4c7b3d1bedad01048810a016c90321b6c884f90c96128d231da718e0027256a856e8f8b8bbd88f0bd0160ef25f1b83284f2f06f98b18f8b3e9d78438ecd98fd380c4337393b6f447d3d79021258c44c822776ee3eb1f52ec942f7b503bc62b14d0aea14f1713ddbdba40a450204fa13db446b38a66c55b5e56c9470bd86233ec25f33fa95508e4efe6e62322002014b1680e8a2cd7b1d1bc96cedbcdc88ec5a2b9158d507334a9b3db4c7266a5e02089ae65d72bb03d61fcf3f627d3ef5c526b99928e6549e5466a5a718a32222c0021e5545eea5ec80e733f57ddcf9cf04c22aff3aedb00117cd621dd1413386252c60679602312a24b0c3da79dd89375001894ca9a78929f9afa4b650dab120d58771a7ff3337fe9252fb77ebd02a7333d188f20f5a1d8963ac48f70ebd75c2d83d80ef56f9bc3e948e8ecfbd516af02dc975a3cb0f256e79f8b9f23aa53008df9e4a232d767733b9cd96f04bf612d4884519a7efd19e1558947aa3c6c9829e1440454c57d9db771b2f73380220a10a7823c918cf0287f554676c6ec32b706f3f140451f399378a03e48ee1ae0e3ce043beff782a4c5b743bfa0d0df88eb4b4db1ad950e92d048336131aabf39380df9cb176359cd4a49d6c45c1c1f4aa0b4ce5ff1b5180130c200e27cdf68bfec6cb5e07b2d16c4a41b7e09fa7c7e0a5cfa76e783edcde0672870f5832be565556310531e340d7b6a9a2a934ed08595796827f70c99332564f5d24f84284c3e9fba16b71e489f966dabef3704d4adb8aca60ce1bc6844780993d52931214454df82fcaf581fd48e2fc2709e3801e9afdc74d2e481160b43d4174bb5670d0bf81568eb93f94d21cc9254a74aa2b8de2945a455335d1bdc5afa25150b742ce37df57dbf2c178885fe951176014fac74b00f9f99bf9c2ff872cd2db66a45e0d761757c29760ae70426c48f358536b3637ed4cc82bdcd2d6d2c25c5a23a2fc742f84047273bda7af3cf0c5996b05d5045c27bf788b7b70b7e2783455311cc6a82dd47a03d4a40039591e9be3eeea8fbbc230e18bb804987086b4c67f7a1e190eb73b58715fd46bdc2033f9ff4b29ac04f8dbf7343af50fd77c4e1ffbb323a1a93191b7d8ada6c5049e9d09f8f310ec3cc72ba2f3f622a65edb442324aafcc74c554964ed7ab7267334825d7e4ad5817b6efa17530566d590c826e39595043f714bf47a10f978e57e72c0eabdbe537a0551885f807a1aae48137f322f6f517ee64462ee714894b4db1f610265a50961ba0c3d36a4a91f6db27c3043fe7af7bb0cc59eb1769eab42df15f50741fa5efb60bd69da7d62143f0d37052b7bd7f5bd1aa3fc886a5a5542089d64f46a586186a3f2c7941ddb380bf73fbb3fcab62be286cac1ab2b737c33e1858e60d970651d54d8414ef1b45ce1a2d278fe4f99f0d43bed45fc66330d8e22b860fa96850265c5a7b8d97cb537a24fc4ab20aa6bea05a79ef7b95dfd173f96cc25f685816ee352cf1aa745fa9437b1d983b82daf26f6dfb42a5f06c742b8b9495d9dca4a428359924a718b982ff383ae2813e12102f87058e78f5a1d3920c1c3909f4a9f46dfe37ee6e6d36c0baf5339eb702ee078587021c19065f9626c9a8c18b5e2593f9bc8587b39c3c95acc4339160f43848451c4370961a1b3939257b68f21bdf4a2830a99fb80f4f2c31c5caab6b6bf7b83a7fccff456593d59990da046c453f2943fd44bc745049da50eafe292776400470f32c1cccfbdbc121e3ae0be950af5911ff8e5f4539adbfe77260a1e901f8f479e000123f5ca9b87ef9900ae6573b7801cf5fc5a904d7475b12f9f47c104b2444d46b6d31aee1784c44a37979d1afd4dd0cbd50fd84b2d15bb5aeebdf23b1d42f3e6f93ded9d1f677a0efb03f152fee8abf6da052931f87e4d90cc18281a394fcb1e6cb442b6d2f322e2f7a17bf4b30b30fa0ad6817ac383189480a2d8b2558163eb954e8f1ed357d2c65fcf509ed3127c998783833d28408fe28773b895b651665c0ad87c8e3abde43e9a2f966a1c5cbd8a00dd2a69360c8c2536f0936d6f6da507db609613f6b05f1c983856d16b351b7ea23915733a84f41be236d3ec0e55ef3528394c572cff987e8af96d3668acac3f1e51cfefcf605605530dab7beb32f01005a486bcf2de1d08", "53ac536300", 1, 1595648217, 0, "4c48bbdd660d26379e52e6de8c4edb4eeffe2cc3e10d5aab68c62dba67c5386e"], + ["bc23df2b029b59bc4f5b8c58cf0a9bc05989c6852ecd576427c24cb1a31dedb5f736f260c10100000002ac6affffffff41461df9a8e4766fa1db421072fc58300822235d508240f293a4c613b90f27790300000002ac53ffffffff01c83a92020000000001ac393881b0010000000000000000064eed020000000000ac37d25d79362f92faf23f395af4e6b78077f5bf1a841e6c93de961eabefdc15422b7ef9a997352c6e9d2513e3e9ea8c43d20251bef8e9e22d6b3bd040e838875068a010a2054160cc2d9a9cd261401c54e1fd64fe449e73ca62d772e21e96000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005d3b9f93c0d2d0df62fc8c649f5892862f6e42c4f422495ad90dffeed192538252dd7c2876830927b5beaf9ab635157bd3cc6e5a017e7f7ba14822b30d021e165add44b8d2d29bd7a7aee03de4b9f7bf52f926e3b345a54fc08df010f054b5fac1023ed7b8686d54f67608e734415ae8732747d8bf498fc5e0ba6556c66a4cf7031b6f3fd8fa46eda56a6f936688d70aff7a88b7d67c2bb25e06f259a68ae761bd030400b585109707d5aa8d404b12bcd0224cd894b649168eab5d46b3e69edc77590b01d09d924c111b79a84ce9efc8a974aa6f458afcc90481d915b6cb02a667ff847a81860fb09010a1aafdb9b38153e9c6c98482954258947fe145bd72529435a8032262181e2cebcee2c92db9a39a01eae6623b8d6da7063fc25a1a9ca0ab11b0fd030be53b12840035377ced19313ce03f672aa6456abae1aca349917e924bc14b320321c2aefe7ad83ee7ea47a1a647b37253ad0b1628c29faf1fe9708ffe9e21d7dc031ad9a9734caa85c0019a0d7cb2c5fd39d8b36a7d3e114441ccd44b346fe3cbbd030eb70496d1e8e47121872f8cd331bf17c92277e7313737dc20b1d9ee0b986803f5fa0a118bf843a4d91a88d08db6cb06453356ff77f933441ef4148a70305d9ed653fe22653f8fb9dd19b237cdd8d5ef6b3018dac28f3acc67f1e0adb787e44fce7453f7f9d7840ff26c634b7a7b0e4dfde476a8ca377c45a32a290f41dad0773c465f614cbc4a7855f8404088276e6df7d217b7273eb175223743efd55585aa84782d6859d3f279ca37a1180dc18387cb8c5fb6d3b3755fd178cae45b74cd6eac7738b589d0540847713c4fa90e1e241885ccdb469847828a6fd4a50bd02b5f02a9d7cacf783b5ad8eb169ebdd445dbe03f3bafe5955f6ed26ee75e6a52ae8d3d16d49916d9e8169c0ffa8dfcc3b77b75e770204c42ce962840a941c463c3b250a149f66cb747123bb0ce65509d9824c084b8558812d6aa9bbc24cc51c45a539e734593b27b4ff44a83e762dd3eb93fed831140886bfd1e96a2cde35b82cfc253cd76f16cb44d8c62c5ca1ca9ca4dfb3d1ccb76ae62d82a5ae015ee7873910a9b5b704ff03cf2c13ceb2ec46d0f4c16d302a97485d17f3cf8cc9e7960539527a704c311a6159e7901526e9f9c49282e47ab620872a70cc30bfd56501d453980e65435eab521b71c78dc604bdc55c49211c1414544659ab71441682012ee38eead163047f1aba4e35d02b86e1e8f6eaab491f4879f1bd571a95bf09f5220524e167466d7250f1b72138d97418ba1945c8e5d6ca013ebf7efd3fdf4eb20be6e7760f2d67786778a8d878bb9bbd8f50c92ff404545a8c06baa36e7c9811bcd6a2fb7bb3e1b15abb3948bf8d7bc66f551d1a5e3cc7f2a4f53a3cdf449ee7c5372c3da343c1ca89f478c182cee07f41344be56a6b63d347d9beb85503cd53e889a55fcb9f20fc5789a83480c8bcf68f241d71ab99ace4c20f8b48bf091ff3225d4aa2503e1aa619a440e96a53002a385650bb922ccc58d246a406c01c0e5b82eadca4bbe8e82ec92d9f30e866526c3f00041d17d7e3671fd6ee929543a53bcd08bdb7d60bb9d4504d39a4c84ca5bbb8a1fef106df9f43ddd2c95d93af260a1a0449ab7a9884c63b2b4ce8550b4d7b2b54fc702ea624390081d5a479dac7ae6c5a0afd54de2c1fa9864f47951171b0bb87900982f68c5224557bad1ae4828932aba298a4ad6a4be48d404329ba9611e9e583774076a313e804039b478f9de073e2f23151270ef47985e8fc1efa88a7ee79937e6e0f363b6f58f276f799147f4801249fcc9cff89b7e5107bf02d6121b5adce4cdcb95f03ecd8cc84ee43103caadf5c26d903ab4500a071140201097fd56475adc40098703002406d9126d4e004c926eb703e95d00b16ec21d04e64d203b5b4a4893f54c9c6102c9c2ed3a618631212bc9b365d57f0b800a04cfe8db57395b46055d2c5187e16015016db5300781275c587433b3960bd47f19cf34532ae7b9ac365a405f5e0810129830f02b3cbe602c7898abce2899e437cb8e0d638540b51c816a7a12adc3c4feda8784b5742cd652842b70c17f7aefcebecfccedb35f503c8a2a0ec14ebc20a1d6af27de0548f9344130ecd3376cdf70801da160a9eb986aad85a3c3075cde895f4c361faa61ea6cf0a4a4f03ef1657c6b9e85fa371ad3a9fb309ae585efbf0a1516cac532b39bdcd2b28c50a0ca272f7cd2483f67de8bc3ccc5c91e8a3592bd0435da336ab0e1760c36f4aa2f0fbc80feb54c7ff9bc5509b95afdbdd6102795982dcb388491526fba52f041a464807f9c8c10d92a99a7c5c35f1dbd43a4f8df2ab43de04e982f1ff9934ec89dd71036f0ccc3f2c86b607951502ffbaad06edf4a2d391d7445126316a8b4565f79596a1b71cd9fc5a6745aaa0e", "ac6a006351ac6a6a", 1, -158057810, 1537743641, "9938317ef35cadc6e1229e01fd07a7dbe52fd5d23abb6e6903d429edc0cdc1d5"], + ["2da3be4303e1ff7f1650734b59053cdc10be0b309c02dc2f73b780b9c3525e2013d35af358020000000765ac53656a5152c7934de9d91ebabacd0050c07445198c93a29291cc47e84984016f65ecbd0a89e7a67e980000000005515151536a3302e5248f027fdfb59c6f847ccc870c610dccd8a854113f18584d3f9bed441ca81816d70200000003ac516a23eae71902561e4a0200000000001466f002000000000351515200000000020000000000000000f2a9880000000000e7b5e07f4fb9d83477fd594b49d44152968ae97d7e1b2a447699c07dbe5364b85bf4de6399c4f820bbb6095ef652f8d80b28d5f3a996ae82748b2565545b1a14e1c7be70ec285b3657fad7b28fc111b8c556d925b71ab59fbac59124c3f7372d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000927dba415ea5c969df51a53fc9cc579283c67c2f54f8c7b91a776f683a5bca570d421ef9dbecd59edc77124699de1b1c01a21fbca01bd154f23adc86476253d80b326388a394402a768f87109192fe47ffa0016880ad5cb8af7bbcbc5349d96c5a9be43b170fd6c9e5af249dbe118e16875ce6519815b0ebb716b2be5398054203222188b036a9579e7baaa31fb7d2f74457ce64ff2631807123602e1b3684e54a0314028181a0649f2042b1ff3b59ea477dae8f4628864e37e737c7d87f2bb8f1410b01b2d459d6ba05e5ee046be20c567fcc23e9be8404a8a8982e44e80c4945d525afdfb13555c971dd590522fd031dc92b3cc54daabe4df9be144a6d169702383e0201b7056347935875c1b3ec7f84c4aa253518c73d709d12757713f975fb93fe79021828b4ff73f4b547b32f81d2cc17d1e00dca14220cb40b9bca2fd401157722e80315e2d5f6baa44c2fa4582551b830bcf57ab1f8275bf66f576afebc4398f8d836020a3d0e94c4eba865705b86f24656cdd00e6a812930153cd8196b630136d1b4f2022a08a6ec5898f96c54207eca0e737fc9c7f0d2017140decc5169b2d240ffcefd77a35985f5bfb0b8ade3cc4650811cbf3fcaa8eb640e726e135096271a6a7bcfe319e8bc18a886bd9d9684337a41d63dd7a985aa78793213275bf95ee93bd9582e57ab4b46f8e1a05f54fd2301db8ab0cc628c0847e55cf9a35c5712607cce161b1256be3b907cfef6accbccada6479c062a16515e7fd8cd3024bc0ba2142ccac817b665cd5950211b0a77dd92a7b5fb88f6729fab69b2a221d58a00357b88807da1bc6efa47ef25d3c046ed86257806b0badaf7acf0eacf70c371c6a45422d35d936461a27e4d9a59f3a5a18bf3555f51fa1c7bbb3a8b2dfb4af2df0a79550ec7d345342b6e6da16c47e57f0b91b44b536609e7e48f8290dbacca28633ebe243eb59497204960aa0fdbd9a871941b7594ade2ccf15433288b7a86f0f2f273226ac815c2de968d08ce97c8f33ca80bdf8fe01c36dc729a0cd797de3040ec0b385b7395713c4db69744f2bc05cc6cbf016d2deb3333da917f920ea6a1d66223764bd7b675963efd23b9b9ab0dc834901be3f8d875fa2406b3ab13f1af6d20aeba715cfeff6b7d74610efeba99db1d5f88552f622a8dffc7cb5488e3d28165d45b87339745653961e5469ef74654c2233858690818f22b0eeeafebb82dd2002ec7f71f193f657dd21267305f220684983538808f9c0ea1da0d2276c1e7d84f896e8850b841ff72d5753c06a748a5a51783a837f7bc343fe696fc651c3b61454b1ed186dc7af289ea3de26f706a845b4515dc123c6bfbb4a0cd22bfddaa8ab801d3df974c631db0623bf3b71a54fcd590ec0b1af245e8dd309b519b193d60b61990af6e244ec002ee7dcc3f6cca768611f852f3ac94f28370eebd00d1660e752d8b06978aba1604808022dc157fc8345ef1fe5f41734bede35163b2cc858821e99177f02e69b6825b8ce01e2c99f201ad179e2eb909a7326188b649c833e780e8aa2a6f5795f7556be5fbb4b2ca19f969a8ea68275bca29cc4b39e5e3ccab251b8f0e6fe405529a108d0a1f98de5579fa164267d5932ebe929a3429181d05d88d6ae797ad1676ad9cb11c98057019f617cb0bd3e5eb57b94f60f7e05c308fe0850830b0fb78d4ce67bc516f02501489d2d9c1258d7ecde855d77fdd7ae5c0667014c5f704dbe8e184bb2462746178fc064aa4b188672f8b444cad8ed9bcfe504b462932d6660d08a3fb012f508aa7f92e882b3c7ed00564e28653322ebbc32c42589d2426e67fa26c7ee034fdd025b2ec9b533ce1e39b202a7bb22fc36ed020ef67f8c3fae5ab4b279b990b67337601da7df544bc24537d0ae6f7c007b27ef2ef93865205ae5f511b858a4c4804671d2b41212d6d40d5a510205e755c2287bd79e90588157e40963ee80cee98739f709c2401a6828f929b4b5557bb6c7461daffafb16789de5c7b64dde96bcafe5d7824fc85e15ae70a22a1c106ca4f16b38df833f9a3b37ac703350943a7f241828eac9320f8213b6d71d77470c3294f8ff0756b88ca77634d3cd53fcb2e5bfca99c20b5ec4f5c54de5aaac92d0ae9c86f08323ff7b63b0d70daeefcb4eb9f572017d07ad005b16fc99ecc6c700b7b5088f82092df124e4765691d379ce83c30e74ea89172e7b9a699c14f0a7d8a1194fd9fc0a47bc40da1ccf7b21316c578a4f56297feadc3c8af70d5a71e64273f7bebccfbd4209ccc4db58368ce7864847c4e88401c1bf2000000000000000022e5250000000000aad986d35d193df13166f316a05b1d28ff015484d71c0164b6f410d1bd0a273373d2e2fecf31764476c4fa8d680a5aab19c4410ed3383a60e76c8e434405226778175cd233f73f103143e7731d7c92cf7407cd1e7dd6536c81dc4ced94b3a4300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011ddde7655a0795056557dec1aade092c8b144e03cb2117f1a5592297966b431057821a9e2e694161bbba23e35df8499a5f4b19c19df403851b66d66b079ce74edf3a746661dfe6eb850ef91c36848a04b291c4a3039b016c11539b8ee871bf76f0772f699faf2ac3544e99be7f7575be24893599c9a55d00b5380214774c25b0228a89bfeb9c60e2de704afd06368b01b401246461092375a7f0fc5de86e21f450229766b45de1685a055f0ca826b1c9fb2431fe8391e61ccb6ff405f9c510221810b088a5b3edb012adad3704747581a39d956f8a3b7ee981e5ede17a9df2fac7045cc8dc91e492ea30dff57397a2a551f088709386948564c5d5eb2cef9f1776b5502196b4f67f2ef426314446f11cad10d2a7a3b94529791b06c58ddece6dda18912031002b58b4b7581b06e1d2ba0baeba5e8689a9f08a376206a06c9f7bb7502fafa020deaf3745ca026cc7f765a71cb9496ed8e72056a34c9be442fe60c17eeaf38b5031cb541cb98c351b0e0941276831697cff31f5311fcf4fa563a46aa43180e596f03045df57992bef76aa0899a940237c314c3099088034954a3c8e399d759d5a1a0edfa87fc1a15cdbaed7667ce3b4758c21e1775de034419c6bd097dac40461484c388ed2538f6b80e11225db50f709a2fe753abdf0d10439131ce9dbe96af60966980b6c24642ba1228b9bbf4f98e1d8c5e3d541d83fce9a86c7420a91c5ac2c7b8bea465873a3a0a8cff481f02363ebad56fb3eeb3e3277dd036d77df95da2811e917dcbb8ec90958865e12aa7569088fc74d0b29bc082e8a7c31958d8764ad0bc98a4ac0ba5b8658e7b0c14764ba531da2b279d2fa674b779ae663c12d5cc2fddba25719f0aed22558994cf79582f369850603c2eb93535f896bcf7fbc171907047eafbc8951910db5f6f5f78f04c47cf9a7533d24a1e7eb925791279a5c9b03718ab6741762894f99f46eda61dd393fc3d1022b579bd2838422259db18008be001f4b9cd9207b4fd2aa6e639dd35397310ded79742e12b3f4fb11c192b8e079616883d83b71ccf636dbe3a18a5080fd4f475f2cdcd2be1c5a6f48ce4ba9046bf47d14edee0478855c405889e680bdbed489bc4974e14f5c5030ef510c07d6638ba7b59d134a226225f915f75f79e8237498fff54a6b0850a0e76a64e911b444ca37b4539688624ed6070293ba0de03c59835bd3cf3e21864861171d0b05ffc90b67180569e1a41993fe7097c5d54442ba485e98a8e88d4d998f32680961247a7c0b69ba2d52b58a194b6361518e263879150b10e27d0bcbefcee01ceb964178c3dfd4b4069171f3b09bfa86f3f33c4e6216680a31274c28c7ba3fa754506371327be35b04efe872ee4ad3f1f1bea80419343a6f92eaa6ca00f793187f5a34a7e25494b616f302f6384cdc7581a89e0209e6c6b9a2ef0ec2e2305b5c02aa340f99f905bb8156dea3e352c6db2a642175faa9c5374ff620b2f794cbbb2404156ee8820ab2eec50f7426df149b893c47d353ad6c9a9847a5703b637328543eae4d987b6a783281246f1375e78a604a295dec39b3635649cbb21671be111f366f8860bb0dbb1b4022b3d41136790ffc0c14111f9257a1ecdb81994e80c86532cac8ec1af22256a9ded0da3febd6cd6bc6ba669b1907420d375f5d2ca734931c92981286216499bf6dc1b762a27f9ed67e9b8f7b82a33f459f67486706fc78e0365d19952fb43a147df736d659522e34318f436d664841ae4d83496e617599943b048f751700dc6e020d63c5f2875126b04e0680c81d27ed321b63267d0bb00b655d00ece21b595bbc540a52ddcf3a7ea9d61873c7b494033ef8f8332a60547fe6d71c1580fbc74e7ed4118a8aaf80ac2641fdafdd6c0703711424f5e6be7bddf20fb15a8ea020198cc693cea4fe7641e3fd386d7225142c6e9f05550123bd656f3f270f6d0b90afd502d86d335953af7d17cdc96d48c89a2bf2cb76fa8976e5693e42ac03b840ba2ed1cb57a8111c0abd9eed5bf86265621a55f1fc4cb80f181222c49917e69a85f027fcc2cd0218d356f13b9d5f33688caef6f85e6ee64121705c15d752745034ecf9c53262915ae0d3adf3d33f512698b114f2d3e88bbde2a4e50a5a4b1f4b36aa9d64e7b31849d7ac9d53d93e46480a611bf27e217878256307d735fc0296ea4ce2aac0eca96b5565054c7cefe7e52ce603b61989724960cd2b3af1c859754b46be78d9b25f94d92eba6d412d83b2cbb3bf5f05ac25c89c57f992af43e7a793a133fff4d06b3c6895fae7b36f68742d2ee4ae2660a330fd47e59e20f90439275fea0eef9253e1877377910565a94b321d52f398250090e1f06bdc15228eb518b7eec5420ddd5c2ae046baf3ce3740437dcd16615ea37d922e456f47ba4277b21403d19a6c77eac7b81c509", "6a535265650053", 0, -1657081709, 0, "456932b184c52f860e0692410cc0e8183639ec9651296751a1e68a3f1878cce8"], + ["030000807082c403015cd8aa3ef532a26dd14a96c632389ec3087ddd11199dfcf2d58577e5f60bbf40000000000165ffffffff016887930000000000086a00006a655151656dde3dc64bf84d8f020000000000000000c38dc005000000002eb923c0506da12599207c508495600523d22c287161ff8618618edab5ec3a245943a72b8044f99e23984d921f0bd66962b34e91eb23340c3878ed7f72b90520ef7fcd48314bc49259fc571f43ded88655bd169cb5bf4789eef7ac3e0d42d011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d1faf2c8f80e783fd3bcaf5264675c7561317473e87636b26c14708145d84200616706a342468e3d0475e026392f1b23a6e723f09ab22823686a82bdefa51ae05ccbf31984f63b9f60e0a1ca59541964874b39ba2d4e5f153e55b6717c75544c94ef813d304c93d2579f952c8941d9d2bfc1cd96ced086fb10b70a9739ae50d0308e49fde9f80c16fd1a27d676f40e1d029c92824b6308d69c89bf05e5fc3148b021e21030d44e6d30dc4512ae6b1f0d9770b523920793336ac21f8d461afa5b61a0a017b4865f347d51a1825679cf9e8c05a6b862a25d42fdf71848a69b29851957972ee22133600156c55acf31ac9a7c9253cb33d1e6db52d1f90c1f3646c073c02022021c6704eeb0b6c576dcfe469d729355273cd13f64235d8d88e83cc5e273e2603135beed1a0ddc15f9def4d485e9a047b285793efaa59022f455e4f0ee9223fe50306cdb04af54a77bd6ac8f6fd8e1c72b031f376670e7e46e4f6c2969b0749e628030fd920ba7909a66af0f03f9f6df5a7b553076d6b3e0032a34d17d06778f83e620314643afd5ec28363673ba7ba19a17f9491c90a2e6afda061bb5174350de4b7966c81a149b203805de1f5eab3addf9775707ca85e9b9cf7b2474a55c664117d243754624a2ea695237e3b68c5bddd28430a739d28401e3c7e123a5e067dee837c55d0660fe1c9bf378b14850c26242888e58c38be417e0293aeccf5e14239f27c24547fc915652ef7c01a1215662adb3da539f2d70d914cb260357bcebb0625bf4c05f78a14d685032b12b2b08b9574f2e89fd21667e0e5151177f4e145ccc3dbdd1d6b3a7c67e1a8103c6e1ca771e6a81081d7183c5298b420434b32aadf87d42e69333b8cf92c022ba839609c0ad45703276751e91bd432986c163ad883398895162b88a9b662ed77fd587147611a9ddee423469c655c40d388e3fc89a9e71360ca532813f96c34a27158b45198f02f2488071e78f88d9efa08ead380dd00f5dd10c9d6cea56105d20a5e1909ed039ed7b591d9345593c93391dc9949317e2f7691b9991f6168a306b134abfeeace7bbbcd01107f9520d660f3bdd0e8a740c04ae02bcf2fde9d06d6215285b1ddc8b6ec2abc5cce9b77efaf0f379d7c22773e0c599ca85fe5e1947dd460eb30aa7de29eab806058ec6f01e72478fba96ecb8eda5b23105e2f4d0e99e77e2938203f02209e5c5aaf512b38268e6b0b84bc42de2a0a617fb3fc3882e3c7ed1b2e4910b4ff34206e3d67d4fc4f37ce7a6732f82c3606ebde9339b68c16e50e85c08d2696d3e7a5fe2876e257f91f54460322d04c8aa8e176ce8852b86cf04ad272d96060e010fdfd02b5267ba109e9df226b6277392e71cb3f0aa8f759c645a716f67cd578e0d57d1c73665395c544861a64417fa249f6158f892d1acc3f37024786ddcacbad99ee1c85574e25d6cf2df4d5dd990f40bd90aa18b8d6e15e7365fc3e127343bbf9b90940bb9cf1bbaa19feddab24e63e61a689a6101cb0b9f340aab4e1faf054e78cad3258cfcd7635b8e4935d0b6176bbbfa677986b46a3978da3372185b5cb0f9c942e157c1f2a1dd8499edfd35a7226806b3ecafec8d57eed0cba17188b7e4e277870c9a07ee8c9e4024bf186558a9f63021195672d19eb64d0dc940e06fbbd49fc807f43fb02aa7b289cad34c571ca318932e3edf450f1534e1af65cf9272c3f5b71c3c004f6625e3d4d6f08671bece34566f045b2228a39e39da5e8e2e0554ae16aae041f0b4b02661f416ddc80548e4b56f27839deac7fe31c82377793ff449d3f03815e3b3eb1ce859aa2d4ff846f1e306e0f1088691281c1b979a753e0e9334d158e3c51ca3d925fd6b62aa873071363f55a0553f41f351877fc66b0dd4b7906f417d5423a9896dd7496e918923885395bdf1d416f4e3502a3338785f1a4f6e11a1c818d8c24b3e96912a2755567f6931a30c1a73bb126e540b28768f6f7db97c4f11fa6f04bb9334d5ce0aea1208f645572a67b9b6f4450edb9dea2c4d251a7f6c8dbd3b95877f40c27bc660e9247faaef1b621a1ba78035bb14b109c9839f3d8aeb68c86ce82ded41eeb71c9082aa08bb45750b205f70e0e775d59214d4af75600566fa495c806851e83b11b4ce0a26dfdd63ed21a9a2a402771ec702fa11781804adc27a722e4672fe8101175a4ee721381922b46e480b2286693d8035fa05bb10617a3638361bb66cc9e628b5da4902d447d9d05a406652700ead9961431412ee4cc4a783012cb0c256dac87bdd721292736a175c9f14900856877a21b00000000000000000000000000772cf68843066f8bbe96ce9aaacb9423fd10bfdc72362813742524c4b3aeabce94ffdeaf646babf67bf5f6ececb61e185fb160efb93bf112584fc9c367e7e4a6cd265b0c9c4691288142d1624827127def7cfaec4c2839a6fd6bf87f4622725a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4ecd0fa650f1cf831a8aaab0f80a7b2637e60cde66f595108433e2dc4f3b2ab10b7c3754fe294e31c3c09b94ce2c850b820bc64d5ad017b41f460d0719e2c35235be3e5eea7783d87bc2cbd13288b080f5f9fcc60e736c638f5009e00cb3d43a0a111d3c2f534272cf3a62a1192b290c11071413c57e2c3913e0b1a2dd5a873031e9a4aacf761b4a0ed392a5dfbeb8cc5718c5967da3615888a51b055f9f92ec10324f584ba3e0c9881effe2921366e718552fef8346774769b145131bccc43edcc0a00d324277a7c5d0fcba6458f3a6529beb72f3df4e1742cba6157710e9eda7cc358b1fa07b61dba5f31c3c55f4871f954191458a37868585907a7235529f973ae020775b189c5d5976109b93ed962ae5d094ee28b2f7a52848248193c57efca6a00020f2900f5911ae98f59d8a5ea7c081ef5a4aeb50aeda3c2754a5c64fddc56a1db020a6a498e970f73af89034e187b25a0fad264c1135808852d72e320139a12e3550314661fc5d3b947310bd0f407f4941be89a3a73cbb0564eb525766ee7bb64c9f40305bf2b735991cf8416044f52fbfff4b25e92b76d5c86f213179a79e8afed74304dddb802a67bd94d47f1e1901023e23d2e4fade4093d6722896b6c75f44da02719fc37020d414ad2f55b7e22658dffbebf76dbc29928ab07798bb9aaab666c64daae412629304e3910fa978cd70198666cf1056f78a875aa6be43c6600a6bab8861d6bd9bafb95ccfbcdf538cbc9a19409db2559fcf1260d988662244ec9a8b8d76629320c5aff4b45e91b2f44dc8ef87634cada8e1a2967ef5f0fd2227f5081ff6294894de1490d6fa2af988381c15eefefefe1998f028f8b2bb25912c0a738ed594733eb69646ea990ed05f0ebe7589f57707ef3651fb6b10443a235d89c64fde5215f01028daf476d2150e130d9d25397015d1f08a8ac40aaaba54ab67890a33c76386417f08059110b09c9489c1a8839fa458a1c6b2dc3ed5b1cd15aa90736a9b3edbfe6c70a734bde897b9a9e7c5491ec912d8248d8bda15dbcc0d7e5084f49d5e0182494b15c60b930fb04c323bc6c074ec3b0841975385765bc323e44f4d5fe67c6b9a1d6add4725a31702a6e4b6679585c41d9b201da4b6ed3fafc0fc2e74cd0d1f756a97eface9380e490627a54fefa9caae4bd756bac4c7afed7d021f95778b435c98efa2823d78db92eb425bb1508db6669c3da2fd61dae5d043cd2a67c92b4be25dda437c46dc6087253a81e51c7d9d0e7ba706e90206f542b41f5b75f0bab844d9db4bbb1c75bf47f91d35c84ccedcc5d90ddf04d981fb136d00c7f60ac1ce6ba789da3e8ae88d4bcc00e6839d963ba4f9cfe063d99efcf0fa7a91e28f85a55d4bac2e670a7f7854b98298ddb207ffe5da155f4f754fa1f937f43fed33624f3851c8914f92dfabae63533f4c12231dd14d74edc4923da296316aea9f276f55f176720f4d8622f362231b79cc876ae5266899063811fa585115080c8f067bbede8e99a3ec1a0359cf8361d33cfeb8f58b679a77bc7d7ce28b102dcbf5bc69f656646e7a4246c82c110d54b9385ee57a51c8fb66a5e9508b4f1e62d55697da7748d5e33ad4603155919e92360d6e7fe3683226da728d999f7362c30e479ae117a402af080c5222c441e49f3da14e359d45fdfc24f455f9706a6d3afaed7cf7096c645e0848e9453b441d244c3b244dc7124c8bf8218cd2d9608f0d36531980a509a433713f9c62eba74bcd4c7ec2ee342d8ca2be77aa84da7d6f50906a5c251a5f492d78033c60fca0a6ee28a43e45485d2c3720a560073e192f9e8a93e337c895f0949afabf713182e1092206f1e4b9a1ac1389f889978b416413ef7a20b7fed3a9788fc903324cc17ba93eb58c19e5d6533f8b73d44540827e58446eb604a0fa0024ae837dc6e15c54aa5166a029275d5c8ef6b91dd377e6b07b1fcc78bc8c22cebd742f87737c252cfbd7657b2ea10296667464237bdf4ea6b852dfbc6a40026d5c72fbdf1efc15fff0bf15d3c81fa45eac79de7aacbe9cb85380d39af0d98fa369bb472483f1b394c0bd22980c8de91524474342966332dcb325e8dc238eed5cc3d95ecc31b82f86a5ca9a34b50bf0e0e5a3e4f612a8c0fedcbb94961dd77d97a9d0b98b35463108e34d41e20f1689e8619e76dc5c8319862138955401245625905d4ecf48ba98644297c49aff44961a6f32bd6f3db4f46c2fef78e394769503c3e10a685d3890d29bdd5896831ae25de1c7652f290f8c333d52f0dd65f7b4012e485c5012b6dba3da514b67d4d0f7f54df5f84a7e24dddfc3e4736743f4159df9b5bd31c3fb0e8fb12bb3731b530aa813f0efab708c81778ae9bca9d4b400a7e33272660edb2485fbcc934bea0bfc81cfedbb2d33a7bbb4df99cec92ae7cd52f5912a055ca1e01a2790c", "005153525151ac", 0, -56721546, 1537743641, "46ba0f0e4a3072bcd842e2c83f81ebe0cab8c3d24ca3757733ea716b614713c9"], + ["41aca02102f5951a2f1d19c3bff41731e78868a07d141e1b0cbb67279b37435383503206cc0100000004ac516551ffffffff09991956f436c10ee3e1db93510ead737be05de5a5165dcc6b054b8408cd5c1b020000000665000065656a3faa844104ed991c000000000008656a5200636a6552d760a30500000000046a53ac530f34b50400000000005e347e000000000002ac0000000000030000000000000000d04c4c04000000003d6d61fc82a01b9cde747cdd1f13c83c00b9133fb46c1698aedb048732c81d2582c0a9f0a823c03c8dd6a5f3a7ca905f95d0eccbfb1745794e81702f6a462dd93c796cfecb2a9a24bf337a82ee1c48bbbfe19260865cf9f0adceb350eee04e6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140dcf0485d845aeb72ce16a193385da67c3870ec0b1101c4365f99d9bda773718c86a28c96e4a593294bf06c2fd3e1449e105a51e681ced4e8a8584549e699c5d485612d97dfb965ba740fc95e15562e20cabe17ba2bbdc789cc36732e6584cd91802831030622fff26aa2cd45c21d8ae463489bfe2ec334b3de900bce0e9e3032c12b7caaec45dacadb61f45214cb8a4d61f548dc81c210d400e792d1e655d080216f77bdf2284c82a4582a25f859c84e5af65dbdc2ef89ba68c345f5ce169aa330a06c28c51144109aa79099332e21ca90b3418c16b8b2e3715396b4997e96485073717763b1af53543560c0e26b99c2b5fe451c481b203819e2404e0e529fdd90402190a67bd91e744939eb2ed2dd086b286baa6596c0ffafd3a40ede24dfff150680221b715121102032bd9d0d94d95f00049e2ee6b2a74bc059c15b5d82a762ab83003261308837499d75f2bf987647123a4344a222c584e49e9e1e17ffa97d460b2250322fd3b3ec8a2d9bd7fe792f94c644bcaaf216c41a9d55c5418d3f859115d20b0032be0d9b8da962d2f34aece443f0d36acba428117a6cb77016528a5d19f49c97ea4b2fb9b527af089b936bf61e76e830477c994c8ed1c902467b0c32c0b34a2b0f971201bdfadb5d74f69d13e69b445475b63804ecaf9db0366703865c52b0ba8860db066ab77e4f564ddb5cf2f0bcb01ad1e5694a1673d3e2d6a9b5927dac7710e30d0cc336097cbe9607613f308e6dc8d26095ae9ab2cc56e2927558290c22961ba062f3e3a2bd6afe379f06801a60420fd96b884ddd9632b7e0526b616553b133758d2c1f519f19eab36953d6d51474973420d08f1046538c56640b4b14a0770dcd35e0d80589cd4b12f396d5a8b624c035e1e7d9e3da22252b76f97c2eca1a3a2e630d682a660aeddf818095313791ff8137cd404d3d8be7ecb75395409b87499a23dc1813635ab36f151668dad1ad9d73359fa94e1706ebd82e505f80cee146384bf6593979598a803b08ef4c9081a3ace1955fedae6db604a11cdb3800ad53cc8691647a5ddaf19213271f7c123a5fb19a109c948e84ff8fd239f4bc38374fcbb2df5776134014ed78c0a7ffaf8401ddd6d5b221c487079d966e459fb984f3c5372f70d3c8fbb7046290296fb749263285e7c5c177a3005cd3bfddec870b6d84a60e896b9f998f031a29f91f946a12c9a4c2e3e1f556ce5b5616d027b453dee024d3aef03e4f3c265197eb79a93131c91b6955a5147f2065501f981b344ac1f29545d74faf8774c420ca8661b88ca18585ee610a6881c1756fc805cd10a388e69904c0a7d82bde7f0671c496e3d52407979a3f8c1ad83025582fa804cfbc4538fb516d3a96631b12a7d1fbc07f3c58d5b17e81511dedb889732e81bc94cfcce828f609a8db5e242338d9158720d64b06cc35cfcd747d24a6031f6bb4cec4a3c206689b3d35db6b9af8b281770404b70f8099d6158060bdbfb0f073b3d8de6afc5d20a2814c04880fc7e82d3cc26ac2993787d87eeab20ecf76ff9c52bfec6089481521a6c7c75d353d9b9a85f017bd6678e07e0bb094ad81b18dc5a3113bbba8664104db0d12ebd306b2504e9b4e2a54bfecf3d998fe543d93ad414199d9e5f3fff7b939c6563bc6dbb1cbc1599586545d2bc093bd601dac89c1400f5a843161503c71f40d015f84c633b0129b147da7b592595113ef1a7c6f8533e9bd21624150570c5779a371a1aa3945a6ba4ecee7521c555c8c70cd70aad8fcdccf7f5edb7e35ee64737eca5c19ff8e15e44b34643cc2dff7c3a57a724e8e8d907226b331b1a430ee7bb0623690136552c4d2c6adce1457f2f49f62d375a247fdb36a0b67ec3c458a8fa0067f28c9a1f2f1faf402d84b36165180eabd6977c469d7f89c8f3370c1fce9ce5d16376737dd5fbfaef9b45d0e301fc291d9907b3f1b4fa9a564fbd5c994d721dea7391349f06d5e1a14a78a83e71bdf5c6d98fbf2d5eede75b6b8d3d70c416b252a51795e912c5e30222b4cfae5274c52514ce439308b82cce8e3e72ec346f5ea00bb0aed798997922991dc8df170cde278f8aa7ef896413c72c60fc474d9ceb4df8e789ecb79e1b58710e6e9c509ebd99463d3da3a837e78755b3a0bc59121ca5e62e138c2d87b1e201eded12e3a7ffeb9468c8453cfe8b00209f691c3420b33125ec88e33f2b682b39724dca771be8ffc8e7a9bc8986eb4caae97f44586418555050031da5efb57e076f84a416e1125f530fd9eb04a0b61ebc5abbb7b31b4e5fafaaafbdfea87d33dcc32803000000000000000000000000cd37ab5980240fa71b23af8a49a33a7aa8633c37a216ac92081889d2458bfd3e43005b8449f45a61c4c803ea8d0f862db4e5942b166e0b671827e988c658b949b28eb2db655a0ec9fb26d29d74b6d9fc94b3ba96a084493176f8ffd39c186d8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f03ae0c697162afd1ef6d7e4306f025a0d9a048f96e4ce887f291ed081dcc79c773d41b4139561a9c1b614c7b5753ac8fc1dc7358ac12d6c8542f72141a24dccc3419b47fc0e7886b766804b22fec30178997ab821d87611afd191679637ad5cbfac7c8a334501a594b38ac8e98f8e2023050687ee25b70b24080c95fd5753b02159587a687e6b5ddbfcc098e746bf70b5fd237053b865b330ebf6da4e82c85b90222ac8ca6e0e91c29ecadbe233b490fd716c65228fd606f41a713237fba80a5550a05b3c95ddc293b4562eadb369b054c4b1b01be99aafc1d9e552c3e8e825484cf5fc62742e27bbe4efd88c5390a94adf721aa96e20f66f48a93169364a3b8fd3d022137f37b8bdb92e51c6d80b0c0ad909113e2db81796cfc64239e827a9e305dbe021675ae4ccf77c1723ec8836a4ba72fab8bd4a06a963ee4dcb5de560453cb93d8021e9e941d22c4aff157782894aae3daea67f01ba2c52eb8b915d8d9a0ae79990c020db34eef44858cf987c199864ea17bb4049b2679bfed9ee7af1ec6733e7ec96c0313fb1e60bbac715be79c0dbc32dd605f614b7b61b2ddade08712c060defa1518ce94c0f486d40d4576016eaf3964c7d03368140fc4412b1f8d78bc562d1d94382965375c6d167db604352f045e090b5d95fbca58afa0ae896a31cdad96294a222bb6e9027c5588d5355a667a03c79e2f051bd826c5c3d3fc82209eaaf2e16a71d1a045e99e1616d0880137302b9780be404dea9178016b61e9f2588c6240e580746ac6808ed7d533435218827b099c07bb2d97cbf5f906db22552b7d53e3749716ede59df4af7379f13e7dba583696e5ce52ea26d87d6aed6dd39ca295e271a508d98b19646dff335e4cde2ecb9bd5e46edcfa75eaf7178abbffc17a5870cc8aa1f1bce04d1ee36bb57cd22e2469646e6a8e850dbbd5b0b5b98c332cb0ceef871e03dda609feb07cd000fc394609f55541fa271c70899418dcd5fe601a51bf6e4c3ea277c5bf0ff4d0e24a75c8edba26169ce30e6b1280d82f9e6c0fb58b5d3e2f67a23bc1ff0f4f4b47964d4d0cfde2934cd258d98a903345ebb19977e9dd553944dfc8c7cc2d1400afbe13ccb354e10a877e7c761db8f043f54b2d7481bd9e0cb51a45bfda3379d972f1d36afe30935238fe09302ea04ff6d123bb099a21bec3d6c4a428716f9678fe6a05ac128b2d30db31bb5c417ab8a7f5cb36875793ec5a4541f52434aada83d985bf37aec25551083e98c7301748c67479bbf6205c846934e812d2ce4d4f7119c368c8f289fa2e99ef5eb53ccd96ab407a73f3d053271c66b0522b5c5e7c7e5d791c2d8f061b08cd51de063f9b031b432f75dcb56a7f6f414caac6c253f3f273dc48d7208f3f3f612f2b9da0158056a63ec6a3f3121b3973e8e26faca1e4eca806f614df76184c68f8fd039e7daccbd5a32a09ef67f9806b57bfe2e09c1488cac3efda58651d8aa1a008fe95ad8a9393e13534e96ed7944b6a3f9648a726973ddb9b9864c53861743f3eafe80c308b3709a6bf188681135af9ff4d40a724e0c35a8582912087a2d7737bf3589defc96998396f2a0cb2c68d15d6f9dacc82de2cc398c05996b6df0b750d9ede1ccda487f7c7348223c18c0bcb4c652398d80798493e1a058cc85bbe420eed4b966ffd1334ac086a07215ecdcf9f28141ac0b243c15d4b4dd6f7f0f6633b7cce157b0bb05c320c4c3c39e3daa7f446481271080d5d394b769ec2966f08de381c492fcf5263840af00d1e3c70231003b80cab395362e14edef8a287daa2586c62711af8c7d227dcbe25f431bbf2ccb586cafd8f340b5aac2fdffc3cc193f53779cc14d4a292f8c892833f25e6f64b80d64691b1d153e69a193175fe7892e597ca6a9c40732da57d8c868122701fdf28c1f9088c9b1fda399bf865601f1f2c796135ca916a61c311b8b0450c5707819330ab5474a0f121d6e927d4ca25459d231d4ada187823be452a3873e0e3a6404cb5b8fb355474fd69580565eedd3cd718d0d57e3ce231e19201a84b606fec5ebfd416ef92170f742c42a876ec053021a968b4aa9acc5307a8d64e3759b62c2db7f9a0b50bf3f36b6b26bfe413919a8cbde18688ff941486f730aa15335f6f5f01f6722b4f766a51b1e640d96f1f9ba196d6a8883950d99235aefb2ef61d2a760ea5b45379223dad08f3490850954fac2d7d20412560243ef0fca7ac61d99e1b67d11070148c1dedd9f8f8403571010752e70da845844009face553dda151658e124ea600d355dd1961a4b1403660000000000000000ded3590500000000c4365075feae5c807c688aeead36dab0f657af23652c7e6080ab978319bef6e9e792df99c959104742ea675f1302e9a4944c0a362572fa15b1040edb746d7eb83953c4c64c26593389a4712a886d9009b27584b5374c14d93a7494c30ebfc065000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f42f69601686375aa901306690b00059bc6daa869ddfc111046a3a91d4fbeaad5dbdd72f01d55fb397ac110ac5d37ab048f7bf7b83ce90b59d0f14f98ebf000e5501a2f78911237f68446ef1bafaee561b5b05fe2c6a01098dcd4a7ac5496fbd5d2541b9cfb24dc89d09f84ac7269930a1f146fd964f88a2ba7fa5e20a483d50203ed1df87809462af16ce7230d9cfc0a65ab7f3af6dac4ede599d739b0ca1c900325b7bc319de5784431daf7da4b36c4ef6b30a30dd98c45aa4dadf7986442db7a0b0340831025863376444029b117253a58ca09bb7413eeb986339a4bb0347fd55aa5fe2bdfb645f96fe53fe292134fb212c018ca8d0f7f719f6a7753f3040a2fd30302121ade1241dabbb52757390d6e5eea7eece094e06fd436f2f52f9a8feacfd70321aa0203bb98f9232dbe385ab669164b6ee373765d47cc4e9c9f9c09c34e00d80313848b45dc03c6b032fd458b1ec610a2d22a15d2a3660d2f83ce3e7e24844100031884dd39037ff2b59f0e0e921526edaf1d4e55f6aa05d5fdada74b4e30081cbe0214e1f71af8d564da562608aa040f1746e812fb004dd97e848cb01b1524d5ae5f561f1b38cd71e7cd30f4c01452a0eb1da8282b6f70c262d1957cf34899ced37010ba2415c46dd8c24edb4ef95212eaecd22d9131dd7291ade65fa60059dfc3b804ef746205bb1bf5e70ecab8af74313f7229704e209f38f907304a21526e2ee655605b2c5606f4a82dcbb17f4bdd7a37912a6727611a216af4787359c7efda9a22db03f5cccc714bc02f193e3c8ff76749b4639b4d4240da2c0e48ab8004db2b27f13077f08234dbf4e298833689009177e7e066f7b4456ef5d2d04d287e212cc66ec65e9ac997a57a0f482194622c8efd9d43cb928953c4e37242faa648e1be96e993e8ec0c1f798d49d178a82fd3c33152cd05a5f19acedd5f4880e997c0054838a1e41a50738bccc8e52ad5105cf3448b0115fc9dfcd3c8e08779aaaa62d73b5bb6ef9ba0e1191bee03a37229d356e3381983a0f47e0015fed5029e636cdd020800c303d3fe42c1b3df2a673a5435b4a0f1d4d2ab914c37fd15e19b5c271c3b3d1239f3f47f91cfc61654224959047c959746e0312311163d1df2b2be611ee6ab06e8476390687e2c35a1db8f9bca41f6238cca74e3a592d2a30f4f8d0bda5b1f294adb28d43bded31114d17ed735083a1774770cd8c833add16a9bfe2364f5af4f13d26e157c4cd49720a659dcf0b4c6c56ee09719f270784f6cb8dbaca6f4454ebe113acf4899a823a2cc7852e1327b0ea9f8b6a2ca3ad6fecb4eb0ae626259ddab202eac4d2d73907fc30e65e4d160149d7cc055bbbb03aa59fb848572c7b3d21fb6422735f377e9213a6607f76bcd52278ad4d02216a492cd4115a4b77a76bcf3be8651831a8561c9c6a4b2212c9bdb2469ebd443aa271edb0b6b3dbf04cb60643bf47d3568c41d3effa2606c77b2811ca222144c2b7b29e472f32c6391eb8e5f80365ea041192a12ca69152a3b549565fb6a2ed410f53476efb2122e4ba63b44b2902133c20484b88665ec356bc1e6f3dfd6acc48f0fc7eb4ba26c4890c7b41cc9e5951ba64b9e287faf2f41983238ba860426c72d1c6ac18be71ea5d7c6a665e1d58bb9cc3ea33ccfd6db7b37885aa115ae6d48da6c8ba554dd9798f911b1d5495da9d00f87c6c937d709da34ed6dbebcdae946b3bf1258905f5e727e75e71fbf3a12d68b2a003abe96e8d974771ff6efe41edf2d7bc636c0855573bea7c6e654e9ef741fc955cc7967092eed7af8b6bf1fe3c19e28920e85d4e77893153690a51f3af70523df53e2fb5afe2eea45018b5a4e38a35eb676fed0b9c7a576dcef2b0fcf16cc469fc734d5f3b5ca8b91fef09ed3c922265d050694e0f4de7ff9c8d0af1d8724e1127cee3ed61bcfbba0c658e341d1e489f80c12dbd1e5ece6e36f472e6a83d169cc55833d9c1b42a2be4e97800cdf30e53d5fc2535274261e96aeb356166f14026019ad62a896870f42d1abb884f3424f08e3a955f44332a353a0f8abc91ca2a1b652421e4585f4625f2860bdce09b2002f7dbc19123df99b91b078d6f1849e56cca685c4d75b0a878be78ae296b52f4fa74970beca5455d4d52862a9325b3b1d3946b9c63e209f1993330dad8e1f5c830df661967391666bf97d340efcf056ff6d1360c2f19a9d7d1739633cf92d49c32b7280582c6ceb748af568863c83cac97a97a776d5a73b380783a42b50853456f6423bf8dd6190880a7157f6464259cda45d0b107ce03c77c229372e4a35ff0a1419baafeb491f5686eaad34fcca41f7e7c9281fd40c3de89138cdffe45faf896714b7c2457743fb36fe61b2db86ce46ba78882c299453c2281ca15fac33b27d7ca6c473e6b591e717ec5f1fd2e945b7b35970c5209bdd0c", "00", 0, 106926605, 0, "088eecc6ed775a7c15d5aaec1aa1f1ae9a4595a75f6ed3325d9471ea7c39e579"], + ["66c7400002495142d14b088fc60ba192778e27f0a88b069c726ed29058867c272d55785f8d030000000151f9e7764a40e1814d0271c1d04c79bf47c06c578576963824e8754cbcfe177192c8b2ca710200000003005300ffffffff04f16eb803000000000765006551ac636aa7966505000000000453656365f7c4d805000000000953acac51636a525265674e1a04000000000751ac006552ac6a7cea33e90100000000000000005027f90300000000af8c655dfefa4210b59bc51b5ea37cfbb7d83c99dbe8ab5a48998662e18d21e33c647c00158d04be705736244dcebd7f525622227033259b12fa993dbab2689777f3af66e604ae7bcac2cabd6e9dff15df7a03ca9d772400fbda59dab8d5a554000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008b4ae02e4e288017d933436965f52e8aece52771dba49def019805e42a1096f30b25454cd784a859316af9e04fcbb1265144ed5726df7bcd1d082d887c367d33c2883b466d77f11cc440d327f835ea9403a964e6740a3ccdcd05607be0b77ad4e5578bed3d7fc85b9c825607b60ecdfb36cb9e9d46650e8db2b0090887c289a9031d2af43e029cd8366162ea0f964942693c1496301cb2b28e2a51de9d985b26050301bed72018e5bf42c1b38df8368c8f8cbfcb9ed3ff5437340b200021b5392d220b051faa1da3fa2433b496cb714bac276a664faa129a108b063a381d37cf75877e95a060249aaf338d9afe06066e3f16334f62ae356f8db0b8a8a495be8f0b353803125aaf2c11398ec5689c03d1fa237a8f5ba8b85df58aa08afb1af903629652940216bd76c60ade09b18f433189d0207655263f23591655b18c2f4c6a042dfb2e12032181dc46045eff52e4f6d810abda04492420e32dda2061a854c8ac4097e5d8ce0211012ce5ee10cef0303bd58eee2305f2d479ba49efc1aa48ebc6603a9e26e07c020b665b2b9f7518afa3bbbf5e78c47fc69796711c7a875ca49a0ee81ea76c53b5857bf9d33d14db63a336cd4ad2a8f527dd1e5c8b4e1426fa02b967aeffb0d597df5e6885d0aee3c26105dbf5b80a7fc109d9ef321c4ccb52e071735b29ec289f634f79f1bf135674b2ce4ceef2b5a1424dc49df0853d81350cf153945503cbaf5c836cd2bbd152d51b1856373055ad6becf0a4ff99d4eff4ae0c277883553f894ea262eaa31ed8ca3b40377a0de80891ce4577899e251d56c0cf0795fdabeb558a29e5068ea3790ddfa3379b9cb6eb83e1fb1e6b6b9929231f5943d3407e6822aeafaf40fa70aac0815b970bd998f61d8ee6d039043cc06e6a56fb8809735654a232b91d5d95e63b2ac4f5897f659474f64fbcf8d901eb31c1e4b226d03e883a3bec79cd1cbe22b983c239854c5a38cfed4ada0ed62111a0b9f3eb76b93a2428732440bfc763b3b398d00bc987d3547c59906792b0a149f359db9a2c8042af2b2186cdf2db73bd3771657767174cf49b85812a4128eb665d86d3169bf52d0604556bf8819ce8ef710666ba60764b3182e70344f743f756ea38fa7e13f856448cdb16e140fc946930cc3f0cc461150704048220602829be2d99e0a7d14b81538d58bc9aaf935baac0a10eb63aa6b12e6f3956ee72931e57feb7c3eb58983790f59a0742538c5bc5c34e3672095642f9a1d813c296aeb301eb71a731d2b438133e0a678072dbfd118d09b62cd8a1dba028da7cfd453a27b73466e018408fcbb703394cfe31b66efb4be07e85fa50647cbb8bcb9743280e07821cc855418ef606720b5230ffe98960f0ab9e85c505a88fc4df6dab259fd5e7f649b15c1b0100f0ffebe0e4faeeaa1fb5a959103efc9c072f50b8c24f5237c686bffb7adc0369f9bb802cca97906015824d13cc79d10ec0386487deee46c37895e11ef9328041fa2e069a3baa9e3a87d1d2ffa2fa0d711fa69547228b9debe5264c8b52f26c64b7602536baa69b6bcd0f0086ef2cefe86bb81613943010830cfa1b3332e0bceaa0d2d41f6c5313a56ff205248fc48aa615d5a8abecfb2976b872dde12ac42189b3a31459b9788a2db570877934a610570d105248abc916e12932550dc161921c2cf0859508c0fb69068bb5e7708f653ebab94d8f153e01a01d6df911bd4f4ffd96d9999d5b185b172501df32838f535660b348ed18f6c31ce5dd92822c66dd93acc34b8a5f0ba4ac484c44a3055a5f0aec61c519ae8e02af1f74a916a240db609340ddb56801f24731b77b1b760ade3f2b1a41d254198ff7ef9ddf542b8e62aa4b9a88afc362a1322316d79b30d01bd4414c794b387e926097d45f9727ae0fb9df012a8364dbd91152b9b34d455fc217a1fdf38b05a9883896dcb7db49bb0dc36f4714c43e0cc77f97fcf4a6a975e773fb23d1ea97c4c03e58d505d98b7935a812199083785ac850ba539489c3dde9d76c1754eac1a63afdef1b240ffc2024051f00469712c6418ff7fc29df8f25a9a1527277cf94f2e24ba279c6be8fa72fdb81d9b3a17bfef8a53c3558e854695e2a397f0825cb50d88a69df1eaad0c37a94c2e6a964cea7e06d381cda8283034c4756bd4475a51625dd7f8fd5296950e70021212a258fa87677f1e2d4a01411679814b6e3cf567f3968f8b4577c7182042b1f4c6806b3088379b9b387d25c6179f884405a77d245aebae744406837189344c9690004f728ba43fc4f15885461c1424ac0c9934304d89c45ca3bfa9a92de799940bc615fc53c193c034973e23ca0dfc91e8060dc14b838261b102b7808789ebe6ecdd09c6e1d7b6567aece4e189ade03147c2004f8bebd6174766279a288b245d6eee17fac6813f43c70a6c5723876e8afd209", "0053ac0065", 0, 667455739, 1537743641, "de889cca9db460c328936ff963f71e9d37ff46438f6c91dd0b32fa422497ea0f"], + ["030000807082c4030289f277ac15e1a3edbc27eb443456d374d3e845c0cef676649bc46ed5c7564b6d0100000006005200515253ffffffff897ce833a63e1cf5f8a2a467326f58254897ccefbe18539f01033b3c47300f3402000000025252ffffffff03f10e02040000000001527c2adf0300000000030053000ce06a000000000003ac51ac000000002af24f3203524c6500000000000000000000000000e58a2a7d29001bd92ea7b3de07e10140d76c9d62e3a13292f1565f6c502652127f4e0eb0acee5970072c8f66e97b50104a98a97320ac4f503a5096ec229ab96954165eaf5adc3023c9cd8b5c8cb725a1f9389f6fc7d03456c0649f08d137b2c5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c732d5d1becb1a0b1f5089048fde567e362a83eb7e48b8fe7e860f20a90ee8027b1b0a83157d20311e4a1be45f4c3d4dd2ca5324c9ddb7c25014585a8e85c6d4bc98ad7e805a577e5ffb5df599f0f539ecd8570c3229139bb3bc269d7a6d817ae76e47b18f25025e5def18f76d8dd86adb31daf0d2d156fed6991c88600d4ce0204b4db5dd6cfad57c06169c3d95d20ec04b456491f5523002f1f2b24724afb030320fb0df7363b5cb18bee2a66013c580af4a326b55e6f9b9a77f80e5028951f230b0129cb973c1314c052c6069233842af084464058faa3d97820b6345099aefc26724b51ba094c53d603d97acbb52b3dce666a605ef5efd1bb57f0f0411081b83602195d941e801a951a8a9fd591961ddb8d5fc7daae4da7d7fb7f8b026874035dc30202975287581e90062840ce80e1363f37d12ef404352dd103d218c9254ff0d7ca0315990cd3280991ed130ddc62b9b0e9fda6b250c03113b5aad0f3bcafc8c70df1032db7222e1e170b7819c36966bd08c8e4fdc521e7278588937a4797d36e792b590313182901c8a1d443677bb941ce10cc54ec64d5bd6f25053c5797e76da17e56d04e3297453f56c9d446c7193074e65ec46d0d462c78f83291d6115321557bcd06d18065c3d27bd94d9b2fef81d1a23ab2831e8b9b6ccf3800eb325901a253868a89860cd2f52e753ba4c2f0de0f3cd8df3e7553b9751d4f6c07e393469713327cbf7ce9892dd2422d4b1ab6adddc10c02f6bbfa100d127b9596b49593103755737e7b3439faa448079466bf2b039dd5362633957b2e9dff756b8d03c43621c7faa987d000267db6fbc67f194e7f22e52d96020a6f706b13088019d468eb93e6455dab317145d9449e258c96fd05917f6150aa3a46c241da046667079c910423593e8de40525e3f39bdf392ee1fc215bfa61ea61f173d654a26226cfb071fa25c4c1d9e9830aa0cb0922ac478876cc05e13080163f1c59a3fca0da8800de843e69175813348666614e79317bff0ff2d004d5c8d572676c048b699319eebdded5fab14a76150f2417514d45de2935f306a179c49dc5de8db70755fdd344e0e5c49ea4b77d9503215e210aa860662e71fa1840cb884799632134cfef1ce9b6bde3d2f52ef377c015f3b5de2216b2fd3d2ed44163ef0a30306e5a0bf8221678d527c92a69acb6e2e66d54a649572990c0c383ab17c782ad3f15e22c09c91884d4e1a014c91064c53155bb351fb364a295f40fa8bc63d0f2b46d6c5a148719e156924efca6291098312cef9b90c25e312320dbdba93851ac915c85cdfada7a02cb77383bacd2cc4e95d7f66caac73289ada6c35177bdd8223889e2b594f843837979e78c7e923c562ec4bc2d2a0a08aadb9d74a9319a340c43200441ff12addc02d038a02275c2d09c0e460e02489ce3bfc2c74cb297609430c378b9528708a9b1c72fb7adbf23d12504690888f8246fc04c0c720cbc1d026020f5475922561f3af0cfcde944e4afac580ddc952aa7d47c5482550d8cae49f73af684b43c0444aaf432b2f52050d98249820802f10015b4e2562c5b7ad430d52612f2ab2d1709734d0f05ec9fe4e20c15508f417803d900b9da34a5bb1b986daf4895668acb6ab81050dc8074bbd3e2ba716bd0d4b1af66286815fcddcc8c743cd68c28c268622c541948bb042a62442a91e140ed9dc0b0e63d495a29e4c9172c79a5a3ce1060bb51922367bc0140cd2442d99ed95c8a249aa250410a228bb375f6fa2ded2521bd97b4b07b6d3197c61eea3e1f070f1fc5c3a7e760d1bbf494592886d4d0b415ac16fb9a4537a21826a034e0b662bf498028eafc0698cbb49b9a6724d93746a426da8224049db54c64dafe7c6a368a7b382c98dc76a0bc29eba7f511286598c104e7205a796a76aed9e238d97eb9b3550f85a9cf220c64233d71e2659a826e7f9f332f092c51b36e9550c74f15eb8026945f877844450138347b3c64876cbc4e13f3fed363c6c4041134e3cc1da6081b5b6170ec4a764742f5ef13edb1e716dd45d13875b5e63fed7b07e9faaabf0b717938674fa8dbae23a234549e16dfcf18f6987edb8dac5392f42384fb9592d9af775cb6fce1c7cb01d1347bdfa2cc310d1ac261c023cc65acca08445dc2c488466a97024e82a2ae8e0c720ca981434e989177df545c0dec8eb6dfb017508fb670d3110b6bdbd15e61f15315da88dfdaecb898b43343e20ea6e6b42892226aa527b873a5314353251f294722b3832751719f16da25a16affeb192f8655c2cc16e5c879bfcde900000000000000008453da0200000000d669e1b04a004cf7889d93a5846f409a93a00b5ab6c4d4ef777d42cb1780ca64bcc23c964324a9eb21d25393b467ff3edd680f0cb521de1a6f6ac707a084e0b60bcb75cb3764288affe5fdc9463d68f7fc4efdb82ff543893312ba403083ee16000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a18d9386037b5625426dfa5c87571f9c684129b2c15fa640bd3b1d5cda05a651ea1c06e5b40e65afe08b26c5401ff39e093cdd852d867c42fc75918858ce3b38a89440c508cd14637e29a79f29869241f5c2a49f9c8a47f992408df81285f747c6c7c10c51400bda8101df76443db05054c8011b8a3f9f401246883be6610a80324fce1e16266585003445ca2d33e45025e105d2a24ec099a9420f185c24ead91020509ea32f77234afbaa52b86010bb5d7c6e0d5a324771b5a30e21c10e6f566f50b02e027498ff6dc1013a6603533ff722014b23aba45888427010bed8a4658c1efa85977d5a047529b6754bc5c572c93958cfe342ea58a999dedd546b58606f42a020e654fcd8087fc45b47bc2b9349bad7d93830c746daf8ffeee395ebf6e1a7b0502163bf9f15337efcfdbf500c87004ac39c140ab9bbd98ac582e65420f7c0001130219fae4b19a5a82dc16c5a901da6d84f78e1f95fd0283e09dd1bfc4a3b4c7a30f0305d385e6560d30767a18055f8a37a985f902dbb73ad8c565c70437f34481d09902158fdf73ebc00a35062f4e54c9f99c9c8fd3bc4412224efbb3165b4b6b976578c12570ac92fa0b01d3018f6959cbeede9b2fb2fe5984be52a9b62106b8e964298150e0a07736a3c1411ffb27374610918c45883c71064f90d06d87034d237a912670c3ce908b9df3e9376fbb386e2c9cdba71646d61f7544e3874a182100ce187a94f7a8272b965e2cad448c5729ec49ab57cae88c812db82fb77c13e9cc305d1a6f323427d5b04c04f9d6d3e71d57bec29df389c237ee2f315e99b3336550f109252c8d0fb6c653f402df1c9a5f6c4df8f8bd38851283fa4cd7c80f5e0193734447f38cdca00b90ea114e00e739399149bfc07a35f48724479b2949e1eb27ea1d53950b7aa866cc15177f42e1061007da12534b4638533f5bf5e4218ee08f1e1b04e98e5182d7f40981287336919f19d7bc96a64ae21adabcdb637934bc62398a72ec5a59cf70544ce9d0d32967a0fd2b12306c048f3cbda4a05257492efb52aa65010a9b2c5461a665d7156fde68054deaaf9488a29c4e3dfa22d46d8b278bb5ebc30be4dcdd18cd4afce3376c209a9cc4e3a3c884efb1b5edd13488f409a6b9982b7391d2f4e76d46bfb30e89e821e1d5f9f93da1a9e71cc83b2ebf7d1991c42ff5ffb1150eb279da39189f7741398c07b3875fc0e9ff02fd98d0de16ab6b371a55508ff3ac31e0838f2dfb5da946c2d9075754084349e309657cfb5a7750caec0e5631cba8e2df49b4eee788ed1b37b509956f98909304e970eee917578685d4dae10a98fd15f13e6109d6e95abf0646d3a344eb9a20e64984e45f55dae4e9e150675aac3a8f17532aa93baf1cf976f18913bb7c751728a33cd6778d01fe29806a997ec157edb01944d1683b4a261573085db4c4eb3c760818eba0312e90760ec277ba9c539b68098618fcd0e8b22609054c1bc8f0f6a5e7d22ba539cc46a7ddf58d15bd17793b3bdbdc73369b9c6408588356c8d4b8b423f160ec255ffca1a870f877ea467f653bc413f0fd294d339a7e57178770837bab9244061396f39c7fc03ef592dc685b2c96404a84b5d5d2eb18b1420ec280ecf6a507dc4835658e6770a319b79fb64010e7f566f8e65deb2b04288e85fcfb6dc06bbd00b805cab87058fee777cecbfbd6d97713cb95c817675aee3944c6905485d50dd91428e116008d538c6cf2c2554d2c06e725d0dd5fce1a7426c084cf258254fa6f5a2f8aaec143d855012712fc8b73caadce2ff19427225caa7866347aba9c817f0bc5a893f9b38bfaea9703e9135e3f42f3aa8c45a488e9b7b4bf693e73a9dc0e173f8d42c309583a5e32e726e6efefdca990d4d4cf832bf97eb78ebdfb55e3216afbca5454f07c50bc009546bd33524d7c076711f4b99cc0e8ed612a6863b57add168255a1239752bbe469c8b94a4bf233e8bc24dec7ce013c0875c6656d0a710d826f7414348c1913a29c15db156dafe3a3d58da8d9acb28978032ce748ee78bfc5e7bc98f664a4d335961c89dd11e865f1b87393e6f660e76fe6376095571aa52029a9ffe1afdbc2311c65debe43b38ecdc041d7a59c1794e5aeb1d7eead9e2562a8b6bb7b3ede4936456676c9c5df2d0fe510803cc1ec388d5e0621c976a3a81ef8a7c60218a5311d59760bf46b31a01caf0db777d2abfc6f0bb25128868d28e26201ce5a33746318989b4cb27d77c910ea8f94fc5d88cf67ed629d4f3d37b46b81a8c231f53a01f15b58c2dda019bc36ee2660086fec020000000000000000000000008d041a581e6cf1f7824dd97b8b224697b687b3c4cc6c6b21071b78e014dd4cec2e35d0f0c213db27d75517f1da95168b742513c7c9ffca8533f14e733adf6034d99c5f78f33cf66f054df225bcdc3624addb57a7b19dd73b4717964c072fa0bd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009260f1418002dd0aad73aab9a67df1a47197a9cf888dd04f585cae64233ac8f1e99e2f3f9819f3fc8aca8ef99fe19f44a5115441e020bbd35242c98b0972d070708f716eb8a64f84578a066dec8a28689785e4cda313a0b0fb77084cc6d2e0950201436d6aec7f94236ef33ccec07f44aaa243bf3604587e45643302045d580d032cf0141aa57b7463eec55a193f5ed839bd097e6860ad359a64409998d7f48cc0032114148e576c450e18a2f3fca277ed23777950f74425589b837e46bfd3024d710b05153cc89e78d7ea89b68be14d6467aa0b02728cec074e2e230f1d512de27eb2632392b2aacce1aa581fdad244e415fc6ac8150d07b7042e5a64271e438dff53021b74115f5a98840db01ed811959651c8aa09aff630c0282ddd0327c879e68905020a3f1bf694cca7f64a968d9fa3e8a576fc3d4462fa51fae01fcaf4105382034e020c82de0419ab3293f79aeca197867039fc346ab1acb5d3a2c7c4c9dcdbfe649d0303de53a3492feea820580b968b0571619838567dee88ca593766ea0d595826ab022f9dfb55e47e7577943a79a00f147b73d13667123b760310a41fee1ec1e00fa8599c8d2192046cd9c4e64bdbc01b285cbc36ce4250333759856d33e1f124fddfd869c9ea1a58abfd7ca3fe1884953c72fbbbbc0f98896e1468011fa1c6e2b0903971acd8e8fdfa6f76bcc0f50829ece214913fc9b1837128531977043fd03efd555a176d1fc5f3bb8311f0c7defe15b2b0d52edef503b78ce4af1a8d75f993412de3b0690db0876f70eb424a9081c06feb21d3b28b899cbc11d8801103cbd006fcca1178bcf378fd08a6c0440ed04bdced819ec3e435a307fa956b297ab316f55c4ac9d97d7cb61093ef386766a3a383d3c02872495d82e3ff547e3354fa636f10a6a0b468015704d5086741c96f0ab7162adc89a35202af3947b975212ca8fc24471c866d47cd497c45e483c47110e0f0ea036e2429298b3aa63abdecadec4c844777e4591ddbdccc45ee0cc58d9635b5230eb6e7cc78434fce4424ba640190dbf72c387dbf73c5faa99da2fcf6991b7c62b44031b3bfa55dddc4e7411f61785542726c666535ea86329db964d75ad846aaa1f3b829cbcc9e0bd56e946659ab7efa2ec9dca280242336f6ce8ca7c035b5b1ec87b9c74ad5526275a706cb1ffc05d31b4a4c0751c33c9907447253362387fc75380103ac00d55727eaa9cc32144c31d2f11307a742eab1a3f2a38c417b71d6228a213d2b5f7d1ed309114f2aa645cc86c7dc6bd1852a7f24e3cbb8b2b6be2d1477a7b069744c8520fbd3323144f4cefc83cb0e63d591147b450d3a3cd01b66188816600ec97ce7aae5355b4f0cf419a35ce84b84b9d1124363be147f8ba79f33906169a02cf6e03f5b17be77656295e413293a9a79798b72bcd2d42a4c4e24d08f95b3605a65ab21e969e9287cf86743a837f0f62262e1e1a2d4e6bdbd4340b8247868125ff8de037dc180b993bb1279539b6eb285aba1b9dcc7d87c02b9f05f235bbce03e4cc540491634e054aaaa79e1c4f1e5a4885187d09e69bdeab1e13ebbd372925976b1dc21df6e66905f961ba4637e7eba732feee6b88793687c4c814540eaa863fb97e825f516724ff41e4eeef93eb8cc3e20b44ef93f44f5f6fdc97377c9d9bfd192324fa48570f077414d37c0f2540720e4edb42e2a82016aacede535da85c95468714a12dfd30a72665748bd926b15c44af59b2d498a7c6a3c342463cf2fb34cfd31c8077eff321f37ce3c7f165e575ba13bdf65370a369c989c667c0f885174af25fe765994961c0b9cecf7b401558a3d0a9cb693ec58fbda277dbde82f760db77629e91cfacb1a454cd81b57c42dc1e0fcabd7ce5a1528192ef19e3ee6a50b9fcd94840698a1576f95b89f29581ba8d2dd3ebc404131e793b753602ca1900eb5c3b49268eb3c089c1acf4899a2be95e52f016a5cd12e2cb97306e1c196c13b03e136b01aa77d08dde3359724fc4500416fcd7cd632e5860dfdd3e9a5045eb1a253c5f29af8737ecf5f4e6528cb084d8aca4337e821d4db3dc68dfecd2029c6e3ba06b66b83ccc8b768e6803a48fdfb3b6b9dc4e3649fff1d6f484ac0a7dddf754953be69dcf6fbda29e2d63cbc432f8e8c7ee0ade69d51cce996a040d9843b02683d758413046bcbc7b8fa40a4e10cd7d3eccb762862bded565cd5ef23edf1927897a7b816e328c3c8abb9bdb199ceb0159714318a73f77ba0ee53d8274b24b1959aff93f4e1e1bc88a35af51dde74f36a41abaa8f826e0929bfb4209df8c331f0113086ccc9a76c31c26c982c8abd3ab6a8302d6cf1887fd5acd8b0cfce7a58215c7eb1d017854872360621d454b969def4cc0f22d0d6c12a0e7b7bf57070ebceae02f7673c2965d4b2ff99ab16a3ad2d22bc427c9d9a0d", "6a", 1, -1222303870, 0, "1aa5380bb4ebe17a9e117c2aaf25237ad067767d7ae89730aebe7436d3fee66f"], + ["d5ebb1320469612a1c79b0d2a3e35d03c25153ec000d064830dff5e60869d9cc53e99384f00200000007ac52636353ac6ac9d09de8b5025d45c8b5536820c8b54a44810d4353cc08c8d155f6d9317a1309fdd3311a02000000026aacffffffff2167db1876305abc521e37da77f773b4a6349b99554f45139867f15a3d685441010000000652006a6a53521c00f3abc128bd4d7d32fc8e29ba9c1a334e01a03595193611db062536353dd7224934470300000007636363000065acffffffff02cbe0c4020000000005ac00656363e948440400000000095300ac65656351656a00000000018afa6501000000000000000000000000a819a91fb1f4591b89e4f0283e61ffb2e9143bdf24846ec98123bf4c3cf013d917f8660782150046a13ddc6a5fd0eac543339cd5e2dced9a6e4f804220ae442ae377efdc6b2b40eb6780ed3f46194ff1ce47b189a3002002e638668424a6c3d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b55500c19d4b582ba1456fdef01441b1fe320df1a1761649bd824a87f127abaf5d64292ea2f99a32c627d3997fe8e987e79261f226775e12e58150275fe871aab6f29e6a065fb4fb9fc4e11656115ad5c4d92256214420a4473dba4be12681d07f67f99c28e446c22ad061040a5f83d692104eebe6ce821f8aa0a5564375969f031ebcddf89577f583d162fa8a1635b583ed3283d9c6c53bf11c2179a3da96e5ba022eb12fe3e692947d4b3857360f217e7ad4d12eadadf7472f5e46e34bd30de9f90a00807b890407de01e76b11c5805f2a1583b68ae34fdbed995b0f69e052788971018697974d032dab895c35be9208a357345a5301a70a386744478467125c739f030f4d15808acc3bcd03a11c020a0d8b845c7d887b17493cbe9e8c6b7be5873a6b031ef3605658de028e9331e378bab31f1bc402907a6dde2615ff2edf8a7a6c044e022e1af3c5e5e747bc68780f043e8a9d681221f0cc74880183dacf06b73b0d9ff60227f232ef19338d5583f24f53565c6595a6b6f063478ab6803857749ffa8c80f40302c39aa3ef6e0fd6ade0d7f80d49ecbd48b5bbbd50fa34c39b901dfcb599a8e2c34c1cac7f3d2c526536fde04607485db4956d614a3d00c258c830a36cb25789c66e6983cbe9c44f1badef35c6255c76fb0a94c5928f9e7467c1f8caa0b13aaf59c2b65b53c746dda925462ac983ecb572131e738b4d1808b3f59c03b7a5454499d1cc87e2af9fe922f34924398b524b694f5b39f7e9f39167341acee5c6ece990c9a211c1188217bf095885fa11aff539ca802ac7ead0cfc76adffb13924e3a813c630a32074b025ea57adf1f735e878795987d5c752027230aeb4d733b01891a682bced410397cf271297c26c3241ca00c1f00b4dcdcba564469065904ee052045faaed081a4f7288a572618be92591672cf37981b350fbe3d01bc16b1f4acda938a897833a2ace7143d407ea01c104a519e6c77d6dfcdb6b755f5028ef7c880ab86f8c7475e80e0ffbd529f7954564bb691978a9dbe6b8e5f2373aa33ae354a92f094c75c0e24dab51600c3da28c31611e2a780166ee0799f2334ed8bffba1ec2f4de3377012cb7e9e2be56f2431935fc390c8ab231ba3d4bbd75856b1412efb521837802cd8d1ab9803bbee1ed4d091aef8cbbe5891d75e88379485f7164ebf7f00fa2114ff9d5d22f0fd1132310f75fdbde9fddc42c802a290eea6abfd86a9f8368487da313a294a7a57f23bc969e63d32f1df6f803c96dd85bcc80570d2f5770126f08ddac68a9fec812423749f1d163c6fee7c0d852c05ea806ca0f9a1241fe9fdd8e30f73d3a699c0f219d60c8a627fa954cede86c64d84934ddff1067f2959f54d42f318696432aabb0650170565cd14e531aa79e7ed6d3e7daad70de99b395f834c76fd16c10dc21849a7926856702ecfd67eaffd7ba6156be92d80466c938a3ea6079b8f6961b085b432358260a21a25641efca4ac92eb86a99de70501b2e885a7b41ba98af4ae36aa907d45ccbc75eddea630aa0a1c40923f007b3710fc756dd16c0736dea646b56a7b4e16117fd48141a132f5c6204c0e36d662399d850ddd8d2488d3fa0111d7d6d556992224c917aaf4515754cd61a5accd0f4e22613d4de8086a1944f56408425645af5de0d4c91d90207f78fa8c3ef3837b0305f7e66398936ec25f6ccb581b954bf4c3ca03ce0789d1a3050da1c2170c495a756988d4a4d914b1c383f223640a3e4a75c0e4cf217f2bb3c37be2398b90b62734838e81d54e5e6e16f2a17466f5b84483212586f71e9684791c895383be3b4fea5674817d89b91595d4ab0580c86c8c2d757f65a462717b8870aff815cd166125452ff0ad6a4c5643c7e180b150a31268132e42f22399abf9107506f9b18d911822ddeb4535b4d7f5debc98557824f468eb55092f584c201f3abbed66f465108f76d9bacebb0771e80a1aa317a25c8cc0f0c6a1932f19885adc2e665aa2b7179391853616ebb7877038529aa9a46c859a6077d9d7c49ae34cdd8e376448ab2c2c3732d677692aa66f0fb9c107b02446de57c90036af12897047cb3229e328ed67a87202312684e488972a5e1e4ba403d7e4873c2347219483d2e9b79425d724ab629964f225e04f32d6b66c7c75b9224c75d7942dd4d6094caafd89e113327b6193ec8b5b1f5276b356c944ccdd529b37e06ea95edaa09899378f9517f5c9169c6656095c4bf20ad0adfbc42f8586a4299c8af4591a5d0bc8a202eba2617ea74f159e4e522ca0a69468f311b3b2abbd2a1a380e4a62ca7048b31da125f6cd535e7709adf2fa2b7208a7213581cfbb5d0082642e6c115dbfcea55021dd0c6cdb6ac691c1c5ea7789ac4ad17a7f34b19693a347245024590be4ce97b3c8f96a5193eb454937a7819e116e397d4578f6c06", "516a", 3, 456556175, 1537743641, "c389852e68dfca984011766845c9228bd8cd11a340dd353df6d0cd689b3bec6d"], + ["cfbbc21004db57f4c43b88dd993e1f27a5103bb45bff6d30745fb5066e16d91663505638f20200000006635151516a006b4bf3d2576f29386d8a046a4752cb0434963a520b8e9b96db434f5b91964a5dede081c10200000001ac788eb485d7aabd5cf339a9262aee4d79b748a95fab8c7e03723493d2aeadcbe2d16a15cd02000000056565515352ffffffff0ccf11104cdd90c40dd03755dc5dbc47d2d2a5225249eaabc27b244d14b36dc40100000001acfd87064f04a029040200000000004b36fb0400000000045265acaccaa88802000000000953ac51536a536565ac47351f04000000000000000000030000000000000000396ff00400000000c19e1258336f6131bc6fdf61542e9a68a7e98e12671d548b09180fb4927cd38bfb3442a7aa5b10dcfa8f999e34c8ed65462d550393d1e5515da140ea29eaa988e2992678c37341edabc1c4332fb2006aa02a24bbdc242fdfd446c0dbf1899e520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077a61f627d046292e2fad16df94ff0f660c22f3be25800049355677282701d4bd149f573e1d2dffb189833fcc94e3c3978e65ac4a8de77e2e4240b718df5cae82446ed121654489b336227a57417eead6991d366658f298609b122cb1ef1c718f5c5177c2d091e2b6525bb50ecb52f6a32ee33fca8848a8d2790fd6bc5ba034e0213312d5170ec55296416b9a3f33f13204212919ef6d44c7ef8bc812f2feb04350225f9297b343de50bc33709e14ce56546cb424bc11699db500d22e85438c3dd240a01d978eb7a391b882f651cd1b24d82634ea5ba8b79765025c51fa2c8c2a13c53b7ebeb38861ac9dc3338aeab2319f2008df2daa9593e3c1e4d4035e965b35c980218ac40590c617187d72f84d25052b872273ac07dba78901b4837813daba22ddc022f3c727bbc8ea152b08bdd2f53c72a3168df30eab1de2f7006f46998dbd5cff302190637902463e1a79f17a5d093d916b7e8001cd3a39fac853878b1f61b35c4a2020912ebbc1decdfd41f74e630c923701d75fc59742ce7066a99335a549b6d930902128c53a58ad614ce280eb072374404618c8ae3a3f69e2c9130b3ca2f818cb7e17dc5d0edc800f3452951669382b6207bd2f890edf8d92458b8d9572ebf1331095779f74ab3cd17905372556a3a4b2de0634feb1b3cf63b50a964f5c507828c9a0ba9779d4b2eb0717b4465158fb62b27a091b6ee81b3118141a8cf9572b18f711fe865fc9844952fa035c31d8a12fa21792bfd9393a03eec0689137426275a798afff93248d6613b849944bcf1dda6d8b58b7ceec3e861c45f4d6cfc03c55e81da2781f5a387830151ebcce8ffb9a31bc3d9782f0ec281373ca32ee1f26f6b69628ced6c1098abecb42993500e75b28fa058a77c3590724de2303c5df1e31e0886db833dd6c498acded301b09b63b94988484062bcfa201a979e1fa150128c58dfd642d25b188c43767abe3f22667f5864b6ec3bee58c8e4b3202f5b24df32f96e5e8eb85db2077650a8f4d7047b6c20865ae7c4c66bfe6433b2d07ae29fa47f22fe0b77c93ef3013b122e8e28ac1329a569ec6fb2251c4f19607eabd726ed43cf467f842ab32017c2546051a29dd0151ba6ceb6fbb556079649eedd847db0b67b3ffc129b369796b6b4ba6ff3e76e397489176357050776661375e13871d5de63b441059a6f898a707a1398ed8f550161645575a844ed9ad5890fc27d7078912dd70301ffb93abe3af2a5588d7c8cdbb0cf4bfa63667a9cee5fd8c5964d367ba84498f54decc0565a917c05a2e063f5a478e56cef4df479a961a14430256f19fbd29ec2608388940a565796510fa5a1aa2918f9f2f734df23bc974da3f643143e24bf680a6f82c317b239af29c7773805a856c65162c9b915399de5ac238d22e64b5679b7d62a492f29f1c8fe64f56777af6549e780cc29eaecf33d2164e9dd82084c11cc86832b235c268106721946a73a80969a35301e716cbe634f1f5c2ada97ccc96bd4908482af4fe6d7b05c39bc93c62115edf51ac9ec85cf2a29f61d382d7afcfb1d101fea0e1cde3692cc2e3110489c11c28949ac322eff9eae47d350703aa32ddd023731454ef87ba138ea16203166dbe54732393404b560257885b31e0a6ad1d877ec8dcbcbc70ebbc7d1228919521a5b50e16d7f35f0bca24e8364ef98ea1ef326c7ac8398206a63c3e8ccd9f507e8ddab3092d1bbd49c2d332e2e1879631cd180b40a404ed7acd268a81b0d7c54033cc51f99c49675099c4c096c734883caf97169d402ecdee6cc29e0629bc138bfd955730df2680afd8646069e71762b2537cb14e4047be5ebc3c6d2e068ab9a9b67510468a364c2480b80ebdb12111b0a43f1507be93b51a606677387ca3b134245f3c359d397e3cdc68dd01c37670a87be4fcb46c1f53a01a18ee085a2f678cd5628d62086d719a782d35673b7112a37fb6b1472b48af7a1705746c16e3bf9f0a1d40b6a32b2bc2d9a2faf43c63aaa34c97bed2162258546a7a4e122ba9e33318a07efd3abd46720f77bb60fd08d6d1b407d8e23ae59a069d2a52d33b82bebd62cf6a0500d0a0eeea9a2805c5def3a3f536e80c26e146148ad8df509969c85b8b5242de41045a0acab75e254c5df1d73c514eb729c0555204e3087600f63c21568c785eade5ad4f371f7b9ab1d227d8efad63c8180bfd23bf7401b2b873898e1be3bc461dd31e0bb1c1b6e7f38ceb76bf84d5fe8628587a7cf9e92963e25682ede10a02c02cc8d3a6629f282c6b31e88a20d40e4122800be9bdaea6fc30000000000000000812a7d050000000091c6874a41398149ebd5a28851e491fd0da445daccf1becccc0055fe9ef3016caba306da7cf1f0d774eb8d716b7c4d0cb563b0a33a1de3853f3481b9cfe69943f0c7237c4509cfb29c7ca622d49ff6a07eb90f23c42dfc9194708e4b3f38252100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c91bd72fd83de781b9df0c9e56df0c0e88e0f3f34f405442ba90e0de30b10b620c8095ea011f5c2f93b4317cfa8d4b34d33910aa344bc14baa9e64d3da26e1d0e653cfad79979c46741a85ed89b4e422b98f71b40680e90755cc4805b53b3b645ed7abb9b942dff38ffa3c802f3ff64cad2b1bdc598b2cd6dc94a8d982cb075b0221c20fa3fe71249a5b76f2975ad36576b78927e3872a01b114eee6cdb31f107c03062510aea61188289cbae21906b4a8dcedebd51759d64d0255113bcbc71286440b0645b0d9accb922cd0ed9f7ba1a02a81c7fbde358cc906d18159ba197285e49342d3c532274b27f1b8439d79c74d394fb1f0a46285067a941a83eb998694f26f021eec69bc26faa699560a953b76c54673cf6d780db934cef39493e76b0787cd950214117c7d97c74b75dd6c248b07307783c9fc7524b090d868781cf9236be8edf6031dcd189c4e382f7bdf144260a2ec712b89b98f139262cf431afffbcb076bd3c4022d45e355ae10f102edb3c6d2820af52998874b08f288a81c8f9a2444dfacdf4f0203e1ee662fa002093c35723632ee124ead2c6a5844443a4abf5ef1dd6c99e9cd605be2e2775a9a352579f973c6e1588d9863aa0c93662eaf2feea72774f6a545cec5248445d9fb26afdd2223d80090f95f52c3dc5d976106917d8749eb423b6715e77d4243e19d436e4d46ca55f623d90fb093daefaf899ecf986c9e0a5529f693af4857eef54f68781e597dcb99087713b928ecc75ab46ec54f21b8c8567c4c59a068b94c79048ea54abfa51b98bcd523ee251bb31cddd9d5c33c780de3397d0f5704c75eef7077ddde9bbb4495714664f5a15a2d588cd6fbe69e19271d5a393dc3d5116656cd88c5bcda9bd691fc4e54b949b8a5c98b07913bf7d2106348e3562b12c9ba0f2982b327b595b86d79457ad20dd25f903f72f2a9508c6a9ec34b59022111b80cfff93cff54d42e28d630a08ef4ff5626ef6ad34a8c2cf61d8ca89470633dc93494e09e7a8777d79ade2b5c34fa7aebe4780a19fe38c5d8e1a4909749ad649c7402af4e36a3450dfcfb9c02466eb312cb2c871ed52a0c059bc1b1b2f5b22d41985b55fd225ee731987da8bc61c3f34acea5ce4c6d8b087ed31b594fa8313937510f64cee72d5a37479120f601d5f1c3a333ea230f6c21e7eb69820b8cce0ff7860deb50af4cc21f935d4f1e1d657ae2e384cb4b58e5b37a1d9984b9ce5b3f96ee6622525f02ee856ec7d98d6600a75cd7c817b92fe3dac769994f22d56f62e9a902a6e477c655af223e6dff052088f40f0a4a200373bd06b538dc8d0202e675f181746f5b71ecb98305976594bc41c0d081067b7cb1b1244ebfcb3546ea8f929d1cdaa41aa82b272c344497a963e46b1002aecb0c482cddf559b0b213378d1ed1f2fadec2ebfe9ad0f46ffd3f64b8a4ebdce9028e1aaa43a406874532f86803df7b3bf30325d4f5501db1993770965e7fc3bcc95d0a41af575d4c60424d2ef3dd575bf628c61712652e1e85c8d914dfa96b1753541916aeb6935d6eeca28edee36b86eb6bd65aa59a9bda736ff9cbe819e75bb9e0cf24730cac9c6600eedcc1889a6b804f5cdd04d74daf1bd1ec3033f99fd5016b486e7a6f5bbf476845ae064ff002db9ea2a926524c7be9e556112610300730d30c4a6ee26ca02657648c97258dc97141f583580446e327c57cad89e1e9a66776d10510847521dee858bb14d8f183397ff39e270d46c75c4b1a95e88c8b04f475a5367e209bbc48e0949be800024a5580cbcb4f01f51f48de15d2a8c3c5516703ee61db1b400db37e6ef2f8ea0e5d24f990c74854b8d8406f49a7772d876b7d900315ac79665bda2b717fd017654779ff30ab8c46cd86eab10683f541675523f34cd89d234d7936d2e51907c73c02725077ba0bda91a5b84ce2fb1261ea074701c95e4b7fccdb8ba8f1832ec286cf0501ac06b9358d4458d47d4a612fdf5ebba230eda377f93426d4289e03d1b3ba11c8819547893e37093a7c987a31bf1e6ca2b2d437bfcf383f48b8163382e9a559f06a480109d8ea75c2c0ab61b4d41baa3ca18be2c52c077d5029167c3fb02e8d1d5f9251072eafb92b018b8bc499d3140ad74eb146d83d2e5bcd63a9787e111b81aaef5c6f463b570cfd37887cdb0789e8f3642acdd53f381971360da02d513dffd40dac2799210c2223676b74135ba2579fb27ebe72d7ec3667c6c277f8af83bc411f17c1e46ede2e9220b314be8b0747b70ccdc09c181f8599e8d92b665e0aca5b50b7272818c57f0000000000000000ae27260300000000fc29c74ec5e20927958cf9db69ef0cc3439090b7ba5b45627aaa8742e32d0daecf911ca6fa134d790fd7f7cb705d73c421ebc2ec7c71eb0539fd59d5eeab7f348cc9096666b931db71e377403d2772cbae27060092477e1a62eff22c05fb42d9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008cd1c72060a2807aa0e310e7cdaab1f2de4f66b876bb37e2fd24a51414b32689ce65133e345fd84a6d791a9534214b5813e580eea8e2237740e3e73a710c7984bec1fbe41511563f4be388c8d324086f655502cb7572aec4f90b2bd498c5b880533ddfb5405f07b9c0ac38828bcb1354b48eeb7a0eb39fcae6a16655fa11a7cb021b80687804ec1eedc7732e20d4fe274ff0fa3b0fd9f5553f9eaf31929494ca6d0325d1258b553e827176f16aec2202519d72a61d0a5354369f0b631817051bfb580b00abec5eeb5de30114bd5754a3e8429a35b7f7e8c99f6b391b801838286b292c5772008d43818a02cfd5c7450ed0208a712b70abf2b67d1811038bf1a9b492a70219a95a0ab722b0ed946bffc67bb42f3550ff6aa51b2fa48c3c2bf8158519f625030531147e86449627880416febd3b9c8b86d0e3b229c8bec5e54fdc155ba44ee302276d5b13298d1b11842b4b68b4730aafa4b2031fcdeb55b0f0ef3a34981bd5e9022b948e494b06a85c5a7b06749a5031ad61fefe4b2531079d9e5cc6cc78bcfb110210a9d05bd3a448cd8447bf224a98caf69de7d1832d7babbbf8775ad363c60adab8770613c2417b265705a71faca91182a30f88ff52ca4b6c799ae8d681eb3ba5cbd5509c5d8eb0ea378dea63af8695d6be062d8c048470a4c53a1c2322b4198a48e223ea664d0f51aa6b0b158830c9c9a80a02dbb6170e34ff7b4fcff371b2c6dad56896a65ee040924eb7959866379c799de78b3bee44ea2310099725764a9be425d83727de91ac6e00f168296105c795539dda79e8a2e8798c65c0368a11e1b5d1324255f23a52b481b574401542e84da0c0ef25895d08b13549ce21b0073883ee73021e86eca96ef260d339e2107fda6c775b007ab99c501a365b7bdeb722dc4c23f0b78fa6d426661a39dd747bacff71683eb3e3598eefbee377afce32887b4c42adefc687edf9b17a4e8826f1747a57cff8ea28c5aa58be97f65d063e0ba4a9a1b4a202407fe853b7f5fdc6aef1920c920721096af19fdcea3a2216a1facfcdad605dd836e1014f82d1d6d8fc640488ef9efd3b12baccaac5efb197736e6224211d3dd08700a8e14b0208a8fa2886c5c71176e04aa376dd11b776cc6d7a50f6720d0fca26f7ebd897d885d24c2a53b2eee84b7aec55c09c12e480dab18ca3091e33afd89a2b70990936c706d88a6b22675597a7e6eca4995223dd911838f71e4379f696753a9a0e4d35013a3c47553cbd38f88073364e3fb5dca3983dfa16633af445ba01b1336cf48f7187cd9669995c774421e7151a96ad714168e656809fd1d9a62b9f115d42dcae407ab35fc36eda9aa6f5e150e2d4fa30e01946467dde1b704b2508a777b9e812b560a20914d0fa2371816ea1189c7157c806023774b783eeb20c745241e2415b0463ad546919299c02959816f89b71eaac823b8ecf2e5cd6e00c55e6493ec3b20146601e8e74bb103fcd0c35544e38e54358fcc2b61298c21baf061c75f6d42ab20a583f5ce2e09bcb9f723f8f72f511aebbc02aad77347b3f4bfec3abff5f5dab9346227aabc4f5c374e8ee5e8cd847db1cb09fcbf8395baf5e1d356c092d8e7bff1f0fa5ac4992616adf03e434f214edf0402680d26bff3a45b58113dc33f0076a7b24afba5251c61b4d7c8a7474f38cc60efb85b138275d153b7d0db4747b852cba130689e582f67b00d8425abf4a544811be13aa94ca8528e0b674b7b5e1663553af36fdeeedae5efa63d389aaa204163c461a5dbe0f4b0d4674c4ad112b19647fec449c50382efebcc45fc46786b90713ab81bf44ab3778e69e31f507658d893a41d3438a524b4abd9d0e8f35a74f39c87204f3dda521e4962e66e14bc13d81eb566e0582b9822aa2c61f8f0df3277c3d9bd650824ff6fb1a32dd9ec31b5a3f9b20e1bf44a610639bc5e97ed971f04e44480308aa6a5ba109125b72380ce4983854d77cd6263e00309b04c8387e2ac7321b9ed1cd0d01c34efc561bd726810f074bcbc91258a40c26a2db497d08e70d435f3bbf2f1ed5fc1b32257892af1f6653c763537281652ed27fdca08ae8cd4d5ee32d7306f4ed95a6f74b2a4c829ff578b3008b03f5794de487477a53cc1b3da555796888f5be84037b9bfdb6f8af19f18ea8c157fea34aefd337ea55d697bed327ec937094d3ec8fddb9d90d4913bdb723e9322a503585e1011d52d5e31a52d0ad095cea3135f808f650831b354426cd48737fc6dbfc19f189b49d32ea4308debc416e656a64d2fd15081097a0b2e9ada9ab70ed8a26ab8597b72a2b161254f7188f324baaa74c71723e6215c9844199d036af32ea09fab1f3a1edb378ecb140954cf8fbf0fb41144c4f9c18356859dfc80e4aff6c3ef27d08747609456ebed32840d1ea9c142bb2a16e32b3a188cc0019e50f", "0053006551", 3, 1575428823, 0, "2d87beec6ff7d96be91f95fe8439f9e2c8470a272388165a4196328073198199"], + ["0260154501a8bca20b25225b3e5d8f66b1bf60e17b826632f54f62932a388afded065ecc0b00000000026565ffffffff02cfdd4f0100000000065253ac65ac6542f863030000000005ac630053530000000000", "5152536a655265", 0, 787355631, 1537743641, "1932d32b2dcb95cf374fc5f5f4be46a8272a70536e98da150cfdfc091f862e78"], + ["0546741902c73a20f3cc22095994bcf6ea8fc42fd52bb1454480cd6954ae6a905e3b04326002000000086a6a5353526a0051ffffffff832511c77a32fef2c1ff0581ec6d9f5d39429e75c10dc0e2c3d3d45e1e97870701000000066a53536a5351ffffffff025c5f130400000000056a65656351837ce7050000000002ac000000000000", "5353516353526a00", 0, -1924696480, 1537743641, "3c58667639ea7056da12413f0a4f3e44437db6c3f316ab5c8eb3b61362e73622"], + ["e029a40a0227714e4609d3b6a76fc76bf6b36d48c485b1045719df08d2388b370b218a5c4303000000055353006551ffffffff09aceee327be4659658038f3f976ca517bb7509af2c5220d3176709d68c57d5d000000000700510065ac5100ffffffff04eb5d14020000000002535164004901000000000153cbb19b0500000000026aaccc388e030000000008510000ac516351630000000000", "5352", 0, -367524853, 0, "5f7e5dd9fb2f1e835a1d5db1c3263ba92295702f13062d3ed3d9a660349c4940"], + ["c73b5f4103ab59d3b5bae63441e72de22394bafea62074187e9555a78d1b02aa3d441f7f5501000000066a000051005295494b2c9dc8186ad05cd4b44147a6b83e47fcafc3e4e1fcaef786e5381dc9642c9e078c000000000453635365ffffffffab2514dd587194cfe32c21c1a9c465f993787d5cb215dd045c9c953e6d1617ba0200000006ac0052536a63ffffffff0320b41d0100000000060052536a5251f8baf1000000000009635363ac535352ac52fa3bee0500000000066553636363000000000001d0d3e104000000000000000000000000982eae68379f8a103d59b35a0150fedb2203d58239361ea0a61983c9918991b407c32f2d5795a6f3bdc363849d7f9f9807ea170692bf282900a4283497ffa3200cc88b802b0da4e74cbea45eafdf50edf0b51c0b329e8a0e0ed9d543966c27ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006010c744d252df627f6b6edc8b3491b3b8f4ef01aaf53948bb9ffd4650f515a51c6c8bfb0ecaf0a8f0c4bfd5e4e87ce1672083c2e45e908185df8fa49b50d03da1dbf4ab2395007dbb3cc9d23eb77a5d4c7efcb174d350cbdbb102240c1e4991b544458142bfc5df8b3e38451735dd3e898d6de1934bfdeaad533be1dc4e21bc0313a45d534eaf2cada1798cd8cda6aa9c2052d51096ef6d51dfe15b790428f59602294396d4c8624e5a332bf9c129681af3424e3b9b33136bc63bb883f47160be6f0b02dfe19645d7e4217ba1c369681d49e9813e59b325a4e1bb8e87da3e48976fd8992b6194ca78f696c89c2292af8c6dfe0f3cecb0fa428d3e621876027beacff1031c3d41b52fae170f824035ec893cabd1ddd6419c4c49c97ad2443c881d5f76220307cfcb58f5cd70fb565334885ed473de2738bf1d455784677e909da17a54cfd00320302992f94387c3075ff3f9b31fa2d237e88a1900dbe52665776ea99e66513a031cc3b006a0f7c694b8ea9cac16c93c32838d383bc601946b2e236939359669aa03064620a06833429262db733cac3c4ae2e57371416b97d321787b723b59ed417dcfe4b3c2b58dc643ff2f6e3b4f99df0e6f8a69561eea93f806cf9adb81628e75258673f9264772d0426ad779f7d23b5a96f10113731e3fbdc4f482058f647f38f476d241eb4347061a9e5d7dd2f77e738de8c35db7c1ae9011aa622fad39a770b7170cb20bb6a8c4eb3535b0934265690d40800b0e02c686cab30e986538917fe1283575aafc625ef35eea0f0ec9d071554b9147ded1d737527eef93547f8495784e9a81c9522d2d7dc73d18119a77199126d559d9913f0e45d5fd4c5d98562a7916499f5e0f104e7689154f1d6adbb4aa20ce1a52e3e0c8fd9f8870ccc64a97582c429cce80337880fbfba399f2e35cb83a76b58d4ef244d11764ef6899bc153e2f5df0dda551ce4746fa5ecfda6297c3ab44399445f797779d5a20de9d4fdfb3d99a945824cdf2df058a0533f4e0162fbc2202a76a58cb31b288f488f3516d0b3294b27cea912370cd122f67c211ba26657fdf171c725ea33edd1caf7a9631ae0af7c5475eca60425187b09e37023c930db601c3183f3de468d762c3d4fc97bc950411c5b5d4e01df807da4e17b9fba0fac4969d791792e71dad83b710a86c9dde58dd8e45b7e04d5e55307ee7954da346e95cd45b3a870c82fbd9175fdf0ce3faf2babb69e08d202ef39c38d74f232dc1fc5497797f8899cd53ca52667349b5d2e7393ec40ba3a81d9a4b84cbaa21f36ed6cec30f5bcf07063caae9f939e1449266adf7457497dbaabfe4c816582726e27147af80be1adf028994189cf9746bf9b4879bf36d69978c6b90f8af8a49e129a961b1d4ec373bbc371e22a507f03f816bc582f341fde1746f6b76b7b9d0a870b6c095e8a21028e146055cc52adf56e22c8279371794bdfa5292154900d61b2f98842b7cdcb4dbf4d4efa56047368b54b4c818b7c72f8205284b2e700b8cd98b21c3a34625fda57f324c5435f8dd6fd375597c002c3239c2a8ce44a876cba59c000e4bca75f4358a3c3aa7961ac7cf21a27388c0cfdb998b7051a3b8843c97be48d8fbbf0b08dde9f5803d2a350c565926090fd1f82ed80c12f25513b996657ef65e73a6c544d3a45cc8fe0c575dbfdf7cb5143a1a74133a42c64229a72dcdb5924c7b5e1da9051a5388a129aab50cdc71a1f81dbeb8920ffb615a839943ce1992ac87b68ad7a522aedbe9cc24efd39894edc884596c075d57ec995bd216d1151cc6fe9c9d220e9cb3ee200c1713ed90829d85f0bc33cead1a026da6cc90a58eb002b412b730baff5924ff93a8dfcee11db8cb544ddcebdb36c8c29ac7c9e111cf9a65f1a6f347584cc2a8d0384bc155760d9b2230552668320a20875c456ce06cbfaa6a6040758e7286ed27429c3bf3ea2d6ce771d0b9aa1bd21c226d8ea7de96cd3d464bc8752d9b7de5864e139d2e9d8a7e323a9c49ef8c15fe8b1982cf82d87e94ed4aa49819462af54c606d429cbf3d3e34d2495d9475724b235edd3f58d0966394408677345e620d45ce5f332c4dc793bbe980b965bfe8fe48ddafb6945a4a36bccdd0f2ecd44933bb11a19e84835639a0235078bace6c4657b90ca8b2fd31643eabc27249ed88e92d839577edffdeab38f345f2a317f38d89e3247519f7bb9bdf75834f27e4c8e98b0491adbab27f4853c66e9b056cd2418e94c6ec8e84ea1dfe280a26e69d7429e41edb11319f5744d0c773872e537995d1ff99b1743c51552ffb977fee9fa71c8ce012a4605fd60afc82d850b27c32e1d52ab085549606c34e767caeb2c5bf01a5e2660d18d2e0ac44359dcd508d76744778bd4fbeb062b0e86a7ae08b1ebc0036dfbc49d822206c81b1349a6728c3a1dc04e97d06", "00526353", 2, 1612076931, 0, "ae3dbbe55a4f7f98004224cea88fbe752f3b159c1a827ee5c587fea430de68e1"], + ["030000807082c403036e68122408f75f2d97cb9d7c81ca3b8c1cce95cbce4639ab5e99ea9b94715d52020000000753536a636353002e249675927295eb8483a3c48c1eeb92ede7d5383acf44fdd145f29474eb3a0680a9a6ef020000000351656a5b3abbdfb2900ea1463158e8e02a96e5cbd3a5dddc4eb276c97228cf49f042e67f4b10ed0200000005656363536affffffff0461f08105000000000453636a53189e5d02000000000965520053526500ac00c5cfc2050000000003535251221fd202000000000153000000007bfa25880200000000000000007a1f7600000000009bce305cc5263292e5f0d0179dccc4704d8a6fa992632d4698e668e697c463dcfd3aceeb33701a11d411b2a49a35c338ecddba6af59b393931fe6c60757aa0a13ffe8d258b0bb197752b5556cc0b611593370eb66ae7c7009f4e98014cae7a1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b22e7294d7330e075b65f94b4e479c7f03fb3591171722bf41fc28f9a1ef7adad2dee3e0f260afcbef9215ff73d82145deb2d8008d98d3139b4f6b00df455213f294d64d2f4e2be0599d63475c918688e11e14f1547f75783fde6406d8aef270eb43f9e29a3c306afb8c44fc376d56180e66bfd292a8d58434ec9a862e357fc70316e528faffd5620b6d518339252481bdbebdccbb81fa67f12acceee78b97322f0319abc84a4b29a049ab37d3491b12796833499b1d8f6619da5d94c08fecc9ca600b01e4f5acd5ab9a5647e80cae89651d09ee26f64bca9f01f7eb6295c1cf56b4a7a080b6c0d61eb8282aa90948cba574d1c0f05a192348f495f6097c8a07a03dd702200904fd4fc995963ed7d062d445bd3245f5c40cf67e374d23d5010e0dba81d3030dc2787693427c99f2831ed708c537ffe9a7c05a17cd2c45d49ebf33e9236702030a5376e71d10e427ed23b9a9f295c52c5b44e7336fc712adffdab5e298360e4f0306b283642efd60e0fb563c8c5d260537921632866c1bc07d8d65400e7bcb2305022f3daf8219b2d548cdecbed851a3b2dc92341acce4064f077be82c91b5b9c2ffa97db89d1cdf27e376684c485adb7adc3d637780a7cb627d82955cb4cfaee0e8c30964f8899711d4abb3be144297a329e628e6425ec109e0ad848d9d74559987f6224a626ef4e0d72baeb94220a63ec00a09f67ba19c11ed519f438ec1d20956d17f294a9c52e16c6b12a4f0395416cff9b12ddac031f9e3915b874b66104d3912f123427111b1865192fa591218a78bd5041a8c21ed2c0baa8a1aa0aefdded14aab9ece6d5dd7831e9e3fa52c15d1c629f44dd7885b84caebfdf782dbd5633b305e302a0e855bf56ce43dff1b83b9276d2c9b61b97ebf7806cf7b285f81114efb77988f65dcd04ce6cba440674e6b5d9852c4d11dcfb243d5859079a6e41ca514ce2f420bd3a2a3f312f6f9a3cea3f96821dc62e49b537ab3cccb4336a233e58732d4f5e9d952a8316efa9383d81416c512ee29a4af03eaea7c152fc81c861ba15429d317c11b4d172bace9df806c93bce2fc583a199883bdb3ddb0a357e14859c9c919b28e4562b9409f405a213f422da65b0a71d2db78509caded62f4fbaf9f3bd900630481dfe3d62110e5802fd327c7ea6a99d1e6fdee79c4fc6c47dc69ae64936b180b5491579c159743731d0af857236f7d480b3844be70597fec904ecf18559bc6398e30a885884110f3baa9de37735db266dda1ef6239784195bc363d55f07da4b6acdd581e0c7c879719104c81aff644198e987ea285d9b43c3d84c07161fb312d6bcd1817385f823191899f231d53050a1a2b8a40668bbc5b503dd66d181730f31f882d1658bba81eca41a570dd5350b276f3ff361eb07219bb7686469e9399c5ad913bbb08bf4387f5f58e745c84f31228e097dc66becdebe70056d4c8767d50e0ba4f76e13cbb28a83101a8ace29ad32b56bcdf2d528ca86ac2b655e97bddbbb58e293d6c0206dad7f595b7554148b29f5eb83c8e169dec3fb7fb51230604654a92ea0bd6de982a574dcffa5999e26f02e8c8a3cdf3e830cdd5c3152c810c3d578dc0163d200cb74e74e7b965e29e15fbc1eb9fec8b63feb8e74d7d246d64bf274d7e17e6565676b812b2cec5adbbc4c23b14b9e824e4a4afcaa3d5247be70297b221f0e106895b632089d763ab55bc5fb464b8306fda41f9041f54ca20a1e03b5ab942c2ff0b86d8763c796a6a75d2626244169799300b8e32388d046266663d510cbf87f6c1079e894df78d0d44d9727d9e5f66b2b55026bdf42cc0e20ac9b7abee59eee31035534a94453de04c9d0fbb5918424684bee6f05dcf54e098eb2587b47e900df70860a681ed7dff7ffd268305587b2806741ffd653bb4f1fad5391cb3493cd62125a4a27e17d90754a0d474ca2418c9dccfbcb91a67a9021931ca8867395667b8bd925daa44dea1eeae95c7e562bc697cd8c9711c560f3c2357b2c51182efc8536e61de26252f02431dca8f0fbd7782283d4b577481df04a8c0682b52efed20a0d197bd7c83b272915c0a80a143e335130ec991a358d8d31573922be3e16b070bf1b484290f4766b3ea6c810330a85c6eb9d1c8fa723d205aebdc3a3897db302c5e0cd64986b03e258c27b1cb5ba326d2a9c5956e0b48dd4efd106806b7a1f2d466ed0867fd353e00aacdb9cba4001ed96d88c0a28f3d51fc935a386877dfede513338f6ed408e90c7a05f5f392fbcfab3999390c0f5161754ca281bb4972d201cf38d455bf00000000000000008352ad040000000014aec4d73913d89a08f7f9a3d932f4bc5007626d7215713812736b46250be6a53fe40f6d2f87b309e141f239a7ee7916557cc4326845876a2d814270ed6b57bb602bc846165bf501a1d8dda28ce7187aa624ed46f0cae5a0d6dd3b4010364eb100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000754e565cc712467392785ff3b353ce6ab7aa1611c17be6c83ca25cff33e42fcf76306812bce8790bf2fe45d24c35586d20a6ebf0d2b81504448bd6559222957f9d9a74496e8a5423018c9e031827f886414a8ccd4f2135c5742c3f7034f7bced839c1235ee83ed43ff8309ce4158e1be8a15d54aeb3d3e891ded80e0668c32780228a72bf9d294edd49fddd68bfa60bcdc1a4476a641ea2aa5bf08fed19b5cd0f20227b13e5b52471820d87a27436d8701870a5ea6c936c7970bfd2162a7a0b612e50b05665ccd3b8a52909ceb9e8bdc622da39f40badbe930e9e32c89811ca6a201075316d8e067d246d33e260d5f66c6fa541237a5d558abdb5743fb7c0065202ede0314daed4420c5659c5c3c746e585c3469ecb35c7f4d7fc9d05053cb74be8ba34803164e25bbcb24ab23c4e73b0ccd24a1ff0113ddb8aac84b62e06e3a213454d4360209b40aa7d91e4bbbcbaae3f4d5c1f027cb998bd44073de85b0ae08a91539c0ab030d3322ae2d00403f63a41e50669ec718060b21bc3a4de02b38d75ba6aa11be8402298aa75028f49c7cdf932d2708046eae357542c691990fa47594b523eae90a39999569bd96ef9ae31241e19d15ab9421edb3bdc962e415840d4e6324f06cdb30610ad44ec1e89effa959233fbf2d08674c2a8c376db7fc08d1a9ebe130bd9b329efdaa1c79469c7076c2e8019c52e0478fdaa4e11bfa44a83ea1b337abc58f9064f386b6cc38d89105a8abccfd88b24e96b54a76969673b05fb0b2706af28b9e7198e2c8ede0b1f1603a03bcceecb810c76688d2881211d0961b5849f6ce562dbe33c0747197ccdf1f8a892129f783d9a0bdd6462a1f837d02c5b7ad5c795937fc67fbad081a41d9c8f1f35017c6c0508c9d1922bb1659495e5229447312672f3be088e4f4fc7cf6420b89f5bf2a8a6aa7451a52740ce648d3affe143b78c8b6775b222b7a5b494f10695f6571178cc3ecc97d6174455f3085c64dd647d4c88ab30a9883706a3740c531768db32f838f9c4fe238e1b1d477513410fc61529d64596ccb6c5a030fd692d8fccea5662ba365a51594b50c5a33ca13a2d163bae74410ccf15b2c17fa9a2ee2e4eafbf9a9d68a0b9207cf12f8a5fcb9b08099438dc877aca2c4542750c2c3de4c90c7f272d73e98d753e7c14d1b8e6a9cd996937444767ba6dfd01c5d39d678f608620ef919e4aac5ea699169c4c89607df56c8ec629bfdac803355be5ec5e2940a9708a49183ff82b0b00b5ce738dbb5ca739437674ec30753f9322e73e1315a5529f2384631a56690d6bdf69f7a6b2828b44881deda96bf78a655bf5c3150d0cf4e72cf5ddb6342c8526f9b240b5b5d4617e3e05f623707d347450f7a9fc979e0d0cac6ae7082c1215a8272db5b5c52f26eda91001d838c2327db8e70b90f97a72e9cf06b52dad1b9d8799875cc18d0602be5896fc361a670a83d97b92f257140d12a1ce8d85b4fd543daec2eae8962bc8f23508246de18a5b0dc6576819e0829eb27845fcf85947103614068e70538ede9bff0f3c702915f4a9fb996deb6956a08aaabc0039163c10d7a92fc4d46bb4181869657503f96214ebc9d3a1f10405a55ce643bb7ff1ff3c493909dd52cccffde3540201bc508b05c51766cb51e9cb56a656466998bae3ccd903cf92387d8fcb355b717e5d505fb42efac5d19775583e8b3c15dd591a1284e1018470d72fbfd65a6c1d3686291b6771186a2b4c523715f44f721f34f06a40b04119aac27b5acc3bc02ad3397efe4c165fe6e2c51f078ddc55ed0cecabd736d9fa858aa565c48659a89a64fa3165160aeb3dad84a6c9a25df17c79f7b5beb0981698d03c0cd4504797d4f8e5962c2ac22c2d9ecca3b7ef12453902a82b559a1bdd1a73756bb7c34a3c50d3ed2ae3cebb7e95f13d901b091a169a7e56c911b4cecc4ae3b78910a7ab78c87cf64b40631577402d67974633ee9029073d81d56185425efca7cf5b65d6fe2d0c96f2dcc48d3bff2891d4bb915953a34f84fababe573aafe4321a2806b8f2b77a3504389f7fd1d987694bdf052e0ac566fb4aa5a60bfe2f6a31795c1f366209269e4654d4e03def3ee3d760cc45a9c3b96cadf811c568156802de0c9e0097094bd04bf02e933bed22c7d46cf180f6671bc2913f8efb70c16363bcdd938133ff38728e5a204c9fc923d0281c6ba45808bd4789ec86f0a56c37d56e79c9fe057957f9bfdc2b1f2d321e9533ee0d404b38f49ca113fbf584cf290b01462a6885de48817eb0939be30ba625776b85a0316aac3047fa7ff62c50ed55869d9a61eda005e647dfac8269557069e30f27cd73ef4798a885ebaa301fd20047e8577e19299bd6cfa0466d6728a4b06382d485307f9280219d1a44a2f2e2e7ba45a5044d75cf691d85e7d9eaf8d74ad0c236fc380ac430a", "006553005365", 2, 432100598, 1537743641, "189bbfeb57f9443fb895e3657c23707180e9b989967e7aa62218c1f34bbd5f90"], + ["030000807082c40303482e88da7538fd8e3fe6141ea04e3637687422c72d66c0d4d5f0f5a918cf606f02000000025152ffffffff296ac87f86cc22eeb95b867888c4ce34f715d0627fe867e38ee79a3055ac2bfe03000000086a53510065535152d621effc28c4cbc2e9446dab4ad11d73333d3cde877dc39690790047d2e9da1f78d416d00000000006515351005353806c6c0203ba8da2030000000000a09dd703000000000451650051e9f3550200000000045263636a6ccb2d0f000000000300000000000000000f704800000000004000d1e8e47dcfa84eac3a2eab3f9030a5dac723ce1232f2ae62a31f91ac65f7dd83563a0cd975fb355f874c7c4da0f719f3825af9f4c79c7c0c10669b291e5985bea6664bd34658ad7cbfb9c0b433912320092f1ea820dbbad2495a67b1d8d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d59ed3b1508c9fbb4592827b3a87e8a333f27cce47e7e462aafbaee57136d089cb9b44c605c12509f4b1c7c4651150a8e9907ffc401e2c1562fcc823e32e4b0aff733561e18ad27bca241c684075807dcb9888fe1d1fac7bb7024c012afc89063e528aab0bda368f5b5d9d77c0ffd1216a69a3fa2a73b4470ee0fd156ecb8a3030ee91be5267e18f97fb9522d844900d3d8959e5915838972fcc0261caf4cab0e030d26a61cb9cd30acd5639723ed61d9f73f13c5f3c608d08ea4ba603fe7d4ff090a087cb4568e346ba9d7b58b8d603ae9e51c011ce6617b0afb569fad305825bc0c2f9f845bc11864a55eb5cb1ef60fb746c381cfce6bc5772a51fc1698d54085d80225eb5da24f617c31825a38c0e48242dad04f87987154cbf00291326bf783735d0312a11bc72dd10a5f35ffdeccb568129efef3d085e78c6283c02be2bce60da6a90308868483a8d14cb9e2fe629a2dc14febd45c738c981afc26f76b97acc306e1550309bb5b9b5aabd31d03f8316bc71a1e01a1761a1728c63a66f7b0b0447949462d0227b29f4b993cf46b841373ccbcec9d6882fa6f29c04fc1c746ba407ab8d89545148637ffde46d7fe3fd66c9f7e0bc45c644058c3f3cbe0cf315ef0f7964a56b6801135459fd3bf94c9104dd925134c589e76b878b5e9c507b1c0940839b3d991516ac9c2b63ef3a7dc5d99eda385edbcf46eaab11ec47dffbdfb9251b87b1147ef38ec1e4cdc71c2cb442e1625563ee21e47401308eb5e8c3efbe7deae9b0ab9eddb0a49054b2cd32cfc1c70801eed98ff07cb62c1381f7967cd03eaef19dd06575d2612ee9928c5de0a9315b98935320942d0b0441e76d7f98867e28682ccf04c0f4c782149b217c8fc4c7d7ccc58f1c755607f9d6d5c70388e170b5ea84f2a421593bee0fbe63e9225704cbbb3de80276c4838e663cbd734a4ce46df66a6c2280cae43af272968d116160fc8d87dc2a1782cac368f5d4284178d32aeb72e1654b7ce9251c9edfccc49e82ca3681096aa1353b74e6bc98c604a8b2e4d0ceeb26a0fdf9e9ba484a4cc6f9936a928e63aeeb38dce5773b86ff4228e6d3a5e3cac1bbf7f30608e40fab185cf6aad5cc0c856af4800623361bd09a228d63600aad3a47894891c4bd0a378a6584267eee4b1160733ae6a5faef3697f939cf063bb3edfe7cee34a9035934848b6536e58f63ef32cd153742a98aaf430c7503d73fc99289248e662a1980f14b7004426bc6d61863f7234665928d9abae73a7a7e542ed174a9601998f6966728bdc05790656ef16714625986a03562a7be753b9d58bff2c91939f5a189cbc9d232609097814b8b274803af0df04ab0601fcf14993e53ea908a6f7f964f931f00814e06dfaf59547ba73ee8aa71c5039aafd1a9b89709ad49183c9ad17b7300d3707064fe2acf917dbf6382ee41f5b98ca7e04277f7a2dde88fdc3fa407a680522b456250e70dd954c74a91c3b9a86e2fe2a64914f221fc12455dddc349e899d9640e90c75bb64a288a13f7f3153ce34111632a267fdceeeb67fdcfc7c65617cc6239b50e8248507d721ceb2df200909118e471d04afa4a2bd71e1b5d58ebd577d4cba3da691bdedf77b6e4de5ea71be31669ca6046497626415bbd9178ad507b7ad9078a876dd421b20e408adc22ae090ad3358e48845ab24169bf1c21da096769eeb4932936acf8a95ba16c15555e83989bdf17082a896f1999bacf271f1d42f9c9ca488882c614e86f3d18a26700367d36efb583e8fba4a4b074df51167eb9feccc13554005a4017b887bfa0df8d568de0fe819b66fbb35b0d1d4eb61bc9b9a28dd675f7120e08c931d7f45fa33215c4259fcafc81592f8f2dff018ecdbac14dcfcb1d07b6483dfe93d567c4e2521495a2182c157a8d42bf35dbe171f51d1dbee269bf27edead4698d955b846b81602dc25e5dc0fd1a8803d52d196e1129c6db55426af2b1b8073704254775cd568e43f486998a41419e8444c3791bd0c51a07af4c295325b035649f5bd9d7ee42ea28ef4711ed556e523154f78ab9a7c5782f41800b9ef7a4b495ac15c2975e632906f80031b17eba7c1c46fb60c9386650486c976447f7721fdb5e4e918e4f98effa9d34e3655c6e7e32681e7dd7083435be749a86b2f7d380d671b3e9981d4ee3da56f30fdcee4955362b6bdfde1497a18611ba3b5ed8036a4677a4fda65ca500fcd95a9ee44ceed32c77c64636ec43e17c2668ebdd99127ce744ea5752fabfa42d809ef4dd4b06828dd9e9fc62046475a7cd462433a7af1d20000000000000000e6ffe2020000000020adb623ba399977401969095f018d59d72c8d8510d725dccb821304f1465b0bbcf7dae10b638dc2048934974ff43db45f6901ccb5db6391ee4d6d107c9881fb228741d4fafd3bd41c062769dacd0d68138955fb100dfe075e13e3fb1295dc410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063bb0effda89f23d9657f2396f877c877845575f8c6317d435d7af78d708e384a345eaf1f18bd7f7eb9a799aa98c11cb6dc47de8c01a16a6a87e23ff40c1340f0b9a57ccfd87f4c051cfa35a3738d6f70b9f3d5c121b3b61ed0b0360e275d7054e98291920a2785f9966097405a10cba6c600b6c23783b47fc68e9596263b516022d579c0b879ebf4c9f8597f830b6f35841a854af08c2795246e521ba9d5969a70302ff28417dabfc2ffd01adf6cec907903febbadddc251a18e48a2d174f5e42ee0b035a6bd634c22e1a3a0c8a18c959662c2128959c9ebb7a1fb2209420bdb8a1cec9a5fd6c0090399ad7bd8a7661147069a2aba4c09bfbf4f9157ad6121d53494f02037ebe0dcdf5ca6e1c689d2ec9799908fd88a5f9d009f6a684e8ed207bc58da1021e8eac0cd65a7e596eff03d5f018e6a4f6fca51226dc441059ccd2a59f306674030df20c446610d705b12a6e21639cfdc40da65efa4826f29ece4438e6c93af4ca02258df474eb90739a5772f82929e4475be50ab068bf3e8a66e139a5dc8b753edf022bdf9aad95443079604d4041f76714da175d2d74bb9ab15bbf9db3eeef0766afff338024a94bd2a18fe389152c0dc5a25ff156513cbde453cfe1c621bb32ff35a9cd40e4799c724f9c994d8c34da1001f2e14607d4b475d594dabd12f15d86f62c1e733dfd4b354eb4c442431a93dc785b685a9b3b097037505a5a6024afb9da066aac314585dbe29c24f09cd0ebdb81e0f0a6c13f309a52d5850ce33b21f9a31c38070bc2d6166a6e6d5f17cc521fc9f999abd62791b144b7a7f12072d1c24c84ffacde655f6e438c5febcbe998013fdaa8806f169eb75af4300905fde0970780a4ad3cb32c3a28e3615b911df82dfefa728233617fac284ed29846a8ae83e070b1de01b07fe439766ead6f3bee71730cf30245da0a5002a1f2c329225b70b3e5209c8236cf04b54f6974853de577d8382a1c2e4472214c6c128050c3433513a63cbe5fa64b14aaf6926fb457d8f0e423a1e0853bcae63697f9691b43a1afd438c4686e5fc0dc0f83475b0003c048f24135becf844c2bc5f5849551025888881ba26e11c031ff221dec6333351997f96584ea88e23ff36d2b8458a08c9e8033af5a5c7a24f2e7572fad216153eff098e6405d78c3e8ca9f0006387c91f278dd8789e71ec585e9f9160201fa1442390c08e7bae68c2f1c413ec1454a564f3dee7a6865961c1b28aeca61d85908f952e1febacde2ee8c9e0b367540a736660c750388f35e150b8ccd0e3089bdd67f5a5e7443b8ceb0f7f780002bf81931f6fa417ca8c5adb89f5624b375321096ab3f3ecd1a22c67e1580022feaa8e253e5af66f4c57a5a7d850f5b6faf860f6a9d34573dd448ca527c7617c40461ecf27047d6bca0af21f6035e35ab28363aae3dba97de9bfaa0793e5e7252472ddb192964959a4b459e14fdb4bbb01a3773fafcb18bcfdbffda5377026e37fb0ee419b1ab38128581549a65973e621c648c5d921c171979b92fd15fbb3a6f173651a9fd2e2bd1e222a7d55e8cbc9337b601e9f85432b608bc21774f0420bd349a57f2ff4b393c6408b3dd2c57f5cd7f6d5b1bf84334c96e32301b642f95b28c4e72fc2d79ac137a1dfe2eeac449d7f606cc6a6d6b12e06afc91e47ea23d5915a68827dedc3677770a9af20eb99c2321c1fb40870aca89fb9b08856e66692e21f662c26bdbbaa84879a07f8f91299078e11a5bebeb49bc42c85ddbc39b9dfe3316f66dbc78fac37105bdc1e7532e23083e2a12c366158cf707048a0ec3154e1831ea8b399855d29012e622710805246aa0280713660e980b1dcbf83c1a2465382c4c515c8022e059ed2fe22f7ece9a1d67ff850c683cf616a4ab7cee0d80d5c1625a9f282314be310cf8b43661386a773d65ab0f281b025ac011e2f1155da665029d35a9b3cfc127d60a6a00a111e56e50ac75a9316b86d20db38bbfc907fbe3748c840636601ae25163a5cd29f42d92d7629618b297d9e3949145b260a77249579adc9fdc56f327d3ae1cb139172ad269592b7243b485009c240763b59d736ad7885ad78a618722bd1e1eb8ec7686c1983a9ce439bee6e36c73b913d5cf76815d26b99c33a431e64764ad4ce1d0ef74bbcda3bc064bbe096eda164b1b320efac5943db89a684fadfa6891f2bd7be368ce27de3b4aca6f14a59812a4291c70d11df582ffadaafc77379708927e322a8e0f2a3f333e2aec601bf860d2796d448b3e8adcf36657b63f21f07b44f826fbc411876dfdd207df7a00000000000000004211580000000000ce4572a3463f2066307acf87cc7c313e0864aff76cde4329f52773e247ee8aa0ad6753ccd2a697cba26cd02be49a54d5bd7e563c31440dd9154665e28100ab240c99a32d1daad75e86f5f061fe86c07f11860395e4eeaa1a1a0262374ee8ed850000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086b140714d5913e8d4b2940659d5bf7c85ec5f3a87494eb2f98f17158083aa4957778781c1dc155937a7d1f76e4c6981cb35fe98a1f0449709451f300d55cac70dd6bf0960d1e85c63ac7e8ad0bda259881f8e4676bfcd76dd69b680fffdf847d41e0cf13ccbd22b3298b55d7cc95a36edf150b265c5ec4cab3e071ce45067900308f835bd433456cdb54096287584f460d5e11f59cca5de84b2a05cf6d539e3af02279b3a78bea45915681b841bf252dc450cc021fb4209889f6852347729756e4b0b04bb50d5ccf9eff57a46feb90bbf50ac3c01eb3d0b67c5167ef0cabecd8069e62c1d411b733217f9b39ff3b30032abc1317b8f3134ba2e9dd1c8fa085d31149903128d06676cf8d81a16c61b19c60d90ffdadd1d6058ba962b5f571022ae745b6602167a92716b8b069c4bf0cce880bb235f9671974e8897c8e45d40c7c843489c420226489156d3b9fbee3f6ca0cfaca9be910b55d80d85cbb47df2a3412254869428032ca60ad80d220689b09e95c5892e95111df456fe07a158dab8816dded70402d70205195b1b7b3aee7f421496f4c7629a77cd4bd361df4d88c493494aa94172802827730436a85f4e9b9328e276ab59fe6b4eb2d97ce9b3cf7b955c454d93710198c46781abef1c53a001d6b54b9d6aa3cfb98f04c979976cc8976635dd06d1f9fea8c75aec10206222c030b00f89d06f67c25e5ad608e3c639c13816cb811299d41ee5372e20a2bbc64604e7edbde73047e58f3f56ebd05d9207b84c9b331c0eea4d591c319009eb6d9721d6c791951838d8306e4eef08e0c98fd54dec948a2b92c76ba81f75cbb4bf42dc34a3f584c6de8a238068cc19c56fc00f58c05213b6db16e4c5ed4bb7247967d58d4c3b1217319d1e21e8befbafb5f573beeefc8ba5f5db51d5d6258f6a2f8504d89900705cd5d76d5e74753d997ab238f7fa946d61f5528c40ff7ce8ec63a7c11958e27487ae5759338336128e49b0a0064bfc9baff7af522fd3686b7ec5f56a4797097790c79956912f200529374595b613a61b4db125b4be384c6dce7595ef60169d3ecb3d006d023959fa962b8d5d1dd246e46b91a217fdfe2c3868afcffec36778a88b44b87855a03180f8cf895aca58a2bd0ce54038ef57f2630f35ccd6a7f58669478bac8f5683dce808744b250e9344efdc33cdf1167fb86f5ec90f1aac87043e5460684b6ff368226d7520cc91c7a5ded30fc940a07d954f25ddf672761846076c1cbff800daf9f9db9a23885f8cf4bbf3de22a9a728f66d8f4bf2322095718243f6e3dc08c4f1f12c0a640168489c9b26e97052eb7bf4513881239975ea4a256fd5fc412de3d7e27ae9bfc05573ae9e15fb5285e1cd73454b97b328553a7faf9d0d3dadcecd8b9ccaa705a10180a9258ab14e3960d0008d89cff085dedbe4577490132e1e6d086dfff9424a051dd99552f00424801886b89220275acd959b70876dc06f3dbfcdcb30774ed35b8142676784878bc8981788edf29cf4451a72a35306401949e1fb4f48eefe9d7c741ed774747dc5775c0730f882d58aa1a733d27051278a00c0979c917d217cdc39e12321a217018d5ef45350c6aacb657a5d3b4ecd290b1e81d52aeb522a0efe8ccef5cf72eae00ed9136e4f77a0172a75a0d5dc523edcc3370533dcef5dd81559c68d7d14b694c6592b7e11e446a923db54bf23ccef02a2f83c991b4d27f8d9fe3f93ef7ae98a3943733f7038cf5b9b72b972ff9cd6e28e06b60630feea681597f9fffa8bcd995a83aa5ead5dd78d8da5dba35c6c0852dba7e9ffb2e7db6c1a92ffcb1b1d507830f15f432ce6a8e6647599385a5860f27d6f2d86aa91df4ef4beadd61345dbb86d590a3a551f6f8b1c12928adc805c95b71d5aea88cdee6845a95bcec5dc7d38463be2b5934e3a8e4036b3765bb896d29d2679cf3a90dee3aa3232b3787c09c0e7bbf393160f9d8dab46ea1c2bea7348c7d77aa6e914e0ffc9f06548b859e3b19814e9a17d18047df3e75357b4ca0f2675222e023d43ec0eed39205b293b4bbabd597109bcb92ebdd22bf10fb5af26bce03ee0bbb6dd33ccc4076c07c50e0d7fd0af9e77ce9411456b437a16cdc68d2eb5ade472e134757a2cfedcd2b3a5cc2c8a8677ffa74de8a3c2ec7253b503d68cfb8eda9059af305cc86975fd1f43d19d0496b34ea88f65dbb812c7e28ceb5794e7d75afea070a86031069f273538d9a27095d0a5a66ce0df50e55709a9385611ea1550cf737826883323cb2aa3930ecd9a4f4a9e85bfd0dad8425696dcf205da2780c6e3bb20e444c1426075fad940fb9de256824374bc709d62a71fdcc66a141bc3ae709a18001bfd13d6d1602676a0f036329cc45ce1a9c14fc1bf01760364f107c843fcb3cd5b924002909329b11b27036c69a6c69520c1e4b144e85b790a", "", 2, -321161762, 1537743641, "81003245fc01e90cc80a125cd46ad2515807074acc5c99ba90a502a51650056c"], + ["da81d61a011e817c9ce94555d5b5dbe7114bc618ed9ad4b69c359a185ec7bac2d617b21ac600000000036a636affffffff047d893f040000000001631020ca0100000000026a65679b140300000000065165636a52ac7089d2040000000004006300637582f2160390208903000000000000000000000000dfd977b42034f9534dc9c2207bd2f804719e11933625ad83131999240b14c28369a1f7bc453fb57c4a85a5874d6ce6a077e2427ca14c1860045b2b3f28078c9516fbea9b544351200c6bfdde38a9a35fbb392971bf004c5304c1a130c8b3487e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cd357b6ccbf83f7437552db002c61caa2044f403faa3e5658b4fdb546df16fb165bf2dfdc1bf23c859187eec8ce6d02b1604fb3a3898cc07f8e8bbe3f898f2e91307eda86430837240ea9664812f151ee6ecdeac01a4e092907791e01793d8ab582a55d07aa836c900f1ed79228060b7129238fdb0caa8c225d9b07311ea993032fd7470733ce368bde5c89d947d6285ff75fdd355466855cc0df724618c03e47020a784264207a83244ab673ed68bbfd98d9bff6bcb9f0e06bbb0cdfda716d46f90b0784b3debd91ea9c414524c10dbb9f8745316564c8da41cd1b05ebc3374825aa8fd99cadfaa9c0e6006722f084448ddfb05c463c513f39805fb0b03ca0433f1e02041a8bb40b69e354fdc93671ad3e75bceec1008d3c2cfff0339e93dea8986bcf0223dc20004b5536a766c4a09a3ef49feca219349fef9e51540ef322847d62c217022fee4b21e15bfcccc48989e41ca96add0e12b8fce0072133b3554a3bf799aedf022b11dc6f702f9fc17557abbf6b8c21a0b21965296bf0db0a6e96124899f2bff1022256e920d5f8e28c0a3ce13d71c31827a963fe1c90ed3c8d523a549ef6d5cc30a304410c1f746b6f199638243f5cf9bb6e915a93539fc6f81d75044aec299c8adbd8d55102947265c4bc6bfa902a5194a556c0e24dd4844dbc6fc97e3166406793b279f2669ba5eb1add7b256af6fbb753a5d8b82b3b1b7864b8380ffd5f289f3339d1c34b99bf648f2b0e86497c5410ef3706133ace729c3f81e1a040c4f8c907bb2faaa4023de73c4eda78d2f3e3b67a0e8213d7b41256639724081d96556f96d8086a4e88c8dd863e4801320f9ad37106713f1c1d89c7fac0cc9f48031dac85f49677af6c77531417f4a469ebd33cf88df9ee72c5c16e54693b712a4bb94b107ab0475b3bbb130d40acffb082566f4308d4985f5db3d6aff04d0c4640e5e5ccaf1e607ad3ebe15cd388da122d59879f8edbba5ef116fa71e182a23b631ca8f2ea86c82bc9692093cd13e35b7ff676bb1a0e635fe33a387b4f376185816a38eee53c92941e2565cbcb90133e241dd1fd58ead526937791f2a0a6653f9075e0322a61b461cb82d4baeb3782b4afdefe5b7a172ce33c4a45f532f12fd1d35b42f6a48ebc9e180e72e9b3a16150d283fb6c8bea446ead8cf66a368fe13073408a63404bb563b8ae82f17a5e07d1f5db366d863608684c57d210a6e4206dec9705d0b2c6f47c00c990d6ea6fdaa77ea74104284451e5f15c42eed3a2cee52e72cdb2b93a0d35654598f0467c7d5f02db3c6580d7fc4591d52cb0a6c1ca5724b7d039dce9f0141882ade09debe2064b802e7fa2756fe741ec4354c20f0d4940d6931d083fe0c72b568fd5db627847b85f7fb903591a92422206cd47d965069c6b0a462c3c59e1ea8883906420d54062441630837ee73efb8d3c69e8a802e83fd5a7952091ea1c0c26bbf61f9797b2f892ce38ee12d39a7267a9a038db1d051943c4dc2df076b50d97e26b2b6cf1675f2602b9d49b13b69bb39100f7ac1a1f2bc7187a7f9215a4e99a92d00a74c9e916ec54352f26f224103ded8a2329630fa7096a215b2a9525e805069478def271d6436ecefcfa929e195d51fbe909a44e5b5d89fba5748c600dbe4a884488aa4c39ecbb2dc94bb25b54855a587123ee9764ae5aba43e97b321ce71d77f4d5b94150d592a5d360bc4a3f7ab55c1e2339db1fffe9505ce5e26b3f37d261f878f55f48242af1ad9ec269f58ef7ad0ce67ea4292e606ee58cce94120fbe09a94622deefc736708f566042127bb2d4292297cbfd9d6d7da303585fcef8762b7d1544ada0234ee604d93a480af602bd5756439622b9b229b177bbecd0cc9d62b1325ea88443178c8ad2a3eb441d7d0de2f849a5bed5d23d339d1dc76fef93f8230f0c4a5ca045bbc70b72081e6665fa895956188e7fef4aadfe20f998c77459fcae21cbae75f288771f5ea4bdfaddbd92e687857dc6f5e740b30954c7c012e838c6f259a6b641d839604461808fdc1bc51ce4111e14b4c4cea9643ad91edc33acd5c8ca7731b91e74f415ab9f60152ed888ab97f0ae1051bd8a49e0019bc575e715a2e08375269838355e55edcef4b487eb283d3f09ed681a34b08c3fb56ef48035f1edfff803bf80a0bc529cc99530d432fe73547b703493ce09ac1d771d8429240144590140d5a23d0998eb7b2105ee057ba89a57e912e72ca8b07e71abc101b437dec0d08c877a8b89b9cae17c121c7ced0b2a2c3678bd17e986ecd467a39be3bb9611c7d8b740fb5c9002000000000000000000000000bb11c596b6b5b5d51c3bb90533c40061e03d4f5be258ca791b70af4d31845bf8669bfa8ad53f5c2a3505bdaf9bd94c77d8f60f571ab47ac1169c4b37ca424b4a43df26282e23cbb640ee2310201a117d42033b9aae14c78fd27e0890a3f5274f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d76a428ea25ab0f0702aa45bf9ea8c08129dbabfb8ba603120add79d06ee509888b393e557292ce292d0de6f91cfec4d20ce5613fdef9222ca04941153f38c764f764ad99683b3447c5e791190b862f74f866e5556044a56780cecf4396e5700b4506fe1d347b7074f31efb7c75ab5f83a169a28869437deacbdd361eec9524e030e06920e9d70dc7f10865207dbcd2efb6b0685354ca6ceb4d6523cfef4e01ffd0214bc34b724e9f1d284ab43547274bfe4c616c9012a54aede015ffdd27cf9fb5a0a05b6274425a769f2d443c3cdef91886b064ffb9836c48032fee5db27e5dffd30303da911cbd56ac92f28306628b397fb489c0abbcb155a1f4b0b4eebc0d552fe0317d32741aac7baf9c02121ff6d1d9fd3b5de3f0b41fa80786b4f0444d527479002104377484eb6954a276defab5d7a8cba6f2a4c8d038fc47b8568c70fa79e134b02265809d02328e5391e0bec266e374e5ded2efd4f2997f73c476fa647f39168fc030f4b4bf4883d21be016959d5320b7ab6edd9c9d56d33ac0aaa5896e1070b2b3d0206a672fa7c4c4ed1fa28599abb74f64a9465fc2a22e3c1e056ce0642e73b052ac233a315f8c7e676b8c1c9e7b6f0bcb5aaab1ae3c7be73494995d2bb9e314d03408c317e7d391e6d6f8ab08c4c0c16caa090e57055fa92ddb2dabc47863708320493d1f637ad512a97332011eb52f4913ac6ef4b327eb21bdf5cf8392c716cbb4bc62b63aa9a097d59a4636b0e3d0270343c0753208d009441e902e2b03818bb44d53d8a50b1802f5a48cd35bbc97495b7f1d295a755abc1677f8c59e3c5021cdc9f331896b54d4e5f1855e23f0dbac640a9d3a723e50128e6a53fc2f218535e7d8543c6770feb0d09380509aa0600990d5b0763f1a69942fe6fd9f0dc69bad6d8fb6793b690c52f0acb66eb907725e41a460aec829622380f2cce7e524e9d37c1d4a75f490328304073a65d472d933f6b063289ae4d8b41d64bb5747330464c339f94ef9b72981bdb0c15e5cbcd7fd526f7704aef7eac5df6b9d9d6f7828ebacd51d28546a840d57ade69ebbc4d1f6f8b5a8f342c2a59bdfb4b8d91b71f10ef93e69c3947e7d09a1a4cc0645b6456a82b33bb868cbc58eb82b1a8ece7a6e771725aae38ca60ac781d25dc8e1b75ac1c6916819b9db54d0daef5e382d68b6033e5e3770ba4463f15ed2425d3531d655d0f5f8753b1763bbcf273f7faa9238b4afb9c4d09f639f753afa9b0405cf163cdb65eb573025be1cc015e188151510cf4a0baca2a5a55d972ab0a549f256a1c3935feeea1bf49a876b9ebac26d12f24f23e1dab70ebf772f992738990a03e9916835b37a4919f1f252a5f2577da1bb3865da7ab0c6731ba1f5b74201baa07b45eadec47097b9716caf657e987382499e58f21d87abd80a294fab958ab817c7ca5dbac3017b586be111ebb023673d6fed02ee748c90deea74bf4f245fbf815645b2918cdccdbabfa8fc317e11d1f9316cf2a89105ec2838ee8bbc92ec265eaa8123f7a6d934fb3bf01175c46a420780e0ededf5e09b9c196a7cfef69e978c37aac49e6fff4ba1b501c9d5a9033089ce50f46dfbaae3ebe0d933cedd0c6749a8e5c1e5c2391e14b6793d1e459a28e94e7eb9b76ced4581a45118c9f4faef7b53019a6d94b394156232f29b2adf357d839d46b2d1892886f9e387ca462664901c54dd7e7e75aab868a0e87f5cfe7ae77b3f6dcbeb995874f4e1a35ff532269c330e863543223a903363bc8b5fa4722dd382480a4071d3baebf795a229686eb127af42c83a29c1fabd646747b74b5fa73f5dd0d5a4a7f14c1da1a1c824c31530dce2e5cde51bf9c366c735378399638368b757f456e4dd29203a5b22ee439fd823b40e98a1a9f2c70ffd1fee9e49423e47087248ea01f9d20c28d4d85242eca8d0fa2b4037a53d7525c4ce2e37e6c3861a6703df24dd0c7d1726b2f14aeddfa70584637b2ed2d336112dc69e5d02a8881e461870294e554f57e631ff81d7a8513a7f0c9d2a7e5421c010966a9e93a2309168e4ba9381c544e54d4bc12887fbc25cd7bfbed56a39803f16cbe509b7783187d97cb9d7d76ce707645f55fb37e7d1a6ad1a0a36b425a54d585af4a3277d72cf490a8cc09b50188521973874a0d04359aac3fd6b7b310d97071e219adedea9d8a10630c9b49a56a162634d8511d595a24850ecd35676a4a4a1b19e6d93e12d51b43ea68fe680042ba8fc700902c2b010886668084aefedbd166f989d0f6af5300a48822f341e168b81b7d62547f86344601fb5600000000000000002aa75e0400000000f103c02e977c7b50bdde067669182ead8d846c4a4dcc763dca61d1af6c84a961cfb65703811ee09ab117ef56bbde6c684155d61b10eea512932fff6a8d611c8f200739ca99b689894a4976b2d7d0ab1bd57ffb9f01a4b93f74de577f4d007735000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d441fda6b113d56747888628c897086b0349aed041ef167410cc700638312f07b8c30ae03778e62e1800a44c58c6691b7f0b69220b267a42515dcbd8fb69329fddf9ee09b7fa706e6f74090b72076930064533603c1b37519a6c074e5985eb4abf3c0fd1bc7efaff57688b516da09000aae7bf120e748ded0b5144c83e7a7d4030db9ab565ba86f5a5163d6ca1a89e9a2ed03400cb902d0f4ccbae08b7cddc49c021c01c37273281de0955f51d4a7204f303c865d3741ec1a1e525c2dc171992ab10a0444fd4914593e663db0e0425a9eb00837d0a6c44cc106ff6ef969d7bc3bb506358858554e51ca1f417da1d6e90d499512796f0ad37756f2abbe331bfed6840b020c026b6654a7875ccc6b2e074e12ffb441d1fbac869b2d4a1c1edbb342620869021c43dade93e963410922bb36787d6082bb960408913d50b3f43c172ee886c0a4022c5805ef2930b2ade2451288eb0d16dd1ab752255cd0bf091190cd90e499f779022a491acda1576b8215913fa84bc331350fb1eb1ab038e918ffdaeb350671ba9602132dbf96308ba71bdf105b4a6462c97056336ddb9c8a7631bbb39d3d827e762b00f81ed7e5a7804b03ca79d5c9f48c06b61b251744986bcb191938974c0f6c6fbf49d45d1735ed7915aeeddf89d55f5e4b63e05068c4c8c8d766feb332c3c916f957f3345da21be888e3be61d431458d3160d6bbcdf4445d1de78d1167f53dee5590f2a03377428f06eac2b0ad1d0bdbba9a6173664bf8fbe1c36f957d7d99cf0e3dc55152910b6f4977c6c296aad545780e6eb02f99c34ce493a13f493657ae9d583bac8766f9e94fc3e49ea1ecf06cdee66c07ca598ce062c239b49cc283e76472ec7377fd5f8e9f57b9ad1e3dd4b6954eabf0be066ddd9117442122827144d9c2158297075c7dafe8c6ecf2c1d6fb72229080b4654f8b46123b7692322c7bf921578bb59d31d04b120d70cc22c436674c0995c05d27668d425bf445c61f205aee96d3efbcdabc286c39d955687e14157fa4cc6dd37b1672a9fa6183d34c65e3ebe56af7c3d28550775003f431f59f29f71e46013491900963f9ccc5be5c05179e6abdbeb5319a528a269cd78365cca8bfb35e011d1eee99838ae9163fd468e02aa70a998749609e4fc1f79500f32c03e5afda0072ac5e30b8b2e9e19eafa8bd645a94db85434ca060ee9772487c90e57dc53223cd62fd8da6b3e2d0d42e76ae14cdd21f3e5d0fe3f0c163847708ba6481d32b6db806e7e41fd613c53558d649a22f0c83c2e96cbb4e92ba55dda3b43c7e34dc174f598585d1aa8749349524dadf35bc3ed932b01c49726ae9c33199cdd8e046c32b23fc023a3bbe6b0dfc228743d0e603d98310927121304b75234c75ab094c19650be324f8ca7b638d628e14319f1e215fea084d6d2580fa5d0670e81120a488728b606bb358a34af869dd95d6d661343dff2ba17ae53eccca9068e99d6120791c16ce935c775756bdda7189f5351f9c14ca8242855f1607fd9e0bbb7dc70d029117d686e520613a831ca9a53350ecaa57c265815aeb8434d40634557a3d2ea813071ee4a3f5d8f6e46e40582714fb0c4af97119461a1f5aa11b901a6385acb081bd9e5bc4e1db8f7d7c9f8788b84c60f8c631deeaf5a0dde6487e92011fad2015a83703bb2f932c828729490e84377bf6ae359250f40277a2f01d391d32f5dd28510b356c0b8996807fe8ef4a882242c08108e1687e90b9a5e8c7f32e9177a0f35b205b85037e21a225c1fd8aa4c5748fd0eeda14359ab8db801d8f5ff7fa470a86d7fea8cdcdbf73fe8f342a7045e116e597a07bd53069b2f5027c9c87f40bef0995d02334f5df9b57971330889951e9c5408b444524ab03d70877d6b4a8a767c614a1fddf0ac7f9887252f010a561358afeb7534239a403a72c1bc2b4c1dc7562a9e6a7da7b6fb178b95630cd9b8fc12bc0fe6c0d0258462c676c6c5b177e3fe27f1fa53f4c992795a160d881341db40e592e9fc28cf3b8ddd91e4e907cfdc290162b2946d136cab39497f480c09f7a8cbdfd6fa121df61207f80a1577ca26e101c340ab58b0049361776bad81e196ce1799f1314c15acf34bdac1c4ec1207e630b039f93320c894ff42862a7ebe48f6e57e3b7bb0b44463baf9a2678104a0bcb9c6b3dc4840f926e150713aaaffab27805c29e1c512d187c6258fcc99004d4b37fcfd24388667cd31b1babbcde262a8dac4c418025695552fcc0d0d3c21a57d1225fbbd1a28e96e6d4dfa25889a7d8cd795b60288cfbec34318caca6a9cba692b90ed9f1baffcd24a4da0740361a0cd264b1d791dfaa9d491819ec6bbfb2f606969706458f44792d1bebfd189b0c264927a8a4f422429fbf623731e64ae262da285b735fd510a9644fea7f8430e3a1a6d5c4e16ed19b0ca96f3305", "516563", 0, -1807184100, 1537743641, "105384dace5745d6cb7b8264f2e86f85e6a1a1c3b3705b64c64fc0f380f2f068"], + ["030000807082c4030184af441a599f9b3b5780fda2925d6fe98ae155dec4de215254bcb8db462d81ff01000000056a65516552ffffffff01d41fd9050000000001530000000000000000039a09d6000000000000000000000000003bf3c4d0e1385897373b3c35238ebeb9925b9539acfabbebdbd9fbf8468a60c2389f18778fe27f5354ec8cdef883302dab795858f6822993bf12121dd694fccd8b9a615d99fb5e341902ee32180ba9d45c45bf65bcc64fd4af883fe0d75451a800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000af0d4f3df62d12b674c7516daad880f56dfd52d3fb472f66e6edd6d8dd79a0e6b8e6b1ec1452a9999ae6bc2733611d9c63ef2f689302a9933f741ca9767dcc5db613b1c0a1d1fa95e34a939b7e015ba050112f7f5e8998ede396593fd49306985f14e481ddf320141e8bb9ab9bb5445ad4d5e9860a4927b3aff0d4589becd8b40312636cf8b96c0782e155827980fd53b85a491e84ea27d072c64ddf16bd09c702032e09c0e63561b511236041006e19e2cbf99b874503ae0fad619cccd9b5eecac80a042be4bd2f76ab354a9059ae117eae35ce5d223bd2e1ce722441b2bc01b5bb9dc3ee164632203a930b54cc233fa10c2fa6803ef83371dd5fcd2dee7330cdfdea021b7ba3556e2c5b2c3b73efdd96a2778adc86463afe368eca9002e8a6f1d9c45403189876c09280233a3f1dc44a2f2f22922067868d62a8ed4bc46e8f966eb2adb5020c29c20fc3ff147af795a1d87dc5c9a3692fd2662abf3a09cca9dafd274e2e6c021508f725f46bbc414301450e1b364fb354a4d0529fe0da0fba51df35307b0dfc03132c3238238ca60ca43d3a036b4a4e09fda0a2a984c917668619b7d94b3a414a4812a970bb2298c06ac462b653c3611e337cc49ef66917b30743cbb1e9fcb832055e5659f27297fee8b72daf5504bc190340bb21a877a895d42ec99aab9f4855293d1552f08132ae11fa705a202b683c77f293c7c9867829896786c904e41bf4ac87b6745e7cb4299b5a0114c2dee217964e28d2df7fd08a84fcf93f80417e6c99099e5ceaab9fddba47688af049fb023712044cee0fdb69d1fd7fbd857a3def60bbb706307cd1dd961dbff91b7811230f224f6753adba07c567e40e43a76d5e56987437d4e23e9b0e7b368ab506785a7834e2abe7432bb6eaa45682edb107a3d1927b815b3ab17151e25f2d0bcfcb59a087f4500238200c95369d48b5032f4d0786c5d968fdde88d0f64991c87907ea78411ec43047b4d8f4e6d5419e7b89cb4282cadc2feb6f03cb896f7f9883603bae8f2b7dc7614a33edda99ff3f8123e9dc47a0d12ae5da70e2212aecef3b454f03eb0fcbe6774d450f2278348753aa5728f331ccf58a67c8935efe29fc9874cbd5ef47a2e0245290a84ef34773e2320ce5151d5ae899b3344eb061970929064ff8a239e85796f4bebce280ba224ec736e990792e83456faf63862c9fd67b27d1bbf9373a222d7b06b83bb1250bd527c4c7c0e6e6a26b3ae01bd6e243e01bb065588cf22855ba9ad66964c81cc4383ef18ea8ed91d9865c133e86653a386dd420d416f50c7aaa3d5379e576e87fa0f844e884a5aece92141eab52d6f9a040ef4bb97cb5c807327d9de9e384cddb77d4bfa2a67657def13277d92bb98d9f42faa71c538e0766d68b7eb872dd23eae5456226434f2ddbcd491ac1aa40b8c7102ff925f022aad6f5889997f12b6410675c6f052866c2a5dc1d8c822ce8961dd973d73ecc357d6d8f3ba8d9f3da32a0fcbd3a1925e210499e522b7d4c5e9b2ca5a07101be4d95f34cf0f2cd22fdd46fa183c4a4e0d046d26f4380c3bc269a61c34aa2fae9c884cfc45c429b3285243b273ebb0a87d51e0e1f7e978dea0f058e721cfd86e0b2365e512418195b5cfad1c013115c8d171f2e493144af8bd3f5c9df5eb54008f31e862df28c393a3fd0e432a8dcc784319915f189c5f9a0460e5c4decf9dad1456198c9f899135d954732c7d8defbce9fd64bcb5467c54d17ecf59498b448a552612af6484dfbd63e8392558124a2ba1883a1551053eaa4591f66b495d32ab2e829a9f0379b95f8fd14c6019e15e592fd8227480532f60e2cc9797e5d2337bdbda51ac5447a323db9bcabd852270f3cac7d998ccd140bc3aeb8a5c00329f295fe0da949169557753c037e18937b48a153ca666011c9938aa3740e2c4b1ac56cbe2f5f2135e4e45442ad6f5611abd3965b331a1ad803052abc50db6cbd057d96a922ba5c297fbf4628a515422b4fa1eb3f5a95fe777b2ad3acff8d3c953fee0b5595cf60cfbb39d9abe302ab740b439f8705a33520c81a87a65405925b953a28692bcbb5a97205d4baacd630d92aa1d26b9feff8206911dc8eb4b2972e3135b4b4e7fa951d09d34fa342d08b091c3afe00bc027d6e580b35ba2847003cd2c42a0dce7f4e20750f48fb0726e7067c774d4bf5a1b6eec31cb20ca3fe467714f97291d23c86c200dc4fd3b854d56590d971a419d0c714f63664c0cfd9a10e3e0d5b98dae041a0d92ff30e5d65b757b9b9575a4e2762211bf4bc022d5faf72a97d3e000000000000000054f9b90400000000ddcbc15995229383d7f49bfde87c5df6b9b4f7cbbb992bfb45ed743904bed6ef590f5acbb9de58524c8d5383e7a0263f1c507cbd7f16673535de847244f0bf51996d76a415485ab6f0ef9cc629ef702d84765e4591294b897511691486ba7f8f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009967be3eb9fb1e5ee87ab68c4c3edad3b4efb0bc8ce9d076922c9e1f8465a06807949e225ab5f9ff8b00c87d3ccb1cfc4893ebc1211d83e092bd7a0b6a7c64809a06f21286fc767feb33a315a768f3f59ae19917fcf8d70b254a83270d93794f54089b46034ed455e5f0a2ded5ffd72b4bd83f4b0c14aa986742b629aa2fff4c03099052c1ff3377dcf7ca6a7c7e9629046972fbef324a44ed0d4eb51d7c643ef303219cdc6416fa84e0e64a048995b09297e552cd2a62687b0d34e7fc94034e61740a041575059a08af353beee33536e5262db09fb6f5c43d71baed429b1d3dba6dba2ad8e4e07cdbfee66e0d69c894e09a49448ffee61b9033defb96d84583f81cb303017c20527ea7569f6579b7713f7edec1cccf018b24be040442cbdfd7b0b86fa302027cab642daec99e2da5bc2734ebfe0ed2de9f0895bd7a20ce0b8b2a7f22dca40326e5ad51fb628f5c32ed61632f5c8b092d9875f1c1357637cbdbc5adb644d740022142dfa22ff5f9173a4e526993b536ad6c4fa53ebf5295e264860f68cca960a902276458a7b8958ec37193bb172ba2e6a969e9cdfb7f0cc66cacf509581c2f5f10fb576cd01a7ca53e319c2897e186373f976fcd8dd1f872f6598808c2d0b29bbedb498cb64e6c66ff90c1eb6bdf27eeb3ec935ff14b71f73a47df939bd2362f63d2bb052c2108958906cd42bf4ce4429683bcced9d771eed641dd25d0ac351a5b19beb4d9970ae871e284c78ffac80f8ff72e1d25f8c66a80c4ad3bdec70332f75831af6db405311754a2be7f9fe84759bbcaaf153dd326a92ebe15bc94adc6b5ab2ae301f4b4aa7054e649a30660bd24e2d108b0b2ce7de562d04523abd22634f58010592e2649c3fad2fddf2d2018ccb5124d7e4adabb8d65822ebbc58f820cc8fa4d72f8341a290d83e777a287c812547bb65ba83084c735e2758e5735b559420ad25c23d33e3cccb766577e2d2298c18e591700bb8b966a3e96a325d76ec207e3e1e07972b7b49a1b16d2a8cdd2c44b47f5694bcba9d72070f2c66bcfcb5abdc718dfeb2cdcbb008454c02c8e9524cffb98e2b9178891a2a20deb8a77df5891616403298a15c04055dfa0518b226ce69b6a72dc923c6ff99e4180a8ebb0854fb0bd4da0bf010726c16bd9ef6de861b6e073bae70c832ec2b1134533865c5546bf242a1f7e0a2fd31dc1934e386d6fc419949d8f84929c7e7e1ff511df82120f128dce7642df9b17e8a8a8e382e9205f32cf134919974fd6622c6dbaf233b96a06b0dd3b647881a30f7c3a2c7eb26b217ed7bce7aaf6219f989ea71794939c1d8290601ca5b1f8a08700c0fea55845ae88d7bc4ee45f83167be4cfa294aa6981f4ce54912858478c7bf78fefe075867b4c1a811b4ab545de68f78caf8f514d031466ce2097a1ab2ec0817628051e942aeee4672b0e4f690b93d1d64f66f22a75017410eefe403fb4433b1e987d08e7733555e2e76f2320fd1186cf8b99e2c47274ed5280e170c426b08665896acc62d649008580f23ba7e6daef5ffc1847109ba3e125597645a08c08b9724e543fef8c906d4969b3dcfda4529cf5d232147a03e09e37ea50ce4f8618bdfd63447aff8ddd8748da6f8e1c30ed5b8967412996ea9c6e183fe5efaa3d58d13fbd03d29b35fe794d387f70d5a83e79b4f5af11da8191d840e4395550d387e44a5a0b90e487f50352be15f8a3c03804ece0719cd61af0545f1af077924eb6ad29ea6178a95819c3c550c67ebf37919830b8258f639334327bb27e263d71e659ea3714d61f1a3143e2e089b5717bbaba7e4e046cec21f4734b81b40dc7397aa6c8b2176e74eb2ee2d82476a1dd6bd8704bd7b98d4f4f8e25e9e7fd3c60ca5625161973fb88655271da9b6c88aa924a02c2cc15ee36f8944db61ab991178d0df69917457331749674dcfa7f45ead66eb4b32ebae6ae2b5b1fbb6f55c6fbd0d8dbc73207e2a9c5dbcd1ba6896053e2d524b7ab1d93cd89de05d9e9139d1aa5245292ecc32cd8141f887451412a8863a9e7de5ff153a3e024d6cc30f6487eb35f1c3fed5702ac3f11a09fd448e1bf630821ed7d37b2ec781e01ca4237ca9389aaf4e5408de3fe0654bafbd5061e543c7b96d0152eff5b379dd3c4ca8517ca5a15896624924da0772a4cdd7a6d5198b4bac210e8e1cb088b462a4688fda55aa42e325369a65a1fbc5700dc405bef6938550041f5ca99ef37cd3a2dade73b9a81546fb4644831becf4c1c2e073dd8bf85cb2d2443cd385b1fcdfde5bf4e71181b85c016589d1abd31ee0000000000000000d65d3404000000004521fbbb975dcfbd346facf305207fb14a8ff72afc9b36294d12eeb655686964ba3513e169008383219c2c9c64551d5b9becdb9aadbbffd42e0fa3a43bb20fc0c317e092bfa9163f89dff50a1434b4b5f141520321e1cc2f8284cc5a93d451bb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165656ecaa8c40476584e4bcfe4abf71764201e7b94ba06a3f69befcfdf12df3ea88b8df5b51f0fef2f2e7b66ad580a5f45945fd82490124b8e5fd3450ce3e124868eb1e661fefbb3b9f33ec48ab960e0d23a2b35494e0e05c4026d6def664949f47055e762b13539be598aac8e9fe9593c7421b35cd0e48d8631cf1787a2e2103094dd544a3e6df940987891cffdefec1c6d70fcf38e8235c5e1e95ad65f09242022805c100890963ab30737dc28b92881bf9dc1047b36967beac82d0027464c2dd0b03ee18a6c459ecd2d46995cda369d2bad08813e68cb39eb3a62da815cb4daa1c98db8f2f4add66e27134371687b0942dd7128f5ccaf3da142c2cce00bc96b141021278d3aec3a31ce4a5947083782d0d7dcc763350e3485eedeca1bd44bbb689c802099a5a5c7aed1d1b58211f0ef0f27c1d507794994d1243208326bb42c4b29a3a0306f2a58568187df93b3c41f20f2881ff1edcfb6a572f4476af9f349f7e028a98032e174b7b45df3a17fac5406bc9fc2bafd5808f1493ddee736cdba6c28b7502a803097c8db877f91d5de43c1b6adad259d8b64ae80662bd7f9cad76e9a30fa4cbbc328124fe2254467f0f20b98cf028b6fe7c34df620134a73f3a2772c7976227a4d7980c2ac676bfef08a19bcaf20e8327199d17b45c678053bf351ce1e9a45b63b1c67297d6c7498b0383dd2035cd5aaa2a2f967bf0f0ac20de13cd972fe23992920d0af46fa48831bf23b9da65ad2498fec77acbc6e82fca430b3121028c54182d99bfab3370793e0bc9c3f4bc7e088a345a6b2297de41a8303dda3652c71c41d544d000b733e0b4f8f2f3bfb08db879f3402b21ba8386674fc43f81be267b8e89df1c20b3be4ade3022246c0d2ab37fb89ff0a91562ac28c1ed41b742713b63d2152505ec26d001495b58d2f06efb25272a189b362fa4cc006b9390adf5a01cf87f8f5f9c44b99ec781cb4b72687f37e680d624f405bd43df22979e04b574ee8abc70360d954bbbefb6cc22871b0b2fa48c0e75faa7e62cf40e78e46614a8ac9c8d973b7ac5f68510e5e2831b98ca9353582c9de42f21e314129929576781223c2d0d246394a28e30996e8c8ce426aca980303fb556f7e04129919d288df481ccf3020750c21589507ba5a61a4228c9baaf5e444b10739bc2fe3da27def6ed7490c67dcc329cfabf744d0988e828299301789c63a4c593bf089afce99ebd6628fd1de98aaf1d248fb80e93de58b67a18d8233e1c0c0a2d511e33bc049edb90c76cd11a2465b23eb0f4040cd3a412cab1f8a45ab5a873554b6ac09cf0d3be2c61aed267f2781033a9bfc71768dff3c8f9ef3664e581b81ca946a8baf7b9e6dba41cb214f2d2f65240f967797a5f114dd164fc5088142711d1f7a286d953434c3114ceb6ccca321c032a30b0ffa00321437870de85e73dd5d23efc5a9bfc305ade360474aee4f851cd609c721232e8bbd0508677e520713d2cea5889a15fd1bf0104c50a03813b13f1d0758f0f50c752c2405deaca1039c6855736617923c6581820f344854ce6527cecbf00e8c9f6533a142597f0c07e151b8396ae2ea23878275c4d0e84b134a7c6d21ad48c1a7890e4d71c3d34bb764aff17fee3292115021309e74d20bd2254de77b3adac40d5fa0cc5b2c57b7f6ce8ac31d10de351060a3ab211a3fc5c93f0f1f6a7f5774c8776d2c085a6abd6be3f4fe6cc71ed430bf10632605870c05ade3bc9ee2438773a02da06aa84bf2975422b63f02104427f47482a7cb34bb596670d7300a13fdacb4fb5899377a7a482d3d5891aadb29e5428314319d378d57394c8a60b84a8e4754be66ccc1c3ac932dedc702e41399a88798528e6f2a9c763a9fdcc19231d348517e3bad20cbb05928629a808a71d084e309b161cefaf164598d12449b456a45ffb53c1698ef60b02398cb6ae3eedbbe3f718bd0da8bd06285276496f66968339b42ac9a4f4d2d63b012a996897f10d88b6ac5cc9b5759ffedd3d355299603ddf1b4a329cd87b61a2451bff023eed9a31911b139d0caa98f82b1bad3f21a53b914826ab6f96315b44df2eed3fba693a4f6b20c70cbf629b27236a28a82df944e5683c55ef189d69499cc11e83b4951d4bf2e4d3a28e084991caceeef6c904bbe7e59c7405b8205f70d5c634200ef5c1b7852ded270644f5a882ad97415983ddc6b9b937473d7f9702785f88c4413640e345242d5e822f909ed61c3c905a923283cb4bbf7bbe3e9c59e0c314a9e7ec2ac5414899a9da3d3aeed749c2ab7b772f43387f0ffe67ba83230b3a57d0e695a4120339a746c2d1b210bc7bc56bd65cb221cc6a16b7575409c7365c922e41baffaf26cb56e76ae802e2ef7411eafef4b278bf593d4840531fec7c7a4780cf808af86988f4a6e04f50a2bda727492a5c7f83e05d102", "6a", 0, 187932507, 0, "fc5dfb9daf75e1c73fdac9475d1076554d7f5294ef21fb86722f5e6da08bc2c8"], + ["1823580f019ab03227fa017910a43e95147e98a69ea42c938eb968893c7c6af7ea1ddee8850300000006526300ac515299ac652a0402d4eb0100000000056a655352632700c00200000000000a42f90200000000056363ac6a53977f7e01000000000000000000032cd71d040000000000000000000000003488736fc9830d49b30b0e1f75efef1095b9953039bb42c975842fb0b65b66cd992226b4404c7b3e0f99d67ac9b6fefed7d20879a18f60ac112b32a03fc122127d122953eb4ac89ed947f8bb25518be535472ffea75cbfc96b44a4feab94da25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be89e14820879e31933dc7df5c06eca40653b85be3bba5043bcb9d16f701a0ff015d052ec565f0e6fb025eadb74702168bbcd260d53a5896ab69556d3215354675ac765829b4f98f84a18f8d0538caf55add8dabfa0a78a63baf851544f359b18425d14ddca599e13d3108c786bb6478da3ccbf79d8b067b726ce13faf76336022cd79fb5f9ba03b5d0d4110345578098b8bc99e430c21c0c165710ab4833754d022f77f00d508319e3be68ba76f51477b6702f99d9ada11920354c22c059ebc2b70b00137f207fbb52cdb11f7d187972d39178ebe510ec8c7d39e9dbe82f342ff83b1d7d3ffde965554cbc44151063d80ed16b7e847ae1ab007c67759b3718d91264031c0c23fdab4536a2b7b8f731b0a34c1219a4b610f9e2018f4adac3e92fffde1d030b7d4d4486ec7217b1bfd0e7a929e0fe2d55d4aa92cdd26b47076166e1f170e80206710eb2ee2b25c26e3393c180080e122707b66bdd727830bca396567b1ec707021a53eb9f8e2d42fdbfea1d5edef5d474bb144a4656cabc4e255212d0fe3a7284020eb5dbb074fa809a293382dc11d6abbe42ed8b059a92a584c5d46b0d520c99a13c1a0af52467e55c3a2ac915610856928f4b60359a37996302d5a45284510794d0eb06a634fbf52ff06e6b9f2216ecdb49762eaf282d41ead09bb2982675baee74a9bb4cb9251106d619b7fd231ad37b09b8d7089069397d3410ea71759b0e7cfdc670708ea5d6e3c24b26a142bd1ffcc9a7735dbb54a1e69a3601c5ee245826b9838f26d2232a99ca830d27f427478acc6b3b065bfbf540cb2c74e60a40b14d4e923ca8261b48b49a1562e1c956c9d44c7fed570c49354125871cafc6a37d6092b34aa1560b76151bf00229cc88afd05df8b002a6b72e9dc89f2bae7d4c0de001ce81aba3d9b602242e4d94f54b538f9b632307e955d43e91afd119741c5d1145aab11068e4c37b02c9299994d457777cdce38e235ff6364124dcbb532100c705c79bfd6ed0134b30237eb69d64abed68b2280290d04b52cf65e68207e97da881e7ae918433d5c11d71fff911dc11477cba43e05c2018033a113b1a66cb15180fa462e30575efbeedf36ac912b4e678602ffd59efe7c58657e2df8c25c53b32a37db08f13796bd9924b2918b5624725add986ea4e6b36b019a8363248924a3336b611a23dc9bac7397d69cea3eb87410e85aa202df4d5b4ed94bc2e8eb1b8a4cbdb140a472689b81c72be390ceb1e22908b300bdcd02a84d246e06e7e1c9783af1794db5e3b8a9926a9959e2353a3cdb9f44ab6acadb62f7e84e8bb9a68c0891e36899687aa1fea188be41c1fe335caf27b86cd1c625e4d9c3d2d719cfc4b6b03b5eeb8d52188f2f3d1069565806f35ae36e6f2c56032104b5fd07ebf90a83726b1eed6aef2ddc8847f9f2079066766bb34f43a08c076f2099bb099fa9b6b9851291f88b1fd28a3d5314611f1746aed50e628a428dfd95e4727609f6ad73399761fc7267ef2359fd722616515a49388392c23706e8ea9a64337036b6f3b95e5b93117bf8c10d286fa9544927874bd8e9eecb6448c93ace05b4cc835f491cc44c01d71cd0e29c50cb493614a8fd7165c670724ff3a13924299e7fb9403861c92a3d1e57932d1777e83eaa3d27cacf85abe72c90fc9bda81ef252bed875b513f85d28401a4d4e75e27522022e9f9c7a73ad149fa8424c894b04f2e3d07d160c47ee67de5bdf31fa3031a13907f9c633762cf1c45cfd3b9334356828812e5cb723c90bf05d95e4e104a055be8e498327cfdace2c7582830915b32a8f68e3da1f3439e01630176dcb695445d8a8a767856dba66affd90e98d707efce67a364b75dcfef89602f75d544094d1643bb97a555ea6b413439f79e9e78e619bfe732d703d6f1008bd513d18452e1d8afae8e9b2c042e63a651ebb239376adf015b2a43c3204f5a29778eff0351e9512b29ed292d47f26182f5fc9e3c7e37c430ab325862d3cfd85143279b54278dd2189b21032e8466d7de4a251839535e7bdad474ba38767a7a5286bf915ad28ff1789f5ff17b717d23c1fdd07cfa7c4e18f047538d71cf886f06b7926615201a880697c70b5895eec190c18129cab6a4b63fa5515ba872ad24c76f81e2014ae699503c8ba0a11445ce6e52ea9d43f8f667dd853e0db43148bc50af29bd9e7ab5bc2c01386c31a4119165632db41ea6650e23fe2e6b7e6b03380536373ea584f87bf84519b65d20ad5b7b869c591552fc79886ffe52c653c2e8fbf1859ab98f46bd68a4a4586276c04c5f59b04000000000000000000000000f9d8722ea556c12cd87e758aca772ba89284aff4d6907c43192c9cbcb06c8bc9858782d26c50aa9ce99f5394a083aa906cf554c3ef6261f62d7f27e60871fb7933ce2f60620c6c0033d7c923a7c610189e7dc1ed8442665d9bc701ef59e3269600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb8b6d399f3bb7d0c3718b0d58f20eb79b99bf72aeadbe45da358ae722bd3a1662b263c28eab42de5e900d215aa8812e9634a970d2e5441959004eb37d58a1cac4a7eddccd99081a47dd18acea702701072a5281c43df79e4b64d5427ad7baf12c5a04a07482bd8668b19ff0f5a2e03030512481850ae985cb42032b6b6aed6303095938352aec5c0872ae275f8ded7126e7c0628ab5258898e847e6ef089cf0a0021d5a7308c4972d238f29a86794d49073bbb898928c810be3f51554c3097328600b08b05df1597f5875449c5804a6516e9f7b0c313dee0ee85589d14382b43f0f0c009b1aed14d92272c74023f3f2557b18a827519804a79d70ce4bfc7a6a1fd629030ce0871978514131e901243e5e944047c2c0352cc227ee17cac062a2ca3fd90a020070767f52b939ca1b11ffc951da98db1872afa1a76fbf1727d18d77ff1cfed2021945cd550d570464e562ec8b146d4dca7191d02880457bf9c99213e78cd60ff60206cf4241a3557106fc208b16c18e6e9b8c6f61ef390a496c749d71863d4d73640307e878a8e1b0adaea380edafc71d6315a37e7996f4d1d032f971f80a23b5387b2e84678dc850f7a04e0ad4a855a92f00c00ff68cf145e9d2650a6920a95e087c317724fe09d9beaf063e10eaa069d26e55e89bf8b9430fd447cf7098c1197d2e5d831c969d274d5c12cc9e7156aa0e023bb8f2d6d64b6213dd84b8419b4b12111740c59c2a414e170b599f7346384d8e02d3422d42f8997cd67bbde0d68b8c5c61e98d3aa38117ea4e35fe3d200e93023b8ab301731cc19f90c04201ca58eed8530e194535064e8103a2f72dcb578a0ce634403f9c73597696a5353539fc926ea705ad8e6e255c79b5529bc1e1b2b39e1b8ce66cb02f58c63631ceba7e79f6d73f66154d6eb0fe8912734c3c2316bf88f7aac1ff0877a95d848ca28435d3cec88207c9bc2fd094e0964caf31886f579c761cada40144e8eb7e8d52554f6ae39d168864520b01e4c15e469cd0392039d7f7ecd0fb0c394c5de5835ed8cba07d95454194367f7f474952941743a4f8802785cc925e6ff9922a6547c250a59cef979d71af1ef96c2f02a58f7ae4613d327421fcf1df9b3e7a050252247d55751abe6bab347ccad778dbfe4e7921ca551a536d2ba2deb53272cd14ebf3d0bdd9855e0528b21417f01386f1ebe9b3c79341f68ff538dacea4801404b68ecfe3312d607f69907bd39e33d4d771da7824988742b1a95ab3df9ca7b1f6c450ca48ee129c2268030995e577011eece1f810ff3a287cbea6a5b0f1a01dfce7d9f4289519fa28ce7a7eddf60906e59b977021dc3723451c46bfffcfff450aef27db55390294090143ce6685ff6edf81bccaf0583648ba393e329484152af450e050d23a4a91a382c433714671f722a701960e1cef05dd4ddd6a8a790e3f7b96cf50be1b78c27be34c0aa6aa74c7875d816823be930f350740d9b96a649ca096232666dec838d043c676bd9592d7f0f23292be7b3f8b9cfd69a39c580ab4e0a5abab3cf84fd9dccbd9d5c0537192a985831d315b1d63c33e3236ec8bb680a8519a3961fff8099788f018ffb921be00d53cca519b1a7e666a5fd3719b0732380cf5ca14a35c1908aa34025614d700118e9d31de7aebb48af85cfde133d06532a6b949f3bb9bd1c5b443e689c0af9024ed2eb09a673e629db81bc7057f90bd50b9b5c52d2028992258344bf5e0a40bf21e686075b6407305936afe04d5d9e9b8458d64f23a93cb25eb28d0ed78b8f1028e205e74ad32c27fa522068dbef9ef770c1fc4e0145e44a0ad3390fc38174d98a4460bf5c900931fe1ff9cf648356caec780f368e3ddd66bfc8a7536bf56271ddfd7618772754ee0c4870208e836274de4c42fe22a715a110e70b3c32998f3a9f62f9befa894299235e48132c0bac9e9f2119bd4e96c787ba1a7584a9422fbbd061a4043b88f17e69d8f37d97042fc4f1d5dc0fb00d2e63a7ac1825e1511935ed6d29ec9811cb871cda15b8d28b48909ddb5e6da5e7135606e3c1ed00c8d774af209b4a7c7e5a07ad8896880814aac8e0f927eaf22826c97bf15e6934ee290739955799840f0eb9851f8aa161e411fa9505fea644f5d5871f0639510d9ee83a64d1d3ae86f69203fa870a266eecb6e3e9bfb7dfc3a090d9af736ae1f9985e3450e8cd9ac884deefa8a9bda44e2e35b41414051d07aaab9de6274ed876204fc9518b17c9c03f8e80502419ea45cb3213079d6ffa889487263185164f8b8b6f4b3a6dbad14a648375d7a0000000000000000facedd040000000088f02883343908f97d096826b38fdab9d17ab4acfa83b6a1948514454c5504b91981df9b2cff2092b3586eb15830a9d196c0f631d57e6d9763df30d4e503aed9161d42c5a5999dbea0c538830c39b83ed307425804fe78db0a63e0663e5d77a700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b12f5087be569116fc913680e5bffed83610ab355c8efaba0f7914f7e8818a133770116528aefbfb953963c69465c0f9218cb25e99775e513403cadb8f579bea0f221962b616e8e6987f29f863418ff9143fca19315428db3de8cc0383df5579f5d9230ff82c3e35ca8dc0aaabe8b4b4fbe858167baf5f70026f135faf5a32cb022fd27a737e03506fe9bb2aee6051e6f80df5343eb12fe525bcb83e417d99370f02024afd246520fb5a24da2a59d7a7f17bc257673f3b6d8bb043faf8a8673c7bb30b071486f17643c3083bbb34c255a8e059e9307933b478a541fe1d70dd749bc3820bb5ddb0fdaca8186dace105b12dab47fd12c19c8984e8ea0fdbc224b65ff6c3021ee61d6079c012d7e46d4ae056660bfd64ebc0e8632dafeaa6020a898a97b8860321182a426aa9abcf111521a24a776d28593e6c57e86a8f331aa1d4797a449db20212ae744e20f18fca5115aa6fae7dc8cfafc89eba2fed08eba2073f75d03dfbc30221fdc2128d5fd0646df3c75b58285ac82573c67ef4cc5dbfe830b5ab23004cf503250486b707bcab1a3f2fc3078d8f36bb683f1e1e4ef3fed0c04296160553c8aaf07b0066a2bcb2cd85f5a558b31694af32a3a54d97c0b20ab4d32280851b9049502662209b8352b1b252b8372bd8df11d07a023e18824d4c42f6aed51ed7fbce650cfd5d92d5235a0acd45f8b456d303f933b849f84e013fb4e7a23eeff293e7fdb0f5a69174f42304ea176d79cd5422d0a683bc06a139ad999e4e3b3e0ccc7a179e56d0268048ebd3c07e235ad189b7528928232d91763b329965872e0236a46f4ff6d5cc8b5353ef9ae4932b87d9d36bc483bb8715d1045dc9343f45534dc51adaaf00c8768bf02e72ce0102914db950b5d602084669721512d6d508a9a5dd8f6de0ae19bd3f851c6c4f4ec64c3c01c3554b0ad8e2f884879b6122ea3cdb052fd5cc3d20d0145d8d0f0b9ee6762fabf2d33f3d96d2fd68ec6eef1fff0d2df21bdae2f06fc178017cc8b50a9cf934b62dac53f97bbd3ecc60455d8e9132811abf4ca1d7f986af0817d5a7cafb5f12d0e3aac072e5b7c565189c4557c261634c245fc24425493b175d1c89968be1d5ebac7d3597d71bfe6502eec35e7c3b9dc8014932131a77fbee3d47ee3434b94adefe8bd06e1c31736361bb1483d4f1c4c323e87a4c7415112b89568f868ed3ea167b8d65584669093e5bf478cf10fe085820042cda1290c9a199b0f890d7f45cd2fffd09bff2b770cbe7e3b49491bab0c5289f0b121c923efbc2bbc5a569d19baca80a1221498894d5a847f83134efd3ba51847de68c881fd75ab948fef50e8514f5f8090b9de03e0ad9f030619c3cab4f915918fbbfde5cf73c0d51118e168eca54ed59f52c641c3628d4b1ed66a94f1d2b286ec7f491f474d21bcb70dc03472153c1b916b9d7f38b40453638f0aed466e3e23f4b8a28f05b9b6e4d4f9992f301e9a53444b471f6102b2e0d2a72ae93a5cda1f8cefcdf8b905febb19e291a65de58e4a501f1bc1ba7a74b1618d4a77fd6a86ab507c22a6acb9aa063701abc697ad6c8d855efdcdce0b4bf6631e2e7d55f18156448b348129b274f1ecb6b07b7fe3751426ee5360a4e86d0e91c2a46eecee60857c811fe050f3fd6cdee5a38cb9c7341dc6a559b05f66c62832285532d56bc8448d2045f35e8687717ffa5a6f959352d2ef46a32abd17ef6d5bebbf1fd0544987c30831a2795ef8c382869f85ea61066889e62c391a490cd58bd80061e9afaa82cbc37ff205963d9c81f42b7023b2dfba07f01af19be65c53781378472eabcbee3b0ea4e9ff1d237998d7cf17c8e26782045405aff94f71ffd492af1971efaf28f1d35917661fd57e0409ad010cee5ec4626d1c8e6dad09c80a9a1c45cc4b54a8e4962b050c4ed6739de1083ec8d6c1ab8dd7700ea5130923f7a70dc932c48f3e9a9eb86a7d90afcfb61801223d246d644604cff77cbccd3da4d9c746f581573cbc703da1b6f6b1fb4688cf9c1b73356a7322c2c3329b147dc9f0fe04c702c40d6037242c4b2c1e0f15322ed6ffa2e520f26fbc9adc9902761c55bc885838888894d04ac8203431030f6a720ef4c314c78e2824ffc5d539029462b5d8b497cb0525391fb6724f28dfbc56194d60f295b79a1411e58cb5240e2f7a615263472664ef8be0d88d68a01403f94a8e2bc3a5b5116373ea9b2c048e19dbb8162fce5c98154e1f2c3d7cd318201fa0f3d10ca61d6960a6be1ae22bd6777cd6e2cc66fdddc88ee8bf0e46e96c6ff37e0732968056fc1783fbf72a614131b710a3dfdf8a0d25272883ea8ff66ef7d1bb7adcfd7d5ae290a87e3a06d18694777a277d323613d50dc585a5e390ecc51d6725efc32c0c25ed59f3d2eef0ead4a734277355fb15b2178e5a13b812d09ec726569aabd0d", "635351515363", 0, 514726874, 1537743641, "0d7014f6d66481c7b25b8eacc5841eda7d401e9b615e619ac172f3937fde7d4b"], + ["1551c81b02e0aa4c852efc8e925e7e9365d39b265e5e1fa40fc6cd305d17bb7680e0902fca0200000004ac5200acba9abdf9709341c196adc518183de834201eb838a4e5cde07d4149cf547085d08a7732de030000000151ffffffff024e026d000000000006526563ac526a2078fb0100000000045252515162ce403f03d0c44e020000000000000000000000000ac382698587a63c36ec24d44ea4bb9835c2dfe334104064bf894bd36052771b6c5a9e27d874bc9f072ab553c335509972bad9b30faae5b0349472a32d081af4f280cd2df66ffdf3dad4c88fa0b2cc4daefd14e3cf7e85a1caa14cac73bd13ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6329d3f61e8021cb7e532b3232d1e633512dfa9d6f89ca08581a9d13149371bdd904663386f9385e87f864344b8c8d096841ececdce0ed169ee1dc468c4d1dc196091d63611698d2dad49f3a24d3c97d90630a79fb34748c7341cca724f5e135558f159ac5a387f3d948e53dd8828cfa029adc6290be18bff9cfc012cc6d5c0223e900f0a8ab6a4ace210dc1c62eaecaf116ff2bb72e2f0690fe8d81589aa51102188ef53b2479e2c6c697382b57ed7c01797005290d869ab9ff9d909a6cfd72140b0343128c804ca54eba5b0581aba91451e131fc439fb6e85168d128f1e7b6daea7f579c456189b967fd9869adad8bcb7edbf773714cc54ddb3ee8bca9e2b577c10219bcfed33156fdcbf529bea41b759c8ed666a6ace5fb69d21f205042dec61ca50209545076acfb6aab2c4f8070b4af85c85ccd525f2c3c40c6b5511cab0484376002261e8c4637a7f76010d58939c4f746dd7ab1ab9c4076ef4c107f28fdadd5bfe003279029ba9bc6bd2b0e238cdb486b20bb3969e4b3a257c55b806e02a3e83654cc031f1fd0e181f3fdc559dfd6015de68affeec47d5317d07dd2e409cd6e975f238320840573509c55d30fc895d1f38a3a21fedfd7690b744f6c1706ad52e42dba009701ea2f749164e91f4a7ec5e864ec6ec4edf305494e63b967b0d2fd0a6eae179c1b398b986802ea8db40983a148d7677ed24b70d4b4f3d7ad5eddf205bf458bb89a3d176fd99a7688f3d72d64f5b22b4077931831d709d560fea2b531d750018fdf5b9f102107bf9ada162b87325be8369a5f87227869d64b769d3d7d9af66455e7b97fd429b255ecae52c720e051d4ab49fa3bdc5dcebb363d4cb4cc9c46b54703ada0fdad5eef5b2f4f273bed64f18f554dc1f507d6c8938b5b649d70e76567670649507b6a46888f50a09d0b732d2e9b276d63da8ad373320754d149300d4a3895d1163dc574f784b7243429f285421858e66f4fd43a26bf379c8607d3493b60e18264c40d84d38624ace8b806745f7c4bd8c3937497f3af0a59979e717fc7ffbf461303f4d128fbcae06dbe7210e930b8da750a4733b5949c1a352f8a34e08426ffc7449767e6b86a8d6c566c389b231df208ca6e21551d6460a2d695004e02262cd0c0e9fa625fcd922fcd574fc0bd889ae758d1aff9b49bbbac21bde3afffd11b75fa1d30c3c3b3824813c58808d8b104a703aaef1a95960df9b2ff80274889adba5ff84abc5c769876f7521c64ad57dd6aec8a36a906816a4abaaced1e06972d1cfe4404521f558e6442874f42ddf08e0c8e75b4b64ef42d34210d63e5c66a4b4c3e267da8fcb084990a2cbe21084a9c9d537e3138a37c056db526bca78321e9b269e67e3f98c452800027947e4afe3a2e5c921741aa1a4143907773eb16e2abcd6dabd687970ae23741205ecb05844810cd28e9e2b630add8c218c0ff826c5f371818ccb3170d634448798582c6cab450091d7bdf7cdc818076f4d8757d6f26cf53d03f7dfd08cb7f04b99e0cfd6bea77c05d6064eb14427156976e2b4cada9ec9ddbe7f0289081c06e3deb53fd230bf93888dd65e4db1d277f7c2b3a0308b0c7a526dc1fa60051801c3af63742750a5df76d06e5b075bba30885e8005e0811159f3d562c490e04931a74b128915391f2615db4a34bf2654c3b496eb0222b03d09f9fe7fe566669064d432a3ca265870efa414b73456641a101053b44d263a3b3add7f4878aa4184b0f45e331d566106441b518b2b2dbfa9f4d1455ed753a830ac351fd68f99ce7cf9dc3b8f76d4532b0ab1eee0ee8a15fa2914e05ac63d0dae1a3f8e2906629f9c7f05a63e07142956cfea743558b64462ec31cadd6c9d1cdfb87329682942a617a5ab4114cfc1d4ceaab8b9b418a66a9644d58758f88f02252a9ce102767297b75332035ca631beeed3a0d0cedba4b73f4656e2c30aa0a9473ca9e18b85f17d992a2b20ebebed1086b295c265c0eef038ce36347daf82e69b13b43a0ee58a6d3f45726a77dbe85b9004bed3d66a9cb5d6ec2b88b05db7f5674a82ef0b807fff136f79543914f9f2e8c05e75929f907d4107143a87422c09c24fdd8276402dd2d61c8b838fef2e56782a9de845917d9f4e76d22f2ca148eba761df9153274adfdcae8362e6b8af229afc94698acecc664219292d6b0993a423293aecfd721d7819e807fc4ddcc22d35473de03f428d58ad7f72acb07c91fbdf900b5f135e8593cb4d5a4fcd00e0af0db01f32ae15ab33cd882df7babcd0b8c9edb8b36a2638d228f310329b72530dfd101000000000000000000000000d76e167fff51cb49cbdd27d311561d7ad04e867823742efbe474bd9a39e7eb2ad800098ad09dc6f915bdcfb67a9deb8dbc2c81cf57bf115d138dc9b27d461d36ff9bd91e7254fb0c285cfe344b6e9de5beccc6853a21ecc104028128eb12be25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c4ac866dc89f19ec1fe6b0af89d1620540b6d091145cfd25f619af43e60a4ad7910dce1b14e462ef70b1e8ed63e68d3425dc6e7a7454b7b04dfd14596f3383b904c5b309455221b82aa5a911e5349ff35d9f77c4c6220448685a6ab833015a8f85e54d3b76145afc411924263e62333be0515f29da06f045fa0f3928bd78ee602241519bd2bf454e9d16e1a3c82311bcd551082b21c9601e193b536e0d4c8b5330226205d28e395597fd47fd9bcf7c67ce8452f47427c463c685714a239f3f020b30b0151eb31417e78258cddd6f49ab7086fc4cb6038d7cb87ceb88ceaa76a619758138439822e19c073b08406e3e736c913199832368974b2bbcc307616909ad6e2031618f645cc480142b43861beddc4fcfc3a62a41431af785e1af687c942259f8f0225d5537cc3b125f6ea2424b25e41ffbb917c1b0ca1f41efad607a80788be175102211439bd3378d1b5529411a6f733e3176cad817d02ff1e8e1fb27d69a0777e3a031496191e88ae4e31f8109591475cd0d5aa452e33b5eae9ae35e6df05ec4350010321b205592ee5cc734876e0619173db0440b28c85b0061e39c855c1801c7642ed259d3e13819b0692cc3755af1727c9348125efc618bd01dceba9857d76100a738f1405faa00b7c13025c84742d4705b6e333ce411e24c6295a397af1ff77c5f10369f9180f765fa0201391aeb1df7ef64e24f4a6853940844d6703c0eefba02ecf43a3616387d1d44a06584f6e525856dc24c899b0a45ac65fed4f0d415c52bcf013af7a5b8f8db697cc2e676f1255b95f2a4c50ab63cf25eeb89b5ccd36a9cb3570fe13a1a1f5d2892f93c4c80fd615d5be7233ec10a1028ba041e4ee4a572a68001fe8b0fae543aea50bce37d627b9eb660bc2aeb63f41630e5570adf37a9ce19ef2df09739dd3aba94a40e0b5c1e53bcfe116a2cd7bdd8e36f5638c160fd0043579e8cc9cee9c7333dba40d1954f912dc203624526023d2f4137a5d20c51b389b6e25cde4f732c444cc5531247fb74d4353372e2f6ae8f0319f2bdd0ce9172a1f62a1303708695c0b5b04dda4a8e690b4f9fe982c3a40988569c564ae93aaebb3ed4ff813cc71f3891cadb84ebadc161b33ba3343d2ad5a2e784557d0d48cef668d00728fb3c08f0001609d4b11777081dcfbc6f6a6470f13fe2e314efa7de300b87a5390cd9b790c79de9413d8c51c69044788ba1bf6fdcaf5cd53b7c32839e129983d73449d7b0ea24da312ff656950ecdddac0fdf572504777b70631785e9336ea387bcab66832c5014acf15aafe5aee3108bdd1faf3023c784ffafa6216b4e8867adbfb9aa404217ebcd6856c888f5625ce69a89deb0cbc5c05c4be1c1e8f7e5c1b061eae42590ef085b775d97377eeba80dee6bc5c9070ff02f6106f0e986323a183af51cd021f1ca0fec644ae84bcc7f4925b023ba06c963d459ddaa12b1caeacf2aa0bc99f3c3a693a4e5136e14a8824631ab8966d8de40629a8035bb0d0f61380906a6579a88de39508472e8291acb8fc05952b66552654dda846d88bd6d1cf41f9fc047ec754e560595ecb37aaea506e6bd4311f6d955172d2c7af84f99d280828b422a14495e50bd24db79fc63542dbc6acd687202e848f0c4a83a4cc6b7f8b9219103528358ec38edd9be55b860088ecf50d220265fdf268f5be67bf56e270b331f94990febc99b27d5c16545b457daefc4134200686deafb8f66bc052a1b620f817c58da26873ea82f9b17eae911dd54a879a3a6f91f85968326bbaea47769b5ba677e05550c3ee1c93f1acaa349693ff5bf40a6c969101b67bf00fff88b9c439b26d9ac1c64d92b359b356d56fd5191cd6d208852069b991891b83545ccd55f4eea7dbecaf02069823781276da6d763bb2184cd34c45358cf68233e5a2cfedd47cad7191848ff3e924933ea53ca6ed537c335a882d154614465e5a8d4111584eb4dbff98705905144fb3d254239af4fa046af234710d2827e4e70e25b8cf3cd7d53473510a3c204771e26b344caabae013901a54c99eb2dd8aa1acb02d9adc759793c1a326e32eb44e4d89e038e1110977a5ce8ee42c38cd5c063e3a6abaabd1220197dd2873aa87808eff4d2ab20c1a1082af06dfa0644d175fa7c75179e475cd8824b476c2f3b8593a29468f0b7f27ed367a4a63815398d0b259e6920afe6897fb9ea011f09e10aeeb6e94f9ce80a93419e36490594d2838cbdecae97b09f280c59e90e7c0cfbc9997bd1175d74ee171153493c2b8157a73d59c2bbd126ad79b74299a60a960227467000000000000000015ae320000000000fee2787eb2191bd32cd37e9e3e5649c16f3fecda26c171bb78fff9fc24eeb3e9e2305cdc40cec5475c56962c7cecaf2b97a5b46910dfb78ee91c6ba6bb710e6b8f5190fec81665661fa941468fbfe08ee835f3571c72f0fdc75cfaf0d843831e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a25b5da35883b02180a1014faa36f3b0f7b003fc4b4d1275cd99c2ec4993c71214f8ea93226d1d717aeef3645ab0bb67f19cf244c0149ca15d953588e9ce19fd9b46e11e718b9404dd12f212a4c2d2f31f39afb62bf825968f474a08eab5a9b105b2d070a79d63f038a88f53182075dd80cfa0932c7a1108c23e48590bd05cd402129f1e9ea09fe3dbc83ceeab34ace11529c559cc4ba848939ac5c42b39b7d2a8031d88a182b86a4bee989ad142c1a2a36d9d5a3fa36a424c58214b3510b45bae580a015b7413ad0ced142a593b5f032f182658a1e9e58d2c9887eab8e93cd2a3d1cfa438d2096db805f7ec7da8a9448d68eb77aaaf15ed2b2069b32d7c80f6ff2010020386b46f7096e81e0755695546aca2abcbc4849a40c468c65ba9f1862088e5720221de012b8ad9b720b9f7bf415d9c445c2e8359bd31a59ad4bc7690aa8fe96310032102335be9f585d010936e43f94171b1251c858bdc9eb7d42a385779df8f5ece021562d82485dc2b2c79c0ecf20b0daa63f7fe586cc0f47dfc8c2005b5062f0e88022fa61ee8656ac2a28495d38d40643b7e3f66b10f100f42046d3211c0554842466e4b0e3328389e49e48ff8213d42f3f3da69161a5779b43021dffe5396c874c34b7e3599ec749a297190504d0d5edd1c6d713727bc0b33ac4282e670aea2bfbc181ee0941947eec2d85919c8efd48ded0a99c7fa02f3db6ad4af8c2726b89e23a8c1d0c9a243aece3e8e65ac052a1b04bee43c094c0ee85a6fe6f772e38d83f59804dcf086ad188e72b51469519965cde4def7e0d427ac15bd1778864ceb82708488504a444a4e3cf02b17fd768f866d902a43e79279dea13592f6b185f9d631e22fb4f68497c9d97266e08b8c035dc5daa88657201682a25a09d613b1dcb638bc560567d6f3f4db5c5c11f89cc2c4c58de19e48685ba52dcfdc612248289f14115d825e37b8c58258f89700ca99a8dab2c23b02c64727e242d0f80d31ec3e3e349e99a40b15092ba2f5626fd86e2c8e1d4adb14275016cb774f174ab42a67814b435f0a949d12dedca070fdb59d4b291b8615a04ea6a034a3a676587481245dbf31b0f6c8896fb9ac1973001ee78d7a48305c02f0ded7f1fa61ab421adda0874e3deffba0c6a3c7b50ce1085d603f6ff4e797d4604ce2d6b485527da65390bae132c8bc8a0862c0893c75e72045eb91118aaef2e5f73c25a6013339e66060f9cdf9824d1041ab102eb888063a1157b19b629b04d5b1043b03d0313e6132949a653f1afa297fb558379d2a22a7dda7cec01c2018450eb6034ebe5b47ceb2060ce0dea62949d0639427f09333c8de2df197b3c3c0ab7a31515db12e0ae4f8a06456e2de9bdccc8e3c47747909122f04c3409f668500a7a211fd419270bfa373be4bd528b18b356d6ff8750149bfbe795d44ab1af79dd587285a1facfc7acf5107a04036cea189112ff7cc7ce098d74ac47bc47b8141c6b704d1f5710e07a43ad807a6f6168beb1c03da895e409763649c11872852dcfcb9a9e9473ea74237a7cff54274be5f67e80b77b0122fc67747080952fb83b70ff95f5ca60aea3e1a3f41294f3ae94b6a675ad18cc090a09f11b8a167cea9c37e14eec25641baf4c6dfbfcc999d57e80152c35e346df57f8c349e27a324d93a67dc74805c2436b6b7695791311c1c28998aecf00a4625aff69390670cb66203225d9b2514240365918760f830f2c3a03e0535062882f597cfd2c4021f51584bdd9de112639166653d17b0206a27a0f7b98215de4e90388aaf02f8213c277dee1f1839d4bffd8f8886fae23c3b9609fd946a363e9cd49b29cc4ba90bc5e5dea7e0787643be850743a1b656d9dc2fe21f77f6158fde184c01d4b1ab23baceee71b46f9bee71b9a69598f56b9ab3606689dbea72ffee3a7275b3bb4a191abb954c6681c370de776d78f4927c7491fad6c3ed41b55beb6ff919bae5d781c504f0fb9e52844e4afa099a7c509952460ab4e3a37c5aba70c0044d062a90d4c7f6402f3b3207494434b4f6777b9352268117b666c0ef18a633cd6042eccf184032b10b99589351d2a8a19ff079f869fb263379c1d4bd4ad39012efc72f9baade917eb1e7e2d69e35a08aa7975b103b41586f3e791f11e1a1d6bd9193171273522e9fada160afc352be6f8cfbc0a1c61c2deb8beb35c45d6cc3f7c361d8366b1d938df8dea7196c9ab48f41f280d774aa683b54c0fa30d0d6c548ebfceafff82e3a1b3d115cece0d7dc00d4e9c529100c2e1a4e214307ee2b44ef78482b55794280e060fc6586ffe55f108084a693b1ad5b7942a7a652cc839fba5ddd45fefcb90cbc47ef070443ca9c5c714fe9ba671708dc98d958c1a8a7e172cdf97db233ab3d022fae782d2d7963e8b9729e7bf3b310520d2dddc9c05e3fa1b62100307105", "65535251", 1, 331693917, 1537743641, "b92a08a87eeb5d86733faf5d488bbb85f527c8aa13ccfd7f858965a5a609e034"], + ["a8e39515042e90f179d0e6d5891d682913600d5149e6c78a28390ca68915cc421a866a2d4e0000000000dac3011071ce542b6f38fcd6b3aa2843e7a67bdd3dbc9d2dc172735f6e0d8b2484d2161203000000086353ac63520063535fbefcf5540a44f2742e78c56f8bc42651c393c940965d1d65335320e876636c983657d402000000055265635152ffffffffb06252da7279175a7049e54b1f72b5a99956191d904afb00d5eed8aa06b9b97e01000000002e1737770269f9c9040000000004ac515365a18b44010000000000a1cc41fe02d9492b03000000000000000000000000c9b25ebb913b3385ff0c34527a436949ba9243ae3969a358c526b63bbcdad59098bd40f17b821467d76d78e77126179a132940c663dcbbd45cfa967329164477b5c562944e23a09937f6769804f9d9f0f84c6984a8d8c5c09fe5236848f4562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f963e3b9e4682859011b273109da7875ec45735154edf46d9c471491def250267f8eb58a6dc649a0b9055dc713586af98d969520f3c80e100eb60e8825958d052fd780a82d66a0b4587e976e8adfebe764439e373237cfd7b0b63fdc02c6568c68adab1056dca44b0142d436bc6dae4bccdd19c022397211843fb83332e39ef803053ebd7888b7c669ac037ef309eaf207fde1b0d35f58c40ae1765e51769c18e1031f0252e645e4c50ab436bf920becc4463b2978e796c31e9912a0ccc0ba5bf1210b023b78a76c184065b0c43a1aa3054b2e6e18c157016d664ae1ee69be77547f0e9257e65a8dae016c830aa74592cf089544bfb3494a15599df9ca53db4dfc8c1b0304e6e156f0dfafdb70b295891ad4f24fd3c4dfe691411799dea4a955b2d4ef93020314ee3ac4b0b5803981427ba3b33fc63f567585e9e815c1c3be25434233a4aa022bb6a0c0464de9c0281865b220bf8dd7009be3029debb605783c8e5d56edef3e0328782b2f8de653574b38b3616d2ed0630a58d642579640520e041d234319cdf70213fd3e71dd8004829a03e096b28e26e76df98f4fee55e40a540d4d4124bd6ba4c652d01fa580d898341ebc402cc7eadc752506046b4676bdc26c5ebdc8701c2d2f739a2ad330e8d13182d833758d426c857ca1e39b5aec57ec0a40143b9de96a08fdbe55db77cf90bdadd1ea8feb0009c945c29dc46e8d7125b4388ace21453d481cf267496a822c26c52ae9e283cadebccb7f73fcd4a169cc0f1ef2d4e2dda371f7584720270c1df81286a61a16b1e9fd4c61226c295e1e4616a009e0228fb498a53166910a59b107fb55262969c8f878b97be8b3e1fba59f90f2a47f8b87c10f7c3b60b8d6159660d74e57b220dd51567919ef2c11902e7e540367533bfe1a3533be7fba3b9729d51df1de94cc492248a01edf7602e1448b5572c49a9960bcd43312313df6f4a75a9d44a74828bcc3ffa7f1b6bad180ae4da1854ea0d7d2b04e9627b7ea86dffac41f5c5fd7f690a6d744d14d37086859e36a1e0bbcf254033c3ba89a8af0878d5b02ef86e3cd155394f0e05b550c41c36765ed606fcf0fb8e3b4c93ca9977563411de035405f2f4323071ade6b2ff9efbd112f0dfb99e11b457e14488e00e56ea5e5c99d65284d96aef32f1e8453812d62b524193c169d5d8b92d93e5a02db845eb0155a5131c000e79f273bede89ac00d38017447d5d1f87107255812512d8d4641e28864df53c0653c57dcede4d326ebca532b5d6058ec80f9e113a5859be655a9fed81f9dfb16a5fd12d91ee3c0258abb228cb4bc9184c68a25706ed040a8088ddadff8bff14f39f6a74dfd303685217cdf1bc61c992bc87e6a84e71ad9ae16472ad6bc0f1bfe016139cebeb19b96205d7d8898f1394c0ecd049a53bc9faee54bdcb06c69685da355644eb427c72fad70dd163736aa9187514c3329a07464130c905b846f581f48c3bd7d728b98bb2bf78efd8e92a83cf7f7650710c513525b0bd1d32c5b08ba19d150676c65c358377c7a7452bcea4af78adb73807af8a2b8a726dc873b0f2c5938c91c109c0d565ca3c9ecad6bcb6f6f892f8aeda0db92c2d8b9c8d0651779c70980d347ad3fae0d373945f039568bfa248907637136c89fe3cc1e14a9f6f728893eaca5d8785f91e2533727b68150485037f846e9bb9a23cf8c1dbb099f475ae3587b66185765ddf4da8cb7f6f309e3840098b21e2bde9593f302e6217e0824910d0f0674c504fdd177b763e115da84687c9e579431852c1880625be09df02b77caf13256f313dec6102eb907db29a7b7effde731497c821d79846f3e770fa56ff91fc791bf3e5e0daf34d2a8daa9e24ae154d42f852c3dfc6fabd4055f8df37d80c0e5fe9cbec444c6978865679bc3ae9d00610a9f4cd42ac46ba6b621834612a8ca9dc86a48c1b32f5f81a8cf8de912eea8f7c688d0114e424597c7b58b79906e2378f5ed1b76669988278bc686bbd944baf82e45caf3b5598e738e9acb189bfe026fe52d3ba60743ad9bcdfb143e505f5a0a603a8e6c06dc214810a040182e57b767d27f7ace8e4c6165ba43b2ae69bfd1d1a21ba28bd2e621d0bd35c08b39ce1f4a085cee248f4edbc19bc6a7a43f481abcd2332f53feac47b9bce7054114da2b7b987e4fc31fef7d337516d8c3a639b439acf188c25b3910ab317ff82c07e82ace8025917d61d310b609641a944369172d41d4042a52d0372655c556f3bdfdc602e8b80c91af301e7b241685f12927ce7daf1bed70a416b2ffa03bce74eb00000000000000005237570100000000c79877c0666f08f669e7aabdaa3e64c4eea7ed3514508b7d0954e88ca8898d665e521df7b8d8833220ebf3ddea8a667ebd40c0b9bc1f2ffddd80c870b3ee96d8479b59ef8fbcc457fe1820cfa339417ab5bb5982ae75986fc04f28fd586e156c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e82e94de3c8876344543fdbcda4dae62e83f7c81b9a1bfec69d21d56248f30bff9fe2a64ec4f6e2b037ceb3f90adc53a3ee2e0496fc4fb4dab3ca94a1e5d8667b4e0589f48a521e23109f26d10d376dfa532d5ab7d49a297493f4b15c56a8e4772f25adaa14b19783737cbbe3e8c8983a2ae8c56bc59fb82b2579c62e38087e70313cac0e69135f5bf416f035b4682f0491449ebea9f84723eee58fbab1a7f787602168faecc701b5b05aa5c0b431afe071c8cc0a9cc8969a69893fc686bf0ec0bd50a07fd6d4d3e01f4a213e55bd82ec10f00c0c041c447017818aa20ca299f435e5f069befab50ca700244f3549e45705db4ddf188f7ad1a9151fee773b6c0d0631e0214d3a068f56ca127f8b89d754351d3699c87e7f76e380559ca3aaf414c16c4ce030ed4ddec54e4751b2eefda7212c4d0486ad69e9f4f2ec8a925fccec288e3e07a0311410284db2b0c955099929108f195be5c456d123c959ae059930e39f422ad2b031fce97e1cb49c1861b07f131b5b95fa789ae84dba94f0b4bdfa30d3d916f37620304d0de4612ffc06d8147799d12a68c9e25cdd0b7d6550d2e0cd96359272896030e9449af746c15f320a286e3b1c57366d56204071f8c0ed655f0900962e210b8097df4942a13d2e3a19240d4ff38def02dcbe24dfb80bb5f8932bcd467a28fc01894d0f7a1c387ef59825f3e1c361e441f863badba4fdc22bfd23c6b523277558c23633d9cfb029e0badd54d5689b9067724d7f3554da202722864d0445b4a0515ce28983ee84a2c8ea3b24396e95a085625d1e124e562f91d4b805524498a21d7235a374d836ea267f977b9ae93e7c96269ff9fcfbd73776a06476516a524eeb2c54640737c36ebe508ed6f544ef9655716fe79f8bd21ba312a0aa4c77d13b304c8a048d8c8d115727785284d6321f0e89154a02199050c8e910035d2d850d182363d47b65d3b4cd8cbe4568059beb81a2aa8e7f506f326a4f777089a5b23b8daba6aa6ad8deefbb842a4c0ca4c61288b5b2faf16ae1bb3ff592bff61cb9fe325dd7da9b5b65eb95d4b9089061266962274492bd204897b9801561e050cd8c23f0047b42dacc9f92f938d2514dea22e4025deecefdfa58493abdce704d63b7f7fdc6057e99a4004d257bad03b74936044b5ce840e8ab6607f9dd57ed6a71d1bead62fef7d5cc5d1014cead43ea121027986c066b775cbfce9a9b3d2bc76540eef59e067242672aefcedecfd8001b52c0514c31539909474a72b888b5b4893a78029d7997d42dce60a8d43b519142d69bb80f58124e6e99d993a6d02fc81d955e4f2c6d528bad3f4d28d2308f75b97f2621393cba346d3cd60f6942f9cc016bfb8f0a8d74ca921daf2e077ede21d9fe9c8283274922b6dac7a117298d71b89407dad6d57a5d578cf61aa15a02aebde171f439faf4ea18bfa6e8391dd42cfb1e1d3fc42bda46b3807f491c3f09feda0841050b90870be7fad610b105577b7a527191bdd64dc63c9f58e90b021939d0c62c9bfcc098d83aca3ff28851100ce9b845c61bcd489c1bdbf71a6e7188909bb30894f4c2228e994d7d38452090aecbc650648907f28351974831d88958fed371cfcb6073733503de3970e1edc1674fbad266f58650fed845a2182ba8696cf38392aa44bb76245c7b72f7c1434fa4bb8f0f272e39bc24f69b50963a43ee4356eda7e5604056a473cf7d0c57a2195e6944b7d8c7a039d8fc70165d131c16d05b5e7302b97af5e5ea63d72ac5277a09d382aa4e3e44432a242d6ad3220ef72ce2418ae760c0ff22a96facfc9afd34e0643a764f01d57551039eab984e8fc345f3539237072af9034082edff505f5e3f822fbcf2eb06a8b7ea5d7a4a2a11fee138dd1d0e874d3b00477a65180d84232027d08ce8a3a39f1455b4c4378d02960708c107a626be25b7524a5d4df9fce8426460fb9a62deb59180f1d49488252b1747f1cb8c7307e2962b47c9924334c3f11505ac5c7bbf9ed3a455a1751bbe750fe4361d78a343144cc65a22c3f4eeb167f19d92adc08df2df32ec503a14bb046ecf9756629f0f8a0e3ebb3bede77341c6cb3ca0f22dc0a08a8edffe8235d9c3b6f98bceb5cd12acbb6fa33651b6bdb1e6c89208d146a3f27daf51391b0d5859cb997119bb6389adeeea32747d51e89ffc94d61b4cb78e0f3eb78fe9b5a42edb43603844c534a5f9a45c701ab1935489e0d23bffb7977a354c1aff2319d612756dc5fee70c94c06637baa5c321cd5dda4c9e5aea3e33e1ecabca99f630f0c6946a333be4b67567d574a4cc38f96abb1a73746efcf18a3b3ac2e3d99742cf963b5804f75dc32b2fcaf44e14688d06914c0a7c15a968fe3e2b16081e562852b7a395519df2f3f6cb59a3de5c129129b2b81988aec05e3992873b00fb00d6e3a7efb8e07365801", "0051", 0, -1287531766, 1537743641, "6f9f56cc0ac3e5bc08e74462812c44a3c79f018112bf595c07e2227373a0cbcd"], + ["030000807082c403011660a7710175e9a0d31a7b9877f11458fb114329f1cb7df9048dae420e20827d0100000009ac53656a5363515251c0344c8203715e2a000000000003000053953a5b05000000000453526a001c649300000000000000000000ae61f70c00", "52ac65", 0, -820935966, 0, "751050cc7c36327938342b9f74fdcaa543e3329478a204ab8236a32e300268f9"], + ["030000807082c40301891d995541c87f2d520ab4ab3aef31effc9ebf9aa565ea5ac9f2999aa7ca6e2102000000025100751ebc2901b0685e0200000000005cf506dd0cbb371d01b8e642010000000000000000000000009531e6643b109ace6240f98db2b1411eb30303c68243f560a56c76b6b2ca539463eda939325a7d58a02b2277d12234147b4a5592cc051f3a7eff4cbe85c838780b4c6d8c2d6240cc4dc68ceb3f12193da36ff25a1e0c8fea11576b940de3085800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000538354a1317914ca1e1aba8aefcf26d2da30ea576432f07b41a404cb6afa2c11b08725f3a32b23424970f5a82ef38d5060bb4e8e5156ea19db8d0cf956d765cd7cc4cdaf452ab170b5b64d347546279b2f9d0e1c5fcf3a3f63a2d48d28a08253f90b774349d7c0144cf23ed4c327ca1348d4abe04617e18efbdebc00970f534e020b38ce41cc8bdc1996ca0ee3e7cce194bb89f14e10d5a2e8268ef9132a540c970220bb6fbb3e17d72e4ead9ccae59fd10cdd2051a9aabe77be0a8a41201f4288b90b04579ebf75a68c1fc0c371d4cc10327284ccf9bf526d02dabb6fc30b7090493572d0b99b07261941bb6eeae66c77393da6dfa8866c1a4cf01da3e1a602e28ef00212af90aefa2733a3758ddfccd70ec73e97e1e6f125115f99b461450dc3b79d26022d748a098eb6d32118cdb4b5d6d8a1b9f09714beedbb76b7b625b7daf206aea50307a00886142a59abe4bc61057838ac46c5f89b8b278388a75608ee84c6194906020893635d404ee13574dcf167ae07dba0bf4de9c5eb7cb0633e799f33cfa5dc9c0217eb08f524017bfb7f143f2122f2c06fb469f4f80fdfafbc6336f3a38b1c21a55effb00d484ae472a115c3e5c2e59f78989ef246b7c77166655cdc7d78bb73bce2f26228dfd756a6356e95f399baaa69a9743be03e36000d9f6daa05c23e1e9f4750702f099868c16ed8e68f8a28063cb2bb7b506a596a4ec5ace6fe4777ff40b3470ccd450a0b006bb0901596f833a02c8239ac989b25ddecf8893a1ace0a199d587cabdf420b630cac8d5006f4fe5e8be09f1309dc55991ce6720699e3b4cdf262645410831b297f5d75c69315e8223637ce15322f27fa4c454534f39cb5053fd1db28acd7995a4df9029391aa43ebe5f4662ef6cc19858a352a18aedcb9f7cba5e5d4ada325fba03642514b08ce0c263b99e6edb8bb37b3bf37820efe1a53fe404c223884f5b829f605ccec2c557beb4541a8a0ed5a96b92dce6633ec60a075aa0e245b1ed8b671493d9cf664a568222b28d7d709392cc564325f36289709983172dcf7a46f42c2da59170179f7b4862fe9df200112fed63f16464b3c0f755f8bc14db8deaf579d3179ebdca6b6496e14087cc0aa905f5f0aac1df341438352f7786153d6139a4eb280a532fb7bff46abe341f07320a7f42534774cd33e1f160599c01b60e510195d205b0769f7bde87524d5eb77a1e4ceaeb0bd73eab70dead45ad0826e9732260c1ef8834a4b96ebcc64dcc905e60d23727fe918648e21c09ebf1cb2219ef9210b7591913a65e8233455885218fde73552b8d2543473c9355f15739a5a0b6093959b6a82fec2f8a968168187ebc7612df5e15689fb21a04fedf0118d74d5edf6bddb9d5e9a144131138375a4eba86bdc5d913bec9b9b4c3e25f254c97564c013eb706ea6e7971375c8d25e09af6e6019cbc708b745ffd474ced9f70f7922d3b5a5bf2f51d93d93f7da4f843b498485915c89173ea58ac8ad8ea061c695647f8fedeadc0e9cd1ec5b6ee56efc640daa81468272e253d50c23885b08707611a5d9ec68dbf01a71a9a2eb7c339ed7d6b902ce8ac99a662344b68a4d7020ea9ab381e0273b842311cb7a62597cc58b58b712c55ed55208901607c87d2334b6e735fdaedf3beff96d72ac68f72a8bc47af542c2deed83123f7d2dbf65b6ecdafc02564334643bc3589ef82cc235113a9b09236ea92f5e9a2ba9a5731ddfc35ce9a32c1ca08b34a9162440ad2509677e4cd92a05a56794e144266be99934e73b7b8b387b035b8b54ca83ec200e162f8a7ef5b699c76e1f01ac844d5a8a32ed087fa15826250db9184dd64bc0dd961da06622f11f8393cddca8b16f9b5adf55d232f89c5b213d4913466f119b3d92baf4e12023e7bbf42b848a3b17085b82b20c2cf7632392ff0a9fa88a960578be8265031377961e981cf140fa509cebcc6bf91be66719d9e3d1a55deff223187706dfc9de7780883e89e3eeaaea8ed2f79143760ffb0d4beea9bf771e6cfde3af10d1786af38a559fb3811b80033c1e6ff60e24e27cd97802f9c20efedc485eddee04f306b478f4e6c79b1ccff16fc6592dac31852f20c5f09ad2df17f9fc75081fc413cead24b7ef46a72c966d6c1abdf47ed9aaf96f786072583df36709de4cbdd0e85d8d30f3ec3fefac7617a82b3ebab1f53e574dc11546236c44f70e07d1995f20f4f227f79a4342543f274977438ba0fee06c65917f31b5c37cdb5e2f0ee42b0541e4415e25cbab030a5a0dd3d96955026ef89d68cb20eab294e0b2eb4e0baff3fafc8dcc4a01675a91777e6183d8c472ee78baf3048e7cc01785800f91d699e90daaefb9f00c6d74d851b9bdf940665cdf132bd714aa0ca60b2c03d90a785a1ba9b93f3448ede6f5703ec9b395ea52c7aba4ffb1af8b44b1317803", "0051ac", 0, -1086482984, 1537743641, "e1051f93a238142d4b2736ed77aa663dea781cdf81d1eff7db7fe9248b1b9498"], + ["030000807082c4030205f4513f3256bcbffc4b2babf96677f05f530d334ea5aeef8ce3ecba8a65500302000000095151516552535265638b910512704066fe9269da3f475d801f5334aa61bae50ba5df1f549f74f9f78c0e95e4ad010000000165c9842b120151154800000000000800ac6563ac515151f9e8b05200000000030000000000000000625ed50400000000780636aef158605d7e18f60fb5cb9dd712fb31ae5d5a4992777cc272ab2b58fda3cd1798b8a2049e499f3a4eca650fd0527a14330f5552824c9381cd318582b1336c171b5291c247cb58381b1c015c891d2065ccce128e1603811c490952e96500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cbbe0d47c06b70e8d12e319da10849d49bfdf4c2d231941f1bc774e55e8f607cfb459c0103d54d75787c5316117bad75dbda6debde4d6853d03a54f9f7d7c6b9db8fa07a22f0c2609d261d67a23d6f5d3492d421a5b29eff6007704df70a612367f5762012c8f0d1efa5664a474fe46c4750f85d93d56de24f5fb7fddd8b4d83031f3f4fb8ffc4c5823f7ba63760729e8abc920a4bfb0c45b18193a5c726aa82d3022f30641383f1713fda3ddbe37c29bfff2d534553ae3536ae364e74db608b7e2f0b00f68f6c7283936c1d017bae86151df98ee38787b34d770dbefd457c2a743a966ed45b7ded0ab3800dc7eac27b008b218c9af22733bfb718ea5a9f063ac63240020a1bf2e9832c0a12c33315806ed6b550cb16c97854ea9037b9fe912ca1c155050202644bc964865f008bd7aee63a5d8d46b015fbe6284af241576e3357daf1c7d102253e62a6a7f2bd87977c870617d17e890dda9f12f3d7fa5e203236bac14eb6aa02111c39d4f2b08f7a977cf0e9a0e48fb98b92beb57514a9c98f28d607acd31e110302c9d2e2712a2b29d54f630d157ebac0ee4e4be288aaec931cf2ecf29da34e10d338fe45bcfa46da012d4cae9b2b132491e4765acf0c54c11019347cc76d8e9e2565314658e41bb85c70545b3b565aebd7c2840750b2f703353cb68f01a2c8bad339988dfbae8790125353e9ace5f2694ed0cb9b857d83b896920426c63cb570ccfac39c1ca4248e4d0b3afb48dec0c8b73342dae3edddd452ca1dc868f975a29750a739470927400b8f7d4d1550b8f30f6da86f3ffaf200ef805b6c9735d208ddaacfdda04a152c52844f64200bdded3c576fc2b9adaea9061003884647425b3c71af3e3e9bea2b7ca610e3cb9112d8adc80ee8eb2a16e48fab323c4984d20a392e47065710748ae9c4e8a8b4c7ad67c8df75e99491e5eba1d1d25dbb00629739c1e5ab9a6d113412eedc0fe25f90fa480422b3d1c62fa6c510818a63a59ee263be3c0498ad234e787eb0ecb5895fe5fc223107ce0e4d156f570bdef566c6a3db8871095f00543546178bcd809587d5bbbfca369d4a413f18748690c1195385758f050b3df208c32ce6a63d0650d2304507fdc3ec2a819d229b366b2b7b03c374fcc728b017334d926d7e2196e78b119e933f40a1f83efc9da5a0f1299d15016605837f75d25afdd8a653ca59ce17c5a614b549997591df2b1cd729e544ea8059df97b3450114ed524fc22716991b1a54ce96fed8fc3aee7b10e3a593c54e4dbbdf9df3c09b88b66c23f5bfeff2a09147b1fd1e41bc5e2d5f76abc4182142e84bc074558d1f24e0635c5f7e25ef7691c57805a911c7a0ac357c01d652cb633e4de9e40cefdd4208027d2aa9a5fce6e64d01a0f14e35d7a0acb4a8e964620503178f5f5c1c0bc82841729fec411aca5ba7fbd195b24d3a8d6eb84f99dad6b5cab5e9b387a77e27f07db50f5ee79fc659c9b7fa2dd57eb0c625a8a7925aa2f0a9e027ec5fbc4ed103f4a9871a177a468889ca03d03427df09260e541d83f971c58eb52362646d6ed60d2674b7e5c9266ce957605158e258b8e6069e99f97c0a80a44e501cc36c172e8d6907b9bcea8c119d18bdb6e4da4d01fd76988ac4f60c15f9e19e2c1b4c6bc95e86e79ac10bd8d49c29620272bd904c9bddf84e76287c296bf97bcb4c04bcc317e566de80a9bf70a26812bafcbfbaf3ecd525c0f82ce190f537150c4ad25a0f9e806eed52eef03545ff35b617a46d35cd48f7a749e7c050d0073d8aed1fbcb7ec1035517bbb82f682892a3753c08cf4842c297bb065fd57be150c6dddfe2d6dadf350eb64b255c393a4bcae395de0e6bb2c75d872cf4bfd3df866583d09e749ac330214bdce853cf44e457958cc3a257c0d5902bac5394fc9627ea617278473b84978be15a3a845711501c05c15dc5a86b91438697e0b92687c28887d1ed887014366b7a0a6a5ed8068d206d899a534f7300a64a1c0b21f26cf7a929cca6401143bf6e66e5adb4bf9ce97cfa2089a1b88734b5574737aaceae0a69f8d9632ae057c62a846560e3b3ae2d616cedb873286a12cee9b44326ef9fb5f64b482100d1db8c74868c4657c3723ca664673a51e6282c042f45c87cd795c115d236c00be4863897265b6e9d7070ddf514b10d1c60c886754f358d8a3be82c1afa797e5ecad33c3158f1015834b524ee6f5a4204d3a7647080c687b752ad8781bbdfae850a73cdeb7e797ca797e16795ee28a65ac7aedc04136f7e672deefdd5667f8a6fc040fa738c0b925b6ad1a7495810500000000000000000000000004e1f0585c024114c9fa95e83e10cfebbf2ca3e9b841e4ef8b69d4e07a1487dd0b23e045cc630462f78a44b1bcc6d4ae5eee07641b558144da6cc047abe656a8091eb6c0c1f8346e386047c847f07e61e6e77bc00de4df9ceb6778cb9ad69b3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000aee0b064970f61078053807f9ff9c510afcbf75458e93e89c3fd0447a4ff2e301cd1e38b59155364253df80751bc1cc3f9f1a6817f347fe357a4552a95fe5ed4aece30900ba35aa535ad03446edb30ccbe57911052dfca1508645c097f3629fdcedddbff28cc054e293340056441d5c76aaf6fdb0960e03bd6b75b829d14d7480319b86e6948012c4d3f48c13a2bf38189191cdace198716b19ccd4604ca0b8e77021e0ac48cb9f4df8218a894501dc5283a0e6ba5665db461ecc2d3e8b2a470bbb10b0796dd1d9030abf402c9e462c8ee6e3f1bbb67b915c8845adfeb26236798b6dce7d52315e457398c0981a58a4a5ce71bd538ebc99299ab7817b9449c48220c0b032c95dc4bde6af4798f9a847e9df259887c021d268ea9fa0ffec690b6e54f6340031324e1c7360d67c47e3f9c06f850bf0b70d02f6e47c7f85000d77a6d08d2b07003032e3341bf56488aab0f23ea10b4f25d5ca536a1d057b07f1d4492b4c2665f520321e77e479f33427c7f459733020761232b4bf72693c413a540b7420529aff2ab0303d8d331183f4e0c8be8563deb4af2c834506ff2016d2de0717eea6b8c4e5f3ec4de04d0f983c0b4b741f520c8a78bad038959d8f7a7714ae7e5ed4fe85fda0262660fecde2211bb71fe37660505bb068f3e3b9f5a2ba2dd0c0c4a3725fb36bf432e11d08e5c6ff98f0d3889cf75fb770a33967979dd20d6055f8de24d097ae11628e359e1c8eb1fc1f8a2a9527e460771f1ff6f87ca90d6e2055aa53e9f35ce8d6fcdfc2d17a433ac8b3caf242bc4275eb581baa9ed3131a9a5b2bf7b35780bdbc0da8850739322283c5374f83c8814985762a2ea169b591a029ef1d517717e3c1313ec478bf9da827411f24983e79b527c966d723d4a733e3e0330cb33088accb5117d32108982035b3e3e91c509428b7655a9a3d4fa5ebaf8a494a98d1eec6774b79cd8400a211b2244e1162405d20ef1d32afab331d35b1113fe90b6cb904ac4156dcf2b7af866c5a57b758ac0f4d3417ca817772327132aeb6a043278fa8cfc61ab7a822b5ef14567ab5e0db148f054305e2501d0209166195c3a66e22fc0272e1e587b4bce5275904786678a156377ad800e8a60b952a1c85adc37f7271a4587d6813db173ca5137539fe2584c4bbcadd64879f4f9c4932c548f9b64257bf9cc199b734725b739a1e1ca431e53f1a5a7436581d2404b3f708ac231e8eb99463bdb3f349e996d68c180d94b023c20842512ab103811c10be628c30ceb67a81012fc51234581808720f7f34eae2b378243a6d56b23e905978ee6f122d117ac13700e1e9ba5b9eed8ff4b4607a9d9924ff9bed6957cccff8371e2baa7fa3698af52205b775d28ca59229c25517486ed31e1287e3de0df4ec5080017ce5f9146e4d06c8da314788f4493e34b8a189668fb0c27eeef4dda30a9f5d7421f9f67d284de91636960ef395bfed887b3c4ff86791db64205e490d02fd589d9ff7ca90441b7b3a2404bdb524475e56dc717b8b7d46a025e1de6144492d061d495f8a7944f7d91c08d019417ecb7272cabe536893a1626656ac81b9955771a7b4f93ee2799eb58f582bdfe0c60d293ef12249fc39cc0f480a5da2293b3952d61cec9a2667b505015a92da1111d12791576e1a8e9d40f5929a5f889abf83eab057acc990e8ede90741f30da49fa385da1504d71b5bed4d75059b124a19789cbc4f6d63f17842619231008916a9f3670a5c6fac94ec0215d880a9aae16fce0b32f324cad069ebfb947c4f5dff485a3e2ac48ae9d757e4bd5f1a1da0ba26f3a0ea6008f5143bccaa004d7bffdf41627661ae134f6e0da0d9ab55f66df3f96c99ee617a2a57e09ddd482e2d0f9b4dfe1fef00ccaede67f99bff8305ab0090e8ea2b723e258a5e14ae8ed96693d729fd7a53da688e691fc5fd9bf0cb9590481387394e69d04be18baf9a984657ee1588b445b23df3c491308c149f2c908c9dfe0029fd4c030cbf68267f72ae6e935dfcbd6a3e83c7ef73e5d13f94bd6b9ffd284791b66513835eef075972d1eca11a6cb4ac7cd263edf0ddb0170370d3c9eeb93548d2cec1ccc34554dc41dd31fcab017bf487f3c8b1510732fdf999a8816caef3c95ed10f16f487ef73444d6a033d19800fca9c57a376105de84571ae8bd25f84969969ad1c8bd41031b3505c0215388f27c6d2f531625e851738f990aed83601c7cab96ac544bd24ae5736348c857e13c2c278fe72d5b1d975f40f35aa8d81d8a25a1540a03a2aaea52b63b476b3e1c0cfd97c65d41c000000000000000003e95640100000000b7bc3afb71be0774d4a857fd28c854eccedec53bda6fb70f60128daf6a5dfb917e58e3e4885b00468938b49f9e5be7b279008db9c7da3c42a9373d0c8a612b83e857dd5e59d2288e178b1f39048b923e292d08821b9b08ee8c29d9f6a9c2ba560000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074f29cb26cf064e4a2a684e757f9e18ba13f16b75332b6679a2a24f3e8ac9c6331f1d9ca7b0197cd35d7ab1346e6f5885bda73beec257c37100758e10dadfa57ba0e342c530ab9b10d000f20ef154b18cf9d3938cdf4a64f1b2e529daf4e91142fb8d9aaaeced3bb584d93d87cf8a1cec9f8075064c8dd5c26ba7f992c646a0e0219b2b519a4d09d7759d873a67dc65a3cfe8f97963c2a02be6624942bdb162ed0021e7d293bb6d2ae4797d3acc890ecd02d8e403a3139d2ad07aa4dc954a98683e00a01c2baa45c05a4c82d859f8783fdf8f5f2f996dc7e04617ad7aac014b49c5c337a6d47e19c013f46a6dc52a033f5f8c2817028fddcfb1ccd4804815587405c30020626548614218cb197c1e54703724eb54324171b1b52e57dcf533ca482fbce14031aad64e357960084c14bde4e043033f83049be8650ad7e4d582207ae575eece1020f879d290698df37f6db02c46dc601e163a4a8598c8bf31b5654d58e8b2ff74703200f13bf887cfb8c684f9e9c2f4b2a855ea4fcac9d24759d12b98c3165b739280209df4602aa6e54780a843b2c49618146abb61e623fb6b40a33ddc0721b84960ee94b937ddc816a6ed44f9984fae8037945eb41729c1f8c6ae22436b53177b80b21a36013b17ed4560c8452e0cf0cf05136687f4157b2a2711743f4c6686ec61d578b17548c34dca84cbf94ab58345ff2adeb47c5021db70059274124ae89918aba009115393ef6046bd6d45a442536f15c7a150efb98edc9874ee766855737e9c6006c679c24a015a3fc33dde6dddda3412b281b85118540c7b913ef902d7c1f2d69289ffcca7b274b9066ca67775a2b698eb524dc289bae35b3b92ba491d684cefa5b829e2943544e9eedc00e7297e27262c8738b67939a03b29a30b8ca375d8a393e2807d9e8bd43ace544ca27e859cbe3f5b76674a09a33eae62241e6c1c15c90768781e6c142ae204077da5d3b0bb5fa188ba00a594ba0b013baeb94c99009057870a3bf23792b72942069173ea00b2ef19ecb20fbf2b6a2d5e28f4e88923c041fc134e892e5b7838220b146c46acc85e1280c20c45b14ee317f87483fd17b6b3a4a4be2f46083cc338f20a83d5589bd282c0a27cccb28c04d95863915db130f8b5776915d31df62e83aa2bf8676495b7a8aa247232d2e081482f7b32333afaa4c5f84617e08f10fa3416b8c563a72091ec91a19cf45a2d6dc185e988189c9537dbc068873eb36359834c0ebc900b6317dfced8aa15fcaf642192807e4626813b2b0a4353b14e8c87baf3dead2b5d29d8ef7c1f2bcd9ade30827e4c79972ba2bfd360ab397df35c3f828629864a120655bb2fec9802dbc18806b4b79b2a46f3c2799796906276edd82dcb16e8c604b3c3772e8cce217547c3b8eff0cd4cad1f14ad72acedbc4e6b93333fe894af554460cae190c5ad29c36dadd6f6ee172ba67c8c3828c86ef8b1ba8b6b372b2339c0d1cf7ee5cd263680f6fba4a5229c24c318c2cc2647e0a4f4e805cb0e97e99495b9b624dc1f06cb8c8fdc874128b1c7c4eafd7ab29abd767baebb315726e27d71b9d81fce17ae38ba1cc1d2aba1c122e9b5a5e786fddeb88898b9ed3b544d6fe668ef59c1f5b286c9cc3e456ed25775d6c029cee9a78ae71ba9b190ff78ca3c7a411971c14308989343ba71e3110f9602cbe6f8e1a53998572a13051355ef520147ff9296cf34b1e705084ad7526c51b7116c8b70e70cbe03f2c837529c3091efdf2362ab8fea9575b9fe1e8443638e05681e48b70e7a4c5c52f611f4de6bc754fdf42e11722913d8e730a1ef1d45a724e3ed1b68ea619df998529d1af464ef8e84815a2df06f068dac368449546beec2b6497e283009cb952876fe13649f3b76810274ba3f24a5c7ab02b6fd4fc92aa45d12f428466b667fb7a742370a5798d767367b403c09b4f3b5c68b291519ee189dea7e8e110e6d213cbb06c1fcfeff9b524ef37fe9da134a6d9ac724cef54d8964ce686c9071cf85fe8cd50b45e7f4d93c0dd55581713dff5ff273769257223876003ee173693dd9cd75814209eff8c9da9633b892886f4980a841d35cb3d0b894220f837462f078ac520eaa0990b279895dfdb34363b6a263b1f8961ec99f27ee69d4acdb3ee74c3eab597e9cb992f9cac95af4d11423c8a2bd3abe14a6be7bf9da017924c3c560a94a9319e0d937042969fa2d172c3688f7a7f4dc5a3a909bfdbd4cbbc5686d28e97ceb32e1bb7296fd9d94f308f1cea5388f8e820288514ffcf4166253f255dd7787b713d8affc2e6b92e96724ae1c5ed12154df740165182ac07a8c335bda8fcc7d45bee636656936390d4c2546980548e2464bcfd2d695e60c4c326b01772bc2d3eebb3fbfa4774a9f19fc394e4609982cd324732ae1075f690b388aabfea563812b9470bfba70c", "5265636aac5152516a", 0, -166871512, 0, "d007e9a6b53bbd86013b3a3704d2597c5990bda0b59b8a3c46704b4ae67d06fc"], + ["e1dd5255034b8e46fecf433eb9def3b807343771a7e8f53e5c949de1a98fff515230fcefc201000000006afeb88005a8a77de577176cd2c5d34b3736cf267156e4d7749d5635ed3d14ffb6e4909e010000000563536a6300f48dfc22e562c18f49569f47b5b17394002844af4cf5c0e07da887313e632d190c60bf14020000000552ac526a51c4343b430184eef00100000000025165de02001803e701a105000000000000000000000000cc7851191685299b2e12e347bca8c63d13d87b39e8b5968502c476d7cc48225537dcb57f977f461f902dc85fca19058b1ffda01fa65fbc670a33dacdb0e3cb42619491e91cd2692228bff2a2cc9aa3e44ba57becc5e80300818fa717a49f9bc700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b04ce49e8f798fa95c54062014ea5e3400918558b8b33b300412bf06e1d81057fb37c84409d4ad2106a137885183751772324b43ac21770d94147babfb179f37cdfcb6aa4f46e32d2e90fb1cfbc82e5a763d95cb1984ea9a3705d42c692024059fa0965aed922081513fe8bd41fba1a53c342475770f246374b37a0f0605aa43030e2a3e88fa1d9f92a8d900a6b68a5d2bc28c526af3ccb6577c09a19543d8f4b0022d87a022c6370917ceaf50b68bb789c144e9af816c55efc0f390a119dd3d55430b081bb2e5b8491de7e32d710d78ab666c832e648494f4508f53828f7a80e259e40caf75a0e1f5cb9b0f2f641eb48a78eebf158bfcf7225754cc3aea7e0e7dba150221f386fc625c0f5dae87a3d036851eeb345f54875b317fbf57457e9fd64dc17c03140298a5790b0b5f3433a1194ea09b4f1f057f5b9de4855db8ab9463eb1fa3a403035ed03ea1c83d34e0401d888c761e8559f0b94540f68891989e51cc9061b04a030fb37d744a42db8db729f9dceb8a6ad5f82ba111b4a48f104f6f81270d6a1bef031f080e2a9bd45afee2d659238235793d3cf057e02c4a549421fa74aabfe5f756a9a9e59699f66ceaf08572f18076504b64ac61a918c7569c44f87d674299fe5059949a88427c2ebcd40ca5dc872c7d6dbe7d3245b9d557ac80379d540425792ac5b7b028f6ddd3a75387b4466d19301f47cac324a98edf256c0280b61bfcca5bef61346e5780c68587d1185fc7113411b9d0940bb496918657d9079e62787b68c10a4e70a0749ae002127551f66561d2478993c3af3636e2592f40e9bc28ddd8c9f4c286f41989ef47b10dc802e35c6edda5c41175d9d3ea983b3fefc96adf3f450603fc35ea8e62dc56683478b187085fae730de68624c804efe1ff61cb09ec04594adc082e7b62f372398478955cd192b806bf4f904a5e928cdcbd7c3e5e8d2f491b61128297ace9df756335ec4642b40360c16d8bf3e5de1afd7a1b7d70b3f751a116a1fde2c88357e75d42a78ee6417e9e12ede76417edefae8f10c4de7e17421fd567a9dd4b9cc06061c08f5c31acc720f94641dd4e5da381a80aeffcfffde767d98a9f107881a740803b37f1738a189e75e557edfc75a3048a3fd220fc0f2ce8f9d543d3825d2a8002657dedd553aa2178201d12076621ed6faae0cae624aea1ac8ec48738ffd4adabb1b8a3220494e0185292e82957dbf6e3f747add0f71bde0a1389e4c90c2448f79f2145979749811438ff016aba83e690b6996a16c9189559c1261d6bac4c35330cd914afd59b10a72c4995264340dcb1f05c1adad70900d201ea00bea3c268722806ed1e44a4df339d8e0289f1073e6d5d44a039b435b1b1c44c476ce7110a83ddbaa5d497aa3daacfb3f166bafbcf614e953779a7a8829f25a8baf61e5026dc231237d3e3d1e96769a99807b53251736685a4812d06c22630a1f2e2319045c2c1da10058873953d3ffe794297230087a4795b562773e273cc1974dd697e081040868495fae61dc4561e363618e951c3827850e09ef33fe0db807b48d16ed45ddacb85f1d7eae7bd5ed0ea8be873e0942a43846112b8982cfd9735675e40417874b0e6acf02ba87626c04701d8d5688ed49a95f2706a5ac0aaad1f3becb2f6f879ed322571b5e66e6c994d7051de55f1558e1f51b8ee75f375c257d35b0b5abbddeba5f2031d29086c87faedfb78a2d9095757feedb0d47224c88807b80588b16ea9a8c6ac0b72064b5c7a7cecf8e0498986ff0513e3b0adcbebe1c7b4afdb5501eab4dfdb4e453db862b2dc330e1fb4d0c8edbe0ad88c95a4009f9c625434a4f815ebfcd5dc687d80e05af535ad5cacf938a370a5551714786bdbec85a24464218a88ab47240fa0f2358928f3c8067fa16cc2c1bc3e403e7dfdd36090001dae6c87c3c1d6b1481e27289ce5225069331f0c03c45ac5f3d495dd767109e531888ecaabc4f03eca2aba5e7bba68f20c8daa3dd709e34e6f359a293da5506fe130fb50e5b7a1519efe4df459f7632f90bae4758c501c56a1f6b0f7f160c6a6550542e824197a987d7ffd0cc1ac1af8875e7ac9d7ba4f7341a58d7957b92407201695e2f280d850de6784eb8481513fd3e4e1fa0c181c0fbd480c2d83f589764664d9a9dbc71d11c4c680e111ee8d35527ed1695892883ff4ab9d3cb5d0de932ce7845bc8f3c3d3b573692d218d9c23322187e193e1c35d5ee61441716299a66c45ff1c9c0d35e75dac09fee285fa17a182b81b4effbfb29d668188a8ca4077822200cf1f9bf5f6ae9f7b020000000000000000000000008229220086948d05b9c51cc53851ce99ffcc9b93f8769c9e20a2a380b7db437e5696ddf4813df400f12d528e4f615ddb17974433819f072954c4ac383b0fd6510f35f7a30352cb9aa0efe6bfd34e0d29f27866746f7f5ef2aaaa25fe38dd435d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eb9540cb2c523ca23ffbea48233e5369cde1714e977aec1b6b0ac4fef21164076e2be0b8260062dcd4a4e1dc56aa9605aaee9ca0593e138f9e37d0449575deaaef70d56734abe12835d0878575f358d54c44b0149fcf8f48c56c022b116900f05302b950b4b70f1c33b7ce046506dc46f54086554358dbe8e5472a11c9589f9d021d4b885050c0d2e4e2a61a6853f3080c6845d75e53470f0c023827616931e172022a4b168d25ea1b4d27cd78f7e552a86acd7fe1dfccbf4fa223c71d51f5ef73250a074d547715f1d2489aba793db650870d19c0bfda598943c757eea9f4773b185bf5c575038b1f017817af120795b0c8110a89db9e7e7888a63daec6ec515d2d9f0223a36df293999f77a142c3dc761379422820a64bddd843849e63b56c5a5051f3030988a48a4090217f3acc34904b7ee89b781db9bed40bc1bc7278a8067551a67e03029b57da239364788da28bd6cf6022412505838b7a57887524d17d8b22e34e360301d5a38cf0a9797e6d30ae05a6e5ee4273b56598654f6617977b23f761d955e203249729835ae17ba365608621672eb52ab21c4cabddc6698877ff31778a0a7881fd3e9e7cb0b5a6155c0398c0340c7c02b82e18815d5d15089ad6f0d1d33cc54862624b4184a0106c48298c326e971c9be5204b0d301d3c8726b3ba44c9eda6415a6411337eb47a11ef546f9ac61b23f4d100ce6fde176f2c760795d3bbd99e8b4551ee08c0d9556bd061a3c17c1e2a62c8be7b2e4c50cd679a9c1e0bdae993afd73bdbfdc1daa54840f80ea3f77ed55c98992950770644e3702b597d7e95cccf771ce18d9acc9194de219aa7f3dbf10c863b5ba60bd0a670f962771760a0b08e9893368cabdc758a1125434a1fa0b3a43813fee10c7fe725feb032d155fa05ff8ed14a3822217a6222745c1329b8521859c21a8909e4e1d31002d6910095d24a90a26c01dbc13801dd4dbdf97dd8c659773685bec51b1bb90f1052f34c59e1560a6e54bd4336d573814dc413f32ddf8619458f0b6cc33565ba51b98e29a8343a9eab469c331199bc567aa0c93ce0ed4bbff952f922511b1739d39571820feb62d29ee1db24f86dbbd90d50b9c328c93fc4c3ab0849e7881841754a70c2baf171c3a760bb71c61014ca29385fef5d18a3a1d5791c9d44164f8af98189df3d29854da5de7e404419b84b288b3275608f37fb1951c81eb6857961afadf58812ae43b4bdba25332b4f0ee7b1a09cf7c05a722227692aa623e4a58332fe6105a7e137ddf375dde1d37d72aa8a295d8172695fc05385cb3e8e3cef3e0dc342723941fccdb4cc973337a5e3076d8b4aaf9388b96c9e473a3bce95d1dda83ee2e2dd2423f10f93cb771c75e23e01874d1cd809f75aa16535db4d5b7ac25f1d0f6b6ad80f8b607659bf87274e0f33e2af27c25a3658599f7ccc886c6de2850a97fc06e4faff37b29ec7b77239554ebffe9e12455bb1c20ce18ce06151705fc389206dff5a653944148d5b3fab22ba62a9a9051dfa42607edc9fc84a702f05878db2b985c34391d4bdd24587da42de31cd91483df2702cb006650a205577f0a69b9d65851be7642be1ba804ceea1ffb7bc94e85f185eff5290e5f494471fccb46c9963f7685f8fbd3309e2ef1617e498bf47224c3b0da8e26236cd0655513224199e942101ec7ca7fa47e8dcf293307507b40409899c39613a299997408e41e912024b9aa86ee1249d7dd7d472217c2a5c271ee01969a24e94894d5861e8d02592781e951d0437dfc1a18a2d6679d773fb794ea92fec1e37154f62314bd50b6315fcea262317a45f023a26480aea0602a8b16c11950ba53eacf4dc3d823c5512587ae61f96420685ff19b5538edabc51983b0093050f669b9b9db3052dd27887c5bec1a0b75b1ce7dadaf87eeede8e2f706a3e0c3405ce721e5819476b693809f075ab0afd5302be11cbff2ce06f5d433ada522b53d915a0450860f6d624a6e5e16ee2e710047b590360f167c4d8dbbfed5f828357900800b66cfee6792c67b53bb326a3cce1fa583127f0a776130d1a04f6093fc0c4b688f7d8dc4f95c9cd060a81b58c69f02278b0271b0e3810579904c9b5af2b87272d16fd8199bbfe8480143615fad301b176cf7fb0da8ce5c5e84d2fb134b0c9eaa18ee7c03ed7d40c1a8f21b532ebe74b0a60f99073b2fbd612c92fb1cf97a72e0453ddbe45b51a9bbc7a65b715fbe6520d7013c6407b9b82c313c65d46bbbb811eccb9569dd6d8232892c8d1cacb55874fcd8dffca466c903c95df4cc6926820000000000000000015a10d0000000000e4315bcaefb2576201e1132caca229c4ad07850f9527eb1ba9623a8ac402696bcf85291c54749a38dcda39dcfdf3724582627803c9cd5a04bce067017574854fc5cab424ff79ae1a76a23e561b5a7a26ec8bd19229f514825ec2423d7c6916fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014280146da999313aacc9b9cdc9122731ca100822af7fc308c16866143c3f89b44d8d6c4a804b007f0e2a844b28c29a62e787cd246622dbedf4d1a9b79fb839711b67380727759f3bd3a75af156548e527774c727a5833f7e6466c8308a77269315c8371f91fed0677554a824342bbd3e1ac2c6a45a457361e6c560668cda5cc023023b2100d24e827bd1330b63a0e98fed36419ed487d316da42d82b2bbf00d1e0312d7a4b4d3431a4859f3d54d3ccad1b7901e17f2844b1f118d1779daf4bc960c0b025ad096688d09d3e2e8d57a8e1f614bd42a1a8ee454f1271a675074afadadb0ba65403f34c21cc56af48fe7dde2155b5194e4823cda6eac58f054fe8a752800022927f6f057db932ed9ea644fa5fb9636ce953726f5e130c1f1e7b4328d01ff250227cfe883d73eb83cb91764dd37b8df88de1861ef9dd955f36f056d2fd5ab2ebf020bbe1341bdfe2bb53d6317eb6050dcd4f03bc631a574b14e044fcf09c30df038022d9033d52ae9f0811feca7cf548b64af18f90c5a399449c987b96144d20e9b36030504e84a83514dcbc4cb034297d9c2af4de1958fe081440eb0034a29da31b283dcc23fad7a3308e71325ecf06da44e6a70b0dbb872c26760ec56c03b490c07b89210ae225d32ff7a0a0989c1c036f76280023455b60430bbfe90129ef8079e0b31a4453ad49b6dd6a3ca21277aa9e59fe87e43fd4d09ed44d8d1d16cb7d70a12d4b9a669410ca7bdc29a4acd1f8b9214f98519f4ddf57fd87339c1d00c567109159c35ac42d8f81d1708e665956eb11f980ecdf29cd8a4785d585dd681cec08521c2dd1529612ce9bd1cf03b5260175793dce905e6ec72006163f672d11cb260f1fb4921217c5efcd010c30b4d6618bf8a72266847d9b0e7b6747777d07a14029f8638996367ceaf68d8463f8929fb62288192486b0ffdbb7106a4ca50873197cbd9802394dcb225287c328d7b8a9a56460511fb92457aca190248c8667586b6cc4a49228150494b5682b8035efca9db5303bfa97d6845cc56f746b9280d6dd5e86564aec6e2da2a4435b684d46669ca84b414c51a06e0a958608d74d7eaa96e1e1cdb5f556bef1d95e0e5c490cfed072e11be995b924406731759108118178b9a4b64dad3574844ac4acf9ef13aa8cbd8b0cb52b6aa8d3f46e2619345a30209d8ca74034702f51bd84493ad675de83779b460ae6021dc55b1ec0d0258dac237229fcd6473da120009c4df9d7a0e54450bf8d8c5ab70905e81e6eefc5259ed02a838b1b4bd1a7be1dc9df88034280f4f0573f1da715387aabff7faa866c4b9c6ac59972fc55b7fd5528932629193623a7f9832389b47693716d003fb858ac834405996c7ad24a8a942cf5ff209ff84a1440c853ba30215aec099f5b6ceb7b69d66d52c6b793f5f5dc88351944b3522aa05fff8db2dde939244fcb4189867bf092cbe5f0139b810291aa60e7cce7bc28ef08e4514998d7f1c20efc62f43d27ca885a647daf9398754786ae2d9b89434a976befc7a533d19a1203dea587b679a93485c0d8fefde0bc2752c762101bc1da9803b10efab28e017da4860eebd76a655a9d028e1523b128593785ae3db9f25545b390a2d6bbc6ab4b5a3d43ad3aa9be14421bbd0bcbca8f9ed723df357c55a0bcacd1c6270a64b0bf330eafdf4600dbd9aedfedd20033cc481a6abc62163f308c19dc4cff204130e808011d9a0d2f448188e1af724a77c910cc001e46294ac20fb3a4ca175d3dbff19bfd53b8982c80cb6dfe1dbea0e53d20ee7be41cd8967e23af12aa8d41e3029ffd759c9e1dd30ebc65cfadf46a57cdb1e6697873eedb5a5e56de937f408667836859baa7d30eae4c55c3e1796ce3eddc0db898c889e778bcc0f162de4a33069a3573d3bde643d9efa82b21089280d0d0efb22c4ce56241692bab564bed233bd2edd114381dc0bf900082307ee4b92c2dd3eac694887de6c0e18a75030f8935d19cb686c98a662d546955b6ba3b77b268624f67aa5582051103e7e511b8ecf38c24686a2520bee410baf7e4b23c33f885088809bd62112b4102139d3aa8aa86c7c87b70351ed530abd6606e1e269e250fb074dcd2798340151c1f934fb50dae33896b487aaeca2bd8651e4a02e0b373df523a10af5cbf0891ac4a16b36bb96ff191d3aa756798d34bf734c5e3fa13285b7574b3ba2a50710206b28e36b872669f3c85bb5c77355222927ee18b5f5b1e3c6fca8b65e3478dff44325d6d0f7819ab4b6e36279667039c4dc7ed01014106f572940aca0855877744b9390a99f7554b5d688792b36b49a64c2e999b6ca27e084dc40edf753ab13a119b2d02780f0db7b7887c0ace17e44a2a6cdf7ec2dc787bcb95ebc982e9bc4c5ac0f0215b43a5b50c4c60de0982293408e3aaa7ccba9509bcf4e40d47358386f02", "52526565ac", 1, -49015535, 1537743641, "5c221ad10230cbf034ab829d18c7cd45af9d6be5b0a14e8674a9c9aff3f3605c"], + ["030000807082c40301ff976aed71d3495c51c0a057ca9d66456810f10ea2af896730f1b935f702e177030000000153ffffffff027f536501000000000451ac536539f8f5010000000002005200000000000000000300000000000000008768320200000000969f937bc429a593aedc0018d05540177f3a2fd55dee2ef801d5c6c7fc1edeea922d1f956585f666a917a6a698f38e04f637cb55387ed3344cc86945bc7148ea2e42788e553c81d7f2e6b8f48af04364a8d326dc836a47620aad463193ab16ca00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cab1008c7ada49dfb5236ba732b4654a0a9049d1b8933ea658784b6076f902c33a68899bba005e843c0cac6e737317e3ca5d3f50a9f33607606fab8b9212285a7f2e57593842874b089ddf611d9cf39b098bfab413d3fd12777836a3bc871a8c16ba5f632f283c582d3f2cde5182b2de802b732093b3feb181b0466d0619d69e03027753259f3e3505f1e216d781e9245066125397a67f359ba38acc24f69494260226f9f414272be73ab593d554f02968913a3d884e8cf7c0663255695118b61c520a00fd7bd7d2e39c0185a0e6d677dae926c7237b94d98efb72652a979d8d6533ed0c437c2112f46ec5373b9010b8abddb2607e00961708d7b03a4a1847f985aab2020ddf06908abfef4e77e59f64d25c15dfbac438646dde1596b1ca84500a79203c020e22a6cf8c9022be54efb8162c35f45439c0ddb530dad05838168cefa7b7b2cb0313d234e044c3b577377039eb86f815cdc0c931e2968c500b87e741d39dc67111031ab7527259845d9d5991d93c7ea52dc82ff7a21b6f524b551590c62790dfcb6f031f9ad53f2f74156eda949fc43b52bea87cd03eec6d3c1fdd4354b3bad530ef9425e8ac1bb9c298a949d41cb3997ce15db977c78c99f17d9a6c96774bde8ab65710429cec5043963931b4bca5cf3d401183dfdd9df886fd04d14bdcdc440039aa832428da4449d3d7f00fbb80b98a6ab3be34758d871c01dddb2c585d52e79e9e3de3f9caf932a84760407ffad4884f05eef14881990d76a4abcaa783fd9c0f7328437a771810bdfe92b2a7c21a28d0023978d660ce66e9b1fb687c74eda0d2a1b6615a5b581faa951f29f1d3825ab9addffcb412e3a9e0b8918d6efd2560e6f5b109a6b14b9b3428fb556c053582b769363ce5e5794483578c406a79273e2051e20552d3372904761d9c5414ea31d6daf3ebdda6772a3e7f58624695627f6842d300314fcd078a86fba10f18205661c43ef8be8d61f703c1f76d4991c828e528eaf4fe7c9ed4c9fffc6c6b0fbcacb175e099b0da24dcf7a6f7812fa56cd8b28192de8ffabe71963cf94ad976f8d05a6e7dc83994874e053d8a01a36d34fbea147df96111bd0e841d1d092509c66aa7bbf0513bae3ea1a0c09628ebdb6ee990c27b13ac65fd1f59444bd346a9c20bc6da22c0921a3305df57b4645e5a289391bfa90bfe878fca3feefa02d11b430cd9a64e8a9e1c6698fd86dc7b5b14a1fde53bfed458c3ff747d861f8beb1b57a005789b8cb3f8ed401543a55cca9c8cba549799b63cb28f0fe5e10d078bda03ad06b8a00ab164448d6632d24a38bef4f056a9a6254edd7ba40599288545029aea887ded62c212da76a26085eccbf93cb28e366d5f762e0ce5f5886eba9fc4b1edf23630aae83b33eea6b7c35b92b1bc91d02a93bf58939c16f3c12956ed205372ddef6ae738a914daa18f4af987210ace632a8d80cd6daa8ea72077388f55f57f3318e02ae3a709c794d570bd3413afefbe21cdb993558b27e616a1504f33ce2d2d72449773b29b94a29e155521ebdf491d17a9bfaef11ad83c013b83c81faeaa225e9a24e17f24517590bd457d3c75a2a6c3b9cff3b0549fac338077507292e73a7973450b8682de9968dbee28384b3daebd9df399ecf478adb1d028111b2189ae7e138cd846f6e72812c9614df66d8961cd74c3569822e953ee27b3f9a53d33d39df521eb432310588a217f1bf40931d8f9707b3adf107882a081a916f9d73fe96f9f767af5424b5da72cdb5b5fdae345e2ac761133281ebbd31fda0fae6e79bf41bf3045a392581c4e066270def35172d9871cf957a2cb773eb234491d27ccb27863f917d3b678b56652608cddacd1fc477df21f7bdc96d055ea8085423034004c47d740d527b0a4bfb93bbecc8d03a3bf16fc86d51584ddca45858514c7fce16efff2b3db5f6ac4cc87f33ec4f85b5dc125c604ce59497d35aff9db57e49c7b9a80fd9e286f43e3b0af4d6f285300e0411b45d200ddf59071041d5be51d721d40b4e9ae0b9f5879b3317defaa1aea67409b2d502b7279375eface4cbbeb2065006547019cec9e65bd24420898a2abd780893cc812a9799019e8b78705a5f47ba047c1e5284bdffc18e5d173709b6e90c30d3cd0eb3f6c6a12b5bdf6f0591818a1082a855331043314ef78e07c8747caf2c5e0192d131f8340c85d4e10adfd388082f88e3bf09873e615289ab2cae8a954dc0cd09ce89c3b8394b99c743ee44e0f02e6693d70c96441d36cb1939597291aae964a3ff329513dbde60b3d55f67cd5cc360000000000000000091e4e00000000004d93e6aeceb38d1bfb1c163219673de0032295eace9fdcd039b22225318334cecd5625208d3e6fd26240343854d7d4ef8334bd9dd23b8b858c2cdf3b4815c404979c37caa2af731a87af4be7c7eaa4f3ca5301c9b4ea79200c5841ed16ce0a40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009741e9a8f53cc722b8e8cac5437fa7d3b92d4c3ab1fd3da939541bd58942f4be8f598ca2c23e55140f78dab9361336280100f66ed83fd75d709b4d3393b5ceced4d00cfcdae81065fb79762a54c37264a465961ce5b57177470fd83b3732645f42c7a622a4a4902e264fe85a1020974f0c1eae5875f4ca50311605a49acf04cb030c4dbd2a58eec9d39c2caa2785cecd5bb9290e6f4e08e91613bcec56b63759b903080b74e2701a8c6ecc6393140e6183d71a82a45b3d94bf7292008442e301e0090b00ff9a4e9c11dd044e861f0aeaf04c96430ffd46c3cbd03afd2c53865e3b698b5605cf9d42562052df28ca99fa2a4ce5ad6bcfbdce973779e30548936dfb732b03072ae6f9b78727c9aff756d1ed9f6fe01a548ce0c691ac2bb432406d694a7e4c0205c2d6a168b77bddf35b00c002e2837b850f74d4f27f4b601d0a59fe5dfc4444021fc579c241ef29857670b0021c2d5519bc219c27205aafe5ff991716e44d5d81021a3ad2a1045cf617870eb1371099655a1f285293546c430a95734bc52770c8670319d2a178f4a1e77f5570a20d26c043be54e83b2dbbcfd3e45662676e5c778ee59dae67ab9f1fa535c0b5612c79827d722140eefe30b90a01c958ebf420338888368855c789c1ec9cf30ea597b04e44be4f1420acb71d7d88195d5346245959559e5c1f0ee60fa3d5082407dd79c13e63f2ee905db4cfc6a2e6704a0a88c114cb0cf704b99725b2aa1a76a43e4b8753ab4fcf9ae346537ec682867767411bcaa1460d5907581bd45a42960546beb5da5f90fc2e5dd693462d3f5ca5de47f8c4a3718b2b7a79e9027e81d9f71b3be78242a926aee9fe5beffdb28f6cd6d7196b6b9193233de1d52d9cae4983a975e1be64a61629d7e88e44913863b4ef5e5cdbe4bde1c8c667cef988b9f89c8c4aa46f6112d9bb61e9061c557604b7f9ced370be9e10d8c96c08f9fd95cf0fb2bc4b4bef9cb08cd987b89caa7902f5881891a5fbfadc8bfe631e9d492e0e5ddc63c14f64bf1aa3fcd9c989f050b8eece27e4cc6b580f48b29ad8f1cda5cc825dec3d7b2c308c55ffb09b5f7c75706daa03004e195cc6c3d5e2c2c44362f4ea5dd314b0e0a3bcc9b88e6eea6da20c13b25a9d8971db2018ce60d8b2fcf14c2b5321b71f91d49c2db6866da54ead528ae4f8e98f55aba0ce6e284ca2b77e7c91bd9771782abda8a3f5c6b9bf23e6d0f08fd134f1410953ec42cde8a88a87e4ca48728e602ff268758df18b2806875a7fb90b64657c5a7efa41c0ad57c9de2085cd0dbb40b2ced74c682a3b13664393704150e371a9f0d25dd0a52321045a032ceb46c5449bf829f877ecafa620644b852e5491b6415c4c9f840bf878f98bc7a6578d2ef04c41340e5aee2d4e81ade6653c9bfd1839f3b48ed5e2a59f3a46971b40e082102411d223682b7f1571daf1fed6be2d23e496f9cc22c8267457902161de3dcb319bc8d1b7f82dbb7612a5903b9f46204e18f1891e1a5630e9a2ea8a5c63ba128ebf284b0b1e868a48011fd468454e072398f6aead291fc405810653f0b7411b07e5dc9723d4cf6faffb6ddbcc223a9dfb3796235c859107548639cbc3fedbb57ad0f37d5756749e3276753e123c1cbee81b20f0c1d4ceebc20515105e89c77893ff52bbfe760cc91af12c8d3d502f56984e52ec809b3e54aed89fc07dc43a57034a79cd97fc8b70f693fd911cc9a2486c72f35c44d72e021067f02e3fe46cd3be56b1af348ed885e32302f0294815321ecc0a61c104217201e18cb95fa2442f41895dd4195e5ddd6f2a04071066b59f41fe77e201954d70df99e997c7e60fea32a8874a9212c3ad66c1dfbab980049fc751d8260983e19fd5cc1ac871053a18048b6dd1dd481b7baf252acdb14df1a4a6b0e3064ce1ef2dd653804d539c12468d59e3384cbc32b6f72e9465798a9a3601be3b9ecd8778a7efb23d6be67f8c5ba11be7dad069750e2fe1d912a89687ef6e8c17682a72e7eb807b7744277cb2f677d85eed9d6ae67e12bfba4edb6a0a5a32146031437ab918bd0c8d2fb8b1acfbac1ad47588dc528bbcf72102c056b45b492750c5d1fc6bb87006e1643d1b0d444456c18cc136efb8e9b10b32082cb13f29ea7e54396f2203fef0aceb81cf63b877604dadd9c22ae7680be0d34e173e20a74062a9555de198b2fee7e107061b1ae68bd14af2467f1ca052827b5cacd17152e26a3846c7b2a076adb2e602a56435912f1b8ffb6009d5221734c4019d6a82a8f333b0a7d3d295c68e5a34ac7f2f39581b868800000000000000007afe3f030000000008672ba22142e5f312befb1500be585347fa4b55c8faaab08b1da7b287e3c842d9a428e777a37aa6307a31cf7a49fa9f46f730712130d45032f12e1616bb915444562477b019bd55dbb00ea9cc8df3863592531954ce511a15a96608923f926a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae69eddcb35f964a4e9acf7367ad39703fd788a3fc7e6d48d5c59f26d0333288b17e6832b07e0b5c338b759bf549004b76d9c18ae87906b2ad6aecc259c821411c817b5f5618cb6544936827b826ddcef3dd290b49839dafa59316d4c5d870a411e44e615fd9641a3421fe40d1ba4ceba7b57a27a9b4a4f87f8ba18bbd7eea540200e68a909192cfda5f3cf4b8240c4ab8b29d7aa6417d3c3fec12d9a85763fe2a031947552dff1b2a72a4f457f98ff62c8fa7280cf2e17776fa9aff33cac0ed20da0a06ffa7ae02675333cd0bdf07de8ea8ea58e8df927d171b412f4f5a591f76275bd812b5a89e5de5084dabbb34ddca1858c461c0d211ac244bca4ca3a25c407432032c4c32e68fc7e6a54a2607cb370d3fa19d98a4695dbfb57fbe1b711ee50ab6d8031636f95237096db14b46732383e1f2f78d04cf60f8f026f6fbeb6399f031daec032b2a02b9373300e73fbaf4492798cf7e06ac8c3c604b0fd51c276f9a8a5d8e5403252221f3db084f29730f0c313ace90668208fe9c88c068a321ff2ad1379ccf0302248fcc601ecd73a8538bb519ec85312cefca18d26aa6a128bdfc32d06edf100783c30e9ff36d086b304ac500dddefb7777ca22d31a3637ba240644d9e8b83d1d35cfcebc81b1069610457f18247e18bdb33d13cb79ad1e72f258f54c0867e70b154f2c187d2d911cd2790fe05b6d7df1f8bbc55179c8adaddd1c38057a7f7be08a0b5e3ebedc794b4ed1df900600f77dd0e9d5c48600148cefc0863d4d6165a494e7dcb8f0986d793cf318a8b88b1ec27cc82e4dc48c79ea5568a2d565aa7753ef1b95b552042febe0cccf26bd97d3c2acd4a817662836408418eef8bbbc6adbf4b88981df82eb41a00bad733277431a7f5b83a391a6fea54c5e8b09d768b70a0e8774aea2dd86e96af1cd0f2829e046487c492d7bd1b34087e20b3e3fed709dba0092a67d77768524ba5e0763010d2428107124f80dda6688a06ff1a97618751670609dcf23a954ab3b47ed32bef10915ddc03f7ae248a316bb43a89ddd278fcf356f8158d500b0cff9b748e29f2d0d970bf4f6e74eebfc4a9d95f4bd127c25ba01dd0595718c4fd7cc33390c967cefd9d75744428d7076d590240839dd96e73401b5bdf02a61be61261a64bdbfc08af77fc51ef86d64f99985c7d6457f09f93d2a641e3ad89075f6e4fcdb444494fc179a0c793244a1ab8815e38c63d9adae29e2cfab2720ab28dae70f124719bc561b95e1f3b570a2ca8d1c5b702444841fac8d6219a98bef3c95ec38d40848b64674dd0ce5ecf64aa5b310dd863b4e129703c0047fc078e60fd6e7f9b86d57aa4831b6ea12ce259214f461741d4553a6b8e144aba436642045c6321002331fd70e4ed7f2a0fbb7600b77ab9d1b3276cc0f5b5c469d5211a7ced0525d6630883ac0c534660507964f93baa4e49f31fbdcd861fbea3cb6da63b229e6c3162e004f3b4d989d504d3ab30ae28cb98bacbd995361bc874c0698b060d5fbd18cd069f1eab2a1944c8d4d8a136c6231fa719593b6973eefc98d1c796989a4a0e1b87e3e2f3f733a90e093aa0a19fa4957ef649a4e31a408994205d7697018d9c7bab53cfce6b233862f178c32c832ca2bc5450d138516287664e5c0fb3f438a50b09bd839fc68ae31a9c50c81618458daa5f5df2f30034c970a9ec1e5d7c50fdb7fa4a202300fe4dfcb5601020c55a1aefba1e129accd5e8769a7deda9530c215e6862a753008e051ba73228285637f7de4c7590da12ce31510dce82b2fe531a0e05611df1ffb01425e5d50307944d68f690c8ee04d9c3f64e2cbf3bfb91e88f39c7face1d49f1f85718d44f9caa30c4cd296f0fe252f4b9592e931323a73b6d09dc8be95465c8877352a564538df9c25242801fa0969af75e680b2cfc78d8d1bde6d14723e2cdc7dff569ae3c860da25a8f6558217bde45d46ddb374b8c6e54e3832c0d35606b4e49bbedc95a2e1b2907348fbe5639295e818cc34126a14c1f583cae31e738a8d0be17d9fe4730337aff200d3b8c62cc852c73f05ce377b36e2f753784a55d32de784ad6d1c446af4fe073b0c62d9f64b4c5a576a98e4140427d82a07301402b01aa20fd226b3f6272e332de5d012d58af5d44752e78c1a83c5a9c6471f29d3a06fd14282f433d2ef9bf007f9bd25cf96fba40ef853eba8844836092cbb9cb9ececf297935cdbc144cebefe2e643cf36c9c7ef8ad0220719dd6676404a0cafaf1cafbe3790624d80a3559632008b161cbc3058e67ffba9e70469a7a64383f14df055e09503518096c37681a0930becedf8e6b16351caf682bdd84f007527f6e104b549b0d41efe7a987ab25ffcb271502d01f38e0f42cfe0f275822115f2283a2aef1d43e020b64ef7e8b3673510ee2377a0d8c291905f45951bfb8e5cb220e", "51ac63536a6aac63", 0, 815141338, 0, "ca1395e9b626f7b0338fb35b47e84bfd3d3913057a5e2d0f696ec858954b48d4"], + ["030000807082c4030214170f63471229151b95d3887e0d7d223a85504ddccb3035b1f19010dacd8698020000000263acffffffff1b3db6276da4af2dbfee7a4f492cc9f63a6045dc4b4687bc1f088ae9d1027e8601000000055200525300ffffffff01cf3098000000000000000000000000000000", "ac65", 0, -1879166880, 1537743641, "1ef5628999397c261f928ef89e4cfe33e58af284400efc23c59bb687e3afcade"], + ["030000807082c4030135390c671d2b33aaae7d934b6c9f61ce0c48feb7a694935669daba5eef22f6ac02000000096565520065ac0052acffffffff04e1e61201000000000852ac636563635352f5a9bf0300000000046565636533cd8a040000000005005251526a9ce706000000000004535152ac0000000080e946e50246039b010000000000000000000000009e66a4a2573f75af8ff73640d385286c1eb2e348dbcdfd789a40cfc5d9c5df5a3c0df77b2fa5c4fc42849f4926e7a569fc045696f285536f82807ba3be017e94c4f49da2397f55ec5cb77790f3dba7e3d2a0468fe607d8421e88821e64dd0f6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2b4e111ab0663e377b0f8d9426f4b4ec29a45868137553ed1f967cb8530270c5eae7defbb661e76c5aeb450dad2ec49776a195f9d1a5a3c425e7b16c61c3be90bf1d37af8537b6d67dafa78c91d5f01d4deb3ce0d2e38bfecfc514c335d9f4053901f5c9a419cedea25c6e18000fc752f13fd1f78a5a2690b51c174acfbe0fa0315768a1253f5195de60446f4c7b5cff34f40af0cf2b34ea821a765a47837cff3032de7f73e0ffe8b14c47c1bdbb056f1eb5a8dbe2a256a30c26b5d8558a2a17e780a0045fe004547b80a8908ed7ec3d07a6a0cc0a3db3675b83b45b3f092d060300993791e360be30320d330ba4892fed04deda84583edaea5180bf9c8b23ab07ac7021fe7698b8ef16ee4d74f7c6e626000486047487a6a3dc38fac6c32ebc3afc7b5020d1ca69392c8c5cce07816f28fd514be1be381a24cc0b20dface6fc1ede017050323fb5591a911f9d65c910d36c9a48a7d1be91523088c494b23bb9a38eff916250323b85e4093f6ee5c0af9a62395b85a7ddab79463851705b5adb077a2debeb05903143bf461fb0c3ff9f9157c6c37855e3bc37b59d9eee465ae3416a9075cbfb79e703a6b173db8980f37de65e73218cfc52528d1dd6e65809fcd16f0d9f691b12eb9e3777f0f78843afadafc6c08e0e65674dd3fca55fb401e871c04ed9c3912547c3da41882785c416ea7b9894b7cb71b5d2bc1a51dab7bc54533e756e14e97ccf58535f5695cdbe925bef9bf128ca844aabd1656e3b481c76f9c31ecbc41c7c36b2a6af815a0f829627493fcbd9dac06902a951c92ac22edec40da899d0233aaadde38daea8aeb70caee7e8d79c641d9557a7810b93fc6c913772ff8ae15e4b0da4ab1ebe628b76d5491a50926cfcaf3166ce367efd0aa7935e7ceee56f73d8d1fd4994fc384b2a7a3dcc66c9ae9579eb17f481ff86df8eaef21a90e59fc366ff7925b1d6a12930a025c537c358400f256e0da3d6f1ec065db12101ec3f0c7dc9b1ee62af923f87ff14201ba315f3bb221c96a8cb79db0dc6aba3857fc0cf65e4eea7de1faa170e29c23fd7b259e18e1b18729e5d6826c71d14098c0ef61d7930451f798a65a7c807edf36271642f27dd11dfa90d4b25799c3df7ea04ed339fe149c32460706737bc0bccff0450b5069c637479db72eeae59dd1f952da892cec3f1e5091df94951bc0264b07470415183ed77d0f299c8b7363019e4365cc06275f5beb54a765dfc0429e0a5c21f80daff3e020b6761cd30a0abeb82ef4c64c77862569556c83228c46600b86da6beab824072663fbd053065015de8a952a943e76872af39b0a2a29174a99519629b3396c034241db8d95fcea6339527d878c4f7bfeaaf205366a9bdb04db66972138bfd59ff005b7b47a78c18729a29fcf529614d171fbda665ff5fcdee0e57b879174f59c5089115a40b409098a3572a90abe46a96dda8f02024daf60516d28163ea081f9477a85215b1da9d360718debeb46e93ec6752ffc2e055ebf53188b88cd5201284092cfa99bed33355094c415a788231491c56624b3879e939eba33e8efbcf76fac603f9e964bd0690ea975bc0e4a66a7e11229e3b258f1d0c8dc0d01961f2826fc476d5f67f0ab830040285b2d65be8688803c2ddc4a2558d6f471111a96f246e39ba1f3419447902b2829e6bab2d475a9b5fefabd5cb5173e7c556e8629afbe67ed730b5a2df220d1d439ffc597cdf45ece500a718894562754abc8e78253f513d8b5324ec0d7d3b15fad45dfd1f15cceac2e2f9e74fdd5b2d9f274d1bc8aaeb51b6870bb1d2b2dddaff68cfa5a69ead06e0f4e555f637f1bc455fb07d30584c510b558ab02d6e378b975364df6378de3435fa68a0ea060e7ce7f04ca196f6826f303deded6df975f557a6c8246759a08d1801ffa689a764bdf93ad5c8aedb28c3db061248a39f716c482a0ce65b59becbeb29d5811f5ec0bfb01373f7fdbb9476b35819a45243af3afd70c2e00b98030801a47e32b7ae323c51cdba3a3cccf4862208e6db0d6ab22a7ea4305f03a6fa3ee503891f0e71fdb05a550c741036d0415e787c0fa504b26cf879fc34a20970af6019b2babc4183e24d2dc4e94b21a9288ccec66dbf4fefbb4cf0fa9dbe38f1ac709780b7a898a35d24a84fc6f9339b6c288143a75583edcf0d63ec960f221ef20c29b5f0975a3516d82688ac935628879d8ff09a4a5853e215bf3592bf31502f0484a7a0bc099b1992e8323446c9c55947e388c089e29ce869e60687063db96e8ef4f5ab62a87c0f1e23e9c895af84f8bde030000000000000000000000007ffe7eb5ca0ff6f12b3516c2c936a094d162cfff038528a3fda1be0232243d2902c54de227109d44a24e6d5a627903d1eae7d3f0a1c6e258dc97cebe82d785bc044665a8e29d40737a7c4a11f1503938262ee72f47618f0b395730c1959575d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f82b727b69ca49996c878ad489b2089bc476f0ab8deca2c373df58ae54da4f40c4a12939cd29cc8d59266c50fa0a9a04d1b83d993dd9ff2b511779b93cbb151e102b5ae27c67d9b295537752c5a721e6e34ff7dd161b88c3f755f568f0ed6b548f0c975693b1687abc049aa4c045066de501700cdec32bfdb7578bb3eec2543b021f5496d948259b3b44ccce4b9f469502e0d5eb911c1e5adbbf11f3329da33d2f021be86b1dd6b9da799ec5a45da1ed7774c68cab706c2b30b1c46bc1b01bce85ff0b020a3f16e13cbdb2d50b955cc6c4dd3e33d5365141e01924dd7ba19bd654f534a7810d60a434e5cbd0301343491a8b8c373f9993e2a1a6ac09fdda4c10d9e698031a60ca33f213f681dee0e779731cc5671626eed22b6ee64eee89b72039058a16031060fe9bfa9b7f6a16baa0fdd5e780f06ceac91cebf15466e0a41bf5a43716df030d7d0490f2e6fac5f5bc4cbd34c6a2922acb0e6b3220bc8cf0bae2aa973babeb0228194be845e4799ca180cca3efda7b8aa7644d97dc011ebbf97751aa3b41cd9b0223e4d8a1b334b957b0ef330f70d062f518ae38f07f85ed9bf003fdb7eedeb732257ea25599fc3161e0c40cce024ab82345f4ecc02b86a1d41d62cdef3b9be7300ccfc80fbd74a796687d6f26e10bf57a746fddb84661a6a6707e0581c512c08df7f940e11fe7c4fe472b5f9a310b08e68b237aef3beabc9b020d943a9047927a969e42e2f7cb26cbe6e2a8301ef81aa4635ea45fdf02ceef2bdb821f906e45f10105ed1094c02d33206fa64040e7cfca32ca65b049ede3ab4b57b82d666bdd635468d2c199b8fea502e42a7345c9b5d6ffb3b7300ff0ad1eb8283410c704adf9aa3a5b03f4f33935e58df0590cb26303e9d2b2872e41862f87da3fe7a10ac12a0a3b269838db384d0a82691c3aae93c992e35ef0e58b2282adf5e5d8904e40d60f4b203172a19f0af9df5cf6c8180c9484104a4d81cb8b535db5888ec69d483d793f42ac79bfff937b7e90dc518fe7302481114f38642f7fb35ef365b2391fef1e8a556dc2374f0488d8cd3190c534b73e15fc51b355b648d5919b3b2befe568ce9aa9f19f931e29c50e281ffafea4ee0b7ac7f865ff6ecb909f8833c759c9dd6a25093a99dd22b09f95d846bcf678d6ba6152a6432f84bd83940e1dc468ea80e243bf0eff8dac9fec10580d1f1c1422d6971057596b25401ef2887d4d0c5d22d457b72478a4befe7b5b4ca443d49c31e0258bc0d12497b27369da946a0d90731e1f0b10dd64b72ad954b01c16d825891edcf16ea7344d51b552e96ac6d0415e40a58eb2fba3c2bc5f4034c68ab2a0a195206095ed2bf3bed93b6675771bbaf58571ce2d8ebcc00674ef5ee20c81e543597ec9bb1ae2fc79a7bbf05a34c9de93d645a192e634e977ede659dafe561d7e6067b0bf9c4c4bfc096537a9dd0eb0d92161401c093d638e890f5de6ddf678472ada430eff845fa98ccfad6d2bfc2fa17613c2155ff891020101a906b9e775144610f7640ffcb543d893f4230fdadf8c496786e8281bbae67bc8d52f55dc08b3f323f207153138fd3da1dc0fe8cce3dd9db5d41c2fc5751541de37e391187ba9d71054e8ffd641aa7f8378a9fa037d41ce66deb431bb9d257877de7ecf7373834df0efb507b22dbb3314e528e2ff399606c9f091e4de80f02732c293db857a9e52265af7f613016beeda1c2407922e456e04afd3d1a5f4081a3d2cc879ac5fafe0e3c873da3912f3c729fa655c1c28ef0a40be533d9f21991e1e43c0447301ef4933a21e50a382fe82b768d708e6a8119bd220106f2632639e508e5636cbaa48959edfbd83fc8422be9e682d614d6b0c854be9cd292ed49235cccbaba038f8c21c90a20f8518b12790be1a7497a6fa4762b0f50b27311ee5821b0c15c0ace3d8d4b767129814bbece0301f7180f85fba2a82266edd260db35749d35b6a5155e9fd2bd5da945d3e8121e39ffb7836469a921e93859b1c19bd045fa84e8fd9720d7afce7b75ff6604df5d4edc4b9c300bb0a4af24f721d1232535c1fd63cb25239bf723d5d205c044728ff4b8c4d4e79fc239c86ea05f349a2bbec78dc8cd53c1b51a9b82de7761246c0f721052e6eb4ab79a31dad88be6541f05a61ea9154ca2a0475cdc8c9f4800fbc9679eafde01c4bdea8a4d9cb7f7ee8c25a3c7bdc36a71bb5da436ef65cefa97aa18a6d2cc24c36c52b3fbdb2eac62aa8c86f6b13f8b897b688b9dfbacd918ee3c5148490e6383f2a685ba07f240353d35b6f7ec1eee2e213949f0a0fb91022c42ae0eff11c2a7cd576d09b3d85c9c16894f19103b729c42629d40790ec0c8cf76c3ea466fa446c64c9cd7a07ec60393e197731e0398633ceb37a9d39bd82e2fb904156d6773743203a7cbf37be74235009d3f0e0ff2a8b080d", "635263", 0, -1524549655, 0, "a3b8c6621791eb6e3f09c41ebad81ff20c38ef2579378e38b2ce2679ff97553e"], + ["030000807082c40302d7ceebc9ab6928f5675587737819cc7702bbc54d16796156796e0ba332e88ac101000000026a5160f9b9074bc18c703895b62005164fcdaf14f2a155e0eb1f944f0cc3efc3a13563565c3b0100000009536a000052516a006affffffff0425b5e5010000000005ac0051006ab9c8e802000000000565acac63008a2c7d05000000000300ac65571e6b0200000000086363536a63516352000000000000000001a65468020000000000000000000000007c240750da4238896354cbecdd1e515db395d203fa8d26272bd98b88fff2a8586555e8ae694459376290e9ebeeedee94a95cc239e2041bd4981cd69aeb1618d04ba253e585b8f41e4fe5a38df7f58053cba1cc6a60a975b7629474641b23b92d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb55d68c4e84f5025a603b36796d64a1910e8170e9e359383579c07a3b80f6fd2a53aa167b9bf3b2a0a847130b77793653b8e33289ba845d9d69cf8b3d654ee7053b9086dc165875e3dd1a74b9183aa01e53f7d96a25350bd91c8a5713f2ad1ed06ce21487ada8948e0358486d41b286e6c5b22cbd9bcc7d4455b632ef36da7b022e77d841f31391b03cdab6f968cd3fe0175ed2cd44f1e99743239b34d3f59cba0317272e85fa6605bb550f1bf15d3c72c0d2c8b6145d530beca231ddc7315367aa0a04b42bdf52ccfb6bef373107ceb44a327edbdbe6562b4f229486ebb76f1f7b64ea4c0ebb1429a8a61b46bff28118bd22de4023124dfc00300e861ff46daf0766032b24266e29e1b0d6011eb357d21e6ad129266e6e1e2c169bb54d6db8ca6e77be022649b32cac081541c925d057a98d727baeddfeb23ac0d9a6a47e4506af131d5a02136b30695b82864985618a271ee5c21f174837e714b3d617f52c3e19c42af85c0225eaafe32437916ac56b5fc06b1b26e546665f8d9b4f6cb13ec5741ffeafc2e60204312999fbee40cd827598777e7c346b9d7a44bdb9f43b2644a81058cfe31914607eb3ce9f1bd281c02595a938a8408fe7899b76ae1f9561c56b218a5c9ee1af83afb7b5b7d65acfa4ac572ce0e250420f3d12fc2b22960e883bffe16ec417a5b8b82828e9a76b7f78b16c7253c2863d6b081434f37483b4285800d32984b78c0471f724f13aa8fa7e71d526c62dd0d790ec1f660ee04e31ef51e9465f11006789a69a351d30ce65b643c70ab21f6afdf1b418388ce125c80c0513fb34a19d1c4cac1af0240c5b8823798d90c78e390d9b03894d24d5165f2d9713e8e3e746157d27434113334422484c3757a4dfe81ed20cb9c9d8a830d8519ea782a28eba32c757d7bfac38fe6776aa0e70420844a0337011651f07704acaee6b35e087fa5295c4075a236cdb14272b3c952a31db624cc38c3199874621d49699a4de0f6650281e348b16fb536a8621be850a3c0b0f3a3bf57ee8722873a79043a0698d590ab95e742e691b0198fc2055401063c07828883e3ce7b671fe818d83d66286f65d671e449a9c9ccc7ee80a7876ee2df4d175d54ea15e4d2a5e8299d6a72bf7b65eb42bfdf80014bf5d007a8c312ca97528ffb9951ded3d74b7db5e5e8f045df5939e815f81bfd21baa1ae64568e1415285dc7dd05cdb96b3d42242b10b4c751636bbc22f12d1b13c545f3462bc92fccd66187f0b42635be4a9fce458e842a53c50c6ffa2e8b4d759cc385521aeef7ed30edbc5c95f73db64cdc90fd490e7ce3e54e1c99a1a346e3d48df7accfcd6632e81c49bae969cd61b7a1ad82ee74ccac0f6574810bc821d389d3ce902250fc40b65b7d20bd2a66af751bbd15d70aa1692a06f55471ca5ff5b754398ab9f2e9de8c84551081e7d9c7377391ac168247409a1f80193b25e6ace99c753d508e2d9475898bb942e9338d5d64e0ed9bb6dcc7af74b6c48b702b33cbc9dd67b902ad93a5fb4dd40f90fb0254c8939270bd9ded3ff4db1e904f3724b69314a69f6b7e76a822ac9c072080efdf402d849a4a7ffe032371d4d81342ad972f731d714eec006003c987fd2196eea3597a6f20be3a60cc651c19ed1f2404b25ac5d6212fcfd9911d11023436c7e6c32fa2352816c154abc90b9c4e78559aa6032174d4240f5334389e0d7e394e48d68551505b7cb1ce1f83af0a425817c29fe9f10c9fb9d8fc592349e0219cfe2e1aa5cdf523cf38aca5a3e574332eec7ef5de9e1fc92742813958d58d80de4cb2c055ac95f48168f10ec74d36d90c1a10214073e86a00dda48a821c353e24310c6dccf365179e3687a7bb5cdd85d8a2a14b2fc9c79942e15cffebe1dc7c1b223f18608dcaad656519f644521d2912a718225fd4259fe7a211a4d6c67277a7cbaa8c734691466fff60e285fe5918ac705bbeea33a5d0f58c0954572a478cf7deb7afc15750f71fd8c55d886c81627c18d8bc9443cbd12b75e76315cecb75f879b3e4435c92b28574c89cb44e2d73254894cf6cfb86c9f974682dce93942c1963e166b82918eb69277f2f523fe3ac246c57a11121d6593d89a9d955aae4b6ac1c2529c6621baba91fb55ce9bcb4f13277865a021ee68b01266382c2ad1e4f74400ebaac6191c14bb9ec0b9fc5744e03f24dea26d140e1147faa44a90393c8abb302c5215e56791e1001245f70a8179a515c41a2ce025abf237eeeed0c0578e00d00310791dbdce9f6aee8c87fd45d3d1053703518a4f369e7852a772a58b62e36bb84a34a62bbfee5957c9479a0dcc3b41e4242bcaab39d33790994a6fe96464d9d79bca9655dd407c93f51b3034f0434cef20798465a7f8724982788734af4469780bfdf4d6e8a1fb9ef732fa486414d054d5b4cb5fdc736e48c94a02", "6a6352630053", 1, 1278606574, 1537743641, "3cbeefa7b28cd4a85d30ae5de7b6471f72d69adcabe3555d7b0c1697327752b8"], + ["9499d2100300111a098c40c5133b89fac9a0ff1b3d2c69d942eb65c113ac0f92a6ba74bec10000000000eb74b07e0aadc89db0f3afb7e36a786db766b0e635796516ee022360a968c5daf8d9d328010000000353535133eb713febc662775a3f6c5f7eef3f357e7aed49cec8141bfb206e4415af348c848e16c50200000003acac51197d48f404b7f45901000000000852005253ac5265518908eb01000000000265acde2ba90500000000096363ac006500536500f57f94000000000001ac00000000018344dd0400000000000000000000000015e47d88bfa8cbdb6b0f0618c6772e7be2632c8e1276a857afdd07bf11e86e316e26288fb7464bc89b7751e29173a7b5ae50cbabdb2e555f788556a0801be409c246b052c16b5b9d7f95444eba25eda80ee35c6ea77e8a6214596c31dfbc69fb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006eb6a25331797f238362eaae2a0575e0b2cb88a55e3073fb0bf32d30a891e1323170ee05d84b2cf9bb7fdd960a439a0302af868324b9da668c5924e940d2543bab9a4751706e5531bceda4f9c860ced6e1d2ecc479dcfbae6c5fb8ea64b36f89ac172e537ab783e8665e97c011dbac2b48b439a69c5f0cad58af50489c1153303197976c3590ab3a6240490f600f992acf3a08c0893163bac067eb89d2601f12a021b314f51302b88bca5b9dcfa9753eb71bc3a82709064588d3781213e45e4307d0a06a4b007857c77b15ec85262d55d9b82037fa6cc8e640f3353f65ccbce867d74b8bf0b1211bc1bd5fb617442c857cbb6d4d13b0a788208a67d100b81a087a9120220e300cb489047e6f2e0ed7a8023d5d2865ff7955784c663f424d848e2435503021a4a445a8de16e9347bbfc2361822e8be96670990d3ee7fb821209460eb06ffc03182ba5ba3486b2b1e30ca9dabb2de6aee8b19aceb633b12468f3f875535e9316020d755debd2b9a3cd0032c4643f3a690007458979f605473ade88c20bee638cca032d6634ba6936edc612679624a2066506340debc9c7b930b641d4d398e1613dcd207348fa8f26a8f8e5d19a0d109f15d18725955d8f9b629e1a5482f7268a424162102a6928c39dceafdb7430dc4a863c535a329717a9ef8fbb52f17012290d836b487217561e1f47e4a46a06e5f59573c536e4d8347b06c601d71f01dd0da6fbd4de3282f73d8f10223222546eeae22cb1752bcfedbffdff2b24d42466f34cd9e609bdad8062c776a541bcfd6d3ee06241e93bb9dac7aacc988fbb4af3db06c6bf7f1c0900df782fd6d2bf223c61da8862ad70daa5ffc03cb52187e70da0f55966febda1d5a1677c3a5987b2c4faa4226229e1224177fcc15b8267adba488ec04303f0547ad26a163a140c6d105a8f668f887e7d1aed33f6fcb3bedef0ba5e158a39303dd1fba90e7823d16169c08ff286013159c0f6d43c9751e81051521b86bcfeea7f3974e5bf20a9aa6678d3140348d58d868ebffbbc327062884ab7b69f730016681d08d8f2bc9067017ecf7fb6595cb41ae04bddf06c3b7f005adda459fcb8032a61b9c81ef6471e389775b65aa4bd9a35261d4797fdd1ad1376eeb54cd9332e2ba65b3c6311446275fd5c5ef985eaa7cd6b0dd606f71b6a9525e65e69787353f66777895626f7529d2713c8a2cb241d6aedeef9f80a609b1b12fbf27fa0d1510fb192028b7d34cd6013cc4a85dda73bb3c6eddaf6eb22d7209020a822ae4972308391b07585dd456e703481c139b1f4ced6bed9f1ebf55bdf12edc639a19f14b0da48fa86118c84c26bafe10389746a60888abfed5ca15b46797bd81db58ffaa4555e025fb1fbf0d1fb47b117bb802d328451791efc58dd9ac2df369afdafe95c4746cda0323e09afdb8dea93cf885d632fdebd1a64fb108ca40245047ebb4024d9d5dcd4e34edabff512e2ad8441ce895124c35777e071a4a0ec3767d209a4dfa62485d9859d2de8b28ffbf0791d8ccb4214297537b0aaa25092ac7a8033fdea65afe371a8b5dc0ac48fcec24607006e3b038e2de572d5601ac9f081412c4c7aaf6912a3ef82cfe65bc07665a4e23e82d31fc31fc64d62d22baac7440462ff7e9e354382b95d5b4f480b0e85c2b33a6a7f914950fa635ed296290fc7699047d2a3f8e093f849aa030af45c3f254ff6f139e94c52b81dd3c4fd0249314f4b9e3a7d114ea1bec5c83642fa7ef706fde4bc7f90a651bf65da5cc888ae53d54b0df2ba9475c9d748263a3971bfac182b6da8c6173469e5d4638de7ae5bd7111c5a61688397c03747882d4a9eceb7732bf7aa958b6cdce86a79eabffd4e8188470f68260a33d13f86b1b7d271dec4c6802c2144456e1038d1f1b6aa81f95de478d1dc6db38973d37128a69e3c7da0c97d478a728255cb3d2ed3347506b16e20bf3bd387010c97c069db9e4a8dc08e154d03c6eb8ecc4b32f2d4bf0a573d9e5f61f15964b3b5ed44334420868bb90e16a0df550150c4273b8fba1b7b939fffb56fb721fd35bbb441b7351d0b05df95e5e18114a7153502bd118b559fb179eb2dc143350b0f34b4986ba74a4100abd8b8ab1249535298bab43816a8d5c4565b197fd118943bc3251a87c1a07e5d182c742cf6294ca6445966265dee9e705a1ef2cd98edaca8b9da0e6f25f6b29771bbd9dfc3bde2ffe537e1f1baaeae0c42ab3d84a301328475835e6d12aee79f52633e17b38e17444fe0d7f4bf9e5cdc07717612af14c90a2af93f2235d4b7fe66d3d474a1ebeff0390927c7c2bda5cb395bb737e6bf716a146ae2039915ed36a66fe709093fe0b2e162fbcd3fbd07366137254dd8f4292e5e76b3606010bc235557917e80e5fe87bdb1b77780d68a7fc15852d6d03f0cfe1aa942ddb17fb33ba1fd0f0d", "515152", 0, 273789000, 1537743641, "71da7673f68329cba17dccd9b7d176387acf0f1c7d42ace03bc4202e8a14388a"], + ["030000807082c4030149d52f8e48166b404f466e33e44721e07a37836da6b93c93842abf1da35fed43010000000765ac636363ac51ffffffff0321761d0400000000056500ac005364c6c705000000000100ed2c6b0400000000036351ac9a9a7741fab44c4b01287a4f05000000000000000000000000975753241cd6114af11e0c2a01d1da7c741afcdc1ec9241cd903e7179e7a6753ea39667a451cfd8769722f3b9bf97f0d2f6b375f1802fc59fe47a0ceeb2c2af8ec296a4bedb1582439fa56330f7dac0e248871ce27a682f90e9ae3c5dd99ddb500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9df23722df050fb55f6f9cb65ecb1a10ab3d21a00c94060f288dec2b79583f2197541ac0296673c98277be80d2fb65020d69e3b4316f3fdf379595bb837b4db8c619f7cf6fdf58e226183b28bc4ae2458e485b0302283a20ef2557bf9605b96f66a85959655274e714530bd1bce1b454deb5423df4834b928c8bcb041e40c21022bdb5ac6b4711b8a3854072be3fd0b69e6cfb6822e17db28d6adc0f65407702b0316ce62b3f88ded95dd08997c0146dcbe6d668fe9958e3c07de4a315ce9e0f1a00a02e7a027227a0795ce654c2b9cbe2a620bf0b38813133efcc0416edac324a654ec8ff7a792aa5c3f4886fe6941cec6dd9dd819e5733120944c0a44aaa86cf85702024c618867cc59b77e443bd151090f67617b945aac3e2c7baf97c0b4605422e4030e012a366f006846882d1f98adcbcce4debbb45810eef41280f5e8d23800ed6b022314c828dcacf74d8f52b4ff26e6d9eeef947654a147ab7a44af1b09c7a9739a022065c68e5b0085da78a117322e4ec43ca28c10e93ab803b429b42f93576eacfa02075fcc09097ddbe1f006f59b7e1430f0e6990f21c712b80b2e98e898389d8c0ad8ace009db252ed8836664fd6722436519ddf2dd3ff784b6c18335e31b2857938d7ba085dceeabe7112bc08ff457c75905fffccdf15c866fd6ba2fd12149ee3f5b99fcc17d86302c794277bf6adb8421a4df356889f15459b195357707aef7d524c5ac68bd70a7eae416192585a2d4cf5789770c58ee0de3fc2156f966453ad2fb3cdf607ceebe0c8247047a707e6e1afc5bbb2892060c1aad52057cdde4e3b717ab5bb6a8c707ec2623fbed045f0921d5a88e4db50cc026781bf868ec972a426d7526b8c9dbe1d496c5a1f599f238a914dd78162101a05cbb2b0f3299cafcf3647eb50851e127575d5e9cdb5ec729616d96bfb3d73b399e0c46af43bc6f1c6bd833a60c28be8a88a9c2e69148cb1a3ccdcd857c1a2358178d683c11110c90c36b6b329f26fd8115c8fc413011ccbb6677fd55687ba55fe9910d464dfd92d244bb6711ac6a27bf706fd4abe11b566b51bfc361c159368326605244d9be404fb4ac3cc082bda7e02ddaf6c9214d2e0e7188952243b1ad8d735fee72e66cb8d69f8c942dd4b551acc8c88a6eec039e7dc5749c24a5fb888d9048cb398c130c4b637b9a3e333df740546ddd11ff99b2cd83c189c5027b1dd27a58b9c6358125a65d1715a879c6a305a186ee4062e2bf9fc1a428dbe001b02997eb5111eb85549aa1d6054cf1cef242712c0e37ae92019050ff4f04e04f92ca6ca0cf2cab83d311956b0ce4b49b6387d89edb94ecb92634727803f9630221b15d57b8556bd1da20cd32bf081cd20beba67c476b4d59679d4c4332aac5fe37180b87ce9d3e98600478a43f4060c00629149abbee4ef2ab287a98ca13e79073938491294f060d777a20c99dc98ff7a19aae8672518d37cda4602f44e908b2c761cdf09101a5194c1d1202adb2364ea7dfa4fbc7a444e5d22f1f0d44cb333fb9b0b244f00fe5bac649963a11b0e36c060f13fca4c0a91b9ab0764ec66de56b3842085486b4e96dbb98a97c4c188c5309075e84791c6b4be177a053d806be1611b407911391a366b307d771b9ea3a33d5719d19ee95b791be4febfa21ff8765090b236271c46b25016ab1b64e3d9abd07ab74b56996a8271e138b6439a884672e7fdc463d9eca7ab8d606ab5593284e4aaf6ef6133b34f31cb5a69e4917d05b49c1b03443f50ec2dc24a3dad77569db3f65fe022b22aeefc5937751c28bb8ea4f339acb633eb73e23af0ad3e71ffa96369d1b12367421aac11f986e0af748386e469718dce3b9e86682c4c6beb0bb450eafa689fac3f8dae6c3a412e6dd3dbf75a638ac94a246f155142d5cf3f1209c2bf7b01fd13390e40b5430401ab6b8796e9e0ca31c58f1d2fe6008f3fe4385e3f75e01432bdc0f37e7deac6e6f58cff6e6fc5efe99ad7f65accfab2dc75727c34ecc35a3cee474a65e1017ee2ded1bb8b01580773bc0305830ae6afbf708d6ba966bd8b29cbb4fbf703cb03db487fb9af5fa8aeee5953aad307db91884f1964c728a6f1c669dbb487bb2f142674078b25f9ad2d4aca23c64849dbc9eaf02b4868d85b792389bf4d654d676a8661cd9c6351d5d5328b25b8935ed8cf05ecce0e32e7f640e0e8fe97e1127adb4f8d31368186f72fa57744d7ff17ec612bc375d0e94d0f73738eb8d924a56ee1a260242f8ff773430e2a6c58970c65e0ed1f5588d8f9140de578e16b8b86d569aa870e9ab41ea79e413db3df8152650f50bcf33774e7847bdd0ef9fbb6615f8766d61a69b9fb4e40f5587dc6d627ba44df9ad76370ad81591eab708bac55535e85f2536367ed08e22ef7bbbb2a667c6fff88bc66c90b1aa1a961d300f0fbbb75808", "51ac63005200515365", 0, -714958258, 1537743641, "f8f1d3dd1317271c8bcd7d33fdde262476701d336f29bfd51f43c7c77d5f2041"], + ["b3704a16040a69c5662d0ed6df28a3f4b4dc90ab3b44f6a78adb9d9b90909e3fe05063f11b0100000009630065656300ac636affffffffc458b0e67c152d03703e9ef7c021728ab55fa59cd3e538effb8d1e9b76760bc70100000002635337448636c2121e2a0a4343c4e116a5b1db5e29aa79fcbe9309821caf2b5891827d5615790100000004516a5265cacf5458d1385dc0e493e5c13735a26d44cce94ca29d9af0f3af3b1d97d015da90b1840a020000000763535165536a6affffffff022a09830300000000035251659c850d0300000000016a0000000000", "6a635363", 2, -151433051, 1537743641, "d3e16af00325ce3868e65cf8495fd598f3266234f46f0260262a8bfc089ac13a"], + ["91cfab7003256dde824c5ba3f6216f6f7a6deb8f8d8371b56fda0180194a4aa7d510d8ab4b0000000004525253acffffffffc5cd13fcecd10f8c4509942b14477d0428ecaf43a4b530bcba1ec89fde616d02000000000351636ae45d15356d28c3fed6a8de46864862b4355dbcbb0fd2e81d465ac6286bfcce6c3b93661f030000000551516aac51fd481ceb01be8651040000000004536a0000000000000100000000000000000014f30500000000137f2d2f958166d21f1fef7bac79305bc366fcba6adb0070d900e76774f82c5f80113f24c396ab473564ab7e822872fdf824caf8e62a8c3fd51dbdc8e75116b0dbadc0005fbfac40474e09e4d783ea31989f27ef1f2f47c98e8cedb8e77ec43900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a597265dfde112e9e51c251c679c39657d9be2b5155dcd587c5c9437baf9730e938dace07350a87d26f4a41bc8feb908060edcc6128c7328aad6d8133930077e09b706f403db2eeef56d15eac3fe0f4332769a317282bd1e113695ff371553d3626a65355343dc953b4e557d1d5dbdb2343ef496c98e09784d3460d0dcd9fedc022980f6d491efcf26e99c4011e2e5d52a0fcbc469747ff14a2bb67e818d815c3c021e0246a83cdfcce4bb76286ac5561baef9ded55bc27f8c0da0a92b0a5cc6664e0a08db4559b74a0fc5ba9c223cc021ca368633bb66b41a3a67e1ff0024faae20bdfd80a22bf12ce1cc8719919e223a3e8696632bba09e68b45d5b681d648cc492f032efa29a39a1a544d35a18ed2df63af53163cbccbe03b19390ef40ff4d1eccbfc03278884bffb664abb6482323bc6add07fc3bc99515984007ae33f462d88c9e478031e570118717f43cadde900906500cbf0e1a01d452e4dd55104cbcff0e8d25c6e02070646cdf54a36a9e9806ababdce63da27f9665c69e5bb146c188dff4c6c131f030c69ff9a71a200dc1807405aa1f3affb7330b6957864457bf07c7f71f32c052bd0a770e3a607921957e01c77c0d0a4b8acde6fae4e28c143da658470d77c1128ca7c228373d66924a8ac104d406b2fc96684938d48ad0d755e6f99bb5a27b719ff6a3fe5531b159dfcb365ef2de4f0ffa0c77d82d147cb99d60e42f0d9df4dc5e3bbdf255847972a0f12018b13c5904479a803f2403082ac9ee3d851420c966b6636b51ead92885b06f371cf67e4960716f1a0c9b86b0ff44e0007196963887bda658e18ee5f2875e06c6a6d23ebe1a9c6ffee52456c5fa850bfdd5d70657ee77cbfd2a75e3d5da951b6fa2835322243585934c8ec1d3d8c03d8fe26ee31f38ac92cd2fda8b2c795ac8084bcb733962ac11839af1ca919d6e6a52384165b11779273d072c92cfc7fe9441b2d4b0833e90dbaa81926b5ba243d83d53abdd6f01ab498d69b113b738f79f603db5dc9bbeef8b39dab200080eed3a2f3f52c16d1df81006b2035e7a0ed1b9920054347893ef63f410206e611de2f4e5ec700c4164c10d1692802f60d3a5c59ee9003ea40cc635d60f4b0d86adee6c50dfca02b59bddeedd9d020be3942454c77b71e92945286b79cf0c18043094d4b47c5161eba0bd1d5a8de811ece3bd18ee486fce21b960c157f690ad759efbdfdd31ce89394aa79737e50d62c98de9f951b41f7987eeb53acd52ff69f4bae7caa6eb2765bbafd51216fd45f67f9c265de446acf5bf8f37f0d1a05ed9e1c55eb327aeda164da4e6c72a8c05dcf6b1465e0e54a915a84ff2afcced3dca5ee4ec02a44256fcda6afbf2892df555eb14348b8016eba2a2bde171c73101b7fe4e344708b5c07b706a34317af7876b4eeff5596875e9aa98bec31b937fd5e500b6b454eb8059b0cd50b40cef1de8ba2e8a11925920466566e51a88bbab1878db423a910653a844e5e145349f458c2bbaf7b2ce74f71c922e755e3089e8b524006038e2e30f0d1b8b32f21e2dcf847254078ec9563660e83f25194e81b14cc91133d70022abe8e90d521f9b4cef4dd826d5b2046429bd2d25b6707d512f189f288032d379252dda433212a3994f397292371660d6a842ac3e07a4d171d341ea55e5e99dd4f67b49bb72bcb92e4dc5d2433781f93a343a1df616156bf99d4875c5f087c1e911f6a6f0974bc1b2fc48e28e7dfe9510cea86f2c9f756eafd2de033b113deed237f10dc04a5766071b1f131c7bfff2a645793a7eb0976cbe2ea1ae70ec235638f5a77493fb24acc73452f38d6e23adbd2a5e801db08f8a10812f03b964af1656f4b247dd3a4ca3d27832cdf887ecf088ac47240e0e12dcf9ad10429cabfeb263191849747394fa0ce050d3aa68fe9750c974c5496e58f0652e392aee87cdcd5faf1ac33aebd991a02601de9bb609841dcd7c59cfc5c12dbc915fada9db8bb8e97c4ae1cb386433a26ae8b67fc562b5029bcf0f0fbc425d76174baf3383e4d64642d8661293605f178bc363d3237cda9729d2eb50920bdf917cc28d1ce09ea5a0c8aff74aa6c21537af44c62356311c64fdc285fde89629c9a13edd2a15dff65786bc87bb582d490f0047561b07a319f21aac58e045e0f8509473cd40ec7ae8acb75f8575633c86732e7ced2b62cf775f1172aa4443736e5cfbb612db9ca92473261dd685faa254ed81d86585109777573f63eb225c0a2feaff4c4da78c3e0649790e0a0dbc5540efa4c4d81e4eb77ddf5d824e19273adbf2ca490aa0cc17210ebe1dd941810bb2dd0c61d9c387de9933082e94d166b5c6b3bf1974f03f9a71401f92265d8fd68cae6b35c1e073e59e05dc7640189cfc7df8d92ea2cc6e6d56f1109e0e479e1062e2d44df41f58db74e463a8854ce95400a", "6a5251ac53", 1, 1019001714, 0, "e836787bc5ff28892b4d83b8b24cb6bf6cfcb60e5cf7b56fbbfa03b36b422ad7"], + ["8e02f857045a93c447ac6a0e684ec1eac9dc8c275820d9c840632ed64b9a3cc1848c9a020500000000086a63650063525363ffffffff66822ee3065c573ec75f58a6d51647d4b7696297c18814075616f17477bfc58301000000076a006a5351510003a25fd0681c8b1a3a34b7f58ef5822c8979526708603406035b4ae933ba399b6af9664a0300000003516351ffffffff57f01abbcf9efb6a7b85326165a29a624b2439c77056b704911e650ac1db14ee03000000096a65526352ac656565ed6422180481021d000000000007525365536563535a814b0300000000066a52ac5163510788de0100000000066a006a5352ace4067f040000000009ac536a5251536a00650000000000", "", 3, 1941426068, 1537743641, "31d1c50bc4f9d33ab112144d4ebd80c215bb3c742f6aba2ed6c774811c6b9fc4"], + ["9fd9aa41047659338d822e852e7f581667cfc98f6e4e00ec880ee9543b25fbb1828fe022be02000000046a5263639f35f8e419a4ea62d97662f6ce17a409c4c5f77bb4db66436e134d554e11f133a89b3b13000000000900ac006a6a6aac63acffffffff4bcfaef8c5e1f00e07d494b5c6c94b35cd98da4b3b4a67bafac9299b399b91a2010000000965656a63ac65525153381704a1a4270ac342201c71bf9420a73427aeb9bd8b50cfeaec9c1bdf18aad2907761600100000008ac516a6aac00516a7260f84802a359fc03000000000463510052e54680010000000005516a6a6a510000000001bd28c30300000000000000000000000063650ece4445baa2a2f4a16b1d7fe008d7997dfea432e06cfabbaf848da7d3502e97a2cf753a75e3e34192ae329f891846b3f29e404c6a89088904f9e35c5f2df91dd74f2ea0d91d331cba1d978de3e1e3b79c837e9503d742f7a1b37c90f1c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019ff89bd56ad3b0d3d4edd5dc40a4c424c18023dc6181c64c26a0620d9ad930b62ab7dbab4fd586e4aec9658de2b73d44d3a986e51e859f52ee981a61ea93a8b12f8572adf0192d74298924f29c0d87e5fd9d7064c8e60b657887e609e214f4ff2550d0f9fb8ca6a5254636bdad350dd486d6ebf6019b07b5569c4d4895018280209de7c323103973e039318b9aaa4a257c8b0e57f224fd02c38f4ee4ae0b5260b02151027a90b66ae0c7618d4775ae0c83497843ad2d3d050be42960d8ffe5f0fad0a044450c420cab583b9099b9ca269369b9d2735679b4eaaa4ab43900d17b01bd5980534f764a5b51d75df1c2e976acebd3d750d790fb4eea43f674fb88b433a0802227f3c59f147581741b873fa0a6fee208849570ed3726b2876d622b1e2300d8c02256f79f9d9ac9f41e366878ccbf2fa023a22d38df71c734ab15bc305f756822203027b598772e68c5b3c4f92f879f758c206e887c46dff08a2b2b11591749aa51f021c39c3ac35ff2c6a2ff2ee1857267f5ebe51b4037ccce2ed1532826dd7e25e4a0221b77ff26255a022edb59f86a95fea9edb06bb077cf005e3f76aaf86c04cfae05a38a30c11ac1dddc6d0c14e4e5013dd9cb7ff46acb6a3384882bdca63b490282541a03f12786fcfaab84befb157dcc5a8d5b5fc8768d4f0bf54e7f49e04dac0f4117c3b93d1927e47d80700313aac9efd4de3356946bf70eb9b209a9fb3823a26cec5544847ac2df4421f9b5235d888542bcbfb8430b4e099659864ec2f9332467099b021b387ae6c84928284744cb5ec9e0bfe09053db31cca857b5dc6f4d6fd8b2d16a2bf3c0debd72d5af9fceff726b95622f0d7b10bb0a27f70269d64f1b461b4e22469b2ddec122c77f9ec2c8fad0406f702b69f4d60f86864711bf336327cb468b729e960bef4c72f68d7e3c97ea774a8271465bdb70d0853410d865c5707567331179d6c550d18c5ecb76810915f4a26522d41a15aa322535c44e1635b2e3047c68b04b5118e4ce7e1c876f15268948372a1faad24854aceca40c74f1794508a9645e4f0764f48af58f8f953df1dbaccc8d7f630bae74185414a3f706e05c812ec6a0eac6200634cadea13c14fa3f0c2447798db5f9a8cbad29706534747327dee3d21abbeba002c9b59310990bbfc6a27fef720d8a72c5ad0d7b9c567bf2f14f89aa92c3264e0e534b9ecc2f88ffd0fc6c3355b1164a6648c19bb17aa0227ee160a77500477044275c0c868a0aae017b51786fef736964ec2ead60cb245daed3ba9bd63a86902645d375583838543594938aa07d90a622b2ef12f56c2ad359be4bb27ed3fc33f68039e183af5f46eaa98e632f64ceff9b6f62e8f731b42eef05876be2c5ae0558ae8f2b93d2b50cc4ccff5d1aa59d3fcd02bc3d9248b22706abecb4e181f256e611c0dd50a11692248f81f5d78e21e36f4b6bb5df447c0e5aaaaec05e9dd2479759b716c78e73da917ef6016d00f3744fc8ede58162c9dd0fde786c07695ecdb03f65beebc21f2b0843b07a35ffae76b95d81cde133f8c076a86c79c1dc8aee00d783767bcc44a18d759a25035bf4683567407aca6e9794aedfc97dc1b36c5f7bc09f524b1f22e5d6b30262a4c19a0086f900e20aa85a31e069338e3b53210e5dab647809d25a15bdc919c7b0a9b3b4ecf586460e176c021c1f80ea1f3c31615497afb40da9874b622ec7b40d88fea3bf7398278ba5f2de533a62ab5a44013c3ecf754775276c15f06fd39a1f532253fff1f2b432d7b51e94657070b26a7d54fb71636d1ac0f0368cd28b27176fbe0cbe7536ef9ecad256e99007cadee3d31fdf675424f0f1d9e82d16a14ea9d9ca6e887495e40eb00ee7dcfe926a27aec9930ac7aa1b14d8e7899a605550f0fb9640c1ad637943e025a72e458716266b55036300256b458caa3c29343446b47404bc156bd8480aa6867e2be45714ecf52b8e95b14aa1ef3504decfbcdee4aa7f591eaf89648c65a23e83f84c27a870ef7857733b1327743ccd56827f9b0a156d2c2970b7f6e8bd9b16f896cc92beb2e3d8db27e1b15ed1ef0f25716566e91f8d81983a364c69b6e6d58a64e5331647c661ae076df5f42116780c3d7515be0fb50918dc5a12e36a44f35c74718c6207804d991c4e3210458749fa26b402b39a11184dd03da7c75cd54dac657c1a4cbf92e6e2cff36d720b032c4ed9206a930eb7513c5e6772fb83f0472a5ac9288a358877493ff3f0970d24db7367e6917d9cf2da54351880105e74406c5b49fb8febe6308a2764034b1a4d919df195381c649951320f633621fb92e9dee69f158262896a8966886a46b02c67ccc7564122b08999707113ad0ec8111dc5b0ddda3428fc2a2ab874bad4c2b44574495bd25d1df4b51517cc2679f987f925fd9f1bc86170b12e4fa48af73a7d707", "6a63ac5163", 2, -1688082806, 1537743641, "fb2682c5389be24440a386b2679784cd14165892b4cda18eae247ddc6cd71bd2"], + ["18c9e76001eba1611efce92c9fd1aad14d87115a6676a85d982010a65e8505b7e826f0019e0000000005acacac6551ffffffff04b3690300000000000263ac90de85000000000004636a5100d6c90401000000000451636551dd18660100000000086a00516a005352ac00000000020000000000000000b7ebc201000000002df2a313e7f10023c0a454a7feb9f10ed3a21978632ee9f3b9d11f4ae39c7712eb0e629b0c773ccf54248e9e9b80a1c6945e44db42bd28ace75ab96318adfb8c495759ce37b41f1899a9fc1a0e9f3aba1145cc9f4a27a0820979ff7c19e26a5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ba109cca7c61e3f1f269d504f12c882a33a85be8225a67902baaf2590648d745d2e86e78a7b186a4b1f9f3360a1ab71ae5a903ffe39377f7a0fa922a7a81d6d53ec01ac3b81926d66118348061adb25733a292f4587314afcec831760fa64a1d5ffc9a586848eeae4212ab30561929c7e1bac88908015a039d2b28c83b249b00227731fa97e62efb16620f3107216f31bfc6a6d386e713d1a88ec907096f50ea7021c05bd0f021c3d6700688fd642ae45009a86d38a8c1f162440962294d7554bdd0a090bec766b4900b0e5432b001d208cbcb709c2ce4d0c43d865b3ddbff801b35713209c3b357179aa99203b01833e5055ef267bf3676cb2830bbf39882a557b6b0205063a3edd7c0117f86a0c11ad39414b62ad73776bad0a176bc33b93c2ca2243022560e588227cd2d62a4d1668543c7b5ccc9b269ab8ffd40c5e00257004252b5f0323f3c29e55a2e87c5825038b2694e174a81bb6f9e10030cbb533571f2d4c6b0003239f65a22e658b06f65656521a804e7bffcf4266174321de6de241fd5a8ddc5403118eb8a39c8e0b4a97252fdda4639a5e952693aeb6cb3ff3729a4e75c357e13b69ef05b47a4999db6b3be2ba2f6f099ee37e20296a64269444af273a778dfdd5d3de115e01e1b655772b28e90c2e5ea34716651412c8a5fa88859778cf1949b466f5bd02338a7bdefefb221ad1b97636f234a30b939596fe864e46d8dbcab95b615f5c3b26551ca6770cb0dcd4eb976b5419d50209460f05fb881cf2af7f8b51aba9f1c09ea3b2bf58aecfc86ccff8ecbc06a501017a58159efc0675bd27fa7c41bbee234c99362300cf75d4da4d7ed2725af286eedb1adf63a06f18767924ee0f2151fbbe75df071e79b1aaec5aaa96a50cdfffba18cdd8e457fe052431c3111ba26b4e38b826c765fa82e15779af6ea727575edf18f07feeb0b00e2d04af90ae97fedd191518c262988c96898215c55397359de85ad65bf0a6ea58c986f382e0482876ba5b13bff26763bdf54e9d0715e49b1cdec6ace3ceb6f8665323cd75177bdd267dce30d715fefacd5690e5c99e1c3f34e2e3745d4de41b6a4c160f66355b2628471420ca18ab79798cb3a20632e1aea208b1fcc049f165f0f895ab60c44aa950b4b98e5ca39e340511eff2593f8e2a3f30979ee5aa7440f3723a7b0a2dbd6ab4720ebb396d28257a57022e9bd7eab986bc89cd31b36161ea856dfecf2a05977e57bbfb7e8b50e5116fe7aec5254b106d2f69570a79749d2db4505a70a9ea0b5185a6861027b1bb4e05c84e60b7d7e0b69775ce98b6a13e2c36e00c3a1d90665cd2ed4ae07c2cf5b765491e9276dad4e4ddb0c2279547dd5ecc0a9f49d937f28f8813bcd6e55d166a48886b19a13dbb681763561db67df7ed18bad2d103079b274da0df1a0858bc61ed0562d67045e9d07c4c41ec7ca667070541511f0d83cd4cb786c01a1b666a31f26133662f8bf9495f6019b0fdeac8da0f39e5a7d3f7250fcc50f4c5e16f7648766965850cbc247eff9165180002251ddcb2aa5da70d6a42cf76d538df8be2a429e4e999fe580ee8b965df25c7b44d062a538cf13c8951bec8c365173dad40602f807a452c44401663bcb1a2091c3036fe5854a35b0e324b3b941d6d6f10b275e32394f1352b3fbf3009b1e77055717ac302f1c0ffc7eb035b38c7b3537ab5aca0a878127254ce8a50ac663966f1bb0d38467d341ead5d732f23cfacc62b119afbf14f0521f793d505f9a1aec1a64368d757102b100e7731c54333932f21abc76f603b4842f3511957e4d192d5adc56eab1205ab4446e81e07de9a0d8c7ef5d9b101b9e8ab762a2814b8fd16dae8b23e1a725f289aeff1f075d87ff61ee87b4b60f8a16007d9d103814df0690650ef6dead94b659cf32bfbeac8056bbbad9e4a3189ec7e757029421a5275749463274d388315f066b1d7846889c024632b8fcc6c1e17d411e6e48eb605a4e04f78dfc072ab884d828e6d7c83aae4088d31957955808c1ed19a2fe1a717f88cbd8ef5f59f958a582419e5d9ea513f3b0a3e659bd755b0a57efe785688ffb2a9e139b8abfbd7f759376e356341f9efee0b874c01ed70d9ca48022a1f532d5f7cbdfd57fe98cd40642893cbda1a9f1d7ac64a4b56552c40dd29e15e3b5550a2ea7e08da86b40bcc6c9786fe5ee0d2103cd55e556318fc04b8bfdd20786ed6753d5650457fadad6719ba2771f06247294fee46c9c8832a4f89716eae6d3c9eb7dd7991385d099066e75eae941d27d26e8adf4525d832dbd7a0d71a0000000000000000580521040000000080585dec1cde34d45fb3d9987885a0bfea94ef919451d117256899ead7bea210823fb0e87a3f65ac465c57a1ad7a784ffd7ecdefb203fcc72091c557f155b278e9359833979f36e553865022e4b0d284ee7e3b4b1a945748f98e582a471db263000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0ff95baa3af710f430e416d188a0d833545e30b8e7823a8e5a0867b5bc3a35e1f6ace5dcbfc65cba05da354e8ded3cfc4a0856da0564e80b2c81670a2e68a3135f9cbf82fbed7260b9c8b443f2c51a3dd161a781e23e517338fa67ab83b0870ff1aa7f02e5348eb7d78322eb79940def930b4bab729a6543082ce873eb75230319f1bfd47f3a9d6c970a2080fbb6f206dd43427203bc77e3bf0d95e551eabce60225a15ef39020d274d5a3725073be8e1a8edb0d726302f326fcd123cef3fcf65c0a00f92b6b9a47e8047922a490f4246622e3b65845f51497a3d2ae7c3420b1e5552556265d048088912b5e82abcad74229c6ab44adcd1a0813159dfff1b0cc50b2021545d872893b7a1607e54c00899a787ab7fb207bff9752bcd3c34bd6bd25fcdf03106d5480124035d26bb125ac3547b478193b8814c2081d2e2d05782e732a45df031f85256a350c1cc88de80870c9450786ba38d78d5207b94f8d754be005df7ef40219eb8dc6a45ba85b69a95bd7be43e93c3485c95547809ba49c6681cd33a29ad2022628e9bdfbafecbec07487dfb9093e535505276f057cc498e68706734d3132f22570b97819d5a8ed0d5b7c0dc5f38cb773957356449c8c553cacbc62c4cb1f24b150bf6c9cdf17089685a23a34e569442385ee41ac5439ed52aaaa9aa4e744d7f54b5d30d2fb5c01f12fa181bee5c7dac32f2f6f9b824ed73074a55f6b831f2ea61c9b99761aa179f453bec9cbf72ed5f9d44ad12081a0c53f866dcfff6b62cd334f122647b3946b087784aca588a268e35ecd277af6e8db0ef66374e42a87ea45a05c7d8c5a43fc779c43829aac21b35e8b694f2280de77117883ae89364c0a7fa00b94dd905abb97500973fb5374a8df1f3e271dfb5b34fc8f5e0845fe1d3474cbd1d196d5ad0b8996d8fb149d4f9130d3931a5b4b91d24b2e5b4217110a0ea8e4b00d16e866a7bedeccc325873f6f28822e9f1c2bf8a39ba4823896f7e241a7972748c0c264966d92de07b5be2c36b4962ff052d85305447984467ac904fdc44752808eb57d8820cee57ba46b5fd79d48cc96854eafe259db8d8bab21b0412af66750deaf4018280aad9bbfd296b466cec89ca093de0305683e76899aa7ce13507e480fdcdc525f46fee5ab4f609a4e76802143d152ceba5194ca5cc439b1944254beb381b3640fa7348cfeba5afceb86f9ad396631984ca9825cf53313291aeb0797df42558e8605f081e7f6bb2c77d1168cf4d9c2763aa9601aa70315fe27a4fcff7805d813dea5c903aae86f2c340f3ccb009618af27f39cf92964256bf890604dc2a27daa57f61c84ad84f35323cc04f83568f1b6935c9e00017a11fbc907847824d7234ad08f5e6cf9e3ce31585a1dea70f0729bcfcedb1779eaacf9c7d1200bdd23534c773473ed559057d377580289e758d6c84054eed30b0c8973a0b2faaf9d28d7f67d6e7c19e64cf19880088fd898da0f42b124111ee831b24e160b4ab66bce2c8ad97cd05d10da26cb67031d23728088d84dbc712ea1ed1503a93fa928e2b32cd3b814de4a975a06b98f4481afaed546ba8ae8d6be7e8b6966b09cbe7020fe65e0ac1109258adebfbd66037207086107d48816b5e6da1db9ee9e7127374d8e8e831f0c4a67f8b7160662d0f741b9210d61c7b191810f78cc64420c20db87fc713b7cc836f81d7699a87361ba22754271560ede23e1ab57fe812ce36475013b6a882466de8e90a4e2971ef8fe74b4bc61e234569f81d0f6ef05292524a0b5d2977b60b0b3be7e4bc77da03d97c600ed60fffe45007e395d8e4dfb1f7cfda467d2a892f051f64f7685d30006b2ebf48282541bfe141438e22c03524b6b74ad0b94de471287b0091fe8895bd9c3e7311bca5d76ffe15dcd1f029e1e4591c927b4423fb5fd62d8457e38e67d782cf2ceb3597f11c1b327d5eb052e58eccea1babc19309d421f0685070271de5c51999c87164dfb751b45792a3535a1f01e42c7c053822b3ea5872374ef62e15847c4c568d1939622e518c42f4b06de1c3c0f56336737a27205ec251d92f14f6dcfdddfd8866ba02fac6722378d1be54fc698e2b1f6ba4fdce5f5dcf6a5e2a78a5f4d561b845078587470ad50dc303763440045e30edaa90f0d50c4d0e0edcd4a2e271ee9696d0623a000b5056dae69d810ec52132e8dcfd754f71786944751ac5671f97f71ac00ad69b21e0b5d32932de69cb5d9a0e937d8ad8fea4b05dfe828683f0d102bf173e8b52d28a79d89118c99c0b70b3dd3e136fffe73457406e84dd76f2c60de5c6225313653fd156a556a696ef253b2f6ebde1b1e07fc0c4daa241d06d8991be789f5e59fad606a3c0263a302f41037b5143e119a0fbc9d8d814b54cbb7f43dfafcbf56455e95e811c3073d9e8d62ad56a0ef0d3fc644922ad907", "", 0, -870437408, 0, "0a7b28d3ffaaeba96d2fc41128a9296aedc4142e8e8733d45a9f0b24d8684bb4"], + ["030000807082c40303a7d7a973cc78661fddf6e34a192dd866854a14cc5597095428957b15fa53ff030200000008650053ac6565ac6affffffff0f14dd16f5f11a1e3aeef65be0bdc3c4b2470aad3c9ee2472f2aca55ff56f53503000000096a53ac00ac636a5165d746d46b1af61453c08c83524842826218055cf99810e4b38243d890df8fb0ae796726d80000000000ffffffff044c76ac0500000000046a516a52e2f3b802000000000100c4807b030000000000408e5b040000000004526aac00000000000b3109810100000000000000000e758e0300000000a050037b6a85aac738c4d81e82b72bd3a233aabd870cadeb6cb8f7556ed03c491e399f2e76bc869b1241829f1224ff843b2f8bc4b489d70960ed1e44d4044bcf9eb5172071c4901f041c6195aa6c2ab9d6b262c99943ec5d8a37383466e3dc7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3567c5aa41a564f409c348474ca85502213b2983d2de3e932ad366582a281a6c8996943d987c1472e52b453376b54f4033713b3a84fb57ecf336516bf6a7789554bd8910e0b735073b44e10fa1cd134f6e69e0afefd8d3d04501f7643c6e356bd487ab09094395516f2e89e4b46877651c034577ac5ac90a753aeaca793466e032ec1d525073e8fdf5be82434b10455ded1532fbea8e731f256fbf1aa63a951e3032b62dc4ddd43ede4c6401e25ca654963b8d138ed055d173d6326fb77872e74400b072dfe3c5bc5484a22465054f34c82591af8e7364503243aa145acfeb27b5362d2acbb31227af47e41d97455f5e06f288c89d7204ead8020a401d14703b66baf02196a1051605aaf57a2bdc26468c394e0acd3c91d6a9b622a5da87fea25841f8e02228d4cd6d7deeed5e802c82d5a26a241b91030e9c45572637ed317a4bc6074aa0304a0a7fae4d92c5261eaf05e91f9d7230129944f176a12255885a8af8c534d670223e0f9b98193cf241a8f8b4b6d6a42ba6b3a92eae80b7ac5bfbb159856dfdab303300afe6d9bceaca0910ffd597624e17f0252ffc049922bd6090a6fba31c0bfdc2bc3194e5ab9637efdaf8ba5b27c5076903321c0420e87eb048cfe68bc925bcc720d80086a6e271b345f88342726c77c9c97e98150d6d9c08ef184286d7a23b27550b8ea906360008a9458baecfbee81c98e54e97d5113acd76d027671ab5d8a93ebbd45156e3833a24a376e55611b54ede77ba191fdd97cb476e9687d732843f63314aa72954233ed7c98e577427e2ee6c368f9696111248109539af40f084c69eacce81c777baca51e71a5de13fed894e185509b62f89501a4fb8e2e5dda821acc0dac963f5ec22fb6821a0726070f38be4a6dd16389833f1369108d4ef2543b6a08bb200ee91e2a2ec72b31313244917935d5ee7f9b7c7cee3026f0c4ccc6851ad85e6f5fe878de6a8d11b0d873c0d8d98834d7b9fc529abff58f3dbafa9c3c399494dc0fa30d8e577700e9f241fb9dbefc4bf9f58fe5f41e0055cffa309c1d3361d486f4ada5bf50cd3dde9b20591a268577020d4b435170f628ef28424d8cf9cd25171cb218be21b076cb7f3a7d5dcef3d86be6cde9dbed706f878be65688c2715fc6ad46b2af7e4ac67e0b10db8f7c97e96398e4eabbf12fb0155984738df3401209ce321ac35904d757b7c70e0c701ce80a14d5baf3f75505361936803ef8e3539eebdf1f2e251ac085c2fb41908b477419adc74744974b0f41f45eeff9560da06e0a44a74a0720f30ee4a32dbf0f7037c4a6d79233f8881b4323fea2c9cfb8a2c41dfce4282028252123977cee5fc6690ee105fd8605e2289ccd369d77fe831449d41d409fb121e9d8e6dd7198f710069acdd735e903c2c12d1ce8429d11436d1dfcc34f7810bf3bdf5ecb25af7f50330c26d6b31a985cc60b05aca8500167a103b43569bdcb0fd2b6ad24f845aae9d6328043fe27019791cdc434046dd3ce1e3e798b8cb91d6eb188447193ed58aed8d5c3a0f0e3097a493baf24a87f5d6252a32781dfed376d5965f0336bba3bab8fd62a9a542972d93998e09056520c670b375567065303ad3e8bcc6ee40b448c6d554d032c8ce3485485f52aa7662c1022160d928e41d1162d9fb6882e4f77886b28531f2d6889c330d6abc3ed26e4a1c51d0c6f37b6ba24dcb3a563f375abf6430f6801de1b28b0bbbacd2ef47917151c4ffbd186aff8a83524e48ed12f586f67e880394dac93a1818562b2bc7d8e15a3b3908e862a5783781f66d3645b6c31f255d9d919ac77613613e68f0ec35d42b344a1f0a2508472177453507e2a77ca94bb004b610b2cf0a37f7c140cb8489acdc146096b5018abed82b1a0e861a7a1e12c49cd69993807644cc67105cc085754a7e571fc84101a9898f84e53bbd0c198df5d61700a92329bba145fd425752956ff4565f38eaf51a03c39830b7ffda68bce48b016e22ddca326627ea4f13c3f64df298996a22d2fe2d71c6ef73240c2e97b1a6bc0a79de95cb0d54af0a48c53f0a19f49c98b36312e547a67e78a97053a0ccf68c440132d120c607b91a50a8079061a01c3576166c9081e385c5d0991822664240c64e13d518d30d4ddeacea4b6b93924c8303c776322f54e27f90ec8525340790d5ca0b2a101fde60af52b3378f807b473b80ac0ea49bb78cc8d796e8b97588efe2ec2854964a139a697f326d5b5490fde6a72621cca08e7a988fa5691b78cb2150253778f741db384bf9d86f56fc8746c77ef29b001a0fd409a2920317bcb5bd57924008b1face314da9a111c98068630c1f76f2a63e9a1a9c246a01e3456359d5a609199f252ca5481606423c3d81af8d22ac24a4bfbb5d2587b7276df3661d9e1a21df84b9f48e83f1cb6fcd4921c471b5fa33cfcbc5e37bc06", "656500635265ac63", 2, 1899969149, 0, "0dc177a37dec5bf20979d01a7662513f1c8ddfb06122a18b1320c4ae834fb09d"], + ["030000807082c403035ad8e68d9eea428655adcdeece176d5610b95ac0c144c71ad126b13940e008970300000000ffffffffdea80599aa8b726c5d641282c77870288d53800aefc693cea04690ccae9282bb0000000003636352ffffffffde0555789c468e8d6278975126e505a6a56b2234a10227c3144c98827bc149fc010000000665515265ac522b2b66fa04659c2b020000000007510051636551531509120500000000040051516a1ab05c02000000000151d966a803000000000500655251ac8748249c0000000003c071f001000000000000000000000000c3588b95c920c339b251320ee0329002d43e8029bc550ddcbd2c12b0c6f39384842df08c2fdcd6a6805e6b44af1dbe0a19a483d5075e5bdc2737c8269bd4e981eff468fdccc2aae8bef6035f400f5ee1b564d20550b2f5719ff49c368dd068b700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a1119cd4e24679c5f81cb2bb4e78400f9d823fd81eb650db7fb915e2027360c8c448e95e7c364c1d4a41ca5209c81f364e59d3f656b26ecb8a058c66547902a799e4ea2e60cd79aa4cc42a3fcc747336d9b6e9a90dd6539d4901839e9b8e2d9fb3a0795f10ddcf9d2a91b22ce2118cd0232345f95ad86f60ff66a47ad38b1dff030d0216dc15b809405056e4a1ba2f03d17e11eb9fe3705769fabe90ce612fa74f021b5b1d95e10481b26e33666a6b5a7dd6d16e99cfed52364266bc6a5d4d8aa6890b0651b66834c9bc81425703b794f33d0b48bed49bfb732f95fd4f51f246f2105f39f92af6e9e0948b65d58e6a78f780cb90003a56fd9fddbcaf716d83998ab1ae0319df2ca9f0c3ee14b5b138c1988145a206aad00a93deb2c9e967a82bbdc27c98020af82ffb667798ecca12eafb82ac4c54532004848e7b78795949a03c6684ee2c032f64ce9a2add431d13504bc550dfd578255f934cd70878f82dab4d8ff4a12f900221a0f766de3cbb14f9d89453478e7055b9e717489e9cd72894bec73491dc3df8021196eb5acb810b32c5de84f546c072716ba54bc963589423c41699e794e50bc53b46ff4e5e67c761056dcd0dc5f8e3815e0b8b9be8fae44008b2fada95ab5e3e701acd5bbd71372272af32498d2b6bf202407fa11d0d5dd739a9be917cd4a9fd17799059b356c10034ca0beab4b76d12e0a731cfa01a587a43ed2db143520ad3246e1ee770b58956ae322a3a36481f841fd5102d7950fe135a0ebec465e26efefbc242d9ff3b643447aaebc7290b919b7f5b7742d9192e42db88c8e28b98dd9d8cc75f8eb8c03d83065ef640d542e8da944b7bb25c2d60554ded6611e1e40f6dd6e44052a0c9d9e5ee0677433f55f3add654c501a9277607f3f158233c006615a4f35b8aedc3e84f8afce5b3cd214ee239fb396a305bac936b3c6a7bcfeccbcc2ad7e7cfe27c348e0cc7fe73ba100bd978658d49fc083ef498aa6bb9dcf1ec5aa2b91b6fb3b0235da0d7a68a62b27bd3a0cbbbadceaaf4d3cb1ea892fda8558ec016526542598499fe291f0eb3167c74edf41564c2b907e9b22fb91c72c9885d72612e64396843fdaa27fccedfc04ba092c819996a27deb209811f6ba20ea1508532cf6188f8031f228bc8d5175820494efbcad4d14b09f35a69f91de51da017c68900f02b4139d037b8c87cf16ef8067aebd3415cd481ac980b18dd01113ea322d860db334f12c7c8958ed35d04629d53e4b1fa5e3e4518ac15284baccde1b6b44776638b2359343235b452840b0a1f4067ba64706d51f179f078e1c1698610c51ff8e6b52ee3c8b3669d7138ad2b42c1f7ee106f715ce2ef55e80a8a18462674bd7cd5ea2cc85d40fd3a38b0a0406d7801b2acd65d8e74eddb16eb81c5afd5fc115fc4c69b2a3edd8d6b16d1c2e033afcb802c441464f8e3f58e53cc136115eaceeddd8634b66a0be4cbbaffdef9baba8ead7fb9cee38c0b2f3f26100e0b6135eb1c3de1d91a37274787c7c9705b39eeb4aeef91947e5737bbb01dc5f150ae117194f93c18b4e51439c3b70f1adb2c6848043e5aa2ef0d90c9cb3e0ca3df859a85313e32a8b345f04de3ed0fdd1992fab2f776b05670486f06b690725ab09fe92b45135d9dd30f282abb67305f91edc9d529d8b84810237de24c21440980b9c43de947d0e1f54d9dbdcfe4b909b352c4d33e07cd06849debb4bf9d0d3987a933d933c4a0ffc4824d8af6ee922ac8954d826f16e909c4c497c7d97f33bde62c52531c8f7aaade80076938609c9a28eb3ab99d04f3feff21e8677458b4abb36ee6b5e0359e6a94a90e4417d329d544c98fb6dd917fe198d51809d669b839ed9aac96b0c9f4ec6d7da5c4163723c24e61482c95a47bc1c3e5ec8f3fe9496f5d4ba588f570c318a2b49596ee48662aa2b3a1d5f6e36d5d251be898c981cde1f5ea780ed356540a07e114820fbf2a713c2e1aab6c327ef22afce3cc6dada47ee3f8a8fd7e367bad3d14dd7c6a674eb936990d26a8018f67e855285dc6ad14b7025454b55aa3457ec11572fd0521fa7a1505241966fa145f342b2ac1810c33a3d2b6c40217fe42b89089260489ac04f0a364b4a13a0ca3b1e1879f9cbaadfa34dd79f3e695ce27ff5665f4ee18dea30584ab74e07a57e628b5eed72531f9f29101a75e1bbf5b364f3487e21fdd682679a0581db567cb44fea07f6af44a11c9e2bfdea72266cc088a67eb95adbcce5a4d496b5ba21842115738ad08e5924211cd69f5f3a93e80b91ea5de092a64602b4ee119b24400000000000000005aee2e01000000002cf3c0b4d2d3942a53efc70aa12cf61452f0c692d24194b5e91f8a8aa9b20f5c532653d35797c1d6973deb6dcf65b889c766df11a07d83fdc5ba808fe14b8672897185a53d524eb9cc4f83993fd1d92af1dc133c1aba9f2a7d295e8021b5720a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029f880e9b05e20744c851796300922b26ce9e740b42271e8602ce153598d867f4b6e12671e432e155850db06d10eb4fffed1ebfd5ba13be5594dd791a92784cdb662494a08c93f1542cf84e4711d27e4ebbb43dce2ab23c78e0938cd9a4dfce71e732c80bd870b144791db5a344f338ac20b7e8922b20b76f675fd9589e3025e0327bbfef1ef92c7dc387dd38757d7966387c25f869016f3680ef6c3df43acdd790302b059b2bc24654938bd3a5ff7b17c1f5b89b1522b212977591fbece96c7eb3d0b06d8ef0c4dc7985eb63b9bc54af96bf8f39720801270e700bd5cce6123791fd408db077e20bdca5baf5f462a80762c7cf10170d111ba4ff4f738d0dcc0397178020c54cf5c7128d158613964a00cce0050d00942846e4dcda54a52f1e0bacc9190020a0effcd753a5d34f5f6beb6bed9c49076601826ff5362b47441bfe76c7668600307c6635f4b59d68987015442305b6b84b1f184d6d09e5db543f2f7301adb591503201a876d24fa076968f99f65e6d95cb1eb1214e6c5c39a97cca8c9795aaf874f030c6c11518c5ed5b394551e6d88b01a33712878f7e9c3bdf2df84375f081d666dcf5ce8e1680595feec4a530ad65391b949790468c25dc15228a9a7a0de61f005517fae89ef9f34ddce32e18512549687f371ccb68349a700939ef407695214e799cd6ec0aa823cd2fa6006bb44b623b8260a1321ad9be62726b8591a7397b34c44de42e0dc7631ac6152de65887932d5f719e28bf62a5a09c383f722c9e8ce49af6993aa01cd2a0149b4262a8abfc55843baccb3ef072346b84ef1574d81367930ccfe78fa3a731d58da6c14d72a9f2884cbb3083e9d79b7bee092e22e560644ef1605507372486d074526a805c9d68be4ec54b4b44b0d74f223a112075689a72b4106405bd8d9d53ffef03a5ac5d8262c783a71708a9c826ddb59967e579ea934e83de9562d716fb1e3e3d978249bc84df0c5d07a460ba620b0e24e0f6da9dc7e9027f073b21337c0c385577e132a600eafefbf1c26cd31c46a8ce6805e9bb2570c2a56e6aab6d42fcf0ca78bff195a86757fc847b4e953f6f0e97a4cecfc540ee2066451b9f9103dfa277b13e4487b59bbf39341f7e54e806f4459787b47c3bb29858b375211b63ba8b4880d6bce55ac84ebee17fb1c00a94414546c9c396f4044902ec378be293c43933f4c70bf1a5bbb495ffb882655fe91a5f270eda8ff8536af97c4a58f75a4008aef05f9835edce5143f697c215227bec6111ccaaa841be9426e70dc6c6719266887f5b9c2a3ca2d9f076a921803c521e63e496af6829fee6af95f2f7097677b944a77b4ed7538713e5ec098d2c973970a424ba944eeee8e84cf23b7f04d4e9a35c367a5d5d9ba61b0e8784cf60d2f3a2e361b5a393959a2e146009c72d1c60c2739dfdb86278975f1933089c3ffca5595dab59a0faebcfb132e78c68d1291bbe22ff5c93ca677d274abbfd4caf22bd66fa48bcf4c26b15c6fd4181b66a60ceb353bc93d81b48abf667d3c7733bf6420cb5801452b9976fe09dbe91a9b9213336ef047cbb0003961cf800eea22221a110eaf65db96d32eac912931ca15bd2a952546096b77351e45f954caf6fe299545f3e4675651d27f850917d4a712549fe2ece9bd920d7f9b8d1b350b5edc4df729756acae69b1835a53f111016d311995da68159c7916f66b381d8daf03f610fda6dec247e4d8024e426f9f70bdf30e3469c10e5e8c78559ea11ed41982f5e42b437ec0282d66665299f4c7d5873022d9d122ce40198a6bc66563a50d723fa7a6f324afa27bcc317c8c52632e1d391834b36d1c34b6047da6fc4ae21088e6cced4d8b16093c1c1d0d9e202d706c7493014e11a1980523f9231f77aed1ce04375ad84a54df81a64836351d504ca678e699d98984a2fc25608f846744c610b957e99d9bc5aca35c7761e082d006945b3ee439d98515a1c2d042851d4ea6f5fde15499e8849318f7835bdbe94948d6651d11a054e71fb8712cef3178e3035830aa9486b8951c6fcbbdd7e33ba87185c076d94fbf70c6c7de65960d470e4913e09dafca14bf71f89742f330743c89b28c0a60110de08390b932104f14fbcc900d3b9251dcf5beaae33f1c262ed50337e5776b560cdf830a2eb5ce829891bebb8c3197b386f342269c7e7aa6b9764971fc0ae02799ef9d455339c85b75fe460933f86c7e748f7c2b55ca0dae199fa995f8aa3b523538dca1d4688ebe3f9664ec70b2e3125b95d9053c235b2c9c20a4ccbc0d0d91e3ab4a66b7481ce000000000000000060464101000000008b64ddc84f4af1ab4a661d1d76e5f3127b7853c549413253ab9e4ebe84d031b38e23e7301ec0b2f53f1a8ec340bf9bfc435a83766ab18d6b2a428491199f551c2d5b88bf8b8e8b175d4f164fd0bc55f82cb45fe763fa706c021576562d200c0c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003421d5cc183aea9973f29e849bb3ca2356a24e4ee93627d05285b27b0023f2136acdd3a7a27df331fb3b1a2732d676b16f3a106b42ba5c1cdad0e70f20b2b6e40c1f6b3a67582f97e606754422bdae97ddee877bfab531bf9dd0c87ca0b2574c20a507464ccdefa60dde446633539aa303476ed1031619d0e98165da84578a8d032ec4869dcf93c651daba7580a8c0c4ba0f02d073311109c1308311578d30f6e2032b85a18b8fe9abde8effbb7c6f97eb28f03ddfaa65115d39530fe7bb5af08e420a0429834469dec43d197fd6a17c1e571beddc71fac75aeafa8a3bc82d2d41bb55ecb31ef3070e302e00251cbd38f7ff9d471008d280384f3f35e2846936e08ae40224f12535d2ab3cb0d4c5391a66c69d38f8b564b582e7924a5ae45d2af2491ceb0316fa1a8b07516b79d806e42d59e402caf2e4863f05ae9929ec95691e5d7de591020154ad5701ec70f286e8281d4caa3bedbdb5bae79415c9947b418e9a5a411618020520c819da894326ec6fe629241044e8c0d1a3619a0705589e5b0ca48787b5030217ca7f8999cf8410a400b083e8b6c1a4a1b52321dcc68e321c69a7f7f06bd86317763be3cf92b7c710710be92d2abca2eb1ba8ebc01615c92c7f6ee1279da0836e36a6e2311dcee4ad102554b788c1c61680b1e893c0728ac7aaf06e68d95ea6ab45116d37cc474af1287ec62053b0b3f2de841a68d29ad685cd87510298aad1852bba9dca4a4a0c80ad7271aa909f6bf787fe9b4af4447e2d13ae8924be8c65f4ecfdde3da95a6c9143aa352fd94366bf3e8217176f8f4bddb94a857f0cd64444264ef416f637fa92b531aeb48a50d60293b959890ece21cfa9976e69e7f7ec4430646d77e1dd8c2ec457242f34d43b117f32944afbcee90c2149ec475473bd3355d1707813e09d6fe9e00299a2cd94a8fb08b8991eda04adc9ede705f3ed299100a73a1ac50a2dbb2ba68422298478b62d72ddb92f622f32ab80b20ccf5495d7b9d54169e5368509af26f3f329e6f37e232e6884c208e78d46719c870c41bedcf02c6e7880f1fd8765ae1fbf07e647ea1d522627f0f79e808ec91629a169a792229c81a7c27ae3cea95be55697a51ffc760767e8f576888f16ad2840efe83b999ed6373ecf635035992a8f3e7996d24fdacbf80314252131583d8c79b8004c3f33c41936b3225a7037217c8c75581175e90d807528987cdeb21bfe4510c95160260b8ef9b709a3a8fff6f1c0404387e4a6a60bc89a93292b248e8c6fc0a4603d71c766802cfd2d94889bbf1d377dff983e78067c0899ee277237072f07fdc28879fa796e8c390f144761988548a16f94eca0e4ac9f4679593a52978b6f87e8c97e2e324d3efffdb7a06f3de6937541b64168cb3884892faa517146b34db8c110e507e2b8b9e5139d7d24337141682514ade55ac3f60993127f44723bb167a43eb468b3d1aaad76c11f1bab47e0935cc63a608b981894372e585e06b72de7e59820771fe7e76f6c20c29a44168bd2a8fe87a2642388bef3fb5c3c1cd4e2cfec9913272090138a6c1cab12133e52aa11fc134443728e9d0b63e69a96b02c9f60301ecfb63ca569b5b5af678392f71e4c049c4c9d8fc426c700dbb6972203990836e0b322d3951fc8d08df14fd1c5586c079d450f4a438e90f10851bfe34d140d8ccfd5ef691a9666db6ef8fe13553e384e9205a26c7ce20a211b203a432bb00d2322c9cbb7cb90c53c71942d7138fddea435327163c4da0498f3497157ea1e3d0dac56cd336778d98ca7bc20e61f368830e7199b9baca0cfcfb1a7291da284622b6db8df6afa8af98aabbefa2abde8cf12669cbaaf0e5bcca1569c8188833873cf10d6324976aafd15e3f4b0e4ded0d88a025d362c1b19964a6fde98f1e88900a2251105c2ce9d9358901824be9773ea71a104d2161952daf033b60dc81626c34b0aa44964f7673af490157cb8eead5c6af6ee82d75582b805190eb6c87c1197397b31ebe341b55ed7866baba0ea5067cae90c4e4565da597fbd4d850baff360024f4a331e0054c72c1b36e9c31a1b3e1df582dd5547b7503be946a094d8cecc67a665c50ef17758dcb0f3ddff3d0ec5ccda3cf2c90f16ae15cddbc052824df4fd3667b1f1a8d747c84621edb6ce6e03687844ea9586e093705f0ba533b226b6bf89bf2f508c8d8b8a01208143877b2b0eeb88f14b500a05894f8b4eac46c364712a7688ce6db181dad810deef69382bc1d2382d1dd162d3a5a5b83706fdc6191623215d441efc7eb64fdabb2551700bdb1f6a7506e67fe049cd6a7cc6d7240f63031a0896b0375c32e0e7bb2aa1dffd949c99adf5eeca09f90bc0ff6c8cfcf9dcc4c1eb99fbe90f4aa80af89875c1079a271c92f4891a9ae9e0fd498e22f5ee88b716879ea96c062c1b0815d98101a6c70c", "51526a6a", 0, 1183303914, 0, "4e851ce8a95bf387e3d02919c2877155bbf3b25e3100378ef67ca0ee78e979c6"], + ["40cd222f0167087d2711273805536f93358e161000d5b4df928934d4e08832a91079748e5400000000055253655365ffffffff04affce600000000000563ac635363a11f430200000000076500516a5363acdc787d03000000000400656a00831795040000000007530051ac6551630000000003000000000000000014fe6c0000000000ea5b779626c7fde08ddd5b573a42b68b75049d3f1ab3adea72f7d3fe133491e02dbf529aa71fc505b98f335cfe1410a0ea4432a328548d253c2c64aeb70c38a6f6151d60f4035b8ece882dd2ddcd5588e2cf11c3469bcb0cf597f248a03b8fbd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b0904d72b46aa3ef8b24bb6b976188ddd204553165c28c7f3be6c2f9c32bbe84839ed0e99dc307e14c82ff731857617dabd07291ca5e14f54c3482d0db4108368281a9cde5f5466d0caa4179bf3c1414b89f5a9cd1ff0585b35389bb21118008d7e22903e2a7d5775b0cf92e65802b7010174249af09cad3e5abd1e031fc0fe10203d119ccdbd911487db248a332ddb99ec51cd6bda53f76263d6ed0e68d2d705f021931e0f99469dbf0ded6c6c8d65e8bcc716123ba08b11465a3030492172b9c150b0660a5184ec8155f26e5cefbbd53b3218a9a809546fb9288a3c32925537df8e2ffe2983abebc99d8f8c7bfa5d722159edee649052a4d5467cad96e9d27928c68030bc02d9e2aa22b178785a109ad59ce8db362299c5f9e9f9a906393e6f2ef6d4a0205dc86272b7bd303d5f8eef58cbdcfed51a7d90529e8df307e576e3dab9e6403030f185696bf5a7393f435ef9cbd863e758d09c5618ba4d49a2270db4a8955b6960305be63d9e666b4ec30f0a9d96ad92760c313ea6aea2896854f9c2cac42ad92d40324133693ae1be01607509c6be7f6d4e735e7b705112850b83d170cff4f0a3b28a083a70400edb480fe0c09821a7dd42e2d0c429fe30ba9628a47a4f3809bbe77aef38f7a78d9bcc05d8f136fd4aacebd3834ba0d684176bda174580eedd02e4dc3fcc51a06c9667d95ee3d24da47c2238bfe9fddb8968fc117b8d76a0454bbd8d6275ef08ca9659a1cc98588e571cfcbf0137efaf0b4efd1c26b4c25e9d6388abd2cd30491929a37033db74a1304655f4e2efa4f6166ebeb5834c8e4a67fb2069b7435c7d82d993033a58e3431079d55d924c4195a3cba6d3ffc8baa331856f203e28da6ceac15d5afcf7af25d45b36adf600086f9e6dc8a212f0a67982e994048292532038a9f5c2d752f30c6510f979f592d7bfde7902872fd475fb42bc736f17d8d122084446f106c097b5f366aebc2327860d432414f2b82d85e3463aa35edc76d7b108c20e37bd56e6d30d5b094c95255debd4de595b0ae0365d76596effcbaf9b98ece08db3213a617e3da55d32c935b767eb902557b072e56966cc634e5cd4fe07cd582e3f0b4e6ae43598d8792dfb9b9f34349958f93477393c4b5426e39038f9fc85ffce279cd6afda3c21d3bd9a95eff6a224f2dc41ff138d43c63bd9be7bc0399ca8aac147d286f0f3fe27a06a9d72de921b2b7063fa3539462f287b99e92f22015c7e69c9b1c473e993ad8df53fc4630a68554808c44a250e2b8113338218af945dcf2323935550f55be032095d1f692df036ff2cb8ff7414ef4f218064dbfce3c18826e780c5223c281249db909883624cd2f80849be79a27b801e4d498fc6931ee36bee705e70d63c8702c9cb58429f28c4ea5eaa51d51bbc71365870efe97446dab5cb4d3c775722bb19777db4b206b72c2a3004c9963cdfabdaa99a4c582165ef20ba9dea0f1bebea0b29c073a20d7beac6a39f16f00dc1191996084da8b892fde1c3a400e2f0535b6d244c2d9583e7120e3b2db290845e944b9d0c462efe6799769d1f9d9420a089b5fca60515aa6b2d6563951e43fd9a058493b66060dd1f77121749eabc314d44d8a5bcb97725afe72fe17f822f6527d9809fd0b17b5992eefc8fdfa84408b23fbab321df046ce2a5eaa338c1c6601ae1317ab97f36847727a72e758d4bbdf20b7155b5b60798d360064f38cfa9903366ace2ead599e21bc015dcd01a3f5b21d43c66fd5bd2815dad56acce77207a5fd0454c68c0b9449025f414292951be02ccd6d5c3538f4923cf4c3f445d83ab0d8fe1421d117ffb0adaea73b87f5d4e69d52212d9a5e17edf3cdcab00a4dd0d3950b517526c4020ccd1d70a9085a460a7e4b46f0d59467ae72be742d3ff5bdb63c6dc0cad6770cbf620f06001801c1d6980023613aca2fcdd2ef6170e95c23ec85691bdc12be3d9eaca0efa9eea62b8bcef116ade2f68ce8ddd9ef2dfa9a20c6c86ee59c8bc619eab07f66015790c99dea603ea18951a7d02ff8a99f245aab86b59f4e8efd0018d96b9cd6224f5a80400bb7bba8bceeb403ff31d1814f69013276817fa20817402ecd8e63dd9f30512fcbfe3af199b209d5f896266e7e51a0cfe7fcf76de1d567714ab9f0045f6b229429481a5b43f8782974fdc288a397dd7ab82ce3d437528bfab5fbf2dc1a3e6db466a76a51abb28622b4703f424d6ddf70d1edb672f0ecbf557e138ae9e74360dbe5a07ba743306a52333e3d86adfe0195f1ceb6570b76569bd2fdced1d759276351cdf7000000000000000003f49400000000003755a06265fedbde73840cfd6efc5df04ae3fbf5afe63db2ca6232743bbe65a597104a8814cec43d2db95eaa19cb190bd8362650b975106a8d2dccafdb1fda559c2a0d78848cb6ffc4666ee10febc70a685ec8d3cac215bc1a9f55ee153d4a6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000114ba3949c016b7d5d5e311153b376b45ef140a2b9ec793ba0eda7d95ed24662ec361c627b98f89b67ea4c2727a7f86a3dbe6075c3a7d3b7ee791b2696bbd1f726cd13419d7bb81d145c4010ae93b8699eaa5f2c92508af31fbbc2fbee02e840accd7837cc67eba93448dfc2e8126b062fdc2b860600f25a635179927569c4900225f99dab9aaef738bae2be546ae6d6b2295537071352934d5943e90b6fb4d76f0318e566b2629929d879412f360aff444bedcaca184ec1d188ea049e6b931bea780b02f858f7eb2f0fc8ad1385262bd1c01259fc75bfd1af8979ec50b09ae62c800ce93ac60d5b08900c0b304b96eb930215c0e654bb9312380c7102050035935b2e0312df4f315aea575d1893a35e4851d6ca3d27e6432f0cf9d86b99de26a01d057703145cdd76c6f39816fb6b3aadfb16f2c7efb97246beaf3610de6b09f239627a5e022930786d598fca07432c31dd7cf2d2051dc308daae2506253973fb25db8f06ce022036d2773f9eb0a631ea9ff72f71e73915235cf786eaf801e67d6d6fab301aed020f9799033f5f2fe65b2ad82ed780f88f4c72a57e4704081758fb65ce7f3a59fa1df120e2b8b68f0ec574fa18918a54ac6c0de79e9a3b3a3db22694f7b0f05896b258999b509579d2a005271cd37bc8f89b6f7076661e4e41a7c95c5998589b197842a55c58bf27b4d1e1ef01b4591a3b766d011bfb768abf6650092c4dcd22aa9c4461fc891dc190a16595acb110dcaf2d290ab04e2085ee53393da8ced6167bd9ed9eb165ce799dd6f051a99d24e96115c0e4e78acf762cbcca862d9a66b14a891c0cb76373143641f46e49c6620438d3184f9a56a3996f6db787f0c3f43d865d4db9a7d91c9ae0001325b7d4c0802d1336506e34fd95b462f95bd83e03d5d90c5c8e8d17c090c89d1b8a0ed9fc2d5591c21b4413160c3aa6323d30301d63399b820fcb15faaba840a39fa6f635463fce35243372c788f3cb2eafd4e031261ded044d5fa8fe092dde74dbf9adccf4feb2582e351990bc42a54ad182023f300900927002ab6e5011ff0f33226170633f22792767b401da6fd6613db011e5b1c0a2cb6c8d61c35e4f23947abdb736a00bdcf7401f7bbb1c165c0088fe2ce81b478037430182ac9d93b8ece33987353f29f45be8c3b9fd0f850129bf667642a959b956e208536e2c835b3ce94e3a1f34f2a60b9655ba18f0fe318a1633864905f7580e2a6c9748a87be4d70fc010eb30f105b0f47b01aaebc05c6462585a2c1e5211e8ef928b46cac3043848f2f2bdbbee567586f8d2ccbdc834b830676912c7d4d4a267bac8498d9b16b1fc81bbeec45c3b014dd43126920fb4be22dac0acf10d057f73030be2a30ecf0164ea6b88d43e391e083dc7211200c2778568145873e7793bad405a5c87a7e8cadf0979020b216403f2fdeaff85deb820f9235d587e47e2cbded957d7c00e0fe077df001705921ad87b363af1f431d540f01bc53324bf44182b90b2f6a70e253d20c6d960e6f4a0453d07d2001347e0b08ae9d4c5ffec85309fc204b0464dc7c9763f0098684b8dd70350b9effb2b3b197bddcad615e3ba821ad20d40a8a107bb680ca33c431bc14253956b23c6138ac491b577dc35d34dc1ee865d26b0fc0138ba00506fa1e866f50618382630f248296a5ffc770b9a67c0fd0c5cfc383fe1629db5296d3beb0a7d36ec2b1447c714bc7d3a2bc4ef1a302329bdf0203e9d8c0352960d9c42fd58ee7b7911cb477c7ecb8f175480c4ba17106c4863b8e00ace8f8c5a96b8349c134bd1a05f7a84dac680da62efca1efa4a947c16a86bb3775437f69fa7fa3647635fc469d54e55b8c3255696bf67823d0b2783db339c4635ce034f1ef4d9332cde356608439de077b6713324aa28093f4c66005cba5620fd03972df3245d0642f0672be9b1f593798837693fd03c08276137bb37ad1cd363f7c1b266c45b1b9037f5c5c0fbc01919e1e6662ba32b6872fc960ef318c005cc36227be0db4dd0ab7db2b722338ed65fb815ffc70fa133857d43c177f20e97572e4ebcff63ed8caa3ca250852fbe1bf793647d7fa20cdb126427250a46a6ef1942a5e680832d5103288cb4c06d60e832cf84be8db1a1c358751e7a3f90ecfbeccbeb9b7d2503e3fdf450c33a7aa97754f858b81ad7ae1d46f403980fef1a45d711943fb7552f1f462ee43769ad5d2cf309e982b7ba07e5ae148f32d827c88d2c8f30a6a0b069bb0b700adf3f2486b24f505e9fae0c7de128c1396dc9bec0aa47d0184166186fb8877a915236de020000000000000000000000006a8841dec34d84895bc6c0b4537b07148a929ef17208d0de517969558a6dc463c05c599d4f698ec9da0fc57b601ae5edf5fac408194267e0d871feea953c600eb5812ab75a0ad9d7f5ef30971a9d0a55b5c1740f289d1f295c5cd55b332d2d4d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a29e9bfc148187189944f1c8e52aceb1a10b0878c98b875e6f65b858dcbc91dc5d52731681e7209d8222c98a42d4bff0d592726457561ea95229e65caf0105e0ba11367b51add4fad5a1d833d2c53eb516c9d4dae1faee90dddac8c53c85a4ba73851800f40085b4f296285e5565d440c09bd1a496af1a6325b3a91d38c3ff78030f4ff52a63b6e1186b79836703165bdf834313815af842096234ab74326987d40328e8a9f0b59c9eee17bd0d2ddd306594fe4d5c42cd73595103a9813bde1660880a043002270e521eb2081f3bc88e2695e634effd87cb3465fb5a8b70e23f8eb62af0435e58029efb42b7b07b50f1e570d213453b7a0457191b083d22a12579c7090210e92fc66f59bc19872402c4939edf71a4dcf78a01570281c2715a5b1e1d72f2031416c71bf2687fc31c446864e00d31b0f24a6760f064e9ff460e5ace9e2d031102181e69582988f746773793236d97e67e6aea9e70d7d34f006145bf50c11f39910211743cc1bcc8b12f8a7f58ef678cbaf5e5f2b71b4893ca4a5c1e7e8ec780ecde02098e1ae8c938e383145b83f08f5a2b49e6f76f3ba6d41cbf4cc2465cee1ed9d0569cc3f5e0f7dcf8941c55e828ff1271b889caa042f7694e49a2717883f99f7572fcb3c15b5132307550b3bca898bd8dac50bac0e22cf9aae4144fe012ccfa0db6c271ce61ee34b05335cf82bb22091bcdd4e81a0ffc877c47feada9f89857905b617e1500ede01824bb6e84867a4a730de0e78188b85997b854031b08137f80dd29b996c50b2979e3ec5ad128d877aaef094aefcecbfe606609ebc20f7d06a2e59d1fc1fbda58675281e5c9dad100cab4ff06620ba39344a97fbf356ccff91810d1e6dd306f7b245dbf32aa80ed6690d1e6e27477ed008ef2f2ff1f344d49ad38792df9e74f470fd9a856f64e09c95304cb0ae3cdcf240bd315280c37a7a468d14cc73ad63e0dda1714241b5b5295cd2a9295e6472993955bbcb550ee85cd4700e311e1d4b6e99c5c5e76bce0f2d4a571d628dfa54f1e742badf0617a501517143685eb032881769b5e46ef1477d16f18d45b551f09c6825c98530dc7fc0b521fe8cb1c10005485a4d4b1f9fa310d465a1597d0480733a11bfdc83c0a8e6db8512e1f2dfff022ab1ad036ba2eb6555b1e6b9b8435068a81227dabb869a5b6fcbe35fd38692a562b09ecd776d47c15c32482000523f3d7b17160048aaf3f2eb9640c767b30738337841a629356aecd83fb8acd70c55c2e142e4296c10aac6e32de4db90a1cdbda954e25705a246a2ba93a7ade33996656951261f7d9b495526d1b02c145d1937cc4a8b3fb3088d9f05fc2562bcb94c87fcaf06f7ba473843112041e903b26d3abde05a2e45951f330bc1da759ca13ac0853f00a06b58613de2036963e67e2d68d5b5d80a0861d4098401343db01007ff5b24359ff8a658cf7f48382d16f6b0406285e218ef1e18414dc3f9721c6cd1910edb6b06a069cd2d83d6d65a9727ce5a6dd06c2a3edefbbfbd36b4cf6f71e2bd10e28757710cdf82db4058d941a6a2104b13d3fa15779d69498550f86fc03333b0cd9dbaa2e8567a978d90a923b66a383b0340f9ba8f38a2aa97d31fd1ae556dd8969f021d930fba51f74533e367058b884d8a9ad7faef2a6761eef94024af3e4454743840727d3afa3a733ea98a34f1808efacd1961b66b026185fc06efa2d81b53567197cdf0cd5128c277d53a203751fbc3bfc836c5c4a9bf853939631cfe605c547c7ae0ccb5e6203a71d29802d45226780f10f896f5435e47b89578052faec6c688a125d107ef5529d44056d50f29bec9f07920725a087ed6ee919b715c84af00c5c152673e332e23a42d449ddcd18b2b7e57755cbbd8c484c4de04cbcd78de5399c75ddc9094fb53ad7e4a0e0b762dadaa37a3c5eb77eef64238b0d153e6121a1a4c0e603fda500ae71cba65bc962584ed4f773eecdcd9d4bf5e3ee7be0db12d00294a27587e69f154a526eed17ee5e04cd50275ae46866197b0cfaa91f7590524d07baf7432e93ab6e890c758fd3f8e42e31653fa8b983703793d437b32939526cdd1ad7a764b91d1e21f929eea0aaa6575ab84ddd2b0fdcb2bbe9b56009378ee6f3ffee11925230b925894d783a305a66bef4c714099f32dd76ae22b37db85b922618cca9b4942cf816faf6ea2cb5d832bcf91fb7137d38e9172517a22ec3c996a4469ab4c1ba844531020d80d091141264e6814c0af2bca8b44b5864311d13a1c8a57ef0dd16f1e972e9a130bcf2243f8791d08b5250efc1fccb001cf73beb16d62b260ead295cee0929bbac96803d6dc82bbd6c4e3ae23194d1c7fc69851324a82dc8dcb239e59ac26c2c8497842750a4bf7267b8b9f4abf28e5fc732cd452017c82d1db1f30748f5668a32f59fe58069db605b3f0e02", "63", 0, 248378420, 0, "26a67be665be779e5e6e196556834efebadd1189a9ca43d1a8826ab6e1c130f6"], + ["030000807082c403040edc61dd3bd6b0083caffb31f323001fc26db89cb905964f2ee7b8be1823987c0000000001acffffffffa4b1a30a2bcd218f46fbc901697bde6dcb39d02d99fcf33b11ffd4f7853091c401000000056365650065409beebf984ea37140213b8f2fd99004f619e706b3a60d294f59fb6838a95fc8815efafe02000000055363535351ffffffff4b79f1884f81b1eb7f6c857216f44bffa55db371ad516a6c80cd678fbf9018470000000001ac34033f73035712a0000000000002656359827c0300000000010054bd0203000000000565ac53ac65ab1b17f60000000000", "535365", 2, 28371754, 0, "03b3ed9c981fca488c55780e5148382c86f0ffe706b9e8070c62412a5542d7eb"], + ["030000807082c40303550fb20b84e5be66c3332edd4ceef200e0718222454f4ef24156d1d977985c8c00000000096565ac526363535253c89143eef192d5fc1270b28a4acd24195c0556927f30c09532a691be4f6fcb48bf5219ee00000000086aacac5100636a00fffffffffd2d541dab3c0a63d854dec8964f34686bd43dc3fbaa36e3ae7f3ae3af86e13402000000085263526563516a53770f1b44024a2eb7040000000001656dd9af050000000000d41c1790000000000388d58c0400000000000000000000000052957a5c8f1009f8c0fe5b9042d8cb611d9dd318d5166df74678cd288608f3ce034a6e39cf382587bfde1c1fdd43e461de0b30ae52b2b2afa0df08ce299ae97be4c5cb8ea6378f20fe5bf690ed2dfd63b9f8b3f5617e22920473873289ca4eea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eec006fc3f685a069de52e7229ca3053f4525fcc8da7491f645f969159e5f029dba80bbb6d537c1deb3c38aa34b7023e9f4a52ba94b1df2935ac5215df34d24b996cf7213083fd6c213c177f655d4cdcf3872471679e95c8d5d9bcf89f9e0abb1ce2e505ae8e9f607c1f9a02b7e46452c56f27e41154bc323271155b47be062d021e9217e97ec73fce7255d609f46c2eb769db3a66cfc01f00d3aaa595798acae4030f62a9f620b938b1fcb8d5acdbc69fe023582762c6d94861575bd087c6ed0d5f0b07893ba77b2c11ece975213b7c3d7eb5ffdf21f6bdf5b8374b8e2d8e3f9702263ed5328d696e15927e9e5deb7045cfe482f4a22b2e92ffb4ce7bf7bdd90294c50311edba0767b8285f5dc5577bebe4f2f8446639fec72a351de8ec63a3629eebae030cac8bcdb148e1942593a25a72a3335cdfda407c5cd3fe1a09e946e0383b186b030ad72622698d8a48f7ca8b845905b9ff7f6d30f1130ef8b955d1f7fc9485e4ef020f1998bc9b3533f799016fdec9c98f68992980d7c03ebd2f09d974ef52e936e8032a6279795470791f18152ab0e65d1b0a7920ea205b3ad21e383eaa30c258d12ae11b50211e7616238ba66afaaa6f9560a4f1adebbb08df6884b6ccfd095b6841adff5c126158c20a7185336a3f9549d063169b19b579a611f026a5f8c28f41903e1c3b83cb231d52e358783159de5c0ce1cb6327aef3baeec3686c23d6302c14646707b8d39a487dacd0d944b0376e12435b2b86b9e33e22201d8ade1762a339f668cf27eec69d0de95706121a645a1c41c42387c241e1d97b284177d80f36dbfb501aa3145bbcc4cd96f8ea40c1b9d7a6375b9eaafece1cba619f59338351d10609c1bf04a8d3d8d736052a105a6e86838148a456e3cb14783585d2319314dfedcc8890309476ea8b8791e027659f40fa7376466cea5857d011f20448821316493cb3c4b4e174a048cf849b7a157ab63cc80e24e7b440c82f753de6b788da7f1af2445851f5c2b5cd8888291ef2b4eaf9bce3b70b23284482b01bdea78d8b39667190229c4dbd7c1af41c48bd3ebf8671040b71522d140037b756058a35a76d7e4049ee62fa3ca50d1b9c3ce9237a7ed2ac5e39f52eca5b3721a82793d172a784943ccd3a32ca7c35dff7d10f9e53660edebca4f5c1bec837d30151dce3f0f8811a5fffc042ad47e2d11a1a0b74447097f8ce69040eb8279f68a131413cc13ae3796f434e4f8c0b6d7be4c246e59142c7798d4dfb3f6c6437ca225dc6fe73bd00e66b0c480cbf4927084a27e007d06d50d4aaa1dc1cf9707b29f8261a6ea0ecd768e1c0a5ba47ee842b5c5440401d75d885850ca5be256e437514e7617f47c67dae36542b78a74b93b8cbcf295a279df1ac4a77d62eb147bb385dbbc46cba73c28995ccda4ac84e8d7fadf68c8b0cb048f93828037572e397790cce1b95f91cfad503a3ee8f8b2594d800bd839ad851999de547facda05eb2e25657996ae7272c928a1b8d0f5dcd0703fecef8f6677ebe8953277c67f104fdde70c43267a93390b291acc3f4c09b4b2af3356127976199885f1a5521f4511f8182f6d8669320506f6477792692c2fd4a6af25c0146006b36c0f622c6ee3620991ef137d200b3d9d150de7ab145607735ccb7e445d9884ef0ba30a3225ca6c37c1be41a2f82fc0cd234f2931f0a4aa8892f79cd93af6333ffeafbef7c97ea8de214999035a09e19a2f80c61f759a75c2e84b66fb1041063aff25638dcf60f74cbf47711b77775563205ab7c47fe9ff0fe29d1be0b2b3b225e35b7af94d0f82904cc31fe48d223516c5ad23018db13d567fca272969c00bf3d91498b92b502c6e1caefd8eda9432816d3fa914150b6830ddf6403819577b40ea7a9ef31cd8ab70aa508452615e07d0bb5ba12676997a44f5e7df31bad27d97f7aa96e837cfb5a95ae573812f00dfc472c5ffb6a9dd3bd5844f38a0e050c5b5c24996d945044c51f808f21ed751575f732acb8aba795af292b7d8c76256a0ce3f6aa27daa4b59527b1f5d84444a78d3d61fbad348de9a9cb6e5ae95eec9b2a1046d01be1d59e1b2e653cd5899bf9a3f64247dcd7c1d2c130b1fcae14f67c7eb2eac8a21dca405fd5150b5de2a4b9036535641b3a8b466e96e82d382224dde65dde3c9aaafda87a9994e5aa33eeb8a4527a7e96fe7dd79c489cba2757bd0377a7b89a977e6b0a11076ecf4b325328cf25e24eb9094b845b3c508edcf9c8b4b4cd3bd6e57b37e3d22a92649efc1b3c5000c020cbc40b0c88fd522c6544d8559e98f447a505000000000000000000000000e792e2529ed195aea70da99e4ab796630d40a0b71db87cdcbf3bbb1a3d6010db216fd864587f40fbfc74cf822e10c314e9727e5a5603d4a5a556e2e9ba0b122f531ea9263fa4676603bdf9a720a9af302b6ad31eb1031162e2b4e979518269c6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009c020cbd69783f3e88670257095cdfd2593d1b4e56e75a7489cb9982ee796d71179c921bb16ede68b7e29088ab6c6e1da700ffcd86602e41b8f21fb47bffcf9b94c1f4b8e891da61d3fdb9ea3f7f7441d1705ebc443de0e6acab6f89d0233345a29adec8b6da66011e7838f4425b80eaf47550dbc1071bda7b9ad4a63108240e021fef108fd8acc487c1e4c4f394a2bdfb6beae71da8ed5eac706f25ea220dc4c8022fdf7772f2172b1dc78ac8402708a8c53d6ee9c92b1b0d2cdddfd977e85a0feb0b07988e7bfc7a4f2ad7b703b36a5165efb040b240b8df7637d89e267472d0a1bd579d1708a9644f20499a691f16fc4aec84e151ed4369f492ec3af0e64c895d42030ae9ab2fd1351337507df27ddadfd34db114dfd4c31dc8189c943cd08ec85aa1022b4d77af9457d8d923cbfe8984e0c12115b172f91ebe7845189f767be359e8590315f30cb84615317d2809906deb469a81c886d7a67fce965260b93168cc81186803036ff09999e910e3d6357edc8991002bf0d401896fb3318d8fe4db0491987a60030c979e402550d7f44e8f7e7c2e7f89ac5e6d623f83d014ab6399ea0cc122f8abfa51555f7e8c5e7a6370934fceac346e2b77604c5a400e3ce0df5c0700cd6b9a375e4a95c0488a485a899b44d14466e42b6ff13b3b59d275fd4d9693f7a4ad660153829718415095310c90cea619058ffde9a990233a5f4f1f7b19a5c882417356efc7b05967dd70505db7dc56d2e8ca702307f34776b1e360ae0b6c01c6af7d32475a7a35d0c17bffc233ff8455a89874444ebf242eb00df6c6fb03e4f5b3215d19bc89d7b6e0b6deb65c45c7f968587181e0f047c963175ae1fd436ddf2f9bba9e866f19cc0011770107e1da46bc25787f6753bbe129dcb73b9e9ed83846441b307424c962807d779f863a2242f3d52f1898aa58669323797b2c7e824978133ed0c00e810327a14c1389fefcad4efd180082718423bc0eb60a73367d9d3b9bcbac7a5aef8a263a701349c0ad0d421b206bea54ced82ac6f2d59248cf3620879d3e4cd8e1a1b08cdc25569d0000fa4d9e27f6817bd762d89364f584f0bfeb95cfd1d5eb93211c2b3040d5cc9c431310ec3d763a8ba14dcdf638be3c281f035ba6cf8b417decd3ebb9c058a31e440916e7d6d4b1d85db3883021a770a8905b089a407d51a53e20a9de92c57b13ee751c8038f4940538e5c18d9826b922070f776558a2aa6ac72ad739c486d0bd3472788d2b24a2d957d9cf0e68398e5ecb9e45faae9fb3d1b68aad09e55250251eb0aa35e7357b572e5cc66c4a7bad8fa330118cf18b87550a8307e31d3ac8233e5097e76c15145dbfc524fefd8e5a829e53d60de006a7d8cc7b5afc709918d2452c6cc6437786411a4a7b314a3f6607fd9391afad4e8523808ecfe594e79957641770d987735aa076054a78ce6e496ddbd6f0fe4a37169a5c9fe2f3781ceab27113987c68e945d52e67254044691d85f4561913f801d65406465bf2a04a8f492d4ca4f0a86dad7d2257d59eeabf066a3aeac25e1c6cb0719c936031ce528750f94dff7c07470a2c7677606d966aafd8b9b1bb4aa32864e9b927e9c64f02ab5a35340751d36264ccdb204d7f420dd4fa000c6abf26bea6d3c3002688e8dee4d1c685a530180f4b8270454248c8f8f03ab156e3f5d3730ee1f0502efe1709c73e4219ee6c99bd817c8badf4a4fe78baea106cf92297845d5d1c9498ebf10da76d44f2469a38b5c4aa117a0d6cd4af6585c05250269d7a5933e1fdd1393bf04d38610d571735598fa6e6119c147cce856318690ed087b8558fb5004012b2947301c2c24be93aa090c902d2913069d78c1f784179e5e3ddfb48586126ff85da476fd8b349370600289e0adf22b86e3e786cfa9d35c7b3021dd6126d9bee4bfc431b866ea91cf7e7e9fdc0afaab17da27cf224f56b7dd8aad02d29486f4e4548cd5399a4eda4b0f5e81e667744e2b3102774db41153e87c6964b23d99f5fd2d75ec0198acabac7e210a8acf8f57007df3d3bdd0796f98c430735b68ed119292943bfa14b69c9d469463a7d8bded639d48ff861dfe82db7b225f16c09198056cea55073b4ba1aece337872601d84b9e4460b7cdfaf7dbd15dd73eaeba79d423aabf8a1ac23fe0faad042f3006f87881bb3df3266178973cfffdc408224baf0e99b164208b6dc5ea98ca489b95eb85d95f492b645fea27e14e103d0b26c04560d2f8e514c3be51e751016f7a394e6838313813421de21a4df530fc75301c8507bb9a97162691fb440000000000000000211df1000000000001f681b499411be50a04e55e8dabb12a9b430de40662c629a82be4caa2d1df7047c7577494bf76bbabe17a0df7e9c093a0378aa656c58cda10e56fa7185cbc796c3ecd573cdd3e2bed85c4d57a007ae3509084e565290c0d38bad549cd56d68b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006502c355164485a95c0abe4033237fe39948430b917f3e5c81ce1d0ad095162bfe0381bc45c4a43f58e4970ff2ecb5ab459fca7a7562f5469a4d2caa855a4ac4afc1f244a46dd8b8de47059801da8dd6807602a724d545c405b8526290a2aa0b75849c729a8f7f6fc9037583bb05e81d3a5112eea3d31e51c2bd600279bbdf2a0317c1cf0276027357e25f2839c614de72a0ba9cc37a884823fe13d357096759c003194b663497ef42a904dfd4573c74398cf9780d1290f8301078f27ef36ca286ef0a05655319e5be2a3e3d92d3d0e36f145fcc34562be45fa2ae58818b8ed11f3590aa62beb1244a4c8d2f1a8be9c1f9348733dcc3d537d5b4f19be7c59efda260e103250d60f713fe83debc9fa800d1e8c3f45543c084d035098542906d6cbf217ab3021674b83ccff8325d2a99a72b7f1df34640b0b12ab462f9542ab29114e5fd7ffe020069da5cb44302c2cd05deec8295522bf609858f1618679e1946f64b84cd2c0e02090a782607156731574ff6cd5e47f6d806b7a6c5b6733072d16ef3322bdf1419020e135fc65f160ffa1019bedd39667f35cd3fac583dd8316197e34a94b97cfba823b17b4f2b939aa041a65a90226ba747287007175106706f86826d9b584832e55c2da259ab5ea9a96066878de8e34539f1cfe45c8bca8aa4906b5dc83b66d2b572fcb4343a0c039722f53550ebba54850e92ff3f5dbc3fad0ef1bdef55a4611860456b078eb8179d0b14df926cb5d86b012445f9f3d408943acec30974b5c2817f070f18d86a5cfaeb49e7f560d9218946fbdfbe5c2979a5a4f0c4696ccc3e205a7164a13e73bf69d50530e68e4d5d88fafee8aa132acf5e37c776a2d36477f1be5d3b46ae83498d83e61c2ad52b0306f6417d728c9d4ddac7030fef6d4300109487d40e81f400106c177f32bac5b2292af7328d2ceccaf52883ad091fac8f5d88396f6e5758f9904049202dc7a37c2b20a5f631a9a403c6a47182b51e04d6cea6b25d951494ddefb447cf50033862b30d8cdbe7ec8fbdbbe3c6d135c5298c987eed8453557688decd290616625c86abbc9b48fb8fb3a36e772ef9a34bae91b7112c3ced46080a72ab4e55f900e130fc729538ac04a69e6dfc7111612b0b398c922d148ae347f46c6eaf4e23820a46d97614d89bf411381ecf1f31740657a95ddc62c4bd7a2fab0b402be141a546a1a7dee64d8d884b9143931a663064c0a2b40b1a9af32f7941a13bce9e9c3cb2edfe68791d79ed145a771f5c60eec26f9401cac0cd1b734d3667dd0f0d4402386cbcc0e2d6fd0e87e4d62588462d275dba839ccd5798f4b51e21ab95497ca5cda0c3445dab12b2f2132df632ed096b7c4bb9b627eeb635f03c2b72197eeb696065f7494a6d24c1bb32441feaed97062e95a30b6e3b1e0c438f614a9528ee08ec16ac8fb98e80fc17a919eb231a7694d93d415a244beea42326ea943854d2e3e8b47277c243a090d7ba69670880a05ab02a9ef06dccb71cae288b045e5a3bbeb484bf9f4a971cd209d5c51ff332c6bd5c34e3ab7e4c9994d7504818f8048ee332c27420efbff753db6bceac0722f8dec432de86a834a78f39d3813ec0693114dd42bbb203ec552eca8f651bdec32007b45649d1293dfc952889107ab5fde2f4e062e7f0884987b0b3eb1aca0b17126b8046c2898b9ecdfcb220b44401c0d7f2377e08b109f0c85bdb7d8ba53ab280b4bdeb2533ada011668a163f9eafbb7f725bcd0e40cfdfae93f3058fe49abb678438c69d4f65890d693cb740eaa61a9c23af709c16c2dd6adae8477717d5827ff433d850b57d7e0115fccfb16ac1c7cf32ad6020fe8cd09466cfd9ecea21a3ea54d27885500db9e97d60f4e4270def5eb5e0e62444c83b995ed5506a6ec3a351c7ae17393b2d514595c1205c9e02815e94220ba2a67916adacdade7e8e392bea03d0f10b7a8954b20cac5469b78e3af7bc100685cbc0a0aea8cf51a151726ddd971c9042d2f0cedfa5a80ec12e0dea33ddb11f86623f6a5d0cc26f3b1d207054cddffce3e9bdcecd2cef37003b992e330ea7d6d54e81d5d420b21a77473bf28bfcc2e60a5d8030a2299803978beddb2d3f42282ce69e29337a0fb684a2a7128b9c00767e7a5623fdb70668a793668f84f4eb6006cea1cd0d55a954f697450af6e6364adb32c5b6b64c578e04705b99c158198e8bc2c3f8f035a7f87b9697334419fa34df536705ae7aecffea6388090aed239ab06b44ab9dcfeb653bcc354e680a2d4a1311134fcac3d7405eaf04530983d4d2b77c5114b778f4ed5e7d372cfd1435cb5e078cdd8317cbffa1f02de8d67e081703748927ad1a58d20f6ee9808b5f63799aeb5be775d6030d119554a022d0acfd5f47a077ab7fdf07b9a70ee134268f3fcd2247cf70b52ccd6d110af91a37dbd26ec200", "ac526300000052636a", 0, -798177479, 0, "6ce36c9939c05ddcb6cd14e1f199e6e691ec0640b5d76ecb995f5e163567c020"], + ["0546a37a04780d3ddbdd4552a73ef08c065430d52b3e3aa078dae3baf08fde5eebee3318f903000000055300636a52ffffffff590dd74627ea19d592e2247b76e8b1506fe9135305b4bc566378fedbf7ca7b5501000000085300635152acac53ffffffff96d94e89d3ff7150350e27f36ef64da475448964fbbea560658eb93eef71da240200000005536a51ac63fffffffff5682825ced18a924b9249ddde14c3869eee2fb813754ac6a3079d274ff5b7ef000000000852ac51006a5200acffffffff03db9009040000000006636a53520051a777cf0400000000025200656730040000000001514e1cb9bb00", "ac", 0, 910430291, 0, "f6c115ca3678c8c38bfbd4dff9512399ec52726587b249da100c8f85826d1aa7"], + ["030000807082c40303d0e548f793813b4e2f59165cb688f6f7a2b905a6cf3c8a85baaa20fb66c9cd50010000000152ffffffffbed6433bdf5e71c248355b1df826c85eaeec87880f374c08cb14ab93c128a37601000000066a006a6a655335f5ae8e8a7a54940d0d2c1959f1409c393e8b347233c445dc03346d6b436aca842826de03000000015170253ea40223eee002000000000163baaccf03000000000451005263000000006ed875aa01545ae6030000000000000000000000009dad46ec81a77fcd76594284289322778e1230a257cc19c955cdb8228f030ed4b0273cda709dd084cee657eb1e74a1fc23a90ded9347cbdc366963a65e5798ebcee8e95ca426eb1946c4d83f2631a7d23b71605961df8f8f6e6213da033d715f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003593373f709203caae4323c865702a4d3402ed5a222b46f8f76dfa64207c13141f611d40bc9177364937e88b542a9189f49a471b00b54b179c6919cf657b02743eaf20b55feaf5d4e2fd8a2f0713a51eaf90026e1e45aeab4c0b2ec80876f910d48b5142a6f06a30c632d603f27a2f7d1222f1f79cd8174b917706cb9a998a75032b818c35689344767ab1ab78947da6a4756623350485de9158bf1403012db6a6020210bced545e0ed186c512a20e9a583f404256124bb0b4030a82346116d972c50a01803e84b3a5127a1a8e96acd4d906278cc031ddd91a81c5ce32c93a14bdc5da0718c0dfea0f9c5b72a2609c89de7714a77ac9d8a3494a68c4982c350055d34002194b553dc5c5b8a68db788ee3ca2950f0bbbe3dbeeebc8c437b2da8fcfaecc39031cac8a6d312e7bcc0d62b246edea86f58ddeb35dc4976a81a94f5968bf00848c0222d0083ec6b00f7321bbc5f47fbbcc3ce7797054c8d3011827d3f1ee2913b00302170f36244cb5ce660f5e9dc699b4344180b20cb94f032936ae3a835291334130032e8ffaa96be8de67fc8b2ebb9a2281846227612785482830ffbb842ad7d4e0ed9b6bcd4c6c21faa34931857d561ad3beca88aac445febe193a5be1d799f7a2147e7296e468df9eefeaa0ac90de8665f1b587537cd8f32ae44d104dee90756e085a7c03da7043ec52b49499484b1aef9033179822db1925642719c9ed480a6fb21c504e6171bfb4e84c1e2d713c6672b326409d327b6fe174935db141108da62332f509219075da865ad98f424ca8ad82a0043fe29813fc37fa89af7e2127e24750ab3e77b0a249f76ab83920b41a19493c32fb41a2d0679c1ee3326fa2ecff3c41b89d281c2833135bcaeff310ea72bd6d4015fd1e04c3238dc0ef656a5047bca8e66a36e489c576e3e8d213f4f599781aaee032378681f186f29661e405142074e71a971169ede2ac26a8fe4b9e07b60c39560a917bb1d07c81e6ae2d48af19d8881da12f573fd8169cdede727f327b7ccf2be48b03927c56bee2ae2575a3bf0743d48f680e01722b0095e40015fef3f3dea0c87d252b5a947b5e03b158962f4a7d9a603e5a1c19209a3d7885799a5af9bb945fbb7d0a223de0b1e72b7693e68d715b8e8893aa5d1e48758f6391265f77e4b9bb35eb7f26e5baf006498057faf5b698a7c1dba448eb15eb23a299cfa64e80e0e66d0e853f457a0bd5f9663c95e27b6062e420d5d60234835242b0421816025e0660626b2bd4a0d7b02a4f401d6b482fcb48a67f0e738848388a612af27a796e0acd324e762ae98115143c96d36eca83dd8391592fb52018ff4521579db817b68a097f4aec9632e15811e7225ca4c664ad287602499e9f6e744803fe651348d85157efb697df8046d944ec28c9c2d4042c82d22e4c89ceb445b8d8c2b98d393b609fe2601ce5145a5b885edf257b5d50a6c25fd6c16b61ae25c790bd9f6b9a0be69192c5caf5183731b42436b36bbb3c34b4eb236fea4b2b6427fba22681c250198576c44dc24a6ffff504543ba587b80d7342e6b0dc46e286dbd52189e41cb5124aca673817229fa86304b44005a2651f7d95f11ec9069f92a6b1a4455e07440d28d6ded9051122b98887021fa8626fe54db9ff4756e57d8c8e8c2224abd10521fb0391916f81a62fdc37bc9eda8160c2c053a31e88804bc469c864a02d680dba8340aaff79376fa0e6a0253bc0665904e6ce9e305c03a48b8592d0fc503964812036a08cabeff42dab14191154888809e76c49c82d8c12635b0309debf98b0ba22fb7fc35e26f9cb97b6cbbdf0a2519a55835b4b264a341b185e0501925e1a2e10b78b54540f70d667e02decd720b70610ab7d653e79a10db812e148d6503f2175b65531d507f6ae09520a368181af5fc6675d4dabeed29a0d4fff86500b5f6654ffc735b2cf278add6d023cf4dfafe2a9413f0d8a704f7757a22d72bcb8fbe85b1adfe924ed6eadb422e1e2210b6be14f4400f847451d0177c8ffba833b11f409204012140c5cf5038c7af63c3a9695d7cccaf1b90a86d7e773131d9fa9a35a317f29a8f95cd1c85f7eca02b110e6a0da2b58ff34bdbb08506cee643a30edfdaa2211fb4744f28fc9fdc6b939405cfaea05d0dcb93750c4283100eec2c06bf3d4405c3a759046ea17c5c5b2810ea4e6ab6e6ae886a7d82ee4a0f37df14a9138cf9e569185859e3ee0228f82f349cbf47f32b1b8633451d2d6c0ff41979a3209156260518b241b834ae7bc996b1aa420110e00cc95d934eab75a8b865f749187f0b2460b640f5c4c5fcae17facc8147440b518401bd657b308d33959997330fb4b5872804a514c8e022181017d71e4e771f8461fabacef5c72294f260d84ea21611df5ba8783303582ae7079afe4779fc18b123d479e36e56f5c696ca706", "ac5163ac6353ac65", 2, -359073691, 0, "d4ebc1c492bde32c68259c9b0759d9505cb470faf157a43e4349045245c00782"], + ["030000807082c40303be4b019c299d439ee93cdced75c9d4c069c285d9330a2957e484d7b00cc8c6b90000000005ac63655163ffffffff1d86ebc4bdc71f0bb662dc408a878bd685dd45f3d1ffbb4aa397aa136da46d420000000002000046f385fa8d45830e5c37e893d579f2e9b7e5b9a2a5b26e13a620485132f8c7462124dd4c010000000400655100c555303e03afab3f01000000000352525378b0e7000000000003006a65e4e07f0200000000015100000000000000000300000000000000006088570400000000d35b81b5e3a730af77d5c081b7bed42462ace0f0e5f455054558ff8110205460e9980379105fda23f7bfdb7353fb4c2f656e1a2f12a3a9316ec1054a67470c76ef08297a88e43bfec79216d31400c1cbb22aa880ddf18e3e7df77a313d19c5620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029106fb8f68329ba8e2a59bc9333fd782f342e5c9c769332341f3a7acf8556643f4b449cd9004fdd3a9cd3c6e15ab4eabf2d3458b7a944656dac4e9542bfbd5d13ff8adbb3ce85b86cf853263aa65006d8a4f0d9ca19cceacb32f964c28416ab1fabbbd034a8aa8b8695c702654ad41e1bfab309a9a73d913d15705c3c35c7f802097bbc22648f2dd518669c9e1ee19160d80bb7b6ee6e962e4fe7861a4958b5b8030418a6c17b1eaba79025b3e50c9a70e25af04ca45e4b64e32e7d040e88fbdaf30b083e33941e4967b5ca454856df0bb13223a978273c150a51546168c885e81a25cd5bcea0f38777292cdb335047edafa117cdd0e458cd471e040750f9916bce98022a0318fe408cbdf46ceb5921c81c4493c57e5f53d6fc30b51a8d8b655e3ecad3022a64dacd8ceca10afce8ce84fb568aeffc219caa5871892bae921aa792f57916032fd8ffbaabadd278b39108aefb209be9b6c6098358266c4184059e43bc1f79da031633179d33769748e8a0b7452e11e1b04ff27082a890e6c8676e35802669a5d50223496ded4b5f93bd755a2df608195cbca227dd3ba162520e63df5a3a8f65b241f5e74c4406af8917cf4934e37768313ec2351e01523d82a0c85ae42264283f0040a9740973195e7e0d1e9d3498a42fb7b5525575d1d674e4efed96d76c67128f3fbeec7f2ad71fd86247b87958cebafbdb61cd9b7ee858ed98bd98f9f1553d04338ce8b99edcd12947ca0c68a813287fedbeaebfee3960d08fb1d9349834a6bdba8a17515957d237af4835c238d16410b3d8962c41eaf8b1e9102be304303382f30e35869fde7880d78977f2229fc83b4971ca065e1396226924af73ae0df3ffc1422c2fc3dc5c45d06259bf5823b4f9f9050306bc8a25a2f00b96cb7e931ced0e842239c7f3390e4e5da780cd63ec6f0d1141da6a7ece4a3fbe7f4a9123cb6c0e0a6660419d937c411d8dde2da45c67384312f10dbcf6bfa6f98e5116e82c69d1b4bae94b421bd9b6f5187e49a49a9e163e57b292c5907ace9ed776343dac566d79989600faa9f69393d9a470a48aca0cd0d822d16524300db965314536e93af3efeb87dd7505a9b31bb7409e5dc7ce76c19fa58f83e138a1a8fb943d9392d4829993f92a9d86ab21171d183b5ff166adcf5260da494c1055ed504254c0ebc32e7b8efe815236fa0068fdb2755c4d072f8abd1c6d79a06f9d828516e755c0ab4b49befbd3a05a5b0aff29bb38eeb9c0f9f2fe6519ffadd4160f23a0d3c865ed2d24db2c1338a5d98db28b1ffb61edf4e1b1be976c864bebcba9cf6ab325c0c53f58e133d0151cb74c1ea2067d8f835a80b25adad2f518059ce0ea71300c111e6fc8a2a4321a3622be8f9b73b108c56f0cc99616a21a852b288580fa70e706956df6f7ecd59c4d37467841074c7673c0d5b66c0eba62198954ce01ac3b0bb5a9dc93339f81189ed2313580931749c0d905c2560e58c7d06623a961e61a9ac538fc5279ff009872ada2568c6f2e5c73c0f67857aa21376f00d209edbb6074e99c2026c911ba22d6a31055e1f0f48ad8870cab8ebdcc23729f145c92ab0cf1a7d0f3dbd4c86db883fd4620dbf9d59ead98d0e5325df5618c2e7441e07b8530d8dad1cca9cce14de170b45a2caadafaeb9041bc5b33079bcad628f0828d4b08f8bab672e8bd937177660f2b2eac990ce19d4c4f13e0f9e9f394a815534e32cddc3ea27ae86483b41f827f14bcf1a5e54b5bc66ff8b7fa3e6027297ff0d49758f582508377d722d16f62fd07b239e1505f34a4805e5786fec8d576ec4cfa847146c2e5010efe3ce57629671811965d225b091552a45a5b94352704725246bc40d7f42874a8d3cffe6a6baa4e64567106f325fc80e349f144fcf37a99c35c46f4e7dbd5917774c930b35ec9bc1619a0ab4aa06c611a6ebeae823e63caa5ccb403404fbccead6087c856314c38676b9f08517ccbfbf383442b2d920b18b959caf9684b0a7a68122e9d93f213e89b226d03e0a7daf7b7190fec5aac6ac978c91202cccad72b8d161cb92a5f3a5667f901dd70d5a929fe3eb9fe2fc4dffa5455b6906d2ea171a5782e1955ef8c64b9c336725d28ecc2a4d5805884fd7aeaed8a103d5c115a039f23c317c96bc8e523f73e27c753e796f36ae4ba49b0633e88b3a5bea27306f4617bc751311c895270b7b40bd6721b34c72d714457e4226984ea1bb344d370f7dccb797964fd954dd0dd7018fd1af07b47ea999c83faf5a528d70bb05c1e65b504aa66c1b17a08f74b3e79e5a63c782b00000000000000007d3cfa0100000000975a63ec7ccbc71dec59c7e04f86251c50a0eb2adec2b55688e7ed8c90139f6502a17178fa2e61018f9b4af7a1a044140b9a2192b6c85a0073a268fa0df6c2ad18bfb4ce409913f97cd63c01e894f2c4334163cfd584ab1e08a92af968b7f8ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d14fa035ac622df1b1a10aea77f54d06e3612e9de3d6c66cea4043cfea679db79b94014a2ec9806fe97bc4f2db60267bf8967f4f7570d9bdcb39a8d66aa4717e0e3de4a504b56a4d346abcb35a60dbb778c2fd6e2222ea62e9a04b6784ea3402f03e7baa69585dc47a3d218543fcfb2b2f112bba96e688881886006b67f1a1ea0216b1d05d5991cd31e97371afc08f860e039e44ecbbd431763519575026e89e4a02157e3a34ff0267dd55b3c332ac631dd4d4e879480169c5efe007c17d65fa2e3f0b033dab21b1951f733f8b7f1948d2899ade714892142bfece37593ecb77f594b1225d923a7d0f1b7fdbf997dce30918e127da7c13bbbcf3452a650d07e360f7f2021b95df8cddf05498512d48678646b28d59125432b8972faf5a2aee0c1f812ff1021d04caa479dd9f0f8ed03a461bd519ac872f02135295e1728400d1269dd16c110308f2127ce7d266823544519cc54da341422ed609db3c2ade910d077117450e94021819d5f46a4b3f480394ce465d65e0cb6549b5c05f797bfef231c14fde30da4103180ddab52e592d5a7d4a18ad03207cdb3379bfef60b29fea7920f13bdbd463dc566603e18a9651388d0a030ebc75bd25653ebc4a0f77a294f47a6ec77efae2f9527ecc7bd8114c8944f8ddc9c50ee86a5b6549ac43bdd1e0947483416dc933f2f3694925cca32c6d09f607053c945702e84ccd457a4cc737712572042bd87065df09033cf0c437373e6ee3092757d6a932a3a1c85eabcc5afb2d979f7d3309701f22c691e537c00f72cfa9c76c99580e1d7b489f27ec59c715a09902205b76856f46567d8fcd7027c3191f34f5018b2402824d3b52e999ba3733e20e74bdc4960261db51bea0ef7a1fde8c88300b1e484f992d82b52939034894976fdf8fc85823476dc9c95087abf0f7717395e488aea4aaf26d30a8227a74e71a4f9c8cb41720622e49f8cb7e01b587dcd14afd14e40713709a2092e406e71fd4d21876b3bec8af56cf7c9114bd2a910d13b1d902f31a9d4301f80fb33f3f574a489c5c9262cba0f95ed02d6f253865efc6a9a6c1e6f936db74571832da462e10a160a051a6e6cd96b58fd4944a9fa6c5de9a46065fe0bac29e2777a9c7255a9176bfba609b99ede7dce36595e9ce86e33d12e7a1bec56c53173c3fb59753b2a5aca8cbadc49112cb47fe0b78c44a09111aa2189670c983be682325c0de1ed899b2f2a0e5ee8aa23bcd9dec7c7ad9481216022402b09ac1df515ab687cfd2ba87cbf4f740ef81276a68e6148190d9f030e38c7d0d2bf6bd42e7aa259f57c1793dd0e5d193e8a8d27362e1a7cd75e1ff34a98af88587805cfd2474a155ebd621ebb83f2482c62adcce79f7ba2985c4f148cce2587b9050a70ae8042f76b31da187b6df83d2062397cd7ec08486b01d4af95e6ce143f673be34bd8c703cce3d62b68da41173179a46baeffe828e16403fece5795ab679ef7ca24f4c687a8746c68eaf4c52ae8ed25695b03fd52ab775b1e58afcbc311437fefccb979e71afc9e0f890f0c01ed786acb306d961c1215a7d3b77e768caddf263aed64a1cea637646baf38a9055a0f1a677b8b1b4f09a102d2813bd637ff0f7e0bb12146e49e697e96ea433b1dfdbf65f2bc0c1a51ba897259d11539790aa1a379029e2e5fffa382e3dc92b2349b30b4f95c5ae06abb2bf0523f94c4dd4c7acf57c1713c871a79ca234e14941f104a8d4be457aab32a233577045c52a5c7f57d3cc5a3dbb29f6b7340ac2aacaeba60294a33a1716046a7af29fe2f00d0ed64ee7159307211408a8f9935cb2f028aa1d0b21b5f3217966ccb3602a7df0a4d22abcae81017fca670717ce830041cae0dd475385d652e58fc398c865a09484e7d9464e7f8c1eb7ef05c154a467474f3ba75ee55e2d1de06dcfd676e2d220112842424e58c4df9f1120735e2eff66356e0bb8dc9d50b8996735249e9ce4e819a4db1204a1ef76faad2c191f42fa1396935954f856d6a6dd93969d88003f44600fba3fcaa81518bfeeeb76d33aa4298bdeea5c7a17e70361b0818c47b94102312da84b0fbde3c1274738eeb15e32138d99a501fac5d0485533f0152a98d96214538d15359074293f8c11ac02090bdfa43c62c3e4c8f46750f463296e00257321f65803981dd61c4899bb2cc4f6704ece798789d149462e27801ef0aa3ec8237ba6211e244494d8b1a9b7ef67360d93abc8a761e5d0f60fa5104e7ae9f088977f5b7ebb0831449075996ec5d4643719630cf4d330cd73840d37a3195f44f99815e30f240000000000000000d5d2eb05000000007b72161478779598c8c36f5ebf43027042a8b60a5d989f273ac706be206f934103b92b9f4bb2cea9e419d8ddd54ed83e6c72d13c92b41dcf16b88594fd0a209e6780c7167ddfaf8b89771ab887a834383920d6e9cfecb56decec9aeb2e99cf9a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000185c44fe8221d36a49bd5d592b87e3a7226a25d7719848b87a6e52db87cddad921fd8cc2dc5932f25f9f9bf09a64efb69fb7a8dcad2b7362a054eb069df9dc98b89de76aeb808c1b278967ad6a034aa6fabb89ae6d2a1b97c37b8faaf993f795915595da23269041d2cfaa3ccbb68f0cc7eb5c04dfe8342ed43cdb8e1cd29b64022b7e660c7cbe11cfbe8355efd08e8d2bdf72669e5478b248321437ff0a7402590318611a574ea60fda4cf6a63b22d56339ca709b72d01441caf72fae492bd7f1c40a07e2835d8657a799cb1f102ed81d694b99ecaf5ec8b1dd9d830160d6d1ddf53c4adf323c9afb355c457928d7bed1a67c6bef27effad76a9a68b6b98e898ad0a8022e07c8d49b6bcf127f5ec841aad7669a7fbb3001232b7af93414153e814c4473020254abf5530065462c8675002bc0f98eca22117f36b68b777969ff21d22d5ad3031aaf04056d4ab0168c4aab43e899e706c4e2e1758e1ceae0b00b567c1d5a46190220695114c52b173badac4228cb41447e1abfbf1276a51b53c6c5d6b49c3e39920302f30f2fb2f8e606378e984c72bc980859810d78bd7d778896b509a8db008712c07163e3884c956060944d832ab04211f94b7a60703509523869e09234c12aaab260a953e137b0812641df8056299c93b192c76b0a40c75c315c39f26695af127b69fb3ee439400f7d086bfa0973daf95cef92a8222265dd64426afbfa731962c446c092d92c02619ef775d00483941c553a826fdaf2fe6a27a22cfdb611505cce41431bcde0125c58ebdd5d7224c3e2adc9ccec212ae29cebaf52ef805b3de56d9fe125b704ae2e0c50ff52ac33264c1e66bf5056bd05dec1fae781cb86f68ab6274a4c20af85b87ef970291dd741e83897be0f5d909c0d055193b3d2aebc37a4668864bcabbca01707cba8329de171b2eb7c109415629dcdbe40b24fe9eac22d6e454336bd6436e78618f1da5683b4aaee1f0e5bca5e0840f9fd9e698e30a0d538154570e6abea199d258b2d3000737364a109ebc190bf28d3e6bdb968dd639956abd2d68475beef379c94dc62541e0d3d1a48d819c3c02a15f32a19e0eabfe2cf416b864ca9954160839500fa6f1a409ab4fbbf0e4280b6d8ed21673907d92302d51b855d1f95007850040202bf1f2f96443b9881fd835fef4b3af8a18811579529a45de5ae7d804aba5167bb860006cac3b0a12b2e3ef4c65b9f0d98d6c1f287ab2cd37a955bb8e15387fdeff77257fe91693f8b5e1cad31e80b34e5a751971952afa02bfcd9e569d65ded4579b93955a4eaca22ac856976439078b0349ec23c41ebd710a59d81260a0cf458fb6fbe28442ae81e19a24c157e32c61552ff1b9f2e4d32ef238f5a02d0f1cb6b6ea76076b0607fd6ba506e634eb9453df46861b91a7ffcddc56378960b16b054036e08f2785172a5bb64e5db3d5da9adb65e231e3c159a192098330c66022428210d70207dc7812f6f9c2c6310e3da4647cbca8b7093674adee5ba7ba1d85ba16438b5b4c0ad14484083ed19ddfa0d6078b711104a4ab3144bcdeadd9e1aa027a6438601fe1c93af402b069500b089ffd9defc76ac0dda692be464afae8fc478a68b7e29ba517b2e375c43c8e2600d12ce2e008c64b2b4f6b47d94277467b20f8a20c41e2780ad6428e971d7063716cfad9e5c83c1ee98edf12bd560860aa69c083c1076d99f28dd91b68aa19aaf493bf6fd19955553e449d7c025ce17b9bbfe34c5fbbf17e0b16cceb040ac62ae92195c5c63017063d9b30ed23a45f0e32fbbbe79bccbe8fe94fd1802c32f13c08aa5df84d0ee02103083b4f65f6622f20697397ded4bb5605a432d6c8663f7f7a7c9c46b30086216b6a36ccb6cca52ebd486860130dbfbf25213f575005dfb5b25ca0bb84f0b55e12806f43fa97ee855abd3be07a5cc7ac805917109346e44e08f7ee6f06f95215605405a9bc87ebb573f327eaf03e3ec33d81e385e40b434fcdd95f6327a58c0862eff4186d7c6c507d132eb4e7223b6d0e666b0adc5902e8cc1f32edd96e53de9c5a539aaee231501a5dc6564727a2c62b7ec5da5f98e89076d0cd1e2f8828372b81a92a0279f0807dd41294890cbb222f439bd4d7f9c547a5c479a1ed3aff2f52c09ca4656587c2e175595160a7c824a977013ae83045bf5e488d4f00a8ce6f3342a88dbb26ed6fcf2ff655eff4c699a78bd2deacc119950272300134a6e49d875a4680528891f6363a379a2339a5a67d2c0e0ac0b12f2efd7311ba1a44960bf770baa34cf0598d0a57881ab6c1c9689520585b6be68ee04193933c2a24abd0bcb19bdf8a75bce9b6370dc922a48d90e1066501489588d6f66cdef53341b7612d1a041869ae7e63b9b540a2fc7218ad6299a31b4813b89f54a9d0ca6dfcab484fc5c84be185edc67968f8a950e00", "6353", 2, 1381533410, 0, "cb7bf268bed5123b8d9be13564e4db7a0f2d207290a875ab353a597da81931ac"], + ["030000807082c40304227940b7af6cd7fa598b1c7ea4d77d67526085f86b1c3032103c5a7f0713c5eb010000000465515153ffffffff06c647aa92d3574d3100c7f2268e40059c49141263de8a31e08f9f277ccf5a3d02000000026500ffffffffeda284c4816f150d8a030590767a46449b110913a017f8db83f5e6028936363a0200000002516326d27b72c618d5adabb7a6260ae63a7f0d23e19b6d2c0242eb3e344cf199bdd0153f9d9503000000065163ac63ac514d1fddf10416d0480400000000046551536a8e831e0100000000045165525170feed03000000000465ac6a008cbb4a03000000000600535300ac6a00000000eb388ce2030000000000000000e9fffe0400000000940ad60989d4626f98d953a353804c047f4fd88e2be3ec7ca0deb16d942dada056721422fd0b8508d8128aaed5dd5801483eab7c3b4b2d164360392537572c8ab556ac6d8ff8653d67fe1488cc4adabfbcfbac3da2a7101b20842fc52a84a3890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069d1a6517d1a02ee2614cd08e585069bb8e4c4d8916a7ad3f49955b2ade780143c1d1d0dad021304ae2f0409d600b4c446799d8da79406b661e2fb5d4b9612a69120ecad4a313d119a2126bab210c7a686a28757094d1400e2f2bb2217a8ddc75b710761ed9b21449ed7cd1bebcfce37cc36075299bbd12006474a842dfd328002243d83429fb13046e73dc100b3abeb286d4cd6b2453b54719b96f768cdc9f5310311a9ffa8a8885f8d93ac4c5b9eda23accd4de8f0c0e647e046a673c248d959d70a048502470ca0c7ff15795aaaf6e745dae6987a0b252c78111c173f16a5c92b5d54589179d622358b8d2ae5c60351e981b6df9ccbb323613d1b1cc12d6162971b02085b17bebbf59f246f7ff5458f426fc02be58aaeed62998d3ab067cc149fa52e031a36d0cba21b37f8ef5dc82e493faede82bb0c1615e7f419130b361b38aa75b10329354ec177e2b87ce8ed3c7b537923be3194b4b72545d9d6a9fe1473f3bd431b022c31d741d5a320de2416f4360e1b99287b125d04cbcbe5ded9927ad7cd521bc8021e1b5f04a53ff0376bb29edf997da63bf268a1d496e053e7836e0b9791729aa3f4c2284c8ed59d679b5728957330d3bb1d3a003968dca7a660d01437fa9d2c06b0624d1ea38c35a7015897641b5d4875dcc711e4b8f9178fff3eba45ce259e2e684e3a4193ef1fbe502f1951ec173c7fcf056f11d59ade94fcc86bfe19d89310076822fb3ef614b5bf81e645dfbf1d48b76d568403d1b043a480dc2dbbd07ce2ac432623a999057d0e0742563c8a47954c60b70a652152a59d6b8a8f6112cf6f3c4b40f8261bc50b7f66b3bb72067e6a560bfbb247e7e16e04cfeaa6689cb673ac4de3095713f411bf1fe5137e6b23c6fd6a9839b604398df2fee761c7fbc1fd7461cdd4e253cd83d5bbcc52479da6d3c0011998fad96b44e7dd27e2ebcdccf22b9593686ff89efd636797acb6796a29754973b1a41e5db9fb195138377df07eb1422a8d7d871138557539ebf5927f821d597d2434f4103a1739448df065a4b5c92c9507891594531aed390a7f305c202c14128c2dded3104c7836bbd88b31b36aa93f6c10ae5a841bdf7f14c691931ce7fa3ca300c22804ab1b5929b4d59d675b905cdee606c04b1de2c8ba0b14d1dcc07f360c8128a140bf341bfad36f2ce3616d934980af1a1890baa964533505c1b3bc7292e7b18b482e7fc9d3f46583eeb2786fda00833bdaad6c4bc8e989c6f1ef4efcd43e3fecb1a0731218c6f9c596ee24c019e90a8ac5c172395ce5d78528cd1e2493fa104e12882a263b25de76814ca2eaffcda87aa53bbba57104d6261f3ea32ced255f845a9c349af68799b68d192f8e2dd637f132b996eddad9bfb263180ce9fae488bb1fb464425fb404fd2bf29d8e15e8ae519aec5f966cd6e96101f79b954ec4179219fc15407322232497582ac90406aa592242bb33a6a20564bba4be0dd7b4b58e9fd25e1606698797fbc19b1897b86f7daaaacda6476991f7adccae52a0af3f547f1d2d5a9c01578496a1fbb7d3b7736733958b93c2477e5de743733fccd901c538c9f4e08844fe455dc560c915e13cd86201dbf35b17654d5b3e942b3bf7b110087a8f10e89b178964a42fb1547d7fb6c0509cf4bc984b944ab791ed3936de2f8a69a990534c1350a8b2c64a1e6198bbd41fab7ba6d3bbcb6f4255dbb496dbd0d7cc2ff5c9dda4e31333d34d09ccd5d383f6c37a1b06dde5f6516094f414cce03fda117fb83d046bfd53e4b0f911d154baa1e163513f64d3040164de3553f443ae735ffca215c574a64a1d66d1bdbbf3f464cbf05cf5d4c863c7350f250ca4db97f10e15e3cce23a5e367660dcc7698bf04fd7785b53e7ffe903dcab388df9bd164b570fd8289c826d801477e7dc167a1bacdd23f51855fe3698ee34eebafd63656430a02017991323d699ddbe0c40ad736b6f5b0d9afde71addc1ba03ba4f15c0f1e10591a59cc78428ea3ba543db6e6a9c91a7032f1cf78e71a8a39f8b1fc2589a1c0434cd3882058696a00b6ff67d2916bd07a79815f8a0be3266916a994e64549fab60333c706e88c6f751b9cd495e0b3cd2da8ffef5b443d30fa792224fb1da347a85e8cc5bc9b17a39c35d1da250b757e0f421ba44b6a68faa362f92dcae227cbf02e115a70aa790c951b827803825fbabd017069426da8b9def622d6def57aa274926623877f86e9aad3980eb0d4fedeb4d297144a243dc40a46003ed212c1073b7fa3d3ca38001e7bfd75d384a17b5dc092ece3577ed2f39056604000000000000000000000000c554d7f95f42ef7260b4662b2803bf14525fa7f695939b096550f7de3243c676a35c61f2aa0af020181369611f104bd2adfdf1dee0d020ee1236ab492c3ed6df695dfe9d2c7c9c070cc898bd87076f2a1e1ca57e14e775103a8c9b7c5bf2d40a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba2c2a31e0083e3775d251f594b221dcb0da6362fac9071704018d6d330f903cc7da4e76a252b2d838f83bf0ce1073ed2ca9b1c7b4c84e6d4c856bb661e87e525a54a430aecd1e159ce9bdf0aed8f11930ed216f241fb307168f103498dc8419aad1400736bc12638256e3f7baf6ca0ae0f681162c56b56767861aab91434c3c031408816dfcf9f3fcb4af6749bd9e2de381c7aa1b20cd0eaec9ed8f89c626feff020f4bede887047fdc194d49533fac21034b48d7380db332f193b4c2d15ab9cd280b0615f767b0d3525a7e8f0da0763942754f4ebf1fa3e4006fbcb06e05d624eeeb4c9888e9baddf72a891114f8b2163bd4c52454b9920b74eb232e6ef32486418c030fbce0743e5cbec4dbb1a6646865700feed98d93f162462c928ae5b0b532d75002294b96be4715ecfea204a1a7c3b133a7a84d7b92f97ad5ce5f358a938e09e5160204d54d6c562327caac774cbac2ccfdc0ebda235f9edb6a35d87b56f4ed2abc500329d0190510b052c13b3bdd2d19ae5bab0993b9b212824fc782a00ddc963639cc02056abe4390a6ebd747a4c9a26226fc3d89c8a180f7d72cfa421cb320f537a7da72934fe9050da7a5dcba19beded00d23d9bec4e4ee5727dd1653cfab5ad36c00323192d13e5d85586fdb8decd41577796f991bbb4ed68dec881010e8ff63703da3306e99c8c5271e4d173a9aa24cf9efd6431e497c70d0493a1f4380e2378f15b21e0905f4e57b4e3c93b7a6770fe973f3f016f862d83c01e049f336a972ad1fa7f7ddadb282bc779e6d8d72e9dfe2b0b35adfc2520b24050c59ef5024a2fa065b56231a4f02f3830f208ae3bd1a4b7d269134ab99368437a4774bb3f7163adb7bbe5caf07318cedc07a09cb1a6b5b10646c3dd641bcdd1f5520436f051f0d4ff816fe45e6aa452dd286bb6111cd35f74b7bf11b1d0e9625cc0add2feac161e350200e6a12abd37f21f4ed3cf73befc2f405a1f96aa9f2168bf0cec2e2f0494c68add67781711ce6bd31d2d95755e8aaa4a2ad9c7138ae2e39fbdec80e549bbedb779c89222fa1041656f5b57f8d417a4ae3c784e136e7f83bd3c7505d065d4dd554dc0aca966743dfb4d3ca0e6e983f52eda24742f5c812165885925255ceddec643a82afbb28088dc013852fd5655fbb5658768c9ec3955bb60be722a8d08528f2ffe62e492e73b38e7a895ff4b63dda99f552257c0a1d8e1c4149580c6cfba50e51ccb56aaac3659763c22638649a571188a0f41c631a7e652e6db0328989aef47f99baad19003b62c06190b233e9dc5079d4e0bb3399ddd0c2a9c8b9480ee4cdc0d59f12be36cb0f5b452d877b861b2beb69e6845f1867ea4eca01c9155cbbfcc3cf0b11efdad2f605f2d6b0fab5b11cf4ce953a2240dcbd5400a534b5a56a233fec518784dc07a9dff348a2ad8e2507ed5dda3b25fd1f84008ffc7b883faccffe4ab65123d5c907af5d1dc9724be1a8f5c2a96e202a772a561a4030d9e58328e5f79fe8de8f9167a7366d7852d46e7c5212f8ac189be3665fe80f61b539d16e93ff7dd7cfbb6cecc2f894813cd248e249eb50b38c55422dc3f6d0b054a91822154c1c7763f9d5e1cea02fa786572cb514efa438099a1acd31a3bb67df940f97106c82004f95280c1cc93a016d66ec740c09f9b14a3b75edbf8a25063a44ab076fb5cf2ae7afcc4f01c690be1ec0e16d5685082a76761b740ab71c5e45e71a0f34221ebbe50493f60943e40d03d67047c6523782e35c59ebce9d86b11d81c54df0841c3071be9a642872068f8a3da5c60219600fed0f4591d02b39ebf129bdeda265b939d44338de50ddcba17f7f220317fb16c86c6888e4b6bf72da60e631faa30d2837f077e6f7b2a462a86840bea8ae938bd597b97e8d248fd7e2a56a1a9d72eed7decbd049fe6046f1865a8910e94535e11941b56479e9b1a5dd6ae3c52c3bd21cc1e3f020455f970ddbcb7f8cb64813df1b0d6df321659eb939eb1d5d216973c5aaaa84efabfb030cb07e09802c952509f9ae284166887cd18c5e76e0977797c32594ce7169306aadd7f040325bb8f9d70695a6fe6f43dd67c6f0d360f9904a0ce452532ce3bbaf1fa72bfd22d403d9441c685d56b278cf83f1e6c755bced6f22c7e040280cf02c301f1272b3b954c879e8761c59591fac04b7fec4b8fc43e8016403fdefddd7ba55d05b51c3df72f1c11fec22569a398b5121ed552d70034b835b469a2509f0eb9779bd46610214640bb0bb662ae505fb81f68bef137cf46eb5a60a1260c2644752d514fdf9e40000000000000000700b0d000000000008c92b660ba26315ce71bf9cc36a03c41f5da181c79a24b9e6884ba4a10f70d5b879995213c6175815e22cc6b8e9a176997139ea4919a42261c339a2317d0dd82819b0dc718686488aa86771cac4e7f7d82d57961179bde1f91eaefbd2ff08440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012fd027d3f97b6689cd447841f94bb95ce5d7c4e358f2f2ea752030c67d8e3e4ab6ff86dcc6e800c1f939cb76260704401433af56c5293806407691b28cefc51d97092fefb8416e3ee3fc309a5cf4e0957f1e0dcd7159c9b9efdbc94d705811105622f61ed11958573dee78f7571239c7afdef42801ecb0311b1a51e19a0555b032b15a72eabd02c49aea2161ebfd4899cde7628bad7f4cac65adddd967f4da73c022e3928ac531b38e41c785094ed92e377791ddbc6f8dba5d33ea98ed92757455d0b00a01edc8999b0a1ca5f295f63c5a0e49369f86b9ce32e6c4878ddde744d2b2b7093996f35e46f5abe4e416ce025efc6d82385f7d6afd1c4d5d9630afbd351890314e32ce1d51e65e6e051a3e0e58216c7dddf5d3b07c8fd41e96d848936c0787502182a843fe3ea21f60a8c24a56b638599aaab8b16a9d5f42097768b3462ac173e031e035d771eea01d2bd1652093bd49d7fd8c62aae4a85e838fa112a8e30c60038020877780801d090de81e7684374ff2e4f094b0ed8c55054744aec64444da5a5030212247c8ae44760a9f823f5d010134fb5aa5de29225318d9d16c9a7b70fb9aa86e0c633410a584ed33bb0ced0e4d5359a87d6ce92450cda672ac8e927842ce08af12cbdca3f1cf8efd90901b579a4c3f38044416e0651516d982c0614b0494b3bccb02a3726321c9aabf1708afcda2a7345436e0822a7b173b392e3821097fbb3b931cef71164009883d3ccce24f537d084852c43f97e7a0fd0f4c6380e4907d7b45637ee973f6134ab1312783f3de2f01d5eec45a86990255ea66e2b4293bc84f5a53cae5a8e433c134bf52c68dd12b284870053b91f20ad23df2c747096702dd0b847008f0f385a2c4b4b93d9a18bdef4eb436dbd3dfaa73831ffe2b9af29c739ac550790f7f683adce027924af6f7e2f16ccef884b61978196f8ad8eba92fea4aef2559027f28ae64910724c0dab9e75ff959f519f29473a63d1a9c35823ff562a2722492f976691685d2e20ee6ae82338239624ac953d70a6c66484c3f6a6af4de35b60d5fc22587ac4def739ad4bd2d545febd0c79a226fde21b904471247b8479c99363297fbc2bb6fb658396e3e8f88f18189d9bc5ffee9a519dfda93298be8fc2fbf507eb780e80ab6a0787478e7afa58f80282f9192f254ad83046e0cfaafe44845254c8dc85c76b91a50cab864404c705447eadd77b8d873db7079f2fc322b68f83b0facd4cb914eaaafcbc51ab6f6c074f8f9b3326168be89c55373fe85e54217783766ed2f09fd1ccf5dc5092698a253c70de580ebf0d6b9755e1158cac65ee04a0d72b9be3425e626413b8451b0a344f4b8f1a12911810f50abfa204e9810765e380aa0272c6e60fc6fd98ef75e5dd18077e6dcb8aafe6f6536f426a08d0cf28d8c9c3677f2abfdfcd767a335b33e1fdf5207cea56085762cc78856184f604ced0262771840f1fa05dfd63b7ffc0cc9ac0bd416f3824dab333e191e22fc3b91f9938c720c1026000daf218f83f4fa3565a5cac2f2cf12391891f60323cafcbd713a7dc501c2aaeef79abbf6e0c85aa05b7071d88d62e5a6e65b22587cac70ddbeee3c895b95e0332d3297b8a8045c68700b19ae50631754eb8054d2db554a79f77c14a290938bd735425ed5b07b9490614074be003799f678f5dd789a7da0b1fcfae6e002eba140bdacdf700c0244e1101f02bf1126e8e05ee78e4591da10ce3f5c2c1609a3e0254c4480b5676088154b8ac542c5fcf1a0091ecc4d72b978f11939c610a04ac58b3f7ba47b8b990a49be6d4e325426b882e03b40ec3a79785a560c8e590a84e727968103c2cb086cfce506ce037d3c9d86f5ca040389050961730abd248956d1525f4f1aa34e19b053686f2b595413da2891c21e177ad330fa391a295f5598ea0cac4490cd348419d90f7ed5d7512f88b4bba3fc1ed94d49aa5bcc3bf6e572c007873143879ec83236f2e689911e334145235ea1a13fe783ee23bf9a5eba42a7641c358aee57a0aafa5fd1ce786156875fa7a1ab9a11faa327535c65faa8c9c04e6cc6972cb178d71bca1afc85e1bd88bb8345eeff9ad475c2e0def93c5cbbe100ab9d57b00e191ebd733972d57d7aca1330277a45de6a14f5524d272c343670d3f626b0c7994f8cebdd92af3341796000cfe722aa528b3b695465b6b79cd7dad549c34ad2ab851ee806ec0ae87d04c604e230f57e2eb7d1035b3d7f3a2e7c3b3fb41ffb92ccbede3709e2a6bb75a6d544496001441e83cdc5e28ebcccec55330cfb3b5ee90980b0b5fff901b06fc30459bf6e9d7091e6484d640179a519f216c4575de3cdb7f7533a0574b72a57b8d1cb0b8590052c07c496fd15db85f54b16b6bab0b0a84e7564e7d2ef5c250053e84617c7383d265384ecfedf668d536fd6232ac30e006", "6563005100ac63", 2, 2108154866, 1537743641, "5780af7489f22c27e42af9b26cc2e0acd2b4c3632e22a3cac66bcf54cfc78ee2"], + ["e913771302ece7c6306424e0bf065a8ec31a9761bd7637bf2d6e8961e1fec2b95d69aecafa02000000036a6300ffffffff67c0befdb86011def9920336669633a5b882f67aa9f66553399e0bc199f19b090000000003516500d5e897a202f988550200000000007cc2c60000000000096353520051526a000000000000020000000000000000ceb79c0000000000a472a979f454581ab1664648ff39eb01e6c769cdaf6690338cd3b43496db2921b2b87ec8589cbd4db8b1caf4f54a1d7c67f1cd4d00d7b37f62d3c2f8319bb09acef7e51d20e22ff0b594e1d59a1b2ff55f4b845f35b515971c898f6f4e027611000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004ed531e1e5cfb500de1e1a1193a5f2e0735585b78765f82b0e33793133e500cc0e89916c9abcc62aab64bd34df6b9ac6c7f2f091eade6d5e87dfc931f8b9b8cde3796c00d3596b134e9ba8e90e0a0c14975055f21a2a8d952d91440fe409058990a4382f86bd324f95d39b79129cffae7440009f614d5be9bcc357f4288920120329da5c5353ad7f03b55c6f51a13e0103caed212cf5b18c46a5bb10cf47c85f920204bcce8c9c8c11b53d145bb70ec8664e506bd3bddd524820efb504ab036061c50b062062f8114ba9b175238ef823159b1fbd55759f733e62a66a185113ba10d0d4ea09949e3396211f7c3a8ab33bd8531408cc9061d2e6c0d8af919a6956e98e4c032db039013fe0eda900c3f175de85464b6a765dd1b91225e56ab0b2faa2465dfe031ccdd1d839110f82c5c0329edf6750c014a9df4beb49fab74ddd7cff0067e2ec02013e5a240a26c9ffe538c77c2fcae43ddca0c53a8833f013138cfa75a58c72fb0201003b913d2b72a254e9bb9c41b8c72300d073c123ee3272a4f817627545e0360326fb916901c802a36bf55eccd46d7d488607d0e124ae2804442c4d86e0f88208bfa59401ef2f23bb1646eb39f632ebcc514ceff9f7aaa796f9d0536976380a61582e48249a8263ceaafc019e671bf69fa340647ed483de18bb22c3db816635a17b2b71297b31f8a652431615c39c8e74f55c33603988c277fc15d8f3c77e75054dca0b50c534af6c67f1466f01ecd688b23800379d7262df99e9d5e3500d45dbdaa51393fbaefd9f7a043126f0b2f0e6d0a8b87344f4e5049d919a2e5ae0332739d8b215764a4b4c32a5844aa2febaa95161ca1141a76cc342e3bca7ce7dfa02b9970fb3ec5b076f2d53ac2c7144c25ec0d78f709184295f4f7c2e6357279ccdc541eb22cc825ee10b376346b7b47ca5774b843cb7ff89133ff362c29c392ebb54f917ea60d4fba7db1d20f6dc872000d810eb779c4676ebfeee9a51bf9de72e2e447df7452b5cbc86f6eb7430f03089c4df1ad934a0b0c38365cf615b52eba9690280ee146279627a22058e968d051ed0d8c3bfc079f7fb5afce8f95853b4f3f87d7feae286e7ef26e61ac6c77a731b95c8102cf085e5350abd6a6c506db15eeb0af1fc383f8c5e6a52a792cd13f06ae5186e43509ae609a2aaa93cd0a167c24bcf2f88fc82e1a06cf17ab8b279c1d56551a382728d220c7b466087f82a38c6fd3766dab78468aa3a7d10aa69c723d19893ca303fe2b5eb3a710f5bcf264198fe17ddfea69ced1c2f83407ef3eefecf42accf7730b88213ad30ed06c87aada3e4c54029ef5183f062a89d90b556a18b0228d0f666f69fb38780ba2aef5a3f27a5fc8959de91bca58326d157515eb0483c701e64aba6c7e249905f9b2392fc31f0aaba6b0c0fbd9d708eec874aa90eb3acabe37256ba16f84f5039e056d865b2780191719d3b3fc576bedf1908b49612be2a3d67adbf3e6381d050044c4f5c728988137242b5784ad6c64bacf5c676e45e09cd18636d870aa224ab362eaa6bf93f4a7a2084f0786e2939c7bdd0c065199cd7c3234b3000b5b42d5ca91136de84b46f2ca356156d001495930c1fd34559b85e5137e0e6f04d0ccebfaa9a6c500f6bfb043b759c734a07e476717128d1a7a007e1c358d47508b47ac08aa913afd5ac86ae6713063007d89eb03a38017edc75a4deb7d87908d184f319e1fb24af548f624bf9fb8c4ea784fb7f72a897ffb91bd1e6448a8f957fb5c81bb3855eefee9313b094906f32ad18d74efadb76b239ea207e46fd4d320806753f95a895e3d7be70a9156e1d276681a2c2cec78c314779744caff45f2f0d7963bb02fc720506ff345ae504e9867793ce55e2d29e914617a53b1cfb2903e55350df9afbe89ad82ab1042903a7bfec26c1649fd41b9d585a114c82a3c16e9ff3454d0ea467f684b51e901f76b8fdc058a636064b4859d7fd1e9b1d7dcabb7b6ea9805496f15b8e7bde2abcd5679fe384661ab794fd5590b0d3716c26f2d99747553b73514676cb5fdc0d0c1bd9ea162e4b751c3068d248baf27e8e613973625d85ef90926a96f2bd56292aa642c2f5ad4a37e554ad80814721a2125fd2e13badd1c6673a3eb0e8afb476780710b66758cece512dfbe8d1e14cc0794133378dd58208549f4e4f50c9ebbadfd542ed21063388c3f20ef233c79c28fcbe92f08503858765d1371e85bc29bb95aaca50848550c8e0a40cf3d6c9faa5f2ca78dd751b3e999f342eca76ff47cac4e8f18935872d5cf3129ac85cced300000000000000000b96cf030000000075c126a347e0675975aa834606bd4b60cd56c72b8329f7ab31ca07290ac9cbdb25c01bbe862e0259c1f17750e18268ac2b737af7f910b45df4450bcc027f274d764dde98f256b30aa388cefeef7e2d977c8862cabd790dabf18afa3470965a0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000628a37ab0d913b2d907a2a25d85ddd60ea63259b6bc39337d785a14c662f9c6df0ec200025206757bc218479863652f9566e5f2768afba27043ee05bc6dc58403dd3c419760e5a887eabe00f19f2c141835b6758d35346d39284af9048e27eea6f9fc67de4c65478526055e44852926510c61cd0bdad912acf9bc6153c4ef7e3030c8a78d7f4fdd2855d93eac7c1997779a25131c798d9f7e05f265361c6f2aea0030e4c74e5ca96b11ca9447bb7303e0c06b14cca397c2f557f7b9152d4bca22b160b02465cb84efe4d05f2d6aebfbd55604a28e45ca84f65f4a343a2a9b94da0118273fef70edf51f3851031bcfad0395c2ca65fbd57db4e6764e3e903de97f7ffae032d178f13568e6b7aad6a975f2681d8d7bbc24a5a28bc06a89a4d2d9c029620d902304a611bb2cc852c5b8df655cb922db3960f3c6b94ef4ced3b39a48fe73d114a02129c6d8a5810e8f0dad8f604aa31bf3079c03259fb66732a397e4346207fed81020a711db19bc8bbc81769c3a26e5bbb1183c615ca8bf8e91b1d6716dac36646320330522e141b3bf5509e6e4a3fdd6b34a4a600a83f351fadf3db8c7dc936f1d72ea00336c070a2be2f58278e9cc4f262fe3b9ec7999a59e5bbfa5ea0578239e3b0100353fea9fec99aca5b4d7a7514369045991afe5e21f0f02dcb6c6b9b50a7dd63381e1ef2644c31561eb1d297822d06075362c4952a93c6ff9da70a6853e7611eb19359763283c81f2ebd76cc8e32bba81343b87144f0125ec6771e6858b230bc32963ff0ccd80b29842b423acd3458a1b19e88ebcd74e2fd91b441c9f126dc588a9c6f152694b8e21e61a1c9e3dbe6c32223c19aa0540e43c369081ef4206f4b939d4359da50080d0d3a41887aa08ba2506d4d4ab627b0298de398a0d1ecfa135bf2bc0f26367915922c8ca0f3cc83474757747642fdd95393b2320704374606409062238fe5fde29c46dee7c69ff455a97cd9d489df44558d0d9d565a0db8a97c46a622448ce593b70859ee0cb511be81dc172e44de2d0fd50ea5eac8f3c9277519c898ac9395d87b2b13edc7f98c23cc4b137f00c6da0ceea1662a3079517690571e232b1973f46bf912f4da21ac6b5f127573523f3cfd3b81325deeacb7965ffd76cd99d7d03189a572b918a162f211fc1204bfd16067897a143deb62f2a976ba53c0408d35caffb45239e5d19204715988f5adb6f143bfd29aea048cfcfb0dbbd4b5107766591e94b8e971782a585965106cb870a3a6db549d0ef41fc2daf8243cb0ccdeab283c7aaeac4634acd845912c91c46625255177e8ed8360ff890d9e97447a2050ae3185a2f09dd59642a6ec30369826e8a7799051792c73793eb5790d1ce9c4db274393bf4753c1f22f5181a7578eb03c2ff9eb42cdb39d42c693b445148beaab9dc37b3a214cafa98dcfe30eab999b0d21c831b56821d7dc973c2ba4ecec07447c781946b0c8fb35e5ef1bfb232fae5da5a243965dd288d21245bc3753e42bf47eec4de420ca7d1d4a734400858953ce0703e7470336ad49846b21e3a0c7b40c7fe7930f2a36e65ef514fba66e8a0c75285d2750e814edab546cb535ae60a782e9aa4ea7ac08e117732025f34fbc6b7eb942135a1aa3e8e3b1b4c669c4ea77a3580a8cab3e11595fca6ba35ca14af125b7eb42e69e80c0b3e13937c923bcacbadd2a2857c0bd12f0278421d6dfbc889e7934c1df5c7261bd1f39590f910402876a8660c6e6cf1ec71fd3bbe786e0e8a3f7f359d9b2b07a01731d1f8940de316c6deed19746278a77a22cce1ac15c2dbc5424c722ee6bb275e2a1c7e8898e35477ec23a208d065fbdb6687782468f5417e63c6f0e2d9464bcebbfc68387bcebe50a3647f63dafbd5bc9d6a5bab247f22ccb5da8624e01196374a5a01aee9cb2ea8d98950bfe86f03ca8a0138df7672e380b97c713d7f8a585d4ee45cc87cf85228bbc6df74ef7081355562bab72aa1503282ab964702134412fbb7ddf7f63e758b29fd519ebaa9dbb7841debed4050cd2cd6c5bc8f443f40605f5fe2957eace39c929068f924fc97d239868bb55006e407f06f5d2be7d3cf6eca38c2b36a1b6ce9c63c2ca63b6af143c427f46bc64f346c5227db5cf8720aa5e98191490e0f31364ba9f66f3b28524436b676c628d46918d557796dd50c8cf5b07139c2912c93043c8364a179047fb7d449fb847d81f436affb89aae69d2208f285987e2c9f43c24dfb7dbd523191d4f3f2203048dc5b9942a41cd460757cf64232a20ed29f23495214d8e333ab6a0daab8549bb09a6f5af452b21459d2f49a566249e1b2b20d8f3be7bd9b0035cb01cbe624e66e86849995c305d863976fc3abe4d683c94aba94e0d8ead97c26b29877743db06ad01ef5cf4571ffedc3dd8e415be9b94fa3c5d941f557b0ba474e85306", "6a005351ac", 1, -1648583335, 1537743641, "4ae3d4613e33ce235ee3dbdeb63f8bcaaef7c8858acd031802242a65bd31fa07"], + ["030000807082c4030376c7cea2cf8ce7add2a641b30b07636b23517870d67a39cf188f5db816a6844c03000000015393e320fc0a442550c8b287f892c67770dad471cffa0b7d3fac46e52279a4ee59614be1c90200000000690676d3297a62d7a442dc88c117372b3e273ccd3e2f4457753e646fba05075d3383be40020000000952516a656300636352bda0ade704714f43000000000007635365526aac00a31854050000000004000053519f40d5030000000002656af3428504000000000463636aac000000000000000000", "515252", 0, -812182387, 1537743641, "70b892580218d49d38e0344c6cd51ed289abb9308cde1aae3f4352a9175a4ade"], + ["4e913e0604161f4a6e972dde2aeefcc970c7d821d7f27a9da45a4f542304cc6118a2061d97020000000151dc744d9fae924dcf4af8a81bb0db49d6a49d7f7782949b2b11384d31573e0295c748f0d40000000003535253451ec13f9255b3f31bfa8e8de81c8cc7e0895cb72a331e55a29ba60407401023c47426bf01000000085163525365516a00ffffffff0797d0eabc7fbfffecc633e8846cbba2aa04cb09fe32c2cf5e9a981e1e533a0b010000000100f4f5a2f8042fa34c01000000000351510010e12a03000000000653006352acacba6878030000000004ac53ac00951404040000000005536352526a0cbdbc7e033f7acb0400000000000000000000000061965221effa7fc06a25dbcadd23849750cc55cfcd184fe25a057520a93c12b64714fdf9066db3cb27306dd49eb94bda88382b24631c6b8cb3b61efe45befdf266439c98cefa1f6baf85aa58bac622dd0f87948c368033e109271f295cb9ce0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2bd1875bf1756a99fad9fe0d24c34eba860feea26baaad769786ff893cbfc0a6dc73a6c83a270bcd53afe678585d89a4e731d8b307148a5609758985c457d45fe13819d005d84e56459f564f7abf8cfec88c6990d20896ee6966c36873f7acc32d516c2a08f07da4b6a9f4f0992bffe949b95d78da010fd1ebdca78dcb20b360219111d50dca92fb1f5bb8a91a000f9a80109a20d39fbfaf9479327402d112e840309b997c71bff175c686cb0a8f22cf5dc662c5024e1cdb8f161a2e7ae825722370b02081c911fd70d9b56286eaa6e4533c682d6d9f46e3105947a7d8d4d3366d21035e9faafc38a9733e591cc2f61906cdba7d39a5dea730af7e811db90287f3bc50211452d4158e386f1bb78c7ad0816767c345c5fcfe3fcef40ba2171fee8bf63110222ad8d18279e898219018d7ed6c38ff7d0d97cd7585d65f94da8eaa427e9ab51031bb32009d3b916e4c5b198573238276e75688c11c51c61b5a7d1a7a35a1d1e72022ce53fd916656538add42edf46b8d785406948185b683c1f93dc963f517dd1c502151c2971bfd780a503f0f6b88acd452c460fef264ec2a284ce12684c0fc03c14aed7521f256fd4b4a14e80a1ba7de915c6437d15a0866f8acec5d84d01e1da013cf06c5acb2479c3663162d2921c598022744d93e23f27ddf99f2aad904f2bd3cf8e26027acd9eef47f59cb783af0a13f0a632a96b60c4fc0ad88294d61443a398fb4a6bea1d0f1e9f1998b85c3ef3bcc1e3c4bbd47f73cf526b367fbf16e5511dcc3ac8e507751b617d161310cfd67baa3f48f2039be877b3637ec9d873f764833475017ee3febebef3494015228e9fb51ae035cb01c95088169c0eac8b4662ee4c168c04015c6ba054e90f767ebe4d7f8e9f08f7aefb8fcc781c634b9f65e5a2fe403dabf186caed3d2936ec1725a6c39cec6ee48e48b6e875adec016f71b5df9e64b47bb2db345157b54fd5ed8644a89e8c49e71d43d9f7f467ea026b4d8561d8a6c5203ba30546d668d8f978e2e9e1f224d1c17f8974d22c376bbcda1cf84a14a879e236f59ff32714d1e9b7bac3d6012848116b4a27dbc7b1d82cf9fb1f521bdbc623b33ab477f2e9ab162a1dc2c5eff8ef21f3c26427f405a8cd2b8ad410cde0df4a0fcf11fb7280c9eb776dd0b0cc30465340b1608bda99dd0be5754b65123f50b1ef99904f9ac7b1b6b68a7da86b4c53583449ac444918b3b7f6a11da35c151c61d52cad2013400cf3788985af6e344f42e8f2d0dcb43cd9c6a24c4224f67373030702ed7d7b68131853af2dea483cb951cb44daed2560e8135e855c8b647de4a64caec451bcace9268dcb5c137ee65ff4930a1977f604314b568c956a53ec4a733c05f783941f5ee1d2b1d88a27349e3f56be9a4446f0f77dcbf64a958b424454750c33a11d584b029b8d0b674522bc0522012620596490860378b0735155bfbf2c48cb476ea5b50e98bc4148351be368c1f22a57920741101c60233232c3c51ad7b8d6942995ef62654141e77b94a01d67147f46742a487b40a668910352c72f08de6c13105c8fd3d1f65de7380b0c853f2a813a76b720e4415de90b1515e3a237b7cd783c07dffe616eac06ac7d6327ec6524dd43426e647846049c03ad5ebcc061fa622ee9eae80eb27b632c3611c6471004315333716827e7a78ede1b8aea2bd364dda02a4a4eb447456fe4de9838c5b500aa595eff13bce2f769ddf33a0f6454d3d4f9b4ca17bbc92ba65b1c42856ef05decf788d827b0097334d2c80c8d5da155e3073d4fb2cd19b450e59a95e0d9e7f4f4a03282b204743a317371a09fe44cbc5a35f7f91936e35dda6d7bdd7b3b25310b5d35f499c76a99ab132b1925f0ff4ffa75d919dcae18a4b1641583153759def04a0421c4843f2a74d6cc4458d0c91da8b210371e53505d33bac59381883b59dfa701b6832e71836da5c9b9027952a6b9bc4a8fbee365a4fddae83948887d7ae6c9ccfbe4c0e61abe318a0a9f7729598131132ef3580d2454e9cc35e80954901c121ae582d78b86a4c751e00739c2fd1fe5b5f5e690ad6c36c20677c130662f7dd6d100b00f4eeabd8e2115ca570c6cd92ad58cbc1bef733f6d7ea8102c7e9425559f2f6dddc2e22e6d073d23307324034bd7d760d864bdadc269c33bf2de3c689f75504f415ae4f7d04279223899fc1e629b849ded1e3b270e09cb660961f704c744381507497b71ad54d4c6b5301eb965daab554b3de221a47bfcb70c962aeca548a4ab3707729c348788f19542b3b46b3c0196f491e6506abce9f204000000000000000000000000e6a19931010041ffdca5a55ab5877da389c8b9e8c2dba2500f88cde749e733e27ea3e5b252c2b8cd16dc7790113dd2591f73bc33e63288806fcca10d97a51abc594493c49cfef2f4bd30d427c9f0436b08ac875f86e65db181a8c469191312d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009b315e1ca9ce820aba6a9f6f6817f4bf94d33b94eacaa29254bff3e81d5e19e7f3de3a49ac38a93c969692402b67247802618630d78b1aa46a1bcb4eb3e9e738e293341577c8071e4e5483156bc688a512ef0a025b7e946d3a69c6f2c47692d33488078f4b46bd1a380cb5735d3be0d89b35776dae1a0a6485d93ed0b78c7276032fe55ec742b6f68cb77c2b1855d353e0194addeb895bb5e9aba85f3469dc30780219ac86dde23953aef57eafaa343abda574efa672e5eaaa492e2936f10c3d11bf0b0881070c3d891d810d779ce40792b687f21d7b8c73ff37f9fa5f0064d14f9d2958bf0edc5ea8c5fd5d0e0ac9ee5c632f792a6cb9dfe9c572fc3ceb409ab003f70207942387f2f301ef1e8c7fa0ab331e14707700dc9cfb1be48eb1b85296792a610327a5090d02f467ac39e8c4ecdfd43b3241988577e3766578f091189fe394e04d022e9a74d32f50f6e2aabf68680825b4d6968dc754730f2d190b9a81d383cc61fb021a6ae6c92b8d8c8baf933154bc4206aae0ba05030d66bc79b8defcbf290ba9f0020f27227640a7e183fadcc473964db245fa262e61c23650b51dd14982f128e85aea2c40086f336ad08907ae5f375c29570eaf6bd0c0a99f403d7885364809db39f1adb59880a4814bf2c0cececca729b0e6557416175863d76322068a73d23e7fa819334166768301499799906aac20d548ab8bb943b52561b313cb28a23e554c07ae4d4f8443472ece2494c5e9e0db67ff5ebc4972872746fe316fa076b881c9776132558e6f3a4faf7a2fe282b69e3e93903c02cdcf6735651acfe3bbc1ae184de373ef75e0a4986ebce13209458bab884fd526be29340f5a198ad3dfc23db4d3846968ac37c2590677dc8d6b5b1fa7a343254d52fa25ed0fb6b3071e1b09085f43e496ea96912aae3814fc22dc32ba5afc4968542168ca5f1b1cde31d19d9131451d44dc03361a151255b81bc29c04e9cfb4b2aa97a38ca02f804dc12607b8105f7891838f785d8c341da620905f815125674da7c1b9d61d7bf03e80c10d87ea90e844d820d0ad83511cdcb37ab143ea7e4d5d28ad2153f389ad1e87d4656a896871313fd3ea5e70c769e0e94ab9fe691d40b9fb518ffb0ec592d112d4ddc6fc168e5643fb04da04b6c51502a0d5f07e128f6fd52a0bde3588308fa5d249c2d3b99fb94f169e1372ea9990499f34f9516b36fbe4b9976c7cc8d09d2b089bad59597d69e2ad9bb82e7183de4c758fc1a8502ed77731812d1d8f802ce9660b14212e0d28278fe54b0f6dacfe50d47dfbea77ffbc589a82ddbe16abe6e7ef86b2f90ec8f4634dcaaf357457d7c97fae65dc73e25fde1c1257107a0982be925fb97df6ccc9e5512821e490ffd8e0729d8a78702cfc5154b7c7d78ea425bf5d2901663d9c4bc4efb93e474c540779aa440e60b1d15406ba6adb4dddad6efd092ac6781c20c97ef89d1c70b58b4a2d3075b13f9c3063053a580889cd2a8cfffe1ee3eada9f0388abebc16fb29e955d22a25ae521b12809bffa58935ee199a03bf5b36c54dfff1092c824bb659076d07f31e23f88442dd8c5e271895246c7d0a3dfe7599754af23e8ca0b79849e87e0e793a0194ae03b06216965d9314a4ea41ea2109f7b137d5a9e5071ea15d6869e1bdcb1147bd3da4caf29e7f069538a2dcad9de59b834b89be470b089c468fd8b1889fc00c1ad82cf67904b7ccde7a284cfec3cfda881f6b5252f1a7a6ef8297e9100dda0670965a928f10784c00c492657d44499b38dccccd5eb10bdf321d0e66f2fdeb5245e000ea4ee110d40983d6338983895be50a9ed08e3dc8f04becd0c74625ccd7872e691bc7089371fe66f81e84af183ad679c423cfe8c8f50cbaa07d6449cefb48af69eabf175d8cd28ec2b7c26df3f12390cb794a311220bd098b68f04839bda8c0e07b42a1e100e1d4fbdf90a90eaf60e801be9d1a1771ae9e8c01d37369d8f9d2dd7cca7c424a3f51fc39b721d2078adfdb6d22b0b1120d3dc2c2a53f9554849fc490e0fe7d637caecbd09d86bdfb8efa8741865c3ad15522c486f6d99974be9b9cf18a6a5e8f6a8ed412d2c723842cc9d25e797fa6cb8cd68a26dd508ddd0de2624e6bf468b6e84feecb883dbdff884a9480f05c9fd077177a00db694c68f002447d615596a6a922cc62a0041e5821b852f2e0f7be0aefe2e474b1db03e1bb467de005ef8ea6f08e53b6a281264f5cbbe805fcf8b2e2b0d23d3d96eec947b7179b0c496b480dc5d2b8715d3045e5b6b096a8353856b0dda14ccf18e76f27bcd69a00100000000000000000000000073a7e29e76f5f8bba0932239fdc8557b07c000a85c59a10e826509d28bb22aa72302470aed796abe27dce6c3a29200423d1561a7d5f55b9082537a9cd16e470b2df8a130e8d8ece21b2571db0ffc80db74f53cbebee80fd220f23695e34490ce00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000399215ff0efdff79fe5e4b961052932fb8c97b667327699bc7ddbb65e6e477d088f4a7707901c93c8f1aa9ecb75b636d1c5f897022d558968414aa394026a4e21c543c303f327c0cdd698a71bba5d5fb0496138ea129894e02c5e28dcff379714b0cd18192d54a362f99e2fa8e38031976d0055f8e7f349db070d6bf312833eb021e7af66a39ec70b589937676d91f3aba68536393e2a079f11114dfb77ad76dbc03053be665dc9bafac50fb56e435c9c780e8ee6e2dc254dd5d46142727d03fef600b08c7aea0b5a6ae0984a500bbc96d4a3b3f9e1021ba0fea1863c6f281cb28c530dac8b3aad06c1186ca664da18ef52a09215d993ea70f6aec0d2fbb567a6e06920316b06a6b26f6532b6c74df636576a60464b7f38f8625277ea62599eb831b9c52030f1b88d33b39e9edc2f1f431f9dbf98bdf683d6a99eb2869556855d8ed0a39110207344fa0491275d25fbc4c3ceef1ae6fddff14ef5bc1820252abe8218c5750dd031b21d5ce3e290390427bc37d79f695b9dd4cbfe75280cca0173bc0c97a33592003227ab6661b84015b555164e641c2fa049314720b62208c82f8a496ee615b5f2257d58703c5f588c0953e0ad5fe2a57cc8a42ca6e6d7b419c74cf6a38ed7f9e7a66dcd8830a34f0c820cf40104547bd545a21dec48995cdcb9ab9519117deebe21bc05c474f7652423135229370ad6116a6b85d03a5bbdff2248c3debaf2f50c83340f65a57aaaff16aa225e34e0c7baf71bb635da38d8ac26da497c16b3af2dbe4abe7ebf0da323121b2b2b769e659f070299327eeabfa4b9fcdf749516b3217b045d18447b1f87c42a94d7a76c0bbd89f6e3d5cfd39d1fdf0f6bc27552e42949b21a9b0886ce6531929f5a3b68eeb4a4bf98b556094f74bd6ecaa53df1ae1f8c9be362a11115f397d52b2f1c2665ff220b1880b5dd0a198a211dde8e8fed55a0cbf64494137fcc743486c721a2c6ba8247fab697abfc4db93d5ff269982753bc4d7e897c946884db70ce73db5531c60cd63ad0058cd5cacd5a436f0ef3398692a20d692a5650707dfed616b08853cc8b123acd1cf317d477f117fe050fe907f82ae5e181eecf13b22d127b00a43e52e1afb02137d217a997de69363861e7961f01386ba3da3ea589b22f10afbd0c938ca4f280b597b40a4ff472b3d4c34695f105e1f3e8ce74948af0429c61650fdd87b6eb0f0b88e8ca4a18823f1523e84fa00d335c54d8b3cddafdf1d60f6641a131be6ec5edfdc5b780bb6eb5596a743131348b0e41ebff5d297071f6d37d5e5e56a124eae0d422400b387a0f295bf16f27ff1a491556e5283d8b9b3474941be12bb69afc223f0e0d1958c4f9fc083d03cc48cf2232fed901c24e3b4cc97c8f88a49132263e328acab174444deee859c62aae72a18bf25e17c28b6e018fd3aacb2a38508b509fc76584cd9197f2471feb2883a3785fd6dd8b3e05af30e3729ff61352cc10ad86d04ea14f20ab9e561bdaf65feb6c7aaed2413b08590fc7e82812f278258a6a36655331d633472c9c91c0bc68687cc3246b8207c2649822a1852cd22b7143bc02bbab59d9a8cbd2520af6cf5af4270817cea40d31567856038833b037913597c72bb528bc0bcb87cfb8095be314cfbf3e067365941c9c2e93c8132f528550fe645acc54aa276383489f20be5e089fc5d24acca45059e0bb025a6395d724d4045c73e250cc3bcc8efa73885f3032ebfa2731aab09f89fec695698fd3edfb2df8207cfab6cedc2efcd74578e447c25c67fff1b75256b5a64aaad6632e63a187a1d0c8cfc323147719f5a8830e45a7832bf9ab407ee46ce562be16aa21b564a9128ce08e8ea8843b343dac22d002d1ce83c67e283ef770bbee3863792061fa1f7a5e65964c94324c3c69212a47c81bb1ad5db2f87dac7a3a09684d23b5d1b279db146d6c411671b700558e55696fcb4257ae51d3ac2c7712ff24c09676733d76bc1f88f12af3cb93b280d5503d8b00ae07fbdd08a7b6de258e10639e9c54f11a1759f0352df2834eae3afc6ecfd5dc745d70ecd4d3688525cb79d10664b6ae65fc4cd8f9616aff0eb8b41ae13759d2e5aed122828060f05f0bac9c0fe20ecadd93aee25906fdff3dc6bad85a720ac895f07cbe0ea42a364edcff4539b638208806527f21ce6fa10e991206186b92696cfce6e03d1be68df791621367a80e78d39856a58c16ffa2cc9a17a6405be564bba82776b114f02a483943a3b12eff6feb1b3d9e82f35888003221ccb21489f53a6ae77ccdfe343cc0f76c793214525021d2f80116078f76e35c4d51cb97cd1c14a61bb6638accad3559b91df1623705c9242e5b7ae4fb3a7cb6427f7712be3a4ee9a366a60ab1cd95bedf7c6c4d79e1d5f970ad6be689d03644fd0895aa85f2a273e1a3b3d745178baa6a3f0af6402", "", 0, -2106854420, 0, "ae35bd5eb6d6a1a242cfab515628b3426f65db0c8f38c28a2390bd0ede324673"], + ["030000807082c403032e55017c69926356baf84d5a05232093e90341f745d8479d486d5babecccfdc2010000000965635163526a63ac00ffffffff2bfea2b091dd1cb124341421a81a370efc1495e4fc90c57f0ffb70aba1a3ca7e0300000006516500ac65ac62fe2a9797246501c66ede45e171b7761a7a44a9423f49230a46322621f11932ea144afd0000000005525153536331ef28ee01ae0d7c0200000000045152650046242cac0000000003c1af1d040000000000000000000000003c455071a8f80e2fbb71ee1880c8159d0a668df04f2dbef55a6d310ce0819e607274b65b8f745af9aa8341e49e3cd20ec18d71354a04214820c9d5ec985ce2ff773196e7d8a3b06ab320975a1796ab1e8ee79000679dd2b637367269f05ad1cd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c73f38ee2c075072d93bda31dbb11fc872720a2c0f35d9e65771a01716e3cea630eb1ae171d9a8d2d79f13e3ab7147aba427df52992651d1eed2bcd9bc7de0fe6380654bc6983a91322f50834766c4c14cc76757fdcb052ff0e75ff809a311c2ef42d71dca9510251d5b8ec9268a714d8d6a397b0ca638caf18d864e0f0f8bdd0223e857ab61e7e043f69e242284b80fcb9d02b4e5b7eda2311e61960112358e1a030c53f86c4e899fc7aeee457ab169b301e818636294ac91c0a8eb52ecbe9910590b009f1bfa94539d5cf0e1a10cbddb4204a1b5850b9bab50a645600fbc50e9ba1b8b621760ab6dd12d4b20b3f863994016e08086d3c1575f55e97f09b88c6b55d30225cc0188e7e9ea2e58b8e30ae5e85390db6f28fa1b822e84113218dece6d0005031ab6d032361deafb1b160d228eed8af1ba3949bce35e9b9e0bf1b8f25860612c0318a2fa4a6c59c8efbfca5d649a846fc795ffe2092a9ab07559e37b8d161993520214ccbc1351c7330155cc97d5db84e0f381f27e3c39ecc414bbf8c1953d0f5a6e03131abe87f8c9fb0ffa2d2d0539edcfde6d5bbf7447158897a9406a1d08557491e001ad23dd83fa938c6bd2055c041011f7780c30a14b4e8cf7b86ab913727621a6f6f916b127970529cdd0f0b8d3fa8d0df69991e5e4b5ed43e9d40c8165187615bd0fe5a43b664b02df7f0051635c1cb60b21bd953bca5a4421e81bd3bb634d02883c5e977714b8e6182815154df97593eecf152db1d096c8af81f5ae8db5772fc428c0fc300d39b3a384b3bce857b41a72a9e1a06e7387b6559df1e57a501558ad7e1e4d545678fbdd01ddd9583955d9a747e271f4016fa825c1dab993bb0d28e491b27214973ff768801556b36b8c9fe71dd1a3f1819df2cad896fd1119889231b8c445a43c7eac2233ed1ec0a861e7c8e646be84fb72c8eb7d546161fb80030e52307455010d7307b3a42a9dadcadd5914a63902c16d0e7569f418c5aaaa661b73a1bc78ac8707d9abaafbda0d360c76500fdaa6c22199073a91c2c25b3bc0801e25a97f0649c1442b01608e03d98da0d6f85c0cc79deffbb7f4a05123ffafc6cd7d4c58ad9aeaf9dc0dcadcc30f8efce4972578b94c6f1ed75fa1c375b2460d349fad3c49d985cef0ed00cd453887e621ba978b336eadb471077ba7583c78322aca0acaacd87c2e57cd967ab07090e793885e0206d67e9d93e80da1aaaddd3d711323702eb21382a084527ee0ebad65a9d1355e5de220c861a4b6b9e03e05ee6b0637fa522308fbd50b4488a5f391a91a9a9878765ca5edf0fc7f287434a72d121c8b8e5c1b078bd2d894924b9b3274e535d64f418b2cd016f1186144ef0499fa337df5dbc284e4e92680926e75bfd23ccfda4b1fa3ba78337a7e35221c4b8ae02b8839b4cd9351c2e282c7fd45c945346f144e0e07876638aaa07f739625696bfac8fd55f30095f9a45b49743976db1117f968bcd17f41cf33b9d01d25a93c70b6ac2ada4a4790da3682036f097f307383cb669e5f4aca217ea1f7c91c54b5fa0f7e76203cbadc7add1d8faa38e07db3fdb3466a0c01917c768a5839ac74323dda1322a01bd9f993e2b58661845c4c9cfdbc993dc9e6b091ad3210536d05d47a4d0a2605d2e564858dbe67cc2a02f39eb5ae36d4b374b057d5b83890d89b73e755fd152d884d137482c2db747ae94cbaf1b84d1e13671c8266582140823ff9391841eacef83bf1a910b99293a72e640dfd1a6092127578b1dc93d8efac23af9dbeeecb58b10a3cd5538dcb8a0e24898af0d1a32795f83feca2bbe1fda17907454cdbcf586f6862995358a7fccdda8ff6809bb75c165feedfa401ada27cb63988a9b3f673cd7972e877bdd82885e4e6020967f4b4fcb69865563d5c7016f1ae19a2082f4cc6571e39eea49310284771b622b44c2af0c47e80e0686f29f411a755fdc063e57704132ea829b3c662701b3299748aa4fb100edd5191afc229d9fe0d456218a1499567cd8bfa3336ea876dcb96b1119322f3985a20257b020fd84e781d92fcb2634c2c7432f7561c4beb01777fcac8c7bca36472236de083862d4c4cc5ba241ac1c194929528bf7fe513904ead50d585a06fa2b1697f3bd0d710effb7be1eb80d7440db7059bbd8b558d4447ad570ae8c3aa8fa9309352d18c19a20872957d5358f88aaf320a94733389caa8b40124539f1e3844977fbdcd510cdd94f8b09cf270cb5f6e3b63768f2ea44e81dc4701327ad7d50eabd35a15c3dcec7fe999b7eb493a825878f09152da5ce6bbac5002000000000000000000000000f799c1c12eafb72f361d7d435eb37a1900b99fb26192c2f56dbddc9b9de933006890db51c74df590047e245007f4d31276cdf236825b771a0d92262afe898f42123cc585956915cd2d66db13b73c2dac41369e5eb99ab53ae1072b5da57130d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0395737787fa8cfe52d373b7982f0818be07bc7bf7ca3103212a2734a0b7780576a497c075b07d61e1fe5c2e8b53bb8e31348467f2f3a32ea9cdb0c82070fda13df3e61323b95672003a206bc08f94b1945d3dcf3c7ed3d30753f889074e18636dd511e9617304af9be24546985f55cf7477984dfca108f0f6c5b5a4c327253030b766648b15c43e2034aeb19d24879f663ed91922e61dc2f6b1027d079d292dc0325d535c97748efadb5bd26c01600ec1f4aac10978eac28a18554b5941824ee880b0750dfcaf45eddf610b976d9adb04cebae7ee1ef47e4e0249311211e517f6aba8cc690876a16539f68943a31c0978aaefd4f63614fd4889e8786f66d15edea7b03290013e10426c6376758ca87c5e40a7b6c93785e772fd3282b9ac493f4e44ac70210dea2bc84be5fe725d44db2881a737f89c3ae13f650a509af328d500b4d61980224eb1ddf0ce3aaaf820c63e3e49f0a946190d6135f217245681c2c309d60e268022b5a29d39d70105919bbb106dac07e8991755d5c100c97efdb1d78bae018682a0310732597c1df068f3b0627287848ff847b989545dcca1a92502198d3d8d31349b53ee1f8292f99b14f80b82ad48cdc0619cc229e2331a37efd6534809a105e94058b640671c1f11edc09cb5e4379f6d3e4d2dbcd012e91da5058c7dff474bf364e587b91bb7f076d7ae4b425b5af8402caa5efce7e4fadb024f0d4e0b75764e04bf54458a1eb5f752d3152eea57ee5dd5f3a3f7fcd18544080c9594ccc1b53da1b80a853923e1e55fbf201eb5a05c775ed48097bbe8cfda8e0720e52fd41f79a3405ad3241b7e3d08f0998c119469601cab6b3ac1418774340e9954a738cd80068c00d1b5052030c5faee4786ed644597fc512759d682987ebc9bc13c42cf5fcb2485b789fb18046f349e85886aa7be0a88f26f0717c84b7eb74acadf805764a3fcefb830fc2e536305b9562de9cebb3deb2e4e8050615bd18ef65a49dc72c27d722c24ca333d0bdda3ee210bf9a5e044cbbf045cbb422e32c1999f366eae93b4ef7fba5c564e7725f833687430f2196c40c5895ac4f74a191e30e0f45278397c228b74423f80c16660b989d2fd3384c5e4597f4d970471caebc454a7e01a4eb8dc906eeb800eb9d60d1051cd414c9b2cebde018551f34c59be575db406352db8422e0bab58707b65d21740a036de4584181f0043e78b15f8a195ac987ba2acc7e6c5699fc7ffc86bcdcc10f6d80a5be04abfff23ac47aa1aa284335f498eff225d5b209da863722d7f602e661553a33550c933d4178fda95510ac6696f9d50b5cdb28ffdd93f8805edcb1386d3fbb9d223a9dca0d15098995145cc3308b3f09939b56c80b7e9d0d823c89d615aa47960cb08bbd840a165a8bc3ab1a01f0f9ccb3325482ece55a34d7b84f93429e60dee98820198c5319ad5bbf45f1dd1af00eab9d1a8f8e7191dbf02c40c3a7b665975a35c61317ab9027469315b681f75cc26a1ce431c754e30b9118a6b48e46e50746e301cd366acfc12bb338d877d79cf8d1dc63677d981fe5376cd48637c56556983b9fde45f3fec938a072d7fa0b2537655f50b7a7d236f83c0eaaf5d59e834af23380ab053e67e55221a01c9e85bf35ce8af69d3d9e0a0e91286a387c54bf3ae70030130588c26c9d10e8b810815fcafeea6dc3795bf7512b454926762829313ffce62fbb81cc9e6826aa6528791debe1c13cd303421d0f2b00dba65110efedd4486f18ca25d21fc371d9039a0c04a84371aa966ce9a4cfe27c3f7bd03ff00f003cdc3ef775803b5e73de74d3159ceecb459e9129b17b1d0fc75ff79996814f779c7e65aa29895596c85360bb4938001a3f8d8f26eb8d0616714a113fa3c88e82156217f0bd419c66c3e955131f80951bfc5ded6322b38f0c215fddae74036445e2b79282882b1c2948aa7d732b61d90407629609920d042434176fa181208b96366835973dd0b58ed9110ca6f057d908e839be83776f45ba99395bd2652546bf42643fdeeddbea83cc6df25619705e14d3aee67a7eb81a2c8c9e5dd1ae3a6077b4830669fe2777485d40f5da3f7a39aaa9eeccf14e266446db5cccb6436079b9c9ecde1eda92eb535463ed68dacb437b78d8e16066214d9cb40730b87930ae108189388815a219811788691eef3f53ab56606e3fedc760e1dbd8fd8124a39f69be08d232776d24aff65ff8643615dff011e6639a6ae8d1ce381b1a14f199d7d3bccb4e9af0b7215086facd691a603ed1bdf3b55fdac60b6312b140ab4b517733ce0000000000000000ba8b6505000000002db3ff72595543dfef70ea5d38b48a8ed9523622ae24cc895683fe42e82c8b9079c87bbe31d06ec4cfeeab529b7f6aba667214d7b24fe663dca614e9365e8b6bbb6538dee22adbd1747a3f3a1f4f0617b2cb7491db95f12bb3c3b49b08e02e8b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f726bfc2aca280408c1b5f6689b5ce72cf3028cbe97c59790371540f968390fe97acd9d2a1e558e126cca52da3346f2a545017e2ea284aa7a8224c6a8f1754c83222faf173bb7d186f30017caa5003071d58cc2eddc85cdcf2a8f4e8f2d580f0a833368a29427350f4c77bd4cba04279acb37e31d3c3ccb0bea5d338d88fa022a69750cfe540600bb399fcc69bd52288aa63224405f3127839d701b4d0a804003247f0cda8c2e57e85e8cf787c1c1baac64adf7f70bccb491eeec52162e40113d0b04f4043413b7f4c71d177fc7590c61f6a2e7a4d02dedc8be304466f2f24bace7fc7e2801ebe46dfe4f82e7c850635fe27ed77287a8c96dfaa58ef02ee903f51d030abce5974f5a6a1143b5b79145e48c0010af012191040130840a6b1d8ed89a93032f9d7a5aab7791bc3d4f0d16e0ce33f2ed97bb8ae1177bf89732d7293965fba80306dbfc2b3baef42cad42229ea3980619d0797cef9527e8688cad00f834f18f1102182a0cc6cdb3a02900d1ecd5bb5601bdac6d32e44d7f423b6161fea6708a8df403264c9503f6d38002a6334c70deb27de66817b15ebfd0c6dc1d4221dd287fda85ba79417a39999390cabb3115f9d13625693a72f16e15622ed8a9d538c784a783114e7f8e85acf3bf08f17de2d58a01738cbfd51cbeb35dbd138b513a2328e542732501f22b1cc46d712a5d9f22bbe8edd81fbe73f80759c51c91b553900c682484e51b04265374bfc3845d09a0e90decbbf9c580ef1bbf53c29c47464921685f2cec8750297c70d3b4b1a2e666646b53d68e41919679c920b0009dba85029222b57a77cc5f812aa22c965380961fc84dfd83cd12fd4c59a2667a0322b3aa2adf5a3140f228041d78ea408d7f574767112dbabf5d7395177505199fe457ca5c0c601970f3fc5faf91b94f4ff67595ec0dd37e5da0dc2f3a4b68a78de4295e45c5a92189fff54ea7a8e5cff9523ec36b33d2544ac4c9ba9c9b67d25f584db52d9b3f98ed1e2a801adad82f7470a7498cd6a5157bd67e18baa8e987dd5158b54fabde314f39d26909249035d9a655f9960b690063dcc1281634958724c79050478e339deead3b8f6c6c94072f892b7d17d11d3f71bac5241291e7cf9d361919a3f44072997b82a78d6d05f41f33a447b8e6fda31f8ffa5ae6a25ec7d4fb503e6e533d1e81fd4579813f83063a6eb340db45dcd02aa1117614abba1e0ac0fc1c92734763245cbac29b5e5a354567e809543a619bc67884f9f20dfa111c5946d92f3b1897865a3b84a5426b9528edbf8a9c572c09d489c1bab2d7688377846fb07524da77a56ea19412fbc251e663b8c1cc89bb2b0d267182bf114533980fcc9c35c1837c60c89e997161254a748b85149d445b1813a40c22a8a2a78a8b5144ca36092abe342f61a0471ab7334a789fa64a5dbba28563f094f547cdfc136269ce66c734f5007306edc1bdee6db1bd337c68a16b8ca10c86c914144cc3cba7e07088939c6607bc92de121546a966e337df8a4eca9a1f115f29c4d8e2cd800bee796b5b8871e7b1923ad6ee05c31b51a7fd1bb6c01140f8c98cbc7c7c64c972c07cb836666d107a253f3608f3ceb1202329f826b5fe2ee159ae62c8bf2519aefb91810dc25f7880f19deb83803d1dd4e1ffebf741eb2808940a0da1e247172d6e1abc83f0bc5010123fe02f1144624698b0c74d04ef533b6bca8de5406412a94e5ace4ffabea00763b49b9201aed30487999973d5a2cf4ff1e534b9d6a110c2ad24d76231898d9e47892f3e0bafe546ebb565a1878f5b5249f0033c44a48083040b4f9b36d578ac9758a629e942c6cd2c9c5bf01659b834931fb6256c8bd81f6491c2c2f2119fbc9a8ba29369a3a752b4d974efdd8fadb68c9318008fd553671a9ee02f4efea84babc1ba75a2ef44060e1f407ebea21c08d52f817777884cb6671c04232cfb50b1434acd5d6c8e64e1c5c8541331b9e968f13af421bf7ef5be754a15ddfefb4679d42ee23bf2d2499120e1154edfdb6952301090d8f3b238c11d3513aa0972e67a9ac14e27baceca01a9e3836ac094bf8af6743ddd9bf06cf39f98a6b822f06c301e09fcdfe58ac76140fe11e99ad88af8b42cacea77fab6ceabb428a24d09011528c0ef6ee1254cddfdc243d998057d156e4c898fd12243f9c4480f03784d521e1aa9d9275091d09b53975448bf84c0d9f6e03e9e9a240de006d5b9713ada7d438c8342a5c208bacc56cab887311959536f0761bd64ea179378ccd4f90fed2ad1e2e8ccffaae19ac402a986dd5964de0b9829977fe5fd25430db57a8f10e37c34df2bb7cea4b0400a7ed22c7fe65e3d9f5f97261613f7583332bb5c41075f2051ee2378b6d08bbf8048e016083428183db7ce353b329588809023489a3cc03355bdaf9396811e2242b122b0922b07", "5151ac53", 1, 186872614, 0, "411926509e5aa03bb6eee0825b0f715110639f622dab91090a46e6d4e7e9e810"], + ["5dc5707902035a6c8fcf19f1c7dc51d6a63cdcb0e26b4ba25ec16ecf02da89d6e3a3b3d14c0000000003535353ffffffff6587b722007ec23f615a6d99f157666d4d7adc32738c7aeeeb4dd683aafc829802000000066a0065530063ffffffff03014b460400000000015169eadd030000000002536a1647500100000000035163520000000003000000000000000043d8040200000000ce3c2e0531d85d8688f10c016abdfc4b321b5509817306bab03a6b398bda1e29228fc996516a92d97fb87e2a31def6ab98e041157102f38839a338adf78772faedeffa5233a97a7975cb9478d86751cfe6ec426af52f91bb720e25d17ab8c83500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d22576c94eb47320325c20d23e468a297798ae0b82f68b823cafcc57f4ee52e2d9237deaf01acdc6f8e404afd54be7db2723c408c31f0807139035f7f16d928edd79a61ce0d09a2d191d951c3d13f8d96073cd0168a8ffe9c5e809da5498cd268a2a017d05ac51b543da6a2ad2886ed8fad0643518613bd88a82f0e34bd21c0d0226baf47caa9431f88087d7f36c3af2e11dd3cd16751a532323cf38bf2bd696060222dbd00a2daf6cfbc851484c744f069edc3d661e379703b7743a56e8d9b4eed90a075c60b6f0c167157d4df854d7c30e0346dabf0219027274a2c7beef64098b452fcc4e0001f57c3849600d70eb0ae8e5f7863eb4b238ab84f8c614c58519d276022117f0a1715d0e6aefc481f7732b8bb17cf6b8406dbcce27525b2b0ad905562502163016ea9791e30bfa9984893cb8058553530f40c167c00f3d035b3c8041fbfb030365e014683a1b794669e4036c75aba7339c330bdcbadda95c37ebba2112059c022af3f2a46a13f673baf07f5ccc69acdd1019db63be50dd83f50564669545fbfe021dc4720ab5874241c3820f7b2c4321543a3b710e0087c68e893b18fdf550284fb7bcaa0aea3c30459fe0c68846fbdde9bb9b10f80fc3decac3d5715b60d3f3818d76985f2342b9f1cc3245f55f134e1b9b6ddfee513b975627415be7aa5e777f80b5ab0772e3f613f989bf8446064da2d8d7799315efed0be04a7b75dd9f70bc479c72627fda55b5b9dfc2ee06c78cb41125f63028dbd15a5059053086a1f872bd529c81cd405dffc328ad4a6827a2ddbea66cd597fdf17a3fc717b69e8b63eb5a5ef4cd914c0e66bfc5558bf3d8aac170d4faebb03d98329fe276349b0c08b154d663f348b30dd2cd804813419885406c27de3fc0a7937d412e7e81d76b1068542f5eba0df010be13d21e7618e60c813890317e8331bc6460c44d3bbecc81194fe3a199c40749f0f091eec3486619d816cd92583a68427a4ee22aafe7cf8f442a43f813c5cf04e0746eb14416ec46b52423b85912fff38e2a9dc03ceeca5b315c33ed19a11ac2062316c9f702042fe1e72e25180d4c7d17f57d65dc885032a4ebe2dde633998a4596157144f1acb0c3d46e7f3e353847d310fd1a430c30fae90d0a93534582a2bd2e4887cd7e8cafba2edcdf08e3ece6633fd2787968437821c9ba79ba970778def13cb9426762249a3c87a2aa35a11d87074125a8528788fe3ff557ef0fad57009cd374b8ce03a96d88fe39fbf8f72815b4d6afd6080fab61b54fcaa78302e2de11311e49db6f461b063a1823867f486104dbdba128affa3b669f1d2cd8eccfb2f40bcfd2b671bcbabb113112e017aa321d8161e233f4371e1e99fe7f326959c2a2afea34b548ba3f9b6bedc4ccb1416b0e7075b738b6432aa7a634e335e3b5aef06b974c716f9230a89a3b91418a91f883bd79207633211a0d3334cabcb6e83e61713faf4b288019bf03de0d39c9ed7f0000e968a8c079c8c85f3c2854ca12eb1dd47d384057e1d83aecbec42ee928f39369effffc7e218173d2f72455edd27888b30ef033574f98259e91d725592b5634ab507c98f8e2ea11e356c03f3a3eff992231d4da232192a7184f8ca9ac577132da6c5633fae6d167a4d858dfeec22dc18512d47f921e8e5ebd6cfc8d022a4756f25cfd4b2dbe51ae238f9fcbf9dffb9546baacdd64ee3b0f744fcd0dbd9f9c8d3e3d692004cb579a904193e442359db9091f20698d5397eb19768b1a7e1a322dad740248b27c1def045ec2eb0a89accd68ccb93e97bf7e6122fcaf468c834f5882cda3cab526c0267fa85610d30596a754fa82267ccd6c1e858a7eb6149f39e6952f885bd252d85941ab96a6a37e475652f14d03f1637be54cab2e3ee3a915adc7537e0707af5307c7ee8867a813adc1558b4624e7bd549f326680ad112216077036ad6df6a05271d73cef8c728b8b528331fa223fbc9ef2dcaec9f483c390bf8c86995d6bb031b35f46807c1b38c5094306810c3cc408033652a705b586a0f469273cfc856dc774656fe6d7e0dc635c59b5010ebbeec27f4daa4f2079d99327124160624d8dec808d0f209dbece713f37abdba3d7ec7f77b15e5d377a3dc58035826e5c46473fe402904fd80dc8f58b0f9fa3f8b2f7d0ff46d581c422e3492c3f0620288d1162c9b26aaab9f6582ddcb87be6313ff95c4258e45e211d7dbc2bca952a096a0790307d85bce7b9c44892414f5844a2889919c57455f29118c49ad794720a1efacd21b6f39ea448d9980cc043063bbdb65358310000000000000000c28d2d0400000000f88c60b43bfeee81a702d551b9ba461ab7230aad2ff1371218373f404a4cd526350720af298fc09c6bc80dc64956b35b7510d323de1e86512afe0b1540b30d98fdb0540ea37ad68a4be200774c7ff1ffd074101b8f267ddb941cd19d1d4fe4ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002ba03c7739d50b33dc62f33566d7ec7913c633e33fa10121f8e6ff6645c0fb942617ce77d68cbc0cfe5ec95cfc60d2b54a686007109dd012348d62b592c70190e3a1013e8179e88e04e0f70007727dfdc89fba6a795d99fa239fac0991210a041193d2bd3efea74d8ecf459d45d1f7284c0f85855d57fb85f6613b3b5e187383020289ddc7be1ae6686666008dc45a4f1ecc9a7f64e3eae3d7d254057b67fd0e090318a5264c8b9dbe72625cd889e54b283ed167091d0eb0737c731863f9b6838da50b070f38462adf0ee50a9cc54cf242dfdbc62a14043e8f72b3ebbc461c63e62608a093ff9e95c2539077702528335d6cd9b17079f8b6f599d396720a353dbb6721021f8512e836b63427367721e28c1f9a1941c19a8d84a7bf46cb50f518f942d599020a0eed20ddd4ee767df97fb1d4006283ef6304d2a2b8258e21a3649c2c1535110222ed19ebcd97b858cd2b2b1cab53c25bb9e0df480878d705a65f50497f14c11603029e776bd237f0dcbe495fdb41df7b797fe0760320249a394bf0731662660f03021a53c51c76c4430db551ea84901bf79ee7e5df37474884e4e3bfd1df23b403d5de507317f28d50df8bb950a88343991ccac619d4b8ddc3e64f2e1339405c87c46b2633dc9eed665bf6a45494f8edb8e157ad5cfdc63ca80b58fa4306a50ed3032e3dd7a15b3e0db9da13eb9695ee0819cd3230cee3381df804c9d1884b3eb2d647dfee98de661fad2a74654b176055cce074b00c956063bf600fe4d4ac696f577c6d581fe0ce7d3e83c836d848b38fcde771754ee897e206c8c8360ffe35c7da695330653b419fa28b4bb6de4282ef8ff70a7a2d4968a0c66ca4cc2eb5473686a7992c52123bf9911bfeed366128e7974295aba8d8b4759a8c771715f07a178951dd5f5038f5c6954b7bbb7d4cafafe36ad2c16b3aae15b7557630fe64ee7399dbf62fac8ea38d711fbf6b0760e358f1fcc9a7db66fd85cabd1adc771172ab179d89f0c6a71ae5f66c79d165dd355ef1e981c39c9d77f073dc2691f9efc4e0e0160022a3804aa44af9f9f4d0dc37338c824b8ea6334abb72d9e8a74c4d544c90edd1f537e1e7cf554f30d856f81e9dfe75776624827dbc8dc101791748fbb86b422ae92f9966c532853726eb717101dcd53c4de3daaf7f01f8a9182de6ca7253ddb8edb522e0f7601e6532e1684ea21659541f6c15d1f62083c3e1c38a27b73d8bdc43fae2105d2e75cb9e5b3340de59cf4abbe74774b35425897a30d0d1b35e514b834d887d83c27c6bd35c97fc2d05ab4e512dc8cb0416d18db5277a713628d40810d83678ca16ddddc6d7ede01afbccef7d85d1de934eb6d076406e65bfb7ace6ba214485a9156b24c2efb09a014be9b06990614b8868f8ac7aaddf0b71515b03f3307df5359a3d59a31c4504a69b898fbe8c352ab913e7ae468f27088e95adb526170bf9ae86781cd7829f7e7cc33f10daf64866a852fa7cbf941b7ca8bb6f11ee30a7b888661912bc445b2d86e37ea16ec2b4489c670948b42ff824d88513b34858de22396a14d7101e0e90be2e691bdfa5481331a0520ed346ad9188e02ef6e3857e60fffe297946bf4c1bad93dc08f63c80857e557b37bf9b0cc5c9b8a43265f5188d1a8063c0ec970963eb70ddaa02e1166ff6cd2ceba5567c2043ad87f3df84ef9d50a52cb5d8f254a7a18963ab3f50e23d4b0f63228f78ff8aa9112cb2435e316f1761cfea49794240569e08b07e242cbc8dbee4ba047076776395c1cead74aef9970ac1432042349af13b5d3fddb5a58c3d7d6fd63120c334d37b33c2c9e7efac352f80a0e67199692ed3a7661d5ec1667a75b1761dcde8791f04de2fc5459e158065a5342e1e9b4db1f4594abc7e2cc895fd3674dc6f29604a14994aeb4e8bb81f6a7d5b50702682061f27ae94ac2d3ce204f589fdc1f45105b300095c62dc85ffcc7c9107f1f198d57207f9b13dc1ee2bbfc416013576054cf7537a6c219791e420ebc1c0e8d6626ce40b7285bfbb3a13f47e3ba92947971047572c70e727cac2da96566a5b216f51531757e5f8a9c7ca1f9cd959222eda8a46509db0543fe357bd4f1e9568b709d2a37a8500bf5d7d4df5b4f782b85edd276211f8155560dc329ead6123c08ece261988781815f482d0e226752ace3576ac51af5cc247624dcc952dc4268a334c4fbf1b9de3c61be0ad6ee03b9e958534741be07504fa7d229e1479fa35b86c87966fbc643904f546d9011227176479e67225ffda53be8e06a645bdba5ea6eab8c385c34cd583300400000000000000000000000089e48529dbabc0822a7c42d138814a6caf0e9f9cd1ffca437fb87208d8cd69587500b38bb5721fe1b0ac197c35c0ad469f337ad3757e28e6d32f7fc167507115ba1fd40be536b77f8908130ec04450808f08b93cc065f3ce67eac61c043d4b1e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2421979e61a8e0c9880486cbbeecf4642390632e5ef0f6c65e2e54b93301eb54932d4306dd52fa767d7ffa48cf70672709355a162c542b7efd48a5defe4ede1eed3feded9fe56b5feb6b043079e4eaa69f95b40348f3c59529fedeb3b8515087de0d21184d798707ecc06cb2e509c2f1eb924b6607750745f8b2d14cf5636ee0317c0568e32f3813c4f04662781eba62fbe5868a2db8f83b22174ffc2cbc41da9022312f3910979623696787551b4ac5a21d9022abe79114ced2bf8095266a6e9ee0b02b7dc8d9b3f75a4438e8c9a454e87b2bc4979900b0fda512040fd6ee8132a06d4c6629e47e11bd7763b8d06125d741527975d94de2e8540a44016f0e6e11e47031769f6deffbde0cfada04c7032578a239d719a0d67b5c49d1a37fa6fc340d5d5030415115e0280bb76ca14b65bb05eccedfccf65d1b5e52a9fc742b0171895534902085a11bb2b58726f3e397a73bc12300c560c1fdafea1ca22ccb4a5a9f425e9d10317a8494ecd608dbb447a195ab34bff8471a4c5aa9e52867047fc1311643dd529032b9e67ff576206e5aa0967ed53d284f889c6997e84857218d42e2f392ba6c9dd997efb437375e2a05a4b929de14c1ee416ee9c13a11717d28b838bcf794f0b71ec135cecd5bd45019b563847f143e6b1bfb83c7b1640dad1692354769493e32b67794de13564d69b5f6cab0070fbd5977e979320d9a9a5923abf5d3b16df3ad1e1e88bc6d989a407309203f6b369f9a392bfe976ad72f9a2f7bf77202781ae8049ea06aa593e7ba65008bbf0e9262229c7b012c0404e27f0318fbf85b112b9ceb8c0c73a4ca01ecd1a855cc2cc70e936c1666fd0390e8116638f347d85d49275c4d93a43f4b634355cd4b11b5d4253e2c9105dbf08b1e2805c7a0b21265420718798004e0fbdd85926da409ba9f1edb4b4b3811190dfa09ace97a9aa9b400a26eacf643f780ef50ba8cbe2eaca3ab5c7cebb50eb5d9c2eb7e37250ead87a4fc9a272b4661d3989ee69ec7a5d24eedfc30b87bd971a75c7a354a346ceb206af5d85fd93ca5813d579bd12f6c55a6380b5ae89e65953c9713557ff304b38650b3c7a6b98e61424a565f428a3806092887a388cb1b3dc2f5cc8fd481f7cf17f55615f6c22bcbaa20bb06150de44ebfeb06408ec8eccfbb4a289ab4ec2bab10bda5cb0db8ce868134030c730553f044716fc3e80658670057633b9ab0320928a0c52ed98b01caf6a26ba308da19f594f7da635546947489a059cac589407d01077e8b32372072897680c15c1f13250329307d52748c3bae5671e1a0aee8583311b79f46c4d944e708e686b82cc14c1c138851592154597fee59fa2726c9dd0162eec190242529d615dc6460e562eb5219dd173fde15b394ea537e4dcece9f916bea1fd30da9c616ffa1806b6a1429fcff4fc49abfdf844f90708636ba4159ffccb920aa59343f2af93bba70361682ffd5e2ab2ee0bc49be977323d3b8a2f05ad097cfac9a6b87d5e4ba6cb8df281d1362518a2215535f05785fe379b604d2c2a2d89ff9d8b9654a130c85002a3b85907f20dd09288a31ab10af8eff5e4e6e2d7cbc2637e6dc9259adebb1773dd26e92b691eb13b465cf503f9286ce2e34d8fe3b3c0b61c5bd71766396c7cc6f1e6d4ffcf92664bfce6bdfc25c9d6190865355e51deb658bbe97e2c8c16763ea3ac72f48104d1f2bd5bafcae36de4e8238428c4e01b70f55cd9919541691ff35283d0ecc925fc11d22eacc3c8673fe0f4add398af6180a58747e10ae8fe8b05178d81a3c1f3167cd851a6384c476652423812c63646b180f8f6969e8d6965b59ae023b277f8f7376ce41d43f7afb022697488c85c97a0f640a1878acafe8eeca95963ba6d0a244da12b7773e7f6c766686075d9542b0dce72c4378015e081f4afa0dcc776622195e82bb98587a1d97e43d16307f15d552bdf01749e90e282f6fd1313e58f32429e9e6ce9848efefa95da422c6930f02933a1ec326da8671d266eb4dbb5b1df7d73379228f6767cafbae13ca2ea97885e3f635dbde942e67d1321fe51e646003b5ceb6b53086cc377109a30dafa452fa0197875ab5c607d85bc77f15fd45defb0b4048b8a125888d4b2d38fefce21204f50f710d0789a95a519b46d96bbdc79af4c986d4b531660196627a53178d7742b35581f1e4438b37bb6dc882278b5d79ce6fe017df34fc18465409b8bbf4ef2fcc3486f0fd41f1e7a75d8c6479745470f42c225fd2e16ac352381e4dd3f1e14933e5137f1a0963fe148f0bcac0b0cc43fa6460c3ccfe0b1ccdbc69bb97aecf5990d25224257fb8a530da9d50db876a6ff9ae1a5bc0556861571df29ec81bcdcc855362051713ad6665388d43c8df48a344c317e5a6f2caa81b6b2df41012906021f67282538ee0b65e9219fc7317595ce05", "65526a00ac63535300", 0, 72056376, 0, "1d5f13a8e6350a15d092d3b42e021c1f18a0f03db9125519be09526091aba51d"], + ["030000807082c40301aaf15af86fa90a77b7a11b94187aaf655b8624abaa94b7379bb212ddef5804c3020000000252633327017701da45a400000000000751006a63656a53f909e02fe1088e0003812fc904000000000000000000000000ce6f71322d6dd7660e2916940b1cb8bc9850da322c4ebf99028a6ea40493af9ae172e19abef1df94198ffc8291baf11c9778e5d3a4f7b031edbc8c306bb72f3da753c93a9bb3cac5251b25b117ffc7f52d2a572541a0094b2d7cad6a7f321af800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cfb47a639cffab16e6b723a6b2532a4125354d3da48dae62341a76adf5fed96aa6d7a3e5cb37b146340e2ec53c4bafd2aca7de26238da30f1302ea6d2065bcdc70cef7a9f82cd48e4db02a4898f6dacfbb7a6d2e8885f051aff0b36bfc2d52ec73e44f4cf7f70708563d33ad827ea2e71ac174bcfa5ecfa15a36d20810af56ca022170158981074666f34fca2a57f496998d7262d5f92bffb54d850ccf415d0be4032e4ee582b21338bef6fb8ea859de3cd8c2448cf6369271d3b2012cbaade787300a078e659b57b367eec229d1eaf2fb4de8f3dad3ff4232fd7db1614f9ca04282340c3a056573d3fcc914f32ac19169ff24f21dfe508c2063b9268ee697bc169e6b03174f1c2357907dbc989575e1fe38b535ca05dad915b35cc952512787a40ddf71022c359e742a6f108955693d35113f10917e153d1d2130479cd4de272e91487c9c021001f392fdd78c01e39eceaedb1784913a718d2dbf9480977b30a1b7201a8bc50216002039e67deb171843f9181bb99697481693a40d7416e905ec4be50f0960f203281ba2218deaa2d6cc3482c406fe525657f8cb388961c9cff2ffb740db4f2a6f3bbbdc8822078ac69520af0719ccdd97166f217cbca93aa3ec0d302db591ed9edcfb28d3c42092ec3d18919228c785e2b132501bbe3472fb6a7ebbf4cc2033573b1dae2295cb7a175a51958826199c67ff8e88909ed28f554dad8744c57be8b9ffc8878774e250488bd2d0d5d393622ff8f397d605649ae42e111f88cf1efadd1b8367e3361bb80bc9ddb0885ddba4696162a860bbb5e892795562e3ebd29de82eef24fd7e9377dd6c2b4221583fbd62e6a128db081438dd066f896ab0eb5dc99d953411b94230e3a14ec55ef78a5903b2f5d31b0efac097403ead2bba31cc6c7073597f46d253ec38b98eec584915862c1920fd825b825f36ae90dea8cf1550c83d821e08b22f65433c217f35723766acaa05cda381c9b3ce15773f4842dd61a9c55ce1d737c59075b39e39e59c55a56ab56cd9f7790836e667af7b4b129bb408fb5eb4a139cc4e88c46907f3351e12e313259e7ea9c6dd8ba8364c304b3d888925be51e6886e4e3f207dd8685e6ceee09fe252ae0afb3c5de82ca331e0ee2f50d85fd232b7089818ffc8355bc216dd7dae8095c2276d4e87ab73cfb54f2ca1915faaa7dba98fd7515fd8ad5e63fe233d5836af840d17fc896d87ecfa5ac4969c7885b75dbbc1c739579b6e8328924e1d4bb557cbddc9951ac2945e5676afb79ac42fbd256944b32292aeef9d544809b93f15b038774e19c34d09369b5d95be7fc7e5b0ccabb0ae6b3c5ae4974fc4325918abace24887f732beae8a9b9871e33ffd977770cafe465003eced6d8bd74b48c905447f082d38b6241973d0f3582548142e6d1677defe342467f4fd5e2ca147bd281af1bfb4dadf8ff19386c99b26a7585d981fa05089aaca006d64ea75c27d1b45c4833a623739c4e98003d63e7eb23eae4d7c424e1cafe87dcb2ea521027c84d4705d65ab5db47ccf8b85d505d0c479d9b068366ad0f6bde069a51b817d1ddf17d02f12144e73329aa2ef910e171b1111c42fa68ee00c028261194e2dc15ce0cac113daec609e20ca32cc79c8e7d7e6e5d9abb4fa6abc45b34c40e4433d7394eb7dce0e2eefeda2cbe8cfa430331418429fffd7079481ece0386ff863ca5dbe321323b4aa545433d1ee8d02a7b4c3dc65ed0915910f66e5eaa9e650fc7063d269ac0491d40e4d47213a157a1acd27d3aef586205332e2e4c8ce4840372bee1338487dfb87e7e0562e0d80911d91b37a5041999fad2cf21d2eeebbd4341be33b9994482b4c6217016f4fe65e4318c2af07c22beb7d075455a90346d0dafc2d12ea09725f137ff80a4bab61846d25250616aaef1f5dedaa9cc46f48cacfe990c14a82d552a40a2534cdd92f4594985b26d5adb78a6a7e7ece736a5fc32e24adcde638b60fedd2c9d702e7041da86e747b5edb08cb5192858b4613dbb283a4a610a3971ca45aa0583c99090a282910c37a554f875129982c5e14b6789c7f28993ecfd387cce1442c97d2d521f653c885ab76ce439241de6f7ff091a2473e2d04e6266122d778719272238f86504a5db13c1e58668d9a8b6eaf30135a5eb335e5d536239068bf17d663de930ca116adfea6ebcab23933bdb6a3a11d0a97122b463ac3b4da96b221429a4cadd924ff9f1e355df10c9e374374d2521fdd3970898a69b9c55790b91b2afa32b5e269e69dee22a65523ee4649e104974e5217afcd875d0000000000000000e669810100000000f6df55ee77501983611708d5fb106ee18e2f59d2fae0fb89da4dbc9009c5b641b642522aecf8d6d4d51f90734c06ebe20f7202fb2136438dab2e204ec30b57cbdaa639369de600b4e9a5ef37f74c1f57fd42fe76bff5112737748737d3824cd20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000091f9a159ccadc63661dc1d0727acd952db562749f5ba8c13d270a2be489c99cf0906edfb5eb6bb476b459579b6ebbd6d641318c31b180beaf9cde2fd9136a6b1a1490bbaa14abd899a63510089c1ebdc251339fd3bf0374022b6768d53f79ca084aa423442381c9d19fc8a4634d46d733d60f4fa693a69f78bd0aebdce4cd903020771348232220c6769347542eafd5604f732aed1681100c91053380f44208227022471c35f828be3296de3360dcaed72eb2e448218eaab1a92d778397c4b292d590b07e80eebf24cf0fce2512ed171921a873554e78025909b51145572fcb44b79c1904a3cb27cf323cccd5987f4d2b8acef0903e447392b5248273af62d6bb445f60204686f18e4e4e543ecf2d2ab45073327a9c853988c96853bddbd8d0da9a1f1e603097e99671ed3251d86e08ee20b9f0340f4f3924cc36dd3ac08dcf24abeffcfec0206a47e178f035d0eb72163731c2954223e17967915a21385f80a3db7e56fcc4f020bb67aca78fdccaeac84902b3a3a9f00ec4465148488ecf8da0b1fadba9d7cc603072a5c31826e6531e005056e4f9db3f3388f75278d7743376a316dd0d80e3691ef98349deac8d48cf89af55628f2232626443e8ad4d74c4e7d2cd18d045376c1d0a06e15f8226ae9504a73feb6ea6112e3dad0b3d781cdb0b47a2b10565313f29be6df7e4820bb207476e814f903e4e854fcf3edc2bbfffee88a274deab345e0970666cc8077e7bb7a1c655881103ff6ee9e40316f43bbe40868d6f1bce71f3fa702b580d22820d9c170ed8c764aeb34e99627f676238e9ffc8148f10b3b0b43a756f2d18ad13ca9d3544ab622b9e94cdbe2597b3f61c3db56c244dc9b78483e02159c317c3dcd47b1651f99d6a287db51583995be592613ae8f07cd5ba4e193246fa2609d09c18a541ef589010e78315c1e0881475c017c8d54a934c7293886e4d95b8f4b5c89bc7f1e4b9941919e6cc4e4091dd78d26465b551c06fe9b7921cf0beabd7d67373089cfebf4db7a2887bed2df275c5c332b5e0904463909fe12e5ccc990979a13bacac82980bd6ad7ac5c64e71dc8cb840f5d3b5849ff09d3eda87407baad487bbc1f6a5b6bf75822e9d7736b75e61b7fee6db836ec4a648babfbb7e1c990891b6722fde24e073862306cf5cc71d5503f71e9732bef51687c66fdb0a96ab4726ac6e327c2f7f60abd03005534b3932160cdbe058d76dd069ba25dcfb8e890154967d78c48a4bdde641926125ef61c4db296807123578361e9d3ab30e985c71811fdfdb42652e49caad62a007c983e8fcb2895edde1fa9034c9ace21e9106caf386ae7d20275dc20f2a30f435bec666af2f9ae38cacc453c2a89a80f1bc47a057bc7c7a0692eb41f0530f5bda5b799933aff291a999affc743d365a03a9bdb2b5897a071cc8573a9089a25827284af6b8dc65e41813c3008e4778f7fab7f64b41ed1fe1453a54ef3843aa34fb52fd1babefd1712ae0f8d740b95e9efc3e55ce96630ea22a4b89d635e7bacf966ab30d8cee80254e9186c47a7d96b23f050a75b928ad45bdbf27ccc4183632894c464f44bc749737b3d081a33595894a0f3e5631b2465ac64e5b930cfcece4bb796d33e7cd0886189f69634a40d2a4562749cc9c3364a1a6a330c60bd617079c92d7d69b7ca4d409d624367eec05cb55470eb26b49250e1f549f0332a9a93d7bd10223a97dd2a06f6cf890f8dd4f405eb6f10d827c1b3d347948320ad153d53dc8ce422c0ba1bfad10a896f930e90622af24f3ec1c2e2f9e6294585f0034e1101e74800fe1315fcdde817cd744264e5ddc00be98100ea07901c162217d66f30f446c580415feb3ff9bfdbad4798f61546a50d27fc3135c5469d6a1a24bf85f3cff723a6b2ff80d63310416ffe4d58a9edb34bd254831f6f5d9e5a282e8e4bd9a9953bf0ed01078ee65ffc12b603dd25b0680946c871d8f2a3e3089dccc516a977b5df47b87f02e7014b0222a02afdd9e6323431c68cbb4c7dcdf9a6cce1ff94bb4d902a2d1780b5a4f3c04302492c74334fe2adb9800186edc061a5b14c381e6f96fce87721a0ce8369882186c81db5e7272184727bf463a82720490d0e252856dd647a30ff2bc14ca62f65752821d4349c68d1a0154752f01938714bbda99ceffb47fbf91ecf1f485d80c5f850fe7986157bd6e8a29cc1103efdd4d96f3e8ae7331aa1a8f232d0c22e9ec7883fd9cf591d4aab81e88cf31f1eba35e1dba4db444702343fcf13795bf8aacfd1cf30846d3df421371c125f1beb9fb570a8424a000000000000000058b3990000000000a8c26daced23b27565587d0e028dc23c9f838c79d62ca3e5f1ac971236a39be08dc2f07e304af45b81804cd3b2dc2e3fb721c3341e612c58141a836410f9b9229df036689518d27c6f1a4d0af2fb88fd7ee4c4e9ffe0710e9cfc99529542bf5800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4757f52bdd94315b0d2806e314f1ca013231fdfc55a3d509d8f8dddc1b96c30dfe65f6e82d34acb21f1b74080cd952ab459f87ad8b9595b80d7e19d242145c2a7cf350b71029ab05df548addcf4c384922b34685ce4920a6e6953ad162408af83af976dd41d7678fd31a617df91869f374598ec948313d3cffe9fd50b056232030d3c9100c3e27a19a90cdd2002b96ef53777628e854991d117c49a791d656170021a47d786651d0c4e508659d02ad1890116c0c88965d79a9cd51069b0cc93a5340b08c3e0b4e7f6b8d2669f69b1fdbbd16394794ea4ae4965cd31b94b65b5f0056b8f5acfff447be52390b86f55f3ce2587bef5333927a0a9d9bcd4a4b769c42c070214bc87aa61c7af4e5c36c2536deef702382ae7b059c578ea9c5293e9108315ea0316a0b130017b0268eabc2ebfb70e791d8b45f4bc24a557500ea09784152e37d2030895f614b94f500ae4e1fe9bae1df1b1b500b4a742f620b3f53e6bf402e99a450208fb2a9a7171f0eeb1bfb957eb89b800ab1becfc516b579d0a51a884ddfa28a4031a7ff488f970ab8bffbedc0debfe88e8529753e67aee80d016acbf19d334f337bc5a6ff212ad77651756aab52c083c88438f37a84baf85ecc964a6e49991f3a0a4013ec7b284be5f6a13863bf4ffaff4172ccf2b68f9d5e090db4013deee235c3457b619aec28105f941f3692b1eb86c103828f981c72165ec831edf08f18e25fa0a9e866e719c717a731e7f353691bdf9b96e6bb4f8b8805b5872d6475251a434021d77736e16b3bc100bac90f79ba702ceef93a3247b0a015fe00e65ebb5b54a0ede654233694612141e37d80bb7766e3cabfe310842e84d2da43d9cac776b151265d51a8f48888f91448f0f24e1068df9c6463d4329c1bf31a8dc791c74edfc9b68d1895b6568a6836a0ebdc775630e7e87d1d804adc60da897401f053050e01b827e39b388711297c28efc8b4ed99869dc86187414ad88e1e770633e4cc256852b58cc43c210d7c7eba8167d3658741e4073d98f89ea38534f66202c05387551923d00a2b864e4d15ee4aa3ef6a5a9e1e759d87c2128b1b8bbb7c5497050f9b2914b1b8d1c72c051bf3f07a174e71e4cabb64a8b324d60dfe2aa9ae20a8e216087c784a509dd09be4cbb8d33b8d37d66dd9c178c45de598712104c9a382900e37a2fc287968329707b54acdb7b80e2e344eb6962bba50c3bbdbc8026821b4539e9ecf169cd799a3992f6651ee37c539973578d62a57b67bbf21d8d3d05661b239cfa15443ede3346e92b6098fc047ebac280fe731598aa2bed0a0ace54c0c7fd542d093b258703a11b54823b47a2dc16e44e181b9f8651d6e46612d4faa3d64eff92d43a538bc8df36e4d6f120e88ca7f947c7db68b7a59f4f3eceea8c97d8301d8458584434f09af0be322df3def2b94b36ecd8ec617f6798b07cd00c58ee757c409aaa8576241270ad1114762e2fad8b0b5e19e1d9d25f5320bafce894c6cda0d8852a93bb2962a48f0e5072a96ceec8ce0ba5c1f68c82e38278dfe4b6aa32379b606b1075a51d7421a2dc07e3c02f3db0fb260c8f5a04359ef7d4f6ede4b759124dc6ac8b3bd9ca58fb950dc8ed9e5b560d3d0f35c6f7cbd1d6068d067faccc52385541c716ed4de7028b86b05ba090c5ba17c8a801f388295b2893db3e93704ff79af3a048a739ae15cc4bf24f7649cc6bf44115ad9625c9705f7a08bb98f50c54dcdb3b3df8cc55f7e6cf0b83923c0cde1c2d7a718bc081a169a0bc0cd652956b354d02b01a256cffbb8bf637bd65b5e61e87219c8d58d97d76a63c4a707b63c2ec07fdf79e94046eef5d0119786c93b72d72f7fcce0ef2a77a633d903fe138c9eb036e2b8fbbac9c611beb235169505fd12b3e48dc41a0a2a2fe77dfc284be0317830c5f20ae5ddbad73371424dcff0e28e31c75772aa6ae99a2c2a152dfdaaec4e9c8569e8eade9708c3acaab3e7d48ce8a77f6177b011cdd9196b3c2d036ca890b3b6d3d5d3ddccd3445f9e4a83fe192e2fb859ff52937e8258f19e0e46ebcf168ca5405ff18499009d1da15e32721b715529b669451ad3d1dee0b895657f2501b0396a0f87c003045ccecb54062ad20e79fd5ca64f7b33927f1ef366c477c0918d6bf935a468817a00ad28f88330e33a3609a1c451958f3e06a0814af9f6c328a2e736e8435b7234d46af34415fdfabae79b2557402de4db9765d48d891af3a6805c9b40588e3e3cd751b2f5fc6df0e25b9064e48cf77055be33b7ea304e3edf2d4cb0f223713d3157b7d8338190fb548de1f4fe5688a1963916b8d2de2b3b7fa355cc23873251cd0bb3c1bb85e0bd42495a00bcb3361ecacb951e41ae7cf26386be055638e238b572c049ad030e8c47e3ff5fcee4cfa213efde71b6b64290dbc4f2af4e3519a7b5cb7a503", "635265ac51ac", 0, -1858386960, 1537743641, "02dea419f79fc0f2c3e470ba2b916872f0dc410bb74732e16613cfbfe5f6be99"], + ["030000807082c403023c1ce03cc6ba8d12ec2005756b2b330569380ece25074956d8a7bc66473dc47a0000000003510063b053d830ff00fbbc80fc69390342d6041abf60ac350bba4001731b1983251ee5f8738e130100000008ac53655263005151ffffffff033028530500000000045300526364662d0500000000066aac51006552dfb7510400000000015200000000000000000100000000000000003117680100000000d5060720815ffaa3adbb9e6fcf48242d81d7a0a9c99936fb03cf7123ef772ed4257cb297e809307bb62d526d9b05b1fb871a415dba0ed92d2e6b7376207ee03a09f09fdb096f36539f19b4d5d64eca7db016a8796b48a737085c3a73c25d4b8600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e449ebce63eb9e32bb497d905b2e01d9f0f9ba7a5ee81270ef24e3a79859232f3c4541469032a3e3cf7578caf14e3221018e29ec18473be93e7d71fc13c90c58c3e582620fa1e091357330ec74e8c73f390626a8ac2173083beb706d2ec35e18ad2127791a4cae610f849ff06ea765a2e9ea01b18c44300cf8809a10855ee98a0329d1be4d788b7ab41369c43519431f88b0b3042d1f709fa865f3fbeb5bffd25b0300358bbcdf357fb0e39f21ced26dd2181b4a01778106eb2fd1318cef173996cf0a0568fc8932b5f8903a274b0c4c1e2136b1ea57df0f671066c14093a93d60486ee05482fb6086bfb9e570f5985117c9877f455541345081be37ce0ebeb8037f270328f525177aa5ccab38a31741ffca771cb12e5cb3a6ab321e25f7885a0256f71f032bb6ed1ff749a11a467844e15d163f73087a015157ceb7df6c3fc2aafad65045031f83c0b042286682dd9aec504af585639965460721c9a021cdbfdf73c7d47af2032072171ae1e67e99b5fa11efedd0c8774c1d42837e089003cbc25eba4671373a030f4557ac5143fb318a2b94300dfa05146977be4d6e4efecf95e8568cf6f9a213c6b5c821b35190d08a3500c3447acc85241912bb289a673428582a8e7fe9c797474f9765bc4d686925c5b86d5b5146cfc9ba5fefc871c1a6bf03d5856747a783c17e61c73ca8df8c80550851b5c9f4a87b84dab6aeeaa2f8ddb53bf4982139b172849142031a67022e0332eb84e35ce8fbfa9ffd4ebdcf9660283d8ecd615cc996eefd53ebc297623123213717e29826b2ca753a15a177848e4e3f79747ba2dd124afa6e14fcf28aac9287fc1848212443c69c524a42ed5fa85d6723862dfd7331e43bdc4d9511d27fa2a54e006872ad176c4faefdf36aa06d6ee62201dfcd0d35d47fde5b0659d1002b1383159f44955a936d7f68c1db535159b16e8792cfb3993d5c5de8dc3d55e43420f10b38c65375e9e71d666fec6bb0ee8917de8590f33588ddb2ea2be23f14d015ed7a5dcf4be493bb32c237f89bee643e310d3d34ca6c9fe8cac989c01b9643feea4fe1c19e7775fc5f3e2806ff46a5ea4372ca3487b63bdaf6756929adac19a0887014c5eefc6302adca3ba66e1152731255254339124f319d646e2f622a9a85f5e89a4da26042ffecc00f73f06f2794b451606250f2f3a0701bf8f303be887a01706e98aae19ecf7775266140686ad1f61731d0bb8ee83c6b3faa9d304ffa411a423184ad4115419260cf7658c82f320a9ce448dad9c52da30a8faa7e440976f45a32527d3544aa305c79474a0eaa688d69af45a85f92e21a0a898f9456f4e11eccde77cf56734620b252b9454a278d1ce36baef1519cbbd6665e8c728dd66af61327209f6a2ee780df6f6c57c4bf8d14f4898d407c2a1d709ebcdcf5a9033ba9239e769f4d8d4605f2ea40fdb7d83784b9f5726bb7c7572f79af0dde11bf7f599dae72616e55cd252343a19b053a3ae41091e1418eab8600a27ba9e72de7fecc952524315fb951e87d66a970e76f04ac47788dfb84e6f0aaba5900f979eb94b82aeea9ee449b1f4fa88bc42a38ad76abf566c9ba11ff52a8b93162fefafcec075a4f9b7562b29a09aa071f4b9808e7fac5d5a4079d55f9839d590382f987ec1fee62c34039d4d9299a7159a788390b2881a427517ceabee96be9ddd8426da3dff8293b7c6ca3b6bfc76d275c656c5208a23e7036a8fd0829bf6c0dd14d2f7bb03c30c495d8f5bd71b735703b1f6863a0e3f68f54382df64343d23037fc6314893183686ba6c76325a037ea487a665992f28313d2d85dd27d0a4d749db9f39a9d9f5caeaa054750293093bae1e3d94d3fa5773568ea208cbebdb9eb05c61984a3f49c71e22399ec834ce7fa9b34b05b0062cc77962bf3ac932984f035d14699783c0541877769ed80803bd5d688f49ffe6b1171cc82c8c73245d7a50fd3e1a13d90eef1dcc919d5655d249faf37419f5d6c24cafb98cdb5c3977a192d3e010a9aaca5bae99751bc954927d87f02c31cc245a31c3210928ab18115fb081c727e5ac3d40f2257a59fe00b99d54d01e8ddb2c2a479c42d7728f56a1a433596e496d9655ef10992ed5dc1a9d53fd71e8d904c6b87957bb94c77d6481462f32bf9f8ed4eec71798d718b60eec76e2dd2e07369cf8cf33d77d7d2bf1cbcce0f0a61af9dfd62cf49859594178ea860ee270ae1a610292a54c4f4415f9ac10b4f484e6d6d6ea680e038f33f866d11a592593286444d0e4829aa04977b799495b647934e9d65e4289a0ee854ff34c75e4151e528ec5a9f122d06cb17369d6459a37b3ec1870a34b31c6b4b5d48ebfab9ceee10d973286b1d3533242e170ecd1f3570d060f36cd3a827cdc66a72be015b07146cdfc0fa1f19be794d50959efce4094d185e914df6c27aaf09", "0053ac6a65", 0, -60658009, 1537743641, "dc3a818aa87574a9f83b915deb7bb5e76f18085e32614687a353db27ea19a1c6"], + ["030000807082c40304c11f5edf06a5597e27193beb2daaf78e5ffff720a495e82148c61a915cc1c8b60300000008636a636363ac6500ffffffffa07eba6fac311f147e0afae948efad0340c8f0dba26e0e2684bb3a185e8724250100000008526352526a52ac00fffffffffa32368e64a49a68f501cee43331b7fd618baa790e8fd633cb575cd3c7fd833e000000000100ffffffff034746b006ffaded3de6d410e5ac8ce1f60eaf590b7af594ea1143450b4bbfe10200000001518f8188780110c7a405000000000363006a00000000000000000347ff4501000000000000000000000000ed9ea3bc9c731b9c5773a121bed895883fd6ec375b1813edb37eff8c6dac2beab004a0a5ed13d4478862d7c193e8bc6b105e002315211872feb9a6a3de92140b17ea85599285cd967dc736d1001ccc8c28388090e149408b72e61c3ebfdf8fc500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e610178733e92ec3a2fb05a80de4956099f34cb295f1bb0198be80d1cd2d3c8d2964622dfc363f7272fe3937ddba729f19de6b34df0d85a2347def1f005e005279aa7504290101bdcfbf87f536a76dc94218ba0a51504efd40c1686b5c68d6fc2d26e6d6af11c25f03dbdd769a680aac46d5e72a9249416504fb641fc2dc288203305c6a25092b9d4d90ee4dd57fe01484b16df501043107b7fb367b0d9a5773e0022f07469d51cc93d7f8a97a88c2e33a8811e36e042d175deabe51215fef606df20b0737dafc475538c4fda28afbc6b3cd39f95ff03c9de87ac5128c6ca81fa918445bdeebcbc70e484d55fe6f15a6dbca6921aaf8c9a2907b23c9c09e2504a13bc70211c9b0fddc805e6be1cf36e63a99e280e7b7fa56522f4aadf7abeba31a70bb0d020dddfde3597b1731a9205be34787309328ae9f766c977b321bdb489cc570f3810227fee88b2c8e079425296d271a1cd5c8ef2f262257f17fbcf11d5b3ae3ea8da10209b6cd2011ba07345346bb46e95d5cd6f61b185def7f1534f02ce1c25567b28e020f442d0132f97dbd48653887c4f4b8e0198f87a295d6a24a86cd9efbaf460977c7911bfcdf653519f6c70e1e4165cd8c5ed50e4cd5a7a395e2f4140594760f38f9c9c6cd0c7035e0307b4f0e9fcd0e21091f1dcff24093bb42576f773a27e181fbab93734228469b58261cc0734d50062a8c962fe4d35f0f21fb613596ba51a16e975fdce212a83a424a5541092e79b18ad8e26e327470244bf803c3cc27d42f71da701c3ad769d5d89f52a6cc48184637ef888c5b5af2b161877dbdb693bbc35e9f2cd5c4278e455a53a63a8eaf83c974290ba4eb9b494ccb2778c227fe6cb2c151dfd28da612ac42e2727edc3a85e54de652c3a5aea7ae5de8236604b631845bfc1e3a34f7c03514ff31fd2721c34f574fa17022098bebd569b8d58e16809789a2426076d19b3b2d899f01e4d3e65273fc304d52f7ead1377eade0d2a8bb08e7b9a71d57910fee3e05f66b8165b07787bda4ec0c4a06105d0865798e6d0da3dadd2f2bce37595a3e80e8c7b7aedab86b984ad84a8191fac8c6dac54205963b81b5c7bb4d0acd75d62e22b7f808286a04755c18d40bcffb9393fbdc75a337c6e7c0d09f2bb2b71732e8fac71eef5b88ce0d7dc7c7423985cc20fc13897f34b14be55465c364488d331d9933f937ac058b35bc2ad1eb203d86fce36f6a88f1dc3933135f0517216fa8ba2d611449ee827cfa0a5a857fa1f9233863f628907c250249841880ff1baeb7455bfe49784843f20c929ee3de121af93c341f6b00d9317eb6b02b824fa74faa40d4ec9c83c3ac21a774915b5af38f6dbbb9f07d15557f5d9228cd2915241eb463b764154446fa63c4db48ec25d8a7db9d5337751173912955533db5773078357bba5d4ec714f89bee5a3331485f142cde8cc00b1e3ddab8c9aa1e8bb398718a69497760256f9acd523340f0b0dae913e1585398ff79f72c409de52958a7e70a0d1f13351d7f838e4dc4a09bdb7df22bfadd814fd52d515f7673f3f862c8e43549772b9311b1936707ec253dbc0d5b2aeec59d00eb3bee152ac3c832a477eaeed7ea75510909baa7b84bbc88140db7098197c3b9ad88dc2550346d15ac51ceb370233b9b64dbffe6c1e5472697c48e72c5992c7d97f86ddadc8ba253990b102a03e48217a22cd9a8a6178fad62f7c6cf558f8ce64abfa18596ce3723605fd00e9e6dd59861cc4ba2434be23d6dedacfa5e07f94cbf3ddb6feab9e063791f57137377eff9d33cc5dd303f6ab7739029fdba061f615e8fb6ea0ae7a0d26f534a903d177b43ac8968e5af972f9c490ad6fa77729c778f78fab8a27ee204dea610e45f37068527e6ceceef9fa671fac8fa85b29c3f8386367cc6a1c840d3d2ca8f65183f9e38202cca5881dd269aaf36f73bd08998b01d86ae6fa78f0d5581b0f0627ce53e549c98dc6212ee67ceb148a3037f322d135ca5a7e028e10abadd149c9dfd4d92d5e877ee70321f1801c6d8552ca6cde18a6c5b8d9b17d97b3b9eb2aa79f63fecef9b1048a19c413ac7783a71a2e6dd07ae06faf3ce3295595eb750d0a0f3f6244d076940b07d2201ad2371a8549995f1faeadb4571e54171c980ce303f4468172c4b23ed8e65b2757e615607368d9bc6b1dcc81bd144c3a852616b58a8e0724882c7dbbdf143a3f05e97bf272102293afe84c4f7f28d062dbb72ba1aa00e11f0d8c4250f13b2d16515dbdf74e18c8efd6bfd5c81fc1f8dc2ca725de120b22e048334ededbf720000000000000000157881030000000084ab99587774b792efee10d1238852823b7bab91e8550e7eb2d78ce900245e46dcb44198761157d8e55e85a63daf6844d869ff5a4171d3f0c1c97b748f4ed513f2bb20b77df73fc1910a51ac61aaf3dc760caced23eb575655ecbfec5da2b8b500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a13033f19fc31b8b7b3654c6cd3b5266295e305cbfbfb09e8477c8713c52ba383260b79fcfbda6b7677e7f5bbf19e12f7fd325aba88cc33777a5b9a031d1f4496d5e29781f2b9b946b2439705aa6f24031acec59bc7dc99d34fd0a89f0b6af14b0d61193eb83e8442f14ae84244a1f125a3e745e105d72966b8e0bbc7d6dff34020c6659148a5b98e7dd94d7bfd863f1ac743d0a05190a5889c361910be04bfa45031f98b51d02e68e3a156fea490032407e9939ca6bd6c748d3a54a0bbc842f1c760b00c125c0bcd0ed27a7d1021e382cf51d16cdeff2e61eb2fe968d3acf42c0029adc5a4222b3f6784aa962415d11543ee5619a355ee6cf5efcf832610e1fcc6e200228802e43a641c4353b5a125fb9085ad387b97f9236f1d1a0bdf70c8e364de26f0215c3ef8d78b16613a93c56ce248ded75dbcb8e274df0220cf306a2be48b1ab4b0314120768a34c422907b1b96118a0322c83cfb6e8a1ccbc7328aafd3da38da0b3021cc609e4d42d04732e9efdba2b3f6f8eee441ab324e4505bd7e211abb020a1c002033660916f3800f04dde17fcdf2f927d839bfce3d4746490fdebfe4645ce8dc257202e5788e7da0221b42efccd3b654429945b5c62c7a46ff0ec462a03e034b61ad3d573911282c9add84eacf00e6a8535314d67f578a2f39a840befe60a7a559e1c658089357dde68ee951428004b6231b3d63b8a53968927c0a24d046cb0759633b7a085ae76e8005148f8a6f0f0c5210e27518ec305508f1de25f2ed83f2b22d470af8048a82e15cac11e5b9090f4aaab34ce64724235a253393a23775a8645a247e023cbcf81681f10d30fd38386adc57ada4d3ab99e30a5f7b1e12d6749ef73f2c0ea006d700494a7313a3b647cc5bfa8425c8f66fc038fac73fa3cf730177f9db3a5eb4f149ef61bba6effb52a34f16261e74c92b79406e93be5df4849206dca20e80487e4c1a56e8ee4263efed3b8927598fa771d8d500e2dbf4480b9b78aa5a39b78ca20e7e1448434b06155a257273ced6a3e9747f8e968ab45dc3ea0d5cb68684bcea00cf82c424b609b28df76bae5943e84a85382f83ae45edc6c9d6f902012ada65a5651d02d3cdee42d03fde49ea08eb678bf53c8bdde45762a531cb1212f9de85f10a412a419a0b1b3b82508336881535a69bc48bc549fe3eb161efd04369549e674c375b2316afb716aa3bc44496d77df68a1157916e3252813ad09b68acf532b7eaf55212f22d6981f6a715c768a95aa32c77664f99851b30bb375955bb9054f18877e843dd18354044dc2e774f89371ab6bb6c08fcecca69b1366b90608ec878aa7cad1a1c619cd10666392a7396412d4b541549d302a62dc8c4d42b7b5141d1054ed14db046b9aace826f03af973bf7ed351fb4204b575fec1c06c11baff96e554bb74a84559f9bc2c3f5ea0ecea2c5b42d53824260fc4572c25ea8349b1bf450c5edab56cee9a22279e5c1352474a2fc2e28617573ba2ec8212f453841a485b62e92cc0f33025afb15caee8411f7b275e7ed5b8f268465984bb62b200dccc12a699b273bfac2bc38c889bda44aecd41c70087e1c72308e6f7e5040cb85fb969e59f1ec8626e806ef4abd2a3c18f2bcd8be3db2aba9b41bb0c0e479188ac1680e258d26616dec7f2764cae268196ea0c463e7eb974cc735e1e64e05f03ddb80729096497bdb3d9ecd54e29e599f725dff43daa026380ae83c4020ec4eb8eff462f2070c5209a82a7e4daac358e22cfe64004c362b630025ac9b555838d7b05a279f916c24ecea788a948479975317c462c480f0b1132d0dc560c998b16bde7cfa0e5b1d1f271436ab9419d28b126d5fdbbbf78e934fac19c69f5c15e81af8bc0bb4b0a388bf91bfacf1321c8c130a6dae56d65001fedd83eff0caaf5112ba66e7e02f55cd4156d881b0830573e0ee8a26dd99dcab9b3d91729489a599a5ccd575ce8cb435645b3e787b624c5c1e759a90c1444a956f96c3441cfaf31076e2d1b985171b9821cf5679c41aac8c172b140a3d226df6ac7ff7632f66bc9e63aafa356e96dd690c675b16aea9ca57e3b433e8575e8854afa95a6c725156f68642b86b81e14396d690ae309fc89d78795fa4899accfb3fc37fb427dbcb862d753d42fa27104671a90dfe7383014cdd8a9f13a292aa7738d0c9235dd0981770031ee528aca79d4ea32ec13ea6bfa032ebc4940df2a668a2de2779209d39bbe40cdf36be477799ce4844bc4d9394063a325c1e90c82c336eaec23a4ff807b06b511fa2479f11dbd32f25099625b2e21020000000000000000000000007dea4b9c2bc0e6c7c963a2ddd16de2a192ae28ae6d6982dc23061e5767f70baa91f8ca766f5649dc3718ecf2db8c0a09be589689f8f31f07d24ceb5a0d8399c906210053c0a00d01421b0396742ce54c36e18bbf65452238022723e1f6a8cab7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007237dcff2e99cf3c85889a47b13d3b0cc52efad001feffc3c69547e439acaf56c19de1cc68b29c25a97df2234bf33bed49204e522718cfc09ae77d237928aba8b4eb72c2c2e15c9713547ce481f820d64f463f22eb57e175276a6f632e930f506558ace4c9f4d3d8cb6acb3a44ff0f2d4e0523287fb1a70a53bbd349c7e42f32031c61b75da8959b15915e0a07e072237bfe54f31dac2baa4fe4a6866501fc4afd031936111b03931b5a080551ad1cc912dbfab02d2c48270d87ac923fcad687ba4c0a02a0f62f92a069286633101c298a10a32375b9745e71b57017da8e8b3c9b4c157ecae0626cd75282d118aa92eeb0b736de1c5a69ced10fced21cc8257e6ee786020c61342c00040a5ed244935854556feb4e200e9e01d075ead8c6e6e5ae9183440212ae344cf2c86e25869baa5bb8677d1dfc6b04a09c2bdc7fe5b4abe24941a3a303057c8c1ef356444ddce267876b21d25c6e7855c6c474b11bd14bc647b2c9579e0210ce0c973140d26d1a623663beb469c3a024602735d5eac2e064363f6a2d05980316e577351149e05b9940f5d7f1c22083b53f38c2838b2c91d081d82ad8e9037bc11511671d445909a54a68390ed4ab0aa9ccb80f8f54ef79591ef78853f4bcc15d43badc4f27d05aebd6931d5e0d81012f7997281831bb7575a6c11d956e868e19f601b24b1cf3dba2158bb14bfe7d67c0b289ca3c2d5747948fc43615c67e648553564728234e6fed1fed7cb76645e0b2afda6834692d1e5b5d543a6c28c67ccff3f12fd6131e07845847e895f15a3b6ffaff1a75eae74e54a4912c9e0fae44e75c878da6bb5b3fd6c3dbe4cdb822db9f415683b9dd9fb5c5d6509d728dc7c05972ac047c7ae3be407fd8ce1172d7a4e891c62797905f2af40a74735155808f462d655a11be2797685eb89960398eef6f65a1d21b68e8ff12556159a6686a2296c21dd1caaeaf104beaf924631888b31f62bd1813dcac0dad5c0e8210b2d47a13f4dffd4bffa68ef11f491a5c4aa99cef12301acd989094f4d5e98424621a748fe15f2ab754b1d385a452f42400432db3246481f47bfefccf7ad5921f900b1ad2d0146cca49928ac85db2963aa2ee79f62c46102ccfa763a28ee723cab2c9891fa0420dfebfd2132616a655dcd260605e2df93626ebec2433c6c344c078f52cf122319e355221a31ed8eeee9e4ef29c1f38cfbcbbe0cd3211d6079ed19397da63e32ec5f72dcac21312d6e6ec8c2f0ff72ef68f2679dd5d061f61991c3a8943b67c731538f47d388ad5a396607a661b385a6293ab3637e484be74b6eafabeeeb165563481d8a225ccef00c117a1cd32cac7898b552a66706b9cdce79fcbf15da996651f48cdadeb1b890902eb16c05c5fe15e60472de034260597fa36e3f94490c1d95cd19e20272edb22b957032c2bb8bb52701b0e6eb63ddf1acbd19a77e9073c77528b45642a7c0311d50d2f73a1843abb2741ce831ff9f85c5c01c6c092e3863482d92cc94a6bf0f1fb46c22c2ceca64c6b599324a0407fca56ced131fd5d22ac8af094e85ffab9c6af46094ae5cd3ee0442f0d4b18255f93b3d73e2df459df3aae45c89c83ff5f0f7ac5016c7a53a1a8693da3603af663899b479c72e042e32c710ecf2adc0e2d619216283d769fa7bac300327c5360e01233115c57f48d9bdcc379b728402bfc2d7dc2caf934b95eb5c7f759027425cbbbf2d7c522638cf414cacb07135705f8718978e3fedae5131c8cc248e7d1e0645dc04476f35eff57b8f785ded2519d3181b0ad2547fc0522df7f056340641b8ffc1676707d5233979c6545c66ef52d50823baf314dbb9cadf02d6cf20ff5c62d1d257a78e5a75c613f9c2286c98c0d80ace84db8ebbb12c73416a0a2c6018e92ea57b3ee567e70b5d99d5aba380d37a80a5ff20c773930deac304664bb25070a590b2658e42c38496d9d9726bed734883e23a9f7669c115a07e90173b12015c58ad750d4157724a0f4ecb427c5e8619a216b7211acdb8f5c3b45f9b08b99f2c5258cefb20f439484e48dc20860cb72eae8651df65318074137aa91018251dfbdab14abf0573c5acd26f6d0dcdc6fdcb8512fdda7b046ac403958c5c041e65f9364f110e3020533d883b769868feec689e16ec6b11b3d4d5a977450cf15a1c41c9746d3679266561c1bb21793b52a9239803d3f2705886564fe3b3b10d10764795952b052b7b18fb310ac578cbd7735852e15a001604fdd013188f996f57e767c74ceef6cd2dff8150fcdfc1d6550450ae2cefb28cdb3095d27a256a2ff09d8e491edfbff6931542842333558a3a05ea42399411ddda6d1b326708ff1c01ed0945fb5ee3592a06775f9886a9c5ccc51b3ef2016776625f5e8658ba245958631ace6e735bcae6fce3bd31d28bb6ecb64debf7468b8d5784603", "53", 0, 717545970, 0, "951eb914326d267a06fbe75b5c3bd4ab59439c3387230f653d3b46b9bf2e725d"], + ["030000807082c403016f33acc3aacd19b222c2130f38038cae803e4d56b77c7599b40469c685069ba8010000000753ac6a6a51656affffffff0374b74905000000000163942fa802000000000055ce8d03000000000663acac6563acf0e6ba5216472980020000000000000000b437a20200000000602590661cc1f748a7c230095d80f4a250615e1586ac1004a103df5139e4cebbb15691d668921c93d146c879e2a27025f0268daebf6497c88df421f81aee4aa93948e0adafae6ba87015ef765aa7efb6ee77e5078b5735edac3ffe2ae295b02100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000583f124a75eed9b4354af9590914d34eaac17f4ad5255509870d054cdfc5b26fe0e1740d35b06458d212c45d548c49714b6af92c9149b216e2fe17b7eb2ffa820ea83f0c5cc949036609e423c2684f20c3fa786a24c9885beb5a9101918ca19091e503462ce667105c46a9f6205d43f9114c5dc11aeda0d5c7cd9d2b08e9d7bd03138677138782dcf0da3066cab2def18165633d72df25a351c11e8bd451cc7a070210c0671e6d99b58d2d79e93af843e057832a9f78abfe522e58e01f21c006ccb50a006e303390abc1e4fb40a4a3b5e5147a76d2cda9e952276e011bcd9f625758b31e46a354748e083f6cb8039f17c3f2d0ced6995c50c203b8ad97212958362474030727ab68b65b2db6066f4949d9683b51701ecb2d78060578a1ec8d9d84e099d20201ff1058c2060c631752a8c9ea44b7b64cb73e2dfd93eb1baab631cb358ba81c032b195e55a3553e2f4c7765c3314b335aaafd47983e07c5f49101cdeb79a2814a021bcca8db8c5bd971a0f74bea023f8e0eaf994970042ede2d0adaffeb2ac01ba10300715335f875be96c2b38119bf88e5b4780d0a4efabc8658b69a5d0bf6d2ea808e55f61f3e29eaa384835c5eaa6f9a70b7c9b3539c1beffcd8cc8667b704b2eeb8b8003df3506f7020d881e58d91f214c2ec5b190a279cf133836176b28624541bff1a1e8022fa8d9dacdbae95a376407cc9ba726579350dce2f98f770cf92fbcb71a106aafd9cda7717b685652ee103bc7f150626c8de4b25b17022d68487f431895d1fe869215ecda7e28d8b41407cc00dfae5fc5c16329e2aebf0b5255fba9bde4a1d811095fe2dbb8ec05b9c2080af0fa0740940029f428c7f0b5ab2f3387d4fb9c84ac93976cfb6652bed302be14a0b5b5a84e1b94362c077434ea2442ac5db06c26a19499e51af770301a1aeaae93c71dd0c609ce28d0b5a02e19e9ab952abc9ecd646d7031ce9d8b2fd569587d9e4dd79a01f72725d97f549766a7b3d8fde754da748daa754ed648c28215c1c45a98e2d6551cda211cc5812c58208c97a77ca9967cbcbcc2d9adbec8137498e1f25ff8633d270586a1622ebb81f6556fcface677f2b2068c417c222dfeceddbcf75977d09298b5a3744f3ce0115ad254c513ec93a934c5fce5eaf991f39133671f62d964903656977d6c588e54207d5f73a5861a056267a7dc7aebe4c26594f79af8c81ddab3fa2b7e65cff149ae79d96e0707292c28bd63df9ba796a0fb30f8e84b1a8a3411f817be18c114bcc9af0b22163217141079f2a4789ff65e1edd68cd5556670ff9ce7a33542c7e77f57ed3bd22076b7d75d1c8fc2d5198d5a5b55f1c5ca6497bad6458d8c38831d330717b6bb42b249e5657144c05a84f0da896c78400d3d9763d8c6405e91875978b7aa51f8dc23909c117e4c7b9930521410551e8946b1320beaa9c5a38eff524ba81049a1eeebe66e0800aef8976b66c59389b6eb6087ac835d8e8860d2656be18ecf62011570dbfebfa59602394d0183e12468e4e10baed6fa955417f6902bc5478a533f16c1312d348da7571d77726f5aa45b140b144773ef6e60bee85cec59b242234b4f3217b50ae30a05c3903a2c4df798a1d3480b5953a920c98de626071b2347f2bf0a3172764b66a2848efdad4afd0dbba98860798bf902cfb2ec52747c18bf45e0b03337058f745f4e33dbfb4c3bcda0b9ccdaadca67cc4a34d7c3f6248afd7ef499ceb9b6bff99aab0698ee4d6bfd3ad7f042a7818a758d0138d3ccb37e078830116d6088f659a92c094fcc3b05fccf2ca0d3c7bcd8e0fb9aed3f38662643903856f443bc1d0d89f935670602466ecd380688fa4ad7d7f6bfa7ea87b4fea9519b2ad750178e4edd1bcbc410c010b67443708ca68f676f78a736a9feec4cc2032ce1539e5a86d5e36635e9a462c7b49f32d9abd2b261f73fe4d98cc158c503809dd5316cd7183260db02566176ac7b4408db1b1db7eb2eaf161885677015af0d82111c9bf84bf145f1f0bc2c86c292e0c776a246a81c828dd7e5b37a9d245647f4214a0e3dffdd8630e3935dfe336bafa0ae16eebc6f7b32dd4f7cb71a7bea71a5c550c066ca0257dde1772f4282e55d4a70dab90cd79867c118a0baab588e6b17da6cf9daa6a6cfb5b465cb8693619c156ad7ffd1026203c0171c10c802325bba34a0818f420ee1565bfd58c83b3efab3a2244da1e54114118740dd87666f56e0255e4ebcce22087626e08d42d6f12dc4f06e015089012ca15f45953f8ad980729876780f2531d6b3a7a62645ece50bc655d604000000000000000000000000c87a3fd582c2af54f02ac6b3645b1f2167155860ad7e5d0b2ba14441a8a9c2943929aa6ee463df053cdc205d5581fc1273b89160996684bcb3758f88ddd70b49f60f33541e2c513b15f08f99be44a27137794dac7d0096e12f0568b5a85e292f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d77a85cea045c9e40b47feee8c3aa3fa85a0ac81a8cd050a26c6dd36acddd4223feb48be1c03058f6b451e12ff68c6b465e7005a858b98128709b972534a262b53d30bee3ee6f84677525624a530b891886518a67615509e49b178aaf9309ab25ffec8a63eb85c03ec175a3adb3afcd906cf9a1c344c9390ede62ee90b98e4870325bd94c5667264b9b17062825653e334bd7dbb6f8a894a8b2ef8bfcb9cef4b39030bf625932fd99e1079172a83f672b966d47ba9a4d02c64ecdab803082d45a6b70a08b8a0973cd93e0a4f63cd81bbbeb91173fc2b723d390c137a6138044c601a7d39d554eb247758a95ee0d26d44670451387a71c3c838934b740b811545f3f318020d7f1105b526a5a1986d4d8fd91ae60fc8e6334c274c51a0f16ba052de206e3f0225f7940bf0ac9fe403dc9807271ed122b7de174f22e254f93bee8f42413f51a7020257aaca68f8493aff308e2b0b4671f523bdcc346fff0faa8c31b032aa8c81f9030baba35bcc0e607ce40b0f880fccfd772da605cad937704b96d76bad48ffb4e802294aaea6cc04a487e96eefc0da226655e8a85c5ac3432752fca534ed7ceeab2968749095782acd18970b68c5ef366092b84e4e8550ce9d7be1c41ea355f01f29b7b6d0d54933c614b9eec3a8ea4c919a413d0b0d735e001f2511cbcb2b12974a1e5f5b3004c24931565b87ffe4ff6e0cc2cd414c640ff78e4102ddde1abfea8a6cb37d587941b24d652e3aa0af4ee0e445de4000eddb562d85465b82f526d55f6be09a4e25d1964a472938efd774b78833e4999e710752ddabce7f89d755a70379f7a49261650843c3ee1b1ddc53d0dfe39d61fde2beff1beb1f43396b79dccd0c45b93363e37e565a8e21e7e533ab04073bcfbf4b58c142afbc1e2d0451a7d73e1a50bc5e4804f2792d3cadd9594f3ac036ecbb62650a2cfa74117c1bdc19f8e97f5a5c5695c4768775889999638c5aaded85f6070009e362a9e94679ce6faa042f3219ae84fc76217a32f64686849dc8d139094e422d9f2ec0c36f186ddd6d7a2485e8f37268901f62b2758e2ce7363bda59e6bc10fb4768cd92bf2868b5cc81ad87ab80f5f3ee54ed1caab56f406bd2985ae1ba50357250f256c5079e28562c3908766c08970ebfe1066db1150cfe754265f2650729055d3256872cadd1902a51712385f76a1c6378a0448f82772b3d4c5742fc034a7d6ba58a967a01dad66256761aa80cff1bb4bd3a9f91d7a8d3b076baf769eb4190b23c50dd4126cfea2ae4d6819442b50326aeefd924066106d067fa1e40bb1d58f4b9c1e2ea26de263bde9199322b9c71d6620743b96e26ad996f2d26c21ec137f0b6e9de2a0a81474668e2bda32ba2b75f266349f8e22cadf6ea7fc0acce8b60c4cb75a2e40454ac4890e2abeccfd55205cb1e056e0487ba0e5a5e1a28f54b6b5ea91366e04e73f17924594a6f11a3104227ccb386a2860d0d4cc0d0a37e3704169dd49891e7fc50240f4b947ac37cbfb1f0d576c3ae6481f14478b0b4a90bd61e43131c42f86b7a2ad86e4bd1899dcb87afcbdbf2933a70a9ded8846fb64213aecb3a797069846eba20046c424ed446cbd83ec1d8d7ee7d55c4099424be2a0d81b7b6c448249148f978bccd9826d1eb0c5686dfa00af74b8f55f8954434e4bb7da96c44790aa3647a2d0cf14684730aba70005149816361992ac6b01a8f951f7bd7e20e033cd93b43635956fc955ed2220ea2ed84e64d0dde9eae61bb260de9ed0d6f095f77eec9fd4d846de0998331929092448dabb27eea56bd6f850151bdba0cfdfee33aacce7c2aede5ba4b199f0a5fc5ab58c6ff241195a3f0d1ed198dafc2abfa45ec664758f4b1b940e7b25ba623be443b2abeeac4dd02763b70e601fd7e69695e702d656220ac47927f16cc223e1e198cd990effa53cc6150633c6fe858ff70b3a03d17cb419bfaf5ac9fff0642d247ae1ccce8155bb0318283ef48d57619348994e18be5b9d4c5a6585962732b11aacedd3eed8d091ed795057d065bfe2f866f727ddc5ba68fb4dc59e099420ec460aa9aefaf2ee52f69ed0c46f6a2d07b69e5f6661d62b38ea1f594be69090b1a106115b2b890eee55489748de355207cd753a36b27ae85a41e402d4ae879c5f934338a6707a79ae4077b242a85b95c9499b3fa79aa5af29db85855d625ed5ed842bf8c0296e47154abdd6dd8bdaec4bad31dc81f6b1e9d159ce0f04bfa178ada60c8d9d5298345587e610049278e778a9fbd3d436e0059a9ae2aa3055aca49f74b51f018a1f62351d7b7704e00da25e7acf1920c8abff668fa489fd9658de39d3bd4bd2ba04a8da010201139e79db376d268cd14d9228f247f010a693a79fdd9c3bdb80f1ba3b1da0ba2649f46372e176af13a92ae590cd2d0ac803056e32ab9a1b99113b0da0e", "53", 0, 2132613102, 0, "9cf1ae70d78a4f42a997bfba71a490244f48ef8bcaf9ab7fc86897e401a5ee42"], + ["030000807082c403017e766e71298193500affb03c5b14eee10c0da1c51fd0418709376cedd04cfab00000000009536a00ac6aacac0065ffffffff03b1508005000000000952006363536a536552861779020000000000ae8ac904000000000653006a63516a00000000486143f801f410ba02000000000000000000000000aaff9cb7de00824da553fdacf47a5c0bf4497fa3328d3954b0f9d95bc77d5d2c3701c9028c0c394190ea9a13a4ec9eee2a43c756a9715d7b923b95d3268a5b27f0d84baca2737d9da0663ed3e0750461b3afefb45c5d7c72b20902227c85c94b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0aa8cdbcac4e7dda9b92f17fb7c5bc1eedad1c22ac204d4861a148fc8af91cf5a68e65e469a801b97ee1ac2b54f8c44f1500c05840be7710cf1baebce325bbbfd8ee0b286326bbaa137f528e8457a5d4f6ef8d52ddbed19543794fdf4c691ec05df272d911a29ec63508ff20ea41ea2e614a5b39c97743de4273c61059096ba031e243bacfb9a0392baf95b446b3ae91d61c2e4ff10b34721a5cb9c670464467c0326ac3aa0cd94947ead19ec0e98013a708da2084bcb0b5c5713610489004becdb0a0424515a8cef41eed3cd2c645df6a281bbd97aec34b40671a9a3d88f7cf5a5a631bbc04b562811396f50b8b8dd030ac869eb6e9f82c73d6c1031e47457ef8256032a488e8834f86bceeaead247644163e0f270bc4c030a36c1aac0c1f74db854420323a9338f512982b44a6e9a2f841b37a72be4cc4573fd8663d2985f8534d9ccd4032bd09c25fa0d1ea4dfd26349c3b78c2f0653e4e77bdca929cd9e313433067a870315a41b9070abdfdefade842a62baba0440d508b3dc73bd183dd207dd5d144a34031c2e56ba26d93f6c7b9b7195d5a76956a93f4ddedf6398367dff9aee7e9d561a41d84a6e0c5e4917bd995989ea9761db05f43a6df2ff32181e3e15198ebf3c4b5256028d22e139ecc51cf3489eb77474f7c4331e5582e9e9b8010f44bb1d2ce78a9feef70026363b93fedd6957f35c027585e21f0f1b0ea800d77f1abc351953ea3c493446a70ff1f8790a21e68d3705bd00034754090116e87e6803ebfaa6752440473f99276ce95744976153e2d477c5b7742cefabd3d7e2556e291d3519b7d8f41aee94440eade118da04ce17974f56cb79cfd97ceb2273e4ce6d9555dac3fd01ce6ec0f98ae19752d24dbceb64d3853a94aea7cc8fb3fa3fa66abb44fe23df2c0356bedb8dca4c45bf3a68b3a99eece2ad15905ef3d19adbc2c18011a34d5526dd319f7ab12802a196f0de4c9c231c67c32b7f26f7d52725717ee2bff07db95ccf2b1216b9010614e5245c66b2aa0f65fd18846c6690286a3f45c5017d409514701b22c8b14f0ca9aa9a917a796c00ab64bbaa2ea95be1ebfb3ab806e0f39f86f7b2875ff23053b691dad8b8522721f1160528820b5f8442ece2304412301bf7bd96bc7cafe31f6b613eb3efe9ab816a9b5566421f837cba39c58386e72da3597025cc798983a4b115d8e1d5a44f78785fe2ffeedd7535726c31425b9c0422acc28cea576f4c746d2cb3eb1aca01b4dba78d4d33e2597023673725d4b752a05090d3baad0c0c73d9bf4a37715ed4fe8adc10378fe95ce5bc47fb63da0740d4b536dfff89503af6aebc9cb8fb89f0b7064532dd362e6d12479786e7feec7a50159ee649e152c80358a148bd603de1736cc2d05083268a88cee78f8974dee51c9e303c0b1e2a78c6c0f50e57f43d3932ab4924e2ff658f9f02515b827c9d6f8bdf4fba013c216c8fb8ca6bf058d8503eb45a1a8d1348c69ac7825d823ac4ed414a0d840073f1ca077ae5e42ec2b03290e28cf6f6e37c881309e661f1692810ddcd3fe311196280c6fdbfd36d222cd536f599c84990a30b67ba832df67d321b782aaf0ad6f5c8c591c06714954673cae540c80ba75eed488736863c35b6163461fde44e02c87167b532833e60af9dd070b9e43294dc962d5138c71ab9ff63542c1f51c4fc035b2741f587714b6e2208c6399e4ca82e0c21c1c5bfc78fd8f449ac65a5f387367579fa9f22e735ecc9eab6b10b85805d6b6a5321c6133d20f063930de1d4b80ba7ccb4de4215c065340dda7fc608189621019a6c2f89155a3908a0f0ec1c727b8864507d0dddca43f2f8534cd70c603eaf01c5581bcbbfcfecbac9f24255d011956987a53c7122cdddc0da14c5c96124d6c55f8f8f3e4ad8b43728746348b4dbc3b3fd0739b82cdd473d97eff519f30815e59bb0cec6e82e5edbb82883ee23370c4677ff0181980ce3331fec10053943ad42e2f842b9936e68458bcb2173d0b05a1a0c7c9004ead0061da02e6890c93b33db2584a6b8ab4ae5504f850526f3f9f7e4cec7eeb1590a22c37a372f9a7f20e5d564a0a0aaf0a08151c4600154f5c6c3f0b1efba5d43da669655ab43b36633ecaf9bfa992dff94c2892652c8d1e10dd8aeaab2ba63c876b5bf281bc49356fef8896b1f7fb28f2bcfc981e8641c3443f0ccd7e1f4d0e945d0b927eba827cfe477718c3952fe5f3a28a454184ee4d3657415c1558194003969857b8394203be7f6ea2cbc9b8d14f308f551356c3092a80b88e2e94ca152b652dfa2ee83a668e18588dde6968e648d69e4ed0d89121173229f4c7e8fa69c9a6f9461082719a5fa2bf62717d4d9964a6746d5a67ad66a9f31e83d7ea60da53bfc6e8700e2fee89cd0be38c4df6b626fd727b694999a0f9c1a752b375b7e210037a8370d", "", 0, -764619433, 0, "e335e0161ac80c883b6a1b2d45eef606746ecde2ccaca77904ccd94faa2bd06f"], + ["f840376403a92299d95e810fbdb0ba53f68add0d46c10d1728a929dfab49025941bb78aace0200000005536551ac513ef8c3f6cb3960fb9c014b30a38d3109894130ef4b44ad87007dfbe76afc7c716e8438aa01000000076aac516a535252ffffffff4ab1606c6f66569900c10b391cc6fffd3e68775e12f3452e4d538f99b4be489f00000000016310f72ab4039efe47010000000000c813b30000000000055252ac0063862b4c010000000005656a6a51650000000001ec22de01000000000000000000000000c3c2f2b6385292b5f01678a03836b1cd1edc1c65f4db9de8780a8ad447b1043148835c3d53d50fbfa3c068449be90ff2d7b4073097dbb896f8034472b550b2805c74811846debd083cdd3bd85bbb748391a7d50318bad7532538f724eadbce3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000391a7738babb87e18f50a7923e2d71ca1c15d09d9feb04fc7c28b4c46242ba251d5ddc01f7566dc5df0c1d98e712bc11af8f6b929d9df44edcb608120a207bd8dff65f3a2749d938a26b8b8e48082365acc9dd8cdaee14854b47474953643be7396cb82df6f2a08f610769ce7b40ee10878d070cdcc4b12f16d0a12e16ea7f8f03219a3467b2267e39a007913f5415ebd7e059f8f7331cc511a7f0269b5e00bcf30305a69f82c205c62e18da45ff5c1721117efe41666dadb30699e56d78064abb8f0b01ed0a21cacced808114281e5605db5423db1f04f95c9b9410f654e8c0a91365cf6c6ef5f44fa51555808efaa914738968e452e500bcf464c20ebe83a4427196032f98462dc8253bd576300f7eeac486519a152d8c244e0c60a6df0e0848e658aa02134fe86e90f8901f9c37d636e5add382b965dd8575e2f793dc9a253e1ae1831e031f7275be490aced12e1cc8eebb4d83565bb6cc639e982f8f0ee9553e8ea2798b032a6b4aaf5f00e8bdd52c9089f664369d537e2df2770f0ce66dada4963503460d032ae72935a1d7ad31f4eb2e275ea5180e5d59df341007b03f6501037888404f50e574aab0484db44d549384ed71978c300f140d2f15ece5525e1200c22abe4154ac397324b07eea38b19c235af80ab5b1636c3bbd3254bc180aae17aed440f1243e0dc08a23938b195000eeb7c19d636ae9ebf0ef4d1b16388fc41ffb35f066c8e52b20b7927189fcb04bf7443c3dd716ae5891264237dbbf230ef525354492dea7dcc98bfe061373b993da3dd75991900c50ff3da8f0ccd18c9f423a08227c2c5894c4a34b66dc239e1611284a152e8acfb57b96799f05178a2b535ddaba110e6ad38371ed2012477ec0307f8a9918e503eaded7fb85ee8ff043578a48cafc4179459e087828f1e343d8fa83c7a8a5f6cec768f03def7c7a21ebd4a4e94a509555aa9a7b0fe6f9b32d8c4202ff35ff65129b5b4ffb57aa68b66df4a9acbf470e879b98d272da962f9433dff6eaa1378cc79abf0038ce7f68bea737af02150a9017ba5093cefa4f515814f6fef0d3410bed515566e5bf4b210007ab10248a5d5c5bcd0fd1963792247038de75ed464656d0bdc716b823ae4a3ecfe0f85912d9292e57712795614a923f10f22773a92b9f7a332ce5b44980e25694ebace80ebd281b98d45c612883fd76b2b7bc745c3b31de26e281882a11b9247555365a65fb79910e0e7556632a90769b975236a7f4ffd0fc2a4504201abec803d4b78ba0aff97e5683f885f5fdead82a24dda20a39a0f4017db86d6859505df120983cee4aea1db4e4ca03ba8215b6fac22e340d96220a79655d2228a240e475664007406f7aeb7149015100d8e615e24ae33e289efdc3f3e1667ea7aa186989b921053541ea61a33d706c97c4525490a50f48cf204190bbfcbeb3aa69f01db8603c1cbd219251b1b4264487d79f9e3ecd642175d13e9a4615b45d738c6dc320dbbfd2ee4e2c4d28e1841313c23c992666abe109b144d333ebd650b186b9626e740dcf2e82df0364d47422076156e910f2605a1abed1cec1374f4264fc445ae5baf1f8d0caac5d5a58f308379a3da0a291b7d6fdeefd265dbce1276a9f3520b44b31edf37b65ff661dca5923dd1291ffe814980a0272e640e63b0f11fb80848ab4771b62a55a2da473b2918aca27475cf2e35a5faa2ca985bc95cc2cb347d0c3f34de39c2fb42abaed31de5e51105cf8402a02e2fcc054625a33847e2214699b5c082868a47239b7b65c20b5f63eb82c6e83041bdfc3cc5ec0dcc59417a2fef4dd869e8615eda6cfab6a60053019148a8fa64a7280ecfaca14c670b7264a448af81bab6bd87acf2264dd2b14ec390920e0822280cf28bc8ad0c6b753645dad81e3111d4d4007aa1891be85ff1d2f27ef61e9fd84b1051ccbb2a9f37b96fbd51228705c8b2ed9f32b4fa6bcfc113070f8f57e17465aa0390f582e6ec4ccf77b83a1d1f9ec28aa9d639f3af98acbadab89a656d4be1fa29a36b8e1136d9c904462bcaeeb473f1dc4e71eac93ceba80c770954f5d673298c2283796a13f79b2b4551881f7feb4b9e8213ad2b27740489ca9150762972b29f347c7d27d0a57af7ca979fbd16ca154559a31d902ef35660385d1236d6c79ecd15907525fb3b69b4c15f5ff6ceebb867830592de5098f79bb7ec3e47254e06f384993229c9bc2af9d1db0193e159cf3c2bd4f97ef17c7cb716589192b4a74c8cb5042f7bbea7e6cec4f6e60b23dfeec8737ce09745f0c1f0685584ef8deeda13b8d79c45be23d655e4ec666814d6aeaa7cf81a5318a7d8739db40d1e1dda84a18d2859fcb99adbc78a16039f894919705914a823552ae22ee1e92c04972852001a007682880a091f5718ef19f7cf392ffdbade614a16c372d797c22342cd19b970c", "655265636aac", 0, -112534160, 1537743641, "7adc6861c7942355a14d9cda58331ad4c3c3e50b14c8a4f249bca3d100f4388d"], + ["030000807082c40304e2e2a47e5587c204fd12ff54c5a73e7db02d7bfd700e74ef28e3a5cd80ed490f03000000056a51535151ffffffff241e9ed477d84995a97a62f5c3874beff1fd2d4b05fd6c2ddfa2d8640da3106903000000025265ffffffff3b8c5272b30db34bd71cc79d6b233d8e42f9d308fcf76a382dad0957c8c9d6900200000002ac63ffffffffe0fad593f10c15f65596b8644518175c1297aa714653c49582601b5204edcf4702000000085353636a6a63515302024885035f3e840500000000016353a84b0500000000025200c9ea1404000000000151002feb34e01fa35f02540eeb050000000000000000000000007c56fa5bd901130864ee732c18c24d87cedca4e3c681cb1f1e11b91d7b714149460cc641e037a035de4e9bbe94e84a841f237cd9583d3ec6bd30e6d95be7756912198bb11f8f366bd027a94e7897adecf7aaf27ebfe8302d7ed9194b34518c6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001810387d682a7848ef38b3d1db32c3d25bd91568cc71e214b5fccfc7b56892445c7fba7a117fbc34f0ef2304b2b4b0c2aadd5e105636749adeb9aa2c8ae8a8b26f772af06b11110f186f39d9aca358791526a4928584ac478d492e8da72df03eb271db34d7394c2a529805af74e03b9ba113161c9a862ad6522bdf7f84ffe242022578fb2bb9ae823a8fecb9ee6d427761e45b20c330780713b37cd4ccf734690a022878bce5af1baa61fac3510deb68f65ab1f0a8a78b706e3b8ca88fc86e0e264c0b0336825525bd89a5d2e24b2a3c4c2f975f41b07b08eebbd8a17d72c07db84c9386c870389917ea84ad3b61f519f0e58492aaf90632b67f4343cdc61268671310020290e47a3d4ebc4c07e4465ae3ed62a482665260208dba3855256c1b3437e68f02283b182eb369331cfd38b55efdb6605a237e3a0e8e6a36293baf18f991bf6972030a15d6bb65756ab4cdba74e55d9c2a6a93edefa25f50c90aaf9f78e613d99b7502104885c53c97068aec065aafbe39bfb240c935458299c44edb4cf562d5052970021cd00d1946007c1d4f068049bfcd033127a80550b901acf9b5c845e7bf14ac997253a9a44c9431fa6bd946920caaabce3aca05cce555f65e086a2d2c47567d4b0c4efc2be2d74961703e3a72e1c9d6a32a3877678965c8d4cb485cd7787d48874f74a4be670723034deed5db93f6ccfc78a2d270a5109f6917e05e40fceccdf1a9e91f94e969683d5d23790603f35d2ce82b2923da873d827a666f816286d13dd86939c71e2895a568a44b93f94da238c980b2dbdc66e84a04b62b56a5604a0c287cf26cb57aacadbfa0ea5b19d216ac5912d03bff2e2ae633659c3fd0c3292d0856eafd377b830ba4a4882f911f3f6bca2d3d5986263e8515c5408ddaa488aa4f27699ee82c54f37ce701cf4c94db9b57852fa60a8e3a64aa8014f584c7d6660883a626c318f0ca5e54a6520f92a228ff9b6830ec5c8c0a53f57e30d1feb83b43ebb5458c77fda385b14d3a97a52d4b2d80667424395910104455fecb93f809da58bb0ed8db4f46c9aed74aff6e39a90f520237f27194dc465e11f67e13057c8240df78294c3a6f498fd61017a29ebc6c1781d6a69cd4f95335583b6e7f98f71c172383a6f95c828c95da3ea2f94509acd1b07db6bd004265525f9c7c657b4bf9056704e9fbf82fec8a7ff8bca13b4155f2fe384a6c9d0677c7648f4595fe28a242c7f380d34e6462e06dccf09494bbf95052e3f9133b79439e80138e81987aa2ab624190671f52624d526e1ceb3693ee045c195a195119acafa9e0a9ed0afd963291bc187f58881fde1381854a2188173242f5a335e310ce558fe8af8295dc45fc0c76b6f445823f09b5bc9cdd9685777b1cb646e6b3b571f8c72b9b1b8c1737724c4908a8d83a25817d7bcae3ab27c3e58a4774c487554ffaaf5673bc6d800bf9b5df80c83117fd23d4ec4674dc3750705ba5daae815525f82c7445591c865e283317fd9a3f22d963a407fac0963b7606a8b6127f36a45d3f3e20c89f44631cd4a2500e377d29ea6cfb198f9e62d8e27b2a431b5e548c2515ee5c82ec513efa52b1213e2c5837811b0cf2fdbe96de4606fcca439cc920df400ba7456f321857b0c495d9c831ccab187775c3d74364d0648fd5c05aabc4eeaf54551d7142c10a05e51d70f94a99b8e150255dec09dec21f7ca1047ff49928341d3a1bff807c0148d502b4ecf05ebb9c3be13b7045d05ab278332c8c5eec66c5ff2487362752b20116a06f2f13b7e2ac9e50e1a9439b1fc2042a6200b1c7607cff6a0f1321c8f4efa96646c54602dffc11b4c015c52c5bf63ba9c8808c29f0e36cd9cba510305ef8114574ca58f2f67dc3c64e00f9e6a235953ef29d8cae73ee330c81a484a013815b09320e52baa48c7383572be51aa3da24286162bdbcd9b74dac4ce442067380c8daf8b799824721b12a79c0697c81cdb80d5a81175bc9a719eb35b44432cc947db01e4388930878737b4c61d133146d47d2ab55460b4ec7e8437bdab0433715a077b3e7661a35a0ed33fc6be1fb752b75bb8af4822b771f7a327311ed035e11fd83722f5d8ecf7579d9440e83a0ddf9de4cb3f65e4b8979e98bba9dbbcea749ef0b1c9e4c8f02235af34a05d37418b28e74c9d7cecb8a2b14ba3ad1ebfc7458236f16b45f5790e873196ac1db77f52e1b09e338b5a23d89af01469a06b33e96f7db366fae4e228def3721e59ab3cd5905379ae7077951afa73eda4727d5b5ab38a466c0099e38f05f513deea8600142238b99050000000000000000000000004654171bfc0ee82de107b2fa2cdad6844ebc156bb89a4f84f721401008e399f763f6b9de3151cb79cb482e2e769e703f1e95254813e4550a65154a8693f644c5a585f753cf3f8bb8d176d15a7a2aa1ce657406e97092d4e5184c0e8d245a17680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004fbb522fe17729934a1b4e10aa6c426c4f5330156d04c32825d267cc411d8dcbccfa0600274bdd2391d336e9c0bf4cc6d7dd8012f2555c1fe34442b78cf3ff3024e4004db4c372d83d1e3180e804bd8bdad700fabe75252bc80d6c4e0344a56ec3fe47d7419ad96eaef60491504fdde750b67fcb4c4e5279b8f9b917017f91303015d44d5eae12c928a9365ab2b4af9c12e089ad0b49f31e6be6e4bea805121ae0323cd65cb2f768416b5f13f513dfde3b685640b92cb6edf72f3a7223842e36c0e0a00af1c8c4713dbd3c5ae0cd3156439f48609fba978f337d8220ea0776e1b0edf91265c2aee6ea44081b45179b3c088d2bccba5cc60ee28458cf4084a66ac419b0306733a4e4aa5ee845c5f768bfb1270848323e9986aec1216512789319db6bc4a032f47fec1496e8e752a20df8e584a32c91b6326063c343506d36668375067f080032385aaba6088a94f701cf9ffc64abb3c843b6b47853f2b8c66bfa3e01c213138032ab98dc33f0dde10768d017406fce0594726e06ed290f169215ab48e65aefc5c020ac365a96baf25755ff6ef12e04cfd28f18dacf43ed1ea4a543a3bc1629f563fe7077ff7db692ecabc0b8066d53a760f73bd8f10c03ad6992df2f0eee6ccc219926c1dba947b3584a56f92d5883e81d30982eebe64eeb7e69ba39a96ee5869e1b5542761a89daa722818d8388e07498014a67681b91675ea51431a30c9743cb8fe81a9d251a0fa83fea312899d4ed597ed7a8d90f7bb77805353e16e20691b2e77ea69642b06128eb650926a60f1dcb214aae7d68bd18e3b1c10dd3bc0cff570790f3916347a678d808a57596b410e2429b095ae27e2759b4678631735cdccc7376ce591a0ead5fbd7651142fc25afc86ae55fed83e3b4e1b4fb13197ddeaa45c1d182a7f2b3901404b8d751cd61dec5a772fa23daf09a723dd3351da42486acfa49f5bcd81ece4f34c03e6c4e45d1990ba855e6a277758ccf2d9ca9a55f40a27959bca636eb88724e2598961f3088b2e79b45e4979dbe119e15e893fc5c0a86b3b315a774fce2b89050320a0b34c36d190b6059e93c244e68eeecfe78f8b8b3f39bd380e9237640cc6a319ec6b2eab133f266a635b4c19e380b5f2619dd4264eab68b70bfd642597ac84cd3a5f46b4385466d86b9f0962dae29b8fb938fc462086335d7cac48e35c9c1a89fa6cb85c0089fd99ca03e8b314a4b5e738392ecd335ecda85d8aba4947ce515dd12b402cd40d1cfdabd2ed7f25d3e32bbafe763b804e77705b85e437abeaf0bdb4f210b6558879f0cceeebe0a2ca2f979a37ecfe68a377f2dabee77260d7b529084cdd30453973103a231b3c65e1ca9c444f4373a48f6bdbe66e144f990ab7246066f4aca85a78fe44ec15c78d89049fa7087836135a78235544e0b869c4d7f8ec7db4b9c92b8d1adac5b027caae8721c9663ce621f72eda40d28508bcac8b7db1afbfb9e6bc706d30c0aecf12633191dfa9a48584fa0637ded8fbcd2581417303cc0407e0a2d0410307ac171a999136fcf450042370c8705df5aa568b31673a57bcacb1a73ac03f859ada877bed3773d86527526e0c2e87ba082f667243aa23684cb8b2ff7a3be9265a0bd362f947945a69a990a448247c5d67b6776c6ac700c72a856ae8e3681e6f8bdf81669b17f86a768724b8719dbaa5bbef151703e592c39c9bca3b02a2fab9b5cbd25fa623848a7505b44cb7c7681abdd3b010a2415ef26ea017b1887f8388079c3b04fbf57996d9ece54dc3b30abdba01b4f7175881013ff4018a3d0619c26237fc03edb0c79c4af6e2cfc28294193dc370d6aa2e8fb5306d77d8b316db54d626a51fa0a5aa9eea830f8458d86fb8403e7f89946cc74dee9956ba7ab9099b21ba938219b204376b45cef1a2669a2bf2347290da6543a1342e6de4089e5e83e8d9f442f793837b3c6baf389a5aac5cf9d3180476f8252ede39730fca19405c956ad5db47296b0c795260f35d9721d12aea0ba567fe138dc0647cb11d2abc33ee6125848bd1c7b16538b61341e61f7b4dc7fa7cfb22c80f2e34aa954f13e6f5f9185617ad9c3d3b51329e83b7939bb769a90a91a1ab58c9ee5d0e3153e78a19dde2507bf4afe38065bc8d34ff12b45970eb428f569649bd430ee27bb437403a711b3c38a6679b190db75eb5071964b33d20930064e4d3b5479b9515ae5cee5c1b784d9085503e2b2812af79e0e074c77c58ce5bec26e42c9250ada7725a54c9cd9f7dc2b49c3a288f49bcd043326d3205b9acd5bc87f59b19e552692b204b0199f702368ed233b8b66c62f4c498e87e747eeddf5ecb65ad5aa1d385a9524ae5e6f82438272beff9118ab192ef373c4a15b235fd966152c60b6216d877055d6b444f29dd9e6dee596a2cda2d767afdbddc5afc46dcd1ae021c57b18ec00", "5151535200ac00656a", 2, 784921415, 1537743641, "8479e12630e5e0e8ea0a0d3349b9d2b8f7558b54f66cf4add79e9dc00a9c6d4b"], + ["030000807082c403030da5748c8cabe90c87cdf03d24454e7164ee6ebd39b9099f8b370f3e91668a640000000000ffffffff032d6451a7153a14b4f0c1f482995c7c7000f20d8199b3ab6b38cc0f8cd65982030000000300ac6affffffffef41993ef801c9f2f33e22dc3b38126edec174ec52fad6f6f5b4f6ec73aa1cad0300000006ac5100530000bc06b3dc0453e62a00000000000165415d81030000000004636565ac99a37a01000000000153e9a0270500000000046a515152a03906bf00000000039201b3000000000000000000000000007aa6a17fae6b4d0b62e5db302e12afc293f2f0be3d779cb6403a69f0ca6a4b7bcde6099dd3c1c21efec7156399d3c6c99735a460f919403942ecf81974cfa8015ad3cfb0945f738ed84fdc1bc1d2d03e5689cd262fc78b805096677ef103366f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a9b7f8167ddef18fff7136e9a0c4df80f59e66ed7dceb5ef74121494dfa6d38ce2f09efd6a24de14d3eff3b4bd1a4bc1088185a2e9e6cabdef546b7565db8a9fe7680133b479382f2a87f7e7eb02a74f1c34dea722a45378d72c2b64fbcf9d16cdfdf41ee34e38be8cb7662cc18e5dab7c4266988ad0dfb5939726156dc54b9502252ae60d662c5be3d0eb57d193f02178e2d9e5e0d42bc25c8137656c3c2887700327a14f4f97b5917bcb4b009c09635dcc4c62e7709254a4c34592ab4ea59410230b038ef9a88d4238541fd7fb9523726f059e50b808836afc0aebe88379955da008635771ec300e8c22dab7e4fae88b0f51a24aa57c33db59959b27dc4e46663b53022a0209e6714cf6393e6e10296b5469d5f60e38a26b182a742af90c86b4a3e180031ad02586f58251f12d9cc37107ea6f24d3662c6a5cb2da2cfdaa18abe2921ccf032ed1bd5a0fbd92166dc28327d29530fa7ab9a205422173452d3fc1d2f20b2c9e020e3c26d79126be1ecd032f13317a7a51a1e14c0f08c8c78c2b761ca947d04540030c8272fd8ca2769bb48f13c194ea152d2b21101c1ed45a8b38b6f13a2b9394120485008957b531bec8b90734c11ff2685a46dca3c1e714c156f030682665d67991e2279cc7593d99a6c349edd210791bc6991a7059e896effa1ad655ab4ce3e6626ec112b88b964b947a74dc748c50af66165d8baf9d8d5d07a5a237fc8d48003a2086e4f5d72edc3da93f6754c0d6fffd553c2033a130baccbe96704cc894532bef1c7f01da9cdce3c7f4d5fac7527ac44556f22a6e95b64837985e66f172bb018961c7975cac781aa01b8a04f56c92d5c84d944fde83296c23085f5dd74a1c5b5f610b55f62c2b05ffa5feb72e0eeddf83ce48e40238e78dd06a146b05edc58dbb7e6917c4ea6d2fae4ac3c9938da990bdd557ae24b72f39d424b0f97acf41fd2af342c556cad91449c82ede40e9ce2e042c79aad72bac6e9a53f01cbdacc232dbbcaf9baa827388bf6fc299d4e0f776c6df6ad4e2685f1f84b8474c21ca7a33a9c7975ff96f13a2e47552f98d2b5a8fd8f708c457736811d1ae7b80e8cbb51a735149a11da7e3fce2b60f4b30d11a91ce6d3609de984030f41cd83b3f46480c4783d322840f06c43c3f054b060ab6916de6a1e7665381b3469fae61476bcfac96c78fa0c1d70ac4e521bb23ec49ec8689d7a6b7bc058e0e134c92b5599a3238bad52efe900f4ffa38d83d65fcc561b0bea01d56e16baf6871fb4ae603981ac07c1da7dcf60000f714ab0a8c8ac756f49d1a9905dd1a90eb755e6dc74361fb499c107333b4e0ae3d4ef98a5b31d1a25e4eba730ef7146b2e81325e5afbd5947d27f430f89715101faaa0821a3fbf052b2ca6c217cdea37f2d54536ac445fb83e6dc5ae0994b535ec2637ec6bda24386c5971fa9675ba236b3fa6d7ef19f49a9add8dbddb1601763ea77984a6345375216e2e1b5cb7c450f525e0fc71315d4bb2af4a74ab3baf181452ff9dc0a895d6e6049623604ec8dcebe5d89358d4d2eb326be86b32e06962bc343d352d88d36ebb3d60524b5281e0c15a876e7c2271fde96590851706dfc7940c10aa2f7a3008347e485eb2d03d98e68e99ee908682a4c93c06eb86c4f8be97f1e23b1c719ca0f1044bde09ac4b5353ef6f07d35a85d45fad4aec1cafdad294d161f320c504eccc46b292261de08a5eb342020301fbbce015cf289c1a08429ed8768399debc1c150ff47b9fea2d65c39731fa3b108ac56713047f54181e6552e055ea1a56c5567dbddb1a9e88186e02f7605cba87e9ceb4b8e62636becd6f6eb5aed71747903fc173c20bd59bf39b8b7ea0560f607360bf73537e817e8aa6a8b5509b2f713787d210fb38e6775044b5f866a32a44f0aed68c1cdb56f25a640b9d9c3cd15136fb144539b3439e2631475a35dfd2494b5b413de1728e25b6c8f17d0f30fe25f493d75c71c085f8280ee123bc31468b527816dbcc4d22674bdf8155cd60996dd57ff03074f936a6cc928e3ba1f10bd40d106999015eafcca7efe26872b46de0268208a5f3b27de18c911d27a02887ce94d7fc455d7f0027ddc54fd23ccfe445cf445cb447375e5173991d55ef1897bb88d5ad5b6d25de5301dccd8a83b5b2f8b43378f6748124362b9d11424fb42698c74338ddad11d8878027593db3e6bab0582865ece8f4753279a8e7895902a5c09e7b24abf7c597cb6eb51aee67577ccaa21b33f044e408c5ea8f22f760a9d3abed200f7b3ccd6d22f78ab056269a918406708180000000000000000035dd5a05000000000a086956937f27578e5a3b527f090f38518f4e8c47fcc531588fd8fe11ec8c39e601d3a330c7911e58709d836a33b539bd0fae28b3fd965fe761397c03558415bdeb2f464462be9b726966649ee360fee781d8238952832b0c20a0f0cdbe30ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005dd289ce4139a4776cebec8e94f8ee34d644ba47c03c5df576e6a9596711aa23c6b566fa2c2888b6250b4365e6db59d00a4e62b44a58f460402d67793b441aebc49ee08ce400f18c1356954afa2609d68f948b0c531aa9c0cba1758fa7bf31553c5c1166af7f1f119f864d92d26ef530184f25c180fa1f4aebca9bc19f7c72d1032ccaea3b25184184a5d25a475e3b90e94593d8dcfffed9832ace1f60361baaf202192826f5aedc528698a03c3ac5ccbc2731e02fefbbd6460a83b4831e877123610b011197f3761e678f04f3de09665ff07fe00d7906d873627d4fd7d666ba2c44f5a53a44a2b1b4afb6c9216b878ef5dcd3a624088d8d07958ded59b17ce80f89d6021a6c1268afdeabd322a28aa712ba238cf360b3f53fcff23d38ec6c92fa49e29e03097bd9ad72a25fcde17a67a85399c020af527c6822e677926fa97d0528cc24010228c79b9d78cbdaed6d3618854622eea9f67a2b59ea434d045947e3534c0e9847031dede4c67e9468881e06c839a9d0b53e53051a548fb3b4979079870d927cdfe6030e3ac9329a232fc8d4c08b40837e362f9c29ed019bdffaf37860980cd70a052a80ae198c9a9d5bd39dfe73b9fdd3130426f528775c83ae5ab298fc15c670d5f3855eef2f4d324b116536a5b275b52c8ff4f4e5ca8ff4ae09bd7068dbb58d3da659a2b3f2536717b6d7b10c513c60dfd7a00b353a37c23155812869dde0901c2b596b32929e8b5bf7c322271b96488ae8152eb7692ab76a7f93795cfe19da4caf8616d6d1bf690ce91d101c8b7b8aa5a768b0b59931f6a40e3d1c22fb9b512a0971e767ac1904bc3e577c841993f68c4e82a13e32d5d69e90b205f09de8a4a34e1f87db13606072bd338049e6e26bde4be2234f148b0190e856ce79ecdb3347c97ca70d3568cd23e48e0d27d423c1d5492d942a51f5f4fe7032346326831d325fe12e6d146dd379b25407b8af0324feed3f9ae63bcaa2a8c28c4946224e05cb2f64193755a9832e0564fb6dc7fc1f2432138c0527d82b7c8d2b4edb34a651915bd1727e22f454c26a7fbf92874db85252db7324f1a4705e9c66f900e62781f9f9cd0ba2f4d7c745c8fcdbb23d8068203bd867358cd5f75294e145d28a9b90af053c79e213910645d420b40b3964d82065e917907a82a9bb9a9931976e0160f7b6091b6eaf26987387da1878470e0a018521eb79b951c3b3ae920d5403a48de7daa207146698524d620c5684cf0addaa99ea66836c8a4acc8460409e8054f581882e67d6b5b3fe20317a6de5759cce88f493c940a3e78d3350704b1fabdbda2e7a56475db55691da3725d6bbb6134a9f7e3501cd5c0c9d31d9002a6c183863da7b3a13730eb618376fe3d73c375fc4d8377d557e0a4b9b67363ee6f38d20f33d5efbc8fc8679b8e7c6a74e3ba896ba676e815458d017691d4ceda693f61a39484c8d528e311e94f1762c2d50a1f246ffa88c16cb98ebe593fa328a9464fdae7c5ccca45ec228d026d4572b712d249f2e309f0a710ad316c1e14ab3c92868458fa5380fc3c96bb9fefff83b89fd7350eb590401f173c6840e4dbfbe6c9d15e309efba1d9efca74a897f9cc3085bafdd312c3a4eefd28ff24e89acc4cebbb33c010632b4cdaba61baf4eb30ac603aa107d5b4a17297a174c078d45707371c064d76b8f5b02424aeaa731f1542d047ead97c4e714fa381aa3b9e55a1c63059e8b740d80d26573e5b53da58c3f147a1a424f764951c9d3b33faed53646fb4612bf4890bf6cf2e1225fe3d5ff61323372ba8bc6273a7595856045461edfbfc7270a6d45995610f42f303e1176acaa89252d86d3469e3bb5544488f4e471386d57cafcd20f699db18600ea5e013552b6a0e8c69164f8e43c8e3eee2f6388d6d5fbde986cf99b6837414bb9962226ec49c395e07964129cf6d378ee93c1fa9ecbd803d75f875b1219c98fd7291e12ffefffed4ab9ab2df9cf96f7afd246e201d7df39221e523bd9b55bfec8fc64655cfab3585404306b6f320d0a9106a5fb6939da4175227d109caa8c25b19914724a775712af8010427180de61d177d49cea579b8f41778c1f248e0e02dbae94f4ea59765bdb8827267d237a415a38538d7141e3126b1c843ca3ba31814de57e9765858ab729ccd7dc2414dfb51d17ac71bb0f26af56cb99d3635b647d552b3c6c14a7161fac07845ee45298749134ef187e4b3d52e0fb0c45a4691f3bb7102c564c8687cabadea5390e58402c8bb658f1487891905a8f33225e8d86b22c8719157e0b6dee6604423dd9731d0200000000000000000000000095a8f7218be020f77743ed7bd6c3fd69d5e4b1da3dcff0e3979eb0374ef7c139695f5ad7e7929eb4b8e2c52c4b9a193ddad01f0243b3fa3b4e7ff734acc873d5587d62f44deb0fafcc3b43a4dbc2682ac5369acefb6e8bf60a523ac1a1001bef0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045ba3f6cbbaa3b4896824ea477ee74d27c57bc6217bbd823176a94f45f18a220185482989498a0bf87757a21df9b7ea94395e53800bfe90c688d34a85885fa3debb47be6bfcb54f626fb65cd232b6a2d438411ae6275ab1c94931bca4b9402581c7c1a10a9f03e7828c6d372085c9f44ee3042514c00ea2fa1221ec036a2afea031287ee42c3d763793f56461f53c4f2b928b3595ff78f6d65d0ffe83b7418999f0321d6f8561bac6c544ab81cc1c76a7ea798a42bbb0ddbb505da41d8db732c976e0b01d9c748286d41922506c1ac830fb74cbbc8e52c32895d23140d66f5af3b0b1b1ff07fa5a422bb19f376f88e11dcef66a5cd2c089238393556546bedb67164c60316d990b5e69a4198c26c06ef3177205113744a4030608b872cf794b0cc4bfc41030f8bac11c9b20bf83bdf1c7009a20a10e6718b78da8c563a979a6b6c1b58d512030f0abf780b449de7c59769ce706fc795368e5e732c09290f789faf1175e5a6cc022509a74b656d02c2b55658ddb1e1ea0a1ab377cfa0c5b13c504a238bbb75db2a0316aa28399d660f30a5a2e9581b6acec4a526248f5e73ad3e5187ee3a1a5ddb060f97bde562321b6a181ebbf2d5d82c2aa147a1ff2d9045175c6cead0c3b8e4739282c73d27322b80eed87a9c7e13cbd1b406313ac8f0ce830909d2cf36e8bd00869f598d0fa9886ac6008e187425ccd599cbcfaabe8234c5f081f8d704904e1f453c321a3573b55966d9b4b830a609b676179ed5f58ec23f92f0ecd7aa927261c8a70caf592a3624bef3471162d15f2538d50964bee5bf804aab00f092d1f371b1d566e00b2f5f5c7e266b59e6ba293afc689a5a1aed7b973ea8f998f7b23ce39dd6374355c824e998384ec667cb2dab247f4ab8d359619b40974c43e14663b9222a079d601a174495ed2d1f077fd237ec4c08e717233245e8197c67c20975aa0e3c9beb1ce123cd56274756acf89a8aead306feb7fd4b1b834004c2a121c1fa35aef0827d6e0c378f98830b4c433d445485c9df80699b4bfbcb035bd2aa0c46bafb8cc4f972a8cf6b4e154641e1b255e7eae0faa373dbd4ace1b2ed3a20433d9d180c65fc1eb672d0200b053153106fd27df0401893ffd5fc93e364e53b3f475998e7a3995d407cc1f93f77a1342be73ebbfdcf2fbe66b3e9e7d3037d897a6139c11e97b1dac7a92c77108555aa079a257098fca35eadc9a7fbb2e06e855ad51a2432cc9a590047418bc49f30f8531c93abf6cd53bfca6373c12da07c24f4c1104721096ffe0d2117edeec12b0a268244d7e982f43673bd506477ffddbf17db3e1881c6aadbd39d0897f2ba2ce5d94289c3ce2034ae32cc6f238a456a52e0dd123ffa21ab286b083c5ea9cd37df98752d8b9368d3956a30c5ff578839feb20b6e86a351db6ef8eab881801cf3b1389a21544d43368048e64270d1e51dd71b5c1a5110fb059a5364fc93b200a9ace11283fcaa80083c4b30af7e0ba8d2729af416eb719d60c5e99528a28fbf0e8cb8433e88f8fe51ddcd78137fc3d8a2f1e64fad055e61a9e44682ad145dffec83bc129713ec6a7ec26a973785fffd7bad04f6b13bc19380899940f24c6c175e2b9dec6ed10b0fec00b008a0ad2e12669103d124eda08f24881d4cc4f8c0bcaa6b6fb5b742e2fa417ffd39042391f669c8584932ee1a0cf752503ec6ceabf2ad28d8e19a878fe3aebfb44dafd690aaf9a07617808ab29ec491c65a79e5518cd768cd4d9ad140de4697d5ef246c738e815523dcd2a4d86b67a706b35053bd8b6960d77978533196b0d48ceee6cf03195c62759193a448124cdc9331510eb5ad90d2ae8e35bd682963008ebb33a2b4fabbd8659a6b59ec9f3ded0e372d357e37c219035f896e6b6166dbb65986afe9e31676092a0d519c8dbfbc719ed10b3f7ca34ca3dc9eda878f3877cfb32058dc05172410330b11e34b68b4f9abfe1b02f81e39bcd291dc6e3f4d955355029b6dfa08e65d0e608185cc28b0fec2574d7b3c78cc8d8963c1783d935761d74e57468eee205a1f86ef140f8c5a47878ceb632572f0de181d595140d2865ec339ce116eb3dddb4832dc9ef199d693d21bc190ee82134b84fced76dabdf444f90699919acbab05b74e00c25dfd9f3c8f6ee4d2323d4c89b64b888bc69cf86cb4d4716ed53985b67ecda73e5ae6cb9ad4195e39cf8723b54c8efd3fa28f0b94994a13666467e2b7e25732c0c23bb2ecaa1c239a847116fb02183cb25f6e3d3295182f6beccda329ce8cfc34f8a521813a91d019d6fd97ceafda9a6d3fe9856526b4f0adec0ebae6dda42ee4d83c7cf266390b73169aa43cf4d86ce29a1fc9720740f9cb40006fd7d9a78467197fd207182f3a016378d6fb769a26af178ba5d811d9f051806dc98046ab4a25bed4991703c706419a70a3ad552f01", "", 0, -1506474503, 0, "93054d6ec434d3af7ce10ab263ad69e385b0673b7f99a7f22157f17782b8e046"], + ["030000807082c403016a57ba705f5ba8660856fc885dd796093b88076fdeecbd55bb2ca0f6444981ca010000000651635265635255f455f601fbb49e010000000009ac655300526351636338f5bc330000000002000000000000000025852505000000005dafaa6beb1f753807810a3d53926cc82f8dd05ea1bff4db79e5e837b8597d627719d0d0411091df8a4b9a4c484edc55b0e138a15a271647d3ed93aefcd6e8d53ec65c6b4ebba7645e7e690f0fa5fc3e9d0ccf7ef4fd60c4a4d42cc0339f4ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dc7aba255cc46133e21c673ef26193d63954389a290614d8ae530c19db6ac52b42d8897f10788d574af92bd09131d910ebd7b9c1eea82c2e34f47dd46e8ec88773a1eb84f09814313bda87d2fe05a0bd4f5615c294ab8df76afdebadb3fb2746ee7ca0a1ae3a50fc1f24adeec8f84937672653901b4dc3a034b9b2d4251c9e9d02216842c5742e56247c4be54c8f92bdd68f81a09645e6c68f85240ef1a620972b02241a0050c49a8690948beefb3bb9eed0464eb86ef2b86436b82bbf05eb7591860b00c056dfa7526578e3adf53e591abd49ed623ca32b22fcf88abc1992c2de9888bbef17280720fab98fe1eafec7c4be0eda2d5206af09fa1e71c92bbe32713e9f0201ed2695b352393a3fa7e59c5da927181cb4f1e5186c74a525c09bbedf9451c90210acd8db477f1108dfc65a270b5a00a567e20003cb44bf9d33be7b0285bffc1a0202aba2b060448614ea3f9db36e9a1b885b4bbff207e6b664c656923896df045f0318dd567b620466c6077250c315a41c5056f56e870627691ba7680c3f2674a74f0228a6d82e7bcf01b2c930b0caec2d4259cf3818b1a6c23f32c722dd928cfa54028b5a99af4b9486dc37c476e1f8575c06f24ce7ae24ba8bebc9c4e4d76570f4fae91d7b28073626f25095e1058acc3e15e4c0f80d42e4da77a97ab8f2f4eb21f500da0ce9dbb1f1fa836e2e2e7bf1ece6b3dde545c1ed6ecb2127311af902e7e539b052c35865fb27707c6712a4e0113bd923e6278c90e89de225ecca5df160d60e2bcf5296418b7dcf764a5ce440356b99d89a2550001fd5fba6bcaa38180657f1de595d9efc1ea5ceaa87348097f1fffefb7e9aebd65c8ccb8076902139e1527e656639af7720fbc59baa5f0b0802f1ae82006ad631ec8e1f6998728482dbb38d3223cfba12948f6f880022f4adbcbd49be8e3b8033fa185a1f9a79abe299ae70efb5b1a48ca12abaabe4d737e6c1c6f8a512a648c4358064fb5c86242a1e15f6f7d3276f36e73d6a940c36bb1a9803eefee23182933eaff96b4bbe2912a97441d0fa054ad87c2f686587390df010caeb32369d11162c476afb408644a63b8b0f13299baff2fe6dfde96d4bcdaf748d6c25296a95e97f70d39f1838f10bd1f42be2179bd086407a9e2ec7aa08d2c122770b3643e160215c5e24902cb91a65d5ee7b81b57bacbd4a2f545adccde4638177ae08f6aa91968c1ce82c4066204e61f984ece0cad182f15d4025bc87c748cb024363a3da284e98e369c3de73ede3f083e4f58af4f9830f8784ec79b0ec4e2d58958b8f8903e11628336ae33021b7bf68e69d372f45dc1df5c0eeb8f95eb4e85181b3de1fc26622e227f4ec27ab775ace7d0d0d830a9b3463ed04427c27cc98c2ccd7d7b5986768b7a4d0b7352dc7c0a6f7766cfaa6747cdaf2a1a24cb069227d36d356196fd972a6be6c5a6e0f79695b770637bba984e30c61dfcf1dc0fefb9f755b57879ec9db3308799bc34b9c799098548c3fa983498d3121f38feb1855b3a8ae038713873e6c4c5997767679b36fb4496da48440636da649885303fe0029091ca55d56a4b6e48b7c823dff5a94ad392fec0142ab572503eaa949b1cd14a6802d15dbceb07a4aa03af291e6210ecf5c717e615cb8a7edbeb12b0b97289777bcbf70373d640101f49e9d29370c26471dd8f291d3a96e237b1727e6c65c4d24c12ebcc86664259013e3a8c79ff01f11dd29232c79d45d4e16979fa68e6b98773586114a43d58c6500622991f8091d9de01c9889ef837d4845f01d4ec0ca8befeb1a214717fdca7f533a4a5671d35e4b95613c6f62d15a8dd9bdf19db6fe269538fd39bfabe886dbb7bab14f5a1bcc32d7aa47fcff2ae0ed0b055fa0d93b58e73c40a2cfb391d721877e0af73a01db0370e65f6fff70195f413b1ad5dedb1d5e6fd83b53e3583dad2c2af767aa14ce0d37d71cd2e27ec762aff4ab5b1613b721ed492cc92804c3622d48116498985cd0ee7410f697321d23a96aed46e794c8314af0b79cc37ebcfdd85894cd9acb01801bf1b30d1ee1b639bd8ea3397b3eca402c67106fb00c74bee74988170cbae1c2d524597408fe69e1a7d924e97717d9f467c0761bb6704c1279d8f1d7658c4fc96cd945cf6af6d6868b2394f572f0e9a3f9c7bec6a4958eb3f622cadd8df969d10443d80a45f2d5516da64a54c2cd93abebdf49364ca413a58327eea412dda39f40e5d1d7ee5920c01f04b059346239b3af271493435e72e887f6be04d16516a39886cdc5261ca4f23b45839ae117195c87008f7401000000000000000000000000bdadeee689db13e46f447710913c92e2ac1040c612a5f97946299011f06c6a3bbc746c8dae85e6f44b627dfd72c51d53e43e7121c3403883fae2a4a4b4dbc0fa40f476498e89a9b9e1116069835fb91a1b9995d1bddbf730134f8f8885ee9d4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d213d1bd5c50402ee93b8e64830192cac521c73dbe38452516dd5582cba7058a61039ccfef582e125e38a8732f6b06ea7c210a5525a5af23e5e202a22bf548ca2ad25aa54b89d001de766af0329d093fced0ce4d2630e371e8a35e9d2f3a5a2653204e6302634ed33abc8f0a9701c143196bffe30185a413b2423faa855e980f0217959d62ca1434357f664cf63930d3f63578b9e2b4794b4950e604a8fbcfbcd8020817dbce4db4b2e6d9caaae5d5bb47e328880c4fef3e745ed30637ea02dff5060a00ff68f60b9be828650cf7c3673f85ebcb5183f3a2c745f231127810736c45ac1b63281af6c42ec55f72f18bbfa48042082532e22bbd45b5ad6af6547bea20da0221a04e5ee97501eeee45845e897e3caa97c16268f524d7ddb825bd67c927692c030820e99918325fd78043a5d8088687a15834972f5e8bfa20fb75fa8605038e8a0317cdf947a7091857775bc0a4dd2f822c753e4b515e7e6ebef81460b8e26c04b30216cca3d30f213e46637061f457f96ccd7f4cb08f74d5fba6e6ef21e1eeb5c7da03243c9a0ce26317328815f3dae43cceaf3c2017f5d1e802a0db5821f8dc51c8fc8ec7f84435916b1dc5fd08d227519e0fcd89fb60cf9f46849cc12032ee95adafc111467125a301a83fbb8cb46023eaf7828a8aa5c5d5a1412cd7c652c6fe692cd09e4f43f5ab16ce12cc22eebdf69b99b8a27c059e73d7b2ddf8a941404bd1538fb921ca63f733f9f8a5a35704430f4fda37c077ead35af79b514fa6e405111593716d3cc5050367acb83044b3d3a0729d9911c4ab608202c23d3e01debaf404fb4da3a6195287f984a923a45bac88db8cba63e54dcaa764651e63a8361780875401a2095b12ea4e515e129f4783b1e456a7609f07e92a995f58f6201720e2dc797c7d82beb5b875239fa665653e15952d60d4acd293421aaf2b4a1ec6b834c298bb414a70893132309c52fed6c3586ab5bbec65d427397c37a8e7f3319d5c0acaa3168b57bf5789fc0aa288119c9f429164257c495a5c35c1261567130386eb572d2b889c4200650ea664e187f523c400fe5eceb6d7d5eb646bc77a67fdc01299878f1f25505010c6968d6fd0c86dbeabf28ddd4a768e5ae0dc4f8fed2f3f8aadced33c1028993517627ba94c611cacefd3f9d9667e891b4f4ef7551dbf9af8dd03ce5b270306f58eee9e9199a0c66f6aef0272437e112d1cd554cbd6ab94d8ddbcf55f06c5d2b7e415c9f78ee556255ccd05773af9c1270ec4252461a6a827ea5c5759684dad4cf565e66aad070a19cfbff4649d8d10d0e4ceb7e1a8b2c98f13e2f909d5c9ce9e38f908bf50e3271c0e8f70c325f722b79afa9f4a8fef4052e463b25e9fff11ca5544f2c877c961621c913333dd0488fd4bfbee69ec9380f9320844b0de8d0ee6a7d6a4a78caa4f552f8ed2cde1edd1e8bb6d1d463b872e59c829d8b3b788670525e4f752f411efc9affb8282829e2722adcb210d4df5edec82fcb53c5df62e353b3a6e868ac20f83a670149dae07ccf4a2c5a5b54070db937cdd421ec001bab947412106fbef8bde72175229b3468898cebcfeaa1e015374f14f661c85bf1c411944da997c28f390eabb37b5c2fc2cc75af623ad095feeed31eeb02d5db52e5b645a125ceea4576f63011646d1ccf116c6dc3ae31b817a9a13d65cc10c60fa7e7542b4f3c165cc39746aa330abeb3efdad278450f26878d68aa7074567c15bf8a3b3c8f2aac29f17d166947bf2a4df02f761e07a066399f4d0e9c638f234f9a0497a6ecdcf07a179f308e8e7f87ec487b2e5e56c4c3aba06b37bb2e2fe8ea127e8796c5916c96cfc9810cf564b9f0226706db57d6c0cb19ecb6220898a7ea7a3f59755f82432f9f433c6ffa2358c4ef38705a80ffaf540099dba17b4b365dd5c75c86d37465ecedf23035cb0ef6cdc2b1a2c3dbb88a43d6340ca150cddc0f58b3a5317e5e2f6ec39d42e4c33ab10760dbda5aab6a61eca933061200af8adae759b269047a7cded6bf829b9053887aca4423320ef57b2770b087444389a3fef8e08a4b3b6679bb58911eb2ba79104e22a40952e2a3d88adb08c9bd41b20e987819692b2466cc1751fd5518992ad042351ba5180390c03e266cd39d242fe0d55a8091287ceb08beea5f7281658541d7370411d5f0aa44d440ca4e05ee66df3f5c684565897f1bb64a733a7c7a160c4aa0755b4d86d2ad7e16ec7cafaf94fea8288c96e8f3442b3a2db8a2062a4565d543574d8aa9a4a73c1b5cd6b873f18af61f301e5ab1272f56191ebcf89201afd8a72ec564cf38bf1cb4651dc4b6c4f521591426c526c5d10819cc91e3a4f55e6ab30cff6c74a3dedbc8ef37cf82ef80515f42111bad84def5de32124c97638359c06bf6007614b62e2914708d7f15619a179a3bcac9c693f7245ab0e", "65636aac63ac", 0, -680068179, 0, "be4e02bb54df20a56342a1a152dfad4b8f039007df6a39e123af7bcb894a4b2f"], + ["030000807082c403015fc21b794ecfe157e69fa071d00ceeae76d152ee5c1eddafa15c8f0b7c84477800000000045252ac52ffffffff021e6f12010000000008516a00656aacac53878589050000000009ac6a656552006a5365aaaa1f1f2e4da2b40100000000000000001bf74f0100000000a3977f7a9ee550211c331af25cf6c9d88b0df25195061efc2cf9ccc7176061979ed3e1145efe38c6b7daca96642b17a4ba8c3fc91dc9ae8ab819153499926ddf00f85e4ea19754017bf9a3563ff2c42ae812a6617fad66fc336a965aaef4eea30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022ce1a3054e9031c7a7034f9b8cc9195656ed4f8622c110ae37c8167aecff331f610e7c1e31058026450f4cf7c0de2f7ecef74231ce5c631b5b955e2803119f5259f7570c4d951360d462795cbd3101fdf5491d8e1c12523fa26707624b84849dc806f43f22b6f5ae701fd9ff953f6a3e75589fec532444c2b169f09a1ff7e4a0311c9ca516cdd73533846679751af76278f33e228cce975d17a2e22463c3db3dc031400d11266c7065b8f13a864d9ebf84a140fb3329b3f6ec50cf7cd86e50940500a05eb280a9ab1d7a41e3b9a109b21c675183e94bf34520a2d05cbd928146516079e27859a6b81dea6e01576d4b3c5ef1abc4cb0a16a85371335d7da68e5a2058d021042833d8e566771c0acb6492cc8c18410536776f7cfd7070b7a4fca9ee2dc8f0229a02f0420e5a91230f6873c45778bd3084639daa2c8374ae686d5b405dc589b0329ff8c1ab6210d5e7d41f4124bffe0a9ba03d6867503b2f1eeff399aac66f7b30226c41284f4db45b4e763a5e2bbd70d532267f17a6b6aea91effec1003df2088f031ba8044528d94f331dbb3905aab7de38fe2f4c0e4f9d78cc9b255b25600375710329ea6587e47fcc8a184cbb406e9e407238150ccc7f7575c2df7ca87dbffe7301a3066f2e4b27e0a8b29827e8349f93b941ff39cfe9a56f3317c51ede5400cbe8ae0c78fe0e3b9e3601f7d146c393d79c9ada051226c39033037754bf38b5791ffa2946ccc1f8087ed880776016124626e59d444ca5f4724e62b9c61bfd8361907d09bea172d6714f05fc9680f02be81e6e6b557358ca37aad9a73a9fe1c35f6756ad7d1aca140c11ba269da8214c6337b92ce7bff7d2a4f8b778f895231c931fc563dbc2c4d73f8775d692f96accc751a97ed08467c9033cced12a8705353523253568ee16e504b7cb826d131b077778da75a771e8483256143213dcfab17f4a1c707c9d1822b02243f417fbf090b4cb28775c74c45a55b6efef9309fccf34ac5f2b18021d0948be3a88f17d679043fb7cd5e86bb6226777639ae2e036dc8d45da463485ecd4f4e90d5ec184c7be4bc9179022b8d3ab2a74ea374efbdb4809e9018932e95f9aefe94fe675a45c18681a6e498804ca9740cc418724b73d7455c7f86d12326d4d817a61d74074841f63fb946c54b2be31d300b2fe3d7ee6589a618c41201d27359ae3f64782b33c912c7e6c8541a41ae33598ceef5cb16eb416a4dcc91655931b41f29693378e2b43dc95253ac20c89ca0294bfa199cdfc6c75679632e41a0b5c40a407ed4ba421986b46967d8d3bc99cf7a90557b790baa370bdd1beb55a2c69f150139d5cdec49a6e13e81fdd0890b6714523264e9904c8363570cbf809298fbbd48da7caedd9f6e47c0293eb03c8f6d22f512e1a2fe120ea9c99370d16929691da371b85a30b89dab5acb1492eaa5b1e37cf3a83e05d637f324c5c5d8b75a43f27b2c9277b4eff4211df29b5dfe72f1ee18e24d7cadf5379d4beecab1f720850e23a9f8c898e2c5d7ba8d53f243bb216c62e95b3b2918d75d7709063d274cb3107ac461781692be642359aa0a43f02d37c80f902a10c003a9c73bfeafcdcec5375fe37c596c4ecb83384aa6d2369123d582b1775bea90ffef9b727743fe6fcb8051e735ce6e122171870382fc68830c77df4a3ec0649b63d5ada34c7e870ae466b4cc03d95bfde7097335bc1784257b4da932e6f7de25e437e5eb0b5e5d50a66e229d4a3525bb0ae4548320ba5edff02c991ec35447b43df41cc147c766fd04c89684026c7ef52161895be8f4ffefc4b9edc0b8d5538a0b8304325971842be04a882a4f8f51e8b1bde24c259048c3541ca9dafc28b51e1166a26b526c29bc89f63b1a4d4b32522fe48055f210ca6ae57cf6308e07a5807df4048316f9f09aab505c144bc87455dbcf812568432032504a8d22005910d2768b28fde4994b75141ffc26ecbb050c40a963e27ead703d76ff94b9accf2804bceb5b0bd660e4ba058fc16f7883bae97433d408fffb2d4c7b753a0ced96c03ed7248d4955280b67eec8aa4ccaeee088072afdd0b40d36da972fd97c257a288f9becb8b9728862e2ab52f9c9acc8cb883766cbd14193e285b36b307d28f3536fe7d936dce89ceb94f643f2d523a28ba4a1627790e81c609064d154e6c9f094b3f0bed2fb9bb1ce07b874c622b775f39ce4e868dcba2234c8f15ae0449254dd3b3ecb70d6ecd7b0d83e0fd48b9d5fd13d1a1e6a625f804bdcf9474571730c921fd3a80aad82913f3f7ecf9ffdb4e68edc7a1be3bab61cf00a7c911a16d0b314a0833c4057ca1ecdf83afbf059b60de90e4dbeaebd7c1ddf0c1e939ebf30e879227de94831729ba134c7bae26cf9e895c3849f5c1a442900cc80eb4d8f77d2a8bf7aac5f00a34ad40fc7d3609af72e0a7583d7008", "51", 0, 50196424, 1537743641, "a197a01d15959777a04ccbe19bb0c4e4514aa85953302bc6260796c644bc1f20"], + ["030000807082c40304ab54234e5e4f44ad5bd2a378336add9d7ef3f0d927c4629f43e47c9d7092fe810000000000ffffffff51f4d94205f10b090cbe85e477506dc7fda4143f448a5544c7ab861ced7bf7b30300000009526363526a63ac6a5146de706410e3df0371c5272e6b31cb80ed7f2b6445f6cb51b04c7b51974de9cff7270a3702000000066a5253655300ffffffffc348ceb123a86b8b59eb4bf8229108266f1f28789bb4153a5f350313f6d0017f01000000075151636365ac52ffffffff0319e4740300000000005ee95e03000000000363656532028b000000000004ac5100ac3b2add42d09b9f4e00", "00520000ac635152", 2, -1843389684, 0, "122f2ecf230b7ba98b0a5b355a71161d24f45be74faf3da10cd41af1627dfe95"], + ["2ee64a7d01050478e40494e1e52b5696da75f0c9aa3f270a9b6e5ed73377e789e4f86baac901000000096a52656a63636a0065919eea410198dea8030000000004536aac000000000003000000000000000097bd2c000000000033fda610b9791949ec1778a3d551313b707878fe29e9ca410f8b770f2127cbffd8342af1e688242c645af676263ba2d2874760c3c7bd13262fc0d146f2bf69b7138080231b7378c06515dc14bd030f46b757d7a9383636fd0dd23bb27627736500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000687202e963386baa88ac03a677baec0db350f2d155cdb8aa3f58a24d6db181c39fca239e07e8125346c50572f7a6035af883d1d99a422727691300f5edc1b4f63f9cfc26cf079159bd0d2fdb6c08170c39e652685e3eb64cd24ec15eaccb5ff2899a23c62161ec6c5d1abb14248370361db56abe24acd66252ae067a86c0148803267625fac571d1f52fe264440f09635954b0b44ecc7c6e8c66bcf11689396674031eb5dd59dfaca3f20c8afd6d4b867937cf7442cb61c811330031c23f9b79b7dd0a01f2acc4fc2eddded43521f3e0eeb9d227b8445ce357bdabf2f1a61a4e2fbf8b9a53bba457f21fd7580a237a7b61c4bf649be4addc5f3139f2c8fe5efc18ff9b0204b5411377aeda597f390a0b06ca27f37e572dc52f0bca98acaf6a1c39d126e8032d44a6f0ff9687abcea963bb4ddc6ecc8af1de0338ac898b822478bed2fff236022ab5e043f2012f13c8149fd5b90ff8eaaeb5ce0b6a90319378756c580d913a4b020d59090b4c21694488579d57eb467b03547757b2478a5d44af3c49080f9929a1021aadf263e66dffeb29978100020f26a2d70bfed549ed555ebb92735dce88d1c84349ed72eac23a21ced3a3012e4ec6a8aa6dfc13ac6fcad0619ad1c1820c3be433250d665199acdf930b8781e65880d826a308882734c128373327f44c2c77cd094bd0d035b668fd6b66d17b52e214b3bcdef5e81b1ef2ae3e4220872c68ce48252d352f9587de087f66691d2b2e985287063664c1fe1020b699114e9129eaadc59dc0e2b0b47e6b0cf9863954898dbe5a6b59d3c15a5b5e2f71c627e1e1975c924b82dcffa1fd373c949194bd52b747221fdca694056064a2ab004acd49e1122eb5be8d8e7962a6aaf821eb5da129ef03b72d9bba42c545785f042b7bceb14497e3e9c0c84e81dbcf6f1a0843bd4968f602e4d8fa66025e9d842e612ad072187064e25b3187f39ebb12c2144177c35fce7b4fdf20545125626ea11213faca6a42813af20b1d733d601c98fada1356a7df7283f88c6e7f1b9b80ea9654c01da2c1763dc35ee98aef74aa113f77eb2d5d31f578a9ec04539a9f6355b8fc71ca3734d573087623de796a4823838586ce917f36724df7e9cd4dedc0d7454fff69f49e114d903e396f13e56b8eec7a1bb1e84c34f20c4ac7bd09136950aa497fc386d37fd5447cc0febc8e308024b6ced8ef19ba5181fba02262d59b1f172b49a345d4200916edcba0bbbe651ced3062b62a2f231bbd3796779d049899df113d701cd297ebeb707ffc559d71be5d421f5372e717652c5c80718d58a6e2bb1b92103bf3b3e8a5947cc71d3a75f98f14f90fcfc6a98ddf3407fc7275704066161ea5e4655ff7c0499f2b0c11a97f37a5e1e419468fde5fb328f62798476504e903845eb831b33210733e23a7f87ac8bbad6f5250c9f3dda9f773e9a9098941b56d0845abbbe4e4eee3857f2e3d38d14fab88d969430e5f1a08763b88112823ddfc5ec5f9e89a6ed0444ab26976e546a8c627daf317b94fd58d28a9862a93b8bdd60f67a33bd62b555e7117a0226634109a425b33ab98782a1f05c47bebee6d7d32a493d36ed111a4c434f892660fd00319f01e583ff11cb88acd956d4db1f4587753c880387d87afe2348f883e4da40b7ac6399bdc0ba59b529fcc54f2358182c4c39cf8a2d5325d4b48fd49b8411c906ccb3225711a20c026154e129164f4f13d56eb2b663519e88fb77b9e73962a888d34fb489bafd7aea76b4a6915025944a065f76674f0b094f7832b0a130b72ef9e81cdf46c2de8416e959c3fa44000975e26355b6732dd4e528788bd6de7804bb979dfab44aa03c8d4b8fa8e6bb565c30710510ba860ee8f1fb5cd50923c5f72998cea30b35fe7c9cd57a8e57060aa64dcc495c0ee38d982db7f3846d76317f65c7f1cd2e2548938de25fdf1e65407d21e40a91e4ec15abdf613327449211ff4638cd02eb3e73323b44349fde5d72b6f399184049f6d021bed73fe9c20a5869e67280ddb730642a37b8d92eda3453c47fdbd78576b5df180cea27250c241872081727ef5ad4b1139685c55585543c27808e4b4f3d9f2e7d0cd3df3cfe12f6c1427984e4d4ab5c411f0931e52ece35edb673e78644b393e3e4420708c2794e02878bdf07b5a3a233f8e9f62ca87aeca4d420ff6ce08c831e64557cd5a4b9c210dc0f074d56f69e416ad03667f9bbb4fee262af1eb3f547b564f5716b113796b16270a4eaa9cfbc93beb26d36144bfbee1f89f86ea911d12846516de976d3536c935420fcc4eb2d419000000000000000000000000007d693a46e7fd8f8f9b267f191ba50099f67127afe88002b4d5819549c9625ffaa8a02b7e90a26f780effdf20406fc6d5757cd168aadcc14dc2850d8875c5e9122a4bcdb0a34646c8541d97843464df0cc45fa25e262ad28eaf033811535acc4b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018b36f0ee555e7c6ecdafb6199086cd9c272d3fbd33e146c69e9590232ac797baf60fc796145c7532d114e891b0bef298c722f57ed628fa83f19b8423426ffbf541a6233fb11e95dfb540c2ebb0ddb7f6d02bf14418e4220bd585cfd0adc8922980aab83c41928af00f8ecee3f1a6935f7e08d8530db2996b69fa6431583b2f403032aa45856aae970392a3d7ee73d08ad165d1cad9137f0511fa14ca34498fd070222567f3323f113be924e0adecf29e239deacd76b90ae49e3b48a2b202620e1e60a03dcdb34e4c6ea23b2aaa04fdd1263d4a562ce7ad4281d2f06f170e6f207aa59e70cd49d1160337d47a4590e7df27eeaa791ae68b34c4101e8d13cb895fec96a02174ad24838e437613e0da69553a5a9ee4d015f6aabc90ebebff723bbb31ee3200317f92103fc41110fb82043d2e126e3470fd13facd976f3a63a4e797313fc682b02187f9bbe7a74a772b4758b22363e9c39fa374bbc0a686cfb8679083d1a580f310210395ef39fb13a1d060deb4aff5bb3e4bbfd8eca738f870ec1545e026fbdfa0d030e048b470fb45e9b6755bf54b45c9ef715f60f49379453999854f0986fb5f8fbaea85957a30611c4bdc75f908b22bf7a19a077c0b04b7248b85e7336666ac3beff53fdc301230c567934bca671e43ff0823107721c7be3c06932b55a4601515b474c14f0f58e5913848b259e8fbcc1cf25d11136bbff0964e6d256ba0b80fd1f76fde5a81fd153a8f927b973a6d19f1853b0d4b52b18e486a1260bff96f49980201b5be92e2987213bd3c9913a796f2e8f55efc53b23440eb49f556148d1b4e73e574dfd24e73d5e60fb51b5b739ac7ec101980e7044272b15b4b902b9d32bdaa1a633c3f71180442a1c75ccf8f4a7470107c73b11cac9fe985ce9cc3e53c764dcee95a9b2ca7a615e936b1a66558842300bae139660c85f20ec910c90f771cfeb5711f6eb1cf9d69ea93758b042933e7abb2da9fd8ee4b8da2b16eb89f8d0d8516ff3e683e1ae95cf8950776e8f301d9fe54a99917eed8c1a8afdbfa1ef563cb1db5f28cd80ee4fda4cecfc6ea4349a9a837a3914aba23afc5bc6be0c6cb2d22fe4e1993f095360180914684b6e800a0fcd56ad5d1306e5b8cb2e1b1d8b5eaa1c1702557792af254a30fbbf801cc16151cd22717d8e738e4e1c5dd90e06de5322e4527cf06b5bd7978ff08cbec1ac1a91a798254af353d3250b9e69124ce859c8ffc50f0e86fa0b8349313cb1ebd7ba799cd00a104f7f23ee7988a4aa2f8b2449075f0d1c1571caa43e51edd14a5ba57bb3d2e35ab3b59de3ebdbc3c65787cd65108d2a532a2be10aa1d6df1dcb38108beba8f7dc36171eb253ec2af247832996542afa4df943e4eb64971fa3f275cb7a6196d4a077fb3d7007af91f04610e78a3fa298a971759a97b4eb57a219cc11f0b251f438c7792eb6b3915380824131586af7ea0b08785d279ef315b9723f457c95f187b96f303b54cadee520121333433023c3a414bdd26127d92d777cbfb2696f02d58c987607635db2303732409210b043554b90f378b1cee9fe2fac944aa3727ff89535558acb319e72b9725562e7a748f10d885ddfcc959d63c03fc78f8da060247d17580892278b9c2d88de754634c83bb1ae08b53fd42300e533c8f8d16a21e3120ba40cafb891e72bf52367f7393ef946f7a1fbd634d5d90f22ec7c34a2ee2a34116b2877a5f4f12a8e010dec4ab757ab1579d8449edaa4b5fc715305ef8a49f2f3f97d86d1d0784d4e8a1cd0baca45c27515e23ae9270bc96727c087cf745399d3f136d14ae15403acf9ad06065203f074d7a8c034d2e5041d717488eee3cfd036fd528c8f279061e2a186f13a28713e9d03a44eca67127e4fa0db7414c15cf012b8d2fc8d3e858c92286308007ebf18290a1e934af2027336626b677084d45f0ef0d2c256cac333b79fee0d7d74b704f66075cbc9bb1c111af9aca8e8d723c32dc2729e627c125048941ff73195636203d4542404c81998216053eb69521d0f47a54d4295be864d332ddb16910cb869f06f7abeb6fcbd37d5103a14f179b90babc5a17401ecad777b7923c743d4524201642342751c270d46eaf3d86c72d89450f91817c139d5794ca9c379fab0f06fca1b82eb40b8614d9e9d65ce071327ed556d26cb6a7b87f1b0fa83754a371f6c17374d75ecbb03831b6cc103032bd684dbd55ee5a15d78d556be3e5519ee5b377709711b62231130404d28ee2b273fb8a4149a448b9110591e5d9ddaccf10a2a6b777c39593d05f7c4f3e72270402bc30100000000000000000000000037709086284432455e15fe0afed42e2e16c096569b396bbec793fe757bdb83e3f40b3786ab6d1462ab0fce01248012df8adef08e1a411b4efecb4feb0800198cb512afd5827cd2221e020cce3573366befa62c9c560b13f44453e18c285326750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075fa177b5849b1002b1535a920e1d0c28e30f111dd5f7c2f446c336eae6f47857e49b3e62ef06645348840c7ab443956e93b5dfc8d489c82e86aa173c3259eabf9dcd2ebc4a6958ca04c91c17877e3d397c906dd906f2730624fac16d4d30a09273ddf3c26e88f66c826b611a9853d6fcae0550ff3acaddf24ba8c627f81c92c021f56f32d3c053ad88e2d9a8c8e86d8b48a51bb50f042e930ad5cd4588102f34a021e6203562756f23c11be32be6494d60985ecea731375033d982709814fe1eb150a06ed7290c5fe731fc6930947fa531f3794046b5cc8985a3b458d8d3da2bfe968eb29f3782d57817c525e948b5beeebc0bbc477c2bd65e93a8b9cf0ed06c96aee030d0cd552c6564e9753a9b76c8a50c57dcb062d6598529893d60226f5942ca8c903061f6fccf63c8385957dc9ff29d7437b0e2bdcd46b150ea51e3d7892bc8a335a0221e72923add45417e39c41dd186629a57f75d7149c6c41d246772f475826d9fe030103d13bdece9966fad4366e98bba56204c5055e3bcb8fea31ee27bd2db5f2a3031a51db2567f640ac3ccc15f53f7a35999827350d28caef40a635f5132b97cbc3b42e1c56e415f03bf691bc0ee5d026a696d8203a1eb92cdf09557e613ab81cf59e202e6b61b65d2295606de67a983e41aa760f69a7010f35573bb88e4526edc41f2ef6a7f95bda7afd75217205311d3969c38d8ae7c888a34449cbd3be4aece1d7b5e7b4246df9c6d0bdbcf9f7330723e35e08d0395d1da2eb3f4efea7f0b2594616ec9d6df6917c956a2a742f2f03b184889151444c9b6e4d7110a06ee1eca37c00eb45e529aab55588a38b661864b0f33ccedab569fdf885654b3b88dc9bee70e414ffe984b681de2536de93c65105532aaac1e61ec541624c8739b4ef376c4c79aeef69b53af75e318a52973e380f053d243ab9e2c9dd19b3ad93a86ea9d01f3ed0296b0e3de46b0101302593e123e70c0f2f9a782778d95a36e9a20d942da0536ecf52535cd1a7be7bd26e3b6e5e32e40b5fc7d4b05204fe09e3fcc4b8b558f277ea46166ca4806a52b94328356e866c1b87d5f8549d85003135cec093a14c4738d751e834c1f026b25394dda57b15c62651d9e94c00dc8a02e0d5f5ddc8708dda62a068b460599f7c025c1a32722bfb6a4a6b511360d1f91686977286c8afa211bb672fd848f8361a62a28c68568c88b2199e282b638815ac72b28e14141fe6707a7a41dc674047e2eb05be18326d28d4a68bc1a3c5f2de6b63fedaac84568116e507c55c14a84d4fc9c2afaabe16298012e5ffc2be2732eb64b7797272ee6e692add780512d0f1d1c0c77189e1eb6b357c4ab7d6e8b382f8d00bf77f5b63e8e9c166a40a2f238124d99cb4d71d471bbc5b7567265ea53e0bd21093fb223256ba12624b629947062b28327389781a6c338ddc7c2b80e2254b5e3e083de22f1060deffca04527ccfc2826b572c477ba44af144df336cd50a3bbd9940761187d95a82ac678cff97faa5fe6dc5a34a9d2952218086352d858bc28eb6cbe7f65c62ca9b6c4bc5fe1d17875e099b556a3eecfea25178c59b92298b32f3e52191fb4cfb500e96d992c726f9c6a1d91daace0475df8321a5fefe5f799b2c18baf44880a7c002340d23e0556fdeb9fff0c845f035f936728525f77fb3fbabeadfce3a2a2de6180a5940d902e955f081ed3ebe6ae14697e94f028cf5a410cd64cc75a20a79af43f98066f495f1379d5f49fe40c31f6f6c93be411d3af965f983171a5f3cb145dfd424d3e0cb60f7cbc92cd5c417a5adbce371dff06ea5afcd2b548b9b9c2c65a3298003d53fe14cafc140a208495876c191b8bb277c6175ce8c04ffa7c6f58e98e198449c60276cadfa579bdac108fe4adae4487345e220055a612da046ece40116de09ccd52944b74f167c5a6ad586d1fe260812a6fa30181322707ec66fc9dbeebed20226722dd6586c6ee6bb0c5e609e6830f94b75220cd8115b33871622c0ffbce57301edc4884cfcb356543ced8206468c4e2e408db43b8504b3a8f3da764b2edd9698fe30c5f928a22cb4a69c25c8957074a8609bd800210f8004ce0e3071f7463092743e08c2623252d2bee62edbc24956abdc4df01c8a7e8438df887d4c62aa2704d8436284c79b5b01710ef62f00ad92e62f83bc16be8e7e98f22a4a0f468447073c7b8716f1447211cd55972081224e6484a60a62e97517b59f14e6bd5939082c07b1d96cadb94950c016a4909598373822ae5d04062a831ddf0b04b595560c9a45451cbae9cf936509de9ebb98fa8df20b29a869282deb32938413be465318a30fc52534e425feff8e697f0c361056bee1805d0e1aca57fe8610211c8641cbeaf83449bb60e48b69de79aeccbfed93c4de452091ef8c1a505519c31b62b8a14da1ff1868ce377e0c", "", 0, -997941885, 1537743641, "e574656e29147db3b8ae2e3798fe6b740ffdbd6f62413e3f4501f74ce474ce10"], + ["9fe0827e017212216323d5e4306fc7e041b1434355df9500a6c1fa9023b93f98bd16b350840100000000200195a6042008b90000000000025253044b7a0100000000096a0065526551635152fbc6250400000000026365c736170200000000026363000000000100000000000000001e5c3c0500000000f35de8d216f549f8dea13e5064869f0df0623dcab56df84c88f45f0bebc9186371ed50424d5c58c90e6e547aae11b049fe3ff135c166c055d4ad5361828c27f4018d2c174bc33a6414f570b107b5dfce46e61d31160d811e42c3bdfa9372326f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fbcd2b4a1492458ec8f0acc471965a19269a9c8965a578e7709e4516fd571e713ed115e9e405ea4e0d5c2d93564f976c0f81db808c764d59ad1edbc9b1f76c2cb81cb5f3c599b0a1983d7c6009296a465be948308e6569af3bb5d53903ee5ad2bc6012455f2698a811513b8558ccd9b43de4773d49a76da1c9d76dcecf95783030227a837079731d1172664c9991b35dbc27590b6d98219c0d95203e2a11e5558022d49f31a6c47ceca674fe57b646ce1aa25bc559152436f10d656a8adfb6892bf0a05d029085a0d34b59531c2b1ceae3dbc4bd0607af66162f14466628764b79033a4a3fcf94d733e5ae5448d2a00d478686fcfe1d424e9372e1c0af41bf663567702122286151000daacdf602d196e324afc0457742732a79d935e5339abd8efec290314d823e0d2bbf37792612d936721d384f0003e66d8531fabbeb407772802a4d90313c2483992ab4ee55f50dc6f3ca677605e416c6fdf780e88853800bb32af3f4a0211f076a3af54fcbeb836303dc6c7a21c7f3f42da9d64f38d202b735f2221b667021e835e8653b85e7bc4e5a5c9890356f9aea10a9a488e9f266cdce4adbc77da42901d05e876bae826370dba00fe69400158507e800995d6e379b90b12582e5af744d4d01029d083c88d783ff2b44f88487132b74bf11b537468f578d0fbc7499517f449c9177d41d3a0e1f2bcd64632d4ba58c4f0342c36a176e310a3ad42a6bcc8adae5fa443c4f17e7c8520b808ec33bd919a6b1b4ba6cd2b73b2580ddd7ce7ae74a48184566866494f2044649b85e8cf82c63596f51401eedfd902e22ad73a4ec522f66e808890d6f00fbe62689f4ae6fe658ac0a3ebd5d274fe1cf906cc96c20e723d857f1dbfa35a8a09c008b011930af360baffffaaccdc4f1d1fb3a87f56ab7f496901f5e0decaa068664dfc7383b294b96740df6cfa5070fb16a150515d59c0b0f4d805f69a5ac5e7c65a19ce9f5db5dd779fd343431c5ae61f01229ee6e5747522b35e9ac2a330b73ad0ba30ed22e8acca316aa0f5a5b2b865616020cd91a031f4376cb6ba887ccc4dc47c01ed11842c707f1f3c4997c11c03c42c89e625e146499722034c93a489914298475e26b26f1cbe418bc809a531fa6d613354ebc2b35123a98c36042d10cad457729b88503d51738d5724c98301a80f1f7ac6598194a91dc6fc87d52841afbe524a7a0dfd33f2164744ae847dc05db51d87fb6c51085181210c0cc6dc98e6af4bd22387763f139f04ca10dc37d007a31a0974b77830d4c6b923c493c4bb17177ecc17f137bde60f19c2c7f0d220f85f1c8aa14707e9a8872e9e0dc8d5df0f266b7ed3d1a250f4fb48d242571b7467cd37acc0849de39beace1d85daefd1817444c38d903c2559a9ef8c529ebaf949f3ddc2d562fdd5d5c93985d75096139c9c1ac732b45dfc213bb99a3cbf543ec02456d1d5e27bba2531ae9ca72c35b5c3114a1bc6410aebdf2176827099a37246d1b206db5064d8efc5334ba845f570e1e29565c04ae01f572cc6cc6d7b48d89e9fd60d58691d6c46f6ce6a4b1565f8bc65a5994f82c44c538bdd09eb78518b69caa5f468bf7bfea939e5030941896cd59888c0c20826eefef19c08a32419ef56a9a94bc223f54444113f5cc7bb17b1cc4b1f3e9430d65c66b4dbd9b57be9eceddf182c17dfb3c39554951c8747a87b8ba315a858d6d85e5ec0298cb53c52e83ac89b8750c86863650a9e506bb8c11f49ea38acedc16d41cfbdef9d0853492f3de8e9634e711f3ea36e292d7ed78f91eb696e162012701569a627d138a232a43ed7e3b0884c8d67baee527b4228aa3daa80db26bc543391468e3dc0820eee85bae5a756123420572e773b27c6cf261e4a7424e71a7e9a803f3143b2503a7f7fdb6f96c650a55a644bdaa4820a5bcee330b2055887aa5923424935812cd8a77f3f6f0d1cfc052d524a3e2764958f242d840610f69b0363cb458be8962f20391a63aa460aa9ff75e81e066127b18cfe433d9f93109f9bd020e70ff5bcb22187a02fa4eb2734339ffecd83e6ce93acbd5c6ac35f48f1247dcbf0ca40251f23702445041aae15ed662d6bbb3b6431229f2bc869fcef4471b2eb7da8b6e80abdcb83ae8e9ba4c894a605e31ea72586270734beb28f1d7ab1f1c32e6a796f1feb1f9d7278ef1f7c54835beb3e93766bafad5efc4c398dec887c0978376a38e06fa94649408a1eb1f758025efe04b2f3c6a7b65975fa7a226cdb8c41db3b7116341961eb69c039820dd981b76d8e7af4b2f0a08c60f3febfe7e9e91e15aab095ec683e6b90653acbe5322fac44c92b2c61c29e6631dcf894c6d4c0f127fa2ef0ab2fcf4f5e49812276ac7762304e9b24f0684a89cacf35fe2e2add4f2e6914966d12ed6f4af438ba53861eb29519835ab716f6ce5cb6ba0706", "515365526552", 0, 669396948, 0, "8c8e3725f70a8b5d708be4e5925075393477ab8da53ac4bb8d934772b5d39ca9"], + ["030000807082c403045c512994979939d10fd1dc9c5638f679fce1b1cf850d2ae58c50d87b01f0df470100000005006552635143f754c7d897c0d445da2d941ec13bb95c1b11bceabaee998e6ba83bd5c21255d0bfb5c2000000000752536565006a6a46404bb420c22f740117d6ba5d9d75b79c6d0718c40fe8b5e791adf03f1f5136dcfe3f8e010000000551ac6a00534e9692b127d3b856c3200ec4a7254ffd0503c6c4436ddb8f258577a9ca421b60caba302f020000000951526a655253636563ffffffff042739150300000000026553e0e48f050000000000106ae40500000000046353636558e79b0400000000046a6aac538de2304c0000000003e98e8f010000000000000000000000009018b8834686cb95b390767e0dbfd6cb5de002682979d77d84a91afa0ed42c57a4dc755bd03e9d58eb555a5dcc83f0a028479c14d883f7d59a3900a4c3d115925d0dbab003be9aae530e3c08e4492fe42d3b2c9c2508d3ffc4fca46cf58c39f90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000069486805d24cb7029a35db80b8207d4702a1351ef743ab88b88356506c097ee7f606a6155c38e395c7d0a9f0895763942509fe5b7c9a8901e4349a18bdf7eab2d75284d463b2e6412d0097e18fe0d81724529fda8db119426bf57cf6a8cf02c46b8e4c208bbb45eb4bc772495a8953679b6abbdd445887bc9793967537ed7979022444cd18f72e3715c08a2b238b26d653cf71e7ff3cc69517138d72d3fe96223503007116d6b35ee769b94f6103f5a956eac926b67e904e3d6cc915e254c97e395b0b0707b26831a742766749aff231a08dd8515828a20fb3bba0e6877b93da6dfbb685b79fc166e4d2a9fc856480e960c8bb9027865bc270bfb883d74c60e07da3c6021e5c2b43264e2d3e0396fcf7b2f3beb6a4983edf3c33ecf422802ccabef50e5302097d0da5f52513d5f6185c8169d45d1d96730107005dd9fa7d925fc6a29dd58a03286f683fc889ac696114046582f6dff5237ab82b1907032a0ddbc1dbacc54831020ec7a021588d33e5fc9541f913a3f3e19f4f70b03d6658ceb07358cecb9f720c0220eb11bd4b082780837bc210d1d4518ba3267d16ecdc7cd11781ba913341a4bcfa3b8389711c21e2a3e00e98799b7426dcaf8627dfc4b6fef131f2d69906ab75584e574018d4ce2e94ecac58453d012f55fb2466d0dfcf486b356a1cd44784383b559b9fecc26b809d264f83f5e8ffe86521cb76866e802d675a85b538f8936412c9c6731a7367c85d867178b7effb4da71cf284c0a9d0fbee6457fa2cc4e9d91844231e819f21887c66f1f40016e337a116623bd7583e2492009daa24c4439c343a6f53e393538cd6668a4a7ccc02c83eb7baadcf62fa2a3dcc52ad2581682125f960eb99a3dd2b3d498f66f2d6b35f66ec00265632f23d802985c31887884dbe65db2bf5f09017eb36206c7f2b762661c205e7f65616c9019b9a335908452e24599cc351d695b07ff3580edc8104294caab068cb2d2ac5cf995d4eaecb394ba194ab0a1b19f19d1475539f9318447036c604bd6ab1a0cc7f6ccde93e084ee4fc6fba5c72f5cfa3ec729ea0a71bd3981124a4123d8764ab1c44b51a9550e04fad17efc8c511ed0fae1b1dbce1b0008c5d634adc245e5e30bec00c47e4bbe726d672b34c25b1bb5c2d060c7951cbe9d553da6261f45557d3d508564d9cd5432dd25bf735a2ee0e86c2bcf4d1cea6fc50e3c5d9695f1fd8dca400760e3b650460f34bc4ac4f14061f0d6c35f5f6a7cb3718399c7e89c2fbe03e64b75b4808fc0b7fe7bf3d2063dee8ca73cb1374265d65d7ab51700a79937fb07016fd93ec747d281044738995205ea36ff7fddf0e0768d0f507aeaa4ca560d794bb6775553d8d22897e5b33165ca3a92baafe23f017d39179f9363d1327576a7dca0f6682f19c6309023a0a63dad297c3fcdae485392ac293b0dc27a37d3d75650d28723c236e2534c67326a2b75acff8abb55bdce2145c7c5e5707f63a1aafd8e65c6f73724256ed628b86c5f3ccea3d45255cd7a76835b4a01206ecfcab793c136954041b85fdd9321228b865770fa614e193768e8e0c66738b7f8c98ff077d35496d9c5dffafe6ecfc144846c5a489f2d0722ce402015b04de2e532e2d6e7621a0fe8c1cedcbf70c391ee71c9c1c2017d371617a20a897f4f83146c2a5ec173346b18f9ccfff7a4677d0b5b0cd728937bb5558a634e8acbf66f7f6535038603126079032ccfb8494dfa7202338b88b5fc3e7d5954fa6c1586e554093b0ffa37e84e24c875cac01da5557972d83270a77d1fb70e61b4b304864f8916d9405be5c13e0e6446fb1d0692fbac715a9886467608b4d9b5a57b63910faea965a00d3c509e06a163e25c47e030310134d346edcaf488820ab7ce2cc91e1b98fda3f8b19cab5c0a1e35f73d38de6ba0da44c707a2baa246d649ef207da93c9f8bf8a2177afb03df050ad07dc14a2478c43d1a32f15fd0343e0110f6ef910985e86b55461887b7b38991d75b05e7007e190672a3ebfb5a3ad00eeee125d2601248e1193d41cbe9192358548bda36e1d34e3ed937fa72f9946abf1518b185d62798e3fdf0be6415a59c21aea5f95653adc36494f1c40b79f4f76777ab6d1ac853c1f60ea48e81f08fcc865f4a7af5dda24ce1422ed2c5473b14b75e5fdaf7925487a514923432fc5816bb57caf32f33e8902187d884c467e1f6f5a975452b01a642eb08bc9b917fca116b3b27549648a99f490673336f88fb3afd7eca3dea98814b1a8187da2a8d8d66396f56bb520f6a222953be35b38b9f77d2e5c000000000000000086623e0100000000bc775afe1a3d81345a34efcb80070910e625512bc654fa9dc79959a0cfb2d2948ab57ff848c066a3399982da25ea15879816e802fbb3cf1fe8c15891c48358db03a944dd855656eb4414ae984a88f6011440f8adafa4911c480fb8ef445b25b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d305f7c92b89fe49a8145b4fe1d49a7bf6a7c6799f5d6153485ff8d3b511211a960919ae13fcdf214dd572fc54c4d0e37146f4a141b34ca4730321d9097a798fdcc2f394f03a3287d2a521025f0e7ee2b129f2cdb20c4682407cc5a4315392569cf6b1adbfdc4e14fe89a886a1098c849b23ea4ce4e1e3dc0c0ed8259bf93ee020a994ec3c64790a298f7a3c3d62079dabf0588caed98e413b63ba21263fd1c6b032a859f29d2960af8d65db52daf33937a6235a72ee71e234dfffebdd1c81ef3f40b00246664ddbf4519067eb80601a63826decffed533350dcacc940e0b966eedcd8b552bb2a127af7c2115bd7cbc3e8cd53ec87c465ec1a1620f11e6de606ce7820330120a33c036a42edbac0628ba625d36734733e654bba5f02cfefa0c85658ab2030f7795cd7cff5009a134de873c6cfe7ecda3a14340723c7f56985e2edeb5195702276dfd55b238f578392581b7cdb1a22724d352e7badcc313d94bc7dba08e58bd021576d644471d1e7cb914fae84f5ff890bcc5fca12fb55b83922ee2a36c088c6b02110dd79bc3c439ddc1483e676e51020c0ecec783489c0ac3da6902239c830807bddf08b65cf379382c04450c33c33e57c28edd1c7c8431d4e431c4c1dffc4095992638c41ee00b42d81579973abfa3f403a353ba084783ca9687a0e6ef55d39703ffff307383afc4d0e9634c491323c194d98f5c221128faa44645e9194462f7d05ab538a4880c5f0784c2eb9e1a87c59ba5ab4a2d6b67691805d08bb5f41cc6fe14a0356b37b46dd36459ae8a5b72b45ad319befbac2f8115162380d85093041b75e17e971259161cca743415aa17348dba2bb55e5a5d346127f43fff53b96afaeeca61e31761b8e488db49ef3033212baa05a04720a34fbc3ddfea52f7f5b1378813d48506768652b9af9cdf80021a9c9d1591d6c482478dde81631b8040124362b5f0e5dc7a202b681777724cf3357f73f6499dcef6867f97aa93b68020ae7a1f8d0655c8035e9ef3a70983321506f5682392a13a72401137895badfe5eb2297246866fc637dc2f47f91f2aa5addf62db00a421232ed777f6e22f671c2724480c8ead9283b9055fc96a20a24d33d950b3de4b3b670b20b7334d357148b8566f768b5fc5d769a8553f50f91cde941020cb70c915dfbe1b43843cc07448071200057a6ef27a518da37263318ea890983205901fbeda84aa3840922e453d562f4ca5af15460632fda14b823631f9f8ebad892a1b13b82d914a7f6a7eb7a115916fab59d325303bd905679af868755852ab3eafb3fd98b63db5ed296d1b403c5817a5aa6a046fa13230d3993f958ae4b5b8dbb5640041a0b63c33f73cf340f90dfae9ef4c8fe98c94e807df3a7ed5762dfdd1d6d4771756d45875b0bd0d579b95b6ceccf2c3a7ac4c09f28fd50de940717d8a8cc26446206e01da21fd88030b697743fa940f0276dbd67629cb390472a24abc5c762e67da8e820bdfe34190c1dfc89a6ace3e2461a80cb82e7d007f3f7a8d669f244c49a10653e38a7e4d71529d87c90cd17e1adfe22307f96a822e5e888e8f19470fead01833969704cc4ca78ec4542fcfb5cecc23d8bdee5cc2cbdebafa02084e00eb2435949145623f15fab6af10ff45f61b64cfde55753bd6632d6ff76bf16ecc8e5b674bb5301e4c39eb3bd5382fb76a81965b1375704cadfe0d0e235a772a2207356d6ccab388fecce64f0f0d640f78feed9bf27b43abb0de81df472cf7363b610d1bad6d709a3b13afa81c6958c2cd9e607cd3dbfdf215c9e50ed5be359882b55416284dddfe6a03e09611758be0cd6ff40a8c07cc30c00cd77b1b763cf5962d7dbb1ef8efb2394daecdbed8892896f3cc92f687a22eef926012ee82289992e6e8a09881be996cbf9dcb58b539fe102511490accbd3af3aa4f2287af6ccb79b190f4b41abf789c4373de05196c142c069121cddf149921f78f69df197916949cdd80ae0ec72cfe3983b8d04df720f93e8bfde68506e6111ddcac878e85f71180b3870311e0a15fbc9f83617c7b2d63dac0a8b7af5e6d0c32e2a85952f008bf913e9f82875e55e469be684e9e236fc6ce6677f6e46016687dc35b72b9066cd1e62b08080783efc72e9e1d62c2cef6dca558f4d0eb913a6ff1a0037e44566d35d4edfb0ea5d0feb69b4769126c42d0868a171e382cdb293a41ac551feb6aa6679ab5b8520c513e37c66081d250a1b53fb189df3b5d89cc4441259b7a51cde4198efc920be262158ad4d889c3dbb831572b66394dbd2a52e49af36e48eb0000000000000000b5d3560000000000a8e7b08e2ef272eb86dc279468fa40f90c6e329f776cf0b9f53c6b96c4a79fdd82c3e7fb9da0985abecb9badf49a8f2cb90f678e23019f6bb350757b19b4750fa7a74dfe17465c407676a451b811873956aa0485550c54db61aa4f0e85bdf03900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d79d0871bbc63ce18f46bb499ae9fcd8a5842b8b08c6b7486f90b636f6086b2961e564dcdc2fa097476aac1a235017ab21fdf14a4311aa1f54fa433feb93386862f92fce04e6f88d89fde9ffd8e930e0f6b494baebd69beb4c6beabb4a2aac213cfebdd0344d9cc8f717b6b8f1fd7ce93a26918cc3045e86e49f035eb1174a1202135d9c7b62e1bcea6edf8557a3751777869eb08d8550b0783c1be421458198640304a5c2fc930782939666203a81ea9d2c28aa50e1494265779d3091cb0c7262fb0b076c07cf4eff622d2ba1211fb1bbae167fc7e90df280d5e75f53c36b2066ea383f8419fb322a1408d1303b7af55ec8d25dcf2c9bc6665d971543343f4ed856d8021133dfa76b9bf1a00414b2f69b8e7c3cf246d0425ad645045311f3c8b0c96351021df17565367e70b5a2d2dab6dde3635dccc2883ecde8f326a0948f1239c44c190301bfa0500ebc9666831ca0a7379444f86ae83d791d67deb0f62c07ad08c22b5f020625ef2b3e76295896d024d85dfb6f7fafa1c8c4fe2d111ac6a12497bc1bd403031070fc623fccba965de25a6538275b003da853f3ebb7e80fbe1738712362ab427f5f27a3f4214508ecfc6171a6d480d8576e94c7e915555c1f650565c32ce1b26a1180442e83acf9b0cf697a319b0dc4766f0efba6836393cabf676ece0f4d9e8629da4152327a9d21cb4d38715d02da39cc392143301c306fba807e00e59ceba036d818d5ccc51dee1fb3531c356778857c6a168d22262069678e2255afe50a21b45b154e162f3f2c503dfef6fd89f50c961e9ac0f910a12406f4275da71b5a44a6c843ef1dba10cd7bb1ab72c63afc03202244e48c40c67c72939f4bb2a41fac0438e4b10476fe37151f34b1bb1204bd0e6152691f3d1e1a5d32ac84dd91a7abd96209cf093276f110a8a4dc8a83a7352d98f5de496b5a1b8f3f70dbaa072ce5ff9a9fd7400b2313cf6150b2adc92dcd379d4da0b6ae4709d80e159735c65bb3b2b9f3c6be3c7973975eb90aacadce8417796da9f6e856530523aaedd7aba2bcbc5182f5663f0875b405790cbd1160a5f09065d70f710617e4fd1cbae040a26923ff6e9361cb268735cc95b71f5c56e28d85d08725d166f1686a21a568e18e3fd06c26005a9dd748fa57cbf23def26b1f20733545bac4f9031d52f377d3b959eb5229af4efcbfd194a8cc9a373e29c3da5c5cf8a1f1b8eaf270089efe4f76c3ee38b8f012dc793ac8c16c711fa3d185d8335405b6dd433822e220ea31ebd0e8aab3f07e08927c36037acf398536e4f39bc2e4ce5163b6d095beb011582d763a3b40fb2f73d9a1f1ee67aaa9461aab2abe6a7a0962b33af0f6c8ca9378aae5a730c25bec78e956034d7dff6cf5f04664482a33280252cf5385eefd93b71e032bbb6cf8a859b02f51d2636e0d175cd166b1c8542b64e51cc377074e167bc4a802eeef4cabfcf67c0d9beb898cc571b268ff1f91c6b157d0ae9aa5210a9ed1485cc70e826ce70468b180c3d9799a69465e290bce34996bf3bee52c0adc7154838d79f8c934fdc8d39f6889f9662cdbdb0303c59df7d02d9d99f3a253c531fb88596cc6f6c38c00ba8b165fdf76660839902c476befebd3b010afdd514dfa8b7fb9a9720f1635d1201b338da0c69f7b0e49a849094e5fc37678df26534442cd2f4186b6dd889321474db197c35ce8f5776553309c36ccc417f4b232021a1ff111190fb56e008cdbec54a2eb12c27aa2c4933db1831e5d2973067ae5469413737503d75ff0e36f360084c7d06dd4314fc2768cb26d5280101c5969155295fe7b6b3ff0c6fffceb820608d6cb3025dc6656b3c7bb966dbd62ff6a243a3b4fe85924bc101b9c0acdd816e4074b964c675d488546f088d2091a13736630feed0f70360fd3ac79fdb6f503deb4f10c4883f40109659d1047d6e30c56c1475b160993d5d4889443bceef8d1f6afd78e83acc15997e63dded518e6bca2662661bd0503b4270a7e61179af24d57f32e04c384ceea71bb06f1d973718aa2899d4ac45d3dd850c16e8ec506920c0c66745f55fc440c1f85e036bffd1a472d62877b0088b289ac17a4ebb1e0e010eb80b693351af063a1d2f58c316e22ad5d11b869f0d6d58c01318da4f70c3c97005c20ca55fd4d3a56baeb57b914325dcbf23071efcde07ca8d0ed5cc63376b36944618f666fb88182cac69108a4fb1f37266b186be48a3e110970b399b2cc5873f458afee6576102fcbecd572f151eb0af3432f7ae88b42a2ce17e986367320be07bfae04689811ae239687ea6d55f8a372f501d5be64a2d28920675f4619e446edef81eb3a1d8237f0be53c0463dd3d72894116886402bf04a8de76cc0de34529da545c69f0eb1299b856903f7b514a6ec51bd336db501aede8cd050139f1af8763037ea190267c870a", "6a6a52536a0000", 1, -339911593, 1537743641, "ebd9254aab96b841160505ce1fda7bdf3044f2e0edddd8c432aa597b90126334"], + ["97d85d4a0100441273bd1c1bdf1be61cf471bd98c60fc48e3e03f7091c01e6111e793fc29d0200000004000052006f3e86ef04b0605e010000000000b6d82a000000000004ac52ac656b7882000000000003ac526368a6da040000000004006a535300000000010000000000000000f8bf7a01000000008ee92a3c9e29f15c4d794ac5fe12384326585ca2419975bf36d27532933cd35b0e5a5c08b207cf07fb2e5262527b4ba5e32e3b2996ad228277f97fded41d237363b5d4518c37236215cde6ad6c6deb3ea64b6ed9f51cb487dc77921a8d23376d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004bcd2e926c8295e2d97b880b1263a2dc401f2951bdd177c028ff8a89cfff4dc068b4e28d0bc9dd11ff564ef0d474f8353771ecb861b107aeb6a379f0a9ef4ea3db98af7baab966abaf9b322a4c5cfe6c7d271d9fb984487f03b304acf4e9df1eb4d57d995f3dc34e19ad18dff8d454ddca66c33c44f82b812ac52eb4301ceef50317a09f9b6ecf6f3c9440ddb7a796a7db975de762fb2d36b799b4d2b293083e630208d47dc1bfb1522a5696b885993ac4a5421e0227450e7b67f7b4c4eec5ee63700b04dfbf48eb8de3d9c2e3e9b4cab2a6f4e6f907b75d77e51fee5f7d8ea476ec392ecf045bd5b3d9c0cea8e1ef385105a9bab7b758c1529135b9bd57ce33e6f06c0200e660b561f31d0f096a21984693aa467f24fc3523bf054f5e40c778b475f312022024f0ba94e31ad9c9070f62537ca1d0a5081712f5218020d11e0b2ff777fdc9030f71a11897ca28970f352c468b6a94cea8b5c4750adcb91f01730903e1abe3110213af951f56d3ab9fb39cce26380596e7640153854abd89a351ce7a7ab8ee5d360223cd4a535623cbab39d629bfc191d2da1da22fd9f5f41a49397477bc1ac921547a38fe23b34bfe19bce51e10aaabcc8815b79546ae0042e62aaff8236d79e10145614624a25f62e168f6b474ddb42b931d267e6a539df6e681e088316941cb052559187a136ac388772462694b56f082ce54ed18e1c5b8b7d4b74054d94cbe1432450742b3b39c4ec363760493fca405937ff78443abc4182fb0a96775d763d1f3e704b53a296092636f72ae726354f6e258bcf2765626ce260e0b83c2a0b5aec66fe9cdcbf5fb716263919265ab5f66f2d4c6d7060cd3cd2148d49308ee84593cf34288cb086c7b2f1c78a8e0e12e85f09bb04a49a5f525d52ed8decece41e4eac584194d2e057150d0df2e20f831d9f762ff14bc2fd7fa51b1f4974ab45fa53ffdf5679cef6dca2a223cf5b0d2e83d50dfe5fd15dfaad4705d11b0d25b0fb90eb0506e882a291588ae88ba35d150c38818c93b47f04e6b4f2d9b26c39c24e0b6c6cc2d206f544853185087aa5e307356f5855cde956aeabeaa4828d9a121e5bc57fc89f472c6fd59fca7dda820ed9e43b2aa2110ac494e155425b42d1e5bc6f4ee5db0f2e7d05ac8b8923cd22fb6f33121a2ccf2ff3be2212a4cfb1b1b3cfb7fa063737c5547d8c1f728027f7855e7618700f7afc622b7a44878341a6f117b7ce70b874d57c1b490addf4b85d1174c539a828f30d524b11162585171330194185f3bf3dc71c1df76ed69e339b21124b4320d489f52c5559743446971624be220aaf37e54f89cc793340c2182ce937ec259b51582061661e333aa1d820f44080248018524f391b6ed2246554e001feeef4a660690876d38b3776d6ffbe5b7ceefa90fd3f35e5d40c4576f562499430bd92e3890bb2ee79469ea7e5b4bf5dc3961f0d5c89a1acc8689d02dac22bdc3179bdb65b2d94d033af156aec3d6176c08325f7bb3ea1422f0c5765caf27d650bd0562a3bc639877e90adc64378855f132341faa5b2eeb4da7c3ef60ac0ecd226093c927a9e582700b121bbc8c5887c5377fc3997dc21b9c4910e21f87c3ba460e3d0c50ff4f39b2ce6ee620762e310e498907a45263da6a89dee8e8315bd1591bde6e6d173b678993452a2f128617baa0a1d9d0d7c143305deac0208546de912b6886074aa134ba05ae7eabf857686b57bb953d70b49753432ccb5de423d6b0eaf9535e59f38ddcda86a2604517e4748cebaf45dced3664a56c598c5d093838ffa584e3bd1d8b9680da22be74124067865675c1924eadfba70eceafcf0b1a9665bb70ab7eb248f23cb10880792b789de836c4b56ec3e4738662ba2f631b530997e62a3b54b6de13818e9eb85121adee6ff19a1785e293b2d80516e56c5626c65635013b61168f305f882a3c0c258db4e087325183b0cbb261da7d1bf1380d5f8f54b3e0514d7bca2084d6f64d15548c1a0a8a90cc7f8cadb1679109d4a02b819f649e1190a7f964dbf244e2d7d2c020a5db61af4bd647d98fbd8de4f68fb81f064a0b262c60c95c1c66f092fb2e6d61cca9a0ffe4e1600fe61c0c777d7e47aed015c5e97e5d69f4d5d462e7b36a95231a4d97f969266d95c711c8fedf92de58ff42974cb3590e2d86116d7cde07496f841439dc492847648e179d5c9e09271d7ada264c39a2b8b126ac8ccc0967f35a828c65eefd09482835c902edaa2b4e53e8308843be0c162ca6deb75d2ad6ba51b95c1700c7fc3e7252d1fe0ef88f8960213ff44a467f7191afdfb52f177be43d88cfe3380a56f252913bfd6beed1c3834a253252af5f8b4a3cc316fd8b50763930fd3aee31b62f0ccb8807dd7545896c454c746014913b15a99f21892ccb9abf14fd7ae6010cf988ec26476106b08234f7aa00", "53", 0, -1310719221, 0, "d790f8e8c76110e7e42323661edbc25320cee3e261e04ae52c746d8d4394a885"], + ["afdd515a04063af696e62fec0e3f68f3301ae16db760f618509a1b569d1b1349d5880a4a5201000000085100ac6351006a63a36296d14722e2b728f5c3efd2eea6bb98f453c1cf4faa9a2b21eb7ef84f083ca6cde9680200000006530052ac5352ffffffff8146f816172132a12f67c75d1057c6a2028b2c77f28a7e6186fdfae792ea37310100000008536a51ac53515153fffffffffb04fb88ede3a6625dbffa7b0dfb390368c20eefd31a9e9390ed570714b78fd2020000000963ac655263acacac6aae9c35d703b94eb700000000000765525351ac6551dc2fe2020000000003006a6ab2c2320000000000056a52656a52d671614c00", "51635165526a53", 0, 2098914000, 1537743641, "c0fec2a2802214c8025393796f124a43a77e41e0aec5360903d63fbd11d6538f"], + ["030000807082c40303637e6f532d205d8b5917a2cf206ce2450f348f1704a3d3cbc0718a587b859f7d0100000007ac00ac00ac6552ffffffff832911418cd8648da462b85c0852b2d6fd3a6a584948510e03521a049ea6bf050100000000fffffffffa6bf0106e14f43f3f3cdfb3d26299c2886c9c0170b4227fe5b62603e298d5850000000000ffffffff01afb27901000000000100bc1d0e470000000003000000000000000058bddd01000000006ec96e76d25bd75a6791dde729a95a977d1dd76e06caeeb3df2c43994e185b8e7569ad405934adcc47df2b66ffdd93b33b6b77bc2c667ef345c0733a32f421f2a99aceae1f62a9f1653e675147f7ff7a1c1847d48bccbc99d7fc3dd5fb11bfb300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000987a64dd0520975584bf7e496a38586b82bfcdd6db056394564ecf2f9eb07fa4520fb7c2e6febfc13cf3ec086fa27edac8179942feceb2a9f55a28d407ec3e128f550b71a950157f700646615bccbfb49691d355673dd632d0bb0ffc9a54e27deafe6e666e97501c0f138d551180f9dbe1450d4ea9a609841167f9ea48ec873803021a2936c99732ade91a68d7f5b3ce0e83232c82135751ad2325e5a8cc135f85020ededc7219693fb2e35cdc7dd91ebf4b50bb160b0ce4b9bcfe923f0b62a3a9a50b04a451ce7a4f6652002d34e1668f2c545bf8c80f5b166fdcf91f2e8eef4b4d6f5c1035e3edd990aa197117132357bb52fb6edaeb4a13e409913c206da63359db0312c2fe336f4b09bf08cc2cabae98b8ae288aca80b80b1e04859280a00eda5f0e021669085502a19f00b63d2d56d51aca25c5525b1f98379181dcc222121226cc85021fb56e2ccd53c23e78e7bb89c8f7962652f2e1534ba529b1da9e7934efc6c9580213ce8391480373db8aa22ca476bad9c7af290980230423c18e7d1e626666a14c0221b4c3092bdc3aef2a78d622b1ea3d37ebb82281144709f346fde31ed80ce7a6b275a54e6f69efbb3b107895cfc7042880f99e038cdb8ebb014071ee3de29fe1cdb13234680ecf8bf7935af6809cd31d15b9cb3606f1a4804be78cae8035aaebec7fe016b7b3d8ca06cda10ebde0c6d31ba76016c64f5f93e4daa446f3271cc6117cd0178dea0db28d69ea0b4dbda831ab52ce43d11d560dd48c1fba5e49718168bb6489b031cbdcfbe90cf929b4e452eb9e79ad57877246fa8e4bfa8f175840b42e838dda736b9ae67285df7055bd4e425037207e50647ba1513ff7dc9943ea005cff06e52ebd87fb55e3c7c933014330b6e4907abb78b67a5f0715458d980ba4517049688f94b7a20636ff71c7613b9c6ea295c7d441a60127d5bc558402b8112e328edb37ab4f1569f597cade68118a77c978a338f806b82a8a3ab5b124373382cf4bcb5eee11398137a9e88fbce57e47e5da9013177876f2982b66ea80bb6685555bc6a647714b746794b4f4bd38e17595ea770370282ba1323190686519fc37c6c89ebd15f96eb1fcdffc0b3a8103072a7a6fb58ae17b5136fd071cee7dd88c80ac6e2a46c9619610a1a1581a0bac06091aba9a7c6cc0193d3b02d30d2de08fa8cae036381c7679385c795b97cdacc16f3885efe064c2d53ae4d6f71a017f5c8cecad91d6e508f3751f01b686141f12a6ec6ebc774c4b84d49516b18d1c7ab4b9438ec3559be06012b69554aaddbf1b08cfa4f5415722821d0544cc39851296e70032b355e3b30b8dc6ed4ed60771b0896d90eeaf4141ded063a574480b98ad1ede6446c1eb793a308bd0b2ac69405507a00bfe19b619708eb9752a9d63576a40317930d4bc9fc4afeda91cd1a04539712e0641667930ed5a4ffc0f4639f7f6af82b687ba8c7ab1352791af4ed618ce4326b0f77ef73ecc94384a76a79d81ca3bba5001053088fd2a772c2199c2e5b94b8e0b0afdc08426b1585c638744f66a2d04a74a9726bcea1b18501ee29b6fa464b3acf749cdd99eb1d7610b9bcdc04106878734aa2a083022cf14e40897401acf634151e78e7a069fb3a8d8c0edf94c4ad42ba88aa46c1b6cdf41bf94a2b4992999cdf092bd69f1fefd1b7f2277635ba3b2b7627219606a54782b50eeea67ce55afdd7e28d3ea2da6086e68a4a8052c462ca1bfb6b34f74773b79a81e305a820bcea2f06ae8148b8b37d8e1f7f09fb46a324fac15ae0c92b282a2ea1997c96c7a4d7546e8759f99bdd52085a729d5d2b90dd4c5529b14d3826b9656235950b20a5d8aa7bfc9da8a31f383c60eb465391878399c77195b0e0f6071ff48fcb85c3d07caabe6d15138db5c6d55ab213b5973bdb4ae259fffa710ed5dc5c02fe6d07aafaccf62d8dc73264b601ac4f71ca638d77b5ac494542dc3d6f1d3b7354c1609a6e7aad10d3508f50c81dee0ea7cd3c8c94d36d592b839a7e202f1fd6eabf50cf09c868f572f321b2a59eb559d32c053da7fc4137aa4267dbb359e11e4dfa1d8dfab5264e2fcbd0c8f3f31d732e07ac7767454c0f1db38d99b77816949545e95b9bf33ad2eaad24b3e0bd3ebd6fbe099987db34923839fa820c1c9ce24ce988762d86a4467e495ef95905ea6c67f2d671a59060979e0f54c7d3d916fa57ed7816f30d583ec7ae439974c22f318294763a881b391192e78a8cfadb8bb6a428cc403c480103b42c195e2e060a6426f0994b8537631e592f5db9789a12e7843f800000000000000000b2861050000000086d6e08526adad2954e3686b271f5f7927b37fc5c8110204de0cca64a12b9be910f776f460b165490732be0cdaaef819bc1951ca53d71538ac33980fc5ec85eeba541610b8007686c7e73da5af5505a6fee5d995b360724883daca27b412cf3b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004726a2e0bffd5237bfc0b4e433f3ccfd23192415437487def77e3e09d86247b96ed35a11bf582791e6818e95d58d4e4972d30e969e8b86168b765af47ac5117124e05b03e42a142e3a433c156fedb6e6dd96415d222fb8a0f0536bb6e882fa4f2c2447dacef98489552e8c4f351a0fc2750f5d1c6d3b83a8dfc50ed85c6b6a210208a39dc1dae03f97d474a19b6abaccb18991a0f669ccdbf5823073ebae389b95031dd258a01c67d1f10bfda2b38c9c8afc27bd9f3e3eee3b29da48ddcdac1377940b08957e6ac2f12d0bb0efca3224237bedee5379da396a008432f878ae1db85ce70a371a4185450f0f9f975f15485b4be40d6a2cf10cade1ee71559cba7a8169e0020397b01ca1903e92865a8c6a5746323168f682e6e8e1ce0835cddabfd580653f0228e9e9eb3d5a5c98f0f4aaac3bf32901482e77d6c01350024ae8ab3dcf1cc181030c3057832c73927ae8692667592d5ecff883a2217a9e140ad06688578d2cb39b0227d7aac321dc0189d3c1947aaa00989335e14d2ae7b2d9f36c8159e7ae4f2c810317e6b820c93939488e4030ea55b2ea1116f798b096f3efa6d63726d067db95015f11bdeb818bc27d5b88d528c43acc9fedc82fd0a58eced9cd3fafbc040dd4769fcec326dab362812a29eadac1143d08eb589a7ac3b7995448915004f4822e2d9160848d9382ea53469f3be828e04e5194a125e9b884feb84f8c6af1be50d120bbfec07154eb30af88dcb1b2ac5ab48b05127b94634f36bc602e41f6f3a4cd277da77c1195d410911330ed1e58247edf486266e152a552df4bbdf6d85ac0c94ba364992001fcd1e9c9d83272e3af8affb840f8b2d1797d6182c635da49ec88e1ca12001c783f43a86c9ff11a0959c914d21c93d30b986a2747e1c0247679a90caec3325a883db5ee9bc8efc16fab8c93fd706577418d28901790e3429047047aab5eda0b369dccd975812a81f0c4ba263ac8eae194987cca6ba5d81c37503115346f7c52600cc2a39af3b34315c4848082435e6e836ea7a8a9d90df1dcdc4a0c5636f32f17de1dbbd79ac5a9562e4967420d37f9af9ec93c15e54c94ceb391614164dae4e4cf8bf16a81e3e44ba77ee6b031382f88d8d8d292bdb7b3dec987e2c05c838b3ca1e988966f3dd9c929bb6fcf015cdebe038381a5482742eadd6403b8ed6f8c80f7ac52633d69b14bdfc991a05cde7aa608622658cef4eac5556ac2db4923431fcebf297beb6f17cead820d2b55ff1321a5f4e81ef87b806b160a46c288b1ae9aec0e126b9d20c445652342576425fa08b75f9e2638343ceb0ba6c13f31366ce0fb6327822d1397fffd937078df7841e2148c13107480af14f0dd6afc1bd02f9002e82cf52c43e5843a89e401cb06ac1be746631cfaf52d8387ac86bd49c7a4f690cb18e8f5c53cf02c85b19ac00b7a180674d673bc73a6bb9194a919530dbb286b204b5a91a022e9bc6bf4c0ad214ed879fcbcc18d155720ec309b1eb0fc9f6d36f51cff6f4d92d2aafd8b59f3e7f58aa953e43f682571a4999a233f24b34725b74599e6de14f8868795935a7a9a466a27b4cd6458a1907ba8ea8a93ff861290ac83d61c100349848985c1a039587529d2d4c0e2e8878329efc2e17fa2738d18d552004184a45f9c4869fd5ada21fe73092c549f557abb3d74ad175118cffeedffbbaf51f44cc1872eeb62e4f2a34cb6e685e0dd8b9d56e1d92f7c93e32fffc60f64c5e410585660afa04638231c40c9247ea0e84a70d2edae659eee5f0bdfb59d94424860437c0dd2be977d0e8be3d921796e7614d40c8ef96eefc0ba1b85424fbda01964d6b97d9fbb2140854846386f5f363e798e9e2af4b1f3c745509cf87e7a9f92a5a20754bd5c910fe1008ddfbe7e9794e86aa9f2c9f81224f8a961441ac578d42ea7e94ee2cc2131e496feb13895a3cb0f1e76bb1575a7a4e2c490ad7f81388f0066bcc7a6775c00835a5ad98c293b4fbe8a8a47a303738c7aaa2d292477fd35a81f57fad88f03f13d1152b16ac0939d814886ee6a5ed93d930fad4ce09e19dec6d071faece531123d088edb3e1b2be5d110e73fe07196bdc9a234382fced4037a1a835cab506167349295ac82b9ca76ec6c16a42bd5c6410936415bfc0964edd79192dd1c8ed0da8adcca40cdddf50ffcfe249f75af77b1126ba054895d9155740649afc172d1bb53bc2bc2e1f48454ed12b23892230560b450ad7f9a8c5ed355837a6b90f533f7d94b4aac756fd540dd6d7d04f6fa94f1e9ad452872b22a4650a897440bb142c35d0000000000000000820b8c0000000000a7292d83b9b573c6c7b8d28b8d40cb5f3921311f79fea5f7f697e0d443eb15c86cdb87ac50d619b7b6adc7723f28265c8be10e5812f4223ac1315dc58cc4b23cb9f0457dc00dff1410b8f58e90ed046a63d566844c2cb000d657774f55e7a13e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab7dfdef30d9e517b8e436ba732717d7b20fc09d8369d87c125b28b86b5144050b66a650063284d39dd3cb3bc12cdc54fcad2db4cab925fb22f1a06a3ef4603ff4a6af183abe396cb85011014ec8531fa1ea5865d156ed8273cd68720d22c27fe91c22e0b66dab8ad134cdae2fd896f9407275d270eca62b6e7d20642bfc7ef60228f362263bd7bf481a7e995ca29a1eaf6e96fc0210135f9ff7e618452586ce4a020124a870cb2b61113be0a9c22be2d6525b6e15bc37d44da01c9b688fe6c1d4fb0a00b8abf9d9ab53c96582e51169e60fe8f559c7be9a03d54dbf615c5a3b6f665d09cbe3d50b7a25b31ad455b5656dd6805e9f469268a1c0a1fa847e59b3bdc8fc0212a27826009bfff3ec30535a0bca112f1c480d30f8e5742fae3b8b3d780afdda03196542aba6171bc69cb3b0071394c4e27bf28066fd623e851984756ff1f3f80802178cf9bf0b25e1cd2d1e9e3ee16a8e0a61618468d0f0bba806234226f974b2ea02147fecbc077abb297601b77d18c43b41cf891ee26adfc4c77fe57b5e02783b2f030ba5068478e738511b4024422ddb182e6cbde89b6ba607a2c168b23fac11088d1e925cb53cf6089b0c45bce5ca220fc9c3d92cfd306e776f93356e34f485fb05eec2b053ba4a406249f10f1391b0fdc25dd094381502efb24ee042f828c803989074d9b812c3a5e25b981bf67b7e395f3071444855950f83f60ad4d77c500dba61656f7ef4b68f3f65aff77d28330d1ec12c51bb0f8c30ba57cdd51022a6572447c6c9c3308f3745b646baaa04aa30714684a931811de07ef54845a025743659168a0a4aa8e6a90f23bc3e505c4089f88754def3409bcabf9a225741ce17c1fa89707c48d2501973890ea51d67c86f662bfdaf05e0ad0a2572ec797acc843ac5771ca75c100d027e6860bf251afdd0b5e112844c3bdc87095340e395cdcbb0deea0942182c4f16a4f5eaf01eeab14ebc31971baf09af05c79070d64846f0c043198337533f6e76cc923b7ea3ac198bb28c0ce68f895f28110927a2ecb1f0696f7d889fba1fc64be47418a10919405fee41a0e99291e0dc3dd43db62c2536bd45751ce8d8426a40c19c38996afa21fee8c9ea0d56274839a5ebfb96b5e0d999bc97311c01627164f834b6cd2732db33709d11cf0ae6f2bd937cad8b07d2a759058980605d05f90e110668626fbdb4b39b69b90ab6ac25a5b50598d4cee30c12884a847ddddf7f81243254582c70fcf385a92a0c9ecf90b5283e3da43a394dea28f475adc7d075a12d3cae9c8edc6aaa95fb83017c85c03adc536f913ee3d93058740f7b365873eb2884fc5013f335b87bdef17f638242feea02d3c309456edd82c72c0ba14de6601ba53e7603878ae8cbf1c73766eaa1cdbd737cd206aa3ca133651c2c5621dd7e2d36783d230e182a0c9a048bb3fb1d75897803f9e0732d3e9df136f73c1baaf77bf6bc20d779073db53e78838129a623d090fad61b3ecec0380b5be2aa0f914fd1607dca614a1f5f4f48f1cbfdc453c240b347f80c0493ca4ff101faa47bce51c2b17aa7d732455f1218e2aa857662abe2ddd526ea2a1c08fd2c1a30c19287a74d8f5dc771022e1592a79881821f333b6535d8921f83370227a0ce13956d968a48773a650df44800e96b8e93ecf32b736be763fa4f9b2ef3f3b885781ecd31bf7d63556b3bc1df5ea16749dc416ff2f40c1c491fd7146822ef5c34a8da0571f68ea16978a65edfb148741f53d529ab6496e896823041b07472d6153b9f44a01801376461fc397c7e0d50fd9fe5ff59715795b62b1f91758ac49308a8a5839c6bbe55e88bb628eed8f2f9d2f1ecc19c85f9f931407fc65e6aaf2227f47fb91d27878f9c74741f632d4fe9551235069eaad629fc5e94d9d6aa64077308ffc1bd25aefb721a9cc2bfcafd6e57c877ab24b9f71db5b88809ccc7bf66100eadd0b2af27ae15e3ccaf85c7b02426016f3d2b3bb9c785dbe879da497d8be76dbd1b250c1ef791b443e0fb0e4709a75156081ad353ca22cacf0c78dc2aef4e5bb19fbd5e780e72eb34cfbfe44450652a3b0f6c73e79ef65ef4f907dbbbda2924e5bec78e4c68138668bd4d8592061531d0ab5741e46777f640785bc8a6492129521f7d4577e6e1b869e06c2724b091071328e9c67a21e36011375c98b71f56c6dee4ae20802517e5447d8203738c8a99811059eb54cc63f4b4a5c24e9732ca7febf3118d87bcb574647837ac84ba928345b1e5a976eaf560437e21150360036b04aaff07afb4ea32e0782ed91d23b588e022455e0dc5fa7ac281a4c80d5ce0abc1743db607fe397ad3ec0f7a1adc04da73caa1bef84061d5953559c3200396d8651ea06ad80c72ccd4fced63450f97afa70af84787d0e83ba5943dfde67a94fb8ec3358823117dff15a7099cac7205", "51ac63", 1, -1175947998, 1537743641, "f4b638f17fec68dfba12311bffaec25102a8cdb5d4981e78216087d510f30945"], + ["35b8fb5302c82d4a316461bf1772160c4344b3ebf58875d32fa5a66c36cabdcc44a2462d04010000000152489ea9c333f483845721b88ba0ca172cce2ab15067d804df4c02adaa845672da34bcbd650000000009006a6353656a6a6a00ffffffff034eee48040000000000b93a1c0300000000016af02042020000000008ac525252536a656574fc396a00", "006aac", 0, -2007214600, 0, "3b6d9dcc2f197e30ed9509c1df8e39b763e7dc22fb910b348d8acd71734aee0a"], + ["d762e424049ab31a1be0b7f3e27d951629ffd13f5638f28e1d793afec6ef937176601305bb0100000000899fac6b2cdfbaa94a3ab48f2140d6b3287f37902883090154873384a67c5a9fe1bab55c0200000008005352530065ac51ffffffff45b427defe4a6101408591b4ead224f525d6780667aaa1eef48981e7d331c6ab0200000009536500656a00ac6a63ffffffff4bb1ec46554d31b95cf0891b4d9533574a8d3fdc3fa9e8d0a6e526efd76e7aff000000000600535153635271f1512801cb6bb50300000000016a000000000357308f00000000000000000000000000a26516fd4ea4a715b99f64dcac7c6a7d23b86edaa7fdeac4b1fd74650a404305d209f68b489fcd3205c724987b0af80c9dbb70f596aeee4a4e2d93d211aac3e9bc1658d99a03d0c562b2b08e6b2219e26d61678ac30f7df0a754e3bee58c90b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d9453ed89905d2cc8e5fd6bf954b09067b8e91b1072601972f6f0ccdc5162f7e5976d62b40871fb695319df7fced1f5b019ba5772ef7dc75bcdcdb393df3b6688c5f0f9f4c1ffe634693b1b20f84c41f0c8e5ad587ed002a5ea13c0249fe65d4fdd31d69b192b0e7f5c29f4002002850756d43daa3ed2c6c33fad7d7202ab4c30208f299e8fafac2d73b6bc59387a4477118a71b12ff41712bbb29e9b03364b60a030981d34b1517d389f9026bd5de6475094cf52a1b61f3fa83cb5e10e72b97f9c60a075bce4088efba9e2fd1f4fc6186fcb72f8bf9a10c3e77e8310b8bc4d8f315e902b73f6a0dc0b0d3a29bced0e56009e492868c75037fa4d822e191a4b364f0350314ad21f0bf530771c9a54e3f5092b12728bcf6a6710d76164d075565afae978502095d81dae9adc84d0546572d78c2ea9a5f9748ce2edae6305f25dfe6b7a6174102211b5a09fcb43c5c8afdbe3d2fcda02cbd6363ee3b64843fe4122c1b1c8b7427031b350ee30e722ea5be46b0cfa97f96ad8c41d5a2b257784e92ebf4758ba8f4890304138721dce4594b55c8a6ed5181adff9da0081cf36bca3910c1431411697a4e74208504fe033faf64943a5f89776e94aaaefeb95607712a1e3cf58f863ee23dcc8de0a6695eeaa218abd3a8b1b3d5b9a5c9e9f493afe46e1ed853d38f4b844acf7f1fa155eef0793fcb012b0ff5f9851f5b8cee5bffbdda2fdec37360be3ed575c512405ebc9d993a98e16fc1fd14b203fe323f16d214dc82b0f92f43d394a86159273d1e232ef991bca5260a5b074be8296b0cb15b0b113f7c0302add50a5ca33d0f6610ba6ee5d283151155949962adc580f45e78aecc18fd12764547a37f69eb35d2a8e3eb875a82603dce66cf60e5d15820690c60a4e21b01d228bd2ec7f41c4d6cca018d4b43dc4337b36a443f55fe0354cfc108992b066ce644d0cf73a15e3a1f285806c402e1af7cb8b3d6202a8dbd23439213edcfc98622ebb216dc9901e4fe12801504cef33a2553b9c28b156df05f6cdd7061d9dce02a1d8616f57fd8165161aa582738ccf274dbe71353f73fe23e111bc02a3184d9642aed519ded114a850333b57ec5be42da952dd4cb5298c3f48cd5767962ec70b2226ad30eb4f449ce4fae8b14c1b0407c0a7d416f154748e182972e08f88acd20ef3d6c24c17ddca12cf18e6f83a6635bd825cdd01451827902e87ee5cb37512c3c35c4b1887655bd032ab53421d2dea2662bb45d6b792b7e87ed4df0ab597e9611f46b196261ab7664a8f31e947089969183c6db309c1830cefd7a82d55ab13e052580fe97ba7a3b35321b52036557fc2f76cedd74b7bb4c2e621142b96245b973a958d109fa59806772ce0486118caa99b2657306c8d8c2c64ffdab7e4171cc5093ab1e0427cdf526227f341ae86ee8c83ad189a02aa8b073a4086c9e43937b7e21560eaaa9430e63163a79a15ead4ec980258ea3e90a7f81f9f24cab7fb03c9bbca661cb9e456d91cbfc6290e2b30405dd0ca1f151cc7ab50ffb609cab7b6a497dc90a75f1018a51870b238882581b4d635cb10ba7e2a2a0f659eff65ddc3b4f54d09e56a6ed3509e112750eb0586de8c9efab312536c8877478ae3a51d44cef4940ce1633962e016de4591eaa73f5346b44cb0dc8f72d494b29e8cafd919cc6122b985eaf90c41a8dd3e971200129d6fc56729e466e648bc853b94fad0d3db365dde637f453eb9a91771d5cb132519123389973c9bb79c424f235413f9b7a3a1f63bbccb3d2f1bef65aadafc55e1365e2b6933dce72702cfec1a3be37b962baaa26f1e805bc4833acc0c6d92e3621ffd380de75c99c30a2b14de3620a65f028067d1851e251eaab3c42abf8f7a9bf835d8c5eb02e06fe6c31cd7ca4e2077cef28f8323f202c7289a0997c304a57113ab5e368e39c708db632cf530c15b4bd5b2281999e7dbe4fb499bc07fc162dfde2dfb60586e887ab9d7ce614b663aceef283a1c6367581b9ceff79fb9015f592c018c3ced409abb7b8e39959b2ffb2ddddeac323dbbdf16906a24baae822beb65afbda4de56e50be0eb57c9327851f0a2b12137e4ee42a905af68a3dddde57cdd8e1dad8e976d779929013da8e8ec6e9b7902d5977c5443d9547bb7c64a82e0655752fef044cb5ca45d38b88e59024eff2d6007f01f19f65c8e971a327d4ecf8bb54137faa38db7105ab19249f41e9dc9d2cc828374af0f8b49d552324ba68fabe6703a68f26b31ebc4f0a59eff51e3ce2172b07e17dd77275af3683320fa4b5d8b6299cae873b561800000000000000000000000000bfaec88bc752d766caaf628383c1292237541fdca33152b05b7f6cddebdf8f1c5bcd9b354f424c1d4192347a869c7f1324d25890c9c70ccea177e52056dea3e917e10a3071b78d51251d4b9efc815ce21817e5254ce5d10212d257612e21414000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000763da5b688a512cd70a746aa6119d19971a80005e1bd2784a2ee3134a3e1cae9263ccc0139eede9af8967b7137dac94a7fa59ddeb1e6b0823128108a41e53a326107eb0c54550cf64f5a902cbeed5f17839b31a9a7a31645588c0b91e05c32e863afc36754663d0ae4a44c0b78ec46b28fae405312092a8e10dba6f3859f457d0308e729bc10f360885a41d2d8e6dbe2ff2a88804023749e2d4e8faf8e731846cf021906fd5b9718e772661b82fa867be3db945d83bd852680d781fb67e28033b6560b00685a1fcf76a8d0057609d5867a3aec489349dc0ecfeeae3662a97a594ceb3db0fe6dc90ac20aa3cd77a4d5de6f8c16ce62751b49038063000eda03ead912320324063a37469d2c153c88618ff604e13141f4c42a5be198954459c2bb83d1cd070316c79f2d776164aad2ec2dcd5eb026964d49c92d3c8399e2513d1342d9dcec8e0218c9ab0840ee3289369177f5b2bb10ed7ffaa9dd1b0d946bd0ee89f0cb8f5f5602070dec82f151f881a05fe70ecfb13ac7d0e526cd3f7039b05b8378436b97833a0227dea8fc1c3c27f8e0308e5f230435b5227288c96ccd0e52aff78dda4e0071195622e4552261c30acb28f32aef56a03f01268b1bfba4f0a71c5aa0c8652460344203806f6ac939ebbc3eb6c452f2892d74c2799152de08a5abbe54e420eb6793981401c18f21af1478a093f154f3c68db0b2ee22070cdec9ade2c88be1f701b45fc448e21b981d30c469b34a17def709c09edf20366dcbaa943198ce17b9970dcbcc300ec98f414f7d7675d04a77390c53dcc3a011851f9d4de225984891ab735dfb1c42fc5e2c0c7a21ac239b23f0a424cb0463057e2cd531e6dc6deb01dc4fd8ddbe95ff4532b337b0d2610de3dca77125f33f7cd4ed74a8bcb9e20ffee0476ac295d354bad3ba128446e6204dc0177c650362aea6afeef9e4c68c1fe8b2221d494ed3cf91202260d55a8200eabd0de65b2ca4b1c771d8df14a6d9a0454ed7f273fc77e72c0f825de1166ddee10e06518abdf1b23f2085055902985185ea4b0352efe8ff9e34a475fa53764aa5e22d15c90d997dbafdaa929196b7ac0d4e71c9fec4ea6e013123a7b4c785a4495bb1bb1e9557a55451b722caa7f5dc28afdbb831683bb306c2b4a3fe73bbc56d807cdfb2bcf10c57009f44fe4927fc3e548b9300d378905c5a47e15535e78bb1573aeafc7b21639ee2eb72f3b2005b8140c8b1fd6aafeed12ea37797b46df07a46ddf2b2ce9c2c670def3026f8c4dd0c11f42034ad88ae9e9a7df29039fad7b6d3eefd093db9553586c793defe167e24cec5ec912c963c0f57afa3dbb315471579e76f61d5c65c340b558471624dffd363ca5527ef46f65e8e4c5673694510cb7293479b8d45082db08e8a95c15c3f898e54b3213bb5155dfe38c1fe66d301ac191eae0618c7a8fece11dcd6a6e8680653faf0b8e214feb388fded18dcfbf0d44fb99cb8cc706f19e23697d66d393c00a427340556135f43333e4261988ca582b46178e92ff235d430d46b6754ce3d34ae2de2df1e78417482a843a4ae8a7220a3ad6324b10d3413c7f57bbb40d0f51c0f4eae987c20eeb80ada5f1eb5abedd5af666e3985c017f934100b065bf0bf8ed7845524a33e5118ce04cae2f118cf2e7379fdb94485f2ddebf25c4b665ba61d64b4455184b5fa7e3328d71d2a40dc3d7b87af3e7d9a78c544e95b844b3432ccd1991f9141cddeb87c691af5a36fe03cb102c27d88d37b64a36eb42c51610c94cc70ad8735f47b800f6effa164e9863e5657d6ff6c71341d29ea26c82601496afe1100922dc88c41504970f0ccc36572ae5a5ba8af125faa11059f8c5224d13e7a8e50940dac8e6f9a23cbb6bb4d17518b0d6c547c12f3002665c430d2d9c18ee7534087281c4e5d7f439d94f0c89b088ae77294293b4dcad8a4a99ba14e31f98927da20ac5cdc36734a239a8df4078d6f5f557f57a28a0e71d67f0d8a90ccf51a9de323436766754f9d4dc1ed2af4ab88b1c3ab2c319f63d3c6c50f82809d36211b498f8d0a68dc993ae2b5ad39e65e5b6ca27b8f9adc45f22768eeb92be2ef87617e18a522d66c95a854761231f0e7e43b2486d8842487b0ea0fb5878029ca6645f807ffb7880acdeea518df42e756a6fb19da42d6f8fa45cd64a5827504d5855d8b78515694639caf7e9aecd51b64d4f3ca2a2b0c6beeab1aa2e1f8e5614ab704f34a83d597076506511e7b22ca2658a29e329e048f44809c5be86dbaf20874395295ad971f1508c63baa133bfb40e5125f9a70f65901000000000000000000000000971f83353eb2063adbc2a314d486e5c542d1d3d4034a43a97e764f4cebc42f48af614551d1f0c569c89edf9e9ee901a412544ce9e219a21af0203cb5806097bec5fbc0f8ee0bee9dd0c23911ba1c267a830222a7a38a5068c1ab0826c86a8f9a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e8d6a0714181e257580a60eb6657aaf70cb61b473ee15b170f6c5cf78cf7a24e7c5574a81471dc4561648ba751f44326f3051f58dcc01efb88ee4696267630ff6c871fc0ad7a9532bf7da0eed166cb4ce19a20b20cd0d1aba6fa1c0ce766f08cbffe1cefee4d29a0b1219736626d190376514e9bd292879ce46eda73f4d37fc9030ae9884cc0f826c04f353060be2b84c6d44433a863b9590533462740ec5d9da80201eb5bf9187d6c8c6356a402204a0e85d5823736a4f1b2814af27b47470bda970a068588dec97af56f3e0b415035cc442e6749e97134ca2b01b190c33fe61ad371b16e57e86e5cb85e5b791e4070b285ce18a462b28bcf04d521f37c78c2669267030b73f432c9866ebb4b5696e3e3435d65b82bd24682ce54f2637478f7efddab8a020561a40ff45e7a67c9cf1f1d0ba52220076674e3c7481a470dc54b9645a34e6a0226637fa23147531b786e1e6c856a192d4114bdc386f95cf7e0d66c802755c260021a2cd1f414d3b84b0c98f014e55d83441a1730a324f2bc970c5653b574bfdef5031152484a20817937bca88325c40cf40e69bea37db40f7fe6925a9a7ded883e050672a5cb625a7eb68a637f5b82556fb465e0753db27af03213dd24017533284fca27baa2c2afdad3fe50ebbfd12d74ae8972a9965562e35de407daeaebce8d57fc68b3df412a3ce1d0dcb5225190383ac18ad8b7b7564f1f70157187c299ddb966a383681d651f8cfe15590bece79c3167ca0f794a8459ae3bcdb3e57137f845286d18c40d9eafe10cabf64ce97e7967bb6b0ead37ed3655b9722ce4d91bed9808969375a48924c9c97c8a51ae185cce41087c9374f6396c80de54989c02796be370780b73da0fb1c6a2f59d1a86b8d3544e737ae56493c8602e766a778f490bea014debf2c68a2e7bcbd14e8e3754bbf0dd69d6127a6e9317e38e8bfddd38a43f90bfd8b47971fa2d418e18ac7b041712e018dc82ff9987eaff28fbf97dd337b717bfef9470b73799642d3f02eb2a039008479ff745d5e73145738f940317175ecb88a758204d15ba081b70d02194ab4e56bad9a4f1afc4a8b18da3f9fc7e06b56f0b5afa9bbbfe63d983c3794465eaead38a6adfc50452f991d3f564e42741edff8567acc252dd968bb6fab39678ccd7a1b3904ed2498e3c6868282df2867abbb92c8ce2767768eb0d0580e2a6fdf968d6279a8247d3ddd5783758327c304c82733d3a2eb62ecb4e8bef76477cea430ac5d0e3e58e05eb5172398ab5c31f9ce0cf3ed3cf181d6e69e69ad59ac270f9aaa508efbe53b1ff376186d0e4ba765767105cd758f115d2c85d0bd28bab42ad590777d0c585fe0e300eb8d44d0eca73e8607a46e934e5d56217eceabdad34d3ca6af779ca789a529e51722f79253dd01d26cbc583155b0dfd621423ab805c7e6922fac2fdb281fa8583777c1670d798d54e1720364219e7694bdf21f211e477ac787d6691980bca2b075a4afa4dd6aafb4bfe080c74d6148fca1fb5491674045e8a5180d7cc15f1a47f8df1b61466dbca6a4f02f2aa6cc3e2e28924c7bed03774a465c048c99fbd234d8244a4c419793e7112a09c57eee56c4f8b90505c800ce4a1ab101dfb7f7dfde0fa87ebeb49a1a4f462ece47e75930d2034f5528eaf20074f8c0fe31a5dc39dbf237a0db82fd8067035eab3b97fa24faa7bf4c912f2d2a4f35e947d16566d33982a8e9b5ba60e747a5608e8a74722bce989997c015a858437ba57d828741854b313502581e0e70a835d4f76469239fab204a5501f651b4d7326e588b98561d5e0816d17789588763f80c373afb143eea5033a8081fd0307b0593c47b1f6890917f0ef9057b0468bd231952f9b4cfd029b78122f50983d6eccf183f0f7a2051c7dd91af2c38c4deff17c314f4533b10d68600560fdb0b614feb3511ac43914158a3a4f3549cd8c9aacbf9c3ba9d1ea85d29478a92d427d029484d9a18abccf6fc8822712d0cb8ac7a53ea67016b73b1aa48a4035e53379a2e369ed2e9c15d8226b0d82eb5c5c59f02b4ec7bd94bb2b5ff603b4cbb00962fb1a4402b61e29bda23c876ca80c6f8fca4c496876f6486615114ea5a18b9ac015f16a34579dd3db259b0d91224a114c4e9cf7df17fc7d8e60f832c1f3ef1330f9be504da85e693390ef8a0b81637916cb6548ef9d9269d8f000df5e423c98fc68df75f4cd18df89cc6dada0bbd0af125ef369853f4b686ea2ce354d4a58388d226f3daaf50e87eff679195d0573367cc542eecc9ca7580488838c2039b5f8a10a3f7a21aa1790c307938f25a27c21dd02ffb4ebfba12ac4706801561e02ce6b77fea4b76e029faede99ae14df590b94468df399e7b1a75f397d8bb51fc6043328fb9edcaa0dd13267d54b7617e767a4589d137045a3dc1d78a5335d98db9fb5dd08", "ac65635251ac0052", 3, -145564471, 0, "41855c977078a8e8b5d4a48a88fd7ee2b504135143296cdce2871ff841af4f1a"], + ["030000807082c4030468b9cd6ebbf01f53afdfa7997e907816ebce05cfc60e4cc895b908ee56758024020000000100ffffffff624a69fc7efcae8aeeb4e953499f78e8512f68afe54fc8642c6d94c84a7596a00000000001656cf09eb5ebc3232c0ffd7143a86e6e2b7aa2b4e1dc710f11c39cf721fb0820deb30b9e5702000000076553525352526a4f91052d96cb2c307fe311529abdf7911ed74f9e1fb72f0994481d8f06f5d3847791a16a030000000151679ac5e901de54ff0100000000076a65ac5152000000000000000000000390f6ae050000000000000000000000002d325a4358b07d90bfd8015eb6e05f18a49c43bcc328fedf04987c0511e8680f0acfe4372ab09fffbe9662bb7e0b15514446c9f9b1a7f4ec99d326fc8d8895872e109d761b3d6a6db0291a10d7bbc2622d8c4de3cd1831286ac4e00af6e1492d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e6af5c3fffd7b999fc4ee43d9690254bd794e5db7f78546801265e7ed8cd68ac122af07c5645e9c1781aec15df7369fb651910ff11d87852ae53637cb467a3f670b629cadf1d6e24adb54e39ca67940c47777c8a0dfc5978071aabd572dac40d8a6ab988f70c15cb88584c7714b8f1de3e1bdd8e453948bd85e8201ee4eaaad0316c9b1b4f77a1c7806f3882eecc986a26a7e55c81b977f7b24fbdb918efb2deb031bb57c4d9ec88c978f42a62165ae50f8f3849e3db8a4412586adf5f9370dc1f70a0247c6b9e660531e80907023993902cd236524ea9bcb3ed150c720a56f6735908be34cede3a464620310aaa33614ae67861d7acc4f9f5e402d4df5bf5f7d2d5403198cccfc7e950199d80219e3844bb76ded1ff953fa0bacab2e4a1c3b1f9a0944032a958bb1ab244a7e9e77d44f92a02c23b3ed96d735eed623225408776181a3240324dad3983255b480320d5fffb0825241bb3232aa53c8e36059b979ad93ab437802246c939f249b357e0f02483d3b0f5fc1f1b64d6382fc57bd8a9adc91e3200cdf0328eb940fc321d93c4d9c6b61569abee97dac8001812d61962526f84ef2e9c760e7f3b36e1e101e99fb1495dd03bffe4f6c9c0ac386eaadd6c6d9073e3f70d4d35501e0d665a0e19d1ada0d95a5267170bb8c90dc01ebbd1afe93ccc94f0e614019a1ff9a4880de6a4d1ba63cb98aef2dd43091f7e743748f02d9f18427fb2198e291d9a517ea321a5d2ee1a05db554fcbf2da9e8b65a40ebdc2935ed04a69dc08e35b760808adce3ccd7dbc25dae3e0ff3892f2631a843c73353a1eb8090014445bcb49fc0da795d632b4ba426d4d61c74a15ca975098fe57e4a7afd32ef90749fa26a94ac8a5e431a140013f49cf90862446fc2887f9d15310c5b5835378427bf084bf22d93031599e4dd0fe9ab4bd9f2496b367ab6df8910e0b4901e0cb79ae8bf0de78dc3595fb5597d70b77e627336ced428b18a92a31c5474c09624edbfb9bb0e63b8601fde2f1bf9dca33cf8511279fffb0c42500dcdb3975537d479fd6947ed8587e9d7beaaeede1d3fae1b4853bef512f8e47004f76b0c3797bd03382abac875bfaa18fd550b7d311a80d1614fa3f396cddd6c127b2608c8ec3c6f3cf28ba3fdb78bbb7f05c5bfc07f26858e3f455e2558b33ea8f8c22b307a71141bf873bcfae0d4306cd3aa7b8b1870d36752ef3177d9d9a6e7ca0bdca188aad55578b7fcd15469a8520876e457afd7db2f1d3c2e4a0faad9b2ffd72be3c8bf713380c17f7c6099ae62e5dd4ac55ac61e7197323189eb55da7c08e5b7abfabd89b47d9bd70af560ca1be197cd10ee5d8d278a833f1c02df483742b4ec7fb7b54cd07f119e39d3699d004ee215ebf3b8395cc707de0eca9293d225807e8923668347b5431f409847b1ddeddfec796c320aec69666d10001062bf823ddb322f6bb767668b0b85d4117c74c6b8172761d78b0cca09b8938bca81b81d97b3c801635c821cc0474adc0d2b0bc64aae3cd211a9f52ad373fd4d0bf046910350ce1985485dc739253ae618f6c761b57c38e8f7ee9cdb4509a5958777d28b3f08bd8036205a42f3cdf800a8e44a9380306faf7b8a89217709f7b970fa71bd583a8c17b1ab6ab39a673baabbb964dd75bd1f0c889b8576a49e6723eaf25b9257b9ee5b28ca98053702d68199f3b83a7239db3e8a823ba2e4bbcbf801090d7dc4312bebb9a01a451085d902bf394eab8759ee2d1595d4baebfe4258b6b9d5a89323b6655d2d653e19fdd0094dc2ef89d2ceec105dc333e26f5e17fc18ade34d6e6386ed926c2f326efcfe26ee9643cec3ecacbe70c31e8c2c58825ce516cd7075ae307eb35a9ab0587195817b7a83e4980c20a5d39fed945b6ba3e791e197016b905ad797a4baaa9895f041649fe2162c141fa20435908e4355ae4d424bfba4cfcaeb802c4d4668ca7a134bd3f45d0ece1acaf06d6754afb40f7de71938bcd3fc308b04c32bc48ca7bdf243a16ca00b97d233389890b666f1c418a001fc7061a22b9771b56463aacb1ce3d486cce0ac72eac56b129bd62efdf14c9695330c5844e89b6e72ef6b7a179c7d09ed403d2156b03486e9b1e62c5d4befbf8b7b2d8a8a8dcf07035e861c34498cf35dfed601b1abb724d066648e20181599de27932a542ef2d03af34d9eeba0424f44ad1929fbdd13a410f6a42915fe821dcb3fcbbafd40e33f9ca714d0f0d6055bdda0072d228883d385d3d3bc02b012a08f7c42208a34c35c4038a6e7f2308d8b9153b57b8c160346d1b1cbd5870000000000000000d910a401000000008fd3f9730ec2f3694a65450af5e3370824daa039280602ae6aabb356d474446132308a671e1b5f09e735b8c6a526dbc8ac7c25db35dec980c727f40476bfdceebeea09b9f0bdc4d1b1c432df97d79719f74e49ee61199c5cda29e23b24fd605400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e6b7677dd168414ce4d67d13bfedb8f680cc471388476541a8a0df090076c25d105d06d9a9c234b32ed91c9f4ea462ce8d1c757d6fcf112af9d74fff5000ad0af8b8371779fc8ec1a96050383901c53c4e403f9da50788e7ab9eb08062d9e52baa4defd604d1a8eee4e9ec8bc5e5258e28360bf411aad9911ff978854e95356c022fb0901ca13c2701e620114b18cf2d7f4248e4915f8ee85dee9af270031b8bd202183eea8428646ad4de901cc719323d486eba6062fa336c68be968987b1b41b8c0b03ebd44adac87732be4c4d6b434eba04199620aba66c15be559452a2741ef7a1ad504eeced063f7d04f6b75c05ca2e2f645e66a50fb8e3b2ac6695842f4beb280217b66fb7507f00df7ab162ba69d9c13f1d2c327ed4ce1a1537beba898741fdaf02110ae4165037fc12697b21b70bf8207b143a783978d818e29b3626ae43629fa50218138a9bf2c797c853056f8253c5fb641c6460e768f9b3193f9ed5f1800ac0ba020c275b8d9fe9f327941e4d28b2601fc6666e7eaf2d6c8b7f7981d4580cd48700032c47040e75e22fa389aea44c0697faba238a5acafc4a1d24c09cdbd13c1c141c31a3741f752a489b1328ed1da5926965ed9497c3d105c859d22a8f62ef53e045635b3c91a4660429a05c2319d11577a242bbee7794428e39e3deb527ab3587089965fd3dba4fff22320f2c928fc60d24c0d74485c99065e98ef71d99ee22500363819c8fa084cbbeaeac73f8138297de14dab4b776d35b5c6f8969301960401aedb98239084a7e31291f682a51d54c2fb22a3aeff45377d4e7add5b1b11da75a63e0a87f16b39dbd5cb9151e732d8c9b901026b9bfb4d59e7e91bd4c96492772433383f202f66fdf46496014329dab7020eba7760c235224040cab1d764fd49b8fb3bbf7c3f1211b82f1b7690cc66e06a522abd6bf24a29d511c18b32020dcd388285417791bfd5310c9a0dce257b5539b8f681f7fac4b906f3c2bb79108258417af6cb8b9531f251dfca374ecc71e601891d04b918e9f129a0f6edeb68826c21658cd4066cfb3abd9289dbc6f78311e7a08052223883b2837b652ee44083018edc642c23cbff776c1e47be0636193c0ecad33d91d8307fbac1b413963be613f88e065706222c888df9edf498f45600a15140577ef903c6ad55135aedfa96c40a8ff4fa9f4be66c8e24f72928af9b69637775a1233770ec75aa1ac1c9e45d288f2e3896eb023d6b4fa81c062e52d6a7402594d393bbfc2bd895e208fa9026c6c18e42852a55242c81b9208c7bfc021620fc902ee8c8d7ad7878859dee38191a43c071f796c942df78869e0140df8d82fd28dc421625bc499859f719304e248010cfb191747d15cf3a11ed21fca61fde51f9ca8c2c5f925b2d4e77783831dc6294eb61f80fd012935035670eedd07b76a8aca4783c5863d99e76fc9da971336d7233bcdeb04853348ec363b36b7cf9ea2e5bf2a380a244063728617644e3d358f24bff7588d2ca38acca0e7cf2ed9b8be96d9fba4888fe6956657b4eaac07d7699744bdb5b0ceefc9dc4416580bdae5ddb216d362aed24389875abc408f338212ede05c88d9480473290ee4b1e1200a0507e6a8bed5340b7da2e867c3e05f58361b1b325fde0af0fd655d159a6a74aa64c8d572b2a642fcd99821738832e82ad2470c00ae44b8559a8698d4e95524071c4c6467956423c4b415f5c05fb28da3256347da2d901d88cc770b07b1a823092fa9e8a905cdb16ab34aa4e9a18b490aecbccfc5dc5b335ae0a2c62b2f2d2cca3f4209b91dc9e1dae9362e941ae2dda8ff5c13ed919a316adb1694e07dc4d493d89c30b2f26f91a1c8bb6f09826d994057a8b9c21a8b57408a524ad0ff12ce45f169724b978f305a42e811ba218afdef2fe4cb157fadd66e03746f36cee718b6a9a5604828684eb158c678e1e549f9b7a4633fcff4c87a8c721e25783136dfae57e023be7e703b2d743e0bf01f02b19fc6ff540b03c733d0f9761684707e23d732529b517e2365db676d4c4d30b67e08b1cd1853818d7e006fa967702a2a83067483c6d70064efbc9d8a8c69874581da1c80dedda7a840704a8f1a575b84d4e12759247bfce4565e4517496b317e712cb6b1a4ea7720d1dd4c91e087a6b8a21c99d38c9a9d8c64407ae92790edd3294f0a63432a193f5e7f07b6d1007eca304b2255fda1746f4790105bdf9227e3a58635186fa2466979a5bfa2982df200f06b2a27341a419f549bd217ffbd17a1abf50914adeb8bd5b0c8642333379fe08a0ca663d8000000000000000074603f0100000000ef612a01f8cc98fe1b311f286571508a536f338bd962cdfc9aa5c180f6bd1932338d870a6710740d7d17d0d588041a5b30daa5e9fab610f9a40be2909fbf24c739f37f1b1fefa729c115d55d2aeb07170d482d9be7b48bc2185364a58f69334300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b00393042c5043b6aa0d23ca1e61d3a7ea5659602a6802b5d41b6670e07cabafe73c5c2bfa5fef3c3c2c8fd5ff2ce4928b817e718dd67e65d16004e2c8f9d9e65e15103c9174d34e483c6ea208378fabb116402a797423d12b9efc4f2847aa729f7cff77636b2f6737d433a1c82c081339a8c12875d6cdbd82ee71b2a7b2848c030a153ae4ba131cc7c22b97d18b2a705e30941ed1c96a1604239b7fab7ae49b25030cfceee681b355551af5ac829dac0befd79bf68307c04da030afe764d966245f0b05f2527014124cd41946d15c7205041a890a1db94b328731269259cdea7a9950880b617afba4edc1346351d8fbc4090ef45bad3c99966d2393d9dc64b46cd4e1022cfeb4e956548a4228d578376b72939a0b373a270ff04ee069993a8965d1e4d9032a288dee47862cff0477452f3a4930c4534bf1327882dac884b04a04c3ad459703119fb25aa691af03823abcf1cafbd20d7ea6c5b89b2f4eac0e3f6805a13dbc420325d59a73a2d79161f632d5257120014410638ec63c9707d5d1490094452426a903191570f53ce4181a06554262bc3decf91de956d426af282238d0f53a2c7f9b705d03f453953ec70740dd2d86c513b710417732ecd82974201872d0309a93f9e5ffc1c93fbf5cd0f2c50db8c508dec05f1bcf137d8d3d6bc48d0c556720f8bba8d35ced299314e1eeeaf3f362f58fa74188f9a94b6235a2735992352cbbdc72635ccffaae12c9a1dfe678d32b274aa5953db3e37be2330f58657d23cd371a520c5f0864903de2fa428d55e1ec1d48209a0a1220d16ff32a0ee08c8256429caf3ec6ee2c4436052ff0b91ccaee90f2ba57f263e9faddfe7a44936faf6aaed2a4c39c7c1a949d67fda95ccba7b704d26f7fc6f8056ee9af3e2b1b6365e5fd007659f55065c479b58316e406223416ce06239c4d780ae0f961b49d823c44cbacfdc5a22d599005362b1b02fbe05816d5a0545cf9602142b5aa5fd09bb3d1c493b80f14b21eafa29d2cc659f026cdcd367683c6f589979db804d486259f39e624f6a611ddb956680fe62c10df520122870c82b1355a562be880f9933bf87a480d93dd892a5713d0632c1769dd207187da16e9b1e5b2d2892f3441e05e22f71dc121e61683cb6b5314da92c648165ee84705872895d566983166ccd81f7a47f09cab76aa91042c09b0459991fedce73d72af976bed25eeab372298e457c0b4ebc9fceae6351e7ee69b0b9c2184eaf8e8fbe0b386e532a6b99970f98ac0f817a508bc0efc79e9bcdffb2929dff50ff5d18bd1b66f491080e36ec3497bd02c3baaef91259036005dc0b136834def3f13c0687db4bcf5a4d01c35213e41ac72ad7e73f8785228f9e82248b39cec4be795aa70cc77510876cbdec59ff34016110a9f8bfc4449b41a57eec4ae7a72ce58f8232307e4d9aff516e7f97f9386734ee39652dda6c67f218e8ba8b0e2a7417d25b4f4f28202b4536c054ef590324300d9f69de5187f88670894007faf19ab3f80068632dc0b133e8fbba615e4c639979237b90631285d2627228b4202cab114e7085be0541518b1612aa174456cbcf7d219dd3652f4e786e3219a709ff8730d58da69f66eb13ec20845a122cc38bf015656159eab308d9b16269919c64266369a16231a0db8caf54378548e46d918d42b95c76bd7029d6cbf35ea01ec91b96cebe96caee52435c65004851865dd9bae8258333b251575c54302d61b285443ddbd8d16f1b3fb41912828bee3ae2a28a1db1bc6b19f7c38a51f11c02327c4fa8b96e3a8af9889b0e43447ea792900139237805e47ee3499d9594c6ad21d72f43ce1dcf83127fc621f4a2f830affd61d439d22546c02b8234e4d88dc82c7bbe51774717188773241bacf68807f315c7525c77443dbf7a35afa699f0568605457f5e91f9fe46bdf6973114e3e89640f2c4a2ae95a77b990371553ae33ac8850e203662cf9fad0ed7ecf53c5c743eb3dbd6db781a607b99fee827b4ec9a08761993110291e6a36a271f93c2994169dacb851c6172f86004c185980a89c4397eae89c8ee4646b83ac91916bfce6097a3e3702e1683e5ceee0db2b8b3a292a4a5090dcdcff356f26fbd58b16fd426feffc6beb5ea2670d43527c70a7dd62cb42aa0ab015e9175275a962582541c46c91ce85f323927d76042ca4fb774f9b6398449e6d0af6b7a97a0e0f688a18791eefa0f5a42453907e097d272856c2ab920feddf321f6c4bcb43548f0f1569437d0c62a9d570ea30c8a7476cc8b16e402a6917b376570387a333d56c52592f6c79dcfefdc089b891aa9b67bbfe3e4d7531d812c429436cd1ce3d563ea5adcbfc7a47a8dd4e7c98818ff6c12315974026955b33eb0b06c72cf3492b07d473057b9298441684318549d6d4bcce8fea6698c2997689e1ca2c33889a8206", "", 1, -1168474435, 0, "5cc47a664764bf31707ebf6c54557649c811cbad79adf0871283024f65534963"], + ["eb5e2c5f028043ece08a5b66cca326e3d61195fbd255b5b4797ceee7c18eb4fd384d2d34550000000001ac07716e1a15eddbdfe0a47fc7bd715733bad390a93906452d522916346bcdd0e6708caa5d0000000006635251525163ffffffff027f2dd80500000000006fac9103000000000665656353536adaa0077100", "6a6352", 1, -1784199066, 0, "d487bb4a762c1f6821dd5cc9d84901a74b5a58bde34abdd5fcc673150981132a"], + ["2803445d0324164b46619b80be3da7a0f952347ee79171cd29c2499e8e30288351a204914501000000025165ffffffff43e3b69474900c3587b54e91c64acef16dcc21195cabbab82e4b636341fd1968020000000163478d26a4de09a32709d109ef87d6e14c9bc2df4ecad878c20891d5f06030a9fa5300a3c60000000008516a006a63635251ffffffff03fba3d30500000000056a530065ac151903040000000000433147020000000001000000000000", "6a53ac6a525200", 1, -1801080151, 1537743641, "59f967a043faaeff85b780a3d8dd855f540d906c12d63cdf10ac65db4a296da5"], + ["030000807082c40304fc42aa2fbce5758458d91880e586c98bdf502fe3abad51ce96ef90b6a1b951e6020000000500005300ac0b6ac5ffa8d837761a9a65b429242d9443df3bc3f5b9486c6de7362e0be247eb06e1c3e40300000006006565655365407e37468f3f95cf79cf580892904402057c399edac8e929c01518c2c5cd18b4713d164d0200000001ac1e0009b9e72103bc8f403422e82eb16e0024fbb9a732062c443ea1a31f323ab0bdee328c02000000086a516a51526a5100ffffffff02745ebb0400000000026a652662380000000000035252009163bd18000000000307800a0300000000000000000000000058be4cb7af61014af6452c3c44dbd65a4f3c1f4d6053dc6c6fae3ac4232a00e3ade392e91ebd33e2acd9255a6fc7fbc956fd07edbe51b31dad601f84a6e8cd04381c66f092b83d8f8b976af1de8c98d49631e1ffab3af0f3e20c3a715bdb1752000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005255ab0f38cb212a340d1bd822ec2d1ad55f2bf3691eba85799ad4560900cd3c363066ec288fe5e3a5b7d581c6fca77edb8a3f1ee4ef94fec2ce185479190fc5e54f469265e4479f4ef092f5ee02e0d239616da1b82ff24d7996740e23bf6fe23d9391fadf4a6b0c44b038dbd516ccc4d890729e2ff32abf9c33dfa6dfc53371031806f3f7b2b1891c394445f35af43d85812fc5b162b21c1eb31effa5f0ed990a0220059634dbf64094e9bc8ba0951a501bfddfd97b3ea9572d3fe9fbf9f959db300b0777b1867487b8f40cf08d32c81333862e0f591061ab5609acf58717b01d1cdd439f57cebc2a2e4e91c54f51f6c00deffe5d5e55ec54841060b874ec1c96d240031fb9f4f576755dc968129332edcdd78ab20d97283481457931c38ed46894f9100222241417876de61427ed0474efc15a08e2a7b52e0261b2f981122f2762e0909d032779e003a0442186428bdfea430ec1774b917dd5daf830af168731485ee6d7d902197e1c728bf017af9d9644d76c66e7556b76ab00d5ecdacbb4ba4dc2b9dfcdd20202c324e6c73ca1e83fe7e64ff3d45b0cbc77f5d3aedaddcc552a5d368775d39b6b48fbc865849115943b0d5ba1e51970c90c10716fc92f87e45bc31f4908ecb49869cb5717e405e49d3245c2626db7162abc5d0cd69270302851b33e8dd282fba01caf9623840fc4075fef1e271e610ddb23ce646ae9b2e6a5eedae7c4ba5e5deb009d9adc43663058a4bfd2a9a9a00bd59e497d14124cc9a94e2e170913229b1a8bc96e0649631b18c9c2fa100cb0a5ecdd12f1f2cd3e054adb89f0baffe289ba08d843a63a77dfbe816212441d93a90612d5beb06abb0ec466bfc1d4ac595e640e6482f2ccb9e28e4f4aa68086bee23028847288aaafd2e652e7931e6fe6f22271be5843532b310f74d88ab5964f9b01a5508b2858e1e36fe490ede13aace83d8f41ae072c938131d9ad35d7c3d7d762267a2f63e3f4fe0afaad85c4bf1abb759fab06d6f824ccc232bf19e238dbbb47415dbf8e98ddbf51f084afe843f6481edfb371cdc09617d2de9573f980ee1743f57e01d96d8571706175061615bdbffa87d54840ac3bfd06def438deb7ee1868a324dacf0993da1e80909e8a234e8bfddbe9dd7139ce2e5d4367e2fbc149fed340a6f5bf6561c54a03ec449f397dc4f48796903e440dd1fa3e9fc096a2f699aa0b9d7d3b681094cbef935ec5f9489b3fd13539be385c837cb0c0924af4c0044afc9864e5fb24dca3a2ec124ae229329b9bf506b1e7a58847c3d26880d410d01896946ed0fc461825c63b0e0a916c15b238e311eb38cf59aecc4fa38608aa4952766d0ae07af8fd897c631a7f5e56044e030b87a32beb1320ece47a89d1ddd560a4fcaa273a58639935ff1a1e791f46f7cef67d651feac42858692aa814484abb1aa9d6005d867a7ff70deb7036a8388fbab4edcc114c0d4bf864dec4efa1b2cb46906fe13aa1b7d0c44afd5dc5cd818eca3ae61d1f0e3e7211c03db9ddbc5ce3311cf3459554b040503d7a8b61d27dadef52bf871a1921c44b193a688f54b78c2bb24229395318df9af3585a45a9d3dfc2416e81323b2909b69c5920a66eb56c4a27c3c65b0c82c1112f0464c8b51442c8c206efa49a2f2faf492327c0058ecaf1112c1861280e43c624afc93ac869a2560432c6d8075657b13d599a181d18c34a3f175b0c95546730c29281788ec2bd5b7883c6abb03a4010fb3bdd3dd28167765dd49d6f7da641c6978cee056712c19d25af186aab2f38363ab8e859e45934fa21fb76014b619361dc2bf5092162693efcca3448158e108e8167bd418418fb5d578cc79e615f536ced3f54cddb36c2b6e75833565cbb80b93d9135e239697ca8cfb42b1a08eac79711dd138c28ba2f0202567cee1652b4c1914257522e785aec1d02bef121e0389955eca8a81c7da50aea797dfb8b7aa43fc2ea74c761aa65cca4aa5c99d11e625663de2973ed5f2271be66ffc24d9bb05c28e84988c968d61c0648580a844f93c6938f9f7f7130f04b562c5b960a89f96bb47fcc279bcd5f89d96c49ac33d6bce42ffe155dd691b0c4a7f34c47e8ebe278cc72b5c3ae0856966d37403f02fd2490eb9a7ff39b85bebc4b889005634e0257d10eab7a3c748fc5e7e245f9d2003c30ff0263e2b4ec2640f4dfeb0896d467ccdffbd1addaf9c116a5310409cc1c5abdb4bb18a61473c26251833c0cb2e1753b4adf380da4eed6c7b2d855a00b8d6d616db8d461089c7fc5455f6069b626c5705189aa777c93646912b20800000000000000000000000000ce0066f15c71c67c3c4c77ab1d4069a0ff06364fac006bf601474b4cb8898e36b1c7dab2217d166a99548de18327e456afec970e72e283d2d19bf1d5132a8e889e5c0806f1f141a07da505943a25a680502939dbddaa34f9f6503da8f2cfce6e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037db8791fac4b4c43a197ccc34b48d3d4b3c02f8144cf47fd16501a15067ab30bf397c31ec396f0c79b96e58480fec01395100ec207a9a6329f2f4ef3e13adb49f5361020c27ad0edb0bbdcf8e12c27a3fadaaabf1a09f3828b311004f5de57a6e49a8281dccab411414ed2dd28f70dcdf76c8998c401f8dd3ba2905cfdc87bb02300cd2c0386d90c9bdc65740abebf5ed1ee1ec1311dfb5a0708fb194626b36bb022ba6d7cee8242723397a57fc516c941ea2339bbe32e895363f406bdc756844d00b005a251f26b872b97d6619659824d911b7ae90f909c7f7d6ed84a7d2d425ffbe37f81383a1c966b576d0a9246cc84335d6d1e264d27c6bcc38557fa1565ca540031133ae711780f07ad14b70f817dbba43758a31bd30f8223250c3253dde690974021082668d488ef0183eb191d92af3c6e503ed5b16f304ca5b7ced06172ec55edc032949c26215095e56905e3c2282450c1a3fc363df851dc3d931016b1b01bf90aa0217ff4d91bfb50c20d75e770f10bafe619cdb4bb7d51b2f74702aceec18bdd0ef0303c474786aeca5855a0922efdbe80bd829952d2d9bf33e6a74be9f1d0ee8ad401b33a7b6df70b5ba67d0f52b17a5ee69ea27b516d79e7fabc1ea3b3fe2d8a26b52c726e7346b722a430ba8036353c81978eb606838e049ae8307b548a1138447d0e984f48f4e367f18ec250f1751970403fca2bb986b1b23fe1d2df9e5232576f834e38ba1feca9e26de369f37a17737e926b50168c4c56a17b3df7d72533734251f4d0c3885409466f15ce8e3e23e4d0e06ac082905225da482622ba5a42aa9867bc49f8bd922c23df2979fd908d35ba6aa0dc638f295035c76e27983d5a23486823bacc497252900e1399e0a11b6da90925d2938854c264f8c862f6a9cdfa1f7470ddd14a72be6288af9d03a77bdeb7e5cde3f36b206fe139edae8781de63f5da1d107c1bbd3fff4680f95cf317c9748746caac4c69432b4d931524f11188ae982d80bf8d995944f0d126d6ae68119541d0678e4976d5f15da984eaa15e625f80cd5c166c7c1d91ffdcc17b18974f3e242665726554c9ae2925e0de85b62f870a60d5aac85ffe1d5a513cf0a7fa2930caa30de0db3f22f7e5744b769bcdbf32ae48423b53c79f2c7f1e15c58f64e7e0cd159493f725f28ebf17d438c23c661c4068ef4bbe7fd66c5e09275a0d2a8725e81ebb2a54f322ba28e76f6fbc5173d6112252e63d90c7f66978c67e886b609edd0eab5e882e4a78837ec329838bd2c2bb296c44aef39939db27cc5232b031bc8d0f42ba8d895dc4706854f97c451e61e987f550eaa9f755d9020cf7732089b6e9a020b143d020788f21eaf1f4103847a320ac5eda39128f5a3ee02a9f60f8188135d26aad8b8da092c8812c1e2e942672f278404bf5d7a5a8c65104a17262602a277193e0a69f4abe792af74c4130459eb6263b715c7665c041c68b66370344371d1034843cc41bce5cb51a9751d16e50ee16de1a321a0d5c59860618b66b02cb1394ee75988126a61942c6fdf90193c1de617af1f2c61c8ef65a4f17a74c13753a5c1965227f6049444aa07c48f7769cdead8ac3e81ba12934cfdf6eab40835f367a519cafc1ef17090916306d6c762203863434523dc56d100c1880716facd237b8a56ceab31c4a26b257499373ddd2a70e3cc38ef83e402a746e5959ba8588ca2e8c93375067540cbef0df52866c71b4e97d2bc74ee7a4a4cd19c4d82d7a83b1004206a897891f5bf0e02d27b7265870ed472a21e93e1ad1407f026532a76429d02a23bab569e67f3a469539532b52ee73ac91ded3e2ce53cac27a3071fb7c70993258a8ecb9c1c425c2dd5b78c3f30f939bdfce5bdac2f72076cf4fafcba4e0af2b3b5c6e502175474e61eda85a136bcdd56e81c0708dbd7b291e41b272934d5260b66b46f943eeb2ba8a053aa2ed3adcab51a1c5bda60a95dec9ef875eb305d43f9ab77e3b8aae6b118590a4541767778d35f8990123e20c4909649389d83d3d2aaae78f4c8db04afc60b7d6a0f6e05b30cb3b90025fba89eaf5bf1ea6b5b45c638117183c7efb258b1b686359bf6430373b0771c9b343e991659a60c57f0bc654ac988af990fb4298a6ae717d80d4af22a5b3616771c08f77524d1c38b3f03d5b63fe1b5967dc02152a371aa16149aa8dd5509e3a0286d2afb163cef36edc397d12d328c3d045342b39d873c640b8878bd7eaf37c550622f8d798e8dc119032930850453248d9a291e1b14266be23fb46319395e41190aa5f9203c58c0b10000000000000000a1a18105000000001d0f3bd24db990ac8247ec1df25cb8913d933ac8538d07e4c0288b62f7f536441b80ba0eee05329736e0667a843949561dff08127db4d2d7ee0149660c6cd725da083ed20a6248410205e6ba2bcc18549e369af193a88e9f44b84bdfcbb6af5100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000237cba9148dd146ebd1c6c3aa915489e88a6cb8fa07ed723453a950bf395c91aa79fb179cb1dd70f28d1d516ad18134c93c4d9f3dadfd0952122101ee946b8808d71eebe2681d7d2c74479207bbfcd735f4450664c14280ec99abaa3819735130a86dd5abd6ad1461123575e167bc75133ded67c028396233f2e3aba778faac50323ccf897bb2dd2d573973628091718586809b52eb9906ea18002e17576b0de9b031a330efdc94abbad9e661ebc038be85802bed1a24b6d40fdf96a1a4804124b990b01461228c00ab1a1e966175039b181040386b0377daf12d917c349e1f3e717e26946ff8c94f6e24b8fbf4ca733034b04384bd782135f325288208dc0fb995bc00313ed6f08e9f851ef3188619f68c423fa07d42f0778d6ca53bcf8cf69b0339ed0030227214cf6ab1dcb70550fa0aa8c31e6fb76e7c803684ac14890346aaacf2b71022166de91330fd25375ffcb6863a4de5782f99f529d52fea87f7314f9b90e44100220f39cf072d8f3ddfe722946665153091d8ec52c5fccefbd1ae3d3e3e09f557d030b5188e1cf01779041e0b97aca6d3af487d6aa331d9965d30aacc4527fbaff16ec88486914e8cf35a6ec04ab20875983986129b6b0ffe3fad990cbb09503d6f113b1b37dbc43ae26d4f4f5067b539018769c1fd0f63adc678c5fd87622a82a8b00dcc9597c510c1e2fac28ce076519e3d2c02c257b09f8408e0088808db8db912a5427614a2b8e001c3e63309042440be99fc21a2c07dbf81c06231a16133f7d183f097227513735b582f45e6153bb44f331eb74aee00bde47bc1dfa3d64aa2dc4bb11d3c0ef9e3f6bb91fa0e0cf8eb6ca9eed7365af5d04de269cc8c2539d95de3a61360d3f55a9367b86b44e2f73c5f12f140961df3db16547a16271a118e5238662b978a5f8889e41b46078395c85655a4bc62a524323faf5e4364f113d45daed7466e22dd6f0191afb34b9271ad93c9af7b95a8f778d2ffe5bc5867676892e573dcfc48a15b2769cfc2e63b2007800aa9efb6f27177ddb081e970ee55a4dff17b4beb202dab975efbb8c7d275de156b966d2cb2ee0dbb09924e395ecbd9d08bbf2a457a12fdf1df12224974f93621cc8edc1eb0fc3a0faa8c2ba781136d14be3a6f40c5641dec85eedaddfd0d4d9eda6ea88270792b7771d933f16d65231d936c75151a03981a8582e13191c7bbd1e91dbe42c2b38a7a4b8126a90247b7970715d585497037ba92b7f44cb76003d38c1d9daaf6478ad6452f1f76c837d7e411e5b5bb9af83822fc97e2afd0615b136165ac09feb350303ac0df8f67d3cf1e8ae764c5cc2ea03f8a76e3cc3a468653ffde232ee16f4f97628c2dc58f77754bfdcfdcd3bed9d1224b04904b1af251b495905a7dfc9a7cd2b18f322e03c527333ac954b8b22f62138584b786954c1ae16dd4c98a40c607ae9503e68215a2fa58ea856716d7596538ea57b2ffc918bc25b3e322efb629bb04f692cf62b4663e81c628457b6264acbe157dc68560c34cdf544d8816ed2f7c2e2703c6ffbb48e14ec11908bba6e8481dbd24aff201aff55ac18171a1b770de7f8ac3cb7a8b91885eedef459c2a8e6bc34e696451cb708c1e34a1f4c4df2250168e9d767f62319c9dfd261530b80d8f581ae15cb4785a8f791c6553be3a3b3bbf1964ac2cc9fc4df108365431af1733d6d02bebff93fe5bcb24c387b0861a22dfd79db27b6f1547501c196074167ffc3341078a215f729930cbd8e88f2924a81197a433b1511543a67fc6aca001455ab868b340a2d1f40d3f8e3bf657db8b8a93dbba237c6979cc90f839fa4f79651d037ef462623e3d49da971ad15c93d96f885223a751edd716f34d365bfa1cf07c23c9562bdb0c4c1d4f93fc63fceb317301d3d881c3d5e80b543dff34536685a42accafafe9fccd6829a01ea7b3a58ac818cf0c5ca5a4afd6225f700c53c3681a1e8e9288e7494fe27a514604dfb4705be53273bf6d8f40bbc17981909ca3e2ed778ace7b130977f6039414de9dd60cafe2fb7478ffabd88c4af8d05062d769ea239a866f9a98647878b7e3b62ab2a3498508aa184d13a4c4c187b516f5f4d0b6b384ba321adb707b18af46be8c996a15c5804c8d33d9d9c3bfedc047b68ffea51568b1348555ca1ba29f136b1dde07b7342b82327d71bf5eef5868828879f05b87840684dbdb216384409876c4ad3562080ae61dcd60af827d93f98c1755749a914fa5f02a35140753a38a21c1ec295a8f20ab0648e94705cd838e8c22c8dd9e19d78a679d6875c2518a3523bbf9e3d823c951c046d8127c22cb7af5dbb3dfd2aaf51ec4be31de2446f8c0710996d7a10bba5d5353cdeb409b6f387ece08d9fbb1ef6975c5b369ed06a129824d72f6f3640f823d373e7f871b68fea54fea1e8b3f6aef4a6e5d1126bdd0c", "52ac53ac6a63656a", 3, 157206664, 1537743641, "606b5f893561832cc423fd8332b12cf24cc77b575906cb01475b4145764a4373"], + ["d35a5e1204bec527fc90e955d68374b678084b235169f59641a88689d29a7b2c4ea45fe3380000000004656a0053ffffffff8f11cb62947a9f062f24348781ba94cf5f3ad2c15798877af49556e055880930030000000553536a65acffffffffb08fd6be067c97a89ca4ffcfc7506f1c6e51acd45cfd601f52e75fd240b5462c020000000251517a592b3f922853cdcda0b161088664c5958ba94b617746abf4c1769538c5c96d6b2dae90010000000863520063ac006300ffffffff03a230100000000000055153536a537aeec80100000000046353536a11cf7f010000000000d5e937220193289c0200000000000000000000000053ef4771d31e0e03d78760d74a9c0fcc53170e66c1a22dad512cb7b06d7414384ac80a0bc71132eb7fd9834b494064aa20e9eb6de004cbef5eb1048a8f48cac0ed40ad7952d6e59738e02b81a7dd5ccb3605a087a8063294aa6e5562a6b902780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047551ceb1f5224e8579fde24b001129db6a724cdbc31f0db2e1365865ee0963f8809a52d586a231d08fa625ab82b46b47419eed7a90a54669b3b6cf8d69565060aa38da96a99375bdf9f2f89e4101cc6146274fe6e4d91c4688957effad3be4adbb8ad024584e0f8836ad62048fdef6d0323f11726035b94eab5d38bc82e775b032fb7f044841f7b53c324e8fd5cb41db583a2f09a021b66fc3d5feac09f75f97f030943dfba1148518394e0f4e8307fb18fc5f769fbe3dc7b0625e91800d018fa750a0455bf7c5b65f142a6cc7f160290322b8e9b10f6b0da16462d202e2a97c8e42d2aa54afc8666a36af93d5bfc4945bce322a6aa93207303b40d025a0988d7e97302137d0e1097239ca4eb1eba98145575795eb22c1858f86c61f246a70aa185a77a022b6a8e53861e1c9c4894a39741e453981169fe646e40fafb3abf12dcba3111b80306ac0471960996c98a47b42a99b068872a8a12aa6cf5fb298bf2f3e144841173020849f0c56e789f5139716d9c8ef5d006ebd2b391215bb86ccbc2e7fa71423c510201d912cdf04601caa5f51a4edceac2a5e97edec8d60acdc4b5d696130549a6d82322e156f77719803b291b8b765cfd784f2322090de0e0bce96d8f48d6d92acce3cfe57348e27a489200a7358c0306856c37eaa90edd6a000e1d3bcfe678407ab564e6b1479f56a9dd7195b5e7173af6c9617e084936e713d8351cd3d33ecc57b44c83cddab12d1d6f73bbdb04e8603bc840440d44596762cf65f5dab54dc86420cce17fecee29e6fbaa7d0de2c24e5f4b331a2b9bdc7b2649e6a8363646e316e905bffbd955b03ce995a3ca2708c63eca63e152797645bc9633981c704a9a0cfd591cf52587d6834cf9088553b7418d6eaa9c7c94ad15256c2477ed47c4bd4418574aeee63c2c8e289dc3cb1167ead38e7fafb6f75649139b38ee1ebfd975f4d6536c054c6558c9fa76e3e578ec18930f25829edb26b783b671f7107e7bcf646c2e2905f84cce1e0b1c32f475cb1ded09e61db0d0cb415b2939ad2fc2ddee0b5d12a3bee4184881067689baa2af8e7cb87b860df529e2fc0fac931a0ef8f3d400169d0c78bd03a957b118f9c7cb651090d0a044019414f98d9f6c8f4b3f979e5e20255d22f7f1fe28a54e3d169385fd5f138db2d2bd64c91e666844e8c6ff62d4ae1b10eaf4d8bf2afbe05a34c414cc951e31db9ab441ddb58b8664841629e343b9561bfe5c8b7bb472ba2a638942b45241eeee35adcfb8f5d1023b2be354f299eafb2ec9e37507410da6f4a853dcdac38d6d3fc7f35e0dfffdefd3f12e35ebfc6dbcbe6d2c374c8c2ce439d6e090d2164fd837cab5dbe08934d4a50ca09ab763aeab1d119d04f3e67511c813b7db63a2ad85faa91e4fede3f2fed50cd853ddcd2e8d3608fe9f5001ec011bf5f4c33d127a2e70af02c68d067baaf5ea50e377224ea11a38e200bf25ce0e2f2d0c89b6262d212b604044e8de25b5c5aa2660f0db291eaf9864181848bc85f8b6e7196b3f3693e510c2c5dda7aa90b87002a485b2d595bfa1459b5e1eed51d666c12212691ecc0ee9c688b12fb7e3b5f8884cd45705a7892a9d322bdea1145a955d854973a835c873dcb0a479c0e0cf918c23ff148702b66e9e9be7eb24c7b1ff38ad4c8568362b5d34421b1901388514e4cdc15b36548aac02d8fd4a3e5a3a0debd383e0d8404e1eeab68316213d460759bffffe7c5b2f07888bd001cf62bd9a273a6b5b9962eece15a8ecf40396f4eab914440d2a87d245afe990c50e139245cda2dbfe8f5d212ce3123a17562c4ec397200bf7442048f8f28c23fc3397ae6e31b28486984c5d5134c7b45d6190b3598268e97011ca81d0077ebe66bb0dde0e68401d1f7a7f91ecd973663f519a2e00394a4c0131cb54196b9dbd62c6d5bd6390eb5b9553321c7a33806a8e2f330e2509f8abcd1796b03a06671efef33f9230c4504161a10ee178d906511f1016c8884d205262f8595504a8131c1195074c6bd41cb2744a28ab04f8e9e4b5227b9b9b3a49f1bd936b6e6d257e620390d601d25228e712898f97be4e458cfdf21d6607e89482298fc1d537373628c12c0367d0f2b94f92da26728cc3e75ae66467f3e602d642487df631ff752c69910fd94c6e4cded80f76aa42244077e5cbf597ecf13128baaa20672b59e403e1c6895b908ca8adcc855f58eb99d70f76fb47e1cb49bbb7babcf0225e4426f15b1188100d6fdc138442cbc321d7914d2b4123f19eecb3ccadc631fce92837594815c7b7eb8b0cb732b7027961b2be00fad8c877eb97110bc989261822039b6c8cf17c80f0f36a3dc87ca507ab54904645595e299410667ff07a900a1e31404ad299d082f3d77446a17cb5b3ba66f124a79dd1f10d85d99789f022c4cffccd62978e49964b84932115e605", "656351", 3, -1256698903, 1537743641, "45217b0135742f9f6c4b323f28d80deba0bf1a95c4bfcdb490e20cd711f1ded4"], + ["ec5f6c6802fe1791d75b90ec4206f672343602c06a22f06ec9a704cf8a50efd436dafb404001000000066351ac65ac63fffffffff0f00647eebe0e44f7da5843f9e55287c769951fc40e149589d5445e207c51b501000000055253535200c321d0ca0312d122050000000009535200636a636353acb167e202000000000151d8a328050000000003516a51b7835258030000000000000000ee407b0500000000713142187dce2157e7698d51d92118c42ae0facc6d604973042028c5815e4beb17df9b550ffd520713e9866a1267c23b63735ff9081c1e015f840bdf352a05f079049e684562e6df94d3e53950b4c76e4fdaa45bed76bfc933f06de3f249b4e100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6e440baaffa8584763646f083d5dbda236a069cbd7a0119998acd79a5724d76732988d22126ae51c1b8ed41ded9e0bb7fbe614e6dc3b9a54321450eff959bd4ae3aea5647f8ef01ebaac56af1084ec0955738d5c053886c198f6aa472fd86fef7ff518fdc98a2e94f18e51f66ccea5dd6d8c82fbce278020af97e33699c0278030853d88c745f0a40832bf444958b5479a5f0835af5e02c3c92c9fe65cd1651b50203986aa8f4be2f81830a832666df3874e9809898492a6f11911edf87e8a48f1f0a033d8917f87e8936efc0d6bc019a0768acd1334e6ac6c153b5254762aa784db7a25d98181bbe06fe682f0b0324956fcf075ad90b7c95c1ca15872b554efcec8f0200f88d980f539d5a0e505502d123d8be14ca8addc3d2ca444b1b7f2cd37388c0022deb9103e45aeeab54cf21139743f51ebe39c5c8b908039bbb318d6aa4ad51e9020d3076c5d4080b4469e855cc91d012532d40aa226bf9d045b5261cd5be793b0f020767855d07b55f6fcb0ae4d159a05dbfd36f492bac8725e26743f4606bbbdbac032d7d24ff166ceb29000838222714070d7f2b51d40a25d34d93c54ebcbebecaf95b9a1298314add1bc8b869fa61bfddf7b544cdaf1d269815a588efd002f5c6a8d8c6962dee192569664bff97c435968d1691d1d130e1a29df8f4f509b0d4b725cd4d91c7c479a0fce925e4726215bd029eee7a1040a97ff79b53001dde23aaa5f220aa36a0710582d552be924f8338970302864e3ed17635fc9a990e47ef18eca08302846ef66e887c3333a604cb2a8cb5f4d4cdb2ca7767c694ea5595e2db963eb04e04abdcc535441c7db0265da456b3a07eb80719f06e51c2c82b71012dcd75a51560e31d5d80c7683834b8b55c63b869ca2dc4b822773f7cae43b86bc366ab8b4d6efefcffb2aea75dd864777f54d4def50d1564e9160fef23bd876aaf32adcbd6b62c60fb77f53fb8767d69bb2b685bac06b04b08ee084166fc669aee375db2686df7ee5994b018372b49667cb3149b5872309fc6acba5905994f8a4974708917a09fbe33ead9258b71dd230a1104af87576d945df65c74a5138a42ce31959a68baecb9a2479a3404e5edd8b2d3d7735fe3a3e46b910df8eb522b45185b200fc85e20fbf1eca75e7a85941fedbb1ba5c0e89c7d93ee527b37eb1781ebdaf8bccc0908ece832d798b1d8512978d0b9a4181e82f69ad300929c34467735fa69aca8433ff7c4f2d504a899b468f845e8aa81f23d56fc7f5328fb70de959e8d9fb3d446617ecf09b22566e9b476ca20fe0212f77d2b097d2d354e5e8fa06f227ae6c5019b18f9558aa1bf3ad8b425a5e1fee9915e62bfb8004bde84043559befa1e7b98f14341a621d7784828c7c2e66a09d25f2f4a40b43933dc5e81bc0010c21496e931793fa48a70e05bbc2e716c8ca38e22594d03f0ce717519064ab9fe84ee9c6b554a50286957a2a422afc43257f0ad2094420aa6969cf2aae2202f5b5b0a68c58889e5c9fae97308013b65170ecfdfb334f9fa5183f219a4c35b2ceca167a05d716f20ddd18aee09d27c9448e66e569b59578e804d05ee974378fe37d6ad3e2f4e87157229b957a66669efc30a3216d6fa9d004b1d66189c52b03b782874bec613fda9f87d8fe90525ed289e95d5b27ba83df5eb7aebc4a5c5434ffedf75e43433e44183d08ccf7ef81b893c68ccd37c1fd0429f18dbf4b04be4abe5c7528363e0f0b3976ae678451f2c8fafc16d672517024ca870f2eca157960cc48b286eba7ad1b01828fb521dc220bfedc518efbe5e944995cbfdf36dfa4dfe00286c0f29d8814ce1b8926edf3338a179b0152f05464b7198616dd1fb4714280d96bfd50bc03cb5988a69610129a5e578239674edd43090c22c47350dc1481bc2af91e27e6b02f972156de3dfec4e05efb51d94516f69d15d00b5a07d5a3638e66d9adf0a890467b1eda5bbd3ce28ea6d01744954485d4fe6c3dfe160ac70cccc3e2a2aba4299aa87784016f368abc6bc65697d3074392a5a0d2b04c12926bc09b2bba4d8cbbb971ea2bf4ad0e2bb1037c67558cef0f139cfc70893d06b2d23da7695ca38c676a90c2a5976f195b4f5da79f741533cfbe2b47396cbbc57006b1f368190f4e04acf12ef8c0806137b04c3e1cab6f75a005dd9636a0354a12b321e1d5ed8dc5817df4df906888db1f4838c160d3b9fee7f22b8e20ae9bb73ae3fb9d73420bbede4f1ddf1c382fe86ee744ebd1971286c90c095dc5c92fe89d61b1320571d9d23d8b869249a644739e378dee6e0000000000000000099b4b900000000006d89dd91e39b957d806a9625f629c317b4c4c3b454046849f0bc59191b6ec35681088173e4937a3069a0848040eee12794321ec0ddc2d2aeaba7febe49a01c6ed09eb4aa861a7a305a0db2353e67617e8377a920f29987b422373b48afecafbf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095873ca6ef98177f56801b8781531f77d557b2d59a2a07bf1eb0faeae49857eae450d9ecdbfa88a0dcfc616d0ff2d65830751326329dfc804af4d054e30e08381509c5381ca5e153e8de64c86590a6bc51fc5816c5a31615bc83c887b05de98d8fef1f46ba181d88b13edcab862ea8f5ec7dc5e175f91f6950a8c29e532ff896021bb3090fe1cd485add130548714d69ae9deae6bc4a65c298a5f3933821c0d4dc0220a4010d13aa1cbfe9d4065d08a1f0e63902e273156a4d45ef062963a5e47c430b03c48a92c4262658cec90a3da55ac8ce0da7828f73bfce95f813f2fec1d89a2c64f6e578d3619235dc0e6861153ac68257ae7b04ccfbfb4a34e50d4defa81ff6031e630a890d8646ba4c30841230a5e73bfa1236be6cb75afe260b9177079175080224b40102db53252b0d0ac69ec3f66b41470dbae884f43e73eef6a086429ef20d031e2b93fa1e78b085f8c78a105eb4e84fb2e4a5dca99039a32f4aefed29a2ad2f031c84986aec307e40b56aef054ef2b76f4976d675e0d4685ea64bf60b50bbb197031c1ed91ee43ded4e2523fe2c78d19d67c8a774453265ff2f99d32e2b379f189a057de0dbdaac4b867bae0890e0b3b698a3b545705f39257ae6e559d6471bd19ab4fe3541fa7808e9fd47b00ac5b282337fd4e0301bdbba7fe054a2389c0c747f9c16518a403caee8d54084a201be9765a62f4c7fb588f69652778840e7da35dabb0fe4cdd8ae4deea639aa430814738306f9201669255b17b1fff3508255636f134846fb96aa5940f114a4fc02a601dc878a843ebd712da95d0022d0a167c31c6c7a6e23db900fe091a2fded76399794c2fe6eee453a66cb0d5737cbf580c9d973be603d18307020f7340a010fcc6a605122a4ecbbfa425980412a266e5a65e07c7723e154dd059975fcb1fab5bf9a2fcde872158d8985bb5b378819ec24623cbcdd81d710ad3a3def6c4043d96927c3951fd3611cf7bc60ca0881dc3a58614375c9d593a4246daf1448336b2b0c194b6468805f3054c7faeffc902d2d9b472d23c2eca1bbe78b963a7c47b8bba61dfa3054c1d1120424a6c5dbaa6bfeb18a04e51ee5828915495e46f0503e1ae06356d26dc528e2651309ea662708558b6b38cdb2802ce63961d83a5a9e49ea9bef33abf4e8c7567157cc1de6868724736eb76167a405c92c9a4b685a80da4a25d4bb153e967ef50b533ea25fdcea9f9afb3cda7f84afdc26c58390eaa881b0c711e011871d3908a83d0766950da7790a7cf7b4242b3ec75c3d2230c604dd83495527e7fffb35cd9abe5e75d1c3c5300fa932ce028c5dec4c394ce40a7577840631aa442786a017ebdb904f911cb2e4a3c41b069ca0eb210dbc3141f77c129d383bf2813bca6117e7e40eddde490eb51aad1e086bf9d879d1a211fa6907ff214ed695da70090233441bada824f2b84c3977cd8e3ea5d17eec26fdc895dab295d5aa360432123a7f6fae21d3b1f9acc30fe594cbb8c1210acc4946beef6654febc92d458a46aca3b91133fe981ef48a9a5e97065ca65cd586a4320920fbac791723099a3b14eef50e0674b0f6aa518a758a124316050d72a25faa483d9154e954559968ef08120c14e5a55443bc89e0b13bac31f741361420ac6bcf4068b11b48aea41a56acb5a7f73e083b80be3bde1c2edb0818eadb53f720827fbcdcd3ec04174996ee3e32182bad777871028f5bfbadc5dd4878554ddf2a6a04a3e0cba88f92c29c6c4547de104af3145f7705bc98d91b76d359fa15fc48a2de6d655780bc3a2043af015fc012187f1cbc04060cea857ef9c03dda48c162c9ee09d8bbeae62479c60f9114afd13a93e231da35eb95de87ee50151ab5e1cff261f908c2749cce5ae776e2d7f16d6680026f31522430c59af6f00d8c3b1618d70b5d89136437aa5eccdcdba3c050ecb12567dc1a16b0e6dd028a40ace949caab5a1b0ef9bbb62f753cf762448e6b29310c20f378c7a80ea363ae937dcbc0f8f7b9928dbceb0b1367ada6e908a589ffda72b14085ca05625c35108c2688f6f3d336a06a4e3006e5ad1c84fe976497c33e999925fe2d84f863cd72ae4f3817b4f0145ac9f0844deb97930f37b05b0d3c3654a32d392367e0a4a7a8eb227ba99d56e34929a912c247d8ecf8b546172568e0d2d5cfca698beadd22be11c3ff050832361cacdde4162e6ff21988d74028cc8a476202f8445b0db1c136fbd0215dbe02892ec3068d7b6cdf604dc410d997c1862e18eb9fe54c658d11833d1c9601c056df9bbc16206dc22aa35d70000000000000000070f1203000000004c2eaab46c6fbe58386b053dd7da5085634722deae9cea9c62567ae3a6c6a3b5fb63ccad84343852b927665d36425c31d6f940d3d49e17d487417059104891b6d11fea7e2094fb1cd34b31e6981633ffbc2f83fdc051e173d1a5c32343bacaed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000745f6cd162c5a69ae133afc6fa3cf7bd94dd7d47fdd0068df985448cf534e03ad7927456a331676bda40ee7d22e48aa1ca166392001d302ab80a0c1128943c7001cc99f3509d35a923019cece51ea4fb5ea1615b8e2779ca16fe16c31c82015cb596654e1bcc765950969ea75151fe19cd96b15136878e4de60474c507c830410211cdc869c4d1ec2d634436e81b86c28257ce67d174745b6c9d8df032e24b2cb90300643b8bfbd06dc75d199e988cbde99080d31d6911ed322bfa6d48be2db7bad90a010c57272e45e674fdc478e60a2315051a5480333ceee4fcad72ebb772959701567ffbf07f7fc4cdf2e6d62cf396a893bebaa01c8724e21b403c4c7b3d08d0430223163222e11c85cf9ee1b6cd2a44890df6f4cb0e86227409439faeeaef50fa76022b9afc8044a8bee51a51a45d14a2640f871a448773545f11fc4f52e1ac6f49da020e09ff5461136ad6db7ffe5ffe3eb19f90385afea821d974cc09d0e390a38a870326500f308d9db96046055fc2b731ec46b85ab2cb979b50fca5f3c57bcb206e01022897474d67856e18c599e5d9156b6cdf807a4ce5d0828e4a037efc9f19afc48dcd46ed56bc9d9d65f534d92f98951659088ff0f74ff260b481d523f961f68f18715809e7d99b26e24ad91d3497c64bd217b5f8515b074525c8148018ac21c1038182228d3ef3e1f4dd85103576a4d2ec6713ca2762c872f57da3f804b6b310c7dbd19bfc3723c14c47b1e2047a18287568ac857d86aeab683336976489032ac5ba5b46704d5fedf7c4501e9203a750cdcb4d905b8ef76e16b80ed31edcd7c88fc4b0ef1514a7e5db8fc9c9e15c58cc25d691622402d99c2f081e8bcc3674f3a6b28e3731f366a81f4106016abb8c2aca72775bd368b254dec33f0801211143ab2dd65c196fadc9bcead26a03fe2d072edd19de44c5686c83d33a892d7a46e0d8c5a2fb62190db7aa06cf7bdcd4c0a08aa31faddd0ad0bef676a4b7d40eba7b2b226442477efb418e0daac42525526ceae9656c5cf4a880190dc2f8131012fc8c5c52c55a8d8029207e697db924c34cceeffc020c05e77b20539bf00dd9a1670f5e4a6b81644feb34bfefdfec1e7419e8fc2c6850cfb3403b122b826dd689b099682e359f3ba429484eecf238d3f709b46b013faf43e0d38510ad70d56cac793aeabb188d7121a554da26dc2b69329824e6277e67191cccaece8a242f505325da8434730a292877b4157ce94602281b8c0233ad86c3ee6ea7969b5b618d42fde2c63e72d4b8fd8e12dab4b696312174ccae3cecbe494944ab3bf921ff2acd86a5c91effdcd0abb58014e0a6cc75003771736c0ea329a404f2fea61f01ae28e292d6ae0516b4aaac2d909cadf82f8d0c5bf83a5ef46c1b81a86b9fd109130720a8d3c3170d2ae62e181191acd8dca8e8cffb5248b3ecff3cdc40ab4bed3d7869616462090667653a93ef581fb28a8d3e95343e7d61f9c316e563918f33eb09b19ee2ff2002efd5088d9b1589bc4026d94eb017f1afe11f9ba7dd85c6cb36941f00aa035ac1f6bf9ffa7c1523bc9f8519b4984d76dfb82ab1fdeb019068fd19932a06ca0a673c5dcd5d02d34514d07a2690bbb1c80f3a93a457c51be5f81db221595f4a597fc208ab497b27a721248ecd9ae82918e5a8d1e367fd8a08a044fb8722c1a76b70d230199dffcacc2b736ef803da3849d33f3c15793a68f0c8ec5fb11d70bf2e95d24997e18798785d4e4f2abc78fc5fb82d00207ea26bd561341ea8fc0e77c8f5d32f6a02d857a521d0b492e720fbd3c595284659e1ae029bb1c364dd8d4cccd9d88e3b9f16623a216bb34c12c5f58da05d20ba008e314062e1b850e99fc6b2fff56f36c40ca1e450dc1b7ff2937257851f2339eb056bfd0b9644be73c08c16e7ad81f1429bedd1458c93b6c3c31d34998f93d69f6bf80b6642078fd91564c4dba8da5f57466a5f09e7af2339fa7c3fe92c8580d206dcdd8ac51d91c0376ed6baf2d9fdbcfe410bc92a4acf69fbcd5a60483aeb120cbd3ce2d9a71db722dcf58686611bf39b14a0e18ec506a514abf07d78730ed9d18aca12e64df5d07c768feafe6729f4ef591e733738d562bf8eea264348477ffc75465175d8abd39032be61a45b94a3bedcb34520983f4a5a04ea356d58d656c72d625319f8bd64cd567dad9a865134ea4af380decadcad3c60d7e833a3d5c262570348edcc6add6012e65af00c281848f1af324f699851bf05440e1604c6edda52cbaf91eea93564d84135925b8764e35886abdd2662befe32cd7955b22cd05d6092bc0d450c10e3e3366320c10daf9b1c9e11522fa81117a8ccddaab0ba1c0d88d0dac3542df2060b142666ae741c0a565d3e4f86590344eb7f0c197bba48fad25a8fbd1ed63cc2a77760f1b0641120212caccb9605f38803", "005352ac", 0, -223476671, 1537743641, "408c00e5ead89c9d9aa98d1e6ec6584ccdf8717670adaaa96e979db62abb26fd"], + ["594f4b3001da72c6ac307feef443140d238ad5f883c774b7758cde4b7068825803cc73622a02000000026551ffffffff04de6b060400000000085265516a63636553b023610000000000096a5163635300acac6a9e310e05000000000465536352d15e7d0200000000026aac0000000000", "51636a53ac", 0, 840857718, 0, "ebb27ba0ca0a4e3815ba9657d1145d28c5ed21f7df430677548229693fffcb26"], + ["9e080608035010858b9ffc1680a88564028e020d034735dfcada93e5f91ad64d14b47bd07301000000030000acc52de7e2ad6a776b02ee98479dfa8e497ee4c83e686a011e86ce47b868c48d0bdd73f6c002000000010072afadde78774b51b703191f81da5e9270cc8972142901b6511bd2b664586db7d12e7cc10000000006acac53656300ffffffff04ce6e8504000000000600655153535346b1310400000000025365ab39da000000000009525153006565635352aff0c403000000000363515300000000030000000000000000feafa904000000005ba4d2ec1bf345719872eeef1a7e8341c4fb9bec46b5811d5058f9905f52e25b7d23a49e0e1430284f4e6f985ce0e90aa53130b3f45b9ffe25977a5a12a52ce3e5bf9bb06a7d53b7c5f35f390eb391da54779381a5f12fac06ff1c9ad7e7629600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c9b92e65baa4dd8454935a81fadf0d74a2f5154bdab752a76ae0d8989f995d96ce8c9fd8f23f4783504383bc24f8eb4134d5f720b610fc4341ae0a4a40022f76e101eb66860398cf822c7084e9cf1829d3fa1a9190025d5f09aefff7596dae82f4080807884dc4829feee3454a431f166c03afc46c31926e61f28bf7690b1db103071e51c6cf460cf5f3cfb689a27d590419b487222c0a732397764ef54c7af00a0228647238aa59d88a877cce80bdeff35e3141a7f42510b37fb3521ccd5bd7c7c80b03f5b5c64824ad882901b818e8faa614b18d39c3c32422776b7acc57351ffaa77279a207a45433bf644d5b4997c34191acbe7cb200f4ff9d4e4f802038bca0b3031ff5addc95a3c44f704435dba98968294e71a08547ed5cbf37032ead78a4c7fd031c568b414e6200ad7eeb6ea41c60bef43f56884f3dce67547908eaa9f922d811032924ada237810eba098ea6c7d0ecd2e75e245506cb930a22b0a2a3682e856d8d022375c6af0911ac3d36f1b67c05815d2b1d231fd5b9a7bb0680c6eca197d0cf7a03134a59ecfb22426bd336bd7d6f216faca54153c5745ce04d3b770c356ea3fa2d71534e42b25190ee0a2931eb12d383e87e9f9e37fe0e1c5007c11217bdfe932a37cf13a04035c29f5dcbd6b7e512b3aebe268444cafd241e4e5ea74b1edb4e7fbcc30e9ec7e17d51085977ed4fc047e293c01a8b0f7babf0ad6746f5739431adcade7445cdafa40fbb85dabf87330eb714b222b091b6584d7c5b8a331216d914dba71542186cebf65dafd649ccdc41833b9116e1cda78d2e1dc1c31c751ff03ee60163260a829599177a0c25594035444ca873a76b469ea58f175adcb16248239798277fcd926e7f2dcb689e6c3a36cac0accc5ab0b07a8abb90122a7df46f1db7b4c1e836e24a0afb7ac1f9abf4fb326785979993a5180ad6335b4a15640fcf16a5ea476af1546a78e6119acf89da88835974a029df50587c7c141bfa64b523e4a64b335188849acb40c82e98a0cd8fdbdf1e5c5434ea61d56704ba1bb8eb59c008e8549bd52d1246a8757e10cf1204daa22e6504746db095a45d80b6213f70c5e4caac29e040a1d4d18973aa0f432b76c9de33f67c4058c600b9a536af5ff7d5f7334ac93627e143d913f28bcfab1088ab743450de2ac9d2e4cf9787cc7c9c08cbcd735d4a99418e63d7ccbca9adbdc6e3108e473d12cb683be29b07df565fc029f8829e5eeb175710428622a42cd2b62541329f254a142f3000da7a9e06f9ad5f46a767560eed361ec4f69d88ec37c0a08914ef31bc7a938a7e0bec2223c67c6a6cdb23c0f2ff95303631e279a0f34abcd26e946e9c4dec8e8ae1c88890e5c04a54983bb3cfc8e7e8c996a73e8817013cb4e39fab83a728046ad2113ed66220d0e53b4bf21b4bf38a17e9a09df15282a3388b1a7aee4d79c1b4d7942ace13c8754d44e5044fec945c5eb63cdd557eb678c90135be6545f6f9f177f875c950b42eae32ab4545f10009416640b807473ab98207f1c143251193c5256f452f5f7f6c7426ad6e2b21a45eb36499e934c9d30726deaa87c88c0c76899094c0e5f4fb489e6e7fb52f4a46f9dea87553beef1b204c730b15b409d7e6d294ac7fec08f25cc1af1b3624f0250f938a9661a07be4bb67a3f778200d038828722c740185f9625ec12ef19cb3329cee5c2f3fb0f53cca2f465177c3dc61da2fd612b96a2da34dd6527ffee397caa161eab4a76b0e484ca39b453416b4b48cd2c91d5b5cb8434b020bd407195464e4b13ede312f606e0b9e84d8df97fb5928f5483f968cda61bc07512b3dbc1955e4d9e11e8329920147ffb5fc0915ad2b2cd0f15cccb82181d8dc312d8960c994084035072679c83ecd15dd06721baa755652db565b041a4bd125f17ea7f54dc58d4ff8db48a00a986fb98c2774d97003f523d630611cabd531de3d3c33ecee186a3ce2d6736ebb2c2e5efe71e9a10b39f1c9b11089288ec692c3b9f3b54817a7512d4405c42de69de9beee2fdf37c9dbd4202e4e25731be47337ed07d6fe11ee8b8c3a953c6f1c0b676d676d9a153d312513ad39e189cdd2555eedc683149ca48fd44b54546047c4c56b3a3591b89d12e14aaa3e5bfffd7c292bd7b62bd1f77a4f0b3b647766a271680b614637500a43ae4f0e2704205aadf30e7e733ce96a3fd21c5ccdbc79c4b08322d1b0784668441990a6b6b92e599f6305bec94b2205ea4ceaa4b018be6622dd347de009363bfcf24ca4ab5bfddc4ab005ffc95f0f961bb35f46684b992e6b3e145818020000000000000000000000000b4126a3efe821510201fcaf6ccda60d95c2892744dafeaa89bb3f0d5d7ac074f8814c5249b196a7fbaabfc50386691b52a8875a429b4bebc36b7e8eb9b8d19afdf37e486cd6ff196a92a992a3dceefa01e211f046b64c9f3778702b1c501fed000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f3cfb72872acfe17de569883a9c7c7e8841fb010cd900c4623429111151b3d520a9737c859e7295f09908e03ce0df0bbed057dca0b536b3ebaa09be0dd89f72edfb90ee041502c880ab74c2584b04c37db3f631d945fee7b7fc863973251d5f97f0f019333e5d4d454992020b70a511d4b11374a3300c4e2999d6487940cdcc0321ef3bfb56e5829aac4f5e4f2e601fed7b3112feaa3aa6bb1ed6548df1ceb6e4021045ae914dbde2d8f28849e067d0810f5cb9fb9d594fe1dd9414888549b452170b0269facb088a0a5915f3f64807a68bef8b061c06720a5133e4a59177234336c654bc9db79428d5feb45e1acacf77cfaa98ed238df67443243d4064af09f9880702302ba9e9af82213e3a9c64afe47cb18e3985dd747f86944a32c909edfbf23a82032c135b800c13751a34b5af5b7e75333f9f27e4f5200bf31d8bfe64872c3fd57f0305a471e649da8e92fd8715f7b5bea72e7871e7868a68d02f78a7b9b082c246b3020ade1544a6a634472aa5d009d6497ba99464994511e02359cb4230bfe1fb10bc03082b2ad4758993c2502ade355d43b332f5034bada4d8efe8fa02e24f9065b288554c6ee66c76bcda25b70f4a58874a12a6239b0e8996aa376240291749bbb9039888e8ba48b1b0c07b505e4c96d42ef555ab916455886e5894b1c96ade025505e574cf8d254b874cc9eb982c57f41a5ae7b0c26861b4ef8416fbe013aa7ed5e3891ef7e90174de0f94b04b18b0e2807b018af0d9b16ffc0d0a65d747315b6c5d75777d015e519fea942875578c1838486653a77e9a1fcf5a8ad81a0a00f35ba0f6fac3a9262148bc0c2c7b359cefdcb6c7175971105a61a66301a724fdadba6580fa7d56b132439c0fdbaeb0f721e31da86e376b0d43368479d3529db159b65e8cccf5b7dc0d5e24c0c597e1e584311086b60a981ed8d31eb3c324a1083875cf7e3cd2140fd2632445b0ad0985671c5424043a17dfb51a52b5238d369aa1d1d31706bdd8d51603646e8e2719391557cce16ce174c42abfb60c1bb454d9a9f0f1b32070351d5e3847eaa8992e780526a2197c1ace2e4ef6f23f010d7ce3808af82633fee667e02172a1fc8f800917aa4ebdcb1d3abaadd81627b7af214deabd3b2e14e3a8ac247515b07d8322f8bedcfe57cd03fc02eb0105d5ae7a9615014196b9cf89581ecb871a07f1a8a7e179ee7b4dd545b986bc47757a038c52943a78f793dc15243262876d28db31ba85b854b181d308645926441d3b7170d93ca73c095c705f9d3d5d41524ad8bcd39acf95604f576d55547c7cdd8b4f2a4689a319892659757ca2530f00fb57df1ad1a3fd1046703640bd6b84a6a4fa339561575fbe6a482f6afb35cb73ac22a48ee98240c2422d1b06422f26c964597ece0bc8c8aa2e70ae8717361b0d8b935f598fa51269bc1bb708e42e8fcf72c9e7ae34fb25a68a6238db0c948641fba7ef4770dbab3474eda55e71a41b23fb59901f067fbec171dbdefe4d7f2e283f6dc091ea47e9beb334a5d7e222e02c1cd0eb998ff4c303376d4865d856fa3722dbcb6b6dd9bbb1ca8ddd044c24c6ef7d715c4d22c8aa0061a509b60529278cb905927ad26a4fb77fd098949b6dddff8dbc9954f2a5952483136750526979e4774ef86b2ff5cdf69e716dec36b677844e4d54401da5904a14b73faf6a64b5b8e42c84b63f1381804898baf6f17283ca9d52715d8588df242634c7f091930da75d1b910ab2341040a5c68e26c4a472ab17fcdd560ff43a566f024ab34410ed315f43be1e9c3349df10229ed4c05a94027002772ef7c566c00c6eefa89ca480d9b3b78a3cea3350d0e84f0952a36869d06f32fee72c272659fadc93a811d866a40192ad0b0c143c466d3881a3444eb02dc2ed241b5a0b20d3c1a0979b1fd0a4709a9e001c278a972b12cc75b9391578d7ca21af81350aa4b34be220a9d0b73b1688c9d86c367add3bb52621483abc775cbd11e52617b2c92bd779208d5476ea902b7ee6abbcf6e459c4c3d5e6c7ce056f2eec3e24767917302724cd125f23dd47c74a12935a8498a555cb252202659026a145181e672e1a69893b431f4104a76a5aec2a000ecbea95e44aa9abe744e2801e260329e7c76dff78377ea27be9099755bac1c37865198c9ba0984e2d0dc1d16e6f1f74aee2155fc1e6665bf01fd5936f3952cc4d82e182b17dc25b51999523f24c8d9a02c3100ff75e37e507fb406229739fc88f24bc941959c2f568e987ad4c364048b88ad8c9ece3303f83974f93e6754fd584ac86393d800000000000000000a39e21040000000093e498199dddfadda537d90b19bf1c230c13b0d6553a1f736f3638220e6ad37f3e932010daa8a3996b5fb903ffd0e20634fa2e799dea18c653a2ad62108f5748499fcd1b19fc683b72dc64537651edc092a96122d1b8c90620fe1a2bbb450601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009e32ada111f22f8b57ff85ad5bcfec0ba1cb88214b8a4901aef437824389c2f0b61a2341dd1c910dc1943d1ffa2d4b776e3dff25e332b8a686ac723b5994ad7162424af18c3b750e472cfddfc0a2952ff50bec4547ca95cf0952eeb5ce8a4f017755594a577b5f9355709e611f166ea9b0e5b7d6da35b1d59a738f2293c425d60301414c9cb781e8382da7dcd8bac07c0a28601bbec0d047b6a5f1fa76233554e60224da35554ad8086322a2284103603311e5cac9daee582201192ad870aa4ec1ee0b006a544f77c4cbfff0e9696e8cf89f0ffea79f0e5e62a2d8b210959651db6eb377f90fa0fe3a1f2d95cb9f7410aa8ad1e9736ac667e70a0b7d7bea14be296bb70221cca07aac7af2879fcb8cc50d689937ab8fe92cc784d8d92753ba5a0bda2781022fcd35e0524e97954ca4ca8b33598e5008f4ff38d866f3aae73a37e3854c06aa022fb48027e151ca2aaec3aa2beb39e98813b89b865f45a47a123f820bf151905702059772991c19c16ba5d69da510c7f75fe75b232171164422d84e3d5477007ba302290b6d4702465bee0aee34cd9b111fd6f69079204296b6511629c172c79ea71578f52d4502a38f13c7df47c41befecc6324719e219b5052d62e3600bb59c1e96c66b8ef1b358eec3ab3424da3954de96c86ac986295a8f41a9374af2b51958866aad7817373fb473d45d527ea12ede722a2cb2ae277f51ddf6714eab7ac01b7eb4a68102e19abc61d6fbdca40ee23989c8d91eb2882a683067cea249e18bfe8cbc484b5a9f2be82a6b167d56c87314710d9139c3b7b8115e7a48973314becfcba13506f57e178b05eb41e2a649c345d6616a24839ae2bde7eb19d10316e717b728a499bf2ea9cc68f93db7df6421f9e96b26aa342121d85d815ed37fe27ac0f56996f68e311e1794262c7bcdba4ea806c7da2a4a82ab7ef97ebbfcc558e427cd25eb28b80d5583660e70e560d037cfb01464af72a63af1f0f5b5451cae5740c5a4347f5d15d3ec5ac483f8219ddacb4712e9630ff21f4ba145d05c659515a464a1cabd9ea1bbbbfa35974ef6da08344f52e23fdc136c035706974268e124c4634c019ec5648c1306b3842fce37786cc87725ab5cbf5da5effd737c9b4dfd12e47d4351597a394e741c191ec3d8b18b14765238c1f4ee2b59ba49c330f336c24b3ca9044db1ef7740d97462d14d6bc3b85f4eb33bf35429c5ae748387c9524860300c52b912c9e541f2606f692bd6830f39a7f1d0599b0578b9b98252de173d14db47ff52ba1d740ee016a50644b0db00419d4ce11be42c76513603664a3e8008cd013804e26b8baa104d05b19261fcb929e8c0a9f63fc7226abb16b4be10b71faf2ee8935b45e8c6b0f9f27f0d2abd3c487bcbcff0db74920ce7043939a8a3bdb6e7ec9645da037a64ffcd7a738bbdd32a13b548b29322d9ce631e82aec15d9e0521e37b032185d3eaf21e650ad530806c95de0c54f869e38c1a2fbca482ff6aae4d768aad59a2d73f96e2d380997445f6c0127c25a5dd5b92252dff2380e90ba8d33f37147c1d0a4a5772bf1af492454df2b4820ab4954c117b7ebe3ad5b6b3575f6d4d79fdfe1ee0325776045df16b0ef1ce383c7d260b972d0d7d79468eaea58391cd09c4a06393b23a9dee598bce71512e92bffa0508392309d2f73403352bced4b8400c204e548911a39bc9557bc81ddaa867baed54c46984ef0f11eba3e96271c82e3f6757200a7ddc13e68b22681f73ce116fb2482288acc72c4534e5bf5017cef8a8100ba40595917096085287a9c490af27e44f272116b595b4df991424053c805aad2d84ba8901e84caa836a970003373ab3699d10660771f292b2efe0d7462c35957c56de0e596fa814a111d389eb11ed8786a1af6bc4df1c95213887f08f3ca8921f9975f7bd325d4eb6c57da20a05ef7bc9a37d2063ab20d086d51e8733c8829d97308e82dffd993da40058fcb559e715163962e1c2d1b9b9d0031f4a8833b5f3f16a8e529751bc71f41531e9e7d65bddc3a4f66f60580e6abd180872060b46bcf3e617798e8cd4631dba72df653aa5151fa4dd2be1ede9c3eb635aa9337483cef458f2d990909520235475487a279c23c67bb3163880b5d42d3a56a414f2aa221a47ed741a316603f555d042ff16102905b93b41a43389802c4756e28858cd7c68ed5f3d3515508c044c1ae282a043adcf146f4674568efea869c085acf9bd6ca1d4a7c453d6b92306e3affb5aa0e490410a1ce4c903f47acede927d896d57d4acbe76501e66cde4aa3b99e418675e5fd5325ac4958918bf74369dd75ce8265ad740fbef935c69046901e83b5cb5cde43946640805afe96594fa00e3478d88e7c66f70967bb5a695d495f5ee5444a9e1ded455f5f30366b1b99cf9483560c56ede8fb3edc53c01b2a16b0e", "", 1, 1166948492, 0, "af9db46eb05173cbd4d41b00e39007044b7ef5e1d9f5bf2f1601adef564eb50c"], + ["030000807082c403035675ed1e0d9dc818f186c6fc9e671b9248fcf78abcdca4777cd731d5eb5cbb66030000000752005365515153a1ddb53073a18bfb926bbf372b0d645e00a5af912927ab6e616d12bfad1588d54cf6c474000000000753515365ac6352e63df008031a418b9de8c197c99d0fd44a723a7b83419e8d9c00a6274fe7f5e00b4a0357030000000452636aacffffffff0251c5b00000000000055300ac6500111e5c0400000000056a006a52533243f06b00000000010000000000000000d791020400000000bdf066c6386f0e9419ac285797e71ff551cd2e94d1715a478ed073240be25fcea5c47fd47238f0bb98f25205c8f2dc9198ff8bedaefc419641522e99df28a3286c63ef2f7a8df6fd641265ff9a8fdddf6bf786e67aa12d5307070c69d1c240bb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000296d69bc38e7127fed3e8c30c8836419203d80504ce90f041adc12907f60d44b501b1297dc99e211fafa8b4194881c2f91300e26297b989edd6e0e13d347ba8d8e318973d45b68aa36c3108070acb72a78a9d02b42246c2d86f189a94e4758ff089a0b7e92ac97ea23f931ad7f883816e61c2d18c4242fe94f9d17b6248c83c803192ccd1faa621a310261911e672d49d0e5b1f9154ffcd62f31cd530494591c710318f41b7e530901d731602b3ffa345d7c545174c1276cc6a28ad04d5a377274610b08f36b8ffcf98016d46347e0812f2dcdc88c5fc0b595afc0c863197525ff0ce901f7d38adcd1fc51e803106b6184526f22b487fe264c65b01395cbba5cfc108d0323c7c229ffed569f484d238ad13c8324d34dabf20ea8fa572d6626f6dfefbb3302290c13f14257651d8f0cb74240e43833c848975d7a52ca851fb71cd94263fe91021821d5b5863c648855ab7b9fb1c9cc521921fbd7dcd993f4705bd68b3d99ce0d031e581652fd44c1c0f17b26a5a867bea0bceb1093cc2b1f346be97405e8f091e0020beef99808b59fe6a934514042c0bebb59655859b8e06c00d3c232868023fc54624b2943a293e905590ca38f5fdc59f39ca299b935e653b891280f6fe934bd33e7f4a45c5e2f432f4c393c579bafaeda6dbd1e08762d99b8834065d153cfab6012966b0462c70df47a6bf98758fcbd7003b41554fc492872e115697c37c9bcb76dbdeaefeab71bd1eace45501ae0cc075cb3c3e6ae9b51c8f0ab18a3688e98443e06d40d81f9eea880d53207dd864c54eaeb85c0a979e881498dcfb7e4a470f906ade29cd9f654b00356339c3d39a0d37c17ab3026297d8fba631e0450aa210915950a1ec3357d5fc8e69d438df1cc013ee90e63e9ac5c9870d6add835265efb79431fff8b1d3434ec40e348968df7e73363e9a32c630c43fac78af81a638df677f0803ec6e6e3cfe3ff006500e86f0b8962604ac08df995fe506b88418e5a14f2d8f0217e8c3df4208e30db54dcd78d40be88d011a0037b66ef4478e02ac4843fe003d002d2f7e422a84fd534be29d80d94fe51807f09d9f216bacb1323132b295f89100c3525cbb377fa95694f93c7a5f2f6253ec48325289c461df383c1f735f3f6d2e16103f317e61e65a61e3d06299f776aff01d59575b8a3e4655c01b3e8b5b5052c876a640271d97ba5567dbcc3e149f76cb1e4b1a8c54e4dbef1b4ed728a4da23811c093a4c5b58b16fd53cbb46dcb60b81688e108478f6fedf609a12f79d4dbf57d350a3a0264e34dad17b1b0ac4045415c1fb73e093648820ce9dcf1b70da2836e32c53667e5e83224f9d52804c4f18a4eadaa788c6091b4322b6ae39c6a8849f8b8a92ada7b61bb66dc1b96efe2af8785dfef4321c13fb910f58ecb8a8e17148bdd1be94fecadb18db8dab42599929df44669001d1944a81406985a70db07d43c2772074322c0b3424400787b06286c3170efe4bc0cb0727ebaba2ed70d80c5d7f62f354e1a1f6783a111d133cd4d5ccbdce236be3a4fddc730e039b1a424599215d7ee2aa2280dc7f9bc2c9ddda1151792943286fa6a4fe32bd09766961a22b86b70d30ca5996acec692d66a3ff21cdc1f29eb82c152f577d253b7ce16617e69885d0722c1da032c3392f1e04c5591e8975d949f54b03d478bd20d981f49f5494c3d9c600458cc8e2587dde6dd9de2cf66b31618f9643ab3c86c1ef8afd7e77d806d1ae9de0665e5d1def637eb90a2727808f783fda553f9e625a99816e66351cce0cc57d52a72ae98c533c135349bf8584170fab43712c81990eb7b48c00aec65ebc5653f77548fec8f001ce277df876c806ca8f4944f85f45f5d06ead37797d7555a6127cd231e5f139d6a2a12234fd61059e0661f0bc799a9e890981d66c99b729b5184983fea2a6b4312e37e0cf047f1955ac8a0e17aff096206c759f724836525ad1f81e4b19ee46cd8a994efb1af9936ac37412b9244f3f8f7e7255135909560e8297c1a1bcf1069a5a36c2574774ccb4acfb53f2ca45e41d64c0e29d9ca2f17997e471ad6fa3437f5f2c8bdfa10cf454374a44dc5c227e3c2bac036558e21dfd15c440180ea4a9aa9ffba03e0d2bb706893d0d450ccd2cfb8ceb267e7b402e6e1b98677ba6b479d565900ccb2e66aadb525a17f0cdcf82fb41d66b27d083d9e3874cf588bc5d8110ddb1c049e8c8dca6ac54dbe91289d084eb5f7bc28767296ae2070ae037e7382507c98208c979bd345187ab1d8f566302817444478eec96fc3b937b44257da114cd595bceac2cf3c06a5a153aec7a8df641113b1feae903ede12c182732a0ca1bed4a56de67c565983ddca2b94a1b7999c8a93910770fa15eae92f9629cbe1bb6929dfb81b9390f30449bdb4b98ebe11361bad7d384e74235527756a8bb48cc608", "6a51636a6a6a5363", 1, -661428148, 1537743641, "9bd87fd9dd7db6a6b679b5324770ed0593abcffed789a637e1186d20c2a69cba"], + ["030000807082c40302d0df87886f153e2f82c72b9296144bacaf7d92f9e658324651a95479e906889c0100000006526351ac6500ffffffff4a1a4db82f2eb26e64bf0187040a70f00cd42c3288d319025e2b9d47d77eac490300000004006a51ace4e23ff7040d6b0e0200000000086365656a6a65530065b5eb04000000000665ac006a526a16ca25040000000006630051515253fb9f4c040000000006ac525365535128ea09eb0000000000", "5365acac63", 1, 906935206, 0, "f953124f6b21a43b57e0ba24b95f2f2a81280631a8119ce9716dec89e0277520"], + ["63e6490201824330f4c08514e3914ac4a16b2b31533d47e640473d07b8590ecee9748c57d40000000001acffffffff04bd57ee0100000000066a51ac526a53a88016050000000007006a6a515153acb77a2f0000000000035352531b516d02000000000765635363ac535200000000034441b10300000000000000000000000096a6c2e659dccd4b824cf40a34a43c0a18fd7563bbdac1aa29fb9d321e9b8181872bb6e1416858331cee79dda1c53595e81f6fa99867619cbc4e4584f62da9a3504675177aff6a4b51450c808a560ef2d660e583b004fccd0d60cee8d944e61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fb3d95c9251a2faf9b734477c4d4733b753b5b8d0d51cb9c6609cc34774132e2ac6c4e10e9793a9cd9ae33bec905b719828ee914e2bc41025f73c0760e0123e9000cd4477d4077be5be16af9788b5825d7630025f004fd189eaf41b62337a1e23965aa95e633e8a61b02364897c2056f050c591b73c7a0fddcf7b478f11544a03118340d9432d4ad7d00d991998822e5c67ec3b62ecc6e9e7ae8ea7ebf0ecbb6d02219b7f777b8a72d48f493fa6bac175238cced663d0210eec7b61a61f50691b840b07d2b847139f0aecccb57759e75a2cf73acfca653a6a1cbb784cec904866660621dfcd256a0537076f2b78a61ecb967ad6ec00107d3194fa9b5b14bcd6d719c4031f804b2493a4d5724bf0080b28a5465ef0bea776e15af2fd57cc188101d70fda022b7c452a75ce8df583b04379802eca03588d681bd5ba03238504bd4cb9bfaa5e030e272e325c8b36199fe8572b922cb976e1aca941a80f6d9e5ffdac4d03f93ea50211b9e28f972d3997fb800b58c3bc2dc335291b51b2a798989ad20d1c5c2116270303b71b15f1aee5ed6e9abb8698eff44e5600fe54056ffcea934d26a39030370a5ea8430ef690c388a739c5287be73c5101b4cce6a1200472afc144ea00d7fd709905795ebffdd32eec390bb957a0926c7d491956daeadb7e8091fb8394fb930382883e8a99fea6525efcf1116643d726254545b8068658509b4c2d5d3db86eef002027fdd03b69cd3db8bdd6fe1c7d39da75a98284b441130b594982bf9197a123eb5a5d79bf245af5e8149991c19b5dd33c79635e4308d6a378b9d465e9ffba09cfd09d626f03e6d5cfe5b4ee3f95c7873d3952c0261ab77962f9d39842d145d5432ed87594dbb135ab5f5fbcbebf9ac753787d1e475c92d08ab9fcc31e3c90f8682ad5a48c29ea175e4dfd99839f6df0952330cba9170d3d4c9e1b60aeba88d71218918e9cdf7f637db99578669d07fc3ad6adf7f3ceef8885b8d72c824e4ab97fbd1792a0afc8140096b8f1c5d3ab85691f92e8cb517556ef5691c70f14224dddaa4bd52aef8c3b60f6b32b0e16e2855fb0323b1392737229325048231d7aa58a32ebcc53d0b493e314bbd55f9e42233ef3e0cf50c3d0855cf8ff9c197cdee44af8f02e5e7f68a7743e87a197dde9983c9af4bb87451832a3195df9ed1601bb01ae311ec86e1c0720697996a7399db5a5311ea4725d537460cd63612fa5ac44a9a4f49c6e083dcd5ff96e663e7c7d37161346bf606a04ca8ac22aa848471b7d9d1f7ac74da72989ad550bbe418a9ed619020e20f08f8e8d9532dcd1e5d19bd3cc9e50a7a25c73d50f016f158c219d487eb32967e13b958ec8dfd64aa62c84af25d92ccd195dc0cefc2413d10480324f15757e6295ddf91c385a5000359602ab06e2512617b39fb4bced96585d37e4b65b155cc2a6fe74b8e4b42940ac1688f87a0241cf802d359e46d14b6b521d8bf2f4f7ab2700960c46fdef717d676e7e2a08a39fa51873518ca10616ec66df421f50faa27b814b567f87eecfd9ac1e3b10a19c230d1487ae99251a24bbce32ff2233d899829a250a6f4ddaa3e0e8a8c34118dda058bc68529daa069bac5bc87950efdeb7dab12e55de5386d554a4b924fd27773bd5c918ecddd1c2261954d7ab23f20260cdfa1ac64a3406768cb73c49766dfe8478b49b61da4b3fdc5d7dc2deb2b0720c8760429549e841476aa48e3bedc340fbb407355923a87d7096ae924db0ea673c53d7da9e2226618a614980432ed5bd1d86527920b7e2387ecd6881913f8fb702e4499fc6ebb3d4c644a221a3f4f03b33fdb725391fabcfe5e23b8cd2bc3dd0bcd0f245522275770fa2636895811b8f9691197ee57381ba6e740984182422195534f7fde6f4f6b3bee80344e94f7f280f531184ae68d8874fbb7feb183c35eaf859a9be2be33fbab6e55204d592d609ac69ebf0c086d255ef75a2d802ee5f667e99f41e2093bcb0f83b4c569b0ef290671cb733c1206f9fbb3e90d2f8790f27388b7c14fdb33d38fc652229b4064a5e38ef7876dfeb34fd3971d889def2db080877279c5e5d542267d3931db89a5cf564483b5bbd6a32b8538343dba698d6e832996ea98c83eeffdec69ef09cf2e33dde515c2112fdfd6a325f3926f66f103183a67d5566596df6b89a4fe987e48e5d1aec4dd0784024cf5ce12b8112c878b7a5f8b09b0df56f8a1a1e4e7cb1cbdc2d70672c1e6dd08952357afbbd7134c0289e06561778b9f2803f6366ab8c1f4ab9e8e293298115f6ccb5ef413793ff9c00000000000000006678a601000000008ec2f6e99054bbc121bb254c20abf04d2b5ac52b50edb65156317a0a8a4ec6c304ff0c8150b03fceb4669f0f71a481eab5ad5694845ba470c9901fa3d6865470462fb5f3eb1a6b26ff29823cd20ca626bd080559df37a184621d34496ce4415a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010872bb97c0ccbe0d6a3dde1e998da10be22719747e6ac75321e9a20381d8fa9b95e907bde6b410a3dcff25a8c3fe4b76950a7474f157cd75590219d9da582da88bf904c0fb8b680435bda53ff47049aab0821e6e2ccac284d0e940607776bf4f81841a46d89cb2636e5be46885a5101e4ff337628f87ed75001adfb5bf78143032407f5ea10f3fc929ced3d0e2fbe71a46f0b0aed584bfe0708bc44d9c64ba121022b02b7df81565cd34c0cdf6ecde2f3b95771c220b1343760df6acfcb7226cad90a07bb0c7d77605aa9b43d1358504c56b927688467272c9020fe90c94bead5e568c80582d1ff6c2150e7a038caa01a93c15055ce0f702ec22673a67c554780ebed0325603add0854b5cb587f998d5288a4b327aa5a09edd938213b1eed102362a0e5031a9577090bb411c3913399cdbafe1d67ed5ffd1756e493384c58c5909bb15fdb020bc1a466d005bcf386e8780e7d91397727bc8bca64f404020612c0d37a3b1b4b022f3d270762ebdb1df96326e9e9ed8a146295860778efde3cfcbc793f4c6b39ce03035ea79c02e78b5a77ad8f41d5bdb33df0029ad18d07de47f671533f65ab1cbee6ca8aab8719d7a075e66cdd2900c1929dbb8818d9e8807100b28329f88550e48a2737d39d4f2517827fd6ea4887f156b1cb24e452560110b7de42fe93b1703a6b65f929d3187aa054a83005eba3936edb11889f1f05d55f1c75bcc11372351ed32e19682a0cc77b23f4a88730dec799e524d9f105b319ea8baf3b8bdd0d0858ed127e9ba6a9949df6cfa353611f389748384a573dca281a1d2dbe222ce0919217e862e0531c95bbde7290358adfef139db98fa83d018af7847d6d759ce597879be4a33833ee8e0519707c9358ecd0d30b83cb056089fdd81dcc475b81dd9915e198c37de8be51ec6feb676ff425d95a1ae4e168b9fcb2a047315e727d41c93031f1dd6e1fc1c7fafab740bc0dfb672d8ddf25804d340c66dfc146d6486f093f16a9afc5e381c90730d9d8ea794c12fb81b0cbcc4b3e55814a82cc0fdd8bbde612df2f40006ebe7df4b90a8e790dac51c508f9e22998f5fdc850014fff7d3f915c3ea850f0ebfd7d76e9a8be867bdda25f6381d24b62d3f5f81f2700cccd897b2137c38ed45bd696763864c9c51871f2e9f4fd495e7bb40f1b79c0e08dc1436c7781a4ef65a4208764f65dc49d8c6ec63fe329d6680dbc250f20c49cdba4050c3709b1ddcf74d3e767606c76177d92f3e18b1305811cbdebe259bbccfdd40b9e4304a706efca6ffac888a761468493f36c42e842077a4b3308b26dee7f6f377ea130568b0837af51cd6344d2cf0bb427b5ac1b4d2bd7d11673a827fbdf9212d972e50aa25e985df8776a75f86eb28674f0cc83522d1b8cf3f075c3acde1f26223684342e1a9cd5d792a95c9beab25a51d8e3361d273644730ccc8255a54337650fa3168f696579fdb9606aafbe69481b70cc42a1e3095795a76c01d988c624d6764b297bb897a6e64dcda5ae7a3d9c88ce452e8b2341966ff620bfb7157a00e2172c437484adebc2829ea9cc31f976a57b25ee9f011341eb5f1401b75abde56968dfaf57e47cb61cc3540fa50e74ef19fa1d24aebf60a780dc7289ba5be97db975a2125b36a66b33c6127db7ec180084223ddb4646f5b3cf3221455c919b8cb44c43f5ad7117f1c8228913af5d5f2d2d3b72b68c3217a96cf777aeea441bfa61d6c9f13be382441acfc8fa1f6238d3f67bb0689aae19f944dc6a5569e8520f210ca3e8764737aa9596be0fa5eb78d13dcb0c28fe5edec52a501c7cd61447a7e956e61072402d8970d7a3bc1f3ea8a0aead18510e91d4b2fe371f45806cd2143e45aad1b3412a2ca51ce5d57b0646e0a53128274d7f1171c9d73b748074551eb6ff1d2885b9fbbd9d44e97896c7d13c84a1ca9411874374e0b00c062c40256bb4827a63d065bafd8bb03d9b84d9d49176d370857689e3081eaec5f1d0b1d0f85eb8ace69cb79839190b06360b5adfc065324f9789b8b8e3eae789866279ab182c8fed207b9acb1396d2175f005f77f1367125204c4208c1384103e35a7c0f823dcee1dc14e89057f9ebfad51794a0c9b9c01974cc28dc0c3904b7120445249d470dd8e62c29a1ae69973e04694522dbd6a5324a2998d0ff83410211611a7bf58e89e0ff992a7241dcf43acde78a0b319144a707a3974e4cc187d6b9c86cccb20ec92f4e8d89869a91a0e2be8a0ddabb87cfcf99970ddec75285d7c5b0f02d96dfca9033d1491b802ed71367c52c32ee60a43d55d1cb05000000000000000000000000b134d678e5456902fc3681bfb8f572deed9d771e8cda5b78608bd3611a1d2f079bc8734c9e13ffc6005810a2af636fdfa04926b6ccc4edb50a7ef6fd9c9ba0b1a7d76026d089fa7dabe5e94656c2046ade241a569ce2df339faa24ad9f18860500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e51e0d739ad790274cc8a5707ff0b5746897fa93d37b9c079c29f5e389c9f5c8b9181a7f5fa89d97cf75089709c3a452eb55d4d8119fbf549d0d76380f15d2a8e31ffd87e718409e9aa7b9705279079c9cb5eeac9881c9915af79cced6df86766a5aaa1daa98e86f1e6ac9406669ea77be50ed9d2d5c6607b5a6bef954245032022d874581c61e514581d27c1e3dddfc5b90514ba145789daa449ed1baf775bf1702267c2166004a004bb0592a76433917f9583afbceeb1010c14cb359c96b14184d0a00613793723cd271cc6b8b4128e282f57ef81adc46965a70ea1736c741b7efb3760ae072772ac310f2d123a29a305fa16489325109aee9be1799eabe2e898ced03066af2491497e9f928b170aee7ee2e1403194297b5630822dfb2401237fa4459022ee5541e974797fd4f823bfa0b80e92d437d18ee9ab9b03e1c6d2f13de132736020d65a5e2451567ea5d083d2fbcb4dcabcbd371aa545eb3065ebad4bb2c088e440226fde7af032b5d4b7ad4d79c18d671bacc10b495c080826312377d45181f2c0f022b232e0850a9ba2437f24bff89bc2164bd11e9eb153d51cf48e316ca66c250e6f871e6506ea7c1afbb252968730b6365a27d3967238779e2b9f1dfa6986cbc4f27d5e139d70fa7b35afc0b52e0235ae0869866fb70e51b15456beb7e93b3c35e99e34215f12d7f81890d38d98784cac626f618291a4ac80ce752f95d77c18786a95dd8ab7f85455948fc3f80954c707804ec3b092b76c5f3de18796a330d606d512fe27fe42f0ed94475814924051b8c8b0fe5f54a95120c09bc388c84b001629452143d4064d95de110513ed3974596270a2d444294fc2fded27adaad769ed50907240bea5b17a7772ccf1aaf6c13120407e008226c11730224194468dfbe0f30a735acb36a4c173915cded74751d964760677e76a41b6046f5bfc1a6f30a35371d3fddd925d39e6112b64056402f1bf42de80c54f260ae92144d7fda502c3b1770cda712205d9053a1c4ad601b00eb998d92cebdea9c41b115ac06d82c5bc487fda24e97399332f03844e8eb1e96dc38f0de98a75138cbfefd420d28aa9fa778467ab1dc7834522a36d05a08d27fc7a0e25bab107b72efa9deceeb82b0aa22a7abd1c8af85a280cee910baa7f8ae395f36b1bca9dfd2b17298dd11f2465ad9c11ddef55409f38eed8a84fc2e7ab19706e5ffe1107a1bf41611e0da95f9070635699f24f600345ef10989d04d9e5deadfe04d9d5da54e104b9e7a1939d5c39f71ad2ec932bff3c9ee2431b97e34666d2fa273d8d18de25981c440861fa37e4dd9914c735e1ddd9121877c1502d535ca636c4767bf7d25f496fbc9dd7d47c2638ce49a18e7d1d2f7294d9a209f4248007977063887eed801dd99642571eb82ae72d4bf615a641f5ae1157ee1101c61159bae55925e389105e5efa312b20217f7a16dcf531785f55ec630e127dfb1d2ea937973f5f671b208994407193f029ac68d625fc9a637c93325f9607d76aea7d8fc40c37e28e11940a8260980cc9b217a95e889d65e92b92e6d52a8259f9b119ce7a88094afc538c9d0b1a9d7bbd41f83c0c09c19e07faddb3e4307ca3193b055856a207eb470bef4a4285a1edb442d1fbddee14220552d918fe95dd3f3fa96eaf5a9f77e1e76563b4c66dfa08903750bf2ec257d12392301065b3ce1ea9ca038255840f756db06d48ba10d07a802e4b90dcf2abc1e76e970c2cc139d79fd579334e578901491c07c9024cc4c01aaca04633543d2d3cb582e209a49107f31a7c536c95eee82328449a514e5f7dfee9815a08e3fd1d7bb66229f6ce8af44cdcefc31aa09f1c53dea9a40941697309ed85f8c66e5589ef204b8aec1d7f861035f5deb51e36ed23cbc7b45aaeec2a62f6be06e0efe8cf5adbbf0c8870de138af81ee6c92aa3aacc03f4c5b967de6565d03c0aae2ce85dd16eb98a120073112a6071316f47300be654f3764eb49636986b869b7ff4426b4f771dbcc80d961da84341f61a4f7fdbe99e5700e3294dc2e15483a674c5ab72884c345ab176e2069fc43d1832bb6cceed247ad374a1bdde1c2bd38a1382cd06a423bf7ff5ace388bcbd82931aa60476f9b5dc9b0f2788560b5c9f66e3256348187d494c869bdc3c993a255f714aeeb6c022174a2b2fa34aaa7f47f5183a0eb82118d0b9ee38bcaec7ed4c30d03673a600a6f65b8a5641721da8b8614dfbbe09769f95b26ea9ee5c6709e026cae9e5da19ae1136d6a005642c1343f592769895918a18f82f624d5342c79110de82bcf1c0125385fc83771cb3d638c34554de518280bc03da876f69ad45e871b24c99ea22565b02870171b465ae72847af7871f4efa157888c458ebbf0767f94122d14ae0b4bf9b1623a00d647db0bc2ee760fcd4b3ab4671efb58f88ed14ffa0d", "51655100006a5151", 0, -1863630669, 0, "9839b0e31aa81cbb288e20dc5a83c05ec197d1ba9a2bd59aa63290ca89548e04"], + ["d51fd12d042b36cc97b5e9d6a61e631b26b6551f8245a7c9925a3153838081fe809b62559f0100000002ac539180c3c16f7c21200b96af93baa4380ad573000d2c9e67bb38f3387e65835308b9857da00200000008526a525300525263c2a4f65a9baff9c8a5629874906e997366e4693fc50798efe8f5b9ce9a9638fb409e808c0100000006510051635165145876b2fb52a0458e8395b2e03bfbe1ba77ecf7567d372e2d5ee4824867e2e97e53a325020000000965526a536a635151acffffffff04417d830400000000046a51006a09bf2f01000000000800526352655363008412e502000000000853535365656a536334ab92000000000002516500000000030000000000000000f5eee9040000000082f54f2e70585cd81f2a2ffb8272373e6b280b34d3f16e665f195c3b1a783f4c7533732691e137dadfe1a15ece73c90cea6843e2e92350aec8217e04625c146223da9d73ddfc7c3b7963041f155ff05833cd1daad0ade5b93f3dce9ebe53c68700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a8a2e92c757522dcf47783d97388726f33be29b86f05d65b599b110314801beb99e18a621567bd602e76430da9e6b2490a6feacb5b8f1b188b6daea7cb6c4aecbd4e47053571735b842e0e82900399cc5f0517a77f044be04b30c13d48a5815fcfab8ac6b05669803ea0d758e18702e8960106bba9e097983f3e2e1aca25e713020489496cf79ba17a805a6002bdb6f349a020aeeffb5778d93abb8f38d64aa84a032267e721f12f66b839d155003b67109dc5bff1dba9b1b1a0b8c81c03792dbbbe0a0129c1280f5a8851c4252cce19c1609e317bb232a953019f7d0a2381c733bf6f693052951e339282348ffa5830ef39db87f08152684b9744e4f56e0b4316cb570205976f565188c9c183c24e3f02f021dc5b9492fa32dce286f64b446b76a8587203014497ddff6c10c9ba867a766fb8d89e3f86d8c881c772c0e4e600b718718a17021c10a3d01420dccb7026543aeca079cbfb60e257a04d77e467807c08067537b0031b75107ece3ff97ce048fc4a0f2040eb282ffaadeb8dd8787256e4af3de7cf7e032077bd37da415f2a61b931ed8e98192ba53cd4832b6ffaf0dffd293a69b065084ba76e9eb0ce3e300e117f0c3072dccda3f21548bd659c7c7b18c6c0bdbc491f27312e20deef268f3b2ca8561474d8a28e5d90b7e79d7292081e2a55318daf9f7443396019f490c22bf0b05f58e79efd39563541edec68d72ead38d3a06db341699a7df6b33cd0bd28370cfc41135a6268c847d64074f17682e9fec9a533f02f80518371323f406335522bc20052b5ffa685cbb8e8c30a28ac43e4979dfe196859f18a89dd1da01f58ed6128dabd0c2b9c1ee53bee288d6d5526aa903207b1690f780f2695b1cedd5580e6c2039e094a7d71059ddb19b16642a44262ab89173d31807113f30ebd16ac665d38e4d049c820d4988b5ecd7278a6142248f9abdd0be154e08c7eccc63a4a0846044726f9789067b73b1f87b3a5d429fa267c6fdd4a779cd238f3f328a41aaf5a9ad003d345c5af48c260e622a8c80f1d96b735c61bb330e725fb37182a9f6833ed5725f26d9ae73312f1db304893bc3e77dd51745c98c0511c73df34e273eebdf8b15252708eaea2aff91e7f8d36d5e941ed1e4377823c037b0d1dae05ffee6e29d7b0897e2f6f1d97f1148118a91937dbbd07c00399f14bc873b225a150b13a61c798deb37b888c07e42ef6fb07bee1648a3f6569e5abc3f57a32702215fb44b3c96cb02206e899bf7b7a0516b63466b3fddce2cb667fbe4bf4774e9b6da91613c851f6b85551809c9354064a7a6bd3a54a630d0952e44a8d7a51135ae2afb3f2c6b76175ce50c7900cf7f38c828b198b84f41b18b81e2de631e92de977e449014aa55788851353d60f869e8e6d814afe44370cfb8676df0a481a40fccceb3d94dbf4061fc5489e455da0c396008ed8c5cbeafc972a62a4278266878bf52f20574004dae4e12d945b5a393c87b601b91f8c6b3b23b0e9ec8b443144e6f8fdfb5b3d8583bd4563cafc7b2cf353322139c918188a3664c746eac35c2a1f9807603a15f95a619cba92c8e04647702b893f07d9de81f6f4476c6c65ee6bc4d934c9cec3d48e19d21a5704a89ef38c5050281f1bba4150fb081fd948503599211354df2b2d658f86b3977e53b7ab2d3ac02fa1b1669168a85993b511d41745fe28180a66bbf3786dcddc3d881a8c958529f9de718639317d75615dc6503062cf3f5faa42781e2bfe38cc915473c79ecc674ebf4ff9d83a901e16e6a1cf27fce26414caa316b742d880701c617e8ba8ec790934e912ee093a1f5e4bee20efbd10527b23ede1c2df67a758126350b8dc64484d095b5a3f8b364b03ee6f8c2b5c9fbd3dbcdb00b69b9ae332816e0d62a217669114805810032c8e2490c7193ce44724bfe4233dd4fb6c0c318c67c446a7bc4250f1941baec146c8e1ae85431d65bb5843ac4c27c119eb5451a6fd7e04047aee9779dae3924bf1da91863dda6955e0571f131201ca04538898df168e224cea0c23c57303767361171fa672a7716e7b8a98f242f8e32951fdb1bf23926f8b61bd95cd34580f8913b4b82b68665a0524ef63baf93503e7c94cda248042266adbcc5e1d70e21bcb863303e0a986683b1d71b96633d3452303fab2d8d87a1781174b6d97553e9ddc8c3b286b1580f3a47e68ab574a3a9beebe36fa36552aa4821a68284bbd8331e57ce7c6974a36a931d8a4691b5ca5330489d14e2866305e705d96b44bf418afb7297224c9ebf935e8c5de1d26d156ffeb1b5fb1283a03000000000000000000000000b6ad3c7df1591e7291166f3b417e177598124ffd116a72c02a2b556e0b059154d6007c5f8814e5514832f0e242fce2c75811b094e4f6ba328d2b18026e7c5b7e48da21662e6718984dad5b0c7c1f534c285163a52d2f563d3b459aca4a50f570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e66b4ef1e9d62c1363b42a519b2eddd005d1c897d4d20d539389cabd10bdad39c34d886a016475efd63ad913d7546f217b960fd7ed16bf1e5fa7aed2e751dc8c1f084526fa776ec34c381e0ffda311dbfe8e6f1e7fcdf4a5886a0c0744908fd8609d518d0452c3469b0a0f367631d876067d4f6835fe51cc41715468d4f8e66021ebb6bf168e0eaeda00d9dfdba5d218be9717f575d7e8c1591610fcac45b736f032fc3163cdaf2115118230fc9026c0c5fee19839bf74df256f8685f26a02430880b00bef1f3a30dc1427e83b525d207bfaf0d2f4667464f1df3c90a2d037d7c36aabcf513833a4cd2f5c727af4f028aba18d6dee23c9bd7b19b98f6c5c9b478b125031eb6d605c42e732b4a45c130799177b4c6fe489c801e45c44bca61329237958302251dcf459e6ca8fd4cca4490144870f3035c5b1f3cd1d119245a44cfd085c94a0214987a19558081ba73ebd35fe2ec6e92e2ae7c3326f000e2b93302f02b043a180300de9156cafab4c52d554a3363a4757b18319f9c705f9b99243b651455000d9e0321c3ec01a9c91b0783bd3c97cfc8e22aa8dc8c34d837304137506390b6aca213e2a5bbc4fd2f746aeef7fc9abb7ecc38181655e970fb81f55350c2520165e70dfce5a47c5db4927807a50dc6c1531e74406b1a41ad166c1687a5f5eddb12dab452541ef343a8a0b659aaf9508fa7fa0ee379db855a3d0ab2aa74186c7fa6456150d69479bc4b1b93553c56e5033b4ed8f9db59c6347e4802f833ff096e38abf3c9b7487e7deb811d27bb1490da714a31c7f0ab5cbf043bbac4e2b4b41c440a8aaafc65ac9daa7b7c1cd239c54d8093b853965355f2ddaa045bd39d1d35531abc593c19c89c4165f181873bfc23ef06bd3d5ce6e3fbeef2ac871d1f7f476b62f95f94e70ea135fbf208ab16b472ba95a6121cecad886a098138fa26d3663cb018ce132ef7826cf94f1a1bd30cd642a5751d68a0892d8bf71c1e461ae78fccfd363920270a372a8a6c369de43eecde809d422d06593899c472bd5e8f11a102f2da9e81d5c10a34b0fcc7509b70e266747f4b33265c4e00f97e1473759cba8dbe6b2928c4704cfa68c1bd7610d1a986f262e6e2d3b9851b49c26a0d6ef54866d5670e01bfe4dbad47d2ab08edb236c2cdfddbcd08a81c568b32fb25ed6c53e7186330526475a4d37bc552b520141e30ac27d22829e2871a5a60759b5423df44c5547a3e24700c4d6523dfcc1819f491c09bf005a81f02c853f0f5c76536b0a7ca7210a025f6f39f2fdf1eccafea1c059b19a64243fe55aa53d417bc310e5df3034cc71e3d80b6999a9ef033823babe244f7447cbae6b37e6d6d352d285e37b68c4e2a6c2eeea7cd658ce4a923e103a3949471cdcae885ffbc93dadf5e139c433d5b4397d7c112feac8a963fd6956109ffa9d14caa84039aab274e070eb999c4efe8f120bca42dd8c4f32abc1d67fa58535add1da69da24d53040831a73c47fcc56dc4e2895519bce088253d49eb22a4b3a435018b95b5c44a9ed1952647ab4a3e39575d43f2d152a582d6a45440c076e7d7536f05737fc1d3ee3ba310727204a5d3f7853b929e0343328a332a1d46b74160451577af87d6edd87cdb3842efc87b6121fb00e12a620bc845337e8e61133781c27444556b666d1bdc56b907d03bef99bb74a431d23d66dad6602d0040bd7240bef4a449c5e8325f8d500d954bb6e01386f44dbf84ebfe4b6863095c79ca1243680fa1ed7471d2151eb91fff9e5fdac07f0b25f823c3421442900447539de2262b6e5bab28948f2169fb93403f978d6500c01270a09301e15ae51844f25f3333ef73351aba570c1b8035dd7b80f4e57998fe125f06f6699a0c32c0b4f714f70d3aff2cdc2c1350d49db463029d9559ae04fb3b775e855c4f5066051bc574db9d3b01e2657de87bf6472791c6205233fc8d145aeceb8ae629c0a17460f6eff08a327d5bc9ed4a0ccb59ed0511cb6a1695101e286115702e92948b86149ecd3750d914233d143949ec95df12a055b9c4931563ee52ffcaef26bb2bbd2c174bc90d164cc34843f9a311eff4084860012086e0b449474695326a10f5bd871df472a1771a0c3c16f1b0a1bdeb7cfcb3014a21e85296329f9c39abbec734b0d7b5ffaa35ac9c00df11accff916d66186415870a7cf8d16302447025c8a2103af9be8506ee66b2761575e4262c9f8372f26fe2a6232114764c9b4c85c7000df0228fed28d8e103c8a935a6d02b0855784c6d072a4b1fee1dc3ca873f189781f2026f3474ebd0000000000000000c57b92020000000094a2a169ffeec8f1e60c3f161f22e7b7adc645bdc7ef45cba683db36f55356b9802413e88e98af834a2bffb6671747d4de56ba0d44227a73e8b30f51cc90fad8ea2fa88d8dc55253a277f9bfeb59279f5edb116c2749f1f11fe69f5022905e7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204975413bbf202b7c173ff7abf041a47dcfd21dd025c68800c002c2649a1b2e13dbf74bf160552ee067d1f588d6074db47e1ea7fb1a9804b09d0773dcc76477a1b4d18fb999cfaa3e70be5b9f1eb307c98bd64e96620431bf4199faf0a1f21c6d4d592872ce393ba4c5de6234b66c86fc9165c2a1a59b9f13acd4dd33bdfdf002132392c98a94406c04a9d3ea4d17c5461e280408686a6b3af96a7673a352fa75032e2ff5496a5c03d17401f728e957f6eb9985af67cbaa4823d106f4d162e864700b082896e27bafbb4b925160a8e708c6cde5f81838f86278ab6426dba95f0f44ff76d86e75c010a26d3d34ff5dae2f414c1b7260ae78db55fd4d3fd367541798890217e938276d34c76de92e5b936b6781c9d83a8b17a2902b1b87a2b50f985182ca0326d8e4233909fe71ce7b4d31bd4a6eff357ada50a6a4ba0cfe36dd9becc138a80201902975c4fba05df42dad5557981096104233ca8996346ae545bba3ca48115f0210ffdc9f0b0a90a910222ee24f44d7087e83d6ef5aaee8ee80bff1b3ed671c5d021291b90104c79a8c5159eae88342fade902f9b52af5eafc16d2eba987bf25ca37e1851e5db885318301e842b8db9256f008213dec8f698cbac3fed5a8e2ef15ff8f2aa3aa8a4bd276e2f016f44ed69af20aeb3c27b013816060e4623edde723d0f9f5d08a117373e0dc3e4f3d67f96e023c5c00b955862828684538fafb6809da2f7b4cbbc53403a015749def633f6d7bb70267f284c1d240dfcee95ef5b8010cdd5dfe81eadbf7c204abf8c74938ab61fb4664bc52797ba43883ba85a06932b7fad934e81bebf329a142415a8fb77f6dc6a5a5f07f90679117385bf969343f9764af239efbff15a13d1742a66fc888ab3900b7d1751f40562e033e07c6f0be3c0381fa3f778f4261a83ec30b33de7ef7cb4433e39717ecf05b611c2f13fd04fdc8c6cf8b8c7b8dfee9a72207fa90837c9f41a23c30a2580463e199d81010a86b0835257c63146b192ef743c7f6fcc4c941ce446316b9c6e74d535be259a29a03e233f100f5585dbb74269941dcbc47ba828f86831db15793e8efbafe8f1cc4e844269e61ce0340162c50e7f54dc60861f0dfbda1913f2869a1d7411d4bade990e43dff3d71760bff87a68d09c43644de0d7722162214ebba8edac94a7531543ae8ae63b1a057fd5aba96921f2bc12a5adec009c13cad0c5d36d69f918f9176704ab7bf1448baa6e170f3d9ad97aa5379d796aff918a71eec6ae1573971776b305324001a0e8bf448edbf9a9ef65264ede297c3e10556ca1b23bd67d7cd26fbf7b5d24c08a05f366cec34aa8bc46c8486d8a1ddb00446cf92fe3d7edda9c30f3a8b828ba89554766acb2c7b5c62d20fc1b22a9ef50bfebe0f7ec798f9c53907212b90c12dfcc4a0003791e7f2797eebb3d4c848a7bf39d5ba2c68b34cacb19566e55c96d073a2ada477e3887e3739b9879955e55a007a91b7e719cd0c2d09c5d90b2424ba89841a36f9bbc5b8b5446c9d7431cc6dd74cc79eb7f1e5cff01bc8133e39c2afb5a52ce707e68bd90ffdf307dcb130151ee73cbcdb97145deb764d6c1782b80a72646fd7f0396209942a6ee3f5fa79400efec72fce6f8108de6db71ae960371b108b487050e74a450f15ccc2c24849f64bef1f9b681e8444b35aeb758331fef99e8cd0746c580e89aa341f098f6ee99392b2f4179849e7114680f76d8d4fd404809f966dd422195c7469e3beaee893d3f1c1c6093b916fe3070bdb56291bda11090171774f6ebc94af8d67aab342cda1b47cec484794e88d09b8e7cc4f56be201645d31eb82c0f9cb7a3574c973c17cd1441819d4bcd13568df9165a4e85d8c021a5f44798bfd9b81c25ed25e74490581225c13693ccc1fa7cc2d485125709e2a8f8fc94b5856007816dc216e3e3100d0e9a6b2f13f79a9a6142fbb89977566db431337b1edb64d2944b7167805d2e04e3da25781d4cbf6f11af5b00d4c691ba356bcae4341cb4adc69ca2624ba91d08530a76c266bbe760d79e7610d6e339c752d2585e099ba41260ffb6a4a887e3b7ce56d5b7634c0390ff883df277117ce3b45ab4350a6cf31699c2b7fa0a18e1744a422fabb8cb31e00c95ddeb580e6c5d7d6a6c27357bc4fa219f0cd8b5b466c682087442081b0e3811eeb8d3eb36e8793ac054dae2082edfbeeaaaa603cfe6180970f1dc3318b47686669e20414f4965ef445fbe827eb04241dab328a94337735a4ce9a0382c4eaeff543de2c08539cb318f3698d5c08783f3b036594286c19858264a5b0dcf0057dbab172c602062856237129493e968baf29b2f264f05228137f9c26478009c3ec5fcf04e1001e78f3468564dce0bb9aa6eb886db0b2a9ce4651ba7852381f31d93ebbd061294f7373612fd404b3038f567e3214c109", "52ac63655200", 0, -615402274, 0, "34ad4cc2f83761e63e9e2003b6cee22bf0d0ffbbdaf5a188f0ae8c32d37a7483"], + ["b343ab4b0327f478f36a63920e47d8ac49bcdf4e84283e7f071a181468451b0c2dead067e700000000009e4c313b9f1c31dc03c0e885fde052521572e9f28463af080554078f3369a676a34cab9b0200000002006affffffffef32edafada28f4c318afaffb30346a14fa5d36ab45c5b9620903c6c6afb0abb0200000009536552ac656a6a65520bf3af38013b25a004000000000453536a53000000000200000000000000008ed68d0200000000526c68d33aa403fd99d8fa323d31f50a6933c22dbc7fe1b4dabbbc7aff21ea1819f53ece18c32aa44591859939d6fd19243cbdce5659041c5456f6cb6a4eb0efde79efe3b097871f5cf8c5a4e50c7e9bba8bfbc83a441b9af37b3b6a2dd6e66e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8314e22f60060f99e38f05c17856f44ce754af2d486129a9ecff91dc46da07901b79913606077a3618c6dcd8b796a7e249a9f81f6a6619b6b92bc69f86a4978aae0b46d35229238be4c59af5a154d57d39d7a84bcbe14af63aeb2d34d9a5d744e670d3cd08afada6477cb98f94cda60ab97950a5e27d2ec2c58fe5963a26396020a7dfcbbe606152ffd88c585a836fd07cf7c40815f784657c4134f795fb409c6022e951921befda01f1a106c6b11b1330902d9a1c27a4b9588a5d4e595771752950a05511a26450a21a8602734fac0cf560f708e57e6f974b366f101b1520b8a9356f48d3a88bb6df4bcb591323fa8c86c64639cd2f867ba80031cbb8376470476370310359ced5aa6d08d7bbd2f4e4e34b3e2388f82e318ea3f6e09b932309a6c63e20311f3f422c2b41a0433ff5d3e4047074dc6bd97fc591c32856aa7910c9f7d91c7030080f5f6be494dbd63372c8780dce1a9a846dbe8fd190ab079245672255916b2030e89522abcd995140a89f80708f8b58335c52fe44282cb9c7b89a78ee6d89f8902271569b9841f2a223acec316b3c338ac8ca1a463a117dcf5d733a5487e585d96fc9351a5a3570ada6c8e5205be477ec81e32d7a201f002f860c66fee95a0c66090a9e84316309be6a7012ce6af789d258510b1dc36fa891616c4229c85730ee46957dcd95a9c30eb46b01f14ce9b8e43b769ea1d7ceacadc2a66a7d11f824461b7b5c2052d85b81fa5b84ceb504d8a4904b27c1f48540c1d725459e4a57e139451a510d82112af6da593d1a0a07c44cf546ecac6c65422b13496d178cddf4e58764ced1d57878fb7cd76f8d3948aee1281903316c984ea82289cb685235ff02e39f9d74cf99de1f614e20c8728f32dc23dd55830d8fcfc1a0a798615a2990bd61864cc391075218c6057ace746056c6cbb41405df2d7b560194188852c6efb11c4bc9621224fcc991613f314ee1d9178e1cee74f6088b7cee78b64f8505786fddb6fb43e19cf70174f836b0daf5061e9e3b6394b8d3b070f733e799e6ffcee5b57b8e3ede2d9ac9e674ae0f63d4c7743c2aa383330efa5af06174a89dab5b52c0b759e6666f7a292ff6dfa452ed044f449d6507985e0858036636e805d08b07e870bad3d6702d8bdfe56d374ae86dd4c0434ccaa22fed19d2a918df78dd4f36af8b1e694add1ad74a2fbdc7053fa79521da40ab3a260ebbf42497c27203604872adc5b488205fe755bc67f22d7785fa574055d2d103d0ce2ed0f7e8aa9b8902ddcba7372123c2c87a549d74ed60c22f42447833413089875ce93e86ff52a442dee3b6e8773a82f39f477b4a0b6b13e4256be39c868de9c6c99e13297feeb6c97f453338b69aae6017a5ca96aee7e2133211e73913a70a05dcf8331ae1b344320cb3b07f1910193652039de0977e474ee97b7a45153f76596d890243ce601f5fc4c1607c4fdb8e2c9c6fd130b23b76cca4969c01a65c1d5a91b68c850a81ea9b751df87aba8c4da0280415fa4c45e2e88d99858c069839b2005a52414b9abdd4cf496ca43712d12473ebf81a2ccef55ab9e11e2bb191c20e4511a8c4b306e72554092de46cc592207e8e67cf0da26c752ee847ef376882592ed373672db7c5e88cb19d5a16eb32536b55d0e349f8437fd957e1fa89cff02552353b5bf2c79c649bc86e9d76f3b31af8609b78c1face726b8f6d8ae4a802a802d47da60f9e4009fd9610ecf93b2567458b378451e9a8a81606cf301f8f4aede369fe53cc92c983b6bfe139871a1d1bc2d61ef62175e60c4b5e1f2fdbfe5079c0c5f44860892919c0f1f092a821be51ab72a26d3e842aedb08e6febfb5785f4df25e5717938cbc4cf8a573ec623ece67a669c2dcdbbd29c688b19524d18a4a92a2001f2077548e0570743be4f23e17bc72d61586f2526e5a82de8e252fb534005860f8f6f1384aef0f76af74a2a71ae1b8762c1307608cadb7ff5ae110ecbb580bf25486c53fc8d2f0cce60a4dbcf62826fe121e28f6e4e617d841fc1a11eee3639b6286ed0cf01e84b676380e5c7eca5efc49446508908bdcdc756bcf0a40745c2aa9a96e3f0d887ca358bac431d9c894eaf0232a20ef4f7d28c919126bf1750947c7d3dff8a2b82f21f2b26d005aba4443a6372a85f096c79c4842e981d6d4aeec6062f9c5b6fa6fdfcdb596273ecb2a496ae0da7e57dac19129db3d6db70c67123437126cc41bdff8e8cf306f68b6e59e6be457d24fb0f5dcea53fc9d0b061e0c9fabaaf64af9a06d1dfca105c58e6dd10c35932b4a62cf1ea6ebcc030000000000000000000000009df39a059bd884746ba1e24c45126608c9f15e2a3f2fe569d8624fc9342ddd5a05b09c0d3d3693da443077b4968a5e219200162626fed96313f0068c2318d57090909fd17d30628c6d0b8348443dd98cb41759881aee927236dbca6b5896f02200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f184a2075b2baf83bc6bbc6b4907225c4e3c1741055790a45c1cc45f9534666b19e1c4c1789fae219b44bf9864131a1f0d964660c46606502e1dd4643e1d38233b211b3539f1da5716472500f5149f8aeec6a5ee69d6ad4d3a8e892e5680dd3d3409ff9e064e04e34f36f8571b2225960d59c4f87663f897bd420b5d185b5d5d03174ead75626f14e66c5b9fbd8d5b1726ddf629ebf17192789960a0eb2bc233ec020aa5cbdddf74b263203e239a74cf5d4f5d1be41772d5e17c17888452c3763e730b02e136d55b9d8505b781258ea3af6028e847434110e408449cd5fb20eed644ddda52fe05dbfedeb30f40867c6d4246bab298769c83ce41f60dcc5b68ddaaa191022078907e101d4909c8079716486fe4def40697a2d3617c47d98f6e3fe38c72080306a34a164e8479a2c46379cb2e7fb5d2e6fe4534dbb8a347b1f5fce1ae0c8928020fd519dab0f7f236df2795fdbf4ec98fc48aa2c84f5f29b2cb3139d9ed48bcb80222f2628b3e7860336adf4f58c4bffcbd499d6ef63f14bef08a8fe39ed5da3b870312f69c6adf8aeb06b4217b5e11b395f200ee684be007ceea879022918f7145b1cc9e840b8e98f0776cf985af648d508523a049fb776e5d55f14e1970d5b782defd0f79cd8164f5ff2eb8e34b6c504ccbf0f5ae7b597c3915a03e682995a0459f82dd4f3f4280c3d8c176bb5a4bf7ae2cd7bf380c6db75fa40a6e8a1e00b9ab780f2cd51a37af3f83d9cbb3971fcdfdf1edba67ba3456baa3fcd0f5c5a1a59c760ee9ecb70498345bf30b967f68cf18f4f718aadd5d5fb5c627ff17a67de116aa1254f4e1db25be7188879c6b1cef547848f2bdcfcf9b7ae91e96f3db2df1913fc762a8a603ff93e49c7e4e6f1409d3dc1411aa5cae5443ed00262a8663d0fff00a61d50cba2ac2649736eed65f9e7e2cccf524ccf457ffd2e711dcff6dc1be359b0e438744b86e878afc32eaaf682feb8836992d1ed96a82e0ad0f5ce1626ccf77e1ab22ba0415e7a7c904a8f50da3fed29742cb514232c09ad1ea0331ee9a0a86d6ef8f5add412ac72d9edec789ea29205c10cacf30f8e64608f0526a7ef40d8881e5574e0b9ff901531d5775acb62723907d017577c1b4e69e99732f0259c7ba83f05171569aab5aa9c07c1651b50e8a8b3613d6adb5d1b6ee140518c8eaa67db363380110b800d2a9dbc5bd6c00e7b4959324f8ec0f2d0120af3c9911d2baa73364dabadc5fe98f966aae778071241c490e9e6849437e823f26be056bd0645bc12e295ff815a51da781815a510f011b52c7c668254dec3758320bc2589a592736406490a011e98f436cc4ba5a17c339b01ca3efccc9d3bffc13cc728346379584a039f1cfe3bc398d8656594cb047531c88e3c2e9823231a7b99a21759ddc45a32281895bd76c9116217187e732dfe4bcb2af7cea752d3093f280910b6ad87d2913ecb5d0858ea0c992e48d7c3464db784ea1faa3af72ab5f62a8c6b1c650bff86befa082b93b0db5511da40bc2111491429e9ffe10bbf6fb0b40efb70586018fdf029e2ed4f54dcbe823f4a41d80d071ab02af39cc8acd483ea542ca7424dc87201f90600d14cf875262d0fbffe45aa3cc8023221da757e721fab7d6a7442b85408e8745ba944594e187766c8bb3be7cef555efa9dda234cf8b46a0eaf4b754baef308a2e6252b02983a41229201218780d7d43c40a8ca847f6d9c520e322198dc62ae3361bb5997ef53de33fcd404338e4715a70ae68bc8a54b874c46407b609ec9afc61317a98c82fedace33d737c5bfc39811098b3b50cdb9719390227aa12cdc318ec5c6c3a0f3bafe4dd3a65f249019ec4bebacd44be8107e01f4620a62402943fd6347dbd040f053f76faa76f3f256174dafaeb6d6e5b2521f3e20fb5c325f28de444e4e6b5346a44131b68d0d6d4329ee2ce47181d8c97704f3e18213e8e01e125984e653a59b663b92586d1e8602e2fc12d830a0ea68f72d2e852fa3aad506ef36d98c1942604dd31414535b7d5f4784824d599a2db5a14544589a438eab16db0794053bf25d4410201d4cb5509bc6ed430651200c14f668f1fa8f215dbf8a65321063dc3791d68bf719c2308767c0340718a73f8772439b09bfa7b24d86e6db0efe8ee43b53e6da0ad0c1ce8d51dd7b3ac3e0988d66b5f8b1ad3805c102a20443e1eb8fa5017234fd54ef79f0a0c5fc8324e6329fc445f41f2ac95385de81cfceb75b25171a67f22cb2df50c8678ba191c28da3b45e3d51f945287aec1c896950eba491180c2242631f23f7b8f55cd2cd46726427b2b1a4d634bfa00828587259d7a5e4640938942a81ae301da8a488a002643d699d3c0c9e869273537b612af0a8a8925e40d4a1016a6b9b48a46d1079e9d4c4182bcdfcb7d4c253d836d0bd367f7c152ebc828e18eedc09", "6aac0000ac5100", 1, -1066185786, 1537743641, "bfe5fcb55a268208ce28467f53b8d61e665faf450d8d7a456d09202aad76dd95"], + ["030000807082c40303429059edc86aab8801774ea13423303f89dfc8e42d04cf0cd2ae0b20e78cd4620300000009526351000051630051ffffffff667622f929d9123ba734c959b7311c6d0839f2d4f683eea416452580033d70910100000003ac515270b0653d3254ba1a160a6470559eff998aa002f72c86994a33d9aadaf7bf57b5f99025320100000008006a520053515352f094b96203aa59130000000000086551516a53536365991d35030000000006536353ac63aca364f20100000000026a000000000000000000020000000000000000dc83140300000000c2e5f9751ff4755a3c503877a0f3b6a742ef3023c3eb13b705eb70393d7ec5b480827acc7abe6da1c97d156c3183b20b32e9de7693edf148c15326a52b76d721cddc64ed86f319519db168714f6fd5148fb43303c4872224c92368c0b8e2e58100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113342a58784540ee2b195d1cba33a18811dc8880454e24d81866bbd7dbd74ed82a06acfa9a7bf138359ed9cbc05ef446a631b33dffec4424fc937f44ab188daa0350fee46c9f0cb90fbfab34024bff4278275086b8222abf7ba065a647fa3f0cc1d6e5bd0d0364cd00c4c43c1273b9cd487601e9f69b6a4e95f70d4de3487d4032f4eb9727285fd7a551d99d25cb21335d5308e91102f3e1bb37e9ef2924bb6f603045d5474088c4561da6fff2fe2756f8af78abd580dc822444efd9f1d87f8edf40a028fd10fb3872714bd89c821617f3896a5aebc382fa1b58b672e622c87623628545312458d34e4c4960054cf14d2832aef3947d22d52e727017737dde287a688030bb23fd26aa57e54754a0a3f00df39f47da5fbd268ae4834013c8239b6a0fc7a0319757258a6f5b04cc47f33d3195750b252df0a0bec924ffb383343c1d65c2d32031feaa824c5092bc0d2af893aa9a2a303cf90c8dad466c3eb535c9eb689ecc03702000fdc2030b6388e09caac9cd746aded3bfd30595897a6e55421297cf8bb45c8021c8ca7aa9ef2edb850ec546b6465935a8fb1512025cb0a99ece5e0ed95d05c944d534c991d3bec62937bfddf94b2a6d119ac7a605df9890d6bb18de0a6dd8fa9710a540fd235aebf719037e919e5719cd0531d5bbc73bb6e90885182f7d3db9ccecafe77f9a89f6b39561f414060f4af1b74cf999527e2c82030ea327fc3ab197a00ac696a474f40c0511b4a1d4ee8918ee0db0d8df287ca9e79c73affd0ea65cc1c454017fdf8d1fb9902a459a584b3019b4b23dd27d1ed5dac00df4b869a6a223921d3e0d7be80c1275850586536a49e1eded99945f81eef016f45f5ec797a56386ffccf0e6697f6e11a93b9ec1bae2cea50dd7deade0116aca3d63febc16f96fd9777f0669266e799f2d22c29872732ec41369e003c600adbfb9a036a3778195fb5cc7d67f61024d225740504849a5265cf5ecfc278166baa56832141ad549aedfd7c8d4a450b985613d7a959d76284dc4c7d16f1d116e27a07be44c18b6f0aa34d846f748045c93d29b57f0de5de31987f7f08e4462f14927aa4d97b04b405d56a7b5ea724fecaefb81473530968bb266370aff8e6b575f414e966a12205d7de2c5deda19a437df95fd73693afd8bccf13efd0d57fe74d33de48317d50a7fcc3741060d8b7fde57798fe12d75728f3c5a726143cb0b3a4cc4ed8b15c28dda507f88dfd897caef8cec651697abc59702dfe80c051e8dd1be37b244076aa759a3177103e83a10b76a0f4cb4c216fbe7329575cc245bca9e0841aa4e0e785e8f4e69bf779c8556d5c730b5db843643558991b481746ed8ddd67cafa7cb2ffef5f520b96d956286f702e1c02bf14cdcd7fccf76c9fff1def65060a2520b8b892c40d61dffa319dc3fd3b1ebb90f6ef1e4fd7acf15d601978f7509a02b00b7b35950c3fe706d90869d772557b456f6ec0656de3511071e691ea73be2c15eb07899adc431f2bef9ba211f8a8122b500a9a68f50dd09523a1852ea1c75c650214f778030bb2b133f685aab9097c5c53006b7e81f9da56eb861cde2295ce47b4d2863f0834bf59118a3309d9685ed87b6dc49f02b55e6cce8b6c36341d67dff0ddc95ef705b9715837b87f0649bc214874c2fca35de37c610132f55a3b1469d940490ead8ad83e5fe7df0644e31e49901ea410a87cd0d80eb3de1177792f94bf06921659be93bcb17c5cd5ddf55829891c33f540b237fb8e8e4da074e9f4c3afb2efc7604e9b2feb350a6f9971cdd97efe173d733f7de9f46d7c06b3b4842f7784fe9b2761c6d11443c090ce4a4644025a609d9cdd62d506078887ab78b2793be6b3700c64ac1b30e224c11490442a35d762cd8c17976068b790073c9b0b897f0af0c3fb2420149137e2903e0c9947dec860b72797b894ffacf525031ab9774d796f841e62e8b7754ad5e1e3538a9c6af8a1a6c820797c937ced6d814cbd167bcda662481fdafddbd3ecbd37f52a7ab13d6fd8112d094d09f70181e1640f98c798954723624d09b769e9dd454db313682f578ca2d69df4662a513c99bb8ee8560c43c5da9f1bf8e9075d72fe17e7d953db385082e1f90298c5bf276b60170c900cc44440213f67dc0173d20dbb1db50544eb51f9e4486f0050b6e1179fc3cefc4703c52c37845bd4e6a4b31dcc0516cd15623a0034f7113d6f961c19eafab3fb0603930ee16e87e549fbd92a8e7d1fc1a5adf68d9c7c6d58f0b7efcdd847e36df24534802b77ba5862a145a622a039ae708309190000000000000000d5cd0e0100000000a5e4ca6db45c9b7fd3f7ef72feb17c7e8e54a9f6b27bfbd893fa18591ed9d5328dc6daea0a6fbb470ac1589540dd194e0392ea75f2d7cd0d7d1c207c967586b58638ed137c90641e087a561e477c5a7261c938d0c5e90ba6548c6e9e6436a59200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b2bc2a61ff6e0d5e8d1bf575ba843ede6585d56a2436240358d539a68d341f2a3c3f7e0233986e5da488051b7120469d972dabeec0d2e84c0daa5491ef11cb6c80768a1fbb5f9e94cb0d2d6e5f8bd063d50e7df0602b2f4e1a24de3105e9491fc7827cb2d0189572f8ea145b785975c37f0d1d2cfaf0712d02e1b69b2232f1b9032422caa810ea9f17bbd5324cb2f48d379554355efbbe13b4e734ae57f16e5999020856da825d1111b73d5653f25484c7e560bb9cf47e387c0b63b1fab206f1ed1e0a053b4ea246ec67e390af9a405fb869c28eafc3482cf948a44c242024f60b4a1c9a7adb84bf48de599caec3ce1c504c779c58169f98ec6053de5efb0e99ae1728031b799a5c6784f3bc2b6ffe789d128030ad64aedf666d65186c2dffc64441c146032ddecab3e0b7eef4244ce4bf2f2c665093e38b70ccc9e9e77dec34ff3f3a12bb02014f05fa3efedcc5c10a9f46ed0a9e82f97c6f7ef012117525471e86270f836c020e445914d2dca9f82b873e16ed0f8b774b127cfbacce8255c3df5a3c503d3622022c7a26e317c99d80d1df157a3bb9f4fd95c1c9d8a5360d5d6fa82e026dd4b9beebe9d3550e0ba23734bb876ec8caaef0448cecf18435e7f629f86092de6c53828c4a9742a2457980029dcbc51dcb6556e75670167be8c7baf52d381d63c637a94d2d01517919e04a4f600627c5056fe8a343435c5816afea33ddbd1c58a19c1f73d5154516c4f8b86669c107c644218657ec6fad81bff1de433e625bab7fa6cbfd3f896a7f638db8d13f1c5e460c649f70c496151e58b417f0cff2e56e1d245e7a76d4d1db9ade4a58ae5c69e616c664893ab5e2c16fbde163b7dd874650b91a5166c9fc4c35aeedeb57f2342ab6df4494e1b8ae59f037eb6566aed473204339c571778c332330c01243a9dda596e21f1f37c7a859d42c809ff8e32a444cffd5e437c41873512ecf856a8cc2aee4aa811e0c0d45029c817b5fb224b73346013c20564e92803428f750f4c1574747c111d35e11dcb98ec075672fea7e0a504db4ccde622c7575456b7f78e64f9e8d9aebe616954689ae8c43b0c322ad83301f36a29474c9373fb1b297f8d63cf3a2b9bbeac3aba09a9a86b74b594dc627c744ddb4c334cd18b3304d0b7987b3ccbfb628186ec352bd53d2f5125cb75f080b987f636682c90ad879f4eecc3e1c52377315434a1fe60b434f0fd7f52bdfbfe6d3bedaf86b730f2104a0c8a146d591cc7434ec6948df10abc39ed8fdbd85fc57d2c1de8a7350d41f05256e9967297a7463ff40c2107b973d9d1b7eb651fb2c63aed4cc5f2c7caa8ebf685e753a342da11bc66776f56ee20c56bc79e402f3a2dfec9ee03c6872fa6415504a1d447c00828b41b36cff1edd8c52efacf59eb5600a6746049fcbc8cf016990b3331b16e9cbdbe8940987c017e7681a0a8e3866ea9bd29222dc2fec6fc3178c85c0157c10d3f0d44b2491c2a004b0f63a41d937d77c44f5261747930b039b6f4a38f3ab9bbe620f50eebc2e54d3c0e49570c493ea1e453e6fa7c344b8f4cdc8cb777968e3aad61cb7420f57b1c2e14182e1963d5322b5a097f65b7390eef2fbc14cc92e2924736dd60b9ae5790205240b7a93a785aa724c6b1b1d68cee6e4f59e2c847d4c8877a436ccd3e43381a7c89b8c678b9d87e149b9fc2d20f2c81ff1db255a376848bdb94eacb785956d34d2a89dc9ba03218b2425f7649e7fb643bb25823d77127df4ebefd0d03e750e023bbd3b5f7c29f3f9b726156f0249861c224cf79fa5cf87323ff00323c390aa5be9d5144b1afa8aae672aacac1f5af9a1bc2085790ee5ef0676dbcc0093e4359c42b6ab183e75878dd33f714bc88d2ecdaa94c378224bd40a896d7bdefe46149903cce3b73b1761394a3a41876bc002d775152587754778e5e1beeeed729d10020c55961705cd48e28bfb3760e44d57704c9a17e1519645373e12cebbe1ea57e9f1394e1e5cfdfd41e021ed5d081789f05f92b60fc97f3352049fa2950a44ce088fb795869232ca022d34c7e9668a2a4b10d6ed296ebf3d90ccc74e0e11717327809e46daa28db120fe7369e9c5f5782228b475851a329e9989751ef9a436fcf030a435399a89da6043cb5a2183e10732092085d68f473207bdc0fdef6d31238ef1e51b2bcf47d61211e5762111bb87be361b5654d680a632d6d62c5e61f81577a4b359570a651a5e9aab243a0743f2d0b83600f8fa81178abca3b1fdbec86e15b82c5c2cc992eea8c4b7da9aed6170557197e33cf9d4fe643d6a2c8545f8489153551c1f51bab338027efed4af2f848862c02c5661593a77c63b7f0dcc18e22e3c91afee5a009de7b132e79720814559981a11a41da596aa120b40232894093f09979a6ad1b71fa457924ddc912ba7183484fca98be66be01f3e0d", "6a536aac5263", 1, -700187145, 1537743641, "f37e713dbd68fb0dbc3b7a371e1e32557dfb28bda58a674d278b1d0f4137b8b9"], + ["d7ff0827013cc62dc605cf7538fccec3be79ecbbdc5304e624a37d25cc5aefdca0c07c9da402000000036aac523f71f3e401870dad030000000006516352516a650000000002f1ee3f000000000000000000000000005486b3b69642eb3a6740f54574d18223125d8c4fadcc5b118762df216ea8b4ed0a9e5a06a37ca26cfa7d11537bcaa7c64faa83c8ff00fcbcc42f7df835845b91766d0b2c5e405581a664d1f7d7ccb25ecb33a777679e94f433f8f180a370eab400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e9d148a3f3c1ecae94a9e7a58bf0359239a3cbe521612724460754ab6d5a27c5ebdb2857dd04f1f2f5c181117107b934bbb25013217806a00ce2dd99827d6c5a90782ef71d892a70bb2f20d02de35c0cf7109c5acfb1538b38bf29b4c4da77ab5515b3fe89e0c73a28cc656a5efe316133066e6ad19f6e4e9f1c1895aba032e1032a7505ae341e56842fde7bb0714a19df375aaf8fdc4f714ab29723fbb16af634030730cb37572c094aa099e37a7068cc20e6207953244f302ee4336e5549e34c140a04aff3d3417ab2a19f43bea6ea03e9d1d5267428d0db861d5124ad5b2e7a6716af3373b6e5659354a30abf7bdd2da51bc29ddf1429b9ac93e64a9f4d4f1404100300120ebc523d8069bcb4f9a7b6c95852444cd356d42bec954c957207d5496f65031dcb00b6378c728c31f2a9a536dc19f6eb8df12c27d76590f45c005c844a96df020bd02a113133e86d92658411a75815d215b826cdd278bcd3e672a0b5dd0c2c890301c49ee6936e7ba5c32ea29a34520f8726bcb2fc09d886dcffb6abad247e96260211765cfeea0666a79d53a3eb9e280dd8bde806f1200e73632b22201cfa00248a18d05e609696c48b1f22d4b8f76f870c427505c71a718cdc8da58b6531c636ae9d9e6777c195ea8c66bae1ba282340feb352881ae29e50fa26985bc1777e1e4fd4d02952f03926f94c5a1f71a436fba3560eb302abbf902364c5daa88aacb65a959f297dace0a52063baa82828524a4cd14adb09a358a07829f1e46c0b94ffd66841f70c269fd5a516ae7dea2dfaa8d58104095c18893cd58b648ddf201867843a1fbb3033dc064c832098af0950a01472b46a22e144b2b5d46cd72d947ac3e5c0ea64251115d56cc20211260e21af879398ea67aba6ecadded2ae8462e4803f22952cf3a87b4dd2acb9bc862edbb0ccafcc18217d915fd9cbbcf2758ada37379d8c7136157eb7e8b9cc94c7eea6f3d5fa708428c524d3e99a6c1bc52ebbcfa4a92e9ded20c671efd3397a120d6398cb4d888fb1d5a0bde2e3b0b6b73bbb29718d5ad75581205d8995468197da70c8a0cea7700146afe8067a14889ced751b0fd326b64db530c5a8d2893c8bfc15889fcede4a92a662b173e4af0dbeeddc89cdd204073d43109858fa636f296b9ea763e127bfd8cc05a3ef1bf73a82c3827cab397f6f43eb436a4731ade28d854c4c83365f35bd95eab2f46d768f343d84a290f3c9ce6b024a8f2fd57dea4a567275f5d1689cc2e067d6785b968409a358fa193665aaec6c7b2f20c9c12a86bea75f2f93605c4a622324c4497dca79207f6cc47f96ff319a27f2e3bcaa39362126cfdcdaba1636e8bc1a7bc447a6873ef1ceea7b7c71b75ea1fa1601f6fe48f464b44bd684f66ca1c211cd67e2181b0dfc61c04feedbdeb8097a024d0785a3d81fd61e46b56d6987a56a93a624a068fc1f03e96fe348f98ee1f9aaba827d836f3d77bb8fd9d543f781c450029c5696503e4757869b6b98a2897c38ef42cde6bf4cd84b0d9a95c73154652e9932e35a3db5d8aef81a9f927273b546c13d2bd82e595fc5d3c411a6b83898af9dd0a7e093524c48dc06c47dc2657611a8b677733f636c705294980402aeef045e04b985e19ca25b4080ad61de689273f3f1afc6674b82b83196e8be9218d8d9061a07f55482db0bb2f587ad7f751f644067fd3b056f5ff7434a8f2fde063865a47ce963b98110b90dcd8ac178187e51bef2b9b41b5d6180ffc963902f3886e8a171b9fe986f83c35c358afe9775f685f470c0897cfe65074737c38f7810512b3682be1fec7c4b5f87cb5f657ac0f541d95733a0160d8eb68e90a245fc025f974c0c6df8c50cf222b03e0a728d9bcdc02e5c236da6c45cd85ff2c007249cfcdac90cdc18cb8dfc4ee89ca3bf161e37adc31498f0c4265264d0bc8f56aed5133270e93a4ed53cf9247d2e6eeb3e7f8c1d721e8d950ecda8fd978527b601a6935536462e70c26291a15ec05119124308df611fbb07f2b3d21569c7e8895ab5d068ab283756e76412abf1c0843361bc5f00881ce83ed5a9f92be15b9f42e684147c0a88e5b61d5f4f4c3641f51c8dae1db931b9fdef6a3458a1777359b547cae63616fb06964d5294065626d23300c0f19ccd8c63ff775242e71d6d44b971be352879e3f83b1fb858a6392f6db526616bb11709a3af8688c7d96ecb71919987f9ad24e9ec7f4b9ed28b76545b17af1532d3631fae988b6e02ba6389d959c316099b124a13c68a931b321848a3254a76885c8b00b6f12d3bdffd5134662d4003000000000000000000000000ec9437123ba462328c6de302c3c4dd931afd4154049eb6d107213997937bb03030a0d2e0832a95cfc93f67ddeb1fe903f888930cf47810340c26cdc1ce1d29637a5e76077e5ce52a8e194453cae4cad6231afcfa9361adb637ff9fdf9c83321100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dd635fe0b4ef10e2e06a332609412c53b055d308b5bdf79d175a864b7961704e84ff210cc23cf37ab001e1e0f6b2023c6ee769d4013951a3c75ca9eda33431ee7d86bfd818955b4f61a3752b4d376b81c63d71e5a38de87891d8c64329b3d406b1405ec6dcb5d1702b246e1221a5ee20b2a37efaa97f2426edc886c34d57a3000214c925b1e8c17fe4e81925015ac0ee73866a9b4bce9e2f6db3f9bab6bb96506a02084b3cb5389c23f1c9190a848b988715642d1ae0b0efbf9213286ed5c2701c630a0101bbf1ed4a89c7694a0c6d8d11f58929d1e0f0f8fe1be513b2b7d6468c62f22998836df086556591459607e976c30b3091c05d5a6a48da0a3dde038dc35ccf030b30989a84d7a3e6a50d7ca9c2d39fc7708dab8c49f3e4c86e44c89dc0f6ccb303029299e1b98b09b68ebed05782a82815a20f0e0d4ebb8734c68b8c4551eac68a0220de5aff4a637d56f764bf7dc73fad96faf6218f13778f97d1eeae89ef33941f0219a36105365f80dfe71e5be8f8e3e5f3d9c5008a4f067fe16d72130195f3b3b9031e53e43672e7c069ed777d2d788853f189d999b11d44b9b431dccb0bde8d519869f1c972869735df6747c171b0b61686ab55bcd1902d46d265cabac5ac1a543eefe8fb4674bdb5683b9755b1378706ce0b57a8b9eb3ac58c3d049cd3ddee569517665f5730c31c25fef3757078e5d47d293c63e02a656a66e6b20525a370ef8043ce6c00fc29ae66c51a6d07ad8fbaf87bc585640a643b7c2896666328f0d00e5c7285e70cdac3c6dad73855eae1e332a571f4b75302a31428897d0fe7997b15dfc5cc80280d21b0a986e8ccd9dd4b25e592953dde985582fcaaa6cff9b2432eb6c26ea1605b796dd3430a3edfe48f7bbce4c47703e7880bac318389016c1a6f8584b2306b605618e221a78486d55c7e6743ec80fbb41242dc57f5b3152187eeb57f3e2d6c91cb101f7021c44b741fa90b8a48bcc50e41420c18ad31df8f9b4612125380980f371100f2d32677e3aed9f11fc7c85ed3787211cd06cb4968a86abcd18b481aff9598b0bac29d074d29425e21c3cc1e77a14a3695d0cbec7c3f69856a5ab89cbaa7bf734005f3540a5b8cef88d7ad216789de072cf291fea8eeff98f842c805b7e1d8df22429d410a32e0028a710ebe5d98a3d1bb9730890e76900e4d044b144a0a07afd53bcc245874d89f3dc1bc9aea25e79e61e14be9f7c70e654ceabf01e38d4817058d22cebfefa8da7588f47dbf9b0708ebec8090ebf9bb59aaec83db5b2865be2d7b708e20f79665b056e4e995eccf5f969e8c77a08c8c0addd054eba568398e4bc9008a872f3cd8d372d86f979bd9055433e3b9b51e3b15a6540b21f6f938c7e86ac98b45625a028383f541ad76f42dcbc360c03deaf7e2b3b795d385edce14c7eb7ee56c3a802635717fbc1128a606236c064761102b1d3e8a6857a5d2d844e8eac79e5109d111c442b4a0551b9e0ad6a9242865165137b83ee5c41da5053b8501a2dc4a3c27a9564fcfe4f8d439ff35d5099164b266ef90271912716519e08d60cfa8b9f36e00215a26511c5b17c5e9358c21c03ba0ebd0bb20b98585eea2d75fe2746ef7fbd92f5ab1cd14d1ba9e2dc18a67473ef0b1ef6bb3521f19e9943827eac22de133d5c3b4c962475b1f09c0f0206dbaf6ada2ff7ea77456e336fdec9378b8b40f6cbc61210101c27c2ae96f993beec612d9466cc06f8ee50615e1b09bfecd81b23ddffb5d37130e70b670a099d8d9409d155f46f34aeaac19deb1159269c0dd95a5bfb31cc0aaaeb46d260ae47fc3499b636b3b8916c4709806ed8492d51c058c742b2b06414ed8d6c24860b7eb502b7b9900f112b9f66c13f334d8ca4f17799f44f86feba2318b1eff0ed3a5dec91ca9ad83a5fb5643893e5c9b72b398a898a2147ca6c69b27fba356ce52fc93cdbbb59bc4807d9c7140d14f55fdeb3da20fabd42fd4ab50fffa1da7b5200219fd92798e3320ba0fbcf05241bdb485e7ed0481657f560d16bdcf6864b63a1ab093f0cd125f16b2deb1d9abf884a4e50125a14bbde133d8b77b26f196065e364197c71da98f49ba1f725be6cf4da023c9864951cf3df984b2600635eaa119f77ccc32676f69fcf907a2e416c2d527fbb45d58d6234642d2ada5e89a3b0d7ffbd6d8ecce51ca51fd78ebcf3d12788472a05350d21ea9e17f2616defa30355cd04a3c2d28e0cc9aaeb9bf71208da96fa2973b5ba5aa5afcc66ca634de31b7daa5fbb479a2065da01888673b949246911e559e7fa657c0c865bf9ae9d5e58ee3a6f5fd5a92752c76e1f6c45d300d2b512683bcfa9042c2b5e9fd4829f1332fdf871f2edee989602d91838752c9888edca054d281d3f523f7d1286468636e03507edc547088dd7d6283e807b54983e90e78f47ec0bfaeb704", "00515163", 0, 57299556, 1537743641, "415586efe52df9e53f53ecd83d1dc8656b2ff18e905a5a30973fccb233dd04fb"], + ["c9843e08037a65994b56b7f32dbd2f843d055259c2a59506952d5883795b1b618fd353f21b000000000600ac536a636affffffff7eb0df6da0d2a82f4453948f4c244d1d6f6b0747cd60b67b2e7487650534e77602000000026363ffffffffa162c27043b8d0480e785f4cb0882af01d56d42ac69a11bed9350936d420e121020000000653516aac52634dcaabd3049daa0800000000000953526a52650053535297c4c10300000000076a515251630053c4393b04000000000952526365525365636aeea6a5030000000007516565656a52527ea0ec080100000000000000003aa3f00300000000b1d64a726f8fa31a88845a4f0f744d697c9585669546760914c07d8d4d74cff367f43a92c4d81d188fe5a047ff2ef29e70202aae34814048eaa8ffd0189b3a3c1423f917232a78969c340eec305e5ea4e224f54544b5460a9770af994987ce4400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000229f13521ea632dcdb25b93dc41605e04eb4d9bbf3206fd244d3e9034d9629abff4747bb244553f43f86d9324519449b48abeb877913a4f3f53fab60666f33981803357e51e83f7c2e1653f2d016a1596c56a86c785d9065d5420c2ac71704a9646ee3a848e928986e685f2ccba0689dbd4a7805374350289225a963aa1cf4ab030c210a3559f89b37968d3c07706c22ae7767e576c9dc8587a9fccbb295aebf99022a7613f62e602d4a59f7e7958c67bb6d182452071a2d062e84c4da45d182d1830b06b0e63647cf6975f8f51ab16bc75809ecf7779b206e002de621d1b41dcafdf78b5b299b7d4e997329663ba7ccea8389c9e0f1d36efb5fe91b5952cfc0bd2f22031b643ab23ba3b3f1a45b9c1d4bdc6da937865af972653eb579ce0b209ae4f8b1032e943cf9376044ff17be8291ada36dad9420fc6cdf9c9934c9dea7cc683f3127021f0298dc5fe7d5c0b15bc69e1182dc6f1cbaded078df1d5a98863991764e7a7b0226fd5043391409709c15b051e7a3382547830e2510ebf243d680c8696f2c4c41022503930f47c1398ed984fa4a0e4c54da5ffbfb2822e7a0564035e8c7081b954123e85a82037e9b31f127afe62c0bbafc72f5a9a0fed3708939fb6bf5346ec6f703cf81e4ea2b1fbbe9f9547506da6d03cd27b808bd758e981949d6f0e347734537eb83ac94f927cab24e68d15e528cacabd943780244e1b6f0bcb6a7756a4938e95c05b151e62c7feb2a3e1c35863f73c9593d0a889705c008b404c7fc7f7e30441e68f910679f9c90fac7103d5481d02da8dcc8992f78f8a71537fcf328632e00fcf07d51adcbde0a98c9ef52c5a0e387959a335930bbbfed50698745ab45d37ed0835a67d806fd659405f29ad9c788690456560e02f10a4755c7f28743379f91ff7d230d7863e2d398301f2c62dce9eb674c61b248c4e6486c2f1925c60b850f89b082bfd148853ee9b271175504e2cdb48e7308f723c2428f7985ee5dc583f49c6aa25b622dce637cb29b20f3c713bb904e0856709b7f37d7c75bf859138149eba5483ca178a668ad7c9a7098ee09f5c8aac6e776ce0ece82152fd2325ef465441623b3af2aa4816d5aa2f436dddd07773ed6250c62e84755a16974953aceb348c2518c31969ccba8d241d290d6b8b61d479a4501585e2fa55f7451d8bbff54d69716673d9c8f90eb1493d86e70827118ba14dc18d045968e4a574f0ac3211be15960a106dd8b30c45d344b45ca95517820d2020e460f595b20ba2e1db4b8c028b85b45630ba311b89fa90033e0ece49818f5c58c73a57d5b4c453fbe8283cf037c4864a0cdb7b05ae2e51abfbb728e0e48bec846c3d639f4b907b9706d74a7ccb2a08810a2eaeebe84bbd4fd9b7251d50137984b68915b15067b9411458102f326bce1473e0ff8b01d92af2fb8b499157ff3d28e3c8c99ac4562e99504819bbe798dccf34bdf236bc2a91c39a0d8f18f33b4effdd2553104ef26ac656537c800051a170f5fffb24a82e929994f0db36682e7c7263e1a9ff49719dc162d56f4a2dfa6a080ecfb3b0f9e30c541975b122a43858e8bc3b754f0bda6b327e013d710a50e962b9685a9d57f482b50e2e037fda0bb49b48e804009ef48521b6d95dfdfa4084dca265b4989f582986d28474d8bc25e26301189373b77434ae32982c5da7819c0b78703c50fb347a2df2fbbd46168958368eaddc590a8bafbe9151a37f9415ad4c55c63895e7213475b3dc35c6bb45296a071be726ad7f2ef5b5904e5dc8136c3a0487d577e4be00a83d3726962e4db15d03c54ef7f1cecec0c84052547755897299918e2f28a4d84bad78015fbd8ac0c6933ec6969f3615635b645c6b79b79f4d3723dc4d65e719dcc9a30c434bf03f3f72b7f7b127af711a9e7e21b82d3369ff1fce90693cdd92d3134a44664890457b68472275bd49bf4ddb1e5da8b3abb0f27d0dd7f3f87f97666b201e2b618fabf895ab73249c6c174154b13fe9023d516beb52ff355c9041333142435042939b2e4f5d824770ae52d0ea6f88da372ab25d0b57edc75f906cbd694cc21188533143d5cf09279301e00b5884de193154251753017e061d3597eff2ee396e12054f2b59c9d5a7b6041914c57aa42682c2896122f05d80156b003ffb1c2a6a098113b1b18f4f396558f58c135faf2b71387d91010a7b04586a59b4ad57e4e7f73eb5875bbb4a4ce5f04f1a43b1d9e7258acffd7aec7416febff03c965724cf1221378fe34da71c4f9c0c4c39183e5c4d84feea72248027a88c7c2c610085a2c5d2de52a1a11a8105dc3819a3a36f4eb53f86c471311d9f82b38432bd0ee20de60685b54f571001bf4b85be798c34081f70207d4451672dcf546b4dfd44ee6cde2c62c1a7a40390f1ef715a78ce8bdd7389859fe67027e6a67a3aa34b6e8bd0b", "52635365acac53", 0, -1950102242, 0, "b51d7d00700ad62a5d74dd03e3941cf0ac980110e0d48b6cdc1560f81ec397d4"], + ["1fd16d0804a90716067b57b6c9540081646b0766b375ac0ee9cef059bbada2548b0ce5471403000000015322c69c7fa5437e6bfc6819f5076ec5913e2eb0a1cdbb4a5d8c423066c020891c9554fddc0200000002ac51ffffffff99624771ffa4ff7380e90608756a05072d5b2a7a2f8fc7b563d5b19379c0cbaf00000000025152fca2632b6835a7d86aeb677e3085f9595fc2f8b24857c6d07cc92890ad35205859c77f9802000000076365520051ac6361b9a92101be241c01000000000651526a52ac516ed65b0803ace66b030000000000000000000000002bca0229e6dcfd7d7ee5ef2bab02dd4f4755ee409e1fbd0c4c4f3bc6d7511c5835f8c534d722d1a9873f9ef7fde2b16869ac33ee3733f966097b1b4f2820a40041a6060be7fde3052faaa3c204ee7f530d10562da8d370525ad73503017bfcf700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050ac06ca2510be7eca65284aa3e063e80179c34f461d0cde7ebef6c80c05c14d0f87807a5554880d73eca867d89bb4ddb95dfdf9c1bf6c58b0f1c55119263aa5e540577bf59847e8a11a37353641c4206482d12b424b55cf558c47901c696cac71ee7229a3f056035b57e0dbfb050fdbf333ab1e75627ab50ab3840c8a5f75d020dc56764e95eb366b9e36a826c76552e32ab493bb72a5007b2738f094c6cffdb032d377ff7c0919b05a681320a687670c23966be9f5aa653f4c8fe0e5bac9965cb0b075b129f057ff93b7c28aa85d70b03c51d6f382d6299bb64d2d8af676c8092eab921e648dc122ac73f7c26cc9173924736e528945bcecc537643ee52c840cffb02044071088562b9d93e75f08a9dd7d659b519c7898974a03d678a58bb3f4c1c2a0328d3633dc16c93101dc40be3bef46bdc25b2d2070df5059139c7f565936e058b02007b4bca0396a3d1c76ea000ae440fb57e580a69e7136fe9a5e97c5084600bfe02191c86f9772a687c636159b38c03f457c3f82d8461b460861bc7204ceb727eb6020e2d04582e631943bce08f8c7ada72cf180c6806d9cf1fae1e908e82e61944a4d3e4f97ee31d550949a58742f9da4f45ca01665849bb465eb47f4d70af42d9e9e00efc8f1386d61b3dec6bea76d24a4211e0cd3b32d073d602584a307a3eb930916930a52626706f232db147b4180a1953acfaa3d58b1e09bb6f4153d3d373f0dff23b6a8f84645ff25e20b0fd6bbe33bf2ff8035f5511b63500451a02c45e8325621bc4b1e8a02474ff24feae47b2cd1ad10992f3e9ef9579086e3a5ab2715e19e027434446a7c74b5e1cb725f99c27af18426cd0153d5dea2ceb2df31f956235e6c1cdf4d90c6e47935168581d599ae208fed535010e24999e5530bf53aa93d92c009fab1f5b66a9a97704e6af5fcc897e9cc3ce07672157853f9a35404990c3760923019c7b1aba6feeca3b34d24ea90e7479d829736987567837ca7ff8cc0306af90cb05315762170058ed5e5a1430114db9150af01ab95aea198976e1c600b11294312ceb6251a9db8535810d124c780c089f9b59c3da40f5d89fdcbbb8bd7e494c9ab7242cf6e5e0cf50d3cbb040aa3fd1ba3b24e4897600119c2ba1843f52281c4da9e05a931e433c8a03ff492b3131dde2fb4d52976e55d640297991a1fae2b4576190092a855a3a66dde91423f921354645bb9005a4c324489a10868bb9de168071a40af2bbef40bd15c626bf577e0bf9a3e0f154319825c0f030339953cf923fec633afcd1ad78d6965ba5001bf1fb6f1e6d84c7e50963d9457c66ddb8e976f3044dece856df44f19bdef204d873c826b4cb03e23bc8881b20332a1bfd0313f3c9c50fb966930f4c405ffdba22ad0bc0c9067071de66462716bf79b55bf59fe9e7b6bfe094ad4ff984a3fdf4344a693a47801f9ea6aca0394dbd4c9758a4529f51fc451e69438b70a491183a1591dcc5477aa186067a99ba08f568645eba3bc226708cb5e30cf3ff042a2bbb23971712603bc27907aab75931d393f70183e6b1b858a265afe91f202cda1ee1c27e62a6a9efd026315fbe2cd45885f4aeab7d5242b9539322b66669264710cdd3f29a6bd744b52c3307bfbf814cdefcc90e3b5640f2b0e705aee9dba8da439b732488c1669ea187f3fb239a4ebe5c730c8f15a8ff30a2e0530fb1be8cb56b0e94d491bbbdc2f2ccbc1c69139c0e7f525ec615b5dadadf625ed38e78496932a635eb298e4d93fa9c0e905d84f67fb9bf13c7532bffd07dd119bfa150bd0891dde6809f818c0204c07524e869693d76a140c803ee82c756657630a6b843c7ece364a2a3c968982a2e2d4569eb4aacb5beedfb9061fe19cc2b7536cd9993f2fe0ce2d5d4e421505e3dd7712a04f96e0a5a772bc6f6e376881582b4a51350b70659ae238378beef452fda1e1569ff85ea0231ab4d33a6931aa2e6b7eaee6da93e0be93225d745749e34fd34d9b723e78d1adfcbf90bec165f4ddf3343468e7c7ea9ae7743b192bb3a9399c4d530125b8ae8d087a8c7cd3d12b02eef93282ecee36ff92559d2f1e6ccdea69827cd6fb75ee6b57d17a5742ccb30682edfa6db66aab5008ad30314873a88e29f1f2a3f40fa1c5a664512e6fbc1d5da7cbe049e0b468824eebe31316884cb3b6b3586c811895bb3d6bed840518ff6cdbab7f4478599b1fef05f453ba947bc04f7f0c55368d2dd9cefc95f97400758a6bb8e95b59dc4beb73242d2e0b8364036f838b8975b486510119d468cdd1a7f93ad150aec7c1e662b00000000000000000d1ddb0200000000ba68f13a517a10ae42394076a444d854a00f8a7a4b85f1d5cb13085f73185e5897c6130ab60f9fc5caeb2a2b2945a944a14a2846a157c383bbd89c80cdd295f992719e4b4bb89a84ad514e25463b9965fbe623ed6fc3bb56c86704e94d666c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb21bc44e6b31ab61ca593e62cffefc4fd7c90150135cbeeeb2e8e5225424615dd55327cda6134acbc126ad3c917b586d0d972d4746e989b53e87c9278f878d2e71b852de9d073d22b3f4fe91043bb952ee96c8be07577f6c723225f8eaf507cbf3ccf56775589c22178f6c0c829b46cab8d89f666338093a665b563ac19766b0319c56c1cd39802378c6f6a0cd286dcdd221246b05dae36b9a31433f88100a2e603181911937e929d96e0d538a32a8cf60885f18e940c19e34136f7fcc186c510530b05362f92998733c9188c40a9d0f2e835972120d8d5a862b4163d79374b4d1ac861cfd8cf9e9fb53a9f465c2267cfe5cdf12f8a78ea9db8f3bee87413f12d07d4032be44923993fa4b5b1d93c6128cf10608bd583e9aa027a910be0f62fe3bd511b021714fab19939b1398128f35cd6fb995f69e3692946b0fa7433ab362096fd6c880201f9fe33d8c56969dcc2798ebf012e0fd8c9a0e33abab2793da499d2c69df723022d9b2761c99d171ce06e001bc3e9f7753e7dc57d8d8e33035b4cd90dafbc050703165aba754f9b8da81c28fb3b5a4c8649605016afced967f141f68e8b08ea64a9916af555de2166a31be53bcae0fde958be8586c3378d221dbe48afce83c17e30829f528d81671ae93dca4f02cd981a8dc1897253e3c062092423aa3c38696a3ebd664e25f0dec3baed472a1f1e3f5e3240e08400dfef1ea9337b8e3713e7a8e8bf89dd242c4cb699a19000db57b95bc4256eafd34daf4b478776c8781666b1c75b805e7475405545202f927bcb3c01f9023d05402fe1bd85e31f4a9767bf2041c3d83275f5484ce135ba96beee560b1a4e13599cb174841b28e2f739e070ab7f61f787c484f6d25d3d2593c02b99fd5612d625c717a7fdd0d184aaad0012ca1b2327a5af3eed1692f05df67373ae16cf8e727f1bc679faf8f4752e2bda8e226791e7066563712c3e7f026a9031a993e88372ac3aa87bc4555b112f97c28d9ef052334ddf34eebcf904ce51f43f750c74f796a8adf251006afcbb13150fb8aaf1b77e5268edf3d7659d5dd261763e9f89cc4d7388c8770cbaeb3035f96cb5ab86cab0978ebac9969e086242632e0f7cd1c7b07e6e13db27c2a986b08594466a4c8728c3e647c67e8703da1764f117826047c9d3753ad05d72557ab24514e5c5a35de35f33cf461542eb22b90178966312f7f4464bff4527894265ba083a8c7e6f5bbbc3db98eee6d61c2d20ea9b8db44d5022223c2be8178d7584a8b3cd56e1b6b81fb837b9cbcf523838aa05deb146e18f081b50de044f028dd807047a226ad631e671899b47037111a82536ca7f7f62b6e0aca753b13e7f2365082c9a00b249e99303e04b06d6acea86f7e05aa0824d4e631ced0b8665a0d95032483b3817b8b15c7b0d84c12aa4467d771a3a4c2ae751494dd6110938743073963c10188541a43f3ae9c376b6393bcec3612b5c4498c8e3ef1f1e62ff34b09f433208f098cfb89e0740137651d75e0b64ae0cd5b6f291ceb34b95d9664ab01cb416f74d44a8437b6aed0bd179808d3e20a4c90e2195733ad884e6f20f59328c3a68f1a06e91b309adfdb6bc78dc53a8b054a6b67974c4774614ae4f19903b05aa49c91ad38e53e07c041a1b21d24307f9bd58ff88ea37588dcc2818b1bedccd958834426a2907b4e34748a858ef6d5c225433abd7c57ff3728ea11362336870be92d71fa8717db34d17e8b6c89a0742cd7d978c0612215669fddf57afb375d9449b9e11c2ecd68e9c2ad18f0944a7198e841dba1c3c52cffa5060f261c634625b13afba67fcfa09a41526914cc5fd0164483b2b5220e2ede2fc0f4e9204554ce4644d6b7cbda801ae8b84a43872b51b98b9bc596b684ff65698a3220328c93d3664b5d08130068698bb01f10d8327bf639f66822e0017cc1868afb95241c81af04d4c5d992a4d1edc94e1f6b2e237e81d777611f541bd8bb708d0626da4109c00008db002b8dc0c689fdf17dcc7a80be3aaab23800d082f049f97a63e69c3533b7c0b6df92bada2232fe49c78030fb89f2b56ed0d009a174ee3a97f76976b8ed1e9f76b7c4288eb91329a2ce202d7948bd413a483bd778080539f96cc6317a5b0569aeaf84d9cd772bc528ee29f3fe501252fef2e5163a4170927d6d8af2e8a9bf8035ef33d57416c524cc7c50c4da219469455fc43a4c24c6df6a3a8b111b568909f4ebd2603e610c7d93beae358ea121f041dee158f17df252f8eca16ac15cf6f7f33d5af8d1d3479606b4c36245b5b27f1baaad83d371da46e01000000000000000000000000be9d237721d3249050ba6fd25c329fc8f8788d8caa52420721062a8088ab538e9d3023fe172b737cbce8af1bc2d542b42beea00f9254dfb71062004eca25d6bd86d88be8e1333d76fde3bac22873bb084a1320f888989c987ce0c297677d155800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000538b90eb3a32009e818753da686ecf93bbcfbcb1eeb06afe1178c1818b9a763b5ac50b299e6e8869e5e3dd551fc830f81a008dfa22209f5322258ffcaba35cc1b31655ce9ee75aae05cd8fede70472f2e473fa1268bc55012b8d00ae41a98f2b687b88674af3b8938dc700bee0b065db72c3a5c939994f982b98c386b1c5a2a7021681b1b76148b7204afdd2d0cc6e61592999ec2dd5ab284d615699f91cee88da021df01133f5f7101f945033483809d97d07061e47912629c7cce25fc82f390dbb0a0767d0617adad0816b1b2d8d08f9c4b0124ff57bc064bfc943e698050251f5e6a13a048942f67666472269293d2457b7018ac9695113f2f69bfbb363da07a15802255761cbd3880628f0e17d95bb0cccf916930fb1a33b83e7d160c94ac06a2ad00326ffea99b65b6797112593115e19d84097f97ccbe537707b39984384d5a9e2d6030d8ad63a78f3c9e7db1d402ed481abdd4dcc6ad91122cff83a5a098a6eb369b003233bfc3eaa084397b12143885ad653c07677bcc3c7bcd9b561956da9fb64d1050220b31b550f14bc4f6a771edfd5066c56f4cd6fe145c969ca9f9c1cbc9eb37a56f280282042e268d144329a81d3076e8c080bafeca5d5b429dd8fc3857c10aefb70a01052337c0b32c07ffd9ebe24973637b0bb7854c7b98e9102d9d1b74c6a3f354d742c7042a532834ffd9eac4644071b70e9df1fe1fdf0b0a6e52f3b06f5d81ddb5c69944ddc808a1d27751036bc6588b2098e23656ea2d9bdc7e039e355143cacf7779dcaabcd25307b36708706adb866409f9b0871d9e51709a2db33792c87a66c25fa07999bd350d91a51a2cd6bda21629cd7da7b235c41bcbfdfbbfcad002fcc60186db77c786bfee2cd2d55f3116f8958cb4e38cefeebc2b13e5e9a1318b54b6789bcad1e803ec5c077784bcf36812a64bd4dcd99ac94e19a74035da2a72e3972c412797bf5cea742b79bfa7b5aeee342e832ff3ff023c2c2a9075f2c29ccd00a3b39e2c831bf4031547cd4e7eeb0cddb151fae21efd0cf6bfc85ef48f7919c286beed8f4ea24ec3fc8555b77748bf3c9cd789d7bf25e9fcfeb33549882b6a1ba6fbecf66b51360446d0d6e3122fff7ead181dfe77b15ae7e211ea60fa469c86e6379b9c2db2e8ae1080e9d9ce38365fb24d5432f79ccd0306b7f2cd170dc3fdac79168344af511420cc13624ad3d5554d80d8b855b9e21678c6dc45d0ea97f66d202afef1aa0500b8f9925b4bdc59b916ddee44b4cac2782a47c31300217377a35c56e93afd0004b42de73f90e5230a1aab877098c6162a55c5604611fe51ba97c3dba9f6deac5205a295f02d813e02d42711f9804d0dea3f0022e0d9f0a2978056f02a4551cece2296568138680cfc9ba4a963c5b1abbce1fb2346320b431b30c9d78f61319ae2a6971370adbe24b2c0b8b39f1a59d8ff95cccb3035459793896b35260064dbba56b927e7ade74ae1a813d53fa547bbdd07dd8592642b229544f662c7421a50f8213ca49cac371cef43eba32b55ee36a5f4fe495384bd6b3f501f5ad717ac1416d931af08a888371bbaed0df3ccdd6315c3174b8c5fe4dc6a591c88c740456026a75cb00aa3defbfeaa2b28c5e901762290017c13da443e1a933859e639ff7099663fb800c28d8c9871c73c4cf73e401b6016f750b09abc1798b61223f6fa66883877a027e1550cdda6aff5eb6f18e263045ce38cc81ec49dde6acecb0e52a6b41ac1fd74a9a2eb8d2ec3fd8e18906e53bdfc6e182d024026d8a7b6105602af9c362521ceea85f86d16207452f3688131f1b57490fa3cc55d8f30079a58d03e952ed1e7c0cc0c63bc3f4f53bac37ff50bb81ff4ac5a71bf3c54574e6b9890f9c98f874f8a82ca8756d0e73e60f8d5047096d6efdae5a0775117ca014a0c9767cbbc0466afacd89428d74f68a7c4896b4215af9a2c37b391e594a8c3fb0810a66d4dbd44d549dd916561cea11f3d0b6e3e789c0ee4c97ec5ecc4170c1c95c573aca95cd203936f7f9cf81122d10b6b48042594cac88297f43a9a41a10a8af7c44822de3c7907a00d35a9adc95944e3a9b10891a74fb34408eb62b3df86f69ebbaf344feb4a94e5fa4a60d590db476d8acc17b6c277d90605e17b06107a25568517b2bdac2c270a5707298c6b2164d8b01b029e894cf2aa7d2ffc9f723cf3bfb0d8bbddb9fd90f684b40849170c67624dab1e6fc74d233db5bf54309ff715819b76393c9520862bcf9a52919d67c3b3087976db83c15d276dfdac07e4f8bca7cea56e89d3d5db29a0aa5ee0bfbd9cad171f43244a07b95fb7bba174371637d5fdeeac694a57776627b0c46d20054a99cd7d88e73903486fe3067a9eb466224fc74977791d34d48f9f4a8344d661f8f03b30d4c0528d8863ff351c642ece2f6a1250e0f6fbfea2302", "6353536a630052ac51", 0, 1915258398, 1537743641, "cdbafb9f10bf6a377826e6d615be05e345e0b96185fcb33f9b4071c829871203"], + ["e9cbda2804102360780b3e41cf7a3573620c06c482ff5422acc8c4a862055bb8f5ce1811e10300000006536351535252ffffffff130b1e24ac59e9cf5ddc502cad2e05c2f5f028f44a2fda2cf0d8b7874d8757020200000004516a5163ffffffff45ffb3f7149b385eca8c913a4e769c1af3af8fc403cf237543beb8154abd05f40200000005526aac0065707f7599e770e998d5f3e638bb63d1d4fcf99e11d02b47548e5400a7e2706e05461ed5c1020000000163e9658d7804c4053801000000000353635142dc620100000000046a5352631d1687010000000006656552acacac9081c6020000000001630000000002c47f1301000000000000000000000000968556cfa845744e746d7e8d000ad78795ad242f2c4e52103d13dc00c2fe9f4e0690f29a69c0708b08c03f8f95ee9440d76317d739fcda6c0f56f57ab7c2de81569060a2782dd2465fdb1fd94ab5d03a8fd8eeafde4e563e52188e2e01cc564200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef5bea3bb1d3fe2943b25f2cdd846c61a03f177019781ef3aeb8fc94c15891893a6a2c5cffef739cc850143354e4ed90813b8c7d9c33a6ea4e73efa62f385074bfc4e0a8b280ddd4429317c8a37ecd466fb4aa0a6fde71c8388e4caf81ce03be5f5a54ee341613e4f2e7b6d93b65f7ae6b6ecb5a6ee14deee5fa980692d7525a031e8ee1a2787c5f8a320de1f8c4653e4bf92929930bfa19ef129f813bf350a0d3032debcee6e3f2b8c4fc4b7eece81ac5e31fb2285c9eeed9a58e0e9dd5d98348c70b015d44bdb0a5ed9d2cd709e49eceee5e50319188aada38a389b44edf7791ecff21d65e8044a3fc4bc9a85b36aa8a97ba2c5d48729b97207aab43ae2194de37870208e8ed35185d90c87c0a153ccd3efac563e6877207eef8ee7e157b67080bcb78021b2f4fea196643a33c1b0db6d6c48e46255cfc028968036ee579669a07ae9df00324f777829e80df5c1a04be606865e8dd9ce873fcdb51b01808e90dea88d8b23b022cf39a5f42cb59b187e87321388c96f63ae22b11989427952deb8fc1ed74d279031614d5f3f2591269dc05eaa75e7156b8d1e5b34570fa16911e5caecf9f356aa66f0abec1755f33a2e29742af58c80128eb9f818ec88a6c10dc14d396c516b8bfe4a1a373cb0c73c61293284d601d3180b8830c13eb9835d7026992c60f10df80fb5ca32632517c0d450db4991aa4566bd453cb06e13d08a142587be07374b3bfc145ea02d78a1de68fde40c2fc4ab69098ea881383ebc806ca89bec90c05dd2f446aa3b9327236cbbe1f5918cee8d13e95acc4d0d0c2964cd5fbd71b847e52d388359fc48577abc402aeb3859fe848b635711247e77369ea46d42cf8623fd533cc4a12d11c376a53d79e1fe683ddaa53751e8abc22c0f37663ae8d16bda4b487714f2efa9035c7baf1ac878a1c12bcdfe0492cbf321a4ab5ab49d6739d26bc90a19f85389ec4e86df2e81909a2a225dadc5018ac32026b399ff2bba9ab72236123b97e4bdf5b6d76fed04e37358810196466577f92796147d9b6a7e5da3419548f41390ec82b451b090fdd2d73cd16b368f6a5591b078528aed249d5ee5a81c2fba609ddfbd219f03e3f3be03faa85e9e31c8b59699bc2df19da36d936ab95f69ee29dcbd96b03fe8b9e434da01128a94d7bf7656b70fb2b49e06d381ea1e1f753f03c8a9f93bd85861e902d9eba470bd3addcd714f03f11fef39b55f74c529a734b8112dc1577efb8c613bd73f2b9438499f8a9da21b9b3f89f52c01411d083e7dfa85f535370746fe14b5919618a40ee702d7b17e4220d16eec43552717a4282040441a5a9daa7577b8156c1742b17c9e468857c9788c7888c3da9a4ff45b16149051416579a49aefadd2182d6fcd97d10f263700c4fd9b5eed2754f541c841fcc2d16995a9de34f6c180dfba109c6c63f86fd3c1ae964dcc61204f1a3ffb68a3a0c81f308e6dded3a59d19ebb15b0fc8366b9f82871ba9d4c6fcb162e5d0f0af5ff0404eddd9bf16eb01d6f5eeb516a3d4ff99da1fdddab759399052ff042ba45275c49e03f8f5ef2de17bb46d178d97d8fe3955c231ffc64dd3fd2464b8562c66d02127f95853a086776a1201958fd58482a9d1d2700c50b7cc02c0d13945c4265ad0ee9aa760fe3f4438c34378786e4d368194827d574ea9d64a704e72c36fc4de240c3384f3be8d4516706a701a049414c49a0c6464d7426ea16b03bdbe65baa13679eb452a9d5d40d5c7ce83e4dbd7f23dc900642b6f0689c9ff88f30979b7352c91c0d4cc18a0acbb593e76501254e7899f76f59d37aaa2f7197ad1f65a1df0d2f0c3aff328279078c2f71f3347961416489d47284b18a411c757252365c3266894dc38092d939b06c848942b0651bebac9debf979fecd2ba679d26feeef9b8c503c412a5f3af12d452cb0a7f8132589fa49bc69727ab3a36b520c0962a820a2d1a994907c2348f4641f1ddd4ffe9df3553188a61af4fddc9550976a6d187a7d95f413e8984d1efd449b89af981caa94b50cec1cdf0f748f69c414fc5c21d897c6dfebae8edffa9d3d32998a6da1b2126cdd927085e8cbdba78613a5fed6cc58d97b185a1ad95df2dfccdc548f16dd45b8c05548687c014c0395a30eacbad0e7789744144f7577c512ad7d4c21f4eed81f78274d240142763aac1a330a250aef104da27bdd70c6349137d154be36d4ef889519cc9a2ac0525e0cfb2ae0187bcbf6df021622cd8748fa74d92568b158edfd3eb3e92af6599fa652e563cf1eabd4e37d6c154b83cc167f64c0d998c4000000000000000072c27004000000007ebe22362fdc578c79c535752791c4696c702bc52ef9701c63e54fbc8ace16f23197e4346e8daecbe3d2d8f7d404da795800cbb3b0997b0c645678466e5d71fe0668e469f173edf712ffac46a1303982c77da83de486185ef9a9783dabfeca1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d454c5fc04c87c3cb044c370a51236b2c6c36c7706e482ecccc5532bca492768b63ef641fd3fa43be2ce7522ccf7405c3dd8e9fe02edeb5da0442a7aa51fd9aed517d00599521f79bbe5b99ef2a8e1d6f5e4ca12cab63a8be358eeac06e4d6194e3a78c5ac8c27b7c58e8743d3e07fb391571bbae2164236ed764a845a086ad3021a9d0675c4176d2a4a69a2b31ce5e720f8c983f467886ca4e982ff421e667e4f03164e90951b7ddc76804e9d9bddaccfd046adbc6e86ed5f96271d794cdb89df0c0a0541007a2a188c466d22e524bef606f1b6bc6efee90596bb1ac6b3efe5dd80eb5b95947540d7d7ffd7ecf583bd77d86f036e88a2618aa3878b8d733b68a7d0a10303c6319ef51976bf4ff21f0200fde25d7237c2f58f83799e3b77d883625b9a5d021b6ee39a26187bf60c42d6d43b91b727f64f80f5024a44a08955bc0e9a74a30f030ae11d3d70af65af781348d4d95f863eca2a06ef2a43bc3ca1b95059cdbcd95b0303c6aca005e274bf7069bf34f780514758a0854d9d9fd0f405691fa85957f6a002168f27a27c2ae8b1f2de71094cc7e2eefee700792039b876b3a415c76e11bb6103dd21fb08d28a849dfc4f624ee34641d77b392e641b786e60019b18324be85f2bc56d2b7b1940ad886cb3526b958773e2945ae41cec16eaaa62c0eb2dc04942c4096b0e7da94df88cfcba7591c0bf5452b4f02b0a2abdfbee94d9eefc0c8c1193d5e10a0f39f008b4c19074d9a8f83a5340c62fee04b803c660e7cda4a226594b098e0e70638248eedb6ce16ed96c0c485b72a6fb934dc8aac30ed32ef222af56484a8a0bce2ee52fa82a1c90512c26cbc6d73676843d768eac0043e7d85f24ec7b9ec3f28fbac2e988b45789fb7c4ef32af7fecefbfafc69b9a08da4186f763e86cbbbfcc8b43837e03d4211ef842b4456827dfc07af9eb1173c0ffb7847f50254a1cd0873bbf373a3eda7760eed7cd24e696a90c5509add197f17b1ff2e18a19eb3ad6b481b69815f9a4045911aede43a0ce46837cd5379d6c31c959ff01ec255ee1790805f7fa74a4b5b120a7be6ddb43157704658f96437dc91d4408e8881eea4747bd4a49cffb57fb70a9afd13405ab29a86aa7cf3d6d863a3672b9fa277f9d37e5ce5a8cbd2d336a49ebe56aaa2a54fbfbf9418ca38e6081b854fc86dde6b1b98f53204697b9cb811c2318b298bdf0f39d803338fa3e65093579fdbfc32ec8e77599921f79be8a137f10a33f51ee0c5a94ff15be24bd52c0317c23170b602cd119017059d57aea66f98d755702ee0bf0e838e9684454691366feea9db180484d00ef19f03716ba2a855ef6a3899c1d3cafbb5c868dbcc4157d6a2430918c5abd6cad184625abd8edec9a38e843503eb3e985042f26e8166b06e792affe53d5ac9e58fb5fa4c58b3eddbca45efb055ba53b9912095ce209a4ba34301e2b0fcf6ba70f7a57059e6993df5cd57789241b89d56d2fe9ee8e9f6ab0f0a8b4937cd583569e06a11f6a7602c71655640c6ae8838e1d64bc972321790976c7ae4a7502cbcb37a6b343e12ed81c60c6de7e29727e9c9e3ba48fb06bb05679ba140a0d9588e66350b0c519c792af251bc2979be75fe90f962e704c45366cc2d77efd36e98faa5c1140b6a02186f0a7927bba2f51a341592dc61b68fa4102d0457a119eccc8bd5cd7810f8b2a68c7ee9d02efb3a39a8703d00386a4bb0616a6780683414f16b8640f634a6b4cdcb6f9a905eceb89aa717fb414d581481f21be8ba59778e737491f1de1dd41dbadddc73467e36ecdbc6f5b0622be5b8f908350ad697f987a4019b6bbfa0581cafbdc1ff27d301da8edaa513cb64dc81d0eb1325924a0766c851d44cfdeeacd65ce69af747d2fa078ee310ee1132eb848912ceb3b69489945589b7909c9b49119d4e84f1b3bf0de4007c75d133f9691a510609d50e52e13da73a655e217bc4dccf0d05c4f5fa796d718214046dab9142462c93cfa34073cd47864cbaae3c38d5af7218a67b77f737e6468b8cf16dd8e85cc8d5b8b858a8c31be9bb2c46a45fc9430b71052a586c00e5538f1fd994115a530910ea773e63839857fddec9af968182add9d027f06acaf2afbd5f7e4cad2584221fc27d9fb2abc45eeb6bb5e5813ab16f8c5d440766e9b89e7a96d729ed465366c33f29134c09bae501edc270377cc2a9054a851c1bef8314c00a30d08cd836ae9d4f14998689338a23a7102904e50164352766822cb762400af8bd80c8e56b1153d402dfbbab07ee93479bfdfae5791399422603b569093483fa2d716d2dd37b134da51a01bc6347fe11545ca6adf56dd8f11ba0a881ba370a533706148c50c1bcbd303e9af4d23e38b6b55cb9824fbcd985ed65b4bd66be93953aee2c195007f653364b8aa8e38e8f9280699c3e63226f8362ac1a0e", "0053526a", 2, -339457146, 1537743641, "da55f3fc4acf4f27b7d3621ec4056668ed61498625a2b3956d4fb224a9b66ab7"], + ["030000807082c40303b954e3134a453518bd20fca247bcafee09e5e4fc39f420ad24b9cac4350ceb56010000000030c644aa8778b59375ef7baafeb61424f45798de1fce20f38ca4fd1fed3e0dc8a4a5ca5303000000050063516aace4558bfa112b2a53f2f985107144fcd25591b5113a482e602701aa4c5d1cfc5c66930134020000000163491dc9190148221401000000000752ac63ac6a63537a20b13f2ce7d50300", "656565530053516a00", 2, -1557445573, 1537743641, "08ee2133abfe0e19a101862010b565d687ac2efba3b9d4a5fe1537324024ee59"], + ["1fd24e16010eca22163d91c16072d67d94242b9d2ccc078d680be74e2507c014b1b39e98c20200000000b42dd6aa0335753d0000000000035300630ee17c05000000000565515151007c06440300000000056a515251530000000000", "6552ac636363516500", 0, -1923103214, 0, "5b647b3f6d808317db98e8e196f412d8e6e7ffe9a64e8edca61ef8bf70505c72"], + ["030000807082c403025c02a4abf512fd81f429c237cdcab1751487e08595ee99624a7e3a50ce4e9cc80300000005655353ac5103cd1e8195174d6ef9727504ccd28b57feeac829f28e3aea57b0e8c239f0ed041643fd0b0300000007ac520000ac6aacffffffff03984f85000000000000bba0a101000000000365636342949701000000000400526365000000000000000000", "515200006a52535363", 1, 851486860, 0, "33667a8512d72bcc163409215fad62c8ba2b28e75256e7565cea98d962aaf726"], + ["15b084620216db3abeb6491eb0ba04a4bf42d3122afb4a0fc129a1677ec0ee37e09a1d94810300000003655152ffffffff557bec0af90686c74ab9fdfc10e39adb374a8b1359ebfb204d8cb98ffb3b5bb50000000006ac535152525115c0d8bd018de85601000000000465630000afb03991010000000000000000d81a900300000000694c0c460f4999aef56c639655b198d1bb386fdd03d9586949d9da415ded0d3e1a57e61d8562cfaff1374c81b0be0494a9ce008504619808c0fd316bb5e770a48f882cc9ecd7ac329e53833c52813a1ac1201ae85fff905ab655e6e38723ff61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001205b52921052d08d336927367adf343456eb8d07c9696789d76e2337c306783f7dc6c5274f278de5f00f45dc7ec1c16f62f5cc885bca6c64c886ab07839996fe1e3d41d0d5d4b6cb56e63b40f7d394b7d0b0ff2b35f2b55763c4702ad3f894be247ba654ec400aab18ecda7a4e665c0dbb100e9c107fe0c7cff1cb6ec1f7ad40200ff3212ae9f5a19e014557fdb91ad0fc23d2306bd81c811c46390a04733682a032486a89a5a10ecee36c797fb1b83d82b5bae311457f27ca818ccbb12ed3b59fe0a0064e3b94b1847d0428ac0f3f10bb8d118a73cc21eae16e4cd45cc284c83b62934dfe6dceec959fc855c28417db74adf8bcbee21559ece098f882363f69e95c50326e45ae5ae0a5efae88674b189fd502c8bf19ff9442ad39ddce0ef78e4c9718e0318254faca4d9dbcfe6bdced720ba13c4b74a0e837d2737d4f707138e1de606a803170cffb701996f27c107196d4a006e48f17bbef92f9a244c611b3306cec1e7cf0213617687e4dc06ae8d60677c04a26a83bdf487f0c484d698075963c576b6b59f032242fa330bfb644223b8577b1bdb9794f8d3e0e0d1557c0693372b10ef07ee62215a48d6aa9dc358f5082282f9a41dff22ae336f9368b41373dc480a69dbd0e07d9607e3b2ea1adc9ca62d56d5a474d6fadeea002aa3347a5e7081f5cfc8b0bee12697921e40cfc5b5db3856e01d886826ed400106cfd5c3fb48e9fb6c3c7057709c801948ed9b6a054b3621eb591f3cfd62c826df3743dc14604249ab022d0db46fd7458dfa3329bd1413655507b14910292dcf07bb143113b6b5eeb2d6b82bc2ca54d890e09da74d8da2fcaedba620a56c9d8f0de1ee975417908bedafbfa717a87ca6dcab40c21df15ccf5e671c044d5d060bd91852337c0814e166f3e90b2cf4ca5fc66e257846eac0551e1496e38f75d3cbf6038fbcd276432000f3043ba81baaffb9266b580ea59b3ea97628267d897e75a626014208bd053a1163088c9a82eba80d0e3d5158442bb3a6f0552153ca0b7a52c6c3c9bc8f6b1937e2cadf9587e842deb937611cc187d6e47055f531c477a607cc4b13343647947a290f2ea9ec071143ce243e1386e14dd9ae45a90f7e804444beb04ab211ffbfcbe6d8376cccd24c022817d95793a88510fbd46eca096b48db13f6e34c0d12989ccefd94c0c9c6b8936a4fbcbec00c5db7bc11c68ee8563600f784f031e03f455382302c86021505a8a6475b185b70d6fc3d15152fc951edb2453b954720b8ec5d246c947dfdb6a5cb9fa1f1a347d477deae430a488a675c50be6e3fdc8c185a82070e5deee906585fd413cd745d8400b1b5e4cb84756db0220d0c38e71cade9add70a8f68b78a14e2687ed757b797b976a7700d307aeefcbbffbe5ec37bb3fb00f16185840be9ea4dd2cea52ee3dfad63be0b406e7cb0fed377f100a96684b68ee1b3c8601e226bd44ce70900a21d923beda131fd347bdc4834351815009e61ac5e4451a22e29be6a40713fcfb12173ba635bf426f753b57d6f2566a85e7e85b7a2af0af0af15a94d0e2889330d045a9e23ad690d7a6ef8563fc14a32f6258d9fff74704bd449e2152a37dfe3c707156041203bb755f6cdec9c38c561270d0065b2b88b5d21c22b26f96b828cd412244b8cd4e539251dedd1f1a50e67a47121076efb9784c25a1d0929f77b0b9fc6e93175a43554541694c7e427af233b341d1a4ac1b75f44737c62b2a181b8f9e86d566af2c8bd54a73243e20f287c7be732de076d51c0859688f10f473b32f9bf992d533c7f6de4d96f8014fe0ec29aa801bdb585c28bf7846e80904074036551005ab685168804e13b90c0c7b01c84c8249302cad1bec0516f7370791ed8c0d6d771891c4441089dfb6bca9cd4c0bcbab89b91c65dc9f8c9da609e1b3b021ec441e12e7c5ecf05a311d7adb1e072906143f93897b41e9d7a4a7b36034802e333c40c06dd7388047e96f35249c4e82c01e0d390faa5b54c8fed9bebff7d64ba8b12033dbaebd678553e58924d721001dc05ac1d9bf39eda9233566591cdb6a57cf4e00ab3f4409905eb18520f49ec9c47dd6e9129961bcfe1e72e1077551852b69a2a772de62876c56e823764dc405180aec6e5bd072020346ef025d1dce7a4bed20c6f68b2f4d1f74667c0c1a170838d66461ae70d19fc583711635bbff61bd3a031539cc83a202886ac810da0bc3e5647013e6919ed5a7a2a800cf6ef159baa5ec9eb74704f3bd04d9e6155ddeff7472bf64e79a34e3a722fd9998909566c83d0e7c98847924e60badd03d87be871a4c37fae1e8e54f848c598139c3df5ef037ed825200199885e9d61d7f0ba398dccd10d0585bedba988765236704ac7383ff5796a568fa7f30ac053f94d8314118038d02a900e6a297364d80c2dcefb6dfb83d21d5a7bcf0c", "00ac5365526a52", 1, -660328878, 0, "77d0a9185d2df8b2ebedd9f4a832d8407f7b5b36a712b12d51d3c5183d985e72"], + ["ad100770049c107f6015b3b720897faf24a669e3e759c86368ac3fe671ba394f87b6ab037c020000000663525163ac518fabbbb2461d834a94af95fba08327d97b3e735ec5f66aa0964301d95ee376c772d99c200000000000ffffffff551c0cceda66f079a303b54cd57acf22eb2a0f62e1fc0faf42dac20223641934030000000365655350edd031f90f63a3a191fd88aa09febefb743fa7b64cc37ece8ec5435335ebf635dbf042010000000700526565636352e398efe60271f29f000000000007ac63ac51acac529a8e7a040000000005ac6a00ac522b9803ca01fa920e0500000000000000000000000063c5520273808d6d34295a9fa76ce541d1c26e45f68719613f5a087f789ace64f7c4163c995c51747791aafd1c3d9474445cab1feeb21a2922d09f7dcc56909db110b5fdaffa09861f81a47cbced9a94809e458e463658ef653f7515a9d6aa0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f96f3c6f843495195a9bcf83d78071438d4d5a755560cdb62188d6fd0cd1777ec8e6ae44faae51a5d20921cb35194a7c6f3ef6d014a562f52bb3763c632be431f312161de2baf9aa6d6aec8d98db6219ab20a3c653a40458188255ed559c55533ff66657105d886391330772ecdca5cfff681c67cc132cec4ee5f57511bc67303133ba6b89d803e33cdbf59f9412f219c3f4ff2ebf436b97fd2150315439984c50302dbf2401e67ac700d6c5151a12a5c242e287a54653480cdb87aeb0f9aabdf930a056c67ef2bb86069cb4ea80ce6ea3ac9928f7247b6ed3cdf8498564592ee2b6ff12933d982d503329f2fa010e3d080b4a871c562f3cc6e582b153de31ad54f85032acface9d8580c51a42b44bbf314b88804bc33b3a190544070e72ffec3a9a1cf032671e1892b07e46910c0dc547a0cbd0d48f00a725fcd53527ecfc1b318bc31ca021e5396e5ff272997675e784a6175a9a06771bacd8586b5da07ec9291d0a6c5be030d5e79bfadfda63a10956c0c6b28d3a0389205c3074ac3c554f1c6eefdc9e519030280a74a023ad591da85c528f6eeee568282ad8b55525c51b7fe5f532c30762b5c29c707034e69b36702f10d820afd577baaa9b8a8cd6421754fe8d7aea1d15b43528acf5081e3f3da2f194ea60eda0ac33e847a60e8425a7bfba6aa43fa74e1a62270e44b8d445a63dd2b5878353b2b9decc184277dada68a9b07fc90ea61d4d986e1718fc731b1d9aff589ee7ac5c2b9f1fa7f8a06192d114a894f216552243816a6b8cc7c4168c3d84790663eb639b39886b65a12ed361e2e662c5da7818679f8ba0a49985fcf2e8b322be8c71a9b71604c48e177cd83b0fa3345dd574c9908296a22cec7fe987f3769c69828cdcca9d91cd9dc80229f5acc9c5927b41122f924386f4b3fb3a6f9a8c190a2bdaa8c2c2125f764822d45d3b98199ff90b193e2a595a89251425d6e194b03a3f6a2145e834df31c365b316ce7954d7ceebd080d649dfd46550ccae4e456c31a35575e164a6c8b98a4691e1d12cf06d0f8235db9b17ac11efc787e0d30b90f67e1d2925d663d8c43a61336b351ae225fa64b23c70d9f633f4d04b0849bb58799e4735e4248d2c3c6a9e3b019c86f3999ad0ace6957d2afcd3f5c83936133b7129328eba34eb59bfefe35543475687f3809dbe373273921734fc218e22828e574c2207a1b3e46fe61e34841db2112cdca18406d775717b362b952024fdafe82b06251e9d25b6e1fee359a6709048615b1803ee62f075a834ca5d1c98f2eedac262cacbeae331a35604bdb0541a50f5574ad474993d8cec748a03025b05d0c3b6854d3bb996cd9d829056f33340f8b8139649f249f522d3e061144116471167e1d0c9a6cecfdc938fbf69d79b6c784c31639ca83586988bf5198cb2c5eb5c0f26ae4e7bf7c27df8a2fe9e58982a5acab9350fb0b19037612f448f7af82bf265df6eb006a853211123325e6b08ea891076218a80e52cf31bdee118462faf0741a21f6e2917600b6b6cba2cc01d20c8dc0fafd27cb7194d400b93ae681fd923703c70bb67fb229c93879545184dbdb3c0cf27b99292ab0f138f366fbeb35fd0475128a104234d5c15cf0d81cfc51be90dc6a752d461a16ab94f154a0290189db0a2c4ee453db5929db85cb5f9403950fe0a0abda73f615e643932091d79b0c869d7e0874d1661452c6f7b0ed7fc768874ff3d1916761c120a2e6a26382e21e420951c3777125a5f543dbfa1966850e75660f0d16e0676a2af3e42e6858ddaaaff132ffa90fb329c67edd3633521c2355394d99350794ea74fd7ca21230d7c8c1960cf4ca8d7266204f109b3ed94c678917307f6dbd72ffa0105e3dfd537c4025670d3cf2fcedf1bee1d9cd2565755f0457e7eb37715efa06c080da98f92ade65411415becc77f3b40f62be89eb0d578d7c1fc4ad63708599d30be531eebe5885a82823f5691889b4bfca751b6befe9151494999786b81fb92cd548793c6a093127ac093444edd0fef79c40fcc258850ce9cb7f149e223026e7d43b1ff11800535e578ef7fe7713a458ee753eea07d5fcf455102743faa9ccac276831fa5c3060babfffa269f87c7264d2e63e0fd5e14bc501426581968abf231c10e68cc342c7135fede859b31d6826a6a3714f122e0501c48a8c5c7c9e17c0c9b4db53c6f0173213f4fe3147d9a430006b9fd8e8cf33d9d49d6a2e63fdb312f775b42da205deecc54b15ef8083ea1b760459e0924b66452e4422c6856bc6c00abccefce10b912c897675910faddaa1c5c59b40537f5305344c0c20c29ff1003627271a269b807079917097a67dfe8a46f5a91772e277c6531bbe36e22926a8ae56b4de19d58bf1f69288179091963a7900809222539faec6574b1110f3f9a239d7956fcdbc01a148d08bf2a20d", "006353", 0, 156952389, 1537743641, "5954be524ce6ea89f4e57e97355f2acab2bf4985a5e231c766f933242e94937d"], + ["b92a0c4b02ce0295bdd5d73447414b8312b7f4cbad9d1e2f510feb53a6d46b0d12e483c53f030000000752ac536a6a5163ffffffff90796a2a2af288b889ef471653c78dfc4b9893409ba950c29effa6079cd0592e02000000026a522232cc12039280a7000000000009ac525363ac65ac53536f277404000000000700516aac63636ae9f9bd0200000000026aac2e689e2800", "53525152ac", 1, 181524863, 1537743641, "970a22c22cce5d4e4aef03bfbabd36739d6d00bd420cabbf43c5df41fe402c73"], + ["030000807082c4030458a8239b5d5ddfe08fe402a2e6c5e6d4006e54a42dc5b8b54dd43738e0b93344030000000300ac6532749e568cf1e3c10ce7ca85442ae668ef0e964fea104c794b183021fd1eb8d03236a75d01000000076aac535265536affffffffde037e397b406d356bd571d452bd70071a853d4a87345da6c5d841d86f19781903000000035100536b67ba3c0466cd166a54578b1ff1ecaf27fb7029ffc7a7cda3353132063e1af183de992e03000000096551006552516a6351ffffffff0495d16c0100000000045365536a259db2030000000001520357b40000000000009d607005000000000100e0bf162dce63fe8100", "63535265", 3, -1904990253, 1537743641, "c3c9335b3326af073e5caab6fff8aefc8f8febe8dfaf823c6affc20ea9eab77c"], + ["9664bd65025689192b5a71209ee33be4543c5ace71617871f588bb92ec0434dd025ad403c2010000000265635b3bacdec99011243f6dc568cfba6f815e1b1bdda63436ac3972a10f032831e95291419f0200000009635153acac515100005f29fd20037a45c102000000000007561c0300000000025152706af4050000000009536a6352635152535100000000030000000000000000c9d79803000000007297df232c1594a272c3be610cf845548e1eaea7d5c33955e58e74079cf0907655cd49acfe9787cb1a86f84f67b307cda54ddbec3650872e75818ad49f87a1688d46d8f9dace0bdcc7a76192ce2a0bca6276c8fa5bcdb9f6e0fbf4ffb8e6dfb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030d3c55b5c0871301309da26c1b441da05505a0db645c807f6b796a04287c38e600c93dd525f5b8e6db30bce061d71423819f34709641f56cd4de024b0e243d74c45ec0f696d023af4382d49c3664a54465b227748f4976c2f143850351167f385637653255d478977ec379b55598611bcf104e2f26bb696e6160d799ff1de280227e014ee219fdda4901975be18381a687b9e98ff6b7d4a197fde30f5ca9096240306fdc0118109eff5291b976356e0aa752ced8a02ac7a0cd66b0b13ef1e9b38c70a01a455d5271da38f675514393268454b20ae5c03d045a6616bf600d61e1a8b10759bb1a55c4661cbae830403dae291fea9b887859bdf584f5e297f7715ab095903197c0f920485dbb133bcab06c32c256f31830e4768d5a61b60ea376aab7e54ae02102b93985f0cf85eb7e6075ad99b54c0a093e7237b4d3c9f681c40165c78456c030741af77883407130aa97bed40f4eebe8e9952cdc86b54a93b69778e76d5af740225327c580e7622f81e0b494820c48ffff6383a458951de19bced14fff5f21ad60223de11fc4a4dc8a7e1b58e1193a7422c4b2f97c126c6ee869880627aae3f6c1c2854c1c2c23a55f3d3a13e652f28e00fcf5138fdcd2e5c0e3770efb36ee490143116a16d5d1a03c72531dbe2f865e9f4d744e30c91189cfc3f0bab6689add28fcbd93c6c7718345a50b2ea624722d0c2c0767bf6be0a9b8c8f98be059587e039356b37528e83ba7a3a610daec8696d0934754d01f575085862efc5c01dc3c3019f318f9f57f3b811ec17f299912825485b64daea16a601f6fc75e24a999a5976c0226b8325f21459861a3811c3af014488c641d01d8b63d30592f20d71d7ad6bd6bdabb08d30c4fdf9d25cffe04448eb5d051a440a7ac8d84c154b7897aabc693893e44d0975b8b0f2a747110600ca3ae5e5fe15116ed13d71e0545b9e61f6500a14271035d35f0f626097a1d91f0958930f8ca42deeb5cd3a82bc0b499e0fdbca9798e3c524b34ef97556e2afe79d39f2f835eefe90593c0a6f3f048ee50c59ccfaa1623f161a720ab4d5031cae8fc9fb65667894596443573ddea847182ea6aed2d1d4db2f795537db491c93ac3c504947191f23520de9bfb5d4469b7a703c04665282df30b27337b53c5655632cd38413c263bcc544297987fb094e591708c5bfbcf0cce17b3b4d907ebfc7d801ba6cd20e95cea4c23e81b1ae14d5a8ef3edd00b4b5f56697bfb157c3a6bf7249be9597d9f930985286d4c916c29f34a3ddd0e77b4978b21c444c03dd776994e08a2e346ae7dcace4af69ec66e26a57dcd1d12c7491659560466e6f547f86dd7207968aae6aefb701fef2dd8c4cafd222daaa13dcb6eb3cb66be4ddabc783cba75dcecd7b097badb63aa4b6010e342c95ebc8c2a3bfc3e56917a047da71f12438d8a80ea2aea3cf391e93cef764e1c306d85bf7378a6c7810861afbe61d99f0ee7ee47d14125a6324313db21aa7837ba913950deac2afa88dd4c6fccaf1aea8131382de942bb5342327c62a112ebff21e8b78bd7547ee5a327d7567aa291ebf08c9ee0ead653f9a70871a28a24170de15947f27d1c0c93fccadfc15aa3ea2ab5ee9ed8aff6b6f61d88ccc2cd145b45f1cec5fd585db8e1f0f58acfb1f91ec7f804af1a7d6fc9cd1b0293733d1265059424f789de0b6f69abc20562c01113e5f65493ec0f2d91a87f502b0c5af57bc19d5c0085abe578c4569690c81285edd99d31a2ac96f012c20bde6b066bd14cb72732fea0f5de378f2fe7e5eacf431061185a00881452ccd90afda840af4476a82f3bf91a95bf9569b121a400aa8fe89b2b3d8242793747f29e4f4a3d05688299d4a97d273c1c1ec5b427da7c4874df12be0540c8ec2b640a9e5a0c16f1a92e83331a446dcfa3ba03cfe938f947d982880211bead796809604d36fd3ffadbc764dd2803301d7b733956e4692fa0aeac791897d2189e6c1b364805a0c0da754ee26a6ee4307af7740b1edbfe5eee7690e07f82684d0b91cefef628417859e10138d4955eb79a8cd7cf615e2dbcc421f94a0230770b3451bba4be1ef522237f5df9089e13b108dff98cd7c0a2c621ffac6ca3d95977967697d73ddb95bfdf2ddbe36f641514e9e801249f695e979bfe01393ffb3ae3f9ec1eb7d45579a7e99e087862bc153cff5f07bd9d7ec721b0c31d66186ec7ceb1fa7972debed0a4dec4707d4e10f6f1b68c936d47d594d59d42a76fb7f719e9be5c8abca5ccf25a5327d4c2ffeb358924999a245eaf8a08e24bc7d223c4d072f000000000000000090a49502000000009bae751bcd5232684d57bc21a6779648d5713b224a6263ba466528b03fc7c3d3890d92c1b68eb9d4de403799e02751037cb55ab15b32aab280ee2bb5366ed72c2d2371f8577dbd5b4a9e1a5e7056c52a538d5d39f8fc51d5820333245da74c3800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097d41635c53c69f9d5493f2ce46b2620a62336dcfadcedef0fdfcde287eb792c4f71c7d7393baa48057a7fd34012106667d9d0fd570329e5e40fc2be9e0ea45764e314de9468cc6a9606bedbc83fd9301c1c0e6e20d12881781771fcbb2189fb4255ff4c86de2e159896f4c043663d0ab04c4680c59cf9415d12962b695dc01021783e60ef5063aebe3a054b4b841c92bfd30970808ecaf2c0476e8010df1f5a603243dd3f305af3b45392f5bad0da8d317e06de86bb52a804b1b524dd543a876780a0413fd758ef1fc2054107ce2a48f268ca37ab16cc9b1bae6f882c44cf479969af4f514177117f1c278d1cf0ebdebfc7f19f452ceaee9c9ad2555ee5cc267b04b0221cd10f978ac78c7c5aa3f3538af71e3f7e6ab77fe33d08416f1599267021788031f7d7909a24a4a7bcd0ff1176a2ce65b9ed38bdcfd407c8a3889f3ca59f4b8930208337d9e9bd6deea72bf3dea06d054a74f5ae85850e2ed3c6aa1b0cabf32355703035b53b4cf0368d276ac6758090b5d8f677247375b8fabd9cf4596cf836093270201cee164fa742ef4707cab59645d56976c7f149f6a9a4805dc840c6b71899d43ad5db84dbb6b30efd775cc437090fd97faca4e5a4851f0c5cfff989e3969a19229278aaa58f51d212de6b334240e521068ee5f857ccc3a351848e8d59ec364829ebbbd13b9d7c247db24a7c8d4404507518697d8e5ba86ceef1b38ab456f4363e5cbea81bc645e03f44a4452baec9516c57331a9929c7da8fce4e3706c84f2ea5917924e83dbf630ebda87536b275942a3c4e7ea49723db35fc080974744fb9e426261d3d3f0a923a23491f95c6e03b6acb117a7a01a638a689afdbfe8d95573f1c5379c563ff8609f93fd00dc714c900fb3cc1531a3cef0d38e2000fef652d03283b63cc545cf0144755caf9eec86d0ab1e17aab5742e6aa3d0b7fb3213fb9707b2ae3bd5f929c97a7b71934e29c06042024732b20c526109ba53503a4fe7db46cbcb5a3b173317e4bd16d75c636acda887353dcdde8b0474ed203f93b3622942cd04b0ba9dc0fb0f60120715d81ebbfd2f90551e20f4e2ba6e361dc279662a9b2cf00b47ab9cbe2673a8699c5facf36e386a5062ff2428a7f383823d1dedc50e2d2685397c5cec9221da4a518d67af017d6117297cbbf0e96bbcc67f2fb23a89ee6bed0fb746ed4edcca8ef44aef9a5bec95217468587c8fa1bbff93ab2a1078536b4cf78272a28fc34d73c10f8128d187fc50455d411a2a4a62eec23703163e6cecdf613dbeecf741e5c387114ad9179cf538219f7e83af2e14d61ca69800777a09a657b43af1d766c4d68b0c4dd8bbfba93915bbec132922540ad2f3e3137b1f7c547fcbe4c644b74cc6a60481bb6758da5b10cad94e9cc88dd52554f063478a6dee4e9a5d1a67ecde742669b1d5859443fd1db2bd44a39768e06c1c1767209d1622d7f3e29b79561678789b80cbde5312f3a50f9f8c9c7216d1b7469e847ca2092136324f94a5f12ebf76f82c29417feddd8d977dcd02a786480c2334cc293bf1c44270f6a5878b8b9e01845a9804df5c88013e8874c723f744245ad9d8ad4cedb316b23c5ef042281fe1cec9d64f2f5575bf6d8f109ec16da1c268daf0d76882b4bfb7ed8d65e8ee640509fe0aa93d8147bccddd5ad4652b675d678bf36cbe8528ccb6fa21fa0774aadb256ab54d4b05ddef9627c2d27185c5cfb89712b3504da9eb25d4c53c5f3391cb737e2db849c4b670da8cb38d5eae3e2350f0d2f54c2f01dc2a92435c34c2b0022d205edd7b7f21f4ac9f5282fefa385688e3f2f4f4dacbb589dcebfab82034e270ec9a295bd1d2544fd83c369c22eff7c909e81612bbe7c446808842099f3a2332c3f216a16fafad1613e45629fe8db25aa79304cf375b9db32a4430cf37f40e05db360c51a3ebb84a5125456eafec4f00435fa30d32cda9e90c5a10dbc9a5df4fd37129667d3de0cccb2a511152b2ec69ee463d1d239bd1800638044384db7497f05290d60f8109649761b57061e54db38a490df984e9a46a19f533eec5fb9e440b9687f1b6279ed86b48fb424d24fe70acdc8ad76a435446df9fbea107266384862483374552feabf9d64f4068b42999d8bfd23ed4b9f4eb3e925cb5030ec9f5a6010c6839de111fbef7be82f4ab09a049b827960b4bf1aa48fd8438200a0255f8e7c19af49ed8855068e10e4b29941e20213bc2a4f12964c4c4b69726960031fe6114bbe1457fcb36637c833deb0bbacddc89cdf9082ff8b11ecbad535dbda2c9995328a8899203000000000000000000000000ac6ca096ea0dcba304da61aae65f9a73dd935b788abf74724dd354c46d3ccd97b341996eb84aaa79fd1cf9497c38f343350ea98d98bb8e6f8726b7232db001e7aa8926e85e07ce78ab26fb4470e8e882dedaf2564db757117443c45022994d8900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000619db6746d409be8e2584fd19d39be49db9a33291cb4cf88161a1380da1ad6bcca4b6f6a24d097e54b16fbc33fb36e9be45f6214c9c408f0bba521e55e4657379b9419ca81592ac69a03dd066281359bc872e282641055ae3dfb2bd716cae88970156c8c51616898fdfc932c35f272ab4a50fac1ffa79e63858a3f39a8a67e28031a6ae938bfcd4d2f902bbc6d7a880d9418ef263d82da963845bfc8af8228852d032f2a1e912fad18325d22ec92ff9a48a645cd6f415698bcfe0e10c1e94ada4e950a02b7117a7cea3147ca0961a5604d53a87c053ba93782558d3e99cf0447ad1503bde86d87334bf8d2d22b1dbc75fc6d3d8d5b054598bb883e495b8f1ea70cacd70329bd603af76f266f521eebb3f267c2f1781554fe7c7f84d83038b04f3b58fcbf030fd662017c4d01fe37b0f2d1728f2b3a0d7fa2aa5f53f2d8fe6a2480802f4e44021837d639e3167aa2d4123484abc5c1ba7b85db56be704456071578c1f13e67e1031cb62d108e1d8bffc3639384e2b797bf78f1bfc09a2fdba947d6b81bf43bffae02009f32ba68867bf2c6cd087eeefa3eaca259a3b3852028a69da8016046f20555cac9b1c9ef79ae2ddbc5143a4912096705ff1b40560a88fbbd2e4452fc2d908d989927e01f0b5debc355f86c0cd7854ee907d7198445e72cc05cef5b05da743ad4ed35169a793ef38bcb7403e8fe185af40639fa4ef376d9d9b30cab8f9582ed0f3e879177fc9fae348ffc8184d5c2d0464c32656f38f06729d2509c72f064555f1ef54e452cf4f64b1956c857631c43612bf2f4345faf090ba341416087c356eec2633307f4fec382962c20ee3292f070af3f8645b546df48de5a527b14c45f08223ce79c4ea38aa17dc163296098cb13e35d399ae38b9b6f3caffff3c8de56c12f3e5d40a7ee89a593b819aabee15cef765ff42a8ac9598ca3e40c60b4ee66f109326889a260ad3db630882bdfdd38ed7686fffebd24918a63d66c265bb2ce1bfe14d12b589860e68f4e18e74bc670dbb9ce56da8eec76510631d0f535c6d8c9c9c0dec73c030e2a4634d50c55e48250ef4547a535f369ef6a59232ddc5be6cf1a8f673582a6ca4b37fb5fbbc74a196a0e1e068484a255028c32930ab21c63411114645a9c663587e9d990d607e126737607d84a4fbcdb7d772c5d028fc2dd7497b33e2076b6737f3aca6663123bd31cf33e0593337a3ea2eebe54a23d0900aefbaed3f84b9e6d79dbe73706a77e340230dcd6498a5c620361a84ce7f7fe7c2bc450f46ad56cf67664d300fe3b35eb4e7f38204c81ab19987a2a06d306c0535d43d0f700a96972959c5ca5156bf55fc484812fd8030e62d67b0826c37072e1831acb9551a7eb7a594be8ec1343d9f414d682b5103eb54ed4af9d667fc6b72e02c67bb09c3daab071644a00ed2964e730f369d2ab78ab9eaeb6e9f3517ed2710d8ebe66c8dba79c88781878b591644d14afd6340255dc52330848fca3471eacc33a97ae3e0d65e8423c258a6078dc3178184a7b0abf27d88e74456cd197f2f91b1cb5f629de7ff3a805671e9ba0e7a0ed3bc41b9e19b9c72f0cf0112e5669c06630e0fb1e1718c32e057139d3647f39752f270988639c29eb6d75eb2a0fe949150e42711cb43043ded12ddbb03bc99d0b4cf4fd8ae903d76a5edb07b188f907221775a54fa5283266ab8e44da7f30c190aeb706669e4cb06ea4d9b6189e2412b8e3b20783888ea03e6acccbe553592ce617ff37df466df0884eeb695d886f5a27f664dc0eee0de084797f6183e2902492c57c4cc4311aeef3d4a00dee7ca4fe330b36a5f4db8f14747e7a8b671dc6f1b689c86088f0d7673a0de8a2b59dcd4b9fe8f3a8292de19ff9795f1d054aed17322460b46a294535466e3d5f0a8faebb09699da5719f557891f3fd12eee02ad8781914aa26694256707c8e90ba460286c028a8fee735606e51a7be16eecf24ac2ef48e542185659ccd23c9332e911d71ad6c9fceba7827b3af2898a7abd2346cffd8ae31edd7bdae017f79b96a9c63b386c5263e13a1e5cb43ee1fdf14a60bce3332b55a95ba85ba5e460fa0bbfb6c5ca8eb9892b5e446affcb315bbdb1fea5cb326dede31ffd94702ce552c945cd196ca2c722426574e67352513ddeb4a2d68fd9061679d4611f5bde4c8b73bb26185e24d4de9fa91381fa07c2dc880eb1eb230d5b2453772b01b55da154890e3e3ab2e2e6f781aea5629d724b2f066ce119880e8c43df4d900ed19e23773d738e4d27f6c5378b90d717ba83e0a7fa79a96509e175eef4a0b1ff0f7f89a3fe43bd8e5b3e491b003b4838e49da1a7edd702b9d3d82c49d1c18e0f1f51da4e5d67b338e75b4b64153e098cb257eba34c77716171f318c856730af4635ebf4cf4d826c8a3357eba6a4ee02ce7f1d87dfdf2ccad62007", "6351636353655363", 1, -222084454, 1537743641, "3507dbb6b4fb0c7ce7a8ebe816b59e1171f9a6dd42994a5de680ca13dd19c688"], + ["030000807082c40303ff5f983fb753a1e10bdceef94ee16f8f01e4eed55f5a9205f5de429aa27cd60b0000000004acac0053c9fd22cf0047040d2eb11fdb53f9c01c2b4bbe4a67b6901cc1bcf45ff882a0d737b9112d010000000452000051ffffffff5030f1d47f1c4d89d9af529daab00bacd2e520378d1a00aa5ff10cb99d25d7b2010000000953635251516a536a6375d0ef2403802c0e04000000000153d12874030000000003006a0067f4230500000000066552526aacaca7a123d1a534d4e500", "6a", 2, -909824731, 1537743641, "9a2a416f6d32ffdc8ecb2289d828534eda7c7d7e4d1f9441927c912315c0914a"], + ["f76ea95103826a519d65ad5972f43673b46884b721ee18b36ada46bd7640a63082572491e503000000086a536a5253ac0063ffffffff8adcb907b9180c459f7e080750d9be4c5a9298226da89f93fd7e8481b98b2e1d030000000353ac00cf980bee07c7d9f9c11a60b2fd418f4676e11a43d1cc7d2189a815bfda179e4c31aedf3f0200000003005351ffffffff029d36080400000000086a51526300516a658c0366010000000007526553515252ac67a929770246d0f005000000000000000000000000d18ac7b4095b6eed68abd16a1f784e0edfe1139576e04bb4c8ba794d17d2b53b4faf746d129ecd990150e9fb2d2106e208f77ee22ff061ab3af449b1d7975297f86d4c7ed024171183bc90ba8a0da5f0474cd0129f2eae321e3f8b9e30d81a5e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb0421326f377cdceb8351198031535322936191e22e939b5c7ee78a4a63ce983a3fe9970e2353ad25b52e98956895f17307099aa7add2f2108eac6f5ab2b5b89e9819b064d97710d87b99921c61de50da5f26cf58aee71d6674432e4f16f58ced27886a456fd87c656024910eb3b617bb6cc1498081d04371f7d910b1f0b54e02051fbc6d25eeb251080a21658a2bfe308d8c81cd8dc77acbb388d8a73ecfca10021169cc8dbff1ca5b9037c28be6ca3d0d1007eac1de49e4964bd6a218f72d151c0a00ec5df826fe97d295a3484c6936a2e985451a3669ef013226308473707a1d2954712e966035af7be13b396a95f2407d1811d8b642b4a30d22aafa95b4d0c759032fad00fe4abfae1961165bf398ea47fbb264b2b5d6c2e1d17e31ff1d69039ddb022d2c9674d61bc1f93ea45e3d13211d94178e926e0387fa26cc22dbb39516597d0308f1d990b194f328bdaf84d53d2631a5740c882af71d7184352c416e053afd95030f5386c0cb14cb2a023d649da1f6dd9f295a7c0a1cef3b2d038e817f82dd1f2d02203aa03a896d45c93d5ccb6b26c9a3a86be001fc40571fc162122ec87874df2e9d6deb4b4f1ee0437e929e4a7793738f1143b8d5241e2af7ccc2535b58a88a39e931f3b821f434b3e1ec436cfe99fb1f23cb692227ddf76203df38c678e77184c9242fbc8b670719aaffcb122b8d5958667cecd338563f34860697ee53a95f768ae8cf6f0b48fec5c15e7f677c4314b0d5a09ba4eedebbb66ae074f3e312c9b55f45b9e0c644ee43fe217f2b7acbb128e09868562f3af459ddb1a7046b0717570d002f274cd04e8d59efb0dc1f7c94306c8e838561347baf6406d8409c324696cf3783fce6712f655b7b990729f846ef5f4790e214ddb850a4d533cc5df62edbe2c5d0c485958670c99d49cf834993dcd3fbb78d8db94241a85100e51680c962b1190564fc99d34e7ba4e6e8478b65bfa6ed9a51c98ab5098c7e9880ea5e8d86196508778f8887eff4d55f0eeed6b8ff6c967ef8bce35787e55af530bd4a79fc9e01f441a16717d151ea7daf0144a4cabea1682ea656dcf90ac5d1449e403fdeef97d8d88b0f6c59e8f8e383b91b0bad19d773b772c7bc0b4af6dea4c972e68e7633bf278c8ef2238847524198a3d9052d37dff0df2d2a8f68252794c53dc47356326bbd87b754d0098ddb8be5be642f9a9402cf694e6b5a347f632239e9ab8b89d9e1a5a1afc8225bfffa082e066495fb27be97913b5432b0851dc90a0c665b04bfcfbdc14731e18199ec95c1103f9ca51e10e9a4bf6200d3350516259c180ba1fdb22d0d3c274738ce2a23330061ae7e7064b2b43b26fd3c801e2e63d9e837b929fb9b28b8122fe8edb8f52d380ebd0d961dde66d1e502aec2e9c94509c5e670c809f7d8b388b78e1d2fbe34c6ca27069b248c3475ca71c72950c64811283d5213599c76202b8230415486ec35d7cb8f04b1776285c46983ad03d042e0fc2dda96106ad43d02d9a5f4d6f7f5bcad66a7e5a9cbd5d464174f4f33260ae5cf72869883e61df468c14e8935c8b40700324844d22ac878f9884d53cff5bbe6087001aa7d4435d490c9e1fafa50c868255a9f80ae33a6b1d4c9156e29c7ed7a3a78a0afa222d3dcb8fd1f896a6a34c22c92c1e7d35e8c4e6025968ec53ac1b650a611fe3db88db39152cdd631509f15af0cfeb5b62c073724f36a1fce58eed98aa90e113244eb6a372d3cc894c6827e11252b6bd7f221cb1fdd60abe1bf05e4feed6212413ff5f71fd4c5db0adda7d8b2a21ae3e4749b57cc800f97e7378519710338bce0db9f5dddb2a648192f00b67b2ace42a577c2e9a0c9dae46fdab24dc2764e5919c3836f82353b5c4b8a5048a08533f14710f85e0cd13b99bad54221fad76058bed559fb1b4c5ed3cac820c7993738535885e65474abbc08d913668822698f1b6b26661a8dc2a2cd543c8a7536b61cf00c1454e01e7d94ee8e3502a5a0a52e2ed0837ccaaba55c926f58c331444f552f5a5198896775f8728defc8b8ff3a385eb2342e16c05463168bf2fe1e265633c915543f0473405f939f32c482c79f9a532159e62ff6f8ec2f2b116f931ade9a1bfd1be7653f04426bbe282c104591aa2c3ef097f66866c0a46de6f4f91cd048b5b866d5c22f52a9ce4e3d3289361d686e95dbe0428604c007afe040e5e358705d1449cc6b236002706af8d2d6eba2a20809c3d37b781289bf28bd4a9a5d9c59930f2d69af93198fec49993a379c2801fd9d6afadcb300f0f3d86398c2d395c277c997b80500000000000000000000000074f0e8c8d65fe3f6972a80f56c940de484bcbc2af2aaaa0555da62fbbc6390707e6870cd0d47c336f8c6f6d424ecdab57ba163ff9887e3f9782e2677e35923c3e3a02a586cb9cd840e9099201cdb436383175a86efafe1caf524babf2a41ebd40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060d898b179f65fb0cc2774bac4cda66b08c34480ed76c84d090f96eab186c64880b1479fd1c47e79c5e379ede454cad5af8813ac144c362eb0faf4ca4549696ca86cd558fea394c427adaaf1dfb26744e71984e5718ef9f8668a56e581f4534fb873cc7bdd4c376ecc0c5a4a49d89a87f8fc7a6284e7f10cd42f573292a4d1c6020d676da441cc296aea6eeb246b61e4f5c2622e7f337a494d9926bc57a356b1d5021752724ebf21f93e3496aaa111613d4f6339b7ac613f26418d246b7982341d200b0654e8aa553b821a1ce96e147acac5ebf8d118b55b3cb2daf23d1483a9b2de116cfd640945a614de113b5c4f80a7d7999bfc7c143d02819875b7fc8dbbd71d0f03193f751d13b395eab7620a418a6205053e8d4117711713f9dc8fcb5e1894c5bf0210c164f2c8db267e7941b0ac6eb91fce248b79233a487f7b3bdb25141301729002202c7bf56ca687de0f5fbabb6ce1fd8bcf54312888a555fde502c9e56b62b58f032f4cf70847ac72be6e1fb9e140b969cdf96cf769649ab296f06a52de3b5cebc102239f50fd6c7b1e53072164148677d46961b7f39cfc82f1064dc9db7f46b07a5d6a678b650b2960147e178045aef9eb31d4778dd86a8226301d77c69bfdec1a671b133918411f3198eff5739f389c4a2348b629eb53699d829304277fe57f38ab39a058c6b60fd7b45a18606f0e371864558eae183cd7dc936d46ee8c9affa33f4484870c5e686d88e32fd5e7d16c60540043bfe6fca382e4ce6ecda5e0326a5b01e952a4db320451454ab75c0c77b4b60ddef1204f790449919d42c17228bfa0175d335776f4504f62358e0dc57eb5c846f485a94ce3b3488b5156d1d8c2f43caba4b35cb78f4daa7803981e1dac8f10ac039238361de2a367583d4b0f8d1304b2e840499e1ceb31d6195feedb01e425fe2258b4b6f32dead7ebd8029f581695c7ff08da4fda1a573bf4b3e89f760fcf5058c480871d01501369b351dbbc2d3517429f63a3cbab9fae783789d547faabd1ff0c67e86130436d9348bb54af4d98b087822b10436c6a5375cdb6fa5a8ec7f59cf3c16c2084f6517dc041d16f03eae78024daf3e4bac973d125aa64f65b3ac1295e9c7d17b0329c2cafe98674f5ae145614826e41ad549077ed4a868e7919904e83ffe2edb5ba0b13f70a7f31652b09f0f90306749851998a87744a6657d2b10f969a1708df55ebe7d73cb24fc8202bd51b05bc422ebf7b93db3cf47003f82fc3987a394b10830cd422fd6f84c495a948498194354d2af0e16602f5bf7c02baffdd7aa7e53080447d494da383057fa57853249f4edcd2122c22b9e1259cc4f3c11328ad72f769e496e008f64713473587ea643f18375ca3a17c06faaca0de4d07de15965049570c2c83b35cf9f88ef30a39ab0807cc0f2bdb6c17904cecd81849808bbfac6d8df757d02151fa906dbdd540f1b9389f222827f18a04b276b4ef00e5f6174819e50adfcf75227086d3b59b1193d694dc362ea81be7946afa56453ce82c3af8bd0d64939dc105be849f26078ef4b9d5986e1ba5b4404d660ab8b8e5299ab475a7a928def771419231cd40e63e180f9a3018397a5a2e2ca2cc8c267826bde56921c66a66c089f93c907d064c6efcded3d02e499fb01665be658368d67895da938eab663f2ca5a431bb39b2f92d3ee1d7633f7d9d0ac4a5211a6b8b7ebebe96bcb35800692a5145e5a9fbe4db9bf1e5759065be49ff4243aa309ee99941aebec5cc84d1104a0d23eb04a93b531730c2abcaf8f864170a39570f15804964c5901dd1c283466f2c4f8980bed7f6471a0529513b7647fc4b787fddae50f16864ed3055902df45d2e6e44d8b9e49928c8a73c0496889edbd1fd08353cf05c97acb77966aba1783e0f1c8f89464f8600882723ac39278e5041dc55c546612e585c4dfdfcf9a92b29c83fab00fd2ebc73d7e667dd7e24a808c7930b94204a8060d7aaaa1e8cf4b864599394a36770e80a5a4d98b0cfbd9a0384f838630bc60696cad28ab957093a0c4a8f0303d798352946f65a43e518f024a69457f3e8bf4ec1b82962ed7253ba17b8be168cf896e3be674d35fea7604793b2dcbcec05e6326aef5e7c966da969305fc07e50706fab0b035c1da6316ada73979ec23bfc352006463475434370dce84670f8657177a7245d99b9c257685d497cc64585782ab5cdb9cb23bc9f9fd7e178bdd58a65fac17b54ae288c73d7731305ab376235f44aab23f5eec53f473e9a93ea2d6d1eed922f7e32c856681a44da7fb57af417fdbb8f684aaf599b32d92a46f37a76c5ce108677a7cdef98ba59674f698667084c9f8c83d69f09c5a2bebb7383108cbc5447535c89fb2bd2597b10443248ed3f497455879e3469fe5a8ee806c22150e8e4d5014024f35c92fec31262cb0f2a1ab70c", "6a6300005253ac00", 2, -1153722531, 1537743641, "3a8f32cae5cbb3eee5bc5cbae864ff9dc67a4fce849c9a985c1f54c1bb002757"], + ["0ac29e390102bceb635b13b9338ceb9ccbe339cccaae7c7bc40666459f979ca274bf36205a0200000000f67032a30130a3ca05000000000400636a519478bfc900", "650053656a65ac53ac", 0, -1085558292, 0, "8e2daa9d34834ddb5e9777162b2e47f44e62f1ff5dfdf399cba9b23ba3517d10"], + ["030000807082c403018a2a1ba687afea4a52029579aeb1d5ddded2bed188674a30c125883690c2cc4903000000076a5151656aacacffffffff03e4f4e301000000000253ac262c19010000000006006a636a65009894d702000000000351636a00000000ec2a3e4300", "6363", 0, 1890242588, 1537743641, "54ffacf547ebc187e8b53de85b716f107afccae8b08dff1af74f0337b7689d31"], + ["030000807082c40303b8623a3f3ff9d19434e3431734f111ce4429ffdca0b89a8a421de97428354e220100000003516363ffffffffb20ba1f6f396bee2616a59af0ff2099efb05fe32c30f9c77e059d29598d508010100000000fffffffffc670846c89acbeb09c68ff838225122394b3e5258a2af8d16c971770eb1639003000000016affffffff049c96aa0300000000086365635151535165a595e80100000000086a525363515363656911630200000000070065536500516ae23b6a05000000000452acac53a0de5df0d6d82e7b00", "6351526a6a", 1, -502947489, 1537743641, "af50ccb58784c20e1a7e9731aea5607c426d700c491d33ccab5074f11049a196"], + ["ef316154027cf974d57c76f066107824238777528d3cc8460c7cecb77d05d516fce7a9b4f5030000000752650000635100ffffffff4e52eab46a0fb57070a9d0f51fb56dc4de70a6c5e9343817013973357aabb0bb0000000003005363ffffffff024dbd0203000000000353006a58e289030000000000c7e7b6f400", "000000635151", 0, 1968658531, 1537743641, "f2e925d91d6ad259bd40968c8045f55966cd923a0eb4044b29644e46ec6520d7"], + ["030000807082c40303c3df1b2dd9eec22f2aacb231785080089ab9b6ba45a554128e092f1fddece5e90300000009acac5300ac51006500ffffffffc23f486b55d90a45a6cd74e1ac31a575ef8d98c662205e45ac11ffc07ffc013a0100000004acac5363ffffffff40e41bcc92726fb663a1c38d9ad238ce3961535b3c63e48737a81cdef21b647f0300000006006351635100ffffffff011c08d20100000000000000000071ec68e603acaaeb0200000000000000000000000016f9ac81bbd982e0bd58a8d0249f9c4def8d3c6a746768eee4661c991eff2fa38a6b35cbdb7ca7ea49f1d234277f19ac920991fef0812a9fa06f09595e25bb3042e9bb00b6e936563417e1ef99407b22cbff6a0c2f534f701577b21825f1da0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de66497b230809c1cce95cfd042e5273fe091143cded579bce06c02fe0937e54ba354eade0b09de1de06a481c0d44fbaf8a8595e10c346ccabaccd2f008cc94a688a2c13041e63749efb7d258e92cdd9d846eb0841f85b9d3e7e216ba4b1500f7ed070649eb0c99a4ab7534c94dd53d0d354c20c7f93d849025bc58388762d800319ea7c49a3865d01f82f01e95bf95d664e91039f7afd58524a8b5515d7f6ff3d0318858c7ba342c66455744149ee0407ebeae6be27cef4dce0d43535928dc775b20a01131338e35a7963484be6c78658f32c108f8211fa3b7f2e98ca33f35d9e6f6fb1456c9c244505fa3861ce578d63aaba4b2a1f4e453fed769d2cae6aca630046031a9d1de3e363453f04cd0f9a92cc1a6db73d3e0753873ff829e1fb56b1ebfdb60226731477b3ca0d73049e639a3389ba02b6e37307980673aeebcbc512d71b46fc022f65afab00bf9c791dd7980143c9b689646b86bc39d1229725386e244ee404730314e8230771edfa4374fa2db71442849ab067bf6dd4118b8c45d167cea6069d8b0228f5a7e335561f85869e44a76b5f772c8b0fca5e8e7b3bb3780addf2643d2353abb35d1d0d631a29525dec1c02beceaa6450f3982b663d29245b15658f16f14e256f5787e73943de9dc271d912cebbd87f4ced0cc163f24093fa46eacd36ede6a22ca339f8d52707fe29b1cf7cc774f51242eb352c7f303a58b9377fe0e397f0cb34f6606ac35ba1e289441496daeaa72e11106c3891316c2da188169b6f0592107fa36442a42ff6fad8bead1279a6121775ee11943d1b20fd61c0eb77e8649f7296dc2efe802878224191224120b9ad1f540202fcef5391fa7c663980a12bfcc10868a619273f8694f16f9b226e8dcc72d50062d0581bb9ca649841aac558e754a266436458684e1c1ffd23280ce68924d5a0c046f128fc0428313c86fd72101aaa65e224fdf141c1b79b4c510ad405065bc9b675b297cb9f311e43949414fe39d55c5afc48d7fc655cff071e0914be05dc5c6ecee0d1e7a10995519e79839bae73dd5b4fd6c765f7468697a06438ddea3e308fe16d55314e18d83faa1ba88a6d05b87231c26ae6c3599520576484bfab5a290e902c75c41e8adc890f70154feb6bac939306d2a8b7255d3e17f3dec2c41ce2b0ccb5ffe1dcedf95241e970af918f88f0217ddbd3eafcfa4ff27910855bdee7de53f6c509354cba8a499bf569649b0b441f201e403e99c031d2c6b9594c9103669178ae6985043472002b68d8b5c6a7b2c548cb5eb7998d651022c81e8625dc307f15eba116f21c3712911762d41072ed9dee0858bf2b3378c38856164a80262ca56754f853e6dc7c88d9040b64fa73727faec9038b2fed7df4a87988ea95105a2be867ccfd9a20ea64069dd264fdd6e014e78de671c32ccb56105dcb90cede3354d7a2df9e5de356de47b89f1ccd5b61627f2f25bff792259c6d79e25042fcf7e53dd6c7f353921eb592f4dce9bff16a7cd9dded1753d0b2daa4d22e8e7d887fede3a4b9a54c2b4ac4364fd04692ebba4dce63448cca21ed1257192e32912a0344e13c9caf6e99f8e3bb5bbe36843ff13dd4d43d73ceff94facc0f81ca31e8a2a73bd0ef394b3ed53465d055bc95912f750a4cfac64266b1552af0d933dfab3edfafb687820dc187df7a19eca8c2dbae6d29c56934adf670a1aa70376275708c6371e271afddb08ca0eb54c93a41e718b46c6a6e021365ece4ec418df7b08409fb1dcd370a0925dd3acf1c5463b5a83b949c4e859937efcd190c3486b533a65395cc647c435adae6fb49509d5263e75f09a896893ef73da8548cd5d77d1ef8fa84bd54ba7dc562ae99e2a28fa435467bd42847c1716e9043262148a9b0f06387f44d7e4318ac690594f1ba15c7671216ca1ceafb50d89acf42258da2e62c1459d6ba68d24c00a3bfb6eb479f4dedcab8724d7bd55ce3a9787697ff9189ca3fc03a9eeb8d1d54ec5109b68bd1ac617803ecd32773d130a876ad40b93baa19f52acfcd1bfae246ef0cd93c1503a14b9bdaabf83a6d01e72f981f9616da5fa648025f5664b15d41eccf1360d931a586f09af69914be175e72bb76caa0aac642a807650af533abe3caeeeea6d00bd69be539b28e3a398dca7edd35872ab59e193588b29e26345bdabbba58b59f6c04762b11d3ae247101f9c6bdde6ccca703d0899676c1c3604052d73ef84559d6b31a36c6279d98ad9b6f2d2a3f4763e5b569d0b744e96b889b6f08294f3d1a457700dabdfb198ed03f8b37775c13038adf137fe3cb0100000000000000000000000081243d8b97d2eac10dfc3893bcc95d2f4d12a2351def841ab4e70d567d16afc0c25d08ff14fc8ca1c2420266bfcd1849e1de1031587b09602273cdd1c5b5fdc8ec6105ad0c092982473ce96c982330c46075223567b111a7ec3e337d66c0096e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cdb2a85e43599025ed31b589ab3358027135c031d8f7ec598bd5ef62e9426b62bb045f0827d67ae4e7d3a9855c2b042dba21376cbae556188fed8c4bb2cb78aa260e2aa88f8076d43b329e0afa5e373990468ccabe2bea611198545ed1b232d4dd02ee9efd4568d79b5267b9d3461703b54c55c6cba65964f4a09571fed64aa30325adc5f51de18f6a4b052ab46278b71e1377ef57479876c82288f2ed2c9fc8850228e40c01fb78edb7e54a4a379b712ecdf63356337d133ed08801c7409d01548b0a0693374db3738a20f767490a0bbe88cdee075c92763026119e2e35a0de4d8278af5d5bff70a12298c91f30b03974599badec14480340e85d0f6a21046d4ff0d3031b1c9960d8cdd447a69069d6a85e083863fd7273909aed28228ad371cafcad56020beee551f060b48332850ce4719347558c03c4bba353c26dd8f03a5524bd76c8030bba634bb56a0ffb54c251ea41d162761186b61a539bdb912e774c2a494245b90325daa4670ac493a85617737cf33894796a1e3f4682a5fead2da94604f3477c900324ddc6924f93fc678614860414befe71100027c895a2470db5490595545350aa42d4fb774317d1544bfe8dfca7db61809c54c320beeb8e6edf49a371a5c22c4504ef474391b7b1617c932ab53ec1744392e197e082a2d69a16d5d6826677cc113fda614cff6df58014af508c2ccb2550d9d7ed08183ef321695ffb5d7b7ab0a48ca9dd4606890dfafe232618c50346067581527c14538007c8d37450278bb72796b6ebf3b590fd4438875365a55aa5c3081a26e12d3a2c790b8bef5d481c34065484c77ebec0303fdcde2da7b60c868deefd664c475493954bbaa6aa343d6e82c0529aac8d6a5c0cd90fb157c14ef65302694de9ba4bde2eb08b23fc2fc8ec6f86ee7bf2dc6dfc0361e725ec5d65ac7b0cae191b56ab00481ac9af1fdd4a3f9d621bf76b5135fd17b86efd1aaf7aafb58b78df6b0861f17b2263fe09b0c0e1bcfc5650004d6963519eceb9c896824e5d0a142934aab254bdf0b09165e3bb1ce3fd3560230c1aaa9f86073bce6736d72fba972e08a5f117927c811b70c315bdea99133e49fdbcde41d7715fab06551643cc0e1ccd5530bd976d3886b2089408089c54923f5a0a59f4197946f1ce720508ee4b7036bd38bae966bc0a9ffc668611eed1564b3fddacfac8bc76a3a6e522ee506a4a61210ba8a934583b11e505864851aed4fecbac636bdc9cfc566782160892b49072da3fdd234d01f13157e9b220a05ffc9e22c1f5cdfb7ba6307e05b67bd91be3c101bf69adc1975719ff674db21b925ed558fde7ebf757ffdbb2f4a8e74e7906f0b6d6fd2ec7b8f70f69603f28c258d92b9b1897ad1ea77c6f45d2c514d9fb7dc2a1d6fc532ea98475ff2e78a12835c46ccf518c4f5d619f63e5459cd19d530fe98f6d6668787a409f34c9b6f9f3ebc117079a9bff3e3f17fc4f8be27e6eddb208c7adf7d533dd8e0d83865a5b17691b8c1b5c1b3ec5a9bf53bc4e49e99deff58139e385e7883458fea77b7c2a520c6fddd9eebced08e0d8ad0d751d2cd0f21a34f81222cb239c8f5bc1ceae9c3c53bcfb785d763340a63f2f353de1330da3b9d99398fa451d3a9d4f34d7e0e476942a1514cb1a8c6b3fcc3d9739d596bb18cfbfe75ee94428703429e3095ed6475d77f5b8064ffec2156df04379e521088815f56737c29718b34ed6eab0c7d8adcb52bcdf42983b6b190004780b691eb49ac4bbf0541a82e8fa9b683eec06c85404d2e1331d677cc4cce84a9815d48bd6dd8b1aa5cb1afb233ff3ade529456aecc87128d476126cf558e9ceea1c75c45ad7401f7125a5fbd56c2f7a318fa48f9c4d25f68fc395d04c9fedc1785c453e7735759973295ca2105e54e4eb885a6606d6be622420cb51c90863ee84b24ae8750c66c3a5ff07c36279c404713abd40583248ca92735a388236c039c6c37e6db02efa9a406a759b5a939f484ee9ce06255e796478c329fb087ad42c9c37d9136bcf1f3b146d1176cde0e5170d0d882cc3cf93fbf55fc9a151dfa44264b8241e83358d891875a844283cc17d5600459f9ff72afb03775a7c73e57a78cce2fbefb2d7781d284be0905ae80a0ff7ed71b8fe014bc63bce701e07c4c4ad949e84f6ef1094972b02a4eccb1782e03b6e85c35a27c1093cbf0d7b47217f29a5aa509fbfdb99e9d6364001c823ce6649b4154e721d4370ae7680ae25136ba1a9e1b92ae4d973980107526b08fe71efc86cf984d2b43a0de3c6912408d311c7917a463c3b5100000000000000005fc70c0500000000d57464a0b8b616f922efd8ac40246827488235dfbac232367122926d36ab0e10a22fea7c4863f9a3fc790cf5f62e66a8144405df4e0c0384d8b82aac28fcb7df1da7fae4d77c257c79eb42e3dfb09f38105bac42bd4c056c5e27a5a6226b2daf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000904e78ac898ba055a11aecc3368e7165bc6e09ff770828a3d692ae9a7f5644d2ef9f5ba7d0c63757021fc3f060b0cf92c97d8099f7ae1480f3c0692ecacadb6d4f821c1e057e613c1e28d800dbfbfcbd7cb18086f5c0c9105d45ad1caa8cf7c3c711470b96a63ed8b15ec0d467ea37df14c0ebfb7d16d31f6280ea444f46e4320329beda6867da9b212b9f48364b4ad3a5dfedc3a5b300bfcaecdb2347b6da272b03251aa9d89714439a03394d00cada713c1c082ed2e387a14dea0c6c5f117d13a20a01ad843d24d2f285a2f79bf148b5058546fde2d1274ed39eb8fee83c1e856715a1dc680484e4fda5fe762018b08faca4406286b8df3bbdd48dd63b0ccfab3a4e03099c71f699bfdb26eb326388435194965126a80cc4f080464161ae75cbe0bf090314b574b4b90817e3b03edc97a5b490b066c45282b399fea98ae33b3e300727bf031d20e071df3f8ddb25d2259431e15b764e07e20855f20421061475a4d3139ec0021a3b13eff413cbb0f0eace2ee88ecace05f100323a665d1bb7436ee26d2d0a6c0324ec29a8685b7fd866388c4f499703fe595c274fb12cfef25cc5bb3ea5d04739ca9b6d101d64821299af876ec1f55d4b5c5d971babd20920c3d7f3a980ce1e662adbf127cccbfec247f4126b3adb632f3944172410b173e1a52339bb1e540ae9bacca744bf38088901240c5ce6e3f80a654e7d52fd7573ed765f50d88a20a8fa54a899c91d3d2838829399544df9fc87f87d4ce6032d09107f1974194ef9a04980c664093e09d2c261cd66b6bf79532bbb9dafb1d71c71652a2c343dd79ed4e7c1e6cb860e2878c105480c02282869e720c18c3e3a172a318b2e08337bbbff92cf552373861daf5992a58b7a1094e086681cc820ab95f3a85d739bdf47f44ab6ed97766ebac005dfbeb68c5c4d33b00229a2c43f3bc39b372d0386fb94ee5ca4344a20fc14ed27733ee35f78903a1b12e886d785b6adf89806d5b424ae2a60e5d86dbc7c3ac8177f623f8b3cc866f410d3efcb8609746cf42c0fd1c717596a4eea137d4dce6eab5ae26bf7ae7af6fc4067536291786c827d19844e00059528b740d771c4f60626e74cb8f750ad372a83b4032c6cb4507bee1b8164154f130edca792a684b2f2a66d8c916e7eaa7c91022462e4f17989f4cf593160c813724001f03b5919442e6a0a9dc548e1d560aef669c0130681d3bb788d705618532bed1b2d660e6789a0b1b7b6c22ecaedcb176718b027f2504435a4b32ab92baa0939c5d359eb52ff33d0e909f676ec46dedfea43b718f771f3baed337fd9e307e1d9af51e21242c74d40da347e5fe4c81c9417d20a7214912050aed6517c13df2d8589401d99a059127bdc3b7780f7ce8e7351c113ba3a0659516115b5b6d6abca37ae481aad3459f32c5727903d3705e7888f2b75ad3fd43c6f99ee3d0a35bf5384edb2a2f14d8630b1a02e45d139b525ce465402ff5bc619205f125b8c8564099989724759df2b83aa53edf6c2bdab9c9e4d1aaf9d81c7c034b1ae513eed40c18914ac5da6354442f87bf45e8d6a0cfc4612739cf5a5ac3eefcfd75ccd4859b48a31d6253e34f5857c0c96c69ac5d4ad5ea67818399e00eb343a5d8d1217998242f79b9df025246065a851b7187e1531cbb5f134ca7603368b8d4842de371a649a2e4e3bd282660fcdbdd16833737630e5c993d98eec93dd0f9a7551828813a3a841d7df6fc9a49debc6c6d7397b4c9d3eef50c402e76f7f0a14fc5c15fea0bb663ff782a2a2d204994e3e1c2fa720718ac3274d9ebb483fb44a6cb9ab0d2dbf6ffb095ee8aff660223045a16e0a9b88555f1e1822b1a00c57e9e51efcb8d6ae656555ae08a34614b7be4d4449aeff69f229d12777503f0282153943373f399ec24238b52bc9f0c541fe259704a0b8c42b14bf8251d370b9c52d3e10c9dff065392a44b79181f2e312e0edb5a52807a9a17ec1cd77c648443fd5a8d9e35a60a4a370e499520721dc68337dc229dd7e1e66b309795fc74e014e8e9872c09844f6903ce1ce4cfaf73dc9f78d425ba7095c8085a1556718933425dce600a2cc6d9540257657cebbab77c0701e0ebb4d539a517931376731ec7cc2feaf87806632bd2bac81a507433ac44f536f9a9c05d853dcbf8e8b0f775a2191f42fcca02d6f6b836561f1514c8e8db834cd60b23a9001f8d82f229bc8fc9cea34da6ba6723f81a33a44ff253c68f1c6c4bf056f78012e79fc4772d1b1f11528e04703cc8379b6af67a2a0d0946b911409ec48f920d2f51262ef4139b05ae017be324d9dcc3d1eebb90880d4002fc185da8141eed3dcb12b55102f2e25880c89a2c4db268dafc25f62b084ab94f783d124da0f134b07dfd5007abdbce7b42886e49c5cc33e9e483710c1d7f9ea6bdd03653a5e3cde50e0e7476d0a", "ac", 1, -1145859658, 0, "8a2c637ee57d8bedf2caff01c20488b5fabfc4a38e6585d3b883894468d6da26"], + ["030000807082c403024a7411500f5982849bbfd24462124954c851d978cd867f2b20a61663f41f20b9010000000465acac65ffffffff1a990d6104bfc4e85e8bfdcf5c0bdda19f7ca458ae6f8e8a848324247f7e66dd000000000265653c5f3c4204d782b404000000000551ac6a00630a028602000000000265653228d80200000000095352ac6a52536a51000846010400000000030051630000000000000000030fb0d302000000000000000000000000a4aa7488bbd0bf7db1ec73fefee568e877fb50f55b2de104f140e43dbfd7c21e0eae010ab9bf9f32c9097b419fbe105dd204be8063932857a332762591190af8e1dcd02656bebdb7014a6fedc4c028d939962d9731f0a751f6fd6df651138faf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000986f387bb184cbe7871ef3561bce8f04523540c00b5b4a1645abf75e61ff67bf0be349aa9e15a3521d2e76eed208b22fcf0822a75e03a1efabcd9e9ae841e83a2e17dbb924a852d6adaf20d15b96204338671e8dad68e6a1fdffd96f97722aef41b3b162d2d7af05ef0a1bdf042d8c74cd91cad646cfb94cc8d835b3944da1ac03171fd89e5609e7ecff6c606964dfce35af10e78e13e5c238539e914f2157844e021253ee2409652ddfd587fee4e427fb8040e14be85ac7de59520cff87284327eb0b00fb0312b439b06f777165d0e4224f81d670cb93e4760958cdb7327abb36529215e6ead094f3c2568533e5d679324da24afbe2ab1548a9034fc2348dd15c65e8030c825e57f25b1194cfd8921758942975f02e98c6697da5bbecd521bdcc9a6ee6022ed6c124aba2567aa45e65ac46e332c219ceb59b53f3ef6b657adaa7e6a2b4ad02036f57b24d1411b79ec5604426d00e389443a82f746a09b5ab5d449def043a0402199ded7e4ad4697b8cf1854763d77636ddea3ae5cd2ed67a70f2b7f6fc0591ae022badf7528076583b191386ce00a7049c18b097604caa808c997fe599cab7e9ef29c4b1785bff095080ca6b5e5c1f335f7068590745203399ef6f1740d39f0e98ccc83ca54e51e10ae54ec42ba7912211eb886c87c08e899851c3eba47cfb3b1055e202cfa2ac22a9e5a4772b912001e63025e92e1e29d8d3b134b87064e3aa8637b190a38b990e004ccc5b32b662d59b78b3935343498ab779b74932244daf2ae2a42325a724ec0709ce1db403ca03d6483369fe0bf505fc97291f2358cfdb93bcc8dc0fd56f9c1179f226b377d6ad9ada3bbd70f4d14c3204574c1131c9fc05b4892f58b1a2b3d1bb9f19c7826230df473f4ee7e991ee22cf5618ae216a45da04fdcf9b07daa60cd461fcdd17fed4529e7626d238cef3f7c1fa31a00a041775fda6b942eb89537c5a2f4ea68399758b60426db7736cd484fdb07e6abe33d774d93565d31b35b8ce1e3d753d67c3cb0910fc73fb27a99f84a5429afab5a5899d79faeafc2f15cb86c668dfee23867bd1c592d2ea76d1e481cb65bb1d41532cfdcc32b97006b603356b976d0fe8dfde95db8417e3c186a273f354f4b3a70a1fed56f62ef1a8b8dbef3243e2e1a5cb602e72a10f26be42f9e52fb8e1a5208491a56d055086fb73e05bae35ec2015d557a49ce88901287075e8181067441f8a61ef5db0fa0a9186b06daf5d4dbb03cdb2fc110b9ee36fa0c91c518a2f94f262a762fdb26da207522d47d4d6630ca105992378ef38ded02b4f3184714f67c925116e3e23468c3575fbec8cd13179250eab102f3af6c99f85f430cf398b7e2fd8a3faf40ec388ac77ec8e0c548f0a08ae84d120fba345a5e16596c4da3c4e95ed3a1467ad844fc24f511f9e1d26833a792653f074a5f7e045e7ba1c0fdbd9e45f73f71cff58c750c7c739d31d119b3a6858e47d8131ff181d7bc78a741a7ae6253973898cac2a3c2ad5e17d3b4071ec1f8019e79118af2697d75625c88da0f9ca2d550fa0a3bcfb645f803f8ca8eba233ce46ff0054a31ab08670972bf10df231c706fe2ad467ac350c9251567e65b1ab83ac9b4119d5f1263c66d3fcb1b7be5b3946427e2fc496d0665cb915e7aed0947fee710f828060a7eddce7ca9fbac7cb840dfc10a82e788905beb048996a5547fd4e77fdb73f58f6c08d70c7d62295342a30e2cf76256e0ea4a63a6693334204fa2d09041858ad3832eac0999aae8441c0edede014e86ae6afa1a769ae0f007db4f9f6cbf5dea9e497155e0a8d4aa786501f51d901965f82069ade39d5288f1330240f6cc299943ca7b7c7769a1efd5edcf37ed2e1606cec694601062bde11ce9e09aa50494092765b6aff99f274e5abe2c31f4ee6ff0daa696dc8d8c6f7e129619fb1910e50bf65962f7cedd57c8da1aeb3c104c73ed0f7499c4434ac22a975580f9801993156b11c9834e89e58f024e68ca3ca745c0794bc385999945d76c189ac2567140f3dfb8c15eaa9227f0a155f3d0cd6161e12815728f42a9323a5868f96c40139182dbf4c6c2ff13dacb76a01eeecd5d2f47c47e59eabc7722980a5b501c7209b8721667757409f6e235d5c3cfb23a5a24e35b7aadba7867735a1b26ef4500a89a525593469599bb7dc249692afc9507dae6f92ab2bd346025cb84b12c43e8aebc69d8538622acaae84f138dafcbad1f1ae521c3f4fa2217503da046595be1e325c219ebcc829d9e9787fe609c7fc01150ec2f8c93ef04fd66bcd77e2f226ee0000000000000000f8a0a6030000000075f24809a5afe4bb4277a6d61b6a986e60acab2a9a9809635279644cb8a31b6cca921ea9e2a9709b045f38897c1e3ab04c881540eb1f33f753fd7fb528fbf142f6872880a1750f79907a82929c7b50dc0fd952630f34364c61f42ccf6ddcf03c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b3a6a7d8476b36be8f510e33809681ea56467f797746754681541e5e8360ca9871bd7e05c7841db817a1c6b29075e628977021525e42498d16224ed22718a8b8f6f67c8f469ea24106d0ae757f8d84c8875c34d4b12929cb1cd5191255f5067d6f9223e922497836215cb3331b3361b8d5b6a2c35a4f5543e707cc27935a9a603053c80a85ae6de6583784218ac180aefa1488a4678ce58fbe5a7d3c35825f9f1022ea681acd9277088935b68f72cf02050683128911b5899436dfb6e4cb661c4590a045c75a5be251c7339493c60da3e15cf972d9f23d48f6c009c4aab7f26c62b270469c3cd0d06e539ab4ce88fb3510f881b2808cc8a9ea8e95cb94dd51ea90b26030b41ee9b0b1d858b45a836a2328f2e8880a59a2183b44faa0f4ff4e6df6c94e10328d923c59ada3f4fae77c8b335e3d59fb5823689498e29fa52b5de1cfa2f3b0d032cfdf8769374e66337d7e76b68231e4183a8005b3182ec3de616f7706a22580a032e63a22418a3b2220b290606889b47520530c6fa560e76f825a3f109543c516f03012b24bc5accbe250ec5d4fd45aa3726e794b32a98618c90ec2e98638314401ead43c2121bc8ee52cf779e64b3e97821a1c9d8fdaf116d6c01b3251a976a4c29cf0d0c4f49dc786a7d3e4fbd6bf779289c8bdb384268b833af7404239fed3cb1b0ce1a0ce20b8c72d86dfff30fd2159c368ca484c4e02237edcaa465de2529a721fdfcef4a93139d06892988bca349c6c2d654c59bfc6216bf986892ef0b484163a734fb4468f7a1c6fae2a9c8b00b04a8f3392c4a0d07caadb243ff482efe1023b40d467d9221ad17f5a50ac853d2e4b895fdfda46bce1d629c40f8cf5823db04643bb38e6002a81f5a74c62f3406e25e2ad7142cd780e2e279956e9d597536732425fb807407bee52a2db3698394ec18747de14e356c072a080e97dc318b38d4695473f4f1351e402ced91be7f68bcbceffec4afff680cdb832ec2738f319cb1df2af9ea2bb479b52b43d0dbbba62b1c6f380d19db129c6e7acfbbb7349e86c2515978a4a47fc4f4917dd21eafef8f84363b8c05adfe77cbdb9fcf7177acf2275d31d505023622d1ca2fdb63fe2bffb1cba6ca4b5e2ee0fe441fa8e47a796c21bb727e87cadb82e34f3ab4f6e5221a6b282b5c381bb68577a86590a0d43467174f9956b59ececa800a03040f5a2c0ae83077c536bb662ce9c4ffb81c8522101373bcfe8b66b30c3df57ba33369399988edb8fd5019aa87dd392223f70f254fe821840ae06c839589fb6699eb380c28f1f50c5e2e2e663589b63b5afdc1958b4ee707bb7ae38cdbc2f3ac635354c9af477aedc928cc269c04090d443f8b1262f799ff06f15288c64c626a10ab71c0b47e8473c16955c995d258d10352e3cdaac7aa940047c9e5843ae4e57c942a6cd12b67ebbbcfa6ed6385ee9773fd2ef650747d24b3d18308d2037830d5a57be30edaaf1a5b1abca415c9898d9e94e3dbfe8cba71d863e7c6867c4d3b33481f0f7988bb3908a95dbc8c29419e950dd25c3d8739e3d80c0649afa2c992cfcf13b02d91cb0961a2c4e5e4f2aea332953f1bc9a1756d383f2ac310a6ce185b3520e5fdc8f8b7753cc5e79e803ac7ea408e2c328fcdae6386ea3b0024cadad7232c8e3b19cc57941979726776c94198b212e57b37b183277d4dc5b88dff470f3d2c4170d0a6c5cb6a927e58b53c194d4c0fc02fc55bde1c0d6bb8b0d04ec1c322016a78b891f562585c9acf803368ea356bfbc25b62faad035dda542ed37211fa4e6223e6fd6caf2ee392d64a9e15f6cb2d362cdf1d6c2c91460455f463b8e6a15e64a29c48d26e5d0571aca0273ec571ac474a95745292023664755550730e23b71bbdf7fa9793f164a6cd0401d50fc5d7a6172d5d446fd72cd8625ecf2f359d8c81d4545f105e3b81d382f8b89d11d3cc37d387b53e386bdc55373e22c78ab35cde97f81e1ae94e924e6a3803b47a8d6ffb91000b26ded02eb5033cac6ed524036dfa077015a3058e4b9befb64f8ac94ac8d6f41c5c3275dfb35a03c7663e10b5843a88b2e2c02a1ca366ce9dec87e0fb8a79a210a5bc8d6bc1af1d35603ccd345a42f78b01cb5123dc0773e5ed504e33cc6e0e68a5b1e1444f5dd9e7d22635b8294f8390d28da3985a147463382e095e0bd70387ce1469cd6530dd4e3d4dd4e71ca2565b605fba4f14c85b9232ae82f03970dbaa2f693e29ab9827427f1902bfb6d3e0493c2d788ec50ffde9f11be265ffd7498500c3d8c6b1a8025439e56c12d5e123f10000000000000000b8c6890500000000d100fcfc317f22e645a0fac59faa18118768c507c63fbfdf4bd882f03fceae774a05757a720f134efa130f0f2eae24c7b8c5e6977bc3dcbe63a7b5a6f0af60d306ed623d35203ea3f692e5d57a424ab9b6fab12718f779ae72a72c37e9baa769000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c2ec908c7955507edb01ee4663595db43fbe72e4cada0cb96ee58edcfc8028d89c3dde305042bd1a1ed50ab00147295b33a14f231142fc51263b0a8b4e7089a45c905930c381f09f081ef130fcefa45a81dc2614a1d4576fc2d13a03e676386fe4d6a2f3a795f0beeba42a6e5370e96d2225854d0df42c09a5e32d32df4123702210fc754711ff085946403245a221c31f540729438466a550de2f5f1639bcdda03040acfd191fbccbcd3ea1f973a002a056d6cceeb86b04a2c94527bf1c7cb792f0a036d538d0e51958d325ef202e4e165691cbf692a7c412df1b2818730652e54afde69f4b2125f1d3218ade092dba37989c66bf9d5b74d062555ed5f1ec82ac36003268016aa478b1c4b44f2a29d0fe6ae7237915e1bce2bda8e3a22a4dfd48e8a630313b1f194df63a6286ca1f62af237d278c0fd7f4de31993dea338dd8406ce40da0219fd67a5488fe47acc34b97385348c4c87207319ee934573929862b83ec651220223ed3ef917dfc8ceeb5d0b04469278ceccb4736e3c85eed35d47831e0b03c9f2022d6c5954cfea4a228dc78f5b51a48366a8739102d2488bf3b989e16bbe02afa1577df632e13baa270051ceecff1564592f6251c9f615aa2b818e7a7ce406739983288e5dfbddca8a552ce7fdbd49b9baa0aa9f7505d65c6a01631dff9f9eea42a96b76b075a2dfb6efb9a536db7f23d733b5e28cf48417c39a5240c9277aba3795e497cfbb3704fb9686b326a1b755bb54aef58c71ce40b6e6bfec27d3b8e3f4ad90494dc5cafe4c07e83920ada2d9057275485b59bc6ca8368e9d1660da75f6a5edea7321084e7c1a5970ae6d3f6f77727f99649ee33c766be545b71702c71eb7be1fdc9c3faa80e130846d103e6327b51c298766c92414adcf986d36a32925826d01f4453f548bd87370bc96e71c4d5b999cdb99cb597a092badae5fa1e1a32cea392c94c3cc2216033051f995996ea17cd031f0b9a3b7522a3c3cb197710a720d8812def5c85928777d1321298441f6ced45f243cd43f88b2619a1916d618232ad78071734de30bdc33d0799e78af5e0ab6354ee260e456e36dff141c076144c395eee850a1fc7ffb2f1f675ceb8ef3145ab9be4ab3f134a4d52001bdd71ac20d55a3c928dc87c4a907ab91c2edaaedc8c8a89a9f710fec34ac731f1c0f73bf9aef353eb13ec982517db637c955fa789d1a4f491dc520724c6aba69c18eeedecf65aa09e021962211c5c8b490420a0ab1ae4c51789a39def7b74a90eb1cac005b317d6c9171a745880a7f61761b68e501dca82ab94160af5e481de0ad2ebd12fbb197efacb06915408a791e79544f5467f824ec6d09720dc5aca2749fd00bdaeb835d3858aa60e463850337509e58a64a7ee5646da813e46443fbc3042bf61d559c86c072c361a60897ad04e47f2d07bf2f976fd5c839bc06a2b7b630f1584ff4f8a863fff0fde8cb423d89132034f655f64e156dcafeeb7ddae37b6e7981ef00cab5854c2fec1703dbdc456a22f6324003147dfa9eb03dd8a545eab7df6c5e99c3061b9018e71ec1c51cabfcd10e354254d3c987853bb5784e84d3e38342003c1caa5f6d3ac81e4aa278af4e62a5e2ac29b39c0d0db53a23052090f519b00b1bc110f930bc578fc4fc45555d4d712d5017835f1d6bfb729adcf50aeaa61427c609f28163d69c5cd9b6de7456435788144cbb790bc0bf467821dccb152d34eedc402bbf0949497fa2db335f224e021c72660ea14a09654a2131034b7c3ac6bfc8a6e85ab18c1a7a2b21cfe424ef95a40dd426c33f4adb3a081e4056fd55fc461da5aeccb174b4ea87b58fc93e547aac8e90bdfc99b9c4c80c3a3b928ebf7b041d550fef79c83fee2f5b1c64d21a11d0d5201a5b12fd1ac943990b023226f9750fc019f010a0b2b9d976eadd9cc4201c0091a33b39d7c6f161ca442c23187a03072a0899d34de0f5416e5b450eecca9fc74075d9d4305baf9f1eb47a61b45556eb701f069f5733c238a4c4cb2e113e04824d3b218ff5231e68d317465a41443cf133e26089b6618df05eddf2e68ff7be8adf3a5b771dcf614462df5158718ac1b084ed86d22a353f78d0573edd43eeab46944fd4955a2dcade14b79108c6752a0e6a6c9229adb3234daf9e23786168ee65f6a491c157e5f5192263e9328437667f49071d46ae480d03ad141761ddbae34c2a82ca60feba079d55d3b05c0ad1dd30dde17b6d02ecd4fb6acb5b8c058f15709572767f5604ceeb5a5b06566af77e04eb475a41d02c23edfc32bb68b904e901a5b108217a13d119f31615313a1d381c573e600bfc78bea8c5cd7cc012b158468140e2fe3041423051bfcd490942c73c8033cc7f6248907e90692fcd8a25c6cbec4ee43163781f3207186c535faa92608b32e7ed24b48163be26b2213f32aa0e", "63", 1, -1539394600, 1537743641, "7075fab13372b72ddb9638fa99d9ab11f13419199ca6fff80239d029fc8f9f39"], + ["dc3c932d03284c3f5d3d17a5399f30dd7e15b151177b3231d49dc69f8af383f0db9f5710810200000004ac5252acffffffffc104354f8bb61478dc23ed3c87c934b32ced189c7a5b6d2fc53ad3ca52a583ca020000000165ffffffff79c4da29d33a9670be87a1afcf15879e33160eacb203e5cb1d6ff54fe80c7cc60100000007516a00005153ac8c270390030bc0b8000000000000145b0c0500000000026a52a27b110400000000055252655251793069fa00", "63635353655253", 2, 1405937753, 0, "4e662bd48278a0c01191e32d955a374276ab30255b4afdce21927edab80ee2af"], + ["030000807082c40301b632bc9878af44b4c14cac41903617d9e4038d719b5ec114726ab8db741f5a100200000008ac536aacac520063ffffffff033e6e560300000000066a516a6553516ab8e00500000000056300acac006aa6220300000000015300000000e5c51a4501aa82d205000000000000000000000000a2fa7f605d4f86d6bf2112c9aa66e6b489e5795f89a80e522e173a4cd3e60e973aa1d838cb253f1a59346e48f38f1da2fa9813ab7f1d1b510e2e6abf0e1dd4438a55455efdf512076396703e353aee51ac181ce5e6ee518426d66f0b7814ca1f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000766ce6223d657645623314e7c681ddf6e2cd8ea67f7d31e7ced4eaef0cf9f65b41df4c96a1377e9cf5247752fcc0462d7c4afaf54c6691e01f5bb6e69862c2455af109df283687c41aa562c986ee4669f922eee4bdae3120e7eecedbbbb6684627acf80ae63ac8c35d3458d4aef370af2aaa162e8ecff72f3dd3ce257225258030a9fb514ef18a1892a98c19abba2d91acc726a091bbe83c37ffc2309904cb460020a586746ee76464cc44147a7ae12ade4ef1292ecc16de336f8c888be10af74230a0725c85a26e146464dc9c64eaf6d65376a7c294484cd2e5a3eb4187f3e29d12bb80bda0a0501e0bc61428f393d7725e926f8cdfbd14ee955ce0890afecde22fc022146c1ef12098bdeb336237cf541fc2c7dd8959998d401fe79fdc5f92b6d06ee022eb37aaa255b61ccb455c3d00c8a6beed42cf72b50ce660e1b52621e31e2f645020fa12da3b001bc0e16724bcd9a0e1005ac0fd01f552e74efd2de673ca4b3dcc3020733d230f5432bcce61572fcf3c1401d8cc6ad5b42f3ebc62001d559a8eaebf00205d9493bd269bb4d6fdc6c85656ac2f96fd3527b2a595df6d3a048a7fc8feee2817890ff93c637185b64a4e086b2ad4b0b4f37ebcac71549fe7f3b692d856965d655ecfeead173cb0847767cfc8823773b76527fa6b801189d4a935a115623da3f75458aded360bf6ffc00c237532536f8a57a2d4fd0fafc142a2afdce8b3969e30900a8f7ca73777212fb35a9aced8cd0a72c57228d456209f5fccc804dc01c700488e570b9708712e039ed5bd5c7085f20920873451653b646f7497d8915e88e3720c960670712040ffdcb7eb2f92db4c4d1d64bea659d9582275866abc58832a5506cde0b6f79fb5abbaee3cb9e45ad98e1633f7cff9844f98e2b7a0e19fe72ba71d8085809b3dbf682e44955c5391d55b5e20b252f07a4e65344541380208ed75d140bf5b815e193093251e5c7cd9ed994cfcbfbc85efa00b408d25c44a4bf3c24c208403b61ce02d0553afc7983e212042d219d5a2960da8f5d5d23d8febfd1c18d5b1c8a4bb020495e134cea9ca86713f4640010f0f89b082b866b6e446e8b1f9046fc7051ea0bdf3c8760529d713e710a8a82b2bff38e2974bb2e3438c5654188abea3f7e8ebe59d7dd000e0c43399a008107a48d9f240f06c8ac9ccb506dea1e9fb10b1d3c80d94a0138e1bd1073ec1cbc98fdb4035571e8cec95c2145f9138f0a6912b014a5842b4fc5bb5f53ac9b1c380182ea14deb96003164fd8f83ddecc9b27a7a9519e1bf0e3f939479b4be48d972db1993ba6efe82032f5e84ab7361574e0ece62356a7b09b9aac655e3e6df216c1b20d5233ae4c8702da8affab6d2e11e8c412eceae9352c3b81d15a948136b02b6dd649949410d4ff9424251bbcd054ffa6f0f808929052c67af7d6747b9f278a8c5a6b7970e40ac34c10881194120352dccaa39ad55330ea1677f82b1318d9b7829d298b158e16180ba482c453d7aafc9314e5cb6e928df3f3b86561ce2fe51ef1ce58c5992efbbb813abc35130731cb9c1db788328e101b14d7cd920d528b8bfec31639d5ef5aa0768a86eb33e261f840ccf74cc77748f96cfcdaee164c01d849cd535ca0dac3c24f594b9cd77d969aa658eb186998901209b7d3ff0fdca2866d11fd5a94b3731a171272518178676e1278587be932eaa7201be46f1b15a5ed711d4d7946ef3962e9c90a09b1d0ae6b729e124cda72fe3c92e862e3fabe8db49964a60bae8ea7d449a6a75acdc986025957f349203ed97dd8eb7c24e92cf989af43758c641af09b5bf78eae5533435ec7db050da80dde1718ade1f453f1a55ba3d0efece494a5258b314ecc3c58fd338342a919237e3c2ece83882647f4acb7e7dcebe09d8d8c4d163892c05379959adebde0e9962ccdddde5a6ea5071f3fdbffe073f0fa04cc5aae39bf820473aad7ea56e0698b6b95dca58288da2d335275f0f6b570e2b7f5da4c12527c809b78572a2fedfa2caecea40da0c4b6123a5d3e583a9c71a8fb7c9320c6325298802a2cf83de4fe6e6f97d272f0a5f92ca809dc49a86ce6af9cdc1825e68b445b0e4217984f3700623de1f8feb36a00ccc323d3db545fd27d03ac37fd41af608bd8eb7929f2929754b76b7f0de13723906d768a5b3aaf4292278c48265118ac9085e8f11eda3c04d44174efa74192036fd5f9e9d9784bfa5e233706898caa7beeaef5cb83a171128bfa0f6e5c9862043ca0a72ace8e9d99f3fb017b7af4d299241abaef9b8bd56e00196548afcd8bf656003e55cebcfbcf7d2274ecf55bfc08d63e1a04033bd19db7a987c54d3df8fb2b5472f3ab69671e1efc8112bfc32bd363ce871f46aa814352aab9d8e6d6992aded0f41f6e3ce0e859bcb84157206342becce050f49458e8180e416e444ddc09", "6a65acac65", 0, -530693294, 0, "192fe079cf4d307c3afc309c4b83a37f16529ffd3d9e345de1f159761d8e601f"], + ["030000807082c40304277f5537146ff9f5774cf45f45eaa76b4aa7542e6be7da5f70ece7660283cbe1020000000265ac52b03cbf461a5ec2de5d3c7c9766d6c08aa2292b4404dfd2725caaf964510851e9dce43a0200000000ffffffff2d6f20efd63bb97aded0c891c347f1dcba41924220ac5ef488a38c1289c536530100000000ffffffff7f725faf1ffb5e77193f9dee6c43e257273d52a2ce99410957d8664efcb4e1930300000008ac635251ac536551ffffffff03f408f502000000000353006ab15eca030000000000445f930500000000056a006a515178d638170000000000", "005300526a65ac", 0, -1326419499, 0, "76ad0ae02828e3743987ec25640f9ca155e68adcb252400f8ad63c6e8fe42652"], + ["d4e40807040eca4df267c39e55d359b1d78a2e3c5d11d4a2ec01ae395992e27a3247744277000000000152100feca319dac5ac0c40e71b4f00f92deff14f5265b811b3efdb8e385f6bd9a0b2febe610200000007516a63ac0053acd9b0da9f6be034ec529937cc32d73b777c939bc8decf3181005151a584bac9a674dbb7050000000000422007fa94b6e0ed29fce1e0f296e59c7ea4de795009f0d647d6a400cac1bdb9794a799e0300000009acacac636500006a53ffffffff011c940301000000000652ac00005352000000000135287201000000000000000000000000f8c15764ab89ce1649df3c7b1ce6cc32662da063c04179e5cb3f5e7b6e99488886597c210599fc3649773d350d90d946c645bbb47a13b06047b9e24cde96a2ba90e55d5991300a37da1bf746df9a9ff02d4d1807494c85956dae8d3621b1d97500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000843c33982988d7d70bb6d37d7b80fab003dca34806f0b191703ba0ba75e35101736f9a1e9fea08cfe3f36f4f910236ad9908b329d6132b0c25a4526bc0c106e99793c8db1a9a6fb2155f882b402565beb48c1e95a64e165d5bcb0be2f09a71d6cdb481515fe3995d6fb37062e09625a56c0d65114eac81cf588db02dfae5ad89032c867d7c2e31b2399c4e6fcc9452c24b2de3f64140a76a78583c1d5f9083a162022a53b019de0d79ff257910b1c3258903772645cf17a4f9c83c3db069094650560b04e33233ef1b01d9b867f7f0666b3837cea333adee8594076b6c016b9a3d2df280fd6ea047d850f69ab90c710265da596ac45c703131d206d7e320b36c7d8a4f031bb5a3e4c39eaba5b6a5e155925f565b8828f81de91d9648548a7055cb15738e0323e0ee4994e5b414b357f5d564d8bdfe2d65743affb52ba495914ac7bdf2f18f030b60bebe502ff0efec447566cf4b8e35a54dc6ba20659899dd94da52909d398d0323638d02212f172c7b838f4f6a27d4864f42b877a15c596f918393ffd0b93b60032db875b26eef78f2404e605cf52aaadc509550dca356bd8b3d51152fbf4094fcd0f8347a3f0d51d2567a5b8d8d0915ca0b83465a988af4cb38552a7d76c5ed60bef3889dee6caf64e25ac9b7c71973c2f77238777f6e3360b23576edb9d7907b7cd56784a775c0076c3244c287ea13b605d47604922d06e9679502285a5b74821a0637dbaeaaaac673420f80b87ce7082e43864ba64cde121b7a690a18e43309a9b85ebbbfaf6231d617240777b29312327d73a812ea8188f0b76bb3d0fe436ae1fb9abc5181dad80d806c0a0248ff01eea641fcdd51455e60e05053318347d737c31b7f7965e6e129335d8772ace68e6df689e76a24cdafe7e15b3b1b9a27af4b1516b8875fe2340508a9d8eac3e2b70e742068e1ba6147097932432ff19d071026eb602d17b01ea771f63ac0500987497e3aabd907e43de7629e78147d10a9ffd5439030c6229227ac7c62a63b9bbf7a6e1d4ea03273ae42c1d1ca87c40af663a1d5b11891dc729109b799576dc21af76ad4361866ea0b6122506e6d7fe6e9758cc1fa835d06486c4361791a30fe745b9b5c23ce67232ee2a41e1cb3c430e318a6f4ebc767a8eb220eab4a50f619419dc89e25ecc0c19405034e9e06661a651e779d909e09997a68c21a05f6c1c2c553fb3f17fd9820745a6bf77c1dab65b2547375ce56d8e8c6440da349fce6ffbff1aa4acee959c0f45bb0faba9e1ce177228dcf42928970edec8ad7b478cf3abdadabab225f86f41e501e968fddf7a0b8f8c08ee38cfb494449040f82ccfc4894872f3b15e165e121a411ecf21edbfd080d95d20d28e669104cc1a5b98d852e77a3cb6b7fcf5913977a93eccc65eb345a0c7233e32870fe07cc940f16fc3738f6197bcdd01f5bd6050b0988baf9d6c6b514a9924d81a4fa5d1ecad9c3a29e7df3160a81de57228252f00799fb498148ad3575c5694116858f4b2a79d76dec817f09d55579d1ca463a89b1e0db56cb27a2826ed81b5b74e32b2826582b6d44eeb3050980af5376379e80718ce7b2c5d648bd3011d38c64a87577c2926904f90f26346f13ad82664d0fdf4a7dc1e6e28b89643a9fd0450cb6e3c98173c3cbe727127ff41031411823cc9873c02486efb77e60739e281b3271a803b80951b2df7f9fbee65ee91ba3384f9cd27dc6c4bec4443f69cc0683f953454b08e9479c2280796f8af0fede29e6df02475dbc7d80fa6bb93e36f5a0751addec62624c708864b8501640f63d8dd1f3b89154226fc14881c1a964663c2a2ecfb723ff824c4a2a296490dd11d80b88f88279370c35810e67b43eda3bdc4f766afe8883a9bf8b68271e4cb22ff6041e33440bd8fb86a87a2e611ca3bb981fa28be8784fb66f494f4abcbfd69d8ecc7fb319eb505a6f50ec37264f72e359a04426d8ad5aa7a7015f973bbba2aafb44a4e4284f2f7d896440d869385677d77a05fd61e549b2968da6b0604a4748e6be74548a35e7f4dfbe2b76c4298040112df075d099e37cad53341166a1771c2e6cddd5d3d8324e8acb5ef3a89dcd27f749d70c94046978dc7558eca8fe7c27bbf11547b4c7d90845ad9640a0f859abbf50915a591ce953b633589b9b514f3c28b20d423df2e1d025c658fd98193e3eb9ea0749cdbbeafdc2c502a962c2fe45319fea2ae5c86b3792f22b37acc1e5d4f8c1a1d626ec36fc1fc33640c4ef3a40df7b61706c2201c02962c934500ff70d5c3861c14798bf74fe96ebb774cb9c7db9285b0042ccfee14e3c82da50e116fdf2a843e025aa326b609145cd27adffd6dcc61014ba7f47fab6ab1453fd6e8a10b0dfe75a203d9c41792410c2fd9b73735cbd72a66af7735221802b2ade014f6cb0bdd261944bd87fa1d1ea784706", "0063ac516a636353", 3, -1812130730, 0, "8afca09d074b62a369938e369e7eb2c76cc06b5cd3e8bcd948b8548fbd331cfc"], + ["030000807082c40301ba1b30538da436a6ddf18f4c27c1555239e9112564c5c23e18881c6f95d8891101000000026552ffffffff039b59ac0500000000095252536a635152ac5383dbab02000000000800000065510052006374100300000000076353536a526aac240fdce10c36ab460300000000000000008b8cda050000000014584e5b68dfed589b3e9d88e0875a3be1869e2ec00de39f78f67682f3dcd5f6d38d0536e29c0913c9abb6198370124ab1104c04b556008b71b06b547a585c9d050c108b2cfda684a0ccbc71d8ebf3144f7966eea9cb5722e8d8e414a385bf120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b2b39b382735033087838433a797cf7e5cd655f4b2226733f4a0833064fd4072224979800ad57d689826d07824d86c629dd9bfddb20ce1a5fae40dc4cab7a1751e1acbb796440cc5c10618a6fc881dbde8f7ffed9b84fe46e91337577e9a092c3e320a4d443f5bad435389e99c4aec734f218fc8880af55677043f0a395abb0217660b86c997be4e908d8b9251b0bf2f4dbaa652ed0f70c82f9004bd2755714b020d8071d59372a1da2286f5bc9965ef1b942941e3081c4a751c11168fb0dc2f1f0a01228a08c4c312af46a974679256698454222350aadf516dcebe019122773fdd0e129aed37b3375e1d28dd2ab11a7a8701b933d49e8abc7f2c015a2881814e5f031e0930c32b844aff43c4a16613ece3f8a28a6bed43fde4ebc649fcdb7f9b805e020ebd964d86ff16cf29c348ffeb7fef6e12daa1c6d26f908b75ca43e6454f388002261a64d0825c96682d45790d7e0b3e06b27984da9cdbdb18437d898be0cd4e1502288cb7bb519dadab835dde5ea3d7dffdac9bcb07999431f29e044c2d680d4b8a021237cad86d1555af9ec6977b25d35c3f1f5d0e7553a69bf7c121905b69cd9631e54101e98650011978bd78ad2c0843e3d30a205e953839ee125f6847ca0327394ea940e4e1959389aa6580f492a0966a4e5b0dd416fbf251905807933e249148f2c43f790d8d959fbe5432caadd043f29041ef9fbd01d44aceb19fabb934f7c977bfc30d1fd9699c90bebad55f37949b2392cc1bec2f2ba66d3bb0749697e0290b5f4faa31bc529d199d436abf7a8798e480f338fab3912b1b7c4244af5a8ff9ec3ab9dc8a3a01abc6a71ba644b2a0d331093a1620158d7791c5a060b92f7475161bdd08119fde64494e709d582e630ec4c61f6425bc758f4f825ae51b3cd3b88c72c9dafae9bfe66840a753a849d3e23ecf3f0ff390abc67f50e088005d03dbf99f08f74c249df1d9f2d7ac223ce52032d1e98fcbd5aa356a45608228bb0d284a53eb9985ebb8f39a3ef3f7c0c8ecaeea18e095ccff82de6d3d1f06fb23ff1555c1cd49adb8f5e5e643355e69d920fa745a459cf8609ff4c0c011ba0db83509d4e666c08971898b96e5edf0eca165e54946894933791a256a7e913e6d99037b1de22db5fd2b942b2280830abcc27025a5934246699bccb52e11b84bff576299cbda90b9f01263d0b2e61ef56c6e769df916f870412de554361204b0fcf92458f80d92f7729da17a13ba14a8223681e31148a17d518dfeb2b21b082616381b49672e9b6e14dad3f707f94d2f68a17675d8ef8bd7dd3d32b176e3be5ad02cf13a12296a3af94fc5014e2c204ffa8c444805c88c2ebf100eedd133a594ded9ccc5861298a84f8b3a3c89c0c0ca7d2f971c671d6c2e6bda083409533478bd0a41b2e145318430b5e3f5ae7f6ec08f02fbbf7cfc61f47c92891e16ad33dc92f4998d541dba63deda9de1125f165f8147d7a1317a5507ccaddad1ca9cc4e6557ea9eff78fb62fcb2caf40bdb937524f52a7b8993c59ae81bd91d0ffee7e3235ca23bd71fa4991411de18a1dbaddee6831008b07ff396270b2c220b7d6732c8d924010ea0239c5e50112f671723c280a791e2ac8160d017f21c799f1f81e2826b396f528397622855e22dcb103714c9bf00d109f37803fa789e4a1b243d7d5149335ccae5608153b6f04e2033f7f1d82ec137359c097ab62ce3e9fabfe55f3e602b0e363b03e8b64136aae21aac86c7026eb5825eb2fb45e09015508954d68c20cb9ad2d3cd658cdd73c5bb1f1bccb4dad59ec08ebf2f2d54b4edf77799dc5de8185cc75b8c97b0162c144505ebca008389a75a006522f6aaecbaa32e321463490f944e1dc6c82fe4fb6569f7684568d03f531915011f54c6b0a42b2927aa7173c34bc87d57998f2deaf0f69a9731105a9da08816b0ff8782ad458b7d6920f72b5219606272b68d3c8a141384c8b4ec8780e89873dd4e218fcc28ab739a6da80f7b05498de13fe4fc1b3c6547cb2767950dab0e9b0c66877c5ffaed22816ce5d61d35848dc93db519f0e4c7cc6fdb1fcfabdca961a7264e53ec1a0bad9492c59ebf8d5aff02ad3cd9827d7d7402fc150fbaff6976625b5aeac5190f23d71573090ab976acaf68d1cc857ed6c448942e85d192ac5d5fa2241e38a7277daf893dd77b9f15278e5c039754d42a1f287dbdbeb2350c46972d8e1691653404761cb2e48763960c51de46429b96bb40b89df9099e6dc2e2feb30b80ad46d07ee2ef29c98aae4654936bfed9299e17c420ac15b2102f98f53ad07d6010000000000000000000000002dff20c141a7ac324ae57abbcd842a59145544abe1ddd8ef1846d1d01b7f0bd3bb45314d92d5ee00346c4b108d422d6c51c53a352193ed9f77ec52c8b0f28153c2b6e077746f60754ffbb6f0f8939e7769d6e0a9a5daba375ede770c42745839000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a729d894c1b239f6a237215889d0c0e2d27272a2b700f684c6aae80af14c7223f9f943e3e60bdb22d15936550010858392e0576696c9afa06c9a295472d8a6efe46c9073ea10fab75c0e423360f7c9a1882db4e0e2080248ade0ee32bab89ee6a5699442c562cd65202c4eaeb2058bc994f2b981e2e63294c97d8855021eb480321db1c910a5323488a545cc9fe20d79dacd2b9113015e36f77424ae4b862039c030c06936b17cd8f3bdc5b0481959461d4f0b35add8705a98bcce872df7b1be26d0a01f2acd100e53aa259212d7627c43714cc471bcb266171588455d78498830396587040f226a32fabd0e197e263fb8d2a399662d7fc108ed6f393e31f779b394a031dfa65b68fa6910583ee0cdabb4adb4a9fd38a96879937b55ffd2c702fe12a2902206bb661d9d76a1af1fe24f66d3f1b28ea170b11458e366d17704c597a85b3b5032ffc41fe654edf5b213ecc51b5b904c1e0339b4d459780169e6759eb2e46520e022535a5ad01c17e2b161d01e35e820051028edc4ca21bb69f0c334f9c6892fb7402016ba5e73f1cd61605f3b79b0306168dae1e2aeb3387bff84d203ddf9fbdadf79dc8504b52bec9aec057daf9cc6d755388a07531cbff83ead2d98632977e615a699bb79a85564c00174517507871696a4dd6c57e8ed62a24d020e13bfb626ebc385cf19ec38bee015e41424e3c13762a78c5ab85f6ad001abb84b92dd3b244e96266c0c2bcf17fda3b124e219f3fd8ef73edf8dd26bd5e7d8281c89327bb28e743d7aa87a9da4b7ac28cfe2704e42764c4947f05a1dce713fa7df2fd7423ebf5c8765603def177054fd6222d6b65ef9681e34724c4cc44c7031c55897725e810592b5078de007a595561df05c5da40559dc360820b2becc236da70928633756c006b2ba9927d425c5fcdf2a7c7b3c00d1630086837c5d8e93904ba4518ddaf07447997fc6f2760110930ab578ef3e9bf45908082fefb084cd44fbe02a901dab17e2ffed15f5f417b075e3f91aabd319f157ca20c45a7e0a2f5a59efe060d63afa1f0e2645bb602c6f42e271771262206b451a8abd5182456637962c2c475a257b7eb8103ec73642ee2478aa6076d8af3e3a9e5667ed25b6efd853b5e3ef152c844c3a28e2721d0d23c72828be45ac71caa63f11d6130422b000a8d9df33de06c8da8757b7da6a22f3f1c8c6ecc8e0005506bebfa0b8770a866e4f791df044d32dcd059fc52af5149e9658a0d6cb7635c0ba2b47380b14a823e2ad0b05375cec51de64d1cb2c8599445f5ba5a3be3a91830aeae97464ced09b1dc6a2375f5a52c3c44b61698430d84336f70b5955779c211bc9ee8c6182de8e08716f69b4aae1e79cc90c6157f82b08c1acd932c01e8fb136e479c6daab8d579e30a0072f064a398606d1ca25cbd9011c055603269f4ba3797198dd9795247ae33766d321a99b2a091a796eb90db4ea81f4f4c8e2d943da50864afd2eaaff21570544fda9e2e90bcd2d0bfa3ec2edb263dbd40b82571d1d7941ea67ad6789e50b86a914482c78114b120e3d8b0ae5d331f4f11204ca1ba1ce4ca19a6db27411f335a7dd96c990314faf36d2d054a40d1d0a801a9343fc57c253ec0e9a993366468038f6aeac5266d60c08f3a6ac6a7992990a78664ceae001d882d0354f8fdbe5fdd0786379eabcbfeb693ae779bac3596469aab006c24a41c99850a0cc53ca49136a7c3c8293c2ee43951fbc05fa23b853358ec6af6876cbfeac5cbf9a9ea11df7fcaae9e36ee85925c007fa0fa4d8fb2049473e0301ea239c9997b87268f8d06ceadcf2ca904bc593e1b02b7875765e407eb78278b32604359553b7e97e2f03bbc40bbe41c61c1a7fb4188005ca2cb135fd29ef9dc8fc6fac1773d473045d33e3bd0a4acfc1ecec51aba95cfa9f7dabc75aeb44c3d8f8fb3f7729e047b2d4cd0b9eb3b2d9c18b42a394db704594c6131fdcda75edde45c2207944645ae3cc48fd9c082f2f65529d0763490a99ee119028767240f3738a64aef3facf0c720b7a42999831b29e751e30abd2bf8b60e949974a40d3a348e8dfbce6e38fab9a5aeefe46924d5a4ee09bf222ba49922d3c5ae172077296f605f6adde0525c7e55cefa33d7b40fc8b1eb96f26bbd3bb76c923d38baf69a753ce751fb296327e318f0ab79722a08a5d57955ca14bad95d068d6b12454a301babda2599e7b2d3f8efb2c06dfb88798664595e3be6a46eae57cb3044f79de997baf9067e7c5ccb7adc3b63eb107434f285fc47dd7ab938f66f9545026464bde6fa515f0000000000000000cd4b7b0300000000824b0b95de066737dfe4b6965837aaa7cff3f670fb122fd8fae94560907a75b3ac55115e659b29221a60cb4cbc5507520df43240de9482ecdf2ef00db9670eeb92c1080f2247eb38a3593991a538a19b6c7c13afcdffdfa1cfa54bd761942b7e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074e8e61e96a0588e6c05fc4858f38c47f37e44091e6b2264c5afa074cf65a4464fda01cdcfe21b152bc158d13e2cc6986f2cf45c6d6d1c803fdcd4bda2d1113b7aa1cf3f8bea51c9a46c26320aa9395a031869991b5e8205419eefc9d58aabd56ff67bf6eff2a0701053a4b9090e69e3850bf927a9f902e7b34c4f8f8938acc70221494e3eaa11ae277a5850138148024c65f32fd2ec989e8c401448c051a0c0750211717368c56f380b54be3993373220c47181e13bd21b1a79227b5bf83d0963840b00e0bf071401f4a9b86f575b3c6dc5da4bdb2f9b0da22c440092c2198bb3622a9406d59153b74a760f6c047127c753b303971e3074df072502c31eb119f2a719022e15010f0ca717cd552cf343720987373da9b802f5c0778bbdf6ce0dfbf9b00d02165c7be2bb9a240e746391273885e787dae7c2dd9f86ec134f3e1a03ac4002cd031b7a871c9a892ca95930baaf6bac58f8d017b63cc747fcaba91e143596502ae902107bd772a6db97b9f3acc29d0a1a74ea0444e8a18f496b94b8da90c71ff1415b031436dc573a8a50ed80b862d5d6cf853aa11141505863941cbc65b6ec7581f48499db065ded29421af68d4c5e2a907b53314b28cead2d84c736bb3693ad6e4f7adda3d947d7845f57ac71a011aee7e2f7d7237f31e2960226fa8c1cbc9af94923b324ed38007bf25eff8e2b1248d74a0a1f229c1886f6688b85a167f0f5903558cd2217c033d37616ea35281a57f0024a2696c86d563abbef24ed6420015b1a1b4bdb8b94aeb43a32d4ec36140fe2159724626ec7df8edad5694b874681acf2f3ad195506a32da87e1c12433c8ce1c69bb43a35f7d045783ad872adfd979f5d6893555651768023741c13ca3ba423c33cf19b4ddcca5ed0eef8041b5048970d9dce7e5764d70ff8f4723e5710e478f59cab39a826160f4c2be33fbcfaeca80b8470981cb3ba3ec0f01089f86c4fc45ed95ad4e1d839d5daba967d77d107cf9ad445dfa6111504b34e08ecd242f01d015afccfee64c02ddbb0b40be9d220021c064e0a105a651a8f6f9f65857c8cc3da6ebe3fe7a315a7798c298e189f3bb7a7755a04d0df4f87852b6873a2a6ed32275e7e7f3ec397c9efb2fc27ca7c89dc921eb96bc67b99d7e18d2a71d0427a2a2ee3041215b9ed14cef16caa48235154b57b3f62a95b160f04e07915ee24df7ef34b188782106dbdc555487916e13b5f764e7799c621c70bd729361ef57209ae55c3efb54089ebbdba5758c62d0b5090f9261b7789932acbff00efeb6452df596dcbdfe94c4e79ac68c10bd66a1d4290c2a8b6aa4dccb36220417abc9c083803222d1804defc1336b877b5562dd83195224b345c6cba1cd3cb2cabeb6a471181d15e1577a8737f33e574fac3b4b5ad3eea3fb122c555648e4dff864c634f99218070edd590b74fbd4bb29d71a5d690d67f4b15e586cb56b43460a985ab6743662f6ae8544c23918277bbd4ad87a7cda5c68703f577cd68fd3f24e16cac28b7750a698820297969077ef9f5637703ce34902d4b63503bd8c507bac96c6da321d088f81be3aa96d7bfa1cba33437420cdb5455028d439f758f9a2942a574bd67236d277db104c338ab6f1313a4e8cf3340333dfd6dc342784e96f3597c20649d3ee31cbc6152a173de13cb26e7295b790e636ac1b9699f9201bd6d8b677ea886e946f401ec600ce96e9503db47673a3699858de0e41f599d867aa4222ee70f64f74e8d22c678b640d5d54ae1ff5c9250041d4a64d445936eaeac7874b92e04784078c229363d7f55f0cdf0fe7b5a7bdb1cc7b1dd80eac4212c67f78277393578b041e1f6fce87b0d63c8a90dca0a585069ca82dfdf78c8f66af1f8124e6428fdba37376a583618b822c41a6c12cf3cb371ee981fe7cac8714b0bf4cf1eb01f7279feb2b28f3a54381b50f361f7328d93a93723f7034b6220cd6de90e09404ce49e5447e73bb014b08906dd92a6dc786ac57400e1cfe8ef237957c31797b04ff9ce5d8eb95298572ce323433b6ac8d8c8f3595740642d12f6c8fa757c2ff1dd69bede75929d6d6b9f7acc81e702e031a0c69b1e17a50f53624dbd8a5930a8a4c1342346bd278e69f0ea4cb205f97651e4de3fac6bf718f3c05c59ab5bb999e44a1978eb4a0cde104a972122c3b0bc39dde304d54019d7d59010c29915f5f8c41a50d5c6e9f0705784e68bd09f6ba353b5ae5ff2fba4f12fd650f7776c1b41291311a19ae2879ff4fee4a7147defdd4b05000aad4ad5a22a49f446bdaa6a8847620619f0817c6ad88a11bac1836eb1ac43f55d4b33963086712d2324f5fc24234a3a0d1ef417b5fcbed4c38e5b5287be76f5e83936872f43166206c6fe3c57073379a09aa09a983e9a2f8d25fa2d9ff77c33823e4a04ed22dd81e36ad14bbf5ea9839e070504", "51006551", 0, -1749758910, 1537743641, "59141dbf96c74bfb6623e63997fdaad953c996b8f8e6146cfc1399dbf6da1580"], + ["76ad533802a273ea8c9ca4cc89ac8a5b2573dda99c26f5cbe48996c0aa0639bb7df8013593030000000663ac636a63ac034146f4dd0060e33a20d8e4b6c0e3c03be98e25982c6aa1617c3bd9b388094d17645bf7030000000163ffffffff038335c802000000000800515265acac520058d0860100000000016ade742e000000000000000000000100000000000000000975b5020000000016e4436fddb8a69ec9e30e3b9e5676fdb87b9e115b6f12dfc903fb554069efb82cb8ae65c7da7ca74f6952bd86305d84a9ed158d0db8a82a6a513a7d280795f727d6bc025e6d907eda1c8f39de65bc4111dda6d98a2364bb8adf9d5db8b7482500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a53b355f6c0fbc05f3d61f4ed08c09dd7679c37703bd63666080b50d79b35eb038875dc4f89c30756b32bf7e4283467d40bb27400a16a2cf2eaa440f628981df39ab0e4ccd233542fa41bb41d0eab385ce0444af556f4f18ab9bd1da704244961269ce2af1723b8ab2697579a4f61f61daacf2ee5c77e78b8c7f4e2609aa0bb303240c96ca586f19f0149d603b6084e7ae6b256f160847b5868f8d35f3ae220be7031ebd52afe2bb1e1478a4308a544fb6bdf478d4d245af901873f080778cde87610b0491ef6959e419e01590edd543bfeb62a3bd4d2bbb234700e1880327a603bee42c57a00c37621f1f1d1d0d45360300fb793c25ae9dd5f57e834a31b4b634972703264fc6092b6dae37a240ee7cd6e934fccc1e4e246d796a8b6885255d5b5817fe02178321ba4955515fadc2c8fa3b99e75c23ec2da0273b5ebfbcd992bc22f0113502228ed3daeef6bd6a937e08672470efd44192cd4226f57d271ebb4b73a5124e39032d102939ebc1e08aef287c9abe0c1be0f205bf1ddf94a37db3b27375d6184b93021150b976f3030e61c2377372933e83f23fd4caa11200e229b2a525496f7f1fcc1648013ee7e2eb48fae476f59e573ff95f47e1a964395708953ac5bf78da0fedc309216973d56674a9fc4ea945c02455fc6946187e5847ec39ec6db445ef1621e90ca04e48b18089d864b75d2509e2c904d322835e2aa46fbb577e3f5df8b2c84979a8d496ffca91a91bfc2c79d2d575f10f4760274e5d770231548e66d9c30c5a0abd98317ef54048f4998456e586b9d1710446fc257964568a0fde3047c5edfa6a3b2d305464e79730e61ae0f5ff7e4d1a5fbd071a5849b0847785b6712f02628115e781323e2a9707b3c03f6cb593ba2e675e1fa0a840ffe263a5a1f312d2dc56b4ed27af20f330affd4407633bde825363a8d4650b928407e52e12d260bbb12fa9920e22d9ceb8278c892e53a32317d47a5c794ff2c7afd812a667d66746b83a4a26a5cfbaba6663821ef7ee9e8c16155e7340d06067a486ca922585ec7f8f2444a02ba35300460662fbf2469a36569074e2093e20fc433998709609a507c89ce89508343e41c28eea6494f2b477ac03e2e55aaee1dae4392b811bcd631d59795902271f08cc5bb390505a884404648cff79715a4482381da2498a647feb4f403f9c3e3d432f96f7d26fde90101628652a122062fe278df15fae55d3c950a897808e9f47421b3a0002554c4cbd07b60741cb47d5e552cba6460965a4459d40a0a219353682f7ed5e2049cef122864bd7834af0e9781a7411daf3c85d11c3fbfacc6bc4e881176be2a3be5d0448b45db08b9f9f9877f79b68201419dc0f8294d341ad07c07a66849d73817286426dcbd3d2a08208ea9d13f97dcf0b8fee693ad1e99523e592fe5c582ba902587a796f60220805c9e50972c3eaec16d01b5bf1e8d765f22d74538e3bc1960c74c19fae9a1ec444cd1ba74ce92cfc3141527fde3d55d7542514e155115d03afb0c4700fcbe1cb996f0168f8ca7e673b7a975ceac9484a7a194b221e0f43cc36b60811d9f95edb521e7a1efd2d407678ed72d0b1aca374e24ec0e0e89f4d1a56bd431fe140c1eef4c1f3f939e38ba98b66d4df9163e855ef59e219d28f84c843df1bd4a692ad012836d92849c4c3694ee82d0701a34e79cfecf2f35fed1fd751a050fede35004338157bddb8e0f9682cc131631b51a0401a014c534cd23f358c49ae59f9eca96f4547aed29f1b3bfb7861c716b84f9d5abe06cfbee81f9226a242f60478f0eafa03b4c96117fefa6d701ffe31795bdc9b374b5c961f63165ede1e5fd58c47e95c33a9b613b368550374f0b1d926e71241d0109774949552fce636cc0fcedd25de2aa227b24f4b0f0fad7a7d70c1b5ef417c98fee0bc2109ab65169ecf007b94f3e2658fe158984efb61e0d0fbdcb6e920547b3d155aa5ce00fe8a31369e0ce5f774ae92eea72a500bd4ad6f0e444a1b7339325f63a7cf4056afe3f4f627206b7ef850dd64ecda442b23e434430ed894d4b9813369d3a3d5e7967e7d64e14ce83c4fcd31e617691050da9b65a6fe4bd1574d11f3a018606b3bc5fce198e9a62b0397bc19cd3fb5ff73292d670613a0670b4b7ff37638d1da22fff0e4bd822c2d220e5ea2e6ad745f2f5a2830e1815940fe4674a3e0a83500dbeca9ed17d8ca74b223654fda87c14af2473197b448a1562e759889c9a189bf480fba7dce140a179423acfeee47f02b1c884aaee798a9469700570f917931ba51c4f62fbaf0f0738b825a91c43539e01a2848fbd78032e1723227f42196136ef00d7c811552141f1e4680938b4f07a5899a65811b11a48794ecd42299be9bdff1283ea3edcc888293cfcd8bbe4fcf4e3c49c443e4c1f02168421a6078e470148224da294f6e09", "00ac00530000ac", 0, -1223583658, 0, "8c094b687b5b150547316dfe325362a98edc59010dbe2801a7bca69574686deb"], + ["030000807082c40302c40cd2455256eb617273a788d4411ab4ef6e5cd03ea35bf9859787f1702d67e700000000095152656a65650051acffffffffbf7776ede5e6fbb8a92e4a1bd45dfb6a3f7ad93aa727805bca87ecb9b5bc84f70300000002ac52e2f9ed8c013633cb040000000006515251525200000000000000000000", "6363530052ac", 0, 772284676, 0, "7be9a5975b2b31c5281af59f5aec7754d204825d42842f401936a4e526b4c54d"], + ["030000807082c403034b3eeba36e8d8e4635bbb81c09738b4c19614006b291260f0c1513c8de6bd82803000000046551ac512b193626d2208353ca187300c2f217efd5577b5fe6a74a9594834afc1d6ef688d71735ca030000000665ac656353003750e1de6306fc3615335ca76426c1514f436e274c92e6d1817ff4a4282e4fc50475618a0000000000ffffffff020187c303000000000852655265006a525364b7640200000000055253526352000000006fe0c54a020000000000000000ea21bc0300000000d0984996dd8d80942cdc45377425105e9c3e25f8225a573d1586fa339de78d2c4c76499436f478191f7a3042ef6f82b8bfdadd4be670c712ee40b77bdaa524fedd0fadfe6a58da0c32472eb4800ac971d8c1e65b9c50c2df76be3380c5cef28c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e0847f5af1d55baa4f049160f617a001af19e47668b8e48510998deab3c9fc0fa68e4a1865f6c38e8f8e8eb9bf47733991805016f0f9b2f1ed8872f4a3a1bc4a0c0a21dc1df11becf1382ee82e8a484d809e62bc336f5c01c868e46e4485b9f257e649585343d3a37a66bb14700417aa7e868b97cb7c4f5c644f0dbad2930430211dfef417fffebb0a959b6276b7c91d257adee4e816dcd4218bcd1e0f183850e022a97f8fd599991ec69a4ba61630403c15f85a1fae298908b6227a549625a3cd70b040e6eef3bf1ab5e5d1a3e98dc6ce04729fb2755d5ac89566d8f73a19292d4d35e7977ec0d12bbd8ab3818fcc5cdbd96ccd9c7ab10591d9001beb37b4efcec890205955a09c1003337f78701b35c52b65da2910821a20f47375b66fa8e7ef97d9403067a20671f2d17d462269598f376d56e4ef4d3d7a3972c8c7a4b5cc05802c682021c4fd9c39aeffa0c945948426b79b5894299cef7f2d8791ce256eed761c7f69d031c212fefcd97633ff7c5cdcafd24881ee8d243ced41b5f61fa27ffd92d2aff1f0317a801fc076f87b9dbe96a8ecb7b323b21fd179bcc69559acf9403cc624d21137c102eb3d5829a1dddd0132b6aacdafbb6b94ee21a268dba5258ff0ad3fb6750813310214440a5ce822f1cd558bcb0a008ab9c15fcea46a2b7a726c503ada8f99b0656468a719afa5626d577a06b97ca350ce9c0f7c5308e8382f1dc028d2e20a0881bfa7e8d2b7f70d5d98db44f92a9a37380f022b90248ae3939db6c98e7957ddff642337992b252ebb50fd9e7d21335d1c3b53e683f598c48ba80ae84b8e768c5e04cc2b0e254ed58d98840baa2a75710c8c272b4a1db51b0789b2140ae0c12b7a7775443a53628b087e2feff3c6bc19b1c71ab26c883c254062f0155e10d80f7c4c96631793f17dd0487ee06d4af35295380ea11815d3a750341d294dafe172fc9d676341f10ad5b2d1752ed337b0cf0dcc6bec3f1627feabb2f3c7f3cba6a6d860206688d6aaf98a4fbff4d96e513aa1a5c28fdcb285a4ee9044ab5c9ed04b720adedcdb9d7c57d0685490928be906b6b3939738142be17ffee067dfd2bd42a289b69c4e9ed332f358cb0231e4dd956d1e75585b2ac6d6adc672ba75ea1949831f7e889dfb43e4ef4bae5e41a58551fd7245d7d16c40ee1c4fc4ce8ae64d342cf9b8abb0473bfb99103ff6f38e7431846c1587b2473bee691817348b4ba2eb6123523879833c3a60e6290f139b1790aa33457c855041b7af85cf0a77ecb892b436679c88e948634f0914d23ba0551a2626f5a24ed21880e760a53be11298082784481b58699b932c1707f95b33d7f441c167c454ad8782696b11e2d718e1bffb0950f8373cbb60b188f07f66c6f90b74652e01860d5bd7fc690f84fcd6bb0b57077a0463ac83060f3cb1c3418298973c5bd88dc8c6bf18944eacc521db907e6c11735d3a7a118f3f4a05604981625dc96ffbd3218a8a87930e41a579250c3228619b03b9d964e7b2fc761c44763730db824cef6bf02afdf0b55665b16690fa851ae6cc29e875e6a99d643c883467f3ddb19de4668b71854fd75f54945961170054cf30f6b88b25a3e891e0c6d5bca93c571d3bff3bc702f8ece811fea51e4b4847a21f7cce08456fbdbbb65d753e7f60a34a5f2b7ff8f41e1166218b69d4ac9901e67ab7108981a26d3eea96dbf853c79c2795916aa53588f1f156c6476ef78d226d9922604ab670d8b0897910de41821e930e5fdcdd0ccfc5983812f5a2372dcda4c3c0996a99c2443a54ed44d0e696962e8d86ffb42dca5502307c00c19a6a3ce4e6faa3c43db6fd343ff92d698295d195911bcabdd9457e240b2e67e0928799eebe8ed7c30619e0c9bbfd36e6315de9732293b3da61769a9734ca23e4a6ed5b992ef541cc0b52620fc4f48e53746f5f1d49cd24bc3ffdf2c0c2ddce08cc31e91ace14df7fa8c239433183749bb9c414bc60d89959244afd37d861f1434efcbd8fb787014aa5659a477cce30fd6f69ede9af976558c87185a2e97d2fd0c19fe95846d1a5f15eeacf16514e43ef679fc88597c6e3600cd295909bc70b5a27cc775a92529d5a141166a83e0ae152bc752367433e53f32ef38574348e15a898e0478a931cb259893569dc45a33bc5c1bca3bd3eaa575d57d42b77d4568831bfe818239148ada21af1e8a7e5871bbfb7cbfd472649636c7b875e6bc922468e9021ca38e71e81a8cdc6878b4c848e3d69de9888eb27bf2ea07223e19bd9e896fe45c405bc261277a96dfe7d642646833268720e900000000000000000000000000b1d0fb7bdd1baf73af879d3f96b4e38aaf5849fa0704b06dba3f4fd2f50ba2507c4d14d6b0b4fdaea68cd3a471df44d312b7c7021cbbd37ad317ac6167093bb3a11cbf98669f4b4e62ce7854e953cb65031a6714dfd11d7c820f1c59a868cda30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060f42ae58ea70cb2484ad5cad4fae671c91e27ed89c005334a41e2e9f0c0290eba2c33b30d7c7896bcd7ede14db04a062d5f2e438c3ff75d2b90da91b3ba899264abe7689ce6a7793e6b2f17644579d9af147b6708ccbc6497bb02b49e8635fc8e90516d548d15ed32fead301372d18c731202e3d99c2822e20b29067284301c030052fd06315974ff1078997be9671674c2bef1f1dc1141282fd68b81b682b822033004e1f95c28466690695559a142d068ae03005a50977796b950e89ce952734d0a08616cb770aaeacd967b44fef420366f8c261a0f097210d1c8df6bec9d502229940b79be0717b250bd430159b59554993f926f9c5c2945b4dcb6c61f9578f215032582751f4deff6a75a3dd1a02e841e7fc3f58b80081c2af67ee3470e471939310229e5b6a9ba4ab92f5689fd28da4b9009ad96c2309149c30e20982bbf434dbbc0022690e8e501e1655b57a9c45db1a8c0325373448672d66c911ee8c9f2fbfa57c4021a5dec0e5cd5a7e839b8cd0f46e5a534456d09352f3cef26413b7c22d4e025000319925bd144cd133df46a6688530e5a94d0c7b0196f9e9f792bf9d934938ef279ee40878cacff9041073012a3f05cc6147552eea91ee05f58d9ff20e44ce75a25099f9b543c047ee9b387c459b256331eda396e88d3b0a437de183abb2b141a2292935472023a133f612297b9182bcf7bbe1fab32c87027e88b744e86f03766b13412f056d642d9720180a3ea6334f69ed0d225dde0f1be31f9636267e6f942aa6cfa8c507a7bfcbf082d61bd06e97a9828bd058835a1a798bf70457240b4a79fe6d1346d0d1420fbb73f1b940b8fed9acca8fd42860139c0951db9e341c7eb475f01e5bdd1d674ba7fd1c891f77ccc7317d88b0c911486875800b0d4650fb033f6c261a7e0f5dff98e98f2186b2074d57c24a656340605b03c64ca4c64e100181eabc8f60f040c71701f6e7a61f18d0d9632e2e091559384763ed79336957fe84a376daf49eb8a8a4eae995c15435fdfd6cb70ac1a67817a620bac06f11fc6a40d137e5e78748941235e413df661e4f2726c4d99c9d0f3dcf08b4dcb20cabfe8d4d5c2a2dd73c9b8b51e55e8d34c6f68b7d8154dc7bd003dd5077ef2fd9fbcc87e674e934a19fbbd8cf1231419a326d2ca71efefc6efddf76c6421956222b050ef6694c21c2f7c0e2ac5db6271941b221bd0b8f064ce92cb6781497dd74c5e4c5c830fd590cdf9aa6e260b64f4ac94ca1f83178fe02bca0d3413db5483375aa77a4c84e210484af22d7ab8e01f6158c183fdb3681d2fa9a14a91dfc88edd7c65a03eeb5f96d307aa40ca376409012df83dcfa0f27109565838b77850088617defa937dcf1c32e22425a9048de2b9a2a9646adacf06105aabdcce3b11d72d04ec271d5e76d2b30f6c33b9f3d0bff928844f7323694791a873c01ddc7fa95bb8ac0a4c8754f5458ae8d13f62700e931c65a880404fff0fdd3bdd3aacc73104438c53888480b7d097f7a7375467cc33788b2633a7b5bbff8ed9afb65522a01748246397b37c117bcf982d90c23e3ee13cbd99d5ccd7b7e7126b9a914c11e691326fab4ddf2935733f63e1955a8e26f7878b2db2cc39d42ccdf1b5b11ee05107c41a0b1dea0832db1cd85c8fb8eb17b4afb1ae07ad6463a1d6af4e1287e0ed6ec25d45f1c84dea84dc90be3ee54aea337635d48a1c9250657bcf1a338183958e6df263c1dfa0e488375a5b35b88c896b17d3b4fa15d540390e6be0f0b2b59d8e8d5d52b44187fdd4f6d3bd3a394e3cfa06eb0f95ccbf5142e2bd8f73b96d3584982fcb123a2f085db81a8a330f5afce48778fb2978bf71ceccdb6caa1ba9e87476aa7ee63c879ff005052c65df2220aa56550b47687ee3892ad98f6bda2bbc637b5522f76dd86f204fbfed47f8c89da65805c7bf183aa76e2c4c9e7d471ef170e54f1c5908ff9cad30bb6e1ea3d5508830c5d008ba03ce957b45b08a2e8afe793b951acefdbe59da55acd21906ceecfa600df00fcc62ad505724fe66b5b4367be8b7e3dae32f20e03aa068fdf978c8e42d3d65c0805f4330323b567eecbda86b7d1e081944230ac12c4a160178aac0134b12319ed15ca2402288eb7470edd53d3a7d60fa395420100fa45df1e2c26704ce316917f1144399d0dc6acd33174c7fe3088472264b475c66159123ee7b05b28e9579a3fcc7fe072fbe6ad7745e4bc81765bb620e7a0e562d4bef1134446e799962f8dc57d8624d051a3d56877bbea0892f5ad9cf461494d0bf464c316093f9deac5a67f2237df661cc77fa36f61b58fc5c0e48ff657895171337190794fb09cae99d95f8c7f2c5245d071c078d64dcd70b90bf9116b4a70156d006edee9f70a5651b46c90ffa4c1e4eb108dbb8c9b5e76a6dd46ddaadfc45668e087c3187980092d80f", "5163ac006a63", 0, -1632957627, 1537743641, "b7cc4fa29b46d04090d94b1ad907e885ddfd896397d0d014f2df3d8c8298a31e"], + ["030000807082c403012868754011c04947935771c1f5c6ba6af0669a42fd505bbefae7234631db07d502000000004aa3a8a2045859e00500000000075252005353ac6a56cf0305000000000097abee0300000000055151515352204dc6040000000004655165630000000096e56ca100", "63ac5351ac", 0, 1583282119, 1537743641, "85296f30478d553e07dc2b7a2af2899430c89669ca0934722db5ac82872b68ef"], + ["030000807082c40303da75fa5336b74cea06d748c0e0c28642cbaca3a3cd3a9923aac2bde9bd59e32703000000086a656363535251ac30a82c63f98243876ad86493ac079a8dea3dfeb2973bd3f6f0d7b3b45327e4f00683aad70300000003ac6565fc3c84acbc0991f3e1bcf5a5003df672c79bf414969a5c2bc6b9c56838577f9c4ab8c376020000000163ffffffff035512b70200000000025252d0d61505000000000553ac6553638e52a20500000000095352acac63ac6a6363000000006d02196400", "65516553530053ac65", 0, 860211217, 1537743641, "e45b2412df9708bc9fb8dc99387469827cafedd5d318b257ff79f5d1e7f49096"], + ["96367b7602d8d06f19acd891628929c4f383c18e4a6e98f2051a9ec32f4a4667c24b489f7900000000020000ffffffffffcd893acf0e2b782a80a59f4634bd821a1c609c83de0731a03f410ecd99975c0200000008006352526500ac65d4a298fb0203bf46000000000007636351536a00638edf9004000000000951535163655300515200000000020000000000000000ff917d000000000065ed541b98723259762758bb7ff366fa10433e076b95529f9a25526ee820f674bb0de6e71f3c9a855d6d80b960c55ea1c431e357015a779730baf57e2f2c2113ed2f3958b8fe5b8ba4237f34498be7a624f25b63f94dc38adb16126ba6899b9500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e79bac232b02311714393c50971d4a678fca293fe924a1ac90317dc7013be22c96041f714ecc2416d8e2b528bd22429337ba003df25cd98c95179a5760b5ab4baf184f2bff025932a41378712a2bc4f816f664ffabcb9f55b7fe6e1398a65524e2537be7493822349aa1648129ddc76e5e382b74e6a05f4609f3ad4936b1777b022ea2ddf7a52c4fe8469b1103225d15df9a87579e9fcf1164acffefdd38616f6c02028e6dec6e09e26cb90de53ce73c149a655167983206fefd086212a0a2f64dda0a07e99c5a4c71e7057da1386cfe72d0cef1bdda569650acb17ce690e2c2b8fd7544a8454cfdb36cffd9b30b5ab974bea55cad4ad1a487dfbeb6619a4cb86c6fa902194a7baa3e6b20c54fdcd0b74770d5310ffd78c189f1924bfaff2e4ae7d40f6802195148f0dae148d9c5c748b915d9e4899a6847e22e30e59f9574c687525a1ec0031ee73953a15097fe84dad00d74af3c79463a606bff4d172fe7a65b0463994aac032b8c4a5b716db45d5fac684c038c292621b235bd0d7998752c40c5649f3bebe00212cfedeecfc2c746fc2679afe4c6667c199576f5f17a3c75cc3ce1e6acc77b55b001a82253d883888ffe2213a114816a50a136bc29a449c4272e9bee7ec7ca7dfbf154f7a0d5dd4951d1bb456d38bc89ffa81710b212e84261224bd6c3991d63634e58e379a903f4ed32dc5813b967702711a64e60679f74a6afd3dec582ef132fba445c7d470531669c173e8ba10d3e21e756d479b64e1e22a37453a7b508e041d31b955b755adb2cf386d0064d5b03a99cdf61cc9f3b4ff8842a8ee489d78b008e6549086657fb9d4f8659bd9670870b18db870ca755477c03916dbca84e8327fffcb077b7a8c20f813c484511b89b14dda22c8c367cab270fa8701f56cffda2548d0a1558bc88e096e38d2bc014c6107dcbcb1f1a50ba23bfe7255bc3e570a1400ab357ae09f42ffe5c8232e6087f5df2e11cf6899f66cd9d61134f837b18f22b95c8798612152fd79d229cb9c243a880eb3112feba4e425155b252f3755ba562ca77b37f6de333260a8798f22b02a3bafce7c45612a7525d8f2ddaebfd8ceff4dae724a5c023df4d7dd5300b80bdcce127683697f961de06f1a24d4a7ca483465ae65756a35f9a4d71b7016a0052072b687d5402e1d9fbee11014117e552f6aa74c05e7a63a3c4093ea1736bf08a829cd49330d67d465ec04028c5f60f3815d15823a8a014bfc6f4602a08602835ec4fc67f805b30b071285bb6da6c5da4aa2f9e9b23e283b88ec97b488634e560d3e55c3f95c23a3f21220ab56f9317a3220154b6f6d15de04840e11bdb52cda6ca8d82f8ee8c0602d44f76eb59aeee60de0561aae1fd65bc752ac860380f1d563738f90fac8536bf6517c9a292356a1a8da8d20cea397c9cb08dc38c68cfe8dab5705711e23cd4437c342d1c49fd6f9c4c54858fee49c6a1ec8ac6f55e76620960a9d9513a7fd26883024baca6f411d5b0b62b3bd9b66b505f92a898a45d4081895302496f6cf0cfed4b62c5d9330884066badabeda7b56be9720b4e8abc91814ae9e5b242db475191c7e1b109f884e4675b218f1577836b1cf46fd192ee0ade2725861bf63179c703b18f1fb96e69fae042409a16be3623b92682190665123c0c9f072b42a36dfaab8a090f51c25c7acf9f7bc113b7dec6517237c2bde013c43e95ae5a7d633650cc197dfce6baa069d1b65dd281f9b01312903f6f53d59f9303cf69e85e4d1503770a20a1943422a4796846e526fb74b9e5666e3a9039fc680590d9f85d932dea3cf0ac06d9ebc10f89be4a3e76c170a455b9620e5e60a979a18332ee5b2a1025025f62b7669ddd381ab2a712720cc8941ac02cac80415e3fd275016452bd0cd9034c3d8614876233708be744d7ac8c6f7e39df3d7d71763bb51f73b8b8bd7d809cfd8a276e4c8bca46a32db361f4d731839434c594ee1fbd781e73ccec2d5378a04ad67385d5630497d541f544b86d28fda3e2ebb66be7103bf7fcc31353171f67b2481d9c53d836074242ecb8d83918f5978377b3e0e9cd38aa5e49a3853088bfa0dd56fb4cbc85e72f8c873955a79bd0bdb75e060297d7f5e17f5e2e05f0f31ef62a8ba53612ac9b7fb13b074eac661973728addd8cc2e9bde6e48a69339d9bd9ccb6400c64fdc8bcd5068a9b40fe38dd0061bd68d027489a27f4d3b99fa99acb897c48bedc8b48bd1bd7b8b51923f043fe083fd4039c6f7f5526f47ada09176ff2ce907501c4ab11b36a131f73cec367e779b1cb3244171b08376cd050000000000000000000000003b2227e96abf3b9de3d464cacd9a94691627057516e0e68fe59758b3f67f12b4452f67503be16630540478af146c2b97af019f3a3d1cd2f852816ab55741afe8c1c99cb7edea8c078b2a8e6a77eeeddd1859beede9e3b04f63f6008ecdd710cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034a84640d50609989ea3a69eb91ddfe58ffebe070875e6c1987e4e2012398bbd8e32e3cfccce51f2b6ec08dbcc900c886a1dbe12cbfc5f0bc42d6bf81a828e8e9978c1f83f5ee313e7651607467d2ac7e7c23fa67795729414d4a9b0523be729356081db34f4997e14f94e172bc3de30686ab498912859caa145e2a0b32b853b0303412d1f07a78b68340acfcf517e24abe819dd31e082ec168f9906b45bc3138f02097b092f2cca46d0cec1ba0f7092aba8a6ee3f63473e0a697f33e9ac9e5f1d7d0b0497f220ad0a5d4aa5e37e6fbea31845cb9f833890f66f6419760da6985365a2f1dd3aa8a497e5d4a2f44659169d10424dc2c69fa41d04b67ed50aa4a256c345021ae91b9f7dcbe96a9a5c4572dbd9db5b72f2efb4db185e462a2d6471a6cbcb6a0329aa8f9d8449c323d0345c0017f343dd7fc1a5e0575e95aa7dd9cb2f8223276d0304fe43c8066b1a9cf3a994a6c46d06c8301671c2294018574490d659220190b8030fc5bba8c6c4462748e66b9730d50ed3760e18686d80f72244e2a476ace5f87a032b6318cda6b519de34669222e04e91c219c372e0d4d04fec2cb6133541e1533ce76ddab91eb12d609f5d0e14f43d59aecf630dca95fde8e93f88617b8f467a4ee0bec9f263042322a17764a944843ee3d58ac6f23859d9d1da698e1064e1c4d27058f3e2a407ea20018ceb89e6a90d0638ccccc62301f99ec275dcff761fba7163350dfc99f88b2d249de9a4dc8a693a309fc793d5c22f1934648ba7763aab72a8a300625cae5a60f2850b9fd6cfe7a9a261dd9b8b5e235eb1c1a15d3b68b6eab1312102e49c3eef8d8bf30bf4097753529b52372c9734ed96a4009bbcbc8c1f9c0d1434a4a1e747b6c00db0ccc8041cac1b11c1e0069ad44a1f23b071d67123349d9dd799d1e9e86c9a6be297e9cf02a48dbb29a1ebfbea0815ae7479392ff9e8096c022203af114c9ce9143b9132bc6a27e6a4ee6e09500fb716ce4b302e05311473dd3521863fb13bd5caf492fd9054f0496c982f9bc67fc0ee9b01718bf01af90166fcef4f8b2e5d50fe920ac949cecacd1032da15eced72e54c437b2779307cc0256acd8e85a5d24412653cf586cfb0e864babc63f9f1364d10ddb6b1fdc9ae5ad760df0b0087bbe7edc6fa2b48535623ac3aebeab3d6d897a57682a9bae0fef9d15f0b0f4627e024d2da0ba3c47637a662bcbaa18532d6fbbafa5e2861c9d2ef06c432d19a6ffb2f435110c81988ff43ca9f565e64d907c1c6f3523320f53b299b2582a6517ca7d4dd1a4f42c8b89db661de64dd206a00fc551eb1a9d290efdb14f3ebed85c7badd4bba3b9a1e833b2488be5c1954aad95d53d537ae231ad96000bfb333bbb5e7446ba42c10ff39a8fddfb39b92d1b07f3aa1c4afe8f62917a87336d2ae1d665343ee862a60bd91fe08f2adb0aa11fcf7707dd94e8ae8e8f22920173d0394cad85cf14441194e4418e26099dd50d258b0227785af75b9711f274f6388454ac57fab3b700fccf28983c7795c22038a455a806f604e4ee10781719f66ce00767a0d5194a1d7f04f3389695b9c50eec0a930fa4e910e7527bd14152d6388dc840825aa48214bff060118ad6f7689da353c4d11b8eb582a06206031da3916d280f82a994a628dab5654f24eb018eb072d7652fc807f8f8c7a4c618d41a5d76557a7876a1cc6fa820da7f6b55cdd7fa3ed1812ce0f86665da6e0f9beb101a9cf46c890589d7a74a5cb6ca12001f1dae51fcc4503eb0d9ebee11d45de23f7c14b1673412bb19acc3a9d676cfe8dd17262c0c082f47f0fee0efdece4991b6e11c0bd9a35e71c2f36953aa7316d6a5eb5fe8388aadfc2a78636923ceb667fdb50467605ac7eef0d0e3540a32ee09f183f471764a45223fb34c76816ac346582c3ac4b11d008208dbe83a7a21697df5b46a7d422465db7aa0a31547eeab2cc08b2ddcadf22e7b66f5f03625a0de5a4af7e5d10657ef9913c9aff75e9eff7bc3457d5eb1103c8babb64783069e2feb6c10f7ef99996f50e2f2e947e6bc642e9f2bd40a221f1ebf7d3c207bbb44a1e70916c92f232ae15bc11e2e423d2c8a0cdff927b574bf2e666bfa26dc0b8ba55338b3186c5c20a3b5f7ebcd224617e58e238a6114a31a574ad001ea3990bcb089df0c9a7595393a0f525c93e8fd074f7a99689df1486fc3173f9071853c359546bf206a41e0dca96e8a7632783c13d7274b403a6033d8a98e302bab543923bd41fb34bb485de44da0ec52e05f054bcb0e15629f435091c1711471d78cfad35bbe0dce429fb0fec4bb98ea6af8dc271a103cc8754d9d669f5589418b24fb626a6afda0f9c0fead068c82c5ad84014fcb0baad69c07e0be34380029931d1984ea1d31c1bfa15f7022cfd499b06ba533c6ccecf9568de576d464c6feab2059d07", "6a655363536a6553", 0, 312005339, 1537743641, "ba6189f82caa3bcb8ed59a81348f672e70487bd6428a756a12b4dcb84327fdde"], + ["030000807082c40301c0c3e1f8f506126d5a3269be998eb8520dd6ae3259793e3153b2bdea67fe1c6400000000065352ac516553ffffffff041ec94b020000000005006a525165a74dca0500000000050063006351496ee302000000000851526a51636a52ac60e5b705000000000000000000682e7840030000000000000000b13da504000000004202c496a3bd165e2da735a69c90c1f512e9f4c9593cf3c539fd3ba2d62da3a190dfa640ef8ec64efeefcbaf8e5ed79c5dc0d8479a9568e2931643a2fc3c59b8a512301eda50db2f2ba41ef54deffc3a111f78b45c10a2db8f930b42c3085dec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004f5d0e73e3a73d994d7322b862d910f00317cce5802b97e592d4c423bdf0568ea338d4d87295928b1f0a73fe14cc4975f8013945b3a073dcafa5213604e1b3aef662461325d8af4307aa5d53035342866fff193efe50d8655c01abe6bbad50c2d88b183e1f29a903db94eebd778f1bc6ef8956651ef3f53404adee9c3a83874f0323234edb6a895103b79ce1edf30cfb53ed805a06e205af2e7246e89777445083031800116c209079831fdfc126aa84d418631676c765dfb38cb225ae4bad6c6b910b03c1161600ef4d117c2dab8e96eac86c91d3a4aacb7569b0609fb0dcd4230424191e48d596147d15bb5fd475dea4d3256c0f9a75ff08786c9d2123ae11dc70c8020540e83b6639c7f43008fac0380ab100c59b8c8f7a0981325bfd719c36e28bd8032ae46c03fc1a5e75320b846554dfb0a64d2dad67e9e8f1a5122f932ba3e0d91f0217bedc2f4f6866d659a8c2e628b47e40c97dbbe158f9a38773bd642396e70c69031b02cc1d2a01a5a0bf4c134546f34a93483ee067a9c41be47c16c827fcef6d8e032e8aa772ce589e97aa5862c00484e1e62893c6e12c0a333681ea7a2b1482ec1c66e38ecbdb2dbff9c05b127ab2bd5073e02a93048ff3ddb43ecba93ffd2cf6ad7f6e2ece8619621a19272213f1b411db8eeabb8216103d56bde5c7bbc0fd7a865f44b56f3b5f6afeb4d35b15f07e8c79fbcdc8484488c93e8ab01e582b9ae22c5326d8fd75cc2c64f56f24b7bdda6158770eac9ded1e1103f5f90abcba4f29317b4b2dc90c4bc4f8a38b07c32cbef0e82483bdb032dfc3921e46ae4f0cdbfd1a55a83e8dcf7062c60b8af9657f074d43a173071627050a6581b49a7a9b6619022677f5fb6dd41c382756a12efb47d22782424d5083be980ae4c58876cf641c4b12e54ae177133c08d858bf2c71b52a6cc8777c587da3cc0f497e23193c24e0febd161f4f994e1f47424627d813bc23ee7b277a92324f1d338df010e3ef96314926877d11560bda0f41760c591ad2963d2a01ee5e69b9bae8fca8c76d4c4b6efc0aee49e1de5eb4bb97a326fcae606a2420db58dcf1b67fb94149f750b8d80ed8f68747047de0489d69848979f6ba67711248a20f12bb20733eae245ab702963cb868db1b1611db379a43505ca388aba5bc7ebef1abdb067571192ab18a12cc473c40bb592c5ae7974ffdc5f33d46129b9ea9ac9abb14c03d9597536ffda74cdebf758b115f93908a399a84f85cadf6bc8b3df2e1904319e4f72bea4922e97d08b3d3822f17a241f4639e7df0f1e6ad529cbbe4c03a77332441b33d96b78218e272fb5c727a83e2f8147a34842edd74454271e6aeb049aace8f983844539d0f631956b9011bd53ffd50d6287cd97bcd511c8f9265424ed6f7ff83e3db9eac6baf702fc4f0d373d6251396d6c193679a294039960651014c36bd5539643c1b29a92678e693773d467cd530f5f4fed95d287cc0d99d4a95ca1acda3e89f5fe83ef273b8c6141944bcae2d1935580f68d7941d5b745564c98beeaf78ea44f8e249aabe3ee6020b7e485bce30669ff12282ac5627fa658c36590f34221e4472e9bdbba881c76a269012dbfc828abcb9af3002040e804353c132add883689e758716a6a7913aa45a85995e7cfae96fa8c0f4dd461967a1b3461c903b47b6162223579668bb072aa260bb68ce9da4e8b69347912b00236936d40ca62e541fd215e10c052d205711fbf89a8c0a5798db6f678c01973d71a3285cc53384158438b7543c236d2794bea1fcd953e36836f274152ac63279f6a2380dc8c7f7e8b442d3619386c261a46c7a13c290de014b51745e97d01c1aa3dd4b4e252ff0e0a7ed382f3d53064b870f6a1f2d3f45c7ccfec005d27932cf618cce3af162335c23ac82c7d6a93876c47c1bcc779ff34fb5653929283d9db5964feda531c51a7dc3f35408925a2469b15bff9eb5cd9d826214a1f479bbc931ef719c59568a2a97d2dd665bc6d62e6583e1d9c31c6a2df96c15feae0989ecdcf8098b1c178f625a3e1476068875d4ab41baacb190a24372ec795e01aab839357900da643c1077a7ede5dce8ee3d6dcd00d4cc991b231c087b3a4eb9bdd7a628f083be3231f004fb3ddbdb349523728fdd31fc57222afa59f2f371fcbf091f1bf15a1231f7d5b5fc596243ddd309068478e022f2526ea48448e67c22872a86453c334d4de81159904fd642d19d120a94064e59d528a24512ed53e7a01ce8048e51cf0ebaf7f31da17819c125e5212b66e608c53e419a394c9eabc8593b522aa400000000000000004bb7c40400000000785cbc78766a5fabb41e5d31af5028d9f23f2083f172a5a242dad418e2c29228d8e689fffb6ecfac995f3655ce6b895a9d3813bc2ace75678f8fde6acb9eaedf79ea3ed70cfc9ef48ac122f4df7614af2566848d53e056fb60dbc4024981752200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe9046b34d73f5596ab4892ad9ea366c2fcf9790bd91f9d671abfe4a9e7856e60896f9f315ab8f1606c478478eb03e47b3531e88a2972db9368821e4df0fb62c0d0a0bac7feb6dd5e8f982c5508913d633614f235f55a3aa5f3e8add7fca389a734bd025c08a30b951f16ec2cb3442bf61be16b6e4fd500792ba498882fd6afa02265fe67d58902edb3e12bb2fa6f76fbd020763ac40089c3690b2c7699abd9ceb022c501a8d80d6aa420c7d9fa64b593e976e5aa5b563cc5bdbb935c12c8213840e0a0173a1674645db923ad27d1310fac5ef8d4c54fd2dbc832cf2763bf7832d5b68de62d841b500b73348a01ab7d609d66b3d1861674114a95efbc272fe37ec3bf502066965e8194b2e72f48db480e6dbd330f3da46533d8e745ff45087969fd6aecb0205620aa56307694d9c5a108b9e1eff298ee9be1ae376d58c9ca52ba1e77f262e03123ca0bfff67bdd364fa6020f71023f75ec55fd595cf33026ee0dea0d5eb04fe021056c23a4e1a2b1b8f7bc0d64d3f3b131fba9c09aeec584a6fa50f9500dbc25702190367ff28eec119f54b722a79e150611a54e4d6da0c68f9fd6ff007389aa6d32f67e8a1c8ea13a24d468f7ce0d6ed52531eb6fa93f6d6dcd7fbcea78c84707511c22c2b858aae541f7e0204d75f3358bef37f5cddf81280667885b48989b0bb93ab2f0a486736999d27686b90071a62c97b40071139b524b2584220911e4e2529fd1512fc46cf2e1de7b904a58650fe050ebcec3538a4e48a95cd4302dc8534b1a7ec7469ffa986d55a15414a3cb839ccf982da2beda0ffcc91769ab91d82b72d277eb783ee700b46a0cc21c6d074000d129a843e4c1885fbf181739f891572612094b680d79663b8d7aaf1590cb5125ec0511ca4e2ad583872364c764fcce413f24f21a48761a446d180a85883fa28944ab0198ba249125552526d719a43a902aef289e93e2410bf624911358923dc1366805036ca58ea6454de940f05bb46b38d2f0bdf6a7676a816fd6c776505fa149a9a6ec53f1b1c23401af255ead8a57ea9f4005f2dcd7dcc3d3c1b6e72868a28b55700c4f8b813192df102d32d7773bbf19f3a844fa4e0855467f484618e0cd90c42506c9d65e505ccae1a98480be22adfaf0ceb73dabbe5a57f4fa3956ca75b93cb04a9dd2113f9638989a846d3fb6a07d1cdfc96c38a0d86fc457ad1094d07d829e20084f4ec5513c7278ee125c853fa3123784753f4431a66de78c22f3efeb8a2d2241c128e63fa75e2c965b35f37a18a97e01ac21b23a11b9e8a749132e059a29c2a113e72f84c7de02871b8234b8cad0d29c2ab3ed7632208c4b781db328d62cfa21f065c5675a26e99c0cf879427b225ccb833e5d4e514d668537f3342c30ecb957f74dd6fb54f38415d0f9bd612dd55fc1ac60b8e73d093d5532f81de3448a698857c027f591ac87cd7be37b79a44016abf5fb97a1875fd4588a72a7f635a426027542e1ff7ab401467a97ebb63bd3e24084e4cce4e514a37443e5badcd8a03896936175d41f6b352bcc1c41932dacbcd2c03d0a98c9f549807a923b3d22ec92e3ea1afcb45afd60ed01716bf83d44b0447e7f1ec3bce8c7f81940ef54f1d6ccdf1e4bf691c3ec767e2732ea0975279e0188999cdf1b73d7a3b051767b56b5e7e7cd6aa42775e1cf380d7c0294951a2352f17e3e8b13e951ed9e1979040730643272e9f32e65c9b52e06255c6e3cf0bd1fe3921205ef39540b759a4285da6913e26fa00a6a912162f73107b6bd06db992197cca851925c848c07f762e6fd49294f48f2c500ae4e86371dff73b47d13d1d2ab0fea50dd197bd3577b2f9e1a642a47d9567f76a67d1bdf1d8be2d13670bd73aa60ca8100b984b2f624918b22570bcec30ad7897b4aae20e6ad9b844a1daa8bc7e52113b0b81981120801a28a7035cf842f806863b1047ae4f8632b825e55d5ea99d329e608bad314f927ec305ffa40e1a1434f8e325c235f0d1917d33121938023d6fb2162ee16734af6bfd16f8bac945809c69c0984904262a00053d0f2684fc5834b87634a8af2910c10cbfc1f0e594a87d440120ea5a8edbba725286bc4929b815fdcf2e7fedeec3a85dc4e43fb1fc2ff212d5671222ea91af6cb103994f295b58c56d338af984e7a2e006710ab96862c4420422c27e51d69ecb14824babc608a9bc591ce5cae29e5e827bcf6ec922e1cb614b4515d871fcc4073608818f4692d09e5c5a9be368c20d6f882188a64b2e239f85bb7ad4a5eb5168e8243e251d6bfae9db5880f627b367cf162e7002000000000000000000000000cc45ce784927e1fece08c1e36fd51e6f9ede8c220142a8cf02f1b1a9997f1a557cf8eb1c99feab96202c304bf0e6e13854689a178a334f7aad9290a2821246d1a863cb4141e476c994a15fd2bea192d5ae7e7c35bc43616f40b838879acb0deb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004b77829ca5d4a1021ca1058d8e7a9ecc73d20e8b78014279a88ff6481a6e02af5dde886eed2d97484329eb8e131fb82765f54fc3fbd6e998dd8d92348ac3dcea09d8a2172ce5c992157150e3ebacfce63bc2502eaa17b01db976bc9dc5fa2cfe4c0484c3862e9b7c99cbe2263cac5f0fdd36587392134325f22ed9506e7a1a8b03014be42ab666c3787037646db035c6767e18cab136ca5869a8a9964ecc62da890213bb3dc8c5b9a7c61786834766eaa0207d318c109b7a6c4df088e68931ab28c60a0747162e9ab247e9442c3251cd4cac97de08445518aa30ffa4096bcd3a6c7fe8346e1ca1e46c89004be431925ce9653ce2ca95a46e2da6d850843313612933860319f492b270b3033a64f0f16ca2f02d67b5bca3d5a2d2f2b10b05197263f30e9c030a31982ac4d953cd71cf8d825b61674b0d2df38abee7e13d696b5fba0ce3d5b30206810735fd297336671425d5d25afa158043dddb952850aa863a187f1239c31d0227c0fa57328fa17c541210d08457824a3483040d9627a2932fd359ff5363262e02213fdbe6db68b97a4ccaf0f838547652925a65aa8170a18aa9bf0a2bf5827a33207d69121ecbc862deb16c96d9ed8c01830d2d5a9448b68515f0fd625a9fc0ed0237fa2cc19b0f682ab471543aa92a8c9f7ee53b45ece78d20bf2d9ec2ae37e9fa3d871782cf5d4fa2eab626fb72d22cd433c16c5d5b1b4d8bf9699639d86a00e33ff9e85584f73d7761d10a227cd01cbb7e8cbc2922f5b8ff58fdf66e90324eb93ddfc969d62298179e7b05097afeb3c31004afd95b66e15a102cf804aebf0c7717a42e29a0b7a4720ccceed535f88ea6859a37f8ca7c64bc97da9a949345711fd9cd78d15730f65f84ef9af36b94bf8d8baf474bbcce2c58fdf0cfb3dec666d30ebfb539fc1dedbfee8cc833ec640b342f3d518777795807a18fd3f01f0d574ef77596f37cd53e4ad3a49d2f755539c95bd6b19c42630d21e81faa1c674c7186d0abd9a0a6de308f30dc60c253cfa936e5d53f95bf2240f4f41afc5e654ab9be4308bb97fd459ba756a2ff1af4ef8238692cd87e8ac651b256a5863102912ee0874d264cfa74a6c9d74c427f8ffdaa6525be12066b10aaf335155dfc3917f2ff58cb1161372b7c40ec2464befbd061f47494949a86f67c0d809dd47f5d1b4f44812e4dd30c16c35caf9f6e869c04835f930f40025e4b3b8985ae796a8bdb87107a09b96f97cc4fc980cb91e4e2779e12f5771e05abdf16dd75ab49546223a3637b3a01d53e2dd072a3d5dd2e0226af9c6c369bd81bcb6e21c4f345f3869e574d148c653860dc9aadf00dd6b4d05cc2ca8475001777d4eee4ed9530bc31ce2cba7eba0e5bb8c8d1da18f194b4f1dac63151b1621f78dd9b4ef4a1f522828a036ddca30a8d1527a32ddda137ed47064a2a03e952d12ae35e7cfd33f1366a6b0bef24643ccdf910a0662f056891e944bc50bee3eee4c3cd21481f3834178c8bd01b311eac00caf8f372994d599a6447ead0264822fdeb8505459cfd64eed843f7b354801c27a7b0f14db95b28fea14fa1c33b452ffa2efd8352a273bcff8f064bc9ed524adbcbc49037fd58207c98e55b214fc0aacaee5d90aae199a14f777040c2b91627a0a76021311433384d46869e8c138436ab7e7a2983b6d9fd55787215f12f68b53109ad5f1f822b7964c262f2c3e7cd66b6962a6ec47f5a6c88a312464062ebc19d1bcb83d0e207a6a9d95ed6230d1e11def23daedbbbc946093b3ff2ed28b7569ba10836f9f7e7235f50df814378035fd794b9d079025ea86333ed1e74f196bea7dd3f10fa8df39563aefd7de5f21156c2904c74a8d317261da7811b7e2c02b40d455cdff4c89df5a44a6c9d269ece29684188afff19b6df5116cc3de8134385b26f27cfa37c1d3f0fc5a4bfca3d1be44d9873dffd2a26434acc28a3b8f1972c54d0e0026bef0ee6d68cbcb958b55a26036f9660e789c92898468664edc029694deed9a1474a8d70ab09329c3e7870ab1edc19564bee42cdbc533493a546771bd9e6219752c4798c19562b66b2407164156a7fdbf5f175150c673c44cfe644804131073db23cdffa7c7a2ace50cf7f63641d24eb1fb72636a4f9380078194f81d85e8dfbf7eb3ecfe41029bc7d5162c36134a3c2fa8635cdb55778f3d8857385af03801b24c4b352262259dbef16c213dec77a216bf428f5226105cd2ddaa839b8da918895dc88633b68ed97b3286e2f4c4245a2c9bcee57f7a945d0ed2d4d052d244e39ec7faef427f22640b40c508a3f98d72045b5d32c65335787017ccaaa08b54f3ea1f9a9c5efb7d8957a27b27b01440f838e3a3880555bca03a2b45afa2a7906cbc64ac5c0515ac3f68b01441a89ce025db178ac9f6d8439715836317f4dca80111e73dd9298c7a6f8d604", "6551ac6553", 0, 1407451662, 1537743641, "c237eb497ce21eaa435b995fc253c823801bf9ccb3986477a6e74942866b238d"], + ["030000807082c40304ac48e5715332938601c404f11d0ea19b56dc8673558f4bb6ff6e31537afc79630000000000e1510f524c242439978eb65097e6cca70a2753b7306c6afb264abaf49b31be1ace95723c03000000096363ac5100636a5351396613a26e141e81387ff0f5fe6964c8989e34c8478ad0d9a491de5d080ed4dbd9bd864302000000020052ffffffffb97f70f1aade76dac58dd111da8d7f848cb87d6221946c62ad210efe3407cf53010000000753000065630000ffffffff0341c09e0400000000026563417ca901000000000853525252535265539ba409030000000004ac6a006a67e3de20776f102700", "515265655100636a", 1, 1595727327, 0, "dbd3e6bcccff4be7cc6dfdd0c2e3b97f7117dd72fb3fa7e6c0c018b71b5099e8"], + ["030000807082c40301a990a924141b4ed5b08f186d6a6ffa3e07794ede8e2f7093a4b173b7be0765b60100000006516a52ac525382b9f0c5033dd3610100000000026a63807b2b0000000000075353636a65ac63c242e00100000000056a635252530000000015f80cec0100000000000000001d0aa6000000000019f5217e67fb853d30e2c4882b70687dcd22ab95dc4088e74fe7b19689a16199140688b3687223ac012877f61397921e46dba3fa5a09cf73839b6e54133f6e14b34620ba4e31503054bc51f2bc5684de64ad9c449bc0aca673880e9458121c5e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a6662b29747c7783c959346acf0d182ac0e8ddc65e075076613e20a24bbfc1ccfaa6970873d736c64f9c43c9b18d78b23054b8d056709c429349c668b6495c16502556a9eeba6f9fd144c94a52c46974ee09c0d63b69850b309890eef2cba09be990667e49c3fb1729b8ae65126c5201fe51d941a0da46100f7cda3630d548b032e4211001f1e2be334e6d7fea9aa9969f17b8d0858633aeaccfb7ffa05daf5f2032ccc53cc006c9734f06ec9d96dd5e43e5c1cdfe396ee0bb9258141c3364f771c0a06ab118c686ec7631a277e2e13804bb372ff72d343d19475cb36881f8d5d1dc0b6c9401f4c187e501365597b72a8a43b79c35839473b7edb559df66b32821efb02101d800b88617c4e00d13b057f24d64f4e488be69aeaf1698293211787b9f7e9021f5b27ea08e47f8ed9dc21352c47b7dd5bf3392706de5bba92316d63fcfdb1cb03129b78bb7bbb5b1217ba6915e95403cccb99059ffeadbc74abe66279b6561788021564f6620a7bf33f7313ce522d05f0e63f1948012debb575e1e28a1f4bb58fa50327f40dafffb3f0482cf4240107c4a5727679202f5958ba23bf5b5bb357be9ef77dc667ace32cdcc93b330b71549af77c314f7542d0e8eb5b7acc5ad3cbd296f289163d1e6282f7ae1d78734dcddc570a12df8013bc5c2dff54cda1d9aa5c763fadbcba19d27010f7ffea49da81af2160e08a7c87e60b825283d5236083a581bb091175a09709eb49f5173b0a4c3c29269b8ee649aa71e3bfe3de976fa32e34a9705a539d405876979b83d6235c9fdd37a37ef5957a30e2e8721b9d9fe566a964a7fa1a31726dc54158e292ed62298a4edad8da448621749146df287956679b953b7e8964b3729593a26ae1aedd68b6ee7acf0565b532dfc4463ad612e2c4615ce4194a14b0aaa03b8eff534d76d1f5cfd924c59ddb035a81ca5566f278df1098eded82a65be0334e27e6de0e53eac6ab8acdf76fdb5e6d50376ff20c45f802383ca407d96d69351679ace759a4c8539b40c85deb75802c8ba3255a9e5ce6e9821f94752e4e1be6086cba60067357e113da5f40659d2fc4a12b5800e91e84e0180ebc3c9922e6aabf5009b57abd13c0bcdae9aa78764f58596fad1b90646d01ec5469578b546a1a671ca4189965af385e685526c233bc7247d341efe60c1e5ad386cfc7ccb89d8dadc22923814c4ce9d076fb6de4dda0c0522018e061d9d9223e278f45a4851695773f0d29adc13df23d85d47bd428d36b5963337d2414904d2d5ba11b61d0b8d423b2716e0315bf70ea9eb24fc88da993894d3acd37d75e4438bc03568715fa0d7f1f75037e750e3c667f6e028aad9420b28751820c5055b369ff6726cffc38218709c9ab7eaf4e42f87fce599efb96abca72174bfcc8833bd71eb0a1f41107926014f6b6deceb8f1baa4aa7c9e925433c8887531bd43f6ca64fd6cc29ae85264db46f2405b9286f2fd0948724b191e88a9a384aa8a6f70211ec088b22fca5285a052d4b75a187967e5cabe80c67f04510684dc0f051543ce798b864d8840b8b6100e2e4225a03eb9066486a4b36f77f88b5f1ed609a0df282f5a118e10416ceef3072daa2a18d65ca8d42c87db1967b76bcc5bfdaec0dc18da9bbf938ee4d3c9e6a421b3227764b188613726a6a54c44fa3970a97653ad548563ee79953ca142264ae6b2c8b077cfcaecebc4d44cf683d1e8243ebb79d3b62be58c4f80954346ceda4ec2070aebe7203e3423b09b32cf6a09041da0751934ef98d6d1185b8e9da9137e138003dc241ae6a0cfe443df23532dbd57ecab9b8cff3c9d22dd26f84f63880424ed5593de331fcb08cb3b21ca8d56c009df4d23e40921d7119847ef49ecc2a22c1a00c0aa9891a0d661dc0f3f78f4e3199b004aafaee30bfee551980c88eaff7337ca427943d9fcca188ca1cd126cabe92e449fe360db79ee8eb965c40146f66b40a73240fdf7d6d113bb5df832e9511ab73902f082ef309a0d3c208f027186b4e8ce0fbdee7bdf086ee8984ded9cc535dd021bdf70910eeae4b0dfaea50fd83579e2ef9d939da2632e32e9cd8f61edc9719ba885948daf7f0bb6dfea256c342b8da47525784854d16b8bb5254a85f2077bcf2e68b3b4197dc7a60842633cce57b01e43eef81943247110011c52036886a0b1127f75079a6f8c206fb7e66bbfeff9f1ca20430a68685b1bcbc0c8ef05ddf5e4042f45f2e930d86932f29270e10a5f6293190266302d7f3580b9f74f64a0af9ce59df72924ef788b7c82e2f51ab65fdb0f1a9a8b488a6cb5dc887f4895eb19b67ca35ca8441d51a6a53b3d595797565c4653010b93cce5ff84a0a16a69b391a901c5ab3c64388ab0a7f0a7099203ce86d9cb406175d41781678dffd1871a149e38786f0af4e3cff8d70bcef1d49bac76bb63a2900a", "525252650053", 0, -97007678, 1537743641, "4fc43a8ec2dcc5711e85b5ec38282698e26d0dbac92b7cf98cd2e5839f5206c2"], + ["030000807082c40302f87e93fa3be87b8c108ebded613dee5f7e6bd1252f4511b5f9a00c1f09aa1de700000000036351654637d26031018db9ad42e05ff133c991bc8c712f8d88727f2863b26b655d086083623c68030000000363ac00ffffffff0447cc1a050000000009ac65536a005352ac52ee50e5040000000000bc38c50300000000066a656a636a65fc0605020000000000e578707be76c3a1300", "ac526352ac6a51ac", 0, 1065294780, 1537743641, "695e79dbad2fe4478a6d5ff2afc572b6c0a69cb73046cc05bb5e2edac386c08b"], + ["030000807082c403039c7663105e6160b37b98cc7909ed2997cc2591f568efc58b57971235fe657ff203000000086a6a6353656a5152ffffffffc055631b0b2f761169d9071534a8fc834aacd2388f07b2a40bd18692dc1cbae403000000046a000053ffffffff19d5768103d50fcfefe9970b2290f3ce32e78dd76b30c05c7a0615578ee7bf8802000000070051636565ac65ffffffff01839bc0030000000007656a006353ac53c59909e600000000029b7a61040000000000000000000000002fb4d7c09efe40c2e8c988bdb7cbfcee26918d74db2bbacb53d398f48dff9316182e2ba18519e309750b57bbe70870d2d605d932db1738be8395d2e58408bee918e37eccaa6d88426ef467c6ccc4e86d188f936361c663e120c64df16a27c211000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009ef6676a11a04dbff2a3f185dd23c1a506be85ea546ea412f53d585c17293536a914b609c4e841271981519c310cac702bf8a2c666e1247f40c8f9eb6a76cf730820c657286d56b6617b1e0edbcf3f63794d1299d7055a74decd36d7f02d1b807da74d83d03c0c7216a6c80764b20eb530c5d4ee1d6773751e90bf447d68efea022646ea2bc1a4ceedc7544ebb1d3c9a9d84ec1360122bd28a9f02b15eb3e188250317b14d3f12f7d5296e659340ae5983808e648fafae9fd03aba52996c9de9da560a071f1e9ccef4717dee8aec047453ddbdac851e9b1ac84029612e6a015b29576271858c5b94d52abd0d0f04e4c636ebdc0c22a753edbd8a757db06838518ce48e0216cee7f386cff5279d506f0cd4c22c5446fcef062b29b74e8c6639ffb7191912031a198aeea491f1004c69cedfc06fcb2becdffb2240e4ef8000a8862ccec76d3e032034b690e3f09a91e581ee8b9e47ca777ea1d669e90fd78aa40c78ab03218b6c0228d78f9f38f5f13646740c4ab0793008d8d6e0d4ed800124eac7a66ad7acd22d031e13975a6d345e1d624e327bdf81828d59cbe7d0464963362195d52bef5fdbeac27b524d2173f184df12721abd4eba03911a9e5ab6d246a7f7cb03b39db2059f5a00c80853c826892390bd7d17bed9143acb3a726a803f0b5db9c03f92dc1908998a47e5eda4822ff3bb3e5272b7a67deae3feec1bb9f08798a28ff6a74a7bcec7033b082b52b0542fdeb4f0343803abb7c1582b248ae71243a75bcf54b7df8b1ebdf37f32a75413e6c9618550d5c10d029d983215f2d0842dd8a1f8dfa0eca2e4745cb3d42f954653195b72b430f253e53f326f9c1c1a6fe2cb193410779c0ef2abd3bec9142cc4c85cabed74fef6e3c474cd82913e44b2f8425b116fdb717ecdcfd8be2cf9cd30c4c35e36c965de95326194b49b8013b55f5cf894ccdd1ee87c8e1c510e00b45acba7df9d442624d488945508e294d21934995079dc09c3d6562c3de4fa2f39cc50700d13389fda0091a57b18eb3a5e1b48e27d3a2b5369eb1f789b24472edb773e31033bc186a437945b08249f11bb98882555584561fdc95cdbfb1be28d3b7aac8535f3a37149e695a00d25f270d84ac6b757cb711d19cfd72cc73d616112ed5cb661e50bc4d1fd3e0726c3bac3442415250709f478d083d0e28ef247fc93756fcb3313b7ad4ffd368a0c88f8a8beda90349de6b3ddf9c9cf830a9ed84efd71fd009bf6910a1c7bb9f5b6485475bb5a3c5dec3f8e8a60a106adb459f5fc4b9ef1d557858603bbc45bb0859539f86922b328c8967cc0914c33264c9c412324b14b20a65ad4ac759050eb91c9c8f27ee594155ce40ffcd5eaed020258b45e8dabdc28d8db776c2c37f0c2e2fff9bcfa8f7898dd1093623f3390a1f7e3307c53c0490d00f621dfd31a7e9ab7c5d41f3c7fb93bea2dc1a8d9196c53fe9278dab7e8bec47f6bdc4a26a322d66fae7d4d1400f3b00b58e5ec299f065c84bcd3e649946fe9290e5eafa828b628b7728fe18ca7f5973a5f8aa5964b075e15093d29ef2b894d9cf20a53b37c5ea4873a74fc3c68342013f821baf4c7ac1c4009786c29763609dda056439ac875611e395a2b64c3351a42820e66772a61f3c12d8d923221fd87e20662ef07bba7f37619b61d2acd0137ba408914d7ed43296690492c9dec01897d84f8e52001fd457ae5aeb317e8e15dde42d55ad192345a89d1a9bc17ec700f32d99ec6a6b5794c08b7594c51a78ffca551c29922190179180d1241bd7930d381a0790d472c2cceefe359b3f15ce161cbad2bd4a669c864b40297686a76c36601dc026e96ffd4d180fc3eaceafc591676e82cc36c8e303cef0a53afd4fe9080ec65d5d07a1afcd496a07be1847af25550c86a52b7a63a7dccb34d04be0dcb635c929ef1f3a2b4f96e488de4d5e3dfe42863d0d23f863805634699062b7f82b26f80776a9e4e26c1ab96b914e641bba182b56214b721592773bc8dab4cd787d343094b2e3422de60809c3498d573697c3aeb446cb312296f7782a2baef54641355a911d4b04ebb3ad2343dc2f7e34001a291239b19a2f68f10a40cf2b26279dc71a198558e5b85c95918008458449c2d6e5818d28367ea94a47aa1e826b62d1a688bbea189f3b49227e9535eb8739b4de6ec03126e2e384bd4c520807746bb02312b8a037d19f230a6e55fe9a5b5ad2dfbb8b0ba8ddd1ee0541b8544edde678601b3328d3df959e320e42d5268e0fddc5a4a2732bf24d8d45faae0cab760d7903a8e4f0431fd8cda000000000000000020b9dd0500000000954e781a68323811d485a54b720b8812e5fb4c8cc3602b21d0ac75237e19c5f7bbf665d9909fd8e37f75de5f9ff33e787eb62f0d2c3d75ce1d05288d10d6f2aef2173f2bdac4cdd94f73b193dbd0108f3bfad9e69612c51fcc83b12be67775ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0e9a7a17c566207044c50e4e761c0a21f45cf2ce3b007334ce11a6a7e42d8a491045b1b789c5af0ca3b9126fe678b6cbe6038c87b0915d42ae8ce26d92a57d936fdac06d728d1b73f5db8218ff44db1b6d51717b801ee98f895da44a5f159d0d18183e78b8581ecce2a4d18407dc1c00b443d4dd6333f767aad591e6fde9d72020bb3a5bc2f44ff759fb07fd9bc0c80428c0dc665d2e4073428c0b99ddd2852ee02069556267235e98ad4bf7e752f753470ed1f7bf521e39c7e2e80a4d3abacf13e0a02e0a641da467a0c52c3823b5644373ceff6a2ca8d3a02e86c6c807717f894b820fa13e75933f7acc0cc3d5e1ad962e7bdcb435593fa0a009ac404b4800cc1590219de10c27a2556fb9405bfe355839772afe466a209b54ea4c4dd57a3a9dbda87021146c55f03d4d2fb129d2f0a1eedc6e602dd24112b08bcc07a018eed148874320307eaa7052bae976055fe1514c4eb17b67788b96e2bcd6c79966914f03ce52ce20220ad845fac8a7181439cefaa206c117468888d3d8ec2883a028ca3cb84cd5e4403124772a5ee78f52c37710b687aabf586f3713b4c89fede5d74242a23ebec986f9ea26ab9b07b570a7ceca13a0ed356290ed95ca0f6e3dc939bca926eca5750b7bc24e9c0351d2581d893f034ebe9cddee31cbc902f15c0cfe13a81a61a34661a48da3befce2e9b3009409a718b00c6ac21fc285e508b00f23ebc9b9d641573719d5cf03978b2135a01cdc4d305b404a58518a3bec21840388d1eae24cd65b0fa2ab745af57b42f94d1ef784ea01d6df5a4cb10c3deaf59499f45b71f6c875568c78df98aa19f1ec61995855f43750c1f9ed0f1fcae2581e1859c7ad766bbe816b0bd07db38e40869ad7d32076c8e2ea8dc5974d0a329cf3ab88a01d26fc7e508e331aed3116ee3dae1cfcb6601b6f028c41afd1867bb9e35e564b97a71360c61adb769dc4fad2db05f670fd88cadcd7b3229e29ecf5fccc1affb6584d22b022ffa6637eca71d2a8e27ae45f05d49159ed2a0d1cefc7f40b179bbfda19d5f421ac69d2e66b335e1a3014b21e480305c12ca0aa40f4b1540e33541d2cefe1ac2a900af5c58302b3e5b98118c9ea1286e9beaa83ce51edbebb0b89b17170972f794a4214648f08e61d05f868517039a11aad7219c50ab1e382cc5cb7808347dd43400ddd0471b48112f842f119056972523c7b2fc3cae79962684e67c5b78726420f3fb27412fa4819ba492e13e361a5a0cfb87d9514105df678d0cad15733b89d4d0487da86c1874f2daffaeb223aaea94f87dfc111003063c6d5449f7c2a603132d6fc67658082a2f411210c8d81f0a6a30cd77e529ee5c0a7049dfc17e99f4acd5801678c587467a99661077c8b91e683ec9d6f2c95c0a12c3b03f6046250f5445e60d2aca537958ce59423a0db9d132b4c6268f357656501567ba8d07cfd9a075fe766dde83667a93c8eab36dbbe919f3fec0419db327ff2157fa0ca34375db91720407052900c93bd4405129ddf3e7a06f96ccb69ff3021c925f05a069a043aeac26c7dd808107a625f3d3c7fd117e623f94657c782c56f25b20e1220f81660aa61fcc7e4d474631085743dd2baff5e760948d16f25418c03fd61c7450f6225b9f9824b9a85526953d4606b3483fe2307d23ca8b9dabfdd0e08b3eb2111c8be40b6d8dfdc571b61a86a220f35f20dbaee3346edf497eb51ef9fe7161ebd832f2a9c9d9e77ea2bcd97c531b014be0cadb9ec1d43d206597f43e446b860e2853fad7efe7db0334c23421ef5109523de0cc0f9dceaa9cf397b669640de1eeb97ee15ada53c140cb6ddfba4be834c16f82126310f6e82324e6c81a948c063787a23b950cd80b5b0ca6e8bafd9db2f826a93e805bdb1d09ed36d9787502a178120baa4ab214d74128474514ecb146c8e97cb2dfdb36ede98a26a1855b6b1a03dc20e6a3ec7c267f682d6e941623e11c427e656e2a30bc6a74f1909396a8460a0b7976846305b6a54760f32d1747c82f0c658eded9222afce5a0c4f25f55d19735860d957dd07493e3caf198b4215ff770684aa15ca2b65a717c041092378e359412eb00081c84625e6eabaa44f564f406c0a113377837466c60f0e531f555ebfef161b86f9cf7e013d324e4cf748a9fcdc2d6b33da5c9b81bce8559f674b05472e8b421b63a78117c1d22e00c16f30536b1f3711df0bbeaa3774e3954d1827c9ac6fb74181e8e4e22fa0902147e3cd2aaf2ef448e391eb1bfb5ceee8ba98bce36b19b44fa9536c1973f6fff6c379aa45131d5e0e9c8dae15a0e0b841577a10dcf12f6710408e520bb8e13829dcfcd73431fbf844ec221c20d750192352811a6b71bad3fa61d3a1f53e1e5d7bdc16a8e07474e733628108dc83f94c658ad6fa5a96b84a38dc2c84c8024243f2bf7bc4cd1faa400", "6a63516a6352", 1, 985379662, 1537743641, "440b9425d2f55e4ff9098eca9a165aa76ee2e590cc3235a9d7622000c182643f"], + ["030000807082c40302c4b22d9d7bfcc7e34336128175623140cf19a6936dc01b1fea3031c365814dc4030000000352ac63ffffffff8e0355059090b7af5c0c1a29636608487a8b7935b3d302a6e9d6e186031040ff020000000700005151526353ffffffff015df9d6010000000002636a0000000058ee9165020000000000000000e0f64802000000002f1f0db9189b9d7c746115a9485979df17d59c579b93389a5d7083c6be809d4495c447bb76951ca07cbb5e07698802035267af6a29e1646b3534acdb7446aa40e9c049f36e7e42336ae77597cfb70cfdf393e70feaad474cc7fb33325101e397000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006aae08a2e5bb2f5c2e9ed651c492b254db674ad1c9522a818f2b0ba8d1b7671083c1e5ac003c20f6c72c23c96899360f175a911da7bb3e60b1ec62c4ba8c860616b82d8affa9a195ecd52decd08994fdf36ee9c6d57f3ca57d82ae3fd5b8027017d859dc6758a6077bbe8f9e65a32b45926ff21428beaeed876c02c13882218902178f82ac3134509fd230c98685843aa931068acba5a05e51bfe06c2442a08c4c02143a4ac49bad9aa8113245440c9b83e3cdf29f5ffd7ea9b6086465ca5fef6e170b00e76d30f76ee6b69a22ca9a0e81c9d26486f52d2bd7a0d7ba1da270f9b53d40e62bcd323b1ecf42cab5fa45dcc883d6c5a846eaf7e20fbbbbac1648a2ba283703260dd6277bbf11c92fa8be789d262c6c2a0a368acb42735e7b1bf82a6eafdee703016acc39278f0c273b87feb873ef27658b28070e14f1803501b23d96dcd3c36c0223bcb696fbb45195ea4451074225353d37b1e20fd565d43ddbdc3d3763975b450227cc6a776d9d75e07500beb0e32afa5bf7d1f5b8cb962c594f8296c1ec01dbae031d6ed827584a05b8a36dead324898fdc574655fad16f1ef2e2248045460593596ebc50aaab033bd66ed164f2a9f66089c257fd0a6db70a98d08bd1cb621c9579bc7d82867f652e474b551eefefb389e276c6edaa815a614b9885a25a51c93ef5cb844a24075257019e498c8a332b76228add36c5d2a1b53bd8f6fe331ec25ce73336fa13f54c3b9925b4c557581547064e66e09957aba58fdca882479d1c7fb3a63fd8710fef0f631501755cc74ebf36ca4247d4ec5e6c2c6537b2b3e379ed7e6acb8752622a3f7ad4fc5fea104a6a0ff89846264dd58a517a3e99e519348a68f179711069ca8d6f20b8a672e7a7eedf56b598aa5887b377290dfe0b961385c5cb5749e9148434c8b90b2988fc8f71a2a4bcc9557d9a8d6d666052d6c9c4ac3361736bd3531269d808e5c37b9dd487d056ed496cf0fc4e383f10606278964f4f6c277102832522596d61773ed7418dd24bbaf09807a8ae10113ace9c32735aa48f4f6bfcd29ecda44a572b74a1a6bebb5e7f964d304de9645a7ffd4f0320e5c50e0077e8b34bd6df0c13a3394ad170547661af4d9af5b4655d5d5a056ead3f9babb826ea8b4d8f3ece0cd53c1314bfe5ed085e90793f41274acbf6955259758b5a53ed4a6a300f5088656af5d7197b039dfc08d4aebbac7a4aaba5e2cd675764d98df4efcfef6a1d67e519e166bbf738c8d9f1a060859a292ecc95edcca7e014e200e752fd0a424158b6f4fa8a1a7bd94e1868aafd01381d35753693961f6113bf633c7c710278516dd0eae0eafb0a95537113f4d8e256192f53b1f78963c2f7edda8c6761c54ddd5dc0c0cf96c226331ae7d77112486a572654145ec3afdc7f3c18729f6a3ec452f19247cc7a519b47739829a105d04de5220a784838214dc56bd2c2a15081d72ac946c23e2fb1caa7d2682dba3c09e9389968679c36c091ed2b852151d61f2da0dc5727efd15dcd8db61346fc53b6cb034934069b8d4ed6c8849346a5cdd1334f0d92aa576546b90919829806fc3317f4b0131eb0c0ae8facbbeaf7d8a12be367b04925d775d4259fe07581b2579f63b4ab07201c924bb8e1d90a2ccb4be31a058d8c4e6a8cc47204bd19e8d6d7c79b38ae8935e62b6d68d7e97c5a324f4770f0453f30b281983cbf7dcd8ed4b432630a0e17f7fa051d5b05bc33ffb02a255355b96159e6349611aa5baf89f8563b68d6725fc8522ed07a449ec6be7d1672eaaaf309fe0e21b0fdb80882a993e6b6de5b00d13e97df1535dc9b54a491d183eabe45a4dd2cb1ed3e1cea05522902d257a413b9f1a98522f16a569fee7ae9e79a10643f0d927b07dc197a446a9a79e09fd196d5c755fbe9cc7ff6835d25b4611292aba9134d891b065955db45b2a5c56d8f6ab95dfa4b5e953e6817e56ca36942b73ce8fb5fa96052f96c979ab9e16da72c3ead939d711078ca2a4c4340b459296efc7ce16fb16b3e1cf1e9d80f2678337a0e81ce8426c46804c62e5696e7f16877cb821cb4e9c3e0ad2de080c319676e4d9cdf93aa14643e77ce3fe713d08990e5b76ee9a721c347f51e4d39a533d2fc54e2918561477eaa6636ce8b9b9c9ffbff673edf77b80e1af8ddaff72ed271b5833e59d24d179be1ecf71caf4fc20b2702407906ce4c903a71b71e8d24522c0c67c37b735021f8b916e9009f82ccdcd7de4f312ef4fb099f89c6c1317349f974e58987c521957b76fd07f2fcd78ed44eae8cda1393267f05b8c015d94bf503000000000000000000000000a1a66bcfb406c816b2c3e96b208db973064c6c72bdced27bc8282a7fb8aee1af0989181152aa1f2bfe317677f0e5b749022eac39af56f29ddc9e6ab5e40d4ad01541e6945372537c4e2ecf3f5f675bd7de2703f46de56c0ac2cfdf5ed5303abe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0ea75fe41b7e6fd5aba9d0859dc951c8c9759f37a8f3d618e926ac768761ea14d0afe8bdddf4e8295e08024e58d05a5137d0f46c440903bf766c54e79e1881738622a956342582eae13fdd1fff7dde4d9d6b08e0bf08002c75a051b32136402a7d2bb5d1670ed81e44c57a3c29860617c8453e2900e684bed4926ddc8e3e030306b56fdaff72b51938d557b155e14d3ef222be11f8aeb3cf3bc8435c9c3c71390222474a13b2953af3df445c12a1b2b2ae498b4bfdcbb25f4aaf8a35316250cc960a090f3cc2543eefb0976ae97da3b87786399d6b80cfdd3e6edc3128072c6888c16f6cf36366b90da85391cb6a8a7426483cf4928a013fd63dda320c75370f4108030f42083421e4185bb8631e93c758d58cb116d6fb8fe483924a2464ad0a1479d70228c7746739cbe497100ae3a22dd0ad1061b40a08307193c9009662aa4d05f4e5020edddca6533fb9b89c06555b02d4998c078e6eeba06eb0d78d4716c3869418e00211c60ef163ab542f3cb59637db3505b2112dce7b6b215c9a10729c2846a1d5a103019334aebb4bff1bc0d924f3b84eded8266b4d45e24f1419fe648d0d35f088518e950c818d9f2634bd831f58de95a0b1e1969878427601c79bf929be2c6cc57c71fa6127057c52166ed640b835610707e75dc3d0e193dd6907bc79cc3f3c30e825cc8b1bdae80ed4d5a67a3830cf455348198e924593a55b3807576730a868106ffdca51711eb40b3d6f7d2eb556e3b6803b2bf5cbbb4fa8d64d13e13b44905f217d35a34f65e90591e1b60bb3043bd8b44c33bc954462053e0c0d3b4f81bedaa6488a78850d9858319fb9e043bd8d3bbbcda1a448ae09d01762fd06db2303f02f6f9fdc77fa9da15bbc7e1cdf4decc66cdc6091fdbcf2559717cff7910ac3ac39734efd2ff2a1c22cb46652558ec45cc11632dcf3147c16aaef193ee6a31ba42fe1c8863560158c5786029b1e600976f70a9f9dc4e90023f204ce3afa68c8af6d6cd634cad0f30695322588e98ae92ebece09c071d42d0a667c8949c5591ab0f5c1381a98201885b21a627fa59a601751e52efb6aa9ab86026002f9e0f0346f322057bdde46e3568aa859af36a267508f40c950f3923e1f5abcae8be06ee86836a95fff156563c261a6cde6afc8caef424801ed53f654e2800634c08c87ff7d894762bffa2f770065adf4b9f69be5c0b569bdf6b9ccf41cf3828218e7878b1adff4da9f1536c61c0244fbf4d55c267dc54711d0b0334984dbde69424172b66735ed33901c0aae93063c28971b61fed25b99f492a10c95364bcc487d65b919430137de23ce0f5c4f4988a4be1a92216126811b3b88d37c5d2b2c0b765c9f6dcef1e75ea430413050b7d80a3de6bdde2b272ca580a9c254811ef3ecf5a63c2f713c2a499c77af988c87bab52eb4b5e8f463a62f1dcff07d70b34404ea42f5d6903c958300d1691e4168b0dc37e6dc4a6142c793804675a49aa9c8d817c5e72f6b49d2f8789b44cf375e6a99555301a05d48a6e01c9bfa9105d6737c3e8472c9c83666b66e709568e94a9516a6af22d37a183a74ebef840aa5f84f9b21d5559835c2e43d3128956a6906709f3578c163013e6174942872967d4fdfeba68cf3dc6445aad2f3fe56915e01ef108271e9a52953b31e51e32d7ae448d52258b4a362412e99e7a61b7d24710b2ac8eff8fdd150263f5f573cbf23d834aa4acd41e083e6d19639e2895ba0efdd8389e4d501fea5cf4f292dd4640cd23ea10205bc3cc7a364908271c084d7ff3b968d65e00b0215aa32268279c8c7947ff5b3ab876766148007e73871b1089b6797263bd507f35984f63f645301aa075ae6fb24f68e936aa6e622adf4eeb913362f20bb40850fa4da368d0b0d0fbc342aa7260542c3aac164acddd35ba58adc78606b86ac62af47390ccf72afff8256e19436a02971c99fe154e553176611f691cc485fd7ba392adadfec693325f3036c78d1a7713d4f35aefbb76adc4eabfc3eae4441aa4afa80579050749076b9cbc1f3b3045111c6c427a5da8e641fe7b12c45417c401c137db301ce5e4daa1d1e86ab32c280e86f3f76b972a1dcc85c7fb436b629f540b6f94728e1c5124a61e18a152a18b2077ccbde4b339672c98f7ebc2f04099691babb8822d35fe199c7c0c86e68bad55ed9b3e1cfefdb0b4bd42222d54f0c88a8606a4eb55011f584e65f5429e02631b056164df81944f426f7dff17c2dd63dedfbf21fde9ec121426976b7166822c2d9fd596dc9c2529630e5cf89c54f2112104653c2e08cccf8b13e50309b16f03973d36b3f71262ed33e89ed327694e67eb6e90be481397ab8e2cf50944cd37f0b43600e2148d28df1e732dfab8b7e69eae44c1998744591215c7c65846312ae535c0e7de6d96785342aaf005431fd01a132b79e3808", "636a52", 0, 1242965623, 1537743641, "81ceb9e293e6e50c6115468561e998d2d2099d2d8ea04db958338b7a6325935e"], + ["6b239674027cbc7881d5f39dc64bab67f999a51f21dd81bbf36db13fbc55baf9638438727a020000000263ac0ba4946a1c90fd2b0d21f729614248a0608028ff71407ce9bb6ad5945d109e8bde6c8ed601000000080053005363520052a7a9d6250432c6b50500000000016a0d25d2050000000006535351636a6a4c87be04000000000463005252963b240000000000026a53e82519f40200000000000000008be1a30500000000872e966ff2028ce2202a99859bb77b6b84862850baf046eb082575dbb9592804809c9a71a26bba6f5bf13872c6d73056f999e7004db11e1443f536676db04c24da6395e3fa9174d2f98ed6e29fa9e1a1de23b6acabeed67aaa16e87eabc2671100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2ba3c1939b0afc86b5f3b1e91ca8d5994219ecdf04b4ec54f3876bafddbb42ed1788fbeb713e5faea9b57a131a1ce3284b381fcb2ae67cab9a03dbfe981d4b240793e3428b1d269fa02b427c542de79b25f6ff503e1612fe03cdd2806156574e3f5a638daf19f2fe2f2115f979124da5b8895d4fbce561ffdce56eecc9b794f0300d4071aa607a9c020db7b12502054b8fe218a8ab8c9ebc07380b9885d12eb5f02015663d9aa204698acf725a2e90c0b54821bc65261f38414f2be46692d83eba30b00905b5b5c48aaef9709751fcc05a8754d79f28c2e347284de93c612d4c12c2141963db44ce7828dc3ecb57435c12d21ce20c3e6c53b0ff4955ad707c0816074031b45fa8fcc1a8085a755be04f2472edffdf93179875647d7bcc075c2e24a7688030bc75bbbf136a261797dbc08bdb27a701705ca85ca12fb3c0d140e177951ff9703003ca76a93e18996c614b095178d2efbec96ab8ef20d0b221981c79f479e09c80208ac11b7c958dd2210e6e4634f8da701294a808c3239d79ff15e1a0bc5e5f9ab022833538f6dfeb732ca8cecee1936eb75e21a03c2f41c5e508cd79fc1b047404aa8df28538f148ce8b6889d45d677b0c4a707e326660f70fd88d7ba07b9a8f7f9fd331c4156d6b06d689a1879a88c4f4c4a8338d1805ad10cb6bb63c568b39582ddeebd198a71a20f1958d879c168472fa0c1eb6fe790162e5846ec652cca3325d8ba54a1d54652d1a34df7cf386e1bc6cd606e63645fa6cf41f1c74cc6793feb1b3976c3cbc20684233495291f1de18d1c3724dbfe5627694975c4c29e688823cb34382e7d1edd1becfcb396b1c15b203c08b44376a8927b0c0c638a33a5b2ee1f423439c07bbd4af019f31e81316858bf43174cda15237529f93e6db35dee36f67f1f5bc6848b23f58afd12d1dace5769663560863003db30b64c83addbbc87c02e889c6a013366a970dbd812c255f27df4f97b0855862a51753e3201983a46111c8e5054f02321856380b819173901acf24ffdd96e5c9bb31f7354264e045310558282b9a95043e100371a0fd879e3fb65eb11c1ee92b38e4b04773ffdb3395d89866229e69ff42192c8b982ebaa4ef1fed6234ccc6438f56606fe2d0fb04b40e6deaa58b79d2534e167db7d37be57410899dfee4eea26398ec87f937dd7d09d439a02168f60e1f15934ded2e846672c53cfe28de1e95d0214f1be0b6b79429dcc5200520f4b9bab2666d63d513ec639507daeabcace1fc917e669a377f5c237a07cc045d4e8eba8f7bfb769b47ec7ef20d00ab4f9d39556e439923f7d85a8ef62a6117a682149edef3daf666fca157c3e748b4a65cce3b068b23aec9dbe690f99b9bb6658d8ec4ad586cb280497ed9f2a6ba07204f75f99f3436a2a963939938e89e8d51f9748e85c37709f6b4d634ebdbe062d0c622af3f06ba8a53d9c851faf5530d2ce65682be2b4bdf2d5a6c2300712635bc8880dd4ec69972f007eac104024b726965407333718b8a6962eae0616e05f1d14d9610b59275432614d16bc10c57b4bf990b879805abf0581652a9f3a212057fbbf380e62ff242854dfa39db98bb155bd5d10cccdac69af84644771778aec98ae669a33dee6d282e6299b9a30d61688a8a863b045e3936e44f604ac6a29c845ba6bb2a301d9bb5cd9e821ef2d461dcc7571cb92abae882f960c6d56f48d35749e1e3bbb0c0bf9c0ca512ab70822709d9bf6138c9ae1fac364c12d004b3987ff55eff75bdaa9acb9b7cc0ee9affeb4125d579b8b49abfe23de8ecce52629e7b8c825e878ae10fb8a85c07c9e58c0c37626862822c0531323a10afe3e25cc8997eabc3101f36af178896d4a973b4fd757b64bf405e42fe61f0b5587fb15c753280f26ad6b833e82f2b9933dcbf1c3c9fe7f4e559d66d64029c0fddb3cb3a5d6e04b3c31a13d3a61cb3d61315eaeb2edbf64880d99fdce1b9dfecc9f422241aa109698033cf2922423fea9ad836d7a9aec11548bb51da7b593e1348e78aca7d7bc8c958f7b529efb2d63ff38b02fc04e79eb6fec00844d590387ca6e3ed5d5c4d58dd90bc22d9cff97da8563e03832dbe2c4fbcd1fecf17022ce38eb2704ab4fcf2c7b5409bd9486febb9e27150c5f451fd4c8c12887e1b3563dfedfb4d474985df51c2cd235f74f36a991e5cee148963c8e167a3dc5836c8a3e87f127c28ee5bd671551aeb8659392f3442e72b17c119385ad8f5fe636f821e71eb0f51c4e1b7d2579fed8d9c46cfcdb7a739dc3c3efe476a98fa7e1b2ac4ba50946d19cb33472000000000000000000000000005ff78a067a304153bad4ce7a0336e0506ad5cc80625927395434ec62204335ac96add6d5c752a1babf21a14a3ee1dc9dca67fd231187efea4e3871e90385f19119eaf2eab07e58d89607233e3b30bf7dc3993ab771fd596d6d231d05d9bb48a800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000db9f674c153df22f18d9b58fa520cbd3c586fde2e7750c8eb06b3d5fa57bad7e7d39d7ba93b30c855e664c61d6759bf3e8253c6a79ea4d07bf10f51f4fb47e4790937b1858a9a324b4bf1230f942a244c112df554adf3c582eba0e2a4ab371ff9f5b9ca46d59e679acf934711dfdac51a0cc3dd8baab07ae7e819f182a3c02750317add8da1314b028a91242dbde64957efc4add8a44167e1d68524698d2188db00326720692ecbc862c92f48027aae113987a00e7855fef87926bdb95ed4b4642e60a061fd58cbbae927c823f7843027a37b4f7d18607ae160f2a5c45186faa5086e3f43ddac4634fbc375f995005d91c4f0412bc4d0a555d3590d6416f92251a6d6f03142e943cc89a491dac8f502abf31f442d9d68f3273709170f1bec2ed37c3fdf003054284b67207312a90b0cfe45dc1ccc85325399376d200a8a61db9d73d0b22d50305c7368fecbee4125064ae6fa5d316ac4e5037121646acdc8ef66b014705aeaa031e44ffa8c476c9f105eb0b4197ca6cd1684b01ae0bfea75c3f5de2e226055b0e0320afec1d0548aba2b34cdfd665ca437ff1646591690f56a41188ce2e965e202f521fadf629173b73997a790afff1eb64047bce569c93c1df77150590913d13cace388cc19d4932e22650ef863183cb2876b4cc801a9ad68c7499e8ad519f701c10d1041c0970425ccd4c3ea9f39b7da20eaf80a7bf14f7e6a1f381d4baf2078019b8a58efa4432396891f16dcabd6dac4fd9893c1bd2693fec00e2ccc5d8660678d40da61183b8ef448cccfae9f81df4e4c6b2b7ebfc51ed5fc8031685ee821d88dd74b4188f137c3d0b41571770934c6bc6611b871288c1256feedc465387f43dc85b38bc076200a6670ee94e8705e2f28b6315785dae3dc9e2b4e473ca5c59b5a7d72c946f0c6183a29c537425592f6e056cfd49b9d3ecac4d7ff40472c46576b9f22d563aaaf78496467e62bc0761af55bc55c6b5cc4bb4c8b8bd200b47ea1181ddbf3b73c24befda2c2b435ccf1802fee70f03741daf082d00f0a7bfa83e342fc39210ffb75055dfce09e6d8def3e4e8ec42892f1d389120719dd63885ece357f2ad2cff4d14f7386ff8851b1d7b0e2c0d17ac125dfb01a45a53a5e60823362a1ef97cdc5420b8755d0645f22fb2b42285b9bdd6a470a827132d89c6c6411fc3975022008ed3a4628b379fc8cc08573ca71469e980d84636718e9a914220962604a42ce0f87d49768252a271fbe553f8a7d3317bc014d9034a70575fced408743ea5e63ffb24788678770088f3e0f9e31d2d44179339db4a0e7cd5a6468f6a1cd46b9951cdd87536675a054cf3d37d8db6cadadb62cd036c614618d21998f0aea32bb5ab7c2fb59737da545c0bc25f89dbdd3537ba0527f039a5a0bee53fac3dbdf86e46566d65c7a60cad7a12b3ede0b2fb74e252604de8cc95ec836cc1def8c2121d6a9499a8ced21b3d9a078da2e3d71d281b06f15c6b7f136f2dbaa6ebe86dfa2e55af4161c97fcf47a0109b92b3a622b917722ad8341c5035b3e450eec9877782c2a82aff3a2976a85c34a4eef22d2e821bbb2ed3c0db701f309ff9104319e430200686f75d84a5bd40f6d63a8c2a93da098c135730f6abb8b6a0025f8aa608d9acb08312452a0e1b07746a495bdb1587bf377f8efb9b872ff1ffe1b072de1b9b76d4300760efe1543bb016fc20566afde5231d15390c5e2aa7e6f1fd7cae2b04f5870aecb0ab2c585019a646d39eedc8cd4c0bf87286757e104c55e5a1ad4dc698fedebe58bbb5899ffeb4f4251c3824b8dfc54e9faa5a65d58db43d2da2ce819b65508cf989a97fec99615a9e2d73d498af5dc3e8515c5982e94d7f16d7d95bd90c1a5886cfa92161e84e2fe87a3b4be6d2b52d29a4f15e6740f9529f997ea3bdf26a1a97812c4fa3e7e7131d1ce967fa7b4c131646d17c0ea46ba441353980462f63783a26c83b7cbd594124d066b1d6e699769da6f8dbb27b988c66b51edc7efe43252deb89a86cabddcfde08feb23eaac9f5ac0d97ca507d2f79c03a651e6c24b0ae44eb172dcef26877e2e88ccbdc333d913ddb355e9ace1ded33f30c5c56d3ba965ddd8f997bd7b2c784f51add3f4ccbf3131c8d42b8ee0f1a5b7d19b510d5810871bf9ccf0e94c10c90ea6cbd95b1fb34c3d5501e7e6e32c5a4ed6b75aa7d6893464bb05b39a1ed6afe3fcf411d383f9e186f7ddeaa3f4c96274eb7a68957db4c481f85d1a8e7f40dc072709c852e57ee1c1a8cb4929c270bb3e28d7a6c4a776e1a4ad53a66630fb9945f8f42dc42cc12528be8284a8cc315cfb2401810ae11cac09ab72c1d0dbfc87a74bb28f41007727c45a2126be1445658dd78589b9f5a6d23fdf1e7b2b57fc36532068ed9f7f802c5b354d3fd8b4493b1992891ebfb985748f16d8f63d2e91903", "6a00", 1, -871106393, 1537743641, "8c0fe6211f15c6ca908661b56b24a6da6ebe081199fa597b5a630fdd997afb4a"], + ["030000807082c403019ea1856f2bccc1f8954b97e0f4cc1918d451214988b172153ad966df831904c60200000001acffffffff0275063902000000000453535151bf50e50300000000090052ac5151655352536cf51c1f4d5daa4700", "51006aac", 0, -862178087, 0, "5e9e9af5d85e2217ed2af9b0fce56d4e6cc2bf4b7a1cbdfe81517a96f7b8cdb7"], + ["10ed837801072e77252099d6375322ece913552eb1820401350c90bbe00249dab61e7fc25e0000000000ffffffff01f006690100000000086a5151650052000000000000029bf95d01000000000000000000000000142d3fcfc7f157e83c225e4c45d9ebabd521412415e14373c2c5c461d03baef34f4c54ab2387fd4e83131b142f1dd247a7d68f05d54b49ba46028c1ba364d140adfdd1c8c320b40436baeb24a1c4c98d58fa0925be017d7178fd2f798c53d24b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae30b9f2d62e927f2667f64b75d0f75500e6b7b42326f71f91a6c04907707a2469618a4ff4f7e38a3dc8a886ac5ec7278f08a46f54bd04e63b7683943aa2819cd214418489a827be6e4de4c99a7579f903e6dcb326005e0abd446b6e80f171125d9c59be5193cb5bbfe936807d59ed3c0e2f09b98aedaca8f0103164dfad2b4f0301881d8ceb5979a5376b659230157437898bd8b550e3ba977f1c25086c3a72e3031d3d125a8b7653ba124061cc4889d964a2f134b8d018aa8a0959bb93605284360a01b3596e6c47bd47361ff86ecaa02b5c5987d8700de3ad48568ce407c1536ca324ba92e30ea6da6c38f4d9a1abce0a11ea84f8f6d5de8bda94e357a2d5c5d924021063850f5376d4b9efae50a00d1987e698d518b967ad499d74d0a707c0e0c9d50201449e160b0fcbb4867e9beac93a533bf94ae41158ec31b193598e3b006652740201c097e2c4dcef700437d44d2e4e45071e770a29978e2ceecd5157147f3b0b22021073fbca92e8f440d6b1afa643a41880e21e3c9fb71137df2f857464146aaf1c0328ba20adfa27fa9b7cd58f7d14078471989296679ac14f43a60d027f36e5096f3f50c24e2058af933709c04877747e3a11c68367895ab710f2196f4ba3de3334864a7581dc0478739811b4fd586efbabb53df82b6f843c1242f09cc3c1df4fa39a4d9e34a731a130b5f0e1f8046fb217a410481697afe37b53d4c5afcd165cb7401925b2bb502187333509252f0a6ea99da665832a3975d3824f3f817dd419b9bcd1b8f3b8a8fde2544ebabcaf20cba5a8c9ebfe6848c580da2d0f37e005607307e10bf0fd731a3bac726782e7aa4ad3956d5a37ea2bb8806a8309e212b0bc346cf56cae99b672bdda8e03eb3f5e53db63129ab9a95689ee946e8759105088c5acb6d3a3f39acd45a105b861475de6d22a66985b6438c49610343e48a2acf48b581f3bba82a381059c4e10e3a012265b980e15a22e944f075cc0e2fd76cbe53be05c35b0f1e56bee5d786e419832173f107b0bd4890e962583928950990761c1863febb50207c224214ae047561b30982e6b2b909ce5854d4a842d3c62fda0779cf491846a8118c56ed05a7fd421161cc3e74aab040a6b6241695b801b86ac5a31b6ab937a8c5c4ef00f97869ed6f4d3c1339aeebdb5a5e2b8aa1912652485e0bff148f711565398447f2120e2fcc6bb64dd69f87a6d0f1c44ccf6ba4703acc4df0ba701a2f3f727e7762aeec5d2b0ab7f4e1271cd98fbc69794df9178d666b113d94c56c4d788bdd324e04fddec3a94b864a542d14157b03dbe652af07acbea6476b53d2d16300c05a5d18d6cc345787262539917fc59943ffc5e364157555a2b9ef7953447cd389b2da1fb37423b8e70eb55bc99e0f7b5a8e6d4098cbf550767caf5a182033b10e4538c71878b70696a254805d4f4569876dfb9ff312e5d01455e5f14f5571b4b389bad84ed813dbb1bab8cfc8dcef48debb0fb8a01e7be281f0910a1064486aa68a34b2833111cfe5e01e08702f0962f5c0bdae55f481a2298f9184363875a6a7873ae7ea959915a9d6f42d105f3ada34538913123f050a30cfc77aa82a4175c1a2d89f6bc065bc4406aa238407b8186e6794282148679a90bff5015746046a1a88533c74b46a925912b6fc183dfdd7af04d596b6e6379f7e7bcb74a3db8842025b5b5547caeef6da2179b34c997c9ec86f3b02909aabbef3e7b16e580d6d3c26109213687cbb8d0f8531dbd6f40aeff5c14a5aeccca530714d6af9df10ad82ae03d91db7f36f0d0a3c5814ea71eee1accc3a5a5f5848a9645a41c9ac9b5f055e5186420734c602710a2f5c59dd251c9610a1d68704d82b8347fecfea04d1f9c619eda8b57922e2a1326f0b0ae4d5187a111a550f7ece5384e1d2a3605f7c2e1f0c4b91c9e185d58353df0d125a95eeb83f54f89dab3910f84bb1124a997eb727db6efa52c25fe746c828bf80464a3b74176cc9a6940ebed09e2fac807765d92d58c66cb8c8f0fb7eb5c0c056d548ffe608bd6ae28b27d4283de7900d29a5ad293606c28c7e3152e785c909dc11dd380ea858648a14166d34e57a60cba2d7fb21918803ab3a6a0ab569bb88a30c477f91fb08a3a2b18941fbe7c225413c0fbb10fcc713f4835469c0c330d0324ac77bdd326c2509d84dfa184a4def649ab387c90752d088d69aafff86a28b459c1d9dd38fb2846f3e7987bcf48c8e95e9f428d9521316e54a954a4363a1adc3970299713710a2588663101787a201264a767040e7f0a3e62969f13891f788d720500000000000000000000000013f417b2f577b8db2b67b9d016f6e1df64c11eb554f22ac1fe4b030f9345ee0f4f5c82fb2fca2080524532f6768bbc9816012863214c3c4d9994c973502cf920f23639e582a52a17a62770faaa3d7755b79abe131296d711ef017f2c21650c580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005052837d5b996d731a8739191ed674a51c8341e0b2b14386800282f7365d88473652662f9e9f20e055e8a7cca65716ecaebb064fc0dabb8281a4364e533ec80228a490c6c7c9736feaa4dc88934eb517035136b72bf2a20abb5bdf3f11fc72477108a30ba465f95da3055adbd7536f3886ac5f09b50f9f9d3a1ec7857f77b8a032820d9a9867d8e87b5d4e9c7039c30e4a712239c81727d90aea10850a9db2612032becc40b65a2d3941a927e4845b3d1580efcb42d92f3205a05e34dee198a915c0b05dfb763319f27a9218ccb77e67480cab8d08ef8a2fb211ad9a153790aed8c94ae60c12563eeeaba8c17fc2e41f0de2b7c70371688f888d807396bc46f41c5d10215b20cdd23f1b1d407768e784d88bcc0c9f4361dc75ce896288b79115fca54f3031b68a5b80a0849772a607dfb6325fd9276466153d9618923916a393f1e97fbee0229bdaf8a660e45a373475aea4480e01168ff4ea7636b4275c5d302000e20b1b8020644822d05df6d8fac01d0f22f68f704666a006378c991237c0ca358f2e748080308a5019dfe26964aa93838c8cfe60d1097993d30f583c32529d2ad3ce61d78034fac24327d064a9b89d6f60f7e1d08a49efc1d89de0c883baf82ccc80188f5f47a6e3d662cfa4e192723d4b10e6140fecfb50e0b98f97f9abebd279c2cf10ff16bc917e40bae6bc9ab553465ae8827059b24601bc9a3b3e39da9991bbbb47cb14830d897401f859166c307580ea219f80ec848e605c5fd68c3e780f682a8e8842772d9f50c51869136f0f0cf475df035c8ceff7576933ae0088f8413e0f032b070080628088bf8d90e4f57173c3449f9c5c812bba4b5ae689e2f085d22689fcf3fa493f84adb623b064729b5a6176578bb0ddb1f5bce0637107a46264e554677c88799d76396eca4583629dfbfa134acc5076aac8e7fb29731705079229974d175fc0857ab173e1aa4dbe91925a2850ba84fc2b601f66aa2253a8004c1f267dc2bc9d58c07d5b4e0534e7a8dccbc15adc85f462ff34ec9178cef9d3b5b72585f6fb579cc556b8d61b4a90e1cf4c96c69fcf2806d95e4e33eeb204065ebf2a26e629501ef74f70cf964a73904c19f8a4ee892759311458a182a044d0261eba02dbc6ff99820d9f741eb2ab5ceb496f05130d95b93405dc8d4edeba622f6e8c9e55cc494455aa2dfe7dbb60f4094fd89de1b2a2fb269607e947f557cc8ef9a457e0cde19c33f075a3b27d492c22976be22c98bde45e1179fb494f11f72b97ed3bf96f21ef55830c62eff1654ef346167f7f3e34e8768bf91522808726d2ab0b31ee905f24ca1d9568ff34952409dbc9842a238378f4c8f6ad83bc10e1ae9112c15a5f25c24d1d8e734a4595179bd3593e57950995aa570dc8740dd42b16f82cb20e4472f15b593fd34d9b88d7634b3d0beebfb7b4dd0a0c33095c5d6a28d00a31dbae4497de8faab332c49aeb8c09b9bedfb87957ec15fa04e364f8b051c0c6f04ce0660db7a453d07b454fec4b6ee4acb981eea7d7cefe56b005358d53d85411121bb74aeab61796da4b65bb6678c303f9fd86d9b977887515ec614693a2110afd61ecfda80966f4ecc797de517c51b05bd334b28b04e2acf72a583c2bafe1292172fbbcfcc4e85c6836122d4e2e8453afb6e958d6c5cb3eea6a7b0184ba7adecb2f43004e989fa4aee43ca5addfaa051875ed61f52a0d36fc36dfe8d07aa5d21e0aa4b97d5e6740726ed7e5e84217c7ecd85f3709f5bc4b0e9405359250d6ab9639a4d921e17de37d6b863bddb4e24f8713099f49506653a8db4f1509a5d90388c518159451e87889744707d925220a57f5b9d879ac01d701c4e675a12732596b0ca8199eb874022aed2248ae9ef980784d8fa3d54d71e343b90b8fbcdaf80b031bff1af9562973fff2641d900420d9d79f948d19e62b0aa74d61928c15fdf76e5625fb6b06f9fe4ba57b72a4e49c85a25ee1f2b77e374c2230af3273ab75f710f8763fe464ca85cb8aeeaba12d0d957fcb11414b0fad6d7be92e8059fb7d785e88b7b72bc13ec54151bcfd6d59b87de6fe8ff40cf7d9fecd440491c31fe7e8ad0ce1af60c2c1a596085aac3e184d4edd7ad1da93ac503dd9580832a3666b50d80a8e2b59f089dcbb4f500475bf5373308c4f0e8262e6aff4318b76ed7ab612f4ee3538670c61ff228cf54a1df2a54acd137953e4b9a1e15309b288dfa15a2eb57dfb936d3d9414b9943e736f5b8bf8b4a4622f95189b2234f76b79711108c6d0aff1319a77f8e8a2599e97c11a3bd7360e2f05a072222dcf45886409a318c087b5cf7fc97333035f7909d46edc64bdd6f7ed8c35f6a18cef3c4e0d6ccc5fc51ccc0e68b8701757ba7486b6f18e47b9dbd5e78f2b4330d6c51c0c325be7e8ec1f21308d4c8a83ef79700db837335399afd04", "6a6a636363acac65", 0, 938823340, 0, "23bcafedf35e56f24cb2a742d6fecb509a2090c1e8b6eb30db1f20de7fd34edb"], + ["26380d7603d6934ed25248f177424fbd67e5075f7601a88be0add2c83554163b0a56cda2710100000002ac6affffffffd157ee44561d1368556a206b3020f8cc940b2a0485f464cb47eac95656663f610300000003536a65ecd586da2f0e935bd54967c7e11ab93dbec44a995a7a522ec8a377ef34614318aeb74712010000000963ac52525363ac53526eb5855e0242750c0200000000066a5365ac536aaecd0b020000000005ac636a00536962452903bac90a040000000000000000000000003644af77c16da9ad64f12222d829d62c318d841d8c64d9bfb531cf6594ba7bee515c7fb7feb93449ac2b0345c7c2f84f7d23048d4a8b670e0614bd6a6fcad6c713b0c9100d502adc98dd0fe9561cedb1bc34c824601d1c0cc3aabc73f384d0d9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005575b67904c9a3da0d0b74c91253480ef0c420f87be59f5359fa87408e451fa7780ad043da81c01e8880f432fb696f3225d7adb32284ec2a22fb0eecabca8112a056f05e9da9c7c15fe6d5757ab8e4039f4dbcbef0e106c8b40e9a4dcfed23ef863614413271b1ef8ac0e732b4fdca748312f49cd0109358f5fb0f7c41a678f2030efd57c86ec1d04db759684b73a0623d078d9c8893a99fdf0af5e4febcde335d020f998ef0ae852a11addc6d76b8ef4fe788014f9051ba9d187ed39df8ff32fa0d0a08bf764384d56be465839f83e4fba62c3bb770ce1bdd13e0da5337385e50ca3034f4e3e932aa37ac756ff963a08a3c7bc32100f39eecde3d71c164b251898ab2032a93787b841d672e5bf22cf0f9387291a839fde713e4a9daaa3dbbe9dec54940032bba8a5de1804a1a30d76e95a364c090a186c726f35f6c7e9daac304d07493570326e5164e50a5ea8e0c5af409764a86fb4c0a2c047fde3aa890571835ed73a1e2021efa58eb40c5e97f28c50e25edd6f8cb0bcc797111070f9e93fc499b88837519021bddce9b4c693f429792162fb4929df332e4da861eaafae863bb1b16e95597a9fcd7e1a6fd4d05fe76168725787392bd9b20e214054b6cc6e7bd6ffcf67f68ceffd46ad1c4ef251522f4f2bff486857aa784eeed44015a8efddffa2850a935c90e1219f3e3215a2ac8f372ff67d486420d6dc697a59b7b3d4bb758df87b1afed4d6146da20dae9b6bf59071c8941a9d64c6d77e349c1d44103bbec1b69e3da350d8371a7b3aa7aacd671ac5763d502b10e745f9c6a714b2917c97a45f98d55952b67379338cf3d283506f966c7ce4278bbc6b5a88bf13897c17ab2d399b3b5602c2cd84184ede1002bc3d77d788eaadd04e7226ef4da7902c9ebde63e44a8e36235889e196404a1f4d32c579ec43e53f86b4ed7f0fc649e3470b93805dbef7097ab278ceacd4e656ea04504265ef801fd8096dbf68066b997e7ef482f614d135407eac4d59689c438995d92440a3878f8e7dc1e399c484dc1d8fad1cf98a08c37be30c6f6cd4baf4b68682aef227bb364e7a9fc0e280f0d048e1112b4d4a2a7f57767a06cab49316452e24e0ac4b9502d1d1bf1322d8ca48fecc1bf615413ed74266a86470e53901385553470556adf5292f4d2224a0c0301a9b9d6cdee1f18df20730aee2275c3f055a8c02635500c7f9a11d7e8fdd90f17b1e24d9ecc8a4480043409b9a18a2a5eb78419c499d05e2ce8fb998cb17b2655b8892eb438c62a940bd60bea41cff4c235969bf581bec6f11700d726a19977679d6f001b3dbf8516a16080a60deffca2f8eaa901136679cf0b8e8f6b04ba4e6ee9fbad2303057462fac701a34aaf700aa325aca3b4e99e3f33d23dbdfb9ccefbd470300dc51475d20d0136a5f03a13348612309082deaf8542b98248171e1b701424bfeb8d59a9b0c55215aec70c503d338e2844d3be225d89294c9fdd315c9c59ff881a8450929eb8fedaade0e5aec2c80dce69216479df62ce49b8e18dad2c014d9ecbad2a91b986e365866771b5fad53eb8513b0f5cb57c8338d317c7863f3158cef034b18e14eddb397f7a60f2323cc6eee6c9a6dd5d91005a65e8fddf06c32c84c9cf1f05253564aa4abc9515c5ead4921e42d651b8bb5ed00bc4cd4bb39cb3b5e93bd2c5df25853d4c445d6d0631edf3965c6a8eac888a311bc8c6c2e05a66e8a4f6e5e577054706fef9da69712031aea7dcca218fea483131363a091a3ff55ee805b30a016e4b293a1821b88ecec8779990eb0194adfa8ef6bb472a1b94a0f2ee8679d70b8c60768670c507781035c816f024edeb8ae171ad7b4e7a04be3b81027699b79140bbe9e4cd4fb3ca2f4f724ac666823ff76c5276d349f577c614b1635a071ecebbf0194129785c992232b109d78365e879e7a88932672dde262c3138ad07136658af863152f7e8a0aaf91f09a3138085c88c6820f7e713253468a600cf3004ccc146a62322bad572c96fe33f56a22d59f068f0a16639387482376178f1b0b1e240799a2fe5e853b129ac720bab1e58862fb5880b31ac260c660894b443077aa3292ed91c83e3e45cba40f97799a4c81cbf8388f2bc3c16f89a5c76cd26f3ab9e617e34223b97b16f8f084730920f705bd3e50a18697c1bd7e9f28aead2fe739a8654ab8ccd452a8f84b2f81303fbe3167f6f74e9e78d2c2f3cfef1cbc729156597d1c05ae43c07aa8cab8b90a9760dd3d621a9f839b8a298d0d9b910af9879073ee5450a6e2515d3cbcbca23a3a4633801e0ca82a040000000000000000000000002e6643a26f7aa614df5b626e664795576e4d3d77d6a540f1efa7a430889e594cc16115946350f37305900d1aed2153452d6ca6c9e1c2959c17a2197739123af3a05847fb17a3fc1f1cab89cafe4259524f71014f7cf34b87815d991ec8688c8c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d9f533231d0065ce3b4cece870a1db6f3d72cbc7a96bd18898c4ea617a7ef5f020ae1ef170457b57dd1f46fc7d741e187af2d65e3ef1df5ced214fe87dde352c3bcb20f42993a667be157531a7efc276da11a9aba804db7c7e29bc8cde512c13c7e9f296af639c10ab363f0e99fd8781ad0e359e3bc88a7750dc59658a52ce55032d2364b463b187f09f4020aea6239132573b5eaecaed24c91494526cb51f3c420308d729d2b7d5d901d19fce7725829872ed0dbab4f45d3556308c02f4c7de6eca0b037dcde2b79ef6a70f123f656b2c923941f0b7b31849ba00a0fe5491e564507d8e2db008301785e6821549bc225bbeeb8afc80f1653cfcea0e4ae2df0fa421a70229e5eeca6308005fa54730e5c7dfbb00c52ab51fe465ca878ac9d5cb0c07daec0303c8b76223ed86b8531dcfa15cb26307b00d6dbcf8eb5c1cc430f3d436ec53b9021e0201164713c215f804aa1aea879a2c2f8f020c20f3eef118960b22c531cb9103126164e49ef57a5d75b653492661a294467c46dcbb6d5a07515bcf73071d1d0f030f6351cdf0805d8194b8c108cdbadce1606df97122b1bc5c4279bbd31219f1b10ce5446c9fdc64f5d6d564c6f889728bd8e7b580709fc81550052bafef353e58837df1ce47d595eab6376aa1ae85d5e78bfb98a7ac4d19e556bac31a0f3611a458d77eedc487ccc7a0ae3913d8a2cf669b587541e3eb797dc634b8304ee3a66265afa39687b9256743d233287cf1ec4cf5938d6fe15301b9ec150da0995f8a2aa8909e31643acd3963eb324c7a6402962cd3b658026d9de1e477505f3f5bbf63423b67c824a8d25d4152d64c3e4e1d3431338d7e7a99096e7e2639697de8bd1fccda9fcdfeda2be065683bd2901b0dccc1957474565af94a8a44766e0470239de14cff54906e24e9f5daec30f4407a22443b87b5fecce9b5954f1d645014a13f6600fe290c299c0478a38bf59b6244e5f2a79fcbc078146374e0a2f6d3fc88df2b612d0f62ef8efe5a0b234d84c885b73400765a61dc74f242b43f6c9f54db7b1ad36f1c1eebdccf4de2eba674cda0eb9daf92abb98582ebc3ec82a2825e0443d8b5dd8e5e58f68df71808410fc1f5516829bb3be27fdfcc0aadda2794a78bd38f3f2f01122925649d1db6bfe34495f7bc26d5fcbd110f403c7810dab5d0dcb5390823ed9e4c6b659a026c764d5b9885b6e2915c954ceec543fba7c01664fb0c77a81c806c927e8549cc5728c63c1dcade38ca0d35a322001410b9f1dbb3c9be8cb0e88f273ffbcd7f30f2680b313ee20938a952ce422d24d6329be5216d66f3f433e8630fc9ae3a231a9066757c7ce4c312e085b0cb2d712da3b3dd2fc80f65f26b26763cb3f826f9ba44ff9c5bc3d012ccfc129384023d9d7d8987eac4bee91496d163c54ae12d2d6ed28ce6520a8afc49016afe963c58830805cd1aea8d552ca6f010cd5873e8ec1852374c51b5f193af115f178ad5c3d06200d62e2a58a2ad0c25f595bba3273781b28a9b1cbec07232061b9566baf1af822bdbe8745659f53dc706b47c2d05e155e0c44c30200988a85e07e04ac90d76d1ec404349cfeac37b7ff6b9d9687546194a8c74001f9294575d41136ae0b5a54f09b3eab19d1a74677ce93b2a1c3dcb5106481477f6099de204b9c80fbef7f2e875098e128479ed6ea2c3556cbe61ecad5ff420e0078f9b0e51448d5a9e430b0e3ffef66b769cd7cf2b39de0c9e3daca93534042fe17ea3f6cd88e737b8927bb94e0c3efd05681d335c234ea85f59448ce2d72de47d79a8306f307571bdb0d23a735f7a0c987bab805c30f80b484444379d60a16b3311fbaad12080f6b381e9a5aadfef6e51a4194f8625c379668c82a09eb692d5c1ccb6290a6885565a0d997f59826595501ffc1462e83256b4d0baa614ab10264e643de75b2835f2b7dd089d7b3755eb69bfe4779cfdd911b9f2fb3c4825e3e041952c662335dcfd267f5e37c33055338dd729f6704d5a20cb3c5f97d5efb6d44ed273c6a8ae4ce84f4c76484722683390f42169fb4d48a8aed177b9655adaf590bb0e3f8c04079fa0260f3a65475a8074a8f83dc1f45bbba05de89375a3191425c7db4bf1c61ccd02e3fe976d993bda09948de98dbbd9042c9e2d1f2a2c2f08c929abb54135378016902e75be40aa0bd1a742a6d7a1876a93133832453e3146077970893696e45cbf638b09ba5b8fd49af3ac08c208f06c0bbe4d3791e2f3f43fc207f5ba417f6bf7b986dda6930383d533a18d00356346878949ca3e8de432c3518ff400000000000000005a8e6e0000000000f10dff52a01d0f77a1c0dc61abcb5bb325cd6c39ab24782747be042dd7567316e35e8b36fa3e872b8142bb216ae894a6a21b6bf61225e816fb8f0c2266353ebaef5f965541fbe9041094f972365cf5f9b5e0fa13d3642f800e24c5364eb47ad1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005952982f625b3896b86ffd64e7ccf38ee8a984052e1ce2626fde0cd018b0fdeae7c92515b8af1fd8ab3722500279f21c646b252eff8e9d80e78d21af42830009793f127c86e28809eedf52b23c16a2edcc13cffc986b563df31472b02459027f8d04b24f3bfe8751d1bcd83c97d96c09bedb8f4fe6c31ea3b53b110d985210b503141e0dc9d314b9f0cec49f3904cde181e134fd9476fffcfa3a37f1ef4cff28d70320df86704db89153a1a4c609df0c0d60c7c7848d1d40351058221517e355a2b60b05a8133a7245ce92d0d4afba28954dc267a79db861f2926304e47532050ac9fca262758480cdddda4dc9685a174f5897ee474fbb7d56aa3c3da7b756c3986dcf02037330f51cc6403a51d936cb460c0134fbf3fc819f74f039b92cf4af9dcd91fa0209e4b72c42b1d4f653c28fd7d16b515ad9986893d1530dcd481749043631dc8e0306efb6c2281594a48bf22bddbd9c2a9d74c619679474bdb66a0563449594e353032d2a6ee681354a36fc0b0e1172372001c798d3f7a35da3b8875eff4eec7859e70316e24d2ebe08c2d87038cfee7605cd55ac0bb8ca0cdbaae592be829c8df1799699a42a80fce806f0027717509c2a1f6dbf6fb449b249dde7f6a172fef94a7a176e08d3c7a784f6fc1f9f46ed5859cd49483603098816b894265b61f06fd8e866fe097bfebd5824c398e9bb42456ac103ba90b25d68df75e91ddd9c6229ed292fa84a4d528a866f29e1a98b64eef03e0cefe0b9249de6748b5e340b3faae8e99ac240d59ac0b39c0aa652699703e3ede2b6633aa623b82f040a9db040aaac42f74bba7c66bbd3e262be0bb51c603fdcbe9135aa0bac50cdce27ae02c12d34825d1d487b7ec84a64d3f1d395a24227ba69e356d689db7e70270cf2b90ee2eb10decf2298d92cb3b4dca781702b15870fdbd9b42218e7d54d6ad489b2461d5af1a3bacbe975022e58febb631586876d115f61f2e52dcf9c108860fc4d5911227e450f7f6909253262866817b6e31ca5e27c8e16a8669848604e0fc4723ce7f83b49e9470f93d2a494d32c29400a75b763ee88c765facb69a233b101d9885aec10ae187457152fcdfa1a46e7e5a76a1cf63397bdc06f11531f5b0a8ae54aa6344aba0981a363495bc954fd4293de710d43dfe118c6176ed08ba1fa0cc5c79719052e96cf1e01123ace0e33a51ebeafc82041d34367534a4e1d695a5b741102d9fde86658946ae281639a2158b1f0002b449e82bb53be2e8529b6bb3308a7285d66d026e81d421cfb3fbded4cb60070d7147072ee1a3148ce75350a57b809d691313c8bdcfcda3e5bdeaa469b896cc64f86116a5a8ce5c385ca66b6061825438f8d78b62d71feca1246a130ac5368b92d254303976555de35908ef351cf6359ee955e0497e303dcd0a8e35586cf31022197b9f6e73ab3f1b06b8948885c7f7a2a0c934d62bfb4be551f4c5c25b6d5c9c924eb8d7e83b315d06367138a141f36f7fb7814bedb8c10f364727d00228f5abd7f981f58ca9d2475651a0b3f4539309421da73e9b1021003a17da8b0394129b99cad4d8a742e453cd3c0d76e88863f401f58e7da140952223054c8d064c468fc7f329cd1822f22a833400c91094b64c8aaa0de5075296f6ea148b00f1106ed41a6eb2b20fe14b6ab6ad01a669dd160c40d94b6b6f98c16aa5d4fea233081547549ab2fc9af1b98edb4c625b3a94284b5343d5fdab83baff9d1f9fd8f2d44bb7134fdb2ef90892ba55173316abe433ce5378d42a41a8b44d81f06a38cc9c141cd94509c941f21ceb40b9eb0613755a753f124632d3839a719ff8c39cc4ee2dbf275185b1ac9ec948f89748009c17c408b51164e1720ba0e6f6e724b8857f12f07616a26b798f507b4402630413dc5e832f9dcaf0efd7feb16664ce48bc5494bea74333efd1613655f54698a8f0b103a86a602b00fcb4c93271dc40ec1d277239722f2dd65ee5dc856042d6cbd98beef15d356cd45bca5a5961638410c33f4699eb0ca9e2ee5bf684fde5130e47dd07cc0f063492bd4ac817799f89778867fa0d4cd5ff5fa226ef43476c7a14ed8fa71f4fd56ce5cca932039cb09e2542f381b61b3e2004c740222d3e1aa303eeffb8f99c286d4aea97c89583991cb44b3f8cd093f24dcb3c86291a5cdc36b64d58fc9d967750741751c83d43d06a69a08382728096612e695104fb21acc2764496419becb71e657e4025f34c2764487903d7a192265931512ad5a9d24e099490fd81649d5f50b613a253e3b8cef6a402666d0deb7cca1f14bd7a2acaa6a174a60ec65d24a192ae45fbdd871aad7f94cbee67f6f31d7797d24a514271962b99bbf38662665c21294d049004b257744a7d55561b18f01adb8128d3b6b73e70e7e9ef5bfe8791b44e60b7a2e381e8da9d73917cb79f440a501", "526a5165515165516a", 0, -553338102, 1537743641, "bef54bded6f03298609f4e0543c4afe02db4da8fd9d25021244b7bcbd0e7cab6"], + ["030000807082c403047cc43954f269b23659f8ec93d5b715a5b6fc2ed317de97ea3c1767c160497b3d030000000851656365656a6363ffffffff378b019f78117e41906ca2970ee279e7a2b9eea411588693255a0142c8b8465b0300000005ac526a526af1a65586ee921fcbc222bdd7cf7fbfcfd294f624ff36f8d399da4bbbb45c968d7efc41a70000000008005200006a53655139b781da042f859f859a2207699b98ba5d3bab50d90328af173b12d93ef39dbd1e98efc80300000000513ab67c04cf675a0200000000040065515164d7fe010000000002526557bfb5050000000000a6bda60200000000016500000000ec6280e300", "5353655163ac0052", 0, 609231033, 1537743641, "5162526130c6c82732cc9f9608a260ca40ed472ddf910a6d5f17d84fde5b0090"], + ["05ebdc430244ae630a5c66466c8ddd0f327acc5bb108bd30c8f86205b11cef44ca050613e7030000000800525100006a0051ffffffff2ecaf5ccb515bb96dbdc2d4a61739a9910e260f5e4342d12a3244366be74942a0000000006ac6a6351ac6a8ca8a0c60305d7ab04000000000563636352630b0b56030000000003ac65527d691b020000000008636a63656a525351000000000200000000000000005cf39403000000003e171e800d39fd35877a8c2e2b0f4c09341d7c88f171980c8511de01543b158a629e9624ea6d0bebd8c518e654da424001fbd25d462793954ad80584f7faa109a1cf30d5f17a9b555b2763103b070150cffbe705f9c150611d261d08dd73b09d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d046fd6a6b48435f762d1cef6ca31aaa1e49b7cefdd47a222ef8020c33d002ce960e5cb9bf43f9ab77b8c9d0231978fed58b1e213350ecc41c4d60ef4278149d936410e6e2ee4ce202783ead5c0e610edd9d6390b0d5d27956be560e231b3083d43e388366bb41899ef0c5fdb552468f08928549db66e733559b58df42eae730215d98639a41d5f44a1b34607b8043982649fcf2a3f1d368a9ee4cde0ee3b5192020623249dbf9e1aa38eb34a89ed164f64be22ee92c13fbd2703fb755efdb48e0d0b00c20ee345247b3e0a6f62e47837ae727ada6699487657525abcb47e30150bec8a5bbe64e898e06f39742597de830126254d770c87d83a94c9082b227083c5d2030a11f0dbc68cbd500fb5f19d0bdc7bfad983ae20587d5e2e5897f4768296a3580228be4ca536100a40ae4813e655430fe03c37ef2236a34761fb1a4e3806da09c40227a579c8ee003f3c865b1fb4a91fec91efe2bd7b61463dcd4d0d464b71ed250e02040264d4a14c063875aac39aa1d533d055244f901fb62d0250206f06eb7665d8030fa4ec16b5e8893f65bb16f01417caeec73ef60826bcf4ed7b842f417aa4252b476034f23617dc80cdce4e06e06d1ef832a49d3c1e34880c2880e144620f844e7a516491a7cfa4fb90da1d219f22d7e8c7ccaf5494e2d45f3ddf5e440de0656ac4ab76efe755be032e1d0c96b13848167e2ae0456235d139645b23a73a6c5e66bca732c41e3e8965c6d03611a4d627b37b53a05f217209eaa8a8f5ceb0d6d66f8b7d2690cd952533fc1e55f5acaba0f6a31927a00e9449986523f19d527c9540cb7995c2db6361ffaa6545f11c8ddfb12a987aa5e60bd7103c3e6e62480f41be2d1d6c4c1464e14a4120683993c9177fc4adc6dd385e4b41b0342de8f19239aa6801002be2479a20238a91623c14b57007754fcc4a359f489bacc4e3066a4ef1248fd367b0e25dbeea0af85e2c257a1541dd53fde4d3bc97cd5b44e15c5e4c06d0a095d5731aa42db9d83d39539fcea8831f5c5ceb84f064dcf89b02e1dd455a7e51cde7b470682921f5e5378724c712c55edc916ad13725398a057190e72ac8800b53cba465caa2b22a0263d4b055364a177a42621ae2e88aa1c3f3f8c655669e31d16e9cd275034420b259c80c73a682fe65292149727cad5e64f73c27ef9851b830b458493c02be4ca81e1006d18e7340b485e0a9f741226a27a350f79052134e0edfae3119f94516a31b79faf73e800927a4a1301353c6e7ec1a271ed435540a9f57776cdae92996f7e739a46856a9c71f143c97b43106eddd7e1b401b9e1e5f4a6c2aaa84cbd92f9ab62c2f3751ca00fe5e4ab6e61cf23a1c1d8366e9d145686630a5b98118ad3a1ba673a9d9f8c87db4cf8cde9e62ee69865bbfb3cd053b35a8763629751c5efc7c109f57586cdeb7c93ecacda7ba0e5d124299132432a4dcb2ccf5a1f0e901bf83a506daa4d2ebfb9248b79fb58a4a796eacb35f3a56418353f11d261dc9fe498e26480126b548e38bc04dda8d0551b9ae588620e9ed78961d39737760b60268cccf115f60afee126181fcdf9b274a58fb476c17a7e2c64cf48e1af974d77fb9048b0268ff2116f8fbf39e1cde91502430c5e6f90245394694360ea880b6bf159e0687236b34088ae708266f2d00ebc24a509b1affacfe0caa65cc87a9efc5107134e300831998d9ef61e30df725a82e3f3dca363f90823918f2d0fcfd03b8579e583241ceb0dc08961dc32fb5ff5ff4ad536cfed4083bd32299077bb9c0cc3a6bdf808bb365d4c5609e73ff17001c30707c7d2704bdb0bdbb2a331a939b17e11b168ee83db154eb32fa27681d537f9faec0ecc3ee911b24dff06e0fb1fb7c5606503410b2c541e81fa8127b3053f063f2ca168a85565fdc27ba476f5cdb236c038d8d5b91c13ab77aaa7aa45edddc46fddacfc3f9357363976a6d4fcd138ff1f398840e9562efcb7761168ee46958f8b86aa9130450aefb24feea7e70a8c3c63c0b7fc057c242a7f1ed4dce5f19eb52e49c205c98d9c4364f1efffc0ec8cc0092b7a1ac910013578fa0ce824885294e5ac4e4994a4d9b8ecd0d5614cccf552fa160f265b1edd58c87d457310cea95051c73da41691d9fa0024ea966b41afda2e03406a882902084d9e1aa3651f644c2cc2ac88ba4be5bfaeb48dcb9abc73c6e9c4e6aa5e28a4f74da42e81768960e8720b29f97052cc8c8360c220e80cce16fa03a694628fd94e769fd50e4376bbdad61f918c47733f18ac87f9bd33f846ada48d5b44a13d8bce54e1ca902000000000000000000000000f9e60f46c0c2ceb0a9639e46df017daac99180ca4ee241ab381b42e64c1a4eece33347be905ecb2bc4e0e08c09e0f8e68a7e727c31454e9b5f58f6fc776469f685e5700785ccb15f7059852adf7552b9cb1b9283aa9ec1d5c9008fbfbfb03f48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006af11bde2363b86b62c3dfc641e169bb2e8544ece1c87c60948745f771b0635d64b8992acd0e7f2cd2d8e81b7e9fb5d63699e7d0bb81a57c4830c23098954a2929c86cc15faba4980e9202c2c0cb734e358b1edc63d9a349c31ed476e363a022ab54b18badc3f7dbd0a009edb20e3254b4f5848232062d90f5e48e790a74179c0223b0e45d71d18df72f2afe6f82a7770e2c720a8c1ec255a7dcbb45e8448921a50323a20f83823c9b235f7bccd6f2fc81a335b9be1bee50bf9e859f1744268e3cf50a00f2a8b236586b983a53cdab561fde8ee3ac5f37e44eafffdfc97fcd9c134b83fd29fd2dafeeedfb0e7683b6ee70bbe3d2dcf88cf01312d668e72bdda2f47912022a71a9cff14e706e154d7285b09cb79ca73d6cabc86d566111c1fa389bfa9b0e0226c1ceaee3625b0e04c00f6011b8d1e2d2519dd3db2d7777641a68b6b3dbb66b021ae8fc4939e3b55aca2211e1aaded3785b21fe7f60c437759db68ae7abeb8d370219ae0162ea9f29d222e704b95e859e13c566553a03aefe4ac3108df75c8275350314aa2731fddd1cac609dbbcfec43a91500b98add35a3f2817ebb656aa69e60f948449a5a7f8efedf2778075437e9ed3663b6cbc34076f3d85aef93df1deb8b2a3220e838752034a6896868d295df6db985098dc7008ca11a2840e5db8804030680431a932f5645f245e796d343715c03824694c379c0f74adf8e9a71e76ed698023ca701a61bbfa4c8b712b75d0b71605b9b3c4987d9da1e6d44172cc67a52698dcde1f6e564b29efe7f2503c813faeec2fee4719a47a710e5de2323dc790ebb26eebfb5a3d85d0b57f5bcb76194dce5410270ac19c6201eb3413e94bd84c347871edd11d540ef09582271aebb64d393449678f74ba30b0426b3c51f1561bea7a31ebf7aaf4b0384cf3bcad6d896aed8603aaea185a341c2f13ecf0c21e8594f4e38f5392dae0f2de9b0814d98091d28b88f287be94b1f2e0b24ab8536b44d246bea3d9ac2c5a4ab2b3c6f698674af9d331bffc2fbe06de74960bf638de0084801749413b35826f7455392be9baaaa26a38fe4de9e2da878db171c884140f325d1ff58764bdd68028521a402dc1420c201f852a225fe866588d621031709986d6130d57c7b7cb396cc1a81750d1d4f679a1cf12f3d06e6817a3288f42486bb8c832179a487711c32d0674e0fc044f6a587f5f789cb22b99e0320429992442b06d8c5345d605bdbcee5087a522ca50cb4819e4a8dfa8cb9e95dada0bc5f667ae1129d5dc06014212b8ad3e6321b5bc04d4cfcbac74b90b474b3d56b81f7bd388307ebce4ca2d9138b5e952725ede771723e74d15113cb48dd50b61183d891c8290e552c1cbd8867bb038960920395d19bd27ce8a7716bb269487323f18becd295bfc51c82ecaf014c12649c7a7827e688f66c0bcbcfeb6d8f6ca0120f312162e70db641ccdeb45c2ecb5bb1d327b46678e5262af595b78294ead29e4e90101df67bd5770549f2b295008df8d1a3e96491965d6a40f23210dc2eb9b31a90970bac8cf47de430e0f5205e5aa2b7535d3e62802fa7ae52975a0fe79851efd054f3e1d44fdd277a6f5a9fe6f16da91c7a0420ef07402ff468b7e70e5d028d9c7c9f936ed0a1f05af146bcd142bedfb8d5c63059a6a3d1f5a314559d74829bbee6eba1d4208750b6ae511d8f779e86d635309063c7251229dac06852e42e0bda167a446f6335104891366c5907c7107828a8f396f53a0b5f79d4da2948bdfbfd055cdaac7b7004e6b505bc279ed8b0ed7a034d87e5b97c5ea466c76d7f470eb0f1d06c1966a6d214b378a7a695dc989a14b0a6fa900058cd1492c76558985917503e0e29fc1b6bc2c5ffa9a1490af144c21feda21e96743f6a7b5ac7184246d018536283b4129e9657fbd75e2d7403e176e6cb07c914dc0cd9960c6ab54e5192596a63419dc5a098fd3d9caf45b648ecd7596792da8ec5cdf3d0f27ec141ec05cd891f02134d7a917aec153630b4b87f05506740e0db011a41778136b9b7447dcfec00ed8f532b60bf7780dfeba3374d50ef4f5e2ef8980e9ced67cd80ce989dad41674cd7044b72c1a042b7436a09d1ced598e7215ceb35d61427fdea22b8fbfc388227e384e6e47eb1407ce2fc3b0617b33fb3d9da0d7123d6a6aaebbb19b5b2968a91cd7e503adfb5cedb22ac72530bc86d3e5de670d1cbed77ad28dc2e353aea76ba829f7b77ed88ac5251427546e6f9643424d856bf9ee51e73028ecd1bdfec0ccb88f84bef00f95dcb19946d2f505505e7f9d2f3751f2a8cf6cfe808cd0a2d1bdccb088e906278ac16bef70e6ab21026e15753f933f6040215985ec41f1adb7b185806bc624fffecae02c86ad3c3728791f1b59dc350b1b929dfdb240df1a1b6880808b4186138eb0d53f0266d0d3aa67200", "", 0, 394333005, 1537743641, "f1785d2097c43f13a9cdf4552b500600d90d026cf3d9869d2d9c21576272b3f6"], + ["030000807082c4030357f8a2ad0503d26988f19adb0732cef0c0b00cc58a9325e7069554050254282303000000095152515153005300003dde4cccde06d72a88f06cf6bab0022d2c83c112971b3b546850f7152e09087b76532532020000000551acac5265ffffffff33130ea0c6123164dbbbe9d8a1318a4700adcb2a9865e504b37a6a3016a4d99401000000086a000063536aac63ffffffff026715c7000000000005655365525300d7c403000000000263520000000061921340020000000000000000cac00904000000005e77cd7fa20ef1c3d42e1ea9f6ab3664f9e9c2455a53dce9ead5f583f39d4e912f8da5e0eda2827081127af94536886e3880bec7bef6b92aa1150e3aeeb76e622e3ab928164de70fa465e40b5f83db6918d378525f1b0d8e47a222e8d1d1acb20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054791326c3265ad17e0adb783885fd2f2e3495afafa6dcd4063645666168d2fabfad08bb348e795e13166416d326e1efd8d69d8945019df4feb87334900c116e18e28e3ccea1ea563750a1a2cb283f3af0ea5c60a235f486189e38cbca19352341a25eea347e47886a2faf566f2afac27f01757086f3b78318b46750d00bf004030a6daef5dc349c65e87ffd2341c9f8dba81a2c897d99867017c37bd7f547df3b021e3c9e6593d73c134500f3b9673e071cf86359e6e7fc10b0a1e805279534b4f30a0054d81db5ef08a70644598ebca450d7b0ec3fa8c07fd65939b3cb7e50ef539cb6c10e10aadf018c35599899b8e73e153a992f60fa20f6242f700ea3b591f115030b9dffe9742e6e3430906f1eaa68e808b07172c760ac77b23d3e75c26d70215702102e8ace1c8f06fc93dce6418e11bad717bebc87b9dfa10c475e2c3bb4537f3e0301f0d6fbd6f560db4b927d363863505998368df767e3ea15bec45527bb39bdf003173c164d5a4161a51116cfa209ddc38cb749c43519c5335db7ea96127417f177022cc45aff8c75ac1afb7fa6b0ad3fdef13951a236960079de42f51ac56b38fd8294b29d23ddd27ea18e108159db46bf46b0412eb0cbbe68ab55a6331fab5546227edba72dd73273308e4bddd6287aa02f475c771a16c089411ad74dfb05d0c9396892f1921fb31e2367a877b0ae898aac811255bbb87cac827e8ca8d3ea08a96875a6627283373e55ed7c59d2a913616c574bfff8da6cd7fdb880a15de4598bf5d1c8308ea9af21054681ba3d045a1ba692e7c315cb6fd3606eb96b782d4f90041ce1f2b9b3f0785e9e228b1b027707e314823ff2a27cf139c9095dc373e1a7e8055d408b6fbb09a8d2236665dfcd43e85bdb21bed8c6c9df38817ad6258ed275ab284be5739760739d02024be816eb97715c6af840a4182c1df1028a11f1b46d3eec9ab85d9836907654c7b185b2ab8adf045aea888f2b40f7a10a67b1bb413583fb58a1d649820af3d29771dbd8cb85dec18e5b480ab8ae3d07df1355019d91ba26f6594a9afeae5e8dc50c25dc63dbc0dfa2c8e19572b4a6a0786a8895922a9210e89c210af019f826c2a9c953999cc80ce3473c46caeb9a5f09526719da7076a6cd2f5d525fd8768b6a2c3ccca4ded3867a60d0f227b7e47d45ab133481ee12be51b8879155fd73c1999dbe18e675dd9fdd4dc7518c518f2ac8c67e6e3080517bd63e5fc0c7f981a41e2cea70aaa4ec6e33196813a9a58271af08e55a6346e3365f877b086927d61042d5f735d8c8b228fec3b65f9b72b610033c27db1e43470a3cfeec6add7df007fa02f37f0d07ec4918cb0ac560c0e4f55f28c698feaba64749077a3cbb5c61b56947a4458152d3fd3830df2ec30a240ba8b62aec4c7058dd4d189538fc5ac7832d2f31558d230f238ca66e1c6b3c7800db33d1c2ebd3d5cb53a2f1aa7dd57f32058602be0215a13c2c8a5f330e9aa3619b903118fa4d21e33abe064a2144351ad5ba26579656ba50f1203498690e9734ae966846ce4c51626f8d91dc995f7fb354ab4281bf0fd9faa60580c9dd8a161eb3c71b3c890c170d9db090da84d3b492fb2caf7bb37524b9b7f27678d88c4377e0d2db1695d46c023b1c1f62450c3c67def311315701c67eddd6573005f038db787122d2fe98c4571293ff33650943d83b48f68a9ba294480aa6804ee1cf0c591c5ce3fda6ca5477b0e3b30a15ec81abf5e869194b8cf153d0f970333f340664aa628fc71acddac399e48cc0d2ed7935c0067ff9583696aa23358c45141b55b8ffb2c03127285b92b2f104474feca00f23cf50469cde6bc3037f4f019b0e9b5d5dbf91e09aeb4aceb7273a53dc533d358c57870a9a7c6a314c11acf49cbe173a1977748accb449de27af5685dcd5661aacd93d6bccd97207b216058644c49077363a447024ef65d1995e1467da1f53e7341ab93a1e6885b9d2dd3108e65ef9cebdb7f004ce4a1a1826ad1abc40da65741d55d8a31edd8266fdb67a5980411f4f4b7e1a7c204a6bd9d2f9663bffcfe9b1cc8f63894cb8d296c1d3d365550dda412e085e989a706957d921ad4630aac719c8cb75bd1a385059b48d92e2d419a42f45de71606e0dd8c1b14808f4a3605fe6d5a3a1083738c0897d7cd4a2926750746fc4fab55addbf6d164832db64228d8afc7e4cd1b4f0a15d1ef217973318a7a40938b0bdb128222f01da5f110e5632df062580295c361d9e207198445d1f8ab89cc4af573ce1de1709b60bf53e2b3867e71f5f398a9c822c0000000000000000b46cda0300000000444bb55ade347eb56b95bdd5284e659f953354a69016ed0ed102d7c1abc6cec86b52d2e09625afd3d26eea2b502bd949b39691c557b671d8c02582b1efc96776688f6c5e0e6eb545d0029df2ae0c4de2189a877cb4e452801a278d5d9acc443d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f76f8029d93721a597beff6279a7c49325b33f1947fcf36270f48b6217253fd532a7557258dd8f89ec6bcf302af127685116692f48778c6692933f250251ace1efb1e3d9cde8a5275791f04da1b4d77d985fb787db639a3d21e5b5fc5b7f6b06a74c8b1dd02ecc31fb2526babb10b48f011ad50dba9ee36227379aef642dfbff0223e982420c0b781cd01aedc7f400bd19442f1bfe6a0cbf5aa2d51402c3952666030168b747cd5b572b675bb1f566cad962e7fc3f46b45c993fb2c665fcf5eaac350b0605e7bcaa0725905ae09c82d21685190c70d75959481bebf75ecafe57f7ab5a9edc7b3385f08937f112e687e9af91580a2f6270f5f2f057afc042895b36e326031b04c52569d828a60098e94d1b47ad474d50f871979ba61c95e4819e78632fef030a45aa42a63cb7b8f5b537d1ffc05aab6348adb29c8fdba416998eccc3a800620303b6ad73513b1f98371c5558d44485e037af8df78d1d5ddf94f907544d0141dc0317ff4cdd493a276e26edbc076203171e6759509823004507c0a860f9e97ecbff032a1e318f7ed56ec5e9e45872b94d4162107bda53f9c84487147a3a74b93fe277bc463d844752a274a2106cc04c8d53eb10ce470156ddaf0057bcbb0fd5027d6b669bc2cc9789196e1a0e9c35d01c2f35e480c82c8fa02828efe544901087401eaaad84ba975be7342e59d7404be3591521c76e122ef419f532b843c197c5e07330f8758b9b62f729d681a8fb2b903fd011981a18e0a66265f4a78a6292382797c4e3cf24b72357a10922b1131809e852aabe392791eb9b792350e9a5d15dd561708ead95fc0ed864a6aab770ee097083cb992102b3fbb371c5a34216e00f3399e72779539c4b05046ed4e4533ce2321cc302327f033d034faaca336836ad0af0404804c7e0b11016283c579764e9e68f9476894118956da11f1d48ac284aa63998820d9edff7fa3f0ded055e7833a756ec3fe7516790f5c1bc774f245516d4dc2355acc3a0ee34af84a5dd4b960c741b9f3f2a32451cd2e03440a837a1622723f9f90bf8dd7417c9cbee8799a72c9287efabce9b8c64157053a8c04070c5aea68686418acccd0141ae06bd4506da66b31c06e42311e7cfad22f7aefd13dae581907f72510de05f6e9d2feba87e098be54a3ed55c530588de486251bad5dfc191b537c386843c8962be4bb97df9f532add14193de1552e2a5d14e2d731ba2a932ff3d6b5627e9d5d886119184dc49c518e182d0f2672dba36f9a5b2882dd26cfdc6a1ba63f28d3b953fe424c29c1d76cc4b0111199db8d9158742e3547a1ccb384bcda17b8a36f56c2e149e8f0e67b014b562f0d3403dcec0a54dff7b42f9b00d71abc83308a4d9c35ab04db1f0f6130f2ef79fcb2acdd69f0b24a005e9564b78585d508e14d637acf956d1bec228acdd88946b1390c0b20152e49033cfc03cc66054b524c60ce1f5c00aff30edf7099970134cbdb74fe9f83cb4609ca6879852b8137cf09a9a8fac6bc18ba30772dafff03f77df3ef157f1e41ad689413c91b103b5349c0a9352a432e5a855df89a5a288b367feb9619d304b2f85b87f5c3ffaeb1b348a43d7dfea54b468319fcde77e23f549ac7d224dc8be675c14ace90b11367823a42c4d2e404b98765fccd3ddf91fbbd4faf661a76fa8e1d8207ff269a5dfd9aca6028773b884e3a38b4f49b7bed4bbdaaaf0e19191e4f5aa24cbf91aec77f05894a9b720a3e4e9ab1fb57bd134f933d57b2fc74e72d835bec1c989444117a36ef8e68f5d63b7b3f27f62b68f1db953a3c95582157ec5e3febb52b032f114144c94cfd94b840c239ac0e414a358009eb387f2495cb958006ff10005658f47271e28bf9d97a2fd3460c8b115b7432a843f631303dee7c619babecbf94f5e8c2b73696e7242a488d0d34d78835336b911db592d0b8432cb179879b78e7e2db75b41c3df7d756f3e9b2e038a1cc5e30610da87d3d07dfafc42168994cb9cb6c7e3bba8c85822530ba77406eb3117a852881f871b384985d51b33134e10f30915a9ecdb53355b59fc02f885171579b472837771f9d02f24355aacbf130ef7ba4f83b6d0084d917a00dd2afbfdbfbf402ce2b585c400b4bd355f29536dc884fbd5a3f24714d266116c2d6677b2aeb671b5c1cd8e095112da430f2894d7e62fc5cb17dbaf87eba5d0b5a086a8238c30214f7d6ece2564f9cfa1cdd9894d429e1e1590674c4988a19e74f01eafcc17bf39628458fe39b26e718f7dc22201caf6cbe58f7defd6e83e65b47d208a4db96f14f0b3ad4970f66c8faef844a2e12770ea7e8943c493c9e7bf78bdeb182c5632dc0b73207677ec69ad840768816994868c3a5961f47f3411b9e4b369aabe3b844c065ca53b3c6591f690edd479cd175a46a8fa2ef007f55894a0d19fd4402b7aa18e08", "00ac6351", 1, 1661871064, 0, "abdb48ab03edaab9a79576068b5b7e1744db7d1bee1d942d12c308448b77658f"], + ["413efa4f01bd5e454d217cb0d8231437c603385a59d661d1f436ed583ff2c3cec62354b664010000000151ffffffff03ab4c18050000000003ac5263bc6fb00300000000003290800400000000066553516a536500000000020000000000000000632c0c050000000097615ae9e0128376a912f9d6fd7cd069fe09c7bbdcdd79a299243f2d2c18673a5b882a350694e6f18ff8a986bcb5418c3edfa4c25034ed03925c1c3e4e0488c6f6004d82137ddf2fd9ab11c5f328fa21e33a2d1ba6559505c57dbdc9efbcf8d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fd29ffce50d1339509bff2e274843f5697a553f5b2b4a90f8ef9c518cf930405a72c07de8e56ba767facd80c789aaee570bb1253a77242d05cad20d5da2ae04cbbb9b243a96a69de13bb5a17d61d68a5e02f60cfe13f7e822d96d6e26d30eb6d55fae09dd85b54d252f305dbb64af3fa3818af68b46b7f8ff6b4e451ef8d138602080c998cbf80968f0f55694ea0576edff74121c5ba5ffd2484f663b3bb4d9c66021bcea15a3a96a53fa5ab48071d6ec9c65c2ceb4200a98fea921e55304931e7780b08523c79b758112cfb4fa4f8328cbfceb05e9376572e8bfa89393fb02554374e27e9746aaffd809789f873e336ddbd07022c572abcf0ecc7d134f6a914a3cf1a031a9cec512523267ef12714717036785fc617bd93b009b20585a440569afc58ba0220c3474afba14fee97e3ad6439f9a1241301568b9032efb6f36fd740e03d81640216e8b2509f7cfa3cb5d479dc40b11b64117c38a99b10ce90b1df03225593138a022409e01fa09a627e1a529ddd7759e891b7523466d22eba2c8257018b6ff9dfbb020144ced145a0a9d7b3dcc6ba60bb04b9d8e03343c42f36fc3662883aac2f01aaa254d307aec53f908b0c82c02a70063f42a051db5fd5022d53011958d2238df7b199db19f9e81b927394e56885c8aec1d3696f7f40ce108b2f44cdc4c82024d315d3e6a6e23cc1f387b45bd46fe32c39ec217312adce3b82030aea55c80b5adec352ca40be57a773bb94f9e00b640dae006d8946bd6050f273c5b1c22d98097711ce2e10b560bd5a4b9f3849aa61a89daa68bd3c1f1324c2895d38c5955d248d34720b40f60e9114b3489db0c24d88992f5266934c3e5bf81e505e486bed503a9692c8efe2f8e2df1fa35d5e883a8dad07971a87cb6b8386e2afa1df7d4dd6228ce9d17e6e03722668571ab6c1b35e66a366e57f17304114df3a7b429f5659545c3212b7bc8625d150f9ac8d1846164d070a4e470d7cff108348cab321fbc3f8bdda005708baa05f692852ee86da1438427a828eb0e885dc93f0e0aea31d3634475fc099cc439220abc6783b9ec592f459b9533ac1d3e3d1f20d51be7d88d0f7c8436c2e50e9232d5b9f85e3266986fcac6ed9a545e709c9c55cc3c6f80d250aa822bacd124ca1849a379f84f6f057c93778c7066e40a65ca3b941c015a4a00a7b554021d413f789a27b1a6165408f31eb552967c23ef7cf4e36eda51e7ad874a658d7472fed6126329b3b5526f5c076c5dff0be449a2fce863fcc7044353a1f9b240dda03c34dfe0543255fcc68f51872e9969c1c5a9194e78b8e7456b48cf1f0b6bde9f7e8d3f40fda7b7408e515ae06b5d2a1c287593a711ba38e302a013a83f7c0fa22c910513b59b9e0a2fe7d6cac05c4b312ca1ad3e39630237febdb30af2edcf47136ae5b20282aa16c340ec4980d1631d4d1b616b0ce361de3928f15b5542ab230260847020e12e2dc430ec7dc76be1aab7ed15e0022da9f1fb3f207e40c33f0153e025de4ffdaf9791aafb55bae3c634d0691334005c20de9a6b92acfe3d616dabfb253a5e7b75474d29fef72538d023d52f915dc7631059b1ff79a48c38199755e9b7a33a0a7a45a4f995fbc1638b37c434fe93c9436d2e1e7c408a3d4e2f2af26094a780837f45de16c021b3328a068ab80f2d6360580dc4ed3162b9988a5749183a64009168b2cc3042d54d4787eeee31cc6ff3157fafa2ec18cf402f06e33fb005bd37271ae6b687c16634f35dacc66f0503ef2b39da8be1472c5f7f80183eb639bc911d119759dab82c626e51e47f508b6dcb487fcb50f2dbb1ba3d161375d8abe90f8224cbae83628ad93a60baeb7637f29281e0615faae673f3369bc2fdb8c543b1af3309f0faae740066a34ad6d16258b4201d262a1fddeee09083e0f3dff6f6bdab9014ecd86a511fd89d723ac4de30123065520b73b9cabb97141377d1cd9132c415a6cdb5f2956838c9cfef4ca763c01ed41d73082d4c06ef26729b4086c05dbc9db29009ef726272e654c1cf390766ec73ee885c0ed38775ed4a62313bf359a785c6b8b92132e728821d0047353d273b19c88bbb552512eb85b1c39da4e841dfda23a5b655e9237e3be67259d522e525f83fb60c7b90d0c511065c6fc8ec463d89a055061d49f28e46c6a8558d140c8469a3f7d09f72afacb3b22a9001c3b907481778343663afe08551ee0a5e2e2afb2ff3d47c9307d7c1bdeaf340f627c858bc6e34b52b4b6001cdbf369a870d1ee2fa8a3098d0068138924b9f4a11f380a322a948d7006364a0000000000000000ccb2700500000000882375194bed71d5c87a15fe6f25a63a6ead3599081b66c2945f2d4c30bb2aa098a7089359191e0f758c60aced9c8c761772c3e9428414b627069de5611edadd1a07e0a2fdbd54c8d06c65fc0a7b78ec4780c01a4845d020afba5f36164e7501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a91774181906a4634f9df9305250c55891a9239d04027c22edfe49db5d63d4193854ba189acf7269030a981389eb6336ca4cacd122dffb069a45013e6b42eac6d2e4e7f48172c65110b9891d1ffce625142390c56232bc4567931125f062b7b1c3d44fec3f71f1a0de697068f8c9e7077f325d39a037cdd1ca9569db39a81900215538f47126a8c48bc23b5f3b432d02bdeaaba7a0672de49363684d768f1140b030e1ce9d85578f0a04df21367589d6576b6150fb194c4f46b2949c684c49ef0430a04a381b57c391a4336b2604604fd27a513954e07e99c0091d262cdc33a57c4cc1faa26c6b51e17a0ca2856dd334cc3f3b502c92ab211749622077fe0d99555a90206b845c40280eaeea6a9b63d9b9570c2933e6fa9fa6ba171e80fd0151907ad48030e09f551545795ec8ea067624b86810d13ce893ac37d5d605be97064e658f42903147ea97e9bea8eb63989ba129feb4cb466ceb8ab74ac103c379d9db91b4b0e490324b7613226b69c1c6caac25b8f36efbf4607d77633b70495844f31291267e5fd0325355a9fe9cc65dab72a29f288f478a9f94be60669653b15148d4d594d7fc7a70e9a8ea44560c698f4d5c274bcca70b100eb05ab217b3f550d83d28d6e458ddfbab908ae07eda3ba330c5aa961543d596ea9257893780c7f551b1ecac38c6be2aac71b7a2f3039e2a66e0c30e48c9710b4069ea8e8d8f13984e0044c7655b2efa27588bd6c8cbfd859b3ea7d8ee20ac9e95726b713afa85a52b884ec7289552f1248fa097f4739f099cebd253f30ed50d1f1770104a30acfe1033a1d6a7fc1d0c675f1f279f3f94658adb16480e26aa6afd8f47e4e904acef2c04485a7c4133962434d7081f5b103a60b3bd80e04434128d2d7d8470364f9e787339bdaf9fd7ad09a3cfa4bac5ed9397b031ee672abb9abbe3bda65416a059af8c0d166d39389707d40446b2dd42993465daec933dc6192051e484ebf56f2b048a340a36fda1e99932a1788cc1e60974e29fd2afb92c53392920c231b7bf95be1b7d2719e819b24d6cde08756dc17f1399c11925e55a97caf8359462f193e13009ee1dec20c402d032ebd0a85cec023fd64dd10185c197775d85fee55290e71e2dda9215cf21220f4fc5733b6e5e9c674cb7829c3504ec3c285eef5112d449027203714b92f712f6e68a851b30016f66e5ef70ffcc38bb6262f44247c40c3df124ceec964fcc6312650b598a0204eca283d667f98c714fdc1ccc29f46710a5a244db1eba78d972b60e515c046354d877f44745a89b5623c6706ffae7f70a99b6d989c2d0a7b627552ad9144288672272b4a2f9f52e6f2e0f44cd082b1da3f7bec4b35d5eef57522d9aee63709f757370cc2190bb095ca5afd7371a8804b922ca369d689148a709eb81f2e3a4a3650de50dcecc2aa24de6d8b11be0e5b5a02d3bfbbd8e22f71eddd299020ab1f18753a6c9d9fe6c9fc4888e37707b59458546eccafeb2b40232a75cc88bc9743e9ac46b1a893607be33087ccfbaf68c4f66eacfee1e1e6d9166feca569e1fb6f6883a4aeacc34ce3210da29820dc83ec69c86baf30f457f636a54037ee4419aa2898f08c8db1c5fa3414ca6e0e4e4778552d712eafd90b2080db11889a721fe93bf55c6f1c864c45cacf2b2043bdd30894e82d82a13581e4d027891603a96c19604ca3f188fc10ea0cd928c63741a73dfa31970b9b73c6153d867eb507f0fe5725f26d46f38cd1bce95d062ffb55d1769edc220fc3197ebb94f3a0f7739213015a661f40c9aba5f599c3c598b6cd664aa271622e36e5556513e37f62e29c34559586de6344c772e8b99ab7003a9144651b4a846cf388b4533b416da73448539c4bca5082c12feab7ae7f09015b0493dd4599cb0baa53fdb72b20aa606daf625fca321d8c19a7e5a9c48dcef3804e63193c0480c33efcec3bff3bc7b870e396c89bfa82c832544931f5b5af12c8279938465476f63b0d14d394a702f301a91bb596354c4998a173e179bb60367270b062d392853e9894bb604e7c9dfe58f8e552fca3b4a8a95d15abf017195ce7dca84e228794868e08af682f9488702ea9e3d0255f93d7f1adb854b1ad9cf97a471277c22d4e13b0277b5768ce1b8a98dedb34a6a6cef579ce6dcb95240da415aa6fbc9ff63106846e0472dbdb1511db01300c4ce2b3db10ce81a054914e5c94d45f6f394c69cd718bed7fa7d6bea7062df68e2c1849116786e5f89fd6f88bdd2c3ec51f7bda334bd3df77cab044ae6736ed797a94e971ecb858dd146f09a4938914c1931fd9bf408a6da330713143556f82b922cd68190f2f09794e44932043abb3369fec867fa99dc49ced9a5340a9142593d3ff99367593c091193bdb1f6d53cc563aebe75fc51c1e1de4ff0179b59e631a76a4b6e01ddd96da1eb88700", "ac6a650000006a65ac", 0, -1754905942, 0, "1e135b1ac7c3c66a90a443f7c3e7614f2f4840e3c7190769a93c85bb7b82722c"], + ["e650db7603b0d5957ae22ef961c1fceab916a94e8b0428159f8413b6cf0b8280565a12bd980100000001659f32f92f12822321c8698b9ef393a8b807e05aa6d09b6f2fe92ddb27afd46fa1542c2de40100000009000065520065530052ffffffffa57bd3f867aa60ed13e9073b1f037743b26742bedebe7b3f9c144776529af8760100000002536aba15ed3501af72340000000000025365d9f368c60300000000000000003d08ee03000000001a7c31309e12a88dfe2c5e919e046be505747d0dc3a2137c1c7e9992337e3ba8e9bc78822cc4276d122f48c95340f883bca398547ce422568dc516b16f70c08876b4fb43670e0f1af711663946d9c33694dd7dace9e53373282383b23a1d06d400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000518920725ea3f565ab2cdb29740ea0e93b4e5865d2082149863561fc94ce822fe3a4e43b09e4c15106a059f813db0e22e4af52245d64bc4965ff4eec8c0dbaf21f3e2367f929e7451da7c08984b8a3f5a7589ba41cb788b1752f4b18c5e4b18e248c768ce61c600fdc836c95ef345228c3e3001783d727421db377b259c4d5d3030095173a39981845d90cdf944d1163c73b8538ce7293032d5c7144a42a2929010224593fad7bc618b65069e0f81272a2e3bfba48e080273ac7b5ebc8f3b6ce62610b02cd2e34e7d42942f87f58caab0a08d34e3539a73d83bb1810d1f86dad147882ed518396d42dda629e95edb7439d9a8be6fd261f5029f0c108c3cade8c2b0e5a0308ed5a3d600a11173ff8e30e6ce56f64a3fe8839ec1da80175b9a6372422588d0315c4c4a8413dfcf4638667aa36c01c3319c0d71280f725c5c3774967b3e70626021282082698d7a1d785f0e1b0c49047238b74e60b1f59d258247e63d7d5376c660224d1b39d85165b063e2810945413d2d2bdb4e0cb8b1a0a8602eaea09b2062ab3022f481fa2b52586a06e2b28bb2ff9ee007e92f5b785dbdc6b5e69e8f51d8c982baf3f074a24593dcaa430ac6fbb8df150cb23feaf8e8a5de5d6c1a63f9c4a90d128c02994e4adf3a495e512aa7ba9ed7c11b1f9f5ace8eb028009beabe0d5eaafa252329537e20f69c715273126b953321e571d6d1e24565ab7c6dfe99b86f188785e00d9fb25d993a6e1c1b16ab058f3a851a08a7264576e9137040619d2ca870c7c822ae226f228669296aed0a0fabbb992ab31f5f0527e2028ee5b53152a2bb1df429aa43af517617035f9a646ea9b8ce40c3cff6b9ebc1970260b68a2a8df2c2decd483398c6de0809cc01d0620e9ee2d16f59c06ca36a029daa8510d54ba818fed3d94f5c9554651aac2c258cb39bd1b5eebba8bcb211791055786940294569b51e7298d2fc8d290bfa8f5862777c0efc0843b9dcb29ab79131a7f51767c59988beb702e0d8a88c374dcfd5cece68f4e56541246a8e21a045781f1d44426fd3a67048e641220d5e678997b62468d3bc11426961a4f784593f8e21a9b397309ec2bbd573fa53f195e667063d1c7bfc3974ffc9b4f69378213c9d0bcf69da7a2705bf0e124cbb1ffe1eac98eb954062ae1e860616b52cf9488e5924d75d497f84036bfe6dd8cfa881b3a39741ed5af73b1403289bcc85e1efca8aa708b930c20244a3d092329abacaf78cfbf6e28e8af6a409c9d405eec489f05c6b7b93e642a7e70a9e90f12893687c8062c511c7477db583bd224eaba8d2a636d083b6103c7a40898eb9861e0dbeffe618c0af50ce5a39df824b1774ee85d6ec2b6cef1d4282ecbd905ded4cba8903853037361ca4836b5ca5dd069923109dd3dc8b81c56c565b908342c6a92f9aef55121c36665c5bd3536e3fa8ea9ab06a7d79391d3642f0a9f13edfe3f0a66971cd6238abdc68a8e092868bea869b65146c99eb5f639e434a253492add48534e24118a4f67fb712beaa41b8cfd37cc145cec2247563b8c1cf0ab0f392115f7b403bb339dd449acd0139fdc4f069401cebc617370be2ee37e313766495d9eefa39bdc525b0aa12bfe53a38eaa97d7b9e82f50dd45260881a160013c89c1921d601e79631a1e8b717d2e4e0a556288f44476323dabb1dcbe64017ba57776ec94d69f5fbc0a86e813f414ee2e956255dc3897a1421e3d29d2150a643106ecbd56a2a4255c780f3f7f2b601c82d33167ea047910b5321779487c5856769980502578ec8aff1577e1293db473af117156342458f1c12f32abdba9421ab21ac1bc1987edb2267f745fb1940367d45ecbac4e6e7d9cee0b6c86457cebd4de99938a8a96c1d81126a89bc664295522dc5c5ca6417d0bac5e56c93b104e0f72deed6fd76825b54a3c1160358103600cd1e390e718a5f2d1cfd500670abfc806dd1bc62e6242cdc78d792a78f81202a45f6d36d2d5ccd9589a0cb3bbaaf97e544c265afff93d80500b8b7bbe6999794eaed921e1ac09771daf1ece8c4e261e627aeda17a47c454e5eb98f7b95f8983731c12f323b86d908aafec63e8bdefc612c7a25b69ad0b1d833d89586e1cb7ee465d27810489c5d5b56cda2089731f7c9a19b76ad2f92e13745f13e27a64b91f6f6d59b04801718f2929865cf8db9dafc61febf6784eabdd3a71b7e585a9cafbab86abb5f1cf77a403909ca483ededafc8003e0bdd5f219da321884623a0d2d8f40d5edc7cc1fcc1b33d3a87c08e0a40bdfc0dd88b04536a1ffaf2a37b99c5b7d204000000000000000000000000aabf35de6c716a3d0a9d90e2abb12842dd26ae29aa6a518cccefc8774e1bf5b717db7431bdb9bc7cd46b94d319f3cf068db8c88c136e89ee1c3f0f906f92364e8f2e8361db7749402ba0a1dee3dd92b9598fd24f4c6e8001781071ae0bdda7eb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000abab7f96e6edca86498506b8435c4e43ead4e08e0b62302e3d5ea0570d2daf015a727d677fa4765aa401d16ef102f06bcb293e29d62c87baf60c6266126888db1303362f148941d1f808e24c41c6d508d7c968d2f91adbc3ae2da48275d3d1e68196127fab5d8e494c8b5386879dc1f616277d4f31a134fbfbbf2e3ddb714b5d03216638d7aabc8f165dbc9d042f8226f018e3a7eef1fd4332b149413560fe3b59021809338221189e38846b2b0a87ef164487df89fc78a8b120967b841e1387bfef0b08f3a3a345fbcaef8da2b6e7b7dacf1d8902e4feeb20f0df5aafbc24ec910f3d795d6e33dcc54da47ec034d57fddeb5d1a5b20a9fe67063269116aa285abd85602239145052e0d6beb3a7c5ed2f4fe417bc01516bc027d264e4401a6658dfd1939022035f3068837dc5207c0f5c96cc98197ef202f8521dfa619abeb5b1e245dc55c031742e08cd7947fae69215a8a4bf89364da1cbf9241d648d88dc5e7ba96c685a1022e7f65893af86cc49f8e71521021f48637f5727d10442ae9289f809948030d05032f2ea2549afc92904da59e4cfe9615749056a3bc1fc8550490500d3a41925ab0a169357bbca03526bce8d8335b9c53929a9f696349fb02833bdc068991df5a2ffffbbefcafeeef2d2f734022a5566c8622779e371b0158560fe679563ab755c4036603c76493bca3e237c5149faa67c579e400f18bd8e74fe69914557b7aa47b0f4e5eca0cd580960b0bb6717844844cfc7cc82d97744d0722027c81f12c0b78b5d6de5e5865a86a216d7284daa91267224c29a2971c6c8bbae623636e44df2d60a8c099043c86826e68126b4af62617ec82093bdd2072b57f0003e735d0a1e8cc690a92a290b7982546b1f176666eeef093f598b2aa96f57fb57212b34e2775c1f773a4ada4d29ac380aaf01ff35f3956108baa750e1227598eb2cc0d9062982a5269abe61b28acf29675bdb83722bdbbae9de18eb4a63e0c2abbc658a5bb027afc22d47ded18fac14c4d04a2c91720b81abfaba7988fd0caa79a846b08550adffcf0cb30bf15ab253605317a2dae6f551afd3f16e09ee50825613df7325f1be3340292827b6185726f4454a868f5659ffedce5889e23e453fdf4837c4694aaa768de951e875a782b123c9288ee74bb6f1183dc95da2fdd464b390ca7aa0a7fd180df464b4bd4d31e1a997fe6f90ac1413c431cb60e3d45658ef8c125e10fd8f40584f884debe0e2d12263aa3fa393d752fe274c2bd314b0c53d5f8d0b57fab9e05caecfff898feb691633e525860d10829c667acf38bc951d1fad00719548570fbc03297f38322626f56da29d540968de17a32427c54f2e5a8026f60c30955bdc765b5b8dbbcd34aa44d3868dae36b9075922d9d44c1004a2241ede0f1fe2e7fedb0d436485f1db59089ff0d271498d741a568b6eb08a01356fce94e92e871b9ffaf191dd3b3ebd8a68ba59b5a7c81ac37e17f4d40c3f71b3d706a03077f1d2756513e5e463e994e0fadb6a2bea3cd83155c1fa372370dd1fcbce49139b874097d948ea71aba12b9e30b80bff2d3494a215897da938264de9df79d17da48d6d512c9a4cfa51f8ae4205eb47a32d08c21b14fb45eb9516ab37e5086f875c2c227be217b773e9f8bb4d0bd4854690ecd6a38ccb853d86b470a3118ac44a21bd2a3aceb47b3633be63ee768718751abd5aefef8291a9fd99e2259d9b0afe5b12f2af901b3aa9418d4f5dff406432bd015a06cadbef0cf6f72f4a2f228b6613665931eb2650932711aae139944be703aa6adcd19a3c9c7fea87190af062eb63cb672edff60081e76dab19dde163359307bcdf1ff4e2c2819e5e2bf01d67f811d7bf2647f926f54cd9006cb4a30da34a7d79117755c397215f9e3c5b5f6b9355774d603296a489aefbc667bfc4da2c052439698d38b9a8c69fbd132e9d4fa477ff17382f32339e341358d35ff49ee3844d083daee9c27009a1724d36c3b269639d726cea4e3d369a3449e54ac0b794b146d5ec6e3c7758157a63e0d324ce4757b60cafe237a02b86be5658cab2008037848a297290652bd39291b665a1f2ced3f640c48deddcae603f7dcf6b222c9ac32a8116f89f851838e5e441e7c4f854e66596003fb6109d60ff4c691c611b2c55b500d94d7255fc5940eb340052e54862fc4b71ad046a7e1ecf303d4c8f5ce87e0695ca92f45fa7027a0e9ebccfecc6daf672ffaef9f64b5d84c5e417e380c7461105ae2419147a9ec6b23389fcdcc8cf2370f2f49173b69d22d7eb92050aad85ff5cac10000000000000000e1a4f100000000004721ab485e31d0c9150699a2ac4e474711cfd94719845c0f74b673e0e95a0c4674740379c046b4799695ae119eae853aa6536f2e7e4eb5b59511b2bf215742f494b1ed3d9315b2af742c6cf27e539ad7b2e76353a759876a8bfcca9e76acfe81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003517a47b71d7bb821b3677bff595a874a5806542098ddee1cc290a05aa76dad292fb830672c17266ff0f2054e4be6e31be1d8d1692ddf1a1d6f5cb3c16a1292182c50a969c5f8f36d6555c9bdc37740cce02d9556a6f6f61978e67b00a5b2230376543dd942f5e631d62864386d70c47b6f6d416b1a85c5df2904a74e7c45ddc0330091aaa5e15b515331d11f9df41df818f9b1f49995e06c9852d51d4c4ddf509022b0afe9ab7bca7890294de5c38d7d4f4bea14adca437508e6bbefa72d0a8a5ad0a0258727f618514771029e4872654539c3ca4cda17201b602a4a62703bbc0a772cf62eb8566e4397d858831b0a0e515d3fb98d9f0bf8c28d6125f8f8f34f8933f030760a6fc185d9ee0a978afb5e53f8ac95bbe95aff329d37eac7724eec01bb293032c224714169fb4b732bd160e19c9425966b1985e8fce22724a80c945b63ec2ea032138a5db4f373654f58dbeb88b76a4500603bd9fe4bbb306af5beae9e5bc6df4020a6b7f14fdbff0c97edb6a68ed577baccfce515a773e2e46600b198451d27e2b0219f563289fcb9a3ba4a9bee61a03188f803734b3a33863a6d4f016352f9394aa16e9ccd4040a5204c776b22845d954f484e6132b5ee31487e0e8cca1c0a0866bc9464721fd2fcda370f13b6fcc0378e6b98b61da1dea7e3b867c9cc84cbab54d7f2901b1b7cc67a5e615baaa5767edbc0b0261edd92f0ada48d3eb0217e18baa639cb62eecd56c788d1ea0eaa893ac976bff1f7a3ec9572e31b944845153c42920b827d17652a8297f4593ec13ff12debb223e694f3dd8aae7e255991378f57e3523f8c53d020422f33d32c54e994480db763cef7029924a022cad0c4c2e6d1c6e44b02acd565474b107e62df0cdc9eccbdd1508a546d2097b49852e4bfae7a8c9d0d934799c614fa737b4b10e4a06ef00e4f23b891b6e85bb8001f3c58ac1d7deb2b4b7b9fe4ab79eeef75a366765f341daac511e64badc9cb85cc34a3e9a66dd839917414c5e64509551eee4a42ce7d57b9876ee0bba0a97f6d459498742d68ea0ec9754b3ff0af0719c89006b302a995e498c7ce110af3f40f0011b4154129a5d0068944b66736ed334293d1f0f0dbe53e67c122c8b051d8f184d536bd9e987bd8ed89d01e8fa0d73d1a416e3585fa5a6214965a907eaadaa6aff1949aac8e597cde4e1dd67b4262c0ef76051ab1278e1a9719fe68fd5d4d32c66b96342308b60c15713a2e60bd7871ab287923c58ae42cbdc97251a89f328efac58d96797bf63ae087e79bc85a1fd755134877b436aefd65ac1fbbb83de3a439e7695dc935302df5947808fbf9afce68cdf5de8d18f5ad9959ffb23d2ab05c3160255ad928d9d46dbcf1e9a2070c479d42122f581ff750ea11a3fbec190f779535cd0c3cac68b68e9627b88cf8eff9c94db0d948c24eecc39ead8527fb7208de7869fa8ea94a718d9d0552a2040973f6a8e92fa0cd6d3df4b88f8487c98498f9f0b383239d66a151f2ff0d1db844d783d5d798aa7a98b6abcc758150fc675132f3eb9f20ef7a07d4bc46f805f5c3ed364815590ffc64169eef887b10cfefa7e0cf09f38c0c37369647159511a81722d69806b154877d16a56dbd1a52c535075ab3f5d525c8d5b2256c68b78729c751a2e2b93e7e3867c7f4c3cf14a51f8f47544d18c0b30f48ba366262c51f9959ab8c5c20ab8b75fa305f11bdf7920357ed2c602f162c4320141d625df2328b646abadcb18ae320f0ff9bfc3238f4620f880c06f2c840933e210599d1d261262db5475cd21d5570f213ed951ac1b19df2db3b6597ed2ce293f6ab8f99e7e0a47248f600bd75245a93cf312a960d6ceed905107e770af724e1529334e1614a430a768560fab4ca5c5db23ae32d07cf64f80ad35a6980cff2c6f6a0ec554f4c0f743acffe32a21b54654bda07ab8f224470903b493cc8203cd5f97e94ae05e270db3a55779efd01c1c690d9b0c464be9d552a2065d39e867ab5a951c6e8c148aada9ec9af097cbf520d644292cdac25e7ce1f80ecb90c1c8fca50aae4ec312d6b439e3727bf7423076b2b844cbc6a368ecfc3d0cb2acffac4fe649d59c9db9691f063652fd78a4628e33167656e8d78a381cfedb43cb2565233c52185e6f7262199f4fe0da2b7b5e18d0d4504105fecc0bce3fdfd7207819efe57c011304b7f023cf09bdf9590eee5513b30c1f19ee84c07300456cd1850421c39731c088f33b8f6ae048f96c8eed7dbb5cdd0cde4081fe8503ac0a7460f48d41054ff8b7422f4f889aa507927e37db17a2341f99fa4ba441912a2a1fbcbe8eea6019e92460fa086f4bd7422cf4aae303972fbb98a3d7e2ecaf1eb5d2d0e9be5112bcd136b25170b1e388c6dfc74d867449a1b1f1fe95539e638ad2346f8a99907d5fcabe054397527b1e3cc3d8f8fe0e", "", 1, -1252882616, 1537743641, "dcf90a7ed146ad8784d757ae491e313018ffe7e657be01718087128f13ffeb45"], + ["030000807082c4030382da53b5415706e735f90f28c793588a3f85c6741ef82bfcbf9094708853b51403000000036a006affffffffbe0d9bda919631b6e9348e4d3dd966cd42f11836d6edcc06d844b1a873b5e4f702000000004e1e931c5ddbe20a335d79789c2dc56080ccf732dd89f53be468d95ac5ba8e00be64577d02000000008fdbdd890340eb800100000000020063d91efe0400000000016303de2c02000000000365526577b1b57b000000000300000000000000001f0fce0100000000b2442f37d3f040ceaee093ab12fe5e4fb5491fb2505cbe6bc6cb964a2af60569e6edaa8805efd6ec9d27e3ce2ee27f82e65711eef130558ff8d8dd554c86274e3d4d49aa2ecb563de9e1ab7283f6ddec3b01d3a6bc0774fa21892eeace4d270b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004362130e3537174fb76dfd7a9c3f6b7794d62889523907f2b6debc35c5447ad6305aad76a2d0c84b9c719161639f746f0f340350c4429b8582e6d60ad2ac8998b208fbedb33c21932a34edb72482acf9271591d262c475de6c3b752810837d6cd99dd149d8320875179a5bd7dd451958a6697429bb14745c38e7ecd90076b9dc0207e4c3bf5d59c0fdba4394499e70d6d00561b6069520b9b565e68e1d0fcabd8d022824728f2ee82d895364cdf47228f31437ec740e71d0a876b6a54455a587b9430a01bf7e3fd802b23056e44bb814b1a7312810e4cd4c8c9b1df65d6957948ef7ddd2be36f7a5b4aa0cad8352e9acfdb0f4746ee0756bf9e777d84990bd35b5f25c020bf5c44ff346392e5b6414f8d4f97f7093e0c35a1c309f0eb32bd7f4520e2b720322d3a22aa593ef5f86e30f65334cdfbabd1dc17529854f07df2f4599fdd1a6860300284d09328fe6bdc49cc16589675a674821f980b0bd79200ea829e04cfa54590302851ccbc405adddf11419c5f9bf1831b16b5abcbb37032553b1499bca3561c0031b6ddfb7c567822c9ba72cdd7130c8a6062996a609a7cb2a358f5dc4fe4948d2e09eddd7e5e82bae5425539cba825b4f2bd1931b4aa788edc0571e036fcdfaf86687d907d55b7d090d937c689e4793a5fcda38c844f0756f7ed21b354846c6f451a3deb7639ee46d28f49e68ad8913d03077d0343dc61dd95ad1a1e6944902df63802746571916120fd5f1d0dfe772964449ab4fb7719943e1362c30ca961f3ef939cb8127457cc93b661dd5580e772554020c89c7adb9304b70a93df52f8abcbeff8b7b0fc0e07a585860d06b37228cd29c4e60e162c39dc3bf30cda9dcc7ea2ba1f36ac6aa1ebe3414c696e16591039bec3b12f31712d7f44d2be440cb9d244787ce41fc0897fca0f18a5d626355e9825f080c4dae686958e42b91c89f8623e465cecdc91a42fe9fefad2a9e74aebe2d00fe314abf0088cb9c48d726b103e4c09ab2bae0f91f666e53e2c6e4dbc29fb73fe3d7c87d79a40e4a6d899f993c13ce466201dea4713ef62543fe858bb20d13c952cc9ad4c3c66e86260cec64c83b0d6bdf6fc15cfaed419edf955a7a60236ca2040ed64cc24d46e2fc520bc9e81001de55bbdc25d742c9264be4e1985685bb56a3a67b0e890457390741ad19f4dbbdb6d8dab3e691270b190e7fa4e18f658c339d894a05bbdf37914cafebee0285441d08a3555b8459ab4b125730344d955f0298768b5d5a67dbd71ff11ac2e46c94c7c90e3fe7f3f681457b76f71e647c94dcdfaafca44a5e4d82d5ca528ca61935369e2673afe6296e1d997ab8d7605643171bd0ecde548f9b8719b0074fc639bb07cb65d3fe112351795f69a03fdb136cea27d8d57b8884d1924880d55876aa5779d1dc8b5b23d9cbbe5e5095c2cd490942533865eac066670cec9c4c9fb0dccb617c15a95956ef9cc0d317d44f3690e90c449b69050107cf9542b28d0eb9f7a882953c2313ed8bae1486380d7d1e765bf16e25932e24534d0f5e6bf4648b0e6f062afe898f9c00a18777260bd61de2b9546c364004d217995635ceb726532622d5663fe26e6ee3540c9a6fc85639e5b050970f2b759853d1c6fffc1c984dff05a7099d8ebe30ad629fc516aaa93a5deb0ea4670fe92cb20a9d1218691b901d81e75a09c6ab9ee9142e3f89cd32371538ab3498115c55de6f50723fb681a0068db321316d5d7886a26c9d53a765a7b6e65ef40b3ea4163799d0ab3b0f064d9c249875f02ffcb86b19800abe6fa289f2ebc9c79803e0a609dab7d250d05aa94bbc1865bdfc4482a58214557bdc85ce7db7569d15b02c0f227ec2d53d0100abef775b5130309a7a06a5d66d13f62ed167dd8ff0760d0aab00c5de7196198a4ecf75de8c69725ec837ca7a325923efafb47a24118ee4941b3d5ba3170bd77c58831f303debe3ca876552401e7ac8792bcdbed8574a985c827a2a75327a65a10e3f36592eea815ba3026cb24d9b93fa3ec0cd4f6151b4eb240b64b248e27a29f3acea3a232711b46327ec9cba97ac6beaf564c4616d7c26ed1c6973ec1984be6ea41abb717b611785854679f1eeb1006562c25de1275996b2476f75786b3c8a63659fa6d4d5a9006e65779d399e972358a091b0091ab501a321de2e4df959d63f0108c090b0c20b84255e1810e8a80cd19f90274bf4028f5c0082e29e4581d5feb100e4b8e0d3311b0fa3edfb44724dff95d8b0df9f12a16dffe9d939e3d31695343f9e034f711b1ddc3a5cb14fdd26a7cc81a6cff1eb0000000000000000000000000085203a4e421b0ed30bef8e0372053b39f077ed5603a5c625bf0fa0d8909a1f84c2337a6838205069faf7714dbbab5309400f0abbd0b40549dfc0596a24dd19435ecb54179dc30cc6cb3a5501a56701b0d7d19032e3dea6933d13610d31829a3d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3bd10df2ae8921a3beb1739ea09af53a13894cfc404029c16399ccac5cafe5dea6df71c6c0b208e0acc9e3f171adac2bab02bb0a53d39a30fe0690639e329cb6394a135a0c2e38a272ee8313d56f3841390ebc965f28629459138f7d5c9db86bc70f1b01ffc85d8208ce8626cf2aae6e1a939989a3bb971677eb8589fac97160323f294380885a845b62bfc454398945b93b9d4ef0071d26c68fe9e176a40b3de032bc9b03ae132670f6b4597e44aa6a4f8f473c3cadd25adb6ea5f69188a5d5b6e0b028a46d643305663ab0ea24ff9bb06567ee2fb3fa93cec6f6fe5607c2561a2d4409334873b7c1c9552da923a568eed16929122a272ee6117d4a7fb7301e29d0f030cecb5732311a8a40156269320f9351474a819e716af779e37890d2171593e510215611f207d40f560630c725a35a93901438e40f0bff0527182a74bd277c52ab60215bf07107a771566dead0ffa708bd7b2d116d7a9f8da5cf455544e31c46d5492020526359b4b7b1254ccbe61cf2b92d1fd8e4880c2282e4dd5d34969f68cf3eb64032db7c4eed1ea31c1cce7d1d717b85122a3969d2e910fd47a371b5765dca455e6afe7471188c21825a79e7850cd550ba4736793ae90a20ec13b95e7e0cfc981ac738f94667fee5e64dc37477111e60e55c0ea9a271d113ac83a9068a2cafd78ff106ba443c5387ef096e80aa59df8848a200797a5fdeb11701cff2816be79df54a9dc50422b76a7ee9038c946139814a4b49ce8e32d92aff749b3f110114a086813d8993c00bcd3da430b14ac40348098e4c0e204099de43f3a72b52e80f0c099243259380f1224e9a21954d0e69c4402b7d1e1415a1dd195959c1e1658b691abacfde851e9b174eadf5a22359eeabd8a41dce5bf4b6aead865fead55b4033b417802d036e3376424b66aa4407a7e88938556128429e6a6c4f96ded7b395c772272b89c56feed89edafe9440ebb5898193265f41530c411760dd325326e535e5bd0aa5ddd7a463f704c45164ef44d5c4a95e4b54bd679193af32a290f13278aaac3152ca47f0c514272b27d14096f7436b8d1455778615224823fa84d08694273c21e89c73214708e492515c4d323be0af7a2ba54a1a9f0b752c17eeff0c593ad5b4578f6cfb0b377ff445d1d1215c078157935928d98a8389eed8acc7f4c8c8b596cbac5a3fa7fbf724009ed791e0d8488bab05d8e5f1789f7c898049c5ad5787d194b97131fe3a68df1633d802b1f7d6604dd1e18d4af4cc559356721090b0419eb453a2cdf77ac3f4ea0e3285005c3efb3263ebd4352751eb2e3c38e8b6e11c5a7beb542d993dc4ba421cf9fdb7c363e79bedba437dffefa39c4bbd4f6f231d8d099ed0edde33f967fe9afdbb1c5ed353cdedc6bcdb4d11e7ef0dd7e0a3d78aa8c5a0ddac04bfa57f525a4f71f53cdafcc6a392e91625555be49e5a4f9e9f1dafd618ead06922ab96293b6ffe395a775c44b0fc84ff0b822d24c676aa1a11183aa68a85e3e9d22b82210fcb74a4bebf5143be543de76ba3026dcf7a52c33206768905546f69ad25fc82404bcf3434d96c303d08f7a9f8a9ec1c46ff732e555d0e77271b2d81cfff37fc414a56bcfacbfd09a6e4ee096a9e01198a9c0642bf6cdaf8f92ea742c48dc265b0d2ff07bc343bae705785bfeb30bdc35d29a57cc6a22a0db5bbefd2c56f9d9cb913629efae20adba4a1e58df71bda80164745d66772a7fe1361d76e4e4389ec1f71cfe4e50d9986e2b507b2c3fc91dbf2b12f0d30bd2eb1a8dba80fca5b23e4f694d45a3c20374035e9e27c2afefe89718cb23ff2700421b68ac6e827cf4ad65d97d1cf19417e88dd40e9b9d7322f16e8703a0ef2be49f6503e3c32a7dec27eb381d41817a3b388718d6741ca6cbf0326cfa667c0f03afe7e69777d24428ef8c76325df1cb27500f0418226f5e4d5b9240513650073afece771c18308d24b664bdb897e0b660ca48469e74a01f0651d1ad0c6ba00bc1ff799e89e5967bbfbf75bbe9355eb2b42e7188cfe472ce5ff7cc042f4b71bc4027415c98bb9116919f7fe6ba9df8fd2839153504f9c4e7e12428eeb97a89149eddcee93c92e9561e7231389ed679ab3a50f8afe065c0238d0b9964b85dbd03dccf13cd91869a21c49139378055d47a81056eb83020a45ffa065c9310aab09de2d824676cd44728c9e7561bed3a5944ab4cb7fb4424850b8d223c20fb8957d97f5caeba04adbae3146f4231a07bf6169b407075c30cc419d7471ec4497d4196bbb6ca8407a67ee95bf6d6bb7ff3490f7af500000000000000002b1ffa0200000000f1af54d6ab0f552ddc5556b0e78a0736b63a568b131b46c1723607bdb2cea61661f6e4f7a3fc3f37702fec58bcc3a135ff9d7982cd151600e95bbb34d8743fc74e28e060986213daf9432ce42cccb3ab3b7c9befa8ee8abc6c37b58af0dd43fa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d276d6edccff9504c4ce5db5e2f80ff75520d5dc44895928b444058ec1df780931efce6768d9a9885929c736f1a66d5df41dd8944f8249054f91c38c92d6ef0ad082a9e4b90eb8aeb60258da1939a7d2ae90afdafe4fc0bae25fa4744d6d9af338648ff85acbc7e012fc63aa1760b7d33df4173dd386acb4c3f9f8f05f78f5d022f3a8a1dee71641558d4534753d45e1b3bce7850831c11afa2c633e0f00b8b59022c8d9e9b70d37587a55cb69fa90aec28eae72df3470199b7fd3d9d46888eff2d0a04698be5e94e2d20bbd8e34e228fb72803fb718ef2f5bd42f9a135598cf4b5445b7ada7c9b5003ee998e6753fc61f804eeeafcd28947e3d37dbfa386d0ecf77d030d5e5564308400d1fe7d9799b8b497281d5f966c48ee08adbda259f883f9687e030804d4e707d16830d6431478085897ea9be6a5f6fefa1c3e62ee737ee1fe88ed021c0ffa649b18ff81c1cc03b927ecf78f0349cade5f97ddce5cb1a51414528c1303254fad1d25259659210964876bc2a9547c6accd328c442a9be8e2053c212ab7f021d2e16620ce3d6dfa97fe660ed54dfd77d79cc47a49a581e56f5703a95f73b8d9f277ee5963bd10cb20a596cd66af93a4f8ec790a30e9d665d0d3dc5dff88fb9f16fc94f3696102959f5b0edacb4a5d806b2c6799822cd4378a7e751db7d263df9c4a8c3d3f67b25d01e695825e66943b5f81bf409c22ef5bca31e59bb06605c6c00c81fa844978aa14b50ed61e95a60ad96cb9f8cebbcef0cecb2f08fcd7134f22fa9e7120c56d849e5070e818923b680786ffd76e0af7e45f55a5b0b0398c337b7fed09d73ddc782b004f614c24438519fbf379cb8a4b622d2c598cf3360cf9f2017dd06e81ba733bd4584dab2f412e5240a991e7ea5b50384268d9ae7b34757995b7f34211d70f261f50a1115ca20bb7d917e0cdd6be3349880c8bd8ee73fa83f032dbaee54c702168c2258515164e48017cd2024cf5e5946b225f3cb745ab0c570a31069d456397e7cdd0ea232a674f2eba5075c69ed243fa3ec209b24941b8f485926897424475b7b17e0f4d806e5a9c263bb6fdbd876986235a7a92d6cef1e796767ea3201c153651e14b02fd765e94b370b054ac702c151f717d5de8f32c0f9b8d37c23688dda5a937a8926836a10f297837d9462315e24b4380907087939bdc5d4143ae88e2104d207280924b0993e4723f62709f4b84e1de679c9d710cc38830421fcf0ff44cc03f41fe685de9460d43ef8698915f445de74f9961f7d5f058d95061aa0772a7db397af87ec2c42e52afcb012c69b032391fa1b654a7b404072b4e6aa42f373fd072c09574aaab2c293e4fe662cf1f65b3b1ebae9befb9f33bba603c126c7586cf643ad435f4427f6adb1c9171d1cdd39a4ee03bfa72a2235db8958c72f41f801e5a85c278bfdae65e194d6b52b255f77b4335690bff375570e9550c7dc1728eaccfa428709a27c4b06e681c532c0313366fa74912e764b5b4e7a3b6a58826df0178209bf8fa262c3bc57bcb434316b19144c138039720b1ebfe1b909c8fdd46a87d26f94b9a8f8d8e3b2c7687b33442d075928eafdad2c5ac53b8d7cb24d4da43871b7d399da0de10fa1e8c0753d99f03e5f05ccc4a89ee0f397a9d2af9eabaf7d6377a5c1502048e2ef746a38f1e5f79b4cfe7ab7285816b2d4a7c7fe537f748877117876fdb1453afd765daf9e22da543b4c76277507ff4c13816859a87db77ecdba1e0a252d70d75fafcdfd2ddb4561be377d63323010513827d311ae7d91df81c6ce44204dca51178896dffa50d067dd78d30ee2b5a0a1886990efd4eb970d2a87f9dcab89ae49d105c35fd1f9a488dd533dad984e24480c5c439c83b4905f64c6205e46e871845aa7fa7a0b1f3b157adbdcc5cb97e3cdcc95801bc3f49f0a09fc8f911d6ddd83dfac11db7b8451b0ca6707b49fbae3c94485ba32a21d073054e9078bb40cfbf18d207b71a6b71dfbb3f70f269718666ad3d0fc63325850cbf3d5a43b3f7f87272f2a801b70a83f2e6f44ffbae9ec3a98bc6dd8e8d16328eba2e303b4648c408bbcd135ec13a2067b47b7bdf0e90f69e983e17570524e8d9924aa1ae6f72d47928e8496e6d66c148ac9c74a3e627de969984308e313b3b3c216dbba8c3ef2927d008d362089c56c996fd38ccba14d3981ad4fed98b4b9756480d4a68acf03d3c66e7f448fbe07daaac10f49e35f6f49e56c6d65d9dc27eabc79f70b02c274bb36ba70328ec1064a6d083c44483b470246dbfe9dfc1f6cb77d391c5ffdcc66f6f603d8cab8632e1c439ba1c0c7259fac3e09ecb21a7761a495c286b32f686e9bb6ee6c212a7357cd01727ae77e5d9e1c280db28d01020e63930707a241db151ee5d49fcfdca2e55fe12ecb360be397ab50b5123aa4867e0efe7f1ed983c104", "52", 2, 200400939, 0, "1be0242883e4053bd417d5ada455724414dbc4690b0f55d04c15a3f0f8e093ca"], + ["7cedf330044e90f2592ab42d78c72851849411f176445234fef4de7cfa4195e7e23ecda465020000000752635265ac636affffffff7e7e282a6b145cd6889b43c203a86f4ed536464139bb5ed7e399461bc9a61b0100000000086352526552525300f06cf15c843a55d5a5fab5d6021f639a343687a516cfd5f9c63c396311dea26dd640fc1303000000045300515398b9c5c578b5c9ee1a1b3e988975c1d7b2d0b35593b731c6bfca280e7b4409b799fecf7d010000000400536363c0278e8703c2cc9d0500000000086a6563acac6a516a4c056c040000000002635223eb8a040000000000a08a1a77027e241205000000000000000000000000aaf2b360ee7485651f2e1c53e5a54b28ae9136f382a0821c269a49d1ac87d32b700c1de214ce629e780375dc810afb927c6a0d5febbb348a52e215250937521f24f25f5f6fdbf427399712a73f31e481d61e869553893bed8af738e7a90d423200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dbae37e80e05e223a155a88758bad028b4c78c4af5707e68e967559305bfedb987b61ad914450aeaeebfdb6ec0d51d474cbe837906f2598b7e036270db3ad9162eb5a6a5faa17301aa38450da72c31fff94df09dac256b4d5979b23983d2b2b7427d13c1fc28c4c7f159ff92b1dded089feb5707890992361cec0d925860f9c1022e33176a95348b18ca7124cda87c96f45cc0af9bdf23eddb1f8ef540d67b61c2032df7f5bc64de54c03bb04cbac13a2a72fa06ce881446a949e923d44b213206400b0212f083ca7d190dfec599c117b8c14e88d6a09b4ce4aa2ebd2030941bf17a4d61ec3f23279d207942b2688ff5ff10f346a85f02e2a0ffa311f9ed96a67a7233032073657b0290c998dc9fb0c0a7ccdcda6c42bb1213592f23e54668bd4608a680032eea31e92f2c01c73166cee68a4cb99820f54560a955340a5afb0afa09809783030e894398d0aba25a45688b7f71c72c9019e712a17c5b7402a1d4af1802451eb0021410e91d7e1c109d3da39b26a2230f8be7ec1e2d4965851bbb2d6e809c96941e03020c98707d237d06ea2c6d955c86a86b64138a46a7f49729958860947513a5089cbb7defdc60870538bdfd0941d301325b49d0a187a5e1bf8a87068e44b403952a21338ed711027d0785623f4bfc19c32f496c48a8ceb45d5e5cd0bad90c269755f6eb1b9bca74c5d3b3c8b991de1c1c515926adebdd32a9693c726dc09d396c1fc01ee6a4365c41f218b4347335617cd10dff4537a060b015c20d7abe8401fe67b55a9a0e974acbcaf85d56c6ad99bfd96fda41ed5549fc3236ef0013e8b92102341bb45a6933b488ad5d02d7ad3d46ed1580e10c7c2876526a2ae23e535c79b6eda6ae04e62fe2d749bfd40151f8804577f3edb755ae547b11ec00368c3d58c347934b6fc3b36657d173e4b0baa92f38abc48f37dabdba42e34bc77e8fa0b8a42f67b8b8a4e5c8f170166c62ee02fe1404480c539013cba291f3a5c6b17bcd7bf275a1d7dcd0a17791c9f253e80d1bfc41e6de1486a5e01a7b8fd09f565f8d58b97e822e7cbd78746874a1a01abd5be629e7c7688f7e52636dcb7efaa05a912a75afa7740207e796148891ec69ed9c22ed25e151aac8697776ce648bdec700ee1e39811c309a1ddef0304604e8b51e961b606252b45a386e603ef10732a84491c7e52273060ddb3f1801c7ed3bf75a5dafea7444e1a1dc8378ff8560e631685be7a0f65bd84f68f9df1d70adb95595ac85a7c4e7aefa815cf87d0aa0ad646b53756ad6298d96b13b0828da3dd35a87e18c628000d67ddbe226daa52f1a6952eda6b580e4ec89da1b31718d7ec0b3d506ddfa881fd033824899a20376a8dc17e491388ff1dde8476582aa8cde8176aa403b1d9df12c0032e2abf4735bfb19bba7762c56173dd21167313d34ee3abf338472e737a77f5f78456dd95eb8f81405037564bf734fb9463eb1c0f24c0b50d829946326638d319f8ee53f6c6c4e3677adbebfb9f392a6ae6417ba479599984f983a0ddcbc5528bf9d0242dc95d4ec703f2ac6b44e2d9534b39082944b1190630d5e9d0e6267889315dc114a399882bc9cb0fd27ce26ad4e44caf1aa44e8880d9ea2e513910b51fbce9c8f02bd8ac57479163b20f5f08fe386b1845562f62b7e2dd48cbfd055675d68c8ca601e77e72b4119f5256227b0b339f7e61c4fd673ce7e0f39583b884a9d4254828f85348fef085b0c978efe450c29fc129c32f0faac8356c4eff8f687d58ef12f51dfe21d0094ea9e3dd59fa1607e9d12fb341f3b7be13ba9d54ee7a5b845d094cddeb0ce5c44b335beb52ef79478be0a5e19a83b85585859d017879c322503647d7c26a0b14caf0c5b8a34e17668b4f822181ac8158bdfe39bbf1bf68f5d6c175404c68afd297a4ac9f539cdaf3ffbc8457349354b969b216d57ee04bd7ca249f748b2e5399c3b10b1edec483119449115dabfaea8bd5e158d0fc4a9ea7c799ea7c3438a9d62e1d30b1126cec4aae2e0e21b72ae27122915fec4f7b1628558b5564b640cfbc28d3dbf6f5ce8492a57274db9693fb640b4b6414df15fbe65a6efd9a1ae17315eb0da268f7c8e63bf05e4e125c7dc2fa3c733a68211dd1ee0bbd537a0d324a6df7fd0ba9199aaaa2a263c804b2baa9bd981508f62b84cf0786edef6444bbc2c95eae1f04d8808a8eeace1713923272dcdb718302db29f5080a88db2d40a855a6a89471ba20c439a2f07bc371de9c638fb69c8b133badfcd6d2a9a4af472b0c864ba2220290ca732404e79b0c38779ccc28fdcff5d00000000000000000000000000421dbd54dffa1d831fe2d158a47b35ed72bbdb43b16c9e852733d6209de395c1ea76a226a091f17c3a999e17cb4233b64779858652d2bb5b0efa96a1138a1235feaa2c38a0be3db7562ff01faf4188cc3b276bb10b20e385b60dabc36ad5e3a30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f9876b3f5faf0234adce086f10a8059d00def858ce2a194a032025594c412813b36376f853347ba0a24747c6904084acb7ec5500b5cfe9c004a2bf0b405ed1e064456351f8c577e2f38791b49de0e2862a9645917a58fbb9570b32337955756710d38418b33f04b7579c7c64828e9d20a86d235876ce151ca9261baa074c45020a2d18d3c375bc8490e28ce640bf6725d8c3662260b4478624c4dbe33133c08f03117da05f3a06aed234f6ecb17d106ae7b92f2d74cfa8e4d51ec4dbccfb6267a20b060488cdef4444975d75837d3e5276ab0c606396f14d5d5d2867728e657ae79e8c0a7fc7e9b958d513a04c17098c60a05fc5d4c6880ee42c41d4dc1b48e674c60212f39b3ac07f5245f3e9cab068c24e63441d47e7b46107fd671e227cccd45f8d0201968fdb81c657cad6cb4c75298e5f8c98587ef6d12dcc70cf1b349a11215002031dab641763866efa5cb2ad1a9e0ac0588e1b7612a6d49b799b25307499dc5fa903062becd98961094543fdf3f8816e63705dd52519e6d7db88b31a763c2aeb7c09021af36c09d02e8b1d199a2bd0a48c9610ef864b3601461bc69c98f5a4d004f6105b88cac75b8085bec1cb5e439242db7bf9b669231746f763a990d655fd01e674bb57b5654cedbf7e3002267006d10ca156120be11f0c6c54c4676cad08d39f7d7172c554ee395efeb5c8f2da251328c01018ddaa44e8b6da738b15b1720d66713120236612021f42f91bcfb275c155267c4d0db0e1b90417465db700584e8024b61f7c46e32dc02737e6d79a12335157c0139bd2652aa9b4a110a34214b3e04c0dbaa1fae22bdbb3d6b28a1362a4c7bbad79fb12e8e83c59f87442050c4aef9018615a7f4cbb07ebc7fb2aa8860504d03ee013cb47117241fdc6337a4e7d1336d4e6b511f04f2d4d9f5276c06919dc9d110427ad07b824e4922056dc0ea1d6a5954761039bdf0bb2d59ff31e8421f6f55a1ebb4e46489d213a769210f3b5f24649ed9c22ac73623c14369a29916603513702cd0e4d7c5dcc0bc4fe2abb317c0979fe4571211a6519c8a80faf2ff74b14c98428376d2d22e9f07a4367aaf58b18be8e0b62b7f231d80a4a660269d7c9227eaaa987463654dd81ec1bb10a8bff9832a70568e31a514ac3f7adadbccb5dd1365a1ca2fff1fa53ae9d95a8c4168260931762f9385fbb80dff12e3d9bf7ecb24590302b6b3ff7602473e7df0e912aa0111789d0231a86ec514b3f9f2e2d18b4b1ae084e6afd13985e3b6d26ee05f076c8b1b92e36ee27bd268069d24164e15da51fc867778e7323808d06598df39cc68ec6957e8233874697afd5ba7a6e41636756fa0bf76d1e54a4f9ec84f1386702af49192286fdebd6976ae434b87bced9b05d0b1f572eaca7ed8290c7817f8e2afa2cb2058cf4982492035295c576c129631b605e9d9dc192e332053ed7f454ae3c512026f229cb5ff7f6dc90e2774f34fe1ebe49e7e9e4f52d3227639344e9cb06ec29caa1d4b9a27ecaf5757d993660a0fbce7b66eb8a6980f33ff07026d5a7add684352c47854948197fcb77779d82f3c13e8670e0eb20cc208074c4130ebfd927ea462ec0b15b857c903df8832d4de1fc1d44b064352e5b29811a31f8b0213d9d446eab9a1a89ec735bd43a324a1b380b47ae4ff6f9d1d1e4268d1fe81d166c30535eda06f91652458906e4662082d5844f97159a05d91b36193ceb3cf4b6934980b955e6fce8954c9bd48d26da35fd3b822de8ad491edee3c3e127cb9b1c3f28330998e472eeeb0380d2c592fbc068051e835533ef95a93e39fb298275a42cd2d0858c6c9913be5909e832bfef683336c28df46e72e0df453dbf1ee6d9a0b9cd3781fbab6d45489f5667e267a443445816bfdd957359ccca0a936a7a92702108e87c01ca169f3562706af3a2e1a253a578b6cee2b6523afe51166ecd4c633233fba2d5b7deaa5cd5f98d1e8d7b8c1fb95b2a433f947ead63811b56b145734848dc07c5c990b67b6c5a24defeabea6ecde68c3e4a46db0e149f0afab950d292470bc31dc0612a17bf6db7c75013767bae84c8973d8802406cce11703cee25ce89c64abd1b465c4a8d88bb1e462b13e9fe2f3607d9a76d85e90b1c6f596bcab8a12becd94282747ed8820d8fe9d49352bbb525dfd61cd86300cf2ed582a57d96c9e3a1bdeb097e005edf84de3fc6c294fd9c3d1413bbbe9de4251e1e6378dec70961e4ba809ad8b385434f059e0f128b44aba6089b9b201896f6fd0205360965a66f84e6373b1fe480a0c0fe2acf9c02b39dd6d098d3944e33c618409c1bdddab86e3e98fbb9253d2ac0107b54be88a20b951b354babb8ff2f13d2d433b9b6a8c754a326176310e89bf51289bb14bb9ae4646bd2be0bc3ef54cd186b6a1ea0930709b41d3f17aceb8f9af9d3c312c6610b", "0051536a6a", 0, -212402746, 0, "7e31c9f2de205ee29bea902503e2294febf8221478886612d39f5c1f8db5a783"], + ["6044a8490331f974fe088adf77f3f4a2220a6cd856250b4745e0523f1d6473a8e0c9ac83a60000000008acac635163006a51e2ceca54f7d2221ac2f64ff383986ef8fd627d375d96c2a4ab29e0d35bb13fe92db23f0200000000085163516351525365ffffffff2549397ac50c741596ae4e2396b0d8869439808c9613de7503d452549e8e7aa80100000000ffffffff03a95dc603000000000100ab817600000000000865536a63520063538c6c7404000000000863655351510052520000000000", "5300530065", 2, 1244939269, 1537743641, "a40471670f6cee6d10a2f35223fbf5d4b709a8d25349fec77f8ff79d50a4fe34"], + ["ce90b24c047fcf1f8a3b04ed4d3a5a05782531faf3dc24abebe7ba5e5b99b5f1e7a5e8a3900000000005acac6a6500714cdcbb30b5b4520bffadc708b3cc315f76b782dfc1c231e99778a74745b3c32670ed260200000007006a6a53ac5352fffffffff2689311f00ac52ad0cefa9d84aca75a2e0fc8b9f9815d5b9126453a8a9822ae0200000003655263ffffffff6fae4144b16aa8d6d760582823fb6082d3c9defeb0874a94e4effc3ccf202aa5010000000752635363ac6a63ffffffff03acf504020000000000c9c69402000000000300ac51c57e0600000000000665ac63635351f6b0c1f6030000000000000000596edd01000000002def07fa812b39eafa1567aa43bff6730b32dd358a6acb349799c070a3e8eaf6421270be201ad8c8971177efd5d17e8286850758b8f7ce2e745be4afd1506f1e702357838e73331bd5db60df56798dc21f8606cc10c5821cae9dcc0ec0bca7950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080c701da9a9e6d45b417a393d1488abd377f64c9b7ffbc68199775a71a91120bf93021ddafef458a1636640dbf14e400b7db5f1df18cc9da72fc4473d6d4004d89beb0fd04e2982c6c81faa2951fe2167d4de64e8033764240f1e56c474ce02786075530cf9d41433ab40c352b2abebdc99588a419fa46009a7edfcbb9db73c6030aeea781597816228bc6be948b38e0a49765a62714f6fbfed9bad9acb31c1b980324ef6b2c71227949aad85885d442e5631631b671e83735b9f8e4e50d5da0d6f10a0116f282f4aa7d0e1e6f2b0f1e42e93d78042213d92c88ba681cf2033f02e2b09b155d6a318db0a9f07979ca48ab283ae3ce9e44c1b8b1e3845bda1c184220510211eb0663567f059eb75c5122dbeefc627a1f393e672278cac0415b9ae0833a81020e8fcfc2b4b6736027deccaf3de652439df236b71aade7c209c02b41d06574f6022af8eb7158e738c757b10d76d1ddd2a1d304b3381e40b16bb48024f40bf97a330229fceabc38f4579ea22898f724d1461bbf3c5370f10a9ee8465e2e4677fa2c86031151b291fac9352ea1eb8b1af7ebd33905a6885d8c7d60a827e454deca91108c73e96be559534959736ab82af477e7e0d2a32e300384f40ae4b4a8c006f1cca1012c2d0bec79788bd7a1fa3a5faa073e7836c674d49b4aafa75a124c1ae2dab5d3e6dcfbf0a289f779f9a452bcc762ff427a8ded60823251a472e33041b59676097446f6fcc49ec84026981d68b748c68782caeb51bdd2a9da9567f64d3366ab42f2de1740a7ec48273625c544b56e75e165658aad71acf1acce2df943b0a9ecc366c99ac4102df480dae3ff9f95d67d87c3d1597e6e51e5084ebe1fbfc218e0f09e8c35d398892b8c5e7c0abdb94e2f2ed7a641b784d112705efbb30e32280775b5109f161457c1d77f13a3675dc6f3cfb6c3a39f2ee5a79e73e5b2991e636d697a10a5a16d093fac679e46f8351c1e1a616f612ad4f0d0c482d88b822260a711e5b9f1ebe98602bed8ff0e352d87ca71691271281b34cb6ec91f0de8e06417e8153ca6d5f721085674de8de553335b99515daea0aff19a7844aef1d7e2aea1f4142c38edaeccd6f3cfe5bd90fe5d7193c6f8f424a06f7869d883d419255f6ae2554ca06e0eb8635f2e95355b43550180216a7a53010b00a45745c3956ad4922ce46c5e36ec8c2e4aac2242f0bb5b9914d18deff7af5d077440d25f5e0ffb7367d79bed438b0978d07fa2944942c586e0df011f377632994a0b5fae0a5a47ff5e6283460d50f58eedcbc26c6ff28e28dc875adeb1164caa90023f649c9dfd397f40bdc8cf620f3f4cc064e7013dae498682819a597b0de10c54f8c51e3f35cfa6fa12429e2576a51128a2856e5f33cdb5e75add2dab2bae07d7f5dd0b3898c943ad0480103e467c42febec612469b0f77a458ef98eee312ea57d90cea140c548bbaa1c8b0b328cb2aa2307cbeac368d47e6cb7fcb97f46b651bd78f2204c0c0c9b20d324681f53933199ef359f16f2177ac2ee91091a81b3a2f2d65d73caa87f2a6b0bce0451eb90d214ebdbe03888cfcdc3d061fff7f12601adc882c92bb014ef23bbaba0185e83fc13537a8a08c0d03f284927990a73c9718e2dd33af85cc08f69ba5bdf866ea044aa7c1265013983d07059c45e6ce78e55cbf6d46484bb5cb46ae3be9c256068aab52508d904b676c5ba4759e847436fd15098496bc54b1dda86d3b0566d99b8aa7241bd4e47eaf79df82056e80f3160d96bbc2848dc16166500439492f36554164e6ae50a89ee0d0d04c94d0c5d73a362bb7ec5bb1ebc3d93c71a5948df33873b1eedbcb3b9907c2d11dcf8a973348517468e0ca6e5a0e52d0e5b3296134033be3ccf7f770674955b2bd4fde1a4ec7ae0f36919f510c1016ef75d5c15f5cc2b656114285de823c3b587496f7b891f535c87d31f3afc1a89a19dda451f397bec56151db7b2c06b57bb37d26f41bb97b32b2d17c7ea5053f50e93e3cd63931dafe69586e0f7d18a9ae5bf1d30fd303baaa76cbe2874c5ff155fc080fb11d36ca679ac626d9a6270c27cfa69ea3e4954b7fcaba6070a7df2ba4dbf32f1530a958cacb25ad21c5dc8d23b3e85e551bce749c24ef0a2b6d935bf30b7ab0fec77fb5d737b84961014f2b0bde7af5228fc4bca0f6c79415f7c92da8cfd1ce1c2e729d06fe1c5bf755caa69bf2208fc1aa2c195827c4487842e9b05aea1bbb4d6523399a8698366f68d899cd67e222bcca7d1af2d39acbfdac1c539e0287893fac1ff639e56afe55dc18b8a147873c080100000000000000000000000008289ef52791f655e350a0d6acb84b7545ed9122bb81e3eb3a9be3fee7f22874a96e9f2f58316ce2b0ecdee424291a947809d37550f7cb081f96c269d9e76bfae4612ae70d574959d9ad8538dec07a2a4dcf8696ceccca0c1f622660b8ce88d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049711acac4ecf648033ffbde64d5302d934af1b3f84b55a4d140df37409bd9c75a5ad87bc23bc33bcf50658cef6b258dc97dce534d1e34e46c1ede8268b879f9d0cdfa59559649b51e76625370ce1cdafaae9d91c90b4f7854abe4365a722abad38572db321a300feb753ebe2d82818d0613d998a21c151ea3395276142541480318723adf918cfc89d467e83d5c14f58e92fd8cd4930905e1a87d7d480b5b39290219f810958967c048d61e2839f2a4fbf31b5e70ffdc4605c85e624dd74e39721d0b0512bff5328b476d47cca72575bde59061af3d823eebb8f12e62e3971bc1398f98eb8087276a4484a2249a82923dbeba93d3a0006161651c3369f41768665a340221e6601b8d959b92b75e5303c9649a5a05b84b9e705949688fb18bcc5548530002298731b863b6c422313259732c79ca1f7d85d1cf2cbbf36933de01941d24b3fb031b308e5118eca33b15bbe43780b006d01c4eeea1e49822a8a925cc4316a8f52c02080cb7eb12cd028b152bd4c378e6a494a5b1386f8a5f7d842528547f8ea91e12022ae95f791abad178ed5664b90d3d8b7720de7f8c18323c9a1415aba4b1a540ccf2339721d9ee71b328899ddb623978688999feb826299c9250890db7ecc6795addefc95bb7fae186a50d2fbe8476b53730e1dd719c23804ad5a05a632b3ecb8d0c0985266b55f5758339e089335422f0754b6454d0857bc9863fff26f25ae34ebb2a79415c943b81367dfdd0aab5ac17e2f0d82e2b69e72638604b6525b3ae4befa79a1fb03b6b43a9db93b8be3d801444dd68140eb6c5d60ec2af0f568f4e47b102ed7e7af1e9f5437cb29afcca499571ec5e53bac2dc333a0029129d707542ad1131642c049ee62b3cbcc0ed49653a813cf4206c5410532ba636aaaa87c43746ed5390e1f3af1f114d03d19f2d46d59834e65a9633f24936d2570d7ae2691b7ad189763a318bf3d799bc3bac4b3e3ec65f64733e522e671914e0c3c83b4ac17d51d6ff413943b8163c73bbac0f691387c17a1e12fcd7581293a5c30ad4f939caee7bebaabb71fa5eacb94aee7d96917f6e43e163e37b2c7bcf5a70805649c30171753d315f45f4f6462c0181469bdbcf0ed3291921c0b6344fd97b46a95023bf6591cc19780ddacb295bc73e658347007336d777367708245127e6aeee4abfd94effd697c6a0113d27e84bdf3d68394061676f5839e335d0a43b1975001f25f8565ef6d6d41e3d9b1259a465e9979e5e3bb21c93e6e205eb37f84ce56f9d0052c0fa00746499b818fa8e20ea59b9afacb13382288134109485bb4cd8306d3871c1930e507150b173f5c32bef666ce67e5955d0ee4d11b61ceb0b2676091aab142d0422a57d47848d3466a6a76d28e3d3e5ec98b104f8579bd84144d2632f5b70dedf943c45bd018737a79b732dcd186318a0b1fc3ac8f10074638a31a7dd3a243abc8d33304a0f318d582c2a06a78ebb3d811ed23e7b42e5e6ae4309ff63ebc35f5a085d9f021e6dbf0ab159ab35a990aaa88dd744bb55a74e13980a570db03026f6635164f417896e530de2bbde698e8bd589d3c7add57576cda6068b76cc93d1aceb84a3d73217af89fd11918f494435d946ae5a44be47ad654a5f6d1ae59e9dc98dac150d0fd7badc18a86e3e14e219662e586cb279bdc73740f87238ee7f6786eb7fe81a014a6dc5ee2eebb91f40560fada63bb80d573901afe997264a01fbb9148a350695cd2d0603e35a7f91970595a6a5afc230a5523dc20e0dfb662d50d5d3587937db0d2ea48767bf3a1ee7fa1ce5b9b1edef32b96255c415881d2e31f645afd0e2eac8827d7736897fef34b0c0bc2c3586d3ff41a949345dec1292af989114ac502363e0086891e12ac8dafb46415517828531d336c3ebdd249b0422d6dd6b4c0d27ed6acedeaf28cb5d978b68461fce51c70528e3fa300f136cb3f9622fd55645e2bf1930a2e95eafd37281df5bf0342889823096c0c13b4e28e74ee0d37523a787a14585edf151415e0714d34d4f4f06222e72f9ab24eb34538b421d9b0ac35f5505a92394ab2d5f4aac8192a20c552966c7e7ce88793330aabb76d0b0dbe2d0dc55511d5a2ba08ca5eb3f24babd7acb4223b38a9eb70b469c738425a94d7ceda099c39d778bc6a5f25848e22e35cae4610399e72b6d465c2077ce598abc33726411138da05ba3d3e0c52a3ac8f71d57f2b75408cd748b2d0cec5043760824d9fa51c23462da79d8bb7052ee794c62a2d06bd53bd90942a685ff5a9a18051ed8809ae08424ef91f5f15583000000000000000006ff990000000000f827656da3267fabe532614a4a45a7de63d17da0551a00abe62b8213edf6457b90250560d3fc76c0f90ade5b0da5e3e826a6661e2276a05beab6849fd81e9b06d960c6d50e8c1f3164010ac8c799308ee1eddf3adfa1e1c7ba5132b4038d072f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2506d15e012977c0053b776882f2795cd0a38423ddaaa8e66d81dea52713f257dec4282742bc02f2304257713030367da1f2dec012d78561e59635a6e468d4bd9bedc83c730a08aca128b1861da8a993b4bdec40d6eedb81909b34373df50c94194166f37b14f10510bb98719442035e495ea6a201c49923427186375f1b579022c45ffb769d58fae8bc02bef168bca2e851c42d3a0a6262a5ccd51bce8fc13d503153ecb53654c1104bc25abab970dcb198e3aae1d6f47a0c34d976811ed06808b0a05ce4fb74a6f8adf0947020834850fe9bcaceae64c52699e400baf77fdda864f684c914d1c5705dcd9a851d3191b7e32c6d3707922b798ddeda22bb0e657fd1902192b82f4e74c2e212d94084df07a04fd8491556034fe0a747c5df027eccef3b5022cf960e897dcb0b81bd3e45e9cfff160350d778bda49bb6dd1eb36dfef62e41c020826343dda60b2f5a37cbea6564566072fdd925ec2c94402a04e1f6efe9547b3030aa4998a6bb800d998fb8d2849b1d440fb535ac6512c0b034c612a7676c30fb302179694a2f129b06d91a0781656e082fe21f12b840aca792852c91d2201fac86d935a4dc31dfe14181341988086b5a2255e53f7b4e32018c28e3c5ae3e8b0d26e6762f9d3fed4b2a6266f5217284243c7a1bd7db37c8681532644f122d758e14d6dee896c8971cd5bce60c6caebbad8368f9d5cf509ac9249041eeaa3fa3bf3d46bd93e8a4f4e0bbc1d0bf06bbf86313a3300943962d847ce27dbb0a32b05bb597c99e185f84f4b8f3b2f6026fd321d1e01ab77811371c7967a962185f80238dffc2c99333779d8876ee083d245d8244a2ba9fdd94fe13b9fedc00740e04cc36553785889e16e9f7c54f6ce66cfa11bdaa20e3ccc63a8ff32cdb5c3a0c6cab5ad58d2dc846121a64eea83756616f53d550f43c9bd27a1287bb1b56937a7ffed53a1635535f2a6571a40c5340f3efb5b9a3130e51fe1ce416c7bacde1f36dde595d18b0af2beeed215fe3c6ac01dcd44475c2dfdb0a2737fc8a40e96797c0917d2baa98f581f53e1c49fc4d020fd93d819b4ebe1c2bafe22976cca67795560eef87fb3ba3cb0b1df930d7430f06a187f6c5aeba0dee5bfcb9ab66a80656c7ca6cc00c7e77825996ccb8261a548222ee54bf96f170387824fab3a1ec1a7424e7def0dd2a59c5ba64ad378ca24b9cca892239bd04b077ba8fc952bd4805e1b4624a83382390da5d0fde210416e7b4a11a40ff808d52d2b6eb921ae8c6ae67148476d60d78d85888af27066a7275f44e103c11537a19cab95b8eea93327243e34724039d2b0a4f70867e343d40d1357122e9a89a5a9e76fd290cb747566c1374dbcf09bb8550ec6003375af71ef074faf0a632317718f54bb31237120448597dc6b46789fba11ad4004080db812e4bd5790c437db3d34f134ed48f2e3b4f5c4b27292a2050bec1895689035bc794123d4c8ccfb04592dde291edce704f01d1678736d5782e7c8bc3853d1bb05fe258159ccf723621db85b2a67bd7481cde1cf676d4d42d2ecaa7ea98e55de4a526b91be482954ea778d819bf57a9cd92f5781a71b5c07d2ee8be5b790e5a944b034d1b85a1838e9dc5f1b247859dcd0b1af62a8a9954b7317c8e5ab87b6d8620e84718a47f4a965b9efe7011c959535ae27889e7daac453cc1bb503c8fc8b2e8c2308fa8c3144e03259986224d99de92e42419088202e80f434c8661121df53a99b506aa43e5c7f68defe0422d7387f9dacca12892b6a529c728aa412955e321f587a4c5d062e9fe7ce3e6fac71c1f1844cd28af602993df8f308e67b89818195ceab21c3e5eb74d0da6c6b9818b8caa43bfe29a5a5b8a4d9c5f624bcf574f805cf73735bcdf3f328f4254ac094bc0b0038ae79380590069d9c282ad9132968c3f4e6da4c8f790f8161549bd63661c180bfed5cb2a8aec83fda82a7f576094269063e50503927d79d66e42a4727b1b4727fb2f29cd3717413459468ec72ceb03ea553e7a1f7046d11fb5bd444cb2b735ee2edb1ada27b6a88dbafe8a753ee028988cbc2a4e9863ffe513f647a80a9f812347c09e9d4dd1540789d6e9dae4c0c0f3475dbcf98c122ccc64ea35530c95f63a99b21d7996c57043cf6eae705815bce1a7905a2737af28482c27154a756464772d828a3a03cf43255066f9760351a9b30a832b4141a72699a81630f73f48f8117069ee52bf4f70c0c20e2cd8b43357392b583dc3767d795265236133799b39691edcb0a48f4affe5102e7129b2f8543c513c76342a738414ab2f2448f1b3e7c7ef5264be21fc54e62c6e297e7a06cb41b874d09ddd97277727a4ecfdd3c6d0f5dc7b502bdf7c9db4ffa822af526efb20130e4f18fe290e836bcc17eea3bd2ec29cca49208370b60501e21781b7fafc71b04d1d1f76a04", "", 1, 1624702481, 0, "5861e491aec1b4512179065fc3d3cf8b99c1b6eb7c484c7fc5dd64f3f9bdc04c"], + ["030000807082c40304356c5d74b905591353cb703171fa81e91f9161ff561f2c3f0f0bb5a9eb7637f801000000056a53006a51286ad401dcedefa57b9cf4caf6118fb1c15c3a8a2f275d00108b36eb35e2567c5e39803601000000056553536351ffffffffb76751feb6bd5926f0465adc362e1fe83023a5a3dce2fda036adb22a696024b803000000007cfdbca6f0b0ff5bdb96344b2561e5bd23f2b94c7d629aa5544272ee17352f20da3cd2310200000000ffffffff0419c2af010000000009ac636a5152acac526a88586305000000000452acac5274713b05000000000552ac515151eec3770000000000026a6a06620a06de937d84010000000000000000e6ce140200000000912650de0cf4f231902c03c825a8610bb8b964e37acdcd753951d1aeac10e09fb87384d16a9712c477db279f6500b6d4c0547d495092a1002e42f9e4e8eb809b6a3c70019061fbeb9784767b03486a14e7b583a8512e800af8f3b7c80a22d37b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c622b321aa1e443100364f4cad85990eac0b7329cbbd7bfba632df7fabb90b8368c60a2945ff8f67f538b3d87476e941fab2344279da88d84884e1836a7be45f5265b6c0a5fb92d3c502b0c968100cf5f581ca16c53121ce84ce6957bce9f38cb168709946b3c60a77da990e47dca557308e5dd73c843f92f3ed765cc215f7032e9088f03032f277aea1fa0974a5caddbe57af9474ded65cfcc730cd1cbac043022992865d216cc142f1024a648bc15bd2f91a51735c9799341fe27fbadb7bb7ae0a04ca22a0ff997be49c982ec380733dbcde186d873d6d1ed8c19f101b232a541573133fc0008a4d19e08a71541eaae0052d423fb2f8fffdc427e63cfd1efd4503032ce70ad4668ed2d6c0ee3031273a56416c707a301b524bef324e14fc4511d25c030ccc852e8cbe3a5cc7f71610a995615e6f8e3e4f1fb68561386ce12e4d0e56230320d98f0c6bcaba1b7269e3166195877723e61eb840b376057c3ad63ebeea4bba0313dffe89bf30bd2a0797eb42e5f190cde80e66edb6d5e3b776f172aee4c50b34023034c48369a0e3e464d667f8e740232489b3198096870b7c0730dc8e71e394246360fe9035c2a0e353d433d350dfe0bb63736a893310d8c7fea83e3a14b10cf6ea8768a4589dbb4d1ce7d772206243ff2e3eb0ad9adf4d9262f61be896f3124769a79414518f7bc6d4dbe2d17aa7f8f3acd7c079c49925b3751a86bea9f12a618bd42f236ba046b4612cdc18e550c4a0d3b3abfc08e5669e60c15bdec521850c3f35644d2e4e663213985157447a013eeaba486387e54c8bf967036246295a7214d275ed06ade9b236d40976b10f80a907aea2f2ec1e3d6bcefd9bfc9a5820a31d6e30d98964a4fdbd01ac8d2db46b10f770f267ee58726da5a58fa77892886b910e64df39a743b467a3acd7273d0dc1f4af26843cb390013de5023637dd0d2d1e97eaa4713e5e5dd6bb3b12be50a8b3558e4d7be8f7663b0156680345fa9476792179b112626bb3d3808cc0809564cf9378630d33f0a2dff73bac797f0d244b379524dacdc944f30ad0205e664f11a28acea9e6967b6b87d8f6c8a966dbbc22be7aaf22f9586d9a4379a442e6748f72edd5d3ad28ad1ebae4fe39b16e8c99e726d9997454c424d4fbfbecffb40e31c77b991bc4aa0176261ba73c1ca55b184279a925b99032adb0c9329bf3ed39ae4e81628d1f290acf2d64e38b3ad4cd976d5e511123e7c66642bf5e74ced761c72acc6cdd3df02c2be687711acd98dba810418563ba29e1bb69998083e3ca1488a4ddbef43350f81680b553f3a8fc55660d5dd518cfba227569bc53d6e032222cb9fd39d50bc8b192d7852e731c22b194c9d794d3363316013490996a5b98fedbda72b3674c987ea7b87123e7b45688ee94ddafa756072b70509679f4fe4f3b0ce0a549495c9e58544917d780646440f53997232ac03c235e3959ff555887d2f32231abf6bd5dfc415f40329cffb5a1b83299d06e283b9c438a0029b5c673182b6aedf0ffbfbad0793748c78e2bffff91f92aba6ca436d7e93427aced0869b56d413ffa316fe54427710cbf9638d79a938421321114aebedc18cf8c581253289578f8813c0cbe3487313c380ec375fd64f0c0eb56950ded032439448b6c5607bc8a47962a393a35bda63f429bafbae5c1ff776946e38ce4695ba678efbadc55f3189460a8b57635a844c79b50e2cd86a8dcc982f73dea14af9ff5aa0519aac2ed99affc3d2c3ed13d6d2883db2f917392958c8ce59ad3cad6be6d20bc396e1d3cf9a4fc9671d5f61ed887b2b457913d16a7c715900ad629a27249a1924b4a9a725dc80dc08b5293b0ba64219c870c97257c64306ab81397d9b90c4f333ad7c0f8f19d28db4802025e5eb084026520e7d8332acd0b4cadcdcf4be38e2b09787bf657989f7e28fdc1312d7896c8a032497a748ef4cc346c0cbcd4a69eeebab424d7e27dd114733a87cfc000aa9429b12fd5af9b0ce2541ffb3ea0d4df985066aa6831c4d0302ddf25a53c901a3090958226017046d6df5c437d483459a5e38d8e829fc2fca205faf3b246a2b0757b8ee7fd27b9edb5d00a7c9129c94cd680c2a38ba8b1f3b7b154dcc14ddf7f697a98e5dfeb37bfb42b7c2a2fefe5a3b4193f9aa577392f13320a6cfe5e796a557835ed06e6267da83ce01311c0197cbbb4e087103089e15a46d6e7fa16faa3d177c74612bc96e677a4d029fe22caa8d8eec79d05afeaf96a20f421a2b0cb92e95262b22ef78bb8804877f3f7d3813caa5802e64b0bd052676950a2d94977abe5e6fa0b10436095e686986e2fa278b0e92325caf55e1be1e10ece70a9dc91d177b625e631c6753e103adf8eb359bb73fcafe7ea53744b6d1b9fc84e3eed4e7e69893f07700d570bf2e576da0c08c16c66c1df13aff6e90a", "acac536a", 1, 912114334, 0, "03744471b15b07d78034c74d77b633a7c49e06756442d293d7370d3d9f5e7f30"], + ["030000807082c40301e41e3e68a89b0c92da14e3590e390e6669a46817f937b2e3478b41892e7d7c910100000003636a63ffffffff020a38fd04000000000763ac5365655263692b5200000000000463526300c9cdc191f5d6d96802bceb5803000000000000000000000000214b0d42945fe51ccd14245082ec73732a852dd82b605c125917fabc1e729270701785c40532fec15b247227f08f882750b381df2fbae0dc9b0ecbfb8f1f140a1304d51a788cababc7bc9d41d84460af454c05fb3eab2fc3224c69319210461800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b78b050cf346f6cad39080f1601bac9fab00fad0b6af6f059841bfed85fa94bebf4bbaae5d40e8dc16979451cdfe951ec63d2ffb0597143cb508603658713c006ea522e53bb79ed3b0112e8591ccbf809fc11d5135e24f3082f17adaa555c8117df080c759b2e77284396998890079dc5e2a8f1d92b12be5fdb7408f6b8024fb031ee998c3b9556590dc50320f176455fa713c2d6b563fd27cbb96e5fb29c0541c02267e0a574bed5df343a648df899d6221f8d05e0b2052654de0a75b36d0bcc1720b0519e2224a2954d1278c5686c420ab9d4270eaf2bd46a13acef9d2f049f7acebb05a8392e635787a2a2b8d26fff5f3be2eb44d82727e2e99326a7a4f4108fe120213c262fc11bb1e5a2d1e8eabe6bb54e0b9adb34944b93430f9e24d49857383170205517de066b26c2a82b70392cb025b26a1b63fc676182b0bfbe1b7379993e965032aec31ed7b230a5759bfe43b01683410dd9a0ab43cad6b5df04a74ded17db0ad030ca4100ccac26288b016329dc79d7c7fbe4ca9a2ae2063244eace93e0fe22e2302133ef3c27fff269ce28ec2c86738ed0ca836c43388b1d8d73ae4bd60228d66b9f5340e11814d7db13eea4c07749e1e1f263f32f61141ac2f6226a61d08b12701047bb17f5b2528f6c7e10db717ffed26e6eae4d76ab30d274dacb1ca4a8865a6d49d18780fcaace801cd57e7b48ea40858977de179cb85be71fa4e97799ef3638cbcbfe5899a7574e895a54a557cce738981a788fa4bffb2158577230dbb6d92ab97d930e5a25b04761ecc501c6f21ccd69d784b91a425ab4c963999af9bc516b1537ffca9abdf53f33f1cef53da1940a35164588516827e0444d6972cb62e488c1ed1ed2cc026709ad2824b6346cbb314c8a3bedbce3c2613603d372d8e70fcc8459bd78f460e59427085f74b537f0c2dfde1b690d786efeb15e46e77905acbf907f86b022b57f4e71a78e1e16b56ccb3ad2f6155be946b45483eaade18f03a6b30be06eb58436a820259c18188f885e0915922f53bc52c8ec104ad5f34bd1aa0926ecb03cb1f1bc5bcfbfcb7aa1f72e154bebef5189d28554e3c7a516ee498fd87b79fb8eee56049687a87ce73c894791f5d2411b4ba24831cf373358b74c28db1b25744df8e4dbfd2c6d962e0f3e7998c81824b500353b05fded9273873af7258a2f7409b68129b287429a885ee2d11ebb76e5794a18821c4717c45044a4cdbc3e1681c42be165676f5aa6f02b64d2e163701e50997556a42d1ddf962df34b52719ec8da3e3a2654fbd5e4793bb93e0b9223748572ac0ca2c9200005bb546447b51dc0b9a7fdcd62bbd4bd1899829e1972f41837de6a6ff0a850e4ba0890c4f52e7c16b157f9624eeb421f0fb14cf39969cdb347e48e05a496bec9a85837b78b6e0237fbca6a0ce2fc3597417b50caa1d74d31a4fb2f44d5ba00013cfcfef4597f6336903acd994477af0f7440aee5cfd24320b6e501808e8feba2bc5d35faf7ee26d6ee23aa9a8b3d3618281d31d925b7cb8a150b05aa8971ee2953f9016e02e10ee53cd32126b0127b285556d29da8e5c864f711b8af60565cc2021fab6bd4f180909548be7ce5e10deff92a22c85732b4e73afd7a21585477310d6b0e9834a39b5e2ff706fffc97c77845e4d547388eccd6856e953f3e3be2736abfbd1e0ba9bb78de2f413ebd8e4d1f4ea05241044be8e79299dd0df7b08dd2b280d539b8d0d7239145ddb43f8ec0caeac523e81de1cb9ba52f9a5a08939019f2633c98ef1f0472bf3d83ce90e74e8f6ece991a0fc15a4a4e3b344cb2ade300434aab1ace49058bfd2a5ed68e53c3b3e898c94641450545eb98c0bed4c08a46af4ba5962e2c25fc7e7652b4b4b79dc4346140dbfef288098f4b6acb738fa60b630e979fd0561380ad7968345994c499a10cba4ab6a84fd1971decb7593c9b4aa94df9b1189e47a9a00b3d34d2dab7d9bb61e2080302b71597f576d2af02a26ffaaa886e48ddcde38729d9fe4c61e789c57fd407669dd487f21d80e6d33be2c810fc274fde0f321a0854f20dbe68e82a700ee2e42cae1f26eb763b17dfcc31b417ccc39880a397b91e5170c58639e282dfd374c88cdcddd2f21fff885314b622c088003937e2c50b4001d166bfc1118ab58dbefeebdc584fdc404421435aaa509f6c17d35065593e8339739d2e23c6d2c6f8150e39ba108e723b48ab3bd343d75d2c6876e56d9a0826de4037f6fff0a1ef316a45cf6531f3f24aae35bd6e478820f61a3b5c970d8065e4423a841b15676da7f89407384d4a603000000000000000000000000f3eed2ac5393a6b86756c2ab4da226a45dd78158647ffb994ebc5802eef23e7de50288ffd08c8837ce0efd17f425171e3fcb5f14e75fd7935e7c15a58a5c9dbb5ce44fc0e3ec5b5a29f9920ff9462d1338d6bb3cc04de9cf2bf79deee94818f30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002f5293aeca98c2df7f26a65db7be15158ebae8e25ee2ff6b87fc242d81f2a647cac19337e5d168cf17a6da1e2c6462507046014f325f68f0d5562ae6f76ee732a4b0e138459bae7daeeafd4d55e26d9eb2dd8e0476142f753d22fa8ac342b129e562b1bb86dcc18324611d0976f80642434844d5b7c9aa3cd670354feb07ead02185593c28002b3d22ded2c1003ca8cad7b22f09754d0ece52e8f7b0fc2607a9a031cc9739426ba6b2d98363f73c8a4e64775609f106f41270c2844500fcf8626b90a02aba10f35cf74fdb888cf11d50da1e23f21d67977470dbdad021de962d2e34eabbcc6a20a7d879c814768148ec7f2dbf137cd917963ea8e1e04b558929d03a7020f40b690b9d666b1336453d5bb8cddd02dc9751bdd0f3c9baf666f7f395fe0ff0216475c6d9734c0884b6472230ceafece5cb6f64e9fa637c3d35bf7a9f344a2d103242a19c1d8547bfe2331793ae6cd6b60b7e0644dac999c2141ca43c5938cc43c021d4140f188e26a2f57590c018c9508ecfba9bf8a6dd1820d2e2181e33cf8d54d020e8927a085d74f5aeaf8dc7c3add4070559cbbcc27b08e8343f564f3206a8406b2740d85f00f493b3e6942a42e7fdbd83c08a827cc9830d6a9d4977744440dcaea2fac725f925c40191627570b75eec3cce5174af1d9c51a9def0d66c5964a15ca1e9c91522dcc7f0f81bc41c34e365ce4a0845ff2bd557a2607d72d4a0fa073cea669c821044a9d4b8c6defc14d8c6738e5ef00959a9e90aee887c334377aa30ac1c3c97451002da92e46b5b91d090732af6b1d9febf74cc421752118475c336b2cb57ad09d8884c87f76cbb610425524b008a0ace1449b49478c38666fc2debb1f3a4624b0338c7464a331fe9609fe6710c1d4150f3fdfc2d0cf1cbb2339b00a5df22e0a95eec3df0d51e471154540c7e5d9f7c247829a51525b28b8e679e073893693be5c41ed2625a0814570d4ea2e582daeb29d5ac215e00f45f8ebb3089bddfc4e3fe1eead1f1215f02ee1c1491c1bc53a7426f9dda0397fa077a3d4c34eb5bbfdd95410312b246498893d9f852d158444223bd906693fe7f1722d3ce8cd49799586ca9b0f2faa0731f104f2c5d3c7e631a7b3e80d46877b488f0c045d250d458d096d2e99a3450f07fbfbd534ea649762b5ab0d2dddd65c4bd19169ea50437b96568832e07a8c5d1000cd0da46d86f304b67b64c1bf11851bfaa0e13a92b8fbc55304ec3e2ca0ee6d21621cb47e48ad5032d2a2082b08a4e51f3e161f902a6d88ce23fca955db8251f2fc6ed7a22b070b61cfb7a5cbf615bcc8ae080b63c3c5ae8f3cf6051aba2405e07456e200a0eb53c7b1af498046609fc4fb1f7c331b661d8e51f22fedf8bd8b357fa0693e22ea6df71feb55ceabff1cad9d1e0974de4ef1cae03f3ecc59ccc875a98fcbd7e31f8c01e8e759b44009d62b9f77d8e3746961dbb70e735e3a472747171888085e80aa1ed66fce828c80983a10aa47ebf5b77f609de73cdf0ea8ff3b220c5f5557b72b7c009cc805438dafae11e22dc127cb764acd90c9579491564f438532309452c1831a4bb8175419ad4f94433480cc9c257f5a6fb94634669d667163aed6bc8b536d28895f972998e02e23d2107f28e72cda9f1a6bfc5af94738ad9177e36fd953d9b069fc507004de3c8574ada8aee91498974eec37a17db952c4ee94574590551c3edd048b80fcb4fe8f699ef3c40d64347a1923c80f332d2d0522bbac78ec26e157324816f5109fe8dc332ff0cc23f0b518fe400516c1e7233eb8fd7339227547780aa40918cb6886583df3a098fd0948d50a298ac3c424bb28d9400a2ee1662fb6482650c063fb730dc222bc343cdc9a1f348fe871b54aecb482235e84eeac0d47b3143f8d963b63737dd1baf2e696cb53e62418f45575d184193d3eaabc48470cda710c19f2ede990099bc654c88c0203b4a54cfd643ba1911dc87b80e8c2072f8bd76b305a66486cacf0d3002708a502e1fbef9e6cdf4d543164a2a749ef5ece0eb8442f419bb7cc22181d54cbd4728ac8e675320bc1b8fc509edc732d9d5afb39a225189100de53fa3b51c24278d2835f55c851e820a87618937d1bea19c6557bb69e1eda5c339233beb966d775aa21a0afda34b58224870925009c1944586cf524965e98a69dfa5e39683e13e8c34381d5768cf73aef675a2db4ce4f6e6e0ec0ae5f45ed8536f756aa379545165cdd95269eadcb1a3e7c9b2754e25ac2b73ef595faf4467335a63f143686ee00362fb686520f1c9325ff5c72345ed5dc7bfc059fd59923c2f9ea507ef831c398789e7a8a9c74e15f52bbe2d40ca3bdef1d4cc8623fd67d794805017dc3bfea7d7927e0531fcadaf8b697d363ab01317de10014060a58f17ec1f8a3563e421670809bd54e3de4da2cc49592cb6602", "516a", 0, -114642225, 0, "14c75adf28d2762f4daa704685112081097aece94de6fd5ceacd6d7bbe8afd72"], + ["030000807082c40303c015f0ddd4a35e8aa135e081083a65254ce63ba08c08e6148a4e89c0c37b1d0900000000065200006a65acffffffffb55de27768dc9224fd06a69f1494d24ef94b82201f2da2a27897f62b5dbe31d6020000000153ffffffffa95b57dc439d67f9694fb45bff31b889a39448c2abec654768604c820fff124601000000076a6565535353ac16ebdb1002107fe70500000000076552006552006aebd54e03000000000200631a77145df035a99e01000000000000000029b88b01000000009ec9c2d9632b2939badcb0dc88963f11ada5fce6fae894fae3750ce5d073db179296933473be7e423fed5d59c62d1280dc58536bc411f2a4451366c36b421bcd9b73219b37d5ea66f799215415f1605229152be37d99d9c2c6c6a400efac546d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000551864f696f37b6481ac5c9c6d8ba719b8bca87e08d7c9eaeacb07cd5bfcb9f12070129afaf727a0d9d0de7938764733d4f183dd035c82bf5689ae6e22bb210cdb535e1b35960b330a56117c7f8a2fe9a49d3c86052a8125b74eacf26a69626dc731415a0861f3b9705586c11ea163ce7a687b57e626cd4100a9969c8c34533603132557dc86017eeb1b2357f4f702e1c97eee7797ce3262b29b1c08df96ee6c610316a8516fe50f3170d9ff02a045c04266d2516fdebe4cab176a58361d3aa2146a0a070263d46a2edccc4f86a45ce6dfd693ecbe82f363ce8185b46f465833bf5d0012f064cfe8ae34ab4440423ac455763b37237a417325d269197c6ed56027ba0602033db322300e5a9e3b1786b7629198692053734ce6e440d4e580828ed8eba6fc032d14b6377307e1a81fd0cb280c90bdfacbfb1169ff0d14c7474fb39dfcbda87f0302b15a162d9f1e693273d41d0eb215264114741ef0b57b56284ddb117d7030a5020c8476f84b58c02c3d3100c3f7476db78b71faa0f11457e077d162931cbddf42021d0c22c138b42425c711ee0294c718505c8d95220cd01fc5bdd7e000fb2279a54ee03da8ea986684f55ad2b6e669379114d400b0660f42ca1ddf8816e88feb8a5093979c892f7a2a22c85f12e345020d371b60206bf9654629765b4dd3873fd58464a9e307ad4a38771a631f87982e640de45bf869b1e4524d8a7176dbc24bbfab3751f628cb5a2787df3487963f8b56feaf9527e0fc3d1488508c5d8d5f6dfc38f4819311076c9c20e165b08cb8fa212263d2b6f25eb022b888a16197590208159128c42a757a50020e702337c57187f2821d2e3a1b0b4e2022df92c414cabe7fb966584134df4e535b9c4c578c180f3cd31d2b3b6e23cd4920a58ed94f1c843a6ef767193263734b8a81969c52c0823d9768579b7f209d4c1e3d6a57eff47802ddf2ea93d2f14a817c7bed7b4f66f582a61770e44f07f9f4cf5702bc0e46fcb311711e46449c59d94c65dd76a6c8147ca6fc654991be18eee64b1fbfaf005f4a355a9e66b7ca6a97bdd0b1e6435b8a56b2e22717b3c645fff918ac742551416c387e5d8e677894930eb9b04b739d67f05f39a9c333334e5ab231f437494294f869ab95d836d9a661e1e143d720d5e7b43d295e5ed2741485e4a3a55c98d0015ee78f2f860a0deb7824e550d0ed45dc75f94f88c795f18cf37af934984197bf7d7373729d5368529dc9fe0552dcd536e86528c7bff2651f8fbe04b591c152b8a926b5fd7a18e45086a62bfb5d4e0978524e62954fc38d837439a8f0bca42a2672786aef60d8932aee4a85bffc065f02b938d477cb8af3868b3da564bc0a9cfc36de8689eb70c998e71cee52ab8e58e5e0ea4391d7a9aaec2140dbe04dc0bb5cdbce7144e882b3f6b5fa4d324925cfeff2178770f036c746fc4e547640fda8458001019561184f4dd1e8c617e1525f6237ed59108e0ac8da5af8583ac7f185264b5373a07f9670c19301466cfd0e5d735e35d9a1e9e956bd382e475b4af4f3a65fbc5f394b168d0ca0e6a1b78e6f90da3ec95bbbc1949e8221c22ff3ff3bb0336833c00d58975502860313ce7a8b4c5023d86ff87b237672ba272c8d4b01002e675b075db1ad24fd6e088bea6b040f633498ad76a81ffc86cba7509372e4b55f9263ac79e48c06cc908c2d2fbe88f84b362e9f351ef48124de74d39893b78a821162715888babef251e3997b6388d656fbc07461603fd2f8079583ffa256c0638ab65edaeaf730a88dc3ab0aab9de3a1e383f47ae83c9606e244cc086d9b0513285bca5159c8e2986519d4376c62c7a2f222992277454ac8d80227de3003e961e44f5fb3db4617cce8a72cfb59652af3166129f75477e1018b2f027c09fc624fbb5ba6b23812c4e9c4b9c86fd6c7845ca6d5f37158f4fde9bac942d20a1c766fd8e1345466a12e7cdecb9eb3e7635c7b2b306d5bb79d84c1971ad8961e197ce1cf9c17cf29310f3c1993edf9a3a75b921fa442a33c83773701a13d649a89b796e5a89ce07f3eaf20343da6edd26fd7e88ecd9851d00e941eef804466d76a5728b1da8076f97bfb5cd9e47b5feb0df9eed08ea3eea3f8b41473a35e264ba67894bd3b66570f5599caa526d9b0d22567cac2b227c56d5ac18bf2f352321bc455c58c3146630762d4bcf99ad998c16fd85d8b5443ddc07b5f4de19d5a3cd599d28783e786d4e2fad8abca9d5c07239af3815a7a164132c8c1d3cb29b974815fc4e3964314d8f24f39b31f3f449eea76364d45a3484b1e2bcb8f79aafce9c5cc85c6c11f873708563c581730d40494a6d56adef288dedafe9ed258fc0d38a4a5d3385c1e0afe9681ffd9e0d7b03cd02e71f9c46033b94fae0de0b5e82a15a3f8f13522c325d976c4f9e395b2b3c900e02bc30008", "6552520052636365", 0, 884530405, 1537743641, "08a2d99a66a1f88f3d26bcaa46c6cb60c5cdf6cc273461cec3d7cf85e554b6c3"], + ["030000807082c4030126f607bfff0a911ef3cef4d6fbfa4a9c4d6d7d24d68e12c5bf31ca0dcf6b6470010000000363526affffffff014d316a0000000000085152acac006363ac000000000000000000", "6351006aac", 0, -142191325, 0, "7b69edc913efbdf8c52c11e6f595ad5d38bdcc05f69303ab72d4083f606ca215"], + ["030000807082c4030470f62e68813cf9abb97405d27b5a7f8229497d954145a0bc81e97682a18d2798000000000023557ab741d8721e998b0f3fa417189570d0ac9ffb2872447363865ebb09a0080a5a5210000000000400516a65ffffffff58cb950290f8f68ddb84a9f9dac0dbea41e956ca9c25a8c4d405b5f3feeb00030100000003006365c503d26f4034c32e11d67cb5ca67db2400c40f5099ce0c4934be7e68454619da7830e439010000000551006aac63ffffffff017868ad0000000000046a6a526a0000000060695b6a00", "006551", 2, -353673078, 1537743641, "aab64bc74942cc9d514be0b15918eef5bb370a5f97ba3ba9de8512626bcd1fe8"], + ["fe3b5e2b04b18ef66b737f06890e554c194cbd11e3cc3762923d598783415f11432efe1611010000000151ffffffff6912e99b38a73aeb7a974a78064c4d439148b5dfcac563337389b7c8c901bbbc0200000002635179cd3dc1ae63af618929c24b7579d8f9c7aa5c444c2e7312524e140f92824c6f05be00cb030000000151c9c404a860b346d38ee1424506e859e6b6b38545062cdba453add929096cb95050f5f21e0100000003526300ffffffff037b1b9a01000000000753516a51006500aa6dec040000000004526363532b30d0050000000007ac6363006351530000000000", "636a5251", 0, -760812935, 1537743641, "3154017b75fb74967e20713852dbd5120099140564ebfb8050b3f6c816745d1f"], + ["030000807082c403010e480791c6744c3564c4a76e4c222fa3a015084934d7d21535127389028c650b0300000002526a4c9f447f04cb3cb10300000000056a6a00ac63982673030000000000d0bc3401000000000153a52bf60100000000000000000000000000010000000000000000faceb000000000008b537116e0c29f7f8bab8704fa633563ff5a3baceeae4a25c3499024f888d8ebc59c9f62d8444139f2fa15865b2e145a84c3be08994f7804bad9106eb2837570e5c04fadc11fbeeca52198d2ef27fc1a2d4effe47b66888d76d285c7c44fa034000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006943d77458cc52a8b09cbed46e4b9d5800a371cffa47a133ee0e294ab23886fac479594df93c68696f12d965d75f616a500a2dae086c9b542d90ecf117ab600cbbf099d78b7d6340f3a098f21c036c8f73a7cce16cdc3e6d2e99aa8938ed1b962dfcae391861992788d08643e491940c3ee76e9d79033b15dd3c2cd896586c730223f71f45eb9a9da348afd2e3dc45d8991a9aaed88d456eb96b753c15f4651975032df6abf011e57a0cf372cf2da228c6ca935ff77ceac1ef00129facceaaa2cbfa0b01f7be9e3c9b7092941bbe2fda13609720be36cc807899cc4216ecb1738ea4935affd772c4ec0922daa2d81aeaf13407a87d8ed9659a7e5eaa8004090829e8640221ce4d487660340f7b9f9993eda751e36da69b69884759f94b066f6c765a0aa60313f0121811248e315dd04a58670efd99ad558d1e09404580995fe738a5c4cd5c021a8efe2031c2f00c3a4f64fc6a3f6c285b41bbb482c54502c0db62cf19c4b7fd031a6f2f34502607d6917d3aacbf744896f020ed533e9e14d315776faa9621ae21030c34935bdf1cb75d2839eac5bad1ca5930c068dfd218c44d727289d4384bb78ac327733b65bb2f0aff786d9b70d3c3de23d64a1d25bdb9989fc07e8614f1abbacda8c9def60aace70657b2c169e326e2cdf42f4ba8483abe3d27cc1c32c7449e0d8dc38c7e58e102ecb16e34b853a6e9761d6b90115c2bc3716236b280b8cedbb38c01dcd46347d225f2aebd8a02f95b9b1b7d39640e7c69ab2d1296f0796cece95ae414c1ec999010f495e959070f58e42b7a431bd1769bef22f8f7296ca7a4965608dd40d588a1b0c577d9fbd55f252c1b68ea1db63a7cfcafda0829cc1418ee37515794aebee2d85cd1af75cddf9a2d18fe4046c008485684e2956fa5ccd4be3d7cac90f18c9ca8556e840c9825762653a38763220609914dd9065b3de8a4d17f7d6d3b6f55774d203a2d80390413bbbb50adba420a9b221909c25a088cdb9c8ed7fa63db901579a5ccc42ec37423835baa2a3c158d7f172e66e0f6677a2fc83c30a4e4074b81353b5f0edf168d82052b83ecab1a10d627bc4d77eb263199039fd268444f305e247ca604c75eb899887cf420fdd678245fd2e39c7fcf49d68cb1100f0e3c4366109be707736a501ca1e07f516dfd40158ee18f8c16eadb54499cbb4681455e9476a7d2cc23101366942b58c3ffe99cd0a6de851109cd70e44ccc36193500f17251161af7b3ea4950062bb9071934d9e3f71588e061e4a58a4d8f1b1663b5a25569e687ecd6ea7c7af5a13cf93c2ea1db97d544df55ba10d42d181114e0f641e9f43ed8e023b7c3f08a8b305a1b8bae5b5c389bc5ad311baa4cbfe919a867adf1b40d402101ce9128704c76f3efa5641884c832603e6b00400504e1d64f3d41c7499303ee6a63d7c7bca21cbb4538981f0f1a9a4c8ffad9f86c612150b3965170735b90b482a1821a81a729f35688a927e080000351ac9a1cdfb66d78640d8180c5e96c5f9b51f432a230ab631506983fd2717520eec92fc1b61e3d8d44064eda7572f9e9aff6865b8a4d166e4ce289452a2d31244ad0845d1532342bfffd4ac25517b05a8ce5b1fc1f7ecddeacc888349c66e3e95bbd213c8157742588ccb2ba00f4be4063ec39ff2b69f19375310b5aafe0619f789f33d7768a8578b481ffb22e044d4aa8afc5a3032f4aeb210764e963912d3906a1f2379190410ae35127c51fd3f04a486de2c50e4343059d36b18fc35b913c7203f702d089fc717b15bcf87fa63c0c042993834d4ab105db79d861d2a4e7c0e1b0880f2a9a51dab3c376ada5ad5bdc63b36e201097b9f8248527785433cfaa36cc3d088e4cb2a0736ef7404a548d7d8654eba074dee08341ba891a0266b628007499c7a9e83220f7526862437dab234c3e7416069c90e45d3872e921e31cf4824368e1f388aa3b64f58ca5627408ebe082354244330efda742f8d45af6735e21d4889f4fdd8d590a65ec5f86b0f85a9575c533ac310b34399c06f3ee500adc96b5cce3d806b576682a2c582acc4bad69e58eeb817cb2700624ab846bcd9e23bb8685b04ffcce2128a7a9f471bf0e25af02abc747ad9871885c27f19b58ca88827b5183b81e95460bafc49c3c28c03a9db1861e72c758f15e6f9366bf2c6695406faf40831be1912e22d6800bb4ffd4231b394dd29060b1a3bc1a4b3a626794e1c78a45ee4fb3d777374a49b325155224c4c9b488340e9402eb9dcce1be1b0c17f83687ddd412378933a83a11d09d9af950a8926a8e797c22c043f37f54a509f0ed4324df9b004befadccbb6fae137de55787a67a5665690f398a81409db5d88e490c966df6eeecb3b58f9fdcb6954e3f7b051d0aab63b4bb62a5da312bdd19729d78b29b23c45ece60e3d07cd87153f4e9a37caf0d", "51", 0, -539949440, 1537743641, "b41b32d88bb0b6d424fabc36309d99b0e76e2d5b17cdbfc1a5410a6fd89b78cc"], + ["9f2da00201da9fbb7ea50a17cbea140c6cc5556e8a5a305b9d2e07b34ce54e302ef2c6302800000000065152526500ac01b2e19001dc4369020000000007536a65515165ac00000000032f226800000000000000000000000000c49ad58483f25ea203731c0ae17ce11293d7118dd3b9043393fce2b62e140791027cc3c5dcb208563e3175cdf0a74df81959dce44f40120fe8a223808672cedda98b66639aabef52b482c60e0783dd3dbb07754e0c0c6760ece32c63818991f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a62b5e79023009f726e6090fe1b0427cf2b4786094cfff1c7c1e41e2ba8e599fe822f952fb515587fc7bdf1fdb6fe199f88076be45b4e4644579932312f15bfaf6c71cdc98a6fb0ca5cd93bbeb806c4ca6f0bd75c0e500e5209ef660a235f7b4a492cb98256674ffd40a9ced118465b4b7488ce3597cc591b4f0f896b32887420309553bb15cb7096a231da9c616746c6ad3212bae99171a4e71deb71805960939031d91824bf9424f483557438d7d88da94fd6863b051c1a0fe6564afec2bcfc97b0a084ad223c9564b9d31c238b887672aa04a1029443ce623acd26fa829d0b283239cd72749aff4415d27ed2cd37789759b110320f0a3e32c1ecfb2158ac2c1608f032676413d8fc76c395428466daf37d885e29e40c286d10521e07b975114d48d5602152e3f42a81723f04c374d97bed029a66b69d0c12cbdbc64199c6e7d8bf78a300223cafa1c3b4fa32ff9d7880ba46a783e947fd81993d24989b7c8160e7fff770303175679c8442337cd1fd3e97f2991027c1cf11ee67a590b366173e3acd02c1b17032a3f5cefb066f8fb1873da44b7ce7228dadfd7e6d46f9b0e0a0d4299c669a26ad9ab21e5f9db6d22dbdac6c92fa793d4da34cfb521d3e40ce1dc2448e152a34036207cc77401cbec948fda9a63a9bb9c3175d7a92dbe900c593f560ef6c7fcb723a67ca4f310e7ee2d1d4752414975e6861b2cd0d15f42ce2159cdec7e829a40daf7f0f64c62cfaded9a9eff3ac807b2cfb013f71fb51bf707c892a3a0a090f5b2152a9fdcc4ae39fcf9dba9284df8d08b71d21debf07c154ccdb74bee8a326b677559c397c83fe2e762cdb5789a6f2a168e59dcfcbfff5987569ff66dcdc6fc591d55550e33b48e006afa7252eb0a86517e6caf92f260dd6dcdf419e94cea354b9ff364b03744210b2612a1fce552444855e22c14a4fbc62c1730ab5bc56d51e6beb251df7e1c6a731f2c29bc7cdbcd4227e4cfd7e49381f56a8cb7d48ce2d94d67da3905805ed37964a76340fa5c60609fd352aab842160080bad078c133853ce1ac85e898e85bf80358b998829f6bcdd9ac02ae16c41f912a303c61a49b4bcd9006ebfc499584dcb9dd0233ae0d7295d28b33238b99b0bf0265277d0be7e5e768e0702374f5995cec07be1d71b4c1a44fc5174c9c1173aa8558f522bf278162e613f15a0f7b6bb02e76fbf34c1631ca9351c4e4a2fdd46865fe55cdbb6c456fc95eab817eb387ac856602a8dade32e5ded37508107828261c75f822a090e010bd928d1f8fc40a27495d6a55d8cb7677f381985d7e0df20d32170772787df9b540c3777ac5995760f0eeb415655e886f4ae878f4f1fb811e9cb1dd5067ae4db6f9d20c868a74b8c93c35ce413afcf0f9b6cd1a7f0dc65fdac6ea0f92785b71c43e38956545d4340cd55f8e5ed895ca15b6b34439cb0cc7f5b525961c192946dfc32415a138267eec89fb01a044f9e13439cbe8a3998ba86691c8fc5c83f29b8c42b9f55a781fe9b9c771e22f70692a3fbecb2e23c721676a9972c62fad18cfba82c2016d844a948aa480a52f29dc8ec3f79448fd01760d77ccaa182b6f29f9a6d2dd9a73df342f8b58a0ffa6737e546be1da8c2635fcaa2c17956bea9c3b62f1a2e8960c96d12fcd9e7a1e43327bda41bbbeeb795c14cc91105cfa5943a4fb909c7368b881fc033619ce21aa27bc06e7eb5437ce70ce1bfa32812e8f75be7a40a3d667cd07519dfbe3e48dfb285729c775a21f058715bd389dae453aff2184ee1442e552ba291eee2c0d25707e32016c8178398b79a4755a0c91e3aff57ff5c44a9264f01eafb9551a2f58c3286c345c5cd85f6bd174aada08e46271a7a93076d629e2c91d048bb0248c1a88deb604e7c7a9e6ac0b7fa3f1257810b5b9d9a14eb2ffa6e01e6231758843d4db5b15acde16daa017a83c6cca6743a2d1de1f676ed84128d27ae4707a03fdcb3947400c5de866c4f88631f7f70a357e47a2485db0f523075f7be5b4bc41fcbbc4b4f0515d53e9c3e67380bc50ef7dce7dc178bfeeb26e3499196943e9dd2de5e0a43dc2ef8c13561af5f3f3710873391392c6f0326fbbbee36f517f4201acfaf35cf1d457f4bfb1b36771d1f4519872c80977fa418e60d51836d499ebff4b64ea226e91411cacaf030214395a053cfd4ee6899294e76001cf53ee9fc8038e3100f7bdf4a9847eae569a745c33cc2b74df56e7a3d0af8c4f4ebcc7faf02b1860c422cc6dfe70433bc64b1ca0579dae46e2543344d8a780544501b40a29ad36fe9b68b636e89b0000000000000000dc990b0000000000414f45873c6f1ec86720420e69b850d713b4d3f8315c1c834615bd42e078fac7ae0b1b431a9252eb08808b700f39628667b617558647df1468a010e9fdb3f07d5a8aaecb7e56c9945c5dbdb10770f140efc88d5cd952404cd5b2f95ed154fda1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009de0a6c013233f2c9c3a314c9ebe94a8074df35a0e66f9c4ed4ef329a3d3e5b804e6ad71e9700bba829311c4d154ec4b36a70efb0142781256203292f916cb5f35dace115287e5da90a53e5522a5f06604dc8d4e2d9efedfc51559ec6ea99144b7482591152af49d2737d2e94bbad538f2a651859b1eec2f5cf71c389a9eedbf03048f672798ee5a0aafe6fd24b576915fa7e11f63df95622d63a2488d74d375e2032e5bbf1f3f76df6113f22bb45673482c58ed2a01f04b8447e16b49eefeba460c0b00601109d56264b4b0fc7ec42e7476f561a8a500cee539133c08018ba69e7004679e88c241fed05eae6e74a97b5380c953b5d572456e4c2510db08a7ae476295031b251b9164d4dd8bcc7dfe8c1ea1b4cb66a30d8fe66590e763d9e9e00a4a54c7021a5ecc88c23be53e393d2a6a81ae77eb7c0787c8f6d543ee12cf54f5861f443803107d1ef6807d7e7c026dc17a97124d325b842aa082f34e7dfc67f2da2bf07d5d022d4d95a8ba55fa3c71f5d148e1f8c5bbbe6f040e42985296d0f85a22362db7a9022becd4967a2fe1ff81adabe3d24eaacb58cec223d0a3afb35ca34f563c5fd227c66aec8e7659135bbf2fcfb740af9756575ec99c1068d57a5449653b1898c3a1d8a48f8a0be51d1355f435fd041d5c41ec544bc933e728fc62b089cffdd1abf04dfd4fb8c6b4f1459247512fec3323ed0fd0b20120345a47aa8eb690c3b2e0a0b6dfdc902d66cd4914ea5475a9b8f12a7b387368007eb0e5ba7859d13031c9ff99c2ba6ce5dab12c178f56efcd1ab0a69db374fb852e11ba28ac8fc5b96bc4bf3a3c478f6cffa90536f7cf025dda37a257be5a7500f84bc008100fa2ce0ef5cba8d8d847a30c968f992b2930fb1ebbec7c66cb6b4323b61352c1e8fb9ad40220aa8db3c3472e569ddc35900a404d6699d4d8fb3a19ae410b823cd9342eac57ed135a3d3f62915763de627f04569a5a32798e3f38a28ec98ed4e49bcb6b0ba7d97a56648571917a6c9ed4cb8ec8b8e7c2f22926d2d7fb07ef2e4b72e21257c7bd77db0e06733a0b5df4310a3221b9d51554309342643c60e7c072ef2310e05778de89e3184d4d69b8b59503aa23b74d72737dbbc3e8527f6070ff3124c7ca9c5459041ee5ce29da0e48d90cbdd055869459c269b15b715b6a42f6e7db7b4c48c1c82b1d29dac22f7e27f001e3ae0ac697e6337d7b5cf0634179139a249be5719c3c496e55428e80c2e108c18065feeb174ec358ca85f0fcab348bda58e0f95cd11385094d6a5143c8614bc7114d3addeee9ade030308db30f5efe9d7948139ffeb85128eb97a3bbcb6a449229a6d56c6255228be9876e15fe7e22898e329eb41db8c764677817be4737b56a3c8e8cae305c2c91106bde4b4b189f603fcdd0f3c127ee3997cd38c27e70c60c0baa4eb23be70678f286bba3b5d7b4389ee14a9a691f2b934c8f4080e79d560302065c9404082fcc5201005586ee97dca2bad041a7117ce5f1fa12e92dc93269348493e53eef1ab387c6cd1eed12ca9b82faf68b16815b502773c72d34916a7dc2298d943515e4b6f336ed9d3cec975f03639ca4ea4edcf1b6314709748aeb81f8c77f00944e994b1afa8a60344a47123b2e91dde93d30ce682626ec02b49c6059574000ed6a9659190be7991b4359c3a0dda1456da1673bedd963c5a1a46c24b44d1580e986d85e0a7ddc9beba63548d76fd97290b5484d48610cab5eac0644c69cc94055ba984cd43d8b0972877f2811e432a546b72cee2127e9ab93283a10d164a65a0cfa48498a1bea8853b742a0a63b0aca2b86c5ae8e9e0f54b76707ce855d956817a276d177c7c793b9a77e561308789abab3a08dc59abd79acab0072a17095b8f180442e5d6328cb513a6f44f11022332ef58228fd0bfc07882de83453748db12e6346475adb1e7c03334fbd3252551208aebfaaa6e830b61554b9cc6f989b96a260797cb9663d3dda386d90ba3a7c8a879b8ceb8c32298d992ee2d2423c16a0b303aceab3e1e3a6e4e5ce362561c480e9b2be529bb7f91c0e15b19d5709b3dd43f1dfad2b2cf7f0e13b764a9dbe58b4ea24a5058dd6ba3508693176e707170f7135afb326eedbd448681c1b612c478cbc085f91455a5d30c2f6460fe82ac2e79b56b1188e7c3514c8ed8a37e55b31e98aeda7c0178bc48a44cad5060a4be51a056372e3e7f5e91f812ddc7af833b3dc4232a41200c38406a2f135a3ce549f067e677bbd0644136952341ec6a70db416d9f6cc9719c786fca027b3174334d8be81a8400000000000000000f1e648050000000046268abcb2b692dd725a958a074ef030580588e5b91e744d8ce6cff075bca3650a3b1eba653bd9c59f6005c7e69df1b8cef690fd87aa2bafce424dd9d2751114062d6b5c09c326c370e645942856bc9dd0aeac83de3deb30b84559d8a1f214c400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dbad189cf31edc7819528e9b49bce987cccab2842357395898c17d6f12a9b76d3371c546368bb44cb87a2b454d14a5974f74fd57c146414c372afd48986e4b03e8b42e472be855af420cf2bc2697e1180bb351a9f4340481c37c04b77924f2bc783701fec954b645104af5c96f0bf72513977877ee48446d58b11ff4de6927e00216975dad2e85ea7836452d7ec68bda1e26237536d09fa2d955371e496c3f07bf0310895a43e334ed7390a0bdf4351c56933ab730e6e81003ef136dec22d8155aa50a023de68f99b23d6dfba652bb4cb8996debe1f3883adb9be6935001b64a4172d031675fd4a3dca89e1570d5ff0c42f3a6bb337c0fc2d966167f04a2a2874746830324f7a669c5e9d0640dedcdcbb79b0d07a51ca8f05dba537c8bc1242f042201e903198df3d15f5723fc12f5b910167012c279a71a552c7253a91b752f56ec4a5c7703172ccfd698fd685c674cd4a66844aa5b8e9c513a3471b7d8382e5ab58f2bc5ce032308bfb449861f8952942ccb31c38b07b48a6bb3e93ec115875c009d723616580305d23131aad77aa555bd8ef2a0f7c5938302fecd0e4da6dac31a9fd949a004f8fc3cf74c097284fee4f691f192018057687324f8a8eacff7286d5cd6b80fa8846bdf94f1f18ab579d32bbe0ba8bbca24cd313ba526e20e18e0c8a79a15547845b0ce0d627355859c53464c5ee3f7979990f719e89c6236e22fb323a984ecf4f0e13ec7ed600ba47d84e561bccbae5ada53cdde6867f1f55a324bd716a6ab1f7bb1d60e94e6ce38a995ede37a02cf3af4daafb1a4e2aa311da36bcb6a940c1f08d6b97b4c1b0b978838f8a9622bce068d99dff003d35ff1d56f7f50dc0623f96e010656254c69fd10bcf7f574d5fe3cd288c475ed51cce6ba951a6345afec8ed12d4651ba498f235a5c6f5ebb73de24e8ce7fd2dd524334b38cf40a49529031e7213f4561a08802d826f37139fbb3439868bd4988c26c12ea3e0e0b1c33b54c37a578b187efb9d2f1d584a7ecfa78b025f0319d84e72ab1c519a505b70e7a0a6a47e984e9dce15e425a689f8140dcbf9a85ed7de80549329d811dde08d207b5c78f30dc82db1314c0c92fe2470e94b0c63ee97cd92a7564b2c4c1c0f571fd864dd674946c065735ccee96b5763b4cc45198f2ddc3a1681985599417fab2d6d49aeeb7380cbce09e2c252ecc4840530a82c9d03765ff7ea84449e6137fdf9f99cbbbf245b6dfadb47097b5aa1b389c4ba78be265d997c5697a404f319ccde9257566d43419e4f202877c9ce295c53c2ddd5d6256102de297e1a742259ebdb1671b07cbd356293672a108ae35cff8440d596302416c0c852013ddc88d1066037ff57c0cfa41cfa1e39ec513e0f83d430f37702532ea46bd04775d57aee6058d68a0b1bb024dc080a2fdcf20f14b47f66798fa921ddfafcbb3cd3592b302c02001a15c68d30d7e0fe6372c9684bd54ba86a916af06c9fef63cf15b67f84b0ea631e75967e78fd607fec95690ffdd807ed3d4a4a7742f5c978fabd3f26b3fa439214c3195e199f412dfdeca668ced82f29fed779ea24482f9a654aced47fd7d14c53ff01c396a422d8ffb59ea7eec63327c665f3ee19efb972509c3ffb133f91c5fa428f102aba3feee847572c5dfb6b43122f6d80092793d498c9e9cda789c67a90800047ae047169f5c5dfde5d25d28379815f6554f19f8de4a612923e8d9f9a01cdc32640553dc9cfc67fb9da6259ce95b288a151bb1c921b190d6051862ced4e4b293aa015f26098fff675438c02952ad3b1b01a907afc429f07f1a3125da53a34a95e1eed2e0c996e3ba8bcb23e00420c871769133f156bb525c0f22dd61d8501d8f4aa77460eb743bf237aa1d5c48969fb89bc4a812b6fc14b000255c30203e38f4475d33a378eb89b985561cf9a60c1e1b3caeeed41670c8776e534430f7e9e2391edd955dad49c5ef90e0d8c46d8dcf358bfec833bac99337131259929db142fca1a5bf494b4c4cca5c0f340b7e0bf67b3e84ca3a0b9d2f0b90269c083e8c6aa4bd1d1ca62e47285fc34331d72fa7904936f530d503e1260e4e286a49f15aed8d614d44814082fe4b25a2381538ef403881bbf74d125042c9eb986663d658771e54edbf6a6525ca6593bb1a4a59bf1bb79ef463b502164e24f7e73a16ba2356282f76f2906cbcf11827b6048f4e3081942cd6bb254a213c39ffaf212d5aa501092f2cd78308aa4c1f16b702613101ec79979d7dbdf6dbf035f6e2ea82b4706cfcb8cc5711af2068aafbfd1c1a6b432434f0777925a053b515c81389803b1968673692bdb7760086b071fb33fe3e7fbf813e2a490ee7f0c322467748d3f84c284ddaf7c1c9c39b8ba9d5e86fd310ef3e1c04c4b7fafee286d0963d455286f62f3a09959b966ffc36a4c501dd9a51c8de0c", "636a", 0, -584490157, 0, "6ff7e51a7642677c41bde46bb71fbeb043aa76af0225f797a0e6b2667e39c767"], + ["e6ebdc6c02415b2fb27da57a28674d3f42e7a6bc252bb0e3862038008da899e35625c12eb5030000000552ac635363c1e17b8be8bfd00c546b2f7cb5f2f4aad3014d1fe14612cef1229e16af85e66c511509ba02000000096aac6a6353ac535153ffffffff030da2de000000000006535152636a633572d7040000000006656365ac6a6ae24740040000000007525352536300536dc25e020100000000000000009529190000000000618bec0783e662c152e90a20ca7a1f44eded7c3a5115d57e99b4e10215fce5b3e467b366140b5ee514016f4b462ae13c0eb6d1278abaff95fd56bfd5b8c5bb66d5f0f292dbf4b8c7d8c8c62ea66104b2339d0be49d4f420297a883862bb7bd3200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e1a45d6dcd9783e9052b1422dbc2f415f2de67ea0e3542bc0ad24a71daa587cfe14f212b6ffc7325aa83cdd4febb7ad5d62b4f7781de69aab844b7ad3967e39285e24c2084587f3f1d63ae497857015f4fe22fcd0f541fc9a722e14601ef527e3299d444d1b0c642dc28859808fc9fbfb2139996eb5096d5c32c974722451a33030214a8960c92c6e7d5da1ddcd3ddbe365bbdaeec0ddb8ab005120c620445028203065e9c695c5772f2fb0a913ace2a77b379b84089557eac02e676de202f8aabec0b0315e186b1241594129560871857991c19a2bdbb73b9ffed407483bdf5c0aeb6533376b0b9f40ed06ab8e3cd02481b755c316f5362ab569a5f056bc2df454a5e031df72550bf7b56d2728e5e746561be7838cf345b3c0d9b00a273e246449a7c5d030b13d3598e46b1343349e8833d899a0c5ef915077b0f8763288c78eca0d9d7000214196e8ebc005495cd5bc766132bce710605b98b1d638f22bf8dcddebe06f457030d497790b0d23fb1abebe2bed482d76418b99d3b56d10cfde289ff4d1dc2c09f0304b693c785ebcb61eb1da3e21ab2b109be757a730ec8f84102349d4a4e965e47784af66a354012b649d32b2320b9edb5c363ce71b971ce0e7a31ff3dfbff05e700debedbcabfb15a062f92c46b31535f630162901b9e1296c3fe91a5f3fdc187689ee8bb04d4302dccd2406c7ac579ae5c8cc5ee6ed5b954c39d599c561ade8a56129f938685629c6a2375337af9ea09d7a0f14e78ee81256d077aea856d80072c845f97a0cbff1edea3e2638336bb3b22545fea11b8f9fcf8b43f217fe522b73fc95a606d7b43264122e254ebbc33521551a8c0465e3175f8593ec7e3b293ee3d3f549611306596b3eeaac04d3c520f4a75f2acb3f4a0893900ffa99384aae96276af51b647265a9e799b4e73f857c23f137d0ce1d89eab0bcf3380ab01303b0ef9c8138c0a4cda68a0e6d36393e91b698454492ba887694734ed3471364c90357143ddd90ef9a2e35603ee9a889f977f69f4987274e6ffa0dd6b9572517fc6214fccb60936fed8c3aba8c2c387048c284caa11183bb9015f0e1c4e3ace05838e8383d15c37ed12e5fbfc804ae1838b1f6bbad5748f36ee27afb435c40f00a3e2c2afed723a06af7c8a3dac2a00e40e3de883bffb6f7f151164e1cc3d0e3104aa9e2596045b9e47be94040ba0f6f8f7b3b9f522b98a350d22bbd32016fdc5985e6b1202be4bd19978a08df8a35e8d97b7a731bff0551ab38256ce06ea5f3a493d1d94a7ce0501956007a0a475e53de70fda38ac954ec17008e92036711872138c05bb5b88e5643ea520135b4ae10e8b7010c7abfc23a74d84b4a4bda054513c4d156578d5963ded66f7e079dd9e0163fe990c37f6ef671594b2fed532ddefe3eeabcca6d1628d4e0603fe15ce2db9f113a629563da6cb107e7f71010c428754d0690f7130500cb0d0c878048e9e56d2b5b8a9dc061dda3ac8e49843a22f2fe3bb66b385e493bed47c9291505bdfd060162606a8437d3ddf1085df1f2d3c079b3fa28dca1150249cac6610b9072bb1018e5c107a9bbe42072992555096ae2aac35268a533d5f00596f78597d5842de8306abd86d2313a1e314820cdf4e5f6a537352741f81df39f59486bf123b21d4d835c2a0f0c6932f9f24e947baaf23658724309ed150b60e28d0812c7c9a0492f65d46b9583f3af35f4500d23c966bc97f621a7d4de1f6ffb8851c8bedf4ec20699edb51554910fd7c3657de967a16c7295c8318863aeb492782fe87e60a9bcc8bb08c8c92d1d0fc5ff1db05b4b874d0ee1a20f26366969cb2a4672613574d43f868471f0f2419c625feaeb09e09752e0a33c95372ec06ec6aef5e85a4aa755cba32f0b4f46b7886eebf5dc99730ebcb0ae4cef780e23895964d41f9405531c555644a285ad8ce603f2720ca1a91a1c3b5bcd2b5fe441e7f3fea7454f0d3941ace3836d33504fde30b6c28492fe91313ee4c29afc5ceaf85f4ee08a693b2d2ca918901d43526228409f80b297b38cee85042e2828439b68f9edde5fcdd562dc432129fc12669dbc85f77f1015cf0fb2a3e5c996ea52cafa36c68f57f281199d7e1c4aaf7dca2fd96716ff2618e30cdd4681f4c8da9ef0e5bc83735ac6c1595acaa63a8397e1f20a0da1b65b9e655c37961a51026f831272484a931c4cc1bdb39af350853650fdb39278b2dc17a6df1343705c87818854064022beb2e97a20dfb5d0741ddef247a1ea867940463183c9e51f9407d9fdf2871fd5b3be62d7859c93f8a1c7c54e9bc3f2fcd25230f0147feea0814bc2baab5d04a8c1725f439de0a415f6437ebea906e0e2929bd1ecb645dcc6e417295ccc5ff1eccbdc0b0852822ff64717f889dabdc7333e4c2b9d3db1a547a23978932168a144a7cd4ba2802724dfd09", "", 1, 1326535143, 0, "820c66675d2820b55b7602408e8cc7674b39e9caa2af60dac41e4461ea270449"], + ["b981b0440243c5047ddf3c20ad8277d0cfe588c6731ad05d923691a558a2150e35920f0d150300000000ffffffff8b3cb7b0208359c903d2784c1dd211f1f2fac9f3a01ee21fd0c996ea36796e210200000000ffffffff020bdc3e020000000000b57c9d0500000000096a655253650053536a00000000020000000000000000b5aee20100000000daef86528d83cbe2e6209163292e31f9fb812b022ee68498a2c5807c43fef1ede7210acc6d85e279ba5c95929440f913959b94e24d9ccde30a018bffaf80f5089855be605856f6b858fcf0427a70e6418e362e5adea7ea7fe740f28e93c7afe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f341b52145c0aa2c0423286abf641763b6c3b47a0f32bbf39e71bee79a637b3f9ca5decd9b6c28d27420215df33406c075f87e6877a7f2d087a383716d602db1af7b5f1d6be831e5c5ba883338931a017b99d4fa7704d83c12911c30fde224f70f25e5435e9057afb32f774048a12115531084a72fc94a2c8eb29613810dc3b40208e1422eceb1834d37c2b60f96b2141f177ec4e63e5dd6dd1a4b21761b06d731021be0bd49c6de687386d729b1b577c0b260e27d2fd4b9b290fd020fe1ced4b4ab0b01e4c221603c2878d361decd7bd64407c172aef5e94759d3ed61f986053bc1596dd3029b58195ed4d802d8625076e5d985567ecfdb5dead9294ec07b251fc4510303c0ccc8cd9d0b2437b60d38f2c8cb9b1a87d22be18671a95d0b21a709b972bd03273041758b0ad6ec68ff8734bcbef99d384443d2f3a9f66d43582ff787a13d05031c2ec09f175a15f78b59442244778f7a2fa2493200ca221c9d06466b9309f5c0022bc6285ad539f8035b34d2c755fa9875dd2558f12aac8bc18dc3d40fe325648c0224aa609625bbfbdf972e8396938bb483a7129bfda69d95cce80e22832dce8ffbb48b60270421012d1089862945db2cdbd4dbb0ccaca5e87ce2a4dd0f5e93cbddfccd4eab92ad02d074f3d70d73067baf989497cd4548adfbbdce3b148c74ff9ddf747132c3d9a9285dcf2461c71662a8c94e35ba9c40af169390d1d4833c740a7ac742fb031bab6237ada8423ecc0a405f08b4b24072b3205435a46c3a907d12ce7cb3da573b5db52353811e1c444192544a355f47094410fa4cbbce8c327db05d42675e351c7cace35e8d8208c73a76b2bd3f5cd7d74fc3c1da773af9d097785b521ad9cb34ab51f877222eaaf37a78b9d6540c54bfa3a0b1d651609c64b2c12539e9fdf7f0f6adb2cb6f72b3cf1583d4adc53081ac348e446f67c038def007a0a8475708a2e0c03de914bc4cc78e73b3c0a5488a78b9939ad3e0cdd3028b339b1fa85306ce8090b515df304edd10bdebccc17632ffd267dec9b4b188aaa1b2fbfee3f625482e03acf701d3962b22241ada13af161152baf31cee09d1e04c0a172bae5a1cb16823037a0e18706f5d102699758ef692ee424aee6f44d030b9c576e0ef88533c8ccfd2af723ebefc91feb74cde67e83477f26b3fd1a3a19b942f0e58a82c17b26ae42df6c677c8819c6e759d238439824c5de7a09663b95f161667fbd510175b3af07c957e273de1ff42a9859902262774c6b5a54a463c5ccec432460e403d04578f3c7de8116f33b5082e4e6f36e9b79b454915d6aee95db79684ed9feca51ddb470772467fb4e251b71b4e26201c404ce3a4aa407e47251062e049e00e777beaacf4eb1582d6b4f84c0db1118024e0870b6d294c9a4d1b7bbd49bc1503e841404da05d0c494605c52b230d8501275c5fc3d386592e439cd620a0b8d1d3567bc546a08b01aae263e03bdc5476857fc92cee383c0b7ab11205a29222a91474bb532453023952b5f8064359b0e20049285ddcc14e2f3fe37943db7f5ded9a9e63c095c93d7b16811aa253834f5c81ddb5c11fd913f0c97abb9acc4050912db1cb5c65df87116b4869e704df27a9b61fa808ab5271cdea29d3081799cc1093e9cc2fb7b3030c7aa6b4d11dc8a321635c336afc35aa0d78a5a6ac5e5b3234c0425521cc3a8adc12df2d9324866c79c08b46e9d96caa7ff9bf44ad19368d91d364edcd9400c8154dc623e2b2770790476ba7b0150def03b11972a0d57fa705868c1c1fc5fba381729894bc52d5f2b822bb7411928f6b0570787e00e43382189dea1334a2e136d2e3976d7378355328616ede4a8a1841796d3977d49fa79f6182ef8abd8a989db2cad1517f4300c97c1d73bce70db6649857a4d8a286ea808f3500ba1f797ef86373ff7a68770ce001cfcc8261a944b7c9af28190e0cbc469076caa318e9df8861d30589df8bf1393731f23c755ee013006da7e7242d1d06be47089fd3f6fc54c4737d6f0902e273ba505b514f40e49a3ba6bfda659c39bde54cea2fb80eb6fc1e75a97b95e21695aab5fac278c2ef8e6383f776300f87cdbaef73b99f5bcfd186751c916b65bcfa29b9202162fc01cd0efc3c5a3122fa13e22da25ef059ba5507240f1973fa8e838cfaabd4d0fcecc99c1d5d18114604da9677d875e2ab3c98643603e4a1b7b599e3ff5442e46d47ccb928859d555f9055b3a3008fac1cd39e7ed18457c338519fdf6741fc2a45f2658006119a57a8bbb08cc75f37d89aabca952b2f77bc5b6c546d8e9000000000000000000000000000aaef51b80af393dd8da5018bf241f9ab7cd1d071eb7afa0fdf119581cbca745716d75a40613a032b1699e9e01522506eec23daa5d5ade086c1473bfe102c33cb5465b6bf799dab981fecdfcb12c801995f30047b38e16915be1ccab4b158410c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009d748a61c533c269dd0ba568a440051e542ec88ce0ea23c83b8e88271db7ed0b90e72281adf7752c9511df730cda54eacda9684ffe8f8cd56e83b5d7a4d78d415260c1e5d77fa42b107041c185d17b4b40968a9082be90e6c910b5bc96077b0ce0232ef3a7eeb2687763db552829ff5d70926734a66738bfdf2afb1063187b690228ad63b9b185ed105c3e18f88c29cbefdffeeb4c44e5208981f4ca86d3c188e3030261e324febc669aa50278dcb6756229843dc01981702a063ceb2d57e68ccbf80b08452ca8d95e44b7295319877097456ed19c1be42c23fac7e76de5996042d52c6e1f2044d082bc9fac3eabc16b66efae59f70ed65fc6e40b48ea2e90e13f2288032484b6774f4875bf86c0f4737b244bd8b94b8e265e9cd3159822760b8393fc6702252e5920e809fb03e22f70c6e0fdb1d39af8f0a1805b19ed35ca5ba784aeda780311a51451e8da2a3a98adfa1f485b795ae05c91dc56e0404f7a64c2102a3a35500313eddbfcdf7c7c8a39f7587e984a499cd42ae4d54d00a808b78a9a3665cbd10e03220e13dc98061300c72bf532123f4f9199b52bb4e0b3f0ee2ec7e6324a9f1e4de64f964ed495fe4510b32d3cd96a86d31790ee04687cd7cb1caf4a4dff62d7a0c3dea40d3f82a086bb8849ac47f911a16b486adcb7e65bcb5f9023544a5fe3233b6a48da9a1eb3ed10ac4b7633562b6b766db2e5f31bfe3a171c270768875f16e27a532e2f493f04596c19eece5ab63ef110730ab14d539d4a83f105a534ad521f555325e42c4c5695232466e42283e29f6eeaafd7d78e40307da198105cb798a3349b6c0ab10a29f16c0fc16cd0fb03551cbfcda41bb4f9d325f972f3535521f3f0aeeb462e72a7bea733e3ba5143cc8c49b277cc5b3e1f63d50197ace33045fb9d4c0105096285c1b84d7223507737f5f35204c16e7b7b8c7d7352df016f437994cb6d260582b1082e5cb996cec9af04ff73508edc8bb88979691a01c5d966d8d6f0ad9a15c943b3b16a7d3227ae1a5e43950f8a4711792bcda3468d1fd91378b0432a95dcaa152a7ca070a0b5e20827d57aa16ee6d5b63351d31cd98d45a7fe09471e72a9d1b8cd3139ac54aa74910a37bfb8fdd6db342e819d5793746a4e7007166ff3394e4f30caeceae900afdbce3a43906e06553751ab415817d614a815bf657112c6032f7e2b064adb8935798cdbd2d58cfa1c5eb5c660cbd396a3630e657ab50302d7926304027065693d0a8190c5209df4f61dbbe783c54e793345c614998b779b619cb63a719ebd9ffcb3f813a569f7e8376adc08c896354ddee0689cacaa9df6c32e469789aa8d52972598cc2d5316c1f22b53637c34cb1fd83de5f7a8e7d50257cbfeed2e0a489bdd78bb3bff9cec33cbb3f26eb9a5fb460ab3ca4e563a1b6488df12dddf4b4548c7fc78f7402b6439c214919be915533776fe82290b1869537f76bd0c8ac823841001c2d0da04d9fb02c0a11ecb9e1e865d672eacfff448fc7c09ab7b16a45911bd9760584133f202af14974160207d44fe724c1b7b15ffb548bae9b7399d73cba4b5a53b717c45fb5c3827fa92630ec9b23de9b1a0149620ac75e155055e1d2b5aa4d459c37ae7ef73d5d60d2bc553dfc9880250641a5503a2387b36c27f06060b9b4f3a51504a4e039ff3420285d272995e8c5616e56f69bb96236eb1c506a3be74cc4c21619e4585217cd8877e86b8ffe406349c5d021dbe513b804228664a6dcdc0664c09e8f8fcfae2516f9c679eeb22c1e2cee882397c12e98b7fe2d61780a608687b551269e09de1515543ca9ed98df0a8820469ecddf338c7a70e842ea9f53528c72c557e43fba590cee0b04574cf753a3efc3f9d8520c63080c12ac4a8b4be7cee695161b7ca28e2ef1d886a7499d7034ef33a18a80791502f7aa20548f8533aff64d7624c108500dc0ccacec025b980a49d904022f3be2bae3d0d40521b227e74f2dd68333e302736fdcf1c51600b3ad5fa531e9c88ff5a6b0cd4f4d596c76ebdc42c1cd990574d26e439c24d927094bf3b6be64bf29a00d2184ec72a63a65f39a6d410e58d729d7ce256c470e11394ea294e89f879f0d4b4efda28109c9696dc7d3e004222f2f60420b4b493981460f7b0aaab784fd16805e3a9bff1d742f17547eb18d5f964d94ad1f4e2bc07e89474aa448a0803ba95f6b08c636b810815b303f41a01a739c2c426d2608f33d532199c86e7fe9c9df00105607d5579f62475ec62e6104eef93df6b0a2c0205c01ee5db87be51a08cd929376aba55079372c3664deb087877090c8f48d445ca7f7e5d0654e082607324d1211890bce56c83cb981bbd119ff4383a80e2b69d474e44cb5725bccddc9fe8c6c3a0727d5cd3637eec5e747e5dd6dc026950159ec815f66a2149d7cb53da61c8fd3382dc1fe508", "ac", 1, 2133401921, 1537743641, "44580fe456870b7e196d3c41ca28fd4e87215128b81c409d9957e19a19b42a94"], + ["1fffc42f024d5f96155009202f270cf30915d62caf43ece6f6964aedb0964114a71b9dc40f000000000652630000ac63cf7e14dcd821a84bc53c5c6d5141f152348bad3f6192e8686c2bbd5679e8cd8de71b05500100000003006a65a009c12804708fb2010000000004ac0053529bdcec030000000001ac9d2a1101000000000652006563ac517d52260500000000009930591d01000000000000000056fb020200000000b779a7a3dba3d571de333876d98a52d8d9ec21e1b9fe9ba69eef686dae347ca358bcbd06c910585e27ab1ee746837bc6ae07f5d379a90d4fa7ebf82ea09564d512c907a13fe802dad39924f15badc937a9005238e6b1ea35fd4688f50e10b5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000736138f53f41464cff13ebee666d86556a02794671141e48b9ec80fcefe37a160132e5bac72733ebf41482d5a392a6f10d61ffa4e8c99233541bd9edd1abcbb144a16d12bb0e0fe8b7150fcfc680e9b9439a2adfb634b04839cd9a5a222ac9597ac0b103745490fee4c23487b0915f62e4403cec84c7757f91e957e0a1eab8fb020019feea91cdc75df091675df58e010d780fc2a96af2454376a29113a56cc72e021035e2baa32f57bf7174b49e71fd25d7260aa9467b1f64e69d4344e838a0fbbf0b08a9ba7a7be20fe8307a4afe8e674b9bc5a65efa39fd889efdc6d70e8ff0cc89ea596abf0a9cee8fd06f2d9bd6454c0172e364e088f66691614c86d3bb3d763403238ed84a52b8355a26daca36214463bcdeb694fab79c4bc85ff526e88c9637550211371c0fa00d35aca499599d207f7d3a2849c414b29016bd6d69f858bb6fd05f0302336c9cdf7e4f635627be64e1288418c4967474d1fab39fdafeb6b6cd18bc99022fa22cdf185d5d169e515c8d9e483ff9800c11dd9eb002e303d7d346045b1e690311505ff392234b8437864a57f33c20b460bf1665263335025c51ad6a3a9bb1ed4ff480a45cb1fe5ed9b38f40a9c3d8cd4aed78e791d2183a3409c4e98c1f548af91ab6120b7373ef820f4cd656e5c45cd2bddee57a0d0c62d5c1c43405ce782559761a11f33107f6dd96753f7707faad466b616d2680fbd410498ab96139e39fb4afcfcf1c05362089da661d8e17742de4c5654b1645cf13632c09dbf00f4e577f842c639d0488ee3929ced86f42e86b277ffd9492f34deaa4dc28cddfc6dc7b489dab8369e09967d3a293eb2ad78c361799af137407bef9f63f459e7c2844c27cbd90c9ed35abaf6a4e8ed44560eeb0fc99563ec7ad3e947db9978a7aef589dee364cc6e1395c1a61fe256a0f57276aab28c33d184486de25e86ef24f73a58cb1929076a3d938e6ff43bea12ab6f16727c19217beb8140fcffbf5889009620607de4728bc5015ef82ae1d31fecd9d9be7a945683482f8c195e487e9626a480779ab83f4447015a486d072bf85db352dc552947427a0388a587a14247c876fa70f5abb5fb3294828359edea69cb4b41cced8e85a80dcea521edfb1edfa32ed285612426bf37c551af8d03678339698cf1071517e90c85d6c90eb6512e04f4df1a83be66f194aba328f8cacf9dfd304dbb6ac73551c3d9eeec83394900c4f32691b3123481fce722a20ecbfc43b781fcf0cf5f3c7b1f04a661bb153795506562595db930a8a5bb20684214e17175797cbeffc0aa5ca4976955ccce1177a40846b0507273ef771fd9c6ec44b0ed1ae99d99f18c544c9205e1dad8cc461b5b5a37f474fdf63939f56945e8a0c81d5adb0aed36bff85be53e2b3a0c96c1bec0299d44114d677c0aa7bb7bf43925355484bac143446d7682bf6272f43d85d9b965be375b4db8fff259c267276ef1bb2cdded726d04f12171abd36b332f034958f37efd2a3870a4edbcb76835530c9a1e9be5bd9922cc10b4a0c5b4ecce0480b41ba5392c3e329f69334b2de4b0d6c1668e74bda5ab928c571acab85488eba3011d1c275f54d0b728f0808c8f2f364bc60560cb29708dc5a2a7edcdf8034639694b804a95bba9cb07b26046c9f31873b16961334149cd2804db665a3ffe37e5bffa87df78506d71e25cc39929b05e0718884c7c741513f1aeac9d9d9a37eb1b27d8bf3eccdbf92fa2edcd298aff9aef1a1bc7687f6c4f2b589a86c582a3ea3eb98cf8b4e7ba5fceeb4adeed62cbc49ca27b39a44c47b52857bc6317684515550dde817f22d2c8dc6ac26b485c7d940248322130d013157dcac33fa4e3a034c796cb8a3f10eda05d1425b57b046217cce18df9447ed4e811beccace219a6ac44171ae9c7e9580c1df6cb13a020a87988f5ed196119825130751b1b6cd8e0d9cba36220615cb90176301cac31b934e75fbc28860d7aa76f477d5c43db8277a4b67f47e041edca24fa4da863b8b463c7f14b91ab4d918e0a1dcd37d525ac2a6290f01343a7bdd4ca6378b4bb3c61acd0dcc118306a83e6d6cc307393caf3f4e44d2fc21c6a533db5fcada6d03a4de692cd469f1f9f8d9e06ec8c67c0ed97ac65351af420bf61e15f7d312e1f6eed1f93c171a434e7a22e329010859d481e868150f3e2f1adafe149eb422a9e4fb4ca1b2c539895d1fc80de165a61c1bd87c95f6075b2769ffef5a45c3a93ffe8da2766cf74ffedb62a4fd0a58f3e8dad7bd31fc42b2b883186585d5cd75cc0039f8ea712e43175a19f23567ae45d5e20b73a35d641fe8945aa8e786844efe478e8ba9cf7948bc4032cdc299371657f0fe7998911d42bbb9cac69a2b9913c42060ecac5812160c98e09cde85599d53c7c3754e89a8143b3ed82b5641ca2eb5458135d2a755fb6ed5640d", "006a6300510000", 0, 1859829999, 0, "2bed3f6da8056338bb041c302a48d6f0be911503faa2e84ea1f3d01e64b4701d"], + ["030000807082c40303788d1dc8e742cede463e295145409130f8c17cbd86f43180427ea7db0d08a13400000000085265516351635165ffffffff03a99d5242475619febfbf7cd23b65349d72bb243f2052c2d5c28a773d50fa3a0300000003526a63ffffffff460becd654865372faa6d790f208bab096a48debefd2dace375d78a5e521044a0300000002516aaea9fc8d0434a4d4050000000001ac92bf810200000000076aac63635253517c173b0500000000025351aa308b000000000000e769cd75f226a0c400", "516552", 0, 333701990, 0, "4eb9dce384181783c902f41c0f978df197de9791c67afe3f61d41bac72118fe8"], + ["030000807082c403011bbe2e5132b1b60d288648cba559cfb5618ea2e2eaa07773055d6de130c8b319020000000952005300635251656affffffff022d77b501000000000465acac65a397eb0400000000050052656a6500000000f7941f6901fc5f2905000000000000000000000000892e08667e501350dcebd08b5e43ec69787abcc2df606c6fe1eb2ed025f9ec94ac54413f7dcaee4c91e83e323f8a9493cdb93af5a39b7def15d31b514a4afa89a276a85fcb77a23266632a27ba0e19883c922f9fa823b470ada9c4de473d521200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d59622991bce72a3c7edf8b1a6261514d7251806607c5bf0b169a41bdf8b9298adb63d9c8a89e73510482b5e310b9f9c83db593c925efd429c21c5d8d2003447e388eb6582613c422bda0a879627a732018dfa68b8475f1345b3ebb868652065a94dceddbc2f84959e0b71371905e58347b4653e4ff85d10472b70b4240179fd0216157459e791e23b4a113631e87ac08c36882a6c1be514ecdfaf3d560e72a264031fa699bb0a491eec5a17739e7199d5c7f387de5e04b3651e9d3bf7935d6455540b08baa7463f6718e6b689b23c7e62fa2b4e68cfcb0126d076f3e36f3e7abd6299266b51a6f0f78634b4b5d919560c52c0184ee780b28b91115828454bc1f0ca67022d988516b883c712b6c452fcd7192cb0a60ab076f905e55873ea375c741c2e91020a1b10c6b2c640711cb81faa1cec63642ee9beeb0f359b53bd02b9b24c64b7cd020956c70110de84a0f9a87a03c01a8357032b9b105bac11605df3e40de56a47990304e92c1507497780a5a3329589d0bbf0b164397f66ae2fcd4494d5b9340c1eaf0207baf3981a0ba294479c693ba1551ae2a0a4b9549bac56e648f6edfa7da8f138fc603041af66161e0a782e3709b9c0ff9f8b8d882e09a269876c5534ec5d6756b5f56c0b24e2a1a8508c7a816a02f2b3778c7fb614d57e5fa1bac36aa7b7c1ba6c8796fa6e9b9cbdbdaa335ea0385ea278fc9c2b018228ac80ea65c10f9388c4bc4223327176aa15ced7d6c0e59b4d2aad91bd8279bc835fb8174c7ba4614f4f5e43ec3bd3523968565b40b75e960259f79e07d7375122211a2bf99330729539eadb73c0bb2b67494746543afa3e6c5c7993316350fb57ce24353041d685e328e10d4fe6bc0cc8807dc2036fbae20e0ac8ae3a1f43231dce37e856c017942a40a693990d9c39b3b3da647a7c4f0547e3b0d6802f5f62e33d9220c3b108d05a05d2ea5d9ff008dab1d36670cf6afe8a93f0f39966533cb21a6d69ef41b7bef93c2b953e387e0dcd5709fd6bc0a5a5ee312998887354543082921e487cedff5d3945b63a2120764543562f3d9b804ca94b808b9cd931f00bd96cef5a0a48418691a70351e41af5eabc96ed4d66cd7d225bbbe4fa0daaa365ddf69f24305751020d81116cb200a64fe6d2ada62d85c4d5e9ae788ea038584e78af6b8bf6fe3a94604050ac6e3ec2422eef32a3ca3897154fe49f2ae2535bed8aafc5f75df6c4df75c3f7727b717a96179cafd550b99ca95bdf9366cf4469f5aa591de248102ed607f0ce244a622e50e13bf7650f713924b02107ce519538e182722b2442a5d5debeb4c6e8c4d8d4c36e9bfc74b5d522cbf4b620c6f4d54b2ad779eafc749e09ab3161f73e7d31970accf18d744f53c97f5cce0c3ea88557e5bc5b449ed188f5a1c3a981cfd346e0b1eca53c8a25670aa5153b14cd09f09066da309e15561ac95103341bd0de712afd5f97d2f455d9950ff5a1b4f4e296c446f2e189114f9ed4aa614ceb0dc417a029b7d9c9e30fad2fc0d0c4331f77aaa55065a3526b6a720cd18b911333b062a064db2eeb35e46d99af335e0bcc9a7d6125f84cd97dd8884f3d4a2f8261034906543eed6c5a95ebb6736b68ee7a1bfcc0c74d01f3835a3c98833ce251f3d5514e821df6d514eb90f2a49d5ab0f80bbc595948a1ad05316920317af189845234f801820606fd3ad1fd30c3b5da5f7d37736c7ec08d18f92184e33509194732052d90c8e0b51c82ed5a8a4d245c8078fc3c61ca0fb82aa0bca7c7d75d85f805ba79dbcfa26a78ed1f1ac8204ad99460e19b52dc8e20ceaa19ee23eb3b2a24f59eb35f2326d2887829a752192af7609713f1fd49e1e7904f05651529231eb7895e83424d8cf07c76f83a9eb1807d038bc326ce7a5b6897fb0c330c3355c736236ec480a71c0dafb556a4c944e4425118b07b65563a61e3a868ac55377f9f6f12253505e3fef42a72e0d105490b2afba2892d69c92363522cf134b05b015098d1241e4dfd22c1eae7e5a7213303c75d4a1881632bdc58a424964565668520170c7fe54b4844f9a11159f062cbf0cf1ca0bb820c44e1a64ab291bad7aa42c98eb6e9a626e102beaf5d555baf4787123e39102d803ab2cd5d102879ff72fc4cf17db78f4034441c61706f476e255268d24da0cc35c989b2403157507623f59b3f3b9447724157942749bb0d17cadc6710645eb2a7d9302d7248ba881c2a1e5e52d916d698518364d5a52f904a4c969590db6a68743c2abd697ad0fb998895aa1ee91f168b553887a24f8c0936457367aee2e60876aac44d050c2fbbee6fcfda4884e6e6ad2702fc22e7885502bc14ffa05a87d53cebc3a7d32074e8e15695ee4fe912c49ad69add31fbc2add0fcd6998b44e39cc8f844944cf7323c6d21516c9680a09285c6b72176939289efe97602", "ac65", 0, -1949763310, 0, "798eb60f16a09dabee5e89ff9242110c266cdf5b1e86f4741c16bd5169f2c661"], + ["030000807082c40303b561ca7722f41e5058fbba86b4975184000c7ff79c207821af027d9de95f518d00000000025263862a2d3bb195392f19e4a3a0e17447e729dcbc92941628c30493cbdc6f89f25a69a9842a0200000007ac6363650065510ad8a3e29ecd0c3a061c88b1ac8a9128649c5dea78acba00f659a4034f3a415212aecbe5010000000163ffffffff02269c000500000000036aac0076646200000000000265007c5bab9400000000027d525d02000000000000000000000000357137489ee2705383028cae3b2146cdb0bb96e51ee3919f866459ebd642c3536b4b21aa1b2de38993fb327a77fe717151c84e4cbd0cdb9ccb4185190c680533fcfa9802840dbb11ba979acdc0dac2a967698b20aa1135e4bc80f98ac929e65a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099473af4c0b9c9b6f122c065db4d7aa370ad99dae883e9949c77e5faa1cabe63f6fc01d8e01eaaa723bf3f5558de0df53172697fff14cc08b161ff15df31813a2ebef9396555e23647672c299e850dd1fb1a5046bddca6fb25ddf6b551ed26ea2c238fef2e334c680a75b408651fa23ce0d3529aec31cda32a07698693262db60221a4b2c059ce1d67b56b3c47a0fecdc7eeac420540c035bf2af84a4885757bc9032d1348670194e6d20326d27765e32e4f6cc13bb3ff6e24ce07a1a99921094dff0a0516135870faa4f466abb274cd84752958f20dbef4e4cd9d493b0439c845d222eb9752ea45e93a27cf0f3cd2dcc47b8875dad336320f88a5a11b266e9fdd9480022169cc1571fe3aee26e600a4cdf332b77cae6163d16db7e15090726564ad8eb2030292d252b64df134bd8bc978f1ef42d7bad0b8131f45da24e6cdacfe6b421ca7030a78670c4eca7029df12b7112bc269b6d32fb6c1bed1b7b9272d83661af48d49020e9d13342c4664045f9ae814295245fcd95f22a28f1be2479ca02ac0308938200216f27141d3bcaaa434ee7469a1094d9c652abbe045f8f8fa078e3bb8c70a6194bc8978aef11155fbe7e39fca06d0a93ad7ee1a404535744b67fde99a5698c8b164e5874f92ecf3c500bc0c557cbbb32deba901a6c7760178a5b1d8939ea3e1215e3c3cb63b36cd079bb8dafd199d4f60072e14600c0659f7157cb6ac7f3d977e53527d9a934b2ba9590778597fd90b4fb75a34417f44bebf2bf9f0ef7814a5debea53961285f038f11773297360a71d27910ace00aa7ae82406cc7113c747fefa0c78d0fb857d57fa3ba06e07a2e341e0483789d387e0ba3e39bcedd34e634d5d3b913751f4e611af76bc370c610d3c68cc7fb141be1a232b477265078afbac94c002dce837d3bb10f9392ce2a93b1f7b7c02ee1f1ed47235db480d142722b2a105cb4d21da2211366acc60531319ff943ece40265397dfa323c3bfb8933052755756900aa0400e6cc2850904df77f31ccda6842515b67b65cadd83a1acbf4058ee1b2d71e2798459b2abe5d967dfdce445e15eba197d7e949d638c7390888ec87c5b21466f9adb8ddb299cd9b1e720cb4ad780b5192474b0fa56d15a6c88b31d7ed5cf89938649e978e596a658fb76c6adfc376d64e60cce22f04cc1a8bc8cc19a538b3e89bfec65d39a80bf8e80b16080066739cdc2a2db1b5b76927f33bff1a17eb26bac68eeb9075c11a202cd12001383615e22b240ae14611ab79ba09ddf29515d76779554f81bae367463ede1ee23540261931d9d608951c685eb4ab1f6b7e08096fbd8712f9c509ff896ffc6dc53abbba6409a0a70d2c98b779baa9075b1c7d3b45ac2d230357be3665bb23a86230434c3dc131fd816fcc32682f6393509835a7b3f7a0b35b4a7d4fc150ecfbc3a09f8fadcc1cd2e8df0873c490608f9d051db2f20ea530b4ffc3290f44714a5398c62aa84332faf0be8ca62aa91754fc502c3d2e67ca38f38fa2d9013ed36a453042cfb0a3ddb5b25a78ecaee36b7b5beb8d1191aa19b7349f248051d299c4c8335145da2b4201547c806f021aa648b3c68955e8723342f098e078c9b3d7e705e6bb2d93bc700812ef9690120075cd5b2ae738e6a33a13d85d8b1f3109c20cb53b152d16171bc514bb2705ddb06d11ef1119e1bbdf0123349abb70e7b4c3285fdfa412b3dbf8bcfbb5d226bb62f177ea0fa957f9b415d3150bafa14a4a98e6f943f4074478689b3afea753fc788aabedf47c26c64cca8b8f1bcd8a7c0cb34f5a524b69262901affa3409478394be1774c91f951e5e88344e6eb1456516f5672a848dfe77461b5452fe377a28a36080101145e989feeb98b7b000c89ee61574a29a1ceffe2504bb1037c0bc10d6d41992177ac65eec3467a286cf75bc06ee91c47543a7776533c16e3e85c3025ab70f5af2f63447596e8e85f0eae63611cafe51a97d862906832ae3802d72fe059ab24190e72269e7635154feb52555405591043c4b3f8c2928ccc89a9e7d2257c0771a3f58b2f0457ec97b1e30906c8261c49fe9705bafead70d97075eda38780af9f374da829967302cd4485b802ebe84735fda3f5114b15df82aa9181046ce4b652e807514c7f0d88ca4c94fda13f76b75ae3b27c6907152d1361f0a9734917f6d8d4916a3e169781c9d92a60acbea404ce33760c100e361fb0c94ec91fd10d1db913075ba13fbdd9bd76aba7aca119796c74e005eb91ab57641c4ef6945b67828cf8dc1e1a77f5d0725cd5b8d20f35b6f5607dc1279030000000000000000000000000942fc3d8529e323feebcf2d6e8d615e917157ccb189addda37f6d698a178e5b3436bd170ef4eec2fde6253944c9b2b0affa582129a8b41cbcf16fd01961ca39a2ea1ff96a24bc876db76fac0fc5b10b13ca11c50f257397838543197d7240df000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d29690fc55ad5dc705d8c5c9452eca07116f38f821d7b9c216c3e77916266bc3d3d0a3370742cf5af3a016f33c48bd0d1567b0017ec799692d3d15ca31b4e40dda619515c8a8ac8139544e842e85d58b7e8d6535f928a3e2c55b10b9a134ef9e0669f2aa4d2f9289e94447d1055a812de99f667329185d0ad3cdf07c4124779030ffdde74c7337041670802b86de489c3acdcf727fa4a2ae7b1c3bddd74e2d16d023021f1063fc025f069e580b7bcbdb75f2e126ee9555db1e82f138ea33986cb710b04341b4d961d2013c3001d80bd381cf86fb6b8b2ebbe7af953067320df4c954d2362347f62ab9054eb41ccbe71fdc88b88d3cbd278acd225d78b393ad17d09fa0209dd9c8bfa0b4244d368b95c25745b2090a13c6c88ea7d25923001f456201fdf032a61e56f227f0a4e15fa62105eb64ac23546a6ccfbb4eafd806ec18ceb65f1150301e7c361fbbba09fbdca02e3a84ebe3be5e646079d09bfa424d1b5c6329990290210feaa1908814845ab11b3faaeb67cc477153ad7e721ad6e0c044a83dea08383032f735cd3deb5fa502d5a9956a8843d50b55dafc9c7b9e94c7d0a6b29bb3b4278f87750db6de54e7c6645cba6bec83a1cfeeb429643bdd6040f666ba40585b000f24fc0ca930ea5853188507b4ec532c2a7a739a5f55bf231b855659b5c60ed473cfdd15a9b4c381277730ba79c648a59f2cde6583b760eba2ae9c34af7641f22eee2c300b770b768a131799ddf9090d272b4c74716ba26e8e68907142068ab0e08f4823e066992cdf2b4cae6384c13f058a6ddc1d05a361bfa88ffa98fe39b2cf2c8062e5d7291c1015aea390f468b375f8c5e635099dd74967b63b2a677e02d6ad2e8889b800401fbb6f432699bc7b19343204ca6c610f42736368f0f8633061c0a25aa73be49871556dcaf81bb1181baac02419539b0374674e133c34365ff8fdc0d972f03659815cab22d19cf609e4f8a06cd063e0fcd8ed46d6ff97c0b2edd770c79aa597428666107960cb057c38fa24db4fee03d8ea635b0843f309b0cb40044551a9162977509954634c697088b301feb23b10fdeb20a6acbba5ba307a747faee2ce3bf7743f4913bc1db10eaef9fd9637c433fb3bd3c9d8dc85f0b819e0d074ba6c606026d3b33e4cb788f596b16a1de5b1ebd410ee55ed4416e2b2803ece1e74bc48daaf23edd32153c1a1cdaa7a836e574d738373422155209e72d83e94a7d693e92f9368344d478ab09c57074040693ba02009f9ab8b1cd59b4db40106a544a97ea8ecbe1bdef2a374ac6b6c38e70e677165b6ba2d40afbc0eb1d6aed5be8519b7139fcb1f1a4309a06bf760171244f8df41dafa38933295eca20da5e72c076a62346dcea2b6f9f1066b7845afaec64aaba904dbb5028120085d749b953231876f79b2ccc3d4be8aeeb85cd10a948bb32460fad71de19d69febea56607378c4012b1245c613fcfb085d8def4aa8d495c1e52cf0a1462d6f30abf8539d5cb1357cf1baeb0ab6afc76b5a216a956f5c7e346f0b3d9c618faa30cbf39d6903f359ef55c2c6261f1c64064cb278d6a9f8de9e958d273563e0be3428ff5895be5ebe59d3729d2c2320321ca1176e99f352671f5c7da44c64da6a252435751a602dfcd10ac6a1be19c1c334bc82ea4ba29700ab1bc27d6d57217576cc7b2e35b341ce69fffed6600bb4ffffb8147e646d81e9f2dfe12adea89b0481f1503d1433f944d891fe38e149a6a06078e99af9719d1473b0c42042e34adee6d2fdc697efef6f52e86e6e2ffc0457116f0c9801b8d2f86611d7311430402690177e43fa33cb9fbe7da4dba35ac80bb71abd272598a082e15b62ad5cb749b16334ea9f6c7ac226979e310bab08eb33c35e3f2fb2b5bc7f0e5b3caf209ab11fe3731437b2660be18a7db38706839c62a2926d7f26decc35749d03b89806a81ece72786b4c546379df4df9fdc2244d0916ff284a15236927a69506976f1a71200296500dcc8524b3d92df5e71342002bbfaa256dda81dc60417257f30ec0092fde226578ddeaeeb0601dac85c26b1cd1b67b5476dd360faa2a19bd9dc64a0b939265e0b47bd77668ba3fadc56d17f5462f936efe900bc9dc31c0986dcc77e801e850517999167ade7dad96a4187b55be5970707b8ba62e44381b7247f19b109741f8124a2cdddfd4dc47bd64146bafef29332239c5d4cc90fed298f7d9f6ff2f7cb3ad58a9444bc6dc9bdcba4e4e729cd6fbe9ae4ac2a5bb48b2bf3389ebf0b38bda287ca8e4afc608955434119496c3e0c96ee69cbbdd5dd8a80bcb2c3a68844a2732112223acd649d13c7de89db35dbc8bc0ba47cca6144fd39db703aa6a803a6ef68d3cd1c5302189267ec404e34f3871c9a495e84121e78f6f4d0b2a546a63cb4094834b00fd69e6ea201c7572112fb46beb00", "65530000ac", 0, -545910436, 1537743641, "03edda4937898dd1d0fb5f3af5c71d200e0be4fbfd92f291147100ed8680eec5"], + ["ec18073a02cb9e3ef8738768a2d55782ef30cd41b47cf83694e4beb832d67270c782c2274201000000050053515151fffffffff76ae42241ce6ccadbc2299772509a731ed0bcea525e35b15f2430b4a6f67ec1000000000652656aac655271e4f4e7024e8bc4010000000003ac6353694ba40500000000096a5365ac6a00525253000000000300000000000000003d27a30300000000f8a3528369549fb4380f71094d98068990343e3806270fb90c717bf2554e83e5705c1f05c23580bb71fbe1b08e1959e04c29c74a72b7fd2beaa6c95bc326e410e61ebb4b07af4b4a6ee7665695444a6a53a38527613621aaad2c2b8fae8104b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f54b31b6ad682f03894dd87d556943e37e3a64ea9ab3a74a073d1704fbaaa66ebf2413fe6e3fe5d4aa7a304ea345a563a5ce1ce9f68a84f1b7caaefc949ddb26bf698407e255b5e58417537605c78bafb941f1dcd7874e285013e99d79037308897b11fccda329d4706508c64cef19e3d207c735cfdb6e381385ecbefc7ed889020f88ff22ed7107ae72c9c664dd3ba54f0d67f60bcab8cc13998255218a020e8e032015159442a9b86fd6bd5166dfd4fd2afe86aec47e1556f83728791c5d0dd5310b0568c345c282a87cd7f3c5c507be1262dcd82cf18f67d6aebe5cf5eff3487ab7993df0f9ba53f1b94bef66ea48fb08b9f536728ce97928f6054cf436f1041976031373b2926b6a71abf27e8c3695f8902e89d3041b042586670e229f65f96fdd9e0315641fae4ccb05f762e5507aa9749c6ec2d2aafe169f24d23ac891e1ade3dc7e021814242d364b3299b876b160a84153cdab5245c97dc4c0061860004c99b45df603180d4eef6f1679130bc5b5d8b9550388cc5819c845ba7ad63da9a56cb21dbb39030732902dc56605e5ba4ad993c959157799e76ae9b19cc33e647575c5ed9d9790c42f7399983ce9541b0725e92cc85f8e88a363199b33deaa1d068c70512c9583fe1d652ed5677a7ae28d756c3258806326da7559851f2b1291d6d8d1de29892638cbe68bee9df594410ac200274ccf6b5e3b9040e4c506071a6a479d883a980b3c14143d46455595c80ed787ebb5d74425109e3f575089fdf64ae0b73a1a2594cf3142fd59324f78a933157ba86d95b597381cd8c950b9d9482378396579be30d94c43a5008ccf02a9a33f84dcb3bb1679157c993144968410bf6c966efe7802804144bad0a40316016ac7c4f6b835cc7a72ed4a01761b9ce36e2e2a611004ce73e613c4609a80a6a2d18e01db5b869d7bea982e9b5b2179de04eb341ba5c6d2eb89c89da738f81a44c20b472078aadd965dabf45cd5d3f53cd74f77993b678eeb7d4db5310ef649f62f0e3e0fbf3089ceb04f0a84549aeec23b30c081a3dba3cf54e180ca2b1f214e80b3c00e595177ecb25cc7328b916c36a73ff3b5666478fe61558b661fa630dac6e6ba9edff2db055053335e0de4fa585eb24c4b4381f6f5d9cc6b15fa3a10496a6bc71b52151cf9deb16c2d521ff80ef2cee834ac421a2ee0b5fd69167f6281b08a9279bbb2c90671eee83ae5ca79007f9935af101ce8fb0f65aea375f9b3044fc5a54df5c4c7428a4a107fbc90dc977a0ed0f16e6251859ef840d1b546760a839189afbe26e1c8d78b3c6b4ae46bf6755fb20d340d47e8df04812f67da834957864df816ed8e0bd96326b58d555616a2d60fec80173286fd6781cc95c7e15ca853332e6eb3c5f1d7ad647efabf840a8766cd145d4bf3b46d7199e3388c9e31b87d521b4e579a153a9b96afe901f463b1aaa0cd2257e1ab88d61068eac336cdd89c9476f19dd381e2102ed0142999cca1b7cb0f7a66f5d8c33dedcbdc2ad5c1389049e6157339fb30efc201bb6b5fdad42da452eacfe9b1676069ed5f0336c1c458679e0fe7fd518c68659cde6b4b1a44a8765954345a4342ad024b1825ce73f5608d1d6ae1ebc8e59acdad3b1860be7e29675d44948123c73507525f06dab7602987bf8aac595c2670852441616deb85a211b9a65983ac36ff8f8c7c3fcbcff70817232aa2316092ef9c41c6047f61dc31abf8f0488556769b12d445a28289116c2fc7ad49d939aeedc6be3b9ac5d4dab93c02bb4ff0f87622b45f8708bcf0a0c2e7a7eef537c03b16b062a8de48122aac705b79c5927a4cafdc935041714dd5b38c716d9382ba9c1e18158101d3829fd9320708eb2f6b4b7684fdbdc334de3cda70987c23b94f87c128734189821956e55ca3b7451f15f86a4ab6189e34e3315e9b51ea39dc151d440022803953466d001e0e2c6fd8053b0451caa31447d298c6ac8291a86eac55fd997d6af1f2c8cda677a24a7a8f04f09ddefc9f340454b375eca64584046cc2647ec3af053851b73fedab60e010b0fb296528d42c9d87b2003f492e0fb8d9a8df40ffba16d3fe17b5736211120d15be1f8d2b1a26f53e186640f62168aba1c4053489490e4a38ca81143931523782a557b315f2476d9e8e059e7daadebb1306791b164fc17ada47a51f6aa403a669cb41bc49fcf9b878ec40958b3de35b63921a557d3ffcecfbfc3c715fc12a2e1df2c029084c1f7b5d52abddca2b50dd2e180c134d6f67ec5f9e22c4aec34cb6ae1f498dd41d5658b861331292a22296ba4e00000000000000006862f50300000000f963e65621ead3f5018d634efca49d4d276d9bc58622c3f5700081cf115b8c26a703b7d5ffab4b69f3af76842d9c0254dde3f22eab7d34635fb6ee90357678faa493362ee0f2eda32f895c1d44c9e4a815098037ffaaa00e85768e40c16d7a0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fe488ff75fd6ca6a413efb23ea0f368a9db576e4ab09c2bf861e57579e5886b20cc7ffcf6fc569f104a08e5f1bbed5bbecb9a2a42c8c1f5e0ec53db24ee4ad764c200250acf09b4d6533b1df9610696de336ff3fb54aa161de82a838def1e8c6ecb7523919c7c4f7f0f52d622c10e0ae4499a724e1814278b7d92e2a97dfec002235f2fca4f9b0554f279ff204f029966ab54e1c5b0cae8141b2aa4db36a216f4032841000fdb8a4dd739a09a8b573d22676130ee05f2c630134241e29903d23da80b0055f3a6c5aa41c1dafdd51e08c413b3ab0dfd8519f7f8ad7cafb58a9bd0c4cabf34cdb5458413e44ee1464aeb01266f2d57b9cfff0cb5073a8eca005659b612031b217d316af8fd5154de6d006d2d99909c7c766c776c4be375688e2ab961c1f603231c46baf3ce99bdca7de80d18fd66cbb087d7a4139c0ce119761006b42d0040022274621415899fb4aa0f4d2a4544bd9f7991a9c79ef834433acc8100c97790df0311bf2c34a69ab27d571935b0f4165daed6023b76e2c53303681428dca94aace20313ca6e05320f9ae2b8bcb396cbb52a17b04c279c45f36f7eabf9cd8210c656e42007c1c0abf81457985ef8b18c9586e988323c58b6e3a8c07e767697c8a90c0d544e126b56123e23da39b49cacd79722c2b191f7c8e2af0530fc31405baac4bf7f8af8e0ad699f819371501d58f27e8c875c189fc53b4cc435f294e8d35a5e7f8bfef7e162baf6a6a10433a642dc657fef495d72fb22f31c15274ba48e32327bb896c8f6cc97ef9196193a08e5b30b62df43c323f41352c913822fc49d366e03e05f800c0b9a965414e4044a2ce955e5dfb86b3afd97f28d89b12875ee79d3dd7bc1eaa0ab7508ac710dfa3535b68f851fc08cd2f7dc36d14ba506419d503031d3dc9b667c6e2f4fdc44617a030b35a42bfb4c3e52548b39c7fe336e5d1afb49fe9347cf03ecabc778b6a757b42a1fb56f86e729bcc029e7a43ae331fc40a6468537a406b4ee9cf2f7c859504a57c657ef3e0be7976e93d8ccd7b785a1e0e96ec2ae4f3c31feb1393a76be0dc44651136d2e1e86b8763ca29a95576a9e36608f2ff6200317155d620d16b73e7af8c249cd736a9d31c33c25bfaf3ad2b840e4700945d87896e1a72b512b0fd3bfea058aa5db60d01785ce05c16542bcf397aeb1fd49dcda08b1cd9083cfeee5bb0fb99676043e6e366bf650096a118c80b7632e72c284b8e13b64b13da98f4572f729daba92b6dae81e44ebf754ffa241b55c5fce95b7c4bae6c9e4cadb0a01574e58258a8fdb7f072ac9000e9dd3e2cb1d82b94bacccc1e48d0fa2b21431dcf4bc17c80c7c83960c4ad3918b2a6bfe5c9848e9d49d67c99161ea5d511bf67230d8cbc86f00de1d5955381597e42d6e0dd16fd9aadb3b78b6d0b2388a380da4c85c25730e7dc2ddbf0bdd86a211e070bbce49b6b359f492026dfcce089538c61a6782d251a7bfb111cc0b4bf0afb84ab49f95bb8cdcb756b56f854245eb28d195838ca39dac5ea6454236fd8d8863fe4a9c6716b6a2146705c74ddb1d2dd25027af030a7dffb26c53ef9e6693739dbf022ade4a5948877ca2c0bdb60a621d92b0d0f8964d09885a8d3787a302a19eec3ff5886317c7cce7877d5c5b8599740acdc12028df80cffb2b9997aca8942b5fae12269410a6b9541579270f125afd50d00c49a0a9f7dd8499cd40a02d464467fc6e14e62301a344c87f694fd7433bde3f9d9b6bde44350f1de533128d4966dd528d6bb860739358ce521032fad7fb651b33c7552b6c5c57a87b6286b1e89ee23d415fee140fd099bb1abe7e8f8222cf01de8422c4199fe70c8ff2f4da3b785c0bf192e035e911c902dbac40dd31c0e192c09880a77c920544e4e8370b5f09f8b2eb6a3bfe1a928ac210874fad23482e69fe163be6bfb6b8cc93c688e859d65513c2ee4deeb2cb022cc9fad4349cc31b71ccc73ad3cb5bd698fbc18124c773ea00f96de377742a324bfbb8b8f0a6650162a1a4e1e9198becb0bb4889f52ad751f218095f2a0ec9874e2b888707eda1022ac6d0c2f5f5c44fc19db108b02e0dfa0aaab1cd4a4a13a1f51770f66bd3f93d174a6f558cbbb45f2d4cf618c048ca0118432fda931e7601d34df7aac2683d5e3f38c9e5051d92997c2363b35de29ab623d8544d3759e01be91f94a658e3b81e026f66efe1c9b628448ab4682baedd15d02dc9c81df4c57f02a93e512881f3ecbca802b0fc4f6250ff2e249839bfb52d97fc24e205d6e6ab9d0cae0a6d9601495da993cb1e1000000000000000005f6a6f0400000000415026b853215595abc7f3191f9e033efec4d0d34bac874a1d783a2cde4ec5d6031559b873c5ffb0074651be33e027c5b4bcc72baa856a92f4f51728fe08bb921b61a6a9b74f6a768e42c30df34075295cad2dd4f4632f79a0df4c0d7dc26b2800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be64c0ec9efa31691c2902729560351da1daf0fd251427eefea21fd750630572b97fc9c97d067fcebe7ea72d88ffa35e10bd384ddfa1eff16d02b30089dfe0fabefd6b429b7ae8844d56620a159d89bba7c1874b986929559b7f232b808283e6764c3bd0e3809f2f941c9929fa84faf0372eab1bebbb615adb3d3629acab7c7e02252eeedda8bd37d630230b48788b2cf92d409d78f4d5641607291ef83aede84c02281e01e72cc76687a5c89f010ca97c76aaa4bd76b016bf50e814b40d8b30f8890b009c1ac89f6587182fe2a1d5f27cf58c1cacf9906f82839a9cf85f59702e97642f6e6e9d9ada0cb466c765c92f8ec99202e88e4569e3d32660a3d39c7ef724b502254293ddb9a8ab29d389ab1d1dcb7940847a792b5bd47a0468866bd278c0ecdf021ddbb77f5038ebb6ef1cc1171b8bd0660883814e5d094519223f81ffdc2b675d031771173249b69be2a09c9d1ba9691a25426d660afd1fb2dde76d38d7805e5b02021959a5e303d1177c4bdb5ff0776e39f8bfbe7e1329fa6818bfe89c92e258152a02041fef7402a12563fed066ff6d2ab310a6e773d0ba55150ead850d3eb590ce8a14865ece1afdbe79f4f6cdde8512f34e9b399c5bce87af8e8b514bbc867996ef31536e706f5561b08deb3d0b5dd510038901e54ee412fb7aeee191e20ae19cc7286c632f394b4627a3a861b49a307f8fc09c425e8c40ade94a8f79624fb4b9466adac5ff1d0329ebfecf3d6cc566c0788af7be939ea8e1e485bce38b28ec56b523e6ca482388625a2689eed8b426df7661d5c26c20e61396a29ec7c9b8bb0de23946b802d743d8bd6c8287cd8c6ee046675aea1af6d6bb0a91ad61dcbac2f0c681cc7788bbace98a60c137e9e008d183bc02cf653da8a99e8e4ba98a65a69708716a540c6efa01b32d78fe91aadbe825ca95043f003150f2103faeee57d4b8f90cc76fce47465c5a38e6a76f707d04a44eac63416a39ad67dc7567feb7db8415e250acef09c26c420beede6e810b11c718b2e99ff2b9426521871bf16af90911a7681e780934482eb7d1b761e9ec8a9ce2608e0dd09f3c23ef8c016c0bd2cc00f7e00d35624d4f917af1fb45e7589a2239b8608960e92c6f8ab10af98c047490ed84e3989b39a2f19bd61aa160b7b7f7a7983835177e073bb3537036db7da352cd00cfdce483ea4d555d86e9547763bf26d1b3af4a2aa4ac294cb383bfd4447657c9987d14cc809cbe165df58acc4870a8f4a62a0ef9e8198dc1c6095d2aa8e199ee47506838842a3937dfd2a0edbfa9045fc553a4d94252c946aa6b45d7231caeb71372258fda868b03e12b7ba8748a7deba754f02cf94236cfa01dc154a58e87bde5fea9402fe05c0840bb08f41be39e374e629eff4cc09d15e6eecdfe1dad635cd95c058aed0321e81ca22363975b2bc2cffc7486aa53c422d36386bceb5b1b46fe2ed7799881407d4743178959fdbc25585f4e34e6d4122d560a188c298e59f7f473b30b3b91f350b6155995b8cfc0093558f6717308af478d988327e6e2ae3e1c10080f123d6300adcab2a455b3251e0c348d056dd7d2e85f1d180a7edf9bf1d72a816cb597bf1ade645c7d8070759f39f331ce1b99963546a0a99448a48fb95d9829364915b5fa183eb711c705fcc85347bbeb987170a0ba82c3190b1804a0d5737050dad97e3c827457d5d768524064b597c76971ac8d9e7d59c7797b8369bed9b8170cc431aede2ded246f63f3e30617702176f5384f9cfc7aef6c8e6e6310405bb03141fc0b00a990c0ce69718e1c7a57ce80637c43a70fe63b30f7eb93f4cff8ea9c958c730e8b6b69657452345ebf3ae8af5f885dc59951abdf0ed4613b19fc6bc715bf2b4eea387a21d733f9b48efcdfa25a068cafce6c02961044718526e2e09b3854409c16a35c903eb35ae443d06e6efacfe943de4f3f60027ba796d01b547386acf0d415ce1380683d97181a7b5c48ce753f89dc678fdf32c5ff4efbed9c3cde467afdd231bd1d8c91dbc7a09c3a6af9c5f2ae63b95a291df96dac55058ad37786852ff9035dc7e1e0cb18465f8817c228c91845d917bdcdda365b3a85e837f33f872614a4b85cde7aec63890c771baf6a8f38468cc0f72e38ccd4a34a7b6fa577dfbbfeebcb233797dc22e08ef2560380d8a76700267737898022c98154d5797f62de995c740c6d9c7ebb6ae186b948b722c11acc9c725c1d78a372424cd08bca10a0f03c87441197d01f71c593fe2467623fbb9331659d669034c6a2312e6c596329cd1afb4ccfdd6ac37f14c579660720932e9da511e461a133303b7272f6ac1dea6cc84fc7231ec838360e9846df68503670bec1fb3ae2c358512ded6c308910e59cf4b10b86723a628249dfecb29d41d8ee10568198f5e6f6393c1d028e2edc8702b2830da08208", "6a51530051", 1, -62700499, 0, "1d4d46bee1f331696c5961f2916139141cf76fa466ed3ba960464c7000d9d2b4"], + ["f4ec04090316d279e4e56ff6e8d13d74a8a03e1ece299c291e3b77090db2955317913860350200000000ffffffffd09726bb1fedbd30f064b97517ba9e3fb943bdf94597ef22e989263e0970094b000000000952006a00ac5163526affffffff62d13599e837272bfc04d53ea3b7912f1676a0b491ffec3e769fe7d5a02087ca00000000085365ac6500630052ffffffff0199527d04000000000853635153ac53526500000000031efadd050000000000000000000000001e5a6930c99c7d4138b5be9e3a9c6e452af723ba5ad5ee04ef510281b6f2b436a78511275fd52c407ab995858e71385fa51a3355dcd450f97ce87c75ced3034e725321b2024ec3af0ffd55418c0cd26f6806a971066e3d940d28f730c795bb3200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e1cee7d2bd7d6d7adec40a29a560b70210b6ba05a74ac60debccd8dcc097ad0c09c52395a5f0b41ee1edeab501fa84659dc5fdfeb9e32afed1a9f07a099c8f64d1b5fae12a50ec1dc378312221598e3a11c0474feb363c4e1941e81f2b64c5673b04148c3bccc7b618b515a45199aa3af7194f29b8694702d0390a25e0ca6c48032ff041b50e7d4cfb1feb15058b5304d298018f79080e33fd3ff7d845b041940a020d053298fc90641ca2256f3ab95ecd58930bae9e58f04e95ecbe4145ac9448950a0715e2fe5d3327ca4d7feac62875bd6a77537db8422ab5cdf23f5ad218ddf1faa5a8be02a83763ae927d6b25c3372b480f16538e5533058af202d58bc12b54d2020dfa7489a272284b3f416e8d9a227120f6a0f4b97dec63cfa83d897e4e292401030c261638dfda33673104bcea691ab8a89fb3a6da4f26d3d913461f378d7ca3310225f603f73fe617b8d347ad2a18ef45aa011acdc7cdaec6bf2b9f948066a7c16d031f0dea96cfe4e8660a5427f8207a3ddb8d2f4f5c7cfdb8efdce8d79cd891d014032c54efaa70ed7e4a0d909df98841a2c3e183c1dc996c7b8a84cb175b9d9f1d20dc16ae81fe83cfe161427a30955eb2794be15a3209aff9f3a83d641dda7825e0dfc050023cec540f9f8caf856f52e79f6bb4081fbea5ef3782a3823268b12a90f2520bc2c5e7804183f47d8b7c1a56db9518695688d29ff8318bd5d703fe6205d3b43191e2bf81d157afb0cc1172cb1fc6893c3b90e2f3b48e21c5ee902cc1c91dfcf546ce4d56a56868fbd846e0003490edb19b5d9b3e424c816cc316414c36cc6e48f9de6690009a8ccefef3d2b279138087b7549004967622d5b353728125d07f9eabc15bc5c003eb975a839654b9a624e822de3129723192689df11d8db405ca24fbfb53d0f493998da9fc8ccbf3b18483c70c78d78bab90119e2d346ae72639bb3b54967618187c85227088db28c47d491d809a3cf3bb2d81791d90dad5572909942cc16518b390712fc66fd14bf96fc74b4e32dc7486298f067474daf08c3dd6e09700dad2054a37301a001b7ba322ca304a63d7f9f5a129675d0aafcc50e975c7d342e208665ac0d52152f7155cc694f886affe58e156574d497e2861843d37a8ee7c4112c221f4e7255a1543003739afd0158419d87db29addf7898c87c0347ef6a763bcae282c6ea8ac83548a35602aa90a333af3503015ae7499b16484c26e377f5bd9d495a0bb5f79d7bbb4d3d330d5ea92b685d593d7445abfcf2e6baffee19fe6fea3d82b2d764800d2345a6a5b12ff303676ed13c1e1c2be9857672565ff0ee23210e33236acd985e87e1640e138cd70d7b3c04366447fedb774cc9933d785b45ef61ba981d54222fa5f4e1f78b9b7bf1ef7ef0c7248b1bb3add2fc43dc1ec955d0644bc6e78949f46df4a111399aaf3ea012ef1b44921cc40ed00bf7767b3fcb3f58bc8d3d152d5f29388449bd3a8bbbb9d19d7e7b3087dd1dac93f62b83aba6613cf7953f22b1fc1778566ca5770bc5524574be6204af2efc0dd7b302d231ec07c0cd567e5607513f1b28b640a29f6c3f1bce61e8e77f3c7c87bd1403406bdccd15c19ef339a2d4b2b0510cb0a29c08adc38fc9190453d2958aa39aa108d1846ebcdbb0b4e0601ccca070fdd662b8edbdac541157ac449ae7de6835d296ff0e513aa8ed2dd38928fc530abcd2289f923327a686dcbc9195532919ca3aaf86e6623571eacebc6c1a00bc8f090885197c7f0f936bd07e674fd8df5ef85c9a614b46e17ee8bc7fa3267b5ef75bcea445418ca6d11f13a7da5a57bad97a0f452b3be867210b6d0641a4f6120e709f593d8f65623b10a08cd434e5cb0e3e01e0258acffa098857b8084966a6f5d4e7291cfd8796ba5370fbcf8a638aac75483002f908be5d29eae917fa7573b86982dd099cc35f94ace1137f584d70de6d61ac3cc5cc84ac8d1564a4abb6063c0d4b345716afc31cad123675d8534601d232413622d4fab8f43b9df7752cf9e356ca3296b62cb7d9865051087190effe986714bdf94c610c611ed9a85534e645bc649f78195ec66d77274b1eeb9b9df7ce554033e389d3b65e613faad41bb66e57500040cef03102395bcb29467f9e04d07ae9ca57df250547b519b0a4bef06076d93139dd4dafef8da9dd583c438269141cd2ed395be1e0197c6e45851d950d88a41c5f5c1d7e1d12a7e024c2b2d8980605e502706bfa1cab939730eb29a55e8ca48779b05a40c92e0dd98d6f839b7cf9c7f02865d30267abc3c4bbf9d4a4e6b299105000000000000000000000000cba611fea1477d62c414a05c26e16f732c9a4b71f41f143df36ce7cab9af65d5649b47fadf8032cc7ab3ca779e05d1b735bbfb8c03b9f69fe50f2fb81799ce4694f4070f1c19c612d2387294426a983b8743e990e3331e9950bffe25ff413e6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000720465713d740619b563452ceecc9c30f1c93767235ae33f3e214f25243b1a1db273fab432147684dc0b4095e7a8ea4fba98b74544b7ea6114aa51e4a8f0df449531e3011a5f8c7bec22adceded3372a4d8fd72706708bb0d5d4132eaf3172b7148c79548801ef5c8c31af7b7c0f29e5131827f812dbd8d1a08c5da5584def4f03129458d4ff36f4ba1112b74564b2a0ababdbb870ac9ac10986b8523c29e22b760216d5d9bc85361f3773a2c84c9f59ab9f022e34c0963f3b7a37e995b650ee28aa0b033a09fc5f37a245c8467dce1fb3ec187f665e391820bade0ffae645f5326659883758b45b6bf8d0bc608593fc554ad8c89dae25796207436e3c9ca6d4ccb5910206b560f5f0dcfe4a1cf60f4931886d08f0cc2ad225082a0e9bf32f0dc671cfed0200a5064fa2f2ff5c93110b01cae815d0640c4c9a625bb4c33687fc827709a638020dbf9009cb9da4db19dc78f76f59a23c613b3a9f18b16a9be956d24a312b91630302d642f156b2569b8c1fd1970dd07043f57df18fd7acaba04f315f54a3eebd4c020e473608dbaee1f619f734b8acf192486d79e82d986d57cf020a83739f55b769aaf11dd4e4f08b325268604b32023b7dda3cc1d9e54636dbf32370eb92a72a7553918c7a8ec993149579f825f390d7e5f5f394593191c349fe0846de10c302983c8f8da1e86e9731d4888d52fc9d934f14a95c5e83925ae4f53d63d61c0db3af989e8762b8af943723fb3a76af08bf762dcf11900ebb4dbfcdab681dbf857a18cec8d6c0b8b83ce41ecdfc0e043e5fd15d587cdeab77db45450d43c1995d1dede810f40abc677ec2d9842c8f6d36b5b044dce6ea7810ff1269eb619edf09cab97507f5a3679979efa743ec00bf95e29cfee9cd72d10c80ae402ae4b9ef089ab9eb784ca4528a09f014c3acee73088fb1961d42eb06be173f535cd24155e802a97c66419c316f8ba08e4c785fc1e15a7b6e766c5a257e2fb936c389b7326ef105956e906e22cace69a4e0c6b902e177698bb377e4047a4784dd0864ab74940dd4db9701aa57465cd5cc89fe3ec8c66d10b061e7757f9d5d6679d7e7c1919bab977e0ce0719f94613e7b790f6c1b33c2608c1a2ac31890adaf7da93076be6bd5eea6aa2dc6df7a81ddbf6926dae8da99d874d25fb65e9fa2d40a318ad1333107878cee44412973f7d13bbdcffffdbb16417a0694e86b700e3acfac6e6ac2c8bd7592286e80a27b18e990302708bdb2dc269686080df3da97c13ca9e824982e33f36d401957447f1dc661422801168900a367e1d9768622574aa63b59e9c6eb8ab8ca84ea24bb2cf32ab67ca6f0e2223c3905a8ff0a5bd1b9141613cf4394bb9e87157943935150022df733d731f4e96577fe02dc475f39b5c74d6c282bf7099e4709520b084dfc49559f8744425c931f0cc04d0b5567d98031e288b0bc918bc0780c172fadfcd6512025e480a08eadfe79a7588455619694685d98a8d4724b984c96d90e971342c6b661ffdbe2a45ac958d01a39d37ad26813c5ff14ca14121ce56f68f9794b1fce6fe7078e18b9e5c96268734a95a81285978d03cfc69cfe0e434cee2552580c63978f7788d592501a5a5bc1d17678f702fd49add146652133e91699c22d37cda59c20baf4fefbaaecaf420db9725ba8566d7b0b9fb439acd02fc27c0e5269792a637d7424fed6cb67709371ad0a7c94b2e398f875be6275fa381cdf194bd5a8408580e38218d868f7a711a302e4f52981ee3f619d80cb1a836bdfa7d73214110a92341b580c17e4ad3c9aa18018bfbfbd7a5b3190fa1c71d46eccae1588a7f3dd305959a560ddad350006dcc3d300ef6181eb30e6c4f5e2b98f0089718ca21a65abd1c6f44d899a7e4c63ca5f87a0e8fa1cccc61fa94df17f3e2b92514f2282bb61188264ef9dfce331859ee2200f94e0f9b49385cacb2681dd6657d5d6c53e64b6d5a676426da65e6702184cba312fda1eb75e42085837175d30d7017166689b110cc977b63be2f1eccba0a2eb2903d6515d5b556537a76ed3e46efa72de913aca0b2173488d818cbdd210b11945edce2bd8d639561174e2ed34e187ea34d34736fb4a7d32d49692777caea09575744932794390c979b5b293531357c5ebcb453b6a4fd3dc1dfd014341cf482c8ae312ac32f9ea67c8652150b3821562e9c2b451a516082124e21c7a7396106278d144ead487dcead9d79ac8ad8247f595e1b2c3e39e88e6e4c93096c263337c8f7ea632e8372c2cf5072294890de91beb97280e14acb4dd9c35ee60f2b1000000000000000055f34e0200000000f011d9b71a37cf1992004109cb0da1788e547e1f1575baa798ba614b0866045e7c31ca787233353bef0ab8b114730c4f0af86933b6df972cd025976b757837ac1f84537dd88148406699a4812e6723cb8ab2964ae7d091e1010139edf90637fb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110e79c22600e8c736c7cf1a31b11ef500879a48b68bbd75c2fa8f3bc28527c68a11a0d371597119801caef304c43469270d36c5c711ddc6d96d13ce2795babbb8cad3c45e96eb28b193c491c5407b4b3442b00a495e2372aa9198a8f2ca3cfa80eed0d93021b0757ffb38ddbc9f363f0d84dd840a10f252b5795bae82d507880324672e08be463492e542ffbca7ab173ea124bb08256ab43d6186722e8c8f36e70316ac573aaad68d0c404816f505bd1b20783438c7ef6b28f4c38731bc6f08b3900a0895f4dc8f294d42d3a89204ccde8b5fe2ef97c0c49566d0fbf81eaa33a1bb8b47b5244f9bfa38736c397f6818446a93868c714b705380c6a3620ec7f660e88c022ba0ce3d8fbb673ac63484fbad70b98949eb5c80d69d90f92cfbd67cbe23b95002180dda55e820feeb8d50d8815dfb0952c395e08d0e0b8f47a00465868c6c17380223c6819ee15d3e07df8ed3f7fd0f9fa082f3245818e245744f1cb2ed1653329702251865f6c717ce2b3d11a3661f50e1e456d342d60d75f78e3499033b5bd4c88702258d4e246c9e3647a23aae3faaaa5381b528d25ad28ecfc3080b8ddee5f6d3d3b2f6c267e47303a81792a297fd4eb016492339c97c02c2a9c4de25df6d42756861277865b29339cc3e95f8623ce1016400269a81bef0cb7b964d08da214be0fbfa5d4793c95e8449fb5e78fc8aa3ac3610170e555b27824ed7ca32901f0c953fe0768c63bdfac39a2a27c2ff3ea6d42da7cc0086149408176f7fb43a3f67b606d5685e3925f34aee2c8347c2ca3e3d5d722b62b22a0285dc1c4680c169eaddf33d726e19ada646bf1522fafa509ba02589e7ed4e76a6ff7841da0b9ed10d3cfe195f9104d8f4eae65fa2f912e7f2cdfdb0e3f3a72abba267ca655342e24bd3d9b46c85bf319141373210f88d379259ef6390828f54c2c3f4aa991df8e6b91821fbaecc1950731fbe5dbbb51a62674947a365acfb4be70ee0d4020721229d7e992626476c2b9eb732ccb686a654273e64be7f0a1b03fa2c553bde5254c58093d2b58df148e27705a71f4fa9295bebd1d295b757d12644bcba7fee43bd67d0a3494e076b49af98cfe1637ba8be749b32491abad3283c8b1d0c20a1ccf47fe858c7b10ff5fed4014fb17bb8dea5bfbc66709b2f4b62838e920695baee158e7b1ff0e4aeae722ab70d79adc599066fdda6769f93812283e03687f5a29584d07872637a768e1d8ee71ef915e3056f4ecbbc4588831d57b5327bf2476bd6bd75950aab5da47da5732fbbc277a2587a74cb4b1edbb97c8e47333505bf113f1a336ab85767d7b43ccbe545bcfb94eb05d315d6a578eb2b63e7e7700913ea9032d94a330463af8a521fdffbfb561197e6fbb2bfa84a47cc0ce63c8c709b07b622892b328333b6b9635d2e49e691f8e41749f1f1b469edcaf187960443b2273df5ae41a3b6884ea9168a735466d9f34d071caf999d4bfa3c07a8eeb2cfaf15b61caf2ce7a843ce52794d5ce55500b6ed522f1ab75bd78e926c47d2810085c1542c2710bfd35421ab72fca8b836cce606e33ad27f00a977e3fcbb22fe618d3993101d3dd3b8ad91cbf590040e0e48c72ec2ee5066f29368f3af50262212269fbc835edc752fdd707afa95a1ce5a9e17430cdb18263654d61b372029f42fb5d7a17bb153bf7d71f83166c6d63368e45b61feb451f4e380f8adbe359665cc3d3c3b11a3ea59d94dd6e043c4eb4f5c5d2f53f1e562d2845560d0c6bdf3ef945453cf74003acfc5af36bb8afc292846a29119865b5895bbedf9a9b5d6677e47f9508c74550a94ffc860e55654fd23b13463fcd2174a2d31cf1ecd115b7a4b8d43561f8382ebe1c4a03020907e0faa7a95e9ab4174a6c3e203566bc585a1c57cee22897cee9966041964cdd91414b8693137e33651c09272debcad073e8aa707783541bcb7974541c23f3e7d00b9b6e6a7631b51f7a86f3139664efd10e124657925e60177bcd0a32e86bde1ef2e15d24c324f62657b1e95a2ad50509bf371b83e05abda018b3cd406e8fa60729f6c20cd8bbe3b4991eec8e1d80c875505f6bdd737fc047f2e0cd6a0e7aaaaaa812c51eca5a21a38d6972ab64a77f098d31bd0d2e7e31712654fde70f45d873a7cd04c35a8f41ed11e2c24b79af365036893b9552585fe9c1e10864d826483074991cfe8c55622a5e929eaca7e16bfd1073f87090d0ad17f8095970e1b99bddb69488396227ba7ffca379fc0ca7993de48e95a6244addc736c145db469980933a456f76a40cab8c0e98de221e58504b467d1e1fd2564df64f0746d57c7ae0f44c81545c93bfd0c1706f1bffc7b116f3d80e588125fe9eae7b7543ebd410947c74d4caa95b2289e8c547f3aa992f3b89531c6c3f39456b497b9fd860ec4e84fb02ba57f3df0ccbd0293be6d4706", "53", 0, 496383266, 0, "1956421ae37da37631b28531b7271195211b54f46c680111eaa3db5238fcf850"], + ["030000807082c403027e27ce690cacfd62969f1a2fc6462cb12d85729adac8371313b774c57bb6e4a9020000000800ac52acacac53acffffffff67fd9e0fed0efabd4a8c39440b3cc97bf51af10549e2e780f585d9f47cbb261b02000000015396fb6fe302b1b50e000000000003526a51bcfb4a050000000003525263760d959366a1f09a02000000000000000079fcfa040000000017720928d781b5db9d03e1b2cb9dd91214d1e7591d19395c77a8bd406f3380094983e88b3e7c25ba444c154cb251b0343a715e02f6f873c18b32e8a88fe52577457c6d2d8177718529cfc7f0af72acf38aa1e57c334c6553c014c5991c1e026500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4f73f03f5ec33da54bbde1bcb2345ade5101ef71d51a15084e0e8b9777952f8b61b3d2adebb83db20854d27d4d1994c629184e48822593b9cca02f5e6b42b6dc9c6a62e04ab203507dc38537a2b48d1f8e7005435120073f9ebcc73623279dc53ea47864ec39648c274f36ee738b093a633891811ece2b0655fbf88967c0226031a40080564a38c2767b362cad27cf3adb2af3ebbd1762030a60f360de71cd7ad031186f02b162f6019a5fc6e6ed387d3d33298f3543ab6d911451b55291db0b8ab0a022393634c8296ae7198b001b73b87ed487d702e78502db9be0737461c2d6677efb1106d36a6ef46831b087c4035a197cb5df8bf8f68a6804ace752b7ec22874022077e7200931cee9ecb159b29f3ed95148e3ff0fd273455c84cc0d7a5ee3aa440327391b4ad3187c4fa72e29354b45adaed2924c596ceded759285edb2e03a83aa03047f8060094a3c49d3c1217a1ba723dbab5d6259192c6072b5fa21d31e720682030c91473f9b9fa5fb98bf7132f5cf37c56e12aef0d0c862ec40bf4fc9798042b00303ab2bba149415819b836f9f28b6de1cc5b03417af709919b4e60fb5f2d064ac57bc6da4b31c410e704937e1ca31c7cec8f54008211e19e1ff28eaac2aa8c54e8839298e9a4b542eed3bc98d41a045a256e52a2a6b0c1cae1bedd6e87ae58a80ae283183601d1d9087a9d95c0d9cae98ef761f15866633d34c930c7f20448a0140b28d49e84bca3ae33902d0e1946b77e1368a068e0945a6db5e58259d9a08000b72410fb659248bdf4755c91dfc4a6144b118901d9dcd79e3a299d88430413af6b7d8704b53d30e33ddbf22f87bc03464571b86d8221fa33a7914e1ce3b962b406e1afd7b01f58eff6f357c2117799b55398a8f49749717ab2ac7385659cb2e252798fa5b65a51b5dbccbc852d5bc309b1296229271651b74734e80bb0792030154524875694fa0d122288e8a86f2be405c664e9565365f703808a69b189b1a05a70e9398717e8231cffa2e8ea4f30a177ff9d041b5cc0775c58d59b2da9e08495f6a9e127c1176f3365c631e9dd31795b19daca5366deaba46c8e615eaaf0d25d9e39004b42f165e4c6d3f72db0215c7e59e4aa67a63e71f8eb4b651a73802a09e73afe2b2b94d813c098176424d3485c94cf1aa87b500ac42a75a08151d2435f25f79f43b0fc028bac4419c1ecf29ad9c46620ea5199523de48720dd711000e0161457e176f8d7cb86b3345e01af7ccc3068df07f13348b28170bf2ba38a85148c8ecd59658d21765394e1850be31cdaf3fb0a29910c4f181dc31cc12045a89ef89b4cafe7a9af48a75efcb1b442f6065f999e300018385e5f8b715aabd01dcad9e4e76259c9cb79ab80bee2c4d19f2e1c97636b65866253aea2c91c49a5faba46e4960063d24682aa473126827a1995907f89608102b7ab4f2e76d260ec4ae91dc46c9a540da1e4943e7c1ad56e1639c81530c679b9a66e7f1f348e178db1747842e330e2c42914381d95f0819831b3aac110cc53bddf32d7981f6310cac6bf1885aeac3e22bcbc44833c99367590fa7ae1d587a02195d791b1355f1f8af186f7622e387beff03b1a7fd697ac4649ca744bfad7642282302f6b9b9dafd89949bcf4b320e323b95f4a59f21a6307a08698a61a94fdf2f22d465c7de13d2a6c940cb5c6ca71077aa0db3d9227f7a67c61d07563acd236d07bcb329aed3147586e285cda49ddaf6966cc1f4e80234360d138724f4683a93411f280a0f05da00ca9b1717c2991ea585cd5963b2639b780262619edb00f3daa92c749f6543a376928f6f216ca700b47c1a8c51e7425e09d252fb8335c5b18b5ddd81cf04f97604542b7418def4462a3b27426f3ef0392683eb10f2b8869abeb931b7e747238484ca777cb54145c7c41c79960353afefd9dce3b6b380578751a596bdd99a922ab4098f06183a3aa4e908c64cfddaa88b3d38c916810daa64ca9df3d352d73d52ea85dd280adaf4857a2a8475086247a60e926221b20acf2872a3e47fe73fe0861afdbbbe4c325c700217187395f150ec3bdec392e5d92ddb6b8bfc70953200c2a352e624179041be0671c53337446c51a92cd2f16f4d9c819c33a3c2681a0e99c4a52be4c2f43dd1c7fdb5b86d699ce7432ed807703e826ad86a29d2b15fd74df5d23922e84746dd7c95df786c3c42be74536f1dfd38dc3b935593a0f23ac534b7302fc5224b7c9b83648adebacdb25c4c0f493f01057fa78ca89e6e6d38b83f21182adbd4810d07a215e262e6b0713161066c78166201000000000000000000000000f2c2c1e30ce4243e43fa2ba0d290354742fb1896f0414bc60e3f610460b5dc8ded899760f18027c162281be1aaf766708dfb941c6533ff079626da5502aa009a47fc1420ed9eacd69e6ea89c6880bf44e781273ecf0fc84f0d08a6fa1eb509e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a843694a7e48ba3023bfc62046df84e3a7bcbf90071276c18fb8c942e43434ba302d16adb4122c5fa34acc5ce12eff8eef498c6b528d5e0b9853b1248760ea98e0a7bcca4a26584d1e6382a72d746a71695a743037216680ed76d022d251a57f4f3caa6ecc37c7b08e9daeffd96fb318548e542fc26fe09a687ee3a81e673c450226703ed5dad32986311e49089d0ec27279a88f8251eb9394faa7e6d26d6e90ab022f7b4b28d8d35df5b6b45c84e363f974662517214114d6221cdbdf0aecb652790b04941e02ade55d7bac4af2db7436262fb5901fea1ac107a3591bae4c7dac080320dd4c9c4a2ddf89245747ab4e9d36860544f33fadc4044f7b470ec461048d620301529df588318f85b82984ae81c8f25cad60dee5d2ccc786cd903a911a7eeb200303becffb5906b06c72d09aeabdffff57aacad843eafe87fcf18668bf8b56b9b60209b7a11e541eb58a2c2d99e41058e4cbb94ea535da81e98e0386b7e1d2964ae602242bcf0340bb5edbf71c63a64f694968e2ff1db9b166494caf55d5250cddaa1d021c56a4b6826c0fc0f1113ee547b6bf860b214804f5e6ea46f95cba12c16fd7b1ce9764fb14c124877c8b4eb778f599eb8174c428ace4ac730e6abd1ae4c42bbf00cd37f55e00ba9dfa1c4bb2e6e6c52b29be0e76e5942da6846701d48526788b0cfe1e1b0046bceeb5dea5dcb468687591fbf2e46b3db74608165fcbcf564bc6fa9e3f546766b199896f09ee901e24fc53bab32de2531e9f117cf6eab60d9d19662914d0ce39b2346b9580649983069fac63427cdcfcb093b43d98c6ebd7f7d9d567f5d99c81ed1562a752c98855d2ab53178cc7a017626756d0d5dde07cebd8cbdb195dd819053d0364d633560ec9da42293526199c2f116bc752d764e858f609f216417985ecde6a4452ccfc8cea2f0f3f122c1ede58e4f2ae22628b70fbdd078a3eee027e5925ab31e9a706d71120d8ab64aedd4d531d56e3b9a8f7e5f53a8ab7f290cb92d103e0c95690a1abc7240551a037d10b1630b07ab45e1cbf20f2b1ed643236e5dee2a9b1c54ea3990aa35981d84ab5e9680b32bbd8b7a11695bd29f863adc0d2be4a8c462ece35e1aaeaae1a6428521c6276bfc488342fdcec88475146c3c0c4ded87b2852c96783bf48ce56de65fb0a73e61af9d6b9eb2fe834ff45e3eb33b94ea2b5926add019a95de58e8ee3f14941b914cd61dc1b2c9012ee8a29b5b94c6acbe3e5607657520ab779297b9e6874fb69aeb6a1d7ee53459676854862fcf611f30af94e378f99c30d264d1443ed64fa38bcd2df17dd1f8abf6d456f50de7a876181db6d7ee297e465c8459b9935378652c40b5dcbd75cbeb37a8825c10593828116eb3f0f8b250a2efae961a1865e3459ce092dac3418e6de4e82cca5cfbea4573067880b6fbb8064eb22b7a00d7511546e0bcbbe4150c20f17dfaadc55931f641f54a77ac4cc3f6fafff43ce5672685a1bd337ef22b8a5f5e759ce3019e9236625f78275869d6837e80d820d513fd6a02400d4f55a656a58a0036af7e5a0533e5a25823dd5877866f27d225bdbc6d1e22b0160b97a0fe58de6d8d210bf96d691dd0ff942b8a968a87260ed38566f733f6e816c8f659d101a59488077d31331d752188fbdd38c1af1e64d8ba184abc6294e856662b3ca135c59afba4c992455eddf8b4f48d9619a5fbe269920a17ebb648cd38b3ac7e2c324a4ae3e4d5c645c0f6739a70d5d5fa2979aea8440b99545cb042983d99197ef1843f63ea2d04ff9c8291d310abc7fe1795b4dc31532eb77e52e5df781a0a7dc417bb9e9f762ba8eda883619fa8f83a63be976cb69360c72b810e2652057de9db259488316de239b49631708ba02f3f388e97809af74c8a99a843d4f2e8d7b6ed19812344e1e7e84d6a8cb283eb7aa35ec4d62843b9297373015c4b0f52753bfaa40e1437d03c83b3e1ce9cc21a31c45dda2c535d2027aedeb61109240b5e15a3779abd53188c0aa61a0fbf1befd564fdbeb7f12c062e957abe4162a1872bd1eb2d22c68f29f35396571545e776e1399144aacc66f786c2c3a041afdb7237a76d13e0f1329c8ba0e947b7c21ee9acd29f6b176818b14af722c9814ae75e62521da3fa86273d0f0db8555aaed0faed38cc35a7b1cb389c7fe99544fcd8b2b1360b73c0b9e055cfffe24e27f4b29252d2b1dc9b1ac57c294efbf541735821970fc4d47356971c894eaac9aa72a13bb705ccaf17b5cbeeec6d3515d8201b089e3e0812ba1023369b5e1e1260f7b618d9c72bb25365afa2cb75af11ef6cadf838b15b781d8a3e749b5112229cb0e2647d16986a5275cde90280e69411c8ef3e3939421dc453a03ac50777063881c6c77ef0cc9b65634ee82472a438f42cd2012e036ec11fec17a2032289d417aa9164bf8b41fa440c", "536aac52", 0, 375685057, 1537743641, "50480d5580e07c9876fd1c733c4464ca52f305b7aa04517bf443474fee42b9e6"], + ["d69a4c4604c912ef2cbc0368f8f8fc2ffc4ebfc57677ee82cc31f20f0d431a3bfbabd1fed4030000000453515253ffffffff62873aef656d82f6741a77ed346724dbb25d58c2e504259caed491c57c0297f2020000000653656a52ac00ffffffff28e9cad39defccf070a9872d01d2ed3d8c0010a4059277f86a7017c16c960e200200000004536a6a5294feca3dba0dc56e7d5eed8afb797c62024799841cfbfff583bf239d7dd194a59c89bdc50300000006525353636351ab906b46031c6d44010000000007ac5151ac6a53650d9c0b0500000000076563ac530051652a9d4004000000000353526a00000000030000000000000000a3434204000000001269ca99d03508c7722f2e8322c811108e7c2b2d343f079af363c4d227d0120a7b5871be63c79634084212613cc7238c556eddf71df249d655d932c3906290ba4348365aa5650ede5f9d82622c75e2309e212bff50e8a17f4c1ce90dbcb10621000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f0cfa80a1516eea4944b85322c529f2d947339977291b3645d378e30c656e89fdb0d77a0817ea94dff1727ced14dc480852ef999f279e289fb2edcd1b15a88ad33e3f2abe2e81126372011ab5bc3506e6d3b90afe5fc4c37d6a7d9149c8a600b80981d6223200e1ff7321ad91397e27d5fc0eccc9ff916978d166b68c9ee845032b9214eb75ec1326e2461e32bb0f68bbb17519e05c8a8eb3f22525184cb9e47802099d1295a8630f50d99d4cf541fdcd6c3371bfe1110da96f0258e86c4a08ec360b056ec2e625f07564a397773f7df72c218a6343dc895a2f459494b916f4be95530faec293c7fbca18577f8dbe70451c93242e18a74fd949615c3a02bbac95466803029c191a9876873b9bd6b308689e78cf546c012e37f7bfd4a3a1b3fdaac9bc3a021a6c21220e6448336b1b3e2a7cc429c4bb5a9a976862e99b32e77407f814ebe1032e85d2eca1b15b9355d7fc5a207bddb35b04308bc5a69fb497b90f29abc2b20502125035078c762fdc753410f144a3197fc5a097ae1cbcaceec0588d7bdce6742d0302e6b6db7fffce818693a4d525e36ba6c08994156669fd69eb2fa50bdd304e1a5bc8c2fccbede6613c2dee00bdd1eb60018a18c428f407172ccb02e026ee6bb533b75f84f2c3da1b67dc431e916ce76455bb46d8c0d296234f2d5b85b109c7eea0a7027e479d92ee7c2a49f63667aa3d0b75871b69b907fc2814ebbdb5e2179550c424c19662344c7d7b57ec1b392d2bb99ed8af350976cc76c1528233b8cfce03ffbf3214027b76c3dd41afc098c5fb48ec945b4724385209cddf165fd715f5b97984e2cb26f1a2a92694767d61fcc7a51237868ad6d8e3e188f0e88af15171f66ff434e9e6f9cd871a9bf8be237958393aaf2cdc43e722d3767d9d563dbd6aa6da44da780fcb87163dc220d104c470367c9384fcb1d106f40622d76dfd5d6932123132cd182c9ae434895ed00e05f9f42c8c95795aec2eaf7a5252409b375faafaf8755fa5c0e8f1a082723530d71f45f34b6f249a6d82c369ec10412120d2844448933fc725c7f669ee21c5793ede4e4a70cad7756b4fc4f8806b668611f2545cd7631a63f77984e612584a0d759a31e57c0ad16e794864683daeffe985c101534d62f932587fe4c9e9889373b8a9a12cbbfc2a782868ed288ce10c7ac22371ce82230a69120909f671516c30802dea357ac8e36ac131406409c67d7a54a111f86a81d18af2459e97c489bbe6cf7a91ed6d30b0097866c5d049184ff96bf8b9ed9a03755f602e7b75793a8859b017a3a0f079770cbc3170289745a903251ae7915ea8953877de3e5373b5e787a22898f7325902f3393eb653296bcd1b63aeb1dc6477400bc4edac6084d9a8cc3e314f324b6bd9735c0faaafe6acb03acfd40156910b23e4bb558e7ced2de8e4cde52950e3701d46d136352e74f2435268db8ba6196b55b2a37b23fdbfe3f4111896b50521c21302fe22cf7ccbd8eb24cbb8b6a35abdb0edba37c0dc8273e33b28fcf2a01d9ad37d768c0df9f4f534afda0912e0a9a12b9c241e48a3e6bf71d87045941d5f77ec025df888d2d52299d3c1b7d8d989c5ef2043b0354fff7468b79e0a6562febc4ec62f50e57295f23e1ea4160a9d91f1e9d8a5744b1c1f4fb60915ce2cb975a40e561f419dec3c38201e01368876bbbaac39233569a94a81ae92c746586f8a67c446e36480deebfbdc360bf4985f28d950324cba0e2b8bc60a614b8aea375f7a2e2fddf2f7e4eae75c616c2966ee0fd88f684cafee1fdf87d28ecd2a5b971a43d9789700b58b525697500933ee606baaef873909affe10b6e9778c70a06c891319729ecf4d64922cfac0c0ce94916a268fbf30c3b94b778d31acbfc64f34a5acd16bfdcb4290e7804c206c31c168e17ecba438786a60de3f37c555cb5c856d0e16e56cdb19db43f5cca81b4f261d952420da2528ebd1a1bc9391a57ad38e13d4b22682e3bb2bf31b222c97e3800327e080ff08e389396ae8975efece0b2ba54a066d5950a6276552b9890df3cc8e8229887e0cedf9a218ed2683a06f204c041557ddd77029e64622bf75de61ef2e659092e89e6d97d56ba104f32f95d54e59dd7a3c77d77b1380f0c1e038e0ba6bef6ddd4addef4ea52a453c3a089aacf12abaae0def001a15bb4b4f5d679959e7f564e2ba9dc7771c66a7cc7ffcb92daaf6ffe4156b8ae463867b0256a24ec2c2d8482947ecf07120a354eb9748ad63e4008acdbff0daf93080b578dcda8d167150f040ffcf334a6d95a0f4433919a164a2b06f020000000000000000000000002f603e6922acd095d4ce3ef2087d759fdc921ce40ffe35463767c32b4d0f126a8d4149afb2c7ade2eb06283f9a16b01665e733685414b737f46cc8f289987f96bc684085bb1ba88f851cac708f3ca064988bf02a07c5ad69e3c2ac5d362d7cea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000549c6134bf5f5f69bc86fa4451770417eff7b491f39e1f8da0106eb4b84dba74a3052736cca9a89cd74c5a420bbe61680f19250c2212c16d719d83ca15f3552fa7daeef7d7d5770eab618acd6db5e7c427204e033c28c47d61c7d8cb642ced1c1215b8c6982dbcec34538293c32f717e5b32009c74e912d23c7c48de9aeb1d51030297d688dfe849b72177c95475bae2de6e3f046b2662944b786637f8e70d6cab030c865538833934d3a868d3a748933fbc2cdd06ce9fba749a8429a084992c90b10b0632a9b64b35fb6994ef09956b430632770421a65700d3ac57d9b386f4a4f6d99b80ad283ee4ce188d4eb332920ef63792fbd608347a43f0594200ab34108bce03112f86c4de1aac84db6b464de740593537431012dfe3550dfa00e5ae0b3cb4670213d61a7185775d668a42de6fe6152f06c4ac8c2f474c7a69c8de0ca87725b61a031987b2cef5aefc949b959a8c216736c9d710a37d1a2b4933b4ecee0310e172d3022cffc7e2fa7e17faf3bde6928fc4bb2a22ee59698b843e746c18530f3d2966de032befe604bd49f825209f54bce19da50a5768c8812ff84415bff27010d9e54c39bcbcbae36e8b834a4fb04e8700f6acf98e198a91ec9c64ae93441fea51e92968271e5825a9496fee56ead2945c0379dbea9300da1bd3385b6f649ce49f32beb06175b90badd3b5a2f68bc72f021c0590b15ab46a025c8ac0d03f739627b29b5f235d96576c88580d242286b2bdf39b8ee0937bf5c30a2ae30f5c24f30a59a765546bb5acc515ab40d1d513695c724904a1d7215599b4c49bec66e44dca24e4ae74670b9e44437c5326d04322b58be2fabe992b8e858dae36b8508bf56c688cbf7805ccb19e293438eb13735b9a3f7f15942d4d757fdd2c853b00341acec05da1800e46e92be8ac9671030593959d5ec80dfaa8832609d01dcca6a062665eb014cb66d896faf78447af6abbf89e828fbb4c2aabfacfc2f58f3ff59cf3a2346281dc931a41e5c1865068ab19029af9217d931eb36d293b2d5dad58c65808ecf852be356791e9a46825fdf47e98d42d20679432bbb672023b308f566759241444c9e18db8a3b4202d6f126a19f82cb8fdcb473e20438d1996ba46c97bb85670eb56553222a0b414dbfb16f86d428305b7d04c295fca54fc58fe614b9ccbadf0fff7d7a3d268f59ec962ad64d7a3d3d663e5e9fbe16bd83a9c0b3e2eadcfb64cbad75b9e7eb13b17005661340deaed65940ffacacdaa1b5698be8716cf821d27ce56eaf492f246a1119f97c0daf504aa0cc0fb27714665f6a08275255cf5eaa0db242d784a79371244ed75e6412cd29143562465649b973b8d5b15944dce1ccbdeedcd6e8343075de033b07ffd5654c709a0dcd077ab9d3f0aea61cf9a82b9d05d4fbed34ddb5d5b31824cf7d9cb9c5230001bd7aae78eafba0a21bea035c7e0aff0eff2386465eedfa98273c19fdb067999b441e353c031a68a83953841c97c4ce063de15ddec4eda3fcb8c6bd06b208ff1e3bae5de76deb2dfd0e51d97c9f8af62d0383c99bc042bb748da21dc72af22b6b778097cbb496183ee07b2275410ddb4c74a521c8934616152be373aaaa5ffdbac0119ea9b42358fe075e601aaf45b23046e1464e299d29fd3ea3eb795964bd5b3b17309798ae917a50fe26d72d420ec8a33f5030627e6541790236ecadb113506b15554cdbf6a1c8bdf6eb1da3aa25b28d8d4d8cb7e9d8536956dddbefd684631f4aac7f7fd174e4297079fc77bdd20b64e15ef115fd1b6cfef0c0075ee8c255748104d1608c9d8067eb6309c9e6f1b60c2c3a00cab30732cc4c5d73a04074a427265c81fb86da53358ffe87a34f1103cb868783e33c19217cde933763c493c90b5dce429b096e277475be43145d1a6f04c52dda5baa2dda17b6bce07b0539f9af1ba51dc35506b765df3b0a89668162b594dfd5a8997e97a73e7f968ea33b96341b3b94fc2d55be45090e3d1e3e66e2040156f4166a6a077eb2ebc7ef5520e051b9a5d129b618d7cc42bd70cb599fb99028b47dda3bdc55aacaa3172a6825446d9f167e09db2243fca66368f58c9b59441328471c86cf822bf41809ee22c079339ee430c2a101eb2a3496082600ae98c7e6589bc1c0e99c4459558a0a7e637f3aa73521dc37bcd401a261754f9b6812679897a4d049c9053478a98d66dd2068cebaf1527fff1a955c8171896b005c5c9799d1a5b3faa0b7e4d5a6c7cba6af537742ba2aa1d6f3ac64f0b6807573c504f6b5d95b2236c3b15dab38d2539465bc0700000000000000000b099400200000000ba565002e51c454d628aa634d2b607872d282e7b9ab80e8c5101f8e803af9f6a21d9709e4e4af8f03c0ba593e89dd3497740219760cd733122106df930e628795f55cd02d5bc87f57a3b03d5ea2d1250fe25dc7e83b68c5bd01aadce2534f31500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a3d8c253ce8f622888e1bd79a4fefdf292d7d7c9323661712b08f553c347a6a63d808eb9f98e5060ec7ea7433879c59ad8cf6a8ffd077a3621034d8b2b9674b32d99f6ce605f8c02cad3f218bfc0452b0d903e4dc67aa7c69bee91d93445418b3005f03973f0e899fbabeae15ee2186436188e5a6a74b7d17b9fdf5bdb092ae0020016e145ef735fa5dc8e8d5f7187653fa5bff16561c939611104be817d6471dd0208b7f2ec3502c3b5f836caf2094044de10100cf0742ed342921dfae447ef60130a02c09b28f1900f4b96b0758ad9bb6ff93de4a283afba75d94ace54a85f47d1db6a7a562521b319d43befdff44036338126b2965c52df4fd33e5deabb8e221cd90318c1fdfdeb5d4d15d61047759b8dfae62a641395d920f6cf8d5f38d2a4da2e0a031b8e5e444762c3b05c19a95f73ba8cdc2cd7378f276a889aefcb6be5fb5dfd85020bbb71794b0136380963e0dde50b4021065a1fc62c9f17634c9e19d1ddd3e7d8032d08db17f3f4f0ae45ae0da0ab070188ddfcd233e670b3503d2b7117b86799fe022fc581259473bea87c2321ea68ca464857384f09a1407ebd97ccebd3cc1027dba553ba3598df43413ceb10eaf4d21370dbe27da1cd9c25787a9181f26a99dcf2748f84eeb20ff2c152a134e063b19b999965cfc1e105f887ee67e398c9050952de993d0ba6f0879f3af4bed4b780dd87231bd86fb3856d2e67c3176f786bbe6f598b1490f95330642f6fd97da153aa1ac9fb6edd8300ad6c5ed23304f6b8569b237e2432d22603976759617040a97a613ff17d60d1da161929ef9076dd9b068c06aaa6870af3090955788bb152aff75d92431243c1c34f099ca29a778b6adc50641c4422e49c14ed0dec143dd8e7aba25d2564021ffc2785a59b6383d25bcc7d02cf03a43c7adf0e9239fec004a9f5b17460e0e7a7c9bf6f7a5bc45b06335735c59ade522c89338f40d73647d4b4f5f8d86676bff43756f8e4c30672117dbe235aa108cb48bd873200a3b8db31e8c7bb3109e2bb3a293a8f663594eafce5314a237c7d7d6565bbaf79afd73f772329a50b4550aa2e1d69de05b0f23ff55a96255ac1833dcb3449e8d81c096000a28f35a0e41e75b75c635fc85d2ca2c6567b2edc9a2a42d6c92585c2a985e02e4993895b0a661e6fe26f8eb4713f04681ebc0dd9aca6eb122bf6b266820a899e9dac1e634abd97c18af846d1fb7f6186b0d5d429565668c73cffc2cdec5cd413ba3a26121ad93f5ce3711d92cc193c977bed8baab03f553b5a8eae376f2121dd3c66a87a7459967c629fcb32534892eaa666f034c21507c9a30b59a74ddc54fb5eba64d1598e6d79586cafec0c902eb0369c1f1b91b4f3cf97263cdd1ef0c32655976669868e483084fc706b9c593fa0f2641409986beb6be2829af11ed4c2f6608e441be7929169703ffd3f46fcb8cb9a583cf644541fcdf015d21d5267a78792dea3354944c28c90c374dda98ba1ca141d0b69a96900693007c4e4ef7b2f59dae4c7a3b374327fc7bc9baa098e58d5581b62d18e3ea03ea43b7af84d4365241418dcd91494783d5b4f39e71ed428d990acb92d21c0fdb01adc56e5bf74d16592d1cc0ea7a1e90e8a303958224dc1783edf268bf1b095a0647429f30c76e3a598044fa79c0f8b700fceeaacf6d8cfee715ec3867fa16171467ce7f6e3e23069dbab217288e555295199171f31033f273d607e1bcc5676f092bf8a5b9a0be6b0b34bdc60c4c914ab20bf0f0b9b24db92d1cfb7668065a867e0cbfa312f7e56a582bbc30304f94b287d7b7c7f305cad955c90a2dd24877c13d512f28faba33bf9144e4253b40d6b1018b62210c82a978fa15d92667278cef7bec24f28e417aaf046fe4529b6fc1120c6f571d3d9fe6552f2d750ae75a3be94c5d48b5b6092d8d16a226999cd2ae110334db8d17677248789d49da74870a35696f2e85d6e02977726035390dda81537bd3ce2b6005a6eeff93293dca8c767ca56c2b41f420f419d8ba6b941c8f582594bffa167dc27112bdbaf5dcf4136510759c86e54979ec8669ef384e9eab7ea7fb6fefe99c858ef66185dcf53b40caf36634e2bdda18eb42692675160ee6ff7a61fbd9347349210f910fbb08d526d607c224de5b2321a015e02ad5950ee3d36faeec53ce6d52b0a8dab0f3c6d19d27b2023cc8579539193f4538f32aaa794226c3c311e43af87a78918b9b36ccfc67b53cc935df47c6a155fb9693850145c026da718ef8901165c1cfd41c4d5c5a68ee7b8e9821a18b8106701b2de7b7652477c5aa2223b1b9d9ac90a2fec4668e583bcd386ff783b831aacaa1b688910acdf1cb596e0696bd3ff43720ace0521df9acc96f64e015a72e1f7125eef15ccd68d2816f045f70a1a0e752e3b8433ff1ee46850bfbcdc59c18c388e012cfb0d", "536365535352526563", 3, -1373976644, 1537743641, "6ca350ef302e0c4b5b45c110758bfe326d415736d325aec3f9bd4ccdb91a615d"], + ["030000807082c40302e3e16858f82ddff037407d2bd2ebc5ce61ce982c23c86fde6ab800fc2107cc0402000000056352526363fffffffff60d9ef254167087e70d3b1ba8c25563f898c8d1c05a867cd93e3ccff5d72e710300000007006a516a53516affffffff02e49792020000000006006a525165ac669507050000000007516a656aacac000ff4640f59133fe70112132503000000000000000000000000ab60c6206764ba77e4f58b79faab2e510ec016d056e0104c20425a8954a26ff5c3b5f7f93e1d54b7086ab1aae4f75abf4786442772e87069cde4d7fa815b7a42750f9b3d7ea625df24925fbafba4353b11e0f6d6156f9d0021f6b4b84c28cc11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8f928b328ef50cb35d9b6954e77259cd8a77a9907689611a9743117830207aaea058a5a472019f2ba5844b709f8010d21ff0c24b56f1dc6110ef9b2b42d5a0b693b61d8300ee91a4b5e3a49d4e3b003e19a94a83c17fa6e981be29faae642eaf8807ef66675d1c5452e16acc7a807932bc3d29abdc05063150aeab4f909799022aec3c007cb2aa249ed243d27b79af3653fab95a3d3f2421ba0a769ae3d4ba7803013eeaca9abdfb57a937a859894fa9b9967a2f02abd0dbd3fdba454745931cd40a010e7e87b198868ce0759e79203d904d3721348220ee0be8de75372cfdfa8aedb350474c0abe41289c7c9eca8a5229884ca296cb8912b3ad9eba3afaee1655c20326f78756a7efe981d2eab14ed2c39869ea824642a6444b87019aae0f4e1d3d53020c23941d306fe413175f653d8de14eff946744fa018434b766b0771828c0fdce0302b65190029badceb270de1245a13079d5aea024ecd0db9572d724232345399d022155bfb3b49692160fbbe6e97994a6475cdc7ab7ab61f9aeaf30cbabc54752e6031f238a15146090c0760981daa904dbbefb0e35d06a6250c50276be89905c82fc1fdce3740d7a99069d9b2d0fa4497ab494d7692c2c5af8beffd772ff0a4e1101d79b120ac59a2caecbcdfd97a1a6699fe0b690694f942ef81ada5f130b2aae6c80da554853f2bfbd463819bc017cb1a7aafb7e855fa548f5ca2a23e56d96cd626acc8bfcd6ba44cc435119d58c289367c2fb41dc2cff3a265e36239e3102ad269a51f3c359b563d24c2255bc3810e7b42db3e5d10d049c174f0243fc28931121770b70af9807829306d34358c4728cb7d12f7f9157c90e6132e11ecf12cb15b0be6eec45b89ba1c260be8fea474063975487030c81b96b23414df1cb7dc742ee46ff7bfde17df0e75685184366fb0cab475e31612fa7e5855b69c69ee8af00a3c6e0388a448a86ecdd0d8cf474beae84da32d5b4c51376d49add3f4f24dd7d0db5fba13f21055f781b76a10da484dd43f22002ff2b2f18f52f5166c1e6c720b2422ea8441f7b5003d69d3b047d948ded8cf7ed8b4cc26940e3f88d5801d27dcfc995a28c5f785205248099c1a860bd9cdcee2d96d87bdb507c21d8a5130b615ff681dd2e8b6ea3146e31042d6c8a3c79a5f2256d6f3a933fb5e55259778d6dcbce8202fae2e1385ef3bc2d8e9df45d6b463c9a3659284312cac7223b7da4ae4f1d4514132eac42dea7012d0fa233b1456abb7018f607a24f121aa6f4f3f67c58190660e272f1c7372ce92b287abc358a2f2eb6893b48b2fa5dc1f8e1e596e00d670c3191513b06ee8919ed8b694513f61e31b85cfab2c2885cfb7584aab9900073ee5ef6959aa55ccdddba9d1a6ebf36c5bec0b02056b47d84f06b389810c9be3e6d3c534809f42d62970569f138650602689ccfe815367773fa3ddfd1be7893a3a09e967245a7b87960e991c77158ad7c497250a55ee6c142174590e07b460ae7a285046070001d6e11ea93664501e56b46d6e5b557aab966512641528fedab434493e259a359b94ff26216d6c8b7a2dec3dbc9edd6168e40e5e8e15596307213c561bba915b78d405d3238aa5b4d1b4a3530f2d4690a945fb6fd91d70958047770250d5899424467a32dd231bf3512181908f3c0567ac5d125cb440129aaa96824f670bc0e9ba112f32cc0868a8f597b8d7680ad200ae3578ea497be6a9911335fc30512e15c64faae7a681d69ad7fae825eb84e8383fa1c2e3a2298e699c86994c442ede0fd9a11f1d9f8eae3ae55bced5f5f1c5b270d332e550654716d211bff859b1857facc8af777a1abf2913c40ceb524827a987c33bd98f64edadaf80ffa67b6420f90cecf6aaf4f68bd276d9df19e98df562033b96cbc3eb84637f905509fc911efabd5f0bd0d21a103fc3dfbc1f08c6da6fb5910c78c279dc95acc8df32a6837592014d05a2bd4ed6848a90b9aed307cac38575e47387496bfd2d0666ce310a1a487805fffeb2d5dffa0cbd472b48f8770f9f330fea888943e585447f0645f916cd0e9f774d129077aa182e9af06f8768b20ac49eb3be650de4a5ff44c1230855482c6a6cc34e675e84ed9dd1eca5718cbad0a004e91798f1a82808e69059bf1bf7828078ae21edff54d7a7e4150505364f86ea3131a4ddd15372af3ea17ed4efb06064ee6f163bdad0829c3510b56d95c94763c33a078beddff11859f89bd38bdcfba47469d621be96baa346746408dad8aa25d87a19e0c3a7d9d106904a316e27ca157ba8d6048a994e53906a836f582c74c30f0427c16c6a15553f2af5125a30f26db3a91f639762edc0e73f47005a4aad5c8c969f9970d9fa9e3e1195e8e6df84226fd9bf14dcd6e53f323911bacd512d8781675d52de9dfe15b8f567ccda8f47e1b4f7db61047e1df5805", "5363655365ac53", 1, 801416275, 0, "88743e8f517207abc6aa24e90a9b9cd72773d224f07fe0d2aa145bf7cabfda4a"], + ["808afb780289b60a0e9daaa37c80ece47455af9433d3c33caf578964e69c15dbb3b64136f5030000000152ffffffff6d63057a5ff568283ef88d4c7b4be772fbd4ce20342987235bad5ad280689ca700000000076365630051ac6aee3bc56e01911fe900000000000300ac657ce445be0251ec25020000000000000000000000005d546d1535afab76beebee62688954f09bde4ec219f0b0b9b16fbbe35fbcd858b71eb3804df9317a41e106e8327df4a78680186d2040def246b7526efe3bd9d2f6b86ed0e1a7ab4a31c9eef1b2e6f51d393372bd78f0dbf7111644ccefb25f8300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0d699a75ae2d5564d1487f1ce4b17467579fd5dd17a0f042f7f23f99a49daa44b0a26c0b9e4a16b1c95d0caeee6344f5b1a6434ecfffb5951431ac9d363ff7bb925f7336ae944471d12bcf0b33b5112758a6a00554956274bda278ab5c9718bdc67b280871cd00e64213f7d3ffffbd64fe849f4b7671beb13b56ec3fac16ac20224b71613693c283e26823e8e02f764dd4ea95592bd2a917536d3557a77e24bed02195a9c8456a960ea694a9c9ccd752401e67be9439d878861bc23d66aba47890b0a000e9dd27e84cbc87ec5651014cb9446ddb642a15b94f4038e59d7ab31cdf682c8ede61cea002fbb3c8dfa6cde6f4818fe91cdf0b339328e23d8064aa09e058002143a62e5059072bf708cc3a8e9d6e062eee5c8f75425f9f1d75eb68e60e4aeea0221c62d3c002562611e4b3f24dd281a4ce87241e2241ddc879561afbebcb374c703016eeb158225b77145b1fda8d1a3cca3f3cf31b785f14c001defda38ef348973020959a8e4302221470482db34611e3a12a8f50255f86ab769550e68d7c3e17a6602149287122186a1bc1351fa9aa29251a79acb16ec14c804f3b7e8efcf06ef0cbd4a0bcc40d58bc368b5ef7a134fbddc5d9824bf8edc1259fc7cd988d47d0cd2e6315359e399e6269645cf7bd631363fccb1abcbc3837f646f7fb4908a1db93c509bd467040777e510a50654d913c39ab49941aaa7a032c1f72ad78472a6c4a05b26d24edf59c3fd5d119a83e4ac2bd2b6d723e861ea4647217e07aa0d01e8c2b490767c02d1a0f92a0b4eda760dac8df9c3dcb740af56072b477f7a40e026410559a8edad69b5d05ad24c29d45cdb1e96b94f001ace53e0c28f5590313e55b5792d05adf2aae3235e2383b2e3a618dfcdcd04fd9b12f11d74798f4d3229b96bfa4972239c0da7703cb792d4e58697554dba040f9b6cf09b67fbe55d5e8f2a68e95d3a86bbc29bdb1f1febbb3472f104d4210adb9fc00c3ed025ebf44474b35ddea9892da08d88a1256572c7f4c3fac78f93871731f63919ecd43e10b22bf141cccd9399ae7700754804d4fa5538a4bdc346fd2c4b78a62d9feca3ef1341bed9160feb25ab5618574fef8542d7c8f712d46129a86591c8d6a69678b793b3d2d2f16f9ccd472a2196d97e9a51aac6246b0708c3c74085cd7ac2453cf7e6395a2be2b3851f08e85f67c57820aa4f4ee757c8b19b451f2878068d3da8e1b7f6b18a4cde6501eb576fa72ef890bda5ecb1b70292c228ce0abac22de3ba3760fdc31159d43ab3c3c1dd14584397ea69b8b543fd7f046fef7260ad80c95153cbd9ed51f4e5799f2ed86fae65dd4707ef06174a62bc7075df3a7588a0aa480e80fd4d3350376c80010a3fa2569356aba9e00ea0faf56fdab8079ec5eb964adbe0e58dad7af700cdad1f2e010b93adb29a68a2754130dd2b0b9042e9b9a7e7c23960f626a588c093d66f4db87ad591609bfd5c8c8ffe522f65355c61d79c50866502c199482e3bcf66c1d0a94c7f2032538fe07fe3045522fb4b7c9f7118cdc00d9f5f6d713bcac1f231eb333663c35f14bc93dfbe6ef5726b1a67350ff41d78b35d83558a60f5fdd0e89f991767048687dc16b8642b3607e807789f281ab3775c4e3c02c1f22f195b2d0701d944c4e6f1c325546da3fe35ff978561ff2fed5ebfd966b69d1b51f64f1b26eb37308d71448b35b956f2a0af5d0306546f3a354941b94014ca390821f27d1eed208b33c7fee328c587ca2dd5fc82e620525081c897c3514e7514ee5a32b7d89acd33bb223bbeea300772d2ee555d43147a9d17791404827e82e52a174091452832e7b8736fd4872474cb100f41d889a79cc3fe47499df546469dfb4c2bad246953f84bc63f650d74f348482654a021d3b44830a9cd0488412a5abeebcc25bd0ce83dcdf7a6f86af46b7b07f599292ff2f41b76e3c38e31dfb61edded4f5b9ad41d8148e4606582e1c0862a03536556183ffb67681d3c152dc4b92ccfcd022b5f356ef7db977e07a4984ddab1d11d1fd7d3f226a761d63077cd1326f1e8dd8d368d0145d897c380a893af59dbf1e2b7de95d7840d8e139cc9e3ab3031b7ebbd6fb24ef956a9ba39445fbe57892a558a925840ebe85c6c0f68c8f38d099f1860456d1d1a76902748c18b944f94d3361046d8fc8c8b47622d0cb9c5bdd1bfc12f64eeadf43f2c018b8d3adbedc873aa5bbaaeffcb5e81e4fc8661c2d47f1a9b6994bc8445aa22b15c5109257183ad6c93950c2ba42b7c15a4a140cc91d1414c77d9a2e3ab2ac166ca95756bdec396d3000000000000000000000000005dbdca85027e4082725499242ce5bc23d2da66d9451705d335ead4edfe0124120c9dfbe02814da8fde6318a6a9fb6fb9278362b951b9658bf8316986696ae3fd5757a19a27ee9cde42133c745d101c9d89f6e77c6149a02cb5c5386e0cbde0b80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085fed1a0b7ba363fece63cef026a73e0506d51c7780788a259f0748ce799cf9cd917f0c7edb290b2d10f3132c5827ad70ee492462f4426b8551fe0ac47b34033530673f8f051bc6af8671f2bd6f27c48e542f4c9c86545cf59494d78c524bb3ef79684f895cd65091467d7ff09272b5ef6c2e8b0ae9fc56fe216c784da7c56070228f95702eb0da109dcf31131ae2e79e45f7c2430d0c64a9fa3b60bfdca38ac1103172e49183329b7f2d0f754c9a0497ff464d7a30650bcd8125bdbdddf1791d9a30b06fecf7ae943ad63bd0fabcb263204d7d6bc2e24bf89a9dee89a228f72c4755430f1c2b8c25b97258a13fcfac3ae9dbdf2cdd076e7436fd0b0fca7f73b1f4d810206d412fc184d1e507c93da48e25432bfd16bc2f1f158a2c7e6d3b25500017a08022eca8ab73fe5c1a4e32474d0178dbd1b229365c7291afb92b4ac263a0bf65222022f39dfea513324ff5bc29f4996832496ea1860e6d42796819118b14a3b3b4a450229faafa1a17b721eaf29fa5bf13d6554c89ad21423a061f1c69583b702e2849902161f31382592acfcbacd6b7474c359def407a34fd26381c435e6cd1b1ec79de10a2029464b28d0eae9820c6e6b9cc128c31276cee206915c560dfa33504eb74cbc9bdbcac89189a2bae8c40c36b2a3747890d2950045660c0a7a6b91866b1e0e068533ad1e2a41878b8fb7a75e92b6cf73792959b80fed47375f90a970f5e5e916421f768e27726880bd4c1f92f06d4bf54ab96ed42bf2a56f41df9a5c702e8a7c93e1b2a2725264742ba2e294d8fcffd96e058e52863d6bb732dfabcccc7cf8eef97876e680784c20799d5dc4ba1cef8086e190581509dd157e0a9eaaa679049240fb4c6d67bd3323143326230a19ce8bdf32ac73940308ce965feb7b5af77c9aa3d53c5634a6b6e83816f03a1c3358bac5e2636bee3a0052f8417d5f9d73a42a86adfa1e486dcfeeafe1e3b0319be22ab0f9effb82da5b05f09c73c39ea10e49f6d28f7f3f961050357ae6f03443ffaed8390fd418a78536572a75c17a9ca3f0fddc28090c90a83999533ca8ce498c311a3534026a65676976d320ac671cdf58a95b0f5e448246d5f15569b3039c1c096d89c223158415743b68fa1bf07869b9d0b655f626bd6433d1f93b0246334dd75431d94666657533540e3b853ed9eede4088911d3f3aa94a18837976baff1240ec8f838d123876a9cc8c330ebd0196feaccf80f5f4e66bf4e0221d18e5156fe208d28165863a97e9e79ad3d07326cc72de3f0869c8031ac583dfebd392c2e8d77bb6dd165c1348fd78dfc95f691bb7f1eba6643174fdcbf58175038894ca5759e831ae8e2b25e3c96f8235e1e3a9d1c40edc5a78d69f21e8b91872d46f6b275b071fbc2c228122877efd511bba502989efcad6c3dac1d5ac1d7bd48e09a7dda65977c7218da7a26a5a7924aff55eb73d7f6a8556af49e0966b434b6d18a0be7a4d9b4dc5d25d112da86da46fcb0d89aba389a3f1bdd5de2808d52cf08d6b8fd7436c62566af4633ba31abaa8896eb998cf489e140fe31529a2a83c6cdd4f7f78168251472f0a9bcbee8cebc9a3843bf71d810a979248eaffc3e34a5e5349b3f860b597708b3f3636216ad5d18e3179fea79e67bb3ce2571ec55be5b7460c4ec8046f0e839f4ab437cf39cce66ebd81c67620a72413bfbd1400c5848d1e7cbf89ebaeb2a4c8bf7e96d1731b93c263c5b09c2488fd206bd01127316f52a8155ad51ffe3ea0565e6ee83d8fff621a4e13af671160d90908e5d7f400c57230b74cd12db1afb29c1f44dd0125101823063dc01417c6b8f11037a157ddf9f01e87cc6f782d0e67db135239eff2e6698dc565cca1e61c0cb64f2a86ec4ff5d05091fc34b2483e51eb072365c821ba6807e1e9800e28d5b40da3809478c3127175e3f7555f02fe6a7f5d16f639cec6b338a5f15f906ac97635fc4639fa6a54e267e2d85bf9467d4007b87cc4c04140a862678774c94a9bcb7e05490fddbf1996812b74fd3767502dc2249d97eeb74fdf9b9a55bf5a29a255c4ecfb292f562adac87860146771d30ce2ac41bd01ca15c3816718682ec99eb3995eaf5d3d4d79c7353818944a246795af0b5936c17b24222f6e2fb0d6b57ccb443d653393991047542525431677bdcf4401252cfaaea1c3153b53109ac1374e94ad4ffa6a50e28f916898b3d69cf13b5f883182b70f0d8f79bc8e682e37e59237620086e4ef74def2b2300221b667d074e9dc55c1929416b8a87b8fc74f5975bd1a085cb1809ad7899b0854f80ab7c6e05cc130e7c82af5b32700cadf9314f65494fdfe2228f36c2fd281ad254a88dfd5185e98ceffacdf2e494974b7957e7c06a588bac17aef045293cfabdc5a510ece15d5fc14136bdb6d92869847298caeba3607394b3f8ac9404fbd1603", "ac5353006500630065", 0, 1826186113, 0, "acfee0bc56b80e7af6ab28588efe82d113adf47e9acb10205ffa36d7abea0574"], + ["030000807082c40303d04eb5d525b385b67c4df43274660e234be2c748b8cd03eaf91164654c8de76102000000056352ac5253ffffffff433659e4b1aa2ba55acfebe9020a9bbb9f2c87f9e6ec0a17c31773ef3e5cdf9702000000026563ffffffffd2d8138a195d19fa8b91876a0e480489ec6122a4393373acf667213dadc0147c030000000151ffffffff01e2cddd0200000000096a516a006a535153635437f74970096072028e817203000000000000000000000000ed49a51d2c9933c05cd2e8cadfe0f6a14d12a35252d0a92f3a2736c9476ed75531447f399e0017ff2490fdcb45a3c81f1d77cc91bf58d7a4e1f96611413705a2140be4497e03d731ed67076341be9a48fb31670e8c3e23d4abf416aa4fa8543e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003dde277346bb3fbec801db2b6048ba20292fec7f338f415abd2b14c527282ac37d6192d7ff2062938dc1a2bbfdc281511e4ab6ee964a7ac937743bb185673817c537b99e1c4936286783aefec686b4b80ecb316acf60f9939363f2719435a03fa9ab72898e0a3509ef323b50a237ce57906e93e779e68243b92dc7408e280ee3020a99966ce89a94d8acbe4229db32a2908a2c7cfcdf142132bb572e255237931a0213bf53b3a3fe43c56ae6fc2cb7c3f4fe60cdcbdb8c14b03fc9e26653963a9a4f0b0253aa76ea56cccf38d7e6fcf202ddb4546a34fda1260c09aeed4ef662f27c7180e76851c66c5717b78e88a1af9809974629b4ed3bce301af41477370f3a1e7d0309b61d98bf2111e83c8f2c00af63c0e5e200921c3f54d4fdea6fc333ec31c681031af13fe9575acb591de355d59d112a83d92bd5c86e16bc6630ffdb2c59e9524c021a6a1caceab8de27fae938f8f455a132b48d0a3c626401f29406f416bb7bb835030b656c0b99d608234cf670bd25e8eeeb9e6a941ddd0123ee2e8439b5b252067a020d4ebfd95a4a5f08de4d40c8afddc132269a4682d50cb9bfd2776c139d146ca458cf78780c903c2da30ac59c5c8f1e47b493ffb4a3e3d2b3224743d5fec7c5f8be14421cf7635495270a59c79f7defdbc998a0257c4f587b816e584da58cd3bb8e70aec995aeecf2f50fb52d409c5c734c6ab57f2c16fd3025ac779e0aa7248f66a98d664eb0b6398a77d95ce8fb62835dd9f90f7d74499ab2a5015eb0e8a82e95fa968eb647b7ca4ede90256d86160dfc69dd494626989247d73ae37edb2cf07e5e07ff2c0b583821667090695a65b85edd6aa6e6b4e7553240b5c68ea163db2097d053e7c307b93dfbbdb5bcebb87286e574923a3135f568cc6c09588b53165c3767a49d5a7ef0186d454eaceaa27cb39543d094bc91587e1a2baa8fa0213828995e217577382e86ee8c87976d0ded803ef1ca0028f5dedbff8c44e03bbcf92bb0f83125c3a865c9f8c6d8e9d21b1258562767967a14636bc970005c4f1a002d4857e8f89d8ce5e425861c161d814afd1cc289d07667fd1a1a8f734ecb50a5d664f9e3302d426b2682886c73262ec8d898623e2880b1bb4f050a43f06f80190819d5fd25102b5adfe7c192f9d3011a8aee1481ca4303f76e285a53bb8211bcd609909ff8d156cac7d5468f0a8543994262a5d3db9a8e52ffcac66dd2223cdc2288eec409fc55dd7ac5cab144d988dd928b89c274ad65a7658550a6e93058a8941958ca42c7b214973470cad9dec228215568b86a34ecd670001249630c10346b16198871b895c72fd5d930f5e9d16ce3e87f72147ba2adf5eab29522519119e672162c6c875ad69b8babc75fba01a6e6812ee9c49840fe2e5dfc4774035e886ee004f08bd7d91cd13522e45e6d13c04f49527397a981faecae4427e5a1a367603978872b8e42c730278506da01982ffd7491875ce605a23acc6b6115c7e211196abd8c66cb9c9420701c8d360177f1ca251f7c594e1f8b97cb06b58d3121351ea29cafa30ea0bb78e638d9cadb4829ac995a922a54ada42cb6b81b1fbf172312e26a7d9572f0cc25f5e72d3e5d60c21572c426bb87406ad6709286ddef94ee9111305189f544cf979480291a86130862c2d378ed2a71fbf49755d7bb17aa45ddf8a587e5e5ece269582bdbaa1f2e4279b708f713f5952ebb2ed5c3cb7979b0cc473edc8f4c3a605e1f3addd87440adaab154a37ed814a623411ee3bc9779ccc96e861d84e18117aedcc45b20e0ec1d58ee172e84c86655037da1316aacb075e99830a9fd50cd3f910a3ce667d3872f29dac3b58dad3f0fa3c391dc05c419e971cace1dc046af9092eeec48d5ee01ff023bf98f449585d3474c73de25a31dc757707565701a77a841f3ddd888aa71a479d6e5a572053ecb8d99e6e5f2413f199b62c1da5b19a382f7502dfe949c14553538949e3031533e108c07d93958ce71e8d7670ffca1d013addb6b90b5d02d2acdd264fc0008f72b829adb734d74af86837cf6b55836f7dde672536ef0a87450cfebb8d2537f80cd995377ce8d663e14f272a3722ed848c592dfa1230c3492326ffbd5de263f4368674ce7e40ec6c3e7bc23fc3e8e1ef89b4231fe39bb79f2255cb2faa0f12135b1febb4c9623bfed2b763aaeda82b54f2656953b22ca3405b78a1c03ab34caee58d15e94931083d9f11aa0e205ddd9369027202d1105df68f3e493d13206a4bc48bc1287747a069184ecd29843ef6fd279eafdef3cf74c5dcec43c0000000000000000648a8c04000000004b6a7b10641c4070151b9275b451d7b0224ac238d850bf103e01c3c3e4b02e29b6d55f4041998d96299a3c602d60e60d3430ddbf6b96ab0b354ef39139928a5a0c205551a20672220f011df430c3088ee0ac23fd1703744dae93831c5d5a7d81000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006abdd2e2dc0757d2c275b9224a5cc252805a564a74443bfa5505d5bfc3d81b0501570aab8a840e0a0a794ad3e7b3d8a94aa67603147acea11cdfadfda713d65ac248f39575b4e5ff238aeca7b164cc05782e7ed4a0bf10a6b58290017fd0b1d7cbb46f51b46be0f6eb55fbb73d927f0379c2530e7b0f20559ce56c06e1dcae71022901ebf6f900169572c7012550577f85cc8704c5a2b3e4d0f1497921439958a5032cd42bfceaee3695c10267662de9b9c85e7d8ebb5be5482183e0e9070ab93a010a04d8db7afcd3abfb4da7638dbd40911d098bc1b9188d60b11e6d264cc16c701034cd2489cd6ec208e1337d20744fafbe7f3faf06ac319e7a42bc0698e99755eb0330209e3497e03de52daf8134ef7d81289802fece1c2595e7b1e1f67e95d07a4b03274fdeaf3702840a9ddbcc580a00007c4efb9a7fa0f884477124d042f2ee8e33030ed031f11e2cd71dfe3d05820f55fdca179ff34ecc17a437f128f9d5c1c5823c021998445efc913163f4507b601675befe4ff57af9ba4ca5f953019e172243057d0212f7846a4be0eac337fd955e88a32d9192e1f70c286edc9b372661585952b9618342e8387d5daf8de4e1e973bb6368e04ed38627001754259e7efcd370d0a17898db2326b68f04931053144a4d50005ffca735735ee0bcce9592bfc8dab78f55cbdda59314c468f99ba85b53dc2b21d9b3e34dfd27bdaf37dec3e17cfa14dd0efadfc43515bd86cba0595b5cba61184fd271c625bf925601fc15383b536ef7170230bab25776ad8933e39f60e0d0a6b8520ab48067d8d31422892f4c9c12fe37e45608bd12f57b6a69ea2d81dcaa29b157dbc9bcb7ef523cbba2f189a8dcdd8959e451303ac4ba35528474fb1f05788d781814dc45133f6eae0cd0ea78444aafb8e3655f6bbda05cb1036c93a3ecf4122411f35bcef56bd34518b6ba6d1390ff0521b90a5b78c15a4f08c496f0c0b22cac6f3b7454f36b2ccad0094bdff729fe3a22983d197079a7b0a09b29d98734933900ddb5394db6bfd79c61653c708f0ab810cd0087497574fccc4dd48c7f0f9035f7c12c34b5be9e55fdc2879076cf1b460b4e6b9e993f4e33061827fb0757a311d8b4defcce6aa54c2ffaaa18bc66ae4f24e1bf09edb9a94fe75cad631332493dc16e3853e3419826cd96209bcb495f4446caa09f93bd7c7c86708da2b7b1bd393f997d962f3e30538150c9a54f4de8b1a57b8ef82e36afedbcdef8935d5c702b7e3e34b364cc8b989cfbf1c37aa5c7b3b029ec1e0bf82472513662297e8b81ffda1cbc6d0ae16452ef191bde806c8121508c60f30d98fcf50f654b5c9530ba462160e1f98dd5c58df91ea920a883b9b9f7bf4f22aa95bc105da1be51a18365e990a07b0de2cd54e9e307ffc12b2e7003c6877777a636fe25c99f118eeb8df6c9016adcf281cbd0792ea5588da6ce95e8e80a4b9797c92a02cf327099dbef7c2aa8774c8eb9a0b877facaf69116f1d5551d7125aee27baf6bb03e8e7b1a3f8f96e428d72918ca74e701a858f17b255c767ad8f2660787cb32dfda3dcfca67589e2bcd5b90f34f50f774a72d1a27b50c1545ae7d59584f0ea4188f72cd855d4b5babcb15aa4612bae43183a71126ce5bdd24119be03f440d3d4ecb4f454547568caf67aae03d04eeeac0e00015150fc3dacbe3205ae1bffd25c250a794479c6db1f4554568dd92cc6252fb7ea881a09d959248bfd5e57d19b9eff13821473aa397ab7286f8c7d8fe56d3cf1cbe3ca174016359f214f023486eda246adff1fad8ff0aca6524c725a6e053644b56ca55f75970189593c9366087aeab2a818f5a66b922684f879fc115bdbe7a30f1a93a955d11f655a2b77f5be579e04b90a695f32d772d9f727bce3d664e31c840b52c62adc46a1a742fac77099c7986ebea2c0c04d2809cfc3b55860142aa1969b48d367e949025b1caf70d3014c69fab7cc19fe4ba4a73eb0de06c1e19715d44658f85313f98ed938464b43dc5869ca134523efd2be9c01e7dc23f98cb3cab11ac302a08131e4eebfca3f89e2dcfc0791629d1016e0c5099def9c387cbbfc1041c14a470d3b4c6f50696afa427c4b7877937dbf1ab428830a164065a658459cc51f127986e5263dc9e6015e5e93aa8ad1fe0607e41a5017cc7395ec637329586f7dd656b9d6f34ae916fd9cd2db7d95388b7610454be0078c3bc0974cdb59dfe23f7f2282553ab986634a642b730b1c611590d2f41fc58a5c1acfadc0a67500997def0504f18446f9fbfa6cc1ca4ae136b61ec605eed7062a4949d527f9216bcc28bc2fe7fd556465fd568835e24a9ac107580965db4f5fbe188d1f27313cc986bcac51efac75be2e0c781d7bd846365600b5e76f498ee138f430ff1ef5de732c1da849b3bc671111fa28d7f3536cd30185b5d6d07", "", 0, 971178703, 0, "1ebaba9df16060cd2439534f3aa7111cc3ab0ed3b59c47005a02be58bd74635f"], + ["45a2a60401557abad87904b0fe2a618196e5136fc28483cd8c18ef5debc82bc80de4d7139e030000000152a42a585c03264a5a0000000000096563516a6aacac6a6a0d136e050000000002656ac80931010000000007ac516a53650051b2daa45000", "6363536a5300", 0, -1766309209, 0, "6a36e6eac9d764d63ebf461fdf5c6be33813cbc3bc39f4c1ec4b9028deff83bf"], + ["89553f1e01c34e0d8f39fde7e9f108717a53bca01135f8721ecdb6c537a43816c6c568189c0200000002ac63921d37b2014847b60400000000066a635352525300000000020000000000000000e6e9a40400000000593d7f9bb78dc5353307b3f6cf6013ea11e5769bba7a5428e7437458f23acd145008c62d971bed7713b2859a59587f9a1699974731dbccb1bd79f13de7fefc3d8724daa3420d7e4fc78d152ce2d5303ebc4eb3dd4790936a39fb1438caa16d79000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f2247672c558bcd4695f93510e07b571cc63cf6bd0b38d471c1a3dd54bb24b2283755ea75891f27d1e7ee66ecefcf916fbab553c6efbec78c2511a93946705a5ab4ab714939b7b9dcb9342b7639182572215e30cb42f904d960f7f44712609ebd0a24e792dc9d4585c1ace7b7994cc9adc26af77fe8fdb29caae7d8d7d146040208645b1b0c8f7c7bcc1a2a1818c05b53393f022524185cfb8d1e8e707e3b4527030983ad25b3ad706cc37aa32a0aaeb7908c2d0639b1cdae8171737e4100795c8d0a020d97efc0c2f82f2d506d74d0609dae53e1d688169b79a12b3d814f5fdf8207f53fe41816461528da822568d708e04711d0e360125f5b3ec1fb7ce18931971b03150da68e8b66e77c26f08b2700baef95fec71171bf47254149d0343d4283c17b030a48c9af684850a8f25565261dbfafda8206803811892e4d26e05c580ce9360602035f387d30e476445ff8fa35930c76b65186f3a20a995156a3465297eb63eaa2021ba1417f6fd4560a02d0960de0598c59d9c49dacdc94676fc52d07efc79614a00229b6844c29e89766a9755c50e200993163f83dfd590f2a4ba07798e5a3e5d1bfdf7cbebe8b643e77d69e862d9f5e2e67e00071e1dea27892b652eed099800b0047364387fd4c78920bc5b71ce928af479128fd1ce5b71535c16f1d09144c63fd38212e35ec2c928d6b79477e00de16cd3832fbe1e5144b6c8b0e880992554f395289c178575c56bd42e53609f9a00f6a4ab5a98f8b6f0d28556e30e97c8a5d579eb811330afcb12120c107f1b2f13fc49d4ea1435e7fb4ab82cd63e2e44d40fc8f9554d5b1b6be8de2f7cbc769ccac226f30554ee28a50bec136e405c4a91a356fa2362abc4dfc702d940f7cf9daec293919dba45056228940e1d2f554701fe63232b8c19764fa5691cf1a99578e354f9c3f29e91d0e24292b2855819a1a39168d0a8c12619c4ec47f4f47362bbd4c651b7e4bcb2415013eeb67d36fa914566c9cb1fc9d3f0b05195dd501dbd5b85d99f8891857bad9339389e7dca4e0e3fe5e5b80fc9654ba52bda2dd7f50edf0d3d75f0230020eef820630661c69017398f5de79821cdb6cc7387979415edb42542ab19c95e67318375dd9fc55e7df81891ef7a96f64964a537fa67248e20532922baeea49eefbdfa145199e1df7e888a5f5c37b916d258048afe98db4c54a03574f482b629e0e033e184d5b3d095496c830d7ba6633d4c600b6e5f0089b6d4142915d334a306cf2daec38a251310a5e8f3fc2aafdadb042b122a09114c830de491e623a1cbcda30d843107f5de6b7b65f8f277accf5d7ee73b55a7d7403c098824f619ff1e1c4529dec5b6c7058950ac6479647000fc20383078a6e75910d96673bfc8f1d773ebc389191f1a360560c47ec3ce61ac3ad90873018400a14626bd522977de79a4eec659465b30dd1cd04ea813d3ae684b2d3d582fe71449e53c3db3e03e7775e82eedbc659babbb89bf88fae95b5f7b7cc04ecff95d3764adf10ea6afab476aef260a14d567ba50f73e7c599f9ad8e8d78c165d1b9b73e732fa04b268fd0e2d55b0b8a32f015f0aaf80760da8e9040f99058c41e0803a4a77cf66cf07882a1041efa89c90aa446b6fa4bccccbb9d829479a5a2eac11a4d8f55114ff9be9961759a15c0ba46312a939ded38dc2cb5840f4408e34482b13a32dd4902440d62528df54f978a79d4e88190ca481251e4ba3245b043a74524e494f0c55a8d171b39f32a02836989afd3de8fccafbdb55f61d4193b0753125706b911b8be175e14c3e4e5f20adb9dc35171fe11efd64512c5eea084a94adddd3faefcd1f6c4333b2cb7a6dc4da7fc259d8aa912b612d6fe6bd1f6bbd36221d0984de27169c727633dbd798b8a8d36018b4d2391aa06921f63fe1bf791f36b23bfcec40975a946ede2ae271eebe0707574c263f9feb7ddb8c04f16e9bf0e94576d277d141278cb0bb642585328e37682c0e073ada303c30809d17eedce16d7c7dc8e39ab89bf93c3fc9508855205197ad5320fae4b624f00e07586ba2c3c284751f741c57adea911a85a6ff8861453964ac7d8899160770ba3b5e69b3d092782fbdeee7a52a111b837e917bc484bda35f14d4bd9d30c3ea9aaf881d1a521a4996ab99de0cc28f7bdaddf19889f00a1104a1eec4588cedbd3197ba687c12db96fcd0530c63ce407ae4d2025945dfda0ed18120fc92cfec162545e167a9e1f23b8b347ed733fe5f30b6351e45e3a411ad9a6fb0745572072b087b18894769f177254641f1acb8fcced000000000000000049c1dd01000000001149a6bf21fc819bff79fa85b4ee8680de5b260e818befd406c4fab7448ff5e37b651ee57a5b1ca3e60cac54745043bd1461bfa4153a182a1a18b275734f76d81c9091a1a0f0cf9a48ffc6ad3934b2c57f9c19bc3ef49fc432104376a9b0a17d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b1ab7cb044c3ebf164daa4c2da3fec5def426318c25f0fb52112ee1f16c4818e01f1ed2658db7e42b8db9b38bbcb63719d27efe19c8648b100161156b21e0b575204ec7dd9addbfc8754cfcf1eb7a975ad32262841f24bf43c8c87c2ad9df26173579b715775a60bd3d3607a27f7c26192322c8a8f6f8f37acf094aa3b73677031e2deb1b790f4a0d1f433552d80fd71c79244050c51e37837ef989d3c0e12c7a022f5078bc64859bc66ff36a79bea9ceb8bc6e428a7ca663a479e8a0c1a19aee110b081074474e616eb6f2ee6283105a2c1479e8797ce65a815196d1c91ff17b2851acc107ad2e43742b828bc8d237cd9704fbf09a97d1bacc46e2f869e08bddf571020157ba962346150b1c71e0c6a516f2c6fff68aa9cabc2c5403cb243ed7dd637a0317d14f78d87ec11260df3dd714b49cc8a7a3b21f8a187ff494e97d5d0f5ff207031a0861e1922a0d33a9d86085267742c5a4484ca7cc5a43901b9b26b2068cfa2c030df5997bd01d7ac5f19e678a655a682b32a913c08363173191b01293bbe48907021c74126d7a22fa38ea3249af705d7451ba2b085d0a938fdfa89cd5a654d85088d863f50b3cc37229307642e52d3dd156ffa06e78eba10cd6d51c4e49bafec6c0a4059abc40da022df19f2b9918f37fc0a4c3ab26b27889601345c8eee7bca02564b554c7f234685c55a3cdcbf70036dcd1cbbd15430a78dd67ec67a45feeb1d7e5297b99a4015a7d7a2cbcdb651667ebe3e644b5a321b1a98c2c3ae2400e5a0935c215939c22ebbd618778cfbe7372f0db6541bb63661f62be777583027920d24b6b44bced4cde1b9aa968d028c00454019b47cca70010fc615f1a3646c510ccd977503fcef97cb4ce593c53c796ca1771b60398c082f314f1aa231b4cc70afc8cda9a37de8a14ea462f81243e448d9855a77f54a7e05d2875d5aebdbdb36d433016f3b92546f467cacc94c74f7c51c8ea30ce95d7efdd8d03db561524cb84912e280bdec2501ea758eb2b4df7dbac853ad4e38499245b38bb86371aba7369d69a380cab5c472dda066eda44b3a9681900888f277e66a13b3844832b245edaebf501e3598cb05d82fcfd4432679df00f918f081fe8cdcd594613d9c51fb9fd187dd4532f03296fb1ba1d2f9cb1f2213cd64679758235bd041fb31ed1ee65ec2a2891ca4641fd744bcd38f2d1d729e0ac448c458f9776e9882113736c2bab120c4e9ec379b19f59a01eed034fcba02f2e75209a546f43885956bd172d3800ad5d341307f0094b7702ce97d0379a9f9dbfd1d24f8d8dce66688511ed9e740fcef4f82e833da48c208e9f418bb15a046ca598451695db8b9cec127adeb9970b3f8d3448b5163a02ed684c093f19da394b546a10100dbae7897be1dba22ecb5271d0f9be972e04ed50accc67415de24ffe60ef0ccb17fb133c192d0fca4044d09b052678c2554820d99f8c5592b3e3225c7c1c276cb6de40cd123a1ef6467e0c4337d02711e754b0fa847f76dd730bb861ca3d5858312c7454a271311aa3c1b40af67969e285d63a029eccdb3136102ebb6d31e1dae239492d38697ed3fe5bf2dea6cca7d74a6f156adae7660253d74c947cd2ef865a96060fa13f0646a6d088f034145a6a2bda1a96816abc1d7f5845f9ff1291366849d4198c20146d93f48965199edf285cb7fd710d08be32ce4def76b342f618da5f3de7f720ce574ab6a3591af9166a90dbad80330a7d8afff0cf3e5978f9d76010183ccb74433baecd004a3d7558876771686017f08f2c58c18563ec75560508f887af925bc89acb514e6ba43fdb67016305271a71968b3bfe1d43e7cf7fe3d18f70fca143cb30a9d843d8bf435ed4898f31be4cf3c3de170d53cd1fbebf734d8d7ad09dd81f0bd057b21e582dca6c888fcce5b95e925602486970a65f57253aed68d27a3966f8a316309b29d22c2644f9ea8665e6b12dae29c17fb6469490199a67a723a97d9f0f7fa6b1f49e2578a19b02b7ff4f8a68cee67759ef82ce8394b8b387dce007c498806f9e2ac9d3bc18528401614beb59528c10303a7b9128bf2e47434b62b36903795f37d59c6b1fc2dbea41d3b81ce491be1b9080fd3ac78e8eb6ff7dba482daaa33fcc5ba9adc989d4bf85180647ba7fc56fa4ce479cb5faf104838586d964acf3373435a6d91c1ca4bca421691ab2f11837096245f5f84eeb7cf5e7dfc62146afb1e3a5e760c18c6495a9b20f644f544d3cc723e8bb8ca2bcd9f52fa207c48456c18abbe6dc651bdae846adf0b0075489e63ab2b931644ffb2392d9d0b664030bdb59dea3cc24be6ecce37ff2483ca459b3095f1b540c8cb077d248d5629f8f29152182e8d0945a7837cbe8f60e3bfb5608e3d7f24843d50f65df1cb54c5e2dfc09b361500db97b4c26af655f31a4bd036e6c171609", "53ac", 0, -2063601244, 0, "002fc7bfe2e15ff2ae89aa9319448aafb237bfda39ddb723b47a8d42d176a9e8"], + ["1d09870401cea927e1d808060d058de7c87898a322bbfa104883730fbe293843d81437b63c020000000365536aa2c7c66201c1f60a0000000000086351ac6a6a636a53000000000119c2e0040000000000000000000000004340e96ce18f6d4e9ea19be08874bfae6b8157da50455c7c8686de126ec6d5c735741bf14bd8111bd3cbd3f636ebfcdecd125a5bc5a39b30696ba2c49979c987f95294ac91991a8127f670560568b0bd98c48cbd2e96c27d751d4876f84faa0f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ddaa8950a1306585c89dc49c1219fe8bb945d13fee3ee06f67691d1a08f2516038ac99c12b51db743447f18c98b863bc634b6fad55ee2a31e6a693f197928e8783bcae4deb5617c0ec193e004b30b33bd3ad1060335367fda7bf11214137a482ed1b83bbe83b9d0817731b08292cf1cc86b05bb74ac2f6e7cc8ccff6419c56d0324d727d8e1fcd765eb3e7b890521ac6b15a8e587dbc697bf3538bfbbf85e9905031895d65a1d0603cbfb623ede58528e16592553d3e0c448e7e3acb3a36823bd850a02c817b17e0b02326753c26d77f9bbd0df4f4d342251157b17a654290693d67a6ac77ddddd0e8b79fecd247323205430cd9500a4fd4aa2c3c09c6fdd86e65b4a02258bfdbfdd78a5587635bedba775ed7947aaf514e978b70281a7866559860bfe0326589a630441b4b9a375a1fac3e3830d7e6f7993a9e5a1dd23256f283e0d1d9f032faa912077d4f426f2f670b00afb06674d96560ed84623afbb7d11ee2608a50b0213fd784e42c1f8aa1b9acd2765615976068028132744ff22e9799dc76beaff1f02002f1b498409000e5cdedf0d77b96212bc1e3bbc976ea085a1fa9a3b7c8916d46f3c8d146c6aee0bc0acc5079c1e36ebb8203033fdc6eb1f4eb67d0e4327fda50cebda89812b841dc6198fea948da254ccc2be0ea303c578b0fc42f7d5729f0f280869b4eda8caf67ceb29d698fe4c16905a132695bc3caa5092c2ffb6ba5a959498cae00d60438a8989218d0b7d8668bb0218019c19f11ac99af1ae1fc93688349929079dca123ea1e489019735ecd2f7d6067e9384dbaca2b93345d5093c721fea69b6f4b84d38e1ed34fcf90553d91173cebd8ef3e6592fdfd787fc19dbf32dbac9011367a8270fac00608a8394526e46ddbf232a5b87253dbd365ba43ec8ec3ec77a1dc2e66b5f29d6fd898575995b52dd47063e066311d82f06493795a9a0f64864111197f6d171e7bd016d920e3db896cdf43e05b0221c52e67edd1fb96f18ae77ab61946caa03db0a44d3330d60cd4fe1a63efe098c23fb9fec0573f29a815ff5d4c0f0d7b9153f78215b4b37be19899e085570ebcd145303878e7916b17c09f5e72b29fbc4f9dbdc790020d76efc43d75833c2ed488590e5234c51096a269c4fb3c394ca5966ffad7ad4ac7a16a083c56ad1583294dcde1fa57322a91c3f0f55172d41418ac0ea1407d23006c5241436914077815ad030a9bc4c96273d1318139342538d1c08421380c3af830c4ea0ff66b2af99a12b94333f6f22a7b289087fde35d00764abeaf81c552dabcef40005e6195800223a03f9fcf21de79d79169cddb06dfb3766eba05a1d3821eec9cad899ee464cda664dc0a2e411ab147e85b038cf0fd15595aec945389f7d0ff4c31d05a08eda27f0b55f0b8d463ca208a566b9cbcb51ea79856cc50a78877c58f4de0249098534a7c629467481194f7d481b7040d34d66692c121bd77040181685177c7ba74965c0f1abba456ce4fd9a6f2079d344ce17db1192092fa160c0e8c6be40fafe313fb63fd964b06ba98e51e8f10bbefe4b27fb6cd20560048adc9ab31445757399c4b4af872856ad222467532eeb3eb713ed408c10c6bce51811e13ccd640c83c90b3f20c402e9c585f08309ce0d13c8e177908aae7cecc918f35b785f07b7de88d2dac5d7236edeac07a0bc99033aa60c739f3a75ffbd24c71514eff04a5090c659e1288a8cb11043c67ae5db556407b7c7ab404888817ee0116a00a65622ed8ea1c5ae35618516a7b09049845ea7ee29d6229ffe5fe98b5319e43286fb5ccd810b3d581ee9b8ac60df687adfd4d7854dc78797f595d1340970378f278edc4cae9bb668130f6021ca18754ed0d9056dca3fe0ec39abbbdd9822c9efe0ef2c303d70200f125e95879d1adfe7b36a6a54516377a13e958ee19649923a05c6705c808d276cc0a92bed9daa3e208555ebea34986c21ab8f85b8166e64ada3a18831a133a636cd53ce053908a98bd353d41092d4ef9a4453b7c7b5c8f08cf1de96842d9bf2deab014b37e347057a98f36a68ab944c1aa1d8aa536b0dd7af5ce2ad6d15564f0a96fb3c33d112d5345bee52970a8a48d935fd2d01934ef96d6f9117dea6c4fa6bce0a723b70bef9dba816afb274de2547d7b64daa798bb6cc1513b07423c598a1e600ba81bcfb09b49f07a586993d6fa2d16f1fb84d6e0a2f93cb5f660b8a0e783840bf59d640c8af0e3d4b399151af4a9a458ef005f6a0946f1d19674334b13857f418006a8a2d94546079365b884d58532ad6e3c8eb9ee6ea15bd1e55ee4e9d8d017e655ace0c47f8b2b4a39baa68cbc228955491a8b73a00886e75fdae9af74c228a86d0fab18bd81d97f36bc62223ef1724cdb7c6ab9b109c0c8185991a66015832f590e80e4be532a1de508be29240c2acfd5ea905", "", 0, 1995900764, 0, "9721fb036a89abab2c9c4a1fd3d7df6af8a834cf1d712fcff97d84aae934009b"], + ["7955cb0002ded4d1fe9ff66bf872c7549d1291f8d6a074f7cfd8edf335a9903036394d27d802000000056a53ac5265873fec7058f64e437f0ea9448066b42015202a1d56d1cb424a55461e80c5f948c4e7bc870200000002ac53c8fd6a58046ced4a010000000008516363acac6a006512eb1e0000000000005ef1a302000000000952ac5365000051ac00fd0a750400000000050063acac530000000000", "6a", 1, -1208408977, 0, "00c4e3d7fcb8def9ad41aba6a934e3e100c260136ccae8575ecf5c19442e6af7"] ] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index ebd1f0403..b99a72da9 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -86,12 +86,43 @@ [[["b3da01dd4aae683c7aee4d5d8b52a540a508e1115f77cd7fa9a291243f501223", 0, "HASH160 0x14 0xb1ce99298d5f07364b57b1e5c9cc00be0b04a954 EQUAL"]], "01000000012312503f2491a2a97fcd775f11e108a540a5528b5d4dee7a3c68ae4add01dab300000000fdfe000048304502207aacee820e08b0b174e248abd8d7a34ed63b5da3abedb99934df9fddd65c05c4022100dfe87896ab5ee3df476c2655f9fbe5bd089dccbef3e4ea05b5d121169fe7f5f401483045022100f6649b0eddfdfd4ad55426663385090d51ee86c3481bdc6b0c18ea6c0ece2c0b0220561c315b07cffa6f7dd9df96dbae9200c2dee09bf93cc35ca05e6cdf613340aa014c695221031d11db38972b712a9fe1fc023577c7ae3ddb4a3004187d41c45121eecfdbb5b7210207ec36911b6ad2382860d32989c7b8728e9489d7bbc94a6b5509ef0029be128821024ea9fac06f666a4adc3fc1357b7bec1fd0bdece2b9d08579226a8ebde53058e453aeffffffff0180380100000000001976a914c9b99cddf847d10685a4fabaa0baf505f7c3dfab88ac00000000", "P2SH"], +["The following is 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], +["It is of particular interest because it contains an invalidly-encoded signature which OpenSSL accepts"], +["See http://r6.ca/blog/20111119T211504Z.html"], +["It is also the first OP_CHECKMULTISIG transaction on the Bitcoin block chain in standard form"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000490047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], + +["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], +["It is an OP_CHECKMULTISIG with an arbitrary extra byte stuffed into the signature at pos length - 2"], +["The dummy byte is fine however, so the NULLDUMMY flag should be happy"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], + +["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], +["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a01ff47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], + +["As above, but using a OP_1"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], + +["As above, but using a OP_1NEGATE"], +[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], +"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], ["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], ["It is an OP_CHECKMULTISIG with the dummy value missing"], [[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], "0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004847304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], +["The following is f7fdd091fa6d8f5e7a8c2458f5c38faffff2d3f1406b6e4fe2c99dcc0d2d1cbb"], +["It caught a bug in the workaround for 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 in an overly simple implementation"], +[[["b464e85df2a238416f8bdae11d120add610380ea07f4ef19c5f9dfd472f96c3d", 0, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"], +["b7978cc96e59a8b13e0865d3f95657561a7f725be952438637475920bac9eb21", 1, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"]], +"01000000023d6cf972d4dff9c519eff407ea800361dd0a121de1da8b6f4138a2f25de864b4000000008a4730440220ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e022049cffa1cdc102a0b56e0e04913606c70af702a1149dc3b305ab9439288fee090014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff21ebc9ba20594737864352e95b727f1a565756f9d365083eb1a8596ec98c97b7010000008a4730440220503ff10e9f1e0de731407a4a245531c9ff17676eda461f8ceeb8c06049fa2c810220c008ac34694510298fa60b3f000df01caa244f165b727d4896eb84f81e46bcc4014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff01f0da5200000000001976a914857ccd42dded6df32949d4646dfa10a92458cfaa88ac00000000", "P2SH"], + ["CHECKMULTISIG SCRIPT_VERIFY_NULLDUMMY tests:"], diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index e7f0464d8..265ba5de6 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -5,32 +5,6 @@ ["serializedTransaction, verifyFlags]"], ["Objects that are only a single string (like this one) are ignored"], -["The following is 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], -["It is of particular interest because it contains an invalidly-encoded signature which OpenSSL accepts"], -["See http://r6.ca/blog/20111119T211504Z.html"], -["It is also the first OP_CHECKMULTISIG transaction in standard form"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000490047304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], - -["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], -["It is an OP_CHECKMULTISIG with an arbitrary extra byte stuffed into the signature at pos length - 2"], -["The dummy byte is fine however, so the NULLDUMMY flag should be happy"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a0048304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2bab01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH,NULLDUMMY"], - -["The following is a tweaked form of 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63"], -["It is an OP_CHECKMULTISIG with the dummy value set to something other than an empty string"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba260000000004a01ff47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], - -["As above, but using a OP_1"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000495147304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], - -["As above, but using a OP_1NEGATE"], -[[["60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1", 0, "1 0x41 0x04cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4 0x41 0x0461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af 2 OP_CHECKMULTISIG"]], -"0100000001b14bdcbc3e01bdaad36cc08e81e69c82e1060bc14e518db2b49aa43ad90ba26000000000494f47304402203f16c6f40162ab686621ef3000b04e75418a0c0cb2d8aebeac894ae360ac1e780220ddc15ecdfc3507ac48e1681a33eb60996631bf6bf5bc0a0682c4db743ce7ca2b01ffffffff0140420f00000000001976a914660d4ef3a743e3e696ad990364e555c271ad504b88ac00000000", "P2SH"], - ["The following is c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73"], ["It is of interest because it contains a 0-sequence as well as a signature of SIGHASH type 0 (which is not a real type)"], [[["406b2b06bcd34d3c8733e6b79f7a394c8a431fbf4ff5ac705c93f4076bb77602", 0, "DUP HASH160 0x14 0xdc44b1164188067c3a32d4780f5996fa14a4f2d9 EQUALVERIFY CHECKSIG"]], @@ -40,12 +14,6 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"], -["The following is f7fdd091fa6d8f5e7a8c2458f5c38faffff2d3f1406b6e4fe2c99dcc0d2d1cbb"], -["It caught a bug in the workaround for 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 in an overly simple implementation"], -[[["b464e85df2a238416f8bdae11d120add610380ea07f4ef19c5f9dfd472f96c3d", 0, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"], -["b7978cc96e59a8b13e0865d3f95657561a7f725be952438637475920bac9eb21", 1, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"]], -"01000000023d6cf972d4dff9c519eff407ea800361dd0a121de1da8b6f4138a2f25de864b4000000008a4730440220ffda47bfc776bcd269da4832626ac332adfca6dd835e8ecd83cd1ebe7d709b0e022049cffa1cdc102a0b56e0e04913606c70af702a1149dc3b305ab9439288fee090014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff21ebc9ba20594737864352e95b727f1a565756f9d365083eb1a8596ec98c97b7010000008a4730440220503ff10e9f1e0de731407a4a245531c9ff17676eda461f8ceeb8c06049fa2c810220c008ac34694510298fa60b3f000df01caa244f165b727d4896eb84f81e46bcc4014104266abb36d66eb4218a6dd31f09bb92cf3cfa803c7ea72c1fc80a50f919273e613f895b855fb7465ccbc8919ad1bd4a306c783f22cd3227327694c4fa4c1c439affffffff01f0da5200000000001976a914857ccd42dded6df32949d4646dfa10a92458cfaa88ac00000000", "P2SH"], - ["An invalid P2SH Transaction"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "NONE"], diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 0996e13c4..325789572 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/upgrades.h" #include "main.h" #include "txmempool.h" #include "util.h" @@ -17,6 +18,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) { // Test CTxMemPool::remove functionality + TestMemPoolEntryHelper entry; // Parent transaction with three children, // and three grand-children: CMutableTransaction txParent; @@ -60,17 +62,17 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) BOOST_CHECK_EQUAL(removed.size(), 0); // Just the parent: - testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); testPool.remove(txParent, removed, true); BOOST_CHECK_EQUAL(removed.size(), 1); removed.clear(); // Parent, children, grandchildren: - testPool.addUnchecked(txParent.GetHash(), CTxMemPoolEntry(txParent, 0, 0, 0.0, 1)); + testPool.addUnchecked(txParent.GetHash(), entry.FromTx(txParent)); for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); - testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); + testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Remove Child[0], GrandChild[0] should be removed: testPool.remove(txChild[0], removed, true); @@ -90,8 +92,8 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) for (int i = 0; i < 3; i++) { - testPool.addUnchecked(txChild[i].GetHash(), CTxMemPoolEntry(txChild[i], 0, 0, 0.0, 1)); - testPool.addUnchecked(txGrandChild[i].GetHash(), CTxMemPoolEntry(txGrandChild[i], 0, 0, 0.0, 1)); + testPool.addUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i])); + testPool.addUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i])); } // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be // put into the mempool (maybe because it is non-standard): @@ -101,4 +103,113 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } +BOOST_AUTO_TEST_CASE(MempoolIndexingTest) +{ + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + entry.hadNoDependencies = true; + + /* 3rd highest fee */ + CMutableTransaction tx1 = CMutableTransaction(); + tx1.vout.resize(1); + tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx1.vout[0].nValue = 10 * COIN; + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); + + /* highest fee */ + CMutableTransaction tx2 = CMutableTransaction(); + tx2.vout.resize(1); + tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx2.vout[0].nValue = 2 * COIN; + pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); + + /* lowest fee */ + CMutableTransaction tx3 = CMutableTransaction(); + tx3.vout.resize(1); + tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx3.vout[0].nValue = 5 * COIN; + pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); + + /* 2nd highest fee */ + CMutableTransaction tx4 = CMutableTransaction(); + tx4.vout.resize(1); + tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx4.vout[0].nValue = 6 * COIN; + pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); + + /* equal fee rate to tx1, but newer */ + CMutableTransaction tx5 = CMutableTransaction(); + tx5.vout.resize(1); + tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx5.vout[0].nValue = 11 * COIN; + entry.nTime = 1; + entry.dPriority = 10.0; + pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); + BOOST_CHECK_EQUAL(pool.size(), 5); + + // Check the fee-rate index is in order, should be tx2, tx4, tx1, tx5, tx3 + CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin(); + BOOST_CHECK_EQUAL(it++->GetTx().GetHash().ToString(), tx2.GetHash().ToString()); + BOOST_CHECK_EQUAL(it++->GetTx().GetHash().ToString(), tx4.GetHash().ToString()); + BOOST_CHECK_EQUAL(it++->GetTx().GetHash().ToString(), tx1.GetHash().ToString()); + BOOST_CHECK_EQUAL(it++->GetTx().GetHash().ToString(), tx5.GetHash().ToString()); + BOOST_CHECK_EQUAL(it++->GetTx().GetHash().ToString(), tx3.GetHash().ToString()); + BOOST_CHECK(it == pool.mapTx.get<1>().end()); +} + +BOOST_AUTO_TEST_CASE(RemoveWithoutBranchId) { + CTxMemPool pool(CFeeRate(0)); + TestMemPoolEntryHelper entry; + entry.nFee = 10000LL; + entry.hadNoDependencies = true; + + // Add some Sprout transactions + for (auto i = 1; i < 11; i++) { + CMutableTransaction tx = CMutableTransaction(); + tx.vout.resize(1); + tx.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx.vout[0].nValue = i * COIN; + pool.addUnchecked(tx.GetHash(), entry.BranchId(NetworkUpgradeInfo[Consensus::BASE_SPROUT].nBranchId).FromTx(tx)); + } + BOOST_CHECK_EQUAL(pool.size(), 10); + + // Check the pool only contains Sprout transactions + for (CTxMemPool::indexed_transaction_set::const_iterator it = pool.mapTx.begin(); it != pool.mapTx.end(); it++) { + BOOST_CHECK_EQUAL(it->GetValidatedBranchId(), NetworkUpgradeInfo[Consensus::BASE_SPROUT].nBranchId); + } + + // Add some dummy transactions + for (auto i = 1; i < 11; i++) { + CMutableTransaction tx = CMutableTransaction(); + tx.vout.resize(1); + tx.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx.vout[0].nValue = i * COIN + 100; + pool.addUnchecked(tx.GetHash(), entry.BranchId(NetworkUpgradeInfo[Consensus::UPGRADE_TESTDUMMY].nBranchId).FromTx(tx)); + } + BOOST_CHECK_EQUAL(pool.size(), 20); + + // Add some Overwinter transactions + for (auto i = 1; i < 11; i++) { + CMutableTransaction tx = CMutableTransaction(); + tx.vout.resize(1); + tx.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; + tx.vout[0].nValue = i * COIN + 200; + pool.addUnchecked(tx.GetHash(), entry.BranchId(NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId).FromTx(tx)); + } + BOOST_CHECK_EQUAL(pool.size(), 30); + + // Remove transactions that are not for Overwinter + pool.removeWithoutBranchId(NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId); + BOOST_CHECK_EQUAL(pool.size(), 10); + + // Check the pool only contains Overwinter transactions + for (CTxMemPool::indexed_transaction_set::const_iterator it = pool.mapTx.begin(); it != pool.mapTx.end(); it++) { + BOOST_CHECK_EQUAL(it->GetValidatedBranchId(), NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId); + } + + // Roll back to Sprout + pool.removeWithoutBranchId(NetworkUpgradeInfo[Consensus::BASE_SPROUT].nBranchId); + BOOST_CHECK_EQUAL(pool.size(), 0); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 4a960df76..9b8674f04 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -23,119 +23,118 @@ struct { const char *nonce_hex; const char *solution_hex; } blockinfo[] = { - {"0000000000000000000000000000000000000000000000000000000000000017", "004e2b5a2020abd95263f39c4d65c1d9112073ccf30a7df5428e5e8a7bbffdb556d6d4fb1978eeae589e10a155f665fbc57bf3b4d1a10ca38b9d4f9ab6d5931524deacd7cf9b774fdf72eb87425950bde392c8cf0c8447c08156f8679702a1a3866b7e4d13601ca5761003db87feea6febda45c5a3b76e5a0992b91182c30eef5a91516c57b3cf8102af61e893561c0e3f6d48582b8beea1de094b33ac87c8725c2386a2eebf434d01d46cfa27ca3ca54a84e0b4853a49ef2862bcb18933a9a41efe8f1081c57fc661db7dbe56c2e7f85af813b0dca2e0e233d1a1cfd65a013de09e12d4bdcf89210246d735486ffab49b468606e091e5e2ba55617602400a7cb91de9e3a217252aec3c6d861f75f8e0611ece2c4efbb174558be083cbe752e2bef323bb6a74179fe2d11eb15627b53321f73ac7684b591f3afb8819767f67e406d78eced8840c19ef57fd38e06bcde60152101804a71d0374a9f34f1fcb9db6f9b9f8ed7418bc8c363348390d246253275fccb27e872e351eab0f7b02899043fd0b4c9ae22f6c95ac52a91fdd185f41852d34be23f14be1de966838724956d436d8c9881199ced14c5fa8511975a65e02c358522cedb334fa2d15e47bebaf62b1be11c3b84265db3a36553a59eb14c24fff633573adb1afe53a2ec158eadfb27b82fe24df22b2229a2188f3d8044c6746a20a2c13b7f53c09ea775af45be369d209a3470644b765644131432427502d6e585269055c48136166bac32e46c2d559a80e91e1348731e7279cd6fa21d1ebc1ff5f451cb8a1134847da0450d1bdf534e3e914acfdfe8f0a1c39fb14b55f027aed21a7d7656305eea2e6a9cdacba0c612b0c0c43c0d1a16eb9fb4a81246a5e3337e5f9c6581d29e3566b20658f843fc43d09e71a220bd5bb75353b2dfcb708340de9a1da1580807c2a5987b8d19870004f355b95832071b52c72747a6a9f58ac41997e5a0ef9509e592229d315de45fb62d7d649eb6ad432f60f5f75a8e1045dfe69517159d6e850c9a3c15d7ac61b77467f04ca7091a99b46313dd5a639b4a77e3fd80a25308062d56ee0eb1eb44f784a316d66297be48b26e8d24e0b4fc88ff99407803d3cecafaed8ffaee81e19dc76f06eae5b790712cf14b3b534b8743d5cf93dd4e2a8111e24f17d2275973544608e88237d2fce06d62ad6f64649dc3e2ac3999a27b7bd0dff90aca9119a00aabb6ac8f1b6d9f43e63e1c0222d0e3b219d244551eb4e5c068b416d859f83d431066423b807ee3e2d5b80cee773a1991854c56ed703016f4febabd2159483ae1962fe5be771fa067ae8b95f4ad89f93141c7609fd8b9cf6b98c606222921eb9ecfdcdb06afa1cc2647e4d22d7411e4079904dd2fbd314f45abcf31e0707a6a85fd631b41fc3432be18c7b5b9b3b0cbb014de9b53643f6bc629ec0dcc82404247712fc62820618a6eb8d86f36893d7e199b678d2b22d8378246008402c962f9cef67db64c32d4231ec9553a7500fc410486ade3d8c506dc517b29972ae9e7528620bf4cc075902dee7ce6439d85a610d1badc39d7e4e118f22166eae2c0f492606f53e019c754df61e0069fcb13316b3bfd82e946497e97713fed435bba57a8f75b66419b32a435b24c907289bc1c6d527821ac4e4bf3eef04e9564b9328b82fd179c29cdfa6801a45a5d540900b894400c88c3790cb3260c59f878611d2881f60e00a3c0ee7ded90f971309c207caf1b8012d7872dd891e153f5cac1643bd54e51436c12607ba22d13e55c9081f2204bc07c996485dcacc41d794df509afdc0c00b4cf79d4e890dd4fdb9c19b2e1373f25b88d9fe5727afc6bc1ce57e2156e8f3c637d2cbb1826670252942df0be221d7495759ef659892bdc75f47c63cace6"}, - {"000000000000000000000000000000000000000000000000000000000000000e", "0067af1274820bfb2e16e1fca76120ea823e5e13b2229815a4cadd5a3f69a062dbaace24d646e73c6742151c1cab9a6e78db9bb8e59d497718be11c5d61c2f160b9d9ee28a907301f977efb9f9efda96e6ff75dd071421260fb945c3d2c5dcbb31f476ab4fd97ab81a1491c78dd2c76954e5a4d426edb110d1ec92bce38611dcc17d8a5435a6aaef673acb3e026215d07be0f0165884185c21819fab0e23d4051eabd209c7f11f040618ba8e4e91f3e9493fe2079d23030dacf9b415552732071db823633f53dec479315eacde8c94b7bb9928645146469b0d6fc0697324633c512e7d8d1c2c392ba9bfdf1fd687fce7a3764a45d79e22787ffb4a3c0a21448ba26ba2a1c3c5c27defd44dca084eba029b140e58ea37a88b2b50ff2a1a1162ab429d891d4c462f5ab9fc615ce14544fd34ebe0fcf8f145ad1200ca3f90d3cd9f2a90f178ee44e52a4ba2b1e6293933f303a3a54f7d586ce3a2263540a7caa5a5d1823035821ebecab9d531c019b29c5387b0e674362c4b75c06913771d4495da11d4db2bb2a001c97c3274f6b6c5f451378aab7462d0891c337a38756f092b127f1cc11503ce8ee245071052c779e17344fba8e72e8f3b1a4b2e6cfd9d104f4147aab9b397de2688f350fcbf568b0ace4c8abf45fc50eb07e87953c44bf6dd5f1775281f353bbac14adf29d3b772568f43b6b9b9b59c35d505bb02ebb455043f0b9070db025ddf02b74e9d23441eb0cc90f4cbdeab6e390a4530e99baabfaa9d84c716803e6239fa0663d47ef5ed5f338b3baf247dc78322d7cab715d3bd18c3fd7539d366ab8d691e1db73e1140ed5ddc0db729186ea24062e8fe31d2eadd2ac01fc737e476c95b6f1f7604daacb993c596c5fda7bc1740d66bd779115beceea175136a5bcdab3b5543884757247725167095ec41f7272dda8dd65e9e787ff300aeb008354a18e293f700985ef36bd19b0cbbc0444115bc05a11be26fefd2448741eb80a9291bd293c817854b84061ae038ec5ef393d37b950d5aa517f2ce2586dc265312de4974235466112ada1572962f3d821fa29e4ffe76c1b5c44084e76ec597e1e518f6ddaa245a4b25bb8bf5d10d206257f64c5844e2d6dfd1703a034424e56b78b987f594bcbd292fbef73c1db13c5d24134fbb306053b2ef07ce5256520292f47514d701a312da0c664097cbd2f1741aa7999583dc585654045d354d615b7a13ccfbb57cf95ba7ba5f219587100a602b30894cbc4ae7dd464496b3f3ea7675d59f072611d3d6af91d655fc7d2635e4771689e06098d5660293e6905316dd9ff91c103157d9879c1ef7e879fd066f011782655de589c4a119ed1197e2313cb5ea640878f0bf2564ef47ee57391d0ff83826848f5b59201ef99f409b9c98b521015682e9fef849b6701164a6031ca11109954dc9f7493266dcd8d635f7b331a7399f3427a84cb4a2bbdc0d09fae852ee167f96ddc2a430214ec29025c14f31b7c350b734959b00f03ae4013e230e5fab29d283f9af487ecc6016a6978f3c49b803fbb795646d79e7d6a4b22c7cacafcdd59d15943f0cc589f193455e5e9bfbd7ab2aec97ea7c19bbab6b0ae0c9b7fc23bc0f2e05b1f9acd991962580d728202eeca5aa104fc80be8fd886c43e1a7476c565b82b1050d75cb5147a7c65d6f12a860bf938daae6b6d13e23e717fc291b34f4e0fb58f42f6fb9030d637d89a507a871f03ea86881d6e04493d9c6c3759bb6f75481153472086f5e93e3867255f5e64c42f3488d1c50f5169767f29893576dfbf7f23767b6abe54fa48cc6cd1de60bb07e12824578a872c2a7538ee0b45f4fa36f397c0bf8bc2df303d76604e0f4ba56d3844a9eff9b4b079e97a052d146c18b67aa0945626e44793d38bf"}, - {"0000000000000000000000000000000000000000000000000000000000000039", "012f3a69fbe4852dbd5eb7ba5e6a284a651174d15e0806c99e6517e048ef61516e0774b4353c1a36693602d5be8037d079e5d425b1c61023cc3963b578da010706fce809dbd9ad849872bf65e0da167bccfea7b50ec5222cfe20b355b05751b1742c06b9e7f7afd519328aa9d494d80c2f5503a4af3d732c11db83b6e4bd47f45d303156e81ad54fd78648c889d6335c1a523b51363faeae6743d97ced65dd1ec4f0ee16e672ff6b02ebfc4336596e4cd03ba72775528919f41ad8d5cb0752e53b5e8c516cae6ef3d588cce01501464e0529569403c0da35e4cdbfe0662948b5963e036a9951d373faacb8872062b97ea8685bdb6786ef17039a0f280581ca5d84817511a54d56680957429aa8adf955aa56a1569bf06704a544c95742847e2835f7cd3a692628ea73366d9a11770ece790781d5db16cea29a988235807fe841a94e8bf8cc6405f5c454ca28b21b17350329c74c772048fb9026e5f7cd45051dd1bbde75ab0c98f11dc116683f00883a0f3d59a7d6fde0186cb623901f1fba687819e980e63f0cfb9801d2e7bd80de30e25d87605812a6cebc8474a17fe9ca41947515b106165bf6e95b322ffebb44cc944abe21f52b949b341b627f6a2d5588a9dd7492e8f3ccdf8142892f23171d4fb36aeb4935bb1eda3726ea753d7bee277fb7d961ddf71a91aa3b71f1e7e694cbc82ba9cb7b3e423a04bf0360dc32dd91f8af30ba61436071410e1df9ab0824fc93648bf223e223025a5cc724d95d166cd14b0538664e4b1950975dfa2132dc8b6e88cc1e094fac05675d166d9eaa8bc81d527bf135d32d6af4dc36410948acd47e14e8318804b29be99e49621779d557601571fc257f2622395ea152bcd361ba60eed8ae4e050bbd6a57371f8591eca6b2f46ba2ac7519d1d7eb1513d68d2f7c3305ada496e1e95b1a346b75fe1ff5180144dc03da8efcfd8b0ba48aa0504257580ebaf09b03c4dfdf29d17674cef1844249d13e05583d31260f05dfa686b484b69e87b851d77cf39761eab21bd9931a4a342da51369f5362a98f24849d4aac8e5ba4f24035ebec9c9a860c156b4d4c37ddfb23e9779d6ab273c6c5dbf15d500f944f669f45a6d7fdaa28cbaee121a8a7a06418e41eb66f2a63e10d16971a7b9f8b9b2218c4c0951758e0dcc46821e3819493a2b31b576a501ccb670d59204a950a551519792f610d5dcbbc22f193d7d9537b300fbafb3d5f2d2618e71e3fbd05d480288741be713054fe621530f722dd1f24c409566ff1ae0894bd05f4260fb29c2e176f6009122151fd4bd093f27b0ff20b6dd594c919f791c69ca5813b5f45c20b1c96dcc4be72723cec5a4d148e155c1045b4ce3177f894ba4072083c46411c41d46950ee9167ce6eb3464bf75bccfa90cdc1b5352925906aea5a29bb3070291b2d89561869db3bb01847737f14dcc21f22285419e4f61e01636cf5513850384488ecf27fbbe099b107617064e18447fdc15554b2c54ea8e96745501892a51b67c6cd95f7ddad5e8788df84eba9cd75e890f05c995cf62c46be46bee730c6ea3aac2e6d0bed9bf2408afe5ceca4e0e752264dd73e69672ad3cff6f030702067cfae0a437ca33e1499ab7131d505dec46741553b0cd3fc9ac365c5f6802db4f8862f5f4797282030d565bc66ca0a790c363ad9d6b47816e780e32d317aa82ee1e530c730e3bc59cc274dc7199476ccff72a8efb574fe5ea6bf9bcf46d17d529eb3988dc72934d721b7de7e05765cfe787242fd0e80746551f6c640ee6dc640d4d14da99f5a6ec655b004e60c69b7744303d04b7d8e3ea5bf4526872964d635304379a0e7d221f7b7721fddd45f92af259cab3a81287a2dc0530287d22b30492b2bb1d354481b2323c4ed5dfbbf0b5"}, - {"0000000000000000000000000000000000000000000000000000000000000005", "00315eb8fc4d578682ddf164933903e8ddba1ca90322f7a5d326700311f9dc82d0acd6b214c8d6ebdc6807f40d5b4943e079dea1739d4aabf5e6cd061727da14c0dfcda695819b360111fb9d6649926fc653d7ee1e1e1c6522deb1ed48e6f46f127e7081ce2a328291292b9d3162afb53180ca2706676972ce4439fcf0ac2634c9a337ad5395e1c9f3e1832edb5535b893ad98334e2fb747ce0e439187a77b674c0f4bb95cfdf1b400390cba29d24092bad472149569b0888547bfb7593e2506eeba9397d8babd07fa834c99fba158ffe4220307dc03d0c6e02bcd2b324cf11981128165f61a9d0b137a2edf698e1f6f84b2a8823baa6ece225b9f2d0188ad9873957daaea3101b883c812c999b7d9fd5c2316155a939fed619c25f32702bf29f5cf103e069635ec139b6ab83ecffb0d93d4f4a6fb6f1eb9df5e62588acff2a3b158fd9a7a477a6cfc63663c8ef70cda017eee67e9434db76ae712ca26a08a69217c09540d6f485c7fafa2da0fc7d317567fdb53e62667fd02561714299d93deef21413ef58e2a376a39ba94b0765b352dc1d46bda765d6bead72426ea0eb3c482ff716615a23186f6ccd37f798961c70f5bd741c715bd6ffb24a0c60a291f2491db12a7085653f836d791ff9c572261a51f68583068de670647be384a01927d5a555236d07eec65537659b17eb4518bca4f6220aff84eca06956084a1499bc94b6d31978772fcca4c663b844d254ed3bae09b900dd61e95d12d5eee366c3b5b237a0d6e40a7c115ed8beccde270bfad2ee5a61079b36937994f5288235b2d2b01062eec454769b92dbffc4f12cda572da6f4f0fd9c182f49ebecfb284503a46a726d67c340a6bc5298e2435b2a7f1b0e6033e7df2c118081b45b5cd517706c3f1e83a7066b54b003b5a1c23a6df4ef1a0aa55d3eb826b1e2dd6a2ea8ef964e800fbfecf1ed41fb585ebf97041ed193a9f5e5f55e81593c77563df944f42ae427466739df93fc4ae1a9d1458978461a4220d39d0b2d11d2d7bed2b359a2adc1514c5cf4c559135265473030c4db84f3322bb066f05b2a04d2a10ac0183a634739d420cc54acaf6cf4c0872dd96258307c4b32592e50fa8184a2626d19b0a0b02447d55d9797fe7f6825ef7dfd05938081022582eb33eb77c270241b97a157f1af8db01b7d358687f0229128be307ab1dc21493f4c27817795f71f18f643cc75e7d5451efb96b9a264906c7210337195a226110b078b8a1c7d4885fd35a0f3a7a44f2eaed3eebd434a2dffb1d11e43d2a9d779b106093a62ad8b5043706d8c08b3c4d5c21c37c32b5c6c7bb7cb075d9452c2ad23feeebd5bf1d3a8db6b8a46a9175f95658dde11b5d7d6d8c14a09f097be7bb54f8102b21a25924ee8982bd9044b7773fd18bb89e39775952b8b239e26001216a4333b1389de3cce0eef196175e1783d1c327125ec521510af88d21ed015ee8509a4dfd7d50e0601de3b1fbe1c797bb4ae162ad1ccc0f8ea1d9fcca9e2c1cd641554c7f417929175036498a1f712afbfb44053768d6dfea7367eb267400c0ebf58d121196ffe4272e0b0ce78d4201488ed6c962e1a8f667c2f76655056511b13a55a6bf63433119e57e6e61f60b9a43bd0d7cdc4ffc4cb8f59e6da62abc423d46c2457fc40f0156efd3cbc7d68ff5da24aafa49b709cbf3198d894483f22c041998015dc26797d0d0b0fa1828f88918066f0c581508e50d8b9c71d8332f061ce6037ea1e52950ae8212a563f9bbb148869a7a3f1287a958f4a209be299d475f9de3b1811784c7cf7b6ed7e33cc2d90c7dff20fa8d9a70da2089666b50667370bddec0d726897e1b99dc54f0f0fe2a84b1faccaeb40c1d6481380235f33f97bf21c3975556546f73c1f17e74476a"}, - {"0000000000000000000000000000000000000000000000000000000000000009", "007636b7d700cf6c94c7e31e417aef2d13444ccfb5012d9514e00a02dadec5c10ef2464f50adadaeffbf02c5b1621befff41b3eff8c38dee732ed868f958bd1e60366da214b0a3ce14b287a6f772c2c644b9b71406e74f2e43435c79f25fd145820f861ced6d93d74b1007e51c85458d8b3a23a170ab1c13512da397fb320bf9ee07fc243d37e30f26b0e4e79722a4509fe2bb18c586e495c8fdb9756fc1faa8c1de16a6dcf99a020a426cf96449f67fa265a1fa2b7bd8f559d5d7f29e307cf58129672001a3caf711123e07c65eb17d63e01410742cd29b807ee3b0458370b9945e82d27d70f019c3c580b0ee1ae79231a4755ad1e0b581ac33142d0d5204876de25717eb8401e545ed00ccace65cdb2a6dae05dc10a1cdf1142b075e36501d3fae3fbfe9b20e43992e0ed01789f998748f0db7336ebe705e23292a42ee01aad64a4f285b9ca21cf2e83f30e179bc1802ab3ad655bd0d2feba902831ddf3c451f4fbec28c1759b79a7ed6dd4ec8d9b638f0d11911e8049cbe841094e20a1595660f2d3a814f48226b0ebd4f7a8bc2406955574fa1a0d78428a9877cd10d82717a7beb0d05e4d3180f975f4bde54813ae42864a56c8f9632520a4452f91c5e80a7674e92352b2f0b4572d67c23841a8a9a35e5a28faf50f242d4d8bc4c85ef0856d2049b5f0d21aef8b31befcf49ddfc7e1836bf14bdfb500d21e9b88090fe0738cd51e8c1e46aec8f5706b24c196693a1e220f4cf27b3b4f648714796b1c0b66faf4ef3764fa913ffeebd4856f1f4716f4e9cac598f2460a86311ca633d197c56573c2a3d9873056cb8afe42a1cfd7772f108e5f46962d9b872a310cf7c9669d32e19ddb88c5a897de73bb8042d5990aa74667726c337b1f9d8a2b0a7f9ae2f983d405535567b68b9524c427b1ecf61148c52ad1a24c9c53484a240321a655a00c4adcffcd19edb6d470616804932c7d46f5ec0b41e6f4473d0626c87c360d284f6e19ed4b73ebbe7030a9a44c4d7dbfbd7fc6c2267a72f2b3997ff5f965f1636df70e550dca9f602625b9e9c5f50aa557e7b4c015acf3c6501b3a3fe33a2d964695e552a1c39781409a52b184bea227bb9c4c1431a784b14c530565339082a96edf349a5133513c514c867400dd46a71937209ca9cdd704d7315432ff55157b808031d3cbc717203a0045d07cd1d91f9d1a2f3914d00f6309cd8394a0b4ac3b1fa8e7052f8207221a1f6c2d0cacadb6f741263676e1a06ef96caa1d2ce7c51c4f5aeb1d4e78835f6c59eaa9ade353e14056a6733db224476956caa0cb44401d7c47a1062682b32ba5f8af75e12db2a091da681b6f9a4b7797e20d29cb1f4e43167ccfe21e61868251adce8cea7db96e2a9ec28a7a4beefc74d6232096f93ef60a39d1e5723f512d0edd6ad233c11a0030766fdd0e14079d65201ae922bb1e4d8d116a2458d12f73288b2068baf792b8ed9f5adcf214a9be69b152308aca00f0c5d2555a4b27e48aab1b09d3118db3be2cc322c5d1a630e3f742b6edff4fd91def6798111f4c322d395d12dbbbf7854b7f2d1ce17e83498321534e503b89bd009c5ccb89b865ec91b5b913c040a3a0afb5788f603e1fe95469b1adea2d9e4529e1eba561d4424be7cc3f5f14cf89ca24e97bf56dbdda8e503e23e217e5869a58b78e9190a7eceafac2f5ddf910fcc8ca9cfce3bdf35f3c5e8785ebece6fddf4401c197f092b8c1688d734b5641451fac9e9d50df441172fcb5ed111d561c3387826aaa6bb84f1f43cdbebb7071ef3c4cad2d9b9c68985b712e45ab99879f199681001b594eb875b5be6d42662aa72def9cc973d40e70999f0e694d39b5b94eec596e1d2169b15177b6c7b0cf091e32de60059b1dad6a613d87689deb45f5704"}, - {"0000000000000000000000000000000000000000000000000000000000000020", "0048c6dacd48a4d9091658d30050325257e636f68003a573707c08ff046193a08a75d2fceda084f4a8830ee75c5bc3dc738d3d4ad175d90e2309a94e7748853ab4fca24ee3b047ba85a4b0782ebb71bc19f3827903c469f670101c8b084a105d04949d9a17a91286dd26841134d0e570a762ce32e5fbc4a636556dd43b102060aa00358c84996579746863d8de8bc7ca1ef1592dbd54e09b60335bc018740e89b36519f3f01dba4c063781f8f08a040d970da2128036ef11645b7343631be849cb6a28ef7b7e15d2343ef814a6b3f65b4bee1f7ce2de1ad82c62fd3f32fc11ac19ef14083e8ebc34958d26a23894c1e91939699e6f6c7eeb94f98ce5130c56b50c8f7119f17ad33e44bebf662c5f742fd72dbc7531214f28e5ae02a413afa4f3c190b97e52fe1f65f29738ea0fef8baa7586c2ea538198993c6cb43fd947f2429a61c3fa3fb7f20a60d4a2c9c7dd503202a972101d22294159b8c20e486d727a9e50bb401e0ae7bcd1a50846b09399817760befd91556fb971780c3a3a2ae7844660fc3c351a7644efde236d9cc6c30f21590cc10f9767a90183489f20d5ae34fafafc1f0541e4645b093ac9893dd061989cdc0e388993e1ff2de60387c324da8d9f2dd53c0062904e28bf92069e0920bad3bc928576c85aeab861e8ba7720cb99a10b456faea4135f677d1e61984a2affac0704e898403203d38ba5c0d10c1d1b8a03dafcd2cb4562da7a7f3c42e47ed5499699b13465c51c16b3ed7759d7dbe52413dd5160c0237b058b2061d1144fb96228d377faa91b2acf70cb5b1ddb4c68244cbf3e47be66677e79920a8a8719df35a3d7fadbb14398905d8c56c7d3b41260406572a8db08596a7b2794843eab71fdb21d485226eb2b213d17b75151ba6456eefa0989f67c99941d2eb18feec1f3c0b3d84fd4b78fcb86c1f536d4f207017e1a87f5f0c795a70293d42aad0dae13dc39947c12f49fd19ce045510358e6fa96d8f0d38c52bf324b01b51bba9c13e93f158f51c375ed57d146de2ec9f82df9fd7c4018931994be34b622eca4093533104f05045d154dc16be633729741a9c2bda0c5b3b372451a07cbe901f21838c6da14f1c88b5d04894959341f622cd253691b13ff457367c5a641bb363680e2d4a26940bd3214205a240b5f1094afe0f7d1ee23b8de70dd01d47b495c5259f18f47a8d1f46677bb33699a9d570c79a52076d20535b78b62cd00d1341337517ecfdc0b31870d0f8f080cc8a6839c4a305e85960ad0605c75763cbba12ca20de78fe814a8c495eafcc73c1c631171b3128b10ce5897dca1992a76cdb767eb7c718c16ff9c738ba9de77f86eb2593861e7255062730162172581795d8606f392fb127975a34c54babff21f774ee18aeb60a503e943301a3595e66b6e951dfb6bf0051d7cf5df66cc2d3c2a20cbedbe99c915e9790def60d6bc232de181bdda7b4766cfe9859ac8cc5728743447935479173b7f311154f4f13391e99d136d4cac53af5df0a0d50faeebfcd59228609a717aed6e5084167c2d5101d1a5414263da16ee6a9f4343f8da599c28775a70f40dace09b3cc523c866d85f83151d25bc2b6b9e135a6ac4a9fb18a34cbbfbe551f93cde4ceb30270ca676710b199f38e565ceb3f39affafdbedf6055cda63f1213f237a0757a9bdfbee861c6f56ea4b0c87546c0363109d7d7254369be4bf992ac02c19fd151107555a74e219b066236a58ca47d9cb13f9f3171b6c452fce518a05d1d2a371fffef2669aa21ce0b110cfad72764a13c4d78891f983d76b04c9c2ebdaa24bd2c2d71fa51bdf98a2f932dd56f8db62147d1d3f27312d9330f1ff25d9aa8632e4c72d2a3867b7232232a33d5ac45be18102756706446302ddee16791717"}, - {"000000000000000000000000000000000000000000000000000000000000001e", "00300031f011ff93ca7dd320f7c4aac5aa695186612c84a6bbe2a3a09557eaf59cde41841672d8fce0f0081d091bc5e9150bbcdd63ceae7c7b2a5828bb34072543866e4313e4ff4a1fb551574d401b030519157103d40974ed67696fa5bfb67e00fc7e15dcbe9eb41428ad2e80a5a1ed3f97ce93b8a3593dd95614d4a3e715de2dca770aee7e64ea9315d72c14e0ec924af9084e3cfad35f59d28f58e4971daf39d19e06943e08db018ea7681a18ef25c13c1284fda08f9e88fa1485820bfb5f0eac973d9ec050f29a57175a1654d6fcaeeb172f67a993887ec1f79653a8baab2bcad739b6f5652c15c4426e141138bca656c0baffeaddd00c9a0329042101432e1690f6e378313a6d922ea15a05afaa0b20ad295c3f33ec91a08483fc2fb10972376ebdaad705c574499b1384a940bc11709bf32993c7661fa36b09544336efd1db17603812415f6c6755b4cc754ad103c97186b533e459d6d8a26ccd7533c3554adce1a71805adf7d8bd09f1efae23057b5d4d3d84065049b3088e6db401cc4731e309b587f4723eb70058f950b51c10a6b69c521a5f162564b20339d2da84945bb08f12b07a62ff4a7653f677a38f0a58cd82811bf61d3d72fc052bc56b6a5f6d6a091feb6f56a65d14f6bfa324afc756c918417ac3eff47dd73c00a97b080e70ae513fadeb44a6572d8c12ca252ae0eb92ef01da8b7404860921980ae093820281a33dceabb91131d066851c56c62057716a0bb8f4f3fd55549a09e56d92d94807003f83676accf556e423252ff3a3c9458db9824f096a3b194c83320c61b860a65948ca1c9a9bc8ba310ab74a8865887c579808145d11584acd95689bd62720c69a1111d413ab6302325b6d1e66ad46e97de6d518c9e6baf8689dd9fc5232cf1cc63bc507a6350a7b28288fc177d7a80b0a63c68cd1df9a631d64da6917028743f628e1abfd3f84d2ad40f3ad912cc2ade127110904d17f19f6f5861bd3f836dbb0a50d9f10349806fa8c6666f464d9ad5aa367442ad0e51be5197af32d9f472b0d674093473e23d84b4858e6adc8973f5f21167f4085d02b84d4ecb3a479e9a43de9ea3c9aa321bdd533cd5fd0bbba2912cef534a0ee3ee6d20f372e9072a6e5a0bc2599313900e34a79ee95669e9d2e66164e1ab79e25ab1968d6cbbdbf5b56137d1675cc03393ac7f7489686b30a834378c2e54d879e59ec251e539ebed55cd1d55eea28f5485418e240aa5728720fdf19af79d01607bfd3668c003893b3172adf214f139b70cf5a094b14bbf0c1a847189dc4ef8d89baaf1178cedf29512ed0a69cc319301b1c56fe0b5daf521d798fc908cbfae19017f4be3eaf2f76cc3dbd653529a64df493cb0c55241502d8cb57489cfd7ae8738248dd0dd613e92233ab4504aacee0e63271fede7a4b0320d245159cdf795a9d736e4153ac01b578559331033dc56252f242e1f791a69f9c55cd7e2a4e718f7212cd57c098a8f929daeb82eaff54634936fa1009f82bfc7f75048fe7b3c792a38f90540555ba12f633c310703b955c5921711e0c54dc5dff0319a5d7f8db931cd867d471257e7bce94344bdb5e779595d4ed42f316974248298c9410bdeb38090d7e67a2931f59a1d92968115aefa041b1c6fb050bb5bf3bd5be555ecbb307c0276f97d8e349ba0cd559d86f02bd92106f592e26c643da125b09b56b79f672117e4a05b942304f970b05db9e17561328cd9f9204dcc76b58bbe26967b7251787b38b1272a993be33f8294bf30586185d95e90bc80a12c94ffb67330ec986a5532d8e680d5d0499265dbace7e1282cf5ab785f1e3b3cdde8df95e6c6f142ec6a0034fda19b67f029ad259375d6187ece3132bf754e603e58f59736c842f6423eca9160c3713ad"}, - {"0000000000000000000000000000000000000000000000000000000000000008", "009a41ce877363d1ee5860fa19102756c11b5f196013bad670a9eb746bf29b344ce7fff419621578a5451dc5c94ba25c01ef1ae46578a0d1796999538e97163e9867213ea0737f8f6c19f6a97803db632c1b842e0166b525d0d7b8a53cf4103c10241afb23d0fd6ebb903a57ed0eb76757f74d19fb9dec8dbabca25b3cbb08ad89dcd7578381af0bf257a91e8dc0fa086c166a2a2b74e8c1fae651e2324567acd5281643699b77da00b65ebff019c4114ba47485c56642b21cf2d49e7e1d7f5641d85e268540fd653f6144c16d881fdd62de0427b751be0e7d70c4f9928381183bde8e729ee331131b87503ae99e99d0c7f1da03e0e3a21e0b741c0704327247cf9292a76062909ca71c92489f59fc48df20273bc6188e691999a2c49c96e3f61dbf866e457408d6d85aea628a2d2efac549dd64925e8f43fd60216d6f067c60fce977fa5c06e7e5ea54bdd13072aec200f493b60dd753ef1fa61401b0fd60337b47fd9a19059bdf531485c7da59ce91a42fddf169224c2fb6310192e5a81ec76e8fff2091f4c0ef42b9a37a921a2e2db1841d32d82e0b06ce458d2f44bb9a47ae34f2be04427895b4c76da145f766d6a458f46706cd3faf4c35a31487184dcf736216538f0476bc29342c6c4ab90ac60b9314231241b630d3c3be3c6bdde93c993aaf2cbcdd117691fa9495dc64a2093f4116e5315d17fe063bc65787de0fb7822f7242a45b35963d865cb7b70e3b74df7d1fb6c7b1da9423d0a96ee3092fd8639b0725d31f11c4960f502c9617b0fe4c61bd093ed4fa232ce26a89e0490fda79040965726b42455772d1df0a3664c1db346dc3d60403eed047325dd70f324390165b4680be05fa23eab23563c43c456196ad109dee0eb7c9e5e550b4f7dcf1b26676c24184f69437efe96188ecb6d1a7e145edf657f916578e0eeffed9a03c01549bcc6c4d66e58b1c1039d78dad56b25e1c529602b5fe514a5a3ab1d4a835313cb6072a2e10b2c3680905c523d8573035255e9223564d0ddcf1dfdb5e071f89d27b2a8d626cbb0674437766eee9924daca532031220a2aecb3ba38d21e83950f77cf659b0dd794c222572eec38c6db5716d14f66ab4b04d7f22bf5cd605566be496830e7eac9331d33eee6c0d24c06d6c7315247673b055699cfb17a37951f23752c59a7e03fc01ad904a5d026fa5fba1d5c8dc505ed5e85ddd1e72403a8e3815e17e6b77d4757fb1b109f20bcdfdc98023bb6d00edecbefbb3b13341c9b464829a8474f1712ba1c5067d9e0643412222f251b994d528d5d2c755150c59087115928927c9324df8d16ddcde404fc7ff269ac7c2c6951986d27e83910ef26bf53597ba1c771f370b7cc65679e79ccdba86a2f701beef2b9b5ef12c490549361e44e1aa808304209eb49b50135b2a380211549cc346d434bd4693304b307749c3c216a130039d01a63d5314a7cee6803d1c90cff04ec71d00410ccc5584608f5488b393334961426969ec64df51b42391ae7c7673d517fb271983f272712a64d35c3e7805b23b1d4d54f4e5a2c4443f7bbec389bf55d77990116516af405cf5672cc2b236185858ad4f2b2eebe81661ae0b8d4dd3b36e3633b36f1da3a15f8cd7e3914df16cea6af9b567cf3e59e4eaf7998b43dc5d9a6203516cecd1d85a83e520f20c81c50aac9d437509fe0742296d0fe37d51ef0ca12c804ec522fdf4b896330d1b4448b303a2cf229b311503b796154aeb3b36f10de522113b0bf8b8935d63c097bc4c514f26eabd9506873508b38aa3fbee462457c3db94671a8b1b132b2752ab64615178049043e27a9d7992a57090ddc8ec0f4f44ab7e1165dd7827680d41583696f5259ab34a154374742a157bc5a74983e9f5a87b7d2dca0fa2fd"}, - {"0000000000000000000000000000000000000000000000000000000000000028", "0028ba8566cb549b6729ca31366c4e57ba4f5fc0c21b57a1b9aea04acf8f06a2b9cb1dcf8a2fbaff1f8113822bb582922595a891ca07e9fd0b47b93c1fd8b54894e5234e74db73a88ab67ed5e815034cb17dcf7c059fc192e4522097420c39f5ccea3f6aa56adda3f408516b43650f6e44a5fc839972b29225cfaa9f26e01ca87585cd9c0b80f601b463d0aeb1a310fc1986553820875eee1dc0dbd668542c5b34b7a62f9cf98727016c949faa1fbe29e739f785cecc811b09191dbbfa0dd4636ca74534bfc7ba46a154f43fe6e4bbda100303fb5614d5337099c2f8f39996e54cb1e9b8b0b5414bb532c075a334ada46dc72d06f961e2e2c297bdd30f822b2b1554b3fcd55bf18f182b01427e179638691cb60fd2ffebc5a3806d74dd8ffadfa180bdf8dfde358b5ba197e1b04b460644202f57df152cd4f29a036e6cf56841a43887624a6ccfc9e9c3374f04fddfd6007ec81ff216eb4f382d61d97c26a8888d9896ed8a45240f27a3e475a39234169ede4c894f0be7ded8a70093045062847e03bb167037c2952a425e113530643cb8d2bd2074ca61bdd6a47a9abd6c917ed90c2bde0e930ec53a15b2099e304101a6c2b64058cbd750be146989819fa7d4d3472536ecc04fed49bd21d9d4b118c75cde96d4ea5d3f3bd326a63620096bdc53305623437c2ca88c933481ebc64c0677f0af7afabdd6ab01711574dd67d369ddb531215dbe7194f0e29123023e5923b5ff597553f213249655654301a2a12ee3fa0b58f7ce668de8d3150340c9503e77f988ff9792f627889ea7d69fe7abb38f82a19f6a6ac1876c32b9380c205f16fb13809ac8a4d1afad5806a57d13792f3515e8996da36896a15937546a074f02829265963cdd1e30269306cda0f886a5c2686f6c4424cd4856a1281ea79d9e60b165e5949c42c31d2218199936f12f73011e46133f40b3b703b76210b8641d593c6cebbea31d3bf1a77130a841c162657386b3622960a25a02780bd9c9b12c389707c88d64cdf8e6cb222181b5403f17db4a78568eea5dd50e3409b12753817dcbcd8cde06aa2712f9cf813711e9418cc09dbc00d19893bbc008b0bbb2bfd01c070d35a58d524ecd5ec4d198a13609de852ab353023b768183e100b74585204230eb4742142b7db65ca69722ef9534be386795615d5ea2c2029d7a5902cccce78d16f097272052683ce85fd6f22108fd4015db5a9b293ad25b06c10200e4c5be233b05b6a11b29f1b55ba9fa633576c061260da81bdd2105d297c72f2d4c91a48945ba206270c3845b5cd76518208a4ecae4744bd5f45283194900351e5a8ba735418f3dfb9fad92dfde64d5c22eef5d897a00185f671d92c1e0cf6d369dadb676495ae5bf5368ed3bc250232137c3884b304a7104f426c9e68565e906f20d9209b67eff681971d9b89151e59e335cd1600810cb3f179c3f2f6a208ad71a9f94d74cd6b4c94d39b465b30d53662ee1d04d8b7cf87291881c0466244979112f1971cedd2e86d25b8441626623b2b9c94ef6ddab720f62111d110edb8b22b9b1905aac911ba3c41f3c3b17e97f0f791e72e5a769e4a12f79ab5187c63e9f2b11d9c3772657165f49a0f24b867998812d085734762fcf0e654ed2e0e0b4bb245dc838fe16e177beb91a0bbc8b92d3ccb79c850251c02277767879f0daa3b72d90723cc590893adb9cb4bce6bc692569682bce622170120d03490ab5991ea375917305023029d8d0f24aa13c83343091f996ac54ceed79f08ee7a5f9fccd128f0f8c6d77976fdd388172fcdc4bdcd30eac49b514230fe28613a4abb139e521bfe9094eabad3e0b8c1d2ab515360caae7c29573c9c0310096846999714f4e523e9acdafb1cda334088dbc6a6262c52af7e471"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "005e10e25ade6dbb9f4a30b487a53178fc6ad3efc50ee83d9b18885575e3ca08a76fd1688251a41a89db13ba975fc245f79b735a47e4f6ee7a667f077ed01356dd935cafb0dc59a47ba6220dd8e16314b21de9f70a70b933d285f510f16572d5973480d8e1e17ba27528bc450faa0babf4d54dc67c87cd6dbf5bc1dbaeb22012174efd65bd83dca2058214d80c89b3b91816f22ea9ea866852a8d6e5da2c597071bef370857d3d2500d26cd1be85c1e1131123c9c4dc89d6bdf95c8f2a32ffdd691a8eeffb56b164b1e14e9e89524f14dbde055bee5da08ee4415b5f04806cee677936c02d61a52a4454218e1add637c2ac329c6c475f90c6a6ffeb703c9553e6d475399f325a21735e6272556c898ddb413bd660f3250540d873b63be28dca85288581513db0b492f213945009fcdb61470e5f1f80595cc72c05924671468fb9b84f5d24cd4c4dfbd456a036a590cf102a90bcf202786bd9c30306d3a16179ddeddf126c42d353c774c2f53d587b8392c0b701fc71c98bfa3ea03387e75fbf02bf9b11e13cce27f33c7c436df092224812db4ce0cad13e2e8631c44b4b202b4607691c00df8f677a55e269b88c765520cfa148954bdb31c88109efb58c3d24b7336a415a7b8398675de8178017113375e3a5ab0f7cbfd5386d09dbf5f7dd3ffdf98481555cb3b939eb80b72a8f25cb37b5ab6220959f15102d86b551d41c8e7ebe6c15cbf2538169fcbdb38a8075e054618a9ae238ca5209bc64464b20fc4f6c8701524832894dc742fdab2838e276164a29b71764fbe445bf7ffe5ab3ef3ec77c7922cd6cdb22cc9f7a4610a782ad2b884d69ef9dd661d6f7a54bd8e800d55ad0d2bac272ae02489039ce29d00d852761586f23dae30d17c44fea793696d8fc4d969a9f485639bdfcb2d3dea7bc0d41481f556b8268f6ef2d785c671f0315300d9b52fc41df40b3412601268e553fd113629672d05b8d2b8c191f40cd4bab0f2f2f0e3d6a8b9d5872c12ca16849d5731a6cd097422163f40c92966ab29dd1358fb2bb8e555bde2dfb16c2eb4a5cee3281cc21509db52720f2f6a95fbb982c136a37ab1fd449356dc1eba6e18f434d529d68cf3549eebea629320b50f242fed338760913e2acf1c37252a7bc8c6a8903d31f134fb8a10ffe3cd77e8a6f3fc9f4793f5e3a439cd86063fc56e999d902d225e33bfd577cf5ef232de9916096379b0c2505ce0e129f09d6b512bc8b5bc7ff9d40c6e0f00f84766072159d59a5d3424ad846f79eb0a14087bf5dc54723ae7a5718f49c20df6baa296f0c312d92648d78805ed5f7e52b7bff3f0d7a767defcba21b65b5eeed6e321a320b98c1bea1ab26d111d9ee024d3d132899950f11f9d54d0a42a84b21db678c19c27ba84f8e259f31ce1a794689873c98dac7c6d716301e9e69ec5cec3293f9912e7017a33f0ca6d2a0d7a0e51fe159fcbeaaef1042110a2ea09812dca9f579d18046c36611390e5316f64a622eb72efc9db3fbb413fda829caa558a91b0f2472ba8bd7e66fdd6788bf10389cda3185bdfdb2bee717c4d9393053519fa476f2f5aac52f034e34fdcec84462c3e51a67af39580c511b29ad2b718bb8b00d2e48b5c3739f5501675b2311f9daaa2ff53f0cfad70b31c81f49e8daafd92f11502aba187d21f641f06d7355286543aae01ef156ffc111f630a88a3924b45c1d595273892663ce79e477c165746b511c744defc4e6319097af15d56d397700b37f85f627e55a196ebbd743474bedf86365457966002d45e9374ca10a67827a381dab09dada93c7743ab1569eb6bd71e27018d44f529d535f49be59fbf520808a835ac471344dd5ef919d96e5804cb6effdd7ef244214eacb89503830a4846b9f455e0b9caf55f1281"}, - {"0000000000000000000000000000000000000000000000000000000000000025", "0013d902acc168f4772161f59bc274ddde6637cc660929fd408d183bc3da498864e072507f1cbfbbf9750e95cffe1c5ac0dce7cf512f964e5a31b90c8f18631a62aefd22dd34a9c82564efd24020f1b02ebea60a1820266102912491304fa22f0a67dcde78bb5583512fe99c6cce6c0779796313dc4c663d3d402f95b3e8413cdab98ad7c4158bfec465783d7f31af2bb143af415c7e13a2d0c332f63955ad11e6616b93385d763f00660c8816af28d5bc0613faacc54bd33b3aba3129080ffb112c463a25d2c590c6c4e8f5e1d2fe3c0e0e08ce6bdedb250faf39a79418e3bbf73bc2081e579a52ee45823263d2cd55aefab4e156202eef22d7bc320843678d0b0eacc2fd5790a7ca25877c4e9fba592b09362bff07e5b6b5b258e3d054ac0031166c6a7ba40c19e24e08cf2f53d1eb469cf6564072e1c35d1fb71165ac2fa404a80f9ebd31a1455512acb403cf8dba0182239a24e79f87f4c8f19bf50dd2f2ee5c3d299a11f610b2f8e84021986ae172cb32fce67d90bb559a06643a5be82b4c25a799e797acedacadf07651c54112f25a5ab62e244ff33f556091dad5866f87540a7213455c5bacc7ca26c73d78f2e4d4427295d216ebd4344c05dd1f510e1fb17df5b5da507dd676a334a8c11cf02533360e01a519fa05a6f33a644e849d17e49a29c52b414b5e9b34f63723461d3e4a02e0811f67c706bf78e0f8cb8d0fb06f61809cdf706534287343cd0c9ed326fe98f1def93e2352b2ff19dda7abf29eb318dc36e5d45a6d9cf3e352c0b9965b28dc424ae32a40cefaa1ccdf1f95a90dd425c2e7ac2670931afb1308d3e4eb861754492dbfd554cb470d5e9ac5b9fabd0d18164ab45980037e64d15d03552224bb330be845139b4f49491becef03b9415388986d6893ae88b0e616a60f5a5da2a2e7c10276586d6199de9a521dddf700ba683addd758b312c2509d4ba13bd46581239d8a30ee11b271a64711c80ef97802ea946a693f16c3060ccb85270de6f043495f98d397df04163b095b830f2632d7cbb8d0d3fff4c39d46dcfe58d358e25f3bb4132b26d88a06c1b3e3d7a32550301d1390663f6c1823cd3d6735ceeb6ad9fff2dda1f35c011306508dc918fb6f7466e81e577610646f1b70eeb649d95f4cf52d99023dc0a73daf50f927b41860bf4e0335b6c776082c7b66bb091c7d37c718a277c60b667c61f6cf1423af2990c2d840bda5ace5448f5a93e97c19ff4fa2169e8f5e19c609384f47492554f10552cce5d78b9f3ea964e1e2591855ee1c252337d2fd4200339833c20c1e03bf1e852a2d1691c7cebc56ae0ed27d59591a1a824365dddf6f27fa76b22d6d15945d79581631a322e69c3ac4d80b80f624c262e9fdcfc4a1675832335cd2673a51a091c12e63691ee675517a574999abd6024e80a5d8024b328fc094e09956d629c6ad3eb9ea052c25b7ed4bd3047734426f954089a1145b38000b0f978e5d2d5ddf5ba28881460d4ef34cf7ccbc2c143941023e6d703263aa9395ee015e4c7dedb6f64d5a100239c6850ae62396b04504a9c82ca7144b796d891231ca1fbd4527fb6b93d48c8ff8bf0f1f869ebf6d115a5a192353fabacac0e3b01fcecf3f34c71fb8435527feb3171d5907775f05c2a3b1d6a2f8ef3893250d372abe33879bbc60c633fb443256d15bf38fc23220e687de154b51cfc161a21e0fe310c6a6d7bed1b20fd778c08b5436a7d538228a8bb1b07e792e94fb4d1ffe1fe8cfd3b90b82311473b4afdecd97e8fbbd230d71e9d8ce10303cddf461677fcde6456e2dbcf26d715c65f372e36d5997818a6661fff2baeb1bd949240de6d3dede0f661accdf84347a5b9541f2f3cfde8c48f56afea71665b6d5f284e4d46f5f6dbdfb77b1d3"}, - {"0000000000000000000000000000000000000000000000000000000000000029", "0068a20b33963dffe13d80a07426f85a5d17d7a4496bec63ea6f9ed6e7c97af76673f3f96b0c945f316e0d04b6e7d10c3c8cf1c406889fd3d7c5ba80d2833a2466bb8123d34ec98aa984f1405e35c5d9a67072fc0c216a4900d71f7fb676219a3dd75c7a95b6dc8c0619b66435790f52a5015a45810db8062d6167592aa70e17ef1cdf94d94b16740b7e627f7a9b10faff45781a9ced61145a6a0be486028ae67ca80ae10d57be61022467c6b294dcc16d5bc6fb94f2b11298ab57a25d236bd146b772d051d2c87488bedabd85a176b23b330b8016e1d5c9755fc6c00464307968c65ef8db40f029b9caffa4684b09bbbbf787e077f8bae7bd17a3f90f713cbd4bc432319484e45ea240986e5ad4dfbe51112decfbbad4f08cf3be954db87debf69a741bcfd912d9a420b5a0717bf92001755fa90c74743bf89ca21c03b7a23a5189efd7f839655bce8ec34f3bdf144702fa91b160d03eb53601b09d8b183d3936b08bf6c526388e8de6dda4011f2bc49fa2ee2c5e00affeffa30d9b9d3af49382593e2a221ded929b956914f30c491b94d18c32198da95716829159f7259a004f9e51890cd1b37cc74c5e9523fff33d4a344ac5c4f4df5f1e20568c82a818d953688df2698ac3c130d97c6be66a12fcf12f44133e436a04d13accebd314c2e3fb7d2c2531079d60eee28ff512360b0e6332c2c9a15acb4603afba102f5a96dff90335080d5702765e76ddfb7e0c936ba1b65e38b8f89a814170d7e3ed2a79ccbf2f0777f3de461a6cebe9c79477b2e1945de1e0fae9dd197a0515c89cbbe2fb6623b0fe2e30cec7427b595a061911fd8c291227b37b734b4e2e7915d451dfcfcd06a2d5f0a6d865ad634480f0415916e0caf1ac96580703f52dd58dbdf92e0144e1f15d4bba0670748cde2cf0b1d96a969f13ed0cd419ab3ba59dc0f2722ace03c66b9fb5ab7a0dd79c049eaa475e8d6d5d5374a352153e01e2a0cd0b65eb86c20abdd48aa4863cb2430a2db95bcbfd4c21f35941732a7803da2022be79f02e934f7ddbdeb153e75105c1eed8abca7cdb366c48126b692fe896f95369efc2a5cb7db161090c3e18a42e10a3f1f8501071d27e374f5ac2e6864dac184cf712f171251b2547175206e40270fa6ffd89509b39571bab0c9d1e61507f2b5422937469c4f6ba2bbf890206a021e8ef56874978b664c45c4b117df9b9ba042e271d89c07bccaf392f8826210a39c39191b191b2b60c295c29510511b0c5ff43446bf6f249618d9db7d23f29a3bdfe9b8809a76e25b6ce71473d7604b5f6490c7d5a5b01cc4e5b717f7143b7ac28060e4a55dadd0e0d2964961e5f1d5435a49b733b332da38657b9172209eed5968c2c3d5bc75794ef67f09752ac3ac10262b7abc2de18df4f5c94da8fbdf4dc86e97339306703f2a320be07c59d5aa5720afdef29748d4cbfaed71215be30228e0cc2c47347faf946626e85f1d548c6286c24e193948d1562fb22f731ffedd4ecadaab0b43de68c000b5c438b476ba61026336d66d68a96d685041729ca1a81f1fff140417374c48e7328b9fc8391126cae4d4f8c9131ce1c024dd420fd1d178790aa150461c7ea8c889f579c4263d5e634bf81ebae373abc10641b05d16c7175a43e4120bff13da579f1ccd1b60440af7d0304323ddea3c55f81bcfa72417955932441cc7c9324e01fa9e5c0e78a975f221361dfff4f9805541a09ace945e5e5ff32567bfbf11d23a2f726a112c35292e00e1412f52b815112484effcb683f6da20799dd30a882a119cddf76a6d971651a2d4571736c2c3bcf76a9d58bed2c91b35ea9a15d84eedcb117df0feb1887188f0c04ff25419ae0e7d688773807e4031985b91aef468c99c7d3488541c574ba9eb1f97669"}, - {"0000000000000000000000000000000000000000000000000000000000000016", "0114026523aa61cb9c0ef1a0283d6164f0dcca4a283176afb68ba6a141b900481fbf776b12fc4a597580199bc7a218260c8d5529e3fca9d226c2d915d7655931a3e2a579db07c9c44f048da0aabc4a0d94ba19a5038c45e13118f49f6b62a2715e322b62ac6016aab22c00abe42ecf22996db812e8ec471bd5c652fca5b50d631a05c64979689701d1a556f930393233ddc7180fd554b5d90f6f0d724262a232e9ca65892f0d5d1407513dd7e3e0248d5b53e5553fd1f38167e8fc8096132737810c0b491b56ea740fedb9cf762343fbfd4610e7013591c47ac033be434449ba1c0e4b9674ff0929856f9682228e212b4552ea9064a5fd26617b55b9131f8f2fb454119ba93fe3abeef5c1014b428d83113a9bb73d76e68735ab5884912bd8b5b25d04b90c9e1b4333cf038d9254db60634f89e599957c6131af553ff17dac66d3bd6977dab6a6b5785d15eabaf4156201fcdb6580d926afc1a740eace9712ddb08295c43804f9b92cea91b91782b62238306a784219e992361d1c19af3eed50622307029433c4dbf1e3cc775ee3502432fc5416f4bb7dffc1296875596c33921efd146f06da1a52c0d539ab6bdd0397e8772393665f5ed19c38a12a5fbfd92ac4ff83c415abc361669827d5b9ea23f2947ca55354910b173a5854e2c00ea6be1fd1eb36cf234a1194095368f2c65f555425776233dee2720226a90200c20086f0eb614251216ac482232d47c91c2cb9080fa80d337c55c1c8755f7e31c90e1c82f70585df997a0517088e2962c176e928163346921940085c89096490c21aa1a150b18846d3cc4cf0b1c51207efadcddd9f231158ec03afb038a40d0764bf87a22d23cbf69e17bc1dffd1e684c53a4635ddd9eef79e14bf596d4447fb0165ecb3da89bd15de9f9cbb6804152c3bc525687aa78e83c23d087a7f7277c6fb9fc202f8cb48748b649edbac4137591b71ec4ff19b66ee1ea3da469c4cc1a0fb15e59417eb2529b3b1d12dcc06987432501ab5e5288740857efbdca0a33f48d5c72591d2c069d2b0391f36c523b2e99ab981a0ce65651c528a56b8efe4d383cec2a9deded0a95378af3f334cf5a5018533e019de8f081994cf7a5eeeb67b07ea1e89dd1a509243c391ef942297d72ff6c8abfe24cd2f630ea9fc25e58d912ba57ff247c529a98c6eec0b05a9f55f308e6bb9b201616d786259e0b2207c422f11c9e529609f22d99ce131a174e842f580476df8750e4d9a4f6d8841fc4e36566f3abf804de2b993333a2cbb7a3731982b7cc27257974ee711bad08ad8d7a317014b8b5bc7b30ee1d5522606e41f14b694897f48455b8f5dfd9399aeb43228ee99e3501a45b2d6cae719cc36589835cab5c402e3cd14faabc113fc7881ef1f899ce27bda0da30084953778cf4005d302942cd403011755214d9ea2d63566c48ae88c529947f8fa1117933221ddde1f55f3bac2ad5a5b91c662dbdf715c50f40f8796e96bab6baad88fdc5e6b9a7fdf3f4a905b48831c969a985347eec5e81b57aca6ad4d5575ef0cb2f4390990b60bdb5b118ac8453575929bae935c10ac5f1448e72fb19bcad2160f6059cb8ad13d0c1d165acf666886e073241772025eb814e909b86fc04847a94ee8a02d171f89b9f5f9354970d1946d78bf01091d33cdf3b07269beedc24ee71e124cd15f95b86f274b4d8b37603527ac4582cf59b113f26d6eb7b8d9107c67e73404add904dcb17b8025c6854de454d2272dbd61e780161f870452f4d02bcd24e2c48e3750590d090c962cc601e912a8b27677d16b4982d1dd3a2510b38c8cf69c4111f2bf91bba16da580bb60d073c71497e2f872c816895cb204e429710322bce69ab4b621661b4e902cdfe3a58cd32eb3edfea5045a9c6da1"}, - {"000000000000000000000000000000000000000000000000000000000000000c", "00337a3fdc5a3149803651d9c42a1698ba6d4f7a04072f15964cc6b212950c0314744437666e4d9395f00bf8254ace4a78b96114818016ed92edb00538342a17985a2f946cc93fd3c0249b0940db31bf9575941f00af32c134cb8c331e81e3802fc5969188a19abc7c073fe4fa46c9f2cc61fe4280ca220f266aff36069c06ec91b8ba5403637b8a1088fd165055b71afe22180c3c94b8ad1ba1af7d2d51957bcc636a1ba6d23c3b01865e9cf99d0667c1390466d8577a218f074dce1038f3fa07d799eaf5cc5c2477c7c6c6997082de22b30f5bb8f3a787f66069ffa3adfb73b02a086c1f2e2e20c1a4d188a863218c47c41b875b8a0700c67e38b109ab4f55a5f77ab9ccdb629eb9ee123156acb0646d1791fa277e1276a324bc021f614b9f38e285b2020f0a5d873b30e95d0fd877a8ae21d57a6e56505b53bf169b4c3bce1a75fd4137b286f73004b256b1f5c98103a4da5a3a954a98f0983a0b5b76b9e2be4bdc658e068a4458abf513fbcd79e270bc9f1c076f421f716505cef53d4acae9652656211c90bcc64c79df5fe3270fa669bc150b6c72cb4b66100c3f079e7990d4b65113625e4d35e8ff2dda45430e0a6b8042915cfef34c324b0ba0e7ef7b13c11eb5d63de1868a2070b2758e1d654a3462b5b3d9bc294af6a8fc895ec3ac77f0252467cb0d1e20ba63b32bab286572a63ef8c8de977207d37acc4885b9df3246d3d1b962b43142d23b599a11901931d65d0a7d1757e6d3364c5626041d98d24311a86663b75b3321c43c98f1d0e56e0a42a69647713182730c32e497d597688ac9385af782da05fa5a930b565fab56876050b541057e7a5f9a868342956c4a49b48d1635681abff86965fb474bafa99fd9be768013f2b667b2d48ab2d713b337115dc9f9ecf5bd207717578d72e806d498b411328b91692faa51d2dc4bc80097a046f3c23035c03421e58f7933015dfb35fed70d3b93ec4b6a5ed1ab8db0fa70f51fbd87f9b601f80766d72f08942deddc91a9986068671fb0173dcc4b0869c36f5e35c9d3b9a4239a805a222d9506f107bc0853db9339a178b30cdb371bd3f1b6ddf2627e3aad3d70b2bd045bd9574eb1e976e055d26f7dafbd68cf1d07e1436d1bbe55d2bb99db226d628f62d25b5bce4031d2bb489392fcd9be0635d5eb9c2eb7a19ac58203959ba221c355661e1154f05d6ee5e284ff3a62f10a0e8d7edc44289ab8fb123bcbff5032d7971e45fe1310caf4060fe9b339e4d160735b6fa1030193829e23554f04bd9715affb87247c91b221330a4fb8842c077a228d8f673ccdbdc2e14578a5d7d0b8ad729e9437ccbbaa8cda168cf395e50e47b462f353dabbbfb108549dc3570ea22cfe4de47823785fc937d47fa07e2086b642e9c851f70fef42682398c5b59ca112dfaa0102f66272441186d863c386332a8554f6f2fa5d9a1174943bd51442355bfd64fde83a49d94c63d82e2a05f164c8a92923bbcc1ec1f7619ac50370043c837d17cc67a9eec9ae5e7aacbdf7ce73777f895f5f9c1407053ea7668329cada2e71cc6c4928851cc14e0ff50aa15e9cd049ebdb557ea1627cb75e008e65a7760114ac5623efcd1985b5e633d1fd2148f92cc0588eb8464b6465aa14b819e491c5f50f5ed3f20da434cb670580c610cb862997a9f8641f29c179723044fd68ef18d3ab8b86e06dc1f8ab31afaa6eca5ef271991ac313cc4d0fcff76e53d4dd91fe3ffe78e5139a3505cd276424e6b0da449d602975edbfb86e05f448fc6be60a2c563eaccb3657add250f09c91a7249c27571027643623b3eea4180573c5a91b09f360625bd37f672a1659e4a95792dfa5656dd28fe9a129a61bd032e8f1340096c0fa51833147efe9b7e5ea85baf8163d54eb"}, - {"000000000000000000000000000000000000000000000000000000000000000d", "003947af0bc096d6e35ae733fdd820b28490ba62340af649a5643c04afe2913532b2f44f05d4c7911f6708e1f2c35bd7f91775f40207bebeb5816db111e53e104423db231554177c13c15fd0e14d3ca6767372671870247e6b54750ea8d25605ae46b7b61791b187323ac0fe693897731f52aae6c0256e49127a15d8c66a31e7b7fa7f976542f38469e82d57af3a98d1579ba7708e1de6be39b153dfb207f6bf45c9c30827784425059cbf1bb1045fab7343032368e66cdd8d739a3262460f6ae1682038ef09c9c5067a6780eabd3fdfe48514e05319891fd28b3bf9e703d4d1c2fe4d733d99392a3b11c1b4160e0b786de3944f551bc16ad9f7cabf075653379e0d79650974b800aa77ac7f5fd2defbe314d5277b6e16114dec52233ea0cecd2a4e13188ee51fd0e72db2e1400f519615f6f0ebab257ebadcf62d5283fd92df3b2895e2233d69ed6c841fc3b87e483b01216ca64a01fddf3a1c321faeb37bddf163df5e731780a4dca6cdeef3a0af2714f1c4ae81ca4854299919b7b536b3e3de2b29f1856875d1a7328eb7d8edf221a92662c61c8bf3a1386303c898838e080e79c12e0368f8cf785277e127d5b3fb9a5c07c503d233e4712647222769d660bde38df2ed1849add989174f0d9d0865ed5c77d36eef2376a1546ad328399d1ad22b8913257cd4ad5d2df1b4c671c86849e921ecebb85e2b04c315d0bd90ed698bc1572fed7f376a4652bdfb910fbcbc463ea26ff1e31f8203cc51d0f11a611d32ed08351d058d8741fd431ff5ff7ae35f5db25239b1a8194fcf659951956d4b9d241cbdba5ad20d67bb429d0bf4535bafa32ce15c7082f503f7f439f63f3ce93c123db0eced1eba9b0f8635745b4f9c95a8eef1da420c215a1542edcba7b5ead5406fc574b15127d4d8921b75bd30b3a234c573d67d2c0c7a24af65355bb91f00a481520c082d20519d52bff49bb60dce421bdde01dcd73e1494f6520fcef32e879d4102957136de86607986f3f05de9a89e0a9e0c5b7e654c234571b03301a230f5e00ca9551bfd9f52412c19d79cc5679b982030cbf2c37aa60415fa35112eb5d83aa9081b6186e149734f86150b303bf94119c3cbe7ef49c92497599134d6f508d491c01448a34330dba5d7db14a7de07525a266d2f4eadb0bf848a32985aa7d39dc959f3029039a8ebe4f95158b136101e55ff31a99b71cd248ab100e8275dc1536e8bfdb0163e56ddb27007bd9ee86098388fa348ebcd79175f684c0dd7cc9b5fdf4da500a81b136e3506f5d9fcf60af1a78917e5871351d37106291b51724644ddb7ef5f97f596a399cceece73950e0eb3d802ac8f3f68996fa91efa1d71bd07910e81881194dbfc6c75363d8c4d0155f697a4074dfa0d91b82877e4b13d37f8dc212f04e4527d971b2d9e1db00dbfe5bec61d057ffd172943cb664ed66b7d0702f0478854b9b70b553f4c0631003711ba63fdff6de4a0c8514cd6bcd600285abb2d95852ae966a1957f66943e974dcba9351e2c4de65a20950da0a03effab0fc02b7b709b1029fb1d668d162fb8e1a9db662cf7b6c17d95a1a14e8e519aa18f31c31420da51398f4fbdf0382517a288428ee48db13c0672bf282316598ca690a5a8a14ff9f6baf4f2fb21931cf0971b2527f92180227dceeb5d06147f304f2c863a65e49290f375691416c74bcb7a8beed7a6185ea29b4cb22def31a3bfe0f30f48daaa309b33ac8638e0a6e338d950059acaa3866960abd61970be4661556c638780773085c0906037f9889cfbaf2a3ec9645531dfa190f1a75fa4a9020c8e793cbd2a5ad40e1ab0e65ffaaf357789d61800431b77d310cd9789f8060bec1bdac1afe3739c4223d5b5b053bea015b60689469d94f9fa6ff9c1b918e"}, - {"0000000000000000000000000000000000000000000000000000000000000010", "0024f30f6a25882567ee711f7639c9bc6a556d177a1a528b6c0e86bd427b80a263729ed7291d7249b76d0edd43152c09c41390c9832c6571078e091cf2dd4b3fb52edce3dd9a0151ab369c2afbb249f00a9ed6150607286179f01a9fcba290bb3f32efb86c5a5f1334192c6ba7bf5781d1ad3465062fee9f4996fd723cf90cba5bcad047c0d371bcf30bbc699f31e0b0bd59111e1c3455b0f8d26de541b3658d48fed905a4ccada90b55f6c14f1143999bded49c3264bbcdd7e2dc3222315cb2f99ea05a17c76d836b882d32f1f59dd132650e1c8a7ec8ce503bb361d3dc5ff56b54f76b0a347452de37a46e58220da9f21756a7c57b4a7ec874acdb0e162d36c12d876fe79355b265462f55a6c81124b5165763c81707784bbebbe29220db258a779e1dade11316518e06c984a57a1804332335f55b4bc9ff2ee52a6015f6cff20893e66775d00278253334513e42dc003a38698c130569423a654adbf2b1bb0222ba56960da25a2985d39928aa39211d2af53cb84db8f538080f325e300f48caa1c881c43a51bcfd1f99d39dc2ff3a0fcb594d64650d66ac042b5a23bfd2363312b3fd06a8e60e102e2947f56d11edf8a24e65dc0a53b81c50f224481bb4a60ddfcb2893b2e5a902f150188b6015512ed0e2295d77811a17393bf083a2383f1efa7717fd537b1e86d6cc5ea9a28aad41b3c5322995563f0469678d7e9dc21b2d61f18d9de70445163e7497d22b67317bf8958dfb2eb58704ced631a25f6dbc6f1e0efcab9b6f968b87448d470e8e735e3b54ac1b515c56a4a3c5b3ddd3556b30b61b0f4c763ab9e19d87b4061d80601db0ec879e541dab3dfb8827a0b4be41e7227c6795ee8ded595ec096aff2f043bf7ba73ec12807e8d4ac10dad3e36d72c3efd979bd5d4a0eda0bfc095f4ea2b6cebdcece3486c4cafa47ae111c36efa300461bc89a2fb163d1bd60a48b48c948449106be8563f7bd9941dbbbc4ff97b85e8b67a96390761d584522e7e93b7e0ed5374bf856744165f059f71cdcc7662380215bc52e196786e52244c92b591ca56076bc1f0255f8ae42662d2336356296946b930149af9a74453f900e2f58e40eb3f6e40602e2ede835bfa2f11c44042829ee68492c5b1dcfb19407d43e399c1091addd66909615b26082d3b59f087b28ff9ea2a4df7b3c13084379f7694f1d149935210ee07cf321221bfac7ec22aa34aac62979d3ba06991533dbbfc25feefdb1b32195cbd35ea3eb636de4f23a12b0b105d67c990c7a49a5a29228a162c1fbb3fa4ae8eaa0f69c0affbe740d6c096561ebf7e9f29bc4cd21a8bf1318df9fe8cd12a626e61f475b193d51934660cba5832632bdeadb3a5a6c53999a2bab7c2564c8dbe2643320873c57cf4c480aa2fba71edb6d0af72d8b5ff26df0e53a22220316d49a40de8db14e3f0546b4d6994ddbcbdea8c9147896e2ca47524c586da79530c326a6a279be92c751680374b92b39d799cc0685d577ea0eefa41db1e95f1fbc28621af2cfcbdb569778ff1f8226907d904f0761c354be4f4c555338c2faff1808614f70fef68d1dbe07d4b38ffb17767d53bbc12e8ddd0d151782ad0b38a87d9a0f109990eeb2d320cf1c78df6aaabb7e2eae1f8f2d143fc2dfb352ec47a18dda4857fd2a76083027968c4829f7a904a2677b9a0fa0f6f436233d2682c5b0c1157eb7ab2473446e9be9891be1ed6bd508c61df845a6e7a163da92845bcb43fd7562ddc96617621e07fd74259fd0aa822c6cfdc17cdf7292bbb50fe609e0100c0f156da2923e76489eb6859e3edbe12072cf03b14d04b66930f417beec37530cda3cd8bb133945c789d0e7dace20b4df856bec76dfa01e195326c862f5724c299f711bd7c83653fdf9fc09567b9d"}, - {"0000000000000000000000000000000000000000000000000000000000000011", "0133ee8bedcf9a133108f3bbcdbc20ea045675d4460c9a61f5f791b15b91b7c0db1a98890582d4af7d0805e55b0b1c875c872acd76e629399a260362b2294447998efe0658d475935e383ab542ef1b14fd5929ea040500296da9df4d9cd774571d5fd981d040dea61a1d8114b75b60d11b0d3661f9e7bfa309da505330c610148a9ee44cc0e3175586361848302599f09e4ce463c21f146df3ededad1e77bbedc8a0ceeab61c82e5023e9b6120c734149756f126022eecde005550f1ba17489287858afed34370e335b0d79e5256475ae6f013064ba86cc8550d81d5730f4b23fecdd5ea7c17533aacab23ce6104b9d38e25b02af860b60fce1d1f1e1457d78d1ccaa04494ec85c8bb5ab61595cd31b3043beb6a3a854f9cfaf0aedbb8c77d32bfe3819fa6772f7db6dab772f323e358d75c2ed4bd434ce4fbab3b4358a380b5d32597c70c6507c06c85fe23a5dbe4fb01f9f23a4318ae07c873440d457553e52791d784830bddf9c0a5de768180287160791ce08b20813b53770caeee1c2d162a31add7e103a1c2d0010b231384612c0b71fafd923967818a43f939acfef2fddafcfbce0539add5792042b99f8d89d676f71862991c550da43c841410e395ee1ec885f3edc7521bb751177e8af31384e6503e222dbf630bb3b6e8b49125d37ed97da2526ae33048ecf5cb775a5a017ef653e2f7c97d50f4083c02ea0f479dfb091993cff5dec1861c1f77088d16af6b863415b000db43d4f790502715ead3d2b34a257c139c3cd9f9e4d2c1c34dec4d8e15d05e1932eb30120f01238eb179daaca436d3672e7eaef13c28fc0d9814b1007a77cfdd61695c6af0f3b6e76c1a092c37b38e806d194e8f05b188e78e7b49be4c62b91a560ec80d3d107164ffb204c67123f7bc3e0685331f3d28e05991a6a1afff58d884da125363018ff237798b046b5a5324181ec2c296f11cc4ed4178ebb16795ae055c83804dcd2714c45014abf4c42ed64c13d3ad3f102b7b22f3d4eec8d4e3b2257caeb49520886bc1e91d446da94211b978af11127370a0f53c9d1b31071107923993c404b9852a8910f7a8ad314e9bbf997bea0e2d463a9648a5a0c166f1732da29e399fb796869d0a74193e165b1cab8880e128386a5314631a37264c2bbb643c707d962dff31e531e4d907daf541f98ae9075aad322ecd5b39b57331602e90a7f95b890c36b721de8c6f091183e8fbd655d6807c3725f479b0d4fd0ceeca3b3b06a3a6e19374e1455c4d1d52758ad27f1d8286240248742539b55743625b66d2ba287fa3740c49272aa80ba4c8a06a2280eb14fac687efd7467e2126ffdc1d90c0efaff22415abc0665554749f302b140f6ed8a5dca60b892197a05ac392bea3ee5cb0af169af45b84987a1745dd080030d8756ee1fe5f85ee0496bd28dc9eec59570e52ed13edb00d30116c0ea00e1196b1bec78ed24103f3cd66ba838202afd0417e0929e16c98f60053da41a4a385eb5929d23a2ef0894b389c569031310bbe6e57092d4c3c26812aff0b5b07889cbf3f1dc7e5aaabd595cdbb5c31c7ba760b822363295e921051152d0695cb2ccae9f70b307c866b08d72c5b025045a5d44a60b007f71f5d30cad4654323f90375a329044bf32e030b0ef9d74558591a2ee00588e0e03ecb374ca50145f4b239b32b0b11bf37a2242517d2caa4a27b79b793f78542604e5a9e3cb08e17d5a73b92c9dac518a081bd7e9d5eee206733c833226caf94d5ae72e9ba9173ba2ba63d790c513b58ad07c0c329da151783484302c54cd17e7e2beb33284f0d15e3986dc9d8897bdf5724084ac9de96cd9cc4f612ed7a1a72093d3d05c6516f5f3b6f64d25c0b36eb1ca6260d4d6022859badb9520ae5abda7a1f567fc3"}, - {"0000000000000000000000000000000000000000000000000000000000000016", "00ad4c1b755dc9c58e34f04a73cd72d1fa52b1b901026c53f7a34bbc8d6a49b0e9f9d8147730727d923304fa4303d831cf23e0c770c23954aa3db6fa781ecc19d0046acf8b2cb3d9b591a423db77e5318dd494e9132255bd9a4cf7a1da661286f4a90b3f4add9be4ee13616e6fd5487344697922c68c3f09eda234baeb4917916be920a204013d311233e9991acca8833021b52b746554128ddca1c381b81865eb5236ea389fc610015c26eda3985ed36a68d049021cfd7c425a73940a3a3734845fe7bd7bd5b5a871cadec99699565653371b8c613629c95832a460c4afa969f7699e73fa70ca2294031b9de3b57f428b02956af9f6aa1dbf7cf09c064462d620ab60199a2923af322bbde70471daaafc28018569bcb794fbe5e295a6c6c2c0ab58813d19930c692a8e7d88d88a878a6557da3a9e8de343d5a49f3a06626ce293ddcf216e46dd4bb9c42a77609745cd0234d86e1520c4c1e6c200e8c864f675bacf95a2284658dbf8de946d9cc48ae56d14e6ca0f490adc3f672cb2df0227b14b9de92d231311cacf0ce3cdfdee7a34d4ede6b2e1e505586e474451f441975eee1e7eae0416bda82ad5a23df8e4f1514a418f58ae980d67702f4a652f78acc7c1afc5f481bc716add96075287e329dfeebdd84be8809831b6c2cfbfbf120d9e139ce13fbbe7672a2c302d996c96c272f3e792657f7dd03704650c001bad0cff9cf4a22e0cc63185b1e9faf617231491ddb98b837ea907b77f95ebb97b37e4fa9da628e214a9a9747981ff4bf5cb79d70c9f0a4878dd6b4b5407417525bea1657fa8f7b5f8f4ae4bff1748a1088adb41650598db865355dfbd57a4de9771ff11bf0973963aac5d8d4f754487e59ee436727ec51acc0718ea30d446255c3f547ba6762fd1fba6dd3a79fdf13962ff87511a8aacdbe743a71ec5955d626b3a7c3e00e9caab2614aa79f8d1e8d424702a3245c7fe701844f83acaded41ee53b23893083e788debafe19f3a40486a5fda582caf61af5a184ed7fb59cf8c7d438521b0ead4dd007f6afab892350afefab6d4bcbda981903879c05031d05bdf5f6257c415a87aa1af9dfae8a1ab4469829df644b7829b3fed35ba622148edd45ad04d88ded050f2a42fe4ad084677addec35c6efe69617e92271008eadfd5cd723ae39a9efaa47d85460af08305c72384789b50bf014ae2ff20f5debfc7dcbf013e8a555a9dd5dd95dac81d95865e1420eb930eea31a202958dea56b67e0ff6500e655c1a966af2b836e269a2a790f953917461e04cc96dc7dfe7fa0be006e0c0fb4c5b15648e7eb43439ed73686cd1996a923c2166318ced4062c9e7541a4482e28db5dbcbd5d363a342722137de0cd353a71140704cdf0d5bd1f16a3c74a3e52999c33d289b767288f82d08b22603afc476a01c242597bc13d0fcb75f2349922d9fe8fae376ce136843322775b5cb928d9b66bcabdd5032b39d9e6ab0727ce7e4dd767131908f12b8bbd8a3daf517097101580647e2725fab5520e846946efee91fee2ba711303fcd640434d8d1c71f06309d2b998326f3f95fa3227c5f61c2ed57f8d4b58b41144ddaf319eeb55a1a104477b0664cb74e3fb69d08e3c96df31d7795928890b5da88cdc85060a5263847291d41ac589863537280a37829bc4f4dc6ff2c7d144f7f86dfcaedc6b5dd2112fb8e1afdee45bc400261b39dcec7e6e581c99e50ec480b499dd6eaf8157816860bee36cb604df26d911b5c2272b0b822c84a6f72754f5e7aef93f5d4db80dc5cd8f6289f2725d28d8d36cd02ae647ba12a50c35f54a853c18797cd79cd376d8b13131562297e5f7113472769978ffc7df12a639ef427f05fabaf921ef21c8fee985237b2f5f8d35a057313dd9c93f74a07c"}, - {"0000000000000000000000000000000000000000000000000000000000000010", "002847a9e24b3a767545e138e4dd96516698cbf35528036ff7b170f245f14647de37f498ca93c87a134822575520850c1a31cbcbf53ddfe5cdfae2f55c865b6558f719629bd4abbe39d6943e45a83e155dfae96508c3b531da5c15d1d097979ab87f20b3a7255e4d630fe9711dbf92dcbfca63326bd898f68555e919101019b84d29a7117074cd476473f1372149f343f12b792dfd6c73f296a859ddde746aa666efd96421976e4a0290183133d93a738261f368002ab9e1b7c85bac1c0f5e8125495b2b5ef68f52a7b5460e2e44bb790cb10850bdc05e10a17edc78d5df9a583792510c37f3621634ba4caa53d68eafb5341879300667a8a35dfa7203440ca72641369c2b6008f3a2d4f91a910dd690fd0346decf48dfed91fb1ec11d3871c0b22df9b4553108fa947f9b1f841505de02efa66cb3726dea9c0768116acbd1bf4cbda712fc23c8dc446d99f4b291111f005e024f4a4f26cee7d15368c74d3e8a3388fa537230ffa6742c91e55771388b3f1aefdeb74a78bbd6160236609de4614687f7ae63f1c3a2c1e2fc4fdaf43c40bdbb5e749948bf609175a9b361169f8b453c7c57057dbd6e9e94c4973de8e2fc8b47f8c62cb1940e0f2ea83574dc6149b3e243c80085ca629bb0327f71f20d142f0b5ecef5cf2167a302d2aa600f4ded7d70121080f99edf8766036d1a235cf05991d201073aaace0326e4796b050ce559fbb123f909848d0e0149b32e27c8ca71e45236ef444b33ae3be7c8f94105fb62f00b5817787f211503b2f83252e63805a9026f93374d1ea31ae8a61302cfe71b67a7c7d7fb769388170272054faddbea5ce42b0ba4d16c3eb6544b6136be40ad164655f4419ac07956c13429f632bf72eed3d8daf0089a715f40647fdfbfef85816569761338d83f24ab1d5b5d8621986e6bf5256a1ba854d72b52ae9f412a006d704df8db7197022a13b0dfe61c0118bcd45b9a285fc3580ef8022fe97ed2fad3793b2d2a57ede2b9033bd6919bdb9c0bfd0de372e6b2c392d1f93e8ebb1435f20ed0673a077b5b4293d0e75d314116af14bd03ee42632bd1e629c68f8065321fc1ec735edb0ba41115ed819536c15fe66af3575b4415f4e076ae2f9a09d594b40fddda23da8193f97b37443d921bb686ed66b2dc6f4dee651d969496b6baecf91fbda73f4f040bdf7e6c8dced033e018515e969cbca90dc29cd7e80ec8bd83a1466f0b46facbb96dee8c375bc71ccdea0e0f3a82ce531802c44284c10b61cc260e641eb1ec16f7a225be28bc13910de4317271310952464baf400c6fdb9a07e470d941a0e1684bca68f4987468ba23157fb70fdcd1acd89aab023aad9d770cb2cc07d31c17ca66750ea77319878321f360f6c8648d4e55a9231858adaa238e8551e71d42d8374708de818ed8168b013ccafd1ee122b1d6b2639e5624dfd270c0de23a2203b7b2a2d2e1ca19e1e4411314f3ca190dad02cb80777f1675e45ea26a76950b4be21a941990c9de2613cd91ec3ae90af059886f50d92ffc1bb5605bc1c8607ed02a64bc6ccf2c57827ae91c8b66a9cc43ef1621e5fceec4d51383ef8f1c5bb51508d658bf915c50f0ccbb140341b01fdf028d6f349cd47231f5c1a44b419048c14fa758ca3d9a822b53db171a201c39c54c0109a1eb1198ee10d8877d4871cb6c4a38ae8be3628ac1b85fc346bd481cbdf3b3a40646e3718d51e8afa198801c3e496b1cb7dc1549f3d7402767c3c76d237264ecba4e45ac9ad953747b78c7802137dbd5c37191c98fe7b4ed2a81be2c8522d86cbfe5e1157b2b8fc58644f1afd623f09d062ed8eaffaaab36cb35f6de728281c0145f3dd35ac1e471b273b2b268f5ddb3bec3192facf438d639304566c4ac6f0e83794197ce276"}, - {"0000000000000000000000000000000000000000000000000000000000000017", "0234ad6332dcf330f5fc461f6fddcb899b0a1ca60e1c51ff039347c08ee76b14033dd30ec121769c0dfc058a4c74703146cd8b38e515b75503732853fa94db689113fb46e2da45a1d5285f8455fc2f858ddf9fc9055653070793bedfaa8f34151e2255e106f24998bf0cd5e5382905d6f2a889b398c0fba87b51a63e4a8a06247ab3c5d0e4cdddc8106625dd11b55fb5b3515819af119dd2637a7ba071a5461f6bbccdcca2fbf7ec02dd083d6f11a6cbe20bd72e77ef89d756777e39093f232f3eacd1a034cadbe4a55abde9934ee9fba4d6111854feaf909598bd0308e3354c923ac111bec1da20bbf404f3a4a62132ec52193a69f1ddb44b5bb47813dba9a534d5c8994be43298583b1699574dcf6e2f42e6cc05efaf490d9941c5059144b9cd82fc505ca71ea6b268fa08bab184e0d7f22172c10360acbd85044585dbb97c6ecdd7cfa844d567c567fe60f7968b7602423ee054823982b3bf7510874603f297031db5452124f6e6646693e5ed87b3aefbd6ac2d986f9cb3462e8966f602ee7d29e579834e51d9e8850007f0715531c1c68cc976e1b1ea26e466c1c6850157c8528f810661025ea444262ce98d74d7d436e35960e53bffd445e28e1bb41e9d5fdd7c145ece400355e51b1adc7a0aeb6efc664aa21d357c52d3c64d741a77b07915775442c58cf5a1b7cb34866a5b74def59b94b15d521c043a308d36518237ae59921401ccb3e91fb51c9bf02d154e9fd41266a5013274b74172304a10d8fb081b134b1edd53d4d9632e3ce86885e05a0ae9649ebd27200cdb7b6026358b930cb2c1e1a49bc61ff51c31120a4bdee14447961ccacfc6f51657d04a3102d30c9d3919562ed62735039be104b4d6b6555d5e740f14370af312a83cd46ec38b7052155795eebd97439c8bb61796aa49894c47ed2bd352cf8be97b8d6e4237d37702b3055fa4cc3db4a45c741b8a4eebdd3bb790e30e2315a477b0ee56f3a70f47969875241bdd113f909b0627a157a820ebd32b9c816869d4e4085a49e6a3dd1a8ce15e3da2c91920ac51ae5934868d8f58bd24810a8dac67bbce1921f8b364f45c2904aa0ee792dfc43bc84c9789da3226e84d278ccf581036411b18af0c2358b571254fe4fadb5e72feff38a1a6295a73299831404efe7b17c821e4f124943c4f0d29841c18b65303f5a4f18c101f57120c44d7bce07b5178489a0d97077c89e486a912e962071705a8723baa3455d5bf420baeddb22f15238b23ae81c461b52ba60d263bbfc731d9057c59ad88c1eebca3337ad122ff9537bde562247ebb6198152fa3c9e5d50c736fcc773812baae51562b45c76017ddbaddf875d97246a2f24726968307262ab69f2a159d653792627d482e8ff21801be8b2a3c41ba83f559fbc73d96d62c39611779cee90ff34102f27ffd6e8fcd04f8c1c983b8cfcb469cd07a49ed16c677666caded05882b11d04b7ea8b2a50abaa48b15923a0110e7b149884ba6431756042ea9fc3c20a01bc622bc2b6bbbaf9c9b424b372be84547c7daef8d12e2d4dda9454aa3801986e72b6eff4a56a75628e82f5164df1e10fef3c833d4a34c60e64dd09b7b6b1f17bdae9ee4e13069782d82d0dfe4aee17f94983ff61a4541266ea02ad3723071f42ae5a1e0f5485d725a09c37d5a072544a5629fb55ab642ca861bbe1f055f3056372ee1dcd3df8ffc091656d81ffb76e7feea4812bbadac26cabb89a587064239441225df503d193518c950c882c8d727a55d4602f95ca2165296b785270a33c220942385a7be67016a78571350c35f56be4c0cd512a0d71826858bef4754d03f70e326361a1df527a252136c730b379c54d2ccc1eaf830e7990eee982b8b5ad34e10b4fcb9c5b33cb22267d74e695c0c27"}, - {"000000000000000000000000000000000000000000000000000000000000000b", "0012b949cd1c913b7c4809115f6c369f7b6a9cea133415652c871a25e3fd5fe3b2f3b146ce2c805e235f224af3fe1b70b345ffebc67c4dc8c96eac9cbf874c32a85624efecdf397e3ab720075eeabddcf95386f701d86a24468c2de342b660bf71dc0ed8b0c02af85c41099f6e1b3078b9fb1a650d675bd27a229fbbbad80f7cb6623618da7ade7151810ad85b30f4cb5b5f783d848e78cc5f4f0f5a45e658cc3a037a656c5e163709e85ee7d64502332c8bd5f61ef4becdc10ef8d1f725be84a3fa23f099c0dce4d6a2f6d55b3b0f1e37b014663abdc68c4753b69b51cc5ae69fa4a9ae72518d28b57ff84f987b41a001e36f2424af6618085d7d950e8c0252f7dded49306f3aeba2f3934adc8b7ccc74342e83014455ba7faf54241515c95e51c05bb4b8db1bb9a327348bbff8be5b851bc5cf74597e951790dc1f84dc60f18bc266d77bc3dedcb7bacef722bf9fcd02bdca7e9b5adaabe9eb347ad0dff10339f83e82c81dcdd90ecc73e221e0e8352b86b5b752e5ce1b539203df03299db2216fd679c414612651f5e40119161507120745f6a4a1c3c21761fd19f4466db39af50e0f184d7e63be6878638d8f32781c6d7f632c4aba4e941f1ff5097d5e5934f7a298ba44f06bdab37f79fa801ef78c8311091e256daf42b8641c752d4f1a8ccc4429dddc971592f01d8967987afa51af32f99fbb468903173dd89d5b7c65e64310db1f6168ac71d8ca418a06e5fb2a65da0ea1e42d53abf86fe9b1eb9756fbbd2ce2bea9692124c391254547132ed0f191ca7baf2454bebbc56065cd9590e947938fd12d4e73439a5e870523889bc7839291ccfa633aaea667a2f3b01b4ebf67aacc6f761aa687418f26c713789bbf59a55c303e1cd62904b5d05819edce9305a3dfcd594670b0ae6b6252d51b88a9f93b8ccf67896478d8ca573f539486013db9a3b1e8cc2f70c8e4c07263a477167519ff9f7d62fc6519df82db6eda5957077338aa70971a0e1102ffafc7338f4f71c080a08089dfcf895a307fcb6407997c81fd46e6f1b2d1f2fb68752458f07f5db7b603897e1f0c61478f5699160305c95ce2fa1af809850ea0258f94b62d3bca81e5fea9e835e27599ff7e8803c005353ccb97afe221013cdb30b50d1d6c79252921eef267fe4b58266277847e44dbd75e87de590a71036fce65f2d8ea75affab3db612362dd5a5ceaecc334e03c3e267a62bbf6914580767ba8c6a1af1bd9bc09cb21e4725dccb74c90f10697a36dc56adcd6d4fa3d58c70230ddcdaf895a86b4befbad9e76837bbfab05557436782c6e91c879594d97d1034b4bf45eb8eb288e87ac390eb08c843e55e758f0b69d9246b31f8b163dc67f92557c132edd2229e7459b8cafd30e0dd8397cde63fa65b4976cdd8545023f0b5d9b9cb00f3702f8acfd61d27473064b434a18221d5674151cd75217a98b3d1d9b598da98ca3eeded8038246fcfc67ca17321b552e1552b7e55e1446e3d987f26574b9fab418b94b419b19e907b4ece45faa6b4732541474e79721bca7f1e3924106f1e393afb85d9268f1566cf0803c34250587e00781cfa3957040b184229804bd4b49249fa1fc108be3087fcdb61254edaf32b9963f0da8283ca96bbdcb1065bdf1b31a4ec91591edb6340af20878e2c80b1f20851bbad545d03ce5b1c4c81c9eea0e5b2b1284eb95a98c6d226e26eb19951ec7ae5a532ae9d6cb3833bf3bb7cab8a2f4c6e67a558ddfa55a2d0f2496f2929d49605633b14b78f3e116abb056eb0cd331a1e6561a8d459cd1e8e7925b3c9f02edf5e421d3270d0acee66703f0e2bae0d1db0e8a8435443e210c3f1307e579539f3ba259ad69811d254b940c8c32368a21145725d14dc3e43aaf419bd5f93c569ac2"}, - {"0000000000000000000000000000000000000000000000000000000000000007", "0122f69589efba97bd9073b0dbd55c0a2355df13142f9eb1f87f508d80d6985461666b17ab34fb39e4b305271f26c736ab25c2a2534abb5fc042bf1f3af8bf26d2c66ce5af1693ceb1c488df4b66a21ec83b6bcd02093f73a09fbb6b81cba47af15071deceb41cc3a92a756dce14d540c5d8e3931a96b1b465adee13b347064de7a36713d1154e00f22a1fb60be6acd3991cf60ba40a8396c778d2816334017ad2de5a5d63d7a8420131974094b04623faa8721292af6f6cb8c08a13ab210b1e1e8ba439034dca6350d86fdb2d39461a3bce095b7227e6a9c8a9ba37925e7e5cc3c52efa6a6cbd1ad86735cc9c6363b680956cbbc83e928bb17cdfa207d240435829a1f1ca66a6be49fc6f9f0952bca443197e034f8e57186d76dfe412aae8eedf3d79dc0b56163ba8f1b2e74059fdd402842529c8c8a4c53ef2aa228bcaf4af515da0f28d3791d8c6aff9f81ebd611e012ef6c93fcd6b26950183c18f4a4275aa74eeaf4f02e72ab5685c58d14b44057258ac7b3b91429cc0c51b829dbe529d63ddeea063061e32584d0401899ae31cc9b65c892f584d9615928e759f1ed53f210e14350217ff962d8e4bb7e122a220235df97cb6cede9f813a12ba109912706b0b0ee85e04f89bb2bbf0fbb7852631d42ef595c4378348244ed1cdef4eed805a75ad2fe62fb7e61c9d0d36dfa31a93f07671deab594a63016642b9dcf4cc1dbfa45045fa48dd62d2569ec272155c4d1f76d52c3b5d1791ff624650920dad3e70d7080b5d9e4e4afe44f268d58bea7e0d4a58ed3c608f092a3b3c690df3ff559fc0f821252941c7a6fe763f05f7d04f65930c45ea41543f40a75e55a6cad89ec4102f242534239c475961717cbffaf8a9f32bd8008d160ce18bbfa4ca636c50b24b4551d1e8a20dac21ae255aaecb1b11f64d856db3301042d35554080d3f8f016f60477fda27b30f8a80d327261a1197df9ab8e81f5373602f93c591d005d5dc36ef990e87c35c7c35098eab5d3194dae38474640578ab2f7dd38c1d48b80e9df41e17aa33cf8e2f76056269e1d6450658dfb903024e495a8fe42321d730d2b745059207649982260d253d3ccb6b8e29ac9af47f263a84821b1a7c6e2009d27dec586036a354d2680c22675816e7c31f16ca129b1c88427921d7f2f734513d3fae398c0e91f9950c261d1379232969ef2aeaf51d5da49efacabd3e24412d64b6e2e3c9e9f52175ec0b6d2d99e0e61d71221368ee8a7fe48bd79c06d79f267370e2ef7cd94b761998b25c5536caafd6bb34b0ade1d96341d15ff6470c9a78f157ac7ca57fd2c51c3bd50325adc312692218bce61c10df0175b39be6091e6d0fe232b97704aa0d59250a43c51394e12ca107efeb5da2390914e7c625ea8cb32030f2dd88d9b41214b0581d63691f111202af3f36a2ca986180bf86687dcefe762c0a58b1382a91be0c8ed1d7cb6a3247e29c6f703e77f53b8ac80c2887207b9d6aeb7cf4789b525228c743a37f9c6d1f9913866b098138f841fb1f865b5a1ee4dafca9410e4ade41fc968d2aebcfc1dc29bd22b173b3ad5ea52731355a438cecdc7020353de1b160de8467d4c3cb15c9c7f8594948ddacfe51f228eac7ad0d52dd1d6129e317759166d4e78a2c26344d70ed0a15899240ce02c784e229130532983f912435d837b05c5b8414af08fcf84c61a0252bf4dc11942c1ac7aa8a805ef86c4049ca21e49a7830fd73a57c5c2db48ad388bfa69f477c33d342d79cc1a744d8bd7b6e9b0a969d99d88c1a9eedd422b1462fd38de530a2711bf1dc5678615522e04aac0353a7ff5dd008ad465a5ed6a7a5d956472f7bfe6011d2ae017fd8e7a6c07f9e4aba929f061f44337733fe6baa23fadd866430b4e33275579ceae3"}, - {"0000000000000000000000000000000000000000000000000000000000000023", "004f01973c4ff102b9dd97838d712a664024fc2b75195bd5e56346be8dbef5e7307377cc96a89bfa8e8f22c9aace5f0abeb5d692837fcab54f1634bf3482f84a6872c838611f3fa004868929b8893acbea596b10044f72f810da984fb24e17d5a9ee20463c4b373fe42638698cd4cc3a848305e5d77e3f7d363eacbdff350fa45a98200b4dcab0dc93fa5628587d6dec9bd636256f823a370b830dd28f95a714cbb8b9f16171fceb084818a9cb59caf5449942f698cfdbb6ff9497fd5121f615c470af9d3bee96c2d1a83680b51a86dc5348279ad252eae9eb75dffff47b4175fd99dd8adcbe3f3d6195a4d859f39ce64443fc8b3dbece79b4f6b601085301da69430b964f5419f373573672ecfb58383d2375fd8d8bc8e10e9cf644000243e1a1b253de730e1eb76d18cf9d610aeb8729b877dc4a26e9925e3fd83a599e35c4e7082bb2705493acd8b5fda491528aa30a471ca15ca2bb874a6f3184e143e1106bbfeeb9aa155692d0df193c94fb6d76f810c2b9dde86fd951a115eccdf3a00c6652ab095272f8d7277d7c097c890d1b8a2646a356c100c47372ef3cd1a77eaa07b751060d9da58f34097257ec5f4186e190fe825ff57f5ac82e9641d52694e6b4cbe295d3d65c40af39943af044298b936f4f5cdf517206b340169a3d350d3479500e2ad674dfb250bc5ed06074cd4847953299137a79e40f96f1a47575350fd428c2c719a354216e4910e5821b5a4d463698a67793c6a39b29cbfac0f3fd9cce7f12b5272737e9ebf9a2d9836916a0775cedc6959c381dff099dc2491e5b569aa3bdfc6391a50192b036e01cfcab87a68990a7a39b4467b7b2ef71247a1a0a24421ca70bdb5111297563666dadfc022e7651382d862c9e7ec6e26933b1c201a31c10f72cc9a9cc1f5e0aa2ec7e507b2a755b59a3db29227c4e974c30ba75c4006e6be6d772b9b7b29523f3b84240e598033179203cb9c67d4edcdaa5c09eb6d7a23ad832eafdba7c3601ed9dea93eaa76bf1e0602b8a833d8a4f7bbcbef90f3164ec9a06f5f8f96f1a1353f014439d2cfe67c604e963dcfc4deff3c0d9a340cd37402239481ff1d409e3aed92b1ba5e58831519158354706b0ba16db43192bd2a5d08dcba1c10be4e418c4838e7fa9759b204386fb2365e1d2c3adfe0621d43f50760bbcda5dfb12178d418fa7fb319ff7262b08fd3d02893837d2f73e4c5b848024cbd5e38256fea5c42e9e97fbd7c7621ebd594bb50e0a3da064c7f62e6ebe0f72a0dc3e9d315acd01a90e4dc9b78715c75a468bc673a6b9a8921473db2e40ea4ebde5fce2a1584e641660951a5ce8324cab4748d45c83c616e3dada6d1fd5d16cfd12f41af7ec2450e5418dd5f927f2ee61a5b6d2999e8bf631be81dd3160d2814ca41559c73e2fc664b63e8f1204c318919a91414db9db50f47eb110857f342c716c548dfcccf8284c2d6c3359df51dd3aee8a775c7424177bed8f95d9d8e1058ce3aefcc5f7dfa45bfdd3ae2d43443a10cbca37e811853863799ac5b210d4ef6c06ea1d3d96964904ff405369554be8a540a24dda84223eb1f6a2d048511ff6c4237ae8ad7124bdbb533d3fabb7eb83e7c1f1cb22a8ac4d4b500ef84bf9f81c5567d63dbce2f6099c4f65e813f09e35f059922be60890f2213012b04df81855e93bd93e01cf7d7aa7a419814d48f5a61d196c64f38c834a1ee1247132e93c21443911a6092428eb2b34c0fad96b6177b0f4e9b2490d0b715da273f96b98f73ef9d9c26b8d30ffd9d311165b422d453c6af16d8412a954720f538e5d33ee3188aff044a537c5619236da90605cae091199e3cf2320ef56a2371f53e947d340c871dbbdb90bd74f893e33e680bb94831bc6e97460e2b51819fd293d94f5"}, - {"000000000000000000000000000000000000000000000000000000000000002f", "006096c727b210b9d1b9004b82b974adfb5df6c14e2a974c33260ab5a39f122791483dafc32bb95c6e2010b0c9177dae668be8462365c9e0546de581fa142f17e15c0811cafffd83bca7b759e5494e4cdd9432f302555b402184c88dfa55e15923e4a10612305471d812646ea3dd77fff5d8f5a387d2f16d3d3bafd634170ff7abef47da24d32ca16417e8b7c00278475ea4e642625f7451d9321f6b63aa09a7e821a28ec3dde6e301e05e57b1e0148784c3d32363993a117a12506b1c0eb01fa0126f59cfb633d353c61d2ce9a1b991221227db6a093351c6d5e6ed25ce8f6b95f9806f6de3d63a7b3ac299d44ef13ed0642eb12797f5b50fb51d4f0541dfc958f3482dbd8fd699f568d7eaa1175cae4754308bdc9bdd2d35b00bc6321633cd2ae081ba254311e261111189366d0744723f071cec38dc33d6136b55f545e71ee8c8b15af087adbdeb40f37b40bd8b920135331eacdcb465e054c0fb798efd1529374c108f15b87eaa38ae61fbc751d47208c7189a245a383d4632807dda88658e73da2535e743cebda9fa4079927637ea5e9704d435cd05103498f557d8416e8f9ae021052d289ea385caebcbf3b05e17bb9105603b7756c90d35a28a428bc57b9d8c221badeb27389be70a04870cf06939795082cfd267d0ecece5cc1e101a7ff63e24eab7cedfabfd8bba2492db05533e8d92cef3650d01d6e516f4cc4155b4c3f27f98c252a70aabb9784e126692242d928f9cb4cad3fffeb4604d43b83048d708981fbd3d8f9d0fe5d4445ddf3a7676dc5b9c6cc51efed4121953570dec81b84be3e1886b494bfb88c004d19d3d1ccab1ebaadbd1b436efa02736e2bac899270ca3653f8c10373177c4bcddad6b07275cfa3445056e3199e846522d5865a6417e6653e2a208bf74f32ec639b6ce57e02cce39b8fe2df7a9d6b2e85cf83302441ded5f4ad005eb7033a2815fc2712019b5f81629b2777ad68b83247f8c449b312926bf12687e380014f80731655a26f56f08a6d22a45a1a61c8cd8bf5f2df2cae8c7900ebfdda686279d69c6d5a35817d0c9097c1e73d8c2f61cfad213f88a55d8de2e1ab96bac0b35ad22e8d91289fccbd0d8cc9d91985ff458bd7918b97dc45814fa6f59fd96e76c775d09cebb52f25d1f9237c0af245205e928e9faf9565546e5fefadf2d037be71cc2935c610e8bd15649d70a30ac47a567d31998f46998d9804133f6549dc5ad847e874abe35b31699f4b096221cdb36a52437e56edb491faedcb49621f232b79f4c8ecbd487991a946b8c32b213dfbf380d738cb50b5da561e9f6a2ca547e3c6d5631b7a69e313ec6a21495dc014d74241b292a56c55b3c7e94b120098f9736a16c15baa3f35916f6c6f38492be565671db9bbc16a8e8f56429c8fb4eea372e66173c23c606e1bc9b1806d11523455360b5aabd2564fcf7a8c94bb71799465bf1c90ba817ea39f9f58dfae81a4b0a23fe31273d392907f36dc4410b3c26cdb191f5332033e7837933e24b0fb728f5d32bf2f2d2b8243f042d07b2fd6b13e6bd696815614603b5e1c20634b1e0360d53f322cba64e39797b314b2516872069d7b4cbc12b773d5e0396250dd32c96181742a2ced4dd78e9ba2fd2f3501f26a0f7ca48c99ad3e3d4a75f609f42db0e1f8cc4f15487a36ffb76ade862ceb201f33f47d1101d05765197c2b702a75497d066d449f3a8d7ba140e2e5f8f1de77fcb4bbe06c115cc382f0e173fabad37d21c75d950c7aaa307949db1beb70a2139955e2c1817a720e7b1d9f1b7e8b20b68a56fa48a7f5db066342564edfd5328c9fecea51358fe428a3031da466f23e5e698150cb41bcbbca4292854f86e70b79ab56c3d7774ec9a20e0af6ddc4818c8ca177a24eed16756"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "011a0a8d08494acd366931eb0eaf77099f5f331eeb12ab66a72263d49952a612562efd7c511652dba74c28778ce5f21cbd435ab922eb84fe96012e6d1a1fe97ce00710cb74d02bb4c417f77c5bf0967554b9415f020bf73137a41603ee3bc4a9535aa6e213b9b9497907ddadba43996d92cf87a418b83cc026e97abcff052eef33a85d634565a3a6b47294cefa831e6cdcd0d153eb7db22919890101f7967c4cc2450efa857ac6e002e316c36c97430583ca31032cfc9c261c739ce7520c61bc2db09196f34ee7731838324709570ff01c070f71bcbcb19a153b4be243856c51ad9581fa1acc171c4a6e9c5a908ae707959275eafe5f2e848cdc541e03f6aa1451183b9b5bd1c446d1dc75119f50b2f6060d7ec943b934af5bdfcd16f506f8ba5eb1be7ab74729ccf584439b7fcf7c016a0d616c50d6bf4cb8c44b335f4472671e2c37e021b4d6b332cf9a34811dff7801591c4e8fc60161656f54ccf658aa02df6edf25a943370e1f2fe41fc7ef5814cbbcfb98cdf7ed5d9dbf09ae97fb6b4b6986f7d341fe67e354dcf017ae76c91a30d2373e1cb0e6f540e2fb805e654559dc3707e310f085d64284b688531444f0a939660282e19fc6ca24f0369b7fb8e9e3fa9fe335c2e240c6eb729f9d7f255dd178d172bca3ebafe51ada2f029b5de4dd0bba526d4d77eade16b30b9a45b2c0c26236b279575cd601a1e7d7b7c8fd29b823630d72722c1683def9dcbf2e3ea2863fa02387c19723d171e9bec9c3733237350288cb46be8e8b4496dcb296535a08331ecb9bd38904c67c26ab19245747b4570d94c9f041e030f50acb03ca34cb0a81976151ecf119ffa5b63616fdbc987649c7fff494a0c367e4a384e165b0c01d8216f357c9304e233ec1d23e32cd00e5ec795a1252d776f825333507c7285c2abba3d654d592cdd0908e2633de62ca0266cdfcd751a004bcde10f2562a5611f376b5ce271dadf6fbad140725d57762aeb86da32cd97f8b882d078aea81de849bbacaded65e1d5bd7f2b21bb6a00a3657ef1463574c33209654fde478945e01f8ba3bb10586a4ce50da5bd16322016cb195a0f5e00d75167f10568d38bd0a83f590bf6110ef75f34deb90f54a4e24a5597209500f8c932cc4b4fce52ab360289bcf4056435b71a7b0b0b1c7e8f737fac3dd66b3e89921f103f171303a5d1305dc8da541423645576dc75b75f0079d5b4ca8cd25f3024c420cd2eb10f086aa7c6dea097057fb3ed7a26396b7a0b50e78f9a82de16af07610ce4a9e69f06515a3f96357f6fe7c0992bc12b8b806961feeea168425b37311076ac1afb8afb3f857f2171807408ed21784cdddb354c67c2bbdcbc0b3df373c2bed09bf55b7199bd306c80270e916461052578e4ef3debe89ecf6f1ba57a4fe0976c2bef8191f9e8f02cbcd59a996915939b9b0fe8c33fa7133307ffe79080bbb4e2e91a067726b658fb0f44b6d717730cfab0f2f4b7e9b896f97f205d529192e7f4e1423df04d410d4930f11d07f7cae367193a970c720f19b48b89910b1c53d8fa8971f6e866740a0d227c394727d0cc217ce15f0ed9300d1295ca478886f62cd42a7ef2a3e31ced2756f9890c11374c5c13c5961fd9a34cd913d39f8874a585f2e0b1a8cb539a135c75db45cb6e50c0ce8575ca24a397fd6e5b1871ac6e2207e88db664f120d1210d8c4fdb8c8f703c5b0328be2cc15faf35f20dbbd86d75dd531673db680bef2026ec43f9ece9b419a24e394719b61c4ff8502a5fc68f9444ceb2fa80dab20e792b5fa4dbb8fc2df10675e991c08f4bcdb348add1d5217c7cd5388e3cf1c248eae242df84396413e8c77db1e3a1305ed87ae50f54ab32d21fbdd44577b9bec0a6adad3eee7866a11bf5b525a80dafae0"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "00e60a09b0daded79b3d858c2657320e58333aa50a46a68d58b7204a95ba7154e20cafce3b0c14bca8e9026948d845ccdf8dec2f9612e338e13e9f2b7bc6b0697c058bbd66ada77cb517127e44ae3f5e84bc3f5a0b3c954d26570e0f7841a90fb3f0e4eed7421ff6e50f914d1cdba4855380c4b9593cdb297704657a76440f3eb55c095cde5520e8d58fba66596181474ca4c6543c3dfb579c9e07c59039211871aec70de01aa75b0139f26ca45ae0abb76fb24128d4f33e9ef93865c81dbdf2b8b0d0ab036e5d62d8d2693f397730d5b7520822ba70e1d3372512bd27a3b46df1be7a7116e49a1061688c1d4453c0f14152401230479d2ac42cab1501bb250a8f0e99ada39a211f8563aac607ad763e853216db65ea16270b53f3e45284e619d1272932f1d10ba1e0c99e9cf55159e651ee456bc23898492898231f04d6b200e08661241078496d637f031f0f1ceedb06d0f59676eaa109882b744348db7a922dbf594ad92b42fe601d65839bf2b11492b4fc8a72f5023b214b0cf3339685b155f992d59513abd51649e50cd4544025885a20c5e9d26db62e630da778d20956208b3cba0ee34989d313a346e981d18bfad9a7a466cc8c28a22c4cffb61431b739985fe634e23a558b20009f68ca2f3ec303aab6585dc5d7963fd074d9d6172e55fefc40205cf3bd936cf8a6c3b47db4c38051b26fee7d33108ed454aee43dfbdde723b432c008ccff257641eb269c7aa2b9240cafc12b46a98346320a4b7a759a9034b5ba1b57cf317ac4b2a7b606d1b60e5042fef8bc59075bbba4dc3183fb5867259b6aa55f1804f9c9d113dd6bfb1cac1f719cd541dbc02bb22cee5a52dee1306861956f955c1df4a1e51a56375a416a1b2c75221470f425079953b3382d023d0d29238ac962f9fe5120f24f95b7ce96173b7f14ab60f6c0d1690f3ba1e0016f947ac2815f224997e362df9f370cdf0e9c69af2e2c46192ccbfd93b2bfa76483d57dede5d6b015810aeef7d9ad6f39a5cc9985c3b3d0ac8dd85e133cad0f1578c0aa2f9cc7ae6244aa7770fee9ceb4721ef901c3184e265f0647f513009d302e898e1f883c0954075e926d7ec82d6a5ba5710f593bb97d048dbe51e80e1445a4dae51b61d9a2d147cabe8127437f3f3fe51a1b7438dfd0f035ea3e06f3dddcf2da6eb33ed9b70189ddebceee9bb37c178547606fd2e5d98ab3792946438f635e6f16e39c9759521266a46308a23857eb0f35ffecaab5b1bfbcc75422af39afdd801199c3443712468c162d955dbeacea4d1b570ecfa53a3e2206035d197b6f42d995147b16c55fcd9b0dfbe7b0144929e5297de8138a3f822835deb7e7ace5dfe333a5be0678f59c70e33f95ff9fb1b946b89fe902d67c77750d551619f69a00ced7be367a8b7d15ba662f1787f401b4f88b940d608f986952aac2c5b5fd6f6f96c43f3d322ed389716b03e403683e05ee06e333513bd9180adde39fd345232c9f9cb4ba34d928762fd43e56974395f2e8eb63e16d6fde15d37db47745d68fd88ab601ba9729b2898def6d83e10c374c83ae1b83b82cf40272b71664293f35d605b0cc44bd0bf1993ef005dd077567346b9660c0d156036ee4ac95f9215413f1b30bcc3c13a683b81cb9a8e28feaceba092148ebf1d90810019289f0c11bed39b95022d01de30091fd5c760d2bd68caf4f3c8c904504e8474aa807368ebc9ab80b7b5aaeaaeeed0fb352c1b2be349d9111a13c6604351327ecd29290258c4857f683c263ca94e4dcbbb7136c4af16149001ed61ad379b7a7aaf4f904717e312c39970da0962e51951d42d598cb30ffc47d5f774e1636d553b249fabf42fe4220f86086ad247efa9f002d7baa2af49d4d0bdd1e76d5fec29c67106bfb54f6"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "00e85247c083dda6f079877a46f5820a8f2eb641362b2989caeb9e63ff802906e7b9f19ae701113feb1f024225c44ad11ba355f7b7615a505dbe42deb4cc7b43521720ff2d212bf24cc587fbe93a8994e59db787017c6e75e9976d31aeb0d4b996d9a4e39aeb5f37f304caa8584c66f5d186d8e273bd18cd356f7817a38f03eba740958ba406d6fa314f22be117a4e9c576d73546d63627ae2baabbf90c91dd7555aeab6d9b9488202dc4f60d6d6fa3f1c5a22e072740ef23021df77221d72a386422054b737e6c62551751f41ff9d71d1281e5c41dc17d5bc36b59ee59119e0a625beefd100a42580a4bcb1576087739ec5f30c4e9a0eb73b3ecf18069559405eca6d087c72e0984a19630887f69da35a0db6bcae483c4ee3fb1176c9f4c224f60738fdbe5f0f72ca9f95109e2551032467b863246573f8f266b9197dbabc072324eb5e89e1d330fa3a0d19ce17d981012765a3e449e9d18d2fd0ba95291ed689cd1dce5204ae6c3ea70cd86f4b71e1b834b07a269ed21aa36b028950c65082c6c82b0f92700dfdd1ecadb4730dad036e1252e408dc4e9edb345e4668abc5f40e9180aa10ddce4a5cc7416f915ea1c8e031b78094d1fde415962d6f95c5b239ddedc75b339dfd787b515e9d6cb318a6377a33180848c801d22dbfb17ab2a678f83f393be3d4df84ac03cbfb7cbc32076313bba23f3d1d5901d4e73925807634927a523a05dbf6a20a339c275f09fd794ba148bf4b877e23ec53d7947aa8205b1b8703436f605943f9c1c1551860dff042666c355bc823088784551b88450a53ac124e7db84845357a0cc86103bcc8f4c65daefda4149121ea257b567acbfddab12d5a773d64aa7239af89a2f1185a244602bfd338aa24ca4208dcaa6139c711f6a588da1496005d31d19b40c06f0ef2a58261569fa68ea7e217021d0fff1e0202a09226a44550d25789d85abc5add375f397dc17727af17e408224c6fcca149d801758b26e2c338e9c517cb04b596c6758cc0a3c28d9fd8c3c1757338a03c327abc9d6ed6fd3de32a14fac06b8005d5cfd0fe9904aa0b1fe12d8c8fe8a5449bbc7cfbcb1247397fb906350cdf55a4b82360eae07b9f55b3892aab1ccf7e39f6cecf2dac2e4bbc66c77f9858cf2689e9fd8de36583f458f0a08d9fdaaf98cba6d9cbd6354ebd964103e157c7e627f189666ab1eb15a0c4868010dd985f183f2959aad4742d291e73e69561a59122842b4848049aaca3ddce13496658e0f1c4b6a9c0adbd58152336ff0d97f7d700aad2dcd9edb0df7086fa08192aa20d67691b374c04cbdeafa7208644c89a4600976208201307db21181e151717f328a52fa580de60e83e95140baad0462a93ef7ca662c06bfd933203b554ce8e3725b371cf11b3d33cc79523b0b5b5779eab9e816d04456fc232557b6f522474f467b5ff126c1b1ba98f0c8e13f2781db937ef4f31c5b63fcc62cb8dd7418c0fc06ed4adda39d131c782f19f602e46d66d7bcbfd447b3714b8343235d4afe537deeec0f961381629dc04aac1fdc2200b1b60705053955dc7643599fa8efd1e15fcdb53dd9ad1b008d5a0a2ae3902dd833efd101b79edb4ee14081364fb46ccf3e5c1ae678efdecf02029e67db95f625b845d2682a5571e332bca1b25cf0ab44e44b5cfe3c90ee175048f2d156270e2385c8aa828f6da8f2c5f7f6aa7bb2343f4b7b312711d0a4d391e077e8e969279022b38826a6255aedc261cb1f546bcb43c8c16e01b05a104ce9bf2e09e17acbd5bd50c6207249544aa3b44d259bb6c663ffeb12dfe8bfa206c8219badc5b8b684fb2cd0fa41096fffababfff1d135dcd96137092feca89f1e1e7d7df2d043e05be23804f796925113b62ada49098413dceaa64b62183"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "00b4d3e45fd4534b6ddcf4b787b87b118eb352c776018b895bbcd29420dd2e556bbecc22e16c385946cf0a624c72df66a1a1b2f5c55ff7570c156955f1e0270a67b42705067ae8a774e425d831146938fa2b3762029250f617621b59a0971781316b926df1d8104c84082822dedf59416ad008e674ae5ee3b5a0e2f8ac56232e538b622a553f962943858ad02bb903a7e83b812fd5d24a7e926b00c55c348d8678bd8a99569d8d7201aa147b021f1729b645f2a0c146648dc98dce4ce92bc587c2fda470e18458131906e50eceabd8772f5c08b9f6702c8c08c4c92ff533116c6c4611e59fe0211e61dec8c4d4692d011487f18b61f99ace0d1a366b10130ea1f9d026cf376914a42c297359ea38fcbddd10886b0af48989ca6846634fe3facae519db2ef6f2144c46e48e1d25a94b251432322dc9c9ab67f91acc39a89ae25612e6dfa145d4f854a8813a97c3b6fa02041d0773bb5919392bcdb4116241b1391b33b2586619f9691f53e5a997f3ba43e57c763cd5265a4d946109d3dcc419054872ad1b45c0bc71527dd0aaaecfa50d0f1f6530919c1e9b339118679f37ed00b275ef1e08c89465960a8c495f0890b4fd446c482f3a79798d226af30c6e4ac390febde51971b52c71673b32fe9b166f2b03e1d7333ddce7042e4cb7b6333c025b625f68b464d30c5af3d75b71b811f96dc632992d95d3ba0719e6ef4feb170d81096bbcad7f5a9b33a39ee5bb0f24e78aebd9e320f82bc1e503d109c5b0734ffaf408835670395a50e7663988cbc6e743723af99f98b931d2a5922fd48afdced489c723d6ee62f7427fdabd109b5c00aae6451970a2737b665cba092b650be6282f3346e7b9f4fb81d4a23b56b1ffc8a784919fff3f237bdcffa389be19e95cf4fb8861759698585e59ce35a7bfe9611abc19d5cae62c834dccaa447cb3adae00fe2780561299a4ddeae15c90231c1e5f1cd7dac519ec931dee65529df7ba52d5732f221d62398c0edc169de40cdac9c90079af34e3964a5a6ef2c15e8a9b1dc3213e41e3ba158306d4a5487aaa5581317b40a007baf9c9fc4bbc0799ee524b02950d48b4d19a514b470ff6d06e20c049da97966bc76e72d67768599ef726927433eed5b22f9c1dc2c92cacdd41ca405713142aa32f6dea9214517959f4e1fc41c99b56b15d00af023120760391fdad4e254273f2ab09525dfd7e4cd40e632c5b1e5dad494711f38bb15c9c4118eb9dfc8210a6e92d5c094b952e64b33373648e4dd49d1ae6451c1b4710754a74ec5885343ceec5ca8561c88d836c074b3e0aa8429909a8c920fa93543f9c5e622444861b84325e7a153d3f3aa37233236bca55351b165e3638d4bddf0d258679f840e64357bbdb9ae8473ee94d42b5e40366d6221957333c72fdfd94072b5cfa686b0264d7b495f90669e9d0026397b211611d6e700be423c77c4603ee115be71052bd0ce846914ac4dd31f40886bfd878955c8f76a931b51d37e27cea0ac910f209b841da8461baeb6df803481ba527f111ef92952e0280788ab3d2946f098f938bfc1f12a5635c7684f256f56f9f7660374119eec6c341595c327a3d798a9505f35e70c72cb88da03a2975ac6250e2db29575206200ebe764072bfd3cb2196f09dda07b2fc35bc4096059b29df8d9971a7a554f3518fc3345ee3f0fee9c6248d3e000cccb6913910e28aa8f03a8d80b8d6940b083b158560c696334af2f1a2aa348ef608c4f0c4542335d6e656cc1803cc66557dbd3acbb1ca81f62ac7089d4e30684cdfcf4960d094288ff1d03174a5c7141d588757bf1fc0a34e6f93f3e6f7febabb5717b8e20b3c9ac27bc9d721903b317c7772b366313dbdab9621c33601da77fa4deb5bd819266afd522bea542bf1"}, - {"0000000000000000000000000000000000000000000000000000000000000014", "00312dad99cd5e1c8c62b13a4e0dd02d358019d54804958d390494860f4c356391717c36a521d0ac82af08811a1ab545d0439b9331128756df25f1b271b7c7370a474c9851a244ed620535b6e7cb05705f1c180a0a1d0486846ab9395689555f09c8c16b0b5fde1f5e1a9f817bdfd120b3b44c66c71a685ccf6d289e390410c755285e444ba475f34330857eda40f9d6912b1c17bc057b966db755e2f171f617a6bab4a0fbde0bc001c4c7c872863804bc7eb0c1adc75a755f59f8d05f71c5f3f0626ee9d1b4700a0879f11c573d0f1c8bd30d209f68f66f686984979490f6dc05a1af9a38e3795434f32374568fd2bd7b56bd40e035d686b119a58b19b848df69c9bfdf16e9d61fb8e71965c9b693a9332852d798ef8ecbc33a3916e3ba4d9ec2fc34df0cef28978a79114ec27be85383c42acec32151d3de419935003eb696d1e5a8dcb9d97637e447937dfb1c437401800e3e750159508b53a28e932645c0bfcaf83f7b10d3e6f44ae4d073e31822d4155bf55a2d569c8da813528245eed072c8b65cc2182253b85e3e13fa2a2b165f9aa681cf7e9db02ce1f722d38ed25f0fd42ff00982864b58c40dc0ade4d325a4c18b2917132b842110d7b8d9d29490cfc31195071e6a19f979aab5769f0bcc5f445ae6e9afbec281c04325296201c875d8d521b781efa2d4f32f5cc80325ac68213d3de14f20ee037dada40b9718fafd2e522a42320fb58d4f5d400c0b5474745e0fc5dbdf01e3936f2d7109c493b53c130d65623529717899fb43f0e45c2fe13107099b79e60fcb86c9e6d970831392b132c7e7a2666546747556078ba1614852313957dfc0840012e6d4d0842ed23a1217135d7fe4639566ae623acfbedff8f7294fb51126dea7e8b79be93cff1177cad3da668ea0545ddbb929de496a1bb2b113db6ca4f0ccfce6171dd7f969a00109ad04d9cc86873b385a86ca66bf3ae3eada64241641d8dfa69894ef20f689c941e29712cc88b79bf60112c7790358ee58cd90b12f6124f02a8ca8baa2a70d9d9a8a21dd2194f665b15d8ad29c55854192f07909085ad78ef19addf964e7d50bcbeaeaf6a6dffbde908d7524746a2495af12d94d84f31ee2dd63d9a07910c7df87668a9d8273f751fbf7b8ea496c809b003211043faa2b2cc3bb6c90d59e9f4dfba1c910717ab901dfa74f75485f647119f1ba74fc1c9678669c4d781bef355de2e22059a93bf1c2604848b77db23cdf430289f9c64c067c53e3f6d0aa79aae378785224c6f7170ec5e39f1e7107dc6425c0c3d1f6ad78b4b110bf0ca427e76cc32cc8b00d93129fabfff18104d2e4440d533f88aab9fe47d68373df72ec520f3ebf9e285513992dcccfcf8294dde182c53b7d35cd7a2a6ef7fe2e7e56ce2351a9b50d6214f499e16e85654c79f2aa040eab284fc4e07fd59416f7d7f97b1df17f1c5de00cdbd3670d11ca01aaa301b3e34f81687a8cd8078309e9b7e02e1d1b09bef63105b68c4bc1eb08b6a91920f7bfa2b55fa8876a9af28c6d5bf249f6ce749be904bd11b673c89e93454f35311aae135e7b72f417d004dbfaad6a928b9b2bd617a343e1e68a0c9a16ffb80c19c6cd810701265e93f442074503aa265cd8e7464c56667eba65053f28e015ff67e688998f4ebc2441068a6074d142b5663cfa3215c2aa8adcb44a08c13a327b91ac301e2503e44d96cc2ed3a199dfab9a9a623a289cbb80ec1e6f71a7c44f76c34c6622269e1ba5704cde0996690aa97b8cc76814d8c3cae4519912d207175c2b1a84b051e7aaa3a224212f2b05ef1d458918df6645bd8fb536f7d4953081d0e4bdb8647e10311d02772a79a16b6b1ac8655d39f8f94235db5aa1427d047c7a4c62ec69b1c79ce16c75210739129bcb42"}, - {"0000000000000000000000000000000000000000000000000000000000000002", "004d8a744cd98656cf97a3c2dc6495915197d72f0b1dd822b385e4297d6e61344ad8cdddc115d70f7c131603a11165c84efce2a971b2782c6cca9a5ab58bec19bf92cb6f8fe051bd1c781264e2da9a9e58fea22108c6359763855e2ba211d17a6b4f5c9545717d1c650ac81b2ea92af9878b2062ffa91c06b777b7fcc2241843e9f705e23e89504802cf9545d329554a2c882e562133cab1999884e686b68a105a9e9bb0027fe6e600a96b5e35c7e929f57900c2fb398e40be0e2a119a3f241f8ef5117e7ef672d73fb1d116f28b321acefe04d6dce35952be03d5d47218a998eac9f29d761c840539743637116577745600d7d57111034d537accb21166058073633249b0d432cb0d4914496cad52279d1e9814b78799af6b515b948969645fb9675739000f260be93760d96e6954ba5271737345476af47de8ac2c7a2b870b5ecf87cd5513a64721db230756bacac5024099519f44f6af93ff72d70fbd6c81a288b8f62405e6c9ef88cbf513a70920d012f26c760e41d350f10df6a20e07059d91657542e980f154a619545c8ce7450ad73e89961177764c375637ceb587103f9f3cc9053ad06c17cb01a1efd660bbcbf345804e119af64a11dff1017e092f6a66f677b33949c0b218973f3d1724b914acfd123c215a1f139451fc80116c44f62eca76ca25a5d85ff3bbd6fb19fc006f2cef40aefd9db50dca532378497555e27f214fb510c322f3b657d4014f965c4360634ec173c3a913854a4d43008c1de83f6ed054b2dc5eafa75e82f6ff835af59a20ea97a7118068d69b4723e885970b68f4705df1475de57ec5ed1639a691ed128616cb8f2516d549dbfe98843720c91dfd474b36d2608bb0cb93b33ade837982544f13b2175ff1a1cd5d8e071fff24f0f9c238fde3b619b81c1bbf31f0766a28bff542830cca9e260248fe9349c60165411ed2b204c9f604818995fb426d84ca73b1393cc323e49dde91a18b30657c976ae622188eb5693816174afad40ecd9b69d154305263bd1980c8ec11a93ef6fc7e8e143015d634b5be01eeef1368897f3e8212b2b6158c3b64abe03613a4c54ffdb4fbc3ca40f738e7bc94f814eb70f76583c663e79e55c9309019bd2d389fb8a1d99ce4fdcbc3058fe6fe1a96e5993f0663bac7cfb099e76924c496a6dfedb0260d4fb739e4020315b8669759930b37c1051e1e86194a9ab6c52345c8cc151fb1c805c62c15202eba4b2d57a794881403b54cb16ddf70973e41b61758ff04d1c67b18ffda05cffe86a689aeb8a5b840a2d2abb4c0c25e54f286040cd5ac22474bb2dba07342756c37e4e12d98d2d9110279453ad11762a34e51f904129d1cebb7569bee0b3f17e3a8e266f3369d197adafe9c8a928fbf1a3c30ee5d1bc5d6a2a3d34df8ca33d7ec2a95aa9c64c60397063dd3de1cef7460962c8e5cf1618bc4d23198384699d8e411dedd194b84abad6b9a0b4cd1bdc66c0721a1b99dd118fee67e2270a04e79e13a94750771483dbe9671121798d823bb70fbed6d6ef5ca9d272f0a8333dd5db7f221f0bac12a36dc81a44a9f9aecc10ad3891687c96b853f4175959dae7ba6db7b96edda1e970bc1deee0cd3fc4d120fee54d262f89618973b387a754809d8cfd75a61f41128c2413345969e19620ed188f3910ba51f9823e23fca7700189835371a8e32e96b9dc2ec336d63f2c50927bad752b2469fb2f1177429a5fc4d8dab04748483912b2c2d252b0953ed32d78bdd40e5a863a55c973260742bf69ab0bb44930f32efd0d592b9dd866012d705a32ecd27dcd34c753eedc2ee2a22fb9d8bf725c4c9527eb20cc4148a6d17d25e35b18dc259c6cc783abf5f5c42d25edfca7d1f42a28814db7cd2f5ded48caea759117add16225b"}, - {"0000000000000000000000000000000000000000000000000000000000000025", "0027319d33403e08c63db54ab050c0062b07b971951e2aeda6764d93fbb980e42c4c462f4d5a495ef80b04c79f74c8369c3fd91478677353188663877d7c49108063ccc515873ad336216a947347f0b20ad2c31f29e8f2104964cc433da6b34b96455d1ea947beea0537a38ee14e5f4eedd3ad37105eef4dc639805345d72c2b637415aa226dc6520323a0c4b5f160631406532dfe3287c19b127b8394a4b5862ca945e8ea56961704c0dae6c1de326d990122565f727cf89bda51dfff0685fb2db9543eeaf10f13f5e4d923e9d85e599a7c218d35b172e2b7ed207cd2b01dab388707f7da3bf3476be3640a9ac94fd2fb257b49c9aac208587dc7fe0edb9534d917d27efbcb55543345b546115ed31d433a0843be9be40ec9c13294654c768ba58a704e7f2e1c283b57c9e42175aecbb6032d5f92bdddc551260921aa2ce62b93119c9a947413deb09303329bddb614062d2ec1f10bcd39d477921b22ec939e7b2c9b59f958618457802f61e3ea7bba0e1c62eec31b741e94ea165ed666cfcae4f27fa9d410d54cf77d46b8cf0618179dc63e6ead1e7d7fa8facde8d6e3cb36aefe586706cc3e204fc666a0ef26a2d19e298bed14c8c8fd1e5650c6b90bdc55b77349896da96eedcadd9d5905d11cc092a7df135870c8d0c30b61bd04396af811ef611dc7349c5d66e323ea2573f808d171de43b6bce22907327f46cf8a9aa5175e33ac29376681cbf35214c63b51ce17b190e787fd74884856f36c1e60fe5f28930a1cb799820a09c11bfd33184bacac8a90ee760fc7134ac5044767c93751ef0406df5de772607c9914e31697ca06fe392e39fbce4c6177ef52c36a325e98856f3b36d230b00031a2a61964f256f21ec8f67987f519bf7398c54b2d92cb2ef43957f81d5a0b1fd913af19d86d47f1178e5310c2e76b7eff849b7772bbbca1012651fb46ac1117b2ffb482a15771df8f67fdb6c52052fc6bfd92cedaecb004da00657795b73c9e132301fbee6920eb25f99927f0ef1a3b42169e771b27643e09b492685d83239ec3b3f92ce0dc611afdbb1212081b7e61a84f2f8510f030cf5f75bb4466da7b537f2a397418f554f35b2a1c04e5f4bff55ec50638d3b10aca9517d41a6f9ddddec658725c2ea6376c9adebc4575623fbda0378d50aca4f4e04d0371e9d7119b95103b7ad01c0f5d7f3998725e7afe36d959e77d9cb3319cf54a18ec4315971eb40a1b3f81b253e837601016235193d0273707428d416ba51f2f1d6f46b6f7875518153325a4038977a2ba931fdb50774856fa6e5a120bd2d79fcc0e571300e6a7043adf89d0327c6a631df5254ef027743fd521f7353cc581bded4cd29ba92bea32050a5749cd503c431f97a3280199ffda14f33f91eef206de879792be081aba684a5e4cc2991208039d298085a593db344dd351f6f07996745bb56d66462e7f354f9c68439b5fb79453d542e1fa1b56e27605e09de43d55f39542065160c3e95cc21fb6dcf4960ede7b45572e3f3d73bb7185140cabd0a6b5300d1206dcfc4c1f84809bcc4a73e00b3965a58a6c4eeb361757d1cff3952ae76d33032c025935125790562d570f4a2d2e52209b6f864691a08bff02e0c7069bedbb4dca57060dd43d8740de07f2dad6090a849eb94c9b05b04cda950377881c38e5154fb7f5b32e1cfc5836186b9c571217b607f41f34d95de62e016dbc6e48fd098445f588d74783475a02fa681e1291ecc3573f47226615aa7752146f0502624af6c8fdbb3c9e5f91410b6a17cf90ea797fcc170762d37c67e2d5e55c897f16f06bedb51064028c9f8235e09e483ab4321cc3a013a4f784c9207f1f7ec3814614439b24638c15169246c8fa938fa84bff5d628705f5fd5fbe29d9fa1547"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "0005cb49890fbbe1ed60872c58f31241d0197d915d36c3fcee36ce5936fe3c495593fe6157294efbb2330ad15a4a30041898f8f8311a7bab44e4adf259854d2b81cd035d97f65127526425c94bb10d6051d8e67c17e578e1f956e16ff1af6333a9d020474fea3e70482e024cf5b350a97b1097b371d3616391d49c75fd3d1db75ddbfad85308ebd1334600ec3cd37937fc4f6d2d52feff5e0e73fe756f2548be3793a1f2acd2477708fc2c5fbe129b14e02024afea5162017961b711ad31aff4b64e525b73921703ec302cec99ae1bfefa74131f6bbf51c99da52d7fa4d282b145c2b7897f8f661af998ecfe222005882f827a4b1a166ab013be084e09fcb705f50ab19922e4674cd070d6825e3ed37a4a1cda93e4b713208cf2cc044aa362e102bd8db9586819e35ac93348e06d6db689742174f53a81961c3003921347ab7be5a4013fe53b3e7efb4d7312e65befb7007b362dc0441d6256eb4012b4ba5f30a755777d431aec1583466277d92ed8e4a5a8bd01274b79fb437910fe81a7e8d07c02976fc8d9436f6d125c78355d201d8e0ef26dd44a13f465e41262f60389f58d76b404124d0eecbe09a59ce24a12d97026e984be9132ca9e3dafdf459f5892854387f6ba23598c62b24dfb43b812d118eb75227cb5fcb7c2334fdef36d23ac2b907e1cf18c92cb87ee0858bf65b342daece21e2d1b6c7901b756f29b83849c6d252186c1fc5824805cb1a4ec0539205e1f1705fd0f1ca3cb72b3f92a39aaf87d0d08a2b494e1cfa6d1226f856399d7060a80ddfce7f43bb3b2f32654e09949e90500bf64893589579e11ac063b5629fe59edfd4ff103f0727f84224e49f514e81c669497f4189af9719d3231f3b8e37a2c51d9f0621fb11cc7ea52e3f0d4b035070f318a6dc768fdb4623cd62476de96439ed38834bf3075ecfb44621f38c200c7c6b4f70c436ca208d2ce816e7dc710551fd681035f205478de7afd46b183859d29cc221583bb7b5413848c8149e3dab13a0c54306c356489ac577149282e9b3b7cf417ca54c1d574e10f5327b6785f5d05cd088902cfd7162c2187b5f4a5d36391ee0aacfa805d27173ac325a4943db540e442d96c14920313dd41d2134fc5131355b303f6de852efa7c1d617a77987edf2130daef934da0994b6b6657053ebb62eb4ede769801b8232cc78952c3c73353820566ed32db1016f37a3f4fff0e64d0a7ccab98449ac1c20fc1574f5f1faf10243be3ed0d4c78893f73d9004dfd9dd9cbfa192e10fdff37d492abd3001e26b08fbed6ce81425cb34d02fec35a1f9131637b15d1dcc6f5dfc28d07168d9c431695dbf934fa45f9dd277f425534070b257cd0260545acc333b5d779fe13a098f649414cb3c0a8f78a5677e4346b2668c3b588f87a947969822497f34f9300d523e4b4c9301fa0c8b7df825788db8b60de94f149c94e536bf7724deb14b74984ef6632e4cd997b420dae69ffed044793dd91eb570076688393ff3d87f86c3c3f70cd9bce09371908355ff84f32e52dbbb8bd0d4ec96000a40cbb5314d59f3cadf842de3d5dc21314898dce76e40b1b55b1f44747f867b137cb71a39c1ba15e7a3f74af47fb6962e65f4c1700f9b1ca5cd82c05d3d511e3dd55a6ed46e6e6fb1d1e065719eed1023c401a8958b40d374820e4c823eeb9af98bee04a24c2bc96aead2d0dfb51534ba45e97aeafe09fdedb0679e5e55cc957f3f3d7f479206de77d4b0eeaf2b23f7c82343f23ba876e863564dee452d1696eaf4a6507218c64d84342f132b791055e913970bd4c6ad22a368c0f8d9b936a17e8fd757e82c09e818dc0d4974c0aba573d8e8ea4a4914e027491d0c6e0f9d26ca6610e5fa24d072badbdc75312399da890090cc1f47446"}, - {"000000000000000000000000000000000000000000000000000000000000002d", "0079283d17c2603c55e540feb3fa41b94d64589c5901b69e428e54993bff01e0712e7b4ddd5a778fd98b00ce35210c0e69b56172506713c5ec507f51d3bf390191750d1522112590a260253b879be5712872e9380ce782bc5512e64d05f25423af49c751aa1916ec68198faa507f9bfecfb06c12c4e9a08e8d8c01f7c51c1df9698d5271309de07aa1f6707c7341fff9fa09652a153ce2e5b1c9199c6813304bc16844f00d90531400ea7ce7613377cbd2dd238560d1c7018926dc278e11fab1423e98e7b92dba524cb5e7ecd2646518f3c314f7ec23fd0e9f4525723580d7415de5afd9f8afa73615a658388e03f6a619845d974d1b353d888bf77e027f885017d30365c078e09fed11f999372c796c1316a99af4bba29f1bceb96cffbee81f2b46a9bdbf2f2ff7c6c98e2293b7748fe383246b658cf67d7060793dd206a4fe91bd4b1c8a48d30e48269a597dbbef150439d9c69f4780be6c5d2cb7466f27af4ba5da798b188cf32f686ecd81a907e8844566698232c9bdfd2304ac5d231eda4a68fdeff3bfad3d39419cfb9a059832bb2a00e7108d6991cb36e5cfdc9369eb7579d72604bb284e7143d5007243f38dccf99fab29ac1e767c1078caa048074e123f95fa7b4ef1de06ba4a5c81c8067a61c613aa83d1f298c454a5bf84f24c40bd0ff406a04baad15b8b8ddee805e0a7b0433b68eb5eca3f0a35a5eff9528523f679182aa5513e9f6658df6411209793cb309a0a2d33a0443ec128d779543c9ababf1728473f2e1227b56364523bcf74d52e65e4be1f7855b5b5646c597d5d540d955fe67b7379a39d7fe6b010d952496990a268c46fe32b72757d50d2c166bb4c176599bb526bf6b9a592a5ac57d4edb57ecf1430ce14ed354ddfce3ddeb6ef91acf5c192c17870dbe2141d243c4b0d4a215b043602211030cbe8a2acdb2c05009d28a21e1797edfa45b2a63fd25eed657036cfef56b7ff01371da8a56ce0d9599969a95adf433dc2443e8bace91c54f8d1ec58d547f4f611f6c6e41f149a467c243067e3567b3e5b758b6ddc8097ef941fe489019336647d54e87fdf45d490dbed6119ee1f1b80412c828e383cb36d51a137838ceea3b888f5cc56fa4212c2c514d65f4c09d244e3ea84c5254aa21cbe64b920a68c0c38e1e0e77e9fd2e7c86e0e08e84688a129030bbb3970c8f6ed4d4860fd9ad4f92542aad12e23071a074cdde459357c03534302dda1ef3fc87e38090c0d61f823e98f2bd99c5570707817d5cba7ffa7ab11397e955e5f13e12a32441ba47a64166daf56ae5912770975444d3a39137ea35d1e36353238443e41ea1ab56f20fc07b71147eca273357b2bc50046dd8d7016418f1ec306c3be97668236d596d18d4fc70e351040fe9c828a6ffae9b608b622f26df589afa576fa480216a86f0682dc451e4712cb994ca6cf074c1a87130bf8caf65f4ccafea49b70dd5bcdf0a4554670f3b014dc5d90b05b8c1ded9955bff2efaca3879e5f9cd74a75c76413aaba61d797c57044af0352c8d8f9d5a103be323afa53d875a8ad03a0094a8d8f85ed1d4a6505bb472ac8cf7252f609f09eec7262e3a7abffae0905ac7afb3f8881b1b00a352edd3272116ae6ee2060266e99545a938f3cdf45b47ce06c3f755d37cc912c03c100225f362ee3f15b817c11128d1aa209bd51830bd0fd69b7a4f7ab7d57b37f9ae4d8fa344196f1cd249856dfa24f7e23bf14fa83ac54322efb2bfdb2ee2ce466b12c52107afb1162ee65ccf22711b5fc793506f8e7df08666f67bd83c3d4703eb682249b7a41630ffdaf0e04dc2053f298a3269ecdd3ad563a95343f102c8260005646f6b4499372c83e6e19e539db870f143d30ce549b59e567d466f1efde59625eb51a5b88"}, - {"0000000000000000000000000000000000000000000000000000000000000076", "000be8f3069e2d41840af4ad792af3ad9b316d18f429af355677e4cae5e224134bbf2eee21c2c331cdc10347b24c4af87f2bd477109e8e57272d5985b43c621feaa6af16ea2c31a7faf36874d32185bb91fe0aaa0e450eb4b1ccba1e7a97d106e743bcf5695b903e7d426c76ae05e6522d7052068973ee5a2dfdcc1507c23881fdf5759043ff8992672dc26ea95e3aebdfbe473ad4cf0e0265bc4d6b7a56bb2958d71ae92b588fe003e0472aa762d977df0c62b39d51819cb6788a316816f54bc6e998c03142b24262d0eef4d946e68b9afc0e12fd564f18c0dcc71ac3fa3120d91e284ad337285fa7cb530eb570aff3fbf932fdfff0d277d39ca5ef0d426aab3649117d9a58d31c35f62944f20afa428a194e748cecd1e4e6fd52f4d90a63f4214f62bc8d53159b294f2948c53c941d87b7926c38129686180a412e5b74678694ffeda791f7e21fda9b637982bc405f02a56c2eb91b5b3b566c31acebbca57dec4259e6232ee296fb3e4f098786d658302ff26eae10c71554b00b2246161450f5d187261376e2b1b19dab5236ed6d0e27249a62315145b093b0ebcc993e044f07ae291004585d90a75e46fb4598f49aa76ee252277999ceea0fadfe35760e4121c62c2785c67e008a3e74f220c80bcf21ea5b08908d709aa2080516187a4723f3dc042502834dd89f8139a45a04e0365226699a37bdf495059f92c769722f77c94242484f14bc96c0aebb9a660991cee144daba431c3b553622cf2056e586f80c4d0ed3fdd1e1b1d991e74d12ed53d773ee18c5fbcfe1340d44b58019e2356112859958346c260ead90955d05c8a2e79f4272a66a2ba2577e3f889d41913baf260b2f65fcb4d70bc8ced173180938243af1f39c4a1914d8b2221abe36cdf7f431c90c51dcc8c78751c5161ffc9d4fa663927fb24205a40fcb471d7325af6dc2002b46c3f74a4ed931d360f1acdf1756daacd7661f1bb809889ba6e6e3c3ec22700f1f65658f7492e50410a7762247a351cdaa4962680aeff6bceb67ab6ec6113a2f1c5a0ecbbb0066a7bca65c63b2a0277faeff069949ef496cc4e3ef5ae13c33af7c95aab3f4e58e4c898533fc1fa64dcb86c97ac75982bf5f3b9d8d8329c37c9ebd4b9835e708690eb36fc10e614a39384738a59f5cba928edba032b3f68e562429b2ca1b646e04df77be0909c2fb3de1a11093c427c169c076da00222184e01e4f7f48ef2dc3c668ab34bad5f27a64a408052a85c15b91536a220208ac5cab01163b6dc2662afc5663caf48ab7be83c2ee3f4d01c51fda36c19c1c35da4c3388e2a728c4d23d7e7531e3e4faffc53a40e8679b5497fc411287d42ee355b75a15db31bcf72396156c68b3d115d701180fc1e3a3fa5a7ddf95b44082dcf8ec26dc1d99a2251e7b7c2f168dff9bf4f40140db799dc152075a7b340d9b4b879126803f6f65084d17b4c32c87a9e60200b52230e91118c371ac4f22ce5f2b53628f5d704536f9a350b29ae88258f3f131565bbf109e43815c2126383838d9d6134f1e1bd602e8b678b5ab508fb741809fe7cac6c88b7ac4eed0117b867613c825a8acddc1f7176765ccb1848c02191c286ba567166fc57086e2d360b92eaa0a893b89812ee9ef58c4abf841c2bfd3c8dce0a3ca41a91c0d9d0536d45e2742d395be42f0d6e890928e42d0fd27dc084fba52388af6d9de6ce45816bc998e44ab589aae063c3b9ca442012186cde20abfca9ae536effeaafd192427d5638d3cfef1fbf2b455acb91d48fb768e9a06c484d208a9fa6756e385a917d814ad8e2e7599d42c53d3beac1031fd957f7373017556a60f24f3ac4806ea5a3ce5d4718b05b7454b524ec97aef1839d39e0e0a07c96b9d0023ed342133abe0686120a35d0a1a"}, - {"0000000000000000000000000000000000000000000000000000000000000002", "0014b7063799854fb8a070b8ab2921ee9d5cfd845610453b2c681a443b7c8222afe24c960f25ff5a834107187da435d1b17f1976f18867d74c629cc81b9c143476adec85aaeea1cf7746c5d4452e0b001c5b495b00a3c007124af6472d1706d6467f7005f3affcd9de4cbfa72bbb56287ccdbb45b1bfdd4b921dca1d25a70f61da071fc5a7bcc48187a7487ad0c645e79887d41524d6f505b021abf601b2452cbd4a38cbbd48e6140083843fb7c9643ba7a5233d667b0aa95029718c042a692b770f6e6ffdd52555f97b704d3f054ebe1cf21306fc016e8fdb4b7a77f7d7e053c5aa858bdca429286aefa65e288955b7fd456091c4a2f204a0ba2c7e021870e50fddeee713f9c1c002fa9584afd02876e907d2d2ca5d635a056b4f108b57416d1502def186c40ea86a9f21210e81c47993b06668a1ff482b9be19b1101b6c3e10ec7ea94f6a4648468f0059832cead50004ce3575005cdc86e9e52e0934ca055e3c87dcb7f2e1e749fba91102d1fae252414f4de76042fb8bb4213441652a3cdd37acb2f92a0ea361ee8da2f9227351f03ad92a5b1b2958f95f5b114597472c0da1cb325043da101088f376deb5d32d407420cf9ad02b385833f1ce384006e3b2df0a9664ce6e485e7143f7cf3f40834b687eec385aff1b243d8d33485567e55bcc24b4b3ede9e7c30262392fb761151b7ca4e6bc19e17c302582bcdfd1573b1ff82d3289945221cedf6cb042e2501563db625000979ebf7511df7616a1e823932590587c6db394a7a5706d752f6db6e0944f738b10b322cad0ac02e50b476d0855741d9d2e12644aff780c504115bccc07a9d55d9c0d1c23b299639fad516f9fd2322ab81599c7f95ee2f691db6fc7e1738203ac56a052ecd19d7a9b647e8b8229595ec4606df711cba8907b54a863669b9c952ac84dbb2f266de83301c647902f08dfa2b0d8e777190d5f015ed98368f8e181ab407d7d16e5652243ded8dd2e23d708b6d43b7501d2409151a368197c798d3abb47d96bf4119fac1b3fdd775475cd333667c8dbd04cb207b6ecadfa69b9d631d06643444fc4e9d089844e44c5125e04d2973d5a5271c7fde453fd02cefe15f14364141c0416e08ce9a0d0a8a09ef410e3e0ebfada580d76270028cf4177ce3170a2f55ec61eae35e19e61f276524cad3bebc363903965ace871b4f1b508e33bc2cb01c75cf2754abcd0da88e17adb0bd9fea4b647ac87eb3826f6b38c8011c98f7aa70d9d94d123bb2b45f29b4b55efb7ce23f2ec47d4473af6ee7ee28e52d1c3400c623ed1c073016aff96e8307ca3753192375b2d262a65cf8bb532c4a164b7cecdef1a542556539ad645aa2a2f7bcc6f519baeb84818d13f4ab4383ee53337d47ceb27f2cb449a4166bf1e4b8c3b740068dadd13161d8326ed9f50409073fd891403af49a3087b004c98998e21ddc9122d991de070bcbb9f33042e503f3c8c8ea5f278f0f153b357a821842bf62ef329fac24922d9bd0922e842b08dbe58899092bf49f138939f04afa8ec199a1d5120bba186f54d221452414f06af903aea37fbf0a2e5b2ee323096e2407e20669ee4fee91f2ee4b9dbc551e3252c770506964afee84c74e6b845de66e3851852d63fcf49bd7c24d819a83fcf365482f8ec41c959a0d73bcbf4252f90c98c112b2eb4c0641f0021101fd120ec72969a0a63582e454b61470e919df059509b92f71c6e3290ddf26f8f7c68fc9bc33e6135e354a4e30ad2190f111c709c04d2707886fc7ef471c1dd9ef10ffcd20ed8c351f614a02dacbcff7f7431eda65f43cae22c1fab2a2e3d458053b0243a909bb56b0126e2064dfaea0a17b194d1c62292b1ac294b71670c84345f963805061687f8700a48004cd0385dcfe51409e"}, - {"000000000000000000000000000000000000000000000000000000000000000d", "001b30abcb837a1ec9e513cf6347dcb1de621eadbc162046dab8d72d25a74d148ddafc4a99a276b346380a74b0c72fd6a43fd56d163d7a6e3c2998a0f7a5152b055e1aad13e4eff8b6c5a8d4637cae54ce792f4e03173f7ccba5e6777f129548b3ff3755557b1ddacb3e09d7b549130021ab7263f13bbf90ef53285da548052023ec4bc3aebefb9e733de71bb0d1adce90fdd50849c8cb6f55eb2b6e81e29a5ead2c1d91dd15ec8e005cbac67c21affb2b91e0ea71e59e5e46ca53217a0e78db591310703f080ea726f7ed466637e0127e781f3a23cc8a67d1ebdb90131dd2ca766e76f215960175be87f113e22577ee3db7dbc748ba6a86ec1e31671f358628e291baa4ef502684d947eb92413914c8662e773b9b8f66c591c477b416b8a5c5a14b3c4b2cac2e221dbfe64f0c67a18ba97fd374393f44e61d99a14b9156c5626a8b456312e7cfd5c5463b65d37f39a5018cb353a5cc6cc5e5cd83311acfeeb5ec0c19a02e0fbeb8faa1a7ff375f42610e0fc989a557293d68061458e318f28c9ae95a6db7365f700aca89c1bf72622b21b444f558acd3244585abddebac21c53c50cf7f02bebe2be5d4c140ea03e6abef6f22bdb485182de4355d1279cb94438902df6853d65e10ae9c49dc7d2d1d15c152def826a3eb91f79d22f7439e4bb43f67424993ebbda26a8fc58144f556b4482b25d8f8bdd811027713cb8cc691f18c4462db66ef39f984f94f86db0b9a4725d0139c616eefc42895e2954d9d5c2de5f202aebf36e9ce636f274ce327b7e67e7f038b5826e1056f58af8edd4c779e6a24b1f9d2f9de15c11e9eb902c33ab3c809f5e470e63579cab87d1d7b9c4da16e301b7acbb3589f5cecc0895814ee80a2d80b1c02fc087f7fae6730ec41b57dc4aa4c71eaa53b2e735e3418183476b09b37ff8729a5c1d7402dca8d96daeedc00649f2fcbb207d1e97d224dbdbacfec970cfab2120a88a79c990579b7607712ad05a8444674a3d775b70248a6fc3262f269fbc547773d4fb9c74d24bfc54e3847f5e2df5bf0bf076389d5b0d7112f307dfe1a8e0e160d99a305ba7a7125a2fb4f78cc72640f186ced0ffd4c494b143b86b82894abe5393c8562d64dacd318a2c1464bdfa797dd4215395331a316db7e5a4e5d1ffa72b60952da1ebde6422448227d5dd744b620a701e6e974ace344d38a489579a3e09281651bd64da532da4eb018d4ee28f560f667b3d0817a728d741fa90cf1d992a08fc1c7c9b8e610194e174a862c547b201d83f70977081e3050a5c558032e6d8b88443c7f390304d3d27a0b2461fd8c11f743d5a26e03903854ff06b0364087906d6e938ce4dcb93437016aefb8f4fb04c44bcb4e977f6156d00385b93d48c9e057eff9a41cc678fb03882b897a6f321d213234e60041b0b43f0092dd7df978e039dd63e1ad6a50fc816d0e3639b6054e3cd0b8155cd4ff0b32f546188f2e9c6256341701a045180f6b0abf5e7db87ba9ff9c8a61f21865ac0f69f6341f5f5c756d5a067a03edecdf4d9f9ed483080e79d84d42a39359c100f892b17d186c5f89995b0b7894f6c161045d2798f6ebf1e744e6fc9e9cadc71471a3a9993761c9d0af8271a93c6e2a715955a3d623d03e6cb0a9e40bf337924e63161df703ffbb1b8b0284ed74a1c7e55a77ef51d584229ceecb747a929d32ca8673e514730dd1cca3572f9e6efe6341bf46fe1e2597c10c521b718d46f2b4811b7a20e9492b8741519e2f748970a1b5f40b06f395f31c5a116357a8781e40863a066ade0dfabd191064f47cbef0d07947d92360fee6c9ed41e9d401b9597e7d3c3ae0cf9dc4c352e6a7a8c92575338962989cc2f727b29f41352f0675c2ded18fe05c134cdfc8707063f10f246cbb70cb"}, - {"000000000000000000000000000000000000000000000000000000000000000b", "006b446880e0536bf7282041cfadc1f9f7c8b593670178892734551c4bc526549a90e45d7e8437f5bc871a58ba1f9ef95953d9ab929b024aa6b5e7e4b2da2061843c81c99ab4171f4d7b0893765dd787851e31530121274cc34eecd59ab56593b4e27cf9ccded9cd5705de9064c756c46949010072a0d40b45f45099b024244e4da3bc6c718b98a373abe258658a83331693ecaf2a66ede9704995c7c17cfba56969c3b89b5f5ed3022ce963a868204f7751117663732a19b5c3db43b740e627433a59d8cd684dea348f60701ffe88bffbd907a9f6626c4ab604663e47cce56eaab672937b77aa270bab062fdcc87b4cf413ae5ba40f430e787897110f6b7fd9c976801fd29252bb0670fb655e16b8f57c1124ed7636c98a0f11d1d3d813a8e835dbb5de9b201f3f870317c7eda77a1c2679a64d746dcbe73dfcc0305ce27cd51876ebc01ca51425336ba1b01c2df25a0160901ff01db14f47dab6890ec16072cba8fac369078c13a1ef4385b14dcfd231f6f817d7a9d6dee1311b755b77be9e1d7da78454518e6f9352a2d07a9713561a1ad95a3a1febdd4786c27a4422f628ce938b9a05a2e9226fa75ef16ea07272eb950ce16434781a3a0684dcf784e8e8d5c476287b6ec7c1cecb07b9e9e106f2360fd553ed03c5544494d06a73aaf4e39fb24d2d14924b2b8d8dc8cd8ea6eec6c69b5f00a27caf840d380df3a4633bcbb98bf1c333c7c71534d8130e2211f11ac0c65dd81f55349279dc42cf6a2d673b302e0e38ae9483cc0441ec6231a35e17a0346ca95f3cea55fafc801b23a28bf2923713f15eaee677811cf56227ff924d4bd490dfbef8a85e7a70e35e44375e07c82dfb3fd9517828ebed9775839bfa64c68a269c85433908920f97966442e0ca97371cd969f62a907f788656f73f39bae574e764b777fc546d809a29a4f3831001366f9daa10fc73f714c105ef3b19fd062e9650071c557764ead388a52e65c53dc0c23bf56f883d70b507dd72039527f73ff2f85541ad445136228b5858ad14df4dde44d481a8d6537240a566ce10ff21f6797b0b211d5876c84a369d07425a81f06d2a524d1930c564d9b4dedbe2903f7993278df7fe0d1a53a8ddc6fd16aef3863519dacb822db6b50b652d15b80a37d83d67b0b669285a30b7ddb6a81be1c8defacd56fc916e0619e155430c47111932a06fdef6bf60217b5a30211b1bd3824fc7eac58e57c1de4b5cfa372a275f2eac0d4dbc81f0c797dfc59b02d43e56ff6a64209a5de423d86ab7d26a84ef6cae73cdaf605bf2a4ed78017c0bab9663f92ac3dbbdbe52c74eda756d2510dc6e6b309321d901a7a303e544c63549cdc99a8c977ae85a268e855ef7392fcbeb00067bc360aa26d46558171f3dd653399ca8c5a164ea6735dce1609e564e1b70b2042b7decf73801a9c3ec4289d47ad1f54cd131864e4001f4957d515b0f0d2bb9dac9dfc02b284d3f2cb904d19bb12f433eec96a661b2c036d5fb90607ef43929008a4e2c69c8bfc6a1451d0bec4c2eab3e7937bc08fe69a585a4a26ffce823b949ee48c5131434141d1923d4fee324e195b77394281f2a82d144736a9aee1265b74e5dca8f2bed0c84d32f4acac9463ded6857785187162fa7a24ff071e7950a67874a0f71f1b117053f8d55794e5f69810530e6b09f1370a97a776fff0a3eb48b215c434d04e432d7a2583656dd15b7fb3015ea72c743da0bc2d35582b0182cba8d0d1b38ff4a1652fbed589719a0fae072cb9dcfb775985e746e7212cbdf6f59d73cd55d8505960ebbed79b82a31f375338e47e59f16386aca4297ed2864e71664385579241867ccdfad8b6d12c03564ff105b2f69e76d75aa73240811be6f0bf0348e3152e63c402ce70b9f9907f0"}, - {"0000000000000000000000000000000000000000000000000000000000000002", "00207482d20c9371ac8ee33f6f642eddeeb13a74e300ea88538e0372273983b4bdf5541d1143e8705bdb0172a69593d236b3d492712ce2cbc76a1a5f3b677e47177589a915684d0b3ce731c9c135d2a67e3ccf680177fedda7abedef9c20a6473556da9f3e02bae08d1034cab60135c83fbc42b38e8b1e840662179519e01d803c6706a80829734212cdd93b05c6ef5d9a44b11f770ad4a547f2e4554ea2049fd615ad9b44f8b87100b0e226c5d466eedd306047e51443ede9c415a9bd0a8b750dfc7c76adfd95f25fdef595fa26b814ed830d56fc51119cbdf5f1a586d024424b4e13bd151d9716e5fe431e6429473ac06428047c1af6eab4178059012913276775752bc70b73fbd0e6015dada77d90bc0827f2a22487a2bd8baac29f599b7fddc7ecf9ae9f2684cb7f52cba2bbb0073604ac58ee9e11111a76c3334adc491e10999b7bf9c7fe79cddcf6959f3e1a73012c79f67ca827b1a6ac40cd143d1bd86d9c24d9851b79f3fd83cc9e8393f4b22fbd56972c8ea8b26a151203a68ec86101437be57427b6b2cce152809bd4e21a1fef9e6a0f8d3499858a3ce6f1850bc1543f65b4022ef6caead06f0bc8d5b2f70c99f4f50ba25a7af20a68d20edfcf42df43bd92a956f9f89928b8576f4130172db37c56c1c7a7a735f895f2a0f22fa69b4fd635db7c370816bb97b94ef5b75ed8d68669179e0b1d021281f834782053fd6898a4ad69813a2a3134de45309545ef9ecf6580f154d38e807b48263583bda821097f2cc03d62f3b9985bf3aad6e1653a2efe1ef4a81cb9d257eb104c251324762f28d72b422cf0d6320a0615bf644201d54e142148be07cbcbf22fea3711ea20557d8a4149a909f484e2821995f24f256e99bb2409514f15ddd6dd56c74082d509988fc550f53b508009e226fe5bceb005d76d8362c9bf6208db486d4bfa0212559dd04261a9b2b6e8e24178f6665e9f13949002a120dc37e6e76f96841180235a281cd454da36140894db242c0a2cdc76b812abb0c1a0f662699d55690ffc0fa7d053beb0d4ceda0d11691cded3aeb91c5e0c353966468c7c67466c82908d3a1872fcc67d4eea23458f421f53c4896652866e016f3f079b405f74921e44e8faa9a22bf736a5359ac5cc7346cc295ff07e20889d2c26efe4cdda1d82afb117b1ae215bd564b3072d34a05286ee6b9cf711c2d82fe35da15a8d9b4d379756ece560328176eb1671926524ee773159544a1339a7db5f5bf619a9e9e6e599f6e61f2ee09c8b38220b2d06e1c9b89f4e3a4b4730f72faba44c3de68c233d265ca6498a8fd754f379f6ed918abefa373ecf27cc4b0e71645227d92218468d64c6a70c59f8b91b36fbfc74d7f43b2ffd9a564551b648124d013f9bfc3f07024323244e396214f48096c203aa368957e70505e1bca107c5765ceed495d96cbb77f39da1de565f1c177fa3de0f3c2483a6d22da66f1da6ce81fdb0d00e6f25e9395f599d82ed91cae2465d3699d41adf0a16f20ce21aae2275a2992871b0f5cc2ea582558a32108d19b24dcc92e55c1e8405a72c71f99bc4f01dcd194a9980b1e3f015aa4ec3fef94b95c27210d49bab1aab8eff1f59f6fd96db59068cdf464e7d8a3857071f4a25ef889a61dd85d5526bb1d2ce56979255084c1188b51eaf1b8d950330413a76298684589610d02646b1d4c840f8ccbbe4c928b152ca67f677689bcbcb22a547294fe24bd9b006a4c2de28ede976128d878a67e64e7df22de64bb880b8917dfb3b9b7ccc1e664330565db410a0154f5ef82b31c473b0ff784d9bfa305f1c8cddc69f4da752266708acd230f2ef7158e19a3bfcc647edecf4d7c85c08b767db5e23543ffc04da43c2f397fa9c973536b2c5ad78479c097c517698d4"}, - {"000000000000000000000000000000000000000000000000000000000000001f", "006aa79a0aa0efc9da0f9172f8430d93917c9dc6e6176b5af2868871915b0d435878e5183de2791ff451072acb90e4052950aa82034b324823d60deb98e5010b741e46fcdbc6651700911dfaa191cd7a08b377710a1d5584aa67b7cf623dc570d6eb10ff483e9a5cdd1bb11c9fa9b4cf77dda3b349a5dc1125cb2230b23523d3caf9f58aa5a57d964549835bcc736b81bc02cd26e4b27c130e3434d2af0432ea23ea597c633145dc035a5b45325521c0d3df51a4cf67b7064bd9ddd0bc071da705ac20c65907cba62f8be286069a52fce29b0e6811e3568dc9852416e2d1a7b1b309c6759971d529eac7a373df38dbcc67c73767ee07bdcf11f62d35096bf6ec0ea741c9ca3bb875bd5f09423a66fc29314146ef2a5095ee0ee74054d9ce2964962878bb115e0faaf5923c06322f85e7a86df743d0827d481632cb5473b461b6ae2803e0e938e9d1efb596eff4186e94052d2eda984630ec5f6c243862b078ef8ba71d57850ad3561735c507b1bf3ff3b567c213f9631375f98c0de462e35158d775c01ff1844dd0c49e31b713aee155f96d1844b90ea5d1bc569cf263c822e08e3903470a5fcc948a8712c7382815cd3b707d7ddc72b103b01ef9c2d06cfbde11df1ef3c875d04d756ea6d275f7210a2cd8212619cba17f88a0836cdae6c5f876e7e82b37bf0fd30d1b00f24f1431fceb35c2601b9fa995075cda962a0f2dfbfed4d5af8bc2d62a97009bb98b111e898af691c9f09e1f425dcfd85d221dde5460ef395c67cfb815c993f2f184a9f3f8f809cb88f64f19489d0bad2e5b74e95b5885209d4123ca667fb3959d0c99bbe41615c8eb141dc3dd2d646131c0dc523fcb16b42b76081a0d5fa3c59567a859e422ef38fe9a102477ac899f0e04ab02c3a41569b9afb50a885ae81d26586b0399a10dd9534043c59a2d4c629b0336e69f009e9d2d5cdc72f3344ae048f32927f35267de420808822c891c26771fe941d72c4cc5406f81d2dccd4f05af7ef6494db39d150de49708bbece206bddc3a562b3b718f071818cbb9d6a5af23fb035a3bc252e0f006a14d243858eba79d6986ed7a51799389fbbc5f3a35c6223c13e83acdee58fb9434f0902b90775d748c08b149c58606fd148995126675dfaf258369f34f90145391076650fbb16c5933456d23f25172b96e0cec0aadf8705030c2df878c832438de51f8cdf64c91480d1316e7b4db5785d2c5281725cebf4e1386b1da111862f4d8959a157eeb0c04b6ed2958fa1b25ddc5e727d4fb6a629cc8cde6fea47abe6733a3268739aee518b77b08375eae810ff7d4c24c3fc59a50fd58a99569aeaba38ea036d31e417ad6c765019726ec9bd042229d55681b4df6d88c4a532e5fa36955fe07bdd21024aa4b8e9faafda19f32527bfb2753adccd8383c750351a581f0d14edb56d6333082c975d2abcc79f4e020aa271850d8aa94e7fc15a9c1f3b0972474fe7d2304d057c43102bd1aa139a252a4259ca53cc40a34763fe9fca1d866bc077a29189a22c6447b0a529994c2065bf9ad7106c2afd50af6815770c6ce016295cb0116361b63c5cb6314768cd1cb77cfaa35e0049617ca0a667b46ab6ffd979cbbb882fac4cf0ebb5d1d21fe1106d89936992d1587ddc55cde366f1da92b6daa751002f9de3a1c07bd2bf302db4d60dca5f09addcd481583f0b3bd9dc4a1d4e94369004f232688357de1d52282f6054fddfa25a415a24ee7d12fc4c1e0c6c7af4221ab7193577436c784458897e5ca22d3057c5f761c67a35cbfd22ef5e20c427cbeddfbc6bfe93d3c923d50bf5544dddfcbc19e33db672f6c0360d71f721f2126fa903e25217b5d0f12dc58ea3f560b279412b4313cdb72e94cea716b1ee5a954d289fdd9d2b658f1"}, - {"000000000000000000000000000000000000000000000000000000000000000f", "008f85222f0a8177517b716351943994c6f586e0fa0fc66377010f7806ea2807bcb4f5c1764c833c12dc0d688b9a0b3beedde858e6317966e91692e0fcf971377d2414749472136ceea64fb93bcfbb689d5e96a500c146659345f881173581e131adb3a8d4e1945b84032b994b9885d71e642883a3bca6a0a5e47b5fac7408509ecf6a7710fdcd4a24788453df8a2e49f40b46369cbab31c22cb9d8223c53c9a731a9a8cafdb3e5200e86ef703345e5fd3cb52476072573286a8fd282d07fe4929024bcfb58952112558c55f5850092f78161aa6aa834954295904f333010fdf28412c099a84a14a3c3ad97ba16a8d43ceb573177af8e77c007c7e42016d35d757430afd68b0c6bf3cfde3d23f2032d37933cca5c22722f0176d6d79a30bd5e66ab4767d77690c3a87ea2f453fef8059e44c46c47bb2ce12168f9014368d35e057d2dad49dc4512a7b66169ad3bfa84c0266ae5d38cbf7b0af2631a22c1a1d148faf093f580a782e8d63aa5069e2f3131b8729ce967d329b8e2123392567201233b2a78702db646d0e46366c762fa72955fd57e1d3206f0119d5d97545cdc289b2962003028bcaca94c5988a795c932f8265d6222ad9d6f82d16b81789679b875b378822bf2d60f8e18c8df2c9b91a92391b8759ac8b204075fd7eb3de2603b9bf13ec212d850a5c91324fbfe8f2a519a0bf3a77eb7c8e3903d5b1d04942a2368752a2a0b8b54eb726de3fe4f82f92a2e564b05dedf25713bf202eb1213ebed681c8150b5a7a084fa1c4f2fec277d4d1fd3163873fa39e33a7cbb7ac1c5411ad068a18dd5fe612b2ab5ff16a0cd7afc8c00715e1686e80e5d314b57612823bf5242a67fba3e4d7bf53b548332f1747e1eac997fecea729e5076e79d1057897c4b4ed1c778ee352917a9f352d1b8e316f7574b7c3d922d281cc35313e44d1f69d0396dbab9c92eb411f880313b1d85fb59cb7ffb0e536252d76a7dc7de1dc8935c7185eb09b0b48b97ac22e4b2e95ec165474c936b5c189fdab4ae45ff9057b35c2f7077163af47697716c5165d4499dfa998ee46054ef0c5fb175a69e50873b451454a371b54ffa6841001ab4c466b8cb38869f20cf1370e9982c49fb7f6221d65b1f6e42581a3cf7295b418eb40aecf77238031c287f2a20d38b9eacbd4e7cc62b5c5a10fb9e6ca0c072964841c5b8357e2b508802f808e1f76bfccd621b55b62fb4a0ffaa9dc46d4a24dd035f0f0b52b550d4c9a09eb0d1a7c869e05a921d4b6638d76bfdb5d2b707ae2ac0c56abbf8a94ac9ebd091b0ccc7f292114e32f3f8ed45d51a79b89558bd9d3fb45035c3b7f5c1ced97f262e5219499b9e3f7f8436af7df39a4ed1da362249e07a93a451e230dea9e89b57666b35f5d243d9e230a0e730d446112c6b4a1dced3d627e3e8e072047edb0671c7da30f325e69f97b19e7a9bb819622c83d4d0be39c5137a8a387b3b29bca9ab17e8721107628b29eae163f930a42eee1ad655a936618aded1633a5fed853d957a2c2545360f0994b1210b8d5a10c99527eff96dc3d521b97f636478fbb61d8bb69c35aa3e670662f1b9bbe7da6f7b6bcfe7e21509bb5ea1d4ffc3ca0c7a21e4adb68d50dc9a7d715825f545a1ddd34e2752ff791fcd0c6971c5d51d23919b684be08276f13f00ffa873790d249897b021651155f07fc37353383e1e5f3a9b15a953ee6be307aa344fe190e12991f0037a16605abfba57dda676ed2399672b51580458cfa6cad8dfddaeed8dcc2ede672d82e9cc7181ac5361508a1e5b9c872e2dd467fca391e39f6f0a01f1721e99d9e556d896b635d8632d760e2f078392f377b62c4be5f7819d45db501b37bb49d89dfba39d83f824c5b2720b9a71422545492675a19cbdffdb89b"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "00c6b1a88a89208c577f80d3306e8d14e40bbfe0b20e334b2a3018ce556c16d3247d99b22164e719dfcf070895990645c6a5ca60d146b5c7f52c80e02b8cec31eac4967898b52f1076c4f5c3ba5dc189a313c53a02f08ad575864c9e3323b0c6c2b4b8a8b1799d965519887d267fc78c43fe6c17e54fcffcafe1fb5f1305036acf8f85697681890b305afa233b4d90139019b529e91e12810ae6675cab65f400c7367f531f5b25f00528edf2b5d508791f84c2838f6580acb90fa6f63e07579f138749749d51b5f3497d52a771d1017a3d470e303b96260619195d4413fa77a3d0f9413fb916e247435307c227a70db6e9d4cdef47a67ed295bd2f1209b50057b1cebcaecdb2c19eaad27888a5526bf2760d86dd696a053d61fbfc913acc48f754fd091a9f663fc1da98e1e82fada08214e1fda8af7f44a0ff82fd692fd5ae7bf0b061fbba5765074a6e369839989c08028a5a229214f533a3a3a0f4b63031f998ced73ad81456f1109f866caa7fcbf152ab6b5aaebb06de492e041f23c973b5ddf1cc6bd64726e1c9b9e76b395b38306504a3da98b569dbe533ea80bd392950179d2e9d10365a83e18624d907190689675cf07e5079d369621a701609ecdb4305acd3c45eef71f18f09a2d9746721a469343f51a701830706ba1855ec6f45f43bd8de43c9eaa6eed9b239fd7ae546e7d08b8b3ba57ca4ee0341c69b884aad2094b803aa74ee635148e02a97c604fccbdecb1a800754aa4401bf4bb5b65b9ffb97db0c986b4f2be88cb1c7c59116b8dfd6264bd23d61ca2129ab14c09c31d538b4f2cdd1e810daf5e0de4eb305ee7dd8fbd23ae595f549469d6bb96ebebcbffa791d4bee182e8db69fc8a3d37fd75f3eb9f07590828e15a55eae1bccb77d063184342a527d528e119d2d9f328242306554c4ddd150254ea6719efe0376d5ee6503b44a8beecacdf195f936d753d7bc761a26d5e1166b8543d0d03ced97f51ee72541da1707521ffb50040cb7c5aacdcfd392a9a5366c41508f624c7319028917c5c7130290f9cdf3d69357b55737990a1fef91be0b688cd5e068588f90bab0d46f1c6e38364daffc982210d7314e08aa1eb275c28f325fec54a41d0a0134123bb5cc4f978fe2e96302c962a10cf11a04527e0c314417e47a9e94a1a8d1854f503199dafa065a21e4042e5d8d4b880f5bbdf1f33cd4a310cda0c7be87bd0b6826e7690dd9b7c9521237eda6b369120a4ab6810911466f4be3fb7fe0f3b36236cbaf3dd0a22eff6509422a141c16276d83ee25ab6c2d9cbb1e059c83af0719c8570edc11cda5a140a82f2834d30f599bb28b4500bc143d5ff7a3bfaf06ba836138a60a20d8221f0cda4c20776ee32be733d3d52c5edc4fb8d3bfe67b1bb1c3ed95a23261311dc42d62e4cf412844fa78820438c53bc6dc107bd770265b9dfeabee9b13d686b30c1f91933a915e571e3232eaa0c40189dd66bc9c4f048868c3df1964f3cc82f04db641f2f1997ed4a1060f07bc05e5d60a378be1f39dff9fc5a2b57df7769d04c3e329ef555b930630e37c96e8e905c170f154f12c6586c8ef6c0c4fb2086402f867975644a155e88334eb15ab12ff0057f90224eac861f6da3f2dd7bc7648a57f835b9d82d57cf4455a39f835da364a5bc47d091cb6089863248d8b8e60f9c1fcffe9ca85d03e88161e5c6eaee19a5d630f04c742f049fa6224d5def3169ac50ced191c3725c9c35c25677a264fa155755227fc5a2e3fa11e05a8b085a88732ad59e85e967df7123ba163072a0f4d5eae3462dcbfce7deb3b5828ae1b5f231db1c9bf0a803f5998b9ebca32c2f87c9438352753f806764387c289548b11b6b795f3165db49a40d8cccc7c17669f7100b57bd4ff1bfdec3cba4267"}, - {"000000000000000000000000000000000000000000000000000000000000000a", "008666ae56c04ce79db3d3085e185bcda4dc9bc65817af22485ca3647942effa0dd6f3f7ab69501d0aff137a9ca30d716925e2d03410bbf417691d63f5d2c718306d53d3da53eb42ae9c08446613df04b6be66a4094ad52a16628d8dafecf5e8793f89aa1a091bb46254ea16f77da42bd36a4e573d33e3113dd623dca20412984bc34a0e8401b85223a46976e7c5fb911c5d95250c9216425befd5eea0628eb55354dced0014b2b20e6ae74092cf4c1cdb8ef82170cc27ea0c8078c62431013c1846a630a9cc28f45f1eeb972a7d9ddb8df2145d653388a1d2b367814201b4df3db1c003b92efe2b6d1bd1dc9da6f5b49e27a3ab57e43e8df47f46d41086ffc812190c7354fc0db20f7c637bef20ffe91c4323d3a9f1d26851a43d16c554fe0adb5a205c7e4212564a87205512caca2485ac38ce937273c0b70c771453c69b3a8d0710747de3e802d6852278b4f5cce9014a123fe2dee09def03a0e54de67dedce177b102806360cf913591644f1e8863629bb3db5e226dfa9a404604a533f05d4ab0788861652b48a4ea4707697941fcd5de7aa3015a7b83aa2fbfa6d14f23d6759d25a077f3d84ab5331d994e734b2dca89fc650eb35f1a45f250db950eac1c97a2766c6edd6296e56649c76992354d3d98bd9bf8aeaae9296e9f23141ad607d80c9426352a5cd13af6f35b194db2432a97a849b3c67130495f932018d16d98cc1c9c5cc57400a80cd143da90f60dbe3abe0d0f9416462e7e3d44f7578cedeb1931a4a4dce6f1ae167f635c950c95ea68baf8f7dad9d3aa995f9e070d5f9958994debe4d274aa2ecb91d8404d643792a46ad4935a6a3cbe8fe2f4eed8cb9d65d075646d5fbac271388981585d17b97cd8bf359b092207917c02ae89551c46d439aa9aab85601da73074c43df0c3886ef20d99ca6c6385172908a3da7b8784b00d2739a1086125fe3ca32f59a6a44f1dcd61d78db2929652174ecd2ff675fa2c4009c4aad49396dadec02bc08850b41f97e344e90461bdfe3fdbd84da7ea81af437e5d589e7a1506555d58063abaa1087ff7d210799a36b4d084172b606e39e001efcad9bea1b0f8f4b66a7fbe7e7d34168b5f82004c436826b3b3f41d724d7c6079b89bb939c4942fff0dbe16e48831f30512eeae201f9548ac30ea2e6c66c75ee46ea5b3f3b791a9ea1d5c2bb2871ee6782f580d79cf548f88e099927c8038d7dd22c609498f37c0cac074956ad94b11923e871809a5197a90c4c638390bb5b3d7855b39e4e3fbf4d96e9a6632f388cd54cb9f53ffb61e4feb7231f5cf578a6d1601feb8135685dfdfd9233d2bdc62220bc0263941cc6d7b19276123445e5b2e69679707f3d26efbbad6e69b1d78779115a493c26b373def3e467fc86922bbaa167d9c436d6aa7ad2268bdcd921ed0403cc99f9d7fb33a89bd0f076debecc7411930937361fe7c4ee9c90697770e974cadfc5f73ba01e42c20cdcf312baa08cebb40ef1046bc174a9421737f5f141e4525302ba94a5fde2d6f83a628786c8e19a20e5046541bbc7ad2bcf9635327878fd440dc62b3d4deb305f3a5175d99e2f737fe89da4fd39e2b41afe4a781d06010f3c1228439e05f41fed6173c5b7113be8d4221f63c17ba2d0c1e6fb36cf73f3639a1f387b3d8c07d87bb2999d57372389174f7d6c59b6e843dcb9721b4553cc6809f9fb4c5324e8b435e31b0d6afae1c81c5e8190902107c582d0f38e243647e5612c19f44e32a9fb187ad6c12958634362e5573519ceab39115007d9c9a19230d36dfcbd4238c6245fe1fee15fc1001b675106679ab361cb7691fbb81cd4e8b663b2f0a011d735163746d36b9e6e4427a0bd36a10a4e5aaebb24d901ca48e80fb17e01fa77a6fd606bc721ffc215"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "00f48ca73716345f177ba8517fcbbfa282b6b88a3a0969e90515185833cb7cb403bd49c301534e50cf5c01da94d1038cadf570b534b3e1bc588391a95f2f701132ffc6629dbc7d608c1133ee4162c1ba825c572507e6f14eea22905d9bd0d5317a3965f362a4de3e6b09bdd25d1783b4146f3e921d0c6127a9a524cf3eb1112a7de0940f4738cfdee2acaf7ffd1f450e7eddbd3c0f2a6e72ab459b5a91a571f0d23e258d9a4fbea004aac2f501c62178a94dd0b0c5687974ed66a84c2f0a0d558036c55c3c4428115627dabd84c60308986f088d38d6d746cb174c92544a447cf3699931791c340cb3c52c60ddb00b3389614ef8f5bb52bf9f594997082bccb64c1314cd971ef47f67e079896149b88d3d0ba715ec1969f9e3f2454161a410f974dafe750c1f14518a74bfe0219f5ad3d17d05c3f9bc797a39506b1cbcf6d5908a216bc10228e6a1e4b8db04f9fe147d0248cebb4349da05ad55c1216e6952c6a688dec32317a368ed212fd4cfe1b2630587987499a301d947920375acb86acbaaa59ff57510d957efad57b56ba6bb19438a50c7a74edd733d32ed9daeaa4b0a5b387e261631e24912e9a551c25516f098f7336f52abbc864421fc02a1eba05a83b1397b4cd0e205f2dd22788b371e23a48b9b331077ea6684b713c209499dc13ba7d445a142604f2a6689ac1a5547dcb9696d99b1930743062a5b74c0683625b6ab731478ab13d976d91a5bbf14b3339c8e533996d3436287fead52922ec33ddd8a0ec09568d916019be61ec17c044cf9e99eabd4ad5f222776a1ab1cbc07f9a118baecf0be236aedddf8820677bd19e9cee206ceb6b6592069ca49abafeef5e910726af92f6dbed3834dc137989dec61890c0ff11e15f674a4e2d2d019a3d81284749a72320d7c5da47b1d1e5d9b2c4f355b91f2b696fdc5bb9de1f23daf290108ee042ba83a5b7ff852de764a5ea1b497d9478d094cd5d54d540962a832f606e8d3258f99b6de241b03a43b6ca21bf68fca3e50b88a2748509fca66369510a099da7372f547fc9be69ed9c6968b7556dd08fd07d55ddd99a1d9333fb39239d7eb47ba316d94911e2c9b6d56c3e025374380f73a6ef63f4379ef3f24880a2c47a875947e12dc77a77c02dd26ce732c56928a18ca09c0f8cb3be759e664831b26917759b87c1ec303f41868453d3db1ef41d4150e6e031e32729c69424518cda366e5f003301d35c8aa7d3e41b76d3216270462dd7f10c39508b851804b27fccbf062e948cb043231f7ccb291be2339d716033658d66e145fd49481070293b70747e5c84128f073f604f83da06a7d0fc52902979cfbf00895a74549c43ffadb06f259d7f0c6156e4c940dd519e90a3856149d5b88e9b87a379a304da0874e335594f35ef5392de5e43b3f0972b8b35303b7c553360f44a28b85987c9df75382a291d783380c5f4ef9af5cd2cdefdeb61e72c2c6ceb4ab979afc03edc43b496047a97af512cbe6f7f0de0475fce6310831e61bea84be090ea651feafc962599a7d2fc60e068cce31bc3090abbd4eb5cf65ca278a660d36f1342683a959d24a03fedfc8b86948f3d1be216654cbbb06edd174f242ea92b3cda34cbfa083990443cb36045d567607df5fc0fd9ec356d45eebf00b6b8f5ea7410677c7dcad4a2189d3f92256999e9cc6551ed446dd3a52e30d925bc68fd435e4f69f3be39f279ffb54c70a641bd85666a48f591c20c296dce721ed581244e715467ac131ee5c977668798703756b16d07cdba9c00aad64bd55a06fed9b28b0fad7924c352ac2d582f311797d80254aabdce991316028e3158641f7d76d69149f3a1cbad0f24af28aba27daed7027d20b9fc64c2ea0e52b2be2054b146c860302be39b58f227c923c"}, - {"0000000000000000000000000000000000000000000000000000000000000010", "00333f1e90c31543d056c279b4fb5a78c7511484ad30d4643ca2cc58b527a0d376074b2703450c7d64da01ff2f247567a9dd5230e3d352e9a0bdbe453b55270b8518f1928ea1dce3f30105e5653aab145e9f619b08361e4373847d9bf8d3315ce6eac5c0da06dd7e4e12bfea98c7a20fd969e3e14707d0be9a6359ff8a060862cfb60263acb5aa6a5505f2413fa679095f0c331623aa2d4bd72342d8b082d0742cfde563230cf10f17264e9eb95faacf584ff5998c641dbd78011cb01319852fb656552a58b3f674c18a414e5560b2b2d4fc1751eb5613cfe89ad37893758deb75b72d771d177a240cff727129b75d4e69361b46e2d261ff751ee13020c98adea7372543d1616721d7c8b3aeea12f89a364831d31d9fed9881a85e452c094c5e6d73845194df4dc5e6909355a2f7ac6737646ac4fd13f2aebfac89823b261156bdd1ebf05b185abfcc817ac1753fb80f005725ae2f8d077cdf15b0cf50d8921b12d1391b5c36c593c9cd15f6cd27a495a472e3bdf5bf9a3dfb1101ea7f28fa16aea0d8bd5645a45f19ba1048dc3c8e112f41b8a8c55abcedd8c1916e6d5c137869fe9e16097c11f8d86346cfdca584743f38deae0c33bc736f137537bff74fed4548d461dd3592e78cabd1069cd52ec93a649a9f7e49f260553496c165be459bb856133dd1bdb4f22bdccfc534255a9975967afa2e998e1b029c48afa8c25308d19bc1b3bb42435a36fcdbe6031c9f94294c75fb4fc05033332b6df895935e1607b62816bfeb991a7875ec9fe471f06d756190b45a713b2896abb67c6d3df9d9154546436ef10989ddec98162cbb04e72cf897a5d96ba4c0b36bf25e26c737096e36d945f55ff1c0ffe1c2f50d2d31718a89b7b8c8683db0dbd17bde93edad78b503ade82112a2eadeb3fa49cad7a7282691199f7d171e3e39bb29f4b0716367027aa9402ba59037cf6e604be62048c87a112401c70d885b7a5096d98d9a38c25dff48f6e2674d9f2af40a155a631d59bd593ebdf83a9efa2c229ac976a3ec25f6227968cc076f3377c606c45ffe42c206fb85ac0370c5791190ed98a68051ca1d1fec994313dfe3b2221fabfbfe5d2a1f44201b59fd7a909b84fb1ddceb0c0361fad596d9a39aaab6eb89f1a809ed725861580f1ed410d4c7233d4137d185207edab17ffab92859050850921383a7ddabedf1b897fd03ce9f6d17b3d5255047f89626db49b0dfe9e4757f0d66fea69c564c0b00d440fb179c29a7f867ed29e80262c9c4bb0fb22ae2a7fb3e5c437fe943935cdc33b9c9011069d9ea0a4553d44cc438e1a1f363c4f2df30623af41ecebf1779f99bfcd79fabfb64d46706bdce5e1c5f96aa30114bec90575ab1dde53252c4346f82ca3d497b88b715504766ba0ec36db9a934bdae69cbce57cad55ece052c9d3301c4a8643b9f3067bccba300bc59c686bd15048426e1d173b0ef7bf5da65670139ce12391aac05fd22d39a1f255b122af0a64bbbd5ebc23afe755d06cabc7fbb1a09cb590342c85af404926dc119ed451089bd44b8dfad2fd992b15206a2bbced7bd7cf5571862371cb8e663b9f10b431419c189f279fafdddae25b855304a8cb3ce7a3625b16ece469a1cc539188338c8925ac48e9658ff864915dbf70d4ee8a578f2a615fca6fb9f07885162720457e65ab97d16f5362ca448ad970e80b7f7edfeacc79b06c7bd6650adfdaf1f1ff49b6c484eea2be071343cebc8ce027e79fa9c2b3581e4f5b657c77cf494792fd1fa8fee6fecbdc99b2f225d8e4f0c32b526482485686531259d3093a42337d0afe9dc9786f18ff703a413a8a70359313cb27e3323147a6e0d6dbd3a561867e0c93ae2468eb48409517257f17218ef8d4439f9731d58f7866a63b7a688"}, - {"0000000000000000000000000000000000000000000000000000000000000015", "010570a8b3c77a7f88fd653f90aec919f098343fd55cd48f0f56fc814be970db12d768d507c0d39ffe6e021e483e248543f6ba9d434e61b9bd2164e24e8aa308b7d88235429dadcb2c518769d92e31be2a58bde201a51dfd34842222661a25630f5e1a0990a0b40c6901d3ba8b6f112c2e984904254adc91c9c7727f87d005cdff01b5cd68c1f76a8292caae8164eccf31fe4a1c6414dcae730e01a416d92b69ec98d26462948e980279a7352990f8bfcdaf1776926cea8acdfa58a2331b2c43258037151dd6a392b912a9416b69667ebc093610856b74175c1581d58928665e908a950114ef7c5cfb6cca92a2ba957a68e5eecfdfe2e33a3cdf240815c70ac4506eafbfe5ac325f89380127afa65ed4dd2b7f4612aba61e5b508767ff43ff9b9349b95aca521d6d57df59755973fd2033ad8fd6f5b5bf7a548e1669139e50f223248de4eb08492fca6eb6b9be9b19360108d5d0624da616b189e530567d99b1704095701e3da7aa036b15ba1350598511323408316bb5784c19031e2d81e572aeabc3d580cf9aee56a8f87607e8e2056e9ef2739ae98be514b4c82bcdd5a65093b3de7402c4f23b1f2245d9d07b05db5d3fa8f9cb6e8f263025b6d179e0d6140fdcc564389836e65e060dd85fc109b9450730d65dcebe5c446dc77c3f11e437bbb382246d629741d7de03cf5865bae16fa801ce7ff796a60d645edd72882c00ac349a7f9ae4bf9b6f6b5c26dd492673690754ca37256ff49bab3b42423f87fe3dfb1021bfc433b7b535f03136f91057a01616c77aad073bedea0b11646dd389c08a933d76072762d1ff641d0e69c55f8a4a68f692c013cecdae063b84269e58ca309de9da6acd538950f7d32647f4b0757247f06c7d1b58b9b0d1ce868194631568fbdb7006449bfa511b2198b6269f32b69bb38a463c3e446f0724b01c7c380186e1ab33d195bbe6b861442bc580f228971d03d124cdb24fc8302275a3b0f2632eeb28c5dc98b6fe7d01d51e3944e94ebdd8c36bbe2bde0313813ffc5a6b318915d169d1a5549f39b327535852690dbcf5cd2c0e4bb9068686ae89d814112620b327e0bd3f8e4b0a0f2c7249951ece69be201613586a726745acdf219e22463d7992984710c7d618924bcf9e5ab894dd00ad28067406c9cb91df33e91374b0ab5121f9a01789790e667ce09c0439f3377c64f6a26ec425e37356a6bd24f64db91a2a76b580448576b571b09b2a26bc0d14165111972315c7d152a083f7737286891e38b9aa7b220fe7a65112501a9f3ee29e4622c48bbcc3bf5064101838c9df5cabc8f8da918547f384e58cf7d2288e1415d2e2949377b9f37fa546f3d2045b1e0e3ff4f9129f66be5989860e6cc1220690e5aa62a94f58fdec370ca4ef60d0ec211a3e25abacba54523ec19fe6d301a971b5171491dd0254d7ec2ec138e644aefbf46d133b79ab0426924d9cfc79b56d5e77f7cc28ff47c71533040805ca643a5ab08424cd2d501141b577139b2a8b2c615c559ea6fa847a9ac8778582bba81e30ef0381a3977ca671d7a28920a6d3b821ac5b290a54420c7c334f9752104b33a5835315754689e2a851ba2b067b1bae1de9588ffdfa034da646ed8636e69678020a71b710ceb4f3c5ee86d189d8388674cd3f0b08560f7fca8a505ccf41e5c6d444dccbd515bb2b5d5c5b16a2eee3c9c6acfd7e66f2ad1f51d650ef60d311cc2013050ed892ff11f543b6596070b2d1a0fcd2d491342807355754d15128e8456f0cc5ccc96da0ef7f130fdc623aa393ca4fe4b086925f463856cfcb1e91d2138d5e945309c85686b4a477a77e52226287faf7311f5f4971e2081ade6eca7337092882e13acfaabab55b383ae335662005ee6ab5e95165fe5265fdd89322"}, - {"000000000000000000000000000000000000000000000000000000000000000e", "007087bcb52115f3833f40ddc74d5eb8692f4e3eb84bb5a7c4cb99b98efcbc8643bbf7035f461ebe42fa0b48dae3c59507ef0ca8f457402b74c65dd554b3e11b2bc0f44f8d7f70cddf490e706b422266c99a099808da81c3154f8216888f52a3a972424277f5bfd36d28c5898c6558fdd0f5e2f652ea7e7135f47b5a8b851889b1139ee31371661f86e5ca471da1e5d950c24a502af4bb2960ba251715489d44cfe9ce5d8176733001c06f3cd44fe544e6a64618e5fff79a3a983d317a1f6aba8b41d40bb50597c2acb4c197a651cd984110240381f09425817b5a3bb250864da83635d7bdee21409d4cc1c123b4314c50a62f98719687a01ebe0c6e020a1575e4ca0baf1f8845f5e2ef71ee08d759112b38c21b357852efd93e4cf3bdf66fbb352bea30940a197c5b7ca3a75ccbc58f4414eb35a33d9441d972432d347b33512564a78534e77c3fd5b8d5f33c9296d602cfd3d88153ccf6e67ca17175f4a6c9eb3e55640f09280df50146830af0b4a5fcfc66ce8dc1969b74b10b434301b495b884bbe11387f16326d23a1872a8cb122565271f0add5e90e0ead151e07da2fe2afa3ec20f0c8236b01d0da7aa7ab1e8c0ef025a5b50fc7ce136086f1b061204a6d543f76eade7c81256a79c821a29ed3c84e2e5aa9b6a3a382aabf31767d1703f8867325ae576445ea8f5c5ac65ec66de2dc279751ae6f702e05abe3d57dae9022af220772ca846e3a43a435939d08dd2d10f9ea7a9a319326fec2b3f3b085d84b3065245d7ddd7695f1edfc43d98b2c2dd390bb6427b10efd6c22dd21abb683f45b93cdf3061da7016980109269a6a294d6f25e7d7a5a183b93a53d64d1f774b23741f7e956b9de1eeb7e31926a50c911ef670c4f60ef71a061d29901b8fa9a10212d429390486cfce1227cb7b4b33ecba91bcafb301a36d92751729beae4b0303bbb4e1837c272729283b0ddca1be914f9aed780405bb44fd88808ade6bd4736664ec69f1f76fd517036562fc820894ee56d7037676571faa0d8f5e36f92280618e709c4bbf4e7814b1b1387bf1afe01e9a6e08a07fb0103631b5db4b8203f5c2967746df3af6bf1f42d236ffd467bd315f771b5fce0575fa00fb90200e29ecc77d51d82e9684a2521f96d818a4276a19e611e2e670d191ac057db7d23e1fbb552d9ed01d63a9053031b88f5171b9304ed0f5810a53367cc8d66a032bccc2ea54a1f9b391b623197ecd01060ccef20afd0adfc2e2c50517aeb393f8c9ce632176adee7731ec13ca43b1b45808e6e19ee7e7d2f613d38db69c8b130823041d8c4d2901f4960300e9c4725e1dc297037230f029f7e9ece985b0f543963c6d819e522814fec42c31b4895363f0dbb8b40a683a5e9c0b03d85b16fe353f2d710e98ee28e2e5e7f1d346455372a89ca775032df7a2f54c713e9ce3221091671110a28be6f64e09c38e3f03878bba758a429a8b5d15b2b119f5deea0d2d698157955a70c936a4dab0b25b89a32d7ea9b9103f1e67f9b1ef71a3644221f021336d675f9627eb147fec996f5c1c13753026e61a6c4d0aa65e9daf6e32fc7e2660cf2307ddbc645c17dffecd2c49b1e4ee160285a4d150e4eab5e2e5dddafb89563ce0562662226abd0d72d071b7f877f4e3c1780c1a67281fb0460bfa93e51dddfda0fd1053c599ce679a07c1728c3b4807b24d16dcc16d6c85889641fe8f2336cabe34142c590220f82a8715caf73600f3f3f452739fbfc57b4766456c801c31f79a6dd75042dee3a730133eb92616ea89f0a64734479d8bb2801d557638b7db7915d92ce18b484f8bca4dcdac14e59a4f79ffbc3cbfc5311c46128a395d1ab1739862618b76d585b8f8cf670623b1bcac63b15b8dc317841476bce7a5270e89f5c1"}, - {"000000000000000000000000000000000000000000000000000000000000000b", "01c5c04fc4cf1132a804d2afabe6d5f9d90a1590061b93fa8dcb4e45c148d0768ba646a181c737fb7fc11a493d3ba2a07be3bddae1f0e94017823ede38fb1025b27a5c3cea448db26093c34ccbaaa18a21b830db073a80ffe05530dcde8a2369c3e236dd37ba7c8598339a5cd2f830c41bcf59440354ee4599a7a4b2fa790b39d662dec5089ad403948e204890fdd38fd4f7f61281b3205616b72b2a86aa6ea174a0271f715a4cac0ca64d80f998c5a52bbbf23c07cee85566b0f4548146ec94e4a623aeb1d67e548e80cb279ea2347b906213083794f6ae914d80208196bbb23156d58dde461231640584d6261f418f1cb5b65c429369e0940f2d920f25d9af9f29dc63b123325df5615d70b06d6b006b16b479742f17c389e102825905612cb66e92d646b3185deb6629988751d56a778e50db3e1a3a731ebf9630b75477298de2e11656a3e3a5fed2c1961857003d0441d51ff056718ad13d559ace383f521c61f1e0e10c500432aa963ceb83c4f4feb3db669f5bdbdfed450e616d52f0a99bbb8fb192dc17e154d1f71ddd7667442a7b5ad6d584e5b2f4773bc2c3ddde2e3ff6f8141600fe08844a99706da396aeb263580afad23c0460393595dda40ea1cda479b3fd354062dde3f47cfb881c405a8d2564673b96ae9774896cbffdf3f6323f6f5786841fbd248961a0bca5ca5560396270ae177a4905b7bf50a59ff8f129890106ba6855ad4d5a6e5db8073ddd3ce50e2665cda4710788c8e3995750f93ffe4449d358db9fc94bb4b336fe937269e256dc3d9dde59b1d4c863e47001c62a45a8b162a87e1f81df2b280fb2fb6ef8cb249df9ae8b2c23696eeaefbddcca521b30db42884b71d8e8e8940ffbddf5425eb45fb7e1123b07718be33515401c02fd0bcf000d1553b901b1219c6adac8d3600dc580526658ad65a4a7f8ddbc740352bbc7fbc423ef2d7bf1621d5df428c7871461b930f019ebc92c3c17751d64a2df6e957d9608d20a0924cc51f495d586ffaa9155d538dcc8c24af0956f8e3fdd47fc97535276fbf239f2756826d31909bdb2820da815381e4780231de3f0ebef217fb90b9b33bd061ec8bf2b5a8c9b5ced7544e5b0cfe376aa0d15f4a12045cd476b55acab88f602e2c552d271a306f33ead265e3eb3fd563c4ac85062f3e79acb5cf681f1a03208d21cf77286de6ab996a24dc1cebf91278cbcade92a65c9b11f1c43ab12d9e3c587299ed34b69bc05630d28eda7a550b938b712e1e587f093d4c716a89c455105c7de06dacf9f6dc8453ca4f4a1f9bad43db358184266bfd54d96a7e82762e8286325821b285ecf9c2e2386bdf15ccdd361a7762bba7285035ebc5f5e712311bfa664162a19170c16fca75e415dc1adee2570241fa448f81aedd72b78c36caef855ea0034b18acb05bd2875064acc68b639937ecb35431f2cbefc3b592f34a4de81637221f46295ab8cd7626d9ef77f528423829c67b7915d21fde6f610526450c63f04163eb5513e2b51b72bf4c18bf728bf7b5ff6daf4e1d86b890f8ffe5948d0b490dcbf4a2e8360ad56f9e5d94f6b82af0ee24d7475ebe989593fd9dbed7b81f0bc6d721493a7a33a564a68f90514ceabee2835c3e770386c1b04be023c06d833b75ab2a10ac77d924b6eb7a8f506e04d79d1f44335ff52f1ce06d2dc033519fc3a5d297d2eb2a1156d70f326a8447bc740de7080199df60b4611cb4e511749b7f530f1b84370b64e72d916f341eb9acefd94a510a9d2e9c7bad7b896b4119805a112aa644a5c0af8e663af9153cc44b5b6f15b9d76e45eae0da95f398223ec82678ffc655172827f94eec038c66752db5f61e56008a43e572fa91de4799e62075ced9fe37d2039bf8c89a84378fac37f363cffa2e8"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "0014f0ece6e362455de0a39d79f74a891df9af877b16188b2d296065b16fded57006d76112807a5609ce0398b2bcc301e3730b0d162abdccbc3a9be8fed6be0d73e97cfd060757ab6cf3a51d6ef97e47c4f8c670016e4a000ec76810b667e23c73c7e151b57cff351b02ae4a0b461b64b18aeab389f53a549710b73dd96b036662330ee4b567bedd3783d8ec823a6b3e9bd824229fed332b1f888565ce028505e73a8a324e93fcb007e6cdcfe78f3ce692771a2799f148e3139dbd42c73deb8c37929d15470c05960d87d9d492b0d2b99ec70c1b4b2180dabed5c150b47527b25e261a3639c2a45c265c355ca5045bf310d6c856368d5e5e963a5c5e0c4d0cbc2a08216bcdc24166c3ae4728cfc4bcc01c59344c1d8aea513b741d55aab8b1be82190b354ee80d1700b3ca919733f82124e16b60f3ae36b03bb1ba1a67bbffc8983ab35df2433f28f36c494dbd53bb670094ae65f9743d4fc4996102835da41a39d0de1f124af0caf0c5303f29bcb939168bc938d6a656fdb64d0a4394c4921ba46f492b11d0d9f4c91e142ef516601808cf7f6c2547256a34424f181d33b6cb10fc3754075e3f1df4d4711f7d66c1cb0e1dd27d795251886b219a0ac683a193c7b58233e8cf2c4fcef5733bda2b29890bbc52580262eff5867c2ed4261dcd8af90e2f3bbf1c49ddd57c09bdc125da89e1db423cc9370d4b02fc0222efa74e7b4f2d23e117ef2425a9041e43543a8eb46b4f907fd19d145667f9c2aefe20bcf96f950558a3ecd760011bf844647640fa13099fc033853610f5c9c709f1b8b1ec62552f37e9bce179e7fe0af3138b92caea1f5957c41952e2f77f44b3dd821f88f817984b7c6dd0af81c747c3009f6ad8ecd19e874b08165dccbec0c90545103d337b35553e01dba90fffe81f4e1123ad4c792767cda348f6e26ebe77729fd2d500768734b59642e1de22c186b598be97bc7f3de9513036437b494db41b3bdce8cb38de749a64d61b1ecc064bc89b54c77e7672c744e2e4b5fb25e0e89dbcdb518f233140f9245dd021a5df09b784f5c8697644f70b92e5066d30180b88afa537aec17429ab192e76c14c58ec93c769ea97b6d868728cdd44668d2c5b2e6c1af4ceddd62ec3d9e329447a9a3919834ffcfd2a30353e2ebc414fc9ccfabe2445bd5647d236055ee0a4014167d17600aa2243c0f060e3ebba6cdb425857f40600f6a74183fd25e8e701ac9255eae4a164196b9909e2ec94b250baa309c7e30be4201464f6925c74070f05f5615b44880ee7daa1ad8a6a3ded93c89aef5a09fb5da27426a327e0e420abbea18969c6f58f01720e01d07b510949ea7974817432455710e9e66d6f2b1777027a7f6082e9276a467383cd755e57dbbdb17d249787210876f447bc10057a6bdd2051b40d4f3cf101efa91dc6dd943993ceb19e3553feb12b9a95ed7615021eca63ca9cc0f1f213e9dac85fd6e1967ffc0b056f7bcfb485cbdb0688354d913eeff98c56925af0250f655e67495742ee24c2778a583ad1a1be18a208026962239ea8e287d72ac1d8486bd6dcf51c7f77a80706734e572923e9c183b3e512f76e41dc3ef7675f06eb077619d9900bd24270e08ae2c1e3d9085ee6131a55c42d3f916bfbd24d368c68d5002b4b4a9d454307957a5745a541dbd09cf5aebe437072ae6177a34a195a06874c0f170f004a33dfd6fb19857046bad37f0ab3a588c95db2934f0fc0e59c7273a10ccccc093523120189d7f76c2df13ec2a52deaa4b26ca6bf877b09e5679eba89bbe5051b178625d42f569d629bb0aa342a3369eb5922b4dc3fc54ab3bdd81b6fd95cb6441416e60c88547b177eaff29ec42a3f5b26b53bcdd125d2f20e4faa602b8c4dea4da072b88f30d77b5bc8"}, - {"0000000000000000000000000000000000000000000000000000000000000005", "0012ff803deee80dfcaa92f0b5345608fd6fac5d0f067cd5a691057d46a5a47170c08ca571fec0b64335045a1c92780f2088cfd2113df6b8466ef48679a0df0ddef88fc0882b71d429216c210ff9e4776f967e1f07038f232c070b8eb541389f8df83a1faa3efeb78a2f3f628cd2a47fe1bfedc38977d741951d1ff3423107d5a8dbe50f96d10968d23e50b6a51246067aac9a20d3dadaaee16e4bd9efe38859df1bd11d3bd357bc072397d6a2dabfc3a3d040e4ac769082b2953a21b918a3c956b50970ca77e7c3ee1df0f049d1f53d74cc10b424f0df1514859fbff3f76b2f8bcdac037fff9a156d3ff0cf659a716fc7f33175fd4bf51fd30bf8c50c9f2fdcd9c78b4f0998f42226b77755f06e1e69d81cad7c7c9b9ca3ab6f0b67ebe173008391b3decf4817815e0926665c33e77ed17996978239601c3bda4f2ccce4a6b4580e458f9794262059c636726ed3fc700317cd6d921892c73ea30847bec7e41e53a4bc5bde53aa65181addb207ca1437a3f6731cb6ee55fd72470bb082db0e0386e30b29734e715b4fe35bdc5e42581a19e1a842cd875befd11262163e2509b615b0641a045808b4c2cc673ca47903c65038ca0d5db4332e8f31d8e654abaa0bf1cbcf1a95e76bd34790d3fdcb88185f81beb6580a87468db2d133daefb57c17f42ae22d2c43eb3a260e055a3e34819c45cd057d6cde27fc09e0da0b06e0ae79c39c23832ed3fde2ef753ceb982920a50c1da48735f9da0598157e2706315af4c0ec0da2387c78dd32e3022ad125c67e27193e511c5773370b974cfc9e00ed2b24c375e1ac4842d022983b2f1489ead8bd7a9ddbe305231f1def0a4a64d916e93741a29c5d4e232adbada96771b1766cd271725affa116486914be5807c7d1b603a6ce68e4d5249d1cd38633e95661c18d70217fe2c3562f52021f37873d8353009c7387559e96636e91b4a07bedae75cbb05c89133a7294b7320ef6275d934472c9ef6cb66a7d954d242bfe9da6df7b3bf5e5f654160f49c1ef1a9c1b2c3042ff522ad6e58ce37455e58920e2efe596c6fc7d140793ba97d53a88c7f8a53672a1d16c43a2c59ff6431c8e88f1a0dd22530af5c20a66779014d69a59d62230e1e2d3079af6d3c7cc59a63ad7ae9366121bcd3e5993d78b22176fb57f0bb8eabe546abfbc119fb54e01a5a708e50464c5d3a9f0d20bc29f815cb57ef8273f83da54d09cdda316654429462f9a2214a11f19db16d4a4052305eb98c779f7bdfc695c56a5e33c09062382158f408b2a46f9fdb7dd84ca024e5ecbf6bb7a08925b569e8f03611911245cf26d9309c9ec1183432f6e0c2f0f9850515bd5e9c4e74fc0e2734799f8a80f66b302a330a273da71e103619064cdd9b07e627d13c93ad77cface39da3a22039e12aeca3886b8c3960122cd9b84cdd3df390c55b2f8cfa95a39f4f8937a2987d9b889a06cc1115642bed17fcf25b79ad92434104f6751d3f69171e183c5bf71e97ae5840451d93510521eedca53457b23457143ab458edb5763de41db1678d106bdfd9987f7e683376058667506550d301c1bc811db3ccb5fc1fcb1e22703e3db5eb9ff7ab943515c43b766ae3bf7c01c984f4cee2a3255705b694954134db59ca537b3a98217d15275dc6203b83269fd02aa3ba9d7984f2d25368422955a1cb5d1793e23f12002cb09a75137eebb4346ea3de0f0e1e1819489f20552e2602418090ce73a80fe77990d81244b50b03e100065bd3d99b603d8e384f21673fb4540796a6e2e062c5f1e148ca1dfeeed75c9f261224a029db20c7e19a1772dccc8a116918f2243e71378717300fc1e160fe2a08ab14c2a5e6f84c3bbc124d7c0f3673dda9c341fa427335179bcff0dd45148a8ff591832906447"}, - {"000000000000000000000000000000000000000000000000000000000000019c", "0044a6c2c7e036d77992e156fac954cf173818c6a7231e3de5cf893397c5f1944b7db3b8d62c6e9ebb4a173dd7e335b0eba3c5bb32708cd0d6d1a7729a1aa41b2624d24c1b543d00e19467abe4ae451fa4fed03701aa6d9aa4920b9b4ff320d82573fbbfd67ddfd10145ac57c86fd1b1131d2829f6f67eece783265d676d037f1ca3224e62c55f18e14df4ea250d1c0a78d8b329a39c3325582755d38f557df253dd6a825776bb35042f15da17e070af615115a58335f76789a65e5d8139afef952195d3ead846a725a66cd2ae2b8afb91eb0917a555f42e739ba74de1d009a4897c78dbdfdb110d8427635f89f122c11c858218cecd91ad951918b4078d492826e1eda33482911c21d67e51923a8ef32312cf4a514af8e54be258f2a4f7bdc90e100c380ffb0ac36c91ff2429a94500f577614189ae7f0436aa8339c9dac09657b60341bbd886de496a96c7205aefd100983a8d1a04c90edcaa38ae2b7d31c29f7a59f0754df62d215155e225fe429548453c1845ee3dd95df7130805ce4b169eeb2c6e268656cc9e4f54a37cd4751b3c29652e9ae00eec50476296cc4659e6431a9b4d078f01b0cc88b705f84e824bccaa54aa15b99425510fa91fbed00d9d64b91421a31ce5666884ab5dbcce17058b46cbaf486bb5cf11e8bde5395a95f436217b24fd5d8e428aac71d70457796a4d5929e765f54aa400a8ae709de75dd1a04da83dd15ddad2e2765ec29243549e4777d317fcbee975a358cd447de07259075b1bb32ac0cb485f6f30e4d428d747a53a3afd1cf76a30c27f85d9ae0e2f8924152caf75e26aa77b588775050d94bce6c545c303c370f83609ea51b72eb502280eb0c5a18bccf3c7553c514fc71dbf1edea29a15b3059dc1434f51a167e21c90b59f500aec870e3e50920664f44bd91ec1c5e9d39234cd28604dae1c2fc829033fc5c53407f8018f46332406f433f5325d69f967075bfe83ff9a6e3d8bfca3fa10aa52fb3d947d7fca0601e8c119fd531bf991227141f0f76e29d7fe36d61946f112a314cce6f6d5f5116b2d953394643fab610cd4faab3a8706a08a01f18008ddeb5db90e5d8adf49f7ef69a81a8cf5e729f53542b1bd2a1657f358910dcc7b73f02c2951b500ab05556e8c7ac8c75c73792327c1f0b8ef82b57fc372e94a3e5e5907ed75a86c039593dcdf119ead2315a20f92268f19f233ba9b26169f7171e6513906af76c206c099dc3232337a2ba21a4e2e8eab4d72f8a0ccc26d632765ce9f22565e7f2dbfabfd08dd8a7efa2de4a4a1b7c35f04145f80b90d8211143f4767bbb5f44764243f365604321790bd44f522f4d2f18599d2c3071f11d3283a73afda82a0189d277a0d4a38fab1be535f26f85480ff388d3b5837b38ad98353c72103c306eca0478951fa9f7363f7035ae7fc0d5e01fb1f8b274bd4dd2f2306165d28c32ec5ed3986db2c2fc9de53ba4a7de5c33b1f9c3db80b0472ffc9d4058cfe3ad23b0da9b28a97a71fe57b103893dd050722d4d0c9f1a4d7440335d690795fe1049765770ca024cfd78bc27dae60c5621a40b891410bf55a04a9cc383ec4cec1096bb829ed458cd2d56d1058d4396848c091723d8175d5e5024cc9a7d4d08012e0776a7e46776722fe84eb37d659822d7b12374503b7c7e11a110959d57462e501a3668d7cba59be26344e73240af87f97d4dff47f1b4dab89be77baa4290c3b114afbc31a4ac79f41d012a7cd2564f72e7b5624f292e5c49b7bd54e6689c2087292de9ea797c84004984f29deed27496e0a431a31dec199b16917a7906497cc35709d6c5bcb329a1724d4f896bca9593c0a0d258e2e5b8e6469d627b23a71c007b12118ecc9bf16a5e404f1618df963d8252e85b564797ed58d42f2"}, - {"0000000000000000000000000000000000000000000000000000000000000006", "0005c144030ab585ab2a30eab225663dc7ced30fcc62184f9a78e7dc0d45d416e5396b251235de32785203189426cb289dd3ef1440623b8bd69b7deddbf8ec0da47fb7e5c4c501c24bc5d47e3c57d97b3db5cac302f3fc93f6c8529fad480a83865f7a0ab7a43893920af3b5e6a7d002a3cdefb21e0f477100a084fc6a0d594c93818d69af5b5cfbf5f9244fc5fe4ec2f8e28d62d2652689255bc12b4f68cf3571152e57e89de0fe08c4c948f855480720e7221e37e35d1add6c9cbb1f264c75b3eed17946ccb57282e6aa6081344e78324612a0c1aea3a1b5ff3bc1337eae35f04b5f719f4170138a1a1fd1d76dabcbe72268da79d8d52efc6a7f920a8b00bd71865e644d5f5717dfe02f9340b59fbece26325c4f45d3deb319d7058d777372417dadaeb3071da6b45e30d68438ed2c04ef7ef50e91bebf5550372615857d2eaf7ef39a60264de575e1063b4452cd46052062b7a3a346fb607822194d5b3f41366d0b1311172b3ace03d684d37534a85b905ebbda697cfb47a0181cbbb519995d2dd0f29209cfd8f4e2e54ebc6cb12f750cf7549bcded308b27eb626d80ee089b7bae352ba3dda65b1ea4dffaeb99900a6b8b167443192b45338a83a1948d61519c34e48b58cbd5e5e00d3278a82c57127c44ce3db531f92497a1d209560aeaddccc1466537e05de898e3af70e4c4c66b6565d14c1c2ff307a3369bd59cc1cf98dc05f85ff0c516cb07fdfa23241022aea13c2c09fbac36dfcdf74739e3b97e165f0c802c5017663e5d6bc411d804ad6025b21f72ded44bd0a58da4943a27dcd007f858c091f3111efd437b140a0c8d131b5b24eb07752f9aaf09f9c2f57f282615e03b5f5096db69420e43a7856ef021f3df725c981512e15e7fc817e7a75c518bbea553ea76bf58c78b18474dc6c9573d82e528832a764d785d4ab717c1a5004a53aeb8d998e0eb2b13e9d0389b8da16758bb4a0327146e48c8a92d757a19ab5fef4973bb775dee3b07d93d4470c3032e4d32f44492d4cb69cddf51bb0c49b92545cc579160bf2316c96cf18645e46b3fcf7305a54a24e3447c573333532e3fba4f499a90f3d7872da9a75af75105895f9cf375ab62d60986b8ec3baa1eca190fa3cdb826944ba6f09dda27fdbf497c0fad26a81c6a75b1e8c5c2a862d3844722f5033e7c5d5001a8a1403e6d5bbd9a31f315f69e4d813c7b8ce004057741d4db90f7bb697d42fc6020516359787df443063ce1dc3e567b85c13c91d07798396d9e11b508ff28640d3e639068d7a7c945e4c5fbc12e700edd9af304f88b2dd967ad45afe550fe5423865961207505af13d536347ae5eee3b08831dbadc0e2bd629af93af90799cade484e2e79fa66c147adb4e48ee1fcfca9c012660d1ef98802fdc3c3f3ae65ce4362be8e36313302f5bc7e360bff86798a303bd7a540ed224c5197a67b597df4bf6722857338c92809cb95b6d02c1706a40ade0d139c0b9d1bf985d27345b1b79678cb54967b32f19e094a8eec4d8719e3fba37af2fd81add298460464c5513d81b6cb46849092a98f5ad0cc57ffeaff04c386e516193554e2f80142841270c8fd784e45d80693a5224d980abaea4905ce4b425905dd50fef12018dfca457109fbe36313925a8d15dde64686d8c12406902f83814f81b10ee4d0b3e97ad0d8dfa5ebf09226d213b177db69f5613cb4ccfcafc8ad4c664ab5b8127f94364851dc031177924ba3d6a3659538d74c151dcd7103680a1e8b460b15656c7d82e601639cc8eb0a512b995e84275aded8121409ddcf362c2d13f7eb0c83a459d662893148d5a81f6572803663e0349d9d1884d2e5c5b67d35ff8cd697e0ea993f4dd49eefcb31f0b482228f04a14f125328ce2de5d5dfccdcee76"}, - {"0000000000000000000000000000000000000000000000000000000000000006", "003ed39a7e92e5c4a21132e5d32301a1d8376fba6b1b011feabb95cf19a91e532449dc35bdde6b54a8a9210d3a3e908dd2bfdf49737bde6880ae349f54f77d4468c339a4d3ea0bf826c8bf51ef9b7e4f529ace2f1342742b3c29a0c7eff632e2aaaab799cd975faf7928b945eed88d64b897e6d4423064c13f2734fceb31223eb679cf25d601784093a7df70223a0f4abf1ecb2fbc0b67c81c933f6a98537d98780de1293d5d342200a0a816f7052a853329f4be39baabdde2ce78bb6e15903a4bc4320107ba665186af678d0a25a118c69d18672bee3c063b5ca84154ac19b5de2e067699d6213afae214b651167de318179639e90912282f11cb7d01269728c7263121514e29a82b5a8c1bc3035efbb71c950118b2ed530393bcab338f6194ff3a219f306a0efcc74305b3029bd08085b34ccd51da11a057c78a5232050700d89fb13acf455c854e448a04a6db4f82011e91551e0de0507b57451d44f5e079990378bf2c1734ce15df9536bedaab35152031d15accf9d6e07d1365e321d153c78f7b51e843e6cc194eaf473d92074498832402e79a0d6e3427ce73dd44168bbdb7a8d80167dbc7e21a2d45c38a80c16638230a612816cf60045d07592355d1e712bba058e2062e24627f14a77003c57398c3462880961a83c6286bd3953f43f265f34874ab1c53e8983d6b8ee9e286f37bbeb224bca435081962a95384bb907a07f459c737e492d0463b8ac62e554b8a04ea4f0f750314d9126795a60f91bbfa671e2b44e467a762195e9bf5cce7e41989b35ef6683449cdc3bc6e1b9827a3dfa68152d32207062bbf7a590978019a45545b5366f0c135629b9e61c76c1e6646136d86f73921d437d3e60981016a3e97a8847e49ab0bd575eff4d090c57b6c112442c2ac12c0463c00211c356185b5700be1c3a2d35231c2b828f994d0e61801cde136bd80c65459213124bc40d6ce33969f9d0a1fb491f2bb53e543f866e2c0d33fcc1a4ca6d5ea050ba5ef29bdc437aaabe964e9f754be99a76bb4f5e00e5b14ca0ed5ed39b8c1b74080fef37eb522b831260a39bdcb6f1c6a39f78404a591eb8b113087ee8cea3851f4afe15e4b6b08a8f9c90757cdda8a0e34b953113657baf55529656dd0e7b4db7dd7d3061c5d31901d1d35adae11c915e7a137b7b957db868475ff916f0b41ad69861698f778dbb0b61297cb26a27dbbceb21bc90e161f8f79e5eb70354c9a68afd15882b4909c1d9e70f231ab66b3a2d3b7178bf2011232fb9325b71f06c79b015c224ef3bd73a623d6f122b7a8df28710dcc9ed902e749cf4a62111b6bad791daba84ea8753c02ec8edddda8faffef24bf624a9de94efd3525f413cfe6fd6d26a91da6fc1b3ed564031b89b75f43c6512aebe2fb9fa79537f7b6a1f46b986b08c49fa907083cf859f2831692bc06d1f8ef6be56108324c59bf1bfb16c6f609185374f6e29d5bf63bc8c9f8b0b14b12b3a8de7f655447440ae51f9b45efad7700fd86a01a9c874b59e51e71518bf1ef1ac15528b0c9bebf1619c29cb3ad4fead6b496c5cf75dd1fba5d3719f650224414f92f8fad496109347b96651cc5cd2e5f827326c2ee6143194e2d750f54947e68466e288a5b205c344854cf035d6c82fa0cc6d04bf36ccfb1ba7f55f40b81e31e585db1e126d1ab232c663cbacdc87e9a892d3bbc4d4e9352b4d65663ee1854cec0fd7c8803931b34cbca8862b30fad1f151aecdae2525b7f7b32942221c42cff1799a2fb8a23a2933c1d0775f97c1857133e50bd860aa25a63a7b504d0acd46ea16b1cb0934182bf497a9ee3e9f1b5647809d8e6c3440e5fc23614d745a10572ce5bddf0d4a05db220a5911850b1a11c745ffd85b7de21c1d043bdf0f954c55e2add53fa"}, - {"0000000000000000000000000000000000000000000000000000000000000010", "01f460cd7acc8a0b205c813580297a189abbbbec6f02882b11ce42c03b32a8e1f53494bf0979a5d75d0f243a1c8148556666b54d931f3ddbae8573b5f7f8a230792b71b42aa519f2b256e5433fa0330cd8dd449f1d51abfa6aedcf97b73f83dc6ba62dfddff4b4a16a201b128fdfa5be599b20245c5fc32e7288f33ea0ad37a1c4ea0a169091459e5877895d844ad1ba396baf4b96fab70ae0215fbfc4e65a07dad30613f23bc44e027ea8a5bd07a71ab7f6f0b110b918f1db889605a323938aa2f4ca7bca60e7d7d629ea3dda8dff7909670d5862c82258872aedd7258b9cd031b1eb1eb4443729375faf14e654e7373dc5c870b8969eb9755f540c048f0a5af6d02aa78b18b5af4e6623328548f5a1891b37b913be6e5a03b504b2003c3083095e413eb23321d6c16c61174a2d3ea752687de16877a5ee1e20b265791b4b361f4bdfe09196ee443c5166a039b7f73e071447c264c93a65c277a4d167cff245af335a10030c719a76506755bb871bb50eea2dba59f8203e727c0fb1bb1d2a11d227bfcb47397ee588332a511e2cfb36b909c80d7a350bea3b338d36cc29a917b0bc9a7f0b0b6db40c43705cc59004203e6db18950b8f1dff425fdd20e50d3b746c7f8e2636f42cb3d4c7f904e212456afaca33839cfc83c236153a6425782b63ec95a3db1f6cc6993b3bfbe1bc62fb237c3768828f960380b971587b4e34cf3a39ee11f8ad155fa149bb7583a10ac6f49140feb257f0567616c770d13d8bcdfb9511481622e0b1b7b17c1ffb4a514f0e32e21b8b3ab201d8492ee8d07af618212f4ed0c674895ef32d208f20f995eb6a03a365dd62b61d3b3283ae2b285dc40316267f5c4c9a305498491a7f12ac832628a703743051c2bdfea3c563c38c4a885891733242f571f7b27b42597c15e47ca00cbaf8666ba6c4a24ddfba135be6b0622c7576b44658ee1919066c88503193fa44cec890fae38a4e1f03a03e5719413983d957d635ddd46100fb9c4eefeb6d12db755b8b4adef17b234477949b022ade6f83129ca9fee144350d3d87bd9d7681d426b0818a0dd7a02ec51f511f20697ba1805c025d379071d7cc57a1863f1d727dae3a7a243463596fcbd4cc12ac3d2e498d56b2b9472e5ef68cbb4edf26d5c5dd04344d68e1b97eb0acae9c523994ca3a5f73698fc1d0edd6f1219cca2707acbc34ceec10f9269f9db54fd111f1f4bef2773e54b81f25745485ded35e0d7beac2faba6879f201f8f50b603ef55bdbfe1a1d3b8ed484fdeaca8ccd9dc954b8bc5c4c5b709a5f18cd50e4e18ecf7cff8d09badbe1cf364b24b0f865e513cb5c120a824e6a79bfb498b3a658deb4af919fa5afd70c6263f07929f904da3c243d7054c72111b5d93fd01c42b1ffbd59791919d544b34c8346dc74733d37a508d071155e5969427f52f32d699256ef01b07f078b4c30f0b0e50cb65d0fbe336915e51327fc46e4e1ae8dd1973e3e93a09c83d2456788416fcef1242031a84164d990c7ce5a039bd8519a584d3bebbe1f74c3c498d0b403a9b7a8e2a748333e57263bbc615c9be7a130a1f12e161db8c67509fd1a658d54e157671c3bc8b011119df87fc9c05dd506445e437414741a96a51238012658177c5eeef5995bca3107556f78a3bd1b7530d07a1fbbb8f108f8b5ead10d6e173cc086755502c6c3703b2f0a94deec5c9ff655450daeb79cd51fe4d16094a9381f40b747ef5fda524f175679dcfd7f5cceb24b84c84e4377a2dcffb23ced2fe2765345dd25dff214b8a3eff167d13b9c852a42fb02ad7163bfa3dcb2435a4a048ec1a37e9a1598edf66463bc70e7f6ebd2cc05b3af6d705295b190989757d9b832e2b9e02be50a62e6472e04709264d8613c7f0cb86152bd1e664"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "000f0222044557a1a3f1e59f77c1d05eb6ca77aa3b011d436e92d453d2fc1270b7458c8c56851fbb55dc031692e27609e19aeeef8101bbf568184f709729b828ccb31de159a270f8e6d4671be090c75b5cdbe16810635a9ad2fbbdbfe479550772b8a8de02dd74497929c872fd55cad6809ef93799e56019d2990196176027a2fd58aaa05a5d32cf82f9d9df9f65338dded4224fb50502d8d477a346460780773f38eeb5ad166900023e1455065ef0176fe0c27f6ef561ab5a1c7d804f30abe3f3f4a1f8ff19e5176c74d39d425f9b3317e20268e3b22385ecf08943d1f3a157f936a784b9dc754216efbd3eb70cbbc967045751f3c9facdedb6ad7502c1eabd788952399cd851f54af0d73938206ba4b00d692288f464739b46e341208a9f788ebe08baa4e2094421c80d0f4884b2d8830a41357585097fed6c38126916fff54720d397c7114dfcec0efd85446d985200117357d78df645f41575c10c5eb452dc9d98b0aa4afe3651a82d184dc7b5460f4ffbe00d86487e7c44049591448151f0cae11982c10d74be720d2f51b6110e0015953444e58d493f830f15329981aede986563087bd9cf4268fd574deb5664cde606eeb910f7a5261b6cccb5314c16746f2c21dbbf2ef63ceecf2b1c0911fd341aca65aea993aee23a95210edcab23cc503c19b309c7c12a3741572bc35afca20261c1a8ffa2f90abab9b6ac85e587a198043cb3acff3535e9fc450435bd9d87edf33135b48f443124ebdd51cddc106f5033961412b6e10cc30e4cc597d1d0afe25ff4ba2d6c35edea841f29c285a36c2524514cfb4afa363ecb330ad468df81aa64c5d599d29c5b3c716b0e4bfc243063427363efee2cfbaa354927bf6512beea4559aa651b96ccbb6ad49f2f0204f1dfe831ccb917c5f091e9405254e9325515c59daee6fa753e9962ca02feb13900a903ddff290cd582a314180ff84bae4ae6f98ad208f71047f488afa506e8a11e1633b6a91f63abcd0e33fabe25baefc7e1dc9c589557693d027699bf96b3498f5b2cd69e57290e5bd79eaad5fe82dbda3753f00bdc9092d251c8611963345bc2f744020c839e027c0df789cef00b02aed51178c555ee77eab0c699fb260cc72b22619681ed38b408527561e122f6767f7f832493fd9293970bf78c41d7647bef7ef2fca8f8f3420857f6dc5b4f2ac70283a6e912c7ac4a0a4a1260192e2475c718f1d587ec09b566614358c9c92374c3e41a9f96605d4f4bd740495273ade22ff25f8ddcb4491de9fecf7f9efc85ce0a383be2684a0a272f9f99491e4b7aa3623a0f6df6e645fc95780fef3a0ade48a121064ec1714a5d06a551a313595dd755f9957841f427d92c33e5e8ff235dc1b7f03662df4a99a457a2562d4663d8f2ea1347851604eb5aebd1b5bd7d9e933c049fdca62e62a14b703ce720c23c32da401b369ca82207871ea5ca82eafeb0f5ea82713fa6125e3b48f80c000ae32a742259d522a0cc2c2015d600c49dc7991f60bd210f9c9dada0ae6386b24cb67d8e5db92733129bb15cbba0ec1f78df486de97cb2f2eb65d772d830f39d2f8b586244fb43e9fdff752bff65c1fde49f164a5bdd63dc13dd2b6967153ce2d1c28254d68e445470cb36433c429df67cc6f9fbd732820b4557daf607a4f17133cfe9556c55936f61bcbf6eebbfdaa1d7162c4d597908760bcc03a3eb086da2ca160cb0b2711a11e3b6a6e8caa5c72521b61f3c961182d36c8bae23b34a83be9610013bec8266add7cbab17db5c05d7098af7b85af4f9cbcdfe3c1fe1725ac31a0f3afefd1ef2ca0de648733dbcf382963537b9222c5598e91f1964f654201bdab93bd9922323ca3bbd9e283930544967ecfb419fed3f6a569b1b615b3e5f4d43fccc6c"}, - {"0000000000000000000000000000000000000000000000000000000000000027", "005b86c33be0c0b9bbb13648ebcc428e9584dc3b1215f609aeeb6cb103902079bef67829e6eba839b18a0454d23f63c8abd5a60ba3a9622775053b65bce948074be9e449eb2fa5adcb00abefbd2aa87c37797898015bf562c6df6768fc2f324e0ae9bfbcdded49fd0d19b4a99422ec804bb698b7672e3d1e0f1aefbc2deb0383270ea4a1efc9eb9f846883ca151224baf2ba1226b9bbaee70dd3e1d1322b6cccf4cf3339e039e0fb0af14da450d491daca2602e21753413e0ff9bd284d57277529c8964155aaf987abe97c80b296df9a0b830ebc25ea6228fbedd5a9c1177b32b92905ae0e02aa1c740e90cadd6a5bba3703e2e9c284bea9a03bd97f123fa497110a5e3a89fa324c20315aad62469cd61813ee51d1cd788feff6f133bbb4f77cae23aa1346321b67aa9206bc3de9f11256c7165b1b12fb95fcd80a1cc3dc637ddb2cc36e3ba464d0395bf983e29d032905a4f431732ea6e7bd05e41e5046ab0ecf463edd4b0bdd34df6dc4dc2a8d1804ab2ff26a6db43cd5dc1507967deb30de73efeede308d8af684987420587e670850feb9851e5e25bb9fb089687aa9a52edf5455e6113a31a6e4b0032d9c644411ccb4930681fbfe914342e67fa643566df7a56e974445f7cb6effa4385f7b2153444e628d76c73c6468eb4bd2801288feb5cba8310266b5856022631a5c64dbb1541aa5cefd7885550b016fe5271a4a69fe0ad602a947e8d229f8d8b1a11454d306960c36e2ebc3e32efa38648eb90d3b66982b65fb40b96e51ddb129b2f40b25749d6e0cabf6a437b73fe5d020c9730a60a55de76e953678385b6bb116a342c343ca8ba2773f724112bd9d2247d632e19e58d262f5ff31329ba37aa5a27f4e932e324f1c18ac261b249700251233554303986fa5426d1a88090fd62d891ae844e4b69ff1bf93f64e7787d114f033db9a0278179b640f0a7fe49303549745339ded54f82d7f86b34ff6b8a521358fa309e1eefc278f31873ad5c20adb8118cf5543b929b884ca85cee8fadae15b63045ca6fc27555f5ba35c6e55cd4b3856fa0fe21d6b0a07dfce73e9837ed34176607f16b997c85b61c9a28323cef1ed40abfd05b6e5a7533fce75d76fa27fc9b9146da498c6097e015fedb2cad2e5d401a0b1566b4a4ce8cbd75d54e0a38378f861725318025931584f860300cb85a792c614ed42829d29a908e524ae4aee29040973ba4bca0db3d912f28d377a5da0f451d3812b067659b0e85d1aa163cd21cbae92098353cb9ee68a2a5b6a47e255885f648df501adde230e46f7b3ba09062a6e5b76e1c1efebd1c40128c39e854b689dc47815d03b9c56a64bfd450f07658ac30a12215efac19e15cad4027d4993b1082b83a535eec39114ebacf6241b5e0d7733da8ef6ea94637b61cf08b747083b1701097c9f6c9ee6b6438ed372ac891a1bb0cec31ce807120bcc734e157a994f9ca13eb73aff8954d3b1cb6c14e1dce7b2971547173b75e388c69439aed67bdbf818200a08c232da51fa96c1af22e705e2c78cdc7e090f480c3e9a29fb5b8321f315c6c10dfcfeab4d25622d48a2689cced2447950d7d02fe63357a3399ddf5c11b796afa0081f9eaec8b1dab096c2374736ff212a348446626e91c09d247a73a7a87821e8edf4ce516f0e833e4bd293b7e3c69d4b2f2c751057c80d1f46da516d93cd0fecc4bdc51095e75b414a259a4fbe44e810293ecfc6696f5f5832324b6e76e87d537a38cb6c21f2ae1841da27d744c8d489f5e1dae57976d552a80eeb68f91a2cacd3ed63214d18b8fa68fe792db4674bfb2647badcec654084eabab0fd39e3582a3e2efa10e372ee6655bfe139466336ad56f91310241f15761113d1501b53094fab3522785326d14cf9564b3290"}, - {"0000000000000000000000000000000000000000000000000000000000000400", "003d8c676b8be132abb260199b5e36a02f1db1666c3050d1928377ea75de7a4a8271fc29c33d619cd41e02aede70c18dfd2077b229b062620ac6e0bd5c5fdc0e808b5133962da7aa9bf4e608643cede0dd1bebeb0cdd73b15ca6d7cbb805e1f7545fc5953e860a87c24daba46415944de74f2ee8dca4e27e6643411f86f643a40333cc7a1cdfe5e424a720b582455cc20e6280640ecbeb63e9654587101670c7cefe51cfd94fc056012235962c417145a4b328bc4047c20a7e22dd2fb3145230b15f105331bc8da1fa522495c2450af9a4120535ddfa26060fab00b8530773de90ed4b48f88c8d05bd2d2f2f544413d3c3253c09cfaf93d2cabfbd38034a292600df56d7b40151096fc83024cfb1510e201b936caa48c9a6b0cd6b664c2efd412df3bddee7850c151e161fe6682d96e8a1fbc163560e2905381ee81fd608ffe39bc5b961185216689357a20c675abe350183f33b90830cdccc7d71291b49802b5df67d2aee649f3333d1708b23c0897658e3d11b4208cf9c510e28a3ac2007537adea74fb491c15e82cae8b19e70f45c339c1fc4578630c682997daa600f92b6d77ff0880dfb72d6dc15716f9b5a26361bb691fa09ba727ae912afe9d2d30b39a18948b40d8bae20897838bacd3f13876e19b0093e63f4d372457e476a50e329701d3a1f0e9fac56e379a530c8a22b192ce9389c24e76d7d05ed38c79c468a75a35de0a96c1ca37b1ef99beb3d1641c44d89d50e85848162877a613f20a913716c930f559b0c634fa8639cfb558ad2becebe1318d4cf4a1bff5f925c6acabd78a484b5b53a926933d79c56750c3181cdef562857c1e1e10950b87130ad67b2b04f1ebf03c56fd660e1d75a979f2fdf9bbeab87bfef081a6576f9d114b5f4ffc6123c2ca185e8a1769935f71b094be549d5da42b4f6a1cf06ad0f809a6fc7f9b1014091005f050da648c3575ad0f6eb5b7de65dbbba773573f277af77058906286ead65aed696f1b60bcf0262095fa2d98eed1ce0034be5f2d89e786c94fcb6105a523aec17bb618169d6bb0357d749dfdc79a8420dd42acce40da69d48b8f5abf4b11ef692e67c602238080344286a988ff4d8656c36597c32b02bb6f5eb4a369c15205fa20bc1a42937496cb8f29811ddf80466522f6960a479a1922dc793c46cad0edc0f792204014a8e7c30aef1ab8830e697533dfba9fa1f1efe3f3bea6471b42b25d39899382a0ac55cc25c5f1682fc01a12336d049e436dbc7045614fa4c9921163539a32bff070402b07541ef61e3953f6d6925463cdc3b570d853461054806953254b31e7ef6bb819bcc17b0d70e4ed268b0970d7105f04569bf42fe755fa0bed9151ee43b200e2f390decd202a1e5a8d48dca14b22fca3c9dedc150e4a33b677179cfbbd8b7769fdafcf87b0838ca64f7703499f9b4617c753ff63890a5f5b5e20c4d41cf36d9d157eecbd255ee39b7a4aed348a40b0d574acf9ce5d093df4724d06777a3c6d4fbbe6dfb173a75acbf6d45ab791dc5f96ae3e3727c21fc31cc09a93eae980a9375dd34e4a617600d66c12b3e5022467514f39b2334b9ad02772a1b628512c7487bd7500cd002cd2ee4cb8595e20234b63ee640bd10d9327d13bd116e3c0e49b38f4d941b2c5e88f6a74bdd4e4c0bb95502d0430e746ade08f495d471c30d653a63aa1a00376442abfc876f7965e91f7f4171c627193d081244b8ddd9995fb9bc33e42522ba2cba2c5cb9fc701fb331628b90d9ddf5ddd6e428f9a4ea37699473190c3c2a991e8fd20dba1214ec976174460362bfe5cf1fc56cb3234e1d8bbb52a25a343571ed7abd3116660ed3519cbe29d29f9b3e66c74dbddeb2cee97980ba1f4a5c8952884bad4eace33884e38e71ac71b8fe2e"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "02c7a8e145dcbc037ba5031cb2d7d5159f344d3c155661bd830f2be755ac66a63f886c8ed9da84707975143bf25ef752693ef6d46171d9c2a7115c4f7174671a4234182152832f6358947c17f4635788035ed5c61cbad5919262ccf96226f3533855083abb141857c1387b1fbc4399a01b813995de8d4455b9896f978acf2113294163df9675fc5233c4fd7e42b1bd925e1f34400a57dbd696742b8a98a668534b0eaab085f6f853034eaaed58649f91e1c0c0c0c4d9d0a036572dd0172b177af8ed96a24ec177046917f914a2a4bcb695e505e0db803fd3a68926a900996b5c3dcc7f608d7d0b3fd7c5f771efa073b7fc645a5952c58ab416d6f08c0580a0f5e844e7e77f40240499ec25263578fbc6ff11102fe6668ccb50871281ce4ca43afc907b6c0c641359518b9c883aed826f92db962a4eda0732357257240661e1dbe62df3c20387d82d605d92fc2f5d44c1048c0ab932d1cfdee2956151983a8e4212969cd0bf2d45ef4c0e4d9b8b9aecc7574e6346c26f881f231818c1297be15509412a0a53ca61bab2dda5091ac21b29f266cd6e523f20d6f084ae4dfa1a59ce947c50c4079bbd175b0deda888b94404ab4ef79d87ebbbc43b26913a5dce4dad91220a66edf7f7538ddc4d79ab991121429e86affe55bedba4737d2c9725d157f1b18e35394bb95f94a79b717423ff75f483160e71da6aeb0dcfcae5b18ee5f8f7fc50e8b34681f15722d243cd1115b663f2564b83e450b370685606c931935392951d6e2b93ed47a02a4e0201d84c268238c6d0d9aa483660f7484e3865d5fcd043c59048897704467b38ab1c882ce2404c881dd043a7a6c3f20f561eba5bbd032aa1a791e814ab66b80283ab3d314695359e6ff4202bfc2a941f6f3715bc0344ea1ac8e76a9d587caad4325f85bcf42317db7d42d58401bd8395894f8e6ffb03a129536c472bd1b673f3b6349e478ac04fdfb49d117919a6e639d243ff4d91423716ee32bbba5b2e3d0be97cd6215c38eb8ea14b52c7ff7c777b059fc8cf13a4324d748881549d99d17297b527367708161eb0046c156c004439350b2070952957e69853d315e7b02707652cdcef3ff7cb9be8d6117e27a2932ab9e1aa2475fe3d87f7a815bf39c35702b2c6c1a4e59c0e602ec09fc6f42985c37d1647a23be51f9244f8d3cee505a61f81a1e74773bce972027d2d8a99e60e341ab115060242c38d23b2be25626464dc3b719ec77e5c6d0bf70adcce43541ee289417d21337202aaea3ec52b1512ffc1c3aedd3fb6e2e425a35807f9fa3450f9c413416cef9508c592e195a3c8b3b7b98dcff57794443afb433be1a91fcbc588d6cd5a40c1e6105939328c1bc6c6e7ad47e553838243b509fd8425a4573bef721c7b5bff844ace9ddba7879f5df0bdf5f4fa11e8a4046bc1223614355bd28de1ef7b9e32e5c2fdb8c64c43a9aeb368f09fd5fe6775d7e735e69a0bebdc8f950fa96295ecb3e163dde88298db15400930d62db165255554cfe994836d9f2726e19de8d8c2a6ac9e9373048c31797636d7a5ecafd81d10e6265a9a4458d6640f6956c741e8b8c3864859dd41d92e269106f9e1f30b290ff9a689954de793d2955b9dcc94da210eed5f2b7099cee30ca705041344f069c345975829bcb4dd04f8f475534ad6b4822c611ad3c79d485f213707080f8378d26f44211d2c29130c7dae6449453c1e349a07db2d5bbe02f619cf08a1778c6488e9b2203a2eed1f53093e789186b5305179cc2669e71a92af9d62540789c8d671ca7480e9f370c65629254440025a07bd3929757b215b887ff2201469f6e10cf1bb4d7fc6f016265d5754660e8373217553a04f3baf18069b97953f15a460dd231fd773220752c852e24deb17789ea3"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "00ff597115286b1d48fcf26e094c5f0179084e36590811fdf3c2c8d6fbca0604154cc45f4b7389bf877f02e1e15da306595c72a8c0bbdcbaafd4841765ea5b0414d9b2d58d222e919dd7e80578a9cdffbb5e5fec03f3f942970a48c51cf1fa3377ed4f4e99d31af5e205f4954d711d9e4518fa03ded777b4abfd307ff1b2078f66bac850a2ad00788539d5676323e53fbf96781c10cd212413a922b9c7620959dc577d93e51a1c2d0ebafaa45068c8e9bde940f4d22565f2b2bf1aba461b3631efcb513a4bda6f844b922735c5296d3a5ff2174cb5d0924a4be38ab963f7312aaef9acb01e2d4d34a326e086e6ca9bfeea83994521296f835c9e258310f142f9268727b4f5d3942ac274631a34c0175aa71a56bd4e36603f3b179f732171beaf99ff5f105ca9169d2e277acce7ab57a4d8bf96effd2a90f5dc0cce1c1396aae890eb489d96c34a8cedb1918b04ed417d01b0b1d556d796fbc99340d3a1fd28aee83218113b02b7d114ed956a1fdccdd11362d5a78067a62489fa3d8b1d82ed558a58c8d084d4eb6180422af7ba9ae046d14faaf7e39ccffe43b51d3a5e6cc22561337c25081df1aab24bd075c8d400f3dec2b224a87f1c75c80ad51f52678edf17605401be2940f034f171ba032d265ae18552c99f8f5cb86292b052716e0dd3fb9588379d6ae4400e55db9bb53539eeed8b75eccd30b5ce03aec61b2513fd75d41856cfe5c64ea213919464f2127b75557a6cb5d7fb104949a07e8e6b8bb93c997c12bcf4d4ce5302ecafed32900dfc2040dc63c6f8a62854a2415ed01e088d4b25cf9ce32bca7cd57d047f102621eb17ca840f945d664ea2725b26cc593ab75d1631c68249528e1d55a436bc6847a1f6ede87baa0a21a426f3ed5bb224f2d2b2307ad37b9550c83c66502cf6fdf739261f97ba3ce385e4eb13a6bee4dce6bb0350257e03e5ecdfa9e221c34e1c2e05bd887f2b2915015d17d6200ba94a6d824708ada25e60c5bf55851e230160b852d4479b6be815f0de92e2a413fd59272ecef4673932eb67bb6fe353ac2a67159f495fca5b064ff60bafa75b35f5b0f0dc3166ad176c665dbc780e25be8884119b63dc2d5343e171eef5bd789596861be80ee96adde4efffd92325c4d2fff92fde79baf14a633d40cbd49ab9682ae9a33b53bd0e8693158ffe0464677ec4e0fadfcedc633508be32c1a3c23e5a53163e3434bdf9e38bd69f53fed876032609eb38d5652a85b4e0b0db85d3e7f5c5a243dac7ba0ea539af362b18aff205a6620ff8013681fc3838b9be8b5782e009b512df6a311c3deb06b0ae03c51cfa66379fd84936d48b57576a010bec1673eea1a08e59aa86541c6d1b7377be7c224169318f550af7f9c2e2a236b7bb4c3335975319141c018165f88ab953b54b6be0ff5e8e041b118c35949809c423d207384e6f597f50cff7d82671751cf3b54e3be0796278923c6d8d1eba4e4b950e3c7106a91359097e13d13466b24b2cac26e82829135ead0f70983c7cf63ae382f0a94971eee996d9d308147debbf57b36f558542e84d4d27badc70fed9810a7095bff446a1a4e400710a13e565be4285389e600f7807104585c190ee5d359568c3ac3efde2b9cea316130d7fd2a34e25a674e40c99f103052af7566843129a10c788d35a6bee5dc2bf37a31e916b3833854c501adb7e32299cd98c1d38e883dfa72b2f6c3c0b391848135358defb635fd4a7d76bd086160cd41b1db22aa773aadbda72774bdc22e5cf613dea734798773a208f51686db70b61be5625d53ad7f1c66b1dbbe7c9240b12536ff2ab91bc3515a4a33caa21e5199bcab32d795c5e9b93985bd99f1daa2c78ccbb6bc41d6a866f569bb541b8d135cd5dbaa2fc6e783b391c9a6e29"}, - {"000000000000000000000000000000000000000000000000000000000000000b", "000f72279dcb3abb7879e4072acde4a253c658f93912d41c7c01a4ad95d9bde241c14b335c9ff8bbccac05fbe515c44e2485eae2823e2eac8695a672d15dc111f6e0c1344df74ae281c3521f768bb5b2577fbcf20acccfa3e60d7cd162a6426136ef375a9f273c408e13b98f1724d3f7e7829da3d30bc6a38968e44ef4330b40b214fa06f629264526667d78c341b5f8f61c331cd35430c8e147a730fb21e2536f60f0cd5a5dbbe501e6c16b9d42bf01d5e800ecb3c09075e5ddb957180da3ce20e8977f3bec4592cc4ff65c9def5433e41f088c1568cc899eec79caf09b6af2d6118496d48cdd2c32a1db0e29b901adc92343224a18b53a5ced6d94102d9c1268e4c327d33ac41db63a5b06194a17044e30673df9965605ad2508b7e8a76ae3aef8cf7fce591255f58e294f69df994282cd86d3e2119b785e121c7a59369c54aaa477adc8697651d6c813ac841dff600c8207926c4981f1d03405fcc1c44da67e66744b4813c569f8b81504b1f40ca223ac313e8da1659f05830cc58d2b0b97617d94a5d3d6b846b3fe64d9ba4e8f3b29959c9b56d5e4e61d494079789762be21b788c8112d9a406dddabe794389194af5004b9698f7278001169933968522e2d568e07c5706101ce7558b74b781b9b5d24fdde87f7a5b458befef5b58f6a197bad9b27317e23189fb5d9fb7d2307ca32ab81f2d85e812f0fa89e711d49e866bd4682882335dc0e6a98f978ab7dd0dbf86bee4bd7bfbe89692c4dc90efe437cedf434855d085b9b0f4dd826d54f456cb0aa349873e7d234d8631cc10faa7abc6cf35a8cbc371756dbfcec0b18cadf98c5923e119cbca4bc2a3b7e6b7d955fb01668eb1b73b0aced87f59249596968e96edcaa3e95a71f944e61bb49779b99a97607b4c21905f4ad76f29a31bda5ea2457be7542557568d9d6f9995a6f0c116400897c496db996bfd015d2bfed9b51a67559373d8d33371a9e5b601fcf4571f3965fd155529aeede7c8a07f436d9c58be0307eb722b3891b845a70c174dcd23dd8ca0a5f34f1b9e0ded52c32daa005752336ba4f290c67dad7370723fe9c454471dcc36a7ba1ddc7f168cbd7aabff09c0bcefc7994f8702d36afae79df06480a8c1f491e9097d8650570f65239657934da7d5687e0d6022ee5a289ec8eaac5fbed13d2c39217fc8f034be25bae7066d5b31a614756a839ddc4cef8ae5b26c3e2842d20416dc2e5e3f9d7fc43e5e7d4f61a2c0bb0f66a07524e513f380811a6ece9de9d7a1f2532126edef15c6ed469e0158389e6cca63f0c601d6889169c3d466e585a99a826e29c84a2e599ab32b174564dc57af4c8335a3bbfc1f7f190e3fdf24441f3f04d1a6a5ee9efa0b657f0baca1a8b79a1caed4efb81cd2ca89e2246f23933a8cbd89dcb7292be303b185a7c059d7a56c0e0d9ad4367e0db240fa7f074959ca80c06f07f4723ceeb3acb69035d3ed780798906974d7d23674e3dcb1bfb7cf77c34398272fc155d863cd7a0378253db7fb5e0fbd2efb3af935d4ab951938e5960060b6ddaf80e46cf38980a3aa0ddabaaf2f1bd8b45129135418aef00fbe90c4244a75852431ae43d77a809dd92ab72c58da7b1abd5c62bc4e1199fecd351652e2ee47c71cd961d9fabf5d901cc484b309d1db8be08577c418ed4dfab334cc6b080e0910a13c7524d811d8f1cbdbe87d79fd6fa6515b1501bde57285cace81095da64c7696ee15b2b21857aeacf456dc154cd044d4dabd3e6b564fbece8c55bbbbcd1d6ba16d8b3381f661ad17e9910818ec48473b2e73b39bfb6719f905218dcb9f7968e8997c5e54bbf59831d652390d195263dff937f0a294a9f96545413d8b75916152ca996380a9301ec97c8c3608843ed12baf555df4bfe4d01"}, - {"000000000000000000000000000000000000000000000000000000000000001c", "008c21b118c4cbb1d0528338165cdfd9d3bab17cdf14bf14b8414d93710508426ec1b6e645c7cf32de5303342ee0e2cfb227ca6e68f37c5fc79a80c11e1d5c15e323053a703995a5e01257d1e948491a9af052c6038a7e7c07877b2704e7b0774e434f8a6d6e3ec012428f97e3e6b393cbbf20664681b687029833362d1804c9ab42fa0b37ffd133707f7a9939cf30a81feff31b3ea35b8a13a261d55857296af59931d812b23639033702142a9e58b9bb5e277dfcc893330a351e59dc199a9e9501189039e51b6a1e5c5d624aa2d7df1cc819832e7cc3a091ab51b744af75e6c202ebdd9ca5b871d985e6716006856fb23737f87e88ab222bbaf346052082bfc754622f101595f172b70d4f2a30dc5e0f057e07875899bcef4c1782c4dfab59d9083e7163b50ec4c9f9a692ab47d18bc314524270616c3d76cf2610ba9ff837dae6933c034153946c521bd275ff01650243df22e552a53bbed742f1585d1c08dc2e6b89df213762e62e194a3533315256c1dfa0ea9cab9b20f7196abe015b9f28ff7deefbf1d9ed40b760d51b0864431bdd889ea828bbac3128758c53af2ece1e1ea12f167e66634edbbfd9b80e41c78e3a94bf39051d859329c6ba3c4551eb8fa26a8afee2fc43cf80b75eaab02169224209093838cc17a26b177f29c59be0540b267e9a7ec662e25193d9cf991a1c6912eae4009e3efe03986d281cc63e9930d384f12cf608c2e5071e84021aef875f0892cf66b0d6b838bdda0ca6225fb712562f7d99af2e6e3145eb98b42f04753e999244919109371c967632a1b281789bba917a6b705efaa0d80cb50b1e39a8440f7cc590f842e9be411b86553d7786641e7829bd3ea1ba89f1223359547b469254e47436de273365e33f93933fb14f92f9f0b0870515ae6cefac57512693169b0b9ce72778caf5da5b17a2abde709f01d2b8654482e62c958a436c80fb5174f783887eab2572e2e96bd922475d391286141e7be5bf1bb33fb81119ed1a922d184bcb89f381c1f4f9c9bba4b2f5822e2f6d7e78ce5141e9b839ea4267695297d0ba6e6010a405e7db0c13b2cf03f3dbaa5b4f4aad143fc5813b2e376d899e1b63192ceaaf75d8b3cb1168bec95f135696c322e62a07c9e2b139be13d24f0ac49cc4b24ee21c3e70ae2039b36396335eea1e6a03125fa0540337410c1b492700d5fd053810fdda71c88ede9d1207af7e47451f2854fefb1092462bc750b99a73e79e1b1c756af3157175e15ef4f15a7b177d60bc9a24248a835d3d7526dced758549cb02d25602e8965ef1a70979a31e8589353b37f873a9a5266259c10f6f7daf1f64e1318f4bab128914b1fa553890f5cfaaf173d00d16adf00dcb0347458952b74636f9c17fe2754d6430dbbb32bd53000d067f257a594c06d2c717967d7e02db4451821e060b29204285b5272a8744b07a891e3aef04d1974f1995f6c2ba4b4fd994f69ca29e67f1062a7def51c70edcbcf53615e974ba3645559b6ca03a21ff158753df395384d598c74a4c9a89309af5b506c8b5a0db8229caf3d624957ba67bade9241765b315edbb6fe457ed33529521e4b1c1e31dc2491e05dd170c7d7d565178e7e39c51d7f14b0dfc79dd940d9e1a2724ceb6d7947f094972fc412cac5615e5d3b35206af049bd115fca9916e15c210af78fa609494e3f80dcd2ffe4a5514e5d18250fdb0d43cc77d671e0a9315f2b3ec5c943a2abb61635978d5f026eed7ddfee44c92acc4d660e589510f989538ea96fec2d2b970800d46c7651a4ad0d6b4e562c4eed566226d971ca70627e047f82b935f831382d3d97440974a66f4df52f51bf47dd53e25f0b53d524265827766d19a5e9a9eb91eeb039fb988e23a7ead242055d7dcb1706eeed6bc"}, - {"0000000000000000000000000000000000000000000000000000000000000005", "0008b49b3508f49d7672d280c575bda9c1f7ba3e9510af18dbf7477d17919b92a06f9a56d97c7d0da97e20571fe3cd59ecfbfbd8a7d96bc306aa60b1fdf34537fa15a2a91d9f511e89849df9694d36860e1aff54056d229fb91be979f6d5561d7e656a9fcc5abe94e4072f457af864f7554371f281ab5d5382a60f372b840a8c960ca1d508e3ff72568d04ddba55a88436e7372220fe996fd8c880d95fd5d5467ccd65d7d6b8fa62026a08e7f706a59fb37fa759476dae5e80427495720cfa241b130baf37c6587357b05b42cea0075554ea0cb41bca4ece396ab90de1337226aaa112fb7d1d420da1762f110aa4a0b22a51ef336304ee49bc5b32470ac00365d1320fb1a1b081da123fc45107700897a90b31c6e141191e1555c9a494cd77e8d202113a8e900de40cb2591f012974ef65eeed6383c6c9227e64e419f79a27200d5b1ec2f958faa3d6e81a5aecfe5b3c01e1786077f4c483ddec93ac272c5eb1a77298f19943fcfc2c462628d7469faa03a9deb992df493a829203495c5755b65c53be69a3c7d92763559d36da8bbb24d11f850397acefa8f852d67a1a0be92dac1d12550974d2fc315bead1c8a832baf8d6ddced13bbcb6ee0fc52b84c8505f45008d447517ab99e9d79c92e2e70af0f178f360646f2a349837cc6aca331959b8d1b51233639fcd185777b05e81c319e1c8a4d7ae6d147715482e4c5e1a04a77e7994195baec8fd95f3d4e38b205f0fb1175440479ab9863947f2d952345ff9a67a1ee1ae769dd364c99b3c94c5e5bccae759213d88c148cb6c1460a24a0530e916755158214aa2ceb606ca20b817582e4cd578e86c2530cceac1ea8bffb564ca78d097fb4fb23b1fe4e4a9cb6859c5a36d93bea0d624ba1e1bcc506fe58ab3797afb63621ad5c7bd02252548141012cec1d89be8e3283bdb5828ee96ff5cf80076a0b658b64bb5fcd9f2aee7e1382e4f14b86df900ed31c71d616823f9320116157c067c9a548dc047211f893f64195853d7a355d6e86f271dc9e5da54b43488a1d2ae1370c09f4bd55263cfca6d82db1032bb0164f27b20c336b05cdf83afccdeb7cd6fbc7d69700c20bb45b9c947c0c10e633428b67bda522e37bf2316f322fce0913fe6ad0d04d073adf18e24ee9c1dd02520e563738c0aebea04f26b732bec509d4dbabc8d0259dfbf2eabca8b5e97b11e1b0b35e6f4c499ee1d2be45542d856ce39ff454436e53fffd169bd516f5a1f20494a19c7dae8fe81b279c42b14826a3d1984432086a6fcb28b4b99f34d47f59bcc4ece5999f7d2e6029f71f8574d33b93f3613b0ded36795c5263817423771ec802d8fdd4b1c7e23ef63781f8ed3d75e781f0971e7a783caedeae0d2b556a0f321a993abfca7571a375751964e37ef4eecb3f4fa6c81ca3a051927a10343e755f10e6c6acb8db078cb9ffe6d7a8273a878146670cf5530ed33f6c623d305d5debb82959eef970559a70bbfd50ba5313600b847f64ee1887512d7d711c5b1ed916ab06d729aa3d82768a8a4fc577869f919c5faddaa5a059dae02f21330d996fa4fb8fa63ea28d755839113207bbaea85c9cceca9657fd59389f1213ea4c1248a7f5f1b5f52e5c558053a2c657d194f270806ee84d47283ef1d72a0436d6b9d503f4d41b107455c62ca9b3cb2f493540e2ef0a149a3a357474512d48a052c452b48de1fe1ccc4219cb51f30940b0f2296d9595060c07139298239bbe878208e8586bd7935e094a2082ab135ac7cdd83a7f28b37a9061f8c4e0c3be63ab3cb6a0b8956c471c6757879320a1f81cb0e41867a33ccb53477d922170f6b1e19d8b3ffdbb1133b8d0de13996d3d1f3819bc9bed78938a593d3e8228b9b9f7a49947d80e9c4f10c59593a6c543984e3"}, - {"0000000000000000000000000000000000000000000000000000000000000436", "0005f1979ef84397e453e2042a228ad0ddcabae0880f51e27d84d79209d6f3d36d77f284d57e2e1741d4019b6edc05c6ddf4ff1fe3d2883ee09ef0ffb8efc656bf3d4016e2c407ab7d05b89b3d2e6a387a78b2ab0e436efae23741d3f661570e2f6f77e28fb43d1d7113c1ba11b9262e3d997a12e0ca609f4dbfa3f8941e179c3c25a41336538a709860aa5aeee38a36fc9aaa4443168d5ed1b0bfc06da4f55e72ee632a7e3af7590617511c220cd648ade47201b53c687a1fa551031735a086fc0375a3cbdf2fd3f5c8eb6bb2cb1ade55ca072773c2e3aa78b96aa8f1bea011f70953ba1a9ce70aa69404863810d3dd86c12157ab83cd384a508ee00953f476971b98abe0ff2643ca4395a9c7f9f2d14c0f76167ee49397654986e754ef7b365e4b861c20290cd7f38f6b55430acfd8712709fd221f12da1a8df1130b9e7d0c55f37f6cc2b13abf7585e7b43ddfe93c0219c7715fdc3ebf5e97464c80cf789e1311daebae15932e24e9d6eaa7926e960ea1d6aed705d35c6c011a45f46a0390db750682b4106aadf811b3ce38b9f15d3172fec11b6ee12bc48ab8166f355b0c53197cd60c49d0742fe48f7be106238f017507fde1bcd944770f956d7cf7d5deab4896551216c12cdb51823f8fc2195fb17b51a33f151d4fe39bb7e358e67f363b1b162391e1a9438a016d2ecb33b2c5bce5a5b6659e31b508444e4b87077ebd4d0f11f8b2fe3d2dde28b02a5a27139c50654a5b67e1528350a0b9ec797d279a4ecb0f890c05c8a253a7f9cf8441f2ef5b39548b12745e3914240c28e677b5d894b8880968bbff9f69bdac700bcc4cde1204d7c6ccef422215f2a8f231099e936d242d1e9b21d05d43e72d0649c6d7b8aa0a7877703221daea4d02a0568b461942ee43da05711505be9de7285a32166ffd7bfbfd5177b0c3e0205a0974be58c7001d4a8015d04697df6356c317593422228ff1c5e40b1e67a2506b6fb5a9fb5109fa3eb9dcc3ba9c0ea30f8969c597ee7b6d8d5dc8b999df286f81175fab9f1476c7d20e0ce2e38205315560b2e39066169b57b30f92046829e0aba3bb05f1ab300e8bb892acb6fbbb24bdccc80fcc111d02759b305a6886fb233cdefb2228c04c2e97550dcd2e3172c7a7eaddf1c0435661f442904f7cb5997133ef6dea7f1f78ddff55debb8857050c8d740a5b28877290f35100cd096143292c9bea39c86bc2f5fba8f9f6d8846892402ea1649bd70b8b0f51fd5a1e07d0cf6f3eb5994f6464de8892159be31bb37254214a393b7693f5a0c65f34c6ad11f63f651117e3d0bf0f711c7e36747be6d64ed1496559082a6c050442d4ab901772ceb7e24cc2a4a6395e923b30163ececa2c959308e695d4260defabb9998f36d4431ccd8d1ea70bdcf1db9b23a0ceefc103c8a01e5d470219513cdb30b7fda48e02611be3f755877def8bfe0b3cb57b1e338395ca6620b3fbdfe3c5049b2f381f0bc8a21c2fc85de44c0bb198c01acbfd8dfa3dd63e1c9a0194984d28535232f693737e4df704045d53490eb4613af7a8d55d5284e36cef492b6a50cd7bb3b61a021cd72fccf6f331dd7319b63a8125b9fe16c68311e65fc2e48d78b08f26f69d8c5a6612a092963c263b990a3d28743b6bdb0e4b6e2d5f8297a5f2bea59e096d93023f4c322af2de73287a4f28dea6def5626c122a99ea8a53183d763d51c926ca8b74b1bb388c921ec31f62b19900878e81baaca5e3f9c3815dbfdb5a2ab18649da1b5a891d277398165d51df5cd6dcdc820ef847d5e1e0df5f8509d249505b67e0bc37f3e3a7345ece854c926fa59eb7c5493ce9146ba25ddf201811480a96ad94c28d1a69b5799577c3b16a531b73e718af3969b06dabd7c93e82f62f280741cddf7df1b5"}, - {"0000000000000000000000000000000000000000000000000000000000000012", "0079da69eca3a8e3a644948e61303a5762b03d127c373ed4630ccef73ce9d338a3effafd963538f5d91100ab56511165c673f558b1aad60e0b60872ef6435b0eb88a7073b702cdbb7e86cc85ec9172aa967b28fd00d59f7f52c86e8672a07135760e4df5284250b1841c1dfbabb61bd95b3d2192e35a57eba12bf5316e3507e362e1a52ac47b67e3b55ad5d120f630b6b59df912bc9e28cf8f6ad2ee6367e77944deea50669d642501d58ce5c487e7297a8970880514dd1028e013643c0631e10eea62ad33f892f5546dc10d8584fa59f8a6093eccc122c5e777138744695162b159fce473ff4c139d4e584f251005721e34d068e900f1a9e40fa92312206ddd34c9db14fd5967eb00d82367c56c1ee1063712c343edd99c89e830e67419bc4499aec64fc18119738d5abcad02a599ce51e6d6bf3d05938cb39be96edd0f937c39606ddbd2aa32c2dbacaf5f46feb51203f1b9b66b444383902040547094d9ed53503bb7e919b9e7521e20fa71d188b46b3047984327b6fdd7fb19598968c18677e5541bb1f3e24fcd0d4638f00ad24311231fe867922dbea084d34a4101b6e750f9127a0bf2352386cc665af9302111c55e147d6bafbc49ee3958b48d0b6dd28bba9407f85f531a5e0bf1bd05bc0dbe80b703a413639cd142a69d321b55b5d1919fbd138cef7a728acc7776915a043b55940e97939b0f840852ecf52944f792ba84d0b276873e8f11e21a4618389326350c3e3183f795b723b7d7e8ce97637e1413147c70b47888874a6649233f7cd5b361c1151867023bca7a7e87570c3bfa234539e3b7a5d650d01a4bae08f49ecdd89ce7a5a243255c6bad1a06181f5811322007357171e8cc15d8b072326ec644c6d1531cd69f0fd36e723e5e45bd240431dd05c8b384a74678e9141f4e4bd957a64c59d7cb352bf974f601f62a7b32bf007ff4bc85d8f59bd2a1610e7cbcce3162d63d36c845b3a6f0f6658cf1f5b816d466bedda1b8d056a015093a4777fb5ea0ab03cad632d1698bc65d96fd397014c48d909511fc7bf5d8a70c857b320b4f9fda86bf03accdb104147b515c1b525086abb2f19e1394669d4de72cf8be5f52ff1873551d82d0007235233c3375084fb88a53e8b607b4e56149f3903828f540b006f01fc95205118c3ca396b58507856bf6a18ec8ae7d6f00a948773751e539d19a5438f5c342025df7dbbc9212c67b182be6009ba211353b7550d15b74659c768b118a15b4d7d1da67f21872d50471b54d558cf9f3142249c79e38288db3df25b9ed42fa5acf85945da4eb0147f00a588d1c6aa717013974d51aa05bc868df3605673188034c075edc9ae426f6c38679cc24bd5e6301fedc52c5d33f238463b74fd7c1054a322c72f11302e0f0de8d7520afe484c65d40f8ab4a84d677fa5200c01ba44e8117bdf30ce4aff2336f4a199e5f6cf3306ea73233aa6a0198c5a75c766e8d76d04439c7300d2b49014f193e32e1ae6753a0e7895a253ed88ce7135f3d403894ec399e4101716be9de54a12a55d29a01dffea96101b38b7de783c0f0654f3e539afb14603fdd0d6f2a8ff9a5f220e4fa2965c4ea8a1d1f49640b239e614cb0f055cac81176bcb3adb55b2bcdbd68244ae50af0aa7f5b79429344a928cf71641c6d62e40825ac33401c8749adf850e5a5b6b17c3b2762281e218f951980d1c883e40e4712c4e5b0ba98727c655d1aed46d693087587f754dcb0c478e79b40d4dfeb1420f9f4242b960c79b707650cc6ec74ba62ea5b0e8f160a5798fbea18d7c7ca04fb8bbe78271dac5997fc320fc6335f65874ff35b9331a2def7f99744af87d343001b1d5b54e8ab538458966cc96bbb1329ff869c51dcce9781de4cb144768523c1ce94bd8203502510"}, - {"0000000000000000000000000000000000000000000000000000000000000016", "000011581d5e0a197314b23ed76975590c56d1bd6a074a30eaead093bbbfb9c552e8c7706ae11b797f1704b88b1c108e18209293b13939d46999c98cbb75a70fb43afab64af32dba76b1f1e4a2f1fd8ebc939d8204c177541aa7effbf023130758fcffcd42ec6cb00410146cfc0bd5f7b177f5874efe55285348ee7f2106381a0e566054c193510cc4219622c1913a94194abb496e2da8b694155b2b78a6719fd70581d75f73534c02d10985c6aad453b66fc2ec322e47e703fc5f1179294ba3c7b3adc1b584db32b02771e2390c9d9ebc320ea376e49c125fea9d90515959db898702c7fc463b1c8a8b44125dc867add343e7465068ad6ef82ba547078b216fbb084a6ed545a1f5cd905394b3d75f396535f1c5673530aba1db8f65fc41b4c225ef9ed77cc215f20d5dffdb429515a9d3ffdf2f2b79a8531229702e1b540d128e1861b210c42c7e58651e8ac77d4a47023fd932ff49efd67b0305318f3e526ab02a1fb5c145fce61914272983910a455b74d1fb65974e1f32860fe4b122e252a4a3674266e3ffc336c75d0e1dd3ec2c0e7e3607508b95a48e05c616d55e69f69d7a81120b20afa4994658a633e8c26da021fbb4efc2d96afb176c354fef0ea6774ff113d0c8676f55471259aa960fc26dcaaae0876b88cd342988bf49651e85bed78b171c1595ce50573fb4939c65867c5b2333a81a915b027c6aae1eaa136bcb0b93139930ea0e77019a3e56134a40e7f50a8b30e1cda8bf2ff79d6e345451fe990f02ca185296f537980064f4cdc4afb7109399466e16c795ca8c4c6743c9c2b4a644e4f025c8b21ffbae1869621af4508e1aea73023adb3abbc0aed99250f034ae3ec6d12ad617c6f678f9e2dd98d7a45dbd646718eefc8969d90dd5228b58bad9d778a2ac9c7a9f4520987e46c5a2fe5375e0f32f3d2810137223df73dd0295811c8748cc67a1a97295ef67b07d88a591754809d66f10db8afcbc79aac0eafcaa98bc5fbcdd0d7c03075f7c90367fb1db88f9d95de0f9431fe67cde1a1a5f78ea02c8a6d769e84550be4a3945c068bc4deb065790edf794fca38d88f2bc66176d2e2415baf7fe2568db4460755e17e801933e137c433726a8de632d0f07aee36f94085ad5aa53c8372cbff1fde279359e3267e5069c5c2eb53234a3b2e82992e15a452e2c7e0757f28d5b1d27535e3cf254b736a2809d4a3099060983d54a890f67969c69734aa0d637b2b44e16645815686e530686e886fea4217291a9643e31cb7c289d5d572e9fa5ae5bf7aaa2ca61a35ef6b6e9015861df09b9f96b20603c6907d145351852bd9de502577b1d24b8d2d16fd41631af65b77e1f75d14e8a823d160e23881543c46b8543868c126c22eee1da6eb9d67acc2c16352ba4ddbda3039699df9dee1b96b69afbd6b50305461ccfd7c0ebc7ffe35e169afd9f50ee1b4832122bc77456a738b3518db269d430c4da2be29d2f660d0b9202805c4c7ee53024580ff79c1d1daf0ac562145813f1a60b76d983a4e2ce6a7fa962a0e4ffa2e40385387365c52d9058028058d4411964a361f4808e0bb8c94ac3613a457a5bc0ebe32f9d20e9fbd9507313be852e989099589ccbd3956cc7909a6bd6dabec928451333d992a795efc6d8e25c59621e94b4d8af460319dd37d42b267598d620a379965076c3d35ac62433773ca08cdef207be59c7c688ce1bcacc1a18558810fa215b04509eb5dac761db8a4c3ad10beba9e39011795309ac0fc3dd417e447279e889e9eb8f5ed4400384b98b09e7c7699489747933a78de5351ffd71531422b35d92db078ff44fa7108353cbcdfa539d62b703faa4d8cc87a323164954067724ef9732bc3fa583175f9b5ab0b50119af9bd7a61847bafb03989f5529"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "0051032be70cfed8bea63361ba582eff3d513f9bea66145bb17f376b15d525d86b757f04331f00bd701801e1687d2f47989b9194e04a5c571f144591e5dbe109bc4b31dbd859aad2cc59aa80ef26b3016f3e41b700ac7b49ccc485bb86d5127934e8d6e0d58b98db6e12b90b1a91e486d1c2488b740fe448ef3a3cfaa1230621a2102b4d8065cb3a128275e6c7f54b67bd600576aa2ccf7bf2f1a7b028c9fa82e7cb570ff538b019008df5759ca0d985c9a425a9315e455760e91eb9c5207ca6f5d0aa87f1dece4377e2d03948e522f9a45901aeacb71fe1f22334cc0455507270921f8cd543aa06dacae06b66210fa767b56942faf637c1083f372b0e78cb2c6ea335838c86736038a5d9d703e87b1ca61979e6d09f8ca948fa15731b879d94c5ebcb99d8df1420f92d075c36419edd530905b486550b65b572ac1a514b2568e1fa59a6b80234452cb2aa8aebdeb44e025a990e88d3dcc2a8e3603831bcd6887997709a0f3e5ced3eb7562b64fa78853c3ff8266e54a83fb4aa10509ab0a430d9a1dbe7f86aacecc39ea45d1fb4e1175026886063446dbf34352e8842343bbc83fdf4230614c1dcba86150ec9c698b0cc6af8c2ce47dc4d371aebad5bf91018b3429073c1d24727de1388b0e3ff14d36e5a741018cf9ebf015078ead152c76bf8439b4ab26607e9a5809f4c16450ae543b695a93f9af85c02efaadc59066421c682a290fd3665526acdbb0f1008a361c3d7a7fba5f94a43cde2bb5565fccaf166b91bd602ea4bda0bc8f09838334aecd38a53f7f4511a479747e30253522f59c917198a62a3feebd61f6b93050be733b20fc7bd26f2c2dab03b14d14b93907aae65184e999f99c9add99e5a4b41fe2072bed95663be2cac3f761f9a891be509aaa27f7ce36b0d81bce14243f7e5b0945ec9313160e55fcde6851f8cd49d86fb03d7de5e49949b51fc81b0719672437c39fbb2720a526fff75d2352b63d715b52bab3d7171a07b1ccd9f08dd60d33f4da5f8da6f119acb21ec8a4335bae3ae30ef9785384dc2f3024308434145475a47e7f7a3f5056e3178ceb51d33c974a439e8eb4a4b2666fcc5bb217ab511c0893d6eee0cc58e1e40ca01f49ffa726c057c71a1d0056b7a3ea380723e9c93184d7f1d1dd61f3b9de786967ce9e544a44a8ad996255b28eb99fe062f286564dd6523de0280efe38d1460f1391c1b844b49adc723263d95660c35f381613b4a051d9349f216653f29738fc1fdd1e5e3e18fa2e26e2292d908bc3caf7db2b8a348171d62e69395393c3a9263ff02de0b0ec8b619ca0bcb29c9f0f160ceb811b0288d87760da70111584b9a2e70ec73385f45a8ea1f6778a8661a6434594929240bc7cda88f1362d4de48745e325c338c1ac3bfb0a4d9dbe6b95e77e7068aca119872f803de8426fa0e5a01ccf8a1d5f6634fe9ab154e0df709f1d34d05d9f4571bb481203a34ef6db2c193fa862a05fca3afb1cfa9beda34be6abc44e32ab5db1ce133f7cf1e507134f3cc40267b7bd7d3f27529be597306a1f5772cc312e55ebd01c38810dc7c738c916e8d0b40fe6501dd8175e2cbd2709242cc80a7b934614e0e7d8c51e589ebccdf4e431b2ba57960d1206c9a311b6a4e29f71ffa133a7ee2ee2aab3da92b7d56a7c30843ae75ed5b3653bda1715b7cf648b227b1b59747320883b9e0a4f68f9b4937da73f1972ee0d7d8ac3b0cbbdcde1c45500fdee380fc9d45a042747c1988a42e8cf7646499c181af3da3a3b6ec1151912cf6cf550fab20c0fb266c09490a5506f2f80491c7c1ef63a43257e9aef0de7555ab4955f3b43046edef39dd756819a99c21df922433b11c8282de4629954f096bf4a120e3cb42556dbbc3d99ce478e95cd64ee92cf8f439"}, - {"0000000000000000000000000000000000000000000000000000000000000002", "007f06c9fd40e6ea745d12f8504d4269f7ce39aff91a88de03be12f0055c4584d3ccc8c74f0bb319f4f201adffdcb113acdf198910f360dba5c9213d37c4c119ee79a22e677737e4dfc1b5b7f3367e4c3d73502614ae659fb8c8b79ba756d839a0e847965a6d14f6362bbf64be651b29e9b71f95bfbed0f8aeb95e7f861a2e4bbbb394d9618521d9c5193b46e7ee7d0776428848253bedec148c5caec43a8924dba3ef4930db5e1f0295c46cf30b08cf999d8045654d7d8eee2818c74d0f1804338d841457fa45d1915a770005c0647b6dd316720d539cdfd771276b835d1fb9bd5329e99bb7bf4ba905ab0d6036418688e7627ace3c8b79ed5ceb611154ea1a1e890c4d3111b5b5efbd2dcd7c554fdb39405fa7c8a5d55115ce377597aade97fb564d3fe36941b18e893850c65120e1b5511cc5389dc804959206499407dcc5a46da54d82b5b268e1b33655227692cb00ef1defb633ed2fb564953a4dfeda2dd4d22eb706512c92ef851ae043eed65610c23734de828b3807f0127a04fd927d6247ef17e6cc6165edcdbb0495f1eb1e0c15b16fe86de38627a4e9dd61a811e628bb5c9b01d3cbfbe15cf90de2543171cc8e6210d2642de184137f6495d94af0796eb7485f8dc9bcb37c547d5ded0c108177d60fb06597535728565fb5ba1f6d390edd0cdaf8d231902b01427363f698d6f85a5c319857ab0c0a6d4c0a990745e52ff40b0073d6d110aaa899a30fcd4c9ecae6a6238bdca1ac11e62a50e824b5b1a32e1092fc78380103d3f4147397a4864b2657dc60b430b57458da0d7376f99cf4f5c17e686a3520f24f460d9f32a8ece4b471be1651f4ba6b2b7cb7132f3833136a16ced924e6f3e7114594c0bf3ce170539f3225175dc8e6f450856edb57f2d1ae48917e3477fc52911777069ad2e2981f9843a2ec32a05e965c797d521e02100f223a12413da5e0320fd81401808f64cb039616e2e3ed8964adf9aef2d353b76d60f1760c96df5f17479534f330cb83b74d42651b9dc54d000bb8aabe1c7b47ddcd8a80afb29737900f7aedf3990e5dfd700385683e1d8193028b8a914c6df325b2b892b74cdb107a22d01ecee813d8a4331328d29746582538618e146d51d7ffd54739cae6f351c1b75b0e748c174b203aa507eda31e720595b0f4fb27e6b697414f3f06ce061804429a99747b3e99268d51d9dc1e27897e482b21228c9fd8e72ee7f97ec73a2b7258daf31e3fefe8140b7cda1f1012df022071526e2f6c30cd06bc700e2e902bbf1e5274a72a1e738c0964acd0fd1f9aeb8507c0410f794d792d551721632bb8d38e4afc137f1d0b8bf24922dc2abba459e3cfb11ee2b5c2e50e51181621438ce2ddb619eed8c312bda500e19fa54d0999189192dea44fe48fe6121927b773f3368e5b7589f4025c4f46f8e7c015bb517505cae93305f4edf6b9ff1f298a6f7464efb94603d31ff7ea6ee6a87cfff9a40e0eaf2bf58e72d77b9f61c937e00d9109737e2b7b218cae3511576ccf8aab027d652c983d080f388795085c577dcae058c9df2060dc274b3985cab75bcd692976f4d0f0300fe7ce12ea3d2a56d1cb0887dd0d602a334f48d35849a78a12246088c02ed55749ba99a240800af023f0edb5d86a8b08f86bd7cec7521878f107ad338c0ee0025ba260111cfbcea6454b497e54f41de5d3e7992338c7ae181523d2367ee700f7fed6411e23afc40ba59f63365f628c0a712dd8dfced01c8f2ec3eb4ae795c94fcff784e8ddf439c235f07f2fc00ac866c2525ab165902957bcc56d6dce1fce950ee0380f6c86ab12e13d4dd105ef423406ea742878dbd61d46466fd8918949015343a4a71d27c179be6c706c2716c46bfe2dd6eb99a3a423c53eedf537e793c542"}, - {"0000000000000000000000000000000000000000000000000000000000000012", "001210e9cfca13c38157c0211b3ef81db65038d98016c8e3a83061c5f7cc9d7537c02eebe675bc79e4c22a0534d4a09018b79d2c63c4304b5dc7300edb7dd343c31f835ca83753ed5506a4674de55aca437aee7b01895a28c1556eb5ee94169a4f504e120cf736eb6b299e3f7f710bb31d8809f3d7b5d15e1b0119f9a6c323417ffc2d4de2fd3e9412a886f0015ab7a3fd9a7a34cc5b4886aec3a1bb6306a76cbaea4dd748729240010df3609556b26f38e75435926ba19f47969d59e72183b51801c98ecda2b803ed012af582544899fd72036503b4304dbc45092c70c5710b74df552c5d0edc40684b3be2a5daa5d1ade641efbb4a322275f1324a0bc5d4982e4ea951677365e511596a1da09fbaa4d735a76caa5ecddba19ceb04962efe9362e702f797b90bcb24fc510a8e1bd3461507e566497e1d18d6a4e9337547527f9183fbcadcd85dcec7873b50bddf14ef05d678f76051b2c37c04f095c5eb4a9036a559d620368b9a2e8415e62f479e84f54dd091e1b1399b165d1812458f5a87f003816782a551515f3cec46c8e1b139ffadf944619b3955d703e6f6b872771d7a18fa4108946b166411485aacab520b7550fc91537f92114d18ea7c18b419f4074d184687cffab87b58b91dd5110bb52540e990abe1ea2294e777d299515d911025981f64c56108abe5c1e00e32940a9c64c0f35a39f9a507e7ce16c684c4fdd344f1e13919da556596d5f9352d9445beefd70cb1b87624cc37ae359d424fef570f29554353bdb83781db17e5872ae02e5aa51ade84c1340ae3c983e311b36406170226488bf2c284ba0e6923abcb1ab9e40bf72446341d2925b5bd5717dc4c9e43645a7a789f301d25c2956c03d6a5baebc73966c53d8dcf891233d3b9efeab4674fcf106eb3bc586ba66bf2e36ed3a935354db6ca478762610ecbb797ad62022f78a172059f6b2defd1abd1b4d0c2a6229e635c023afac4c49b497b822a913ae7be04a48d3d0885e61bc8f7d7a18b071be5af9258b71a37f1a1bcce82d34195ccf15d75de63b09d073e944ec8d21b205ec90617b72197041098af0a36b49cbedfd631a03bf70dc329c9174e0d397b29d6a8268b3c5029469ed77e9d4e2205da3ff856ab2af11ee83a9d738bf6421dbc63fe691f4edeedee3bf1fe79881bc2e5fb3eda3b1cfee8065fa4fb3b6d5565ccb6b0a592ffed920ef93973a606bf2f77b8462d01379020eb8a41c0654fda1b6ab00b46d5ed54a539fb597f92eb916fffbbbf6dfe84a223275fa1fa8a8f4ca4b7d5865156c5ab68bc9fa6b00c2d1c38dc962ce4c7e062d0167836111f1449e20715344526f1d70d86ddc13772cbe4d49f34ce3d32c630154487ac65c4ebe5cb1307fd63dfd548b0971fa34f824b4065fb95e9ebf5a91efaf02a0a827bfb19b104ed76c5e107a66d42c5547ae57623e93b6ec9e47911c36e4361d8de1396a8d4aaae6e602aaf773c85470af8d43d055f0adb9e88d1a7b37e1710fd4974eca078bf9d55109ff579f77b779d453de56332fbba360f06959e4ac2e6e8abcbb81b4f12fd710b08065e1fa70d2d18f97593930ca188c16bc7f63406593a13d1a6368a44d19f9bed8ba0ecf62fa2ce6026a2475fd5413e79a798fed7a40743d59410527b062e0f83718d920aa938c2d6ca3115a6fa52de57a66825c9bd8e5dc4194b48e2f50b1069da4493ca4a3f18af5f271e82931cbb38f730113580963d06c8924552e27862d71ec432f89b17bcedf39f99f58397ae78328a7cb43893140b30c218708a21379881d400dda67181e2599bd3b8197dc7826409a93e9cf116ee5fc3609e43ce98d1b20f0ebbc10b8c7f39c58513f08dbb206b2d145a45771232a1ec86973170d16031bd0cdf9464dab3923142"}, - {"0000000000000000000000000000000000000000000000000000000000000358", "01c238139398c8a6f3e0c793c34f437a675e186ca22d0b03c6b720100fd5a2355d44b2260ec3313704a40df0b1f5f5f90c61d0c043a6027b8f664878fce82b176226af6c980ba714f5d20663492d423e7b520c99096a2def500adf1ea1321177ffff16d1acec0e63761d314d7cbb5bf934f9a011fbd9336b5d64f87269880dfa196930e419c793f4e14d641ce5e47aa3b3363c7474453d5ba292c97e12bd01446bd96bb3f5df16ac04b5a97057d346dbba00364db2bb82a6cc365d962309b53d530f0e40c1a86da26883e710eda6565aea382cfbdf84634ed9e70e38291dfd6acc2b2fb71a31054340fbdedfa2c971b74e947eb94f6e393a863556c90b3dd7024126c41140e0344bed35e2f2c49a1fc259177cebfd7966ae439deec608a037a1b5c94612946b19bcfab6f78b42451d02b63727417105e528faf6861a57434346391863f6c55242df7711f2cac2b7575b03742f93d3df08ab809311675956dbb9cedbb2fe2d069e22afcc492edb9042b14fd897a26c5c28322dc116ca454722d11279f44437c9d9585dca7a677725b32510ce39e353e88bb8f698dca46958e36ccb5c6063067fa69e0c08a04c474bf721bf690a92bd681d3ecf0dbcb1cd2d4803d4fb12d0def66f392b634d7c4498159fa7cea611c7e33871449d53e1fecb001db91e5c2fca345d7423287b928936c40058370e5073ddc2f00ee4066507f9aabdf17ab84941e369e223db91ffe36204aba7095c50f70269ca6b377384f3d3321e9d862d5839b29fa693a5d01cd2f949d7b900e7ed539e253c9d86af82f2b145f86c8550192c61f197badd3d7f0f9104288a59d7a1bdfb42bf9958579723aaf9d5ff1c2fcea21089841eb14bd52cece703c22aee7d74f60fd47dba0e9182772ebff2a39b4bc00ddeae9c0ca745ab7e8accdc32736d71859df15dec1365eb3d120603ae8e94e548b6eb9edf54496bbf5b8962e9f0497942b29fffc15afc10fe242bc5d2fd19a30d911efef606f51c31901d7b3fa3d5945630ae64c292c19676b2111a4b2280462b5d6444d299a99f105a08fb35fd900dce03cf07888b40bfcc12c31e7a9a3d24c7b9590b3408a9df714e6d63ff40235fe79ee77571f09ccd5d16557be7530a23967ae0b1e1815b0bb95c433fa9ba3368a65081e6780b6dffe95f00efa76efc4efad79e04179a11a8685097867f50794e4de82ae0d1b86cbd10e68d92e77739bdc4cb2345eb462d20dbef8d23cf26f92ac64bd1d728e3ec43cf7bdba962e4b2178062298b8fab4cd9c0c7835d774f5e59c6fb19f85f2f040a71466ff8acc403be6680ba1038cd1fe0011fbf2720c07faf4aaf06ffdf84a600003a79b668649af5a34736dd6d03592ba9aafb84bfccb51ea1cdef7a33cd550a3766c19877b140a7a66e484fb9ee72b0ddc59f055298e1adb2bfb9ed5ad2fa021a8a462e82b4bdf036b1f4211e77bb3fce70055ca3cbfb4e082e14844d4beec4b8739b66b5f4da991ae3ce754e9b4057fdcb67ab853736a4fa77b374a6ceb1504efec92236cd490b5234a3b51d813cf37f35316139a92e49961a71b63dab1a1454ddcde1f614357006e9e1cd87333c2f8c16861940c6ac36836c4ae445a3c280c60d4872d70e17bd3a9f9d996227c8bfa47c3edd136ad8475947e005bc9476f45b6ce5fb2a00bf2897c09ea9b05fcb8b12c62ab0a295e1b9b3d4a604cf42e3d58769dd7861120355bb09de7b713ab1d5fa52e0bdb77f223d96df62dc3533f0a1c5c5ae5319451ade29beb46fdce3cc0b0269690cebf00172bcc78fe8eb9856cca516c453348ebcbfce1eab279e61d54dc0ebb6968f8bfaafdd1033ec1483df6dd972a8e4c706af455144939f28072b000a400e56c1bd08fa46573ff5924dcac674d071"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "006e1e15bcb15dbdc47c815d44b3bd471a90de82fc4547977b349d9537622316515c6f3b85cfe5b66ff2018178a7b3264a3959da30a953a576207a2b9392585e406edd179acc035dbd865673b74f0a0ab1b1cf5b0357854e3056ce98d48a2127a89167985b0ab3b35d461d1ae6aa276b7bb8327675f17e13d1e863b7de3c072d2ee2cf9fbb596346056359dc4c1bc74f7eb5b53fe552ec7b1001db40b7e4e27da967ce6e74db51fe06d369e5920fe77f0741c57c84f1a556b2f1da6b1e2e5ad2cacff0f059c9771591247294664c1679e90407302990e03828c7de0cf3fc89eb3cc562f4b8cfe82d8263cafdd2ba27d6f9539dfb24d9be0e543598ed0af92c6acf9a61fdc2770616003fba6b3a645d45c944dbb6c0f0612c352fee653857fd5955e67b9d4dee1055379a8e74a643f965c81278cef68e6cb19cde9b15f3369c621733e7c7f8a62951d2ecb2bd8bfa200601111f20c2cc6d5896345585ad74663d89d87a3bc4099868519a9163b4ff08b405106805337b15fc7d4e06d57f0d32cb356ffbade3d2b6b527ff6b5d3d3006392884a7f8e7b1fd6294e713ae5f3f4ab51178543506fbb74e8ca76f678f693236bd56d98a17d7ba243609e0cd82564410a2710a82d1ce4e26714270cb87c3164c4c3164699fd777a2561bda754026873c9f12144011163401ab130f63aa1465e6580c56915b9b66030191a8d78858cb152aabf091a3cadb8e41a6d43b1205ca93825010d28a9da91223564af03a8a0ed5a0ee1c428ea66bd80302e82b55b5cbb157e98c97178f5c34c8268c85d046536f6f25e68fe0d1ad9fbb78e2ce118645179113e392dc8b12bd1f181009fabf78ba471d47d15f97dd667b3d70f3cf2150f0a118e93d7425133ae222aaa0cf352219336cd460d3a4e23f98e81d1604e6c3178f4297638842acb9dfc2299b878fac3c00c307b488cb117ff24f542459ec7781948efcac4b0f083be43084f80a5855984f976a362a1babf2d7fd383f0fcdd266d247cc5917b5a565d8ba1e5a3e3afa5e236b95af5cb63f949617ce237b45ea1479fc92d2074281e58e997748fc3081166a39bba8cbcb469c57238bb4852e933c60fdd492ce9bcd525ad2a757fe9c0d45427dcb195174db8a22d41a3475c0e6770fed5f66b4541be1dd5c45cecae74f18dc54a21faa9f0a8f121a6f71ffa0a5d942ab84e1c17c89a62378d2f7002c3084ef160f1e238179840bccefee9d367e914fa81df1cfacf64ad03d946cb2b87658778192d5dae75f29a2dcf66465bf1791a9a2f6babb17d98bccbdc002133294bff267e7cf9d4198608359821f111cb9e7a9351eabe789571cf4f37b058e32bbf21db38ffe32b514756160f1d07117f13c41aa57c7af9c9a0dba072f780aade5372f0ec9bde947a68b49dc224ff19fef9b00d2b759bfc8c1dd6af283417844b46cd3043f632108330883d5b15a339aa28443f7e8f33165dcf7a5e315c7128ce530dfa9da66b1682b951e2d9ae2ad2b913de657668a5388e6fd067a80f5f35bfad2cbba27491a380227f52a77f7b78265ef8ffa2d32184251287a1de22e5282dd6967bdd5f29cff64ce15a49b5d31fc29d3dace32da8135fc35e4fe593c54d5f614fa40bc37ee9280961adb9d7032d554e1c431f337fefd1999015db3b0080eebbf6f09c68de3feb91347e4df90c927688c1cf8d411dd9664f6f21a6095160211b0fe7418456e66dff18411b02773013c6de70e9d49ba2b0d50e9b2d4a498ffff530ae64562710e869439d692bf01c55e32bbd1b930cbccc1ef38f2482d1040945a5c02609799808099ba2ae8d0e3deecc8306d1add12bb049342b4b2e720dd80a3a175d6dfbc6a6fde3ccbf6058adcc98aa165933b3d50a478709d787b1aa41a86"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "001fc828b48aaf46eefee2b03a2221f8c36088737e012602db650d10db2bfe6353836642f64a42f9c08a09bfe726abed9845aa3ec160068c5c0c81dc888fe3257fe2a03ab2e949e749640a876b2e491d0930e9100e9b3ee0145e1aef3b70d25358dd20d18cdf3973973430d394336008137ce1654d76e63bc6b916fa746a1cbcd32455f6aadde935a533c2d2586f038bdfc27036275c261ae11cd17036758a3d6ebe0b54201af5da02764b28cc1b68b99fc6c248b9b0d9a1fc6357ac7c19631b8b37db0887c89e92040efb1894dac68a22a203bc97d2e7d963457b70d75ff9592e26bc503b44ce10b3c9936db61c2dc7a7f344d5de32022d6a741bda0f870918254e16b72c3f92f6fadc67599b309aedb635e8d2ad685f87ab2efe58e07d48ad47781d7bda57106166594bd9720cdab5110782eb361e2852f9c51324e4b92c6613dc3776f01412f364871d49582d352f010170275100bce051ebe323ad34feb154826ceea30b8703fe7f12f92938a0b1886598919d03ba3510b7011ea5227b66fd775ed19528cd643d5d53d91cefc0245f775af6160512c8f8843c49c83db65302fb0bb50eb88fe15453a6d4b05e21d6e33630c1ca7134ffd12ed7218b94641385d11fb541f67e04ad6aedd65ec9109515890e4dea69f6cb626d7b6017760dbb1332542355475cf1c9bb07551cbbd7e07ca357792a3fc51a0276847b23567deaf4767822c5533962da3e9889e027ab2ac93bd4e8af2172b368d7685a8aaaf0fefc340cfc09f82159dd53073c6139f5696a20afbd07686a2d9966d61dab6805d920f30492df6df386395e249d15a293c7e808e3d91034b3878e47796d2ee651f2cb1d543bd38593dc2edd4572e2f35bb1e98734f9965a2fd04b0a7896113f5ebfc3e8266abba94993752f5945e2dc2ecda79869d97934e3092a0d966f2e5de2b70049f08975480ce09358744a0a7079d1335d312b1313f0aff0599550bef2a602a37974eb2cffdc3f22b80497245da7dd4155b92cc4889b71bc8af991bf25f4109bdf28c58aec7297fb9324052f60a2049b39410b013b27e3d5c4d96c824b51c2a7c1c97276c0bc2bc622011a266756f986fe5434f75fd8b5bd85b43514800d0d7cf693d46545d29744a8fb70912da24e31928a0ea5b46d34c489ca505aa1d068cc876557acf0182400a95f542b6a0e2fd7cd913640c627f5c0931d3eab47a2bd5f18634e256867267e0adc092f0a45bf2eb506af007adc725a43df3af52039a9388b5ecc5b020a1289f7ec0c225b913d6293f47bdcfba176e476d6cf05486add3dac5a2d681261519c35cfecdd713b11be0ae60a9426e7ea059c93a23ace24da4318951cfe87065755feab3610cbc9f841812ca431aad1a87fbf971171c794bb156bad191a834b4e41476a3845d8b98802258bd0270c3aef1ac0b03fd3cb681dc64db5e14a1d643d94f0e0c00d3b9333797459e60137effa22b609c782917b2a3053865437b79c40b095f932703ce82e75b69ff094f352f0fbd34545a1839f1ca77c58a802fdcc3ffd6963fb68e7b5b524d0d80dbfbff16a070d6ba2abdc10e9095595413f92583141097c0b747d1645a54808c81fa918b9e502eed7e70d6b3dbd5627286d2e7eabcaebf57065b4c9757ec2cdf571bd19ae03255570a6d01f24d772423217a446cde30a8f4f0d04809d746aaf6b05f286e4791c6d780e482894e44e2106b28e51aad553ffc392e8eefe308e116cb700de430abceeb82a12856bea25e6d13fc51a5d81dcaf8308003105fc4ab660cebfd6e0faf749e5f213953b0b2fb9fb6f32d7adbbf97fa398c7bc7922d7843be94c09bec7c96e252147ab0bf7d9174bef339f303d0a22160bf1baf387e36f6e02c64b90d10373370bdf2870"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "006d4fc54a0adf96ce1fc11c64e3de217fdf1ea7391764f4e9113675f7f5921347cdc9bcad7c08f23ac408c51171dd6e8a818c1861e4ddad260132eb1ebf872db71693311b8b2b179b44c9e5fc5abab0657cb8081330b55fc28e08e8e40cc37902d841a0e2d20987b77d9dcd50e2619ef1fd7a48b383d2ba4b5a7fdfc84b147d82b50d452ab2a2101635605561bd91649de60d154b8c9faa6341edf082019eb84a33b5f32c1fd3d5102e18ec78cad22680bb3161cbb64505b4bd355f03232f86292056f15b30c66490e9d65b823eef55ce081100fddc02364eb3fafb8351c96faf6a43903e792f187dd5c43f8db35fc5e6054dfabd8bb70adefd9c2a1305541af1d789eaff7f024d4b790c59908a32669531c8dc865b8c7876ba26349288364282de6adb4de4137e6fe3fe901b47c823c5417a6f8a96b6639b3b4a1b4a1494b6efeb79a7e773364c51832d1b90eb71a000f038439e1146d89b3740937b6a43a2af79fed63b5df0a70982ac7067d425b9c5d2d90f06eebad8e6360b0ccd9cfd1d7401e608d5a63e5fa33b08b2fca4cf3bd8dc9f56691999f43585b7a258309f2b1d7a7aab0fb186b7c0512b2eceeff7137c7c33e70a561f0dc01554de456d0647e5f7e4f5c7c450ace214101241841353fae09bc8a8f6bf6706ffc7cda431ff07b2f5d032a89b7d3f0f757d1ef779546b4e4c47821dbcd16903697889838bf8d9018f41e922286fede2ddd734aa5f7f94468bf0791dfa5656d138ebc75e5fda3bb952048255a288e67d3df49450fab20fd102f8db5a0136068e0f2b74550a72fabe6920b95b6cb30fb21b032f05ff7edf7aa1bed7919f714adce29f64e6cc7c82913d9a8785a7a25389df0ed714233ece561eec76950319ccea3f37e557df5e14854a8936c11738be9cae622e05799af097ef654c5ed72fd2d310daa94157e65a02ef45d1a248d4dbcadff4a9a23c0da166104cde9b462a656101630a714d49f4ebfa64240ad5b9dfc73240656bd34413a6a186e854f55eba59661a5cba6249699df5b4a6a0feb1acca9a3dde70804a9b129fd147098b47d871cd468f7d60d3068ab639a0ca0d54c6344d1363cf9cd3ccdd06aea77dba7e67fdf91bb777c60a940796b5d784a113ce83f74b450572306899353d1dfc037fbf606c438c84b203a2a885e9c8149d1f1705c766aa7757b6ad9d9ec455635ea929d65f507ea816fa89abb1c6809276db631de82c3c59457c5098b821ff4631cb8dc5eed7b1a32173ed1690d9925aaf51655b773db96e972d942efa7830fe8ae2e23d17d764077fedc57d591144fdc22562f8caddbab84a16b4c8126cbce87ccff940dc8c8456035468567a6a1829da14162e02724c578ccf9c66423f73756a8802fac4f13f4e820dc6771863f36324485d60cf5d7902b627a604aab5a8ddea272d97b560e43e8a24c10e339d164d0bb37d9f42903266e0cdbacc1d5d01e71eb65fd41d0eba7b7a065093b2eb7e7462bd6316c550271db1b012e9ef24905f1645f68c519325a8cb1e0e2b99fee909c847209298864aeee2a6d9c23b90e61b6b96732c6ae09b93f45e8d019e7bc749776a3cabd635dfc13d0a0d1d508a9e5725df9a92ce4a2c1f24c5eb685e2b2383c605dbeeef6dd668986fb2601bd6722d5fb9a309ff28ae86a1e969cb0a0457e73ee3b68932b71f730d1979ca6f052244b4100631db70a8ae4f3f75d7220cd3f77d9286fd83147345a9ad64e5ae4b1afe123327dcab55e3e3ef5bdcbcb291ff3c2cb2047af79697135050c2a195d8ed43c2f1c4fc51ec8cc6c390ce8f29b4b7055dd0a203ebae858f01ba71a7aed67f9e8e3b81baec9c5b1e85785968d06272443f6460bf9e5940687b90f05985dd827684fbdad90dc6e54719b678"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "012230ffdf84d68f1b31a025c04f744049728b8ba401516fde3f82dcbce044a856cdfda10a6ae9b52f9801ba5562bd14a2ffda98a1fa32bc46190ec27f2b231d8487910c2a3a5f55ecb2a98a3065aa8d957e31650cca1bcbe7e29c7fe8a2838b113e8031111ced3e12261646b2844f1fef373426420377f1a70c6e1e1b8b12ddf169836134bb417c29dd71db00b6c3e3fd3cb71659f576a3e40b215c63761ae7e01545e5e112ece7031e48e9616304297c2b312884b8eae494adfe0fc41146b5b86612a4d3471104dd0afcc96643823ba6e4277932869a9e3111d95554c4d95822397f7bbef0b92c6329cbb117d0b2d17b13d08944fe6dbfef98fdb3051c286c89472e012d1d45377f7cce7a0aa0bd60c90cc95dadd38e0e2e9111c65e0973450ad8835f987507d2ee209a179f6be63de689274029c9c6d07d72390ec06489cc4d0c8375c84635c4b5062f98b5df34f501a79fad370e58c70427903e202bf1babe589df25f10ba38c7614d6867572791cff3b77a41dc553e6c7b0dc124ed151915c9ece614314f70a0ede2d678476214fad467dfd99005b3cf83fa636608bd2ee3ad80460c07cd4026a53e07b85e11a473edd81224193eb19e0f39d76aa08d21f14248b27a5971732924866b79e50e05b08f6b46a0f879a950f9a8c46681f3e6fff2fd333a3ead1ad84b89faf9845a8a583e834b315d13eb0589cb21604507b7d36f858426b1f015d01b727f9c0da77b76caf11fe3c93f675852e72a8f522a3fb3463c9b72d3179dd4113af7f73edf79d1e5fc07fc102f6c69dfda4a26713771ec66e55f6181e65572f5cae505c8630ad35908d7704ce7352dba0aa3730d1d46572220cf4a84a2ce8164e9d4bee0e2b77e2870bbe632069a17f94d8efa710246c66db7e401a7a7b0fe0dd5208645ad8b8a4431c2d403efaa6aec59dfcdff6c7f023764f5e992ae8d5ea2a19fa8a44779acbefca0de102dadbece101f81228c18c98b5189b748535d104c034b699556d0665abfcac19c8f3cfcd88d1d903e8709b9f14e8453852ae4a9c657fab42e0a690afcca8115486f664f221533326d44afba5c86a640a8d2dcb82190fb09234ffac08ba0a59064eef9517e39b27b652c3341edf4d1a09eed97f2f2ed4162fd56a2d07ee943a3e79188d90efb2928d5f3c23b954982373152e4094f142844ce5cb0b9e084109861c45eb7b8bc703d11d3be71d9ca3dbd643037cf756cdf262ecb76994c209fb9c3f72ad54f6b7463981c43fcd9177e6ff15827b5fc132d8a4885a862f2b8996f7ff0ce7a358b702112020bfd714185cff7a53171e61d4db63fdb2edb222843b07aadff81d5c0c44270eea2591e2c1e8ee02c0cf4f9936dbb3bab15d2cb62d9bd1dbbc1af819249b9d5b333db8a491bfa5662343ab2c21dd371382004bd111ea991a8958719742e49d72c913866d8372b20746c06dc1a8b03f5bea64aa9700d55d1535fe3eb0862631046a37b95b7221185e9428481060e1a35d51c2f95553f1c4ef5e8c64828fd6bb32675151cb8d506c2bda5f85512cb3c17c509f22b3f0d7b7454b1405ac6fed39f19d109c3ed3905b1de4b070fc61cda3011d2bf4ac85564b75836741ba4d453cb368ddfee0413311d47dd0ab204c9ccf1c84fae633cce7571954a0d1742d65d0706758cb5215023bd815535a63416f61044876adccee5a68b8b817348dd85016326be09ca114a739b7f5da90f1da2d121dcae5d205d7ccb268713ec5d456d125c97df0802f3f746278530e7cdd489126b825e8f8b72b13211f37ed2a48145047c8d00d621a2bcebaf61b0397d49c49c742f8976c98cffe5101d7fa3da662eef01f47a25fd4d495946e71857f9a32e3247019450f99d9f9074662472ddcbf10e5fd98a"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "002a1775ce594566fc7c63c3862029fa4406954e2e07976c812720045f0822e22da9ddcb3d9ff6b8bee90962eec23418527f1386417302fd5fd22841fb69804e9203c047269397b828a5a85447b4adcac114019c06094cd24798fdfd2cb0d1a5c4454ac798d97e64542b1cc1956c1286eb6c30e5db54dcae997c2e31eda0089c1432fc0a650aa78b5130ed4c56fe685c38dc105c1634e97be38319841a18b60ee8c36b2487dd2d960e057c14d3d285c1fdff40e592f00078a1b20dfe13537215221f9e94c5fec3fb9be6f99ce325817bff432876ea860e8c72c90779d3d681694e157a4830b83e2bfc84babf9d2d4541a655206c2ad7c5b183de818e10280a63394b0805fc7f92305051e03179ad1d8c085a4686fc335ae455eb526c41ad739233af6f3f05531c65a1c5676cdff3b492c3d5efae19bdd10b5b772d1fc00a9230486235be4233bfa44cfedef6b97b8c8900648c29f48792dbd8c5f2bb66f980d191879eed15186ec275998ec66b8ebda3460352105926e6d5c8fd0efeeeefdc151335b7881835b9d706de21fe599a7a29ca7ec61faf2f81b314a7234ed3d335e9f2d534b40272be855ac34aba6d2d2a9c2861643f8c885e0f912573e4c45153156b948575bf4eff497970554f3ae23005039003bd89ddfda584dacf2e0d824c1c542a42318762c29d0dc982b8c425e952f73fa9837353bf5e081542a0571e082524ccd2f65550b9e5ca063dd5d039daaa2e86b7e035d501247210eb4ce1835e3c06461a95b40c8198ca22c8539c0d736fd76b6ad17d8ac21f1bd29d14d49f0ce07e42d7cd1a7b61239013a3c309e8a7e6aced2341be6c9b38e95a094b509e7ac2902630f299742c06b3d0a21598c0f009168ef6da5fe13ca40f58b75b4db95330b7ae0e7c149705acf925ef3ce1bd7840ad3241f8cd171d2bd1f7065b4d9af52801d8cbc1535f8c6b8f57516d30e4466136d0b9b94126012638668afd22d303a5bdc6d269b6a5771928a602552d27f0c3aff0c68c51e5b4d29f9b40ab7a81db12125f1459d7c1cfffaad46eb0a3fb99dac9fd85dc16f69df8a3ccd04fe0c9340a15ae98b12cb432281e1dfdca29871275acddd9727690a24a1ce81fb29c821c0ab2dd37335949c462053355b6a496f19ffd423439023f3a37129e053b52f5543bae88a25ba19707e504c27ff17c9d512f560b9202dcfc7f3c85475c74e80507589adb7a05abd428f15981c7c1c724a55c0d2121ae0c75aa4c03e0b27818bf4c479052e5609f19743de0675816d6d167cdbb65df7c628f5a1aceff41a2051b3cd2a91674854730a1667e5127d9718dda64354c961e887fd32fe36c6ca7efc0e6c412120b73478c1c832ea00b2db109b22da4b18928a307177a3eaec16201c398a6374583d98d09a0846ff472b333db5bb10274ff77d3b4b275ef5861e9a31c8d74ca4e2ab2b7027568a95d9679233ee6d4fc53536636f449daead206f286a103475d9178b3f34bcdca3b4dccec1726a71c721ad4138f872ab9020356b4ba413df93f9978021189c0d8adcbbc40fd7a75a849532fe1d3457337bc37040e1e6416825b7567c40ab24d7e919f9e78da8f1b89434c299db6fb32ca827f081c8708b5e23ed337217b1a270588bc0f3f71924c29ccb75cbc3fc8c80303161ffc84c4bbf8b58080831030211c6c74375a262b8062b53ad225cfc071d58d94b6bce71021dbe52d13f87d95609a6993b03c028a73a4f41a5348770997165f84e3bca930cd9f132406dd66fb66c1255855fe0c62dbd62e5804fd7ad6b3ee474e5c198cb370b482745acccddba1d9a3bfed4828bbfe2b8f672ebf78db0efcac51e813dcedbdd1e1de854f514df8c25f5dc71d15021a74e6b9537c09b3f9b561ef19a7d37df9e3"}, - {"0000000000000000000000000000000000000000000000000000000000000403", "0037d3d925920a7bb424b0c80b94bda2acb6fa61811ab235f33ad0e2738a9b635a1fc8f51dba091de56009f231c1c7c47fb0a285973f06ef78d282dafb71281f065fb1756c9129a3da73aa224c062936fc96a46105228b6e56e3b785f7b0a8996e5f435a45a17bf24d31c394cededd00fb2254969f39cb80a9ad291148aa136d0969506c4febeb5ed446a161b87949a32b37981df661592366d6a7f99792ba8656dfd1ccd10fa94000aaf4af0a5713b9cafeb6a66175afe271d3f88200146921658717418ef5cfc80f7ffb9003833adedaa80595f99c9008765a55e0831db26538413491d1f0d6081a3bd74ad5cf59421280b883b24acde924d40fec0736692e4c841513b3553b029569100753e5ff55f82a8aae42a38e177ec14d42eab14a0050d99f1ed1ca195da9b8909bdd47d40d12923540144e86d59f423c1fbb33244cdef909720cd5b872753a2b1e4f1c60ff0307a187e9879098e5b2573938c57a97cad27f8378083f8b112df08101c184bcb619f1e5d739899d50b51964efeaf26174e9c9edd5e0e9e9da91f651d0032331bd9e3ceea89d4f5733c5d8754224299ccf35a0781633a2467e876f468bba69083fe95276e210de6fb15f6e73c515b278a5c0d9469ee1c820b5d2711e8ba31a9b27e5241a283d468af873f0564d32d3d59bb4194349728fbaf12b4fd1f67781d74f05eaeda4ffd4d60943f4060b02d6faecf8b4ec41d62c9b2a19bcd80d0daaa21e5c5d586bfd9c35115cc4960698af774d550abea1f5ea4bcbbf0e8cc27a7227d5e18694b7bd95155965551f1ef25fb393d4becdd6313a7dcfb686980bdd1c4d8dda32338f6ad47ea2448322193eb25f6611a09d6f9868f9cd8c85a4f87d3fd98b49753fda4d138a4c81c6d90d731b0fa17ab049a3b70745bcf7b4287a83c592daa2bfe714059ba3c6a4bf0d6378f3b7012a85bbdc8df0f535fcb498a76c9c594a599935d82f665b7a8635de9df314d48f0e68be267ff995b22211bbf107db3614cbd8eed1e6ac99f0e900fcfc1c4b325b12e43ab7edb3e361b397f52298f24b1c361a9e03e9cfc99681d9e03dcb408067bb35f87935d4201f186836d9044d977d10dc7863297b95d273487f286209090569819825f8d099a392ce75cc2261809a838b11a1fde4ef958a89c586113b3bb78fd2c3ea1e581701ee335d045745fba4bab5d0594d3ce72ddcbeb48404a495c0e1497bbfd3dd38f716cc7602cdc79861bd167305f9db8c552c9fcd6571b435add986ef1b034939006c69f2e51ec96d68159019ac90ba84fcd8b5e9060afc88a948cacdd26b8a416ae21d03b6bb1feaaf15975532514c53ac7ee99193b89dd0f1082813fa5c0eaddac6fc49e492cef823b67eccad7dd78911380725ce8690f159cb1f205d781c1579409721959a297a0263a5ab647231d3beef42e5947b4fccda97da82f92d839d27dfda132d42b44342c535fdaa59f13ef8130b17cdf6c1333e17ba5c949ad1f6fba777c27d237a47dabce40f6a4a2b9f1d45d3b3e3ba43a8bf5dbb360bcbf7d013541a6ae713818fee49b665cb0432448917fb6ea2f0500c7a80d6622d76bddbda3129d3d4080ce0def2290b90e480c621f816def77184f8bd016022749d9ed512bc015a6c429f8d3a39ab618bdc1ac2053ad996ea098fd6d24fe2d3ff256a7181cada84cf14fe5ec8dce6f27bfcd0f739bb77700311515d26c40daffacd4338bfffff55e51641397b49831e90ef772c0fdd49c14e3894cd5b566fc6cab2aea3adbaecd3078dac3ba883069edcc401b461e0e7f60816fd34a22a1e8752b1cafce7dba3b37fbde24b7da1bd51633a0d66a903005cea113985f48181d3958e4855d4834b4f5125b33857822b73cfc908c356e05e61151aafd2"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "0066f07022cd4b851d91a1b28726eccb69ea7eee710331ccabe9e134851a95c512d0bc98c6bab45e4ac90ffe5c8f2408f463de3b24398f27755e51a5b8bdb63801dbf777dc24a19be33777c8fba7da22239f991f0448c867bb5bc6e943f2813c832577d6cfdfb7402b097b3b2b21d62ef9cf94f25aa2a0dfad983f722daf09c412ec301f9785e716d335c4edd79a5672d66c2855d574b11b5ae5bd5b4e368a06c79d4636175b096903a509dedc0f28cf6c779a5597ee87eaff5f5a17990a05b310109bdf6fcc0ac220d5654f2cb3344842890908c34c090a56bcad0860936e22423c2a085585a31cf0154dca18af4344733a3b3eedd8cad5ce58de5506b9a99a698cbb8b212b70eefc23945ca01647d5d0277d599a95aa7e4b77354640e238dcfe1a19dd25552ab531f7c10d2ddd317485258f70e54e13c3b91c5a301fbf3b574f5151808f1478016d61c5a2522de0e1023f145e00c6cabe472c7398dbf952d32f7e9e2fd00520ee95852840d1c82255cdc64cd01ab2bf1fc2850ff2cb1d53b1a313a5d554b1d7725ccd2ce91daff438112bebb41f25319aee94c0d8412f4dcb2239776c063f65bb5544d694aec9c0cc39195a3d67e0de786a10f6690602a15c611a008509a3b58e91674ddd23df0d5023033f5a353be7f5635e40c236fe818195c8e63544ca845f1f708d083205365539fccec1431c349802d8255fcdec0c2d7a9b106a4f7b23e228aa5b04c509a6a676dd0b3a549ce65635bcc89d7f66ac9d3fd81137ba333673350dc2ba984fb649b8e3a26b3d18f241e4a7f4e0a8ac8bb6500a28ddfb51e2cc453a283e085d1cd57f4dee72c1a9b2335b747d6135137505f60d0aece7a6debbdb3b4632471528cf591036161a741cd403a7614c2178d140f7e9ec49ef86b09c36ce52511f26b3e898a6caf4e6561c91ee2e86e933bfdb6001433d2d7411358fa466e464a63c4baee734795f535694eadd5de944b59651272d5ac044ab2eb03c18971d452fa10fd318ef2f9e2519b8bbc5fd977a762bb32ad1b5b5f1729f1bf7d96488184b4025a26833d7630484a34886c857d8866e608a4b07d47d29c4f82e251aef12f5638982554c3a87b04974e972be687e0de810abffcd190a1d855a04b11225f3db9c64bcca081b369253bd7ba388eb8abd7736f73faca69f4ad65a57054ca733a845981b30ff4176bd363d92d6e7fda7d617b4f77f72656283745e1b5025690633128bfa6456079d65bb1291e2f1c2d4246a11523b223b2198ec401abe7cb6f00e42d13bd6221b6312d455672015239c0b6c1d91e0e34795ba30a2a69bb3f58a267ed69d7f1222f62f7bd8e02d6eced1e6e7f89faa295eb83ca81028194563999e58cdfe39342e70895b8e47dc9f9312edd0a8f8988d33bc2e11345c9f46d507e73dc6bb04b9e33ad012403752b0149ec4ffdf02ca7f365ca238bc8ccfa0a14ac96d2dd7713c3e17d600665ab6b9165758f86baee113b43b15598aaf4fc1ea0897360233b82d804091bb0fafa6c8ea0a5c0deec9757beb321e29cca7911006a33d2f462420db5b968b14d6aba9281a56052ccd7a606c2c4975fa639deb136f59bde51f0e4dcf4510e5c6f03238bfc4fb082700537ed68a28645cccc828e79d7f1b835d8324bc92dab9fda587059e55fcb6888bf2c7fc34e215d98922a7e3bb301a10a568b4f60c322196a6847a212cf275716afe3fce196f616b7a896374d0f11271014dddad9bd95ac59537dba2f4e93e7c3ff553068ca4d0eb61c394cfaf790d4690dadf8eb6d737e95390e34f83e8e989779adf35d66d9654b70131bf03c7587b573cbe4cab79dce62563467161d406730b7d7308cfe88d298575fdbe4044dd936aca1d11496fb2150db476093146ae4a4a6f"}, - {"0000000000000000000000000000000000000000000000000000000000000016", "0012abbb486c2095622f0530c5419392f1a07d1a3c037ab4440cd0214104d002d69da5fb6b27e49dd3a5084cfc25520423f4bb057791ca63619e24dabf439038c44f4d26f194b3f26816a0d7ff519e18ddd78cab23e574a967dbf07bbd29129a21698af930d11a84f62c7fca5755924e69509b134e9347ecddaf5698179f3033cdc73dd7d819fee3940cb2d2716951225f7a763b198c89b855a8d8b8c3b66515c5e5b2225c5e1e7701298f70550fbc448f6035efc772e1eb34353b0dd308e87968d7b146519c6332dc6cb7b8268d8c7956ed0526ab53e6919637d0c7c2445ffdf1be41ebd52bdb0aab4422131d20139a55a2d857f547ae931fdfd5bd0ff2393a400afab482f0f5d2a4720df9be24793e382194deab364a008db6e7e2be6af02dacd59a0a8b4d1464faeee212ad26f4de44b329d8ee0e3edd764552304b061d5ee6fee1727c265f1b4801bba39a5e571e023f098d344642d90bdeb18172e7ccede4b090d377317857126455ac2909eeb68940b50411bf5292f5031cdd86213ad48815cb1fd9ab78ea7b6f1579fe12a12bfc65de8fad90539b942539d0499a0152e56aba35039fde89b1a266652cbab6e2fccd87ead3f7194acb0946433716d3a2c4aa4cb15893b44898696487caab06eaf09db1a7329368c4f2a2854c7a24efb3ac9e6f173a839846928cece2c0a86ab8c45332adf897a838156ca77c7ad288356489e3a1975311e9508b1cbb9a187cc6db48547d99c84cb450e5ba645e9e85fd77ff3b72fb47416053e1a0d7ca0e45e79c929cc43fc3ee435b04492f69e4cd87c4864deeba76a1d5b0b7a666249b5342d74ac0767a94a8109af3674e39641accaa461cb5443be63d45552e36c5843e909dc7bc138e64387d7f1d80519175534b6547d7d212b2c2daf802b548c57384c9f1f3f7c607c6c632dde02b384fff9fae0112877b451ad43bab1438cdb2f7b3ce77bf3a26dc13a804a4495dc113b88f3155402397a0a03937c02e0e299dca552f6551df76817d0aecf95ce702d06f191dedfeec198990f85b25c646d648b48d95f30fbf80012e3974dac413b17556525ec919af6d1f9430c7c42a820b50f3cd909b242efa2e6e5a944ad76b1e5433171525885a53f164b6a3e380ca2bceb374f01fa1933ada6346dd74ae53fc5c764ff7781a567547d9a6600ed6d7801d94da713226230d47df06c5752a57cfc0221e0c4b3009514f5d2c4252adf3e2399bbbd822b92b467c7a6ca2e8a1986d33bceb7c1fed1203316948502487b4bcd96d090b0ea7711ee14eb64ae37a18cc14177aad4bda9ecbc5bd823b5a145ebd3cde9065f32dbb4414e3b24275d20e4529c8ac061e73d1d3feee18a612e2f8c6772c56af51e125b8935cdf72b6fd87281ecaccc42dce5bbe989905de557e039b333d69ea0180e6a6e3482bec7074511c11291610bd0ff8435a1e8b47a0858b79133776b3b333b255bb34ca5aaad20b5bdcc3878329af57ba581265c70bbe30297879ae36ec965e76504c18b94e665eaec443c209d0319d96099423f284a3c5fdc74ee1169fead76b2ecf5b6f9210900a888859236598eb54aae75165fddf411985610b420ddd9ac51be3455dd460f8cd56bde7ba4fb6c02683c703ea21b451794b747be67b266a0faf5fb7b702efc30d9304e1e5bb9a01582349d54916e24e1efe0b048f98f3cb6b08f676d0b668abba38413ff5db6b272435680a95d567241454dae7bde15ad40f7c92d235605c5a2c5b56b16b25c7b6a2599e3685ac94c8b5036718b4875361f32a7a504ffd87ad32f9189e1eb82975baa8d0d2daf92458182748574f2770cd9d1c9505b3095225824c06d1054817724e50ce400d5457a343285eced8782b21d85716affdbc326224ecff3150"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "00027229c452938ea70bf42bfb67ac95cd6d1d00fd2e206e5d4698d08be38733fa6d5fcec27716f4a77b049b93154f9b2e11ae08a069cccdf6b453437fb7d010f1a1f32b5b7b0daaceb194615622f5692eacc377082eaf3706c3ea6b2f79e2d812c1ffdd28b490afbc149b52f0006185c3624535ca4e6778e2781997993e32e38bf1e87401c3e142560218554d1e658038f09254239b3e012e9f538380b6c05fe868d34a2d1fb0eb0c4b399d823a9c9de897e7c0cf6b1a7ead90bc50dd1c02474ef3cc166303e1924df7d29c7e2089d6b6723a75745b61a63a9f821c87567970c76a3c1edf320b469097e8945b92377d74d5b99b7587bd858b6eea321082e6787255ecedbb9bb18f31e92e4928dabf60291c2758e8fbe57f19b08103c3156672a5701b0f3e5c4b07fb33bd2571a376d4cc32b7fcb0cba09dffce726cc6f42d3922018f38fe47f0e44f41870f879dd4fc013980d1fe97b9e3a3437337fae41b20eafd5cc4a6116499cb104461eff772a70f1f79077a4810d55a06044200e8f2e233a357ab90d4e76892111130910c3b29745ae6081ae10727a634826ff6897f0055bd7a71050a6d26a141a3f27659b389d3b714a5dda61b76e0066a9b30be5deb1f1e3e16b656d4b83ebcc0bb165807e113bfd3ab9e21b0f772e52321109d49ac92a33410d835807a879630ec1d61769ac04a620de8bf42ad043d6bac5004214a90a181ac77c838f6a318d69ecc18fbc63961d40502d2bdb33370e98fa58557ed8e8d086a1771931eacd7e71672078ac4ada9870b9246e05826b30e7057a749398468e1166d5c8f3efa5c2bc608143a790f035d5984d6a25045eb1c4a07cd3daff44760c6c74418777b4038148d143fb1a5c4b011919513a14ea9aca46213e58be28eb3e8ee756babdb3cbc15432fe28aa678c1e68773667643cfd11268dc7eb10078842afadeeb5f72dce239b85d7bdd51fbb805211c6bb66b902763d353aab353989ca19a268c34436e031018da9469d669c87d845c51d40d6965111018382e00ddacd21cf0a56a21233fd0a033a9998d74b2760def9ea4f64a6f11d4831474ba62d5e1b03e75fe3523517a09e6b339cdeaa513a040f6a6f302a4d8c94d12d703d39e8e1201295884d4d7e8a78e0c6b33f08d1dc386f07a0e5351c40a431efea3c37518b038ab1801b5d121ecd1967e9df732dc27d02a78bc7b1fa51d2d759b2261d15868998244b02f3a449252b6d51f5a133b10b33651f46bb405ca1c25f8a1e7a5a45fe13517b8fe759e18505b926e55b7f5626122ae16beed8e0801d8df9b9f0d09853d60cbdee2b549bb221a7b251f66bd80f2ea84c175bda85b9867737acc171f4b3b0c47be34cc636da5a50e63965ca63145ef4b332a95463752beba55f98f1bef570ee1e0fc7e9eb0b8866e00989904bb0c20ed1614006948ade62d302aadc9e40830519cb3176cc1fc0080cce1fdbca9d655323cc41f7c47d3ec0e35cbf77998debfc7c6be776955b28e2c29d4f1352387e13cb5e84347ecb8beebdf982b7a07adbcbe630805174414db766065034f1571dc78ca1f19bfeb7e1d2cff7cf022300e95ab31f200d642b20d2e12d7d7fde863f878f19b5f7182e0e6d73e14740e9f1151e7c4600486602595f9fc4689e76532695b017e707149e4ed0b6a7cc665db42644dac1a7d28ed0a26bc2dee4af88ea5fcc37aedb3872ec5a8bab9dd0f0e851ca185e39eadc977d0444e27b2f0aafae44f5d56f42b17bafe21ead48a80d5628263985fbd679606263ddcab8721c98114172dc4edbf1e80383c72a810ffad98a91dc183f1ece3aeb3b5fc01a38fd0bd3213fad3e2ed075d52eb2ee8fa774e91027d605a055c1f4831659a92f54716c5e292b5e5831672c8b8afc3"}, - {"0000000000000000000000000000000000000000000000000000000000000007", "003b58a789a43e9b6b98f2155f4659953c81555d9e1b93f33dd8487c55fbe9f93f3c6f6732cf0758066715473740121bcbb31d2673de9adb3e25884f2e9f071b1d2556ebd5cdcd3a0b1770fd43ae56aef457dfce041e7a36e8d11121f2c800b359c0de6577908e5aad330399edc6a8642f64f3c554b2ab0a3d83c3daebe10a842feafbc5a18f36f250de47d60f1f866dbf92e21b568d90c6c9efec7009aa84835a4616b4c43fb77d0108b19cb3c3c5e776645334c9c3100d91cc9aa6280c862c09b316f38f2486e70ac9f4f341cf5f31bfed0777a1d4f2205c9d848c68282e5b0d0f3752fd1cbc136d8d7357081d7b093d659291f9ca89986a920cab01f928bcfa86eb7f28f65450aafc77052a225964af0e964f018eaadb93d477b59d3dd685919979b4be860cece9754fd961e9689a92f0dad3ee760bc99aaa6d284792c57e54c88151da3615704002b73298de031e00b9ee4659512cdea39821bf28b71f9e618db3365310e81091835ad19d5e6c95289d4ed9ce4bbc39a03925e1c957ad21b2d9357c05059feea319b365ae9068502f5b9885d7e1476aa41884dc521eda99793e034a0d608459c9a6e665ac7bc53d39e006c5c2a7d0a5ee24bd616c815f3941b8a0256a6ec9d72676fbdf140219480aa6dd866b51397493d1e6a2d60d3d5b789e671ac394f985620c0168b824364278033a1e829b7ad7065eb8f10b033150a437f48b22634ae2900ab4a45d190938e615d95e6fd733b5c1ed44d2afdb2a3f6f0a198cae5ca6a600fb418ee30e92f1139d0cae3e1d5f31338c84ad1bd72b09dd63c3661f023d757cccfb81073b6a129f079d17dad8211f552387fe5f1bfa47160a2d83c310697c795be047254944727a338f96c6a01163fd7b5ce45f53261114abca4547958776d8eeed39401ccfd55171aa93f2d4832b6389a70c939eafa40125367d8052e671857e82656a5716de77d39cb9703bdcc31eca5d43fba1835749e2f95843312a1bd07a02808d25b24ecfedf6d88070f68638da4432178170587975cb122138d3b42be9a154530cd37ed89f65fe109fb8f44f8fb9e32bfe820a8c267378cd593b2517224c16b7a1c9b24c880043e3d75debfedef47e3d9c15161cceb54d7eb0767db29b276a393798b77d970b7275877989a0a1d90f43675e017fb4171e94fc59a408845cedb8156eff8bd7a27b85e3230531eeebf7242a045df482253105d95183d4ee67636142423ab85e15f085ff115a10cd9df82231c123ceecd49977e3c12911cd1cc5a2700380e5556729f0d0f2dc2efb8078120ab48dd91c9204f0da71a9622bf0f9c968ce8a7473725bfee73a4a61dad649740077cb46afedf7cc021244e165a40fd370eaef121b9c1800acdf26fbd11133415ff15e52d50cee1d55bc6dd84cd5888b5cae770359f3c8dd5214b2ae42737eb4d6f925010ccc6b1d12e8dac86b691fb5d3afb516f6cbdaa1efff12aef0189e7a4f1b5fa0bd8e73d281d01aaa9d6abb2ef8ec93468d121b653d9996403a7c04f43b5f7950fbebde0dfee5de50cfbbf5fc6064bf1ffeba8de2fef7a3d734b21277bed7bc91f0f625c740d058d6a59cbaee4019e67b69351f332bd2c0f5a88577b5c589594efbe1211b6e0b5dd3225ac87d42f9c73542a20a66bad5800414f86a4408c73b9d24a209dac245d971483f9f242ae6fbf7ba75db83f95ae363192f91fa0f9dd9ef420dbd7b9d01e3040f86272279a9f1e7c70b1f7cc1592cfe9ca8dcb5a7edea3d6618e4384c99c64f3c66d807354e42a778e777cffd30e26abd99e0e7e1b3ea410bbc5c604bd7aad31ee94275c7cba742d7cbdea8b213177350965602ef06d30153b7d9de2924d93086a72a0eee4c26e7bb4d9a1b72e47af0d694dd000b4e38"}, - {"000000000000000000000000000000000000000000000000000000000000000d", "001d3a5e7d663d53a3234107da4892c638e5d5310d03647e6b65b127b1c818b2ee605aa1369a9dbc57130c7e464079ddde53f199c52ef3edf3b15233f65cef12ac3b49fddaaffdc70a5222175f5e6d814b9d04ed0194747430122a137e0a91048e5a2e69480b91a8c20b181dc853868b3c8240233121cf11a9a4151343f10bb4d3e7890d9a6f5b5cc2c66bad89fb0fa6fc865e22ab04ebc80d96efbd4b124ea97539ddf2b5d5572501833238f2e06f6d960ff0d6c4f3aa3a0dccbf94100e13c48797954883d651453b835701eaada9d848cb0bbfcd7fa8103eb5a174913bc06b36958db9f64dec1d2a77cb89dbbb49724d9578df34e306e069bd2926022bb3386f255b45f0c1d4640a785225445b188af30806023c19cd06ab225811993829b668979747180c07b3611db48e4679a36011592ea328b4c720dedcf12f669f5cd95170f2b01673f8b6599fb51921d05bfa01aba1270fdc426d87e955034ecb77ca9bbc358bcf11fd26d317aa8787cf98067ba9f9430616bedea8df0832a654839827632378116722b6d578fd2f4c661c13727da103519fe5903b4414ddfa61adbfc3d63df107fa2dbbf094a382fee5f428976ca735a275ddc6373496b3b4345772b0d345e40af1ddb22e78f2fab84e0f7a230d5d5de452f60e21fe5ded0c6a61d37ad9861603ae291a177c1f02a184a2cb29cf3734325c0ab606d01ec2e83a7945f9d0d72daf7c1dc31105fc12d17abb347c10a939b3df7539ae6d55853e88723d4c7607b1c8f82fca9336f6dda8ad60f7c43f87ff9c86f53b0ec326459de63feb95ba3e41611fa31b20db56ef0bdda6163f39125bfb11b3baa95090b788639edc0011c75f34364958a0dc24547ddf62ce1b704c3c758a3044c5ebf51d194990c4835598794ca1be5b96cbce32f59e245d22cd59e723c54416c75515fd1e5587450031c008d044b236ed73208022f3cac590bc310e9c0a170431ebeeeaa1b9a012f27f226072a0b4dc47ff29c75deee315d1af76e34a053e78dcced8b0b7df192c6249d76ecbd147aab54656a2e28842d0b65dd00906c33fb7a463d2b1c06fd564853fd4d28821d6cc8b2132a9f69a6c84276f8b62dd141f3672f2ed389409104236e8384eb9d34379e366bec2353a3e07f22f15154692f4d2221e33cf2e6b8ce76a1f6aeb177ee8d50b6d7e3ef9db45d595e054eee2350de7b4fabe54a9178a62216720fb814ea686753bb6ecd6f2739a9d22134c6f17315b11bf2242332d02409e0a7a877f82c24e5d5485dc6c4b9fe5aca85942cfd13b266079a21e0e96e7beab135e7b58e06484e9369d9923c16ad6bc252bbc0c94de7a7ff1b5b42768b440320153114ce2178f00ca7fe20b09f545ac35dcf9d99f36347a0cd520b03e632f16a34d8405251cebcb7846475db7343f00cf75fb9b0f981ae8f4302aab1b07aa00929ed525032fb760724c0f53889413ce633a811d3379bc72df05fc9e1b9fc20c9947c510e28d1c32287553e73e001c42cd3f56a4e43943ef13842d600523c8ff3fbb290292e672471ed8a1cd1c9196c92a2e1307cc79b4372c0897c2c5a057b914d2437dc0b837b13ce598575508525db5b9451ebd486241ed47b1d2eedef2b7893b65b21690cf2791a1502b1a56f0e20e331a9cfc8dee085c21456d4e67ae85b12126f43b5e4081eaee897c0faa449ee36408ff279024fde1d8bb89cb05f67aef35157c5d9396606eb30ed63df677450634c19a970257e1151ad2ef1a17bc8c46cf575e21ee219f5883c50e444e06ade9d5399c95a3efb124c6da002ed608ec3c4d53dc1e611517885c059195cf84c31eb21de5001fc17728e0a8b0bfbe2eb8f514ebf3d29ce256dd4939339c7a14a644e5c0caa4445adc54211fa4ca2789"}, - {"00000000000000000000000000000000000000000000000000000000000003f1", "002d56c2e04ab1885ef230446aa853491c0af04f1b4d54bfcb7b5ec65796b9f7dbf9de5e06d9c5775988105991f35827dc65b8a673cdb56a2f1a0a36f5c82a2bd4726d6294613b4f5ba335162cc3470bab9ae5280082636f3fe2de79e2d1f5bd3ded7cd630b572813e43647aab7d51bd9da4cb4579b6d8d3e3099d5e8248211d46b0dc158028c5da1347d1307ff68a6657e67a313f1341725da4011ee1774919fcc13e1a3a7e995201a09f0ddfc6ce5bdcf9e4fe9c28ac3a0527358e391a6d020e4b12a6fdf3bba524005bc7be7ab638f50e01f5e79903c122b76123f48c9c4339c934dc9ca02a49e50293311f3c4734bd696fc56ad9ead62bfc2b05051261997e535f2759c242d09ac66f1943029f1e0f1d604f39340c6a69bef18998d3f18a978b581f0f460c53dfd732c92f5f204fd34c23aad653c601bf8def15b09b95f4df7971997b495c0bf7d4dae13c19bae0038539267c934679889c77844ed2b6aaefbb7dcb3c2183ca521d22c319d675a4d7f6e821b9bcc9745bdb11f6d154ae1089bdee6173c1ebf69dfcf8894ca4433586342e47aebdafa26af3e0e069450b24855cb3470aa7db853a257fdb6034c15e87b77e84e3f5690a7720f09740d7adfd65750a53635f5f6f70ed64b411380d9d2feb241724d312b0313514acbd394930f5dce11661de2c31995b4b6c5962e2f8a574d6e2c83dcb17057a4b6b0e86f363bc41529ea93445a8b5ae39285a323d9400ec7046ddded9b334f1698b4d368f140e0d07027f0ce09c1e8974bf812968d359987fc0b5ee6b4ce847931b1a1dcda07236624b55505b07435afe960b448988f29f246ba72423f90463e55526466ab0e21dba872ba1c9dbbcc0975570fe42a99abe8ade73be1304de1cabcf7efd7da2c9e2eb5b85f6c260fbdf3f23ac240fcb89175c49faf437b0e34c0575aedfb4b700990ac41e0d43897d9746f48e4aaccaa8ff1aa6dd4da56602dfaaa3e55686466b8eba81db1a5bdaca6e07381afde89aca03747d90bd422440c4579f255ff91444512b3769427ff36ff19abf51ac5b149cbbb6f90d7580f494a33447d9fad0f516bc19c45bb5857a5a40a3f2241d611f6f9b5f36da41ed374a31533d004a239c2aa63399a6270cfd46f7da5ffb6e22b158d52442f2f5348f6dee85fad5471aa967d9d2a1521a087902b629bf4c99ebfee383f2490bd22aae74a0bfba5820fedfdd259c14ccfa840595983b67b31230fccdd20af299f860c905e590ed50c62073d2925919dc14d40b055d604764cc07cf2924967de559915050bf8af004b9023e64da4b85e4df31dee0d280a2d1977c80ec1e04c7690d91f076d47b3319f0ff385df1d8be5e2f1bc45c29f4ed1d67f9f794e62b68d26f51001bdd3c2ef8d6a2d50f363d9769971bb2d426771c947a7bb302a00f15b15f328153d4e4d3c07a4ac19bdc9b188e45998f072b7c3d3ff743657a77461e13a24a1e1e8f24a513de999a9101f2ac837ab0404431b8ed2f6bfb292e41ab43ad7753f56c15425df53f517ffe1c517413cc86561959267b001842b21536ca5a5791b3e47d3a5f06c8b05ac0f1db556772b1cf2ea34f637cbdef156dfdcd76b102438b284a17465e12ff80909c7949355fb7abac6d4243ebab1770f5ed8115fd3bd195a00379859bc2ac3c81710fd355156f4a31148012db5648efbf7bc29d0c1709bd453f9cc34bc73aaa5c6d5c07443d9b1f765c0fe2477113244f9adced56fdd95d2ea82996adcc3f5897a0d89834dcfcca32147466d410a2d0f8de9d13e514285303cbc273f902d45048dc25d4fb102cca0fcfa777369ec4e8962dc1875457612699155d28a77407857c79e97463b4b34ec89bc39e3dbef44437b766adf76ac820befe7586f8d1daebc4"}, - {"000000000000000000000000000000000000000000000000000000000000000f", "00893317f3e2b0ebe43b6437d0ea447d629932d94c289d25cf206b6dbb7d23e330c348b338f135fde6890c50f1ae1c09b220c09ec62ca4da5dd6472d1cee792974e70918115059544767d168ca8f422dd63ada4707f6752040e4c4018ece56262dd38e7ec0541d0225115ba61b7bd1a9e1caad32be1c326de96e8c9e5e202e86d9bff820175f25d1b4600742367919fe35351166bde4342aa6d245fcfdf6727c7e9ed234d85cf13d0596de227f43fc410c6261a2065ba234f8bbd5da36360416d88fdfa2c3cec7262ceeeb1bd22cda97b65b0d821304dcd862cb795225615553f0270ebcfc2b331975a38acb3bb53bf13c24e911e539d59d92bb012409a5ad8affd4fe09087f0127fed9200097fdb2db7d1dd3b692b66705cf732d61df4d9cb2ff24d0fc5f710d211e3f740db38c9b95226494a457da4bc71e51580fd256ae05cfcdb34a17b731323d4d1f75a23e13aa0112a3bcc41c1a35cc186258a3c32e7e24867dfb8702ff2c162587be23ad0932b938a9e3e0d923d1bf9a02ce137e38e06dd9c32b09d845554e6ac35dba1f7d1e78e7f6a59b88a9b3f762a8cee2df5d6f895bcc4c027bed3939823933e5c5a35081a3b10a2954337cab214c897c721ac39feb1df24784277c9eee37df962f0666042a475d1d916343d106131d05f4aa5c51d7fe15705f454e89456fb541db2fef69cc2b0281f855ce06d1fffab651226ba51c3118e673dca2193f99dfe0193057c5778ca24d6cdb81ae4812b8e38ce03f504b09165ca636ccc3a173c0130c4564f36ee3fe9f2c57116f59c7058543b2a0d031f45ba52f790c80ef4dee09174aae5baeeeafa968856e1ecfd0626c2475e3ff28636c34d1d69241bd648a04f8e17802ba4b5909990ee6bc5075478021cc3863b04db2c7eac9f3dcc3fe36bb8f8ab9143371ff94ca2d6be653c2ec67dcddb600aedec913c5bdb259cf912d05473b1225fa3e1d64131ccb557c2640c5db0de72fdccc25721d4c7ca99a0f7e8bc14c633d6337c97587f8656801ed6f515269154f8126722a0ba7ff7431c9fe8e50f4c7e697a52603756f9793cf889f0f9261d4c56d430d3855b37c83077dcc15fedc672ba3dd75f10335975d84e0cdd15d08b7ad507c9627856aaf652e82fb227e7b9bbb778d5b5605461fa285f3974e96b7dcc5aeb6b21b38e7c70957f0d313f6801be776c2783fcd2446cc84b8d852270e9b9c0f8c9fad906e6b148eef8d87b720bea95e133bbba91bce2942d4e6b2bcd27d80a11f5a8d3f9315690cb03d4f5327aa5e52c3d6a32533592f3ae652106681d095517ac7642384d9d54197fd68ee8f2a8a7329cec960e5a87df3de685ed2664a5f998a3d9f7254d34ff0a52fb837ff1225d24370297ece9dd8a005733ae73fb81e6ec1365fdae946fb78e2c5e8de0172043944512ad2aa5caf9f659f364226d2d0bb5c20390e31f60cb05f1449ec84e172285fdb49b5a378bbab060819f9e4c1f67bf41555c003f69fc772b7fbf50b0f39f5a386df504f795b5461a1b452494534783fba11f184b18b19b5cad6a953a7b2d5ffe7b399ff9d973303df99b26683695e51762940e54c5a28311aed2f1c81ad2c23673ac1487f62d1bda673b24abcfed6f0403615273f7455c1b7b585d5a6ee4dd5c15afe32de0661b7fdf1cf9421cef3c86389794f7b9de91f5d36074f9b2ac0a429ddff1cf1d1d57c6f4cc7d5b8733a0cc91912a1cb7fb4a54db7b8bd6282165d361ce03239a79add42923da38992551e1f7e00e655ab56d6721104d275d59f45016d6f01d1baf830856fbe14be4519adc560cde02939f1d5d313627ff67db99173331523f2f9505755f196fad835a2a4783e662047144e1d42376c14cad323cdc89b1438a43be4276fdffc8f3d"}, - {"0000000000000000000000000000000000000000000000000000000000000040", "005b32b36a9169b7b99a110fbec8837486e4bca13110c247c840cd761be100328c07a10f3ac6b05821043cbd966461162c4597be649dfa51939df4831fe1ad74da1f150829fb87afcac8f832fc953a5947d78f3f050d186c0102cd691374560df7737c7632431cc6df23e69770cd166ef8b9595ba989e7708b542affb57b1503320e7ac676909c4231ec40129e8b2a42fb1b8331d1d3e3f47d86e5f7f936cc54738b3de983f01af30b2b76afe2c62a63427311c29bdbc97d0c40d4b94a47a84ef55aaac15bf05586d36e6a315df9983e990716be07eb910897936a5b918af3928d5cb82fd8a10a2a0c73c9b65c12b5c8d9b3d6c9d2dc359b0cee79240c8fae92f5accba5798c811dee7dc8ac72c8557d8f23ea7a1bd6a92325b8b3c2b7163417cd77a19d711e0dabacc2f6ce452e96fc04d67153ea5d8adb1ec2e1171a898b26c9c30d1f83a33c604ff77e5ab8fbc13b0216d7b9e74ea22d18e58522233329a30b777d92462c969b053025224fb733571ea749d292441b9ea0d605a4aef04798470d43542378251d78edbd5fb36fe6064ae9eab551459948c9672b9ad07d8e15bd7c37700230673f40a6521f6d86809ac860a642c334bd74a006999336a34a1e55853de3f13b2352d985ecdfad3f0c242318d1c4f1dec90e814c2ff401ccf5d5ca1eba0e18a1415707ff372f72410e0b58db9e3428f95dce04e2c847d9495dbcc32014bf17a6b3c61ac8dbeacd0d23169cd550426f834904de8a33002e872197d69c0e8b121aa0c6b665331e85353d68ca823ef2bbac3b295a9d52baefac49ab8de55183fe9f3aaac5da289905898414a658a59cc63f309c26c36c313861789bdd1afd87ae0f86d6ed2c359806e4508c7a0fd47558e20ee775e4ae4b85a0b92d8231e035828965e3fb1ada2f86a5f17a238a8b7cfea8237c58a2670a79d9e5ac018dce55d7c42f975bd2708b07da46dd1838ecf7e21a83964c34ac6055d918531f9156c912a390f9596f1553a659371101dbb7ebc1d75be5b97cb3b46b6e522b6afbf5ec65050175a053838cc4683e5426bbb3e31065d7684c9665f15edf1422263898f957f3f09f4712869b2803069648387292b92a96aeb55032fcbb2f17f4a137fd90e2f79cd1d721d1749d3e0b8c35107f2197e29456b1671fcec2966f9833c227382e9c5c5d039af24e0e302dd58d9721b6ecde586942be1471e92513e742f91a47f75d01e2b17bab98fa2eef557ed9231e0ab04ee186fd2b032449a7b5d8851761d80c064204dd87eb5d17a59e6525a7b7597b45b8115da03c0b4a9c0baa1bc953889623f6c6e9696d9de99fc08910b6aa2c8e5faae7aa72b356d7fd2a4fc6a7df831510f3f168ec4d3337a1c48a8db2f25cc2e4e9b9ad3f16dbbc649260802942438287eff74db641b2b229df01e9e6176228aaf9f13a449ef34ed8392f023908e57caf7f70c82393f1b0c569912ce55576b595ffd33406e4095ec5075034d0af181f5273e56e3fecd202261ab4f4025494420f402c8716d1df651a953fba1a4009b7872fd4b1bbebebf8f22001f3d8e7a7dcbf459311265a728fdb77ffee37b1eb2fe9f92d5f5876f7ce0dd35f5277e3fa35436271da1b545b6d05cd0cb4174262daf665275bb9cbd6b7839be19e8f3ee4dc9a9f02d033b39d9092fbb4c1434edd2a0ac511adf84f70194fc6319a0bdaabdd7a2387551f3255d45c763093053e66cdaf4382b44bdab21a2d2f5b35985e95857a074c8ceed798cf03bca2d22f81a2dc8cc390bc0c680463e6354accd9d5b959551ce8bb83a2adc33f2b550f1fdb6dac0a71853d8551ac326a34c1333dff1c9b219f492e9bd6e525dd33734747d9c8863d6c9461d2533b9f301f15e0b8b242b9ff376d71331c4d3f230a"}, - {"0000000000000000000000000000000000000000000000000000000000000006", "00080440fa43a4305708d1a60b2db84114295dc0ea0c5d7c7e508323fc4da1820298da1314dc3770737729c136a45ccd747f7e2164cda6600c5de4f070db144f803cdf809c421786559ba1f5e7bbc765453d03450589bbe40dce6e76b507d62003f8081ea99cfbc1a052aaa4a45fb37267af0cf5db0ae272ae09c2b114670e7c731eae4d334b1d9c11183850faa5a1b1578de225af72a95e2b5c839c4ea46d995cc6e32fea5eca8700e01cf97b344201d5a59090f874138eda581f91ac1411faa6c62ef4f5c6113320e8468e1f58be5d760b020905baa504f19a4920d4d52fc48f22b21c5aa28a296b474d9fa0edad55744407a0f80305a5177a557f12f5afddfc9698639c4ba9b08ce5d2f2e74a38d50e4694c4f2939ba385a49d8685d65351e38dfa3f2e3c19349a5df5b197c3e0a742e660d180a6727b1f264628f08308310ee353818a72b6b9f4169db62113695604827fdc595b4d0b724ce2d4055cef656bc49b417014c5ad7183cb8dfcd49834e57cf411c3ac04bfabe90b4c9c4a7b1ce7f345daa32fa2ee7d72250799e30f0be54fc7fc496958b022fd82aa768f6b6550df25b116df11bc332be9fbd03952ca09c9b0c98507366c8f1b1aa3745e546407e77996cd5338058dbad79bcc8418b3f4cedb6c5b59aba974920cf9d3973e48bc43f443b944232aa42d47a21a1a684c5b519716cd9dac4e0536b9d0f4842f05e25f133b5d21434512ff9ecc3b3a79247b419df9c50dbbb5128db7505e30c43825e30888b9f7671607a3c869b54fcf2aaf0db828dabd422e3d4446c1ece4f79d94f683b0c7d11b0115fa2d100c96bbc8a61bf2e7da9ef1a74145b149afbbefb11d0d40693b6417dd35b66e2b678876d7471eb1bd63090dbc73ae75cbcce7ac3372758d7907ea81cef43d4b49024f9762d6b50ec1c0483f0554b9b6c290168c5500322be3128f66fe8ed166dcb3d6f8be2fcdd26af70d81d2a1c9688fada806389b266bfdbae1e71d2b611338bbf033886203fa57a545b2ecd061ec62df23fd2ea19271ebef42df8b14178d626dfc725e601cbc33052abaca9546a113ca22d31f3e9bf1c27bd7fa435f07d3b9237ca9b9fd9dfae0876db97d86a0fc1902fe185de9dda18e0181569451d6fdfdcf0a0efc9ac1cb51df4cbe1e70390f98d3d5452ab658719ef11747c90b0a8e4dd15186bdd1ee561c44ed235261997fe47023ac7c71af52ab5726a3825614b6f8b8a075dfebc00d9e5dd8eacfaa3bb8f28373e6c75ad5c7bc9224461efc561f7f87df65ab973303031e9a4645eb3ef4f113763d1aea9f82f5d54001cf4aac06ddebee5b835213f4778a8af4a96bb3f051b729720f420e139bbefe242d6b5ff066c5cd5170444d66d7edd7a1673e98996b1f939097345e2dfcec78588c525c57eee4ffce4606749a8b4bca77f5731a31c39ca0b1267b74f9699f09834c8c22f2d901b53051e2e6b78e3934c470c1cd194f4bcb45b41501b78a03c614d8ce8eaca3fac9692a94841241342c2ffb4cc3cfd35ccf392a19fb9e5e11c0341853110650e8d705f5de303c79e2cc97df721a916a25a0f7971bfeca7463b8db92e95871ab907d2b1496254b8c99aa776264146dbd7282eb98db53aa527ba580e16d3e9776941678be53eea64496967fb70a7d2167ffc6c2b51e0b948aed2e553acaabb6a4f919905d0bc84830eff90e8497e3d4acddcace1c560f0c9c2903b7c4c2dfb4ade16a3df6a8f93d92794cfe353a3d64de77a62dd22f748871ce0c9e663eb63d3d12db28b05328cef1d6d7d3230f3a46ed580c0eddfe69702d0971ad8cad852cd815c97d91c61292be9f61167520eaa191c68cbd1b24b31ab82b71446bb3aaa31f429233187227b9ea33f2f09261b4ee975a5db5ca"}, - {"0000000000000000000000000000000000000000000000000000000000000002", "006f901c59a010c72be0e2e881e81a61565d0e0a97261214ee04d3968be764e43e4e3edb9a918b596de90d214f243b243d2372e99464aa5b4ac1650bb8f65b0dc97c089c92c0af49a55436c5b3597529467e57b706dd3c39eb077549462dc11a99f13729c538ba656337178449b7d4fd10e56e5432f374379f1b47ba24fd1b9e9db876b0b8adddcee3f0e5776f2506e4592fbc4a654712805b0551a18cd8e294faae7affccf8b57b0a80f79219472ea69f3fe11d4d93bf59c37596dc1f2e028bef28e87f93c0cef646bf61918a581fd6d6ae28038f2c8ccfd6437649452fb74a8c1695ba357cc82ab20c9229bcde4ff3c1a2fe15e520e264317f32351430d1bab4e00ebf977c63ff3bde679d11f08e1da71bf659fec6b2ced3980adc5aa4e8bba73cf71cfcea14f0f7992988e005c49be188aba80bde34b097f7b1694a2bd2a79ca5dbd95c57822b67d232abec56723001401cc1cccd886f5f239982504fbcfec461b899a257384fb3a359be15613ef72becf64445cdf1dedd13069c25178c483de9b97550dbffc70e75d4d69683be1b0885b7564cfd1f245cdb268efcaa2acd653ce4a609ba48ea102342773c03b10eb470a3acc0d76f71b014c71176b548d632b01ef34acce3eb22a62ebae70f10da2f2ed05c3985572bd1f4d9a8feeecd18bb7d16207f6d6920700d759f28d3396c27f016ce2579d792083a8e4aed5b85af5cc3510c98cc19a6dc947cfc400c11d90b052ad0e7a23f85289b4b4cb1ca28161cbd0d4ec7d00f0523df792a79a738f9b99e88b4da277a1aeb3bf992b93f03d1eab1e8d84b7768ffc152d1f20e8f97d467a17691c922c1b276100b9d4bb2fbb8de2940b2fcb84afa9c899eb656ef629c46a5717eb1ec0ec600a4fc04d45d3502247643280abd9db11c88d35888ae8e635b057b0a670589233caa1a4098f4b4cf00c36fc6279609a1058aa014030e492d3555de66e70b99e89efc51df58b586c2f89f2624be7b7857990a050bfa8f6a0bcdab4ad17180a44ca6be843cbc948030236b97a1aefd47aa7ed4a3e955b98d2c7e7ebd650dd68b698dc43b3858a7e91b3d73573aa2447ec29b433ac6329766502dfcf9c8555bc9fca703701d4ff52fddf4c0c34e23c1f951f3f6d852d94a4f613e57307706b51f3521caf733c3f881434b3fa70474fcd97c0478d752b4cdc599bbb2574e00526bb324ee1cf4351fd71b312d134a998bf0632c57e8e172306279f72308763e6753103c8786e71895655b403ecc0db9c278096b22fa978a74ea8bb481cc8d66d0d8c825df06ea05b44165345bc852e47e0451cf475c159de432beec12def11f4bd5266f9e3ac20b4d1c8c3cb5e6e7ff351a0e3feccce21d4f820ed26a41694cf98c503ba59f2dc7d9b56114b0f5f954b7fca7e987775a12bde18d00d1b2c5b605a38f8e2fe11b64d4bb14c53cbf320839056d9c5f1509d2ccaad48b56d05cba2d9a5fc3ee035f94dc71ca91cc8e43d05d7bffcad92415723b3707403b40810ce625be9b138ce34cc3b61b94741c6c03e55bcf7b5b1a9eda2a420c3ef417412758fa548b07d72911790546c84202e0eb507960b16f1f78635211b077d032e35f81e97094643b7199de9ba17630f52c4dbe3277e0071d2d2f84c33273085187a538062a01523cd23a18476b9ec210f4bead92896b2b56c8a306ccd454dca44eed84d1440082213039838b1770020ad1841d6122929b170db4024036014178d1f676700c75e2a1a6474da78ecfa5a16dbe42e9cd979a12af092f754a434e0457f546c0c22c66c16db76cf4ceec245385a0c15edae5473c92ceebda0d331c325a02d00a27799a22d7f9d9e5c2b54a08c043f1a88c107d1d0b9f709f79080d7d586d92645a72a4712311ccabdd"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "005ac1e7e9ec960df137f0750ebbef144eb4ec488904723a2d7892c80cb4a622f429301ad5bda92fd58a08d3d7312be01f473d4f16a045ef0566f0759de91c2622b235d554e5a962341290fba5d6891a0c75c8bf090f4c168a696cc953d130fb16473678ce81d16a0c17ba6164ace4870b775ea1ace76beab06fce7368180f6fa53c3e0b3acacc69f37b72b718daed04bd2d9e6f9eee43a7a587e7629698d0dc702ad2b75718bc99011a473fdc8d32d9128fb54a56c3d01a5f55d8226b066e3e5a1503945660549325e8ee963e50a05f6dc7088c28a2e9eb7a2bba736219c63f4b8e25f17384f00cae7fdd741fe02b09c0ebc881de48f39e035ee60e1878ad84ca5077bf30e0164e50c8ffda294034e9814f5262f4f1e7856bb316b983c768806b7b77df74da1de495dd2f18f917243bb9aa19d09212a956bdb72a3a6aaca7ffed6e9bdbf6f45cabf04bb3113e9ad48601ba70e17a11a8f7bc5aa07494d8a56540ad3b89171baff6b4f40f43d8eb3f53d748f2770e30dfb44fff07af9f22066fc9cfff4ec2f953611ff138995ed32a4e484b17b895bcd35cb2150c074eeb9a4011d27f160404c93cef7d6eb5f0ceb178af1d1fc204015529a2392752f0482acf5fbdd29719786de15601e1f6a33e066de607fa0cf1a5a4e100e62b2f58bdf86cd33b5b52cd6f05095526f3887a15fbcd3f78f731c25c79b002fe41eb092ef3f3bbb7037238c028e19e94b3354e35188c4c3e9cff19e655891847ebad9e5735d2d3d70eda488f53c45f230171017d2fd1d482766695b856158952a6d3e0cdbf3b38f374863f541d7e86d0dc280430dd4c654a7265aafc31b7a4584a494811eb874a1c591a6a4254c76dd947b22d794ed734ce9918570f0e64dd7412608e2fe82fc0f5aef760e8a8526574f613c41cfa16342589a9d7e666b4b87ca62c2416e16c0136daab3cf6faebc08d81e1d3ca97bd536a9a21da03516f545e483108c5ba057310d3ef4a841b17e45803821dfad8121771657f75fff6d6fe95c9ce524f5516608d6d6adf3187ab74ca3f9853c12b56a99e134c0802df629407aa83a733952341e166e9747b1d12643983a6b37b3d180dee9675501f666d6d69ba198ba90c0fcb9e868746a983be62ddb443d55e01acde3e0e2084e27ff326c05ffb9b5297b09601cd93f7761ea20405562bccad0b076f4310c0ae1c8c20a7da4629b60c4378a4cbc741636556c1a21a29537185030fd4a918d457e289a6e8038533725b24ebdc05ba7850201739cba3e56d5261bd8878e88ad94adec6334bbf221e04f092ed3a482042b17986013f6f2c15bccbde228f0bf81614643181e7bfc3f2b979ed63b0d3e2195641109c964ccace0642e6b4022f12f7781939115025c3654255c75330d333d62d16d305e23a562ef159121003eb5f03c3c829eca4e650d41b5d6894b2d15489c42f2eed7d6d0fd00760ddb646db57d2b5a0d3501e12071bd3842c480400697861523abeec70cf07b92c9e1b917c0cd19522f77d9a84d731e34a95dae27921b310531ccd7acbb0bf75b112a919b7e76afccedb2bf217f5f2ce965b6ee574cc81b7652515599db95e8ba125490a04d2497fe5654394ad60f933b21c339d20a53cafee417b19adfb9a15869f2bd3548e08e9361bfb04a1a75a43299cdd82d9d14621ed1ba07993f5d94209a2cf3816579da4c86444279ae7f10923adccf24311cfdc390514d9bad9d0e33a1248e94e2e6112a80613cde4f76e89664c719c91e4c494e226af2c3d77e50e82eedf635d167d7019d59421c41dad737e78be422119b4e3e6c8d5df923714ff735aa41709c73ce1890fa9b1859806b675c3ca911a281adf944b2fea9f5d30314e5325676e6dd0ab048a4d28e91abcd89a630e"}, - {"00000000000000000000000000000000000000000000000000000000000003aa", "0046e8aa8dd6bccde4d227d290e391f698cb7f87890951bbd93689486d3658b5d7a7d43eae85857530cd0697c0777597e6ccc603345600bceeca3c88b7c5c32b0a9742fae7e9417005a70e75cfb4e5cd631205eb020a4db66dcaebab30d17114f627f9bd54612d75af05f1059238c3374aa54153a59550034e76e3b651280496f7a79793b2b1afe061bf967777728dc25f96f219388c9d27d83e7af7ecd2d709c0589bc8ab7eb0b202db4e5855c3bc6cede5913db23b96d4ca4456797f1442467d0ed665cec38363b6e6dd00e61f6c112b941434b3b20a4a596c6eabe290f460b309edc97f0050158a2e575049f27eaaa59be14ae2510b2d4a3fd83204068dc93aa45abf8c02e8dd0778957e5ae7b8f98f0f2d49ad53debc4f557d53a01c40b70ea681ddc4d332fadb9fd9536836d06f54fe1c7117a26abcdd03353aac743ea3d8f41b2ebc25946f6a70fa441edbf633007a3f47d54c778bf0a8d68c144d75d785177d29130d06ddfe488b4cf0956bd14212fd2b129af2b71b0d10550c9755918807a2f0d6d23753df95c0a16f97101fa7ee4d5d3b110ff67d155abef48db18b6ad825a707fd1b05864e84e9b7b534f417e7887579ba71149811d5e8fff825f2cf3c24536a099d561ea4a75c03e012bc7699098fe0d29e3a8682fc6530b339129db6df2ae5bfd3521e15c723ba548a4bc2e9132ae45ebc9000ff9dcb77513ab59b3330205fc59f20895dadcb9b5f3f2434296aacc9faf218eebd68456a7499df7b6a072ad3277349989994561236c4e6bc617765b95920388494e2ee8eaf034cac54c7dff92a519dcd58d4f20af6cd1e924bdc587f327c7147fbf073a80e1f63e320a164b1450bfbbf8505a2d9c9c996ad154d1733ef2a649616aedfda7dcf71152c7eab551375077cda99344a72c899dc3989f9c58411a457c299db4b94b5aa0118686bc720a599ad8c65b02dff19f3ddbedfc825353c4512130ef31bb451b47082e6e89a9c9c3835b817101c9432db0d1341e5b5ff164605727cb7ba08641c46fed9eddc6cff4ab5574deb46953a6df776f9b4063021cd417a1c49f8a9d0e3b2b7c3359d6732a1e2067a87e9fec1ccb26e2fa7d139cfd1172aff7fe85c0f4f1d550e48d917cc23b343886c5e8abc455e1eb4355a96659d22a62fd65d53912e2d9ce2a9709a65770140a318ff14cad780daf4bf1fec9b9d30a9b315fc1101bd1140f9f267f4bd83a5c9f03e7e54c9dd18423c1289f24de0411364a157752b79b966eb3f7a08405c01ab7a90a990ed9ee6d627bce2b125979b2cf2000249dc49df55d53ac9fbe025a599c7402f3c26d7b2296943d8528e3b19d84687abc4f715f2f0cedde98a2adce728bce0313b0248766339e84f89e72cf8fafb451f0f9e3197fc7bcd9696da4dc2b84a1b12595a1104dd60c943d4b059ce8430e23adfd8ea49bd52997e139026fa5e482cd953f0115d80362c3628ebf4e2cc1b09744b5687fa64419dc4bccfd33c1286f1b684b930e16de24dcefebf8121a674feeb5d6a31f936edb5058d9ada2d316e2b972982fde1f3d7ace7ab5c10aa1835de690af2d241fb9c93a0d95e40b73749fe2baf1aaa9c4c534d96f4a202c26d057ee8e35f7e7cd9a248c2c38c91a5c319fefd262083b40092cd2bdffae60521508f04c5f4b3ad85508b361427f565005b07c91653b14f7e1cb631d2e394ceaa59dc62386c1b590d110f614b7195e7cdeca73764f9ec96f34e327f6c5b338135934268410f958dc421296ff1a6284d5564f10a9eee81c81500f18e91b1d1801e633e99281e94461145646acbd80b5f634e68d60cd6fb8f2b9d9ecb9c0c0a0b803b5065fdd324f604d36a3eb23f34f260d724d106a3628ecbff474b564aced796e26d39b57777"}, - {"000000000000000000000000000000000000000000000000000000000000000b", "004119923cced1f108e0372cbf43ee2e60f3bed7bd13a6d8eac89c27e30763e301df2dedd1d073be53110cd1f9d93dc73898462ef5650cbf5bf1ce6f3e6a4d1f610e7a12244bebc286b4e01f4c1da9d8dd1857c60f6cfd343a0760838fcc423aa1c1bc791e4b0abb4f1c2cace44dd302d8b17ad569da5f7665d2c86fc89c28c21c65ad8b5915cc4ee3d2a26f75da1d48da36c66d1cfd8ddeefb40bed77795b4a5d0512ade89d28b304ede16a2e5b443948181242defcca3db866721d6b47020b66e3191200ea80768394c552c6220c5980080c3d622c4343c5dd9a6bd6110ff5b972c9663fa26915d5d2a0f1e19c8d1161246eebb1631dd18434538e09e316be4dcf9edb96a6e19549ef2c652ec9959b3d2ea46db8f34dd53b1eda4541af7a7efa4a213f726f22ba2eb94011683d8d12065663c8376297639b56e94894ab3713d3323f2692356cc2338e8615f2bd37ab0138f3a8d15a5e9731cd42bd30dc3b7ce8496c25f41098e60e3f0c5fbbf33261e33ecc1b46164473369002d4423f541c2d37e52d63b776d4f7514ba39c99bc433b2397f159b279f32717e025d4b8b68d09b9f64c01daeb48826a0cddb056423abbaa8346d86e5f152419767c31f95cda75047275ac6d4de69e18ced487040536b9ea1f072109936f12e1dbd68439de0336477a1ac125609668e04fd82a658b82de7da28b913e478d0854d115298bb28c6d5f424b497bc21d3eddac8c2f164013e301aa9629e44ad65d1f5a39fa153751a5660f6e43bc0c5170f78100e4b3b9bec6055ccf0cda831496fe149762f50938a43232191ef0d52c318eb52308c5205ea1e68dcf3806b88c7b6f1b063641f4ad170ee96b68921f60c97b2814821ee1dc2eb9d5b782711968c17854258a97aea897e2e9c595e6269378a21e2b0675873310d9bac1722381e49e0927c3fe1fb3240073f2333a4d87009e868294aed97d18cece4f9930042c6792bd1a87cb5ded35a4e3475bfe741f73c3fe191accd72188df7ec4d451e896e307e4a0c1677b821e4dfc7d0de662a5dad882dc066fa16536dd1b17e1010605ce59e61cb9ccfc51f3275336091056dce72c08482c4128a7a8633eda71eddf9d83810372487b1505634ce5f4903847c1d340f70b08472e49e85f43a4216087a5f4c908c55191949336c68b76ea8d1ee438008e9ba8dea54a95bbe0b2c92e59788cd5ceb64aef279d3e38f665cf43968c459444576181c3de5772e31ffcfbccccf4ba87b985ea6be9ecbdab78ba5ffb47292d4760865bc5f17fc934e57b4accf59b91f3ffbc02ba72bce1d93110f0a1e0a19fafccad7194ac43061f835dbdeedc82112bb112d55f227a06058cf702b3030e10465ac32cab38b35283b5f0feea73b4583b57062b3bdb160c966ac2db959569c41ce9b9666f017e050cfe3f00c9ed0f54c7063938419135df9556b72f056ed2fa90c89b5ec41f677f25c855535ca6dcd5a70834d3307b473521236bd166c328518abf5f3a095629d9f6ca05dc1df3d77fa64d31c888d5bbf8d37e3b083e6dc6adc5e11329e042058d991c35ec379f17301efb5664a5cdf78ccbc85771525690620ae61dc9a31d7cff74965594a199aee3788c3072f97c299b173925864e1bc6da49373d80f29f372af33b2f5bdfb0c90a58f9704845462b42ca03c052c07b811ed5711a4f3d2b6b7c7b6c3139f30098020243fa62223ad9fcf51809767f1c9e2699f94477d8a0c344622b26d7f9aa1a79d709cc21e8e73509151e4155b65a2b5857a2d70fc9bd52c8e73515bc99667052775c71a2fb57f9d711f1d7894e05ec9055ae51f5ef9e2080a6686ceb051e4cfe681b7c4dabfd37724b5bb9233caa171ff9683ee989fd8f50842aea35f6a7efdf15ca61ddf5652a"}, - {"0000000000000000000000000000000000000000000000000000000000000005", "0035afde4b88e0f3cd1dd4e703b3487d6380763f0332a16ccccf942641c04db473567969be7d073b631c1c9edcbbcb2225331de373414cf6f93b9b45fd09d22c94e4bea9910f59dadc049970745932c82ddae8240d6df10b2ef89441eaead62030fea4170a7699ddde3fa42a159311d805894805c1a15231b1e598580b3b0e41575b04674925e98364b9316b2205e489de876f1399e290b8cc339fe49467b50c4d23df45ec5a6c82029db50ca4cc6ce0d37c516451b9726d70090eaf6019b2a2bf9bcc873b6aeb76b5333d71be1a669a850b1379b0ea0116d174b796626ed97d39ee98bbf7fc50435755290998ddc1afd9277e1843994e4221fad12515c89f3cad9d2ead2d45345f8eec679181a9ecff73242f956c5c0d4e3d6536674df4fb80de4f7cdeb23c2f03be9cebd13bf36f0d0518f6d8191d74c0700d7d6bd23e0b637387b5f2da075a6ac0e1f2aeb87986100479234733970f2fa06655f24673caf1c9825e84e626a7c5ac418bab251f30d2902d9b1fba6b4f57ec751a1c6ff2f44a985bb23e18de56d990df03ce9f958c335403fa5993df45a9bee3eb99d23e9ac7f83ff5120a235d9f63dc1479fd0f6352ac5a31a309e61e2f6624cae95ab814961bb57b23323b5fd1bec2ba3cc44b0bf4a0e25a24a839f403b6dc2cd074da30301f81da106aafadc86fad47ce23c514f87562f181aa512b4704b3e02d2b0dd6390314626b92f84fe5d0d434859e12492ae7bcdd8c1b8037455a3d361e02982ab709020b9d7ad31d8d56bb2aa832c367d7eb9f19337e310124107a42de2122d71f5d74a0aebdb2b9909e7bac5505d6c0d4e66a54455799053fe77987b5b13bfccc86137067277b07471f6b5d32d993afd9956515cda6b506b32d54e9d56ec16056010ec59474f641c2dd893942e5a42356187f79707a590882f4e4c33aa67f7e0f00469f5b3587597b4df960bca2537872b35addc1851a4af9b3970dc963bdc101b754166f4e993114f91801516a0e885355b1e55f00f7c7db7f14e166945dff18ba34bdc15b9b4fb96da284b95277c5047fd95140013b2f5564a46aafa39df705ed748a31fc4479e28724eca5b6fa0ea3372d81c261eb9ea0b0db5aba2baf030307c9401a2a9eda1908bfed5befae53a21c51030df559e94460859be0e9c7b44e70086e4a3636e1840429286643db06af1f2e12d9fd599eedc73c9c4e655328139cc8d66fa9e9915564b0f3d2b6b1ea9da8c20aa0191a7d82b3e70d5911e0dc9d97b0bd30313fbc365d72402438e229f4f033b108b0bbe1485f14f2a90a189fdfa251c7c29bcc010c0009a30dc163ee8db836813c43b456e9ff4ddef6aadadca5cdc9611b31700acffedc7e83977ef8a7312cbdc36a94d2ab771031201d8539ba217f494abb1a65df7dfe8f15d13d570f07368cc0cf0f97930745d2ada0aff5632a6dda46c908396a1dcfc23937546140abb1bdd30045c30670c133451368932f6081c9a0d4aac16a1b8a024410e5e5410156cc855c2792fa1926002be0ae2e8c14b565a00b3b0d25f9ce0795402292a85c665e4585f20f75ae435a2be3c910d76e963a76af9167159eb321bb941f0d356dc12c912438c4ce259d9af1aaf9cbaa96d99814a38dfca7567b72eded81fbeafc0c6c8aefaaeabd07bb36896b46dc10629190bddd279ed912edd44d644023be19279065ee86fd06b7dcdbe68293481dc5810d583d8f388d800352f352f68121bed788a37cbcd412cbaed54a2334d79917f34158a090f9cdfbb4c9790af073ee42c929076919541b805bce268c71f4bebe1b63622257b2b475b8418521a775eba1a3d81f8ffc10294ef4348c9bdbc4fef2d5e167f9e9ba53f4c6b92e4ba560ba8c5075f97ef5861e52f271a9d7f45469"}, - {"0000000000000000000000000000000000000000000000000000000000000004", "0045cc55438ec569072433ac0b4a3c314bad15e9ea0bbc1daac7914ab6e487c4b90a460e016fdbbb944701c21a300c9d917daf7600c93f55ff0dd8d2b8ce3e21528deda497b17bfe7512751eac6e5920afcc6c1709c32b821c96d679a48db3c17273ad16251c3357b426405cecfaccf9678533f328ad2a6f90fe8a5ea626173a0637108c0517cd6991f5b221eb989740786d991e2793a15497744309a38388b5bfcb69cc9ef915aa024229a2f59f9103367dc777b06a928e8b551abea9118849e101d3bbb1677e7217e4e265a5e306172aa827957e826156c243bd82234d63249c556328dff7502f1f69ff90524913b4a992f5124054c61414d0b52209371555831572b1dac0b2658942b6a17331f16b1b0f1f3a6e93ea218dbf5047a2024261067c1d7c99d109b806bffb05ac79e85e41c2dbd14e3eb68c7739a21122bbb0af0b06385d9a614ec3b5404064b3bcfb0f0626a2fa0d0406d2d45dd587b6ad6f4a1039d5e509412bf7a354e14e8b55f624cbdbcacb797fab7c6a9320c7f467eb937efcc9f6a4b8d83e3faaeb8d590ea424519c02ea0aa6f8f15f94fafba840073b149fe4ee0b53d112940de10d7e81d12c758cc2e986974d429b2856e38d8866ddd997f8842b4af6c3b24946761d3e1d57a1056234c2b7ef3b339915b24b21d49db365ff249d6459e653465b52e2b2a03828c6e20116746dff06418b11dd87629c6c8fb0f69a2334d99c04db69001518c56e8807bbbca8498230e930d1f93186bbb6c0080baf83c76a34d3e59f0462fcb503a9901efad6a01dae857207cfbbe6ec4114f0c7e9e1befe5d1bab510f01c17cc08abbb1e41e5190ffc0f0d770dc3caa411c3b4b0a471ef053fbf6540e34b54b96614dfaf319174b9b81b72aa63bef1255bc2fd792ba3a5f7c82983b0753fffd54fab7248533c43a56387ec32b36e10500af84affe504a5aac050125f8e746f246d19c3510600436ac55acf3198e9e673726e95389daa4b0541c146bac2644190d82f93fd2a9ed1ddf271a2b38fcdb1e5b5c26759b39c1881b334638b753e15d50f8b41d06f4d684840e94957e64a227a9c6417d2976b5b2b92e11251f0ae568916cabc307dbd3e7ea8a67f58b470916770f400c7cf26c5f4a1319647a3ac02a1720e10caf8476dc0e53bf45d77395ea340e6e3e061ad15d08098598614aa2d8c7ffa1b942cb1bf1f435927b4b0f5eb5a5f790e97cd47c164a7fc8035ac63eda3bf60ca54f5686930932d1e0a453ad7c4dd183234e1f0316754dcbf8cf1caddbabe2b5c0a54999a54f1f24821c2004e91218a7eb168af5b28d7cfe65dc3bb4417e3559fea3f6a1d1156ba4b446093c176eac4e57757a2efe45bf904c83a0da2303a17ad0b9e340d37c4d7932b19ee1988f39f30ea50381bb6c26ceb92cddf63100e808c2f666fe87c609f6e7dbda384a2642bedd54085b46ae4cc503a4b6e9fbe1c8720797f94effcbc0051f4cba5a18ff1ba2e2008ad01dbc255f37548c9908e3a3e1bd19511106fac6542e7de6be2140b8c8290a6df3dbdc03dfe557e166070cc19c073fb1baf7010e23cbe9f4c578a3d01a51b378133655616d6cf16d159921a1bec984e2e62c615aed7cdd1b0d27fc3c3f61bde50d20a358f5cab9e98760f9e38f7ed97f90b8074d05736b43358d8f0ae355fecd12f61dd89a29b0272dd7a3f013bc4dd75493844cd7f97ec6d4fbd2b30e0686a9d89e5481fc5e03984af7952d9c6a7840c715fbed41c3768483d69b0a2cea6abe5719c4b9c6d60967ef909a632079dd6b36ecc97c0c85e596bc0fce193b5fc2658e9352e3ee5399ffbf5d0e47013ec77c1746daa6791473e3136a8195f95ae0f4c2c6eb9c101f55d586b15953c57928a60caf4abc438debbce892"}, - {"0000000000000000000000000000000000000000000000000000000000000021", "00b4902728a8a8db67b1344baf4a1541ecf8b81a13497b3d1afdef05e987b8371d61bc7e91ea3d5623da211b3cdb2c7937e1dc8ff280a14bbb2e1ab93e1ef63f42443440707e9fa9e9544cb3aa0211ad11127de20510adad4304c3d22c7896d03642b7520650dab1e440815ac4565306cd56af65fdd8c4e2398c5fcf921d092a3375fc546f490983514747c08e0d05b93cc87809b3ed5caf6f3cb9bc0150ffb77d090646df553a8a05da226fd5e3e28f255bd2c3261eeae68a59d50b890a6d0c15cd4f4210c67500f4ca5f3ceca4eeb54b1f199ef8edab49c3438d29a5882e51555d95911b505a1e7572ef79079f85386bb2aa543cd6bcce024964040e1c11e176f6bf41f06a8279d5278e653298cc5f45174369adc50e0b0923c8522c4197ab18ee88dd344619869faff6e7a3ef6ab48454e34718994dc35517483418b334a1ea80cd78fc2347f6a0ec869485d8e8cd011e4876cd487ab6abba1033b85aa2ccac03cd8bbd1b8674e18c675e69d85952d782b7475164e4b684e00546885da78b59bd3cf1c22b15593ede908e56e86506f46ef8eec72c65d028c0fcda75ff46fa77f8443a04a02602a9e72ca9ea5e169e94538cd2b28279b7a50fe890a963499df14b0f2397f3a630d5562aff50f00674ddac27f82dc3d8c393d36620273a385b5c2b760dff53fadac9b7ff651d555fb1b47f8f01939f7f4301f8a97f6aac5ddf951261176acf434ca0d67e16341bea85245eb5f345cb1ae2904a4f2954eceedd30d914e32f30c4b2e9cbd659645ac4ccef27a8111eb6da21aa258f5812cb3d94ae13fa2c2beadd675b558cef04808a72859cc96584a32964a9cf1c26803df5d53e0667d5edd244e3a3f41530c428a069b534fa337fae113c9734d30ecc8f488b1238e4c2a3b96d101b6ec95ef9a6b173d99401feee86f0dc6fdf8f3bddfbcda1018f8fd12e50dce74be42313456b8334fa0051512b22c10e554fda2429ab2df2713c2d1a624511366ec72495b94943c94f367e3e83dd3be2c5610467ef0ee228008798fa5e8d8f5b2673ec00791f82fac57e51310924ba88fc28ff13c9ef7454dcb9a3265d75f31cac1bf164e9b752d691346c3c4308f62ddb5ce07ee76e101d19500bb571d5e40bd139d25180e328f439960e5ee2330143623c8d9e15263638bc6f69c94035ca4608b0dde2ed0908aa84b290b77213355d42aa35abc01ae7299e7b4ec649b761b5f02db0c24997c75c23d22012c9e4acca4f47d8d274362c63995b2bb81967cb26b4b7bdc058c61cee0f829b7f60bf64e8fa2f4a152bdaa99004a90aa9a2e8d5dfb6ba073a269c3b8a9f46df4edc7caf04ebbca7552dbae525ffc2bd5f68cc352d1bbdf2d07bf79581337650a19a894e11d91e144397ecdd70e4be315068c43d416c323e38eff7f5f20191bd02519c0121eb6fd3027c3403b1b527b4d9622ac3ea2b21e429c3e085f57f4b340136a3bfbc196505e729cc84ad8373a63a926acf4ebf9e5a5e9edf011b6af75e98b7a11de8a19363577f034a2b05f467c4061e6db182b8cb01cd7d95f60378387e8bf37e09030f1629865f10dcf0e4fd24f3d557e129894232db240ac8be642c4bd483530351721934850a1782f74c7b6cd964442c65acedca5ab7458dd11a3ea721f96be80582d796e0440d287425317bf9478cb4a396da9c4a11f4f2f4b10590b64abae528d14267a2fd2c5fecd417c9c4a0ae5f4c91c22cd7d037e494ce972dba0400362fb5c5f662a7a78ba1252186d5b487a2dfde81ca072a52dacf8c03d4ce1f02bbc5eb6e81cf00b51b4420f20cbc2362e8a34dbc64ebd83ffb25920bfead7435a3ed98dddbb9bdafb0b37653eddd6eb65bd6e34a5dda65bba828a4eb8e542807f5661ada22497e01c9"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "000f32f3eff1e9a9cfb380d8ee306ac44bf431106c23699a165dadc6d184dcf3c54bc5bc6da1192d1b3004306658e45998cb67d5b3f82b3a4f39281bdcd6f81bdb790c5e4704189ff85278081f4850a1d6fcc91403b8677ed8084e1e90f16292d9c604d92b16ea840432e2ff8e44d3c26bec3a769e11dd94b5b8a5dbe91905d0ff96830fa8ffc78210725eddb200638e77acab0aa2339544c6fe96b020a657e5fa1671bc64926f1e0e39defb94dfa6c920ad428b4228b155855b8d9d251e6042dde91482c9a69152ac82afb39516b9e9a4261d2b7796c7aafae5cc87f6e778c8026e45b4199bab1fe07fd3e2ce325699b968a2bc4f20fe799113db890ed66ac04954a19ff8b2c18ea31d17550e475a9b2442bc0dc7dc1a920743d795e219bd38aa880317dad93d900354a9e4648b842bc81a25d7446782d55e248e42dda29a05ef12419dbe49d9e5f8ccb78ef7fca428005e79a3aca4018bf75ee0fc5a6d3e461c3f1a140012349dc5ad4f8d2ac200133c2620fd6a5e0695d57601182aa49d27997978af144a45f4333772bb3eba67113ae1f32b0cf6fee17ce133c6a2415cac2af1a22a03d16f75ae74fb53d617f22d431e82bcf84fbef73808158bc8aac8a898a249d77de8ef09ca481c5ef8441663279562ef9555ebc59a3c7a63c7736e99fd4bf617c65490f74f2492b77ec4226d281c272af33c802b0081689404512551582a03e1524ad5215a9f9c1bb4283d0b61fde8f155a2e582ec29a2016e5e7d3bd7960cb2e566298d3790c0f7e38fbf271ffe4f0e58b61223715a68a6997fa7bab2d30d7570cecd1b1db314970253d209e64e610514c54374542723c6cd789b9e3f126e5ac2ab77ecf7de6952b789ebf29a96b0b606913b76959e3c6f9d8f9bc1e5e95bba5d59ed4ed58b77497a7f8b9a1c4591ec03452a09b4fa96da1099813a006398a5a105de7d331fc14ebb2ff7f9727af5319d229fdc67271d057b7360f5f2dccbbbbb2e40de7aa604ae06cdafd07120fb50c08a8ccb51a42fec2478e50c3327a90cddd4c78b37240b0c4a2dc51110798234015b28cae7146d1b43f4095789d3a3265ed7dcc9c3486f7d14f057a9f7e2d24a1943f47452cb40da643709647a2426826c917b4701413a2a3d78dce02c538462aea6afb39bcaef22d548cfdf65d4265d11fe943a098cbcab39277761d2da41371cd9c6b679c5165cb8714a5c1d215f14bd227b08eddbe17ab75b0f7dcfa12d0fa56395d24e97add3a3ceae5b67fa604c7597813b5f39dfc05564d0fb4ef4cb637393c75c95bb77060c98fefd99498812b573d8c1ed5106a673075acb337638ccc40a2d894981aaa85335df82775f46db3d0f21e0cd3ba48db7537810973b0f7dcbd5ebf63d71b4a3c00f86032b32b5769f9debc87d9dff8281ddefb201d34ba6a991a0796ed0208c361e1f1a63d5f861b40d29cae09b9e4a2f6b9fb6fa47da12b264c354d93d06e44e5e744b004b967a047d93ade54567f3369b194790dede375a9b391d83ba4c65ef7ca29b1fb743d2056e53cac90d6d7fcbac352ecdcae66666da362b1d5f0c83165022ec355c4f480032705883237dff7775217fce56b9dd41634a47ebd96af5051bc2ca1ec45030dad36ff1e3e3955324238532b71bc144de979772033d472e25d20c5e964bd2ce2ec177420a6cd6aa313f90c316a738405bcbd6483618e9f20a0e4e78fcad0525944d3ec20a69e85fa08aed1acd9d8dc817d0d1384744d1d0e7dab599b07a264bd5518aded2b71fe404d70c6c5d6bed0fa89501dbc93c1f30be76fc42832b7d77688d0d8db3c3c4247edeea19d242db524ae9129bffd6014a15b8eb4ba1abcf446470cd824c46c81e5cda5bb70a69a31d77b200f95597ed601e0ba72a"}, - {"00000000000000000000000000000000000000000000000000000000000003d6", "01547d9556dbf38f94c2c76036fa35c277563aa87714b0bb9f2a89eb5cffd0b5d7c4dbd1ba6e3d98c0fa0e3c85fa9e8d0e155e7bb472b5a9ca8e43a9b8db304889faec5016840584df3580bbfa2d3e057b3b22a20347f399c5d00a6180b292c8b9b4eaf8f9407541c029df33f6462e218bb8acf4e88fbf71024702be3bb60ca88bebaf48673a939cc17e452c115dad937448bf26a41974cc4b3898f5bd743b6fec796b32ca5f3aeb0dcde1b7ebcfd78710d43a3b265a9aa6d7991fef692ad239a4e6e86d95e52d38e136e952668e8815d7d412d6f7a1bb93e83f4aa9e29554534dbddb0fbf22f115e1e36f06e48751e59a8313d67d94b0cd6c9b24e11497d93988cff91927f13404233d8cb2745cf4de2e511a7c209cd73f174188c83fe0e9c63e70fff6bbfb3654adede531c5239bb143e41fd6c5415297bdd3636e3a54d003b20153bdb939533fcaf16f6d3a5db7a301c2a2965fc2993cac59a19b42dc63c8f4a5ed3af7063bbb0a2ae29c0d23d6e1c45d9cd73d16b83f3b0001e1737faa20c3bb920c74eaf6e3f58a4ca35c1db22136f4cb7b0aa5a49c7734a34d70a0c56af18d526a028656e6d2d42f4d7d39f3f515d0ac4d495d50b096054c3ec74c8adec87ed2b2c20cdd56aa8f5d784e84148342979aabe26bfcb3986b6afd09a71225dc0ce11c2fa326c8161383212bd21b47aafac9a60af05a7701f8ca2b6e27f7ff91210052d7f720a0456844f1830a94bb1d9c93354eafc07242a272dfd75feb5c8d1716ab6d269c77ccfdde2079ee19efb5dea2c81d2e1316b03ee737e36463eed618fa7359e39fc80adeddad12c910b770cdd132b90f91a55ea62e236918feeb4a42ab5b9ca92bd263870cc8adf1de2cab4a19ff14012414b635b1dbe429dff8f2fbe3bf65c4e1f59671917553c7ea0670a023dbc54806ef648a8b2fef7b7cf80160f9ba3b8a584e7dabb8cd2475b9c6c490f8c0551eab1602a8de4250f3dc2555887543c68a06b60c0a2a12b60ccccfa8d5e09c2575e1ea917a5686d4b48b746b8ef0551daa3326f1cb5e4a6a38b70737dbf435097ce68b26452b5d56c931995fdd3021825153ec4c0bfc815bfae5715567a9210facf8d0bdbc267359d22695acb3439157e1c738d43e885de3d15a0c8e05b745d103e4b024190ba875857f113ce9ad72e43146cd065ac17248d86017025e56fdc7d44f4ece6b9cabb92daf25dd0e92e14d83eee4745bdd17996a448c13aa17aa5de5b9d1a0753ee664403fc5ec626de3dce15c38d6df7734d91d87a17d459b733bdabeb22cfaf96009d51ee859d42760ac4d2502a938ab06968cf536582f872ee5b9e536117036d7236cbd3609cb359949e810181d2e52532b0ba650d70f9ee4c1322c09fa427a19ba13194acaa6473cc31248821cf22ebd5f5d7f6704ae7ecc87cd8ba2e11d6224ca9580a19c3f18ea10050671895aca2bb1c88131f703ac64c88d31de9c4007ca6ae713fc5991e42a9276393a448cd3c6dc137f143ed4ed82ded4abf5a215d00e74d72610225ee8e72bc71ccf57207a2f8d01062e076995b6a1f0988e7e5887dfdd1f9806078f7c296c375953925da7dd0a4b30c4fcfc02e253c172eb887adcca02aa2fe355a7b7445d06e9f71a294fde89850ab2fba51303d99a8281095ee4bbe2576ce5c9d7b0a21aeadd25d8779a43b414fc4b5ce4d6bac558d9c1e040c796f9f0551e675832fd375a2b920d6fa67964df61f1e68a954afaec8044abd60e30d35210f8bfa48785f992e58fee3925050e566bbae5e1cca39ea48922cd72afab0c5e3eda043fc74d23691dda518812e462f8dac3a645f7dcdc071b3312174894bfb382fc63bdf7c7f9d5b371769bd01d63b614844e64f58ea50732037a892e7880d9efcb"}, - {"0000000000000000000000000000000000000000000000000000000000000022", "0004030f316defaf9df74ca4d571f86b38835d3a8f0e003d42f55a25c5f2a20ce561748f836a02fb932805c5ed5f87968f32d14f30fa97a8c84cb5dbb3945d07056576db6426f1f78cd174b0b54ea4cc3f79defc100a3c420629d717a55b9164a83e6e9467cba74d5d4c073e64031492c3686f6593dacfb48e1099b82a4f1837036f8d4eaf3bb41622a9799aba00ef6be78d3b18b8f0cce7a0692315e8e18f36e6074096549ce4c9000ead6f1c0f29438e4c818c315681b47df6f2d541088aabd003c9a5fbb20088065ad19ee35364de556630f766eac192a9a390c43478d851b793743ebc4fe831a697081a7627c7f493249e1db07825d221354e0206d8ab4de52cb291a3789124773e16057890bed07012aa8b6efbf77579d3de913961d869ba9c2f5b6b5a0e98712f48a4dd39c07623b5abffe9a9008c4aa8e30eb4fff8fcf3f611c92c9323be76bc42700015a60d0c6a6c6f3d08351269ef76785a447e8e8deb7d319d23711a88560b6760f7fe32a6e272fa21e4f132de61239c9fdf8b0e32baf920e24eab7dcea2d57c5851b52e08fca69553a7ffa0dea34ac53bd6930a76ba5a3b201accc3d9c9cb62d359543049c8ba737a43ff8782382926f6e611a7e55511263161e72a33849a7fbb1c2bd0fa6398d4b924d274c2c1f47f057d35794efd2b2f3c856b94a5f4ef495dd394886cfe1ced5db871e70da73ee9e4092ddf11d923284dfb2cf2c5dc37a8fc10bcd17be84b65b56bf974a63bd02ece81a8bb6b6d19ad07876e2dd7d57451e385ca1c9ee230567a810f1fd98dcfae4ee88eacf7126004ab777d6d19cd3d6213ee528cd1c895babc2c44d5f55270a2b785dbea9b5861778dff9a565769eef739b0ff655ebddf99a07b18935369318da2569d5352cb765b7dacc58a1a801a2e7839e6291fd7a10f93e31dc0fb0d9938592a4839011b0f3afb4b0534e51ca2416fddf3f5c890f0d06705c1d445f2776da7f28dc5cfd7c1a1addf5b3eca8a18fd2dada3da8987337fd278b82db151579eda43ee38b60ca56f0ee1c2a727f7e19dc828da67913f0cd60f03dae010ca7f075c423539d2e25b7a4114deab1b104bfd0dfee955856ff745efd0b510d6270431bed41dd6522857dc20798cdec92de84dfb4a9888ba26ae277696d9ae948ba9e46d749b91d6ccc16dceaec2dd0397ca4c96539528b5f5f612985c444297569674e819e6bbb983ca255c5ef88238aff4f54215a11a15a945d477af3d63852b622dd4aa657f9c2616b11b72b150d50fafc3286e0173d898e089637d5736b4dffa4d08af68a42b873e819161c5cf2b71093575bd175ef6211c3c95708a770b97cd1317379f028e0c3d32a9390dce999ebfcbbff9e019815930db0f9894f82870e52fde36a1e3991559f3cdf5a449bedd76633d36797a0432943863f69fdfefb2f0a3a805ef8ab3b0db81eb27f4634a8dd6187f97d1430a4ce7684cc4c8efbfeb219a738bb1a1ad57524c94419cb1d3b5f143fbb7e84d392d2ddb96a57f0095861655ea485a94241ec7100ef1be41a91a429feefd1247f75f61c697153f9b231a539948562bff157485b55f962ca4ea139aff0a1712a9cdf1ef0c5b37aacea28ecfe69ed62f5391d05313066d0ac7e6034f640c067d324d991a5040fcd34605edac20bd09ca27af68c77f6cc1a0c2c36979d0530fc62eb2c25e962944b1a428afa316a920dfdbc68e1bcbb1a38d4be191a38a12a7d1248ce4f0112cb3c46938ae654ded4a29e9ca86c58b4a423e714b5b9a76099f432143631e738579e29c5ad5ee8cab31cb6b630d2b473623ca5d008a217113ea168b6c694c252f322eca52b1c1665f87bcc394145e52ebfdf5103132ae3025e50f9d6c55b9bae2081d227099c7bb031fd331"}, - {"0000000000000000000000000000000000000000000000000000000000000006", "007c0779e65899914a5f2305887132ce6d59fd1f8d453843ae6ca8b847f3a04859657a79d3055dff8ecf1708b8cfe74ac0cea6e7f7ab8bc02b220a21bf13521fbe964eb52ae2fdede4637c13e417599da8f56e341a3882542bf269d1c662359afb6d48eaf0bdb7b03f31bc73c6c497ec497e45c3c260f68315a5f23f881a2b6596bf81e5af698123864be236244f3c7c7ff0553236edca5ee270e3c8fef886666c6f5f05a6fd193807b6c4b405f0dd6df1c190d8ed09fe961d389608d727dd54098a322e95eea025a345496a06b7a63cf0490ed6153f39076deafa13393240d117fb55fa9d04d8275b0bac9250f0659c9a046f24e4a83a74dff7b36c165b13766d91fdf5713ad7a6f54e4603b966df8bb020e00b3c11519b553c55353613e7609246327d934716e2df91a9166ca11e7e31f745dcb628e58974fa9a212f5f7eff13590ce3dc6553c749583edc4859c27d013b64419ba28325ddcf1761d4722f2e3c733c839d5a3b5bc7ffa24ed58b10c63676b3071201c7117e0732696215dedd240572b4946852684fe55a3b9a30a5336569e36579f1efd05d4557556ae49d7b3c1205c4042dac08f319e6456394817a17d128e0700f76d29511d13b4c7b5cb8dbec21657305bab5ae4720fda51a0f86ef9a74f38f1be70ba3c29d6f77c98e9194412428c8e4c2884afd3d03e71a5379f91e8ae032170ccc03d583fd231518a0d5be37caff7b694e60a79e96eb0ce0953243cf059ec95e12a47456fd6a962f79fba40841489643d3733ee64352b2caa43e5136d8d99c511d093ab292dbbf5d6065e2d80b9e6b557f73384100099488c8abd9e1c9e391d0d886bbb479bbef97393a1011011e13a234c73ef5724420d0fcd26e7e99c0800a7e2d1194ad9da7db46718ff3c056548b820b54b721c18ba54fb9cbf3f7d8f33ae31af82a450454a67d00d37174ae62eb6130da52dcae17f958e4ff2d21931d64174fdd4a66c33ac4925b473a4da907885d3dd30c11c4e32792f5c0c79713a1b4723c8917b077fa814067968919912c71e2f587963cc9529df70db356910a4ead4b34846acf14d296e9cc6bd555cb697851d614133acf2155c891e001654cbdf0d8cde63556736a1391162c5421b23527fc8275ac7369add549ffa47322c6e3cb45d9fd2da85e53942733d85627549590a701b72818f5f2723f9ee0625b3f303a5b00533dde4d1726a386538bee79c838d58ea138b045708a7830250a7de278a4b94949d677b2003ce2b8adbd14f6e1c10b7afdff7246d85453bf254ca14deef310d49c13bd02622932dcf163effe4200ec549e10e0bdfd7b303e2d1c0266fda0b9b71461b2f8ac4298b1e0d417af6c165903ae52f98b35fa038272971e69b6058896c1132278d16cff57e0758326c2c49ebf0445eb32b9542d0134615b3b27a469f93944718efe20972fd17994f5061e158d0a25f09b621e91680a280b8605df12e8e216a739d2dbe6b867790ae242597a61e0c0c8762dde2764c365570c8bc0a3fab2a82b5e4f8227e176b55d0264f666ddab9deb6d3b42caf9993b39286fbf49d409561b473e7659cbd776117ea0fa3325b31e1d629832167c7765f4b6b5ddcec89dcb5537fbdb81df44405f535304e55deb6b838566c20b37dc839ef13ea11803999dfbd4c999cb018006dfb2f256a20f3b5e062d2535d1b58d541c8eee061556ccb7bc3d8846998348184cb4805348760bb88e537240c949c8f3708ae514254547f0fb57afadc6fb9754c1f877b24e737903ac0b31c3bda8d46d6946920953ab745c7f83239d58070b7cea5f7ade5bb960bfa201243aed52cfed97b44b17a4cb2e140910a28c74d1a4a3ce0149e5fafa104730f443cdef95c336efb5754f7abb30c1c0315f97b2"}, - {"0000000000000000000000000000000000000000000000000000000000000003", "003722b77b8537f5c469d0e521551b484a0279cfc718434a3e86d3a77bb738127d77a00e45432731433614bf7ac9b3f2d2fbc36bb193fdf1fcd872eb4c404f2277ac8977d97c28eaecc361307c6b277786fd62cb0844d2069d8f5d1be32eb3235c2117355e543f95850bbee1ccea0bb485c0f33a72385a355ac208bbde970f070f95c3abf0b3785de3f90b40bd7f629b9dcc023cf362029c53c40d1931346ac55f1641810fb076960e86e7f919482b5e8f13a3e43c61606d272a7a952917812c10a51ff2f5c94e0572c6b8744d5f9254bd2f3e2f867ff69b7055e44c8521954967cb1e487914c05f455d7be7eaf1115935276620f5829a69e9f3c4a31239bf92b8ea9411d7802163d6dd8a24b68fb700f04d13e36ed4d5ef2fdd3449ba9cecd24f4d1cbe8fd61322cceb94ab1875d76891ee4c550ca2504373e32e2420cc222da96719df87d32319b68c5149897127e00586abed611ef0ff0ce90171823371d97bc656be8c1df21f729e289bbff49b45ec95c11b2da78b1e042906d8dcaa26d95cc3aa9f755d92644095e902f692a63feabfa5226afd4758fb848e84f1bec14e73ac397608815c7d288a036868bc81fd7e77881d9d8c8fe64c11395e283b1a74dbaaa40940b065b16eef53d7bdae0a663e902e6efd53c2b923213e44ba15d62ad99cbb1705c6c65fa0c09fb8ed720158681fc9530478c600077138e051121519a46cf0ad2df662bda3ef9f0b9d3ae92d19fbea5b9d823ec4f846cb54be195d54d6670bf4e7f8549eed7fdcc6554083d069ae1842350f7a1a17172e5b19b32fa556741f6a7e7aef1ec01b40f80e0eaa934f690247e90f2338c733e091d0c333b9f70fcffa1852c64e8cccb4b24e1c2342f4d5fbb842a0145de19fde995c6dea095218119c0fb212c3575eb624ac8adc1289e6bdbc7c663282c807c9edccbe354401460c0c5a22c31fbe6bb37c22e259c5e10af1cf7e0f45888fa25b76c9559952c020507c4181e995def51469a29a98091ca44a5e64e5bc3d60b7300b5dd32c1e307793e65dfe8588cb17a33a7a8fc26ce33c478906ba35f363a43c0bb394c5c9e3501e432a11fb9d580dfe316ac806a2dd1b2924d207ea761a3758d239ca0fd7ce93100fcad18b79343889ef032ad6dc984e7a2396dabce695e9b5f5b417ad03e890fb3a3f3f36e104693d1665988c577bf0c174e8486a7eb8a519b66d284255119058a733687ca6e90046e1631a1d3b223b05e4d192490c5d14c40a6494e6c8689d5714cbc2bf17a63d5c0206c452789315270671ed6b7af9bc473e0a9fd16055da3265c5c4d2dda07be40ba3c5be09ea11f5e7ca40ac73c9743ba1245e09b4927a54ff017519ce0a632a24e0fb773304b509679882a2bb3777331acc411f5b93708cf4d499259b4a09f3909b3cc7ea0328b050b9461bf12a6215f8dab129e5c4c8b1560910e1ee004d4ad22138e871da837ea47496db377f7013880776574d96bd9322a13e668dd00ccffe8c409c1dfd0d4ab6d1672cbd3e73db24cd41ad800f72061911f5a55802e846775cce085844ec6e1a3fdaf367a43b3dcc57c956024ac64bd66975d15ee345509fede13de83e3377980cfdb6834509bb5e514a005d5de8e0405605a61fad1db5ba44e4ba22f3f49ec7eafcc04a133487243dcb85f97c84617f53bc52fd5cfdec7c3a29606b8081e36005ab4e6829f662d2424c0438cc5e200a27808f908b85e907459c5e51c172893cb942103da90219d0cff6e4d046a42b4451b879605ceeaf8b13f91376601c856dd97f351fdccc84a3536b1b03e62781aa73412a4f456e1873dd357e0d3907e9572fb33de314a10f922257ec0dd5573ebe5cf9be23787f133faaaffc931405057f8f946cf7c2d9114f7f6be357"}, - {"0000000000000000000000000000000000000000000000000000000000000016", "018ec6ba92014dfd68d6d702e5d92f8612b957060628b6c1c8c21dc6d4f9206421c6e67882bbf77b1ec71f7db235daeb8403a501454718ac7d1b4064ba14bf304faa7d6e50073687615304fe783834f8767898450764e545de19a3c331ada2e6119b1a28ce85683af60b7f7ffad94345deb15451f089f652c5f3353684790cdfa9cf30d288cbf8c385fa61e6d47e5376fbe2c434b7cb21dad7f06124cd848abb7842c587cff7f0bf026a6b75558533c196f21419c3db0cb1e88a3fdccb1163a39a0548767fff16415efed8b8b93a970c35ee04b924dd46d87a6b71c3633f04226305e52713101a167c5d52a0fa2ec3ddb7746c86b8857a102850f9c205a8b58cb60deb23c33282a2e77f80411c9fb517b30c247eb508cec00d67c451bf8659d309ba962e974526fbebe7fc582fa73f08c55015fc738de47096387a32e9fb691252ce3333460b9b2c732743480a7e447a01cd41e810cb2e292f18e1897af3b975338ed3b949215bcce013d741af5c8d636c536d725e2cbb1466420d6e08d1f4ecda478b12963e96f6e67a492fd3823213497c24035e07f957fe11f613fc61de198d9651c2067e451d63c8eb39165ff09030d1630046c3d2b1561f95948f78ced4f7019ef5b272634ebdd1b3fe319807702bded3432745453266332e650e3b2245de303039cf6eae27524e8771afe3cc19c471924320de3bb1033608e0bc30d17da136229e14dd44b115e50e85ce31b704854ba97a278d86f57517ccbd42694919df20058c84492fe2a8a93ea0f76b0e5c302b8f51df485320834fc9a09c6c7378f0327c0dd85b0de1435a931e049f78d6044afe6bd4e1716205cf728cf95c924210218b81adc0edf99bdb46d4d3dae202dbc6597f679d1870bdd9740a3e45aa2bc1c0c453499942a5b5b41f1f3155b9ff60432751d1a4dc975018ddef5197e725027df477974633706f01d1e543ecdfa1b3d85e3c7b06a5bf7254d3d9491966f3fbab34f2652698337cfb067e3d3a3459e08980afd759c6eb7365de13bac7a03fd2bb4731aff64be614360d3c63796e0984787828170af98c8ca6bc73b716725ffbab80566df27d99911c768152ab507a6562c5436f267f94f25713dd0e571ce60c875926a739942be251e0c6d6d691cfd52b712462c48e4692d9c0ff650b67eb7de3df3d4a7ff70c04530304e593c331a7a8e113bbad358dce983ca5570542cc5326ee44277262b9d70f59f62f29451d666b315e4380e6ee91d1a86463c12f6a6c1199e353f7fd57a507d7722bcacdcac31a43c1586ad296c15e91040a94786581e57a1555701413a2e7f34acefa7c2e72131804b60fdad673410f138500c4dd828ab39fc1b8178365a484e8e00fb62cf2c4d4b2e87da72a7f63261a87555fe867c09d9837932ec8fe5309192d8b65a1029eadcb2b540abb865ef2aac5e3ebcdb9d259f05f169e8d3a1f54187d87c581f0666e6373bc471f41901b2b5bb2df66ddcde0c6e1e496d9ca552cb78b9ae84788dd26fbe951fbd28296cf6846e72a33de59a64c0c2d8cfe76e04227181613f56e4486e99a78ee84da2b5e735bc40c145d33e324b76f628359e8e5fec02e123410bc258af427bf2184797bcb71ad8a8852bc5512bf3481384aa648f884e67ea9c1198b844b3d80830526244a544e52a690972324f827e1324a84bfaa2c422cee4315612215327a5bfbc17b79f33dbf1b42150ab782627f04a1543acd75b000eb40258cb3373ebf23288e5504efde17892814e2dcdff8f98265160a7422e74fd8a81a0f0daa8d677c63cd53525870db92fc4fd1b5311c1eab2dd21f46970dc8f3a5cf48aea80a2de535a32faf987594080a3b8cedb1df985a3f0e1c6ae7354e789d8b272cc2d76b313fe0c32d921a121d"}, - {"0000000000000000000000000000000000000000000000000000000000000020", "00830f6275c3027f210387bd9a4ed45a46257cf51a3dac95cc53641a75db5aa511bb38374e2ea699581f1723f93ddfbd62cff22d722ef2960ae65bd95c928022906b5fdf6469117aa97283651da1855e57972fed03333fcd0a2446c9821aa50f59e2428f4ae49bf8230691f2fb16ca48c7f9e44294cef8e5860a5b1e82e204da5680932d6f6ddc1c01809d95eb38e145d7fb771bdd7e877fa3281f41b3858911ecf1debc2599533c06f2793cb29bd029ca0a217416531fce78813b679c0eedd685cfca0579d1a8b4d2a1345fb652b67cb2cb0b5cfaa1398b54dc6cefa269a29534f6f1449984991af8635adf489d35a5aed8864762ea0ab057d7747407434e2b9c5a084dc0d3d1167bcc0199620b6e273f0f236516d5fa3bcbd7f466517a3a03fa0ef3def9c1134a21b56baf43a3e4ad83e41dceb08a0956d8030829bbf7964fb48855d45754c869ddb1ad32d23e2a18015c11f4d903cdf131df70e86f0e9b7306e1196ae201b01d76642af6797f31c078ba6ecea9c6545c02d401d2e5193b4b275124982252ce6fc6fd4c4b9ca74e3a01bf5cfdda084baf94a59753dfaf3236237abe4809c630ee6aa6287f9422911a162b82ca5bcabc2cf62ed31fe06f5aa37705664a3f1b63e246b63b7e84171630bc4fde0ba87a76df7608147a42829bfb9a92a21efb64494a1ccd672980aac73a7f727b250c3f7c5c05b50b99ceb3e313d03702f9fc9e0f6a184e10d096133f1a847839bd1fdaa1763fe479ff6374569f907c2b4126cea5e219ab452f13803f40a5ad2ec8d481923c982288a2e03f816a24d51d9430e06a35817240a50c0b0da11851bc53f74bc6eb35d8d739c7ea3ce7f10c43fa0723a142cfb85563db9a5842e959c1b9910712838999915ebe057a89034d02723cb65919d8da4f20477fb16390472b12cca3eecfded97fe6859f87a200bd26471fa1b78fec2e105a684965c9c5a0d071ee39fb5bab75508929c9f7e4b26c3cc931e7f49cb323135e90cdc5d52bf8d0b274c1f37c0af9da14fe6bbcab8075a0296b3dd9fd40bb61cdfe397f1a299aae15030fc20f3ba853779076e2143e592ad3c730fea0c43224cdca1fdff475858fc6d8997daf2dcfd1f6b6f02af4e4d719b01bcbffc284ba4a52e94abbc4f790782db0ef4b4a6972e5aad833d0012bdf4d1e0b8d7b0904a5b57b9f4c833c78026288f2c1760617355ebc993c4cfa7ca03312afbf3b95ccf87f6f2989a0cf9ec824de04738092fe6954cee2896adfefe1ad80ef326a39f595622a4f5c63f21c67f0a7f8502a277d7b96490cd304e794d8fb539308110431178f16ab0578bf7d157b01f93a2b89f1ec6943a2c7af4fa525a45588e312b126bde465cae77315b399a87b35292f433260b1352ecd29ff99329acdd854a20d4c10dac08bffd4ab00c85a016090129566d9c27a3623bb1aafec189cf71519c934da0f98928b66e49cb43fefe665b0d7128d0e689293f0cab85a5c7714ff184737176f911bbdc0184d7ef5650db672fccf435ebb53fb51e3e3546d52011fa43fc3ebc923fcd412deeb32f8a93aa8ef052125ec39f56456e449b5844520463e1715548818f05315b1559d7321ceef55bc52e09f999149c36b0ea4e72763b3f1078fe283f518f4576561849726087ff5980a07870512693dff75ddb2b3dfadaa95a9940e6dac1584cf717bdd8653e53f44a117dcbbc94de8d765630d610c0a7e1c490940163135116aa53d5c6caee5424c8985b6b2963a073e3c9524d3484bb6ba5bdbd7f6112f959b876c6d0def13566d3069a64a23685722781246be504d04c045dbd5c236cff366fcbcad29268f137a7c457754bfe2eb10f30d816f315b05cd3bfbfa3830050ab46481416eb4e738195d45e266e43ee698"}, - {"00000000000000000000000000000000000000000000000000000000000003bf", "004f47f15f8a883b31d12097f23d3d2d0c3717979248266c9ef992ee4ec685f992abe88cc6ecfe97eaf404e2d89968212109dbee22a71099b30a8d0a7c2906384a43ed4bbd41b9f75924d8ab38060da092d3e83205cb07218d6f75ffd7b238e1275fe1e6de757ba59c137c548866898a7f081f614f47970541a675d4f5d7062393f8a1cdf98ca4d44168a690f951652914e044128c99b90288eef5da43b302f9651a8af198babe510641e63c2b30f2099a6911f8e6104f55fecf70d96c440fad23dc2a582fc455f7ad90c467a2c5fc97fb172a00a98f410ac29da7a744a6d375ac2988fb6d550046f5f53b90d3fa3b3aa386b7ebd8e372f1dcbf335907103a7384d775dbaa2963b1a172dce181da5d78ad38584f2860ecefa5e8c993c39f290809ffdc906584152a793303735e65db65e169cb2c8354af8496029854a19d359f72bc6dcbda55ffbeeb5509d220393a78013bcdd194d878397fef48b51468acb34a369ce4b70a46bbee434413151ebac7711ac576b644ff97568301930043360560913799223d18f90109ca2bb80fc5208b291c9389451d0cbc944b785d5595c598fbc2cc119ae6086e8d460b7433837660f15c2552505ca02e12b207bb0fd19fddab1156a37365f8bdb2ba563d061bb1a6facba58e7b673de25bfc2d5b7dbede5eb418524c0bb8051e2323c5c2999920dfa04b41cb7e78f201b9bf88a0d7a9e17384d31ed7e7c141e8e9b62f291525a6c7a849ae9c7844238661bd1436c2bb3f23df0bbc4dd14c4c1ae3846f838c58276dcce995147b7830320feeca95936bfbeaa3bc4eef8f90fc5fd4693a0cd8792ea6940b4993f0955ca5cc38d38a55be54e015b56161f7b99883defc7b10f4f8305f8010bf61091e23671ef427107d567ba6813251cab26053d81e194d5b7344f29e679f0bf5d58c9c50f23e01ac94e745072186f8d5c2be7136d49459f64bc031aec0b3d2e60e2ef48152d117e9c173c7b61a76967a1594d74b621c5107f1b50e8623070002b06258d2c2ae571f83d548371fe02ed806a39783851b244af352d40b7c08a5245dc2f5ee4aba0918d025406f35dc8a5c7717ec55305ff4aa4d1b43d4e4503571294768ad8906af41b625329d86395f947d6546a40245e7ee56259ff9f94a6b2766d6b2f224e5e978895da24b29032dfe1d2901093f1b6faee481a5687cd0c4e21133055514cf876b0c34595fe81ada4f19d6870323e0742b0c0158b2f40f4ad586f2a28a478caac17a4ee97212ea2e3c756b2ba9c3d41ad8d1d5078d489a36c7e57231a63eea650b74a65a6e46ab60a95ca1cc047a3b9077fd7d1e850c06db155b96a68ffd9e817edc6b5fd10053d26af033ddeafe2dabf5d38b4633404c1cfc6a18013576f75a6cdbf9aa9a02718d478766d2c7f531e5a6b6db8008111be60e486de2ac91f47ecce4c4ea36bffefda83113e990e5220b2d2d3a05d409dfed2e90e479669c0927f2274f99d358d0c973df4e3d7531073c39ebb1303cdb28ae578d7d4a8e641fe2b100fef83b3c52cb172ca39abaa875a173544513dac8898aaf7a394b742606f6bf6290ca29d7c6242f14df2cda44d1b4da401d3531ba5f9072b2ea6ae9ba28e87a52e2d95db82d29e214b98c10a8aabf1ce53f1e49d7fa2b23f3a5630a66f963b74812b91a92524ec5f891f8ede4e9ad7a2cfa9d5f44f2abd7beea44047a340d429a29f5ed7a231f5c50dd9a6344fe78629001fb0a8dab7855b783585b1517ae97791d9d20e6376a487eca1e5bf2b27a0e37e967dea3c631866a539959294be9e8d81a5a5d410f943f33a56b3dea8964413f2e4d8e87d31be62c3fedd3acf56c0109863f57b4bedd09fe7d4afabc1645d5fc241a5891131e3a6a245452281fa984be4b17"}, - {"000000000000000000000000000000000000000000000000000000000000001f", "0031f9e6e8645e35b05014daeaf5ae630e121eaf6a01029d772831524df94858acc070f4568fee3c286411a24c5403c933ab239b12c4174fec6f134759ede43cb5f3b91cd54bf3c3052484c145dda5214d3d3c7d06a85b188caad0e79a7462bd8bd6c553701a9e33ce2904c1fc8ba89a1dcd69d6f67a7991b7c9effeaf1a150db95625a793cf6a5e4579e7dc31927d26ff2ce62823e3934b54bd70b11ef3985b2e260d1a67708eb3041e3d667f2159db0e15a2206fdf23154da99848fb096cbcb40e876c6d795e8217c3a01014fba5dddf7a0b2f7e9d2490b912fae6734552524b3dcaf0baa8ef0e4aeab9ee134ef31ea6b1e09962fec983416e1f2e05daf1e915a44791a854e61c58db84ba9e83da727a2f519c72722123974b82081f47e43aeaddda1e26f90e35171052dcdf913301a7909dfdf236b050986fbe24d78c350b904c28f7eee297384a7721a00553a14603e835c97b8192c0d87f613365aa178499928a1f101712570e4f8850ba60e5f781a53cd13e4c82194acc15b4fa52dcdb85a7dd67f3654ac72aca0dff1f42c41af3f9204f5545d551fa763682b8f3d5ee5d0fa85d0be048e04311fddfd18406004dea1c45c0bff886c9141a4eac9b120e43316765e6dfcd97b9bcc79cf1ed116b81de248d4013a06b227daab703b90e091dc1a1173b657e46a4d70bdb7972daea582fe4d0c433a595067769d385e378a3c64df0e7240d675e0221b0939b0fcf50c0ef9e1db7111c025e90ddb70cabe38b4ec71303a324a35edd81bb99b6709fdea69d9c73d5249d3fc744106f1f835d902317eebbc244721f94feca3113948fbe91a6ebd7be0fa360101efec73dd0fecdc73527aba73258e6076e44674c93d9b4f64754b75a3230cb5e4260611f976d13b45bedf1bc3531b5eb43674b62ea6bd6a7d85b59db066fc959a6d60b221bcd1b00ed31fc0c0798369a7fe147bc513f8131e57410dc01741edc91a9638b6035404c5137b7df7f4bde1340301a69f7fb62cb05271b56b350433b8310197d331262b9634ac06498f1cecdf80f344b8a87216a5b30300a0ef8e95a5203b8b895f5e01f366d55d1555287b939f66502ea66ec0b4dc2f8aba1fc8a7afeb03bbea10f750344b60d11ad57cfa30b2c3fded95bf378cdfa20df23f7875fb119c203c39aca435c29cc611bba7b026279a91496c9d2e783c1d417320fd4f8a907fd1948175d643b2ac54ff8bac4bf037a9d773054bf18a00e75cf8d168e425d2a16a1a435d15b2153efacbc2f2809c7ef5b4b53212c1053c79cc390f92a1bdc4f5107c72fb471143167fa980143772fd446d96e7bfd290f36bba4a70e8891d8f4c8b0826a3f5ba4e19d389a1d4776a0f32e753fd3d7a40c3abef9a5f40cd038dd5eac3c7ad872b669a4ef869d4c7e1eb634d5929d680203991f58a20f5dd70dd5d79f35cf35d6762f0eaa0b704d85ed6a40598985550bab7b5325e0437822be094caf8a60c3ff6d3b8451c1ffaecfacca92f7b3ff4d5463f5e32e7b41a38ff8f5cb7ec73253691e619003c5b6177c0c195fce18c37989513fe18400f00aeb1339d9639277575fc6a243906f71aad5adb91c29380480d1532588b999722de0bedbcdcec89651f796364a7ad56cff71d6e79e0857155bc5e0535b7dbcd11b04739981159dab2bec07b2f967de57735e3f9b8ee710c36544af8fa84e7f5c428516dbd3b934d629ffdc0daa17de278e8953ffcc93828aa9725503d7f1d1031edfea2bf20d5990ef4f48e356fe3902a9f3d7f8e21903eab38a4e19f4b151727528bc1e750363f6f3f5241fea13028fd6d910c3235933eeef59129cf3fedd2feccfc3a8ee94b9ae2fa7fa44569de21d50516e5837c4ef18f1e1fe8b5171b7a6a1d431ff110c9dca0d"}, - {"0000000000000000000000000000000000000000000000000000000000000006", "0053769b0f2ab8cf56de834c6e21de00dbac896b3b3b94f4b16d945f61e609953053aa7796acff7ff73100ed25744a11099e9f0d822052124f849650b7a6f90a976d1c59ab4a9bc0e8e119a7c46695fa32b113d910442a6644d3bc1570f7d6205e3484ae5fc5ff0ea91cdd85e584d2daeafe58e51722af3e1d4b2a9296ad22836921a219ba70db5174af187705baab1af944e02512dce59bd0549c860a77fe3f5c335b027b38aec70e9a888c3a8d8127571b9165c53448f502cd2a8e411d5cf1d935e4b9eb7349868b85fd859a2ba47f9beb5a6142e119a8f081756d3a13d251b5cef895fbd426700eabab991f310ba3bff72749471d22fb539a003d27c6817ba8d699fbac2ea3b5c344e2c50c782f662637aa252e1e5662a2e67e15f5dd6d4395b5d4bdca953366f550e820f311b2093d0db1f299675a7c9bcb013a7cffe25bb1031be800065961f354d5972a34e87b024b9d504ef7f841ea945361fba51b510be6f25d743a48cd280e23521d3c52a4030053a093141b9a4a010f8cb49ca658a222de2744f5a0d0791e11d251c21310d4f8d790d14929e6668144b3450be8a0bcac25f8047184ff42951e27be4c963f63d4d1cda83d989d2311fdcab09786b8197e0301b82ec9b7f5c34e531c4d04e70b0658a21e27dd1f828fd741744cd10bc7bb2f0d1c69e14e6160df0f35d27951b912e2f0863e36bc038b176e36e900e3cbb941021a6df9e4a3f48d636926441610a6c9cb490a16e3726ddaa8467e9f3cba5016af8653146a320dec98f49b7d26519aaccd55e5ff19ef9aa7589ccb616f490265eb195cad00d5123199190755a7e5c7ffb108d0e5fbbb3a813e0f1096cbe727e9660b718a19f9876db43ab2b6999531a017593b363bb7495e58b9a5c96de4bf7ab7d92d48d213ca2358d864e23fa19661b9a8984584c6c7264ed2ba57b8005c7acf5c9d2c710889ba554ad75172f9caf9bbc77380a59d1c641e8dcda8c73b2c46ddbab4b057bc551e1022b9088a6dcf58b9b235eced236533ac4d9ffc5af8d489662c22efa681a9a0f769a7b28a387cb55800b23b76ba910e47f431631e4bad14bcfd991590c01bf4327a7ba46e19d6996519bbaad5e587cacc80fe0fe9cb00e4888caf19023619dc62003a38f9bd8a2b1d195d34df8abe0dd317e45aa8da568d97ec951873011cf9c9c449bf4994111589c67d8dea92b5954be21c4d7ea662a0e025cc8b257de573f6617d227f340c023fa510359ec8df312d60e2b4a56e80bddb50617b06dfe491c28a57933ff36316cca0443edccff81d7f056ea897f293714b5d43f39da5d3b2610aca4939b512f3c2ec83c6177ea26a8440a133657e4cef5c3b351439846c526b01c9a7a1f1c4eb60909d28773397e942d692c117258bebd11a95b2a5d63ac7a4c95d565d038e593990514e28c7a8d0a1912cd639f7a4fac19b3ef3c45e18a7e3ed733483f974d56c3e5e5bd69b0c082189d34d142ac3785dc562f03f5aa565f20fb4e91bc5f6143f07c2e47f0f826b5fb8f53344153d29ec0461506efb8f086b6d6230f2349723ca59aa9ab1f8246d24dfb81089153973c753774a541e299fb4e0cc0b13abc6b69bd6fd04b8e890d2f14bc28b33d9f8de37894c36f7dca4caf5bec7acd46e0d8a88855ec3ea0842491d6e0c67a4f20141964872d2a0d462af533a0dd75bf1499c1c955161e259966b8a27531dfb42350b988581110466bf230c71a17362893cf385540221105a6462d74d501b84ec5203b96afe9afc02bcbf090b3451d38108f7c0e5375441e22d114598bad9a71423476ba5634c7f79387db3660d2ce4ad96243ab78e110ae5b95351b3533e4d9705b77dd24b577edec5141d4075b1d8d702d32761663f383709fb137e5f50f1"}, - {"000000000000000000000000000000000000000000000000000000000000001e", "0049495267c57b1546cea029f70e2fc48e49908f3a01843e2f0796e8e0d472157fbec9a90247333e22a108fd27d70b619297cc915527a4c635967502ff0712254c46e44199cb235e76e604693a04aa7b4bd4ebb20e7faabb070ee4d6e7a33559873b1801b73b7312ad18504f22f763e9afb61db1ea05cf3024ec81cb42f223fdbe8cc8da8b611cca43516efb968ce3a132782e36dbc7396f6278ed4f8816923853a151c6f01cd88700bcc256a2868670bfe860ffb6d52261405d9401f44c1535b479177af1c636568611de408a556b5fcaf00aafd3c5e005fb3de8203721f1c4db7f327d1b304d3c7d0cf862b3ec3dc89a19794d6b62927a97d9c83d02a08ee56846d7c437dde05c92aa4e81a59fdd97e324ac0db35476e9b5b79565f5257dd84f4f237e31c40b6b1a234008934f43f8a24ee16e8bd65fde97c6c5337a4e2b421a223de5b3a618c26c621f62033fc4ab010eb966eda13b75ef31823fc4d70148ba911cb6744d34bba0659e26394a387643375e60422a0ad4de3d136769c12f05c69d5675741b1c20f1e95f4eb9533745fcb71047b821a9ed87a4ea3a3cd973c5865e4c4c0d8615f645ea9805e64813c900a771dd120cecc4f01089f8cd3f260ec5a5d4615c44ab47210d7d4c0d4410bddf6c3108e38f9662e4a92df3d9a66ff279f0c426d902c9d124dded451e235ae8b4e9e27371d76d92050b377caaa65209d27a13f68d2f314df8a2599d3e15756178750975acd5eaf4f36eeee8d9ea931305bc274a241189ef8635b4c6fabcdeeed55af641dda4433d4c8b78e2a9e77f5e3aa802ccc1e9c695573a996c098b4be66d242c633b20710ab5a9a38ddf3fd6151f2852b402bc0fecbcff6c930f71ebd073061ed83ef60c3a22c24b4ffd38d985163777dbc9da97627e17eb52ac642cecb13fdfcad2b7decc78ce9e1e9df511ed0279397c20299163524ef703036852d7540d3fec0e06d6499934dbe831d998f3ad9ae97b4210f7ba705618df8fe1fcd0470d239dc1dfd25d64b5d54cd5669c31b8cf77af56c3a99439774a137186a762491e48b104c9e7f692c310c51f03307ab11cea4dfe817967f207757d67c20771bc469862d3d96de570f9cd2b4abb19d6640ab4d71f8fc8ebb3364976ce2a281fb2fcf574d703ea02a26239354ed9e092ebc9170da098ef460416d4bc504fcad4ce8f76c0936d93be273333d5eb0896248c98b36d99df3e71c6c896db227a2b9a2add1657d913f120d285e493e7cc9045bbb21264117a21695baf6b08616f8767e86907af59421eae08dedeb30c3f5f48ba4bf9c8f36370c5057166783838b1c8990cca43dd621c8d073aa8b42430c441ce87fe7838a31e92b2f9f7288c917ce80dfd997d030bb9e79f03e42f0cc3bd9c55bf057356d50cd753c9cd73be9ee6060409b0f76f2d1d85b7e2d1ddb2100dfda9217476140d4c5e14fcdd67cdb85313dc0cc6e173431c3c2fea1f9b4bcad8c9a36b29878387a2ad17125ec33a2a5123478454f98bdd89a273a58d3364a23a2b8a1d0f2504aa042d2bd06eddf42a04e39f69013d42fb5f8d2b1718f2065f202b07cf12c1b69f584f618f5cb93cc20ccf036013d1f77d95dd0257a23e14ea7e80f8b9a71d3e7f2752530cb4eeff22ba4b4132a5673db25cbe045eec6b69418aa1c037a114fc18f4d9db99f093c209d1b10bf8082e44772b37522176e4d60f2d1abb8415da35947c8bcda53a28d35d4741807b28f65f251e59c42faba1b39be1c81e273ccd42e87f6e1fbf935a05dab6b10094b1caa654a30e7fb895bcea386af68b12bb7e7d4bdabf64fd8d163fc4e78ef5f7c2df555808498d78c9e5bb59f9ec6a344ee8dc0fcd73bfdc632227b29f6b63d7515d0e126c1b9c8699ab7494834d"}, - {"0000000000000000000000000000000000000000000000000000000000000029", "00346c46f773deb7cb31a1fcb128fa86577ffe731225dc3ee84ae1e513fbf905d6d3381f42de6cffc355104e1d19fb5d98c934ef3310b57568973aeb9d3e6e2ec80b35b0e04a47f7d3c5b384d0c609ce94f37ac3080ca5b653924d3ca2ff31c5bd377ab4ef8fbdd18d14c3a9aa47f9d367d6c3891cd06676bfb6339ff2dd125293338790bb39314f69cd39d0043eec4a19cf854058bc3978db881d9cf976d0b877bf4a0d28d67ccf00752de3964194ba3daa66287d5435a1d12b90c4cb00fbbe0be902666fe08a051c3759089d70fd56fd01244b475e76a3c67fdf5c74041c65417d336b32442d2732448b4e5f055362e4766744b628d1c89d8e52ed01847433f7827e32c7c4e059c28e6364283aba6e990f97bd9da5116cd3d728017a8f7d7f74fc10948078118d27729d6583bf49f4048f1cf894c1ca90b657a22f85bdb96427ced9a926a40b0e3604167e13d9f2500198f9ba43d7e2890ac4d47b2b27dccf9a737dcaed21e851c88ad765d9f2a3a5218be71b0d623a4bd7930a294afbb6323b01986f332b746535d1ecf6959252107019ab428a82673ede33c7dfbdaf7dbf605909c0022f7e3ac3573c477d27e7a95674d262aaa2d79e8c0be7a5ea6a031a3443dcf1139bb19b80579019e4a5047b85b1a38e862e96fc21502925bac11fae51479c45bfefa7c89c2c617b5294c8cfe6b53582b0d4e9c0019dcacde633be57b154612caa14c7544ff8dfcdd808cd587d26cccb3f994f53c580f497559bddd9ecdd07d88c46af03e10a5ba7d141f78b0dae5a62b4d0bd1bff020a7493e94925f451d6029c2f2515fdda6aec06538c61f7c42c07f8bb90f0e2e69a9ad966170d42077e8cfe7b61ed89232312825dc08ea776c93c6a920bfcd5ef3be76709773140dd1254b2e0968b8f2bae303da4e147176a37e13c03fdbee2c07d6aa2114b4102054346f3d2843fdf1a37380d4b3ed20743d2e7a73a3f8d44d7f0bd099ddfa659c25f27130a903ee7170afd2aad1f1d4c5943d191960ae52a397da58c8d323923ecf7408ffd43bb5d29c0d777035ee9c85874350b3114c30551e1fbf48cf64448fa333ee74b1b2de3198364636d0940b9723312036d3bcfb65482b8eff012612eafbe84ca4d18ef019b096ba31b27cbdc56a049cc1afead9edcdbaaf85567d7f63a2d9336bb5bb1044dd65b270a09931dcc1077229bfccc963a06970f101b58d5c90a07fe78dbf6f833f4ae5a879377c45926af1cfa451885adeb43132bc4715cd975953bce394bdbd55523da50c9a9c4057c29d848269aacdc926f05016b2d51b771bdf75f518cae231614d97e1e443413ee435b7d9b8521039194b28137f2360738dc6f430a3dc3ef13d3fb5f0441a40a5f7d10811043aea7a5231d35bafde571f186b8f6ff60622342ee8d3f9c9304ddd0855b661413bacc03dbcffd45b143cebdb5ff1e2947f7860c75bdc50b033187e9b444d3441c0a6010a08f5ddf17b417edaf115db20e306505f28edddc56276dac60b4f5d1aa0606a2c7b7b866ccb89c1e71057c97c798720b4dd42126e325f4aea717c899b74705f4103127c9c1f5eeb4921d3db230fb4672bf493a295cda244d9df485f04935267648dba1d10a552c8f324c11e1c2e36959a99997b4c9d4d9462a2fd6991f06cec44cb961b1e97601e534e7e8b7bee52e791d831d6a6660f89817df52c4c2b4fe4c9f0d5f93ba573009b86505ccd809cff0e3950df9f7ca5ed37a5d91ce1a9ecbdc1f1c5d8ae91034b70c31535718bd9ea4fd09c7aac4bc55e9ecf0a20220804cba3ad7183bf52b0fc95fd0f90df0b9ff9a6192961e7261320991174d10ab099c635406936570428cb498131dab2a5c41d61e4d8684a454c3d5135ad24560454bd9dd3b1a9b1c"}, - {"000000000000000000000000000000000000000000000000000000000000000e", "0043c00c93738ce1e4352b017bdcae3f75a1bccd1c08902516d4101534b5c350e2a64a98d28d59d6d1110221c59d260516a738a5b62aeb43c38e2d73f948290dd4265e6975c123f7c62982d77c6d7f45f71d77690e71e8dad90a02316a314318c2195b1925ad7708be50d5ee04c39b8bfb7c2305719af1877df90f3282066af655aeafa5e93b941c97f35f484be624b0f8b2197bc464202c72fc5dfe356927afd57bee7684b7488003fe09134e5e33adebc5b3f043ef93e9e0d9bb2e3a14eb8ff47f4dd2b89b80c6148c60853a85321c8b2509fe155edaae1497de84c166d243d6b55d78944aba205543425157f28ff3ba135b6ce4dc9ae08b1badd40f0f23393e21e9475182934d9b4ae1e5b87718f93b376e7d95ef5556234956d4e82e6e9079778cd8404c19af44de7d49eb90b3bc443f28e07e1ec5f49eaaa13bed563262d6c08dd3f3447c51e5b785b56f8fd50c02cb16bd06da18993593338701c4f72d4df7d7132109e0147f218da7f33dbdb77340d02b1a4c2c3d793b087dc4c6c6cf3b6742f43098cfdac2994ea4dd77d456484775ab95f67ebdcd85ed4bfd29099a1cbdf4bb0aa9c602ec4f7037696a34bb08458299d97b93c53a0d1f89baf1da77950083e3c7edb394e54bc1d9e9fc34e78b60759fee4575be27cbdb72cd26222759d8c04c240bf9b76ccf4d9170d707594d6851cff89cff0205f21e76034994a335c3216187493dfe7f953b26e051b1263b4bba34abda7d15ab447cdb1b4d665a71c608c6c49fff84a2a87f4350dfb5450dcc89ddc8b1585757af4c7ae619e792669761343fde4de49a9236e70f66aa2dfae48a779385744d5f30939ab3dcff5a6f12514a24e607210edaf044226665352271e138b56347c8ae317d92d6558934c77466f4645634cdf1e9b549e0d5e6715a96b3fe00d60aa87e5302688cd71df400ae4c7748845a57d3d6c2038e389fe50e6e3893e62785ee5327db8cf37c1fd43bc135bd55d63fd704170148c95b21b46509fc5ff37f834e391de60fbe4c840da7368f20c5e41dd3fb72ee525b13bd42cd3f722502b660f71a399de1d2a2d11b700be708bf4bf20ba911dcbf6e9a4a01d3ff4321ce21f0948a4bfc5e2253068b65f3705289c7835f344be0338df9b3939ff7df31e3b5c2269be23fb77b349f61d2e1a326de7f1a12025a004862939d5383c4d4883753acbe0b2ff535dc1bf7c19f39e3582fb1ad03ad5ee3462df6b8bf9470171355f69535a6e7f33e9532dffc0839c41db9bb25226e2f8a2c22ba175e4d590efee2b406531b3439a80d45879124623991197bf14dbc7ead1ea854194b2c203ce620bb5ba161a627426d2a1a304afb8bf994c513d6aa22e959ef50e58ae30544c5ec260b4f5ab874302786ad7e5da58763058782637d026de7c137a7a603487fc94a6028cf56235344c5daafb9fd801cf9292bc7251f83a7ea05ec5c7964147c39d3b87f7e4f44067bd9bbe274166fbe2803792be9537629ccde0bf01524ca3427900550f876f2bf9b2b48e95573fbcd0803777f18bda516a3cd38e368f8b41b41c18e1d021c04571ffc1a3460f9ad1452a34675c9e56f0977459b183ac4f218861969692763c0b8c48a1931c31610bc3cd58f9120ef1d3bb4af7511c7b55265e38cb62f0e084f992b176fa29be07e6578f165596efbbefb7b7743725cd533ddb54ef5db649f49ad107dca5f9eea510ed65ac6b48745b151fb3427b9ce6edd3ad31291f33eef9279799b02b99ec954711aeb22a6526ff8f2c80b697b8326d92d6b2c3ca35e6af6539972e51e4a9a42a79c57b0d5619bfb398705955951e612aebdc7a50d5bbefffdc85e96608c92700b32e03751e5fb937a38cb7484e41432210c04f41ef4cf44d9a52d962528"}, - {"000000000000000000000000000000000000000000000000000000000000035b", "003d7a484b0c9c1872b2a16fe1476995f749b182520262e83fc45ecbb7642f678e4eef29fb90abfdd14117990f170c084ba0de053323ed733b79d1151f52a524bc9edb53d06f81833562e4d5f93a4a83c0785c541047d2219c17c767db219328409bed873e693af1f4310d4e236216aadf7c8d9b38afda10e6d5939e1d644cd1feda485d8b1529e95544c3d3b4f5f33ab153535bb04cf6281b3b5533ab67382b7cff5a5c69b8b4fa0bd97e35d50b92656d20a50ad03be5776263fed1b1248bf6e2a74b7adc6030a9e4bd63866e8942fc38cb0f91bdbc2c880002e98601752e3aac459e8ded4ba019395b9e034ff0df4dce62592974d1c5dafc51560a1504870964d1655d09df36554af4e3869c9257827725b2acd7ae0b82edc7ac669189418219a725fcc6b12209ca1ee6b6079bc382e894f9eaa06f382cbb20f624e66ccec2b15627a80833f9ec7edce361ce3f617b00637b7da3d468abac4eb4c7e755a4f15a8131bc573cda0a36d52b299dd50f840a17f52c2ec874b6d12101365e514cafad29f261a40a553e3e318254721fc91cc8469005584e2729c0b2e052eacbed4135383952021196e76cc82def307452bbcdc386a6466275144726bbd4d52266b497c0aa67def97224166db716e5b90321f491519d42034cfc32b4df53d25cc61739069d299f05193890910cb7e302ddcfcd10f9cccb1891d7034ce4223e5bb1b108a6e1cc4f61802c961eaa49530d39ea3e4ca9bfc5e1cae3b183a1bf25113b372e9b381eecf71355b84151b1548e1a265115f4de3b03b938a2bb483354eee32073f5565ae6024555f7f999190da3d358fd1c559b8b23c18a8a981d4f94ef1f5941195aa331d9cca467611272f8812abc2f1b505a43800eef6c128fcb63569ca1b3123caba429742d8ede44135b7343059623af2c9911be1234771ca7ce0d451302bd0e7b774f3316fd9d70c2267b986e1598be5d0807100ccdb50313637fd01584fdff70ca4ab21da6090751f5d516975f39e2e5e2e0a6bffb11a358bcbc6008a951741da7f669ce259999d57bc38e8ad2db6bf52bd6a255e4696537e2ed830921eb8096f86edbddb363804d64629cdc0f3022b6b78ec18d51fff57c42b839e13bd99491759cce1c050a4836e3ca17cd120113468952b459f64473fc04a6110a4d5b5a1bdc570a65099b668151564a939323942743f2979612a857a2e50e2ae78ffbf65bade3b5f38a43f74fe90d6f3df4f80a823dc10609cc2ab6b5811f0970b3758610d034f810fd5c58bea3a817859983c3005d135322d9db7d86266344ce4f13f482b89e9292b64327dd30f93d6451353ee4ebc1686857cf03a5a277428445ec455dd3fd47fce49ce056a257d65534e85bb2c10a1bbab8b90267a91d1100fa6913f850385921c935f22cff7fade002d77c5bf0d7be357e1c10d57b0ca9e639381c6b2944b83ae1acaa14c7db1ac5e02efd9a1dcc05b18ada0e0dd16add5850eff56e40fd77ca4d75102d36f54231a5ed01299f161b44e979273950dfc2d8de1e55f0139f40f6b38df696a249b51e18c06cb559272afb521801962c44ccfa0bd0b5e47a794eedd1a5e7cf6dad1443249a4a8fbcc7b7e153db7478767232041555072aa286c2a8d6d66fe07086c635b633ae8432dd93b405094b6622649fade3f985f25cb072ce35baf3f27705a1ee53e75a14859b1b909af48f7ec84e025f5e5818495a6780cecbd1be16d59444ea7d69bbf658db191a364ea87a4a34793e6d54f7a52f23029e3d553dba0970a90b33d446d1c9c4421a5de94ed16b783af097453ca78306519c4111f33b366776838af453ff0e1715984d9eee0d617ea10472f9806878936776fe2a091b471f7aec0db1bfda02c2714de560d21b69db16d2"}, - {"000000000000000000000000000000000000000000000000000000000000000a", "000ee6ddaac3c7a9b5fd21f541ae6d81bc436ea24000876ced434cc9c12fea943c0e3c605a482f7e39d323af314c0fa0922fc0fd92e4e53906113f923f1f6d61170b87a01ddff30003f6ca51fc12c9bc11ae9f3605eb3b26abab9a838f5040d56f47ecd8b5360e8a6a0a5cb575052bb499b2d0764602da8059d3a5785d7b1b9b2dbd9c089483a40f63e3662a88016808d6d5992cafdf32ed68d2eb9f65752f24e0ef972fa4dbd6210672ce2e9569819b8199e4011065f7499d90d31a1c3c420393528ff96d2f22d6eb9dfa7e767299bf5ebd0e3c5eba2e1dccd7b5d9725a57438d46854fbe5c092ceae5bcfd993ddf734db4e1fbd5baa5febb1d9446075e771fec902fcded5f07adf4da714e27c778c42226f12f455d5216ff769383447cdffd5a3d2659cbf60de5d69555131e8ccf39d20461da66b0fa9c4b8c1927e7539058d4bbf914cd8624a3384e66c9527864e10217fcda4582732d2fc0871b423dc4e71a9c1dd152241057fdb6233a49576ba356bde1ecc0eef2ab54d81b6403f0ed7753a5ea595441147a67a98bd7beb916319d79ce72aead53d895b5ff47d87b8660e2d8f04a076bf2bba4e3a6896343920661e089b4da803fdc24457b65887ae473d746ae78d670dd8ade98567cebbb083d6ef133c94beb730b21ad8d144388927a9ef6991915a672d55e0fd1c121860c68f8a94350f25c4ae50d5567cc458c9063863c871942efdf9312a0df14d3111f3ea58ba3aa9df9089219c1a1dc2915b7d99f531881956e48e25d4f260c06a393f5d736a4d8da086e48ac068f9af5cfedf3c42811275e1db6830bd4eda91758fed0ef616aadbe64a45493e0c721db9c9eae85227bcc7aee5a1031823776fca2c64929e3dc772a2531e28f7dfc5979c94cae67de766503d685249b50ed3fa91bc2ed5cc52bb1e754a2825a482e5d557dd2cc0130a1b3f4cf54a307c2c164b620089ee600ff69fe1c875e34b00a2c75042134b6daed32769f0f9fea77049977742f4312742f90b69dcb6c53aeaabb595c15688e7d86ccf0cee3945cca9cede542c786269ee04e06866260ac07032ae7f3d50dba2a34627f15f5e3ee490cefefe4d87cd190323cdbbc7afa6b81935dd2780fdc652b46219249f76af3d83cb22ff1dff1bd03c5108f5c9ad90db2526e2112ee8be6694500a4fdeeeb0730b23093dcb2891fe626df9cee0092e16cfa61520fece3c865a064d5385392791dddd3b0ccfa98b9d7122a02ac05d7b05f67beb3780fa69c2337819b5dea1fd037bfe54cef70e45607065c47bf4e15d4b8464f09599d2ecd46194b9b7dd0af43397b2eb8f8f940b3188a765af2208a4119cff795f3c7838eae8c9b1cc616e388fdb046b9234fec74881d452e3daf53da606219f5f0dc07acf8fdb523929662fbb162bed9f83807020a6cb65d510fe6e6be1669f6dedd92aaabdfecd40c9e09bbc3913d66e1ce1542507be3ce6a609b5eda0f22ededd3dd0c6db963c25a267c97c210a1733c544fc91b854af331cdf7652b16e5eeaa66e1de79ea4103af543dbc18bd8f2a3126116ef08cb5e85dd1a5d528d32216078c7e015e4d961c1168c03219fc9627c72d0465b1509763cebc38f67d7de6f06278227c11125308dfb28ae37e27641ce535cb2c56f6f1eafba3dc053a960fc294a217c2cd307476094039e7bd9b953512bc8ec4e64f71792c0fb3f0b04ba7990605199aa10ab8acd10dcfcead0a7a3261325b83b9f84d1c6a8a262b3ef822f1bb2be3e0e26b1c2bf9d8df3408930709ecf71aad43338be7dd119077663271e26cbcd16231a0ca0a2f9c4457f3a11590e561d78db1567df54815e9b3aaeb5516a904423c24256deb6746c91fc44d1c0a4c7c416b1d07d292f31178f34b9e7eab1e12af"}, - {"000000000000000000000000000000000000000000000000000000000000000f", "00a437c55f115f8de60ad25789f4eb05876819ba2403e5816da12e283bd5cb134d9d2619a67e061c45c102c92d5f0e4279752ac7935a49a6acd51ad7e9d631055a1434dfb056efe8d7e4e0cd788dca2eac1e02a1031bbac286e2fc6feaed70603640ba608825fb28c81da7a512848cb3d0c862f4c5875347f29523ba57d507f3795329030b251e02d5e519ebdf02bd049a341333a9823cc2661e193d19d6cf8071d87e890196fb7400f2dee19708553f002b52992e742f2d727ed38483039e11bb7a837c9170f1b3746ab1fee6cc68fd8fd5070b42ce0421fd555c3050bb6a592e4cbd0c486cf717dc26d83fec4045c23be7cfbfc0085f65f17c700802d1f65887592eab0185d62b7f4ad231e4139319a309e49bf0f928f6e1e28c714c6feeb366ccc27866ad08bd6355c66fcc87c344d6ce513d0ba7a5af3f22470bbc967e054f93c3d71e62cd76606dd4d7591584bb0206cdcb43cfff78e994b5b48bc1a99317d87ad5590f7778829d8af0e05c25165b70dd32ad99400e80f72f7c6f940a6395b72be1032d2c1f25ed1c9614d893365fd66fbe57ad2bd739047f87297b469f2d3660470262ce3be10c6a6da9a7b29633be985181d43dd3b722a6f6d9bc1d5f1fe9e327f37dc49b16f6221b856008a703b4f8ccc2df8bfb60dc617382f5ccf33f85a6132edcb00e5d70392d46213cd2a03f8089b7cd703e02e74fe9ca5015ca954e30e6dfc27ad613ef3e2a2e242625a6645a40f5008812665d3e5e71ffcf916f38048cb1fc0e4f24c7f6da2240d2581784cd7f4c08880740405d479d8121753e24db0e7baad9bac4b09ef0063ae567bf972aed6f52049d982df2c5bc141263251330424cf225b22d6e9f07d5ceed8b12907b56c76e093eeaebed1a94dff82d13db1ae4ebfd5d247d248016b4b719c14c400b8cd27759254efa926f519a2b300158903c16c0d87ace5c85ecc92ff0fa320734cdf555a0268c4c1c817d0ad085f90a64aa9615be9ffadf2ae51d07e84cc639d7e494111c24e4413172ae8e8171e1dddfce75ebebd10fd769f06b9f76566e3fb7c604a9495731deaf3f40e2d079d9e1597842eed1c8b13a6f05113ca16f830d4344324ef2f6c2dd0fdab7881b3196f47f0d6ba0c407f1faebddf96ad4d03a697a2fa87639b498c9694bc3d7e475f28213121e7fda4901d7451cccdc1a5d8362e2cef275e791321b0ad1ed27d1d721ab6c1345cec304977854604e0a7f7bf02f0b4702605143a96ca89d424dd2ae69665543b7f737151fe8b5d294189b6350234622a3f72b8f0bdeb86813b9b1a1ee1bc4e1e54073aead70a089e3516fc06f46da5c220d21391df4b898d1b2d10cfa4a191de52b1a0c3cfd551ff14f69cd53e62bf438f9dbe5764f2f2ddc9a20ec558b9bd1ce965e856ff85694855c9b44070a8f01b34ca7a108f861655d127aa33ef7bb8cb24e6bfcfef85c7907f32fa53b55d5e979c6201bcdb5135155e3e51f274780e5a49776e042bb10053b005b4d9d6ca6bb5d1bd5f80516805172d69f24e69ea1260f799573cae3821bae7cc6c865f91c46c8dbdd7272151e93e0030c8c09804c615ef4693cf945909859c12fa8dc4ea1b209d7f75834a3cae7d9594bc15e4d4e4e361c40641b0384fd20271798727f0e52e5bf8ff00ac50232d6956666b58f07e2d16020523daf16aa2d2d6dc1c7e95d936d9def73786251a46fb1009e90d71c766d585c13e3212c2b74bfee47ac8e952af6069566332422f89b9bdfc4d467f80fcb940a0bc39af47019b04e7c3e9e043131d7234075bbf464d5609760ab2105bc744ccc40f6824b45b7bfc826fa366a38c94b1f8b6c113892986cf2e4b897c67c52a2dbd93f05572046f7456a0dc9e2bbb986b3d74fc01dcdba989c47"}, - {"000000000000000000000000000000000000000000000000000000000000003d", "0046697102de3edbdfbcb7bac3d92cc9fc30d75db801b27d97cdc296c7f07010b21cd4a3727c57fa90d4147be341ef8dd335bd5ef436686b9e8d25e0f989591c45433154d9ee12ef9403ec5c62bf86ab29b9cf9f025b464e042428bd3a169226f5aed925e1b1ef3a7e0e766c86c5c88828636c62579f9719431566dd26a938e2460cdf28065fee86165be74769caf0fe3bd94b4ff6d3f07d5c7307350c260d4a5a8aea691e1f0de6031d898099c2a70e6b45927cb06aa4e595622cad1c27ac053414d82675ff4875dbd954428238f399b4930c00a1678b0b87dff740e30410573d34c906951e1334c462bdc057d8f51c4a2b21cadf17f6ffdad8ac6806ea8418108ac619ddbf75365ce18bb608825c4f350ee77a6a2225687b818393e428f94171fde358f2e217a535ba8c9d1ccf708bc53429569dc2986996e0d05213eefd549db4758fcc79e8087b3a86ec3a3958e30095b33bc50d3427e62b44f375c226eda19ecebd9f14f9c64e5545ae30814ee4b408b2a4cd81a3dd34740f3d81082a73c7bfbc3835b5286b64769ba6fb5af618cf99cbec5c5331349aa9a6356cc7cf15c4ff15c60ae2d6a2765e437fa0fbd467227e29152b3a296f1a221c8189b28f18bb591549e6935c6e56a8e595ca951435bc3eb9492329ccee2443e2b251f287dfb80e241ce2b590f7a956bf8117059a454ecf6d96c631c5e706d59d9df2525c0ea857668d9270252afc647940bc38925230b3d01443fe5cd684ebe478bdefca1921e10c871f2bc3267f95ce8023e9c8accc9100da6e38d6373193e9afe46d8f3cc168f4c3c9ca7b6bf3be7f740b37cb79c926308d3f6ff7c89cf03b2ad9317d98b4277a7b75a112df07596866e1e7ee93e20276d903d82bb399d01e162d4fa0504494e9e727f76ebdbbe3783d15ebe530e68ef5bc2796f6f4bc74bb481afc120d00cfeb7c940709a6fc217785cc42c3fe9f471d858c1dce0e16a392c13f1cdfc6becf39606e8de87d075909771ac61d21772f623bb1998537663ab5b65ef6452d2f35935651ad7a9e48c493f7eb2fb54ad170d07404fbbb63fc90f77d96221a4909f053efd7883f2d050692fcf4e91c4cd73786057edcf9f4c262619db8381cb70be70a07f3dc714732901cb99c58ed23959bb43ecddb2260e10e816299481540f0d9fe6b74de4156053c248396e3f1fb29ef008ae43dc50dcd6c71d07d0904af23af2bccf59073f2b911717690b332543fe4073193fabee8e99d9180f0bb61f1f89851198f6fdb53a6de801e2178618a90e6bcd7f319bdcf7b6f700e09cdbef24acb9c5ad45132c369fde1a4c0594ab58720406bd36dcaa2dd59cca51822bbf5322e6f9238930de7b5c11a89b012a2327761f74a597a7595d69e891a7d0b16e9a8395be75032a54254b87aec137a6cab01106b863930a1ddfbf940190c420da24688969287395e97d0579c3074f006555a49559d9b5d72bfe6ae1284d6e3c2924b4b698888a563cfa0ea98595afd97360a8f6101e18937e003e9c7a36f65d6c052def65e05f1e422f60f4932c73a440fbd5f55ce7b427def2f1e7425e956ee78177e6ae913407bc036f8fc9c67e6112fcff4be7b8747e0ad859be8c11939fad71c0681163e26de84550ddd5952fb13d2f80fc30fc93e0dbf0306df6a618a7f8ee862f4d8eac1aff64c1f1cdafe0df2b4155688c2ded14e035328dd0060e7bd87eb0d108372db39a407f981fc212efcdaec82c7cf1b56b3155d229be449860b7327a9b6206fc6d2e31d5e25500d315e6bc507b53aaa2ef4c76b276086e7d1db92fc6c358f645c7ef49ffed557e02879795f296ede9f5726120563ad4a6d34a1d356ac3f3cf08e79fc16612070047dace7aa3fd3bd20e71048e9d8cdfba1daf049"}, - {"000000000000000000000000000000000000000000000000000000000000002a", "007fdaed3735b74db866f0f936aeaa78f4e730076d1814817a5a4b969dd96f947a277fe80540d3bcf9723381f9b570e3350942d413d4a62c7d2985599ab3be3f100fb2a6960f4adca107ad8df5601252d994dd5904f54138ac9ef2834ffc96b21e60f2e3be40de123b334c8b52956fe923c512874394600c873a903f3e2a18b3e1dbf5cb640f41ab18cc9bfb627eb3d73830942ec27c80191eed6b27f4c6a8e1e29385f1fd97d9f6060d4327bdca27b8a08421da6775d5b98831b8f1e715d0a21e7087fd7083c7e1bf98ad3bde49e6f81ec0071442152be2e227ed7e508d4ec0ba018767716a800d882992d75191e4e83231724dfd9e597e563805a3158fb93d63d7c86d693d62f27ffdf138f639092bb8206515d1280c9d61bc4605878b47b59e0fc0da96e61897ed23914999356c5a2637bcd4757711b7fd45de4dd7cdc786b3e3c7cdacc5480d744c2aa0fe5f45ec01be7900034938948d62a24c947fba5d60b9dc55aa15ebe457d99bcc85cded031cbaf9a62ce2d2d1c495026474489e29ec376be0570497c6c2c5f80419bd8325bb61420c2ab8cda04485e0ece768d603e15aec6303e83451b8554d3b2d4d50e498342cf83ba4f1af4b1b59aa10b4258dffe6867479ede8f1cdffef95b0260f7cdac03146bc68576ee3beef6bdcf51ed8bc2aef1e775387361d0e49de19a30f36ac743dca381371a9022e119b122a32cd5eab19dba7d45387ec221f823b1bc8310f66c8a7d247e3c3c8f2ceec875c05dc11d50794963106b1bfa59c19321ed1f7838309e35e221a0fdf16610d2076316cc4a3fa115184a9f29592b8a002cd97382dc618e072373171777a788098721f0f3628c203c996cd0bee78a8250213352fee728dd6330530ad7d2eb8ab4853cd9133c4964c3a6510b28e4cc656aeab959e977f86c89bf63572d9c946716fbaac18011e87801409c4d5da6fd397e3b2a639ab90b6ac150719b96e60c395cd1bcc54492cc9b8e5900e16a0b30221e88c7cc783990402e57d05dab21da16fcda3d906f06aa33f98f9fd90f930f1c49c8b3c8ac18bebeb110668e56efbdf2ff9286346bea82318f5703e55cd27f7fb8b97513e71f83833118e59465d1312ca5fd016596d39eacfc8708d2613d98f68a04e116c1500f82fb39da8254ed32331bb489cb45e2dd2d948ff772e0184d40fceca7f8ea96b119147b7c06d87b014fb10171fa5c76d2229716af6c5a2b35d691a652f96347f02e7df99f7d5f268b9b7d44f1ec7d00d147999bbb7060e5f4169210ded0f7cf782467721d61618f79c57046b2496b0b7258dcc9d32215d5c883371559c45f96329c690e57997ffd28896cd2175f24de922f173c205921d2bed45f967779cc69d24ce4a89bc0dbbfba634f71a39c1a9cfc78e0dc84a515fe456653a7f9e380122f628a3c7a14132f1610278b4a738988b78028d0e071a121f1b29bd9edc01f97b303fbccc6d2b139d1333fc6e47dc0727b3876478737a4a45a5609a892e26e71d7ef5cdfe3083c0330682d4ed226676bfdf54052fae7c4fa33f4392f123536d2fb5fe0440b092150e9e8978f2e97563aeb80416b4dc80e18c8938c7d22186fe888c5318195ed3e238db6a462125888be5dc224fcde0fad00c7179502a6cc66977eeb19a5d918d01cd4158d2e0f9fde335d2985d9d02ed03cacd0e9f0d011db68ea3197954b211178cc7bee19648d8d89619c49be46ee7e69bb8bb697b5e7f61fa64acddeef14668861c2f975bc1b9f8965c32fcbe81e299b9b94e1bbcc3f8201a7c71ff2352f8bfb8b099f73197ada11e88cf9c3d188cd5174762c460385ff8c6eea786d537777f802ed2efe1a7f1842d1d3b62693640fb8026596eaccd09d95fb2f5a9e7c856c8c636615337c634"}, - {"0000000000000000000000000000000000000000000000000000000000000007", "0124a9483114abcb470b4644f2cf0c79d142f09e3e1c028db098d6ec64e237357ebd60856a0942daa62f3cd91fff2593e1ecfe5b3aa33bfac3975b13fb5c624fd5bc1ef29e67c5766de67bfec9ed96e1d35c52b60b7d350c26ac1e1d947f256db25b470db54fb536023ee5fa6711a71ed3ad058423c2f1f0637db17c3c1e2f94e4e1c6903a98a744593af94bdcc699761576883b1b9c196cf62827bf5c886d88de70bacca35a009e029feb8c978f97918cb1d267f52ebc952bd2d4162833638ce3f3d6b0fbb1d2e4b06b2afdea241e9c815f1837dfb801699b77fe8942ea50ef8274e2604d06662fbcf24bfd5129709df0031483fb5f412119bfef390656821d989ed737128d52bcb0cf72be7ecad52bbf06c48911f5920a1f86cd50b81971ac9c78101e93731887a562b794b7b59a84b55bfddb40e58a663063021e88dcb6789c86573b6c522801eb34c54dd5b63d6e0346a794486bb9e9a8d57adefe6ba766bf28594127386e9bd98aa0d69d710665f37078234d83c8d6da651c49331deee7d5f9ad338a1507619aeaf74c5bfca21e3ed691f972c66bc4cda5fb9ec1dc323323f1c4fd171b5e3579063df5996948b8c2758aa75f653d9ea3355b03d3b18d8360db935676ad37de3b7117be472132c86b3e949fa9798aefa78304caf386c08f7ea9d0363f0b04106adb29934ea473b5724a3543db2acca711ae95165e9cf7c74e8232e4cace2fb8bf35a8e24814c88b8ca831bea3d71394ebac3de3d643eb3cddb7165df9d0229a749f4db6c846bd44c33636b8f96e342020fbd424db48759ac6347cdbc5ec770fa53ccee0211a12c6ada9bd87543e89257760729eb5527655f123040dfc3717671de71e4261c8f2f2fb72debf8bbc25f6eb6283d1497cd1c31298576b0782ff58597025284d077d70e4cf999366b2c3e2dd56c4c3ed726469061722b9b9a38115efa5e71fb0ce736662df7cfb9512d3c5e099ad7cb978cd94a7aa3ad76d5864b0a25a27cf6bf1a7bb69c1fa32c33a2f4e51d9db00d5f2e45f5962fceaa2272739320b4394f2ae2333e3dd4a1d0ffd6cb19d5979d756ebf1d1939d4c80f8d919b85829424a929790855518122525e96f1f4580ebb7180119f39386de894be4e021e5d0577a813291cc5aec652b160f2d0ed8af4b30ce772169f35bba4fea3a8ed006ccc5306ac8139c4510674e59f0bac1eb1acfc9da27d22c4fcd20fdb741ec03262c1fd7b50e2c5e2a170a0424b8e69ee5a33458715940955a4c60fa876d140b82d19a8b0c760f6145417ade1c9966bc837a6df609b03af89a6804af498d815eb66f4e72ca0a7c34aa47b224a2a457ff430b79a62e74cc4773a40e5e4627246dd178a71ef2ed65f6861fc0c53e418af1cd928047bbed2aaadf8503fd29253a91daf3718af2df3eaa0775286d46b8db7dda05f1b602324aed65d05b573f39b45ca4457153adaa381457c42b90bed706d7cfa024fa1b7b80945305a43993aa95461c1617a439d0db38ff8e09cfda99a192e0c60e8d53eb17a130fd76370d93e946de975bd3446501dc532be416953db9c0c81deadce3981499cfc3ea5628817cb64baf07ff2f8831b81c4285cd3ca55b0873962ae6b0c951203eb5ad3eb3ef4a1a52a112dab955f68cb4abd9c71ad206f20c9882d757f09c8b8dbc9162f1a5f6b8a235d242592c740c559e1dd325248915c380ddb9b65052de1b1f0d7e3e9907a738496c48e0e968ef9aad0ff5bcdc9f36b3fc9e1319d945b0e1fa4b6554463f6c595f710a0ff791f59cd0ffbeeea1451e852978d1f83454d0d738862470a5f261e9a07d461bbd43373221f53d368f161577826a099bd981cd5867ae7dffc288307e653e437eb74c1692908caefa967236f250a7221d5cfa73"}, - {"0000000000000000000000000000000000000000000000000000000000000339", "005b0b144ecae618b78d94feb671c1cd62701926100102ce1111ee9b5f876444df913b007a4ed875cb2218516b240fb910a9e67e91cc14102011fb67d78db42183bf7fba6d15df6f75130fff65a02e940f1fa70000fc074bcf57d47f56d210233a40c7af88adff801e07df5941c24a6a6a794221a9a6acf8a8ea28bb471d0954c6ae014381f9ac162173092fccf0e074738e36420ce66bae78f17df294747424c5d2ad6fa6d6620e040c7ec25e8d0ea7c73e55264e7d80a175681182951a46c37b0f9daedcfb4e27b2fad8142e059d59d57b0ba9fc8629cb85e35cb5d4df38748f7bae0dbf4cea39e2f77507d99883c1d9942cb05418c23405f66311058c0423862ce173b23700a092d8571a8a3d15826a36a28462a329f56f600645bbb859b83971cf5e696b12ee6ee6dd6327fb49a151cdb720688da3cbb31f1b2d1c4c4db6e7ec09b132e2e43676848a08e6f812ed0332051f6e05cc651e7b73b36cf8720dd159dad37b58361bb3dc5eb0736024f6531a44627609e11af8be03ec1486694353925c608236eac9b8fa19405a01452e43175a998f478d2719758a7c507b269cc81c060e033c7fbefb8a4951303ec6d4b74bb5864a0abf5cb416e9adad5032e2c1e41a347b8dc48d335c7efb86c1095d95fb0b4de0e3aaf062fbcef3aaae316dde18ea1b2a2ab1144a13ebdb0dd1dcf10f199d4b6e9bf51f0b61d5e765f48f87e0dbe2e210335bdaacc7df52e3190d392ea208d8004dbb642a3a3e5f3d3d787d90130e094f06405afe599863c2660727cfadf80cd35751344d4d50e29c7a33717dc58a0d7bc0fedf1ffcf3b80c266591a9728105cc8ab35a14e0b2d5b184df795f62757da16a6821954c31b75534e615526f81f71d8c2876ca0fe94fa1d5479f154a78ebbdf9ecea75c8ee289837ed6f20533d78476461912a3ab71273bf93a2018f55dc7f4255edec0d4280ff6892c689f17e6f994762ba94d6dd3233b8652547ee620981a07c1bc4a70a1dabab24698ae5b53a42b991e771acc7c9a86263294c9a33e08a65251c25f6973cca1ae9ac12fa3791038c55d8544bbe7c7901f0b6c2dae02d363ab98e8b24d046fbbd1f6941676564456e65b2ea031819692204cd1eb5df28ec07508ba1cc9946d6188fa5bf49ce07d72e2d655f7845e913e1f5de78517176d0f5b96a03399230ba072d986a38d08c3977467214c3510ced176aed91c6773671e591c1886d16fea2fbd5d9464b1de3ee1db813a6276a5543a1b7e702c8fc37af44f124f02fefe0d3b879d156f619c0cfdcda5014ffeed00626247be75b2743947d72af8951d82a746a1c5ec320b6db327508dde108bc3346fa4e4cf3030affb0e72d2b157b660e26dabec9fa968a6b3703a3765f4446314835c0e56caa81805d63ff0e66439572d8ac9b0402c6cc06891862333fccb03ac263eb0a50b595dc692e858274d3e722bfc2fc441077e1566f0f99be988f081fd95dcdc83ca29581d46d56cdce06273358b56515c071d68848f511c0f3c21fecdc543f71c17c5829094d53f884a6596d9b2da2c1e367f3aedaa3dc6e080b1800f1b1d7ce6f5c2552476dc7157dfb849995b00d5f7c2ee003d76f3ec8a53cc4f79765a58fce1aa736da67f9936542e571d03669da6893660a6adb24f20b6ec35fc6eea42b9242c5191140a9be8a561fa71221d2dacab2737c2baede34867233ccb17697983c9c100772333487993d620a92d28b5a12a92f897e611321a6f1a6a75f59f36da725d8dd5e17cabc9b59ddde0cafe79e04e7fb6da0675252e6c687452e0e3c738e326606cba192c5615194c42526acf0a5e575b95da919030697070b1679f61b2257ef7fa2b71d051e91892fc0dfd181341597c553c46449ca7c032f80bc1169"}, + {"00000000000000000000000000000000000000000000000000000000000024b2", "0026ca22cec36c1937fcc1c7379c054dced412c3a11becd6e3cdd3090b1961a4f9db3c30b6ce55f77f32187ea5f868a23955853a54583ae4cfea025f159044407c6bff1a9bc6494a6ed52d697cc395c50cd879f30637d73f100409a6c428f42a0ddea12a71edd8cf3f0c1da21072091ef36e6ca2596c1e86be5b107536e420fee672cfa22417dfaad91d906ac41a7b8a76c0c2213482f207ef1c6ff95a8220e27bf2eef62019256203036f50bc90809ebcc1db0676e52d1b4f033ff903183b27d45f0f67ed53f683fd56b43a699dc9f091e117e6621e9af0b02be0992a733ffeddbac5fb7c49852ad10c2fa3b0b92fc0cda438c8be0e127621f6e4f90df4a9b703d1e74297f7a1c8b433a016006e1f769b155d6e6b01ebaed3adfb83027543da91799d8fa49219d7eba700c94d88b836f3a3a5517ca57f3d1120ce26d189a1074b6f5abf75d3100c3157b925e94a46ba042488e905d47bc18880e0a828ef9e81b832d0b61427686b2940ab3be198d307fc64498f8baf6f9f29fe193dbf9b9048a3424d8f22432ebabee2ef795ff8153e4717dea77004c3ac24a41d272ea9fa5dd1d9b8c605f7b3180a83bae378fb52a1b26deabcf0daa98f120c10d42762a6b72d695331878fba6165dad0734e3f08059f7a8dcf7c7cd3d440f009b4b4f58b6af1258e14c67593f89a2def471fb5b2e9b15e3df016f5132407126a431f4304488d3550a88822234242657a07311c198e10044c9c3d4692167a6df59e6a5ed7f51e970801b91e9c8ae26e82225168421fef16ddc579d1d32dd74d3b661beaf5a9ffb4d7c928db3e5937151abf0f29137e4bdb99f9ae96f34db7487236c0519e024223e1fcff065d50ff938d9581947aa36d7797d761311fe1a9ffe3cbdb7b3f43d6ba76c465f2544cf8f12f25c732c12d49a6a274be62efc64dc8f9ef24fb6a3b007b7d568c544469628b42c3e371db76e542be84311ebcf6c07ad7ec34ce2fe2debf3173971b92df9b150252818a1e0a4339661f46414fff41a201e211173627de34c75acdf3e35fc4b843d2efe7a7a3c8de46b600d1ea22f95e318d537f220d99a70c192cc1bc8c850d8a6f977a498c94673ce2a04532c1c30f36199e650519d318b2cfc205e09b64ec34b98e0d3c90da7f604a096e33e89e5e15f139c501ad60cb6df2e731449f008924270e05119342a3a2e24a37159db7d13092411b1d06728d4a07671089d3fd0c5e642df3da5c2a3c027426696f9aa0c38e43632745ed08de3c47569ec214922d44b8e6c077f602b3a84e4004a2475c1c24a201aa2d9dd3c8f6753d7c37eedeef7a22b3d81f6d531a7ebe59d36191d78c59551c9ebe501594447c947f0c308f1641cd72976f5b69dd2dd76aff033b5e91141f7d45593710cea54f65e41bd5bd4fe9c5240e8ac201b3cf649e01b10c83ef88771cf783fecf30383a7b593f76a758dd518925a9f883897ef44f4d523d46e70dbbc5570c1ac3618c3de53172592a9dc537d4e7d20f4df281c1919a5ae04ec2a2191b8ff8ecc8a78ff302555dedb24551e726ef62121de15ba173c0bd34ab1e350d749fc8f3135e05d205691ad2ccc8257a957b0803c20a3054b130cc2ab5e9ebdb57ce1e3e75815e0bc0e21fa5d2ceff943034a3c5b887bd61b33f647d01e9bd2c2e8dedfea5a8d489ffeb203b518d7fe2a829a29e4cf44d18615a0d865435457481cb69587d3019c334b55789a97bd1dd52bcf270b23d165aedfda01aab0afe6323332328c1b223cb4ab11278487b1fd303a53ad1090b4bcd4a17b152352e2761a0642e4a780f6875ed99cfede0d08e978d6cdf083ec748f68d41115800d56026bb0986e274f52a58049aaba31618fe2ffded45a0632711b138243499455971f3bbf5eacd"}, + {"00000000000000000000000000000000000000000000000000000000000000cc", "00ef1327f8e5fd65553e60ef249d8c786f59d7bae20c9053dfc20643233a3ab273223f6b46308c12cbfe0baa7b3f716c28cff80516b49b79fceb38ec1b7dee31fcfacf8a8feb3daf0d036390e0a0073bccbc2af210838f54f38fd9907f96250c4ed258e5b950f393ff1138146d8eed4e4d7b95e12c2a982e29e9d998afd51895228fba8bbce4682605fd5c45da65f03e12fd2d4294a5afe696e430e88594791baac0e5365caeedc70291d9c6458ed294ecaf32b4915c217958ab6d27b3121818d41e056014c457c1333c97c1f55f3f98c35b09f6873bf70521fd6ed613bef8515a4b58c7fe8f4335f65b220c1ce6695250e50f7cc8eed22bd81e68e507f5677ab75adc81ccd0f55100b6e7a9e10b51dcf744a7ffbea6746e23bcc81466bf5da1070adf79f5ef10598175c6aa47abb1ada659136114faec87996c8927431acc98e890d1daf8c8f9e6e0cb8e50d67ec45f03305c716fc52a2429d061947af64c51d579b3c6430b2fe493ec5acc0fc104f276d1e7a20532e58e24a91076d722914e1751c2de5393584f1f61aa02b22d8524f3515e474d1ad8c98c134582d50c8a8fbe9da4150a2422195656b361155214b5bd79fa2975c87789fb13cf2ce2c0ca5bc0de8d53ae783b5bd9fa1af10be50f6887d48ede2e77b2fd34c5f65e6e0677c819dc8d113c9de81aca9b4323f2366c6de96efa11c294e1fa06efb894f84973b7623cf1ef59b957ca17d8fae0a90c1a0c6c010401f51e4482ff3257ffd628983b3f122a875f50ba1d0ec1aee0b2f931ee9274c4ee70cf333feb6cb08f21a4fb11edf84157c828b7727f3c729c0a0fa1f45f1d0110ff1e24528278956ec4a8da544c482b73ad873467dbb9fca69e3859512abb70772e72170f00d6ca6cfd419e2311e0c476ce5a1715fea60a198d5d1e3cdf9df3eda682fbb728b3b4e6993b4ba90118c4561182e9e0aa28b2e66a6ff0525a2b7fbeff3313669d36e44a014c0d2745477592c654a1f656fc0b75e06254f3cfe9b4f0814ad4315540956d1fc179370e25a73092c3c78872662e58f5f3b26143bc7e9f05dbd98cfa4b12590a0e34c00c5d048f9c95fe20ab089206acea458d06eb5ef1326aa09dbcef945f78920ea21e81f4e52e79e2517a726579c4c3d3af3fffad2f8f3a02e14c49506c1bb761d5ce5f8f6b147cccfd0317839dd354df430a5f7ad1f4fbe8db7e6e9c969f1137d98095527757559372e5fc479eaccc5d6baa5a0a06ef9608d5dccffb2d92719ae4f6730923fa4daa1b5884a4785d9f97a1d5e73e9fc90eb2910998424911274f10ecd1a860d35f7177118d9eca1625f42cfe2091e34e4b5b3e5572e6958bf0d1a9818b0dd0a8d413666fff245c37e3393a21a37da18d0110022b817e20bc4a3819cdd0a4b0fc4827c0e16a2f88209fc2e301e5275341a5cbd766b9b8a44479f8527f6c194f78070a63115a598cf9c14e7479c83f18f62177769c2a05fcf28b260f263cc06583903addcc52e322dfcf61287cb7897d9091ece987a2ddbe588a6a979977d9fb0fe23cb8e8f0c1658df903764a75b8a23d14bc4c743d785fe3b9695443f42444606723808b496afbe97e37770b3918a05be3ea1084b44bf4c2614ee2bd8ee144c8ad3d4bfd152dfcc5a80d8872d136ec46fe57ef07cbd0e1155ec8e560bce2330cd1443e00e5346ee7106a7c28d7d951c5359612985425a2f9be58f0462814a2dc4c1b14419cb3be0291cdd81ff61b3896c5c7230374a127143269e6d2f45e673f5199fff93940530902ab1806981382f7979361bbe0695e4662f39aa811fa176bc0d77259d963f367c9e7eb40f5333132c60e4cdad5903a1545e273667aa8ebd42216405e68d131844f1578ce591eda470aaf0cda3d1f2b141b1df4"}, + {"000000000000000000000000000000000000000000000000000000000000138f", "005ccdc553532b92e89982161cf128fe755f1e25f30811e95b59086c3b30ba6396b8ac8e0d27446f749a325ffcfdc7300e199b5bb824d949883e39f2f4933132ccfe2280d1d24fc3f82357eaa9e132f1827f8f4d01ea432f314793715dfe35578567e33a93c0be85a217a79f4a730f3625ab93731c1fc01c6f86ee1dd1880acac4998461e32950b6373c35d8378e6afc3f10660fd5c6f1ece9c09fd1a632417c4841f1f18d794ed803e7449268428c6c26ed56110969837aa03a37b72a2290e640486e9d6d9b2b42cd7d67172e85ae3794be083e35a9b9482a89e27c19485afb2842c8c0f941792a24d5718451ae90d77d84cd5edc47edaf0b7b66b00aa607e59d48ccf08194f2c04b990110fd2457188f517017cfae2ae47ff83a3559bce297357371d28ff21d046a3a401504c5656a827a5cddf96e6852f4d70558c3571f7adefad5c52e162f57b9a79997757dfa3206574c4a81126796b7f5130610dcd38acfde57df1714b2bb19eba14bdfaa7e91a983bbea51b524ceadfa2f35cde5390c1fd59bb4f77e9fea37f63cd4324b9642176b68069fc849594254b571d8ead30254fbe879096a46bc2393cbb7a76e6670beb85d6dcd906f44860f16f9c350d9aed94c3b07aa42fcf7e26e4d96bcd00ca07b0cdf8f60898fc2e4230f6803c5e99e53a9dd1f54a1d502d3ad97161d82b5121974eb3b47fd6ff809284abe789746df0d4662852fa28191ebd5b80cda2811cece07f29d5fb2c05568526e3ca2b35f7b8ff91061093661a23b712df134da00d7e261aa2190e3016900fd4330a1e539c0cbe94e14cd0c8b87e71d59a00daeb08a900ed3410c5c820817456c7582bbb9365534b0f710020d7a454a7bf7f06742469b28dbdfbcd92c922587f4e4466394fff4f872e4e65e4c189fa8f23a3142ab17548621e07b05c3dff647526e78563c8300ec300cdf9365173928352d69e1c75d7e9c588e480fa294a26650f0d7ac0fd2893abb9332979f5daa9a1eae2e0ede1a51b4ecce926157725b5147f93f034731d356166eb60c77f091c3951baadbf9493e9a3f320d4f5510d16496e92b9ca1505a220d48c86a0c6e8444214f66291c9907e11b478eb3435032364ad829a34340bebd27558a75e65b34f87eb9a7cd7a25ba86a26b829ed3c32136afbbe357656b41e67f70695fb349027406ff0af14a25dfe56278a26a59ed20423f89c1035d6e53175aa0c9a16a9089e78ea05ccb6d68c38a08b56553e56f520be89910901206455397b45d882c44fe2eb7fe28674594cb75af6abb0931c389aed1e410fb3471892460d9c1e9b717547174ca0ff932ea0a4208e25ba763c291826a447cc5e32941cdbab4948c14c7335302cb4f0ab2e8f1ea79213498a790f9f8196555d7a3606e9b71e1e0c83c1ec9ea439dd33d8e0c02a08a72a896428b1ac8929f72fc0085a5f4df70510b24a8e9e3d42b84c76e65e94d2fb94f8b185fc7721bc49540b74fde3d3c38a2b33cba6ca25f18d4778b52a87f52956d1551ca88e59254af1a21a05a796cdb0a59f6fbf8545a13b52040aea237dad97be22e53ab2497da2e370a3c855d2e37a873bf478692d2da94c6159148d1dfdc4b99bbd444ade4f598116d45b8a8ab1df65f75e2c7c522820992f1cc47c676c16bf6bc3803d37767a5f60895b2ddf41d32563b82d0447988cf0c0ffa8a980e8331d595719d4bac8e2d22cdede8a4131b7c64585cba15416b2173d4e153946c92c405d12890c779192c395774411348bea8745ec7871c98d203efa07c3d7465bdbfed09aef6cd89133cbf9cda872c43cc46fadfc17b16c6c819277a36d67f28da34370f184aed92c7c062552bd3bed2c7f861a9dbd9c61c22dc4e2f28a6d7b144bfb9b99d5243e2ab33588d83"}, + {"0000000000000000000000000000000000000000000000000000000000000b6c", "008876c9418cc0fabf51d07b658daa5a465cda0ddd05c3042d8daaf603ba9245a1c2afa7158f485c376e27232e770956972b85ec33db7df69901fffff136fc4c7c9ca7c3a230218694475fd2dbff8ee74d5f217b0509fa79f307b49a8f03d367f841564f4eb6bb18404ddc37538ddd0d17c2da3626cb675b6ea03e796f1f168ccb5f7cf7ab51c22752a8567e96d144084c13c335fbfbd654f86015d4da1401916b7b9988f49c5d3109cbde61aba236a9a914b21ee040ea1f836d3cddfe0d379541091debbbd03ac0ee8f6b9ecc508cde61b41f24c9d2d326626dadb82249a99df311a54f7e05e020f85e5174341ddde5fd56400e44115f56cb1e4afb0e12c66755613f2f5fce152d29b686154fe7b362f126d04ab0828a7b85dd7244e03344e34de59cd7b7bd1029a7bb868ef1233172f97b4cdb05674c733bd9162f28849eb310e276d71dc46148da21b93f894defb30251c6951d5b4e2d9397777f404fdd96debb59a30d30d1db51602f651df858940a576fef3585534cfaaa1b5875b2170d914c91fcc514f87ad4aedd879a9d3e243d8f7c0f0e4ce68acff6f0704f01062a3c971dd50996eaea3891ea1fe0cf216d8b70ccac8ea9e4d2f520b48cc0b79d900ffa96b3bbce9fc8992d248e83f91b5aed1b975d6f3eedfb1274c9fe5fe4a19477249b2995532d98ce7d9dc0d152ee05cb7254dc6e115c2f06304a6c68486d29b3956495fcf884cf4781de5cd10e60c99eb41921418588c7c81056c6ae0d5973ab322141f9bf5e8ed59f133934879859fa6627115c012e41bff31cff915fa15317b59f01edfea9981fb032270d8e749ea565035d47b6c23a959707e213f6bcfb2d13973b43b5068c8ef618aabfd65c0bcf47e97e15b11d641af00bde89b54c5e82137b3e39bde38493e35e31bdb5de184d58676374247d89d7317594feda81f2036d7bfdd387c4baaae400f187dd0f6d3df577a28a0a09fa9e81d9a9ed605396a8e661dd22f2eb9b6ebb09d8bb139c8c20d8e9c2a13b05c4f4954a709d463126bca3e545dc1125fa5483d1e9fc6a69444f8f4bf80b16a1728f9dc14372c326091655b8caea2c19cb4b2e7d83f4191f355b9e00e3a5f42984b7d5559f61e818d3be1d628a725ddb6692c9e3e1167ddab71ced541e8cacd17ca4ac654b0e33c2743c885194a911755b0cbbecf775a6030582fbd0e277c17308392a3526692b59edd6f8a4742330ae741a72d3abaf1b02992a341447871ab10c8108dcf2f67ec5ece479e55ed5036e241714670de5939382e4627d0398daaede6afabc71197db42093f3da9da0a093003a5c61f3a23f1fcff72aef5230630d098b367863cc31b81d96614b3f1e352fa0fc79dcd907934a8ad440dab9ea72e3d63e52fd32641317ddd1718cebbc97968bd5d7c9e663ef3c350623bddf64cb8c2f26d5091de0f2a9ca96ba1e97e01f6c29ad9a6aa5d9fc481605387622ddc1ee914cfc2745214407f0d529c1467458e5cd9c31adebae9f97334a7a37eb9e6a274802354dc56206e611c7dc84e409a61c4cf34ff43de3b8846afb75cefd6ef7ed382942bf62909f51167162d515a85f63f49f38231ea7070f8f95a543c434f24e3b44b78747df95b052fca2162bc50ab1c4a30c4f58ac25846c7e52d1b5a4f6cae209e152152b03f2a2334ae9e333ea41fb8693fcfa770e83ae46d1a56bf35a506641816f3a4a24281ec6a81829ef4f26a10fcdf40fc24bcdb649a73c2d1a772620957e5fc4e89b3d46cb66e3da4b0f7e4eba1c28fd0b2b56c4f65e0be6fbc641b0a15e6bfda334d4b7711f2d95a490cc3c92dc94a344584a4df32a3dbedfbe3f462624d7dfd41994d254f789fab49b89691e735f4e6d177e5a3858cdd72c5759c7dfb8067998ff1dc1"}, + {"0000000000000000000000000000000000000000000000000000000000002b93", "008f0670a8d50c02c3e44514f265459da51df724924796ec653c398f0fdf88b5543862d68dbb489258d1201e423accd7222f99ab0276d6d36e8d31bff3ee744cb36f6a4a23f72badafe8f635706aaa86e1758acb07fb70ff8946e8b1a65376503fb6806ab443b80f37175470f41b160ba1a0ec42e606e8a77b9cfade53f60ee08c182f083a968c1589f3545e824a7d4f158e5820ccc67cf6a3b807d4c8e550086d9c130f17dbf283046347155550ba735afd350bad59793980d3991145148da12f01103e53977bd2469d2ada767d6a3c7d5c38ec7d1405b0dc25f7f473cdaedbb53399e09d01bc431f0e7c5ba1e75365e86483eb37da69bb6f7d40c90675b04aac0773ca6307135ce0dc1ee6a1bb3f068b250bb45a558a77b073f4b71bdfbe8919f5ec592f5212738a276c6f4d61b37522429220cc4d0f97d58e9760c0bc7ca76b3503bad15880005e654a2fee34796601d8e8d182c6e8ec895040c8f1ae7b5d040df90c9d0ebc4241335e1e676dfc846c4bb068a22ae459a7dc17fb294cfdeb26f79790c55b1d5233a99491bc765c368b9462738e9face214e720a771f383059f9ba86a0cfa3f48941126f6ba193271c8627b45babf75a41118c94b759f2ba41ddb51b9360c4a8232f41a387e8f24d76c07e121f8bf2c2bb7b8b7ca3592a0289f60e09b644ee7d3ea8e9b8261dc04817d798f09b57a394601f865c71598e459065f9081e087c7509e59ee66ef46aa7719c593324dab4106d1fb47c9522bb2d2464d28db9bd61aa0771d10e374d1e0e7024aa75ad7064a2ca29fd37f9ac7331e1635ce09bed232c599fa0d1b033a628de59bddb3640d15a6e6eb7f0ad3231fbd2b07b393c5d15c7929ecfb527ebb702d0a1ef6fdfe292d4d7be16a64390376069af8acde8902da74fb098c30e4171d6c518b86ed9a23e11ca50931149ceeef0b00d4bd1cc3c2de1d9ff643dbb52db94f74241e285b223c379b1bd56f71683f7272fb675794da3d5a36d70e2a2a97b9aabacfc535f50153b54701f0e39b1f6f1506246b4f93c8337b14c5e9ed7060661b5916ef150112bad677f0fb6dff40e0fd4c18714986ac7be8d514a8cb3806b83cebe9851273db56b4cc9e9b4c1c6a0a5f649454a6c4cd425eb11fb9c50999d77630eac61d4522e35e0e8c155bc4744c406876a554109338a600f5c7c7198ee143dadfa62be2629195902c5504fa15cc00d4a586226fc09be7338efb62c1d0e9ef4af01bc51c09b0c922ffd69ed751a25f2daeaee25880391cf76f00fedb801fe898c3b0896f9376120f1d52e102ed3c2cdc424b837ef852484ef31bd5648c51af413d9db503f39cdf51a1b24a7f3367a95b0abe79966e0528139e1009d3bcf99bc62279fc1c35e7c0100f4717ee03a4ae1ba031243b122e97474a59a6615214cb0b393b138a4c36b3f915556994e7348e60addbb0a1129dca295ecea19fd6ebd3a7f16e5c76f252b7b0331b1957be11670aefae3531f9ea7141c8d6378e25b51b1a3a71814b10bbf18763de6ea1e26e56fe9bb5991f2ffc39301b27a587fff20b6314393e1ab7124ece4c6d7e817357f6fef290d542d4f96dd5fe6fb1b3dc230ce416c69ec331fecd52710d3ac9bb6b605dcb082543b96b568ae12ba768e8af0c53ab1714dbdd2eb30b7b86e5fbd7b875bedf8357e079a9baa87915cd5f1b6f01240e2502c5e29f8349f9f8e2767cc2b58f2813d6734acb190191e865c2d5f37a0e675761de92ec2ffc7636b0cfe354c562f37b1752646dea7d3d78570b9a89e994c530586220a8ebdc5b78d23de1b79bf516fadeed20cca40b05ee75cfca57790ec66cb936882426acdd92738ec9c6b2f2b0d4dd30eaf1ed5cb6af2d58f98e8aa5018f8512b65dbff3bacf12dbdc9126"}, + {"0000000000000000000000000000000000000000000000000000000000000399", "0105ce49bf09a646bf50f7b731f3bcf2721518c65a30f86eab949e7ebb83e73382adc20231341a9be93009a89d3f238e7faba90ce857bad9763e41b53b5832221459ea8d262d7b98a04733ccd908d1fb5a75195f0ceea9c95da010c5b04207d681684d1aa37ddb9cc754fb07234957be12f5ec968220e5b3c2adab9d2e8e17d3ec6f78a1b7dfdd219271ae958d34d7ef15dfff372a4af62156ecb2c86ee59fb248aa09fbf510cd72011d90c1d444e44de9f6c0eb0f7ab355f81053e4c82c4be498a15004a3fab4d40bcaf2f4a678e45644f5103b9ebad49fbf29c4bd51b5ac9446363270b48f62112a1a27cc62005394f90705a4ba8b35d6145128b40175991798527146fff705982761759a844b38deb323f8f61a25d0d3093c5f22d5a5bab957ac5bfe1cbf184d62ef5207caa8dd6203ec854b108a4191d3b4d22821bd0cb2bbc0e9f6e1d490cf547ee934511841af011f73d20caec2a7cf54935d16d5d9997dcffa58f10aa2520ec963ea8d71698364a2ea0830e9b4cd259f166d25003f99945153be36f1ecfce44a2f6955b12830b2b9ebb6180601491dc83c5d75fc963706f594910a5a2c7eb39602d5f29700ba37bbbf8441cfdd8b052396d5afc549bf2c9ed545fe7ee5495a325253acf60ce8a641cbf07c01fc74fa50cce8fcbb0dad9ba17b0d154a33cd62ab2fbdd006670061dd1ec65af656930768b896cb96c16b2caae40bdf4cf945b35158e34f10b513040c06510ebc0d3385e25aed1d36cd91dbf71872321a456f6c0f9159d571bc5eec7a870a3727353dcf4b5505a3636b4b9814096bc863d6b723789c870f17e74a5fdb2391dd38e3a37cb0b74d283e9d75f50fcf3e8b7917a4d8e1e4b18c7b2702a8aced2b74461be966a40d92847dfb4bc20d0b6b39b11f6b4a61f61c3a147065cabc9b1b5f43295a7e11d13f086e100c01b2d73861c65d978674d1a13363e48df4e9be0ec806770bc53d99b9a9326f81fcb632bfa9e7c5bc463e13c05b0a82871c443a4e717a9ae98861b4c814aa49500eec9fef9f95f3aed4c64f43e4352ec2dd16b082109c098c2a1e23b94b2ce26cee15ea250fd79d89042a9152f7ddcddf7f266a660200b58f323746b2e51313bf8b14b155e808d0c6c1b17f1aa6dac11539e26e3c947a905c1515757f8c463f26ded79a9be3bbed35146a556089f0aafdd2f6e1aa1d77f84d43cd0ca2cb2846e3658fe23d6b8fcf22aff7ad6b7535a3516dd217d56ea468715543926e8582a0fe55122a7d3e4f944c76a676d15727fcca0446a075454966dc763ed1ff1e2483876397c678bf4ef6d4264c27fae59e58c809283eb7d9ea9a4ced959dc6052abd75866db29fd07431a655763e6642f53ee79ca2f6ed603f7b9dbc1d36341a91aa3fba0231e6da8638a2cb8c35ff2eb1bcc7021e4ad37e535b49e64973a8646d514abe38b63c1406703a38620d8f38ac96fbaf8e6023539ced1fd1d01702dfc941a497c78f83d21726b4b1437056fba36c23cfc7546d8e48631e5774a9b235d72da806f3e055097e9b6b921f60013d816343cfc91aa0f446f661f912719aca431e4e278a18f3f4c55b79de776ddc38522bc7bbc361eec6a5ca9f939535a28f32cf8c7f19cc39f15ec03d16aacbca34d3a184a0d97f18ea1e0e210ae32e722a95a51b6341d12fcb1ba6f91e035ba958172b7fa6626ad2f77606e347b6cdc4550c8071cbb51c5aa30a6514d48de7b205c13e318ccedd3e3cd38e1cf2a49528164c92ef1ac3b58b4eb5e9bd43dac1d70be32f650508190fb83518ac40cc2e9270bd5f8733145f1edd520d81b55e8fb17f407b01ed0522f18e920c738b0e57ea1ba5acb3b1f9f6f3bce311e65da576437c12d8f7a853cb521a297f3e71292b6c035e73fb"}, + {"00000000000000000000000000000000000000000000000000000000000010f1", "00148ce2afce7bafa649a72c2fc68d2b22f75c922909661c03f24b1355b7fa626f6a35cfc1584638a893054b3dfc080161906bd013d4fcd79cc101dc50bb2012cdbbbd21caab62fa53d2ecea544852c621bd0a65049c1854ed5b17e0eec0b0ed4074bb5a8946397b850fcb0bb7eb9aaaab5ea6925dd251fc25769631380d0d505764454d68c38f1d86debae409f70a4cfd7ead11fbc19cc8206ef171207474c5d7e28e33145cae8600ffb3e8af5d73c3ec0c72405bf4522364eb3c60cd0d765498eee3ca53b107b3cd96d4556e46f6571f490c2a61e7d0c61c504844a5571a57266e230eff1d9249696741702c4deb72c707502d4d10625ba19eb84c0ad5d5b9d891f1231b77071335e47b9a2e353fde3a3641afdffb734f99b7e6d8988368e56eb08d3b48632ba25f79d74d06755fc987b5cc516b2734095ef0c32cf881ebd517f0a33a62746565f05f75a6d65bb0ec0240e6e75e3087fbf56054126a4befc1f356fe69912cef93940453c387413c556fdaae35ea33f05d2fa1043528508a09db9fd9b4e1ebd2d3548909332eb56c31c56a4043155dafffe714165273963f92efde19da02e458fc2ec1d85248b463b274dca2e2f5f8db473c1a325392a6cf117f3f3fc41b53def655f40c9d34c0201a7749b0cb0d77cfbea2484212d32156883b8fe92f5b94504fad2ad5e3f416e53048f555bc05b1d7f2053218a37ec45d710a63208155a0ccd19fa2b227c544a3037d98f7fdf7e540e49759efe3cd71c40c5379058f3ad762a56087976e162d50b8008ea5cd36f8c063e91ca7ece15433927efa649c7d9aa774673f7fac0c942866b050de2ef53d94001ba774aa67c8b8e23b3dbc534b7b95014b1695d756b349b6e9da1ed4a9f30ec2d3d4fe747585b96ab2533ca298ba1577b848291cd873e122a263ff3acf953685b56f560d4091d3b6003a2d48410594b0ba345396c83e85159101599a7035be2e88b6d0eca4dbf5a914535e85426596d3c36a075c43351a4a54049c3081cd9e4a63e647041902071bd4bdbd0ca2a7594df7d34c514a83c7260b3b98030c86be0a290b13b59abc76973df4eeda518f9f006e384bb31a3ea295cb1d3cd75f5ed07871f460353b51136a6ef84217b0b58ccf24cfe3c18b2a88b6dc65df1af290df4dfa4069f462b56dd6461309e92b71a09302b5d38bb3530777a353f136d045942dffea9f337d25c376162daeac2592a844eeabdfce8a3611be50281a8c1b26f9a78133501e0603b947cfbdaa1836bb053d484eb1c9dcc5f50d46e9382776f0924f9c7635690a12518060695d79988c418185c92602eb953e12331b11c5e379150e53d585478bbe40578afaa4791d0727cfd20a450c1c9c7e2904c3436d50fa8def149c585a56043dc9f48791c74215f3bbcf751d800d1f136801ade205cec6593de3870564f44839931efc7f62da01c64291ca822a0f1064b668fd72dd5ad37b185227040e4a0188610487867f21b6f0e12e9b46407aed4205f68f93ffc68e6510ca525e327dc260db627d6d6504e42065168acbc3793e419f3b54cab9159f5138fa279504151eca62398968663d96f2115a8ebb9d86770cef6543cf13290d0bf235a089db40897a412d57a23c7adb616d172bf79c23848d1bcfb69d24c9cc748a0741a4b289e271b1ae3cc3ffc5e4c8e1346d75c7aa183b86323b0bbc20808e437267d19685399f17f6732911a968fd55a9f7914e72beee9fe18912aabd68122a4af59e4634a729d96433f38fe14e8a1ab018dbe70d8c1b3d7f9ba2910fd2f20010636da0f6be8c366a1c730589018dc0ebdc6b2556f036db81bc82ff31780d9c3990141f2f81d48652043e1a442a2396f628481c70c9084870f551f32be346a5d9b650d5abb8b2f6"}, + {"00000000000000000000000000000000000000000000000000000000000008a6", "000bcfc59ad2b22723cf557da9ef5e465d7f133eff4d447dec3fd68ccb6a11d7fe67de526e665bb8b0fb456a0d16b6da51ccf3af245f00bf5dea05bcd98157630cac81e66817d780f2e70a3a6545d22ed07bf3c90ddf60d1b8039b51a8021230ea9ead269c26d7f12012e782afeeeb5d31aeb9b571eecddbae8c4cf5917a3259fd6201b149359798f3b67fb760511b88319d4532de545c4a189fd53287451cabc9a4d9e9c496f80a007d58131b887582e77a634b7c47820131dfaf3ebc09e758dd352e23d7f06f345242dd8205279ad678110a328661bd64f2eb73d6014117a35b576ffbde88bd191561bf48de6861c58347de95550a7f07e27c09d90ec336f87eac3f01c5ef3191e336d4c91dac36fe4e1d3d430dc70c7945c82dd3b957b25ebb19449b1756240e77f5db1fcbc5b3e6e91cf1fbde734d781d66899892d7af4da7a5bbfcd2ab79216cf94b209e59e79c044286933dc85ad3ec2fd167443e9c8e2e21790ccb3197befae817c941a37573d41e48b8690a2b0ff6e30fd89da1c9ca7e00bc40212aa09e4ac1bcdfb27a4320f946deae4e6a09600c325f7de146ba75b51a096d073b2cefa1865b22969f769370fc7eea88945f06044d34ff2550d6b9671e0f46efe6fc9e1621d51e889918959a92e7706105d1962244bcfeabe8d00a95dcaf212d0dd2e24b0a771be0c647a7fbf456b97675eee4076ed1f91844ea6eee5d5303d45aa701af709f8874961e3db8d1aebc13e07ca99c0d7d8f1f64ef5cded142874293f525a47792f4044239def3b5715679fb3342e2c50f4fa5ce81ef766a979169e272a92e5939a90ab42333b0ea4401ef78d3c92550d4d1837731d18420b12f23470835538793744f41cee9e724f5bf2d901cdc9914d10d7623aa7624cb122cdd6e0dccb51ea75708f5109d6d298fdabf05901673fe1592a37b4cc00691a42ebdc3b294a6946457794cbf496835f5d5f714ea228670a7a4a15a76943b51c8dfe996db74c7262533d43df717c3a3181c94e6b5fe500e193878f9903a17a4ae1b582483f9b2f438d5a57595fecf10c6ec0ed9ee3777ebf693ccddd69f34f72926d89297ee8e31c50d88f2515163075604c95f272357617bfcb263144e4b8aed1450b9a43ee3a4fdcd616a2d1357f2bd5c9fd34dfdea86abd73ac7fad3e0c24a87cb5a1df90baee4eeecd290c5f5eb7510c1fb33368e795e150e24a152a63e0aae59178db73b6d3c6f927327768c8f12269dea1fe2246d15879190f7b9cb40f0394fb0cd2651dbca84e3bbd3ee30e3ac48b679e183df93c9a913476cbbf99acccded3614181cf9f605529d9c18ba193341d0f8120f4898bd97d54dc5e849f7a57095d617c38417d5182628eca0a3d63d44c1e5e1ed10b5dd6b54779cfcac19f3c9cdc805aeecdc9b18e37a2bd40a4dee7351872af39efbb482ee635f49eff8582096177ee2e382379a8df57d121a9abf178a0d4f3d37b80b39f799c94af1a3b127a19d8f1d2c2ea5c69a83af3587a1bd88ed099d7dbcf51fb229c8757a9292db990ae646c9c4032bcc9bb77203f9512e04c43ac8ae6427eba478a24ad1b0d647b61944cf92562bde97278c24afcb7af3efb897920a73420d9f8e1b29609edc4c2a09dcaa38b3de19ca09a4a35e6ce0c1f6b637e4c90f16ef03694f067aaf10427b33738e8da5b12f506a3a8aeb9336d33d0bdab1160c83ba36b28778de4db21d1d5ea796e624b7eab9881283c7017ea07e36900c30d2928c0d94fac999ed46b60a77bbcf43749f900a22204f5a16981a9ff5e10379f922d449c74b7aa41d4614ed2e7ab34e93e57c25f790f1e6e2325ff45a952559be60f4b36389db149379823fb6c5e72675041c2bcf336f61588bb5bfaa14a4c7b8b409ce61d61ad0"}, + {"000000000000000000000000000000000000000000000000000000000000086b", "0003c35591af1b17dbeff0d6e4e5ab65efdab06825099efdbd4414c5cb0429e596f0f4d553913abeb64805e1612e8fc86f53a17c22f2abf69939af6b313b2011947e39672be2e98037974683ca23f24eebf731371ac49eaa9714dcfb11f5539471aad3120f5274396d1c3911fcae63a71f8f4f42acb6d3a1a99bfc34efde2105054a0a2844d5792d72c49fb603260357572adb4ce79fe51b9a9a7fbe3ca7dd3ccf00be8d8cbac91603eb28522e24a0715a9e76368cfe5fa3151e3dca8f19e9576173928aabd25b72aa3771d0a98a5833941d0ed647ee0f6164d72b47d278efafadde22c296fc1547dd872f10db03f116619690b3df198dfd2c7d212b09ba87688a57a28d5d9a32cfd7cf498d60538d5e4b0f0119c800cb935fcac256e134d86535bd1e7a9f5e0d622c2fcd628e7b94609155fec477b1624fde2de21095ffadfcc504d7d3cbc2eeb1bd14bcc59c8af52600a79e405fc66a22ad7e981158f509025d8d33ed4c0d29f641991e6d639c3265defc352e6daece7c7c9c170f5232d8690615f7d26480c9481745abff5bba033de88e6b96d89f5f7a50d524b16d8871dcc3ff22980919c866e703dce4822e25014ec8a2a28ca0f7903b137cbfa2db56f440da02c5dbd1d955eee05f9a80c31ee2f3a691a848a77b03e23ca265c86e8526d51f002fda0ad50fdab1d97cd548a950dcc27321e4df6df50cef98ededddfb55f2dcf189b050cff09dbff1a09c11fdf6b91e9ab687ee16a8d31febe04e5f36d69e1f1df4549524cd73a8bb11f73acbdcb423dba81f92a432b89277cca371c33af8b6ee7344bd6b03345b9feb0e2d8fef4e674099ed15045cf1b4b309aa94df56a91cd7099fa3cbddfbffb7b42752f0a3f7a47e5f7ab1144d72f148736a97c88d3a2e2c6c4192c3dc5c9d4e2e17029a784ce88bf83d82ee3a630190e53e70e411004a9680f18260d70cc7705388c45a792b7bf7aecc116a858b10693bfd7584c219aac86bc1d208ef359113ffe1541c1e50558b6982bced6bc0571ef47e2c6e24d8f435af5ad6a0dd6ee2575f981e7589a78ed8b8013c283bbf6dca21e3a8f863e3e6933643a9db9b680b464b830a91d142dba1e50c203fbc761388f4a2fb0a618b673877940bd7f024b87fc38af60aa679aa7f1a983c5520a2375fd45e05e2e8b9553a9850393ed80951ff1812169ee74257e17285eacc257a63ae7be33bdd4d30b69b9ad3a6aa67793b511a3653415a25b414019e1a1a69ecbfc02bf1bf119487c28fe5376018143e64e835dd447960b691f26bcefd44e9907f16f6228607672dce6af6aa7ef391735e811d228f9f2eea33192c0334523d9b37ea1340447786ce4a28f7f7da387fce077ca8f213c6593612ee46487a64d53ff339533b54cb773488c3aa14a7b3bb76d95a607bb9455500d34f0a3537d93df00d623266a5ca18cf215854d41c094b3a159a82f7258846e0dc6baf52a56f98db2007b7122330617a5b98ac714c4f56d736670c7709d61ffc3509eab71955df7012574a7ddd561918b55cbb01951da1ee8e6317c9aa442270a64a82114fd77b73112bed9d5a270eef920762127b3945466d63582b9d0ab07529c2a3863d47856215d6caf880ad35d928f321098da6ec4ab057ad3fe52774e9e1fa589a3431f105a6a1ec955ae9bfe11283c7a75a197dd4793a8eea1930f47a5f151f435761b1f9737ea6ef1a25ff53ad23fac30bd60d45834bc7e6f521616a25c2a57298042a3d118e300b52dcd1e93b9d83e4508b236b3fe0971c59e5ea6c594519f2a4f3400bb7bf78eb59ea60ea6526e37d719bdcf35b1327ad08ed88def87e1b81cb20da4d17511c157130d7552c117383ae034739ef793481d50dd2d28fb98e0407604164cd51f953fd109a"}, + {"0000000000000000000000000000000000000000000000000000000000000285", "002323f5168d9298971261aa304528ae13fb712a5d1d8ec7b757d4a1f18754935e17b67145015b3f58300babe567800f771b4ab14327562fba2613d2733c3c0f88a773e3a995d5c7c3e1b30a691f5ed97d3b905213d2427638ddc7331079d6978e38670723d7b9cef028da51a0bd385c3bdc0852c0d435c280e788f035042c27dbe964f3133bee9c130385c21b54dcc8aacfab3c9585be6c971127b6c713d3502eeaf1566595c2a003b6829d61b8193feddc511aa0ebe355905a59ca3e23fad13cb2cf2e53bc8933b1553abc77275c5e171e17172ec8668ca3d78a2ac380ddebcd852b8330eb911de095b84890a4d322e862e467c3971109033969401ec9a5dea70f011720e9b74195645a7adc0b597631379bdb53d89c1b7b780539218a66aaf29cfa39ccf627a05ab217535dacf90f341eb7370f2a8b6a5b1212301617aa97f59bfdb0e225f006347fd767819ffb30002e45b5d08240fbc81ff7c25673931f5a2adca8bd02a21a84734fb1f96f325591d8e271fa9e9a17fee5084e8722d548a6c862a8c50ba665ff6d62f7df308a599c76c7d62bf94d607e26c9834b9baadc3b3995e30ceab0907a6baa75aed3318fbe95cb44ec93ad6799123f2fe08d963419867cd1f790470561b57517b67f19cacfe9aa4e3f8152f8f65610d605ab76ec9d343b28675991100cb6bdce42e6b880c0dd5e06d41b8d6e032a04cbd581103842dd51b1b4cdde2541fb75230508995567f0567a9be11ea437f05afc39aeb0b53767204481e88499f3e17d5a46f3acf4fb6711687b8dc14d805656a762752bac8746dcfdc7202a60eb35ee570922315c5c6ccd7f88dbc204ff4d7acf51857f9482254572cb8a4bf311c7fdd63b044b74ee626096295b09821327465d3d9def3bd64c60b4ecaa7e737bf89a1e0c5431ad77e4dbe7c493f300483d7247dc1bcdbe00aeceb17b088bf5b2e3674367e8e56a120e9e9a8710b9e3bfca9eb5ab62c0a7df19f676062c3d7cf52d00db5d3f3f96b4e78aaf205af3ad5190fe5cb063bf010ab2e8c75f93c75ccae5ee10e4c61a68e11bd29a04cf07eff71cb8c98b90821c137cb94ce844ff2fcf14f9b5f1aeb3b765e1ad3682345a4f3a269e7a01181c1cd3f7f1ae9dd9dd84e6471d4ddba690775ada6f4da9ce9defdeeb93fbf376887a523a0a13c8ff1f6301ca93eb6e9bff47896381a1a194665abc29573ce709f6b230acc959eeed7e259234d060aa1f3b3b6b7a07c40fcae7985b8137a583f1accd0481132457d34a082edde78724adbf9087727652e49f714fd6cda4fb0236c4b4dbd1c35ddd25f68f283ab4aa61e77b466422333e07a0ad5c23e83fe85120e9f496fbbdbe96ef0df9171878a40d89298a231662c6fd1610adde76910f9823c5c20cdf7b7baed1446c4b6519c21dd3d3d700d1c8e55403fd298fa10380cf39dce36235bd2d16261c56a87a55f3c14e89b51c99588f32f9325dd98f0238a41a4898e265927e642e37417bc5c4b7f9a93a0e93775cd91ee1396c3d64955ef47d7179c27ab5dc00ddf0f8771c3ea1b44c34139d607cc587d7f6acd20b60bba0df65dff1e7a7b47b4bd56b122145172b690b1196099d8f4a697819a2b07ca2a061b5a95bf74917ac1b50899c97f1800391e6c66d0000ebbcf7d77901b0c0bbe85ec32d8ed3e72a23c679aea53ff9bb0f1b7eb1c3ecdc3719583cf2163354c1dcde51ba7b941b11555f9ddb4475bd880299f7f7bb3e159579cfcf2233fce372db0b9b53af75ae3de3a79dcb861399fb0c438a52ae1cbee13337f4b93e29ca2e27ea9ee53538cc4dbc238f28cea13203a1f5c00cad164af05b7f0d0b86b226c4b1f2761211ffc36c3fb117f5134a043227ce45606050cf1d25242d7be288b1de16ffa7bd"}, + {"00000000000000000000000000000000000000000000000000000000000003ae", "00a6772f6e1018f0fefa448e6342bd05a60572a2692d6a736e4e1903d8d69b568e507dd1ee7340be47850b182fd40846cdf311b094226e39f199a2693ba5db3b31773e3f10a12b3a9cd4080bfc0981a4f8f49f7b00eeaa2b46d7540341a1753ac0f6b676f225daf5cc0a4ac2c05d9d137938dd235948415dd90069c8bb1619df0421de488a9cadfeb830ea59b4320f1e78651f1af70b5fdc74909bdb651410562b170678109dcb3100de0d857121a1d99086b23d399318c1229fd67ff9076713c847954a9b90417091af0f3aa2aaa8f5ce8231acc3ef621a3dc5c6ea39a963530a5294db392b345323d71778f78657f1b0c6e70ad5e355ee5e3567fa192f299be7d3a7fb7d42c9f394ed73b352cd7d31b53a74db519f1454e524db2cef6aea884f53707fc1aa236a378554a33937fae89680f964cebdcebbf6fb4847cd9bfb25e7633961d495a2176dec360c3a542f290115a7bb0dd9fc8ffe7e229e1c78b6975bb93cd9160380cdfc404bd5f4e529218463430c6624a935477b1db83f7ed5ea554d9d4ba57bb5eac66d76e378dd6d527376eff2ef6e4dc7d418f2617898d6eeb99ff1300ea65bc34d99bc2b94b9e7d89d6e162e0382f70f48367da2f0ac768e7fc5de7733a56ae26e28e6f488a22b7eada245efa373ffee153f424cc4de425ebe32644e4a145551f6a461d3810ab59e7332bf0a4b78bc6b01ca4865f0504e92eabdb0311f44b7e474ec3f74d205f0aed08a6ca401bf496119fee1a859f1b49ee2c80fe75ed2fa12b671d38a43c52aa457a9eb12d6d9a12365bef5f84afbdebe2f14b82dd9859af09e9ebab00260b5216493078fbdce2705e7bcc3e9c8547f56bc331782d2bebe991ffbb0446063a93f9b24a95c713c1520fa0457504049f7a40851a96a38a27b8916ee08326e0a22495733caeef8f5814bcd5092e7283e143803b41d446059acf167ce6359e54d84bd4b664caebe1f37aaa046e1fd33b3a95434197e0c62b255dd930116659c03328675ab0c11e1c8c39b633e7f80594efa313edee95be69375b89858c19eed99c6b3855a0eca10307365a2c527a0dbe412a12734e2398547ae99743db88f6869e0450798049455d950d60e2048b8d01a12085c55d59caa05c8019acf6377582369233d06a72725af377ea8ac97fd32a4edbd7167b55354ade67b03c0bb2105e682eb99dd128042dd1a0eeb697a7893402a9ba798e327efb7f1e7fe4542a8c66d063af2060c30336cacc97a97c5985464372ca20b21827d011b3ba094853f9df8e77214a695ea6383b5d3e85897c407180c2c7ac9e973ba8854ace74f34327fe93c580c16fbb612cca08565943882e841d07f1e5bb858d9be15f2b9e3bfd1fcbf17bcb39be0b522a67939b3cd9b43f31286f571643fc3b7949461bfd31304531d0bd003de20c53aee5c2fb859c20c25b50c950368dd47e32298b96c6d65bb8362cc63b4b0fc45a60a05d59a151c3fd5644214c38b3e21b327c5d55c27f5057fcf4642a45e2566b8b6dbd2fb458cc76474edb38c3785dd26d75d91af580d36d1385384c3dd8e4d0c0dd5177f3dc6248aad125a215ddb0465f942e9493cc13ec3f428f55e58acd41d5f24c982a93acca750e79d6cc2a435b06d16ff913972c7a164aae5f61ab218b99f1f7b0677ae9e680e26bf9b14819548e90189cf9c2fcc5907604fa038f9bc25f44b42415b6386c11253907e62118715e0a1300abdb02da5b4c8d239ee956ef5ebf43e80235d3d360031e40eb426a27c3d266444150cf510d0e89d5c45292c409bf3789e743e01cf6d6f7717412e2c8b012d2b5bc8b2548cd148fdf1658ddb2ee4339942f4c9361963b1c958a6565335daa13abe7ccf5e5edffbb9237b812598f76c0a43214ae1d0d83ab8"}, + {"0000000000000000000000000000000000000000000000000000000000000276", "0030d24773a58caf67e24275edca3e562745b9356828f28788279f49b7604053e9b6febf95b500114bcc0153915d091de9d771a934a652a806fda19c703ba0117ec0be4b0f1f53aa96f1f0b463bb6d4621ebd800015e9c933702d7243927c429a8a502caf6b83fff980f1ddb119455981b31d64959806c307b4a42fc7c6208f8be5a63d50a171cedb36908e4c6a4e449f6cf9d880b2cdf7725d0937259695c68679a86be133759bb02a022d71f553f718d72606558fdd621e2823738ab0e2a9349180ab0c4f6c0a1fcb3fa80f8dfa8bf2c5d18e1fa6f2d8c65c377871206fc74407e2fb91c281e1ad07acd4e8cc5f8b6d0a41a0bb700d51d30377bbb0aa7655a094b2caad99e56eb44b7b452cbcf7fc6f2230ae492eeb79b31c0aec2f9c59c5c575999fee7d90d58a15418b04b3794096115ae2989c91380fae12017e1bc4d470c30e99d7ab6722bc6323648b2bcc48a03514c804fb75899f2c7c8b82dcce277643ade6e2f1b50adbff2d81443a7c84c2d62e637ef124e99783011129a6fd1bfa647fe622160c5c466009c5997709b16689c1fb30a26e1cc2052b8d0f05fcdc7ba3e995707897149551b0048ece314d6d93c4fa22489795a753bd02ad0a6908245025d070df8ee1bb2129c5422181165f392ef0e7b4ad0f822b5fb3640a66d093c62d81d1d1a5e8b9ae441bcfeb607a049e82da0cefe7128090cf621224ca482f78bc9f5c0fd672a87eb1e8aa415cddcb46b0dd292e3b322cd0722539554f8b413522cd384f10e923a4ac19c044b64f452fea6a9367059337f1a7dad4da1e3cbf4baf94de34aef5b547c9c1509cbc8b0bc443dc1c91e03a1c6d25830f37caee517419a766cb81be83f8b6288aacd4c60739fdbfd781028d2bebb570b8611497fb5e4ce3aa739d4ea3fb848401127cf9d571187cf7f25531be166aee9335fa6a101f0e2ee8b3ee321fdb07314309bd080f308dd99de13924df2db8aeb0fcb86b40bd44d3aba1ba7521b780a549ff49305c4f53a60c4ce5a72d07b149ebe8256110d735744876a27e10511e397d360e17f2cda548c08028a3bbe8e32ef8bd8ec04b36db4c325377d8db219a7d957a91b1b694926619ecc9373de5e20783c3410fe2ad5575ab60124f4d299c5cb0d46b708f832bf2cc7c9e8a0ec11bb8df292e4a22a802b56d9bcdeac0de5f0c88b6abc3de54f177e72c4b983377f5e61b4175ebfc9dfdba2ed1f704235de7d25d89c9431769b1f44698c8f91a809be55986bf7c5f0b249fdda8f2029e49fcdb6d9a7f7ed1b1a42f25e1272e5259e539022fdd4477c0b6bdd2a8da4381f2aa6913a82d7e3ae8972d62f1fec11f1bcdb591d10cb4d5271d0fa2b3436e784e5a4b07597cc425553cdbc8b61a8891149973bf33c3fec35953bed1204236a2ae1a5fa91f4da9f042d27e547f36ffffa5af4f6307e4aaf1a403a0b2924fd35e45f314bb5badc559d0a4e85b61e3dba877b13d2bc03dbf061d1c6afeb15d5f036fef793fb8cbc158fdba6f647e693b49b75e3e3e61c66f81839d8d90f19134da5d5a38b6796f2053f7eceecf46a5109971b19cf569570f9e7c69754d69839761a6dbeda09a317a474582d8fff46a1b5b36b5aa5f856a12bd65f9244b4d5e341d229a2b1a3192c0de477a76a45ff6ee706186e7a28c9807d9eb83232c5e7f8c49e49f9899107fedff9fb4f1a1d962db0b945439532a77b39de270e0879ccc150ba7ac16d616af29d466d79811ebdeb396133882ba1efeb9e92673268ef9e021e6bfa3fcd09eace20da4729234397e0e39f94174734b8df95ca3c2a7478445b8091bbfdb51f92c7b8b99a4defd0760eb33f1279d59c0cde4462673afe9998b47a52734419035fcc8a4bead91212e2ca612b4c9dc31351316e"}, + {"000000000000000000000000000000000000000000000000000000000000031c", "001109e266da0ec6eaba92c04af5769a68cb783cab1e7baa98f667990f699b041b5b611fa9b89b1d5f8904e99c5cd7d127379ae583d96568a4ff32fb7a4d4f0d23c2fafb036dd75d00035c9636af55a113db452d072a5c74d6b2e73be25bf678925b194f244d1f3e7a1d0587aa8c6b0e9177e9224c25730f1cc32e910709205342b212d6026ddb3ad41a1c5e82154ec1fc5ad02d7fc420a35937afa95c8467c4fd971b1ee89f675c04385d09bf07da0988a31193884c89047eb1152705080a4fade16b917ddcfc6675a0f935cf33099ca51209fd116844340b4bd52ac346bdbe7b5aed4b3c99db437d424bc3bbf039f2d5558ee95ed0172194de2a51056b89c90433a6ebe869917a8534b981364333956f1a9823c64bba44c1de60d408e4680599cbe1fb7bb734a77ab47d12adfb1e9424c01fc7b17758cedc6fcf694526fd53b26267c72b46a5eeb9525dcb4b5eace2031e0849355b1db5e553643017e7a5b5ff8e3784b72e7cf7c76f974f53c39a180b59ddb3c24fe37d1c0d13da52344baf6031a4dbc4dfd0750706e8e0d9a8ff1438aed3bed193c172b156c2595cc4addae1fe3f03042ff42d95c4dd4ba95e63b20abb3d320d143e2d6104662ce64917e7436af500cd38081fde3f7832d3880f215ab570ce1d3e899452be99f8ab96b0b19898b8232a557ba5df13bb00c9f34c00f6f7f6588277023805e61d83eb4be450a366825e7e4ce5f15730b89d571c497e14875643110632365581d58c3b50825b66b2229d6c881024ef97ac9b3234ca47b0e4f71e379b122c894166c010573db9888345e65cfdd12e073db85c0bd3ffb2b267d6fbddfbe1258c2e7561ef40b3922624a07c4391f4472dc7e6a934c9f32686502e7a5d161917e24c35497e47e7dee45f24761525dd3435d6f42cdd674027e8c9fbbb4183622e47671f791b9e0eb0009be12526d26baedb5984a4302a919d5c5671c50a3e769733e86c744fb74af5643c592e92d1ff18695d176ce3a8419aa4cb84f6b896a5c4f0fa5b769a7481293a8a74fc20f6499b1282b0a698f6a514affdfbc2019b64451bb337a5bfaf41d7233f3244eb6f8b0a4c1418cff1d6d9749b5422a361e2ff7d2e94999cff9d128615b11b864c584ae685811747ebfb3c059ead513cd5db45b925d3597fff27ba5050094b1c41de3cb1103a6122f3d2ccaf96f1a196861605fe1be918c51d206a2cec2b70c2ede18cc9d96a6692ea8643da72aa1501d36c2ee795cfb9b5918dc0dc4d7206c63271111e70f7ef520cdc7d99d435fc42d0dfadbf419f89e1162a48daee093883f7be7494e9b1dbdd2d403ff21e1a8c6bb71bd5ea836d2309b0ec4f4be6efdb1fbfdb16954234d3077dee73d761de62e473391ae63925ab1ea0da380850fd8ddd16c6590b4d284aced277869e00d8aec284c87f5972df05bf7ce3c75e982d3ed66121cf471da2dc41cf19e782a0ddb7bc49943afe0ca404c82b8aada3fa03c13fa67f73d12e764c5af7e00e134af5aecd6e991bd590e42b457dabb66d41790a6d02c8cdff1616c1e3b0157785807d4431ebae31c1574010540c2ba89cf5f4532983a45f19e28b7bf9b0640a2f4efaf38878491d0a628a6dd2acf4d9fd3eece3504592f05b229061b206b52aeaae62999fe196d176092af49eb8900d7b6cbdd2ebe8256e9d5ad9b04b851a6ad5b8a20d23f38201a499462d1cf94081ed0b7815a48f97b8e69dcbbd15465363653f8b279ebf3813179464806f98e7f7e1dca2efb25f329df57272771f10c956ac0e26dd958cc464ba38afbe2badf17f559a43cfac0d1257a26109812a6d77675d72c3709e749851189e3ee1956c9f8002262610f4ee764c0dd9e05255d9a745305b94bfe3d8190b8165df6abc7dbe96fa"}, + {"0000000000000000000000000000000000000000000000000000000000000329", "022e7f086a9b2dd6dbbf71736d8ff5c13af31713f42ae7664efb29ca8588c8c43b1d6f5ca1a073f181270a60d5e262973a07a58ea22830b5081fb9557e02d90b2af6027defc90b9f3b91f961a50f4a5d131b75e41045cffff8cdb6bb1ee8d71ce256687247661615e31e755cbac719e169e426c356cfed8b4db1c156d8bf220f1254fa8d00859a60a6ac07413f824a9dba945646cc8f476caa99c3e08064e5726c071e62d7fda8e802b227c58f4962dd1c0044211c2868deadfb38ad6922798a4576dfd6a1507b32e4b9e6a29d5fe3700fb30f1d658f685e55bf2452f87bcf47ee2ec0b1d72aad1da96cd23612eb15a962541e22c73a8d376f76ac4c0e44f9d8d44dfd31347aa51abbd733732ac35a57e10e7cddace8e74f93f4a5b1a701f3faae59cf548fdf2b652eb84a8faad3336a58080b7c9feef01a1fccee39e22214f990d6cae27a08eaeaf4374664acb4e1da0256f53a3193852b0e88763ac5719f722787d5ab0d03b1d2869696e5215ce621b04daf04e8769d7ad48704ee6931d1d595b6c835d070e3eb540937253bdf40235b417092afce9f946155b494d866d3adb6bd93ed05422b8d75e241d18c7ba401e47985fb875dbcdd301dfc91d5c4d756f5498222bd64b077022e9e396fe90dd865cf71aadd715ab5f6f918ffc48348a2fd760a1c351d285cce461d8e77e325c156c67217b8db318a05b640a5abdd1a379e7802379a2d3cc8c7787be2d0130272c5075b2e07759191b65b55b865c715ae88c709d57b04b1dee9cfd8bff10de85f01a24776f3ed8528c0978e85a5c9fd8e6ca5182be77411b4f45c5c30081937879ca0190904e562f6cc293f5dfb2ef03a060ce3e70b7f1917d6f217e423c4e41a0ab44a7c425c1fa9bb3dfab1e60bd06e2268e97e01f28983bfee772fa17612099aba71985d145f05c4ab2a3553bd674f027d6fc2189dac7b838041043a884388f275311877250d352767987d0bb119653e9c402e1d9f1d3f7d190e0642bbc69149cb93ea72a546158f7e22cb78748622cf9bb50a2539c15fa554a8bbec76f64110351a680a60f3d15e0c5948ee311482c1c0b161713a7322eb21648f81334c412f66e1476e613f1cf9f82d1cb75e3e2afd225b6e0537bf36c7c6e7dbbf9dfbc3d28f2842f826b2fea8d3d39815c457f2acd0053a890d3ba505199febdc0de53db63e311a647a5e344a96d8f14305bf4ce56d95fbb0d5b241d5e26c3b020aa2d433e7191ee1e16ac74ab738e995d6913b70a30cd599c2941f78f1f44023fa6f7c9222ff0b21d72a93911bfe4a09e79d1f8d042623d24d91bac6ad21a103179f8c9e316fa5226126643d7ea8535ad94d52e9b6acff707b0b76e13a1148e3234befd1b2d79761add0b79bcc61315555de5b1dea3777e6a3e95a2fdc4a2588542c4a06d0bf87d3177b099565e646ed3315f1a64b988b951352f53a404626c169b2e205ccd084c1b588fecff54350d73b7b2a44af9dc7d6e3ef6f8d36dcbefc9f67481b1351dfa2dbbdf3d11527babef4720dc1379f1709834adc5b876357f70d20f1e3e9e38274da3bf70417f0e4fad6df19513511c37f0fc6a3d1388909fe9b1ac3243f865964bda93325d3f7d8d3f9e5ffb4d6c92406df5212a12c67f1d3743f0be7e4d18b3a33e4d1071ed531286b05c1598f853a6d6ab5c6330cf51ea416c808c0619b26b1b26571e7fc76cfce0db53754550bce8a81bd88b65cc54d937726a6c095a51f2f20503c51c30a05643bcdfa812491ec35d52b6fa23c1b261b449e8a358b73230629b1e3105855808eecf3f10e38ecce180350607f28d34515544ced5269167e31651bbacc9f8bee2e81c4ffc201b6fe11b5aaecf4f4782e17d484e0bad7c1e8cdc9976af7a26f9416fe054f"}, + {"00000000000000000000000000000000000000000000000000000000000006a2", "0013b4e457c83e54503011ee8e27088c8b70ffbb5b1583aa037970c7658833f3b8862f969600bf9e83751119938d731229ed9ff243e5dcf4f5b9b68e90a1b31a4d8187b6954189e204b2b3e45e511e269b32e0c406bababdfcb42657f4fd94e230339dbbb6421ffb430c5ebc6b1dcf6d58d7405383b53f090622751d350723f8cb38ed90ac01e84d227a25aca6311b1b5d755f2ca16202751c73251187350793628a69648911d3910803eaaa5a85b43b45d2972e8f63710b989d1d77550ba1d71f3e8559497e98b824ef47cbef3910bd0f202221ba2345e9cca5826ef6f5ac5e4466eaa41f451c36a9d3597bd522eaedf36660f6df1106a64938be5d0d470e87325b3df3ca674125c2a5c2fcbc7554c8cc2e3713fee71c388fef0c13e48e211da9cff21d830616f56b909ccfc990f64291c55ea321d6d932b8c51020a0b5b3da68d0edb036249dad5ae6c145676d4a4b01131580d7841d93883f58eecfdd9ac70e64be6d490bdf15fbe45b07294c2c84dc8ffac7356e54fce4670515513f3b781617c3bb61675df2e7f19a27cfb2450ae00cab77260743e84299b315e5fb37b35f7fa420086d4e102ad9cb50f2b9579708ee331e08edd7cfa30e063617dc0c1b2cfef974e227c3860f200b7c7d98119a279cbb4cbbcf5830f66002ee26da0e2e97a4dd1ac00561afe7c62d4d1a471bacefdd531b49fac2ab05293ba78be5dc1991441071880b962575ab1967ef28cbf7620be79e19f6d86550006042d27a14fc84871ea0df741f2761e542574418a4f53e2e4045998bd91ee8959bb226d7b9f95c4a37487c2efaa23f9dd4a6166f4fc2b0b3c499a4a273ff5e27aa9906ebffff14538144ea9aa5967f568449668275e95fadd6be1bca194e11d332a3fc173296136f77eade51271d1cdc8b2bd4ec5cdd1a79cb17ac35988f50dc11b190760ee100eb9447542643c76efc6012d386ee3943e1d57055138cd9296345f707497175b57ab4ceeb2c035ef4c402e34bbaeb07bf3d5ba6855ba575e1b21cad17b71d052251c4ee1d25bf53b4f2f26f3629a32e415f6deb111005104a045b678e44e45c3d6e2031d63739ad582a79abbec2d8b727158c34212265f3020fe27e1c331aacc512a3b2cac1f0a8c57b2ae889b1ef0ebf5dfd1f41975d80e15ddf80f1f21199619e259e163621b901a0b16b6aa60ecf324b148e5575d3013bb38c6dbc021d2e88fca175133fe6703a5474bc818a61f7003d10661947f7ba621fe9bd6584d6e7f7e9d29d9892aa12804b1c4ea72585ac50b3b4ba399f9f04e3f8b55a01cd1d471260e917565f85088562da09baeeb973bf05a4bdc83aa1bfbde04e444a052ada92de627d14070a1b018cbae32843b41241da16fcdeb1f4caf7da971bf0b290ba653981f06d02b29b7f97f597a176992f013af8dd53c34ac239e9d765d941c5ab37db9d122c0c6949654448df88de493223012f08f54b591afd2a0a2ba0f8946955d5e30bf4dcb73ab5aba51c3ecd7011dbd1936c0e59e35279e37859fdbaa634fbdf106e0350bdf2f0f29ce9e3948366474ad141a567757457199d6ac11007d84eaadfd2719a986e75336aecf5182e758cc17f610fc597c6f4cc4cc46d9719105d53a445f79a8823d475b95ec4b7d4fe6e8132beccfd70bd0169abf1c3990be1f164c3e26b2553fabf957d709f2121b407f916aae0d9412372d6a72dd21c26da73f807dad14db7e21df3418c824947baea25b28fbd96ee20b135dc96e8dc6fef72044e6d65c4aa130b5921800d221d724d4468d350b476aa5ff92555be13d7302132605ae9ce8e7b5d0d86c79dc8418bbe9ceb37084011bbe76ee6c9cf4ad72b24b42cad9a31c6f7cecb5e26db141da68e020080ef75aa98cd62c2847c3aad1c"}, + {"00000000000000000000000000000000000000000000000000000000000023bc", "004110e7bb9afc4d10362018f22772502bae42d94223146ecc1015ee79918a25ae2bca73b2913556e98449eb8ac8845adf17ad03379fe1759a7a48a5fecadd529807471eab572594ec78cdc765185a6b7a1e0b6602a6bd3f936bf701cf1e427b499ed1e8d369ca0ad03ba17c8aa21732a35a0b643753c2c21b74a4dfaa24137f2435ed09adc8519d46a2cc7ce9c61f8e38ff041ab6646bf80cd380ab66e26c284200957ec99823bd005f4558ff5ef62b723c14103eb1b352cdd39ce38914c1dd79180d902f76cd62195b7d385181f0aefa780b8400da234da771fc5fd1c1634651888ad2c6e4d022eb1a3145387aa1e1bc73fd6c35d7fdfeb19a294209b74ea02ce21a8b462c93d1f65a56fd2ad7dca8540b62b175aa5e7a2ffdedb1a63aac666909f07d6d650a725765050aea56ceeac0d9a93963018bdeb24d951241b3fc0b4f392ababfc68a0f670c09bbf1ee5902007047897e8f5edd3913743592f93a6a0050d33c5834acc4af4b9ef4d7558b03a20fe4bdb15a59d73e21104cbfee0315ad61b5f6b58df546da35b949132f8936daef74ae8fec1b321a3630d3fcf1f1bd84f868c6117e9f045f4f560b0a7bd8c6e4638832f5cc7e0c872c956cef5c154487bb4fe3462c583bb9c113efd19e15f75d912689f182bf66b6ada33d1a864f099f92582f77cb6f81ee51fda17084b1d7f92f3aab423b34ec021c6fa2a6dc4fed599735ea19f2d2ddd6b1be25860bd398c1121a86e2fe1d1223d27b7e84f5ff28d4760470c96a3c064446f9a8696fa96ff18f5e6bdb909d40f26d38cda827f145d5a603037716d69ab9fff97f15c0f374dcc60554bd3ae27d8a1837a93968d00f481e4d21aa450d99c141df035f757299baaafdd9d71d1e89da1b121a0c7bae75d72c50ce819dde48b211b020cac4f1f63a3657d96c430339a9f6160855fc97aa0197c0db7ca81d11e5fd20f070a5151cccf05e34bf0bb6fb758683a10d0d6184a106df48ad9a8faf836907c1acb767890a6f5c75060a45fdedaad4da36d58611ca2d74fdb34173b70d85896ac7b24edc48d93c1505af4c9b8ca08fd99329234ae83027219dff56ba2b19d2045fefdbe269e59e76a4a2c2698682e9b97c7e19378f23c0124c97e641345a214e6ec53efadf72b8506053bfbd74dfc9c25396d1134f0afdb4935cf8b904dfeca598db8d8ce4be142d784a52de6e9d7d041e0f013c1c5129574bb6f641530a5a0856465cb2a8a00fcb036b4a6dcb4bded0a2c0ce671bd9bd5e3645552881863fa3d6a9e2db4502f16a3a0e691f26beb3771335312572162305c7be14e4245279cdf1628fe31f31da4e73026ad589f43493fdf15e1dd562c353e36d13ecde9aede3876b7f51d18e5943d92ae634b84b8b23a3269bf24d754f782ec417dfc86f6a2ba736113504b3fe4dfde7f3d7d9cf24a94144ce667033f92c6b28ad8560944ef92d12af84cedeba7936aed57707e316e05385d8a2cde3614c31ac6ad885962b2ff5154d1dccd5d4a0efd6ebb1e7b5288bc9276ac71ab6dd461b8c1126789090de89eb930ae3320d5992f4cf10e11cb65c1757d6b7cf6727830df6dc64ea709b76fb571e303cb5ea1844d1442114f2c2e49111ab0a307b0a2084dd0dc690e951412dd2c5b33938397ac2ec6c95065483d33cc5095f5276b3b9facf25d0fe6694ced60fb5097c6eafeae3db9981c87434946b11957a54b01cde156789abe5f5d593b22f854ec51d955ab7b9d64403ea464257aa8d607f4597dbe9497ee2e29dc2a20ddf188619f2bc57f6eb1328ebf101137d52bece05614537c879e4b615e1c029cbbad1df5f04a1bde8952637c578a0551a894c349398585dd3c2a638f6638a2ba59d25471598a9cc6e445fb26041534ce1ffb346"}, + {"0000000000000000000000000000000000000000000000000000000000000132", "01119fda2950ed71ca98d36a1c59b252ddd2d75032053a2e35ac4b389df205b7b660bf7fe77dd8dfe9a801c12246c6e62ce9fe6313b3597bb6053f091d3fe1025af2d1858e1b947819d2dcea7783ed289f0b09400481508a804b8468eada531440995fd3bb74bebd03105b354b4a95f424f761a228b1749d149c7b6c1f321b533a5e9fd98f49425cba2ae6f05a9f8ab47e7d9627b0256273ee3b318e4193299e5971ed0d60a97242033e97df2755982ec6f521ff9ca725f1d6f3799f1e2269d78564cbe52abc1b77d6f3d530aac88eff8bad0f6ab2ef3827bc37a66b356f0e57e8c7de2adef1fb2288416209981ccb4a1dd3216ebe3ad17ec05187460fe8a77874d4d0b8e050290c65584826e335f8d6cb290415299253ed17325892e63bdd6c4f053abdda1f1dac5cde54c90c0b6b2264a3e4558df5ca31ff7dc223fbf72d9321bcb7a27d474110dda761d2eef382f2018c3e2bd3c84857d66a11627331ef61eafefe5d4e0df764fdbf04ce07e1ed94d545b8cdb6aaec1d19b50344c44df99a7cf71ae3d220ceae6a98a460d2607c0b46b86e0173720bf99fb728f352c68251bb74932c1a77e5096cc92cc3b5b75757eefed99e7c7979bb7626f4d2e9f3cb716cae3648ad16617c16a4e8d8c4f81ba15900c860f41b21c1a78b0c6c7a4e4041d2eedd3b597526f0131c79d1be843d18fca237c21ddef3f70525202dd514bc0370561613397a0b5f6a45bc24d315b974265f10147fc001bace2e60486abdb876040a0bb02f1787905ac0c3fdf153449ce4490e85f4471d0e62f0a8a663eaa3d456a2df1b4a6f80cc8c76e74a0e3515ba9b0f8a70ac771450ac60e1ad59f8cbaac80eaca50166a4811f6174b57a765b646e409c35c8be100e4e06d8eee4d3cd60f2cc292cad0321e1dcbfdf2a9a97060768a1b5a130e3ef60520bbb72fffbba4601601502f6094d39d907a6b1e76ecdae98435b11870d257704c6a7403bfeea617ef6e2c297221bbe013f06ab9b31f382bf80497726ca0dec94f245edd4ecc509946f381044728719cb90ef087083196df1fa7daf02a977fa5b74ac37f4eb8053a482ae786084043d5612e8e2e1538a407b8d3ee47b962aad496effef27be0f047c7ec9c8019148a8b2384ab11661f5aafcdd982c4c99b9265a20052c45b4476350314b18ee7b5c20017acd44f750391dfc4775da16c4401184dd5175c126607bc8b1e59505ea1e835acc4328da1805195eb1041a5ba7531f4d457633332824b672b26589fa0fbc390787d659d2c3033c771501e9bee0330d96dfa88b05cc67627cc24077d5eda333caa7e8aa9658b588f50e8494fc0b5a3ad76e1fc4b893c7f811ce2dd264f20fd44cf0d90ea085c150e7aceee4ddb26c7a1874bc1da4561ac658626cd0b688f47fdf359eb54698eaa6040a335d294f6123cb70016fe390b1c0747b8552c763d1cf7cfb22a90547571cdee6f0495360f35bae0a1155147cfc610f216e43740a442525819884ce58c0122637ac50a5e46ff0a8dbb8e7ffa793320b9b72ca08dc52cf10877d2fc601509fbbc00c460a157ee93e0ca5c5d93515752f11d922c2e1e2f9497d83eef10010ed2b4a6a3b30b3ead30aecaee3e166c94d9e876d2671299e6e0c1a395563b52f485339160818f3245c06dafd54e8520f03613d966e13f57b5e56d593d17b4c315ddf242190c583b855f986c7fbd6033c3ce4ae1bcb7dc22bce617ac3a474651ab6b2bd1ff0d820242ec563cdd65d312b69c2f31966a3de79727dd870310cfc2a6f2e8d708cfde003c17732fb015b0e2ca78b1c9ead803e8f0a51a29b61d30d40417a811218846a2e32bf0c4a5e1e5fff4a962018e4f411d3599bfdf149bd4aa5da284f3d62e7c500c73bd1f5faf29bae30"}, + {"00000000000000000000000000000000000000000000000000000000000009c6", "0002c06fe29bbf7923cda38f12fa16fd84a0b08dd10132b1ad69a0402f54657106cdb92b6cae796b9f4200fc12fed958e15f95b3c0e05faf2d85d3e31edeae0b104e437f4fe0e8c56ab477f8ba9e2a5d77b4c40406b8f3ac1a4a9108f29fc63ffbf04455ab509937220f7738edc3dc17efe9a6d3ee35b9c8b6c856fc07e20c3ef48a30217309ed5ca38c7fe435098bb3d1af8912dc96e70ed89e9b30b6515db89579247db9e617e30c6e9a2d1908bf82d234b539e8cd6f2ec3927988cd31d74da009b183bfde4dd378583d7bb58721d1aae013a6a474cf5c9f29b49461fa9b9cb5e19ab7f9dbf14786fc16b2e3430d707a764202ed35a9bd8395200f23aec5de3a52bf79ab884307d7dcf79bb0929ef690302eaf7f23f12f1dae033604da35b5f6c6c4b8a1d63c49ff99a3e48fcdc9b4050c095277f5ec14b2ce6e414b64cf66d45368c51b5428f6b1ff12aac8bdfbe300eb33e5f2185ca124a45266b5b6cea96c7c4cfff90d3ddbdaf28c819dc6cda452372c709764a11f85bd04c2d2db4f46100d2097d181b1285b7ca4a45049a34b8e270245318733c34985b107432989e43efa78ed06aa1b230bcb0b5ace8f523df06aaffe89da35c37d08d393f1968747abe3e336246546518634073c7c8723e8fdc27ca7b647ebbf0296ffdfb620b152932f8b318fb3a3ddf076f7b0dd46342d7393e59f557828f10e96b9a9b60d4f5dff2a430cf4b0f323d13c9f12ba24a17fb8a72bba67bb9d73412db177eeaeab3910c90fedeeb90f16b83111a57665beb659ae4c4e5e472c430ccaa3de1a51fbe9c595c2c954c705b1d31422ad1d59248160e5b325947181dd4dc8ec0d25ff1dab2a22267b244809399cacaac345b2cf6a136cf9be2aa823bfa202eb4b633cc898144e1bbbed6b2235dc3575524a5cd978600b4b8857c673df35e86a19291dea6900199a824f8cbe13afffa3466c23d0a63b22bae8a906396332e84ffe952d00f4d567f3fb91b280549a7e0e1f3ba97866097544eb01bcb99f5e896aa4fe37d02f7da6330c8f6509c2472360163918c59689d7eac304e4054cb2f646d5bbe9f1571b45ed017d6a4d1236090a8f62ec18776af001d3f21f5ab7f97b6f2cdd4c23d68e516edd7e8dca2187cd6148163eb021df9f9c42236fdaedfb0c19f4ded9fb6c612c6b69f43d0464019139b46a2466419cb7b571ebf2fb2ec4145816e44297b38d6a9b036fe751558cf3419f258e2b8de0861ca246a03ec84d07eb4712c925a68290edd7f62b97502fb693f1d95587003519c84ff2410e97a176e08403b32351561cf16b403c460a70e3a9a29d26d5259942cc9410eda13e1fbfef85bd37f413ba06ec9b49040661cbc68cdfe2c19900766509c97f41c7741898700a6e68553798c8a980c4c26c097117793d1c3c663800e47f837c172cf95265b0e5d69bed72570d552b985b1e4668ab1d2ddd6414f82a4c526a9f2feb99c2ab02e10d2385565c29139654c4a5aa0e81e8dbf53f6c081a7c732c2c81fd751561ad3d5abcc0c6d0cf1d0d01b3f16fff5d12b748f061f7cee8c213b7deff868b302743cb4acfc2e7ef0617bb105458fab20fb833600d8eea28d0a737d348da6195552a2b19d4a4113fa939f015449bd13049a55095c13b4d865f76e3bd86ce0889df9815124089b96c63ddea452599aea8ee872909b696fc84e0d365b529d5406c6e2475c6929dd61a33fcea0dbfce878de63106f48679850a75c0b4147a55e075e54557f6fd78bd46361dff208a6bc396ec7209923a6e9be49d2fc5e0e20465282cea328dd1c4a50f14b9e5454bfbeb0de595092ef4ef95867459328214c51a566fcc4580c532b33de72c9206b2039bce69216d7c8651d8e64f65dc443b59b3e5c932cb5c0bce"}, + {"00000000000000000000000000000000000000000000000000000000000001dd", "002a7c283f0819ae52acf1326c185b70968be97b910213dae37f0810ed8ff00929e5680b4a7fa1fbd1b40a853d7acf9821b958ef87d8c653c8bb09c29c021d2b4f050e914cee96dc954d400e6ac6776d531f2b1f17d32341b88d029366c623f68cbd6bf1abaf92ac831b0409063655d467769e84042236faf6a393d68d0324f81f3d87cc79e67ccb5332e29f4cde455d156a2025e6f20e04f002cf84db665be340b0335c00ddba5f04a2fb69189ac66926b2709758e407cf41a5bacafa04c9963b6e42c57d12b272628cbee998e2a68edd231fb04cda4c958937716642bbb3d23b6d93216def8d4070acf2d31c20811b7e85fa783f5cfdbcd2db2c8c08f0d52296c97a12562e33f9bc785bb19cd9134e4650601e79de1f98cdab73e524e92a951d52f11fb9a51209dc381ce4a7997262737edbbd36c2c73cf6573920bbec99519d8ae9f053a2f0e6ecbf291f082ede2c02499431adc620750bfee03bd6b68a783a3476232d1330c8de18ea35b9cdc727c5a150348b1feff92d600b90a260ffe27803fb66a19b95729312ae8b3d6ac11fd70c66c5173ea555c46371d92c55d1c60c0f8a2904b45a50a846a1f24041154b0fbfc89ea4f83c265508ea574a16424479dc3df2c51f7f587df69c3ab65f12308b1ad5c8ce19f9d2248e93398e7d2e0c5b248313bf1f9b2cd0e085830644d92c7c241d3c8d0db1a30b5bbaf611dc70dbab3c8327dccc602955ccfdb04f0c47cec8ddab0df9f21a5437b65c3b7524a919b94d0b99630e3d55693eafd001d1149b84a91a67cb70e20c1135bc3fd76330e88c98de05481e22aae6596bc40c1b17b0bc98180deb79916a1cf3d48314fc9f395717e3ed97fa91664f2b6173f3c5470b1138b95b666f1e97fee0f9d820c2f0d72375eec25378f94517e8a729f2a30987f6e7edd69f233f13613396115e1604e3010bd72e8f011e5efa8a83893579cb662bb2ddfa4b061dc16b65b0bd01fb3a628f22dfeb970a629da7fa1988d5fb2f1e2e67aeb6a2a012d0f8892e7d9254aa303637cd4e74d9cbb4f0274d5dbba39aa65b1b65e00563aa16599842d71baa823e86c49a34f62f1151a52562c66d8199de2959a6e2fe219eaa550a0df310c912d30eb25acfe5fcc8e405e9c7b0dfb61f0393e5f92c346b78e6dfb0b3e77752e562b216ed2ebc341ebb05896774501d23f100eb31b8764a3b75df5d36e20871855467de5dfe09831758d81c6b90123831774b290c1b1cb57e88326defc91257cdd8d6bef79c9889941526eb7f12c7fdf30a7c559eb76073a1ee5dfbb21f10e7339256469fa651fea48db7ec8db1a5323f6740136b1ab4aa645d5d55b6e172c1ba994963131bedbb2171c95acf2048b5893d323e3fea4cc93d3333181a57dd32d4846b5c6765ec66dc404d29fe7644d90cc0028120190ed8255b91c09281962887e350f05db61e151a1aaddfd2e583a0b466607943eb45a27ad1cc56057fcc147670c3f7cf976078bbe63e083151cda990463b64855bdb57df4f18178bcde68c8ea17fdc8cb0071591037768d4aba0285147c730cb81d0f3fc2690513f92e9ab2cf9ef772b7a5d337482f2a6e23f38151165cfb84fab4d43ba8411679ad3558d2b155ec9991256b7a7de60f7511bae87f74c7da003262fdc6c2b07b9887d6e4c1dfabfb52cdf736da41b53c69f6a54447b27e05511f84b8f98b45b3ae330114956396cc123355a5e774f9e06d86653dcbdd7c0a5003b1e2c8e391f9415d5692ed58b457413acceb9fab33d77c90c0c44d9ef60619e693b43b72ba73df2ce39d1750ead1a4c92d88687ed5ddfd735a9b061b96f4d321ace5c1698f5b7078fc01f61ae934129c57da2863a7850616138b74e02db343166bfb8505048d97efc2d9ed520"}, + {"0000000000000000000000000000000000000000000000000000000000000634", "0193aef5ece2b7abaddc406076ff97dd4145f66f5901965a3ef8601209855f0239f9132e5132f535810003b3428af716f68fde4c31860264be34d381f726481eaf1e9321ea83539de4c2c9a7507e857c7e582ea622e2ad51edd08a51f582962d14b961ddeb99f7bfd72a38f5aea839e77ffa7f32b89e474dbb2cb219d77d28c5a5688de75addfd927314dec35da6fea6d8fa1b357649c141a471633a606592994371aaa317be964809fcd8b2eadd2a4bff602541d950ca6de236d18a0c1456c0a58311746d14ab61b1b52d69babf0b1d28020ea2245434e96f7fde784223681d7b5ce39bea5c6650e0fa8ca16ccff369e7d7c5b86323a23a78d4589d0deeb68e64a9bc39621fc1bd0239b54eeb4418271c5670b4ad8ee385978d9af623f7c4410b9332fd490e0f98475b4b8d3588ab8c43b4957b38e682ddb947c81ddfd27bda4f23ee8f10133488a5ca2e15b591fb080351e35e1babc4756e5b915229b721d8939448fcd4682e378be39d63abc6bc369477563281f3633cc494157924683fa6e2d759d9258bbb7d96a9aa736eb6462d74e3e8010e268915c3638fc5c4237cf45cbd8c48081fd8e7087139d3bbfb91ab052adc248957546f0b0fea0d6ffbcecdd969c7a44781252992a5e3f8e4fa0ec29db341c3c09b5d8414a4f8bce545c45a5fe28950686cf7616120adb42f29db2e750a2681aed564de0721a256454be190cc70b14f807ea5c49caeb5788808943f52b41c9885c567d31307e66452f35058af5d0aa78abf2f981c4ac44a733815a36a41044f9196160b93affc7604a6edd48a87b3d3d8bddee8dd7ce7990746efa4d153e383c03e5176ed3db530dd8b7c9e8e20282ac7b68d7f20926747c91a566c9b7afb3bdb2c0aa02590ac844fe5b73a65b7d9d33ffe5015dd7f880dcd6dc86caf6151dc0c132bf3b1ed960adad1c774024d624a30473f7ac2d699115e6b6352f1cdd8931b1a43574d2fe11a55d68a344bfadbe6894712bcfe380377b952d8743c7dce0e355986b68a5e32e237d9043fb2d7e6e9951ac8b333d50d26743a258736ee49ac076ae0f662550b43f046d95d3a5c866b79029ffd2a37f4cc33ead464b749d845bedc7ceefe6ecbf4731e26044a92235a597fe492d69b6ded2daebd4d1b570d27c8b13f5eeb759d86f662977c5c79f9336acf6b0f05b820e62ea3af7b24a4a1f89eb3e4592d8d168c4228a5d738bd146205b911a304f2577cae22a1d1512811cbb721e6a48a2bea4045ecb73b252e677ff782034981ac9dfa34f0a7dd1a380d1765e3f219989eb486072ebcc31783d16ea7fbd0b042bbfee5979a0e33f64005fd27f2e358d91b77f41fb44fbbb376fa1f8cf92df5326ed49af75ae5c405c82844cc3df7097e8fc233fda4edf5e9184db90024afa2e197c1a51b9fbcf5066759732a690e0fc1ff4774976886c63e87fc89751708acc4d692e9d0dc93a5af4643b311dbdfd4f70e0859bff5cff583e5ef8ca5a228658c39761b9342c98d604f2d042a233fba18ab6df7f67652f4dcf80b800d2270702b0c7fa79b70b0ed08ac91b936f812f70b2861bd03825e6571635f678333e40f0a0bf8d3068b35e535637df81f75ed9b182e5afc93aa67cd39ea263ea6ce0cb61612e79806c6450ae94aa62b13d977050a9a55f00794deafed5ef32cdbe849ff224ddc09b920d71e26bf5ee6dfecfa33a693a3f6ea13af55f7890b89bc2eb66bbe09a9c503c48e4b97f73216dbd7af126dfbc6ed228a9193fcf48bedbed0f5dcbdfd6899149ae17910cd678165c5764459c2d0ee2ae4584a2a244c56c1e6a9a6bf9fc8b5849ad91525e7d5d21682215bc1e999d59915cb14047c2ed03c3d5f2b1ec59c2f672ebd3cb020afdbf215f6ba3935b245e7f820bf"}, + {"0000000000000000000000000000000000000000000000000000000000001fe4", "0034d0d7ea85cb9ebadb02f966bd4f9979c65c359d1d065768e9dedb4fe25dca595adb5f2f2862fc9b6b2175ca9045140ce0f38ba3459e7b0255a5cefe3440280f23c18c8be782e5eb0635bf50c5b2d2ee1e45a11eaa3f4dea8f3f18a03de87d57e90a2e20b4546e93496a83814ffc2023ebcfb95c0b5853aac46d5f897f2036c98666cf3c04b75b59ef2f5cdaca8066f6d22f35f43334142e0acf86c9e45ab1a9df11c56d128dbb00c7c049a55cacdfd99af3c851cb0fba0295177d6b0a49560fc682968aeb40c0f3eca3ddd537e0fdd44701e46b1e174ce175dce4b6df83c02f134d7e9f6fa004f4ff5731217d3def62822b605413b29821fc95df0de4e8f1151e00156d28b1da703cb4b12ce1f312c83080c3864c6d183dd9e46a8cf9fde8cf03603b37271b9bb30b8c5ecfeb62429266a46b2d871599dde9dd251dfd71a60f6d9727d5759f2b4e8a020eadf6ed580815fa0dcaec087b72b7308ceac3600d2b5379eb420d5aef338da3fb0961e565915b2d90d78e959dee4917a8affe4b690df5b52929a8a3f30a77d894ff67812fb5ece0c0f3ea81dc2ed4385a5cf24a6a6ebbebf10ab4c9d53656df732869c26994213976cbcaf792c52ff4d55df0233a919770531cd7d4a236abd05978ed0d2026f259daba55c57c013e6fa830285159956afa17e824a74ae62e533a0f82d90b4fce29982d374ac20a03ac177e93bdf8e51893e683c662bf3cd33dfa6c0b8c6649efc9e946f2abd25484538c822c5b3952dd1266633b98591ac3c505f34c8b1c77e5bfdd9d6d873953dfd27f6116fbdd203545cc431bbf4fb01cccaf1580bd90330713d0fbbf1231b6dc2561bd207a162b3ca544ea9dd94ae51af433e120f068f908acd1246c2b2075dde71c60e3cfbc246d2fe868b5d1aa36cd994d165e56129d2d88fcdcf59b69672bb1e665580d5500c34291235ecaa792fd8570f6e6b4d17e47ce61b0147c33c0f9c842b0f34331a9b5951eaa59961a93e51104774705a0f595c20b71f55479b1d4e36875d58912c507da512bfb6d854cc91dcdfe2b66b8143614fc0436ecf89fc317e0a852b1305179c621c0357f706720071678f1745b25cec9f53ce55d17a183e4b70db70e0cecc42b148e48e5a371ff97da554558b358096c1a6e978b2cf09a899f4b2810e56ad6f30b4519ce6004a4698a20068d698aed91b63a7e25baf1eef9efe62174451fd74e9ae7a51da31f50e0b1551dce4efd060eac0f6eee55560d9e71733073fe5e2de9c47e8add32337422c85179c8f7cba6841c43eb5a369cbef07d0718d84b2ab839f9e1a3d5493969bcd6f8bf3fe783124c2b6cdc4b915dff90467f49720f0dc0605733dd113992bea19a77d91a9651a1e792af18def9698a0d72eecc9f8e301c5dede86744bacc100218ee9d4f8d0243fd8cd5198b233799e33ed2f34e2970b17b332024d59ecd6cea5e6bf79b530bf95158bb5c84ff91440bdca15963cf8916b0ec0384782e9ae9e8f03031a40cc67c1bbd4ffce51912a1791d20fb5d80b7dc6077042e7d829c5ea0e78e195812aa60b28a92c07ec25634ad5b6d0b3204a1f5fa6453e66cd376cd411fc3280bdbb1d0055c61b9c02fa4861278fb816719deac5618114ba17f542b4fdc90959953e95f6e72665acf1e02f4361117540971ab5fa0e7c10900b0ccda3508b70c376b57fcd41f77d6149367df3b34250e551d8c860bb5eafa6a4e892b256410c46ff67630799d06c45745c96fb9632978ada096774e9ac45c8ea0edd9bd530b641e2aebc74c52fea7e255d061095a8aeb3be901250439bb706ac49bd38e28ec43d5005a3c743dbec431185784cce36dfb86d2869593bf1eeda74f181c313fdbcc9b472fac1ffef50b60086b3af340d33ef54a"}, + {"00000000000000000000000000000000000000000000000000000000000026fe", "0076543e7f0921bb345aa4f261fc16b5dc8a13ac6f73df25b51db48c61d38e3bc7b57ee9eef3945ae7ca229d4d4d0454dfd8c94176269846c862827ef486b57efee6aa3264c1f7c60ef9acd872ee32ca0b9f49c908d53d3c31dd9645f37391dea0b230e26cf27ace8c51263dfade982e35a01bc5c7e3393cef20441a6b9c10620b5b97cefe60c3beb338fc7a006914957384dc1d70fea28a8e2ddef4e14312b73035c51bdddbc2fd00b2d234d99740adf366436de05483e5919cd78b5310990f980514e7e55051e34509f7255b2483ba18ea2a42eba3c5786b63d26ac91344526c5f5549fdfe5f4e9c3cd8a31dbf06f23dc53ef76e5bba37d57ee207016c8ac05ead2991e54b7234682dfc0d24bf98882506a57ff3e1cd45b928ff76623efa7eda7484b97b1512e5816f65d598fff6714539174746da3e19df4e8e4187e4115afa9da1f20c94234168744e425f5ffe9600a26cc76dd0505550e4c050327ff24e649a93f3820e530e5f816a8d51a14f81ddd677fbadb4f25324bc02571de3444b82b0afd97421edb1dbc945a19a81802bef6382f18c91196155969dd2ca4e39fc6df5ccfb0343119f356cbf796acf839de5d20c76182ddc8e0c2e1e326867e82f534fe364f02a6a217d7a3a18aa7812f82772a276825fc39cb2ecd1a91f6151c4daffab1606be448109db4cc88374895db49d8316ff5b4cf60f6a716bbd87bbc83fa9141817539e361e4c3ea19a400044971752b7a98d2247a292efadcfb4f97e16c7155be91d0a5060b8d42a9460ce551f3145b2bc531316ed65258a6cf111adec677005ffd5ae56efdc4b53142baa166587e03962d522575c43f64a13bb332af32b919517a66038f564b77385982ab1d1cc83f946f31bb516826460bf5930f182e438eda5da36c85373be54da04780ab375c3cfcda5ae15cfcf2634ff38012e035f09896fe9e373b20a80e4dac8fda848638ad36805474b4692d7eb8af1fef908fa6ab94f1be2d98bad108f96a5d029c91fb4fbb25b96fa725221405f5b1520bf67559f5846f9f56d4322799a098d95e8cf72751e2d5c9b5f9e7d73f0d01af116713c4ecccabc50771eba1e16ffaf1ca9f975a3e7add075113b119a3f2b33efe791355a3829128d0697d3e4f58aa868bf76ea3c8b74d2bca39e855fdee6fbb0fb37269aea962d6705303b9bfc5813d1ff99a0c2069388a520379f944e0ac598b544d886ade38bc5154f5165fac91e96571c07f849b4118a8898aecd70d903529f62f57b58a5510aa4589325a1e25d7d20921a41d1e9d9e3a1b1aa5b054b714fea049a16a6cf4067b44477fe33481fce8e06a662f7b91032ddeda4309c99b0b68258a4dfe290099e6f740390ecbaa4a354eeb9b35f1dd345fe59742184d4330e32ed41d86d73d2df796691f1069be93b07137a8545029cce34eff3566ee3f70d368f5d999110d8d661c68c55348eebb3bfe2cccd233e703e567110939a6cc48b8dd74f01f292b467225154a033164d3e162f8914db6923fdaf364c2f42a17ad3989cb9910901cad94543902d00ed5381dc3bc5c9d23794b0cd248119be05e83839690f2d3ce77625af60b05fbd220d3169e8369736e1180683eebf49e11d6798fdea8116e9320cef6a42659af786a468f9a32e3f0b1269380811e92c031934554aa9598646d71d8af10f9baa9d0d6284596520e1ffab3908154ac44c6e1737db2eb22b3fbdb58d8d4cb09a0f160aefb783b66c1b3d645d45951a2df4d3f4c3870e65675939a13a6ee89f5f170cb76e623e5fb05b429a76882a557082720a7efa7f2f05fe397b90ab81ff482772c34c01331b7e7dcd7c13403eb9b016aff0d1f4b709506399da40f89440c8152aec2a2ad4a3d7b3ebc91a366aee5b4dd2ddf9fb"}, + {"0000000000000000000000000000000000000000000000000000000000000cfc", "0053689b781f1e8fffb6a0767f5a9fee99d7f5db640eae25fbfd84a9410548732b02771bef4722fce6750408cb61be5101d77575888ca0f6ad36dfc53aee880b5c031a04d84d89470de1f04e25ecca4d43b7c451007a37a7e111a0b6e1df635b74a55718e30af326981b7ef4a227c8925cca36f2874aee43d516d6ec23f22bd3eb3a4e8fc52154d09553edf3bcbf4ce0fd7f5449cb475258b7c3b5ca8d275e17d1870f1a9819eaf300b503c1124ab934788fa407125084b59723ce5ffc0b232e91841423e382e281e09aed7782b9c4fecea00621d64f4582ef28594d25ff7f5007f64c8bd6f5e05fbbae0414d8d81bf53b98974add34ce6f64dc16580602f7d084b360f5c8a944fad5ea17e160141520f51bb18f2ec01625b106d102083b94f4e8db418c66fa075e7fb1dd0882608f91f52a2be78e5ecbfdd6a73f71a7cce13762ab4fc19ff7620dcb95eb562b1e769d08c6c935b009cc0d0e57f100b329e9d1da79f69036169e2cbc6956482513e7937823bceda16217eca0891ef6d2556a1e6707482cfc18ba7071272ef31a0bde2a5d93b29cad09e5be08a4f8c1391666c01e7834690a2a693452b07bc1bbf100d0f08d85a93115b74f4e10bb2b3996e4dfad594de2295b600d352ae7549440171cf8bf2fe3c41d5cf2d271e9ffc0152e5491892d264ec60847907bfb68591498cdcbfc2ae41db8f7c70d84147e779f58b3d764365297eb1d1deb599fe23b397a76658cea9eb9720a3837f9d3984e8c9275e9af1d5eab974ef90607e11d2c9b1e715be33a65fd9de1226a9944b0d9c4392aeed379493b178b5018ff3a2010b820d533148e66f91b25f29fd51509f4697ea604236e12c3e7d72635ece7a2f87e43bb70cf863be68e3303a48243dca5d537a173c39b58f551092ef0a284456a364c8f9bd28f2b3b097d85d9181f265cdff2d3014ee7c641df0e49426e155806e16161711b93332a06e6a9af819cbe2b077e820358b99c7ac954f89d47046404a465d6ecb1e6b9e25482cc4cd580f83e405535ba759cc4a4e9798a1e2588cfd26fc969675e063a0612aa1c5e15279b199381d3249b8bec8cf4eeda122d303a654b957690cfb655b4ede8d3c5df2fd4171611a75d3d05d0d330cfb6d20ec4e47a3d2e795aff0e2640abe0950b0ddd4fc0836ff4eb1a3e73e31f0e99049808296b9826a18369b7f20dcf31e70f38fa16542c2cd334c2d23eae9f0a268691ef71f5fc91385fe60fdb2329c95bef4148a2724687782f5261877e372c1395cb582b335911b6f54456a0c43fad1748fec0da167e444b6c2e9703c75921f4ed51bc149df95919c22054ef98eb1cdd416542624888ac4a58db834d48272b4e8f2d1ceaa1119fe4c8be6871bb43352d7c6251304ebd80f14ed030af37e674e4e43e4a59e43a0aad0268a6fed7c2298b2fd1109032c22c91012b6fa2320f0c27634d639d6df747023b5dab0bb70143faaf75085695f4b5904185926ab480d93c48628cf05bd9fa09edcd3811984a7ad45d29f4e7ffaeb6f72d1f87cf047cfc5c6aa697cfa96102d552ef1ab5a7cbd4e86f3f98c41ec990ecb1973fe9784c7a152a6bedfb1d2c1c15836e96d024f1ff2fa1d13fcddda1cd2778cd271c2df14b4b135823cf73d3db7cb03b3e2bbbb73fea02f47512b84272206c34c43ec5325bcf10ba3df5890f050f746047bc7547495117a749dcf1b50dda85380abd4114b1ca6b8bc8aad3a0866b3bbaf9ff7e4f491a925904e195a36711a047a6eb3e7c6edb083972791d6893886ab4aa6fb8ce721f8a1f28dc8bff52ab6e2c3ca216faa7b775e8df3746ffd0b25a4ccb3317bb22d535d71a1f5655288d235d699b0f4907f29202724181139d5b5429c8dac6a505a5f6aec980373482a8"}, + {"0000000000000000000000000000000000000000000000000000000000000836", "00747b2490a195794b752231ab22941d124b097253087d2f12c4a56d3fbc3d74f5952d605a780bfd44bb14c7beeb58a2a1614a2581b18742e900eaa02de062170b5b274e0bbd57e95a441bcda6185b11bf3fac4a0242cc19996039b34fd492e5983955891d834e8fa910263329c8c9735eec249842eed3c8febed8bf07101126c3dfa807a6c8ddcb912af6c31f5757d83d58b2118a9cbc9ed6179979a0f50537e89a257d6ef026270773b69261488692a523b35926a2c20da76e0f27e316f3e2029b18934b4682f2c211705386f2f59c7795172f7b09f28eeff4fcdaa1bb68d805e99493bc6e78438dbd858f29ea05ad49066b14c5978637c7984cf91807c69f7ec99f06e5b3836a15ab52f9735e51a1db1dddca1551196885f82f02a2d3fee29cd85a8c63772d623fb17333815da127640f63ad41d5a51d9840f53436ce9d43b3ee67b84b841a24576bcdb78430f34a00b42be43afbe283f7d631a0e1b4bbc1bd8f38e6ca239b463bb74a2b237bd233b5117f44dea09935697012ad23cf6352e38fa280945dcfbb73e726c07e3fe52a115c7374b8704bd302230c31ec3918d9e44dc8750b35ae07bb086bb1a7bc817b64702e89fc12dbc6103ba947f9004fd9dfdc97448be6caf485a5e1dacaa6126cc8d42f67296f687311ba62d807d15a74fc02ff22636468329fc9af4d65a31508fbbf32f79699e19102aa6cbe0f54d34d750ee322eca2652158bf4b265904852656dfa2ffffda3910c3f22c0d5d308d0f9bef119ff67ad68d8cd4dd7f81eb6e3b61c6d063d9e2e92637832a77ea16abdb45935b07e6a48d549dec5dce07b75eac59609dab8c92a220261ef3488a877dead3134da0ace8295f298cdaa71836ecf33ebb90dd64fe1a91d7bf11634cd7f6c6d28f854a67f3b4099f7abc7c801ffe5375e17fc44947f218d99282e4b63eee7e013936322c12c420a0e731db5bf1e448ed4d9bc57e13fbd62d249ed93b7b0b15861b6b3a675cc85dd5520989108eda0a93b4a0f8d70742c524726dde96c1001cbbb6516e5d421b1afa8a75cd7d6966ca5dd9e281054965b89f0ce9f1afaf64297b582dba65e47a78231d2ab95d76d2c2850f94e4ab34c2dbf5403950e4dc1559429e3c0805588b4891bbaafafab5558f3de40b2c7a7db305921cff13940620b37d0726eb92de69f317b77cedf1e13c55bed3d2f7b3e3b52d43755c16723bb87bf9e31656f19f14796a0a682adac4aa1c884f1a4bbf322595d811c3ef73a76d1d9d1e66b6564d1b4eb7abd30465108dc2b60705d159d02aaa8999eca824628ccf0d4a81cdeb6742fff9d29993723bbe72843b84a27a1c62b11d30c94571865489c7988adf2b4428fc29ba4b1805674e28b751ecfb043b06ccfc5cbd5910d507751bfa69c01b56573d7a8f76aa46b5e74e03c238f6d2533f14efeb353ef13808f1950d52e38803fbf217e9014411996668e1c24cba16457cf4cb400577b454c9979ab19c4684e83de06b2dafce7034be26cfbaa28c1e2b5987d38293769c59d1de105523b306f20b6eaddeb7e3145cf4b80e3b59a5738652f03f1eb77a71ad8ac526a1cb033ff0f266b52ef050d2941fc6e5f3723a623be07ac226becf8c34cef770ccb025f6ac6741141c913013d3d7ea46a82d5ffb3cf21105bc6874f4461783f494c963515d9aae6ade78634e144795bc1dea1e73b25df4c6d8dbd70b3b54fc950b0efa86d56408c8370aab51f5194f1241d5ecbe663610cd55cf84b6d931dff951f4d9c98500f2787de8720d9a5ceb08ceae3399215666bfb631075e9e5e8b4318bddfa5e40b279f14bc766ce3bda91f25dc5a1aac1ecf5d57d5888b29698fc55caac478d9bac5ee8ea1207a3b4969987e9dfff5e2b20520fe353b7dad6c42"}, + {"000000000000000000000000000000000000000000000000000000000000381a", "00031d3459d877ccdc94c47f5d3bf6d5a5c51204136475cd28eb276957ed86b78818440c422c4c5a569604759ec2d4c4bed2995df3d39a78af39901a0fc551686f8edbcda0a753ca48870edb7cfd9e09725a2b300b610e19624b63610b2c34d04efb970a8b7f39dd0410fe7dd340187b49732e8366e07f1d71bc307e54742ab3a59c0fcef57736143770c7ce80ff89847e808f67573efd70ebf101b8b30cad0e6633afd8715edae0067302ca7da030f1398454e4edd987fd5f18faa2d41813036bd5edf6b1a47761fec53af3d8d75d5b6b873b807408a8e6e33988c994f268d7d77541fb94a32d4533f72e70d17c74abe675d9774308068de15784c60ef60e1477f90eebf9b29309eff7c0d32769dffbf21392e3a18811a28f1df6c29faf1cdba8b1b9f256eb212d27e1a45443a19bde3599ca433b217a70d6fd392e2a3af2bf9148ab333d8422bf63fc656d36d9f1310278169d3111b40db0fa94eb45375005b9b9bc847a154229e47c5b0d5101f67833d97555fa79da1b102d19566b7cdb534e1b98e0941ee46fce0d432536cc6830c5a27586e0ab9d3850e5114cf33a42d351fc523027b03be4fa726309ea3ad6bd42c3477ed1117bf9907f54165171b0e809ba26585f916adbf65d7adf812e357989e65e62d7d563ce448d25fc5ad9370dcd9ce543783b2a4e6ef0f399ff36548ad46cef1b235e2fd7039e3fcf198b323f213db676163f784f53283a9b8424b82660d18c7269e26bc357bfde4bcb68321d442b06f816d09b0ef1dd07f6b3d9b3e24e29d9955e5bc50f071275eca982db742252d4a79f221a0ebc14ae0b0615e250ad570a52f942b5ddd3deb45b2d2fdb6af83dfdc67e0477e9d9c24a36ef02e1ff62b460f73832216ebe874e5079a11346e9be697af9d6f8429eb7ff693625368aaa532354e9b7bb0aeeeac6a91edb7ea80038877c584bce32737be215d8cc8c3e267792ba0a07065d4a0959bc14fb1bb39810233df73447dc6577027057e232125489f0a8707fc84f82b4c5f3f913a31a1c4e73d1ab9eaff751b473885cb5bdd16ad9ac91085180fe21972595ad543090bad2f46893dd79073b90cda659f66cbe29f5e10a89b8d6561700e6398e941fb85b28270afd7fce7564f2f73807aa6d47d774a0514a9f9d0e5afb03f70d55939d38d44da3474e5f9302843e3fc682628dda6c21014fb0475add71dafca80e5616825899d6c75fa8022940f78fb220501e0c19131c0de8ba5b0da6e5fc373f62feeeedf9167f63d932f703c59995be74d9e395c39f3dbce770215e2bfa0285bed0ec3274d1f514514ea81b7a74becb34b5212ae9ce81abcd32550b077870d7640eced31e1f8bd204a6b975f1925639a6d54369b49b5ef573646cc8b83416a3a42a9da2cd9019752a94fe5e715082fa446602cfe57b804651c6439ab31adb3ecbcf1223f94897051496285c144655729fd578144819927568fae6b50fb8eaf34c6b4da5f329871645748f12116f15f9fe46809cd9cb713797d7fdec04e5fbea0b1e82fe4036038b004dc2e236679ffde054ed8e18547e2bd5e7782da3cc8463cd8524d65da2f68c4784112c6773eeb70722ae3ea982a13090db11cfed10715e67b3d99aa5156db5005cda71e5575883b373abd2cdd50b7519bc032d601d25dcfe28f83e529827b9bc2f0ecefdadb1331a7c97f70ce5527ca263a7f1f68bbac4d67e1a0923471dc7cf4b5bc7ae0b28059a4bdc56aaa455b08232cb449cdf134de9114d458603dfaee6a1973e56f910e9bc74641623ed12e992bdf32c4b1985459a0e0520b957af1448d9dade2c23cbce2c0121edd45adf4623c014696149c76387220b1aff5e946f273e7d2d78298625429d90e1e3eefb638d68ef59c5c23eb83302"}, + {"0000000000000000000000000000000000000000000000000000000000000270", "00857b99c44b09aa8286005e75073e386a62b7f59c165cbefe6c301f09f41b917cb11400fe4133d9053c33ef39ac16146d213400e9f03bfdc102bdc09755825d0ec69fe6ed8875e2b06702a47ccbbe88d3d7c799065570f99605a4a7f9bdc079e0a1fc303ff65ee0ca144196f10894c060cc71f6817dd53b9ddbe491c8a424e1a982b5a320ab7e28b33acdaceace1742b1d7962699c1fb8dafd4e1e9082398a2ef55af82adfd687601fd63524a80a3b75d0cc68d37421f8e416e581c9a1e2e5917b551f1cba6cd071037cd06161b92d8ba72128c4cca478be1f1d1df83b46e541e791d1bb96cd41741cccc4461033928c8d18be3a241d2dbf53b99fc1d1caa091ab5b34ffcf582d58f4c15c1e4c21502662faa99fab04d1ef34a9775772ddbe7aa78225fe36d41f6d51bdfd17464cad776f628d38d39fecf7ed05a5f2a8f87adf0dd15d2ca2643db3da1f608753a79c5018dfd22aa04bd5240ea20a9ec7a810a454ad9466c163ce472c60f1842f3b1e19d69972c0c9d0fa6508333a8d3882170c6f5eea5f373062dcd214f9e8eb88536b86f6a23d31428b3be2676eb59a4623ce718006709f282d693a2e543d007f2106af79ef55d9098d6b93bc7b413225d906358a27790cbefaf02eff279a3a11419b78c191a584f1ffe93743eb82031f85478510018bde1555eaab79d8e19a73073ffa0b221835a77f9019e63aaaae043530266a4a445a796b5f904d155b423bc8b84c375d321ef1f95c86b5d5eb28e69d72ab40b831d0f62d1b81bcf4391a3616e7fcd31d30a2665106c65eca15a9eb3d3e854e0f3ec52a53913d23110037a7bac5c0559e27b0465b5b160a4eec290b7479e241e79556c9bc18190533780ca5b7a86b2ef17c3b3189a7ceca20dc70169f5e9cfcffb04f71b5bbdf01586afa5883428807fc808888a82e1e24e466b3f6eea011da3d6c184d2877a81311e6e7429b3accb7eb9f708e1642821c6300fa7be00923750525d4d4eb2d95201fa4bb6c8c8e638d72df7b08d40ab7e2b5c148c2065d894c38ff31a9dcdab26dd62470c49baad11e83f25979f3753db5fa1609a167d285400fecb2d5b91725a267ce6f4d71347c613d785cac3c7429db5de88d642331d3d3014194320f785b86ebe58099f17777d347c716ca383df6ea78c07b8729a507f0e2dfd9dcd7f017c6ba2751dc1c91e5098d6994c4686b8d1f7ef7e28615572217097fdb3f1329fd7aaea2dc42d742b9804f9c8e92e90a5e1c969b5c2717ca6e6a11e16c71e2487d1753889c5b36c4663488ba0d210f5d1d19eba075dc8677c50d334d73f370441f9275fa4b8de7f4413fd575af510041feb78e41353afec8587e19371511164ea9002d97a64e82de283895e7ed155be18a31535af43a1b5159a2368a225555fd3d4ae514fdb279801a8d33a978e556af97de25ed81f15b0a0b1b94e551d4edca48b199fd1afbc02aea7e77e9a6144b7312a05cd9965eb94e375d8cf55cc54cdceca1d379873640f9144be33f1053fe938b1afbadbfa8e5173b6032405dbc10148d277a4b2fca1880af30c1cbb075678861f93b410a4d63ba74375932b7d5385baf1a95930500e19d593e3d2c834d860e277793dde28c621b890052d3a4e7b5f9efb7b1757f2dd207ffa7590841dc62f01f88b65f6228d4715a57056053576749c6a3dd4d11191c3c1e5c6f41f080aa2773e4369faa37f3979c02aa4a603730c9a92db76c41698f529b2da461d8f303a8ab4472b61b963b406b68429d62b561ef83ed8d417865c76681223f6be6259311a5b2e4ad481782bb41e8545b7e1d1f709c9d7b62915ef554db6b350037b3314fbe3cb2f6a03dc6ec3c75dee54b9afaf73a27844bf0345979179812425e5221e57f176f9fc9d93c1"}, + {"00000000000000000000000000000000000000000000000000000000000008a5", "0003703e1f2a9869c342406284c7d828357c1a5cff49a05fa17d1276b7b80084fbd2d831338b055e56e411b4eee5d0dc950f0c33117e85e2d5e46fc9ccda883a5f67beaa91b7b0da00d79a15e21ff2fac3da0d060305a55397c579943cbf69df1a69da32c5f31df15a0c3e4611c5a7fbadf8c6d2d7715d5b7916a65cb8950ed98e1d2ed5545ef46b64aa7dd8d30a415d7389c41801ba308814b7397535579322c7e6be2ff0f5a4a802a68bc49fb54ea5de3d73786ccae32e1e043bd7df0c0452747a0a5e41354d01918bf8b4c0aab27f6f4c12f24ef77908215bde23516afed90175f69759db1319d12415b8c81ff150cde4b15032e021d050aeb3be151e35c939892cd529c8918cd0a39fa90f27ce58812d161cd96ca68c87a667b807e3d9b91ea2b89d025e22abbc345e5fd7fd5060a44436d69856e7c01a2a02278d9e9962cf437197d1c510466a45f777445d99fb027d13bc6b0ec90c79b6620c655ce7e587e4d003601db354f6d3d6222578bc221a17b7f229381c8bbb260cff2e111ba3a62b4780658c927de1aa4af2b6b8481c0af9d032e4eeb5b530c1e4e3fb2cfd34630aec2606fc489c34c8b48725bd5555df2f09edf44d9ac73f0b1bd3607704f1659395114fe451fe5f38b03e9a680fce33a44d952e418edbd4adbbe957761228fd19da2d43ded32c93644bdea5e4b4ad58e465fdc259454f069c7a1bf48c8c1f91f3a45568f5eab66494da0cc62d49860f5a9092d8a4aef3230244271a77aa355358088ed8d9ae08df4ea113c3822a370e01de34aef50815eb7e3a1a58a224f5df743831b6c272f47cfdc00a14e8f756a118c444e829e54c877dfea957015c038f1fe22eb8ba2489c16c801300a4ffeba59f7dddabbb1eef29f075ce3e8f7dc865c49e32630591de74d2412312076a6d1d797dc2c1c6d78df31021d2b772b72102a697b863d107d5abb7627545998ee52681ce488814a291cdb3c859f3ae4f06cc436a5ca23b82bc3a9c0773259a288c9ce9f4e27a5984e706f32029bb88f61ac35707a2ced552b5158516a86bce99ded4dd6e0d2319beb6be1540650a97a410026a96712eaa6b9120232db16402d33fc6acf0a75e4dcd231e11a8542986588f777f0cab1fcde08b0a2f0cd2ce36bbfa97dc5069289dd1051bf506f17f1726ab65df45d414baac8504fe052f2699f330ea42b13b3c9af520f8af558a5d34dea4ff68964f26f4a2f35076dfd759e3a6afaebd0f549932fc0590dec9ea3505d16daffeb940f8e4a64507f25a2ee792a57097846b29524e6d8618f7165f0c276eeaaee776ab69fe217f66cf05fd8afa5fb45d212fbc2ab10a4ba7d49072874ff4dd522229dd31a9184721323019aaf96551129e94171811d1dcfa331f5f3686ab7ba581a3a98606e35bc5555dbfd9db4d7c03414d7d8ee0eac3103df036bdba40a8a03437cce7244e1f490e1e6c275a6c059673fd6f3985c8d8d5640bbee197ee4a2e832baf6231a447ec79598c7cd4723227ff5f2da2a23155c8e607a9b8da6dc22395f28f07bcb399248adb0ea77440e2b24abf5d849971ebba0f232e09bc68e7f1968763e4ddfbc25eb2fefa5d2f165a42fb67d606cfc3ef723ebce570856b56fb5b4e2a73fb4270d8ddcee3dad7ea03f8ccda177f752e1e07b23ba68d686c43dfdbb2504bf13b8e08e75b129d0df00241679f72efeeeac389a9a964bced07dff2af08af67710a939f0da566d1ff1813b4e0ab4e7f381e78a527a688a50a33df79bb7af4f9da8f414f3a88770979bda57b05cd2ccc26d520a5bc708bb4859f15074058ce3bd71beb8f94a618b6ab5088e6fa3abb8e5f0ea9619b455005bfc19bc3ececeb41f103e1e97ab632692763b4a3ecf3e8cfa3e287673c21e6b30fa293"}, + {"00000000000000000000000000000000000000000000000000000000000000a5", "007363032a9d0cd1045df0c6a8f541d440291263e345ab659bba2e83efbca3964ad6f3112f866d7ebe6909ae4ceac14a4ae28b92d6f2c53e77372127fd2e3f3dcbe1f656917a9b4fcb7ad26478a56ee3b5da4b730eab2628d1547d80cda19122c5ab06905981b270d232cebdb17e4ee6d72a50637da7a53846530b9f5e26308323114c7c4e4bfea463a16bc23af637941aee148c8cc6dec67e70cdf389298729e4db5f1eb119e5dc05ca0bc1beeb5651611d90a370caef967cecfb2dd91ca8d4bf570886f5ec21552ba13757c37405de0f360832e61222de1b3da3c4b0efa2ab080e58cbb629b32f9e31f5585134c9d405347aeb4477be0613d8724a07b55c581a50e380cbfba468e8d35c1e05f57789a10ad7748fb9e61711513091a09d1b9e6ce725cb2b7c0b12e9e545db2d9fbac3560c5dc8dd35f3ec9b88c5105c4fff7d5cd5a9f5771134c954a59d30af2d444d008088b3a72c8cc1a90340562be178e1f531fab56e075075010d05ac0b05aed195da19b7311b97fbfc14136369e33e18f696d18a11a07f461fe23ef29a48407cdee5ad2efaf827e0cb88eea0793b266ce79bd1410096ea2fa7727381a45ac1dd59f538f15e8f333a000aa46b42220c21d666dda1b4e6f807177eddfcad7014c7fd885cf0bd5df7a1f48eea4ce435ba0a35a91b3cd8e786c7194235c458f578a2d5646ad2b77ed153033feda056d03961b39aa45ff641858d5092d65b9e097dae4d80cc3964dac4d18328a41594ca2dd0ae6d6159ae53b5b0cd8de443b80ea0e776c789953c8e507a6ffe998d26f227ff7e6c74416a10076d97bdcf980d66ee329e7565d1d639b3fc285795911fbd11a67f20a20c8201d557fd744524a07df8ebb5e92b348eb22cfe3b854917532d364442e6de35a3c1df9fd694204ccf44a170df99e50408052349ec1d0e95b33fc1ff01ace97e3886532a7db043b4467531edde95f532661acff3f5f8973b8b5d3fd39edb756595b02f1c40320cd8d25f38033bea8b83fa350efb4a9bb7b69e06a912b414df85d6d1b77d4cc34ceae6dae8df29f17bc204ddf9f2bcc4e4fe6394b362946b716ecd6f7fdd9c2c5193c94adeae85de2d983d75e04b46d9187fde1c1ba32b3488d9eaefa37411d22762034e8832bd62eb276db7d4641fa9315a1f936f9a2e8c21cde95c9af103dd48418bc2d2e0fa388902f6f62cdae2c07e79810b477cd7a9d528cad45d1d707a77c95762ad9fa0dd1bf3592bcb920201a6d6443b4ec25f21c38b346d5061ad73472d1c3471265df8293e4f21124e1795e7bc0758a9bc840b4df4d5bc849ce6fa89dd605334ef650c78775a8dccb27fabb993246d458365a62f5a60961265fb2087a5a94da47443e8d3ffab5994eab3b42e35cbf9edc7dc2eacea8654a0d2db7af5dcedd5689801c33561980b00010fd5151dc0fb3405d4f318f58009b50e6cfb4e55d0970cb8a3c9fe88f2beda9c798308ad87c6601b492dd35d26c87bf6cd71fafc3b22151b1d1d147df86977defbc386a6424ab66cec37c41f054399c49bdb1711c90a285cf57fedea1c6bdaa679237b4c199038c07dd4bda3aed87cc7864f597ea5bc05e7861d81ed37ab99159467274640a93fab79d8f808023faddf28a1cf9edd0507fec56705f14c520ede02cd2bb7bd0438c4c55902b857ea2d06a9ea971afd2260a588e7d9542ff0d522a98a3f372ea5375fc6a70adc25f5228c468935e7e67f44c11021c16638f795133d0798a032c60ba959f8d864626ad6a7c61b94ff0436b1c9b20111f48207d2fa6618c0d1959a7a5ba10cc2af268792acc4f697d1b20e8e34ea8e399d39151f17b926cc13b8d5053a12ddd5238f336a1f3c21002a759bf4fc5398e584f4e38517f1fc113efa34cadf"}, + {"0000000000000000000000000000000000000000000000000000000000000556", "003d75ea1757f9575803925110772a5a19c5bfc0d6097944e897871a13dac8f28e009f42657b13ae49480346774a6fe17d29d9d790c2f1793445e1253019f925598194932dad71e326e38c13f53909f812b0f663044f099edf42d597c57102f8369a2579fb5bfd54b90513b7457ddbda2b06e17338e4c24b0512885a0b9605f245ebcd072145b5fd96109a6e424336499fb2c325361a2b4c0d3b5eabfe8336fd497de6781dfb16130177dc49a096ce4b67cf31089341e5611e4fcb728e14ed6c193e321abbe068c1db6577c2549379f97ffe0a184e8bdfaca6bfde85b56751acfa9ab81199812430ced3db08a1cccb5d0ee3c031a6dadac9aa96564604261ebc3ecc82b2f7a7c1a882ef3c7a0dda35967426001135e51a2b5d6712836d9d780dcdd3b11cf78b1125834f45ce22c5f30bb17cfdec20fd82325199762984bf6fe15cc459a740e50006e1a76f1558fe87780111777de880ea5e170d708346888a3064f6524ea4064efd3ce54f889b0ab57887a265dafefe183c0d9a0aec8943821e842b5fffc631b0386885c6d21dd64f48c555bd8728b82daef26a49bd7156069729bbe12908dc03c7811fb3c7e94f5299996db0662d26fad60f19fdd4fc075d994b2c2c11e8d4aadc2dac50f31f700fa5bb4cb049cf6bb80ea5c4dd77810653663d40fd21baebba9d139818b0b2a6e249f55075bcae5eec97071f88f814cf85453e5b78b7894b5a0e4f953386b927ea3e5c708b494b736003de3fb7df2560a85547bf0ec2167578f1653bf5e175e7897226f6b2dc1da27240e85da0e8a2f5f9eac4ebb2b871076afd967fd2cf23cf6c35aecd7c2eb2a8f33b0da55424d2cff8dcd84766952249da7be8df5ef47e8cd547e152161e9c48289759c91acbd4d8f8fe4472cce3e6baf71279c4603ddf52f0e8e634fba79ee5704e78fa9572cdba53f20096448c7e44a98ad58545cb21be058677eb97d4262e66b63d7233345dab752ad96fe5ecf30faaf9fedd350e37b2c6d55b61f94666235dd0fe8b29a47f2ff35c1596ce9a9df163a423a5c984e97e7a3b351e026b036ccc3183a7bcef8c7861801df027736b8fdd38973005ede5798d37ffa39e5479444d5f6b7b427dab7e1468376746255fa16dc65238cdd30d8268ce7cdfad32d69d8786df101fcc6ae5d615ddd89ecd6c5e10290504ef975a1b5ee6e55ed19faa7ca2cdeb2a5f157b22b17d25710967dedf6174033f655eb90a4a70feca2d50c42efa90061fd434183012631caa4fd55fb5d730592a50f8e35ce1c42f26d617ca463a0e8bd8e844065f2ddaf16322cb73875526cfd6add22f7bb4d00e68ff4c2520245ae92e065a0033eb183eaa7c565ce210734c1a5f1d3ef94698732802cc2ea305f17e978b1e5d816ba692093090ec727a9b1e5edd265f7970c701de2c086ab0fc21dfc5252944c6697e60aa1d45ba0713c9331a2d49f3f861e3810770247a45c479954011d84196fe616939d4bc87e3dc4058af504b1b71a91236a179be47e774d4cd160816654921f52938f52d03eb8b82098b0ad9dd6b013446a071394b8bb2fd2354f5cc85f61c579d1ecd7895297ce2de46faf40f7c1269efae41ed7201c6f1559eaeafda2360ae1b17d82ee474229d912a0f6094a3bd804d9e2629c755060002ebc7ce290ef75fb56781f81c6c16ed367b2c06c77a845ccd74e1442d725c298cd9f6915747607d34a80ac9059b0e4603cf97e752a1f5ac1adcccacb561de0f707f18de4a7ac7b4dc9631053d031ac0fd381a6203930bb65ecc0b36e1b1d262cfb95f7a585f95795d4334fce09bec601fe7d3b505ef3b5cf54565b185a40d04621d5c4ea85c8c36415498c59e29353f4d994f2656d2f82692dad593f3d49f684cbceecc80ffa29d"}, + {"00000000000000000000000000000000000000000000000000000000000007d1", "00aeb44d7e06121526c0422e41f0069e1a2b9f4a020afd1e6ac00384b84d3d53d97c7e9bdd80cd1d9567021ec9c3704b9f28cc6f725724aeacd59b3a5234c024b5e287a6a86653c0ae156c4cdddffd628c32732409e94772ecc9476b9e8ca34bb3a6c434db5b301af035612f583f0f02d7efad53edafdc1a314a991bcedd1265a58749e5c443b0d891e12c61c1b16cbe50d9e617c5ad1b0ba737f1fa3921b7b968aa75da167e96fc02c6c74864d76fd78c9218d5aa6fa3e27a8f3e87160fc9557b8c0d1bd3ad37219a355e85cd7b2c17cdd60727c673606d595bcadaf1855b34dcd0f9cdbb745c3ce3eb235130dc7bf1230522553cec4e8cca155c3702e4c4dd2524fc47dbd7b16a2ea90b815c2311dfb5178fa138d65277e5e125018266d534b1e997afc21003ef6cdcdda029936ecb40dc63518a7a8a61b5b4900463a49c160291cbb03e725d116d3a4157f4dcbaf50351c8918302df255800611d5ed842d8b9cc660ce704200bdc664656536bb16939a5f3e092aef657cdc30c1ff956e0ebc8bda4c4760c7c5e22cde9935db2cd1182a427a25721477bf7f48a2b790bbd5e982cae960408558035c50793c39283f0b7c649398faa3e55d834114cea6bd72617d809ea2c4276ec6aa274bee2a9144357325d49afd9cb13717eebf89fa50b92aab01e1d2d2f6dc4569b7b0af4762d41bd4f11b4badd2433074284266ea281e13c1c45b70ced9d6e5ff09358c32345d7deafe7f4519557c7f33863c6a299f0b834783e21a7f3f8735bc1f95264327c5f5e098940de415854d6252e0adf7641c35376baf343beb1d7b57320e316b1e34cfd8a219b273e28da17ca39766eae154fc61c98ab96e22665a534f3562056e118ba623c7a87872909ed07ebd481afc6fe47d711d7129a8fdbdd56ce2c0c8afbaabd1e11eb163311ddb0a88594f537d3c80271b853dac925b99fa9114287ebfb11b873bb96030994f9c9758b5a96965c339ae7ef97c2c11d7865fe0fea5a31c5e2a2b1cb4d45fd2af0081eb10cda581f703b3d483e653cbb6363a9a31d7ca7dae0665ce81805021f432395627b50f852aaaf43a8cd432c1a1a463a793bef4bef1015df442474d1719df2a769f73eee22f341e14fe2db5525ed86df3cbff329ca33f228e8253073053ed8488f445b32848ab4751e4cc11963bb041fa557ae8c4db7e27100bac59e8c1c64c9b777a416c5dc88ec6a1bc1f13a4392009fb6ee565eda6aab0b1a831a9035d49bb10497dca74daa3efe9c3ff7a253ce7d2572a894997df188d855ce02e3acefdf5bd80fc217cfc56ee3e5eda231d291c815b130b12c281d101712f18a9afb8b9d2339b2294e262a76367e84da25982c6ae81b5b75892b7264802860952e98d5754e400c5a776ddc15b9c16d57ceb173a49b693e5f52fb0344e626dcc6353d06059b8ee8796c2389607fbf680a2d3f6b53875c38fbe1a672643b754deeeab7fc370525f76889503188f707c331eccd47b8df4e2f884028454ba10a92fd2b9845a329aab8d2f769c89d8abf053d897826cbfe94faa326b7535fb5a5eabcb07fb74033fc84e955271ba73ac8d2cb6999e68cf5df730f08d020b34b2ad6fbb91ee0b5241ca47d294131ca7a1724e35b36cdd007f8009173236af0963554fbdeb806f12f5a03d82339590ab666db5ff546b3469b7e38117d3c5856b276dfe50325f930f886a58ab7d897dc21851173e6cd72e98445e628a44fcc6dec0b18cd434321eded229c66970ce1f75950dbcea1ff27d829d6219b4c8f3425a883ef609520f56f8141ddbffb08f33ebacb078ba27aa3652c145996c00d1d1d973d83053a81960955aa4809fd7f3bbb9afc95d72f1d3bad543ba9baef3214cd26e048d3c31f3af18512183c30b9"}, + {"0000000000000000000000000000000000000000000000000000000000000ad8", "00366b8f109695c55333509096f3c8c1e29418145a32ab8a66bce2b3a7615757976eef5f5fb7e6be4a290fd5d18f73c84557b91053e8b6d5eb69acf37818333e693218e851acf4a5340a7ee063ff9321b8fed39f003c363bd6a8c363e1202359ebf3d9a514999600901003177a4ae17d9bd9a052c0685e9b6aabb4376e5605040b4e8901b78b6cbc165338585b4ad398dd6aee2e679bb04d8da856736194e1bb68d435ef15501ca2017a6256b1824e3905a510a34e592ceca8a37b579c3db3a208662faba7be4c642e7f39f16da2edffd7ea33fd766fcde5b2ddfe13364f1dde862a554776ddb4540e845bb3d9684ffff73a04c0d2a43bb41b7feea110d8f272c5a1ae0d545ea8c0b8ee8c9e440cb69a7d50c3dd78ca6a765b763b66ee9bbd6e6379f69e62cb117b4b5b7025cc5d36b4b2aba33c738e8919b606251821dfd423060f698c2a03b636f20cfd1d8bfc27ae01940ef3b2202271db504932f9d49a6f625fbd5eba0978a91681cd2a070fa9b151da2ffa617c08df98f5263f4f7f1e5535853ab626955ce86f75edc05f2bce2b8e132f3de37b47427ad6c8917bad9efd8d3eab9203ebfcbfe1e81e99481b713e5f9fb8d53670ec12f72b070b4bdbfc25adfef1c4456d61f57d3002b454f6228c0f25804a94a3bdc2d7bc1f7cd762471c76fa922429a7eaddf1c055a518544c66d1bdce7ee3d888b00507b5ef79d5c4e9002023c30c263f5a90d3b565301abbc4af2d2004afc73a998562d8a08b22f11fdc1012d1b1bba10547e4ff0d4452046cbef985439c115c2b2e03be55ec55d9b0f2e6e532e90eb34ccd1ec780060818b6e883ad709dbda122ab7c52d6ab29f64ffc2704d41e55e71f2fa0bfc2f481cbef5556df72e4ca0723f14c880444e49e9d88260151a66f1bc41a8d3c12a0c2fdf972fd75f367f179db1bd00964a47ca1b602b5f1be2ad6290fa322e0cf8c8bf77c3ab36adf4116b766a5140acae7f89c4282e23d1d2996d0f7e63e16eb59e1d5dda73f9d2b5464efb4e9b7a1cb9d95d157f1b4644a9a5d90f17d85f918ba50aeaefb96200502bca8cd738816429e6a34885aadf99ad856b8d38e03cf48943242771f2acae068c7e4cc9c2c919d96c60a5f778509230439852b13a15442dbd217ef9864360efc888e8adc754f3d3752e3fb5f65ecc298cb9cb302c7a36df502cddc846674789bb76d8e2d49bedd99196bce65c41c5beb5a9b64a3aaf3863e26d7b55af10e4221a1ff4437b47f2c1560123dca21d85ed61e261e6809b1c06a3e73ba52d36afbdca3f96c135a427908ea6b3f6049671fbcb3e1412c9ab879bb2797f3fb44033cd8dbdc6bbefb0309de6be914f6c8121ec36b0dfab72feed696dd1425037b933eef48eaae55331233d7caba161e44d8f49336f078c33f21be44b354da042259012a6575b13f712180ebf534f20a80930f0b33beb530b0584647bdfc344f21c64d5eadf7dd0af61889fbc6f2c76cebaac4f5026bd0015f4d1a5fa0d9233bc21535902a8e8cb912f322e73f08d96c1a69110e58cf6b80202183b70a4167a41fd291698b19ce98106f84d167ccb69b733eb5fa2db8941a4b959a14cf12669f1832263fe1b213c29e4839f919a925145e9d229a9d5412f406fdcd68f42b07b0e68e04bf93fb2604b4dbcc20ce4684e7fa11e1d7fc49d16787db629a439156c1aeaa28fbab019b55d9647df30be81f9f28076cc12741356cf5b992a2a3319b3621450d1ff3ab13d632d121547df9454a44b769b29f62fdcbdfbbaf0bd75f18621e43b7c8d6c4d04f30bf933a7e7c5e2c171225d83556e0314e6972607fe65e1ca2b0511b8222bc9c1ceae5d7b79340a3b9071e8fd530158c164a2e5aee5741d3acdd2ac163bc716438a9d10ccedd91"}, + {"00000000000000000000000000000000000000000000000000000000000003b3", "00b8c0bba0c9c897e3f42236a72d3d159d817f61472defb97ea1ec43e5e256b7c551e39dee023677c18812c290a23c1b15830ca511e8ec7f4a3535a8fabdaa30d2173d89a8026dbe43a5000e42e14ec17c3aa3b6015eac61ca18561928f11333a03226f5b33f1433f92f151ae50dda780ffa131636dcd2705e4dce98c8f103a4210c6bc8911124c914d6b131ca7a28b03e39e6182fd4a9a69b083b07af87190c433d03dff75fafc90884f760ba1538b3b36473fb2cee9b4f80a2ddce673bb67dde1f279b7de4fa791d88de2d7f70ab7d74811512f2f400196ce1cafad2e451c6757e9dc5d7dacf32f35cd6dd560874d1124491676487f5312aeb508f08e125dc06525ab0e77064d0a7da2f93d0541eb23c168dee7fc687a8d85dfef641547b0baab2cbbba6a809436479fccf8651f957630a8f4178d4e4ba8b4b51395b92d37c5cbcaf5bca35f1143b3aae6fba1d07be0176550fdc44f5af09a0031bb0d3067fcca35ff9e00d291733931f349b7f39c41bc7f28d7f89477d052802318b9c799bbd5dedea26f2efc3f7ba4a4435d66606e884787d157b0cfa3c69548adf8e92b46eb6738b02190223d551449145f91684aaea3566276d9696e43ab267deb5d873eb985645721fda0966bab09ccc5f06b0c7303301ad85570d833a4d9ab4c12bfdf2f293343e99bfcd212a2b9dbeb439e2e89a09b8b41a8d3504b7d752389a401b06cdf48bde2aaebd80915a85b82c1dbc7a6e4ecd356f2032f053f9fd4e21ac57818d0f7f9e2233c56f223fa98585a75e0a0de4a07f3a551a1eed947c8b077b0d1a787ceac6b46e30c033e58013e055c4660e19e1bc31caaa7f5df1f7542a5e59dc3e5687346b142b81b122e8858d526b6ea67a9f7d942d654d9bb0ae82778e9d878fbbc964fa094cd302e94bc6ff70c37c36bfff3ad52bd6bc79098c52af9c1700cfe6b1d38a0a4e879e73bb7f22cee26263547ecd5a8ec5ded919ec0191d126e5917d3bcada24380f08074e64e98af89413f11490f704ffb3a074d851ee580d77e32ff6d1e29fbd11274c0575ee1614a5b67cf2027e1a04bd6fcd1de14ba40945e610922b6a3a73ad0340383168ccbb4b4069f13264fda7bcd9a4cad0001e570c8b58cae235a8d275bfae438049c50e8f1bf123f8d76ce5703f3bb2d9e5a50a517ef74b6d1f5da600e9b471d30e85177ebc1a5ac57c554720b7dabe64055132c80e391efdffd6110ae17e5d9dab22ddd13906c5007c2ff0d45bcd7e042e495edad9d6555a58162712f56102ec7f3f6ff1c72f74f12336a24837cd320fb62ebdf68b5e43719603a1d868efe55c5f9140dd36124462f093af3da445b6a2194dadafb4b2de9cdb1ddbac4371484707069e0468e7f28c961f7c7142741fb6492b19dceabbfdd013220f7920b28a76355ece01bf461ed5027bced2e2c1a279c1caf57fa5920e0b4bb093a8105bd88bb8bde721a4c5ff8e8e3a95e741029be844db55fbe5a77bc4ce02ba5171eb3f0ff5490344e74842cda6454b35f04fc227d444a80a6e02d105a9247a30c2253c4bc6e0c258776c9846a89d301f57df0ce2ff163419dd1127bcae65621ec8689e6d410f940d85e4c86a60f1c731e21bacfe1e6c9c7d6e3f2a3869b45d8e4c7308f43316dbe8d1c743fe3c00af031799f39d5a92e9dff4b6cc9368358675b916b09b0ad092473e2118f71c6f59fde852cb739ca15e024c1d5524bb9c20754fea0a428d8556a2d311fdb8bfa5274e3cd39ad036515763628adf1a2a8d2a1dea896a06f2498143211ecb4db7829c043891b1abadefa532216133c76198fc590178a36099b02854ff731185db07b0c7ba4f0334f998fc20c081c95b28ee83b36694365fd7e13d1855f75ff3146bd4a8003941ac513c76"}, + {"0000000000000000000000000000000000000000000000000000000000000728", "028a9e3025d1b4412a3914f6ddfa9551a2ec7b53402350cb9a1c5843b326846964844f9cd2761ab8190d0ac01aa816d0424f63925148e7f55b4a10feba0dec1630d2c39fdcc99dac4a71f151a33d4e8711b948450caedea304b76565bdda31af8035a8d10c452a943e1c1fb69cfd89789f1da5a3506e6ffbecf894517b9615aa935ff31e9027745f4184e03eb614a3d076b5c124e9f37c841bb14d369a746fd0320bf541adaed4ac02c566fb0fe10c315acc112b211720aadc59d872552dc6bb749cd9c9c51b860763305c857203c19ba4721c28bc764b9aa81dcaf5024c0d17bc09af2213c9be66011baf495bcd13750e5934f6d4398aa0c81ae5761ac314e5b28fdba379d6c1e7c49460158d4635405a52879b47e09fa363245b0c23ea6485e314339e8e801fbccc7414f67777c6b1c456995ca71b7de71d4e85515ba5b4d5f2faa79df40abfaad9be4f758c3d2cd50295f018256191e369b10262951e2ac0a6054cb96e06f0cd69f144c1304527657fb9e68c55eb9050ecec1c6704b48d9ea9e920cf237c38dfe7454db83db4832fbdfe7496207ec3261d74cfa6b3b7727984dff21c10170bffc2cb6cf1924523e01575ffcd6dfeaf3e0710ae5cc224513fc4c74ca71c17eed741fb4f3b6429235d6e627cf587fbc3b1a30f8a59504500543d323a4836aedf0e52c7a777de150017ea3c622255727a80055ff22351c15b2bc72f673a4f4a913a0e9cbfd503087af234b3f2b027fd3d535f5fdb6efd89fdbe2a0c0e3dd48e17df4877732e3173553ae450f690170f2937579c17018fa21574b2b7efdbca81631a80bd08f105c4677171d82ee32373591df156f902fa25ff6b601abf3b1f4ba37009f34132147a388f5e487199e7720ae3fa61fb5ca69af75241cdbf37da191b7c0f3c1689557648beb38e91e893692f5f69a966617bbe9da50330fda891c6323c6d3cf0dbfde90e8881c308c67c17fe7fc6260c5339d3ef72279fd18de931b85e56e303664d014297b6db0dd331fdbbbeda21b6e494afed08f4f20fd21496fd643df18e91697dad9e6c9a464609969d8acf2e7b4d8f93711a83f89f38f9b0e86e9e17f5f10e5e9bf948fff5943679e6f179480a1c10610e585e5e2fc75f22a8a47380633b7128f4afb073f128b6cda6ac0aa67b366605deceb98e79ba1e969fce06d2ace7166f834989091180332068696a6f91e3644c72aec9c95e6629cd06a6ff8b6d28d6bb4d9bc0111e760793f88dbb30e6c3335d40bcb01d49088eb3132b206e67784b2f5e9ae2055ae9eac63e97af9c8ed2195a44b44b4a62ff9818f4aa43736955b1a371f7e37063dfc0fae29edf4c153b5866690f9b5cbe9c97a82ec6056943dba4ff45ee26e330dc224ee7f15aeb9341d11cdf20d1834695487510715df87209743d8ba903dd732a2fc60c4879b601b74758aa4d17b2f22dc4151cfaf94f8802150ccfc390e62286c5e28e9fd7890967596503f506cfef88f1c16f1577c1314a6dbf4f1386292195e5972d3576d27b82b7fc0b46c45a5b8d043e041ca3d6978f579cd215807f185cafbaaa06e03d49c44900e109cb130cd564e8e357fff364dff51443891dda0f519d10fc70874f13d44693130f59203b45d59b88bc6c20c7744cd49884ffb301959e8ee6c7053bd926260493ed6379859af5ffcf119fc1763bcb0c845f3ab1385625d9f4468251ffca2ebe0afcdb66368b15417898ec3dcfd6d3a2d949d56e3037f5cb6378576deca7e856e1749e4a0d747d2c4e9f5f968f5c0ba4e1fb25ca3753746d07803d5993f60b55bed9c5599525c1f8618c0ba411b9d174f2448f4ded5e205d0ebe747551c680fe775ce1442dff1c2d6c6b9791232c3a2eae57101a29006be97321f162b6ad74df656b"}, + {"00000000000000000000000000000000000000000000000000000000000022cc", "00685ddb1f521327b6abf189a5158a4575b72cde210d4a59245edd28715d3e753dd544b81dda6b9b67f2019c5dc24251eed9c903319b3356b430806d55b16808d35ffeb0e56fa531b0f15b1314ae84cedf39d1c902adb2058a894a8102021203dc44c0f29e1838b5602672269b56de2d16f85562684c4aebccdaea4b5acd0c3e7ff98abc931bf9ed74032042b7aa8ff319b86e39ee863b1e58cf1affa814f65d63444d829fbf07c7019bfba89a184f5aea9e97f88c407b0b010578d9af498c1ef3033b997be91745d60f74bade12c6787098070c32aba8098a7148ba91381fe5602498f62e20e64ca29317fc5cbf89b58dd585da6ecf45b8ed572d1102a2a0978d6779279af2807310be50a514eb1abaf91fb15445d84a75ae791ec2c79ed5c3568ba79d9f2c0cd48c7a3304e188cfd9f41fbbaee95d9e3996702f1303f5faa4d3ce42f28106a9086317ddd225b0b471008400e81f5b912dda2b352869e6399563428c063e144be4a22be1c50ff98523affb5b0f9501b25659f20c2639d1e54b0b9bad96e30a3a7952c4f53a9c56c32a3ffcf2238aa3bcf57b0835ad59200a5cb5fd95d5016493cfc00f0ac1c3a3a086397ce3c4e1598efaac02f9b7d979c1ede65797b260437136bb47907a577a0ebdb14d751534e9bd0637304944ee8fc839df44703d6cafd14eb00c83b0ec94dcdfe60929711ad39509064a09cbbfcdf35d6a57d63025c91a2293ae9d5bb41afa970e11eed59bc93c97a84041af56cda01c4b0108a94d99e14fdaa71fc03161bb4f59f0c4dc18caa215274961d3528e39cde0bc2a167ad29f27fabdb55b077761879f316a41db7ea2039e3ec7b94679edce833b70aec21253fdbf4bedb55b7354be798c18f077b313a600d0bf4f7a13d5a5a266ca35b698bc7d767fa154beffd4ce29ee399cca06ddf5bb40b6be641d044c00e42b7dba4a0f265afc2043ef05e7b07dc747b4fb08655d3ea29e46e7de4202497c67ebbd89d4f7a82715ae722a669038969420120537c032918d8ff49e37843d1f2ba73343b9a1a70e23c6fc9b5f8a6d3d86f003e869cc69506e8f51a7f0add4db277daa08b459301f80ac7d106e93c1ca07225f6e77c2e92fad52caff0556fe7b8483470105dec5a549da7a3ac398f670290bb0b97280edf13f8c5be284ce2c9d5ee682fb4e99034ba38ca9a2aca19415f1dfedc0e5907b5fb770010981c214628d09f9626f149d6b30893145bece1bb90fc462db8151f02da36f21989d621cedbb99ce23b32247596928168a4f72318738d27b329641cc7398050bc2d33ffa31b9bbd00462c4bfef52d1c18ef3b6e6634d6c72cc5ee54bc3d7d7a4895ce22e651394271f1159d6855c0c2de9ffdc870ffddcc722063438de9620df89b1f59966eeff04991ae8538c7278a1b62363016be01ae9d2e9a9fa97812f522ae8417a2a7667f02d7f54f82327f74d7e5f48d148505d9240409644d708cc757719e1d6852e4d718fb199b6f0d02aeab5750a3720fc826c5803da0ef2823dfefad8e24eea4eda06b0519aedd81e47745744a6a8af19e559e5ef6db73a323333128f2a578227a4c8eada4b6217ee9449f315c610bd3d6288bb5668e74e3ebae55208541150001eec95c25cda16abb08262fa9a7e0afadeb35b185301af6b3b93f14243e4e647b383da13760eefd6822d2439199b39cfd7c1020ff4214ff0c02b2c58bfd5b90d178dc60f8b640d6f637208d92f96391b830d989318f7e63b3436b647f80f9416bf6832d117f49bd4310ff4b14d126853775e3db251da9cffca1df09f88cb18bb47646297e461fcafc4f556bd257a68a814e7a832c10f80792cc797cf6114e819561063328d7da7583b2bb761c512edfcbcf1f6b81b47a0da14e79ed433"}, + {"0000000000000000000000000000000000000000000000000000000000000547", "00150450ad5048eaa719525e4920f869308a77de840a748122a990c028f42484a6b3aa51b6757e3eb7ad02a810a7c7dbf48eec9f91962ae40f29dd413efef16e95cc950a38b9c5c7510b8bdf654f9f03617eb0141b0588fa7e4be58744ce3595c0eaf1033d0abe64d31d4376a93d52650d9c0b56a2dd47fb61cb44112c4a1c3b9a73232d7689ddee841857e068ed4052cfde4a23ec0c3f73de7fb5238c37904b44612b2faabe36930074a25a5957d1f9caa6c10adbec46b65cc918321c1783827320061b70dc76a49c556adcd53052ea1026078f2b6bd0176e53ce11a1183fc573d0b20e95132d4fcc4ecb45f1b8abf4a08751baee3de5f33c3b7150092b450ab5c6d9c34a1488a68848ca968f021c06d64edf7f39d31bc08d27d579b117eed596ae9c37006b25d009d2369d71651d80a27a64eb497195cd144e1f27d18a7c16e2c2499c4d33ac91b07481a086328f63005d3905d806d47f039c702969cb3918798fd41b1e5a29c79a37e3a1abeaf91b1390e039cb1c3d9fd79d1549b655b2d0eb75fe6f6176d1fc08e96464b791221bbe5e4d1349e6d7d3f14800967aea1b4d0efd46b405dcf4c2b8dba259a57672380d7b0e8dfa91d9b7ed0d9acce599cf8f710b4431c4aa8f4dee4f46d3610b0fe54aa91425597b6e7fd57055af22a1af1abe940878c57c28582b96a78675db41e1636d6356955cb75c01eaeac08ce8f619be0a183574789b2ef3917a73b023b39d06c62256af43f9059093d39746b2a1de4c31023b3953bf4f399f7eee91b74b94e958d0259c715539c2f6c265cf83b39074663d776f304e62ea1783fd01ff0d1a03e553fdd4da030b262b22850672b460790593f120da87523157d950b3ad85c4ad9c0e189c5203222d72b0f6429db5b6d7d59ac2d3b29a5155171e4b0955004eaa5c1bfa0769dbb8d7403aa28b168959004340986067a57fae43a27ed0c49c0a0dcab32bb202b17cc908f81d1bf191c45fb56717812c8cd68f9c0329caeddac78cf3b45462f26158e17664c334f8bf50b6671f4f6e88b7831d2527e14794ce66e1568a7b0e4e95a0d24f2e98ccfaf8b205f64422d53219fcee21902571549863f36e5c12d40841c66fc1c0ffaa2b101b53f182baa2c3e406c7d092632cda2388152e39118a2aa04dc8bf18e73ef1b4d3e12f45585057b1c30748c5b7478baa54b6d3f1618836f37906fefd6152119bc963aa44d9afd6fc4242c494fedda33c93216e08ba38770c550474bc8a322d92445d38f24ab9930a15780b6fa7ec0f95f4c988000841e3fa72255461a40cc991760ca169fda4cfa3b24fa2ea55e85834970914b3a90e725b7b116b72026699ad011d0d89d4df5511ab11f0f5216da3e13bd571f334c09163e7d76c1a2229a9adce8a549d08e592d2b37b1181433c10721101fd841ec5079cfbe086c0b37f090349262550d8d6104841abf1c434273370429d953bea8112395f626f0252f7380ce0bb37342e7921f4e6a272f2539eb67b2ac1fb75711d00e55370e68cb3c031fa7d9a9696430ab811d84343f51dd12771cf3d72d290c63d7a62f419b4f7d2fb753057beccc1f083372a60b66df279c50ef691c3ec5cd6b93256a1a53eaa3c1cbed0cb4b8237db5af97393c94d9636e5074ec5661ad4803809ca0772cff53fa333495a86653c1377ae4f1dedbe835d0aee8ac8c169abcfa17d554d16dfab2a4153dae1740a8b6bec8442cff357a170fe89c6bb2dd851bd0d39219c2b88b9ed1bf58cd2868e7cceb1579797de22a910209370db957b2f4351f33017bae7dd1c668d968a387b0d1ef89f1b0baeeac616503b715a00ba30a3823120a6faaadbf0457898938ce373239defab589c0049520476d8aa8bebbe4fd72c5ae4589e061b546874"}, + {"0000000000000000000000000000000000000000000000000000000000000483", "0094a2bccd4dd6b9718d843db64f86fdce01f65ba317b7a27f63dabd953c2ca19a6cb9328e1d73b769260978805111d3e135fc34a1f8cbc42b957b161babea254d87450d993dd9c53b042743c98f352af27149fb13ed7dd32c596b8db803541307cb1252a03fb58fa81b83fca9d214b63be31df1e7d0965061f0927de83e1792edf669d05515ca6fe7b88ce001f29720f6a0fc1f45bd2b1e08dd34655dec06f672b2db39ff1c6a8f01b8df7401857891c971306436de3a3a5d773f82901071b556025c95e9a640e3b80ee4efa10930311f060c79e8be35b5c395efb8823e63491710d6b932e9551898063614b803b5f6f832efe71c6acdd1a9749c0e041c9afd599250efec533060f62edb5cbd2a5dbd5816f8ace96e5d5cbfca3eb44b7c4d2d9ac7e5785bf6100be51d61e00a29867f3a3944e98f4788225e41f22a380fc61a19415f88e365a2e66193323b169910d001ebc096215c846ba64194b87445d455b5722f1c050a09bb70925f7a55ce76a3822fb80d1a22e7bc9cea13bdb6019ad9551ae3c21325bc3781d1cc2d33da0720819312687c1ce3fb9e43a395ee77f205acd6911706258ca258d543af2a3a049ad75db632d0f797bee62fd53de03ca8c2256761a65d6dfb505206fa9c690806f452ea4817caf4c34fe1ca4dec9dbc8e073f916e1964e5688d150c7cc0db0374b12db6f9bb3afb5e2e059217e568966b22e2b1819df98e0270f6e0da8bca3b2f9fa282966b8f2d7d27e9f157972ec8e33989de0bdc999e698d3b7fe4e6d11f66be84c8cda0763b6329b9f9d1fae7cd27a864080a21c6a40ab3f0f7ff880f7c443b04f879dbf3c5a2daab9d1d150a5574bba60fa162f61a0524e30c9490ff88c7ccd8dc32d1f36d13b45414cb0e6f60e05662ed54de8552fae2fd9f4038dffe69e3d204baa2d7439489f1ac461e345c5e8f046378922049f423a5c084a7fdc4c0b23b22dd5dd6148cb627a18605f19cbf748122a656a55d439ecdcd295db303c797e1d99bc174441dca8c2355a5fd3a1538cb3371d51685fb8ce2e7567c790fda592756f95514b0b557532423cfe50c8bbe3ffe77ab398d5eb7a057600af630a3c827f6fb55d24f32fe8aeb36bb2b0c1bf8918046133305c7e59521df4150f7bbea1f308f4f3dcc2c10ddc141d295766188e3c349ddbfde44f1061f70856e8713b923d8cbc56e7371b3ef2f7f9d2f4a81f56401a56595ca046ba26b7fc16335d87a6fff2977dbc43cdf53fd074c029a72c7270d9522d1f7da6a931792faadde6dcc12f99d58eb82f66d3959ae150e6c4593488411de336938d099f6bc6b66247cefbb2d544c42fa9f876bde085771a5f5f7f33fbc3aa8061285e31d7716dbc0b9cb2188ca43ac4a6ba4392319427125488d3306419d86172059d2fd4e3dfc92c3e705bc81dc8e46ea27d671d508a17c26f62776d3595b28c397fd9ad1ec72bef54342ab7708623d9a75fca311f65a8e711a0307f5dcc23be44b215e3ba51377fc19f25950fc65b3677917b36bdaf0e4b2624e14980a07c753d7da886e9d1a8c81d26e6055c0d680ac932349945c77756273afcefd680fd5679c52c858198c0c1d3c55540e5ebaa9b1ffa1db0711bfef16495edebb25289ec88a59bff79a788415352bc0a228ab16e89f0e97930a30df0113d5c811b99a3735dccdfc6ec44a240c0f04094d73c9b909232973c57d79d506fffbd2321011ecd35356db7f156759b36fa6da3b9b3eed4c7bcce5dcd3a2b74335e187c7decd494e642c7c694212c3e614869012199a07a68a2cbd465e0c72525c51361b7c363e904293e6ca48ae97cd99ba3a4bb6be6621d15cece7d7629dff2f14addb5d7aefe1427f79be291534c511210687373f057541352cae2357d89ec9"}, + {"0000000000000000000000000000000000000000000000000000000000000523", "004168265f6724295a44579ca27b6c528e3a98af860998cb3367d28ebfee57a3367eccf8d5fa8c53a3c6015674e373d14515fe0df45a0656f9f98b539a64105729aae40ea242c17775257ba1ffb4fa7553796efc07b72edef6587bf3af64618f0b96536e37cbf4eb4c0b9913ba758aa3ba6422354af459f1fda3fb77c8a02ba7fe152b0ea337263eb3b89f37439e088874c2244c80bc754a1daa8d6639376052e52b7de6081b552c023163975b6c2515dd1b918556b17ae06f5adf229c4c40e28071167c8587236693eef6ad11a5d16e84ea0d43ea06d9085693301070d6f97229e51d5d79716b126ee2b3fb178eebf00f3307cd5483853ebedd47a309a973e2a5c9a5d2a06ef52045dc881e9f311a76a02dc62e2e5e98aa58cc7ae31899e95a9b66059d82af0a60db6b59cefcd2dc608155052fb1028cb07e519e0e0ee7fb7a17598143ddc14a284819d063f02c0c73004a26915121512fa7b521e7ce6e5ae0e2bcecf9b014bb612e86865810418f827ba7cd37696de574d81e181e8c7e4b496c1afa00044d41585d36f8577c0c782949ab8337600bd5adb206df334c37abdbd3df6afe033d78523fc54f4cc0d3f6d73e71bb89e0e93eceea3db5038ede9b0f19fb54d5b9c57a13b222c39fc332035216dea869342186a3210366f544fae32cb7d692322abbd0f61f4c05f7dd756633ece61e609096d81302cbed3212d45309433ad383d538e879e3b84fe5181085b1232dcfd131e36c2367475c3b6cdf415aca2623f2d51a359b49ff8626649e0bee716f07b4fb43b838cf1e701a240d93ca51b390c672d7b531f2500c3b0ff19ba1da58103ddfdbc48e93bf9a3573683154602309f4efa99af5b50b5413eb71feb8fdd9b5f7a86115cf3ae28b0d3a1acce2445e98290e73eb803fe7ae25091fd8188fd94eefc7972fc3f2b6efd1943f998b01dc789c2d8bb47ded7b6602f24f0932df443c82bc59c1fb7fc858893505f6275b35bb08ce46cedc80231b76653c6b12133dd05312c626abeebd3933d8a66d31fdaec9bdaa5a91d8a2593189ef0aab5ad77c64440a29ddc91513119f71a3c4dce2d80c91ec735567470d22b3abef0574031e375205d5d20f5985bc9056900d4c7ae608cd227331b8c1f98fafa56d2a2efc267c16e9e2ac43adcd0bdd29467458615dbe18dfb7f1310876ae1ccd920dd0a39af49e0ecd9ad987703e68f76557eb5386e3cd612172f83d29502422b07e7e34aa0a7e5185772908b1991fe34b5b3391ddd6fed1c598147728e2284abb67ce9843d3eaa7973d02cdcf9479171f25976cad1127bafa6300412ffef955cfb4c666196f9dd2d8adc0edcab4a2e8fac618f4ccf79269d920171d4b4927ff9b8ebad2a13d17393261b27dbf462e98fac5bcec4a2fe7f9e9265cd33bce666b5cf904057ae50c6010d868d04afa2de3d2bbf6b7c9578e7c1bf7f533f7c78785ca75e636ed7cfd6df4e43070ad06d306fac607f26be51aa1a7d6ee01a5803fb993560b0e59e662dc3703c572474db1d2f35a0008d58231077e174e8a43331e56ab8392474450debf40fd2f482cda4b8bc02139670e5ad36b68c01b1548f6b2ef761ba5c17e0d6fbc33a78e21c812d7d43aea1c58524229d07d432ff6a175f0e3942d8cd767b14884f8483106f73b0355957b8f17da083600c8b2e2bb601762093df302150191b001ce37a47e87dca8faed9017ecc4101d210e30d338ccefd29102e0699e16148dbd4da828ff65882b67628949945602c3ba365a04345df1620e4ef19cc4a4a9474cf31135f2246f958cd3582bf064bb65b3f75c18719643f877d0cb050692157807e01bb7c69f72989ffb784016bdb4e134d2246bf5aef823e977a7e7586be1348316cae7fa96931e4fdb8917"}, + {"0000000000000000000000000000000000000000000000000000000000000edf", "00488b0b4f619277300cb0166cc02f908c9b55623f27b94bf9a7d3858dc6f108d6e154fc9e7fe35a0c6418d78747511d324962d6c88686e6ff57a9729da7f92bf0ccbee86c7b959ee3a2fd629f1a454ecd6a972b06634ca69406ebefa6e5f2d66ed06de903b43ba6de336d99b7d6f19531ac58e6ce713fe421b4c9f8813f077dca472b696191dc19b3c914b7fb411185d379c73c812caf33b4a215da7cc64186792d064fe7fe3ff300f1e10c05407a2f4f8d31556a0ee5b9ca00bfc1cf0265c8ad4a0eee3bdc11f1871ee266574d42ddbdcb36a1735877681333830e0591cad79e63505b9d44075a4cac4831b9e78bd5e9c941f2d5179706c2defd9804ea694f6dca8bff7aedf3a66636e35f63c29e798920abfe43cc97bff2ec831356007689d0d8ff1c0273139f4c5ccce52d35e2d6e47798da9b0a036fb411fb17133e2ee01e2243acd043a541c45ab8f3e6d5a68d016cb925830e974d845021cdc44fabf65e73d814a8064d0cac336066fbeb10c33527597e8165408c14b401d63a56bf44dae4ef9041b01b5362b657a27fe0c60f3ce7a9edc83be8ba73c64711e38e4e9413f56f110abe62eff5d71c73d43ab24ff7fddb4e6566d6f22011b3f50c43d37e66dc71e2a63af67bf55e74bb9f2719cd4efc724aea43cfd5c478eb506a993bf5f07dc9248ba9e1c195b4f8b31bf4436c3e3ef1a31c7389ba06dd6cbddc8f275c7e8aa890e25e62562517f9259a25390accdd6ee4779852067c64d85ace462ede0c2311ed00fe9bcc0860633e646f7fd4af0b55cfbaca74313f3611665b078f3ac7e60982b989b5d9059ff87f06ee0868b6d729031ddf8818dc478632cbac9fb5782a0184198693255311d81458bc35f6c27006fddfd40cb01939d8841c195c65a10d933746047e40af22100f808a2919d87be72d79e8ea225c78c6eb455a28c1007f9bc76397b8e6dfe0f23294746c3e868ffb6c1f05520b89d3c9e3f2c93919d57671e1f6987a959f6c18db53a1ef8c299795050301be4be6c99e2e7f278b33ce16eea8e11a73d85e359e206f22e56fb47b8d740d7f7af44a4593a3a407115e4dc772e590645cfd5219fb3ed68ca53d8db817864fbbe768dda7491f0a7b162e9a9bc2376171d79a61a0dead62b55540abfd2e2395219dbc4cbc1673a832a1c6e2043134ce3bd3e80342b347d60d834bc29d508e23e3d2ca9e4e362ef110c8d2eb89cfae83175752a64a78f28adaef5ff0aa0968ab5b3a291e0f535e7231739534c5536fb12004355817b95c52555d6e18a974205d6c2f1b93fd3f2507cadc11740877e54adb56251fee367a73c6195074106fa68374d501036abdd34d6031f4a57db72d4e8208453323152eec59f506332e46f8e8d54b5fbc720a0c3ed353e30e4933f3ef685480652b668013d8cb4a05238b2335ec1e11627722050ff2e671815e336e52146413b053e71d19588462bc4e97e6f5f44fd6420607a2823e336ef909da59d22d27f79c36a38df7ce0545d5a73ad1947d390a97b5576f6070561753b3e2df0aa1dcb574c55e2b8ed3e0e0e4ec3e79a77cfc91f82efaaccafb4d146be56984d38d67a209868d30cf120b24cf04c555c7479605b7f6d5eb1cab346b3b3b0c40a472320b97d3392647e59cc4de3612cd63983b22095a57049a629443254c71207e53fc09653f31b8f40e635cef17cfb64b37b0d22c4441ea7593d615a465142592e6344bef7b1186a1ebe6373ec1a0819986eb18cfb49533e1bf3fda4f247f8eb153d7cfbd1ee98610315eaa2d054b4ebea05350e2fe6b7541429a45b432c10e07b86e117b86f4e3f7251fed4204d71073b135725e0f4f917103ddcaf463e9ca0f3d1eec999f3d62f9e4d0ee5e5b0763ed070cdf66b62ab787bfb9b4"}, + {"0000000000000000000000000000000000000000000000000000000000000277", "001009413583c088bcaa3416517245a52315ba878e06f0ac9f23209e3d6c6114de7167a0fd558e2b2fc30d1f9974936cd4a79611549ef47263aab79e79efbd114108f2480e2f49271e314b8318c3e8c531c8ca8d037fc79e8e192fcf4868b188056b556cee8d1a89e81ef76610ddd23670b53822f2662cef67a92e1dc428069273e57f255d1faba2e34aa7fef325932815e5b208998339bbc7eabdd46be6fe9ed3b686837078779b0064079cffcec933ce24a0504f5ebc386c1f4f79430a6b2eca04ca56e6b268a4104e625c57e177bf25020dd82f6099ed6295955a551930ab8283d83ddf15761b3221ee9bff35affbf7c91dffccc1070ee53d8b83055d015549d3f3bd5571218399cdad014b85522c360774ab93b4465012a67391afe23026cebde5d798e7059edbf1fa052111a147a4eb2a2e3519505db73a4735d66730b71a5237e5a647e1d8d65923ae8d1d9db500f9c3025e976a41d09bd063e4a7e6f2d9289ddfb20e53f76ec3636963e62d02130eb4cbe0cdedfad47c057c6628c70a497c6374e3d10ee9da7681475ff77c0b0b70711f0c34fd56bdf151c115599cc83ab7c0b619300542305ae2cb854113370f30883348e71acad34ce31fcddc5c4e87a139594303ce1d5ac4273956d01b300184661c34bb073ab1bb75a94f6cea7c12a2081f920730495a204b98df3356b9cf35cd119675700d0b22d88bf2231fa1fb8102bffe78a7e1a9e173662e2a9d8a3985d9ac7373b4d58795c6dd6e89c69d95361286a716d16362d1e66b247c7f727785a40bd31a6528afb58236e33acfd926e4bb29346aaa0b2dbbc39a0f7732e5fdaea8fd8823558674d1e105994177c9cd17d6cad34388a8e54b7c72aca8681ea91ad5f2bd2d17507522c85205acc62fa6d420eea247d70c1f526148e3b254d8d893c0e8fca7d2def9b6c2b23a595ebd005869313db0bef7d2de64f7907c2bd229889c4bf82058fb8fd70cd22360f78495767d021294b17ed71004b74ce8b2569b2f7dea90ffe32d78c6f2359de773248791d6dc11f0ab74dea8de254e4dca567c586432046cb52c5adbe161bdfca5a54361fe7225485a501b04a96d44060c622689b6245ddec72bc928efb9fd7a07e17ec9fd449c8dc1dcf1ed47bb29ace90ecbd674196b5c604a08f9eadbebb1dce3f0ef2f53f81bee0b04f905b870ddee750fb5b1555aeec5d96f647e075164345b3425dc3fb71bd87848876cd112de03f8695f366dc9def11c397d757de4d4af4bc72dd5bd5b7dd13fe35eb024117dc2f45de4f7a0dc3d56035ada057a08081c0ddc0fddc7a3a0b1fbdbb19010a0863821950dbb45aabd484d0d296db26684ee83bdf8505ab9601fee65f2a8d0a48ab9e4f22617253bc641171a75af71223ebd4b35739bad07678173c5056e216efd230c072eceecf248425b009d4612e0b243be092237aeb8626693212d26df2d9e760d1e4f7d430b5f645cdbe30b93c5bacb1033189ac6417616e7b22c6607722dbd31bd22190621aa0f5182137887ab06654a292bf62807aa49eb90c401b724fa83d37c73080d7170d704731391b7723aca3b1ff6fe85229547b15d58caac6b2b29aa03fb3110891b4235c52c6fc4dc23047d7f73e5392293d41d5b8a7d452c986400fff66afbfd5d691907e5c42176139faae70cc7cee748348b12c39bdb234fe10f6b2eaed9eff6224765b3ddec2a9a6db74a4a0c1b0aab73c34f6358c77906fc5137b37fb47cf232257553c4a9fd2bf3f3fc54159e72e7e14abfd29b800a8ba97f615a8757eb5ab8c155fe765b2e493c8d44624c94cb5befd2bfed4ab80e94d6a3f261ce15fb722fd51308e76f3151981c867a35fc979efd461ab0a93135c5d6d4a4abc78d3ce662dc3c49d29d92f8ce7b"}, + {"000000000000000000000000000000000000000000000000000000000000005f", "0033d78f74a4f55bc463d88cbc522f1a448397fbb2076e970b36e21c179d0803777d6378722197560aeb161b24bb8a5bfb23d220d2d32cea32d8f831dd5afc369ef6121eaaf19187e57551e846ef1753e6bb450e01713ac33a173f039dd6b27d1f2152dd54cf31c4c02393f554cc0cc2c9a40fb28d8972b893e8cd5f9c9b1d5d269e272450a36ebc25b6375c61460bdcb30300622975ea93d88eff6b4187322cca4d2dfb8737fa060277bbe5da53a6938252a031f8c9a688cdb234527e160acc1df38d62e12321a58cf9fdad1366db9c2ec20a81fa7338d2a049397591f15eab8f5ab1673e6c5613b41cb4af235857eeecb7020cc549ce667a99e8060c223497ea987dafcf2518894fe9fb1e70723a32e41c1a8546365adfc7038b724acfa3360ea6fb7be82e12c1cd23d9d23e991094a1569f4b18fca7ab3738242097a3f1cd5609d9ba4805b33f3e142a2bb2735547008d821b7361c7ab1ca36065dddf998222f51cfc8a32f1a9a3e712c814ec42e51501dae7d1cbd332592501f9e74481d90c09cc82f5644faca52f67eede10be04cf570081676281d144610935d900365613d3c0dc037529deb384de07e05f046e163db462be87df18242f3c72791ceff7efb74d355bcdd9ce2ddd9978a31508f2db0a227662b3db55f959044d3c7fd9d37f30122aed87b3f1530505572c0437665c710a4cf17419cd019bc7e486a549c7494950683d473da302621afb110a87885f4fc707d17466218379fce88cab577c826b11d30d7e4e2e168df484e38bd4e160c4f4ecd648b03e3dfda8d9704c9fc46164c8d1c48e369f1079d5480cf9a6f5a9c9967a95692295686bc7d75040fdc9e21d6da5861e8e18098038222fa048aaad8bc038604a105d4fd091688b63d5d14815c74ba45e86ebb8bd21402c02ea84a260672d3b25f17fd245b61a76d27e7d0109e6a31583ebb07c7de4185458a31290c7549d090ad63bf30447b98f06140188867ef7aa6d907e8c691207463d84a0abeb0a4d66595c5712bded921a935723aef5ec97544ccca41364dba24f86d1981239f5620c73506f841fea636046888f28f4c8ee588cf7733c1f972a75c15451efda62237e516790e54210bcb5ec170151f129d474232229c28d29637b1e2ae6b4f9c63548e399f0d160ef05bb63b0646b1c31c1c41592570197111d7685a019438b44aef7e74cc5a71bd497a51568ddf9ebc860518364a20697c20a8cb92ccf65c61a6a0a64ea2b3f03c967821fb338828f90c15cdd0b256a69f65d1791a1b33544ee6ac1812d9c17709e06111794ae81061732d10ed562a4d9f55b5e7cfc79182b59ade138cc273149d809f057f5960b50e11f64121334f97ee1536a65fb2a0828e05be03eba8ed5daa53dc5ee9e8d29c655fcbfc61cae4b233a0f2e12a1f2024380490b645fa59ee390532244e745ce27fde712145c78a34957208d5923d78f464ae04e12d973833a22cdeb9aa14d1cdaf1ec84c75ff89a214bab7d7b4e423fefc16c31165fe7291695e2b5188f08379e9d4f036d638d975c4de3df4ba1b3b68f7a22dae477b7f151688fda6a663525b55428eb07c8b93e507c14bdcc03f7a861d9e06935387430f93d0a5fcdd1b7758d0f0c6db4d0f9106e2dc3fc526f704cc1dd2d5fdf19ab06e9dc980718f423a3879169c2a127fc840314a3db10ebb27567b45cc5c3eff71c555bcf96137d1979851634028b07faa467fdaa037c672e2152ad41fecabf2f0d1e0a9ad74ea724077689aff65c6f1c0a5bd9261021f3514ba21901e1412296149b5d68e6dbf059c01cc712aac5b3fa4daabd62be2a5304ccf03eea9985128f6b92abdbbecf264aa1b5e966de66fe929e850b254ada6f24906bcff882b2e062ef4f960df2dbb972"}, + {"0000000000000000000000000000000000000000000000000000000000000812", "00461f6d26517c89507da33b4d5233f4e64cf24abd0bf549b88ae7d1f1a24e23fd4ffdce425e699d700e10c4d14adc10dd0aa9c8f6f1736e82a62fc79a6f7314405130ca09c99b6dd0715aec486eaceddada5d51035e0515cc98d02b5facec879669d58b39e8bff7043b7917b481aa9313687316225a435bf59d9df137e40b409c811a5ee3af1b6ca1bc768e810eb6ea7e065b0c2dd69c3e9e5af1cde05729a0dc926610c7bffba9058c5080dc41e3a96d332458a7df9692d1373fc39e22e9493c56d802e0cc53435df47f72c1d88e1dea6e0f5e7b47a78a836d6c8030fca4ff37453557d5e6585236ff446de08f55d261f5dd1dca4bd74baddd658210ecbe570f0620de63842800d6df1f024155bb8ca81c0ef651c4e0039562ab22a8184cf05bb5a19e679b13a03fd888338433b305d3424fee2831fa1d925cb124692dab735d60a386e04511425e66ea54a39a650602ce093d660c0fbc6359e145b17f5d09713fba6f5c1c4b01639a5eb84139ae98637e4379e667c4d43817058dbd75774ae2ec5ee411cc4bf89df5727b79f3221df0d28c51944521dd68a38e245b5e6e76799f29df03950e741758cd99185711c31d1c8ea08a59e7c39c214044ac45f80ab9f9483224539d4aeab8697c5baf07b389e70048755a7ff0239da15df5970cbbfb80041c6f0931348d74bb60b4743f4c6eda86841e35c3a903e03e858d8a5dad9854d06deefef218abc058fe6e871ca6474564baf13563e9f22afcfb234e1d1b54a835bc9c61faab63f9c9b52579cb49f27e5bc9f41cc8376ebb1704cf2ac7611aa6edac55b2c9fe2e352d3606af7328154e52958a05b08a847135709df80fdcfe092814269696290983e12413da29ff264bfad2a5b30efafdbadd474511ca17548d032e26baa0a1bb42e53f5a6d06b4eb8a616ed3b5fb12f56605b83ed8ac8000f43a62790668d4b88599c5587878d6c9853b394a06d04d7c4c93764b24b784fe79feb8f1c1c40e8cfd0eec8571f0281e73c7842385a14d0645e64cf299e5112ec27a5d52eaa6dc0f9209d62830688f1afa7b180ab30b2189d3171f52c280fd1dc6322d6c7a936a9021cfc79ab90b8dbdba611410ef3b6d62f6b3dfb0c61a25ac3dadd70ac110df231a4bda28f685bf9940e549c1fb22a9df0047c6c4a841e866bf5add5ebf845e01caa70da561fa0d90925072596f578c83b0bd03e61c5b834020b039a9f7afb4b0195181653a78af718b0d1b59321d0a881270c267a321e16fde9c93fc7c01357b92c0cc5651e53d0f84566c4cc279f8367b2fb504958ee48baa1f497455540a747d5b258025b727791de93f6eece7b7573f9f8555d5478bbdb1436db2af055ce467e9d30037923960c79547acac3a4aba750c0e56830442d9081b1948e2d1b32dc74dc36a91c0b802fdd60b49c7f9af5c8112d92ef8902a9370180fe74d9fde4369e6badf89a095710d3daa622266b49843062c6068799d772f13e9a0f9b11cd9295ad654f09e1eee7a2f8ce9b75fa11af2e002e037e27c2f7e7ce0048242893c4d5f8d571ba67f253d62723d853ab63b0e505f103adde1076e403387f4abb52e2c92f87edb13daa1201988e8bcb0c441cbfcc7b4cdee87911f631d5e4c2c264b00dceeebd7cca1d965f2e6c17ec8e71528929bb30de3d942ec39542de423a283853f5a8b18add1fa4e0d2fe1b697b8aa20663f0f32a3dc45be1d3fa3a2228e1017178285df87616e060a69da20882ee4ad8c309d57951f35844b7ee6169940780f3f5f26fab710dc1b14030c9462ca2fd63791dd18dc1dbb4ef26b746416fb9dd8661845dcd0282e214b53fa7542f7b578f4762db1d16904d8dc7233617d4fabedca793a5fbefa1e52592a6d0c9c2deb7d3b73c7fd4316"}, + {"0000000000000000000000000000000000000000000000000000000000001b3b", "0047b17bb0414d1b5deb37f1d7c162fb0a44bf642e1eebfe8f9447d513a49197c13c4b35b2a1b3ded96f0565b735a308200fbedb20f16bfc3b72327754255a1880e4b70806aecdac9bb23da53d357a3612fc5ed32b609bdbc8552d64fd768468053be91ef5751ae19057873ac0469eaa6d729e459cd2c72a41d5f7dcb285373dddce26de92d1624a3467ccf5ee12c6ab1e94859e211feaf42b1be3c5e929f5edddf8773062df2ec306f9ee51936cfac7a07bb15d006a9fb1b78a7872ba632eed756426bc8bdb423779bbd4e53efb871840bd249a4d2580a463c9c9d9b39f68c236d655157409b4331b74e8ff1f559503131388456995e51221fd90c91f1706888c087b3f0aeee583ddb88d22c5f8bcffc61fe5053ee94f721769a318878c7e9efe256555908129fd53afa325ce9def2172ab1073b0c5a27cb91c6c34451522dd95069ba04fc8237e57109e63bdf715b7019834156af0a303a6dce23e2be6814d49d877344e1ecf34878caf2ce3999354b783e5a506e2d65dbf3a0542b5c33268de85ed71e08fa0ee9e316741da64184a7bc7e9ebb32bb7c26c2b3bd5ef266ad104d79abd0448e450ef8703588eb770a3af1722cc98b651aaa828cf57e52b551beb727453cfdd2b0fdddd4233d22918be4faa53471c79aa21d1ca893eccbf487e9e67bb5b3715d90febfd6b8596892f627dc84f5e4d1d86820348445fa59f61bbb55cc415d13bc8f9f259f005b6037d62b6eeb09e01aac4f25fd5c2380a174b1fff08258acc90660b4fbaea7815d193433521e5207df95e2d23797b5a10c5774ae5834ac9f0a2153dcd6e8af605d715586302c42d4e2d03c08664c73540ac8dd6ce31d7ea8b22d8267b7b96079621f940a63eddfe44f5330977e55b51db4e9acc64fbc6b78cb7072d1db0794b91e2b4abdebff38ea60900bbd7a65795ecbed13d047516b81914d649c7d1b545c5fe7195d9a6f84c4e53c62fc44b3b056be8b7867df9538a21e6ae1576381930db774f763fefe27725e68238960196bf70c98165399e8b692b802bdd75279f12d3533b3dd43cb0b50f530175e32635b7c114e5950163036e1dad1dfe871a52b3a740d2cdd5b09f356eb4defd9ae4c218f94126eb25e4b1519f654581f4bc75fb704991e55d796438c71697d9e6aadd7ded4964ba6bbdcf6f1d7ee46b0b559beaca914b71501cc502617258eef0eb7cb99e49362612dc9a5853d12b549ad0d39a953c9638485115cdb1e42f1f908f16d6751af9518b21aa9814a15b16eb2d77cf998972eefbd46e187bfae67da95646080c7b02c32443e44a8f662610d0ee839265e557ce0017646bf075485bbcc43c61f7260fcd3f39d61cdceb2496d5b3399726faf72063f6a767f5e5cfc43f366826003cf34f73ba939e48d40c56479431c2fb9289f806d9aa83ba42df6a7c54a5b1cdeb2b166d6c5eb66a19064351a3edc0c98d8a5449c5c8162d9d6af470db18ad6923010e03ada185733d0c37fb3d0f72f2f4b440b5df33356948eda247ca88bd7cb372aeb7febe5e115c6dffee1adedeecf4344c98c726bd5dfe6c603135a27c0f1ce1d197cf3f637ef3258ac0ff434f0b25203b4aeb879c3d4bf7a053deaee3d414f7fbf4c5804ee82bf20ba4fbdfe5d5f521c7e17819ef057dd90a09ad6bc93151687dd5bba87cc9f39c4ed323bc9941144b8e7ebdd058435f8c41cdcc772f08e4ab0b76aa1c87f412ab4f90c5f7f142e4cd77a4713b217accbb2936633bba682a9949b464f58cd531e693d5bd4cc90d05494744ee8e9f90ee376c9ad6e865de6dbbd0a315b7862d594c956d6b2302137ea90226d098179644303aa742e52ee233883da52260cfca3ab38519480f3af93f220016ff91fbdaa544d0fa037b0362de3d28"}, + {"0000000000000000000000000000000000000000000000000000000000002324", "01aff257a2dc9edd0a0d746c6a6cef718c99b8369c06a3bec78c4214f38b4180bc582d01c337605b00581b1985dcfc5b9937405c6254504cc7b931c7de64d42139418b928b87c47c1cd6f4ba4eb3f7529f3d065c105694b36a865841ead3214063678b82dd3c9965f02c72757a10d55e32ea0c356ceb3daf660eb7f3af4d162c9df4ec78ac63c64d81b4e576120b7dadffa6c31dce3592f6edb9fbe1b2d340aba9532cd4cf66b6b0030b20bd12417aac6c0bd1442f1192a8f439d7ad2043afefc125e9f5dda794290145fff626f55d5942262417aee79f22d0fbd911a2cfde7f462108ea90cd6844a3f497cfd40f48a85e7493037ed0c9bb962f2f510389f68a139fb52165eb21e780290235c9dbbbb74e15c13639eb0bb488d8e39a637c63c1eec6d55db60503cac2ed44e15945cf85636027ac1b665162b853dd06810f95ba4fc34bab6a613027d9e505496978245502d59463be442ce3602ba4e1a2ebe2f1c06bbe82a51b2789a259077f0042d694cf66dd92c9e78bb60a5c033889716d09a1871be142c3f1b8d6824696740a12107bc55959d97ce171b243d4885e65a77c63dc95e90a6a150a77dd9f3fe04020e07db6b5f1ce78bdb4e3122d71095cd127ff9c18a2a0497990d153316ad26a1e4a7d2075cc8dbb57d1159103d4fa62642e37c65e200c5f2d2763d601fa00023b4153a4874e21fad80302e0523050aea40d9a396102f2f5726aa6bcf9f02a0ac599579f48552dbeaa00e01607bf0e4f7cd7341617cb8d857346c35051abca6703f4010eb4685b47d01949a2256c597e22ebefb2c6db7f0ecd98e31c1ed00cd93a3ede88e102af36a0e18f10d17913085f848d554a6ca5a798bf3b2a1256ae6d5accae8a16b9260e150d9c5b2d2e35efaeb74773aaf1f81a81275cd9c01a13cc7c888af68edf9e54a0e74ff67d4b29d29c5702277fe6605ab4c306f35a76485c1ed2b85c3fd3bb08d31271ed550d49bf2bc21414e11a790cd0b886c909fef20a016b3f53d29b549e852c4f91fb57584e1a0d1051fc1a3694dff82510df42c024acea9650123f033e2d23d380f525116f55d945e22f19e56c3773b953b6fdc0f19cd86bdfcd47990b4ac7ea01bbb4124c2144aa39a95f4b6b19cca33752fad7aa08465ae3732845bf911e2954335503928c539a70f112e779967b02794a8bd19378e6f7a327556e76badedfdeb7e4212016fe5c08287a3fd89ad75117e3eb6df4f9b158c01b8f1f710ec6e8b7e93477a3b17515fa93dc9f450c1fbcea3e71da4908d4b5b5a5bf50b3465a78f971a11a987e5ddf92bce776742ce77b7deb9f60d97eb455566b9efc95ec580bfb7286c80b57c6ee956c78ddaf209f03c82f141a23361fe3ea8467652607fbbf435b46e4eef200a60e8b5224f60a485f4266ed16fe9e3e02daf37beca9eb476615b111237491fc56b17d9b5e0fb7992184ccfea8c04114c47cd66161c9a32ec850031e3a0bd084a81edd9fb22bcd23b8e165235cc43608ddad66978f4d19224ca6576957e596ed4d3f1f900915f9c276cec19eebdcf0cc7d42a0dcca2aa77c5829a9e7519bcfe1fef935a7ae6651ecda22a99e28621494cc4c70e5304d5a43c69c8a726f5e177db89690289196c6c3972fdb7320133b61dc6c3e24d05b4dfc0ba5132cc845ce03e93c42d4b49eace225d93464be0dd4e6536ed960f0d51a22a1bf7411b1d596385ef1580b574ff85c8a03aff086b11c4dfe2b327e3c6c355a4432e984e04229a74259d762fd908e82d197c1ae0fdf6166091bc2daf975d2a06bd9b8b92796db62954dfabde727d6bea1dea6187f3252b776d6f6fc113c265d61e0c359c0f3e1a45674c2fca8be9788b99a2335c6ce28aa956ddd1ff65d8ee6f036e78cc59e08f9"}, + {"0000000000000000000000000000000000000000000000000000000000000c80", "0124356ce1406f4b224e830c4b225b4539d479a139184889247b32ae75cb822872cfe75c93b51b1e3e28025357091b4b5f3f967fd3817cdb21a28185bcc0a60ad084ccc7af8eb39287a3efd248449ed5fe5d18b5040918ccf912fd29686511aeb5312af1bd90b18ff30f0eac4cecf23c77b299e0f64b28bf34dfb51158a609d15576c2d7a334cca305f665f942ce05afbf3f504ac0432c265d8671cd07f66ae251b5370f177977f604217ca683120afbfd6432ef19c40abce094133eb11bee6a3a67da754b7bd5a71635cd63b78ec19e2c0b059c2dc65709dabbaee5363b96fe4975a8e959ddb5111ba130ad37e4a9ce1f1699356a88fe8861ddaf04061a5603d9a16d233a8a551f1fbd368626a51cb09219035d0f5d133c1f9adc872220f8779dfe0376979315b6df1e608daf13a996943f8d730495158ed1d35a33a4425d8825fe9ff416e57cbab4f8e1631bb7a0080171bac7006a3799ca54828124e826dea07dfb40561d29fbb56eef47a9b7ad21d2c8f98331767038f6e5114d61a872db9d8b97ba2245a820ede98e1d16e4eb17e2fe1c9f0b553102f6e28cd24cb4291ec1d463d60917d2afa80f530d589a090ec36e004eca319aaece4dee27917e6ae8d983e145708de41481ca3073f0ca0f85e50b56ce9ed5068df200c27aeba2219593ef3f2915228b97e0a3eb279063479a56796af15cfd40d504f755add18b94cef8bb85040532a06d8dafafb71722685cf728615c0f2c0d46e60fe0bb05e3def7b5402a826fce02a40e9123de063870b4fc1377749d762e58cb1d77d95d617bc62b18980afe00de4353394b5c05b816754e062467a8b988bf8365dda63c87d4f07015787b407d4d3ca16d04e194b399ae019c78b635f826ca4466f6d3333afe6bd43d7233f87e6b4f5adcfa399855c02b91230e908303ca974c7c3fc38bbf645f0142f682af1f1a85c86e532dfd4b2fc4f3281b5512567103e96d9c79a0ff65b8df8b4bc7d29db95a97840819d4c94470d1dbc23f4c16e17a3c7b7404ff1ffa140f5a70dc097100b364d4365974528e7786ff63ff0afb65ec9a4f861284bcaa1adcf28c170c1e1bd924197afd20646b778583cbd2e132e96cd5cf00dd77da11ab33bd9f0736d9533474dd54d4c445605653b4db15e284228d9d2cc7b163653363e5a4057649f0f4f90c24ed10f1577cafc5c461ee4b114e25747976547424f3b9de811b3b77e6a392dc47647eb28218f5d20b0e103a0406dec78beb99f1b31d3d968e6766fe0510664886ea465e9d315f6b56c643cec672269a747db80c6368c28b134571399210f7d6de1069e23030a6e71149fbfd7cad846bb3ebd59979c9c39ed93fba839d1fac33fbdc4cb158c43b2853656e532a27469ef8fe41b27d66ce12adba9790d6b99fd0aa99fd61f3b5f80208f1a416f97cadd0a131074c5302146e57da0b350ab876b23df447fbaa38e4133ab29ca353935e871d083c1d1374237a65ee442165fb7575a16b687933c122a2738eef60d6bb7af8a3517b74288cf6c231b517038dad7c4d1072a6851f1398e0e9f12911493c67cf193359d6339f2ebb1b41b84e9fdd848a6170d8577a0b34db7ae5891e9103e790daa3d38acd0d80567e481245d892dfc51911acea791218e76bea7ad3bd5fd5058e60564c56e5ab44fcf4936ac0b37dc8412fcd3d21ac5a7d5d6374894193731e77a8219e9fae1f73370b5c07deb9c4234a7bf57549437cf3a1b0bd11c93516b1a39901505dbcab1beb9d7bede18bb6489dd9b90713d9bf66eeffbfe858a564555c194a0fdfdea8501dd95368a61e9a5f0efcc5347a58867e572dde64650e306446696b7b5df91a045adfd0d6167ed719576264c5be90f22714394bb997a316d0217b110c5b8077"}, + {"0000000000000000000000000000000000000000000000000000000000000625", "0027c7641442df2e7fa446c786bbf9e9eebcf5bda1342fb6c134955cb79f96035a0b45f7959e318ea0ea0721698467e53db73d4c50f25f643cd8595d37f7e20aca2776b6af0d5fcefca4815ff5e6dd3c4bcf765d00f0b220c2ee0047a43933e37dc8f6e677de5d251533d9feac5fce4eb3f261635b4c4a2425448870c30811766eb6b84684aaa86c845b32e824d1976a1a6cc4117cdec323e74ae9bd7867899273f2ef280a1cf81000fa80bda0e412f3bfefb25628a39c716ff7f12f61017bb7b9151e71839d6ae131c3e0feb9a1425f22fa19c71f06e996ae9f29ee033308c0b4c98a14303a8f2a4ce1872b9bcf3bee3d747390e4b64b1817fd45730e6fd151d74f2da3d992a59b0f34978ed435faff7e0fcc20d9a0681acda9f861e7c9947e58b6245ee2ac1affe932e8d5d4031d7ac8b78bd8ae1261239b382424e889c62dea95ed9bde99f5eff834dea5145e42b20201553a2097343b0559a6d920d3ea422e1c3b4fc11860a23ab5939c0183456261e6589bfaf47b5e312404047db844c96dcc4dd483844dedfa86536ed348880e9f8969f09e1bb1468124c22941d429dcaa95708e1ae54635c05b9fd0f6d3a218c8e28320ee481bbb161bfc1e81da29ca9f5adae67567d7042a548edbb82b22031a2ee809dfbabc8d14b36ade83460475bae7434a1ffd8bef15ac08ea35050245e5b5e64257f961e907d3d3aeb326882bad22314915f8bb7cf63829a06c0e6de8fb5f46287117909241554413aab686ff0f87125ebb91db0678d684f4e4b722e41ae1cdddbd197128940eb940d7a9a2e3af04d373cf0f01416dada9440d0a29ead657d0af21fb9588702f39c19febaeaec30d65abf1f21bc159adb762c8253803534d53bf4a1a21a8867158a061c5f6f206aab6c1a511ef055d43b7266f6b316fdbc105836414ba3a56dc0174a05716d20057f15ee3907c494db1c2304327b6589760aa9e8d735b259d86dd8b81999677ce947c5ede727dd9374a00921f76d87bdcd3fff578a02fde6a9fa02d3e081a054143229904a815d5a546f8c856b665dfb059372908c5c71f11301653a660b4218d35a18de4ca1ea1b612d46eeb819be50fcafc948a19aa52eaaee0dab7940fa240c350d99665d5a4a8402ed30e4a2687f512ff65755f8c1ca56c3b8b443a7cf1e7b1ffad671e1e170da5d455afdb4bfbf7b73375867074af081c7da6802d0cf1f1bce335536ce15641c44fbd5d96a30ff5fe1a0c76f7afed3e2db25c35953a553426ef62b7a0359e611db334f3b6efb8eb6b1e26f5832708ff5f6c901612926202d1af5ac95a3340d3a2fbaf30179b9fd121000787318e9b6df5c055db8f7028c1ac308f20731aee7b4943186cbec5d6d5e0e3710f1da076fbda753a0bf22c336741a170ccf3f7594d05117c603a91330173f143bf0123851aff70aa6cc297f9cb96da4e230c7f4c71d1d21507e671959672ed5bd322b5bfe5a50be58c96f294654d7c78e5ac3c7ae122877d5688cd0d364085faab9c7f608d41c5c1fe5c64f9167aaaf303cfa7f30d1d1897cd1a6147adb5afd13e33b472f21d472346110f601db3cc52229a668f8664229fec2e1bd922407d504baac86121d5311aecc7943b5d11f3281fbaae71686197fb0f968443c994e72556dbf09603c1ea203d7841cde7616798f776ea4e51b599aeee08e721d97106f1566ea879072ccbcc4668c735c6c20a57ef45063a8c6be8d3d16653164939157eda32e220bd3f787027f6a19ed886b252d1e23a752bbaadb60d83474f445bad9d1659f640cb324b4f24cf3fd24f164c62c4fea830ddedce5226952a75e0e9b7ec68ef31e6eaa96da7db817d5edcef11e8cfa756e67e44954dae5aaf837992c1dd6856dcb7c25152454074dbf2"}, + {"0000000000000000000000000000000000000000000000000000000000000217", "00497e2f54186131f9d932ca36aa90e171bc1f26bf3ac1db282010a527cb71c72fc3f5dd5e443bbc5c19136ffbd63b90f468bd55838c70bf98e2fa747ae92e1ab1a6f3cc89827ee1621c6671fa49972e257b05920cd22ebf4bc7579f49a4531ec77b73a16401f19fa819eb5fd8f3d32bf2de86a4266523f92dda26bb608620ca4f050a13602f6c3bd3275cc3530f56b31e14f32d4224b8e350f89310c71546c9b53519f540b3bf60056df6b33922e083a81213ba2c5121b51a5d3169a61edae13d48a1d33368366474b2aa58bd1e695e8f27064a326854d543ded2cc748a86fdbb02aa7e1e2a0c1d4a4382cf0afe129bae62d87ee6118e3a57b3f32a13bb7ab4f5d594c1c57061c13b0f6d8109e42f3d293c9f4f2d24fc512de33de8f1774a4832df29dabd3424b89f8f790ad5b6955912b3df3cfa398fd8eff5532c7cbba27ce3dc97bc62557ccb3887b60789f08da50832472d745651ad1ad768725e568082621f16664a1f48c3aa2ed0f2611787543d72a7f1258874ff35790a82f0d726628ac370f172992fe437aaf6ab78d430131879a8fd23ebb79b249257a86750fd6875b69783107a5335a017ae30c09b728bf4414f08fe6739cfca1e5b6f4373d5cac7ac077210814bed69c5e1b307b3443ec44e38939dab773278a283d066e69ba5fbbb255a28237735aa6e05792da6917d70b595abdf1243e60e863580ac1092b9f2b67341f4d4d0d79cf67d3b142dad3d974dd48471c481a5feebb570f2cf82bbea541006cfb5c34de3d7fbcb6229a7ed57153985de4e961cba255ec252aaeca6b383c2f9ba83022421d70e6017f456197e149910d07aea14bce14426a78cd7baa220b1b1c6ef60e5bb34e7a2ed82dc6968cbc2d824e91803dd5e89e40a87c2b4b94c71d7665385b0becafb21dcf36b060921dbad1fa274ee4b0a0fc2857ff813011e436e3f42f7ea6d1c52cf1eb778fef4837b7a433ffb4e738bb75f2bec3b7902e454251b70729be589167148f4cddd390f91c7c1e0d41de2c2ecc4f9e6052e79bc584b68632b5d46c318e2ebc495c9b9b30364033cdd204026fdbd5173f1fd3f12eec97f235a615f3e21e49b89e31abd1f2725582866aea19ae593fd0e1a98bb195d3b2f5bf0a3a860cde541db0a603f02301cafa7f79f4b7e2342a30244b1bdcf0a14945c44930268568e59ef41eda9d0e3d938d8bc81c164dcc3b00ba3438c9f845737127a661825f7debd9103f45b530ca5f61c701b3dcf5c76d281485fc71163f5ed5da81e2819f2b29297a7f69f5747f74c6efe0d53909294031deeeef18c0ed3c2d9c3fab7570332e90437d53c176983f51293ba994b5a73014c2485bddafd33b0f81307ca9c04c4f372db05720337dc23f5c428bf370a3a4f5dc6e2e8adbf7617c58464d038a9fb0bf7868b01dd1e947d429892c5a7c2ec585ddb04bcce4c11502b5ddc1f4a9c00af8163d4c4fe72288d6522d7e6cf161aa4e0ff4c76f75997638c4ab7687d67955ddbf14d9beb7e896e700beb5ef53d1f6e2ead8c717a60ff0847de075f0c3826a7383b149d6a3692cc365ed0e22e23a4150ad5305cc4aa56e080fe54e5dcdbffd2e51c9ffc56c89e18492b2a98f2f058bb723f1c52c78229a974f84c6534334508d895e2eb95468016bb5d060b56587df3efd927edd0072c8667f95afdadbc29b214888e73db9494a5733ea2672740861d72d1b681f611593ff28c851a13d6ffb1fff1ae4ab98d679d2e5e1ba80c0d5d5b2d0b2d9166ae9cdba0feb7ce5c2dca1079f8a1b79fcd89e31a12e2607763891552bf771d2f789a37cc52401d5cd4345314b8aeba499b5b16ea19865783c98e65a98840e57d3dbef8c5e15a5b17ec205acd22b153a4a3d0cbd3bacca73f767afb55a254"}, + {"0000000000000000000000000000000000000000000000000000000000000642", "0009f24f53dadd7efd36306647234aaef8de5f56700a07e381b985953a9c15d2888de9bd59acc9bd723805a58657dd5318caea8cb389d272ee2137303bd79214a3ba1db8d4e1b3943fd3ea324e3214fbc18bf9f510c8498f341437f36969d3fc60f2d48e615edb7aad181771fca6aabc4162b252c391e2368eed2bdfecd23e591a679920539b6f13842d7ca45c31733c16e3c047cc932458b54f3fe88428ff19cad172dbb7fef64e05e9006e68519fd5b2d6c923cfcdce86f9aa9d4c7910c0ac80a29884550732e45ca6abf2b2c84f9b2c520a64fb281c5903a107ad02d200fcd266c066f9885635355bc1ca3031ad912144a702253e9971a6de405409c241df3084ec5e87e013add16659957783715fd9269eaee8d9cb3e7ea67ed2e1774fc9fad4ed7c61e31cc135253596378b38fb7973db67b7974acd3f3af4455a04a169a9fa657fb9b49913ee539e39cdd96d0a001efebd9e0b53795880912b44d99b1a129192c4aa0bea4f3138e885b3b5bfb0e6806211acb97818260506b4faf4eee691f96e3b54132dda18daad947d17fc17812ef193880d136c4941ae995001f95e3a3d98e80aa2bab339432bbca59831ebf9b42a6ec8b53a9f0710006fa9a41a48093353d4de1fc8675be0299f3eac1eb7c9cdbc59ba538fc34360ac3f61f302149d6dae6127ddfef1df07bfe32636733f45bb95a0da756a9c057afdfaa0eb071db1ebb07a0534b84cb399c5bc101f25ab1fcf4b90a9bc50524a7c52861218af1c4194161b61d8516660f3790ec1f8a05271913077b6b4572e9893fd6c0d1c7d65d294fec5ab2375f61531fc130d64a22147244447fb54b1e424ddeabe8d0977d05f243e5d1376996d33f1b3b5641e733a7722abbd8a721b255e253ae246cf7e3fe9a9a95ba75e9456d51acd1d1a1ebac4e58da3f9e582206639b19a0ca9769257020e21bbb8c92a88e66bc09ed6b5195c2bee63feab0f337acbcc7b297ff23e74ecd6edaeb5c406568dca13d436bd52d0cdf4c0c3f49ee3bb5c77109b9baee34212cd5e835999c765f4857906f63cda7d7dfdad78023554ef672142e1bc4eb6e23d74d789eb3e1dbfe50c664458b58ce06bd55eb4af0bf67d5d2f40f848a202d8a84c2af14ce9bec0a0c62ad902d5be3cd825791c727f0f8a8d0121555832e35d583b44f4944abc11025bb59817a8688bc5fbd26c14acd9d4ed573bee8d32554e15d1505272fd73677971d0f22e1a8a141db6064f9bbf9898fae935d9f23b0eb9fccae499fb1c1a09d50f6be5cdb2aea62ee174bc737f12291491acb0043598581aa78d8bf16410afd5f0332c56531083f32ce9399250598b6f17b179a446fafff2cefd77304904dd841693959c51381d9317a2dc5e862cbcb556de2c2f6b5246a1d27bb8844707f96f0cb6d75b9b8c3a02821cf857f45e6ba9f301e4d52d72b0bed0f4a42e07b9e58a129baa9fdc078952137c16df0f2abe6d6a160e52ea337297b1dd37025c31cb564a021d74bb621a9abb6b614b08cec410c44308d223a519d98a57d108c62eccd1c4f93c9d58f3b8fd22da82234af27ed21a926f1ff8b4323df3d882e88165e1994b2e3669490a2a314920d1e0a31883c478234a39f9f7ae39b74037fe9c5133145997515ba661336ca7bb8984bfff450434c03e9c6854fd8e5fa19ecbd9a8a6849cbb6515254f4df50cd20b9fab9cb39d24fbe44562374dfe1b1e5d1adf10b37b2fbfffb5681130cfa62f033889793b9edc0d0c668bc99384e51b11d149a1795f1c6fc90e81c5b9dda9c069b7277163f7184add1968f825b01dcd1b0eac090bd3796fe38c15ff1895a410fcf8f61ad6fc295aa44021b83d84dcf047d2f64816773e0621ea4bbfdeb04f97c986d56be2ff5bd315a5ff6358"}, + {"0000000000000000000000000000000000000000000000000000000000000cbc", "002f39326974fc51d9ff50c71cd16570baf0ac5338199689bd654d577e96f4f6435c7b7c6b7b6b7d95a810e29437dcd0f66dcfbdd1148392eb95a839983803116b22d1ca8a7de7e0e335e0ace64fad927712ccea05667b86439a6a6f1648bb23a37bac837a9bff23b5290865c0749b2d60ed70b33e865e3bfa0a6570615d11e2d54bf78b90e900a551b329f2d12d8d2e1a927e3efefa451bab9153aac3a6fd2dc384e9ec9f3057c907cdd311d494ebacb005531cea193511a0e41859d60cc4166c95555b0177f157c620cbbfe5ffb7f48aa20e4f7afb7a6f45a1dea9d1b47b692e1ebb69dd4d4582f1a68531741cc1f2b159e3c56f437eb5863cedce10d8427073a6a3f5ef23e5db8c75dfa981e2d745471899ebbe8daa47c5be12459451d590068f6fd4d90f11b5f6b412884e5bc80d06a7ee68bdbb112c5dcdbd1582acbeb94b7f8fc15923ffd45917b61b9135f0d00185ba99e3b0fa89b16045536fb76bc1cdd313434e33f576ccf952a53de022048be9791ac55f5cb4b0c4169c1d0733da9ef1eebac5de197dfa0ba78b3dd7403d9d6d610ae5cd9769d1d5ff8bea94a5bc6d159eaf0a85a7226fe4c3cfcef09424bd4f02ae54789ecfae0feb047c96135ff7f17304a46e4c2b6e7b1a16d19b0fe347c6df1b97cde7c936a1d2cbba2b17a01eb2972389cd1665a49b8b8c0ec23fc1cc326d2d3a307d1006b1d0d20bb29f5da4eed3b5424f711754097d6fe308245b8c1923eb6de14c34203abf118938c9f3b4b50f1b695f7783d9a8fe9ac51b134aae1dc6433ca18c106964aced8792effb23186995546ae313fd7f6f39126cb2f02948a3967838e7756348b4422bc87a371c4b63a2f132d79f754d1de569a5e67c022a3d3a1d2d1400fedfc646a633b00a019d44a08a69ca31df87a316c018d17447d1da8e2e22d7d1d39b962ff89b6cd50252e667cb425de124a7c7e04373dd3a2961923bd30ee279150e57ddb1d162e5991e316c556ce0ef52d00da3ac2c50922ab1b88211827c6e4dfd4af1cf690a277dfedc7e5d32078665955f3ee7cdcdf0501355c40920385c2a5f63a98072e5f52cb3a862c8cddb202f35938e1dcb9dca119893aaaf0375b59fe4ab9f456d124c3626e74ca5f76b3d37b1e8c56b8291225d8252211014fd790d62e5e77cd2320365f772194538a24a05951e0cbf8eb54b93c7119b1a7330749b3adfe2b52323ce97aa14714bfb36f5112dd1c2758f248ed5260fa01f1ca6c9c705ffc73be1c77f5f9b1c233fcde01b63b9bc222285d51a30a613713c4786a9975b4a760ca2c88a8e6db4cdfbebe67c4e3fa7bf54f7fec4685747d48258a72b41b0bd75a05be43b85bd0f3f16b9290b0bada9bd11f9ebdc16ab22c6525ec41a3a4f19308b5a2e3114445b0534460d9043f7c676d2186e330441fb7c81274f39fe2fe36439cead729a1b7a62280f3d6921d4202c951c7b5589defc4b5e613cba90db09001f8ee0a576655670d211eac445a12248925eab395fdf84fd95dd9fc8d1f3c7814c68964ab4d29dcd0dda98cb67da517fb9ee8955007e8d3fab37fe8873431e9a90af3114938ca5f6b3064fe66ea27ed9048820a3da412496e51f2c44784f96e8665e525d1dcbd431cd422d3695ffaecd3514bd47ac543e6e1f3e5e7e0506228b1dd74d39bb5210937f6cf5e35a6c1d9d562b458443f118616aef7fb2c08e3bf5b7112f1f6f7b06278dcc470280882a7081e653b71a9714ae5c138e0d4bc79a9f6bcf0785b0d12d58e9b569b01f581b210522fd7f3147c874a6b7a4781c641936971cb8c2661748995f81108b5969e414401a300519efb8f9891e0b25c104ce8ce9dac543c24871db8c4e2db8b460b13fe69ef6be5f5387323664c4e64e4fcd48ddf4aae3"}, + {"0000000000000000000000000000000000000000000000000000000000002ca1", "00300bc198c86c744e2d0370e3e8d0352e382e24e80726bf4bb9084f6ca6a690b0da6e83c4cb805619d604a99ea32cd4b6ef82ad912c8eeee599ca5e6f371818a2cccea0196ea3a74663ec6e6a12019bc8d641db0263c7d6b91634d3e5edb0645673d4a0f87fbf0c950d0a7245e4868bfb323e545ed94724ca3dc236c3dd0bbb6b54dbd4fb1953fb11555d2e057a4ec7193cc2259ddbaa610e7af526dfc63bb9ca5d8756485bebc3089d4e8dbd16b0bcd9c4638b27eb28a11e812d8d6d31b32de0c69af329f227599ce3701c62c7faf769c108d93d54bbb23f03ec10a485b8bb0e77276e5a259920e4bcac5be6e4c36d5524a9a431fbee7c2e98dc280f9864ef5f888d0ee0de1330e99bf6ca8dddb7563832bbf530649abf10e09c1a208574ac7aa2699e06471e258759e7f74915c442e31d12b36405261b33409e2b18fa6a40a100059fe0b2b92dea646af8747b3f7c02c105fca211f76120c9a622997fc9da5229b94f7d07df869c032b2209f00260e327d3b496eaca59f6f612c9cdc432ec450b798651ec0f954120a4ea142d2f3e873b2954d0556b81774787214c2f930dd69c1747082f5a8cbb9510a9fbc602936feb4a8dc181749d321d1286d111ce3dcd28ebd78a67d37c925c711b35f20f175fd9ccd1e871a0c653d2da7995697b69f76251260a7c934f9fa12178bfb87148d7b8ded717777b030375dbc0a720471707dc5429907466c7096e5f60b5084eae315ed4179f5e3e946aa45fd65dbf9252d44b10d1e0c86e564be1a6dd71884cb0d86da424fa0bbf28cf4969ec0cddb765c773c7def8cdd65ec47ff87b1716c717dacf04df404a68fc5b4a7b1f23db7a881f1f3821b04cceea8de37d64fac6c6e55da86777922e265fc40161931f4aff68d7e0e140f55e65d4faa0cb2aa945f9e39462e17cd07708e8f839df0c3cb8e91b038b467faf30db51fddb24a838745f75ee25af970a06179f30468afe55780b61dba8cc82a53b4d09f23a1821adba10679e655aac72f7b1591a597135f73c451d37549a7edb5937f83671f4b55c8e0e1b6bd7f4bb095765cdfc973a6771cb02c4717e0dae79919782360c26b8ee13142a7decad40fbb539603c7c98d72872228d05b4cc98580be239775c50544365db4bbe6d0d785b7fd4ff33fe75ce622a665b57692b34409c365c0664af995197b7bdb6ae11c3564689916e2ddd86a71a7e8a4e771a95dfa37061d93cb84ffae50e9f3578223e6cf29834a3abd345c444c66982993a94f112fd34523455ee1ed819ecee642593dff6758f0c9d299e09f096b18753f572b27ab5406ef77765a8129973ca3857d6f81ed178c4901544a4f7fff2a600497bde8b21087db8ab8cf109c00c7328a42993cf530d7c3c8245a7f7722599f3bf53cf0ba5e263485b42e4bbb06c0421fab1389435214d866447ec67b2eef826fea6c32b4433a97fdcbe37383b6668abcef5dde9c719f7f22211749d8112df5d5d3993ac46a0b44129fc59bce52d8c9dbcc154807922f965738cd0b216b665fc5968062fbfdf6e5ea815e68ff613a33fb1f60b94dd9b7d255e8c80e81535b91f5f2ad0726d0bcabe803a5e3107166fb7e644eaeb86c942314a6de8e1f5801a012908571e03d7d548db16654125529f81d504e175062807410bd0b220833f778f41485e66b79ccec4bae7d526eabcc431195c97bb7dc296d6b154f65872d5506132df59cb525302d930eb633b5ab9d1560b3d5cd74f338dcc90242f01358f2d158731d89335fc1752b019096c72f88351d786ba8f86d2e551d85a21607adb662a436658e05c6dc7b69d83f444c4623f06dc3ca4910d9aef92380dae68f6f1044440f2ea399b1d78018b4e5352ab1598105582d30580c7ef85458bf273438d"}, + {"0000000000000000000000000000000000000000000000000000000000000601", "00a52925b268311fa6fbb0ff7c58061566097f05f4134f28ce5e8fea109cbed1fdc974da78a14fcbda7308cad94d90d184c3f0a621c8dfc6cf4ddaa793e5c30e1b28840fb8af27e770b2077cf2773e796af6d9df0fe82c8d5f316f37ad71b1294dddc1104f5596a87d1ae13fedcc10b174d9b5c66c653fbe4e4ab63e75841b5f7cfe06e60d8133af15bbda5b0eadbb5d707df71f71fb852c571ddbf6e9f618f6dc956dadb2ff76bd1022e5bd6d87f7d9169ed17fcfbcc30fe7fd9ff69d1be329f6410f72d9efad9b3d0cda839772f69ca3de1e5149b96e8cbac8f62c6334ec6f54ca1d62daae23273bef8b6dcdecd1bb1e25a193f1353eb4157ce7be1944ca3a842ccb45eeafa673203e66ea700f3b3ff821cc3d4c19f14f13e60612c86d6405635619dacc4b4c19bf94bbd494978555995d8b763f06a020fdb7475ad9af06c8f1e291e8148753fec5ea2656385a9c1d00f5309046c5ac15b70021c5311e1b3c9653f5cd9c0f67139ef4e1153b61914232301ed511aa17b340bc0417afea4d0df0d6cac405065937b5960c8a5aec8109c3f417958de737122162d321f95c7a44cdbbe23702cd543f10cd7c29da3506b717ec28779f551ddc94109c2fae409966f51fbdf12607de70b1e5c8afda891237da9bcf0d0bd14e1ed3284cb23d42d68f3f8cc81aeea2cbe690044328f5e24ce1416fb5dcf8f239ef016190574b349ae5fab6517571ff13e1009df52456197322d6411dd0b3770063e4c43b052561c6901f5e12d3f39cbd108e2511f235991b3a37d3062bf8a23744b38cc7271764f304a105de557ab0ae3d58932b9f04f58f9c1084c8637cda2869cde213d71d013bb01f0d8d91cea2a97bffa0b201fc6e14b7bf78829d40d50d3656bb849b9d7f620c058375c2a9aa35a973cfc639bb86b1d52976e96939f74d6ad6ae7e4c03d2ed800195da5b98c28a2cefdb21533bbef954e9b4b4e5560ebc097e8492d3c53dbad20ba56aa24db81c6fcab106dc3618bc873976dee2258d593a97b9a1f85fbbbf15656b780a0f1c2732b762033bf604a956a05ef4701121faaf9b86b70fd1ebb60cccfa580b1e9ebe4042161ab46ecc52b1a2cb6c01e3cd1a25b6ee17b79a7e1a56673affda3694f608028fe19da8bf1d0b59fbc62488f303e88f0f5df66e640364bf73beebafbfc60e05752c38aa43a8eb20a5e7037641ac8e430c7adbaf0b040f27846bfc6b803ef48049d756c139931da18a0b2395f7dec5ae1bd1b091508a2cadfc787231065a69dab68f8429e337922187171ed66dfa9904f9fd8f08e66aa1b321a2a138cde1dc1b3dea60c6931f1446509ce3ee8ad44ca1c159b867f86ffb6f103d5cea173012d56a940fbb658f54c5dd73421eae2a46f91e8037f3bbfcd05449a37d54772a19de807603e3bfe10104264a6cbf50f819c23d113b7057b679a1c0ae55a716e615225946bf484fe592b1006fa379fcdd500709133b095cea4862d94579721b3cc3dd09963bf16abf26e7c2dd366edb27bd55f3bf525c4cc5d697fcaa210633732f750448f5a36b922f65be40cd7bced73ac24f426591ee9468e6afb497b4d7ffca3abdd0ff179e0945ea42044354a73c2a416c2e9671310dab3f6649422f124c9ff052d1a8d8257619b69186d1d038b86c04716c5470cb9910e956f17d0d4a03a61ae77e45461bf4ef94301d5242ed66a3ffc0f920d205fdb070fd04a1da09129e9d93d0cfa18ce922faf13171b9d8dd0f66ba48cb07d3519c6123fd8a45107a3bde7885520d0d4d4da9cb115be9f2f686663d220dc7dc14ab06340314f14e11dd4f4d3f47474dcaa3fe6363bda3181055cbb05d9eb91d6bd86509c8507b7e72085c5939247ccfb0e549a10e69da348d255ed0b256291c1b60"}, + {"0000000000000000000000000000000000000000000000000000000000000385", "01664300c29c6af1b90f80a55969bf308f5b19c14f13b60d7e9e4fba01a614d4ba332bad5561e27fb807058f452c049995bd20e4749e492733cb3dcf9e78e111fa5d47f4ae4149d13f61d43fe989777813de776903f1f7c429ead11dc43dc3593ff246fe684576a4771579d7d9feed8179d50fc431d5c4f1756d9d0e79cb087e657974a4ec3182e227dbfebf48567196de552d17ce89ddb9e8401370525269e4a0120b0addb8ec5802d9a2b47cd1dac93ce3e70cc7be74decd5a7945c9148db917c545e83494a16749e3e0315e620519b0740a0f89a8e319570dc1de2122051c77b59e051a40f842eae3b897a655fb396b94989f32803166588fe6a507f867e759c7f8cde11431dee7acb0f770aa7c0f833f7d251d4aa0bb29dbe3b8d9bfd9a8db61a79b892e266bd7fd61d3c3d96f55b3b075ecec7dfdb3f53a7d405732e8adb1a0bbc704e5e6c632b28736b0bf18d201a62a95d7021f9b266a40d5a0d4796aac769915761183ac79e805ba14f51c12f3cfc668b66dad795fc513f14ad4eb19998f060af72f1147d4af9f371ee05a5f20931e64282a2de4b195f3f73fa00b1d2ebc7ae801ec63b74dc6fc4adebf38e6d36af7a6dcd77c4103157177958a5d04e4fe4f139c8a511b2953aad0c4fc102728a9691b689918dd99f799fcd833b11abe1a132165748f7dcdb06e8c1f832f46331de71a1ff9d8f3027fd81c1f12c24af2a4f39e3030ec71d7c3b7980c09dec7da9612afd4db31b22c6c67d71d455fcad6a31feb8c449e88bbdb5f3b78ab29e691ba961b1c1ca245bb2623a7606b03a47e3784a054122eca0af881020433e292dcce083d8e3992bb1f982481833b905c9e0eab776b8293aa4bff8d443a2ac0e1c5273e0df2a21e88457b054fc3fce190134932f86e310954f17677220bb3b3ea5a1ae71daadd793374c1eb733fdbbec9017b798f180b1d770c86c29c2f2db5795294ecc0370d8a014d8a8660dcd8ab245b4f4edf3531816f33f9298305cc1d9a7b9af1dd9336af5996995c9d3522e0361d763b69d5b1acee7b753cf9fce41360643d6b8601a8a256edc1f661761891d816ee96f124ff55a8c66ac505ce6b2ec6ebd54a79639270c84a71f71549010f99f7428759b815b36c25504cad4449e44b1eaf4739aeada9c9563057c6e4c5731a45ddb9800b73a9a3028e5de01f59440f0be0557d0d76858d7fe5ae1f1563b507b1c39a4d253524b9804ce863226cfe945ec527aee5cbae4bd2cd0454f38c90a2b65b573d1b7e622a84f15c1ff84a1ffa3273f433417e2284667fb9d5117e119be18a428c71e4525078313bd0b50034a6312583c1d98a101ec1d45f2463e460e5a55d3e0f6a201d16fc44a6106133af34c3c6ba4a964af8c6dcd67d21d3af23820f41514bddf30fae1f66ae6e229e6d630204f8a74dcbb35066f7543604a1b51aae09778d2b046ca48df654f616f1c143cb89a4a79577737505f822790206e70ff6e7e63d02f1874716f5a7577859c3259a2ac42fca3f8f5719a318159a17f53f976a411a04f82e7dadd58bf17b0348bb5eedae8ec99fdbea0d0c48739112106fe9752ec419a07ae5aa5b48b9c1b310714e09e1c71b6586c718ab756be95e80e71524bc225d69c0454e419eafb6d8c9a4eb2a8245e51a9a570247743aea18ccf6fff3b7d03dbfc5a6ce4178289839381f271eb804b5cfd2d3cda5bef1669c1c78a9c70710fc72d5ef29098bfd810d7cac4d2a25fd1d3c4454800c8556261947f3a8f9db13f030bf505e5b868108d0a287bd6052ff865310d5346d7ba83f9788a85a335977bee4a564c7a6822767e1cffd0f35197f98f110d3aac13155d03b0a3c43a4abc3d7d9bb22963fe111c16e112e0fd0915c84e6b8cc413142d16a3e1e24"}, + {"00000000000000000000000000000000000000000000000000000000000017be", "0056dbe2d1558381705130ea16a2e8291c0eeab8340a730e985dc5bb3b4c5770afef4da1e434e91de16f175d7122bf2286cda03291a2edb80d04c2945091b117e37a9ed655d0abd856f6a6b65ce7b1b7b63a489100951d6bf580b7a4f8dbe2306d9b58521de27895d302933432751a62efc0e604dd447cea35d6798ecf650fd391646e4a454f68d6415469d8788ec1a6590fc110c1175aafc4e1869408442466b616c1739b0bbd41041beb7e7ec639a3faf913576ad9113799faff70881b49395ed1a5a305b8abd6f645ef31523001f586bc1098fd142fdc83dd1685d60689dd80a6b64655eadc3a3f6316d79aea0b697206060b334e618db9f39fd8081f8feaf2df948167ff6115b77cd50a61e934e9c70b37b4264c47ee62b8de925cddc86a7d1ed6302e1727d053888e66478bc71764485bcdb541dcb45d947128ed6f3e2e5db80f996193c7ce53d17ebd20babbf502f77b665bd796a103c3220d2ceffe3d213135888b123c940f8b732f1ffa78913feb287884fc69fdf18223f9e9f2c7517d6bee5e434c05cb7f694bad0df62d3e7addadf35387398168e653be797a29ae9b9fda9405a9fd62d6d99effa8e140d4b26653284ce1f3f9760a8266c1a005aa9194a6362a40d249623340195ef609f0eab59ec79f6a696f245619709f3aa0d617a2ce0bed160722b2510db4f53132e96d292cd52d754686059ca6b9d60ce75e7d96406e71191c14b79dbaaf3816ff15dff1d83afcf982319cb0a566ea673fd44f241263a7319a5cd30eeb84a648e4e538cb1e8f9dc22450109db91f1a80d4fbe2085080dbc53e3e765439a111da67fac1b8663de5e953dcf0f307c69e563a1eed137f75dc8d974a234d89525cb4a78268e8cc1c2dc319d017d3b953406b6f45ca94c57a43d6a6b35a5e895834a66002292329b84d6bf948fa5e6f6f775d6afc009a6d95d28d99b39f5d11ff0b5bbf3d42300b98db0280a87ac55eb4d7da2a9385b4c17ea6861ff5ce2506853e601687710782d2a1b6b8aeef8327317bd3e41e29c376481d7a50f8b3a2ea56de0589e69b94b78605bc56aeb110f3e4ba27538124674af13c4bebe0f77ae35f16c560b09b662ce8f79f59f3766b9e5754a408784131f2d159adb2f60339471e4a18e11750bd4a24327a5e5bde53bd50d2c353c0cdc35dce39fa62ff03a631db1f4deaa33ddf31bf6d5893f93a48742efa2487ca742bff7b4dff42547e30db8cf5a3d17fb00a0645a270236038af2a21f727efe575025589b4da3c1cd5e47afd5f18bd6176a4860bba34212b88782bf91597021631cd5e29a79af1a72d4bcc612b7a3f957f18cf6388271cd871361f483fda456b322fa497e3031f61f731beaaee1bc18f26a76ee83d1e395e9e916f27355f26241f6ca33c30b3514376650d664b9525f101cbf1204318b6f3767ad3cab36d384e7dc7d4195e2cda2d5b5b15295f62f6a43736de37a13f9fdb382d0ce1af8c612d7915930d921c55b82ea19ca27318c80fd0b0ab0c93da291efde27a5adb1cda275597e2250609aec909ee372d9080b45293b329f303a93c4c54490d669010d696dd036f762868cd3355b1cdfc8cb523354d96cd4af67865f5351f3e5f27cdca605deedb251823e06d9c77f999dd8324b97dba76d9d798bfd302ee0b1aff04d5bd9db231c2746108d95e630b340e04dbbaa1180ca534797050679bdbb83127756a92ec170b9c08fcd0a17c881b35f249d995965735d66e1d2846a9dd18bb88e9eb3d63cd47d3d82d5f6f3ca2a112dc3af41208b1ccd4c2aaaccedcb8431843fbad4136a167f09c5f0b9b35e2d4556da71b4b2f291ed54f168a2c3cb66eda81aa8f27a7f075b9db1a1e1b196b1aeebc348bd13921fea0c6d73e7f5abe6cd5db085a"}, + {"000000000000000000000000000000000000000000000000000000000000088e", "006a43da6c7b9ffff09a81d276d11e2cebcfc993ed03e2e0a08044e792faf1a25cb14ae09619b0b42693029e72182700db8f314a311b868e8289184479bb306da514732963047130e0d9b8caedd856922498121f0ea14c5844e97cf9de6d8460ab25696e0af9bea25e3220caaedb90b23389beb613cec41cbb2ad15b70c5149f8b44cb60799d3f0df6617f54113f6fc7fe040c188aa0e3ec301aa3a2f555323936f2162d4f59510405a96b5a4f1c3bf140dd03a3dccddd956083ebd4441a596b48e1160f6da87d93897fa514d59282be8a80144dbc5c134cd3ed589e747d1f367c2f19ca19d5501968e10c00dea10b9266f8e64c4a5fea5b8b1941ef0c491d7f8924f0b1b285831c302bed5910b59db03e13231921b96023531942c95ec8d932cf5a6a7b819e0eaa595dc26cdc33819ac138d315abcd3bb3350851101ba8c06bd23e2f582ce5701cec58d6b6cddc267e06131b30849908dfbe0f2740c64da4aa938ab6b19d2ac977ec8e4fb813b52bd2ed3fbf5e9aa20c3c3cc51d1c9e9d6d876c0c782b5553f5397b562c5e16a64439c747641450fd94b45fe409d6f37fba182ab5d5150830d68bfee9e57ff0c0e4e2535830521ca05739a5101ae4b6ff4497133490b6a8d8eeb8c283ac38de921c3f0b921f6fcc9dd850894353f049d3407bdc3b5a398f27d66d70a031d4fc357e0665f90306447b12f00991e49a58ef4b3793c722199125a4b151bb7b2faf1f788e010adc87e57b6291fd1845dd552675592a93416917268929b593c94887f817705b167eb7fb3e5f8de57fa0f9699cd3c4e239e8767f640ad5ed7af76810bb7b99fc6101037362b50cebe3877207a7be6eca584b33d533dbb94ee4effa4e57e75a470347bde38b1281393e2f9f62b54c6ce3ed8c513df569be97c2493cf0372a5f61ce919d1f24160a4c850ee7e078c1c2047cd4017cc8afe7334f4323a9506ff92230393de007d7377756f7a88dfbb831fe96f44c39aedc7d4d2e0e05aed31407338dcf5730ffe2687955264ad1cf46543be5964f2b2cd39dba377818ecd1b63f767c6c8611453906a4a51cd15b5c7319c0bb84f21c3f3cc889175ba20487ec7809ba5cd801c5d181ce3bcadcc6213074318b72171d6cd593b3d8493b18e97c20f3e7f674964f1fb29d7697d05a99056cd9eb164ce0bab07609b999cdb39a0198ef74924f3f422cd6f78bfb365e3064656b0b223603eaadd3b9daae10b9c145f2c38c24d8cb3185384ce5ccb5f3952c9d12053385fa4ef22cccf54f2fa0810d31ade8dd1ff2607750903e792210077ecb3b11a88fb766587a6545704e828d3a9f0010739ffa3f95baad7a87a17b38bc993478c3ca7f001a9522fca20de10dad08a28f181f97950e87b396fa2ea8da2fdb6a04efa274d4779a64396788e1bd0a0f05adc1a99f650d8f474a8412cf228ab5bc9278f206123ff17fe60ee90b353731ebe3131054fa5aba5a5d29a1d4219279bc3bd27515e66733e0c6a1d1ba0ae82f031420602789bfdc8eb57e1378d2ed9bae4d8cb212936c0b0fce04af6df5eb5edf5b14bf09fb9e032c2eb229b15f309971b77233ccc1358e5a0cc1b164c8183a08e19fdeab40f6a921e6cddd84f20d2dba2bae3f4c63f9e290acc9b4fd048e7fff42f52ef975ed5210ab5729569149c346059d5aa073501bc36a1f14b91c6bbe64190ec1b2f56942e278ab6a374c6efcc756186e05b8555c49fb81d9d57f67347d167c0a1ab9d0269059a571a0ed39831dc91cf4d1632aacf7bc7df21a9f550806983a58c5faea14e96092e7b096ffb00e445274fdcc52e711cccfa7a979ca531dfee1373bee3b6d11fe4253b483d9bba50a8a46882e819e57ad0d81e2460dddab264b9e06283b37c6a6c6adb59b995e"}, + {"000000000000000000000000000000000000000000000000000000000000014d", "0096e1752a899332cae450367b2d6d7db1c25c36080800cf3bdba0efb50f8652ae7ceef6c4daddffc6e910085c886959aa3d001e7254e99f20352cf2bdc14024764bd9754c5d7f5643e3cd22f8e9b65b9f139ac503ae7d05d090b0e9ee809404b147d865f151ffce510d86373bc824b9612650f65c877382131e64fd59f61a83070673afaead918d730134527f5b2e3a9b2d5d2189c94e9b4cda25be2385f878d11ad628b53f2753009dac0588de2a5f6331b20ba5a8f8a894e85335e610d10ba447d35ba5c2aba36c35dfb9c9b9d2f3cba102198306e9f1c6a5f275419b80740df5d48b521b4c1dca1d93bd506c1b5933c44cdc406aded7b699e313240d83e1390979a11b5e0453dc5c90b95c4a1ec7ae2828f9fb005442cbcb1778a810d87e9f26f8be6b12240ec5f79dd3acffe5d6d8059be06242e5a7d9d2f4271c04ff890af8ed20a734cf3a3ce191376c4a8cb10118b471a688dbef3f6f01a0f6d5f8e973699b9df61a72c51ecd649613c6cfb2e0ecbfbc052d0e2d3ade08745505159bb1e19ec0e17d39ef5ed8f10d4a93a613e6919b1099190f49b6b24683128f0d4fc10dde770380b7a4bd05282b1e7473d235694c4ed0c83d599a0d29eaa2788f4c12ba0b017b1d690a657bf74f769d20b76bbbeaef0889cb8bb7f346e7c0f728765d7d6b23bb2749560e6b1702cf3369efa1cb710fb77b98e002bd053e79957b14f09ab1111c9ae521ab9833518d3357926618cd9a6512e8aa2de0e36b4791295c9fa8039576026e48347db4e6b377de9ff259534fdaa4984837439c2018e46f226c16d838d14756d012dd6d4a0acb577f0ea0e441980515f995d79f83356f9a738a204c9dfcb528457ba452d53ad64afffe6a89f9dde73962b56b029b2925e44fc5642ab029a1b8a49bb64a3b7044c1b7cf16ea8d1e5407f5b73f7bc5fdbfb36700db6ce17e46b8bedfe0124115cf0ebadfd47ea9ea2839d59af4db301d01c1f37b2e74479dfb12d861ae052ec4dfdb9752039fd1a4e129f6277a70af5d60b12772219d135944f94b5a855f0a5cfeddfc1a1bed540ce01650a151cce1ecf250e377e3c4bc78b4cce33a132462469a184de7449952c9397b4811ba139b490b20a6da7d8ca7abef458039759b5a132ec6011e76a92ed94b286b1747f97bd627d62565951e7f16d9e21308dd4f51d2c5ef638aedd54e0daf500588af9d4cdb62f89c9542a639d77119a942386bb256840e7eb71d1d1baf98a0db1f45801b16482b646821dbfdef4548461fadbb4128163d5beb647a1ab9321d363b0af0f30d61e75b2fcd4f61f6a36681647f688a5a0c58aa501cb4763a65a0a8f90612b2fa061bed65a91055856e36c3a66331f375d19e77547165575fdf26829af2974c504cbc19d79d64c11439d48bfde562f5a0fea2fa04d5e346ec08d18771c3814ddf712aecc20d1677315a51cd967bd87fe7a8da88b36f5803167e1a94b1c931d6a792ba8f7562e177970ce3dd37e6c0f4dc886134759ca07d59bbcce629d3fea7d7214115b42f87b30d0c8f70b346d4af728d6744bb401b05e67c7aa0640f704b158a69f3a3bd08131333c3ca05780b9c0d3f133e23433ec653cccfe0642843780bb62b327d61381cea345d700ce57d775ad35d70e0c22d52135e82d90885b67305c3c7692870b11ee4c1ad68c3d3bfca342e8363e55b9ec35f4552c8f4167b76db4635babdce0cef3cce355812f187c3d5f7ddc6e78df354becf871ab8d71a330c52489c41752e092f125daab95ee5fa0ae7fb9c53353dc7c9cdb1e7065e934d1e5b9125ba1560a429ebc7c6d6c1eb7203bdd9a708c7aa57ea5f2a5c7e5a46a56a59d8f7583f1b7ecd02c5069a1d9048387439bee951bd6a78c515dd3cc3196182ffc726"}, + {"0000000000000000000000000000000000000000000000000000000000000429", "0060e3d23bd52aa8bfe2335c5520fb0d70445fb60300790f2dea4511ba30b4b1eb7895b11e0de67b15011b6346bfa3d0d7d71dacc72d33fd6c423d303b3a391e1dd9055da1d1971fcdf4111249dae6b8197b40690eff645e6270221385e7b2ad83f41228ffe09a8f0f1936dd2a940b0dcc98f943b24539387320b53955222823a7b7c75af55522d7b4f5b8357e6e258b581e0828702bdc96cc0458ef5bc8536eff7b0f655e1dc3920494b8fff4c4bd1cdcee25a7b9ff2fdac1abd8b46f169ff2517f550f42c3d851e78ac1c88c953c3587150a539a2553917d734c1ee35af6ebc7dd6ba7ffc96f10fe3b574748d80477093443e250ccf7894a1fcc5409aa763a38cc6a03e799a1843579dbe7616d9cb3cc241fa96c5ace96dd6bcca4ad3a628e72ad37d780c71896cd7d9d903c4d6222d405205438217daccf2327485076a6fbed7349b59ee926b37cc67afa5cde9d0702f369299d5fed8d7086d0dccf3714df41a5bf43ae0a7e05b87195243736ece310d36aa626930075c1890ec64a4b45861021659983ed8c50b47d58fc7b05ba4e54ec290e24f0916b75c687045efddf2088bfd5c10e0021fd0dab63e1610f01a38421ce346d8126cba01b35da12f5cc4d92fc0078acb65844124e36bff2a7244994cb34d14035b73423e1d1b5f78ed4e31cadc533ea8d27c3180dc54c68c3daf32eb60dc1623cc50303e6de169584a34b0c1149a2f977f7576388fb48ed0bad2296aa49b823b26c06b08ce2e186bfa6dcd0a90afe377e2ba4aa7f6adc621b3fa4bdbd5743992b034dcb1283ab274d01930985e2a5bfe60f1f06bb5f3b0640153166de55f3ae1e235af9a2224cdfd30ac5b8133880b1c88b615aaf78d28aabd1374ed67d9efada122034653c4ccaaef88bb50f6dc3310261e57796fe15f253bb170d6c0f9bc9591bbdd3365a4c0bf45808008c027cbdc3832e93dbc591c8c76be99ac435aa1b050d2d0b4b833694b3281a484856f09f43af7b7bd72063fa262a48d9ecce02829696b5ce15d4b09b7d5342bd5f1cec16bc453c1b753cb862606157bf31043c0662c71466c68cf1eb03258c865ba462e2577f18e91b0876d25bf24895d142e5740562b02388f0bcbed1091147071dcaedeac7070610466c8371a6cf7eba2214fc90cf51519ad156f7f4e80d6edbcdbf453baa99077c0e493d88fb18eb5c87a7116e0f6f8846dcb5322158551ea1df5c3dee9852c2eea4e1cde3183d7f43230621ba0c5e38e5346926b62637111214473e9a4433180be3c7d4cb97451165798dfb129610c49c2c730af2fba5ff4d85b6b7c762183af310fc897b15088a38f2c3b1a3358125d53f99e5cf5f405725dafcdc521d3a96f864cda83e9308b97ed667c7bf199f3cbc6c250d56150751df9b860b430ea936fea22d1cfeea61021fe2acdac59a4ccaffe339a7f16a9adfba5ae4d0190a0e49a30fcb1d2d11d56dae49c1724e0eb51c0e0fa30fbbe54730512434f49e864c097e206f9a6816165544d14adbedaf384613160f6dd544ffbbef957d11fc28eda871ddedf48ff714417e61125ed95f9fbc349ffbc7e13a6e2defc8548914b0c6aa83d49531a5220585de42229ca97205c4bf3765993249f35c21973f5fc4e33595d66bf9a15551114f7aad95e738878302226836dfe1dc2566f1d1f079dcff37213ebffe86039adfd74d959bd1a6cd62d68020ace23b92b844061a6db673649464a9fefd224a252e28820a90544ed52dfbf78480cd6dd0aa88e390e3a032fd0f6d2d8c2b0baa11065b12dbe8b58f2380a0d7aa2975e47e8a273445eb6179daa2832a96f40cc0600785be6a7b945315a1b42e5650f896e439e63d9ffdc465de16ff63ca1b343d82fe53c49ad75c3546f7555705bbebf618af"}, + {"0000000000000000000000000000000000000000000000000000000000001274", "0000fea5fed6c72f6bf731cc279d5202341213079200b1c0a6869e1bdda1042210aac25e20e1b69c518a0afdf132be5630b0d30d82db52777462b560bace964d7535a3712fedf99ce787c69750bb0a6a46dca344090551b028e14aabc63a010aeb464e547820d874614234d665019840dcf2bbe8105eff4ca2a7f97b08a0097d4d83c9b60a23f3b2734d5f716ed31343b9a8b51c2c6d0ebe64f687afca442997299fdb59cadf141400fe55d700ddf767cb0098c566e5411ecf9b9d03912d1615dcec14e5c13d31c49ca2c02d6542c7d007bc0b1315bb9e98d2038c0f1807f85621f6c6657be879168ab6490cc5ff8ce607c3e531554ad31af79fdaf307eb04a880a143bdc609d104f567ee86347435e8d00dffb460f5580f154628a449cbb1186669fabecce211724f28ec7c6c75ffc5d5065968ffbe1fef9b6363618eb345a8b05f6d8fc2a760545b3ce2a18f7b343d00f1f22442982094fd1220648f6f1dd19f7a1cf0480bf259ba82d117f5608382395494e3ad44280cb1e50d116d4b078d524a9ee421e88f10767da2f17b4f3d2279c5a48b9ab0dfbd80b4e7dc5018ae966adad2b402b2029565d3dc0103e206d7eddbb089e7a41912ee0b5435e8500b66688c7e239ea7cf347a002e1c5cab1929dc4ce1e849e3bb3681a20a9b2c189490ea3e2b23e442b602e57fb1851463cb87b4aa860c3e5f046d04f34a15b7c2fcfbe57a25697dd3bc02efd83ccdc321b1e7a9fc92ed29fb4782fa83ca59b925c09c7bb40910ba9728c44535242622efb7253405a3e05ee7bc2eb782d959f2508b9d51a3cd854d4de9ba899309bb0b156eea797243d1dc1a71c8d27719bd98bc5436801da4dcec6cc856a7698233ea7e5a748b9def1f94df2d7baeb604d9c9a3c643d7c21370650249891a30275c26f449b89713d31f73d9688c66ceb3e147ffac070084a9662c855f510d90c0e22aa57e266f7f13e89b0093fc810697c4a0ddb8409ba34d153969ab357be204578a72dd1b1f3b733a21366f1c31251ec2dfabe7242f16e978ccb178a7d004a6f852617afc24d9f5de02888e4a181bf41b6698b4d6c252f549c974755baa38f1a2b001a2c0b99db2c6b269fc030283d8999db315dd7c328f5c92bb05dca1c3bafaa4dcfa887766901d0cd15acd0897dbb75ad6dd4d5d2b7e1208d8431704abe3ca1d0798f7a9e5b0c14064522cae85494cd62a8802db6d5e4717711bb453c8395207a6a15df25c236e22b5764bbf76e842d57ac2f8b6f262a133a522325099fd50114c9af0c6fc4397fe38871a6a3e94750f0fc482d40d133993ef532c6b9ba0ca4c53ba6369124f55256d0730377b65661020ba3edd9ad435a63612306c3cfc8de7c2cfa643fddd66d3ad3161ad31da304cf998bfecee8d67ce24698a40c131d964369ddf014660ad302c16dfa2d301041cb6cd3d6ddc7e059f04eb95ebb2d7a323cd8911ad58e07a137df9be150b19ce55fc5f8fadfdfa7d55e077baf39acbc57719f82022fb3816a4a0dfbac878a09affdd06cf25fc2af402fea3fbdc0a809f0765972176c2caa6520938fde81fb0720e805dc1710e7df3323e21f891877653b7601b156922f4e7cc4bc174d60ddc66c3c19e0e1659194e77939e2ce801b7c08046efea613ad9d42d1135b90210a37ac50fab71686bccc7d4e7456f692edda9960c41c170dbed4109f34ad7d16471e64a728fdba29a224f5ac74fde7667ecb3a92c5456422b41d11ea3ff54c937c5225ddb89b8c67d082a7258c7bf49df93de13155ef70f598cfbe9b1c410d0a790767d8f3fb5d51a116e6ec3d626b57e14a7dca9eb0ad6e2a91a1f5c16964dbad29081fc97b8439a3e728b3f11715e4799409a7e1cfe181feccd2099aef5db70eea12abde6e1"}, + {"0000000000000000000000000000000000000000000000000000000000001332", "007185e1818c8290cfe2c282e0964b24e4c0f615070d5ade4dd6ca5cf581cdd24ab6db2772ec4e1a5dca1a0a43d6cd711ad9d2cb674369437032a3b65b921f26788a127c9e6671ca356650cdf63aedad7c71df1811ead21f9f15a99cd7dce34722f9d2b1ceae9648e21e7099b50914601b3154b2c9cafc981e48ff5843eb2596a34547b7148fd3af33547c7eaf99bd770fc3073129ae98b3a8d1f37d0373ee9be1893e9b967e77e901427500d58c23a8a19364ccf96c5de66d57dbaca31d25c1baa3b3b2ffc03bf40098d57525751854c24127db24279c50af98d452c3a9caf4d36a949e5542b13a76e9e5fc9feb75ddd4358bab6111467b0297d5ca0216a07d77594d12f8b685f9455eb7ce13c4721616364c8e0be5621725a93a94ece36ea0d26e999a301c07ea87c92b43053122b09248ebbf72ae5b5bff3d1c3c71721c44afaa07e7cd19fc4af72656f69738f37f07cf67436e9453b6b87a81498ac0959c8d8bfd416b2d5c5e6d46df1d9d063ec934f77dc6aedfa53c0ecc189cf4610c86cbfec6c703381d9fa9132a5f1f816c4b56d2a28d972e99975708477469e48ea685b92332218584c4b7a4177139f07346cb4a66cdb6493de3c531075d7158a32f9b7e5bc504d258748d8d887b5ed92f86466f3b0c2a4f4c7053ec00e5e6b612df52eecc311e55c12c603b1d9ad0f562ffb4f1623ac5d2493f096d8fa3936dae99f756d1f4aeb6eb45d05eb3ae863e6ebe0a2510f85b32f533f254e195cb159cdfcf0129408de9000fb62b5dee364d7234dede1098772be32f473db0629901c1e6e6971440e4ca4b2e1cfae9411454eb1f82ac518b6687e42e1a73bb8ddd7358c2703149ffea1cf311fbc6e823bdcee584296696ed3e651b45768572cbcfe7eef4a29d53bb33463d4cf3f9171f9f054f0ca0e5e9bd59492d25ff2d9fb2d6be4aee036e335e5e52d77bfd4ec834886fa6164283f84cdd098a64fbe048827ab50a51d74812ca79177fd1974e177bfc2de45e203b5b667448e5229bf22f13f23fae389785c8a5b4d005c45326635c44ed7a55de3f79e7076f0b53cd0ee7d99c0c1558c963ccda1de8985f03197d6133a80b72ee868af21ef327a47ff333dfacd109612d4b4026748fd36da5a19853cb1615dd9714830e4b9f024866ecc76b918205ca3fa1f16cd90dc331052bbb516b9cf6173a5034c12c65883d93c9b3b6070b675ed847966d00b5119300e95a9454efdaf0c74b140ef749ffe7748bc3dba29a1dd8bec2c6557d18ff315e19a847a333bd55b1634c25daaa059bf9d147951589f4ef2289176340f4e7375efd8316fad93f8fdf1df699f60a6c654bcaf4c2b9d1eae8f1bab8bdf83015e7dc3bdd9298dab681656f147d3a9724347d79a3505b26346f9f564396239638d73cc4ce3bf955015506225d37d8a278e3dbc57063b14dadecfb92090567099d138d988e86d76b0c147488f266b97eaebd6b9e1be641bd75377b0fc07c2283b71d2d09143e2a3bd848df6ba93621609bf012659e3d74a4bf5abbfc78bf08e7d0b21648e9f4c7acf0bce34c45a1c035d030d811ac01035347c72eb5c1c23da2bf21c15b039763350c0fe787d6f0b8e7d4e84190a3bb5e197097953a651a10523bde57177d5ffb11dd75630269a231900b73089c884c3bcd842f9c09a213eb2784956c2b90ed462086f5f764200929574492a739b7b0b5b5177f176b08a17cb83149ae5ec96632104ede614d4e8f0c37bd13918204dc1e5a5115b144d7a22fe8432cb77f7f0d098feb14fa95b13aeca0891633591fd25248f8e448288b0b35a626740fd65fe6e19c48c04b21aeded8421f3755df945d0769590b5237f4b773e60fb912f34c56364bfb476cd9e184c1678d1a612f8a3dd65b9867"}, + {"0000000000000000000000000000000000000000000000000000000000000044", "00773b47fb113669fc24767d65d5008a5e9b1afc2017283d75319d04d3e51e84d5bdbfece9a03b77217b0b4f31f449e02565b62640bb52df516cf933f0148c1686a0e072661ad7a04aa6beb954af11e6d2f2cebd07cf48a41d70ecfbc868016550c7f2b4de887adaa8143c9685898b15948ce6e21669a19bbcc5b48d2a181ee6eb95ab21239dccd3a4b3e538c1d702fa590320294e23ed656f47cdc9a552bf22da30a5082b19ebf105153946446ed721c6ae619d64d2d51a9201f6604220a98ad3270c58ad5dde373e5ec58191d16211b4d60e9b9f1e16690405ee42e313542ac8ab057c3a8daf187f3dd776cf9b9d1b91b4de19709f49eddbd9bdea05edf73464a76c097d50a161d09524150f66b5b37108df7c531585d102ed57b114048f63ec69692e4416205126981d888be1f18805060ef10abd778e35469041493ea7e259e63f6043c4803768f0531821ba9f540108e6a0c21e347149e19023ef961f359bffd280521d4673c5b20fd0f6b7c902a7b196f0dcae48cf8a9a0db4cd4c7116d99ecfe313e56ff1742f356ebdb9ba3c227b43216894e3f48ab7099555a49e60e47793800614ac5a0b1bb2e1bc23a277985617d986f7ff3acd0e873181543d7885f1e9f131d7be10f9bc3f92d19a30ba13617daa1b65fb4f433847474d45fb4a9c9d75935f67c0d2b21b9393a1fb061f6e4787a1493dadb4024ffbc8834a7dfe7f5812cbdfa7168e9e4e9daa2f0d87c44a2b4f7991e01474a34966aa061235b6db1808cff4c379b812fdf0cff3559ef390e6e625fd845911d0e52a4f560f4d2558087ae57fefca5b46794b1e2363fa374c77c06be73b6259101a9ab2770cbe3f4741a017156979e6c7f3c305e1f6de3bf6d3315774d926df2d16385cfd12ef1d52bf6dbcda4a1ab773c6e64de7f336cceaf52d8639d7e62a7c5eae3727f2af79027f0e9be38512c8767242fc3439b28d3245d8598b1721a795d3d7f9b8cf453c0caaf1887b2ff8fb7da60362734a3bd6e299e5c1c4501b3f143d453ed340c426c3336127a98ec5cf1145b9bf52f90dd2810ffb06156506476e0d239d89bc07884e59fbf26f59b82ecb49984d4423e11ded798255527567d13ae7971f552730ca5b1ab42ed9bfff15e42eccb80c212c084dad7636a912d2f751a361799f44d4f1781e45eb20bda99904ba1832eb030ce3f303a05593ff8c169aedbad9895243d451fdd4b05580877845176f44fe7273f4f0c1193b4747c4d7552d4c47b46cd8b27ce6d257d920fe5fbf4476c1deb9550d03c700d5e942aab8ab1d2939053574f5cc208223dc9ce45816fce2897e7cdf6be7164b90ce13cc4167a5483321db5969dd7fe4b71984355bb1f4a6a146d5da1be62723da6aa6561537f0bd72b6e61249b156e5a973a90830d996430fc6bf2426037750e05db5f949fe8c174d355a286e32377cdf46584825e4165fde157d59a766457d477ac247f6557d14d0bc3218dab1f90fdc71dc40974a54944d51351f2a4f7da360965d879ab06611453db585c4df79137b03cbab6565242e77a311c260cb483a612a85781e104a49ec7326a7d133bd7b057c8c584a7e2b07fa067f32257ae8a1538a8d5a7f74b286fb07664ce1949a8a3370758bf2e25725799e7530c75b73b25ddf152b050396992a2ccc824defe3244065346441d0a8d6f89a0a2e6760ebc6b526ab6f14472cb4f88b55095c324a34d0efdb39ce22b92dc3073cce4485ceb89a5bda3f478b5b7fa695ead0c96498d85f6a0a5a595553d5aa09b2528a5745d947bdff22909955d55d6548d5542e3cf16fe1edad9d7db27fa71b69bfbd92706c7ee47c21dafd6ca7ec494b7f9c328219e73f26654b3f5f4b2509cc7ea0b4751db98b16854f547efe5c53130584"}, + {"00000000000000000000000000000000000000000000000000000000000004f1", "013de39a9540c2646bde41b816df2d89756bdd12fb1519bfa650deee25cbca4277adb58ace40dffc42a608438ea1119ca633e646e631b03936b9ece51732bf2587917048e4aff7846f769794d07b420ee6f52fb905b273ca0989c07bf81780ffdac8aac65e70d93e3846b73662fd535b015b08b67484f6130afb6b3f7d55154167e3de246cab7994c223ba113d09cc723108d918bc7ac36bcc679efa71a2115dcd197b42f7fa7bf401f1a12316127bc19a81442e48b7726d3177924d7f2bd83d32b059d91faa0012de7ffad2918d25d4db461826c786f0cdaf7cc6b0120164bbeaecfd349dc29024a976d76a18bd39e51e84ce8f7d7811f3efb4173103beca35bc76816bf43622bd26ca657133497f88ad4f39fcfbf3aa7edf86c98564414291f5e5e6dfab1d1c7bf5e30ecd784b9548a46bd446b4f534e73088df2d1c951d558cd550a9e4882f89c975ae87635ff501054814a1299fcdd5fca311975dd7dec1583f33c2460e41cd286f5e0b0bc601311b16f51b85370151249c077cea1c064ad9b32c64b53e63dd247b5d7fdc11466e3e1e2ca9f1af7dae9f5a30ef739456b3803aaa410d24591e5e5d0ba3d4cb93023a7e0e0dd2cf52cef6638beef88e5b6887193278889febe82e8850d56d7c2e5a4442ba10ec43bc6e4459775c5342822217ff79380bee68b11043ff0f52979e81770cf2c407b7770707d4d33ff613ed4b02a921150c4eb1f1ba1dbbde0244b6beb6b65561fccace36401a39ed89a344ae28661c57b2737dd1ffeee15234e177f32f970ecffacd6327afec43a84c9a44913296c3a5f55526f37a1aed340ddb79726214ee2784d0f653284fecbea5727865af54f6ad631967f8b78c8d9924d74cecf3378cfeb6ae105e2d80fa464fc3482118fc747f6cf76f74bc8d9f13a87badff596a55a63003deadc214ddf1c0b0b5db013ed70d1e4f7cbd8958234ec5b4016d0d3ab2d3ff1e63dc0e959adcf9903514fbd4726f86c52ebf643610034a52a26c7dc982e9d15ced1163c57f436c1a99195206f353699bf7f26fa3a721e78cbf3c67fe849d0fe0f78a094bd32d2b7041dc547d7f29cc81954e6319969d2c2b0da3919ab4726e53735e2cc468ec92c6163e9697b19ab3e3a33a2455a2cb3ba5a1f35e0c2b174ff6f88a22796dd8c6d236531aa7415b17d0fe40070f1c78f89544f0d849612f87483a11bfd0be8c0028e11418868f7c98fe3f9332adac616d8c743bdb5e10b7d0e0dec7895b661271617e3f2d01e7291c3bdd282283fd88d2e760b5d6d62bbcdb35c5ce5b17261f10bf5707732f8801e6c7814e397ab60f3394be9b933d6ddb6fac591a19394a19365150c0675f5c7ff951122153c0f4a6e44db6c7914e313a7ff5ba7993e22544581e4e4577d847c48e74d4885348795045164b0d04e266031ee2bf41fd7100a3ac724590cafdbe0b5b09d0e331d2363923c02af3d8f3661ad9aeb054f7e30602f4d88173b23fe4024328eb6759bd8813563b8b0b1872ac365333fd4bccf22b29d05255092f9db3b808531050c6249055347a940b65abf39da93afe3e9c0fa53a3fd98bda05f06cb3bdf5a7fff53aab73a3761d716f6059938e4d924fa282e69b3a7614a512c88239bf8f5ffeecd52beda493f570ecce168a99dbcba50af269f326068f774d496684b45688a5ec9c158eed1063a576ef09293128c02aef62db085fb7827f9b5d166d8d8533ce69a13f84c1cd3cefbe610756fc249877482dbddb5e98854221f8929fd11862d7db1d80b60d81f38c150e293ccb9103693da97c3ea2781decd2370653ceb6d11988982f1861ca6b3e96cf0477f0d51e356d9f832f32dba90a06b4935c4691ba74b420f43d2f3bcc20185b17858529f0ccfd110e8494b97cb5"}, + {"00000000000000000000000000000000000000000000000000000000000000d0", "00943c4eeac4ad0d2385d22d71b81ebe437852c94525b1ed45229dfa76fb38d3c5e3736381c00512db880d79a493af91f15b5d0e724b3b18c537401a1df07a399b94f38ca54e1b4e0c57c24dee681ea8f2d7023d00a40a3f340895f5ad8b9097ee0f9f60457f37828f4c5ddef2f4971f630523189312f512da43e732a4dc0a598e11680804927ac5111afc0db6dda838dd0aae11453e94f71714cd2d35931143a8b54ea1c6bab5610441db62264b442ac009b1417810cba534f24be7bb3f77a78f9b2085cf5acdf580e8db4b7b1a651d2eb8154ba6ff6fd6716980a2d15e4634a786f97458202b25a56627139d6ec14af3c6cd28b7fd2a1f8c1856ef055b58c0e8b59411d64592ab1315f20d4f3092b9c60f6fdb00d82a70957be28921ccea88869114de233d06443cdfaba549439af93128c0c1d2bcf5149f4e1f07d2b190bee2073b8edec31711c86c958c68be359b04510438ae27dde3b76e66a6bbbdd4ebbbe7bed65f77d8e5bdcb212db54a69a7af7e55342dee691eeb1a30f795018d93a048d6731368c99c59ba0ace59ad726f5d4da1c39e31fdc590e8b369fe369300ac98a0e90470d67b80d4cd010528742624c02a12c72496d03d05566248b30f7a92b38e817aa8ddb8449bf16507ea0c557ffb0263a39d6184241119e2619217569c89d43c8bb656e0d6cd790148b44781b2dce32fd65a03ad0d1d693d019cebf96dace0ead12ee5ee12395d3d5c1a7a17307c74f2e7ff1e86f461dfa295f2e9d738f71e895c22078e4d1195885821cb5cd89267631a2c8027f1a7f120255d634c8846bef37197e9dfe1feb34c0d717d2e02c7df7194ac73892b5034099dddde1ef130c697c9ffa00893187a33c962c42f81cf909bde472072d3516b8d7e1533db54e363c255897ebc8c44194db3bdc3bfe7cfd3ba84f6b7216146bdf6683d8edb015604c2f584fa43b43c618ca1936456d8f5deb9b712d09f8fefa3d29f655fa255ec17ff2ff47b7fd6cd0670340a82308ae3e7a481a3795376759adcfdbf5e4e46e52e53d9ebdde37a86659f6676e7c56bbf0c7e05822e03850e916ff6e7526035be5150b59b85d795458dc63dbe95a28fb10f086d5ff0b3137f755dae2a0fdeceeffdcc4213498b53035f721129a7714fbab81848696a6927aa81efaa8497f3bd60126e725a08d204657be4138155103456907750507e2e417f751151226674a099e9a391f7117260e737651d54c7d8c14808d43fec8803f8cccd7841b856c8bcc4920d48e5bc15bbfd8b2291fdf6fbd075dd89525c11aa7eef978e0b009d3660c2c77be674f71ec0479e6fbd269f59660cc084f6d14aa6e5065514d18135bf0955a2cfcefb0d7273565309d401d10523016266a5d3576e5ee2f81092f97f17d12c3152ebb1e7526a80615b2c3c06ae038fe7763c196881f523d1be7b901e06d2e7ff2f321b0b32a1771aa7ad36db32a825af1f624febd78cd91b0cc2f2c312fd9b439ef4c2e35e70d972b8743d3c302591fb1b1d79310bdd838260b98106c406585e51075abb9173520757b19f32aa94ef28f16b167ef10f12313a82e160a8eb31dc11371e5d4ee483deee4e861576d1092e688563930c37d8b66202264e361545f91a5c23ee6610b7f5e01813e07ccade756d7e9a0a87069c0b401717380dcb6d28370e6352ab44ef5ee46d495175b71d56660563318a4025715056fec21cc2c41c5955d8bc94b213606b646f994b726995ff953b611e71831e4f53d5f37f8713f6482786998126dd5b9e0b3642322f0bf056e71489e72d63928f56071be79137bb5d817d60285f4376cb1b84ebdb8709ee9e1823137f671b4047a8ed1f0812ff4d4ac6f12a0fb7b42e1b8418e197531640f68796f0bfddf059d4bb167244"}, + {"0000000000000000000000000000000000000000000000000000000000000ad5", "002f9b1e475e6f6321db87753b7399725380ffd1d030922fd167ed9a59f9517484e2fc88a27073f44d0f2145e6dc4d628cc387f3834f4f50cc7ce72b3c6c362f5c14858f1abfb5361026937df29502ad6536a6eb0099007c6b47e28a553665a0e750d00dfe2c7d1f0814288a5d699ec0ab654af1b5d59370775b65bfb0350242ea4a9fd588fac645e087b75cfc11e9e8b91471309c3c2b6450cd61f80c87dfafe51dd2f0c1be4db007c635ff650d21812f3b92df2638e5790cd68b8e8f2cf743684025ff05640993fd08781ff987096ea32d280647dbb8cff692e5eb884df7c6f7cace34f6b9e33daed25d1b68485de0c56492afc009cd3d7f0b0ffa07e94447af869087f903327482b1fa127a323a7ebf0ef75a4190e06a7365ea9238b0b5a5f8ad933243b907fa309638b9388fdce880ef5cdfcbd5de2b11f086135df6e539c8b8e87328230d38f89b957a55ebe88901eb232e221003f72960246fa87b01a148366bb293096e2edbeec527624d2350fc7cd6f7b50d2c4c26961effd55e49abc557ef3945ed494658922bb198b6ef20bd3ffe20748567cd466650d5bcb09a0d81d293e81663c513171613dbf54e228ba6c400d4e28f35b23e52891fbdc136391dc1d1c77fe4e7298e180951a8b31ee4c93428ea1add61a2c454a44c36359529d224ae6ea993aa47a2b5ed57212a75f06fd9b6a1edf9bca50424497104a0b1e1ed98a4e8cd3c2da749ce5bb45f359f9fab8a4db0aedb16281ad5ee3e1edad35d0261089696463e67e68fc8fa52803affb13d734650949733dc369449e7f03d6ad3c402f5760509592a3c0b920b120a05666b4b6f70d60571a8dfd375f559f927f22b35efc6ae5ea5fdd7a7c5852b398c16fcb099f94f0b69cdfce1e1212f862a628b4a25f025fc8438b6c1318f0ff25a6baca9622dc3198f1fec0932f1d8a930006d1db00d89fd452312f22bc250278e2f809a835b11c63c1ed1574880f0fb94508e323776d52c7c7951044d1be9578be013d7e7948846f53a2d42e4dca573065f1582866f89ddedcbb1b3eaaee070e8fd572394009432d8b74ab166a7b1e788dbe51772862f7a7dfc02ea8c87c68b06653e2373518e2763f278ecb5a844114abcfb22959d66bbd262561e18282560016ee1fa16e93be3fe1d26378e93945bfbe1118a13f21be2df04ec472d202f59b7d65bc350cf63f832b4cbddbe070f61fdaffe0ecbcaf708d276c9ca8ae79dcf3fa234154fd8f863a3b9bf5406a8e85cf0e4c66ff51536f637c4d46daa604fc39f8de4e39830b427d2d23eea021ce41ca58454fd6352f873b4037f861d523c2a9d0d4c1dc67120aa71edb956059f1de1a4861de118359b210a66868fe3020d67e9c339dbc1c61a73fb94110f23471e2c47cc99c135cb328ec0be55e12751f41ef700b20277d841532c79596e55b973de639cb9bf8af38196e4da61f73075bce6c8f9466caa96b7d4f8ccf61787915947ec86a77a71c387fc41e60a7b42dcb88f2cfaad144b12a8cba8da6449d83aaec1b5e8b399c2026d7668edab3d19d5112229ed54945a07fbb55f9a13388280dcd42e80dd1884da2bfc60871dc8ff45cb1bb06658d2e707f9ea7c64b15e67315a9966f746d44a47a3415264e57f3cfaa9ddf7d2686b68189b48bc0d409fc727cd66ddca78d3a50c3ec8924ad37f993926470e0c995f0fedc6ad25913d30818d80238d80531090562c15d27a3999dde1d58c95a26610a738ee4d167592f4d9a0ad3f5bb4a3d4999fc15dfc6ef46a14152982ecc90c4dee642cc2ec8f1a98f93342eef6e6561b435df8b08bc3c847256dd2d689a98ab25890783f8abf3e7d60b0a3e585168091e6deea06597724a65d193f01ab2f26a1d009e90469e3fc971eb3de729d"}, + {"0000000000000000000000000000000000000000000000000000000000001506", "005b0ceeeb6de013dab7318c122a19e234c493601e29c2dbcf6f4bd4d4868fe2e951e703a26ec576aa410cb721477fc940bbc704a57ed153630324139d9a621f324dc8114a5325c909a508fbf7541b18a75d657e1043378899e9e481514203baa4ffb806bf30570ee217e9e75e2d6b583f845853b721d74c4e86febb31f51223dfd95bd032817a4b91299c5d3d06dc72d914cf247271a6ae1047056f17b5d1cfbda5739c37de634401e03270b406865555c192d975564291646d9d5fa813e2370f7c72364bd11a96dba4f7c339fdee3d85a80e9a443ee14885598995b848e5597b9b88e83d57dd19627f5b481c2b6af858c41b02eb7a4a3862d3241802493cc3f7d199ab271c83e6342b4a24fad1ad1bc60d621fba25c814bb94e3610887e5046b0805bba111029fa2f47feb6ac7e881d15b4f2979ef9a04dd20b608f67f1bf1427b1545cca7321cff912b04f59f60fa03683b0af025abb161b021436916912e24b8574ffc91a3b6e5af31b577dd7b1c107c7cba4335de7e9d1e2290a5232a1ebb87d26c0afede785b8b1f0f1c148f436592584e9a769b9e91eabe2565965eeb85dec14c045c1b16011b4c379467085a2d7fc12b40d57d0e1004e79bfdec73a5afaa0f51bab6fe51e1946570f22c0620d83bbb0e364f1ee811137c4c0af33f9ffef98c0daca46fa9883cd1f546852fb0744a7a15ef7d342e06b4b5fde7565ff99ae7756671408ab55daef35878419e2e2313d5fed342bb043daa3f41e30b047e18710c6534fba79a12bbed3b820b6c3801549bb31a744a105e1d93fa5d1001219a5a1fb75ddd6acdc93f78de0ab97d6a6e4345a8b58f524157cceb3ced0199e69b23cd9cb797d5ea01da3aa7ce33689376b5ce57f68a10899b132b3bc72de7a3a8f7805b0892f2df599f7926a01b0227534ac1ba5362f1189c49aec2575bbeb2013880d204c82c38eb495174d43a2f15c8d1dc34e638c4eb9564559c476e29a414e2eda161f86f93dada0150ebf60d2252edfbbce0bf22d2fdfe2ac3d912a41007f95e4c9be0df7895720e6372360161b63ffc7508a3c5ff2a92e4756a9af2aff166f151a430df695f361184c7a98f0f15da9324cea3db906e97565ca1530b0c69bb4a9576a367e970b672deea16648156ecde17ad62ea1a470423dbbfa22535ed1ff09fc0384c99031fd2825cb1279198db125629ec3ff5f7a55845356533f5cd19b4e6c3f12927d744d167fe5726bfef7d117c16f05d61d9816572e2e8d4ae90f98243add2ac4ebc3b9a975534571fe5f5a6ede5ea8a1b713df7ab181c324c6b1b2f531c8c92fe192226b5bc95b0e7091d6d7e6fa3a3cf79b7baf2c4bdfbbb498a7ef875f32478fbc4892dadf3f1bf4909494cd7272b227c72fd653e2768cd1af301205b0731505f3ebe13431ac82207374727bbad295fe3986560af4684ce4e0b3c29a80bc02f8f635eca771576f55d5dac779dad0f5bd0521671c497cfeba1b36e80d1ea19dbc321d6f79c4a0a1811ec618ea977f35a9c2424ba4224eac9be1aeea809c0549624d447f90a3f40b96ad67bd09d3b320cd50f3fb219f36968977d87771b9d4fc98a928fb588c1105dde2e31d4af25bb18c3fc0436f5a661cd3a3b2c852c658398a5393bb7f568e33c71cba2f7231a31fa0ba510b7add98acb9dc7a13034f522adf9e1baf5ac3a7ece90314ed7e7493548498c42ab1645717ace7512ddd1b8b83695a5c1c0b17694224a766945ba5c0e41998dc21ab0cc1bb44a37e6477c03eaab0a9fd5d416bb5b921f0d5c8e9994437e827278911f087e0dc46621d7938d62ab4bd3db388fb6646bf2f81c7df38b2b747fe2d5f22c43aa3cc4544df641e934747256562ddd83b30ae40007b08a2365531d012ae8fbbddaec"}, + {"0000000000000000000000000000000000000000000000000000000000000064", "018d219242e7ff85dbe5c36843f9de75ff65516f0c27477d768f234c337ff1abfe1ae30fa30f3ed9ae102b2c237f56535bc1aebf46a20d3b3b05c5007518883a2574fe29942c1edd78972829fe44360db67bd0c702e20707e7063d25555283ab8b30b065454afec5451734e9734311dca8e993c5cb784ff0398bb4ad0d8d1adc72efc93467a5ed4552e2de471775c493534b1e1cbc4ad3d852df779c47c7faafe5553f411e7fdb800422e6539e5d979903322608ac6afe41d9013d4fd813a82b970148fb36ac5532d2572ae2ddacc391e57b0ccd22362a18652d47a1b34024e84aca10db5ac2461203293a87873386accae16a08dadf2080121e84a70a2b015f8d1fca4d7e3b61e090cf7f2cbd207549f2152711c6cbcdd7a8b13fe9c6646e4b12726759eacf17f4933a140bc60ffc69c3a5d451694552831f7ed41997ff8dceca138caa1de347143370ca3778920b0f03b36e2b3c0ad9c78b98a295a5787a557310902bd9274404219a97c60f22b495745cd6594dad4b58ec40156edefdde572b596bff8344953231e544a7bbf92721a9ab28b2e5463de747a284aa3460d8bc541121c804bf6f0bc71b99d93b2c02d68ffa7bcf99fd1f9a501e6cb402ac4fab39fdfbbc86a26bc65f56c89b264c095581bb52a540cbbebda1267de6d2907bc736dd281bb78f0b0ea3fa47ddf498f65b4877ee7010f38cd30650afc449b2900ffaf282656f26246cab5ae87d2610cf6bbe48982ab9771d93bba6bd307e788a5c169c07332ccc92ed0ead9ca1c539a565ead6575c32c4095bf9a491d3aaa509c456f5c953e9fd7e35859c9cc20ce7b6ce3fab2149707631e8e3956fa8a29dc57d533930148f431b9a45ddea87341556fd0a9f221834c925fd93370b2324932da723cb1a3e4cee1f607a8c2e3febdad32667b6634c8e3b2af56935bb2b21ff2302018d332ab59acf657e16220f7ac7fceab9fbfdf91e06b0a7a9ce4847c8fe22f0fd0b3d7d8954b1ab8e131889a6f37d8aaaeb8d9083f554fc41056da7179119564cb73c10d881096cb5a6de633d059dceed95fbfd0ae66250aecf9f6ac06f64e4ce2d152555238ff8100cf6ba6be32d4841faff4922f07dec1e5dc61dd48312ef3184421c8d854458a64f11d3a02277f61e04d7294c356b661ec9cf857a541a2524ffa9ca331794f703acb2b58ad25fcaa28eb1702572ec3635427b993a1a4daabcdad88969efa951e7d9be532f18fe19b79e0e4905674a909323eaa2a1f6232b9f4d86c7d9057b1f04852c782ac3d9eb0b33cc6566f4997f4cfb784a060710bc186860d5a00134e2207997fba2851f23c01de03ff31ece77e09660a35718fe9ac189105898b510a65f422f09f84b9274662b81b4a3d1b8ef7699b2533e7f119f6a43596806279cb14c4756cca577af3c03a72e7ba86915c9fb84f140c2fa2b7dee8ff4f5eb47099f80645b3470fe9d95172b3c7116e9ca5f59e809134f04e3613d5b3ec5e39033a73932bdc879838b40e0436c40f040c5c06cc43ce62386893363fa91160ba6826233cfd332b8598889b9526ba63c575431ab4b020cc2a25339414ed674bfccdebdd5e245fb43810fb1f69c17a8b6c1bbf4b1ce116c915d8cd71c536414a0a1b8840c9239249e54a321d7642593b67b48da0c89728cdb49691b8dbfb1cdca4cfaad76477650a42ab81b0ea197109ae44e33a415c3809e84c9b51e9f1047a5fc0be03c15201185898f55a3072c34bc01c92270698a124924ac632413e07ba2e6fa0aaf15db1019c317c138e89c1bc2ea46c59eed16b22c6fd9a1215560f50f4621593544a057d50de7afaa7165d3d37e51986b2afb22046b4c6656a7f0c0ab93ac9cff877259327fc860997f95fc6d98d38a6fce270d0e1f886e"}, + {"0000000000000000000000000000000000000000000000000000000000000f1d", "01062ede308a524f99e010cca87a186c810ccdb6de3a45a7e84ba5223f544005d93265e8e711ff3c691a0f280dff2d4e28509021c258ecb5ea0cb37baea0cc11ff1278daa52fc57e796226f7fdba715f8a3c6fdb02c5c6d08f4ebaa317c9e8fe8fef9646cf63382934454d5dd36356c19b245e07fbf34d39ae523ab69c6505702dae820e3b2358b4b4346fbb36a202e61d54e936a05714fe8e147f2549d5254a7a912e0d127f254a06fb78421c6291854ab9a0882ed6c86075e4f1006547a5ef87066bcc81d457c6f78df49d8a99ce96f67e2206ec2ae7e581374118d41f11efbb4afc16bdbfeb3aff2e67cf1ef7edb7b0c589883d8beee27539b985071d2e7f6e24b5a9e20412e888d40a00c08c19a37e31289e1b1d5537eddcd6b35b4c9b295b67f43ee0c41395ccff466c02e7781f11c7d64942d542195f630a2c5e02ed6fa4f4d19223f592fbb73402033e1fe7700274e4de8cde7287cabc80a88633ddf059d1f72ebd14e54b19798e668f60f4e428c4b4ccf2649d142a800526c251f11622c93f02b422dcb39f1d7678b4218014b7e6624d552f23896412f992c08e7605fdd7f498059450da4414896d452111bc2b3b6fa08769bb1d9b075f1d3bfbc24a24cd67a5f6f9db41a5e1cbb597e60eca9795ec4a896192e03d1663f17b637589fc3f6c17b5ac925bde5077f9739433875937f22b6452a76303c6cfaa981212614b6862838ad27b9f1d239abb34255301a8a1639c455e0a62cbc9dbfd1948308cae8f08f53a7cf602c4e5698877618c697112f9181bbcd81e81d9b10559eb91d247c35331724b5f29659ec4b312f1951a41d0c6577c1f64a71c779b55bd743056f85d733cdc155b08fb51a2aaef4372cfd2fa8d9e3f6d27237f55c956fce5486d7511fbe9f05edcdf9920894d60d5087a150f5dce5f84f43a2be68a5af59be27f01460a5f234408f3533461f404be17a18d90cc816450bb234c3c27ac3da24667b521c1dd576cdcfc395005a3bbdce78c4b13c5dd60d7c1e0e52d1316ce849259fe4d8cbdd71ed512449726d94d2641fbb3be3c550b41bf00ffe43ca34756622e4d9389c50a9bd075ba15eac9e83d46f354c9e672e0656c10be01685480bd2d8815c3e822a8c58c26ca539ae13d52e9857d00a07e98b5eff170736bcd7c3a4649d611e70feedeb7090179633f1ec1a512cf64a0a78dc973dad26ffa0f7c115325e3b0d172dbecd416fd4868004a23e7f884ca05542751e92d8227d5a6f3d9766798357e0d57138b186f71023da9d48dd8b90456d2e16241ae482dc52907c9eabbf2b2a6c9a4b74217e3beb8819390f8eb0e0ff6b9802964161fc3df235a03cacabab48affb18e1f52ea2c2cd8455959b8527dc3d01150b446da4e6a3b675a5feb6e4c45db2d2561c1e13dc1a92734c59f014cf2d6df88c8ef01a158081b74559efea75ca36b0443d48f8677a111c56b428f95dfc0ef1c377c428c06005d919f8f1ae73e9333f00a5d78c0fd1bd21d551ba9f8edca1c65ecf4db42016a46a76aeae5589169067934f8e6ddcd5743ae511812a587eb787ddd4e990e4878c172d915e14d3e00ea2b6b0f84875325b59c0ce250d2228acbaf98aaf0f28d1e766d1db10d22d7524dd483ef9ecb56ffbdb5ac37d29a1a5f3c9bea7901790819ac081b75af635344de53bfa9ac2ad8b11f086e4dc55ce2acb7e77132a0b37b6368c6345fa4cb05eba750cc979445848bd1ce341e70099f72d547f2299129eb20214cd50c94448a90b5d781a08a1d95c3074903823cd2889b6d02918d8a7eaa4e38157ae5232a0945b4731676dd7071164f22d5785eee03be1f7e17a4fa7db5d7313ba95b76b31cf237d2f9285d53301fb509213c0bac2f689842be6e56467ddde63e6913"}, + {"0000000000000000000000000000000000000000000000000000000000000553", "01df4850a61bb8118ce085d5b460c325bd235ce61a03205a69df444078db903655dad5f426947a9eef4704f53ad89bd182c507fde233904fb87962a50c9c753bdfe4debc1a59db9b8f143b3fa25f9dc905509a6f04267f02aa480acb2707ec28bde70cc3178c19731a27cca7a1a3cc59837b33d86e9175268a76fdf9e6891697b1d6fbc8f857ce381286ae24f447871c1dfc2220c091757468a695518fc5894871de917b0e7333640688c585039afaaadebc26d9ba702239cedd18db3f07b14e94d0a85d4d8995236ecc1eee0ed8ed9b64b20cbaad4399317b9db5b485feda571715881eb865cf358923e0480feb7f38e34ceefeffcd2770f0fea9e9099a63104a8e4b3dfcf3d793aa4a4986412333f8f90c36a3e13984d4fe702b26efcdee68e26544dafe5720334e0afaa2602db3fca47aa3c5c67e70ce36308622434a827915ae5abdaef765c87f6bee220013c87d084b28435bd22e7d8a5094175bc66651beda7c4e743707630a86ff03c7fb0e33839548d89101b3d03fb12dad82002896c2e8e44ac7c01d7ef616afe15aada83bbae27c42a26d51d0f9172011e293d5f3ce3532d41e183a0f7d5a2a4fe4e4235313b73be6d2a637be1120417a2280e8031df8eae6f0304b3693d22abf727928f83d935ecfd926c197b86cb8ff092eb5d576ccb731f08fe4b9ac93cfc671b45d94f57ae143d21bb6bb0dcb82d38717d82ff98728ce6a52cb8ee5d45d7b994ac70a64819fd9c343f2b6e69376d48211d6d2e81b1a9a2e5f935b655f2d653596ecd33c55d1e699222f3c173cc08fdede79b2a875b63e6126aab50b1d91eb11b7173dce4ba5f7212ce968eff9fad74516de15f02f2abaf9d32324d5e86219a2bff571b67b8693f77f1ffb62e626d1f62f7b0a66ccb2d33f21f6b5b0b93c4320d725bf72faaf98c44447b74041858cc599b09f03f7a798f447663d185954a27e5c5499f8589d5b4b16394427718d01091564b50aee559f2a1cb2def32a0d005b9a6903953530367cdc1aea11ef4b055b7f6b0f52f0db0e1e8ba56f8303258f221da2e91efca73e15368ac0e3c640bf28e2127374b3dd915a00ccd1431634b24ccf09be8a905874c1b94c9532f04cd7e9e12b91d1f0f20dcab5b23bd7694bc6b7f1ff363a4c6f4384543b2ea776c3bda2553816d520223de9da76040c8dee8d87e75d4bcbae929545ef08ccc16ef060050cae0b4f85affa6fc3e4a1e5bcb776949f979f3e0f1caaf6d35d91b139b1025991fc66dd32bfe69d60cc4ed8bb7ae815b64cbfc5557643499691ca489c7d28132a4a3470095ee1d026b19571eef439104febd0612005762a0eed1f19e34af2c07627c391f8a53ff8f51726a35be3073353935239beb6665b32952d55097a369244edeeaf266f9b5535da626f315e3d9b92547104ae62c7f18fc2d50606e15cbc724ae63724df884606a525e47e994bd4f0cf322cbbb28d3df17ef2455e0ec70fca599c040af378c44e8453be2203e39877c3165e330575071f299a2d527c762b1a1de5745f97cd08bd0320891f6995b516d1f6237a9d1e59a017c78f1dde51d8e08f3edccee925f2693a86aee7ce7d280d157d32965c226bf7efe8b2c75a4413366e5ab6be012bd17f9a52d3fd936671a5774eb6011170443d3a4e050e76457b464e1d94a0153d606fa75a2d51bb582023b905fca71183ed58165769d66101de24f13d5028191788e9711129a9a0b04bc991f9ba1f25249e252126d4c16df69313eed9c303a9ab7b62222ff6f71e940b4121fcbf61bd5d907ed49afd444095cdd65f6a1912ce39125404cab37c3774814532b986fc319dce710ead0d78df2706e572c6436617fb1e2d9051b676bf11b057e725148b47194b9798555faba733c7bfab71"}, + {"000000000000000000000000000000000000000000000000000000000000249a", "0033d4cfdad02b8deebc69050a4ffe064312de17e5058daf47655dc89b76ab74c028ab9ddd51299627270161875e140129f01f5cb32966f08521686f6fe56f4012135bee9358b12c1b26f0d2e5194ad52f5e488f0207724bb68a5bdc745983b7d7f55c4a0f9fdfd245104a1a315e5f23bb8bf595e0386b76f24db5fbd8f907f107b518c50debdb02f1add2b53f09346b96999509cfb0db8663d18d9b18d1717529ba20df65cd4c5d015a1c18d89d81391c515506c7440219fda458bb4108c580b11f2636a79f5163f87e512cb6eb8f17e47104048c72bf227bcf66f831523873d752042bd4178e19e6abd7bdcee2e9bd3a524640a9ed589221792764038d7be55d86eeaf7412038a51e05120fab79d97341522b72a4eafb83197129a089c5aaa12ba9ddb2def28cca24803bbc3edf45f46548bd03a2dc343ce83ec2cb8bf2008910095c26be6cfaffe3beadc3d5b542d00c4c8f77884a03d3acdc185ae207ced056f3689e903edbe62d20461c518da420cfbd1d07d72c8b907a00506f2ca668e2b6510b4514f1552ef809bcccdb3c23af494ce5a1bfc5596456421f87549aa785c3843db09dd443fdd94c1a566b32235fc684fca8fadf5d94e12f0c15fc09415aae29953ef3b722405bb3d5f96a541c8829623a5eed72f8ef4d0edb21acdbee6519c7145e1c41e455a0dceef693a1c1ee36ee6ec365e6c69059ecd8f9852aa7b757a50b55128ee60b4de7758093338844cad0d41bd36285468a4e0d233005a5c4b980889cb92dc9ff87b72796223da148c88a1f8edd89634f87fcad726f0e7ec6e16927efd9f8b53bd5d3f0a09cff7358307045862d231dc6e8f183668a0139dee1b10d77706a4522fc514f41c0d36b4cdb0316da922189a8192faf856abfb47b22d5c2f015689ba9d34416439cc0c339da37bd9f96d04f7f06993af471f3e0f01e0e8c9770b0658940f028eb7c48d7108b47edced177f6b8692ec422b6e1e0581432e7439f1f7394b26138a5c0e145fbe55f233d343de358e51ec6516de68250721db4acd1108da4a5464fd37f6bd57876bcb6d09003e5f10182b0f63fea20949a95756fd3ff83c6b2105570709c98b8a501e283fe8daa61eb6ff39f727106686fc5a05445e9b1a92976a216744fc8911d57f3cd655764fcf3b7a919c2a04cc7e0b7f72f27cb9e30292766f752039234f3132755f4543aa67c0d7bce429120a0b82def9cd7f71d4316a36877e7e53b4697c0375587238d8976926d7834c0d7ad81dfe5890626e09f0827ef4888eb45c86320e6b5a0c7e708e7e6288101ddb18f51ae51f4d25447806ee981ab1555a55c25d5fbee802adf249bc6f1723414a709a60c517ff411729b2034208ec3877be651534c19de163cc6e1a662326c536cd8a06dee8a984b1b76e3e8643d1fd8cda05f4b0d681eae78b977e55d77fedc2d18b52f5ec06165967e5204d9ab50f29c6a86a5bfe5ef5ae1c5ee30fc1e4dc174b604b59b5a22eee502fa1dd9c3e012763eb3f7fa5f1bde5e35ef8ef2ec80132bb659bf70e12ccc611ab1ac4aeea8485d20e7a09bb52aa3ea7e22e5a097c7e6f366fff5393c8ef2298d5965af45efb35f1d2be61626175a4a8c3f84c6f50b6044adbe3533e31c79baed3e515743844996fad41493f0dfefd94081bb55805e433e7e27be5a03fe8934df457fcf7b71c434f052a4890f395fe12dc10f857bba8cb1e3c5e1d52aec63ad06541f9f1b200b1f862a0b7a6fd144f374ea6b92a1d3d99bd7f06ed5bbd44b7afc69f614709c15b2a57615cbd35bad1ff96a0a8c96db812f28317b64cc4f198e19f8140c2ccc36150c0d2ee18392a29b0b37ea4cb0b26d60bc38b18ce32a8e6cb9e5db635c6ad903b4e4e5328e7c36c174672d14392ff00c2"}, + {"00000000000000000000000000000000000000000000000000000000000007de", "0006952d60d34eede8cf8204bb4d33364d3bda07650e399f130333af2fcf116389c01e1f0a8ded759e2b16a38fac874a04667ede58ba457b19dee41cdffbf4200f33d76b08c43d55dd972e5639f8ca61f35470ef0b6bdcd62e02f63bec3591b92afd00e9721ed3ff2a636aeb697a34762df48cf6c73254a032d4b51d83f126faae7f96e56ee1a00c976eaec5a69ee43c5df38d3774863bd9d6aa79d89373cc2020c9222c4b9218e70299307cc86ba995d2f8923da09ef2309bde2fcb1219ee64534c8ffe594a3432dd857cd890ea6adbdc50168603571f1a0e075be01306349c9bf19ea53ea0872450476bdad53c6be816f5d200e37d06082a715c840954656984a49567c34d4293a0156ec0c9b2f6dc5f1c6d87ba359ffba56f86b33a15a82e29459df4499b2d9719a163940cd7433535d85cbeecd5af6797a46836b322f511673dc19718a6f87bf96fb668c9346dc7016ad61ea54f237b627a0045e48d41a32390bc3ef10d9a2e29a1cddd0cc15e33695c509fbce0fc9116cc23052a373f0b6de384e4570d6b7b5812d188f82cec4394f27a84dbc09d5401575eaa7ad1aaa210becc24059107ef05d84ef3e074826749454ee2654e1ce73d1f96a7dde9b65b8bda1076b0805e74df55b1fe8a6a063e5a3ef99f9ea93e1e85b32cb5bd9aaa4357178546cdcb87fdaab0539820b7deaae845227009dba6e606160ce58fd45b755895d0dfa3f564a9f893bc15064d2c0d53fd9e0b4d9d5cc6ee3f7345e35185ff69d207b404ea2c61f2ed2c94e533c15b3aa1ddb3bcb4840d22e0fd1d26d91f3d2813b6cbc4d261dab6fcd59923a24d93b2768917cd4a34b601e40dbd47423581a8608aefeedc5877a961df86cebc705fa272c63672a92e210aa5fa639151e20a452b685792724b5f349e643d8e7447b35720550479c42a3fe1d1ba174a7c8277012efcacbb95e79ef606559786530bae7fde5ca9cc058d02de074851465c18719b2e4f6224e24d492a1f13db533cf58c7768e3d801422e9250de968e9fa09733930c53026ffe35a987e94a2edbcba6a5241bead20c48db6edbcc93bb7579b61ddbb14a0a6ef8fdbc8f19f068e6d4e0a93f76bbe76643660355e1e1d97d0d128baad86f32685d9f339271b06f4fb8ac8c9637c9148cfd168f60ee89754bb4568b4b80121878db39e8091baa5e62913147eb161327c765cefdb269bbf7b30a6871826c8dc686db94f377c9f5ae355aa777508115a894cad507ce7edb9672ca0f33196142eb6ee87967551667265db8a55a2ee7a1f170b2520831976ff71450852254c72e99ef92d14a78386e119e7b5d891c25132acd8ccc21d31a55b3d248a938a209af9eafa31c8a5d7bd397d3d5b7bc32744f5c1b58d270dc524d257216c34e19b36996681b81b65e2fdfb75a5f581602470dc97b82599574ee40e8116e9959fc1036cb281f2491bff754b8f17cf2d37a0fd0ffe3ee3cdff18902eb047fe91183e9459b83d181cb8479b9f29caecc2f860f2d60e67165e37c2623f4eedbcace8e16752a0c7fd8f5b70a78e466bb65fedd67325e2305be96f434ba8b969f508d40c073b82b64e03ca219e39903c211c834f3fd123c15f9cd5667f3dfdb8a9fd65e131c2875b1e8aadee5dd580bc2b584b5ba35c3461004bf0365f06b626e9e17b0fa022781eb4676c673fc582d1a034f65999589b591f2386993cc3d2e2888d1bff1108576fd6271a59fe54c220eeb77389d116379b8e2157878ef5a5e618f697fc6353d41e96aac4d1e45ad12264f4d10a67ad3c06bf23840761dd498228764261941679f28493d619bd671b6ffe20a0d85c3db39ab40b57a7df6a7ff71ea96d5b4f4d826730c4c3ce2084a5b1ed07ed2b4495d01466706fcb2a6406472523b"}, + {"000000000000000000000000000000000000000000000000000000000000095c", "01369a38b74c4ce5fbfee0c4ec36b800a484f9d1a20f00c52f568aea7a7d0622a58b4c30ea70257de7fc0f924d8cde1a770578bfe54839c2d56e8efddf1fb42023d9fcbf94a743b478133a4459c29248963294610aee346c13a4c0e9e96ce0fd524aedd8ec233c131f1a5a89b4288ef4ef92a986c76164c809bca21c3ffb12e55290210f037d2b58e4b08f5a752ec5c0df0cbd1e3e6984920d4e71175271ed8fb3e76d079b8b8bd5024bcdc6f9d2e33f6f27073ddb4dce8fb1757eeb1644827441e7dd6941b1a7fc10c1ecdce742c77f5ea30c26ccd227469b0f2a7a5567ddbde51f2342fbf12686a6f7b1cde21f433a27fa8f4c7ada9ac2d6393e880a0f079eae83af9732c9c5000f7adf05725313ad4523ca72650967a2b5cf36b31614cda5ca0f487e3fdb0b422fbd3fcad185d683d220d9e2f22f6d331d320e10babc0ba6e389dd34bd546378cf0f59f9759702e6018876855d2c4d79f3f8615064b5dc753ce2d3e91712bd7426d18adc01777676b64bd287ff20f91ba0f90ce3bb5d84d4cc0add0531f250f78214a0f8f29a1018bb1c74c3485f27c5a244bc7130b925a883744f530e65e963bcc9b44aa9ea8249456cf1b6c9dbb8c62d13db12b4a60566177299235483f52dd1da1bb69b0814754639000fa14116fda6801abce09da67cb875ae1bcff504aa1efb65c12b15f646619cc655c99649d503f68426361abd1d645f73b278b11642062d19fcdd1e2a8e6a103b218fe88dc23e7e70e751a88cde78ee27ddce4588583ccb1f66828bc29ace3d8f98d6f5e83a17f57b5ae81e45fc2937f7fff414cbb1aa7dcbfa06389e4cef98d4aee59a32e1e8fd2299d37cbc6a52089e5684b8cf1d118c6d65cf513fa1bbc2153eaa0b0d3842297e12d027968724884d448ecde73b7f74e65ef8efe0ebdd410b2542b692e5ca07bef4cd1f6a170292cd704c145c4123e240bf14f1751b817d3d299c13a19c4ff00d0c99ad4102283afc0468d3e88983c912c746b86650ecedba45aa1ea5e50ac2a18a9f397336e1361dfeec95c5a72d65ed7afbb2aa3b86b5f79b058a8fb20e4919085cf4e3d5ceb10f328c507600c452060b350960a3c33fefe6d627e36de2af7bb77dac24b20955a45413fbe5b654f96b79241ee4683ba5c03a268c429ee3d373fa8453f974b270790dda35bf070301d7db36c24e45e1f5d1198b532e130676f8b5b70c125df2336e207dc97c63ad0c3a76fe63c27828ec0b03ac952eb1e5d390e734fe6ecdf9fa99ce1e06630db1694af1237c472e97c3e3575aef84fa2598857b0afe7a997aad4adba8fc04460f239c5253a398d5951811cbde2254e3f6d98f371469d2f9833a5e1f4a110b6e3d16a0073cbfd86ff1d160ca9ed170e2dd71c629b51460f35e0509c405985715d9eaf71b4719d0ed03e4b5e0334881ea929097836ed1ccd66dc1dc1d264367a281391dd5699ecd47fe1dcaae2248713813db145cbe7e0dd26da3da3c52554fa3033901d6af089a29f03ef5f469271d4f4c562a75748bc9f04fdf04390e3edf8f7862982bcfd31b0b02590786c816b7928a377737511ca16ef361f1fa0c14628c675082dd67ab1ef2011f4f6abbf399df640c237fdf92a097fef2a825e93f7aca5491d6fe7be3547f1e3a6a63c21c1058041422894fb49089b5a634c5eef8075229cb71e9220a4b9c4adc8fc559e1142c43a77ddfd3c6e99ee7d637b762e9a2d7ca09cee578d5b8e74bfe42c53f3ed13c2f9ac1e51c9ab516edc4c236bb8f2adbbafc12a709df1295e98c72bf09fa12452a215f3d31ebf7608a2944cf585f536037f735d805c3c2979676b55f975e135a7c163d8b9c73b79dc23703ef178d87a4b1915815c50599327ce019fd6eb732f7bcbea632725574e3"}, + {"000000000000000000000000000000000000000000000000000000000000029c", "007c7cd7d3abd28fdc79b08d46b42a88b91c3ba9bd01243a458c0e28ef96b4ce0a47fe597fdf155f50910d02d469ab1179d5afb732627ed317f69616fd23710efb551a0386f627f5a8117e3ec617909dc59019bd068e37a4a99a1a692feac7b60abe1c42127f5cf3616d9a6ba2b0df6b0dfabae8ee58efa8cec682feca8415b87dc98f9df0c7a89fe54e30b617097726cf1ead1c62c35112cceb597fb317942e41db46f038dbfcf10fe7d7fe394b0f71cea7173d8f7d025a08ed37566b22270439aaf634f5e974a280cff8bfeecca8bdb2c013d08325e8469b5e4dcde36eb6eae36673dc93c13b1c5b0a4e061b9781b98e8689e739ba2dddd7b17f1e11b8c14c9923f01b342e735ad5b09349c31a7d261b3e9c656fec35dcdbf79e0423315d457e3c8eb9630f17840198244992b3de8d975e9e5f386ef44a99b0ac204f354b60aa30b56c53f2840595ac0ede571735c900f5ebce1303b686b4bf10cb1f7c70bc60b67654f507244c0b544bb263e38fc1ecf23ad3fe8763fcc72519e6f922019145a154c051ef90b0dbb0a106bc3f676590a3c9c1e0182f5a7806ae65bc91be36043391b4056a6a689ae01e91cccd5545b7c6393deb3fff0a0706502a0a7282c57b213e20cdc408765d755aba9ca60d678a01ae26c3c99e62f2ea2ab2e892406379c74b1e38b37316e0fefb85c4c3ce71ab6222761adbf2c20132cd561519200d56beb54292d92407b3b81e0a9c0a49e33cbd6701338497032fd12b878a3810971a45047f2b6ef7d47646c4f0a9d216564caf69ef1dc91c3b7cf778006b8d9fb0b4b79480d21b66d23a5c491a153336008adaaa79d7b7121362c1e4150032bb38ce15eb4274538e4eb4a716535fe0f862cd38219611e417d41a7db40c62aa95552236cc3695510fc248e6821d6a5cf056f3a149b1ed33e43152546d5ebb3810f2008bdd28d49dda4b05de709120ad0b0c37b50b4b764a033fdb745a2b496c017d60e5eeb3736cebbf3d710620e48f51aaad7fbda4509610949c38f6c29a494a2737a7a6af31d0e1bb78aa0213ed1c0ab2d7f762a50a3a34a83196de351ac5f6059d717ecb3eab3f94971c433b6f8ad6a52b5eb8588710d831a3a2bebd355b186435235b9b00897356a211984582ae590a93556e3af88283b59fedd5a2e005e35de087d2e68ebb8f2a038050cc61a11cefe1a194b49d25b52f33bd5acb8525940d1f905b435951336b672c71afb319e4bfd38a0d03ab4a261387fbd54bf431c2b4061d1893b460bd16fe9661ea0fe0d8b0e56285ae413370ac3dd0578c0aa35c845e095f94f97c24390f389b358fbefb01102d5e89a8811e999b0a77d7edb976d3ee8f3a5d0bca265ecba10d903ba38746d466beb0d3228e8d94e9fd2c30b6964f780f53f2837612885aa5a9fbe09b674d01bc610d9c0424ccf0df1617caf23c69bf9c3350a802fbe3d21fc1d5a93178d3b9fc2f7fedac795003d522a8a4a99cd7c81f229f849d6769b8de77cfd988476188ce72f62c1057a952d68d724874ca550b3b9bb10e790da6d3065445e98252dbcc5ab32cf5702e09681354c0b76068c9db8b18131127b58530d13156a4af4d7d2f7c4029aa69f6514767687d5e9e430d5d7a624e833781bb9819752277f529314f26499f38918baf054b34810637ad8dfe7831c0673d70458aa85e759b2d4f855cbd5a5041d3dbe56a88e085559b95bbc49e0656d8a56e9a2211e2d7227875759b8ea93abab5161144221edfd425dd5361d33044479fce4bbcd5f4130617e8ac53c9d9af4f02c27be9e8643207b2508844445b9aea41942111ddad85330c6940b598bbfa1061084ea74e60c27e74aa3451c626be7f87072d1b7be809882c5b684a50ceba58e1c2a03321bf26697f833f"}, + {"0000000000000000000000000000000000000000000000000000000000001357", "000617afffd9dce5be88e024370bab7ece4e5dbb9628ed3a3297d060afbf57737e3d61d52e3f321401a402991d8b79839e882d70403994a933b5960352d8df078ec9d2e111b776ecc374c68bd32871f9b1b0f10000c883e027c2dd28bea3945d894099c559fc37524634349d1c21a8114ba800643f19b50cbf6da0bd8b3218bd845b21fa442dec5dc32cf124d45203ab7d6b751a478536505582e976824450e025d4794684386d810a256ee7828553b93d38a55701cca4ae79f395c18327251ab984169001b70d333600741bb2997abfefbb3c37849daf9fc32bbab769c7a8d672828d75d7289c45a5867537195c6f230f968d4cb4857287e4761a900a346e0ca0a27927c60fa383de67af08efed4eee302025c543df9f98c1da90562addddc4d24d063736bc2f2f86ea30746b1bb808a3c469f229b569f811f1b5401b8de74b704bafbce494711758a68d4d4a9a629d02670a19e03a6c8df96760c6ed2ba94c7a193cd971217f75ccfb4a59468aefc4cd4be071913d214ca72c035ee4b8ba92f4d2b51762b9986364c60f379d03850aa7769e68c43f04fb54628c653f922654ed7cf1f50593c5d7f8022cf779ba317f6afff3155792536de929572d25ea5b7a29b462d414a1a88e7599704faa4915c107434d8813df0203c6f8c45420064a3a7e3e59227c5ee0750a5db155ee528afd9fd46cfa8378d20803791d9e3f8c8c727cbfd03d4703e044126b761d7e156f5a0fd1d4ff83c2db6256774084ab204db9dbb2417e86efda117b2978067440d24a07b1a94f51f35857255499002219f36de248d894e641cb31fc5ecf820a3dbc76845ed8d9c8bda15bcd588b2a235d985e568444cefe662cf93bf99f98c58c5646b6cdd07f27d723b419a1e95327b9695453b06a323b1105e9b5cba949288de4d361c19b40e856d2eabcee75f012bebd99004eb40314575b536ab2e2d6a55f86a4ee267ac88738d88d86fcd7464cf367e4741cb55a42e7775f9b5803f110924ea3e72f222db7cfe8d0719646035739df2fa442a3fad86d41e7c5699c7ff1c352c6ea5caf5504ecf67462e2dd5752a46a2ab4586daeda799d920c0e90747622d005474d4156f2a1456aa6181f1c3bef0677ae3cc31a43c7bbaa30b86d2f853938cd1626b51b994ec5c322fc7dab4774d9bcc29555f1fed4d50a0a613eaa8384bc10b88cc59fef6683b708a4be863a4ee7c5d9d6ac251bb8c4f590f9b32979f35c989e382a6fada31fe97bc38e2be67347daacbeee67ff62b13e6c5e44a6527293f1b5f54c34b42932d924d7a9620dfaffca500eccfb2c7dc0f4b31c7d1cddc012d48c2f23fdd90ed656ef607f14d815385bed65214e79b20f87c26abeddf0abcc0513d3de2bcdf2a6ee7c653f125bdd6f0b5d61b1ebf7e272afdf55c65d599394db01ef25b6adb939f5ee6f547e6825b1251fc390f95b1d3c237d1716f488b83936416c6687a632ecf970832a5f4362e71ec1234e06d5055873bd9a6cefbd171c7325e51ade2d4891f0370a19f256b7baaabefb6fb605903b783acd4361073d92c325340395bf2b54ebf13854a33f3d52de2b1592d72babfc359a55d613c6bf0e54f79d40d9114eda6164bbf4f114553cdc322bb410b0a307fc1306559c33656689cdae4fa13efe988402bba6cd6b83b15a697501fa82367baf10f2d936dd34dec6766b52cc6504131862c1ee7a46c25759f72a055dbaa66ba363fbe848c365eabcb151eb41173316678a2d8a516a08ad702559165764637e7783d51bbe19d04ad9e31caf3349e785753d751a755db299633b4372c7f2e891213cfb52f7a3ecd9ea4a45f6d5a2531c35d4aff1547169310851f81931bd1ac106774bc226c411756bb0cbf5916cc2f24be14cdd74a88baefd"}, + {"0000000000000000000000000000000000000000000000000000000000000ed4", "00b210d686183ba3e140f22b31aeef34b74b5b7aa630351e5c844c7e776de14458867cce9b1cfcdefd0c047ca29390f14d19c6c6e12d358d195486c3455fca0825b1631ddada4d6e8e33ad1b4aa02187e9d8e6eb018e63f18e1300cab8ae512ac85fea652e4e6a2e60545b83aa6a19cb37295de7071b66b44df64c73d3d7030be0fb628856756569168620eb1a35d82036456b188deeaf8ab419a9e8c102a37075cf39ac9c57c01c043c352e263377adba73a3d73d2ccf79e3a7dfb8b917dc3d10af15f915dfd5b233f62e760a7cf1582f4117654f5a2b9439ebd092051136ef9b05b92270e6901923297181c8d209d1cb72ce216ce80d290a8ecbfa0add0bd4f79e91891c4ba1d391b504d0d385711fa915eaad436ea9e8cd54ba13e8804e757b1d81bcaa4925576dffcd6477f1cb8f137a0278c901bd2f0e1b4b5a3322e3ba1fe21b1e1b16da51ea07eafc0ab8962303dd63595f44c8b3b3d4310ab30b6b4554827e3bb0401e64aebc151ed5d591852df5d1d6619a8152c3730cb6ef26dea1e60158f201689ad4de4dc0004eabf911c8fc8874132375c2eca1e99a6c022212c7de88b70d4cb080da666abfaa5f5481decf9059a9d475d47313c25e965316aaa3684771c5e653b4dd67204e40081765a399200fb0f8f03e24ad3e7ea1796f3f1b1cdb1fe93eee08e0f489dd47c41cecd6e49dc978d21b530f0293f08d53957767a637af8b3e4346627af737e1168b8451b05960f53690a322d9fa46a9ef9a5bf475219c326ce15fb8a18f0c92ae792bd96d4e0632f2433c4df66e1df30c45c6cd044566d1ade598e7f98fb9105d69a8b2c9d5b9470ec4922dde7ec27c55bb40174395ab24bb5810c9a8dc345378b0ddd925a5cc9eb816adcbf7f311adc7fa8078b90446275e6afb1ab598335efc08a5956f37083416df393a45ede948d978c100f5e1922e02a9686dd9018b04a4b55213fd1b824d1a5bcc7cda1d79c19ca6031b4faa60d9739f18b1cf0a1a0a76995a2513611709fa9fd1f6571d34be1ef84d4b04d07ce2a7ab638fb651a03c2005c9e9f54fa6110718c4e158f300de0f53f4cc792bcd227bef0d79237d3a38f91eea7387564487b6b5e2e1d4201a2a801651ca2c4da34bdff3db1334e5546209708b54e23f358404739f6d1517784569fc3f53b8bab698b86d610539143c43c6522473fc730bc560435572bcf48f8f37c4b6250fa95d5d9af9f79a53f097c6d073bad86714b31d242f9cafd79afcb3e3f5594775ee7eb9ba80153ad5ec43cd7bd1f474627aeaca44e50978d21e640659313d741048cceedfc0ca0d24e6ccdd05ae248344017406efea9ca9ba350445c36b03a677fb3a38700a0ea30f65748efbfc99fa5300d48bff673adf6c771fac02d796e8ce23d8c9987c56de2502306f351d820888761c275e13196a78937a4eac3ef17ed46db0d0244875ce54cbf5474f11124cd71b84fda8bef3457e20929c883d9ae7acfda464c8604a3726e46398f67626a68feb47ca79dcb6e243e340210bd1994f0dd04f176f997d930af38f9f68e2d042e980c5da0d9969082f1399d01d6a1799c4fe235a013eea8ce1caabca7819d81bd0e564c0dd5481d43b1b694aa524da9fb9cd22b766b9d8252c939c871919fcdc71d2e258fa6c690db15e3a011349bb0ec2f6d180c657cefed5fd37cf1b1acc7200238daf5d07d24f87a3d449602878db420f730b45a3d06be7f68ae13442e5642b185f5e3b7c60ffec96bb5a3cdb231ae714e1e0e68293b0fcb56615b81119a7da075d0fa2e4d28e66ae8d4da24f426b184b969a3423307fbce042666cd0f6555949307d9819011edfcccb71ac83d43402a8af8c7e02ea763bd01a63cf95d89c3ce1e218e4a038df776e9b535abd64"}, + {"0000000000000000000000000000000000000000000000000000000000003718", "00e2267ee3831153d2829094ad437a4cb96bb4dec017efefee40d496f5f67db7627178efaef6cebbf46d012c816701d892313e8da63e60f71ac9e784f217991416ce0117b367d7e60403d3403739b93e706a75510647d8590f4b0c4180e431f205efb901c96dbf44b32a50b6053955e679cc937347c99c9f72263ed75bbd092b372579def19b20926262845808158db32ef5021c95dc371e4e2ad89ad24b26d6f88012d4517c4fcc0253da36318d10a1c005816ffd9ed1693ae4d8285e25c9ac4ba174c971bfadc39aa956e48aaf27f5d39415072b92189d698b677c25e071f5b0b5995b78bc3426780cd31672debfbfeb32718a14296dd399ff68ea0d34be35fadefad3a98679326df84cf2a351fa613213f18688f51e5a2187311188bbf7197cd37353552a0f6e462aaf66cd3d4873b4738874c38b73053c3f61112af99bffde1ccd6ed3920176910cb38a995f596804acee4d6dced2d5fdd9c0ac60cd80daf0a7ff79c00e2a5311d3d195a1f337aa45b8d6eef2fe7f7d5c41104e2115da206be37082d6049038111dfbbc59ac7e13cc2c62dc9b2380fae1a1837bae437343119f44f604f22fab90d240d98cea8281a1a8f7236b519d4c194da4fe803fbd722fede8c66b65387a3ddabed3cc6713bcd44142896445597f58b908e38bf72183fce16819e92754ca0e675ef28ee62c174b25eaf26a79eb0008cb78f2704319971e5be14d52f8e88c6468f7842e36f74793539ec8d16113f720c85dfce6692db7e16a2248bdb74b5229d5479f15c3ffe321622462db17a6274935f2938ddf3f6d03352b1c605a9724e6fb32420a52d206e6f96a19f2fd411eeca0e3b09bc671646a236103f6301301975685226e92bb3118a2a8b981c8115c0f16d4d4626d3aedd3ad782898e11d645ce4652dcdde51f6a17463cd9f552f222ce3ee38c2b6a96e011269f0f71c851fb00050f5551bad6e37b39fafa1272dabf2eb25dc518fd349e32c5f84a7adaefd738c1399441106cf0a8ed01f364fe9d67f1a4aa5df7ea131d4b681a5e6346b711af7125be4d1120ae490ad4b05beeda0692193d7ac68a467b6e4397538293cbfe41d5fafc1178c5ac56dbc25c82c7638461eee9ca794105c9949518bfb98e09051f38cebffb71b26d8f5d220808c08024dae92a2d64423f6f3c9fa5dc83b863c101c88a1ca2c77997ad6e174613f85437710bca74e3bc9fc29e3f89ab1f30dc5a18e482bc5c6d8b3b8901d41cdf5355eec6138c912368648274cd6170a78a57083449734690d93923b37a5bb6a8079f01e77a28314ed1740ee6ac3fdf18bf3835e29e7f97d1a354cf2196b8fe12c22d02bfa31d2d9413dbb1ce9c3b08eb517e11a3552cdca9fff7691a2d29a75c07ce6f2717e1cd8db1627efebcdac256b281a63f02f8bfebfa0530157bfe4e2738887c90280410baa959469ca2f2f9210467a80ecd0f92b181552099f58b7dd5ebebe97760178003643c50aaf0cd21680595c64eaa9a5b75f500f97afc01528194dcf3ef397dcc6928e8d84d4ac641447090a34980f95f3cbd6c58ecee4beb4e41fb2722222f5497d5011e5b5ef443b4c5a4ebd59539bc9d429a6c2b09f24da31d21728e0b17e9c0707ed185f8e2f1196aec867744fe2cde85cad59915e99f0f62f800248d5f8bed239f3b1eb754d014993ae9f6bdbf4c60a516233fdcd1001b5d3521edaf50082add2fffb3f04722c135e9d1fc9a22a760afb7d992e44f07b30172d4729dcc293a3d9279b2411e7a84efb0b70dbae430c410b61fb50bbc5ca1b771079ce1159f8b7fb2d3c1648dffa7d1949a12ee236e4bc7b8a774ee7be26ce15f6164c692a93ebe3ca81c0a04c6b817c40ada83b328e62dedbdd08636a53a974aa6d2f6b119b7c2cd3"}, + {"0000000000000000000000000000000000000000000000000000000000003d9d", "0013f9595ddb1757dbc7715fc9af27689f17061cf81107350bc6d54d1ee82497599851cbeb009e7b5ca2058467ff82d0cffaf605008c60796de20184b26fda0fcc01d3e1cb0ad38e8f8453b8361b6dac55dd23dc1b381fd5fd17bc9da1bbc24c03f23345bbea961c8a231bcb3d979eae5360494515a4d87a2752e8feef931cd01a3f4a9eb3eb5c52b3e65128fac11576d7971727aacada34db7f3f4f0e53909ca320caeb495c4513049a7fe9a5901a5994774296c34ac1556eb094201318b22f6ccc9ca405009e655737c73e016d80b513020dda2f90c8dc5e3b717e42e318eff05127f1526c4a53c7feb951f2562be1698aab8ed7f1cb320ddc2740098a3f17f20e3c71cbb4b5f0613580ca1a89f9c08b639c4d6425f5446baadb99ed2758e4668374dd140d12dcf1da791d95632eece3a048f4ef34fa8be85a0639d8f72dd8a46ba1f88684a071621a813e701f05e200fdb9b363515a12b6ca6693a25b103a423b5b20a102f1cfa62c4f4d5f9135c24a2b365981900458908503626bc229578ea6ec91f42fb4f2718def18de879203669c2f61de1e9976cb53501d3b0799cca216bfaa01cadbf00480dafe819cb65da139ff2dc5a11df73524e10b62274b416b19e1348da64afb99d38df90e831b9c251db7d0ebc8fce81384af3e6b3d360d5913b42d0f560c49ee47c5d83ac2e0917ed6b5c4e7155259027ed3b2d0e8115f778f52cd5475b1c52ee437ed4b208b6b3153a052f7240682db933d99f5032cd8991b23c5869e6171609faa8de38dadeaebf213017f9d34534e8d63552fc03dfeba7739e6ecb28e48dcd496e0099c45ca3d690be7ffcc920f0a402edd7b2498de461acb83af2f20b5a72bf2c2e3732cdea0bd61d704f80a213ffc1183b5df9ff7e47bb0aba08fa6289d61550ac7834b4c4ebdef82a481886514b328c7949788f4014e1fee5d0129eac988d03549c2f3b4df006e7a7e0a01192161148055668cf52f83bc25818fbd4e70fb1afcfaf6fec9c596522c52116c7f4ca2041051add82b0b8c6ef769dc93bd8165550a5bcd59869e333e3103eb46c2a7838b6cc537d8f631d3ca06ffb2583cbb06f0eef51ca711e15dc2f54ca0550b05c41c3ea10c1223c89bd65591b4decd11ee2e3fb11d1e4c9ee2641fdb1acdca932e7746e0c27d162facb5406118b1d801dcb0514454fe7139b021a50e22801133005dc4760e4a8ed20db4e5f1ba5e342bafb4ca35208a7466081162c9a4012c692db60ae17185d9f9bd19e30e16493ed695595de4c16bdae7c426e3ddb90b2a55fdacb5059f806d891acc3d4e76d08e1ceff9e4f6fe52cdc70a452e5cea92198d672a30ae41edb6a945feeb6c76175fd9371fe11985920db41059c5759650f777522718f447546491cf613b3db54795f97d13ab06ff5af201fd965696dc9a4985f0e1421b3d97dd47acb0bfe30dbd76fc6c4466087add510cfafec11a242674d7f611c03717890a8852b154014de75d582d9dbc93def33c95b24b86508c14c87ca40ccf57d0ddf28ad8d41205976d3e9272b04ff6f043db35b8d2de98f79d500f1bbbeb144f33497d9ed292ef2127b69ce793bf863132cae57bb4ce739b4588d4a00c717031933bb3889f3ec4e2de3ede4649d4b6c56f8a5d96f76df4fcfbae09607dbec68b2781fba6d390165d8c59508132d90e1f3282c24b0afbbecd3472752efc1cb9e3d73a8e691aad5402655852858714c87fd85a4d6ee20edc490c2e47ac4c9fe559c7ef8aa5fcf8eadfa2a70e7f24551fff61cb1e9c8459870bc497ec7b3a55fc12f57e9c234a74a5d212e54924ffe46fd14c093d5f44da59bf23a3c17358d41d1f00a4d833ea432ec670b1d9df3b5f1dbbe2d41985cf4eaf28d91ee5713edc82b83495"}, + {"00000000000000000000000000000000000000000000000000000000000000a4", "00a0f3484914f2c3215661ee32b01b622e9e9273cb08e8d315319131b0b7bdc270cf2c98a15085b2f36010634ac03b4d4f45f46ac22bc93187019160d0702f25af860e77ce33a492459923eadc06cadf6fdd9242090abf00a25a560958b7b3dba24519691abd1aebd71d56842ec307c307ad5b43727a7e97714d171efd110a6ca95806325c9992f1726032379506d9541f261211ea26b26fc6aa259332428d821ae5db69cc5bf29c05c49f5004e753d76ea191de2e0f3e2dbc70511b2a2a719c02ffdc7ffd6ecd471073c63de60e4a1a8fa22831a77127536eb6b8012423736da7f5406577fd0440723ec3e23d8983f949c81485d59846b211385bf710cf93eefe968a772b8171e1a71cff757c6afb6b8217befce6d4ca207ecdc207c938fa95eeee0b9eac092153f74f611b0f4f9715fa0b2f597dd718affdb776245083c840d83c7359cd932b35b0bfbd0782344f5300e33d7143856ae12a6003d6b8e0007992698ee7245e3c13969731c07fbd2fd7d99ff3896e73fcff42680636c5bc007429a5d0a652e8bde3ec2304c219d08c1e34270b945b7955653996fba3d1e3fe9de13ac2f702e0e697cba54ef9d18b639fd32dea627ced966f9a1062b9545094746fc886c28f2a9f89d15e2d5c5dc81f0aa3f4e5de72570b2883daef766b555a0bdbcd3c9f712793d5b4c7c5de281a6c87e3f0c724effba7e006a09f8b6e15b387517773ea3fd894e9bc030f18934ceba2c0a7d3b6f5602aa8aba5487882fc3fd9bfc2156b92526f8705bff18c127da69eb9e5314a8f05dc2596aa55a3143486bd0476cdde5bf1a608ef750746105bf489891d0fd36785db3aacf479fb82e33f033550683aa8d0fcbf15f34376d36adfe4cee17d7c756b1745e20f6a9bbf4f1851474d3461aa92b23b38fce62048e6e4822c5e49753314c1e3f9617d66a47a59a900bfcd6b89f7407ff163e889c96599caae081989db1644b3583348b17c6487a3b9ac6fa005c48beed5d71419d1d335093640ce37648d73f4bb4a2119b68ec1263c2ddb6a5eafe5d39d78d035e7b51f07925972990b6618d942e5fba93fffa20cf2d3caf677c1377aac22fadc9505ca6882c076e370789e8ff6309817392412ac32f388a28dc19f99119b3b2f7745ec969297bc1b3f6eb347d843af6d09d4f7d6c8b8d9d04a506901078ce3c9f7e19521db45c14f758e60058ede1a7fed0a0f54d5d70cc37acb02b11795b91139eeb55afa6a0f1a0dc415c5c52dd4100298e1b609255ba6fc399057174f5de6f6b64fea73959901f15836a0e83a44e4117fa9957a4e4188e29d434833f6a0f6b7c59880c815dc7fce56f18a9bcdaaea4eb6711f03799fbf1e3d16175965d851af7bc7e703e832e7cf5586e558fe9328f6d3cf584be41790bfe71c72ce7b85fee7179f7b016f5dd587dafadfb2fa804423527cb0c679145053049f40a27c1299b7800443c0874e94ccf09ad49ade1ef65f69131b042de023128ca3419e2946139dfe7b2cea06d66d9ed0e9e026238d3af4ee51c7522ef18e05e307c2dd236781826f71dbfb106ba58563f260e11d334e689589beb3111263377afec3fd4e763bbc8644b5fc858e1fe63f024136d202635722f4797bd61c487d45a38b95b66fade7350b81ec3ff6a7ca7daea20351051711cf19a2fcfa04f34d3dc72950bbd255ee05a03f2614471c86c209154d72615459b418d7acdc31a33f3141d401eabd1d8793a74684ba575f9c01284d4d4e1b4ee83f414f8c569963528b330d5b39ad740ddd96d7e06ac64186ac41f0d5745aa198b4d248eb61dd15ba961d201f017459bcc67583ff66b05ee858136cddf43188d8318b233158ef5b0b38744969d0312d38a58ca30c074f7fab973857c4b5b7b2269dc051"}, + {"0000000000000000000000000000000000000000000000000000000000002d03", "001b01791c29861fac40658af2c22511a9cf3f5d21061acc6d1b57d59d5ff08257903f5a3973e658a0fb09d1aa56405edb6ba6e5e3a853b7e2fb19eb7c6ae932b4ded5895bc432ebb9a4b6003f639e3787bf6c1100ce7ddd5f428bc7fa7f861b1ffd1cf2ed9d9f4d4146c57375f35748b914e018202c4a7452664c948d540ce80ab222a7c8ab40f182dd8840ce9d783378050741b8938ad89a85852ec284a20fea77e9cc2c921a3e0582585965c9a9efcfcbb587f05a1d5a27d0b51f281ebd6fabf4d5e09b814416e823c9980aa1475abe3211d667ca464718c32d4e613a2aaed98d11c8d18a3850c822a96655f9d589c79599bf36382e41a6d3b19107f39dae678a1a6fb8dd12f71d6be9f1c77c6f82b141d68a75aed8d979708145b8f2ca14e9dde559a18611453716d1eb3c9db45043ea637ff2b14a7baaac851a4abcdf2791f60b32f2339b92c6385f40991e9def003c533e0d076f21be15a2c0bacaa81e28e015d7bb069ac1052849f0f33911b3079c9a1c44eeaaf8bd7b0124de1faacd374b92add4de04c794a9a748113f233c169235615ecb2b97f9c67e9152d41bbe947f8c840211567aff550f97d11f241c1ac8d5e9847ef4725319dd88fc19d11b71ec19e85f82ccddd63c96d5d66406a5cbbb26d3ed05787540c9617e83b56bb6923aa61133df8a6716beb369a351c258a19864b87626beb40b6431694a25b563ce1aa0ce2f7729650f66f4e26e1a85ccd2b7ab247f84bbb372a5eb801924d52b6d11172c643a23ca447b713db7a3e53dccea4a243fd2381a2c0555b9d79c85e667f28f54f9689792147f0c1e1a53adc8e526a6c79daa82f21cc4e6c5eec910c2961ec08415bd53b5b5e890e6402275dc46b92399c5153c57f63c361261f37515a7b77a5e90230bea7db9ed431f4ce7841200cd54b1447afdac752740bf5aa78b003866fd56c248bffa3402a17fc8bab5221e3fee32013bd6ae2b274a2da2a162a40b564625ccf1f45dfb02a4f3e84894608dc5b53286e9e9fc98b799dd015515d95ae0bf6363e1e62694d7fdebe9aad41479ea90055831124d82dfced368d42cb2e523daba1dfb651a3b252578fe275ddb71b9944d27c20f5a27e11ec186138b6bf02e8a25a0672e643c9f58c2f1c5827e6ca11559c69ebf14cbe9e63e119801a9dde8f72fdf234400cd3c9de515df634cfc706de99114fd230a513f760cc51347d1581576c12d25149c416875e7fa1ef65d11b94fdc85049611a2703369b0fbdf393a54127ace12b6c57a35e6bb27e9b2859a1273e0ee0e3c3f7672064a912020c7bce9ee26142746d8018a4dc4d954313048f23380520b0192c3c70a7be26a3322605b81820d5b0278c9d9ccffcd1d66ad6b7831ca1d8695bcdd275e5b3a1a9013b35e8e92c9b5373b59bc3bf2fe32007dad87d603ece90737f7b8bcd0e3a2991db7b0240873860b58923190edfbfab8a5673e0373825ff7ae023fbb90bf825b30870c80e4a9a31539ba5cefa708034a64024815065d932f53593bc5ac9ea6887aeced0f886d904471fbdff00c5155c4fcae399ffbf55dad3231679372e97d73d65fbaaa36da64aef236385ba9118bdec5377046c3a163841b81fa4cc326c2fdb9ae23fc2238d5530d097e58e26ab79fdfed2389f8641d053ebc07352c9febaca0e1ba2c2af14d0e7a1b374822b05c9e929fb38b7cdd93efc3fd54594174f94eef0abd8369a287de09e4e8b1015b730011ba51b178a00c198dffbcccae9ae70d93b24fd6a68dd7e1dc7c8408c01f4d669456f731f1b667c4fe75fa08443057d00ae009f5c95eeba1e7b1e29fe628951a971679bbae1c30d0ffdc074c775679033c797720ba16a8327dd32b76618ecc1591b1e593d9c5556469177355bf6869"}, + {"0000000000000000000000000000000000000000000000000000000000000ba5", "0084253538de5f112ab556c7543e759a170039e61b248352d419a55a4bce3ce68030d28af21e0d9fd9c31a71ef908d499222d34b360d23f0e13203699a60e9358e0a856752d0f19732fb60b26c38cb2ce73e410e08795745ae6f3a89da3c50989689db5f27fb9cb92d36dee44351ec1307d7fb86129b3372cf8495fc2a830c032f0e210f1f9dab9741103832d1d9c7a793756b143222e709140b69b99d83b908d261c331c25a88c601d2ac48d9c8d4dc8717803aa7c336974d4f5ebf1b076fcf47a5eb2779f93cf1b1ed4da09d2d858b16102642295761dc41e3568f34b9b2c0b7562d9c93aa729915d7444f6a660b57dc6a055d5f8eff087a987d3621baf2d5350e57db98010981f84ff976899cde7ec6328801a045d191eef8cac4ab8978f41dfc039c2ffa3e279ddd769c37c951c534b00ce3ec6640087697b76b35a75f2adf32dbd026bc790c73677753a53b0f6e013b28b36e5b6875b3785363fc7a0a054ea17668c41de19362ac9f9dfb3ced4448a842484aba7edef981149073118a646b79e3ae11939b1c910da9f13f63af1650853cd56b96697dabc1b1c8f1f3326faf53ae9508937078b007d116620088169effc0aea3005c723220ceae62706bb1879d31a243162a9ab562381d83b20a7ba37de827922bce04f2cc43a8482df2e9fbdf9226de9bde981f13c1bfbad42174fd8911d959fc13f40163b28ae192ffff999b901e3aa0c7b82d4ce4fcec10d4db119ddcf3d5d49613d0c7c55db7932c3f916d09a550de21a98e7fe729213aafcae03577e08d17e022648f68d4917e9b343a63319ce03b29e4697934db083790cf9e0f49c5f0dfe1cb01c09192d77dddf35e4c960784d9db3b0357b457f8c25c520e36a138627508d545b52d978f81b59db63028c38e0a40d933e80929d8fc01b4693a7dc6a5530648c32e7647ccfd62a40372924e36dfa77fa3acd20e2a42d574a20615cb7819d061137394350dc0b4451db8b9681f6fe27efd7c0868a397dc49d1e566a1522670fdb3598b8835b2fd4457c23e9df120a3edc1d76cbceaba7afd03f83eaf1a7a39c0fd3927bfda4a13beda27958d2cd36e391859f353c91a259ddd61e9bb04fdfbdaa2d6673d9f6c3209ff79481e3e638ea973e0d7d77d6960cd19b31d37862edbabf8793dd4c3e62b6c6717a1a108796c210459e92e700fc8278feef34fb1ef053746023ecd8d0d41107fba1ba921888dd1388ea193e2f156db092d166f8bad940a4f5489f8e60875e949e99f811d9714311fdfa49b13f185438e99c1e6792a07a5d83eed8a130c1db5d7d57c10fdc8f2e62645ed28fc27f64b15195964632152c955656c32a283616e013883e9def526dccaa8fa54e415cdc7368f38dc423e2b1ff297d953190d45eea4aab5adc0f93fb4e2eaee5908fc7f5a0605bbb5485cf0e3ea58536d3474c5f5ee57f86c684a8c16d4d5234d23ac5936f54cf8e44a09145b831425933fe28620998db520e8c027fed3627118d57fa82e4e83b5d30cc85be5b868b133d2e2f29d1c18baea198df7d4e86f2445e237c1bbc98e73b8c60ca87f7743acb3e6b472a269ab8c251ce0e322cb5b10bf75601ef896e951e17cf9256758d06665d04eaa1e9847c12338abae401ae539ac35e2ab9cffd6c986823c2b630884ed28cd8378c62b8835c23cdd99b9a26fd2c4731cda744270e5ff95dc97755a566d25f5a391b6f07d222acd9bffd572ccd8cf0535a27da96d92a3b2235825df6a7b09d96a99e99128f1af72f9436c945d1fdb08c4e638081069b7e1d396a4bdb65a8a9f965ae37c2accb7df552ed5cbdbd9c4a4edbc32ad41f5f2665309d8b97e4623ac9f6c6a40dfa864a0c90b6f5fc41c238e273179676f41c94c750eeb4695624ddfb967a8"}, + {"00000000000000000000000000000000000000000000000000000000000008ab", "0078683e3e9e738dabf610672e7e03f8280ac7c5c9401285ccbde1481bc7dc3c9bf3feacbf65057b9c2a3238f3b50d6e9eed9fb38736a1c58db6b3b83f2a8560c94c497ae517355661070eb34c129a4db03274d6035d44c6c4de8957c919a7b8ce78daeaff6c9f0e7f2b075ba0dd4d7727473cc2efcd51eb9f4a8e1e5ec305fcd31d7ec184dde8afb132d9632ef92ac2164ce90799c109d8058f3d61de961799d7d0dac6207fb782008ed49df8852faadbf9d58f0232b45ea8c41ddfab10b506559bd3becf5299b338307f016d926b394ba2069337c2c9666659f7cf02b4f4411379ae5171049127597a686f923ee1c55965f003de99028b13d9ac2a04711e4e1ee6895b42fe03f4e439d5ab2a111ee08c0ebf7b86261554bdc8f7f4372ecc16b94c8d13f7ed0d3987febbc5c1bb6e510576bac92c4315bcfd9a761be512cdab1b1ddbdc96532ddb43b011a1adda09cc0136dbf6da6235fb335767a85e6ce0930b78bf002908250c824b8cf472874dd1ec9fdefbb9fefe54bd8e0342d2dcfd11b900bb1a827c6545e11cd985d3aefd0dc5c1234c8989754d6f08fe1fe8e4ca993b1b378102493e8462f01609d20530c73d492fc92851db0db559e08f9b59a590c78edcb637c4e81a3e4905f4fabd0c054d7d7118abbbce02e1f09392936d40bfffad0529a1daec115053318f33d51085df49aeadcf15ca26083676137c0568c2520eb346502772fdd8b55ab3d3376ec2f7d6a39f6dfc5e9492bee7930e0ac8b3c91609fd62c20b84fdc2366fe16544f0df0859f73d35b0172cae239bdf42b31cd362865b45177e8e5a9fab9309bb99a19fc898630f04327c4f5899925f9c157c224e87cf5c12ee84edfa7105de185e9a65f2679cac972236e670f3d8df257e431b1329702bbef5927f1b0932422d2b9a28b579ad6583dfe7344ea92bf27530d60313868ced554588b001f15deb9251ecce4e7cf7322043316ee04c3dc13e0ee2eef44f909a84e73c365911c9510d7776021fcb1d25f03e69c462c0c69bfc061d5e56337f0f4463750d03f520be195a346b3a166d0d0713d248962ef9a01673537dc1f318f8c7c930413e6653ad899e459d22d6f71da9ce2c2dd961151f112acb45d97f2175c180bb081ee768243f73481e929b65823b8b8faf34097fb448753961bc766baa1ceacf09750d4ba5e1ab9f4c5a338595352f014ce9fbfe2f0aaf86ac4be52f69cf33315313bfcfc257f434e89f0eb680a776124d6d0b65a186f738fe0482e729742013a4751d6f07150af8c632736a9b174b547a3fefdf15f68b8e345c5c1d429761c66e37f5cdd945544af73c60ef3a7ddb7535af07a4e0725dc336260bde72c71c37f473e18e92d7d53fe58d0e5d968aa14c96034b1ce0e49bfe9e48317728bb340a7b3e5ef4e437dcec04c66bdc5aad383bdb7c1050759b32b8c21cd4374b39b8631712366c0bc83ba623286b2331ed2bbc8ac216b5727c3a550f58efc1035f5ba9759cf112d70bca4a3c5f682ad63277024284d8f4eecfb9cb537ba85404c9b6c61107b84d82213571c23f505d9c894fb2510e3dfc600ed2ead99054a173ff98c888b55ed44a0b085798a50f4e0249c64961a0ba21e4cdc46ef8092779e2cca722721571ae77e842cc62535a7e72f42b3008275931b77835f1c59e1bd144effb3b8f5cfdd4f7088964c7db54e7f1e3b272b6d0ff7d88b6a7e9221d3a20c26dc4d09561ce26344eb6755803408b5aa3b075d34fe6cfb1385de1802a67cffb8aa38e713e18760cbadab3bd1c2f9954a9715d9fa2b76a7393fe65f61f6ae5ac9d20883d268f49fd98d50d3b118f9fbfa84c03aa8c05a1f18de3a3a648696184ad98305ecb0759684bf6be1b6951bc3d98c07b6258eaf9849e27af"}, + {"0000000000000000000000000000000000000000000000000000000000000b98", "0191ccfa9d67dde9e6e144d8e045df95bc5df8f8d913bc09a21b9da2e7996901c781b48dc3273dbbe41b0c7a3c6cf188610173c0a1b50e3b353d302b4ef2b32962af06a5a710d7ab6036d3fe68ed7362c61e6444038e0793479b9def96e7570e3b69c83a99ae1a41dd0e22c55a8659b68daf2dc10b71f7a63998fa9782270ca7254128d23a729693e49f50aed3abb8047f392f1b244d486bce7bf1ab0e02877e6393bce78209ef4f0645e4cdaf5c775d24be0201a5d4acd5df0034baff36e31a7eb74f0914df2463798fc2cb96c99dbb22241f2b9ad90d8d7a553aff234a8f23d9ace9baf040c11f4bc4a91ba10485932aa66f3cd67adab569d994630b5f4b094aacdea57913d2ea656a3e1a98825829a03e793e841b588ea6e954b422ee573d2a6c27d4fea41bba7ee6384c4ee7cc1332eaa4de877b3af49f18671c372116e48b72995b8bd25eb2381ae5ab202dadf20338bbf8c491c6eb024c624d73bf6e6ec106bd898c12dda4da6064466d8408623eb1624be0d32cf44ed31589856fc7c85babbc8eb3288544554eb570db155444d4f2717962a87519f2761dff70d1fa5a089a2829052c7f048a8324a4901f74c1ccc878fa3e42f75fb70b6d78df8bb93227e7240ac446fa299f0e1758b8190d905952b92078d3bd6c3479cd75edc1c6444fc4a81544d559460558f1715bb18dcf254f15892e1bb6c70ce376e7fd930ae0a519023f674238c25ddfd376e71533117c2d4a9a71ddb44406f32f030d5521fa8a2827109231845a8dc70c05e4ee77d253e1fe6a9e191136b16513f91ed5a75d7bf3e19633fa3df54c3d9a91123db977e8d98fe78e94e48bba740e7e2dd0fd45ae171c5663c2cda71a85adea095aea6fd3f6075fda9b144940cefdb3eeabe3d0533133cb9c2b1e6fff0b881de876dd5b258373b3a3e4723feb5349ac04b1bc11028132dee0e2f7014ff502282c11d21a8a82566fc122d87be6a9d0c1913732c2f70b3f55bdaedc16e8f006236fe315d53e11bed1845d14c5e57a0df474679341d7cda1357b33ebe6ae9c5b9d6ec98b8d8a5edf9b03b48069a2b3d7cbbe5080eaafa53892a444b962d905d332f54a81f37270f0d448f739ba36214d1da52f21280520e5dbb497003536f0e4da089b65aefc3e8230319443135e57c766225cd6d668f5db61161ea5b206d9245c89e3de639a17e65ea671aff63b63fe169f115082690a0504c518fc21b3363e4d648f4e47918707d8ab013303e9883e4e6280b0ee2ec0fbc978b2dd198aae8f71d7e223dbf643cb7bb97a72155f5f277e07f2290d48cd759d2fba7a1c7663d37af447fa35a73797eb4843eaf309a1b6159957ba8bff75049bb0230c8f5760df859c6e52a122ebb4508909b15d558b821dae776b65505d291492354de9b6872d84cfd4f9d406701e47d58b116965cf92374eca417902827a5b801b3917c9098e3635785b8261ddf79c50f2e45d23ad11d16a5cc8567e8376a4d1b3c7f5a82c9a8bb80c7a60e7e453392632d9f4737622df74475dd9ad33b36407156880ec14d3ffb60882e7942a7cea9cd89a3cbb3aad351e26d18d22d7e9043d98d14f3ab90bf69b612794a22faacb5534a987138acab9e9e92b955f9c503a975ec71da87717a1ab74d4a3607b7d77fa4ca1be08562f188fe0938f6279213afcb98598817ccea7675e9cfea57e57daffab430753c6432aeeb2347e792e1e5a6a42b7e0d9715e5432e2a74295116220f86cb42b413770cb5f3cf756cc84c9a3d6ffc6ac61f69f4411bec7f0725583f5171e634818ce2099753cb4a7b2230ec40d21df63d3d15ba33aeed945bab5d3d6948c211c2b132d6254e52879565890e33012fb67bd23f4296da6eb660b70011c6775b096422fdeb006b7b8ef"}, + {"0000000000000000000000000000000000000000000000000000000000001f85", "0006523a496062e91bf9c3e6e07878b525bfa9e4582ea8fe2e7c10432bcabd97c3b25d35db64da7cb3280ca4a499eecba8e969e4358547458d9623ef7ee7191504ef48a3a4af3143a851faf39e4361763baec4c700ce15b79d8c93711e8900f1b64e111c7605168fbd0a65e48a19cb30f52a8db377fc73700a2a2379e5bc1a6b9977a91a12412e427563a3b45ed373f79d933c2193465cf11d22f19a1346347d62e2a26cfadf9cc3000ac97e74829767fa9a108a049fbe1d8e69382f120b6d290b5453b301def0f5bbd0f640f1882874f7e519d4915e3f8ea1767618d4e43076294e5c713495055939ffa71218b77d279ac7b1d25a02ce887818eccc03e07625c9d7ef34d8f85460cbedc5ad48b9af804845d9bf7fae9d9a1b4bb61599d4bf58b9fc9f5c124406078424491f413bd171e12d35ec39ff2715ffdf2267495bf584f4fe8dc22a67a01d41d049e98dfd635a0103bf056e61b187b08b2515e14aff6a21fc7e67aa1d176bc6704ff9f1f4b79433e642a54938807db0af0d7ece76e98d6629054e664dba4cdb49f376563f102bed02941c69cb357c22a6f52a6bbe4fe7d61ff1580985ec2cc6c8f0b99a4a819c961d6cdc81ab7aa41a0e4c017bf8bb5db5eb66256e2bd012b18245b7a3a50b611c7d2ed32497d8e142e03060a12d6e51f14afc0baa57da69cfff8b804c01b3bffabf4784ffdd2eed0ab72cbf2bd5eab4c8c5c4e40f30d1916bbf8d9f4927b19af49ecb842d4f288308582bd03226d2dd69751eefff2b772dff1b9390a25eb5acad59c8050f5ca21fe4fa1444e8e2d19de6238a7232394de96b55d1250b6cea8546052d6f96e91281715a4456297b79ddcf16139e87c411832d292914012b3a19d679e8bfe66f1f89f1920967c91b4270e2234e7774ae034974be40355f1efbbc12435afe9073d1c3b693610e90af1902000a1b493eea05455c71315fc4722256d96c5fb8d0085dc8aa58a70e45fa78c5db94b347366fbd3c999907f62b500d058df3dc9d61b6ef45b81e322d3485000dba3f4e92966042f4891176f56061f4619731773008346eb37ddad6170b08f40fe5755df384b0bdb4f614be5b8b0b52fff69eea733621401ec4daf63b68d014e58775b0cea898ad5751f3b47c9cb5cf4c4ed9386cdd4b891f671fadc671785462634beac6fef7cf0f0609022e47a3466bf793b8ccf860f1de6be17917f50ee817715504db079230d49b3cdf7236d79e5b00b50920112add9a391159ee43c1592de2f315e09be36e21c15c1d2bb07d9be64f3a865be0163b820d3e5c1b0970fc212205755c3cff1168051e2d70890a8c5bb85ca5667d859936992eb017786ff491d70c665a52ea1bc4f9f4198f23968011f3cad7b6f8a1455390c0ac25ad3d43a1de749927288ae72af0a48ad0fc9929c2032e49ab81472457aff7f2fbd29ef6d5cd4895932c17d85a741f87b486db2c95394f74c4ca6df4b373b11326bf048aa2d7537c34c58e4b70177e596b99387a1e2421a40f69c975ad9643cd81213a85b3eb3dae22067885f530ab72d9b982027bd7a85eb604f9d684f54c6993b31a6e125fc8bf262ab765bdc362761bdfbd1fe70caa430fbf77793802cc279ced84c85768fea932c0ce3a53cf6beda01624524f5ff6ffadd2de7dcd03b7b2c0c11fe07dad9b0420b250a85efd09bfe39d0c5cf8a2da87bbaded97011c1479117ca964f4196e044f0eea548339c1efbd71e98758b82db0241ca96c4110d5d988254d19f4a4748126efc90a0762bf193214389b77eee560ef58b1622a20cab630af8e6f027b2c8c6fe6cd58bcf1caabd8e8ee708b9a9dacd8100f1b7773db08a6713fc9dc01febf7a8948b83b5ca74c32d57f12a9b5ee77d808f4e455537bf9d8d69731ab"}, + {"0000000000000000000000000000000000000000000000000000000000000a65", "002a908ea8a042d1102da06927d821d44b39cf3a862da4da0e999a805ef49148dce3d077ef0dbffd176608450a6f8c4ce488847e08420a6e6ac7384e7d49dc2294d9c29349bf89a52f45cc7f667805e167dd9f7c0e39c0a1d691000cfeb5325a2dc6a2532a89b9a3c714ddf8dcc1a934b175a9f83a9861335f33b17b31db1ab49269cfb32629a659849c905395f31352de58124ee68e1c1269be71cb0de5fe063a9fbe68efd6e69a0103202d9904f258323ea8b79e4ddb9e75197f43fc0d4b05f2e8a642815ec53630cde9b126d3e9fb77b70beeff8001c7c2070ecd7300e3f8eb99004cf352201766e69cbb2289af90583786aff70d8a4d5d7bb39502c63a9c3a2c64e98eba50752ebbcc1c8c49fb4cb3079b8a2eda648399ee49e86636634a36d9399e70780664ed810809fd8166357277067b9421ca611fdd4b0742565fc4315c4dd0f8d37450bf4fa9caba18d71a005f197e176362b589a32277dd32917525eefd93d5203a252cd44c024dc8c22413c1ca6eae3441f5315b00f52d37eb01197c4bc1617ac064e661a1be7dc29e2162fb001965d1b135bcf7a55a7f23860dde17e4980a1fef24502f7103885d416ee9933c6d92787bb4d0323992f452950106acf074f1fef5c4121ea6bbf5eb20da24b1d19e78198594545286d67eee81863e95522d603dff9b27053ff7cfb7bd116061ab841eff9a3d06dce5f711132559a65ec4b9bab2f611436cd084261f376301ddcc21f5632df20b2d4624bcf1c3a9db221aca541f5ee747179b6565d784c92b3a73eb9b9ab3253d2241220c7fb4aeb6a43101271b49888b53ec0312864cea91a25ba576fda2146720bcaaa5f917944c448cbf6689a07e89828a55db6d39f6075353dd6fb42cfb3f6677cb6ed9841c33f01b582c1f2fb7fddd9d30da36b8b1165068ebc214ad76a82aa308149c1590004b9f6b114a03dae0bff2616c276e2ccb0d5bd884239f5e0da69f448be12fc26f10595aeefc82bb19c901afb7d2864f157ea19b408c803c1ca60ab2f2a8d1107a7a944825bc1f525ee240125664ab4cc3fcab5301204be6114e73368c80221cb154b26b85ecfe4e442b14c556a19b58f50fdcc7b427c926c67ad7950c310f983b8509a9cc1183e7833402fc5e6d603b707716525f5e5efee3271bad28b54c2b648d7f809a9d06f501c099fc3781e5fe4c95d1ad6b2c171c7b027a5cce1fa91eae8a5925f5b90e72ea6b659f3d2f1277c7cd023500ffb520fa5b7a66b4755771379e45df3fd1d64cc7a570b3e821c34fec14e9ef57987e96d5dda1c810db2e37d785894b0678675a00e8bebe6f6fb70dbd1cc1cf5eb1de297912a99560e5f2cbd7c9669fb75b1502aabecd7324d3e4485406ae5c31656bcaf8c0e44366d289c79f1527100be5d7ab379ffa0e0439661904f0764a860d8994fd8479e9d7d97eeeb725de3ceb1ae338e413a1b341ca47a36d595384897e9e78b0e018835b7ae2c6cab83f222389dcef596936cd19ce47573adea1d7eac72bc71ea5b569d0ae99f23d3753b00c6be5fd61acb463c68e5364a02eda916c7c543b75176de7157f1d82fefd62923ec4795f720aa213a4ce10cade890f1333549f65a426c53bf1c5f8fe995c4b3a1c97e58fda648312ffe7cef4edb92a5eecb6ee6309c027411f8ea0fe866693029ca68462fc48bca50217189c947f5f3d93532432beaba80020e1c14f22f820e75b2a78cdec10f4816694d5d41d3e9a7c7c672b3f76c47144a7a279685ac792fdf24322903e9bc8eb162dc1fbe954c90cfa4164ef9273ac6af79c782ae560089781f8f39f7bb48bd8fdf7d0d327c1a0dfa4c2177c83f2ebd042a3aef6e336dec062cdaf36f6cacb1c59dd1487a3e11364d442d3613468b8ce537393be"}, + {"00000000000000000000000000000000000000000000000000000000000001e0", "0019884ee8a0fc475b35817b1e9f98a12961fd1783238a62f800d7b82739f8c71642ded05e0519bf941f246983199d157574ef2d124ef7be1f7960850b13893e079fd3a0eb2ec782c56500c3f84caf987b9e150302e25bd9eb47e9ee5c4362e34ec2b50a45179ff67e059e4130334bb88dd76041188e5e4069865a56068e03fca6c8a0e083fdecc012d4f06422559ec7fa5d5507bc5a190a93222710f41284fa5096960c709e0cb1118b870ea1d4be53e059f3782656a621822f5b8033222c1749bb64e337477694baf6489ed3019c3c08b514888250fa4dcc3f4772588c0773db2a715d7be4c33fe75c4dd49d9cdf345b69494979ab7f1734df9f71123b09c916d08fc7b5dab1289d125e0481cde8c0e827a64c268255ddd50c5164a336e84ff66ef7feb1ff19c86d91fdd408bdb5dd03389a616fa1a278198a491c1bc1877b1b68ff6f7ff2544823b1918f483db6ae043ca8c91b92b9d5f50dd19671f70b89129d1cb94b05d2ead1ad054caba0df0460a1c1ec02e8f71b1116266ba1ab6d8b8007ccdf42b34eea361b4e04ddaec42bb29edbcfe4bd7137851339d79be7f74014fac5e609eced7c008f5b09d5dcc2dc2dd0f9aebe395808c038d53285c41ce11d317a14c425d3a7f2bf1a9a8b2f2d3826f8661d9a12ed87f2e39eadaa24fcf2d7ed5438088bdd9c24960dfe41d8c649cb554b36411a9bd20533971cd46b7f0be1a1016516f50a83a00b9d06e36f7b86d5d97143ddd389cc8c95e58c0f656d3e68930d44e3ad7391ffeca345326bff2f122615549f31ef37bd734b19325463c8cd94fc75dcb1ddbe209934ee101df2fbfeae0a1f9e944211a21f41e8b4ebb266b74cbb4493eb9d8a21cc0fe8b0f0eae82274585936e41362a3dd116f6733f28521aaaee40740bc370e1ffc258739794ea196dbd51245dd5c4111edc0843818d5002fe2df9d178c33c458424f111625b131bdf8cbd300316fa7b19e2a2f6d02a1bc1c1beedee5cf9af596060c6adc8e5e47a32c20c1bd0d18cfe5f0afda6feb097d2ef7a6cad5931ea560d7d7beb82a137478ad8b0670d8f424188973e0e1c5497bfd18d674e71516d62be6c9795a6cd9879ac666a0c2c56686093e7201c9123fd5126d3ddb49fd8082bd1fbdbc52c38eda38a73cc37a01f814eb95619a6415e6b33a4277061adae703bd4483d1dc0de7edf3346e7ee4553768363dc18b1a3d216aea599a992a82c844e4649ed6da8e7d454609dbeec6b8d412231dd8416e756062c171ab7a65a2239f2c31fc5c87dd5a5ee5de6d542acd8ef3178a200437f2cfbf0f4fb76872b11e79b8e1b4c69a93c8d3093caf4c1d71e9eba08963627cb63685176e5faa8c0bd0395e3c97e612fba0a14d5def6d9d74f98e08d029c84d9e9a35f037ff8bc2fd45eb3961c5f05a444100f0cddc0dd62c86f002647dc6baa869ce5efa72b12494a6c71329769f923a232971700b1dc867908bcf11246e496c9e95fb1c7783a7d93189556d5e136d0f2a2e6fbd3ff59dcfc3db22ed69c873d51f7aedf7dc0768ace4391460c11afe1148f8e2db70a3e333231217abe29303de9ab5dc48c17eecd6f5973f315d61b50b06a0fa544471e49ffac22dd56bfcaf1daf9b895a0edb03f6e0654187f05901eccd95589221a6b6c989069174f8460bfacd3617e322ca1aeb1d10bd68a1210c4b7c6bb49452ab84b6443e7e41f2d21b649a67d70ca34ceefbb7c7cff361f26d46956932cb2b1ee8993ddd442e6b12d45eb8d50453532534fd4f0a58e57c17a1bb5371dd86f98c5a048f2b6dbad14a3a745c1e1afdcbc17a10dbf5c91c522cff6d0cfa20deba878318092d1eb4f79d97bd3233888aaaad433c949d9e7b1a0d5f12e8676377cc8cd1a97c32cdfdd6dc9067b1"}, + {"0000000000000000000000000000000000000000000000000000000000000a2a", "002098293c21b2afafe052ad2ac3280d2fd75ea6300800ec336c981c77002cf200b3cddb6706597c5bb51f9379a383c8ea628b3893642153ca19ebe45eea4f4b315dad3ad5cfefc2f1668f9d717345aa681370e612d09c884f2c0f11c3ba249bb7c47dbb7caffcb29725b315921b2ff11f8675c459787c1c7efb33b9b6841345811784a1b21dbd133207daf652b117a18ca1253a2d953c7d19506917b0e77f16f0c61efa5318eeb8012a03db979aafa9aca568db25e3927a6eed3bd16901547fc7822f8aedc57623bd97adbe396e3b99ec7324662595f3cbc941673e26c49e528a069bec9f939e39ae97ce9cf02a01ca20d5dcc05ddf8fa36eddc9400882a424fb9981f3bdba3382efbab49d042a0ec5950e363c3a0c16c911b06c72a706cbd9f115fd7a4d0d2b017c9a04a290652f0d237e386a5b09bb5e58eb4e376a4d3149a106935ab01920c37949ba868b591045027244c960423012c9c630c6d3f13399b0975a1b503b5dd52190e25b7b3332a707133d17567507fea39403d945722e063f6ac21e10956554084a1a90d816404b994c9c6be197af8578157e23b283bdd7037c9946142b6f0d519bbf73f05e018f2b4f36192f70b9477219627c9e7d479c037c01f19bc132f98472b34d02e01c875a21dedd5af1423e11eefb2d67a1a704bb2ecc8ff65dd326ae4fc5ae748bca536f1d67795d9eac8c03fc18d34474ec07abc82185a48c8478df33d1b0bb28e35bf180cd36388d2f95ee7fc6a672589b56cd970dbb4e2f558d87e5a086d4229273030ddf8eb6067127e057cc12746869ee8095959450541efcf79ed1e104b45b4662c168b9685993938527b73e72fa988e7e10720180b525d77fd14281c80c67378cb83ad0cc380b60d983a708704bcc0302d954746c418169b1769b42de5c449ae123fb2023a4cd33f3397f1990da25610170d591b2993e679ded84388f40e9b5cbed178cf31a6abc88a655c8f374ef239ab3757a498b2e1a1ffb089f82c48bae0b659699221407a8e0a4cd30f6fa642c58cc164f0d0a3eaca112daef7ee3ccc675088796113d6e9ce38b655ef57964bff5c2105ba08f7f807733e747b51e97c7799960441d793468726cc2788b211806bda7a4e03c837c7d3594c841b069d8955b5a2f35a71b9cf1ce1770d26616e895f65b626917dfcaf2033da7e7c2d47c78e926e0f0d84a97ad5cecb986672442d9b2d8a94d3578a7d2ee56bceaecbf66bef3fe0c6ab878a0f0ca89d1ebb19eff1079cd48a33a2d680ef0de49181472578ade64fda5c4dfb70b455ac6cb11f3cfc67ed87d45308e31429e5113292d36785210299101ad215190029cd192a1c4e92cf0e0532bdd7e174dcc9a29d1f7c739cd33ca7e6d4b52430dbff50d1bfe41a22421ef9d7ae4747cb934962dee2d112b950678d6cfd28947868b84027681e2eb86baf35b5126070483adb8ce6ae32f8ec301cc7977a25feef877b406dc2dc7bfb9b907fda405fdaacf6bc6b5643b9e4d1d44ffb75a750847d2f2b433b2ee00f6faa63bddbf06a14ed775c581a2ff5a494685697f92d12ad92fd21a699ecec1c9c3a3acbb7555cb75617d5cb77b7d4919d0c24c5a5d1ed93f48e58770ae9d5624fdfcbdfb2146c42ef9777be1f83c08f6997a795b60065babe0069d1cdd3a556dc3fa7f30dbfd67ff206e00d61b7421395ab72669863dac5b6391594aaffdcc849f5fb413e4f8c38b0b77e77050c41105571b520dbad9e3201f3afd20940d0f34d64da3f78f3b010923a372f4160be63f296aee560185d6f2de56c5bcc1baefbcfae0128bee7d182ddd85d05612523076d7551f4c774637134a618c6ce621ab644ac33c6dc7996d373ddaee7a4bb6ad2c91a4f2a1c6640515af335cade400f6e8f1"}, + {"0000000000000000000000000000000000000000000000000000000000001b0b", "003242e09e94e78b29be96cc5b67ed0775373efa15482e2d90706d5d63c0cb853344b3c6a190de5395e200bdc6f56270ccfdb36873a95871941987f50d6dda18153d3b31567efcfaf1657ab2e8b62b2d99b9f5d7065f099334f31133ad06e22d1c17c601144aef204f0bd36f151288de93b0c7c56e8ffc9b9961e26ec6230c7f1eff814bf2abee2074988d267baa7985dc59a010905ff367903782f286e58d922fe199e8c83fb1190304a87687ca4e75d6dc2811604b6c9647ad766a503919afe7ce62ed57485b060f00df1076eb3f5c1b520519039f7210f6d782d1f3a9feb5a9f18e2c1f6013354f0b7a03de2301152583804f76a8a0f37e489dc5046fcacaf5a88fdb7dbd93635d2cb73288bb786c9708bb7a59f2a274fb9c15878a3565423e83a63d26150e259ddbd1f26ed1e178542c05fc6445b094fdb665178a7992dfb06829dffa96a6c270cbaa43f8b9904a012417a7bc1777e55fc2a060552e53adc8c49553aa02b5fe718fc4905944fba8596be4cc66efd0ba6e39125b092b3704ed5e8d7ec3b0d4c4d4667d8d59328f2cd38256da721525d91ec2d67d5374d97b309978e50221f98290728e219e5ce1c42fbf0b896cfd1258573bbf454a91cfe8338e7ec80480ef7462562956a5b202c9f6dd0c45d2269908952db4c6f48685b8fea3c62890594bb6924d19a3c3f7a414dbdddaf8f298a58403e7ed273622fc6b28cbf0eaec39c796781f795755125243d6886f706bd23181919861c81d72ba73e5dc09866166df1f9819056294e88cad9d560bbb75e2b874e9d450b53320d1bee6f8ace55c305a7b6ddb0e2b0fc9132b3b4c99e6c796c1bee31a9ebe95171e28ec36df9d3df3718d6bbd0fd406cfbffca1a1ea36193e2589cda3e3f025c9849403a72fa261e102054eac4642dadca69ca67a5beab9d59de7cb4902d8a79a0500012c19d097522321d0a1e3f210b9e5f55a2a8d38e01bf973d409140706db1161d72f75e33230ce1a5b452831f18892de588b3185c61a0fd4aa5a780b79bf9437b5439c6e530a5ab18a93dd05ccaeb553dbb76a2b02582e9af08a2bcfba8050cc6475981a53aeb7d4010b3b78c6cb8f69a79b5e030ad7d5ac49f3459642fe035bd50e1ac4504a468271c8ecbfc8fd1a86996fff464d62b98f173dc6be05775f9cf365eebc221b7a19014323718cd473a1cec5202163aa6e8c321e1288d12b02e165ef508a5df29968a91179cfc66c14ff278314fb97da0d547974b574b33536d6b379eb0a718c5034e393dfffe245f1d4c0098a12634e82e6657c3c0b06707856339d5c8359fe6152e9441178795cfcae9b2749429b4514e1efdeb7e36dceb8f47a3d55f47d4806767643ef231f7f3aeb2186878f96958f8518401a45800e45db53cdadd4ba0841fb6546f774b4bc571e033e12fb2684aeb7989282d4084460a2da71bb60c76033032302a8eb0bb3969658ce5ad9c213b957bc011d925d3c964ec456a9b8d8e8a1ced1cf530cbc845f28769a98a4ca90a4b91f74e18738b28f0daedfd3e6056740dfe2615e854f4ba05a68ead1b90242318ef7242da4d0af097d61dbd477c133f0fb3ea3cc37f64509235453241ee0e11d28e4657ae9408a26d0dcd5229d64becd9eb029d9d0726c749172073f804f5c1bd9073983da8fa48f63492de1658f1b3b8536317c010908f8b9c388935c1701b8314ff28accea9535fa14f90b0fb8731f8f232586093237c9e1af969f139bc6762132acc285c94954ddc632588eed3d48fc0b3aad801649fd5609c86972f32434400eb03259339b70bfe62f6911a4b36293f5bdb08436b3e6c0ca04f07814a11e1bbacc488a7c0dd367d5230dd22ce2c7251d019a84bd757f6f2ba849d7340a0bed713136a738f56bca"}, + {"0000000000000000000000000000000000000000000000000000000000000f8c", "003d0b5f1617c405285421306b2ae86a2d399c33a81e39c4502b59da9d13ac125ca547006da24d9a618901a158a9d3d6d8575dec7c1deafee59f41b0baeb190600272ddddb80ed090e20cee918c0245dfb0aaf44053edc86f958c2ed01a780d9088ea520a3eec533417da16c72f2efc48993461a0c0bd4c3b2cb55597b6205ec3b227fc219e156f5e08e18ac9d00a0810bec7c0cbee93aa29962bcf807d170d52d62da63f677e452051ef18472cc031ca8a732e403fa950975657008050b55bac826588ab8fb83c20d46e662f24afc364ea50cf9f4be8a55cfc0d46814cd75e70c0a6e3fff7f7013a77195bc15b42ce219020f31679f423e7b53ba420ecda6ef21862bc53a56a51f065dcba6879cf62ce6223f2c3779d752cce9ea447c616f85f16a7f197a05170a4bdc93a6e415a71e04b9e3cc5a015140ef7f382d2af23ceb1f94fbe2a4732ae2fa91e9acb5ae4a03027aa9072fda25250b32d1543422e8a5beddae017607c38bd34217331ff2c0f15ac97b55e73685de4a5f05e8578797e810f79e38d83e64c76fe2eec33fe516085cd23c2489375da7b225e781760146b536d9bec5070347988ece6f589edef376b59cd77e30a07de8b52192a4869594148757cf94eb9749b63eaa29fbeb941ea10acd359a19f1f7eb63be1235bca9d08f7da998250e91750c94b6e9e67af8de6f6ccb4e5d95d4cfde02a7bdbb414748c1080be0977b79c15ca44a6d90630ed9bb29380cae8c8d81e332736c732ec5bcdae4c009aa9e8ab65eaac5151fc1c4eefbf379231a113d2935740a1c5c60d5c7afb0b3b5dcc2eac2db62f7816b0324ba6b7eaaaadbb007a351f1df1c316e9a35f7ab0e355b45406526c3f70ef2862dc592d59ac16d02261d40aa5f8214193d9c4e54ab6f73fbfdc88c2ecd471d525af1b718193cfa0612c283aa2d4ce427996737003f1e8ba274669fb69f12f99f1d6ab589de93720803f20b2f0dd99d0f739720b9e055289847c3c997b92ccbd563078f5916a1aa55f9267fac233e359d0198440f0b2b961cfc15796684fda25ef9218539b9c9d405400a51aec15c704c6768829a4d15129e7c96dceb060889d81272e111a27954946ad564ea70b61fbf030dcfa4331e1e254bdc78d37fbf720d699a131f389f1829eec79c1e9d9b23c853da54c215b295ba17432705fbf1e9a2184688df6ae21c89294d154e3aee1b09071c02fa040fc131b806c0d946a3fa8c844e3a695815775e4383ec5a19b98366e013fc248f1835ff054a2891afdfd69f404171e392e268bc5ea923bbb9f55e0dd4e2b38eb13461d854521e40b6ec90eab71a0fa21f4b44c2d96f63bb99b2f362c3ce47ae0643bd74ff1a54e7f0d24e31472ebcc3b9cc7d3621cc137a2a71212c55b84c7b203df333742076ca81b571aeccee8000a47a791b823fa52a7b403c3e73e07a58641b537609b7ba9e0249a0bd0ad7b1d4d9b4145ca91853b8b42934a3d82522a7239b6f346cd1da18de7ed4ba8a0f2b5a3c1da04b6fb4721dd6ab37e53c1a47acfd7362101cff9cd096ef3fd77b83bb45b2d46a25b7517f1b20475ac7cdedaaf18f063506c86573fa69e217da1820f7fea1e55c5ddcea86442a15490963d20b9f63535695be809a66af2d5f2d46688eec17dae4665cebaa01fd8ba7c35637db73942232a79bdd3d25c18f8d911f4c3f72435fc07be7d5a286eced159f928e3eb55c1a53d74905dbfe21a7a2289d7bee229a59dfda234e1abc691f2150bb0b02ec064f4c5744de27c7d83d0f09a9d294cfc691fa98d291dd1ddde5fe8813f5bbdc18e6d2ce6c30ae6bd512d25e1e7c4769ae3e1b9f4d26c32943ab5079ff35c2163e70cb9225c381bf67e84bf9546b08b9deafd6b2660aeb65558dadd8f4b692"}, + {"0000000000000000000000000000000000000000000000000000000000000ad2", "0012c8aecc0d9278a5af2943d7f8dfd258a25feab011e66922091387cf5f40e1484a18b55ac3e23c5d480ca2f27c9e84e0fcc3a507c99dc008834ba37d4609148d9184108f2e45e8c023d14930c68cf84fb7c2f800c5a153230958c1d3f662037e7ca9ef6a96fff22c3fa8db088dd4618d56b58574774402f6374bf8171410083a8b14840dfbcb4d666a6e4966ff13563c9d2e8c49bd66ed2da24f8a3e89de7cd2b68295e758422f056fa7e8df8a330e9a9694dfb4755a42d21b1cae8d07341f5caa53e7acf53ac1bc9de268f47d356530bc17557543bb1395c779e6852ad8b69ef55c6eeaf16826147a44cae8842f563fe3351f58eda593308d17b10b1a5870c814f2a305b4118a3c7566719c34ee8c1623392b309dcf6947e842e3d0f1eac84d5c9b70b31f10ceefab6c0a4fce65fc52029d7c4fdd27ea0cc63d393e6dbc341f5379410cd8d0f7647ceae0535e50f70405f0e8b50768e599b234c2dac691459dd7550ddd226c4fa68e495e5fdd24b3eba1c9a262840036d4d70f62a4d9718d3bcfcbd9c4e18a3dab16b02afc1a3e1103a4c50a08effd0d2267b623c157e1f253be0b67085bddab048f049b9bf9838a274e4bce8e693b9f3b30de952726d550919f8a458974d3fda1817918b50d0bbfd5fa572246fd6644d0c2be411d11e573d0bba22015cc8433e420d1f06342ba3de72ee174656c664807039a5ed00869c858bf8859dd7186c65fb9dce1d31fef91b8008b5c39e21e546c834a78be7d2a7f5f7619f64ad0a4ac7803969e64ad6bde5772f2029963e61f537ef61914dd95988b52af7ed01c313dc7159c160d6037d3522027a9c45a6212479ac67a8989b5ebfc28150f5097739ad5b751254b9fc5a45dec8adc710b0e117bb100d3613b0f46516e91ed351a17ff3c0167482f1dd5669c08c137b8955d2ac7d5157bb919450a003b887343e633cd806005beb042c1aeb6833686bc3d33fbc0551e0843fb1f966392e551f9b8375441e10495edadb58131b5c85c03a2a7416a4562762e6e7a0e8ceb87b31cb534fcf9b5597f52de3318a43d055c054a224740e334cda4c325f9416d8f21a56ef380ed1a4113895a5c14ab9347b5fbeb62b0e5848f7901b207e97b3fb6c33538bdc650a8afc2a482a85df7f8f452f894d53228168773045668044407d59f78fb0c830185d8f7610ba9e5261aa0499521d161d1c66f074d0950af2baa6474dffd9eb15a9bae5a0c71e74542d4023e558c69dcaabb1b88048794605c4668f5fa14a91e242ec33a4fbccde155c458d44368ed66af8dbe8709541e740cd6750b45af7835b4c6422e2dbddfb5f534eece9b1b6c228dc1bb13590b5066be3165f42fa20b1226c12567ade97b12965e97516a3998f46ef4b23ec78b206ce8a8c9aa72954b2648b5656c1a0efd43011c261dc81fb6c3fa87d102c190f24630d73432e012635c68dd619a2ffbe2b22e13be13fa6524d975d002017837bd0f6994c3ef52e317c963bd5903daf66c349aa79e3519ef710bacea27e0d7e6ab12b9dae1e908f097a877c3971d22a121d91b2af3c9db695cc0ea0d16d0ecc6619027e8b7f173e0f795b62d6856e3fc09847629adde84bdc84fb140b3971ac11004d032f5324641fc4e5805cfd69f944ec1fda9735158ffe4c708a5158110079928a4e561c0325492469109dfaa9011cbddaac04b106f7af371a8c129575269fadad8f90c43a16ffa8c5da2aede71d7ff9a16458aec966d260e4caa59a2238433b0c25798db632757d6185eb210090e91e2d458228dfc6169280ee49f6252bd983315355542cedf652c4d975f67ac08bf3f632e3d3d06d90d792aa1dd46d1cc90d121321cd83bc4aa004f7eb8203527c622cbde50cff5c5dc5ce41a3a6d93bc1c41"}, + {"0000000000000000000000000000000000000000000000000000000000000f5a", "0081dd9be2e0ab034c9a00848a7fc8e51d33b0f13937b7825e5c549d05d3a4d3d6bd6e3ffdc9c59485e50d15ea06f2211fe70ac755e96fb20fb9ece71297d230ef019faccf3423aca8e439b4ff1476401b5dcda20213c05d22d0455537425a9980f116c2ae8f56458b42af122624a8a465878bd6f2ecf2ce51e82bfcb4f32a203d6076afff25b787c626cf5714c27321fe82263824d7814619ba7714dc48caabd54c2e8ed5bb1fae02ebe90a72e6adc171b424245cc84b5b346a7acca85a45fc786c96e73f3cec7886176f090263ba94371221a2eac4a1af596de0ce2ae2e4687a1ece961a31dc28567a085395d0a5b04ad394b31cf305d7e1b4f5ec049914fa1d0b3f493842d6a666df128699dcfd909136c0b32e0f6ef62dfa82348ec9f45edbabbc3e875c08c511c29fdfb6a94f96a1023ac5beca2b6b92344830ddb76cd2947827afde346c82ebf7056f05ad1c4601e68571c00ce1046fd0e1a319ee7215899e302cf20ac5e36dd5a025e796a5f28530c84200d16a4d83e911baf0de205726bd734852da04bb9c3ed73b98743523792d7dad9b7441df791632b5cd2d35cfad6ef03208143c5f3ecf474aab456240eded187f72711ec20e0df2e882e61cb1ab02ae46f0be7f5b4a1bdfbebe1632b69e12e2a4ec5d3387c3878c5915b9c6bdd1129f46ec0e1dfe6edf69c2c3b8b76cce6b66b20ffb44e1086feec161ddc387a85af2bb1be9067eabaf3c42d81a692f8e1b46d1356496041a1633d7993a4a7f894a2512844dff28074dea48b27b19a9454d5d60d83bb77c9b8654ed6d780571dd199c4ced0dc315371aa9e30e094258f0decb4dd921923732a51b0de3839360de2d2635db4264e00ba2d934f5113a5f8b12e59fbcc1130daf306a8cf72f2bdb33e77c51b6ceb650be0d9c26db2cb150abe415641a32bf0827256bade1ddee5f031eda0ca5c28829d130a08be2dbaa7848ef74f15915bfa6a0c865b755fc580358de3525c1e32d1adf730375531f2d653391875592782bd1dfd20dc41899d51a607e1d1fdc6edeeefe441c3dd00f7e16add63dd6048c9dc47b837414eeaba1132509d4df7adb5e44e50896d2a9955781f2d194b1e82efd69f981cd53874805da25d75dff76d3fbcb41d6677c9f78bd0e9d04a75d4fe3c6435f6e3fa64f5a1ec45af2168a6c9d27d4040f894a160eefe5eb452781467ba1c24d48bbf5481af0b28ae0aefe37b7c9e4516a53a8c12156a925b809839bb9978728368f3031b7f72df312558ad3bcb70b4a186752ca1bcbf027d3ccb43ba10519fed169460f2185baa7149d637cbfd2c0a14a871f1bfb9c2a7e1cb2dc48f79f026b4792f7825073f8c75252de3c7d3816cb1e1edd565796a7568356e5e85ebc8d5dcd734e29bba9a0e75f6d63ebf78fc2690067a67f7dc50c052cb9ddf548fb56e612431a4eb0bea8df9771e2d41602c533a7d30c5f47d0a5f3213254adcd24da906747bd37df137116cff45cc61876e4be4b02c33a4f61595636bfd2687bb34cff36b570508a1747779e44770e2bb13568a8c40fea61a2362df2cd08ccb0345e7021bf1f01e05d71def10cc7dadc763b966260f660d3139f1179f9af3d0b9d660791a5cba4165e53db3e3715e1514be20d199ccce436347d4a306e0b7090649b05cb5cd9b65b1ecf781ff782b2f358ea16dff27b2a074e441fe0301a7fb4b95232ea275d5216eadd28a309634f251285f30bc60e1494deb686da4407f321643e1387c662ebfa8d78253480395f3515ba83f5bad412b935b285f29a5da37732db394bf6652fdb362f4a1714412aee0ba9c471551604c8baf6119a231b859f17464421d888756ef8b7c5de8860b476164f1e85395b806510cd34b47fd140095a065a931a6ed2d8f5cd"}, + {"0000000000000000000000000000000000000000000000000000000000001ca7", "018bbb465b2c7d279b5c006c91f192d26bbedb0b5f0fc5ff3c9b5f5e0d854427dec85c3362136b980f5a0ac03a46b645bc87a963b1eab32dcee5ba5337948f13926e35cbe1c579a9d5c1e64160a0a8a1d335583e0388f86c9edb595165b483ab2c7354fea1a0b8ff8f0464b3371ec419e150f471a805d785b0f1341781cb055ca0783408ae4bd11d509dc586fe04d1edcbdd4008481ab564a2c379c9d541598b2a508e24addd9389025404aaca0bdd3fa71c58c32ad8bcd232f85d449d0d1635d048d2a17396c52702eb38c4ca013a76978c262822065c58368cd69ef2cfc66e89b6c1c9d9102a28a9423bfa51fa31b617b464c86f38ed86d67371ab031099c50b723e0dbe46e0db92e3439a257d3f0a7129b189a5ded6ded1b90693a621b584b984d5f3dbbc13720262a6922a119bc112c44fdc3e4d25973587791714293a30d714b1fb402508a27924a1bdee1c2aba06e68e64141d98e9fc62715efdbc9d25bea73133850804dffef7205e97c45a3207e52d7dc991f65c4a684c5536456198c7615f46a84ea9522b925352f31a9e577feb965ba116496d440681545857fa7a9d5e90a5094b91ed7e1079dd8f74e09a6e96d88add89d9ec8f365aa642b59cf685b61893fc634f820d6e8cdd65db14458d7b1714a4dfdd10e66e8b4e5e8eccd0d98f112a15060c85cc3f0b2e8a44daeded2521822090de5b0adf3ccb3e8b6732f0a504994eb1cab6357e7b929d1cb5b1a94eb71237d4ca1204b023eb3498267d233e0e583904ff4744888aad663bff64766a4259b4fe361926d67db397fffccab056426cf567f5f198f785300b081bfbd9d602b2e87ea12f9f269725b8e57839374f537fe6f6de3abba272658e405f18d5bfe3905ce81657e5544799da65686f2586084d54929ff83951982f2485c56d4d6cd6a092032e29b19ce9047a39e6c301cfae9b98cce93114694175c954810e6cae1f883c065bc1c4e45c19f389069424f0360e86cf6afd5e02048365346411a1e4cbfe0410e7f1ff122c1ab4857f169d211520d02433c7abc37705b8ac854611928c310888a456f616cebf3f77f79187ffc5dae6c95991c015bbaa622a4e9c95b9e883c588cfd3cbc8505ef01c1e471d4071e3d093ad6ae4888ca9632989341bbcba3a519652016ff17d91bb168c6de72b29f50554edd0081b549499e77025621ed0b5521358ed1d6993faa923a16d3d7c13f31375cc13ad2b4cc6758b565ecd7c19443a447f93fe573fd7f23c10313616074e1a2d572bdcfe71d1d252faab664544e653638f01793c71dc094476efe24788cc89e9432fda4b60e52381dd2c1e3faf67a9a39a11e52bf6a70b4b74ddea2a87dd321c0ceec5695e040afd0fc4e2b164e73531b4533ddd5b43f3a2bbe0715085a2bbe58e50e6b489c570f8360f0238fff1f2c91c5d670cf1c367cbd130cf87197025250fa3f5bbca3ff5c65f63cc1834aff629a73d5b8f125832fa3221241f6c59493f93ee8e62a4ebdae2911b8edce4ba109fccab6c635182cf91e92c5ddcf43502fe06d0b5890838d431a0cf91d3f3fac2359a4f4013248111d15716c753da540358a75399ea22bda000038514e1e58f9b5d04233122575201d165e1de156f11e2b44d19192abb4c93c7181cf13626c454dc8deb025320e7e113225cbccca02566e13ef4f3d2dc83c703c973e5bb4743faecd0a629a44495a7c8f01e69501062a247fbc98ff33471a107e17ad17578926cbc811b2436d6671d469331e463116f98ffa54caf4ba6180a65d92f4233931fe06fa84edfc9a58280f47a713b1abaac49d28c5834e760e506b3c1aa3bc3aa3ec408130a5daa0f52af39996115648b52c2fb3dd37d11f04d465d7dca21f76b6abbfa8dc76087aef78258f27b"}, + {"0000000000000000000000000000000000000000000000000000000000000bc1", "004450e8399792037fed35c905efa3c21e38d52c6b1a9e1b7f36c9078cd3168225bf4a17ba006a1c33c105ac22792314370dbdda79509dde862661105dd0bc1734ad9f12df287bc4e251893becc8d9a7a0b5a8b202a1b7af30a845d1eec9741ae35dc7ef76a75fca9a0ec65dcb909e1435111711ec74fed6bafaefba5d270d786fb0cb60ca87a597b21c7dbbdcb515bb158d6d525f1fccef9ae98fe891d5392df1b3668547dcafad00ac04cb81655fa9546532a56adc1485330f51eba6398e2ecafaa3af693566e7dfa46a01c7296aba34550cbd71a81810deedaf1d66f2bb61cc86b89d3e602e29509ea7455a9b5efc58e44f7532763a219991ad6904ee19a63a61c4d1afc1943eff55ed4ed59579b4da0c02414b38863837ae0014ea4061373ee69f7bd6fe1f4a2445a3dda331d4fae383a5b7a10d118211cf4a27be2e0764df3bb96234d4f270a868c26d94774415023370acf062d8df19e9d7af3b65fd1ea6e53b9209296b434df2d7e69dd42e46b02964107e79a83a193402ab263fe89b9c1f5940e26678f667d933e4fba3741a05bf62ffbe4543f829592ff5697b330a30d8df2609d23bc50150404a8742316ad3b8b00d1a850d0d451ddd8bf5be989c03731db39d09dbfb0e6096fb9e580e883695be8cc12535dc0155a3ed4206208d154a9b1b7b4190f135a6bbed2e82a070e2fc7d2a976b68aa06d04f38d85b93adcde182bdd0d2d8fd565378a11d50fc27b26d5c2d73e7f668a1ea5702668900fb067712d2a7e0a4c7c60b68fa02affbfa2aaab58e1f13702fa397ac1adb4849d174c3990342619d869e9f8eb40e902975cd075e796a2a3add92f799af086a5fc14a2623ba6ed063f95db88106cf46c6a529cfe38f2f4816075c3000652327de28734c84fcb355b92bf0f5662bbdcdec0cd39d311ee4331545cbf685ea12ba057a00c9b9744f721c01d7ade055ef7566cf443b7b6cfb22524f88ac256bef59d7430efd312c38df0aebf20b29808d72609075c5ef231dbac4f8ddab7818dd915834aa7307c32e829d9f99c4447e591856cf2638447201c3aaa04c80fd7264ef10af5037226b8b7d9de7d84c24d44ea5939d79b72025514d5ebbc6f5d17f07a22ed6fa88b85dac7fcf6b9503fcc08a8a750f798d7c378f2f294bbd927fedb2643ad7e3864b14e89ba467014145e3b224f46d37c862e0d9ccb89aca68f81b7644d04c03c3a427efe9b507aa1b3ed58e43a29c569e0a45e2cbdfc6a3b47bee33bf265dedea7fb5dea2b8139020a22b1c7873a89b556e8be7043d95fbbdc5e60428dad7014baec5c505c521ef479091b60890713d1c71293659d7b8e0f91f03985db97a758edc799a801977768cdba3c5f12a17e1b7226a8862e17e5ed7172fbe0279ae6f994bd85bc499563f5617471e1a49750621a11e464620fd1f2af10a849fb0a066486426b11766899f7ef0cf979f3074da42b7df8d6671d5f7ec1b63737f6cd4418906acc2e3aab3892cf5572a59a425c8b7c6ea0eace8a597b60df034eab5b15714c01c0ca5264020f3638bc743e2124d9fa82497780cb70f2a44f7e8d8cc99c1066002d42c56e72eec8cd837f311df8f6a174fa83ae245e2397cf7f4a8ee84cfda8a21d2071f4e5cb0c132b94c5b46ffa593bd817f62590687d979422367c9c057c895d64dfac2d957375d2c16f186588f928fcfd50a3283e3aa6aae7ca7783a7507606a3fe715dfaf71c028e0455ca1866e365e7dce08600ea80adf7aa5664481befea20a994b705db96e0693d7a2e85bdfadaddfd16322f05621dd8fd740bf1abb792df20f3d24e3e3e309596550cf0716ddb2ec159c219a71d22d53ecca729c0d62fd34b2519a7d081767873ac5e5a5b9e7b3524dbf39a810ab4df4d044"}, + {"0000000000000000000000000000000000000000000000000000000000002463", "011fe9bc62c35e571b70d8e6156662d3977edd9c6908d716a2f024c50f3a17416e5352b6b647827951db087e2c820307836c956e53e44e6c5ebe07a7f97c9b57ed4fefa85ace10d918c58db34a9039979d8fc68402399beca0aacb415cebe67c7cc1e45ac26bf63bc60837dc6c6fb132df9c5214b2d6d8038a13197e5fb90e16b5f2c99e364d026e243a42c45406a8115846e438294fa86f18db2fc2cd3bd3db65e00f1ecbdf23f3056e7094fd53bd63064799d24df66702ba03db5a90400a5ed7c81273b5cd7d8a39196a5167270bbb70e016888a83ea2329714d92a2a0f7192605ba24f3ddfd1aa8dc830967d769da99943e4bb3cab1700bedd9530cb1a88ecb4b99bdc01cb4e53d75a3ae2f8bd40dfe1823cdf4f1466e8dc95c44d35672fd49e4e0fc47cb0ccc007931c4828786264464ffe85877dd9f7f88a011be5754d79a027747c847258071cb024e9a566a79016b58ea58047a2f507c2274f034debd7d19cfc107175661aa6d871655b95574b3c0baf1aada84fb88a301b0a4a69655ac035f682920566486deba5b5f9d221771b0d2ca6fae19e8f1a40a57aabd1a0925d9af410818a516a2a4aec1c40744a78a2d2865efb8fa40673f49ea91f3319f79a47f44f78a6416930fc59c074840bcbdf6b8e0d4cf72c028b3dce4b9aea782ba2a6442842d16791bd0fedeab249c0f6519e3583bfb6e2f063c77bde9c4d4c4bc81c157113f95f6bc917e1faa11538e09391cd92f54703307b9f461c4f63a5c94773bb3376fe02a52affa58470da36d34ade11dde697149b574ea4b94128b1d1725340d3cc4617af47e61bd08162e78fd30fe29cd64639cceb0f521322bb0349b14d53add6b47b161fd3cb2f2d0fece01b71c90247f0dd91da60b879521094a362ce0daccae3fed16277f1c5962b1a5136eaceb7ee2131039c3d70561bb430001b724ea96932162f54920770aa0982109a111cbe13a478694199a3f1ffe746e3eb176b1e7b5bc7edb1507b99a57fd07b1727af34376945187dd6fd85584e41a8f830e2a75ea29ff53a49b46684c6e2d945901a60708a5971b846871c8bef0ce37f41ddc583a6e57cc25e2374c989b42fda99cea23d1e5c83f17b17c401415439540d9857694712a94e47734a4dd8028bc09fa2410dd7ea111eabaee6ce6d6a6f641428e341fb9fc09ab158aef08e2584d9235fd14d855fb39d93b1dc5171128cfffd11b4fbb460386ff4b9071cb926ef733209933a8dc50497eb26c328e947ce4ee2974bfa2ca3e5cfbc6cc263a5f7844d58376e952fb30d49d92b209f1cba737c4516abcb468684d7845ce4aa9b96459137f7dd1df2a8a3581f56b2972e33b3afb01b97d6b1133c4a6031df831e65c15f35f41864e9e66fe3d173c3f36b21fd292d8ef82845943cda1c2d8f2fe489b02a7516d88d4e139843f07e9bcdad45e8b75d5bd280d7511c690d681f5125f9455cc6aa2564a6c7fd62210d391f99be88ca58b6ef772aee490a2d39fd8fcb31ba7a1df74347d79c64241e493bf1fb21bd158ff2f02c71463efd424dd8b7503841bcd23a20fda5c4032037ff93329bc5511e8c5ad0369fb02e34e28bd04e9121dd774a41b91a594c0c3c773f2dc35fd28df5591554c137795e248cfd368e588167b91039fa35fdd9a05ab0f64e249c7479a8935e09d791936afd858271c303a7a00289c2e96fb19d351576aed59370e8cdd2606b820fa88936a87b132e10a232419d1d91c706a32222c06670891d3d15246c300694216aa6da7dcab8210ee67a1ba218d17245e112825899236e6957981e9262a86f1dbd6ffdfbc3dcad992dd1b8314269ddcab1a2555ecef9d73f16c8a6665735f9421c9853ede1c2228f26c5e4905a0a6285230581ae4d8bf0a31d3bb"}, + {"0000000000000000000000000000000000000000000000000000000000001247", "00d9f8926165d90d59f842aa762eec20afe572224d40aae70f81eac8fff933997516d05a167286fcfa571c77cffd5a16286f1ab3574698c89eae18f45d96c242a325860ba39713ac73e549a6bc1e23a8141ffcc9043bc596d385f7f28296b05b656d73c44736b707610fb61fd6ebd52feb755801c141d7736db5695a9dff095b92f2897074fbce157484c2d4f3f1346111c3ce45f9de9fcab1370f8ec0462348de6f89f461103a8009dca2efe3ddc5ebb27921ec6f7786453dbc89ee4d1ff011da43c89d092405558aa070cf02b62ade8b32280554734e1d203fb568c3552c626b59142fdcec592e64a6f09c573855b3230577f451103b5c833bcf2e11540d2f472918579534a33297fc60bb5f70be0f6717707b0bd6b9031bf34022f7397484ce47cddc11ad126c546fdd05b0183fea23d22afdc5f108784db20b1aa424f89657fcfde64ce27007391e10b4ebb31bb70206faa8b709221b8674272ec2ff05bb494d9f0546190ef3d682942591a02972b52f1646d3c77dfe97e817d61358f0176c1995c8c3100b2f0a8df04872883e7c7a2fa0b16393f755d9c956d84fc756ed8a5d091e02f5474c2e72c165d4025315cfb2ca4a72b87a660a11e0bf47ef9f4697f12bb13da664cafc9b07f4b5c035a5aaad6ded6a3bab4ef44e814d69929a033ce14b4a19ab9ee993bb23b9a0c5e0c8747b6f83545dd606031b3a11e61e6227e6e6e65a8ab663d2c9617e2f1823568c58648ebf0be2d652a85428bfe5070caf6b8812a54bb9b51d014b9ee9a3e29254f5c9243f9bf022343b81c401a17cf35ba529e5e86eb7db968a5f043c08850e32bb5bc8b1a5744639d8fac8f9bb95b684610898b13f4b5594d0e857b3d98dc915ad1b06b4595b126f4b2ced1af4df4fa721b2a00f5b3090c9eff0c92f48e5ddc95c09a34b59c53fcfb5e7b19cf1efcf8601e58121fc18cc19260eb880cd6306ae482bb6402d04d4724a5ffe27b9f7b131e6fee5d2c915564a28632996637e3263656bbdeaf823bceb8eb33f6a5cbcb638b60b2d86a3073537e957a77f72e92f2678dcf6aa0db2793e583586fff2b858376174642640c6b49adc17635c6dd44f87cfde15f3f1adca9f2a3ed85fcd813865a3d3a655f5a7ed84a5e0fadc1e76c727bab2f372704e3b96fc2b43f100a8722ccb051a3cb6f2640e0364b0bd46db9e393eeef07c58dc7fe1c07ed669381cadcefc2ad88158fad653951d6de38d2bb6b4be5303650dce6d862973f927b413bf5ebf2d91a132c15e2a7a5f64fbd3a645114773baa7cd26967f77992a68037d9c03700cb668cea553f86aba392b2597baee9832814a89cdf6de65edc10480b5f2e69d3b88f2a2910c6eb8b474565ca8dfb6c27db948240a9982f9593124661d3539e3f5edca34c2e35244cd0762badcf356021d657e8356b82b3cf973483052afcf3fcdbb072e03b46f8c48cfab14dfe1d512d1de438daa2b36acfe029ea5e6c29be7494bcfa23ff728d47204019297860e996d869891ede19390c66932eab4d23cbdfe2c93048458423c4547538c044171ac2a9738f913346dac1337e48d7550c8b55c8377d71962b6664dcfb9b2f20c42fcd4cf03fa30295911e33cdff7ce0666d6bc023d60674ebd8f60891eb5aad46a5d7b8f509bbe7f870309d1be8a168e0755e7c4bf11a64881538b53099e25ebe4d801ac5cefd3c1d2d444a9e73a5018540a440d8df44dbc3171edbff99284eb55c43caa1dd00e1f22cfd1f3b114024edd18d50dc1316fba04fa32f680059358debd94e2f7005d92ecb33319aaced43e2ea50a5c8f820e94095cbe51e19d44d58fc56658ac11000f2af5b1a0d895112f2a619903f91c64d9d1f85f3b110186f3bb06a0b34c824677bcd53a87af555ed997"}, + {"00000000000000000000000000000000000000000000000000000000000005bb", "001ac390930ab7f47acf242ec04f4911472a1e5560077ab1761ccf16e38e7c02e8e41ecad5434f54fa1c16df6d2f4d6b7e536226a4176d3c9b99c00fdd6cbe3c556bff6f980688fb7a985dda5766d2887a5dab3d0103cae41f102a8ca6949476ef713009f184511c7926717f6fcb58f8e1feefe3c4eef94f49ae89b9b7740e7ff0c9479df179a1067144ba11620cc53b482cb44b82248a041e2fa1336398f037cde886703b9b9b940400a5298b5c62e3fb96d522f5d6340e3eddfcc9374272969090d7b315be45664ee8c03f69f20896f18b105b22b414b37aebad77515f13b3dc950784915228117007617c91a377b3bfa55d3bd0738ecfa297f1d009e1061269cbc195c27b30dd7b401d6f26301bd8a42dd83a790294f539141b149e84659ad9594ad4c70010707ff5019a867735e8b14782b0bcbb334a1ff6bb21d422c1a4a5a5a75fd6a2b16be2f538e569a7545300807ca1b61a328fe527879aaffb3f6a6c98fd0a462e70128ffc26600150cee5d2fa5489b6f7f05f7a831c742749770f34df529313209ac4ddd1f2865a114c45b026c780d28cafd7dba619785105cb0166dd7f3f0eb90cdfae5204319e5ca7b664cf128a809e793b6a19c29d4ef5d74440c9e46b6a37ebdec6e320bb48a21650abe506252c3f9fc9544144f398d912374df3544dcf6bce18593862dbf236f546bc2b22e1c51ef6dd04b5b2ad1890cbeabc1a4129f432abecc1c887ae6f08a693ef72465a1dcc913172f8bc04e943abda415e1890392806200a7f67d5550e7871b7ce0fc170f8a619a922a013efdc93cd5ce56f446c9859926dd2edc206304e98060fe1796945f093341b01907ab5fd396d500794cc14e1cc01734ffa9bb2f65503665c9b9ae924d4223fb6d08745670bd86afa5917fe8b03f4f9ff4d4a6306b49a93997cf9a5f574d643170cd8fcc6de00f0523292edfa2dd78e813662465a61ffdefdf337142396c6f5d33da5dcc6154859b808433cf69e9025079c8b96266d2073bffdd12685f48cf9842a11c2e21df9f61b43e65143faa7aa593b62f75326acbe469403120ab2c90843e0471243a1077c84637e8b1c2fbb50aab37af398791d2d8605a33566921f22c87e5cb6157fb290daf2669bed6815b2cc7f0eb9e130ff21ce3062aee1d2e642af55aec81c2b5fb36a638bd9b75114137f2bb3d64c6bc36cea53a17b749748137f256d1f34aaf248ccdbe4731733329fd5ad0254fefa25091db48dad448bace3ba4e75b991e745afaf7ebf3af230182b83bc9f579fb4677393e94a3859ee3cd13e9720ee95ba2874db2fb3a4b22ce81b09ca7ed03fb43a238843eb990bb75b0ab9237ad2cebfd8ea1cb26682273eeb546e0e3503ae10941d8d513c31310acd33982fdbad57b7f3cc55aa35fc758479fb63b63b7f3fb00256badef4ccdbead01871048c2728215465afc370174cbab55a8f6a6d454a33e5cfbdf09211b5dca3850739bfc202b4373fcdfd91d244202bfd3731d2a67a08f3f467381c7f3ee95fd61114db1f41ab3432bdba03f5ba1833ef6007ed8e411808a7c7b512e65c4b9607cfec18ea243bcf7de8f3cf0ffb152d21773948592b141180c662388d4f72643f6f6f541aa71cb9bb8441e0a4fe0b53c6b9bf2a0496d2acac6952c3f451f2054ac5639542948944c312db53a92dccd7b15b80f6338dfbe85d617b5b2add87d7df7fd0b69d787d24d6126d79d533accb3beef8e6787741dedb7fdefe24e82d38ec8b394fb1bdf66c476649f54f05e39f1c0a970acc9fc2ff6330bd8028710b90bb430df6f49bc02a35775d27ade703c76a95e61f1db4045dd6c53f79ef13848eb20ab0fc3fcc9f33588528c05afa2abf59cb69ef1c7c3f5bae9eeba017823edd6959f63fbfef1c"}, + {"0000000000000000000000000000000000000000000000000000000000000ebb", "00acc80df3df6ab75aaca389d1c9804cf85cd3d09b01c202bb8551b1ddd46f6268b3f5475df3a311ec8c12c293e5061f4755c047ca3803f0a87ec82a98cf824122bc15952e0227e32965bd614b7f0191499fbf44046c9e9f558b849b90e7b7033bf9c84b106afbd32412873a5da595f92128b296f5d1eae88dea0b58612b26c05d8915976758c01a061a28bf1c81e3615489352707c26895699a0551d437c0ecfc819e4840fb522c04ce95a0390c1639f24431e4cdf949af9bd61dea182773a2d01414404985beb65f363d38cf22d45c4d5110ac5d0e3a94933dc354b2985ffc4da26ad475f6203031dc234ba62bfd46c9f3dbb9b95292b914d7a9220666d9e53c053358f45792dd884efd6e6a7a9831c547347c7099b314b3fce194bcaa66aec755237e78d72604044c7ee0cdd7f5e17371b1d1e1e8dfcb2e61c581a105eaf069e61d9d7fc8a00ee96f2787d9dc97b603ec0c3482891d9910dd72c26542fba4f6413c7e520855739b42e912eb7d74bbb0c97883ab555c1f7c4d082284b22446185ed92f52c26a722f6efd4558cc39240da45f0562b40bf2b034ff34ca770af5d89ab819053e886adc0acb2a572cc56079e92151cd1efdc8d0155917cf1a7931dff4a0946fa7d9f9331ddc5fefe410e7a6cbc58b3472e703ec79676d632f3fedfd141614a510af84ab79ef9d2a81cd53ad0eb950db908c1e0b7d964e6b5ffb8badaa23dd29ea4aa220bc3ad4b7103eba597576327bf24f3514d9c2b30188086e31bd12726c6f085462ace282e3faf0f47c6b622ebef4b2300f529a77d47401d699748b3fe4a03a3f8133f5f015956c65f1d587d5bf2361d523b512e8cf7333dcc01aa85190906f391db37d71e7451c4be2d0d916f7343909d348d4a15cf7be5b34b1445a5925ae30b01d683fa644849674b2c1d78ce7bed3f699f36a251f3d4f00f9822690169c8f088a4059409f5130784005b5d51a780647ba0ee4ecf1ef057c2dde7f5e260db9386c1d5679ce211fec33dcd2d37118b304c54a98b875ed38a65d5a7970b10bc994156fe555de1de1c7b2573b0699e60a82f1232990a9b1dd3ace2f0de8bfd85738506184892cd9fcc94774281eafd50ddf80a7dc4715075f734e0bdd8aeb513ed29decb9ad0b3c089a161807da806aa14e1c2aac8422fbdc37ce8900db1131eb042e34a6f192b7b53184b152a929c328b946f9925c2f051b2e959451fdf5e699e4665e9102a37e9f4b4c0c5f547bf9d9cabff3059262c1a023f61a9af36e3b1f6121d2bacc199e648e6662533c171a05baf37f690b353b435959763535d9c4efc971935b373edd80af640c9e03c3a00f815368a6d09a5c8dfa2841bea9281d54ba85ac498a5daf524594d57b144a06285960531e562a5da61630497cb704afc6f778dd59590bb9f903fcc38623c23310ddd506f22f71dd69f3b1972df123fdf2da6ed74f251263a5860450bf0de37cd601f90861d3c02eaf4f7fc13021de0628b834ac9b2723ca177e993c5636ada9e5518382c3387bb549bcd8d8460ec1bc835fd80e2acac0ba2392e41f42ef645c45cc31bc63b7886e9a13a83beaafa3dfa746c1fc19bedd2577bbd05ccf246f3e4356b2943ded55c5f25279ac4945aeb350aed435af3ba8547552c68670defb59100af8cd1e2be32dcf8ae3c821924cc09f5b93bcb0304ee7a2c1bad8fae2cccbf5c947d3ed4578bffd80121464e33fdacee2a97c5f58511aff67a2654cf9829d14ea5ace1685e4f6968ed32cdf28eb7a08a39936610c9b8bcef04e8180ede30149fb3e6a8180fb1501f06c29667ec22c68b3d5d279c9d6fe8b0f6a1cdf2b7c110d388c98c56f5ac449e23e0e3013f68044389d2512da8557b907f294f47a3326b1625e524040be6960"}, + {"000000000000000000000000000000000000000000000000000000000000159f", "004c6cb4d71465ccb24f4228ef9c0914b3efd2e2972635f932406cc7f5c558c7c832f30aca7ac5f5b76b1a8f63c3ccd640f1c2c6e3051328b9d5ab4e30b5a033f183bb080d1943136179754c52fe8b42077ee18d052cd3d3b9d537b5cfeed3f3c069e966991016c3b8201f09e81815ac91e557c60d3be1538e3477b56beb1636ad0b5c4643d0cbd438e92571182771063d6d5120e5c4689e0ecaf753aa527bac202ab1880699d14a0068cb730310ffb3c8d2e2bae94f9f0943d416495f1100199b535ffa750a8f6191b0e368bddbc5d1368908c07069b8848f9cead9b72cc0c213b1d0ed5827f773181d6b585cece5a33748925761c4ee7ddf78979110bb1b88d758661331e3e428c621e8198c79d2992a2836df40e6d31068e7c644924aa6e7fd50a0dacadc236ba79171d9f821c9f444edaf483485ec55b2473444526fb00d7c22ebf8dc048478397dfdfaea91c6e102e8d8ba8c64b58d7b2e3046d4ec2a3a45f2fa00d2429944de031d9b9d26f535270ad35131afc631fbbc03d06638b34b7d533e98c9cce355b7b6b51f390d8a1405fbf53547911dbae625146667af8a9bb258ae56041a36b0d50eab75debbc60265bc7953053c7a07ae0b2b2140760ec2497c7b45eedf662d558a755d3b1d05a2691829138564a4f71645c855713663d79613ff2d5e82d6cf53002b54c683e660aa706b92d99edced04e72670b8d449f73399d1b529db3ca1786efb14461f4bdb8b599e90bd5f9f42f43a49762583b79763f71a9c72a45b0ffcd084087207d84e8e24a6d64cf9ef2069ee5e18b3eb57dc4c7926585437373e8e5c2f9e0a9d3c69e548ffe28110e2e319ef91ad65c45361550aefc27f23b80df5f0ee13f3acc31c1ed68b58766327568ee0dbaaccd9639df3280f6ab232ac18be416d391d0f1f039bbc2931eed4db246aefddb27a3eff3d006690e49fc57eb076a9d3768eff3ae5b38c51625119b20199ee59162aceb5a1c758624b94e5a9bc711504cc4ad940440136958ae2ddf73bf03da892db2bd235e065f30fe58599de23e9b41fe7fb72be0eff78f00290ea95008d1ddd2babf4489c588621c9263727bb1eb4ab5055c8ed198bab72dcd4fda463506f1db4862e156da711a0c7a128909308d6a3e79dbe29168eea32c0e9a6700d581d032069f60b6abecb63373d8ac0012a43ec654fbda7e4a4c0251983b644840aabb64f0c9e0604dc5949ad2435f4a4455d4b7d35709cef650e8e79ab9e5450cd3b97e26d55efeca219ef731ec415cb6e1853ef625baa4462682359173175aad247c6041111accc534a3f9aa010a96e2728319719af6e732e2fb350a9115f530a4ae89a4bef504b492b7e13060464f557e790dfbacc99f46c6bac28b9d250906466065c11e37f183b52eaef314e20b633c16fa7b76afa01d2ce9379d054e16e4a21a7666923c5a191f7a23622bc19c7c4f65681ba55d35e547fad4583a614327c070400a2eca6dc038c59219873616574f13e3c188125e53cfded90d9756f3c03c0f6d4bb952e93f34170056bd2f2dfe9cc6ba41cb2a7535994a11326160b152048e9e3dd12cee3dc2e7961aa5aa65f0d093c1bdd0d0c064784d9a8f1332a59215061727ea27aff230647473d6044d5d3e6ed40969c94e7794660119ab0ea01ef9d0d5786e8db6603516a6aaa786a8b439a24a30ec11bc28247cfefccce234384780c0a0efa14b04f1027b97c23eece6bb51ae40499ad25c9552c2dc050107d857ae4647409e8e051c8b661bc1e260551f1580ce0d7187dc6cd968f9411fc55148f160c2351757e0d979597ce6a29475b8186dd16d1c2979227fd1f0013c4f4f5fba24ef33429d9756ae82d8f605a1f299e5efebe8de562aca1487db648ed7371d5e42e9d27b0"}, + {"0000000000000000000000000000000000000000000000000000000000000158", "001c93009f8bea13690e44cd634301914c568c720504cb4dd2940e05df7c715387076700d8e4ccdb88080ae0f27f0a6402532264320c597ce6c377e47cf15b0e79774c53cc9cc52ecae16cce3da43ef444fb6eae04506dc0741700573deab0c367c3e3e935b175fbbb1857e3803a24e005714821a342189b6d97ee7fe2821061cae7fd509681c8e8a6d6d3bb04af3079bfd3973539ac992216caf7809ca5478866649221d012a4fe010841dcacd822154ebb77f948ca7d4e45623b790522fd4ca4b90f9f41e814d2e00920a9368e899c4acd0c5aa6201acc973b444be2abee44d968fff81440642dfc7523bf9ae8a57b48e64110c890d5dec53ad2940d28690eb3f01975829015cf55f7f501de4f3488584d92da6cb0b19ddfab35f611e06481418c92db545b36566780ce9cd3e5e9eaa98d5ed00c668c2e7e51e96d7097c40de598713db776ec4cbecf7e9898fb08da0479a2e96152f29be672426345ca756d64af13477f29aac6d8204ca3590c3883e8fd5d60022063b74c6f06fef7b1b388ecbe7acfa576f43880bd6694b41e9a1545639003170985842318ce6bed782b5dae5e654e06a1e03dbdd7b1e1dca904d8182778b22d9dd9d3dc089c85edfec96683bec572a080e3c6e5904577dfa00e559ce9a0cc85b4e26921745f98fd6ce5f08c792a23416a8829dd14751ae6266eac67ed5f45413b65fb0671719128db3a1f1cbcb0fecd7dc3813dde6b29ce162d9c6f994ea679830c230e54ccf58f6674db43dd0b7b6b30505ca4eb4427767885e6590a316efaf16b2ed172a7085b16c74013d4e8b2d2321200de76fb6d11346f30266b84c190b681325a5f97e4736cc4afd81cfd1b1f999b9355c122c448e033adca410496901e161f2346c9c7704b5efe11dd1c53c16243e8bdcfee2285493160ef085facbd2349516f947226153dd52b00b7a4aa8f0983df184884deb9510639d0b23bc55f5a29d372ee98bad2e574e5edd34f27f6643974b467011029f151d850dd4ce6f1cd714f7b799dcfd4af982eae873c579794275762831698a945e57ae6dfd5370101cab4eee3662b5c64b028d4fbdb46b3f3ba3c1d61c9c769e99f8fbb4bd03675ff43a06a854d1f516314b412fb38f253a7a95c167b10d08f7e19d53a1c473de7a2cd246fc899cd6f345987f25945424affd7ac0c04f761d9915fde9754739edff6e71678f21c433d25498f5195b5218de3dd23e370b7a4fd64221fe85720af59a5e725144ba8ff05735b7f47c57538af672b422eeff0ba719367a2931ac36f62cebb58655d38d01cab24af0a1b257aed0ba60b886cf6ee30d05dfd492f29ccff5020ef79636a76b4ccdad03f1cf4db811b4290122163a0723dbccfd51086f39fae3143798295459bcd2977946d3de0210622cebca52e36943a9c28029490e07199b614d00673a6f9fdc36aa35ef9b73a0970d4fafacea3f48893c677e4d90f6638715d839d2c918dc0f89353fb6be2f7fa39bfe19a66bdbeb3b549fae6b2a29932712265984bfdf882b63438d4aa0f05f947c984eb9a47ee4d25fc214fcfc3211ebdb7e111a4ee4dde1e052b5c9d6621abe0b866dbe0385bed079fa914a0eee831ce2522d026b606851f8aeffef827e0b7aca6141b60c75f666c43d8b28e4f7d94a835039717d5c04af924d5f2d29471a91c9d23476c25e02c13599773298a71b617a2c56db97151334e8a06224979cd8ab3a60ac1479ac5a5a5f37e4d76f65b73165b22cfd6149766134e06aad6236eedfaf43f785b26242e8e8b661bcf8d00ae045e0f3af569e2acb4c4aa3c242bab53b8ac39fa0596df8574fe828892572ef8273e8f90474e1b6108a0e42185d04522120ad8517f31dbcf2485da1f211a232371389cb45f272b7eaba5"}, + {"0000000000000000000000000000000000000000000000000000000000000606", "0038adfe05454b9b32bde2b987b84eaa2b67f404a929cdceaba42338316a7053890c41637962dff6779a092d487520885f9484eec256caaef9e0d9c1fcba58511e8e79831970ef3b86469b6e728516f825988c3d0373fcf4360bfe86dc3345240cdc51138ca67fe6b60810e8c5664d09991d86a0f7962672610a25c93c8b1b16655e138ff9dcd621c52f7cead36279ccde199f2814afd8b98a30d98e8f79b0eacec1eb255afe49fc026a87d136936811ea0e7203135c2b85292a09b7730940b4a1252a0685b6143500352bcaa6f9ae78f77618aeb5f2e6a31055b7fcf3c0acec42d25a011d168f50397ac8a7df1141bf52f6bf3bd52a79f5987593640c3325a9f4d4a0db584e146a4e44da3945305b3eaa373253b53fe19cdd66a64902a0f961171dc75aa34b2e5aa5dfaf26a1b1844fd327a299b2a2f2c858ca1a31eba5613113b6f7f6a24409df3d8efa2bdaff945b00be977a889c3a9f748fd09e7b33ad80ffdbb61ffa107186e5bf09b33882ecc46e9f56a1ce0d5e78610604cad340b0d16af112b4019afafa4219192a7cf418219016e52695799dd49fb68cc1e6e799eebb502a66049d4ff3e20f5261a45cc7411f7b54ba7139b68ca30d85c5e822de11cb02d2a1b4cd37de192ace990fe70d8064123b9f3281fa53374f9265d55a612436b86c1f994f272f7418f5e5151256bac234eea6c1ba1e7f0c073cfafb3400b5a2be12b39362d010d8e9cad26727c3825a4d8a4beae68df31ae242c3d99003f7de923415e7885d1ab0a550f8e6de4dc76ad75696be78ba552e431bf6a1c2ad46e635f6a9cf3515a27ace66400f75fba5235c9b6351b04152048e37fcc6fb6a5a4640d3c5cfdad4ad6ba55014a5b9c62b19eab493e12c0f84c5b086610e47987f16b583422e3e1c803649b91593ba53626a0b3be8e677697553cba5f0d5dd774500c4f323b2939853b05f323269c8e1bd942bda22e60ae08e9e85b12407c2b63508173d59df5c145e79fd1f46752b94d7db60e05da3d0465946a6fc087d19ea328976de1bf562bdeb9af6b58539d451d2b971209305706b28d2092f40afb180e427d248ba31c036bd770729239580c9bf6747e120e126a3e315709e6d54670b99945127c822809e611178a49760ad941f74ca775312bbe91f585baf075238d32b4758aa83423671c201fb7f623e4c2c06e65cc5897dd53a8a786f58dd66060f293743aec6ad8d3f0229a7f20c3a7070593ec20327c7db38a61bc1d84f709dddb6cda82c100cf713415f7a5863e27d355d8c590555d0c8e2548dd3346308ac55091f4a58f75166633973642faa23bedc03ac1427f8b0fec9c7852659d35e3ae9957f9615fcb2f90bffb754c4eed927f642311602a0896c91fda519170d9af22e569b630b19bc039cbcb0ac55203677a4bc02df3e4e37d936e5cc6941ce49e2f83aac733f423d175a4584544ca8bce2ef74c5cde453755da4d4a64f257c9dd1379a5e5faab26724676a5bbe5e6afaec345b66558a6be02527678546c60143e5d64296193231094a096e011b6597993c60d439c8f6eb3d825b8ee8176dc625580a633b0db133e870cb35769625b6d85636806bb60c2231451cd656988167152e745693c30460b97d6d1fdfd5b149eaa6abce72d74e947476d68b04928069930f83e8a3bd418e9c39a4e8d6b607eb280ae89b759f71712bfa7915ad6fb8f899f77139b8f80c02bb301d0cd314a563b0fb11dcd359120ba9aa1142a8433f1853debeb1802a6eca725a27aa4e5ff21707ba93310c06dc02c552634d5d75ee69b37f3a7cc2180a64ec9e53da45a30b65963966ac32e645bdfe970928535ca4c93636bc59b0b6bdd6eb28869fda48282620aed0ea12a6d0be0c77a57ed2f1fa250f5c42a5"}, + {"00000000000000000000000000000000000000000000000000000000000004dd", "000229b5f56c140d9cce93f203ab56da28d85b8416067fcf6142a0acb1f38170c834bb4b763ae336393208b69c3faed40baf9ea951a6fae2ea82449ef8d8700d9c0c59825e2933e884811bb5ea95064355564f5a002bbd40f5ca75733d9a00ed8f594ae4c1ecfa245606ae7d04275e30698030c242e135c7a4cf3a885d0e0ad829b9b6960ad7af42a183ad61987f5d879b5bca2a30060b4ccfe85b7167753442c8618ddc821a9056001632bba8573f0fc5ad3475cf34bf4adef97c521112ac0b351489335d2ffdc2c009742520d75b594e651117240c1f571ca2e220c8c330d2635ad037f9653d2e4cf979dc684c4f98e899d0f2e3450ae2473eff4a006581abf591ef832fa4009e3f513809073752a97d022837d3c8085a26d9bc91b96119b030fcbbbe3e65084394dd498d29b56d6570ee44e5417873a25f8d2709eb169e8de22277b05490a437ca78e5bc6b79eb2101c7a6e13d1ac067ab6436c82f4423ae5cc75e1caf12a2c9da4f1a1aa11e20e3fdaf7d3e455115aaa3a709446e85c9ca86590dec9317a6b93fe0cdf9704fa219e41a0a65e6a9b9aaa9d2c8293e2a4a13b35716e00bd60b354e09f0f7d3aad140181c5c0b20747ae94716a45e11505cc1092f38922aa4e6a5dc9af8e742882e77b232be91a3353c2b65177d3c4d017c6e9a87fe3d7e735debd1d224a19ca61c1a5d5d77184219e63b02454b552dc0a2fd074b82c15ab141dcd5831c896b0fb122feafc787d6d89d3124631639722d611de99c02f48cae7e427b795851169f5159e496e160581d011b7ce5136bc7fbfef9651c58917739ab8ad75fcaa002738576fb27c01b5971e0681db816908c7e70ba003d20bdc541d08bc385ec0577b47d3f1a788ab5ef5510ae48d0aa2eba37b61d414c8af60b346f415c09524802b4eb3968384bce6b65423143776a8d94bac18a0040b94f62c1a1ccbc89b20336bcf08d9bc43826a8264dc6b8bb14b84f6fa633674460b356deacbe8ed1033e8b4a504f74ebfc101297a140b198edc92a5d17059cf3a5d1c62a30a02041b96093b4bce7deea7a130edc6a1e8f15f7e34863b2884351c404b5748bbed21109e515dad10ff99b26f5513058f2423573f5427e1456a1c2f207fb5563d1b36ed4d91fd4df73a88d615bd74ec51bb14c53a6cc8785c2bdeb62e06b1a8e4600d2dc349a968a31ced24053592f1c804e806eb3ba28b2accb725d252965edd9aaaf695256cc9cbf11b00a6470ef130f23b4adb530dd1d55445c55c23c66f70f9830960304c17b8c7ed3b018344c81693df1d46a0cefac4bc0074198f2aaa630863d6515ac471645dd2bff1a4b0633333da8065614cffd48558d710fac000e9f3ecb021f8c1bd944b3720e4244598fa1b5ed341c87c5b8fdd676c5c672a5633fcea06981758ff8f50048f7a18e4226dce5feb09ad6dc1310cdcb0c2564028c490c204b546c6a17d6671260870a4d469b91dd076adb89c19e56351903b2a8ce2d61aa0798f469b9149c6d5f99e5455bef79b680bd5b3f5fb069be3f3d0237a5f77406b6f3e1a1b24eb0e4c1ff6872fff7f51f2ee2c6860cf15b9482fb94ec6e462706beb9d65d147916ae6ddd38bf67f017bf97f98afb67c4dd3063202c3e42d55745278d48140fe9d7dc2ed7a8df5d3a0a4d6166e19e415593c5c538677d2ff5df54d3984010dbad82a2cd1eab5b9521555fc4ec4693ef17dd011b8ed7571f9ad777902ae34cbe68ff2323621eacd43f6a1cb52fe2dd8ffb6827e4127443cf20e05c32de11cf3b52b1856f3c7d66e12dd5665a9ab8193c731415a6f8fbb891bd0b354eb513563a125def22594c4e35c47215f7b70b3ffe34f8951e51607270b19b471038cae7f8ae4ff5ec803da7a08854cd7b4954dbbe88"}, + {"0000000000000000000000000000000000000000000000000000000000001190", "008e0a8d28735fb9cf5f448996d2ba76d7823f434f10d6a2cd14600b1d5deb743bfa24557210157f719505dbab16bb47fadbfbe4b20dc3cfc9ffa298fdccfb096b2ecf484fd30adeb3b6939d4cd4f33dbe7c65ee039aa58e7061e91b9643c16c0ea8eadf1119fedb1f0cc59fd6701f40dd04ad68a934e64d9a3b53f4aa3f2f4edaf01311c2c4ea5084278b472c9dbcb03e217e34dcf28f195c7b6d952595b81dc7a87fb7a13e15bb0406ea3744d5804fb73f280011dde222bd86d94b5e12ded672a5cbd51307c2e307b5d4b9e21ffbda2f4b0893da708f4c64c4997c526d34a6586e29837d843a1699441552d524efee90e8279763f72b027e59a87a15fd01adfae31d87b13ba75def47c8a6c2ae764d2f1a820146de0d779bf0433304bfaa66656165ba62ee2216ce7fae3c698bff1704391af5a42d51f39906254d2b2f26611e72ebac3bd5f2cdf85d53414ddec2cd037bc91dfe8ff0572ac7e8a5b4ffb7fe4311dec88d07e997b01c1feda17d67f08bd57ad8b08b66ae88b203f3e9579189d20ec1bf5124ee7caabdd9ccd6bd56141539b2b5087ebd08c8a3c1dd7a27bd583c6dae900777fd64f4b8e9ade68c05bce7c6221ba0b85ddc9e2b660da1e75869d580a3f336a56eeb77c5c19fc26b0c73dccf9218c7f55831d1e2a94cc7f9922331d22e1978bcba34d06b91d356a5c60734d89de3cc9e48380b4f299f0493e1d52240d801e67b4ad61e9c966d6c46a6b38ef4ab6115ce7db5023a339e457c816d32e12b8e03d2fad1b88b41fad7810245162ee6c4fc6ccf45ee6f880c954af7d357280f29c1c912c0a99d4fa410a66c7be31fc81530fbe5c35ad9f276c6e9170d8137976e73f3a1c885ea7d7466efd47cb19decb9181d1468cbae0432d915a5a7e7327f4ca16b0d335fd7f11a2e256c59d487679040d5b6843a416590e9583d2202c5b61c3588b4f2e68dc49bc6c80df678b41c80926f793e42225d156d81e22902e777596a67eb38aed60308f7791d21d02d4670e4afdce1ac3d38c5f6056e188cb10003dbd4a949aef1adb5e0549d79c3faf719143cef9a99972df9394e73aa91c3ca9993a0f4fc571cf04bcbd2cc3bb6cf5ee4d0c3c8936d496e5aca6c28503eaef65c16d1d8f8e2f0837f9928e2e45ec3663a54e451338f5d3beb9f7506b3b04e6588dd1ad7660458bf3cd7d69fb0ce1cd26bb85bacde9c1137bf510b6bf0bbc2caeff8acf9f3d38f61d74aae619af9450af04aae0873fff9b0b7519855cc9591d0d518f70a19a6594d478e60d5178494e547d034c7904abef270055792242dcaef3a7acbd1a9d76ba2c3a40e9f9a740fb4bf9de6c402d7bcfeb202e37c5809dc8b1a0cdb0959ca22c88b9329bf7dc2e435c0d1cdc3fab01b9211f088d01cd5bb91cb06217ba995ad3d0e03793c1903e64b43df12c4337148c067749636554428cbdd0b203a5f0fcf38aae1d83f562c8bf37e99e1500f18860974aa731d54f952f35f52716248b7b9c8ddf02ef51d8da60aaa78e4fbd64512d752c20489d7e93bbdf10ca5adbe825efd1f1e60356ed3ee16464ccc9df6951eb12720144831c9713f45c530f805557d873ca94612e6e99c161d2ef31221e1524d414f7b06e89acbf5216bee10e70c715f740b85ed8bdf15b6181236af6e0e9a7dcf33974ee922fe5682e0c87ef2b06df73095320c82364e28fa53c67bc6cbc9573fe6347bdb230310a221d648dd717fbe88026a52561f77032e9cc73b271c1ddc75e626155116c2c01ea4e1ed232c5e5a451056d10cfc13c4454efeb6fdd141162e19d7f274782c45fdc70e16e7bb3a784390e3f71052ab291aa5d2112501db51250917891e58e283d78bff3fbbbc7c4112b29e8ec9fe3ee3fbb091f456711d5192bcd9cea5"}, + {"000000000000000000000000000000000000000000000000000000000000130b", "017acafe3934c0f3b2595a9f9e71c84eeda3dbc2851f9fa4f3f91b641940d8d2522723f90642b93f56481fb42edb33d63983b630d21f04a33c1102be9b7b8829c32739f8d6ee22d1afa394fc414321746cb7b58d0b419c7d33a02db75efbf54eca5f7a33307d5a7b570eb455a34ab3a901e11f21ec8f9db329a1b29e7d370e56fbdb418dba8363ccc10dea501a2ed0825a4b8854fe55cf8499d1f8de6aaba0a4fffc335b43dd981e02af1c719e0e01bf236e52704f5db678d24fb8c17628abfa82bc1249b4d4401409a1decb3ac891dc9ba539d9776a5392b7b7eb10387b786921f2534b3ca2fd3db8f2ac07d4f77974d165c6dbf59379b9b039628c0376b0b42e6e4f41f2cdd3084cc0d3f5f85bf2191f0a4337386326cf9bda72d1c800ffc3c649447727621a30ed8796e085af0de481ccc2ca6bfcd7c9f44cbf287655763ecf5ff3b1e835f77beb4ff19a319a1acc020fe9ef526da61de2efb0df7a3e392cf440ed3d080b1e6cdd9a8cc3ab02ff94d684bd725e4c3298af4c1829e76017c84f3bc9ba659226d82b25688472098e2b69eb1c6ab0bfabc53e66490c521d76298c7f8baa0be26e87214db5090b19d43867e3de7eefee7b24d62165c966448ffb937d0093acd43ddb018196f415fc10b31d930e8a1dad2dd2a17e0eff383c95cb298ff32481a5b734f3309fd520b27ba1d3604e5f5f1dcefa04fdc4c2f34f1354873c5059441b809347cd3e233538b43fa96867a7ab8423962662d4ea1a24033b109810f60f33b51fd85dce52f36cb93af296f51a3f51bd32465fe792e320a34729e5c504e64c15d86373552f08ef1a4cfccaacbb3aaf31e92efd971ec3933d56a3093ce8c719a7b619bf53f32a94b04c12f8cb1be5ca0df68faeca370e21f8d302bfb2eaab56239059f7a51734e92d609bc3f926d644a65bb18749e4ddb97e0c0235f514a029a45dc54fe2c54e192ae54fd419574e55401b6b1f1c3e474a66459e3dad6d21847b9489f9044dae6767d94ea3f06b524caf484628c8360b0ca63a3cd205e81164ddfd9c66ee77d055eaa4a616edd2084e16ca86830de419b79415aa7d4745b75e91017409f16d1f5a893c45170b1336f8ad16cb340659a1f310ec4b76b34fce27f284b9d6dd6880eed38459600117071fd95d11992152b4221483e077ad7b70ad2c4602c01fbce1dc1697d70df210bdaa23c4a9103da8bc236c2e1918dcb4dfea88f6b282e5a753395e7fe4f8196bfd30520ad953f932021833985439273f1d0b6a19a4dc7d2f8ac9e9f20cf55c72c5eccdf5d4109cf81420eb9c1acf8d7e9bb79736535bdf4a65acf9c7f924a1057c3f20c14f2b5d8844fc48ca2e9028fe936d283b9adc006e6b5b7a8697afd47ed29b0c111d7d5e438cbd7b5220dccf7a2b36d5325eb2bebf0cbfe70d0516ce827089c3614f5e907a3bd016853dd77a687a34593360215a04ef502e19ccf4e0307e7588bc639d0c8e4bc01be77e8751f002a91de6ce357030130e9622949cf56764fd85bccd8a17cc7ed3ea975b976524153a3d6007a9e01de09801a43b5235518d873857ba24811c29429819ad5b7dd5066f57fa5fe10f7f3b6e1976074c1fa26e6de2c5942352dec3e5d9f29a048240e8ede2f87b8b4dfa1894c1cff217a59f03360894060a0e44e88bbabdece032f511c39425610696d2622921bcce6d3427b9ee35cabb535afc96d2601ddb360e35c660eb4e966576eff240edfebb910f4d1107b820cc1f675cd1b7c8bb2472b0b9beef43797d9c6fe30ab33a2c31979d01302b03db864c66b163ba3a369826f331d65f74a71dc66539aa76fe765a889096264a1b82278d78d76df7a9b21359cae5744d28d3eae7fc5e86acb7e3daaf4bf62a196abdf7f80a9d8319d242"}, + {"0000000000000000000000000000000000000000000000000000000000000154", "00a5d3d4fee34b1fd4fdd07abe65572e81e878262f06de2c3cc845e4074455648fa6b462a658ea18cf15075fa926d4dccce18f9bc12ba64e55dc9521f279b121fcf3a89dd72c3f6b03626f92a8b6ee0cd938b06103f3183339029f12317da6e277b95b27be997e5c1e11a1a8c273a86251c3324292d96beb8a54b69ebebc1546578c32aa0cbd7b70c63023ca035991d04f24df26ee278573dc1b7ef736945cdd7d6366ceb43a7ee512979207180be214c0bc8246bc695934e42ac9aa921aecad62106ec14bdc6af4aeb14a7589a280745f5a31ebae70422c8cbfb16f0336c625d3b2d7765f55045bef7d12a9dbfc15aa1b67037a720a961e621f78cf140d6e9f791a7e4dd95eb598acb370c63ac21dd5796257de205e3b0f11fcdfe6ee72b9d8bdd07f554e5e158a4bba9aa2af078988152d11d8ac7dfa06d957ce7c6badf323b3c275dde88a955f6959a7aa701fcd9000e43e4b27d850f7a2ad1547df42c14f808dbcb2eb256af40a3a1d348af684b491a9296e2a4720f79da316fdae084c124235ccaef3e84a478d8efabe9ae3615b9623976c3b1d47fbd9194f875fa75e6d723b5e9a0ef05fb7340b49cebea8b27da369aa8947fa56a5ed4b58b619ec2b6e7b7b68180cfbe28ff2edbe7e4aca16385a5122520ef544a2760722c3bdca8347dedd043e6646bce22147bfec2015fc19d3aaeadc5c5d012916ceefe7000d1e99e6448247a542fb994fcc2f089844fa957e5a958f736836d76b74e3a16a15b872d66120f56a2ca7661d2d5baf82e2d2b86e40c6bf4978002c7ba417dee26ee9abdca32aa56e46e5c6a26e980e1ca9e9b623cca30fbe8ba57a7b36850e4ff25ba8911d61da4e58cb7a5bf97052663fe93054c3114dee5221a3818d27238e69978e928a62ca51e4a9ab927eb12ec8c544615968b5dee90512ed61f76ec9e5bd0c1601c4f95b0221f55f345a722e68249a8c9ae33cc5290e6add805dd8632fd3f6f11d20df3622fdc33fe12619bbd9b2e6cbfb349503d4721d61f7556e9598850b1f6a22fb98c84da6f1cdc7c474cd4fa29a87bd6a5d0895f9a350c68161ac25b25a4a308b8d74e99b8d28150e77b06f526ff35acf91ded8944fd4b00d8c2fbf2166a2ec5cea7491c7a783ba7e728cede2e29660a424da32631e25faf3f0ed130451ed404ab8dc19030002fdb7cb4f2159b32913cae7265e9f92e3db5f57303f8e564e36d48d3f9032eaf137fb547b4da61e97b31e7455bb1ed22620bd6f355ff93ff312d584fb8cbd6966ee6b1e66fba378d1c6f651df4c1b44771d38840925a185af89961b4576825bc53c927ac2173f765b1e914ddb1e9ec2f1b708a36826bf8351bd26dd7a312978f2da5fdbbfc323bb64fcc0abe7a547795cdda1359205a0c9eb9637696583e1c46b2e2adead79442e03650780c74b8be92ed32767b97a82af38d4dd3cbe03cd9f669aa0c6918dc3833c96739b95e704defccc0392dcdedb687e2b7eaf848600fe891b713dbcc881139e0ace7708fc173bfffade3974006ed85a7e4432074b3c1626c8ee2e6924c1812b49f2e69aaadc139d35c3f225c86ba517a709c3de093d6e5b6c5edf3082153acdf0c828465f73b7c5644c59632db350572bbe6eeeadab9aa64d47c3c9d8588cf1836668ee56e6c305909ff879e6a24d4e7b74967331fe4a6e8e15479507089c835171f32df51218d0cac890727e5a1409d909085542a3d5c4a94c3ef6a4a5e0c629ce86f2f438284fe98899569490bbd36356dddfc08e955a7fe25009d1aac858779ae9d18260d5167a241e3e1f9f9c3012370bc4764cb5c87d1f928b309a469a73dd5fd4281cd37df42ad67df94b2b64ce2abd1fc568e15f3067561af7cd63e3bb39d4a0e6a2826db49236aa1b1925"}, + {"0000000000000000000000000000000000000000000000000000000000000bf6", "00282ba93bcb748b9fe6c7aeb755207f59377f360909990ac08116e389e69be15ecf7c37cce244bf07f10d031b17ccce0054841041acadfcd43262237f4a1a1661bb5a4e953b64b133eba14de1454723d6fd0615059d44488a0a3dff454506b0df4cbfbdb52a5d31700a4815198a461164efcb02de304ac5791c663676250a0e88623eb044af889e8653b963e22edfb05959550cfc12e11a57f880c66b714c2ea0d9d90506f3d7ac0129671ddd06950d1d59d273a53716da86d23c678627b0f647cf916c39813d96c6a5d020ae019616297718390a2e8651535fb415f3f1bfb69bef56025b60f11a49a0fca3314367c971b3741e304df69f16f66ac6051c203f7710369731b940a6fbe39e572b569e0cba112510c6dfd2df13d07c712279a5cb18ccf72acbcf0870276273ca2810d23861751b8ea43d805a6f9f540b36c0ef5a776fc1e3252259f7476c3eab107f78fa016bd2cd6059a333472c12de5619a53532bd0b244c2884fce94058873dbf052565013bdad9f4ed3755101a5c2dfc485cafe7a93a02ddaf66d5bcc7e934271825a6d4610228d65faf9c33bd4abc47ed0c158d3118044ddcd7bbda0c8da8445547dbec49d5ba69b04c633c45ba2daa9c165ae6a19590ea371d1185c1f6b71d1bf9bce2e612fae9803771f5f866e97d29e339f6cd20cbb4e11b5948ab52242346badb1dc29e8cdff7a30cb7f36e98cc955d8547f21e53b2a3412493ae9e231eb39cf1b5d0c37734280707d7ce057610d3f5b19c0cb9fc2cca0b9c7b8223b6ff8abf2ef1f939f7119f0e650ad1ae19a2f59fb5f3a3adc1b405b45f2f098a0ed1e42bd989715f2be63802daf66e06b795588cb41342e9c1208f0133d10f7942b74a23ffa6f15e4330193ef7aecc465e8d5ffa43aed367d1878f6d9db22d4d2544f779a93f977171d656bbc297321fc51ce13d010072361ec47cf7a00da0146f4e12d2f1f317e8fe229fce879a710d0dddbf6302e95ba70a8bbe36c9e60436007615ee5447af6322c3c97336c1bcb53722cb06822cdee647451097c0343acfdf52122622f76330022f52da86c6db1ec59b00848dcc168c687274080d03fe55484049e8009f6102ffeaa30f1e61117dcc0125327635bc25a55f59d2a4eeb7a93c69f5179e027e62d3c7a1e9f5b5c5e62888b6ac6c0c9ac75cbeb80d0e78538a86f5754bbd348465f44ca69e4a0237345d1d1b3acdd80e5cc16aec3a5ed3e7e79ed392799dc31076a6cecb8714bf3db1214722f8c731c15318de02170e5dc8fdf20bc197eb54108f3eb1e909f6108a580ff95c46400fb99b7ea0bdf381fa13a7bb757ef276320536a1e932e9bbd00dbc60ac6da1932050bf8aed1aab952a1b48c69aaf8082cae078dbe0ead6b267062763ac5297619cd59b7ad28a736d13a63082130b7e02bda966daecc28faf7a116331943400e7d4ef98e2153f99303dd2360944bb625dd997e1116f381f4c5e156eb7e9ede55b51f72f533568daab153eae30a72d1f923a3f0b181ccd77f2b313fae04a2e8cb65f1c13078bf500c90f660dcf0e232015bb577d837c33b42f0d8c5588de54aacecfa6e293e8f5059d48b8d8cce6081bf68686ad56c7ea9580ecb6f911c9fc1911dfe11eeb1729cf0bf5c5297378c0145c653b98ff9fe7a6038b1c01442f6937c7eb239f6fb55cc501c77b3b122a5e5e316a4b656f80f418078149378ab8c8386d6c2e07a1a02d4cc5bc6fc455ade53a8e1e017bf5e62635934396d7aa6487afb186800c368166093839f1a203fe37e276016b8c504863fd36b12abd1982374d053e3252710aac3e6596853a5b706b489ec3cadefff817681b3687a601c17916540e2dc47b2278891dac77188bd713f2cfa189a5ac819acd21a32738095d4005"}, + {"0000000000000000000000000000000000000000000000000000000000000904", "00d3689dcc540c42a60c1955cb611252b16afb7b770a0c061f9f943b16df69b808226189168d9eddee4c20db4c67daa9fb4d750c139d823804418e5f305dc0253293ccfd8a8026728235c937d0fb7a71cd1b874a064eb4d9255120f9d1daa37d595d109e8422db2c083039dc737de08c6f8ab0858d577cfb921af57fd6e11d6034cd9172f7e1ee6733fd76e76f1a449335c79d33b4f36208a183e1715903fb73e103bdd1fadc2252018eed1ada9a05bcf79ef79dc5e348c717d91dea9e3dae536e0813785d7c420504706e8f8a245218a69224e5d2b931e838b9cbcd23bc6c494e8e0b06f131414e9c8b2abf25529d8dff37ed8cf5b6be7833d53b3308a1dd148b93ec6bdb81d26b524f5ded8a3a7b0963099ea8f1b2893bf5bc1fd462a26d2f5b64a33c77951c5276eaf2f7737bebdbe4da87b34f028f86f7a388241d679fc65fb01fa8cee70001c405a293d0dadbaf02c65578c82a734b68cd83cf6a61591552d0bbad2a054c9bc71103dda2f491c3bd9ca532eb4797fbc8410e3fbdcb80a650eff265047199ab1a663cd873187932002d569511fdabda89e4ece0c8779d85d3b0d7f504984ea2431ed291ec944103fec85e78c9802be56006795135cce27499d912417df752d07e8141de3934091d6ed71e674ce79092e357424d2bae89a4df4ded1f64d9f3299b390b9869b24cb07d3e3a77cfdca58c03f008fb96cc6c3a78a5c281fde00d615e53558312142fd1207aec9e437792b57f66f965016739dc34e20934d4df4312742ba90b53b73ac71b77a7099f7f76250bf17ae499f863c800f73f0f5ed1cb57fbfd5ad7064288d9aec3c43c60a754e22d72013dde889a7a770a2dc7076e223e7df64a8373dbd75ed15ad012e2e327f7f716a9920a31c37522b602d30c4500e9fa81f63a13872dfd6c4713d21d67218474606e21157726aa00f3ec523f09d997cc5672ed83be986d3a430ad42e07452773904510fa39013bf6cee0f16beaa7df990b027d8b3ffe11cdc4aaa08331ffa14b2a8e33d7c1b018b20b6703d773b7f7769a92c95b3cdf58603f8b7105658e528d10ea212621a316a0d7db0e5e5d5c0c5108588419d664f2818f2837877d7d4592260134d46e20aaf1a276273fdd83a057a93f7739eb61a2fe875081928c146f70c567d07afab8056027137d3cff9bfc08c1e66717963b0d81b3b4a5a56d5c1d6fe8992fba10d179371c0ecd5fff9236b566fcfbf6faf19b999e0b8cecb0b3c86d63251bb23c13fc7ebd1aa132dd534d9ad56b0e7115e39cba898f3e639b628a869fd4a10d2bd19e9a6ad93ba011754537e1c0c20c46b90fe61ed75d45e31802a1d9f5432b5e7fd03e22cb976fcf125839f51aabd9fb729d55547dd2ba52179bb1566c42d6d61b4752878d2cbc76b42dfa56c24ff2bd538a032eef10474f7dc9a9ec8155c17abdbc9c16d942c935de1286caa3ea6f3bd686a3e77d9bef8ad51c9cb9264c656379b8e1c5dc5aa7421ae4c85e87577e5ef42f8eec68621066d9851454e0f9bd232dbe53f1546d099280e0ab853164df3e909d579329a5503d1be23750287e87276b9979b65936fce3414c9e1875b75a9610d58609bac54e9e98bf733ddbcd3c211c88af9ead39cd3d79c5564041ac7557554df2fe56b3c4374d630c1a056d955bf0256a4d7105b0b1dbf1d8bf9ebd8d1ec3914b339f44acfa72a78e5e7b17b2074319e09117ebd7cbb5788b47dade776d5dd6a01a1b9d57c4842d50cc64d9ad86c7ba543460d45b3bca6e9adec09e0c2b5b8679cddf19265ef13f8a7d9e1aa66456204a44c1d551b5dbcecffb0664bafbd5aef18bdfd8245814713a5cfed1d7e508fc4184c7e912e15df0f1f22e20d90515fe0ae7699a04b77d03bc399217f8f13453"}, + {"0000000000000000000000000000000000000000000000000000000000000869", "000a133e004e8576d8a950506bbf02c532919e76d30d102bd973ac33e17a11924dc35d0d00a239af04c80305f426deeac771c1b0a77a71c616da7f8556c18211b60af3949c3cf59f41c1d6ebd5bbc8911793ce0a015ce8d90ec5759c7be7119fcf1b0b08cbd1feb72407aaeedc0256f7b93c38b494bb6ef8f63571b25b2e13270c46e349ba50ac6bc2352a274520f7c3570a9519fec71b4bce532d6b9d943f8ecb6a698566f5953c0d8324db8fc786f30bd923f64172e83e5afe1f120450e4b6b984592a05cf10c88e057638863657bb164c11604a27af048ba55881f162612327bf0717bb0e6b31e1ec87ced10ca4bcc2a5c969f72eeed6439845cc1116a66606c58e88f8629562176d37a9bea10df69f19b0044fc3dec2e9f823f48a5e4c0746c1369e779a16201c405dd78b5f7501796f8f528f02e0653c61bf3801f2fd8b15e0d0b99398a72470e9d672929c21ee01623e0caf809c5d507eca8698fa8ba2ed40d9adb20beb65902c04a3c9684801c58e43c3f4cb235da033094a6735b9a6a85df77260e97339e3f90fbe546e83211c19fd256a7b4993490867537b10ab25585b845f07fea658644a00617ca25ac34fed58d6eb615a402d1bf431987b4d4eb09b76e2a1e2a93b50c891ad377e13f87d68c6a4b4e77dd324bdcd7b890dc0fa3b741d393cfbfeecd55b692f28aacd80da987edb685f33e50b8384b1fc69183348e295d8d3ed6a49c2139807fd399b9ff2319cb86902de5831e27bd32b1b0d1d82601abe4bf7e9af272daa1e82abfc71d111c0d2d7aa493073f58acb193f7b688434fce9cf07da92f53f3f3e0d275cda0e5d39978333213dbe235124931f2e262c1db1e6690e675595b9d7023d1c52d017a4725d3b4d34cca34c1ace4c61081a23c51671d565af4313d0204b245e833f625dd58b8b689a535c5b1730601db9c1000bf025d7dbbce5bdc612ec5aa69526057dfae4ec1b031c67362473f1edc5832d2dda48ace1d8073f0405611a4dfb8ea2f9048701914a6da6486b1a1198e72e1624b15714798ef272ba3c6a7cc02f065fbfeb2407481c06459f67a1040b80b0b527feb98cf47ba0846ac99367a9e235cb4bc86bd99ee087ff3f573de103079daeb9dc4f1d89ecd5632570f99815004a6e9a4b081dc60c2351b26503c753e58ed7f96ddae0f52d570543bdc5c8c1a6b7cad543caafaa0288f6bf35a5591ea349b6b158fb3f67670205a6f2d586ed76dd7d890a258d6c72a21bef6cec0196a2599ca521b2d4cdc133fb3b06deda3609da34473f665968ab73b6fc50cc0a5436ece951ac49fa81e8c58f75c20e629397b0ed17d0f61b499404cb6f15d1fb8c44f95d9f68168da20be3e48d8d56df832abc2104c84a35bc95d091fb4917e962a68a9480318bb3333bf1406214fe8792ab18031fda9e42267669ea92457855fd5cf5973914d947070751755850dd0da33a24843bc06159eca8b1f2044f927c702c67ea375c02b7dd4169b1f291a0dacfe0504fc75f70d88b77179d78bcd169a7dbc7e03ea3c311c5e0e440dfb737b89fa5eaa6c4469af88a996c692ef2aa6d73f1eeb9cc8817794bed7a2622487a9bd926aa49b1a1cf93a3412273b53a68c4e4fbb6b789d380f7f4419921d1ab19d63a4cdcd6537f40237e020304c5d270d75fb6bb1386c7ed34e47e330a7ddc5729077a864746915ce8f995a2f0bbbd53e1a3d813ffbd04ccd6f952919c934731d43d396370b9c7e051b5e7052ea3c794c2a84f43310346c45b05acd42b78173605615f6f2bd9b9e7b596e2311f9604b94730b9a7ba1450878a90d6d80743a1f2011c95035971af9ab344073bf4f7ec65aca969b565336272059db9b3dbbbcb2729f74f74379327f986d45162bfd1c557dc2ebe79"}, + {"00000000000000000000000000000000000000000000000000000000000015b8", "00e32ae2030b9cd4f0f3d7b26b711d260f14f4013b0489ad07dea76647ea6b6203b8f7cddeb68557f31e025d939699a83153a3dcb38e7ba92d19d35db29844250db9d5924b779af274d4d16370ced59f862d10960aad7919aeaef325ccb127ea7d60e84a40b577a1ad160d75fd1607bea35813a3b6cee4c999106c5726c41caa34dde44c9ea8ffa512e4ab35da2ccfb06c76ae601bac4ee8b42eb7e01ab62dcd771ec5cc41f0778c04eab882b3966abfcb22c08a832d5d172be3fb5b7b3680be82569c9ce734edc9cdc0650502f2f5387c2c0d92ffe7138c3f04f1ab916b1e37dd111e3e9947ae149571d9aa455e349f7c47711f7b952abc3c1897970b0b9f55af84dc84712333123453e01d228ade0e7f33c38673670dbf81326898937e4982f705e75984f811e4020bd5dd973193ca052b8c344077524cdf56dd2bbf1397951bd379187a63ee7762173202c33bd97801d8b6dcaa9fb753b730e24e8d522c462f725fd81e3817b529f5535a2d6ba074849afeea75678df9ea5019e9fca0021b29ead99b45b0325970c5ec71f44ba03207b6d48c5db78902e5068cdaf72d89b2fd9086390c415b1e26551f0f55f359731bd392a2ff1cdc113f32bd62fa8271896bc98af65694480145b130fa7c4c23b95281ade2e2893cadc31134f6e380ce8b08960626d7553a57940977cd83941c0c774a128d3bbc27210959147240c88d26dffaa2d7ecae87ad8bac2cf4a659448f117b9d63d5cc7fe76016d8e5da5ffa9390130be7f42a6199ad2f2b8631741427f4e93c7d7a517113fc63505d54ff0de4401693e96d7f226584b8e99525f93774e312c6dfdc147402316cb11561c4fd8a2d4edc1ae535dbcf3f8fabd7dd03fb00470f739fc1973cd3a72a3f167345a67ce6d5e1d0545a4a225d70af453f0d501b5f991b6f00552aef6634d23877d2485f011362966be5411d2e65b44c40b36615ce7c17bf0c43a3fda585d54ecb86939657ea528a56b5ab19f0ba0f8502d3a6f384a9b875d0fc96cd10657d0018d566293956c918136fb0cb9e799aabed7abab66bdcd24b0be6ed045630e13ff20a6c4600f9912fcd7d7e7b5842420c0a71e522394d7f8536604105ef15df9af8793579437920d3ca20ad23176f3053c51bacfc9d70d14c2b447d0fdc8d8becb115440148fadd65b6bd3b0203d34628da5381f0da4077397e417e4e2e5218af8f16674b9cc3a61373f7d821a3af41b28879add5cd4511337c6fa71546deba5d882fc35450ca8095bf7be3154cfb8da0dbdca95c05f34f87ce200e2c42f5ebd2081fe95054967b10fe6213baf35d29c4fe164857ac54dd6e292f97aa2590dd9765784e51c6c3171be4b20b0ef2ef0acb2b11b0b3b2c7eccc0d950750daa3af1ae23e3236c7a18bf902455453f707bdef10dafe5503e276ae6550cd81aaf7f1b67bb544c2192b3870f608f0eac944d50221bd1246d820d4dfba0480197cd8159885fadce642994520d44ae03a9e5a024873e9ff2e6b2a02ea6aa771f55ed3021169a7aea864bf94ca0f21342f38956a2105a37672263460da2049fcf3c43368b73844b380d39e7a142f11335175b274cfe36c11c23dae1c109bd8a61e32fa2cfd221a09bf3a88981937cc1c1a3100818a17d33562ab6960f19bf6757516ce36ab56c87c52f2bf524864a0e4bca8e7534eac1a54eab38493b0cd64db467c91d2e8cec6169e438a29b5b41a58e6a4b15f17f5725c4b3d95925270217e35aba7e3d95adc8adab0d52d05bf2c49922f33cec318dd85bbbcaaf6abec70630e7da1802e042698e5ff21cc34e5df15901dec9db35b1ee41575a01675b8ed26e06ac51dd815bece91e52580b7cbedf7e4f0615147a78c197bd2b6e516fe3510eaeb87819819de7b49"}, + {"00000000000000000000000000000000000000000000000000000000000010cb", "001c706aaf1d2d270809e6a7d2f0c2e6d14fdeb0fb45a06a7826a9bf5dd9d5351ca95cee56311238e38e265ab1e87b96e535a50b9274a52b7f050e1fdb2a613c8c34e4faeba1f1ab2ff9491d6a3ac2bab6de17f4034e289b81e2f115d98352582f39eabf0ee4b8a63609b1a731b294c00cb7d6050d91af99b5d0c59224bd1cde9904ee54d7c7e069b2548f463389d66fd94f513456a794ce7f6c25ffd2642312db55f952b23adf5e022d01bdc0095ec69602c86404fc877647665a0fbe052b212a8ec9af0e63fa91be31d7aa68f047fbe4f10849c857d496eb0ecb5e516fd336e9ea8ef9bce5e30c712538749a2fd33cbe29a7ba67f63ad4b41cfb8503db6a54cf09d339a6b840961a85daf8cde10e0e7f0530ca61d79d6e71c276a05da5d0fc28658271511a2c66ef1b089ad6ced7897863f35eb94a1f8d7e112340bbbc184fa328cd2480d5eb656ccb3a58f53ffce1018a6b65f742de3599b2e4f0e471a0ce0f4635feae6347b451c0aa6223c319c7559c42a6f621695b15e5026c9eee6324785743a9d1d43eb387fee23dbac6a92be0872fe6f14007e668c2dc4936656d8db61caff901b5c55eb763273f27ee701d04f975c1c7f13b27c40b3e7d442e20f995c8e860c81acf5d9944ae761c7f0774cecfac4f61954822734e27f59de61dfb5df1231e782cb80aa7306163f3c2c96d545a4e7d5cfc7941057dcc28d54fdbebd72f7223bff7e1ef3b993e731f44bae280d9d635c5926e45176255a9f16e1def3472091f7c03bb4d3195d89735d98b4c2841bdc696bd601b3d8d56f4d9f28b4c1dd3882750a9c962e419dac40aec8adc7778b479deedb1105a12a4533c0a3bcbee0d382def81ccc43535c3230cbf24d3c92deabf8ad3122d6509b010c152e0cf6331216de222dce3fa51f712b86777d4cab0f46946a42ecc7cbdc5a52799248c00a39cbb306a08c3f0c592aa08c6140a10bb59daaf1ffb1c3d0612ec912b7dd38cdb744a11109651cd301b33adc52337b3adede8b87cb9704107cb415e83835e2ab4116d9ba7ecfc83c6f49eea3a468cc23ce4c611025ed04229d7cdd9cef38f7dad66517b5d1a9310817a679dfa27f741c62ef98d4771523ada699db7152e806454200f205f27d435311a6d993200a892de3f47a34f10dfa283f92e4ff609a439dd8e5c85b9cef60376ccb769db5c8bda96128e9c55f352d93e39a5cf2d12c6c95aa141355fa1b5e670c90339aa335eff310cd0b53a3e5b391ef35ff3aaf1753eb542dcf689860e57616933f11347891342603b611e7965efd2148309c42bec5b58540d2b5353a9f742111d384009f33116cd0fb759612c0dded96217c01af53564426e3b3f0d7687e1ac911ee2cf3312a1dc60c524f380fd426215b2bfcf3145ec92aa2627bb12647b2ef1ca5e748908ebe5c036433f6749f3d377204a0580f690f50a972565a7288e542a6f6c5c762ed0e8fcd1cf8d9d6c3208ef9f7d6cc4f7b0e701e100ec524258961cb4601725880ba53c9f1f834bd495c42ae382da22705154402a68c9bfda353873f1ebb46396e10daab13e1b14da466184a4af77bce7e0b945b5e8e13f6a578b348b2b37cd3710a197733da82697069a4b39126f9af635bc6d609d5175206a3335f808c820df5b864912f59f55093e3602bc07fad2cc6250c345c3a0d8c7e16a98ef196aebd5a759410dbf9c56468664c211a06d1b699518505f83caccc905db5981d3bb38d7ac89e48549742e7b44e30326ec9b49cec38a614b046ec3f39ab607100ca0d19e94200f4dbd926d77f8fda50ae071e83d13473b3b255b4cf11e2c7252872da68c94d0df9e5626748f2b20af7ba3cf2fb2d64c6160cd984a35151d3963476e8f6c7103fd94370f55edca9a6c15b7699b"}, + {"0000000000000000000000000000000000000000000000000000000000001652", "000a779571c2b44d7fda937d5fe3bb9e115998225c27b127878d952eb93618234f049d80fdf74af479bc0e06a4ee7c3bf1f1f790a3fb656b9b6e102fd4bf1d37bc3d0c342841d58d6bb8077cc872f75dc09ed87b04f649f7b94de4c79ec550c893a5ce09fcca9c2ec41e996e951bcba813bae46a3ae564d7e2b74216ec1837769d422f628791a33469caccf222ff1cb09c0dc644a863e76ba8ad03b418277a4fc8d1a2294079054105f317a155c9e50b10bd6135d568d9bca73ebe0bfc09d6e360b6e5f6e734d355b727b1ad5e1a5cf6f8f2139e437b24ce679b154ce7934e47e5b38b08dea856305c12403b68b803c334b3a1dbb428b5d9719b4d8406198dae290c1a60d8df246f90d17736a7d5d9bb5a2b23b1a24e13b7873bd5f4c8ace717a5922d6d568e09dc3e4ebf46f037a15721cad1c89748c8e9fcdbc452dae3f63d260103fb3305b9bbc47db57d227f9eda01855c386233d5c5b206c0e98c0c571a145574ed8b01c41de3ce955a87961300a4e8e49df529279d792e02212d5f3145587d6f9bf0e275e0033d049d2984ee03a63cf8270aaa9968a7022d9cc7c8118fcdbd8fa9095f60901160ac5966268b05a3f78d5f27819c10a5121741864fc51b4abf4e52c3dd6b7e9692463ca933204b8f4174a9d2bf521f42253339225e0cb1d9788f25ab39d05a0cc696e3d33567c3ba73e78a0a3d42330249a879614ebc8d783eb2fe55ef9e812ec12ce9070dc8068eab914542a27551bd022dc6493c2a5eda760b506784f7ae16ad9cf601b6b9d6d5a0a9a8ff55bd49a9faedfc21ffa5c864fbfd4aea7a73032cd9b0aa10f9ce5e1d6e898ff162463d28792045ed503010e729cd33e68c9375739c87d3b316ac09699e79b22943276286057ecea191fa6353f119c0fc55560db0ab163c6f320637e3d99be0b8454e3c369f3ac24c5ece8f004a3d5a88cc21f292c6e0f1b4568a006b9ccf3c6d0fecc50d8cdc3d7eef5393a96bb16f399e860f377b0668190b2a05a01463d25a8f3570dfb2d4ee1ab83e09bbbdd6a68f20d5fd64414591438ddcd65e0fb14f0f38e8fa732c82cfdfaeb3bdc8c9f43f0d15de0ef9270afcc9395769c74a4863de8df68ba303ee38a39527bfaa4be42d797591ed74720c6cbede28589e6f12404eb2acfbdd50453ea0d44fefae3e1ee6819c409c0f21f70cc903f3eea75415ca5a74236978a80cd3771566da06fc513d0d8a9ee29f65d527f9a165175aa725808bf060ce3e93545ec355301f7671953179194e75b405acc35fa7f56e271ae8cfde2f3f3f94bf18c80fb6a0cf2a072b578791519cf875c9d86c7251ef470fc008c1ba440527f7df41bbfab4b7e5f7995d0f67185d0127afc6ceaebf375415aaec9d93615fbe1e7b3cb78b3ebf9022034719e860395f02425a28b3326800c06bff8570bf9fc7a090724ace349aa35d38831110204bca839e86f91c433102d21f36b1ad5097b42007b665d46b5daf0dffbc41ef49cd90397d0b1e083112709c889af0db7d9c4421831b651f71ade89676a30b889ab706a6d839586cd3e05ee4001112db88e2d12c71c540a2cb40fe79d4d3a5a355ac1345ad7b4b500e63cf4ccfd694df53b44300add9bc60e2c8bb3c5c24e50f9f30df7a196ea8d37300e934656cec2c3f6301707d660176f9edd674304c29fcca1d6d7c9c6352181344ce010873005edaac7f16e597c7258c5b6e8f2646d2d2a45acdd334e5a3ac041da8ba532ddb6e2b2e9ac20670ce59bcdb13b38e193e7ca33fd4faa93e24f02a49186692d1f022e27579fcb5c4b99c0b88ae26667f70b5d8b387b755969eb7711216996aff8cdc401f833dd0a6ef57b9c9270253e70a4dcc455de0e15c546644401f4a99e6a1f6cf366a94ab9b9a9da237"}, + {"00000000000000000000000000000000000000000000000000000000000008a3", "00bd559ad249caded7163150acabdd099a9b71d9ef0164c5d5474368d8e29427fad66f52da483cb24dc9099541a094c501522a12d13abc168d9597124cda1b09e8ccd1940fb1079f9bd523095d4a4222091f71d507a6f46ae61a5e4edbd368ac9755ceeaa96bb5559c2e4a76b261af004ffcfc341e305bab61c33a314a2708136892c6a1907dc94b611adbb024919f8fbab1333e0f7550f67b9399f9d806224251fce1fe581eb48d022f32780d1d0f479a0b90e56a445b40daf958ea08459284091c96cb78c3d1981c6359404b5ddbdfb15910c881a317e1bd338d0703eab164458f006b5850d328ac448b1591940bbe06646c1c3dbdd68a7f5d1d9e035de483af172f1dfea3442f487aa3fa6ad9de25180f771303ba48be41ae02b4517b38db6691c59ca7ce0efa114766102c9da3fe9354cad16525cf1c169af65032e2c9a4b5bc8dc5cea89327f3d65a6f491cf7b9016615bf0ddad08b90fcd33ea6673c1127ea92a5ad39533b84ede54811c7cb33ad216e1748fe98bea0010454b56d5e1540a8fdd57bd47c7d8573d9d75f86902be46a7925e3dc43b88e660e39b18c8e2eb439a4611ef1de111193cc7d2ab1358db7f3e05dd4d1dd1ccf2b166968fdcb5c18cca632f4d4998d4cfa37974a202265e71fbfcbd89729b9760dd036b2d594297f62b25b9f87360f6d6ab39372a5d0c5cf78aaedda7f090d055397152aa3943d374585e8bbbd9c06dc99df8d8b0eeb272c96d535997537317fd3587ee2f154fcb4a1061da9cbe782fa16acb2c2ed771849fd9414ceb99e2e94cc8a489e474fe11fd62fd65c5d55a36eb41bc90600b5e4b0dc3529705a7343f1ed08e52f683588f0153897538b32f38de09372603337e8722146db84700811669028a07ffbcee8408956ce92947cbdcd06cd347b1f3c7f1f23911593352178cd56a998e798dc06018981989865229f597f2042a7335f7441e59308362b91e7a2a1a159c9d27195273b31c36188fa9d64ad067578aa0cb55069aefb837c7de2babdbc56aedca62d51874d6e5929c901ed592cf56347c26f7976a0b90785793c7e42792d272956ae8d38d26e1d91d7b5042668be86fd21bac73d6f0422a6c49ffbb4b95fcadc0a0779e0bf13afe5afd9c1f0afd0f829477b79b7951bc1ec704c5ae185bee863e21b23f935842d53a2a70429dfdaa54f20435069461524c474f9e6c33ceaf717334af18008a3ec8f02d24b7174028570ca3d197713d70bdf671f6dcb6cb2552bbdd1c0c73e06febc042530bf7594d49253596db2ece2c6bba5d362787edc086dec83461bfd2b1af5c285235eddbdd0c8fb95011393ecc91d4b82c9a53b4823e756bc3ed9c97762f51758ef4643d760df66d5220ef2a8f16d0d584aa13b47f9ce5e3c95bfc8b527c4af0840547a96e1bab11c026da16b29b571b3c779b405b64c55fb25921d240815a7c92389e4ce0b400d0394244d275a2883fc9cad184a76bc4b67dafb9dd5f296c1fafdd0d52795c90b2359216bd8a3e7b130d2c6883f4b22c61a7edb043b04f1216b98b229bdee9de584f9c3cf51a18452ec346101275e18e9546dd7b1897ff0e56d27052dbc96e1089edee91097a616bd683320a61c3fcd99131be1ce1b1ad10379500751ea1907c550f3c1df249c5c1edb032aa0be98954b435de075e9daff4c3df0f41282e0196d679fa990cb85ea1946e6d0e212ea1f437cce8b1001b5f53545fcc2d862b11bdfdfc23532bd76650d737e7fb49224b7e56b92d79ac74e5b61ea9b3ccc4b0604c6988324320374bd5269f1739f30c4c1e736150b07a9158b152e45588b66ce13d7f33614dc55d18211ad8ba63caad39fee4c15548ef3d40162d6f5b3cd3aa9afeda0a2e20ba02f83c414e9c5e92a863c0eee"}, + {"000000000000000000000000000000000000000000000000000000000000060a", "01d2f32340427431391d16fabe7b216613d15d80681b62e9583e17017fdb641cb65170856f7448fc274902aeec53d897351cdd2f63ef74a588eac7df5d7bdb1eed33294d8cdf9d8bfcb28b5ee0534a07ec5cc10c03509defdcfe91c7f712d062511b03d228005d65f2173b5f718c4d2dad222fab662bf8f8b2f6d2de109f19b03f9ba70fcebfe3e257de5b5ba2ae85951e382c216f326211cbacdbfe8cc4024be6e39715ec3e368a029e2ddca4e2ca21891592041f956b9b415c5fba8a1915379a8e697b09b7f71302d4d426850ad5352d3e0ffa048387841826e7c6857a38db171572b2f7b6bc158033ee7499e27925c642d403bcd01512425287d303c43f35efc70112da7b91fb6c5506b4acdf0d7f2b0650346a801b280df734410f67d424a583d4efa53f0c8054496d59d613e16950ce9c2ed5fb41625aa25d1f10aea44d57a310e3bd165b333fcd05ff4cfa1a6004062daf12158bbbbae81178efd228997e7cfcd1ba04fc199894475cbdbc55330c482acd6a3b3afbad680d3ef334cc9354919c5af0e977e6d6797ad519e5512d62c72cd398d54ce381652cec4e999da727d3002406c17f4810cd21b7846e64d948d12a5f5a945e4c0408cd0fcf78f00d7f8523d25812fe7034cb1253f3c1098aa4d1c75ff18b110522270bac8e99bcdb365115126f4c0251abfca9d82913a83b2e6eda40503bf007053be4754a85a8f5fbb461fc43d1da45458c6de66f14bd8c1c6645d5b9342d079ddd58ee22189993dff62c94c9e5c56559cbddb7053489ae3f1a55c47340092f616db5fe5349eb3ed6da061bf8f016a02d95291d127b16475487d2bd7ed1d4422428a686bff8f7a9c73872cfdd604f3a92e0efab4f217d6a6339131f6c981515124083e57eb1e1213765564da43eb7b59f0c181dad1ad7954e285fe69c845f9aade7c9199e6a894a0201f8b90a1375ebeda6e68c233f8b163274d512751b65b3919309ba08f986c274de519e5d1c4cbc3a4d06535660c79deefb1810a2da09bac6f911ec1cd37145e3f2cf43d4a6eb9e81e5f904537fbe3dc01c90320b69bcfb5dc3dc1a970225107a416cd9ed0b51a1bc2394aecfbdccd5d9a2c6773b9bd8d241eea492157911464e093a0a77e76ac5746195e606bd58c2bb66d4260c133035d6490d905a842fa95f9f8a1c705a80cd0568245aa790bb0fea59b14fe210a37c5ff175b207448f961807231bf3568a668e5ab8242e71945a891707a696f660922bbeaf1b60bb640732dccecdc8eb3d1a5979e6935540213418c9ea545181c33ea91ec7f70a5c49801547285cf80e91f64ca2fea9ef607faf4365e49ff8a3a8552b7913b847ba52feba644af94b6c21e19ee9250a7927efb755aa243c2a92c9afbd649131a2d4f8bf702107f28fd3d56234bfda6d3eb7e52403e43c54411e0aabe1d111fb845a102b1f96fb5611250eac40028bece3911575d2e34076ad8e272db28405b3bf0dc686fb631251758bd2c9e33a4ef275876626c93d9a2deeeea1e1c785211b63fabf56b3de34dc0d4e7f4f7db40b23aed6f1710d408f407269777a071e737cffdf8f56b78f0fd33f17b0576d45301c82d20ff961fd4459071d4d81e12dca37b5ce2eaf7ad6915f3572ff28d946b6cfbc58766b4b6d7a33feb884e707e5cd61efe796ed9ea021e54f45dfeca3b8954bba3116cf9a92ff2a7fffa2767d9773ae3e7cc8ffe2a60d063ee9ae0c9fbb934d55d6cd4d2ab33d387d9a181769e9215d9892ef4109d2a5a524b3f54ae8ff77561983b9f1291c37d8fdc5b53636de572185001d59c11b242e16e4ac29d37a1f13e74a3bd5062ae31e8f4f1b8568ddf528ebb5d375d368b1e9d535ba2e3aeac93563bf40e3995f3f710cf8895369f17a5a5d14bb6a"}, + {"0000000000000000000000000000000000000000000000000000000000000e67", "006104bfc0d7d12fed0162241b28c22d415cb1cfce0298bccfdba64f6dd1ea60337cc2e4d07a2a2608811c6349d7c3fa24f5de5a3741e4673a334a157bc7fa446497645065ba7bf319e6084ab828ca589bf6e27505865af28b79e631d46d08bc72f7dee29844d9c4012ee92dbb696f5d137d70b668bff7a3b6a0021cbcf10a915468d66e6b379f96321d2d7e5d4a3e9457c03e0ed89d84b09ee9e9902e31d885a573c961d61ca35004f87f677c1c0bc5f488d05331602f80d9b57d42e906ab11d9be0fdc48b8f1968a87ebea39d083394e481675f2a85e35a76fdd1de94005578d7f693a1fd931472a4cda98ea6f19c532d61a6ecba7a5b7377b48ac08c9c485b7d187e37809d46f80d0f9d17b21fc57782e7716962acf2b6d67f246bfcfdf0aae04efd86fb019cd9e44c9133548ef9251a62eb596009bfeff55e01fa46402d88b00789d0173d96c73fed1aaf737ddbc00b9d2a4b0c56406c5c7371a98ef1fe39ba07d0f511c3457dfa65c99893954b45c89c76d493dbc106dfe1ee42ce1dd9f15c79636c50bfe76a99f1b909993451f39549b5e885c95e7ed75e570377be338d25bf783010541dc774b2b7baac350cc925bc2885f926dc6293e9dba3d86d3a8a1ff5a76c75d60892aedc1bd07e907fb5c3eec0af4e501bac201fa4364355e1daf0bef135d45bc07518f3b92dbe4abed79bb7de16eff7ffd05cd3cbbb283b05220f970d1cda05ea280dc3b684f0def76a6f31c62f39e6e340d2f7a74ca45621f32f41c791c8d5a13bce4a12dc77d7f40d502613454282b2a7b7c717ce58ad96444e327f1be4fd68e2915f30f069fa966b8629621a0ea11abd773a0589476ddefbc15d35bb95e6929f3af87317065100c4ce68327c09910467371ee469069fbfd773223ebd0c2a8a2b7c2c11893dc9cd8d091f0e476b4bd443021595daa9cd40b0283a1da707171afc89bf90a414d19b7a116fecac676aad68670af80f5b539eacbb3e14656edab7aed7910e572e131dba74ded3f34256be26e79ab133620c543cd346925515c433c4586b0e65d98df20607c8fc1104d709b7e9c8125e925a574aeae31b271245e4f6c7d311d9cdc318609960e595d15fd9eb75e357d03be1440d9d42f4994094dd387b02d458e56cd8c3eadf638360a1e2d53321d268eab48c07814ab4acf7dbfee02d774daf574feb9c0bce41c63cfe532eb4c7ece86657034e580bb9b47ebf6d9c528e5e0268ef3553bfc25283d6c9916cddf7129f341006f412f50759cea1f3d4bc67d8d5ba8a2e69f863f5add092a5cecbcc6d60bd61b8980affb1f99cbc145b0c19c98a79d8c7fc45cc9aef7dd2ce9bfba74d8dd6dccf18f26409e883317291cc6e7eae04fa97341f1cd640dedef071e10671e32746226230cd132f7a5f612634529c75b7b938d0566f3f07305d276f2e859100851c42ae052fefb4725d679933bb2e36baa6aa3cc7d1f6626c88f19cf7d13b49d05f686b8f37b82b44cb5bd315e0cb4fbb4bb18ecb40e0a0a8993ceaf329fd72e6ff9339cd77f870728a418d00340d554d7015a1022dbe49bd567b4473305afd1d0ac781199a7e58f2041bd9f1184fb60480d34924e1a793625d7ca514fea1f015a391e5dda8017155b7c80a94b9ba6863523682d2873bbc09e6cb0056ec4d7370db33ed7366511fead2d3b2a825990e922c1cd3180eba683eead129e264a09d92845edb40a2bb5db26a624b12f84e4d60d3ad954c1daefb622ab2d61ab41644e36bffc14a497a8d99bc14fc77072250b0d81157f95aeb0d52c133bf7a87fca50c138f61e37eecc99dcd121bc98b1d843624f90778e7a9ed64c18ca1a88450e5c76a82751948a291caeb301585e78263ddfed46da579fa16574a37776c8ad31d6dc2a66"}, + {"0000000000000000000000000000000000000000000000000000000000001a1e", "02c15514adacf021e7dc629d773d4eb9b9d4fb7e2f0bd2407da31e4923d48236140e69808da546b6e5ed0cc7515e51102a70df67f67cdc3721130fe67db65e300bcae2168cad7ecd25447c0949243d3eca0aec9b079344297cc4dcef96a1f1dc14e7a4059990f4e583092ad5c6d947c1c09a582435065637e1296eec816d12102b2758094c0665a0b469d176335e4639b368d420611dbf82d13dd5e1b1624b7868c5060459d8cdf80619f75625f4561df9a3e7765dc388a2503bbcf3e01d962c8042f9de6bd39a6538ece99fe6dc399bfa390e8c8d9cce6452ebe7ba1945b0756ee39e4f1e636f5605cea4f4f2ba91f0a2f748827ad725d5177bfb5127b53c7827d385a12d4432a0a8a244bd62d8ee88d028009364b3d94fcd17e6f3f112b15c757a6d9e627937afffbeca1284d3f891a703cd57907289853bd917494d324df71a6e3b2518473233b998e232fab930850783928ff2946959551d8174fbc01ef357c05acdd40a564fe99b4b87fd79a0f247b0bffd1da7a635bb6720f9947f9b26866da04a96fa00b956d6255056d01627cbd41f88d7636b757e72e530c1f4855720d7b6370f2e89749bc85394b74ef46d446aae767aa298e0304c989eea99608f3f8802666778bbbf0f403edf9b8c1ddff3b0abdb2f914b4ff3157ebb9244c83910d2ff26e3f7bd2b4a41278da2e35914f3339eb60eb673d3094e114395921ec7f999b37e1132719b6bec3c4c20364b2635f8d68160f2b9c462482c7d569303df78c80b9c0bd14049a15985ea3aa5a6578a3b5c6b9f73b214f48ad797171f492bad5211b164a5561fdbdf0d8211dc5722a48b4de16de122ffc1f0fa5657489889862c63a3b82b4c7af7f30097eeaffd955659eefa7d2e1447b37fbf659367815b92dd28aa31cd569810dd7f429f2a486ddae7d5c131a667b2c5fca7bd757fa6a802dc0a288dc3a7d92391f496186a32132bc879c0c4042f87432b1cdbe569da105d325097d821c193e3b106bea48a55164bd7d2de0c08bf7d3f2772961cf3b31c5f07a61de7c1d3738cb3eab256992e568cbaa24103d892044f61f23dd296c23936c873c51e383d1b82144dc3e97e8b9f3b916f916590b29c93c9bcde6db01a557312778f562d5dd16877d1f6355a30b29c0ec52cd2ae11171e93db29f57896b6567d6ab74d7ceea804dfd8a0910a5ee2df875427853c2da123307bb0dd59181dfedd9783e4e85a86365b58260a9fb67d644b08dad713428f6306a0ed4973c9f9b9b6658d1fd4693b5da341dd5194d5942ea677b93be4d9c73c548e38092341a411ce321f986e553ff6745dc2464816b8422c935c0f40633a5771d7b3edddc1648e2b453308200d79af05b952d17aa994a1d1d8fbbdf68ded95051324de11b9ff90bd2e9af81625a8d1cd5285bd1e6f0e039a5d2e5b43aa49197ea123b3481c60fa99d43185098683ee4620e871fd1b9118c6998eb4bb9d1dea490b8222218f5792fce4f516a849c15a6ed5c5bc564d122f34c37c22439b4d450223a340729b42c7fe162a08fc2af542dbe8f3492330c8b2f107de7d2ddf172a0deb5df3a94a081968b5b5a321f3a3a5ac94d46dcb12e6f7b889a7dcf96f1e48562be67dca745f5f1d8f2c36fca37ee8cea56414933c655e91a595e3940cee08215963559728f4dbbd32900d1fc23a62fa75dfff13db343b85c73a6aba40d7d3ecc9a44e434d179bfa2636a7cb3b8adfdca3f76a96d3f3baaaf1aaba183c3deec644305f6f7d1fdcc798e36fb2d675aa376a4f12c6aa342214dc1bb979698e71e9a6b67a709e34822f6454c866dcfa7b60f91833346643c2dd12bf0b0f1575133e6905a5e0b28773c9697a47cea5c7d7c1e62bf283b4f6243523e887b566e56a1372f297bb3e33"}, + {"00000000000000000000000000000000000000000000000000000000000022de", "007f388bed6b91756ea3e0866716ef6e9485fae6160195c7cda5c1e43f96ee359e105bcf4e8c293690420939124f04a0196363910421187811575929db40500b0bfdd1e8964aa334b801e3339a336d585a30852f1dc294a2d3d36f9ecc747458f3d41b4572415496df2a9fb1f882156cdabf9f65e681f38019865d6d47482277e24c9b8973eb34a41254faae4c5e2caa9dde5925ec118f3d8fa767ae00f434645957154367afe72000c59c79182c8faddd24424b9ebbb09ccd651b00540c96b9c7eec648a28a1d72c2e575d0f2250078511a011598db8e0788edf0ddc15ae24b62f63d6f93f71a2743a3c43ece55471a9802a76f31561a6f365c3647029bfa736395883afc0632bc25d4a8661b25d5aa0310f3c3fd3a183e75d359d6de3e5910b5dfbb74b7660af906917dc42b12e3e484aae1dbd20eaee037ef301572b7fc24d85b4aff9c82b27dcd421cee1639230d0188fec59f0dd4c0ced69c1ad07abd23692b1bd30735af942df597dcf6f403a36371bc416cf3e29a58570f586b05c357dc49515689788ad9581b8887dd913a41dc35e1ac9c9f9f4ea534eb6b36cc8af0299b6d3905750425da0366bdc59a7824477d7946b6f35c4ec90b8e61790fa74a4fa92396ea856661027828d40abb11dbe36bba516fe8ec8913106677285a4790d8034d1d1bf9fd87990889ddffc369b954a3d1c172be7e1812226c2b100cbe82c42bf4423456b6cb2bac3b4828135cb54f7a933a01f7f4a2057ad92136ba8e19fec313b412d43c089a71f06fd1625329b78d49ac92c59e4080932ddb1645910fd874dfb1f358e214231f62041acc41fd2c4e7b7127b3042459e1457f6b307fce9825aa4d2b942277f52665f2a77dd107b4f16cb3280f20c7551ff6cd855f97a6144131f69bab5648fb4b81261eefbf629094e8bcc4e36077f46d51a647da51fc01dca9a9ac12e2f7e2e2b1c9229dae099e95370177143d3b38ab661f19758494a01b32f0c27155b45a872a867dc50f9d76473695e9e2c4f9357f5ba6bb6c455d985f4e2c21486fde6576c6a8ceda6e010a7dc2b504130f429ac33376781ee4af5bbe8d768005bc4cb5092b15c4f296a8bd8c54a298eecd790a5161755a8605cc46bf890b8ff93d508501842b78c7261e5deeb1096891c528a300e57bf2f0aa9e8af2623cdf16bba20427704120484b6af8be26e4983d2685c783ce85d0174f84598719c6beefcc3603a94d4aa62750725df50671d7f9903ec255f779643ebd2fd8122fae3319e61928dcdaa44880d6a483140de63d2d7d7dc9dd449e0ee00d908e0f2164fc054198641e8fb0d74279c9b4117884b9335028a9f50c7223d3c03675ecf73329e52603f77f20cffba99356e51a365b75825f7db56d77542784f3c2663c493a2e564d73f753e9d6ebb0c2f2027a2330a7117c67a20507474fc47282a02cb572de17bbc7a335959316f74a05e3687cfb5227bc5b1b7f084f50902760e77740d420df9a495521c09b911e5f199a8343918b8386fc74f22552a76524a22c8c70ff06084e7fefe9b3ab98e004fadf35eb5f60483f287851712d90ebdd6b512877170d3b7fb34f16813917ae3b5ed54ede6081bdd7cc646fb336658121fd8fbafc52959b48d13375dfa4ce8616c157533a05ee1dc1120f215c348b54357d68adb4da7f5f48d55c005b3e7a23d05746e44d968f7601d4dbdff702861030d6e3a4140e6e1a29978be541f713f8e2cc9aa1ac32fecc941ee4aa4c41bc7f91ea5328ff87cbf35a8de17d1d3d1ad6d4384b0df52d10b3984d62e1678e86dd150ee425490bc727ee7107fda0f5d2433ab1c5d407be9d123fad5c201355601d926d3923787be86a4aa5be0b8d5750171ad658f8e97798b5dcaed46345a9af70c441"}, }; -/* TODO: Regenerate miner tests after launch // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { @@ -144,6 +143,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) CMutableTransaction tx,tx2; CScript script; uint256 hash; + TestMemPoolEntryHelper entry; + entry.nFee = 11; + entry.dPriority = 111.0; + entry.nHeight = 11; LOCK(cs_main); fCheckpointsEnabled = false; @@ -166,6 +169,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // will be closer to the tip, and blocks will appear slower. pblock->nTime = chainActive.Tip()->GetMedianTimePast()+6*Params().GetConsensus().nPowTargetSpacing; CMutableTransaction txCoinbase(pblock->vtx[0]); + txCoinbase.nVersion = 1; txCoinbase.vin[0].scriptSig = CScript() << (chainActive.Height()+1) << OP_0; txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = CTransaction(txCoinbase); @@ -175,7 +179,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) pblock->nNonce = uint256S(blockinfo[i].nonce_hex); pblock->nSolution = ParseHex(blockinfo[i].solution_hex); -*//* +/* { arith_uint256 try_nonce(0); unsigned int n = Params().EquihashN(); @@ -254,7 +258,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) std::cout << "\"}," << std::endl; } -*//* +*/ CValidationState state; BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL)); @@ -281,7 +285,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 10; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -301,7 +306,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 350; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + bool spendsCoinbase = (i == 0) ? true : false; // only first tx spends coinbase + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx)); tx.vin[0].prevout.hash = hash; } BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -310,7 +316,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // orphan in mempool hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -320,7 +326,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 39000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; @@ -328,7 +334,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[1].prevout.n = 0; tx.vout[0].nValue = 49000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -339,7 +345,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; tx.vout[0].nValue = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -352,12 +358,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) script = CScript() << OP_0; tx.vout[0].scriptPubKey = GetScriptForDestination(CScriptID(script)); hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vin[0].prevout.hash = hash; tx.vin[0].scriptSig = CScript() << (std::vector)script; tx.vout[0].nValue -= 10000; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -368,10 +374,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 49000LL; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -397,7 +403,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].scriptPubKey = CScript() << OP_1; tx.nLockTime = chainActive.Tip()->nHeight+1; hash = tx.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); BOOST_CHECK(!CheckFinalTx(tx, LOCKTIME_MEDIAN_TIME_PAST)); // time locked @@ -411,12 +417,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx2.vout[0].scriptPubKey = CScript() << OP_1; tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; hash = tx2.GetHash(); - mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); + mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx2)); BOOST_CHECK(!CheckFinalTx(tx2, LOCKTIME_MEDIAN_TIME_PAST)); BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); - // Neither tx should have make it into the template. + // Neither tx should have made it into the template. BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); delete pblocktemplate; @@ -443,6 +449,5 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) fCheckpointsEnabled = true; fCoinbaseEnforcedProtectionEnabled = true; } -*/ BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 6b189a6b5..a7decc94e 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/upgrades.h" #include "key.h" #include "keystore.h" #include "main.h" @@ -26,9 +27,9 @@ typedef vector valtype; BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup) CScript -sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn) +sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, int whichIn, uint32_t consensusBranchId) { - uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL); + uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, consensusBranchId); CScript result; result << OP_0; // CHECKMULTISIG bug workaround @@ -44,10 +45,12 @@ sign_multisig(CScript scriptPubKey, vector keys, CTransaction transaction, BOOST_AUTO_TEST_CASE(multisig_verify) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; ScriptError err; CKey key[4]; + CAmount amount = 0; for (int i = 0; i < 4; i++) key[i].MakeNewKey(true); @@ -82,21 +85,21 @@ BOOST_AUTO_TEST_CASE(multisig_verify) // Test a AND b: keys.assign(1,key[0]); keys.push_back(key[1]); - s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err)); + s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId); + BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); - s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i)); + s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err), strprintf("a&b 1: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); keys.assign(1,key[1]); keys.push_back(key[i]); - s = sign_multisig(a_and_b, keys, txTo[0], 0); - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i)); + s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err), strprintf("a&b 2: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -104,21 +107,21 @@ BOOST_AUTO_TEST_CASE(multisig_verify) for (int i = 0; i < 4; i++) { keys.assign(1,key[i]); - s = sign_multisig(a_or_b, keys, txTo[1], 0); + s = sign_multisig(a_or_b, keys, txTo[1], 0, consensusBranchId); if (i == 0 || i == 1) { - BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } s.clear(); s << OP_0 << OP_1; - BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err)); + BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err)); @@ -127,15 +130,15 @@ BOOST_AUTO_TEST_CASE(multisig_verify) { keys.assign(1,key[i]); keys.push_back(key[j]); - s = sign_multisig(escrow, keys, txTo[2], 0); + s = sign_multisig(escrow, keys, txTo[2], 0, consensusBranchId); if (i < j && i < 3 && j < 3) { - BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j)); + BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), consensusBranchId, &err), strprintf("escrow 1: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } else { - BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j)); + BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), consensusBranchId, &err), strprintf("escrow 2: %d %d", i, j)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } } @@ -276,6 +279,8 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) BOOST_AUTO_TEST_CASE(multisig_Sign) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Test SignSignature() (and therefore the version of Solver() that signs transactions) CBasicKeyStore keystore; CKey key[4]; @@ -312,7 +317,7 @@ BOOST_AUTO_TEST_CASE(multisig_Sign) for (int i = 0; i < 3; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i)); } } diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index 8837e56c3..a530749e7 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -16,6 +16,7 @@ BOOST_FIXTURE_TEST_SUITE(policyestimator_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) { CTxMemPool mpool(CFeeRate(1000)); + TestMemPoolEntryHelper entry; CAmount basefee(2000); double basepri = 1e6; CAmount deltaFee(100); @@ -63,7 +64,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); txHashes[j].push_back(hash); } } @@ -132,7 +133,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); txHashes[j].push_back(hash); } } @@ -168,7 +169,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 5; k++) { // add 4 fee txs for every priority tx tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, CTxMemPoolEntry(tx, feeV[k/4][j], GetTime(), priV[k/4][j], blocknum, mpool.HasNoInputsOf(tx))); + mpool.addUnchecked(hash, entry.Fee(feeV[k/4][j]).Time(GetTime()).Priority(priV[k/4][j]).Height(blocknum).FromTx(tx, &mpool)); CTransaction btx; if (mpool.lookup(hash, btx)) block.push_back(btx); @@ -187,9 +188,8 @@ BOOST_AUTO_TEST_CASE(TxConfirmStats_FindBucketIndex) { std::vector buckets {0.0, 3.5, 42.0}; TxConfirmStats txcs; - txcs.Initialize(buckets, MAX_BLOCK_CONFIRMS, DEFAULT_DECAY, "Test"); - + BOOST_CHECK_EQUAL(txcs.FindBucketIndex(-1.0), 0); BOOST_CHECK_EQUAL(txcs.FindBucketIndex(0.0), 0); BOOST_CHECK_EQUAL(txcs.FindBucketIndex(1.0), 1); diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index e7e627ae0..8bdff9700 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -42,22 +42,18 @@ BOOST_AUTO_TEST_CASE(reverselock_errors) BOOST_CHECK(failed); BOOST_CHECK(!lock.owns_lock()); - // Make sure trying to lock a lock after it has been reverse locked fails - failed = false; - bool locked = false; + // Locking the original lock after it has been taken by a reverse lock + // makes no sense. Ensure that the original lock no longer owns the lock + // after giving it to a reverse one. lock.lock(); BOOST_CHECK(lock.owns_lock()); - - try { + { reverse_lock > rlock(lock); - lock.lock(); - locked = true; - } catch(...) { - failed = true; + BOOST_CHECK(!lock.owns_lock()); } - BOOST_CHECK(locked && failed); + BOOST_CHECK(failed); BOOST_CHECK(lock.owns_lock()); } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index c2b29ab67..16c713300 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -7,6 +7,7 @@ #include "base58.h" #include "netbase.h" +#include "utilstrencodings.h" #include "test/test_bitcoin.h" @@ -251,7 +252,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK(banned_until.get_int64() > now); BOOST_CHECK(banned_until.get_int64()-now <= 200); - // must throw an exception because 127.0.0.1 is in already banned suubnet range + // must throw an exception because 127.0.0.1 is in already banned subnet range BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.1 add")), runtime_error); BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0/24 remove")));; @@ -295,4 +296,44 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); } + +BOOST_AUTO_TEST_CASE(rpc_raw_create_overwinter_v3) +{ + SelectParams(CBaseChainParams::REGTEST); + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::ALWAYS_ACTIVE); + + // Sample regtest address: + // public: tmHU5HLMu3yS8eoNvbrU1NWeJaGf6jxehru + // private: cW1G4SxEm5rui2RQtBcSUZrERTVYPtyZXKbSi5MCwBqzbn5kqwbN + + UniValue r; + std::string prevout = + "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"," + "\"vout\":1}]"; + r = CallRPC(string("createrawtransaction ") + prevout + " " + + "{\"tmHU5HLMu3yS8eoNvbrU1NWeJaGf6jxehru\":11}"); + std::string rawhex = r.get_str(); + BOOST_CHECK_NO_THROW(r = CallRPC(string("decoderawtransaction ") + rawhex)); + BOOST_CHECK_EQUAL(find_value(r.get_obj(), "overwintered").get_bool(), true); + BOOST_CHECK_EQUAL(find_value(r.get_obj(), "version").get_int(), 3); + BOOST_CHECK_EQUAL(find_value(r.get_obj(), "expiryheight").get_int(), 21); + BOOST_CHECK_EQUAL( + ParseHexToUInt32(find_value(r.get_obj(), "versiongroupid").get_str()), + OVERWINTER_VERSION_GROUP_ID); + + // Sanity check we can deserialize the raw hex + // 030000807082c40301f393847c97508f24b772281deea475cd3e0f719f321794e5da7cf8587e28ccb40100000000ffffffff0100ab9041000000001976a914550dc92d3ff8d1f0cb6499fddf2fe43b745330cd88ac000000000000000000 + CDataStream ss(ParseHex(rawhex), SER_DISK, PROTOCOL_VERSION); + CTransaction tx; + ss >> tx; + CDataStream ss2(ParseHex(rawhex), SER_DISK, PROTOCOL_VERSION); + CMutableTransaction mtx; + ss2 >> mtx; + BOOST_CHECK_EQUAL(tx.GetHash().GetHex(), CTransaction(mtx).GetHash().GetHex()); + + // Revert to default + UpdateNetworkUpgradeParameters(Consensus::UPGRADE_OVERWINTER, Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT); +} + + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index e1fcd8829..e7cc0570f 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -16,7 +16,10 @@ #include "rpcserver.h" #include "asyncrpcqueue.h" #include "asyncrpcoperation.h" +#include "wallet/asyncrpcoperation_mergetoaddress.h" #include "wallet/asyncrpcoperation_sendmany.h" +#include "wallet/asyncrpcoperation_shieldcoinbase.h" + #include "rpcprotocol.h" #include "init.h" @@ -44,6 +47,13 @@ bool find_error(const UniValue& objError, const std::string& expected) { return find_value(objError, "message").get_str().find(expected) != string::npos; } +static UniValue ValueFromString(const std::string &str) +{ + UniValue value; + BOOST_CHECK(value.setNumStr(str)); + return value; +} + BOOST_FIXTURE_TEST_SUITE(rpc_wallet_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_addmultisig) @@ -289,20 +299,20 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance) LOCK(pwalletMain->cs_wallet); - + BOOST_CHECK_THROW(CallRPC("z_getbalance too many args"), runtime_error); BOOST_CHECK_THROW(CallRPC("z_getbalance invalidaddress"), runtime_error); BOOST_CHECK_NO_THROW(CallRPC("z_getbalance tmC6YZnCUhm19dEXxh3Jb7srdBJxDawaCab")); BOOST_CHECK_THROW(CallRPC("z_getbalance tmC6YZnCUhm19dEXxh3Jb7srdBJxDawaCab -1"), runtime_error); BOOST_CHECK_NO_THROW(CallRPC("z_getbalance tmC6YZnCUhm19dEXxh3Jb7srdBJxDawaCab 0")); BOOST_CHECK_THROW(CallRPC("z_getbalance tnRZ8bPq2pff3xBWhTJhNkVUkm2uhzksDeW5PvEa7aFKGT9Qi3YgTALZfjaY4jU3HLVKBtHdSXxoPoLA3naMPcHBcY88FcF 1"), runtime_error); - - + + BOOST_CHECK_THROW(CallRPC("z_gettotalbalance too manyargs"), runtime_error); BOOST_CHECK_THROW(CallRPC("z_gettotalbalance -1"), runtime_error); BOOST_CHECK_NO_THROW(CallRPC("z_gettotalbalance 0")); - - + + BOOST_CHECK_THROW(CallRPC("z_listreceivedbyaddress too many args"), runtime_error); // negative minconf not allowed BOOST_CHECK_THROW(CallRPC("z_listreceivedbyaddress tmC6YZnCUhm19dEXxh3Jb7srdBJxDawaCab -1"), runtime_error); @@ -374,7 +384,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) CZCPaymentAddress paymentAddress = pwalletMain->GenerateNewZKey(); pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==1); - + // Set up paths boost::filesystem::path tmppath = boost::filesystem::temp_directory_path(); boost::filesystem::path tmpfilename = boost::filesystem::unique_path("%%%%%%%%"); @@ -402,10 +412,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) std::string s1 = paymentAddress.ToString(); std::string s2 = CZCSpendingKey(key).ToString(); - + // There's no way to really delete a private key so we will read in the // exported wallet file and search for the spending key and payment address. - + EnsureWalletIsUnlocked(); ifstream file; @@ -434,7 +444,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet) BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) { LOCK2(cs_main, pwalletMain->cs_wallet); - + // error if no args BOOST_CHECK_THROW(CallRPC("z_importwallet"), runtime_error); @@ -446,7 +456,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) auto testPaymentAddress = testSpendingKey.address(); std::string testAddr = CZCPaymentAddress(testPaymentAddress).ToString(); std::string testKey = CZCSpendingKey(testSpendingKey).ToString(); - + // create test data using the random key std::string format_str = "# Wallet dump created by Komodo v0.11.2.0.z8-9155cc6-dirty (2016-08-11 11:37:00 -0700)\n" "# * Created on 2016-08-12T21:55:36Z\n" @@ -458,10 +468,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) "%s 2016-08-12T21:55:36Z # zaddr=%s\n" "\n" "\n# End of dump"; - + boost::format formatobject(format_str); std::string testWalletDump = (formatobject % testKey % testAddr).str(); - + // write test data to file boost::filesystem::path temp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); @@ -474,19 +484,19 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) std::set addrs; pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==0); - + // import test data from file into wallet BOOST_CHECK_NO_THROW(CallRPC(string("z_importwallet ") + path)); - + // wallet should now have one zkey pwalletMain->GetPaymentAddresses(addrs); BOOST_CHECK(addrs.size()==1); - + // check that we have the spending key for the address CZCPaymentAddress address(testAddr); auto addr = address.Get(); BOOST_CHECK(pwalletMain->HaveSpendingKey(addr)); - + // Verify the spending key is the same as the test data libzcash::SpendingKey k; BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k)); @@ -504,10 +514,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) UniValue retValue; int n1 = 1000; // number of times to import/export int n2 = 1000; // number of addresses to create and list - + // error if no args - BOOST_CHECK_THROW(CallRPC("z_importkey"), runtime_error); - BOOST_CHECK_THROW(CallRPC("z_exportkey"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_importkey"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_exportkey"), runtime_error); // error if too many args BOOST_CHECK_THROW(CallRPC("z_importkey way too many args"), runtime_error); @@ -548,7 +558,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) for (UniValue element : arr.getValues()) { myaddrs.insert(element.get_str()); } - + // Make new addresses for the set for (int i=0; iGenerateNewZKey()).ToString()); @@ -558,19 +568,19 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) int numAddrs = myaddrs.size(); BOOST_CHECK(numAddrs == n1+n2); pwalletMain->GetPaymentAddresses(addrs); - BOOST_CHECK(addrs.size()==numAddrs); - + BOOST_CHECK(addrs.size()==numAddrs); + // Ask wallet to list addresses BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); arr = retValue.get_array(); BOOST_CHECK(arr.size() == numAddrs); - + // Create a set from them std::unordered_set listaddrs; for (UniValue element : arr.getValues()) { listaddrs.insert(element.get_str()); } - + // Verify the two sets of addresses are the same BOOST_CHECK(listaddrs.size() == numAddrs); BOOST_CHECK(myaddrs == listaddrs); @@ -623,19 +633,19 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations) BOOST_CHECK(ids.size()==0); std::shared_ptr op1 = std::make_shared(); - q->addOperation(op1); + q->addOperation(op1); BOOST_CHECK(q->getOperationCount() == 1); - + OperationStatus status = op1->getState(); BOOST_CHECK(status == OperationStatus::READY); - + AsyncRPCOperationId id1 = op1->getId(); int64_t creationTime1 = op1->getCreationTime(); - + q->addWorker(); BOOST_CHECK(q->getNumberOfWorkers() == 1); - - // an AsyncRPCOperation doesn't do anything so will finish immediately + + // an AsyncRPCOperation doesn't do anything so will finish immediately std::this_thread::sleep_for(std::chrono::seconds(1)); BOOST_CHECK(q->getOperationCount() == 0); @@ -649,7 +659,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations) BOOST_CHECK_EQUAL(op1->getResult().isNull(), false); BOOST_CHECK_EQUAL(op1->getStateAsString(), "success"); BOOST_CHECK_NE(op1->getStateAsString(), "executing"); - + // Create a second operation which just sleeps std::shared_ptr op2(new MockSleepOperation(2500)); AsyncRPCOperationId id2 = op2->getId(); @@ -683,8 +693,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations) BOOST_CHECK_EQUAL(op2->isSuccess(), true); BOOST_CHECK_EQUAL(op2->isCancelled(), false); BOOST_CHECK_EQUAL(op3->isCancelled(), true); - - + + v = q->getAllOperationIds(); std::copy( v.begin(), v.end(), std::inserter( opids, opids.end() ) ); BOOST_CHECK(opids.size() == 3); @@ -702,7 +712,7 @@ class CountOperation : public AsyncRPCOperation { public: CountOperation() {} virtual ~CountOperation() {} - virtual void main() { + virtual void main() { set_state(OperationStatus::EXECUTING); gCounter++; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); @@ -714,7 +724,7 @@ public: BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations_parallel_wait) { gCounter = 0; - + std::shared_ptr q = std::make_shared(); q->addWorker(); q->addWorker(); @@ -739,7 +749,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations_parallel_wait) BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations_parallel_cancel) { gCounter = 0; - + std::shared_ptr q = std::make_shared(); q->addWorker(); q->addWorker(); @@ -755,7 +765,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations_parallel_cancel) q->closeAndWait(); int numSuccess = 0; - int numCancelled = 0; + int numCancelled = 0; for (auto & id : ids) { std::shared_ptr ptr = q->popOperationForId(id); if (ptr->isCancelled()) { @@ -764,7 +774,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations_parallel_cancel) numSuccess++; } } - + BOOST_CHECK_EQUAL(numOperations, numSuccess+numCancelled); BOOST_CHECK_EQUAL(gCounter.load(), numSuccess); BOOST_CHECK(q->getOperationCount() == 0); @@ -790,19 +800,19 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations) BOOST_CHECK_NO_THROW(CallRPC("z_getoperationresult [\"opid-1234\"]")); BOOST_CHECK_THROW(CallRPC("z_getoperationresult [] toomanyargs"), runtime_error); BOOST_CHECK_THROW(CallRPC("z_getoperationresult not_an_array"), runtime_error); - + std::shared_ptr op1 = std::make_shared(); q->addOperation(op1); std::shared_ptr op2 = std::make_shared(); q->addOperation(op2); - + BOOST_CHECK(q->getOperationCount() == 2); BOOST_CHECK(q->getNumberOfWorkers() == 0); q->addWorker(); BOOST_CHECK(q->getNumberOfWorkers() == 1); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); BOOST_CHECK(q->getOperationCount() == 0); - + // Check if too many args BOOST_CHECK_THROW(CallRPC("z_listoperationids toomany args"), runtime_error); @@ -817,28 +827,28 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations) // idempotent BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getoperationstatus")); array = retValue.get_array(); - BOOST_CHECK(array.size() == 2); - + BOOST_CHECK(array.size() == 2); + for (UniValue v : array.getValues()) { UniValue obj = v.get_obj(); UniValue id = find_value(obj, "id"); - + UniValue result; // removes result from internal storage BOOST_CHECK_NO_THROW(result = CallRPC("z_getoperationresult [\"" + id.get_str() + "\"]")); UniValue resultArray = result.get_array(); BOOST_CHECK(resultArray.size() == 1); - + UniValue resultObj = resultArray[0].get_obj(); UniValue resultId = find_value(resultObj, "id"); BOOST_CHECK_EQUAL(id.get_str(), resultId.get_str()); - - // verify the operation has been removed + + // verify the operation has been removed BOOST_CHECK_NO_THROW(result = CallRPC("z_getoperationresult [\"" + id.get_str() + "\"]")); resultArray = result.get_array(); BOOST_CHECK(resultArray.size() == 0); } - + // operations removed BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getoperationstatus")); array = retValue.get_array(); @@ -905,29 +915,37 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) std::string zaddr1 = pa.ToString(); BOOST_CHECK_THROW(CallRPC(string("z_sendmany tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ ") + "[{\"address\":\"" + zaddr1 + "\", \"amount\":123.456}]"), runtime_error); - - // Test constructor of AsyncRPCOperation_sendmany + + // Mutable tx containing contextual information we need to build tx + UniValue retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + if (mtx.nVersion == 1) { + mtx.nVersion = 2; + } + + // Test constructor of AsyncRPCOperation_sendmany try { - std::shared_ptr operation(new AsyncRPCOperation_sendmany("",{}, {}, -1)); + std::shared_ptr operation(new AsyncRPCOperation_sendmany(mtx, "",{}, {}, -1)); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "Minconf cannot be negative")); } try { - std::shared_ptr operation(new AsyncRPCOperation_sendmany("",{}, {}, 1)); + std::shared_ptr operation(new AsyncRPCOperation_sendmany(mtx, "",{}, {}, 1)); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "From address parameter missing")); } try { - std::shared_ptr operation( new AsyncRPCOperation_sendmany("tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) ); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "No recipients")); } try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany("INVALID", recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, "INVALID", recipients, {}, 1) ); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "payment address is invalid")); } @@ -935,7 +953,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) // Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix. try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany("zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) ); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "payment address is for wrong network type")); } @@ -944,7 +962,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) // invokes a method on pwalletMain, which is undefined in the google test environment. try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany("ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, "ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) ); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "no spending key found for zaddr")); } @@ -959,27 +977,47 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) LOCK(pwalletMain->cs_wallet); UniValue retValue; - + + // Mutable tx containing contextual information we need to build tx + retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + if (mtx.nVersion == 1) { + mtx.nVersion = 2; + } + // add keys manually BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress")); std::string taddr1 = retValue.get_str(); CZCPaymentAddress pa = pwalletMain->GenerateNewZKey(); std::string zaddr1 = pa.ToString(); - + // there are no utxos to spend { std::vector recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany(taddr1, {}, recipients, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, taddr1, {}, recipients, 1) ); operation->main(); BOOST_CHECK(operation->isFailed()); std::string msg = operation->getErrorMessage(); BOOST_CHECK( msg.find("Insufficient funds, no UTXOs found") != string::npos); } - + + // minconf cannot be zero when sending from zaddr + { + try { + std::vector recipients = {SendManyRecipient(taddr1, 100.0, "DEADBEEF")}; + std::shared_ptr operation(new AsyncRPCOperation_sendmany(mtx, zaddr1, recipients, {}, 0)); + BOOST_CHECK(false); // Fail test if an exception is not thrown + } catch (const UniValue& objError) { + BOOST_CHECK(find_error(objError, "Minconf cannot be zero when sending from zaddr")); + } + } + + // there are no unspent notes to spend { std::vector recipients = { SendManyRecipient(taddr1,100.0, "DEADBEEF") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, recipients, {}, 1) ); operation->main(); BOOST_CHECK(operation->isFailed()); std::string msg = operation->getErrorMessage(); @@ -989,10 +1027,10 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) // get_memo_from_hex_string()) { std::vector recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr ptr = std::dynamic_pointer_cast (operation); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); - + std::string memo = "DEADBEEF"; boost::array array = proxy.get_memo_from_hex_string(memo); BOOST_CHECK_EQUAL(array[0], 0xDE); @@ -1002,28 +1040,28 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) for (int i=4; i v (2 * (ZC_MEMO_SIZE+1)); std::fill(v.begin(),v.end(), 'A'); std::string bigmemo(v.begin(), v.end()); - + try { proxy.get_memo_from_hex_string(bigmemo); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "too big")); } - + // invalid hexadecimal string std::fill(v.begin(),v.end(), '@'); // not a hex character std::string badmemo(v.begin(), v.end()); - + try { proxy.get_memo_from_hex_string(badmemo); } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "hexadecimal format")); } - + // odd length hexadecimal string std::fill(v.begin(),v.end(), 'A'); v.resize(v.size() - 1); @@ -1035,33 +1073,31 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_CHECK( find_error(objError, "hexadecimal format")); } } - - + + // add_taddr_change_output_to_tx() will append a vout to a raw transaction { std::vector recipients = { SendManyRecipient(zaddr1,100.0, "DEADBEEF") }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr ptr = std::dynamic_pointer_cast (operation); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); - + CTransaction tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 0); - - CAmount amount = 123.456; - proxy.add_taddr_change_output_to_tx(0,amount); + CAmount amount = AmountFromValue(ValueFromString("123.456")); + proxy.add_taddr_change_output_to_tx(amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 1); CTxOut out = tx.vout[0]; BOOST_CHECK_EQUAL(out.nValue, amount); - - amount = 1.111; - proxy.add_taddr_change_output_to_tx(0,amount); + amount = AmountFromValue(ValueFromString("1.111")); + proxy.add_taddr_change_output_to_tx(amount); tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 2); out = tx.vout[1]; BOOST_CHECK_EQUAL(out.nValue, amount); } - + // add_taddr_outputs_to_tx() will append many vouts to a raw transaction { std::vector recipients = { @@ -1069,36 +1105,36 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) SendManyRecipient("tmUSbHz3vxnwLvRyNDXbwkZxjVyDodMJEhh",CAmount(4.56), ""), SendManyRecipient("tmYZAXYPCP56Xa5JQWWPZuK7o7bfUQW6kkd",CAmount(7.89), ""), }; - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, recipients, {}, 1) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, recipients, {}, 1) ); std::shared_ptr ptr = std::dynamic_pointer_cast (operation); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); - + proxy.add_taddr_outputs_to_tx(); - + CTransaction tx = proxy.getTx(); BOOST_CHECK(tx.vout.size() == 3); BOOST_CHECK_EQUAL(tx.vout[0].nValue, CAmount(1.23)); BOOST_CHECK_EQUAL(tx.vout[1].nValue, CAmount(4.56)); BOOST_CHECK_EQUAL(tx.vout[2].nValue, CAmount(7.89)); } - + // Raw joinsplit is a zaddr->zaddr { std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", raw)); - + // we have the spending key for the dummy recipient zaddr1 std::vector recipients = { SendManyRecipient(zaddr1, 0.0005, "ABCD") }; - - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, {}, recipients, 1) ); + + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, {}, recipients, 1) ); std::shared_ptr ptr = std::dynamic_pointer_cast (operation); TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); - + // Enable test mode so tx is not sent static_cast(operation.get())->testmode = true; - + // Pretend that the operation completed successfully proxy.set_state(OperationStatus::SUCCESS); @@ -1110,21 +1146,21 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) std::string hex = find_value(resultObj, "hex").get_str(); BOOST_CHECK_EQUAL(hex, raw); } - - + + // Test the perform_joinsplit methods. { // Dummy input so the operation object can be instantiated. std::vector recipients = { SendManyRecipient(zaddr1, 0.0005, "ABCD") }; - - std::shared_ptr operation( new AsyncRPCOperation_sendmany(zaddr1, {}, recipients, 1) ); + + std::shared_ptr operation( new AsyncRPCOperation_sendmany(mtx, zaddr1, {}, recipients, 1) ); std::shared_ptr ptr = std::dynamic_pointer_cast (operation); - TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); + TEST_FRIEND_AsyncRPCOperation_sendmany proxy(ptr); // Enable test mode so tx is not sent and proofs are not generated static_cast(operation.get())->testmode = true; - - AsyncJoinSplitInfo info; + + AsyncJoinSplitInfo info; std::vector> witnesses; uint256 anchor; try { @@ -1146,7 +1182,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) } catch (const std::runtime_error & e) { BOOST_CHECK( string(e.what()).find("number of notes")!= string::npos); } - + info.notes.clear(); info.vjsin.push_back(JSInput()); info.vjsin.push_back(JSInput()); @@ -1156,15 +1192,15 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) } catch (const std::runtime_error & e) { BOOST_CHECK( string(e.what()).find("unsupported joinsplit input")!= string::npos); } - + info.vjsin.clear(); try { proxy.perform_joinsplit(info); } catch (const std::runtime_error & e) { - BOOST_CHECK( string(e.what()).find("JoinSplit verifying key not loaded")!= string::npos); + BOOST_CHECK( string(e.what()).find("error verifying joinsplit")!= string::npos); } } - + } @@ -1202,29 +1238,489 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys) boost::filesystem::current_path(GetArg("-datadir","/tmp/thisshouldnothappen")); BOOST_CHECK(pwalletMain->EncryptWallet(strWalletPass)); - + // Verify we can still list the keys imported BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); arr = retValue.get_array(); BOOST_CHECK(arr.size() == n); - + // Try to add a new key, but we can't as the wallet is locked BOOST_CHECK_THROW(CallRPC("z_getnewaddress"), runtime_error); - + // We can't call RPC walletpassphrase as that invokes RPCRunLater which breaks tests. // So we manually unlock. BOOST_CHECK(pwalletMain->Unlock(strWalletPass)); - + // Now add a key BOOST_CHECK_NO_THROW(CallRPC("z_getnewaddress")); - + // Verify the key has been added BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); arr = retValue.get_array(); - BOOST_CHECK(arr.size() == n+1); + BOOST_CHECK(arr.size() == n+1); // We can't simulate over RPC the wallet closing and being reloaded // but there are tests for this in gtest. } + + +BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_parameters) +{ + SelectParams(CBaseChainParams::TESTNET); + + LOCK(pwalletMain->cs_wallet); + + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase toofewargs"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase too many args shown here"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "INVALIDtmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "** tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad to address + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ INVALIDtnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // invalid fee amount, cannot be negative + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "-0.0001" + ), runtime_error); + + // invalid fee amount, bigger than MAX_MONEY + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "21000001" + ), runtime_error); + + // invalid limit, must be at least 0 + BOOST_CHECK_THROW(CallRPC("z_shieldcoinbase " + "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "100 -1" + ), runtime_error); + + // Mutable tx containing contextual information we need to build tx + UniValue retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + if (mtx.nVersion == 1) { + mtx.nVersion = 2; + } + + // Test constructor of AsyncRPCOperation_sendmany + std::string testnetzaddr = "ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP"; + std::string mainnetzaddr = "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U"; + + try { + std::shared_ptr operation(new AsyncRPCOperation_shieldcoinbase(mtx, {}, testnetzaddr, -1 )); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "Fee is out of range")); + } + + try { + std::shared_ptr operation(new AsyncRPCOperation_shieldcoinbase(mtx, {}, testnetzaddr, 1)); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "Empty inputs")); + } + + // Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix. + try { + std::vector inputs = { ShieldCoinbaseUTXO{uint256(),0,0} }; + std::shared_ptr operation( new AsyncRPCOperation_shieldcoinbase(mtx, inputs, mainnetzaddr, 1) ); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "payment address is for wrong network type")); + } + +} + + + +BOOST_AUTO_TEST_CASE(rpc_z_shieldcoinbase_internals) +{ + SelectParams(CBaseChainParams::TESTNET); + + LOCK(pwalletMain->cs_wallet); + + // Mutable tx containing contextual information we need to build tx + UniValue retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + if (mtx.nVersion == 1) { + mtx.nVersion = 2; + } + + // Test that option -mempooltxinputlimit is respected. + mapArgs["-mempooltxinputlimit"] = "1"; + + // Add keys manually + CZCPaymentAddress pa = pwalletMain->GenerateNewZKey(); + std::string zaddr = pa.ToString(); + + // Supply 2 inputs when mempool limit is 1 + { + std::vector inputs = { ShieldCoinbaseUTXO{uint256(),0,0}, ShieldCoinbaseUTXO{uint256(),0,0} }; + std::shared_ptr operation( new AsyncRPCOperation_shieldcoinbase(mtx, inputs, zaddr) ); + operation->main(); + BOOST_CHECK(operation->isFailed()); + std::string msg = operation->getErrorMessage(); + BOOST_CHECK( msg.find("Number of inputs 2 is greater than mempooltxinputlimit of 1") != string::npos); + } + + // Insufficient funds + { + std::vector inputs = { ShieldCoinbaseUTXO{uint256(),0,0} }; + std::shared_ptr operation( new AsyncRPCOperation_shieldcoinbase(mtx, inputs, zaddr) ); + operation->main(); + BOOST_CHECK(operation->isFailed()); + std::string msg = operation->getErrorMessage(); + BOOST_CHECK( msg.find("Insufficient coinbase funds") != string::npos); + } + + // Test the perform_joinsplit methods. + { + // Dummy input so the operation object can be instantiated. + std::vector inputs = { ShieldCoinbaseUTXO{uint256(),0,100000} }; + std::shared_ptr operation( new AsyncRPCOperation_shieldcoinbase(mtx, inputs, zaddr) ); + std::shared_ptr ptr = std::dynamic_pointer_cast (operation); + TEST_FRIEND_AsyncRPCOperation_shieldcoinbase proxy(ptr); + static_cast(operation.get())->testmode = true; + + ShieldCoinbaseJSInfo info; + info.vjsin.push_back(JSInput()); + info.vjsin.push_back(JSInput()); + info.vjsin.push_back(JSInput()); + try { + proxy.perform_joinsplit(info); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("unsupported joinsplit input")!= string::npos); + } + + info.vjsin.clear(); + try { + proxy.perform_joinsplit(info); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("error verifying joinsplit")!= string::npos); + } + } + +} + + +BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_parameters) +{ + SelectParams(CBaseChainParams::TESTNET); + + LOCK(pwalletMain->cs_wallet); + + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress toofewargs"), runtime_error); + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress just too many args present for this method"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"INVALIDtmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "** tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"**\"] tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad from address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ] tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // bad to address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] INVALIDtnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB"), runtime_error); + + // duplicate address + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\", \"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] " + "tmQP9L3s31cLsghVYf2Jb5MhKj1jRBPoeQn" + ), runtime_error); + + // invalid fee amount, cannot be negative + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "-0.0001" + ), runtime_error); + + // invalid fee amount, bigger than MAX_MONEY + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "21000001" + ), runtime_error); + + // invalid transparent limit, must be at least 0 + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "0.0001 -1" + ), runtime_error); + + // invalid shielded limit, must be at least 0 + BOOST_CHECK_THROW(CallRPC("z_mergetoaddress " + "[\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] " + "tnpoQJVnYBZZqkFadj2bJJLThNCxbADGB5gSGeYTAGGrT5tejsxY9Zc1BtY8nnHmZkB " + "0.0001 100 -1" + ), runtime_error); + + // memo bigger than allowed length of ZC_MEMO_SIZE + std::vector v (2 * (ZC_MEMO_SIZE+1)); // x2 for hexadecimal string format + std::fill(v.begin(),v.end(), 'A'); + std::string badmemo(v.begin(), v.end()); + CZCPaymentAddress pa = pwalletMain->GenerateNewZKey(); + std::string zaddr1 = pa.ToString(); + BOOST_CHECK_THROW(CallRPC(string("z_mergetoaddress [\"tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ\"] ") + + zaddr1 + " 0.0001 100 100 " + badmemo), runtime_error); + + // Mutable tx containing contextual information we need to build tx + UniValue retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + + // Test constructor of AsyncRPCOperation_mergetoaddress + MergeToAddressRecipient testnetzaddr( + "ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", + "testnet memo"); + MergeToAddressRecipient mainnetzaddr( + "zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", + "mainnet memo"); + + try { + std::shared_ptr operation(new AsyncRPCOperation_mergetoaddress(mtx, {}, {}, testnetzaddr, -1 )); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "Fee is out of range")); + } + + try { + std::shared_ptr operation(new AsyncRPCOperation_mergetoaddress(mtx, {}, {}, testnetzaddr, 1)); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "No inputs")); + } + + std::vector inputs = { MergeToAddressInputUTXO{ COutPoint{uint256(), 0}, 0} }; + + try { + MergeToAddressRecipient badaddr("", "memo"); + std::shared_ptr operation(new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, badaddr, 1)); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "Recipient parameter missing")); + } + + // Testnet payment addresses begin with 'zt'. This test detects an incorrect prefix. + try { + std::vector inputs = { MergeToAddressInputUTXO{ COutPoint{uint256(), 0}, 0} }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, mainnetzaddr, 1) ); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "payment address is for wrong network type")); + } +} + + +// TODO: test private methods +BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals) +{ + SelectParams(CBaseChainParams::TESTNET); + + LOCK(pwalletMain->cs_wallet); + + // Mutable tx containing contextual information we need to build tx + UniValue retValue = CallRPC("getblockcount"); + int nHeight = retValue.get_int(); + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nHeight + 1); + + // Test that option -mempooltxinputlimit is respected. + mapArgs["-mempooltxinputlimit"] = "1"; + + // Add keys manually + BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress")); + MergeToAddressRecipient taddr1(retValue.get_str(), ""); + CZCPaymentAddress pa = pwalletMain->GenerateNewZKey(); + MergeToAddressRecipient zaddr1(pa.ToString(), "DEADBEEF"); + + // Supply 2 inputs when mempool limit is 1 + { + std::vector inputs = { + MergeToAddressInputUTXO{COutPoint{uint256(),0},0}, + MergeToAddressInputUTXO{COutPoint{uint256(),0},0} + }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, zaddr1) ); + operation->main(); + BOOST_CHECK(operation->isFailed()); + std::string msg = operation->getErrorMessage(); + BOOST_CHECK( msg.find("Number of transparent inputs 2 is greater than mempooltxinputlimit of 1") != string::npos); + } + + // Insufficient funds + { + std::vector inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},0} }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, zaddr1) ); + operation->main(); + BOOST_CHECK(operation->isFailed()); + std::string msg = operation->getErrorMessage(); + BOOST_CHECK( msg.find("Insufficient funds, have 0.00 and miners fee is 0.0001") != string::npos); + } + + // get_memo_from_hex_string()) + { + std::vector inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000} }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, zaddr1) ); + std::shared_ptr ptr = std::dynamic_pointer_cast (operation); + TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); + + std::string memo = "DEADBEEF"; + boost::array array = proxy.get_memo_from_hex_string(memo); + BOOST_CHECK_EQUAL(array[0], 0xDE); + BOOST_CHECK_EQUAL(array[1], 0xAD); + BOOST_CHECK_EQUAL(array[2], 0xBE); + BOOST_CHECK_EQUAL(array[3], 0xEF); + for (int i=4; i v (2 * (ZC_MEMO_SIZE+1)); + std::fill(v.begin(),v.end(), 'A'); + std::string bigmemo(v.begin(), v.end()); + + try { + proxy.get_memo_from_hex_string(bigmemo); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "too big")); + } + + // invalid hexadecimal string + std::fill(v.begin(),v.end(), '@'); // not a hex character + std::string badmemo(v.begin(), v.end()); + + try { + proxy.get_memo_from_hex_string(badmemo); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "hexadecimal format")); + } + + // odd length hexadecimal string + std::fill(v.begin(),v.end(), 'A'); + v.resize(v.size() - 1); + assert(v.size() %2 == 1); // odd length + std::string oddmemo(v.begin(), v.end()); + try { + proxy.get_memo_from_hex_string(oddmemo); + BOOST_FAIL("Should have caused an error"); + } catch (const UniValue& objError) { + BOOST_CHECK( find_error(objError, "hexadecimal format")); + } + } + + // Test the perform_joinsplit methods. + { + // Dummy input so the operation object can be instantiated. + std::vector inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000} }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, zaddr1) ); + std::shared_ptr ptr = std::dynamic_pointer_cast (operation); + TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); + + // Enable test mode so tx is not sent and proofs are not generated + static_cast(operation.get())->testmode = true; + + MergeToAddressJSInfo info; + std::vector> witnesses; + uint256 anchor; + try { + proxy.perform_joinsplit(info, witnesses, anchor); + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("anchor is null")!= string::npos); + } + + try { + std::vector v; + proxy.perform_joinsplit(info, v); + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("anchor is null")!= string::npos); + } + + info.notes.push_back(Note()); + try { + proxy.perform_joinsplit(info); + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("number of notes")!= string::npos); + } + + info.notes.clear(); + info.vjsin.push_back(JSInput()); + info.vjsin.push_back(JSInput()); + info.vjsin.push_back(JSInput()); + try { + proxy.perform_joinsplit(info); + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("unsupported joinsplit input")!= string::npos); + } + + info.vjsin.clear(); + try { + proxy.perform_joinsplit(info); + BOOST_FAIL("Should have caused an error"); + } catch (const std::runtime_error & e) { + BOOST_CHECK( string(e.what()).find("error verifying joinsplit")!= string::npos); + } + } + + // Raw joinsplit is a zaddr->zaddr + { + std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("rawtxn", raw)); + + // we have the spending key for the dummy recipient zaddr1 + std::vector inputs = { MergeToAddressInputUTXO{COutPoint{uint256(),0},100000} }; + std::shared_ptr operation( new AsyncRPCOperation_mergetoaddress(mtx, inputs, {}, zaddr1) ); + std::shared_ptr ptr = std::dynamic_pointer_cast (operation); + TEST_FRIEND_AsyncRPCOperation_mergetoaddress proxy(ptr); + + // Enable test mode so tx is not sent + static_cast(operation.get())->testmode = true; + + // Pretend that the operation completed successfully + proxy.set_state(OperationStatus::SUCCESS); + + // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). + BOOST_CHECK_NO_THROW( proxy.sign_send_raw_transaction(obj) ); + UniValue result = operation->getResult(); + BOOST_CHECK(!result.isNull()); + UniValue resultObj = result.get_obj(); + std::string hex = find_value(resultObj, "hex").get_str(); + BOOST_CHECK_EQUAL(hex, raw); + } +} + + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp index cb1a427db..d6c93ef3b 100644 --- a/src/test/scheduler_tests.cpp +++ b/src/test/scheduler_tests.cpp @@ -30,14 +30,7 @@ static void microTask(CScheduler& s, boost::mutex& mutex, int& counter, int delt static void MicroSleep(uint64_t n) { -#if defined(HAVE_WORKING_BOOST_SLEEP_FOR) boost::this_thread::sleep_for(boost::chrono::microseconds(n)); -#elif defined(HAVE_WORKING_BOOST_SLEEP) - boost::this_thread::sleep(boost::posix_time::microseconds(n)); -#else - //should never get here - #error missing boost sleep implementation -#endif } BOOST_AUTO_TEST_CASE(manythreads) diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index c8cfe2872..209ff06c9 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -2,6 +2,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/upgrades.h" +#include "core_io.h" #include "key.h" #include "keystore.h" #include "main.h" @@ -31,6 +33,8 @@ Serialize(const CScript& s) static bool Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, ScriptError& err) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Create dummy to/from transactions: CMutableTransaction txFrom; txFrom.vout.resize(1); @@ -44,7 +48,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri txTo.vin[0].scriptSig = scriptSig; txTo.vout[0].nValue = 1; - return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0), &err); + return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), consensusBranchId, &err); } @@ -53,6 +57,7 @@ BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(sign) { LOCK(cs_main); + uint32_t consensusBranchId = SPROUT_BRANCH_ID; // Pay-to-script-hash looks like this: // scriptSig: // scriptPubKey: HASH160 EQUAL @@ -106,22 +111,24 @@ BOOST_AUTO_TEST_CASE(sign) } for (int i = 0; i < 8; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i)); } // All of the above should be OK, and the txTos have valid signatures // Check to make sure signature verification fails if we use the wrong ScriptSig: - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { + PrecomputedTransactionData txdata(txTo[i]); for (int j = 0; j < 8; j++) { CScript sigSave = txTo[i].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; - bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); + bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, consensusBranchId, &txdata)(); if (i == j) BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); else BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j)); txTo[i].vin[0].scriptSig = sigSave; } + } } BOOST_AUTO_TEST_CASE(norecurse) @@ -154,6 +161,7 @@ BOOST_AUTO_TEST_CASE(norecurse) BOOST_AUTO_TEST_CASE(set) { LOCK(cs_main); + uint32_t consensusBranchId = SPROUT_BRANCH_ID; // Test the CScript::Set* methods CBasicKeyStore keystore; CKey key[4]; @@ -203,7 +211,7 @@ BOOST_AUTO_TEST_CASE(set) } for (int i = 0; i < 4; i++) { - BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); + BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i)); BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i)); } } @@ -262,6 +270,7 @@ BOOST_AUTO_TEST_CASE(switchover) BOOST_AUTO_TEST_CASE(AreInputsStandard) { LOCK(cs_main); + uint32_t consensusBranchId = SPROUT_BRANCH_ID; CCoinsView coinsDummy; CCoinsViewCache coins(&coinsDummy); CBasicKeyStore keystore; @@ -332,16 +341,16 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txTo.vin[i].prevout.n = i; txTo.vin[i].prevout.hash = txFrom.GetHash(); } - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0)); - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1)); - BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1, SIGHASH_ALL, consensusBranchId)); + BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2, SIGHASH_ALL, consensusBranchId)); // SignSignature doesn't know how to sign these. We're // not testing validating signatures, so just create // dummy signatures that DO include the correct P2SH scripts: txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast >(oneAndTwo); txTo.vin[4].scriptSig << static_cast >(fifteenSigops); - BOOST_CHECK(::AreInputsStandard(txTo, coins)); + BOOST_CHECK(::AreInputsStandard(txTo, coins, consensusBranchId)); // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4] BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 22U); @@ -350,7 +359,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) { CScript t = txTo.vin[i].scriptSig; txTo.vin[i].scriptSig = (CScript() << 11) + t; - BOOST_CHECK(!::AreInputsStandard(txTo, coins)); + BOOST_CHECK(!::AreInputsStandard(txTo, coins, consensusBranchId)); txTo.vin[i].scriptSig = t; } @@ -363,7 +372,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd1.vin[0].prevout.hash = txFrom.GetHash(); txToNonStd1.vin[0].scriptSig << static_cast >(sixteenSigops); - BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins)); + BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins, consensusBranchId)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U); CMutableTransaction txToNonStd2; @@ -375,7 +384,7 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd2.vin[0].prevout.hash = txFrom.GetHash(); txToNonStd2.vin[0].scriptSig << static_cast >(twentySigops); - BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins)); + BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins, consensusBranchId)); BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index a1e3dbdc2..bb363be41 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -5,6 +5,7 @@ #include "data/script_invalid.json.h" #include "data/script_valid.json.h" +#include "consensus/upgrades.h" #include "core_io.h" #include "key.h" #include "keystore.h" @@ -87,12 +88,13 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu return txSpend; } -void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, uint32_t consensusBranchId, bool expect, const std::string& message) { ScriptError err; - CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); + CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey); + CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit); CMutableTransaction tx2 = tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0), &err) == expect, message); + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), consensusBranchId, &err) == expect, message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); #if defined(HAVE_CONSENSUS_LIB) CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); @@ -187,6 +189,7 @@ private: std::vector push; std::string comment; int flags; + uint32_t consensusBranchId; void DoPush() { @@ -204,7 +207,7 @@ private: } public: - TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_) + TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_), consensusBranchId(0) { if (P2SH) { creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL); @@ -236,7 +239,7 @@ public: TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) { - uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType); + uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType, 0, consensusBranchId); std::vector vchSig, r, s; uint32_t iter = 0; do { @@ -288,7 +291,7 @@ public: { TestBuilder copy = *this; // Make a copy so we can rollback the push. DoPush(); - DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, consensusBranchId, expect, comment); *this = copy; return *this; } @@ -372,114 +375,61 @@ BOOST_AUTO_TEST_CASE(script_build) "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true ).Num(0).PushSig(keys.key1).Num(0).PushRedeem()); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much R padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG + "P2PK with too much R padding", 0 ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much S padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG + "P2PK with too much S padding", 0 ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too little R padding but no DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG + "P2PK with too little R padding", 0 ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with bad sig with too much R padding but no DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG + "P2PK NOT with bad sig with too much R padding", 0 ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with too much R padding but no DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG + "P2PK NOT with too much R padding", 0 ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 1, without DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 1", 0 ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 2, without DERSIG", 0 - ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 2", 0 ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 3, without DERSIG", 0 - ).Num(0)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 3", 0 ).Num(0)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 4, without DERSIG", 0 - ).Num(0)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 4", 0 ).Num(0)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 5, without DERSIG", 0 + "BIP66 example 5", 0 ).Num(1)); - bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, - "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(1)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 6, without DERSIG", 0 - ).Num(1)); bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, - "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 6", 0 ).Num(1)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 7, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 7", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 8, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 8", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 9, without DERSIG", 0 + "BIP66 example 9", 0 ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 10, without DERSIG", 0 - ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 10", 0 ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 11, without DERSIG", 0 - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); - bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, - "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG + "BIP66 example 11", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 12, without DERSIG", 0 + "BIP66 example 12", 0 ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); - good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, - "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG - ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with multi-byte hashtype, without DERSIG", 0 - ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, - "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG + "P2PK with multi-byte hashtype", 0 ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, @@ -629,6 +579,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_AUTO_TEST_CASE(script_valid) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; // Read tests from test/data/script_valid.json // Format is an array of arrays // Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ] @@ -652,12 +603,13 @@ BOOST_AUTO_TEST_CASE(script_valid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, consensusBranchId, true, strTest); } } BOOST_AUTO_TEST_CASE(script_invalid) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; // Scripts that should evaluate as invalid UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); @@ -677,12 +629,14 @@ BOOST_AUTO_TEST_CASE(script_invalid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, consensusBranchId, false, strTest); } } BOOST_AUTO_TEST_CASE(script_PushData) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on // the stack as the 1-75 opcodes do. static const unsigned char direct[] = { 1, 0x5a }; @@ -692,29 +646,29 @@ BOOST_AUTO_TEST_CASE(script_PushData) ScriptError err; vector > directStack; - BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata1Stack; - BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), consensusBranchId, &err)); BOOST_CHECK(pushdata1Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata2Stack; - BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), consensusBranchId, &err)); BOOST_CHECK(pushdata2Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); vector > pushdata4Stack; - BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), &err)); + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), consensusBranchId, &err)); BOOST_CHECK(pushdata4Stack == directStack); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } CScript -sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transaction) +sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transaction, uint32_t consensusBranchId) { - uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); + uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, consensusBranchId); CScript result; // @@ -736,15 +690,17 @@ sign_multisig(CScript scriptPubKey, std::vector keys, CTransaction transac return result; } CScript -sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction) +sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction, uint32_t consensusBranchId) { std::vector keys; keys.push_back(key); - return sign_multisig(scriptPubKey, keys, transaction); + return sign_multisig(scriptPubKey, keys, transaction, consensusBranchId); } BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + ScriptError err; CKey key1, key2, key3; key1.MakeNewKey(true); @@ -757,24 +713,26 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12); CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); - CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12, consensusBranchId); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); - CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12, consensusBranchId); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); - CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + ScriptError err; CKey key1, key2, key3, key4; key1.MakeNewKey(true); @@ -790,61 +748,64 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); - CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); - CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); - CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig - CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order - CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order - CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys - CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys - CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures - CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } BOOST_AUTO_TEST_CASE(script_combineSigs) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Test the CombineSignatures function + CAmount amount = 0; CBasicKeyStore keystore; vector keys; vector pubkeys; @@ -862,62 +823,62 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript& scriptPubKey = txFrom.vout[0].scriptPubKey; CScript& scriptSig = txTo.vin[0].scriptSig; - CScript empty; - CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty); - BOOST_CHECK(combined.empty()); + SignatureData empty; + SignatureData combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, empty, consensusBranchId); + BOOST_CHECK(combined.scriptSig.empty()); // Single signature case: - SignSignature(keystore, txFrom, txTo, 0); // changes scriptSig - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); // changes scriptSig + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); CScript scriptSigCopy = scriptSig; // Signing again will give a different, valid signature: - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig); // P2SH, single-signature case: CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG; keystore.AddCScript(pkSingle); scriptPubKey = GetScriptForDestination(CScriptID(pkSingle)); - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); scriptSigCopy = scriptSig; - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSigCopy || combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig); // dummy scriptSigCopy with placeholder, should always choose non-placeholder: scriptSigCopy = CScript() << OP_0 << static_cast >(pkSingle); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSigCopy, scriptSig); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, scriptSigCopy); - BOOST_CHECK(combined == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); // Hardest case: Multisig 2-of-3 scriptPubKey = GetScriptForMultisig(2, pubkeys); keystore.AddCScript(scriptPubKey); - SignSignature(keystore, txFrom, txTo, 0); - combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); - BOOST_CHECK(combined == scriptSig); - combined = CombineSignatures(scriptPubKey, txTo, 0, empty, scriptSig); - BOOST_CHECK(combined == scriptSig); + SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId); + BOOST_CHECK(combined.scriptSig == scriptSig); // A couple of partially-signed versions: vector sig1; - uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL); + uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, consensusBranchId); BOOST_CHECK(keys[0].Sign(hash1, sig1)); sig1.push_back(SIGHASH_ALL); vector sig2; - uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE); + uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, consensusBranchId); BOOST_CHECK(keys[1].Sign(hash2, sig2)); sig2.push_back(SIGHASH_NONE); vector sig3; - uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE); + uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, consensusBranchId); BOOST_CHECK(keys[2].Sign(hash3, sig3)); sig3.push_back(SIGHASH_SINGLE); @@ -933,32 +894,34 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) CScript complete13 = CScript() << OP_0 << sig1 << sig3; CScript complete23 = CScript() << OP_0 << sig2 << sig3; - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b); - BOOST_CHECK(combined == partial1a); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial1a); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial1b, partial2b); - BOOST_CHECK(combined == complete12); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial1b); - BOOST_CHECK(combined == complete13); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial2a, partial3a); - BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial2b); - BOOST_CHECK(combined == complete23); - combined = CombineSignatures(scriptPubKey, txTo, 0, partial3b, partial3a); - BOOST_CHECK(combined == partial3c); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial1b), consensusBranchId); + BOOST_CHECK(combined.scriptSig == partial1a); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial2a), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial1a), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1b), SignatureData(partial2b), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete12); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial1b), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete13); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial3a), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete23); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial2b), consensusBranchId); + BOOST_CHECK(combined.scriptSig == complete23); + combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial3a), consensusBranchId); + BOOST_CHECK(combined.scriptSig == partial3c); } BOOST_AUTO_TEST_CASE(script_standard_push) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + ScriptError err; for (int i=0; i<67000; i++) { CScript script; script << i; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), consensusBranchId, &err), "Number " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } @@ -967,7 +930,7 @@ BOOST_AUTO_TEST_CASE(script_standard_push) CScript script; script << data; BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push."); - BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data."); + BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), consensusBranchId, &err), "Length " << i << " push is not minimal data."); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); } } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 989ed7428..c5a6ba1d4 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "data/sighash.json.h" #include "main.h" @@ -15,6 +16,7 @@ #include "sodium.h" #include +#include #include @@ -92,8 +94,23 @@ void static RandomScript(CScript &script) { script << oplist[insecure_rand() % (sizeof(oplist)/sizeof(oplist[0]))]; } -void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { - tx.nVersion = insecure_rand(); +// Overwinter tx version numbers are selected randomly from current version range. +// http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution +// https://stackoverflow.com/a/19728404 +std::random_device rd; +std::mt19937 rng(rd()); +std::uniform_int_distribution version_dist(CTransaction::OVERWINTER_MIN_CURRENT_VERSION, + CTransaction::OVERWINTER_MAX_CURRENT_VERSION); + +void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t consensusBranchId) { + tx.fOverwintered = insecure_rand() % 2; + if (tx.fOverwintered) { + tx.nVersion = version_dist(rng); + tx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + tx.nExpiryHeight = (insecure_rand() % 2) ? insecure_rand() : 0; + } else { + tx.nVersion = insecure_rand() & 0x7FFFFFFF; + } tx.vin.clear(); tx.vout.clear(); tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0; @@ -143,7 +160,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { // Empty output script. CScript scriptCode; CTransaction signTx(tx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); assert(crypto_sign_detached(&tx.joinSplitSig[0], NULL, dataToBeSigned.begin(), 32, @@ -152,15 +169,16 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) { } } -BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) +BOOST_FIXTURE_TEST_SUITE(sighash_tests, JoinSplitTestingSetup) BOOST_AUTO_TEST_CASE(sighash_test) { + uint32_t overwinterBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId; seed_insecure_rand(false); #if defined(PRINT_SIGHASH_JSON) std::cout << "[\n"; - std::cout << "\t[\"raw_transaction, script, input_index, hashType, signature_hash (result)\"],\n"; + std::cout << "\t[\"raw_transaction, script, input_index, hashType, branchId, signature_hash (result)\"],\n"; #endif int nRandomTests = 50000; @@ -169,15 +187,16 @@ BOOST_AUTO_TEST_CASE(sighash_test) #endif for (int i=0; i> tx; CValidationState state; - if (tx.nVersion < MIN_TX_VERSION) { + if (tx.fOverwintered) { + // Note that OVERWINTER_MIN_CURRENT_VERSION and OVERWINTER_MAX_CURRENT_VERSION + // are checked in IsStandardTx(), not in CheckTransactionWithoutProofVerification() + if (tx.nVersion < OVERWINTER_MIN_TX_VERSION || + tx.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD) + { + // Transaction must be invalid + BOOST_CHECK_MESSAGE(!CheckTransactionWithoutProofVerification(tx, state), strTest); + BOOST_CHECK(!state.IsValid()); + } else { + BOOST_CHECK_MESSAGE(CheckTransactionWithoutProofVerification(tx, state), strTest); + BOOST_CHECK(state.IsValid()); + } + } else if (tx.nVersion < SPROUT_MIN_TX_VERSION) { // Transaction must be invalid BOOST_CHECK_MESSAGE(!CheckTransactionWithoutProofVerification(tx, state), strTest); BOOST_CHECK(!state.IsValid()); @@ -250,7 +287,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) continue; } - sh = SignatureHash(scriptCode, tx, nIn, nHashType); + sh = SignatureHash(scriptCode, tx, nIn, nHashType, 0, consensusBranchId); BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); } } diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 5c701c5cc..02a3a50d2 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -12,6 +12,7 @@ #include "main.h" #include "random.h" #include "txdb.h" +#include "txmempool.h" #include "ui_interface.h" #include "util.h" #ifdef ENABLE_WALLET @@ -30,20 +31,30 @@ ZCJoinSplit *pzcashParams; extern bool fPrintToConsole; extern void noui_connect(); +JoinSplitTestingSetup::JoinSplitTestingSetup() +{ + boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; + boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; + pzcashParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); +} + +JoinSplitTestingSetup::~JoinSplitTestingSetup() +{ + delete pzcashParams; +} + BasicTestingSetup::BasicTestingSetup() { - assert(init_and_check_sodium() != -1); - ECC_Start(); - pzcashParams = ZCJoinSplit::Unopened(); - SetupEnvironment(); - fPrintToDebugLog = false; // don't want to write to debug.log file - fCheckBlockIndex = true; - SelectParams(CBaseChainParams::MAIN); + assert(init_and_check_sodium() != -1); + ECC_Start(); + SetupEnvironment(); + fPrintToDebugLog = false; // don't want to write to debug.log file + fCheckBlockIndex = true; + SelectParams(CBaseChainParams::MAIN); } BasicTestingSetup::~BasicTestingSetup() { - ECC_Stop(); - delete pzcashParams; + ECC_Stop(); } TestingSetup::TestingSetup() @@ -92,6 +103,13 @@ TestingSetup::~TestingSetup() boost::filesystem::remove_all(pathTemp); } + +CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(CMutableTransaction &tx, CTxMemPool *pool) { + return CTxMemPoolEntry(tx, nFee, nTime, dPriority, nHeight, + pool ? pool->HasNoInputsOf(tx) : hadNoDependencies, + spendsCoinbase, nBranchId); +} + void Shutdown(void* parg) { exit(0); diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index 2f75332d4..ae528d682 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,6 +1,8 @@ #ifndef BITCOIN_TEST_TEST_BITCOIN_H #define BITCOIN_TEST_TEST_BITCOIN_H +#include "consensus/upgrades.h" +#include "pubkey.h" #include "txdb.h" #include @@ -10,15 +12,23 @@ * This just configures logging and chain parameters. */ struct BasicTestingSetup { + ECCVerifyHandle globalVerifyHandle; + BasicTestingSetup(); ~BasicTestingSetup(); }; +// Setup w.r.t. zk-SNARK API +struct JoinSplitTestingSetup: public BasicTestingSetup { + JoinSplitTestingSetup(); + ~JoinSplitTestingSetup(); +}; + /** Testing setup that configures a complete environment. * Included are data directory, coins database, script check threads * and wallet (if enabled) setup. */ -struct TestingSetup: public BasicTestingSetup { +struct TestingSetup: public JoinSplitTestingSetup { CCoinsViewDB *pcoinsdbview; boost::filesystem::path pathTemp; boost::thread_group threadGroup; @@ -27,4 +37,34 @@ struct TestingSetup: public BasicTestingSetup { ~TestingSetup(); }; +class CTxMemPoolEntry; +class CTxMemPool; + +struct TestMemPoolEntryHelper +{ + // Default values + CAmount nFee; + int64_t nTime; + double dPriority; + unsigned int nHeight; + bool hadNoDependencies; + bool spendsCoinbase; + uint32_t nBranchId; + + TestMemPoolEntryHelper() : + nFee(0), nTime(0), dPriority(0.0), nHeight(1), + hadNoDependencies(false), spendsCoinbase(false), + nBranchId(SPROUT_BRANCH_ID) { } + + CTxMemPoolEntry FromTx(CMutableTransaction &tx, CTxMemPool *pool = NULL); + + // Change the default value + TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; } + TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; } + TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } + TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } + TestMemPoolEntryHelper &HadNoDependencies(bool _hnd) { hadNoDependencies = _hnd; return *this; } + TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } + TestMemPoolEntryHelper &BranchId(uint32_t _branchId) { nBranchId = _branchId; return *this; } +}; #endif diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index 68516599d..b7affaacd 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -119,29 +119,60 @@ BOOST_AUTO_TEST_CASE(util_ParseTorReplyMapping) {"Foo", "Bar Baz"}, }); - // Escapes (which are left escaped by the parser) + // Escapes CheckParseTorReplyMapping( "Foo=\"Bar\\ Baz\"", { - {"Foo", "Bar\\ Baz"}, + {"Foo", "Bar Baz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\Baz\"", { - {"Foo", "Bar\\Baz"}, + {"Foo", "BarBaz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\@Baz\"", { - {"Foo", "Bar\\@Baz"}, + {"Foo", "Bar@Baz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\\"Baz\" Spam=\"\\\"Eggs\\\"\"", { - {"Foo", "Bar\\\"Baz"}, - {"Spam", "\\\"Eggs\\\""}, + {"Foo", "Bar\"Baz"}, + {"Spam", "\"Eggs\""}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\\\Baz\"", { - {"Foo", "Bar\\\\Baz"}, + {"Foo", "Bar\\Baz"}, }); + // C escapes + CheckParseTorReplyMapping( + "Foo=\"Bar\\nBaz\\t\" Spam=\"\\rEggs\" Octals=\"\\1a\\11\\17\\18\\81\\377\\378\\400\\2222\" Final=Check", { + {"Foo", "Bar\nBaz\t"}, + {"Spam", "\rEggs"}, + {"Octals", "\1a\11\17\1" "881\377\37" "8\40" "0\222" "2"}, + {"Final", "Check"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Escaped=\"Escape\\\\\"", { + {"Valid", "Mapping"}, + {"Escaped", "Escape\\"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Bare=\"Escape\\\"", {}); + CheckParseTorReplyMapping( + "OneOctal=\"OneEnd\\1\" TwoOctal=\"TwoEnd\\11\"", { + {"OneOctal", "OneEnd\1"}, + {"TwoOctal", "TwoEnd\11"}, + }); + + // Special handling for null case + // (needed because string comparison reads the null as end-of-string) + BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(Null=\"\\0\")")); + auto ret = ParseTorReplyMapping("Null=\"\\0\""); + BOOST_CHECK_EQUAL(ret.size(), 1); + auto r_it = ret.begin(); + BOOST_CHECK_EQUAL(r_it->first, "Null"); + BOOST_CHECK_EQUAL(r_it->second.size(), 1); + BOOST_CHECK_EQUAL(r_it->second[0], '\0'); + // A more complex valid grammar. PROTOCOLINFO accepts a VersionLine that // takes a key=value pair followed by an OptArguments, making this valid. // Because an OptArguments contains no semantic data, there is no point in diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 7723cce1d..9fd35c2cc 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -6,7 +6,10 @@ #include "data/tx_valid.json.h" #include "test/test_bitcoin.h" +#include "init.h" #include "clientversion.h" +#include "checkqueue.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "core_io.h" #include "key.h" @@ -14,6 +17,7 @@ #include "main.h" #include "script/script.h" #include "script/script_error.h" +#include "script/sign.h" #include "primitives/transaction.h" #include "sodium.h" @@ -42,7 +46,6 @@ static std::map mapFlagNames = boost::assign::map_list_of (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) - (string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG) (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) @@ -86,10 +89,12 @@ string FormatScriptFlags(unsigned int flags) return ret.substr(0, ret.size() - 1); } -BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup) +BOOST_FIXTURE_TEST_SUITE(transaction_tests, JoinSplitTestingSetup) BOOST_AUTO_TEST_CASE(tx_valid) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Read tests from test/data/tx_valid.json // Format is an array of arrays // Inner arrays are either [ "comment" ] @@ -98,6 +103,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); + std::string comment(""); auto verifier = libzcash::ProofVerifier::Strict(); ScriptError err; @@ -108,7 +114,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); continue; } @@ -133,7 +139,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) } if (!fValid) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); continue; } @@ -143,29 +149,40 @@ BOOST_AUTO_TEST_CASE(tx_valid) stream >> tx; CValidationState state; - BOOST_CHECK_MESSAGE(CheckTransaction(tx, state, verifier), strTest); - BOOST_CHECK(state.IsValid()); + BOOST_CHECK_MESSAGE(CheckTransaction(tx, state, verifier), strTest + comment); + BOOST_CHECK_MESSAGE(state.IsValid(), comment); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size(); i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); break; } + CAmount amount = 0; unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(&tx, i), &err), - strTest); - BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); + verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), consensusBranchId, &err), + strTest + comment); + BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err) + comment); } + + comment = ""; + } + else if (test.size() == 1) + { + comment += "\n# "; + comment += test[0].write(); } } } BOOST_AUTO_TEST_CASE(tx_invalid) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + // Read tests from test/data/tx_invalid.json // Format is an array of arrays // Inner arrays are either [ "comment" ] @@ -174,6 +191,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); + std::string comment(""); auto verifier = libzcash::ProofVerifier::Strict(); ScriptError err; @@ -184,7 +202,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); continue; } @@ -209,7 +227,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } if (!fValid) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); continue; } @@ -221,20 +239,29 @@ BOOST_AUTO_TEST_CASE(tx_invalid) CValidationState state; fValid = CheckTransaction(tx, state, verifier) && state.IsValid(); + PrecomputedTransactionData txdata(tx); for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) { if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout)) { - BOOST_ERROR("Bad test: " << strTest); + BOOST_ERROR("Bad test: " << strTest << comment); break; } unsigned int verify_flags = ParseScriptFlags(test[2].get_str()); + CAmount amount = 0; fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker(&tx, i), &err); + verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), consensusBranchId, &err); } - BOOST_CHECK_MESSAGE(!fValid, strTest); - BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err)); + BOOST_CHECK_MESSAGE(!fValid, strTest + comment); + BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err) + comment); + + comment = ""; + } + else if (test.size() == 1) + { + comment += "\n# "; + comment += test[0].write(); } } } @@ -311,9 +338,6 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification) // Also, it's generally libzcash's job to ensure the // integrity of the scheme through its own tests. - // construct the r1cs keypair - auto p = ZCJoinSplit::Generate(); - // construct a merkle tree ZCIncrementalMerkleTree merkleTree; @@ -347,8 +371,8 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification) auto verifier = libzcash::ProofVerifier::Strict(); { - JSDescription jsdesc(*p, pubKeyHash, rt, inputs, outputs, 0, 0); - BOOST_CHECK(jsdesc.Verify(*p, verifier, pubKeyHash)); + JSDescription jsdesc(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0); + BOOST_CHECK(jsdesc.Verify(*pzcashParams, verifier, pubKeyHash)); CDataStream ss(SER_DISK, CLIENT_VERSION); ss << jsdesc; @@ -357,25 +381,26 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification) ss >> jsdesc_deserialized; BOOST_CHECK(jsdesc_deserialized == jsdesc); - BOOST_CHECK(jsdesc_deserialized.Verify(*p, verifier, pubKeyHash)); + BOOST_CHECK(jsdesc_deserialized.Verify(*pzcashParams, verifier, pubKeyHash)); } { // Ensure that the balance equation is working. - BOOST_CHECK_THROW(JSDescription(*p, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument); - BOOST_CHECK_THROW(JSDescription(*p, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument); + BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 10, 0), std::invalid_argument); + BOOST_CHECK_THROW(JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 10), std::invalid_argument); } { // Ensure that it won't verify if the root is changed. - auto test = JSDescription(*p, pubKeyHash, rt, inputs, outputs, 0, 0); + auto test = JSDescription(*pzcashParams, pubKeyHash, rt, inputs, outputs, 0, 0); test.anchor = GetRandHash(); - BOOST_CHECK(!test.Verify(*p, verifier, pubKeyHash)); + BOOST_CHECK(!test.Verify(*pzcashParams, verifier, pubKeyHash)); } } BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; auto verifier = libzcash::ProofVerifier::Strict(); CMutableTransaction tx; tx.nVersion = 2; @@ -403,13 +428,14 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity) jsdesc->nullifiers[0] = GetRandHash(); jsdesc->nullifiers[1] = GetRandHash(); - BOOST_CHECK(!CheckTransactionWithoutProofVerification(newTx, state)); + BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); + BOOST_CHECK(!ContextualCheckTransaction(newTx, state, 0, 100)); BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature"); // Empty output script. CScript scriptCode; CTransaction signTx(newTx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); assert(crypto_sign_detached(&newTx.joinSplitSig[0], NULL, dataToBeSigned.begin(), 32, @@ -417,6 +443,7 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity) ) == 0); BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state)); + BOOST_CHECK(ContextualCheckTransaction(newTx, state, 0, 100)); } { // Ensure that values within the joinsplit are well-formed. @@ -506,6 +533,8 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity) BOOST_AUTO_TEST_CASE(test_Get) { + uint32_t consensusBranchId = SPROUT_BRANCH_ID; + CBasicKeyStore keystore; CCoinsView coinsDummy; CCoinsViewCache coins(&coinsDummy); @@ -525,17 +554,99 @@ BOOST_AUTO_TEST_CASE(test_Get) t1.vout.resize(2); t1.vout[0].nValue = 90*CENT; t1.vout[0].scriptPubKey << OP_1; - int64_t interest; - BOOST_CHECK(AreInputsStandard(t1, coins)); - BOOST_CHECK_EQUAL(coins.GetValueIn(0,&interest,t1,0), (50+21+22)*CENT); + BOOST_CHECK(AreInputsStandard(t1, coins, consensusBranchId)); + BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); // Adding extra junk to the scriptSig should make it non-standard: t1.vin[0].scriptSig << OP_11; - BOOST_CHECK(!AreInputsStandard(t1, coins)); + BOOST_CHECK(!AreInputsStandard(t1, coins, consensusBranchId)); // ... as should not having enough: t1.vin[0].scriptSig = CScript(); - BOOST_CHECK(!AreInputsStandard(t1, coins)); + BOOST_CHECK(!AreInputsStandard(t1, coins, consensusBranchId)); +} + +BOOST_AUTO_TEST_CASE(test_big_overwinter_transaction) { + uint32_t consensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId; + CMutableTransaction mtx; + mtx.fOverwintered = true; + mtx.nVersion = 3; + mtx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + + CKey key; + key.MakeNewKey(false); + CBasicKeyStore keystore; + keystore.AddKeyPubKey(key, key.GetPubKey()); + CKeyID hash = key.GetPubKey().GetID(); + CScript scriptPubKey = GetScriptForDestination(hash); + + vector sigHashes; + sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY); + sigHashes.push_back(SIGHASH_NONE); + sigHashes.push_back(SIGHASH_SINGLE); + sigHashes.push_back(SIGHASH_ALL); + + // create a big transaction of 4500 inputs signed by the same key + for(uint32_t ij = 0; ij < 4500; ij++) { + uint32_t i = mtx.vin.size(); + uint256 prevId; + prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100"); + COutPoint outpoint(prevId, i); + + mtx.vin.resize(mtx.vin.size() + 1); + mtx.vin[i].prevout = outpoint; + mtx.vin[i].scriptSig = CScript(); + + mtx.vout.resize(mtx.vout.size() + 1); + mtx.vout[i].nValue = 1000; + mtx.vout[i].scriptPubKey = CScript() << OP_1; + } + + // sign all inputs + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()), consensusBranchId); + assert(hashSigned); + } + + CTransaction tx; + CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION); + ssout << mtx; + ssout >> tx; + + // check all inputs concurrently, with the cache + PrecomputedTransactionData txdata(tx); + boost::thread_group threadGroup; + CCheckQueue scriptcheckqueue(128); + CCheckQueueControl control(&scriptcheckqueue); + + for (int i=0; i<20; i++) + threadGroup.create_thread(boost::bind(&CCheckQueue::Thread, boost::ref(scriptcheckqueue))); + + CCoins coins; + coins.nVersion = 1; + coins.fCoinBase = false; + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + CTxOut txout; + txout.nValue = 1000; + txout.scriptPubKey = scriptPubKey; + coins.vout.push_back(txout); + } + + for(uint32_t i = 0; i < mtx.vin.size(); i++) { + std::vector vChecks; + CScriptCheck check(coins, tx, i, SCRIPT_VERIFY_P2SH, false, consensusBranchId, &txdata); + vChecks.push_back(CScriptCheck()); + check.swap(vChecks.back()); + control.Add(vChecks); + } + + bool controlCheck = control.Wait(); + assert(controlCheck); + + threadGroup.interrupt_all(); + threadGroup.join_all(); } BOOST_AUTO_TEST_CASE(test_IsStandard) diff --git a/src/timedata.cpp b/src/timedata.cpp index a14d69c11..1dcef2de3 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -99,7 +99,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample) if (!fMatch) { fDone = true; - string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin Core will not work properly."); + string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Zcash will not work properly."); strMiscWarning = strMessage; LogPrintf("*** %s\n", strMessage); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); diff --git a/src/tinyformat.h b/src/tinyformat.h index 5971b7af8..4bb96953d 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -155,7 +155,7 @@ namespace tfm = tinyformat; #endif #ifdef __APPLE__ -// Workaround OSX linker warning: xcode uses different default symbol +// Workaround macOS linker warning: Xcode uses different default symbol // visibilities for static libs vs executables (see issue #25) # define TINYFORMAT_HIDDEN __attribute__((visibility("hidden"))) #else @@ -584,7 +584,7 @@ inline const char* printFormatStringLiteral(std::ostream& out, const char* fmt) // Formatting options which can't be natively represented using the ostream // state are returned in spacePadPositive (for space padded positive numbers) // and ntrunc (for truncating conversions). argIndex is incremented if -// necessary to pull out variable width and precision . The function returns a +// necessary to pull out variable width and precision. The function returns a // pointer to the character after the end of the current format spec. inline const char* streamStateFromFormat(std::ostream& out, bool& spacePadPositive, int& ntrunc, const char* fmtStart, diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 60181b440..99c76995b 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -1,3 +1,8 @@ +// Copyright (c) 2015-2017 The Bitcoin Core developers +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include "torcontrol.h" #include "utilstrencodings.h" #include "net.h" @@ -285,17 +290,61 @@ static std::map ParseTorReplyMapping(const std::string ++ptr; // skip opening '"' bool escape_next = false; while (ptr < s.size() && (escape_next || s[ptr] != '"')) { - escape_next = (s[ptr] == '\\'); + // Repeated backslashes must be interpreted as pairs + escape_next = (s[ptr] == '\\' && !escape_next); value.push_back(s[ptr]); ++ptr; } if (ptr == s.size()) // unexpected end of line return std::map(); ++ptr; // skip closing '"' - /* TODO: unescape value - according to the spec this depends on the - * context, some strings use C-LogPrintf style escape codes, some - * don't. So may be better handled at the call site. + /** + * Unescape value. Per https://spec.torproject.org/control-spec section 2.1.1: + * + * For future-proofing, controller implementors MAY use the following + * rules to be compatible with buggy Tor implementations and with + * future ones that implement the spec as intended: + * + * Read \n \t \r and \0 ... \377 as C escapes. + * Treat a backslash followed by any other character as that character. */ + std::string escaped_value; + for (size_t i = 0; i < value.size(); ++i) { + if (value[i] == '\\') { + // This will always be valid, because if the QuotedString + // ended in an odd number of backslashes, then the parser + // would already have returned above, due to a missing + // terminating double-quote. + ++i; + if (value[i] == 'n') { + escaped_value.push_back('\n'); + } else if (value[i] == 't') { + escaped_value.push_back('\t'); + } else if (value[i] == 'r') { + escaped_value.push_back('\r'); + } else if ('0' <= value[i] && value[i] <= '7') { + size_t j; + // Octal escape sequences have a limit of three octal digits, + // but terminate at the first character that is not a valid + // octal digit if encountered sooner. + for (j = 1; j < 3 && (i+j) < value.size() && '0' <= value[i+j] && value[i+j] <= '7'; ++j) {} + // Tor restricts first digit to 0-3 for three-digit octals. + // A leading digit of 4-7 would therefore be interpreted as + // a two-digit octal. + if (j == 3 && value[i] > '3') { + j--; + } + escaped_value.push_back(strtol(value.substr(i, j).c_str(), NULL, 8)); + // Account for automatic incrementing at loop end + i += j - 1; + } else { + escaped_value.push_back(value[i]); + } + } else { + escaped_value.push_back(value[i]); + } + } + value = escaped_value; } else { // Unquoted value. Note that values can contain '=' at will, just no spaces while (ptr < s.size() && s[ptr] != ' ') { value.push_back(s[ptr]); @@ -327,8 +376,10 @@ static std::pair ReadBinaryFile(const std::string &filename, s while ((n=fread(buffer, 1, sizeof(buffer), f)) > 0) { // Check for reading errors so we don't return any data if we couldn't // read the entire file (or up to maxsize) - if (ferror(f)) + if (ferror(f)) { + fclose(f); return std::make_pair(false,""); + } retval.append(buffer, buffer+n); if (retval.size() > maxsize) break; @@ -364,7 +415,7 @@ public: TorController(struct event_base* base, const std::string& target); ~TorController(); - /** Get name fo file to store private key in */ + /** Get name for file to store private key in */ std::string GetPrivateKeyFile(); /** Reconnect, after getting disconnected */ diff --git a/src/txdb.cpp b/src/txdb.cpp index 9a23596d9..f1adb11be 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -65,6 +65,9 @@ void static BatchWriteHashBestAnchor(CLevelDBBatch &batch, const uint256 &hash) batch.Write(DB_BEST_ANCHOR, hash); } +CCoinsViewDB::CCoinsViewDB(std::string dbName, size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / dbName, nCacheSize, fMemory, fWipe) { +} + CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe) { } @@ -304,12 +307,21 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nVersion = diskindex.nVersion; pindexNew->hashReserved = diskindex.hashReserved; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->hashReserved = diskindex.hashReserved; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; pindexNew->nSolution = diskindex.nSolution; pindexNew->nStatus = diskindex.nStatus; + pindexNew->nCachedBranchId = diskindex.nCachedBranchId; pindexNew->nTx = diskindex.nTx; + pindexNew->nSproutValue = diskindex.nSproutValue; + + // Consistency checks + auto header = pindexNew->GetBlockHeader(); + if (header.GetHash() != pindexNew->GetBlockHash()) + return error("LoadBlockIndex(): block header inconsistency detected: on-disk = %s, in-memory = %s", + diskindex.ToString(), pindexNew->ToString()); uint8_t pubkey33[33]; komodo_index2pubkey33(pubkey33,pindexNew,pindexNew->nHeight); if (!CheckProofOfWork(pindexNew->nHeight,pubkey33,pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus())) diff --git a/src/txdb.h b/src/txdb.h index 220cfb171..04ac8627b 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -20,8 +20,8 @@ struct CDiskTxPos; class uint256; //! -dbcache default (MiB) -static const int64_t nDefaultDbCache = 100; -//! max. -dbcache in (MiB) +static const int64_t nDefaultDbCache = 450; +//! max. -dbcache (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; @@ -31,6 +31,7 @@ class CCoinsViewDB : public CCoinsView { protected: CLevelDBWrapper db; + CCoinsViewDB(std::string dbName, size_t nCacheSize, bool fMemory = false, bool fWipe = false); public: CCoinsViewDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 6931afb3d..2dc9a4642 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -11,6 +11,7 @@ #include "main.h" #include "policy/fees.h" #include "streams.h" +#include "timedata.h" #include "util.h" #include "utilmoneystr.h" #include "version.h" @@ -19,20 +20,24 @@ using namespace std; CTxMemPoolEntry::CTxMemPoolEntry(): - nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0), hadNoDependencies(false) + nFee(0), nTxSize(0), nModSize(0), nUsageSize(0), nTime(0), dPriority(0.0), + hadNoDependencies(false), spendsCoinbase(false) { nHeight = MEMPOOL_HEIGHT; } CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, - unsigned int _nHeight, bool poolHasNoInputsOf): + unsigned int _nHeight, bool poolHasNoInputsOf, + bool _spendsCoinbase, uint32_t _nBranchId): tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight), - hadNoDependencies(poolHasNoInputsOf) + hadNoDependencies(poolHasNoInputsOf), + spendsCoinbase(_spendsCoinbase), nBranchId(_nBranchId) { nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); nModSize = tx.CalculateModifiedSize(nTxSize); nUsageSize = RecursiveDynamicUsage(tx); + feeRate = CFeeRate(nFee, nTxSize); } CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) @@ -55,7 +60,7 @@ CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : // Sanity checks off by default for performance, because otherwise // accepting transactions becomes O(N^2) where N is the number // of transactions in the pool - fSanityCheck = false; + nCheckFrequency = 0; minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee); } @@ -97,8 +102,8 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, // Used by main.cpp AcceptToMemoryPool(), which DOES do // all the appropriate checks. LOCK(cs); - mapTx[hash] = entry; - const CTransaction& tx = mapTx[hash].GetTx(); + mapTx.insert(entry); + const CTransaction& tx = mapTx.find(hash)->GetTx(); for (unsigned int i = 0; i < tx.vin.size(); i++) mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) { @@ -140,7 +145,7 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem txToRemove.pop_front(); if (!mapTx.count(hash)) continue; - const CTransaction& tx = mapTx[hash].GetTx(); + const CTransaction& tx = mapTx.find(hash)->GetTx(); if (fRecursive) { for (unsigned int i = 0; i < tx.vout.size(); i++) { std::map::iterator it = mapNextTx.find(COutPoint(hash, i)); @@ -158,8 +163,8 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem } removed.push_back(tx); - totalTxSize -= mapTx[hash].GetTxSize(); - cachedInnerUsage -= mapTx[hash].DynamicMemoryUsage(); + totalTxSize -= mapTx.find(hash)->GetTxSize(); + cachedInnerUsage -= mapTx.find(hash)->DynamicMemoryUsage(); mapTx.erase(hash); nTransactionsUpdated++; minerPolicyEstimator->removeTx(hash); @@ -167,25 +172,30 @@ void CTxMemPool::remove(const CTransaction &origTx, std::list& rem } } -void CTxMemPool::removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight) +void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) { // Remove transactions spending a coinbase which are now immature extern char ASSETCHAINS_SYMBOL[]; if ( ASSETCHAINS_SYMBOL[0] == 0 ) COINBASE_MATURITY = _COINBASE_MATURITY; + // Remove transactions spending a coinbase which are now immature and no-longer-final transactions LOCK(cs); list transactionsToRemove; - for (std::map::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { - const CTransaction& tx = it->second.GetTx(); - BOOST_FOREACH(const CTxIn& txin, tx.vin) { - std::map::const_iterator it2 = mapTx.find(txin.prevout.hash); - if (it2 != mapTx.end()) - continue; - const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); - if (fSanityCheck) assert(coins); - if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { - transactionsToRemove.push_back(tx); - break; + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->GetTx(); + if (!CheckFinalTx(tx, flags)) { + transactionsToRemove.push_back(tx); + } else if (it->GetSpendsCoinbase()) { + BOOST_FOREACH(const CTxIn& txin, tx.vin) { + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); + if (it2 != mapTx.end()) + continue; + const CCoins *coins = pcoins->AccessCoins(txin.prevout.hash); + if (nCheckFrequency != 0) assert(coins); + if (!coins || (coins->IsCoinBase() && ((signed long)nMemPoolHeight) - coins->nHeight < COINBASE_MATURITY)) { + transactionsToRemove.push_back(tx); + break; + } } } } @@ -205,8 +215,8 @@ void CTxMemPool::removeWithAnchor(const uint256 &invalidRoot) LOCK(cs); list transactionsToRemove; - for (std::map::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { - const CTransaction& tx = it->second.GetTx(); + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->GetTx(); BOOST_FOREACH(const JSDescription& joinsplit, tx.vjoinsplit) { if (joinsplit.anchor == invalidRoot) { transactionsToRemove.push_back(tx); @@ -251,6 +261,25 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list } } +void CTxMemPool::removeExpired(unsigned int nBlockHeight) +{ + // Remove expired txs from the mempool + LOCK(cs); + list transactionsToRemove; + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) + { + const CTransaction& tx = it->GetTx(); + if (IsExpiredTx(tx, nBlockHeight)) { + transactionsToRemove.push_back(tx); + } + } + for (const CTransaction& tx : transactionsToRemove) { + list removed; + remove(tx, removed, true); + LogPrint("mempool", "Removing expired txid: %s\n", tx.GetHash().ToString()); + } +} + /** * Called when a block is connected. Removes from mempool and updates the miner fee estimator. */ @@ -262,8 +291,10 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigned i BOOST_FOREACH(const CTransaction& tx, vtx) { uint256 hash = tx.GetHash(); - if (mapTx.count(hash)) - entries.push_back(mapTx[hash]); + + indexed_transaction_set::iterator i = mapTx.find(hash); + if (i != mapTx.end()) + entries.push_back(*i); } BOOST_FOREACH(const CTransaction& tx, vtx) { @@ -276,6 +307,28 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigned i minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate); } +/** + * Called whenever the tip changes. Removes transactions which don't commit to + * the given branch ID from the mempool. + */ +void CTxMemPool::removeWithoutBranchId(uint32_t nMemPoolBranchId) +{ + LOCK(cs); + std::list transactionsToRemove; + + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + const CTransaction& tx = it->GetTx(); + if (it->GetValidatedBranchId() != nMemPoolBranchId) { + transactionsToRemove.push_back(tx); + } + } + + for (const CTransaction& tx : transactionsToRemove) { + std::list removed; + remove(tx, removed, true); + } +} + void CTxMemPool::clear() { LOCK(cs); @@ -288,7 +341,10 @@ void CTxMemPool::clear() void CTxMemPool::check(const CCoinsViewCache *pcoins) const { - if (!fSanityCheck) + if (nCheckFrequency == 0) + return; + + if (insecure_rand() >= nCheckFrequency) return; LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); @@ -297,20 +353,21 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const uint64_t innerUsage = 0; CCoinsViewCache mempoolDuplicate(const_cast(pcoins)); + const int64_t nSpendHeight = GetSpendHeight(mempoolDuplicate); LOCK(cs); list waitingOnDependants; - for (std::map::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; - checkTotal += it->second.GetTxSize(); - innerUsage += it->second.DynamicMemoryUsage(); - const CTransaction& tx = it->second.GetTx(); + checkTotal += it->GetTxSize(); + innerUsage += it->DynamicMemoryUsage(); + const CTransaction& tx = it->GetTx(); bool fDependsWait = false; BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. - std::map::const_iterator it2 = mapTx.find(txin.prevout.hash); + indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash); if (it2 != mapTx.end()) { - const CTransaction& tx2 = it2->second.GetTx(); + const CTransaction& tx2 = it2->GetTx(); assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull()); fDependsWait = true; } else { @@ -348,11 +405,13 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const intermediates.insert(std::make_pair(tree.root(), tree)); } if (fDependsWait) - waitingOnDependants.push_back(&it->second); + waitingOnDependants.push_back(&(*it)); else { CValidationState state; - assert(ContextualCheckInputs(tx, state, mempoolDuplicate, false, 0, false, Params().GetConsensus(), NULL)); - UpdateCoins(tx, state, mempoolDuplicate, 1000000); + bool fCheckResult = tx.IsCoinBase() || + Consensus::CheckTxInputs(tx, state, mempoolDuplicate, nSpendHeight, Params().GetConsensus()); + assert(fCheckResult); + UpdateCoins(tx, mempoolDuplicate, 1000000); } } unsigned int stepsSinceLastRemove = 0; @@ -365,15 +424,17 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const stepsSinceLastRemove++; assert(stepsSinceLastRemove < waitingOnDependants.size()); } else { - assert(ContextualCheckInputs(entry->GetTx(), state, mempoolDuplicate, false, 0, false, Params().GetConsensus(), NULL)); - UpdateCoins(entry->GetTx(), state, mempoolDuplicate, 1000000); + bool fCheckResult = entry->GetTx().IsCoinBase() || + Consensus::CheckTxInputs(entry->GetTx(), state, mempoolDuplicate, nSpendHeight, Params().GetConsensus()); + assert(fCheckResult); + UpdateCoins(entry->GetTx(), mempoolDuplicate, 1000000); stepsSinceLastRemove = 0; } } for (std::map::const_iterator it = mapNextTx.begin(); it != mapNextTx.end(); it++) { uint256 hash = it->second.ptx->GetHash(); - map::const_iterator it2 = mapTx.find(hash); - const CTransaction& tx = it2->second.GetTx(); + indexed_transaction_set::const_iterator it2 = mapTx.find(hash); + const CTransaction& tx = it2->GetTx(); assert(it2 != mapTx.end()); assert(&tx == it->second.ptx); assert(tx.vin.size() > it->second.n); @@ -382,8 +443,8 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const for (std::map::const_iterator it = mapNullifiers.begin(); it != mapNullifiers.end(); it++) { uint256 hash = it->second->GetHash(); - map::const_iterator it2 = mapTx.find(hash); - const CTransaction& tx = it2->second.GetTx(); + indexed_transaction_set::const_iterator it2 = mapTx.find(hash); + const CTransaction& tx = it2->GetTx(); assert(it2 != mapTx.end()); assert(&tx == it->second); } @@ -398,16 +459,16 @@ void CTxMemPool::queryHashes(vector& vtxid) LOCK(cs); vtxid.reserve(mapTx.size()); - for (map::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) - vtxid.push_back((*mi).first); + for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) + vtxid.push_back(mi->GetTx().GetHash()); } bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const { LOCK(cs); - map::const_iterator i = mapTx.find(hash); + indexed_transaction_set::const_iterator i = mapTx.find(hash); if (i == mapTx.end()) return false; - result = i->second.GetTx(); + result = i->GetTx(); return true; } @@ -520,5 +581,6 @@ bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) const { size_t CTxMemPool::DynamicMemoryUsage() const { LOCK(cs); - return memusage::DynamicUsage(mapTx) + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage; + // Estimate the overhead of mapTx to be 6 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented. + return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 6 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + cachedInnerUsage; } diff --git a/src/txmempool.h b/src/txmempool.h index cd0f9a54b..6b6434f1e 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -13,6 +13,10 @@ #include "primitives/transaction.h" #include "sync.h" +#undef foreach +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" + class CAutoFile; inline double AllowFreeThreshold() @@ -41,25 +45,54 @@ private: size_t nTxSize; //! ... and avoid recomputing tx size size_t nModSize; //! ... and modified size for priority size_t nUsageSize; //! ... and total memory usage + CFeeRate feeRate; //! ... and fee per kB int64_t nTime; //! Local time when entering the mempool double dPriority; //! Priority when entering the mempool unsigned int nHeight; //! Chain height when entering the mempool bool hadNoDependencies; //! Not dependent on any other txs when it entered the mempool + bool spendsCoinbase; //! keep track of transactions that spend a coinbase + uint32_t nBranchId; //! Branch ID this transaction is known to commit to, cached for efficiency public: CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, - int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false); + int64_t _nTime, double _dPriority, unsigned int _nHeight, + bool poolHasNoInputsOf, bool spendsCoinbase, uint32_t nBranchId); CTxMemPoolEntry(); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } double GetPriority(unsigned int currentHeight) const; CAmount GetFee() const { return nFee; } + CFeeRate GetFeeRate() const { return feeRate; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } bool WasClearAtEntry() const { return hadNoDependencies; } size_t DynamicMemoryUsage() const { return nUsageSize; } + + bool GetSpendsCoinbase() const { return spendsCoinbase; } + uint32_t GetValidatedBranchId() const { return nBranchId; } +}; + +// extracts a TxMemPoolEntry's transaction hash +struct mempoolentry_txid +{ + typedef uint256 result_type; + result_type operator() (const CTxMemPoolEntry &entry) const + { + return entry.GetTx().GetHash(); + } +}; + +class CompareTxMemPoolEntryByFee +{ +public: + bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) + { + if (a.GetFeeRate() == b.GetFeeRate()) + return a.GetTime() < b.GetTime(); + return a.GetFeeRate() > b.GetFeeRate(); + } }; class CBlockPolicyEstimator; @@ -91,7 +124,7 @@ public: class CTxMemPool { private: - bool fSanityCheck; //! Normally false, true if -checkmempool or -regtest + uint32_t nCheckFrequency; //! Value n means that n times in 2^32 we check. unsigned int nTransactionsUpdated; CBlockPolicyEstimator* minerPolicyEstimator; @@ -99,8 +132,21 @@ private: uint64_t cachedInnerUsage; //! sum of dynamic memory usage of all the map elements (NOT the maps themselves) public: + typedef boost::multi_index_container< + CTxMemPoolEntry, + boost::multi_index::indexed_by< + // sorted by txid + boost::multi_index::ordered_unique, + // sorted by fee rate + boost::multi_index::ordered_non_unique< + boost::multi_index::identity, + CompareTxMemPoolEntryByFee + > + > + > indexed_transaction_set; + mutable CCriticalSection cs; - std::map mapTx; + indexed_transaction_set mapTx; std::map mapNextTx; std::map mapNullifiers; std::map > mapDeltas; @@ -115,15 +161,17 @@ public: * check does nothing. */ void check(const CCoinsViewCache *pcoins) const; - void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; } + void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = dFrequency * 4294967296.0; } bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); void remove(const CTransaction &tx, std::list& removed, bool fRecursive = false); void removeWithAnchor(const uint256 &invalidRoot); - void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight); + void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeConflicts(const CTransaction &tx, std::list& removed); + void removeExpired(unsigned int nBlockHeight); void removeForBlock(const std::vector& vtx, unsigned int nBlockHeight, std::list& conflicts, bool fCurrentEstimate = true); + void removeWithoutBranchId(uint32_t nMemPoolBranchId); void clear(); void queryHashes(std::vector& vtxid); void pruneSpent(const uint256& hash, CCoins &coins); diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index 07314bc5c..dfc84f921 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -3,8 +3,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#ifndef __UNIVALUE_H__ -#define __UNIVALUE_H__ +#ifndef UNIVALUE_H__ +#define UNIVALUE_H__ #include @@ -293,4 +293,4 @@ extern const UniValue NullUniValue; const UniValue& find_value( const UniValue& obj, const std::string& name); -#endif // __UNIVALUE_H__ +#endif // UNIVALUE_H__ diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 47ca7aca7..14f4c3c4f 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -35,7 +35,7 @@ bool ParseInt32(const std::string& str, int32_t *out) errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); if(out) *out = (int32_t)n; - // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow + // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // platforms the size of these types may be different. return endp && *endp == 0 && !errno && @@ -51,7 +51,7 @@ bool ParseInt64(const std::string& str, int64_t *out) errno = 0; // strtoll will not set errno if valid long long int n = strtoll(str.c_str(), &endp, 10); if(out) *out = (int64_t)n; - // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow + // Note that strtoll returns a *long long int*, so even if strtol doesn't report an over/underflow // we still have to check that the returned value is within the range of an *int64_t*. return endp && *endp == 0 && !errno && n >= std::numeric_limits::min() && diff --git a/src/util.cpp b/src/util.cpp index be7517573..dd9b709a2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -926,7 +926,7 @@ std::string PrivacyInfo() { return "\n" + FormatParagraph(strprintf(_("In order to ensure you are adequately protecting your privacy when using Zcash, please see <%s>."), - "https://z.cash/support/security/index.html")) + "\n"; + "https://z.cash/support/security/")) + "\n"; } std::string LicenseInfo() @@ -940,6 +940,12 @@ std::string LicenseInfo() "\n" + FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or .")) + "\n" + "\n" + - FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) + + FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit and cryptographic software written by Eric Young.")) + "\n"; } + +int GetNumCores() +{ + return boost::thread::physical_concurrency(); +} + diff --git a/src/util.h b/src/util.h index 424c6693a..faf741409 100644 --- a/src/util.h +++ b/src/util.h @@ -219,6 +219,13 @@ std::string HelpMessageGroup(const std::string& message); */ std::string HelpMessageOpt(const std::string& option, const std::string& message); +/** + * Return the number of physical cores available on the current system. + * @note This does not count virtual cores, such as those provided by HyperThreading + * when boost is newer than 1.56. + */ +int GetNumCores(); + void SetThreadPriority(int nPriority); void RenameThread(const char* name); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 054992cfb..0a5fbb3d2 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include using namespace std; @@ -46,6 +47,20 @@ string SanitizeFilename(const string& str) return strResult; } +std::string HexInt(uint32_t val) +{ + std::stringstream ss; + ss << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << val; + return ss.str(); +} + +uint32_t ParseHexToUInt32(const std::string& str) { + std::istringstream converter(str); + uint32_t value; + converter >> std::hex >> value; + return value; +} + const signed char p_util_hexdigit[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index d6973a130..ccdc6a76b 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -24,6 +24,8 @@ std::string SanitizeFilename(const std::string& str); std::string SanitizeString(const std::string& str); +std::string HexInt(uint32_t val); +uint32_t ParseHexToUInt32(const std::string& str); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); signed char HexDigit(char c); diff --git a/src/utiltest.cpp b/src/utiltest.cpp index 5cebc1a5d..4599cec3c 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -4,6 +4,8 @@ #include "utiltest.h" +#include "consensus/upgrades.h" + CWalletTx GetValidReceive(ZCJoinSplit& params, const libzcash::SpendingKey& sk, CAmount value, bool randomInputs) { @@ -45,9 +47,10 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, mtx.vjoinsplit.push_back(jsdesc); // Empty output script. + uint32_t consensusBranchId = SPROUT_BRANCH_ID; CScript scriptCode; CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); // Add the signature assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, @@ -63,7 +66,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, libzcash::Note GetNote(ZCJoinSplit& params, const libzcash::SpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { - ZCNoteDecryption decryptor {sk.viewing_key()}; + ZCNoteDecryption decryptor {sk.receiving_key()}; auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); auto note_pt = libzcash::NotePlaintext::decrypt( decryptor, @@ -129,9 +132,10 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, mtx.vjoinsplit.push_back(jsdesc); // Empty output script. + uint32_t consensusBranchId = SPROUT_BRANCH_ID; CScript scriptCode; CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); // Add the signature assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, diff --git a/src/utiltime.cpp b/src/utiltime.cpp index a7cdeb114..f1a408a31 100644 --- a/src/utiltime.cpp +++ b/src/utiltime.cpp @@ -43,20 +43,7 @@ int64_t GetTimeMicros() void MilliSleep(int64_t n) { - -/** - * Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50 - * until fixed in 1.52. Use the deprecated sleep method for the broken case. - * See: https://svn.boost.org/trac/boost/ticket/7238 - */ -#if defined(HAVE_WORKING_BOOST_SLEEP_FOR) boost::this_thread::sleep_for(boost::chrono::milliseconds(n)); -#elif defined(HAVE_WORKING_BOOST_SLEEP) - boost::this_thread::sleep(boost::posix_time::milliseconds(n)); -#else -//should never get here -#error missing boost sleep implementation -#endif } std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime) diff --git a/src/version.h b/src/version.h index 91a464030..25527895d 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 170002; +static const int PROTOCOL_VERSION = 170003; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -24,10 +24,6 @@ static const int MIN_PEER_PROTO_VERSION = 170002; //! if possible, avoid requesting addresses nodes older than this static const int CADDR_TIME_VERSION = 31402; -//! only request blocks from nodes outside this range of versions -static const int NOBLKS_VERSION_START = 32000; -static const int NOBLKS_VERSION_END = 32400; - //! BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp new file mode 100644 index 000000000..30ef560df --- /dev/null +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -0,0 +1,923 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "asyncrpcoperation_mergetoaddress.h" + +#include "amount.h" +#include "asyncrpcqueue.h" +#include "core_io.h" +#include "init.h" +#include "main.h" +#include "miner.h" +#include "net.h" +#include "netbase.h" +#include "rpcprotocol.h" +#include "rpcserver.h" +#include "script/interpreter.h" +#include "sodium.h" +#include "timedata.h" +#include "util.h" +#include "utilmoneystr.h" +#include "utiltime.h" +#include "wallet.h" +#include "walletdb.h" +#include "zcash/IncrementalMerkleTree.hpp" + +#include +#include +#include +#include + +#include "paymentdisclosuredb.h" + +using namespace libzcash; + +int mta_find_output(UniValue obj, int n) +{ + UniValue outputMapValue = find_value(obj, "outputmap"); + if (!outputMapValue.isArray()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation"); + } + + UniValue outputMap = outputMapValue.get_array(); + assert(outputMap.size() == ZC_NUM_JS_OUTPUTS); + for (size_t i = 0; i < outputMap.size(); i++) { + if (outputMap[i].get_int() == n) { + return i; + } + } + + throw std::logic_error("n is not present in outputmap"); +} + +AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( + CMutableTransaction contextualTx, + std::vector utxoInputs, + std::vector noteInputs, + MergeToAddressRecipient recipient, + CAmount fee, + UniValue contextInfo) : + tx_(contextualTx), utxoInputs_(utxoInputs), noteInputs_(noteInputs), + recipient_(recipient), fee_(fee), contextinfo_(contextInfo) +{ + if (fee < 0 || fee > MAX_MONEY) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range"); + } + + if (utxoInputs.empty() && noteInputs.empty()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "No inputs"); + } + + if (std::get<0>(recipient).size() == 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing"); + } + + toTaddr_ = CBitcoinAddress(std::get<0>(recipient)); + isToTaddr_ = toTaddr_.IsValid(); + isToZaddr_ = false; + + if (!isToTaddr_) { + CZCPaymentAddress address(std::get<0>(recipient)); + try { + PaymentAddress addr = address.Get(); + + isToZaddr_ = true; + toPaymentAddress_ = addr; + } catch (const std::runtime_error& e) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("runtime error: ") + e.what()); + } + } + + // Log the context info i.e. the call parameters to z_mergetoaddress + if (LogAcceptCategory("zrpcunsafe")) { + LogPrint("zrpcunsafe", "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write()); + } else { + LogPrint("zrpc", "%s: z_mergetoaddress initialized\n", getId()); + } + + // Lock UTXOs + lock_utxos(); + + // Enable payment disclosure if requested + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); +} + +AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress() +{ +} + +void AsyncRPCOperation_mergetoaddress::main() +{ + if (isCancelled()) { + unlock_utxos(); // clean up + return; + } + + set_state(OperationStatus::EXECUTING); + start_execution_clock(); + + bool success = false; + +#ifdef ENABLE_MINING +#ifdef ENABLE_WALLET + GenerateBitcoins(false, NULL, 0); +#else + GenerateBitcoins(false, 0); +#endif +#endif + + try { + success = main_impl(); + } catch (const UniValue& objError) { + int code = find_value(objError, "code").get_int(); + std::string message = find_value(objError, "message").get_str(); + set_error_code(code); + set_error_message(message); + } catch (const runtime_error& e) { + set_error_code(-1); + set_error_message("runtime error: " + string(e.what())); + } catch (const logic_error& e) { + set_error_code(-1); + set_error_message("logic error: " + string(e.what())); + } catch (const exception& e) { + set_error_code(-1); + set_error_message("general exception: " + string(e.what())); + } catch (...) { + set_error_code(-2); + set_error_message("unknown error"); + } + +#ifdef ENABLE_MINING +#ifdef ENABLE_WALLET + GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); +#else + GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1)); +#endif +#endif + + stop_execution_clock(); + + if (success) { + set_state(OperationStatus::SUCCESS); + } else { + set_state(OperationStatus::FAILED); + } + + std::string s = strprintf("%s: z_mergetoaddress finished (status=%s", getId(), getStateAsString()); + if (success) { + s += strprintf(", txid=%s)\n", tx_.GetHash().ToString()); + } else { + s += strprintf(", error=%s)\n", getErrorMessage()); + } + LogPrintf("%s", s); + + unlock_utxos(); // clean up + + // !!! Payment disclosure START + if (success && paymentDisclosureMode && paymentDisclosureData_.size() > 0) { + uint256 txidhash = tx_.GetHash(); + std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); + for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { + p.first.hash = txidhash; + if (!db->Put(p.first, p.second)) { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); + } else { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); + } + } + } + // !!! Payment disclosure END +} + +// Notes: +// 1. #1359 Currently there is no limit set on the number of joinsplits, so size of tx could be invalid. +// 2. #1277 Spendable notes are not locked, so an operation running in parallel could also try to use them. +bool AsyncRPCOperation_mergetoaddress::main_impl() +{ + assert(isToTaddr_ != isToZaddr_); + + bool isPureTaddrOnlyTx = (noteInputs_.empty() && isToTaddr_); + CAmount minersFee = fee_; + + size_t numInputs = utxoInputs_.size(); + + // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects + size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); + if (limit > 0 && numInputs > limit) { + throw JSONRPCError(RPC_WALLET_ERROR, + strprintf("Number of transparent inputs %d is greater than mempooltxinputlimit of %d", + numInputs, limit)); + } + + CAmount t_inputs_total = 0; + for (MergeToAddressInputUTXO& t : utxoInputs_) { + t_inputs_total += std::get<1>(t); + } + + CAmount z_inputs_total = 0; + for (MergeToAddressInputNote& t : noteInputs_) { + z_inputs_total += std::get<2>(t); + } + + CAmount targetAmount = z_inputs_total + t_inputs_total; + + if (targetAmount <= minersFee) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, + strprintf("Insufficient funds, have %s and miners fee is %s", + FormatMoney(targetAmount), FormatMoney(minersFee))); + } + + CAmount sendAmount = targetAmount - minersFee; + + // update the transaction with the UTXO inputs and output (if any) + CMutableTransaction rawTx(tx_); + for (MergeToAddressInputUTXO& t : utxoInputs_) { + CTxIn in(std::get<0>(t)); + rawTx.vin.push_back(in); + } + if (isToTaddr_) { + CScript scriptPubKey = GetScriptForDestination(toTaddr_.Get()); + CTxOut out(sendAmount, scriptPubKey); + rawTx.vout.push_back(out); + } + tx_ = CTransaction(rawTx); + + LogPrint(isPureTaddrOnlyTx ? "zrpc" : "zrpcunsafe", "%s: spending %s to send %s with fee %s\n", + getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee)); + LogPrint("zrpc", "%s: transparent input: %s\n", getId(), FormatMoney(t_inputs_total)); + LogPrint("zrpcunsafe", "%s: private input: %s\n", getId(), FormatMoney(z_inputs_total)); + if (isToTaddr_) { + LogPrint("zrpc", "%s: transparent output: %s\n", getId(), FormatMoney(sendAmount)); + } else { + LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(sendAmount)); + } + LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee)); + + // Grab the current consensus branch ID + { + LOCK(cs_main); + consensusBranchId_ = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + } + + /** + * SCENARIO #1 + * + * taddrs -> taddr + * + * There are no zaddrs or joinsplits involved. + */ + if (isPureTaddrOnlyTx) { + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); + sign_send_raw_transaction(obj); + return true; + } + /** + * END SCENARIO #1 + */ + + + // Prepare raw transaction to handle JoinSplits + CMutableTransaction mtx(tx_); + crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); + mtx.joinSplitPubKey = joinSplitPubKey_; + tx_ = CTransaction(mtx); + std::string hexMemo = std::get<1>(recipient_); + + + /** + * SCENARIO #2 + * + * taddrs -> zaddr + * + * We only need a single JoinSplit. + */ + if (noteInputs_.empty() && isToZaddr_) { + // Create JoinSplit to target z-addr. + MergeToAddressJSInfo info; + info.vpub_old = sendAmount; + info.vpub_new = 0; + + JSOutput jso = JSOutput(toPaymentAddress_, sendAmount); + if (hexMemo.size() > 0) { + jso.memo = get_memo_from_hex_string(hexMemo); + } + info.vjsout.push_back(jso); + + UniValue obj(UniValue::VOBJ); + obj = perform_joinsplit(info); + sign_send_raw_transaction(obj); + return true; + } + /** + * END SCENARIO #2 + */ + + + // Copy zinputs to more flexible containers + std::deque zInputsDeque; + for (auto o : noteInputs_) { + zInputsDeque.push_back(o); + } + + // When spending notes, take a snapshot of note witnesses and anchors as the treestate will + // change upon arrival of new blocks which contain joinsplit transactions. This is likely + // to happen as creating a chained joinsplit transaction can take longer than the block interval. + { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto t : noteInputs_) { + JSOutPoint jso = std::get<0>(t); + std::vector vOutPoints = {jso}; + uint256 inputAnchor; + std::vector> vInputWitnesses; + pwalletMain->GetNoteWitnesses(vOutPoints, vInputWitnesses, inputAnchor); + jsopWitnessAnchorMap[jso.ToString()] = MergeToAddressWitnessAnchorData{vInputWitnesses[0], inputAnchor}; + } + } + + /** + * SCENARIO #3 + * + * zaddrs -> zaddr + * taddrs -> + * + * zaddrs -> + * taddrs -> taddr + * + * Send to zaddr by chaining JoinSplits together and immediately consuming any change + * Send to taddr by creating dummy z outputs and accumulating value in a change note + * which is used to set vpub_new in the last chained joinsplit. + */ + UniValue obj(UniValue::VOBJ); + CAmount jsChange = 0; // this is updated after each joinsplit + int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 + bool vpubOldProcessed = false; // updated when vpub_old for taddr inputs is set in first joinsplit + bool vpubNewProcessed = false; // updated when vpub_new for miner fee and taddr outputs is set in last joinsplit + + // At this point, we are guaranteed to have at least one input note. + // Use address of first input note as the temporary change address. + SpendingKey changeKey = std::get<3>(zInputsDeque.front()); + PaymentAddress changeAddress = changeKey.address(); + + CAmount vpubOldTarget = 0; + CAmount vpubNewTarget = 0; + if (isToTaddr_) { + vpubNewTarget = z_inputs_total; + } else { + if (utxoInputs_.empty()) { + vpubNewTarget = minersFee; + } else { + vpubOldTarget = t_inputs_total - minersFee; + } + } + + // Keep track of treestate within this transaction + boost::unordered_map intermediates; + std::vector previousCommitments; + + while (!vpubNewProcessed) { + MergeToAddressJSInfo info; + info.vpub_old = 0; + info.vpub_new = 0; + + // Set vpub_old in the first joinsplit + if (!vpubOldProcessed) { + if (t_inputs_total < vpubOldTarget) { + throw JSONRPCError(RPC_WALLET_ERROR, + strprintf("Insufficient transparent funds for vpub_old %s (miners fee %s, taddr inputs %s)", + FormatMoney(vpubOldTarget), FormatMoney(minersFee), FormatMoney(t_inputs_total))); + } + info.vpub_old += vpubOldTarget; // funds flowing from public pool + vpubOldProcessed = true; + } + + CAmount jsInputValue = 0; + uint256 jsAnchor; + std::vector> witnesses; + + JSDescription prevJoinSplit; + + // Keep track of previous JoinSplit and its commitments + if (tx_.vjoinsplit.size() > 0) { + prevJoinSplit = tx_.vjoinsplit.back(); + } + + // If there is no change, the chain has terminated so we can reset the tracked treestate. + if (jsChange == 0 && tx_.vjoinsplit.size() > 0) { + intermediates.clear(); + previousCommitments.clear(); + } + + // + // Consume change as the first input of the JoinSplit. + // + if (jsChange > 0) { + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Update tree state with previous joinsplit + ZCIncrementalMerkleTree tree; + auto it = intermediates.find(prevJoinSplit.anchor); + if (it != intermediates.end()) { + tree = it->second; + } else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); + } + + assert(changeOutputIndex != -1); + boost::optional changeWitness; + int n = 0; + for (const uint256& commitment : prevJoinSplit.commitments) { + tree.append(commitment); + previousCommitments.push_back(commitment); + if (!changeWitness && changeOutputIndex == n++) { + changeWitness = tree.witness(); + } else if (changeWitness) { + changeWitness.get().append(commitment); + } + } + if (changeWitness) { + witnesses.push_back(changeWitness); + } + jsAnchor = tree.root(); + intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) + + // Decrypt the change note's ciphertext to retrieve some data we need + ZCNoteDecryption decryptor(changeKey.receiving_key()); + auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); + try { + NotePlaintext plaintext = NotePlaintext::decrypt( + decryptor, + prevJoinSplit.ciphertexts[changeOutputIndex], + prevJoinSplit.ephemeralKey, + hSig, + (unsigned char)changeOutputIndex); + + Note note = plaintext.note(changeAddress); + info.notes.push_back(note); + info.zkeys.push_back(changeKey); + + jsInputValue += plaintext.value; + + LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", + getId(), + FormatMoney(plaintext.value)); + + } catch (const std::exception& e) { + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); + } + } + + + // + // Consume spendable non-change notes + // + std::vector vInputNotes; + std::vector vInputZKeys; + std::vector vOutPoints; + std::vector> vInputWitnesses; + uint256 inputAnchor; + int numInputsNeeded = (jsChange > 0) ? 1 : 0; + while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { + MergeToAddressInputNote t = zInputsDeque.front(); + JSOutPoint jso = std::get<0>(t); + Note note = std::get<1>(t); + CAmount noteFunds = std::get<2>(t); + SpendingKey zkey = std::get<3>(t); + zInputsDeque.pop_front(); + + MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()]; + vInputWitnesses.push_back(wad.witness); + if (inputAnchor.IsNull()) { + inputAnchor = wad.anchor; + } else if (inputAnchor != wad.anchor) { + throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); + } + + vOutPoints.push_back(jso); + vInputNotes.push_back(note); + vInputZKeys.push_back(zkey); + + jsInputValue += noteFunds; + + int wtxHeight = -1; + int wtxDepth = -1; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + const CWalletTx& wtx = pwalletMain->mapWallet[jso.hash]; + // Zero confirmation notes belong to transactions which have not yet been mined + if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); + } + wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; + wtxDepth = wtx.GetDepthInMainChain(); + } + LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", + getId(), + jso.hash.ToString().substr(0, 10), + jso.js, + int(jso.n), // uint8_t + FormatMoney(noteFunds), + wtxHeight, + wtxDepth); + } + + // Add history of previous commitments to witness + if (vInputNotes.size() > 0) { + if (vInputWitnesses.size() == 0) { + throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); + } + + for (auto& optionalWitness : vInputWitnesses) { + if (!optionalWitness) { + throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); + } + ZCIncrementalWitness w = *optionalWitness; // could use .get(); + if (jsChange > 0) { + for (const uint256& commitment : previousCommitments) { + w.append(commitment); + } + if (jsAnchor != w.root()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Witness for spendable note does not have same anchor as change input"); + } + } + witnesses.push_back(w); + } + + // The jsAnchor is null if this JoinSplit is at the start of a new chain + if (jsAnchor.IsNull()) { + jsAnchor = inputAnchor; + } + + // Add spendable notes as inputs + std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); + std::copy(vInputZKeys.begin(), vInputZKeys.end(), std::back_inserter(info.zkeys)); + } + + // Accumulate change + jsChange = jsInputValue + info.vpub_old; + + // Set vpub_new in the last joinsplit (when there are no more notes to spend) + if (zInputsDeque.empty()) { + assert(!vpubNewProcessed); + if (jsInputValue < vpubNewTarget) { + throw JSONRPCError(RPC_WALLET_ERROR, + strprintf("Insufficient funds for vpub_new %s (miners fee %s, taddr inputs %s)", + FormatMoney(vpubNewTarget), FormatMoney(minersFee), FormatMoney(t_inputs_total))); + } + info.vpub_new += vpubNewTarget; // funds flowing back to public pool + vpubNewProcessed = true; + jsChange -= vpubNewTarget; + // If we are merging to a t-addr, there should be no change + if (isToTaddr_) assert(jsChange == 0); + } + + // create dummy output + info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new + + // create output for any change + if (jsChange > 0) { + std::string outputType = "change"; + auto jso = JSOutput(changeAddress, jsChange); + // If this is the final output, set the target and memo + if (isToZaddr_ && vpubNewProcessed) { + outputType = "target"; + jso.addr = toPaymentAddress_; + if (!hexMemo.empty()) { + jso.memo = get_memo_from_hex_string(hexMemo); + } + } + info.vjsout.push_back(jso); + + LogPrint("zrpcunsafe", "%s: generating note for %s (amount=%s)\n", + getId(), + outputType, + FormatMoney(jsChange)); + } + + obj = perform_joinsplit(info, witnesses, jsAnchor); + + if (jsChange > 0) { + changeOutputIndex = mta_find_output(obj, 1); + } + } + + // Sanity check in case changes to code block above exits loop by invoking 'break' + assert(zInputsDeque.size() == 0); + assert(vpubNewProcessed); + + sign_send_raw_transaction(obj); + return true; +} + + +/** + * Sign and send a raw transaction. + * Raw transaction as hex string should be in object field "rawtxn" + */ +void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) +{ + // Sign the raw transaction + UniValue rawtxnValue = find_value(obj, "rawtxn"); + if (rawtxnValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); + } + std::string rawtxn = rawtxnValue.get_str(); + + UniValue params = UniValue(UniValue::VARR); + params.push_back(rawtxn); + UniValue signResultValue = signrawtransaction(params, false); + UniValue signResultObject = signResultValue.get_obj(); + UniValue completeValue = find_value(signResultObject, "complete"); + bool complete = completeValue.get_bool(); + if (!complete) { + // TODO: #1366 Maybe get "errors" and print array vErrors into a string + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); + } + + UniValue hexValue = find_value(signResultObject, "hex"); + if (hexValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); + } + std::string signedtxn = hexValue.get_str(); + + // Send the signed transaction + if (!testmode) { + params.clear(); + params.setArray(); + params.push_back(signedtxn); + UniValue sendResultValue = sendrawtransaction(params, false); + if (sendResultValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); + } + + std::string txid = sendResultValue.get_str(); + + UniValue o(UniValue::VOBJ); + o.push_back(Pair("txid", txid)); + set_result(o); + } else { + // Test mode does not send the transaction to the network. + + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + + UniValue o(UniValue::VOBJ); + o.push_back(Pair("test", 1)); + o.push_back(Pair("txid", tx.GetHash().ToString())); + o.push_back(Pair("hex", signedtxn)); + set_result(o); + } + + // Keep the signed transaction so we can hash to the same txid + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + tx_ = tx; +} + + +UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info) +{ + std::vector> witnesses; + uint256 anchor; + { + LOCK(cs_main); + anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor + } + return perform_joinsplit(info, witnesses, anchor); +} + + +UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInfo& info, std::vector& outPoints) +{ + std::vector> witnesses; + uint256 anchor; + { + LOCK(cs_main); + pwalletMain->GetNoteWitnesses(outPoints, witnesses, anchor); + } + return perform_joinsplit(info, witnesses, anchor); +} + +UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor) +{ + if (anchor.IsNull()) { + throw std::runtime_error("anchor is null"); + } + + if (witnesses.size() != info.notes.size()) { + throw runtime_error("number of notes and witnesses do not match"); + } + + if (info.notes.size() != info.zkeys.size()) { + throw runtime_error("number of notes and spending keys do not match"); + } + + for (size_t i = 0; i < witnesses.size(); i++) { + if (!witnesses[i]) { + throw runtime_error("joinsplit input could not be found in tree"); + } + info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], info.zkeys[i])); + } + + // Make sure there are two inputs and two outputs + while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { + info.vjsin.push_back(JSInput()); + } + + while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { + info.vjsout.push_back(JSOutput()); + } + + if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { + throw runtime_error("unsupported joinsplit input/output counts"); + } + + CMutableTransaction mtx(tx_); + + LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", + getId(), + tx_.vjoinsplit.size(), + FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), + FormatMoney(info.vjsin[0].note.value), FormatMoney(info.vjsin[1].note.value), + FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); + + // Generate the proof, this can take over a minute. + boost::array inputs{info.vjsin[0], info.vjsin[1]}; + boost::array outputs{info.vjsout[0], info.vjsout[1]}; + boost::array inputMap; + boost::array outputMap; + + uint256 esk; // payment disclosure - secret + + JSDescription jsdesc = JSDescription::Randomized( + *pzcashParams, + joinSplitPubKey_, + anchor, + inputs, + outputs, + inputMap, + outputMap, + info.vpub_old, + info.vpub_new, + !this->testmode, + &esk); // parameter expects pointer to esk, so pass in address + { + auto verifier = libzcash::ProofVerifier::Strict(); + if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { + throw std::runtime_error("error verifying joinsplit"); + } + } + + mtx.vjoinsplit.push_back(jsdesc); + + // Empty output script. + CScript scriptCode; + CTransaction signTx(mtx); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); + + // Add the signature + if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, + dataToBeSigned.begin(), 32, + joinSplitPrivKey_) == 0)) { + throw std::runtime_error("crypto_sign_detached failed"); + } + + // Sanity check + if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], + dataToBeSigned.begin(), 32, + mtx.joinSplitPubKey.begin()) == 0)) { + throw std::runtime_error("crypto_sign_verify_detached failed"); + } + + CTransaction rawTx(mtx); + tx_ = rawTx; + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << rawTx; + + std::string encryptedNote1; + std::string encryptedNote2; + { + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << ((unsigned char)0x00); + ss2 << jsdesc.ephemeralKey; + ss2 << jsdesc.ciphertexts[0]; + ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); + + encryptedNote1 = HexStr(ss2.begin(), ss2.end()); + } + { + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << ((unsigned char)0x01); + ss2 << jsdesc.ephemeralKey; + ss2 << jsdesc.ciphertexts[1]; + ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); + + encryptedNote2 = HexStr(ss2.begin(), ss2.end()); + } + + UniValue arrInputMap(UniValue::VARR); + UniValue arrOutputMap(UniValue::VARR); + for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { + arrInputMap.push_back(inputMap[i]); + } + for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { + arrOutputMap.push_back(outputMap[i]); + } + + + // !!! Payment disclosure START + unsigned char buffer[32] = {0}; + memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer + std::vector vch(&buffer[0], &buffer[0] + 32); + uint256 joinSplitPrivKey = uint256(vch); + size_t js_index = tx_.vjoinsplit.size() - 1; + uint256 placeholder; + for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { + uint8_t mapped_index = outputMap[i]; + // placeholder for txid will be filled in later when tx has been finalized and signed. + PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; + JSOutput output = outputs[mapped_index]; + libzcash::PaymentAddress zaddr = output.addr; // randomized output + PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; + paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); + + CZCPaymentAddress address(zaddr); + LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString()); + } + // !!! Payment disclosure END + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("encryptednote1", encryptedNote1)); + obj.push_back(Pair("encryptednote2", encryptedNote2)); + obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); + obj.push_back(Pair("inputmap", arrInputMap)); + obj.push_back(Pair("outputmap", arrOutputMap)); + return obj; +} + +boost::array AsyncRPCOperation_mergetoaddress::get_memo_from_hex_string(std::string s) +{ + boost::array memo = {{0x00}}; + + std::vector rawMemo = ParseHex(s.c_str()); + + // If ParseHex comes across a non-hex char, it will stop but still return results so far. + size_t slen = s.length(); + if (slen % 2 != 0 || (slen > 0 && rawMemo.size() != slen / 2)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo must be in hexadecimal format"); + } + + if (rawMemo.size() > ZC_MEMO_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Memo size of %d is too big, maximum allowed is %d", rawMemo.size(), ZC_MEMO_SIZE)); + } + + // copy vector into boost array + int lenMemo = rawMemo.size(); + for (int i = 0; i < ZC_MEMO_SIZE && i < lenMemo; i++) { + memo[i] = rawMemo[i]; + } + return memo; +} + +/** + * Override getStatus() to append the operation's input parameters to the default status object. + */ +UniValue AsyncRPCOperation_mergetoaddress::getStatus() const +{ + UniValue v = AsyncRPCOperation::getStatus(); + if (contextinfo_.isNull()) { + return v; + } + + UniValue obj = v.get_obj(); + obj.push_back(Pair("method", "z_mergetoaddress")); + obj.push_back(Pair("params", contextinfo_)); + return obj; +} + +/** + * Lock input utxos + */ + void AsyncRPCOperation_mergetoaddress::lock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : utxoInputs_) { + pwalletMain->LockCoin(std::get<0>(utxo)); + } +} + +/** + * Unlock input utxos + */ +void AsyncRPCOperation_mergetoaddress::unlock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : utxoInputs_) { + pwalletMain->UnlockCoin(std::get<0>(utxo)); + } +} diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h new file mode 100644 index 000000000..1619b5c97 --- /dev/null +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -0,0 +1,189 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ASYNCRPCOPERATION_MERGETOADDRESS_H +#define ASYNCRPCOPERATION_MERGETOADDRESS_H + +#include "amount.h" +#include "asyncrpcoperation.h" +#include "base58.h" +#include "paymentdisclosure.h" +#include "primitives/transaction.h" +#include "wallet.h" +#include "zcash/Address.hpp" +#include "zcash/JoinSplit.hpp" + +#include +#include + +#include + +// Default transaction fee if caller does not specify one. +#define MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE 10000 + +using namespace libzcash; + +// Input UTXO is a tuple of txid, vout, amount +typedef std::tuple MergeToAddressInputUTXO; + +// Input JSOP is a tuple of JSOutpoint, note, amount, spending key +typedef std::tuple MergeToAddressInputNote; + +// A recipient is a tuple of address, memo (optional if zaddr) +typedef std::tuple MergeToAddressRecipient; + +// Package of info which is passed to perform_joinsplit methods. +struct MergeToAddressJSInfo { + std::vector vjsin; + std::vector vjsout; + std::vector notes; + std::vector zkeys; + CAmount vpub_old = 0; + CAmount vpub_new = 0; +}; + +// A struct to help us track the witness and anchor for a given JSOutPoint +struct MergeToAddressWitnessAnchorData { + boost::optional witness; + uint256 anchor; +}; + +class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation +{ +public: + AsyncRPCOperation_mergetoaddress( + CMutableTransaction contextualTx, + std::vector utxoInputs, + std::vector noteInputs, + MergeToAddressRecipient recipient, + CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE, + UniValue contextInfo = NullUniValue); + virtual ~AsyncRPCOperation_mergetoaddress(); + + // We don't want to be copied or moved around + AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy construct + AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress&&) = delete; // Move construct + AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy assign + AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress&&) = delete; // Move assign + + virtual void main(); + + virtual UniValue getStatus() const; + + bool testmode = false; // Set to true to disable sending txs and generating proofs + + bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + +private: + friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing + + UniValue contextinfo_; // optional data to include in return value from getStatus() + + uint32_t consensusBranchId_; + CAmount fee_; + int mindepth_; + MergeToAddressRecipient recipient_; + bool isToTaddr_; + bool isToZaddr_; + CBitcoinAddress toTaddr_; + PaymentAddress toPaymentAddress_; + + uint256 joinSplitPubKey_; + unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; + + // The key is the result string from calling JSOutPoint::ToString() + std::unordered_map jsopWitnessAnchorMap; + + std::vector utxoInputs_; + std::vector noteInputs_; + + CTransaction tx_; + + boost::array get_memo_from_hex_string(std::string s); + bool main_impl(); + + // JoinSplit without any input notes to spend + UniValue perform_joinsplit(MergeToAddressJSInfo&); + + // JoinSplit with input notes to spend (JSOutPoints)) + UniValue perform_joinsplit(MergeToAddressJSInfo&, std::vector&); + + // JoinSplit where you have the witnesses and anchor + UniValue perform_joinsplit( + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor); + + void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error + + void lock_utxos(); + + void unlock_utxos(); + + // payment disclosure! + std::vector paymentDisclosureData_; +}; + + +// To test private methods, a friend class can act as a proxy +class TEST_FRIEND_AsyncRPCOperation_mergetoaddress +{ +public: + std::shared_ptr delegate; + + TEST_FRIEND_AsyncRPCOperation_mergetoaddress(std::shared_ptr ptr) : delegate(ptr) {} + + CTransaction getTx() + { + return delegate->tx_; + } + + void setTx(CTransaction tx) + { + delegate->tx_ = tx; + } + + // Delegated methods + + boost::array get_memo_from_hex_string(std::string s) + { + return delegate->get_memo_from_hex_string(s); + } + + bool main_impl() + { + return delegate->main_impl(); + } + + UniValue perform_joinsplit(MergeToAddressJSInfo& info) + { + return delegate->perform_joinsplit(info); + } + + UniValue perform_joinsplit(MergeToAddressJSInfo& info, std::vector& v) + { + return delegate->perform_joinsplit(info, v); + } + + UniValue perform_joinsplit( + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor) + { + return delegate->perform_joinsplit(info, witnesses, anchor); + } + + void sign_send_raw_transaction(UniValue obj) + { + delegate->sign_send_raw_transaction(obj); + } + + void set_state(OperationStatus state) + { + delegate->state_.store(state); + } +}; + + +#endif /* ASYNCRPCOPERATION_MERGETOADDRESS_H */ diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 4e8a20be6..6f33b514e 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -5,6 +5,7 @@ #include "asyncrpcoperation_sendmany.h" #include "asyncrpcqueue.h" #include "amount.h" +#include "consensus/upgrades.h" #include "core_io.h" #include "init.h" #include "main.h" @@ -30,6 +31,8 @@ #include #include +#include "paymentdisclosuredb.h" + using namespace libzcash; int find_output(UniValue obj, int n) { @@ -50,13 +53,14 @@ int find_output(UniValue obj, int n) { } AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( + CMutableTransaction contextualTx, std::string fromAddress, std::vector tOutputs, std::vector zOutputs, int minDepth, CAmount fee, UniValue contextInfo) : - fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo) + tx_(contextualTx), fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo) { assert(fee_ >= 0); @@ -95,12 +99,20 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( } } + if (isfromzaddr_ && minDepth==0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Minconf cannot be zero when sending from zaddr"); + } + // Log the context info i.e. the call parameters to z_sendmany if (LogAcceptCategory("zrpcunsafe")) { LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write()); } else { LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } + + + // Enable payment disclosure if requested + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { @@ -167,6 +179,21 @@ void AsyncRPCOperation_sendmany::main() { s += strprintf(", error=%s)\n", getErrorMessage()); } LogPrintf("%s",s); + + // !!! Payment disclosure START + if (success && paymentDisclosureMode && paymentDisclosureData_.size()>0) { + uint256 txidhash = tx_.GetHash(); + std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); + for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { + p.first.hash = txidhash; + if (!db->Put(p.first, p.second)) { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); + } else { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); + } + } + } + // !!! Payment disclosure END } // Notes: @@ -283,6 +310,15 @@ bool AsyncRPCOperation_sendmany::main_impl() { t_inputs_ = selectedTInputs; t_inputs_total = selectedUTXOAmount; + // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects + size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); + if (limit > 0) { + size_t n = t_inputs_.size(); + if (n > limit) { + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Too many transparent inputs %zu > limit %zu", n, limit)); + } + } + // update the transaction with these inputs CMutableTransaction rawTx(tx_); for (SendManyInputUTXO & t : t_inputs_) { @@ -304,6 +340,12 @@ bool AsyncRPCOperation_sendmany::main_impl() { LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total)); LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee)); + // Grab the current consensus branch ID + { + LOCK(cs_main); + consensusBranchId_ = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + } + /** * SCENARIO #1 * @@ -339,16 +381,20 @@ bool AsyncRPCOperation_sendmany::main_impl() { // Prepare raw transaction to handle JoinSplits CMutableTransaction mtx(tx_); - mtx.nVersion = 2; crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); mtx.joinSplitPubKey = joinSplitPubKey_; mtx.nLockTime = (uint32_t)time(NULL) - 60; // jl777 tx_ = CTransaction(mtx); // Copy zinputs and zoutputs to more flexible containers - std::deque zInputsDeque; + std::deque zInputsDeque; // zInputsDeque stores minimum numbers of notes for target amount + CAmount tmp = 0; for (auto o : z_inputs_) { zInputsDeque.push_back(o); + tmp += std::get<2>(o); + if (tmp >= targetAmount) { + break; + } } std::deque zOutputsDeque; for (auto o : z_outputs_) { @@ -446,283 +492,220 @@ bool AsyncRPCOperation_sendmany::main_impl() { * zaddr -> taddrs * -> zaddrs * - * Processing order: - * Part 1: taddrs and miners fee - * Part 2: zaddrs - */ - - /** - * SCENARIO #3 - * Part 1: Add to the transparent value pool. + * Send to zaddrs by chaining JoinSplits together and immediately consuming any change + * Send to taddrs by creating dummy z outputs and accumulating value in a change note + * which is used to set vpub_new in the last chained joinsplit. */ UniValue obj(UniValue::VOBJ); CAmount jsChange = 0; // this is updated after each joinsplit int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 - bool minersFeeProcessed = false; - + bool vpubNewProcessed = false; // updated when vpub_new for miner fee and taddr outputs is set in last joinsplit + CAmount vpubNewTarget = minersFee; if (t_outputs_total > 0) { add_taddr_outputs_to_tx(); - CAmount taddrTargetAmount = t_outputs_total + minersFee; - minersFeeProcessed = true; - while (zInputsDeque.size() > 0 && taddrTargetAmount > 0) { - AsyncJoinSplitInfo info; - info.vpub_old = 0; - info.vpub_new = 0; - std::vector outPoints; - int n = 0; - while (n++ < ZC_NUM_JS_INPUTS && taddrTargetAmount > 0) { - SendManyInputJSOP o = zInputsDeque.front(); - JSOutPoint outPoint = std::get<0>(o); - Note note = std::get<1>(o); - CAmount noteFunds = std::get<2>(o); - zInputsDeque.pop_front(); - - info.notes.push_back(note); - outPoints.push_back(outPoint); - - int wtxHeight = -1; - int wtxDepth = -1; - { - LOCK2(cs_main, pwalletMain->cs_wallet); - const CWalletTx& wtx = pwalletMain->mapWallet[outPoint.hash]; - wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; - wtxDepth = wtx.GetDepthInMainChain(); - } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", - getId(), - outPoint.hash.ToString().substr(0, 10), - outPoint.js, - int(outPoint.n), // uint8_t - FormatMoney(noteFunds), - wtxHeight, - wtxDepth - ); - - - // Put value back into the value pool - if (noteFunds >= taddrTargetAmount) { - jsChange = noteFunds - taddrTargetAmount; - info.vpub_new += taddrTargetAmount; - } else { - info.vpub_new += noteFunds; - } - - taddrTargetAmount -= noteFunds; - if (taddrTargetAmount <= 0) { - break; - } - } - - if (jsChange > 0) { - info.vjsout.push_back(JSOutput()); - info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange)); - - LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n", - getId(), - FormatMoney(jsChange) - ); - } - - obj = perform_joinsplit(info, outPoints); - - if (jsChange > 0) { - changeOutputIndex = find_output(obj, 1); - } - } + vpubNewTarget += t_outputs_total; } + // Keep track of treestate within this transaction + boost::unordered_map intermediates; + std::vector previousCommitments; - /** - * SCENARIO #3 - * Part 2: Send to zaddrs by chaining JoinSplits together and immediately consuming any change - */ - if (z_outputs_total>0) { + while (!vpubNewProcessed) { + AsyncJoinSplitInfo info; + info.vpub_old = 0; + info.vpub_new = 0; - // Keep track of treestate within this transaction - boost::unordered_map intermediates; - std::vector previousCommitments; + CAmount jsInputValue = 0; + uint256 jsAnchor; + std::vector> witnesses; - while (zOutputsDeque.size() > 0) { - AsyncJoinSplitInfo info; - info.vpub_old = 0; - info.vpub_new = 0; + JSDescription prevJoinSplit; - CAmount jsInputValue = 0; - uint256 jsAnchor; - std::vector> witnesses; + // Keep track of previous JoinSplit and its commitments + if (tx_.vjoinsplit.size() > 0) { + prevJoinSplit = tx_.vjoinsplit.back(); + } - JSDescription prevJoinSplit; + // If there is no change, the chain has terminated so we can reset the tracked treestate. + if (jsChange==0 && tx_.vjoinsplit.size() > 0) { + intermediates.clear(); + previousCommitments.clear(); + } - // Keep track of previous JoinSplit and its commitments - if (tx_.vjoinsplit.size() > 0) { - prevJoinSplit = tx_.vjoinsplit.back(); + // + // Consume change as the first input of the JoinSplit. + // + if (jsChange > 0) { + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Update tree state with previous joinsplit + ZCIncrementalMerkleTree tree; + auto it = intermediates.find(prevJoinSplit.anchor); + if (it != intermediates.end()) { + tree = it->second; + } else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); } - // If there is no change, the chain has terminated so we can reset the tracked treestate. - if (jsChange==0 && tx_.vjoinsplit.size() > 0) { - intermediates.clear(); - previousCommitments.clear(); + assert(changeOutputIndex != -1); + boost::optional changeWitness; + int n = 0; + for (const uint256& commitment : prevJoinSplit.commitments) { + tree.append(commitment); + previousCommitments.push_back(commitment); + if (!changeWitness && changeOutputIndex == n++) { + changeWitness = tree.witness(); + } else if (changeWitness) { + changeWitness.get().append(commitment); + } + } + if (changeWitness) { + witnesses.push_back(changeWitness); + } + jsAnchor = tree.root(); + intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) + + // Decrypt the change note's ciphertext to retrieve some data we need + ZCNoteDecryption decryptor(spendingkey_.receiving_key()); + auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); + try { + NotePlaintext plaintext = NotePlaintext::decrypt( + decryptor, + prevJoinSplit.ciphertexts[changeOutputIndex], + prevJoinSplit.ephemeralKey, + hSig, + (unsigned char) changeOutputIndex); + + Note note = plaintext.note(frompaymentaddress_); + info.notes.push_back(note); + + jsInputValue += plaintext.value; + + LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", + getId(), + FormatMoney(plaintext.value) + ); + + } catch (const std::exception& e) { + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); + } + } + + + // + // Consume spendable non-change notes + // + std::vector vInputNotes; + std::vector vOutPoints; + std::vector> vInputWitnesses; + uint256 inputAnchor; + int numInputsNeeded = (jsChange>0) ? 1 : 0; + while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { + SendManyInputJSOP t = zInputsDeque.front(); + JSOutPoint jso = std::get<0>(t); + Note note = std::get<1>(t); + CAmount noteFunds = std::get<2>(t); + zInputsDeque.pop_front(); + + WitnessAnchorData wad = jsopWitnessAnchorMap[ jso.ToString() ]; + vInputWitnesses.push_back(wad.witness); + if (inputAnchor.IsNull()) { + inputAnchor = wad.anchor; + } else if (inputAnchor != wad.anchor) { + throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); } - // - // Consume change as the first input of the JoinSplit. - // - if (jsChange > 0) { + vOutPoints.push_back(jso); + vInputNotes.push_back(note); + + jsInputValue += noteFunds; + + int wtxHeight = -1; + int wtxDepth = -1; + { LOCK2(cs_main, pwalletMain->cs_wallet); - - // Update tree state with previous joinsplit - ZCIncrementalMerkleTree tree; - auto it = intermediates.find(prevJoinSplit.anchor); - if (it != intermediates.end()) { - tree = it->second; - } else if (!pcoinsTip->GetAnchorAt(prevJoinSplit.anchor, tree)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); + const CWalletTx& wtx = pwalletMain->mapWallet[jso.hash]; + // Zero-confirmation notes belong to transactions which have not yet been mined + if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); } + wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; + wtxDepth = wtx.GetDepthInMainChain(); + } + LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", + getId(), + jso.hash.ToString().substr(0, 10), + jso.js, + int(jso.n), // uint8_t + FormatMoney(noteFunds), + wtxHeight, + wtxDepth + ); + } + + // Add history of previous commitments to witness + if (vInputNotes.size() > 0) { - assert(changeOutputIndex != -1); - boost::optional changeWitness; - int n = 0; - for (const uint256& commitment : prevJoinSplit.commitments) { - tree.append(commitment); - previousCommitments.push_back(commitment); - if (!changeWitness && changeOutputIndex == n++) { - changeWitness = tree.witness(); - } else if (changeWitness) { - changeWitness.get().append(commitment); + if (vInputWitnesses.size()==0) { + throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); + } + + for (auto & optionalWitness : vInputWitnesses) { + if (!optionalWitness) { + throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); + } + ZCIncrementalWitness w = *optionalWitness; // could use .get(); + if (jsChange > 0) { + for (const uint256& commitment : previousCommitments) { + w.append(commitment); + } + if (jsAnchor != w.root()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Witness for spendable note does not have same anchor as change input"); } } - if (changeWitness) { - witnesses.push_back(changeWitness); - } - jsAnchor = tree.root(); - intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) - - // Decrypt the change note's ciphertext to retrieve some data we need - ZCNoteDecryption decryptor(spendingkey_.viewing_key()); - auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); - try { - NotePlaintext plaintext = NotePlaintext::decrypt( - decryptor, - prevJoinSplit.ciphertexts[changeOutputIndex], - prevJoinSplit.ephemeralKey, - hSig, - (unsigned char) changeOutputIndex); - - Note note = plaintext.note(frompaymentaddress_); - info.notes.push_back(note); - - jsInputValue += plaintext.value; - - LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", - getId(), - FormatMoney(plaintext.value) - ); - - } catch (const std::exception& e) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); - } + witnesses.push_back(w); } - - // - // Consume spendable non-change notes - // - std::vector vInputNotes; - std::vector vOutPoints; - std::vector> vInputWitnesses; - uint256 inputAnchor; - int numInputsNeeded = (jsChange>0) ? 1 : 0; - while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { - SendManyInputJSOP t = zInputsDeque.front(); - JSOutPoint jso = std::get<0>(t); - Note note = std::get<1>(t); - CAmount noteFunds = std::get<2>(t); - zInputsDeque.pop_front(); - - WitnessAnchorData wad = jsopWitnessAnchorMap[ jso.ToString() ]; - vInputWitnesses.push_back(wad.witness); - if (inputAnchor.IsNull()) { - inputAnchor = wad.anchor; - } else if (inputAnchor != wad.anchor) { - throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); - } - - vOutPoints.push_back(jso); - vInputNotes.push_back(note); - - jsInputValue += noteFunds; - - int wtxHeight = -1; - int wtxDepth = -1; - { - LOCK2(cs_main, pwalletMain->cs_wallet); - const CWalletTx& wtx = pwalletMain->mapWallet[jso.hash]; - wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; - wtxDepth = wtx.GetDepthInMainChain(); - } - LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", - getId(), - jso.hash.ToString().substr(0, 10), - jso.js, - int(jso.n), // uint8_t - FormatMoney(noteFunds), - wtxHeight, - wtxDepth - ); + // The jsAnchor is null if this JoinSplit is at the start of a new chain + if (jsAnchor.IsNull()) { + jsAnchor = inputAnchor; } - // Add history of previous commitments to witness - if (vInputNotes.size() > 0) { + // Add spendable notes as inputs + std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); + } - if (vInputWitnesses.size()==0) { - throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); - } - - for (auto & optionalWitness : vInputWitnesses) { - if (!optionalWitness) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); - } - ZCIncrementalWitness w = *optionalWitness; // could use .get(); - if (jsChange > 0) { - for (const uint256& commitment : previousCommitments) { - w.append(commitment); - } - if (jsAnchor != w.root()) { - throw JSONRPCError(RPC_WALLET_ERROR, "Witness for spendable note does not have same anchor as change input"); - } - } - witnesses.push_back(w); - } - - // The jsAnchor is null if this JoinSplit is at the start of a new chain - if (jsAnchor.IsNull()) { - jsAnchor = inputAnchor; - } - - // Add spendable notes as inputs - std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); - } - - - // - // Find recipient to transfer funds to - // + // Find recipient to transfer funds to + std::string address, hexMemo; + CAmount value = 0; + if (zOutputsDeque.size() > 0) { SendManyRecipient smr = zOutputsDeque.front(); - std::string address = std::get<0>(smr); - CAmount value = std::get<1>(smr); - std::string hexMemo = std::get<2>(smr); + address = std::get<0>(smr); + value = std::get<1>(smr); + hexMemo = std::get<2>(smr); zOutputsDeque.pop_front(); + } - // Will we have any change? Has the miners fee been processed yet? - jsChange = 0; - CAmount outAmount = value; - if (!minersFeeProcessed) { - if (jsInputValue < minersFee) { - throw JSONRPCError(RPC_WALLET_ERROR, "Not enough funds to pay miners fee"); - } - outAmount += minersFee; + // Reset change + jsChange = 0; + CAmount outAmount = value; + + // Set vpub_new in the last joinsplit (when there are no more notes to spend or zaddr outputs to satisfy) + if (zOutputsDeque.size() == 0 && zInputsDeque.size() == 0) { + assert(!vpubNewProcessed); + if (jsInputValue < vpubNewTarget) { + throw JSONRPCError(RPC_WALLET_ERROR, + strprintf("Insufficient funds for vpub_new %s (miners fee %s, taddr outputs %s)", + FormatMoney(vpubNewTarget), FormatMoney(minersFee), FormatMoney(t_outputs_total))); } - + outAmount += vpubNewTarget; + info.vpub_new += vpubNewTarget; // funds flowing back to public pool + vpubNewProcessed = true; + jsChange = jsInputValue - outAmount; + assert(jsChange >= 0); + } + else { + // This is not the last joinsplit, so compute change and any amount still due to the recipient if (jsInputValue > outAmount) { jsChange = jsInputValue - outAmount; } else if (outAmount > jsInputValue) { @@ -733,42 +716,44 @@ bool AsyncRPCOperation_sendmany::main_impl() { // reduce the amount being sent right now to the value of all inputs value = jsInputValue; - if (!minersFeeProcessed) { - value -= minersFee; - } } + } - if (!minersFeeProcessed) { - minersFeeProcessed = true; - info.vpub_new += minersFee; // funds flowing back to public pool - } - - // create output for recipient + // create output for recipient + if (address.empty()) { + assert(value==0); + info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new + } else { PaymentAddress pa = CZCPaymentAddress(address).Get(); JSOutput jso = JSOutput(pa, value); if (hexMemo.size() > 0) { jso.memo = get_memo_from_hex_string(hexMemo); } info.vjsout.push_back(jso); + } - // create output for any change - if (jsChange>0) { - info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange)); + // create output for any change + if (jsChange>0) { + info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange)); - LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n", - getId(), - FormatMoney(jsChange) - ); - } + LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n", + getId(), + FormatMoney(jsChange) + ); + } - obj = perform_joinsplit(info, witnesses, jsAnchor); + obj = perform_joinsplit(info, witnesses, jsAnchor); - if (jsChange > 0) { - changeOutputIndex = find_output(obj, 1); - } + if (jsChange > 0) { + changeOutputIndex = find_output(obj, 1); } } + // Sanity check in case changes to code block above exits loop by invoking 'break' + assert(zInputsDeque.size() == 0); + assert(zOutputsDeque.size() == 0); + assert(vpubNewProcessed); + sign_send_raw_transaction(obj); return true; } @@ -850,6 +835,10 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { pwalletMain->AvailableCoins(vecOutputs, false, NULL, true, fAcceptCoinbase); BOOST_FOREACH(const COutput& out, vecOutputs) { + if (!out.fSpendable) { + continue; + } + if (out.nDepth < mindepth_) { continue; } @@ -921,7 +910,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info std::vector> witnesses; uint256 anchor; { - LOCK2(cs_main, pwalletMain->cs_wallet); + LOCK(cs_main); anchor = pcoinsTip->GetBestAnchor(); // As there are no inputs, ask the wallet for the best anchor } return perform_joinsplit(info, witnesses, anchor); @@ -986,13 +975,15 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( {info.vjsin[0], info.vjsin[1]}; boost::array outputs {info.vjsout[0], info.vjsout[1]}; - #ifdef __LP64__ +#ifdef __LP64__ boost::array inputMap; boost::array outputMap; - #else +#else boost::array inputMap; boost::array outputMap; - #endif +#endif + uint256 esk; // payment disclosure - secret + JSDescription jsdesc = JSDescription::Randomized( *pzcashParams, joinSplitPubKey_, @@ -1003,8 +994,8 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( outputMap, info.vpub_old, info.vpub_new, - !this->testmode); - + !this->testmode, + &esk); // parameter expects pointer to esk, so pass in address { auto verifier = libzcash::ProofVerifier::Strict(); if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { @@ -1017,7 +1008,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( // Empty output script. CScript scriptCode; CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); // Add the signature if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, @@ -1073,6 +1064,28 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( arrOutputMap.push_back(outputMap[i]); } + + // !!! Payment disclosure START + unsigned char buffer[32] = {0}; + memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer + std::vector vch(&buffer[0], &buffer[0] + 32); + uint256 joinSplitPrivKey = uint256(vch); + size_t js_index = tx_.vjoinsplit.size() - 1; + uint256 placeholder; + for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { + uint8_t mapped_index = outputMap[i]; + // placeholder for txid will be filled in later when tx has been finalized and signed. + PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; + JSOutput output = outputs[mapped_index]; + libzcash::PaymentAddress zaddr = output.addr; // randomized output + PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; + paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); + + CZCPaymentAddress address(zaddr); + LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString()); + } + // !!! Payment disclosure END + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("encryptednote1", encryptedNote1)); obj.push_back(Pair("encryptednote2", encryptedNote2)); diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index c69fce4c9..9d812fae1 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -12,6 +12,7 @@ #include "zcash/JoinSplit.hpp" #include "zcash/Address.hpp" #include "wallet.h" +#include "paymentdisclosure.h" #include #include @@ -50,7 +51,7 @@ struct WitnessAnchorData { class AsyncRPCOperation_sendmany : public AsyncRPCOperation { public: - AsyncRPCOperation_sendmany(std::string fromAddress, std::vector tOutputs, std::vector zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue); + AsyncRPCOperation_sendmany(CMutableTransaction contextualTx, std::string fromAddress, std::vector tOutputs, std::vector zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue); virtual ~AsyncRPCOperation_sendmany(); // We don't want to be copied or moved around @@ -65,11 +66,14 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs + bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + private: friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing UniValue contextinfo_; // optional data to include in return value from getStatus() + uint32_t consensusBranchId_; CAmount fee_; int mindepth_; std::string fromaddress_; @@ -113,6 +117,8 @@ private: void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error + // payment disclosure! + std::vector paymentDisclosureData_; }; diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp new file mode 100644 index 000000000..527f810bc --- /dev/null +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -0,0 +1,497 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "asyncrpcqueue.h" +#include "amount.h" +#include "consensus/upgrades.h" +#include "core_io.h" +#include "init.h" +#include "main.h" +#include "net.h" +#include "netbase.h" +#include "rpcserver.h" +#include "timedata.h" +#include "util.h" +#include "utilmoneystr.h" +#include "wallet.h" +#include "walletdb.h" +#include "script/interpreter.h" +#include "utiltime.h" +#include "rpcprotocol.h" +#include "zcash/IncrementalMerkleTree.hpp" +#include "sodium.h" +#include "miner.h" + +#include +#include +#include +#include + +#include "asyncrpcoperation_shieldcoinbase.h" + +#include "paymentdisclosure.h" +#include "paymentdisclosuredb.h" + +using namespace libzcash; + +static int find_output(UniValue obj, int n) { + UniValue outputMapValue = find_value(obj, "outputmap"); + if (!outputMapValue.isArray()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation"); + } + + UniValue outputMap = outputMapValue.get_array(); + assert(outputMap.size() == ZC_NUM_JS_OUTPUTS); + for (size_t i = 0; i < outputMap.size(); i++) { + if (outputMap[i].get_int() == n) { + return i; + } + } + + throw std::logic_error("n is not present in outputmap"); +} + +AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( + CMutableTransaction contextualTx, + std::vector inputs, + std::string toAddress, + CAmount fee, + UniValue contextInfo) : + tx_(contextualTx), inputs_(inputs), fee_(fee), contextinfo_(contextInfo) +{ + assert(contextualTx.nVersion >= 2); // transaction format version must support vjoinsplit + + if (fee < 0 || fee > MAX_MONEY) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range"); + } + + if (inputs.size() == 0) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Empty inputs"); + } + + // Check the destination address is valid for this network i.e. not testnet being used on mainnet + CZCPaymentAddress address(toAddress); + try { + tozaddr_ = address.Get(); + } catch (const std::runtime_error& e) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("runtime error: ") + e.what()); + } + + // Log the context info + if (LogAcceptCategory("zrpcunsafe")) { + LogPrint("zrpcunsafe", "%s: z_shieldcoinbase initialized (context=%s)\n", getId(), contextInfo.write()); + } else { + LogPrint("zrpc", "%s: z_shieldcoinbase initialized\n", getId()); + } + + // Lock UTXOs + lock_utxos(); + + // Enable payment disclosure if requested + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); +} + +AsyncRPCOperation_shieldcoinbase::~AsyncRPCOperation_shieldcoinbase() { +} + +void AsyncRPCOperation_shieldcoinbase::main() { + if (isCancelled()) { + unlock_utxos(); // clean up + return; + } + + set_state(OperationStatus::EXECUTING); + start_execution_clock(); + + bool success = false; + +#ifdef ENABLE_MINING + #ifdef ENABLE_WALLET + GenerateBitcoins(false, NULL, 0); + #else + GenerateBitcoins(false, 0); + #endif +#endif + + try { + success = main_impl(); + } catch (const UniValue& objError) { + int code = find_value(objError, "code").get_int(); + std::string message = find_value(objError, "message").get_str(); + set_error_code(code); + set_error_message(message); + } catch (const runtime_error& e) { + set_error_code(-1); + set_error_message("runtime error: " + string(e.what())); + } catch (const logic_error& e) { + set_error_code(-1); + set_error_message("logic error: " + string(e.what())); + } catch (const exception& e) { + set_error_code(-1); + set_error_message("general exception: " + string(e.what())); + } catch (...) { + set_error_code(-2); + set_error_message("unknown error"); + } + +#ifdef ENABLE_MINING + #ifdef ENABLE_WALLET + GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 1)); + #else + GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 1)); + #endif +#endif + + stop_execution_clock(); + + if (success) { + set_state(OperationStatus::SUCCESS); + } else { + set_state(OperationStatus::FAILED); + } + + std::string s = strprintf("%s: z_shieldcoinbase finished (status=%s", getId(), getStateAsString()); + if (success) { + s += strprintf(", txid=%s)\n", tx_.GetHash().ToString()); + } else { + s += strprintf(", error=%s)\n", getErrorMessage()); + } + LogPrintf("%s",s); + + unlock_utxos(); // clean up + + // !!! Payment disclosure START + if (success && paymentDisclosureMode && paymentDisclosureData_.size()>0) { + uint256 txidhash = tx_.GetHash(); + std::shared_ptr db = PaymentDisclosureDB::sharedInstance(); + for (PaymentDisclosureKeyInfo p : paymentDisclosureData_) { + p.first.hash = txidhash; + if (!db->Put(p.first, p.second)) { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Error writing entry to database for key %s\n", getId(), p.first.ToString()); + } else { + LogPrint("paymentdisclosure", "%s: Payment Disclosure: Successfully added entry to database for key %s\n", getId(), p.first.ToString()); + } + } + } + // !!! Payment disclosure END +} + + +bool AsyncRPCOperation_shieldcoinbase::main_impl() { + + CAmount minersFee = fee_; + + size_t numInputs = inputs_.size(); + + // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects + size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); + if (limit>0 && numInputs > limit) { + throw JSONRPCError(RPC_WALLET_ERROR, + strprintf("Number of inputs %d is greater than mempooltxinputlimit of %d", + numInputs, limit)); + } + + CAmount targetAmount = 0; + for (ShieldCoinbaseUTXO & utxo : inputs_) { + targetAmount += utxo.amount; + } + + if (targetAmount <= minersFee) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, + strprintf("Insufficient coinbase funds, have %s and miners fee is %s", + FormatMoney(targetAmount), FormatMoney(minersFee))); + } + + CAmount sendAmount = targetAmount - minersFee; + LogPrint("zrpc", "%s: spending %s to shield %s with fee %s\n", + getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee)); + + // update the transaction with these inputs + CMutableTransaction rawTx(tx_); + for (ShieldCoinbaseUTXO & t : inputs_) { + CTxIn in(COutPoint(t.txid, t.vout)); + rawTx.vin.push_back(in); + } + tx_ = CTransaction(rawTx); + + // Prepare raw transaction to handle JoinSplits + CMutableTransaction mtx(tx_); + crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); + mtx.joinSplitPubKey = joinSplitPubKey_; + tx_ = CTransaction(mtx); + + // Create joinsplit + UniValue obj(UniValue::VOBJ); + ShieldCoinbaseJSInfo info; + info.vpub_old = sendAmount; + info.vpub_new = 0; + JSOutput jso = JSOutput(tozaddr_, sendAmount); + info.vjsout.push_back(jso); + obj = perform_joinsplit(info); + + sign_send_raw_transaction(obj); + return true; +} + + +/** + * Sign and send a raw transaction. + * Raw transaction as hex string should be in object field "rawtxn" + */ +void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj) +{ + // Sign the raw transaction + UniValue rawtxnValue = find_value(obj, "rawtxn"); + if (rawtxnValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); + } + std::string rawtxn = rawtxnValue.get_str(); + + UniValue params = UniValue(UniValue::VARR); + params.push_back(rawtxn); + UniValue signResultValue = signrawtransaction(params, false); + UniValue signResultObject = signResultValue.get_obj(); + UniValue completeValue = find_value(signResultObject, "complete"); + bool complete = completeValue.get_bool(); + if (!complete) { + // TODO: #1366 Maybe get "errors" and print array vErrors into a string + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); + } + + UniValue hexValue = find_value(signResultObject, "hex"); + if (hexValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); + } + std::string signedtxn = hexValue.get_str(); + + // Send the signed transaction + if (!testmode) { + params.clear(); + params.setArray(); + params.push_back(signedtxn); + UniValue sendResultValue = sendrawtransaction(params, false); + if (sendResultValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); + } + + std::string txid = sendResultValue.get_str(); + + UniValue o(UniValue::VOBJ); + o.push_back(Pair("txid", txid)); + set_result(o); + } else { + // Test mode does not send the transaction to the network. + + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + + UniValue o(UniValue::VOBJ); + o.push_back(Pair("test", 1)); + o.push_back(Pair("txid", tx.GetHash().ToString())); + o.push_back(Pair("hex", signedtxn)); + set_result(o); + } + + // Keep the signed transaction so we can hash to the same txid + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); + CTransaction tx; + stream >> tx; + tx_ = tx; +} + + +UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInfo & info) { + uint32_t consensusBranchId; + uint256 anchor; + { + LOCK(cs_main); + consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + anchor = pcoinsTip->GetBestAnchor(); + } + + + if (anchor.IsNull()) { + throw std::runtime_error("anchor is null"); + } + + // Make sure there are two inputs and two outputs + while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { + info.vjsin.push_back(JSInput()); + } + + while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { + info.vjsout.push_back(JSOutput()); + } + + if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { + throw runtime_error("unsupported joinsplit input/output counts"); + } + + CMutableTransaction mtx(tx_); + + LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", + getId(), + tx_.vjoinsplit.size(), + FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), + FormatMoney(info.vjsin[0].note.value), FormatMoney(info.vjsin[1].note.value), + FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) + ); + + // Generate the proof, this can take over a minute. + boost::array inputs + {info.vjsin[0], info.vjsin[1]}; + boost::array outputs + {info.vjsout[0], info.vjsout[1]}; + boost::array inputMap; + boost::array outputMap; + + uint256 esk; // payment disclosure - secret + + JSDescription jsdesc = JSDescription::Randomized( + *pzcashParams, + joinSplitPubKey_, + anchor, + inputs, + outputs, + inputMap, + outputMap, + info.vpub_old, + info.vpub_new, + !this->testmode, + &esk); // parameter expects pointer to esk, so pass in address + { + auto verifier = libzcash::ProofVerifier::Strict(); + if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { + throw std::runtime_error("error verifying joinsplit"); + } + } + + mtx.vjoinsplit.push_back(jsdesc); + + // Empty output script. + CScript scriptCode; + CTransaction signTx(mtx); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); + + // Add the signature + if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, + dataToBeSigned.begin(), 32, + joinSplitPrivKey_ + ) == 0)) + { + throw std::runtime_error("crypto_sign_detached failed"); + } + + // Sanity check + if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], + dataToBeSigned.begin(), 32, + mtx.joinSplitPubKey.begin() + ) == 0)) + { + throw std::runtime_error("crypto_sign_verify_detached failed"); + } + + CTransaction rawTx(mtx); + tx_ = rawTx; + + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << rawTx; + + std::string encryptedNote1; + std::string encryptedNote2; + { + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << ((unsigned char) 0x00); + ss2 << jsdesc.ephemeralKey; + ss2 << jsdesc.ciphertexts[0]; + ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); + + encryptedNote1 = HexStr(ss2.begin(), ss2.end()); + } + { + CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); + ss2 << ((unsigned char) 0x01); + ss2 << jsdesc.ephemeralKey; + ss2 << jsdesc.ciphertexts[1]; + ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); + + encryptedNote2 = HexStr(ss2.begin(), ss2.end()); + } + + UniValue arrInputMap(UniValue::VARR); + UniValue arrOutputMap(UniValue::VARR); + for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { + arrInputMap.push_back(inputMap[i]); + } + for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { + arrOutputMap.push_back(outputMap[i]); + } + + // !!! Payment disclosure START + unsigned char buffer[32] = {0}; + memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer + std::vector vch(&buffer[0], &buffer[0] + 32); + uint256 joinSplitPrivKey = uint256(vch); + size_t js_index = tx_.vjoinsplit.size() - 1; + uint256 placeholder; + for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { + uint8_t mapped_index = outputMap[i]; + // placeholder for txid will be filled in later when tx has been finalized and signed. + PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index}; + JSOutput output = outputs[mapped_index]; + libzcash::PaymentAddress zaddr = output.addr; // randomized output + PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; + paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); + + CZCPaymentAddress address(zaddr); + LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), address.ToString()); + } + // !!! Payment disclosure END + + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("encryptednote1", encryptedNote1)); + obj.push_back(Pair("encryptednote2", encryptedNote2)); + obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); + obj.push_back(Pair("inputmap", arrInputMap)); + obj.push_back(Pair("outputmap", arrOutputMap)); + return obj; +} + +/** + * Override getStatus() to append the operation's context object to the default status object. + */ +UniValue AsyncRPCOperation_shieldcoinbase::getStatus() const { + UniValue v = AsyncRPCOperation::getStatus(); + if (contextinfo_.isNull()) { + return v; + } + + UniValue obj = v.get_obj(); + obj.push_back(Pair("method", "z_shieldcoinbase")); + obj.push_back(Pair("params", contextinfo_ )); + return obj; +} + +/** + * Lock input utxos + */ + void AsyncRPCOperation_shieldcoinbase::lock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : inputs_) { + COutPoint outpt(utxo.txid, utxo.vout); + pwalletMain->LockCoin(outpt); + } +} + +/** + * Unlock input utxos + */ +void AsyncRPCOperation_shieldcoinbase::unlock_utxos() { + LOCK2(cs_main, pwalletMain->cs_wallet); + for (auto utxo : inputs_) { + COutPoint outpt(utxo.txid, utxo.vout); + pwalletMain->UnlockCoin(outpt); + } +} diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h new file mode 100644 index 000000000..c7faf28e8 --- /dev/null +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -0,0 +1,129 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef ASYNCRPCOPERATION_SHIELDCOINBASE_H +#define ASYNCRPCOPERATION_SHIELDCOINBASE_H + +#include "asyncrpcoperation.h" +#include "amount.h" +#include "base58.h" +#include "primitives/transaction.h" +#include "zcash/JoinSplit.hpp" +#include "zcash/Address.hpp" +#include "wallet.h" + +#include +#include + +#include + +#include "paymentdisclosure.h" + +// Default transaction fee if caller does not specify one. +#define SHIELD_COINBASE_DEFAULT_MINERS_FEE 10000 + +using namespace libzcash; + +struct ShieldCoinbaseUTXO { + uint256 txid; + int vout; + CAmount amount; +}; + +// Package of info which is passed to perform_joinsplit methods. +struct ShieldCoinbaseJSInfo +{ + std::vector vjsin; + std::vector vjsout; + CAmount vpub_old = 0; + CAmount vpub_new = 0; +}; + +class AsyncRPCOperation_shieldcoinbase : public AsyncRPCOperation { +public: + AsyncRPCOperation_shieldcoinbase(CMutableTransaction contextualTx, std::vector inputs, std::string toAddress, CAmount fee = SHIELD_COINBASE_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue); + virtual ~AsyncRPCOperation_shieldcoinbase(); + + // We don't want to be copied or moved around + AsyncRPCOperation_shieldcoinbase(AsyncRPCOperation_shieldcoinbase const&) = delete; // Copy construct + AsyncRPCOperation_shieldcoinbase(AsyncRPCOperation_shieldcoinbase&&) = delete; // Move construct + AsyncRPCOperation_shieldcoinbase& operator=(AsyncRPCOperation_shieldcoinbase const&) = delete; // Copy assign + AsyncRPCOperation_shieldcoinbase& operator=(AsyncRPCOperation_shieldcoinbase &&) = delete; // Move assign + + virtual void main(); + + virtual UniValue getStatus() const; + + bool testmode = false; // Set to true to disable sending txs and generating proofs + + bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + +private: + friend class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase; // class for unit testing + + UniValue contextinfo_; // optional data to include in return value from getStatus() + + CAmount fee_; + PaymentAddress tozaddr_; + + uint256 joinSplitPubKey_; + unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; + + std::vector inputs_; + + CTransaction tx_; + + bool main_impl(); + + // JoinSplit without any input notes to spend + UniValue perform_joinsplit(ShieldCoinbaseJSInfo &); + + void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error + + void lock_utxos(); + + void unlock_utxos(); + + // payment disclosure! + std::vector paymentDisclosureData_; +}; + + +// To test private methods, a friend class can act as a proxy +class TEST_FRIEND_AsyncRPCOperation_shieldcoinbase { +public: + std::shared_ptr delegate; + + TEST_FRIEND_AsyncRPCOperation_shieldcoinbase(std::shared_ptr ptr) : delegate(ptr) {} + + CTransaction getTx() { + return delegate->tx_; + } + + void setTx(CTransaction tx) { + delegate->tx_ = tx; + } + + // Delegated methods + + bool main_impl() { + return delegate->main_impl(); + } + + UniValue perform_joinsplit(ShieldCoinbaseJSInfo &info) { + return delegate->perform_joinsplit(info); + } + + void sign_send_raw_transaction(UniValue obj) { + delegate->sign_send_raw_transaction(obj); + } + + void set_state(OperationStatus state) { + delegate->state_.store(state); + } +}; + + +#endif /* ASYNCRPCOPERATION_SHIELDCOINBASE_H */ + diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp index a5ef786d8..69a2649b1 100644 --- a/src/wallet/crypter.cpp +++ b/src/wallet/crypter.cpp @@ -153,7 +153,7 @@ static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey, bool CCryptoKeyStore::SetCrypted() { - LOCK(cs_KeyStore); + LOCK2(cs_KeyStore, cs_SpendingKeyStore); if (fUseCrypto) return true; if (!(mapKeys.empty() && mapSpendingKeys.empty())) @@ -179,7 +179,7 @@ bool CCryptoKeyStore::Lock() bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) { { - LOCK(cs_KeyStore); + LOCK2(cs_KeyStore, cs_SpendingKeyStore); if (!SetCrypted()) return false; @@ -316,14 +316,14 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) if (!EncryptSecret(vMasterKey, vchSecret, address.GetHash(), vchCryptedSecret)) return false; - if (!AddCryptedSpendingKey(address, sk.viewing_key(), vchCryptedSecret)) + if (!AddCryptedSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) return false; } return true; } bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &address, - const libzcash::ViewingKey &vk, + const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { { @@ -332,7 +332,7 @@ bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &addr return false; mapCryptedSpendingKeys[address] = vchCryptedSecret; - mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk))); + mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(rk))); } return true; } @@ -384,7 +384,7 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) std::vector vchCryptedSecret; if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret)) return false; - if (!AddCryptedSpendingKey(address, sk.viewing_key(), vchCryptedSecret)) + if (!AddCryptedSpendingKey(address, sk.receiving_key(), vchCryptedSecret)) return false; } mapSpendingKeys.clear(); diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h index b310b77b0..bcee188cf 100644 --- a/src/wallet/crypter.h +++ b/src/wallet/crypter.h @@ -201,13 +201,13 @@ public: } } virtual bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, - const libzcash::ViewingKey &vk, + const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); bool AddSpendingKey(const libzcash::SpendingKey &sk); bool HaveSpendingKey(const libzcash::PaymentAddress &address) const { { - LOCK(cs_KeyStore); + LOCK(cs_SpendingKeyStore); if (!IsCrypted()) return CBasicKeyStore::HaveSpendingKey(address); return mapCryptedSpendingKeys.count(address) > 0; diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 9bcc5f533..4aeaf00df 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -281,7 +281,7 @@ TEST(wallet_tests, find_unspent_notes) { wallet.GetFilteredNotes(entries, "", 2, false); EXPECT_EQ(1, entries.size()); entries.clear(); - // If we also ignore spent notes at thie depth, we won't find any notes. + // If we also ignore spent notes at this depth, we won't find any notes. wallet.GetFilteredNotes(entries, "", 2, true); EXPECT_EQ(0, entries.size()); entries.clear(); @@ -328,7 +328,7 @@ TEST(wallet_tests, GetNoteNullifier) { auto sk = libzcash::SpendingKey::random(); auto address = sk.address(); - auto dec = ZCNoteDecryption(sk.viewing_key()); + auto dec = ZCNoteDecryption(sk.receiving_key()); auto wtx = GetValidReceive(sk, 10, true); auto note = GetNote(sk, wtx, 0, 1); diff --git a/src/wallet/gtest/test_wallet_zkeys.cpp b/src/wallet/gtest/test_wallet_zkeys.cpp index c7912ae7a..b40479e87 100644 --- a/src/wallet/gtest/test_wallet_zkeys.cpp +++ b/src/wallet/gtest/test_wallet_zkeys.cpp @@ -66,6 +66,53 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) { ASSERT_EQ(m.nCreateTime, now); } +/** + * This test covers methods on CWallet + * AddViewingKey() + * RemoveViewingKey() + * LoadViewingKey() + */ +TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) { + SelectParams(CBaseChainParams::MAIN); + + CWallet wallet; + + // wallet should be empty + std::set addrs; + wallet.GetPaymentAddresses(addrs); + ASSERT_EQ(0, addrs.size()); + + // manually add new viewing key to wallet + auto sk = libzcash::SpendingKey::random(); + auto vk = sk.viewing_key(); + ASSERT_TRUE(wallet.AddViewingKey(vk)); + + // verify wallet did add it + auto addr = sk.address(); + ASSERT_TRUE(wallet.HaveViewingKey(addr)); + // and that we don't have the corresponding spending key + ASSERT_FALSE(wallet.HaveSpendingKey(addr)); + + // verify viewing key stored correctly + libzcash::ViewingKey vkOut; + wallet.GetViewingKey(addr, vkOut); + ASSERT_EQ(vk, vkOut); + + // Load a second viewing key into the wallet + auto sk2 = libzcash::SpendingKey::random(); + ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key())); + + // verify wallet did add it + auto addr2 = sk2.address(); + ASSERT_TRUE(wallet.HaveViewingKey(addr2)); + ASSERT_FALSE(wallet.HaveSpendingKey(addr2)); + + // Remove the first viewing key + ASSERT_TRUE(wallet.RemoveViewingKey(vk)); + ASSERT_FALSE(wallet.HaveViewingKey(addr)); + ASSERT_TRUE(wallet.HaveViewingKey(addr2)); +} + /** * This test covers methods on CWalletDB * WriteZKey() @@ -138,6 +185,50 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) { ASSERT_EQ(m.nCreateTime, now); } +/** + * This test covers methods on CWalletDB + * WriteViewingKey() + */ +TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) { + SelectParams(CBaseChainParams::TESTNET); + + // Get temporary and unique path for file. + // Note: / operator to append paths + boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + boost::filesystem::create_directories(pathTemp); + mapArgs["-datadir"] = pathTemp.string(); + + bool fFirstRun; + CWallet wallet("wallet-vkey.dat"); + ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); + + // No default CPubKey set + ASSERT_TRUE(fFirstRun); + + // create random viewing key and add it to database directly, bypassing wallet + auto sk = libzcash::SpendingKey::random(); + auto vk = sk.viewing_key(); + auto addr = sk.address(); + int64_t now = GetTime(); + CKeyMetadata meta(now); + CWalletDB db("wallet-vkey.dat"); + db.WriteViewingKey(vk); + + // wallet should not be aware of viewing key + ASSERT_FALSE(wallet.HaveViewingKey(addr)); + + // load the wallet again + ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun)); + + // wallet can now see the viewing key + ASSERT_TRUE(wallet.HaveViewingKey(addr)); + + // check key is the same + libzcash::ViewingKey vkOut; + wallet.GetViewingKey(addr, vkOut); + ASSERT_EQ(vk, vkOut); +} + /** @@ -214,5 +305,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) { wallet2.GetSpendingKey(paymentAddress2.Get(), keyOut); ASSERT_EQ(paymentAddress2.Get(), keyOut.address()); + + ECC_Stop(); } diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp new file mode 100644 index 000000000..539cf4b2a --- /dev/null +++ b/src/wallet/rpcdisclosure.cpp @@ -0,0 +1,305 @@ +// Copyright (c) 2017 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "base58.h" +#include "rpcserver.h" +#include "init.h" +#include "main.h" +#include "script/script.h" +#include "script/standard.h" +#include "sync.h" +#include "util.h" +#include "utiltime.h" +#include "wallet.h" + +#include +#include + +#include +#include + +#include + +#include "paymentdisclosure.h" +#include "paymentdisclosuredb.h" + +#include "zcash/Note.hpp" +#include "zcash/NoteEncryption.hpp" + +using namespace std; +using namespace libzcash; + +// Function declaration for function implemented in wallet/rpcwallet.cpp +bool EnsureWalletIsAvailable(bool avoidException); + +/** + * RPC call to generate a payment disclosure + */ +UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); + string strPaymentDisclosureDisabledMsg = ""; + if (!fEnablePaymentDisclosure) { + strPaymentDisclosureDisabledMsg = "\nWARNING: Payment disclosure is currently DISABLED. This call always fails.\n"; + } + + if (fHelp || params.size() < 3 || params.size() > 4 ) + throw runtime_error( + "z_getpaymentdisclosure \"txid\" \"js_index\" \"output_index\" (\"message\") \n" + "\nGenerate a payment disclosure for a given joinsplit output.\n" + "\nEXPERIMENTAL FEATURE\n" + + strPaymentDisclosureDisabledMsg + + "\nArguments:\n" + "1. \"txid\" (string, required) \n" + "2. \"js_index\" (string, required) \n" + "3. \"output_index\" (string, required) \n" + "4. \"message\" (string, optional) \n" + "\nResult:\n" + "\"paymentdisclosure\" (string) Hex data string, with \"zpd:\" prefix.\n" + "\nExamples:\n" + + HelpExampleCli("z_getpaymentdisclosure", "96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2 0 0 \"refund\"") + + HelpExampleRpc("z_getpaymentdisclosure", "\"96f12882450429324d5f3b48630e3168220e49ab7b0f066e5c2935a6b88bb0f2\", 0, 0, \"refund\"") + ); + + if (!fEnablePaymentDisclosure) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled."); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + // Check wallet knows about txid + string txid = params[0].get_str(); + uint256 hash; + hash.SetHex(txid); + + CTransaction tx; + uint256 hashBlock; + + // Check txid has been seen + if (!GetTransaction(hash, tx, hashBlock, true)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + } + + // Check tx has been confirmed + if (hashBlock.IsNull()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet"); + } + + // Check is mine + if (!pwalletMain->mapWallet.count(hash)) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction does not belong to the wallet"); + } + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + // Check if shielded tx + if (wtx.vjoinsplit.empty()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); + } + + // Check js_index + int js_index = params[1].get_int(); + if (js_index < 0 || js_index >= wtx.vjoinsplit.size()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid js_index"); + } + + // Check output_index + int output_index = params[2].get_int(); + if (output_index < 0 || output_index >= ZC_NUM_JS_OUTPUTS) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid output_index"); + } + + // Get message if it exists + string msg; + if (params.size() == 4) { + msg = params[3].get_str(); + } + + // Create PaymentDisclosureKey + PaymentDisclosureKey key = {hash, (size_t)js_index, (uint8_t)output_index }; + + // TODO: In future, perhaps init the DB in init.cpp + shared_ptr db = PaymentDisclosureDB::sharedInstance(); + PaymentDisclosureInfo info; + if (!db->Get(key, info)) { + throw JSONRPCError(RPC_DATABASE_ERROR, "Could not find payment disclosure info for the given joinsplit output"); + } + + PaymentDisclosure pd( wtx.joinSplitPubKey, key, info, msg ); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << pd; + string strHex = HexStr(ss.begin(), ss.end()); + return PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX + strHex; +} + + + +/** + * RPC call to validate a payment disclosure data blob. + */ +UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); + string strPaymentDisclosureDisabledMsg = ""; + if (!fEnablePaymentDisclosure) { + strPaymentDisclosureDisabledMsg = "\nWARNING: Payment disclosure is curretly DISABLED. This call always fails.\n"; + } + + if (fHelp || params.size() != 1) + throw runtime_error( + "z_validatepaymentdisclosure \"paymentdisclosure\"\n" + "\nValidates a payment disclosure.\n" + "\nEXPERIMENTAL FEATURE\n" + + strPaymentDisclosureDisabledMsg + + "\nArguments:\n" + "1. \"paymentdisclosure\" (string, required) Hex data string, with \"zpd:\" prefix.\n" + "\nExamples:\n" + + HelpExampleCli("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"") + + HelpExampleRpc("z_validatepaymentdisclosure", "\"zpd:706462ff004c561a0447ba2ec51184e6c204...\"") + ); + + if (!fEnablePaymentDisclosure) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error: payment disclosure is disabled."); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + // Verify the payment disclosure input begins with "zpd:" prefix. + string strInput = params[0].get_str(); + size_t pos = strInput.find(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX); + if (pos != 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure prefix not found."); + } + string hexInput = strInput.substr(strlen(PAYMENT_DISCLOSURE_BLOB_STRING_PREFIX)); + if (!IsHex(hexInput)) + { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected payment disclosure data in hexadecimal format."); + } + + // Unserialize the payment disclosure data into an object + PaymentDisclosure pd; + CDataStream ss(ParseHex(hexInput), SER_NETWORK, PROTOCOL_VERSION); + try { + ss >> pd; + // too much data is ignored, but if not enough data, exception of type ios_base::failure is thrown, + // CBaseDataStream::read(): end of data: iostream error + } catch (const std::exception &e) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure data is malformed."); + } + + if (pd.payload.marker != PAYMENT_DISCLOSURE_PAYLOAD_MAGIC_BYTES) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, payment disclosure marker not found."); + } + + if (pd.payload.version != PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Payment disclosure version is unsupported."); + } + + uint256 hash = pd.payload.txid; + CTransaction tx; + uint256 hashBlock; + // Check if we have seen the transaction + if (!GetTransaction(hash, tx, hashBlock, true)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); + } + + // Check if the transaction has been confirmed + if (hashBlock.IsNull()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction has not been confirmed yet"); + } + + // Check if shielded tx + if (tx.vjoinsplit.empty()) { + throw JSONRPCError(RPC_MISC_ERROR, "Transaction is not a shielded transaction"); + } + + UniValue errs(UniValue::VARR); + UniValue o(UniValue::VOBJ); + o.push_back(Pair("txid", pd.payload.txid.ToString())); + + // Check js_index + if (pd.payload.js >= tx.vjoinsplit.size()) { + errs.push_back("Payment disclosure refers to an invalid joinsplit index"); + } + o.push_back(Pair("jsIndex", pd.payload.js)); + + if (pd.payload.n < 0 || pd.payload.n >= ZC_NUM_JS_OUTPUTS) { + errs.push_back("Payment disclosure refers to an invalid output index"); + } + o.push_back(Pair("outputIndex", pd.payload.n)); + o.push_back(Pair("version", pd.payload.version)); + o.push_back(Pair("onetimePrivKey", pd.payload.esk.ToString())); + o.push_back(Pair("message", pd.payload.message)); + o.push_back(Pair("joinSplitPubKey", tx.joinSplitPubKey.ToString())); + + // Verify the payment disclosure was signed using the same key as the transaction i.e. the joinSplitPrivKey. + uint256 dataToBeSigned = SerializeHash(pd.payload, SER_GETHASH, 0); + bool sigVerified = (crypto_sign_verify_detached(pd.payloadSig.data(), + dataToBeSigned.begin(), 32, + tx.joinSplitPubKey.begin()) == 0); + o.push_back(Pair("signatureVerified", sigVerified)); + if (!sigVerified) { + errs.push_back("Payment disclosure signature does not match transaction signature"); + } + + // Check the payment address is valid + PaymentAddress zaddr = pd.payload.zaddr; + CZCPaymentAddress address; + if (!address.Set(zaddr)) { + errs.push_back("Payment disclosure refers to an invalid payment address"); + } else { + o.push_back(Pair("paymentAddress", address.ToString())); + + try { + // Decrypt the note to get value and memo field + JSDescription jsdesc = tx.vjoinsplit[pd.payload.js]; + uint256 h_sig = jsdesc.h_sig(*pzcashParams, tx.joinSplitPubKey); + + ZCPaymentDisclosureNoteDecryption decrypter; + + ZCNoteEncryption::Ciphertext ciphertext = jsdesc.ciphertexts[pd.payload.n]; + + uint256 pk_enc = zaddr.pk_enc; + auto plaintext = decrypter.decryptWithEsk(ciphertext, pk_enc, pd.payload.esk, h_sig, pd.payload.n); + + CDataStream ssPlain(SER_NETWORK, PROTOCOL_VERSION); + ssPlain << plaintext; + NotePlaintext npt; + ssPlain >> npt; + + string memoHexString = HexStr(npt.memo.data(), npt.memo.data() + npt.memo.size()); + o.push_back(Pair("memo", memoHexString)); + o.push_back(Pair("value", ValueFromAmount(npt.value))); + + // Check the blockchain commitment matches decrypted note commitment + uint256 cm_blockchain = jsdesc.commitments[pd.payload.n]; + Note note = npt.note(zaddr); + uint256 cm_decrypted = note.cm(); + bool cm_match = (cm_decrypted == cm_blockchain); + o.push_back(Pair("commitmentMatch", cm_match)); + if (!cm_match) { + errs.push_back("Commitment derived from payment disclosure does not match blockchain commitment"); + } + } catch (const std::exception &e) { + errs.push_back(string("Error while decrypting payment disclosure note: ") + string(e.what()) ); + } + } + + bool isValid = errs.empty(); + o.push_back(Pair("valid", isValid)); + if (!isValid) { + o.push_back(Pair("errors", errs)); + } + + return o; +} diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 83f0e5cac..bb42ffa1d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -128,8 +128,9 @@ UniValue importprivkey(const UniValue& params, bool fHelp) pwalletMain->SetAddressBook(vchAddress, strLabel, "receive"); // Don't throw error in case a key is already there - if (pwalletMain->HaveKey(vchAddress)) - return NullUniValue; + if (pwalletMain->HaveKey(vchAddress)) { + return CBitcoinAddress(vchAddress).ToString(); + } pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; @@ -144,7 +145,7 @@ UniValue importprivkey(const UniValue& params, bool fHelp) } } - return NullUniValue; + return CBitcoinAddress(vchAddress).ToString(); } UniValue importaddress(const UniValue& params, bool fHelp) @@ -233,11 +234,11 @@ UniValue z_importwallet(const UniValue& params, bool fHelp) "1. \"filename\" (string, required) The wallet file\n" "\nExamples:\n" "\nDump the wallet\n" - + HelpExampleCli("z_exportwallet", "\"test\"") + + + HelpExampleCli("z_exportwallet", "\"nameofbackup\"") + "\nImport the wallet\n" - + HelpExampleCli("z_importwallet", "\"test\"") + + + HelpExampleCli("z_importwallet", "\"path/to/exportdir/nameofbackup\"") + "\nImport using the json rpc call\n" - + HelpExampleRpc("z_importwallet", "\"test\"") + + HelpExampleRpc("z_importwallet", "\"path/to/exportdir/nameofbackup\"") ); return importwallet_impl(params, fHelp, true); @@ -256,11 +257,11 @@ UniValue importwallet(const UniValue& params, bool fHelp) "1. \"filename\" (string, required) The wallet file\n" "\nExamples:\n" "\nDump the wallet\n" - + HelpExampleCli("dumpwallet", "\"test\"") + + + HelpExampleCli("dumpwallet", "\"nameofbackup\"") + "\nImport the wallet\n" - + HelpExampleCli("importwallet", "\"test\"") + + + HelpExampleCli("importwallet", "\"path/to/exportdir/nameofbackup\"") + "\nImport using the json rpc call\n" - + HelpExampleRpc("importwallet", "\"test\"") + + HelpExampleRpc("importwallet", "\"path/to/exportdir/nameofbackup\"") ); return importwallet_impl(params, fHelp, false); @@ -427,7 +428,7 @@ UniValue z_exportwallet(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "z_exportwallet \"filename\"\n" - "\nExports all wallet keys, for taddr and zaddr, in a human-readable format.\n" + "\nExports all wallet keys, for taddr and zaddr, in a human-readable format. Overwriting an existing file is not permitted.\n" "\nArguments:\n" "1. \"filename\" (string, required) The filename, saved in folder set by zcashd -exportdir option\n" "\nResult:\n" @@ -448,7 +449,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) if (fHelp || params.size() != 1) throw runtime_error( "dumpwallet \"filename\"\n" - "\nDumps taddr wallet keys in a human-readable format.\n" + "\nDumps taddr wallet keys in a human-readable format. Overwriting an existing file is not permitted.\n" "\nArguments:\n" "1. \"filename\" (string, required) The filename, saved in folder set by zcashd -exportdir option\n" "\nResult:\n" @@ -483,6 +484,10 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys) } boost::filesystem::path exportfilepath = exportdir / clean; + if (boost::filesystem::exists(exportfilepath)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot overwrite existing file " + exportfilepath.string()); + } + ofstream file; file.open(exportfilepath.string().c_str()); if (!file.is_open()) @@ -643,6 +648,94 @@ UniValue z_importkey(const UniValue& params, bool fHelp) return NullUniValue; } +UniValue z_importviewingkey(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "z_importviewingkey \"vkey\" ( rescan startHeight )\n" + "\nAdds a viewing key (as returned by z_exportviewingkey) to your wallet.\n" + "\nArguments:\n" + "1. \"vkey\" (string, required) The viewing key (see z_exportviewingkey)\n" + "2. rescan (string, optional, default=\"whenkeyisnew\") Rescan the wallet for transactions - can be \"yes\", \"no\" or \"whenkeyisnew\"\n" + "3. startHeight (numeric, optional, default=0) Block height to start rescan from\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nImport a viewing key\n" + + HelpExampleCli("z_importviewingkey", "\"vkey\"") + + "\nImport the viewing key without rescan\n" + + HelpExampleCli("z_importviewingkey", "\"vkey\", no") + + "\nImport the viewing key with partial rescan\n" + + HelpExampleCli("z_importviewingkey", "\"vkey\" whenkeyisnew 30000") + + "\nRe-import the viewing key with longer partial rescan\n" + + HelpExampleCli("z_importviewingkey", "\"vkey\" yes 20000") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("z_importviewingkey", "\"vkey\", \"no\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + // Whether to perform rescan after import + bool fRescan = true; + bool fIgnoreExistingKey = true; + if (params.size() > 1) { + auto rescan = params[1].get_str(); + if (rescan.compare("whenkeyisnew") != 0) { + fIgnoreExistingKey = false; + if (rescan.compare("no") == 0) { + fRescan = false; + } else if (rescan.compare("yes") != 0) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + "rescan must be \"yes\", \"no\" or \"whenkeyisnew\""); + } + } + } + + // Height to rescan from + int nRescanHeight = 0; + if (params.size() > 2) { + nRescanHeight = params[2].get_int(); + } + if (nRescanHeight < 0 || nRescanHeight > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + } + + string strVKey = params[0].get_str(); + CZCViewingKey viewingkey(strVKey); + auto vkey = viewingkey.Get(); + auto addr = vkey.address(); + + { + if (pwalletMain->HaveSpendingKey(addr)) { + throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the private key for this viewing key"); + } + + // Don't throw error in case a viewing key is already there + if (pwalletMain->HaveViewingKey(addr)) { + if (fIgnoreExistingKey) { + return NullUniValue; + } + } else { + pwalletMain->MarkDirty(); + + if (!pwalletMain->AddViewingKey(vkey)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error adding viewing key to wallet"); + } + } + + // We want to scan for transactions and notes + if (fRescan) { + pwalletMain->ScanForWalletTransactions(chainActive[nRescanHeight], true); + } + } + + return NullUniValue; +} UniValue z_exportkey(const UniValue& params, bool fHelp) { @@ -681,3 +774,43 @@ UniValue z_exportkey(const UniValue& params, bool fHelp) return spendingkey.ToString(); } +UniValue z_exportviewingkey(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "z_exportviewingkey \"zaddr\"\n" + "\nReveals the viewing key corresponding to 'zaddr'.\n" + "Then the z_importviewingkey can be used with this output\n" + "\nArguments:\n" + "1. \"zaddr\" (string, required) The zaddr for the viewing key\n" + "\nResult:\n" + "\"vkey\" (string) The viewing key\n" + "\nExamples:\n" + + HelpExampleCli("z_exportviewingkey", "\"myaddress\"") + + HelpExampleRpc("z_exportviewingkey", "\"myaddress\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + EnsureWalletIsUnlocked(); + + string strAddress = params[0].get_str(); + + CZCPaymentAddress address(strAddress); + auto addr = address.Get(); + + libzcash::ViewingKey vk; + if (!pwalletMain->GetViewingKey(addr, vk)) { + libzcash::SpendingKey k; + if (!pwalletMain->GetSpendingKey(addr, k)) { + throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr"); + } + vk = k.viewing_key(); + } + + CZCViewingKey viewingkey(vk); + return viewingkey.ToString(); +} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3179e2e9e..27e94134d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5,6 +5,7 @@ #include "amount.h" #include "base58.h" +#include "consensus/upgrades.h" #include "core_io.h" #include "init.h" #include "main.h" @@ -23,7 +24,9 @@ #include "utiltime.h" #include "asyncrpcoperation.h" #include "asyncrpcqueue.h" +#include "wallet/asyncrpcoperation_mergetoaddress.h" #include "wallet/asyncrpcoperation_sendmany.h" +#include "wallet/asyncrpcoperation_shieldcoinbase.h" #include "sodium.h" @@ -72,7 +75,7 @@ void EnsureWalletIsUnlocked() throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue); +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); uint64_t komodo_interest(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) @@ -87,6 +90,7 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight)); } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); @@ -122,7 +126,7 @@ UniValue getnewaddress(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"account\" (string, optional) DEPRECATED. If provided, it MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"zcashaddress\" (string) The new zcash address\n" + "\"zcashaddress\" (string) The new Zcash address\n" "\nExamples:\n" + HelpExampleCli("getnewaddress", "") + HelpExampleRpc("getnewaddress", "") @@ -199,7 +203,7 @@ UniValue getaccountaddress(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"zcashaddress\" (string) The account zcash address\n" + "\"zcashaddress\" (string) The account Zcash address\n" "\nExamples:\n" + HelpExampleCli("getaccountaddress", "") + HelpExampleCli("getaccountaddress", "\"\"") @@ -264,11 +268,11 @@ UniValue setaccount(const UniValue& params, bool fHelp) "setaccount \"zcashaddress\" \"account\"\n" "\nDEPRECATED. Sets the account associated with the given address.\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The zcash address to be associated with an account.\n" + "1. \"zcashaddress\" (string, required) The Zcash address to be associated with an account.\n" "2. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nExamples:\n" - + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"tabby\"") - + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"tabby\"") + + HelpExampleCli("setaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"tabby\"") + + HelpExampleRpc("setaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", \"tabby\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -310,12 +314,12 @@ UniValue getaccount(const UniValue& params, bool fHelp) "getaccount \"zcashaddress\"\n" "\nDEPRECATED. Returns the account associated with the given address.\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The zcash address for account lookup.\n" + "1. \"zcashaddress\" (string, required) The Zcash address for account lookup.\n" "\nResult:\n" "\"accountname\" (string) the account address\n" "\nExamples:\n" - + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") - + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + HelpExampleCli("getaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"") + + HelpExampleRpc("getaccount", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -345,7 +349,7 @@ UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" "[ (json array of string)\n" - " \"zcashaddress\" (string) a zcash address associated with the given account\n" + " \"zcashaddress\" (string) a Zcash address associated with the given account\n" " ,...\n" "]\n" "\nExamples:\n" @@ -425,22 +429,22 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) "\nSend an amount to a given address. The amount is a real and is rounded to the nearest 0.00000001\n" + HelpRequiringPassphrase() + "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The zcash address to send to.\n" - "2. \"amount\" (numeric, required) The amount in btc to send. eg 0.1\n" + "1. \"zcashaddress\" (string, required) The Zcash address to send to.\n" + "2. \"amount\" (numeric, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n" "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" "4. \"comment-to\" (string, optional) A comment to store the name of the person or organization \n" " to which you're sending the transaction. This is not part of the \n" " transaction, just kept in your wallet.\n" "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n" - " The recipient will receive less zcash than you enter in the amount field.\n" + " The recipient will receive less Zcash than you enter in the amount field.\n" "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" - + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") - + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") - + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") - + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") + + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") + + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"") + + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true") + + HelpExampleRpc("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -709,7 +713,7 @@ UniValue listaddressgroupings(const UniValue& params, bool fHelp) " [\n" " [\n" " \"zcashaddress\", (string) The zcash address\n" - " amount, (numeric) The amount in btc\n" + " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"account\" (string, optional) The account (DEPRECATED)\n" " ]\n" " ,...\n" @@ -755,7 +759,7 @@ UniValue signmessage(const UniValue& params, bool fHelp) "\nSign a message with the private key of an address" + HelpRequiringPassphrase() + "\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The zcash address to use for the private key.\n" + "1. \"zcashaddress\" (string, required) The Zcash address to use for the private key.\n" "2. \"message\" (string, required) The message to create a signature of.\n" "\nResult:\n" "\"signature\" (string) The signature of the message encoded in base 64\n" @@ -763,11 +767,11 @@ UniValue signmessage(const UniValue& params, bool fHelp) "\nUnlock the wallet for 30 seconds\n" + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"my message\"") + + + HelpExampleCli("signmessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"my message\"") + "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + + HelpExampleCli("verifymessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" \"signature\" \"my message\"") + "\nAs json rpc\n" - + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", \"my message\"") + + HelpExampleRpc("signmessage", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", \"my message\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -808,21 +812,21 @@ UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "getreceivedbyaddress \"zcashaddress\" ( minconf )\n" - "\nReturns the total amount received by the given zcashaddress in transactions with at least minconf confirmations.\n" + "\nReturns the total amount received by the given Zcash address in transactions with at least minconf confirmations.\n" "\nArguments:\n" - "1. \"zcashaddress\" (string, required) The zcash address for transactions.\n" + "1. \"zcashaddress\" (string, required) The Zcash address for transactions.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received at this address.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" "\nExamples:\n" "\nThe amount from transactions with at least 1 confirmation\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\"") + + + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\"") + "\nThe amount including unconfirmed transactions, zero confirmations\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 0") + - "\nThe amount with at least 6 confirmation, very safe\n" - + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" 6") + + + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" 0") + + "\nThe amount with at least 6 confirmations, very safe\n" + + HelpExampleCli("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\" 6") + "\nAs a json rpc call\n" - + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\", 6") + + HelpExampleRpc("getreceivedbyaddress", "\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\", 6") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -871,7 +875,7 @@ UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) "1. \"account\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nAmount received by the default account with at least 1 confirmation\n" + HelpExampleCli("getreceivedbyaccount", "\"\"") + @@ -961,7 +965,7 @@ UniValue getbalance(const UniValue& params, bool fHelp) "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "3. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress')\n" "\nResult:\n" - "amount (numeric) The total amount in btc received for this account.\n" + "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n" "\nExamples:\n" "\nThe total amount in the wallet\n" + HelpExampleCli("getbalance", "") + @@ -1047,14 +1051,15 @@ UniValue movecmd(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. \"toaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" - "3. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" - "4. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" + "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n" + "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" + "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n" "\nResult:\n" "true|false (boolean) true if successful.\n" "\nExamples:\n" - "\nMove 0.01 btc from the default account to the account named tabby\n" + "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n" + HelpExampleCli("move", "\"\" \"tabby\" 0.01") + - "\nMove 0.01 btc timotei to akiko with a comment and funds have 6 confirmations\n" + "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n" + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") + "\nAs a json rpc call\n" + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"") @@ -1115,13 +1120,13 @@ UniValue sendfrom(const UniValue& params, bool fHelp) if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( "sendfrom \"fromaccount\" \"tozcashaddress\" amount ( minconf \"comment\" \"comment-to\" )\n" - "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a zcash address.\n" + "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a Zcash address.\n" "The amount is a real and is rounded to the nearest 0.00000001." + HelpRequiringPassphrase() + "\n" "\nArguments:\n" "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" - "2. \"tozcashaddress\" (string, required) The zcash address to send funds to.\n" - "3. amount (numeric, required) The amount in btc. (transaction fee is added on top).\n" + "2. \"tozcashaddress\" (string, required) The Zcash address to send funds to.\n" + "3. amount (numeric, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n" "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n" "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n" " This is not part of the transaction, just kept in your wallet.\n" @@ -1131,12 +1136,12 @@ UniValue sendfrom(const UniValue& params, bool fHelp) "\nResult:\n" "\"transactionid\" (string) The transaction id.\n" "\nExamples:\n" - "\nSend 0.01 btc from the default account to the address, must have at least 1 confirmation\n" - + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + + "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n" + + HelpExampleCli("sendfrom", "\"\" \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") + "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n" - + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") + + + HelpExampleCli("sendfrom", "\"tabby\" \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") + + HelpExampleRpc("sendfrom", "\"tabby\", \"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -1186,14 +1191,14 @@ UniValue sendmany(const UniValue& params, bool fHelp) "1. \"fromaccount\" (string, required) MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "2. \"amounts\" (string, required) A json object with addresses and amounts\n" " {\n" - " \"address\":amount (numeric) The zcash address is the key, the numeric amount in btc is the value\n" + " \"address\":amount (numeric) The Zcash address is the key, the numeric amount in " + CURRENCY_UNIT + " is the value\n" " ,...\n" " }\n" "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n" "4. \"comment\" (string, optional) A comment\n" "5. subtractfeefromamount (string, optional) A json array with addresses.\n" " The fee will be equally deducted from the amount of each selected address.\n" - " Those recipients will receive less zcashs than you enter in their corresponding amount field.\n" + " Those recipients will receive less Zcash than you enter in their corresponding amount field.\n" " If no addresses are specified here, the sender pays the fee.\n" " [\n" " \"address\" (string) Subtract fee from this address\n" @@ -1204,13 +1209,13 @@ UniValue sendmany(const UniValue& params, bool fHelp) " the number of addresses.\n" "\nExamples:\n" "\nSend two amounts to two different addresses:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") + "\nSend two amounts to two different addresses setting the confirmation and comment:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") + "\nSend two amounts to two different addresses, subtract fee from amount:\n" - + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + + + HelpExampleCli("sendmany", "\"\" \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\",\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") + "\nAs a json rpc call\n" - + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") + + HelpExampleRpc("sendmany", "\"\", \"{\\\"t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1\\\":0.01,\\\"t1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -1301,21 +1306,21 @@ UniValue addmultisigaddress(const UniValue& params, bool fHelp) "\nArguments:\n" "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n" - "2. \"keysobject\" (string, required) A json array of zcash addresses or hex-encoded public keys\n" + "2. \"keysobject\" (string, required) A json array of Zcash addresses or hex-encoded public keys\n" " [\n" - " \"address\" (string) zcash address or hex-encoded public key\n" + " \"address\" (string) Zcash address or hex-encoded public key\n" " ...,\n" " ]\n" "3. \"account\" (string, optional) DEPRECATED. If provided, MUST be set to the empty string \"\" to represent the default account. Passing any other string will result in an error.\n" "\nResult:\n" - "\"zcashaddress\" (string) A zcash address associated with the keys.\n" + "\"zcashaddress\" (string) A Zcash address associated with the keys.\n" "\nExamples:\n" "\nAdd a multisig address from 2 addresses\n" - + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + + HelpExampleCli("addmultisigaddress", "2 \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + "\nAs json rpc call\n" - + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") + + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"t16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"t171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") ; throw runtime_error(msg); } @@ -1488,7 +1493,7 @@ UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n" " \"address\" : \"receivingaddress\", (string) The receiving address\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n" - " \"amount\" : x.xxx, (numeric) The total amount in btc received by the address\n" + " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included\n" " }\n" " ,...\n" @@ -1664,17 +1669,17 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " {\n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n" " It will be \"\" for the default account.\n" - " \"address\":\"zcashaddress\", (string) The zcash address of the transaction. Not present for \n" + " \"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for \n" " move transactions (category = move).\n" " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n" " transaction between accounts, and not associated with an address,\n" " transaction id or block. 'send' and 'receive' transactions are \n" " associated with an address, transaction id and block details\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the\n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n" " 'move' category for moves outbound. It is positive for the 'receive' category,\n" " and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the \n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n" " 'receive' category of transactions.\n" @@ -1864,12 +1869,12 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) "{\n" " \"transactions\": [\n" " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n" - " \"address\":\"zcashaddress\", (string) The zcash address of the transaction. Not present for move transactions (category = move).\n" + " \"address\":\"zcashaddress\", (string) The Zcash address of the transaction. Not present for move transactions (category = move).\n" " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n" - " \"amount\": x.xxx, (numeric) The amount in btc. This is negative for the 'send' category, and for the 'move' category for moves \n" + " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n" " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n" " \"vout\" : n, (numeric) the vout value\n" - " \"fee\": x.xxx, (numeric) The amount of the fee in btc. This is negative and only available for the 'send' category of transactions.\n" + " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n" " \"blockindex\": n, (numeric) The block index containing the transaction. Available for 'send' and 'receive' category of transactions.\n" @@ -1952,7 +1957,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) "2. \"includeWatchonly\" (bool, optional, default=false) Whether to include watchonly addresses in balance calculation and details[]\n" "\nResult:\n" "{\n" - " \"amount\" : x.xxx, (numeric) The transaction amount in btc\n" + " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" " \"blockindex\" : xx, (numeric) The block index\n" @@ -1963,9 +1968,9 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"details\" : [\n" " {\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n" - " \"address\" : \"zcashaddress\", (string) The zcash address involved in the transaction\n" + " \"address\" : \"zcashaddress\", (string) The Zcash address involved in the transaction\n" " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n" - " \"amount\" : x.xxx (numeric) The amount in btc\n" + " \"amount\" : x.xxx (numeric) The amount in " + CURRENCY_UNIT + "\n" " \"vout\" : n, (numeric) the vout value\n" " }\n" " ,...\n" @@ -2123,7 +2128,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" - "This is needed prior to performing transactions related to private keys such as sending zcash\n" + "This is needed prior to performing transactions related to private keys such as sending Zcash\n" "\nArguments:\n" "1. \"passphrase\" (string, required) The wallet passphrase\n" "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n" @@ -2237,7 +2242,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) "\nSet the passphrase for 2 minutes to perform a transaction\n" + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") + "\nPerform a send (requires passphrase set)\n" - + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") + + + HelpExampleCli("sendtoaddress", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") + "\nClear the passphrase since we are done before 2 minutes is up\n" + HelpExampleCli("walletlock", "") + "\nAs json rpc call\n" @@ -2288,7 +2293,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) "\nExamples:\n" "\nEncrypt you wallet\n" + HelpExampleCli("encryptwallet", "\"my pass phrase\"") + - "\nNow set the passphrase to use the wallet, such as for signing or sending zcash\n" + "\nNow set the passphrase to use the wallet, such as for signing or sending Zcash\n" + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") + "\nNow we can so something like sign\n" + HelpExampleCli("signmessage", "\"zcashaddress\" \"test message\"") + @@ -2339,7 +2344,7 @@ UniValue lockunspent(const UniValue& params, bool fHelp) "lockunspent unlock [{\"txid\":\"txid\",\"vout\":n},...]\n" "\nUpdates list of temporarily unspendable outputs.\n" "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n" - "A locked transaction output will not be chosen by automatic coin selection, when spending zcash.\n" + "A locked transaction output will not be chosen by automatic coin selection, when spending Zcash.\n" "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n" "is always cleared (by virtue of process exit) when a node stops or fails.\n" "Also see the listunspent call\n" @@ -2472,7 +2477,7 @@ UniValue settxfee(const UniValue& params, bool fHelp) "settxfee amount\n" "\nSet the transaction fee per kB.\n" "\nArguments:\n" - "1. amount (numeric, required) The transaction fee in BTC/kB rounded to the nearest 0.00000001\n" + "1. amount (numeric, required) The transaction fee in " + CURRENCY_UNIT + "/kB rounded to the nearest 0.00000001\n" "\nResult\n" "true|false (boolean) Returns true if successful\n" "\nExamples:\n" @@ -2501,9 +2506,9 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total confirmed zcash balance of the wallet\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed zcash balance of the wallet\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet\n" + " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" + " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2574,9 +2579,9 @@ UniValue listunspent(const UniValue& params, bool fHelp) "\nArguments:\n" "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n" "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n" - "3. \"addresses\" (string) A json array of zcash addresses to filter\n" + "3. \"addresses\" (string) A json array of Zcash addresses to filter\n" " [\n" - " \"address\" (string) zcash address\n" + " \"address\" (string) Zcash address\n" " ,...\n" " ]\n" "\nResult\n" @@ -2584,10 +2589,11 @@ UniValue listunspent(const UniValue& params, bool fHelp) " {\n" " \"txid\" : \"txid\", (string) the transaction id \n" " \"vout\" : n, (numeric) the vout value\n" - " \"address\" : \"address\", (string) the zcash address\n" + " \"generated\" : true|false (boolean) true if txout is a coinbase transaction output\n" + " \"address\" : \"address\", (string) the Zcash address\n" " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n" " \"scriptPubKey\" : \"key\", (string) the script key\n" - " \"amount\" : x.xxx, (numeric) the transaction amount in btc\n" + " \"amount\" : x.xxx, (numeric) the transaction amount in " + CURRENCY_UNIT + "\n" " \"confirmations\" : n (numeric) The number of confirmations\n" " }\n" " ,...\n" @@ -2595,8 +2601,8 @@ UniValue listunspent(const UniValue& params, bool fHelp) "\nExamples\n" + HelpExampleCli("listunspent", "") - + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") - + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleCli("listunspent", "6 9999999 \"[\\\"t1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"t1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") + + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"t1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"t1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); @@ -2646,6 +2652,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); entry.push_back(Pair("vout", out.i)); + entry.push_back(Pair("generated", out.tx->IsCoinBase())); CTxDestination address; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); @@ -2668,9 +2675,9 @@ UniValue listunspent(const UniValue& params, bool fHelp) BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *tipindex,*pindex = it->second; uint64_t interest; uint32_t locktime; int32_t txheight; - komodo_accrued_interest(&txheight,&locktime,out.tx->GetHash(),out.i,0,nValue); if ( pindex != 0 && (tipindex= chainActive.Tip()) != 0 ) { + komodo_accrued_interest(&txheight,&locktime,out.tx->GetHash(),out.i,0,nValue,(int32_t)tipindex->nHeight); interest = komodo_interest(txheight,nValue,out.tx->nLockTime,tipindex->nTime); entry.push_back(Pair("interest",ValueFromAmount(interest))); } @@ -2826,12 +2833,6 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp) std::vector sample_times; - if (benchmarktype == "createjoinsplit") { - /* Load the proving now key so that it doesn't happen as part of the - * first joinsplit. */ - pzcashParams->loadProvingKey(); - } - JSDescription samplejoinsplit; if (benchmarktype == "verifyjoinsplit") { @@ -2869,13 +2870,36 @@ UniValue zc_benchmark(const UniValue& params, bool fHelp) } else if (benchmarktype == "verifyequihash") { sample_times.push_back(benchmark_verify_equihash()); } else if (benchmarktype == "validatelargetx") { - sample_times.push_back(benchmark_large_tx()); + // Number of inputs in the spending transaction that we will simulate + int nInputs = 555; + if (params.size() >= 3) { + nInputs = params[2].get_int(); + } + sample_times.push_back(benchmark_large_tx(nInputs)); } else if (benchmarktype == "trydecryptnotes") { int nAddrs = params[2].get_int(); sample_times.push_back(benchmark_try_decrypt_notes(nAddrs)); } else if (benchmarktype == "incnotewitnesses") { int nTxs = params[2].get_int(); sample_times.push_back(benchmark_increment_note_witnesses(nTxs)); + } else if (benchmarktype == "connectblockslow") { + if (Params().NetworkIDString() != "regtest") { + throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); + } + sample_times.push_back(benchmark_connectblock_slow()); + } else if (benchmarktype == "sendtoaddress") { + if (Params().NetworkIDString() != "regtest") { + throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); + } + auto amount = AmountFromValue(params[2]); + sample_times.push_back(benchmark_sendtoaddress(amount)); + } else if (benchmarktype == "loadwallet") { + if (Params().NetworkIDString() != "regtest") { + throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); + } + sample_times.push_back(benchmark_loadwallet()); + } else if (benchmarktype == "listunspent") { + sample_times.push_back(benchmark_listunspent()); } else { throw JSONRPCError(RPC_TYPE_ERROR, "Invalid benchmarktype"); } @@ -2938,7 +2962,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) } } - ZCNoteDecryption decryptor(k.viewing_key()); + ZCNoteDecryption decryptor(k.receiving_key()); NotePlaintext npt = NotePlaintext::decrypt( decryptor, @@ -3111,7 +3135,8 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) // Empty output script. CScript scriptCode; CTransaction signTx(mtx); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); // Add the signature assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, @@ -3173,6 +3198,7 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp) "Output: {\n" " \"zcaddress\": zcaddr,\n" " \"zcsecretkey\": zcsecretkey,\n" + " \"zcviewingkey\": zcviewingkey,\n" "}\n" ); } @@ -3181,18 +3207,14 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp) auto addr = k.address(); auto viewing_key = k.viewing_key(); - CDataStream viewing(SER_NETWORK, PROTOCOL_VERSION); - - viewing << viewing_key; - CZCPaymentAddress pubaddr(addr); CZCSpendingKey spendingkey(k); - std::string viewing_hex = HexStr(viewing.begin(), viewing.end()); + CZCViewingKey viewingkey(viewing_key); UniValue result(UniValue::VOBJ); result.push_back(Pair("zcaddress", pubaddr.ToString())); result.push_back(Pair("zcsecretkey", spendingkey.ToString())); - result.push_back(Pair("zcviewingkey", viewing_hex)); + result.push_back(Pair("zcviewingkey", viewingkey.ToString())); return result; } @@ -3231,9 +3253,10 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp) if (fHelp || params.size() > 1) throw runtime_error( - "z_listaddresses\n" + "z_listaddresses ( includeWatchonly )\n" "\nReturns the list of zaddr belonging to the wallet.\n" "\nArguments:\n" + "1. includeWatchonly (bool, optional, default=false) Also include watchonly addresses (see 'z_importviewingkey')\n" "\nResult:\n" "[ (json array of string)\n" " \"zaddr\" (string) a zaddr belonging to the wallet\n" @@ -3246,16 +3269,23 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); + bool fIncludeWatchonly = false; + if (params.size() > 0) { + fIncludeWatchonly = params[0].get_bool(); + } + UniValue ret(UniValue::VARR); std::set addresses; pwalletMain->GetPaymentAddresses(addresses); for (auto addr : addresses ) { - ret.push_back(CZCPaymentAddress(addr).ToString()); + if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) { + ret.push_back(CZCPaymentAddress(addr).ToString()); + } } return ret; } -CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1) { +CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ignoreUnspendable=true) { set setAddress; vector vecOutputs; CAmount balance = 0; @@ -3277,6 +3307,10 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1) { continue; } + if (ignoreUnspendable && !out.fSpendable) { + continue; + } + if (setAddress.size()) { CTxDestination address; if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { @@ -3294,11 +3328,11 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1) { return balance; } -CAmount getBalanceZaddr(std::string address, int minDepth = 1) { +CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) { CAmount balance = 0; std::vector entries; LOCK2(cs_main, pwalletMain->cs_wallet); - pwalletMain->GetFilteredNotes(entries, address, minDepth); + pwalletMain->GetFilteredNotes(entries, address, minDepth, true, ignoreUnspendable); for (auto & entry : entries) { balance += CAmount(entry.plaintext.value); } @@ -3324,6 +3358,9 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) " \"amount\": xxxxx, (numeric) the amount of value in the note\n" " \"memo\": xxxxx, (string) hexademical string representation of memo field\n" "}\n" + "\nExamples:\n" + + HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + + HelpExampleRpc("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -3347,14 +3384,14 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr."); } - if (!pwalletMain->HaveSpendingKey(zaddr)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found."); + if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); } UniValue result(UniValue::VARR); std::vector entries; - pwalletMain->GetFilteredNotes(entries, fromaddress, nMinDepth, false); + pwalletMain->GetFilteredNotes(entries, fromaddress, nMinDepth, false, false); for (CNotePlaintextEntry & entry : entries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); @@ -3376,6 +3413,8 @@ UniValue z_getbalance(const UniValue& params, bool fHelp) throw runtime_error( "z_getbalance \"address\" ( minconf )\n" "\nReturns the balance of a taddr or zaddr belonging to the node’s wallet.\n" + "\nCAUTION: If address is a watch-only zaddr, the returned balance may be larger than the actual balance," + "\nbecause spends cannot be detected with incoming viewing keys.\n" "\nArguments:\n" "1. \"address\" (string) The selected address. It may be a transparent or private address.\n" "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" @@ -3413,16 +3452,16 @@ UniValue z_getbalance(const UniValue& params, bool fHelp) } catch (const std::runtime_error&) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr."); } - if (!pwalletMain->HaveSpendingKey(zaddr)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found."); + if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found."); } } CAmount nBalance = 0; if (fromTaddr) { - nBalance = getBalanceTaddr(fromaddress, nMinDepth); + nBalance = getBalanceTaddr(fromaddress, nMinDepth, false); } else { - nBalance = getBalanceZaddr(fromaddress, nMinDepth); + nBalance = getBalanceZaddr(fromaddress, nMinDepth, false); } return ValueFromAmount(nBalance); @@ -3434,12 +3473,15 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() > 1) + if (fHelp || params.size() > 2) throw runtime_error( - "z_gettotalbalance ( minconf )\n" + "z_gettotalbalance ( minconf includeWatchonly )\n" "\nReturn the total value of funds stored in the node’s wallet.\n" + "\nCAUTION: If the wallet contains watch-only zaddrs, the returned private balance may be larger than the actual balance," + "\nbecause spends cannot be detected with incoming viewing keys.\n" "\nArguments:\n" "1. minconf (numeric, optional, default=1) Only include private and transparent transactions confirmed at least this many times.\n" + "2. includeWatchonly (bool, optional, default=false) Also include balance in watchonly addresses (see 'importaddress' and 'z_importviewingkey')\n" "\nResult:\n" "{\n" " \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n" @@ -3458,21 +3500,26 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); int nMinDepth = 1; - if (params.size() == 1) { + if (params.size() > 0) { nMinDepth = params[0].get_int(); } if (nMinDepth < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0"); } + bool fIncludeWatchonly = false; + if (params.size() > 1) { + fIncludeWatchonly = params[1].get_bool(); + } + // getbalance and "getbalance * 1 true" should return the same number // but they don't because wtx.GetAmounts() does not handle tx where there are no outputs // pwalletMain->GetBalance() does not accept min depth parameter // so we use our own method to get balance of utxos. - CAmount nBalance = getBalanceTaddr("", nMinDepth); - CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth); + CAmount nBalance = getBalanceTaddr("", nMinDepth, !fIncludeWatchonly); + CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth, !fIncludeWatchonly); uint64_t interest = komodo_interestsum(); - CAmount nTotalBalance = nBalance + nPrivateBalance + interest; + CAmount nTotalBalance = nBalance + nPrivateBalance; UniValue result(UniValue::VOBJ); result.push_back(Pair("transparent", FormatMoney(nBalance))); result.push_back(Pair("interest", FormatMoney(interest))); @@ -3495,6 +3542,9 @@ UniValue z_getoperationresult(const UniValue& params, bool fHelp) "1. \"operationid\" (array, optional) A list of operation ids we are interested in. If not provided, examine all operations known to the node.\n" "\nResult:\n" "\" [object, ...]\" (array) A list of JSON objects\n" + "\nExamples:\n" + + HelpExampleCli("z_getoperationresult", "'[\"operationid\", ... ]'") + + HelpExampleRpc("z_getoperationresult", "'[\"operationid\", ... ]'") ); // This call will remove finished operations @@ -3515,6 +3565,9 @@ UniValue z_getoperationstatus(const UniValue& params, bool fHelp) "1. \"operationid\" (array, optional) A list of operation ids we are interested in. If not provided, examine all operations known to the node.\n" "\nResult:\n" "\" [object, ...]\" (array) A list of JSON objects\n" + "\nExamples:\n" + + HelpExampleCli("z_getoperationstatus", "'[\"operationid\", ... ]'") + + HelpExampleRpc("z_getoperationstatus", "'[\"operationid\", ... ]'") ); // This call is idempotent so we don't want to remove finished operations @@ -3615,6 +3668,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) + strprintf("%s", FormatMoney(ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" "\nResult:\n" "\"operationid\" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" + "\nExamples:\n" + + HelpExampleCli("z_sendmany", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" '[{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]'") + + HelpExampleRpc("z_sendmany", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", [{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -3688,7 +3744,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) if (!memoValue.isNull()) { memo = memoValue.get_str(); if (!isZaddr) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr."); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo cannot be used with a taddr. It can only be used with a zaddr."); } else if (!IsHex(memo)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format."); } @@ -3767,15 +3823,571 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) o.push_back(Pair("fee", std::stod(FormatMoney(nFee)))); UniValue contextInfo = o; + // Contextual transaction we will build on + int nextBlockHeight = chainActive.Height() + 1; + CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight); + bool isShielded = !fromTaddr || zaddrRecipients.size() > 0; + if (contextualTx.nVersion == 1 && isShielded) { + contextualTx.nVersion = 2; // Tx format should support vjoinsplits + } + if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + contextualTx.nExpiryHeight = nextBlockHeight + expiryDelta; + } + // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); - std::shared_ptr operation( new AsyncRPCOperation_sendmany(fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) ); + std::shared_ptr operation( new AsyncRPCOperation_sendmany(contextualTx, fromaddress, taddrRecipients, zaddrRecipients, nMinDepth, nFee, contextInfo) ); q->addOperation(operation); AsyncRPCOperationId operationId = operation->getId(); return operationId; } +/** +When estimating the number of coinbase utxos we can shield in a single transaction: +1. Joinsplit description is 1802 bytes. +2. Transaction overhead ~ 100 bytes +3. Spending a typical P2PKH is >=148 bytes, as defined in CTXIN_SPEND_DUST_SIZE. +4. Spending a multi-sig P2SH address can vary greatly: + https://github.com/bitcoin/bitcoin/blob/c3ad56f4e0b587d8d763af03d743fdfc2d180c9b/src/main.cpp#L517 + In real-world coinbase utxos, we consider a 3-of-3 multisig, where the size is roughly: + (3*(33+1))+3 = 105 byte redeem script + 105 + 1 + 3*(73+1) = 328 bytes of scriptSig, rounded up to 400 based on testnet experiments. +*/ +#define CTXIN_SPEND_P2SH_SIZE 400 + +#define SHIELD_COINBASE_DEFAULT_LIMIT 50 + +UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 2 || params.size() > 4) + throw runtime_error( + "z_shieldcoinbase \"fromaddress\" \"tozaddress\" ( fee ) ( limit )\n" + "\nShield transparent coinbase funds by sending to a shielded zaddr. This is an asynchronous operation and utxos" + "\nselected for shielding will be locked. If there is an error, they are unlocked. The RPC call `listlockunspent`" + "\ncan be used to return a list of locked utxos. The number of coinbase utxos selected for shielding can be limited" + "\nby the caller. If the limit parameter is set to zero, the -mempooltxinputlimit option will determine the number" + "\nof uxtos. Any limit is constrained by the consensus rule defining a maximum transaction size of " + + strprintf("%d bytes.", MAX_TX_SIZE) + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. \"fromaddress\" (string, required) The address is a taddr or \"*\" for all taddrs belonging to the wallet.\n" + "2. \"toaddress\" (string, required) The address is a zaddr.\n" + "3. fee (numeric, optional, default=" + + strprintf("%s", FormatMoney(SHIELD_COINBASE_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" + "4. limit (numeric, optional, default=" + + strprintf("%d", SHIELD_COINBASE_DEFAULT_LIMIT) + ") Limit on the maximum number of utxos to shield. Set to 0 to use node option -mempooltxinputlimit.\n" + "\nResult:\n" + "{\n" + " \"remainingUTXOs\": xxx (numeric) Number of coinbase utxos still available for shielding.\n" + " \"remainingValue\": xxx (numeric) Value of coinbase utxos still available for shielding.\n" + " \"shieldingUTXOs\": xxx (numeric) Number of coinbase utxos being shielded.\n" + " \"shieldingValue\": xxx (numeric) Value of coinbase utxos being shielded.\n" + " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("z_shieldcoinbase", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + + HelpExampleRpc("z_shieldcoinbase", "\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + // Validate the from address + auto fromaddress = params[0].get_str(); + bool isFromWildcard = fromaddress == "*"; + CBitcoinAddress taddr; + if (!isFromWildcard) { + taddr = CBitcoinAddress(fromaddress); + if (!taddr.IsValid()) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or \"*\"."); + } + } + + // Validate the destination address + auto destaddress = params[1].get_str(); + try { + CZCPaymentAddress pa(destaddress); + libzcash::PaymentAddress zaddr = pa.Get(); + } catch (const std::runtime_error&) { + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); + } + + // Convert fee from currency format to zatoshis + CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE; + if (params.size() > 2) { + if (params[2].get_real() == 0.0) { + nFee = 0; + } else { + nFee = AmountFromValue( params[2] ); + } + } + + int nLimit = SHIELD_COINBASE_DEFAULT_LIMIT; + if (params.size() > 3) { + nLimit = params[3].get_int(); + if (nLimit < 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of utxos cannot be negative"); + } + } + + // Prepare to get coinbase utxos + std::vector inputs; + CAmount shieldedValue = 0; + CAmount remainingValue = 0; + size_t estimatedTxSize = 2000; // 1802 joinsplit description + tx overhead + wiggle room + size_t utxoCounter = 0; + bool maxedOutFlag = false; + size_t mempoolLimit = (nLimit != 0) ? nLimit : (size_t)GetArg("-mempooltxinputlimit", 0); + + // Set of addresses to filter utxos by + set setAddress = {}; + if (!isFromWildcard) { + setAddress.insert(taddr); + } + + // Get available utxos + vector vecOutputs; + pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, true); + + // Find unspent coinbase utxos and update estimated size + BOOST_FOREACH(const COutput& out, vecOutputs) { + if (!out.fSpendable) { + continue; + } + + CTxDestination address; + if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { + continue; + } + // If taddr is not wildcard "*", filter utxos + if (setAddress.size()>0 && !setAddress.count(address)) { + continue; + } + + if (!out.tx->IsCoinBase()) { + continue; + } + + utxoCounter++; + CAmount nValue = out.tx->vout[out.i].nValue; + + if (!maxedOutFlag) { + CBitcoinAddress ba(address); + size_t increase = (ba.IsScript()) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE; + if (estimatedTxSize + increase >= MAX_TX_SIZE || + (mempoolLimit > 0 && utxoCounter > mempoolLimit)) + { + maxedOutFlag = true; + } else { + estimatedTxSize += increase; + ShieldCoinbaseUTXO utxo = {out.tx->GetHash(), out.i, nValue}; + inputs.push_back(utxo); + shieldedValue += nValue; + } + } + + if (maxedOutFlag) { + remainingValue += nValue; + } + } + + size_t numUtxos = inputs.size(); + + if (numUtxos == 0) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any coinbase funds to shield."); + } + + if (shieldedValue < nFee) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, + strprintf("Insufficient coinbase funds, have %s, which is less than miners fee %s", + FormatMoney(shieldedValue), FormatMoney(nFee))); + } + + // Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee) + CAmount netAmount = shieldedValue - nFee; + if (nFee > netAmount) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount))); + } + + // Keep record of parameters in context object + UniValue contextInfo(UniValue::VOBJ); + contextInfo.push_back(Pair("fromaddress", params[0])); + contextInfo.push_back(Pair("toaddress", params[1])); + contextInfo.push_back(Pair("fee", ValueFromAmount(nFee))); + + // Contextual transaction we will build on + int nextBlockHeight = chainActive.Height() + 1; + CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), nextBlockHeight); + if (contextualTx.nVersion == 1) { + contextualTx.nVersion = 2; // Tx format should support vjoinsplits + } + if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + contextualTx.nExpiryHeight = nextBlockHeight + expiryDelta; + } + + // Create operation and add to global queue + std::shared_ptr q = getAsyncRPCQueue(); + std::shared_ptr operation( new AsyncRPCOperation_shieldcoinbase(contextualTx, inputs, destaddress, nFee, contextInfo) ); + q->addOperation(operation); + AsyncRPCOperationId operationId = operation->getId(); + + // Return continuation information + UniValue o(UniValue::VOBJ); + o.push_back(Pair("remainingUTXOs", utxoCounter - numUtxos)); + o.push_back(Pair("remainingValue", ValueFromAmount(remainingValue))); + o.push_back(Pair("shieldingUTXOs", numUtxos)); + o.push_back(Pair("shieldingValue", ValueFromAmount(shieldedValue))); + o.push_back(Pair("opid", operationId)); + return o; +} + + +#define MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT 50 +#define MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT 10 + +#define JOINSPLIT_SIZE JSDescription().GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) + +UniValue z_mergetoaddress(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-zmergetoaddress", false); + std::string strDisabledMsg = ""; + if (!fEnableMergeToAddress) { + strDisabledMsg = "\nWARNING: z_mergetoaddress is DISABLED but can be enabled as an experimental feature.\n"; + } + + if (fHelp || params.size() < 2 || params.size() > 6) + throw runtime_error( + "z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n" + + strDisabledMsg + + "\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`" + "\nto combine those into a single note." + "\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they" + "\nare unlocked. The RPC call `listlockunspent` can be used to return a list of locked UTXOs." + "\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit" + "\nparameter is set to zero, the -mempooltxinputlimit option will determine the number of UTXOs. Any limit is" + "\nconstrained by the consensus rule defining a maximum transaction size of " + + strprintf("%d bytes.", MAX_TX_SIZE) + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. fromaddresses (string, required) A JSON array with addresses.\n" + " The following special strings are accepted inside the array:\n" + " - \"*\": Merge both UTXOs and notes from all addresses belonging to the wallet.\n" + " - \"ANY_TADDR\": Merge UTXOs from all t-addrs belonging to the wallet.\n" + " - \"ANY_ZADDR\": Merge notes from all z-addrs belonging to the wallet.\n" + " If a special string is given, any given addresses of that type will be ignored.\n" + " [\n" + " \"address\" (string) Can be a t-addr or a z-addr\n" + " ,...\n" + " ]\n" + "2. \"toaddress\" (string, required) The t-addr or z-addr to send the funds to.\n" + "3. fee (numeric, optional, default=" + + strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" + "4. transparent_limit (numeric, optional, default=" + + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit.\n" + "4. shielded_limit (numeric, optional, default=" + + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" + "5. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n" + "\nResult:\n" + "{\n" + " \"remainingUTXOs\": xxx (numeric) Number of UTXOs still available for merging.\n" + " \"remainingTransparentValue\": xxx (numeric) Value of UTXOs still available for merging.\n" + " \"remainingNotes\": xxx (numeric) Number of notes still available for merging.\n" + " \"remainingShieldedValue\": xxx (numeric) Value of notes still available for merging.\n" + " \"mergingUTXOs\": xxx (numeric) Number of UTXOs being merged.\n" + " \"mergingTransparentValue\": xxx (numeric) Value of UTXOs being merged.\n" + " \"mergingNotes\": xxx (numeric) Number of notes being merged.\n" + " \"mergingShieldedValue\": xxx (numeric) Value of notes being merged.\n" + " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("z_mergetoaddress", "'[\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf") + + HelpExampleRpc("z_mergetoaddress", "[\"t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\"], \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + ); + + if (!fEnableMergeToAddress) { + throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled."); + } + + LOCK2(cs_main, pwalletMain->cs_wallet); + + bool useAny = false; + bool useAnyUTXO = false; + bool useAnyNote = false; + std::set taddrs = {}; + std::set zaddrs = {}; + + UniValue addresses = params[0].get_array(); + if (addresses.size()==0) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, fromaddresses array is empty."); + + // Keep track of addresses to spot duplicates + std::set setAddress; + + // Sources + for (const UniValue& o : addresses.getValues()) { + if (!o.isStr()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string"); + + std::string address = o.get_str(); + if (address == "*") { + useAny = true; + } else if (address == "ANY_TADDR") { + useAnyUTXO = true; + } else if (address == "ANY_ZADDR") { + useAnyNote = true; + } else { + CBitcoinAddress taddr(address); + if (taddr.IsValid()) { + // Ignore any listed t-addrs if we are using all of them + if (!(useAny || useAnyUTXO)) { + taddrs.insert(taddr); + } + } else { + try { + CZCPaymentAddress zaddr(address); + // Ignore listed z-addrs if we are using all of them + if (!(useAny || useAnyNote)) { + zaddrs.insert(zaddr.Get()); + } + } catch (const std::runtime_error&) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + string("Invalid parameter, unknown address format: ") + address); + } + } + } + + if (setAddress.count(address)) + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address); + setAddress.insert(address); + } + + // Validate the destination address + auto destaddress = params[1].get_str(); + bool isToZaddr = false; + CBitcoinAddress taddr(destaddress); + if (!taddr.IsValid()) { + try { + CZCPaymentAddress zaddr(destaddress); + zaddr.Get(); + isToZaddr = true; + } catch (const std::runtime_error&) { + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); + } + } + + // Convert fee from currency format to zatoshis + CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE; + if (params.size() > 2) { + if (params[2].get_real() == 0.0) { + nFee = 0; + } else { + nFee = AmountFromValue( params[2] ); + } + } + + int nUTXOLimit = MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT; + if (params.size() > 3) { + nUTXOLimit = params[3].get_int(); + if (nUTXOLimit < 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of UTXOs cannot be negative"); + } + } + + int nNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT; + if (params.size() > 4) { + nNoteLimit = params[4].get_int(); + if (nNoteLimit < 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative"); + } + } + + std::string memo; + if (params.size() > 5) { + memo = params[5].get_str(); + if (!isToZaddr) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr."); + } else if (!IsHex(memo)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format."); + } + if (memo.length() > ZC_MEMO_SIZE*2) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", ZC_MEMO_SIZE )); + } + } + + MergeToAddressRecipient recipient(destaddress, memo); + + // Prepare to get UTXOs and notes + std::vector utxoInputs; + std::vector noteInputs; + CAmount mergedUTXOValue = 0; + CAmount mergedNoteValue = 0; + CAmount remainingUTXOValue = 0; + CAmount remainingNoteValue = 0; + size_t utxoCounter = 0; + size_t noteCounter = 0; + bool maxedOutUTXOsFlag = false; + bool maxedOutNotesFlag = false; + size_t mempoolLimit = (nUTXOLimit != 0) ? nUTXOLimit : (size_t)GetArg("-mempooltxinputlimit", 0); + + size_t estimatedTxSize = 200; // tx overhead + wiggle room + if (isToZaddr) { + estimatedTxSize += JOINSPLIT_SIZE; + } + + if (useAny || useAnyUTXO || taddrs.size() > 0) { + // Get available utxos + vector vecOutputs; + pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false); + + // Find unspent utxos and update estimated size + for (const COutput& out : vecOutputs) { + if (!out.fSpendable) { + continue; + } + + CTxDestination address; + if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { + continue; + } + // If taddr is not wildcard "*", filter utxos + if (taddrs.size() > 0 && !taddrs.count(address)) { + continue; + } + + utxoCounter++; + CAmount nValue = out.tx->vout[out.i].nValue; + + if (!maxedOutUTXOsFlag) { + CBitcoinAddress ba(address); + size_t increase = (ba.IsScript()) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE; + if (estimatedTxSize + increase >= MAX_TX_SIZE || + (mempoolLimit > 0 && utxoCounter > mempoolLimit)) + { + maxedOutUTXOsFlag = true; + } else { + estimatedTxSize += increase; + COutPoint utxo(out.tx->GetHash(), out.i); + utxoInputs.emplace_back(utxo, nValue); + mergedUTXOValue += nValue; + } + } + + if (maxedOutUTXOsFlag) { + remainingUTXOValue += nValue; + } + } + } + + if (useAny || useAnyNote || zaddrs.size() > 0) { + // Get available notes + std::vector entries; + pwalletMain->GetFilteredNotes(entries, zaddrs); + + // Find unspent notes and update estimated size + for (CNotePlaintextEntry& entry : entries) { + noteCounter++; + CAmount nValue = entry.plaintext.value; + + if (!maxedOutNotesFlag) { + // If we haven't added any notes yet and the merge is to a + // z-address, we have already accounted for the first JoinSplit. + size_t increase = (noteInputs.empty() && !isToZaddr) || (noteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; + if (estimatedTxSize + increase >= MAX_TX_SIZE || + (nNoteLimit > 0 && noteCounter > nNoteLimit)) + { + maxedOutNotesFlag = true; + } else { + estimatedTxSize += increase; + SpendingKey zkey; + pwalletMain->GetSpendingKey(entry.address, zkey); + noteInputs.emplace_back(entry.jsop, entry.plaintext.note(entry.address), nValue, zkey); + mergedNoteValue += nValue; + } + } + + if (maxedOutNotesFlag) { + remainingNoteValue += nValue; + } + } + } + + size_t numUtxos = utxoInputs.size(); + size_t numNotes = noteInputs.size(); + + if (numUtxos == 0 && numNotes == 0) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge."); + } + + // Sanity check: Don't do anything if: + // - We only have one from address + // - It's equal to toaddress + // - The address only contains a single UTXO or note + if (setAddress.size() == 1 && setAddress.count(destaddress) && (numUtxos + numNotes) == 1) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Destination address is also the only source address, and all its funds are already merged."); + } + + CAmount mergedValue = mergedUTXOValue + mergedNoteValue; + if (mergedValue < nFee) { + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, + strprintf("Insufficient funds, have %s, which is less than miners fee %s", + FormatMoney(mergedValue), FormatMoney(nFee))); + } + + // Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee) + CAmount netAmount = mergedValue - nFee; + if (nFee > netAmount) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount))); + } + + // Keep record of parameters in context object + UniValue contextInfo(UniValue::VOBJ); + contextInfo.push_back(Pair("fromaddresses", params[0])); + contextInfo.push_back(Pair("toaddress", params[1])); + contextInfo.push_back(Pair("fee", ValueFromAmount(nFee))); + + // Contextual transaction we will build on + int nextBlockHeight = chainActive.Height() + 1; + CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), + nextBlockHeight); + bool isShielded = numNotes > 0 || isToZaddr; + if (contextualTx.nVersion == 1 && isShielded) { + contextualTx.nVersion = 2; // Tx format should support vjoinsplit + } + if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) { + contextualTx.nExpiryHeight = nextBlockHeight + expiryDelta; + } + + // Create operation and add to global queue + std::shared_ptr q = getAsyncRPCQueue(); + std::shared_ptr operation( + new AsyncRPCOperation_mergetoaddress(contextualTx, utxoInputs, noteInputs, recipient, nFee, contextInfo) ); + q->addOperation(operation); + AsyncRPCOperationId operationId = operation->getId(); + + // Return continuation information + UniValue o(UniValue::VOBJ); + o.push_back(Pair("remainingUTXOs", utxoCounter - numUtxos)); + o.push_back(Pair("remainingTransparentValue", ValueFromAmount(remainingUTXOValue))); + o.push_back(Pair("remainingNotes", noteCounter - numNotes)); + o.push_back(Pair("remainingShieldedValue", ValueFromAmount(remainingNoteValue))); + o.push_back(Pair("mergingUTXOs", numUtxos)); + o.push_back(Pair("mergingTransparentValue", ValueFromAmount(mergedUTXOValue))); + o.push_back(Pair("mergingNotes", numNotes)); + o.push_back(Pair("mergingShieldedValue", ValueFromAmount(mergedNoteValue))); + o.push_back(Pair("opid", operationId)); + return o; +} + + UniValue z_listoperationids(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) @@ -3786,7 +4398,7 @@ UniValue z_listoperationids(const UniValue& params, bool fHelp) "z_listoperationids\n" "\nReturns the list of operation ids currently known to the wallet.\n" "\nArguments:\n" - "1. \"status\" (string, optional) Filter result by the operation's state state e.g. \"success\".\n" + "1. \"status\" (string, optional) Filter result by the operation's state e.g. \"success\".\n" "\nResult:\n" "[ (json array of string)\n" " \"operationid\" (string) an operation id belonging to the wallet\n" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 9dc96f10c..8172c00e3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -8,7 +8,9 @@ #include "base58.h" #include "checkpoints.h" #include "coincontrol.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" +#include "consensus/consensus.h" #include "init.h" #include "main.h" #include "net.h" @@ -111,6 +113,10 @@ bool CWallet::AddZKey(const libzcash::SpendingKey &key) if (!CCryptoKeyStore::AddSpendingKey(key)) return false; + // check if we need to remove from viewing keys + if (HaveViewingKey(addr)) + RemoveViewingKey(key.viewing_key()); + if (!fFileBacked) return true; @@ -194,10 +200,10 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address, - const libzcash::ViewingKey &vk, + const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { - if (!CCryptoKeyStore::AddCryptedSpendingKey(address, vk, vchCryptedSecret)) + if (!CCryptoKeyStore::AddCryptedSpendingKey(address, rk, vchCryptedSecret)) return false; if (!fFileBacked) return true; @@ -205,12 +211,12 @@ bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address, LOCK(cs_wallet); if (pwalletdbEncryption) { return pwalletdbEncryption->WriteCryptedZKey(address, - vk, + rk, vchCryptedSecret, mapZKeyMetadata[address]); } else { return CWalletDB(strWalletFile).WriteCryptedZKey(address, - vk, + rk, vchCryptedSecret, mapZKeyMetadata[address]); } @@ -240,9 +246,9 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) +bool CWallet::LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret) { - return CCryptoKeyStore::AddCryptedSpendingKey(addr, vk, vchCryptedSecret); + return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret); } bool CWallet::LoadZKey(const libzcash::SpendingKey &key) @@ -250,6 +256,38 @@ bool CWallet::LoadZKey(const libzcash::SpendingKey &key) return CCryptoKeyStore::AddSpendingKey(key); } +bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk) +{ + if (!CCryptoKeyStore::AddViewingKey(vk)) { + return false; + } + nTimeFirstKey = 1; // No birthday information for viewing keys. + if (!fFileBacked) { + return true; + } + return CWalletDB(strWalletFile).WriteViewingKey(vk); +} + +bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk) +{ + AssertLockHeld(cs_wallet); + if (!CCryptoKeyStore::RemoveViewingKey(vk)) { + return false; + } + if (fFileBacked) { + if (!CWalletDB(strWalletFile).EraseViewingKey(vk)) { + return false; + } + } + + return true; +} + +bool CWallet::LoadViewingKey(const libzcash::ViewingKey &vk) +{ + return CCryptoKeyStore::AddViewingKey(vk); +} + bool CWallet::AddCScript(const CScript& redeemScript) { if (!CCryptoKeyStore::AddCScript(redeemScript)) @@ -963,7 +1001,8 @@ void CWallet::MarkDirty() } /** - * Ensure that every note in the wallet has a cached nullifier. + * Ensure that every note in the wallet (for which we possess a spending key) + * has a cached nullifier. */ bool CWallet::UpdateNullifierNoteMap() { @@ -977,16 +1016,17 @@ bool CWallet::UpdateNullifierNoteMap() for (std::pair& wtxItem : mapWallet) { for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) { if (!item.second.nullifier) { - auto i = item.first.js; - GetNoteDecryptor(item.second.address, dec); - auto hSig = wtxItem.second.vjoinsplit[i].h_sig( - *pzcashParams, wtxItem.second.joinSplitPubKey); - item.second.nullifier = GetNoteNullifier( - wtxItem.second.vjoinsplit[i], - item.second.address, - dec, - hSig, - item.first.n); + if (GetNoteDecryptor(item.second.address, dec)) { + auto i = item.first.js; + auto hSig = wtxItem.second.vjoinsplit[i].h_sig( + *pzcashParams, wtxItem.second.joinSplitPubKey); + item.second.nullifier = GetNoteNullifier( + wtxItem.second.vjoinsplit[i], + item.second.address, + dec, + hSig, + item.first.n); + } } } UpdateNullifierNoteMapWithTx(wtxItem.second); @@ -1248,7 +1288,9 @@ boost::optional CWallet::GetNoteNullifier(const JSDescription& jsdesc, hSig, (unsigned char) n); auto note = note_pt.note(address); - // SpendingKeys are only available if the wallet is unlocked + // SpendingKeys are only available if: + // - We have them (this isn't a viewing key) + // - The wallet is unlocked libzcash::SpendingKey key; if (GetSpendingKey(address, key)) { ret = note.nullifier(key); @@ -2205,7 +2247,7 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const * populate vCoins with vector of available COutputs. */ uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime); -uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue); +uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight); void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const { @@ -2249,9 +2291,9 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const { if ( pcoin->vout[i].nValue >= 10*COIN ) { - komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue); if ( (tipindex= chainActive.Tip()) != 0 ) { + komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->nHeight); interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime); } else interest = 0; //interest = komodo_interestnew(chainActive.Tip()->nHeight+1,pcoin->vout[i].nValue,pcoin->nLockTime,chainActive.Tip()->nTime); @@ -2580,6 +2622,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC CReserveKey reservekey(this); CWalletTx wtx; + if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false)) return false; @@ -2629,36 +2672,23 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt wtxNew.fTimeReceivedIsTxTime = true; wtxNew.BindWallet(this); - CMutableTransaction txNew; - - if ( 0 ) - { - // Discourage fee sniping. - // - // However because of a off-by-one-error in previous versions we need to - // neuter it by setting nLockTime to at least one less than nBestHeight. - // Secondly currently propagation of transactions created for block heights - // corresponding to blocks that were just mined may be iffy - transactions - // aren't re-accepted into the mempool - we additionally neuter the code by - // going ten blocks back. Doesn't yet do anything for sniping, but does act - // to shake out wallet bugs like not showing nLockTime'd transactions at - // all. - txNew.nLockTime = std::max(0, chainActive.Height() - 10); - - // Secondly occasionally randomly pick a nLockTime even further back, so - // that transactions that are delayed after signing for whatever reason, - // e.g. high-latency mix networks and some CoinJoin implementations, have - // better privacy. - if (GetRandInt(10) == 0) - txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); - - assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); - assert(txNew.nLockTime < LOCKTIME_THRESHOLD); - } - else - { + int nextBlockHeight = chainActive.Height() + 1; + CMutableTransaction txNew = CreateNewContextualCMutableTransaction( + Params().GetConsensus(), nextBlockHeight); txNew.nLockTime = (uint32_t)chainActive.Tip()->nTime + 1; // set to a time close to now + + // Activates after Overwinter network upgrade + // Set nExpiryHeight to expiryDelta (default 20) blocks past current block height + if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) + { + if (nextBlockHeight + expiryDelta >= TX_EXPIRY_HEIGHT_THRESHOLD){ + strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD."); + return false; + } else { + txNew.nExpiryHeight = nextBlockHeight + expiryDelta; + } } + { LOCK2(cs_main, cs_wallet); { @@ -2779,8 +2809,6 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY; if ( USE_EXTERNAL_PUBKEY == 0 ) { - //fprintf(stderr,"use notary pubkey\n"); - //scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG; bool ret; ret = reservekey.GetReservedKey(vchPubKey); assert(ret); // should never fail, as we just unlocked @@ -2788,6 +2816,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt } else { + //fprintf(stderr,"use notary pubkey\n"); scriptChange = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG; } } @@ -2839,6 +2868,19 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(), std::numeric_limits::max()-1)); + // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects + size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); + if (limit > 0) { + size_t n = txNew.vin.size(); + if (n > limit) { + strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str()); + return false; + } + } + + // Grab the current consensus branch ID + auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); + // Sign int nIn = 0; CTransaction txNewConst(txNew); @@ -2846,17 +2888,20 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt { bool signSuccess; const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey; - CScript& scriptSigRes = txNew.vin[nIn].scriptSig; + SignatureData sigdata; if (sign) - signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes); + signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId); else - signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes); + signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId); if (!signSuccess) { strFailReason = _("Signing transaction failed"); return false; + } else { + UpdateTransaction(txNew, nIn, sigdata); } + nIn++; } @@ -3725,15 +3770,28 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) * Find notes in the wallet filtered by payment address, min depth and ability to spend. * These notes are decrypted and added to the output parameter vector, outEntries. */ -void CWallet::GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth, bool ignoreSpent) +void CWallet::GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable) { - bool fFilterAddress = false; - libzcash::PaymentAddress filterPaymentAddress; + std::set filterAddresses; + if (address.length() > 0) { - filterPaymentAddress = CZCPaymentAddress(address).Get(); - fFilterAddress = true; + filterAddresses.insert(CZCPaymentAddress(address).Get()); } + GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable); +} + +/** + * Find notes in the wallet filtered by payment addresses, min depth and ability to spend. + * These notes are decrypted and added to the output parameter vector, outEntries. + */ +void CWallet::GetFilteredNotes( + std::vector& outEntries, + std::set& filterAddresses, + int minDepth, + bool ignoreSpent, + bool ignoreUnspendable) +{ LOCK2(cs_main, cs_wallet); for (auto & p : mapWallet) { @@ -3754,7 +3812,7 @@ void CWallet::GetFilteredNotes(std::vector & outEntries, st PaymentAddress pa = nd.address; // skip notes which belong to a different payment address in the wallet - if (fFilterAddress && !(pa == filterPaymentAddress)) { + if (!(filterAddresses.empty() || filterAddresses.count(pa))) { continue; } @@ -3763,6 +3821,11 @@ void CWallet::GetFilteredNotes(std::vector & outEntries, st continue; } + // skip notes which cannot be spent + if (ignoreUnspendable && !HaveSpendingKey(pa)) { + continue; + } + int i = jsop.js; // Index into CTransaction.vjoinsplit int j = jsop.n; // Index into JSDescription.ciphertexts @@ -3783,7 +3846,7 @@ void CWallet::GetFilteredNotes(std::vector & outEntries, st hSig, (unsigned char) j); - outEntries.push_back(CNotePlaintextEntry{jsop, plaintext}); + outEntries.push_back(CNotePlaintextEntry{jsop, pa, plaintext}); } catch (const note_decryption_failed &err) { // Couldn't decrypt with this spending key diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 01285ca2b..0f9e6c5da 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -8,9 +8,9 @@ #include "amount.h" #include "coins.h" -#include "consensus/consensus.h" #include "key.h" #include "keystore.h" +#include "main.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "tinyformat.h" @@ -61,7 +61,6 @@ static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; #define _COINBASE_MATURITY 100 static const unsigned int WITNESS_CACHE_SIZE = _COINBASE_MATURITY+10; -class CAccountingEntry; class CBlockIndex; class CCoinControl; class COutput; @@ -154,7 +153,7 @@ struct COutputEntry int vout; }; -/** An note outpoint */ +/** A note outpoint */ class JSOutPoint { public: @@ -273,6 +272,7 @@ typedef std::map mapNoteData_t; struct CNotePlaintextEntry { JSOutPoint jsop; + libzcash::PaymentAddress address; libzcash::NotePlaintext plaintext; }; @@ -575,6 +575,86 @@ public: } }; +/** + * Internal transfers. + * Database key is acentry. + */ +class CAccountingEntry +{ +public: + std::string strAccount; + CAmount nCreditDebit; + int64_t nTime; + std::string strOtherAccount; + std::string strComment; + mapValue_t mapValue; + int64_t nOrderPos; //! position in ordered transaction list + uint64_t nEntryNo; + + CAccountingEntry() + { + SetNull(); + } + + void SetNull() + { + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; + nEntryNo = 0; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + //! Note: strAccount is serialized as part of the key, not here. + READWRITE(nCreditDebit); + READWRITE(nTime); + READWRITE(LIMITED_STRING(strOtherAccount, 65536)); + + if (!ser_action.ForRead()) + { + WriteOrderPos(nOrderPos, mapValue); + + if (!(mapValue.empty() && _ssExtra.empty())) + { + CDataStream ss(nType, nVersion); + ss.insert(ss.begin(), '\0'); + ss << mapValue; + ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); + strComment.append(ss.str()); + } + } + + READWRITE(LIMITED_STRING(strComment, 65536)); + + size_t nSepPos = strComment.find("\0", 0, 1); + if (ser_action.ForRead()) + { + mapValue.clear(); + if (std::string::npos != nSepPos) + { + CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); + ss >> mapValue; + _ssExtra = std::vector(ss.begin(), ss.end()); + } + ReadOrderPos(nOrderPos, mapValue); + } + if (std::string::npos != nSepPos) + strComment.erase(nSepPos); + + mapValue.erase("n"); + } + +private: + std::vector _ssExtra; +}; /** @@ -876,9 +956,15 @@ public: //! Load spending key metadata (used by LoadWallet) bool LoadZKeyMetadata(const libzcash::PaymentAddress &addr, const CKeyMetadata &meta); //! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet) - bool LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ViewingKey &vk, const std::vector &vchCryptedSecret); + bool LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); //! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h) - bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, const libzcash::ViewingKey &vk, const std::vector &vchCryptedSecret); + bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector &vchCryptedSecret); + + //! Adds a viewing key to the store, and saves it to disk. + bool AddViewingKey(const libzcash::ViewingKey &vk); + bool RemoveViewingKey(const libzcash::ViewingKey &vk); + //! Adds a viewing key to the store, without saving it to disk (used by LoadWallet) + bool LoadViewingKey(const libzcash::ViewingKey &dest); /** * Increment the next transaction order id @@ -1041,8 +1127,19 @@ public: void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } /* Find notes filtered by payment address, min depth, ability to spend */ - void GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth=1, bool ignoreSpent=true); + void GetFilteredNotes(std::vector & outEntries, + std::string address, + int minDepth=1, + bool ignoreSpent=true, + bool ignoreUnspendable=true); + /* Find notes filtered by payment addresses, min depth, ability to spend */ + void GetFilteredNotes(std::vector& outEntries, + std::set& filterAddresses, + int minDepth=1, + bool ignoreSpent=true, + bool ignoreUnspendable=true); + }; /** A key allocated from the key pool. */ @@ -1098,88 +1195,4 @@ public: READWRITE(vchPubKey); } }; - - - -/** - * Internal transfers. - * Database key is acentry. - */ -class CAccountingEntry -{ -public: - std::string strAccount; - CAmount nCreditDebit; - int64_t nTime; - std::string strOtherAccount; - std::string strComment; - mapValue_t mapValue; - int64_t nOrderPos; //! position in ordered transaction list - uint64_t nEntryNo; - - CAccountingEntry() - { - SetNull(); - } - - void SetNull() - { - nCreditDebit = 0; - nTime = 0; - strAccount.clear(); - strOtherAccount.clear(); - strComment.clear(); - nOrderPos = -1; - nEntryNo = 0; - } - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - //! Note: strAccount is serialized as part of the key, not here. - READWRITE(nCreditDebit); - READWRITE(nTime); - READWRITE(LIMITED_STRING(strOtherAccount, 65536)); - - if (!ser_action.ForRead()) - { - WriteOrderPos(nOrderPos, mapValue); - - if (!(mapValue.empty() && _ssExtra.empty())) - { - CDataStream ss(nType, nVersion); - ss.insert(ss.begin(), '\0'); - ss << mapValue; - ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end()); - strComment.append(ss.str()); - } - } - - READWRITE(LIMITED_STRING(strComment, 65536)); - - size_t nSepPos = strComment.find("\0", 0, 1); - if (ser_action.ForRead()) - { - mapValue.clear(); - if (std::string::npos != nSepPos) - { - CDataStream ss(std::vector(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion); - ss >> mapValue; - _ssExtra = std::vector(ss.begin(), ss.end()); - } - ReadOrderPos(nOrderPos, mapValue); - } - if (std::string::npos != nSepPos) - strComment.erase(nSepPos); - - mapValue.erase("n"); - } - -private: - std::vector _ssExtra; -}; - #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index 5482348e3..5e144eabe 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -71,6 +71,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) } break; } + case TX_MULTISIG: { // Only consider transactions "mine" if we own ALL the diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index ec6c55ee3..4bf191380 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -106,7 +106,7 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, } bool CWalletDB::WriteCryptedZKey(const libzcash::PaymentAddress & addr, - const libzcash::ViewingKey &vk, + const libzcash::ReceivingKey &rk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta) { @@ -116,7 +116,7 @@ bool CWalletDB::WriteCryptedZKey(const libzcash::PaymentAddress & addr, if (!Write(std::make_pair(std::string("zkeymeta"), addr), keyMeta)) return false; - if (!Write(std::make_pair(std::string("czkey"), addr), std::make_pair(vk, vchCryptedSecret), false)) + if (!Write(std::make_pair(std::string("czkey"), addr), std::make_pair(rk, vchCryptedSecret), false)) return false; if (fEraseUnencryptedKey) { @@ -142,6 +142,18 @@ bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash:: return Write(std::make_pair(std::string("zkey"), addr), key, false); } +bool CWalletDB::WriteViewingKey(const libzcash::ViewingKey &vk) +{ + nWalletDBUpdated++; + return Write(std::make_pair(std::string("vkey"), vk), '1'); +} + +bool CWalletDB::EraseViewingKey(const libzcash::ViewingKey &vk) +{ + nWalletDBUpdated++; + return Erase(std::make_pair(std::string("vkey"), vk)); +} + bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript) { nWalletDBUpdated++; @@ -471,6 +483,19 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, // so set the wallet birthday to the beginning of time. pwallet->nTimeFirstKey = 1; } + else if (strType == "vkey") + { + libzcash::ViewingKey vk; + ssKey >> vk; + char fYes; + ssValue >> fYes; + if (fYes == '1') + pwallet->LoadViewingKey(vk); + + // Viewing keys have no birthday information for now, + // so set the wallet birthday to the beginning of time. + pwallet->nTimeFirstKey = 1; + } else if (strType == "zkey") { libzcash::PaymentAddress addr; @@ -585,14 +610,14 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, libzcash::PaymentAddress addr; ssKey >> addr; // Deserialization of a pair is just one item after another - uint256 vkValue; - ssValue >> vkValue; - libzcash::ViewingKey vk(vkValue); + uint256 rkValue; + ssValue >> rkValue; + libzcash::ReceivingKey rk(rkValue); vector vchCryptedSecret; ssValue >> vchCryptedSecret; wss.nCKeys++; - if (!pwallet->LoadCryptedZKey(addr, vk, vchCryptedSecret)) + if (!pwallet->LoadCryptedZKey(addr, rk, vchCryptedSecret)) { strErr = "Error reading wallet database: LoadCryptedZKey failed"; return false; @@ -694,6 +719,7 @@ static bool IsKeyType(string strType) { return (strType== "key" || strType == "wkey" || strType == "zkey" || strType == "czkey" || + strType == "vkey" || strType == "mkey" || strType == "ckey"); } @@ -968,11 +994,7 @@ bool BackupWallet(const CWallet& wallet, const string& strDest) pathDest /= wallet.strWalletFile; try { -#if BOOST_VERSION >= 104000 boost::filesystem::copy_file(pathSrc, pathDest, boost::filesystem::copy_option::overwrite_if_exists); -#else - boost::filesystem::copy_file(pathSrc, pathDest); -#endif LogPrintf("copied wallet.dat to %s\n", pathDest.string()); return true; } catch (const boost::filesystem::filesystem_error& e) { diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index f9f71e00c..e455ad953 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -136,10 +136,13 @@ public: /// Write spending key to wallet database, where key is payment address and value is spending key. bool WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta); bool WriteCryptedZKey(const libzcash::PaymentAddress & addr, - const libzcash::ViewingKey & vk, + const libzcash::ReceivingKey & rk, const std::vector& vchCryptedSecret, const CKeyMetadata &keyMeta); + bool WriteViewingKey(const libzcash::ViewingKey &vk); + bool EraseViewingKey(const libzcash::ViewingKey &vk); + private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index 3849b2ffc..baefeae4e 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -12,12 +12,20 @@ uint256 PaymentAddress::GetHash() const { return Hash(ss.begin(), ss.end()); } -uint256 ViewingKey::pk_enc() { +uint256 ReceivingKey::pk_enc() const { return ZCNoteEncryption::generate_pubkey(*this); } +PaymentAddress ViewingKey::address() const { + return PaymentAddress(a_pk, sk_enc.pk_enc()); +} + +ReceivingKey SpendingKey::receiving_key() const { + return ReceivingKey(ZCNoteEncryption::generate_privkey(*this)); +} + ViewingKey SpendingKey::viewing_key() const { - return ViewingKey(ZCNoteEncryption::generate_privkey(*this)); + return ViewingKey(PRF_addr_a_pk(*this), receiving_key()); } SpendingKey SpendingKey::random() { @@ -25,7 +33,7 @@ SpendingKey SpendingKey::random() { } PaymentAddress SpendingKey::address() const { - return PaymentAddress(PRF_addr_a_pk(*this), viewing_key().pk_enc()); + return viewing_key().address(); } } diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index efae2af22..2dbe10a60 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -1,5 +1,5 @@ -#ifndef _ZCADDRESS_H_ -#define _ZCADDRESS_H_ +#ifndef ZC_ADDRESS_H_ +#define ZC_ADDRESS_H_ #include "uint256.h" #include "uint252.h" @@ -8,6 +8,7 @@ namespace libzcash { const size_t SerializedPaymentAddressSize = 64; +const size_t SerializedViewingKeySize = 64; const size_t SerializedSpendingKeySize = 32; class PaymentAddress { @@ -38,11 +39,39 @@ public: } }; -class ViewingKey : public uint256 { +class ReceivingKey : public uint256 { public: - ViewingKey(uint256 sk_enc) : uint256(sk_enc) { } + ReceivingKey() { } + ReceivingKey(uint256 sk_enc) : uint256(sk_enc) { } - uint256 pk_enc(); + uint256 pk_enc() const; +}; + +class ViewingKey { +public: + uint256 a_pk; + ReceivingKey sk_enc; + + ViewingKey() : a_pk(), sk_enc() { } + ViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(a_pk); + READWRITE(sk_enc); + } + + PaymentAddress address() const; + + friend inline bool operator==(const ViewingKey& a, const ViewingKey& b) { + return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc; + } + friend inline bool operator<(const ViewingKey& a, const ViewingKey& b) { + return (a.a_pk < b.a_pk || + (a.a_pk == b.a_pk && a.sk_enc < b.sk_enc)); + } }; class SpendingKey : public uint252 { @@ -52,10 +81,11 @@ public: static SpendingKey random(); + ReceivingKey receiving_key() const; ViewingKey viewing_key() const; PaymentAddress address() const; }; } -#endif // _ZCADDRESS_H_ +#endif // ZC_ADDRESS_H_ diff --git a/src/zcash/CreateJoinSplit.cpp b/src/zcash/CreateJoinSplit.cpp index 9c7760e4f..8f651f910 100644 --- a/src/zcash/CreateJoinSplit.cpp +++ b/src/zcash/CreateJoinSplit.cpp @@ -5,6 +5,7 @@ #include "../util.h" #include "primitives/transaction.h" #include "zcash/JoinSplit.hpp" + #include "libsnark/common/profiling.hpp" #include "komodo_defs.h" char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; @@ -17,10 +18,8 @@ int main(int argc, char **argv) { libsnark::start_profiling(); - auto p = ZCJoinSplit::Unopened(); - p->loadVerifyingKey((ZC_GetParamsDir() / "sprout-verifying.key").string()); - p->setProvingKeyPath((ZC_GetParamsDir() / "sprout-proving.key").string()); - p->loadProvingKey(); + auto p = ZCJoinSplit::Prepared((ZC_GetParamsDir() / "sprout-verifying.key").string(), + (ZC_GetParamsDir() / "sprout-proving.key").string()); // construct a proof. @@ -36,4 +35,6 @@ int main(int argc, char **argv) 0, 0); } + + delete p; // not that it matters } diff --git a/src/zcash/GenerateParams.cpp b/src/zcash/GenerateParams.cpp index e1557bea6..94f1c73c1 100644 --- a/src/zcash/GenerateParams.cpp +++ b/src/zcash/GenerateParams.cpp @@ -20,13 +20,7 @@ int main(int argc, char **argv) std::string vkFile = argv[2]; std::string r1csFile = argv[3]; - auto p = ZCJoinSplit::Generate(); - - p->saveProvingKey(pkFile); - p->saveVerifyingKey(vkFile); - p->saveR1CS(r1csFile); - - delete p; + ZCJoinSplit::Generate(r1csFile, vkFile, pkFile); return 0; } diff --git a/src/zcash/IncrementalMerkleTree.hpp b/src/zcash/IncrementalMerkleTree.hpp index 67b356318..151a395c1 100644 --- a/src/zcash/IncrementalMerkleTree.hpp +++ b/src/zcash/IncrementalMerkleTree.hpp @@ -1,5 +1,5 @@ -#ifndef ZCINCREMENTALMERKLETREE_H_ -#define ZCINCREMENTALMERKLETREE_H_ +#ifndef ZC_INCREMENTALMERKLETREE_H_ +#define ZC_INCREMENTALMERKLETREE_H_ #include #include @@ -202,5 +202,4 @@ typedef libzcash::IncrementalMerkleTree ZCIncrementalWitness; typedef libzcash::IncrementalWitness ZCTestingIncrementalWitness; -#endif /* ZCINCREMENTALMERKLETREE_H_ */ - +#endif /* ZC_INCREMENTALMERKLETREE_H_ */ diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 590700cd9..2685569d3 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -10,11 +10,11 @@ #include #include #include -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" -#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp" -#include "libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp" - +#include +#include +#include +#include +#include "tinyformat.h" #include "sync.h" #include "amount.h" @@ -28,7 +28,7 @@ CCriticalSection cs_ParamsIO; CCriticalSection cs_LoadKeys; template -void saveToFile(std::string path, T& obj) { +void saveToFile(const std::string path, T& obj) { LOCK(cs_ParamsIO); std::stringstream ss; @@ -42,14 +42,14 @@ void saveToFile(std::string path, T& obj) { } template -void loadFromFile(std::string path, boost::optional& objIn) { +void loadFromFile(const std::string path, T& objIn) { LOCK(cs_ParamsIO); std::stringstream ss; std::ifstream fh(path, std::ios::binary); if(!fh.is_open()) { - throw std::runtime_error((boost::format("could not load param file at %s") % path).str()); + throw std::runtime_error(strprintf("could not load param file at %s", path)); } ss << fh.rdbuf(); @@ -69,77 +69,33 @@ public: typedef default_r1cs_ppzksnark_pp ppzksnark_ppT; typedef Fr FieldT; - boost::optional> pk; - boost::optional> vk; - boost::optional> vk_precomp; - boost::optional pkPath; + r1cs_ppzksnark_verification_key vk; + r1cs_ppzksnark_processed_verification_key vk_precomp; + std::string pkPath; - JoinSplitCircuit() {} + JoinSplitCircuit(const std::string vkPath, const std::string pkPath) : pkPath(pkPath) { + loadFromFile(vkPath, vk); + vk_precomp = r1cs_ppzksnark_verifier_process_vk(vk); + } ~JoinSplitCircuit() {} - void setProvingKeyPath(std::string path) { - pkPath = path; - } - - void loadProvingKey() { - LOCK(cs_LoadKeys); - - if (!pk) { - if (!pkPath) { - throw std::runtime_error("proving key path unknown"); - } - loadFromFile(*pkPath, pk); - } - } - - void saveProvingKey(std::string path) { - if (pk) { - saveToFile(path, *pk); - } else { - throw std::runtime_error("cannot save proving key; key doesn't exist"); - } - } - void loadVerifyingKey(std::string path) { - LOCK(cs_LoadKeys); - - loadFromFile(path, vk); - - processVerifyingKey(); - } - void processVerifyingKey() { - vk_precomp = r1cs_ppzksnark_verifier_process_vk(*vk); - } - void saveVerifyingKey(std::string path) { - if (vk) { - saveToFile(path, *vk); - } else { - throw std::runtime_error("cannot save verifying key; key doesn't exist"); - } - } - void saveR1CS(std::string path) { - auto r1cs = generate_r1cs(); - - saveToFile(path, r1cs); - } - - r1cs_constraint_system generate_r1cs() { + static void generate(const std::string r1csPath, + const std::string vkPath, + const std::string pkPath) + { protoboard pb; joinsplit_gadget g(pb); g.generate_r1cs_constraints(); - return pb.get_constraint_system(); - } + auto r1cs = pb.get_constraint_system(); - void generate() { - LOCK(cs_LoadKeys); + saveToFile(r1csPath, r1cs); - const r1cs_constraint_system constraint_system = generate_r1cs(); - r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(constraint_system); + r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(r1cs); - pk = keypair.pk; - vk = keypair.vk; - processVerifyingKey(); + saveToFile(vkPath, keypair.vk); + saveToFile(pkPath, keypair.pk); } bool verify( @@ -154,10 +110,6 @@ public: uint64_t vpub_new, const uint256& rt ) { - if (!vk || !vk_precomp) { - throw std::runtime_error("JoinSplit verifying key not loaded"); - } - try { auto r1cs_proof = proof.to_libsnark_proof>(); @@ -174,8 +126,8 @@ public: ); return verifier.check( - *vk, - *vk_precomp, + vk, + vk_precomp, witness, r1cs_proof ); @@ -198,12 +150,9 @@ public: uint64_t vpub_old, uint64_t vpub_new, const uint256& rt, - bool computeProof + bool computeProof, + uint256 *out_esk // Payment disclosure ) { - if (computeProof && !pk) { - throw std::runtime_error("JoinSplit proving key not loaded"); - } - if (vpub_old > MAX_MONEY) { throw std::invalid_argument("nonsensical vpub_old value"); } @@ -303,6 +252,12 @@ public: } out_ephemeralKey = encryptor.get_epk(); + + // !!! Payment disclosure START + if (out_esk != nullptr) { + *out_esk = encryptor.get_esk(); + } + // !!! Payment disclosure END } // Authenticate h_sig with each of the input @@ -345,8 +300,14 @@ public: // estimate that it doesn't matter if we check every time. pb.constraint_system.swap_AB_if_beneficial(); - return ZCProof(r1cs_ppzksnark_prover( - *pk, + std::ifstream fh(pkPath, std::ios::binary); + + if(!fh.is_open()) { + throw std::runtime_error(strprintf("could not load param file at %s", pkPath)); + } + + return ZCProof(r1cs_ppzksnark_prover_streaming( + fh, primary_input, aux_input, pb.constraint_system @@ -355,20 +316,20 @@ public: }; template -JoinSplit* JoinSplit::Generate() +void JoinSplit::Generate(const std::string r1csPath, + const std::string vkPath, + const std::string pkPath) { initialize_curve_params(); - auto js = new JoinSplitCircuit(); - js->generate(); - - return js; + JoinSplitCircuit::generate(r1csPath, vkPath, pkPath); } template -JoinSplit* JoinSplit::Unopened() +JoinSplit* JoinSplit::Prepared(const std::string vkPath, + const std::string pkPath) { initialize_curve_params(); - return new JoinSplitCircuit(); + return new JoinSplitCircuit(vkPath, pkPath); } template diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index a8c08d21b..6a2d4e1f2 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -1,5 +1,5 @@ -#ifndef _ZCJOINSPLIT_H_ -#define _ZCJOINSPLIT_H_ +#ifndef ZC_JOINSPLIT_H_ +#define ZC_JOINSPLIT_H_ #include "Zcash.h" #include "Proof.hpp" @@ -48,22 +48,17 @@ class JoinSplit { public: virtual ~JoinSplit() {} - static JoinSplit* Generate(); - static JoinSplit* Unopened(); + static void Generate(const std::string r1csPath, + const std::string vkPath, + const std::string pkPath); + static JoinSplit* Prepared(const std::string vkPath, + const std::string pkPath); + static uint256 h_sig(const uint256& randomSeed, const boost::array& nullifiers, const uint256& pubKeyHash ); - // TODO: #789 - virtual void setProvingKeyPath(std::string) = 0; - virtual void loadProvingKey() = 0; - - virtual void saveProvingKey(std::string path) = 0; - virtual void loadVerifyingKey(std::string path) = 0; - virtual void saveVerifyingKey(std::string path) = 0; - virtual void saveR1CS(std::string path) = 0; - virtual ZCProof prove( const boost::array& inputs, const boost::array& outputs, @@ -78,7 +73,11 @@ public: uint64_t vpub_old, uint64_t vpub_new, const uint256& rt, - bool computeProof = true + bool computeProof = true, + // For paymentdisclosure, we need to retrieve the esk. + // Reference as non-const parameter with default value leads to compile error. + // So use pointer for simplicity. + uint256 *out_esk = nullptr ) = 0; virtual bool verify( @@ -103,4 +102,4 @@ protected: typedef libzcash::JoinSplit ZCJoinSplit; -#endif // _ZCJOINSPLIT_H_ +#endif // ZC_JOINSPLIT_H_ diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 460e68f9d..faacd2720 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -1,5 +1,5 @@ -#ifndef _ZCNOTE_H_ -#define _ZCNOTE_H_ +#ifndef ZC_NOTE_H_ +#define ZC_NOTE_H_ #include "uint256.h" #include "Zcash.h" @@ -68,4 +68,4 @@ public: } -#endif // _ZCNOTE_H_ \ No newline at end of file +#endif // ZC_NOTE_H_ diff --git a/src/zcash/NoteEncryption.cpp b/src/zcash/NoteEncryption.cpp index a5ea2da15..9ae0ba5c3 100644 --- a/src/zcash/NoteEncryption.cpp +++ b/src/zcash/NoteEncryption.cpp @@ -135,6 +135,52 @@ typename NoteDecryption::Plaintext NoteDecryption::decrypt return plaintext; } +// +// Payment disclosure - decrypt with esk +// +template +typename PaymentDisclosureNoteDecryption::Plaintext PaymentDisclosureNoteDecryption::decryptWithEsk + (const PaymentDisclosureNoteDecryption::Ciphertext &ciphertext, + const uint256 &pk_enc, + const uint256 &esk, + const uint256 &hSig, + unsigned char nonce + ) const +{ + uint256 dhsecret; + + if (crypto_scalarmult(dhsecret.begin(), esk.begin(), pk_enc.begin()) != 0) { + throw std::logic_error("Could not create DH secret"); + } + + // Regenerate keypair + uint256 epk = NoteEncryption::generate_pubkey(esk); + + unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE]; + KDF(K, dhsecret, epk, pk_enc, hSig, nonce); + + // The nonce is zero because we never reuse keys + unsigned char cipher_nonce[crypto_aead_chacha20poly1305_IETF_NPUBBYTES] = {}; + + PaymentDisclosureNoteDecryption::Plaintext plaintext; + + // Message length is always NOTEENCRYPTION_AUTH_BYTES less than + // the ciphertext length. + if (crypto_aead_chacha20poly1305_ietf_decrypt(plaintext.begin(), NULL, + NULL, + ciphertext.begin(), PaymentDisclosureNoteDecryption::CLEN, + NULL, + 0, + cipher_nonce, K) != 0) { + throw note_decryption_failed(); + } + + return plaintext; +} + + + + template uint256 NoteEncryption::generate_privkey(const uint252 &a_sk) { @@ -176,4 +222,6 @@ uint252 random_uint252() template class NoteEncryption; template class NoteDecryption; +template class PaymentDisclosureNoteDecryption; + } diff --git a/src/zcash/NoteEncryption.hpp b/src/zcash/NoteEncryption.hpp index 11346ebc1..321d7dead 100644 --- a/src/zcash/NoteEncryption.hpp +++ b/src/zcash/NoteEncryption.hpp @@ -31,6 +31,11 @@ public: NoteEncryption(uint256 hSig); + // Gets the ephemeral secret key + uint256 get_esk() { + return esk; + } + // Gets the ephemeral public key uint256 get_epk() { return epk; @@ -87,9 +92,34 @@ public: note_decryption_failed() : std::runtime_error("Could not decrypt message") { } }; + + +// Subclass PaymentDisclosureNoteDecryption provides a method to decrypt a note with esk. +template +class PaymentDisclosureNoteDecryption : public NoteDecryption { +protected: +public: + enum { CLEN=MLEN+NOTEENCRYPTION_AUTH_BYTES }; + typedef boost::array Ciphertext; + typedef boost::array Plaintext; + + PaymentDisclosureNoteDecryption() : NoteDecryption() {} + PaymentDisclosureNoteDecryption(uint256 sk_enc) : NoteDecryption(sk_enc) {} + + Plaintext decryptWithEsk( + const Ciphertext &ciphertext, + const uint256 &pk_enc, + const uint256 &esk, + const uint256 &hSig, + unsigned char nonce + ) const; +}; + } typedef libzcash::NoteEncryption ZCNoteEncryption; typedef libzcash::NoteDecryption ZCNoteDecryption; +typedef libzcash::PaymentDisclosureNoteDecryption ZCPaymentDisclosureNoteDecryption; + #endif /* ZC_NOTE_ENCRYPTION_H_ */ diff --git a/src/zcash/Proof.cpp b/src/zcash/Proof.cpp index 1b2199407..e7264e684 100644 --- a/src/zcash/Proof.cpp +++ b/src/zcash/Proof.cpp @@ -1,11 +1,11 @@ #include "Proof.hpp" -#include -#include - #include "crypto/common.h" -#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp" -#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp" + +#include +#include +#include +#include using namespace libsnark; diff --git a/src/zcash/Proof.hpp b/src/zcash/Proof.hpp index 3b6b5e568..5f05aa2c5 100644 --- a/src/zcash/Proof.hpp +++ b/src/zcash/Proof.hpp @@ -1,5 +1,5 @@ -#ifndef _ZCPROOF_H_ -#define _ZCPROOF_H_ +#ifndef ZC_PROOF_H_ +#define ZC_PROOF_H_ #include "serialize.h" #include "uint256.h" @@ -274,4 +274,4 @@ public: } -#endif // _ZCPROOF_H_ +#endif // ZC_PROOF_H_ diff --git a/src/zcash/Zcash.h b/src/zcash/Zcash.h index c2dfe548b..9e6684475 100644 --- a/src/zcash/Zcash.h +++ b/src/zcash/Zcash.h @@ -1,5 +1,5 @@ -#ifndef _ZCCONSTANTS_H_ -#define _ZCCONSTANTS_H_ +#ifndef ZC_ZCASH_H_ +#define ZC_ZCASH_H_ #define ZC_NUM_JS_INPUTS 2 #define ZC_NUM_JS_OUTPUTS 2 @@ -14,4 +14,4 @@ #define ZC_NOTEPLAINTEXT_SIZE (ZC_NOTEPLAINTEXT_LEADING + ZC_V_SIZE + ZC_RHO_SIZE + ZC_R_SIZE + ZC_MEMO_SIZE) -#endif // _ZCCONSTANTS_H_ +#endif // ZC_ZCASH_H_ diff --git a/src/zcash/prf.h b/src/zcash/prf.h index c6cb45384..dec934f4a 100644 --- a/src/zcash/prf.h +++ b/src/zcash/prf.h @@ -3,8 +3,8 @@ Zcash uses SHA256Compress as a PRF for various components within the zkSNARK circuit. */ -#ifndef _PRF_H_ -#define _PRF_H_ +#ifndef ZC_PRF_H_ +#define ZC_PRF_H_ #include "uint256.h" #include "uint252.h" @@ -15,4 +15,4 @@ uint256 PRF_nf(const uint252& a_sk, const uint256& rho); uint256 PRF_pk(const uint252& a_sk, size_t i0, const uint256& h_sig); uint256 PRF_rho(const uint252& phi, size_t i0, const uint256& h_sig); -#endif // _PRF_H_ +#endif // ZC_PRF_H_ diff --git a/src/zcash/util.h b/src/zcash/util.h index bbfeac1c3..10886e3ca 100644 --- a/src/zcash/util.h +++ b/src/zcash/util.h @@ -1,5 +1,5 @@ -#ifndef __ZCASH_UTIL_H -#define __ZCASH_UTIL_H +#ifndef ZC_UTIL_H_ +#define ZC_UTIL_H_ #include #include @@ -8,4 +8,4 @@ std::vector convertIntToVectorLE(const uint64_t val_int); std::vector convertBytesVectorToVector(const std::vector& bytes); uint64_t convertVectorToInt(const std::vector& v); -#endif // __ZCASH_UTIL_H +#endif // ZC_UTIL_H_ diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 14eabebff..2c7e99a67 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include #include #include @@ -9,14 +11,18 @@ #include "primitives/transaction.h" #include "base58.h" #include "crypto/equihash.h" +#include "chain.h" #include "chainparams.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "main.h" #include "miner.h" #include "pow.h" +#include "rpcserver.h" #include "script/sign.h" #include "sodium.h" #include "streams.h" +#include "txdb.h" #include "utiltest.h" #include "wallet/wallet.h" @@ -26,6 +32,39 @@ #include "zcash/IncrementalMerkleTree.hpp" using namespace libzcash; +// This method is based on Shutdown from init.cpp +void pre_wallet_load() +{ + LogPrintf("%s: In progress...\n", __func__); + if (ShutdownRequested()) + throw new std::runtime_error("The node is shutting down"); + + if (pwalletMain) + pwalletMain->Flush(false); +#ifdef ENABLE_MINING + GenerateBitcoins(false, NULL, 0); +#endif + UnregisterNodeSignals(GetNodeSignals()); + if (pwalletMain) + pwalletMain->Flush(true); + + UnregisterValidationInterface(pwalletMain); + delete pwalletMain; + pwalletMain = NULL; + bitdb.Reset(); + RegisterNodeSignals(GetNodeSignals()); + LogPrintf("%s: done\n", __func__); +} + +void post_wallet_load(){ + RegisterValidationInterface(pwalletMain); +#ifdef ENABLE_MINING + // Generate coins in the background + if (pwalletMain || !GetArg("-mineraddress", "").empty()) + GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); +#endif +} + void timer_start(timeval &tv_start) { @@ -59,11 +98,7 @@ double benchmark_parameter_loading() struct timeval tv_start; timer_start(tv_start); - auto newParams = ZCJoinSplit::Unopened(); - - newParams->loadVerifyingKey(vk_path.string()); - newParams->setProvingKeyPath(pk_path.string()); - newParams->loadProvingKey(); + auto newParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string()); double ret = timer_stop(tv_start); @@ -187,11 +222,8 @@ double benchmark_verify_equihash() return timer_stop(tv_start); } -double benchmark_large_tx() +double benchmark_large_tx(size_t nInputs) { - // Number of inputs in the spending transaction that we will simulate - const size_t NUM_INPUTS = 555; - // Create priv/pub key CKey priv; priv.MakeNewKey(false); @@ -210,26 +242,20 @@ double benchmark_large_tx() auto orig_tx = CTransaction(m_orig_tx); CMutableTransaction spending_tx; + spending_tx.fOverwintered = true; + spending_tx.nVersion = 3; + spending_tx.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID; + auto input_hash = orig_tx.GetHash(); - // Add NUM_INPUTS inputs - for (size_t i = 0; i < NUM_INPUTS; i++) { + // Add nInputs inputs + for (size_t i = 0; i < nInputs; i++) { spending_tx.vin.emplace_back(input_hash, 0); } // Sign for all the inputs - for (size_t i = 0; i < NUM_INPUTS; i++) { - SignSignature(tempKeystore, prevPubKey, spending_tx, i, SIGHASH_ALL); - } - - // Serialize: - { - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << spending_tx; - //std::cout << "SIZE OF SPENDING TX: " << ss.size() << std::endl; - - auto error = MAX_TX_SIZE / 20; // 5% error - assert(ss.size() < MAX_TX_SIZE + error); - assert(ss.size() > MAX_TX_SIZE - error); + auto consensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_OVERWINTER].nBranchId; + for (size_t i = 0; i < nInputs; i++) { + SignSignature(tempKeystore, prevPubKey, spending_tx, i, 1000000, SIGHASH_ALL, consensusBranchId); } // Spending tx has all its inputs signed and does not need to be mutated anymore @@ -238,12 +264,14 @@ double benchmark_large_tx() // Benchmark signature verification costs: struct timeval tv_start; timer_start(tv_start); - for (size_t i = 0; i < NUM_INPUTS; i++) { + PrecomputedTransactionData txdata(final_spending_tx); + for (size_t i = 0; i < nInputs; i++) { ScriptError serror = SCRIPT_ERR_OK; assert(VerifyScript(final_spending_tx.vin[i].scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, - TransactionSignatureChecker(&final_spending_tx, i), + TransactionSignatureChecker(&final_spending_tx, i, 1000000, txdata), + consensusBranchId, &serror)); } return timer_stop(tv_start); @@ -322,3 +350,117 @@ double benchmark_increment_note_witnesses(size_t nTxs) return timer_stop(tv_start); } +// Fake the input of a given block +class FakeCoinsViewDB : public CCoinsViewDB { + uint256 hash; + ZCIncrementalMerkleTree t; + +public: + FakeCoinsViewDB(std::string dbName, uint256& hash) : CCoinsViewDB(dbName, 100, false, false), hash(hash) {} + + bool GetAnchorAt(const uint256 &rt, ZCIncrementalMerkleTree &tree) const { + if (rt == t.root()) { + tree = t; + return true; + } + return false; + } + + bool GetNullifier(const uint256 &nf) const { + return false; + } + + uint256 GetBestBlock() const { + return hash; + } + + uint256 GetBestAnchor() const { + return t.root(); + } + + bool BatchWrite(CCoinsMap &mapCoins, + const uint256 &hashBlock, + const uint256 &hashAnchor, + CAnchorsMap &mapAnchors, + CNullifiersMap &mapNullifiers) { + return false; + } + + bool GetStats(CCoinsStats &stats) const { + return false; + } +}; + +double benchmark_connectblock_slow() +{ + // Test for issue 2017-05-01.a + SelectParams(CBaseChainParams::MAIN); + CBlock block; + FILE* fp = fopen((GetDataDir() / "benchmark/block-107134.dat").string().c_str(), "rb"); + if (!fp) throw new std::runtime_error("Failed to open block data file"); + CAutoFile blkFile(fp, SER_DISK, CLIENT_VERSION); + blkFile >> block; + blkFile.fclose(); + + // Fake its inputs + auto hashPrev = uint256S("00000000159a41f468e22135942a567781c3f3dc7ad62257993eb3c69c3f95ef"); + FakeCoinsViewDB fakeDB("benchmark/block-107134-inputs", hashPrev); + CCoinsViewCache view(&fakeDB); + + // Fake the chain + CBlockIndex index(block); + index.nHeight = 107134; + CBlockIndex indexPrev; + indexPrev.phashBlock = &hashPrev; + indexPrev.nHeight = index.nHeight - 1; + index.pprev = &indexPrev; + mapBlockIndex.insert(std::make_pair(hashPrev, &indexPrev)); + + CValidationState state; + struct timeval tv_start; + timer_start(tv_start); + assert(ConnectBlock(block, state, &index, view, true)); + auto duration = timer_stop(tv_start); + + // Undo alterations to global state + mapBlockIndex.erase(hashPrev); + SelectParamsFromCommandLine(); + + return duration; +} + +double benchmark_sendtoaddress(CAmount amount) +{ + UniValue params(UniValue::VARR); + auto addr = getnewaddress(params, false); + + params.push_back(addr); + params.push_back(ValueFromAmount(amount)); + + struct timeval tv_start; + timer_start(tv_start); + auto txid = sendtoaddress(params, false); + return timer_stop(tv_start); +} + +double benchmark_loadwallet() +{ + pre_wallet_load(); + struct timeval tv_start; + bool fFirstRunRet=true; + timer_start(tv_start); + pwalletMain = new CWallet("wallet.dat"); + DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRunRet); + auto res = timer_stop(tv_start); + post_wallet_load(); + return res; +} + +double benchmark_listunspent() +{ + UniValue params(UniValue::VARR); + struct timeval tv_start; + timer_start(tv_start); + auto unspent = listunspent(params, false); + return timer_stop(tv_start); +} diff --git a/src/zcbenchmarks.h b/src/zcbenchmarks.h index b2bc2e373..60a0be848 100644 --- a/src/zcbenchmarks.h +++ b/src/zcbenchmarks.h @@ -12,8 +12,12 @@ extern double benchmark_solve_equihash(); extern std::vector benchmark_solve_equihash_threaded(int nThreads); extern double benchmark_verify_joinsplit(const JSDescription &joinsplit); extern double benchmark_verify_equihash(); -extern double benchmark_large_tx(); +extern double benchmark_large_tx(size_t nInputs); extern double benchmark_try_decrypt_notes(size_t nAddrs); extern double benchmark_increment_note_witnesses(size_t nTxs); +extern double benchmark_connectblock_slow(); +extern double benchmark_sendtoaddress(CAmount amount); +extern double benchmark_loadwallet(); +extern double benchmark_listunspent(); #endif diff --git a/zcutil/build-debian-package.sh b/zcutil/build-debian-package.sh index 8c2d05c3f..870530083 100755 --- a/zcutil/build-debian-package.sh +++ b/zcutil/build-debian-package.sh @@ -18,6 +18,7 @@ if [ ! -d $BUILD_PATH ]; then fi PACKAGE_VERSION=$($SRC_PATH/src/zcashd --version | grep version | cut -d' ' -f4 | tr -d v) +DEBVERSION=$(echo $PACKAGE_VERSION | sed 's/-beta/~beta/' | sed 's/-rc/~rc/' | sed 's/-/+/') BUILD_DIR="$BUILD_PATH/$PACKAGE_NAME-$PACKAGE_VERSION-amd64" if [ -d $BUILD_DIR ]; then @@ -50,8 +51,8 @@ cp $SRC_DOC/man/zcashd.1 $DEB_MAN cp $SRC_DOC/man/zcash-cli.1 $DEB_MAN cp $SRC_DOC/man/zcash-fetch-params.1 $DEB_MAN # Copy bash completion files -cp $SRC_PATH/contrib/bitcoind.bash-completion $DEB_CMP/zcashd -cp $SRC_PATH/contrib/bitcoin-cli.bash-completion $DEB_CMP/zcash-cli +cp $SRC_PATH/contrib/zcashd.bash-completion $DEB_CMP/zcashd +cp $SRC_PATH/contrib/zcash-cli.bash-completion $DEB_CMP/zcash-cli # Gzip files gzip --best -n $DEB_DOC/changelog gzip --best -n $DEB_DOC/changelog.Debian @@ -63,7 +64,7 @@ cd $SRC_PATH/contrib # Create the control file dpkg-shlibdeps $DEB_BIN/zcashd $DEB_BIN/zcash-cli -dpkg-gencontrol -P$BUILD_DIR +dpkg-gencontrol -P$BUILD_DIR -v$DEBVERSION # Create the Debian package fakeroot dpkg-deb --build $BUILD_DIR diff --git a/zcutil/build.sh b/zcutil/build.sh index f789c7a8d..d40aa47a2 100755 --- a/zcutil/build.sh +++ b/zcutil/build.sh @@ -2,6 +2,22 @@ set -eu -o pipefail +function cmd_pref() { + if type -p "$2" > /dev/null; then + eval "$1=$2" + else + eval "$1=$3" + fi +} + +# If a g-prefixed version of the command exists, use it preferentially. +function gprefix() { + cmd_pref "$1" "g$2" "$2" +} + +gprefix READLINK readlink +cd "$(dirname "$("$READLINK" -f "$0")")/.." + # Allow user overrides to $MAKE. Typical usage for users who need it: # MAKE=gmake ./zcutil/build.sh -j$(nproc) if [[ -z "${MAKE-}" ]]; then @@ -11,10 +27,10 @@ fi # Allow overrides to $BUILD and $HOST for porters. Most users will not need it. # BUILD=i686-pc-linux-gnu ./zcutil/build.sh if [[ -z "${BUILD-}" ]]; then - BUILD=x86_64-unknown-linux-gnu + BUILD="$(./depends/config.guess)" fi if [[ -z "${HOST-}" ]]; then - HOST=x86_64-unknown-linux-gnu + HOST="$BUILD" fi # Allow override to $CC and $CXX for porters. Most users will not need it. @@ -25,6 +41,11 @@ if [[ -z "${CXX-}" ]]; then CXX=g++ fi +# Allow users to set arbitary compile flags. Most users will not need this. +if [[ -z "${CONFIGURE_FLAGS-}" ]]; then + CONFIGURE_FLAGS="" +fi + if [ "x$*" = 'x--help' ] then cat <>>>>>> zcash/master "$MAKE" "$@" V=1 diff --git a/zcutil/fetch-params.sh b/zcutil/fetch-params.sh index 8bb31fc35..10bade7cb 100755 --- a/zcutil/fetch-params.sh +++ b/zcutil/fetch-params.sh @@ -6,27 +6,83 @@ PARAMS_DIR="$HOME/.zcash-params" SPROUT_PKEY_NAME='sprout-proving.key' SPROUT_VKEY_NAME='sprout-verifying.key' -SPROUT_PKEY_URL="https://z.cash/downloads/$SPROUT_PKEY_NAME" -SPROUT_VKEY_URL="https://z.cash/downloads/$SPROUT_VKEY_NAME" +SPROUT_URL="https://z.cash/downloads" +SPROUT_IPFS="/ipfs/QmZKKx7Xup7LiAtFRhYsE1M7waXcv9ir9eCECyXAFGxhEo" SHA256CMD="$(command -v sha256sum || echo shasum)" SHA256ARGS="$(command -v sha256sum >/dev/null || echo '-a 256')" +WGETCMD="$(command -v wget || echo '')" +IPFSCMD="$(command -v ipfs || echo '')" + +# fetch methods can be disabled with ZC_DISABLE_SOMETHING=1 +ZC_DISABLE_WGET="${ZC_DISABLE_WGET:-}" +ZC_DISABLE_IPFS="${ZC_DISABLE_IPFS:-}" + +function fetch_wget { + if [ -z "$WGETCMD" ] || ! [ -z "$ZC_DISABLE_WGET" ]; then + return 1 + fi + + local filename="$1" + local dlname="$2" + + cat <&2 <&2 + exit 1 fi fi } @@ -100,8 +156,8 @@ EOF cd "$PARAMS_DIR" - fetch_params "$SPROUT_PKEY_URL" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7" - fetch_params "$SPROUT_VKEY_URL" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82" + fetch_params "$SPROUT_PKEY_NAME" "$PARAMS_DIR/$SPROUT_PKEY_NAME" "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7" + fetch_params "$SPROUT_VKEY_NAME" "$PARAMS_DIR/$SPROUT_VKEY_NAME" "4bd498dae0aacfd8e98dc306338d017d9c08dd0918ead18172bd0aec2fc5df82" } main diff --git a/zcutil/make-release.py b/zcutil/make-release.py new file mode 100755 index 000000000..c19544312 --- /dev/null +++ b/zcutil/make-release.py @@ -0,0 +1,668 @@ +#! /usr/bin/env python2 + +import os +import re +import sys +import logging +import argparse +import subprocess +import traceback +import unittest +import random +from cStringIO import StringIO +from functools import wraps + + +def main(args=sys.argv[1:]): + """ + Perform the final Zcash release process up to the git tag. + """ + opts = parse_args(args) + chdir_to_repo(opts.REPO) + initialize_logging() + logging.debug('argv %r', sys.argv) + + try: + main_logged( + opts.RELEASE_VERSION, + opts.RELEASE_PREV, + opts.RELEASE_FROM, + opts.RELEASE_HEIGHT, + opts.HOTFIX, + ) + except SystemExit as e: + logging.error(str(e)) + raise SystemExit(1) + except: + logging.error(traceback.format_exc()) + raise SystemExit(2) + + +def parse_args(args): + p = argparse.ArgumentParser(description=main.__doc__) + p.add_argument( + '--repo', + dest='REPO', + type=str, + help='Path to repository root.', + ) + p.add_argument( + '--hotfix', + action='store_true', + dest='HOTFIX', + help='Use if this is a hotfix release from a non-master branch.', + ) + p.add_argument( + 'RELEASE_VERSION', + type=Version.parse_arg, + help='The release version: vX.Y.Z-N', + ) + p.add_argument( + 'RELEASE_PREV', + type=Version.parse_arg, + help='The previously released version.', + ) + p.add_argument( + 'RELEASE_FROM', + type=Version.parse_arg, + help='The previously released non-beta non-RC version. May be the same as RELEASE_PREV.', + ) + p.add_argument( + 'RELEASE_HEIGHT', + type=int, + help='A block height approximately occuring on release day.', + ) + return p.parse_args(args) + + +# Top-level flow: +def main_logged(release, releaseprev, releasefrom, releaseheight, hotfix): + verify_tags(releaseprev, releasefrom) + verify_version(release, releaseprev, hotfix) + initialize_git(release, hotfix) + patch_version_in_files(release, releaseprev) + patch_release_height(releaseheight) + commit('Versioning changes for {}.'.format(release.novtext)) + + build() + gen_manpages() + commit('Updated manpages for {}.'.format(release.novtext)) + + gen_release_notes(release, releasefrom) + update_debian_changelog(release) + commit( + 'Updated release notes and changelog for {}.'.format( + release.novtext, + ), + ) + + +def phase(message): + def deco(f): + @wraps(f) + def g(*a, **kw): + logging.info('%s', message) + return f(*a, **kw) + return g + return deco + + +@phase('Checking tags.') +def verify_tags(releaseprev, releasefrom): + candidates = [] + + # Any tag beginning with a 'v' followed by [1-9] must be a version + # matching our Version parser. Tags beginning with v0 may exist from + # upstream and those do not follow our schema and are silently + # ignored. Any other tag is silently ignored. + candidatergx = re.compile('^v[1-9].*$') + + for tag in sh_out('git', 'tag', '--list').splitlines(): + if candidatergx.match(tag): + candidates.append(Version.parse_arg(tag)) + + candidates.sort() + try: + latest = candidates[-1] + except IndexError: + raise SystemExit('No previous releases found by `git tag --list`.') + + if releaseprev != latest: + raise SystemExit( + 'The latest candidate in `git tag --list` is {} not {}' + .format( + latest.vtext, + releaseprev.vtext, + ), + ) + + candidates.reverse() + prev_tags = [] + for candidate in candidates: + if releasefrom == candidate: + break + else: + prev_tags.append(candidate) + else: + raise SystemExit( + '{} does not appear in `git tag --list`' + .format( + releasefrom.vtext, + ), + ) + + for tag in prev_tags: + if not tag.betarc: + raise SystemExit( + '{} appears to be a more recent non-beta non-RC release than {}' + .format( + tag.vtext, + releasefrom.vtext, + ), + ) + + +@phase('Checking version.') +def verify_version(release, releaseprev, hotfix): + if not hotfix: + return + + expected = Version( + releaseprev.major, + releaseprev.minor, + releaseprev.patch, + releaseprev.betarc, + releaseprev.hotfix + 1 if releaseprev.hotfix else 1, + ) + if release != expected: + raise SystemExit( + "Expected {!r}, given {!r}".format( + expected, release, + ), + ) + + +@phase('Initializing git.') +def initialize_git(release, hotfix): + junk = sh_out('git', 'status', '--porcelain') + if junk.strip(): + raise SystemExit('There are uncommitted changes:\n' + junk) + + branch = sh_out('git', 'rev-parse', '--abbrev-ref', 'HEAD').strip() + if hotfix: + expected = 'hotfix-' + release.vtext + else: + expected = 'master' + if branch != expected: + raise SystemExit( + "Expected branch {!r}, found branch {!r}".format( + expected, branch, + ), + ) + + logging.info('Pulling to latest master.') + sh_log('git', 'pull', '--ff-only') + + branch = 'release-' + release.vtext + logging.info('Creating release branch: %r', branch) + sh_log('git', 'checkout', '-b', branch) + return branch + + +@phase('Patching versioning in files.') +def patch_version_in_files(release, releaseprev): + patch_README(release, releaseprev) + patch_clientversion_h(release) + patch_configure_ac(release) + patch_gitian_linux_yml(release, releaseprev) + + +@phase('Patching release height for auto-senescence.') +def patch_release_height(releaseheight): + rgx = re.compile( + r'^(static const int APPROX_RELEASE_HEIGHT = )\d+(;)$', + ) + with PathPatcher('src/deprecation.h') as (inf, outf): + for line in inf: + m = rgx.match(line) + if m is None: + outf.write(line) + else: + [prefix, suffix] = m.groups() + outf.write( + '{}{}{}\n'.format( + prefix, + releaseheight, + suffix, + ), + ) + + +@phase('Building...') +def build(): + base_dir = os.getcwd() + depends_dir = os.path.join(base_dir, 'depends') + src_dir = os.path.join(base_dir, 'src') + nproc = sh_out('nproc').strip() + sh_progress([ + 'Staging boost...', + 'Staging libevent...', + 'Staging zeromq...', + 'Staging libgmp...', + 'Staging libsodium...', + "Leaving directory '%s'" % depends_dir, + 'config.status: creating libzcashconsensus.pc', + "Entering directory '%s'" % src_dir, + 'httpserver.cpp', + 'torcontrol.cpp', + 'gtest/test_tautology.cpp', + 'gtest/test_metrics.cpp', + 'test/equihash_tests.cpp', + 'test/util_tests.cpp', + "Leaving directory '%s'" % src_dir, + ], './zcutil/build.sh', '-j', nproc) + + +@phase('Generating manpages.') +def gen_manpages(): + sh_log('./contrib/devtools/gen-manpages.sh') + + +@phase('Generating release notes.') +def gen_release_notes(release, releasefrom): + release_notes = [ + 'python', + './zcutil/release-notes.py', + '--version', + release.novtext, + '--prev', + releasefrom.vtext, + ] + if not release.betarc: + release_notes.append('--clear') + sh_log(*release_notes) + sh_log( + 'git', + 'add', + './doc/authors.md', + './doc/release-notes/release-notes-{}.md'.format(release.novtext), + ) + + +@phase('Updating debian changelog.') +def update_debian_changelog(release): + os.environ['DEBEMAIL'] = 'team@z.cash' + os.environ['DEBFULLNAME'] = 'Zcash Company' + sh_log( + 'debchange', + '--newversion', release.debversion, + '--distribution', 'stable', + '--changelog', './contrib/debian/changelog', + '{} release.'.format(release.novtext), + ) + + +# Helper code: +def commit(message): + logging.info('Committing: %r', message) + fullmsg = 'make-release.py: {}'.format(message) + sh_log('git', 'commit', '--all', '-m', fullmsg) + + +def chdir_to_repo(repo): + if repo is None: + dn = os.path.dirname + repo = dn(dn(os.path.abspath(sys.argv[0]))) + os.chdir(repo) + + +def patch_README(release, releaseprev): + with PathPatcher('README.md') as (inf, outf): + firstline = inf.readline() + assert firstline == 'Zcash {}\n'.format(releaseprev.novtext), \ + repr(firstline) + + outf.write('Zcash {}\n'.format(release.novtext)) + outf.write(inf.read()) + + +def patch_clientversion_h(release): + _patch_build_defs( + release, + 'src/clientversion.h', + (r'^(#define CLIENT_VERSION_(MAJOR|MINOR|REVISION|BUILD|IS_RELEASE))' + r' \d+()$'), + ) + + +def patch_configure_ac(release): + _patch_build_defs( + release, + 'configure.ac', + (r'^(define\(_CLIENT_VERSION_(MAJOR|MINOR|REVISION|BUILD|IS_RELEASE),)' + r' \d+(\))$'), + ) + + +def patch_gitian_linux_yml(release, releaseprev): + path = 'contrib/gitian-descriptors/gitian-linux.yml' + with PathPatcher(path) as (inf, outf): + outf.write(inf.readline()) + + secondline = inf.readline() + assert secondline == 'name: "zcash-{}"\n'.format( + releaseprev.novtext + ), repr(secondline) + + outf.write('name: "zcash-{}"\n'.format(release.novtext)) + outf.write(inf.read()) + + +def _patch_build_defs(release, path, pattern): + rgx = re.compile(pattern) + with PathPatcher(path) as (inf, outf): + for line in inf: + m = rgx.match(line) + if m: + prefix, label, suffix = m.groups() + repl = { + 'MAJOR': release.major, + 'MINOR': release.minor, + 'REVISION': release.patch, + 'BUILD': release.build, + 'IS_RELEASE': ( + 'false' if release.build < 50 else 'true' + ), + }[label] + outf.write('{} {}{}\n'.format(prefix, repl, suffix)) + else: + outf.write(line) + + +def initialize_logging(): + logname = './zcash-make-release.log' + fmtr = logging.Formatter( + '%(asctime)s L%(lineno)-4d %(levelname)-5s | %(message)s', + '%Y-%m-%d %H:%M:%S' + ) + + hout = logging.StreamHandler(sys.stdout) + hout.setLevel(logging.INFO) + hout.setFormatter(fmtr) + + hpath = logging.FileHandler(logname, mode='a') + hpath.setLevel(logging.DEBUG) + hpath.setFormatter(fmtr) + + root = logging.getLogger() + root.setLevel(logging.DEBUG) + root.addHandler(hout) + root.addHandler(hpath) + logging.info('zcash make-release.py debug log: %r', logname) + + +def sh_out(*args): + logging.debug('Run (out): %r', args) + return subprocess.check_output(args) + + +def sh_log(*args): + PIPE = subprocess.PIPE + STDOUT = subprocess.STDOUT + try: + p = subprocess.Popen(args, stdout=PIPE, stderr=STDOUT, stdin=None) + except OSError: + logging.error('Error launching %r...', args) + raise + + logging.debug('Run (log PID %r): %r', p.pid, args) + for line in p.stdout: + logging.debug('> %s', line.rstrip()) + status = p.wait() + if status != 0: + raise SystemExit('Nonzero exit status: {!r}'.format(status)) + + +def sh_progress(markers, *args): + try: + import progressbar + except: + sh_log(*args) + return + + PIPE = subprocess.PIPE + STDOUT = subprocess.STDOUT + try: + p = subprocess.Popen(args, stdout=PIPE, stderr=STDOUT, stdin=None) + except OSError: + logging.error('Error launching %r...', args) + raise + + pbar = progressbar.ProgressBar(max_value=len(markers)) + marker = 0 + pbar.update(marker) + logging.debug('Run (log PID %r): %r', p.pid, args) + for line in p.stdout: + logging.debug('> %s', line.rstrip()) + for idx, val in enumerate(markers[marker:]): + if val in line: + marker += idx + 1 + pbar.update(marker) + break + pbar.finish() + status = p.wait() + if status != 0: + raise SystemExit('Nonzero exit status: {!r}'.format(status)) + + +class Version (object): + '''A release version.''' + + RGX = re.compile( + r'^v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-(beta|rc)?([1-9]\d*))?$', + ) + + @staticmethod + def parse_arg(text): + m = Version.RGX.match(text) + if m is None: + raise argparse.ArgumentTypeError( + 'Could not parse version {!r} against regex {}'.format( + text, + Version.RGX.pattern, + ), + ) + else: + [major, minor, patch, _, betarc, hotfix] = m.groups() + return Version( + int(major), + int(minor), + int(patch), + betarc, + int(hotfix) if hotfix is not None else None, + ) + + def __init__(self, major, minor, patch, betarc, hotfix): + for i in [major, minor, patch]: + assert type(i) is int, i + assert betarc in {None, 'rc', 'beta'}, betarc + assert hotfix is None or type(hotfix) is int, hotfix + if betarc is not None: + assert hotfix is not None, (betarc, hotfix) + + self.major = major + self.minor = minor + self.patch = patch + self.betarc = betarc + self.hotfix = hotfix + + if hotfix is None: + self.build = 50 + else: + assert hotfix > 0, hotfix + if betarc is None: + assert hotfix < 50, hotfix + self.build = 50 + hotfix + else: + assert hotfix < 26, hotfix + self.build = {'beta': 0, 'rc': 25}[betarc] + hotfix - 1 + + @property + def novtext(self): + return self._novtext(debian=False) + + @property + def vtext(self): + return 'v' + self.novtext + + @property + def debversion(self): + return self._novtext(debian=True) + + def _novtext(self, debian): + novtext = '{}.{}.{}'.format(self.major, self.minor, self.patch) + + if self.hotfix is None: + return novtext + else: + assert self.hotfix > 0, self.hotfix + if self.betarc is None: + assert self.hotfix < 50, self.hotfix + sep = '+' if debian else '-' + return '{}{}{}'.format(novtext, sep, self.hotfix) + else: + assert self.hotfix < 26, self.hotfix + sep = '~' if debian else '-' + return '{}{}{}{}'.format( + novtext, + sep, + self.betarc, + self.hotfix, + ) + + def __repr__(self): + return ''.format(self.vtext) + + def _sort_tup(self): + if self.hotfix is None: + prio = 2 + else: + prio = {'beta': 0, 'rc': 1, None: 3}[self.betarc] + + return ( + self.major, + self.minor, + self.patch, + prio, + self.hotfix, + ) + + def __cmp__(self, other): + return cmp(self._sort_tup(), other._sort_tup()) + + +class PathPatcher (object): + def __init__(self, path): + self._path = path + + def __enter__(self): + logging.debug('Patching %r', self._path) + self._inf = file(self._path, 'r') + self._outf = StringIO() + return (self._inf, self._outf) + + def __exit__(self, et, ev, tb): + if (et, ev, tb) == (None, None, None): + self._inf.close() + with file(self._path, 'w') as f: + f.write(self._outf.getvalue()) + + +# Unit Tests +class TestVersion (unittest.TestCase): + ValidVersionsAndBuilds = [ + # These are taken from: git tag --list | grep '^v1' + ('v1.0.0-beta1', 0), + ('v1.0.0-beta2', 1), + ('v1.0.0-rc1', 25), + ('v1.0.0-rc2', 26), + ('v1.0.0-rc3', 27), + ('v1.0.0-rc4', 28), + ('v1.0.0', 50), + ('v1.0.1', 50), + ('v1.0.2', 50), + ('v1.0.3', 50), + ('v1.0.4', 50), + ('v1.0.5', 50), + ('v1.0.6', 50), + ('v1.0.7-1', 51), + ('v1.0.8', 50), + ('v1.0.8-1', 51), + ('v1.0.9', 50), + ('v1.0.10', 50), + ('v7.42.1000', 50), + ] + + ValidVersions = [ + v + for (v, _) + in ValidVersionsAndBuilds + ] + + def test_arg_parse_and_vtext_identity(self): + for case in self.ValidVersions: + v = Version.parse_arg(case) + self.assertEqual(v.vtext, case) + + def test_arg_parse_negatives(self): + cases = [ + 'v07.0.0', + 'v1.0.03', + 'v1.2.3-0', # Hotfix numbers must begin w/ 1 + 'v1.2.3~0', + 'v1.2.3+0', + '1.2.3', + ] + + for case in cases: + self.assertRaises( + argparse.ArgumentTypeError, + Version.parse_arg, + case, + ) + + def test_version_sort(self): + expected = [Version.parse_arg(v) for v in self.ValidVersions] + + rng = random.Random() + rng.seed(0) + + for _ in range(1024): + vec = list(expected) + rng.shuffle(vec) + vec.sort() + self.assertEqual(vec, expected) + + def test_build_nums(self): + for (text, expected) in self.ValidVersionsAndBuilds: + version = Version.parse_arg(text) + self.assertEqual(version.build, expected) + + +if __name__ == '__main__': + if len(sys.argv) == 2 and sys.argv[1] == '--help': + main() + else: + actualargs = sys.argv + sys.argv = [sys.argv[0], '--verbose'] + + print '=== Self Test ===' + try: + unittest.main() + except SystemExit as e: + if e.args[0] != 0: + raise + + sys.argv = actualargs + print '=== Running ===' + main() diff --git a/zcutil/release-notes.py b/zcutil/release-notes.py old mode 100644 new mode 100755 index 47f234906..01f658f07 --- a/zcutil/release-notes.py +++ b/zcutil/release-notes.py @@ -4,6 +4,21 @@ import argparse from itertools import islice from operator import itemgetter +TEMP_RELEASE_NOTES_HEADER = [ + '(note: this is a temporary file, to be added-to by anybody, and moved to\n', + 'release-notes at release time)\n', + '\n', + 'Notable changes\n', + '===============\n', + '\n', +] + +RELEASE_NOTES_CHANGELOG_HEADING = [ + 'Changelog\n', + '=========\n', + '\n', +] + author_aliases = { 'Simon': 'Simon Liu', 'bitcartel': 'Simon Liu', @@ -55,6 +70,10 @@ def document_authors(): f.write('Zcash Contributors\n==================\n\n') total_contrib = {} for notes in os.listdir(os.path.join(doc_dir, 'release-notes')): + # Commits are duplicated across beta, RC and final release notes, + # except for the pre-launch release notes. + if ('-beta' in notes or '-rc' in notes) and '1.0.0-' not in notes: + continue authors = authors_in_release_notes(notes) for author in authors: commits = int(authors[author]) @@ -68,34 +87,56 @@ def document_authors(): f.write("{0} ({1})\n".format(n, c)) ## Writes release note to ./doc/release-notes based on git shortlog when current version number is specified -def generate_release_note(version, filename): +def generate_release_note(version, prev, clear): + filename = 'release-notes-{0}.md'.format(version) print "Automatically generating release notes for {0} from git shortlog. Should review {1} for accuracy.".format(version, filename) - # fetches latest tags, so that latest_tag will be correct - subprocess.Popen(['git fetch -t'], shell=True, stdout=subprocess.PIPE).communicate()[0] - latest_tag = subprocess.Popen(['git describe --abbrev=0'], shell=True, stdout=subprocess.PIPE).communicate()[0].strip() + if prev: + latest_tag = prev + else: + # fetches latest tags, so that latest_tag will be correct + subprocess.Popen(['git fetch -t'], shell=True, stdout=subprocess.PIPE).communicate()[0] + latest_tag = subprocess.Popen(['git describe --abbrev=0'], shell=True, stdout=subprocess.PIPE).communicate()[0].strip() print "Previous release tag: ", latest_tag notes = subprocess.Popen(['git shortlog --no-merges {0}..HEAD'.format(latest_tag)], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate()[0] lines = notes.split('\n') lines = [alias_authors_in_release_notes(line) for line in lines] - release_note = os.path.join(doc_dir, 'release-notes', 'release-notes-{0}.md'.format(version)) + temp_release_note = os.path.join(doc_dir, 'release-notes.md') + with open(temp_release_note, 'r') as f: + notable_changes = f.readlines() + # Assumes that all notable changes are appended to the default header + if len(notable_changes) > 6: + notable_changes = notable_changes[3:] + ['\n'] + else: + notable_changes = [] + release_note = os.path.join(doc_dir, 'release-notes', filename) with open(release_note, 'w') as f: + f.writelines(notable_changes) + f.writelines(RELEASE_NOTES_CHANGELOG_HEADING) f.writelines('\n'.join(lines)) + if clear: + # Clear temporary release notes file + with open(temp_release_note, 'w') as f: + f.writelines(TEMP_RELEASE_NOTES_HEADER) -def main(version, filename): +def main(version, prev, clear): if version != None: - generate_release_note(version, filename) + generate_release_note(version, prev, clear) document_authors() if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument('--version') + parser.add_argument('--version', help='Upcoming version, without leading v') + parser.add_argument('--prev', help='Previous version, with leading v') + parser.add_argument('--clear', help='Wipe doc/release-notes.md', action='store_true') args = parser.parse_args() root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) doc_dir = os.path.join(root_dir, 'doc') version = None - filename = None + prev = None + clear = False if args.version: version = args.version - filename = 'release-notes-{0}.md'.format(version) - main(version, filename) + prev = args.prev + clear = args.clear + main(version, prev, clear)